This patch set updates ppc "irq" and PTE translation display of book3e. - Support "irq" command for recent kernel The ppc's "irq" could not work well for recent kernel at all because ppc_init() always made SIZE(irq_desc_t) invalid by itself. And also, "irq" options were not supported entirely. Stash legacy ppc_dump_irq() behind generic_dump_irq() so that "irq" works on recent kernel and follow toward mainline updates lightly by using generic irq functions. - Fix PTE translation for book3e Although book3e uses multiple PTE bits for one attribute, ppc_translate_pte() can not handle such attributes well. And further privilege (kernel) RW protection bit assign of book3e are different from user's ones. Fix and add these translation features in ppc_translate_pte(). - results of update Before: irq can not work at all. crash> help -m | grep dump_irq dump_irq: ppc_dump_irq() crash> irq irq: cannot determine number of IRQs After: "irq" command work well crash> irq 36 IRQ: 36 STATUS: 24004 (IRQ_LEVEL) HANDLER: ebc08004 typename: c07c7044 " OpenPIC " startup: c00ca754 <default_startup> shutdown: c00ca6f0 <default_shutdown> enable: c00ca7b8 <default_enable> disable: c00ca5a8 <default_disable> : ACTION: eac56e80 handler: c043e398 <serial8250_interrupt> flags: 8080 name: c07c4534 "serial" dev_id: ebe3bec0 next: 0 DEPTH: 0 crash> irq -s CPU0 CPU1 CPU2 CPU3 CPU4 CPU5 CPU6 CPU7 16: 0 0 0 0 0 0 0 0 OpenPIC bman-err,qman-err,error_rx,fman-err,fman-err,pme-err 17: 0 0 0 0 0 0 0 0 OpenPIC ds3232 : crash> irq -c 0 -s CPU0 16: 0 OpenPIC bman-err,qman-err,error_rx,fman-err,fman-err,pme-err 17: 0 OpenPIC ds3232 : crash> irq -a IRQ NAME AFFINITY 16 bman-err,qman-err,error_rx,fman-err,fman-err,pme-err 0-7 17 ds3232 0-7 : Before/After: PTE translation is updated like crash> vtop f987c01c [kernel vaddr] PTE PHYSICAL FLAGS ff974241255 ff974000 (PRESENT|USER|RW|COHERENT|DIRTY|ACCESSED) * multiple bits attribute USER or RW(non privilege) is not set in 255h => Fix as below PTE PHYSICAL FLAGS ff974241255 ff974000 (PRESENT|K-RW|COHERENT|DIRTY|ACCESSED) Thanks, Toshi Toshikazu Nakayama (6): ppc: update dump_irq() ppc: rework nr_irqs initialization ppc: add show_interrupts ppc: add get_irq_affinity ppc: fix the handling of PTE flags in translate_pte ppc: handle privilege level rw access from pte defs.h | 7 ++++- ppc.c | 65 ++++++++++++++++++++++++++++++++++++++++++++------------------- 2 files changed, 50 insertions(+), 22 deletions(-)
Date: Mon, 25 Jun 2012 13:28:24 +0900 Subject: [PATCH 1/6] ppc: update dump_irq() A ppc's "irq" command can not work out in recent kernels or can not support several IRQ features like CONFIG_SPARSE_IRQ. Try to use generic_dump_irq() as possible f size of irq_desc is already valid in kernel_init(). Signed-off-by: Toshikazu Nakayama <nakayama.ts@xxxxxxxxxxxxxx> --- ppc.c | 19 +++++++++++-------- 1 files changed, 11 insertions(+), 8 deletions(-) diff --git a/ppc.c b/ppc.c index 90fe246..4dc6e4b 100755 --- a/ppc.c +++ b/ppc.c @@ -360,16 +360,19 @@ ppc_init(int when) MEMBER_OFFSET_INIT(thread_struct_pg_tables, "thread_struct", "pg_tables"); - STRUCT_SIZE_INIT(irqdesc, "irqdesc"); - STRUCT_SIZE_INIT(irq_desc_t, "irq_desc_t"); - /* as of 2.3.x PPC uses the generic irq handlers */ - if (VALID_SIZE(irq_desc_t)) - machdep->dump_irq = generic_dump_irq; + if (VALID_SIZE(irq_desc_t)) + /* + * Use generic irq handlers for recent kernels whose + * irq_desc_t have been initialized in kernel_init(). + */ + machdep->dump_irq = generic_dump_irq; else { machdep->dump_irq = ppc_dump_irq; - MEMBER_OFFSET_INIT(irqdesc_action, "irqdesc", "action"); - MEMBER_OFFSET_INIT(irqdesc_ctl, "irqdesc", "ctl"); - MEMBER_OFFSET_INIT(irqdesc_level, "irqdesc", "level"); + STRUCT_SIZE_INIT(irqdesc, "irqdesc"); + STRUCT_SIZE_INIT(irq_desc_t, "irq_desc_t"); + MEMBER_OFFSET_INIT(irqdesc_action, "irqdesc", "action"); + MEMBER_OFFSET_INIT(irqdesc_ctl, "irqdesc", "ctl"); + MEMBER_OFFSET_INIT(irqdesc_level, "irqdesc", "level"); } MEMBER_OFFSET_INIT(device_node_type, "device_node", "type"); -- 1.7.0.4
Date: Mon, 25 Jun 2012 13:53:04 +0900 Subject: [PATCH 2/6] ppc: rework nr_irqs initialization When CONFIG_SPARSE_IRQ=y, irq_desc symbol is not defined, however, nr_irqs can be used instead. And like x86, default value is changed from 0 to 512 (NR_IRQS which is kernel config default value in powerpc). Signed-off-by: Toshikazu Nakayama <nakayama.ts@xxxxxxxxxxxxxx> --- ppc.c | 5 ++++- 1 files changed, 4 insertions(+), 1 deletions(-) diff --git a/ppc.c b/ppc.c index 4dc6e4b..a6b7d31 100755 --- a/ppc.c +++ b/ppc.c @@ -392,8 +392,11 @@ ppc_init(int when) if (symbol_exists("irq_desc")) ARRAY_LENGTH_INIT(machdep->nr_irqs, irq_desc, "irq_desc", NULL, 0); + else if (symbol_exists("nr_irqs")) + get_symbol_data("nr_irqs", sizeof(int), + &machdep->nr_irqs); else - machdep->nr_irqs = 0; + machdep->nr_irqs = 512; /* NR_IRQS (at least) */ if (!machdep->hz) { machdep->hz = HZ; if (THIS_KERNEL_VERSION >= LINUX(2,6,0)) -- 1.7.0.4
Date: Mon, 25 Jun 2012 14:29:42 +0900 Subject: [PATCH 3/6] ppc: add show_interrupts Support irq stats "-s", "-c" options by using generic_show_interrupts. Signed-off-by: Toshikazu Nakayama <nakayama.ts@xxxxxxxxxxxxxx> --- ppc.c | 6 ++++-- 1 files changed, 4 insertions(+), 2 deletions(-) diff --git a/ppc.c b/ppc.c index a6b7d31..6bc2f4e 100755 --- a/ppc.c +++ b/ppc.c @@ -360,13 +360,14 @@ ppc_init(int when) MEMBER_OFFSET_INIT(thread_struct_pg_tables, "thread_struct", "pg_tables"); - if (VALID_SIZE(irq_desc_t)) + if (VALID_SIZE(irq_desc_t)) { /* * Use generic irq handlers for recent kernels whose * irq_desc_t have been initialized in kernel_init(). */ machdep->dump_irq = generic_dump_irq; - else { + machdep->show_interrupts = generic_show_interrupts; + } else { machdep->dump_irq = ppc_dump_irq; STRUCT_SIZE_INIT(irqdesc, "irqdesc"); STRUCT_SIZE_INIT(irq_desc_t, "irq_desc_t"); @@ -474,6 +475,7 @@ ppc_dump_machdep_table(ulong arg) fprintf(fp, " dump_irq: generic_dump_irq()\n"); else fprintf(fp, " dump_irq: ppc_dump_irq()\n"); + fprintf(fp, " show_interrupts: generic_show_interrupts()\n"); fprintf(fp, " get_stack_frame: ppc_get_stack_frame()\n"); fprintf(fp, " get_stackbase: generic_get_stackbase()\n"); fprintf(fp, " get_stacktop: generic_get_stacktop()\n"); -- 1.7.0.4
Date: Mon, 25 Jun 2012 14:41:22 +0900 Subject: [PATCH 4/6] ppc: add get_irq_affinity Support irq affinity "-a" option by using generic_get_irq_affinity. Signed-off-by: Toshikazu Nakayama <nakayama.ts@xxxxxxxxxxxxxx> --- ppc.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/ppc.c b/ppc.c index 6bc2f4e..be290da 100755 --- a/ppc.c +++ b/ppc.c @@ -367,6 +367,7 @@ ppc_init(int when) */ machdep->dump_irq = generic_dump_irq; machdep->show_interrupts = generic_show_interrupts; + machdep->get_irq_affinity = generic_get_irq_affinity; } else { machdep->dump_irq = ppc_dump_irq; STRUCT_SIZE_INIT(irqdesc, "irqdesc"); @@ -476,6 +477,7 @@ ppc_dump_machdep_table(ulong arg) else fprintf(fp, " dump_irq: ppc_dump_irq()\n"); fprintf(fp, " show_interrupts: generic_show_interrupts()\n"); + fprintf(fp, " get_irq_affinity: generic_get_irq_affinity()\n"); fprintf(fp, " get_stack_frame: ppc_get_stack_frame()\n"); fprintf(fp, " get_stackbase: generic_get_stackbase()\n"); fprintf(fp, " get_stacktop: generic_get_stacktop()\n"); -- 1.7.0.4
Date: Mon, 25 Jun 2012 17:11:55 +0900 Subject: [PATCH 5/6] ppc: fix the handling of PTE flags in translate_pte Some platforms like as BOOK3E own multiple bits PTE flag. #define BOOK3E_PAGE_USER BOOK3E_PAGE_BAP_SR | BOOK3E_PAGE_BAP_UR #define BOOK3E_PAGE_RW BOOK3E_PAGE_BAP_SW | BOOK3E_PAGE_BAP_UW Modify to handle condition with (pte64 & flag) == flag for all PTE flags and make considerations about not bit assigned attributes like HWWRITE. Signed-off-by: Toshikazu Nakayama <nakayama.ts@xxxxxxxxxxxxxx> --- ppc.c | 30 ++++++++++++++++++++---------- 1 files changed, 20 insertions(+), 10 deletions(-) diff --git a/ppc.c b/ppc.c index be290da..1238c08 100755 --- a/ppc.c +++ b/ppc.c @@ -948,25 +948,35 @@ ppc_translate_pte(ulong pte32, void *physaddr, ulonglong pte64) others = 0; if (pte64) { - if (pte64 & _PAGE_PRESENT) + if (_PAGE_PRESENT && + (pte64 & _PAGE_PRESENT) == _PAGE_PRESENT) fprintf(fp, "%sPRESENT", others++ ? "|" : ""); - if (pte64 & _PAGE_USER) + if (_PAGE_USER && + (pte64 & _PAGE_USER) == _PAGE_USER) fprintf(fp, "%sUSER", others++ ? "|" : ""); - if (pte64 & _PAGE_RW) + if (_PAGE_RW && + (pte64 & _PAGE_RW) == _PAGE_RW) fprintf(fp, "%sRW", others++ ? "|" : ""); - if (pte64 & _PAGE_GUARDED) + if (_PAGE_GUARDED && + (pte64 & _PAGE_GUARDED) == _PAGE_GUARDED) fprintf(fp, "%sGUARDED", others++ ? "|" : ""); - if (pte64 & _PAGE_COHERENT) + if (_PAGE_COHERENT && + (pte64 & _PAGE_COHERENT) == _PAGE_COHERENT) fprintf(fp, "%sCOHERENT", others++ ? "|" : ""); - if (pte64 & _PAGE_NO_CACHE) + if (_PAGE_NO_CACHE && + (pte64 & _PAGE_NO_CACHE) == _PAGE_NO_CACHE) fprintf(fp, "%sNO_CACHE", others++ ? "|" : ""); - if (pte64 & _PAGE_WRITETHRU) + if (_PAGE_WRITETHRU && + (pte64 & _PAGE_WRITETHRU) == _PAGE_WRITETHRU) fprintf(fp, "%sWRITETHRU", others++ ? "|" : ""); - if (pte64 & _PAGE_DIRTY) + if (_PAGE_DIRTY && + (pte64 & _PAGE_DIRTY) == _PAGE_DIRTY) fprintf(fp, "%sDIRTY", others++ ? "|" : ""); - if (pte64 & _PAGE_ACCESSED) + if (_PAGE_ACCESSED && + (pte64 & _PAGE_ACCESSED) == _PAGE_ACCESSED) fprintf(fp, "%sACCESSED", others++ ? "|" : ""); - if (pte64 & _PAGE_HWWRITE) + if (_PAGE_HWWRITE && + (pte64 & _PAGE_HWWRITE) == _PAGE_HWWRITE) fprintf(fp, "%sHWWRITE", others++ ? "|" : ""); } else fprintf(fp, "no mapping"); -- 1.7.0.4
Date: Tue, 26 Jun 2012 14:45:17 +0900 Subject: [PATCH 6/6] ppc: handle privilege level rw access from pte A book3e PTE format own separated read and write protection bits to set privilege user (kernel) or non privilege user. The kernel rw ptes set only privilege bits and user rw ptes set both bits. Handle privilege bits for kernel pte and new K(Kernel)-RW protection display from translate_pte. Signed-off-by: Toshikazu Nakayama <nakayama.ts@xxxxxxxxxxxxxx> --- defs.h | 7 +++++-- ppc.c | 5 +++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/defs.h b/defs.h index 09e1bed..7a8ad6c 100755 --- a/defs.h +++ b/defs.h @@ -2768,6 +2768,7 @@ struct machine_specific { ulong _page_accessed; ulong _page_hwwrite; ulong _page_shared; + ulong _page_k_rw; /* platform special vtop */ int (*vtop_special)(ulong vaddr, physaddr_t *paddr, int verbose); @@ -2806,6 +2807,7 @@ struct machine_specific { #define _PAGE_ACCESSED (machdep->machspec->_page_accessed) /* R: page referenced */ #define _PAGE_HWWRITE (machdep->machspec->_page_hwwrite) /* software: _PAGE_RW & _PAGE_DIRTY */ #define _PAGE_SHARED (machdep->machspec->_page_shared) +#define _PAGE_K_RW (machdep->machspec->_page_k_rw) /* privilege only write access allowed */ /* Default values for PAGE flags */ #define DEFAULT_PAGE_PRESENT 0x001 @@ -2839,8 +2841,6 @@ struct machine_specific { #define BOOK3E_PAGE_BAP_UR 0x000008 /* User Readable */ #define BOOK3E_PAGE_BAP_SW 0x000010 #define BOOK3E_PAGE_BAP_UW 0x000020 /* User Writable */ -#define BOOK3E_PAGE_USER BOOK3E_PAGE_BAP_SR | BOOK3E_PAGE_BAP_UR -#define BOOK3E_PAGE_RW BOOK3E_PAGE_BAP_SW | BOOK3E_PAGE_BAP_UW #define BOOK3E_PAGE_DIRTY 0x001000 #define BOOK3E_PAGE_ACCESSED 0x040000 #define BOOK3E_PAGE_GUARDED 0x100000 @@ -2849,6 +2849,9 @@ struct machine_specific { #define BOOK3E_PAGE_WRITETHRU 0x800000 #define BOOK3E_PAGE_HWWRITE 0 #define BOOK3E_PAGE_SHARED 0 +#define BOOK3E_PAGE_USER (BOOK3E_PAGE_BAP_SR | BOOK3E_PAGE_BAP_UR) +#define BOOK3E_PAGE_RW (BOOK3E_PAGE_BAP_SW | BOOK3E_PAGE_BAP_UW) +#define BOOK3E_PAGE_KERNEL_RW (BOOK3E_PAGE_BAP_SW | BOOK3E_PAGE_BAP_SR | BOOK3E_PAGE_DIRTY) /* FSL BOOKE */ #define FSL_BOOKE_PAGE_PRESENT 0x00001 diff --git a/ppc.c b/ppc.c index 1238c08..23f2cc2 100755 --- a/ppc.c +++ b/ppc.c @@ -226,6 +226,8 @@ probe_ppce500_platform(char *name) if (IS_PAE()) { PTE_RPN_SHIFT = BOOKE3E_PTE_RPN_SHIFT; PLATFORM_PAGE_FLAGS_SETUP(BOOK3E); + /* Set special flag for book3e */ + _PAGE_K_RW = BOOK3E_PAGE_KERNEL_RW; } else PLATFORM_PAGE_FLAGS_SETUP(FSL_BOOKE); fsl_booke_mmu_setup(); @@ -957,6 +959,9 @@ ppc_translate_pte(ulong pte32, void *physaddr, ulonglong pte64) if (_PAGE_RW && (pte64 & _PAGE_RW) == _PAGE_RW) fprintf(fp, "%sRW", others++ ? "|" : ""); + if (_PAGE_K_RW && + ((pte64 & _PAGE_K_RW) == _PAGE_K_RW)) + fprintf(fp, "%sK-RW", others++ ? "|" : ""); if (_PAGE_GUARDED && (pte64 & _PAGE_GUARDED) == _PAGE_GUARDED) fprintf(fp, "%sGUARDED", others++ ? "|" : ""); -- 1.7.0.4
-- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility