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#ifdef CONFIG_FRAME_POINTER 104 pushq $0 /* Dummy push for stack alignment. */ 105#endif 106#endif 107 /* Set the vendor specific function. */ 108 call __xen_hypercall_setfunc 109 /* Set ZF = 1 if AMD, Restore saved registers. */ 110#ifdef CONFIG_X86_32 111 lea xen_hypercall_amd, %ebx 112 cmp %eax, %ebx 113 pop %edi 114 pop %esi 115 pop %edx 116 pop %ecx 117 pop %ebx 118 pop %eax 119#else 120 lea xen_hypercall_amd(%rip), %rbx 121 cmp %rax, %rbx 122#ifdef CONFIG_FRAME_POINTER 123 pop %rax /* Dummy pop. */ 124#endif 125 pop %r8 126 pop %r9 127 pop %r10 128 pop %r11 129 pop %rsi 130 pop %rdi 131 pop %rdx 132 pop %rcx 133 pop %rax 134#endif 135 /* Use correct hypercall function. */ 136 jz xen_hypercall_amd 137 jmp xen_hypercall_intel 138SYM_FUNC_END(xen_hypercall_hvm) 139 140SYM_FUNC_START(xen_hypercall_amd) 141 vmmcall 142 RET 143SYM_FUNC_END(xen_hypercall_amd) 144 145SYM_FUNC_START(xen_hypercall_intel) 146 vmcall 147 RET 148SYM_FUNC_END(xen_hypercall_intel) 149 .popsection 150 151 ELFNOTE(Xen, XEN_ELFNOTE_GUEST_OS, .asciz "linux") 152 ELFNOTE(Xen, XEN_ELFNOTE_GUEST_VERSION, .asciz "2.6") 153 ELFNOTE(Xen, XEN_ELFNOTE_XEN_VERSION, .asciz "xen-3.0") 154#ifdef CONFIG_XEN_PV 155 ELFNOTE(Xen, XEN_ELFNOTE_VIRT_BASE, _ASM_PTR __START_KERNEL_map) 156 /* Map the p2m table to a 512GB-aligned user address. */ 157 ELFNOTE(Xen, XEN_ELFNOTE_INIT_P2M, .quad (PUD_SIZE * PTRS_PER_PUD)) 158 ELFNOTE(Xen, XEN_ELFNOTE_ENTRY, .globl xen_elfnote_entry; 159 xen_elfnote_entry: _ASM_PTR xen_elfnote_entry_value - .) 160 ELFNOTE(Xen, XEN_ELFNOTE_FEATURES, .ascii "!writable_page_tables") 161 ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE, .asciz "yes") 162 ELFNOTE(Xen, XEN_ELFNOTE_L1_MFN_VALID, 163 .quad _PAGE_PRESENT; .quad _PAGE_PRESENT) 164 ELFNOTE(Xen, XEN_ELFNOTE_MOD_START_PFN, .long 1) 165 ELFNOTE(Xen, XEN_ELFNOTE_PADDR_OFFSET, _ASM_PTR 0) 166# define FEATURES_PV (1 << XENFEAT_writable_page_tables) 167#else 168# define FEATURES_PV 0 169#endif 170#ifdef CONFIG_XEN_PVH 171# define FEATURES_PVH (1 << XENFEAT_linux_rsdp_unrestricted) 172#else 173# define FEATURES_PVH 0 174#endif 175#ifdef CONFIG_XEN_DOM0 176# define FEATURES_DOM0 (1 << XENFEAT_dom0) 177#else 178# define FEATURES_DOM0 0 179#endif 180 ELFNOTE(Xen, XEN_ELFNOTE_SUPPORTED_FEATURES, 181 .long FEATURES_PV | FEATURES_PVH | FEATURES_DOM0) 182 ELFNOTE(Xen, XEN_ELFNOTE_LOADER, .asciz "generic") 183 ELFNOTE(Xen, XEN_ELFNOTE_SUSPEND_CANCEL, .long 1) 184 185#endif /*CONFIG_XEN */ 186