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
27SYM_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
46SYM_CODE_END(startup_xen)
47 __FINIT
48
49#ifdef CONFIG_XEN_PV_SMP
50.pushsection .text
51SYM_CODE_START(asm_cpu_bringup_and_idle)
52 UNWIND_HINT_END_OF_STACK
53 ENDBR
54
55 call cpu_bringup_and_idle
56SYM_CODE_END(asm_cpu_bringup_and_idle)
57
58SYM_CODE_START(xen_cpu_bringup_again)
59 UNWIND_HINT_FUNC
60 mov %rdi, %rsp
61 UNWIND_HINT_REGS
62 call cpu_bringup_and_idle
63SYM_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 */
80SYM_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
131SYM_FUNC_END(xen_hypercall_hvm)
132
133SYM_FUNC_START(xen_hypercall_amd)
134 ANNOTATE_NOENDBR
135 vmmcall
136 RET
137SYM_FUNC_END(xen_hypercall_amd)
138
139SYM_FUNC_START(xen_hypercall_intel)
140 ANNOTATE_NOENDBR
141 vmcall
142 RET
143SYM_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 */
181