Skip to content

Commit

Permalink
sparc64: Fix probe_kernel_{read,write}().
Browse files Browse the repository at this point in the history
This is based upon a report from Chris Torek and his initial patch.
From Chris's report:

--------------------
This came up in testing kgdb, using the built-in tests -- turn
on CONFIG_KGDB_TESTS, then

    echo V1 > /sys/module/kgdbts/parameters/kgdbts

-- but it would affect using kgdb if you were debugging and looking
at bad pointers.
--------------------

When we get a copy_{from,to}_user() request and the %asi is set to
something other than ASI_AIUS (which is userspace) then we branch off
to a routine called memcpy_user_stub().  It just does a straight
memcpy since we are copying from kernel to kernel in this case.

The logic was that since source and destination are both kernel
pointers we don't need to have exception checks.

But for what probe_kernel_{read,write}() is trying to do, we have to
have the checks, otherwise things like kgdb bad kernel pointer
accesses don't do the right thing.

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Feb 9, 2009
1 parent 40bdac7 commit aeb3987
Show file tree
Hide file tree
Showing 10 changed files with 25 additions and 48 deletions.
2 changes: 1 addition & 1 deletion arch/sparc/lib/GENcopy_from_user.S
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
#define PREAMBLE \
rd %asi, %g1; \
cmp %g1, ASI_AIUS; \
bne,pn %icc, memcpy_user_stub; \
bne,pn %icc, ___copy_in_user; \
nop
#endif

Expand Down
2 changes: 1 addition & 1 deletion arch/sparc/lib/GENcopy_to_user.S
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
#define PREAMBLE \
rd %asi, %g1; \
cmp %g1, ASI_AIUS; \
bne,pn %icc, memcpy_user_stub; \
bne,pn %icc, ___copy_in_user; \
nop
#endif

Expand Down
2 changes: 1 addition & 1 deletion arch/sparc/lib/NG2copy_from_user.S
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
#define PREAMBLE \
rd %asi, %g1; \
cmp %g1, ASI_AIUS; \
bne,pn %icc, memcpy_user_stub; \
bne,pn %icc, ___copy_in_user; \
nop
#endif

Expand Down
2 changes: 1 addition & 1 deletion arch/sparc/lib/NG2copy_to_user.S
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
#define PREAMBLE \
rd %asi, %g1; \
cmp %g1, ASI_AIUS; \
bne,pn %icc, memcpy_user_stub; \
bne,pn %icc, ___copy_in_user; \
nop
#endif

Expand Down
2 changes: 1 addition & 1 deletion arch/sparc/lib/NGcopy_from_user.S
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
#define PREAMBLE \
rd %asi, %g1; \
cmp %g1, ASI_AIUS; \
bne,pn %icc, memcpy_user_stub; \
bne,pn %icc, ___copy_in_user; \
nop
#endif

Expand Down
2 changes: 1 addition & 1 deletion arch/sparc/lib/NGcopy_to_user.S
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
#define PREAMBLE \
rd %asi, %g1; \
cmp %g1, ASI_AIUS; \
bne,pn %icc, memcpy_user_stub; \
bne,pn %icc, ___copy_in_user; \
nop
#endif

Expand Down
2 changes: 1 addition & 1 deletion arch/sparc/lib/U1copy_from_user.S
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
#define PREAMBLE \
rd %asi, %g1; \
cmp %g1, ASI_AIUS; \
bne,pn %icc, memcpy_user_stub; \
bne,pn %icc, ___copy_in_user; \
nop; \

#include "U1memcpy.S"
2 changes: 1 addition & 1 deletion arch/sparc/lib/U1copy_to_user.S
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
#define PREAMBLE \
rd %asi, %g1; \
cmp %g1, ASI_AIUS; \
bne,pn %icc, memcpy_user_stub; \
bne,pn %icc, ___copy_in_user; \
nop; \

#include "U1memcpy.S"
2 changes: 1 addition & 1 deletion arch/sparc/lib/U3copy_to_user.S
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
#define PREAMBLE \
rd %asi, %g1; \
cmp %g1, ASI_AIUS; \
bne,pn %icc, memcpy_user_stub; \
bne,pn %icc, ___copy_in_user; \
nop; \

