]>
Commit | Line | Data |
---|---|---|
c08aef14 GKH |
1 | From 8a8158c85e1e774a44fbe81106fa41138580dfd1 Mon Sep 17 00:00:00 2001 |
2 | From: Matt Redfearn <matt.redfearn@mips.com> | |
3 | Date: Thu, 29 Mar 2018 10:28:23 +0100 | |
4 | Subject: MIPS: memset.S: EVA & fault support for small_memset | |
5 | ||
6 | From: Matt Redfearn <matt.redfearn@mips.com> | |
7 | ||
8 | commit 8a8158c85e1e774a44fbe81106fa41138580dfd1 upstream. | |
9 | ||
10 | The MIPS kernel memset / bzero implementation includes a small_memset | |
11 | branch which is used when the region to be set is smaller than a long (4 | |
12 | bytes on 32bit, 8 bytes on 64bit). The current small_memset | |
13 | implementation uses a simple store byte loop to write the destination. | |
14 | There are 2 issues with this implementation: | |
15 | ||
16 | 1. When EVA mode is active, user and kernel address spaces may overlap. | |
17 | Currently the use of the sb instruction means kernel mode addressing is | |
18 | always used and an intended write to userspace may actually overwrite | |
19 | some critical kernel data. | |
20 | ||
21 | 2. If the write triggers a page fault, for example by calling | |
22 | __clear_user(NULL, 2), instead of gracefully handling the fault, an OOPS | |
23 | is triggered. | |
24 | ||
25 | Fix these issues by replacing the sb instruction with the EX() macro, | |
26 | which will emit EVA compatible instuctions as required. Additionally | |
27 | implement a fault fixup for small_memset which sets a2 to the number of | |
28 | bytes that could not be cleared (as defined by __clear_user). | |
29 | ||
30 | Reported-by: Chuanhua Lei <chuanhua.lei@intel.com> | |
31 | Signed-off-by: Matt Redfearn <matt.redfearn@mips.com> | |
32 | Cc: Ralf Baechle <ralf@linux-mips.org> | |
33 | Cc: linux-mips@linux-mips.org | |
34 | Cc: stable@vger.kernel.org | |
35 | Patchwork: https://patchwork.linux-mips.org/patch/18975/ | |
36 | Signed-off-by: James Hogan <jhogan@kernel.org> | |
37 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
38 | ||
39 | --- | |
40 | arch/mips/lib/memset.S | 7 ++++++- | |
41 | 1 file changed, 6 insertions(+), 1 deletion(-) | |
42 | ||
43 | --- a/arch/mips/lib/memset.S | |
44 | +++ b/arch/mips/lib/memset.S | |
45 | @@ -218,7 +218,7 @@ | |
46 | 1: PTR_ADDIU a0, 1 /* fill bytewise */ | |
47 | R10KCBARRIER(0(ra)) | |
48 | bne t1, a0, 1b | |
49 | - sb a1, -1(a0) | |
50 | + EX(sb, a1, -1(a0), .Lsmall_fixup\@) | |
51 | ||
52 | 2: jr ra /* done */ | |
53 | move a2, zero | |
54 | @@ -257,6 +257,11 @@ | |
55 | jr ra | |
56 | andi v1, a2, STORMASK | |
57 | ||
58 | +.Lsmall_fixup\@: | |
59 | + PTR_SUBU a2, t1, a0 | |
60 | + jr ra | |
61 | + PTR_ADDIU a2, 1 | |
62 | + | |
63 | .endm | |
64 | ||
65 | /* |