diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index f7df49d..c98d9c7 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -3275,6 +3275,13 @@
 			[KNL] Number of legacy pty's. Overwrites compiled-in
 			default number.
 
+	pvlock_type=	[X86,PV_OPS]
+			Specify the paravirt spinlock type to be used.
+			Options are:
+			queued - native queued spinlock
+			pv     - paravirt queued spinlock
+			unfair - simple TATAS unfair lock
+
 	quiet		[KNL] Disable most log messages
 
 	r128=		[HW,DRM]
diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h
index 12deec7..941a046 100644
--- a/arch/x86/include/asm/paravirt.h
+++ b/arch/x86/include/asm/paravirt.h
@@ -690,6 +690,15 @@ static __always_inline bool pv_vcpu_is_preempted(long cpu)
 
 #endif /* SMP && PARAVIRT_SPINLOCKS */
 
+enum pv_spinlock_type {
+	locktype_auto,
+	locktype_queued,
+	locktype_paravirt,
+	locktype_unfair,
+};
+
+extern enum pv_spinlock_type pv_spinlock_type;
+
 #ifdef CONFIG_X86_32
 #define PV_SAVE_REGS "pushl %ecx; pushl %edx;"
 #define PV_RESTORE_REGS "popl %edx; popl %ecx;"
diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c
index 8bb9594..3a5d3ec4 100644
--- a/arch/x86/kernel/kvm.c
+++ b/arch/x86/kernel/kvm.c
@@ -646,6 +646,10 @@ void __init kvm_spinlock_init(void)
 	if (!kvm_para_has_feature(KVM_FEATURE_PV_UNHALT))
 		return;
 
+	if ((pv_spinlock_type == locktype_queued) ||
+	    (pv_spinlock_type == locktype_unfair))
+		return;
+
 	__pv_init_lock_hash();
 	pv_lock_ops.queued_spin_lock_slowpath = __pv_queued_spin_lock_slowpath;
 	pv_lock_ops.queued_spin_unlock = PV_CALLEE_SAVE(__pv_queued_spin_unlock);
diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c
index 041096b..ca35cd3 100644
--- a/arch/x86/kernel/paravirt.c
+++ b/arch/x86/kernel/paravirt.c
@@ -115,11 +115,48 @@ unsigned paravirt_patch_jmp(void *insnbuf, const void *target,
 	return 5;
 }
 
+/*
+ * The kernel argument "pvlock_type=" can be used to explicitly specify
+ * which type of spinlocks to be used. Currently, there are 3 options:
+ * 1) queued - the native queued spinlock
+ * 2) pv     - the paravirt queued spinlock (if CONFIG_PARAVIRT_SPINLOCKS)
+ * 3) unfair - the simple TATAS unfair lock
+ *
+ * If this argument is not specified, the kernel will automatically choose
+ * an appropriate one depending on X86_FEATURE_HYPERVISOR and hypervisor
+ * specific settings.
+ */
+enum pv_spinlock_type __read_mostly pv_spinlock_type = locktype_auto;
+
+static int __init pvlock_setup(char *s)
+{
+	if (!s)
+		return -EINVAL;
+
+	if (!strcmp(s, "queued"))
+		pv_spinlock_type = locktype_queued;
+	else if (!strcmp(s, "pv"))
+		pv_spinlock_type = locktype_paravirt;
+	else if (!strcmp(s, "unfair"))
+		pv_spinlock_type = locktype_unfair;
+	else
+		return -EINVAL;
+
+	pr_info("PV lock type = %s (%d)\n", s, pv_spinlock_type);
+	return 0;
+}
+
+early_param("pvlock_type", pvlock_setup);
+
 DEFINE_STATIC_KEY_TRUE(virt_spin_lock_key);
 
 void __init native_pv_lock_init(void)
 {
-	if (!static_cpu_has(X86_FEATURE_HYPERVISOR))
+	if (pv_spinlock_type == locktype_unfair)
+		return;
+
+	if (!static_cpu_has(X86_FEATURE_HYPERVISOR) ||
+	   (pv_spinlock_type != locktype_auto))
 		static_branch_disable(&virt_spin_lock_key);
 }
 
@@ -473,3 +510,4 @@ struct pv_mmu_ops pv_mmu_ops __ro_after_init = {
 EXPORT_SYMBOL    (pv_mmu_ops);
 EXPORT_SYMBOL_GPL(pv_info);
 EXPORT_SYMBOL    (pv_irq_ops);
+EXPORT_SYMBOL    (pv_spinlock_type);
diff --git a/arch/x86/xen/spinlock.c b/arch/x86/xen/spinlock.c
index 1e1462d..9fc8eab 100644
--- a/arch/x86/xen/spinlock.c
+++ b/arch/x86/xen/spinlock.c
@@ -82,7 +82,7 @@ void xen_init_lock_cpu(int cpu)
 	char *name;
 
 	if (!xen_pvspin) {
-		if (cpu == 0)
+		if ((cpu == 0) && (pv_spinlock_type == locktype_auto))
 			static_branch_disable(&virt_spin_lock_key);
 		return;
 	}
@@ -130,8 +130,8 @@ void xen_uninit_lock_cpu(int cpu)
  */
 void __init xen_init_spinlocks(void)
 {
-
-	if (!xen_pvspin) {
+	if (!xen_pvspin || (pv_spinlock_type == locktype_queued) ||
+			   (pv_spinlock_type == locktype_unfair)) {
 		printk(KERN_DEBUG "xen: PV spinlocks disabled\n");
 		return;
 	}
