From: Ross Philipson Date: Fri, 20 Feb 2009 20:03:42 +0000 (-0500) Subject: Added reserved memory from e820 map to pages mapped into IOMMUs for X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=e18060e6c22734a274fee2139c563e9ad1b9ff0a;p=xenclient%2Fxen.git Added reserved memory from e820 map to pages mapped into IOMMUs for dom0. This is for broken BIOS issues where the RMRRs do not report the correct reserved ranges for devices. Changes to be committed: modified: xen/arch/ia64/xen/mm.c modified: xen/arch/x86/mm.c modified: xen/arch/x86/setup.c modified: xen/arch/x86/tboot.c modified: xen/drivers/passthrough/vtd/iommu.c modified: xen/drivers/video/vga.c modified: xen/include/xen/mm.h --- diff --git a/xen/arch/ia64/xen/mm.c b/xen/arch/ia64/xen/mm.c index 418a24b..1a4c24d 100644 --- a/xen/arch/ia64/xen/mm.c +++ b/xen/arch/ia64/xen/mm.c @@ -3180,12 +3180,19 @@ int get_page_type(struct page_info *page, u32 type) return 1; } -int page_is_conventional_ram(unsigned long mfn) /* CS 19085 mem to page */ -{ +int page_is_ram_type(unsigned long mfn, unsigned long type) /* CS 19085 mem to page */ +{ + /** + * N.B. This function should really be enhanced to return what is more in line with the e820 + * semantics for usable and reservered RAM. For example type RAM_TYPE_CONVENTIONAL can + * include the areas freed after OS loader calls ExitBootServices: + * EFI_LOADER_CODE, EFI_LOADER_DATA, EFI_BOOT_SERVICES_CODE, EFI_BOOT_SERVICES_DATA, and EFI_CONVENTIONAL_MEMORY + * The reserved regions would include: + * EFI_RUNTIME_SERVICES_CODE, EFI_RUNTIME_SERVICES_DATA, EFI_MEMORY_MAPPED_IO, EFI_MEMORY_MAPPED_IO_PORT_SPACE and EFI_PAL_CODE + */ return (efi_mem_type(pfn_to_paddr(mfn)) == EFI_CONVENTIONAL_MEMORY); } - long arch_memory_op(int op, XEN_GUEST_HANDLE(void) arg) { diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index b076282..4e8dd2d 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -287,15 +287,30 @@ void __init arch_init_memory(void) subarch_init_memory(); } -int page_is_conventional_ram(unsigned long mfn) /* CS 19085 mem to page, CS 19083 fixed test */ +int page_is_ram_type(unsigned long mfn, unsigned long mem_type) /* CS 19085 mem to page, CS 19083 fixed test */ { 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 --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c index e0a510b..39557b6 100644 --- a/xen/arch/x86/setup.c +++ b/xen/arch/x86/setup.c @@ -995,6 +995,9 @@ void __init __start_xen(unsigned long mbi_p) 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); @@ -1047,9 +1050,6 @@ void __init __start_xen(unsigned long mbi_p) 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 --git a/xen/arch/x86/tboot.c b/xen/arch/x86/tboot.c index 6b51bc3..608d34d 100644 --- a/xen/arch/x86/tboot.c +++ b/xen/arch/x86/tboot.c @@ -251,18 +251,6 @@ int __init tboot_parse_dmar_table(acpi_table_handler dmar_handler) return rc; } -int tboot_in_range(paddr_t start, paddr_t end) -{ - if ( g_tboot_shared == NULL || g_tboot_shared->version < 0x02 ) - return 0; - - start = max_t(paddr_t, start, g_tboot_shared->tboot_base); - end = min_t(paddr_t, end, - g_tboot_shared->tboot_base + g_tboot_shared->tboot_size); - - return start < end; -} - /* * Local variables: * mode: C diff --git a/xen/drivers/passthrough/vtd/iommu.c b/xen/drivers/passthrough/vtd/iommu.c index 905104d..6808bd6 100644 --- a/xen/drivers/passthrough/vtd/iommu.c +++ b/xen/drivers/passthrough/vtd/iommu.c @@ -1035,7 +1035,6 @@ static int intel_iommu_domain_init(struct domain *d) if ( d->domain_id == 0 ) { extern int xen_in_range(paddr_t start, paddr_t end); - extern int tboot_in_range(paddr_t start, paddr_t end); /* * Set up 1:1 page table for dom0 except the critical segments @@ -1043,12 +1042,10 @@ static int intel_iommu_domain_init(struct domain *d) */ for ( i = 0; i < max_page; i++ ) { - /* CS 19084 remove tboot_in_range, CS 19085 use page_is_conventional_ram */ - /*if ( !page_is_conventional_ram(i) || + /* 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) || xen_in_range(i << PAGE_SHIFT, (i + 1) << PAGE_SHIFT) ) - continue;*/ - if ( xen_in_range(i << PAGE_SHIFT_4K, (i + 1) << PAGE_SHIFT_4K) || - tboot_in_range(i << PAGE_SHIFT_4K, (i + 1) << PAGE_SHIFT_4K) ) continue; iommu_map_page(d, i, i); diff --git a/xen/drivers/video/vga.c b/xen/drivers/video/vga.c index 302899a..05a704b 100644 --- a/xen/drivers/video/vga.c +++ b/xen/drivers/video/vga.c @@ -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)) || /* CS 19085 mem to page */ + if ( page_is_ram_type(paddr_to_pfn(0xB8000), RAM_TYPE_CONVENTIONAL) || /* CS 19085 mem to page */ ((video = ioremap(0xB8000, 0x8000)) == NULL) ) return; outw(0x200a, 0x3d4); /* disable cursor */ diff --git a/xen/include/xen/mm.h b/xen/include/xen/mm.h index 1c0733e..02eacf5 100644 --- a/xen/include/xen/mm.h +++ b/xen/include/xen/mm.h @@ -101,8 +101,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 */