Message ID | 20190718034214.14948-3-npiggin@gmail.com |
---|---|
State | New |
Headers | show |
Series | spapr: implement dispatch and suspend calls | expand |
On Thu, 18 Jul 2019 13:42:12 +1000 Nicholas Piggin <npiggin@gmail.com> wrote: > H_PROD is added, and H_CEDE is modified to test the prod bit > according to PAPR. > > Signed-off-by: Nicholas Piggin <npiggin@gmail.com> > --- Reviewed-by: Greg Kurz <groug@kaod.org> > Changes since v5: > - Add the prod bit here > - Fix target CPU > > hw/ppc/spapr.c | 1 + > hw/ppc/spapr_hcall.c | 32 ++++++++++++++++++++++++++++++++ > include/hw/ppc/spapr_cpu_core.h | 1 + > 3 files changed, 34 insertions(+) > > diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c > index 3e5678d467..68341c128d 100644 > --- a/hw/ppc/spapr.c > +++ b/hw/ppc/spapr.c > @@ -4309,6 +4309,7 @@ static void spapr_cpu_exec_enter(PPCVirtualHypervisor *vhyp, PowerPCCPU *cpu) > > /* These are only called by TCG, KVM maintains dispatch state */ > > + spapr_cpu->prod = false; > if (spapr_cpu->vpa_addr) { > CPUState *cs = CPU(cpu); > uint32_t dispatch; > diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c > index e615881ac4..098b3dda22 100644 > --- a/hw/ppc/spapr_hcall.c > +++ b/hw/ppc/spapr_hcall.c > @@ -1050,14 +1050,44 @@ static target_ulong h_cede(PowerPCCPU *cpu, SpaprMachineState *spapr, > { > CPUPPCState *env = &cpu->env; > CPUState *cs = CPU(cpu); > + SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu); > > env->msr |= (1ULL << MSR_EE); > hreg_compute_hflags(env); > + > + if (spapr_cpu->prod) { > + spapr_cpu->prod = false; > + return H_SUCCESS; > + } > + > if (!cpu_has_work(cs)) { > cs->halted = 1; > cs->exception_index = EXCP_HLT; > cs->exit_request = 1; > } > + > + return H_SUCCESS; > +} > + > +static target_ulong h_prod(PowerPCCPU *cpu, SpaprMachineState *spapr, > + target_ulong opcode, target_ulong *args) > +{ > + target_long target = args[0]; > + PowerPCCPU *tcpu; > + CPUState *cs; > + SpaprCpuState *spapr_cpu; > + > + tcpu = spapr_find_cpu(target); > + cs = CPU(tcpu); > + if (!cs) { > + return H_PARAMETER; > + } > + > + spapr_cpu = spapr_cpu_state(tcpu); > + spapr_cpu->prod = true; > + cs->halted = 0; > + qemu_cpu_kick(cs); > + > return H_SUCCESS; > } > > @@ -1882,6 +1912,8 @@ static void hypercall_register_types(void) > /* hcall-splpar */ > spapr_register_hypercall(H_REGISTER_VPA, h_register_vpa); > spapr_register_hypercall(H_CEDE, h_cede); > + spapr_register_hypercall(H_PROD, h_prod); > + > spapr_register_hypercall(H_SIGNAL_SYS_RESET, h_signal_sys_reset); > > /* processor register resource access h-calls */ > diff --git a/include/hw/ppc/spapr_cpu_core.h b/include/hw/ppc/spapr_cpu_core.h > index f9645a7290..a40cd08ea0 100644 > --- a/include/hw/ppc/spapr_cpu_core.h > +++ b/include/hw/ppc/spapr_cpu_core.h > @@ -46,6 +46,7 @@ typedef struct SpaprCpuState { > uint64_t vpa_addr; > uint64_t slb_shadow_addr, slb_shadow_size; > uint64_t dtl_addr, dtl_size; > + bool prod; /* not migrated, only used to improve dispatch latencies */ > struct ICPState *icp; > struct XiveTCTX *tctx; > } SpaprCpuState;
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 3e5678d467..68341c128d 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -4309,6 +4309,7 @@ static void spapr_cpu_exec_enter(PPCVirtualHypervisor *vhyp, PowerPCCPU *cpu) /* These are only called by TCG, KVM maintains dispatch state */ + spapr_cpu->prod = false; if (spapr_cpu->vpa_addr) { CPUState *cs = CPU(cpu); uint32_t dispatch; diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c index e615881ac4..098b3dda22 100644 --- a/hw/ppc/spapr_hcall.c +++ b/hw/ppc/spapr_hcall.c @@ -1050,14 +1050,44 @@ static target_ulong h_cede(PowerPCCPU *cpu, SpaprMachineState *spapr, { CPUPPCState *env = &cpu->env; CPUState *cs = CPU(cpu); + SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu); env->msr |= (1ULL << MSR_EE); hreg_compute_hflags(env); + + if (spapr_cpu->prod) { + spapr_cpu->prod = false; + return H_SUCCESS; + } + if (!cpu_has_work(cs)) { cs->halted = 1; cs->exception_index = EXCP_HLT; cs->exit_request = 1; } + + return H_SUCCESS; +} + +static target_ulong h_prod(PowerPCCPU *cpu, SpaprMachineState *spapr, + target_ulong opcode, target_ulong *args) +{ + target_long target = args[0]; + PowerPCCPU *tcpu; + CPUState *cs; + SpaprCpuState *spapr_cpu; + + tcpu = spapr_find_cpu(target); + cs = CPU(tcpu); + if (!cs) { + return H_PARAMETER; + } + + spapr_cpu = spapr_cpu_state(tcpu); + spapr_cpu->prod = true; + cs->halted = 0; + qemu_cpu_kick(cs); + return H_SUCCESS; } @@ -1882,6 +1912,8 @@ static void hypercall_register_types(void) /* hcall-splpar */ spapr_register_hypercall(H_REGISTER_VPA, h_register_vpa); spapr_register_hypercall(H_CEDE, h_cede); + spapr_register_hypercall(H_PROD, h_prod); + spapr_register_hypercall(H_SIGNAL_SYS_RESET, h_signal_sys_reset); /* processor register resource access h-calls */ diff --git a/include/hw/ppc/spapr_cpu_core.h b/include/hw/ppc/spapr_cpu_core.h index f9645a7290..a40cd08ea0 100644 --- a/include/hw/ppc/spapr_cpu_core.h +++ b/include/hw/ppc/spapr_cpu_core.h @@ -46,6 +46,7 @@ typedef struct SpaprCpuState { uint64_t vpa_addr; uint64_t slb_shadow_addr, slb_shadow_size; uint64_t dtl_addr, dtl_size; + bool prod; /* not migrated, only used to improve dispatch latencies */ struct ICPState *icp; struct XiveTCTX *tctx; } SpaprCpuState;
H_PROD is added, and H_CEDE is modified to test the prod bit according to PAPR. Signed-off-by: Nicholas Piggin <npiggin@gmail.com> --- Changes since v5: - Add the prod bit here - Fix target CPU hw/ppc/spapr.c | 1 + hw/ppc/spapr_hcall.c | 32 ++++++++++++++++++++++++++++++++ include/hw/ppc/spapr_cpu_core.h | 1 + 3 files changed, 34 insertions(+)