From 7f50ea05ac848e22a70c9a9471904637aea2f907 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 28 May 2009 23:27:56 -0700 Subject: X86: Keep track of more descriptor state to accomodate KVM. --- src/arch/x86/faults.cc | 22 ++++++++-- .../x86/isa/insts/general_purpose/system_calls.py | 36 ++++++++++------ src/arch/x86/isa/insts/romutil.py | 2 - src/arch/x86/isa/microops/regop.isa | 15 +++++-- src/arch/x86/miscregs.hh | 18 +++++--- src/arch/x86/process.cc | 48 ++++++++++++++++------ src/arch/x86/system.cc | 19 ++++++--- 7 files changed, 116 insertions(+), 44 deletions(-) (limited to 'src/arch/x86') diff --git a/src/arch/x86/faults.cc b/src/arch/x86/faults.cc index 10b539248..34137444f 100644 --- a/src/arch/x86/faults.cc +++ b/src/arch/x86/faults.cc @@ -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, diff --git a/src/arch/x86/isa/insts/general_purpose/system_calls.py b/src/arch/x86/isa/insts/general_purpose/system_calls.py index fb282502d..9501116d9 100644 --- a/src/arch/x86/isa/insts/general_purpose/system_calls.py +++ b/src/arch/x86/isa/insts/general_purpose/system_calls.py @@ -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. diff --git a/src/arch/x86/isa/insts/romutil.py b/src/arch/x86/isa/insts/romutil.py index 2fcc56e8a..10653e1cc 100644 --- a/src/arch/x86/isa/insts/romutil.py +++ b/src/arch/x86/isa/insts/romutil.py @@ -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 diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index 6935c780d..dfa10587a 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -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; diff --git a/src/arch/x86/miscregs.hh b/src/arch/x86/miscregs.hh index 088dbeace..106996848 100644 --- a/src/arch/x86/miscregs.hh +++ b/src/arch/x86/miscregs.hh @@ -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) diff --git a/src/arch/x86/process.cc b/src/arch/x86/process.cc index f7b5468b4..c643a7924 100644 --- a/src/arch/x86/process.cc +++ b/src/arch/x86/process.cc @@ -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); diff --git a/src/arch/x86/system.cc b/src/arch/x86/system.cc index 66bee70e8..1594cc375 100644 --- a/src/arch/x86/system.cc +++ b/src/arch/x86/system.cc @@ -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); -- cgit v1.2.3