]> git.proxmox.com Git - mirror_ubuntu-kernels.git/commitdiff
KVM: x86: hyper-v: Introduce KVM_CAP_HYPERV_ENFORCE_CPUID
authorVitaly Kuznetsov <vkuznets@redhat.com>
Fri, 21 May 2021 09:51:36 +0000 (11:51 +0200)
committerPaolo Bonzini <pbonzini@redhat.com>
Thu, 17 Jun 2021 17:09:38 +0000 (13:09 -0400)
Modeled after KVM_CAP_ENFORCE_PV_FEATURE_CPUID, the new capability allows
for limiting Hyper-V features to those exposed to the guest in Hyper-V
CPUIDs (0x40000003, 0x40000004, ...).

Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Message-Id: <20210521095204.2161214-3-vkuznets@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Documentation/virt/kvm/api.rst
arch/x86/include/asm/kvm_host.h
arch/x86/kvm/hyperv.c
arch/x86/kvm/hyperv.h
arch/x86/kvm/x86.c
include/uapi/linux/kvm.h

index 7fcb2fd38f42e8388d220173ee86ade6b1a5d911..80154d5d98a189a23c6aee66d6ca97405fe11e3a 100644 (file)
@@ -6891,3 +6891,14 @@ This capability is always enabled.
 This capability indicates that the KVM virtual PTP service is
 supported in the host. A VMM can check whether the service is
 available to the guest on migration.
+
+8.33 KVM_CAP_HYPERV_ENFORCE_CPUID
+-----------------------------
+
+Architectures: x86
+
+When enabled, KVM will disable emulated Hyper-V features provided to the
+guest according to the bits Hyper-V CPUID feature leaves. Otherwise, all
+currently implmented Hyper-V features are provided unconditionally when
+Hyper-V identification is set in the HYPERV_CPUID_INTERFACE (0x40000001)
+leaf.
index 1fdb212127c4a27d97f5448395a34b76fa6c64f9..556a8ec89451ade55c84737e0deccd8d861213db 100644 (file)
@@ -543,6 +543,7 @@ struct kvm_vcpu_hv {
        struct kvm_vcpu_hv_stimer stimer[HV_SYNIC_STIMER_COUNT];
        DECLARE_BITMAP(stimer_pending_bitmap, HV_SYNIC_STIMER_COUNT);
        cpumask_t tlb_flush;
+       bool enforce_cpuid;
 };
 
 /* Xen HVM per vcpu emulation context */
index dbd3152b1379eea1633996b3020220b693366a8c..02b0ee189f82d5e37a59b416b76fa1791aed2d2c 100644 (file)
@@ -1853,6 +1853,27 @@ void kvm_hv_set_cpuid(struct kvm_vcpu *vcpu)
                vcpu->arch.hyperv_enabled = false;
 }
 
+int kvm_hv_set_enforce_cpuid(struct kvm_vcpu *vcpu, bool enforce)
+{
+       struct kvm_vcpu_hv *hv_vcpu;
+       int ret = 0;
+
+       if (!to_hv_vcpu(vcpu)) {
+               if (enforce) {
+                       ret = kvm_hv_vcpu_init(vcpu);
+                       if (ret)
+                               return ret;
+               } else {
+                       return 0;
+               }
+       }
+
+       hv_vcpu = to_hv_vcpu(vcpu);
+       hv_vcpu->enforce_cpuid = enforce;
+
+       return ret;
+}
+
 bool kvm_hv_hypercall_enabled(struct kvm_vcpu *vcpu)
 {
        return vcpu->arch.hyperv_enabled && to_kvm_hv(vcpu->kvm)->hv_guest_os_id;
index 60547d5cb6d72451e25c8d7ae3df04e0b0267d9a..730da8537d058ddc6e57071ca31da24ab6c0868b 100644 (file)
@@ -138,6 +138,7 @@ void kvm_hv_invalidate_tsc_page(struct kvm *kvm);
 void kvm_hv_init_vm(struct kvm *kvm);
 void kvm_hv_destroy_vm(struct kvm *kvm);
 void kvm_hv_set_cpuid(struct kvm_vcpu *vcpu);
+int kvm_hv_set_enforce_cpuid(struct kvm_vcpu *vcpu, bool enforce);
 int kvm_vm_ioctl_hv_eventfd(struct kvm *kvm, struct kvm_hyperv_eventfd *args);
 int kvm_get_hv_cpuid(struct kvm_vcpu *vcpu, struct kvm_cpuid2 *cpuid,
                     struct kvm_cpuid_entry2 __user *entries);
index 63e48738764e6766357b4a6dec6fe383b6e6ff07..475376a9741912e6d8e04713a7dbb442ec462c82 100644 (file)
@@ -3955,6 +3955,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
        case KVM_CAP_HYPERV_TLBFLUSH:
        case KVM_CAP_HYPERV_SEND_IPI:
        case KVM_CAP_HYPERV_CPUID:
+       case KVM_CAP_HYPERV_ENFORCE_CPUID:
        case KVM_CAP_SYS_HYPERV_CPUID:
        case KVM_CAP_PCI_SEGMENT:
        case KVM_CAP_DEBUGREGS:
@@ -4878,6 +4879,9 @@ static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu,
 
                return static_call(kvm_x86_enable_direct_tlbflush)(vcpu);
 
+       case KVM_CAP_HYPERV_ENFORCE_CPUID:
+               return kvm_hv_set_enforce_cpuid(vcpu, cap->args[0]);
+
        case KVM_CAP_ENFORCE_PV_FEATURE_CPUID:
                vcpu->arch.pv_cpuid.enforce = cap->args[0];
                if (vcpu->arch.pv_cpuid.enforce)
index 79d9c44d1ad734b14f815b1b5b246abddb66ced4..7928161440925565c1a08af93c4960f1a493b9f3 100644 (file)
@@ -1083,6 +1083,7 @@ struct kvm_ppc_resize_hpt {
 #define KVM_CAP_SGX_ATTRIBUTE 196
 #define KVM_CAP_VM_COPY_ENC_CONTEXT_FROM 197
 #define KVM_CAP_PTP_KVM 198
+#define KVM_CAP_HYPERV_ENFORCE_CPUID 199
 
 #ifdef KVM_CAP_IRQ_ROUTING