From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43628) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1c6m3S-0001Vc-Tb for qemu-devel@nongnu.org; Tue, 15 Nov 2016 17:18:17 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1c6m3R-00036Y-PV for qemu-devel@nongnu.org; Tue, 15 Nov 2016 17:18:14 -0500 From: David Gibson Date: Wed, 16 Nov 2016 09:17:52 +1100 Message-Id: <1479248275-18889-10-git-send-email-david@gibson.dropbear.id.au> In-Reply-To: <1479248275-18889-1-git-send-email-david@gibson.dropbear.id.au> References: <1479248275-18889-1-git-send-email-david@gibson.dropbear.id.au> Subject: [Qemu-devel] [RFCv2 09/12] ppc: Add ppc_set_compat_all() List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: groug@kaod.org, clg@kaod.org, aik@ozlabs.ru, mdroth@linux.vnet.ibm.com, nikunj@linux.vnet.ibm.com Cc: agraf@suse.de, qemu-ppc@nongnu.org, qemu-devel@nongnu.org, abologna@redhat.com, thuth@redhat.com, lvivier@redhat.com, David Gibson 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 --- hw/ppc/spapr_hcall.c | 31 +++++-------------------------- target-ppc/compat.c | 34 ++++++++++++++++++++++++++++++++++ target-ppc/cpu.h | 3 +++ 3 files changed, 42 insertions(+), 26 deletions(-) diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c index 48b253f..96d50ad 100644 --- a/hw/ppc/spapr_hcall.c +++ b/hw/ppc/spapr_hcall.c @@ -881,20 +881,6 @@ static target_ulong h_set_mode(PowerPCCPU *cpu, sPAPRMachineState *spapr, return ret; } -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, @@ -902,7 +888,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; @@ -947,18 +932,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..8de9dfb 100644 --- a/target-ppc/compat.c +++ b/target-ppc/compat.c @@ -124,6 +124,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 +138,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 91e8be8..201a655 100644 --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h @@ -1317,6 +1317,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) */ -- 2.7.4