* [Qemu-devel] [PATCH 0/3] xics/kvm: Fix issues with older KVMs on POWER9 hosts
@ 2019-06-13 16:44 Greg Kurz
2019-06-13 16:44 ` [Qemu-devel] [PATCH 1/3] xics/spapr: Prevent RTAS/hypercalls emulation to be used by in-kernel XICS Greg Kurz
` (2 more replies)
0 siblings, 3 replies; 8+ messages in thread
From: Greg Kurz @ 2019-06-13 16:44 UTC (permalink / raw)
To: David Gibson; +Cc: qemu-devel, qemu-ppc, Cédric Le Goater, Greg Kurz
This series fixes various issues that can happen when running a spapr
machine on a POWER9 host and KVM doesn't have proper support to destroy
XICS-on-XIVE devices (ie, without the changes at [1]).
Patch 1 and 2 fix a QEMU crash that happens with the default settings, ie.
ic-mode=dual and kernel-irqchip is unspecified (ie, emulated fallback is
allowed).
Patch 3 allows to detect the same KVM limitation when passing
kernel-irqchip=on, and to error out early instead of exiting at
the next guest reboot.
--
Greg
[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=5422e95103cf9663bc86cf1056a3ea44c2e2f09e
---
Greg Kurz (3):
xics/spapr: Prevent RTAS/hypercalls emulation to be used by in-kernel XICS
xics/spapr: Register RTAS/hypercalls once at machine init
xics/spapr: Detect old KVM XICS on POWER9 hosts
docs/specs/ppc-spapr-xive.rst | 4 ++-
hw/intc/xics_kvm.c | 49 +++++++++++++++++++++++--------------
hw/intc/xics_spapr.c | 54 +++++++++++++++++++++++++++++++++++------
hw/ppc/spapr_irq.c | 16 +++++++++++-
include/hw/ppc/spapr.h | 4 ---
include/hw/ppc/xics.h | 1 -
include/hw/ppc/xics_spapr.h | 2 ++
7 files changed, 95 insertions(+), 35 deletions(-)
^ permalink raw reply [flat|nested] 8+ messages in thread
* [Qemu-devel] [PATCH 1/3] xics/spapr: Prevent RTAS/hypercalls emulation to be used by in-kernel XICS
2019-06-13 16:44 [Qemu-devel] [PATCH 0/3] xics/kvm: Fix issues with older KVMs on POWER9 hosts Greg Kurz
@ 2019-06-13 16:44 ` Greg Kurz
2019-06-14 1:34 ` David Gibson
2019-06-13 16:44 ` [Qemu-devel] [PATCH 2/3] xics/spapr: Register RTAS/hypercalls once at machine init Greg Kurz
2019-06-13 16:45 ` [Qemu-devel] [PATCH 3/3] xics/spapr: Detect old KVM XICS on POWER9 hosts Greg Kurz
2 siblings, 1 reply; 8+ messages in thread
From: Greg Kurz @ 2019-06-13 16:44 UTC (permalink / raw)
To: David Gibson; +Cc: qemu-devel, qemu-ppc, Cédric Le Goater, Greg Kurz
The XICS-related RTAS calls and hypercalls in QEMU are supposed to be
called only when the KVM in-kernel XICS is in use.
Add some explicit checks to detect that, print an error message and report
an hardware error to the guest.
Signed-off-by: Greg Kurz <groug@kaod.org>
---
hw/intc/xics_spapr.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 46 insertions(+)
diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
index 5a1835e8b1ed..d470ab5f7a2a 100644
--- a/hw/intc/xics_spapr.c
+++ b/hw/intc/xics_spapr.c
@@ -41,11 +41,31 @@
* Guest interfaces
*/
+static bool check_in_kernel_xics(const char *func)
+{
+ if (kvm_irqchip_in_kernel()) {
+ error_report("pseries: %s must never be called for in-kernel XICS",
+ func);
+ return true;
+ }
+
+ return false;
+}
+
+#define CHECK_IN_KERNEL_XICS_HCALL \
+ do { \
+ if (check_in_kernel_xics(__func__)) { \
+ return H_HARDWARE; \
+ } \
+ } while (0)
+
static target_ulong h_cppr(PowerPCCPU *cpu, SpaprMachineState *spapr,
target_ulong opcode, target_ulong *args)
{
target_ulong cppr = args[0];
+ CHECK_IN_KERNEL_XICS_HCALL;
+
icp_set_cppr(spapr_cpu_state(cpu)->icp, cppr);
return H_SUCCESS;
}
@@ -56,6 +76,8 @@ static target_ulong h_ipi(PowerPCCPU *cpu, SpaprMachineState *spapr,
target_ulong mfrr = args[1];
ICPState *icp = xics_icp_get(XICS_FABRIC(spapr), args[0]);
+ CHECK_IN_KERNEL_XICS_HCALL;
+
if (!icp) {
return H_PARAMETER;
}
@@ -69,6 +91,8 @@ static target_ulong h_xirr(PowerPCCPU *cpu, SpaprMachineState *spapr,
{
uint32_t xirr = icp_accept(spapr_cpu_state(cpu)->icp);
+ CHECK_IN_KERNEL_XICS_HCALL;
+
args[0] = xirr;
return H_SUCCESS;
}
@@ -78,6 +102,8 @@ static target_ulong h_xirr_x(PowerPCCPU *cpu, SpaprMachineState *spapr,
{
uint32_t xirr = icp_accept(spapr_cpu_state(cpu)->icp);
+ CHECK_IN_KERNEL_XICS_HCALL;
+
args[0] = xirr;
args[1] = cpu_get_host_ticks();
return H_SUCCESS;
@@ -88,6 +114,8 @@ static target_ulong h_eoi(PowerPCCPU *cpu, SpaprMachineState *spapr,
{
target_ulong xirr = args[0];
+ CHECK_IN_KERNEL_XICS_HCALL;
+
icp_eoi(spapr_cpu_state(cpu)->icp, xirr);
return H_SUCCESS;
}
@@ -99,6 +127,8 @@ static target_ulong h_ipoll(PowerPCCPU *cpu, SpaprMachineState *spapr,
uint32_t mfrr;
uint32_t xirr;
+ CHECK_IN_KERNEL_XICS_HCALL;
+
if (!icp) {
return H_PARAMETER;
}
@@ -111,6 +141,14 @@ static target_ulong h_ipoll(PowerPCCPU *cpu, SpaprMachineState *spapr,
return H_SUCCESS;
}
+#define CHECK_IN_KERNEL_XICS_RTAS(rets) \
+ do { \
+ if (check_in_kernel_xics(__func__)) { \
+ rtas_st((rets), 0, RTAS_OUT_HW_ERROR); \
+ return; \
+ } \
+ } while (0)
+
static void rtas_set_xive(PowerPCCPU *cpu, SpaprMachineState *spapr,
uint32_t token,
uint32_t nargs, target_ulong args,
@@ -119,6 +157,8 @@ static void rtas_set_xive(PowerPCCPU *cpu, SpaprMachineState *spapr,
ICSState *ics = spapr->ics;
uint32_t nr, srcno, server, priority;
+ CHECK_IN_KERNEL_XICS_RTAS(rets);
+
if ((nargs != 3) || (nret != 1)) {
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
return;
@@ -152,6 +192,8 @@ static void rtas_get_xive(PowerPCCPU *cpu, SpaprMachineState *spapr,
ICSState *ics = spapr->ics;
uint32_t nr, srcno;
+ CHECK_IN_KERNEL_XICS_RTAS(rets);
+
if ((nargs != 1) || (nret != 3)) {
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
return;
@@ -182,6 +224,8 @@ static void rtas_int_off(PowerPCCPU *cpu, SpaprMachineState *spapr,
ICSState *ics = spapr->ics;
uint32_t nr, srcno;
+ CHECK_IN_KERNEL_XICS_RTAS(rets);
+
if ((nargs != 1) || (nret != 1)) {
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
return;
@@ -213,6 +257,8 @@ static void rtas_int_on(PowerPCCPU *cpu, SpaprMachineState *spapr,
ICSState *ics = spapr->ics;
uint32_t nr, srcno;
+ CHECK_IN_KERNEL_XICS_RTAS(rets);
+
if ((nargs != 1) || (nret != 1)) {
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
return;
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [Qemu-devel] [PATCH 2/3] xics/spapr: Register RTAS/hypercalls once at machine init
2019-06-13 16:44 [Qemu-devel] [PATCH 0/3] xics/kvm: Fix issues with older KVMs on POWER9 hosts Greg Kurz
2019-06-13 16:44 ` [Qemu-devel] [PATCH 1/3] xics/spapr: Prevent RTAS/hypercalls emulation to be used by in-kernel XICS Greg Kurz
@ 2019-06-13 16:44 ` Greg Kurz
2019-06-14 1:38 ` David Gibson
2019-06-13 16:45 ` [Qemu-devel] [PATCH 3/3] xics/spapr: Detect old KVM XICS on POWER9 hosts Greg Kurz
2 siblings, 1 reply; 8+ messages in thread
From: Greg Kurz @ 2019-06-13 16:44 UTC (permalink / raw)
To: David Gibson; +Cc: qemu-devel, qemu-ppc, Cédric Le Goater, Greg Kurz
QEMU may crash when running a spapr machine in 'dual' interrupt controller
mode on some older (but not that old, eg. ubuntu 18.04.2) KVMs with partial
XIVE support:
qemu-system-ppc64: hw/ppc/spapr_rtas.c:411: spapr_rtas_register:
Assertion `!name || !rtas_table[token].name' failed.
XICS is controlled by the guest thanks to a set of RTAS calls. Depending
on whether KVM XICS is used or not, the RTAS calls are handled by KVM or
QEMU. In both cases, QEMU needs to expose the RTAS calls to the guest
through the "rtas" node of the device tree.
The spapr_rtas_register() helper takes care of all of that: it adds the
RTAS call token to the "rtas" node and registers a QEMU callback to be
invoked when the guest issues the RTAS call. In the KVM XICS case, QEMU
registers a dummy callback that just prints an error since it isn't
supposed to be invoked, ever.
Historically, the XICS controller was setup during machine init and
released during final teardown. This changed when the 'dual' interrupt
controller mode was added to the spapr machine: in this case we need
to tear the XICS down and set it up again during machine reset. The
crash happens because we indeed have an incompatibility with older
KVMs that forces QEMU to fallback on emulated XICS, which tries to
re-registers the same RTAS calls.
This could be fixed by adding proper rollback that would unregister
RTAS calls on error. But since the emulated RTAS calls in QEMU can
now detect when they are mistakenly called while KVM XICS is in
use, it seems simpler to register them once and for all at machine
init. This fixes the crash and allows to remove some now useless
lines of code.
Signed-off-by: Greg Kurz <groug@kaod.org>
---
hw/intc/xics_kvm.c | 19 -------------------
hw/intc/xics_spapr.c | 8 --------
hw/ppc/spapr_irq.c | 3 ++-
include/hw/ppc/spapr.h | 4 ----
include/hw/ppc/xics.h | 1 -
include/hw/ppc/xics_spapr.h | 1 +
6 files changed, 3 insertions(+), 33 deletions(-)
diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c
index 5ba5b775615e..5c4208f43008 100644
--- a/hw/intc/xics_kvm.c
+++ b/hw/intc/xics_kvm.c
@@ -331,15 +331,6 @@ void ics_kvm_set_irq(ICSState *ics, int srcno, int val)
}
}
-static void rtas_dummy(PowerPCCPU *cpu, SpaprMachineState *spapr,
- uint32_t token,
- uint32_t nargs, target_ulong args,
- uint32_t nret, target_ulong rets)
-{
- error_report("pseries: %s must never be called for in-kernel XICS",
- __func__);
-}
-
int xics_kvm_init(SpaprMachineState *spapr, Error **errp)
{
int rc;
@@ -360,11 +351,6 @@ int xics_kvm_init(SpaprMachineState *spapr, Error **errp)
goto fail;
}
- spapr_rtas_register(RTAS_IBM_SET_XIVE, "ibm,set-xive", rtas_dummy);
- spapr_rtas_register(RTAS_IBM_GET_XIVE, "ibm,get-xive", rtas_dummy);
- spapr_rtas_register(RTAS_IBM_INT_OFF, "ibm,int-off", rtas_dummy);
- spapr_rtas_register(RTAS_IBM_INT_ON, "ibm,int-on", rtas_dummy);
-
rc = kvmppc_define_rtas_kernel_token(RTAS_IBM_SET_XIVE, "ibm,set-xive");
if (rc < 0) {
error_setg(errp, "kvmppc_define_rtas_kernel_token: ibm,set-xive");
@@ -454,11 +440,6 @@ void xics_kvm_disconnect(SpaprMachineState *spapr, Error **errp)
close(kernel_xics_fd);
kernel_xics_fd = -1;
- spapr_rtas_unregister(RTAS_IBM_SET_XIVE);
- spapr_rtas_unregister(RTAS_IBM_GET_XIVE);
- spapr_rtas_unregister(RTAS_IBM_INT_OFF);
- spapr_rtas_unregister(RTAS_IBM_INT_ON);
-
kvmppc_define_rtas_kernel_token(0, "ibm,set-xive");
kvmppc_define_rtas_kernel_token(0, "ibm,get-xive");
kvmppc_define_rtas_kernel_token(0, "ibm,int-on");
diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
index d470ab5f7a2a..8d605b68a7a0 100644
--- a/hw/intc/xics_spapr.c
+++ b/hw/intc/xics_spapr.c
@@ -285,14 +285,6 @@ static void rtas_int_on(PowerPCCPU *cpu, SpaprMachineState *spapr,
void xics_spapr_init(SpaprMachineState *spapr)
{
- /* Emulated mode can only be initialized once. */
- if (spapr->ics->init) {
- return;
- }
-
- spapr->ics->init = true;
-
- /* Registration of global state belongs into realize */
spapr_rtas_register(RTAS_IBM_SET_XIVE, "ibm,set-xive", rtas_set_xive);
spapr_rtas_register(RTAS_IBM_GET_XIVE, "ibm,get-xive", rtas_get_xive);
spapr_rtas_register(RTAS_IBM_INT_OFF, "ibm,int-off", rtas_int_off);
diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index 3156daf09381..dfb99f35ea00 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -114,6 +114,8 @@ static void spapr_irq_init_xics(SpaprMachineState *spapr, int nr_irqs,
}
spapr->ics = ICS_BASE(obj);
+
+ xics_spapr_init(spapr);
}
#define ICS_IRQ_FREE(ics, srcno) \
@@ -236,7 +238,6 @@ static const char *spapr_irq_get_nodename_xics(SpaprMachineState *spapr)
static void spapr_irq_init_emu_xics(SpaprMachineState *spapr, Error **errp)
{
- xics_spapr_init(spapr);
}
static void spapr_irq_init_kvm_xics(SpaprMachineState *spapr, Error **errp)
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index 4f5becf1f3cc..60553d32c4fa 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -676,10 +676,6 @@ typedef void (*spapr_rtas_fn)(PowerPCCPU *cpu, SpaprMachineState *sm,
uint32_t nargs, target_ulong args,
uint32_t nret, target_ulong rets);
void spapr_rtas_register(int token, const char *name, spapr_rtas_fn fn);
-static inline void spapr_rtas_unregister(int token)
-{
- spapr_rtas_register(token, NULL, NULL);
-}
target_ulong spapr_rtas_call(PowerPCCPU *cpu, SpaprMachineState *sm,
uint32_t token, uint32_t nargs, target_ulong args,
uint32_t nret, target_ulong rets);
diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
index d6f8e4c4c282..eb65ad7e43b7 100644
--- a/include/hw/ppc/xics.h
+++ b/include/hw/ppc/xics.h
@@ -119,7 +119,6 @@ struct ICSState {
uint32_t offset;
ICSIRQState *irqs;
XICSFabric *xics;
- bool init; /* sPAPR ICS device initialized */
};
#define ICS_PROP_XICS "xics"
diff --git a/include/hw/ppc/xics_spapr.h b/include/hw/ppc/xics_spapr.h
index 2476b540edfa..6c1d9ee55945 100644
--- a/include/hw/ppc/xics_spapr.h
+++ b/include/hw/ppc/xics_spapr.h
@@ -36,5 +36,6 @@ void spapr_dt_xics(SpaprMachineState *spapr, uint32_t nr_servers, void *fdt,
int xics_kvm_init(SpaprMachineState *spapr, Error **errp);
void xics_kvm_disconnect(SpaprMachineState *spapr, Error **errp);
void xics_spapr_init(SpaprMachineState *spapr);
+void xics_spapr_connect(SpaprMachineState *spapr);
#endif /* XICS_SPAPR_H */
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [Qemu-devel] [PATCH 3/3] xics/spapr: Detect old KVM XICS on POWER9 hosts
2019-06-13 16:44 [Qemu-devel] [PATCH 0/3] xics/kvm: Fix issues with older KVMs on POWER9 hosts Greg Kurz
2019-06-13 16:44 ` [Qemu-devel] [PATCH 1/3] xics/spapr: Prevent RTAS/hypercalls emulation to be used by in-kernel XICS Greg Kurz
2019-06-13 16:44 ` [Qemu-devel] [PATCH 2/3] xics/spapr: Register RTAS/hypercalls once at machine init Greg Kurz
@ 2019-06-13 16:45 ` Greg Kurz
2019-06-14 1:40 ` David Gibson
2 siblings, 1 reply; 8+ messages in thread
From: Greg Kurz @ 2019-06-13 16:45 UTC (permalink / raw)
To: David Gibson; +Cc: qemu-devel, qemu-ppc, Cédric Le Goater, Greg Kurz
Older KVMs on POWER9 don't support destroying/recreating a KVM XICS
device, which is required by 'dual' interrupt controller mode. This
causes QEMU to emit a warning when the guest is rebooted and to fall
back on XICS emulation:
qemu-system-ppc64: warning: kernel_irqchip allowed but unavailable:
Error on KVM_CREATE_DEVICE for XICS: File exists
If kernel irqchip is required, QEMU will thus exit when the guest is
first rebooted. Failing QEMU this late may be a painful experience
for the user.
Detect that and exit at machine init instead.
Signed-off-by: Greg Kurz <groug@kaod.org>
---
docs/specs/ppc-spapr-xive.rst | 4 ++--
hw/intc/xics_kvm.c | 30 ++++++++++++++++++++++++++++++
hw/ppc/spapr_irq.c | 13 +++++++++++++
include/hw/ppc/xics_spapr.h | 1 +
4 files changed, 46 insertions(+), 2 deletions(-)
diff --git a/docs/specs/ppc-spapr-xive.rst b/docs/specs/ppc-spapr-xive.rst
index 7a64c9d04951..6159bc6eed62 100644
--- a/docs/specs/ppc-spapr-xive.rst
+++ b/docs/specs/ppc-spapr-xive.rst
@@ -142,8 +142,8 @@ xics XICS KVM XICS emul. XICS KVM
(3) QEMU fails at CAS with ``Guest requested unavailable interrupt
mode (XICS), either don't set the ic-mode machine property or try
ic-mode=xics or ic-mode=dual``
-(4) QEMU/KVM incompatibility due to device destruction in reset. This
- needs to be addressed more cleanly with an error.
+(4) QEMU/KVM incompatibility due to device destruction in reset. QEMU fails
+ with ``KVM is too old to support ic-mode=dual,kernel-irqchip=on``
XIVE Device tree properties
diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c
index 5c4208f43008..c7f8f5edd257 100644
--- a/hw/intc/xics_kvm.c
+++ b/hw/intc/xics_kvm.c
@@ -452,3 +452,33 @@ void xics_kvm_disconnect(SpaprMachineState *spapr, Error **errp)
/* Clear the presenter from the VCPUs */
kvm_disable_icps();
}
+
+/*
+ * This is a heuristic to detect older KVMs on POWER9 hosts that don't
+ * support destruction of a KVM XICS device while the VM is running.
+ * Required to start a spapr machine with ic-mode=dual,kernel-irqchip=on.
+ */
+bool xics_kvm_has_broken_disconnect(SpaprMachineState *spapr)
+{
+ int rc;
+
+ rc = kvm_create_device(kvm_state, KVM_DEV_TYPE_XICS, false);
+ if (rc < 0) {
+ /*
+ * The error is ignored on purpose. The KVM XICS setup code
+ * will catch it again anyway. The goal here is to see if
+ * close() actually destroys the device or not.
+ */
+ return false;
+ }
+
+ close(rc);
+
+ rc = kvm_create_device(kvm_state, KVM_DEV_TYPE_XICS, false);
+ if (rc >= 0) {
+ close(rc);
+ return false;
+ }
+
+ return errno == EEXIST;
+}
diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index dfb99f35ea00..75654fc67aba 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -669,6 +669,19 @@ static void spapr_irq_check(SpaprMachineState *spapr, Error **errp)
return;
}
}
+
+ /*
+ * On a POWER9 host, some older KVM XICS devices cannot be destroyed and
+ * re-created. Detect that early to avoid QEMU to exit later when the
+ * guest reboots.
+ */
+ if (kvm_enabled() &&
+ spapr->irq == &spapr_irq_dual &&
+ machine_kernel_irqchip_required(machine) &&
+ xics_kvm_has_broken_disconnect(spapr)) {
+ error_setg(errp, "KVM is too old to support ic-mode=dual,kernel-irqchip=on");
+ return;
+ }
}
/*
diff --git a/include/hw/ppc/xics_spapr.h b/include/hw/ppc/xics_spapr.h
index 6c1d9ee55945..d968f2499ca7 100644
--- a/include/hw/ppc/xics_spapr.h
+++ b/include/hw/ppc/xics_spapr.h
@@ -35,6 +35,7 @@ void spapr_dt_xics(SpaprMachineState *spapr, uint32_t nr_servers, void *fdt,
uint32_t phandle);
int xics_kvm_init(SpaprMachineState *spapr, Error **errp);
void xics_kvm_disconnect(SpaprMachineState *spapr, Error **errp);
+bool xics_kvm_has_broken_disconnect(SpaprMachineState *spapr);
void xics_spapr_init(SpaprMachineState *spapr);
void xics_spapr_connect(SpaprMachineState *spapr);
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [Qemu-devel] [PATCH 1/3] xics/spapr: Prevent RTAS/hypercalls emulation to be used by in-kernel XICS
2019-06-13 16:44 ` [Qemu-devel] [PATCH 1/3] xics/spapr: Prevent RTAS/hypercalls emulation to be used by in-kernel XICS Greg Kurz
@ 2019-06-14 1:34 ` David Gibson
2019-06-14 5:37 ` Greg Kurz
0 siblings, 1 reply; 8+ messages in thread
From: David Gibson @ 2019-06-14 1:34 UTC (permalink / raw)
To: Greg Kurz; +Cc: qemu-ppc, Cédric Le Goater, qemu-devel
[-- Attachment #1: Type: text/plain, Size: 5296 bytes --]
On Thu, Jun 13, 2019 at 06:44:54PM +0200, Greg Kurz wrote:
> The XICS-related RTAS calls and hypercalls in QEMU are supposed to be
> called only when the KVM in-kernel XICS is in use.
I've applied this, but reversed the sense of the sentence above, which
appears to be the intent.
>
> Add some explicit checks to detect that, print an error message and report
> an hardware error to the guest.
>
> Signed-off-by: Greg Kurz <groug@kaod.org>
> ---
> hw/intc/xics_spapr.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 46 insertions(+)
>
> diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
> index 5a1835e8b1ed..d470ab5f7a2a 100644
> --- a/hw/intc/xics_spapr.c
> +++ b/hw/intc/xics_spapr.c
> @@ -41,11 +41,31 @@
> * Guest interfaces
> */
>
> +static bool check_in_kernel_xics(const char *func)
> +{
> + if (kvm_irqchip_in_kernel()) {
> + error_report("pseries: %s must never be called for in-kernel XICS",
> + func);
> + return true;
> + }
> +
> + return false;
> +}
> +
> +#define CHECK_IN_KERNEL_XICS_HCALL \
> + do { \
> + if (check_in_kernel_xics(__func__)) { \
> + return H_HARDWARE; \
> + } \
> + } while (0)
> +
> static target_ulong h_cppr(PowerPCCPU *cpu, SpaprMachineState *spapr,
> target_ulong opcode, target_ulong *args)
> {
> target_ulong cppr = args[0];
>
> + CHECK_IN_KERNEL_XICS_HCALL;
> +
> icp_set_cppr(spapr_cpu_state(cpu)->icp, cppr);
> return H_SUCCESS;
> }
> @@ -56,6 +76,8 @@ static target_ulong h_ipi(PowerPCCPU *cpu, SpaprMachineState *spapr,
> target_ulong mfrr = args[1];
> ICPState *icp = xics_icp_get(XICS_FABRIC(spapr), args[0]);
>
> + CHECK_IN_KERNEL_XICS_HCALL;
> +
> if (!icp) {
> return H_PARAMETER;
> }
> @@ -69,6 +91,8 @@ static target_ulong h_xirr(PowerPCCPU *cpu, SpaprMachineState *spapr,
> {
> uint32_t xirr = icp_accept(spapr_cpu_state(cpu)->icp);
>
> + CHECK_IN_KERNEL_XICS_HCALL;
> +
> args[0] = xirr;
> return H_SUCCESS;
> }
> @@ -78,6 +102,8 @@ static target_ulong h_xirr_x(PowerPCCPU *cpu, SpaprMachineState *spapr,
> {
> uint32_t xirr = icp_accept(spapr_cpu_state(cpu)->icp);
>
> + CHECK_IN_KERNEL_XICS_HCALL;
> +
> args[0] = xirr;
> args[1] = cpu_get_host_ticks();
> return H_SUCCESS;
> @@ -88,6 +114,8 @@ static target_ulong h_eoi(PowerPCCPU *cpu, SpaprMachineState *spapr,
> {
> target_ulong xirr = args[0];
>
> + CHECK_IN_KERNEL_XICS_HCALL;
> +
> icp_eoi(spapr_cpu_state(cpu)->icp, xirr);
> return H_SUCCESS;
> }
> @@ -99,6 +127,8 @@ static target_ulong h_ipoll(PowerPCCPU *cpu, SpaprMachineState *spapr,
> uint32_t mfrr;
> uint32_t xirr;
>
> + CHECK_IN_KERNEL_XICS_HCALL;
> +
> if (!icp) {
> return H_PARAMETER;
> }
> @@ -111,6 +141,14 @@ static target_ulong h_ipoll(PowerPCCPU *cpu, SpaprMachineState *spapr,
> return H_SUCCESS;
> }
>
> +#define CHECK_IN_KERNEL_XICS_RTAS(rets) \
> + do { \
> + if (check_in_kernel_xics(__func__)) { \
> + rtas_st((rets), 0, RTAS_OUT_HW_ERROR); \
> + return; \
> + } \
> + } while (0)
> +
> static void rtas_set_xive(PowerPCCPU *cpu, SpaprMachineState *spapr,
> uint32_t token,
> uint32_t nargs, target_ulong args,
> @@ -119,6 +157,8 @@ static void rtas_set_xive(PowerPCCPU *cpu, SpaprMachineState *spapr,
> ICSState *ics = spapr->ics;
> uint32_t nr, srcno, server, priority;
>
> + CHECK_IN_KERNEL_XICS_RTAS(rets);
> +
> if ((nargs != 3) || (nret != 1)) {
> rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
> return;
> @@ -152,6 +192,8 @@ static void rtas_get_xive(PowerPCCPU *cpu, SpaprMachineState *spapr,
> ICSState *ics = spapr->ics;
> uint32_t nr, srcno;
>
> + CHECK_IN_KERNEL_XICS_RTAS(rets);
> +
> if ((nargs != 1) || (nret != 3)) {
> rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
> return;
> @@ -182,6 +224,8 @@ static void rtas_int_off(PowerPCCPU *cpu, SpaprMachineState *spapr,
> ICSState *ics = spapr->ics;
> uint32_t nr, srcno;
>
> + CHECK_IN_KERNEL_XICS_RTAS(rets);
> +
> if ((nargs != 1) || (nret != 1)) {
> rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
> return;
> @@ -213,6 +257,8 @@ static void rtas_int_on(PowerPCCPU *cpu, SpaprMachineState *spapr,
> ICSState *ics = spapr->ics;
> uint32_t nr, srcno;
>
> + CHECK_IN_KERNEL_XICS_RTAS(rets);
> +
> if ((nargs != 1) || (nret != 1)) {
> rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
> return;
>
--
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: 833 bytes --]
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [Qemu-devel] [PATCH 2/3] xics/spapr: Register RTAS/hypercalls once at machine init
2019-06-13 16:44 ` [Qemu-devel] [PATCH 2/3] xics/spapr: Register RTAS/hypercalls once at machine init Greg Kurz
@ 2019-06-14 1:38 ` David Gibson
0 siblings, 0 replies; 8+ messages in thread
From: David Gibson @ 2019-06-14 1:38 UTC (permalink / raw)
To: Greg Kurz; +Cc: qemu-ppc, Cédric Le Goater, qemu-devel
[-- Attachment #1: Type: text/plain, Size: 7506 bytes --]
On Thu, Jun 13, 2019 at 06:44:59PM +0200, Greg Kurz wrote:
> QEMU may crash when running a spapr machine in 'dual' interrupt controller
> mode on some older (but not that old, eg. ubuntu 18.04.2) KVMs with partial
> XIVE support:
>
> qemu-system-ppc64: hw/ppc/spapr_rtas.c:411: spapr_rtas_register:
> Assertion `!name || !rtas_table[token].name' failed.
>
> XICS is controlled by the guest thanks to a set of RTAS calls. Depending
> on whether KVM XICS is used or not, the RTAS calls are handled by KVM or
> QEMU. In both cases, QEMU needs to expose the RTAS calls to the guest
> through the "rtas" node of the device tree.
>
> The spapr_rtas_register() helper takes care of all of that: it adds the
> RTAS call token to the "rtas" node and registers a QEMU callback to be
> invoked when the guest issues the RTAS call. In the KVM XICS case, QEMU
> registers a dummy callback that just prints an error since it isn't
> supposed to be invoked, ever.
>
> Historically, the XICS controller was setup during machine init and
> released during final teardown. This changed when the 'dual' interrupt
> controller mode was added to the spapr machine: in this case we need
> to tear the XICS down and set it up again during machine reset. The
> crash happens because we indeed have an incompatibility with older
> KVMs that forces QEMU to fallback on emulated XICS, which tries to
> re-registers the same RTAS calls.
>
> This could be fixed by adding proper rollback that would unregister
> RTAS calls on error. But since the emulated RTAS calls in QEMU can
> now detect when they are mistakenly called while KVM XICS is in
> use, it seems simpler to register them once and for all at machine
> init. This fixes the crash and allows to remove some now useless
> lines of code.
>
> Signed-off-by: Greg Kurz <groug@kaod.org>
Applied, thanks.
> ---
> hw/intc/xics_kvm.c | 19 -------------------
> hw/intc/xics_spapr.c | 8 --------
> hw/ppc/spapr_irq.c | 3 ++-
> include/hw/ppc/spapr.h | 4 ----
> include/hw/ppc/xics.h | 1 -
> include/hw/ppc/xics_spapr.h | 1 +
> 6 files changed, 3 insertions(+), 33 deletions(-)
>
> diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c
> index 5ba5b775615e..5c4208f43008 100644
> --- a/hw/intc/xics_kvm.c
> +++ b/hw/intc/xics_kvm.c
> @@ -331,15 +331,6 @@ void ics_kvm_set_irq(ICSState *ics, int srcno, int val)
> }
> }
>
> -static void rtas_dummy(PowerPCCPU *cpu, SpaprMachineState *spapr,
> - uint32_t token,
> - uint32_t nargs, target_ulong args,
> - uint32_t nret, target_ulong rets)
> -{
> - error_report("pseries: %s must never be called for in-kernel XICS",
> - __func__);
> -}
> -
> int xics_kvm_init(SpaprMachineState *spapr, Error **errp)
> {
> int rc;
> @@ -360,11 +351,6 @@ int xics_kvm_init(SpaprMachineState *spapr, Error **errp)
> goto fail;
> }
>
> - spapr_rtas_register(RTAS_IBM_SET_XIVE, "ibm,set-xive", rtas_dummy);
> - spapr_rtas_register(RTAS_IBM_GET_XIVE, "ibm,get-xive", rtas_dummy);
> - spapr_rtas_register(RTAS_IBM_INT_OFF, "ibm,int-off", rtas_dummy);
> - spapr_rtas_register(RTAS_IBM_INT_ON, "ibm,int-on", rtas_dummy);
> -
> rc = kvmppc_define_rtas_kernel_token(RTAS_IBM_SET_XIVE, "ibm,set-xive");
> if (rc < 0) {
> error_setg(errp, "kvmppc_define_rtas_kernel_token: ibm,set-xive");
> @@ -454,11 +440,6 @@ void xics_kvm_disconnect(SpaprMachineState *spapr, Error **errp)
> close(kernel_xics_fd);
> kernel_xics_fd = -1;
>
> - spapr_rtas_unregister(RTAS_IBM_SET_XIVE);
> - spapr_rtas_unregister(RTAS_IBM_GET_XIVE);
> - spapr_rtas_unregister(RTAS_IBM_INT_OFF);
> - spapr_rtas_unregister(RTAS_IBM_INT_ON);
> -
> kvmppc_define_rtas_kernel_token(0, "ibm,set-xive");
> kvmppc_define_rtas_kernel_token(0, "ibm,get-xive");
> kvmppc_define_rtas_kernel_token(0, "ibm,int-on");
> diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
> index d470ab5f7a2a..8d605b68a7a0 100644
> --- a/hw/intc/xics_spapr.c
> +++ b/hw/intc/xics_spapr.c
> @@ -285,14 +285,6 @@ static void rtas_int_on(PowerPCCPU *cpu, SpaprMachineState *spapr,
>
> void xics_spapr_init(SpaprMachineState *spapr)
> {
> - /* Emulated mode can only be initialized once. */
> - if (spapr->ics->init) {
> - return;
> - }
> -
> - spapr->ics->init = true;
> -
> - /* Registration of global state belongs into realize */
> spapr_rtas_register(RTAS_IBM_SET_XIVE, "ibm,set-xive", rtas_set_xive);
> spapr_rtas_register(RTAS_IBM_GET_XIVE, "ibm,get-xive", rtas_get_xive);
> spapr_rtas_register(RTAS_IBM_INT_OFF, "ibm,int-off", rtas_int_off);
> diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
> index 3156daf09381..dfb99f35ea00 100644
> --- a/hw/ppc/spapr_irq.c
> +++ b/hw/ppc/spapr_irq.c
> @@ -114,6 +114,8 @@ static void spapr_irq_init_xics(SpaprMachineState *spapr, int nr_irqs,
> }
>
> spapr->ics = ICS_BASE(obj);
> +
> + xics_spapr_init(spapr);
> }
>
> #define ICS_IRQ_FREE(ics, srcno) \
> @@ -236,7 +238,6 @@ static const char *spapr_irq_get_nodename_xics(SpaprMachineState *spapr)
>
> static void spapr_irq_init_emu_xics(SpaprMachineState *spapr, Error **errp)
> {
> - xics_spapr_init(spapr);
> }
>
> static void spapr_irq_init_kvm_xics(SpaprMachineState *spapr, Error **errp)
> diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
> index 4f5becf1f3cc..60553d32c4fa 100644
> --- a/include/hw/ppc/spapr.h
> +++ b/include/hw/ppc/spapr.h
> @@ -676,10 +676,6 @@ typedef void (*spapr_rtas_fn)(PowerPCCPU *cpu, SpaprMachineState *sm,
> uint32_t nargs, target_ulong args,
> uint32_t nret, target_ulong rets);
> void spapr_rtas_register(int token, const char *name, spapr_rtas_fn fn);
> -static inline void spapr_rtas_unregister(int token)
> -{
> - spapr_rtas_register(token, NULL, NULL);
> -}
> target_ulong spapr_rtas_call(PowerPCCPU *cpu, SpaprMachineState *sm,
> uint32_t token, uint32_t nargs, target_ulong args,
> uint32_t nret, target_ulong rets);
> diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
> index d6f8e4c4c282..eb65ad7e43b7 100644
> --- a/include/hw/ppc/xics.h
> +++ b/include/hw/ppc/xics.h
> @@ -119,7 +119,6 @@ struct ICSState {
> uint32_t offset;
> ICSIRQState *irqs;
> XICSFabric *xics;
> - bool init; /* sPAPR ICS device initialized */
> };
>
> #define ICS_PROP_XICS "xics"
> diff --git a/include/hw/ppc/xics_spapr.h b/include/hw/ppc/xics_spapr.h
> index 2476b540edfa..6c1d9ee55945 100644
> --- a/include/hw/ppc/xics_spapr.h
> +++ b/include/hw/ppc/xics_spapr.h
> @@ -36,5 +36,6 @@ void spapr_dt_xics(SpaprMachineState *spapr, uint32_t nr_servers, void *fdt,
> int xics_kvm_init(SpaprMachineState *spapr, Error **errp);
> void xics_kvm_disconnect(SpaprMachineState *spapr, Error **errp);
> void xics_spapr_init(SpaprMachineState *spapr);
> +void xics_spapr_connect(SpaprMachineState *spapr);
>
> #endif /* XICS_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: 833 bytes --]
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [Qemu-devel] [PATCH 3/3] xics/spapr: Detect old KVM XICS on POWER9 hosts
2019-06-13 16:45 ` [Qemu-devel] [PATCH 3/3] xics/spapr: Detect old KVM XICS on POWER9 hosts Greg Kurz
@ 2019-06-14 1:40 ` David Gibson
0 siblings, 0 replies; 8+ messages in thread
From: David Gibson @ 2019-06-14 1:40 UTC (permalink / raw)
To: Greg Kurz; +Cc: qemu-ppc, Cédric Le Goater, qemu-devel
[-- Attachment #1: Type: text/plain, Size: 4707 bytes --]
On Thu, Jun 13, 2019 at 06:45:05PM +0200, Greg Kurz wrote:
> Older KVMs on POWER9 don't support destroying/recreating a KVM XICS
> device, which is required by 'dual' interrupt controller mode. This
> causes QEMU to emit a warning when the guest is rebooted and to fall
> back on XICS emulation:
>
> qemu-system-ppc64: warning: kernel_irqchip allowed but unavailable:
> Error on KVM_CREATE_DEVICE for XICS: File exists
>
> If kernel irqchip is required, QEMU will thus exit when the guest is
> first rebooted. Failing QEMU this late may be a painful experience
> for the user.
>
> Detect that and exit at machine init instead.
>
> Signed-off-by: Greg Kurz <groug@kaod.org>
Applied, thanks.
> ---
> docs/specs/ppc-spapr-xive.rst | 4 ++--
> hw/intc/xics_kvm.c | 30 ++++++++++++++++++++++++++++++
> hw/ppc/spapr_irq.c | 13 +++++++++++++
> include/hw/ppc/xics_spapr.h | 1 +
> 4 files changed, 46 insertions(+), 2 deletions(-)
>
> diff --git a/docs/specs/ppc-spapr-xive.rst b/docs/specs/ppc-spapr-xive.rst
> index 7a64c9d04951..6159bc6eed62 100644
> --- a/docs/specs/ppc-spapr-xive.rst
> +++ b/docs/specs/ppc-spapr-xive.rst
> @@ -142,8 +142,8 @@ xics XICS KVM XICS emul. XICS KVM
> (3) QEMU fails at CAS with ``Guest requested unavailable interrupt
> mode (XICS), either don't set the ic-mode machine property or try
> ic-mode=xics or ic-mode=dual``
> -(4) QEMU/KVM incompatibility due to device destruction in reset. This
> - needs to be addressed more cleanly with an error.
> +(4) QEMU/KVM incompatibility due to device destruction in reset. QEMU fails
> + with ``KVM is too old to support ic-mode=dual,kernel-irqchip=on``
>
>
> XIVE Device tree properties
> diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c
> index 5c4208f43008..c7f8f5edd257 100644
> --- a/hw/intc/xics_kvm.c
> +++ b/hw/intc/xics_kvm.c
> @@ -452,3 +452,33 @@ void xics_kvm_disconnect(SpaprMachineState *spapr, Error **errp)
> /* Clear the presenter from the VCPUs */
> kvm_disable_icps();
> }
> +
> +/*
> + * This is a heuristic to detect older KVMs on POWER9 hosts that don't
> + * support destruction of a KVM XICS device while the VM is running.
> + * Required to start a spapr machine with ic-mode=dual,kernel-irqchip=on.
> + */
> +bool xics_kvm_has_broken_disconnect(SpaprMachineState *spapr)
> +{
> + int rc;
> +
> + rc = kvm_create_device(kvm_state, KVM_DEV_TYPE_XICS, false);
> + if (rc < 0) {
> + /*
> + * The error is ignored on purpose. The KVM XICS setup code
> + * will catch it again anyway. The goal here is to see if
> + * close() actually destroys the device or not.
> + */
> + return false;
> + }
> +
> + close(rc);
> +
> + rc = kvm_create_device(kvm_state, KVM_DEV_TYPE_XICS, false);
> + if (rc >= 0) {
> + close(rc);
> + return false;
> + }
> +
> + return errno == EEXIST;
> +}
> diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
> index dfb99f35ea00..75654fc67aba 100644
> --- a/hw/ppc/spapr_irq.c
> +++ b/hw/ppc/spapr_irq.c
> @@ -669,6 +669,19 @@ static void spapr_irq_check(SpaprMachineState *spapr, Error **errp)
> return;
> }
> }
> +
> + /*
> + * On a POWER9 host, some older KVM XICS devices cannot be destroyed and
> + * re-created. Detect that early to avoid QEMU to exit later when the
> + * guest reboots.
> + */
> + if (kvm_enabled() &&
> + spapr->irq == &spapr_irq_dual &&
> + machine_kernel_irqchip_required(machine) &&
> + xics_kvm_has_broken_disconnect(spapr)) {
> + error_setg(errp, "KVM is too old to support ic-mode=dual,kernel-irqchip=on");
> + return;
> + }
> }
>
> /*
> diff --git a/include/hw/ppc/xics_spapr.h b/include/hw/ppc/xics_spapr.h
> index 6c1d9ee55945..d968f2499ca7 100644
> --- a/include/hw/ppc/xics_spapr.h
> +++ b/include/hw/ppc/xics_spapr.h
> @@ -35,6 +35,7 @@ void spapr_dt_xics(SpaprMachineState *spapr, uint32_t nr_servers, void *fdt,
> uint32_t phandle);
> int xics_kvm_init(SpaprMachineState *spapr, Error **errp);
> void xics_kvm_disconnect(SpaprMachineState *spapr, Error **errp);
> +bool xics_kvm_has_broken_disconnect(SpaprMachineState *spapr);
> void xics_spapr_init(SpaprMachineState *spapr);
> void xics_spapr_connect(SpaprMachineState *spapr);
>
>
--
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: 833 bytes --]
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [Qemu-devel] [PATCH 1/3] xics/spapr: Prevent RTAS/hypercalls emulation to be used by in-kernel XICS
2019-06-14 1:34 ` David Gibson
@ 2019-06-14 5:37 ` Greg Kurz
0 siblings, 0 replies; 8+ messages in thread
From: Greg Kurz @ 2019-06-14 5:37 UTC (permalink / raw)
To: David Gibson; +Cc: qemu-ppc, Cédric Le Goater, qemu-devel
[-- Attachment #1: Type: text/plain, Size: 5526 bytes --]
On Fri, 14 Jun 2019 11:34:59 +1000
David Gibson <david@gibson.dropbear.id.au> wrote:
> On Thu, Jun 13, 2019 at 06:44:54PM +0200, Greg Kurz wrote:
> > The XICS-related RTAS calls and hypercalls in QEMU are supposed to be
> > called only when the KVM in-kernel XICS is in use.
>
> I've applied this, but reversed the sense of the sentence above, which
> appears to be the intent.
>
Oops indeed... Thanks !
> >
> > Add some explicit checks to detect that, print an error message and report
> > an hardware error to the guest.
> >
> > Signed-off-by: Greg Kurz <groug@kaod.org>
> > ---
> > hw/intc/xics_spapr.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
> > 1 file changed, 46 insertions(+)
> >
> > diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
> > index 5a1835e8b1ed..d470ab5f7a2a 100644
> > --- a/hw/intc/xics_spapr.c
> > +++ b/hw/intc/xics_spapr.c
> > @@ -41,11 +41,31 @@
> > * Guest interfaces
> > */
> >
> > +static bool check_in_kernel_xics(const char *func)
> > +{
> > + if (kvm_irqchip_in_kernel()) {
> > + error_report("pseries: %s must never be called for in-kernel XICS",
> > + func);
> > + return true;
> > + }
> > +
> > + return false;
> > +}
> > +
> > +#define CHECK_IN_KERNEL_XICS_HCALL \
> > + do { \
> > + if (check_in_kernel_xics(__func__)) { \
> > + return H_HARDWARE; \
> > + } \
> > + } while (0)
> > +
> > static target_ulong h_cppr(PowerPCCPU *cpu, SpaprMachineState *spapr,
> > target_ulong opcode, target_ulong *args)
> > {
> > target_ulong cppr = args[0];
> >
> > + CHECK_IN_KERNEL_XICS_HCALL;
> > +
> > icp_set_cppr(spapr_cpu_state(cpu)->icp, cppr);
> > return H_SUCCESS;
> > }
> > @@ -56,6 +76,8 @@ static target_ulong h_ipi(PowerPCCPU *cpu, SpaprMachineState *spapr,
> > target_ulong mfrr = args[1];
> > ICPState *icp = xics_icp_get(XICS_FABRIC(spapr), args[0]);
> >
> > + CHECK_IN_KERNEL_XICS_HCALL;
> > +
> > if (!icp) {
> > return H_PARAMETER;
> > }
> > @@ -69,6 +91,8 @@ static target_ulong h_xirr(PowerPCCPU *cpu, SpaprMachineState *spapr,
> > {
> > uint32_t xirr = icp_accept(spapr_cpu_state(cpu)->icp);
> >
> > + CHECK_IN_KERNEL_XICS_HCALL;
> > +
> > args[0] = xirr;
> > return H_SUCCESS;
> > }
> > @@ -78,6 +102,8 @@ static target_ulong h_xirr_x(PowerPCCPU *cpu, SpaprMachineState *spapr,
> > {
> > uint32_t xirr = icp_accept(spapr_cpu_state(cpu)->icp);
> >
> > + CHECK_IN_KERNEL_XICS_HCALL;
> > +
> > args[0] = xirr;
> > args[1] = cpu_get_host_ticks();
> > return H_SUCCESS;
> > @@ -88,6 +114,8 @@ static target_ulong h_eoi(PowerPCCPU *cpu, SpaprMachineState *spapr,
> > {
> > target_ulong xirr = args[0];
> >
> > + CHECK_IN_KERNEL_XICS_HCALL;
> > +
> > icp_eoi(spapr_cpu_state(cpu)->icp, xirr);
> > return H_SUCCESS;
> > }
> > @@ -99,6 +127,8 @@ static target_ulong h_ipoll(PowerPCCPU *cpu, SpaprMachineState *spapr,
> > uint32_t mfrr;
> > uint32_t xirr;
> >
> > + CHECK_IN_KERNEL_XICS_HCALL;
> > +
> > if (!icp) {
> > return H_PARAMETER;
> > }
> > @@ -111,6 +141,14 @@ static target_ulong h_ipoll(PowerPCCPU *cpu, SpaprMachineState *spapr,
> > return H_SUCCESS;
> > }
> >
> > +#define CHECK_IN_KERNEL_XICS_RTAS(rets) \
> > + do { \
> > + if (check_in_kernel_xics(__func__)) { \
> > + rtas_st((rets), 0, RTAS_OUT_HW_ERROR); \
> > + return; \
> > + } \
> > + } while (0)
> > +
> > static void rtas_set_xive(PowerPCCPU *cpu, SpaprMachineState *spapr,
> > uint32_t token,
> > uint32_t nargs, target_ulong args,
> > @@ -119,6 +157,8 @@ static void rtas_set_xive(PowerPCCPU *cpu, SpaprMachineState *spapr,
> > ICSState *ics = spapr->ics;
> > uint32_t nr, srcno, server, priority;
> >
> > + CHECK_IN_KERNEL_XICS_RTAS(rets);
> > +
> > if ((nargs != 3) || (nret != 1)) {
> > rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
> > return;
> > @@ -152,6 +192,8 @@ static void rtas_get_xive(PowerPCCPU *cpu, SpaprMachineState *spapr,
> > ICSState *ics = spapr->ics;
> > uint32_t nr, srcno;
> >
> > + CHECK_IN_KERNEL_XICS_RTAS(rets);
> > +
> > if ((nargs != 1) || (nret != 3)) {
> > rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
> > return;
> > @@ -182,6 +224,8 @@ static void rtas_int_off(PowerPCCPU *cpu, SpaprMachineState *spapr,
> > ICSState *ics = spapr->ics;
> > uint32_t nr, srcno;
> >
> > + CHECK_IN_KERNEL_XICS_RTAS(rets);
> > +
> > if ((nargs != 1) || (nret != 1)) {
> > rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
> > return;
> > @@ -213,6 +257,8 @@ static void rtas_int_on(PowerPCCPU *cpu, SpaprMachineState *spapr,
> > ICSState *ics = spapr->ics;
> > uint32_t nr, srcno;
> >
> > + CHECK_IN_KERNEL_XICS_RTAS(rets);
> > +
> > if ((nargs != 1) || (nret != 1)) {
> > rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
> > return;
> >
>
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2019-06-14 5:39 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-06-13 16:44 [Qemu-devel] [PATCH 0/3] xics/kvm: Fix issues with older KVMs on POWER9 hosts Greg Kurz
2019-06-13 16:44 ` [Qemu-devel] [PATCH 1/3] xics/spapr: Prevent RTAS/hypercalls emulation to be used by in-kernel XICS Greg Kurz
2019-06-14 1:34 ` David Gibson
2019-06-14 5:37 ` Greg Kurz
2019-06-13 16:44 ` [Qemu-devel] [PATCH 2/3] xics/spapr: Register RTAS/hypercalls once at machine init Greg Kurz
2019-06-14 1:38 ` David Gibson
2019-06-13 16:45 ` [Qemu-devel] [PATCH 3/3] xics/spapr: Detect old KVM XICS on POWER9 hosts Greg Kurz
2019-06-14 1:40 ` 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).