#ifdef CONFIG_PPC_PSERIES
 static bool __prombss prom_radix_disable;
+static bool __prombss prom_xive_disable;
 #endif
 
 struct platform_support {
        }
        if (prom_radix_disable)
                prom_debug("Radix disabled from cmdline\n");
+
+       opt = prom_strstr(prom_cmd_line, "xive=off");
+       if (opt) {
+               prom_xive_disable = true;
+               prom_debug("XIVE disabled from cmdline\n");
+       }
 #endif /* CONFIG_PPC_PSERIES */
 }
 
        switch (val) {
        case OV5_FEAT(OV5_XIVE_EITHER): /* Either Available */
                prom_debug("XIVE - either mode supported\n");
-               support->xive = true;
+               support->xive = !prom_xive_disable;
                break;
        case OV5_FEAT(OV5_XIVE_EXPLOIT): /* Only Exploitation mode */
                prom_debug("XIVE - exploitation mode supported\n");
+               if (prom_xive_disable) {
+                       /*
+                        * If we __have__ to do XIVE, we're better off ignoring
+                        * the command line rather than not booting.
+                        */
+                       prom_printf("WARNING: Ignoring cmdline option xive=off\n");
+               }
                support->xive = true;
                break;
        case OV5_FEAT(OV5_XIVE_LEGACY): /* Only Legacy mode */
 
 #include <linux/cpumask.h>
 #include <linux/mm.h>
 #include <linux/delay.h>
+#include <linux/libfdt.h>
 
 #include <asm/prom.h>
 #include <asm/io.h>
        return true;
 }
 
+static const u8 *get_vec5_feature(unsigned int index)
+{
+       unsigned long root, chosen;
+       int size;
+       const u8 *vec5;
+
+       root = of_get_flat_dt_root();
+       chosen = of_get_flat_dt_subnode_by_name(root, "chosen");
+       if (chosen == -FDT_ERR_NOTFOUND)
+               return NULL;
+
+       vec5 = of_get_flat_dt_prop(chosen, "ibm,architecture-vec-5", &size);
+       if (!vec5)
+               return NULL;
+
+       if (size <= index)
+               return NULL;
+
+       return vec5 + index;
+}
+
+static bool xive_spapr_disabled(void)
+{
+       const u8 *vec5_xive;
+
+       vec5_xive = get_vec5_feature(OV5_INDX(OV5_XIVE_SUPPORT));
+       if (vec5_xive) {
+               u8 val;
+
+               val = *vec5_xive & OV5_FEAT(OV5_XIVE_SUPPORT);
+               switch (val) {
+               case OV5_FEAT(OV5_XIVE_EITHER):
+               case OV5_FEAT(OV5_XIVE_LEGACY):
+                       break;
+               case OV5_FEAT(OV5_XIVE_EXPLOIT):
+                       /* Hypervisor only supports XIVE */
+                       if (xive_cmdline_disabled)
+                               pr_warn("WARNING: Ignoring cmdline option xive=off\n");
+                       return false;
+               default:
+                       pr_warn("%s: Unknown xive support option: 0x%x\n",
+                               __func__, val);
+                       break;
+               }
+       }
+
+       return xive_cmdline_disabled;
+}
+
 bool __init xive_spapr_init(void)
 {
        struct device_node *np;
        const __be32 *reg;
        int i;
 
-       if (xive_cmdline_disabled)
+       if (xive_spapr_disabled())
                return false;
 
        pr_devel("%s()\n", __func__);