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 | |
10 | #include <asm/boot.h> |
11 | #include <asm/asm.h> |
12 | #include <asm/msr.h> |
13 | #include <asm/page_types.h> |
14 | #include <asm/percpu.h> |
15 | #include <asm/unwind_hints.h> |
16 | |
17 | #include <xen/interface/elfnote.h> |
18 | #include <xen/interface/features.h> |
19 | #include <xen/interface/xen.h> |
20 | #include <xen/interface/xen-mca.h> |
21 | #include <asm/xen/interface.h> |
22 | |
23 | .pushsection .noinstr.text, "ax" |
24 | .balign PAGE_SIZE |
25 | SYM_CODE_START(hypercall_page) |
26 | .rept (PAGE_SIZE / 32) |
27 | UNWIND_HINT_FUNC |
28 | ANNOTATE_NOENDBR |
29 | ANNOTATE_UNRET_SAFE |
30 | ret |
31 | /* |
32 | * Xen will write the hypercall page, and sort out ENDBR. |
33 | */ |
34 | .skip 31, 0xcc |
35 | .endr |
36 | |
37 | #define HYPERCALL(n) \ |
38 | .equ xen_hypercall_##n, hypercall_page + __HYPERVISOR_##n * 32; \ |
39 | .type xen_hypercall_##n, @function; .size xen_hypercall_##n, 32 |
40 | #include <asm/xen-hypercalls.h> |
41 | #undef HYPERCALL |
42 | SYM_CODE_END(hypercall_page) |
43 | .popsection |
44 | |
45 | #ifdef CONFIG_XEN_PV |
46 | __INIT |
47 | SYM_CODE_START(startup_xen) |
48 | UNWIND_HINT_END_OF_STACK |
49 | ANNOTATE_NOENDBR |
50 | cld |
51 | |
52 | leaq (__end_init_task - PTREGS_SIZE)(%rip), %rsp |
53 | |
54 | /* Set up %gs. |
55 | * |
56 | * The base of %gs always points to fixed_percpu_data. If the |
57 | * stack protector canary is enabled, it is located at %gs:40. |
58 | * Note that, on SMP, the boot cpu uses init data section until |
59 | * the per cpu areas are set up. |
60 | */ |
61 | movl $MSR_GS_BASE,%ecx |
62 | movq $INIT_PER_CPU_VAR(fixed_percpu_data),%rax |
63 | cdq |
64 | wrmsr |
65 | |
66 | mov %rsi, %rdi |
67 | call xen_start_kernel |
68 | SYM_CODE_END(startup_xen) |
69 | __FINIT |
70 | |
71 | #ifdef CONFIG_XEN_PV_SMP |
72 | .pushsection .text |
73 | SYM_CODE_START(asm_cpu_bringup_and_idle) |
74 | UNWIND_HINT_END_OF_STACK |
75 | ENDBR |
76 | |
77 | call cpu_bringup_and_idle |
78 | SYM_CODE_END(asm_cpu_bringup_and_idle) |
79 | |
80 | SYM_CODE_START(xen_cpu_bringup_again) |
81 | UNWIND_HINT_FUNC |
82 | mov %rdi, %rsp |
83 | UNWIND_HINT_REGS |
84 | call cpu_bringup_and_idle |
85 | SYM_CODE_END(xen_cpu_bringup_again) |
86 | .popsection |
87 | #endif |
88 | #endif |
89 | |
90 | ELFNOTE(Xen, XEN_ELFNOTE_GUEST_OS, .asciz "linux" ) |
91 | ELFNOTE(Xen, XEN_ELFNOTE_GUEST_VERSION, .asciz "2.6" ) |
92 | ELFNOTE(Xen, XEN_ELFNOTE_XEN_VERSION, .asciz "xen-3.0" ) |
93 | #ifdef CONFIG_XEN_PV |
94 | ELFNOTE(Xen, XEN_ELFNOTE_VIRT_BASE, _ASM_PTR __START_KERNEL_map) |
95 | /* Map the p2m table to a 512GB-aligned user address. */ |
96 | ELFNOTE(Xen, XEN_ELFNOTE_INIT_P2M, .quad (PUD_SIZE * PTRS_PER_PUD)) |
97 | ELFNOTE(Xen, XEN_ELFNOTE_ENTRY, _ASM_PTR startup_xen) |
98 | ELFNOTE(Xen, XEN_ELFNOTE_FEATURES, .ascii "!writable_page_tables" ) |
99 | ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE, .asciz "yes" ) |
100 | ELFNOTE(Xen, XEN_ELFNOTE_L1_MFN_VALID, |
101 | .quad _PAGE_PRESENT; .quad _PAGE_PRESENT) |
102 | ELFNOTE(Xen, XEN_ELFNOTE_MOD_START_PFN, .long 1) |
103 | ELFNOTE(Xen, XEN_ELFNOTE_PADDR_OFFSET, _ASM_PTR 0) |
104 | # define FEATURES_PV (1 << XENFEAT_writable_page_tables) |
105 | #else |
106 | # define FEATURES_PV 0 |
107 | #endif |
108 | #ifdef CONFIG_XEN_PVH |
109 | # define FEATURES_PVH (1 << XENFEAT_linux_rsdp_unrestricted) |
110 | #else |
111 | # define FEATURES_PVH 0 |
112 | #endif |
113 | #ifdef CONFIG_XEN_DOM0 |
114 | # define FEATURES_DOM0 (1 << XENFEAT_dom0) |
115 | #else |
116 | # define FEATURES_DOM0 0 |
117 | #endif |
118 | ELFNOTE(Xen, XEN_ELFNOTE_HYPERCALL_PAGE, _ASM_PTR hypercall_page) |
119 | ELFNOTE(Xen, XEN_ELFNOTE_SUPPORTED_FEATURES, |
120 | .long FEATURES_PV | FEATURES_PVH | FEATURES_DOM0) |
121 | ELFNOTE(Xen, XEN_ELFNOTE_LOADER, .asciz "generic" ) |
122 | ELFNOTE(Xen, XEN_ELFNOTE_SUSPEND_CANCEL, .long 1) |
123 | |
124 | #endif /*CONFIG_XEN */ |
125 | |