Re: [PATCH] [PPC32] Fix vmalloc address translation for BookE

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

 



(2012/01/19 14:42), Suzuki K. Poulose wrote:
On ബുധന്‍ 18 ജനുവരി 2012 08:11 വൈകു, Dave Anderson wrote:


----- Original Message -----
(2012/01/16 14:15), Suzuki K. Poulose wrote:
This patch fixes the vmalloc address translation for BookE.This
patch is based on the PPC44x definitions and may not work fine for
other systems.

crash> mod
mod: cannot access vmalloc'd module memory
crash>


After the patch :

crash> mod
MODULE NAME SIZE OBJECT FILE
d1018fd8 mbcache 6023 (not loaded) [CONFIG_KALLSYMS]
d1077190 jbd 58360 (not loaded) [CONFIG_KALLSYMS]
d107ca98 llc 4525 (not loaded) [CONFIG_KALLSYMS]
d1130de4 ext3 203186 (not loaded) [CONFIG_KALLSYMS]
d114bbac squashfs 26129 (not loaded) [CONFIG_KALLSYMS]


On ppc44x, the virtual-address is split as below :

Bits |0 10|11 19|20 31|
-----------------------------------
| PGD | PMD | PAGE_OFFSET |
-----------------------------------

The PAGE_BASE_ADDR is a 64bit value(of type phys_addr_t).

Note : I am not sure how do we distinguish the different values (PGDIR_SHIFT etc)
for different PPC32 systems. Since there are a lot of different platforms
under PPC32, we need some mechanism to dynamically determine the PGDIR, PTE
shift values. One option is to put the information in the VMCOREINFO.

Hi Suzuki,

How about using powerpc_base_platform symbol?

*PTRRELOC(&powerpc_base_platform) = t->platform;

$ grep -rIw platform arch/powerpc/kernel/cputable.c
/* The platform string corresponding to the real PVR */
.platform = "power3",
.platform = "power3",
.platform = "rs64",
.platform = "rs64",
.platform = "rs64",
.platform = "rs64",
.platform = "power4",
.platform = "power4",
:
:

This kconfig based platform string data can be read
base_platform = symbol_value("powerpc_base_platform symbols");
read_string(base_platform, buf, buffer-size);
at ppc_init(POST_GDB).

I think platform can be distinguished with following naming rules.
- CONFIG_40x=y: platform is "ppc403"
- CONFIG_44x=y: platform is "ppc440"

Thanks,
Toshi

That makes good sense. Suzuki, are you re-working the patch
with Toshi's suggestion?

I will take a look at this. Sorry, have been a bit busy.

Hi Suzuki,

I'd put forward a proposal which can make your BookE support easy to adjust.
If this patch set is suitable for your Note's solution,
please merge into your works, and I'm not sure about BookE's word like PPC44X,
also please make reform of its staff.

Thanks,
Toshi.

Thanks
Suzuki

--
Crash-utility mailing list
Crash-utility@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/crash-utility


Date: Thu, 2 Feb 2012 09:06:23 +0900
Subject: [PATCH 1/4] ppc: change from define value to variable

PGDIR_SHIFT, PTRS_PER_PTE, and PTRS_PER_PGD values are depend on
PowerPC 32bit target platform.
Change them to int value and set existing values as defaults.

[Todo]
Learned this approach from x86.c.
However, since these defines are also provided as devel package,
not static, extern them now (or announce disappearing).

Signed-off-by: Toshikazu Nakayama <nakayama.ts@xxxxxxxxxxxxxx>
---
 defs.h |   10 +++++++---
 ppc.c  |    4 ++++
 2 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/defs.h b/defs.h
