ia64/xen-unstable

changeset 19259:507b264f0a21

vtd: boolean boot parameter to allow inclusive mapping of all memory below 4GB

Signed-off-by: Ross Philipson <ross.philipson@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Mon Mar 02 11:23:23 2009 +0000 (2009-03-02)
parents 35baf43f2713
children 58edfadb2d87
files xen/arch/ia64/xen/mm.c xen/arch/x86/mm.c xen/arch/x86/setup.c xen/drivers/passthrough/vtd/dmar.c xen/drivers/passthrough/vtd/iommu.c xen/drivers/passthrough/vtd/x86/vtd.c xen/drivers/video/vga.c xen/include/xen/mm.h
line diff
     1.1 --- a/xen/arch/ia64/xen/mm.c	Mon Mar 02 11:11:19 2009 +0000
     1.2 +++ b/xen/arch/ia64/xen/mm.c	Mon Mar 02 11:23:23 2009 +0000
     1.3 @@ -3236,9 +3236,56 @@ int get_page_type(struct page_info *page
     1.4      return 1;
     1.5  }
     1.6  
     1.7 -int page_is_conventional_ram(unsigned long mfn)
     1.8 +int page_is_ram_type(unsigned long mfn, unsigned long type)
     1.9  {
    1.10 -    return (efi_mem_type(pfn_to_paddr(mfn)) == EFI_CONVENTIONAL_MEMORY);
    1.11 +    u32 mem_type = efi_mem_type(pfn_to_paddr(mfn));
    1.12 +
    1.13 +    if (type & RAM_TYPE_CONVENTIONAL)
    1.14 +    {
    1.15 +        switch (mem_type)
    1.16 +        {
    1.17 +        case EFI_BOOT_SERVICES_CODE:
    1.18 +        case EFI_BOOT_SERVICES_DATA:
    1.19 +        case EFI_LOADER_CODE:
    1.20 +        case EFI_LOADER_DATA:
    1.21 +        case EFI_CONVENTIONAL_MEMORY:
    1.22 +            return 1;
    1.23 +        default:
    1.24 +            break;
    1.25 +        }       
    1.26 +    }
    1.27 +    if (type & RAM_TYPE_RESERVED)
    1.28 +    {
    1.29 +        switch (mem_type)
    1.30 +        {
    1.31 +        case EFI_RUNTIME_SERVICES_CODE:
    1.32 +        case EFI_RUNTIME_SERVICES_DATA:
    1.33 +        case EFI_RESERVED_TYPE:
    1.34 +        case EFI_MEMORY_MAPPED_IO:
    1.35 +        case EFI_MEMORY_MAPPED_IO_PORT_SPACE:
    1.36 +        case EFI_PAL_CODE:
    1.37 +            return 1;
    1.38 +        default:
    1.39 +            break;
    1.40 +        }
    1.41 +    }
    1.42 +    if (type & RAM_TYPE_ACPI)
    1.43 +    {
    1.44 +        switch (mem_type)
    1.45 +        {
    1.46 +        case EFI_ACPI_RECLAIM_MEMORY:
    1.47 +        case EFI_ACPI_MEMORY_NVS:
    1.48 +            return 1;
    1.49 +        default:
    1.50 +            break;
    1.51 +        }
    1.52 +    }
    1.53 +    else if (type & RAM_TYPE_UNUSABLE)
    1.54 +    {
    1.55 +        return (mem_type == EFI_UNUSABLE_MEMORY);
    1.56 +    }
    1.57 +
    1.58 +    return 0;
    1.59  }
    1.60  
    1.61  
     2.1 --- a/xen/arch/x86/mm.c	Mon Mar 02 11:11:19 2009 +0000
     2.2 +++ b/xen/arch/x86/mm.c	Mon Mar 02 11:23:23 2009 +0000
     2.3 @@ -279,15 +279,39 @@ void __init arch_init_memory(void)
     2.4      subarch_init_memory();
     2.5  }
     2.6  
     2.7 -int page_is_conventional_ram(unsigned long mfn)
     2.8 +int page_is_ram_type(unsigned long mfn, unsigned long mem_type)
     2.9  {
    2.10      uint64_t maddr = pfn_to_paddr(mfn);
    2.11      int i;
    2.12  
    2.13      for ( i = 0; i < e820.nr_map; i++ )
    2.14      {
    2.15 -        if ( (e820.map[i].type == E820_RAM) &&
    2.16 -             (e820.map[i].addr <= maddr) &&
    2.17 +        switch ( e820.map[i].type )
    2.18 +        {
    2.19 +        case E820_RAM:
    2.20 +            if ( mem_type & RAM_TYPE_CONVENTIONAL )
    2.21 +                break;
    2.22 +            continue;
    2.23 +        case E820_RESERVED:
    2.24 +            if ( mem_type & RAM_TYPE_RESERVED )
    2.25 +                break;
    2.26 +            continue;
    2.27 +        case E820_UNUSABLE:
    2.28 +            if ( mem_type & RAM_TYPE_UNUSABLE )
    2.29 +                break;
    2.30 +            continue;
    2.31 +        case E820_ACPI:
    2.32 +        case E820_NVS:
    2.33 +            if ( mem_type & RAM_TYPE_ACPI )
    2.34 +                break;
    2.35 +            continue;
    2.36 +        default:
    2.37 +            /* unknown */
    2.38 +            continue;
    2.39 +        }
    2.40 +        
    2.41 +        /* Test the range. */
    2.42 +        if ( (e820.map[i].addr <= maddr) &&
    2.43               ((e820.map[i].addr + e820.map[i].size) >= (maddr + PAGE_SIZE)) )
    2.44              return 1;
    2.45      }
     3.1 --- a/xen/arch/x86/setup.c	Mon Mar 02 11:11:19 2009 +0000
     3.2 +++ b/xen/arch/x86/setup.c	Mon Mar 02 11:23:23 2009 +0000
     3.3 @@ -985,6 +985,9 @@ void __init __start_xen(unsigned long mb
     3.4  
     3.5      if ( opt_watchdog ) 
     3.6          watchdog_enable();
     3.7 +    
     3.8 +    if ( !tboot_protect_mem_regions() )
     3.9 +        panic("Could not protect TXT memory regions\n");
    3.10  
    3.11      /* Create initial domain 0. */
    3.12      dom0 = domain_create(0, 0, DOM0_SSIDREF);
    3.13 @@ -1037,9 +1040,6 @@ void __init __start_xen(unsigned long mb
    3.14      if ( xen_cpuidle )
    3.15          xen_processor_pmbits |= XEN_PROCESSOR_PM_CX;
    3.16  
    3.17 -    if ( !tboot_protect_mem_regions() )
    3.18 -        panic("Could not protect TXT memory regions\n");
    3.19 -
    3.20      /*
    3.21       * We're going to setup domain0 using the module(s) that we stashed safely
    3.22       * above our heap. The second module, if present, is an initrd ramdisk.
     4.1 --- a/xen/drivers/passthrough/vtd/dmar.c	Mon Mar 02 11:11:19 2009 +0000
     4.2 +++ b/xen/drivers/passthrough/vtd/dmar.c	Mon Mar 02 11:23:23 2009 +0000
     4.3 @@ -377,6 +377,19 @@ acpi_parse_one_rmrr(struct acpi_dmar_ent
     4.4          return -EFAULT;
     4.5      }
     4.6  
     4.7 +#ifdef CONFIG_X86
     4.8 +    /* This check is here simply to detect when RMRR values are not properly represented in the 
     4.9 +       system memory map and inform the user */
    4.10 +    if ( (!page_is_ram_type(paddr_to_pfn(rmrr->base_address), RAM_TYPE_RESERVED))||
    4.11 +         (!page_is_ram_type(paddr_to_pfn(rmrr->end_address) - 1, RAM_TYPE_RESERVED)) )
    4.12 +    {
    4.13 +        dprintk(XENLOG_WARNING VTDPREFIX,
    4.14 +                "RMRR address range not in reserved memory base = %"PRIx64" end = %"PRIx64"; " \
    4.15 +                "iommu_inclusive_mapping=1 parameter may be needed.\n",
    4.16 +                rmrr->base_address, rmrr->end_address);
    4.17 +    }
    4.18 +#endif
    4.19 +
    4.20      rmrru = xmalloc(struct acpi_rmrr_unit);
    4.21      if ( !rmrru )
    4.22          return -ENOMEM;
     5.1 --- a/xen/drivers/passthrough/vtd/iommu.c	Mon Mar 02 11:11:19 2009 +0000
     5.2 +++ b/xen/drivers/passthrough/vtd/iommu.c	Mon Mar 02 11:23:23 2009 +0000
     5.3 @@ -992,8 +992,6 @@ static int intel_iommu_domain_init(struc
     5.4  
     5.5      if ( d->domain_id == 0 )
     5.6      {
     5.7 -        extern int xen_in_range(paddr_t start, paddr_t end);
     5.8 -
     5.9          /* Set up 1:1 page table for dom0 */
    5.10          iommu_set_dom0_mapping(d);
    5.11  
     6.1 --- a/xen/drivers/passthrough/vtd/x86/vtd.c	Mon Mar 02 11:11:19 2009 +0000
     6.2 +++ b/xen/drivers/passthrough/vtd/x86/vtd.c	Mon Mar 02 11:23:23 2009 +0000
     6.3 @@ -27,6 +27,10 @@
     6.4  #include "../dmar.h"
     6.5  #include "../vtd.h"
     6.6  
     6.7 +/* iommu_inclusive_mapping: when set, all memory below 4GB is included in dom0 1-1 iommu mappings except xen and unusable regions */
     6.8 +static int iommu_inclusive_mapping = 0;
     6.9 +boolean_param("iommu_inclusive_mapping", iommu_inclusive_mapping);
    6.10 +
    6.11  void *map_vtd_domain_page(u64 maddr)
    6.12  {
    6.13      return map_domain_page(maddr >> PAGE_SHIFT_4K);
    6.14 @@ -153,9 +157,22 @@ void iommu_set_dom0_mapping(struct domai
    6.15  
    6.16      for ( i = 0; i < max_page; i++ )
    6.17      {
    6.18 -        /* Set up 1:1 mapping for dom0 for all RAM except Xen bits. */
    6.19 -        if ( !page_is_conventional_ram(i) ||
    6.20 -             xen_in_range(i << PAGE_SHIFT, (i + 1) << PAGE_SHIFT) )
    6.21 +        /* Set up 1:1 mapping for dom0 */
    6.22 +        if ( !page_is_ram_type(i, RAM_TYPE_CONVENTIONAL) )
    6.23 +        {
    6.24 +            /* Default it to use only conventional RAM areas and let RMRRs include needed reserved regions */
    6.25 +            if (iommu_inclusive_mapping)
    6.26 +            {
    6.27 +                /* When set, the inclusive mapping maps in everything below 4GB except unusable ranges */
    6.28 +                if ( (i >= 0x100000) || page_is_ram_type(i, RAM_TYPE_UNUSABLE) )
    6.29 +                    continue;
    6.30 +            }
    6.31 +            else
    6.32 +                continue;
    6.33 +        }
    6.34 +
    6.35 +        /* Exclude Xen bits */
    6.36 +        if ( xen_in_range(i << PAGE_SHIFT, (i + 1) << PAGE_SHIFT) )
    6.37              continue;
    6.38  
    6.39          tmp = 1 << (PAGE_SHIFT - PAGE_SHIFT_4K);
     7.1 --- a/xen/drivers/video/vga.c	Mon Mar 02 11:11:19 2009 +0000
     7.2 +++ b/xen/drivers/video/vga.c	Mon Mar 02 11:23:23 2009 +0000
     7.3 @@ -79,7 +79,7 @@ void __init vga_init(void)
     7.4      switch ( vga_console_info.video_type )
     7.5      {
     7.6      case XEN_VGATYPE_TEXT_MODE_3:
     7.7 -        if ( page_is_conventional_ram(paddr_to_pfn(0xB8000)) ||
     7.8 +        if ( page_is_ram_type(paddr_to_pfn(0xB8000), RAM_TYPE_CONVENTIONAL) ||
     7.9               ((video = ioremap(0xB8000, 0x8000)) == NULL) )
    7.10              return;
    7.11          outw(0x200a, 0x3d4); /* disable cursor */
     8.1 --- a/xen/include/xen/mm.h	Mon Mar 02 11:11:19 2009 +0000
     8.2 +++ b/xen/include/xen/mm.h	Mon Mar 02 11:23:23 2009 +0000
     8.3 @@ -273,8 +273,12 @@ unsigned long avail_scrub_pages(void);
     8.4  
     8.5  int guest_remove_page(struct domain *d, unsigned long gmfn);
     8.6  
     8.7 -/* Returns TRUE if the whole page at @mfn is ordinary RAM. */
     8.8 -int page_is_conventional_ram(unsigned long mfn);
     8.9 +#define RAM_TYPE_CONVENTIONAL 0x00000001
    8.10 +#define RAM_TYPE_RESERVED     0x00000002
    8.11 +#define RAM_TYPE_UNUSABLE     0x00000004
    8.12 +#define RAM_TYPE_ACPI         0x00000008
    8.13 +/* Returns TRUE if the whole page at @mfn is of the requested RAM type(s) above. */
    8.14 +int page_is_ram_type(unsigned long mfn, unsigned long mem_type);
    8.15  
    8.16  extern unsigned long *alloc_bitmap;	/* for vmcoreinfo */
    8.17