xref: /linux/arch/x86/xen/xen-head.S (revision 5b734b49de8e195a9c9693d0d256ed1ca9fe6c9b)
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	/* Set up %gs.
35	 *
36	 * The base of %gs always points to fixed_percpu_data.  If the
37	 * stack protector canary is enabled, it is located at %gs:40.
38	 * Note that, on SMP, the boot cpu uses init data section until
39	 * the per cpu areas are set up.
40	 */
41	movl	$MSR_GS_BASE,%ecx
42	movq	$INIT_PER_CPU_VAR(fixed_percpu_data),%rax
43	cdq
44	wrmsr
45
46	mov	%rsi, %rdi
47	call xen_start_kernel
48SYM_CODE_END(startup_xen)
49	__FINIT
50
51#ifdef CONFIG_XEN_PV_SMP
52.pushsection .text
53SYM_CODE_START(asm_cpu_bringup_and_idle)
54	UNWIND_HINT_END_OF_STACK
55	ENDBR
56
57	call cpu_bringup_and_idle
58SYM_CODE_END(asm_cpu_bringup_and_idle)
59
60SYM_CODE_START(xen_cpu_bringup_again)
61	UNWIND_HINT_FUNC
62	mov	%rdi, %rsp
63	UNWIND_HINT_REGS
64	call	cpu_bringup_and_idle
65SYM_CODE_END(xen_cpu_bringup_again)
66.popsection
67#endif
68#endif
69
70	.pushsection .noinstr.text, "ax"
71/*
72 * Xen hypercall interface to the hypervisor.
73 *
74 * Input:
75 *     %eax: hypercall number
76 *   32-bit:
77 *     %ebx, %ecx, %edx, %esi, %edi: args 1..5 for the hypercall
78 *   64-bit:
79 *     %rdi, %rsi, %rdx, %r10, %r8: args 1..5 for the hypercall
80 * Output: %[er]ax
81 */
82SYM_FUNC_START(xen_hypercall_hvm)
83	ENDBR
84	FRAME_BEGIN
85	/* Save all relevant registers (caller save and arguments). */
86#ifdef CONFIG_X86_32
87	push %eax
88	push %ebx
89	push %ecx
90	push %edx
91	push %esi
92	push %edi
93#else
94	push %rax
95	push %rcx
96	push %rdx
97	push %rdi
98	push %rsi
99	push %r11
100	push %r10
101	push %r9
102	push %r8
103#endif
104	/* Set the vendor specific function. */
105	call __xen_hypercall_setfunc
106	/* Set ZF = 1 if AMD, Restore saved registers. */
107#ifdef CONFIG_X86_32
108	lea xen_hypercall_amd, %ebx
109	cmp %eax, %ebx
110	pop %edi
111	pop %esi
112	pop %edx
113	pop %ecx
114	pop %ebx
115	pop %eax
116#else
117	lea xen_hypercall_amd(%rip), %rcx
118	cmp %rax, %rcx
119	pop %r8
120	pop %r9
121	pop %r10
122	pop %r11
123	pop %rsi
124	pop %rdi
125	pop %rdx
126	pop %rcx
127	pop %rax
128#endif
129	FRAME_END
130	/* Use correct hypercall function. */
131	jz xen_hypercall_amd
132	jmp xen_hypercall_intel
133SYM_FUNC_END(xen_hypercall_hvm)
134
135SYM_FUNC_START(xen_hypercall_amd)
136	vmmcall
137	RET
138SYM_FUNC_END(xen_hypercall_amd)
139
140SYM_FUNC_START(xen_hypercall_intel)
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