From: Joao Martins <joao.m.mart...@oracle.com> Add a way to disable DMA translation support in AMD IOMMU by allowing to set IVHD HATDis to 1, and exposing HATS (Host Address Translation Size) as Reserved value.
Signed-off-by: Joao Martins <joao.m.mart...@oracle.com> Signed-off-by: Alejandro Jimenez <alejandro.j.jime...@oracle.com> --- hw/i386/acpi-build.c | 6 +++++- hw/i386/amd_iommu.c | 19 +++++++++++++++++++ hw/i386/amd_iommu.h | 1 + 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 423c4959fe809..9446a9f862ca4 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -1863,7 +1863,11 @@ build_amd_iommu(GArray *table_data, BIOSLinker *linker, const char *oem_id, /* IOMMU info */ build_append_int_noprefix(table_data, 0, 2); /* IOMMU Attributes */ - build_append_int_noprefix(table_data, 0, 4); + if (!s->iommu.dma_translation) { + build_append_int_noprefix(table_data, (1UL << 0) /* HATDis */, 4); + } else { + build_append_int_noprefix(table_data, 0, 4); + } /* EFR Register Image */ build_append_int_noprefix(table_data, amdvi_extended_feature_register(s), diff --git a/hw/i386/amd_iommu.c b/hw/i386/amd_iommu.c index b6851784fb9f1..378e0cb55eab6 100644 --- a/hw/i386/amd_iommu.c +++ b/hw/i386/amd_iommu.c @@ -107,6 +107,9 @@ uint64_t amdvi_extended_feature_register(AMDVIState *s) if (s->xtsup) { feature |= AMDVI_FEATURE_XT; } + if (!s->iommu.dma_translation) { + feature |= AMDVI_HATS_MODE_RESERVED; + } return feature; } @@ -472,6 +475,9 @@ static inline uint64_t amdvi_get_perms(uint64_t entry) static bool amdvi_validate_dte(AMDVIState *s, uint16_t devid, uint64_t *dte) { + + uint64_t root; + if ((dte[0] & AMDVI_DTE_QUAD0_RESERVED) || (dte[1] & AMDVI_DTE_QUAD1_RESERVED) || (dte[2] & AMDVI_DTE_QUAD2_RESERVED) || @@ -482,6 +488,19 @@ static bool amdvi_validate_dte(AMDVIState *s, uint16_t devid, return false; } + /* + * 1 = Host Address Translation is not supported. Value in MMIO Offset + * 0030h[HATS] is not meaningful. A non-zero host page table root pointer + * in the DTE would result in an ILLEGAL_DEV_TABLE_ENTRY event. + */ + root = (dte[0] & AMDVI_DEV_PT_ROOT_MASK) >> 12; + if (root && !s->iommu.dma_translation) { + amdvi_log_illegaldevtab_error(s, devid, + s->devtab + + devid * AMDVI_DEVTAB_ENTRY_SIZE, 0); + return false; + } + return true; } diff --git a/hw/i386/amd_iommu.h b/hw/i386/amd_iommu.h index e1354686b6f03..daf82fc85f961 100644 --- a/hw/i386/amd_iommu.h +++ b/hw/i386/amd_iommu.h @@ -177,6 +177,7 @@ /* AMDVI paging mode */ #define AMDVI_GATS_MODE (2ULL << 12) #define AMDVI_HATS_MODE (2ULL << 10) +#define AMDVI_HATS_MODE_RESERVED (3ULL << 10) /* Page Table format */ -- 2.43.5