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>
9207 kdi_idt: Cast GATESEG_GETOFFSET through uintptr_t
Reviewed by: Yuri Pankov <yuripv@yuripv.net>

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/intel/kdi/kdi_idt.c
          +++ new/usr/src/uts/intel/kdi/kdi_idt.c
↓ open down ↓ 13 lines elided ↑ open up ↑
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  23   23   * Use is subject to license terms.
       24 + *
       25 + * Copyright 2018 Joyent, Inc.
  24   26   */
  25   27  
  26   28  /*
  27   29   * Management of KMDB's IDT, which is installed upon KMDB activation.
  28   30   *
  29   31   * Debugger activation has two flavors, which cover the cases where KMDB is
  30   32   * loaded at boot, and when it is loaded after boot.  In brief, in both cases,
  31   33   * the KDI needs to interpose upon several handlers in the IDT.  When
  32   34   * mod-loaded KMDB is deactivated, we undo the IDT interposition, restoring the
  33   35   * handlers to what they were before we started.
↓ open down ↓ 35 lines elided ↑ open up ↑
  69   71  #include <sys/types.h>
  70   72  #include <sys/segments.h>
  71   73  #include <sys/trap.h>
  72   74  #include <sys/cpuvar.h>
  73   75  #include <sys/reboot.h>
  74   76  #include <sys/sunddi.h>
  75   77  #include <sys/archsystm.h>
  76   78  #include <sys/kdi_impl.h>
  77   79  #include <sys/x_call.h>
  78   80  #include <ia32/sys/psw.h>
       81 +#include <vm/hat_i86.h>
  79   82  
  80   83  #define KDI_GATE_NVECS  3
  81   84  
  82   85  #define KDI_IDT_NOSAVE  0
  83   86  #define KDI_IDT_SAVE    1
  84   87  
  85   88  #define KDI_IDT_DTYPE_KERNEL    0
  86   89  #define KDI_IDT_DTYPE_BOOT      1
  87   90  
  88   91  kdi_cpusave_t *kdi_cpusave;
↓ open down ↓ 4 lines elided ↑ open up ↑
  93   96  kdi_drreg_t kdi_drreg;
  94   97  
  95   98  #ifndef __amd64
  96   99  /* Used to track the current set of valid kernel selectors. */
  97  100  uint32_t        kdi_cs;
  98  101  uint32_t        kdi_ds;
  99  102  uint32_t        kdi_fs;
 100  103  uint32_t        kdi_gs;
 101  104  #endif
 102  105  
 103      -uint_t          kdi_msr_wrexit_msr;
 104      -uint64_t        *kdi_msr_wrexit_valp;
 105      -
 106  106  uintptr_t       kdi_kernel_handler;
 107  107  
 108  108  int             kdi_trap_switch;
 109  109  
 110  110  #define KDI_MEMRANGES_MAX       2
 111  111  
 112  112  kdi_memrange_t  kdi_memranges[KDI_MEMRANGES_MAX];
 113  113  int             kdi_nmemranges;
 114  114  
 115  115  typedef void idt_hdlr_f(void);
 116  116  
 117  117  extern idt_hdlr_f kdi_trap0, kdi_trap1, kdi_int2, kdi_trap3, kdi_trap4;
 118  118  extern idt_hdlr_f kdi_trap5, kdi_trap6, kdi_trap7, kdi_trap9;
 119  119  extern idt_hdlr_f kdi_traperr10, kdi_traperr11, kdi_traperr12;
 120      -extern idt_hdlr_f kdi_traperr13, kdi_traperr14, kdi_trap16, kdi_trap17;
      120 +extern idt_hdlr_f kdi_traperr13, kdi_traperr14, kdi_trap16, kdi_traperr17;
 121  121  extern idt_hdlr_f kdi_trap18, kdi_trap19, kdi_trap20, kdi_ivct32;
 122  122  extern idt_hdlr_f kdi_invaltrap;
 123  123  extern size_t kdi_ivct_size;
 124      -extern char kdi_slave_entry_patch;
 125  124  
 126  125  typedef struct kdi_gate_spec {
 127  126          uint_t kgs_vec;
 128  127          uint_t kgs_dpl;
 129  128  } kdi_gate_spec_t;
 130  129  
 131  130  /*
 132  131   * Beware: kdi_pass_to_kernel() has unpleasant knowledge of this list.
 133  132   */
 134  133  static const kdi_gate_spec_t kdi_gate_specs[KDI_GATE_NVECS] = {
 135  134          { T_SGLSTP, TRP_KPL },
 136  135          { T_BPTFLT, TRP_UPL },
 137  136          { T_DBGENTR, TRP_KPL }
 138  137  };
 139  138  
 140  139  static gate_desc_t kdi_kgates[KDI_GATE_NVECS];
 141  140  
 142      -gate_desc_t kdi_idt[NIDT];
      141 +extern gate_desc_t kdi_idt[NIDT];
 143  142  
 144  143  struct idt_description {
 145  144          uint_t id_low;
 146  145          uint_t id_high;
 147  146          idt_hdlr_f *id_basehdlr;
 148  147          size_t *id_incrp;
 149  148  } idt_description[] = {
 150  149          { T_ZERODIV, 0,         kdi_trap0, NULL },
 151  150          { T_SGLSTP, 0,          kdi_trap1, NULL },
 152  151          { T_NMIFLT, 0,          kdi_int2, NULL },
↓ open down ↓ 6 lines elided ↑ open up ↑
 159  158          { T_DBLFLT, 0,          syserrtrap, NULL },
 160  159  #endif
 161  160          { T_EXTOVRFLT, 0,       kdi_trap9, NULL },
 162  161          { T_TSSFLT, 0,          kdi_traperr10, NULL },
 163  162          { T_SEGFLT, 0,          kdi_traperr11, NULL },
 164  163          { T_STKFLT, 0,          kdi_traperr12, NULL },
 165  164          { T_GPFLT, 0,           kdi_traperr13, NULL },
 166  165          { T_PGFLT, 0,           kdi_traperr14, NULL },
 167  166          { 15, 0,                kdi_invaltrap, NULL },
 168  167          { T_EXTERRFLT, 0,       kdi_trap16, NULL },
 169      -        { T_ALIGNMENT, 0,       kdi_trap17, NULL },
      168 +        { T_ALIGNMENT, 0,       kdi_traperr17, NULL },
 170  169          { T_MCE, 0,             kdi_trap18, NULL },
 171  170          { T_SIMDFPE, 0,         kdi_trap19, NULL },
 172  171          { T_DBGENTR, 0,         kdi_trap20, NULL },
 173  172          { 21, 31,               kdi_invaltrap, NULL },
 174  173          { 32, 255,              kdi_ivct32, &kdi_ivct_size },
 175  174          { 0, 0, NULL },
 176  175  };
 177  176  
 178  177  void
 179  178  kdi_idt_init(selector_t sel)
 180  179  {
 181  180          struct idt_description *id;
 182  181          int i;
 183  182  
 184  183          for (id = idt_description; id->id_basehdlr != NULL; id++) {
 185  184                  uint_t high = id->id_high != 0 ? id->id_high : id->id_low;
 186  185                  size_t incr = id->id_incrp != NULL ? *id->id_incrp : 0;
 187  186  
      187 +#if !defined(__xpv)
      188 +                if (kpti_enable && sel == KCS_SEL && id->id_low == T_DBLFLT)
      189 +                        id->id_basehdlr = tr_syserrtrap;
      190 +#endif
      191 +
 188  192                  for (i = id->id_low; i <= high; i++) {
 189  193                          caddr_t hdlr = (caddr_t)id->id_basehdlr +
 190  194                              incr * (i - id->id_low);
 191  195                          set_gatesegd(&kdi_idt[i], (void (*)())hdlr, sel,
 192      -                            SDT_SYSIGT, TRP_KPL, i);
      196 +                            SDT_SYSIGT, TRP_KPL, IST_DBG);
 193  197                  }
 194  198          }
 195  199  }
 196  200  
 197      -/*
 198      - * Patch caller-provided code into the debugger's IDT handlers.  This code is
 199      - * used to save MSRs that must be saved before the first branch.  All handlers
 200      - * are essentially the same, and end with a branch to kdi_cmnint.  To save the
 201      - * MSR, we need to patch in before the branch.  The handlers have the following
 202      - * structure: KDI_MSR_PATCHOFF bytes of code, KDI_MSR_PATCHSZ bytes of
 203      - * patchable space, followed by more code.
 204      - */
 205      -void
 206      -kdi_idt_patch(caddr_t code, size_t sz)
 207      -{
 208      -        int i;
 209      -
 210      -        ASSERT(sz <= KDI_MSR_PATCHSZ);
 211      -
 212      -        for (i = 0; i < sizeof (kdi_idt) / sizeof (struct gate_desc); i++) {
 213      -                gate_desc_t *gd;
 214      -                uchar_t *patch;
 215      -
 216      -                if (i == T_DBLFLT)
 217      -                        continue;       /* uses kernel's handler */
 218      -
 219      -                gd = &kdi_idt[i];
 220      -                patch = (uchar_t *)GATESEG_GETOFFSET(gd) + KDI_MSR_PATCHOFF;
 221      -
 222      -                /*
 223      -                 * We can't ASSERT that there's a nop here, because this may be
 224      -                 * a debugger restart.  In that case, we're copying the new
 225      -                 * patch point over the old one.
 226      -                 */
 227      -                /* FIXME: dtrace fbt ... */
 228      -                bcopy(code, patch, sz);
 229      -
 230      -                /* Fill the rest with nops to be sure */
 231      -                while (sz < KDI_MSR_PATCHSZ)
 232      -                        patch[sz++] = 0x90; /* nop */
 233      -        }
 234      -}
 235      -
 236  201  static void
 237  202  kdi_idt_gates_install(selector_t sel, int saveold)
 238  203  {
 239  204          gate_desc_t gates[KDI_GATE_NVECS];
 240  205          int i;
 241  206  
 242  207          bzero(gates, sizeof (*gates));
 243  208  
 244  209          for (i = 0; i < KDI_GATE_NVECS; i++) {
 245  210                  const kdi_gate_spec_t *gs = &kdi_gate_specs[i];
 246  211                  uintptr_t func = GATESEG_GETOFFSET(&kdi_idt[gs->kgs_vec]);
 247  212                  set_gatesegd(&gates[i], (void (*)())func, sel, SDT_SYSIGT,
 248      -                    gs->kgs_dpl, gs->kgs_vec);
      213 +                    gs->kgs_dpl, IST_DBG);
 249  214          }
 250  215  
 251  216          for (i = 0; i < KDI_GATE_NVECS; i++) {
 252  217                  uint_t vec = kdi_gate_specs[i].kgs_vec;
 253  218  
 254  219                  if (saveold)
 255  220                          kdi_kgates[i] = CPU->cpu_m.mcpu_idt[vec];
 256  221  
 257  222                  kdi_idt_write(&gates[i], vec);
 258  223          }
