diff --git a/xen/drivers/passthrough/vtd/iommu.c b/xen/drivers/passthrough/vtd/iommu.c index 6428c8fe3e..10c71132db 100644 --- a/xen/drivers/passthrough/vtd/iommu.c +++ b/xen/drivers/passthrough/vtd/iommu.c @@ -57,7 +57,7 @@ bool __read_mostly iommu_qinval = true; bool __read_mostly iommu_snoop = true; #endif -int nr_iommus; +static unsigned int __initdata nr_iommus; static struct iommu_ops vtd_ops; static struct tasklet vtd_fault_tasklet; @@ -1165,13 +1165,6 @@ int __init iommu_alloc(struct acpi_drhd_unit *drhd) unsigned long sagaw, nr_dom; int agaw; - if ( nr_iommus >= MAX_IOMMUS ) - { - dprintk(XENLOG_ERR VTDPREFIX, - "IOMMU: nr_iommus %d > MAX_IOMMUS\n", nr_iommus + 1); - return -ENOMEM; - } - iommu = xzalloc(struct vtd_iommu); if ( iommu == NULL ) return -ENOMEM; @@ -2226,6 +2219,10 @@ static void __hwdom_init setup_hwdom_rmrr(struct domain *d) pcidevs_unlock(); } +static struct iommu_state { + uint32_t fectl; +} *__read_mostly iommu_state; + static int __init vtd_setup(void) { struct acpi_drhd_unit *drhd; @@ -2251,6 +2248,13 @@ static int __init vtd_setup(void) goto error; } + iommu_state = xmalloc_array(struct iommu_state, nr_iommus); + if ( !iommu_state ) + { + ret = -ENOMEM; + goto error; + } + /* We enable the following features only if they are supported by all VT-d * engines: Snoop Control, DMA passthrough, Queued Invalidation, Interrupt * Remapping, and Posted Interrupt @@ -2508,8 +2512,6 @@ static int intel_iommu_group_id(u16 seg, u8 bus, u8 devfn) return PCI_BDF2(bus, devfn); } -static u32 iommu_state[MAX_IOMMUS][MAX_IOMMU_REGS]; - static int __must_check vtd_suspend(void) { struct acpi_drhd_unit *drhd; @@ -2534,14 +2536,7 @@ static int __must_check vtd_suspend(void) iommu = drhd->iommu; i = iommu->index; - iommu_state[i][DMAR_FECTL_REG] = - (u32) dmar_readl(iommu->reg, DMAR_FECTL_REG); - iommu_state[i][DMAR_FEDATA_REG] = - (u32) dmar_readl(iommu->reg, DMAR_FEDATA_REG); - iommu_state[i][DMAR_FEADDR_REG] = - (u32) dmar_readl(iommu->reg, DMAR_FEADDR_REG); - iommu_state[i][DMAR_FEUADDR_REG] = - (u32) dmar_readl(iommu->reg, DMAR_FEUADDR_REG); + iommu_state[i].fectl = dmar_readl(iommu->reg, DMAR_FECTL_REG); /* don't disable VT-d engine when force_iommu is set. */ if ( force_iommu ) @@ -2594,15 +2589,13 @@ static void vtd_resume(void) for_each_drhd_unit ( drhd ) { iommu = drhd->iommu; - i = iommu->index; spin_lock_irqsave(&iommu->register_lock, flags); - dmar_writel(iommu->reg, DMAR_FEDATA_REG, - iommu_state[i][DMAR_FEDATA_REG]); - dmar_writel(iommu->reg, DMAR_FEADDR_REG, - iommu_state[i][DMAR_FEADDR_REG]); - dmar_writel(iommu->reg, DMAR_FEUADDR_REG, - iommu_state[i][DMAR_FEUADDR_REG]); + dmar_writel(iommu->reg, DMAR_FEDATA_REG, iommu->msi.msg.data); + dmar_writel(iommu->reg, DMAR_FEADDR_REG, iommu->msi.msg.address_lo); + if ( x2apic_enabled ) + dmar_writel(iommu->reg, DMAR_FEUADDR_REG, + iommu->msi.msg.address_hi); spin_unlock_irqrestore(&iommu->register_lock, flags); } @@ -2615,8 +2608,7 @@ static void vtd_resume(void) i = iommu->index; spin_lock_irqsave(&iommu->register_lock, flags); - dmar_writel(iommu->reg, DMAR_FECTL_REG, - (u32) iommu_state[i][DMAR_FECTL_REG]); + dmar_writel(iommu->reg, DMAR_FECTL_REG, iommu_state[i].fectl); spin_unlock_irqrestore(&iommu->register_lock, flags); iommu_enable_translation(drhd); diff --git a/xen/drivers/passthrough/vtd/iommu.h b/xen/drivers/passthrough/vtd/iommu.h index 216791b3d6..6f41068c09 100644 --- a/xen/drivers/passthrough/vtd/iommu.h +++ b/xen/drivers/passthrough/vtd/iommu.h @@ -499,8 +499,6 @@ struct qinval_entry { #define VTD_PAGE_TABLE_LEVEL_3 3 #define VTD_PAGE_TABLE_LEVEL_4 4 -#define MAX_IOMMU_REGS 0xc0 - extern struct list_head acpi_drhd_units; extern struct list_head acpi_rmrr_units; extern struct list_head acpi_ioapic_units; diff --git a/xen/include/asm-x86/iommu.h b/xen/include/asm-x86/iommu.h index 970eb06ffa..65a0b02f60 100644 --- a/xen/include/asm-x86/iommu.h +++ b/xen/include/asm-x86/iommu.h @@ -22,7 +22,6 @@ #include #define DEFAULT_DOMAIN_ADDRESS_WIDTH 48 -#define MAX_IOMMUS 32 struct g2m_ioport { struct list_head list;