[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-ppc] [PATCH v6 31/37] spapr: add a 'pseries-3.1-dual' machine type
From: |
Cédric Le Goater |
Subject: |
[Qemu-ppc] [PATCH v6 31/37] spapr: add a 'pseries-3.1-dual' machine type |
Date: |
Thu, 6 Dec 2018 00:22:45 +0100 |
This pseries machine makes use of a new sPAPR IRQ backend supporting
both interrupt modes : XIVE and XICS, the default being XICS.
The interrupt mode is chosen by the CAS negotiation process and
activated after a reset to take into account the required changes in
the machine. These impact the device tree layout, the interrupt
presenter object and the exposed MMIO regions in the case of XIVE.
KVM is not yet supported.
Signed-off-by: Cédric Le Goater <address@hidden>
---
include/hw/ppc/spapr_irq.h | 1 +
hw/ppc/spapr.c | 18 ++++-
hw/ppc/spapr_hcall.c | 13 ++++
hw/ppc/spapr_irq.c | 142 +++++++++++++++++++++++++++++++++++++
4 files changed, 173 insertions(+), 1 deletion(-)
diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
index 26727a7263a5..af429148ce2d 100644
--- a/include/hw/ppc/spapr_irq.h
+++ b/include/hw/ppc/spapr_irq.h
@@ -51,6 +51,7 @@ typedef struct sPAPRIrq {
extern sPAPRIrq spapr_irq_xics;
extern sPAPRIrq spapr_irq_xics_legacy;
extern sPAPRIrq spapr_irq_xive;
+extern sPAPRIrq spapr_irq_dual;
void spapr_irq_init(sPAPRMachineState *spapr, Error **errp);
int spapr_irq_claim(sPAPRMachineState *spapr, int irq, bool lsi, Error **errp);
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 3cdc66484f42..232956116518 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -2634,7 +2634,8 @@ static void spapr_machine_init(MachineState *machine)
spapr_ovec_set(spapr->ov5, OV5_DRMEM_V2);
/* advertise XIVE */
- if (smc->irq->ov5 == SPAPR_OV5_XIVE_EXPLOIT) {
+ if (smc->irq->ov5 == SPAPR_OV5_XIVE_EXPLOIT ||
+ smc->irq->ov5 == SPAPR_OV5_XIVE_BOTH) {
spapr_ovec_set(spapr->ov5, OV5_XIVE_EXPLOIT);
}
@@ -4002,6 +4003,21 @@ static void
spapr_machine_3_1_xive_class_options(MachineClass *mc)
DEFINE_SPAPR_MACHINE(3_1_xive, "3.1-xive", false);
+static void spapr_machine_3_1_dual_instance_options(MachineState *machine)
+{
+ spapr_machine_3_1_instance_options(machine);
+}
+
+static void spapr_machine_3_1_dual_class_options(MachineClass *mc)
+{
+ sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
+
+ spapr_machine_3_1_class_options(mc);
+ smc->irq = &spapr_irq_dual;
+}
+
+DEFINE_SPAPR_MACHINE(3_1_dual, "3.1-dual", false);
+
/*
* pseries-3.0
*/
diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index ae913d070f50..186b6a65543f 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -1654,6 +1654,19 @@ static target_ulong
h_client_architecture_support(PowerPCCPU *cpu,
(spapr_h_cas_compose_response(spapr, args[1], args[2],
ov5_updates) != 0);
}
+
+ /*
+ * Generate a machine reset when we have an update of the
+ * interrupt mode. Only required on the machine supporting both
+ * mode.
+ */
+ if (!spapr->cas_reboot) {
+ sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
+
+ spapr->cas_reboot = spapr_ovec_test(ov5_updates, OV5_XIVE_EXPLOIT)
+ && smc->irq->ov5 == SPAPR_OV5_XIVE_BOTH;
+ }
+
spapr_ovec_cleanup(ov5_updates);
if (spapr->cas_reboot) {
diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index 94bb4d27758a..157c335f6f8d 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -399,6 +399,148 @@ sPAPRIrq spapr_irq_xive = {
.reset = spapr_irq_reset_xive,
};
+/*
+ * Dual XIVE and XICS IRQ backend.
+ *
+ * Both interrupt mode, XIVE and XICS, objects are created but the
+ * machine starts in legacy interrupt mode (XICS). It can be changed
+ * by the CAS negotiation process and, in that case, the new mode is
+ * activated after extra machine reset.
+ */
+
+/*
+ * Returns the sPAPR IRQ backend negotiated by CAS. XICS is the
+ * default.
+ */
+static sPAPRIrq *spapr_irq_current(sPAPRMachineState *spapr)
+{
+ return spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT) ?
+ &spapr_irq_xive : &spapr_irq_xics;
+}
+
+static void spapr_irq_init_dual(sPAPRMachineState *spapr, int nr_irqs,
+ Error **errp)
+{
+ MachineState *machine = MACHINE(spapr);
+ Error *local_err = NULL;
+
+ if (kvm_enabled() && machine_kernel_irqchip_allowed(machine)) {
+ error_setg(errp, "No KVM support for the 'dual' machine");
+ return;
+ }
+
+ spapr_irq_xics.init(spapr, spapr_irq_xics.nr_irqs, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+
+ spapr_irq_xive.init(spapr, spapr_irq_xive.nr_irqs, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+}
+
+static int spapr_irq_claim_dual(sPAPRMachineState *spapr, int irq, bool lsi,
+ Error **errp)
+{
+ int ret;
+ Error *local_err = NULL;
+
+ ret = spapr_irq_xive.claim(spapr, irq, lsi, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return ret;
+ }
+
+ ret = spapr_irq_xics.claim(spapr, irq, lsi, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ }
+
+ return ret;
+}
+
+static void spapr_irq_free_dual(sPAPRMachineState *spapr, int irq, int num)
+{
+ spapr_irq_xive.free(spapr, irq, num);
+ spapr_irq_xics.free(spapr, irq, num);
+}
+
+static qemu_irq spapr_qirq_dual(sPAPRMachineState *spapr, int irq)
+{
+ return spapr_irq_current(spapr)->qirq(spapr, irq);
+}
+
+static void spapr_irq_print_info_dual(sPAPRMachineState *spapr, Monitor *mon)
+{
+ spapr_irq_current(spapr)->print_info(spapr, mon);
+}
+
+static void spapr_irq_dt_populate_dual(sPAPRMachineState *spapr,
+ uint32_t nr_servers, void *fdt,
+ uint32_t phandle)
+{
+ spapr_irq_current(spapr)->dt_populate(spapr, nr_servers, fdt, phandle);
+}
+
+static Object *spapr_irq_cpu_intc_create_dual(sPAPRMachineState *spapr,
+ Object *cpu, Error **errp)
+{
+ Error *local_err = NULL;
+
+ spapr_irq_xive.cpu_intc_create(spapr, cpu, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return NULL;
+ }
+
+ /* Default to XICS interrupt mode */
+ return spapr_irq_xics.cpu_intc_create(spapr, cpu, errp);
+}
+
+static int spapr_irq_post_load_dual(sPAPRMachineState *spapr, int version_id)
+{
+ /*
+ * Force a reset of the XIVE backend after migration. The machine
+ * defaults to XICS at startup.
+ */
+ if (spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) {
+ spapr_irq_xive.reset(spapr, &error_fatal);
+ }
+
+ return spapr_irq_current(spapr)->post_load(spapr, version_id);
+}
+
+static void spapr_irq_reset_dual(sPAPRMachineState *spapr, Error **errp)
+{
+ /*
+ * Reset the selected interrupt mode to reconnect to KVM. At startup,
+ * the machine uses XICS as it is the default interrupt mode.
+ */
+ spapr_irq_current(spapr)->reset(spapr, errp);
+}
+
+#define SPAPR_IRQ_DUAL_NR_IRQS 0x2000
+#define SPAPR_IRQ_DUAL_NR_MSIS (SPAPR_IRQ_DUAL_NR_IRQS - SPAPR_IRQ_MSI)
+
+sPAPRIrq spapr_irq_dual = {
+ .nr_irqs = SPAPR_IRQ_DUAL_NR_IRQS,
+ .nr_msis = SPAPR_IRQ_DUAL_NR_MSIS,
+ .ov5 = SPAPR_OV5_XIVE_BOTH,
+
+ .init = spapr_irq_init_dual,
+ .claim = spapr_irq_claim_dual,
+ .free = spapr_irq_free_dual,
+ .qirq = spapr_qirq_dual,
+ .print_info = spapr_irq_print_info_dual,
+ .dt_populate = spapr_irq_dt_populate_dual,
+ .cpu_intc_create = spapr_irq_cpu_intc_create_dual,
+ .post_load = spapr_irq_post_load_dual,
+ .reset = spapr_irq_reset_dual,
+};
+
/*
* sPAPR IRQ frontend routines for devices
*/
--
2.17.2
- [Qemu-ppc] [PATCH v6 21/37] spapr: add a 'reset' method to the sPAPR IRQ backend, (continued)
- [Qemu-ppc] [PATCH v6 21/37] spapr: add a 'reset' method to the sPAPR IRQ backend, Cédric Le Goater, 2018/12/05
- [Qemu-ppc] [PATCH v6 22/37] spapr: add a 'pseries-3.1-xive' machine type, Cédric Le Goater, 2018/12/05
- [Qemu-ppc] [PATCH v6 28/37] spapr/xive: fix migration of the XiveTCTX under TCG, Cédric Le Goater, 2018/12/05
- [Qemu-ppc] [PATCH v6 23/37] linux-headers: update to 4.20-rc5, Cédric Le Goater, 2018/12/05
- [Qemu-ppc] [PATCH v6 25/37] spapr/xive: add state synchronization with KVM, Cédric Le Goater, 2018/12/05
- [Qemu-ppc] [PATCH v6 29/37] spapr: set the interrupt presenter at reset, Cédric Le Goater, 2018/12/05
- [Qemu-ppc] [PATCH v6 30/37] spapr/xive: enable XIVE MMIOs at reset, Cédric Le Goater, 2018/12/05
- [Qemu-ppc] [PATCH v6 27/37] spapr/xive: add migration support for KVM, Cédric Le Goater, 2018/12/05
- [Qemu-ppc] [PATCH v6 26/37] spapr/xive: introduce a VM state change handler, Cédric Le Goater, 2018/12/05
- [Qemu-ppc] [PATCH v6 24/37] spapr/xive: add KVM support, Cédric Le Goater, 2018/12/05
- [Qemu-ppc] [PATCH v6 31/37] spapr: add a 'pseries-3.1-dual' machine type,
Cédric Le Goater <=
- [Qemu-ppc] [PATCH v6 32/37] ppc/xics: introduce a icp_kvm_connect() routine, Cédric Le Goater, 2018/12/05
- [Qemu-ppc] [PATCH v6 33/37] spapr/rtas: modify spapr_rtas_register() to remove RTAS handlers, Cédric Le Goater, 2018/12/05
- [Qemu-ppc] [PATCH v6 34/37] sysbus: add a sysbus_mmio_unmap() helper, Cédric Le Goater, 2018/12/05
- [Qemu-ppc] [PATCH v6 35/37] spapr: introduce routines to delete the KVM IRQ device, Cédric Le Goater, 2018/12/05
- [Qemu-ppc] [PATCH v6 37/37] spapr: add KVM support to the 'dual' machine, Cédric Le Goater, 2018/12/05
- [Qemu-ppc] [PATCH v6 36/37] spapr: check for KVM IRQ device activation, Cédric Le Goater, 2018/12/05
- Re: [Qemu-ppc] [Qemu-devel] [PATCH v6 00/37] ppc: support for the XIVE interrupt controller (POWER9), no-reply, 2018/12/05