powerpc/watchpoint: Fix DAWR exception for CACHEOP

'ea' returned by analyse_instr() needs to be aligned down to cache
block size for CACHEOP instructions. analyse_instr() does not set
size for CACHEOP, thus size also needs to be calculated manually.

Fixes: 27985b2a64 ("powerpc/watchpoint: Don't ignore extraneous exceptions blindly")
Fixes: 74c6881019 ("powerpc/watchpoint: Prepare handler to handle more than one watchpoint")
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/20200723090813.303838-4-ravi.bangoria@linux.ibm.com
This commit is contained in:
Ravi Bangoria 2020-07-23 14:38:06 +05:30 committed by Michael Ellerman
parent f6780ce619
commit f3c832f135

View file

@ -538,7 +538,12 @@ static bool check_dawrx_constraints(struct pt_regs *regs, int type,
if (OP_IS_LOAD(type) && !(info->type & HW_BRK_TYPE_READ))
return false;
if (OP_IS_STORE(type) && !(info->type & HW_BRK_TYPE_WRITE))
/*
* The Cache Management instructions other than dcbz never
* cause a match. i.e. if type is CACHEOP, the instruction
* is dcbz, and dcbz is treated as Store.
*/
if ((OP_IS_STORE(type) || type == CACHEOP) && !(info->type & HW_BRK_TYPE_WRITE))
return false;
if (is_kernel_addr(regs->nip) && !(info->type & HW_BRK_TYPE_KERNEL))
@ -601,6 +606,15 @@ static bool check_constraints(struct pt_regs *regs, struct ppc_inst instr,
return false;
}
static int cache_op_size(void)
{
#ifdef __powerpc64__
return ppc64_caches.l1d.block_size;
#else
return L1_CACHE_BYTES;
#endif
}
static void get_instr_detail(struct pt_regs *regs, struct ppc_inst *instr,
int *type, int *size, unsigned long *ea)
{
@ -616,7 +630,12 @@ static void get_instr_detail(struct pt_regs *regs, struct ppc_inst *instr,
if (!(regs->msr & MSR_64BIT))
*ea &= 0xffffffffUL;
#endif
*size = GETSIZE(op.type);
if (*type == CACHEOP) {
*size = cache_op_size();
*ea &= ~(*size - 1);
}
}
static bool is_larx_stcx_instr(int type)