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] hvmloader: Add new test for MSR_SHADOW_GS

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] hvmloader: Add new test for MSR_SHADOW_GS_BASE validity after SWAPGS instruction.
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Mon, 20 Jul 2009 04:45:29 -0700
Delivery-date: Mon, 20 Jul 2009 04:46:20 -0700
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 1247736650 -3600
# Node ID 8ce42378828bfa1576cbc601cadf61cb21439bf7
# Parent  fe4c6845a9d7453f5a72cd69cb26c17b4df1c9af
hvmloader: Add new test for MSR_SHADOW_GS_BASE validity after SWAPGS 
instruction.

Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx>
---
 tools/firmware/hvmloader/hvmloader.c |   20 +++++-
 tools/firmware/hvmloader/hypercall.h |    3 -
 tools/firmware/hvmloader/tests.c     |  104 +++++++++++++++++++++++++++++------
 tools/firmware/hvmloader/util.h      |   10 +++
 4 files changed, 114 insertions(+), 23 deletions(-)

diff -r fe4c6845a9d7 -r 8ce42378828b tools/firmware/hvmloader/hvmloader.c
--- a/tools/firmware/hvmloader/hvmloader.c      Thu Jul 16 10:26:55 2009 +0100
+++ b/tools/firmware/hvmloader/hvmloader.c      Thu Jul 16 10:30:50 2009 +0100
@@ -22,8 +22,8 @@
 
 #include "roms.h"
 #include "acpi/acpi2_0.h"
+#include "util.h"
 #include "hypercall.h"
-#include "util.h"
 #include "config.h"
 #include "apic_regs.h"
 #include "pci_regs.h"
