ppc: Add ppc_set_compat_all()
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>
This commit is contained in:
		
							parent
							
								
									152ef803ce
								
							
						
					
					
						commit
						f6f242c757
					
				| 
						 | 
				
			
			@ -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;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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) */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue