[libvirt] [PATCH 3/3] qemu_process: add check for hyperv features
John Ferlan
jferlan at redhat.com
Tue Mar 29 15:10:42 UTC 2016
On 03/29/2016 09:31 AM, Pavel Hrdina wrote:
> Commit 7068b56c introduced several hyperv features. Not all hyperv
> features are supported by old enough kernels and we shouldn't allow to
> start a guest if kernel doesn't support any of the hyperv feature.
>
> There is one exception, for backward compatibility we cannot error out
> if one of the RELAXED, VAPIC or SPINLOCKS isn't supported, for the same
> reason we ignore invtsc, to not break restoring saved domains with older
> libvirt.
>From yesterday's dialog, there's also commit id '59fc0d06' which adds
"hv_crash" and commit id '600bca59' which adds "hv_time".
Neither is handled via these bits, but wouldn't both fall into the same
trap since both were added after commit '2e8f9080'?
>
> Signed-off-by: Pavel Hrdina <phrdina at redhat.com>
> ---
> src/cpu/cpu_x86.c | 8 ++++++++
> src/cpu/cpu_x86_data.h | 8 ++++++++
> src/qemu/qemu_process.c | 31 +++++++++++++++++++++++++++++++
> 3 files changed, 47 insertions(+)
>
Now I was going to ask about a capability bit for this, but seeing none
in previous commits, I thought I was safe... I guess not.
The rest looks OK to me, although I wonder if there's a way to avoid
missing this for future changes
John
> diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c
> index 90949f6..b7f1690 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 88dccf6..777cc8d 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 9334a75..07b9df2 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++) {
>
More information about the libvir-list
mailing list