From: Nicholas Piggin <npiggin@gmail.com>
To: David Gibson <david@gibson.dropbear.id.au>
Cc: "Greg Kurz" <groug@kaod.org>,
"Nicholas Piggin" <npiggin@gmail.com>,
qemu-devel@nongnu.org, qemu-ppc@nongnu.org,
"Cédric Le Goater" <clg@kaod.org>
Subject: [Qemu-devel] [PATCH v4 5/5] spapr: Implement ibm,suspend-me
Date: Tue, 16 Jul 2019 12:47:26 +1000 [thread overview]
Message-ID: <20190716024726.17864-6-npiggin@gmail.com> (raw)
In-Reply-To: <20190716024726.17864-1-npiggin@gmail.com>
This has been useful to modify and test the Linux pseries suspend
code but it requires modification to the guest to call it (due to
being gated by other unimplemented features). It is not otherwise
used by Linux yet, but work is slowly progressing there.
This allows a (lightly modified) guest kernel to suspend with
`echo mem > /sys/power/state` and be resumed with system_wakeup
monitor command.
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
hw/ppc/spapr.c | 26 ++++++++++++++++++++++++++
hw/ppc/spapr_rtas.c | 32 ++++++++++++++++++++++++++++++++
include/hw/ppc/spapr.h | 7 ++++++-
3 files changed, 64 insertions(+), 1 deletion(-)
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 5c54e1cb9a..b85d41bb1e 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1710,6 +1710,11 @@ static void spapr_machine_reset(MachineState *machine)
void *fdt;
int rc;
+ if (spapr->suspend_reset) {
+ spapr->suspend_reset = false;
+ return;
+ }
+
spapr_caps_apply(spapr);
first_ppc_cpu = POWERPC_CPU(first_cpu);
@@ -2721,6 +2726,23 @@ static PCIHostState *spapr_create_default_phb(void)
return PCI_HOST_BRIDGE(dev);
}
+static Notifier wakeup;
+static void spapr_notify_wakeup(Notifier *notifier, void *data)
+{
+ WakeupReason *reason = data;
+
+ switch (*reason) {
+ case QEMU_WAKEUP_REASON_RTC:
+ break;
+ case QEMU_WAKEUP_REASON_PMTIMER:
+ break;
+ case QEMU_WAKEUP_REASON_OTHER:
+ break;
+ default:
+ break;
+ }
+}
+
/* pSeries LPAR / sPAPR hardware init */
static void spapr_machine_init(MachineState *machine)
{
@@ -3078,6 +3100,10 @@ static void spapr_machine_init(MachineState *machine)
qemu_register_boot_set(spapr_boot_set, spapr);
+ wakeup.notify = spapr_notify_wakeup;
+ qemu_register_wakeup_notifier(&wakeup);
+ qemu_register_wakeup_support();
+
if (kvm_enabled()) {
/* to stop and start vmclock */
qemu_add_vm_change_state_handler(cpu_ppc_clock_vm_state_change,
diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
index a618a2ac0f..60a007ec38 100644
--- a/hw/ppc/spapr_rtas.c
+++ b/hw/ppc/spapr_rtas.c
@@ -216,6 +216,36 @@ static void rtas_stop_self(PowerPCCPU *cpu, SpaprMachineState *spapr,
qemu_cpu_kick(cs);
}
+static void rtas_ibm_suspend_me(PowerPCCPU *cpu, SpaprMachineState *spapr,
+ uint32_t token, uint32_t nargs,
+ target_ulong args,
+ uint32_t nret, target_ulong rets)
+{
+ CPUState *cs;
+
+ if (nargs != 0 || nret != 1) {
+ rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
+ return;
+ }
+
+ CPU_FOREACH(cs) {
+ PowerPCCPU *c = POWERPC_CPU(cs);
+ CPUPPCState *e = &c->env;
+ if (c == cpu)
+ continue;
+
+ /* See h_join */
+ if (!cs->halted || (e->msr & (1ULL << MSR_EE))) {
+ rtas_st(rets, 0, H_MULTI_THREADS_ACTIVE);
+ return;
+ }
+ }
+
+ spapr->suspend_reset = true;
+ qemu_system_suspend_request();
+ rtas_st(rets, 0, RTAS_OUT_SUCCESS);
+}
+
static inline int sysparm_st(target_ulong addr, target_ulong len,
const void *val, uint16_t vallen)
{
@@ -483,6 +513,8 @@ static void core_rtas_register_types(void)
rtas_query_cpu_stopped_state);
spapr_rtas_register(RTAS_START_CPU, "start-cpu", rtas_start_cpu);
spapr_rtas_register(RTAS_STOP_SELF, "stop-self", rtas_stop_self);
+ spapr_rtas_register(RTAS_IBM_SUSPEND_ME, "ibm,suspend-me",
+ rtas_ibm_suspend_me);
spapr_rtas_register(RTAS_IBM_GET_SYSTEM_PARAMETER,
"ibm,get-system-parameter",
rtas_ibm_get_system_parameter);
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index 5d36eec9d0..df0b0c15da 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -171,6 +171,10 @@ struct SpaprMachineState {
bool use_hotplug_event_source;
SpaprEventSource *event_sources;
+ /* Machine has been suspended, so the next machine_reset should not
+ * reset state, but just return and allow execution to resume. */
+ bool suspend_reset;
+
/* ibm,client-architecture-support option negotiation */
bool cas_reboot;
bool cas_legacy_guest_workaround;
@@ -631,8 +635,9 @@ target_ulong spapr_hypercall(PowerPCCPU *cpu, target_ulong opcode,
#define RTAS_IBM_CREATE_PE_DMA_WINDOW (RTAS_TOKEN_BASE + 0x27)
#define RTAS_IBM_REMOVE_PE_DMA_WINDOW (RTAS_TOKEN_BASE + 0x28)
#define RTAS_IBM_RESET_PE_DMA_WINDOW (RTAS_TOKEN_BASE + 0x29)
+#define RTAS_IBM_SUSPEND_ME (RTAS_TOKEN_BASE + 0x2A)
-#define RTAS_TOKEN_MAX (RTAS_TOKEN_BASE + 0x2A)
+#define RTAS_TOKEN_MAX (RTAS_TOKEN_BASE + 0x2B)
/* RTAS ibm,get-system-parameter token values */
#define RTAS_SYSPARM_SPLPAR_CHARACTERISTICS 20
--
2.20.1
next prev parent reply other threads:[~2019-07-16 2:48 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-07-16 2:47 [Qemu-devel] [PATCH v4 0/5] spapr: implement dispatch and suspend calls Nicholas Piggin
2019-07-16 2:47 ` [Qemu-devel] [PATCH v4 1/5] spapr: Implement dispatch counter and prod bit on tcg Nicholas Piggin
2019-07-16 7:34 ` David Gibson
2019-07-16 9:27 ` Nicholas Piggin
2019-07-17 1:51 ` David Gibson
2019-07-17 5:51 ` Nicholas Piggin
2019-07-16 2:47 ` [Qemu-devel] [PATCH v4 2/5] spapr: Implement H_PROD Nicholas Piggin
2019-07-16 8:22 ` David Gibson
2019-07-16 2:47 ` [Qemu-devel] [PATCH v4 3/5] spapr: Implement H_CONFER Nicholas Piggin
2019-07-16 8:25 ` David Gibson
2019-07-16 10:25 ` Nicholas Piggin
2019-07-17 1:51 ` David Gibson
2019-07-16 2:47 ` [Qemu-devel] [PATCH v4 4/5] spapr: Implement H_JOIN Nicholas Piggin
2019-07-16 8:26 ` David Gibson
2019-07-16 2:47 ` Nicholas Piggin [this message]
2019-07-16 8:30 ` [Qemu-devel] [PATCH v4 5/5] spapr: Implement ibm,suspend-me David Gibson
2019-07-16 11:15 ` Nicholas Piggin
2019-07-17 1:54 ` David Gibson
2019-07-16 2:55 ` [Qemu-devel] [PATCH v4 0/5] spapr: implement dispatch and suspend calls no-reply
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190716024726.17864-6-npiggin@gmail.com \
--to=npiggin@gmail.com \
--cc=clg@kaod.org \
--cc=david@gibson.dropbear.id.au \
--cc=groug@kaod.org \
--cc=qemu-devel@nongnu.org \
--cc=qemu-ppc@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).