023288b
From: David Gibson <david@gibson.dropbear.id.au>
023288b
Date: Fri, 18 Oct 2019 15:19:31 +1100
023288b
Subject: [PATCH] spapr: Don't trigger a CAS reboot for XICS/XIVE mode
023288b
 changeover
023288b
023288b
PAPR allows the interrupt controller used on a POWER9 machine (XICS or
023288b
XIVE) to be selected by the guest operating system, by using the
023288b
ibm,client-architecture-support (CAS) feature negotiation call.
023288b
023288b
Currently, if the guest selects an interrupt controller different from the
023288b
one selected at initial boot, this causes the system to be reset with the
023288b
new model and the boot starts again.  This means we run through the SLOF
023288b
boot process twice, as well as any other bootloader (e.g. grub) in use
023288b
before the OS calls CAS.  This can be confusing and/or inconvenient for
023288b
users.
023288b
023288b
Thanks to two fairly recent changes, we no longer need this reboot.  1) we
023288b
now completely regenerate the device tree when CAS is called (meaning we
023288b
don't need special case updates for all the device tree changes caused by
023288b
the interrupt controller mode change),  2) we now have explicit code paths
023288b
to activate and deactivate the different interrupt controllers, rather than
023288b
just implicitly calling those at machine reset time.
023288b
023288b
We can therefore eliminate the reboot for changing irq mode, simply by
023288b
putting a call to spapr_irq_update_active_intc() before we call
023288b
spapr_h_cas_compose_response() (which gives the updated device tree to
023288b
the guest firmware and OS).
023288b
023288b
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
023288b
Reviewed-by: Cedric Le Goater <clg@fr.ibm.com>
023288b
Reviewed-by: Greg Kurz <groug@kaod.org>
023288b
(cherry picked from commit 8deb8019d696c75e6ecaee7545026b62aba2f1bb)
023288b
---
023288b
 hw/ppc/spapr_hcall.c | 33 +++++++++++++--------------------
023288b
 1 file changed, 13 insertions(+), 20 deletions(-)
023288b
023288b
diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
023288b
index 140f05c1c6..05a7ca275b 100644
023288b
--- a/hw/ppc/spapr_hcall.c
023288b
+++ b/hw/ppc/spapr_hcall.c
023288b
@@ -1767,21 +1767,10 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
023288b
     }
023288b
     spapr->cas_pre_isa3_guest = !spapr_ovec_test(ov1_guest, OV1_PPC_3_00);
023288b
     spapr_ovec_cleanup(ov1_guest);
023288b
-    if (!spapr->cas_reboot) {
023288b
-        /* If spapr_machine_reset() did not set up a HPT but one is necessary
023288b
-         * (because the guest isn't going to use radix) then set it up here. */
023288b
-        if ((spapr->patb_entry & PATE1_GR) && !guest_radix) {
023288b
-            /* legacy hash or new hash: */
023288b
-            spapr_setup_hpt_and_vrma(spapr);
023288b
-        }
023288b
-        spapr->cas_reboot =
023288b
-            (spapr_h_cas_compose_response(spapr, args[1], args[2],
023288b
-                                          ov5_updates) != 0);
023288b
-    }
023288b
 
023288b
     /*
023288b
-     * Ensure the guest asks for an interrupt mode we support; otherwise
023288b
-     * terminate the boot.
023288b
+     * Ensure the guest asks for an interrupt mode we support;
023288b
+     * otherwise terminate the boot.
023288b
      */
023288b
     if (guest_xive) {
023288b
         if (!spapr->irq->xive) {
023288b
@@ -1797,14 +1786,18 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
023288b
         }
023288b
     }
023288b
 
023288b
-    /*
023288b
-     * Generate a machine reset when we have an update of the
023288b
-     * interrupt mode. Only required when the machine supports both
023288b
-     * modes.
023288b
-     */
023288b
+    spapr_irq_update_active_intc(spapr);
023288b
+
023288b
     if (!spapr->cas_reboot) {
023288b
-        spapr->cas_reboot = spapr_ovec_test(ov5_updates, OV5_XIVE_EXPLOIT)
023288b
-            && spapr->irq->xics && spapr->irq->xive;
023288b
+        /* If spapr_machine_reset() did not set up a HPT but one is necessary
023288b
+         * (because the guest isn't going to use radix) then set it up here. */
023288b
+        if ((spapr->patb_entry & PATE1_GR) && !guest_radix) {
023288b
+            /* legacy hash or new hash: */
023288b
+            spapr_setup_hpt_and_vrma(spapr);
023288b
+        }
023288b
+        spapr->cas_reboot =
023288b
+            (spapr_h_cas_compose_response(spapr, args[1], args[2],
023288b
+                                          ov5_updates) != 0);
023288b
     }
023288b
 
023288b
     spapr_ovec_cleanup(ov5_updates);