[PATCH v5 03/10] x86/asm/entry: Fix asmvalidate warnings for entry_64_compat.S

Josh Poimboeuf
2015-06-10T12:07:34Z

Fix the following asmvalidate warnings:

asmvalidate: arch/x86/entry/entry_64_compat.o: native_usergs_sysret32(): unsupported fallthrough at end of function
asmvalidate: arch/x86/entry/entry_64_compat.o: entry_SYSENTER_compat()+0xcf: unsupported jump to outside of function
asmvalidate: arch/x86/entry/entry_64_compat.o: entry_SYSENTER_compat()+0x113: unsupported jump to outside of function
asmvalidate: arch/x86/entry/entry_64_compat.o: entry_SYSENTER_compat()+0x16d: unsupported jump to outside of function
asmvalidate: arch/x86/entry/entry_64_compat.o: entry_SYSENTER_compat(): missing FP_SAVE/RESTORE macros
asmvalidate: arch/x86/entry/entry_64_compat.o: .entry.text+0x56e: return instruction outside of a function

1. native_usergs_sysret32 is redirected to from a jump rather than a
call, so it shouldn't be annotated as a function. Change ENDPROC ->
END accordingly.

2. Ditto for entry_SYSENTER_compat.

3. The stub functions can be called, so annotate them as functions with
ENTRY/ENDPROC.

4. The stub functions aren't leaf functions, so save/restore the frame
pointer with FP_SAVE/RESTORE.

5. The stub functions all jump outside of their respective functions'
boundaries to the ia32_ptregs_common label. Change them to be
self-contained so they stay within their boundaries.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
---
arch/x86/entry/entry_64_compat.S | 35 +++++++++++++++++++----------------
arch/x86/include/asm/func.h | 6 ++++++
2 files changed, 25 insertions(+), 16 deletions(-)

diff --git a/arch/x86/entry/entry_64_compat.S b/arch/x86/entry/entry_64_compat.S
index bb187a6..07f5ae8 100644
--- a/arch/x86/entry/entry_64_compat.S
+++ b/arch/x86/entry/entry_64_compat.S
@@ -13,6 +13,7 @@
#include <asm/irqflags.h>
#include <asm/asm.h>
#include <asm/smap.h>
+#include <asm/func.h>
#include <linux/linkage.h>
#include <linux/err.h>

@@ -32,7 +33,7 @@
ENTRY(native_usergs_sysret32)
swapgs
sysretl
-ENDPROC(native_usergs_sysret32)
+END(native_usergs_sysret32)
#endif

/*
@@ -270,7 +271,7 @@ sysenter_tracesys:

RESTORE_EXTRA_REGS
jmp sysenter_do_call
-ENDPROC(entry_SYSENTER_compat)
+END(entry_SYSENTER_compat)

/*
* 32-bit SYSCALL instruction entry.
@@ -523,10 +524,15 @@ ia32_tracesys:
END(entry_INT80_compat)

.macro PTREGSCALL label, func
- ALIGN
-GLOBAL(\label)
- leaq \func(%rip), %rax
- jmp ia32_ptregs_common
+ENTRY(\label)
+ FP_SAVE
+ leaq \func(%rip),%rax
+ SAVE_EXTRA_REGS(8+FP_SIZE)
+ call *%rax
+ RESTORE_EXTRA_REGS(8+FP_SIZE)
+ FP_RESTORE
+ ret
+ENDPROC(\label)
.endm

PTREGSCALL stub32_rt_sigreturn, sys32_rt_sigreturn
@@ -534,9 +540,9 @@ GLOBAL(\label)
PTREGSCALL stub32_fork, sys_fork
PTREGSCALL stub32_vfork, sys_vfork

- ALIGN
-GLOBAL(stub32_clone)
- leaq sys_clone(%rip), %rax
+ENTRY(stub32_clone)
+ FP_SAVE
+ leaq sys_clone(%rip),%rax
/*
* The 32-bit clone ABI is: clone(..., int tls_val, int *child_tidptr).
* The 64-bit clone ABI is: clone(..., int *child_tidptr, int tls_val).
@@ -545,12 +551,9 @@ GLOBAL(stub32_clone)
* so we need to swap arguments here before calling it:
*/
xchg %r8, %rcx
- jmp ia32_ptregs_common
-
- ALIGN
-ia32_ptregs_common:
- SAVE_EXTRA_REGS 8
+ SAVE_EXTRA_REGS(8+FP_SIZE)
call *%rax
- RESTORE_EXTRA_REGS 8
+ RESTORE_EXTRA_REGS(8+FP_SIZE)
+ FP_RESTORE
ret
-END(ia32_ptregs_common)
+ENDPROC(stub32_clone)
diff --git a/arch/x86/include/asm/func.h b/arch/x86/include/asm/func.h
index 52b3225..1d923bd 100644
--- a/arch/x86/include/asm/func.h
+++ b/arch/x86/include/asm/func.h
@@ -37,6 +37,12 @@
.endif
.endm

+#ifdef CONFIG_FRAME_POINTER
+#define FP_SIZE __ASM_SEL(4, 8)
+#else
+#define FP_SIZE 0
+#endif
+
/*
* This macro tells the asm validation script to ignore the instruction
* immediately after the macro. It should only be used in special cases where
--
2.1.0