xref: /illumos-gate/usr/src/uts/intel/brand/common/brand_solaris.S (revision da7fc762b82ced1a0ec19a51e04cdf823187ec77)
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21/*
22 * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright 2019 Joyent, Inc.
24 */
25
26/*
27 * This is an assembly file that gets #include-ed into the brand-specific
28 * assembly files (e.g. sn1_brand_asm.s) for Solaris-derived brands.
29 * We can't make these into functions since in the trap context there's
30 * no easy place to save the extra parameters that would be required, so
31 * each brand module needs its own copy of this code.  We #include this and
32 * use brand-specific #defines to replace the XXX_brand_... definitions.
33 */
34
35#include <sys/asm_linkage.h>
36#include <sys/privregs.h>
37#include <sys/segments.h>
38#include "assym.h"
39#include "brand_asm.h"
40
41#ifdef _ASM	/* The remainder of this file is only for assembly files */
42
43/*
44 * syscall handler for 32-bit user processes:
45 * See "64-BIT INTERPOSITION STACK" in brand_asm.h.
46 * To 'return' to our user-space handler, we just need to place its address
47 * into %rcx.  The original return address is passed back in SYSCALL_REG.
48 */
49ENTRY(XXX_brand_syscall32_callback)
50	CALLBACK_PROLOGUE(XXX_emulation_table, SPD_HANDLER, SYSCALL_REG,
51	    SCR_REG, SCR_REGB);
52	CALC_TABLE_ADDR(SCR_REG, SPD_HANDLER);
53	mov	%rcx, SYSCALL_REG; /* save orig return addr in syscall_reg */
54	mov	SCR_REG, %rcx;	/* place new return addr in %rcx */
55	mov	%gs:CPU_RTMP_R15, SCR_REG; /* restore scratch register */
56	call	x86_md_clear		/* Flush micro-arch state */
57	mov	V_SSP(SP_REG), SP_REG	/* restore user stack pointer */
58	jmp	nopop_sys_syscall32_swapgs_sysretl
599:
60	retq
61SET_SIZE(XXX_brand_syscall32_callback)
62
63/*
64 * syscall handler for 64-bit user processes:
65 * See "64-BIT INTERPOSITION STACK" in brand_asm.h.
66 * To 'return' to our user-space handler, we just need to place its address
67 * into %rcx.  The original return address is passed back in SYSCALL_REG.
68 */
69ENTRY(XXX_brand_syscall_callback)
70	CALLBACK_PROLOGUE(XXX_emulation_table, SPD_HANDLER, SYSCALL_REG,
71	    SCR_REG, SCR_REGB);
72	CALC_TABLE_ADDR(SCR_REG, SPD_HANDLER);
73	mov	%rcx, SYSCALL_REG; /* save orig return addr in syscall_reg */
74	mov	SCR_REG, %rcx;	/* place new return addr in %rcx */
75	mov	%gs:CPU_RTMP_R15, SCR_REG; /* restore scratch register */
76	call	x86_md_clear		/* Flush micro-arch state */
77	mov	V_SSP(SP_REG), SP_REG	/* restore user stack pointer */
78	jmp	nopop_sys_syscall_swapgs_sysretq
799:
80	retq
81SET_SIZE(XXX_brand_syscall_callback)
82
83/*
84 * See "64-BIT INTERPOSITION STACK" in brand_asm.h.
85 * To 'return' to our user-space handler, we just need to place its address
86 * into %rdx.  The original return address is passed back in SYSCALL_REG.
87 */
88ENTRY(XXX_brand_sysenter_callback)
89	CALLBACK_PROLOGUE(XXX_emulation_table, SPD_HANDLER, SYSCALL_REG,
90	    SCR_REG, SCR_REGB);
91	CALC_TABLE_ADDR(SCR_REG, SPD_HANDLER);
92	mov	%rdx, SYSCALL_REG; /* save orig return addr in syscall_reg */
93	mov	SCR_REG, %rdx;	/* place new return addr in %rdx */
94	mov	%gs:CPU_RTMP_R15, SCR_REG; /* restore scratch register */
95	mov	V_SSP(SP_REG), SP_REG	/* restore user stack pointer */
96	jmp	sys_sysenter_swapgs_sysexit
979:
98	ret
99SET_SIZE(XXX_brand_sysenter_callback)
100
101/*
102 * To 'return' to our user-space handler we need to update the user's %eip
103 * pointer in the saved interrupt state on the stack.  The interrupt state was
104 * pushed onto our stack automatically when the interrupt occured; see the
105 * comments above.  The original return address is passed back in SYSCALL_REG.
106 * See "64-BIT INTERPOSITION STACK" and "64-BIT INT STACK" in brand_asm.h.
107 */
108ENTRY(XXX_brand_int91_callback)
109	CALLBACK_PROLOGUE(XXX_emulation_table, SPD_HANDLER, SYSCALL_REG,
110	    SCR_REG, SCR_REGB);
111	CALC_TABLE_ADDR(SCR_REG, SPD_HANDLER); /* new ret addr is in scratch */
112	mov	SCR_REG, SYSCALL_REG;	/* place new ret addr in syscallreg */
113	mov	%gs:CPU_RTMP_R15, SCR_REG; /* restore scratch register */
114	mov	V_SSP(SP_REG), SP_REG;	/* restore intr stack pointer */
115	/*CSTYLED*/
116	xchg	(SP_REG), SYSCALL_REG	/* swap new and orig. return addrs */
117	jmp	sys_sysint_swapgs_iret
1189:
119	retq
120SET_SIZE(XXX_brand_int91_callback)
121
122#endif	/* _ASM */
123