xref: /openbmc/linux/arch/x86/xen/xen-head.S (revision 360823a09426347ea8f232b0b0b5156d0aed0302)
1b2441318SGreg Kroah-Hartman/* SPDX-License-Identifier: GPL-2.0 */
29702785aSThomas Gleixner/* Xen-specific pieces of head.S, intended to be included in the right
39702785aSThomas Gleixner	place in head.S */
49702785aSThomas Gleixner
59702785aSThomas Gleixner#ifdef CONFIG_XEN
69702785aSThomas Gleixner
79702785aSThomas Gleixner#include <linux/elfnote.h>
808b6d290SSam Ravnborg#include <linux/init.h>
931f29270SJuergen Gross#include <linux/instrumentation.h>
107077c33dSJeremy Fitzhardinge
119702785aSThomas Gleixner#include <asm/boot.h>
127077c33dSJeremy Fitzhardinge#include <asm/asm.h>
1331f29270SJuergen Gross#include <asm/frame.h>
144f277295SJuergen Gross#include <asm/msr.h>
150341c14dSJeremy Fitzhardinge#include <asm/page_types.h>
164f277295SJuergen Gross#include <asm/percpu.h>
17abbe1cacSJosh Poimboeuf#include <asm/unwind_hints.h>
187077c33dSJeremy Fitzhardinge
199702785aSThomas Gleixner#include <xen/interface/elfnote.h>
204e903a20SMukesh Rathor#include <xen/interface/features.h>
21526abeaeSJuergen Gross#include <xen/interface/xen.h>
22526abeaeSJuergen Gross#include <xen/interface/xen-mca.h>
237e0edc1bSJeremy Fitzhardinge#include <asm/xen/interface.h>
249702785aSThomas Gleixner
25c504b2f1SVitaly Kuznetsov#ifdef CONFIG_XEN_PV
2608b6d290SSam Ravnborg	__INIT
27bc7b11c0SJiri SlabySYM_CODE_START(startup_xen)
28fb799447SJosh Poimboeuf	UNWIND_HINT_END_OF_STACK
291ab80a0dSJosh Poimboeuf	ANNOTATE_NOENDBR
309702785aSThomas Gleixner	cld
3104b6b4a5SBoris Ostrovsky
323adee777SBrian Gerst	leaq	(__end_init_task - PTREGS_SIZE)(%rip), %rsp
334478c407SBoris Ostrovsky
344f277295SJuergen Gross	/* Set up %gs.
354f277295SJuergen Gross	 *
36e6401c13SAndy Lutomirski	 * The base of %gs always points to fixed_percpu_data.  If the
37e6401c13SAndy Lutomirski	 * stack protector canary is enabled, it is located at %gs:40.
38e6401c13SAndy Lutomirski	 * Note that, on SMP, the boot cpu uses init data section until
39e6401c13SAndy Lutomirski	 * the per cpu areas are set up.
404f277295SJuergen Gross	 */
414f277295SJuergen Gross	movl	$MSR_GS_BASE,%ecx
42e6401c13SAndy Lutomirski	movq	$INIT_PER_CPU_VAR(fixed_percpu_data),%rax
434f277295SJuergen Gross	cdq
444f277295SJuergen Gross	wrmsr
454f277295SJuergen Gross
4696e8fc58SJuergen Gross	mov	%rsi, %rdi
472f62f36eSMiroslav Benes	call xen_start_kernel
48bc7b11c0SJiri SlabySYM_CODE_END(startup_xen)
4908b6d290SSam Ravnborg	__FINIT
50c3881eb5SMiroslav Benes
51c3881eb5SMiroslav Benes#ifdef CONFIG_XEN_PV_SMP
52c3881eb5SMiroslav Benes.pushsection .text
53c3881eb5SMiroslav BenesSYM_CODE_START(asm_cpu_bringup_and_idle)
54fb799447SJosh Poimboeuf	UNWIND_HINT_END_OF_STACK
555b2fc515SPeter Zijlstra	ENDBR
56c3881eb5SMiroslav Benes
57c3881eb5SMiroslav Benes	call cpu_bringup_and_idle
58c3881eb5SMiroslav BenesSYM_CODE_END(asm_cpu_bringup_and_idle)
59336f560aSJuergen Gross
60336f560aSJuergen GrossSYM_CODE_START(xen_cpu_bringup_again)
61336f560aSJuergen Gross	UNWIND_HINT_FUNC
62336f560aSJuergen Gross	mov	%rdi, %rsp
63336f560aSJuergen Gross	UNWIND_HINT_REGS
64336f560aSJuergen Gross	call	cpu_bringup_and_idle
65336f560aSJuergen GrossSYM_CODE_END(xen_cpu_bringup_again)
66c3881eb5SMiroslav Benes.popsection
67c3881eb5SMiroslav Benes#endif
68c504b2f1SVitaly Kuznetsov#endif
699702785aSThomas Gleixner
7031f29270SJuergen Gross	.pushsection .noinstr.text, "ax"
7131f29270SJuergen Gross/*
7231f29270SJuergen Gross * Xen hypercall interface to the hypervisor.
7331f29270SJuergen Gross *
7431f29270SJuergen Gross * Input:
7531f29270SJuergen Gross *     %eax: hypercall number
7631f29270SJuergen Gross *   32-bit:
7731f29270SJuergen Gross *     %ebx, %ecx, %edx, %esi, %edi: args 1..5 for the hypercall
7831f29270SJuergen Gross *   64-bit:
7931f29270SJuergen Gross *     %rdi, %rsi, %rdx, %r10, %r8: args 1..5 for the hypercall
8031f29270SJuergen Gross * Output: %[er]ax
8131f29270SJuergen Gross */
8231f29270SJuergen GrossSYM_FUNC_START(xen_hypercall_hvm)
8331f29270SJuergen Gross	ENDBR
8431f29270SJuergen Gross	FRAME_BEGIN
8531f29270SJuergen Gross	/* Save all relevant registers (caller save and arguments). */
8631f29270SJuergen Gross#ifdef CONFIG_X86_32
8731f29270SJuergen Gross	push %eax
8831f29270SJuergen Gross	push %ebx
8931f29270SJuergen Gross	push %ecx
9031f29270SJuergen Gross	push %edx
9131f29270SJuergen Gross	push %esi
9231f29270SJuergen Gross	push %edi
9331f29270SJuergen Gross#else
9431f29270SJuergen Gross	push %rax
9531f29270SJuergen Gross	push %rcx
9631f29270SJuergen Gross	push %rdx
9731f29270SJuergen Gross	push %rdi
9831f29270SJuergen Gross	push %rsi
9931f29270SJuergen Gross	push %r11
10031f29270SJuergen Gross	push %r10
10131f29270SJuergen Gross	push %r9
10231f29270SJuergen Gross	push %r8
10331f29270SJuergen Gross#ifdef CONFIG_FRAME_POINTER
10431f29270SJuergen Gross	pushq $0	/* Dummy push for stack alignment. */
10531f29270SJuergen Gross#endif
10631f29270SJuergen Gross#endif
10731f29270SJuergen Gross	/* Set the vendor specific function. */
10831f29270SJuergen Gross	call __xen_hypercall_setfunc
10931f29270SJuergen Gross	/* Set ZF = 1 if AMD, Restore saved registers. */
11031f29270SJuergen Gross#ifdef CONFIG_X86_32
11131f29270SJuergen Gross	lea xen_hypercall_amd, %ebx
11231f29270SJuergen Gross	cmp %eax, %ebx
11331f29270SJuergen Gross	pop %edi
11431f29270SJuergen Gross	pop %esi
11531f29270SJuergen Gross	pop %edx
11631f29270SJuergen Gross	pop %ecx
11731f29270SJuergen Gross	pop %ebx
11831f29270SJuergen Gross	pop %eax
11931f29270SJuergen Gross#else
120242f7584SJuergen Gross	lea xen_hypercall_amd(%rip), %rcx
121242f7584SJuergen Gross	cmp %rax, %rcx
12231f29270SJuergen Gross#ifdef CONFIG_FRAME_POINTER
12331f29270SJuergen Gross	pop %rax	/* Dummy pop. */
12431f29270SJuergen Gross#endif
12531f29270SJuergen Gross	pop %r8
12631f29270SJuergen Gross	pop %r9
12731f29270SJuergen Gross	pop %r10
12831f29270SJuergen Gross	pop %r11
12931f29270SJuergen Gross	pop %rsi
13031f29270SJuergen Gross	pop %rdi
13131f29270SJuergen Gross	pop %rdx
13231f29270SJuergen Gross	pop %rcx
13331f29270SJuergen Gross	pop %rax
13431f29270SJuergen Gross#endif
135*b960062aSJuergen Gross	FRAME_END
13631f29270SJuergen Gross	/* Use correct hypercall function. */
13731f29270SJuergen Gross	jz xen_hypercall_amd
13831f29270SJuergen Gross	jmp xen_hypercall_intel
13931f29270SJuergen GrossSYM_FUNC_END(xen_hypercall_hvm)
14031f29270SJuergen Gross
14131f29270SJuergen GrossSYM_FUNC_START(xen_hypercall_amd)
14231f29270SJuergen Gross	vmmcall
14331f29270SJuergen Gross	RET
14431f29270SJuergen GrossSYM_FUNC_END(xen_hypercall_amd)
14531f29270SJuergen Gross
14631f29270SJuergen GrossSYM_FUNC_START(xen_hypercall_intel)
14731f29270SJuergen Gross	vmcall
14831f29270SJuergen Gross	RET
14931f29270SJuergen GrossSYM_FUNC_END(xen_hypercall_intel)
15031f29270SJuergen Gross	.popsection
15131f29270SJuergen Gross
1529702785aSThomas Gleixner	ELFNOTE(Xen, XEN_ELFNOTE_GUEST_OS,       .asciz "linux")
1539702785aSThomas Gleixner	ELFNOTE(Xen, XEN_ELFNOTE_GUEST_VERSION,  .asciz "2.6")
1549702785aSThomas Gleixner	ELFNOTE(Xen, XEN_ELFNOTE_XEN_VERSION,    .asciz "xen-3.0")
1551cfd4ccbSJan Beulich#ifdef CONFIG_XEN_PV
1568c5e5ac3SJeremy Fitzhardinge	ELFNOTE(Xen, XEN_ELFNOTE_VIRT_BASE,      _ASM_PTR __START_KERNEL_map)
1578f5b0c63SJuergen Gross	/* Map the p2m table to a 512GB-aligned user address. */
158daaa42f0SKirill A. Shutemov	ELFNOTE(Xen, XEN_ELFNOTE_INIT_P2M,       .quad (PUD_SIZE * PTRS_PER_PUD))
1597077c33dSJeremy Fitzhardinge	ELFNOTE(Xen, XEN_ELFNOTE_ENTRY,          _ASM_PTR startup_xen)
1601cfd4ccbSJan Beulich	ELFNOTE(Xen, XEN_ELFNOTE_FEATURES,       .ascii "!writable_page_tables")
1619702785aSThomas Gleixner	ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE,       .asciz "yes")
1627e0edc1bSJeremy Fitzhardinge	ELFNOTE(Xen, XEN_ELFNOTE_L1_MFN_VALID,
1637e0edc1bSJeremy Fitzhardinge		.quad _PAGE_PRESENT; .quad _PAGE_PRESENT)
164d1e9abd6SJuergen Gross	ELFNOTE(Xen, XEN_ELFNOTE_MOD_START_PFN,  .long 1)
1658c5e5ac3SJeremy Fitzhardinge	ELFNOTE(Xen, XEN_ELFNOTE_PADDR_OFFSET,   _ASM_PTR 0)
1661cfd4ccbSJan Beulich# define FEATURES_PV (1 << XENFEAT_writable_page_tables)
1671cfd4ccbSJan Beulich#else
1681cfd4ccbSJan Beulich# define FEATURES_PV 0
1691cfd4ccbSJan Beulich#endif
1701cfd4ccbSJan Beulich#ifdef CONFIG_XEN_PVH
1711cfd4ccbSJan Beulich# define FEATURES_PVH (1 << XENFEAT_linux_rsdp_unrestricted)
1721cfd4ccbSJan Beulich#else
1731cfd4ccbSJan Beulich# define FEATURES_PVH 0
1741cfd4ccbSJan Beulich#endif
1751cfd4ccbSJan Beulich#ifdef CONFIG_XEN_DOM0
1761cfd4ccbSJan Beulich# define FEATURES_DOM0 (1 << XENFEAT_dom0)
1771cfd4ccbSJan Beulich#else
1781cfd4ccbSJan Beulich# define FEATURES_DOM0 0
1791cfd4ccbSJan Beulich#endif
1801cfd4ccbSJan Beulich	ELFNOTE(Xen, XEN_ELFNOTE_SUPPORTED_FEATURES,
1811cfd4ccbSJan Beulich		.long FEATURES_PV | FEATURES_PVH | FEATURES_DOM0)
1821cfd4ccbSJan Beulich	ELFNOTE(Xen, XEN_ELFNOTE_LOADER,         .asciz "generic")
1831cfd4ccbSJan Beulich	ELFNOTE(Xen, XEN_ELFNOTE_SUSPEND_CANCEL, .long 1)
1849702785aSThomas Gleixner
1859702785aSThomas Gleixner#endif /*CONFIG_XEN */
186