diff options
author | Peter Zijlstra | 2021-11-10 11:01:22 +0100 |
---|---|---|
committer | Peter Zijlstra | 2021-12-11 09:09:50 +0100 |
commit | d5d797dcbd781cb7c526ad32f31c7fd96babfdb2 (patch) | |
tree | dd64239b122e8ab932f750b121d88bdacbff9120 /arch/x86/mm/extable.c | |
parent | 13e4bf1bddcb65dd028aaa492789e8d61efaafa1 (diff) |
x86/usercopy: Remove .fixup usage
Typically usercopy does whole word copies followed by a number of byte
copies to finish the tail. This means that on exception it needs to
compute the remaining length as: words*sizeof(long) + bytes.
Create a new extable handler to do just this.
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Josh Poimboeuf <jpoimboe@redhat.com>
Link: https://lore.kernel.org/r/20211110101326.081701085@infradead.org
Diffstat (limited to 'arch/x86/mm/extable.c')
-rw-r--r-- | arch/x86/mm/extable.c | 9 |
1 files changed, 9 insertions, 0 deletions
diff --git a/arch/x86/mm/extable.c b/arch/x86/mm/extable.c index c869f43e8a2e..41eaa648349e 100644 --- a/arch/x86/mm/extable.c +++ b/arch/x86/mm/extable.c @@ -145,6 +145,13 @@ static bool ex_handler_imm_reg(const struct exception_table_entry *fixup, return ex_handler_default(fixup, regs); } +static bool ex_handler_ucopy_len(const struct exception_table_entry *fixup, + struct pt_regs *regs, int trapnr, int reg, int imm) +{ + regs->cx = imm * regs->cx + *pt_regs_nr(regs, reg); + return ex_handler_uaccess(fixup, regs, trapnr); +} + int ex_get_fixup_type(unsigned long ip) { const struct exception_table_entry *e = search_exception_tables(ip); @@ -217,6 +224,8 @@ int fixup_exception(struct pt_regs *regs, int trapnr, unsigned long error_code, return ex_handler_imm_reg(e, regs, reg, imm); case EX_TYPE_FAULT_SGX: return ex_handler_sgx(e, regs, trapnr); + case EX_TYPE_UCOPY_LEN: + return ex_handler_ucopy_len(e, regs, trapnr, reg, imm); } BUG(); } |