#include "U3memcpy.S"
55 changes: 16 additions & 39 deletions arch/sparc/lib/copy_in_user.S
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* Copyright (C) 1999, 2000, 2004 David S. Miller (davem@redhat.com)
*/

#include <linux/linkage.h>
#include <asm/asi.h>

#define XCC xcc
Expand All @@ -27,18 +28,7 @@
* to copy register windows around during thread cloning.
*/

.globl ___copy_in_user
.type ___copy_in_user,#function
___copy_in_user: /* %o0=dst, %o1=src, %o2=len */
/* Writing to %asi is _expensive_ so we hardcode it.
* Reading %asi to check for KERNEL_DS is comparatively
* cheap.
*/
rd %asi, %g1
cmp %g1, ASI_AIUS
bne,pn %icc, memcpy_user_stub
nop

ENTRY(___copy_in_user) /* %o0=dst, %o1=src, %o2=len */
cmp %o2, 0
be,pn %XCC, 85f
or %o0, %o1, %o3
Expand All @@ -49,22 +39,24 @@ ___copy_in_user: /* %o0=dst, %o1=src, %o2=len */
/* 16 < len <= 64 */
andcc %o3, 0x7, %g0
bne,pn %XCC, 90f
sub %o0, %o1, %o3
nop

andn %o2, 0x7, %o4
and %o2, 0x7, %o2
1: subcc %o4, 0x8, %o4
EX(ldxa [%o1] %asi, %o5)
EX(stxa %o5, [%o1 + %o3] ASI_AIUS)
EX(stxa %o5, [%o0] %asi)
add %o1, 0x8, %o1
bgu,pt %XCC, 1b
add %o1, 0x8, %o1
add %o0, 0x8, %o0
andcc %o2, 0x4, %g0
be,pt %XCC, 1f
nop
sub %o2, 0x4, %o2
EX(lduwa [%o1] %asi, %o5)
EX(stwa %o5, [%o1 + %o3] ASI_AIUS)
EX(stwa %o5, [%o0] %asi)
add %o1, 0x4, %o1
add %o0, 0x4, %o0
1: cmp %o2, 0
be,pt %XCC, 85f
nop
Expand All @@ -74,14 +66,15 @@ ___copy_in_user: /* %o0=dst, %o1=src, %o2=len */
80: /* 0 < len <= 16 */
andcc %o3, 0x3, %g0
bne,pn %XCC, 90f
sub %o0, %o1, %o3
nop

82:
subcc %o2, 4, %o2
EX(lduwa [%o1] %asi, %g1)
EX(stwa %g1, [%o1 + %o3] ASI_AIUS)
EX(stwa %g1, [%o0] %asi)
add %o1, 4, %o1
bgu,pt %XCC, 82b
add %o1, 4, %o1
add %o0, 4, %o0

85: retl
clr %o0
Expand All @@ -90,26 +83,10 @@ ___copy_in_user: /* %o0=dst, %o1=src, %o2=len */
90:
subcc %o2, 1, %o2
EX(lduba [%o1] %asi, %g1)
EX(stba %g1, [%o1 + %o3] ASI_AIUS)
EX(stba %g1, [%o0] %asi)
add %o1, 1, %o1
bgu,pt %XCC, 90b
add %o1, 1, %o1
add %o0, 1, %o0
retl
clr %o0

.size ___copy_in_user, .-___copy_in_user

/* Act like copy_{to,in}_user(), ie. return zero instead
* of original destination pointer. This is invoked when
* copy_{to,in}_user() finds that %asi is kernel space.
*/
.globl memcpy_user_stub
.type memcpy_user_stub,#function
memcpy_user_stub:
save %sp, -192, %sp
mov %i0, %o0
mov %i1, %o1
call memcpy
mov %i2, %o2
ret
restore %g0, %g0, %o0
.size memcpy_user_stub, .-memcpy_user_stub
ENDPROC(___copy_in_user)

0 comments on commit aeb3987

Please sign in to comment.