summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/arch/x86/faults.cc22
-rw-r--r--src/arch/x86/isa/insts/general_purpose/system_calls.py36
-rw-r--r--src/arch/x86/isa/insts/romutil.py2
-rw-r--r--src/arch/x86/isa/microops/regop.isa15
-rw-r--r--src/arch/x86/miscregs.hh18
-rw-r--r--src/arch/x86/process.cc48
-rw-r--r--src/arch/x86/system.cc19
7 files changed, 116 insertions, 44 deletions
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);