diff options
-rw-r--r-- | arch/x86/kvm/vmx.c | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 628d012112f5..8dc59aaab3db 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -718,6 +718,7 @@ static void vmx_get_segment(struct kvm_vcpu *vcpu, | |||
718 | static bool guest_state_valid(struct kvm_vcpu *vcpu); | 718 | static bool guest_state_valid(struct kvm_vcpu *vcpu); |
719 | static u32 vmx_segment_access_rights(struct kvm_segment *var); | 719 | static u32 vmx_segment_access_rights(struct kvm_segment *var); |
720 | static void vmx_sync_pir_to_irr_dummy(struct kvm_vcpu *vcpu); | 720 | static void vmx_sync_pir_to_irr_dummy(struct kvm_vcpu *vcpu); |
721 | static void copy_vmcs12_to_shadow(struct vcpu_vmx *vmx); | ||
721 | static void copy_shadow_to_vmcs12(struct vcpu_vmx *vmx); | 722 | static void copy_shadow_to_vmcs12(struct vcpu_vmx *vmx); |
722 | 723 | ||
723 | static DEFINE_PER_CPU(struct vmcs *, vmxarea); | 724 | static DEFINE_PER_CPU(struct vmcs *, vmxarea); |
@@ -5930,6 +5931,50 @@ static void copy_shadow_to_vmcs12(struct vcpu_vmx *vmx) | |||
5930 | vmcs_load(vmx->loaded_vmcs->vmcs); | 5931 | vmcs_load(vmx->loaded_vmcs->vmcs); |
5931 | } | 5932 | } |
5932 | 5933 | ||
5934 | static void copy_vmcs12_to_shadow(struct vcpu_vmx *vmx) | ||
5935 | { | ||
5936 | unsigned long *fields[] = { | ||
5937 | (unsigned long *)shadow_read_write_fields, | ||
5938 | (unsigned long *)shadow_read_only_fields | ||
5939 | }; | ||
5940 | int num_lists = ARRAY_SIZE(fields); | ||
5941 | int max_fields[] = { | ||
5942 | max_shadow_read_write_fields, | ||
5943 | max_shadow_read_only_fields | ||
5944 | }; | ||
5945 | int i, q; | ||
5946 | unsigned long field; | ||
5947 | u64 field_value = 0; | ||
5948 | struct vmcs *shadow_vmcs = vmx->nested.current_shadow_vmcs; | ||
5949 | |||
5950 | vmcs_load(shadow_vmcs); | ||
5951 | |||
5952 | for (q = 0; q < num_lists; q++) { | ||
5953 | for (i = 0; i < max_fields[q]; i++) { | ||
5954 | field = fields[q][i]; | ||
5955 | vmcs12_read_any(&vmx->vcpu, field, &field_value); | ||
5956 | |||
5957 | switch (vmcs_field_type(field)) { | ||
5958 | case VMCS_FIELD_TYPE_U16: | ||
5959 | vmcs_write16(field, (u16)field_value); | ||
5960 | break; | ||
5961 | case VMCS_FIELD_TYPE_U32: | ||
5962 | vmcs_write32(field, (u32)field_value); | ||
5963 | break; | ||
5964 | case VMCS_FIELD_TYPE_U64: | ||
5965 | vmcs_write64(field, (u64)field_value); | ||
5966 | break; | ||
5967 | case VMCS_FIELD_TYPE_NATURAL_WIDTH: | ||
5968 | vmcs_writel(field, (long)field_value); | ||
5969 | break; | ||
5970 | } | ||
5971 | } | ||
5972 | } | ||
5973 | |||
5974 | vmcs_clear(shadow_vmcs); | ||
5975 | vmcs_load(vmx->loaded_vmcs->vmcs); | ||
5976 | } | ||
5977 | |||
5933 | /* | 5978 | /* |
5934 | * VMX instructions which assume a current vmcs12 (i.e., that VMPTRLD was | 5979 | * VMX instructions which assume a current vmcs12 (i.e., that VMPTRLD was |
5935 | * used before) all generate the same failure when it is missing. | 5980 | * used before) all generate the same failure when it is missing. |