mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-09-24 02:08:04 +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:
@@ -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);
|
||||
}
|
||||
|
||||
|
@@ -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__);
|
||||
|
Reference in New Issue
Block a user