Skip to content

Commit 69a94e5

Browse files
Ravi Bangoriagregkh
authored andcommitted
powerpc/watchpoint: Fix quadword instruction handling on p10 predecessors
[ Upstream commit 4759c11 ] On p10 predecessors, watchpoint with quadword access is compared at quadword length. If the watch range is doubleword or less than that in a first half of quadword aligned 16 bytes, and if there is any unaligned quadword access which will access only the 2nd half, the handler should consider it as extraneous and emulate/single-step it before continuing. Fixes: 74c6881 ("powerpc/watchpoint: Prepare handler to handle more than one watchpoint") Reported-by: Pedro Miraglia Franco de Carvalho <pedromfc@linux.ibm.com> Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://lore.kernel.org/r/20200902042945.129369-2-ravi.bangoria@linux.ibm.com Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent 810d237 commit 69a94e5

File tree

2 files changed

+11
-2
lines changed

2 files changed

+11
-2
lines changed

arch/powerpc/include/asm/hw_breakpoint.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ struct arch_hw_breakpoint {
4242
#else
4343
#define HW_BREAKPOINT_SIZE 0x8
4444
#endif
45+
#define HW_BREAKPOINT_SIZE_QUADWORD 0x10
4546

4647
#define DABR_MAX_LEN 8
4748
#define DAWR_MAX_LEN 512

arch/powerpc/kernel/hw_breakpoint.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -520,9 +520,17 @@ static bool ea_hw_range_overlaps(unsigned long ea, int size,
520520
struct arch_hw_breakpoint *info)
521521
{
522522
unsigned long hw_start_addr, hw_end_addr;
523+
unsigned long align_size = HW_BREAKPOINT_SIZE;
523524

524-
hw_start_addr = ALIGN_DOWN(info->address, HW_BREAKPOINT_SIZE);
525-
hw_end_addr = ALIGN(info->address + info->len, HW_BREAKPOINT_SIZE);
525+
/*
526+
* On p10 predecessors, quadword is handle differently then
527+
* other instructions.
528+
*/
529+
if (!cpu_has_feature(CPU_FTR_ARCH_31) && size == 16)
530+
align_size = HW_BREAKPOINT_SIZE_QUADWORD;
531+
532+
hw_start_addr = ALIGN_DOWN(info->address, align_size);
533+
hw_end_addr = ALIGN(info->address + info->len, align_size);
526534

527535
return ((ea < hw_end_addr) && (ea + size > hw_start_addr));
528536
}

0 commit comments

Comments
 (0)