index 82d51e5..b64e886 100755
--- a/defs.h
+++ b/defs.h
@@ -2603,9 +2603,13 @@ struct load_module {
 #define VTOP(X)            ((unsigned long)(X)-(machdep->kvbase))
 #define IS_VMALLOC_ADDR(X) (vt->vmalloc_start && (ulong)(X) >= vt->vmalloc_start)
 
-#define PGDIR_SHIFT   (22)
-#define PTRS_PER_PTE  (1024)
-#define PTRS_PER_PGD  (1024)
+extern int PGDIR_SHIFT;
+extern int PTRS_PER_PTE;
+extern int PTRS_PER_PGD;
+/* ppc32's default page table format */
+#define PGDIR_SHIFT_DEFAULT	(22)
+#define PTRS_PER_PTE_DEFAULT	(1024)
+#define PTRS_PER_PGD_DEFAULT	(1024)
 
 #define _PAGE_PRESENT   0x001   /* software: pte contains a translation */
 #define _PAGE_USER      0x002   /* matches one of the PP bits */
diff --git a/ppc.c b/ppc.c
index a6e67fd..52d665d 100755
--- a/ppc.c
+++ b/ppc.c
@@ -69,6 +69,10 @@ static void ppc_display_machine_stats(void);
 static void ppc_dump_line_number(ulong);
 static struct line_number_hook ppc_line_number_hooks[];
 
+int PGDIR_SHIFT = PGDIR_SHIFT_DEFAULT;
+int PTRS_PER_PTE = PTRS_PER_PTE_DEFAULT;
+int PTRS_PER_PGD = PTRS_PER_PGD_DEFAULT;
+
 /*
  *  Do all necessary machine-specific setup here.  This is called twice,
  *  before and after GDB has been initialized.
-- 
1.7.8.163.g9859a


Date: Thu, 2 Feb 2012 09:37:23 +0900
Subject: [PATCH 2/4] ppc: add page table size variables

Add PGD_TABLE_SIZE and PTE_TABLE_SIZE and fill pagetables with
corresponding order size.
Also make consideration of machdep->pgd, ptbl realloc().

Signed-off-by: Toshikazu Nakayama <nakayama.ts@xxxxxxxxxxxxxx>
---
 defs.h |    4 ++++
 ppc.c  |   24 ++++++++++++++++++------
 2 files changed, 22 insertions(+), 6 deletions(-)

diff --git a/defs.h b/defs.h
index b64e886..68169b1 100755
--- a/defs.h
+++ b/defs.h
@@ -2606,10 +2606,14 @@ struct load_module {
 extern int PGDIR_SHIFT;
 extern int PTRS_PER_PTE;
 extern int PTRS_PER_PGD;
+extern int PGD_TABLE_SIZE;
+extern int PTE_TABLE_SIZE;
 /* ppc32's default page table format */
 #define PGDIR_SHIFT_DEFAULT	(22)
 #define PTRS_PER_PTE_DEFAULT	(1024)
 #define PTRS_PER_PGD_DEFAULT	(1024)
+#define PGD_TABLE_SIZE_DEFAULT	(1 << 12)
+#define PTE_TABLE_SIZE_DEFAULT	(1 << 12)
 
 #define _PAGE_PRESENT   0x001   /* software: pte contains a translation */
 #define _PAGE_USER      0x002   /* matches one of the PP bits */
diff --git a/ppc.c b/ppc.c
index 52d665d..f00092e 100755
--- a/ppc.c
+++ b/ppc.c
@@ -72,6 +72,8 @@ static struct line_number_hook ppc_line_number_hooks[];
 int PGDIR_SHIFT = PGDIR_SHIFT_DEFAULT;
 int PTRS_PER_PTE = PTRS_PER_PTE_DEFAULT;
 int PTRS_PER_PGD = PTRS_PER_PGD_DEFAULT;
+int PGD_TABLE_SIZE = PGD_TABLE_SIZE_DEFAULT;
+int PTE_TABLE_SIZE = PTE_TABLE_SIZE_DEFAULT;
 
 /*
  *  Do all necessary machine-specific setup here.  This is called twice,
@@ -94,10 +96,10 @@ ppc_init(int when)
                 machdep->pageoffset = machdep->pagesize - 1;
                 machdep->pagemask = ~((ulonglong)machdep->pageoffset);
 		machdep->stacksize = PPC_STACK_SIZE;
-                if ((machdep->pgd = (char *)malloc(PAGESIZE())) == NULL)
+		if ((machdep->pgd = (char *)malloc(PGD_TABLE_SIZE)) == NULL)
                         error(FATAL, "cannot malloc pgd space.");
                 machdep->pmd = machdep->pgd;
-                if ((machdep->ptbl = (char *)malloc(PAGESIZE())) == NULL)
+		if ((machdep->ptbl = (char *)malloc(PTE_TABLE_SIZE)) == NULL)
                         error(FATAL, "cannot malloc ptbl space.");
                 machdep->last_pgd_read = 0;
                 machdep->last_pmd_read = 0;
@@ -190,6 +192,16 @@ ppc_init(int when)
 		if ((THIS_KERNEL_VERSION >= LINUX(2,6,0)) &&
 			symbol_exists("hardirq_ctx"))
 			STRUCT_SIZE_INIT(irq_ctx, "hardirq_ctx");
+		/*
+		 * realloc page table buffers if size is changed.
+		 */
+		if ((PGD_TABLE_SIZE != PGD_TABLE_SIZE_DEFAULT) &&
+		    (machdep->pgd = (char *)realloc(PGD_TABLE_SIZE)) == NULL)
+			error(FATAL, "cannot realloc pgd space.");
+		machdep->pmd = machdep->pgd;
+		if ((PTE_TABLE_SIZE != PTE_TABLE_SIZE_DEFAULT) &&
+		    (machdep->ptbl = (char *)realloc(PTE_TABLE_SIZE)) == NULL)
+			error(FATAL, "cannot realloc ptbl space.");
 		break;
 
 	case POST_INIT:
@@ -322,7 +334,7 @@ ppc_uvtop(struct task_context *tc, ulong vaddr, physaddr_t *paddr, int verbose)
 
 	page_dir = pgd + (vaddr >> PGDIR_SHIFT);
 
-	FILL_PGD(PAGEBASE(pgd), KVADDR, PAGESIZE());
+	FILL_PGD(PAGEBASE(pgd), KVADDR, PGD_TABLE_SIZE);
 	pgd_pte = ULONG(machdep->pgd + PAGEOFFSET(page_dir));
 
 	if (verbose)
@@ -344,7 +356,7 @@ ppc_uvtop(struct task_context *tc, ulong vaddr, physaddr_t *paddr, int verbose)
 		fprintf(fp, "  PMD: %lx => %lx\n",(ulong)page_middle, 
 			(ulong)page_table);
 	
-        FILL_PTBL(PAGEBASE(page_table), KVADDR, PAGESIZE());
+        FILL_PTBL(PAGEBASE(page_table), KVADDR, PTE_TABLE_SIZE);
 	pte = ULONG(machdep->ptbl + PAGEOFFSET(page_table));
 
         if (verbose) 
@@ -411,7 +423,7 @@ ppc_kvtop(struct task_context *tc, ulong kvaddr, physaddr_t *paddr, int verbose)
 
 	page_dir = pgd + (kvaddr >> PGDIR_SHIFT);
 
-        FILL_PGD(PAGEBASE(pgd), KVADDR, PAGESIZE());
+        FILL_PGD(PAGEBASE(pgd), KVADDR, PGD_TABLE_SIZE);
         pgd_pte = ULONG(machdep->pgd + PAGEOFFSET(page_dir));
 
 	if (verbose)
@@ -433,7 +445,7 @@ ppc_kvtop(struct task_context *tc, ulong kvaddr, physaddr_t *paddr, int verbose)
 		fprintf(fp, "  PMD: %lx => %lx\n", (ulong)page_middle, 
 			(ulong)page_table);
 
-        FILL_PTBL(PAGEBASE(page_table), KVADDR, PAGESIZE());
+        FILL_PTBL(PAGEBASE(page_table), KVADDR, PTE_TABLE_SIZE);
         pte = ULONG(machdep->ptbl + PAGEOFFSET(page_table));
 
 	if (verbose) 
-- 
1.7.8.163.g9859a


Date: Thu, 2 Feb 2012 09:53:19 +0900
Subject: [PATCH 3/4] ppc: don't use PAGEOFFSET() for address translation

Use pgd_index() or pte_index() because directory size is not equal to
to page size such like in PowerPC BookE platforms.

Signed-off-by: Toshikazu Nakayama <nakayama.ts@xxxxxxxxxxxxxx>
---
 ppc.c |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/ppc.c b/ppc.c
index f00092e..4f8087a 100755
--- a/ppc.c
+++ b/ppc.c
@@ -335,7 +335,7 @@ ppc_uvtop(struct task_context *tc, ulong vaddr, physaddr_t *paddr, int verbose)
 	page_dir = pgd + (vaddr >> PGDIR_SHIFT);
 
 	FILL_PGD(PAGEBASE(pgd), KVADDR, PGD_TABLE_SIZE);
-	pgd_pte = ULONG(machdep->pgd + PAGEOFFSET(page_dir));
+	pgd_pte = ULONG(machdep->pgd + pgd_index(vaddr));
 
 	if (verbose)
 		fprintf(fp, "  PGD: %lx => %lx\n", (ulong)page_dir, pgd_pte);
@@ -357,7 +357,7 @@ ppc_uvtop(struct task_context *tc, ulong vaddr, physaddr_t *paddr, int verbose)
 			(ulong)page_table);
 	
         FILL_PTBL(PAGEBASE(page_table), KVADDR, PTE_TABLE_SIZE);
