xref: /linux/arch/x86/xen/xen-head.S (revision adc4fb9c814b5d5cc6021022900fd5eb0b3c8165)
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