All of lore.kernel.org
 help / color / mirror / Atom feed
From: Nuno Das Neves <nunodasneves@linux.microsoft.com>
To: linux-hyperv@vger.kernel.org, linux-kernel@vger.kernel.org
Cc: virtualization@lists.linux-foundation.org,
	mikelley@microsoft.com, viremana@linux.microsoft.com,
	sunilmut@microsoft.com, wei.liu@kernel.org, vkuznets@redhat.com,
	ligrassi@microsoft.com, kys@microsoft.com,
	sthemmin@microsoft.com, anbelski@linux.microsoft.com
Subject: [PATCH v3 09/19] drivers/hv: create vcpu ioctl
Date: Tue, 28 Sep 2021 11:31:05 -0700	[thread overview]
Message-ID: <1632853875-20261-10-git-send-email-nunodasneves@linux.microsoft.com> (raw)
In-Reply-To: <1632853875-20261-1-git-send-email-nunodasneves@linux.microsoft.com>

Introduce ioctl for creating a virtual processor in a partition.

Co-developed-by: Lillian Grassin-Drake <ligrassi@microsoft.com>
Signed-off-by: Lillian Grassin-Drake <ligrassi@microsoft.com>
Signed-off-by: Nuno Das Neves <nunodasneves@linux.microsoft.com>
---
 Documentation/virt/mshv/api.rst |   9 +++
 drivers/hv/mshv_main.c          | 119 +++++++++++++++++++++++++++++++-
 include/linux/mshv.h            |  10 +++
 include/uapi/linux/mshv.h       |   5 ++
 4 files changed, 142 insertions(+), 1 deletion(-)

diff --git a/Documentation/virt/mshv/api.rst b/Documentation/virt/mshv/api.rst
index 71c93b73e999..2538756bc86b 100644
--- a/Documentation/virt/mshv/api.rst
+++ b/Documentation/virt/mshv/api.rst
@@ -87,3 +87,12 @@ memory to stop the pages being moved by Linux in the root partition,
 and subsequently being clobbered by the hypervisor. So the region is backed
 by real physical memory.
 
+3.4 MSHV_CREATE_VP
+------------------
+:Type: partition ioctl
+:Parameters: struct mshv_create_vp
+:Returns: vp file descriptor, or -1 on failure
+
+Create a virtual processor in a guest partition, returning a file descriptor to
+represent the vp and perform ioctls on.
+
diff --git a/drivers/hv/mshv_main.c b/drivers/hv/mshv_main.c
index c5c18826a38f..c3ac8c371d0f 100644
--- a/drivers/hv/mshv_main.c
+++ b/drivers/hv/mshv_main.c
@@ -25,6 +25,9 @@ MODULE_LICENSE("GPL");
 
 struct mshv mshv = {};
 
+static int mshv_vp_release(struct inode *inode, struct file *filp);
+static long mshv_vp_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg);
+static struct mshv_partition *mshv_partition_get(struct mshv_partition *partition);
 static void mshv_partition_put(struct mshv_partition *partition);
 static int mshv_partition_release(struct inode *inode, struct file *filp);
 static long mshv_partition_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg);
@@ -32,6 +35,12 @@ static int mshv_dev_open(struct inode *inode, struct file *filp);
 static int mshv_dev_release(struct inode *inode, struct file *filp);
 static long mshv_dev_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg);
 
