File 0015-x86_64-Fix-check-for-__per_cpu_offset-initialization.patch of Package crash.28010

From 44e5801d9016987b6b4ebd571bfde8ae3e75da7b Mon Sep 17 00:00:00 2001
From: Philipp Rudo <prudo@redhat.com>
Date: Thu, 5 Aug 2021 15:19:37 +0200
Subject: [PATCH] x86_64: Fix check for __per_cpu_offset initialization

Since at least kernel v2.6.30 the __per_cpu_offset gets initialized to
__per_cpu_load.  So first check if the __per_cpu_offset was set to a
proper value before reading any per cpu variable to prevent potential
bugs.

[ kh: added check for the existence of __per_cpu_load ]

Signed-off-by: Philipp Rudo <prudo@redhat.com>
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
---
 x86_64.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/x86_64.c b/x86_64.c
index 6eb7d67..87cbeae 100644
--- a/x86_64.c
+++ b/x86_64.c
@@ -1285,6 +1285,7 @@ x86_64_per_cpu_init(void)
 	struct machine_specific *ms;
 	struct syment *irq_sp, *curr_sp, *cpu_sp, *hardirq_stack_ptr_sp;
 	ulong hardirq_stack_ptr;
+	ulong __per_cpu_load = 0;
 
 	ms = machdep->machspec;
 
@@ -1326,7 +1327,12 @@ x86_64_per_cpu_init(void)
 	else if (!ms->stkinfo.isize)
 		ms->stkinfo.isize = 16384;
 
+	if (kernel_symbol_exists("__per_cpu_load"))
+		__per_cpu_load = symbol_value("__per_cpu_load");
+
 	for (i = cpus = 0; i < NR_CPUS; i++) {
+		if (__per_cpu_load && kt->__per_cpu_offset[i] == __per_cpu_load)
+			break;
 		if (!readmem(cpu_sp->value + kt->__per_cpu_offset[i],
 		    KVADDR, &cpunumber, sizeof(int),
 		    "cpu number (per_cpu)", QUIET|RETURN_ON_ERROR))
@@ -5595,14 +5601,18 @@ x86_64_get_smp_cpus(void)
 	char *cpu_pda_buf;
 	ulong level4_pgt, cpu_pda_addr;
 	struct syment *sp;
+	ulong __per_cpu_load = 0;
 
 	if (!VALID_STRUCT(x8664_pda)) {
 		if (!(sp = per_cpu_symbol_search("per_cpu__cpu_number")) ||
 		    !(kt->flags & PER_CPU_OFF))
 			return 1;
 
+		if (kernel_symbol_exists("__per_cpu_load"))
+			__per_cpu_load = symbol_value("__per_cpu_load");
+
 		for (i = cpus = 0; i < NR_CPUS; i++) {
-			if (kt->__per_cpu_offset[i] == 0)
+			if (__per_cpu_load && kt->__per_cpu_offset[i] == __per_cpu_load)
 				break;
 			if (!readmem(sp->value + kt->__per_cpu_offset[i], 
 			    KVADDR, &cpunumber, sizeof(int),
-- 
2.33.1

openSUSE Build Service is sponsored by