[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] tboot: use TXT's DMA-protected DMAR table to setup VT-d
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1233233071 0 # Node ID 31798b19f25c1209f8a266127df3e77f71af09b6 # Parent 202afa5384c4fdc49262ddef1f3b88c651b647b1 tboot: use TXT's DMA-protected DMAR table to setup VT-d Signed-off-by: Joseph Cihula <joseph.cihula@xxxxxxxxx> --- xen/arch/x86/tboot.c | 132 +++++++++++++++++++++++++++++++------ xen/drivers/passthrough/vtd/dmar.c | 11 ++- xen/include/asm-x86/tboot.h | 3 3 files changed, 126 insertions(+), 20 deletions(-) diff -r 202afa5384c4 -r 31798b19f25c xen/arch/x86/tboot.c --- a/xen/arch/x86/tboot.c Thu Jan 29 12:10:39 2009 +0000 +++ b/xen/arch/x86/tboot.c Thu Jan 29 12:44:31 2009 +0000 @@ -18,6 +18,10 @@ tboot_shared_t *g_tboot_shared; static const uuid_t tboot_shared_uuid = TBOOT_SHARED_UUID; +/* used by tboot_protect_mem_regions() and/or tboot_parse_dmar_table() */ +static uint64_t txt_heap_base, txt_heap_size; +static uint64_t sinit_base, sinit_size; + /* * TXT configuration registers (offsets from TXT_{PUB, PRIV}_CONFIG_REGS_BASE) */ @@ -37,10 +41,33 @@ static const uuid_t tboot_shared_uuid = extern char __init_begin[], __per_cpu_start[], __per_cpu_end[], __bss_start[]; +#define SHA1_SIZE 20 +typedef uint8_t sha1_hash_t[SHA1_SIZE]; + +typedef struct __packed { + uint32_t version; /* currently 6 */ + sha1_hash_t bios_acm_id; + uint32_t edx_senter_flags; + uint64_t mseg_valid; + sha1_hash_t sinit_hash; + sha1_hash_t mle_hash; + sha1_hash_t stm_hash; + sha1_hash_t lcp_policy_hash; + uint32_t lcp_policy_control; + uint32_t rlp_wakeup_addr; + uint32_t reserved; + uint32_t num_mdrs; + uint32_t mdrs_off; + uint32_t num_vtd_dmars; + uint32_t vtd_dmars_off; +} sinit_mle_data_t; + void __init tboot_probe(void) { tboot_shared_t *tboot_shared; unsigned long p_tboot_shared; + uint32_t map_base, map_size; + unsigned long map_addr; /* Look for valid page-aligned address for shared page. */ p_tboot_shared = simple_strtoul(opt_tboot, NULL, 0); @@ -68,6 +95,30 @@ void __init tboot_probe(void) printk(" shutdown_entry: 0x%08x\n", tboot_shared->shutdown_entry); printk(" tboot_base: 0x%08x\n", tboot_shared->tboot_base); printk(" tboot_size: 0x%x\n", tboot_shared->tboot_size); + + /* these will be needed by tboot_protect_mem_regions() and/or + tboot_parse_dmar_table(), so get them now */ + + 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; + + /* TXT Heap */ + txt_heap_base = + *(uint64_t *)__va(TXT_PUB_CONFIG_REGS_BASE + TXTCR_HEAP_BASE); + txt_heap_size = + *(uint64_t *)__va(TXT_PUB_CONFIG_REGS_BASE + TXTCR_HEAP_SIZE); + + /* SINIT */ + sinit_base = + *(uint64_t *)__va(TXT_PUB_CONFIG_REGS_BASE + TXTCR_SINIT_BASE); + sinit_size = + *(uint64_t *)__va(TXT_PUB_CONFIG_REGS_BASE + TXTCR_SINIT_SIZE); + + 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) @@ -125,33 +176,26 @@ int tboot_in_measured_env(void) 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 ( txt_heap_base == 0 ) + return 0; + rc = e820_change_range_type( + &e820, txt_heap_base, txt_heap_base + txt_heap_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 ( sinit_base == 0 ) + return 0; + rc = e820_change_range_type( + &e820, sinit_base, sinit_base + sinit_size, + E820_RESERVED, E820_UNUSABLE); if ( !rc ) return 0; @@ -162,12 +206,62 @@ int __init tboot_protect_mem_regions(voi E820_RESERVED, E820_UNUSABLE); if ( !rc ) return 0; + + return 1; +} + +int __init tboot_parse_dmar_table(acpi_table_handler dmar_handler) +{ + uint32_t map_base, map_size; + unsigned long map_vaddr; + void *heap_ptr; + struct acpi_table_header *dmar_table; + int rc; + + if ( !tboot_in_measured_env() ) + return acpi_table_parse(ACPI_SIG_DMAR, dmar_handler); + + /* ACPI tables may not be DMA protected by tboot, so use DMAR copy */ + /* SINIT saved in SinitMleData in TXT heap (which is DMA protected) */ + + if ( txt_heap_base == 0 ) + return 1; + + /* map TXT heap into Xen addr space */ + map_base = PFN_DOWN(txt_heap_base); + map_size = PFN_UP(txt_heap_size); + map_vaddr = (unsigned long)__va(map_base << PAGE_SHIFT); + if ( map_pages_to_xen(map_vaddr, map_base, map_size, __PAGE_HYPERVISOR) ) + return 1; + + /* walk heap to SinitMleData */ + heap_ptr = __va(txt_heap_base); + /* skip BiosData */ + heap_ptr += *(uint64_t *)heap_ptr; + /* skip OsMleData */ + heap_ptr += *(uint64_t *)heap_ptr; + /* skip OsSinitData */ + heap_ptr += *(uint64_t *)heap_ptr; + /* now points to SinitMleDataSize; set to SinitMleData */ + heap_ptr += sizeof(uint64_t); + /* get addr of DMAR table */ + dmar_table = (struct acpi_table_header *)(heap_ptr + + ((sinit_mle_data_t *)heap_ptr)->vtd_dmars_off - sizeof(uint64_t)); + + rc = dmar_handler(dmar_table); destroy_xen_mappings( (unsigned long)__va(map_base << PAGE_SHIFT), (unsigned long)__va((map_base + map_size) << PAGE_SHIFT)); - - return 1; + + /* acpi_parse_dmar() zaps APCI DMAR signature in TXT heap table */ + /* but dom0 will read real table, so must zap it there too */ + dmar_table = NULL; + acpi_get_table(ACPI_SIG_DMAR, 0, &dmar_table); + if ( dmar_table != NULL ) + ((struct acpi_table_dmar *)dmar_table)->header.signature[0] = '\0'; + + return rc; } /* diff -r 202afa5384c4 -r 31798b19f25c xen/drivers/passthrough/vtd/dmar.c --- a/xen/drivers/passthrough/vtd/dmar.c Thu Jan 29 12:10:39 2009 +0000 +++ b/xen/drivers/passthrough/vtd/dmar.c Thu Jan 29 12:44:31 2009 +0000 @@ -506,6 +506,15 @@ static int __init acpi_parse_dmar(struct return ret; } +#ifdef CONFIG_X86 +#include <asm/tboot.h> +/* ACPI tables may not be DMA protected by tboot, so use DMAR copy */ +/* SINIT saved in SinitMleData in TXT heap (which is DMA protected) */ +#define parse_dmar_table(h) tboot_parse_dmar_table(h) +#else +#define parse_dmar_table(h) acpi_table_parse(ACPI_SIG_DMAR, h) +#endif + int acpi_dmar_init(void) { int rc; @@ -519,7 +528,7 @@ int acpi_dmar_init(void) if ( !iommu_enabled ) goto fail; - rc = acpi_table_parse(ACPI_SIG_DMAR, acpi_parse_dmar); + rc = parse_dmar_table(acpi_parse_dmar); if ( rc ) goto fail; diff -r 202afa5384c4 -r 31798b19f25c xen/include/asm-x86/tboot.h --- a/xen/include/asm-x86/tboot.h Thu Jan 29 12:10:39 2009 +0000 +++ b/xen/include/asm-x86/tboot.h Thu Jan 29 12:44:31 2009 +0000 @@ -36,6 +36,8 @@ #ifndef __TBOOT_H__ #define __TBOOT_H__ + +#include <xen/acpi.h> #ifndef __packed #define __packed __attribute__ ((packed)) @@ -110,6 +112,7 @@ void tboot_shutdown(uint32_t shutdown_ty void tboot_shutdown(uint32_t shutdown_type); int tboot_in_measured_env(void); int tboot_protect_mem_regions(void); +int tboot_parse_dmar_table(acpi_table_handler dmar_handler); #endif /* __TBOOT_H__ */ _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |