summaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
authorNicholas Piggin2018-04-01 07:50:36 +0200
committerMichael Ellerman2018-04-03 13:50:08 +0200
commit252988cbf037f3d446eea222afb46cc134d32c71 (patch)
tree06ef89cd7dbc79de88ce5a27cc8ce05d751a7bda /arch/powerpc
parentKVM: PPC: Book3S HV: Fix ppc_breakpoint_available compile error (diff)
downloadkernel-qcow2-linux-252988cbf037f3d446eea222afb46cc134d32c71.tar.gz
kernel-qcow2-linux-252988cbf037f3d446eea222afb46cc134d32c71.tar.xz
kernel-qcow2-linux-252988cbf037f3d446eea222afb46cc134d32c71.zip
powerpc: Don't write to DABR on >= Power8 if DAWR is disabled
flush_thread() calls __set_breakpoint() via set_debug_reg_defaults() without checking ppc_breakpoint_available(). On Power8 or later CPUs which have the DAWR feature disabled that will cause a write to the DABR which is incorrect as those CPUs don't have a DABR. Fix it two ways, by checking ppc_breakpoint_available() in set_debug_reg_defaults(), and also by reworking __set_breakpoint() to only write to DABR on Power7 or earlier. Fixes: 9654153158d3 ("powerpc: Disable DAWR in the base POWER9 CPU features") Signed-off-by: Nicholas Piggin <npiggin@gmail.com> [mpe: Rework the logic in __set_breakpoint()] Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/kernel/process.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 24a591b4dbe9..1237f13fed51 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -718,7 +718,8 @@ static void set_debug_reg_defaults(struct thread_struct *thread)
{
thread->hw_brk.address = 0;
thread->hw_brk.type = 0;
- set_breakpoint(&thread->hw_brk);
+ if (ppc_breakpoint_available())
+ set_breakpoint(&thread->hw_brk);
}
#endif /* !CONFIG_HAVE_HW_BREAKPOINT */
#endif /* CONFIG_PPC_ADV_DEBUG_REGS */
@@ -815,9 +816,14 @@ void __set_breakpoint(struct arch_hw_breakpoint *brk)
memcpy(this_cpu_ptr(&current_brk), brk, sizeof(*brk));
if (cpu_has_feature(CPU_FTR_DAWR))
+ // Power8 or later
set_dawr(brk);
- else
+ else if (!cpu_has_feature(CPU_FTR_ARCH_207S))
+ // Power7 or earlier
set_dabr(brk);
+ else
+ // Shouldn't happen due to higher level checks
+ WARN_ON_ONCE(1);
}
void set_breakpoint(struct arch_hw_breakpoint *brk)