Currently, the existing qspinlock implementation will fallback to test-and-set if the hypervisor has not set the PV_UNHALT flag. This patch gives the opportunity to guest kernels to select between test-and-set and the regular queueu fair lock implementation based on the PV_DEDICATED KVM feature flag. When the PV_DEDICATED flag is not set, the code will still fall back to test-and-set, but when the PV_DEDICATED flag is set, the code will use the regular queue spinlock implementation. Cc: Paolo Bonzini <pbonzini@xxxxxxxxxx> Cc: "Radim Krčmář" <rkrcmar@xxxxxxxxxx> Cc: Jonathan Corbet <corbet@xxxxxxx> Cc: Thomas Gleixner <tglx@xxxxxxxxxxxxx> Cc: Ingo Molnar <mingo@xxxxxxxxxx> Cc: "H. Peter Anvin" <hpa@xxxxxxxxx> Cc: x86@xxxxxxxxxx Cc: Peter Zijlstra <peterz@xxxxxxxxxxxxx> Cc: Waiman Long <longman@xxxxxxxxxx> Cc: kvm@xxxxxxxxxxxxxxx Cc: linux-doc@xxxxxxxxxxxxxxx Cc: linux-kernel@xxxxxxxxxxxxxxx Cc: Jan H. Schoenherr <jschoenh@xxxxxxxxx> Cc: Anthony Liguori <aliguori@xxxxxxxxxx> Suggested-by: Matt Wilson <msw@xxxxxxxxxx> Signed-off-by: Eduardo Valentin <eduval@xxxxxxxxxx> --- Documentation/virtual/kvm/cpuid.txt | 6 ++++++ arch/x86/include/asm/qspinlock.h | 4 ++++ arch/x86/include/uapi/asm/kvm_para.h | 1 + 3 files changed, 11 insertions(+) diff --git a/Documentation/virtual/kvm/cpuid.txt b/Documentation/virtual/kvm/cpuid.txt index 3c65feb..117066a 100644 --- a/Documentation/virtual/kvm/cpuid.txt +++ b/Documentation/virtual/kvm/cpuid.txt @@ -54,6 +54,12 @@ KVM_FEATURE_PV_UNHALT || 7 || guest checks this feature bit || || before enabling paravirtualized || || spinlock support. ------------------------------------------------------------------------------ +KVM_FEATURE_PV_DEDICATED || 8 || guest checks this feature bit + || || to determine if they run on + || || dedicated vCPUs, allowing opti- + || || mizations such as usage of + || || qspinlocks. +------------------------------------------------------------------------------ KVM_FEATURE_CLOCKSOURCE_STABLE_BIT || 24 || host will warn if no guest-side || || per-cpu warps are expected in || || kvmclock. diff --git a/arch/x86/include/asm/qspinlock.h b/arch/x86/include/asm/qspinlock.h index eaba080..f89b469 100644 --- a/arch/x86/include/asm/qspinlock.h +++ b/arch/x86/include/asm/qspinlock.h @@ -1,6 +1,8 @@ #ifndef _ASM_X86_QSPINLOCK_H #define _ASM_X86_QSPINLOCK_H +#include <linux/kvm_para.h> + #include <asm/cpufeature.h> #include <asm-generic/qspinlock_types.h> #include <asm/paravirt.h> @@ -46,6 +48,8 @@ static inline bool virt_spin_lock(struct qspinlock *lock) if (!static_cpu_has(X86_FEATURE_HYPERVISOR)) return false; + if (kvm_para_has_feature(KVM_FEATURE_PV_DEDICATED)) + return false; /* * On hypervisors without PARAVIRT_SPINLOCKS support we fall * back to a Test-and-Set spinlock, because fair locks have diff --git a/arch/x86/include/uapi/asm/kvm_para.h b/arch/x86/include/uapi/asm/kvm_para.h index 94dc8ca..ad2e8fe 100644 --- a/arch/x86/include/uapi/asm/kvm_para.h +++ b/arch/x86/include/uapi/asm/kvm_para.h @@ -24,6 +24,7 @@ #define KVM_FEATURE_STEAL_TIME 5 #define KVM_FEATURE_PV_EOI 6 #define KVM_FEATURE_PV_UNHALT 7 +#define KVM_FEATURE_PV_DEDICATED 8 /* The last 8 bits are used to indicate how to interpret the flags field * in pvclock structure. If no bits are set, all flags are ignored. -- 2.7.5