diff -r f8187a343ad2 xen/arch/ia64/xen/mm.c --- a/xen/arch/ia64/xen/mm.c Fri Feb 20 17:02:36 2009 +0000 +++ b/xen/arch/ia64/xen/mm.c Mon Feb 23 14:35:20 2009 -0500 @@ -3236,8 +3236,13 @@ int get_page_type(struct page_info *page return 1; } -int page_is_conventional_ram(unsigned long mfn) +int page_is_ram_type(unsigned long mfn, unsigned long type) { + /** + * N.B. This function could be enhanced to return what is more in line with the e820 + * semantics for usable and reservered RAM. Since it is only used once in vga.c in + * the IA64 case it is ok to ignore the type parameter. + */ return (efi_mem_type(pfn_to_paddr(mfn)) == EFI_CONVENTIONAL_MEMORY); } diff -r f8187a343ad2 xen/arch/x86/mm.c --- a/xen/arch/x86/mm.c Fri Feb 20 17:02:36 2009 +0000 +++ b/xen/arch/x86/mm.c Mon Feb 23 14:35:20 2009 -0500 @@ -279,15 +279,30 @@ 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; + 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 f8187a343ad2 xen/arch/x86/setup.c --- a/xen/arch/x86/setup.c Fri Feb 20 17:02:36 2009 +0000 +++ b/xen/arch/x86/setup.c Mon Feb 23 14:35:20 2009 -0500 @@ -986,6 +986,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); if ( (dom0 == NULL) || (alloc_vcpu(dom0, 0, 0) == NULL) ) @@ -1036,9 +1039,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 diff -r f8187a343ad2 xen/drivers/passthrough/vtd/dmar.c --- a/xen/drivers/passthrough/vtd/dmar.c Fri Feb 20 17:02:36 2009 +0000 +++ b/xen/drivers/passthrough/vtd/dmar.c Mon Feb 23 14:35:20 2009 -0500 @@ -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_include_reserved=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 f8187a343ad2 xen/drivers/passthrough/vtd/iommu.c --- a/xen/drivers/passthrough/vtd/iommu.c Fri Feb 20 17:02:36 2009 +0000 +++ b/xen/drivers/passthrough/vtd/iommu.c Mon Feb 23 14:35:20 2009 -0500 @@ -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 f8187a343ad2 xen/drivers/passthrough/vtd/x86/vtd.c --- a/xen/drivers/passthrough/vtd/x86/vtd.c Fri Feb 20 17:02:36 2009 +0000 +++ b/xen/drivers/passthrough/vtd/x86/vtd.c Mon Feb 23 14:35:20 2009 -0500 @@ -26,6 +26,10 @@ #include "../iommu.h" #include "../dmar.h" #include "../vtd.h" + +/* 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); void *map_vtd_domain_page(u64 maddr) { @@ -147,15 +151,22 @@ void iommu_set_dom0_mapping(struct domai void iommu_set_dom0_mapping(struct domain *d) { u64 i, j, tmp; + u32 mem_type; extern int xen_in_range(paddr_t start, paddr_t end); BUG_ON(d->domain_id != 0); + /* input param overrides default memory mapping */ + mem_type = RAM_TYPE_CONVENTIONAL; + if (iommu_include_reserved) + mem_type |= RAM_TYPE_RESERVED; + 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 for all RAM except Xen bits and reserved, unusable, etc. */ + /* Modified to include reserved memory regions for some broken BIOS' */ + if ( !page_is_ram_type(i, mem_type) || + xen_in_range(i << PAGE_SHIFT, (i + 1) << PAGE_SHIFT) ) continue; tmp = 1 << (PAGE_SHIFT - PAGE_SHIFT_4K); diff -r f8187a343ad2 xen/drivers/video/vga.c --- a/xen/drivers/video/vga.c Fri Feb 20 17:02:36 2009 +0000 +++ b/xen/drivers/video/vga.c Mon Feb 23 14:35:20 2009 -0500 @@ -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 f8187a343ad2 xen/include/xen/mm.h --- a/xen/include/xen/mm.h Fri Feb 20 17:02:36 2009 +0000 +++ b/xen/include/xen/mm.h Mon Feb 23 14:35:20 2009 -0500 @@ -273,8 +273,10 @@ 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 +/* 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 */