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