ppc: work out irq and fix pte translation display

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

 



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

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

 

Powered by Linux