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