[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-ppc] [PATCH v3 19/35] spapr: toggle the ICP depending on the selec
From: |
Cédric Le Goater |
Subject: |
[Qemu-ppc] [PATCH v3 19/35] spapr: toggle the ICP depending on the selected interrupt mode |
Date: |
Thu, 19 Apr 2018 14:43:15 +0200 |
Each interrupt mode has its own specific interrupt presenter object,
that we store under the CPU object, one for XICS and one for XIVE. The
active presenter, corresponding to the current interrupt mode, is
simply selected with a lookup on the children of the CPU.
Migration and CPU hotplug also need to reflect the current interrupt
mode in use.
Signed-off-by: Cédric Le Goater <address@hidden>
---
hw/intc/xive.c | 19 ++++++++++++++++++
hw/ppc/spapr.c | 40 +++++++++++++++++++++++++++++++++++++
hw/ppc/spapr_cpu_core.c | 44 +++++++++++++++++++++++++++++++++++++++++
include/hw/ppc/spapr.h | 1 +
include/hw/ppc/spapr_cpu_core.h | 2 ++
include/hw/ppc/xive.h | 1 +
6 files changed, 107 insertions(+)
diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index 20e216f03c5b..2daa36f77a6b 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -88,6 +88,25 @@ static void xive_eq_push(XiveEQ *eq, uint32_t data)
* XIVE Interrupt Presenter
*/
+Object *xive_nvt_create(Object *cpu, const char *type, Error **errp)
+{
+ Error *local_err = NULL;
+ Object *obj;
+
+ obj = object_new(type);
+ object_property_add_child(cpu, type, obj, &error_abort);
+ object_unref(obj);
+ object_property_add_const_link(obj, ICP_PROP_CPU, cpu, &error_abort);
+ object_property_set_bool(obj, true, "realized", &local_err);
+ if (local_err) {
+ object_unparent(obj);
+ error_propagate(errp, local_err);
+ obj = NULL;
+ }
+
+ return obj;
+}
+
/* Convert a priority number to an Interrupt Pending Buffer (IPB)
* register, which indicates a pending interrupt at the priority
* corresponding to the bit number
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 32c7801b249e..0c59816bf3d6 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -251,6 +251,7 @@ static void xive_system_init(MachineState *machine, int
nr_irqs, Error **errp)
spapr->xive = spapr_xive_create(spapr, TYPE_SPAPR_XIVE, nr_irqs, errp);
if (spapr->xive) {
+ spapr->nvt_type = TYPE_XIVE_NVT;
spapr_xive_hcall_init(spapr);
}
}
@@ -1522,13 +1523,32 @@ static int spapr_reset_drcs(Object *child, void *opaque)
/* Setup XIVE exploitation or legacy mode as required by CAS */
static void spapr_reset_interrupt(sPAPRMachineState *spapr, Error **errp)
{
+ Error *local_err = NULL;
+ const char *intc_type;
+
/* Reset XIVE if enabled */
if (spapr->xive_exploitation) {
spapr_xive_mmio_unmap(spapr->xive);
}
+ /* Reset CPU ICPs */
+ spapr_cpu_core_reset_icp(&local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+
if (spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) {
spapr_xive_mmio_map(spapr->xive);
+ intc_type = spapr->nvt_type;
+ } else {
+ intc_type = spapr->icp_type;
+ }
+
+ spapr_cpu_core_set_icp(intc_type, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
}
}
@@ -3963,6 +3983,26 @@ Object *spapr_icp_create(sPAPRMachineState *spapr,
Object *cpu, Error **errp)
return NULL;
}
+ if (spapr->xive_exploitation) {
+ Object *obj_xive;
+
+ /* Add a XIVE interrupt presenter. The machine will switch
+ * the CPU ICP depending on the interrupt model negotiated
+ * at CAS time.
+ */
+ obj_xive = xive_nvt_create(cpu, spapr->nvt_type, &local_err);
+ if (local_err) {
+ object_unparent(obj);
+ error_propagate(errp, local_err);
+ return NULL;
+ }
+
+ /* when hotplugged, the CPU should have the correct ICP */
+ if (spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) {
+ return obj_xive;
+ }
+ }
+
return obj;
}
diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c
index 76bff4cc372d..3df2bda53f50 100644
--- a/hw/ppc/spapr_cpu_core.c
+++ b/hw/ppc/spapr_cpu_core.c
@@ -256,3 +256,47 @@ static const TypeInfo spapr_cpu_core_type_infos[] = {
};
DEFINE_TYPES(spapr_cpu_core_type_infos)
+
+void spapr_cpu_core_reset_icp(Error **errp)
+{
+ CPUState *cs;
+
+ CPU_FOREACH(cs) {
+ PowerPCCPU *cpu = POWERPC_CPU(cs);
+ cpu->intc = NULL;
+ }
+}
+
+typedef struct ForeachFindICPArgs {
+ const char *icp_type;
+ Object *icp;
+} ForeachFindICPArgs;
+
+static int spapr_cpu_core_find_icp(Object *child, void *opaque)
+{
+ ForeachFindICPArgs *args = opaque;
+
+ if (object_dynamic_cast(child, args->icp_type)) {
+ args->icp = child;
+ }
+
+ return args->icp != NULL;
+}
+
+void spapr_cpu_core_set_icp(const char *icp_type, Error **errp)
+{
+ CPUState *cs;
+
+ CPU_FOREACH(cs) {
+ ForeachFindICPArgs args = { icp_type, NULL };
+ PowerPCCPU *cpu = POWERPC_CPU(cs);
+
+ object_child_foreach(OBJECT(cs), spapr_cpu_core_find_icp, &args);
+ if (!args.icp) {
+ error_setg(errp, "Couldn't find a '%s' icp", icp_type);
+ return;
+ }
+
+ cpu->intc = args.icp;
+ }
+}
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index d5e168f5ad4e..43ef5f743974 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -168,6 +168,7 @@ struct sPAPRMachineState {
const char *icp_type;
uint8_t xive_exploitation;
sPAPRXive *xive;
+ const char *nvt_type;
bool cmd_line_caps[SPAPR_CAP_NUM];
sPAPRCapabilities def, eff, mig;
diff --git a/include/hw/ppc/spapr_cpu_core.h b/include/hw/ppc/spapr_cpu_core.h
index 1129f344aa0c..c7ccc99d22e7 100644
--- a/include/hw/ppc/spapr_cpu_core.h
+++ b/include/hw/ppc/spapr_cpu_core.h
@@ -38,4 +38,6 @@ typedef struct sPAPRCPUCoreClass {
} sPAPRCPUCoreClass;
const char *spapr_get_cpu_core_type(const char *cpu_type);
+void spapr_cpu_core_set_icp(const char *icp_type, Error **errp);
+void spapr_cpu_core_reset_icp(Error **errp);
#endif
diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h
index 328b093eb9c3..24ce58812a7c 100644
--- a/include/hw/ppc/xive.h
+++ b/include/hw/ppc/xive.h
@@ -191,6 +191,7 @@ extern const MemoryRegionOps xive_tm_os_ops;
void xive_nvt_pic_print_info(XiveNVT *nvt, Monitor *mon);
XiveEQ *xive_nvt_eq_get(XiveNVT *nvt, uint8_t priority);
+Object *xive_nvt_create(Object *cpu, const char *type, Error **errp);
void xive_eq_reset(XiveEQ *eq);
void xive_eq_pic_print_info(XiveEQ *eq, Monitor *mon);
--
2.13.6
- [Qemu-ppc] [PATCH v3 09/35] spapr: notify the CPU when the XIVE interrupt priority is more privileged, (continued)
- [Qemu-ppc] [PATCH v3 09/35] spapr: notify the CPU when the XIVE interrupt priority is more privileged, Cédric Le Goater, 2018/04/19
- [Qemu-ppc] [PATCH v3 10/35] spapr: add support for the SET_OS_PENDING command (XIVE), Cédric Le Goater, 2018/04/19
- [Qemu-ppc] [PATCH v3 11/35] spapr: introduce a 'xive_exploitation' option to enable XIVE, Cédric Le Goater, 2018/04/19
- [Qemu-ppc] [PATCH v3 12/35] spapr: add a sPAPRXive object to the machine, Cédric Le Goater, 2018/04/19
- [Qemu-ppc] [PATCH v3 14/35] spapr: add device tree support for the XIVE exploitation mode, Cédric Le Goater, 2018/04/19
- [Qemu-ppc] [PATCH v3 13/35] spapr: add hcalls support for the XIVE exploitation interrupt mode, Cédric Le Goater, 2018/04/19
- [Qemu-ppc] [PATCH v3 15/35] sysbus: add a sysbus_mmio_unmap() helper, Cédric Le Goater, 2018/04/19
- [Qemu-ppc] [PATCH v3 16/35] spapr: introduce a helper to map the XIVE memory regions, Cédric Le Goater, 2018/04/19
- [Qemu-ppc] [PATCH v3 17/35] spapr: add XIVE support to spapr_qirq(), Cédric Le Goater, 2018/04/19
- [Qemu-ppc] [PATCH v3 18/35] spapr: introduce a spapr_icp_create() helper, Cédric Le Goater, 2018/04/19
- [Qemu-ppc] [PATCH v3 19/35] spapr: toggle the ICP depending on the selected interrupt mode,
Cédric Le Goater <=
- [Qemu-ppc] [PATCH v3 20/35] spapr: add support to dump XIVE information, Cédric Le Goater, 2018/04/19
- [Qemu-ppc] [PATCH v3 21/35] spapr: advertise XIVE exploitation mode in CAS, Cédric Le Goater, 2018/04/19
- [Qemu-ppc] [PATCH v3 22/35] spapr: add classes for the XIVE models, Cédric Le Goater, 2018/04/19
- [Qemu-ppc] [PATCH v3 23/35] target/ppc/kvm: add Linux KVM definitions for XIVE, Cédric Le Goater, 2018/04/19
- [Qemu-ppc] [PATCH v3 24/35] spapr/xive: add common realize routine for KVM, Cédric Le Goater, 2018/04/19
- [Qemu-ppc] [PATCH v3 25/35] spapr/xive: add KVM support, Cédric Le Goater, 2018/04/19
- [Qemu-ppc] [PATCH v3 26/35] spapr/xive: add a XIVE KVM device to the machine, Cédric Le Goater, 2018/04/19
- [Qemu-ppc] [PATCH v3 27/35] migration: discard non-migratable RAMBlocks, Cédric Le Goater, 2018/04/19
- [Qemu-ppc] [PATCH v3 28/35] intc: introduce a CPUIntc interface, Cédric Le Goater, 2018/04/19
- [Qemu-ppc] [PATCH v3 29/35] spapr/xive, xics: use the CPU_INTC handlers to reset KVM, Cédric Le Goater, 2018/04/19