From: Nicholas Piggin <npiggin@gmail.com>
To: David Gibson <david@gibson.dropbear.id.au>
Cc: "Nicholas Piggin" <npiggin@gmail.com>,
qemu-ppc@nongnu.org, qemu-devel@nongnu.org,
"Benjamin Herrenschmidt" <benh@kernel.crashing.org>,
"Cédric Le Goater" <clg@kaod.org>
Subject: [Qemu-devel] [PATCH] spapr: add splpar hcalls H_JOIN, H_PROD, H_CONFER
Date: Fri, 12 Apr 2019 15:42:13 +1000 [thread overview]
Message-ID: <20190412054214.707-1-npiggin@gmail.com> (raw)
These implementations have a few deficiencies that are noted, but are
good enough for Linux to use.
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
This has been tested with TCG with some Linux hacks to use H_JOIN/H_PROD
for suspend and CPU unplug (plus an implementation of ibm,suspend-me to
do the suspend). Not sure if KVM might need some more work to support
H_JOIN properly, but right now Linux only uses it on PowerVM.
hw/ppc/spapr_hcall.c | 84 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 84 insertions(+)
diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index 8a736797b9..6829cadcd3 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -1065,6 +1065,86 @@ static target_ulong h_cede(PowerPCCPU *cpu, SpaprMachineState *spapr,
return H_SUCCESS;
}
+static target_ulong h_join(PowerPCCPU *cpu, SpaprMachineState *spapr,
+ target_ulong opcode, target_ulong *args)
+{
+ CPUPPCState *env = &cpu->env;
+ CPUState *cs = CPU(cpu);
+
+ if (env->msr & (1ULL << MSR_EE))
+ return H_BAD_MODE;
+
+ /*
+ * This should check for single-threaded mode. In practice, Linux
+ * does not try to H_JOIN all CPUs.
+ */
+
+ cs->halted = 1;
+ cs->exception_index = EXCP_HALTED;
+ cs->exit_request = 1;
+
+ return H_SUCCESS;
+}
+
+static target_ulong h_confer(PowerPCCPU *cpu, SpaprMachineState *spapr,
+ target_ulong opcode, target_ulong *args)
+{
+ target_long target = args[0];
+ CPUState *cs = CPU(cpu);
+
+ /*
+ * This does not do a targeted yield or confer, but check the parameter
+ * anyway. -1 means confer to all/any other CPUs.
+ */
+ if (target != -1 && !CPU(spapr_find_cpu(target)))
+ return H_PARAMETER;
+
+ /*
+ * H_CONFER with target == this is not exactly the same as H_JOIN
+ * according to PAPR (e.g., MSR[EE] check and single threaded check
+ * is not done in this case), but unlikely to matter.
+ */
+ if (cpu == spapr_find_cpu(target))
+ return h_join(cpu, spapr, opcode, args);
+
+ /*
+ * This does not implement the dispatch sequence check that PAPR calls for,
+ * but PAPR also specifies a stronger implementation where the target must
+ * be run (or EE, or H_PROD) before H_CONFER returns. Without such a hard
+ * scheduling requirement implemented, there is no correctness reason to
+ * implement the dispatch sequence check.
+ */
+ cs->exception_index = EXCP_YIELD;
+ cpu_loop_exit(cs);
+
+ return H_SUCCESS;
+}
+
+/*
+ * H_PROD and H_CONFER are specified to only modify GPR r3, which is not
+ * achievable running under KVM, although KVM already implements H_CONFER
+ * this way.
+ */
+static target_ulong h_prod(PowerPCCPU *cpu, SpaprMachineState *spapr,
+ target_ulong opcode, target_ulong *args)
+{
+ target_long target = args[0];
+ CPUState *cs;
+
+ /*
+ * This does not maintain a prod flag for the vCPU that PAPR asks for.
+ */
+
+ cs = CPU(spapr_find_cpu(target));
+ if (!cs)
+ return H_PARAMETER;
+
+ cs->halted = 0;
+ qemu_cpu_kick(cs);
+
+ return H_SUCCESS;
+}
+
static target_ulong h_rtas(PowerPCCPU *cpu, SpaprMachineState *spapr,
target_ulong opcode, target_ulong *args)
{
@@ -1860,6 +1940,10 @@ 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_CONFER, h_confer);
+ spapr_register_hypercall(H_JOIN, h_join);
+ 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
WARNING: multiple messages have this Message-ID (diff)
From: Nicholas Piggin <npiggin@gmail.com>
To: David Gibson <david@gibson.dropbear.id.au>
Cc: qemu-ppc@nongnu.org, qemu-devel@nongnu.org,
"Nicholas Piggin" <npiggin@gmail.com>,
"Cédric Le Goater" <clg@kaod.org>
Subject: [Qemu-devel] [PATCH] spapr: add splpar hcalls H_JOIN, H_PROD, H_CONFER
Date: Fri, 12 Apr 2019 15:42:13 +1000 [thread overview]
Message-ID: <20190412054214.707-1-npiggin@gmail.com> (raw)
Message-ID: <20190412054213.HNjRdHxcekRENvnfiyX1AcHTTKPKrfQllTUOzfEEQhU@z> (raw)
These implementations have a few deficiencies that are noted, but are
good enough for Linux to use.
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
This has been tested with TCG with some Linux hacks to use H_JOIN/H_PROD
for suspend and CPU unplug (plus an implementation of ibm,suspend-me to
do the suspend). Not sure if KVM might need some more work to support
H_JOIN properly, but right now Linux only uses it on PowerVM.
hw/ppc/spapr_hcall.c | 84 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 84 insertions(+)
diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index 8a736797b9..6829cadcd3 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -1065,6 +1065,86 @@ static target_ulong h_cede(PowerPCCPU *cpu, SpaprMachineState *spapr,
return H_SUCCESS;
}
+static target_ulong h_join(PowerPCCPU *cpu, SpaprMachineState *spapr,
+ target_ulong opcode, target_ulong *args)
+{
+ CPUPPCState *env = &cpu->env;
+ CPUState *cs = CPU(cpu);
+
+ if (env->msr & (1ULL << MSR_EE))
+ return H_BAD_MODE;
+
+ /*
+ * This should check for single-threaded mode. In practice, Linux
+ * does not try to H_JOIN all CPUs.
+ */
+
+ cs->halted = 1;
+ cs->exception_index = EXCP_HALTED;
+ cs->exit_request = 1;
+
+ return H_SUCCESS;
+}
+
+static target_ulong h_confer(PowerPCCPU *cpu, SpaprMachineState *spapr,
+ target_ulong opcode, target_ulong *args)
+{
+ target_long target = args[0];
+ CPUState *cs = CPU(cpu);
+
+ /*
+ * This does not do a targeted yield or confer, but check the parameter
+ * anyway. -1 means confer to all/any other CPUs.
+ */
+ if (target != -1 && !CPU(spapr_find_cpu(target)))
+ return H_PARAMETER;
+
+ /*
+ * H_CONFER with target == this is not exactly the same as H_JOIN
+ * according to PAPR (e.g., MSR[EE] check and single threaded check
+ * is not done in this case), but unlikely to matter.
+ */
+ if (cpu == spapr_find_cpu(target))
+ return h_join(cpu, spapr, opcode, args);
+
+ /*
+ * This does not implement the dispatch sequence check that PAPR calls for,
+ * but PAPR also specifies a stronger implementation where the target must
+ * be run (or EE, or H_PROD) before H_CONFER returns. Without such a hard
+ * scheduling requirement implemented, there is no correctness reason to
+ * implement the dispatch sequence check.
+ */
+ cs->exception_index = EXCP_YIELD;
+ cpu_loop_exit(cs);
+
+ return H_SUCCESS;
+}
+
+/*
+ * H_PROD and H_CONFER are specified to only modify GPR r3, which is not
+ * achievable running under KVM, although KVM already implements H_CONFER
+ * this way.
+ */
+static target_ulong h_prod(PowerPCCPU *cpu, SpaprMachineState *spapr,
+ target_ulong opcode, target_ulong *args)
+{
+ target_long target = args[0];
+ CPUState *cs;
+
+ /*
+ * This does not maintain a prod flag for the vCPU that PAPR asks for.
+ */
+
+ cs = CPU(spapr_find_cpu(target));
+ if (!cs)
+ return H_PARAMETER;
+
+ cs->halted = 0;
+ qemu_cpu_kick(cs);
+
+ return H_SUCCESS;
+}
+
static target_ulong h_rtas(PowerPCCPU *cpu, SpaprMachineState *spapr,
target_ulong opcode, target_ulong *args)
{
@@ -1860,6 +1940,10 @@ 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_CONFER, h_confer);
+ spapr_register_hypercall(H_JOIN, h_join);
+ 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
next reply other threads:[~2019-04-12 5:42 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-04-12 5:42 Nicholas Piggin [this message]
2019-04-12 5:42 ` [Qemu-devel] [PATCH] spapr: add splpar hcalls H_JOIN, H_PROD, H_CONFER Nicholas Piggin
2019-04-12 5:46 ` no-reply
2019-04-12 5:46 ` 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=20190412054214.707-1-npiggin@gmail.com \
--to=npiggin@gmail.com \
--cc=benh@kernel.crashing.org \
--cc=clg@kaod.org \
--cc=david@gibson.dropbear.id.au \
--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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.