Commit 92fbc7b195b824e201d9f06f2b93105f72384d65

Authored by Jan Kiszka
Committed by Paolo Bonzini
1 parent 10ba54a589

KVM: nVMX: Enable unrestricted guest mode support

Now that we provide EPT support, there is no reason to torture our
guests by hiding the relieving unrestricted guest mode feature. We just
need to relax CR0 checks for always-on bits as PE and PG can now be
switched off.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Reviewed-by: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

Showing 1 changed file with 14 additions and 4 deletions Side-by-side Diff

... ... @@ -2252,6 +2252,7 @@
2252 2252 nested_vmx_secondary_ctls_low = 0;
2253 2253 nested_vmx_secondary_ctls_high &=
2254 2254 SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
  2255 + SECONDARY_EXEC_UNRESTRICTED_GUEST |
2255 2256 SECONDARY_EXEC_WBINVD_EXITING;
2256 2257  
2257 2258 if (enable_ept) {
... ... @@ -4877,6 +4878,17 @@
4877 4878 hypercall[2] = 0xc1;
4878 4879 }
4879 4880  
  4881 +static bool nested_cr0_valid(struct vmcs12 *vmcs12, unsigned long val)
  4882 +{
  4883 + unsigned long always_on = VMXON_CR0_ALWAYSON;
  4884 +
  4885 + if (nested_vmx_secondary_ctls_high &
  4886 + SECONDARY_EXEC_UNRESTRICTED_GUEST &&
  4887 + nested_cpu_has2(vmcs12, SECONDARY_EXEC_UNRESTRICTED_GUEST))
  4888 + always_on &= ~(X86_CR0_PE | X86_CR0_PG);
  4889 + return (val & always_on) == always_on;
  4890 +}
  4891 +
4880 4892 /* called to set cr0 as appropriate for a mov-to-cr0 exit. */
4881 4893 static int handle_set_cr0(struct kvm_vcpu *vcpu, unsigned long val)
4882 4894 {
... ... @@ -4895,9 +4907,7 @@
4895 4907 val = (val & ~vmcs12->cr0_guest_host_mask) |
4896 4908 (vmcs12->guest_cr0 & vmcs12->cr0_guest_host_mask);
4897 4909  
4898   - /* TODO: will have to take unrestricted guest mode into
4899   - * account */
4900   - if ((val & VMXON_CR0_ALWAYSON) != VMXON_CR0_ALWAYSON)
  4910 + if (!nested_cr0_valid(vmcs12, val))
4901 4911 return 1;
4902 4912  
4903 4913 if (kvm_set_cr0(vcpu, val))
... ... @@ -7876,7 +7886,7 @@
7876 7886 return 1;
7877 7887 }
7878 7888  
7879   - if (((vmcs12->guest_cr0 & VMXON_CR0_ALWAYSON) != VMXON_CR0_ALWAYSON) ||
  7889 + if (!nested_cr0_valid(vmcs12, vmcs12->guest_cr0) ||
7880 7890 ((vmcs12->guest_cr4 & VMXON_CR4_ALWAYSON) != VMXON_CR4_ALWAYSON)) {
7881 7891 nested_vmx_entry_failure(vcpu, vmcs12,
7882 7892 EXIT_REASON_INVALID_STATE, ENTRY_FAIL_DEFAULT);