uverbs_ioctl.h 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637
  1. /*
  2. * Copyright (c) 2017, Mellanox Technologies inc. All rights reserved.
  3. *
  4. * This software is available to you under a choice of one of two
  5. * licenses. You may choose to be licensed under the terms of the GNU
  6. * General Public License (GPL) Version 2, available from the file
  7. * COPYING in the main directory of this source tree, or the
  8. * OpenIB.org BSD license below:
  9. *
  10. * Redistribution and use in source and binary forms, with or
  11. * without modification, are permitted provided that the following
  12. * conditions are met:
  13. *
  14. * - Redistributions of source code must retain the above
  15. * copyright notice, this list of conditions and the following
  16. * disclaimer.
  17. *
  18. * - Redistributions in binary form must reproduce the above
  19. * copyright notice, this list of conditions and the following
  20. * disclaimer in the documentation and/or other materials
  21. * provided with the distribution.
  22. *
  23. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  24. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  25. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  26. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  27. * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  28. * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  29. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  30. * SOFTWARE.
  31. */
  32. #ifndef _UVERBS_IOCTL_
  33. #define _UVERBS_IOCTL_
  34. #include <rdma/uverbs_types.h>
  35. #include <linux/uaccess.h>
  36. #include <rdma/rdma_user_ioctl.h>
  37. #include <rdma/ib_user_ioctl_verbs.h>
  38. #include <rdma/ib_user_ioctl_cmds.h>
  39. /*
  40. * =======================================
  41. * Verbs action specifications
  42. * =======================================
  43. */
  44. enum uverbs_attr_type {
  45. UVERBS_ATTR_TYPE_NA,
  46. UVERBS_ATTR_TYPE_PTR_IN,
  47. UVERBS_ATTR_TYPE_PTR_OUT,
  48. UVERBS_ATTR_TYPE_IDR,
  49. UVERBS_ATTR_TYPE_FD,
  50. UVERBS_ATTR_TYPE_ENUM_IN,
  51. };
  52. enum uverbs_obj_access {
  53. UVERBS_ACCESS_READ,
  54. UVERBS_ACCESS_WRITE,
  55. UVERBS_ACCESS_NEW,
  56. UVERBS_ACCESS_DESTROY
  57. };
  58. /* Specification of a single attribute inside the ioctl message */
  59. /* good size 16 */
  60. struct uverbs_attr_spec {
  61. u8 type;
  62. /*
  63. * Support extending attributes by length. Allow the user to provide
  64. * more bytes than ptr.len, but check that everything after is zero'd
  65. * by the user.
  66. */
  67. u8 zero_trailing:1;
  68. /*
  69. * Valid only for PTR_IN. Allocate and copy the data inside
  70. * the parser
  71. */
  72. u8 alloc_and_copy:1;
  73. u8 mandatory:1;
  74. union {
  75. struct {
  76. /* Current known size to kernel */
  77. u16 len;
  78. /* User isn't allowed to provide something < min_len */
  79. u16 min_len;
  80. } ptr;
  81. struct {
  82. /*
  83. * higher bits mean the namespace and lower bits mean
  84. * the type id within the namespace.
  85. */
  86. u16 obj_type;
  87. u8 access;
  88. } obj;
  89. struct {
  90. u8 num_elems;
  91. } enum_def;
  92. } u;
  93. /* This weird split of the enum lets us remove some padding */
  94. union {
  95. struct {
  96. /*
  97. * The enum attribute can select one of the attributes
  98. * contained in the ids array. Currently only PTR_IN
  99. * attributes are supported in the ids array.
  100. */
  101. const struct uverbs_attr_spec *ids;
  102. } enum_def;
  103. } u2;
  104. };
  105. /*
  106. * Information about the API is loaded into a radix tree. For IOCTL we start
  107. * with a tuple of:
  108. * object_id, attr_id, method_id
  109. *
  110. * Which is a 48 bit value, with most of the bits guaranteed to be zero. Based
  111. * on the current kernel support this is compressed into 16 bit key for the
  112. * radix tree. Since this compression is entirely internal to the kernel the
  113. * below limits can be revised if the kernel gains additional data.
  114. *
  115. * With 64 leafs per node this is a 3 level radix tree.
  116. *
  117. * The tree encodes multiple types, and uses a scheme where OBJ_ID,0,0 returns
  118. * the object slot, and OBJ_ID,METH_ID,0 and returns the method slot.
  119. */
  120. enum uapi_radix_data {
  121. UVERBS_API_NS_FLAG = 1U << UVERBS_ID_NS_SHIFT,
  122. UVERBS_API_ATTR_KEY_BITS = 6,
  123. UVERBS_API_ATTR_KEY_MASK = GENMASK(UVERBS_API_ATTR_KEY_BITS - 1, 0),
  124. UVERBS_API_ATTR_BKEY_LEN = (1 << UVERBS_API_ATTR_KEY_BITS) - 1,
  125. UVERBS_API_METHOD_KEY_BITS = 5,
  126. UVERBS_API_METHOD_KEY_SHIFT = UVERBS_API_ATTR_KEY_BITS,
  127. UVERBS_API_METHOD_KEY_NUM_CORE = 24,
  128. UVERBS_API_METHOD_KEY_NUM_DRIVER = (1 << UVERBS_API_METHOD_KEY_BITS) -
  129. UVERBS_API_METHOD_KEY_NUM_CORE,
  130. UVERBS_API_METHOD_KEY_MASK = GENMASK(
  131. UVERBS_API_METHOD_KEY_BITS + UVERBS_API_METHOD_KEY_SHIFT - 1,
  132. UVERBS_API_METHOD_KEY_SHIFT),
  133. UVERBS_API_OBJ_KEY_BITS = 5,
  134. UVERBS_API_OBJ_KEY_SHIFT =
  135. UVERBS_API_METHOD_KEY_BITS + UVERBS_API_METHOD_KEY_SHIFT,
  136. UVERBS_API_OBJ_KEY_NUM_CORE = 24,
  137. UVERBS_API_OBJ_KEY_NUM_DRIVER =
  138. (1 << UVERBS_API_OBJ_KEY_BITS) - UVERBS_API_OBJ_KEY_NUM_CORE,
  139. UVERBS_API_OBJ_KEY_MASK = GENMASK(31, UVERBS_API_OBJ_KEY_SHIFT),
  140. /* This id guaranteed to not exist in the radix tree */
  141. UVERBS_API_KEY_ERR = 0xFFFFFFFF,
  142. };
  143. static inline __attribute_const__ u32 uapi_key_obj(u32 id)
  144. {
  145. if (id & UVERBS_API_NS_FLAG) {
  146. id &= ~UVERBS_API_NS_FLAG;
  147. if (id >= UVERBS_API_OBJ_KEY_NUM_DRIVER)
  148. return UVERBS_API_KEY_ERR;
  149. id = id + UVERBS_API_OBJ_KEY_NUM_CORE;
  150. } else {
  151. if (id >= UVERBS_API_OBJ_KEY_NUM_CORE)
  152. return UVERBS_API_KEY_ERR;
  153. }
  154. return id << UVERBS_API_OBJ_KEY_SHIFT;
  155. }
  156. static inline __attribute_const__ bool uapi_key_is_object(u32 key)
  157. {
  158. return (key & ~UVERBS_API_OBJ_KEY_MASK) == 0;
  159. }
  160. static inline __attribute_const__ u32 uapi_key_ioctl_method(u32 id)
  161. {
  162. if (id & UVERBS_API_NS_FLAG) {
  163. id &= ~UVERBS_API_NS_FLAG;
  164. if (id >= UVERBS_API_METHOD_KEY_NUM_DRIVER)
  165. return UVERBS_API_KEY_ERR;
  166. id = id + UVERBS_API_METHOD_KEY_NUM_CORE;
  167. } else {
  168. id++;
  169. if (id >= UVERBS_API_METHOD_KEY_NUM_CORE)
  170. return UVERBS_API_KEY_ERR;
  171. }
  172. return id << UVERBS_API_METHOD_KEY_SHIFT;
  173. }
  174. static inline __attribute_const__ u32 uapi_key_attr_to_method(u32 attr_key)
  175. {
  176. return attr_key &
  177. (UVERBS_API_OBJ_KEY_MASK | UVERBS_API_METHOD_KEY_MASK);
  178. }
  179. static inline __attribute_const__ bool uapi_key_is_ioctl_method(u32 key)
  180. {
  181. return (key & UVERBS_API_METHOD_KEY_MASK) != 0 &&
  182. (key & UVERBS_API_ATTR_KEY_MASK) == 0;
  183. }
  184. static inline __attribute_const__ u32 uapi_key_attrs_start(u32 ioctl_method_key)
  185. {
  186. /* 0 is the method slot itself */
  187. return ioctl_method_key + 1;
  188. }
  189. static inline __attribute_const__ u32 uapi_key_attr(u32 id)
  190. {
  191. /*
  192. * The attr is designed to fit in the typical single radix tree node
  193. * of 64 entries. Since allmost all methods have driver attributes we
  194. * organize things so that the driver and core attributes interleave to
  195. * reduce the length of the attributes array in typical cases.
  196. */
  197. if (id & UVERBS_API_NS_FLAG) {
  198. id &= ~UVERBS_API_NS_FLAG;
  199. id++;
  200. if (id >= 1 << (UVERBS_API_ATTR_KEY_BITS - 1))
  201. return UVERBS_API_KEY_ERR;
  202. id = (id << 1) | 0;
  203. } else {
  204. if (id >= 1 << (UVERBS_API_ATTR_KEY_BITS - 1))
  205. return UVERBS_API_KEY_ERR;
  206. id = (id << 1) | 1;
  207. }
  208. return id;
  209. }
  210. static inline __attribute_const__ bool uapi_key_is_attr(u32 key)
  211. {
  212. return (key & UVERBS_API_METHOD_KEY_MASK) != 0 &&
  213. (key & UVERBS_API_ATTR_KEY_MASK) != 0;
  214. }
  215. /*
  216. * This returns a value in the range [0 to UVERBS_API_ATTR_BKEY_LEN),
  217. * basically it undoes the reservation of 0 in the ID numbering. attr_key
  218. * must already be masked with UVERBS_API_ATTR_KEY_MASK, or be the output of
  219. * uapi_key_attr().
  220. */
  221. static inline __attribute_const__ u32 uapi_bkey_attr(u32 attr_key)
  222. {
  223. return attr_key - 1;
  224. }
  225. /*
  226. * =======================================
  227. * Verbs definitions
  228. * =======================================
  229. */
  230. struct uverbs_attr_def {
  231. u16 id;
  232. struct uverbs_attr_spec attr;
  233. };
  234. struct uverbs_method_def {
  235. u16 id;
  236. /* Combination of bits from enum UVERBS_ACTION_FLAG_XXXX */
  237. u32 flags;
  238. size_t num_attrs;
  239. const struct uverbs_attr_def * const (*attrs)[];
  240. int (*handler)(struct ib_uverbs_file *ufile,
  241. struct uverbs_attr_bundle *ctx);
  242. };
  243. struct uverbs_object_def {
  244. u16 id;
  245. const struct uverbs_obj_type *type_attrs;
  246. size_t num_methods;
  247. const struct uverbs_method_def * const (*methods)[];
  248. };
  249. struct uverbs_object_tree_def {
  250. size_t num_objects;
  251. const struct uverbs_object_def * const (*objects)[];
  252. };
  253. /*
  254. * =======================================
  255. * Attribute Specifications
  256. * =======================================
  257. */
  258. #define UVERBS_ATTR_SIZE(_min_len, _len) \
  259. .u.ptr.min_len = _min_len, .u.ptr.len = _len
  260. #define UVERBS_ATTR_NO_DATA() UVERBS_ATTR_SIZE(0, 0)
  261. /*
  262. * Specifies a uapi structure that cannot be extended. The user must always
  263. * supply the whole structure and nothing more. The structure must be declared
  264. * in a header under include/uapi/rdma.
  265. */
  266. #define UVERBS_ATTR_TYPE(_type) \
  267. .u.ptr.min_len = sizeof(_type), .u.ptr.len = sizeof(_type)
  268. /*
  269. * Specifies a uapi structure where the user must provide at least up to
  270. * member 'last'. Anything after last and up until the end of the structure
  271. * can be non-zero, anything longer than the end of the structure must be
  272. * zero. The structure must be declared in a header under include/uapi/rdma.
  273. */
  274. #define UVERBS_ATTR_STRUCT(_type, _last) \
  275. .zero_trailing = 1, \
  276. UVERBS_ATTR_SIZE(((uintptr_t)(&((_type *)0)->_last + 1)), \
  277. sizeof(_type))
  278. /*
  279. * Specifies at least min_len bytes must be passed in, but the amount can be
  280. * larger, up to the protocol maximum size. No check for zeroing is done.
  281. */
  282. #define UVERBS_ATTR_MIN_SIZE(_min_len) UVERBS_ATTR_SIZE(_min_len, USHRT_MAX)
  283. /* Must be used in the '...' of any UVERBS_ATTR */
  284. #define UA_ALLOC_AND_COPY .alloc_and_copy = 1
  285. #define UA_MANDATORY .mandatory = 1
  286. #define UA_OPTIONAL .mandatory = 0
  287. #define UVERBS_ATTR_IDR(_attr_id, _idr_type, _access, ...) \
  288. (&(const struct uverbs_attr_def){ \
  289. .id = _attr_id, \
  290. .attr = { .type = UVERBS_ATTR_TYPE_IDR, \
  291. .u.obj.obj_type = _idr_type, \
  292. .u.obj.access = _access, \
  293. __VA_ARGS__ } })
  294. #define UVERBS_ATTR_FD(_attr_id, _fd_type, _access, ...) \
  295. (&(const struct uverbs_attr_def){ \
  296. .id = (_attr_id) + \
  297. BUILD_BUG_ON_ZERO((_access) != UVERBS_ACCESS_NEW && \
  298. (_access) != UVERBS_ACCESS_READ), \
  299. .attr = { .type = UVERBS_ATTR_TYPE_FD, \
  300. .u.obj.obj_type = _fd_type, \
  301. .u.obj.access = _access, \
  302. __VA_ARGS__ } })
  303. #define UVERBS_ATTR_PTR_IN(_attr_id, _type, ...) \
  304. (&(const struct uverbs_attr_def){ \
  305. .id = _attr_id, \
  306. .attr = { .type = UVERBS_ATTR_TYPE_PTR_IN, \
  307. _type, \
  308. __VA_ARGS__ } })
  309. #define UVERBS_ATTR_PTR_OUT(_attr_id, _type, ...) \
  310. (&(const struct uverbs_attr_def){ \
  311. .id = _attr_id, \
  312. .attr = { .type = UVERBS_ATTR_TYPE_PTR_OUT, \
  313. _type, \
  314. __VA_ARGS__ } })
  315. /* _enum_arry should be a 'static const union uverbs_attr_spec[]' */
  316. #define UVERBS_ATTR_ENUM_IN(_attr_id, _enum_arr, ...) \
  317. (&(const struct uverbs_attr_def){ \
  318. .id = _attr_id, \
  319. .attr = { .type = UVERBS_ATTR_TYPE_ENUM_IN, \
  320. .u2.enum_def.ids = _enum_arr, \
  321. .u.enum_def.num_elems = ARRAY_SIZE(_enum_arr), \
  322. __VA_ARGS__ }, \
  323. })
  324. /*
  325. * An input value that is a bitwise combination of values of _enum_type.
  326. * This permits the flag value to be passed as either a u32 or u64, it must
  327. * be retrieved via uverbs_get_flag().
  328. */
  329. #define UVERBS_ATTR_FLAGS_IN(_attr_id, _enum_type, ...) \
  330. UVERBS_ATTR_PTR_IN( \
  331. _attr_id, \
  332. UVERBS_ATTR_SIZE(sizeof(u32) + BUILD_BUG_ON_ZERO( \
  333. !sizeof(_enum_type *)), \
  334. sizeof(u64)), \
  335. __VA_ARGS__)
  336. /*
  337. * This spec is used in order to pass information to the hardware driver in a
  338. * legacy way. Every verb that could get driver specific data should get this
  339. * spec.
  340. */
  341. #define UVERBS_ATTR_UHW() \
  342. UVERBS_ATTR_PTR_IN(UVERBS_ATTR_UHW_IN, \
  343. UVERBS_ATTR_MIN_SIZE(0), \
  344. UA_OPTIONAL), \
  345. UVERBS_ATTR_PTR_OUT(UVERBS_ATTR_UHW_OUT, \
  346. UVERBS_ATTR_MIN_SIZE(0), \
  347. UA_OPTIONAL)
  348. /*
  349. * =======================================
  350. * Declaration helpers
  351. * =======================================
  352. */
  353. #define DECLARE_UVERBS_OBJECT_TREE(_name, ...) \
  354. static const struct uverbs_object_def *const _name##_ptr[] = { \
  355. __VA_ARGS__, \
  356. }; \
  357. static const struct uverbs_object_tree_def _name = { \
  358. .num_objects = ARRAY_SIZE(_name##_ptr), \
  359. .objects = &_name##_ptr, \
  360. }
  361. /* =================================================
  362. * Parsing infrastructure
  363. * =================================================
  364. */
  365. struct uverbs_ptr_attr {
  366. /*
  367. * If UVERBS_ATTR_SPEC_F_ALLOC_AND_COPY is set then the 'ptr' is
  368. * used.
  369. */
  370. union {
  371. void *ptr;
  372. u64 data;
  373. };
  374. u16 len;
  375. u16 uattr_idx;
  376. u8 enum_id;
  377. };
  378. struct uverbs_obj_attr {
  379. struct ib_uobject *uobject;
  380. const struct uverbs_api_attr *attr_elm;
  381. };
  382. struct uverbs_attr {
  383. union {
  384. struct uverbs_ptr_attr ptr_attr;
  385. struct uverbs_obj_attr obj_attr;
  386. };
  387. };
  388. struct uverbs_attr_bundle {
  389. struct ib_uverbs_file *ufile;
  390. DECLARE_BITMAP(attr_present, UVERBS_API_ATTR_BKEY_LEN);
  391. struct uverbs_attr attrs[];
  392. };
  393. static inline bool uverbs_attr_is_valid(const struct uverbs_attr_bundle *attrs_bundle,
  394. unsigned int idx)
  395. {
  396. return test_bit(uapi_bkey_attr(uapi_key_attr(idx)),
  397. attrs_bundle->attr_present);
  398. }
  399. #define IS_UVERBS_COPY_ERR(_ret) ((_ret) && (_ret) != -ENOENT)
  400. static inline const struct uverbs_attr *uverbs_attr_get(const struct uverbs_attr_bundle *attrs_bundle,
  401. u16 idx)
  402. {
  403. if (!uverbs_attr_is_valid(attrs_bundle, idx))
  404. return ERR_PTR(-ENOENT);
  405. return &attrs_bundle->attrs[uapi_bkey_attr(uapi_key_attr(idx))];
  406. }
  407. static inline int uverbs_attr_get_enum_id(const struct uverbs_attr_bundle *attrs_bundle,
  408. u16 idx)
  409. {
  410. const struct uverbs_attr *attr = uverbs_attr_get(attrs_bundle, idx);
  411. if (IS_ERR(attr))
  412. return PTR_ERR(attr);
  413. return attr->ptr_attr.enum_id;
  414. }
  415. static inline void *uverbs_attr_get_obj(const struct uverbs_attr_bundle *attrs_bundle,
  416. u16 idx)
  417. {
  418. const struct uverbs_attr *attr;
  419. attr = uverbs_attr_get(attrs_bundle, idx);
  420. if (IS_ERR(attr))
  421. return ERR_CAST(attr);
  422. return attr->obj_attr.uobject->object;
  423. }
  424. static inline struct ib_uobject *uverbs_attr_get_uobject(const struct uverbs_attr_bundle *attrs_bundle,
  425. u16 idx)
  426. {
  427. const struct uverbs_attr *attr = uverbs_attr_get(attrs_bundle, idx);
  428. if (IS_ERR(attr))
  429. return ERR_CAST(attr);
  430. return attr->obj_attr.uobject;
  431. }
  432. static inline int
  433. uverbs_attr_get_len(const struct uverbs_attr_bundle *attrs_bundle, u16 idx)
  434. {
  435. const struct uverbs_attr *attr = uverbs_attr_get(attrs_bundle, idx);
  436. if (IS_ERR(attr))
  437. return PTR_ERR(attr);
  438. return attr->ptr_attr.len;
  439. }
  440. static inline bool uverbs_attr_ptr_is_inline(const struct uverbs_attr *attr)
  441. {
  442. return attr->ptr_attr.len <= sizeof(attr->ptr_attr.data);
  443. }
  444. static inline void *uverbs_attr_get_alloced_ptr(
  445. const struct uverbs_attr_bundle *attrs_bundle, u16 idx)
  446. {
  447. const struct uverbs_attr *attr = uverbs_attr_get(attrs_bundle, idx);
  448. if (IS_ERR(attr))
  449. return (void *)attr;
  450. return uverbs_attr_ptr_is_inline(attr) ? (void *)&attr->ptr_attr.data :
  451. attr->ptr_attr.ptr;
  452. }
  453. static inline int _uverbs_copy_from(void *to,
  454. const struct uverbs_attr_bundle *attrs_bundle,
  455. size_t idx,
  456. size_t size)
  457. {
  458. const struct uverbs_attr *attr = uverbs_attr_get(attrs_bundle, idx);
  459. if (IS_ERR(attr))
  460. return PTR_ERR(attr);
  461. /*
  462. * Validation ensures attr->ptr_attr.len >= size. If the caller is
  463. * using UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO then it must call
  464. * uverbs_copy_from_or_zero.
  465. */
  466. if (unlikely(size < attr->ptr_attr.len))
  467. return -EINVAL;
  468. if (uverbs_attr_ptr_is_inline(attr))
  469. memcpy(to, &attr->ptr_attr.data, attr->ptr_attr.len);
  470. else if (copy_from_user(to, u64_to_user_ptr(attr->ptr_attr.data),
  471. attr->ptr_attr.len))
  472. return -EFAULT;
  473. return 0;
  474. }
  475. static inline int _uverbs_copy_from_or_zero(void *to,
  476. const struct uverbs_attr_bundle *attrs_bundle,
  477. size_t idx,
  478. size_t size)
  479. {
  480. const struct uverbs_attr *attr = uverbs_attr_get(attrs_bundle, idx);
  481. size_t min_size;
  482. if (IS_ERR(attr))
  483. return PTR_ERR(attr);
  484. min_size = min_t(size_t, size, attr->ptr_attr.len);
  485. if (uverbs_attr_ptr_is_inline(attr))
  486. memcpy(to, &attr->ptr_attr.data, min_size);
  487. else if (copy_from_user(to, u64_to_user_ptr(attr->ptr_attr.data),
  488. min_size))
  489. return -EFAULT;
  490. if (size > min_size)
  491. memset(to + min_size, 0, size - min_size);
  492. return 0;
  493. }
  494. #define uverbs_copy_from(to, attrs_bundle, idx) \
  495. _uverbs_copy_from(to, attrs_bundle, idx, sizeof(*to))
  496. #define uverbs_copy_from_or_zero(to, attrs_bundle, idx) \
  497. _uverbs_copy_from_or_zero(to, attrs_bundle, idx, sizeof(*to))
  498. #if IS_ENABLED(CONFIG_INFINIBAND_USER_ACCESS)
  499. int uverbs_get_flags64(u64 *to, const struct uverbs_attr_bundle *attrs_bundle,
  500. size_t idx, u64 allowed_bits);
  501. int uverbs_get_flags32(u32 *to, const struct uverbs_attr_bundle *attrs_bundle,
  502. size_t idx, u64 allowed_bits);
  503. int uverbs_copy_to(const struct uverbs_attr_bundle *attrs_bundle, size_t idx,
  504. const void *from, size_t size);
  505. __malloc void *_uverbs_alloc(struct uverbs_attr_bundle *bundle, size_t size,
  506. gfp_t flags);
  507. static inline __malloc void *uverbs_alloc(struct uverbs_attr_bundle *bundle,
  508. size_t size)
  509. {
  510. return _uverbs_alloc(bundle, size, GFP_KERNEL);
  511. }
  512. static inline __malloc void *uverbs_zalloc(struct uverbs_attr_bundle *bundle,
  513. size_t size)
  514. {
  515. return _uverbs_alloc(bundle, size, GFP_KERNEL | __GFP_ZERO);
  516. }
  517. #else
  518. static inline int
  519. uverbs_get_flags64(u64 *to, const struct uverbs_attr_bundle *attrs_bundle,
  520. size_t idx, u64 allowed_bits)
  521. {
  522. return -EINVAL;
  523. }
  524. static inline int
  525. uverbs_get_flags32(u32 *to, const struct uverbs_attr_bundle *attrs_bundle,
  526. size_t idx, u64 allowed_bits)
  527. {
  528. return -EINVAL;
  529. }
  530. static inline int uverbs_copy_to(const struct uverbs_attr_bundle *attrs_bundle,
  531. size_t idx, const void *from, size_t size)
  532. {
  533. return -EINVAL;
  534. }
  535. static inline __malloc void *uverbs_alloc(struct uverbs_attr_bundle *bundle,
  536. size_t size)
  537. {
  538. return ERR_PTR(-EINVAL);
  539. }
  540. static inline __malloc void *uverbs_zalloc(struct uverbs_attr_bundle *bundle,
  541. size_t size)
  542. {
  543. return ERR_PTR(-EINVAL);
  544. }
  545. #endif
  546. #endif