Print this page
8956 Implement KPTI
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Robert Mustacchi <rm@joyent.com>
9210 remove KMDB branch debugging support
9211 ::crregs could do with cr2/cr3 support
9209 ::ttrace should be able to filter by thread
Reviewed by: Patrick Mooney <patrick.mooney@joyent.com>
Reviewed by: Yuri Pankov <yuripv@yuripv.net>


   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 
  26 #pragma ident   "%Z%%M% %I%     %E% SMI"
  27 
  28 /*
  29  * Companion to kdi_idt.c - 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/kdi_regs.h>


  38 
  39 /* Nothing in this file is of interest to lint. */
  40 #if !defined(__lint)
  41 
  42 /* 
  43  * The default ASM_ENTRY_ALIGN (16) wastes far too much space.  Pay no
  44  * attention to the fleet of nop's we're adding to each handler.
  45  */
  46 #undef  ASM_ENTRY_ALIGN
  47 #define ASM_ENTRY_ALIGN 8
  48 
  49 /*
  50  * We need the .align in ENTRY_NP (defined to be ASM_ENTRY_ALIGN) to match our
  51  * manual .align (KDI_MSR_PATCHOFF) in order to ensure that the space reserved
  52  * at the beginning of the handler for code is exactly KDI_MSR_PATCHOFF bytes
  53  * long.  Note that the #error below isn't supported by the preprocessor invoked
  54  * by as(1), and won't stop the build, but it'll emit a noticeable error message
  55  * which won't escape the filters.
  56  */
  57 #if ASM_ENTRY_ALIGN != KDI_MSR_PATCHOFF
  58 #error "ASM_ENTRY_ALIGN != KDI_MSR_PATCHOFF"
  59 this won't assemble
  60 #endif
  61 
  62 /*
  63  * kdi_idt_patch will, on certain processors, replace the patch points below
  64  * with MSR-clearing code.  kdi_id_patch has intimate knowledge of the size of
  65  * the nop hole, as well as the structure of the handlers.  Do not change
  66  * anything here without also changing kdi_idt_patch.
  67  */
  68 
  69 /*
  70  * Generic trap and interrupt handlers.
  71  */
  72 
  73 #if defined(__xpv) && defined(__amd64)
  74 
  75 /*
  76  * The hypervisor places r11 and rcx on the stack.


  77  */
  78 
  79 #define TRAP_NOERR(trapno) \
  80         popq    %rcx;           \
  81         popq    %r11;           \
  82         pushq   $trapno
























































  83 
  84 #define TRAP_ERR(trapno)        \
  85         popq    %rcx;           \
  86         popq    %r11;           \
  87         pushq   $0;             \
  88         pushq   $trapno
  89 
  90 #else
  91 
  92 #define TRAP_NOERR(trapno)      \
  93         push    $trapno
  94 
  95 #define TRAP_ERR(trapno)        \
  96         push    $0;             \
  97         push    $trapno
  98 
  99 #endif  /* __xpv && __amd64 */
 100 
 101 
 102 #define MKIVCT(n) \
 103         ENTRY_NP(kdi_ivct/**/n/**/);    \
 104         TRAP_ERR(n);                    \
 105         .align  KDI_MSR_PATCHOFF;       \
 106         KDI_MSR_PATCH;                  \

 107         jmp     kdi_cmnint;             \
 108         SET_SIZE(kdi_ivct/**/n/**/)
 109 
 110 #define MKTRAPHDLR(n) \
 111         ENTRY_NP(kdi_trap/**/n);        \
 112         TRAP_ERR(n);                    \
 113         .align  KDI_MSR_PATCHOFF;       \
 114         KDI_MSR_PATCH;                  \

 115         jmp     kdi_cmnint;             \
 116         SET_SIZE(kdi_trap/**/n/**/)
 117 
 118 #define MKTRAPERRHDLR(n) \
 119         ENTRY_NP(kdi_traperr/**/n);     \
 120         TRAP_NOERR(n);                  \
 121         .align  KDI_MSR_PATCHOFF;       \
 122         KDI_MSR_PATCH;                  \
 123         jmp     kdi_cmnint;             \
 124         SET_SIZE(kdi_traperr/**/n)
 125 

 126 #define MKNMIHDLR \
 127         ENTRY_NP(kdi_int2);             \
 128         TRAP_NOERR(2);                  \
 129         .align  KDI_MSR_PATCHOFF;       \
 130         KDI_MSR_PATCH;                  \



 131         jmp     kdi_nmiint;             \
 132         SET_SIZE(kdi_int2)
 133 






























 134 #define MKINVALHDLR \
 135         ENTRY_NP(kdi_invaltrap);        \
 136         TRAP_NOERR(255);                \
 137         .align  KDI_MSR_PATCHOFF;       \
 138         KDI_MSR_PATCH;                  \

 139         jmp     kdi_cmnint;             \
 140         SET_SIZE(kdi_invaltrap)
 141 















 142 /*
 143  * The handlers themselves
 144  */
 145 
 146         MKINVALHDLR
 147         MKTRAPHDLR(0)
 148         MKTRAPHDLR(1)
 149         MKNMIHDLR/*2*/
 150         MKTRAPHDLR(3)
 151         MKTRAPHDLR(4)
 152         MKTRAPHDLR(5)
 153         MKTRAPHDLR(6)
 154         MKTRAPHDLR(7)
 155         MKTRAPHDLR(9)
 156         MKTRAPHDLR(15)
 157         MKTRAPHDLR(16)
 158         MKTRAPHDLR(17)
 159         MKTRAPHDLR(18)
 160         MKTRAPHDLR(19)
 161         MKTRAPHDLR(20)
 162 
 163         MKTRAPERRHDLR(8)
 164         MKTRAPERRHDLR(10)
 165         MKTRAPERRHDLR(11)
 166         MKTRAPERRHDLR(12)
 167         MKTRAPERRHDLR(13)
 168         MKTRAPERRHDLR(14)

 169 
 170         .globl  kdi_ivct_size
 171 kdi_ivct_size:
 172         .NWORD [kdi_ivct33-kdi_ivct32]
 173         
 174         /* 10 billion and one interrupt handlers */
 175 kdi_ivct_base:
 176         MKIVCT(32);     MKIVCT(33);     MKIVCT(34);     MKIVCT(35);
 177         MKIVCT(36);     MKIVCT(37);     MKIVCT(38);     MKIVCT(39);
 178         MKIVCT(40);     MKIVCT(41);     MKIVCT(42);     MKIVCT(43);
 179         MKIVCT(44);     MKIVCT(45);     MKIVCT(46);     MKIVCT(47);
 180         MKIVCT(48);     MKIVCT(49);     MKIVCT(50);     MKIVCT(51);
 181         MKIVCT(52);     MKIVCT(53);     MKIVCT(54);     MKIVCT(55);
 182         MKIVCT(56);     MKIVCT(57);     MKIVCT(58);     MKIVCT(59);
 183         MKIVCT(60);     MKIVCT(61);     MKIVCT(62);     MKIVCT(63);
 184         MKIVCT(64);     MKIVCT(65);     MKIVCT(66);     MKIVCT(67);
 185         MKIVCT(68);     MKIVCT(69);     MKIVCT(70);     MKIVCT(71);
 186         MKIVCT(72);     MKIVCT(73);     MKIVCT(74);     MKIVCT(75);
 187         MKIVCT(76);     MKIVCT(77);     MKIVCT(78);     MKIVCT(79);
 188         MKIVCT(80);     MKIVCT(81);     MKIVCT(82);     MKIVCT(83);


 213         MKIVCT(180);    MKIVCT(181);    MKIVCT(182);    MKIVCT(183);
 214         MKIVCT(184);    MKIVCT(185);    MKIVCT(186);    MKIVCT(187);
 215         MKIVCT(188);    MKIVCT(189);    MKIVCT(190);    MKIVCT(191);
 216         MKIVCT(192);    MKIVCT(193);    MKIVCT(194);    MKIVCT(195);
 217         MKIVCT(196);    MKIVCT(197);    MKIVCT(198);    MKIVCT(199);
 218         MKIVCT(200);    MKIVCT(201);    MKIVCT(202);    MKIVCT(203);
 219         MKIVCT(204);    MKIVCT(205);    MKIVCT(206);    MKIVCT(207);
 220         MKIVCT(208);    MKIVCT(209);    MKIVCT(210);    MKIVCT(211);
 221         MKIVCT(212);    MKIVCT(213);    MKIVCT(214);    MKIVCT(215);
 222         MKIVCT(216);    MKIVCT(217);    MKIVCT(218);    MKIVCT(219);
 223         MKIVCT(220);    MKIVCT(221);    MKIVCT(222);    MKIVCT(223);
 224         MKIVCT(224);    MKIVCT(225);    MKIVCT(226);    MKIVCT(227);
 225         MKIVCT(228);    MKIVCT(229);    MKIVCT(230);    MKIVCT(231);
 226         MKIVCT(232);    MKIVCT(233);    MKIVCT(234);    MKIVCT(235);
 227         MKIVCT(236);    MKIVCT(237);    MKIVCT(238);    MKIVCT(239);
 228         MKIVCT(240);    MKIVCT(241);    MKIVCT(242);    MKIVCT(243);
 229         MKIVCT(244);    MKIVCT(245);    MKIVCT(246);    MKIVCT(247);
 230         MKIVCT(248);    MKIVCT(249);    MKIVCT(250);    MKIVCT(251);
 231         MKIVCT(252);    MKIVCT(253);    MKIVCT(254);    MKIVCT(255);
 232 






 233 #endif




   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);


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