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>
---
hw/ppc/spapr_hcall.c | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index e615881ac4..8b208ab259 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -1050,14 +1050,41 @@ 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];
+ CPUState *cs;
+ SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
+
+ cs = CPU(spapr_find_cpu(target));
+ if (!cs) {
+ return H_PARAMETER;
+ }
+
+ spapr_cpu->prod = true;
+ cs->halted = 0;
+ qemu_cpu_kick(cs);
+
return H_SUCCESS;
}
@@ -1882,6 +1909,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 */
--
2.20.1
On 17/07/2019 07:39, Nicholas Piggin 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>
> ---
> hw/ppc/spapr_hcall.c | 29 +++++++++++++++++++++++++++++
> 1 file changed, 29 insertions(+)
>
> diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
> index e615881ac4..8b208ab259 100644
> --- a/hw/ppc/spapr_hcall.c
> +++ b/hw/ppc/spapr_hcall.c
> @@ -1050,14 +1050,41 @@ 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;
Shouldn't that be EXCP_HALTED instead ?
commit 1dd088946cf4 seems to say that h_cede is equivalent to the hlt
instruction on x86 but in 7 years things have changed.
C.
> 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];
> + CPUState *cs;
> + SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
> +
> + cs = CPU(spapr_find_cpu(target));
> + if (!cs) {
> + return H_PARAMETER;
> + }
> +
> + spapr_cpu->prod = true;
> + cs->halted = 0;
> + qemu_cpu_kick(cs);
> +
> return H_SUCCESS;
> }
>
> @@ -1882,6 +1909,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 */
>
Cédric Le Goater's on July 17, 2019 11:33 pm:
> On 17/07/2019 07:39, Nicholas Piggin 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>
>> ---
>> hw/ppc/spapr_hcall.c | 29 +++++++++++++++++++++++++++++
>> 1 file changed, 29 insertions(+)
>>
>> diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
>> index e615881ac4..8b208ab259 100644
>> --- a/hw/ppc/spapr_hcall.c
>> +++ b/hw/ppc/spapr_hcall.c
>> @@ -1050,14 +1050,41 @@ 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;
>
> Shouldn't that be EXCP_HALTED instead ?
Possibly, I'm not sure. I don't know if it even makes a difference in
ppc code?
Thanks,
Nick
On 17/07/2019 07:39, Nicholas Piggin 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>
> ---
> hw/ppc/spapr_hcall.c | 29 +++++++++++++++++++++++++++++
> 1 file changed, 29 insertions(+)
>
> diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
> index e615881ac4..8b208ab259 100644
> --- a/hw/ppc/spapr_hcall.c
> +++ b/hw/ppc/spapr_hcall.c
> @@ -1050,14 +1050,41 @@ 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];
> + CPUState *cs;
> + SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
shouldn't we grab the SpaprCpuState of 'target' instead ?
> + cs = CPU(spapr_find_cpu(target));
> + if (!cs) {
> + return H_PARAMETER;
> + }
> +
> + spapr_cpu->prod = true;
> + cs->halted = 0;
> + qemu_cpu_kick(cs);
> +
> return H_SUCCESS;
> }
>
> @@ -1882,6 +1909,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 */
>
Cédric Le Goater's on July 17, 2019 8:16 pm:
> On 17/07/2019 07:39, Nicholas Piggin 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>
>> ---
>> hw/ppc/spapr_hcall.c | 29 +++++++++++++++++++++++++++++
>> 1 file changed, 29 insertions(+)
>>
>> diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
>> index e615881ac4..8b208ab259 100644
>> --- a/hw/ppc/spapr_hcall.c
>> +++ b/hw/ppc/spapr_hcall.c
>> @@ -1050,14 +1050,41 @@ 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];
>> + CPUState *cs;
>> + SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
>
> shouldn't we grab the SpaprCpuState of 'target' instead ?
Yes we should, good catch.
Thanks,
Nick
© 2016 - 2026 Red Hat, Inc.