21c648463a4a0aa4bdb7a2720cbb76321b341872
[akaros.git] / kern / include / umem.h
1 /* Copyright (c) 2009, 2010 The Regents of the University of California
2  * Barret Rhoden <brho@cs.berkeley.edu>
3  * Andrew Waterman <waterman@cs.berkeley.edu>
4  * See LICENSE for details.
5  *
6  * Functions for working with userspace's address space. */
7
8 #ifndef ROS_KERN_UMEM_H
9 #define ROS_KERN_UMEM_H
10
11 #include <ros/common.h>
12 #include <process.h>
13
14 /* Is this a valid user pointer for read/write?  It doesn't care if the address
15  * is paged out or even an unmapped region: simply if it is in part of the
16  * address space that could be RW user.  Will also check for len bytes. */
17 static inline bool is_user_rwaddr(void *addr, size_t len);
18 /* Same deal, but read-only */
19 static inline bool is_user_raddr(void *addr, size_t len);
20
21 /* Copy from proc p into the kernel's dest from src */
22 int memcpy_from_user(struct proc *p, void *dest, const void *va,
23                      size_t len);
24
25 /* Copy to proc p into va from the kernel's src */
26 int memcpy_to_user(struct proc *p, void *a, const void *src,
27                    size_t len);
28 /* Same as above, but sets errno */
29 int memcpy_from_user_errno(struct proc *p, void *dst, const void *src, int len);
30 int memcpy_to_user_errno(struct proc *p, void *dst, const void *src, int len);
31                  
32 /* Creates a buffer (kmalloc) and safely copies into it from va.  Can return an
33  * error code.  Check its response with IS_ERR().  Must be paired with
34  * user_memdup_free() if this succeeded. */
35 void *user_memdup(struct proc *p, const void *va, int len);
36 /* Same as above, but sets errno */
37 void *user_memdup_errno(struct proc *p, const void *va, int len);
38 void user_memdup_free(struct proc *p, void *va);
39 /* Same as memdup, but just does strings.  still needs memdup_freed */
40 char *user_strdup(struct proc *p, const char *u_string, size_t strlen);
41 char *user_strdup_errno(struct proc *p, const char *u_string, size_t strlen);
42 void *kmalloc_errno(int len);
43 bool uva_is_kva(struct proc *p, void *uva, void *kva);
44 uintptr_t uva2kva(struct proc *p, void *uva);
45
46 /* Helper for is_user_r{w,}addr.
47  *
48  * These checks are for addresses that the kernel accesses on behalf of the
49  * user, which are mapped into the user's address space.  One interpretation is
50  * whether or not the user is allowed to refer to this memory, hence the
51  * MMAP_LOWEST_VA check.  But note that the user is allowed to attempt virtual
52  * memory accesses outside of this range.  VMM code may interpose on low memory
53  * PFs to emulate certain instructions.  However, the kernel should never be
54  * given such a pointer.
55  *
56  * Without the MMAP_LOWEST_VA check, the kernel would still PF on a bad user
57  * pointer (say the user gave us 0x10; we have nothing mapped at addr 0).
58  * However, it would be more difficult to detect if the PF was the kernel acting
59  * on behalf of the user or if the kernel itself had a null pointer deref.  By
60  * checking early, the kernel will catch low addresses and error out before page
61  * faulting. */
62 static inline bool __is_user_addr(void *addr, size_t len, uintptr_t lim)
63 {
64         if ((MMAP_LOWEST_VA <= (uintptr_t)addr) &&
65             ((uintptr_t)addr < lim) &&
66             ((uintptr_t)addr + len <= lim))
67                 return TRUE;
68         else
69                 return FALSE;
70 }
71
72 /* UWLIM is defined as virtual address below which a process can write */
73 static inline bool is_user_rwaddr(void *addr, size_t len)
74 {
75         return __is_user_addr(addr, len, UWLIM);
76 }
77
78 /* ULIM is defined as virtual address below which a process can read */
79 static inline bool is_user_raddr(void *addr, size_t len)
80 {
81         return __is_user_addr(addr, len, ULIM);
82 }
83
84 #endif /* ROS_KERN_UMEM_H */