@@ -40,7 +40,15 @@ asm (
     /* C runtime kickoff. */
     "    cld                         \n"
     "    cli                         \n"
-    "    movl $stack_top,%esp        \n"
+    "    lgdt gdt_desr               \n"
+    "    mov  $"STR(SEL_DATA32)",%ax \n"
+    "    mov  %ax,%ds                \n"
+    "    mov  %ax,%es                \n"
+    "    mov  %ax,%fs                \n"
+    "    mov  %ax,%gs                \n"
+    "    mov  %ax,%ss                \n"
+    "    ljmp $"STR(SEL_CODE32)",$1f \n"
+    "1:  movl $stack_top,%esp        \n"
     "    movl %esp,%ebp              \n"
     "    call main                   \n"
     /* Relocate real-mode trampoline to 0x0. */
@@ -50,8 +58,7 @@ asm (
     "    sub  %esi,%ecx              \n"
     "    rep  movsb                  \n"
     /* Load real-mode compatible segment state (base 0x0000, limit 0xffff). */
-    "    lgdt gdt_desr               \n"
-    "    mov  $0x0010,%ax            \n"
+    "    mov  $"STR(SEL_DATA16)",%ax \n"
     "    mov  %ax,%ds                \n"
     "    mov  %ax,%es                \n"
     "    mov  %ax,%fs                \n"
@@ -67,7 +74,7 @@ asm (
     "    xor  %esi,%esi              \n"
     "    xor  %edi,%edi              \n"
     /* Enter real mode, reload all segment registers and IDT. */
-    "    ljmp $0x8,$0x0              \n"
+    "    ljmp $"STR(SEL_CODE16)",$0x0\n"
     "trampoline_start: .code16       \n"
     "    mov  %eax,%cr0              \n"
     "    ljmp $0,$1f-trampoline_start\n"
@@ -90,6 +97,9 @@ asm (
     "    .quad 0x0000000000000000    \n"
     "    .quad 0x008f9a000000ffff    \n" /* Ring 0 16b code, base 0 limit 4G */
     "    .quad 0x008f92000000ffff    \n" /* Ring 0 16b data, base 0 limit 4G */
+    "    .quad 0x00cf9a000000ffff    \n" /* Ring 0 32b code, base 0 limit 4G */
+    "    .quad 0x00cf92000000ffff    \n" /* Ring 0 32b data, base 0 limit 4G */
+    "    .quad 0x00af9a000000ffff    \n" /* Ring 0 64b code */
     "gdt_end:                        \n"
     "                                \n"
     "    .bss                        \n"
diff -r fe4c6845a9d7 -r 8ce42378828b tools/firmware/hvmloader/hypercall.h
--- a/tools/firmware/hvmloader/hypercall.h      Thu Jul 16 10:26:55 2009 +0100
+++ b/tools/firmware/hvmloader/hypercall.h      Thu Jul 16 10:30:50 2009 +0100
@@ -34,9 +34,6 @@
 #include <stdint.h>
 #include <xen/xen.h>
 #include "config.h"
-
-#define __STR(...) #__VA_ARGS__
-#define STR(...) __STR(__VA_ARGS__)
 
 /*
  * NB. Hypercall address needs to be relative to a linkage symbol for
diff -r fe4c6845a9d7 -r 8ce42378828b tools/firmware/hvmloader/tests.c
--- a/tools/firmware/hvmloader/tests.c  Thu Jul 16 10:26:55 2009 +0100
+++ b/tools/firmware/hvmloader/tests.c  Thu Jul 16 10:30:50 2009 +0100
@@ -22,6 +22,10 @@
 
 #include "util.h"
 
+#define TEST_FAIL 0
+#define TEST_PASS 1
+#define TEST_SKIP 2
+
 /*
  * Memory layout during tests:
  *  4MB to 8MB is cleared.
@@ -73,7 +77,7 @@ static int rep_io_test(void)
 {
     uint32_t *p;
     uint32_t i, p0, p1, p2;
-    int okay = 1;
+    int okay = TEST_PASS;
 
     static const struct {
         unsigned long addr;
@@ -121,44 +125,114 @@ static int rep_io_test(void)
         {
             printf("Bad value at 0x%08lx: saw %08x expected %08x\n",
                    (unsigned long)p, *p, expected);
-            okay = 0;
+            okay = TEST_FAIL;
         }
     }
 
     return okay;
 }
 
+static int shadow_gs_test(void)
+{
+    uint64_t *pd = (uint64_t *)PD_START;
+    uint32_t i, eax, ebx, ecx, edx;
+
+    /* Skip this test if the CPU does not support long mode. */
+    cpuid(0x80000000, &eax, &ebx, &ecx, &edx);
+    if ( eax < 0x80000001 )
+        return TEST_SKIP;
+    cpuid(0x80000001, &eax, &ebx, &ecx, &edx);
+    if ( !(edx & (1u<<29)) )
+        return TEST_SKIP;
+
+    /* Long mode pagetable setup: Identity map 0-16MB with 2MB mappings. */
+    *pd = (unsigned long)pd + 0x1007; /* Level 4 */
+    pd += 512;
+    *pd = (unsigned long)pd + 0x1007; /* Level 3 */
+    pd += 512;
+    for ( i = 0; i < 8; i++ )         /* Level 2 */
+        *pd++ = (i << 21) + 0x1e3;
+
+    asm volatile (
+        /* CR4.PAE=1 */
+        "mov $0x20,%%ebx; "
+        "mov %%ebx,%%cr4; "
+        /* CR3 */
+        "mov %%eax,%%cr3; "
+        /* EFER.LME=1 */
+        "mov $0xc0000080,%%ecx; rdmsr; btsl $8,%%eax; wrmsr; "
+        /* CR0.PG=1 */
+        "mov %%cr0,%%eax; btsl $31,%%eax; mov %%eax,%%cr0; "
+        "jmp 1f; 1: "
+        /* GS_BASE=2; SHADOW_GS_BASE=3 */
+        "mov $0xc0000101,%%ecx; xor %%edx,%%edx; mov $2,%%eax; wrmsr; "
+        "mov $0xc0000102,%%ecx; xor %%edx,%%edx; mov $3,%%eax; wrmsr; "
+        /* Push LRETQ stack frame. */
+        "pushl $0; pushl $"STR(SEL_CODE32)"; pushl $0; pushl $2f; "
+        /* Jump to 64-bit mode. */
+        "ljmp $"STR(SEL_CODE64)",$1f; 1: "
+        /* Swap GS_BASE and SHADOW_GS_BASE */
+        ".byte 0x0f,0x01,0xf8; " /* SWAPGS */
+        /* Jump to 32-bit mode. */
+        ".byte 0x89, 0xe4; "     /* MOV ESP,ESP */
+        ".byte 0x48, 0xcb; 2: "  /* LRETQ */
+        /* Read SHADOW_GS_BASE: should now contain 2 */
+        "mov $0xc0000102,%%ecx; rdmsr; mov %%eax,%%ebx; "
+        /* CR0.PG=0 */
+        "mov %%cr0,%%eax; btcl $31,%%eax; mov %%eax,%%cr0; "
+        "jmp 1f; 1:"
+        /* EFER.LME=0 */
+        "mov $0xc0000080,%%ecx; rdmsr; btcl $8,%%eax; wrmsr; "
+        /* CR4.PAE=0 */
+        "xor %%eax,%%eax; mov %%eax,%%cr4; "
+        : "=b" (ebx) : "a" (PD_START) : "ecx", "edx", "memory" );
+
+    return (ebx == 2) ? TEST_PASS : TEST_FAIL;
+}
+
 void perform_tests(void)
 {
-    int i, passed;
+    int i, passed, skipped;
 
     static struct {
         int (* const test)(void);
         const char *description;
     } tests[] = {
         { rep_io_test, "REP INSB across page boundaries" },
+        { shadow_gs_test, "GS base MSRs and SWAPGS" },
         { NULL, NULL }
     };
 
     printf("Testing HVM environment:\n");
 
-    passed = 0;
+    passed = skipped = 0;
     for ( i = 0; tests[i].test; i++ )
     {
         printf(" - %s ... ", tests[i].description);
         memset((char *)(4ul << 20), 0, 4ul << 20);
         setup_paging();
-        if ( (*tests[i].test)() )
-        {
+        switch ( (*tests[i].test)() )
+        {
+        case TEST_PASS:
             printf("passed\n");
             passed++;
-        }
-        else
-        {
+            break;
+        case TEST_FAIL:
             printf("failed\n");
-        }
-    }
-
-    printf("Passed %d/%d tests\n", passed, i);
-    BUG_ON(passed != i);
-}
+            break;
+        case TEST_SKIP:
+            printf("skipped\n");
+            skipped++;
+            break;
+        }
+    }
+
+    printf("Passed %d of %d tests\n", passed, i);
+    if ( skipped != 0 )
+        printf("Skipped %d of %d tests\n", skipped, i);
+    if ( (passed + skipped) != i )
+    {
+        printf("FAILED %d of %d tests\n", i - passed - skipped, i);
+        BUG();
+    }
+}
diff -r fe4c6845a9d7 -r 8ce42378828b tools/firmware/hvmloader/util.h
--- a/tools/firmware/hvmloader/util.h   Thu Jul 16 10:26:55 2009 +0100
+++ b/tools/firmware/hvmloader/util.h   Thu Jul 16 10:30:50 2009 +0100
@@ -4,6 +4,16 @@
 #include <stdarg.h>
 #include <stdint.h>
 #include <xen/hvm/hvm_info_table.h>
+
+#define __STR(...) #__VA_ARGS__
+#define STR(...) __STR(__VA_ARGS__)
+
+/* GDT selector values. */
+#define SEL_CODE16          0x0008
+#define SEL_DATA16          0x0010
+#define SEL_CODE32          0x0018
+#define SEL_DATA32          0x0020
+#define SEL_CODE64          0x0028
 
 #undef offsetof
 #define offsetof(t, m) ((unsigned long)&((t *)0)->m)

_______________________________________________
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] hvmloader: Add new test for MSR_SHADOW_GS_BASE validity after SWAPGS instruction., Xen patchbot-unstable <=