Re: [Crash-utility] crash-4.0.2.12 PPC64 changes to make it understand64k pagesize

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, 2005-11-17 at 13:18 -0800, Haren Myneni wrote:

> > But it's your call... so when you and Haren are happy, just let
> > me know. 
> 
> Badari, Thanks a lot for doing this. This approach is useful to
> support easily even for future changes. One minor comment, instead of
> hardcoding in ppc64.c source file for 'm->l1_index_size = 9', can we
> define INDEX  macros in the header file and use them here. For
> example, PTE_INDEX_SIZE_L4. I am thinking we can map/understand easily
> to see what is l1 or l2. What do you think? 

Okay, here is the latest to include what Dave and Haren want.

Please review.

Thanks,
Badari
--- crash/defs.h	2005-11-17 10:45:13.000000000 -0800
+++ new/defs.h	2005-11-17 14:44:14.000000000 -0800
@@ -2101,23 +2101,31 @@ struct efi_memory_desc_t {
 #define PGD_OFFSET(vaddr)       ((vaddr >> PGDIR_SHIFT) & 0x7ff)
 #define PMD_OFFSET(vaddr)       ((vaddr >> PMD_SHIFT) & (PTRS_PER_PMD - 1))
 
-/* 4-level page table changes */
-#define PGDIR_SHIFT_L4	(PMD_SHIFT + (machdep->pageshift - 5))
-#define L4_SHIFT	(PGDIR_SHIFT_L4 + (machdep->pageshift - 5))
-
-#define PTE_SHIFT_L4 17
-
-#define PTE_INDEX_SIZE_L4  9
-#define PMD_INDEX_SIZE_L4  7
-#define PGD_INDEX_SIZE_L4  7
-
-#define PTRS_PER_PTE_L4		(1 << PTE_INDEX_SIZE_L4)
-#define PTRS_PER_PMD_L4		(1 << PMD_INDEX_SIZE_L4)
-#define PTRS_PER_PGD_L4		(1 << PGD_INDEX_SIZE_L4)
-
-#define L4_OFFSET(vaddr)	((vaddr >> L4_SHIFT) & 0x1ff)
-#define PGD_OFFSET_L4(vaddr)	((vaddr >> PGDIR_SHIFT_L4) & (PTRS_PER_PGD_L4 - 1))
-#define PMD_OFFSET_L4(vaddr)	((vaddr >> PMD_SHIFT) & (PTRS_PER_PMD_L4 - 1))
+/* 4-level page table support */
+
+/* 4K pagesize */
+#define PTE_INDEX_SIZE_L4_4K  9
+#define PMD_INDEX_SIZE_L4_4K  7
+#define PUD_INDEX_SIZE_L4_4K  7
+#define PGD_INDEX_SIZE_L4_4K  9
+#define PTE_SHIFT_L4_4K  17
+#define PMD_MASKED_BITS_4K  0
+
+/* 64K pagesize */
+#define PTE_INDEX_SIZE_L4_64K  12
+#define PMD_INDEX_SIZE_L4_64K  12
+#define PUD_INDEX_SIZE_L4_64K  0
+#define PGD_INDEX_SIZE_L4_64K  4
+#define PTE_SHIFT_L4_64K  32
+#define PMD_MASKED_BITS_64K  0x1ff
+
+#define L4_OFFSET(vaddr)  ((vaddr >> (machdep->machspec->l4_shift)) & 0x1ff)
+
+#define PGD_OFFSET_L4(vaddr)	\
+	((vaddr >> (machdep->machspec->l3_shift)) & (machdep->machspec->ptrs_per_l3 - 1))
+
+#define PMD_OFFSET_L4(vaddr)	\
+	((vaddr >> (machdep->machspec->l2_shift)) & (machdep->machspec->ptrs_per_l2 - 1))
 
 #define _PAGE_PRESENT   0x001UL /* software: pte contains a translation */
 #define _PAGE_USER      0x002UL /* matches one of the PP bits */
@@ -3308,6 +3316,23 @@ struct machine_specific {
         uint hwstacksize;
         char *level4;
         ulong last_level4_read;
+
+	uint l4_index_size;
+	uint l3_index_size;
+	uint l2_index_size;
+	uint l1_index_size;
+
+	uint ptrs_per_l3;
+	uint ptrs_per_l2;
+	uint ptrs_per_l1;
+
+	uint l4_shift;
+	uint l3_shift;
+	uint l2_shift;
+	uint l1_shift;
+
+	uint pte_shift;
+	uint l2_masked_bits;
 };
 
 #define IS_LAST_L4_READ(l4)   ((ulong)(l4) == machdep->machspec->last_level4_read)
--- crash/ppc64.c	2005-11-17 10:45:16.000000000 -0800
+++ new/ppc64.c	2005-11-17 14:38:33.000000000 -0800
@@ -122,18 +122,44 @@ ppc64_init(int when)
 				machdep->flags |= VM_ORIG;
 			}
 		}
