@@ -239,3 +239,27 @@ bool spapr_xive_irq_disable(sPAPRXive *xive, uint32_t lisn)
xive_source_irq_set(xsrc, lisn - xsrc->offset, false);
return true;
}
+
+void spapr_xive_mmio_map(sPAPRXive *xive)
+{
+ XiveSource *xsrc = &xive->source;
+
+ /* ESBs */
+ sysbus_mmio_map(SYS_BUS_DEVICE(xsrc), 0, xsrc->esb_base);
+
+ /* Thread Management Interrupt Area: User and OS views */
+ sysbus_mmio_map(SYS_BUS_DEVICE(xive), 0, xive->tm_base);
+ sysbus_mmio_map(SYS_BUS_DEVICE(xive), 1, xive->tm_base + (1 << TM_SHIFT));
+}
+
+void spapr_xive_mmio_unmap(sPAPRXive *xive)
+{
+ XiveSource *xsrc = &xive->source;
+
+ /* ESBs */
+ sysbus_mmio_unmap(SYS_BUS_DEVICE(xsrc), 0);
+
+ /* Thread Management Interrupt Area: User and OS views */
+ sysbus_mmio_unmap(SYS_BUS_DEVICE(xive), 0);
+ sysbus_mmio_unmap(SYS_BUS_DEVICE(xive), 1);
+}
@@ -1519,6 +1519,19 @@ static int spapr_reset_drcs(Object *child, void *opaque)
return 0;
}
+/* Setup XIVE exploitation or legacy mode as required by CAS */
+static void spapr_reset_interrupt(sPAPRMachineState *spapr, Error **errp)
+{
+ /* Reset XIVE if enabled */
+ if (spapr->xive_exploitation) {
+ spapr_xive_mmio_unmap(spapr->xive);
+ }
+
+ if (spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) {
+ spapr_xive_mmio_map(spapr->xive);
+ }
+}
+
static void spapr_machine_reset(void)
{
MachineState *machine = MACHINE(qdev_get_machine());
@@ -1555,6 +1568,8 @@ static void spapr_machine_reset(void)
ppc_set_compat(first_ppc_cpu, spapr->max_compat_pvr, &error_fatal);
}
+ spapr_reset_interrupt(spapr, &error_fatal);
+
qemu_devices_reset();
/* DRC reset may cause a device to be unplugged. This will cause troubles
@@ -1664,6 +1679,7 @@ static int spapr_post_load(void *opaque, int version_id)
{
sPAPRMachineState *spapr = (sPAPRMachineState *)opaque;
int err = 0;
+ Error *local_err = NULL;
err = spapr_caps_post_migration(spapr);
if (err) {
@@ -1698,6 +1714,12 @@ static int spapr_post_load(void *opaque, int version_id)
}
}
+ spapr_reset_interrupt(spapr, &local_err);
+ if (local_err) {
+ error_report_err(local_err);
+ return -EINVAL;
+ }
+
return err;
}
@@ -35,6 +35,8 @@ typedef struct sPAPRXive {
bool spapr_xive_irq_enable(sPAPRXive *xive, uint32_t lisn, bool lsi);
bool spapr_xive_irq_disable(sPAPRXive *xive, uint32_t lisn);
void spapr_xive_pic_print_info(sPAPRXive *xive, Monitor *mon);
+void spapr_xive_mmio_map(sPAPRXive *xive);
+void spapr_xive_mmio_unmap(sPAPRXive *xive);
/*
* sPAPR encoding of EQ indexes
When the XIVE exploitation interrupt mode is activated, the machine needs to expose to the guest the MMIO regions used by the controller : - Event State Buffers - Thread Interrupt Management Area for the OS and User views Migration will also need to reflect the current interrupt mode in use. Signed-off-by: Cédric Le Goater <clg@kaod.org> --- Changes since v2: - introduced spapr_xive_mmio_unmap() - introduced spapr_machine_reset() for reset and post_load hw/intc/spapr_xive.c | 24 ++++++++++++++++++++++++ hw/ppc/spapr.c | 22 ++++++++++++++++++++++ include/hw/ppc/spapr_xive.h | 2 ++ 3 files changed, 48 insertions(+)