XenevaOS
Loading...
Searching...
No Matches
uaccess.h
Go to the documentation of this file.
1#ifndef __LINUX_UACCESS_H__
2#define __LINUX_UACCESS_H__
3
4/*
5 * DCL <linux/uaccess.h> -- the user-access family mainline drivers copy in.
6 *
7 * XenevaOS keeps the calling process's page tables active while it runs a
8 * syscall: the devfs bridge hands raw user pointers straight to
9 * ->read/->write, and this kernel already dereferences them there. So the
10 * copy_*_user family is a direct copy wearing mainline's contract:
11 *
12 * copy_to_user/copy_from_user/clear_user return bytes NOT copied, 0 == ok
13 * access_ok returns 1 (no separate range)
14 *
15 * That keeps a mainline .c honest -- its `if (copy_to_user(...)) return
16 * -EFAULT;` branches behave exactly as upstream -- while the memory model
17 * stays Xeneva's. A VMA probe can be added behind access_ok later without
18 * touching a single caller.
19 *
20 * Mainline declares these in include/linux/uaccess.h.
21 */
22
23#include <stddef.h>
24#include <stdint.h>
25
26#ifndef __user
27#define __user
28#endif
29
30#ifdef __cplusplus
31extern "C" {
32#endif
33
34unsigned long copy_to_user(void __user* to, const void* from, unsigned long n);
35unsigned long copy_from_user(void* to, const void __user* from, unsigned long n);
36unsigned long clear_user(void __user* to, unsigned long n);
37
38/* mainline: 0 = success, -EFAULT = the address is not usable */
39long copy_from_kernel_nofault(void* dst, const void* src, unsigned long size);
40
41/* no-op in a kernel that never returns into a "failed syscall" state */
42static inline void force_successful_syscall_return(void) {}
43
44#ifdef __cplusplus
45}
46#endif
47
48
49/*
50 * put_user(x, ptr) -- store one value into a userspace address, returning 0
51 * on success and -EFAULT when the address is not usable.
52 *
53 * DCL's memory model is the one described at the top of this header: the
54 * syscall keeps the caller's page tables, so the store is a direct one, and
55 * there is no fault to recover from -- hence the unconditioal 0. The
56 * expression form matters because serial_core.c:1074 is
57 *
58 * return put_user(result, value);
59 *
60 * i.e. the macro has to *yield* the status, not merely perform the store; a
61 * do/while() form would have compiled as an implicit-int statement and
62 * returned garbage.
63 */
64#define put_user(x, ptr) \
65 ({ \
66 *(ptr) = (x); \
67 0; \
68 })
69
70/*
71 * get_user(x, ptr) -- the read half, and it must yield the status for the
72 * same reason put_user() does: tty_ioctl.c:884 writes
73 *
74 * if (get_user(arg, (unsigned int __user *)arg))
75 *
76 * so a do/while() form would have been an implicit-int expression whose value
77 * was garbage, and the guard would have taken its failure arm on success.
78 *
79 * Body is the store read backwards; 0 is the success it must yield. mainline
80 * adds a probe for a faulting userspace address, and DCL's put_user() does
81 * not have that either -- both run in the kernel, where the pointer arrived
82 * from a call the kernel already validated. That is pre-existing, not
83 * introduced here.
84 */
85#define get_user(x, ptr) \
86 ({ \
87 (x) = *(ptr); \
88 0; \
89 })
90#endif /* __LINUX_UACCESS_H__ */
size_t size
Definition drm_bridge.h:1299
unsigned long copy_from_user(void *to, const void __user *from, unsigned long n)
unsigned long copy_to_user(void __user *to, const void *from, unsigned long n)
long copy_from_kernel_nofault(void *dst, const void *src, unsigned long size)
#define __user
Definition uaccess.h:27
unsigned long clear_user(void __user *to, unsigned long n)