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 */ 49 ENTRY(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 59 9: 60 retq 61 SET_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 */ 69 ENTRY(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 79 9: 80 retq 81 SET_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 */ 88 ENTRY(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 97 9: 98 ret 99 SET_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 */ 108 ENTRY(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 118 9: 119 retq 120 SET_SIZE(XXX_brand_int91_callback) 121 122 #endif /* _ASM */