Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
arch
sparc
lib
user_fixup.c
Go to the documentation of this file.
1
/* user_fixup.c: Fix up user copy faults.
2
*
3
* Copyright (C) 2004 David S. Miller <
[email protected]
>
4
*/
5
6
#include <linux/compiler.h>
7
#include <linux/kernel.h>
8
#include <linux/string.h>
9
#include <linux/errno.h>
10
#include <linux/module.h>
11
12
#include <asm/uaccess.h>
13
14
/* Calculating the exact fault address when using
15
* block loads and stores can be very complicated.
16
*
17
* Instead of trying to be clever and handling all
18
* of the cases, just fix things up simply here.
19
*/
20
21
static
unsigned
long
compute_size(
unsigned
long
start
,
unsigned
long
size
,
unsigned
long
*
offset
)
22
{
23
unsigned
long
fault_addr =
current_thread_info
()->fault_address;
24
unsigned
long
end
= start +
size
;
25
26
if
(fault_addr < start || fault_addr >= end) {
27
*offset = 0;
28
}
else
{
29
*offset = fault_addr -
start
;
30
size = end - fault_addr;
31
}
32
return
size
;
33
}
34
35
unsigned
long
copy_from_user_fixup
(
void
*to,
const
void
__user *
from
,
unsigned
long
size)
36
{
37
unsigned
long
offset
;
38
39
size = compute_size((
unsigned
long
) from, size, &offset);
40
if
(
likely
(size))
41
memset
(to + offset, 0, size);
42
43
return
size
;
44
}
45
EXPORT_SYMBOL
(
copy_from_user_fixup
);
46
47
unsigned
long
copy_to_user_fixup
(
void
__user *to,
const
void
*
from
,
unsigned
long
size)
48
{
49
unsigned
long
offset
;
50
51
return
compute_size((
unsigned
long
) to, size, &offset);
52
}
53
EXPORT_SYMBOL
(
copy_to_user_fixup
);
54
55
unsigned
long
copy_in_user_fixup
(
void
__user *to,
void
__user *
from
,
unsigned
long
size)
56
{
57
unsigned
long
fault_addr =
current_thread_info
()->fault_address;
58
unsigned
long
start = (
unsigned
long
) to;
59
unsigned
long
end = start +
size
;
60
61
if
(fault_addr >= start && fault_addr < end)
62
return
end - fault_addr;
63
64
start = (
unsigned
long
) from;
65
end = start +
size
;
66
if
(fault_addr >= start && fault_addr < end)
67
return
end - fault_addr;
68
69
return
size
;
70
}
71
EXPORT_SYMBOL
(
copy_in_user_fixup
);
Generated on Thu Jan 10 2013 13:18:49 for Linux Kernel by
1.8.2