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 */