@@ -942,7 +942,8 @@ static void spapr_dt_rtas(sPAPRMachineState *spapr, void *fdt)
/* Prepare ibm,arch-vec-5-platform-support, which indicates the MMU features
* that the guest may request and thus the valid values for bytes 24..26 of
* option vector 5: */
-static void spapr_dt_ov5_platform_support(void *fdt, int chosen)
+static void spapr_dt_ov5_platform_support(sPAPRMachineState *spapr,
+ void *fdt, int chosen)
{
PowerPCCPU *first_ppc_cpu = POWERPC_CPU(first_cpu);
@@ -961,6 +962,13 @@ static void spapr_dt_ov5_platform_support(void *fdt, int chosen)
} else {
val[3] = 0x00; /* Hash */
}
+
+ /* TODO: introduce a kvmppc_has_cap_xive() ? Works with
+ * irqchip=off for now
+ */
+ if (spapr->xive) {
+ val[1] = 0x80; /* OV5_XIVE_BOTH */
+ }
} else {
if (first_ppc_cpu->env.mmu_model & POWERPC_MMU_V3) {
/* V3 MMU supports both hash and radix (with dynamic switching) */
@@ -969,6 +977,9 @@ static void spapr_dt_ov5_platform_support(void *fdt, int chosen)
/* Otherwise we can only do hash */
val[3] = 0x00;
}
+ if (spapr->xive) {
+ val[1] = 0x80; /* OV5_XIVE_BOTH */
+ }
}
_FDT(fdt_setprop(fdt, chosen, "ibm,arch-vec-5-platform-support",
val, sizeof(val)));
@@ -1027,7 +1038,7 @@ static void spapr_dt_chosen(sPAPRMachineState *spapr, void *fdt)
_FDT(fdt_setprop_string(fdt, chosen, "linux,stdout-path", stdout_path));
}
- spapr_dt_ov5_platform_support(fdt, chosen);
+ spapr_dt_ov5_platform_support(spapr, fdt, chosen);
g_free(stdout_path);
g_free(bootlist);
@@ -1106,7 +1117,13 @@ static void *spapr_build_fdt(sPAPRMachineState *spapr,
_FDT(fdt_setprop_cell(fdt, 0, "#size-cells", 2));
/* /interrupt controller */
- spapr_dt_xics(xics_max_server_number(), fdt, PHANDLE_XICP);
+ if (!spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) {
+ spapr_dt_xics(xics_max_server_number(), fdt, PHANDLE_XICP);
+ } else {
+ /* populate device tree for XIVE */ ;
+ spapr_xive_populate(spapr->xive, fdt, PHANDLE_XICP);
+ spapr_xive_mmio_map(spapr->xive);
+ }
ret = spapr_populate_memory(spapr, fdt);
if (ret < 0) {
@@ -1552,6 +1569,10 @@ static int spapr_post_load(void *opaque, int version_id)
}
}
+ if (spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) {
+ spapr_xive_mmio_map(spapr->xive);
+ }
+
return err;
}
@@ -2332,6 +2353,7 @@ static void ppc_spapr_init(MachineState *machine)
XICS_IRQS_SPAPR + xics_max_server_number(),
xics_max_server_number(),
&error_fatal);
+ spapr_ovec_set(spapr->ov5, OV5_XIVE_EXPLOIT);
}
}
@@ -3463,6 +3485,11 @@ static qemu_irq spapr_qirq_get(XICSFabric *dev, int irq)
return NULL;
}
+ /* use XIVE qirqs when XIVE exploitation mode is on */
+ if (spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) {
+ return spapr->xive->qirqs[irq - spapr->ics->offset];
+ }
+
return spapr->ics->qirqs[irq - spapr->ics->offset];
}
@@ -1613,6 +1613,12 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
(spapr_h_cas_compose_response(spapr, args[1], args[2],
ov5_updates) != 0);
}
+
+ /* We need to rebuild the device tree for XIVE, generate a reset */
+ if (!spapr->cas_reboot) {
+ spapr->cas_reboot = spapr_ovec_test(ov5_updates, OV5_XIVE_EXPLOIT);
+ }
+
spapr_ovec_cleanup(ov5_updates);
if (spapr->cas_reboot) {
A couple of adjustments need to be done to activate XIVE exploitation mode. First, the hypervisor should advertise support for both models XIVE legacy and XIVE exploitation in "ibm,arch-vec-5-platform-support". The sPAPR machine starts with the XICS interrupt model (the default behavior could be changed later on for POWER9) and, depending on the guest capabilities, the XIVE exploitation mode is negotiated during CAS. A reset is then performed to rebuild the device tree with new XIVE properties under the "interrupt-controller" node. Finally, the MMIO regions for the ESB and TIMA should be mapped at reset time and post_load when XIVE exploitation mode is on. Signed-off-by: Cédric Le Goater <clg@kaod.org> --- hw/ppc/spapr.c | 33 ++++++++++++++++++++++++++++++--- hw/ppc/spapr_hcall.c | 6 ++++++ 2 files changed, 36 insertions(+), 3 deletions(-)