| 1 | /* SPDX-License-Identifier: GPL-2.0-only */ | 
|---|
| 2 | .text | 
|---|
| 3 | #include <linux/linkage.h> | 
|---|
| 4 | #include <linux/objtool.h> | 
|---|
| 5 | #include <asm/segment.h> | 
|---|
| 6 | #include <asm/pgtable_types.h> | 
|---|
| 7 | #include <asm/page_types.h> | 
|---|
| 8 | #include <asm/msr.h> | 
|---|
| 9 | #include <asm/asm-offsets.h> | 
|---|
| 10 | #include <asm/frame.h> | 
|---|
| 11 | #include <asm/nospec-branch.h> | 
|---|
| 12 |  | 
|---|
| 13 | # Copyright 2003 Pavel Machek <pavel@suse.cz | 
|---|
| 14 |  | 
|---|
| 15 | .code64 | 
|---|
| 16 | /* | 
|---|
| 17 | * Hooray, we are in Long 64-bit mode (but still running in low memory) | 
|---|
| 18 | */ | 
|---|
| 19 | SYM_FUNC_START(wakeup_long64) | 
|---|
| 20 | ANNOTATE_NOENDBR | 
|---|
| 21 | movq	saved_magic(%rip), %rax | 
|---|
| 22 | movq	$0x123456789abcdef0, %rdx | 
|---|
| 23 | cmpq	%rdx, %rax | 
|---|
| 24 | je	2f | 
|---|
| 25 |  | 
|---|
| 26 | /* stop here on a saved_magic mismatch */ | 
|---|
| 27 | movq $0xbad6d61676963, %rcx | 
|---|
| 28 | 1: | 
|---|
| 29 | jmp 1b | 
|---|
| 30 | 2: | 
|---|
| 31 | movw	$__KERNEL_DS, %ax | 
|---|
| 32 | movw	%ax, %ss | 
|---|
| 33 | movw	%ax, %ds | 
|---|
| 34 | movw	%ax, %es | 
|---|
| 35 | movw	%ax, %fs | 
|---|
| 36 | movw	%ax, %gs | 
|---|
| 37 | movq	saved_rsp(%rip), %rsp | 
|---|
| 38 |  | 
|---|
| 39 | movq	saved_rbx(%rip), %rbx | 
|---|
| 40 | movq	saved_rdi(%rip), %rdi | 
|---|
| 41 | movq	saved_rsi(%rip), %rsi | 
|---|
| 42 | movq	saved_rbp(%rip), %rbp | 
|---|
| 43 |  | 
|---|
| 44 | movq	saved_rip(%rip), %rax | 
|---|
| 45 | ANNOTATE_RETPOLINE_SAFE | 
|---|
| 46 | jmp	*%rax | 
|---|
| 47 | SYM_FUNC_END(wakeup_long64) | 
|---|
| 48 |  | 
|---|
| 49 | SYM_FUNC_START(do_suspend_lowlevel) | 
|---|
| 50 | FRAME_BEGIN | 
|---|
| 51 | subq	$8, %rsp | 
|---|
| 52 | xorl	%eax, %eax | 
|---|
| 53 | call	save_processor_state | 
|---|
| 54 |  | 
|---|
| 55 | movq	$saved_context, %rax | 
|---|
| 56 | movq	%rsp, pt_regs_sp(%rax) | 
|---|
| 57 | movq	%rbp, pt_regs_bp(%rax) | 
|---|
| 58 | movq	%rsi, pt_regs_si(%rax) | 
|---|
| 59 | movq	%rdi, pt_regs_di(%rax) | 
|---|
| 60 | movq	%rbx, pt_regs_bx(%rax) | 
|---|
| 61 | movq	%rcx, pt_regs_cx(%rax) | 
|---|
| 62 | movq	%rdx, pt_regs_dx(%rax) | 
|---|
| 63 | movq	%r8, pt_regs_r8(%rax) | 
|---|
| 64 | movq	%r9, pt_regs_r9(%rax) | 
|---|
| 65 | movq	%r10, pt_regs_r10(%rax) | 
|---|
| 66 | movq	%r11, pt_regs_r11(%rax) | 
|---|
| 67 | movq	%r12, pt_regs_r12(%rax) | 
|---|
| 68 | movq	%r13, pt_regs_r13(%rax) | 
|---|
| 69 | movq	%r14, pt_regs_r14(%rax) | 
|---|
| 70 | movq	%r15, pt_regs_r15(%rax) | 
|---|
| 71 | pushfq | 
|---|
| 72 | popq	pt_regs_flags(%rax) | 
|---|
| 73 |  | 
|---|
| 74 | movq	$.Lresume_point, saved_rip(%rip) | 
|---|
| 75 |  | 
|---|
| 76 | movq	%rsp, saved_rsp(%rip) | 
|---|
| 77 | movq	%rbp, saved_rbp(%rip) | 
|---|
| 78 | movq	%rbx, saved_rbx(%rip) | 
|---|
| 79 | movq	%rdi, saved_rdi(%rip) | 
|---|
| 80 | movq	%rsi, saved_rsi(%rip) | 
|---|
| 81 |  | 
|---|
| 82 | addq	$8, %rsp | 
|---|
| 83 | movl	$3, %edi | 
|---|
| 84 | xorl	%eax, %eax | 
|---|
| 85 | call	x86_acpi_enter_sleep_state | 
|---|
| 86 | /* in case something went wrong, restore the machine status and go on */ | 
|---|
| 87 | jmp	.Lresume_point | 
|---|
| 88 |  | 
|---|
| 89 | .align 4 | 
|---|
| 90 | .Lresume_point: | 
|---|
| 91 | ANNOTATE_NOENDBR | 
|---|
| 92 | /* We don't restore %rax, it must be 0 anyway */ | 
|---|
| 93 | movq	$saved_context, %rax | 
|---|
| 94 | movq	saved_context_cr4(%rax), %rbx | 
|---|
| 95 | movq	%rbx, %cr4 | 
|---|
| 96 | movq	saved_context_cr3(%rax), %rbx | 
|---|
| 97 | movq	%rbx, %cr3 | 
|---|
| 98 | movq	saved_context_cr2(%rax), %rbx | 
|---|
| 99 | movq	%rbx, %cr2 | 
|---|
| 100 | movq	saved_context_cr0(%rax), %rbx | 
|---|
| 101 | movq	%rbx, %cr0 | 
|---|
| 102 | pushq	pt_regs_flags(%rax) | 
|---|
| 103 | popfq | 
|---|
| 104 | movq	pt_regs_sp(%rax), %rsp | 
|---|
| 105 | movq	pt_regs_bp(%rax), %rbp | 
|---|
| 106 | movq	pt_regs_si(%rax), %rsi | 
|---|
| 107 | movq	pt_regs_di(%rax), %rdi | 
|---|
| 108 | movq	pt_regs_bx(%rax), %rbx | 
|---|
| 109 | movq	pt_regs_cx(%rax), %rcx | 
|---|
| 110 | movq	pt_regs_dx(%rax), %rdx | 
|---|
| 111 | movq	pt_regs_r8(%rax), %r8 | 
|---|
| 112 | movq	pt_regs_r9(%rax), %r9 | 
|---|
| 113 | movq	pt_regs_r10(%rax), %r10 | 
|---|
| 114 | movq	pt_regs_r11(%rax), %r11 | 
|---|
| 115 | movq	pt_regs_r12(%rax), %r12 | 
|---|
| 116 | movq	pt_regs_r13(%rax), %r13 | 
|---|
| 117 | movq	pt_regs_r14(%rax), %r14 | 
|---|
| 118 | movq	pt_regs_r15(%rax), %r15 | 
|---|
| 119 |  | 
|---|
| 120 | #if defined(CONFIG_KASAN) && defined(CONFIG_KASAN_STACK) | 
|---|
| 121 | /* | 
|---|
| 122 | * The suspend path may have poisoned some areas deeper in the stack, | 
|---|
| 123 | * which we now need to unpoison. | 
|---|
| 124 | */ | 
|---|
| 125 | movq	%rsp, %rdi | 
|---|
| 126 | call	kasan_unpoison_task_stack_below | 
|---|
| 127 | #endif | 
|---|
| 128 |  | 
|---|
| 129 | xorl	%eax, %eax | 
|---|
| 130 | addq	$8, %rsp | 
|---|
| 131 | FRAME_END | 
|---|
| 132 | jmp	restore_processor_state | 
|---|
| 133 | SYM_FUNC_END(do_suspend_lowlevel) | 
|---|
| 134 | STACK_FRAME_NON_STANDARD do_suspend_lowlevel | 
|---|
| 135 |  | 
|---|
| 136 | .data | 
|---|
| 137 | saved_rbp:		.quad	0 | 
|---|
| 138 | saved_rsi:		.quad	0 | 
|---|
| 139 | saved_rdi:		.quad	0 | 
|---|
| 140 | saved_rbx:		.quad	0 | 
|---|
| 141 |  | 
|---|
| 142 | saved_rip:		.quad	0 | 
|---|
| 143 | saved_rsp:		.quad	0 | 
|---|
| 144 |  | 
|---|
| 145 | SYM_DATA(saved_magic,	.quad	0) | 
|---|
| 146 |  | 
|---|