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-devel

[Xense-devel] [PATCH v2] txt: 5/5 - use TXT's DMA-protected DMAR table t

To: "'xen-devel@xxxxxxxxxxxxxxxxxxx'" <xen-devel@xxxxxxxxxxxxxxxxxxx>, "xense-devel@xxxxxxxxxxxxxxxxxxx" <xense-devel@xxxxxxxxxxxxxxxxxxx>
Subject: [Xense-devel] [PATCH v2] txt: 5/5 - use TXT's DMA-protected DMAR table to setup VT-d
From: "Cihula, Joseph" <joseph.cihula@xxxxxxxxx>
Date: Thu, 29 Jan 2009 00:56:05 -0800
Accept-language: en-US
Acceptlanguage: en-US
Cc: "Wang, Shane" <shane.wang@xxxxxxxxx>, Keir Fraser <keir.fraser@xxxxxxxxxxxxx>
Delivery-date: Thu, 29 Jan 2009 01:02:34 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xense-devel-request@lists.xensource.com?subject=help>
List-id: "A discussion list for those developing security enhancements for Xen." <xense-devel.lists.xensource.com>
List-post: <mailto:xense-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xense-devel>, <mailto:xense-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xense-devel>, <mailto:xense-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xense-devel-bounces@xxxxxxxxxxxxxxxxxxx
Thread-index: Acl6wtaRRy/Fr8NrQcCqcrf3x96JqQHK7bow
Thread-topic: [PATCH v2] txt: 5/5 - use TXT's DMA-protected DMAR table to setup VT-d
The VT-d DMAR ACPI tables may not be DMA protected by tboot.  However, SINIT 
saves a copy of them in the SinitMleData struct in the TXT heap (which is DMA 
protected).  So we should read the DMAR table from that copy if launched by 
tboot.

Signed-off-by: Joseph Cihula <joseph.cihula@xxxxxxxxx>

diff -r 28d9dd8e3a81 -r e9325545f67c xen/arch/x86/tboot.c
--- a/xen/arch/x86/tboot.c      Wed Jan 28 18:23:38 2009 -0800
+++ b/xen/arch/x86/tboot.c      Wed Jan 28 18:42:51 2009 -0800
@@ -20,6 +20,10 @@ static const uuid_t tboot_shared_uuid =

 extern char __init_begin[], __per_cpu_start[], __per_cpu_end[], __bss_start[];

+/* 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 @@ extern char __init_begin[], __per_cpu_st
 #define TXTCR_HEAP_BASE             0x0300
 #define TXTCR_HEAP_SIZE             0x0308

+#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,29 +176,18 @@ int tboot_in_measured_env(void)

 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) )
+    if ( txt_heap_base == 0 ||
+         !reserve_e820_unusable(&e820, txt_heap_base,
+                                txt_heap_base + txt_heap_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) )
+    if ( sinit_base == 0 ||
+         !reserve_e820_unusable(&e820, sinit_base, sinit_base + sinit_size) )
         return 0;

     /* TXT Private Space */
@@ -155,10 +195,60 @@ int tboot_protect_mem_regions(void)
             TXT_PRIV_CONFIG_REGS_BASE + NR_TXT_CONFIG_PAGES * PAGE_SIZE) )
         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 28d9dd8e3a81 -r e9325545f67c xen/drivers/passthrough/vtd/dmar.c
--- a/xen/drivers/passthrough/vtd/dmar.c        Wed Jan 28 18:23:38 2009 -0800
+++ b/xen/drivers/passthrough/vtd/dmar.c        Wed Jan 28 18:42:51 2009 -0800
@@ -28,6 +28,7 @@
 #include <xen/pci.h>
 #include <xen/pci_regs.h>
 #include <asm/string.h>
+#include <asm/tboot.h>
 #include "dmar.h"
 #include "iommu.h"

@@ -519,7 +520,9 @@ int acpi_dmar_init(void)
     if ( !iommu_enabled )
         goto fail;

-    rc = acpi_table_parse(ACPI_SIG_DMAR, acpi_parse_dmar);
+    /* ACPI tables may not be DMA protected by tboot, so use DMAR copy */
+    /* SINIT saved in SinitMleData in TXT heap (which is DMA protected) */
+    rc = tboot_parse_dmar_table(acpi_parse_dmar);
     if ( rc )
         goto fail;

diff -r 28d9dd8e3a81 -r e9325545f67c xen/include/asm-x86/tboot.h
--- a/xen/include/asm-x86/tboot.h       Wed Jan 28 18:23:38 2009 -0800
+++ b/xen/include/asm-x86/tboot.h       Wed Jan 28 18:42:51 2009 -0800
@@ -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__ */


Attachment: xen-txt-05b-use_protected_dmar.patch
Description: xen-txt-05b-use_protected_dmar.patch

_______________________________________________
Xense-devel mailing list
Xense-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xense-devel
<Prev in Thread] Current Thread [Next in Thread>
  • [Xense-devel] [PATCH v2] txt: 5/5 - use TXT's DMA-protected DMAR table to setup VT-d, Cihula, Joseph <=