Commit dd598091 authored by Nadav Amit's avatar Nadav Amit Committed by Paolo Bonzini

KVM: x86: Warn if guest virtual address space is not 48-bits

The KVM emulator code assumes that the guest virtual address space (in 64-bit)
is 48-bits wide.  Fail the KVM_SET_CPUID and KVM_SET_CPUID2 ioctl if
userspace tries to create a guest that does not obey this restriction.
Signed-off-by: default avatarNadav Amit <namit@cs.technion.ac.il>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent 3c3c29fd
...@@ -53,14 +53,14 @@ u64 kvm_supported_xcr0(void) ...@@ -53,14 +53,14 @@ u64 kvm_supported_xcr0(void)
return xcr0; return xcr0;
} }
void kvm_update_cpuid(struct kvm_vcpu *vcpu) int kvm_update_cpuid(struct kvm_vcpu *vcpu)
{ {
struct kvm_cpuid_entry2 *best; struct kvm_cpuid_entry2 *best;
struct kvm_lapic *apic = vcpu->arch.apic; struct kvm_lapic *apic = vcpu->arch.apic;
best = kvm_find_cpuid_entry(vcpu, 1, 0); best = kvm_find_cpuid_entry(vcpu, 1, 0);
if (!best) if (!best)
return; return 0;
/* Update OSXSAVE bit */ /* Update OSXSAVE bit */
if (cpu_has_xsave && best->function == 0x1) { if (cpu_has_xsave && best->function == 0x1) {
...@@ -88,7 +88,17 @@ void kvm_update_cpuid(struct kvm_vcpu *vcpu) ...@@ -88,7 +88,17 @@ void kvm_update_cpuid(struct kvm_vcpu *vcpu)
xstate_required_size(vcpu->arch.xcr0); xstate_required_size(vcpu->arch.xcr0);
} }
/*
* The existing code assumes virtual address is 48-bit in the canonical
* address checks; exit if it is ever changed.
*/
best = kvm_find_cpuid_entry(vcpu, 0x80000008, 0);
if (best && ((best->eax & 0xff00) >> 8) != 48 &&
((best->eax & 0xff00) >> 8) != 0)
return -EINVAL;
kvm_pmu_cpuid_update(vcpu); kvm_pmu_cpuid_update(vcpu);
return 0;
} }
static int is_efer_nx(void) static int is_efer_nx(void)
...@@ -151,10 +161,9 @@ int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu, ...@@ -151,10 +161,9 @@ int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu,
} }
vcpu->arch.cpuid_nent = cpuid->nent; vcpu->arch.cpuid_nent = cpuid->nent;
cpuid_fix_nx_cap(vcpu); cpuid_fix_nx_cap(vcpu);
r = 0;
kvm_apic_set_version(vcpu); kvm_apic_set_version(vcpu);
kvm_x86_ops->cpuid_update(vcpu); kvm_x86_ops->cpuid_update(vcpu);
kvm_update_cpuid(vcpu); r = kvm_update_cpuid(vcpu);
out_free: out_free:
vfree(cpuid_entries); vfree(cpuid_entries);
...@@ -178,9 +187,7 @@ int kvm_vcpu_ioctl_set_cpuid2(struct kvm_vcpu *vcpu, ...@@ -178,9 +187,7 @@ int kvm_vcpu_ioctl_set_cpuid2(struct kvm_vcpu *vcpu,
vcpu->arch.cpuid_nent = cpuid->nent; vcpu->arch.cpuid_nent = cpuid->nent;
kvm_apic_set_version(vcpu); kvm_apic_set_version(vcpu);
kvm_x86_ops->cpuid_update(vcpu); kvm_x86_ops->cpuid_update(vcpu);
kvm_update_cpuid(vcpu); r = kvm_update_cpuid(vcpu);
return 0;
out: out:
return r; return r;
} }
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
#include "x86.h" #include "x86.h"
void kvm_update_cpuid(struct kvm_vcpu *vcpu); int kvm_update_cpuid(struct kvm_vcpu *vcpu);
struct kvm_cpuid_entry2 *kvm_find_cpuid_entry(struct kvm_vcpu *vcpu, struct kvm_cpuid_entry2 *kvm_find_cpuid_entry(struct kvm_vcpu *vcpu,
u32 function, u32 index); u32 function, u32 index);
int kvm_dev_ioctl_get_cpuid(struct kvm_cpuid2 *cpuid, int kvm_dev_ioctl_get_cpuid(struct kvm_cpuid2 *cpuid,
......
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