Skip to content

Commit

Permalink
VT-d: per-domain IOMMU bitmap needs to have dynamic size
Browse files Browse the repository at this point in the history
With no upper bound (anymore) on the number of IOMMUs, a fixed-size
64-bit map may be insufficient (systems with 40 IOMMUs have already been
observed).

Fixes: 27713fa ("VT-d: improve save/restore of registers across S3")
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Release-Acked-by: Ian Jackson <iwj@xenproject.org>
  • Loading branch information
jbeulich committed Nov 12, 2021
1 parent e2d0a42 commit c06e3d8
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 5 deletions.
15 changes: 11 additions & 4 deletions xen/drivers/passthrough/vtd/iommu.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ bool __read_mostly iommu_qinval = true;
bool __read_mostly iommu_snoop = true;
#endif

static unsigned int __initdata nr_iommus;
static unsigned int __read_mostly nr_iommus;

static struct iommu_ops vtd_ops;
static struct tasklet vtd_fault_tasklet;
Expand Down Expand Up @@ -645,7 +645,7 @@ static int __must_check iommu_flush_iotlb(struct domain *d, dfn_t dfn,

iommu = drhd->iommu;

if ( !test_bit(iommu->index, &hd->arch.vtd.iommu_bitmap) )
if ( !test_bit(iommu->index, hd->arch.vtd.iommu_bitmap) )
continue;

flush_dev_iotlb = !!find_ats_dev_drhd(iommu);
Expand Down Expand Up @@ -1308,6 +1308,11 @@ static int intel_iommu_domain_init(struct domain *d)
{
struct domain_iommu *hd = dom_iommu(d);

hd->arch.vtd.iommu_bitmap = xzalloc_array(unsigned long,
BITS_TO_LONGS(nr_iommus));
if ( !hd->arch.vtd.iommu_bitmap )
return -ENOMEM;

hd->arch.vtd.agaw = width_to_agaw(DEFAULT_DOMAIN_ADDRESS_WIDTH);

return 0;
Expand Down Expand Up @@ -1457,7 +1462,7 @@ int domain_context_mapping_one(
if ( rc > 0 )
rc = 0;

set_bit(iommu->index, &hd->arch.vtd.iommu_bitmap);
set_bit(iommu->index, hd->arch.vtd.iommu_bitmap);

unmap_vtd_domain_page(context_entries);

Expand Down Expand Up @@ -1789,7 +1794,7 @@ static int domain_context_unmap(struct domain *domain, u8 devfn,

if ( !found )
{
clear_bit(iommu->index, &dom_iommu(domain)->arch.vtd.iommu_bitmap);
clear_bit(iommu->index, dom_iommu(domain)->arch.vtd.iommu_bitmap);
cleanup_domid_map(domain, iommu);
}

Expand Down Expand Up @@ -1819,6 +1824,8 @@ static void iommu_domain_teardown(struct domain *d)

for_each_drhd_unit ( drhd )
cleanup_domid_map(d, drhd->iommu);

XFREE(hd->arch.vtd.iommu_bitmap);
}

static int __must_check intel_iommu_map_page(struct domain *d, dfn_t dfn,
Expand Down
2 changes: 1 addition & 1 deletion xen/include/asm-x86/iommu.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ struct arch_iommu
struct {
uint64_t pgd_maddr; /* io page directory machine address */
unsigned int agaw; /* adjusted guest address width, 0 is level 2 30-bit */
uint64_t iommu_bitmap; /* bitmap of iommu(s) that the domain uses */
unsigned long *iommu_bitmap; /* bitmap of iommu(s) that the domain uses */
} vtd;
/* AMD IOMMU */
struct {
Expand Down

0 comments on commit c06e3d8

Please sign in to comment.