aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/kvm/vmx.c45
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,
718static bool guest_state_valid(struct kvm_vcpu *vcpu); 718static bool guest_state_valid(struct kvm_vcpu *vcpu);
719static u32 vmx_segment_access_rights(struct kvm_segment *var); 719static u32 vmx_segment_access_rights(struct kvm_segment *var);
720static void vmx_sync_pir_to_irr_dummy(struct kvm_vcpu *vcpu); 720static void vmx_sync_pir_to_irr_dummy(struct kvm_vcpu *vcpu);
721static void copy_vmcs12_to_shadow(struct vcpu_vmx *vmx);
721static void copy_shadow_to_vmcs12(struct vcpu_vmx *vmx); 722static void copy_shadow_to_vmcs12(struct vcpu_vmx *vmx);
722 723
723static DEFINE_PER_CPU(struct vmcs *, vmxarea); 724static 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
5934static 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.