| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283 |
- // SPDX-License-Identifier: GPL-2.0
- #include <linux/types.h>
- #include <linux/mm.h>
- #include <linux/slab.h>
- #include <linux/idr.h>
- #include <asm/mshyperv.h>
- #include "mshv.h"
- #include "mshv_root.h"
- /*
- * Ports and connections are hypervisor struct used for inter-partition
- * communication. Port represents the source and connection represents
- * the destination. Partitions are responsible for managing the port and
- * connection ids.
- *
- */
- #define PORTID_MIN 1
- #define PORTID_MAX INT_MAX
- static DEFINE_IDR(port_table_idr);
- void
- mshv_port_table_fini(void)
- {
- struct port_table_info *port_info;
- unsigned long i, tmp;
- idr_lock(&port_table_idr);
- if (!idr_is_empty(&port_table_idr)) {
- idr_for_each_entry_ul(&port_table_idr, port_info, tmp, i) {
- port_info = idr_remove(&port_table_idr, i);
- kfree_rcu(port_info, portbl_rcu);
- }
- }
- idr_unlock(&port_table_idr);
- }
- int
- mshv_portid_alloc(struct port_table_info *info)
- {
- int ret = 0;
- idr_lock(&port_table_idr);
- ret = idr_alloc(&port_table_idr, info, PORTID_MIN,
- PORTID_MAX, GFP_KERNEL);
- idr_unlock(&port_table_idr);
- return ret;
- }
- void
- mshv_portid_free(int port_id)
- {
- struct port_table_info *info;
- idr_lock(&port_table_idr);
- info = idr_remove(&port_table_idr, port_id);
- WARN_ON(!info);
- idr_unlock(&port_table_idr);
- synchronize_rcu();
- kfree(info);
- }
- int
- mshv_portid_lookup(int port_id, struct port_table_info *info)
- {
- struct port_table_info *_info;
- int ret = -ENOENT;
- rcu_read_lock();
- _info = idr_find(&port_table_idr, port_id);
- rcu_read_unlock();
- if (_info) {
- *info = *_info;
- ret = 0;
- }
- return ret;
- }
|