+static const struct file_operations mshv_vp_fops = {
+	.release = mshv_vp_release,
+	.unlocked_ioctl = mshv_vp_ioctl,
+	.llseek = noop_llseek,
+};
+
 static const struct file_operations mshv_partition_fops = {
 	.release = mshv_partition_release,
 	.unlocked_ioctl = mshv_partition_ioctl,
@@ -53,6 +62,94 @@ static struct miscdevice mshv_dev = {
 	.mode = 0600,
 };
 
+static long
+mshv_vp_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg)
+{
+	return -ENOTTY;
+}
+
+static int
+mshv_vp_release(struct inode *inode, struct file *filp)
+{
+	struct mshv_vp *vp = filp->private_data;
+
+	/* Rest of VP cleanup happens in destroy_partition() */
+	mshv_partition_put(vp->partition);
+	return 0;
+}
+
+static long
+mshv_partition_ioctl_create_vp(struct mshv_partition *partition,
+			       void __user *arg)
+{
+	struct mshv_create_vp args;
+	struct mshv_vp *vp;
+	struct file *file;
+	int fd;
+	long ret;
+
+	if (copy_from_user(&args, arg, sizeof(args)))
+		return -EFAULT;
+
+	if (args.vp_index >= MSHV_MAX_VPS)
+		return -EINVAL;
+
+	if (partition->vps.array[args.vp_index])
+		return -EEXIST;
+
+	vp = kzalloc(sizeof(*vp), GFP_KERNEL);
+
+	if (!vp)
+		return -ENOMEM;
+
+	vp->index = args.vp_index;
+	vp->partition = mshv_partition_get(partition);
+	if (!vp->partition) {
+		ret = -EBADF;
+		goto free_vp;
+	}
+
+	fd = get_unused_fd_flags(O_CLOEXEC);
+	if (fd < 0) {
+		ret = fd;
+		goto put_partition;
+	}
+
+	file = anon_inode_getfile("mshv_vp", &mshv_vp_fops, vp, O_RDWR);
+	if (IS_ERR(file)) {
+		ret = PTR_ERR(file);
+		goto put_fd;
+	}
+
+	ret = hv_call_create_vp(
+			NUMA_NO_NODE,
+			partition->id,
+			args.vp_index,
+			0 /* Only valid for root partition VPs */
+			);
+	if (ret)
+		goto release_file;
+
+	/* already exclusive with the partition mutex for all ioctls */
+	partition->vps.count++;
+	partition->vps.array[args.vp_index] = vp;
+
+	fd_install(fd, file);
+
+	return fd;
+
+release_file:
+	file->f_op->release(file->f_inode, file);
+put_fd:
+	put_unused_fd(fd);
+put_partition:
+	mshv_partition_put(partition);
+free_vp:
+	kfree(vp);
+
+	return ret;
+}
+
 static long
 mshv_partition_ioctl_map_memory(struct mshv_partition *partition,
 				struct mshv_user_mem_region __user *user_mem)
@@ -228,6 +325,10 @@ mshv_partition_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg)
 		ret = mshv_partition_ioctl_unmap_memory(partition,
 							(void __user *)arg);
 		break;
+	case MSHV_CREATE_VP:
+		ret = mshv_partition_ioctl_create_vp(partition,
+							(void __user *)arg);
+		break;
 	default:
 		ret = -ENOTTY;
 	}
