9 #include <linux/module.h>
10 #include <linux/sched.h>
11 #include <asm/current.h>
13 #include <asm/pgtable.h>
41 static pte_t *maybe_map(
unsigned long virt,
int is_write)
59 static int do_op_one_page(
unsigned long addr,
int len,
int is_write,
60 int (*
op)(
unsigned long addr,
int len,
void *
arg),
void *arg)
67 pte = maybe_map(addr, is_write);
90 static int buffer_op(
unsigned long addr,
int len,
int is_write,
91 int (*
op)(
unsigned long,
int,
void *),
void *arg)
98 n = do_op_one_page(addr, size, is_write,
op, arg);
100 remain = (n < 0 ? remain : 0);
109 while (addr < ((addr + remain) &
PAGE_MASK)) {
110 n = do_op_one_page(addr,
PAGE_SIZE, is_write,
op, arg);
112 remain = (n < 0 ? remain : 0);
122 n = do_op_one_page(addr, remain, is_write,
op, arg);
124 remain = (n < 0 ? remain : 0);
133 static int copy_chunk_from_user(
unsigned long from,
int len,
void *arg)
135 unsigned long *to_ptr =
arg, to = *to_ptr;
137 memcpy((
void *) to, (
void *) from, len);
150 buffer_op((
unsigned long) from, n, 0, copy_chunk_from_user, &to):
155 static int copy_chunk_to_user(
unsigned long to,
int len,
void *arg)
157 unsigned long *from_ptr =
arg, from = *from_ptr;
159 memcpy((
void *) to, (
void *) from, len);
172 buffer_op((
unsigned long) to, n, 1, copy_chunk_to_user, &from) :
177 static int strncpy_chunk_from_user(
unsigned long from,
int len,
void *arg)
179 char **to_ptr =
arg, *to = *to_ptr;
182 strncpy(to, (
void *) from, len);
204 n = buffer_op((
unsigned long) src, count, 0, strncpy_chunk_from_user,
212 static int clear_chunk(
unsigned long addr,
int len,
void *
unused)
214 memset((
void *) addr, 0, len);
220 return buffer_op((
unsigned long) mem, len, 1, clear_chunk,
NULL);
231 buffer_op((
unsigned long) mem, len, 1, clear_chunk,
NULL) : len;
235 static int strnlen_chunk(
unsigned long str,
int len,
void *arg)
237 int *len_ptr =
arg,
n;
239 n =
strnlen((
void *) str, len);
254 n = buffer_op((
unsigned long) str, len, 0, strnlen_chunk, &count);