474a44
commit da49e2010b3cb88b4755d69d38fe90af6ba218b2
474a44
Author: Dave Anderson <anderson@redhat.com>
474a44
Date:   Fri Jun 1 10:58:00 2018 -0400
474a44
474a44
    Update for the recognition of the new x86_64 CPU_ENTRY_AREA virtual
474a44
    address range introduced in Linux 4.15.  The memory range exists
474a44
    above the vmemmap range and below the mapped kernel static text/data
474a44
    region, and where all of the x86_64 exception stacks have been moved.
474a44
    Without the patch, reads from the new memory region fail because the
474a44
    address range is not recognized as a legitimate virtual address.
474a44
    Most notable is the failure of "bt" on tasks whose backtraces
474a44
    originate from any of the exception stacks, which fail with the two
474a44
    error messages "bt: seek error: kernel virtual address: <address>
474a44
    type: stack contents" followed by "bt: read of stack at <address>
474a44
    failed".
474a44
    (anderson@redhat.com)
474a44
474a44
diff --git a/defs.h b/defs.h
474a44
index 931be07..6e6f6be 100644
474a44
--- a/defs.h
474a44
+++ b/defs.h
474a44
@@ -3391,6 +3391,9 @@ struct arm64_stackframe {
474a44
 #define VSYSCALL_START             0xffffffffff600000
474a44
 #define VSYSCALL_END               0xffffffffff601000
474a44
 
474a44
+#define CPU_ENTRY_AREA_START       0xfffffe0000000000
474a44
+#define CPU_ENTRY_AREA_END         0xfffffe7fffffffff
474a44
+
474a44
 #define PTOV(X)               ((unsigned long)(X)+(machdep->kvbase))
474a44
 #define VTOP(X)               x86_64_VTOP((ulong)(X))
474a44
 #define IS_VMALLOC_ADDR(X)    x86_64_IS_VMALLOC_ADDR((ulong)(X))
474a44
@@ -5829,6 +5832,8 @@ struct machine_specific {
474a44
 	ulong kpti_entry_stack;
474a44
 	ulong kpti_entry_stack_size;
474a44
 	ulong ptrs_per_pgd;
474a44
+	ulong cpu_entry_area_start;
474a44
+	ulong cpu_entry_area_end;
474a44
 };
474a44
 
474a44
 #define KSYMS_START    (0x1)
474a44
diff --git a/x86_64.c b/x86_64.c
474a44
index 1d5e155..54b6539 100644
474a44
--- a/x86_64.c
474a44
+++ b/x86_64.c
474a44
@@ -407,6 +407,11 @@ x86_64_init(int when)
474a44
 				machdep->machspec->modules_end = MODULES_END_2_6_31;
474a44
 			}
474a44
 		}
474a44
+		if (STRUCT_EXISTS("cpu_entry_area")) {
474a44
+			machdep->machspec->cpu_entry_area_start = CPU_ENTRY_AREA_START;	
474a44
+			machdep->machspec->cpu_entry_area_end = CPU_ENTRY_AREA_END;	
474a44
+		}
474a44
+
474a44
                 STRUCT_SIZE_INIT(cpuinfo_x86, "cpuinfo_x86");
474a44
 		/* 
474a44
 		 * Before 2.6.25 the structure was called gate_struct
474a44
@@ -879,20 +884,21 @@ x86_64_dump_machdep_table(ulong arg)
474a44
 
474a44
 	/* pml4 and upml is legacy for extension modules */
474a44
 	if (ms->pml4) {
474a44
-		fprintf(fp, "			  pml4: %lx\n", (ulong)ms->pml4);
474a44
-		fprintf(fp, "		last_pml4_read: %lx\n", (ulong)ms->last_pml4_read);
474a44
+		fprintf(fp, "                     pml4: %lx\n", (ulong)ms->pml4);
474a44
+		fprintf(fp, "           last_pml4_read: %lx\n", (ulong)ms->last_pml4_read);
474a44
 
474a44
 	} else {
474a44
-		fprintf(fp, "		      pml4: (unused)\n");
474a44
-		fprintf(fp, "	    last_pml4_read: (unused)\n");
474a44
+		fprintf(fp, "                     pml4: (unused)\n");
474a44
+		fprintf(fp, "           last_pml4_read: (unused)\n");
474a44
 	}
