Dne St 11. ledna 2012 00:37:50 Petr Tesarik napsal(a): > [...] > I can see now that this is unnecessarily complicated, because the > node_remap_* variables are static arrays of MAX_NUMNODES elements, so I > can get their size from the debuginfo at POST_GDB init and initialize a > machine-specific data type with it. I'll post another patch tomorrow. And here we go. Tested on my system and seems to work just fine. Petr Tesarik SUSE Linux
From: Petr Tesarik <ptesarik@xxxxxxx> Subject: [x86] Add correct handling of regions allocated with the remap allocator References: bnc#738742 Patch-mainline: no For NUMA x86, the pgdat is remapped into the node's physical memory. Since that physical memory may not be reachable through the identity mapping, a small part of the identity mapping is used. This special case has never been handled properly by crash. Signed-off-by: Petr Tesarik <ptesarik@xxxxxxx> --- defs.h | 4 ++ x86.c | 119 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 115 insertions(+), 8 deletions(-) --- a/defs.h +++ b/defs.h @@ -4253,6 +4253,10 @@ struct machine_specific { ulonglong last_pmd_read_PAE; ulonglong last_ptbl_read_PAE; ulong page_protnone; + int max_numnodes; + ulong *remap_start_vaddr; + ulong *remap_end_vaddr; + ulong *remap_start_pfn; }; struct syment *x86_is_entry_tramp_address(ulong, ulong *); --- a/x86.c +++ b/x86.c @@ -996,6 +996,7 @@ static int x86_uvtop_xen_wpt(struct task static int x86_kvtop_xen_wpt(struct task_context *, ulong, physaddr_t *, int); static int x86_uvtop_xen_wpt_PAE(struct task_context *, ulong, physaddr_t *, int); static int x86_kvtop_xen_wpt_PAE(struct task_context *, ulong, physaddr_t *, int); +static int x86_kvtop_remap(ulong, physaddr_t *); static ulong x86_get_task_pgd(ulong); static ulong x86_processor_speed(void); static ulong x86_get_pc(struct bt_info *); @@ -1006,6 +1007,7 @@ static uint64_t x86_memory_size(void); static ulong x86_vmalloc_start(void); static ulong *read_idt_table(int); static void eframe_init(void); +static int remap_init(void); #define READ_IDT_INIT 1 #define READ_IDT_RUNTIME 2 static char *extract_idt_function(ulong *, char *, ulong *); @@ -2014,6 +2016,8 @@ x86_init(int when) "pr_reg"); STRUCT_SIZE_INIT(percpu_data, "percpu_data"); + remap_init(); + break; case POST_INIT: @@ -2084,6 +2088,72 @@ eframe_init(void) } /* + * Locate regions remapped by the remap allocator + */ +static int +remap_init(void) +{ + ulong start_vaddr, end_vaddr, start_pfn; + struct machine_specific *ms; + struct syment *sp; + + if (! (sp = symbol_search("node_remap_start_vaddr")) ) + return FALSE; + start_vaddr = sp->value; + + if (! (sp = symbol_search("node_remap_end_vaddr")) ) + return FALSE; + end_vaddr = sp->value; + + if (! (sp = symbol_search("node_remap_start_pfn")) ) + return FALSE; + start_pfn = sp->value; + + ms = machdep->machspec; + ms->max_numnodes = get_array_length("node_remap_start_pfn", NULL, + sizeof(ulong)); + if (ms->max_numnodes < 1) + ms->max_numnodes = 1; + + ms->remap_start_vaddr = calloc(3*ms->max_numnodes, sizeof(ulong)); + if (!ms->remap_start_vaddr) + error(FATAL, "cannot malloc remap array"); + ms->remap_end_vaddr = ms->remap_start_vaddr + ms->max_numnodes; + ms->remap_start_pfn = ms->remap_end_vaddr + ms->max_numnodes; + + readmem(start_vaddr, KVADDR, ms->remap_start_vaddr, + ms->max_numnodes * sizeof(ulong), "node_remap_start_vaddr", + FAULT_ON_ERROR); + readmem(end_vaddr, KVADDR, ms->remap_end_vaddr, + ms->max_numnodes * sizeof(ulong), "node_remap_end_vaddr", + FAULT_ON_ERROR); + readmem(start_pfn, KVADDR, ms->remap_start_pfn, + ms->max_numnodes * sizeof(ulong), "node_remap_end_vaddr", + FAULT_ON_ERROR); + + return TRUE; +} + +static int +x86_kvtop_remap(ulong kvaddr, physaddr_t *paddr) +{ + struct machine_specific *ms; + int i; + + ms = machdep->machspec; + + for (i = 0; i < ms->max_numnodes; ++i) { + if (kvaddr >= ms->remap_start_vaddr[i] && + kvaddr < ms->remap_end_vaddr[i]) { + *paddr = PTOB(ms->remap_start_pfn[i]) + + kvaddr - ms->remap_start_vaddr[i]; + return TRUE; + } + } + return FALSE; +} + +/* * Needs to be done this way because of potential 4G/4G split. */ static int @@ -2768,12 +2838,13 @@ x86_kvtop(struct task_context *tc, ulong } pgd = (ulong *)symbol_value("idle_pg_table_l2"); } else { - if (!vt->vmalloc_start) { + if (x86_kvtop_remap(kvaddr, paddr)) { + if (!verbose) + return TRUE; + } else if (!vt->vmalloc_start) { *paddr = VTOP(kvaddr); return TRUE; - } - - if (!IS_VMALLOC_ADDR(kvaddr)) { + } else if (!IS_VMALLOC_ADDR(kvaddr)) { *paddr = VTOP(kvaddr); if (!verbose) return TRUE; @@ -3023,12 +3094,13 @@ x86_kvtop_PAE(struct task_context *tc, u else pgd = (ulonglong *)symbol_value("idle_pg_table"); } else { - if (!vt->vmalloc_start) { + if (x86_kvtop_remap(kvaddr, paddr)) { + if (!verbose) + return TRUE; + } else if (!vt->vmalloc_start) { *paddr = VTOP(kvaddr); return TRUE; - } - - if (!IS_VMALLOC_ADDR(kvaddr)) { + } else if (!IS_VMALLOC_ADDR(kvaddr)) { *paddr = VTOP(kvaddr); if (!verbose) return TRUE; @@ -3354,6 +3426,8 @@ x86_dump_machdep_table(ulong arg) int others; ulong xen_wpt; char buf[BUFSIZE]; + struct machine_specific *ms; + int i, j, max_numnodes; switch (arg) { default: @@ -3489,6 +3563,35 @@ x86_dump_machdep_table(ulong arg) machdep->machspec->last_ptbl_read_PAE); fprintf(fp, " page_protnone: %lx\n", machdep->machspec->page_protnone); + fprintf(fp, " MAX_NUMNODES: %ld\n", + machdep->machspec->max_numnodes); + + ms = machdep->machspec; + max_numnodes = ms->max_numnodes; + + fprintf(fp, " remap_start_vaddr:"); + for (i = 0; i < max_numnodes; ++i) { + if ((i % 8) == 0) + fprintf(fp, "\n "); + fprintf(fp, "%08lx ", ms->remap_start_vaddr[i]); + } + fprintf(fp, "\n"); + + fprintf(fp, " remap_end_vaddr:"); + for (i = 0; i < max_numnodes; ++i) { + if ((i % 8) == 0) + fprintf(fp, "\n "); + fprintf(fp, "%08lx ", ms->remap_end_vaddr[i]); + } + fprintf(fp, "\n"); + + fprintf(fp, " remap_start_pfn:"); + for (i = 0; i < max_numnodes; ++i) { + if ((i % 8) == 0) + fprintf(fp, "\n "); + fprintf(fp, "%08lx ", ms->remap_start_pfn[i]); + } + fprintf(fp, "\n"); } /*
-- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility