Linux 6.16-rc6
[linux-2.6-block.git] / arch / x86 / xen / xen-head.S
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /* Xen-specific pieces of head.S, intended to be included in the right
3         place in head.S */
4
5 #ifdef CONFIG_XEN
6
7 #include <linux/elfnote.h>
8 #include <linux/init.h>
9 #include <linux/instrumentation.h>
10
11 #include <asm/boot.h>
12 #include <asm/asm.h>
13 #include <asm/frame.h>
14 #include <asm/msr.h>
15 #include <asm/page_types.h>
16 #include <asm/percpu.h>
17 #include <asm/unwind_hints.h>
18
19 #include <xen/interface/elfnote.h>
20 #include <xen/interface/features.h>
21 #include <xen/interface/xen.h>
22 #include <xen/interface/xen-mca.h>
23 #include <asm/xen/interface.h>
24
25 #ifdef CONFIG_XEN_PV
26         __INIT
27 SYM_CODE_START(startup_xen)
28         UNWIND_HINT_END_OF_STACK
29         ANNOTATE_NOENDBR
30         cld
31
32         leaq    __top_init_kernel_stack(%rip), %rsp
33
34         /*
35          * Set up GSBASE.
36          * Note that, on SMP, the boot cpu uses init data section until
37          * the per cpu areas are set up.
38          */
39         movl    $MSR_GS_BASE,%ecx
40         xorl    %eax, %eax
41         xorl    %edx, %edx
42         wrmsr
43
44         mov     %rsi, %rdi
45         call xen_start_kernel
46 SYM_CODE_END(startup_xen)
47         __FINIT
48
49 #ifdef CONFIG_XEN_PV_SMP
50 .pushsection .text
51 SYM_CODE_START(asm_cpu_bringup_and_idle)
52         UNWIND_HINT_END_OF_STACK
53         ENDBR
54
55         call cpu_bringup_and_idle
56 SYM_CODE_END(asm_cpu_bringup_and_idle)
57
58 SYM_CODE_START(xen_cpu_bringup_again)
59         UNWIND_HINT_FUNC
60         mov     %rdi, %rsp
61         UNWIND_HINT_REGS
62         call    cpu_bringup_and_idle
63 SYM_CODE_END(xen_cpu_bringup_again)
64 .popsection
65 #endif
66 #endif
67
68         .pushsection .noinstr.text, "ax"
69 /*
70  * Xen hypercall interface to the hypervisor.
71  *
72  * Input:
73  *     %eax: hypercall number
74  *   32-bit:
75  *     %ebx, %ecx, %edx, %esi, %edi: args 1..5 for the hypercall
76  *   64-bit:
77  *     %rdi, %rsi, %rdx, %r10, %r8: args 1..5 for the hypercall
78  * Output: %[er]ax
79  */
80 SYM_FUNC_START(xen_hypercall_hvm)
81         ENDBR
82         FRAME_BEGIN
83         /* Save all relevant registers (caller save and arguments). */
84 #ifdef CONFIG_X86_32
85         push %eax
86         push %ebx
87         push %ecx
88         push %edx
89         push %esi
90         push %edi
91 #else
92         push %rax
93         push %rcx
94         push %rdx
95         push %rdi
96         push %rsi
97         push %r11
98         push %r10
99         push %r9
100         push %r8
101 #endif
102         /* Set the vendor specific function. */
103         call __xen_hypercall_setfunc
104         /* Set ZF = 1 if AMD, Restore saved registers. */
105 #ifdef CONFIG_X86_32
106         lea xen_hypercall_amd, %ebx
107         cmp %eax, %ebx
108         pop %edi
109         pop %esi
110         pop %edx
111         pop %ecx
112         pop %ebx
113         pop %eax
114 #else
115         lea xen_hypercall_amd(%rip), %rcx
116         cmp %rax, %rcx
117         pop %r8
118         pop %r9
119         pop %r10
120         pop %r11
121         pop %rsi
122         pop %rdi
123         pop %rdx
124         pop %rcx
125         pop %rax
126 #endif
127         FRAME_END
128         /* Use correct hypercall function. */
129         jz xen_hypercall_amd
130         jmp xen_hypercall_intel
131 SYM_FUNC_END(xen_hypercall_hvm)
132
133 SYM_FUNC_START(xen_hypercall_amd)
134         ANNOTATE_NOENDBR
135         vmmcall
136         RET
137 SYM_FUNC_END(xen_hypercall_amd)
138
139 SYM_FUNC_START(xen_hypercall_intel)
140         ANNOTATE_NOENDBR
141         vmcall
142         RET
143 SYM_FUNC_END(xen_hypercall_intel)
144         .popsection
145
146         ELFNOTE(Xen, XEN_ELFNOTE_GUEST_OS,       .asciz "linux")
147         ELFNOTE(Xen, XEN_ELFNOTE_GUEST_VERSION,  .asciz "2.6")
148         ELFNOTE(Xen, XEN_ELFNOTE_XEN_VERSION,    .asciz "xen-3.0")
149 #ifdef CONFIG_XEN_PV
150         ELFNOTE(Xen, XEN_ELFNOTE_VIRT_BASE,      _ASM_PTR __START_KERNEL_map)
151         /* Map the p2m table to a 512GB-aligned user address. */
152         ELFNOTE(Xen, XEN_ELFNOTE_INIT_P2M,       .quad (PUD_SIZE * PTRS_PER_PUD))
153         ELFNOTE(Xen, XEN_ELFNOTE_ENTRY,          .globl xen_elfnote_entry;
154                 xen_elfnote_entry: _ASM_PTR xen_elfnote_entry_value - .)
155         ELFNOTE(Xen, XEN_ELFNOTE_FEATURES,       .ascii "!writable_page_tables")
156         ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE,       .asciz "yes")
157         ELFNOTE(Xen, XEN_ELFNOTE_L1_MFN_VALID,
158                 .quad _PAGE_PRESENT; .quad _PAGE_PRESENT)
159         ELFNOTE(Xen, XEN_ELFNOTE_MOD_START_PFN,  .long 1)
160         ELFNOTE(Xen, XEN_ELFNOTE_PADDR_OFFSET,   _ASM_PTR 0)
161 # define FEATURES_PV (1 << XENFEAT_writable_page_tables)
162 #else
163 # define FEATURES_PV 0
164 #endif
165 #ifdef CONFIG_XEN_PVH
166 # define FEATURES_PVH (1 << XENFEAT_linux_rsdp_unrestricted)
167 #else
168 # define FEATURES_PVH 0
169 #endif
170 #ifdef CONFIG_XEN_DOM0
171 # define FEATURES_DOM0 (1 << XENFEAT_dom0)
172 #else
173 # define FEATURES_DOM0 0
174 #endif
175         ELFNOTE(Xen, XEN_ELFNOTE_SUPPORTED_FEATURES,
176                 .long FEATURES_PV | FEATURES_PVH | FEATURES_DOM0)
177         ELFNOTE(Xen, XEN_ELFNOTE_LOADER,         .asciz "generic")
178         ELFNOTE(Xen, XEN_ELFNOTE_SUSPEND_CANCEL, .long 1)
179
180 #endif /*CONFIG_XEN */