* [PATCH 1/4] ARM64: Refactor code to support multiple page level
2015-12-05 16:29 [PATCH 0/4] ARM64: 3 Level page support Pratyush Anand
@ 2015-12-05 16:30 ` Pratyush Anand
2015-12-05 16:30 ` [PATCH 2/4] arm64: Decide VA Bits on the basis of _stext symbol value Pratyush Anand
` (3 subsequent siblings)
4 siblings, 0 replies; 8+ messages in thread
From: Pratyush Anand @ 2015-12-05 16:30 UTC (permalink / raw)
To: ats-kumagai
Cc: Pratyush Anand, timur, asamson, kexec, rruigrok, sgoel, dyoung
This patch refactor existing code, so that multiple page level can be
supported. No functional change. Platform dependent values like page
table level, page shift and VA bits are still hard coded as 2, 16 and
42, to support 2 level 64K pages.
Signed-off-by: Pratyush Anand <panand@redhat.com>
---
arch/arm64.c | 44 +++++++++++++++++++++++++++++++++++++++++---
makedumpfile.h | 26 ++++----------------------
2 files changed, 45 insertions(+), 25 deletions(-)
diff --git a/arch/arm64.c b/arch/arm64.c
index 06daf646e35d..643c21f8feb1 100644
--- a/arch/arm64.c
+++ b/arch/arm64.c
@@ -23,7 +23,6 @@
#include "../makedumpfile.h"
#include "../print_info.h"
-#if CONFIG_ARM64_PGTABLE_LEVELS == 2
typedef struct {
unsigned long pgd;
} pgd_t;
@@ -45,8 +44,6 @@ typedef struct {
#define PUD_SHIFT PGDIR_SHIFT
#define PUD_SIZE (1UL << PUD_SHIFT)
-#endif
-
typedef struct {
unsigned long pte;
} pte_t;
@@ -96,6 +93,41 @@ typedef struct {
#define MODULES_END PAGE_OFFSET
#define MODULES_VADDR (MODULES_END - 0x4000000)
+static int pgtable_level;
+static int va_bits;
+static int page_shift;
+
+int
+get_pgtable_level_arm64(void)
+{
+ return pgtable_level;
+}
+
+int
+get_va_bits_arm64(void)
+{
+ return va_bits;
+}
+
+int
+get_page_shift_arm64(void)
+{
+ return page_shift;
+}
+
+static int calculate_plat_config(void)
+{
+ /*
+ * TODO: Keep it fixed for page level 2, size 64K and VA bits as
+ * 42, as of now. Will calculate them from symbol address values
+ * latter.
+ */
+ pgtable_level = 2;
+ va_bits = 42;
+ page_shift = 16;
+
+ return TRUE;
+}
static int
is_vtop_from_page_table_arm64(unsigned long vaddr)
@@ -114,6 +146,12 @@ get_phys_base_arm64(void)
unsigned long phys_base = ULONG_MAX;
unsigned long long phys_start;
int i;
+
+ if (!calculate_plat_config()) {
+ ERRMSG("Can't determine platform config values\n");
+ return FALSE;
+ }
+
/*
* We resolve phys_base from PT_LOAD segments. LMA contains physical
* address of the segment, and we use the lowest start as
diff --git a/makedumpfile.h b/makedumpfile.h
index e333ae8a37a2..abe6a9897095 100644
--- a/makedumpfile.h
+++ b/makedumpfile.h
@@ -503,28 +503,10 @@ do { \
#define PMASK (0x7ffffffffffff000UL)
#ifdef __aarch64__
-#define CONFIG_ARM64_PGTABLE_LEVELS 2
-#define CONFIG_ARM64_VA_BITS 42
-#define CONFIG_ARM64_64K_PAGES 1
-
-/* Currently we only suport following defines based on above
- * config definitions.
- * TODOs: We need to find a way to get above defines dynamically and
- * then to support following definitions based on that
- */
-
-#if CONFIG_ARM64_PGTABLE_LEVELS == 2
-#define ARM64_PGTABLE_LEVELS 2
-#endif
-
-#if CONFIG_ARM64_VA_BITS == 42
-#define VA_BITS 42
-#endif
-
-#ifdef CONFIG_ARM64_64K_PAGES
-#define PAGE_SHIFT 16
-#endif
-
+int get_va_bits_arm64(void);
+#define ARM64_PGTABLE_LEVELS get_pgtable_level_arm64()
+#define VA_BITS get_va_bits_arm64()
+#define PAGE_SHIFT get_page_shift_arm64()
#define KVBASE_MASK (0xffffffffffffffffUL << (VA_BITS - 1))
#define KVBASE (SYMBOL(_stext) & KVBASE_MASK)
#endif /* aarch64 */
--
2.5.0
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH 2/4] arm64: Decide VA Bits on the basis of _stext symbol value
2015-12-05 16:29 [PATCH 0/4] ARM64: 3 Level page support Pratyush Anand
2015-12-05 16:30 ` [PATCH 1/4] ARM64: Refactor code to support multiple page level Pratyush Anand
@ 2015-12-05 16:30 ` Pratyush Anand
2015-12-05 16:30 ` [PATCH 3/4] arm64: Fix KVBASE Pratyush Anand
` (2 subsequent siblings)
4 siblings, 0 replies; 8+ messages in thread
From: Pratyush Anand @ 2015-12-05 16:30 UTC (permalink / raw)
To: ats-kumagai
Cc: Pratyush Anand, timur, asamson, kexec, rruigrok, sgoel, dyoung
Currently we assume that there are only two possible configuration
supported by kernel.
1) Page Table Level:2, Page Size 64K and VA Bits 42
1) Page Table Level:3, Page Size 4K and VA Bits 39
Ideally, we should have some mechanism to decide these from kernel
symbols, but we have limited symbols in vmcore, and we can not do much.
So until some one comes with a better way, we use _stext symbol value
for VA bits determination.
We also assume that when VA Bits are 39, Page table level will be 3 and
Page size will be 4K, while when VA Bits are 42, Page table level will
be 2 an Page size will be 64K.
Signed-off-by: Pratyush Anand <panand@redhat.com>
---
arch/arm64.c | 34 +++++++++++++++++++++++++++-------
1 file changed, 27 insertions(+), 7 deletions(-)
diff --git a/arch/arm64.c b/arch/arm64.c
index 643c21f8feb1..4d50012529c3 100644
--- a/arch/arm64.c
+++ b/arch/arm64.c
@@ -115,16 +115,36 @@ get_page_shift_arm64(void)
return page_shift;
}
+#define PAGE_OFFSET_39 (0xffffffffffffffffUL << 39)
+#define PAGE_OFFSET_42 (0xffffffffffffffffUL << 42)
static int calculate_plat_config(void)
{
- /*
- * TODO: Keep it fixed for page level 2, size 64K and VA bits as
- * 42, as of now. Will calculate them from symbol address values
- * latter.
+ unsigned long long stext;
+
+ /* Currently we assume that there are only two possible
+ * configuration supported by kernel.
+ * 1) Page Table Level:2, Page Size 64K and VA Bits 42
+ * 1) Page Table Level:3, Page Size 4K and VA Bits 39
+ * Ideally, we should have some mechanism to decide these values
+ * from kernel symbols, but we have limited symbols in vmcore,
+ * and we can not do much. So until some one comes with a better
+ * way, we use following.
*/
- pgtable_level = 2;
- va_bits = 42;
- page_shift = 16;
+ stext = SYMBOL(_stext);
+
+ /* condition for minimum VA bits must be checked first and so on */
+ if ((stext & PAGE_OFFSET_39) == PAGE_OFFSET_39) {
+ pgtable_level = 3;
+ va_bits = 39;
+ page_shift = 12;
+ } else if ((stext & PAGE_OFFSET_42) == PAGE_OFFSET_42) {
+ pgtable_level = 2;
+ va_bits = 42;
+ page_shift = 16;
+ } else {
+ ERRMSG("Kernel Configuration not supported\n");
+ return FALSE;
+ }
return TRUE;
}
--
2.5.0
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH 3/4] arm64: Fix KVBASE
2015-12-05 16:29 [PATCH 0/4] ARM64: 3 Level page support Pratyush Anand
2015-12-05 16:30 ` [PATCH 1/4] ARM64: Refactor code to support multiple page level Pratyush Anand
2015-12-05 16:30 ` [PATCH 2/4] arm64: Decide VA Bits on the basis of _stext symbol value Pratyush Anand
@ 2015-12-05 16:30 ` Pratyush Anand
2015-12-05 16:34 ` Timur Tabi
2015-12-05 16:30 ` [PATCH 4/4] arm64: Fix for ARM64 3 level translation tables Pratyush Anand
2015-12-10 8:14 ` [PATCH 0/4] ARM64: 3 Level page support Atsushi Kumagai
4 siblings, 1 reply; 8+ messages in thread
From: Pratyush Anand @ 2015-12-05 16:30 UTC (permalink / raw)
To: ats-kumagai
Cc: Pratyush Anand, timur, asamson, kexec, rruigrok, sgoel, dyoung
KVBASE should be VMALLOC_START. So fix it.
Signed-off-by: Pratyush Anand <panand@redhat.com>
Reported-by: Sameer Goel <sgoel@codeaurora.org>
---
arch/arm64.c | 3 ++-
makedumpfile.h | 3 +--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/arm64.c b/arch/arm64.c
index 4d50012529c3..a94a4ba16dd5 100644
--- a/arch/arm64.c
+++ b/arch/arm64.c
@@ -199,7 +199,8 @@ get_machdep_info_arm64(void)
{
info->max_physmem_bits = PHYS_MASK_SHIFT;
info->section_size_bits = SECTIONS_SIZE_BITS;
- info->page_offset = KVBASE;
+ info->page_offset = SYMBOL(_stext)
+ & (0xffffffffffffffffUL << (VA_BITS - 1));
info->vmalloc_start = 0xffffffffffffffffUL << VA_BITS;
info->vmalloc_end = PAGE_OFFSET - PUD_SIZE - VMEMMAP_SIZE - 0x10000;
info->vmemmap_start = VMALLOC_END + 0x10000;
diff --git a/makedumpfile.h b/makedumpfile.h
index abe6a9897095..c42fc8142663 100644
--- a/makedumpfile.h
+++ b/makedumpfile.h
@@ -507,8 +507,7 @@ int get_va_bits_arm64(void);
#define ARM64_PGTABLE_LEVELS get_pgtable_level_arm64()
#define VA_BITS get_va_bits_arm64()
#define PAGE_SHIFT get_page_shift_arm64()
-#define KVBASE_MASK (0xffffffffffffffffUL << (VA_BITS - 1))
-#define KVBASE (SYMBOL(_stext) & KVBASE_MASK)
+#define KVBASE VMALLOC_START
#endif /* aarch64 */
#ifdef __arm__
--
2.5.0
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply related [flat|nested] 8+ messages in thread* Re: [PATCH 3/4] arm64: Fix KVBASE
2015-12-05 16:30 ` [PATCH 3/4] arm64: Fix KVBASE Pratyush Anand
@ 2015-12-05 16:34 ` Timur Tabi
2015-12-07 6:16 ` Pratyush Anand
0 siblings, 1 reply; 8+ messages in thread
From: Timur Tabi @ 2015-12-05 16:34 UTC (permalink / raw)
To: Pratyush Anand, ats-kumagai; +Cc: sgoel, dyoung, asamson, kexec, rruigrok
Pratyush Anand wrote:
> + & (0xffffffffffffffffUL << (VA_BITS - 1));
Shouldn't this be ULL instead of just UL?
--
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the
Code Aurora Forum, hosted by The Linux Foundation.
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 3/4] arm64: Fix KVBASE
2015-12-05 16:34 ` Timur Tabi
@ 2015-12-07 6:16 ` Pratyush Anand
0 siblings, 0 replies; 8+ messages in thread
From: Pratyush Anand @ 2015-12-07 6:16 UTC (permalink / raw)
To: Timur Tabi; +Cc: ats-kumagai, asamson, kexec, rruigrok, sgoel, dyoung
Hi Timur,
Thanks for your review.
On 05/12/2015:10:34:14 AM, Timur Tabi wrote:
> Pratyush Anand wrote:
> >+ & (0xffffffffffffffffUL << (VA_BITS - 1));
>
> Shouldn't this be ULL instead of just UL?
I think on 64 bit platform, unsigned long is always 64 bit (with gcc). More
over, info->page_offset is unsigned long. So, I think using UL would be in sync,
no?
~Pratyush
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 4/4] arm64: Fix for ARM64 3 level translation tables
2015-12-05 16:29 [PATCH 0/4] ARM64: 3 Level page support Pratyush Anand
` (2 preceding siblings ...)
2015-12-05 16:30 ` [PATCH 3/4] arm64: Fix KVBASE Pratyush Anand
@ 2015-12-05 16:30 ` Pratyush Anand
2015-12-10 8:14 ` [PATCH 0/4] ARM64: 3 Level page support Atsushi Kumagai
4 siblings, 0 replies; 8+ messages in thread
From: Pratyush Anand @ 2015-12-05 16:30 UTC (permalink / raw)
To: ats-kumagai
Cc: Pratyush Anand, timur, asamson, kexec, rruigrok, sgoel, dyoung
From: Sameer Goel <sgoel@codeaurora.org>
Add the implementation for PMD translation in case of 3 level page tables.
Assign the kernel page size based on the page structure read from the kernel
ELF file.
Signed-off-by: Sameer Goel <sgoel@codeaurora.org>
Signed-off-by: Pratyush Anand <panand@redhat.com>
---
arch/arm64.c | 36 ++++++++++++++++++++++++++++++------
1 file changed, 30 insertions(+), 6 deletions(-)
diff --git a/arch/arm64.c b/arch/arm64.c
index a94a4ba16dd5..ab20389fa673 100644
--- a/arch/arm64.c
+++ b/arch/arm64.c
@@ -36,7 +36,7 @@ typedef struct {
} pmd_t;
#define pud_offset(pgd, vaddr) ((pud_t *)pgd)
-#define pmd_offset(pud, vaddr) ((pmd_t *)pud)
+
#define pgd_val(x) ((x).pgd)
#define pud_val(x) (pgd_val((x).pgd))
#define pmd_val(x) (pud_val((x).pud))
@@ -68,6 +68,11 @@ typedef struct {
*/
#define PHYS_MASK_SHIFT 48
#define PHYS_MASK ((1UL << PHYS_MASK_SHIFT) - 1)
+/*
+ * Remove the highest order bits that are not a part of the
+ * physical address in a section
+ */
+#define PMD_SECTION_MASK ((1UL << 40) - 1)
#define PMD_TYPE_MASK 3
#define PMD_TYPE_SECT 1
@@ -83,10 +88,18 @@ typedef struct {
#define pmd_page_vaddr(pmd) (__va(pmd_val(pmd) & PHYS_MASK & (int32_t)PAGE_MASK))
#define pte_offset(dir, vaddr) ((pte_t*)pmd_page_vaddr((*dir)) + pte_index(vaddr))
+
+#define pmd_offset_pgtbl_lvl_2(pud, vaddr) ((pmd_t *)pud)
+
+#define pmd_index(vaddr) (((vaddr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1))
+#define pud_page_vaddr(pud) (__va(pud_val(pud) & PHYS_MASK & (int32_t)PAGE_MASK))
+#define pmd_offset_pgtbl_lvl_3(pud, vaddr) ((pmd_t *)pud_page_vaddr((*pud)) + pmd_index(vaddr))
+
/* kernel struct page size can be kernel version dependent, currently
* keep it constant.
*/
-#define KERN_STRUCT_PAGE_SIZE 64
+#define KERN_STRUCT_PAGE_SIZE get_structure_size("page", DWARF_INFO_GET_STRUCT_SIZE)
+
#define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
#define PFN_DOWN(x) ((x) >> PAGE_SHIFT)
#define VMEMMAP_SIZE ALIGN((1UL << (VA_BITS - PAGE_SHIFT)) * KERN_STRUCT_PAGE_SIZE, PUD_SIZE)
@@ -97,6 +110,15 @@ static int pgtable_level;
static int va_bits;
static int page_shift;
+pmd_t *
+pmd_offset(pud_t *pud, unsigned long vaddr)
+{
+ if (pgtable_level == 2) {
+ return pmd_offset_pgtbl_lvl_2(pud, vaddr);
+ } else {
+ return pmd_offset_pgtbl_lvl_3(pud, vaddr);
+ }
+}
int
get_pgtable_level_arm64(void)
{
@@ -256,7 +278,7 @@ vtop_arm64(unsigned long vaddr)
{
unsigned long long paddr = NOT_PADDR;
pgd_t *pgda, pgdv;
- pud_t *puda;
+ pud_t *puda, pudv;
pmd_t *pmda, pmdv;
pte_t *ptea, ptev;
@@ -271,8 +293,9 @@ vtop_arm64(unsigned long vaddr)
return NOT_PADDR;
}
- puda = pud_offset(pgda, vaddr);
- pmda = pmd_offset(puda, vaddr);
+ pudv.pgd = pgdv;
+
+ pmda = pmd_offset(&pudv, vaddr);
if (!readmem(VADDR, (unsigned long long)pmda, &pmdv, sizeof(pmdv))) {
ERRMSG("Can't read pmd\n");
return NOT_PADDR;
@@ -298,7 +321,8 @@ vtop_arm64(unsigned long vaddr)
break;
case PMD_TYPE_SECT:
/* 1GB section */
- paddr = (pmd_val(pmdv) & PMD_MASK) + (vaddr & (PMD_SIZE - 1));
+ paddr = (pmd_val(pmdv) & (PMD_MASK & PMD_SECTION_MASK))
+ + (vaddr & (PMD_SIZE - 1));
break;
}
--
2.5.0
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply related [flat|nested] 8+ messages in thread* RE: [PATCH 0/4] ARM64: 3 Level page support
2015-12-05 16:29 [PATCH 0/4] ARM64: 3 Level page support Pratyush Anand
` (3 preceding siblings ...)
2015-12-05 16:30 ` [PATCH 4/4] arm64: Fix for ARM64 3 level translation tables Pratyush Anand
@ 2015-12-10 8:14 ` Atsushi Kumagai
4 siblings, 0 replies; 8+ messages in thread
From: Atsushi Kumagai @ 2015-12-10 8:14 UTC (permalink / raw)
To: Pratyush Anand
Cc: timur@codeaurora.org, asamson@codeaurora.org,
kexec@lists.infradead.org, rruigrok@codeaurora.org,
sgoel@codeaurora.org, dyoung@redhat.com
Hello Pratyush,
>Hi Atsushi,
>
>ARM64 was supporting only two level page support. These patches add support
>for 3 level page table as well.
>
>~Pratyush
Thanks for your work, I'll merge these patches into v1.6.0.
Regards,
Atsushi Kumagai
>Pratyush Anand (3):
> ARM64: Refactor code to support multiple page level
> arm64: Decide VA Bits on the basis of _stext symbol value
> arm64: Fix KVBASE
>
>Sameer Goel (1):
> arm64: Fix for ARM64 3 level translation tables
>
> arch/arm64.c | 103 +++++++++++++++++++++++++++++++++++++++++++++++++++------
> makedumpfile.h | 29 +++-------------
> 2 files changed, 98 insertions(+), 34 deletions(-)
>
>--
>2.5.0
>
>
>_______________________________________________
>kexec mailing list
>kexec@lists.infradead.org
>http://lists.infradead.org/mailman/listinfo/kexec
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply [flat|nested] 8+ messages in thread