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>

Split Close
Expand all
Collapse all
          --- old/usr/src/cmd/mdb/i86pc/modules/unix/unix.c
          +++ new/usr/src/cmd/mdb/i86pc/modules/unix/unix.c
↓ open down ↓ 12 lines elided ↑ open up ↑
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  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 (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
  23      - * Copyright 2015 Joyent, Inc.
       23 + * Copyright 2018 Joyent, Inc.
  24   24   */
  25   25  
  26   26  #include <mdb/mdb_modapi.h>
  27   27  #include <mdb/mdb_ctf.h>
  28   28  #include <sys/cpuvar.h>
  29   29  #include <sys/systm.h>
  30   30  #include <sys/traptrace.h>
  31   31  #include <sys/x_call.h>
  32   32  #include <sys/xc_levels.h>
  33   33  #include <sys/avintr.h>
↓ open down ↓ 368 lines elided ↑ open up ↑
 402  402          { TT_SYSC64, "sc64", ttrace_syscall },
 403  403          { TT_INTERRUPT, "intr", ttrace_interrupt },
 404  404          { TT_TRAP, "trap", ttrace_trap },
 405  405          { TT_EVENT, "evnt", ttrace_trap },
 406  406          { 0, NULL, NULL }
 407  407  };
 408  408  
 409  409  typedef struct ttrace_dcmd {
 410  410          processorid_t ttd_cpu;
 411  411          uint_t ttd_extended;
      412 +        uintptr_t ttd_kthread;
 412  413          trap_trace_ctl_t ttd_ttc[NCPU];
 413  414  } ttrace_dcmd_t;
 414  415  
 415  416  #if defined(__amd64)
 416  417  
 417  418  #define DUMP(reg) #reg, regs->r_##reg
 418  419  #define THREEREGS       "         %3s: %16lx %3s: %16lx %3s: %16lx\n"
 419  420  
 420  421  static void
 421  422  ttrace_dumpregs(trap_trace_rec_t *rec)
↓ open down ↓ 2 lines elided ↑ open up ↑
 424  425  
 425  426          mdb_printf(THREEREGS, DUMP(rdi), DUMP(rsi), DUMP(rdx));
 426  427          mdb_printf(THREEREGS, DUMP(rcx), DUMP(r8), DUMP(r9));
 427  428          mdb_printf(THREEREGS, DUMP(rax), DUMP(rbx), DUMP(rbp));
 428  429          mdb_printf(THREEREGS, DUMP(r10), DUMP(r11), DUMP(r12));
 429  430          mdb_printf(THREEREGS, DUMP(r13), DUMP(r14), DUMP(r15));
 430  431          mdb_printf(THREEREGS, DUMP(ds), DUMP(es), DUMP(fs));
 431  432          mdb_printf(THREEREGS, DUMP(gs), "trp", regs->r_trapno, DUMP(err));
 432  433          mdb_printf(THREEREGS, DUMP(rip), DUMP(cs), DUMP(rfl));
 433  434          mdb_printf(THREEREGS, DUMP(rsp), DUMP(ss), "cr2", rec->ttr_cr2);
      435 +        mdb_printf("         %3s: %16lx %3s: %16lx\n",
      436 +            "fsb", regs->__r_fsbase,
      437 +            "gsb", regs->__r_gsbase);
 434  438          mdb_printf("\n");
 435  439  }
 436  440  
 437  441  #else
 438  442  
 439  443  #define DUMP(reg) #reg, regs->r_##reg
 440  444  #define FOURREGS        "         %3s: %08x %3s: %08x %3s: %08x %3s: %08x\n"
 441  445  
 442  446  static void
 443  447  ttrace_dumpregs(trap_trace_rec_t *rec)
↓ open down ↓ 27 lines elided ↑ open up ↑
 471  475          }
 472  476  
 473  477          if (cpu == -1) {
 474  478                  mdb_warn("couldn't find %p in any trap trace ctl\n", addr);
 475  479                  return (WALK_ERR);
 476  480          }
 477  481  
 478  482          if (dcmd->ttd_cpu != -1 && cpu != dcmd->ttd_cpu)
 479  483                  return (WALK_NEXT);
 480  484  
      485 +        if (dcmd->ttd_kthread != 0 &&
      486 +            dcmd->ttd_kthread != rec->ttr_curthread)
      487 +                return (WALK_NEXT);
      488 +
 481  489          mdb_printf("%3d %15llx ", cpu, rec->ttr_stamp);
 482  490  
 483  491          for (i = 0; ttrace_hdlr[i].t_hdlr != NULL; i++) {
 484  492                  if (rec->ttr_marker != ttrace_hdlr[i].t_marker)
 485  493                          continue;
 486  494                  mdb_printf("%4s ", ttrace_hdlr[i].t_name);
 487  495                  if (ttrace_hdlr[i].t_hdlr(rec) == -1)
 488  496                          return (WALK_ERR);
 489  497          }
 490  498  
