WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] tboot: use TXT's DMA-protected DMAR table

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] tboot: use TXT's DMA-protected DMAR table to setup VT-d
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Thu, 29 Jan 2009 18:55:14 -0800
Delivery-date: Thu, 29 Jan 2009 18:56:06 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# 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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] tboot: use TXT's DMA-protected DMAR table to setup VT-d, Xen patchbot-unstable <=