Message ID | 20220123090417.630-1-jszhang@kernel.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | riscv: extable: fix err reg writing in dedicated uaccess handler | expand |
On Sun, 23 Jan 2022 01:04:17 PST (-0800), jszhang@kernel.org wrote: > Mayuresh reported commit 20802d8d477d ("riscv: extable: add a dedicated > uaccess handler") breaks the writev02 test case in LTP. This is due to > the err reg isn't correctly set with the errno(-EFAULT in writev02 > case). First of all, the err and zero regs are reg numbers rather than > reg offsets in struct pt_regs; Secondly, regs_set_gpr() should write > the regs when offset isn't zero(zero means epc) > > Fix it by correcting regs_set_gpr() logic and passing the correct reg > offset to it. > > Reported-by: Mayuresh Chitale <mchitale@ventanamicro.com> > Fixes: 20802d8d477d ("riscv: extable: add a dedicated uaccess handler") > Signed-off-by: Jisheng Zhang <jszhang@kernel.org> > --- > arch/riscv/mm/extable.c | 6 +++--- > 1 file changed, 3 insertions(+), 3 deletions(-) > > diff --git a/arch/riscv/mm/extable.c b/arch/riscv/mm/extable.c > index 05978f78579f..35484d830fd6 100644 > --- a/arch/riscv/mm/extable.c > +++ b/arch/riscv/mm/extable.c > @@ -33,7 +33,7 @@ static inline void regs_set_gpr(struct pt_regs *regs, unsigned int offset, > if (unlikely(offset > MAX_REG_OFFSET)) > return; > > - if (!offset) > + if (offset) > *(unsigned long *)((unsigned long)regs + offset) = val; > } > > @@ -43,8 +43,8 @@ static bool ex_handler_uaccess_err_zero(const struct exception_table_entry *ex, > int reg_err = FIELD_GET(EX_DATA_REG_ERR, ex->data); > int reg_zero = FIELD_GET(EX_DATA_REG_ZERO, ex->data); > > - regs_set_gpr(regs, reg_err, -EFAULT); > - regs_set_gpr(regs, reg_zero, 0); > + regs_set_gpr(regs, reg_err * sizeof(unsigned long), -EFAULT); > + regs_set_gpr(regs, reg_zero * sizeof(unsigned long), 0); > > regs->epc = get_ex_fixup(ex); > return true; Thanks, this is on fixes. I'm not sure if it's saner to have these be register numbers rather than offsets, but regs_get_register is this way so it's probably better to have them match.
diff --git a/arch/riscv/mm/extable.c b/arch/riscv/mm/extable.c index 05978f78579f..35484d830fd6 100644 --- a/arch/riscv/mm/extable.c +++ b/arch/riscv/mm/extable.c @@ -33,7 +33,7 @@ static inline void regs_set_gpr(struct pt_regs *regs, unsigned int offset, if (unlikely(offset > MAX_REG_OFFSET)) return; - if (!offset) + if (offset) *(unsigned long *)((unsigned long)regs + offset) = val; } @@ -43,8 +43,8 @@ static bool ex_handler_uaccess_err_zero(const struct exception_table_entry *ex, int reg_err = FIELD_GET(EX_DATA_REG_ERR, ex->data); int reg_zero = FIELD_GET(EX_DATA_REG_ZERO, ex->data); - regs_set_gpr(regs, reg_err, -EFAULT); - regs_set_gpr(regs, reg_zero, 0); + regs_set_gpr(regs, reg_err * sizeof(unsigned long), -EFAULT); + regs_set_gpr(regs, reg_zero * sizeof(unsigned long), 0); regs->epc = get_ex_fixup(ex); return true;
Mayuresh reported commit 20802d8d477d ("riscv: extable: add a dedicated uaccess handler") breaks the writev02 test case in LTP. This is due to the err reg isn't correctly set with the errno(-EFAULT in writev02 case). First of all, the err and zero regs are reg numbers rather than reg offsets in struct pt_regs; Secondly, regs_set_gpr() should write the regs when offset isn't zero(zero means epc) Fix it by correcting regs_set_gpr() logic and passing the correct reg offset to it. Reported-by: Mayuresh Chitale <mchitale@ventanamicro.com> Fixes: 20802d8d477d ("riscv: extable: add a dedicated uaccess handler") Signed-off-by: Jisheng Zhang <jszhang@kernel.org> --- arch/riscv/mm/extable.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)