OSDN Git Service

KVM: nVMX: Do not forward VMREAD/VMWRITE VMExits to L1 if required so by vmcs12 vmrea...
authorLiran Alon <liran.alon@oracle.com>
Fri, 22 Jun 2018 23:35:10 +0000 (02:35 +0300)
committerPaolo Bonzini <pbonzini@redhat.com>
Mon, 6 Aug 2018 15:58:45 +0000 (17:58 +0200)
This is done as a preparation for VMCS shadowing emulation.

Signed-off-by: Liran Alon <liran.alon@oracle.com>
Signed-off-by: Jim Mattson <jmattson@google.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
arch/x86/kvm/vmx.c

index f91a159..27fd3e1 100644 (file)
@@ -9107,6 +9107,30 @@ static bool nested_vmx_exit_handled_cr(struct kvm_vcpu *vcpu,
        return false;
 }
 
+static bool nested_vmx_exit_handled_vmcs_access(struct kvm_vcpu *vcpu,
+       struct vmcs12 *vmcs12, gpa_t bitmap)
+{
+       u32 vmx_instruction_info;
+       unsigned long field;
+       u8 b;
+
+       if (!nested_cpu_has_shadow_vmcs(vmcs12))
+               return true;
+
+       /* Decode instruction info and find the field to access */
+       vmx_instruction_info = vmcs_read32(VMX_INSTRUCTION_INFO);
+       field = kvm_register_read(vcpu, (((vmx_instruction_info) >> 28) & 0xf));
+
+       /* Out-of-range fields always cause a VM exit from L2 to L1 */
+       if (field >> 15)
+               return true;
+
+       if (kvm_vcpu_read_guest(vcpu, bitmap + field/8, &b, 1))
+               return true;
+
+       return 1 & (b >> (field & 7));
+}
+
 /*
  * Return 1 if we should exit from L2 to L1 to handle an exit, or 0 if we
  * should handle it ourselves in L0 (and then continue L2). Only call this
@@ -9191,10 +9215,15 @@ static bool nested_vmx_exit_reflected(struct kvm_vcpu *vcpu, u32 exit_reason)
                return nested_cpu_has2(vmcs12, SECONDARY_EXEC_RDSEED_EXITING);
        case EXIT_REASON_RDTSC: case EXIT_REASON_RDTSCP:
                return nested_cpu_has(vmcs12, CPU_BASED_RDTSC_EXITING);
+       case EXIT_REASON_VMREAD:
+               return nested_vmx_exit_handled_vmcs_access(vcpu, vmcs12,
+                       vmcs12->vmread_bitmap);
+       case EXIT_REASON_VMWRITE:
+               return nested_vmx_exit_handled_vmcs_access(vcpu, vmcs12,
+                       vmcs12->vmwrite_bitmap);
        case EXIT_REASON_VMCALL: case EXIT_REASON_VMCLEAR:
        case EXIT_REASON_VMLAUNCH: case EXIT_REASON_VMPTRLD:
-       case EXIT_REASON_VMPTRST: case EXIT_REASON_VMREAD:
-       case EXIT_REASON_VMRESUME: case EXIT_REASON_VMWRITE:
+       case EXIT_REASON_VMPTRST: case EXIT_REASON_VMRESUME:
        case EXIT_REASON_VMOFF: case EXIT_REASON_VMON:
        case EXIT_REASON_INVEPT: case EXIT_REASON_INVVPID:
                /*