.. | .. |
---|
| 1 | +/* SPDX-License-Identifier: GPL-2.0-or-later */ |
---|
1 | 2 | /* |
---|
2 | 3 | * Berkeley style UIO structures - Alan Cox 1994. |
---|
3 | | - * |
---|
4 | | - * This program is free software; you can redistribute it and/or |
---|
5 | | - * modify it under the terms of the GNU General Public License |
---|
6 | | - * as published by the Free Software Foundation; either version |
---|
7 | | - * 2 of the License, or (at your option) any later version. |
---|
8 | 4 | */ |
---|
9 | 5 | #ifndef __LINUX_UIO_H |
---|
10 | 6 | #define __LINUX_UIO_H |
---|
.. | .. |
---|
21 | 17 | size_t iov_len; |
---|
22 | 18 | }; |
---|
23 | 19 | |
---|
24 | | -enum { |
---|
25 | | - ITER_IOVEC = 0, |
---|
26 | | - ITER_KVEC = 2, |
---|
27 | | - ITER_BVEC = 4, |
---|
28 | | - ITER_PIPE = 8, |
---|
| 20 | +enum iter_type { |
---|
| 21 | + /* iter types */ |
---|
| 22 | + ITER_IOVEC = 4, |
---|
| 23 | + ITER_KVEC = 8, |
---|
| 24 | + ITER_BVEC = 16, |
---|
| 25 | + ITER_PIPE = 32, |
---|
| 26 | + ITER_DISCARD = 64, |
---|
| 27 | +}; |
---|
| 28 | + |
---|
| 29 | +struct iov_iter_state { |
---|
| 30 | + size_t iov_offset; |
---|
| 31 | + size_t count; |
---|
| 32 | + unsigned long nr_segs; |
---|
29 | 33 | }; |
---|
30 | 34 | |
---|
31 | 35 | struct iov_iter { |
---|
32 | | - int type; |
---|
| 36 | + /* |
---|
| 37 | + * Bit 0 is the read/write bit, set if we're writing. |
---|
| 38 | + * Bit 1 is the BVEC_FLAG_NO_REF bit, set if type is a bvec and |
---|
| 39 | + * the caller isn't expecting to drop a page reference when done. |
---|
| 40 | + */ |
---|
| 41 | + unsigned int type; |
---|
33 | 42 | size_t iov_offset; |
---|
34 | 43 | size_t count; |
---|
35 | 44 | union { |
---|
.. | .. |
---|
41 | 50 | union { |
---|
42 | 51 | unsigned long nr_segs; |
---|
43 | 52 | struct { |
---|
44 | | - int idx; |
---|
45 | | - int start_idx; |
---|
| 53 | + unsigned int head; |
---|
| 54 | + unsigned int start_head; |
---|
46 | 55 | }; |
---|
47 | 56 | }; |
---|
48 | 57 | }; |
---|
| 58 | + |
---|
| 59 | +static inline enum iter_type iov_iter_type(const struct iov_iter *i) |
---|
| 60 | +{ |
---|
| 61 | + return i->type & ~(READ | WRITE); |
---|
| 62 | +} |
---|
| 63 | + |
---|
| 64 | +static inline void iov_iter_save_state(struct iov_iter *iter, |
---|
| 65 | + struct iov_iter_state *state) |
---|
| 66 | +{ |
---|
| 67 | + state->iov_offset = iter->iov_offset; |
---|
| 68 | + state->count = iter->count; |
---|
| 69 | + state->nr_segs = iter->nr_segs; |
---|
| 70 | +} |
---|
| 71 | + |
---|
| 72 | +static inline bool iter_is_iovec(const struct iov_iter *i) |
---|
| 73 | +{ |
---|
| 74 | + return iov_iter_type(i) == ITER_IOVEC; |
---|
| 75 | +} |
---|
| 76 | + |
---|
| 77 | +static inline bool iov_iter_is_kvec(const struct iov_iter *i) |
---|
| 78 | +{ |
---|
| 79 | + return iov_iter_type(i) == ITER_KVEC; |
---|
| 80 | +} |
---|
| 81 | + |
---|
| 82 | +static inline bool iov_iter_is_bvec(const struct iov_iter *i) |
---|
| 83 | +{ |
---|
| 84 | + return iov_iter_type(i) == ITER_BVEC; |
---|
| 85 | +} |
---|
| 86 | + |
---|
| 87 | +static inline bool iov_iter_is_pipe(const struct iov_iter *i) |
---|
| 88 | +{ |
---|
| 89 | + return iov_iter_type(i) == ITER_PIPE; |
---|
| 90 | +} |
---|
| 91 | + |
---|
| 92 | +static inline bool iov_iter_is_discard(const struct iov_iter *i) |
---|
| 93 | +{ |
---|
| 94 | + return iov_iter_type(i) == ITER_DISCARD; |
---|
| 95 | +} |
---|
| 96 | + |
---|
| 97 | +static inline unsigned char iov_iter_rw(const struct iov_iter *i) |
---|
| 98 | +{ |
---|
| 99 | + return i->type & (READ | WRITE); |
---|
| 100 | +} |
---|
49 | 101 | |
---|
50 | 102 | /* |
---|
51 | 103 | * Total number of bytes covered by an iovec. |
---|
.. | .. |
---|
72 | 124 | iter->iov->iov_len - iter->iov_offset), |
---|
73 | 125 | }; |
---|
74 | 126 | } |
---|
75 | | - |
---|
76 | | -#define iov_for_each(iov, iter, start) \ |
---|
77 | | - if (!((start).type & (ITER_BVEC | ITER_PIPE))) \ |
---|
78 | | - for (iter = (start); \ |
---|
79 | | - (iter).count && \ |
---|
80 | | - ((iov = iov_iter_iovec(&(iter))), 1); \ |
---|
81 | | - iov_iter_advance(&(iter), (iov).iov_len)) |
---|
82 | 127 | |
---|
83 | 128 | size_t iov_iter_copy_from_user_atomic(struct page *page, |
---|
84 | 129 | struct iov_iter *i, unsigned long offset, size_t bytes); |
---|
.. | .. |
---|
154 | 199 | #define _copy_from_iter_flushcache _copy_from_iter_nocache |
---|
155 | 200 | #endif |
---|
156 | 201 | |
---|
157 | | -#ifdef CONFIG_ARCH_HAS_UACCESS_MCSAFE |
---|
158 | | -size_t _copy_to_iter_mcsafe(const void *addr, size_t bytes, struct iov_iter *i); |
---|
| 202 | +#ifdef CONFIG_ARCH_HAS_COPY_MC |
---|
| 203 | +size_t _copy_mc_to_iter(const void *addr, size_t bytes, struct iov_iter *i); |
---|
159 | 204 | #else |
---|
160 | | -#define _copy_to_iter_mcsafe _copy_to_iter |
---|
| 205 | +#define _copy_mc_to_iter _copy_to_iter |
---|
161 | 206 | #endif |
---|
162 | 207 | |
---|
163 | 208 | static __always_inline __must_check |
---|
.. | .. |
---|
170 | 215 | } |
---|
171 | 216 | |
---|
172 | 217 | static __always_inline __must_check |
---|
173 | | -size_t copy_to_iter_mcsafe(void *addr, size_t bytes, struct iov_iter *i) |
---|
| 218 | +size_t copy_mc_to_iter(void *addr, size_t bytes, struct iov_iter *i) |
---|
174 | 219 | { |
---|
175 | 220 | if (unlikely(!check_copy_size(addr, bytes, true))) |
---|
176 | 221 | return 0; |
---|
177 | 222 | else |
---|
178 | | - return _copy_to_iter_mcsafe(addr, bytes, i); |
---|
| 223 | + return _copy_mc_to_iter(addr, bytes, i); |
---|
179 | 224 | } |
---|
180 | 225 | |
---|
181 | 226 | size_t iov_iter_zero(size_t bytes, struct iov_iter *); |
---|
182 | 227 | unsigned long iov_iter_alignment(const struct iov_iter *i); |
---|
183 | 228 | unsigned long iov_iter_gap_alignment(const struct iov_iter *i); |
---|
184 | | -void iov_iter_init(struct iov_iter *i, int direction, const struct iovec *iov, |
---|
| 229 | +void iov_iter_init(struct iov_iter *i, unsigned int direction, const struct iovec *iov, |
---|
185 | 230 | unsigned long nr_segs, size_t count); |
---|
186 | | -void iov_iter_kvec(struct iov_iter *i, int direction, const struct kvec *kvec, |
---|
| 231 | +void iov_iter_kvec(struct iov_iter *i, unsigned int direction, const struct kvec *kvec, |
---|
187 | 232 | unsigned long nr_segs, size_t count); |
---|
188 | | -void iov_iter_bvec(struct iov_iter *i, int direction, const struct bio_vec *bvec, |
---|
| 233 | +void iov_iter_bvec(struct iov_iter *i, unsigned int direction, const struct bio_vec *bvec, |
---|
189 | 234 | unsigned long nr_segs, size_t count); |
---|
190 | | -void iov_iter_pipe(struct iov_iter *i, int direction, struct pipe_inode_info *pipe, |
---|
| 235 | +void iov_iter_pipe(struct iov_iter *i, unsigned int direction, struct pipe_inode_info *pipe, |
---|
191 | 236 | size_t count); |
---|
| 237 | +void iov_iter_discard(struct iov_iter *i, unsigned int direction, size_t count); |
---|
192 | 238 | ssize_t iov_iter_get_pages(struct iov_iter *i, struct page **pages, |
---|
193 | 239 | size_t maxsize, unsigned maxpages, size_t *start); |
---|
194 | 240 | ssize_t iov_iter_get_pages_alloc(struct iov_iter *i, struct page ***pages, |
---|
195 | 241 | size_t maxsize, size_t *start); |
---|
196 | 242 | int iov_iter_npages(const struct iov_iter *i, int maxpages); |
---|
| 243 | +void iov_iter_restore(struct iov_iter *i, struct iov_iter_state *state); |
---|
197 | 244 | |
---|
198 | 245 | const void *dup_iter(struct iov_iter *new, struct iov_iter *old, gfp_t flags); |
---|
199 | 246 | |
---|
.. | .. |
---|
201 | 248 | { |
---|
202 | 249 | return i->count; |
---|
203 | 250 | } |
---|
204 | | - |
---|
205 | | -static inline bool iter_is_iovec(const struct iov_iter *i) |
---|
206 | | -{ |
---|
207 | | - return !(i->type & (ITER_BVEC | ITER_KVEC | ITER_PIPE)); |
---|
208 | | -} |
---|
209 | | - |
---|
210 | | -/* |
---|
211 | | - * Get one of READ or WRITE out of iter->type without any other flags OR'd in |
---|
212 | | - * with it. |
---|
213 | | - * |
---|
214 | | - * The ?: is just for type safety. |
---|
215 | | - */ |
---|
216 | | -#define iov_iter_rw(i) ((0 ? (struct iov_iter *)0 : (i))->type & (READ | WRITE)) |
---|
217 | 251 | |
---|
218 | 252 | /* |
---|
219 | 253 | * Cap the iov_iter by given limit; note that the second argument is |
---|
.. | .. |
---|
241 | 275 | { |
---|
242 | 276 | i->count = count; |
---|
243 | 277 | } |
---|
244 | | -size_t csum_and_copy_to_iter(const void *addr, size_t bytes, __wsum *csum, struct iov_iter *i); |
---|
| 278 | + |
---|
| 279 | +struct csum_state { |
---|
| 280 | + __wsum csum; |
---|
| 281 | + size_t off; |
---|
| 282 | +}; |
---|
| 283 | + |
---|
| 284 | +size_t csum_and_copy_to_iter(const void *addr, size_t bytes, void *csstate, struct iov_iter *i); |
---|
245 | 285 | size_t csum_and_copy_from_iter(void *addr, size_t bytes, __wsum *csum, struct iov_iter *i); |
---|
246 | 286 | bool csum_and_copy_from_iter_full(void *addr, size_t bytes, __wsum *csum, struct iov_iter *i); |
---|
| 287 | +size_t hash_and_copy_to_iter(const void *addr, size_t bytes, void *hashp, |
---|
| 288 | + struct iov_iter *i); |
---|
247 | 289 | |
---|
248 | | -int import_iovec(int type, const struct iovec __user * uvector, |
---|
249 | | - unsigned nr_segs, unsigned fast_segs, |
---|
250 | | - struct iovec **iov, struct iov_iter *i); |
---|
251 | | - |
---|
252 | | -#ifdef CONFIG_COMPAT |
---|
253 | | -struct compat_iovec; |
---|
254 | | -int compat_import_iovec(int type, const struct compat_iovec __user * uvector, |
---|
255 | | - unsigned nr_segs, unsigned fast_segs, |
---|
256 | | - struct iovec **iov, struct iov_iter *i); |
---|
257 | | -#endif |
---|
258 | | - |
---|
| 290 | +struct iovec *iovec_from_user(const struct iovec __user *uvector, |
---|
| 291 | + unsigned long nr_segs, unsigned long fast_segs, |
---|
| 292 | + struct iovec *fast_iov, bool compat); |
---|
| 293 | +ssize_t import_iovec(int type, const struct iovec __user *uvec, |
---|
| 294 | + unsigned nr_segs, unsigned fast_segs, struct iovec **iovp, |
---|
| 295 | + struct iov_iter *i); |
---|
| 296 | +ssize_t __import_iovec(int type, const struct iovec __user *uvec, |
---|
| 297 | + unsigned nr_segs, unsigned fast_segs, struct iovec **iovp, |
---|
| 298 | + struct iov_iter *i, bool compat); |
---|
259 | 299 | int import_single_range(int type, void __user *buf, size_t len, |
---|
260 | 300 | struct iovec *iov, struct iov_iter *i); |
---|
261 | 301 | |
---|