From 9f5921014bbec7c92eb60a27ee66718a274aa1f0 Mon Sep 17 00:00:00 2001 From: Ross Philipson Date: Sat, 21 Feb 2009 14:03:06 -0500 Subject: [PATCH] Add iommu_include_reserved boolean parameter to allow reserved memory to be included in iommu mappings (not included by default). Also adds a warning when the RMRRs do not match the system memory map. Changes to be committed: modified: xen/drivers/passthrough/vtd/iommu.c modified: xen/drivers/passthrough/vtd/dmar.c --- xen/drivers/passthrough/vtd/dmar.c | 14 ++++++++++++++ xen/drivers/passthrough/vtd/iommu.c | 14 ++++++++++++-- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/xen/drivers/passthrough/vtd/dmar.c b/xen/drivers/passthrough/vtd/dmar.c index ffcda32..245b1a7 100644 --- a/xen/drivers/passthrough/vtd/dmar.c +++ b/xen/drivers/passthrough/vtd/dmar.c @@ -356,6 +356,20 @@ acpi_parse_one_rmrr(struct acpi_dmar_entry_header *header) return -EFAULT; } +#ifdef CONFIG_X86 + /* This check is here simply to detect when RMRR values are not properly represented in the + system memory map. This check can be extended to IA64 if the page_is_ram_type() function + is updated to properly report what are reserved memory ranges */ + if ( (!page_is_ram_type(paddr_to_pfn(rmrr->base_address), RAM_TYPE_RESERVED))|| + (!page_is_ram_type(paddr_to_pfn(rmrr->end_address) - 1, RAM_TYPE_RESERVED)) ) + { + dprintk(XENLOG_WARNING VTDPREFIX, + "RMRR address range not in reserved memory base = %"PRIx64" end = %"PRIx64"; " \ + "iommu_include_reserved parameter may be needed\n", + rmrr->base_address, rmrr->end_address); + } +#endif + rmrru = xmalloc(struct acpi_rmrr_unit); if ( !rmrru ) return -ENOMEM; diff --git a/xen/drivers/passthrough/vtd/iommu.c b/xen/drivers/passthrough/vtd/iommu.c index 6808bd6..b48d500 100644 --- a/xen/drivers/passthrough/vtd/iommu.c +++ b/xen/drivers/passthrough/vtd/iommu.c @@ -40,6 +40,10 @@ static spinlock_t domid_bitmap_lock; /* protect domain id bitmap */ static int domid_bitmap_size; /* domain id bitmap size in bits */ static unsigned long *domid_bitmap; /* iommu domain id bitmap */ +/* iommu_include_reserved: include reserved memory ranges in dom0 1-1 iommu mappings if set */ +static int iommu_include_reserved = 0; +boolean_param("iommu_include_reserved", iommu_include_reserved); + static void setup_dom0_devices(struct domain *d); static void setup_dom0_rmrr(struct domain *d); @@ -1024,8 +1028,9 @@ static int intel_iommu_domain_init(struct domain *d) { struct hvm_iommu *hd = domain_hvm_iommu(d); struct iommu *iommu = NULL; - u64 i; struct acpi_drhd_unit *drhd; + u64 i; + u32 mem_type; drhd = list_entry(acpi_drhd_units.next, typeof(*drhd), list); iommu = drhd->iommu; @@ -1036,6 +1041,11 @@ static int intel_iommu_domain_init(struct domain *d) { extern int xen_in_range(paddr_t start, paddr_t end); + /* input param overrides default memory mapping */ + mem_type = RAM_TYPE_CONVENTIONAL; + if (iommu_include_reserved) + mem_type |= RAM_TYPE_RESERVED; + /* * Set up 1:1 page table for dom0 except the critical segments * like Xen and tboot. @@ -1044,7 +1054,7 @@ static int intel_iommu_domain_init(struct domain *d) { /* CS 19084 remove tboot_in_range, CS 19085 use page_is_conventional_ram */ /* Modified to include reserved memory regions - this fix will be pushed upstream */ - if ( !page_is_ram_type(i, RAM_TYPE_CONVENTIONAL|RAM_TYPE_RESERVED) || + if ( !page_is_ram_type(i, mem_type) || xen_in_range(i << PAGE_SHIFT, (i + 1) << PAGE_SHIFT) ) continue; -- 2.39.5