]> xenbits.xen.org Git - xenclient/xen.git/commitdiff
tboot patch 3/5 - protect TXT ranges
authorRoss Philipson <ross.philipson@citrix.com>
Wed, 4 Feb 2009 16:11:34 +0000 (11:11 -0500)
committerRoss Philipson <ross.philipson@citrix.com>
Wed, 4 Feb 2009 16:11:34 +0000 (11:11 -0500)
tboot no longer marks the TXT heap/SINIT/private config space
as E820_UNUSABLE in the e820 table, so Xen must mark them so
(to disallow them from dom0).

 Changes to be committed:
modified:   xen/arch/x86/e820.c
modified:   xen/arch/x86/setup.c
modified:   xen/arch/x86/tboot.c
modified:   xen/include/asm-x86/e820.h
modified:   xen/include/asm-x86/tboot.h

xen/arch/x86/e820.c
xen/arch/x86/setup.c
xen/arch/x86/tboot.c
xen/include/asm-x86/e820.h
xen/include/asm-x86/tboot.h

index 8b79c5ea176e97f29e5020998f967120790de050..e884c4f388dce00f713b30fa1048daebd3f2ebe6 100644 (file)
@@ -391,11 +391,14 @@ static void __init machine_specific_memory_setup(
     reserve_dmi_region();
 }
 
-/* Reserve RAM area (@s,@e) in the specified e820 map. */
-int __init reserve_e820_ram(struct e820map *e820, uint64_t s, uint64_t e)
+static int reserve_e820(struct e820map *e820, uint64_t s, uint64_t e,
+                       uint32_t orig_type, uint32_t new_type)
 {
     uint64_t rs = 0, re = 0;
-    int i;
+    int i, remove;
+
+    /* if reserving region, can delete instead */
+    remove = (new_type == E820_RESERVED);
 
     for ( i = 0; i < e820->nr_map; i++ )
     {
@@ -406,37 +409,89 @@ int __init reserve_e820_ram(struct e820map *e820, uint64_t s, uint64_t e)
             break;
     }
 
-    if ( (i == e820->nr_map) || (e820->map[i].type != E820_RAM) )
+    if ( (i == e820->nr_map) || (e820->map[i].type != orig_type) )
         return 0;
 
     if ( (s == rs) && (e == re) )
     {
         /* Complete excision. */
-        memmove(&e820->map[i], &e820->map[i+1],
-                (e820->nr_map-i-1) * sizeof(e820->map[0]));
-        e820->nr_map--;
+        if ( remove )
+        {
+            memmove(&e820->map[i], &e820->map[i+1],
+                    (e820->nr_map-i-1) * sizeof(e820->map[0]));
+            e820->nr_map--;
+        }
+        else
+            e820->map[i].type = new_type;
     }
     else if ( s == rs )
     {
-        /* Truncate start. */
+        /* Truncate start or split. */
+        if ( !remove )
+        {
+           /* split */
+            if ( e820->nr_map+1 > ARRAY_SIZE(e820->map) )
+            {
+                printk("e820 overflow\n");
+                return 0;
+            }
+            memmove(&e820->map[i+1], &e820->map[i],
+                    (e820->nr_map-i) * sizeof(e820->map[0]));
+            e820->nr_map++;
+            e820->map[i].addr = s;
+            e820->map[i].size = e - s;
+            e820->map[i].type = new_type;
+            i++;
+        }
         e820->map[i].addr += e - s;
         e820->map[i].size -= e - s;
     }
     else if ( e == re )
     {
-        /* Truncate end. */
+        /* Truncate end or split. */
+        if ( !remove )
+        {
+            if ( e820->nr_map+1 > ARRAY_SIZE(e820->map) )
+            {
+                printk("e820 overflow\n");
+                return 0;
+            }
+            memmove(&e820->map[i+1], &e820->map[i],
+                    (e820->nr_map-i) * sizeof(e820->map[0]));
+            e820->nr_map++;
+            e820->map[i+1].addr = s;
+            e820->map[i+1].size = e - s;
+            e820->map[i+1].type = new_type;
+        }
         e820->map[i].size -= e - s;
     }
-    else if ( e820->nr_map < ARRAY_SIZE(e820->map) )
+    else if ( e820->nr_map+1 < ARRAY_SIZE(e820->map) )
     {
-        /* Split in two. */
-        memmove(&e820->map[i+1], &e820->map[i],
-                (e820->nr_map-i) * sizeof(e820->map[0]));
-        e820->nr_map++;
-        e820->map[i].size = s - rs;
-        i++;
-        e820->map[i].addr = e;
-        e820->map[i].size = re - e;
+        /* Split in two or three. */
+        if ( !remove )
+        {
+            memmove(&e820->map[i+2], &e820->map[i],
+                    (e820->nr_map-i) * sizeof(e820->map[0]));
+            e820->nr_map += 2;
+            e820->map[i].size = s - rs;
+            i++;
+            e820->map[i].addr = s;
+            e820->map[i].size = e - s;
+            e820->map[i].type = new_type;
+            i++;
+            e820->map[i].addr = e;
+            e820->map[i].size = re - e;
+        }
+        else
+        {
+            memmove(&e820->map[i+1], &e820->map[i],
+                    (e820->nr_map-i) * sizeof(e820->map[0]));
+            e820->nr_map++;
+            e820->map[i].size = s - rs;
+            i++;
+            e820->map[i].addr = e;
+            e820->map[i].size = re - e;
+        }
     }
     else
     {
@@ -457,6 +512,18 @@ int __init reserve_e820_ram(struct e820map *e820, uint64_t s, uint64_t e)
     return 1;
 }
 
+/* Set E820_RAM area (@s,@e) as RESERVED (or delete) in specified e820 map. */
+int __init reserve_e820_ram(struct e820map *e820, uint64_t s, uint64_t e)
+{
+    return reserve_e820(e820, s, e, E820_RAM, E820_RESERVED);
+}
+
+/* Set E820_RESERVED area (@s, @e) as UNUSABLE in specified e820 map. */
+int reserve_e820_unusable(struct e820map *e820, uint64_t s, uint64_t e)
+{
+    return reserve_e820(e820, s, e, E820_RESERVED, E820_UNUSABLE);
+}
+
 unsigned long __init init_e820(
     const char *str, struct e820entry *raw, int *raw_nr)
 {
index 6c039b0f3353ddc48cca47cb7130ae0ea8e32eae..b8694e816dfeabb3cca37b8189be9ab2431ca5f8 100644 (file)
@@ -1047,6 +1047,9 @@ 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.
index 9e1419646d94ffed6c69d7b2741d2c264e84adc0..603f3301fb3fe101e0407a0ec4dc50b3bb1bf76f 100644 (file)
@@ -6,6 +6,7 @@
 #include <asm/fixmap.h>
 #include <asm/page.h>
 #include <asm/processor.h>
+#include <asm/e820.h>
 #include <asm/tboot.h>
 
 /* tboot=<physical address of shared page> */
@@ -17,6 +18,23 @@ tboot_shared_t *g_tboot_shared;
 
 static const uuid_t tboot_shared_uuid = TBOOT_SHARED_UUID;
 
+/*
+ * TXT configuration registers (offsets from TXT_{PUB, PRIV}_CONFIG_REGS_BASE)
+ */
+
+#define TXT_PUB_CONFIG_REGS_BASE       0xfed30000
+#define TXT_PRIV_CONFIG_REGS_BASE      0xfed20000
+
+/* # pages for each config regs space - used by fixmap */
+#define NR_TXT_CONFIG_PAGES     ((TXT_PUB_CONFIG_REGS_BASE -                \
+                                  TXT_PRIV_CONFIG_REGS_BASE) >> PAGE_SHIFT)
+
+/* offsets from pub/priv config space */
+#define TXTCR_SINIT_BASE            0x0270
+#define TXTCR_SINIT_SIZE            0x0278
+#define TXTCR_HEAP_BASE             0x0300
+#define TXTCR_HEAP_SIZE             0x0308
+
 void __init tboot_probe(void)
 {
     tboot_shared_t *tboot_shared;
@@ -84,6 +102,44 @@ int tboot_in_measured_env(void)
     return (g_tboot_shared != NULL);
 }
 
