X86: Keep track of more descriptor state to accomodate KVM.
authorGabe Black <gblack@eecs.umich.edu>
Fri, 29 May 2009 06:27:56 +0000 (23:27 -0700)
committerGabe Black <gblack@eecs.umich.edu>
Fri, 29 May 2009 06:27:56 +0000 (23:27 -0700)
src/arch/x86/faults.cc
src/arch/x86/isa/insts/general_purpose/system_calls.py
src/arch/x86/isa/insts/romutil.py
src/arch/x86/isa/microops/regop.isa
src/arch/x86/miscregs.hh
src/arch/x86/process.cc
src/arch/x86/system.cc

index 10b539248fb96de22f88444504fe9a9a3e309445..34137444f777c4b4414536b8a2e4f1975ce0b1e4 100644 (file)
@@ -208,11 +208,18 @@ namespace X86ISA
         tc->setMiscReg(MISCREG_EFER, 0);
 
         SegAttr dataAttr = 0;
+        dataAttr.dpl = 0;
+        dataAttr.unusable = 0;
+        dataAttr.defaultSize = 0;
+        dataAttr.longMode = 0;
+        dataAttr.avl = 0;
+        dataAttr.granularity = 0;
+        dataAttr.present = 1;
+        dataAttr.type = 3;
         dataAttr.writable = 1;
         dataAttr.readable = 1;
         dataAttr.expandDown = 0;
-        dataAttr.dpl = 0;
-        dataAttr.defaultSize = 0;
+        dataAttr.system = 1;
 
         for (int seg = 0; seg != NUM_SEGMENTREGS; seg++) {
             tc->setMiscReg(MISCREG_SEG_SEL(seg), 0);
@@ -223,11 +230,18 @@ namespace X86ISA
         }
 
         SegAttr codeAttr = 0;
+        codeAttr.dpl = 0;
+        codeAttr.unusable = 0;
+        codeAttr.defaultSize = 0;
+        codeAttr.longMode = 0;
+        codeAttr.avl = 0;
+        codeAttr.granularity = 0;
+        codeAttr.present = 1;
+        codeAttr.type = 10;
         codeAttr.writable = 0;
         codeAttr.readable = 1;
         codeAttr.expandDown = 0;
