* [Qemu-devel] [PATCH ppc-for-2.9] ppc/spapr: implement H_SIGNAL_SYS_RESET
@ 2016-12-05 5:50 Nicholas Piggin
2016-12-05 6:07 ` David Gibson
0 siblings, 1 reply; 2+ messages in thread
From: Nicholas Piggin @ 2016-12-05 5:50 UTC (permalink / raw)
To: David Gibson, qemu-devel, qemu-ppc
Cc: Nicholas Piggin, Thomas Huth, Greg Kurz
The H_SIGNAL_SYS_RESET hcall allows a guest CPU to raise a system reset
exception on CPUs within the same guest -- all CPUs, all-but-self, or a
specific CPU (including self).
This has not made its way to a PAPR release yet, but we have an hcall
number assigned.
H_SIGNAL_SYS_RESET = 0x380
Syntax:
hcall(uint64 H_SIGNAL_SYS_RESET, int64 target);
Generate a system reset NMI on the threads indicated by target.
Values for target:
-1 = target all online threads including the caller
-2 = target all online threads except for the caller
All other negative values: reserved
Positive values: The thread to be targeted, obtained from the value
of the "ibm,ppc-interrupt-server#s" property of the CPU in the OF
device tree.
Semantics:
- Invalid target: return H_Parameter.
- Otherwise: Generate a system reset NMI on target thread(s),
return H_Success.
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
hw/ppc/spapr.c | 4 ++--
hw/ppc/spapr_hcall.c | 41 +++++++++++++++++++++++++++++++++++++++++
include/hw/ppc/spapr.h | 5 ++++-
3 files changed, 47 insertions(+), 3 deletions(-)
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 684d1d4..b693ab5 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -2265,7 +2265,7 @@ static void spapr_machine_finalizefn(Object *obj)
g_free(spapr->kvm_type);
}
-static void ppc_cpu_do_nmi_on_cpu(CPUState *cs, run_on_cpu_data arg)
+void spapr_do_system_reset_on_cpu(CPUState *cs, run_on_cpu_data arg)
{
cpu_synchronize_state(cs);
ppc_cpu_do_system_reset(cs);
@@ -2276,7 +2276,7 @@ static void spapr_nmi(NMIState *n, int cpu_index, Error **errp)
CPUState *cs;
CPU_FOREACH(cs) {
- async_run_on_cpu(cs, ppc_cpu_do_nmi_on_cpu, RUN_ON_CPU_NULL);
+ async_run_on_cpu(cs, spapr_do_system_reset_on_cpu, RUN_ON_CPU_NULL);
}
}
diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index 35499ae..fd9f1d4 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -881,6 +881,46 @@ static target_ulong h_set_mode(PowerPCCPU *cpu, sPAPRMachineState *spapr,
return ret;
}
+#define H_SIGNAL_SYS_RESET_ALL -1
+#define H_SIGNAL_SYS_RESET_ALLBUTSELF -2
+
+static target_ulong h_signal_sys_reset(PowerPCCPU *cpu,
+ sPAPRMachineState *spapr,
+ target_ulong opcode, target_ulong *args)
+{
+ target_long target = args[0];
+ CPUState *cs;
+
+ if (target < 0) {
+ /* Broadcast */
+ if (target < H_SIGNAL_SYS_RESET_ALLBUTSELF) {
+ return H_PARAMETER;
+ }
+
+ CPU_FOREACH(cs) {
+ PowerPCCPU *c = POWERPC_CPU(cs);
+
+ if (target == H_SIGNAL_SYS_RESET_ALLBUTSELF) {
+ if (c == cpu) {
+ continue;
+ }
+ }
+ run_on_cpu(cs, spapr_do_system_reset_on_cpu, RUN_ON_CPU_NULL);
+ }
+ return H_SUCCESS;
+
+ } else {
+ /* Unicast */
+ CPU_FOREACH(cs) {
+ if (cpu->cpu_dt_id == target) {
+ run_on_cpu(cs, spapr_do_system_reset_on_cpu, RUN_ON_CPU_NULL);
+ return H_SUCCESS;
+ }
+ }
+ return H_PARAMETER;
+ }
+}
+
typedef struct {
uint32_t compat_pvr;
Error *err;
@@ -1097,6 +1137,7 @@ 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_SIGNAL_SYS_RESET, h_signal_sys_reset);
/* processor register resource access h-calls */
spapr_register_hypercall(H_SET_SPRG0, h_set_sprg0);
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index 04d2821..a2d8964 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -347,7 +347,8 @@ struct sPAPRMachineState {
#define H_XIRR_X 0x2FC
#define H_RANDOM 0x300
#define H_SET_MODE 0x31C
-#define MAX_HCALL_OPCODE H_SET_MODE
+#define H_SIGNAL_SYS_RESET 0x380
+#define MAX_HCALL_OPCODE H_SIGNAL_SYS_RESET
/* The hcalls above are standardized in PAPR and implemented by pHyp
* as well.
@@ -660,4 +661,6 @@ int spapr_rng_populate_dt(void *fdt);
#define SPAPR_LMB_FLAGS_DRC_INVALID 0x00000020
#define SPAPR_LMB_FLAGS_RESERVED 0x00000080
+void spapr_do_system_reset_on_cpu(CPUState *cs, run_on_cpu_data arg);
+
#endif /* HW_SPAPR_H */
--
2.10.2
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [Qemu-devel] [PATCH ppc-for-2.9] ppc/spapr: implement H_SIGNAL_SYS_RESET
2016-12-05 5:50 [Qemu-devel] [PATCH ppc-for-2.9] ppc/spapr: implement H_SIGNAL_SYS_RESET Nicholas Piggin
@ 2016-12-05 6:07 ` David Gibson
0 siblings, 0 replies; 2+ messages in thread
From: David Gibson @ 2016-12-05 6:07 UTC (permalink / raw)
To: Nicholas Piggin; +Cc: qemu-devel, qemu-ppc, Thomas Huth, Greg Kurz
[-- Attachment #1: Type: text/plain, Size: 5208 bytes --]
On Mon, Dec 05, 2016 at 04:50:21PM +1100, Nicholas Piggin wrote:
> The H_SIGNAL_SYS_RESET hcall allows a guest CPU to raise a system reset
> exception on CPUs within the same guest -- all CPUs, all-but-self, or a
> specific CPU (including self).
>
> This has not made its way to a PAPR release yet, but we have an hcall
> number assigned.
>
> H_SIGNAL_SYS_RESET = 0x380
>
> Syntax:
> hcall(uint64 H_SIGNAL_SYS_RESET, int64 target);
>
> Generate a system reset NMI on the threads indicated by target.
>
> Values for target:
> -1 = target all online threads including the caller
> -2 = target all online threads except for the caller
> All other negative values: reserved
> Positive values: The thread to be targeted, obtained from the value
> of the "ibm,ppc-interrupt-server#s" property of the CPU in the OF
> device tree.
>
> Semantics:
> - Invalid target: return H_Parameter.
> - Otherwise: Generate a system reset NMI on target thread(s),
> return H_Success.
>
> Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Applied to ppc-for-2.9, thanks.
> ---
> hw/ppc/spapr.c | 4 ++--
> hw/ppc/spapr_hcall.c | 41 +++++++++++++++++++++++++++++++++++++++++
> include/hw/ppc/spapr.h | 5 ++++-
> 3 files changed, 47 insertions(+), 3 deletions(-)
>
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index 684d1d4..b693ab5 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -2265,7 +2265,7 @@ static void spapr_machine_finalizefn(Object *obj)
> g_free(spapr->kvm_type);
> }
>
> -static void ppc_cpu_do_nmi_on_cpu(CPUState *cs, run_on_cpu_data arg)
> +void spapr_do_system_reset_on_cpu(CPUState *cs, run_on_cpu_data arg)
> {
> cpu_synchronize_state(cs);
> ppc_cpu_do_system_reset(cs);
> @@ -2276,7 +2276,7 @@ static void spapr_nmi(NMIState *n, int cpu_index, Error **errp)
> CPUState *cs;
>
> CPU_FOREACH(cs) {
> - async_run_on_cpu(cs, ppc_cpu_do_nmi_on_cpu, RUN_ON_CPU_NULL);
> + async_run_on_cpu(cs, spapr_do_system_reset_on_cpu, RUN_ON_CPU_NULL);
> }
> }
>
> diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
> index 35499ae..fd9f1d4 100644
> --- a/hw/ppc/spapr_hcall.c
> +++ b/hw/ppc/spapr_hcall.c
> @@ -881,6 +881,46 @@ static target_ulong h_set_mode(PowerPCCPU *cpu, sPAPRMachineState *spapr,
> return ret;
> }
>
> +#define H_SIGNAL_SYS_RESET_ALL -1
> +#define H_SIGNAL_SYS_RESET_ALLBUTSELF -2
> +
> +static target_ulong h_signal_sys_reset(PowerPCCPU *cpu,
> + sPAPRMachineState *spapr,
> + target_ulong opcode, target_ulong *args)
> +{
> + target_long target = args[0];
> + CPUState *cs;
> +
> + if (target < 0) {
> + /* Broadcast */
> + if (target < H_SIGNAL_SYS_RESET_ALLBUTSELF) {
> + return H_PARAMETER;
> + }
> +
> + CPU_FOREACH(cs) {
> + PowerPCCPU *c = POWERPC_CPU(cs);
> +
> + if (target == H_SIGNAL_SYS_RESET_ALLBUTSELF) {
> + if (c == cpu) {
> + continue;
> + }
> + }
> + run_on_cpu(cs, spapr_do_system_reset_on_cpu, RUN_ON_CPU_NULL);
> + }
> + return H_SUCCESS;
> +
> + } else {
> + /* Unicast */
> + CPU_FOREACH(cs) {
> + if (cpu->cpu_dt_id == target) {
> + run_on_cpu(cs, spapr_do_system_reset_on_cpu, RUN_ON_CPU_NULL);
> + return H_SUCCESS;
> + }
> + }
> + return H_PARAMETER;
> + }
> +}
> +
> typedef struct {
> uint32_t compat_pvr;
> Error *err;
> @@ -1097,6 +1137,7 @@ 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_SIGNAL_SYS_RESET, h_signal_sys_reset);
>
> /* processor register resource access h-calls */
> spapr_register_hypercall(H_SET_SPRG0, h_set_sprg0);
> diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
> index 04d2821..a2d8964 100644
> --- a/include/hw/ppc/spapr.h
> +++ b/include/hw/ppc/spapr.h
> @@ -347,7 +347,8 @@ struct sPAPRMachineState {
> #define H_XIRR_X 0x2FC
> #define H_RANDOM 0x300
> #define H_SET_MODE 0x31C
> -#define MAX_HCALL_OPCODE H_SET_MODE
> +#define H_SIGNAL_SYS_RESET 0x380
> +#define MAX_HCALL_OPCODE H_SIGNAL_SYS_RESET
>
> /* The hcalls above are standardized in PAPR and implemented by pHyp
> * as well.
> @@ -660,4 +661,6 @@ int spapr_rng_populate_dt(void *fdt);
> #define SPAPR_LMB_FLAGS_DRC_INVALID 0x00000020
> #define SPAPR_LMB_FLAGS_RESERVED 0x00000080
>
> +void spapr_do_system_reset_on_cpu(CPUState *cs, run_on_cpu_data arg);
> +
> #endif /* HW_SPAPR_H */
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2016-12-05 7:49 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-12-05 5:50 [Qemu-devel] [PATCH ppc-for-2.9] ppc/spapr: implement H_SIGNAL_SYS_RESET Nicholas Piggin
2016-12-05 6:07 ` David Gibson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).