# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1233231039 0
# Node ID 202afa5384c4fdc49262ddef1f3b88c651b647b1
# Parent 378a85ff1260684af3cb7420e2a15b6034d0812c
tboot: tboot no longer marks TXT regions as E820_UNUSABLE, so Xen must
explicitly disallow them itself.
Signed-off-by: Shane Wang <shane.wang@xxxxxxxxx>
Signed-off-by: Joseph Cihula <joseph.cihula@xxxxxxxxx>
---
xen/arch/x86/e820.c | 105 +++++++++++++++++++++++++++-----------------
xen/arch/x86/setup.c | 3 +
xen/arch/x86/tboot.c | 65 +++++++++++++++++++++++++++
xen/include/asm-x86/e820.h | 3 +
xen/include/asm-x86/tboot.h | 1
5 files changed, 137 insertions(+), 40 deletions(-)
diff -r 378a85ff1260 -r 202afa5384c4 xen/arch/x86/e820.c
--- a/xen/arch/x86/e820.c Thu Jan 29 11:36:09 2009 +0000
+++ b/xen/arch/x86/e820.c Thu Jan 29 12:10:39 2009 +0000
@@ -391,8 +391,9 @@ static void __init machine_specific_memo
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)
+int __init e820_change_range_type(
+ 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;
@@ -406,55 +407,79 @@ int __init reserve_e820_ram(struct e820m
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--;
- }
- else if ( s == rs )
- {
- /* Truncate start. */
- e820->map[i].addr += e - s;
- e820->map[i].size -= e - s;
- }
- else if ( e == re )
- {
- /* Truncate end. */
- e820->map[i].size -= e - s;
- }
- else if ( e820->nr_map < ARRAY_SIZE(e820->map) )
- {
- /* Split in two. */
+ e820->map[i].type = new_type;
+ }
+ else if ( (s == rs) || (e == re) )
+ {
+ if ( (e820->nr_map + 1) > ARRAY_SIZE(e820->map) )
+ goto overflow;
+
memmove(&e820->map[i+1], &e820->map[i],
(e820->nr_map-i) * sizeof(e820->map[0]));
e820->nr_map++;
+
+ if ( s == rs )
+ {
+ e820->map[i].size = e - s;
+ e820->map[i].type = new_type;
+ e820->map[i+1].addr = e;
+ e820->map[i+1].size = re - e;
+ }
+ else
+ {
+ e820->map[i].size = s - rs;
+ e820->map[i+1].addr = s;
+ e820->map[i+1].size = e - s;
+ e820->map[i+1].type = new_type;
+ }
+ }
+ else if ( e820->nr_map+1 < ARRAY_SIZE(e820->map) )
+ {
+ if ( (e820->nr_map + 2) > ARRAY_SIZE(e820->map) )
+ goto overflow;
+
+ 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 = e;
- e820->map[i].size = re - e;
- }
- else
- {
- /* e820map is at maximum size. We have to leak some space. */
- if ( (s - rs) > (re - e) )
- {
- printk("e820 overflow: leaking RAM %"PRIx64"-%"PRIx64"\n", e, re);
- e820->map[i].size = s - rs;
- }
- else
- {
- printk("e820 overflow: leaking RAM %"PRIx64"-%"PRIx64"\n", rs, s);
- e820->map[i].addr = e;
- e820->map[i].size = re - e;
- }
+ e820->map[i+1].addr = s;
+ e820->map[i+1].size = e - s;
+ e820->map[i+1].type = new_type;
+ e820->map[i+2].addr = e;
+ e820->map[i+2].size = re - e;
+ }
+
+ /* Finally, look for any opportunities to merge adjacent e820 entries. */
+ for ( i = 0; i < (e820->nr_map - 1); i++ )
+ {
+ if ( (e820->map[i].type != e820->map[i+1].type) ||
+ ((e820->map[i].addr + e820->map[i].size) != e820->map[i+1].addr) )
+ continue;
+ e820->map[i].size += e820->map[i+1].size;
+ memmove(&e820->map[i+1], &e820->map[i+2],
+ (e820->nr_map-i-2) * sizeof(e820->map[0]));
+ e820->nr_map--;
+ i--;
}
return 1;
+
+ overflow:
+ printk("Overflow in e820 while reserving region %"PRIx64"-%"PRIx64"\n",
+ s, e);
+ return 0;
+}
+
+/* Set E820_RAM area (@s,@e) as RESERVED in specified e820 map. */
+int __init reserve_e820_ram(struct e820map *e820, uint64_t s, uint64_t e)
+{
+ return e820_change_range_type(e820, s, e, E820_RAM, E820_RESERVED);
}
unsigned long __init init_e820(
diff -r 378a85ff1260 -r 202afa5384c4 xen/arch/x86/setup.c
--- a/xen/arch/x86/setup.c Thu Jan 29 11:36:09 2009 +0000
+++ b/xen/arch/x86/setup.c Thu Jan 29 12:10:39 2009 +0000
@@ -1035,6 +1035,9 @@ void __init __start_xen(unsigned long mb
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 -r 378a85ff1260 -r 202afa5384c4 xen/arch/x86/tboot.c
--- a/xen/arch/x86/tboot.c Thu Jan 29 11:36:09 2009 +0000
+++ b/xen/arch/x86/tboot.c Thu Jan 29 12:10:39 2009 +0000
@@ -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> */
@@ -16,6 +17,23 @@ tboot_shared_t *g_tboot_shared;
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
extern char __init_begin[], __per_cpu_start[], __per_cpu_end[], __bss_start[];
@@ -105,6 +123,53 @@ int tboot_in_measured_env(void)
return (g_tboot_shared != NULL);
}
+int __init tboot_protect_mem_regions(void)
+{
+ uint64_t base, size;
+ uint32_t map_base, map_size;
+ unsigned long map_addr;
+ int rc;
+
+ 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);
+ rc = e820_change_range_type(
+ &e820, base, base + size, E820_RESERVED, E820_UNUSABLE);
+ if ( !rc )
+ 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);
+ rc = e820_change_range_type(
+ &e820, base, base + size, E820_RESERVED, E820_UNUSABLE);
+ if ( !rc )
+ return 0;
+
+ /* TXT Private Space */
+ rc = e820_change_range_type(
+ &e820, TXT_PRIV_CONFIG_REGS_BASE,
+ TXT_PRIV_CONFIG_REGS_BASE + NR_TXT_CONFIG_PAGES * PAGE_SIZE,
+ E820_RESERVED, E820_UNUSABLE);
+ if ( !rc )
+ 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
diff -r 378a85ff1260 -r 202afa5384c4 xen/include/asm-x86/e820.h
--- a/xen/include/asm-x86/e820.h Thu Jan 29 11:36:09 2009 +0000
+++ b/xen/include/asm-x86/e820.h Thu Jan 29 12:10:39 2009 +0000
@@ -24,6 +24,9 @@ struct e820map {
};
extern int reserve_e820_ram(struct e820map *e820, uint64_t s, uint64_t e);
+extern int e820_change_range_type(
+ struct e820map *e820, uint64_t s, uint64_t e,
+ uint32_t orig_type, uint32_t new_type);
extern unsigned long init_e820(const char *, struct e820entry *, int *);
extern struct e820map e820;
diff -r 378a85ff1260 -r 202afa5384c4 xen/include/asm-x86/tboot.h
--- a/xen/include/asm-x86/tboot.h Thu Jan 29 11:36:09 2009 +0000
+++ b/xen/include/asm-x86/tboot.h Thu Jan 29 12:10:39 2009 +0000
@@ -109,6 +109,7 @@ void tboot_probe(void);
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__ */
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|