summaryrefslogtreecommitdiff
path: root/sys/src/cmd/vmx/exith.c
diff options
context:
space:
mode:
authoraiju <devnull@localhost>2017-06-18 22:17:35 +0000
committeraiju <devnull@localhost>2017-06-18 22:17:35 +0000
commit2806a34ec0152cbf8ac0e2198bda111a9b1273bd (patch)
tree788b51551953265bd54211d44b674f7ed7b05d45 /sys/src/cmd/vmx/exith.c
parented040d676ad95858211ec8b5f43e8713692fdeb2 (diff)
vmx(1): linux kernel loading; PIT fixes to support linux; support VGA 0x3D4 word writes; support sending virtio ethernet packets to a file and prepending snoopy headers
Diffstat (limited to 'sys/src/cmd/vmx/exith.c')
-rw-r--r--sys/src/cmd/vmx/exith.c73
1 files changed, 64 insertions, 9 deletions
diff --git a/sys/src/cmd/vmx/exith.c b/sys/src/cmd/vmx/exith.c
index f68566607..0c27bc9bd 100644
--- a/sys/src/cmd/vmx/exith.c
+++ b/sys/src/cmd/vmx/exith.c
@@ -14,6 +14,13 @@ struct ExitInfo {
u32int ilen, iinfo;
};
+static char *x86reg[16] = {
+ RAX, RCX, RDX, RBX,
+ RSP, RBP, RSI, RDI,
+ R8, R9, R10, R11,
+ R12, R13, R14, R15
+};
+
static void
skipinstr(ExitInfo *ei)
{
@@ -242,7 +249,7 @@ cpuid(ExitInfo *ei)
break;
case 2: goto literal; /* cache stuff */
case 3: goto zero; /* processor serial number */
- case 4: goto literal; /* cache stuff */
+ case 4: goto zero; /* cache stuff */
case 5: goto zero; /* monitor/mwait */
case 6: goto zero; /* thermal management */
case 7: goto zero; /* more features */
@@ -305,6 +312,7 @@ rdwrmsr(ExitInfo *ei)
if(rd) val = rget("efer");
else rset("efer", val);
break;
+ case 0x8B: val = 0; break; /* microcode update */
default:
if(rd){
vmerror("read from unknown MSR %#ux ignored", cx);
@@ -323,12 +331,6 @@ rdwrmsr(ExitInfo *ei)
static void
movdr(ExitInfo *ei)
{
- static char *reg[16] = {
- RAX, RCX, RDX, RBX,
- RSP, RBP, RSI, RDI,
- R8, R9, R10, R11,
- R12, R13, R14, R15
- };
static char *dr[8] = { "dr0", "dr1", "dr2", "dr3", nil, nil, "dr6", "dr7" };
int q;
@@ -338,13 +340,65 @@ movdr(ExitInfo *ei)
return;
}
if((q & 16) != 0)
- rset(reg[q >> 8 & 15], rget(dr[q & 7]));
+ rset(x86reg[q >> 8 & 15], rget(dr[q & 7]));
else
- rset(dr[q & 7], rget(reg[q >> 8 & 15]));
+ rset(dr[q & 7], rget(x86reg[q >> 8 & 15]));
skipinstr(ei);
}
static void
+movcr(ExitInfo *ei)
+{
+ u32int q;
+
+ q = ei->qual;
+ switch(q & 15){
+ case 0:
+ switch(q >> 4 & 3){
+ case 0:
+ vmdebug("illegal CR0 write, value %#ux", rget(x86reg[q >> 8 & 15]));
+ rset("cr0real", rget(x86reg[q >> 8 & 15]));
+ skipinstr(ei);
+ break;
+ case 1:
+ vmerror("shouldn't happen: trap on MOV from CR0");
+ rset(x86reg[q >> 8 & 15], rget("cr0fake"));
+ skipinstr(ei);
+ break;
+ case 2:
+ vmerror("shouldn't happen: trap on CLTS");
+ rset("cr0real", rget("cr0real") & ~8);
+ skipinstr(ei);
+ break;
+ case 3:
+ vmerror("LMSW handler unimplemented");
+ postexc("#ud", NOERRC);
+ }
+ break;
+ case 4:
+ switch(ei->qual >> 4 & 3){
+ case 0:
+ vmdebug("illegal CR4 write, value %#ux", rget(x86reg[q >> 8 & 15]));
+ rset("cr4real", rget(x86reg[q >> 8 & 15]));
+ skipinstr(ei);
+ break;
+ case 1:
+ vmerror("shouldn't happen: trap on MOV from CR4");
+ rset(x86reg[q >> 8 & 15], rget("cr3fake"));
+ skipinstr(ei);
+ break;
+ default:
+ vmerror("unknown CR4 operation %d", q);
+ postexc("#ud", NOERRC);
+ }
+ break;
+ default:
+ vmerror("access to unknown control register CR%d", ei->qual & 15);
+ postexc("#ud", NOERRC);
+ }
+}
+
+static void
dbgexc(ExitInfo *ei)
{
rset("dr6", rget("dr6") | ei->qual);
@@ -380,6 +434,7 @@ static ExitType etypes[] = {
{".wrmsr", rdwrmsr},
{".movdr", movdr},
{"#db", dbgexc},
+ {"movcr", movcr},
};
void