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 <[email protected]>
---
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 <[email protected]>
---
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 <[email protected]>
---
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 <[email protected]>
---
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 <[email protected]>
---
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 <[email protected]>
---
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
[email protected]
https://www.redhat.com/mailman/listinfo/crash-utility