[PATCH V5 3/7] x86/entry: Move PUSH_AND_CLEAR_REGS out of error_entry()

From: Lai Jiangshan
Date: Tue Apr 12 2022 - 08:52:43 EST


From: Lai Jiangshan <jiangshan.ljs@xxxxxxxxxxxx>

error_entry() doesn't handle the stack balanced. It includes
PUSH_AND_CLEAR_REGS which is commonly needed for all IDT entries and
can't pop the regs before it returns.

Move PUSH_AND_CLEAR_REGS out of error_entry() and make error_entry()
works on the stack normally.

After this, XENPV doesn't need error_entry() since PUSH_AND_CLEAR_REGS
is moved out and error_entry() can be converted to C code in future
since it doesn't fiddle the stack.

The text size will be enlarged:

size arch/x86/entry/entry_64.o.before:
text data bss dec hex filename
17916 384 0 18300 477c arch/x86/entry/entry_64.o

size --format=SysV arch/x86/entry/entry_64.o.before:
.entry.text 5528 0
.orc_unwind 6456 0
.orc_unwind_ip 4304 0

size arch/x86/entry/entry_64.o.after:
text data bss dec hex filename
26868 384 0 27252 6a74 arch/x86/entry/entry_64.o

size --format=SysV arch/x86/entry/entry_64.o.after:
.entry.text 8200 0
.orc_unwind 10224 0
.orc_unwind_ip 6816 0

The tables .orc_unwind[_ip] are enlarged due to it adds many pushes.

But .entry.text in x86_64 is 2M aligned, enlarging it to 8.2k doesn't
enlarge the final text size.

And it will only increase the footprint when different interrupts and
exceptions happen unlikely heavily at the same time.

Signed-off-by: Lai Jiangshan <jiangshan.ljs@xxxxxxxxxxxx>
---
arch/x86/entry/entry_64.S | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
index e1efc56fbcd4..835b798556fb 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -325,6 +325,9 @@ SYM_CODE_END(ret_from_fork)
*/
.macro idtentry_body cfunc has_error_code:req

+ PUSH_AND_CLEAR_REGS
+ ENCODE_FRAME_POINTER
+
call error_entry
movq %rax, %rsp /* switch to the task stack if from userspace */
ENCODE_FRAME_POINTER
@@ -987,8 +990,6 @@ SYM_CODE_END(paranoid_exit)
SYM_CODE_START_LOCAL(error_entry)
UNWIND_HINT_FUNC
cld
- PUSH_AND_CLEAR_REGS save_ret=1
- ENCODE_FRAME_POINTER 8
testb $3, CS+8(%rsp)
jz .Lerror_kernelspace

--
2.19.1.6.gb485710b