diff mbox

[PULL,062/107] ppc: Add ppc_set_compat_all()

Message ID 20170202051445.5735-63-david@gibson.dropbear.id.au
State New
Headers show

Commit Message

David Gibson Feb. 2, 2017, 5:14 a.m. UTC
Once a compatiblity mode is negotiated with the guest,
h_client_architecture_support() uses run_on_cpu() to update each CPU to
the new mode.  We're going to want this logic somewhere else shortly,
so make a helper function to do this global update.

We put it in target-ppc/compat.c - it makes as much sense at the CPU level
as it does at the machine level.  We also move the cpu_synchronize_state()
into ppc_set_compat(), since it doesn't really make any sense to call that
without synchronizing state.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/spapr_hcall.c | 31 +++++--------------------------
 target/ppc/compat.c  | 35 +++++++++++++++++++++++++++++++++++
 target/ppc/cpu.h     |  3 +++
 3 files changed, 43 insertions(+), 26 deletions(-)
diff mbox

Patch

diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index f4531c5..42d20e0 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -921,20 +921,6 @@  static target_ulong h_signal_sys_reset(PowerPCCPU *cpu,
     }
 }
 
-typedef struct {
-    uint32_t compat_pvr;
-    Error *err;
-} SetCompatState;
-
-static void do_set_compat(CPUState *cs, run_on_cpu_data arg)
-{
-    PowerPCCPU *cpu = POWERPC_CPU(cs);
-    SetCompatState *s = arg.host_ptr;
-
-    cpu_synchronize_state(cs);
-    ppc_set_compat(cpu, s->compat_pvr, &s->err);
-}
-
 static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
                                                   sPAPRMachineState *spapr,
                                                   target_ulong opcode,
@@ -942,7 +928,6 @@  static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
 {
     target_ulong list = ppc64_phys_to_real(args[0]);
     target_ulong ov_table;
-    CPUState *cs;
     bool explicit_match = false; /* Matched the CPU's real PVR */
     uint32_t max_compat = cpu->max_compat;
     uint32_t best_compat = 0;
@@ -986,18 +971,12 @@  static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
 
     /* Update CPUs */
     if (cpu->compat_pvr != best_compat) {
-        CPU_FOREACH(cs) {
-            SetCompatState s = {
-                .compat_pvr = best_compat,
-                .err = NULL,
-            };
+        Error *local_err = NULL;
 
-            run_on_cpu(cs, do_set_compat, RUN_ON_CPU_HOST_PTR(&s));
-
-            if (s.err) {
-                error_report_err(s.err);
-                return H_HARDWARE;
-            }
+        ppc_set_compat_all(best_compat, &local_err);
+        if (local_err) {
+            error_report_err(local_err);
+            return H_HARDWARE;
         }
     }
 
diff --git a/target/ppc/compat.c b/target/ppc/compat.c
index 1059555..458da26 100644
--- a/target/ppc/compat.c
+++ b/target/ppc/compat.c
@@ -18,6 +18,7 @@ 
  */
 
 #include "qemu/osdep.h"
+#include "sysemu/hw_accel.h"
 #include "sysemu/kvm.h"
 #include "kvm_ppc.h"
 #include "sysemu/cpus.h"
@@ -124,6 +125,8 @@  void ppc_set_compat(PowerPCCPU *cpu, uint32_t compat_pvr, Error **errp)
         pcr = compat->pcr;
     }
 
+    cpu_synchronize_state(CPU(cpu));
+
     cpu->compat_pvr = compat_pvr;
     env->spr[SPR_PCR] = pcr & pcc->pcr_mask;
 
@@ -136,6 +139,38 @@  void ppc_set_compat(PowerPCCPU *cpu, uint32_t compat_pvr, Error **errp)
     }
 }
 
+typedef struct {
+    uint32_t compat_pvr;
+    Error *err;
+} SetCompatState;
+
+static void do_set_compat(CPUState *cs, run_on_cpu_data arg)
+{
+    PowerPCCPU *cpu = POWERPC_CPU(cs);
+    SetCompatState *s = arg.host_ptr;
+
+    ppc_set_compat(cpu, s->compat_pvr, &s->err);
+}
+
+void ppc_set_compat_all(uint32_t compat_pvr, Error **errp)
+{
+    CPUState *cs;
+
+    CPU_FOREACH(cs) {
+        SetCompatState s = {
+            .compat_pvr = compat_pvr,
+            .err = NULL,
+        };
+
+        run_on_cpu(cs, do_set_compat, RUN_ON_CPU_HOST_PTR(&s));
+
+        if (s.err) {
+            error_propagate(errp, s.err);
+            return;
+        }
+    }
+}
+
 int ppc_compat_max_threads(PowerPCCPU *cpu)
 {
     const CompatInfo *compat = compat_by_pvr(cpu->compat_pvr);
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index 22842dd..4d72d75 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -1326,6 +1326,9 @@  static inline int cpu_mmu_index (CPUPPCState *env, bool ifetch)
 bool ppc_check_compat(PowerPCCPU *cpu, uint32_t compat_pvr,
                       uint32_t min_compat_pvr, uint32_t max_compat_pvr);
 void ppc_set_compat(PowerPCCPU *cpu, uint32_t compat_pvr, Error **errp);
+#if !defined(CONFIG_USER_ONLY)
+void ppc_set_compat_all(uint32_t compat_pvr, Error **errp);
+#endif
 int ppc_compat_max_threads(PowerPCCPU *cpu);
 #endif /* defined(TARGET_PPC64) */