|
|
|
@ -61,6 +61,7 @@ |
|
|
|
#include "vmx.h" |
|
|
|
#include "x86.h" |
|
|
|
#include "x86_descr.h" |
|
|
|
#include "x86_flags.h" |
|
|
|
#include "x86_mmu.h" |
|
|
|
#include "x86_decode.h" |
|
|
|
#include "x86_emu.h" |
|
|
|
@ -434,6 +435,52 @@ static void hvf_cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void hvf_load_regs(CPUState *cs) |
|
|
|
{ |
|
|
|
X86CPU *cpu = X86_CPU(cs); |
|
|
|
CPUX86State *env = &cpu->env; |
|
|
|
|
|
|
|
int i = 0; |
|
|
|
RRX(env, R_EAX) = rreg(cs->accel->fd, HV_X86_RAX); |
|
|
|
RRX(env, R_EBX) = rreg(cs->accel->fd, HV_X86_RBX); |
|
|
|
RRX(env, R_ECX) = rreg(cs->accel->fd, HV_X86_RCX); |
|
|
|
RRX(env, R_EDX) = rreg(cs->accel->fd, HV_X86_RDX); |
|
|
|
RRX(env, R_ESI) = rreg(cs->accel->fd, HV_X86_RSI); |
|
|
|
RRX(env, R_EDI) = rreg(cs->accel->fd, HV_X86_RDI); |
|
|
|
RRX(env, R_ESP) = rreg(cs->accel->fd, HV_X86_RSP); |
|
|
|
RRX(env, R_EBP) = rreg(cs->accel->fd, HV_X86_RBP); |
|
|
|
for (i = 8; i < 16; i++) { |
|
|
|
RRX(env, i) = rreg(cs->accel->fd, HV_X86_RAX + i); |
|
|
|
} |
|
|
|
|
|
|
|
env->eflags = rreg(cs->accel->fd, HV_X86_RFLAGS); |
|
|
|
rflags_to_lflags(env); |
|
|
|
env->eip = rreg(cs->accel->fd, HV_X86_RIP); |
|
|
|
} |
|
|
|
|
|
|
|
void hvf_store_regs(CPUState *cs) |
|
|
|
{ |
|
|
|
X86CPU *cpu = X86_CPU(cs); |
|
|
|
CPUX86State *env = &cpu->env; |
|
|
|
|
|
|
|
int i = 0; |
|
|
|
wreg(cs->accel->fd, HV_X86_RAX, RAX(env)); |
|
|
|
wreg(cs->accel->fd, HV_X86_RBX, RBX(env)); |
|
|
|
wreg(cs->accel->fd, HV_X86_RCX, RCX(env)); |
|
|
|
wreg(cs->accel->fd, HV_X86_RDX, RDX(env)); |
|
|
|
wreg(cs->accel->fd, HV_X86_RSI, RSI(env)); |
|
|
|
wreg(cs->accel->fd, HV_X86_RDI, RDI(env)); |
|
|
|
wreg(cs->accel->fd, HV_X86_RBP, RBP(env)); |
|
|
|
wreg(cs->accel->fd, HV_X86_RSP, RSP(env)); |
|
|
|
for (i = 8; i < 16; i++) { |
|
|
|
wreg(cs->accel->fd, HV_X86_RAX + i, RRX(env, i)); |
|
|
|
} |
|
|
|
|
|
|
|
lflags_to_rflags(env); |
|
|
|
wreg(cs->accel->fd, HV_X86_RFLAGS, env->eflags); |
|
|
|
macvm_set_rip(cs, env->eip); |
|
|
|
} |
|
|
|
|
|
|
|
int hvf_vcpu_exec(CPUState *cpu) |
|
|
|
{ |
|
|
|
X86CPU *x86_cpu = X86_CPU(cpu); |
|
|
|
@ -517,10 +564,10 @@ int hvf_vcpu_exec(CPUState *cpu) |
|
|
|
if (ept_emulation_fault(slot, gpa, exit_qual)) { |
|
|
|
struct x86_decode decode; |
|
|
|
|
|
|
|
load_regs(cpu); |
|
|
|
hvf_load_regs(cpu); |
|
|
|
decode_instruction(env, &decode); |
|
|
|
exec_instruction(env, &decode); |
|
|
|
store_regs(cpu); |
|
|
|
hvf_store_regs(cpu); |
|
|
|
break; |
|
|
|
} |
|
|
|
break; |
|
|
|
@ -535,7 +582,7 @@ int hvf_vcpu_exec(CPUState *cpu) |
|
|
|
|
|
|
|
if (!string && in) { |
|
|
|
uint64_t val = 0; |
|
|
|
load_regs(cpu); |
|
|
|
hvf_load_regs(cpu); |
|
|
|
hvf_handle_io(env_cpu(env), port, &val, 0, size, 1); |
|
|
|
if (size == 1) { |
|
|
|
AL(env) = val; |
|
|
|
@ -547,7 +594,7 @@ int hvf_vcpu_exec(CPUState *cpu) |
|
|
|
RAX(env) = (uint64_t)val; |
|
|
|
} |
|
|
|
env->eip += ins_len; |
|
|
|
store_regs(cpu); |
|
|
|
hvf_store_regs(cpu); |
|
|
|
break; |
|
|
|
} else if (!string && !in) { |
|
|
|
RAX(env) = rreg(cpu->accel->fd, HV_X86_RAX); |
|
|
|
@ -557,11 +604,11 @@ int hvf_vcpu_exec(CPUState *cpu) |
|
|
|
} |
|
|
|
struct x86_decode decode; |
|
|
|
|
|
|
|
load_regs(cpu); |
|
|
|
hvf_load_regs(cpu); |
|
|
|
decode_instruction(env, &decode); |
|
|
|
assert(ins_len == decode.len); |
|
|
|
exec_instruction(env, &decode); |
|
|
|
store_regs(cpu); |
|
|
|
hvf_store_regs(cpu); |
|
|
|
|
|
|
|
break; |
|
|
|
} |
|
|
|
@ -614,21 +661,21 @@ int hvf_vcpu_exec(CPUState *cpu) |
|
|
|
case EXIT_REASON_RDMSR: |
|
|
|
case EXIT_REASON_WRMSR: |
|
|
|
{ |
|
|
|
load_regs(cpu); |
|
|
|
hvf_load_regs(cpu); |
|
|
|
if (exit_reason == EXIT_REASON_RDMSR) { |
|
|
|
simulate_rdmsr(env); |
|
|
|
} else { |
|
|
|
simulate_wrmsr(env); |
|
|
|
} |
|
|
|
env->eip += ins_len; |
|
|
|
store_regs(cpu); |
|
|
|
hvf_store_regs(cpu); |
|
|
|
break; |
|
|
|
} |
|
|
|
case EXIT_REASON_CR_ACCESS: { |
|
|
|
int cr; |
|
|
|
int reg; |
|
|
|
|
|
|
|
load_regs(cpu); |
|
|
|
hvf_load_regs(cpu); |
|
|
|
cr = exit_qual & 15; |
|
|
|
reg = (exit_qual >> 8) & 15; |
|
|
|
|
|
|
|
@ -656,16 +703,16 @@ int hvf_vcpu_exec(CPUState *cpu) |
|
|
|
abort(); |
|
|
|
} |
|
|
|
env->eip += ins_len; |
|
|
|
store_regs(cpu); |
|
|
|
hvf_store_regs(cpu); |
|
|
|
break; |
|
|
|
} |
|
|
|
case EXIT_REASON_APIC_ACCESS: { /* TODO */ |
|
|
|
struct x86_decode decode; |
|
|
|
|
|
|
|
load_regs(cpu); |
|
|
|
hvf_load_regs(cpu); |
|
|
|
decode_instruction(env, &decode); |
|
|
|
exec_instruction(env, &decode); |
|
|
|
store_regs(cpu); |
|
|
|
hvf_store_regs(cpu); |
|
|
|
break; |
|
|
|
} |
|
|
|
case EXIT_REASON_TPR: { |
|
|
|
|