diff --git a/hypervisor/arch/x86/guest/guest.c b/hypervisor/arch/x86/guest/guest.c index fe48af056..16765c05b 100644 --- a/hypervisor/arch/x86/guest/guest.c +++ b/hypervisor/arch/x86/guest/guest.c @@ -110,8 +110,6 @@ inline bool vm_lapic_disabled(struct vm *vm) enum vm_paging_mode get_vcpu_paging_mode(struct vcpu *vcpu) { - struct run_context *cur_context = - &vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context]; enum vm_cpu_mode cpu_mode; cpu_mode = get_vcpu_mode(vcpu); @@ -120,10 +118,10 @@ enum vm_paging_mode get_vcpu_paging_mode(struct vcpu *vcpu) return PAGING_MODE_0_LEVEL; } else if (cpu_mode == CPU_MODE_PROTECTED) { - if ((cur_context->cr4 & CR4_PAE) != 0U) { + if ((vcpu_get_cr4(vcpu) & CR4_PAE) != 0U) { return PAGING_MODE_3_LEVEL; } - else if ((cur_context->cr0 & CR0_PG) != 0U) { + else if ((vcpu_get_cr0(vcpu) & CR0_PG) != 0U) { return PAGING_MODE_2_LEVEL; } return PAGING_MODE_0_LEVEL; @@ -273,8 +271,6 @@ out: int gva2gpa(struct vcpu *vcpu, uint64_t gva, uint64_t *gpa, uint32_t *err_code) { - struct run_context *cur_context = - &vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context]; enum vm_paging_mode pm = get_vcpu_paging_mode(vcpu); struct page_walk_info pw_info; int ret = 0; @@ -284,15 +280,14 @@ int gva2gpa(struct vcpu *vcpu, uint64_t gva, uint64_t *gpa, } *gpa = 0UL; - pw_info.top_entry = cur_context->cr3; + pw_info.top_entry = exec_vmread(VMX_GUEST_CR3); pw_info.level = pm; pw_info.is_write_access = ((*err_code & PAGE_FAULT_WR_FLAG) != 0U); pw_info.is_inst_fetch = ((*err_code & PAGE_FAULT_ID_FLAG) != 0U); pw_info.is_user_mode = ((exec_vmread16(VMX_GUEST_CS_SEL) & 0x3U) == 3U); pw_info.pse = true; - pw_info.nxe = - ((cur_context->ia32_efer & MSR_IA32_EFER_NXE_BIT) != 0UL); - pw_info.wp = ((cur_context->cr0 & CR0_WP) != 0UL); + pw_info.nxe = ((vcpu_get_efer(vcpu) & MSR_IA32_EFER_NXE_BIT) != 0UL); + pw_info.wp = ((vcpu_get_cr0(vcpu) & CR0_WP) != 0UL); *err_code &= ~PAGE_FAULT_P_FLAG; @@ -304,7 +299,7 @@ int gva2gpa(struct vcpu *vcpu, uint64_t gva, uint64_t *gpa, ret = local_gva2gpa_pae(vcpu, &pw_info, gva, gpa, err_code); } else if (pm == PAGING_MODE_2_LEVEL) { pw_info.width = 10U; - pw_info.pse = ((cur_context->cr4 & CR4_PSE) != 0UL); + pw_info.pse = ((vcpu_get_cr4(vcpu) & CR4_PSE) != 0UL); pw_info.nxe = false; ret = local_gva2gpa_common(vcpu, &pw_info, gva, gpa, err_code); } else { diff --git a/hypervisor/arch/x86/guest/instr_emul.c b/hypervisor/arch/x86/guest/instr_emul.c index 3932e18fe..3dcc53ff8 100644 --- a/hypervisor/arch/x86/guest/instr_emul.c +++ b/hypervisor/arch/x86/guest/instr_emul.c @@ -1643,8 +1643,7 @@ vie_calculate_gla(enum vm_cpu_mode cpu_mode, enum cpu_reg_name seg, int vie_init(struct instr_emul_vie *vie, struct vcpu *vcpu) { - uint64_t guest_rip_gva = - vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context].rip; + uint64_t guest_rip_gva = vcpu_get_rip(vcpu); uint32_t inst_len = vcpu->arch_vcpu.inst_len; uint32_t err_code; int ret; diff --git a/hypervisor/arch/x86/guest/instr_emul_wrapper.c b/hypervisor/arch/x86/guest/instr_emul_wrapper.c index ea9723c6d..8ae146159 100644 --- a/hypervisor/arch/x86/guest/instr_emul_wrapper.c +++ b/hypervisor/arch/x86/guest/instr_emul_wrapper.c @@ -26,8 +26,6 @@ is_descriptor_table(enum cpu_reg_name reg); int vm_get_register(struct vcpu *vcpu, enum cpu_reg_name reg, uint64_t *retval) { - struct run_context *cur_context; - if (vcpu == NULL) { return -EINVAL; } @@ -37,10 +35,9 @@ int vm_get_register(struct vcpu *vcpu, enum cpu_reg_name reg, uint64_t *retval) } if ((reg >= CPU_REG_GENERAL_FIRST) && (reg <= CPU_REG_GENERAL_LAST)) { - cur_context = - &vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context]; - *retval = cur_context->guest_cpu_regs.longs[reg]; - } else if ((reg >= CPU_REG_NONGENERAL_FIRST) && (reg <= CPU_REG_NONGENERAL_LAST)) { + *retval = vcpu_get_gpreg(vcpu, reg); + } else if ((reg >= CPU_REG_NONGENERAL_FIRST) && + (reg <= CPU_REG_NONGENERAL_LAST)) { uint32_t field = get_vmcs_field(reg); if (field != VMX_INVALID_VMCS_FIELD) { @@ -61,8 +58,6 @@ int vm_get_register(struct vcpu *vcpu, enum cpu_reg_name reg, uint64_t *retval) int vm_set_register(struct vcpu *vcpu, enum cpu_reg_name reg, uint64_t val) { - struct run_context *cur_context; - if (vcpu == NULL) { return -EINVAL; } @@ -72,10 +67,9 @@ int vm_set_register(struct vcpu *vcpu, enum cpu_reg_name reg, uint64_t val) } if ((reg >= CPU_REG_GENERAL_FIRST) && (reg <= CPU_REG_GENERAL_LAST)) { - cur_context = - &vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context]; - cur_context->guest_cpu_regs.longs[reg] = val; - } else if ((reg >= CPU_REG_NONGENERAL_FIRST) && (reg <= CPU_REG_NONGENERAL_LAST)) { + vcpu_set_gpreg(vcpu, reg, val); + } else if ((reg >= CPU_REG_NONGENERAL_FIRST) && + (reg <= CPU_REG_NONGENERAL_LAST)) { uint32_t field = get_vmcs_field(reg); if (field != VMX_INVALID_VMCS_FIELD) { @@ -305,8 +299,7 @@ static void get_guest_paging_info(struct vcpu *vcpu, struct instr_emul_ctxt *emu ASSERT(emul_ctxt != NULL && vcpu != NULL, "Error in input arguments"); cpl = (uint8_t)((csar >> 5) & 3U); - emul_ctxt->paging.cr3 = - vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context].cr3; + emul_ctxt->paging.cr3 = exec_vmread(VMX_GUEST_CR3); emul_ctxt->paging.cpl = cpl; emul_ctxt->paging.cpu_mode = get_vcpu_mode(vcpu); emul_ctxt->paging.paging_mode = get_vcpu_paging_mode(vcpu); @@ -348,8 +341,7 @@ int decode_instruction(struct vcpu *vcpu) if (retval < 0) { if (retval != -EFAULT) { pr_err("decode instruction failed @ 0x%016llx:", - vcpu->arch_vcpu. - contexts[vcpu->arch_vcpu.cur_context].rip); + vcpu_get_rip(vcpu)); } return retval; } @@ -363,7 +355,7 @@ int decode_instruction(struct vcpu *vcpu) if (retval != 0) { pr_err("decode instruction failed @ 0x%016llx:", - vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context].rip); + vcpu_get_rip(vcpu)); return -EINVAL; } diff --git a/hypervisor/arch/x86/guest/instr_emul_wrapper.h b/hypervisor/arch/x86/guest/instr_emul_wrapper.h index 2e5f135cc..a0fdc19a0 100644 --- a/hypervisor/arch/x86/guest/instr_emul_wrapper.h +++ b/hypervisor/arch/x86/guest/instr_emul_wrapper.h @@ -31,65 +31,6 @@ #define INSTR_EMUL_WRAPPER_H #include -/** - * - * Identifiers for architecturally defined registers. - * - * These register names is used in condition statement. - * Within the following groups,register name need to be - * kept in order: - * General register names group (CPU_REG_RAX~CPU_REG_R15); - * Non general register names group (CPU_REG_CR0~CPU_REG_GDTR); - * Segement register names group (CPU_REG_ES~CPU_REG_GS). - */ -enum cpu_reg_name { - /* General purpose register layout should align with - * struct cpu_gp_regs - */ - CPU_REG_RAX, - CPU_REG_RCX, - CPU_REG_RDX, - CPU_REG_RBX, - CPU_REG_RSP, - CPU_REG_RBP, - CPU_REG_RSI, - CPU_REG_RDI, - CPU_REG_R8, - CPU_REG_R9, - CPU_REG_R10, - CPU_REG_R11, - CPU_REG_R12, - CPU_REG_R13, - CPU_REG_R14, - CPU_REG_R15, - - CPU_REG_CR0, - CPU_REG_CR2, - CPU_REG_CR3, - CPU_REG_CR4, - CPU_REG_DR7, - CPU_REG_RIP, - CPU_REG_RFLAGS, - /*CPU_REG_NATURAL_LAST*/ - CPU_REG_EFER, - CPU_REG_PDPTE0, - CPU_REG_PDPTE1, - CPU_REG_PDPTE2, - CPU_REG_PDPTE3, - /*CPU_REG_64BIT_LAST,*/ - CPU_REG_ES, - CPU_REG_CS, - CPU_REG_SS, - CPU_REG_DS, - CPU_REG_FS, - CPU_REG_GS, - CPU_REG_LDTR, - CPU_REG_TR, - CPU_REG_IDTR, - CPU_REG_GDTR - /*CPU_REG_LAST*/ -}; - /** * Define the following MACRO to make range checking clear. * diff --git a/hypervisor/arch/x86/guest/vcpu.c b/hypervisor/arch/x86/guest/vcpu.c index 69742630d..bea38ecec 100644 --- a/hypervisor/arch/x86/guest/vcpu.c +++ b/hypervisor/arch/x86/guest/vcpu.c @@ -14,6 +14,141 @@ extern struct efi_ctx* efi_ctx; vm_sw_loader_t vm_sw_loader; +inline uint64_t vcpu_get_gpreg(struct vcpu *vcpu, uint32_t reg) +{ + struct run_context *cur_context = + &vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context]; + + return cur_context->guest_cpu_regs.longs[reg]; +} + +inline void vcpu_set_gpreg(struct vcpu *vcpu, uint32_t reg, uint64_t val) +{ + struct run_context *cur_context = + &vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context]; + + cur_context->guest_cpu_regs.longs[reg] = val; +} + +inline uint64_t vcpu_get_rip(struct vcpu *vcpu) +{ + if (bitmap_test(CPU_REG_RIP, &vcpu->reg_updated) == 0 && + bitmap_test_and_set_lock(CPU_REG_RIP, &vcpu->reg_cached) == 0) + vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context].rip = + exec_vmread(VMX_GUEST_RIP); + return vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context].rip; +} + +inline void vcpu_set_rip(struct vcpu *vcpu, uint64_t val) +{ + vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context].rip = val; + bitmap_set_lock(CPU_REG_RIP, &vcpu->reg_updated); +} + +inline uint64_t vcpu_get_rsp(struct vcpu *vcpu) +{ + struct run_context *cur_context = + &vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context]; + + return cur_context->guest_cpu_regs.regs.rsp; +} + +inline void vcpu_set_rsp(struct vcpu *vcpu, uint64_t val) +{ + struct run_context *cur_context = + &vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context]; + + cur_context->guest_cpu_regs.regs.rsp = val; + bitmap_set_lock(CPU_REG_RSP, &vcpu->reg_updated); +} + +inline uint64_t vcpu_get_efer(struct vcpu *vcpu) +{ + if (bitmap_test(CPU_REG_EFER, &vcpu->reg_updated) == 0 && + bitmap_test_and_set_lock(CPU_REG_EFER, &vcpu->reg_cached) == 0) + vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context].ia32_efer + = exec_vmread64(VMX_GUEST_IA32_EFER_FULL); + return vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context].ia32_efer; +} + +inline void vcpu_set_efer(struct vcpu *vcpu, uint64_t val) +{ + vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context].ia32_efer = val; + bitmap_set_lock(CPU_REG_EFER, &vcpu->reg_updated); +} + +inline uint64_t vcpu_get_rflags(struct vcpu *vcpu) +{ + if (bitmap_test(CPU_REG_RFLAGS, &vcpu->reg_updated) == 0 && + bitmap_test_and_set_lock(CPU_REG_RFLAGS, + &vcpu->reg_cached) == 0 && vcpu->launched) + vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context].rflags = + exec_vmread(VMX_GUEST_RFLAGS); + return vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context].rflags; +} + +inline void vcpu_set_rflags(struct vcpu *vcpu, uint64_t val) +{ + vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context].rflags = val; + bitmap_set_lock(CPU_REG_RFLAGS, &vcpu->reg_updated); +} + +inline uint64_t vcpu_get_cr0(struct vcpu *vcpu) +{ + uint64_t mask; + + if (bitmap_test_and_set_lock(CPU_REG_CR0, &vcpu->reg_cached) == 0) { + mask = exec_vmread(VMX_CR0_MASK); + vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context].cr0 = + (exec_vmread(VMX_CR0_READ_SHADOW) & mask) | + (exec_vmread(VMX_GUEST_CR0) & (~mask)); + } + return vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context].cr0; +} + +inline int vcpu_set_cr0(struct vcpu *vcpu, uint64_t val) +{ + return vmx_write_cr0(vcpu, val); +} + +inline uint64_t vcpu_get_cr2(struct vcpu *vcpu) +{ + return vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context].cr2; +} + +inline void vcpu_set_cr2(struct vcpu *vcpu, uint64_t val) +{ + vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context].cr2 = val; +} + +inline uint64_t vcpu_get_cr4(struct vcpu *vcpu) +{ + uint64_t mask; + + if (bitmap_test_and_set_lock(CPU_REG_CR4, &vcpu->reg_cached) == 0) { + mask = exec_vmread(VMX_CR4_MASK); + vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context].cr4 = + (exec_vmread(VMX_CR4_READ_SHADOW) & mask) | + (exec_vmread(VMX_GUEST_CR4) & (~mask)); + } + return vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context].cr4; +} + +inline int vcpu_set_cr4(struct vcpu *vcpu, uint64_t val) +{ + return vmx_write_cr4(vcpu, val); +} + +inline uint64_t vcpu_get_pat_ext(struct vcpu *vcpu) +{ + return vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context].ia32_pat; +} + +inline void vcpu_set_pat_ext(struct vcpu *vcpu, uint64_t val) +{ + vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context].ia32_pat = val; +} + struct vcpu *get_ever_run_vcpu(uint16_t pcpu_id) { return per_cpu(ever_run_vcpu, pcpu_id); @@ -128,15 +263,12 @@ int create_vcpu(uint16_t pcpu_id, struct vm *vm, struct vcpu **rtn_vcpu_handle) static void set_vcpu_mode(struct vcpu *vcpu, uint32_t cs_attr) { - struct run_context *cur_context = - &vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context]; - - if (cur_context->ia32_efer & MSR_IA32_EFER_LMA_BIT) { + if (vcpu_get_efer(vcpu) & MSR_IA32_EFER_LMA_BIT) { if (cs_attr & 0x2000) /* CS.L = 1 */ vcpu->arch_vcpu.cpu_mode = CPU_MODE_64BIT; else vcpu->arch_vcpu.cpu_mode = CPU_MODE_COMPATIBILITY; - } else if (cur_context->cr0 & CR0_PE) { + } else if (vcpu_get_cr0(vcpu) & CR0_PE) { vcpu->arch_vcpu.cpu_mode = CPU_MODE_PROTECTED; } else { vcpu->arch_vcpu.cpu_mode = CPU_MODE_REAL; @@ -153,6 +285,17 @@ int start_vcpu(struct vcpu *vcpu) ASSERT(vcpu != NULL, "Incorrect arguments"); + if (bitmap_test_and_clear_lock(CPU_REG_RIP, &vcpu->reg_updated)) + exec_vmwrite(VMX_GUEST_RIP, cur_context->rip); + if (bitmap_test_and_clear_lock(CPU_REG_RSP, &vcpu->reg_updated)) + exec_vmwrite(VMX_GUEST_RSP, + cur_context->guest_cpu_regs.regs.rsp); + if (bitmap_test_and_clear_lock(CPU_REG_EFER, &vcpu->reg_updated)) + exec_vmwrite64(VMX_GUEST_IA32_EFER_FULL, + cur_context->ia32_efer); + if (bitmap_test_and_clear_lock(CPU_REG_RFLAGS, &vcpu->reg_updated)) + exec_vmwrite(VMX_GUEST_RFLAGS, cur_context->rflags); + /* If this VCPU is not already launched, launch it */ if (!vcpu->launched) { pr_info("VM %d Starting VCPU %hu", @@ -193,27 +336,22 @@ int start_vcpu(struct vcpu *vcpu) * instruction needs to be repeated and resume VCPU accordingly */ instlen = vcpu->arch_vcpu.inst_len; - rip = cur_context->rip; - exec_vmwrite(VMX_GUEST_RIP, ((rip +(uint64_t)instlen) & + rip = vcpu_get_rip(vcpu); + exec_vmwrite(VMX_GUEST_RIP, ((rip+(uint64_t)instlen) & 0xFFFFFFFFFFFFFFFFUL)); /* Resume the VM */ status = vmx_vmrun(cur_context, VM_RESUME, ibrs_type); } - /* Save guest CR3 register */ - cur_context->cr3 = exec_vmread(VMX_GUEST_CR3); + vcpu->reg_cached = 0UL; - /* Save guest IA32_EFER register */ - cur_context->ia32_efer = exec_vmread64(VMX_GUEST_IA32_EFER_FULL); set_vcpu_mode(vcpu, exec_vmread32(VMX_GUEST_CS_ATTR)); - /* Obtain current VCPU instruction pointer and length */ - cur_context->rip = exec_vmread(VMX_GUEST_RIP); + /* Obtain current VCPU instruction length */ vcpu->arch_vcpu.inst_len = exec_vmread32(VMX_EXIT_INSTR_LEN); cur_context->guest_cpu_regs.regs.rsp = exec_vmread(VMX_GUEST_RSP); - cur_context->rflags = exec_vmread(VMX_GUEST_RFLAGS); /* Obtain VM exit reason */ vcpu->arch_vcpu.exit_reason = exec_vmread32(VMX_EXIT_REASON); diff --git a/hypervisor/arch/x86/guest/vlapic.c b/hypervisor/arch/x86/guest/vlapic.c index 9280057ef..b8fa4109a 100644 --- a/hypervisor/arch/x86/guest/vlapic.c +++ b/hypervisor/arch/x86/guest/vlapic.c @@ -427,7 +427,7 @@ static void vlapic_set_tsc_deadline_msr(struct acrn_vlapic *vlapic, struct vcpu_arch *arch = &vlapic->vcpu->arch_vcpu; /* transfer guest tsc to host tsc */ - val -= arch->contexts[arch->cur_context].tsc_offset; + val -= exec_vmread64(VMX_TSC_OFFSET_FULL); timer->fire_tsc = val; add_timer(timer); diff --git a/hypervisor/arch/x86/guest/vmcall.c b/hypervisor/arch/x86/guest/vmcall.c index 5e30b2696..3e3a7c77b 100644 --- a/hypervisor/arch/x86/guest/vmcall.c +++ b/hypervisor/arch/x86/guest/vmcall.c @@ -16,14 +16,12 @@ int vmcall_vmexit_handler(struct vcpu *vcpu) { int32_t ret = -EACCES; struct vm *vm = vcpu->vm; - struct run_context *cur_context = - &vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context]; /* hypercall ID from guest*/ - uint64_t hypcall_id = cur_context->guest_cpu_regs.regs.r8; + uint64_t hypcall_id = vcpu_get_gpreg(vcpu, CPU_REG_R8); /* hypercall param1 from guest*/ - uint64_t param1 = cur_context->guest_cpu_regs.regs.rdi; + uint64_t param1 = vcpu_get_gpreg(vcpu, CPU_REG_RDI); /* hypercall param2 from guest*/ - uint64_t param2 = cur_context->guest_cpu_regs.regs.rsi; + uint64_t param2 = vcpu_get_gpreg(vcpu, CPU_REG_RSI); if (!is_hypercall_from_ring0()) { pr_err("hypercall is only allowed from RING-0!\n"); @@ -179,7 +177,7 @@ int vmcall_vmexit_handler(struct vcpu *vcpu) } out: - cur_context->guest_cpu_regs.regs.rax = (uint64_t)ret; + vcpu_set_gpreg(vcpu, CPU_REG_RAX, (uint64_t)ret); TRACE_2L(TRACE_VMEXIT_VMCALL, vm->vm_id, hypcall_id); diff --git a/hypervisor/arch/x86/guest/vmsr.c b/hypervisor/arch/x86/guest/vmsr.c index a332ba460..7fa156312 100644 --- a/hypervisor/arch/x86/guest/vmsr.c +++ b/hypervisor/arch/x86/guest/vmsr.c @@ -147,10 +147,9 @@ int rdmsr_vmexit_handler(struct vcpu *vcpu) int err = 0; uint32_t msr; uint64_t v = 0UL; - int cur_context = vcpu->arch_vcpu.cur_context; /* Read the msr value */ - msr = vcpu->arch_vcpu.contexts[cur_context].guest_cpu_regs.regs.rcx; + msr = vcpu_get_gpreg(vcpu, CPU_REG_RCX); /* Do the required processing for each msr case */ switch (msr) { @@ -162,7 +161,7 @@ int rdmsr_vmexit_handler(struct vcpu *vcpu) case MSR_IA32_TIME_STAMP_COUNTER: { /* Add the TSC_offset to host TSC to get guest TSC */ - v = rdtsc() + vcpu->arch_vcpu.contexts[cur_context].tsc_offset; + v = rdtsc() + exec_vmread64(VMX_TSC_OFFSET_FULL); break; } case MSR_IA32_MTRR_CAP: @@ -244,10 +243,8 @@ int rdmsr_vmexit_handler(struct vcpu *vcpu) } /* Store the MSR contents in RAX and RDX */ - vcpu->arch_vcpu.contexts[cur_context].guest_cpu_regs.regs.rax = - v & 0xffffffffU; - vcpu->arch_vcpu.contexts[cur_context].guest_cpu_regs.regs.rdx = - v >> 32U; + vcpu_set_gpreg(vcpu, CPU_REG_RAX, v & 0xffffffffU); + vcpu_set_gpreg(vcpu, CPU_REG_RDX, v >> 32U); TRACE_2L(TRACE_VMEXIT_RDMSR, msr, v); @@ -259,15 +256,13 @@ int wrmsr_vmexit_handler(struct vcpu *vcpu) int err = 0; uint32_t msr; uint64_t v; - struct run_context *cur_context = - &vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context]; /* Read the MSR ID */ - msr = (uint32_t)cur_context->guest_cpu_regs.regs.rcx; + msr = (uint32_t)vcpu_get_gpreg(vcpu, CPU_REG_RCX); /* Get the MSR contents */ - v = (cur_context->guest_cpu_regs.regs.rdx << 32U) | - cur_context->guest_cpu_regs.regs.rax; + v = (vcpu_get_gpreg(vcpu, CPU_REG_RDX) << 32U) | + vcpu_get_gpreg(vcpu, CPU_REG_RAX); /* Do the required processing for each msr case */ switch (msr) { @@ -279,8 +274,7 @@ int wrmsr_vmexit_handler(struct vcpu *vcpu) case MSR_IA32_TIME_STAMP_COUNTER: { /*Caculate TSC offset from changed TSC MSR value*/ - cur_context->tsc_offset = v - rdtsc(); - exec_vmwrite64(VMX_TSC_OFFSET_FULL, cur_context->tsc_offset); + exec_vmwrite64(VMX_TSC_OFFSET_FULL, v - rdtsc()); break; } diff --git a/hypervisor/arch/x86/io.c b/hypervisor/arch/x86/io.c index 7fe3a5870..f2535cd53 100644 --- a/hypervisor/arch/x86/io.c +++ b/hypervisor/arch/x86/io.c @@ -29,13 +29,10 @@ emulate_pio_post(struct vcpu *vcpu, struct io_request *io_req) if (pio_req->direction == REQUEST_READ) { uint64_t value = (uint64_t)pio_req->value; int32_t context_idx = vcpu->arch_vcpu.cur_context; - struct run_context *cur_context; - uint64_t *rax; + uint64_t rax = vcpu_get_gpreg(vcpu, CPU_REG_RAX); - cur_context = &vcpu->arch_vcpu.contexts[context_idx]; - rax = &cur_context->guest_cpu_regs.regs.rax; - - *rax = ((*rax) & ~mask) | (value & mask); + rax = ((rax) & ~mask) | (value & mask); + vcpu_set_gpreg(vcpu, CPU_REG_RAX, rax); } status = 0; } else { @@ -323,14 +320,10 @@ int32_t pio_instr_vmexit_handler(struct vcpu *vcpu) int32_t status; uint64_t exit_qual; int32_t cur_context_idx = vcpu->arch_vcpu.cur_context; - struct run_context *cur_context; - struct cpu_gp_regs *regs; struct io_request *io_req = &vcpu->req; struct pio_request *pio_req = &io_req->reqs.pio; exit_qual = vcpu->arch_vcpu.exit_qualification; - cur_context = &vcpu->arch_vcpu.contexts[cur_context_idx]; - regs = &cur_context->guest_cpu_regs.regs; io_req->type = REQ_PORTIO; io_req->processed = REQ_STATE_PENDING; @@ -338,7 +331,7 @@ int32_t pio_instr_vmexit_handler(struct vcpu *vcpu) pio_req->address = VM_EXIT_IO_INSTRUCTION_PORT_NUMBER(exit_qual); if (VM_EXIT_IO_INSTRUCTION_ACCESS_DIRECTION(exit_qual) == 0UL) { pio_req->direction = REQUEST_WRITE; - pio_req->value = (uint32_t)regs->rax; + pio_req->value = (uint32_t)vcpu_get_gpreg(vcpu, CPU_REG_RAX); } else { pio_req->direction = REQUEST_READ; } diff --git a/hypervisor/arch/x86/virq.c b/hypervisor/arch/x86/virq.c index 2f280b02e..bae90339f 100644 --- a/hypervisor/arch/x86/virq.c +++ b/hypervisor/arch/x86/virq.c @@ -52,13 +52,11 @@ static const uint16_t exception_type[32] = { static bool is_guest_irq_enabled(struct vcpu *vcpu) { - struct run_context *cur_context = - &vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context]; uint64_t guest_rflags, guest_state; bool status = false; /* Read the RFLAGS of the guest */ - guest_rflags = cur_context->rflags; + guest_rflags = vcpu_get_rflags(vcpu); /* Check the RFLAGS[IF] bit first */ if ((guest_rflags & HV_ARCH_VCPU_RFLAGS_IF) != 0UL) { /* Interrupts are allowed */ @@ -302,10 +300,7 @@ void vcpu_inject_gp(struct vcpu *vcpu, uint32_t err_code) void vcpu_inject_pf(struct vcpu *vcpu, uint64_t addr, uint32_t err_code) { - struct run_context *cur_context = - &vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context]; - - cur_context->cr2 = addr; + vcpu_set_cr2(vcpu, addr); vcpu_queue_exception(vcpu, IDT_PF, err_code); vcpu_make_request(vcpu, ACRN_REQUEST_EXCP); } diff --git a/hypervisor/arch/x86/vmexit.c b/hypervisor/arch/x86/vmexit.c index 54e4cd857..7f6eb4006 100644 --- a/hypervisor/arch/x86/vmexit.c +++ b/hypervisor/arch/x86/vmexit.c @@ -243,14 +243,18 @@ static int unhandled_vmexit_handler(struct vcpu *vcpu) int cpuid_vmexit_handler(struct vcpu *vcpu) { - struct run_context *cur_context = - &vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context]; + uint64_t rax, rbx, rcx, rdx; - guest_cpuid(vcpu, - (uint32_t *)&cur_context->guest_cpu_regs.regs.rax, - (uint32_t *)&cur_context->guest_cpu_regs.regs.rbx, - (uint32_t *)&cur_context->guest_cpu_regs.regs.rcx, - (uint32_t *)&cur_context->guest_cpu_regs.regs.rdx); + rax = vcpu_get_gpreg(vcpu, CPU_REG_RAX); + rbx = vcpu_get_gpreg(vcpu, CPU_REG_RBX); + rcx = vcpu_get_gpreg(vcpu, CPU_REG_RCX); + rdx = vcpu_get_gpreg(vcpu, CPU_REG_RDX); + guest_cpuid(vcpu, (uint32_t *)&rax, (uint32_t *)&rbx, + (uint32_t *)&rcx, (uint32_t *)&rdx); + vcpu_set_gpreg(vcpu, CPU_REG_RAX, rax); + vcpu_set_gpreg(vcpu, CPU_REG_RBX, rbx); + vcpu_set_gpreg(vcpu, CPU_REG_RCX, rcx); + vcpu_set_gpreg(vcpu, CPU_REG_RDX, rdx); TRACE_2L(TRACE_VMEXIT_CPUID, (uint64_t)vcpu->vcpu_id, 0UL); @@ -260,24 +264,22 @@ int cpuid_vmexit_handler(struct vcpu *vcpu) int cr_access_vmexit_handler(struct vcpu *vcpu) { int err = 0; - uint64_t *regptr; - struct run_context *cur_context = - &vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context]; + uint64_t reg; int idx = VM_EXIT_CR_ACCESS_REG_IDX(vcpu->arch_vcpu.exit_qualification); ASSERT(idx>=0 && idx<=15, "index out of range"); - regptr = cur_context->guest_cpu_regs.longs + idx; + reg = vcpu_get_gpreg(vcpu, idx); switch ((VM_EXIT_CR_ACCESS_ACCESS_TYPE (vcpu->arch_vcpu.exit_qualification) << 4) | VM_EXIT_CR_ACCESS_CR_NUM(vcpu->arch_vcpu.exit_qualification)) { case 0x00U: /* mov to cr0 */ - err = vmx_write_cr0(vcpu, *regptr); + err = vcpu_set_cr0(vcpu, reg); break; case 0x04U: /* mov to cr4 */ - err = vmx_write_cr4(vcpu, *regptr); + err = vcpu_set_cr4(vcpu, reg); break; case 0x08U: /* mov to cr8 */ @@ -285,16 +287,17 @@ int cr_access_vmexit_handler(struct vcpu *vcpu) * * set reserved bit in CR8 causes GP to guest */ - if (*regptr & ~0xFUL) { + if (reg & ~0xFUL) { pr_dbg("Invalid cr8 write operation from guest"); vcpu_inject_gp(vcpu, 0U); break; } - vlapic_set_cr8(vcpu->arch_vcpu.vlapic, *regptr); + vlapic_set_cr8(vcpu->arch_vcpu.vlapic, reg); break; case 0x18U: /* mov from cr8 */ - *regptr = vlapic_get_cr8(vcpu->arch_vcpu.vlapic); + reg = vlapic_get_cr8(vcpu->arch_vcpu.vlapic); + vcpu_set_gpreg(vcpu, idx, reg); break; default: panic("Unhandled CR access"); @@ -318,7 +321,6 @@ static int xsetbv_vmexit_handler(struct vcpu *vcpu) { int idx; uint64_t val64; - struct run_context *ctx_ptr; val64 = exec_vmread(VMX_GUEST_CR4); if ((val64 & CR4_OSXSAVE) == 0UL) { @@ -331,16 +333,14 @@ static int xsetbv_vmexit_handler(struct vcpu *vcpu) return -1; } - ctx_ptr = &(vcpu->arch_vcpu.contexts[idx]); - /*to access XCR0,'rcx' should be 0*/ - if (ctx_ptr->guest_cpu_regs.regs.rcx != 0UL) { + if (vcpu_get_gpreg(vcpu, CPU_REG_RCX) != 0UL) { vcpu_inject_gp(vcpu, 0U); return 0; } - val64 = ((ctx_ptr->guest_cpu_regs.regs.rax) & 0xffffffffUL) | - (ctx_ptr->guest_cpu_regs.regs.rdx << 32U); + val64 = (vcpu_get_gpreg(vcpu, CPU_REG_RAX) & 0xffffffffUL) | + (vcpu_get_gpreg(vcpu, CPU_REG_RDX) << 32U); /*bit 0(x87 state) of XCR0 can't be cleared*/ if ((val64 & 0x01UL) == 0UL) { diff --git a/hypervisor/arch/x86/vmx.c b/hypervisor/arch/x86/vmx.c index c10621a52..918537cc1 100644 --- a/hypervisor/arch/x86/vmx.c +++ b/hypervisor/arch/x86/vmx.c @@ -314,23 +314,18 @@ static void init_cr0_cr4_host_mask(__unused struct vcpu *vcpu) uint64_t vmx_rdmsr_pat(struct vcpu *vcpu) { - struct run_context *context = - &vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context]; - /* * note: if context->cr0.CD is set, the actual value in guest's * IA32_PAT MSR is PAT_ALL_UC_VALUE, which may be different from * the saved value context->ia32_pat */ - return context->ia32_pat; + return vcpu_get_pat_ext(vcpu); } int vmx_wrmsr_pat(struct vcpu *vcpu, uint64_t value) { uint32_t i; uint64_t field; - struct run_context *context = - &vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context]; for (i = 0U; i < 8U; i++) { field = (value >> (i * 8U)) & 0xffUL; @@ -342,23 +337,21 @@ int vmx_wrmsr_pat(struct vcpu *vcpu, uint64_t value) } } - context->ia32_pat = value; + vcpu_set_pat_ext(vcpu, value); /* * If context->cr0.CD is set, we defer any further requests to write * guest's IA32_PAT, until the time when guest's CR0.CD is being cleared */ - if ((context->cr0 & CR0_CD) == 0UL) { + if ((vcpu_get_cr0(vcpu) & CR0_CD) == 0UL) { exec_vmwrite64(VMX_GUEST_IA32_PAT_FULL, value); } + return 0; } static bool is_cr0_write_valid(struct vcpu *vcpu, uint64_t cr0) { - struct run_context *context = - &vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context]; - /* Shouldn't set always off bit */ if ((cr0 & cr0_always_off_mask) != 0UL) return false; @@ -370,8 +363,8 @@ static bool is_cr0_write_valid(struct vcpu *vcpu, uint64_t cr0) * CR0.PG = 1, CR4.PAE = 0 and IA32_EFER.LME = 1 is invalid. * CR0.PE = 0 and CR0.PG = 1 is invalid. */ - if (((cr0 & CR0_PG) != 0UL) && ((context->cr4 & CR4_PAE) == 0UL) && - ((context->ia32_efer & MSR_IA32_EFER_LME_BIT) != 0UL)) + if (((cr0 & CR0_PG) != 0UL) && ((vcpu_get_cr4(vcpu) & CR4_PAE) == 0UL) + && ((vcpu_get_efer(vcpu) & MSR_IA32_EFER_LME_BIT) != 0UL)) return false; if (((cr0 & CR0_PE) == 0UL) && ((cr0 & CR0_PG) != 0UL)) @@ -411,11 +404,9 @@ static bool is_cr0_write_valid(struct vcpu *vcpu, uint64_t cr0) */ int vmx_write_cr0(struct vcpu *vcpu, uint64_t cr0) { - struct run_context *context = - &vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context]; uint64_t cr0_vmx; uint32_t entry_ctrls; - bool paging_enabled = !!(context->cr0 & CR0_PG); + bool paging_enabled = !!(vcpu_get_cr0(vcpu) & CR0_PG); if (!is_cr0_write_valid(vcpu, cr0)) { pr_dbg("Invalid cr0 write operation from guest"); @@ -427,9 +418,10 @@ int vmx_write_cr0(struct vcpu *vcpu, uint64_t cr0) * When loading a control register, reserved bit should always set * to the value previously read. */ - cr0 = (cr0 & ~CR0_RESERVED_MASK) | (context->cr0 & CR0_RESERVED_MASK); + cr0 = (cr0 & ~CR0_RESERVED_MASK) | + (vcpu_get_cr0(vcpu) & CR0_RESERVED_MASK); - if (((context->ia32_efer & MSR_IA32_EFER_LME_BIT) != 0UL) && + if (((vcpu_get_efer(vcpu) & MSR_IA32_EFER_LME_BIT) != 0UL) && !paging_enabled && ((cr0 & CR0_PG) != 0UL)) { /* Enable long mode */ pr_dbg("VMM: Enable long mode"); @@ -437,9 +429,9 @@ int vmx_write_cr0(struct vcpu *vcpu, uint64_t cr0) entry_ctrls |= VMX_ENTRY_CTLS_IA32E_MODE; exec_vmwrite32(VMX_ENTRY_CONTROLS, entry_ctrls); - context->ia32_efer |= MSR_IA32_EFER_LMA_BIT; - exec_vmwrite64(VMX_GUEST_IA32_EFER_FULL, context->ia32_efer); - } else if (((context->ia32_efer & MSR_IA32_EFER_LME_BIT) != 0UL) && + vcpu_set_efer(vcpu, + vcpu_get_efer(vcpu) | MSR_IA32_EFER_LMA_BIT); + } else if (((vcpu_get_efer(vcpu) & MSR_IA32_EFER_LME_BIT) != 0UL) && paging_enabled && ((cr0 & CR0_PG) == 0UL)){ /* Disable long mode */ pr_dbg("VMM: Disable long mode"); @@ -447,16 +439,16 @@ int vmx_write_cr0(struct vcpu *vcpu, uint64_t cr0) entry_ctrls &= ~VMX_ENTRY_CTLS_IA32E_MODE; exec_vmwrite32(VMX_ENTRY_CONTROLS, entry_ctrls); - context->ia32_efer &= ~MSR_IA32_EFER_LMA_BIT; - exec_vmwrite64(VMX_GUEST_IA32_EFER_FULL, context->ia32_efer); + vcpu_set_efer(vcpu, + vcpu_get_efer(vcpu) & ~MSR_IA32_EFER_LMA_BIT); } else { /* CR0.PG unchanged. */ } /* If CR0.CD or CR0.NW get changed */ - if (((context->cr0 ^ cr0) & (CR0_CD | CR0_NW)) != 0UL) { + if (((vcpu_get_cr0(vcpu) ^ cr0) & (CR0_CD | CR0_NW)) != 0UL) { /* No action if only CR0.NW is changed */ - if (((context->cr0 ^ cr0) & CR0_CD) != 0UL) { + if (((vcpu_get_cr0(vcpu) ^ cr0) & CR0_CD) != 0UL) { if ((cr0 & CR0_CD) != 0UL) { /* * When the guest requests to set CR0.CD, we don't allow @@ -468,7 +460,8 @@ int vmx_write_cr0(struct vcpu *vcpu, uint64_t cr0) CACHE_FLUSH_INVALIDATE_ALL(); } else { /* Restore IA32_PAT to enable cache again */ - exec_vmwrite64(VMX_GUEST_IA32_PAT_FULL, context->ia32_pat); + exec_vmwrite64(VMX_GUEST_IA32_PAT_FULL, + vcpu_get_pat_ext(vcpu)); } vcpu_make_request(vcpu, ACRN_REQUEST_EPT_FLUSH); } @@ -483,7 +476,9 @@ int vmx_write_cr0(struct vcpu *vcpu, uint64_t cr0) cr0_vmx &= ~(CR0_CD | CR0_NW); exec_vmwrite(VMX_GUEST_CR0, cr0_vmx & 0xFFFFFFFFUL); exec_vmwrite(VMX_CR0_READ_SHADOW, cr0 & 0xFFFFFFFFUL); - context->cr0 = cr0; + + /* clear read cache, next time read should from VMCS */ + bitmap_clear_lock(CPU_REG_CR0, &vcpu->reg_cached); pr_dbg("VMM: Try to write %016llx, allow to write 0x%016llx to CR0", cr0, cr0_vmx); @@ -491,19 +486,6 @@ int vmx_write_cr0(struct vcpu *vcpu, uint64_t cr0) return 0; } -int vmx_write_cr3(struct vcpu *vcpu, uint64_t cr3) -{ - struct run_context *context = - &vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context]; - /* Write to guest's CR3 */ - context->cr3 = cr3; - - /* Commit new value to VMCS */ - exec_vmwrite(VMX_GUEST_CR3, cr3); - - return 0; -} - static bool is_cr4_write_valid(struct vcpu *vcpu, uint64_t cr4) { /* Check if guest try to set fixed to 0 bits or reserved bits */ @@ -558,8 +540,6 @@ static bool is_cr4_write_valid(struct vcpu *vcpu, uint64_t cr4) */ int vmx_write_cr4(struct vcpu *vcpu, uint64_t cr4) { - struct run_context *context = - &vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context]; uint64_t cr4_vmx; if (!is_cr4_write_valid(vcpu, cr4)) { @@ -572,7 +552,9 @@ int vmx_write_cr4(struct vcpu *vcpu, uint64_t cr4) cr4_vmx = cr4_always_on_mask | cr4; exec_vmwrite(VMX_GUEST_CR4, cr4_vmx & 0xFFFFFFFFUL); exec_vmwrite(VMX_CR4_READ_SHADOW, cr4 & 0xFFFFFFFFUL); - context->cr4 = cr4; + + /* clear read cache, next time read should from VMCS */ + bitmap_clear_lock(CPU_REG_CR4, &vcpu->reg_cached); pr_dbg("VMM: Try to write %016llx, allow to write 0x%016llx to CR4", cr4, cr4_vmx); @@ -583,7 +565,6 @@ int vmx_write_cr4(struct vcpu *vcpu, uint64_t cr4) static void init_guest_state(struct vcpu *vcpu) { uint32_t field; - uint64_t value; uint16_t value16; uint32_t value32; uint64_t value64; @@ -594,8 +575,6 @@ static void init_guest_state(struct vcpu *vcpu) uint16_t es = 0U, ss = 0U, ds = 0U, fs = 0U, gs = 0U, data32_idx; uint16_t tr_sel = 0x70U; struct vm *vm = vcpu->vm; - struct run_context *cur_context = - &vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context]; enum vm_cpu_mode vcpu_mode = get_vcpu_mode(vcpu); pr_dbg("*********************"); @@ -613,7 +592,7 @@ static void init_guest_state(struct vcpu *vcpu) pr_dbg("Natural-width********"); if (vcpu_mode == CPU_MODE_64BIT) { - cur_context->ia32_efer = MSR_IA32_EFER_LME_BIT; + vcpu_set_efer(vcpu, MSR_IA32_EFER_LME_BIT); } /* Setup guest control register values @@ -621,17 +600,18 @@ static void init_guest_state(struct vcpu *vcpu) * checked. */ if (vcpu_mode == CPU_MODE_REAL) { - vmx_write_cr4(vcpu, 0UL); - vmx_write_cr3(vcpu, 0UL); - vmx_write_cr0(vcpu, CR0_ET | CR0_NE); + vcpu_set_cr4(vcpu, 0UL); + exec_vmwrite(VMX_GUEST_CR3, 0UL); + vcpu_set_cr0(vcpu, CR0_ET | CR0_NE); } else if (vcpu_mode == CPU_MODE_PROTECTED) { - vmx_write_cr4(vcpu, 0UL); - vmx_write_cr3(vcpu, 0UL); - vmx_write_cr0(vcpu, CR0_ET | CR0_NE | CR0_PE); + vcpu_set_cr4(vcpu, 0UL); + exec_vmwrite(VMX_GUEST_CR3, 0UL); + vcpu_set_cr0(vcpu, CR0_ET | CR0_NE | CR0_PE); } else if (vcpu_mode == CPU_MODE_64BIT) { - vmx_write_cr4(vcpu, CR4_PSE | CR4_PAE | CR4_MCE); - vmx_write_cr3(vcpu, vm->arch_vm.guest_init_pml4 | CR3_PWT); - vmx_write_cr0(vcpu, CR0_PG | CR0_PE | CR0_NE); + vcpu_set_cr4(vcpu, CR4_PSE | CR4_PAE | CR4_MCE); + exec_vmwrite(VMX_GUEST_CR3, + vm->arch_vm.guest_init_pml4 | CR3_PWT); + vcpu_set_cr0(vcpu, CR0_PG | CR0_PE | CR0_NE); } else { /* vcpu_mode will never be CPU_MODE_COMPATIBILITY */ } @@ -639,10 +619,8 @@ static void init_guest_state(struct vcpu *vcpu) /***************************************************/ /* Set up Flags - the value of RFLAGS on VM entry */ /***************************************************/ - field = VMX_GUEST_RFLAGS; - cur_context->rflags = 0x2UL; /* Bit 1 is a active high reserved bit */ - exec_vmwrite(field, cur_context->rflags); - pr_dbg("VMX_GUEST_RFLAGS: 0x%016llx ", cur_context->rflags); + vcpu_set_rflags(vcpu, 0x2UL); /* Bit 1 is a active high reserved bit */ + pr_dbg("VMX_GUEST_RFLAGS: 0x%016llx ", vcpu_get_rflags(vcpu)); /***************************************************/ /* Set Code Segment - CS */ @@ -1023,10 +1001,9 @@ static void init_guest_state(struct vcpu *vcpu) value32); value64 = PAT_POWER_ON_VALUE; - cur_context->ia32_pat = value64; exec_vmwrite64(VMX_GUEST_IA32_PAT_FULL, value64); - pr_dbg("VMX_GUEST_IA32_PAT: 0x%016llx ", - value64); + pr_dbg("VMX_GUEST_IA32_PAT: 0x%016llx ", value64); + vcpu_set_pat_ext(vcpu, value64); value64 = 0UL; exec_vmwrite64(VMX_GUEST_IA32_DEBUGCTL_FULL, value64); @@ -1561,17 +1538,15 @@ static void init_exit_ctrl(__unused struct vcpu *vcpu) static void override_uefi_vmcs(struct vcpu *vcpu) { uint32_t field; - struct run_context *cur_context = - &vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context]; if (get_vcpu_mode(vcpu) == CPU_MODE_64BIT) { /* CR4 should be set before CR0, because when set CR0, CR4 value * will be checked. */ /* VMXE is always on bit when set CR4, and not allowed to be set * from input cr4 value */ - vmx_write_cr4(vcpu, efi_ctx->cr4 & ~CR4_VMXE); - vmx_write_cr3(vcpu, efi_ctx->cr3); - vmx_write_cr0(vcpu, efi_ctx->cr0 | CR0_PG | CR0_PE | CR0_NE); + vcpu_set_cr4(vcpu, efi_ctx->cr4 & ~CR4_VMXE); + exec_vmwrite(VMX_GUEST_CR3, efi_ctx->cr3); + vcpu_set_cr0(vcpu, efi_ctx->cr0 | CR0_PG | CR0_PE | CR0_NE); /* Selector */ field = VMX_GUEST_CS_SEL; @@ -1642,11 +1617,9 @@ static void override_uefi_vmcs(struct vcpu *vcpu) } /* Interrupt */ - field = VMX_GUEST_RFLAGS; /* clear flags for CF/PF/AF/ZF/SF/OF */ - cur_context->rflags = efi_ctx->rflags & ~(0x8d5UL); - exec_vmwrite(field, cur_context->rflags); - pr_dbg("VMX_GUEST_RFLAGS: 0x%016llx ", cur_context->rflags); + vcpu_set_rflags(vcpu, efi_ctx->rflags & ~(0x8d5UL)); + pr_dbg("VMX_GUEST_RFLAGS: 0x%016llx ", vcpu_get_rflags(vcpu)); } #endif diff --git a/hypervisor/bsp/uefi/uefi.c b/hypervisor/bsp/uefi/uefi.c index e48797f73..620c0d774 100644 --- a/hypervisor/bsp/uefi/uefi.c +++ b/hypervisor/bsp/uefi/uefi.c @@ -54,8 +54,6 @@ void efi_spurious_handler(int vector) int uefi_sw_loader(struct vm *vm, struct vcpu *vcpu) { int ret = 0; - struct run_context *cur_context = - &vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context]; ASSERT(vm != NULL, "Incorrect argument"); @@ -67,21 +65,21 @@ int uefi_sw_loader(struct vm *vm, struct vcpu *vcpu) vlapic_restore(vcpu->arch_vcpu.vlapic, &uefi_lapic_regs); vcpu->entry_addr = (void *)efi_ctx->rip; - cur_context->guest_cpu_regs.regs.rax = efi_ctx->rax; - cur_context->guest_cpu_regs.regs.rbx = efi_ctx->rbx; - cur_context->guest_cpu_regs.regs.rdx = efi_ctx->rcx; - cur_context->guest_cpu_regs.regs.rcx = efi_ctx->rdx; - cur_context->guest_cpu_regs.regs.rdi = efi_ctx->rdi; - cur_context->guest_cpu_regs.regs.rsi = efi_ctx->rsi; - cur_context->guest_cpu_regs.regs.rbp = efi_ctx->rbp; - cur_context->guest_cpu_regs.regs.r8 = efi_ctx->r8; - cur_context->guest_cpu_regs.regs.r9 = efi_ctx->r9; - cur_context->guest_cpu_regs.regs.r10 = efi_ctx->r10; - cur_context->guest_cpu_regs.regs.r11 = efi_ctx->r11; - cur_context->guest_cpu_regs.regs.r12 = efi_ctx->r12; - cur_context->guest_cpu_regs.regs.r13 = efi_ctx->r13; - cur_context->guest_cpu_regs.regs.r14 = efi_ctx->r14; - cur_context->guest_cpu_regs.regs.r15 = efi_ctx->r15; + vcpu_set_gpreg(vcpu, CPU_REG_RAX, efi_ctx->rax); + vcpu_set_gpreg(vcpu, CPU_REG_RBX, efi_ctx->rbx); + vcpu_set_gpreg(vcpu, CPU_REG_RCX, efi_ctx->rcx); + vcpu_set_gpreg(vcpu, CPU_REG_RDX, efi_ctx->rdx); + vcpu_set_gpreg(vcpu, CPU_REG_RDI, efi_ctx->rdi); + vcpu_set_gpreg(vcpu, CPU_REG_RSI, efi_ctx->rsi); + vcpu_set_gpreg(vcpu, CPU_REG_RBP, efi_ctx->rbp); + vcpu_set_gpreg(vcpu, CPU_REG_R8, efi_ctx->r8); + vcpu_set_gpreg(vcpu, CPU_REG_R9, efi_ctx->r9); + vcpu_set_gpreg(vcpu, CPU_REG_R10, efi_ctx->r10); + vcpu_set_gpreg(vcpu, CPU_REG_R11, efi_ctx->r11); + vcpu_set_gpreg(vcpu, CPU_REG_R12, efi_ctx->r12); + vcpu_set_gpreg(vcpu, CPU_REG_R13, efi_ctx->r13); + vcpu_set_gpreg(vcpu, CPU_REG_R14, efi_ctx->r14); + vcpu_set_gpreg(vcpu, CPU_REG_R15, efi_ctx->r15); /* defer irq enabling till vlapic is ready */ CPU_IRQ_ENABLE(); diff --git a/hypervisor/common/hv_main.c b/hypervisor/common/hv_main.c index 6d9b0b61e..fa81f9a22 100644 --- a/hypervisor/common/hv_main.c +++ b/hypervisor/common/hv_main.c @@ -102,8 +102,7 @@ void vcpu_thread(struct vcpu *vcpu) basic_exit_reason = vcpu->arch_vcpu.exit_reason & 0xFFFFU; per_cpu(vmexit_cnt, vcpu->pcpu_id)[basic_exit_reason]++; - TRACE_2L(TRACE_VM_EXIT, basic_exit_reason, - vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context].rip); + TRACE_2L(TRACE_VM_EXIT, basic_exit_reason, vcpu_get_rip(vcpu)); } while (1); } diff --git a/hypervisor/common/vm_load.c b/hypervisor/common/vm_load.c index 15e7c600f..e4c52b4cb 100644 --- a/hypervisor/common/vm_load.c +++ b/hypervisor/common/vm_load.c @@ -73,29 +73,27 @@ static uint64_t create_zero_page(struct vm *vm) int load_guest(struct vm *vm, struct vcpu *vcpu) { int32_t ret = 0; + uint32_t i; void *hva; - struct run_context *cur_context = - &vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context]; uint64_t lowmem_gpa_top; hva = GPA2HVA(vm, GUEST_CFG_OFFSET); lowmem_gpa_top = *(uint64_t *)hva; /* hardcode vcpu entry addr(kernel entry) & rsi (zeropage)*/ - (void)memset((void*)cur_context->guest_cpu_regs.longs, - 0U, sizeof(uint64_t)*NUM_GPRS); + for (i = 0; i < NUM_GPRS; i++) + vcpu_set_gpreg(vcpu, i, 0UL); hva = GPA2HVA(vm, lowmem_gpa_top - MEM_4K - MEM_2K); vcpu->entry_addr = (void *)(*((uint64_t *)hva)); - cur_context->guest_cpu_regs.regs.rsi = - lowmem_gpa_top - MEM_4K; + vcpu_set_gpreg(vcpu, CPU_REG_RSI, lowmem_gpa_top - MEM_4K); pr_info("%s, Set config according to predefined offset:", __func__); pr_info("VCPU%hu Entry: 0x%llx, RSI: 0x%016llx, cr3: 0x%016llx", vcpu->vcpu_id, vcpu->entry_addr, - cur_context->guest_cpu_regs.regs.rsi, + vcpu_get_gpreg(vcpu, CPU_REG_RSI), vm->arch_vm.guest_init_pml4); return ret; @@ -105,8 +103,6 @@ int general_sw_loader(struct vm *vm, struct vcpu *vcpu) { int32_t ret = 0; void *hva; - struct run_context *cur_context = - &vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context]; char dyn_bootargs[100] = {0}; uint32_t kernel_entry_offset; struct zero_page *zeropage; @@ -150,11 +146,13 @@ int general_sw_loader(struct vm *vm, struct vcpu *vcpu) /* See if guest is a Linux guest */ if (vm->sw.kernel_type == VM_LINUX_GUEST) { + uint32_t i; + /* Documentation states: ebx=0, edi=0, ebp=0, esi=ptr to * zeropage */ - (void)memset(cur_context->guest_cpu_regs.longs, - 0U, sizeof(uint64_t) * NUM_GPRS); + for (i = 0; i < NUM_GPRS; i++) + vcpu_set_gpreg(vcpu, i, 0UL); /* Get host-physical address for guest bootargs */ hva = GPA2HVA(vm, @@ -217,11 +215,11 @@ int general_sw_loader(struct vm *vm, struct vcpu *vcpu) /* Create Zeropage and copy Physical Base Address of Zeropage * in RSI */ - cur_context->guest_cpu_regs.regs.rsi = create_zero_page(vm); + vcpu_set_gpreg(vcpu, CPU_REG_RSI, create_zero_page(vm)); pr_info("%s, RSI pointing to zero page for VM %d at GPA %X", __func__, vm->vm_id, - cur_context->guest_cpu_regs.regs.rsi); + vcpu_get_gpreg(vcpu, CPU_REG_RSI)); } else { pr_err("%s, Loading VM SW failed", __func__); diff --git a/hypervisor/debug/dump.c b/hypervisor/debug/dump.c index 6911b99f7..71d47b7f4 100644 --- a/hypervisor/debug/dump.c +++ b/hypervisor/debug/dump.c @@ -49,9 +49,6 @@ struct intr_excp_ctx *crash_ctx; static void dump_guest_reg(struct vcpu *vcpu) { - struct run_context *cur_context = - &vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context]; - printf("\n\n================================================"); printf("================================\n\n"); printf("Guest Registers:\r\n"); @@ -61,39 +58,39 @@ static void dump_guest_reg(struct vcpu *vcpu) vcpu->arch_vcpu.cur_context); printf("= RIP=0x%016llx RSP=0x%016llx " "RFLAGS=0x%016llx\r\n", - cur_context->rip, - cur_context->guest_cpu_regs.regs.rsp, - cur_context->rflags); + vcpu_get_rip(vcpu), + vcpu_get_gpreg(vcpu, CPU_REG_RSP), + vcpu_get_rflags(vcpu)); printf("= CR0=0x%016llx CR2=0x%016llx " " CR3=0x%016llx\r\n", - cur_context->cr0, - cur_context->cr2, - cur_context->cr3); + vcpu_get_cr0(vcpu), + vcpu_get_cr2(vcpu), + exec_vmread(VMX_GUEST_CR3)); printf("= RAX=0x%016llx RBX=0x%016llx " "RCX=0x%016llx\r\n", - cur_context->guest_cpu_regs.regs.rax, - cur_context->guest_cpu_regs.regs.rbx, - cur_context->guest_cpu_regs.regs.rcx); + vcpu_get_gpreg(vcpu, CPU_REG_RAX), + vcpu_get_gpreg(vcpu, CPU_REG_RBX), + vcpu_get_gpreg(vcpu, CPU_REG_RCX)); printf("= RDX=0x%016llx RDI=0x%016llx " "RSI=0x%016llx\r\n", - cur_context->guest_cpu_regs.regs.rdx, - cur_context->guest_cpu_regs.regs.rdi, - cur_context->guest_cpu_regs.regs.rsi); + vcpu_get_gpreg(vcpu, CPU_REG_RDX), + vcpu_get_gpreg(vcpu, CPU_REG_RDI), + vcpu_get_gpreg(vcpu, CPU_REG_RSI)); printf("= RBP=0x%016llx R8=0x%016llx " "R9=0x%016llx\r\n", - cur_context->guest_cpu_regs.regs.rbp, - cur_context->guest_cpu_regs.regs.r8, - cur_context->guest_cpu_regs.regs.r9); + vcpu_get_gpreg(vcpu, CPU_REG_RBP), + vcpu_get_gpreg(vcpu, CPU_REG_R8), + vcpu_get_gpreg(vcpu, CPU_REG_R9)); printf("= R10=0x%016llx R11=0x%016llx " "R12=0x%016llx\r\n", - cur_context->guest_cpu_regs.regs.r10, - cur_context->guest_cpu_regs.regs.r11, - cur_context->guest_cpu_regs.regs.r12); + vcpu_get_gpreg(vcpu, CPU_REG_R10), + vcpu_get_gpreg(vcpu, CPU_REG_R11), + vcpu_get_gpreg(vcpu, CPU_REG_R12)); printf("= R13=0x%016llx R14=0x%016llx " "R15=0x%016llx\r\n", - cur_context->guest_cpu_regs.regs.r13, - cur_context->guest_cpu_regs.regs.r14, - cur_context->guest_cpu_regs.regs.r15); + vcpu_get_gpreg(vcpu, CPU_REG_R13), + vcpu_get_gpreg(vcpu, CPU_REG_R14), + vcpu_get_gpreg(vcpu, CPU_REG_R15)); printf("\r\n"); } @@ -101,11 +98,9 @@ static void dump_guest_stack(struct vcpu *vcpu) { uint32_t i; uint64_t tmp[DUMP_STACK_SIZE]; - struct run_context *cur_context = - &vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context]; uint32_t err_code = 0; - if (copy_from_gva(vcpu, tmp, cur_context->guest_cpu_regs.regs.rsp, + if (copy_from_gva(vcpu, tmp, vcpu_get_gpreg(vcpu, CPU_REG_RSP), DUMP_STACK_SIZE, &err_code) < 0) { printf("\r\nUnabled to Copy Guest Stack:\r\n"); return; @@ -113,11 +108,11 @@ static void dump_guest_stack(struct vcpu *vcpu) printf("\r\nGuest Stack:\r\n"); printf("Dump stack for vcpu %hu, from gva 0x%016llx\r\n", - vcpu->vcpu_id, cur_context->guest_cpu_regs.regs.rsp); + vcpu->vcpu_id, vcpu_get_gpreg(vcpu, CPU_REG_RSP)); for (i = 0U; i < (DUMP_STACK_SIZE/32U); i++) { printf("guest_rsp(0x%llx): 0x%016llx 0x%016llx " "0x%016llx 0x%016llx\r\n", - (cur_context->guest_cpu_regs.regs.rsp+(i*32)), + (vcpu_get_gpreg(vcpu, CPU_REG_RSP)+(i*32)), tmp[i*4], tmp[(i*4)+1], tmp[(i*4)+2], tmp[(i*4)+3]); } @@ -128,12 +123,10 @@ static void show_guest_call_trace(struct vcpu *vcpu) { uint64_t bp; uint64_t count = 0UL; - struct run_context *cur_context = - &vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context]; int err; uint32_t err_code; - bp = cur_context->guest_cpu_regs.regs.rbp; + bp = vcpu_get_gpreg(vcpu, CPU_REG_RBP); printf("Guest Call Trace: **************************************\r\n"); printf("Maybe the call trace is not accurate, pls check stack!!\r\n"); /* if enable compiler option(no-omit-frame-pointer) the stack layout diff --git a/hypervisor/debug/shell.c b/hypervisor/debug/shell.c index cc19b3d9f..4ab77df7b 100644 --- a/hypervisor/debug/shell.c +++ b/hypervisor/debug/shell.c @@ -588,7 +588,6 @@ int shell_vcpu_dumpreg(int argc, char **argv) struct vcpu *vcpu; uint64_t i; uint64_t tmp[DUMPREG_SP_SIZE]; - struct run_context *cur_context; uint32_t err_code = 0; /* User input invalidation */ @@ -618,8 +617,6 @@ int shell_vcpu_dumpreg(int argc, char **argv) return -EINVAL; } - cur_context = &vcpu->arch_vcpu.contexts[vcpu->arch_vcpu.cur_context]; - if (vcpu->state != VCPU_PAUSED) { shell_puts("NOTE: VCPU unPAUSEed, regdump " "may not be accurate\r\n"); @@ -630,48 +627,49 @@ int shell_vcpu_dumpreg(int argc, char **argv) vm->vm_id, vcpu->vcpu_id); shell_puts(temp_str); snprintf(temp_str, MAX_STR_SIZE, "= RIP=0x%016llx RSP=0x%016llx " - "RFLAGS=0x%016llx\r\n", cur_context->rip, - cur_context->guest_cpu_regs.regs.rsp, cur_context->rflags); + "RFLAGS=0x%016llx\r\n", vcpu_get_rip(vcpu), + vcpu_get_gpreg(vcpu, CPU_REG_RSP), + vcpu_get_rflags(vcpu)); shell_puts(temp_str); snprintf(temp_str, MAX_STR_SIZE, "= CR0=0x%016llx CR2=0x%016llx\r\n", - cur_context->cr0, cur_context->cr2); + vcpu_get_cr0(vcpu), vcpu_get_cr2(vcpu)); shell_puts(temp_str); snprintf(temp_str, MAX_STR_SIZE, "= CR3=0x%016llx CR4=0x%016llx\r\n", - cur_context->cr3, cur_context->cr4); + exec_vmread(VMX_GUEST_CR3), vcpu_get_cr4(vcpu)); shell_puts(temp_str); snprintf(temp_str, MAX_STR_SIZE, "= RAX=0x%016llx RBX=0x%016llx " "RCX=0x%016llx\r\n", - cur_context->guest_cpu_regs.regs.rax, - cur_context->guest_cpu_regs.regs.rbx, - cur_context->guest_cpu_regs.regs.rcx); + vcpu_get_gpreg(vcpu, CPU_REG_RAX), + vcpu_get_gpreg(vcpu, CPU_REG_RBX), + vcpu_get_gpreg(vcpu, CPU_REG_RCX)); shell_puts(temp_str); snprintf(temp_str, MAX_STR_SIZE, "= RDX=0x%016llx RDI=0x%016llx " "RSI=0x%016llx\r\n", - cur_context->guest_cpu_regs.regs.rdx, - cur_context->guest_cpu_regs.regs.rdi, - cur_context->guest_cpu_regs.regs.rsi); + vcpu_get_gpreg(vcpu, CPU_REG_RDX), + vcpu_get_gpreg(vcpu, CPU_REG_RDI), + vcpu_get_gpreg(vcpu, CPU_REG_RSI)); shell_puts(temp_str); snprintf(temp_str, MAX_STR_SIZE, "= RBP=0x%016llx R8=0x%016llx " "R9=0x%016llx\r\n", - cur_context->guest_cpu_regs.regs.rbp, - cur_context->guest_cpu_regs.regs.r8, - cur_context->guest_cpu_regs.regs.r9); + vcpu_get_gpreg(vcpu, CPU_REG_RBP), + vcpu_get_gpreg(vcpu, CPU_REG_R8), + vcpu_get_gpreg(vcpu, CPU_REG_R9)); shell_puts(temp_str); snprintf(temp_str, MAX_STR_SIZE, "= R10=0x%016llx R11=0x%016llx " "R12=0x%016llx\r\n", - cur_context->guest_cpu_regs.regs.r10, - cur_context->guest_cpu_regs.regs.r11, - cur_context->guest_cpu_regs.regs.r12); + vcpu_get_gpreg(vcpu, CPU_REG_R10), + vcpu_get_gpreg(vcpu, CPU_REG_R11), + vcpu_get_gpreg(vcpu, CPU_REG_R12)); shell_puts(temp_str); snprintf(temp_str, MAX_STR_SIZE, "= R13=0x%016llx R14=0x%016llx R15=0x%016llx\r\n", - cur_context->guest_cpu_regs.regs.r13, - cur_context->guest_cpu_regs.regs.r14, - cur_context->guest_cpu_regs.regs.r15); + vcpu_get_gpreg(vcpu, CPU_REG_R13), + vcpu_get_gpreg(vcpu, CPU_REG_R14), + vcpu_get_gpreg(vcpu, CPU_REG_R15)); shell_puts(temp_str); /* dump sp */ - status = copy_from_gva(vcpu, tmp, cur_context->guest_cpu_regs.regs.rsp, + status = copy_from_gva(vcpu, tmp, vcpu_get_gpreg(vcpu, CPU_REG_RSP), DUMPREG_SP_SIZE*sizeof(uint64_t), &err_code); if (status < 0) { /* copy_from_gva fail */ @@ -680,7 +678,7 @@ int shell_vcpu_dumpreg(int argc, char **argv) snprintf(temp_str, MAX_STR_SIZE, "\r\nDump RSP for vm %hu, from " "gva 0x%016llx\r\n", - vm_id, cur_context->guest_cpu_regs.regs.rsp); + vm_id, vcpu_get_gpreg(vcpu, CPU_REG_RSP)); shell_puts(temp_str); for (i = 0UL; i < 8UL; i++) { diff --git a/hypervisor/include/arch/x86/cpu.h b/hypervisor/include/arch/x86/cpu.h index 72da16b44..b62f527aa 100644 --- a/hypervisor/include/arch/x86/cpu.h +++ b/hypervisor/include/arch/x86/cpu.h @@ -152,6 +152,65 @@ #ifndef ASSEMBLER +/** + * + * Identifiers for architecturally defined registers. + * + * These register names is used in condition statement. + * Within the following groups,register name need to be + * kept in order: + * General register names group (CPU_REG_RAX~CPU_REG_R15); + * Non general register names group (CPU_REG_CR0~CPU_REG_GDTR); + * Segement register names group (CPU_REG_ES~CPU_REG_GS). + */ +enum cpu_reg_name { + /* General purpose register layout should align with + * struct cpu_gp_regs + */ + CPU_REG_RAX, + CPU_REG_RCX, + CPU_REG_RDX, + CPU_REG_RBX, + CPU_REG_RSP, + CPU_REG_RBP, + CPU_REG_RSI, + CPU_REG_RDI, + CPU_REG_R8, + CPU_REG_R9, + CPU_REG_R10, + CPU_REG_R11, + CPU_REG_R12, + CPU_REG_R13, + CPU_REG_R14, + CPU_REG_R15, + + CPU_REG_CR0, + CPU_REG_CR2, + CPU_REG_CR3, + CPU_REG_CR4, + CPU_REG_DR7, + CPU_REG_RIP, + CPU_REG_RFLAGS, + /*CPU_REG_NATURAL_LAST*/ + CPU_REG_EFER, + CPU_REG_PDPTE0, + CPU_REG_PDPTE1, + CPU_REG_PDPTE2, + CPU_REG_PDPTE3, + /*CPU_REG_64BIT_LAST,*/ + CPU_REG_ES, + CPU_REG_CS, + CPU_REG_SS, + CPU_REG_DS, + CPU_REG_FS, + CPU_REG_GS, + CPU_REG_LDTR, + CPU_REG_TR, + CPU_REG_IDTR, + CPU_REG_GDTR + /*CPU_REG_LAST*/ +}; + /**********************************/ /* EXTERNAL VARIABLES */ /**********************************/ diff --git a/hypervisor/include/arch/x86/guest/vcpu.h b/hypervisor/include/arch/x86/guest/vcpu.h index 27caec306..530724cee 100644 --- a/hypervisor/include/arch/x86/guest/vcpu.h +++ b/hypervisor/include/arch/x86/guest/vcpu.h @@ -263,6 +263,8 @@ struct vcpu { #ifdef CONFIG_MTRR_ENABLED struct mtrr_state mtrr; #endif + uint64_t reg_cached; + uint64_t reg_updated; }; #define is_vcpu_bsp(vcpu) ((vcpu)->vcpu_id == BOOT_CPU_ID) @@ -273,6 +275,25 @@ static inline void vcpu_retain_rip(struct vcpu *vcpu) } /* External Interfaces */ +uint64_t vcpu_get_gpreg(struct vcpu *vcpu, uint32_t reg); +void vcpu_set_gpreg(struct vcpu *vcpu, uint32_t reg, uint64_t val); +uint64_t vcpu_get_rip(struct vcpu *vcpu); +void vcpu_set_rip(struct vcpu *vcpu, uint64_t val); +uint64_t vcpu_get_rsp(struct vcpu *vcpu); +void vcpu_set_rsp(struct vcpu *vcpu, uint64_t val); +uint64_t vcpu_get_efer(struct vcpu *vcpu); +void vcpu_set_efer(struct vcpu *vcpu, uint64_t val); +uint64_t vcpu_get_rflags(struct vcpu *vcpu); +void vcpu_set_rflags(struct vcpu *vcpu, uint64_t val); +uint64_t vcpu_get_cr0(struct vcpu *vcpu); +int vcpu_set_cr0(struct vcpu *vcpu, uint64_t val); +uint64_t vcpu_get_cr2(struct vcpu *vcpu); +void vcpu_set_cr2(struct vcpu *vcpu, uint64_t val); +uint64_t vcpu_get_cr4(struct vcpu *vcpu); +int vcpu_set_cr4(struct vcpu *vcpu, uint64_t val); +uint64_t vcpu_get_pat_ext(struct vcpu *vcpu); +void vcpu_set_pat_ext(struct vcpu *vcpu, uint64_t val); + struct vcpu* get_ever_run_vcpu(uint16_t pcpu_id); int create_vcpu(uint16_t pcpu_id, struct vm *vm, struct vcpu **rtn_vcpu_handle); int start_vcpu(struct vcpu *vcpu); diff --git a/hypervisor/include/arch/x86/vmx.h b/hypervisor/include/arch/x86/vmx.h index 7f7c6e2a4..938a20172 100644 --- a/hypervisor/include/arch/x86/vmx.h +++ b/hypervisor/include/arch/x86/vmx.h @@ -447,7 +447,6 @@ uint64_t vmx_rdmsr_pat(struct vcpu *vcpu); int vmx_wrmsr_pat(struct vcpu *vcpu, uint64_t value); int vmx_write_cr0(struct vcpu *vcpu, uint64_t cr0); -int vmx_write_cr3(struct vcpu *vcpu, uint64_t cr3); int vmx_write_cr4(struct vcpu *vcpu, uint64_t cr4); static inline enum vm_cpu_mode get_vcpu_mode(struct vcpu *vcpu)