return -EIO;
        }
 
-       /*
-        * Future improvement: start with them disabled
-        * and handle DD2 and later scheme of merged escalation
-        * interrupts
-        */
-       name = kasprintf(GFP_KERNEL, "kvm-%d-%d-%d",
-                        vcpu->kvm->arch.lpid, xc->server_num, prio);
+       if (xc->xive->single_escalation)
+               name = kasprintf(GFP_KERNEL, "kvm-%d-%d",
+                                vcpu->kvm->arch.lpid, xc->server_num);
+       else
+               name = kasprintf(GFP_KERNEL, "kvm-%d-%d-%d",
+                                vcpu->kvm->arch.lpid, xc->server_num, prio);
        if (!name) {
                pr_err("Failed to allocate escalation irq name for queue %d of VCPU %d\n",
                       prio, xc->server_num);
                rc = -ENOMEM;
                goto error;
        }
+
+       pr_devel("Escalation %s irq %d (prio %d)\n", name, xc->esc_virq[prio], prio);
+
        rc = request_irq(xc->esc_virq[prio], xive_esc_irq,
                         IRQF_NO_THREAD, name, vcpu);
        if (rc) {
 
        pr_devel("Provisioning prio... %d\n", prio);
 
-       /* Provision each VCPU and enable escalations */
+       /* Provision each VCPU and enable escalations if needed */
        kvm_for_each_vcpu(i, vcpu, kvm) {
                if (!vcpu->arch.xive_vcpu)
                        continue;
                rc = xive_provision_queue(vcpu, prio);
-               if (rc == 0)
+               if (rc == 0 && !xive->single_escalation)
                        xive_attach_escalation(vcpu, prio);
                if (rc)
                        return rc;
        /* Allocate IPI */
        xc->vp_ipi = xive_native_alloc_irq();
        if (!xc->vp_ipi) {
+               pr_err("Failed to allocate xive irq for VCPU IPI\n");
                r = -EIO;
                goto bail;
        }
        if (r)
                goto bail;
 
+       /*
+        * Enable the VP first as the single escalation mode will
+        * affect escalation interrupts numbering
+        */
+       r = xive_native_enable_vp(xc->vp_id, xive->single_escalation);
+       if (r) {
+               pr_err("Failed to enable VP in OPAL, err %d\n", r);
+               goto bail;
+       }
+
        /*
         * Initialize queues. Initially we set them all for no queueing
         * and we enable escalation for queue 0 only which we'll use for
         * our mfrr change notifications. If the VCPU is hot-plugged, we
-        * do handle provisioning however.
+        * do handle provisioning however based on the existing "map"
+        * of enabled queues.
         */
        for (i = 0; i < KVMPPC_XIVE_Q_COUNT; i++) {
                struct xive_q *q = &xc->queues[i];
 
+               /* Single escalation, no queue 7 */
+               if (i == 7 && xive->single_escalation)
+                       break;
+
                /* Is queue already enabled ? Provision it */
                if (xive->qmap & (1 << i)) {
                        r = xive_provision_queue(vcpu, i);
-                       if (r == 0)
+                       if (r == 0 && !xive->single_escalation)
                                xive_attach_escalation(vcpu, i);
                        if (r)
                                goto bail;
        if (r)
                goto bail;
 
-       /* Enable the VP */
-       r = xive_native_enable_vp(xc->vp_id);
-       if (r)
-               goto bail;
-
        /* Route the IPI */
        r = xive_native_configure_irq(xc->vp_ipi, xc->vp_id, 0, XICS_IPI);
        if (!r)
 
        pr_devel("  val=0x016%llx (server=0x%x, guest_prio=%d)\n",
                 val, server, guest_prio);
+
        /*
         * If the source doesn't already have an IPI, allocate
         * one and get the corresponding data
        if (xive->vp_base == XIVE_INVALID_VP)
                ret = -ENOMEM;
 
+       xive->single_escalation = xive_native_has_single_escalation();
+
        if (ret) {
                kfree(xive);
                return ret;
 
        u32     q_order;
        u32     q_page_order;
 
+       /* Flags */
+       u8      single_escalation;
 };
 
 #define KVMPPC_XIVE_Q_COUNT    8
  * is as follow.
  *
  * Guest request for 0...6 are honored. Guest request for anything
- * higher results in a priority of 7 being applied.
- *
- * However, when XIRR is returned via H_XIRR, 7 is translated to 0xb
- * in order to match AIX expectations
+ * higher results in a priority of 6 being applied.
  *
  * Similar mapping is done for CPPR values
  */
 static inline u8 xive_prio_from_guest(u8 prio)
 {
-       if (prio == 0xff || prio < 8)
+       if (prio == 0xff || prio < 6)
                return prio;
-       return 7;
+       return 6;
 }
 
 static inline u8 xive_prio_to_guest(u8 prio)
 {
-       if (prio == 0xff || prio < 7)
-               return prio;
-       return 0xb;
+       return prio;
 }
 
 static inline u32 __xive_read_eq(__be32 *qpage, u32 msk, u32 *idx, u32 *toggle)
 
 static u32 xive_queue_shift;
 static u32 xive_pool_vps = XIVE_INVALID_VP;
 static struct kmem_cache *xive_provision_cache;
+static bool xive_has_single_esc;
 
 int xive_native_populate_irq_data(u32 hw_irq, struct xive_irq_data *data)
 {
                        break;
        }
 
+       /* Do we support single escalation */
+       if (of_get_property(np, "single-escalation-support", NULL) != NULL)
+               xive_has_single_esc = true;
+
        /* Configure Thread Management areas for KVM */
        for_each_possible_cpu(cpu)
                kvmppc_set_xive_tima(cpu, r.start, tima);
 }
 EXPORT_SYMBOL_GPL(xive_native_free_vp_block);
 
-int xive_native_enable_vp(u32 vp_id)
+int xive_native_enable_vp(u32 vp_id, bool single_escalation)
 {
        s64 rc;
+       u64 flags = OPAL_XIVE_VP_ENABLED;
 
+       if (single_escalation)
+               flags |= OPAL_XIVE_VP_SINGLE_ESCALATION;
        for (;;) {
-               rc = opal_xive_set_vp_info(vp_id, OPAL_XIVE_VP_ENABLED, 0);
+               rc = opal_xive_set_vp_info(vp_id, flags, 0);
                if (rc != OPAL_BUSY)
                        break;
                msleep(1);
        return 0;
 }
 EXPORT_SYMBOL_GPL(xive_native_get_vp_info);
+
+bool xive_native_has_single_escalation(void)
+{
+       return xive_has_single_esc;
+}
+EXPORT_SYMBOL_GPL(xive_native_has_single_escalation);