We introduce a 'xive_exploitation' boolean at the machine level to enable the XIVE interrupt mode for newer machines and to disable it on older ones.
The XIVE interrupt mode can still be forced on the command line with a machine option. That might be a bit dangerous. To be discussed. Signed-off-by: Cédric Le Goater <c...@kaod.org> --- hw/intc/spapr_xive.c | 10 ++++++---- hw/ppc/spapr.c | 52 +++++++++++++++++++++++++++++++++++++++++++++----- include/hw/ppc/spapr.h | 1 + 3 files changed, 54 insertions(+), 9 deletions(-) diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c index b732aaf4f8ba..f7fab70cb8bb 100644 --- a/hw/intc/spapr_xive.c +++ b/hw/intc/spapr_xive.c @@ -736,8 +736,9 @@ static const VMStateDescription vmstate_spapr_xive_ive = { static bool vmstate_spapr_xive_needed(void *opaque) { - /* TODO check machine XIVE support */ - return true; + sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine()); + + return spapr->xive_exploitation; } static const VMStateDescription vmstate_spapr_xive = { @@ -863,8 +864,9 @@ static const VMStateDescription vmstate_spapr_xive_icp_eq = { static bool vmstate_spapr_xive_icp_needed(void *opaque) { - /* TODO check machine XIVE support */ - return true; + sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine()); + + return spapr->xive_exploitation; } static const VMStateDescription vmstate_spapr_xive_icp = { diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 9fe3a9966b12..d3a4b1f8f6f9 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -961,10 +961,11 @@ static void spapr_dt_rtas(sPAPRMachineState *spapr, void *fdt) spapr_dt_rtas_tokens(fdt, rtas); } -/* 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) +/* Prepare ibm,arch-vec-5-platform-support, which indicates the MMU + * and the XIVE features that the guest may request and thus the valid + * values for bytes 23..26 of option vector 5: */ +static void spapr_dt_ov5_platform_support(sPAPRMachineState *spapr, void *fdt, + int chosen) { PowerPCCPU *first_ppc_cpu = POWERPC_CPU(first_cpu); @@ -987,7 +988,16 @@ 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_exploitation) { + val[1] = 0x80; /* OV5_XIVE_BOTH */ + } } else { + if (spapr->xive_exploitation) { + val[1] = 0x80; /* OV5_XIVE_BOTH */ + } /* V3 MMU supports both hash and radix in tcg (with dynamic switching) */ val[3] = 0xC0; } @@ -1048,7 +1058,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); @@ -2441,6 +2451,11 @@ static void ppc_spapr_init(MachineState *machine) spapr_ovec_set(spapr->ov5, OV5_HPT_RESIZE); } + /* advertise XIVE if not disabled by the user */ + if (spapr->xive_exploitation) { + spapr_ovec_set(spapr->ov5, OV5_XIVE_EXPLOIT); + } + /* init CPUs */ spapr_set_vsmt_mode(spapr, &error_fatal); @@ -2840,6 +2855,21 @@ static void spapr_set_vsmt(Object *obj, Visitor *v, const char *name, visit_type_uint32(v, name, (uint32_t *)opaque, errp); } +static bool spapr_get_xive_exploitation(Object *obj, Error **errp) +{ + sPAPRMachineState *spapr = SPAPR_MACHINE(obj); + + return spapr->xive_exploitation; +} + +static void spapr_set_xive_exploitation(Object *obj, bool value, + Error **errp) +{ + sPAPRMachineState *spapr = SPAPR_MACHINE(obj); + + spapr->xive_exploitation = value; +} + static void spapr_machine_initfn(Object *obj) { sPAPRMachineState *spapr = SPAPR_MACHINE(obj); @@ -2875,6 +2905,15 @@ static void spapr_machine_initfn(Object *obj) object_property_set_description(obj, "vsmt", "Virtual SMT: KVM behaves as if this were" " the host's SMT mode", &error_abort); + + spapr->xive_exploitation = true; + object_property_add_bool(obj, "xive-exploitation", + spapr_get_xive_exploitation, + spapr_set_xive_exploitation, + NULL); + object_property_set_description(obj, "xive-exploitation", + "XIVE exploitation mode POWER9", + NULL); } static void spapr_machine_finalizefn(Object *obj) @@ -3956,7 +3995,10 @@ DEFINE_SPAPR_MACHINE(2_12, "2.12", true); static void spapr_machine_2_11_instance_options(MachineState *machine) { + sPAPRMachineState *spapr = SPAPR_MACHINE(machine); + spapr_machine_2_12_instance_options(machine); + spapr->xive_exploitation = false; } static void spapr_machine_2_11_class_options(MachineClass *mc) diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index a25e218b34e2..c4f051f974fe 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -129,6 +129,7 @@ struct sPAPRMachineState { const char *icp_type; sPAPRXive *xive; + bool xive_exploitation; }; #define H_SUCCESS 0 -- 2.13.6