git://git.onelab.eu
/
linux-2.6.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git]
/
arch
/
sparc64
/
lib
/
user_fixup.c
diff --git
a/arch/sparc64/lib/user_fixup.c
b/arch/sparc64/lib/user_fixup.c
index
0278e34
..
19d1fdb
100644
(file)
--- a/
arch/sparc64/lib/user_fixup.c
+++ b/
arch/sparc64/lib/user_fixup.c
@@
-11,61
+11,56
@@
/* Calculating the exact fault address when using
* block loads and stores can be very complicated.
/* Calculating the exact fault address when using
* block loads and stores can be very complicated.
+ *
* Instead of trying to be clever and handling all
* of the cases, just fix things up simply here.
*/
* Instead of trying to be clever and handling all
* of the cases, just fix things up simply here.
*/
-
unsigned long copy_from_user_fixup(void *to, const void __user *from, unsigned long size
)
+
static unsigned long compute_size(unsigned long start, unsigned long size, unsigned long *offset
)
{
{
-
char *dst = to
;
-
const char __user *src = from
;
+
unsigned long fault_addr = current_thread_info()->fault_address
;
+
unsigned long end = start + size
;
- while (size) {
- if (__get_user(*dst, src))
- break;
- dst++;
- src++;
- size--;
+ if (fault_addr < start || fault_addr >= end) {
+ *offset = 0;
+ } else {
+ *offset = start - fault_addr;
+ size = end - fault_addr;
}
}
+ return size;
+}
- if (size)
- memset(dst, 0, size);
+unsigned long copy_from_user_fixup(void *to, const void __user *from, unsigned long size)
+{
+ unsigned long offset;
+
+ size = compute_size((unsigned long) from, size, &offset);
+ if (likely(size))
+ memset(to + offset, 0, size);
return size;
}
unsigned long copy_to_user_fixup(void __user *to, const void *from, unsigned long size)
{
return size;
}
unsigned long copy_to_user_fixup(void __user *to, const void *from, unsigned long size)
{
- char __user *dst = to;
- const char *src = from;
-
- while (size) {
- if (__put_user(*src, dst))
- break;
- dst++;
- src++;
- size--;
- }
+ unsigned long offset;
- return
size
;
+ return
compute_size((unsigned long) to, size, &offset)
;
}
unsigned long copy_in_user_fixup(void __user *to, void __user *from, unsigned long size)
{
}
unsigned long copy_in_user_fixup(void __user *to, void __user *from, unsigned long size)
{
- char __user *dst = to;
- char __user *src = from;
+ unsigned long fault_addr = current_thread_info()->fault_address;
+ unsigned long start = (unsigned long) to;
+ unsigned long end = start + size;
- while (size) {
-
char tmp
;
+ if (fault_addr >= start && fault_addr < end)
+
return end - fault_addr
;
- if (__get_user(tmp, src))
- break;
- if (__put_user(tmp, dst))
- break;
- dst++;
- src++;
- size--;
- }
+ start = (unsigned long) from;
+ end = start + size;
+ if (fault_addr >= start && fault_addr < end)
+ return end - fault_addr;
return size;
}
return size;
}