Print this page
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>
9207 kdi_idt: Cast GATESEG_GETOFFSET through uintptr_t

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 ↓ 59 lines elided ↑ open up ↑
  93   95  kdi_drreg_t kdi_drreg;
  94   96  
  95   97  #ifndef __amd64
  96   98  /* Used to track the current set of valid kernel selectors. */
  97   99  uint32_t        kdi_cs;
  98  100  uint32_t        kdi_ds;
  99  101  uint32_t        kdi_fs;
 100  102  uint32_t        kdi_gs;
 101  103  #endif
 102  104  
 103      -uint_t          kdi_msr_wrexit_msr;
 104      -uint64_t        *kdi_msr_wrexit_valp;
 105      -
 106  105  uintptr_t       kdi_kernel_handler;
 107  106  
 108  107  int             kdi_trap_switch;
 109  108  
 110  109  #define KDI_MEMRANGES_MAX       2
 111  110  
 112  111  kdi_memrange_t  kdi_memranges[KDI_MEMRANGES_MAX];
 113  112  int             kdi_nmemranges;
 114  113  
 115  114  typedef void idt_hdlr_f(void);
 116  115  
 117  116  extern idt_hdlr_f kdi_trap0, kdi_trap1, kdi_int2, kdi_trap3, kdi_trap4;
 118  117  extern idt_hdlr_f kdi_trap5, kdi_trap6, kdi_trap7, kdi_trap9;
 119  118  extern idt_hdlr_f kdi_traperr10, kdi_traperr11, kdi_traperr12;
 120  119  extern idt_hdlr_f kdi_traperr13, kdi_traperr14, kdi_trap16, kdi_trap17;
 121  120  extern idt_hdlr_f kdi_trap18, kdi_trap19, kdi_trap20, kdi_ivct32;
 122  121  extern idt_hdlr_f kdi_invaltrap;
 123  122  extern size_t kdi_ivct_size;
 124      -extern char kdi_slave_entry_patch;
 125  123  
 126  124  typedef struct kdi_gate_spec {
 127  125          uint_t kgs_vec;
 128  126          uint_t kgs_dpl;
 129  127  } kdi_gate_spec_t;
 130  128  
 131  129  /*
 132  130   * Beware: kdi_pass_to_kernel() has unpleasant knowledge of this list.
 133  131   */
 134  132  static const kdi_gate_spec_t kdi_gate_specs[KDI_GATE_NVECS] = {
↓ open down ↓ 52 lines elided ↑ open up ↑
 187  185  
 188  186                  for (i = id->id_low; i <= high; i++) {
 189  187                          caddr_t hdlr = (caddr_t)id->id_basehdlr +
 190  188                              incr * (i - id->id_low);
 191  189                          set_gatesegd(&kdi_idt[i], (void (*)())hdlr, sel,
 192  190                              SDT_SYSIGT, TRP_KPL, i);
 193  191                  }
 194  192          }
 195  193  }
 196  194  
 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  195  static void
 237  196  kdi_idt_gates_install(selector_t sel, int saveold)
 238  197  {
 239  198          gate_desc_t gates[KDI_GATE_NVECS];
 240  199          int i;
 241  200  
 242  201          bzero(gates, sizeof (*gates));
 243  202  
 244  203          for (i = 0; i < KDI_GATE_NVECS; i++) {
 245  204                  const kdi_gate_spec_t *gs = &kdi_gate_specs[i];
↓ open down ↓ 25 lines elided ↑ open up ↑
 271  230   * Called when we switch to the kernel's IDT.  We need to interpose on the
 272  231   * kernel's IDT entries and stop using KMDBCODE_SEL.
 273  232   */
 274  233  void
 275  234  kdi_idt_sync(void)
 276  235  {
 277  236          kdi_idt_init(KCS_SEL);
 278  237          kdi_idt_gates_install(KCS_SEL, KDI_IDT_SAVE);
 279  238  }
 280  239  
 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  240  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  241  kdi_update_drreg(kdi_drreg_t *drreg)
 356  242  {
 357  243          kdi_drreg = *drreg;
 358  244  }
 359  245  
 360  246  void
 361  247  kdi_memrange_add(caddr_t base, size_t len)
 362  248  {
 363  249          kdi_memrange_t *mr = &kdi_memranges[kdi_nmemranges];
 364  250  
↓ open down ↓ 22 lines elided ↑ open up ↑
 387  273   * the IDTs for slave CPUs by copying the one used by the boot CPU, which has
 388  274   * already been interposed upon by KMDB.  Were we to interpose again, we'd
 389  275   * replace the kernel's descriptors with our own in the save area.  By not
 390  276   * saving, but still overwriting, we'll work in the current world, and in any
 391  277   * future world where the IDT is generated from scratch.
 392  278   */
 393  279  void
 394  280  kdi_cpu_init(void)
 395  281  {
 396  282          kdi_idt_gates_install(KCS_SEL, KDI_IDT_NOSAVE);
 397      -        /* Load the debug registers and MSRs */
      283 +        /* Load the debug registers. */
 398  284          kdi_cpu_debug_init(&kdi_cpusave[CPU->cpu_id]);
 399  285  }
 400  286  
 401  287  /*
 402  288   * Activation for all CPUs for mod-loaded kmdb, i.e. a kmdb that wasn't
 403  289   * loaded at boot.
 404  290   */
 405  291  static int
 406  292  kdi_cpu_activate(void)
 407  293  {
↓ open down ↓ 33 lines elided ↑ open up ↑
 441  327          kdi_ds = kdi_fs = kdi_gs = B32DATA_SEL;
 442  328  #endif
 443  329  
 444  330          kdi_memranges[0].mr_base = kdi_segdebugbase;
 445  331          kdi_memranges[0].mr_lim = kdi_segdebugbase + kdi_segdebugsize - 1;
 446  332          kdi_nmemranges = 1;
 447  333  
 448  334          kdi_drreg.dr_ctl = KDIREG_DRCTL_RESERVED;
 449  335          kdi_drreg.dr_stat = KDIREG_DRSTAT_RESERVED;
 450  336  
 451      -        kdi_msr_wrexit_msr = 0;
 452      -        kdi_msr_wrexit_valp = NULL;
 453      -
 454  337          if (boothowto & RB_KMDB) {
 455  338                  kdi_idt_gates_install(KMDBCODE_SEL, KDI_IDT_NOSAVE);
 456  339          } else {
 457  340                  xc_call(0, 0, 0, CPUSET2BV(cpuset),
 458  341                      (xc_func_t)kdi_cpu_activate);
 459  342          }
 460  343  }
 461  344  
 462  345  static int
 463  346  kdi_cpu_deactivate(void)
↓ open down ↓ 70 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX