linux/drivers/hv/mshv_portid_table.c

84 lines
1.6 KiB
C
Raw Permalink Normal View History

Drivers: hv: Introduce mshv_root module to expose /dev/mshv to VMMs Provide a set of IOCTLs for creating and managing child partitions when running as root partition on Hyper-V. The new driver is enabled via CONFIG_MSHV_ROOT. A brief overview of the interface: MSHV_CREATE_PARTITION is the entry point, returning a file descriptor representing a child partition. IOCTLs on this fd can be used to map memory, create VPs, etc. Creating a VP returns another file descriptor representing that VP which in turn has another set of corresponding IOCTLs for running the VP, getting/setting state, etc. MSHV_ROOT_HVCALL is a generic "passthrough" hypercall IOCTL which can be used for a number of partition or VP hypercalls. This is for hypercalls that do not affect any state in the kernel driver, such as getting and setting VP registers and partition properties, translating addresses, etc. It is "passthrough" because the binary input and output for the hypercall is only interpreted by the VMM - the kernel driver does nothing but insert the VP and partition id where necessary (which are always in the same place), and execute the hypercall. Co-developed-by: Anirudh Rayabharam <anrayabh@linux.microsoft.com> Signed-off-by: Anirudh Rayabharam <anrayabh@linux.microsoft.com> Co-developed-by: Jinank Jain <jinankjain@microsoft.com> Signed-off-by: Jinank Jain <jinankjain@microsoft.com> Co-developed-by: Mukesh Rathor <mrathor@linux.microsoft.com> Signed-off-by: Mukesh Rathor <mrathor@linux.microsoft.com> Co-developed-by: Muminul Islam <muislam@microsoft.com> Signed-off-by: Muminul Islam <muislam@microsoft.com> Co-developed-by: Praveen K Paladugu <prapal@linux.microsoft.com> Signed-off-by: Praveen K Paladugu <prapal@linux.microsoft.com> Co-developed-by: Stanislav Kinsburskii <skinsburskii@linux.microsoft.com> Signed-off-by: Stanislav Kinsburskii <skinsburskii@linux.microsoft.com> Co-developed-by: Wei Liu <wei.liu@kernel.org> Signed-off-by: Nuno Das Neves <nunodasneves@linux.microsoft.com> Reviewed-by: Roman Kisel <romank@linux.microsoft.com> Link: https://lore.kernel.org/r/1741980536-3865-11-git-send-email-nunodasneves@linux.microsoft.com Signed-off-by: Wei Liu <wei.liu@kernel.org> Message-ID: <1741980536-3865-11-git-send-email-nunodasneves@linux.microsoft.com>
2025-03-14 12:28:56 -07:00
// 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;
}