Current code uses 32 bit destination ID irrespective of the fact that guest has enabled x2APIC support through control register[XTEn] and completely depends on command line parameter xtsup=on. This is not a correct hardware behaviour and can cause problems in the guest which has not enabled XT mode.
Introduce new flag "xten", which is enabled when guest writes 1 to the control register bit 50 (XTEn). Also, add a new subsection in `VMStateDescription` for backward compatibility during vm migration. Signed-off-by: Sairaj Kodilkar <[email protected]> Reviewed-by: Vasant Hegde <[email protected]> Reviewed-by: Alejandro Jimenez <[email protected]> --- hw/i386/amd_iommu.c | 21 +++++++++++++++++++-- hw/i386/amd_iommu.h | 4 +++- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/hw/i386/amd_iommu.c b/hw/i386/amd_iommu.c index f5aa9c763d02..4a86e62a3b92 100644 --- a/hw/i386/amd_iommu.c +++ b/hw/i386/amd_iommu.c @@ -1523,6 +1523,8 @@ static void amdvi_handle_control_write(AMDVIState *s) s->cmdbuf_enabled = s->enabled && !!(control & AMDVI_MMIO_CONTROL_CMDBUFLEN); s->ga_enabled = !!(control & AMDVI_MMIO_CONTROL_GAEN); + s->xten = !!(control & AMDVI_MMIO_CONTROL_XTEN) && s->xtsup && + s->ga_enabled; /* update the flags depending on the control register */ if (s->cmdbuf_enabled) { @@ -1996,7 +1998,7 @@ static int amdvi_int_remap_ga(AMDVIState *iommu, irq->vector = irte.hi.fields.vector; irq->dest_mode = irte.lo.fields_remap.dm; irq->redir_hint = irte.lo.fields_remap.rq_eoi; - if (iommu->xtsup) { + if (iommu->xten) { irq->dest = irte.lo.fields_remap.destination | (irte.hi.fields.destination_hi << 24); } else { @@ -2379,6 +2381,7 @@ static void amdvi_init(AMDVIState *s) s->mmio_enabled = false; s->enabled = false; s->cmdbuf_enabled = false; + s->xten = false; /* reset MMIO */ memset(s->mmior, 0, AMDVI_MMIO_SIZE); @@ -2443,6 +2446,16 @@ static void amdvi_sysbus_reset(DeviceState *dev) amdvi_reset_address_translation_all(s); } +static const VMStateDescription vmstate_xt = { + .name = "amd-iommu-xt", + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_BOOL(xten, AMDVIState), + VMSTATE_END_OF_LIST() + } +}; + static const VMStateDescription vmstate_amdvi_sysbus_migratable = { .name = "amd-iommu", .version_id = 1, @@ -2487,7 +2500,11 @@ static const VMStateDescription vmstate_amdvi_sysbus_migratable = { VMSTATE_UINT8_ARRAY(romask, AMDVIState, AMDVI_MMIO_SIZE), VMSTATE_UINT8_ARRAY(w1cmask, AMDVIState, AMDVI_MMIO_SIZE), VMSTATE_END_OF_LIST() - } + }, + .subsections = (const VMStateDescription *const []) { + &vmstate_xt, + NULL + } }; static void amdvi_sysbus_realize(DeviceState *dev, Error **errp) diff --git a/hw/i386/amd_iommu.h b/hw/i386/amd_iommu.h index ca4ff9fffee3..d39019b216af 100644 --- a/hw/i386/amd_iommu.h +++ b/hw/i386/amd_iommu.h @@ -102,6 +102,7 @@ #define AMDVI_MMIO_CONTROL_COMWAITINTEN (1ULL << 4) #define AMDVI_MMIO_CONTROL_CMDBUFLEN (1ULL << 12) #define AMDVI_MMIO_CONTROL_GAEN (1ULL << 17) +#define AMDVI_MMIO_CONTROL_XTEN (1ULL << 50) /* MMIO status register bits */ #define AMDVI_MMIO_STATUS_CMDBUF_RUN (1 << 4) @@ -414,7 +415,8 @@ struct AMDVIState { /* Interrupt remapping */ bool ga_enabled; - bool xtsup; + bool xtsup; /* xtsup=on command line */ + bool xten; /* guest controlled, x2apic mode enabled */ /* DMA address translation */ bool dma_remap; -- 2.34.1
