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