diff options
Diffstat (limited to 'usr/src/uts/intel/sys')
-rw-r--r-- | usr/src/uts/intel/sys/archsystm.h | 2 | ||||
-rw-r--r-- | usr/src/uts/intel/sys/asm_linkage.h | 327 | ||||
-rw-r--r-- | usr/src/uts/intel/sys/comm_page_util.h | 33 | ||||
-rw-r--r-- | usr/src/uts/intel/sys/machtypes.h | 45 | ||||
-rw-r--r-- | usr/src/uts/intel/sys/psw.h | 98 | ||||
-rw-r--r-- | usr/src/uts/intel/sys/pte.h | 107 | ||||
-rw-r--r-- | usr/src/uts/intel/sys/reg.h | 17 | ||||
-rw-r--r-- | usr/src/uts/intel/sys/regset.h | 10 | ||||
-rw-r--r-- | usr/src/uts/intel/sys/stack.h | 130 | ||||
-rw-r--r-- | usr/src/uts/intel/sys/trap.h | 105 | ||||
-rw-r--r-- | usr/src/uts/intel/sys/traptrace.h | 275 |
11 files changed, 1092 insertions, 57 deletions
diff --git a/usr/src/uts/intel/sys/archsystm.h b/usr/src/uts/intel/sys/archsystm.h index 55c387f9b1..0cc12086f3 100644 --- a/usr/src/uts/intel/sys/archsystm.h +++ b/usr/src/uts/intel/sys/archsystm.h @@ -186,7 +186,7 @@ extern void *plat_traceback(void *); * The following two macros are the four byte instruction sequence of stac, nop * and clac, nop. These are used in startup_smap() and hotinline_smap() as a * part of properly setting up the valid instructions. For more information on - * SMAP, see uts/intel/ia32/ml/copy.s, uts/i86pc/os/machdep.c and + * SMAP, see uts/intel/ml/copy.s, uts/i86pc/os/machdep.c and * uts/common/os/modctl.c. * * Note that smap_disable and smap_enable are resolved to stubs at compile time, diff --git a/usr/src/uts/intel/sys/asm_linkage.h b/usr/src/uts/intel/sys/asm_linkage.h index 6dcc9c4f9f..9ba6a9c777 100644 --- a/usr/src/uts/intel/sys/asm_linkage.h +++ b/usr/src/uts/intel/sys/asm_linkage.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -19,20 +18,334 @@ * * CDDL HEADER END */ + /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ +/* + * Copyright 2019 Joyent, Inc. + */ + #ifndef _SYS_ASM_LINKAGE_H #define _SYS_ASM_LINKAGE_H -#pragma ident "%Z%%M% %I% %E% SMI" +#include <sys/stack.h> +#include <sys/trap.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef _ASM /* The remainder of this file is only for assembly files */ + +/* + * make annoying differences in assembler syntax go away + */ + +/* + * D16 and A16 are used to insert instructions prefixes; the + * macros help the assembler code be slightly more portable. + */ +#if !defined(__GNUC_AS__) +/* + * /usr/ccs/bin/as prefixes are parsed as separate instructions + */ +#define D16 data16; +#define A16 addr16; + +/* + * (There are some weird constructs in constant expressions) + */ +#define _CONST(const) [const] +#define _BITNOT(const) -1!_CONST(const) +#define _MUL(a, b) _CONST(a \* b) + +#else +/* + * Why not use the 'data16' and 'addr16' prefixes .. well, the + * assembler doesn't quite believe in real mode, and thus argues with + * us about what we're trying to do. + */ +#define D16 .byte 0x66; +#define A16 .byte 0x67; + +#define _CONST(const) (const) +#define _BITNOT(const) ~_CONST(const) +#define _MUL(a, b) _CONST(a * b) + +#endif + +/* + * C pointers are different sizes between i386 and amd64. + * These constants can be used to compute offsets into pointer arrays. + */ +#if defined(__amd64) +#define CLONGSHIFT 3 +#define CLONGSIZE 8 +#define CLONGMASK 7 +#elif defined(__i386) +#define CLONGSHIFT 2 +#define CLONGSIZE 4 +#define CLONGMASK 3 +#endif + +/* + * Since we know we're either ILP32 or LP64 .. + */ +#define CPTRSHIFT CLONGSHIFT +#define CPTRSIZE CLONGSIZE +#define CPTRMASK CLONGMASK + +#if CPTRSIZE != (1 << CPTRSHIFT) || CLONGSIZE != (1 << CLONGSHIFT) +#error "inconsistent shift constants" +#endif + +#if CPTRMASK != (CPTRSIZE - 1) || CLONGMASK != (CLONGSIZE - 1) +#error "inconsistent mask constants" +#endif + +#define ASM_ENTRY_ALIGN 16 + +/* + * SSE register alignment and save areas + */ + +#define XMM_SIZE 16 +#define XMM_ALIGN 16 + +#if defined(__amd64) + +#define SAVE_XMM_PROLOG(sreg, nreg) \ + subq $_CONST(_MUL(XMM_SIZE, nreg)), %rsp; \ + movq %rsp, sreg + +#define RSTOR_XMM_EPILOG(sreg, nreg) \ + addq $_CONST(_MUL(XMM_SIZE, nreg)), %rsp + +#elif defined(__i386) + +#define SAVE_XMM_PROLOG(sreg, nreg) \ + subl $_CONST(_MUL(XMM_SIZE, nreg) + XMM_ALIGN), %esp; \ + movl %esp, sreg; \ + addl $XMM_ALIGN, sreg; \ + andl $_BITNOT(XMM_ALIGN-1), sreg + +#define RSTOR_XMM_EPILOG(sreg, nreg) \ + addl $_CONST(_MUL(XMM_SIZE, nreg) + XMM_ALIGN), %esp; + +#endif /* __i386 */ + +/* + * profiling causes definitions of the MCOUNT and RTMCOUNT + * particular to the type + */ +#ifdef GPROF + +#define MCOUNT(x) \ + pushl %ebp; \ + movl %esp, %ebp; \ + call _mcount; \ + popl %ebp + +#endif /* GPROF */ + +#ifdef PROF + +#define MCOUNT(x) \ +/* CSTYLED */ \ + .lcomm .L_/**/x/**/1, 4, 4; \ + pushl %ebp; \ + movl %esp, %ebp; \ +/* CSTYLED */ \ + movl $.L_/**/x/**/1, %edx; \ + call _mcount; \ + popl %ebp + +#endif /* PROF */ + +/* + * if we are not profiling, MCOUNT should be defined to nothing + */ +#if !defined(PROF) && !defined(GPROF) +#define MCOUNT(x) +#endif /* !defined(PROF) && !defined(GPROF) */ + +#define RTMCOUNT(x) MCOUNT(x) + +/* + * Macro to define weak symbol aliases. These are similar to the ANSI-C + * #pragma weak _name = name + * except a compiler can determine type. The assembler must be told. Hence, + * the second parameter must be the type of the symbol (i.e.: function,...) + */ +#define ANSI_PRAGMA_WEAK(sym, stype) \ +/* CSTYLED */ \ + .weak _/**/sym; \ +/* CSTYLED */ \ + .type _/**/sym, @stype; \ +/* CSTYLED */ \ +_/**/sym = sym + +/* + * Like ANSI_PRAGMA_WEAK(), but for unrelated names, as in: + * #pragma weak sym1 = sym2 + */ +#define ANSI_PRAGMA_WEAK2(sym1, sym2, stype) \ + .weak sym1; \ + .type sym1, @stype; \ +sym1 = sym2 + +/* + * ENTRY provides the standard procedure entry code and an easy way to + * insert the calls to mcount for profiling. ENTRY_NP is identical, but + * never calls mcount. + */ +#define ENTRY(x) \ + .text; \ + .align ASM_ENTRY_ALIGN; \ + .globl x; \ + .type x, @function; \ +x: MCOUNT(x) + +#define ENTRY_NP(x) \ + .text; \ + .align ASM_ENTRY_ALIGN; \ + .globl x; \ + .type x, @function; \ +x: + +#define RTENTRY(x) \ + .text; \ + .align ASM_ENTRY_ALIGN; \ + .globl x; \ + .type x, @function; \ +x: RTMCOUNT(x) + +/* + * ENTRY2 is identical to ENTRY but provides two labels for the entry point. + */ +#define ENTRY2(x, y) \ + .text; \ + .align ASM_ENTRY_ALIGN; \ + .globl x, y; \ + .type x, @function; \ + .type y, @function; \ +/* CSTYLED */ \ +x: ; \ +y: MCOUNT(x) + +#define ENTRY_NP2(x, y) \ + .text; \ + .align ASM_ENTRY_ALIGN; \ + .globl x, y; \ + .type x, @function; \ + .type y, @function; \ +/* CSTYLED */ \ +x: ; \ +y: + + +/* + * ALTENTRY provides for additional entry points. + */ +#define ALTENTRY(x) \ + .globl x; \ + .type x, @function; \ +x: + +/* + * DGDEF and DGDEF2 provide global data declarations. + * + * DGDEF provides a word aligned word of storage. + * + * DGDEF2 allocates "sz" bytes of storage with **NO** alignment. This + * implies this macro is best used for byte arrays. + * + * DGDEF3 allocates "sz" bytes of storage with "algn" alignment. + */ +#define DGDEF2(name, sz) \ + .data; \ + .globl name; \ + .type name, @object; \ + .size name, sz; \ +name: + +#define DGDEF3(name, sz, algn) \ + .data; \ + .align algn; \ + .globl name; \ + .type name, @object; \ + .size name, sz; \ +name: + +#define DGDEF(name) DGDEF3(name, 4, 4) + +/* + * SET_SIZE trails a function and set the size for the ELF symbol table. + */ +#define SET_SIZE(x) \ + .size x, [.-x] + +/* + * NWORD provides native word value. + */ +#if defined(__amd64) + +/*CSTYLED*/ +#define NWORD quad + +#elif defined(__i386) + +#define NWORD long + +#endif /* __i386 */ + +/* + * These macros should be used when making indirect calls in the kernel. They + * will perform a jump or call to the corresponding register in a way that knows + * about retpolines and handles whether such mitigations are enabled or not. + * + * INDIRECT_JMP_REG will jump to named register. INDIRECT_CALL_REG will instead + * do a call. These macros cannot be used to dereference a register. For + * example, if you need to do something that looks like the following: + * + * call *24(%rdi) + * jmp *(%r15) + * + * You must instead first do a movq into the corresponding location. You need to + * be careful to make sure that the register that its loaded into is safe to + * use. Often that register may be saved or used elsewhere so it may not be safe + * to clobber the value. Usually, loading into %rax would be safe. These would + * turn into something like: + * + * movq 24(%rdi), %rdi; INDIRECT_CALL_REG(rdi) + * movq (%r15), %r15; INDIRECT_JMP_REG(r15) + * + * If you are trying to call a global function, then use the following pattern + * (substituting the register in question): + * + * leaq my_favorite_function(%rip), %rax + * INDIRECT_CALL_REG(rax) + * + * If you instead have a function pointer (say gethrtimef for example), then you + * need to do: + * + * movq my_favorite_function_pointer(%rip), %rax + * INDIRECT_CALL_REG(rax) + */ + +/* CSTYLED */ +#define INDIRECT_JMP_REG(reg) jmp __x86_indirect_thunk_/**/reg; -#if defined(__i386) || defined(__amd64) +/* CSTYLED */ +#define INDIRECT_CALL_REG(reg) call __x86_indirect_thunk_/**/reg; -#include <ia32/sys/asm_linkage.h> /* XX64 x86/sys/asm_linkage.h */ +#endif /* _ASM */ +#ifdef __cplusplus +} #endif #endif /* _SYS_ASM_LINKAGE_H */ diff --git a/usr/src/uts/intel/sys/comm_page_util.h b/usr/src/uts/intel/sys/comm_page_util.h new file mode 100644 index 0000000000..331162c5ca --- /dev/null +++ b/usr/src/uts/intel/sys/comm_page_util.h @@ -0,0 +1,33 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2016 Joyent, Inc. + */ + +#ifndef _COMM_PAGE_UTIL_H +#define _COMM_PAGE_UTIL_H + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(_KERNEL) + +extern caddr_t comm_page_mapin(); + +#endif /* defined(_KERNEL) */ + +#ifdef __cplusplus +} +#endif + +#endif /* _COMM_PAGE_UTIL_H */ diff --git a/usr/src/uts/intel/sys/machtypes.h b/usr/src/uts/intel/sys/machtypes.h index 05ad8896d4..a7b618bed8 100644 --- a/usr/src/uts/intel/sys/machtypes.h +++ b/usr/src/uts/intel/sys/machtypes.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,19 +19,51 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _SYS_MACHTYPES_H #define _SYS_MACHTYPES_H -#include <sys/feature_tests.h> +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Machine dependent types: + * + * intel ia32 Version + */ + +#if (!defined(_POSIX_C_SOURCE) && !defined(_XOPEN_SOURCE)) || \ + defined(__EXTENSIONS__) + +#define REG_LABEL_PC 0 +#define REG_LABEL_SP 1 +#define REG_LABEL_BP 2 +#if defined(__amd64) +#define REG_LABEL_RBX 3 +#define REG_LABEL_R12 4 +#define REG_LABEL_R13 5 +#define REG_LABEL_R14 6 +#define REG_LABEL_R15 7 +#define REG_LABEL_MAX 8 +#else /* __amd64 */ +#define REG_LABEL_EBX 3 +#define REG_LABEL_ESI 4 +#define REG_LABEL_EDI 5 +#define REG_LABEL_MAX 6 +#endif /* __amd64 */ + +typedef struct _label_t { long val[REG_LABEL_MAX]; } label_t; -#if defined(__i386) || defined(__amd64) +#endif /* !defined(_POSIX_C_SOURCE)... */ -#include <ia32/sys/machtypes.h> /* XX64 x86/sys/machtypes.h */ +typedef unsigned char lock_t; /* lock work for busy wait */ +#ifdef __cplusplus +} #endif #endif /* _SYS_MACHTYPES_H */ diff --git a/usr/src/uts/intel/sys/psw.h b/usr/src/uts/intel/sys/psw.h index 8b84f5ff3a..6201a1c733 100644 --- a/usr/src/uts/intel/sys/psw.h +++ b/usr/src/uts/intel/sys/psw.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -19,20 +18,105 @@ * * CDDL HEADER END */ +/* Copyright (c) 1990, 1991 UNIX System Laboratories, Inc. */ +/* Copyright (c) 1984, 1986, 1987, 1988, 1989, 1990 AT&T */ +/* All Rights Reserved */ + /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _SYS_PSW_H #define _SYS_PSW_H -#pragma ident "%Z%%M% %I% %E% SMI" +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _ASM + +/* Flags Register */ + +typedef struct flags { + uint_t fl_cf : 1, /* carry/borrow */ + : 1, /* reserved */ + fl_pf : 1, /* parity */ + : 1, /* reserved */ + fl_af : 1, /* carry/borrow */ + : 1, /* reserved */ + fl_zf : 1, /* zero */ + fl_sf : 1, /* sign */ + fl_tf : 1, /* trace */ + fl_if : 1, /* interrupt enable */ + fl_df : 1, /* direction */ + fl_of : 1, /* overflow */ + fl_iopl : 2, /* I/O privilege level */ + fl_nt : 1, /* nested task */ + : 1, /* reserved */ + fl_rf : 1, /* reset */ + fl_vm : 1, /* virtual 86 mode */ + fl_res : 14; /* reserved */ +} flags_t; + +#endif /* !_ASM */ + +#define PS_C 0x0001 /* carry bit */ +#define PS_MB1 0x0002 /* unused; must be 1. */ +#define PS_P 0x0004 /* parity bit */ +#define PS_AC 0x0010 /* auxiliary carry bit */ +#define PS_Z 0x0040 /* zero bit */ +#define PS_N 0x0080 /* negative bit */ +#define PS_T 0x0100 /* trace enable bit */ +#define PS_IE 0x0200 /* interrupt enable bit */ +#define PS_D 0x0400 /* direction bit */ +#define PS_V 0x0800 /* overflow bit */ +#define PS_IOPL 0x3000 /* I/O privilege level */ +#define PS_NT 0x4000 /* nested task flag */ +#define PS_RF 0x10000 /* restore flag */ +#define PS_VM 0x20000 /* virtual 86 mode flag */ +#define PS_ACHK 0x40000 /* alignment check enable (486) */ +#define PS_VINT 0x80000 /* virtual interrupt flag */ +#define PS_VINTP 0x100000 /* virtual interrupt pending */ +#define PS_ID 0x200000 /* ID flag */ + +#define PS_ICC (PS_C|PS_AC|PS_Z|PS_N) /* integer condition codes */ + +#define FMT_FLAGS_REG \ + "\20\26id\25vip\24vif\23ac\22vm\21rf" \ + "\17nt\14of\13df\12if\11tf\10sf\7zf\5af\3pf\1cf" + +#define PSL_USER 0x202 /* initial user FLAGS */ + +/* user variable PS bits */ +#define PSL_USERMASK (PS_ICC|PS_D|PS_T|PS_V|PS_P|PS_ACHK|PS_NT) + +/* PS bits changeable by the sahf instruction */ +#define PSL_LSAHFMASK (PS_ICC|PS_P) + +/* + * kernel flags settings + * + * Note that the kernel's SMAP protection relies on PS_ACHK not being present in + * the following two definitions. See uts/intel/ml/copy.s for more + * information on SMAP. + */ +#define F_OFF 0x2 /* interrupts off */ +#define F_ON 0x202 /* interrupts on */ + +#ifndef _ASM +typedef int psw_t; +#endif + +#include <sys/tss.h> +#include <sys/segments.h> /* selector definitions */ -#if defined(__i386) || defined(__amd64) +#define USERMODE(cs) ((uint16_t)(cs) != KCS_SEL) -#include <ia32/sys/psw.h> /* XX64 x86/sys/psw.h */ +#include <sys/spl.h> +#ifdef __cplusplus +} #endif #endif /* _SYS_PSW_H */ diff --git a/usr/src/uts/intel/sys/pte.h b/usr/src/uts/intel/sys/pte.h index 09c009d421..ff8d6bb506 100644 --- a/usr/src/uts/intel/sys/pte.h +++ b/usr/src/uts/intel/sys/pte.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,19 +19,111 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _SYS_PTE_H #define _SYS_PTE_H -#pragma ident "%Z%%M% %I% %E% SMI" +#ifndef _ASM +#include <sys/types.h> +#endif /* _ASM */ -#if defined(__i386) || defined(__amd64) +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _ASM + +#ifdef PTE36 /* PTE36 ---------------------------- */ + +typedef uint64_t pteval_t; +typedef pteval_t *pteptr_t; + +#define PRPTEx "llx" + +typedef struct pte32 { + uint32_t Present:1; + uint32_t AccessPermissions:2; + uint32_t WriteThru:1; + uint32_t NonCacheable:1; + uint32_t Referenced:1; + uint32_t Modified:1; + uint32_t MustBeZero:1; + uint32_t GlobalEnable:1; + uint32_t OSReserved:3; + uint32_t PhysicalPageNumber:20; +} pte32_t; + + +typedef struct pte { + uint32_t Present:1; + uint32_t AccessPermissions:2; + uint32_t WriteThru:1; + uint32_t NonCacheable:1; + uint32_t Referenced:1; + uint32_t Modified:1; + uint32_t MustBeZero:1; + uint32_t GlobalEnable:1; + uint32_t OSReserved:3; + uint32_t PhysicalPageNumberL:20; + uint32_t PhysicalPageNumberH; + /* + * An easy way to ensure that + * reserved bits are zero. + */ +} pte_t; + +struct pte64 { + uint32_t pte64_0_31; + uint32_t pte64_32_64; +}; + +#define NPTESHIFT 9 +#define NPTEPERPT 512 /* entries in page table */ +#define PTSIZE (NPTEPERPT * MMU_PAGESIZE) /* bytes mapped */ + + +#else /* PTE36 */ + /* PTE32 ---------------------------- */ + + +typedef uint32_t pteval_t; +typedef pteval_t *pteptr_t; + +#define PRPTEx "x" + +typedef struct pte { + uint_t Present:1; + uint_t AccessPermissions:2; + uint_t WriteThru:1; + uint_t NonCacheable:1; + uint_t Referenced:1; + uint_t Modified:1; + uint_t MustBeZero:1; + uint_t GlobalEnable:1; + uint_t OSReserved:3; + uint_t PhysicalPageNumber:20; +} pte_t; + +#define pte32_t pte_t + +#define NPTESHIFT 10 +#define NPTEPERPT 1024 /* entries in page table */ +#define PTSIZE (NPTEPERPT * MMU_PAGESIZE) /* bytes mapped */ + +#endif /* PTE36 */ + +#define PTE_VALID 0x01 +#define PTE_LARGEPAGE 0x80 +#define PTE_SRWX 0x02 + +#endif /* !_ASM */ -#include <ia32/sys/pte.h> /* XX64 x86/sys/pte.h */ +#ifdef __cplusplus +} #endif -#endif /* _SYS_PTE_H */ +#endif /* !_SYS_PTE_H */ diff --git a/usr/src/uts/intel/sys/reg.h b/usr/src/uts/intel/sys/reg.h index 211919ea27..bdfb0ad46a 100644 --- a/usr/src/uts/intel/sys/reg.h +++ b/usr/src/uts/intel/sys/reg.h @@ -27,12 +27,23 @@ #ifndef _SYS_REG_H #define _SYS_REG_H -#pragma ident "%Z%%M% %I% %E% SMI" +#ifdef __cplusplus +extern "C" { +#endif -#if defined(__i386) || defined(__amd64) +/* + * This file only exists for i386 backwards compatibility. + * Kernel code should not include it. + */ -#include <ia32/sys/reg.h> +#ifdef _KERNEL +#error "kernel include of reg.h" +#else +#include <sys/regset.h> +#endif /* _KERNEL */ +#ifdef __cplusplus +} #endif #endif /* _SYS_REG_H */ diff --git a/usr/src/uts/intel/sys/regset.h b/usr/src/uts/intel/sys/regset.h index 12b8f9e888..69b4d86806 100644 --- a/usr/src/uts/intel/sys/regset.h +++ b/usr/src/uts/intel/sys/regset.h @@ -143,15 +143,15 @@ extern "C" { /* * (This structure definition is specified in the i386 ABI supplement) * It's likely we can just get rid of the struct __old_fpu or maybe - * move it to $SRC/uts/intel/ia32/os/fpu.c which appears to be the + * move it to $SRC/uts/intel/os/fpu.c which appears to be the * only place that uses it. See: www.illumos.org/issues/6284 */ typedef struct __old_fpu { union { struct __old_fpchip_state /* fp extension state */ { - int state[27]; /* 287/387 saved state */ - int status; /* status word saved at */ + int state[27]; /* 287/387 saved state */ + int status; /* status word saved at */ /* exception */ } fpchip_state; struct __old_fp_emul_space /* for emulator(s) */ @@ -159,9 +159,9 @@ typedef struct __old_fpu { char fp_emul[246]; char fp_epad[2]; } fp_emul_space; - int f_fpregs[62]; /* union of the above */ + int f_fpregs[62]; /* union of the above */ } fp_reg_set; - long f_wregs[33]; /* saved weitek state */ + long f_wregs[33]; /* saved weitek state */ } __old_fpregset_t; #endif /* __i386 */ diff --git a/usr/src/uts/intel/sys/stack.h b/usr/src/uts/intel/sys/stack.h index 5521acfc8f..a893e317ea 100644 --- a/usr/src/uts/intel/sys/stack.h +++ b/usr/src/uts/intel/sys/stack.h @@ -20,19 +20,141 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2004 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _SYS_STACK_H #define _SYS_STACK_H -#pragma ident "%Z%%M% %I% %E% SMI" +#if !defined(_ASM) -#if defined(__i386) || defined(__amd64) +#include <sys/types.h> -#include <ia32/sys/stack.h> /* XX64 x86/sys/stack.h */ +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * In the x86 world, a stack frame looks like this: + * + * |--------------------------| + * 4n+8(%ebp) ->| argument word n | + * | ... | (Previous frame) + * 8(%ebp) ->| argument word 0 | + * |--------------------------|-------------------- + * 4(%ebp) ->| return address | + * |--------------------------| + * 0(%ebp) ->| previous %ebp (optional) | + * |--------------------------| + * -4(%ebp) ->| unspecified | (Current frame) + * | ... | + * 0(%esp) ->| variable size | + * |--------------------------| + */ + +/* + * Stack alignment macros. + */ + +#define STACK_ALIGN32 4 +#define STACK_ENTRY_ALIGN32 4 +#define STACK_BIAS32 0 +#define SA32(x) (((x)+(STACK_ALIGN32-1)) & ~(STACK_ALIGN32-1)) +#define STACK_RESERVE32 0 +#define MINFRAME32 0 + +#if defined(__amd64) + +/* + * In the amd64 world, a stack frame looks like this: + * + * |--------------------------| + * 8n+16(%rbp)->| argument word n | + * | ... | (Previous frame) + * 16(%rbp) ->| argument word 0 | + * |--------------------------|-------------------- + * 8(%rbp) ->| return address | + * |--------------------------| + * 0(%rbp) ->| previous %rbp | + * |--------------------------| + * -8(%rbp) ->| unspecified | (Current frame) + * | ... | + * 0(%rsp) ->| variable size | + * |--------------------------| + * -128(%rsp) ->| reserved for function | + * |--------------------------| + * + * The end of the input argument area must be aligned on a 16-byte + * boundary; i.e. (%rsp - 8) % 16 == 0 at function entry. + * + * The 128-byte location beyond %rsp is considered to be reserved for + * functions and is NOT modified by signal handlers. It can be used + * to store temporary data that is not needed across function calls. + */ + +/* + * Stack alignment macros. + */ + +#define STACK_ALIGN64 16 +#define STACK_ENTRY_ALIGN64 8 +#define STACK_BIAS64 0 +#define SA64(x) (((x)+(STACK_ALIGN64-1)) & ~(STACK_ALIGN64-1)) +#define STACK_RESERVE64 128 +#define MINFRAME64 0 + +#define STACK_ALIGN STACK_ALIGN64 +#define STACK_ENTRY_ALIGN STACK_ENTRY_ALIGN64 +#define STACK_BIAS STACK_BIAS64 +#define SA(x) SA64(x) +#define STACK_RESERVE STACK_RESERVE64 +#define MINFRAME MINFRAME64 + +#elif defined(__i386) + +#define STACK_ALIGN STACK_ALIGN32 +#define STACK_ENTRY_ALIGN STACK_ENTRY_ALIGN32 +#define STACK_BIAS STACK_BIAS32 +#define SA(x) SA32(x) +#define STACK_RESERVE STACK_RESERVE32 +#define MINFRAME MINFRAME32 + +#endif /* __i386 */ + +#if defined(_KERNEL) && !defined(_ASM) + +#if defined(DEBUG) +#if STACK_ALIGN == 4 +#define ASSERT_STACK_ALIGNED() \ + { \ + uint32_t __tmp; \ + ASSERT((((uintptr_t)&__tmp) & (STACK_ALIGN - 1)) == 0); \ + } +#elif (STACK_ALIGN == 16) && (_LONG_DOUBLE_ALIGNMENT == 16) +#define ASSERT_STACK_ALIGNED() \ + { \ + long double __tmp; \ + ASSERT((((uintptr_t)&__tmp) & (STACK_ALIGN - 1)) == 0); \ + } +#endif +#else /* DEBUG */ +#define ASSERT_STACK_ALIGNED() +#endif /* DEBUG */ + +struct regs; + +void traceregs(struct regs *); +void traceback(caddr_t); + +#endif /* defined(_KERNEL) && !defined(_ASM) */ + +#define STACK_GROWTH_DOWN /* stacks grow from high to low addresses */ +#ifdef __cplusplus +} #endif #endif /* _SYS_STACK_H */ diff --git a/usr/src/uts/intel/sys/trap.h b/usr/src/uts/intel/sys/trap.h index d412386176..3bc5f32367 100644 --- a/usr/src/uts/intel/sys/trap.h +++ b/usr/src/uts/intel/sys/trap.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -19,20 +18,112 @@ * * CDDL HEADER END */ +/* Copyright (c) 1990, 1991 UNIX System Laboratories, Inc. */ +/* Copyright (c) 1984, 1986, 1987, 1988, 1989, 1990 AT&T */ +/* All Rights Reserved */ + /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * + * Copyright 2018 Joyent, Inc. */ #ifndef _SYS_TRAP_H #define _SYS_TRAP_H -#pragma ident "%Z%%M% %I% %E% SMI" +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Trap type values + */ + +#define T_ZERODIV 0x0 /* #de divide by 0 error */ +#define T_SGLSTP 0x1 /* #db single step */ +#define T_NMIFLT 0x2 /* NMI */ +#define T_BPTFLT 0x3 /* #bp breakpoint fault, INT3 insn */ +#define T_OVFLW 0x4 /* #of INTO overflow fault */ +#define T_BOUNDFLT 0x5 /* #br BOUND insn fault */ +#define T_ILLINST 0x6 /* #ud invalid opcode fault */ +#define T_NOEXTFLT 0x7 /* #nm device not available: x87 */ +#define T_DBLFLT 0x8 /* #df double fault */ +#define T_EXTOVRFLT 0x9 /* [not generated: 386 only] */ +#define T_TSSFLT 0xa /* #ts invalid TSS fault */ +#define T_SEGFLT 0xb /* #np segment not present fault */ +#define T_STKFLT 0xc /* #ss stack fault */ +#define T_GPFLT 0xd /* #gp general protection fault */ +#define T_PGFLT 0xe /* #pf page fault */ +#define T_RESVTRAP 0xf /* reserved */ +#define T_EXTERRFLT 0x10 /* #mf x87 FPU error fault */ +#define T_ALIGNMENT 0x11 /* #ac alignment check error */ +#define T_MCE 0x12 /* #mc machine check exception */ +#define T_SIMDFPE 0x13 /* #xm SSE/SSE exception */ +#define T_DBGENTR 0x14 /* debugger entry */ +#define T_INVALTRAP 0x1e /* invalid */ +#define T_ENDPERR 0x21 /* emulated extension error flt */ +#define T_ENOEXTFLT 0x20 /* emulated ext not present */ +#define T_FASTTRAP 0xd2 /* fast system call */ +#define T_SYSCALLINT 0x91 /* general system call */ +#define T_DTRACE_RET 0x92 /* DTrace pid return */ +#define T_INT80 0x80 /* int80 handler for linux emulation */ +#define T_SOFTINT 0x50fd /* pseudo softint trap type */ + +/* + * Pseudo traps. + */ +#define T_INTERRUPT 0x100 +#define T_FAULT 0x200 +#define T_AST 0x400 +#define T_SYSCALL 0x180 + -#if defined(__i386) || defined(__amd64) +/* + * Values of error code on stack in case of page fault + */ + +#define PF_ERR_MASK 0x01 /* Mask for error bit */ +#define PF_ERR_PAGE 0x00 /* page not present */ +#define PF_ERR_PROT 0x01 /* protection error */ +#define PF_ERR_WRITE 0x02 /* fault caused by write (else read) */ +#define PF_ERR_USER 0x04 /* processor was in user mode */ + /* (else supervisor) */ +#define PF_ERR_EXEC 0x10 /* attempt to execute a No eXec page (AMD) */ + /* or kernel tried to execute a user page */ + /* (Intel SMEP) */ + +/* + * Definitions for fast system call subfunctions + */ +#define T_FNULL 0 /* Null trap for testing */ +#define T_FGETFP 1 /* Get emulated FP context */ +#define T_FSETFP 2 /* Set emulated FP context */ +#define T_GETHRTIME 3 /* Get high resolution time */ +#define T_GETHRVTIME 4 /* Get high resolution virtual time */ +#define T_GETHRESTIME 5 /* Get high resolution time */ +#define T_GETLGRP 6 /* Get home lgrpid */ + +#define T_LASTFAST 6 /* Last valid subfunction */ + +/* + * Offsets for an interrupt/trap frame. + */ +#define T_FRAME_ERR 0 +#define T_FRAME_RIP 8 +#define T_FRAME_CS 16 +#define T_FRAME_RFLAGS 24 +#define T_FRAME_RSP 32 +#define T_FRAME_SS 40 -#include <ia32/sys/trap.h> /* XX64 x86/sys/trap.h */ +#define T_FRAMERET_RIP 0 +#define T_FRAMERET_CS 8 +#define T_FRAMERET_RFLAGS 16 +#define T_FRAMERET_RSP 24 +#define T_FRAMERET_SS 32 +#ifdef __cplusplus +} #endif #endif /* _SYS_TRAP_H */ diff --git a/usr/src/uts/intel/sys/traptrace.h b/usr/src/uts/intel/sys/traptrace.h index 1dd20a9492..b8e579499e 100644 --- a/usr/src/uts/intel/sys/traptrace.h +++ b/usr/src/uts/intel/sys/traptrace.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,19 +19,279 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. */ #ifndef _SYS_TRAPTRACE_H #define _SYS_TRAPTRACE_H -#pragma ident "%Z%%M% %I% %E% SMI" +#ifdef __cplusplus +extern "C" { +#endif + +#include <sys/privregs.h> + +/* + * Trap tracing. If TRAPTRACE is defined, an entry is recorded every time + * the CPU jumps through the Interrupt Descriptor Table (IDT). One exception + * is the Double Fault handler, which does not record a traptrace entry. + * + * There are facilities to (conditionally) interleave tracing of related + * facilities e.h. x-calls. + */ + +/* + * Note: non-assembler files that include this file must include + * <sys/systm.h> before it, for the typedef of pc_t to be visible. + */ + +#define TTR_STACK_DEPTH 10 + +#ifndef _ASM + +#define TTR_PAD1_SIZE (sizeof (long) - 1) + +typedef struct { + uintptr_t ttc_next; + uintptr_t ttc_first; + uintptr_t ttc_limit; + uintptr_t ttc_current; +} trap_trace_ctl_t; + +typedef struct { + struct regs ttr_regs; + greg_t ttr_cr2; + union _ttr_info { + struct _idt_entry { + int cpuid; + short vector; + uchar_t ipl; + uchar_t spl; + uchar_t pri; + } idt_entry; + struct _gate_entry { + int sysnum; + } gate_entry; + } ttr_info; + uintptr_t ttr_curthread; + uchar_t ttr_pad[TTR_PAD1_SIZE]; + uchar_t ttr_marker; + hrtime_t ttr_stamp; + int ttr_sdepth; + pc_t ttr_stack[TTR_STACK_DEPTH]; +} trap_trace_rec_t; + +#define ttr_cpuid ttr_info.idt_entry.cpuid +#define ttr_vector ttr_info.idt_entry.vector +#define ttr_ipl ttr_info.idt_entry.ipl +#define ttr_spl ttr_info.idt_entry.spl +#define ttr_pri ttr_info.idt_entry.pri +#define ttr_sysnum ttr_info.gate_entry.sysnum + +#define TRAPTR_NENT 128 + +extern trap_trace_ctl_t trap_trace_ctl[NCPU]; /* Allocated in locore.s */ +extern size_t trap_trace_bufsize; +extern int trap_trace_freeze; +extern trap_trace_rec_t trap_trace_postmort; /* Entry used after death */ + +#define TRAPTRACE_FREEZE trap_trace_freeze = 1; +#define TRAPTRACE_UNFREEZE trap_trace_freeze = 0; + +#else /* _ASM */ + +/* + * ptr -- will be set to a TRAPTRACE entry. + * scr1 -- scratch + * scr1_32 -- 32-bit version of scr1 + * scr2 -- scratch + * marker -- register containing byte to store in marker field of entry + * + * Note that this macro defines labels "8" and "9". + */ +#ifdef TRAPTRACE + +#if defined(__amd64) + +#define TRACE_PTR(ptr, scr1, scr1_32, scr2, marker) \ + leaq trap_trace_postmort(%rip), ptr; \ + cmpl $0, trap_trace_freeze(%rip); \ + jne 9f; \ + LOADCPU(ptr); \ + movl CPU_ID(ptr), scr1_32; \ + shlq $TRAPTR_SIZE_SHIFT, scr1; \ + leaq trap_trace_ctl(%rip), scr2; \ + addq scr2, scr1; \ + movq TRAPTR_NEXT(scr1), ptr; \ + leaq TRAP_ENT_SIZE(ptr), scr2; \ + cmpq TRAPTR_LIMIT(scr1), scr2; \ + jl 8f; \ + movq TRAPTR_FIRST(scr1), scr2; \ +8: movq scr2, TRAPTR_NEXT(scr1); \ +9: movb marker, TTR_MARKER(ptr); + +#elif defined(__i386) + +#define TRACE_PTR(ptr, scr1, scr1_32, scr2, marker) \ + movl $trap_trace_postmort, ptr; \ + cmpl $0, trap_trace_freeze; \ + jne 9f; \ + LOADCPU(ptr); \ + movl CPU_ID(ptr), scr1_32; \ + shll $TRAPTR_SIZE_SHIFT, scr1; \ + addl $trap_trace_ctl, scr1; \ + movl TRAPTR_NEXT(scr1), ptr; \ + leal TRAP_ENT_SIZE(ptr), scr2; \ + cmpl TRAPTR_LIMIT(scr1), scr2; \ + jl 8f; \ + movl TRAPTR_FIRST(scr1), scr2; \ +8: movl scr2, TRAPTR_NEXT(scr1); \ +9: movb marker, TTR_MARKER(ptr); + +#endif /* __i386 */ + +/* + * ptr -- pointer to the current TRAPTRACE entry. + * reg -- pointer to the stored registers; must be on the stack + * scr1 -- scratch used as array index + * scr2 -- scratch used as temporary + * + * Note that this macro defines label "9". + * Also captures curthread on exit of loop. + */ +#if defined(__xpv) +#define __GETCR2(_mov, reg) \ + _mov %gs:CPU_VCPU_INFO, reg; \ + _mov VCPU_INFO_ARCH_CR2(reg), reg +#else +#define __GETCR2(_mov, reg) \ + _mov %cr2, reg +#endif + +#if defined(__amd64) + +#define TRACE_REGS(ptr, reg, scr1, scr2) \ + xorq scr1, scr1; \ + /*CSTYLED*/ \ +9: movq (reg, scr1, 1), scr2; \ + movq scr2, (ptr, scr1, 1); \ + addq $CLONGSIZE, scr1; \ + cmpq $REGSIZE, scr1; \ + jl 9b; \ + movq %gs:CPU_THREAD, scr2; \ + movq scr2, TTR_CURTHREAD(ptr); \ + __GETCR2(movq, scr2); \ + movq scr2, TTR_CR2(ptr) + +#elif defined(__i386) + +#define TRACE_REGS(ptr, reg, scr1, scr2) \ + xorl scr1, scr1; \ + /*CSTYLED*/ \ +9: movl (reg, scr1, 1), scr2; \ + movl scr2, (ptr, scr1, 1); \ + addl $CLONGSIZE, scr1; \ + cmpl $REGSIZE, scr1; \ + jl 9b; \ + movl %gs:CPU_THREAD, scr2; \ + movl scr2, TTR_CURTHREAD(ptr); \ + __GETCR2(movl, scr2); \ + movl scr2, TTR_CR2(ptr) + +#endif /* __i386 */ + +/* + * The time stamp macro records a high-resolution time stamp for the + * given TRAPTRACE entry. Note that %eax and %edx are plowed by this + * macro; if they are to be preserved, it's up to the caller of the macro. + */ + +#if defined(__amd64) + +#define TRACE_STAMP(reg) \ + rdtsc; \ + movl %eax, TTR_STAMP(reg); \ + movl %edx, TTR_STAMP+4(reg) + +/* + * %rbp should be set before invoking this macro. + */ + +#define TRACE_STACK(tt) \ + pushq %rdi; \ + pushq %rsi; \ + pushq %rdx; \ + pushq %rcx; \ + pushq %r8; \ + pushq %r9; \ + pushq %rax; \ + pushq %r12; \ + movq tt, %r12; \ + leaq TTR_STACK(%r12), %rdi; \ + movl $TTR_STACK_DEPTH, %esi; \ + call getpcstack; \ + movl %eax, TTR_SDEPTH(%r12); \ + popq %r12; \ + popq %rax; \ + popq %r9; \ + popq %r8; \ + popq %rcx; \ + popq %rdx; \ + popq %rsi; \ + popq %rdi + +#elif defined(__i386) + +#define TRACE_STAMP(reg) \ + xorl %eax, %eax; \ + xorl %edx, %edx; \ + btl $X86FSET_TSC, x86_featureset; \ + jnc 9f; \ + rdtsc; \ +9: movl %eax, TTR_STAMP(reg); \ + movl %edx, TTR_STAMP+4(reg) + +#define TRACE_STACK(tt) \ + pushl %eax; \ + pushl %ecx; \ + pushl %edx; \ + pushl %ebx; \ + pushl $TTR_STACK_DEPTH; \ + movl tt, %ebx; \ + leal TTR_STACK(%ebx), %eax; \ + pushl %eax; \ + call getpcstack; \ + addl $8, %esp; \ + movl %eax, TTR_SDEPTH(%ebx); \ + popl %ebx; \ + popl %edx; \ + popl %ecx; \ + popl %eax + +#endif /* __i386 */ + +#else + +#define TRACE_PTR(ptr, scr1, scr1_32, scr2, marker) +#define TRACE_REGS(ptr, reg, scr1, scr2) +#define TRACE_STAMP(reg) +#define TRACE_STACK(reg) + +#endif /* TRAPTRACE */ -#if defined(__i386) || defined(__amd64) +#endif /* _ASM */ -#include <ia32/sys/traptrace.h> /* x86/sys/traptrace.h */ +#define TT_SYSCALL 0xaa /* system call via lcall */ +#define TT_SYSENTER 0xab /* system call via sysenter */ +#define TT_SYSC 0xad /* system call via syscall (32-bit) */ +#define TT_SYSC64 0xae /* system call via syscall (64-bit) */ +#define TT_INTERRUPT 0xbb +#define TT_TRAP 0xcc +#define TT_INTTRAP 0xdd +#define TT_EVENT 0xee /* hypervisor event */ +#ifdef __cplusplus +} #endif #endif /* _SYS_TRAPTRACE_H */ |