mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2026-06-08 18:14:53 +00:00
vcpu: add get/set register APIs
there will be 3 types of vcpu runtime contexts: - runtime contexts always saved/restored during VM exit/entry, which include general registers rax/rcx/rdx/rbx/rbp/rsi/rdi/r8~r15, cr2 and msr for spectre control (ia32_spec_ctrl) - runtime contexts on-demand cached/updated during VM exit/entry, which include frequently used registers rsp, rip, efer, rflags, cr0 and cr4 - runtime contexts always read/write from/to VMCS, which include left registers not in above this patch add get/set register APIs for vcpu runtime contexts, and unified the save/restore method for them according to above description. v3: - update vcpu_get/set_cr0/4 as unified interface to get/set guest cr0/cr4, use on-demand cache for reading, but always write to VMCS for writing. v2: - use reg_cached/reg_updated for on-demand runtime contexts - always read/write cr3 from/to VMCS Signed-off-by: Jason Chen CJ <jason.cj.chen@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user