uverbs_ioctl_merge.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665
  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. #include <rdma/uverbs_ioctl.h>
  33. #include <rdma/rdma_user_ioctl.h>
  34. #include <linux/bitops.h>
  35. #include "uverbs.h"
  36. #define UVERBS_NUM_NS (UVERBS_ID_NS_MASK >> UVERBS_ID_NS_SHIFT)
  37. #define GET_NS_ID(idx) (((idx) & UVERBS_ID_NS_MASK) >> UVERBS_ID_NS_SHIFT)
  38. #define GET_ID(idx) ((idx) & ~UVERBS_ID_NS_MASK)
  39. #define _for_each_element(elem, tmpi, tmpj, hashes, num_buckets_offset, \
  40. buckets_offset) \
  41. for (tmpj = 0, \
  42. elem = (*(const void ***)((hashes)[tmpi] + \
  43. (buckets_offset)))[0]; \
  44. tmpj < *(size_t *)((hashes)[tmpi] + (num_buckets_offset)); \
  45. tmpj++) \
  46. if ((elem = ((*(const void ***)(hashes[tmpi] + \
  47. (buckets_offset)))[tmpj])))
  48. /*
  49. * Iterate all elements of a few @hashes. The number of given hashes is
  50. * indicated by @num_hashes. The offset of the number of buckets in the hash is
  51. * represented by @num_buckets_offset, while the offset of the buckets array in
  52. * the hash structure is represented by @buckets_offset. tmpi and tmpj are two
  53. * short (or int) based indices that are given by the user. tmpi iterates over
  54. * the different hashes. @elem points the current element in the hashes[tmpi]
  55. * bucket we are looping on. To be honest, @hashes representation isn't exactly
  56. * a hash, but more a collection of elements. These elements' ids are treated
  57. * in a hash like manner, where the first upper bits are the bucket number.
  58. * These elements are later mapped into a perfect-hash.
  59. */
  60. #define for_each_element(elem, tmpi, tmpj, hashes, num_hashes, \
  61. num_buckets_offset, buckets_offset) \
  62. for (tmpi = 0; tmpi < (num_hashes); tmpi++) \
  63. _for_each_element(elem, tmpi, tmpj, hashes, num_buckets_offset,\
  64. buckets_offset)
  65. #define get_elements_iterators_entry_above(iters, num_elements, elements, \
  66. num_objects_fld, objects_fld, bucket,\
  67. min_id) \
  68. get_elements_above_id((const void **)iters, num_elements, \
  69. (const void **)(elements), \
  70. offsetof(typeof(**elements), \
  71. num_objects_fld), \
  72. offsetof(typeof(**elements), objects_fld),\
  73. offsetof(typeof(***(*elements)->objects_fld), id),\
  74. bucket, min_id)
  75. #define get_objects_above_id(iters, num_trees, trees, bucket, min_id) \
  76. get_elements_iterators_entry_above(iters, num_trees, trees, \
  77. num_objects, objects, bucket, min_id)
  78. #define get_methods_above_id(method_iters, num_iters, iters, bucket, min_id)\
  79. get_elements_iterators_entry_above(method_iters, num_iters, iters, \
  80. num_methods, methods, bucket, min_id)
  81. #define get_attrs_above_id(attrs_iters, num_iters, iters, bucket, min_id)\
  82. get_elements_iterators_entry_above(attrs_iters, num_iters, iters, \
  83. num_attrs, attrs, bucket, min_id)
  84. /*
  85. * get_elements_above_id get a few hashes represented by @elements and
  86. * @num_elements. The hashes fields are described by @num_offset, @data_offset
  87. * and @id_offset in the same way as required by for_each_element. The function
  88. * returns an array of @iters, represents an array of elements in the hashes
  89. * buckets, which their ids are the smallest ids in all hashes but are all
  90. * larger than the id given by min_id. Elements are only added to the iters
  91. * array if their id belongs to the bucket @bucket. The number of elements in
  92. * the returned array is returned by the function. @min_id is also updated to
  93. * reflect the new min_id of all elements in iters.
  94. */
  95. static size_t get_elements_above_id(const void **iters,
  96. unsigned int num_elements,
  97. const void **elements,
  98. size_t num_offset,
  99. size_t data_offset,
  100. size_t id_offset,
  101. u16 bucket,
  102. short *min_id)
  103. {
  104. size_t num_iters = 0;
  105. short min = SHRT_MAX;
  106. const void *elem;
  107. int i, j, last_stored = -1;
  108. unsigned int equal_min = 0;
  109. for_each_element(elem, i, j, elements, num_elements, num_offset,
  110. data_offset) {
  111. u16 id = *(u16 *)(elem + id_offset);
  112. if (GET_NS_ID(id) != bucket)
  113. continue;
  114. if (GET_ID(id) < *min_id ||
  115. (min != SHRT_MAX && GET_ID(id) > min))
  116. continue;
  117. /*
  118. * We first iterate all hashes represented by @elements. When
  119. * we do, we try to find an element @elem in the bucket @bucket
  120. * which its id is min. Since we can't ensure the user sorted
  121. * the elements in increasing order, we override this hash's
  122. * minimal id element we found, if a new element with a smaller
  123. * id was just found.
  124. */
  125. iters[last_stored == i ? num_iters - 1 : num_iters++] = elem;
  126. last_stored = i;
  127. if (min == GET_ID(id))
  128. equal_min++;
  129. else
  130. equal_min = 1;
  131. min = GET_ID(id);
  132. }
  133. /*
  134. * We only insert to our iters array an element, if its id is smaller
  135. * than all previous ids. Therefore, the final iters array is sorted so
  136. * that smaller ids are in the end of the array.
  137. * Therefore, we need to clean the beginning of the array to make sure
  138. * all ids of final elements are equal to min.
  139. */
  140. memmove(iters, iters + num_iters - equal_min, sizeof(*iters) * equal_min);
  141. *min_id = min;
  142. return equal_min;
  143. }
  144. #define find_max_element_entry_id(num_elements, elements, num_objects_fld, \
  145. objects_fld, bucket) \
  146. find_max_element_id(num_elements, (const void **)(elements), \
  147. offsetof(typeof(**elements), num_objects_fld), \
  148. offsetof(typeof(**elements), objects_fld), \
  149. offsetof(typeof(***(*elements)->objects_fld), id),\
  150. bucket)
  151. static short find_max_element_ns_id(unsigned int num_elements,
  152. const void **elements,
  153. size_t num_offset,
  154. size_t data_offset,
  155. size_t id_offset)
  156. {
  157. short max_ns = SHRT_MIN;
  158. const void *elem;
  159. int i, j;
  160. for_each_element(elem, i, j, elements, num_elements, num_offset,
  161. data_offset) {
  162. u16 id = *(u16 *)(elem + id_offset);
  163. if (GET_NS_ID(id) > max_ns)
  164. max_ns = GET_NS_ID(id);
  165. }
  166. return max_ns;
  167. }
  168. static short find_max_element_id(unsigned int num_elements,
  169. const void **elements,
  170. size_t num_offset,
  171. size_t data_offset,
  172. size_t id_offset,
  173. u16 bucket)
  174. {
  175. short max_id = SHRT_MIN;
  176. const void *elem;
  177. int i, j;
  178. for_each_element(elem, i, j, elements, num_elements, num_offset,
  179. data_offset) {
  180. u16 id = *(u16 *)(elem + id_offset);
  181. if (GET_NS_ID(id) == bucket &&
  182. GET_ID(id) > max_id)
  183. max_id = GET_ID(id);
  184. }
  185. return max_id;
  186. }
  187. #define find_max_element_entry_id(num_elements, elements, num_objects_fld, \
  188. objects_fld, bucket) \
  189. find_max_element_id(num_elements, (const void **)(elements), \
  190. offsetof(typeof(**elements), num_objects_fld), \
  191. offsetof(typeof(**elements), objects_fld), \
  192. offsetof(typeof(***(*elements)->objects_fld), id),\
  193. bucket)
  194. #define find_max_element_ns_entry_id(num_elements, elements, \
  195. num_objects_fld, objects_fld) \
  196. find_max_element_ns_id(num_elements, (const void **)(elements), \
  197. offsetof(typeof(**elements), num_objects_fld),\
  198. offsetof(typeof(**elements), objects_fld), \
  199. offsetof(typeof(***(*elements)->objects_fld), id))
  200. /*
  201. * find_max_xxxx_ns_id gets a few elements. Each element is described by an id
  202. * which its upper bits represents a namespace. It finds the max namespace. This
  203. * could be used in order to know how many buckets do we need to allocate. If no
  204. * elements exist, SHRT_MIN is returned. Namespace represents here different
  205. * buckets. The common example is "common bucket" and "driver bucket".
  206. *
  207. * find_max_xxxx_id gets a few elements and a bucket. Each element is described
  208. * by an id which its upper bits represent a namespace. It returns the max id
  209. * which is contained in the same namespace defined in @bucket. This could be
  210. * used in order to know how many elements do we need to allocate in the bucket.
  211. * If no elements exist, SHRT_MIN is returned.
  212. */
  213. #define find_max_object_id(num_trees, trees, bucket) \
  214. find_max_element_entry_id(num_trees, trees, num_objects,\
  215. objects, bucket)
  216. #define find_max_object_ns_id(num_trees, trees) \
  217. find_max_element_ns_entry_id(num_trees, trees, \
  218. num_objects, objects)
  219. #define find_max_method_id(num_iters, iters, bucket) \
  220. find_max_element_entry_id(num_iters, iters, num_methods,\
  221. methods, bucket)
  222. #define find_max_method_ns_id(num_iters, iters) \
  223. find_max_element_ns_entry_id(num_iters, iters, \
  224. num_methods, methods)
  225. #define find_max_attr_id(num_iters, iters, bucket) \
  226. find_max_element_entry_id(num_iters, iters, num_attrs, \
  227. attrs, bucket)
  228. #define find_max_attr_ns_id(num_iters, iters) \
  229. find_max_element_ns_entry_id(num_iters, iters, \
  230. num_attrs, attrs)
  231. static void free_method(struct uverbs_method_spec *method)
  232. {
  233. unsigned int i;
  234. if (!method)
  235. return;
  236. for (i = 0; i < method->num_buckets; i++)
  237. kfree(method->attr_buckets[i]);
  238. kfree(method);
  239. }
  240. #define IS_ATTR_OBJECT(attr) ((attr)->type == UVERBS_ATTR_TYPE_IDR || \
  241. (attr)->type == UVERBS_ATTR_TYPE_FD)
  242. /*
  243. * This function gets array of size @num_method_defs which contains pointers to
  244. * method definitions @method_defs. The function allocates an
  245. * uverbs_method_spec structure and initializes its number of buckets and the
  246. * elements in buckets to the correct attributes. While doing that, it
  247. * validates that there aren't conflicts between attributes of different
  248. * method_defs.
  249. */
  250. static struct uverbs_method_spec *build_method_with_attrs(const struct uverbs_method_def **method_defs,
  251. size_t num_method_defs)
  252. {
  253. int bucket_idx;
  254. int max_attr_buckets = 0;
  255. size_t num_attr_buckets = 0;
  256. int res = 0;
  257. struct uverbs_method_spec *method = NULL;
  258. const struct uverbs_attr_def **attr_defs;
  259. unsigned int num_of_singularities = 0;
  260. max_attr_buckets = find_max_attr_ns_id(num_method_defs, method_defs);
  261. if (max_attr_buckets >= 0)
  262. num_attr_buckets = max_attr_buckets + 1;
  263. method = kzalloc(sizeof(*method) +
  264. num_attr_buckets * sizeof(*method->attr_buckets),
  265. GFP_KERNEL);
  266. if (!method)
  267. return ERR_PTR(-ENOMEM);
  268. method->num_buckets = num_attr_buckets;
  269. attr_defs = kcalloc(num_method_defs, sizeof(*attr_defs), GFP_KERNEL);
  270. if (!attr_defs) {
  271. res = -ENOMEM;
  272. goto free_method;
  273. }
  274. for (bucket_idx = 0; bucket_idx < method->num_buckets; bucket_idx++) {
  275. short min_id = SHRT_MIN;
  276. int attr_max_bucket = 0;
  277. struct uverbs_attr_spec_hash *hash = NULL;
  278. attr_max_bucket = find_max_attr_id(num_method_defs, method_defs,
  279. bucket_idx);
  280. if (attr_max_bucket < 0)
  281. continue;
  282. hash = kzalloc(sizeof(*hash) +
  283. ALIGN(sizeof(*hash->attrs) * (attr_max_bucket + 1),
  284. sizeof(long)) +
  285. BITS_TO_LONGS(attr_max_bucket + 1) * sizeof(long),
  286. GFP_KERNEL);
  287. if (!hash) {
  288. res = -ENOMEM;
  289. goto free;
  290. }
  291. hash->num_attrs = attr_max_bucket + 1;
  292. method->num_child_attrs += hash->num_attrs;
  293. hash->mandatory_attrs_bitmask = (void *)(hash + 1) +
  294. ALIGN(sizeof(*hash->attrs) *
  295. (attr_max_bucket + 1),
  296. sizeof(long));
  297. method->attr_buckets[bucket_idx] = hash;
  298. do {
  299. size_t num_attr_defs;
  300. struct uverbs_attr_spec *attr;
  301. bool attr_obj_with_special_access;
  302. num_attr_defs =
  303. get_attrs_above_id(attr_defs,
  304. num_method_defs,
  305. method_defs,
  306. bucket_idx,
  307. &min_id);
  308. /* Last attr in bucket */
  309. if (!num_attr_defs)
  310. break;
  311. if (num_attr_defs > 1) {
  312. /*
  313. * We don't allow two attribute definitions for
  314. * the same attribute. This is usually a
  315. * programmer error. If required, it's better to
  316. * just add a new attribute to capture the new
  317. * semantics.
  318. */
  319. res = -EEXIST;
  320. goto free;
  321. }
  322. attr = &hash->attrs[min_id];
  323. memcpy(attr, &attr_defs[0]->attr, sizeof(*attr));
  324. attr_obj_with_special_access = IS_ATTR_OBJECT(attr) &&
  325. (attr->obj.access == UVERBS_ACCESS_NEW ||
  326. attr->obj.access == UVERBS_ACCESS_DESTROY);
  327. num_of_singularities += !!attr_obj_with_special_access;
  328. if (WARN(num_of_singularities > 1,
  329. "ib_uverbs: Method contains more than one object attr (%d) with new/destroy access\n",
  330. min_id) ||
  331. WARN(attr_obj_with_special_access &&
  332. !(attr->flags & UVERBS_ATTR_SPEC_F_MANDATORY),
  333. "ib_uverbs: Tried to merge attr (%d) but it's an object with new/destroy access but isn't mandatory\n",
  334. min_id) ||
  335. WARN(IS_ATTR_OBJECT(attr) &&
  336. attr->flags & UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO,
  337. "ib_uverbs: Tried to merge attr (%d) but it's an object with min_sz flag\n",
  338. min_id)) {
  339. res = -EINVAL;
  340. goto free;
  341. }
  342. if (attr->flags & UVERBS_ATTR_SPEC_F_MANDATORY)
  343. set_bit(min_id, hash->mandatory_attrs_bitmask);
  344. min_id++;
  345. } while (1);
  346. }
  347. kfree(attr_defs);
  348. return method;
  349. free:
  350. kfree(attr_defs);
  351. free_method:
  352. free_method(method);
  353. return ERR_PTR(res);
  354. }
  355. static void free_object(struct uverbs_object_spec *object)
  356. {
  357. unsigned int i, j;
  358. if (!object)
  359. return;
  360. for (i = 0; i < object->num_buckets; i++) {
  361. struct uverbs_method_spec_hash *method_buckets =
  362. object->method_buckets[i];
  363. if (!method_buckets)
  364. continue;
  365. for (j = 0; j < method_buckets->num_methods; j++)
  366. free_method(method_buckets->methods[j]);
  367. kfree(method_buckets);
  368. }
  369. kfree(object);
  370. }
  371. /*
  372. * This function gets array of size @num_object_defs which contains pointers to
  373. * object definitions @object_defs. The function allocated an
  374. * uverbs_object_spec structure and initialize its number of buckets and the
  375. * elements in buckets to the correct methods. While doing that, it
  376. * sorts out the correct relationship between conflicts in the same method.
  377. */
  378. static struct uverbs_object_spec *build_object_with_methods(const struct uverbs_object_def **object_defs,
  379. size_t num_object_defs)
  380. {
  381. u16 bucket_idx;
  382. int max_method_buckets = 0;
  383. u16 num_method_buckets = 0;
  384. int res = 0;
  385. struct uverbs_object_spec *object = NULL;
  386. const struct uverbs_method_def **method_defs;
  387. max_method_buckets = find_max_method_ns_id(num_object_defs, object_defs);
  388. if (max_method_buckets >= 0)
  389. num_method_buckets = max_method_buckets + 1;
  390. object = kzalloc(sizeof(*object) +
  391. num_method_buckets *
  392. sizeof(*object->method_buckets), GFP_KERNEL);
  393. if (!object)
  394. return ERR_PTR(-ENOMEM);
  395. object->num_buckets = num_method_buckets;
  396. method_defs = kcalloc(num_object_defs, sizeof(*method_defs), GFP_KERNEL);
  397. if (!method_defs) {
  398. res = -ENOMEM;
  399. goto free_object;
  400. }
  401. for (bucket_idx = 0; bucket_idx < object->num_buckets; bucket_idx++) {
  402. short min_id = SHRT_MIN;
  403. int methods_max_bucket = 0;
  404. struct uverbs_method_spec_hash *hash = NULL;
  405. methods_max_bucket = find_max_method_id(num_object_defs, object_defs,
  406. bucket_idx);
  407. if (methods_max_bucket < 0)
  408. continue;
  409. hash = kzalloc(sizeof(*hash) +
  410. sizeof(*hash->methods) * (methods_max_bucket + 1),
  411. GFP_KERNEL);
  412. if (!hash) {
  413. res = -ENOMEM;
  414. goto free;
  415. }
  416. hash->num_methods = methods_max_bucket + 1;
  417. object->method_buckets[bucket_idx] = hash;
  418. do {
  419. size_t num_method_defs;
  420. struct uverbs_method_spec *method;
  421. int i;
  422. num_method_defs =
  423. get_methods_above_id(method_defs,
  424. num_object_defs,
  425. object_defs,
  426. bucket_idx,
  427. &min_id);
  428. /* Last method in bucket */
  429. if (!num_method_defs)
  430. break;
  431. method = build_method_with_attrs(method_defs,
  432. num_method_defs);
  433. if (IS_ERR(method)) {
  434. res = PTR_ERR(method);
  435. goto free;
  436. }
  437. /*
  438. * The last tree which is given as an argument to the
  439. * merge overrides previous method handler.
  440. * Therefore, we iterate backwards and search for the
  441. * first handler which != NULL. This also defines the
  442. * set of flags used for this handler.
  443. */
  444. for (i = num_method_defs - 1;
  445. i >= 0 && !method_defs[i]->handler; i--)
  446. ;
  447. hash->methods[min_id++] = method;
  448. /* NULL handler isn't allowed */
  449. if (WARN(i < 0,
  450. "ib_uverbs: tried to merge function id %d, but all handlers are NULL\n",
  451. min_id)) {
  452. res = -EINVAL;
  453. goto free;
  454. }
  455. method->handler = method_defs[i]->handler;
  456. method->flags = method_defs[i]->flags;
  457. } while (1);
  458. }
  459. kfree(method_defs);
  460. return object;
  461. free:
  462. kfree(method_defs);
  463. free_object:
  464. free_object(object);
  465. return ERR_PTR(res);
  466. }
  467. void uverbs_free_spec_tree(struct uverbs_root_spec *root)
  468. {
  469. unsigned int i, j;
  470. if (!root)
  471. return;
  472. for (i = 0; i < root->num_buckets; i++) {
  473. struct uverbs_object_spec_hash *object_hash =
  474. root->object_buckets[i];
  475. if (!object_hash)
  476. continue;
  477. for (j = 0; j < object_hash->num_objects; j++)
  478. free_object(object_hash->objects[j]);
  479. kfree(object_hash);
  480. }
  481. kfree(root);
  482. }
  483. EXPORT_SYMBOL(uverbs_free_spec_tree);
  484. struct uverbs_root_spec *uverbs_alloc_spec_tree(unsigned int num_trees,
  485. const struct uverbs_object_tree_def **trees)
  486. {
  487. u16 bucket_idx;
  488. short max_object_buckets = 0;
  489. size_t num_objects_buckets = 0;
  490. struct uverbs_root_spec *root_spec = NULL;
  491. const struct uverbs_object_def **object_defs;
  492. int i;
  493. int res = 0;
  494. max_object_buckets = find_max_object_ns_id(num_trees, trees);
  495. /*
  496. * Devices which don't want to support ib_uverbs, should just allocate
  497. * an empty parsing tree. Every user-space command won't hit any valid
  498. * entry in the parsing tree and thus will fail.
  499. */
  500. if (max_object_buckets >= 0)
  501. num_objects_buckets = max_object_buckets + 1;
  502. root_spec = kzalloc(sizeof(*root_spec) +
  503. num_objects_buckets * sizeof(*root_spec->object_buckets),
  504. GFP_KERNEL);
  505. if (!root_spec)
  506. return ERR_PTR(-ENOMEM);
  507. root_spec->num_buckets = num_objects_buckets;
  508. object_defs = kcalloc(num_trees, sizeof(*object_defs),
  509. GFP_KERNEL);
  510. if (!object_defs) {
  511. res = -ENOMEM;
  512. goto free_root;
  513. }
  514. for (bucket_idx = 0; bucket_idx < root_spec->num_buckets; bucket_idx++) {
  515. short min_id = SHRT_MIN;
  516. short objects_max_bucket;
  517. struct uverbs_object_spec_hash *hash = NULL;
  518. objects_max_bucket = find_max_object_id(num_trees, trees,
  519. bucket_idx);
  520. if (objects_max_bucket < 0)
  521. continue;
  522. hash = kzalloc(sizeof(*hash) +
  523. sizeof(*hash->objects) * (objects_max_bucket + 1),
  524. GFP_KERNEL);
  525. if (!hash) {
  526. res = -ENOMEM;
  527. goto free;
  528. }
  529. hash->num_objects = objects_max_bucket + 1;
  530. root_spec->object_buckets[bucket_idx] = hash;
  531. do {
  532. size_t num_object_defs;
  533. struct uverbs_object_spec *object;
  534. num_object_defs = get_objects_above_id(object_defs,
  535. num_trees,
  536. trees,
  537. bucket_idx,
  538. &min_id);
  539. /* Last object in bucket */
  540. if (!num_object_defs)
  541. break;
  542. object = build_object_with_methods(object_defs,
  543. num_object_defs);
  544. if (IS_ERR(object)) {
  545. res = PTR_ERR(object);
  546. goto free;
  547. }
  548. /*
  549. * The last tree which is given as an argument to the
  550. * merge overrides previous object's type_attrs.
  551. * Therefore, we iterate backwards and search for the
  552. * first type_attrs which != NULL.
  553. */
  554. for (i = num_object_defs - 1;
  555. i >= 0 && !object_defs[i]->type_attrs; i--)
  556. ;
  557. /*
  558. * NULL is a valid type_attrs. It means an object we
  559. * can't instantiate (like DEVICE).
  560. */
  561. object->type_attrs = i < 0 ? NULL :
  562. object_defs[i]->type_attrs;
  563. hash->objects[min_id++] = object;
  564. } while (1);
  565. }
  566. kfree(object_defs);
  567. return root_spec;
  568. free:
  569. kfree(object_defs);
  570. free_root:
  571. uverbs_free_spec_tree(root_spec);
  572. return ERR_PTR(res);
  573. }
  574. EXPORT_SYMBOL(uverbs_alloc_spec_tree);