Page MenuHomeFreeBSD

D5023.diff
No OneTemporary

D5023.diff

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

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)

Event Timeline