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; + } + 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 */ -- 2.20.1