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>
*** 18,28 ****
*
* CDDL HEADER END
*/
/*
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
! * Copyright 2015 Joyent, Inc.
*/
#include <mdb/mdb_modapi.h>
#include <mdb/mdb_ctf.h>
#include <sys/cpuvar.h>
--- 18,28 ----
*
* CDDL HEADER END
*/
/*
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
! * Copyright 2018 Joyent, Inc.
*/
#include <mdb/mdb_modapi.h>
#include <mdb/mdb_ctf.h>
#include <sys/cpuvar.h>
*** 407,416 ****
--- 407,417 ----
};
typedef struct ttrace_dcmd {
processorid_t ttd_cpu;
uint_t ttd_extended;
+ uintptr_t ttd_kthread;
trap_trace_ctl_t ttd_ttc[NCPU];
} ttrace_dcmd_t;
#if defined(__amd64)
*** 429,438 ****
--- 430,442 ----
mdb_printf(THREEREGS, DUMP(r13), DUMP(r14), DUMP(r15));
mdb_printf(THREEREGS, DUMP(ds), DUMP(es), DUMP(fs));
mdb_printf(THREEREGS, DUMP(gs), "trp", regs->r_trapno, DUMP(err));
mdb_printf(THREEREGS, DUMP(rip), DUMP(cs), DUMP(rfl));
mdb_printf(THREEREGS, DUMP(rsp), DUMP(ss), "cr2", rec->ttr_cr2);
+ mdb_printf(" %3s: %16lx %3s: %16lx\n",
+ "fsb", regs->__r_fsbase,
+ "gsb", regs->__r_gsbase);
mdb_printf("\n");
}
#else
*** 476,485 ****
--- 480,493 ----
}
if (dcmd->ttd_cpu != -1 && cpu != dcmd->ttd_cpu)
return (WALK_NEXT);
+ if (dcmd->ttd_kthread != 0 &&
+ dcmd->ttd_kthread != rec->ttr_curthread)
+ return (WALK_NEXT);
+
mdb_printf("%3d %15llx ", cpu, rec->ttr_stamp);
for (i = 0; ttrace_hdlr[i].t_hdlr != NULL; i++) {
if (rec->ttr_marker != ttrace_hdlr[i].t_marker)
continue;
*** 535,545 ****
"non-TRAPTRACE kernel?\n");
return (DCMD_ERR);
}
if (mdb_getopts(argc, argv,
! 'x', MDB_OPT_SETBITS, TRUE, &dcmd.ttd_extended, NULL) != argc)
return (DCMD_USAGE);
if (DCMD_HDRSPEC(flags)) {
mdb_printf("%3s %15s %4s %2s %-*s%s\n", "CPU",
"TIMESTAMP", "TYPE", "Vec", TT_HDLR_WIDTH, "HANDLER",
--- 543,554 ----
"non-TRAPTRACE kernel?\n");
return (DCMD_ERR);
}
if (mdb_getopts(argc, argv,
! 'x', MDB_OPT_SETBITS, TRUE, &dcmd.ttd_extended,
! 't', MDB_OPT_UINTPTR, &dcmd.ttd_kthread, NULL) != argc)
return (DCMD_USAGE);
if (DCMD_HDRSPEC(flags)) {
mdb_printf("%3s %15s %4s %2s %-*s%s\n", "CPU",
"TIMESTAMP", "TYPE", "Vec", TT_HDLR_WIDTH, "HANDLER",
*** 745,757 ****
{
mdb_printf(
"Given a PFN holding a page table, print its contents, and\n"
"the address of the corresponding htable structure.\n"
"\n"
! "-m Interpret the PFN as an MFN (machine frame number)\n");
}
/*
* NSEC_SHIFT is replicated here (it is not defined in a header file),
* but for amusement, the reader is directed to the comment that explains
* the rationale for this particular value on x86. Spoiler: the value is
* selected to accommodate 60 MHz Pentiums! (And a confession: if the voice
--- 754,777 ----
{
mdb_printf(
"Given a PFN holding a page table, print its contents, and\n"
"the address of the corresponding htable structure.\n"
"\n"
! "-m Interpret the PFN as an MFN (machine frame number)\n"
! "-l force page table level (3 is top)\n");
}
+ static void
+ ptmap_help(void)
+ {
+ mdb_printf(
+ "Report all mappings represented by the page table hierarchy\n"
+ "rooted at the given cr3 value / physical address.\n"
+ "\n"
+ "-w run ::whatis on mapping start addresses\n");
+ }
+
/*
* NSEC_SHIFT is replicated here (it is not defined in a header file),
* but for amusement, the reader is directed to the comment that explains
* the rationale for this particular value on x86. Spoiler: the value is
* selected to accommodate 60 MHz Pentiums! (And a confession: if the voice
*** 884,894 ****
#ifdef _KMDB
/* ARGSUSED */
static int
crregs_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
{
! ulong_t cr0, cr4;
static const mdb_bitmask_t cr0_flag_bits[] = {
{ "PE", CR0_PE, CR0_PE },
{ "MP", CR0_MP, CR0_MP },
{ "EM", CR0_EM, CR0_EM },
{ "TS", CR0_TS, CR0_TS },
--- 904,914 ----
#ifdef _KMDB
/* ARGSUSED */
static int
crregs_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
{
! ulong_t cr0, cr2, cr3, cr4;
static const mdb_bitmask_t cr0_flag_bits[] = {
{ "PE", CR0_PE, CR0_PE },
{ "MP", CR0_MP, CR0_MP },
{ "EM", CR0_EM, CR0_EM },
{ "TS", CR0_TS, CR0_TS },
*** 900,909 ****
--- 920,935 ----
{ "CD", CR0_CD, CR0_CD },
{ "PG", CR0_PG, CR0_PG },
{ NULL, 0, 0 }
};
+ static const mdb_bitmask_t cr3_flag_bits[] = {
+ { "PCD", CR3_PCD, CR3_PCD },
+ { "PWT", CR3_PWT, CR3_PWT },
+ { NULL, 0, 0, }
+ };
+
static const mdb_bitmask_t cr4_flag_bits[] = {
{ "VME", CR4_VME, CR4_VME },
{ "PVI", CR4_PVI, CR4_PVI },
{ "TSD", CR4_TSD, CR4_TSD },
{ "DE", CR4_DE, CR4_DE },
*** 914,951 ****
{ "PCE", CR4_PCE, CR4_PCE },
{ "OSFXSR", CR4_OSFXSR, CR4_OSFXSR },
{ "OSXMMEXCPT", CR4_OSXMMEXCPT, CR4_OSXMMEXCPT },
{ "VMXE", CR4_VMXE, CR4_VMXE },
{ "SMXE", CR4_SMXE, CR4_SMXE },
{ "OSXSAVE", CR4_OSXSAVE, CR4_OSXSAVE },
{ "SMEP", CR4_SMEP, CR4_SMEP },
{ "SMAP", CR4_SMAP, CR4_SMAP },
{ NULL, 0, 0 }
};
cr0 = kmdb_unix_getcr0();
cr4 = kmdb_unix_getcr4();
! mdb_printf("%%cr0 = 0x%08x <%b>\n", cr0, cr0, cr0_flag_bits);
! mdb_printf("%%cr4 = 0x%08x <%b>\n", cr4, cr4, cr4_flag_bits);
return (DCMD_OK);
}
#endif
static const mdb_dcmd_t dcmds[] = {
{ "gate_desc", ":", "dump a gate descriptor", gate_desc },
{ "idt", ":[-v]", "dump an IDT", idt },
! { "ttrace", "[-x]", "dump trap trace buffers", ttrace },
{ "vatopfn", ":[-a as]", "translate address to physical page",
va2pfn_dcmd },
{ "report_maps", ":[-m]",
"Given PFN, report mappings / page table usage",
report_maps_dcmd, report_maps_help },
{ "htables", "", "Given hat_t *, lists all its htable_t * values",
htables_dcmd, htables_help },
! { "ptable", ":[-m]", "Given PFN, dump contents of a page table",
ptable_dcmd, ptable_help },
! { "pte", ":[-p XXXXX] [-l N]", "print human readable page table entry",
pte_dcmd },
{ "pfntomfn", ":", "convert physical page to hypervisor machine page",
pfntomfn_dcmd },
{ "mfntopfn", ":", "convert hypervisor machine page to physical page",
mfntopfn_dcmd },
--- 940,993 ----
{ "PCE", CR4_PCE, CR4_PCE },
{ "OSFXSR", CR4_OSFXSR, CR4_OSFXSR },
{ "OSXMMEXCPT", CR4_OSXMMEXCPT, CR4_OSXMMEXCPT },
{ "VMXE", CR4_VMXE, CR4_VMXE },
{ "SMXE", CR4_SMXE, CR4_SMXE },
+ { "PCIDE", CR4_PCIDE, CR4_PCIDE },
{ "OSXSAVE", CR4_OSXSAVE, CR4_OSXSAVE },
{ "SMEP", CR4_SMEP, CR4_SMEP },
{ "SMAP", CR4_SMAP, CR4_SMAP },
{ NULL, 0, 0 }
};
cr0 = kmdb_unix_getcr0();
+ cr2 = kmdb_unix_getcr2();
+ cr3 = kmdb_unix_getcr3();
cr4 = kmdb_unix_getcr4();
! mdb_printf("%%cr0 = 0x%lx <%b>\n", cr0, cr0, cr0_flag_bits);
! mdb_printf("%%cr2 = 0x%lx <%a>\n", cr2, cr2);
!
! if ((cr4 & CR4_PCIDE)) {
! mdb_printf("%%cr3 = 0x%lx <pfn:0x%lx pcid:%lu>\n", cr3,
! cr3 >> MMU_PAGESHIFT, cr3 & MMU_PAGEOFFSET);
! } else {
! mdb_printf("%%cr3 = 0x%lx <pfn:0x%lx flags:%b>\n", cr3,
! cr3 >> MMU_PAGESHIFT, cr3, cr3_flag_bits);
! }
!
! mdb_printf("%%cr4 = 0x%lx <%b>\n", cr4, cr4, cr4_flag_bits);
!
return (DCMD_OK);
}
#endif
static const mdb_dcmd_t dcmds[] = {
{ "gate_desc", ":", "dump a gate descriptor", gate_desc },
{ "idt", ":[-v]", "dump an IDT", idt },
! { "ttrace", "[-x] [-t kthread]", "dump trap trace buffers", ttrace },
{ "vatopfn", ":[-a as]", "translate address to physical page",
va2pfn_dcmd },
{ "report_maps", ":[-m]",
"Given PFN, report mappings / page table usage",
report_maps_dcmd, report_maps_help },
{ "htables", "", "Given hat_t *, lists all its htable_t * values",
htables_dcmd, htables_help },
! { "ptable", ":[-lm]", "Given PFN, dump contents of a page table",
ptable_dcmd, ptable_help },
! { "ptmap", ":", "Given a cr3 value, dump all mappings",
! ptmap_dcmd, ptmap_help },
! { "pte", ":[-l N]", "print human readable page table entry",
pte_dcmd },
{ "pfntomfn", ":", "convert physical page to hypervisor machine page",
pfntomfn_dcmd },
{ "mfntopfn", ":", "convert hypervisor machine page to physical page",
mfntopfn_dcmd },