843e19887f64dde75055cf8842fc4db2171eff45johnlev/*
843e19887f64dde75055cf8842fc4db2171eff45johnlev * CDDL HEADER START
843e19887f64dde75055cf8842fc4db2171eff45johnlev *
843e19887f64dde75055cf8842fc4db2171eff45johnlev * The contents of this file are subject to the terms of the
843e19887f64dde75055cf8842fc4db2171eff45johnlev * Common Development and Distribution License (the "License").
843e19887f64dde75055cf8842fc4db2171eff45johnlev * You may not use this file except in compliance with the License.
843e19887f64dde75055cf8842fc4db2171eff45johnlev *
843e19887f64dde75055cf8842fc4db2171eff45johnlev * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
843e19887f64dde75055cf8842fc4db2171eff45johnlev * or http://www.opensolaris.org/os/licensing.
843e19887f64dde75055cf8842fc4db2171eff45johnlev * See the License for the specific language governing permissions
843e19887f64dde75055cf8842fc4db2171eff45johnlev * and limitations under the License.
843e19887f64dde75055cf8842fc4db2171eff45johnlev *
843e19887f64dde75055cf8842fc4db2171eff45johnlev * When distributing Covered Code, include this CDDL HEADER in each
843e19887f64dde75055cf8842fc4db2171eff45johnlev * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
843e19887f64dde75055cf8842fc4db2171eff45johnlev * If applicable, add the following below this CDDL HEADER, with the
843e19887f64dde75055cf8842fc4db2171eff45johnlev * fields enclosed by brackets "[]" replaced with your own identifying
843e19887f64dde75055cf8842fc4db2171eff45johnlev * information: Portions Copyright [yyyy] [name of copyright owner]
843e19887f64dde75055cf8842fc4db2171eff45johnlev *
843e19887f64dde75055cf8842fc4db2171eff45johnlev * CDDL HEADER END
843e19887f64dde75055cf8842fc4db2171eff45johnlev */
843e19887f64dde75055cf8842fc4db2171eff45johnlev/*
843e19887f64dde75055cf8842fc4db2171eff45johnlev * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
843e19887f64dde75055cf8842fc4db2171eff45johnlev * Use is subject to license terms.
843e19887f64dde75055cf8842fc4db2171eff45johnlev */
28e4da25922bdfc5cba7ab29f47de911bbd78009Matthew Ahrens/*
28e4da25922bdfc5cba7ab29f47de911bbd78009Matthew Ahrens * Copyright (c) 2012 by Delphix. All rights reserved.
28e4da25922bdfc5cba7ab29f47de911bbd78009Matthew Ahrens */
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev#include <mdb/mdb_modapi.h>
843e19887f64dde75055cf8842fc4db2171eff45johnlev#include <mdb/mdb_ks.h>
843e19887f64dde75055cf8842fc4db2171eff45johnlev#include <mdb/mdb_ctf.h>
843e19887f64dde75055cf8842fc4db2171eff45johnlev#include <mdb/mdb_gelf.h>
843e19887f64dde75055cf8842fc4db2171eff45johnlev#include <mdb/mdb_target_impl.h>
843e19887f64dde75055cf8842fc4db2171eff45johnlev#include <mdb/mdb_kvm.h>
843e19887f64dde75055cf8842fc4db2171eff45johnlev#include <mdb/mdb.h>
843e19887f64dde75055cf8842fc4db2171eff45johnlev#include <xen/public/xen.h>
843e19887f64dde75055cf8842fc4db2171eff45johnlev#include <xen/public/arch-x86/xen.h>
843e19887f64dde75055cf8842fc4db2171eff45johnlev#include <errno.h>
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlevstatic mdb_ctf_id_t domain_type;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev/*
843e19887f64dde75055cf8842fc4db2171eff45johnlev * Some constants found in the non-public sched.h header file
843e19887f64dde75055cf8842fc4db2171eff45johnlev */
843e19887f64dde75055cf8842fc4db2171eff45johnlev#define MAX_EVTCHNS NR_EVENT_CHANNELS
843e19887f64dde75055cf8842fc4db2171eff45johnlev#define EVTCHNS_PER_BUCKET 128
843e19887f64dde75055cf8842fc4db2171eff45johnlev#define NR_EVTCHN_BUCKETS (MAX_EVTCHNS / EVTCHNS_PER_BUCKET)
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev/*
843e19887f64dde75055cf8842fc4db2171eff45johnlev * "struct domain" is an internal Xen structure. Rather than trying to
843e19887f64dde75055cf8842fc4db2171eff45johnlev * keep the mdb source in sync with Xen, we use CTF to extract the
843e19887f64dde75055cf8842fc4db2171eff45johnlev * interesting bits from the binary, and stash them in the structure
843e19887f64dde75055cf8842fc4db2171eff45johnlev * defined below.
843e19887f64dde75055cf8842fc4db2171eff45johnlev */
28e4da25922bdfc5cba7ab29f47de911bbd78009Matthew Ahrenstypedef struct mdb_xpv_domain {
843e19887f64dde75055cf8842fc4db2171eff45johnlev short domain_id;
843e19887f64dde75055cf8842fc4db2171eff45johnlev int tot_pages;
843e19887f64dde75055cf8842fc4db2171eff45johnlev int max_pages;
843e19887f64dde75055cf8842fc4db2171eff45johnlev int xenheap_pages;
843e19887f64dde75055cf8842fc4db2171eff45johnlev ulong_t domain_flags;
843e19887f64dde75055cf8842fc4db2171eff45johnlev char is_hvm;
843e19887f64dde75055cf8842fc4db2171eff45johnlev struct vcpu *vcpu[MAX_VIRT_CPUS];
28e4da25922bdfc5cba7ab29f47de911bbd78009Matthew Ahrens struct evtchn *evtchn[NR_EVTCHN_BUCKETS];
28e4da25922bdfc5cba7ab29f47de911bbd78009Matthew Ahrens struct domain *next_in_list;
28e4da25922bdfc5cba7ab29f47de911bbd78009Matthew Ahrens} mdb_xpv_domain_t;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlevstatic uintptr_t
843e19887f64dde75055cf8842fc4db2171eff45johnlevget_dom0_addr()
843e19887f64dde75055cf8842fc4db2171eff45johnlev{
843e19887f64dde75055cf8842fc4db2171eff45johnlev GElf_Sym sym;
843e19887f64dde75055cf8842fc4db2171eff45johnlev uintptr_t addr;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev if ((mdb_lookup_by_obj(MDB_TGT_OBJ_EVERY, "dom0", &sym)) == 1) {
843e19887f64dde75055cf8842fc4db2171eff45johnlev mdb_warn("can't find symbol 'dom0'");
843e19887f64dde75055cf8842fc4db2171eff45johnlev return (0);
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev if (sym.st_size != sizeof (uintptr_t)) {
843e19887f64dde75055cf8842fc4db2171eff45johnlev mdb_printf("Symbol 'dom0' found, but with the wrong size\n");
843e19887f64dde75055cf8842fc4db2171eff45johnlev return (0);
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev if (mdb_vread(&addr, sym.st_size, sym.st_value) == -1) {
843e19887f64dde75055cf8842fc4db2171eff45johnlev mdb_warn("can't read data for symbol 'dom0'");
843e19887f64dde75055cf8842fc4db2171eff45johnlev return (0);
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev return (addr);
843e19887f64dde75055cf8842fc4db2171eff45johnlev}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlevtypedef struct domain_walk {
843e19887f64dde75055cf8842fc4db2171eff45johnlev uint_t dw_step;
843e19887f64dde75055cf8842fc4db2171eff45johnlev} domain_walk_t;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlevint
843e19887f64dde75055cf8842fc4db2171eff45johnlevdomain_walk_init(mdb_walk_state_t *wsp)
843e19887f64dde75055cf8842fc4db2171eff45johnlev{
843e19887f64dde75055cf8842fc4db2171eff45johnlev domain_walk_t *dwp;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev if (wsp->walk_addr == NULL)
843e19887f64dde75055cf8842fc4db2171eff45johnlev if ((wsp->walk_addr = get_dom0_addr()) == NULL)
843e19887f64dde75055cf8842fc4db2171eff45johnlev return (WALK_ERR);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev dwp = mdb_alloc(sizeof (domain_walk_t), UM_SLEEP);
843e19887f64dde75055cf8842fc4db2171eff45johnlev dwp->dw_step = FALSE;
843e19887f64dde75055cf8842fc4db2171eff45johnlev wsp->walk_data = dwp;
843e19887f64dde75055cf8842fc4db2171eff45johnlev return (WALK_NEXT);
843e19887f64dde75055cf8842fc4db2171eff45johnlev}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlevint
843e19887f64dde75055cf8842fc4db2171eff45johnlevdomain_walk_step(mdb_walk_state_t *wsp)
843e19887f64dde75055cf8842fc4db2171eff45johnlev{
843e19887f64dde75055cf8842fc4db2171eff45johnlev domain_walk_t *dwp = (domain_walk_t *)wsp->walk_data;
28e4da25922bdfc5cba7ab29f47de911bbd78009Matthew Ahrens mdb_xpv_domain_t dom;
843e19887f64dde75055cf8842fc4db2171eff45johnlev int status;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev if (wsp->walk_addr == NULL)
843e19887f64dde75055cf8842fc4db2171eff45johnlev return (WALK_DONE);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev status = wsp->walk_callback(wsp->walk_addr, (void *)wsp->walk_addr,
843e19887f64dde75055cf8842fc4db2171eff45johnlev wsp->walk_cbdata);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
28e4da25922bdfc5cba7ab29f47de911bbd78009Matthew Ahrens if (mdb_ctf_vread(&dom, "struct domain", "mdb_xpv_domain_t",
28e4da25922bdfc5cba7ab29f47de911bbd78009Matthew Ahrens wsp->walk_addr, 0) != 0)
843e19887f64dde75055cf8842fc4db2171eff45johnlev return (WALK_ERR);
843e19887f64dde75055cf8842fc4db2171eff45johnlev wsp->walk_addr = (uintptr_t)dom.next_in_list;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev dwp->dw_step = TRUE;
843e19887f64dde75055cf8842fc4db2171eff45johnlev return (status);
843e19887f64dde75055cf8842fc4db2171eff45johnlev}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlevvoid
843e19887f64dde75055cf8842fc4db2171eff45johnlevdomain_walk_fini(mdb_walk_state_t *wsp)
843e19887f64dde75055cf8842fc4db2171eff45johnlev{
843e19887f64dde75055cf8842fc4db2171eff45johnlev domain_walk_t *dwp = (domain_walk_t *)wsp->walk_data;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev mdb_free(dwp, sizeof (domain_walk_t));
843e19887f64dde75055cf8842fc4db2171eff45johnlev}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlevtypedef struct vcpu_walk {
843e19887f64dde75055cf8842fc4db2171eff45johnlev uint_t vw_count;
843e19887f64dde75055cf8842fc4db2171eff45johnlev uint_t vw_step;
843e19887f64dde75055cf8842fc4db2171eff45johnlev} vcpu_walk_t;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlevint
843e19887f64dde75055cf8842fc4db2171eff45johnlevvcpu_walk_init(mdb_walk_state_t *wsp)
843e19887f64dde75055cf8842fc4db2171eff45johnlev{
843e19887f64dde75055cf8842fc4db2171eff45johnlev vcpu_walk_t *vwp;
843e19887f64dde75055cf8842fc4db2171eff45johnlev uintptr_t off;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev if (wsp->walk_addr == NULL)
843e19887f64dde75055cf8842fc4db2171eff45johnlev if ((wsp->walk_addr = get_dom0_addr()) == NULL)
843e19887f64dde75055cf8842fc4db2171eff45johnlev return (WALK_ERR);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev if (mdb_ctf_offsetof(domain_type, "vcpu", &off)) {
843e19887f64dde75055cf8842fc4db2171eff45johnlev mdb_warn("can't find per-domain vcpu information");
843e19887f64dde75055cf8842fc4db2171eff45johnlev return (WALK_ERR);
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev wsp->walk_addr = wsp->walk_addr + (off / NBBY);
843e19887f64dde75055cf8842fc4db2171eff45johnlev vwp = mdb_alloc(sizeof (vcpu_walk_t), UM_SLEEP);
843e19887f64dde75055cf8842fc4db2171eff45johnlev vwp->vw_step = FALSE;
843e19887f64dde75055cf8842fc4db2171eff45johnlev vwp->vw_count = 0;
843e19887f64dde75055cf8842fc4db2171eff45johnlev wsp->walk_data = vwp;
843e19887f64dde75055cf8842fc4db2171eff45johnlev return (WALK_NEXT);
843e19887f64dde75055cf8842fc4db2171eff45johnlev}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlevint
843e19887f64dde75055cf8842fc4db2171eff45johnlevvcpu_walk_step(mdb_walk_state_t *wsp)
843e19887f64dde75055cf8842fc4db2171eff45johnlev{
843e19887f64dde75055cf8842fc4db2171eff45johnlev vcpu_walk_t *vwp = (vcpu_walk_t *)wsp->walk_data;
843e19887f64dde75055cf8842fc4db2171eff45johnlev uintptr_t vcpu_ptr;
843e19887f64dde75055cf8842fc4db2171eff45johnlev int status;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev if (vwp->vw_count++ >= MAX_VIRT_CPUS)
843e19887f64dde75055cf8842fc4db2171eff45johnlev return (WALK_DONE);
843e19887f64dde75055cf8842fc4db2171eff45johnlev if ((wsp->walk_addr == NULL) ||
843e19887f64dde75055cf8842fc4db2171eff45johnlev (mdb_vread(&vcpu_ptr, sizeof (uintptr_t), wsp->walk_addr) == -1) ||
843e19887f64dde75055cf8842fc4db2171eff45johnlev (vcpu_ptr == 0))
843e19887f64dde75055cf8842fc4db2171eff45johnlev return (WALK_DONE);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev status = wsp->walk_callback(vcpu_ptr, (void *)vcpu_ptr,
843e19887f64dde75055cf8842fc4db2171eff45johnlev wsp->walk_cbdata);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev wsp->walk_addr = wsp->walk_addr + sizeof (uintptr_t);
843e19887f64dde75055cf8842fc4db2171eff45johnlev vwp->vw_step = TRUE;
843e19887f64dde75055cf8842fc4db2171eff45johnlev return (status);
843e19887f64dde75055cf8842fc4db2171eff45johnlev}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlevvoid
843e19887f64dde75055cf8842fc4db2171eff45johnlevvcpu_walk_fini(mdb_walk_state_t *wsp)
843e19887f64dde75055cf8842fc4db2171eff45johnlev{
843e19887f64dde75055cf8842fc4db2171eff45johnlev vcpu_walk_t *vwp = (vcpu_walk_t *)wsp->walk_data;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev mdb_free(vwp, sizeof (vcpu_walk_t));
843e19887f64dde75055cf8842fc4db2171eff45johnlev}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlevint
843e19887f64dde75055cf8842fc4db2171eff45johnlevdomain(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
843e19887f64dde75055cf8842fc4db2171eff45johnlev{
28e4da25922bdfc5cba7ab29f47de911bbd78009Matthew Ahrens mdb_xpv_domain_t dom;
843e19887f64dde75055cf8842fc4db2171eff45johnlev uintptr_t off, vcpu_addr, evtchn_addr;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev if (!mdb_ctf_type_valid(domain_type)) {
843e19887f64dde75055cf8842fc4db2171eff45johnlev mdb_warn("Can't parse Xen domain info.\n");
843e19887f64dde75055cf8842fc4db2171eff45johnlev return (DCMD_ERR);
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev if (!(flags & DCMD_ADDRSPEC)) {
843e19887f64dde75055cf8842fc4db2171eff45johnlev if (mdb_walk_dcmd("domain", "domain", argc, argv) == -1) {
843e19887f64dde75055cf8842fc4db2171eff45johnlev mdb_warn("can't walk domains");
843e19887f64dde75055cf8842fc4db2171eff45johnlev return (DCMD_ERR);
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
843e19887f64dde75055cf8842fc4db2171eff45johnlev return (DCMD_OK);
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev if (DCMD_HDRSPEC(flags))
843e19887f64dde75055cf8842fc4db2171eff45johnlev mdb_printf("%?s %3s %8s %8s %8s %3s %?s %?s\n",
843e19887f64dde75055cf8842fc4db2171eff45johnlev "ADDR", "ID", "TPAGES", "MPAGES", "FLAGS", "HVM",
843e19887f64dde75055cf8842fc4db2171eff45johnlev "VCPU", "EVTCHN");
843e19887f64dde75055cf8842fc4db2171eff45johnlev
28e4da25922bdfc5cba7ab29f47de911bbd78009Matthew Ahrens if (mdb_ctf_vread(&dom, "struct domain", "mdb_xpv_domain_t", addr,
28e4da25922bdfc5cba7ab29f47de911bbd78009Matthew Ahrens 0) != 0)
843e19887f64dde75055cf8842fc4db2171eff45johnlev return (DCMD_ERR);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev if (mdb_ctf_offsetof(domain_type, "vcpu", &off)) {
843e19887f64dde75055cf8842fc4db2171eff45johnlev mdb_warn("can't find per-domain vcpu information");
843e19887f64dde75055cf8842fc4db2171eff45johnlev return (DCMD_ERR);
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
843e19887f64dde75055cf8842fc4db2171eff45johnlev vcpu_addr = addr + (off / NBBY);
843e19887f64dde75055cf8842fc4db2171eff45johnlev if (mdb_ctf_offsetof(domain_type, "evtchn", &off)) {
843e19887f64dde75055cf8842fc4db2171eff45johnlev mdb_warn("can't find per-domain event channel information");
843e19887f64dde75055cf8842fc4db2171eff45johnlev return (DCMD_ERR);
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
843e19887f64dde75055cf8842fc4db2171eff45johnlev evtchn_addr = addr + (off / NBBY);
843e19887f64dde75055cf8842fc4db2171eff45johnlev mdb_printf("%?lx %3d %8x %8x %8x %3d %?lx %?lx\n",
843e19887f64dde75055cf8842fc4db2171eff45johnlev addr, dom.domain_id, dom.tot_pages, dom.max_pages, dom.domain_flags,
843e19887f64dde75055cf8842fc4db2171eff45johnlev dom.is_hvm, vcpu_addr, evtchn_addr);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev return (DCMD_OK);
843e19887f64dde75055cf8842fc4db2171eff45johnlev}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlevstatic const mdb_dcmd_t dcmds[] = {
843e19887f64dde75055cf8842fc4db2171eff45johnlev { "domain", ":", "display Xen domain info", domain },
843e19887f64dde75055cf8842fc4db2171eff45johnlev { NULL }
843e19887f64dde75055cf8842fc4db2171eff45johnlev};
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlevstatic const mdb_walker_t walkers[] = {
843e19887f64dde75055cf8842fc4db2171eff45johnlev { "domain", "walk list of Xen domains",
843e19887f64dde75055cf8842fc4db2171eff45johnlev domain_walk_init, domain_walk_step, domain_walk_fini },
843e19887f64dde75055cf8842fc4db2171eff45johnlev { "vcpu", "walk a Xen domain's vcpus",
843e19887f64dde75055cf8842fc4db2171eff45johnlev vcpu_walk_init, vcpu_walk_step, vcpu_walk_fini },
843e19887f64dde75055cf8842fc4db2171eff45johnlev { NULL }
843e19887f64dde75055cf8842fc4db2171eff45johnlev};
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlevstatic const mdb_modinfo_t modinfo = { MDB_API_VERSION, dcmds, walkers };
843e19887f64dde75055cf8842fc4db2171eff45johnlev
28e4da25922bdfc5cba7ab29f47de911bbd78009Matthew Ahrenstypedef struct mdb_xpv_panic_info {
28e4da25922bdfc5cba7ab29f47de911bbd78009Matthew Ahrens int pi_version;
28e4da25922bdfc5cba7ab29f47de911bbd78009Matthew Ahrens} mdb_xpv_panic_info_t;
28e4da25922bdfc5cba7ab29f47de911bbd78009Matthew Ahrens
843e19887f64dde75055cf8842fc4db2171eff45johnlevconst mdb_modinfo_t *
843e19887f64dde75055cf8842fc4db2171eff45johnlev_mdb_init(void)
843e19887f64dde75055cf8842fc4db2171eff45johnlev{
843e19887f64dde75055cf8842fc4db2171eff45johnlev uintptr_t pip;
28e4da25922bdfc5cba7ab29f47de911bbd78009Matthew Ahrens mdb_xpv_panic_info_t pi;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
28e4da25922bdfc5cba7ab29f47de911bbd78009Matthew Ahrens if (mdb_readsym(&pip, sizeof (pip), "xpv_panic_info") == -1) {
843e19887f64dde75055cf8842fc4db2171eff45johnlev mdb_warn("failed to read xpv panic_info pointer");
843e19887f64dde75055cf8842fc4db2171eff45johnlev return (NULL);
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
28e4da25922bdfc5cba7ab29f47de911bbd78009Matthew Ahrens if (mdb_ctf_vread(&pi, "struct panic_info", "mdb_xpv_panic_info_t",
28e4da25922bdfc5cba7ab29f47de911bbd78009Matthew Ahrens pip, 0) == -1)
843e19887f64dde75055cf8842fc4db2171eff45johnlev return (NULL);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev if (pi.pi_version != PANIC_INFO_VERSION) {
843e19887f64dde75055cf8842fc4db2171eff45johnlev mdb_warn("unrecognized hypervisor panic format");
843e19887f64dde75055cf8842fc4db2171eff45johnlev return (NULL);
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev if (mdb_ctf_lookup_by_name("struct domain", &domain_type) != 0) {
843e19887f64dde75055cf8842fc4db2171eff45johnlev mdb_warn("Can't parse Xen domain info: "
843e19887f64dde75055cf8842fc4db2171eff45johnlev "'struct domain' not found.\n");
843e19887f64dde75055cf8842fc4db2171eff45johnlev mdb_ctf_type_invalidate(&domain_type);
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev return (&modinfo);
843e19887f64dde75055cf8842fc4db2171eff45johnlev}