aboutsummaryrefslogtreecommitdiff
path: root/arch/x86/mm/extable.c
diff options
context:
space:
mode:
authorPeter Zijlstra2021-11-10 11:01:22 +0100
committerPeter Zijlstra2021-12-11 09:09:50 +0100
commitd5d797dcbd781cb7c526ad32f31c7fd96babfdb2 (patch)
treedd64239b122e8ab932f750b121d88bdacbff9120 /arch/x86/mm/extable.c
parent13e4bf1bddcb65dd028aaa492789e8d61efaafa1 (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.c9
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();
}