diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c index 90949f68cce125ce925e7bd422b62ce07e2514f7..b7f16903c06e224272c115b305b9acaf0568a4bb 100644 --- a/src/cpu/cpu_x86.c +++ b/src/cpu/cpu_x86.c @@ -75,6 +75,14 @@ static const struct x86_kvm_feature x86_kvm_features[] = {VIR_CPU_x86_KVM_PV_UNHALT, { .function = 0x40000001, .eax = 0x00000080 }}, {VIR_CPU_x86_KVM_CLOCKSOURCE_STABLE_BIT, { .function = 0x40000001, .eax = 0x01000000 }}, + {VIR_CPU_x86_KVM_HV_RUNTIME, { .function = 0x40000003, .eax = 0x00000001 }}, + {VIR_CPU_x86_KVM_HV_SYNIC, { .function = 0x40000003, .eax = 0x00000004 }}, + {VIR_CPU_x86_KVM_HV_STIMER, { .function = 0x40000003, .eax = 0x00000008 }}, + {VIR_CPU_x86_KVM_HV_RELAXED, { .function = 0x40000003, .eax = 0x00000020 }}, + {VIR_CPU_x86_KVM_HV_SPINLOCK, { .function = 0x40000003, .eax = 0x00000022 }}, + {VIR_CPU_x86_KVM_HV_VAPIC, { .function = 0x40000003, .eax = 0x00000030 }}, + {VIR_CPU_x86_KVM_HV_VPINDEX, { .function = 0x40000003, .eax = 0x00000040 }}, + {VIR_CPU_x86_KVM_HV_RESET, { .function = 0x40000003, .eax = 0x00000080 }}, }; struct x86_model { diff --git a/src/cpu/cpu_x86_data.h b/src/cpu/cpu_x86_data.h index 88dccf67a2650e326446d940713d2f4b79dc58da..777cc8d4a4f5b601cccdaab1009d9a373cb63edd 100644 --- a/src/cpu/cpu_x86_data.h +++ b/src/cpu/cpu_x86_data.h @@ -48,6 +48,14 @@ struct _virCPUx86CPUID { # define VIR_CPU_x86_KVM_PV_EOI "__kvm_pv_eoi" # define VIR_CPU_x86_KVM_PV_UNHALT "__kvm_pv_unhalt" # define VIR_CPU_x86_KVM_CLOCKSOURCE_STABLE_BIT "__kvm_clocksource_stable" +# define VIR_CPU_x86_KVM_HV_RUNTIME "__kvm_hv_runtime" +# define VIR_CPU_x86_KVM_HV_SYNIC "__kvm_hv_synic" +# define VIR_CPU_x86_KVM_HV_STIMER "__kvm_hv_stimer" +# define VIR_CPU_x86_KVM_HV_RELAXED "__kvm_hv_relaxed" +# define VIR_CPU_x86_KVM_HV_SPINLOCK "__kvm_hv_spinlock" +# define VIR_CPU_x86_KVM_HV_VAPIC "__kvm_hv_vapic" +# define VIR_CPU_x86_KVM_HV_VPINDEX "__kvm_hv_vpindex" +# define VIR_CPU_x86_KVM_HV_RESET "__kvm_hv_reset" typedef struct _virCPUx86Data virCPUx86Data; diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 9334a753b35bfae28b9832ab179867bf8291b799..07b9df27397ce251c5a16c76d6a23ca50a1c6428 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -3928,6 +3928,37 @@ qemuProcessVerifyGuestCPU(virQEMUDriverPtr driver, } } + for (i = 0; i < VIR_DOMAIN_HYPERV_LAST; i++) { + if (def->hyperv_features[i] == VIR_TRISTATE_SWITCH_ON) { + char *cpuFeature; + if (virAsprintf(&cpuFeature, "__kvm_hv_%s", + virDomainHypervTypeToString(i)) < 0) + goto cleanup; + if (!cpuHasFeature(guestcpu, cpuFeature)) { + switch ((virDomainHyperv) i) { + case VIR_DOMAIN_HYPERV_RELAXED: + case VIR_DOMAIN_HYPERV_VAPIC: + case VIR_DOMAIN_HYPERV_SPINLOCKS: + VIR_WARN("host doesn't support hyperv '%s' feature", + virDomainHypervTypeToString(i)); + break; + case VIR_DOMAIN_HYPERV_VPINDEX: + case VIR_DOMAIN_HYPERV_RUNTIME: + case VIR_DOMAIN_HYPERV_SYNIC: + case VIR_DOMAIN_HYPERV_STIMER: + case VIR_DOMAIN_HYPERV_RESET: + case VIR_DOMAIN_HYPERV_VENDOR_ID: + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("host doesn't support hyperv '%s' feature"), + virDomainHypervTypeToString(i)); + goto cleanup; + break; + case VIR_DOMAIN_HYPERV_LAST: + break; + } + } + } + } if (def->cpu && def->cpu->mode != VIR_CPU_MODE_HOST_PASSTHROUGH) { for (i = 0; i < def->cpu->nfeatures; i++) {