x86/power: Move restore_registers() to top of the file
Because restore_registers() is page-aligned, the assembler inexplicably adds an unreachable jump from after the end of the previous function to the beginning of restore_registers(). That confuses objtool, understandably. It also creates significant text fragmentation. As a result, most of the object file is wasted text (nops). Move restore_registers() to the beginning of the file to both prevent the text fragmentation and avoid the dead jump instruction. $ size /tmp/hibernate_asm_64.before.o /tmp/hibernate_asm_64.after.o text data bss dec hex filename 4415 0 0 4415 113f /tmp/hibernate_asm_64.before.o 524 0 0 524 20c /tmp/hibernate_asm_64.after.o Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net> Cc: Pavel Machek <pavel@ucw.cz> Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com> Link: https://lore.kernel.org/r/8c7f634201d26453d73fe55032cbbdc05d004387.1611263462.git.jpoimboe@redhat.com
This commit is contained in:
parent
b682369d47
commit
125f0b7d24
|
@ -23,6 +23,52 @@
|
|||
#include <asm/frame.h>
|
||||
#include <asm/nospec-branch.h>
|
||||
|
||||
/* code below belongs to the image kernel */
|
||||
.align PAGE_SIZE
|
||||
SYM_FUNC_START(restore_registers)
|
||||
/* go back to the original page tables */
|
||||
movq %r9, %cr3
|
||||
|
||||
/* Flush TLB, including "global" things (vmalloc) */
|
||||
movq mmu_cr4_features(%rip), %rax
|
||||
movq %rax, %rdx
|
||||
andq $~(X86_CR4_PGE), %rdx
|
||||
movq %rdx, %cr4; # turn off PGE
|
||||
movq %cr3, %rcx; # flush TLB
|
||||
movq %rcx, %cr3
|
||||
movq %rax, %cr4; # turn PGE back on
|
||||
|
||||
/* We don't restore %rax, it must be 0 anyway */
|
||||
movq $saved_context, %rax
|
||||
movq pt_regs_sp(%rax), %rsp
|
||||
movq pt_regs_bp(%rax), %rbp
|
||||
movq pt_regs_si(%rax), %rsi
|
||||
movq pt_regs_di(%rax), %rdi
|
||||
movq pt_regs_bx(%rax), %rbx
|
||||
movq pt_regs_cx(%rax), %rcx
|
||||
movq pt_regs_dx(%rax), %rdx
|
||||
movq pt_regs_r8(%rax), %r8
|
||||
movq pt_regs_r9(%rax), %r9
|
||||
movq pt_regs_r10(%rax), %r10
|
||||
movq pt_regs_r11(%rax), %r11
|
||||
movq pt_regs_r12(%rax), %r12
|
||||
movq pt_regs_r13(%rax), %r13
|
||||
movq pt_regs_r14(%rax), %r14
|
||||
movq pt_regs_r15(%rax), %r15
|
||||
pushq pt_regs_flags(%rax)
|
||||
popfq
|
||||
|
||||
/* Saved in save_processor_state. */
|
||||
lgdt saved_context_gdt_desc(%rax)
|
||||
|
||||
xorl %eax, %eax
|
||||
|
||||
/* tell the hibernation core that we've just restored the memory */
|
||||
movq %rax, in_suspend(%rip)
|
||||
|
||||
ret
|
||||
SYM_FUNC_END(restore_registers)
|
||||
|
||||
SYM_FUNC_START(swsusp_arch_suspend)
|
||||
movq $saved_context, %rax
|
||||
movq %rsp, pt_regs_sp(%rax)
|
||||
|
@ -102,49 +148,3 @@ SYM_CODE_START(core_restore_code)
|
|||
ANNOTATE_RETPOLINE_SAFE
|
||||
jmpq *%r8
|
||||
SYM_CODE_END(core_restore_code)
|
||||
|
||||
/* code below belongs to the image kernel */
|
||||
.align PAGE_SIZE
|
||||
SYM_FUNC_START(restore_registers)
|
||||
/* go back to the original page tables */
|
||||
movq %r9, %cr3
|
||||
|
||||
/* Flush TLB, including "global" things (vmalloc) */
|
||||
movq mmu_cr4_features(%rip), %rax
|
||||
movq %rax, %rdx
|
||||
andq $~(X86_CR4_PGE), %rdx
|
||||
movq %rdx, %cr4; # turn off PGE
|
||||
movq %cr3, %rcx; # flush TLB
|
||||
movq %rcx, %cr3
|
||||
movq %rax, %cr4; # turn PGE back on
|
||||
|
||||
/* We don't restore %rax, it must be 0 anyway */
|
||||
movq $saved_context, %rax
|
||||
movq pt_regs_sp(%rax), %rsp
|
||||
movq pt_regs_bp(%rax), %rbp
|
||||
movq pt_regs_si(%rax), %rsi
|
||||
movq pt_regs_di(%rax), %rdi
|
||||
movq pt_regs_bx(%rax), %rbx
|
||||
movq pt_regs_cx(%rax), %rcx
|
||||
movq pt_regs_dx(%rax), %rdx
|
||||
movq pt_regs_r8(%rax), %r8
|
||||
movq pt_regs_r9(%rax), %r9
|
||||
movq pt_regs_r10(%rax), %r10
|
||||
movq pt_regs_r11(%rax), %r11
|
||||
movq pt_regs_r12(%rax), %r12
|
||||
movq pt_regs_r13(%rax), %r13
|
||||
movq pt_regs_r14(%rax), %r14
|
||||
movq pt_regs_r15(%rax), %r15
|
||||
pushq pt_regs_flags(%rax)
|
||||
popfq
|
||||
|
||||
/* Saved in save_processor_state. */
|
||||
lgdt saved_context_gdt_desc(%rax)
|
||||
|
||||
xorl %eax, %eax
|
||||
|
||||
/* tell the hibernation core that we've just restored the memory */
|
||||
movq %rax, in_suspend(%rip)
|
||||
|
||||
ret
|
||||
SYM_FUNC_END(restore_registers)
|
||||
|
|
Loading…
Reference in New Issue