1*4882a593Smuzhiyun/* SPDX-License-Identifier: GPL-2.0 */ 2*4882a593Smuzhiyun/* Xen-specific pieces of head.S, intended to be included in the right 3*4882a593Smuzhiyun place in head.S */ 4*4882a593Smuzhiyun 5*4882a593Smuzhiyun#ifdef CONFIG_XEN 6*4882a593Smuzhiyun 7*4882a593Smuzhiyun#include <linux/elfnote.h> 8*4882a593Smuzhiyun#include <linux/init.h> 9*4882a593Smuzhiyun 10*4882a593Smuzhiyun#include <asm/boot.h> 11*4882a593Smuzhiyun#include <asm/asm.h> 12*4882a593Smuzhiyun#include <asm/msr.h> 13*4882a593Smuzhiyun#include <asm/page_types.h> 14*4882a593Smuzhiyun#include <asm/percpu.h> 15*4882a593Smuzhiyun#include <asm/unwind_hints.h> 16*4882a593Smuzhiyun 17*4882a593Smuzhiyun#include <xen/interface/elfnote.h> 18*4882a593Smuzhiyun#include <xen/interface/features.h> 19*4882a593Smuzhiyun#include <xen/interface/xen.h> 20*4882a593Smuzhiyun#include <xen/interface/xen-mca.h> 21*4882a593Smuzhiyun#include <asm/xen/interface.h> 22*4882a593Smuzhiyun 23*4882a593Smuzhiyun#ifdef CONFIG_XEN_PV 24*4882a593Smuzhiyun __INIT 25*4882a593SmuzhiyunSYM_CODE_START(startup_xen) 26*4882a593Smuzhiyun UNWIND_HINT_EMPTY 27*4882a593Smuzhiyun cld 28*4882a593Smuzhiyun 29*4882a593Smuzhiyun /* Clear .bss */ 30*4882a593Smuzhiyun xor %eax,%eax 31*4882a593Smuzhiyun mov $__bss_start, %_ASM_DI 32*4882a593Smuzhiyun mov $__bss_stop, %_ASM_CX 33*4882a593Smuzhiyun sub %_ASM_DI, %_ASM_CX 34*4882a593Smuzhiyun shr $__ASM_SEL(2, 3), %_ASM_CX 35*4882a593Smuzhiyun rep __ASM_SIZE(stos) 36*4882a593Smuzhiyun 37*4882a593Smuzhiyun mov %_ASM_SI, xen_start_info 38*4882a593Smuzhiyun mov initial_stack(%rip), %rsp 39*4882a593Smuzhiyun 40*4882a593Smuzhiyun /* Set up %gs. 41*4882a593Smuzhiyun * 42*4882a593Smuzhiyun * The base of %gs always points to fixed_percpu_data. If the 43*4882a593Smuzhiyun * stack protector canary is enabled, it is located at %gs:40. 44*4882a593Smuzhiyun * Note that, on SMP, the boot cpu uses init data section until 45*4882a593Smuzhiyun * the per cpu areas are set up. 46*4882a593Smuzhiyun */ 47*4882a593Smuzhiyun movl $MSR_GS_BASE,%ecx 48*4882a593Smuzhiyun movq $INIT_PER_CPU_VAR(fixed_percpu_data),%rax 49*4882a593Smuzhiyun cdq 50*4882a593Smuzhiyun wrmsr 51*4882a593Smuzhiyun 52*4882a593Smuzhiyun call xen_start_kernel 53*4882a593SmuzhiyunSYM_CODE_END(startup_xen) 54*4882a593Smuzhiyun __FINIT 55*4882a593Smuzhiyun 56*4882a593Smuzhiyun#ifdef CONFIG_XEN_PV_SMP 57*4882a593Smuzhiyun.pushsection .text 58*4882a593SmuzhiyunSYM_CODE_START(asm_cpu_bringup_and_idle) 59*4882a593Smuzhiyun UNWIND_HINT_EMPTY 60*4882a593Smuzhiyun 61*4882a593Smuzhiyun call cpu_bringup_and_idle 62*4882a593SmuzhiyunSYM_CODE_END(asm_cpu_bringup_and_idle) 63*4882a593Smuzhiyun.popsection 64*4882a593Smuzhiyun#endif 65*4882a593Smuzhiyun#endif 66*4882a593Smuzhiyun 67*4882a593Smuzhiyun.pushsection .text 68*4882a593Smuzhiyun .balign PAGE_SIZE 69*4882a593SmuzhiyunSYM_CODE_START(hypercall_page) 70*4882a593Smuzhiyun .rept (PAGE_SIZE / 32) 71*4882a593Smuzhiyun UNWIND_HINT_FUNC 72*4882a593Smuzhiyun ANNOTATE_UNRET_SAFE 73*4882a593Smuzhiyun ret 74*4882a593Smuzhiyun .skip 31, 0xcc 75*4882a593Smuzhiyun .endr 76*4882a593Smuzhiyun 77*4882a593Smuzhiyun#define HYPERCALL(n) \ 78*4882a593Smuzhiyun .equ xen_hypercall_##n, hypercall_page + __HYPERVISOR_##n * 32; \ 79*4882a593Smuzhiyun .type xen_hypercall_##n, @function; .size xen_hypercall_##n, 32 80*4882a593Smuzhiyun#include <asm/xen-hypercalls.h> 81*4882a593Smuzhiyun#undef HYPERCALL 82*4882a593SmuzhiyunSYM_CODE_END(hypercall_page) 83*4882a593Smuzhiyun.popsection 84*4882a593Smuzhiyun 85*4882a593Smuzhiyun ELFNOTE(Xen, XEN_ELFNOTE_GUEST_OS, .asciz "linux") 86*4882a593Smuzhiyun ELFNOTE(Xen, XEN_ELFNOTE_GUEST_VERSION, .asciz "2.6") 87*4882a593Smuzhiyun ELFNOTE(Xen, XEN_ELFNOTE_XEN_VERSION, .asciz "xen-3.0") 88*4882a593Smuzhiyun#ifdef CONFIG_X86_32 89*4882a593Smuzhiyun ELFNOTE(Xen, XEN_ELFNOTE_VIRT_BASE, _ASM_PTR __PAGE_OFFSET) 90*4882a593Smuzhiyun#else 91*4882a593Smuzhiyun ELFNOTE(Xen, XEN_ELFNOTE_VIRT_BASE, _ASM_PTR __START_KERNEL_map) 92*4882a593Smuzhiyun /* Map the p2m table to a 512GB-aligned user address. */ 93*4882a593Smuzhiyun ELFNOTE(Xen, XEN_ELFNOTE_INIT_P2M, .quad (PUD_SIZE * PTRS_PER_PUD)) 94*4882a593Smuzhiyun#endif 95*4882a593Smuzhiyun#ifdef CONFIG_XEN_PV 96*4882a593Smuzhiyun ELFNOTE(Xen, XEN_ELFNOTE_ENTRY, _ASM_PTR startup_xen) 97*4882a593Smuzhiyun#endif 98*4882a593Smuzhiyun ELFNOTE(Xen, XEN_ELFNOTE_HYPERCALL_PAGE, _ASM_PTR hypercall_page) 99*4882a593Smuzhiyun ELFNOTE(Xen, XEN_ELFNOTE_FEATURES, 100*4882a593Smuzhiyun .ascii "!writable_page_tables|pae_pgdir_above_4gb") 101*4882a593Smuzhiyun ELFNOTE(Xen, XEN_ELFNOTE_SUPPORTED_FEATURES, 102*4882a593Smuzhiyun .long (1 << XENFEAT_writable_page_tables) | \ 103*4882a593Smuzhiyun (1 << XENFEAT_dom0) | \ 104*4882a593Smuzhiyun (1 << XENFEAT_linux_rsdp_unrestricted)) 105*4882a593Smuzhiyun ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE, .asciz "yes") 106*4882a593Smuzhiyun ELFNOTE(Xen, XEN_ELFNOTE_LOADER, .asciz "generic") 107*4882a593Smuzhiyun ELFNOTE(Xen, XEN_ELFNOTE_L1_MFN_VALID, 108*4882a593Smuzhiyun .quad _PAGE_PRESENT; .quad _PAGE_PRESENT) 109*4882a593Smuzhiyun ELFNOTE(Xen, XEN_ELFNOTE_SUSPEND_CANCEL, .long 1) 110*4882a593Smuzhiyun ELFNOTE(Xen, XEN_ELFNOTE_MOD_START_PFN, .long 1) 111*4882a593Smuzhiyun ELFNOTE(Xen, XEN_ELFNOTE_HV_START_LOW, _ASM_PTR __HYPERVISOR_VIRT_START) 112*4882a593Smuzhiyun ELFNOTE(Xen, XEN_ELFNOTE_PADDR_OFFSET, _ASM_PTR 0) 113*4882a593Smuzhiyun 114*4882a593Smuzhiyun#endif /*CONFIG_XEN */ 115