]> xenbits.xen.org Git - xenclient/xen.git/commitdiff
Newer better workaround for incorrect RMRRs in BIOS - in
authorRoss Philipson <rossp@latara.uk.xensource.com>
Tue, 3 Mar 2009 14:53:39 +0000 (14:53 +0000)
committerRoss Philipson <rossp@latara.uk.xensource.com>
Tue, 3 Mar 2009 14:53:39 +0000 (14:53 +0000)
sync with upstream.

 Committer: Ross Philipson <rossp@latara.uk.xensource.com>
 Changes to be committed:

modified:   xen/arch/ia64/xen/mm.c
modified:   xen/arch/x86/mm.c
modified:   xen/drivers/passthrough/vtd/dmar.c
modified:   xen/drivers/passthrough/vtd/iommu.c
modified:   xen/include/xen/mm.h

xen/arch/ia64/xen/mm.c
xen/arch/x86/mm.c
xen/drivers/passthrough/vtd/dmar.c
xen/drivers/passthrough/vtd/iommu.c
xen/include/xen/mm.h

index 1a4c24d10753740dbc6488e841023e0807df6695..6d570b26649afd3360eb4d36a165f5fd79403c52 100644 (file)
@@ -3180,17 +3180,58 @@ int get_page_type(struct page_info *page, u32 type)
     return 1;
 }
 
-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);
+int page_is_ram_type(unsigned long mfn, unsigned long type)
+{
+    /* N.B. I believe the implementation below is correct for determing EFI memory types.
+       It needs testing but it is only used once in vga.c right now for conventional ram
+       (and xc not really interested in IA64). */
+    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;
 }
 
 long
index 4e8dd2d2390d0aa1db7c9d57c2e73b0fddd675c0..c5d8226653cc2e78dd0851bfbedb561736e0727b 100644 (file)
@@ -304,6 +304,15 @@ int page_is_ram_type(unsigned long mfn, unsigned long mem_type) /* CS 19085 mem
             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;
index 245b1a741e364149011f068a243077a5a6f4d787..94a5c80c369bc77f32241955ec7f6c30ab2241b5 100644 (file)
@@ -365,7 +365,7 @@ acpi_parse_one_rmrr(struct acpi_dmar_entry_header *header)
     {
         dprintk(XENLOG_WARNING VTDPREFIX,
                 "RMRR address range not in reserved memory base = %"PRIx64" end = %"PRIx64"; " \
-                "iommu_include_reserved parameter may be needed\n",
+                "iommu_inclusive_mapping=1 parameter may be needed\n",
                 rmrr->base_address, rmrr->end_address);
     }
 #endif
index b48d500952e40027405455daddd294d2324399e1..5bfedbbc0bcf018173c71e18a99826eacfcc4076 100644 (file)
 #include "extern.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);
+
 #define domain_iommu_domid(d) ((d)->arch.hvm_domain.hvm_iommu.iommu_domid)
 
 static spinlock_t domid_bitmap_lock;    /* protect domain id bitmap */
 static int domid_bitmap_size;           /* domain id bitmap size in bits */
 static unsigned long *domid_bitmap;     /* iommu domain id bitmap */
 
-/* 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);
-
 static void setup_dom0_devices(struct domain *d);
 static void setup_dom0_rmrr(struct domain *d);
 
@@ -1030,7 +1030,6 @@ static int intel_iommu_domain_init(struct domain *d)
     struct iommu *iommu = NULL;
     struct acpi_drhd_unit *drhd;
     u64 i;
-    u32 mem_type;
 
     drhd = list_entry(acpi_drhd_units.next, typeof(*drhd), list);
     iommu = drhd->iommu;
@@ -1041,21 +1040,28 @@ static int intel_iommu_domain_init(struct domain *d)
     {
         extern int xen_in_range(paddr_t start, paddr_t end);
 
-        /* input param overrides default memory mapping */
-        mem_type = RAM_TYPE_CONVENTIONAL;
-        if (iommu_include_reserved)
-            mem_type |= RAM_TYPE_RESERVED;
-
         /* 
          * Set up 1:1 page table for dom0 except the critical segments
          * like Xen and tboot.
          */
         for ( i = 0; i < max_page; 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, mem_type) ||
-                 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;
 
             iommu_map_page(d, i, i);
index 02eacf501acd1db1c83502aa9a0b4e627b2a20c3..9024540ad7fb4eb000aceb07b48c97c70649e891 100644 (file)
@@ -103,6 +103,8 @@ int guest_remove_page(struct domain *d, unsigned long gmfn);
 
 #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);