Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

powerpc/pseries: Fix xive=off command line

On POWER9, if the hypervisor supports XIVE exploitation mode, the
guest OS will unconditionally requests for the XIVE interrupt mode
even if XIVE was deactivated with the kernel command line xive=off.
Later on, when the spapr XIVE init code handles xive=off, it disables
XIVE and tries to fall back on the legacy mode XICS.

This discrepency causes a kernel panic because the hypervisor is
configured to provide the XIVE interrupt mode to the guest :

kernel BUG at arch/powerpc/sysdev/xics/xics-common.c:135!
...
NIP xics_smp_probe+0x38/0x98
LR xics_smp_probe+0x2c/0x98
Call Trace:
xics_smp_probe+0x2c/0x98 (unreliable)
pSeries_smp_probe+0x40/0xa0
smp_prepare_cpus+0x62c/0x6ec
kernel_init_freeable+0x148/0x448
kernel_init+0x2c/0x148
ret_from_kernel_thread+0x5c/0x68

Look for xive=off during prom_init and don't ask for XIVE in this
case. One exception though: if the host only supports XIVE, we still
want to boot so we ignore xive=off.

Similarly, have the spapr XIVE init code to looking at the interrupt
mode negotiated during CAS, and ignore xive=off if the hypervisor only
supports XIVE.

Fixes: eac1e731b59e ("powerpc/xive: guest exploitation of the XIVE interrupt controller")
Cc: stable@vger.kernel.org # v4.20
Reported-by: Pavithra R. Prakash <pavrampu@in.ibm.com>
Signed-off-by: Greg Kurz <groug@kaod.org>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>

authored by

Greg Kurz and committed by
Michael Ellerman
a3bf9fbd 02c5f539

+66 -2
+15 -1
arch/powerpc/kernel/prom_init.c
··· 172 172 173 173 #ifdef CONFIG_PPC_PSERIES 174 174 static bool __prombss prom_radix_disable; 175 + static bool __prombss prom_xive_disable; 175 176 #endif 176 177 177 178 struct platform_support { ··· 809 808 } 810 809 if (prom_radix_disable) 811 810 prom_debug("Radix disabled from cmdline\n"); 811 + 812 + opt = prom_strstr(prom_cmd_line, "xive=off"); 813 + if (opt) { 814 + prom_xive_disable = true; 815 + prom_debug("XIVE disabled from cmdline\n"); 816 + } 812 817 #endif /* CONFIG_PPC_PSERIES */ 813 818 } 814 819 ··· 1223 1216 switch (val) { 1224 1217 case OV5_FEAT(OV5_XIVE_EITHER): /* Either Available */ 1225 1218 prom_debug("XIVE - either mode supported\n"); 1226 - support->xive = true; 1219 + support->xive = !prom_xive_disable; 1227 1220 break; 1228 1221 case OV5_FEAT(OV5_XIVE_EXPLOIT): /* Only Exploitation mode */ 1229 1222 prom_debug("XIVE - exploitation mode supported\n"); 1223 + if (prom_xive_disable) { 1224 + /* 1225 + * If we __have__ to do XIVE, we're better off ignoring 1226 + * the command line rather than not booting. 1227 + */ 1228 + prom_printf("WARNING: Ignoring cmdline option xive=off\n"); 1229 + } 1230 1230 support->xive = true; 1231 1231 break; 1232 1232 case OV5_FEAT(OV5_XIVE_LEGACY): /* Only Legacy mode */
+51 -1
arch/powerpc/sysdev/xive/spapr.c
··· 20 20 #include <linux/cpumask.h> 21 21 #include <linux/mm.h> 22 22 #include <linux/delay.h> 23 + #include <linux/libfdt.h> 23 24 24 25 #include <asm/prom.h> 25 26 #include <asm/io.h> ··· 664 663 return true; 665 664 } 666 665 666 + static const u8 *get_vec5_feature(unsigned int index) 667 + { 668 + unsigned long root, chosen; 669 + int size; 670 + const u8 *vec5; 671 + 672 + root = of_get_flat_dt_root(); 673 + chosen = of_get_flat_dt_subnode_by_name(root, "chosen"); 674 + if (chosen == -FDT_ERR_NOTFOUND) 675 + return NULL; 676 + 677 + vec5 = of_get_flat_dt_prop(chosen, "ibm,architecture-vec-5", &size); 678 + if (!vec5) 679 + return NULL; 680 + 681 + if (size <= index) 682 + return NULL; 683 + 684 + return vec5 + index; 685 + } 686 + 687 + static bool xive_spapr_disabled(void) 688 + { 689 + const u8 *vec5_xive; 690 + 691 + vec5_xive = get_vec5_feature(OV5_INDX(OV5_XIVE_SUPPORT)); 692 + if (vec5_xive) { 693 + u8 val; 694 + 695 + val = *vec5_xive & OV5_FEAT(OV5_XIVE_SUPPORT); 696 + switch (val) { 697 + case OV5_FEAT(OV5_XIVE_EITHER): 698 + case OV5_FEAT(OV5_XIVE_LEGACY): 699 + break; 700 + case OV5_FEAT(OV5_XIVE_EXPLOIT): 701 + /* Hypervisor only supports XIVE */ 702 + if (xive_cmdline_disabled) 703 + pr_warn("WARNING: Ignoring cmdline option xive=off\n"); 704 + return false; 705 + default: 706 + pr_warn("%s: Unknown xive support option: 0x%x\n", 707 + __func__, val); 708 + break; 709 + } 710 + } 711 + 712 + return xive_cmdline_disabled; 713 + } 714 + 667 715 bool __init xive_spapr_init(void) 668 716 { 669 717 struct device_node *np; ··· 725 675 const __be32 *reg; 726 676 int i; 727 677 728 - if (xive_cmdline_disabled) 678 + if (xive_spapr_disabled()) 729 679 return false; 730 680 731 681 pr_devel("%s()\n", __func__);