-	pte = ULONG(machdep->ptbl + PAGEOFFSET(page_table));
+	pte = ULONG(machdep->ptbl + pte_index(vaddr));
 
         if (verbose) 
                 fprintf(fp, "  PTE: %lx => %lx\n", (ulong)page_table, pte);
@@ -424,7 +424,7 @@ ppc_kvtop(struct task_context *tc, ulong kvaddr, physaddr_t *paddr, int verbose)
 	page_dir = pgd + (kvaddr >> PGDIR_SHIFT);
 
         FILL_PGD(PAGEBASE(pgd), KVADDR, PGD_TABLE_SIZE);
-        pgd_pte = ULONG(machdep->pgd + PAGEOFFSET(page_dir));
+        pgd_pte = ULONG(machdep->pgd + pgd_index(kvaddr));
 
 	if (verbose)
 		fprintf(fp, "  PGD: %lx => %lx\n", (ulong)page_dir, pgd_pte);
@@ -446,7 +446,7 @@ ppc_kvtop(struct task_context *tc, ulong kvaddr, physaddr_t *paddr, int verbose)
 			(ulong)page_table);
 
         FILL_PTBL(PAGEBASE(page_table), KVADDR, PTE_TABLE_SIZE);
-        pte = ULONG(machdep->ptbl + PAGEOFFSET(page_table));
+        pte = ULONG(machdep->ptbl + pte_index(kvaddr));
 
 	if (verbose) 
 		fprintf(fp, "  PTE: %lx => %lx\n", (ulong)page_table, pte);