↓ open down ↓ 39 lines elided ↑ open up ↑
 530  538          dcmd.ttd_cpu = -1;
 531  539          dcmd.ttd_extended = FALSE;
 532  540  
 533  541          if (mdb_readsym(ttc, ttc_size, "trap_trace_ctl") == -1) {
 534  542                  mdb_warn("symbol 'trap_trace_ctl' not found; "
 535  543                      "non-TRAPTRACE kernel?\n");
 536  544                  return (DCMD_ERR);
 537  545          }
 538  546  
 539  547          if (mdb_getopts(argc, argv,
 540      -            'x', MDB_OPT_SETBITS, TRUE, &dcmd.ttd_extended, NULL) != argc)
      548 +            'x', MDB_OPT_SETBITS, TRUE, &dcmd.ttd_extended,
      549 +            't', MDB_OPT_UINTPTR, &dcmd.ttd_kthread, NULL) != argc)
 541  550                  return (DCMD_USAGE);
 542  551  
 543  552          if (DCMD_HDRSPEC(flags)) {
 544  553                  mdb_printf("%3s %15s %4s %2s %-*s%s\n", "CPU",
 545  554                      "TIMESTAMP", "TYPE", "Vec", TT_HDLR_WIDTH, "HANDLER",
 546  555                      " EIP");
 547  556          }
 548  557  
 549  558          if (flags & DCMD_ADDRSPEC) {
 550  559                  if (addr >= NCPU) {
↓ open down ↓ 189 lines elided ↑ open up ↑
 740  749              "-m Interpret the PFN as an MFN (machine frame number)\n");
 741  750  }
 742  751  
 743  752  static void
 744  753  ptable_help(void)
 745  754  {
 746  755          mdb_printf(
 747  756              "Given a PFN holding a page table, print its contents, and\n"
 748  757              "the address of the corresponding htable structure.\n"
 749  758              "\n"
 750      -            "-m Interpret the PFN as an MFN (machine frame number)\n");
      759 +            "-m Interpret the PFN as an MFN (machine frame number)\n"
      760 +            "-l force page table level (3 is top)\n");
 751  761  }
 752  762  
      763 +static void
      764 +ptmap_help(void)
      765 +{
      766 +        mdb_printf(
      767 +            "Report all mappings represented by the page table hierarchy\n"
      768 +            "rooted at the given cr3 value / physical address.\n"
      769 +            "\n"
      770 +            "-w run ::whatis on mapping start addresses\n");
      771 +}
      772 +
 753  773  /*
 754  774   * NSEC_SHIFT is replicated here (it is not defined in a header file),
 755  775   * but for amusement, the reader is directed to the comment that explains
 756  776   * the rationale for this particular value on x86.  Spoiler:  the value is
 757  777   * selected to accommodate 60 MHz Pentiums!  (And a confession:  if the voice
 758  778   * in that comment sounds too familiar, it's because your author also wrote
 759  779   * that code -- some fifteen years prior to this writing in 2011...)
 760  780   */
 761  781  #define NSEC_SHIFT 5
 762  782  