@@ -240,6 +341,7 @@ static void
 destroy_partition(struct mshv_partition *partition)
 {
 	unsigned long flags, page_count;
+	struct mshv_vp *vp;
 	struct mshv_mem_region *region;
 	int i;
 
@@ -269,9 +371,16 @@ destroy_partition(struct mshv_partition *partition)
 	hv_call_finalize_partition(partition->id);
 	/* Withdraw and free all pages we deposited */
 	hv_call_withdraw_memory(U64_MAX, NUMA_NO_NODE, partition->id);
-
 	hv_call_delete_partition(partition->id);
 
+	/* Remove vps */
+	for (i = 0; i < MSHV_MAX_VPS; ++i) {
+		vp = partition->vps.array[i];
+		if (!vp)
+			continue;
+		kfree(vp);
+	}
+
 	/* Remove regions and unpin the pages */
 	for (i = 0; i < MSHV_MAX_MEM_REGIONS; ++i) {
 		region = &partition->regions.slots[i];
@@ -285,6 +394,14 @@ destroy_partition(struct mshv_partition *partition)
 	kfree(partition);
 }
 
+static struct
+mshv_partition *mshv_partition_get(struct mshv_partition *partition)
+{
+	if (refcount_inc_not_zero(&partition->ref_count))
+		return partition;
+	return NULL;
+}
+
 static void
 mshv_partition_put(struct mshv_partition *partition)
 {
diff --git a/include/linux/mshv.h b/include/linux/mshv.h
index 91a742f37440..50521c5f7948 100644
--- a/include/linux/mshv.h
+++ b/include/linux/mshv.h
@@ -12,6 +12,12 @@
 
 #define MSHV_MAX_PARTITIONS		128
 #define MSHV_MAX_MEM_REGIONS		64
+#define MSHV_MAX_VPS			256
+
+struct mshv_vp {
+	u32 index;
+	struct mshv_partition *partition;
+};
 
 struct mshv_mem_region {
 	u64 size; /* bytes */
@@ -28,6 +34,10 @@ struct mshv_partition {
 		u32 count;
 		struct mshv_mem_region slots[MSHV_MAX_MEM_REGIONS];
 	} regions;
+	struct {
+		u32 count;
+		struct mshv_vp *array[MSHV_MAX_VPS];
+	} vps;
 };
 
 struct mshv {
diff --git a/include/uapi/linux/mshv.h b/include/uapi/linux/mshv.h
index 7ead5f1c8b14..251976348441 100644
--- a/include/uapi/linux/mshv.h
+++ b/include/uapi/linux/mshv.h
@@ -30,6 +30,10 @@ struct mshv_user_mem_region {
 	__u32 flags;		/* ignored on unmap */
 };
 
+struct mshv_create_vp {
+	__u32 vp_index;
+};
+
 #define MSHV_IOCTL 0xB8
 
 /* mshv device */
@@ -39,5 +43,6 @@ struct mshv_user_mem_region {
 /* partition device */
 #define MSHV_MAP_GUEST_MEMORY	_IOW(MSHV_IOCTL, 0x02, struct mshv_user_mem_region)
 #define MSHV_UNMAP_GUEST_MEMORY	_IOW(MSHV_IOCTL, 0x03, struct mshv_user_mem_region)
+#define MSHV_CREATE_VP		_IOW(MSHV_IOCTL, 0x04, struct mshv_create_vp)
 
 #endif
-- 
2.23.4


  parent reply	other threads:[~2021-09-28 18:32 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-09-28 18:30 [PATCH v3 00/19] Microsoft Hypervisor root partition ioctl interface Nuno Das Neves
2021-09-28 18:30 ` [PATCH v3 01/19] x86/hyperv: convert hyperv statuses to linux error codes Nuno Das Neves
2021-09-28 18:30 ` [PATCH v3 02/19] x86/hyperv: convert hyperv statuses to strings Nuno Das Neves
2021-09-28 18:30 ` [PATCH v3 03/19] drivers/hv: minimal mshv module (/dev/mshv/) Nuno Das Neves
2021-09-28 18:31 ` [PATCH v3 04/19] drivers/hv: check extension ioctl Nuno Das Neves
2021-09-28 18:31 ` [PATCH v3 05/19] drivers/hv: create partition ioctl Nuno Das Neves
2021-09-28 18:31 ` [PATCH v3 06/19] drivers/hv: create, initialize, finalize, delete partition hypercalls Nuno Das Neves
2021-09-28 18:31 ` [PATCH v3 07/19] drivers/hv: withdraw memory hypercall Nuno Das Neves
2021-09-28 18:31 ` [PATCH v3 08/19] drivers/hv: map and unmap guest memory Nuno Das Neves
2021-09-28 21:27   ` Olaf Hering
2021-09-28 21:27     ` Olaf Hering
2021-09-30 14:17     ` Wei Liu
2021-10-04 17:08       ` Nuno Das Neves
2021-09-28 18:31 ` Nuno Das Neves [this message]
2021-09-28 18:31 ` [PATCH v3 10/19] drivers/hv: get and set vcpu registers ioctls Nuno Das Neves
2021-09-28 18:31 ` [PATCH v3 11/19] drivers/hv: set up synic pages for intercept messages Nuno Das Neves
2021-09-28 21:38   ` Olaf Hering
2021-09-28 18:31 ` [PATCH v3 12/19] drivers/hv: run vp ioctl and isr Nuno Das Neves
2021-09-28 18:31 ` [PATCH v3 13/19] drivers/hv: install intercept ioctl Nuno Das Neves
2021-09-28 18:31 ` [PATCH v3 14/19] drivers/hv: assert interrupt ioctl Nuno Das Neves
2021-09-28 18:31 ` [PATCH v3 15/19] drivers/hv: get and set vp state ioctls Nuno Das Neves
2021-09-28 18:31 ` [PATCH v3 16/19] drivers/hv: mmap vp register page Nuno Das Neves
2021-09-28 18:31 ` [PATCH v3 17/19] drivers/hv: get and set partition property ioctls Nuno Das Neves
2021-09-28 18:31 ` [PATCH v3 18/19] drivers/hv: Add enlightenment bits to create partition ioctl Nuno Das Neves
2021-09-28 18:31 ` [PATCH v3 19/19] drivers/hv: Translate GVA to GPA Nuno Das Neves

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1632853875-20261-10-git-send-email-nunodasneves@linux.microsoft.com \
    --to=nunodasneves@linux.microsoft.com \
    --cc=anbelski@linux.microsoft.com \
    --cc=kys@microsoft.com \
    --cc=ligrassi@microsoft.com \
    --cc=linux-hyperv@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mikelley@microsoft.com \
    --cc=sthemmin@microsoft.com \
    --cc=sunilmut@microsoft.com \
    --cc=viremana@linux.microsoft.com \
    --cc=virtualization@lists.linux-foundation.org \
    --cc=vkuznets@redhat.com \
    --cc=wei.liu@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.