AMD IOMMU: only disable when certain IVRS consistency checks fail After some more thought on the XSA-36 and specifically the comments we got regarding disabling the IOMMU in this situation altogether making things worse instead of better, I came to the conclusion that we can actually restrict the action in affected cases to just disabling interrupt remapping. That doesn't make the situation worse than prior to the XSA-36 fixes (where interrupt remapping didn't really protect domains from one another), but allows at least DMA isolation to still be utilized. Signed-off-by: Jan Beulich --- v2: Split off generic and VT-d code changes to a separate, prerequisite patch. Rather than disabling interrupt remapping here, do the respective checks only when interrupt remapping is to be enabled, thus allowing "iommu=no-intremap" to be used to enable DMA remapping inspite of the errata detected here. --- a/xen/drivers/passthrough/amd/iommu_acpi.c +++ b/xen/drivers/passthrough/amd/iommu_acpi.c @@ -659,6 +659,8 @@ static u16 __init parse_ivhd_device_spec switch ( special->variety ) { case ACPI_IVHD_IOAPIC: + if ( !iommu_intremap ) + break; /* * Some BIOSes have IOAPIC broken entries so we check for IVRS * consistency here --- whether entry's IOAPIC ID is valid and @@ -921,7 +923,7 @@ static int __init parse_ivrs_table(struc } /* Each IO-APIC must have been mentioned in the table. */ - for ( apic = 0; !error && apic < nr_ioapics; ++apic ) + for ( apic = 0; !error && iommu_intremap && apic < nr_ioapics; ++apic ) { if ( !nr_ioapic_entries[apic] || ioapic_sbdf[IO_APIC_ID(apic)].pin_setup ) --- a/xen/drivers/passthrough/amd/iommu_init.c +++ b/xen/drivers/passthrough/amd/iommu_init.c @@ -1194,7 +1194,8 @@ int __init amd_iommu_init(void) BUG_ON( !iommu_found() ); - if ( amd_iommu_perdev_intremap && amd_sp5100_erratum28() ) + if ( iommu_intremap && amd_iommu_perdev_intremap && + amd_sp5100_erratum28() ) goto error_out; ivrs_bdf_entries = amd_iommu_get_ivrs_dev_entries(); @@ -1211,7 +1212,7 @@ int __init amd_iommu_init(void) goto error_out; /* initialize io-apic interrupt remapping entries */ - if ( amd_iommu_setup_ioapic_remapping() != 0 ) + if ( iommu_intremap && amd_iommu_setup_ioapic_remapping() != 0 ) goto error_out; /* allocate and initialize a global device table shared by all iommus */