-		switch (machdep->flags & (VM_ORIG|VM_4_LEVEL)) 
-		{
-			case VM_ORIG:
-				/* pre-2.6.14 layout */
-				free(machdep->machspec->level4);
-				machdep->machspec->level4 = NULL;
-				machdep->ptrs_per_pgd = PTRS_PER_PGD;
-				break;
-			case VM_4_LEVEL:
-				/* 2.6.14 layout */
-				machdep->ptrs_per_pgd = PTRS_PER_PGD_L4;
-				break;
+		if (machdep->flags & VM_ORIG) {
+			/* pre-2.6.14 layout */
+			free(machdep->machspec->level4);
+			machdep->machspec->level4 = NULL;
+			machdep->ptrs_per_pgd = PTRS_PER_PGD;
+		} else {
+			/* 2.6.14 layout */
+			struct machine_specific *m = machdep->machspec;
+			if (machdep->pagesize == 65536) {
+				/* 64K pagesize */
+				m->l1_index_size = PTE_INDEX_SIZE_L4_64K;
+				m->l2_index_size = PMD_INDEX_SIZE_L4_64K;
+				m->l3_index_size = PUD_INDEX_SIZE_L4_64K;
+				m->l4_index_size = PGD_INDEX_SIZE_L4_64K;
+				m->pte_shift = PTE_SHIFT_L4_64K; 
+				m->l2_masked_bits = PMD_MASKED_BITS_64K;
+			} else {
+				/* 4K pagesize */
+				m->l1_index_size = PTE_INDEX_SIZE_L4_4K;
+				m->l2_index_size = PMD_INDEX_SIZE_L4_4K;
+				m->l3_index_size = PUD_INDEX_SIZE_L4_4K;
+				m->l4_index_size = PGD_INDEX_SIZE_L4_4K;
+				m->pte_shift = PTE_SHIFT_L4_4K; 
+				m->l2_masked_bits = PMD_MASKED_BITS_4K;
+			}
+
+			/* Compute ptrs per each level */
+			m->l1_shift = machdep->pageshift;
+			m->ptrs_per_l1 = (1 << m->l1_index_size);
+			m->ptrs_per_l2 = (1 << m->l2_index_size);
+			m->ptrs_per_l3 = (1 << m->l3_index_size);
+
+			machdep->ptrs_per_pgd = m->ptrs_per_l3;
+
+			/* Compute shifts */
+			m->l2_shift = m->l1_shift + m->l1_index_size;
+			m->l3_shift = m->l2_shift + m->l2_index_size;
+			m->l4_shift = m->l3_shift + m->l3_index_size;
 		}
 		machdep->vmalloc_start = ppc64_vmalloc_start;
 		MEMBER_OFFSET_INIT(thread_struct_pg_tables,
@@ -306,6 +332,10 @@ ppc64_dump_machdep_table(ulong arg)
         fprintf(fp, "               ptbl: %lx\n", (ulong)machdep->ptbl);
 	fprintf(fp, "       ptrs_per_pgd: %d\n", machdep->ptrs_per_pgd);
 	fprintf(fp, "           machspec: %lx\n", (ulong)machdep->machspec);
+	fprintf(fp, "     pgd_index_size: %ld\n", machdep->machspec->l4_index_size);
+	fprintf(fp, "     pud_index_size: %ld\n", machdep->machspec->l3_index_size);
+	fprintf(fp, "     pmd_index_size: %ld\n", machdep->machspec->l2_index_size);
+	fprintf(fp, "     pte_index_size: %ld\n", machdep->machspec->l1_index_size);
 }
 
 /*
@@ -413,15 +443,19 @@ ppc64_vtop_level4(ulong vaddr, ulong *le
 	if (!level4_pte)
 		return FALSE;
 
-	page_dir = (ulong *)((ulong *)level4_pte + PGD_OFFSET_L4(vaddr));
-	FILL_PGD(PAGEBASE(level4_pte), KVADDR, PAGESIZE());
-	pgd_pte = ULONG(machdep->pgd + PAGEOFFSET(page_dir));
-
-	if (verbose)
-		fprintf(fp, "  PGD: %lx => %lx\n", (ulong)page_dir, pgd_pte);
-
-	if (!pgd_pte)
-		return FALSE;
+	/* Sometimes we don't have level3 pagetable entries */
+	if (machdep->machspec->l3_index_size != 0) {
+		page_dir = (ulong *)((ulong *)level4_pte + PGD_OFFSET_L4(vaddr));
+		FILL_PGD(PAGEBASE(level4_pte), KVADDR, PAGESIZE());
+		pgd_pte = ULONG(machdep->pgd + PAGEOFFSET(page_dir));
+
+		if (verbose)
+			fprintf(fp, "  PGD: %lx => %lx\n", (ulong)page_dir, pgd_pte);
+		if (!pgd_pte)
+			return FALSE;
+	} else {
+		pgd_pte = level4_pte;
+	}
 
 	page_middle = (ulong *)((ulong *)pgd_pte + PMD_OFFSET_L4(vaddr));
 	FILL_PMD(PAGEBASE(pgd_pte), KVADDR, PAGESIZE());
@@ -433,7 +467,8 @@ ppc64_vtop_level4(ulong vaddr, ulong *le
 	if (!(pmd_pte))
 		return FALSE;
 
-	page_table = (ulong *)pmd_pte + (BTOP(vaddr) & (PTRS_PER_PTE_L4 - 1));
+	page_table = (ulong *)(pmd_pte & ~(machdep->machspec->l2_masked_bits))
+			 + (BTOP(vaddr) & (machdep->machspec->ptrs_per_l1 - 1));
 	if (verbose)
 		fprintf(fp, "  PMD: %lx => %lx\n",(ulong)page_middle,
 			(ulong)page_table);
@@ -447,7 +482,7 @@ ppc64_vtop_level4(ulong vaddr, ulong *le
 	if (!(pte & _PAGE_PRESENT)) {
 		if (pte && verbose) {
 			fprintf(fp, "\n");
-			ppc64_translate_pte(pte, 0, PTE_SHIFT_L4);
+			ppc64_translate_pte(pte, 0, machdep->machspec->pte_shift);
 		}
 		return FALSE;
 	}
@@ -455,11 +490,12 @@ ppc64_vtop_level4(ulong vaddr, ulong *le
 	if (!pte)
 		return FALSE;
 
-	*paddr = PAGEBASE(PTOB(pte >> PTE_SHIFT_L4)) + PAGEOFFSET(vaddr);
+	*paddr = PAGEBASE(PTOB(pte >> machdep->machspec->pte_shift)) 
+			+ PAGEOFFSET(vaddr);
 
 	if (verbose) {
 		fprintf(fp, " PAGE: %lx\n\n", PAGEBASE(*paddr));
-		ppc64_translate_pte(pte, 0, PTE_SHIFT_L4);
+		ppc64_translate_pte(pte, 0, machdep->machspec->pte_shift);
 	}
 
 	return TRUE;

[Index of Archives]     [Fedora Development]     [Fedora Desktop]     [Fedora SELinux]     [Yosemite News]     [KDE Users]     [Fedora Tools]

 

Powered by Linux