X86: Keep track of more descriptor state to accomodate KVM.

This commit is contained in:
Gabe Black 2009-05-28 23:27:56 -07:00
parent 47877cf2db
commit 7f50ea05ac
7 changed files with 116 additions and 44 deletions

View 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,

View 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.

View 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

View 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;

View 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)

View 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.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.dpl = 3;
csAttr.defaultSize = 0;
csAttr.longMode = 1;
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.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.dpl = 3;
dataAttr.defaultSize = 1;
dataAttr.longMode = 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.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.dpl = 3;
csAttr.defaultSize = 1;
csAttr.longMode = 0;
csAttr.system = 1;
tc->setMiscRegNoEffect(MISCREG_CS_ATTR, csAttr);

View 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);