@samitouri / QOSamiQemu / commits / ced009256e

amd_iommu: Turn on XT support only when guest has enabled it

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 <sarunkod@amd.com> Reviewed-by: Vasant Hegde <vasant.hegde@amd.com> Reviewed-by: Alejandro Jimenez <alejandro.j.jimenez@oracle.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Message-Id: <20260302115130.5903-3-sarunkod@amd.com>

Sairaj Kodilkar committed Mar 2, 2026 at 17:21 UTC ced009256e6ed6ae93785d00699fdfb956584f5b
2 files changed +22 -3
hw/i386/amd_iommu.c
+19 -2
@@ -1579,6 +1579,8 @@ static void amdvi_handle_control_write(AMDVIState *s)
1579 s->cmdbuf_enabled = s->enabled && !!(control &
1580 AMDVI_MMIO_CONTROL_CMDBUFLEN);
1581 s->ga_enabled = !!(control & AMDVI_MMIO_CONTROL_GAEN);
1582 + s->xten = !!(control & AMDVI_MMIO_CONTROL_XTEN) && s->xtsup &&
1583 + s->ga_enabled;
1584
1585 /* update the flags depending on the control register */
1586 if (s->cmdbuf_enabled) {
@@ -2054,7 +2056,7 @@ static int amdvi_int_remap_ga(AMDVIState *iommu,
2056 irq->vector = irte.hi.fields.vector;
2057 irq->dest_mode = irte.lo.fields_remap.dm;
2058 irq->redir_hint = irte.lo.fields_remap.rq_eoi;
2057 - if (iommu->xtsup) {
2059 + if (iommu->xten) {
2060 irq->dest = irte.lo.fields_remap.destination |
2061 (irte.hi.fields.destination_hi << 24);
2062 } else {
@@ -2437,6 +2439,7 @@ static void amdvi_init(AMDVIState *s)
2439 s->mmio_enabled = false;
2440 s->enabled = false;
2441 s->cmdbuf_enabled = false;
2442 + s->xten = false;
2443
2444 /* reset MMIO */
2445 memset(s->mmior, 0, AMDVI_MMIO_SIZE);
@@ -2501,6 +2504,16 @@ static void amdvi_sysbus_reset(DeviceState *dev)
2504 amdvi_reset_address_translation_all(s);
2505 }
2506
2507 +static const VMStateDescription vmstate_xt = {
2508 + .name = "amd-iommu-xt",
2509 + .version_id = 1,
2510 + .minimum_version_id = 1,
2511 + .fields = (VMStateField[]) {
2512 + VMSTATE_BOOL(xten, AMDVIState),
2513 + VMSTATE_END_OF_LIST()
2514 + }
2515 +};
2516 +
2517 static const VMStateDescription vmstate_amdvi_sysbus_migratable = {
2518 .name = "amd-iommu",
2519 .version_id = 1,
@@ -2545,7 +2558,11 @@ static const VMStateDescription vmstate_amdvi_sysbus_migratable = {
2558 VMSTATE_UINT8_ARRAY(romask, AMDVIState, AMDVI_MMIO_SIZE),
2559 VMSTATE_UINT8_ARRAY(w1cmask, AMDVIState, AMDVI_MMIO_SIZE),
2560 VMSTATE_END_OF_LIST()
2548 - }
2561 + },
2562 + .subsections = (const VMStateDescription *const []) {
2563 + &vmstate_xt,
2564 + NULL
2565 + }
2566 };
2567
2568 static void amdvi_sysbus_realize(DeviceState *dev, Error **errp)
hw/i386/amd_iommu.h
+3 -1
@@ -102,6 +102,7 @@
102 #define AMDVI_MMIO_CONTROL_COMWAITINTEN (1ULL << 4)
103 #define AMDVI_MMIO_CONTROL_CMDBUFLEN (1ULL << 12)
104 #define AMDVI_MMIO_CONTROL_GAEN (1ULL << 17)
105 +#define AMDVI_MMIO_CONTROL_XTEN (1ULL << 50)
106
107 /* MMIO status register bits */
108 #define AMDVI_MMIO_STATUS_CMDBUF_RUN (1 << 4)
@@ -413,7 +414,8 @@ struct AMDVIState {
414
415 /* Interrupt remapping */
416 bool ga_enabled;
416 - bool xtsup;
417 + bool xtsup; /* xtsup=on command line */
418 + bool xten; /* guest controlled, x2apic mode enabled */
419
420 /* DMA address translation */
421 bool dma_remap;