mshv_portid_table.c 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. // SPDX-License-Identifier: GPL-2.0
  2. #include <linux/types.h>
  3. #include <linux/mm.h>
  4. #include <linux/slab.h>
  5. #include <linux/idr.h>
  6. #include <asm/mshyperv.h>
  7. #include "mshv.h"
  8. #include "mshv_root.h"
  9. /*
  10. * Ports and connections are hypervisor struct used for inter-partition
  11. * communication. Port represents the source and connection represents
  12. * the destination. Partitions are responsible for managing the port and
  13. * connection ids.
  14. *
  15. */
  16. #define PORTID_MIN 1
  17. #define PORTID_MAX INT_MAX
  18. static DEFINE_IDR(port_table_idr);
  19. void
  20. mshv_port_table_fini(void)
  21. {
  22. struct port_table_info *port_info;
  23. unsigned long i, tmp;
  24. idr_lock(&port_table_idr);
  25. if (!idr_is_empty(&port_table_idr)) {
  26. idr_for_each_entry_ul(&port_table_idr, port_info, tmp, i) {
  27. port_info = idr_remove(&port_table_idr, i);
  28. kfree_rcu(port_info, portbl_rcu);
  29. }
  30. }
  31. idr_unlock(&port_table_idr);
  32. }
  33. int
  34. mshv_portid_alloc(struct port_table_info *info)
  35. {
  36. int ret = 0;
  37. idr_lock(&port_table_idr);
  38. ret = idr_alloc(&port_table_idr, info, PORTID_MIN,
  39. PORTID_MAX, GFP_KERNEL);
  40. idr_unlock(&port_table_idr);
  41. return ret;
  42. }
  43. void
  44. mshv_portid_free(int port_id)
  45. {
  46. struct port_table_info *info;
  47. idr_lock(&port_table_idr);
  48. info = idr_remove(&port_table_idr, port_id);
  49. WARN_ON(!info);
  50. idr_unlock(&port_table_idr);
  51. synchronize_rcu();
  52. kfree(info);
  53. }
  54. int
  55. mshv_portid_lookup(int port_id, struct port_table_info *info)
  56. {
  57. struct port_table_info *_info;
  58. int ret = -ENOENT;
  59. rcu_read_lock();
  60. _info = idr_find(&port_table_idr, port_id);
  61. rcu_read_unlock();
  62. if (_info) {
  63. *info = *_info;
  64. ret = 0;
  65. }
  66. return ret;
  67. }