KVM: nVMX: Refactor handle_vmwrite
Refactor existent code so we re-use vmcs12_write_any to copy fields from the shadow vmcs specified by the link pointer (used by the processor, implementation-specific) to the VMCS12 software format used by L0 to hold the fields in L1 memory address space. Signed-off-by: Abel Gordon <abelg@il.ibm.com> Reviewed-by: Orit Wasserman <owasserm@redhat.com> Signed-off-by: Gleb Natapov <gleb@redhat.com>
This commit is contained in:
committed by
Gleb Natapov
parent
4607c2d7a2
commit
20b97feaf6
@ -5842,6 +5842,33 @@ static inline bool vmcs12_read_any(struct kvm_vcpu *vcpu,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static inline bool vmcs12_write_any(struct kvm_vcpu *vcpu,
|
||||
unsigned long field, u64 field_value){
|
||||
short offset = vmcs_field_to_offset(field);
|
||||
char *p = ((char *) get_vmcs12(vcpu)) + offset;
|
||||
if (offset < 0)
|
||||
return false;
|
||||
|
||||
switch (vmcs_field_type(field)) {
|
||||
case VMCS_FIELD_TYPE_U16:
|
||||
*(u16 *)p = field_value;
|
||||
return true;
|
||||
case VMCS_FIELD_TYPE_U32:
|
||||
*(u32 *)p = field_value;
|
||||
return true;
|
||||
case VMCS_FIELD_TYPE_U64:
|
||||
*(u64 *)p = field_value;
|
||||
return true;
|
||||
case VMCS_FIELD_TYPE_NATURAL_WIDTH:
|
||||
*(natural_width *)p = field_value;
|
||||
return true;
|
||||
default:
|
||||
return false; /* can never happen. */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* VMX instructions which assume a current vmcs12 (i.e., that VMPTRLD was
|
||||
* used before) all generate the same failure when it is missing.
|
||||
@ -5906,8 +5933,6 @@ static int handle_vmwrite(struct kvm_vcpu *vcpu)
|
||||
gva_t gva;
|
||||
unsigned long exit_qualification = vmcs_readl(EXIT_QUALIFICATION);
|
||||
u32 vmx_instruction_info = vmcs_read32(VMX_INSTRUCTION_INFO);
|
||||
char *p;
|
||||
short offset;
|
||||
/* The value to write might be 32 or 64 bits, depending on L1's long
|
||||
* mode, and eventually we need to write that into a field of several
|
||||
* possible lengths. The code below first zero-extends the value to 64
|
||||
@ -5944,28 +5969,7 @@ static int handle_vmwrite(struct kvm_vcpu *vcpu)
|
||||
return 1;
|
||||
}
|
||||
|
||||
offset = vmcs_field_to_offset(field);
|
||||
if (offset < 0) {
|
||||
nested_vmx_failValid(vcpu, VMXERR_UNSUPPORTED_VMCS_COMPONENT);
|
||||
skip_emulated_instruction(vcpu);
|
||||
return 1;
|
||||
}
|
||||
p = ((char *) get_vmcs12(vcpu)) + offset;
|
||||
|
||||
switch (vmcs_field_type(field)) {
|
||||
case VMCS_FIELD_TYPE_U16:
|
||||
*(u16 *)p = field_value;
|
||||
break;
|
||||
case VMCS_FIELD_TYPE_U32:
|
||||
*(u32 *)p = field_value;
|
||||
break;
|
||||
case VMCS_FIELD_TYPE_U64:
|
||||
*(u64 *)p = field_value;
|
||||
break;
|
||||
case VMCS_FIELD_TYPE_NATURAL_WIDTH:
|
||||
*(natural_width *)p = field_value;
|
||||
break;
|
||||
default:
|
||||
if (!vmcs12_write_any(vcpu, field, field_value)) {
|
||||
nested_vmx_failValid(vcpu, VMXERR_UNSUPPORTED_VMCS_COMPONENT);
|
||||
skip_emulated_instruction(vcpu);
|
||||
return 1;
|
||||
|
Reference in New Issue
Block a user