Example #1
0
/*ARGSUSED*/
int
pte_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
{
	uint64_t level = 0;

	init_mmu();

	if (mmu.num_level == 0)
		return (DCMD_ERR);

	if ((flags & DCMD_ADDRSPEC) == 0)
		return (DCMD_USAGE);

	if (mdb_getopts(argc, argv,
	    'l', MDB_OPT_UINT64, &level) != argc)
		return (DCMD_USAGE);

	if (level > mmu.max_level) {
		mdb_warn("invalid level %lu\n", level);
		return (DCMD_ERR);
	}

	if (addr == 0)
		return (DCMD_OK);

	return (do_pte_dcmd((int)level, addr));
}
Example #2
0
/*ARGSUSED*/
int
pte_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
{
	int level = 0;
	uint64_t pte = 0;
	char *level_str = NULL;
	char *pte_str = NULL;

	init_mmu();

	if (mmu.num_level == 0)
		return (DCMD_ERR);

	if (mdb_getopts(argc, argv,
	    'p', MDB_OPT_STR, &pte_str,
	    'l', MDB_OPT_STR, &level_str) != argc)
		return (DCMD_USAGE);

	/*
	 * parse the PTE to decode, if it's 0, we don't do anything
	 */
	if (pte_str != NULL) {
		pte = mdb_strtoull(pte_str);
	} else {
		if ((flags & DCMD_ADDRSPEC) == 0)
			return (DCMD_USAGE);
		pte = addr;
	}
	if (pte == 0)
		return (DCMD_OK);

	/*
	 * parse the level if supplied
	 */
	if (level_str != NULL) {
		level = mdb_strtoull(level_str);
		if (level < 0 || level > mmu.max_level)
			return (DCMD_ERR);
	}

	return (do_pte_dcmd(level, pte));
}
Example #3
0
static int
do_ptable_dcmd(pfn_t pfn)
{
	struct hat *hatp;
	struct hat hat;
	htable_t *ht;
	htable_t htable;
	uintptr_t base;
	int h;
	int level;
	int entry;
	uintptr_t pagesize;
	x86pte_t pte;
	x86pte_t buf;
	x86pte32_t *pte32 = (x86pte32_t *)&buf;
	physaddr_t paddr;
	size_t len;

	/*
	 * The hats are kept in a list with khat at the head.
	 */
	for (hatp = khat; hatp != NULL; hatp = hat.hat_next) {
		/*
		 * read the hat and its hash table
		 */
		if (mdb_vread(&hat, sizeof (hat), (uintptr_t)hatp) == -1) {
			mdb_warn("Couldn't read struct hat\n");
			return (DCMD_ERR);
		}

		/*
		 * read the htable hashtable
		 */
		paddr = 0;
		for (h = 0; h < hat.hat_num_hash; ++h) {
			if (mdb_vread(&ht, sizeof (htable_t *),
			    (uintptr_t)(hat.hat_ht_hash + h)) == -1) {
				mdb_warn("Couldn't read htable\n");
				return (DCMD_ERR);
			}
			for (; ht != NULL; ht = htable.ht_next) {
				if (mdb_vread(&htable, sizeof (htable_t),
				    (uintptr_t)ht) == -1) {
					mdb_warn("Couldn't read htable\n");
					return (DCMD_ERR);
				}

				/*
				 * Is this the PFN for this htable
				 */
				if (htable.ht_pfn == pfn)
					goto found_it;
			}
		}
	}

found_it:
	if (htable.ht_pfn == pfn) {
		mdb_printf("htable=%p\n", ht);
		level = htable.ht_level;
		base = htable.ht_vaddr;
		pagesize = mmu.level_size[level];
	} else {
		mdb_printf("Unknown pagetable - assuming level/addr 0");
		level = 0;	/* assume level == 0 for PFN */
		base = 0;
		pagesize = MMU_PAGESIZE;
	}

	paddr = mmu_ptob((physaddr_t)pfn);
	for (entry = 0; entry < mmu.ptes_per_table; ++entry) {
		len = mdb_pread(&buf, mmu.pte_size,
		    paddr + entry * mmu.pte_size);
		if (len != mmu.pte_size)
			return (DCMD_ERR);
		if (mmu.pte_size == sizeof (x86pte_t))
			pte = buf;
		else
			pte = *pte32;

		if (pte == 0)
			continue;

		mdb_printf("[%3d] va=%p ", entry, base + entry * pagesize);
		do_pte_dcmd(level, pte);
	}

done:
	return (DCMD_OK);
}
Example #4
0
static int
do_ptable_dcmd(pfn_t pfn, uint64_t level)
{
	struct hat *hatp;
	struct hat hat;
	htable_t *ht;
	htable_t htable;
	uintptr_t base;
	int h;
	int entry;
	uintptr_t pagesize;
	x86pte_t pte;
	physaddr_t paddr;
	size_t len;

	/*
	 * The hats are kept in a list with khat at the head.
	 */
	for (hatp = khat; hatp != NULL; hatp = hat.hat_next) {
		/*
		 * read the hat and its hash table
		 */
		if (mdb_vread(&hat, sizeof (hat), (uintptr_t)hatp) == -1) {
			mdb_warn("Couldn't read struct hat\n");
			return (DCMD_ERR);
		}

		/*
		 * read the htable hashtable
		 */
		paddr = 0;
		for (h = 0; h < hat.hat_num_hash; ++h) {
			if (mdb_vread(&ht, sizeof (htable_t *),
			    (uintptr_t)(hat.hat_ht_hash + h)) == -1) {
				mdb_warn("Couldn't read htable\n");
				return (DCMD_ERR);
			}
			for (; ht != NULL; ht = htable.ht_next) {
				if (mdb_vread(&htable, sizeof (htable_t),
				    (uintptr_t)ht) == -1) {
					mdb_warn("Couldn't read htable\n");
					return (DCMD_ERR);
				}

				/*
				 * Is this the PFN for this htable
				 */
				if (htable.ht_pfn == pfn)
					goto found_it;
			}
		}
	}

found_it:
	if (htable.ht_pfn == pfn) {
		mdb_printf("htable=%p\n", ht);
		if (level == (uint64_t)-1) {
			level = htable.ht_level;
		} else if (htable.ht_level != level) {
			mdb_warn("htable has level %d but forcing level %lu\n",
			    htable.ht_level, level);
		}
		base = htable.ht_vaddr;
		pagesize = mmu.level_size[level];
	} else {
		if (level == (uint64_t)-1)
			level = 0;
		mdb_warn("couldn't find matching htable, using level=%lu, "
		    "base address=0x0\n", level);
		base = 0;
		pagesize = mmu.level_size[level];
	}

	paddr = mmu_ptob((physaddr_t)pfn);
	for (entry = 0; entry < mmu.ptes_per_table; ++entry) {
		len = mdb_pread(&pte, mmu.pte_size,
		    paddr + entry * mmu.pte_size);
		if (len != mmu.pte_size)
			return (DCMD_ERR);

		if (pte == 0)
			continue;

		mdb_printf("[%3d] va=0x%p ", entry,
		    VA_SIGN_EXTEND(base + entry * pagesize));
		do_pte_dcmd(level, pte);
	}

done:
	return (DCMD_OK);
}