diff options
author | Nicholas Piggin <npiggin@gmail.com> | 2018-04-01 01:50:36 -0400 |
---|---|---|
committer | Michael Ellerman <mpe@ellerman.id.au> | 2018-04-03 07:50:08 -0400 |
commit | 252988cbf037f3d446eea222afb46cc134d32c71 (patch) | |
tree | 06ef89cd7dbc79de88ce5a27cc8ce05d751a7bda | |
parent | e303c08787c4cbe1ca07912817dff205ed802985 (diff) |
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>
-rw-r--r-- | arch/powerpc/kernel/process.c | 10 |
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) | |||
718 | { | 718 | { |
719 | thread->hw_brk.address = 0; | 719 | thread->hw_brk.address = 0; |
720 | thread->hw_brk.type = 0; | 720 | thread->hw_brk.type = 0; |
721 | set_breakpoint(&thread->hw_brk); | 721 | if (ppc_breakpoint_available()) |
722 | set_breakpoint(&thread->hw_brk); | ||
722 | } | 723 | } |
723 | #endif /* !CONFIG_HAVE_HW_BREAKPOINT */ | 724 | #endif /* !CONFIG_HAVE_HW_BREAKPOINT */ |
724 | #endif /* CONFIG_PPC_ADV_DEBUG_REGS */ | 725 | #endif /* CONFIG_PPC_ADV_DEBUG_REGS */ |
@@ -815,9 +816,14 @@ void __set_breakpoint(struct arch_hw_breakpoint *brk) | |||
815 | memcpy(this_cpu_ptr(¤t_brk), brk, sizeof(*brk)); | 816 | memcpy(this_cpu_ptr(¤t_brk), brk, sizeof(*brk)); |
816 | 817 | ||
817 | if (cpu_has_feature(CPU_FTR_DAWR)) | 818 | if (cpu_has_feature(CPU_FTR_DAWR)) |
819 | // Power8 or later | ||
818 | set_dawr(brk); | 820 | set_dawr(brk); |
819 | else | 821 | else if (!cpu_has_feature(CPU_FTR_ARCH_207S)) |
822 | // Power7 or earlier | ||
820 | set_dabr(brk); | 823 | set_dabr(brk); |
824 | else | ||
825 | // Shouldn't happen due to higher level checks | ||
826 | WARN_ON_ONCE(1); | ||
821 | } | 827 | } |
822 | 828 | ||
823 | void set_breakpoint(struct arch_hw_breakpoint *brk) | 829 | void set_breakpoint(struct arch_hw_breakpoint *brk) |