Two patches that cure fallout from commit:
  3cded4179481 ("x86/paravirt: Optimize native
pv_lock_ops.vcpu_is_preempted()")
While chasing a regression I noticed we potentially patch the wrong
code in native_patch().
If we do not select the native code sequence, we must use the default
patcher, not fall-through the switch case.
Fixes: 3cded4179481 ("x86/paravirt: Optimize native
pv_lock_ops.vcpu_is_preempted()")
Signed-off-by: Peter Zijlstra (Intel) <peterz at infradead.org>
---
 arch/x86/kernel/paravirt_patch_32.c |    4 ++++
 arch/x86/kernel/paravirt_patch_64.c |    4 ++++
 2 files changed, 8 insertions(+)
--- a/arch/x86/kernel/paravirt_patch_32.c
+++ b/arch/x86/kernel/paravirt_patch_32.c
@@ -56,15 +56,19 @@ unsigned native_patch(u8 type, u16 clobb
 				end   = end_pv_lock_ops_queued_spin_unlock;
 				goto patch_site;
 			}
+			goto patch_default;
+
 		case PARAVIRT_PATCH(pv_lock_ops.vcpu_is_preempted):
 			if (pv_is_native_vcpu_is_preempted()) {
 				start = start_pv_lock_ops_vcpu_is_preempted;
 				end   = end_pv_lock_ops_vcpu_is_preempted;
 				goto patch_site;
 			}
+			goto patch_default;
 #endif
 
 	default:
+patch_default:
 		ret = paravirt_patch_default(type, clobbers, ibuf, addr, len);
 		break;
 
--- a/arch/x86/kernel/paravirt_patch_64.c
+++ b/arch/x86/kernel/paravirt_patch_64.c
@@ -68,15 +68,19 @@ unsigned native_patch(u8 type, u16 clobb
 				end   = end_pv_lock_ops_queued_spin_unlock;
 				goto patch_site;
 			}
+			goto patch_default;
+
 		case PARAVIRT_PATCH(pv_lock_ops.vcpu_is_preempted):
 			if (pv_is_native_vcpu_is_preempted()) {
 				start = start_pv_lock_ops_vcpu_is_preempted;
 				end   = end_pv_lock_ops_vcpu_is_preempted;
 				goto patch_site;
 			}
+			goto patch_default;
 #endif
 
 	default:
+patch_default:
 		ret = paravirt_patch_default(type, clobbers, ibuf, addr, len);
 		break;
Peter Zijlstra
2016-Dec-08  15:42 UTC
[PATCH 2/2] x86, paravirt: Fix bool return type for PVOP_CALL
Commit 3cded4179481 ("x86/paravirt: Optimize native
pv_lock_ops.vcpu_is_preempted()") introduced a paravirt op with bool
return type [*]
It turns out that the PVOP_CALL*() macros miscompile when rettype is
bool. Code that looked like:
   83 ef 01                sub    $0x1,%edi
   ff 15 32 a0 d8 00       callq  *0xd8a032(%rip)        # ffffffff81e28120
<pv_lock_ops+0x20>
   84 c0                   test   %al,%al
ended up looking like so after PVOP_CALL1() was applied:
   83 ef 01                sub    $0x1,%edi
   48 63 ff                movslq %edi,%rdi
   ff 14 25 20 81 e2 81    callq  *0xffffffff81e28120
   48 85 c0                test   %rax,%rax
Note how it tests the whole of %rax, even though a typical bool return
function only sets %al, like:
  0f 95 c0                setne  %al
  c3                      retq
This is because ____PVOP_CALL() does:
		__ret = (rettype)__eax;
and while regular integer type casts truncate the result, a cast to
bool tests for any !0 value. Fix this by explicitly truncating to
sizeof(rettype) before casting.
[*] The actual bug should've been exposed in commit 446f3dc8cc0a
("locking/core, x86/paravirt: Implement vcpu_is_preempted(cpu) for KVM
and Xen guests") but that didn't properly implement the paravirt call.
Cc: Peter Anvin <hpa at zytor.com>
Cc: Ingo Molnar <mingo at kernel.org>
Cc: Thomas Gleixner <tglx at linutronix.de>
Cc: Borislav Petkov <bp at alien8.de>
Cc: Jeremy Fitzhardinge <jeremy at goop.org>
Cc: Chris Wright <chrisw at sous-sol.org>
Cc: Alok Kataria <akataria at vmware.com>
Cc: Rusty Russell <rusty at rustcorp.com.au>
Cc: virtualization at lists.linux-foundation.org
Cc: Pan Xinhui <xinhui.pan at linux.vnet.ibm.com>
Cc: Paolo Bonzini <pbonzini at redhat.com>
Fixes: 3cded4179481 ("x86/paravirt: Optimize native
pv_lock_ops.vcpu_is_preempted()")
Reported-by: kernel test robot <xiaolong.ye at intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz at infradead.org>
---
 arch/x86/include/asm/paravirt_types.h |   14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)
--- a/arch/x86/include/asm/paravirt_types.h
+++ b/arch/x86/include/asm/paravirt_types.h
@@ -508,6 +508,18 @@ int paravirt_disable_iospace(void);
 #define PVOP_TEST_NULL(op)	((void)op)
 #endif
 
+#define PVOP_RETMASK(rettype)						\
+	({	unsigned long __mask = ~0UL;				\
+		switch (sizeof(rettype)) {				\
+		case 1: __mask =       0xffUL; break;			\
+		case 2: __mask =     0xffffUL; break;			\
+		case 4: __mask = 0xffffffffUL; break;			\
+		default: break;						\
+		}							\
+		__mask;							\
+	})
+
+
 #define ____PVOP_CALL(rettype, op, clbr, call_clbr, extra_clbr,		\
 		      pre, post, ...)					\
 	({								\
@@ -535,7 +547,7 @@ int paravirt_disable_iospace(void);
 				       paravirt_clobber(clbr),		\
 				       ##__VA_ARGS__			\
 				     : "memory", "cc" extra_clbr);	\
-			__ret = (rettype)__eax;				\
+			__ret = (rettype)(__eax & PVOP_RETMASK(rettype));	\
 		}							\
 		__ret;							\
 	})
Pan Xinhui
2016-Dec-08  16:40 UTC
[PATCH 2/2] x86, paravirt: Fix bool return type for PVOP_CALL
hi, Peter
	I think I know the point.
then could we just let __eax rettype(here is bool), not unsigned long?
I does not do tests for my thoughts.
@@ -461,7 +461,9 @@ int paravirt_disable_iospace(void);
  #define PVOP_VCALL_ARGS                                                       
\
         unsigned long __eax = __eax, __edx = __edx, __ecx = __ecx;      \
         register void *__sp asm("esp")
-#define PVOP_CALL_ARGS                 PVOP_VCALL_ARGS
+#define PVOP_CALL_ARGS 					\
+       rettype __eax = __eax, __edx = __edx, __ecx = __ecx;    \
+       register void *__sp asm("esp")
Maybe Matching Threads
- [PATCH 0/2] Fix paravirt fail
- [PATCH 00/13] x86/paravirt: Make pv ops code generation more closely match reality
- [PATCH 00/13] x86/paravirt: Make pv ops code generation more closely match reality
- [PATCH 2/2] x86, paravirt: Fix bool return type for PVOP_CALL
- [PATCH 2/2] x86, paravirt: Fix bool return type for PVOP_CALL