↓ open down ↓ 116 lines elided ↑ open up ↑
 879  899  
 880  900          mdb_free(fset, sz);
 881  901          return (DCMD_OK);
 882  902  }
 883  903  
 884  904  #ifdef _KMDB
 885  905  /* ARGSUSED */
 886  906  static int
 887  907  crregs_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
 888  908  {
 889      -        ulong_t cr0, cr4;
      909 +        ulong_t cr0, cr2, cr3, cr4;
 890  910          static const mdb_bitmask_t cr0_flag_bits[] = {
 891  911                  { "PE",         CR0_PE,         CR0_PE },
 892  912                  { "MP",         CR0_MP,         CR0_MP },
 893  913                  { "EM",         CR0_EM,         CR0_EM },
 894  914                  { "TS",         CR0_TS,         CR0_TS },
 895  915                  { "ET",         CR0_ET,         CR0_ET },
 896  916                  { "NE",         CR0_NE,         CR0_NE },
 897  917                  { "WP",         CR0_WP,         CR0_WP },
 898  918                  { "AM",         CR0_AM,         CR0_AM },
 899  919                  { "NW",         CR0_NW,         CR0_NW },
 900  920                  { "CD",         CR0_CD,         CR0_CD },
 901  921                  { "PG",         CR0_PG,         CR0_PG },
 902  922                  { NULL,         0,              0 }
 903  923          };
 904  924  
      925 +        static const mdb_bitmask_t cr3_flag_bits[] = {
      926 +                { "PCD",        CR3_PCD,        CR3_PCD },
      927 +                { "PWT",        CR3_PWT,        CR3_PWT },
      928 +                { NULL,         0,              0, }
      929 +        };
      930 +
 905  931          static const mdb_bitmask_t cr4_flag_bits[] = {
 906  932                  { "VME",        CR4_VME,        CR4_VME },
 907  933                  { "PVI",        CR4_PVI,        CR4_PVI },
 908  934                  { "TSD",        CR4_TSD,        CR4_TSD },
 909  935                  { "DE",         CR4_DE,         CR4_DE },
 910  936                  { "PSE",        CR4_PSE,        CR4_PSE },
 911  937                  { "PAE",        CR4_PAE,        CR4_PAE },
 912  938                  { "MCE",        CR4_MCE,        CR4_MCE },
 913  939                  { "PGE",        CR4_PGE,        CR4_PGE },
 914  940                  { "PCE",        CR4_PCE,        CR4_PCE },
 915  941                  { "OSFXSR",     CR4_OSFXSR,     CR4_OSFXSR },
 916  942                  { "OSXMMEXCPT", CR4_OSXMMEXCPT, CR4_OSXMMEXCPT },
 917  943                  { "VMXE",       CR4_VMXE,       CR4_VMXE },
 918  944                  { "SMXE",       CR4_SMXE,       CR4_SMXE },
      945 +                { "PCIDE",      CR4_PCIDE,      CR4_PCIDE },
 919  946                  { "OSXSAVE",    CR4_OSXSAVE,    CR4_OSXSAVE },
 920  947                  { "SMEP",       CR4_SMEP,       CR4_SMEP },
 921  948                  { "SMAP",       CR4_SMAP,       CR4_SMAP },
 922  949                  { NULL,         0,              0 }
 923  950          };
 924  951  
 925  952          cr0 = kmdb_unix_getcr0();
      953 +        cr2 = kmdb_unix_getcr2();
      954 +        cr3 = kmdb_unix_getcr3();
 926  955          cr4 = kmdb_unix_getcr4();
 927      -        mdb_printf("%%cr0 = 0x%08x <%b>\n", cr0, cr0, cr0_flag_bits);
 928      -        mdb_printf("%%cr4 = 0x%08x <%b>\n", cr4, cr4, cr4_flag_bits);
      956 +        mdb_printf("%%cr0 = 0x%lx <%b>\n", cr0, cr0, cr0_flag_bits);
      957 +        mdb_printf("%%cr2 = 0x%lx <%a>\n", cr2, cr2);
      958 +
      959 +        if ((cr4 & CR4_PCIDE)) {
      960 +                mdb_printf("%%cr3 = 0x%lx <pfn:0x%lx pcid:%lu>\n", cr3,
      961 +                    cr3 >> MMU_PAGESHIFT, cr3 & MMU_PAGEOFFSET);
      962 +        } else {
      963 +                mdb_printf("%%cr3 = 0x%lx <pfn:0x%lx flags:%b>\n", cr3,
      964 +                    cr3 >> MMU_PAGESHIFT, cr3, cr3_flag_bits);
      965 +        }
      966 +
      967 +        mdb_printf("%%cr4 = 0x%lx <%b>\n", cr4, cr4, cr4_flag_bits);
      968 +
 929  969          return (DCMD_OK);
 930  970  }
 931  971  #endif
 932  972  
 933  973  static const mdb_dcmd_t dcmds[] = {
 934  974          { "gate_desc", ":", "dump a gate descriptor", gate_desc },
 935  975          { "idt", ":[-v]", "dump an IDT", idt },
 936      -        { "ttrace", "[-x]", "dump trap trace buffers", ttrace },
      976 +        { "ttrace", "[-x] [-t kthread]", "dump trap trace buffers", ttrace },
 937  977          { "vatopfn", ":[-a as]", "translate address to physical page",
 938  978              va2pfn_dcmd },
 939  979          { "report_maps", ":[-m]",
 940  980              "Given PFN, report mappings / page table usage",
 941  981              report_maps_dcmd, report_maps_help },
 942  982          { "htables", "", "Given hat_t *, lists all its htable_t * values",
 943  983              htables_dcmd, htables_help },
 944      -        { "ptable", ":[-m]", "Given PFN, dump contents of a page table",
      984 +        { "ptable", ":[-lm]", "Given PFN, dump contents of a page table",
 945  985              ptable_dcmd, ptable_help },
 946      -        { "pte", ":[-p XXXXX] [-l N]", "print human readable page table entry",
      986 +        { "ptmap", ":", "Given a cr3 value, dump all mappings",
      987 +            ptmap_dcmd, ptmap_help },
      988 +        { "pte", ":[-l N]", "print human readable page table entry",
 947  989              pte_dcmd },
 948  990          { "pfntomfn", ":", "convert physical page to hypervisor machine page",
 949  991              pfntomfn_dcmd },
 950  992          { "mfntopfn", ":", "convert hypervisor machine page to physical page",
 951  993              mfntopfn_dcmd },
 952  994          { "memseg_list", ":", "show memseg list", memseg_list },
 953  995          { "scalehrtime", ":",
 954  996              "scale an unscaled high-res time", scalehrtime_cmd },
 955  997          { "x86_featureset", NULL, "dump the x86_featureset vector",
 956  998                  x86_featureset_cmd },
↓ open down ↓ 29 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX