Blame SOURCES/github_8618ddd8_CONFIG_ARM64_USER_VA_BITS_52

608733
commit 8618ddd817621c40c1f44f0ab6df7c7805234416
608733
Author: Dave Anderson <anderson@redhat.com>
608733
Date:   Fri Feb 1 15:01:29 2019 -0500
608733
608733
    First phase of support for ARM64 kernels that are configured with
608733
    CONFIG_ARM64_USER_VA_BITS_52, which causes the PTRS_PER_PGD count
608733
    to increase from 64 to 1024.  Without the patch, "WARNING: cannot
608733
    access vmalloc'd module memory" will be displayed during session
608733
    initialization, and the translation of any mapped kernel virtual
608733
    address that requires a page table walk will fail, leading to a
608733
    myriad of other errors.
608733
    (anderson@redhat.com)
608733
608733
diff --git a/arm64.c b/arm64.c
608733
index 45c7313..2308612 100644
608733
--- a/arm64.c
608733
+++ b/arm64.c
608733
@@ -1,8 +1,8 @@
608733
 /*
608733
  * arm64.c - core analysis suite
608733
  *
608733
- * Copyright (C) 2012-2018 David Anderson
608733
- * Copyright (C) 2012-2018 Red Hat, Inc. All rights reserved.
608733
+ * Copyright (C) 2012-2019 David Anderson
608733
+ * Copyright (C) 2012-2019 Red Hat, Inc. All rights reserved.
608733
  *
608733
  * This program is free software; you can redistribute it and/or modify
608733
  * it under the terms of the GNU General Public License as published by
608733
@@ -209,6 +209,8 @@ arm64_init(int when)
608733
 		ms->page_offset = ARM64_PAGE_OFFSET;
608733
 		machdep->identity_map_base = ARM64_PAGE_OFFSET;
608733
 		machdep->kvbase = ARM64_VA_START;
608733
+		machdep->is_kvaddr = generic_is_kvaddr;
608733
+		machdep->kvtop = arm64_kvtop;
608733
 		ms->userspace_top = ARM64_USERSPACE_TOP;
608733
 		if (machdep->flags & NEW_VMEMMAP) {
608733
 			struct syment *sp;
608733
@@ -262,11 +264,17 @@ arm64_init(int when)
608733
 			break;
608733
 
608733
 		case 65536:
608733
+			if (kernel_symbol_exists("idmap_ptrs_per_pgd") &&
608733
+			    readmem(symbol_value("idmap_ptrs_per_pgd"), KVADDR,
608733
+			    &value, sizeof(ulong), "idmap_ptrs_per_pgd", RETURN_ON_ERROR))
608733
+				machdep->ptrs_per_pgd = value;
608733
+		
608733
 			if (machdep->machspec->VA_BITS > PGDIR_SHIFT_L3_64K) {
608733
 				machdep->flags |= VM_L3_64K;
608733
-				machdep->ptrs_per_pgd = PTRS_PER_PGD_L3_64K;
608733
+				if (!machdep->ptrs_per_pgd)
608733
+					machdep->ptrs_per_pgd = PTRS_PER_PGD_L3_64K;
608733
 				if ((machdep->pgd =
608733
-				    (char *)malloc(PTRS_PER_PGD_L3_64K * 8)) == NULL)
608733
+				    (char *)malloc(machdep->ptrs_per_pgd * 8)) == NULL)
608733
 					error(FATAL, "cannot malloc pgd space.");
608733
 				if ((machdep->pmd =
608733
 				    (char *)malloc(PTRS_PER_PMD_L3_64K * 8)) == NULL)
608733
@@ -276,9 +284,10 @@ arm64_init(int when)
608733
 					error(FATAL, "cannot malloc ptbl space.");
608733
 			} else {
608733
 				machdep->flags |= VM_L2_64K;
608733
-				machdep->ptrs_per_pgd = PTRS_PER_PGD_L2_64K;
608733
+				if (!machdep->ptrs_per_pgd)
608733
+					machdep->ptrs_per_pgd = PTRS_PER_PGD_L2_64K;
608733
 				if ((machdep->pgd =
608733
-				    (char *)malloc(PTRS_PER_PGD_L2_64K * 8)) == NULL)
608733
+				    (char *)malloc(machdep->ptrs_per_pgd * 8)) == NULL)
608733
 					error(FATAL, "cannot malloc pgd space.");
608733
 				if ((machdep->ptbl =
608733
 				    (char *)malloc(PTRS_PER_PTE_L2_64K * 8)) == NULL)
608733
@@ -306,9 +315,11 @@ arm64_init(int when)
608733
 		machdep->flags |= VMEMMAP;
608733
 
608733
 		machdep->uvtop = arm64_uvtop;
608733
-		machdep->kvtop = arm64_kvtop;
608733
-		machdep->is_kvaddr = generic_is_kvaddr;
608733
 		machdep->is_uvaddr = arm64_is_uvaddr;
608733
+		if (kernel_symbol_exists("vabits_user") && 
608733
+		    readmem(symbol_value("vabits_user"), KVADDR,
608733
+		    &value, sizeof(ulong), "vabits_user", RETURN_ON_ERROR))
608733
+			machdep->machspec->vabits_user = value;
608733
 		machdep->eframe_search = arm64_eframe_search;
608733
 		machdep->back_trace = arm64_back_trace_cmd;
608733
 		machdep->in_alternate_stack = arm64_in_alternate_stack;
608733
@@ -350,10 +361,14 @@ arm64_init(int when)
608733
 	case POST_GDB:
608733
 		arm64_calc_virtual_memory_ranges();
608733
 		machdep->section_size_bits = _SECTION_SIZE_BITS;
608733
-		if (THIS_KERNEL_VERSION >= LINUX(3,17,0))
608733
-			machdep->max_physmem_bits = _MAX_PHYSMEM_BITS_3_17;
608733
-		else
608733
-			machdep->max_physmem_bits = _MAX_PHYSMEM_BITS;
608733
+		if (!machdep->max_physmem_bits) {
608733
+			if (machdep->machspec->VA_BITS == 52)  /* guess */
608733
+				machdep->max_physmem_bits = _MAX_PHYSMEM_BITS_52;
608733
+			else if (THIS_KERNEL_VERSION >= LINUX(3,17,0)) 
608733
+				machdep->max_physmem_bits = _MAX_PHYSMEM_BITS_3_17;
608733
+			else
608733
+				machdep->max_physmem_bits = _MAX_PHYSMEM_BITS;
608733
+		}
608733
 		ms = machdep->machspec;
608733
 
608733
 		if (THIS_KERNEL_VERSION >= LINUX(4,0,0)) {
608733
@@ -601,6 +616,11 @@ arm64_dump_machdep_table(ulong arg)
608733
 
608733
 	fprintf(fp, "            machspec: %lx\n", (ulong)ms);
608733
 	fprintf(fp, "               VA_BITS: %ld\n", ms->VA_BITS);
608733
+	fprintf(fp, "           vabits_user: ");
608733
+	if (ms->vabits_user)
608733
+		fprintf(fp, "%ld\n", ms->vabits_user);
608733
+	else
608733
+		fprintf(fp, "(unused)\n");
608733
 	fprintf(fp, "         userspace_top: %016lx\n", ms->userspace_top);
608733
 	fprintf(fp, "           page_offset: %016lx\n", ms->page_offset);
608733
 	fprintf(fp, "    vmalloc_start_addr: %016lx\n", ms->vmalloc_start_addr);
608733
@@ -691,6 +711,8 @@ arm64_parse_machdep_arg_l(char *argstring, char *param, ulong *value)
608733
 			*value = dtol(p, flags, &err;;
608733
 			if (!err)
608733
 				*value = MEGABYTES(*value);
608733
+		} else if (STRNEQ(argstring, "max_physmem_bits")) {
608733
+			*value = dtol(p, flags, &err;;
608733
 		} else {
608733
 			*value = htol(p, flags, &err;;
608733
 		}
608733
@@ -750,6 +772,12 @@ arm64_parse_cmdline_args(void)
608733
 					"setting kimage_voffset to: 0x%lx\n\n",
608733
 					machdep->machspec->kimage_voffset);
608733
 				continue;
608733
+			} else if (arm64_parse_machdep_arg_l(arglist[i], "max_physmem_bits",
608733
+			        &machdep->max_physmem_bits)) {
608733
+				error(NOTE,
608733
+					"setting max_physmem_bits to: %ld\n\n",
608733
+					machdep->max_physmem_bits);
608733
+				continue;
608733
 			}
608733
 
608733
 			error(WARNING, "ignoring --machdep option: %s\n",
608733
@@ -1065,8 +1093,8 @@ arm64_vtop_2level_64k(ulong pgd, ulong vaddr, physaddr_t *paddr, int verbose)
608733
                 fprintf(fp, "PAGE DIRECTORY: %lx\n", pgd);
608733
 
608733
 	pgd_base = (ulong *)pgd;
608733
-	FILL_PGD(pgd_base, KVADDR, PTRS_PER_PGD_L2_64K * sizeof(ulong));
608733
-	pgd_ptr = pgd_base + (((vaddr) >> PGDIR_SHIFT_L2_64K) & (PTRS_PER_PGD_L2_64K - 1));
608733
+	FILL_PGD(pgd_base, KVADDR, machdep->ptrs_per_pgd * sizeof(ulong));
608733
+	pgd_ptr = pgd_base + (((vaddr) >> PGDIR_SHIFT_L2_64K) & (machdep->ptrs_per_pgd - 1));
608733
         pgd_val = ULONG(machdep->pgd + PAGEOFFSET(pgd_ptr));
608733
         if (verbose) 
608733
                 fprintf(fp, "   PGD: %lx => %lx\n", (ulong)pgd_ptr, pgd_val);
608733
@@ -1129,8 +1157,8 @@ arm64_vtop_3level_64k(ulong pgd, ulong vaddr, physaddr_t *paddr, int verbose)
608733
                 fprintf(fp, "PAGE DIRECTORY: %lx\n", pgd);
608733
 
608733
 	pgd_base = (ulong *)pgd;
608733
-	FILL_PGD(pgd_base, KVADDR, PTRS_PER_PGD_L3_64K * sizeof(ulong));
608733
-	pgd_ptr = pgd_base + (((vaddr) >> PGDIR_SHIFT_L3_64K) & (PTRS_PER_PGD_L3_64K - 1));
608733
+	FILL_PGD(pgd_base, KVADDR, machdep->ptrs_per_pgd * sizeof(ulong));
608733
+	pgd_ptr = pgd_base + (((vaddr) >> PGDIR_SHIFT_L3_64K) & (machdep->ptrs_per_pgd - 1));
608733
         pgd_val = ULONG(machdep->pgd + PGDIR_OFFSET_L3_64K(pgd_ptr));
608733
         if (verbose)
608733
                 fprintf(fp, "   PGD: %lx => %lx\n", (ulong)pgd_ptr, pgd_val);
608733
diff --git a/crash.8 b/crash.8
608733
index 8c11615..f9de36d 100644
608733
--- a/crash.8
608733
+++ b/crash.8
608733
@@ -278,6 +278,7 @@ ARM:
608733
 ARM64:  
608733
   phys_offset=<physical-address>
608733
   kimage_voffset=<kimage_voffset-value>
608733
+  max_physmem_bits=<value>
608733
 X86:
608733
   page_offset=<CONFIG_PAGE_OFFSET-value>
608733
 .fi
608733
diff --git a/defs.h b/defs.h
608733
index b473972..05f2d17 100644
608733
--- a/defs.h
608733
+++ b/defs.h
608733
@@ -3049,7 +3049,7 @@ typedef signed int s32;
608733
 #define PMD_SHIFT_L3_64K     (29)
608733
 #define PMD_SIZE_L3_64K      (1UL << PMD_SHIFT_L3_64K)
608733
 #define PMD_MASK_L3_64K      (~(PMD_SIZE_L3_64K-1))
608733
-#define PGDIR_OFFSET_L3_64K(X) (((ulong)(X)) & ((PTRS_PER_PGD_L3_64K * 8) - 1))
608733
+#define PGDIR_OFFSET_L3_64K(X) (((ulong)(X)) & ((machdep->ptrs_per_pgd * 8) - 1))
608733
 
608733
 /*
608733
  * 2-levels / 64K pages
608733
@@ -3136,6 +3136,7 @@ typedef signed int s32;
608733
 #define _SECTION_SIZE_BITS      30
608733
 #define _MAX_PHYSMEM_BITS       40
608733
 #define _MAX_PHYSMEM_BITS_3_17  48
608733
+#define _MAX_PHYSMEM_BITS_52    52
608733
 
608733
 typedef unsigned long long __u64;
608733
 typedef unsigned long long u64;
608733
@@ -3215,6 +3216,7 @@ struct machine_specific {
608733
 	ulong kern_eframe_offset;
608733
 	ulong machine_kexec_start;
608733
 	ulong machine_kexec_end;
608733
+	ulong vabits_user;
608733
 };
608733
 
608733
 struct arm64_stackframe {
608733
diff --git a/help.c b/help.c
608733
index ff0c80b..ba15dec 100644
608733
--- a/help.c
608733
+++ b/help.c
608733
@@ -179,6 +179,7 @@ char *program_usage_info[] = {
608733
     "    ARM64:",
608733
     "      phys_offset=<physical-address>",
608733
     "      kimage_voffset=<kimage_voffset-value>",
608733
+    "      max_physmem_bits=<value>",
608733
     "    X86:",
608733
     "      page_offset=<CONFIG_PAGE_OFFSET-value>",
608733
     "",