mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-09-24 10:17:28 +00:00
HV:treewide: Add exec_vmread16 and exec_vmwrite16 functions
In the hypervisor, VMCS fields include 16-bit fields, 32-bit fields, 64-bit fields and natural-width fields. In the current implement, no exec_vmread16/exec_vmwrite16 is for accessing 16-bit fields. So there are many type casting for the return value and parameters vmread/vmwrite operations. Create exec_vmread16 and exec_vmwrite16 functions to access 16-bit fields in VMCS; Update related variables type for vmread/vmwrite operations; Update related caller according to VMCS fields size. V1--V2: This is new part of this patch serial to only update 16-bit vmread/vmread opertions and related caller. V2--V3: Add "hu" for uint16_t argument in log function; Add comments for function get_vmcs_field; Update related variables type for exec_vmread16; Rename temp variable 'low' into 'value'. V3-->V4: Few updates for exec_vmread16. V4-->V5: Few updates for coding style; Replace "hux" with "hu" in log function for 16-bit variable. V5-->V6: CPU_REG_64BIT_LAST is used in the vm_get_register and vm_set_register to make condition statement more understandable. Signed-off-by: Xiangyang Wu <xiangyang.wu@intel.com> Reviewed-by: Junjie Mao <junjie.mao@intel.com>
This commit is contained in:
@@ -286,7 +286,7 @@ int gva2gpa(struct vcpu *vcpu, uint64_t gva, uint64_t *gpa,
|
||||
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_vmread(VMX_GUEST_CS_SEL) & 0x3UL) == 3UL);
|
||||
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);
|
||||
|
@@ -44,7 +44,11 @@ int vm_get_register(struct vcpu *vcpu, enum cpu_reg_name reg, uint64_t *retval)
|
||||
uint32_t field = get_vmcs_field(reg);
|
||||
|
||||
if (field != VMX_INVALID_VMCS_FIELD) {
|
||||
*retval = exec_vmread(field);
|
||||
if (reg < CPU_REG_64BIT_LAST) {
|
||||
*retval = exec_vmread(field);
|
||||
} else {
|
||||
*retval = (uint64_t)exec_vmread16(field);
|
||||
}
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -73,7 +77,11 @@ int vm_set_register(struct vcpu *vcpu, enum cpu_reg_name reg, uint64_t val)
|
||||
uint32_t field = get_vmcs_field(reg);
|
||||
|
||||
if (field != VMX_INVALID_VMCS_FIELD) {
|
||||
exec_vmwrite(field, val);
|
||||
if (reg < CPU_REG_64BIT_LAST) {
|
||||
exec_vmwrite(field, val);
|
||||
} else {
|
||||
exec_vmwrite16(field, (uint16_t)val);
|
||||
}
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -223,7 +231,21 @@ encode_vmcs_seg_desc(enum cpu_reg_name seg,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*Description:
|
||||
*This local function is to covert register names into
|
||||
*the corresponding field index MACROs in VMCS.
|
||||
*
|
||||
*Post Condition:
|
||||
*In the non-general register names group (CPU_REG_CR0~CPU_REG_LAST),
|
||||
*for register names CPU_REG_CR2, CPU_REG_IDTR, CPU_REG_GDTR,
|
||||
*CPU_REG_NATURAL_LAST, CPU_REG_64BIT_LAST and CPU_REG_LAST,
|
||||
*this function returns VMX_INVALID_VMCS_FIELD;
|
||||
*for other register names, it returns correspoding field index MACROs
|
||||
*in VMCS.
|
||||
*
|
||||
**/
|
||||
static uint32_t get_vmcs_field(enum cpu_reg_name ident)
|
||||
{
|
||||
switch (ident) {
|
||||
|
@@ -158,7 +158,7 @@ int start_vcpu(struct vcpu *vcpu)
|
||||
vcpu->vm->attr.id, vcpu->vcpu_id);
|
||||
|
||||
if (vcpu->arch_vcpu.vpid)
|
||||
exec_vmwrite(VMX_VPID, vcpu->arch_vcpu.vpid);
|
||||
exec_vmwrite16(VMX_VPID, vcpu->arch_vcpu.vpid);
|
||||
|
||||
/*
|
||||
* A power-up or a reset invalidates all linear mappings,
|
||||
|
@@ -2340,13 +2340,12 @@ apicv_inject_pir(struct vlapic *vlapic)
|
||||
if (pirval != 0UL) {
|
||||
rvi = pirbase + fls64(pirval);
|
||||
|
||||
intr_status_old = (uint16_t)
|
||||
(0xFFFFUL &
|
||||
exec_vmread(VMX_GUEST_INTR_STATUS));
|
||||
intr_status_old = 0xFFFFU &
|
||||
exec_vmread16(VMX_GUEST_INTR_STATUS);
|
||||
|
||||
intr_status_new = (intr_status_old & 0xFF00U) | rvi;
|
||||
if (intr_status_new > intr_status_old) {
|
||||
exec_vmwrite(VMX_GUEST_INTR_STATUS,
|
||||
exec_vmwrite16(VMX_GUEST_INTR_STATUS,
|
||||
intr_status_new);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user