Commit 92fbc7b1 authored by Jan Kiszka's avatar Jan Kiszka Committed by Paolo Bonzini

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: default avatarJan Kiszka <jan.kiszka@siemens.com>
Reviewed-by: default avatarGleb Natapov <gleb@redhat.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent 10ba54a5
...@@ -2252,6 +2252,7 @@ static __init void nested_vmx_setup_ctls_msrs(void) ...@@ -2252,6 +2252,7 @@ static __init void nested_vmx_setup_ctls_msrs(void)
nested_vmx_secondary_ctls_low = 0; nested_vmx_secondary_ctls_low = 0;
nested_vmx_secondary_ctls_high &= nested_vmx_secondary_ctls_high &=
SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES | SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
SECONDARY_EXEC_UNRESTRICTED_GUEST |
SECONDARY_EXEC_WBINVD_EXITING; SECONDARY_EXEC_WBINVD_EXITING;
if (enable_ept) { if (enable_ept) {
...@@ -4877,6 +4878,17 @@ vmx_patch_hypercall(struct kvm_vcpu *vcpu, unsigned char *hypercall) ...@@ -4877,6 +4878,17 @@ vmx_patch_hypercall(struct kvm_vcpu *vcpu, unsigned char *hypercall)
hypercall[2] = 0xc1; hypercall[2] = 0xc1;
} }
static bool nested_cr0_valid(struct vmcs12 *vmcs12, unsigned long val)
{
unsigned long always_on = VMXON_CR0_ALWAYSON;
if (nested_vmx_secondary_ctls_high &
SECONDARY_EXEC_UNRESTRICTED_GUEST &&
nested_cpu_has2(vmcs12, SECONDARY_EXEC_UNRESTRICTED_GUEST))
always_on &= ~(X86_CR0_PE | X86_CR0_PG);
return (val & always_on) == always_on;
}
/* called to set cr0 as appropriate for a mov-to-cr0 exit. */ /* called to set cr0 as appropriate for a mov-to-cr0 exit. */
static int handle_set_cr0(struct kvm_vcpu *vcpu, unsigned long val) static int handle_set_cr0(struct kvm_vcpu *vcpu, unsigned long val)
{ {
...@@ -4895,9 +4907,7 @@ static int handle_set_cr0(struct kvm_vcpu *vcpu, unsigned long val) ...@@ -4895,9 +4907,7 @@ static int handle_set_cr0(struct kvm_vcpu *vcpu, unsigned long val)
val = (val & ~vmcs12->cr0_guest_host_mask) | val = (val & ~vmcs12->cr0_guest_host_mask) |
(vmcs12->guest_cr0 & vmcs12->cr0_guest_host_mask); (vmcs12->guest_cr0 & vmcs12->cr0_guest_host_mask);
/* TODO: will have to take unrestricted guest mode into if (!nested_cr0_valid(vmcs12, val))
* account */
if ((val & VMXON_CR0_ALWAYSON) != VMXON_CR0_ALWAYSON)
return 1; return 1;
if (kvm_set_cr0(vcpu, val)) if (kvm_set_cr0(vcpu, val))
...@@ -7876,7 +7886,7 @@ static int nested_vmx_run(struct kvm_vcpu *vcpu, bool launch) ...@@ -7876,7 +7886,7 @@ static int nested_vmx_run(struct kvm_vcpu *vcpu, bool launch)
return 1; return 1;
} }
if (((vmcs12->guest_cr0 & VMXON_CR0_ALWAYSON) != VMXON_CR0_ALWAYSON) || if (!nested_cr0_valid(vmcs12, vmcs12->guest_cr0) ||
((vmcs12->guest_cr4 & VMXON_CR4_ALWAYSON) != VMXON_CR4_ALWAYSON)) { ((vmcs12->guest_cr4 & VMXON_CR4_ALWAYSON) != VMXON_CR4_ALWAYSON)) {
nested_vmx_entry_failure(vcpu, vmcs12, nested_vmx_entry_failure(vcpu, vmcs12,
EXIT_REASON_INVALID_STATE, ENTRY_FAIL_DEFAULT); EXIT_REASON_INVALID_STATE, ENTRY_FAIL_DEFAULT);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment