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

[Xen-devel] [PATCH] to fix S3 page fault issue for intel TXT

To: Keir Fraser <keir.fraser@xxxxxxxxxxxxx>, "xen-devel@xxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxx>
Subject: [Xen-devel] [PATCH] to fix S3 page fault issue for intel TXT
From: "Wang, Shane" <shane.wang@xxxxxxxxx>
Date: Tue, 2 Feb 2010 17:07:18 +0800
Accept-language: en-US
Acceptlanguage: en-US
Cc: "Wang, Shane" <shane.wang@xxxxxxxxx>, "Cihula, Joseph" <joseph.cihula@xxxxxxxxx>, "Hao, Xudong" <xudong.hao@xxxxxxxxx>
Delivery-date: Tue, 02 Feb 2010 01:08:27 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
Thread-index: Acqj5x6/T4UdBH4FSXiQTtJRDBxPCQ==
Thread-topic: [PATCH] to fix S3 page fault issue for intel TXT
This patch is to fix S3 issue for Intel Trusted Execution Technology.
Those unmapped pages cause page fault when MACing them and finally cause S3 
failure.

Thanks.
Shane

--
 xen/arch/x86/smpboot.c  |    2 -
 xen/arch/x86/tboot.c    |   60 +++++++++++++++++++++++++++++++++++---
 xen/common/page_alloc.c |    4 +-
 3 files changed, 59 insertions(+), 7 deletions(-)

