xref: /freebsd/sys/x86/linux/linux_x86.c (revision 0541653520fc122ef01595d405f0633bd129947d)
12434137fSDmitry Chagin /*-
24d846d26SWarner Losh  * SPDX-License-Identifier: BSD-2-Clause
32434137fSDmitry Chagin  *
42434137fSDmitry Chagin  * Copyright (c) 1994-1996 Søren Schmidt
52434137fSDmitry Chagin  * All rights reserved.
62434137fSDmitry Chagin  *
72434137fSDmitry Chagin  * Redistribution and use in source and binary forms, with or without
82434137fSDmitry Chagin  * modification, are permitted provided that the following conditions
92434137fSDmitry Chagin  * are met:
102434137fSDmitry Chagin  * 1. Redistributions of source code must retain the above copyright
112434137fSDmitry Chagin  *    notice, this list of conditions and the following disclaimer.
122434137fSDmitry Chagin  * 2. Redistributions in binary form must reproduce the above copyright
132434137fSDmitry Chagin  *    notice, this list of conditions and the following disclaimer in the
142434137fSDmitry Chagin  *    documentation and/or other materials provided with the distribution.
152434137fSDmitry Chagin  *
162434137fSDmitry Chagin  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
172434137fSDmitry Chagin  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
182434137fSDmitry Chagin  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
192434137fSDmitry Chagin  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
202434137fSDmitry Chagin  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
212434137fSDmitry Chagin  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
222434137fSDmitry Chagin  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
232434137fSDmitry Chagin  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
242434137fSDmitry Chagin  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
252434137fSDmitry Chagin  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
262434137fSDmitry Chagin  * SUCH DAMAGE.
272434137fSDmitry Chagin  */
282434137fSDmitry Chagin 
292434137fSDmitry Chagin #include <sys/param.h>
302434137fSDmitry Chagin #include <sys/signal.h>
31*4281dab8SDmitry Chagin #include <x86/specialreg.h>
322434137fSDmitry Chagin #include <x86/trap.h>
33*4281dab8SDmitry Chagin #include <x86/x86_var.h>
342434137fSDmitry Chagin 
352434137fSDmitry Chagin #include <x86/linux/linux_x86.h>
362434137fSDmitry Chagin 
379016ec05SDmitry Chagin #define LINUX_T_UNKNOWN  255
389016ec05SDmitry Chagin static int _bsd_to_linux_trapcode[] = {
399016ec05SDmitry Chagin 	LINUX_T_UNKNOWN,	/* 0 */
409016ec05SDmitry Chagin 	6,			/* 1  T_PRIVINFLT */
419016ec05SDmitry Chagin 	LINUX_T_UNKNOWN,	/* 2 */
429016ec05SDmitry Chagin 	3,			/* 3  T_BPTFLT */
439016ec05SDmitry Chagin 	LINUX_T_UNKNOWN,	/* 4 */
449016ec05SDmitry Chagin 	LINUX_T_UNKNOWN,	/* 5 */
459016ec05SDmitry Chagin 	16,			/* 6  T_ARITHTRAP */
469016ec05SDmitry Chagin 	254,			/* 7  T_ASTFLT */
479016ec05SDmitry Chagin 	LINUX_T_UNKNOWN,	/* 8 */
489016ec05SDmitry Chagin 	13,			/* 9  T_PROTFLT */
499016ec05SDmitry Chagin 	1,			/* 10 T_TRCTRAP */
509016ec05SDmitry Chagin 	LINUX_T_UNKNOWN,	/* 11 */
519016ec05SDmitry Chagin 	14,			/* 12 T_PAGEFLT */
529016ec05SDmitry Chagin 	LINUX_T_UNKNOWN,	/* 13 */
539016ec05SDmitry Chagin 	17,			/* 14 T_ALIGNFLT */
549016ec05SDmitry Chagin 	LINUX_T_UNKNOWN,	/* 15 */
559016ec05SDmitry Chagin 	LINUX_T_UNKNOWN,	/* 16 */
569016ec05SDmitry Chagin 	LINUX_T_UNKNOWN,	/* 17 */
579016ec05SDmitry Chagin 	0,			/* 18 T_DIVIDE */
589016ec05SDmitry Chagin 	2,			/* 19 T_NMI */
599016ec05SDmitry Chagin 	4,			/* 20 T_OFLOW */
609016ec05SDmitry Chagin 	5,			/* 21 T_BOUND */
619016ec05SDmitry Chagin 	7,			/* 22 T_DNA */
629016ec05SDmitry Chagin 	8,			/* 23 T_DOUBLEFLT */
639016ec05SDmitry Chagin 	9,			/* 24 T_FPOPFLT */
649016ec05SDmitry Chagin 	10,			/* 25 T_TSSFLT */
659016ec05SDmitry Chagin 	11,			/* 26 T_SEGNPFLT */
669016ec05SDmitry Chagin 	12,			/* 27 T_STKFLT */
679016ec05SDmitry Chagin 	18,			/* 28 T_MCHK */
689016ec05SDmitry Chagin 	19,			/* 29 T_XMMFLT */
699016ec05SDmitry Chagin 	15			/* 30 T_RESERVED */
709016ec05SDmitry Chagin };
719016ec05SDmitry Chagin 
722434137fSDmitry Chagin /*
732434137fSDmitry Chagin  * If FreeBSD & Linux have a difference of opinion about what a trap
742434137fSDmitry Chagin  * means, deal with it here.
752434137fSDmitry Chagin  */
762434137fSDmitry Chagin int
linux_translate_traps(int signal,int trap_code)772434137fSDmitry Chagin linux_translate_traps(int signal, int trap_code)
782434137fSDmitry Chagin {
792434137fSDmitry Chagin 	if (signal != SIGBUS)
802434137fSDmitry Chagin 		return (signal);
812434137fSDmitry Chagin 	switch (trap_code) {
822434137fSDmitry Chagin 	case T_PROTFLT:
832434137fSDmitry Chagin 	case T_TSSFLT:
842434137fSDmitry Chagin 	case T_DOUBLEFLT:
852434137fSDmitry Chagin 	case T_PAGEFLT:
862434137fSDmitry Chagin 		return (SIGSEGV);
872434137fSDmitry Chagin 	default:
882434137fSDmitry Chagin 		return (signal);
892434137fSDmitry Chagin 	}
902434137fSDmitry Chagin }
919016ec05SDmitry Chagin 
929016ec05SDmitry Chagin int
bsd_to_linux_trapcode(int code)939016ec05SDmitry Chagin bsd_to_linux_trapcode(int code)
949016ec05SDmitry Chagin {
959016ec05SDmitry Chagin 
969016ec05SDmitry Chagin 	return (code < nitems(_bsd_to_linux_trapcode) ?
979016ec05SDmitry Chagin 	    _bsd_to_linux_trapcode[code] : LINUX_T_UNKNOWN);
989016ec05SDmitry Chagin }
99*4281dab8SDmitry Chagin 
100*4281dab8SDmitry Chagin u_int
linux_x86_elf_hwcap2(void)101*4281dab8SDmitry Chagin linux_x86_elf_hwcap2(void)
102*4281dab8SDmitry Chagin {
103*4281dab8SDmitry Chagin 	static u_int elf_hwcap2 = 0;
104*4281dab8SDmitry Chagin 	static bool elf_hwcap2_valid = false;
105*4281dab8SDmitry Chagin 
106*4281dab8SDmitry Chagin 	if (!elf_hwcap2_valid) {
107*4281dab8SDmitry Chagin 		if ((cpu_stdext_feature & CPUID_STDEXT_FSGSBASE) != 0)
108*4281dab8SDmitry Chagin 			elf_hwcap2 |= LINUX_HWCAP2_FSGSBASE;
109*4281dab8SDmitry Chagin 		elf_hwcap2_valid = true;
110*4281dab8SDmitry Chagin 	}
111*4281dab8SDmitry Chagin 	return (elf_hwcap2);
112*4281dab8SDmitry Chagin }
113