# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1235993003 0
# Node ID 507b264f0a21a4e4fa30177ee28e1ae645eb9799
# Parent 35baf43f271363c7b71d3fba44a469590841df3a
vtd: boolean boot parameter to allow inclusive mapping of all memory below 4GB
Signed-off-by: Ross Philipson <ross.philipson@xxxxxxxxxx>
---
xen/arch/ia64/xen/mm.c | 53 ++++++++++++++++++++++++++++++++--
xen/arch/x86/mm.c | 30 +++++++++++++++++--
xen/arch/x86/setup.c | 6 +--
xen/drivers/passthrough/vtd/dmar.c | 13 ++++++++
xen/drivers/passthrough/vtd/iommu.c | 2 -
xen/drivers/passthrough/vtd/x86/vtd.c | 23 ++++++++++++--
xen/drivers/video/vga.c | 2 -
xen/include/xen/mm.h | 8 +++--
8 files changed, 120 insertions(+), 17 deletions(-)
diff -r 35baf43f2713 -r 507b264f0a21 xen/arch/ia64/xen/mm.c
--- a/xen/arch/ia64/xen/mm.c Mon Mar 02 11:11:19 2009 +0000
+++ b/xen/arch/ia64/xen/mm.c Mon Mar 02 11:23:23 2009 +0000
@@ -3236,9 +3236,56 @@ int get_page_type(struct page_info *page
return 1;
}
-int page_is_conventional_ram(unsigned long mfn)
-{
- return (efi_mem_type(pfn_to_paddr(mfn)) == EFI_CONVENTIONAL_MEMORY);
+int page_is_ram_type(unsigned long mfn, unsigned long type)
+{
+ u32 mem_type = efi_mem_type(pfn_to_paddr(mfn));
+
+ if (type & RAM_TYPE_CONVENTIONAL)
+ {
+ switch (mem_type)
+ {
+ case EFI_BOOT_SERVICES_CODE:
+ case EFI_BOOT_SERVICES_DATA:
+ case EFI_LOADER_CODE:
+ case EFI_LOADER_DATA:
+ case EFI_CONVENTIONAL_MEMORY:
+ return 1;
+ default:
+ break;
+ }
+ }
+ if (type & RAM_TYPE_RESERVED)
+ {
+ switch (mem_type)
+ {
+ case EFI_RUNTIME_SERVICES_CODE:
+ case EFI_RUNTIME_SERVICES_DATA:
+ case EFI_RESERVED_TYPE:
+ case EFI_MEMORY_MAPPED_IO:
+ case EFI_MEMORY_MAPPED_IO_PORT_SPACE:
+ case EFI_PAL_CODE:
+ return 1;
+ default:
+ break;
+ }
+ }
+ if (type & RAM_TYPE_ACPI)
+ {
+ switch (mem_type)
+ {
+ case EFI_ACPI_RECLAIM_MEMORY:
+ case EFI_ACPI_MEMORY_NVS:
+ return 1;
+ default:
+ break;
+ }
+ }
+ else if (type & RAM_TYPE_UNUSABLE)
+ {
+ return (mem_type == EFI_UNUSABLE_MEMORY);
+ }
+
+ return 0;
}
diff -r 35baf43f2713 -r 507b264f0a21 xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Mon Mar 02 11:11:19 2009 +0000
+++ b/xen/arch/x86/mm.c Mon Mar 02 11:23:23 2009 +0000
@@ -279,15 +279,39 @@ void __init arch_init_memory(void)
subarch_init_memory();
}
-int page_is_conventional_ram(unsigned long mfn)
+int page_is_ram_type(unsigned long mfn, unsigned long mem_type)
{
uint64_t maddr = pfn_to_paddr(mfn);
int i;
for ( i = 0; i < e820.nr_map; i++ )
{
- if ( (e820.map[i].type == E820_RAM) &&
- (e820.map[i].addr <= maddr) &&
+ switch ( e820.map[i].type )
+ {
+ case E820_RAM:
+ if ( mem_type & RAM_TYPE_CONVENTIONAL )
+ break;
+ continue;
+ case E820_RESERVED:
+ if ( mem_type & RAM_TYPE_RESERVED )
+ break;
+ continue;
+ case E820_UNUSABLE:
+ if ( mem_type & RAM_TYPE_UNUSABLE )
+ break;
+ continue;
+ case E820_ACPI:
+ case E820_NVS:
+ if ( mem_type & RAM_TYPE_ACPI )
+ break;
+ continue;
+ default:
+ /* unknown */
+ continue;
+ }
+
+ /* Test the range. */
+ if ( (e820.map[i].addr <= maddr) &&
((e820.map[i].addr + e820.map[i].size) >= (maddr + PAGE_SIZE)) )
return 1;
}
diff -r 35baf43f2713 -r 507b264f0a21 xen/arch/x86/setup.c
--- a/xen/arch/x86/setup.c Mon Mar 02 11:11:19 2009 +0000
+++ b/xen/arch/x86/setup.c Mon Mar 02 11:23:23 2009 +0000
@@ -985,6 +985,9 @@ void __init __start_xen(unsigned long mb
if ( opt_watchdog )
watchdog_enable();
+
+ if ( !tboot_protect_mem_regions() )
+ panic("Could not protect TXT memory regions\n");
/* Create initial domain 0. */
dom0 = domain_create(0, 0, DOM0_SSIDREF);
@@ -1037,9 +1040,6 @@ void __init __start_xen(unsigned long mb
if ( xen_cpuidle )
xen_processor_pmbits |= XEN_PROCESSOR_PM_CX;
- if ( !tboot_protect_mem_regions() )
- panic("Could not protect TXT memory regions\n");
-
/*
* We're going to setup domain0 using the module(s) that we stashed safely
* above our heap. The second module, if present, is an initrd ramdisk.
diff -r 35baf43f2713 -r 507b264f0a21 xen/drivers/passthrough/vtd/dmar.c
--- a/xen/drivers/passthrough/vtd/dmar.c Mon Mar 02 11:11:19 2009 +0000
+++ b/xen/drivers/passthrough/vtd/dmar.c Mon Mar 02 11:23:23 2009 +0000
@@ -377,6 +377,19 @@ acpi_parse_one_rmrr(struct acpi_dmar_ent
return -EFAULT;
}
+#ifdef CONFIG_X86
+ /* This check is here simply to detect when RMRR values are not properly
represented in the
+ system memory map and inform the user */
+ 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_inclusive_mapping=1 parameter may be needed.\n",
+ rmrr->base_address, rmrr->end_address);
+ }
+#endif
+
rmrru = xmalloc(struct acpi_rmrr_unit);
if ( !rmrru )
return -ENOMEM;
diff -r 35baf43f2713 -r 507b264f0a21 xen/drivers/passthrough/vtd/iommu.c
--- a/xen/drivers/passthrough/vtd/iommu.c Mon Mar 02 11:11:19 2009 +0000
+++ b/xen/drivers/passthrough/vtd/iommu.c Mon Mar 02 11:23:23 2009 +0000
@@ -992,8 +992,6 @@ static int intel_iommu_domain_init(struc
if ( d->domain_id == 0 )
{
- extern int xen_in_range(paddr_t start, paddr_t end);
-
/* Set up 1:1 page table for dom0 */
iommu_set_dom0_mapping(d);
diff -r 35baf43f2713 -r 507b264f0a21 xen/drivers/passthrough/vtd/x86/vtd.c
--- a/xen/drivers/passthrough/vtd/x86/vtd.c Mon Mar 02 11:11:19 2009 +0000
+++ b/xen/drivers/passthrough/vtd/x86/vtd.c Mon Mar 02 11:23:23 2009 +0000
@@ -26,6 +26,10 @@
#include "../iommu.h"
#include "../dmar.h"
#include "../vtd.h"
+
+/* iommu_inclusive_mapping: when set, all memory below 4GB is included in dom0
1-1 iommu mappings except xen and unusable regions */
+static int iommu_inclusive_mapping = 0;
+boolean_param("iommu_inclusive_mapping", iommu_inclusive_mapping);
void *map_vtd_domain_page(u64 maddr)
{
@@ -153,9 +157,22 @@ void iommu_set_dom0_mapping(struct domai
for ( i = 0; i < max_page; i++ )
{
- /* Set up 1:1 mapping for dom0 for all RAM except Xen bits. */
- if ( !page_is_conventional_ram(i) ||
- xen_in_range(i << PAGE_SHIFT, (i + 1) << PAGE_SHIFT) )
+ /* Set up 1:1 mapping for dom0 */
+ if ( !page_is_ram_type(i, RAM_TYPE_CONVENTIONAL) )
+ {
+ /* Default it to use only conventional RAM areas and let RMRRs
include needed reserved regions */
+ if (iommu_inclusive_mapping)
+ {
+ /* When set, the inclusive mapping maps in everything below
4GB except unusable ranges */
+ if ( (i >= 0x100000) || page_is_ram_type(i, RAM_TYPE_UNUSABLE)
)
+ continue;
+ }
+ else
+ continue;
+ }
+
+ /* Exclude Xen bits */
+ if ( xen_in_range(i << PAGE_SHIFT, (i + 1) << PAGE_SHIFT) )
continue;
tmp = 1 << (PAGE_SHIFT - PAGE_SHIFT_4K);
diff -r 35baf43f2713 -r 507b264f0a21 xen/drivers/video/vga.c
--- a/xen/drivers/video/vga.c Mon Mar 02 11:11:19 2009 +0000
+++ b/xen/drivers/video/vga.c Mon Mar 02 11:23:23 2009 +0000
@@ -79,7 +79,7 @@ void __init vga_init(void)
switch ( vga_console_info.video_type )
{
case XEN_VGATYPE_TEXT_MODE_3:
- if ( page_is_conventional_ram(paddr_to_pfn(0xB8000)) ||
+ if ( page_is_ram_type(paddr_to_pfn(0xB8000), RAM_TYPE_CONVENTIONAL) ||
((video = ioremap(0xB8000, 0x8000)) == NULL) )
return;
outw(0x200a, 0x3d4); /* disable cursor */
diff -r 35baf43f2713 -r 507b264f0a21 xen/include/xen/mm.h
--- a/xen/include/xen/mm.h Mon Mar 02 11:11:19 2009 +0000
+++ b/xen/include/xen/mm.h Mon Mar 02 11:23:23 2009 +0000
@@ -273,8 +273,12 @@ unsigned long avail_scrub_pages(void);
int guest_remove_page(struct domain *d, unsigned long gmfn);
-/* Returns TRUE if the whole page at @mfn is ordinary RAM. */
-int page_is_conventional_ram(unsigned long mfn);
+#define RAM_TYPE_CONVENTIONAL 0x00000001
+#define RAM_TYPE_RESERVED 0x00000002
+#define RAM_TYPE_UNUSABLE 0x00000004
+#define RAM_TYPE_ACPI 0x00000008
+/* Returns TRUE if the whole page at @mfn is of the requested RAM type(s)
above. */
+int page_is_ram_type(unsigned long mfn, unsigned long mem_type);
extern unsigned long *alloc_bitmap; /* for vmcoreinfo */
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|