mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
vtd: boolean boot parameter to allow inclusive mapping of all memory below 4GB
Signed-off-by: Ross Philipson <ross.philipson@citrix.com>
This commit is contained in:
1 parent
3b38f56731
commit
6efe0dfb1c
8 files changed
+119
-16
No files matched your search
+49
-2
@@ -3236,9 +3236,56 @@ int get_page_type(struct page_info *page, unsigned long type)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int page_is_conventional_ram(unsigned long mfn)
|
||||
int page_is_ram_type(unsigned long mfn, unsigned long type)
|
||||
{
|
||||
return (efi_mem_type(pfn_to_paddr(mfn)) == EFI_CONVENTIONAL_MEMORY);
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
+27
-3
@@ -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;
|
||||
}
|
||||
|
||||
@@ -985,6 +985,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);
|
||||
@@ -1037,9 +1040,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.
|
||||
|
||||
@@ -377,6 +377,19 @@ 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 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;
|
||||
|
||||
@@ -992,8 +992,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);
|
||||
|
||||
/* Set up 1:1 page table for dom0 */
|
||||
iommu_set_dom0_mapping(d);
|
||||
|
||||
|
||||
@@ -27,6 +27,10 @@
|
||||
#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)
|
||||
{
|
||||
return map_domain_page(maddr >> PAGE_SHIFT_4K);
|
||||
@@ -153,9 +157,22 @@ void iommu_set_dom0_mapping(struct domain *d)
|
||||
|
||||
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);
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||