2323#define PAGE_ATTR (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY)
2424
2525/*
26- * control_page + KEXEC_CONTROL_CODE_MAX_SIZE
27- * ~ control_page + PAGE_SIZE are used as data storage and stack for
28- * jumping back
26+ * The .text.relocate_kernel and .data.relocate_kernel sections are copied
27+ * into the control page, and the remainder of the page is used as the stack.
2928 */
30- #define DATA(offset) (KEXEC_CONTROL_CODE_MAX_SIZE+(offset))
3129
30+ .section .data .relocate_kernel,"a" ;
3231/* Minimal CPU state */
33- #define RSP DATA(0x0 )
34- #define CR0 DATA(0x8 )
35- #define CR3 DATA(0x10 )
36- #define CR4 DATA(0x18 )
37-
38- /* other data */
39- #define CP_PA_TABLE_PAGE DATA(0x20 )
40- #define CP_PA_SWAP_PAGE DATA(0x28 )
41- #define CP_PA_BACKUP_PAGES_MAP DATA(0x30 )
42- #define CP_VA_CONTROL_PAGE DATA(0x38 )
32+ SYM_DATA_LOCAL (saved_rsp, .quad 0 )
33+ SYM_DATA_LOCAL (saved_cr0, .quad 0 )
34+ SYM_DATA_LOCAL (saved_cr3, .quad 0 )
35+ SYM_DATA_LOCAL (saved_cr4, .quad 0 )
36+ /* other data */
37+ SYM_DATA_LOCAL (va_control_page, .quad 0 )
38+ SYM_DATA_LOCAL (pa_table_page, .quad 0 )
39+ SYM_DATA_LOCAL (pa_swap_page, .quad 0 )
40+ SYM_DATA_LOCAL (pa_backup_pages_map, .quad 0 )
4341
4442 .section .text .relocate_kernel,"ax" ;
4543 .code64
@@ -63,14 +61,13 @@ SYM_CODE_START_NOALIGN(relocate_kernel)
6361 pushq %r15
6462 pushf
6563
66- movq PTR(VA_CONTROL_PAGE)(%rsi ), %r11
67- movq %rsp , RSP(%r11 )
64+ movq %rsp , saved_rsp(%rip )
6865 movq %cr0 , %rax
69- movq %rax , CR0( %r11 )
66+ movq %rax , saved_cr0( %rip )
7067 movq %cr3 , %rax
71- movq %rax , CR3( %r11 )
68+ movq %rax , saved_cr3( %rip )
7269 movq %cr4 , %rax
73- movq %rax , CR4( %r11 )
70+ movq %rax , saved_cr4( %rip )
7471
7572 /* Save CR4. Required to enable the right paging mode later. */
7673 movq %rax , %r13
@@ -83,10 +80,11 @@ SYM_CODE_START_NOALIGN(relocate_kernel)
8380 movq %r8 , %r12
8481
8582 /*
86- * get physical address of control page now
83+ * get physical and virtual address of control page now
8784 * this is impossible after page table switch
8885 */
8986 movq PTR(PA_CONTROL_PAGE)(%rsi ), %r8
87+ movq PTR(VA_CONTROL_PAGE)(%rsi ), %r11
9088
9189 /* get physical address of page table now too */
9290 movq PTR(PA_TABLE_PAGE)(%rsi ), %r9
@@ -95,10 +93,10 @@ SYM_CODE_START_NOALIGN(relocate_kernel)
9593 movq PTR(PA_SWAP_PAGE)(%rsi ), %r10
9694
9795 /* save some information for jumping back */
98- movq %r9 , CP_PA_TABLE_PAGE( %r11 )
99- movq %r10 , CP_PA_SWAP_PAGE( %r11 )
100- movq %rdi , CP_PA_BACKUP_PAGES_MAP( %r11 )
101- movq %r11 , CP_VA_CONTROL_PAGE( %r11 )
96+ movq %r9 , pa_table_page( %rip )
97+ movq %r10 , pa_swap_page( %rip )
98+ movq %rdi , pa_backup_pages_map( %rip )
99+ movq %r11 , va_control_page( %rip )
102100
103101 /* Save the preserve_context to %r11 as swap_pages clobbers %rcx. */
104102 movq %rcx , %r11
@@ -229,13 +227,13 @@ SYM_CODE_START_LOCAL_NOALIGN(identity_mapped)
229227 /* get the re-entry point of the peer system */
230228 movq 0 (%rsp ), %rbp
231229 leaq relocate_kernel(%rip ), %r8
232- movq CP_PA_SWAP_PAGE( %r8 ), %r10
233- movq CP_PA_BACKUP_PAGES_MAP( %r8 ), %rdi
234- movq CP_PA_TABLE_PAGE( %r8 ), %rax
230+ movq pa_swap_page( %rip ), %r10
231+ movq pa_backup_pages_map( %rip ), %rdi
232+ movq pa_table_page( %rip ), %rax
235233 movq %rax , %cr3
236234 lea PAGE_SIZE(%r8 ), %rsp
237235 call swap_pages
238- movq CP_VA_CONTROL_PAGE( %r8 ), %rax
236+ movq va_control_page( %rip ), %rax
239237 addq $(virtual_mapped - relocate_kernel), %rax
240238 pushq %rax
241239 ANNOTATE_UNRET_SAFE
@@ -246,11 +244,11 @@ SYM_CODE_END(identity_mapped)
246244SYM_CODE_START_LOCAL_NOALIGN(virtual_mapped)
247245 UNWIND_HINT_END_OF_STACK
248246 ANNOTATE_NOENDBR // RET target, above
249- movq RSP( %r8 ), %rsp
250- movq CR4( %r8 ), %rax
247+ movq saved_rsp( %rip ), %rsp
248+ movq saved_cr4( %rip ), %rax
251249 movq %rax , %cr4
252- movq CR3( %r8 ), %rax
253- movq CR0( %r8 ), %r8
250+ movq saved_cr3( %rip ), %rax
251+ movq saved_cr0( %rip ), %r8
254252 movq %rax , %cr3
255253 movq %r8 , %cr0
256254
0 commit comments