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 /* 23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #if defined(__lint) 28 29 #include <sys/systm.h> 30 31 #else /* __lint */ 32 33 #include "genassym.h" 34 #include "../common/brand_asm.h" 35 36 #endif /* __lint */ 37 38 #ifdef __lint 39 40 void 41 lx_brand_int80_callback(void) 42 { 43 } 44 45 #else /* __lint */ 46 47 #if defined(__amd64) 48 49 /* 50 * See "64-BIT INTERPOSITION STACK" in brand_asm.h. 51 */ 52 ENTRY(lx_brand_int80_callback) 53 GET_PROCP(SP_REG, 0, %r15) 54 movq P_ZONE(%r15), %r15 /* grab the zone pointer */ 55 /* grab the 'max syscall num' for this process from 'zone brand data' */ 56 movq ZONE_BRAND_DATA(%r15), %r15 /* grab the zone brand ptr */ 57 movl LXZD_MAX_SYSCALL(%r15), %r15d /* get the 'max sysnum' word */ 58 cmpq %r15, %rax /* is 0 <= syscall <= MAX? */ 59 jbe 0f /* yes, syscall is OK */ 60 xorl %eax, %eax /* no, zero syscall number */ 61 0: 62 63 .lx_brand_int80_patch_point: 64 jmp .lx_brand_int80_notrace 65 66 .lx_brand_int80_notrace: 67 CALC_TABLE_ADDR(%r15, L_HANDLER) 68 1: 69 movq %r15, %rax 70 GET_V(%rsp, 0, V_SSP, %rsp) /* restore intr. stack pointer */ 71 xchgq (%rsp), %rax /* swap %rax and return addr */ 72 jmp sys_sysint_swapgs_iret 73 74 .lx_brand_int80_trace: 75 /* 76 * If tracing is active, we vector to an alternate trace-enabling 77 * handler table instead. 78 */ 79 CALC_TABLE_ADDR(%r15, L_TRACEHANDLER) 80 jmp 1b 81 SET_SIZE(lx_brand_int80_callback) 82 83 #define PATCH_POINT _CONST(.lx_brand_int80_patch_point + 1) 84 #define PATCH_VAL _CONST(.lx_brand_int80_trace - .lx_brand_int80_notrace) 85 86 ENTRY(lx_brand_int80_enable) 87 movl $1, lx_systrace_brand_enabled(%rip) 88 movq $PATCH_POINT, %r8 89 movb $PATCH_VAL, (%r8) 90 ret 91 SET_SIZE(lx_brand_int80_enable) 92 93 ENTRY(lx_brand_int80_disable) 94 movq $PATCH_POINT, %r8 95 movb $0, (%r8) 96 movl $0, lx_systrace_brand_enabled(%rip) 97 ret 98 SET_SIZE(lx_brand_int80_disable) 99 100 101 #elif defined(__i386) 102 103 /* 104 * See "32-BIT INTERPOSITION STACK" in brand_asm.h. 105 */ 106 ENTRY(lx_brand_int80_callback) 107 GET_PROCP(SP_REG, 0, %ebx) 108 movl P_ZONE(%ebx), %ebx /* grab the zone pointer */ 109 /* grab the 'max syscall num' for this process from 'zone brand data' */ 110 movl ZONE_BRAND_DATA(%ebx), %ebx /* grab the zone brand data */ 111 movl LXZD_MAX_SYSCALL(%ebx), %ebx /* get the max sysnum */ 112 113 cmpl %ebx, %eax /* is 0 <= syscall <= MAX? */ 114 jbe 0f /* yes, syscall is OK */ 115 xorl %eax, %eax /* no, zero syscall number */ 116 0: 117 118 .lx_brand_int80_patch_point: 119 jmp .lx_brand_int80_notrace 120 121 .lx_brand_int80_notrace: 122 CALC_TABLE_ADDR(%ebx, L_HANDLER) 123 124 1: 125 movl %ebx, %eax 126 GET_V(%esp, 0, V_U_EBX, %ebx) /* restore scratch register */ 127 addl $V_END, %esp /* restore intr. stack ptr */ 128 xchgl (%esp), %eax /* swap new and orig. return addrs */ 129 jmp nopop_sys_rtt_syscall 130 131 .lx_brand_int80_trace: 132 CALC_TABLE_ADDR(%ebx, L_TRACEHANDLER) 133 jmp 1b 134 SET_SIZE(lx_brand_int80_callback) 135 136 137 #define PATCH_POINT _CONST(.lx_brand_int80_patch_point + 1) 138 #define PATCH_VAL _CONST(.lx_brand_int80_trace - .lx_brand_int80_notrace) 139 140 ENTRY(lx_brand_int80_enable) 141 pushl %ebx 142 pushl %eax 143 movl $1, lx_systrace_brand_enabled 144 movl $PATCH_POINT, %ebx 145 movl $PATCH_VAL, %eax 146 movb %al, (%ebx) 147 popl %eax 148 popl %ebx 149 ret 150 SET_SIZE(lx_brand_int80_enable) 151 152 ENTRY(lx_brand_int80_disable) 153 pushl %ebx 154 movl $PATCH_POINT, %ebx 155 movb $0, (%ebx) 156 movl $0, lx_systrace_brand_enabled 157 popl %ebx 158 ret 159 SET_SIZE(lx_brand_int80_disable) 160 161 #endif /* __i386 */ 162 #endif /* __lint */