+int tboot_protect_mem_regions(void)
+{
+    uint64_t base, size;
+    uint32_t map_base, map_size;
+    unsigned long map_addr;
+
+    if ( !tboot_in_measured_env() )
+        return 1;
+
+    map_base = PFN_DOWN(TXT_PUB_CONFIG_REGS_BASE);
+    map_size = PFN_UP(NR_TXT_CONFIG_PAGES * PAGE_SIZE);
+    map_addr = (unsigned long)__va(map_base << PAGE_SHIFT);
+    if ( map_pages_to_xen(map_addr, map_base, map_size, __PAGE_HYPERVISOR) )
+        return 0;
+
+    /* TXT Heap */
+    base = *(uint64_t *)__va(TXT_PUB_CONFIG_REGS_BASE + TXTCR_HEAP_BASE);
+    size = *(uint64_t *)__va(TXT_PUB_CONFIG_REGS_BASE + TXTCR_HEAP_SIZE);
+    if ( !reserve_e820_unusable(&e820, base, base + size) )
+        return 0;
+
+    /* SINIT */
+    base = *(uint64_t *)__va(TXT_PUB_CONFIG_REGS_BASE + TXTCR_SINIT_BASE);
+    size = *(uint64_t *)__va(TXT_PUB_CONFIG_REGS_BASE + TXTCR_SINIT_SIZE);
+    if ( !reserve_e820_unusable(&e820, base, base + size) )
+        return 0;
+
+    /* TXT Private Space */
+    if ( !reserve_e820_unusable(&e820, TXT_PRIV_CONFIG_REGS_BASE,
+            TXT_PRIV_CONFIG_REGS_BASE + NR_TXT_CONFIG_PAGES * PAGE_SIZE) )
+        return 0;
+
+    destroy_xen_mappings((unsigned long)__va(map_base << PAGE_SHIFT),
+                         (unsigned long)__va((map_base + map_size) << PAGE_SHIFT));
+
+    return 1;
+}
+
 /*
  * Local variables:
  * mode: C
index 8602ca85ac9fd2b5a80e5fc58db0b27c2f0f4a84..1fba42fc7e0a7cf3db39fb4a06052a362a0b1262 100644 (file)
@@ -24,6 +24,7 @@ struct e820map {
 };
 
 extern int reserve_e820_ram(struct e820map *e820, uint64_t s, uint64_t e);
+extern int reserve_e820_unusable(struct e820map *e820, uint64_t s, uint64_t e);
 extern unsigned long init_e820(const char *, struct e820entry *, int *);
 extern struct e820map e820;
 
index 07ee9a734ad15dc1d841496aa1d3bb215feb0040..65a9cfedc6ea6948bd09b27c48c16c6f4cb9e286 100644 (file)
@@ -100,6 +100,7 @@ extern tboot_shared_t *g_tboot_shared;
 void tboot_probe(void);
 void tboot_shutdown(uint32_t shutdown_type);
 int tboot_in_measured_env(void);
+int tboot_protect_mem_regions(void);
 
 #endif /* __TBOOT_H__ */