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