Пример #1
0
static x86pte_t
get_pte(hat_t *hat, htable_t *htable, uintptr_t addr)
{
	x86pte_t buf;

	if (htable->ht_flags & HTABLE_COPIED) {
		uintptr_t ptr = (uintptr_t)hat->hat_copied_ptes;
		ptr += va2entry(htable, addr) << mmu.pte_size_shift;
		return (*(x86pte_t *)ptr);
	}

	paddr_t paddr = mmu_ptob((paddr_t)htable->ht_pfn);
	paddr += va2entry(htable, addr) << mmu.pte_size_shift;

	if ((mdb_pread(&buf, mmu.pte_size, paddr)) == mmu.pte_size)
		return (buf);

	return (0);
}
Пример #2
0
static x86pte_t
get_pte(hat_t *hat, htable_t *htable, uintptr_t addr)
{
	x86pte_t buf;
	x86pte32_t *pte32 = (x86pte32_t *)&buf;
	size_t len;

	if (htable->ht_flags & HTABLE_VLP) {
		uintptr_t ptr = (uintptr_t)hat->hat_vlp_ptes;
		ptr += va2entry(htable, addr) << mmu.pte_size_shift;
		len = mdb_vread(&buf, mmu.pte_size, ptr);
	} else {
		paddr_t paddr = mmu_ptob((paddr_t)htable->ht_pfn);
		paddr += va2entry(htable, addr) << mmu.pte_size_shift;
		len = mdb_pread(&buf, mmu.pte_size, paddr);
	}

	if (len != mmu.pte_size)
		return (0);

	if (mmu.pte_size == sizeof (x86pte_t))
		return (buf);
	return (*pte32);
}
Пример #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);
}
Пример #4
0
/*
 * Report all hat's that either use PFN as a page table or that map the page.
 */
static int
do_report_maps(pfn_t pfn)
{
	struct hat *hatp;
	struct hat hat;
	htable_t *ht;
	htable_t htable;
	uintptr_t base;
	int h;
	int level;
	int entry;
	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);
				}

				/*
				 * only report kernel addresses once
				 */
				if (hatp != khat &&
				    htable.ht_vaddr >= kernelbase)
					continue;

				/*
				 * Is the PFN a pagetable itself?
				 */
				if (htable.ht_pfn == pfn) {
					mdb_printf("Pagetable for "
					    "hat=%p htable=%p\n", hatp, ht);
					continue;
				}

				/*
				 * otherwise, examine page mappings
				 */
				level = htable.ht_level;
				if (level > mmu.max_page_level)
					continue;
				paddr = mmu_ptob((physaddr_t)htable.ht_pfn);
				for (entry = 0;
				    entry < HTABLE_NUM_PTES(&htable);
				    ++entry) {

					base = htable.ht_vaddr + entry *
					    mmu.level_size[level];

					/*
					 * only report kernel addresses once
					 */
					if (hatp != khat &&
					    base >= kernelbase)
						continue;

					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 & PT_VALID) == 0)
						continue;
					if (level == 0 || !(pte & PT_PAGESIZE))
						pte &= PT_PADDR;
					else
						pte &= PT_PADDR_LGPG;
					if (mmu_btop(mdb_ma_to_pa(pte)) != pfn)
						continue;
					mdb_printf("hat=%p maps addr=%p\n",
					    hatp, (caddr_t)base);
				}
			}
		}
	}

done:
	return (DCMD_OK);
}
Пример #5
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);
}
Пример #6
0
int
ptmap_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
{
	physaddr_t paddrs[MAX_NUM_LEVEL] = { 0, };
	size_t entry[MAX_NUM_LEVEL] = { 0, };
	uintptr_t start = (uintptr_t)-1;
	boolean_t writable = B_FALSE;
	boolean_t user = B_FALSE;
	boolean_t wflag = B_FALSE;
	level_t curlevel;

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

	if (mdb_getopts(argc, argv,
	    'w', MDB_OPT_SETBITS, TRUE, &wflag, NULL) != argc)
		return (DCMD_USAGE);

	init_mmu();

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

	curlevel = mmu.max_level;

	paddrs[curlevel] = addr & MMU_PAGEMASK;

	for (;;) {
		physaddr_t pte_addr;
		x86pte_t pte;

		pte_addr = paddrs[curlevel] +
		    (entry[curlevel] << mmu.pte_size_shift);

		if (mdb_pread(&pte, sizeof (pte), pte_addr) != sizeof (pte)) {
			mdb_warn("couldn't read pte at %p", pte_addr);
			return (DCMD_ERR);
		}

		if (PTE_GET(pte, PT_VALID) == 0) {
			if (start != (uintptr_t)-1) {
				ptmap_report(entry, start,
				    user, writable, wflag);
				start = (uintptr_t)-1;
			}
		} else if (curlevel == 0 || PTE_GET(pte, PT_PAGESIZE)) {
			if (start == (uintptr_t)-1) {
				start = entry2va(entry);
				user = PTE_GET(pte, PT_USER);
				writable = PTE_GET(pte, PT_WRITABLE);
			} else if (user != PTE_GET(pte, PT_USER) ||
			    writable != PTE_GET(pte, PT_WRITABLE)) {
				ptmap_report(entry, start,
				    user, writable, wflag);
				start = entry2va(entry);
				user = PTE_GET(pte, PT_USER);
				writable = PTE_GET(pte, PT_WRITABLE);
			}
		} else {
			/* Descend a level. */
			physaddr_t pa = mmu_ptob(pte2mfn(pte, curlevel));
			paddrs[--curlevel] = pa;
			entry[curlevel] = 0;
			continue;
		}

		while (++entry[curlevel] == mmu.ptes_per_table) {
			/* Ascend back up. */
			entry[curlevel] = 0;
			if (curlevel == mmu.max_level) {
				if (start != (uintptr_t)-1) {
					ptmap_report(entry, start,
					    user, writable, wflag);
				}
				goto out;
			}

			curlevel++;
		}
	}

out:
	return (DCMD_OK);
}