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 2007 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 * 25 * Copyright 2018 Joyent, Inc. 26 * Copyright 2020 OmniOS Community Edition (OmniOSce) Association. 27 */ 28 29/* 30 * Companion to kdi_asm.s - the implementation of the trap and interrupt 31 * handlers. For the most part, these handlers do the same thing - they 32 * push a trap number onto the stack, followed by a jump to kdi_cmnint. 33 * Each trap and interrupt has its own handler because each one pushes a 34 * different number. 35 */ 36 37#include <sys/asm_linkage.h> 38#include <sys/asm_misc.h> 39#include <sys/machprivregs.h> 40#include <sys/privregs.h> 41#include <sys/kdi_regs.h> 42#include <sys/trap.h> 43#include <sys/param.h> 44 45#include <kdi_assym.h> 46#include <assym.h> 47 48/* 49 * The default ASM_ENTRY_ALIGN (16) wastes far too much space. 50 */ 51#undef ASM_ENTRY_ALIGN 52#define ASM_ENTRY_ALIGN 8 53 54/* 55 * Generic trap and interrupt handlers. 56 */ 57 58#if defined(__xpv) 59 60#define INTERRUPT_TRAMPOLINE 61 62#else 63 64/* 65 * If we're !xpv, then we will need to support KPTI (kernel page table 66 * isolation), where we have separate page tables for user and kernel modes. 67 * There's more detail about this in kpti_trampolines.s and hat_i86.c 68 */ 69 70#define INTERRUPT_TRAMPOLINE \ 71 pushq %r13; \ 72 pushq %r14; \ 73 subq $KPTI_R14, %rsp; \ 74 /* Check for clobbering */ \ 75 cmpq $0, KPTI_FLAG(%rsp); \ 76 je 1f; \ 77 /* Don't worry, this totally works */ \ 78 int $8; \ 791: \ 80 movq $1, KPTI_FLAG(%rsp); \ 81 /* Save current %cr3. */ \ 82 mov %cr3, %r14; \ 83 mov %r14, KPTI_TR_CR3(%rsp); \ 84 /* Switch to paranoid %cr3. */ \ 85 mov kpti_safe_cr3, %r14; \ 86 mov %r14, %cr3; \ 87 \ 88 cmpw $KCS_SEL, KPTI_CS(%rsp); \ 89 je 3f; \ 902: \ 91 /* Get our cpu_t in %r13 */ \ 92 mov %rsp, %r13; \ 93 and $(~(MMU_PAGESIZE - 1)), %r13; \ 94 subq $CPU_KPTI_START, %r13; \ 95 /* Use top of the kthread stk */ \ 96 mov CPU_THREAD(%r13), %r14; \ 97 mov T_STACK(%r14), %r14; \ 98 addq $REGSIZE+MINFRAME, %r14; \ 99 jmp 5f; \ 1003: \ 101 /* Check the %rsp in the frame. */ \ 102 /* Is it above kernel base? */ \ 103 mov kpti_kbase, %r14; \ 104 cmp %r14, KPTI_RSP(%rsp); \ 105 jb 2b; \ 106 /* Is it within the kpti_frame page? */ \ 107 mov %rsp, %r13; \ 108 and $(~(MMU_PAGESIZE - 1)), %r13; \ 109 mov KPTI_RSP(%rsp), %r14; \ 110 and $(~(MMU_PAGESIZE - 1)), %r14; \ 111 cmp %r13, %r14; \ 112 je 2b; \ 113 /* Use the %rsp from the trap frame. */ \ 114 /* We already did %cr3. */ \ 115 mov KPTI_RSP(%rsp), %r14; \ 116 and $(~0xf), %r14; \ 1175: \ 118 mov %rsp, %r13; \ 119 /* %r14 contains our destination stk */ \ 120 mov %r14, %rsp; \ 121 pushq KPTI_SS(%r13); \ 122 pushq KPTI_RSP(%r13); \ 123 pushq KPTI_RFLAGS(%r13); \ 124 pushq KPTI_CS(%r13); \ 125 pushq KPTI_RIP(%r13); \ 126 pushq KPTI_ERR(%r13); \ 127 mov KPTI_R14(%r13), %r14; \ 128 movq $0, KPTI_FLAG(%r13); \ 129 mov KPTI_R13(%r13), %r13 130 131#endif /* !__xpv */ 132 133 134#define MKIVCT(n) \ 135 ENTRY_NP(kdi_ivct##n); \ 136 XPV_TRAP_POP; \ 137 push $0; /* err */ \ 138 INTERRUPT_TRAMPOLINE; \ 139 push $n; \ 140 jmp kdi_cmnint; \ 141 SET_SIZE(kdi_ivct##n) 142 143#define MKTRAPHDLR(n) \ 144 ENTRY_NP(kdi_trap##n); \ 145 XPV_TRAP_POP; \ 146 push $0; /* err */ \ 147 INTERRUPT_TRAMPOLINE; \ 148 push $n; \ 149 jmp kdi_cmnint; \ 150 SET_SIZE(kdi_trap##n) 151 152#define MKTRAPERRHDLR(n) \ 153 ENTRY_NP(kdi_traperr##n); \ 154 XPV_TRAP_POP; \ 155 INTERRUPT_TRAMPOLINE; \ 156 push $n; \ 157 jmp kdi_cmnint; \ 158 SET_SIZE(kdi_traperr##n) 159 160#if !defined(__xpv) 161#define MKNMIHDLR \ 162 ENTRY_NP(kdi_int2); \ 163 push $0; \ 164 push $2; \ 165 pushq %r13; \ 166 mov kpti_safe_cr3, %r13; \ 167 mov %r13, %cr3; \ 168 popq %r13; \ 169 jmp kdi_nmiint; \ 170 SET_SIZE(kdi_int2) 171 172#define MKMCEHDLR \ 173 ENTRY_NP(kdi_trap18); \ 174 push $0; \ 175 push $18; \ 176 pushq %r13; \ 177 mov kpti_safe_cr3, %r13; \ 178 mov %r13, %cr3; \ 179 popq %r13; \ 180 jmp kdi_cmnint; \ 181 SET_SIZE(kdi_trap18) 182#else 183#define MKNMIHDLR \ 184 ENTRY_NP(kdi_int2); \ 185 push $0; \ 186 push $2; \ 187 jmp kdi_nmiint; \ 188 SET_SIZE(kdi_int2) 189 190#define MKMCEHDLR \ 191 ENTRY_NP(kdi_trap18); \ 192 push $0; \ 193 push $18; \ 194 jmp kdi_cmnint; \ 195 SET_SIZE(kdi_trap18) 196#endif 197 198/* 199 * The only way we should reach here is by an explicit "int 0x.." which is 200 * defined not to push an error code. 201 */ 202#define MKINVALHDLR \ 203 ENTRY_NP(kdi_invaltrap); \ 204 XPV_TRAP_POP; \ 205 push $0; /* err */ \ 206 INTERRUPT_TRAMPOLINE; \ 207 push $255; \ 208 jmp kdi_cmnint; \ 209 SET_SIZE(kdi_invaltrap) 210 211 .data 212 DGDEF3(kdi_idt, 16 * NIDT, MMU_PAGESIZE) 213 .fill MMU_PAGESIZE, 1, 0 214 215#if !defined(__xpv) 216.section ".text" 217.align MMU_PAGESIZE 218.global kdi_isr_start 219kdi_isr_start: 220 nop 221 222.global kpti_safe_cr3 223.global kpti_kbase 224#endif 225 226/* 227 * The handlers themselves 228 */ 229 230 MKINVALHDLR 231 MKTRAPHDLR(0) 232 MKTRAPHDLR(1) 233 MKNMIHDLR/*2*/ 234 MKTRAPHDLR(3) 235 MKTRAPHDLR(4) 236 MKTRAPHDLR(5) 237 MKTRAPHDLR(6) 238 MKTRAPHDLR(7) 239 MKTRAPHDLR(9) 240 MKTRAPHDLR(15) 241 MKTRAPHDLR(16) 242 MKMCEHDLR/*18*/ 243 MKTRAPHDLR(19) 244 MKTRAPHDLR(20) 245 246 MKTRAPERRHDLR(8) 247 MKTRAPERRHDLR(10) 248 MKTRAPERRHDLR(11) 249 MKTRAPERRHDLR(12) 250 MKTRAPERRHDLR(13) 251 MKTRAPERRHDLR(14) 252 MKTRAPERRHDLR(17) 253 254 .globl kdi_ivct_size 255kdi_ivct_size: 256 .NWORD [kdi_ivct33-kdi_ivct32] 257 258 /* 10 billion and one interrupt handlers */ 259kdi_ivct_base: 260 MKIVCT(32); MKIVCT(33); MKIVCT(34); MKIVCT(35); 261 MKIVCT(36); MKIVCT(37); MKIVCT(38); MKIVCT(39); 262 MKIVCT(40); MKIVCT(41); MKIVCT(42); MKIVCT(43); 263 MKIVCT(44); MKIVCT(45); MKIVCT(46); MKIVCT(47); 264 MKIVCT(48); MKIVCT(49); MKIVCT(50); MKIVCT(51); 265 MKIVCT(52); MKIVCT(53); MKIVCT(54); MKIVCT(55); 266 MKIVCT(56); MKIVCT(57); MKIVCT(58); MKIVCT(59); 267 MKIVCT(60); MKIVCT(61); MKIVCT(62); MKIVCT(63); 268 MKIVCT(64); MKIVCT(65); MKIVCT(66); MKIVCT(67); 269 MKIVCT(68); MKIVCT(69); MKIVCT(70); MKIVCT(71); 270 MKIVCT(72); MKIVCT(73); MKIVCT(74); MKIVCT(75); 271 MKIVCT(76); MKIVCT(77); MKIVCT(78); MKIVCT(79); 272 MKIVCT(80); MKIVCT(81); MKIVCT(82); MKIVCT(83); 273 MKIVCT(84); MKIVCT(85); MKIVCT(86); MKIVCT(87); 274 MKIVCT(88); MKIVCT(89); MKIVCT(90); MKIVCT(91); 275 MKIVCT(92); MKIVCT(93); MKIVCT(94); MKIVCT(95); 276 MKIVCT(96); MKIVCT(97); MKIVCT(98); MKIVCT(99); 277 MKIVCT(100); MKIVCT(101); MKIVCT(102); MKIVCT(103); 278 MKIVCT(104); MKIVCT(105); MKIVCT(106); MKIVCT(107); 279 MKIVCT(108); MKIVCT(109); MKIVCT(110); MKIVCT(111); 280 MKIVCT(112); MKIVCT(113); MKIVCT(114); MKIVCT(115); 281 MKIVCT(116); MKIVCT(117); MKIVCT(118); MKIVCT(119); 282 MKIVCT(120); MKIVCT(121); MKIVCT(122); MKIVCT(123); 283 MKIVCT(124); MKIVCT(125); MKIVCT(126); MKIVCT(127); 284 MKIVCT(128); MKIVCT(129); MKIVCT(130); MKIVCT(131); 285 MKIVCT(132); MKIVCT(133); MKIVCT(134); MKIVCT(135); 286 MKIVCT(136); MKIVCT(137); MKIVCT(138); MKIVCT(139); 287 MKIVCT(140); MKIVCT(141); MKIVCT(142); MKIVCT(143); 288 MKIVCT(144); MKIVCT(145); MKIVCT(146); MKIVCT(147); 289 MKIVCT(148); MKIVCT(149); MKIVCT(150); MKIVCT(151); 290 MKIVCT(152); MKIVCT(153); MKIVCT(154); MKIVCT(155); 291 MKIVCT(156); MKIVCT(157); MKIVCT(158); MKIVCT(159); 292 MKIVCT(160); MKIVCT(161); MKIVCT(162); MKIVCT(163); 293 MKIVCT(164); MKIVCT(165); MKIVCT(166); MKIVCT(167); 294 MKIVCT(168); MKIVCT(169); MKIVCT(170); MKIVCT(171); 295 MKIVCT(172); MKIVCT(173); MKIVCT(174); MKIVCT(175); 296 MKIVCT(176); MKIVCT(177); MKIVCT(178); MKIVCT(179); 297 MKIVCT(180); MKIVCT(181); MKIVCT(182); MKIVCT(183); 298 MKIVCT(184); MKIVCT(185); MKIVCT(186); MKIVCT(187); 299 MKIVCT(188); MKIVCT(189); MKIVCT(190); MKIVCT(191); 300 MKIVCT(192); MKIVCT(193); MKIVCT(194); MKIVCT(195); 301 MKIVCT(196); MKIVCT(197); MKIVCT(198); MKIVCT(199); 302 MKIVCT(200); MKIVCT(201); MKIVCT(202); MKIVCT(203); 303 MKIVCT(204); MKIVCT(205); MKIVCT(206); MKIVCT(207); 304 MKIVCT(208); MKIVCT(209); MKIVCT(210); MKIVCT(211); 305 MKIVCT(212); MKIVCT(213); MKIVCT(214); MKIVCT(215); 306 MKIVCT(216); MKIVCT(217); MKIVCT(218); MKIVCT(219); 307 MKIVCT(220); MKIVCT(221); MKIVCT(222); MKIVCT(223); 308 MKIVCT(224); MKIVCT(225); MKIVCT(226); MKIVCT(227); 309 MKIVCT(228); MKIVCT(229); MKIVCT(230); MKIVCT(231); 310 MKIVCT(232); MKIVCT(233); MKIVCT(234); MKIVCT(235); 311 MKIVCT(236); MKIVCT(237); MKIVCT(238); MKIVCT(239); 312 MKIVCT(240); MKIVCT(241); MKIVCT(242); MKIVCT(243); 313 MKIVCT(244); MKIVCT(245); MKIVCT(246); MKIVCT(247); 314 MKIVCT(248); MKIVCT(249); MKIVCT(250); MKIVCT(251); 315 MKIVCT(252); MKIVCT(253); MKIVCT(254); MKIVCT(255); 316 317#if !defined(__xpv) 318.section ".text" 319.align MMU_PAGESIZE 320.global kdi_isr_end 321kdi_isr_end: 322 nop 323#endif 324