A recent patch to the the upstream 2.6.23 kernel, and RHEL5
kernels from 2.6.18-40.el5 and beyond, changes the ppc64
PTE_RPN_SHIFT in pgtable-64k.h from 32 to 30 bits. This
in turn causes the crash utility's virtual-to-physical address
translation of kernel vmalloc() and user-space virtual addresses
to fail on ppc64 kernels configured with 64K pages. During
crash session initialization, this warning message is displayed:
WARNING: cannot access vmalloc'd module memory
The same message will appear if the "mod" command is subsequently
attempted.
Translations and reads of vmalloc'd kernel virtual addresses and
user virtual addresses will appear to work, but bogus data will
be returned because the resultant physical address that is read
is incorrect.
The attached patch recognizes whether this patch has been applied
and adjusts the PTE shift value accordingly. There's also some
additional "help -m" output for the machine-specific data that
was missing from the display.
The patch tests OK, and I don't believe any other vtop-related
changes are required, but given that the ppc64.c was contributed
by IBM, can I get an ACK from the IBM brain-trust out there?
Thanks,
Dave
--- crash-4.0-4.8/defs.h 2007-11-13 11:21:32.000000000 -0500
+++ next/defs.h 2007-11-13 11:20:00.000000000 -0500
@@ -2526,7 +2526,8 @@
#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 PTE_SHIFT_L4_64K_V1 32
+#define PTE_SHIFT_L4_64K_V2 30
#define PMD_MASKED_BITS_64K 0x1ff
#define L4_OFFSET(vaddr) ((vaddr >> (machdep->machspec->l4_shift)) &
0x1ff)
--- crash-4.0-4.8/ppc64.c 2007-11-13 11:21:32.000000000 -0500
+++ next/ppc64.c 2007-11-13 11:20:00.000000000 -0500
@@ -160,7 +160,8 @@
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->pte_shift = symbol_exists("demote_segment_4k") ?
+ PTE_SHIFT_L4_64K_V2 : PTE_SHIFT_L4_64K_V1;
m->l2_masked_bits = PMD_MASKED_BITS_64K;
} else {
/* 4K pagesize */
@@ -305,7 +306,7 @@
void
ppc64_dump_machdep_table(ulong arg)
{
- int others;
+ int i, c, others;
others = 0;
fprintf(fp, " flags: %lx (", machdep->flags);
@@ -368,10 +369,43 @@
fprintf(fp, " max_physmem_bits: %ld\n",
machdep->max_physmem_bits);
fprintf(fp, " sections_per_root: %ld\n",
machdep->sections_per_root);
fprintf(fp, " machspec: %lx\n", (ulong)machdep->machspec);
- fprintf(fp, " pgd_index_size: %d\n",
machdep->machspec->l4_index_size);
- fprintf(fp, " pud_index_size: %d\n",
machdep->machspec->l3_index_size);
- fprintf(fp, " pmd_index_size: %d\n",
machdep->machspec->l2_index_size);
- fprintf(fp, " pte_index_size: %d\n",
machdep->machspec->l1_index_size);
+ fprintf(fp, " hwintrstack[%d]: ", NR_CPUS,
machdep->machspec->l4_index_size);
+ for (c = 0; c < NR_CPUS; c++) {
+ for (others = 0, i = c; i < NR_CPUS; i++) {
+ if (machdep->machspec->hwintrstack[i])
+ others++;
+ }
+ if (!others) {
+ fprintf(fp, "%s%s",
+ c && ((c % 4) == 0) ? "\n " : "",
+ c ? "(remainder unused)" : "(unused)");
+ break;
+ }
+
+ fprintf(fp, "%s%016lx ",
+ ((c % 4) == 0) ? "\n " : "",
+ machdep->machspec->hwintrstack[c]);
+ }
+ fprintf(fp, "\n");
+ fprintf(fp, " hwstackbuf: %lx\n",
(ulong)machdep->machspec->hwstackbuf);
+ fprintf(fp, " hwstacksize: %d\n",
(ulong)machdep->machspec->hwstacksize);
+ fprintf(fp, " level4: %lx\n",
(ulong)machdep->machspec->level4);
+ fprintf(fp, " last_level4_read: %lx\n",
(ulong)machdep->machspec->last_level4_read);
+ fprintf(fp, " l4_index_size: %d\n",
machdep->machspec->l4_index_size);
+ fprintf(fp, " l3_index_size: %d\n",
machdep->machspec->l3_index_size);
+ fprintf(fp, " l2_index_size: %d\n",
machdep->machspec->l2_index_size);
+ fprintf(fp, " l1_index_size: %d\n",
machdep->machspec->l1_index_size);
+ fprintf(fp, " ptrs_per_l3: %d\n",
machdep->machspec->ptrs_per_l3);
+ fprintf(fp, " ptrs_per_l2: %d\n",
machdep->machspec->ptrs_per_l2);
+ fprintf(fp, " ptrs_per_l1: %d\n",
machdep->machspec->ptrs_per_l1);
+ fprintf(fp, " l4_shift: %d\n",
machdep->machspec->l4_shift);
+ fprintf(fp, " l3_shift: %d\n",
machdep->machspec->l3_shift);
+ fprintf(fp, " l2_shift: %d\n",
machdep->machspec->l2_shift);
+ fprintf(fp, " l1_shift: %d\n",
machdep->machspec->l1_shift);
+ fprintf(fp, " pte_shift: %d\n",
machdep->machspec->pte_shift);
+ fprintf(fp, " l2_masked_bits: %d\n",
machdep->machspec->l2_masked_bits);
+
+
}
/*