arch/x86/kernel/relocate_kernel_64.o: file format elf64-x86-64 Disassembly of section .text.relocate_kernel: 0000000000000000 : * %rcx preserve_context * %r8 host_mem_enc_active */ /* Save the CPU context, used for jumping back */ pushq %rbx 0: 53 push %rbx pushq %rbp 1: 55 push %rbp pushq %r12 2: 41 54 push %r12 pushq %r13 4: 41 55 push %r13 pushq %r14 6: 41 56 push %r14 pushq %r15 8: 41 57 push %r15 pushf a: 9c pushf /* zero out flags, and disable interrupts */ pushq $0 b: 6a 00 push $0x0 popfq d: 9d popf /* Switch to the identity mapped page tables */ movq %cr3, %rax e: 0f 20 d8 mov %cr3,%rax movq kexec_pa_table_page(%rip), %r9 11: 4c 8b 0d 00 00 00 00 mov 0x0(%rip),%r9 # 18 movq %r9, %cr3 18: 41 0f 22 d9 mov %r9,%cr3 /* Save %rsp and CRs. */ movq %rsp, saved_rsp(%rip) 1c: 48 89 25 00 00 00 00 mov %rsp,0x0(%rip) # 23 movq %rax, saved_cr3(%rip) 23: 48 89 05 00 00 00 00 mov %rax,0x0(%rip) # 2a movq %cr0, %rax 2a: 0f 20 c0 mov %cr0,%rax movq %rax, saved_cr0(%rip) 2d: 48 89 05 00 00 00 00 mov %rax,0x0(%rip) # 34 /* Leave CR4 in %r13 to enable the right paging mode later. */ movq %cr4, %r13 34: 41 0f 20 e5 mov %cr4,%r13 movq %r13, saved_cr4(%rip) 38: 4c 89 2d 00 00 00 00 mov %r13,0x0(%rip) # 3f /* save indirection list for jumping back */ movq %rdi, pa_backup_pages_map(%rip) 3f: 48 89 3d 00 00 00 00 mov %rdi,0x0(%rip) # 46 /* Save the preserve_context to %r11 as swap_pages clobbers %rcx. */ movq %rcx, %r11 46: 49 89 cb mov %rcx,%r11 /* setup a new stack at the end of the physical control page */ lea PAGE_SIZE(%rsi), %rsp 49: 48 8d a6 00 10 00 00 lea 0x1000(%rsi),%rsp /* jump to identity mapped page */ addq $(identity_mapped - relocate_kernel), %rsi 50: 48 81 c6 5a 00 00 00 add $0x5a,%rsi pushq %rsi 57: 56 push %rsi ANNOTATE_UNRET_SAFE ret 58: c3 ret int3 59: cc int3 000000000000005a : * %r11 preserve_context * %r13 original CR4 when relocate_kernel() was invoked */ /* set return address to 0 if not preserving context */ pushq $0 5a: 6a 00 push $0x0 /* store the start address on the stack */ pushq %rdx 5c: 52 push %rdx /* * Clear X86_CR4_CET (if it was set) such that we can clear CR0_WP * below. */ movq %cr4, %rax 5d: 0f 20 e0 mov %cr4,%rax andq $~(X86_CR4_CET), %rax 60: 48 25 ff ff 7f ff and $0xffffffffff7fffff,%rax movq %rax, %cr4 66: 0f 22 e0 mov %rax,%cr4 * - Write protect disabled * - No task switch * - Don't do FP software emulation. * - Protected mode enabled */ movq %cr0, %rax 69: 0f 20 c0 mov %cr0,%rax andq $~(X86_CR0_AM | X86_CR0_WP | X86_CR0_TS | X86_CR0_EM), %rax 6c: 48 25 f3 ff fa ff and $0xfffffffffffafff3,%rax orl $(X86_CR0_PG | X86_CR0_PE), %eax 72: 0d 01 00 00 80 or $0x80000001,%eax movq %rax, %cr0 77: 0f 22 c0 mov %rax,%cr0 * Clearing MCE might not be allowed in TDX guests, depending on setup. * * Use R13 that contains the original CR4 value, read in relocate_kernel(). * PAE is always set in the original CR4. */ andl $(X86_CR4_PAE | X86_CR4_LA57), %r13d 7a: 41 81 e5 20 10 00 00 and $0x1020,%r13d 81: 90 nop 82: 90 nop 83: 90 nop 84: 90 nop ALTERNATIVE "", __stringify(orl $X86_CR4_MCE, %r13d), X86_FEATURE_TDX_GUEST movq %r13, %cr4 85: 41 0f 22 e5 mov %r13,%cr4 /* Flush the TLB (needed?) */ movq %r9, %cr3 89: 41 0f 22 d9 mov %r9,%cr3 /* * If SME is active, there could be old encrypted cache line * entries that will conflict with the now unencrypted memory * used by kexec. Flush the caches before copying the kernel. */ testq %r8, %r8 8d: 4d 85 c0 test %r8,%r8 jz .Lsme_off 90: 74 02 je 94 wbinvd 92: 0f 09 wbinvd .Lsme_off: call swap_pages 94: e8 c0 00 00 00 call 159 * To be certain of avoiding problems with self-modifying code * I need to execute a serializing instruction here. * So I flush the TLB by reloading %cr3 here, it's handy, * and not processor dependent. */ movq %cr3, %rax 99: 0f 20 d8 mov %cr3,%rax movq %rax, %cr3 9c: 0f 22 d8 mov %rax,%cr3 testq %r11, %r11 /* preserve_context */ 9f: 4d 85 db test %r11,%r11 jnz .Lrelocate a2: 75 28 jne cc /* * set all of the registers to known values * leave %rsp alone */ xorl %eax, %eax a4: 31 c0 xor %eax,%eax xorl %ebx, %ebx a6: 31 db xor %ebx,%ebx xorl %ecx, %ecx a8: 31 c9 xor %ecx,%ecx xorl %edx, %edx aa: 31 d2 xor %edx,%edx xorl %esi, %esi ac: 31 f6 xor %esi,%esi xorl %edi, %edi ae: 31 ff xor %edi,%edi xorl %ebp, %ebp b0: 31 ed xor %ebp,%ebp xorl %r8d, %r8d b2: 45 31 c0 xor %r8d,%r8d xorl %r9d, %r9d b5: 45 31 c9 xor %r9d,%r9d xorl %r10d, %r10d b8: 45 31 d2 xor %r10d,%r10d xorl %r11d, %r11d bb: 45 31 db xor %r11d,%r11d xorl %r12d, %r12d be: 45 31 e4 xor %r12d,%r12d xorl %r13d, %r13d c1: 45 31 ed xor %r13d,%r13d xorl %r14d, %r14d c4: 45 31 f6 xor %r14d,%r14d xorl %r15d, %r15d c7: 45 31 ff xor %r15d,%r15d ANNOTATE_UNRET_SAFE ret ca: c3 ret int3 cb: cc int3 .Lrelocate: popq %rdx cc: 5a pop %rdx leaq PAGE_SIZE(%r10), %rsp cd: 49 8d a2 00 10 00 00 lea 0x1000(%r10),%rsp ANNOTATE_RETPOLINE_SAFE call *%rdx d4: ff d2 call *%rdx /* get the re-entry point of the peer system */ movq 0(%rsp), %rbp d6: 48 8b 2c 24 mov (%rsp),%rbp leaq relocate_kernel(%rip), %r8 da: 4c 8d 05 00 00 00 00 lea 0x0(%rip),%r8 # e1 movq kexec_pa_swap_page(%rip), %r10 e1: 4c 8b 15 00 00 00 00 mov 0x0(%rip),%r10 # e8 movq pa_backup_pages_map(%rip), %rdi e8: 48 8b 3d 00 00 00 00 mov 0x0(%rip),%rdi # ef movq kexec_pa_table_page(%rip), %rax ef: 48 8b 05 00 00 00 00 mov 0x0(%rip),%rax # f6 movq %rax, %cr3 f6: 0f 22 d8 mov %rax,%cr3 lea PAGE_SIZE(%r8), %rsp f9: 49 8d a0 00 10 00 00 lea 0x1000(%r8),%rsp call swap_pages 100: e8 54 00 00 00 call 159 movq kexec_va_control_page(%rip), %rax 105: 48 8b 05 00 00 00 00 mov 0x0(%rip),%rax # 10c addq $(virtual_mapped - relocate_kernel), %rax 10c: 48 05 15 01 00 00 add $0x115,%rax pushq %rax 112: 50 push %rax ANNOTATE_UNRET_SAFE ret 113: c3 ret int3 114: cc int3 0000000000000115 : SYM_CODE_END(identity_mapped) SYM_CODE_START_LOCAL_NOALIGN(virtual_mapped) UNWIND_HINT_END_OF_STACK ANNOTATE_NOENDBR // RET target, above movq saved_rsp(%rip), %rsp 115: 48 8b 25 00 00 00 00 mov 0x0(%rip),%rsp # 11c movq saved_cr4(%rip), %rax 11c: 48 8b 05 00 00 00 00 mov 0x0(%rip),%rax # 123 movq %rax, %cr4 123: 0f 22 e0 mov %rax,%cr4 movq saved_cr3(%rip), %rax 126: 48 8b 05 00 00 00 00 mov 0x0(%rip),%rax # 12d movq saved_cr0(%rip), %r8 12d: 4c 8b 05 00 00 00 00 mov 0x0(%rip),%r8 # 134 movq %rax, %cr3 134: 0f 22 d8 mov %rax,%cr3 movq %r8, %cr0 137: 41 0f 22 c0 mov %r8,%cr0 #ifdef CONFIG_KEXEC_JUMP /* Saved in save_processor_state. */ movq $saved_context, %rax 13b: 48 c7 c0 00 00 00 00 mov $0x0,%rax lgdt saved_context_gdt_desc(%rax) 142: 0f 01 90 0a 01 00 00 lgdt 0x10a(%rax) #endif movq %rbp, %rax 149: 48 89 e8 mov %rbp,%rax popf 14c: 9d popf popq %r15 14d: 41 5f pop %r15 popq %r14 14f: 41 5e pop %r14 popq %r13 151: 41 5d pop %r13 popq %r12 153: 41 5c pop %r12 popq %rbp 155: 5d pop %rbp popq %rbx 156: 5b pop %rbx ANNOTATE_UNRET_SAFE ret 157: c3 ret int3 158: cc int3 0000000000000159 : SYM_CODE_END(virtual_mapped) /* Do the copies */ SYM_CODE_START_LOCAL_NOALIGN(swap_pages) UNWIND_HINT_END_OF_STACK movq %rdi, %rcx /* Put the indirection_page in %rcx */ 159: 48 89 f9 mov %rdi,%rcx xorl %edi, %edi 15c: 31 ff xor %edi,%edi xorl %esi, %esi 15e: 31 f6 xor %esi,%esi jmp .Lstart /* Should start with an indirection record */ 160: eb 07 jmp 169 .Lloop: /* top, read another word for the indirection page */ movq (%rbx), %rcx 162: 48 8b 0b mov (%rbx),%rcx addq $8, %rbx 165: 48 83 c3 08 add $0x8,%rbx .Lstart: testb $0x1, %cl /* is it a destination page? */ 169: f6 c1 01 test $0x1,%cl jz .Lnotdest 16c: 74 0c je 17a movq %rcx, %rdi 16e: 48 89 cf mov %rcx,%rdi andq $0xfffffffffffff000, %rdi 171: 48 81 e7 00 f0 ff ff and $0xfffffffffffff000,%rdi jmp .Lloop 178: eb e8 jmp 162 .Lnotdest: testb $0x2, %cl /* is it an indirection page? */ 17a: f6 c1 02 test $0x2,%cl jz .Lnotind 17d: 74 0c je 18b movq %rcx, %rbx 17f: 48 89 cb mov %rcx,%rbx andq $0xfffffffffffff000, %rbx 182: 48 81 e3 00 f0 ff ff and $0xfffffffffffff000,%rbx jmp .Lloop 189: eb d7 jmp 162 .Lnotind: testb $0x4, %cl /* is it the done indicator? */ 18b: f6 c1 04 test $0x4,%cl jz .Lnotdone 18e: 74 02 je 192 jmp .Ldone 190: eb 4a jmp 1dc .Lnotdone: testb $0x8, %cl /* is it the source indicator? */ 192: f6 c1 08 test $0x8,%cl jz .Lloop /* Ignore it otherwise */ 195: 74 cb je 162 movq %rcx, %rsi /* For ever source page do a copy */ 197: 48 89 ce mov %rcx,%rsi andq $0xfffffffffffff000, %rsi 19a: 48 81 e6 00 f0 ff ff and $0xfffffffffffff000,%rsi movq %rdi, %rdx /* Save destination page to %rdx */ 1a1: 48 89 fa mov %rdi,%rdx movq %rsi, %rax /* Save source page to %rax */ 1a4: 48 89 f0 mov %rsi,%rax testq %r11, %r11 /* Only actually swap for ::preserve_context */ 1a7: 4d 85 db test %r11,%r11 jz .Lnoswap 1aa: 74 1f je 1cb /* copy source page to swap page */ movq %r10, %rdi 1ac: 4c 89 d7 mov %r10,%rdi movl $512, %ecx 1af: b9 00 02 00 00 mov $0x200,%ecx rep ; movsq 1b4: f3 48 a5 rep movsq %ds:(%rsi),%es:(%rdi) /* copy destination page to source page */ movq %rax, %rdi 1b7: 48 89 c7 mov %rax,%rdi movq %rdx, %rsi 1ba: 48 89 d6 mov %rdx,%rsi movl $512, %ecx 1bd: b9 00 02 00 00 mov $0x200,%ecx rep ; movsq 1c2: f3 48 a5 rep movsq %ds:(%rsi),%es:(%rdi) /* copy swap page to destination page */ movq %rdx, %rdi 1c5: 48 89 d7 mov %rdx,%rdi movq %r10, %rsi 1c8: 4c 89 d6 mov %r10,%rsi .Lnoswap: movl $512, %ecx 1cb: b9 00 02 00 00 mov $0x200,%ecx rep ; movsq 1d0: f3 48 a5 rep movsq %ds:(%rsi),%es:(%rdi) lea PAGE_SIZE(%rax), %rsi 1d3: 48 8d b0 00 10 00 00 lea 0x1000(%rax),%rsi jmp .Lloop 1da: eb 86 jmp 162 .Ldone: ANNOTATE_UNRET_SAFE ret 1dc: c3 ret int3 1dd: cc int3 Disassembly of section .altinstr_replacement: 0000000000000000 <.altinstr_replacement>: ALTERNATIVE "", __stringify(orl $X86_CR4_MCE, %r13d), X86_FEATURE_TDX_GUEST 0: 41 83 cd 40 or $0x40,%r13d