474a44
 
474a44
 	if (ms->upml) {
474a44
-		fprintf(fp, "		      upml: %lx\n", (ulong)ms->upml);
474a44
-		fprintf(fp, "	    last_upml_read: %lx\n", (ulong)ms->last_upml_read);
474a44
+		fprintf(fp, "                     upml: %lx\n", (ulong)ms->upml);
474a44
+		fprintf(fp, "           last_upml_read: %lx\n", (ulong)ms->last_upml_read);
474a44
 	} else {
474a44
-		fprintf(fp, "		      upml: (unused)\n");
474a44
-		fprintf(fp, "	    last_upml_read: (unused)\n");
474a44
+		fprintf(fp, "                 GART_end: %lx\n", ms->GART_end);
474a44
+		fprintf(fp, "                     upml: (unused)\n");
474a44
+		fprintf(fp, "           last_upml_read: (unused)\n");
474a44
 	}
474a44
 
474a44
 	if (ms->p4d) {
474a44
@@ -1016,10 +1022,14 @@ x86_64_dump_machdep_table(ulong arg)
474a44
 			fprintf(fp, "\n   ");
474a44
 		fprintf(fp, "%016lx ", ms->stkinfo.ibase[c]);
474a44
 	}
474a44
-	fprintf(fp, "\n                 kpti_entry_stack_size: %ld", ms->kpti_entry_stack_size);
474a44
-	fprintf(fp, "\n                      kpti_entry_stack: ");
474a44
+	fprintf(fp, "\n    kpti_entry_stack_size: ");
474a44
+	if (ms->kpti_entry_stack_size)
474a44
+		fprintf(fp, "%ld", ms->kpti_entry_stack_size);
474a44
+	else
474a44
+		fprintf(fp, "(unused)");
474a44
+	fprintf(fp, "\n         kpti_entry_stack: ");
474a44
 	if (machdep->flags & KPTI) {
474a44
-		fprintf(fp, "%lx\n   ", ms->kpti_entry_stack);
474a44
+		fprintf(fp, "(percpu: %lx):\n   ", ms->kpti_entry_stack);
474a44
 		for (c = 0; c < cpus; c++) {
474a44
 			if (c && !(c%4))
474a44
 				fprintf(fp, "\n   ");
474a44
@@ -1028,6 +1038,16 @@ x86_64_dump_machdep_table(ulong arg)
474a44
 		fprintf(fp, "\n");
474a44
 	} else
474a44
 		fprintf(fp, "(unused)\n");
474a44
+	fprintf(fp, "     cpu_entry_area_start: ");
474a44
+	if (ms->cpu_entry_area_start)
474a44
+		fprintf(fp, "%016lx\n", (ulong)ms->cpu_entry_area_start);
474a44
+	else
474a44
+		fprintf(fp, "(unused)\n");
474a44
+	fprintf(fp, "       cpu_entry_area_end: ");
474a44
+	if (ms->cpu_entry_area_end)
474a44
+		fprintf(fp, "%016lx\n", (ulong)ms->cpu_entry_area_end);
474a44
+	else
474a44
+		fprintf(fp, "(unused)\n");
474a44
 }
474a44
 
474a44
 /*
474a44
@@ -1586,7 +1606,10 @@ x86_64_IS_VMALLOC_ADDR(ulong vaddr)
474a44
                 ((machdep->flags & VMEMMAP) && 
474a44
 		 (vaddr >= VMEMMAP_VADDR && vaddr <= VMEMMAP_END)) ||
474a44
                 (vaddr >= MODULES_VADDR && vaddr <= MODULES_END) ||
474a44
-		(vaddr >= VSYSCALL_START && vaddr < VSYSCALL_END));
474a44
+		(vaddr >= VSYSCALL_START && vaddr < VSYSCALL_END) ||
474a44
+		(machdep->machspec->cpu_entry_area_start && 
474a44
+		 vaddr >= machdep->machspec->cpu_entry_area_start &&
474a44
+		 vaddr <= machdep->machspec->cpu_entry_area_end));
474a44
 }
474a44
 
474a44
 static int