-        codeAttr.dpl = 0;
-        codeAttr.defaultSize = 0;
+        codeAttr.system = 1;
 
         tc->setMiscReg(MISCREG_CS, 0xf000);
         tc->setMiscReg(MISCREG_CS_BASE,
index fb282502dee240f400b584f4e0683abc9c846343..9501116d906490bd46c9b80ec4bca44c7a7e9928 100644 (file)
@@ -77,8 +77,10 @@ def macroop SYSCALL_64
     wrlimit cs, t1, dataSize=4
     # Not writable, read/execute-able, not expandDown,
     # dpl=0, defaultSize=0, long mode
-    limm t4, ((0 << 0) | (1 << 1) | (0 << 2) | \
-              (0 << 3) | (0 << 5) | (1 << 6)), dataSize=8
+    limm t4, ((0 << 0)  | (0  << 2)  | (0 << 3)   | \
+              (1 << 4)  | (0  << 5)  | (1 << 6)   | \
+              (1 << 7)  | (10 << 8)  | (0 << 12)  | \
+              (1 << 13) | (0  << 14) | (1 << 15)), dataSize=8
     wrattr cs, t4
 
     # Set up SS.
@@ -88,8 +90,10 @@ def macroop SYSCALL_64
     wrlimit ss, t1, dataSize=4
     # Writable, readable, not expandDown,
     # dpl=0, defaultSize=0, not long mode
-    limm t4, ((1 << 0) | (1 << 1) | (0 << 2) | \
-              (0 << 3) | (0 << 5) | (0 << 6)), dataSize=8
+    limm t4, ((0 << 0)  | (0  << 2)  | (1 << 3)   | \
+              (0 << 4)  | (0  << 5)  | (1 << 6)   | \
+              (1 << 7)  | (2  << 8)  | (1 << 12)  | \
+              (1 << 13) | (0  << 14) | (1 << 15)), dataSize=8
     wrattr ss, t4
 
     # Set the new rip.
@@ -126,8 +130,10 @@ def macroop SYSCALL_COMPAT
     wrlimit cs, t1, dataSize=4
     # Not writable, read/execute-able, not expandDown,
     # dpl=0, defaultSize=0, long mode
-    limm t4, ((0 << 0) | (1 << 1) | (0 << 2) | \
-              (0 << 3) | (0 << 5) | (1 << 6)), dataSize=8
+    limm t4, ((0 << 0)  | (0  << 2)  | (0 << 3)   | \
+              (1 << 4)  | (0  << 5)  | (1 << 6)   | \
+              (1 << 7)  | (10 << 8)  | (0 << 12)  | \
+              (1 << 13) | (0  << 14) | (1 << 15)), dataSize=8
     wrattr cs, t4
 
     # Set up SS.
@@ -137,8 +143,10 @@ def macroop SYSCALL_COMPAT
     wrlimit ss, t1, dataSize=4
     # Writable, readable, not expandDown,
     # dpl=0, defaultSize=0, not long mode
-    limm t4, ((1 << 0) | (1 << 1) | (0 << 2) | \
-              (0 << 3) | (0 << 5) | (0 << 6)), dataSize=8
+    limm t4, ((0 << 0)  | (0  << 2)  | (1 << 3)   | \
+              (0 << 4)  | (0  << 5)  | (1 << 6)   | \
+              (1 << 7)  | (2  << 8)  | (1 << 12)  | \
+              (1 << 13) | (0  << 14) | (1 << 15)), dataSize=8
     wrattr ss, t4
 
     # Set the new rip.
@@ -178,8 +186,10 @@ def macroop SYSRET_TO_64
     wrlimit cs, t1, dataSize=4
     # Not writable, read/execute-able, not expandDown,
     # dpl=3, defaultSize=0, long mode
-    limm t4, ((0 << 0) | (1 << 1) | (0 << 2) | \
-              (3 << 3) | (0 << 5) | (1 << 6)), dataSize=8
+    limm t4, ((3 << 0)  | (0  << 2)  | (0 << 3)   | \
+              (1 << 4)  | (0  << 5)  | (1 << 6)   | \
+              (1 << 7)  | (10 << 8)  | (0 << 12)  | \
+              (1 << 13) | (0  << 14) | (1 << 15)), dataSize=8
     wrattr cs, t4
 
     # Only the selector is changed for SS.
@@ -210,8 +220,10 @@ def macroop SYSRET_TO_COMPAT
     wrlimit cs, t1, dataSize=4
     # Not writable, read/execute-able, not expandDown,
     # dpl=3, defaultSize=1, not long mode
-    limm t4, ((0 << 0) | (1 << 1) | (0 << 2) | \
-              (3 << 3) | (1 << 5) | (0 << 6)), dataSize=8
+    limm t4, ((3 << 0)  | (0  << 2)  | (0 << 3)   | \
+              (1 << 4)  | (0  << 5)  | (1 << 6)   | \
+              (1 << 7)  | (10 << 8)  | (0 << 12)  | \
+              (1 << 13) | (0  << 14) | (1 << 15)), dataSize=8
     wrattr cs, t4
 
     # Only the selector is changed for SS.
index 2fcc56e8af5e467bff4f22645f353b56610e4ca1..10653e1ccbb7b5188d09dbda60b84acb60509af3 100644 (file)
@@ -76,10 +76,8 @@ def rom
     # Check if we're changing privelege level. At this point we can assume
     # we're going to a DPL that's less than or equal to the CPL. 
     rdattr t10, hs, dataSize=8
-    srli t10, t10, 3, dataSize=8
     andi t10, t10, 3, dataSize=8
     rdattr t5, cs, dataSize=8
-    srli t5, t5, 3, dataSize=8
     andi t5, t5, 0x3, dataSize=8
     sub t0, t5, t10, flags=(EZF,), dataSize=8
     # We're going to change priviledge, so zero out the stack selector. We
index 6935c780d2c71613d4f4c1132d92157db0192318..dfa10587a57243e0a277cd5142c071168183251a 100644 (file)
@@ -1247,9 +1247,18 @@ let {{
             SegDescriptor desc = SrcReg1;
             SegSelector selector = SrcReg2;
             if (selector.si || selector.ti) {
+                if (!desc.p)
+                    panic("Segment not present.\\n");
                 SegAttr attr = 0;
                 attr.dpl = desc.dpl;
+                attr.unusable = 0;
                 attr.defaultSize = desc.d;
+                attr.longMode = desc.l;
+                attr.avl = desc.avl;
+                attr.granularity = desc.g;
+                attr.present = desc.p;
+                attr.system = desc.s;
+                attr.type = desc.type;
                 if (!desc.s) {
                     // The expand down bit happens to be set for gates.
                     if (desc.type.e) {
@@ -1257,12 +1266,12 @@ let {{
                     }
                     attr.readable = 1;
                     attr.writable = 1;
+                    attr.expandDown = 0;
                 } else {
-                    if (!desc.p)
-                        panic("Segment not present.\\n");
                     if (desc.type.codeOrData) {
+                        attr.expandDown = 0;
                         attr.readable = desc.type.r;
-                        attr.longMode = desc.l;
+                        attr.writable = 0;
                     } else {
                         attr.expandDown = desc.type.e;
                         attr.readable = 1;
index 088dbeace434ec517153dfc677debef3c9d436d8..1069968482cb6f25fdd9eec2f3e2356ce1d7bada 100644 (file)
@@ -834,12 +834,18 @@ namespace X86ISA
     EndBitUnion(SegDescriptor)
 
     BitUnion64(SegAttr)
-        Bitfield<0> writable;
-        Bitfield<1> readable;
-        Bitfield<2> expandDown;
-        Bitfield<4, 3> dpl;
-        Bitfield<5> defaultSize;
-        Bitfield<6> longMode;
+        Bitfield<1, 0> dpl;
+        Bitfield<2> unusable;
+        Bitfield<3> defaultSize;
+        Bitfield<4> longMode;
+        Bitfield<5> avl;
+        Bitfield<6> granularity;
+        Bitfield<7> present;
+        Bitfield<11, 8> type;
+        Bitfield<12> writable;
+        Bitfield<13> readable;
+        Bitfield<14> expandDown;
+        Bitfield<15> system;
     EndBitUnion(SegAttr)
 
     BitUnion64(GateDescriptor)
index f7b5468b401b9f78ce942f0791eaf0ca68fea121..c643a7924275d34183364cdf868f1209188f13c7 100644 (file)
@@ -208,12 +208,18 @@ X86_64LiveProcess::startup()
         ThreadContext * tc = system->getThreadContext(contextIds[i]);
 
         SegAttr dataAttr = 0;
+        dataAttr.dpl = 3;
+        dataAttr.unusable = 0;
+        dataAttr.defaultSize = 1;
+        dataAttr.longMode = 1;
+        dataAttr.avl = 0;
+        dataAttr.granularity = 1;
+        dataAttr.present = 1;
+        dataAttr.type = 3;
         dataAttr.writable = 1;
         dataAttr.readable = 1;
         dataAttr.expandDown = 0;
-        dataAttr.dpl = 3;
-        dataAttr.defaultSize = 0;
-        dataAttr.longMode = 1;
+        dataAttr.system = 1;
 
         //Initialize the segment registers.
         for(int seg = 0; seg < NUM_SEGMENTREGS; seg++) {
@@ -223,12 +229,18 @@ X86_64LiveProcess::startup()
         }
 
         SegAttr csAttr = 0;
-        csAttr.writable = 0;
-        csAttr.readable = 1;
-        csAttr.expandDown = 0;
         csAttr.dpl = 3;
+        csAttr.unusable = 0;
         csAttr.defaultSize = 0;
         csAttr.longMode = 1;
+        csAttr.avl = 0;
+        csAttr.granularity = 1;
+        csAttr.present = 1;
+        csAttr.type = 10;
+        csAttr.writable = 0;
+        csAttr.readable = 1;
+        csAttr.expandDown = 0;
+        csAttr.system = 1;
 
         tc->setMiscRegNoEffect(MISCREG_CS_ATTR, csAttr);
 
@@ -307,12 +319,18 @@ I386LiveProcess::startup()
         ThreadContext * tc = system->getThreadContext(contextIds[i]);
 
         SegAttr dataAttr = 0;
-        dataAttr.writable = 1;
-        dataAttr.readable = 1;
-        dataAttr.expandDown = 0;
         dataAttr.dpl = 3;
+        dataAttr.unusable = 0;
         dataAttr.defaultSize = 1;
         dataAttr.longMode = 0;
+        dataAttr.avl = 0;
+        dataAttr.granularity = 1;
+        dataAttr.present = 1;
+        dataAttr.type = 3;
+        dataAttr.writable = 1;
+        dataAttr.readable = 1;
+        dataAttr.expandDown = 0;
+        dataAttr.system = 1;
 
         //Initialize the segment registers.
         for(int seg = 0; seg < NUM_SEGMENTREGS; seg++) {
@@ -324,12 +342,18 @@ I386LiveProcess::startup()
         }
 
         SegAttr csAttr = 0;
-        csAttr.writable = 0;
-        csAttr.readable = 1;
-        csAttr.expandDown = 0;
         csAttr.dpl = 3;
+        csAttr.unusable = 0;
         csAttr.defaultSize = 1;
         csAttr.longMode = 0;
+        csAttr.avl = 0;
+        csAttr.granularity = 1;
+        csAttr.present = 1;
+        csAttr.type = 0xa;
+        csAttr.writable = 0;
+        csAttr.readable = 1;
+        csAttr.expandDown = 0;
+        csAttr.system = 1;
 
         tc->setMiscRegNoEffect(MISCREG_CS_ATTR, csAttr);
 
index 66bee70e84a8adfff3ba095e17987ed77f7d8467..1594cc3752d0e6949c531a3aacebdc55fc5cff84 100644 (file)
@@ -93,24 +93,33 @@ installSegDesc(ThreadContext *tc, SegmentRegIndex seg,
     uint64_t limit = desc.limitLow | (desc.limitHigh << 16);
 
     SegAttr attr = 0;
+
+    attr.dpl = desc.dpl;
+    attr.unusable = 0;
+    attr.defaultSize = desc.d;
+    attr.longMode = desc.l;
+    attr.avl = desc.avl;
+    attr.granularity = desc.g;
+    attr.present = desc.p;
+    attr.system = desc.s;
+    attr.type = desc.type;
     if (desc.s) {
         if (desc.type.codeOrData) {
             // Code segment
+            attr.expandDown = 0;
             attr.readable = desc.type.r;
+            attr.writable = 0;
         } else {
             // Data segment
+            attr.expandDown = desc.type.e;
             attr.readable = 1;
             attr.writable = desc.type.w;
-            attr.expandDown = desc.type.e;
         }
     } else {
-        attr.writable = 1;
         attr.readable = 1;
+        attr.writable = 1;
         attr.expandDown = 0;
     }
-    attr.longMode = desc.l;
-    attr.dpl = desc.dpl;
-    attr.defaultSize = desc.d;
 
     tc->setMiscReg(MISCREG_SEG_BASE(seg), base);
     tc->setMiscReg(MISCREG_SEG_EFF_BASE(seg), honorBase ? base : 0);