↓ open down ↓ 12 lines elided ↑ open up ↑
 271  236   * Called when we switch to the kernel's IDT.  We need to interpose on the
 272  237   * kernel's IDT entries and stop using KMDBCODE_SEL.
 273  238   */
 274  239  void
 275  240  kdi_idt_sync(void)
 276  241  {
 277  242          kdi_idt_init(KCS_SEL);
 278  243          kdi_idt_gates_install(KCS_SEL, KDI_IDT_SAVE);
 279  244  }
 280  245  
 281      -/*
 282      - * On some processors, we'll need to clear a certain MSR before proceeding into
 283      - * the debugger.  Complicating matters, this MSR must be cleared before we take
 284      - * any branches.  We have patch points in every trap handler, which will cover
 285      - * all entry paths for master CPUs.  We also have a patch point in the slave
 286      - * entry code.
 287      - */
 288      -static void
 289      -kdi_msr_add_clrentry(uint_t msr)
 290      -{
 291      -#ifdef __amd64
 292      -        uchar_t code[] = {
 293      -                0x51, 0x50, 0x52,               /* pushq %rcx, %rax, %rdx */
 294      -                0xb9, 0x00, 0x00, 0x00, 0x00,   /* movl $MSRNUM, %ecx */
 295      -                0x31, 0xc0,                     /* clr %eax */
 296      -                0x31, 0xd2,                     /* clr %edx */
 297      -                0x0f, 0x30,                     /* wrmsr */
 298      -                0x5a, 0x58, 0x59                /* popq %rdx, %rax, %rcx */
 299      -        };
 300      -        uchar_t *patch = &code[4];
 301      -#else
 302      -        uchar_t code[] = {
 303      -                0x60,                           /* pushal */
 304      -                0xb9, 0x00, 0x00, 0x00, 0x00,   /* movl $MSRNUM, %ecx */
 305      -                0x31, 0xc0,                     /* clr %eax */
 306      -                0x31, 0xd2,                     /* clr %edx */
 307      -                0x0f, 0x30,                     /* wrmsr */
 308      -                0x61                            /* popal */
 309      -        };
 310      -        uchar_t *patch = &code[2];
 311      -#endif
 312      -
 313      -        bcopy(&msr, patch, sizeof (uint32_t));
 314      -
 315      -        kdi_idt_patch((caddr_t)code, sizeof (code));
 316      -
 317      -        bcopy(code, &kdi_slave_entry_patch, sizeof (code));
 318      -}
 319      -
 320      -static void
 321      -kdi_msr_add_wrexit(uint_t msr, uint64_t *valp)
 322      -{
 323      -        kdi_msr_wrexit_msr = msr;
 324      -        kdi_msr_wrexit_valp = valp;
 325      -}
 326      -
 327  246  void
 328      -kdi_set_debug_msrs(kdi_msr_t *msrs)
 329      -{
 330      -        int nmsrs, i;
 331      -
 332      -        ASSERT(kdi_cpusave[0].krs_msr == NULL);
 333      -
 334      -        /* Look in CPU0's MSRs for any special MSRs. */
 335      -        for (nmsrs = 0; msrs[nmsrs].msr_num != 0; nmsrs++) {
 336      -                switch (msrs[nmsrs].msr_type) {
 337      -                case KDI_MSR_CLEARENTRY:
 338      -                        kdi_msr_add_clrentry(msrs[nmsrs].msr_num);
 339      -                        break;
 340      -
 341      -                case KDI_MSR_WRITEDELAY:
 342      -                        kdi_msr_add_wrexit(msrs[nmsrs].msr_num,
 343      -                            msrs[nmsrs].kdi_msr_valp);
 344      -                        break;
 345      -                }
 346      -        }
 347      -
 348      -        nmsrs++;
 349      -
 350      -        for (i = 0; i < kdi_ncpusave; i++)
 351      -                kdi_cpusave[i].krs_msr = &msrs[nmsrs * i];
 352      -}
 353      -
 354      -void
 355  247  kdi_update_drreg(kdi_drreg_t *drreg)
 356  248  {
 357  249          kdi_drreg = *drreg;
 358  250  }
 359  251  
 360  252  void
 361  253  kdi_memrange_add(caddr_t base, size_t len)
 362  254  {
 363  255          kdi_memrange_t *mr = &kdi_memranges[kdi_nmemranges];
 364  256  
↓ open down ↓ 22 lines elided ↑ open up ↑
 387  279   * the IDTs for slave CPUs by copying the one used by the boot CPU, which has
 388  280   * already been interposed upon by KMDB.  Were we to interpose again, we'd
 389  281   * replace the kernel's descriptors with our own in the save area.  By not
 390  282   * saving, but still overwriting, we'll work in the current world, and in any
 391  283   * future world where the IDT is generated from scratch.
 392  284   */
 393  285  void
 394  286  kdi_cpu_init(void)
 395  287  {
 396  288          kdi_idt_gates_install(KCS_SEL, KDI_IDT_NOSAVE);
 397      -        /* Load the debug registers and MSRs */
      289 +        /* Load the debug registers. */
 398  290          kdi_cpu_debug_init(&kdi_cpusave[CPU->cpu_id]);
 399  291  }
 400  292  
 401  293  /*
 402  294   * Activation for all CPUs for mod-loaded kmdb, i.e. a kmdb that wasn't
 403  295   * loaded at boot.
 404  296   */
 405  297  static int
 406  298  kdi_cpu_activate(void)
 407  299  {
↓ open down ↓ 33 lines elided ↑ open up ↑
 441  333          kdi_ds = kdi_fs = kdi_gs = B32DATA_SEL;
 442  334  #endif
 443  335  
 444  336          kdi_memranges[0].mr_base = kdi_segdebugbase;
 445  337          kdi_memranges[0].mr_lim = kdi_segdebugbase + kdi_segdebugsize - 1;
 446  338          kdi_nmemranges = 1;
 447  339  
 448  340          kdi_drreg.dr_ctl = KDIREG_DRCTL_RESERVED;
 449  341          kdi_drreg.dr_stat = KDIREG_DRSTAT_RESERVED;
 450  342  
 451      -        kdi_msr_wrexit_msr = 0;
 452      -        kdi_msr_wrexit_valp = NULL;
 453      -
 454  343          if (boothowto & RB_KMDB) {
 455  344                  kdi_idt_gates_install(KMDBCODE_SEL, KDI_IDT_NOSAVE);
 456  345          } else {
 457  346                  xc_call(0, 0, 0, CPUSET2BV(cpuset),
 458  347                      (xc_func_t)kdi_cpu_activate);
 459  348          }
 460  349  }
 461  350  
 462  351  static int
 463  352  kdi_cpu_deactivate(void)
↓ open down ↓ 36 lines elided ↑ open up ↑
 500  389                  return (0);
 501  390  
 502  391          if (tt == T_BPTFLT && kdi_dtrace_get_state() ==
 503  392              KDI_DTSTATE_DTRACE_ACTIVE)
 504  393                  return (1);
 505  394  
 506  395          /*
 507  396           * See the comments in the kernel's T_SGLSTP handler for why we need to
 508  397           * do this.
 509  398           */
      399 +#if !defined(__xpv)
 510  400          if (tt == T_SGLSTP &&
 511      -            (pc == (greg_t)sys_sysenter || pc == (greg_t)brand_sys_sysenter))
      401 +            (pc == (greg_t)sys_sysenter || pc == (greg_t)brand_sys_sysenter ||
      402 +            pc == (greg_t)tr_sys_sysenter ||
      403 +            pc == (greg_t)tr_brand_sys_sysenter)) {
      404 +#else
      405 +        if (tt == T_SGLSTP &&
      406 +            (pc == (greg_t)sys_sysenter || pc == (greg_t)brand_sys_sysenter)) {
      407 +#endif
 512  408                  return (1);
      409 +        }
 513  410  
 514  411          return (0);
 515  412  }
 516  413  
 517  414  /*
 518  415   * State has been saved, and all CPUs are on the CPU-specific stacks.  All
 519  416   * CPUs enter here, and head off into the debugger proper.
 520  417   */
 521  418  void
 522  419  kdi_debugger_entry(kdi_cpusave_t *cpusave)
↓ open down ↓ 11 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX