diff --git a/xen/drivers/passthrough/amd/iommu_acpi.c b/xen/drivers/passthrough/amd/iommu_acpi.c index 084dfeeefb..c98bed8343 100644 --- a/xen/drivers/passthrough/amd/iommu_acpi.c +++ b/xen/drivers/passthrough/amd/iommu_acpi.c @@ -65,7 +65,11 @@ static void __init add_ivrs_mapping_entry( /* override flags for range of devices */ ivrs_mappings[bdf].device_flags = flags; - if (ivrs_mappings[alias_id].intremap_table == NULL ) + /* Don't map an IOMMU by itself. */ + if ( iommu->bdf == bdf ) + return; + + if ( !ivrs_mappings[alias_id].intremap_table ) { /* allocate per-device interrupt remapping table */ if ( amd_iommu_perdev_intremap ) @@ -81,8 +85,9 @@ static void __init add_ivrs_mapping_entry( ivrs_mappings[alias_id].intremap_inuse = shared_intremap_inuse; } } - /* Assign IOMMU hardware, but don't map an IOMMU by itself. */ - ivrs_mappings[bdf].iommu = iommu->bdf != bdf ? iommu : NULL; + + /* Assign IOMMU hardware. */ + ivrs_mappings[bdf].iommu = iommu; } static struct amd_iommu * __init find_iommu_from_bdf_cap( diff --git a/xen/drivers/passthrough/amd/iommu_init.c b/xen/drivers/passthrough/amd/iommu_init.c index 35d3a77a79..a4480858cf 100644 --- a/xen/drivers/passthrough/amd/iommu_init.c +++ b/xen/drivers/passthrough/amd/iommu_init.c @@ -1122,7 +1122,8 @@ int iterate_ivrs_mappings(int (*handler)(u16 seg, struct ivrs_mappings *)) return rc; } -int iterate_ivrs_entries(int (*handler)(u16 seg, struct ivrs_mappings *)) +int iterate_ivrs_entries(int (*handler)(const struct amd_iommu *, + struct ivrs_mappings *)) { u16 seg = 0; int rc = 0; @@ -1135,7 +1136,12 @@ int iterate_ivrs_entries(int (*handler)(u16 seg, struct ivrs_mappings *)) break; seg = IVRS_MAPPINGS_SEG(map); for ( bdf = 0; !rc && bdf < ivrs_bdf_entries; ++bdf ) - rc = handler(seg, map + bdf); + { + const struct amd_iommu *iommu = map[bdf].iommu; + + if ( iommu && map[bdf].dte_requestor_id == bdf ) + rc = handler(iommu, &map[bdf]); + } } while ( !rc && ++seg ); return rc; diff --git a/xen/drivers/passthrough/amd/iommu_intr.c b/xen/drivers/passthrough/amd/iommu_intr.c index edc3cae431..e22a98e312 100644 --- a/xen/drivers/passthrough/amd/iommu_intr.c +++ b/xen/drivers/passthrough/amd/iommu_intr.c @@ -607,7 +607,7 @@ void amd_iommu_read_msi_from_ire( } int __init amd_iommu_free_intremap_table( - u16 seg, struct ivrs_mappings *ivrs_mapping) + const struct amd_iommu *iommu, struct ivrs_mappings *ivrs_mapping) { void *tb = ivrs_mapping->intremap_table; @@ -683,14 +683,15 @@ static void dump_intremap_table(const u32 *table) } } -static int dump_intremap_mapping(u16 seg, struct ivrs_mappings *ivrs_mapping) +static int dump_intremap_mapping(const struct amd_iommu *iommu, + struct ivrs_mappings *ivrs_mapping) { unsigned long flags; if ( !ivrs_mapping ) return 0; - printk(" %04x:%02x:%02x:%u:\n", seg, + printk(" %04x:%02x:%02x:%u:\n", iommu->seg, PCI_BUS(ivrs_mapping->dte_requestor_id), PCI_SLOT(ivrs_mapping->dte_requestor_id), PCI_FUNC(ivrs_mapping->dte_requestor_id)); diff --git a/xen/include/asm-x86/amd-iommu.h b/xen/include/asm-x86/amd-iommu.h index ad8e4a35a2..b792f7f432 100644 --- a/xen/include/asm-x86/amd-iommu.h +++ b/xen/include/asm-x86/amd-iommu.h @@ -127,7 +127,8 @@ extern u8 ivhd_type; struct ivrs_mappings *get_ivrs_mappings(u16 seg); int iterate_ivrs_mappings(int (*)(u16 seg, struct ivrs_mappings *)); -int iterate_ivrs_entries(int (*)(u16 seg, struct ivrs_mappings *)); +int iterate_ivrs_entries(int (*)(const struct amd_iommu *, + struct ivrs_mappings *)); /* iommu tables in guest space */ struct mmio_reg { diff --git a/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h b/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h index e0d5d23978..494464080b 100644 --- a/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h +++ b/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h @@ -98,7 +98,8 @@ struct amd_iommu *find_iommu_for_device(int seg, int bdf); /* interrupt remapping */ int amd_iommu_setup_ioapic_remapping(void); void *amd_iommu_alloc_intremap_table(unsigned long **); -int amd_iommu_free_intremap_table(u16 seg, struct ivrs_mappings *); +int amd_iommu_free_intremap_table( + const struct amd_iommu *, struct ivrs_mappings *); void amd_iommu_ioapic_update_ire( unsigned int apic, unsigned int reg, unsigned int value); unsigned int amd_iommu_read_ioapic_from_ire(