diff options
author | Abel Gordon <abelg@il.ibm.com> | 2013-04-18 07:36:25 -0400 |
---|---|---|
committer | Gleb Natapov <gleb@redhat.com> | 2013-04-22 03:51:44 -0400 |
commit | 20b97feaf615da2c43361e1dda7efd068a4446ef (patch) | |
tree | 74976cbba36be27a16cfd8b13ccc7fe17b6abf4c /arch/x86 | |
parent | 4607c2d7a2ee90707de2b3b37e4d9156e05cdf29 (diff) |
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>
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/kvm/vmx.c | 52 |
1 files changed, 28 insertions, 24 deletions
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 7dc599630430..1ee63cae82cd 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -5842,6 +5842,33 @@ static inline bool vmcs12_read_any(struct kvm_vcpu *vcpu, | |||
5842 | } | 5842 | } |
5843 | } | 5843 | } |
5844 | 5844 | ||
5845 | |||
5846 | static inline bool vmcs12_write_any(struct kvm_vcpu *vcpu, | ||
5847 | unsigned long field, u64 field_value){ | ||
5848 | short offset = vmcs_field_to_offset(field); | ||
5849 | char *p = ((char *) get_vmcs12(vcpu)) + offset; | ||
5850 | if (offset < 0) | ||
5851 | return false; | ||
5852 | |||
5853 | switch (vmcs_field_type(field)) { | ||
5854 | case VMCS_FIELD_TYPE_U16: | ||
5855 | *(u16 *)p = field_value; | ||
5856 | return true; | ||
5857 | case VMCS_FIELD_TYPE_U32: | ||
5858 | *(u32 *)p = field_value; | ||
5859 | return true; | ||
5860 | case VMCS_FIELD_TYPE_U64: | ||
5861 | *(u64 *)p = field_value; | ||
5862 | return true; | ||
5863 | case VMCS_FIELD_TYPE_NATURAL_WIDTH: | ||
5864 | *(natural_width *)p = field_value; | ||
5865 | return true; | ||
5866 | default: | ||
5867 | return false; /* can never happen. */ | ||
5868 | } | ||
5869 | |||
5870 | } | ||
5871 | |||
5845 | /* | 5872 | /* |
5846 | * VMX instructions which assume a current vmcs12 (i.e., that VMPTRLD was | 5873 | * VMX instructions which assume a current vmcs12 (i.e., that VMPTRLD was |
5847 | * used before) all generate the same failure when it is missing. | 5874 | * used before) all generate the same failure when it is missing. |
@@ -5906,8 +5933,6 @@ static int handle_vmwrite(struct kvm_vcpu *vcpu) | |||
5906 | gva_t gva; | 5933 | gva_t gva; |
5907 | unsigned long exit_qualification = vmcs_readl(EXIT_QUALIFICATION); | 5934 | unsigned long exit_qualification = vmcs_readl(EXIT_QUALIFICATION); |
5908 | u32 vmx_instruction_info = vmcs_read32(VMX_INSTRUCTION_INFO); | 5935 | u32 vmx_instruction_info = vmcs_read32(VMX_INSTRUCTION_INFO); |
5909 | char *p; | ||
5910 | short offset; | ||
5911 | /* The value to write might be 32 or 64 bits, depending on L1's long | 5936 | /* The value to write might be 32 or 64 bits, depending on L1's long |
5912 | * mode, and eventually we need to write that into a field of several | 5937 | * mode, and eventually we need to write that into a field of several |
5913 | * possible lengths. The code below first zero-extends the value to 64 | 5938 | * possible lengths. The code below first zero-extends the value to 64 |
@@ -5944,28 +5969,7 @@ static int handle_vmwrite(struct kvm_vcpu *vcpu) | |||
5944 | return 1; | 5969 | return 1; |
5945 | } | 5970 | } |
5946 | 5971 | ||
5947 | offset = vmcs_field_to_offset(field); | 5972 | if (!vmcs12_write_any(vcpu, field, field_value)) { |
5948 | if (offset < 0) { | ||
5949 | nested_vmx_failValid(vcpu, VMXERR_UNSUPPORTED_VMCS_COMPONENT); | ||
5950 | skip_emulated_instruction(vcpu); | ||
5951 | return 1; | ||
5952 | } | ||
5953 | p = ((char *) get_vmcs12(vcpu)) + offset; | ||
5954 | |||
5955 | switch (vmcs_field_type(field)) { | ||
5956 | case VMCS_FIELD_TYPE_U16: | ||
5957 | *(u16 *)p = field_value; | ||
5958 | break; | ||
5959 | case VMCS_FIELD_TYPE_U32: | ||
5960 | *(u32 *)p = field_value; | ||
5961 | break; | ||
5962 | case VMCS_FIELD_TYPE_U64: | ||
5963 | *(u64 *)p = field_value; | ||
5964 | break; | ||
5965 | case VMCS_FIELD_TYPE_NATURAL_WIDTH: | ||
5966 | *(natural_width *)p = field_value; | ||
5967 | break; | ||
5968 | default: | ||
5969 | nested_vmx_failValid(vcpu, VMXERR_UNSUPPORTED_VMCS_COMPONENT); | 5973 | nested_vmx_failValid(vcpu, VMXERR_UNSUPPORTED_VMCS_COMPONENT); |
5970 | skip_emulated_instruction(vcpu); | 5974 | skip_emulated_instruction(vcpu); |
5971 | return 1; | 5975 | return 1; |