mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/herbert/cryptodev-2.6.git
synced 2026-04-28 21:46:02 -04:00
KVM: x86: hyper-v: Make Hyper-V emulation enablement conditional
Hyper-V emulation is enabled in KVM unconditionally. This is bad at least from security standpoint as it is an extra attack surface. Ideally, there should be a per-VM capability explicitly enabled by VMM but currently it is not the case and we can't mandate one without breaking backwards compatibility. We can, however, check guest visible CPUIDs and only enable Hyper-V emulation when "Hv#1" interface was exposed in HYPERV_CPUID_INTERFACE. Note, VMMs are free to act in any sequence they like, e.g. they can try to set MSRs first and CPUIDs later so we still need to allow the host to read/write Hyper-V specific MSRs unconditionally. Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com> Message-Id: <20210126134816.1880136-14-vkuznets@redhat.com> [Add selftest vcpu_set_hv_cpuid API to avoid breaking xen_vmcall_test. - Paolo] Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
committed by
Paolo Bonzini
parent
4592b7eaa8
commit
8f014550df
@@ -1323,6 +1323,41 @@ struct kvm_cpuid2 *kvm_get_supported_hv_cpuid(void)
|
||||
return cpuid;
|
||||
}
|
||||
|
||||
void vcpu_set_hv_cpuid(struct kvm_vm *vm, uint32_t vcpuid)
|
||||
{
|
||||
static struct kvm_cpuid2 *cpuid_full;
|
||||
struct kvm_cpuid2 *cpuid_sys, *cpuid_hv;
|
||||
int i, nent = 0;
|
||||
|
||||
if (!cpuid_full) {
|
||||
cpuid_sys = kvm_get_supported_cpuid();
|
||||
cpuid_hv = kvm_get_supported_hv_cpuid();
|
||||
|
||||
cpuid_full = malloc(sizeof(*cpuid_full) +
|
||||
(cpuid_sys->nent + cpuid_hv->nent) *
|
||||
sizeof(struct kvm_cpuid_entry2));
|
||||
if (!cpuid_full) {
|
||||
perror("malloc");
|
||||
abort();
|
||||
}
|
||||
|
||||
/* Need to skip KVM CPUID leaves 0x400000xx */
|
||||
for (i = 0; i < cpuid_sys->nent; i++) {
|
||||
if (cpuid_sys->entries[i].function >= 0x40000000 &&
|
||||
cpuid_sys->entries[i].function < 0x40000100)
|
||||
continue;
|
||||
cpuid_full->entries[nent] = cpuid_sys->entries[i];
|
||||
nent++;
|
||||
}
|
||||
|
||||
memcpy(&cpuid_full->entries[nent], cpuid_hv->entries,
|
||||
cpuid_hv->nent * sizeof(struct kvm_cpuid_entry2));
|
||||
cpuid_full->nent = nent + cpuid_hv->nent;
|
||||
}
|
||||
|
||||
vcpu_set_cpuid(vm, vcpuid, cpuid_full);
|
||||
}
|
||||
|
||||
struct kvm_cpuid2 *vcpu_get_supported_hv_cpuid(struct kvm_vm *vm, uint32_t vcpuid)
|
||||
{
|
||||
static struct kvm_cpuid2 *cpuid;
|
||||
|
||||
Reference in New Issue
Block a user