Skip to content

Commit a3961f8

Browse files
maheshsalmpe
authored andcommitted
powerpc/powernv: Fix kexec crashes caused by tlbie tracing
Rebooting into a new kernel with kexec fails in trace_tlbie() which is called from native_hpte_clear(). This happens if the running kernel has CONFIG_LOCKDEP enabled. With lockdep enabled, the tracepoints always execute few RCU checks regardless of whether tracing is on or off. We are already in the last phase of kexec sequence in real mode with HILE_BE set. At this point the RCU check ends up in RCU_LOCKDEP_WARN and causes kexec to fail. Fix this by not calling trace_tlbie() from native_hpte_clear(). mpe: It's not safe to call trace points at this point in the kexec path, even if we could avoid the RCU checks/warnings. The only solution is to not call them. Fixes: 0428491 ("powerpc/mm: Trace tlbie(l) instructions") Cc: stable@vger.kernel.org # v4.13+ Signed-off-by: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com> Reported-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> Suggested-by: Michael Ellerman <mpe@ellerman.id.au> Acked-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
1 parent 12841f8 commit a3961f8

File tree

1 file changed

+12
-3
lines changed

1 file changed

+12
-3
lines changed

arch/powerpc/mm/hash_native_64.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@
4747

4848
DEFINE_RAW_SPINLOCK(native_tlbie_lock);
4949

50-
static inline void __tlbie(unsigned long vpn, int psize, int apsize, int ssize)
50+
static inline unsigned long ___tlbie(unsigned long vpn, int psize,
51+
int apsize, int ssize)
5152
{
5253
unsigned long va;
5354
unsigned int penc;
@@ -100,7 +101,15 @@ static inline void __tlbie(unsigned long vpn, int psize, int apsize, int ssize)
100101
: "memory");
101102
break;
102103
}
103-
trace_tlbie(0, 0, va, 0, 0, 0, 0);
104+
return va;
105+
}
106+
107+
static inline void __tlbie(unsigned long vpn, int psize, int apsize, int ssize)
108+
{
109+
unsigned long rb;
110+
111+
rb = ___tlbie(vpn, psize, apsize, ssize);
112+
trace_tlbie(0, 0, rb, 0, 0, 0, 0);
104113
}
105114

106115
static inline void __tlbiel(unsigned long vpn, int psize, int apsize, int ssize)
@@ -652,7 +661,7 @@ static void native_hpte_clear(void)
652661
if (hpte_v & HPTE_V_VALID) {
653662
hpte_decode(hptep, slot, &psize, &apsize, &ssize, &vpn);
654663
hptep->v = 0;
655-
__tlbie(vpn, psize, apsize, ssize);
664+
___tlbie(vpn, psize, apsize, ssize);
656665
}
657666
}
658667

0 commit comments

Comments
 (0)