Skip to content

Commit e536057

Browse files
dwmw2bp3tk0v
authored andcommitted
x86/kexec: Cope with relocate_kernel() not being at the start of the page
A few places in the kexec control code page make the assumption that the first instruction of relocate_kernel is at the very start of the page. To allow for Clang CFI information to be added to relocate_kernel(), as well as the general principle of removing unwarranted assumptions, fix them to use the external __relocate_kernel_start symbol that the linker adds. This means using a separate addq and subq for calculating offsets, as the assembler can no longer calculate the delta directly for itself and relocations aren't that versatile. But those values can at least be used relative to a local label to avoid absolute relocations. Turn the jump from relocate_kernel() to identity_mapped() into a real indirect 'jmp *%rsi' too, while touching it. There was no real reason for it to be a push+ret in the first place, and adding Clang CFI info will also give objtool enough visibility to start complaining 'return with modified stack frame' about it. [ bp: Massage commit message. ] Signed-off-by: David Woodhouse <[email protected]> Signed-off-by: Borislav Petkov (AMD) <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent dc6ffa6 commit e536057

File tree

1 file changed

+11
-7
lines changed

1 file changed

+11
-7
lines changed

arch/x86/kernel/relocate_kernel_64.S

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -95,11 +95,10 @@ SYM_CODE_START_NOALIGN(relocate_kernel)
9595
lea PAGE_SIZE(%rsi), %rsp
9696

9797
/* jump to identity mapped page */
98-
addq $(identity_mapped - relocate_kernel), %rsi
99-
pushq %rsi
100-
ANNOTATE_UNRET_SAFE
101-
ret
102-
int3
98+
0: addq $identity_mapped - 0b, %rsi
99+
subq $__relocate_kernel_start - 0b, %rsi
100+
ANNOTATE_RETPOLINE_SAFE
101+
jmp *%rsi
103102
SYM_CODE_END(relocate_kernel)
104103

105104
SYM_CODE_START_LOCAL_NOALIGN(identity_mapped)
@@ -219,16 +218,21 @@ SYM_CODE_START_LOCAL_NOALIGN(identity_mapped)
219218

220219
/* get the re-entry point of the peer system */
221220
popq %rbp
222-
leaq relocate_kernel(%rip), %r8
223221
movq kexec_pa_swap_page(%rip), %r10
224222
movq pa_backup_pages_map(%rip), %rdi
225223
movq kexec_pa_table_page(%rip), %rax
226224
movq %rax, %cr3
225+
226+
/* Find start (and end) of this physical mapping of control page */
227+
leaq (%rip), %r8
228+
ANNOTATE_NOENDBR
229+
andq $PAGE_MASK, %r8
227230
lea PAGE_SIZE(%r8), %rsp
228231
movl $1, %r11d /* Ensure preserve_context flag is set */
229232
call swap_pages
230233
movq kexec_va_control_page(%rip), %rax
231-
addq $(virtual_mapped - relocate_kernel), %rax
234+
0: addq $virtual_mapped - 0b, %rax
235+
subq $__relocate_kernel_start - 0b, %rax
232236
pushq %rax
233237
ANNOTATE_UNRET_SAFE
234238
ret

0 commit comments

Comments
 (0)