diff -r caf013bb1a9f xen/arch/x86/smpboot.c
--- a/xen/arch/x86/smpboot.c    Wed Jan 27 07:44:40 2010 -0500
+++ b/xen/arch/x86/smpboot.c    Tue Feb 02 10:52:25 2010 -0500
@@ -103,7 +103,7 @@ static void map_cpu_to_logical_apicid(vo
 /* State of each CPU. */
 DEFINE_PER_CPU(int, cpu_state) = { 0 };
 
-static void *stack_base[NR_CPUS];
+void *stack_base[NR_CPUS];
 DEFINE_SPINLOCK(cpu_add_remove_lock);
 
 /*
diff -r caf013bb1a9f xen/arch/x86/tboot.c
--- a/xen/arch/x86/tboot.c      Wed Jan 27 07:44:40 2010 -0500
+++ b/xen/arch/x86/tboot.c      Tue Feb 02 10:52:25 2010 -0500
@@ -174,7 +174,7 @@ static void update_iommu_mac(vmac_ctx_t 
 }
 
 #define is_page_in_use(page) \
-    ((page->count_info & PGC_count_mask) != 0 || page->count_info == 0)
+    (page_state_is(page, inuse) || page_state_is(page, offlining))
 
 static void update_pagetable_mac(vmac_ctx_t *ctx)
 {
@@ -236,6 +236,30 @@ static void tboot_gen_domain_integrity(c
     memset(&ctx, 0, sizeof(ctx));
 }
 
+/*
+ * For stack overflow detection in debug build, a guard page is set up.
+ * This fn is used to detect whether a page is in the guarded pages for
+ * the above reason.
+ */
+static int mfn_in_guarded_stack(unsigned long mfn)
+{
+    extern void *stack_base[NR_CPUS];
+    void *p;
+    int i;
+
+    for ( i = 0; i < NR_CPUS; i++ )
+    {
+        if ( !stack_base[i] )
+            continue;
+        p = (void *)((unsigned long)stack_base[i] + STACK_SIZE -
+                     PRIMARY_STACK_SIZE - PAGE_SIZE);
+        if ( mfn == virt_to_mfn(p) )
+            return -1;
+    }
+
+    return 0;
+}
+
 static void tboot_gen_xenheap_integrity(const uint8_t key[TB_KEY_SIZE],
                                         vmac_t *mac)
 {
@@ -250,8 +274,21 @@ static void tboot_gen_xenheap_integrity(
 
         if ( !mfn_valid(mfn) )
             continue;
+        if ( (mfn << PAGE_SHIFT) < __pa(&_end) )
+            continue; /* skip Xen */
+        if ( (mfn >= PFN_DOWN(g_tboot_shared->tboot_base - 3 * PAGE_SIZE))
+             && (mfn < PFN_UP(g_tboot_shared->tboot_base
+                              + g_tboot_shared->tboot_size
+                              + 3 * PAGE_SIZE)) )
+            continue; /* skip tboot and its page tables */
+
         if ( is_page_in_use(page) && is_xen_heap_page(page) ) {
-            void *pg = mfn_to_virt(mfn);
+            void *pg;
+
+            if ( mfn_in_guarded_stack(mfn) )
+                continue; /* skip guard stack, see memguard_guard_stack() in 
mm.c */
+
+            pg = mfn_to_virt(mfn);
             vmac_update((uint8_t *)pg, PAGE_SIZE, &ctx);
         }
     }
@@ -266,12 +303,27 @@ static void tboot_gen_frametable_integri
 static void tboot_gen_frametable_integrity(const uint8_t key[TB_KEY_SIZE],
                                            vmac_t *mac)
 {
+    unsigned int sidx, eidx, nidx;
+    unsigned int max_idx = (max_pdx + PDX_GROUP_COUNT - 1)/PDX_GROUP_COUNT;
     uint8_t nonce[16] = {};
     vmac_ctx_t ctx;
 
     vmac_set_key((uint8_t *)key, &ctx);
-    *mac = vmac((uint8_t *)frame_table,
-                PFN_UP(max_pdx * sizeof(*frame_table)), nonce, NULL, &ctx);
+    for ( sidx = 0; ; sidx = nidx )
+    {
+        eidx = find_next_zero_bit(pdx_group_valid, max_idx, sidx);
+        nidx = find_next_bit(pdx_group_valid, max_idx, eidx);
+        if ( nidx >= max_idx )
+            break;
+        vmac_update((uint8_t *)pdx_to_page(sidx * PDX_GROUP_COUNT),
+                       pdx_to_page(eidx * PDX_GROUP_COUNT)
+                       - pdx_to_page(sidx * PDX_GROUP_COUNT), &ctx);
+    }
+    vmac_update((uint8_t *)pdx_to_page(sidx * PDX_GROUP_COUNT),
+                   pdx_to_page(max_pdx - 1) + 1
+                   - pdx_to_page(sidx * PDX_GROUP_COUNT), &ctx);
+
+    *mac = vmac(NULL, 0, nonce, NULL, &ctx);
 
     printk("MAC for frametable is: 0x%08"PRIx64"\n", *mac);
 
diff -r caf013bb1a9f xen/common/page_alloc.c
--- a/xen/common/page_alloc.c   Wed Jan 27 07:44:40 2010 -0500
+++ b/xen/common/page_alloc.c   Tue Feb 02 10:52:25 2010 -0500
@@ -932,8 +932,6 @@ void init_xenheap_pages(paddr_t ps, padd
     if ( pe <= ps )
         return;
 
-    memguard_guard_range(maddr_to_virt(ps), pe - ps);
-
     /*
      * Yuk! Ensure there is a one-page buffer between Xen and Dom zones, to
      * prevent merging of power-of-two blocks across the zone boundary.
@@ -942,6 +940,8 @@ void init_xenheap_pages(paddr_t ps, padd
         ps += PAGE_SIZE;
     if ( !is_xen_heap_mfn(paddr_to_pfn(pe)) )
         pe -= PAGE_SIZE;
+
+    memguard_guard_range(maddr_to_virt(ps), pe - ps);
 
     init_heap_pages(maddr_to_page(ps), (pe - ps) >> PAGE_SHIFT);
 }

Attachment: txt_s3_fix.patch
Description: txt_s3_fix.patch

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-devel] [PATCH] to fix S3 page fault issue for intel TXT, Wang, Shane <=