Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F136795105
D5023.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
10 KB
Referenced Files
None
Subscribers
None
D5023.diff
View Options
Index: head/sys/arm/arm/minidump_machdep.c
===================================================================
--- head/sys/arm/arm/minidump_machdep.c
+++ head/sys/arm/arm/minidump_machdep.c
@@ -61,8 +61,6 @@
uint32_t *vm_page_dump;
int vm_page_dump_size;
-#ifndef ARM_NEW_PMAP
-
static struct kerneldumpheader kdh;
static off_t dumplo;
@@ -196,8 +194,9 @@
return (0);
}
-/* A fake page table page, to avoid having to handle both 4K and 2M pages */
-static pt_entry_t fakept[NPTEPG];
+/* A buffer for general use. Its size must be one page at least. */
+static char dumpbuf[PAGE_SIZE];
+CTASSERT(sizeof(dumpbuf) % sizeof(pt2_entry_t) == 0);
int
minidumpsys(struct dumperinfo *di)
@@ -208,9 +207,7 @@
uint32_t bits;
uint32_t pa, prev_pa = 0, count = 0;
vm_offset_t va;
- pd_entry_t *pdp;
- pt_entry_t *pt, *ptp;
- int i, k, bit, error;
+ int i, bit, error;
char *addr;
/*
@@ -228,48 +225,11 @@
counter = 0;
/* Walk page table pages, set bits in vm_page_dump */
ptesize = 0;
- for (va = KERNBASE; va < kernel_vm_end; va += NBPDR) {
- /*
- * We always write a page, even if it is zero. Each
- * page written corresponds to 2MB of space
- */
- ptesize += L2_TABLE_SIZE_REAL;
- pmap_get_pde_pte(pmap_kernel(), va, &pdp, &ptp);
- if (pmap_pde_v(pdp) && pmap_pde_section(pdp)) {
- /* This is a section mapping 1M page. */
- pa = (*pdp & L1_S_ADDR_MASK) | (va & ~L1_S_ADDR_MASK);
- for (k = 0; k < (L1_S_SIZE / PAGE_SIZE); k++) {
- if (is_dumpable(pa))
- dump_add_page(pa);
- pa += PAGE_SIZE;
- }
- continue;
- }
- if (pmap_pde_v(pdp) && pmap_pde_page(pdp)) {
- /* Set bit for each valid page in this 1MB block */
- addr = pmap_kenter_temporary(*pdp & L1_C_ADDR_MASK, 0);
- pt = (pt_entry_t*)(addr +
- (((uint32_t)*pdp & L1_C_ADDR_MASK) & PAGE_MASK));
- for (k = 0; k < 256; k++) {
- if ((pt[k] & L2_TYPE_MASK) == L2_TYPE_L) {
- pa = (pt[k] & L2_L_FRAME) |
- (va & L2_L_OFFSET);
- for (i = 0; i < 16; i++) {
- if (is_dumpable(pa))
- dump_add_page(pa);
- k++;
- pa += PAGE_SIZE;
- }
- } else if ((pt[k] & L2_TYPE_MASK) == L2_TYPE_S) {
- pa = (pt[k] & L2_S_FRAME) |
- (va & L2_S_OFFSET);
- if (is_dumpable(pa))
- dump_add_page(pa);
- }
- }
- } else {
- /* Nothing, we're going to dump a null page */
- }
+ for (va = KERNBASE; va < kernel_vm_end; va += PAGE_SIZE) {
+ pa = pmap_dump_kextract(va, NULL);
+ if (pa != 0 && is_dumpable(pa))
+ dump_add_page(pa);
+ ptesize += sizeof(pt2_entry_t);
}
/* Calculate dump size. */
@@ -331,9 +291,9 @@
dumplo += sizeof(kdh);
/* Dump my header */
- bzero(&fakept, sizeof(fakept));
- bcopy(&mdhdr, &fakept, sizeof(mdhdr));
- error = blk_write(di, (char *)&fakept, 0, PAGE_SIZE);
+ bzero(dumpbuf, sizeof(dumpbuf));
+ bcopy(&mdhdr, dumpbuf, sizeof(mdhdr));
+ error = blk_write(di, dumpbuf, 0, PAGE_SIZE);
if (error)
goto fail;
@@ -349,81 +309,21 @@
goto fail;
/* Dump kernel page table pages */
- for (va = KERNBASE; va < kernel_vm_end; va += NBPDR) {
- /* We always write a page, even if it is zero */
- pmap_get_pde_pte(pmap_kernel(), va, &pdp, &ptp);
-
- if (pmap_pde_v(pdp) && pmap_pde_section(pdp)) {
- if (count) {
- error = blk_write_cont(di, prev_pa,
- count * L2_TABLE_SIZE_REAL);
- if (error)
- goto fail;
- count = 0;
- prev_pa = 0;
- }
- /* This is a single 2M block. Generate a fake PTP */
- pa = (*pdp & L1_S_ADDR_MASK) | (va & ~L1_S_ADDR_MASK);
- for (k = 0; k < (L1_S_SIZE / PAGE_SIZE); k++) {
- fakept[k] = L2_S_PROTO | (pa + (k * PAGE_SIZE)) |
- L2_S_PROT(PTE_KERNEL,
- VM_PROT_READ | VM_PROT_WRITE);
- }
- error = blk_write(di, (char *)&fakept, 0,
- L2_TABLE_SIZE_REAL);
- if (error)
- goto fail;
- /* Flush, in case we reuse fakept in the same block */
- error = blk_flush(di);
- if (error)
- goto fail;
- continue;
- }
- if (pmap_pde_v(pdp) && pmap_pde_page(pdp)) {
- pa = *pdp & L1_C_ADDR_MASK;
- if (!count) {
- prev_pa = pa;
- count++;
- }
- else {
- if (pa == (prev_pa + count * L2_TABLE_SIZE_REAL))
- count++;
- else {
- error = blk_write_cont(di, prev_pa,
- count * L2_TABLE_SIZE_REAL);
- if (error)
- goto fail;
- count = 1;
- prev_pa = pa;
- }
- }
- } else {
- if (count) {
- error = blk_write_cont(di, prev_pa,
- count * L2_TABLE_SIZE_REAL);
- if (error)
- goto fail;
- count = 0;
- prev_pa = 0;
- }
- bzero(fakept, sizeof(fakept));
- error = blk_write(di, (char *)&fakept, 0,
- L2_TABLE_SIZE_REAL);
- if (error)
- goto fail;
- /* Flush, in case we reuse fakept in the same block */
- error = blk_flush(di);
- if (error)
+ addr = dumpbuf;
+ for (va = KERNBASE; va < kernel_vm_end; va += PAGE_SIZE) {
+ pmap_dump_kextract(va, (pt2_entry_t *)addr);
+ addr += sizeof(pt2_entry_t);
+ if (addr == dumpbuf + sizeof(dumpbuf)) {
+ error = blk_write(di, dumpbuf, 0, sizeof(dumpbuf));
+ if (error != 0)
goto fail;
+ addr = dumpbuf;
}
}
-
- if (count) {
- error = blk_write_cont(di, prev_pa, count * L2_TABLE_SIZE_REAL);
- if (error)
+ if (addr != dumpbuf) {
+ error = blk_write(di, dumpbuf, 0, addr - dumpbuf);
+ if (error != 0)
goto fail;
- count = 0;
- prev_pa = 0;
}
/* Dump memory chunks */
@@ -484,17 +384,6 @@
return (0);
}
-#else /* ARM_NEW_PMAP */
-
-int
-minidumpsys(struct dumperinfo *di)
-{
-
- return (0);
-}
-
-#endif
-
void
dump_add_page(vm_paddr_t pa)
{
Index: head/sys/arm/arm/pmap-v6-new.c
===================================================================
--- head/sys/arm/arm/pmap-v6-new.c
+++ head/sys/arm/arm/pmap-v6-new.c
@@ -1049,6 +1049,36 @@
return (pa);
}
+/*
+ * Extract from the kernel page table the physical address
+ * that is mapped by the given virtual address "va". Also
+ * return L2 page table entry which maps the address.
+ *
+ * This is only intended to be used for panic dumps.
+ */
+vm_paddr_t
+pmap_dump_kextract(vm_offset_t va, pt2_entry_t *pte2p)
+{
+ vm_paddr_t pa;
+ pt1_entry_t pte1;
+ pt2_entry_t pte2;
+
+ pte1 = pte1_load(kern_pte1(va));
+ if (pte1_is_section(pte1)) {
+ pa = pte1_pa(pte1) | (va & PTE1_OFFSET);
+ pte2 = pa | ATTR_TO_L2(pte1) | PTE2_V;
+ } else if (pte1_is_link(pte1)) {
+ pte2 = pte2_load(pt2map_entry(va));
+ pa = pte2_pa(pte2);
+ } else {
+ pte2 = 0;
+ pa = 0;
+ }
+ if (pte2p != NULL)
+ *pte2p = pte2;
+ return (pa);
+}
+
/*****************************************************************************
*
* PMAP second stage initialization and utility functions
Index: head/sys/arm/arm/pmap-v6.c
===================================================================
--- head/sys/arm/arm/pmap-v6.c
+++ head/sys/arm/arm/pmap-v6.c
@@ -3536,6 +3536,52 @@
return (m);
}
+vm_paddr_t
+pmap_dump_kextract(vm_offset_t va, pt2_entry_t *pte2p)
+{
+ struct l2_dtable *l2;
+ pd_entry_t l1pd;
+ pt_entry_t *ptep, pte;
+ vm_paddr_t pa;
+ u_int l1idx;
+
+ l1idx = L1_IDX(va);
+ l1pd = kernel_pmap->pm_l1->l1_kva[l1idx];
+ if (l1pte_section_p(l1pd)) {
+ if (l1pd & L1_S_SUPERSEC)
+ pa = (l1pd & L1_SUP_FRAME) | (va & L1_SUP_OFFSET);
+ else
+ pa = (l1pd & L1_S_FRAME) | (va & L1_S_OFFSET);
+ pte = L2_S_PROTO | pa |
+ L2_S_PROT(PTE_KERNEL, VM_PROT_READ | VM_PROT_WRITE);
+ } else {
+ l2 = kernel_pmap->pm_l2[L2_IDX(l1idx)];
+ if (l2 == NULL ||
+ (ptep = l2->l2_bucket[L2_BUCKET(l1idx)].l2b_kva) == NULL) {
+ pte = 0;
+ pa = 0;
+ goto out;
+ }
+ pte = ptep[l2pte_index(va)];
+ if (pte == 0) {
+ pa = 0;
+ goto out;
+ }
+ switch (pte & L2_TYPE_MASK) {
+ case L2_TYPE_L:
+ pa = (pte & L2_L_FRAME) | (va & L2_L_OFFSET);
+ break;
+ default:
+ pa = (pte & L2_S_FRAME) | (va & L2_S_OFFSET);
+ break;
+ }
+ }
+out:
+ if (pte2p != NULL)
+ *pte2p = pte;
+ return (pa);
+}
+
/*
* Initialize a preallocated and zeroed pmap structure,
* such as one in a vmspace structure.
Index: head/sys/arm/arm/pmap.c
===================================================================
--- head/sys/arm/arm/pmap.c
+++ head/sys/arm/arm/pmap.c
@@ -3738,6 +3738,52 @@
return (m);
}
+vm_paddr_t
+pmap_dump_kextract(vm_offset_t va, pt2_entry_t *pte2p)
+{
+ struct l2_dtable *l2;
+ pd_entry_t l1pd;
+ pt_entry_t *ptep, pte;
+ vm_paddr_t pa;
+ u_int l1idx;
+
+ l1idx = L1_IDX(va);
+ l1pd = kernel_pmap->pm_l1->l1_kva[l1idx];
+ if (l1pte_section_p(l1pd)) {
+ if (l1pd & L1_S_SUPERSEC)
+ pa = (l1pd & L1_SUP_FRAME) | (va & L1_SUP_OFFSET);
+ else
+ pa = (l1pd & L1_S_FRAME) | (va & L1_S_OFFSET);
+ pte = L2_S_PROTO | pa |
+ L2_S_PROT(PTE_KERNEL, VM_PROT_READ | VM_PROT_WRITE);
+ } else {
+ l2 = kernel_pmap->pm_l2[L2_IDX(l1idx)];
+ if (l2 == NULL ||
+ (ptep = l2->l2_bucket[L2_BUCKET(l1idx)].l2b_kva) == NULL) {
+ pte = 0;
+ pa = 0;
+ goto out;
+ }
+ pte = ptep[l2pte_index(va)];
+ if (pte == 0) {
+ pa = 0;
+ goto out;
+ }
+ switch (pte & L2_TYPE_MASK) {
+ case L2_TYPE_L:
+ pa = (pte & L2_L_FRAME) | (va & L2_L_OFFSET);
+ break;
+ default:
+ pa = (pte & L2_S_FRAME) | (va & L2_S_OFFSET);
+ break;
+ }
+ }
+out:
+ if (pte2p != NULL)
+ *pte2p = pte;
+ return (pa);
+}
+
/*
* Initialize a preallocated and zeroed pmap structure,
* such as one in a vmspace structure.
Index: head/sys/arm/include/pmap-v6.h
===================================================================
--- head/sys/arm/include/pmap-v6.h
+++ head/sys/arm/include/pmap-v6.h
@@ -200,6 +200,8 @@
void pmap_dcache_wb_range(vm_paddr_t , vm_size_t , vm_memattr_t );
vm_paddr_t pmap_kextract(vm_offset_t );
+vm_paddr_t pmap_dump_kextract(vm_offset_t, pt2_entry_t *);
+
int pmap_fault(pmap_t , vm_offset_t , uint32_t , int , bool);
#define vtophys(va) pmap_kextract((vm_offset_t)(va))
Index: head/sys/arm/include/pmap.h
===================================================================
--- head/sys/arm/include/pmap.h
+++ head/sys/arm/include/pmap.h
@@ -263,6 +263,7 @@
void *pmap_kenter_temporary(vm_paddr_t pa, int i);
void pmap_kenter_user(vm_offset_t va, vm_paddr_t pa);
vm_paddr_t pmap_kextract(vm_offset_t va);
+vm_paddr_t pmap_dump_kextract(vm_offset_t, pt2_entry_t *);
void pmap_kremove(vm_offset_t);
void *pmap_mapdev(vm_offset_t, vm_size_t);
void pmap_unmapdev(vm_offset_t, vm_size_t);
Index: head/sys/arm/include/pte.h
===================================================================
--- head/sys/arm/include/pte.h
+++ head/sys/arm/include/pte.h
@@ -43,6 +43,7 @@
#ifndef LOCORE
typedef uint32_t pd_entry_t; /* page directory entry */
typedef uint32_t pt_entry_t; /* page table entry */
+typedef pt_entry_t pt2_entry_t; /* compatibility with v6 */
#endif
#define PG_FRAME 0xfffff000
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Nov 20, 2:45 PM (16 h, 54 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
25715839
Default Alt Text
D5023.diff (10 KB)
Attached To
Mode
D5023: ARM minidump - new interface for pmap
Attached
Detach File
Event Timeline
Log In to Comment