Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

powerpc: Fix oops due to bad access of lppaca on bare metal

Commit 8e0b634b1327 ("powerpc/64s: Do not allocate lppaca if we are
not virtualized") removed allocation of lppaca on bare metal
platforms. But with CONFIG_PPC_SPLPAR enabled, we still access the
lppaca on bare metal in some code paths.

Fix this but adding runtime checks for SPLPAR (shared processor LPAR).

Fixes: 8e0b634b1327 ("powerpc/64s: Do not allocate lppaca if we are not virtualized")
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>

authored by

Aneesh Kumar K.V and committed by
Michael Ellerman
a6201da3 19e68b2a

+8
+3
arch/powerpc/include/asm/lppaca.h
··· 34 34 #include <linux/threads.h> 35 35 #include <asm/types.h> 36 36 #include <asm/mmu.h> 37 + #include <asm/firmware.h> 37 38 38 39 /* 39 40 * The lppaca is the "virtual processor area" registered with the hypervisor, ··· 115 114 116 115 static inline bool lppaca_shared_proc(struct lppaca *l) 117 116 { 117 + if (!firmware_has_feature(FW_FEATURE_SPLPAR)) 118 + return false; 118 119 return !!(l->__old_status & LPPACA_OLD_SHARED_PROC); 119 120 } 120 121
+2
arch/powerpc/include/asm/spinlock.h
··· 56 56 #define vcpu_is_preempted vcpu_is_preempted 57 57 static inline bool vcpu_is_preempted(int cpu) 58 58 { 59 + if (!firmware_has_feature(FW_FEATURE_SPLPAR)) 60 + return false; 59 61 return !!(be32_to_cpu(lppaca_of(cpu).yield_count) & 1); 60 62 } 61 63 #endif
+3
arch/powerpc/kernel/time.c
··· 266 266 267 267 static inline u64 calculate_stolen_time(u64 stop_tb) 268 268 { 269 + if (!firmware_has_feature(FW_FEATURE_SPLPAR)) 270 + return 0; 271 + 269 272 if (get_paca()->dtl_ridx != be64_to_cpu(get_lppaca()->dtl_idx)) 270 273 return scan_dispatch_log(stop_tb); 271 274