Branch data Line data Source code
1 : : /*
2 : : * Copyright (c) 2015 Dmitry V. Levin <ldv@altlinux.org>
3 : : * All rights reserved.
4 : : *
5 : : * Redistribution and use in source and binary forms, with or without
6 : : * modification, are permitted provided that the following conditions
7 : : * are met:
8 : : * 1. Redistributions of source code must retain the above copyright
9 : : * notice, this list of conditions and the following disclaimer.
10 : : * 2. Redistributions in binary form must reproduce the above copyright
11 : : * notice, this list of conditions and the following disclaimer in the
12 : : * documentation and/or other materials provided with the distribution.
13 : : * 3. The name of the author may not be used to endorse or promote products
14 : : * derived from this software without specific prior written permission.
15 : : *
16 : : * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 : : * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 : : * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 : : * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 : : * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 : : * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 : : * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 : : * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 : : * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 : : * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 : : */
27 : :
28 : : #include "defs.h"
29 : : #include <fcntl.h>
30 : :
31 : : #include "xlat/uffd_flags.h"
32 : :
33 : 5 : SYS_FUNC(userfaultfd)
34 : : {
35 : 5 : printflags(uffd_flags, tcp->u_arg[0], "UFFD_???");
36 : :
37 : 5 : return RVAL_DECODED | RVAL_FD;
38 : : }
39 : :
40 : : #ifdef HAVE_LINUX_USERFAULTFD_H
41 : : # include <linux/ioctl.h>
42 : : # include <linux/userfaultfd.h>
43 : :
44 : : # include "xlat/uffd_api_flags.h"
45 : : # include "xlat/uffd_copy_flags.h"
46 : : # include "xlat/uffd_register_ioctl_flags.h"
47 : : # include "xlat/uffd_register_mode_flags.h"
48 : : # include "xlat/uffd_zeropage_flags.h"
49 : :
50 : : static void
51 : 40 : tprintf_uffdio_range(const struct uffdio_range *range)
52 : : {
53 : 40 : tprintf("{start=%#" PRI__x64 ", len=%#" PRI__x64 "}",
54 : : range->start, range->len);
55 : 40 : }
56 : :
57 : : int
58 : 130 : uffdio_ioctl(struct tcb *const tcp, const unsigned int code,
59 : : const kernel_ulong_t arg)
60 : : {
61 [ + + + + : 130 : switch (code) {
+ - ]
62 : : case UFFDIO_API: {
63 : : struct uffdio_api ua;
64 [ + + ]: 25 : if (entering(tcp)) {
65 : 15 : tprints(", ");
66 [ + + ]: 15 : if (umove_or_printaddr(tcp, arg, &ua))
67 : 5 : return RVAL_DECODED | 1;
68 : : /* Features is intended to contain some flags, but
69 : : * there aren't any defined yet.
70 : : */
71 : 10 : tprintf("{api=%#" PRI__x64
72 : : ", features=%#" PRI__x64,
73 : : ua.api, ua.features);
74 : : } else {
75 [ + + ][ + - ]: 10 : if (!syserror(tcp) && !umove(tcp, arg, &ua)) {
76 : 5 : tprintf(", features.out=%#" PRI__x64
77 : : ", ioctls=", ua.features);
78 : 5 : printflags64(uffd_api_flags, ua.ioctls,
79 : : "_UFFDIO_???");
80 : : }
81 : 10 : tprints("}");
82 : : }
83 : 25 : return 1;
84 : : }
85 : :
86 : : case UFFDIO_COPY: {
87 : : struct uffdio_copy uc;
88 [ + + ]: 25 : if (entering(tcp)) {
89 : 15 : tprints(", ");
90 [ + + ]: 15 : if (umove_or_printaddr(tcp, arg, &uc))
91 : 5 : return RVAL_DECODED | 1;
92 : 10 : tprintf("{dst=%#" PRI__x64 ", src=%#" PRI__x64
93 : : ", len=%#" PRI__x64 ", mode=",
94 : : uc.dst, uc.src, uc.len);
95 : 10 : printflags64(uffd_copy_flags, uc.mode,
96 : : "UFFDIO_COPY_???");
97 : : } else {
98 [ + + ][ + - ]: 10 : if (!syserror(tcp) && !umove(tcp, arg, &uc))
99 : 5 : tprintf(", copy=%#" PRI__x64, uc.copy);
100 : 10 : tprints("}");
101 : : }
102 : 25 : return 1;
103 : : }
104 : :
105 : : case UFFDIO_REGISTER: {
106 : : struct uffdio_register ur;
107 [ + + ]: 25 : if (entering(tcp)) {
108 : 15 : tprints(", ");
109 [ + + ]: 15 : if (umove_or_printaddr(tcp, arg, &ur))
110 : 5 : return RVAL_DECODED | 1;
111 : 10 : tprints("{range=");
112 : 10 : tprintf_uffdio_range(&ur.range);
113 : 10 : tprints(", mode=");
114 : 10 : printflags64(uffd_register_mode_flags, ur.mode,
115 : : "UFFDIO_REGISTER_MODE_???");
116 : : } else {
117 [ + + ][ + - ]: 10 : if (!syserror(tcp) && !umove(tcp, arg, &ur)) {
118 : 5 : tprints(", ioctls=");
119 : 5 : printflags64(uffd_register_ioctl_flags,
120 : 5 : ur.ioctls, "UFFDIO_???");
121 : : }
122 : 10 : tprints("}");
123 : : }
124 : 25 : return 1;
125 : : }
126 : :
127 : : case UFFDIO_UNREGISTER:
128 : : case UFFDIO_WAKE: {
129 : : struct uffdio_range ura;
130 : 30 : tprints(", ");
131 [ + + ]: 30 : if (!umove_or_printaddr(tcp, arg, &ura))
132 : 20 : tprintf_uffdio_range(&ura);
133 : 30 : return RVAL_DECODED | 1;
134 : : }
135 : :
136 : : case UFFDIO_ZEROPAGE: {
137 : : struct uffdio_zeropage uz;
138 [ + + ]: 25 : if (entering(tcp)) {
139 : 15 : tprints(", ");
140 [ + + ]: 15 : if (umove_or_printaddr(tcp, arg, &uz))
141 : 5 : return RVAL_DECODED | 1;
142 : 10 : tprints("{range=");
143 : 10 : tprintf_uffdio_range(&uz.range);
144 : 10 : tprints(", mode=");
145 : 10 : printflags64(uffd_zeropage_flags, uz.mode,
146 : : "UFFDIO_ZEROPAGE_???");
147 : : } else {
148 [ + + ][ + - ]: 10 : if (!syserror(tcp) && !umove(tcp, arg, &uz))
149 : 5 : tprintf(", zeropage=%#" PRI__x64, uz.zeropage);
150 : 10 : tprints("}");
151 : : }
152 : 25 : return 1;
153 : : }
154 : :
155 : : default:
156 : 0 : return RVAL_DECODED;
157 : : }
158 : : }
159 : : #endif /* HAVE_LINUX_USERFAULTFD_H */
|