On Thu, 11 Apr 2019 08:34:08 +0200 Cédric Le Goater <c...@kaod.org> wrote:
> From: Benjamin Herrenschmidt <b...@kernel.crashing.org> > > H_PROD should be fully functional, H_CEDE is modified to > ignore a proded CPU. H_CONFER is a stub to avoid returning > an error. > > Signed-off-by: Benjamin Herrenschmidt <b...@kernel.crashing.org> > Signed-off-by: Cédric Le Goater <c...@kaod.org> > --- > target/ppc/cpu.h | 3 +++ > hw/ppc/spapr_hcall.c | 37 +++++++++++++++++++++++++++++++++++++ > 2 files changed, 40 insertions(+) > > diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h > index 42eadc4b7997..07cea7268c0c 100644 > --- a/target/ppc/cpu.h > +++ b/target/ppc/cpu.h > @@ -1141,6 +1141,9 @@ struct CPUPPCState { > * sreset), so flag this here. > */ > bool resume_as_sreset; > + > + /* Used by SPAPR for H_CEDE/H_PROD */ > + bool prodded; > #endif > > /* Those resources are used only during code translation */ > diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c > index 8a736797b9bf..be8044a92f2f 100644 > --- a/hw/ppc/spapr_hcall.c > +++ b/hw/ppc/spapr_hcall.c > @@ -1057,6 +1057,11 @@ static target_ulong h_cede(PowerPCCPU *cpu, > SpaprMachineState *spapr, > > env->msr |= (1ULL << MSR_EE); > hreg_compute_hflags(env); > + if (env->prodded) { > + env->prodded = false; > + return H_SUCCESS; > + } > + The "H_CEDE is modified to ignore a proded CPU" sentence in the changelog is slightly inaccurate since the "prod" bit is reset, as described in LoPAPR v1.1 14.11.3.3 H_CEDE. Appart from that LGTM. Reviewed-by: Greg Kurz <gr...@kaod.org> > if (!cpu_has_work(cs)) { > cs->halted = 1; > cs->exception_index = EXCP_HLT; > @@ -1065,6 +1070,36 @@ static target_ulong h_cede(PowerPCCPU *cpu, > SpaprMachineState *spapr, > return H_SUCCESS; > } > > +static void spapr_do_wakeup_on_cpu(CPUState *cs, run_on_cpu_data data) > +{ > + cs->halted = 0; > + cs->exception_index = -1; > +} > + > +static target_ulong h_prod(PowerPCCPU *cpu, SpaprMachineState *spapr, > + target_ulong opcode, target_ulong *args) > +{ > + target_ulong target = args[0]; > + CPUPPCState *env; > + > + cpu = spapr_find_cpu(target); > + if (cpu) { > + env = &cpu->env; > + env->prodded = true; > + run_on_cpu(CPU(cpu), spapr_do_wakeup_on_cpu, RUN_ON_CPU_NULL); > + } else { > + return H_PARAMETER; > + } > + return H_SUCCESS; > +} > + > +static target_ulong h_confer(PowerPCCPU *cpu, SpaprMachineState *spapr, > + target_ulong opcode, target_ulong *args) > +{ > + /* Do nothing (supposed to confer timeslice). */ > + return H_SUCCESS; > +} > + > static target_ulong h_rtas(PowerPCCPU *cpu, SpaprMachineState *spapr, > target_ulong opcode, target_ulong *args) > { > @@ -1860,6 +1895,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_CONFER, h_confer); > spapr_register_hypercall(H_SIGNAL_SYS_RESET, h_signal_sys_reset); > > /* processor register resource access h-calls */