Cihula, Joseph
2009-Jan-20 05:49 UTC
[Xense-devel] [PATCH] txt: 2/6 - explicitly protect TXT addr ranges from dom0
tboot no longer marks the TXT heap/SINIT/private config space as E820_UNUSABLE in the e820 table, so Xen must explicitly disallow those regions from dom0. Signed-off-by: Shane Wang <shane.wang@intel.com> Signed-off-by: Joseph Cihula <joseph.cihula@intel.com> diff -r 3d294dba4255 -r bde0fd053306 xen/arch/x86/domain_build.c --- a/xen/arch/x86/domain_build.c Fri Jan 16 13:25:37 2009 -0800 +++ b/xen/arch/x86/domain_build.c Fri Jan 16 13:34:36 2009 -0800 @@ -29,6 +29,7 @@ #include <asm/paging.h> #include <asm/p2m.h> #include <asm/e820.h> +#include <asm/tboot.h> #include <public/version.h> @@ -1038,6 +1039,20 @@ int __init construct_dom0( rc |= iomem_deny_access(dom0, sfn, efn); } + /* Remove access to TXT Heap/SINIT/Private Space. */ + if ( tboot_in_measured_env() ) + { + unsigned long sfn, efn; + + for ( i = 0; i < ARRAY_SIZE(txt_protmem_range_starts); i++ ) + { + sfn = paddr_to_pfn(txt_protmem_range_starts[i]); + efn = paddr_to_pfn(txt_protmem_range_ends[i]); + if ( sfn <= efn ) + rc |= iomem_deny_access(dom0, sfn, efn); + } + } + BUG_ON(rc != 0); return 0; diff -r 3d294dba4255 -r bde0fd053306 xen/arch/x86/mm.c --- a/xen/arch/x86/mm.c Fri Jan 16 13:25:37 2009 -0800 +++ b/xen/arch/x86/mm.c Fri Jan 16 13:34:36 2009 -0800 @@ -109,6 +109,7 @@ #include <asm/e820.h> #include <asm/hypercall.h> #include <asm/shared.h> +#include <asm/tboot.h> #include <public/memory.h> #include <xsm/xsm.h> #include <xen/trace.h> @@ -216,7 +217,7 @@ void __init arch_init_memory(void) { extern void subarch_init_memory(void); - unsigned long i, pfn, rstart_pfn, rend_pfn, iostart_pfn, ioend_pfn; + unsigned long i, pfn, rstart_pfn, rend_pfn, iostart_pfn, ioend_pfn, j; /* * Initialise our DOMID_XEN domain. @@ -279,6 +280,19 @@ void __init arch_init_memory(void) for ( ; pfn < rstart_pfn; pfn++ ) { BUG_ON(!mfn_valid(pfn)); + /* Ensure the TXT ranges are not marked as I/O since that memory */ + /* can''t be used in dom0. */ + if ( tboot_in_measured_env() ) + { + for ( j = 0; j < ARRAY_SIZE(txt_protmem_range_starts); j++ ) + { + if ( (PFN_DOWN(txt_protmem_range_starts[j]) <= pfn) + && (pfn <= PFN_DOWN(txt_protmem_range_ends[j])) ) + break; + } + if ( j != ARRAY_SIZE(txt_protmem_range_starts) ) + continue; + } share_xen_page_with_guest( mfn_to_page(pfn), dom_io, XENSHARE_writable); } diff -r 3d294dba4255 -r bde0fd053306 xen/arch/x86/tboot.c --- a/xen/arch/x86/tboot.c Fri Jan 16 13:25:37 2009 -0800 +++ b/xen/arch/x86/tboot.c Fri Jan 16 13:34:36 2009 -0800 @@ -15,12 +15,18 @@ string_param("tboot", opt_tboot); /* Global pointer to shared data; NULL means no measured launch. */ tboot_shared_t *g_tboot_shared; +/* TXT memory ranges which need to be protected from dom0 */ +uint64_t txt_protmem_range_starts[TXT_PROTMEM_RANGE_MAX]; +uint64_t txt_protmem_range_ends[TXT_PROTMEM_RANGE_MAX]; + static const uuid_t tboot_shared_uuid = TBOOT_SHARED_UUID; void __init tboot_probe(void) { tboot_shared_t *tboot_shared; - unsigned long p_tboot_shared; + unsigned long p_tboot_shared, map_addr; + uint64_t base, size; + uint32_t map_base, map_size; /* Look for valid page-aligned address for shared page. */ p_tboot_shared = simple_strtoul(opt_tboot, NULL, 0); @@ -48,6 +54,34 @@ void __init tboot_probe(void) printk(" tboot_base: 0x%08x\n", tboot_shared->tboot_base); printk(" tboot_size: 0x%x\n", tboot_shared->tboot_size); } + + /* Get TXT heaps/SINIT/Private Space addresses. */ + 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) ) + panic("Could not get TXT heaps/SINIT/Private Space addresses\n"); + + /* 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); + txt_protmem_range_starts[0] = base; + txt_protmem_range_ends[0] = base + size - 1; + + /* 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); + txt_protmem_range_starts[1] = base; + txt_protmem_range_ends[1] = base + size - 1; + + /* TXT Private Space */ + txt_protmem_range_starts[2] = TXT_PRIV_CONFIG_REGS_BASE; + txt_protmem_range_ends[2] = TXT_PRIV_CONFIG_REGS_BASE + + NR_TXT_CONFIG_PAGES * PAGE_SIZE - 1; + + destroy_xen_mappings((unsigned long)__va(map_base << PAGE_SHIFT), + (unsigned long)__va((map_base + map_size) << PAGE_SHIFT)); } void tboot_shutdown(uint32_t shutdown_type) diff -r 3d294dba4255 -r bde0fd053306 xen/include/asm-x86/tboot.h --- a/xen/include/asm-x86/tboot.h Fri Jan 16 13:25:37 2009 -0800 +++ b/xen/include/asm-x86/tboot.h Fri Jan 16 13:34:36 2009 -0800 @@ -2,7 +2,7 @@ * tboot.h: shared data structure with MLE and kernel and functions * used by kernel for runtime support * - * Copyright (c) 2006-2007, Intel Corporation + * Copyright (c) 2006-2009, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -90,6 +90,26 @@ void tboot_shutdown(uint32_t shutdown_ty void tboot_shutdown(uint32_t shutdown_type); int tboot_in_measured_env(void); +/* + * 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) +#define TXTCR_SINIT_BASE 0x0270 +#define TXTCR_SINIT_SIZE 0x0278 +#define TXTCR_HEAP_BASE 0x0300 +#define TXTCR_HEAP_SIZE 0x0308 + +#define TXT_PROTMEM_RANGE_MAX 3 +extern uint64_t txt_protmem_range_starts[TXT_PROTMEM_RANGE_MAX]; +extern uint64_t txt_protmem_range_ends[TXT_PROTMEM_RANGE_MAX]; + #endif /* __TBOOT_H__ */ /* _______________________________________________ Xense-devel mailing list Xense-devel@lists.xensource.com http://lists.xensource.com/xense-devel
Keir Fraser
2009-Jan-20 08:57 UTC
[Xen-devel] Re: [PATCH] txt: 2/6 - explicitly protect TXT addr ranges from dom0
Xen tracks protected memory regions in its private e820 structure. If tboot is no longer marking E820_UNUSABLE in e820, then have Xen manually add the regions to its private e820. Then you won¹t need your new ad hoc structure plus needing to process that new structure in various places. -- Keir On 20/01/2009 05:49, "Cihula, Joseph" <joseph.cihula@intel.com> wrote:> tboot no longer marks the TXT heap/SINIT/private config space as E820_UNUSABLE > in the e820 table, so Xen must explicitly disallow those regions from dom0. > > Signed-off-by: Shane Wang <shane.wang@intel.com> > Signed-off-by: Joseph Cihula <joseph.cihula@intel.com>_______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Cihula, Joseph
2009-Jan-21 07:41 UTC
[Xen-devel] RE: [PATCH] txt: 2/6 - explicitly protect TXT addr ranges from dom0
We had an earlier version of our patch that just altered the e820 table, but we were concerned about the code complexity needed to do that (the existing Xen e820 fns aren''t sufficient for this). Here is the change that we would need to add-do you prefer this: diff -r dbac9ee4d761 xen/arch/x86/e820.c --- a/xen/arch/x86/e820.c Mon Sep 08 16:02:13 2008 +0100 +++ b/xen/arch/x86/e820.c Sat Nov 22 02:04:51 2008 +0800 @@ -373,11 +373,13 @@ 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) +static int reserve_e820(uint32_t type, struct e820map *e820, + uint64_t s, uint64_t e, uint32_t t) { uint64_t rs = 0, re = 0; - int i; + int i, remove; + + remove = (type == t); for ( i = 0; i < e820->nr_map; i++ ) { @@ -388,55 +390,131 @@ 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 != 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 = t; } else if ( s == rs ) { - /* Truncate start. */ + /* If not remove, split it in two, or else, truncate start. */ + 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].addr = s; + e820->map[i].size = e - s; + e820->map[i].type = t; + i++; + } 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. */ - 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; + /* If not remove, split it in two, or else, truncate end. */ + 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].size -= e - s; + i++; + e820->map[i].addr = s; + e820->map[i].size = e - s; + e820->map[i].type = t; + } + else + e820->map[i].size -= e - s; } else { - /* e820map is at maximum size. We have to leak some space. */ - if ( (s - rs) > (re - e) ) + /* If not remove, split in three, or else, split in two. */ + if (!remove) { - printk("e820 overflow: leaking RAM %"PRIx64"-%"PRIx64"\n", e, re); + if ( e820->nr_map+2 > ARRAY_SIZE(e820->map) ) + { + printk("e820 overflow\n"); + return 0; + } + 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 = t; + i++; + e820->map[i].addr = e; + e820->map[i].size = re - e; } else { - printk("e820 overflow: leaking RAM %"PRIx64"-%"PRIx64"\n", rs, s); - e820->map[i].addr = e; - e820->map[i].size = re - e; + if ( e820->nr_map < ARRAY_SIZE(e820->map) ) + { + 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 + { + /* 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; + } + } } } return 1; +} + +/* Reserve RAM area (@s,@e) in the specified e820 map. */ +int __init reserve_e820_ram(struct e820map *e820, uint64_t s, uint64_t e) +{ + return reserve_e820(E820_RAM, e820, s, e, E820_RAM); +} + +/* Reserve RESERVE area (@s, @e) as UNUSABLE in the specified e820 map. */ +int reserve_e820_reserved(struct e820map *e820, uint64_t s, uint64_t e) +{ + return reserve_e820(E820_RESERVED, e820, s, e, E820_UNUSABLE); } unsigned long __init init_e820( From: Keir Fraser [mailto:keir.fraser@eu.citrix.com] Sent: Tuesday, January 20, 2009 12:57 AM To: Cihula, Joseph; xen-devel@lists.xensource.com; xense-devel@lists.xensource.com Cc: Wang, Shane Subject: Re: [PATCH] txt: 2/6 - explicitly protect TXT addr ranges from dom0 Xen tracks protected memory regions in its private e820 structure. If tboot is no longer marking E820_UNUSABLE in e820, then have Xen manually add the regions to its private e820. Then you won''t need your new ad hoc structure plus needing to process that new structure in various places. -- Keir On 20/01/2009 05:49, "Cihula, Joseph" <joseph.cihula@intel.com> wrote: tboot no longer marks the TXT heap/SINIT/private config space as E820_UNUSABLE in the e820 table, so Xen must explicitly disallow those regions from dom0. Signed-off-by: Shane Wang <shane.wang@intel.com> Signed-off-by: Joseph Cihula <joseph.cihula@intel.com> _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Keir Fraser
2009-Jan-21 08:09 UTC
[Xen-devel] Re: [PATCH] txt: 2/6 - explicitly protect TXT addr ranges from dom0
On 21/01/2009 07:41, "Cihula, Joseph" <joseph.cihula@intel.com> wrote:> We had an earlier version of our patch that just altered the e820 table, but > we were concerned about the code complexity needed to do that (the existing > Xen e820 fns aren¹t sufficient for this). Here is the change that we would > need to adddo you prefer this:Well, I''m not sure about the implementation in e820.c, but still I prefer this approach overall. Go with this approach and I''ll clean up the e820.c parts myself if I can think of a simpler way to implement this mechanism. -- Keir _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel