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