17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5ae115bc7Smrj * Common Development and Distribution License (the "License"). 6ae115bc7Smrj * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 22ae115bc7Smrj * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate #ifndef _ONTRAP_H 277c478bd9Sstevel@tonic-gate #define _ONTRAP_H 287c478bd9Sstevel@tonic-gate 297c478bd9Sstevel@tonic-gate #if !defined(_ASM) 307c478bd9Sstevel@tonic-gate #include <sys/types.h> 317c478bd9Sstevel@tonic-gate #endif 327c478bd9Sstevel@tonic-gate 337c478bd9Sstevel@tonic-gate #ifdef __cplusplus 347c478bd9Sstevel@tonic-gate extern "C" { 357c478bd9Sstevel@tonic-gate #endif 367c478bd9Sstevel@tonic-gate 377c478bd9Sstevel@tonic-gate /* 387c478bd9Sstevel@tonic-gate * on_trap() provides protection against various kinds of machine exceptions, 397c478bd9Sstevel@tonic-gate * and must be used with extreme caution. Like setjmp(), on_trap() returns 407c478bd9Sstevel@tonic-gate * zero when explicitly called and non-zero when it returns as the result of 417c478bd9Sstevel@tonic-gate * an exception. The caller should not attempt to interpret the actual integer 427c478bd9Sstevel@tonic-gate * return value except to test whether it is zero or non-zero. on_trap() and 437c478bd9Sstevel@tonic-gate * no_trap() are NOT DDI interfaces for public consumption. For now, the 447c478bd9Sstevel@tonic-gate * on_trap() mechanism is separate from on_fault() protection and the t_lofault 457c478bd9Sstevel@tonic-gate * protection used by the various copy routines. 467c478bd9Sstevel@tonic-gate * 477c478bd9Sstevel@tonic-gate * Calls to on_trap() may be nested, but only the most recently installed bits 487c478bd9Sstevel@tonic-gate * apply. Protection bits may be OR-ed together if the caller wishes to 497c478bd9Sstevel@tonic-gate * protect against more than one type of trap. If on_trap() returns non-zero, 507c478bd9Sstevel@tonic-gate * the bit corresponding to the trap that triggered return to on_trap() will 517c478bd9Sstevel@tonic-gate * be stored in the ot_trap field of the caller's on_trap_data. 527c478bd9Sstevel@tonic-gate * 537c478bd9Sstevel@tonic-gate * After calling on_trap(), the caller may elect to modify ot_trampoline to 547c478bd9Sstevel@tonic-gate * install a custom trampoline routine prior to executing the protected code 557c478bd9Sstevel@tonic-gate * region. No other fields of the on_trap_data should be modified by the 567c478bd9Sstevel@tonic-gate * caller. The trampoline may not be applicable on all platforms. 577c478bd9Sstevel@tonic-gate * 587c478bd9Sstevel@tonic-gate * The on_trap_data structures are kept in a stack (linked list) whose top 597c478bd9Sstevel@tonic-gate * is pointed to by the current thread's t_ontrap field. A no_trap() call 607c478bd9Sstevel@tonic-gate * pops the top element from the stack and resets t_ontrap to ot_prev. 617c478bd9Sstevel@tonic-gate * We assume the caller has allocated the on_trap_data on the stack or 627c478bd9Sstevel@tonic-gate * made other arrangements, so we do not need to worry about deallocation. 637c478bd9Sstevel@tonic-gate * 647c478bd9Sstevel@tonic-gate * If repeated calls to on_trap() are made using the same on_trap_data address, 657c478bd9Sstevel@tonic-gate * the topmost stack element is modified in-place (the same on_trap_data is 667c478bd9Sstevel@tonic-gate * not pushed twice), allowing callers to use on_trap() in a loop. The act 677c478bd9Sstevel@tonic-gate * of catching an exception does NOT modify t_ontrap. Even if on_trap() 687c478bd9Sstevel@tonic-gate * returns non-zero, the caller must use no_trap() to clear trap protection. 697c478bd9Sstevel@tonic-gate * 707c478bd9Sstevel@tonic-gate * Calls to no_trap() are permitted when the on_trap_data stack is empty; they 717c478bd9Sstevel@tonic-gate * have no effect. no_trap() only modifies t_ontrap; it does not modify the 727c478bd9Sstevel@tonic-gate * internals of the topmost on_trap_data element. It is therefore legal for 737c478bd9Sstevel@tonic-gate * callers to examine the contents of the on_trap_data (specifically ot_trap) 747c478bd9Sstevel@tonic-gate * after the data is popped using no_trap(). 757c478bd9Sstevel@tonic-gate * 767c478bd9Sstevel@tonic-gate * A given platform may not implement all the forms of on_trap() protection. 777c478bd9Sstevel@tonic-gate * The on_trap_data will be pushed on the t_ontrap stack with ot_prot set 787c478bd9Sstevel@tonic-gate * regardless. We must guarantee that if the platform does not implement 797c478bd9Sstevel@tonic-gate * a trap protection, the exceptional condition will trigger a panic. We do 807c478bd9Sstevel@tonic-gate * not permit a platform to allow the exceptional condition to occur silently 817c478bd9Sstevel@tonic-gate * and then continue to execute the caller's protected code region. 827c478bd9Sstevel@tonic-gate */ 837c478bd9Sstevel@tonic-gate 847c478bd9Sstevel@tonic-gate #define OT_DATA_ACCESS 0x01 /* data access exception protection */ 857c478bd9Sstevel@tonic-gate #define OT_DATA_EC 0x02 /* error correction trap protection */ 867c478bd9Sstevel@tonic-gate 87ae115bc7Smrj #if defined(__x86) 88ae115bc7Smrj #define OT_SEGMENT_ACCESS 0x03 /* segmentation exception */ 89ae115bc7Smrj #endif 90ae115bc7Smrj 917c478bd9Sstevel@tonic-gate #if !defined(_ASM) 927c478bd9Sstevel@tonic-gate 937c478bd9Sstevel@tonic-gate typedef struct on_trap_data { 947c478bd9Sstevel@tonic-gate ushort_t ot_prot; /* active protection bits (see above) */ 957c478bd9Sstevel@tonic-gate ushort_t ot_trap; /* bit of actual trap that occurred */ 967c478bd9Sstevel@tonic-gate uintptr_t ot_trampoline; /* %pc for trap return (if any) */ 977c478bd9Sstevel@tonic-gate label_t ot_jmpbuf; /* label for longjmp back to on_trap */ 987c478bd9Sstevel@tonic-gate struct on_trap_data *ot_prev; /* pointer to previous on_trap_data */ 997c478bd9Sstevel@tonic-gate void *ot_handle; /* access handle */ 1007c478bd9Sstevel@tonic-gate void *ot_pad1; /* reserved for future use */ 1017c478bd9Sstevel@tonic-gate } on_trap_data_t; 1027c478bd9Sstevel@tonic-gate 1037c478bd9Sstevel@tonic-gate #if defined(_KERNEL) 1047c478bd9Sstevel@tonic-gate 105*6a3e8e86SRichard Lowe extern int on_trap(on_trap_data_t *, uint_t) __RETURNS_TWICE; 1067c478bd9Sstevel@tonic-gate #pragma unknown_control_flow(on_trap) 1077c478bd9Sstevel@tonic-gate extern void no_trap(void); 1087c478bd9Sstevel@tonic-gate 1097c478bd9Sstevel@tonic-gate extern void on_trap_trampoline(void); /* default trampoline */ 1107c478bd9Sstevel@tonic-gate 1117c478bd9Sstevel@tonic-gate #endif /* _KERNEL */ 1127c478bd9Sstevel@tonic-gate #endif /* !_ASM */ 1137c478bd9Sstevel@tonic-gate 1147c478bd9Sstevel@tonic-gate #ifdef __cplusplus 1157c478bd9Sstevel@tonic-gate } 1167c478bd9Sstevel@tonic-gate #endif 1177c478bd9Sstevel@tonic-gate 1187c478bd9Sstevel@tonic-gate #endif /* _ONTRAP_H */ 119