-- 
1.7.8.163.g9859a


Date: Thu, 2 Feb 2012 09:41:46 +0900
Subject: [PATCH 4/4] ppc: define BookE page table format

BookE provides 64bit physical address and translates virtual address
by extending PGD to 16KB table (two-level translation).
Thus PTRS_PER_PTE owns 512 indices, PTRS_PER_PGD owns 2048 indices,
and fill PGD with 16KB buffer to access whole virtual address space.

Signed-off-by: Toshikazu Nakayama <nakayama.ts@xxxxxxxxxxxxxx>
---
 defs.h |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/defs.h b/defs.h
index 68169b1..b6c7cd9 100755
--- a/defs.h
+++ b/defs.h
@@ -2614,6 +2614,12 @@ extern int PTE_TABLE_SIZE;
 #define PTRS_PER_PGD_DEFAULT	(1024)
 #define PGD_TABLE_SIZE_DEFAULT	(1 << 12)
 #define PTE_TABLE_SIZE_DEFAULT	(1 << 12)
+/* BookE page table format */
+#define PGDIR_SHIFT_PPC44X	(21)
+#define PTRS_PER_PTE_PPC44X	(512)
+#define PTRS_PER_PGD_PPC44X	(2048)
+#define PGD_TABLE_SIZE_PPC44X	(1 << 12)
+#define PTE_TABLE_SIZE_PPC44X	(1 << 14)
 
 #define _PAGE_PRESENT   0x001   /* software: pte contains a translation */
 #define _PAGE_USER      0x002   /* matches one of the PP bits */
-- 
1.7.8.163.g9859a


--
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