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 05/19] drivers/hv: create partition ioctl
Date: Tue, 28 Sep 2021 11:31:01 -0700	[thread overview]
Message-ID: <1632853875-20261-6-git-send-email-nunodasneves@linux.microsoft.com> (raw)
In-Reply-To: <1632853875-20261-1-git-send-email-nunodasneves@linux.microsoft.com>

Add MSHV_CREATE_PARTITION, which creates an fd to track a new partition.
Partition is not yet created in the hypervisor itself.
Introduce header files for userspace-facing hyperv structures.

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         |  12 ++
 arch/x86/include/asm/hyperv-tlfs.h      |   1 +
 arch/x86/include/uapi/asm/hyperv-tlfs.h | 124 +++++++++++++++++++++
 drivers/hv/mshv_main.c                  | 141 ++++++++++++++++++++++++
 include/asm-generic/hyperv-tlfs.h       |   1 +
 include/linux/mshv.h                    |  16 +++
 include/uapi/asm-generic/hyperv-tlfs.h  |  15 +++
 include/uapi/linux/mshv.h               |   8 ++
 8 files changed, 318 insertions(+)
 create mode 100644 arch/x86/include/uapi/asm/hyperv-tlfs.h
 create mode 100644 include/uapi/asm-generic/hyperv-tlfs.h

diff --git a/Documentation/virt/mshv/api.rst b/Documentation/virt/mshv/api.rst
index 75c5e073ecc0..f92892b27ccc 100644
--- a/Documentation/virt/mshv/api.rst
+++ b/Documentation/virt/mshv/api.rst
@@ -39,6 +39,9 @@ root partition can use mshv APIs to create guest partitions.
 
 The module is named mshv and can be configured with CONFIG_HYPERV_ROOT_API.
 
+The uapi header files you need are linux/mshv.h, asm/hyperv-tlfs.h, and
+asm-generic/hyperv-tlfs.h.
+
 Mshv is file descriptor-based, following a similar pattern to KVM.
 
 To get a handle to the mshv driver, use open("/dev/mshv").
@@ -58,3 +61,12 @@ number. If not, it will return 0.
 The first extension that can be checked is MSHV_CAP_CORE_API_STABLE. This
 will be supported when the core API is stable.
 
+3.2 MSHV_CREATE_PARTITION
+-------------------------
+:Type: /dev/mshv ioctl
+:Parameters: struct mshv_create_partition
+:Returns: partition file descriptor, or -1 on failure
+
+This ioctl creates a guest partition, returning a file descriptor to use as a
+handle for partition ioctls.
+
diff --git a/arch/x86/include/asm/hyperv-tlfs.h b/arch/x86/include/asm/hyperv-tlfs.h
index 606f5cc579b2..2b6f7dca79e6 100644
--- a/arch/x86/include/asm/hyperv-tlfs.h
+++ b/arch/x86/include/asm/hyperv-tlfs.h
@@ -11,6 +11,7 @@
 
 #include <linux/types.h>
 #include <asm/page.h>
+#include <uapi/asm/hyperv-tlfs.h>
 /*
  * The below CPUID leaves are present if VersionAndFeatures.HypervisorPresent
  * is set by CPUID(HvCpuIdFunctionVersionAndFeatures).
diff --git a/arch/x86/include/uapi/asm/hyperv-tlfs.h b/arch/x86/include/uapi/asm/hyperv-tlfs.h
new file mode 100644
index 000000000000..8a5fc59bb33a
--- /dev/null
+++ b/arch/x86/include/uapi/asm/hyperv-tlfs.h
@@ -0,0 +1,124 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef _UAPI_ASM_X86_HYPERV_TLFS_USER_H
+#define _UAPI_ASM_X86_HYPERV_TLFS_USER_H
+
+#include <linux/types.h>
+
+#define HV_PARTITION_PROCESSOR_FEATURE_BANKS 2
+
+union hv_partition_processor_features {
+	struct {
+		__u64 sse3_support:1;
+		__u64 lahf_sahf_support:1;
+		__u64 ssse3_support:1;
+		__u64 sse4_1_support:1;
+		__u64 sse4_2_support:1;
+		__u64 sse4a_support:1;
+		__u64 xop_support:1;
+		__u64 pop_cnt_support:1;
+		__u64 cmpxchg16b_support:1;
+		__u64 altmovcr8_support:1;
+		__u64 lzcnt_support:1;
+		__u64 mis_align_sse_support:1;
+		__u64 mmx_ext_support:1;
+		__u64 amd3dnow_support:1;
+		__u64 extended_amd3dnow_support:1;
+		__u64 page_1gb_support:1;
+		__u64 aes_support:1;
+		__u64 pclmulqdq_support:1;
+		__u64 pcid_support:1;
+		__u64 fma4_support:1;
+		__u64 f16c_support:1;
+		__u64 rd_rand_support:1;
+		__u64 rd_wr_fs_gs_support:1;
+		__u64 smep_support:1;
+		__u64 enhanced_fast_string_support:1;
+		__u64 bmi1_support:1;
+		__u64 bmi2_support:1;
+		__u64 hle_support_deprecated:1;
+		__u64 rtm_support_deprecated:1;
+		__u64 movbe_support:1;
+		__u64 npiep1_support:1;
+		__u64 dep_x87_fpu_save_support:1;
+		__u64 rd_seed_support:1;
+		__u64 adx_support:1;
+		__u64 intel_prefetch_support:1;
+		__u64 smap_support:1;
+		__u64 hle_support:1;
+		__u64 rtm_support:1;
+		__u64 rdtscp_support:1;
+		__u64 clflushopt_support:1;
+		__u64 clwb_support:1;
+		__u64 sha_support:1;
+		__u64 x87_pointers_saved_support:1;
+		__u64 invpcid_support:1;
+		__u64 ibrs_support:1;
+		__u64 stibp_support:1;
+		__u64 ibpb_support: 1;
+		__u64 unrestricted_guest_support:1;
+		__u64 mdd_support:1;
+		__u64 fast_short_rep_mov_support:1;
+		__u64 l1dcache_flush_support:1;
+		__u64 rdcl_no_support:1;
+		__u64 ibrs_all_support:1;
+		__u64 skip_l1df_support:1;
+		__u64 ssb_no_support:1;
+		__u64 rsb_a_no_support:1;
+		__u64 virt_spec_ctrl_support:1;
+		__u64 rd_pid_support:1;
+		__u64 umip_support:1;
+		__u64 mbs_no_support:1;
+		__u64 mb_clear_support:1;
+		__u64 taa_no_support:1;
+		__u64 tsx_ctrl_support:1;
+		/*
+		 * N.B. The final processor feature bit in bank 0 is reserved to
+		 * simplify potential downlevel backports.
+		 */
+		__u64 reserved_bank0:1;
+
+		/* N.B. Begin bank 1 processor features. */
+		__u64 acount_mcount_support:1;
+		__u64 tsc_invariant_support:1;
+		__u64 cl_zero_support:1;
+		__u64 rdpru_support:1;
+		__u64 la57_support:1;
+		__u64 mbec_support:1;
+		__u64 nested_virt_support:1;
+		__u64 psfd_support:1;
+		__u64 cet_ss_support:1;
+		__u64 cet_ibt_support:1;
+		__u64 vmx_exception_inject_support:1;
+		__u64 enqcmd_support:1;
+		__u64 umwait_tpause_support:1;
+		__u64 movdiri_support:1;
+		__u64 movdir64b_support:1;
+		__u64 cldemote_support:1;
+		__u64 serialize_support:1;
+		__u64 tsc_deadline_tmr_support:1;
+		__u64 tsc_adjust_support:1;
+		__u64 fzlrep_movsb:1;
+		__u64 fsrep_stosb:1;
+		__u64 fsrep_cmpsb:1;
+		__u64 reserved_bank1:42;
+	} __packed;
+	__u64 as_uint64[HV_PARTITION_PROCESSOR_FEATURE_BANKS];
+};
+
+union hv_partition_processor_xsave_features {
+	struct {
+		__u64 xsave_support : 1;
+		__u64 xsaveopt_support : 1;
+		__u64 avx_support : 1;
+		__u64 reserved1 : 61;
+	} __packed;
+	__u64 as_uint64;
+};
+
+struct hv_partition_creation_properties {
+	union hv_partition_processor_features disabled_processor_features;
+	union hv_partition_processor_xsave_features
+		disabled_processor_xsave_features;
+} __packed;
+
+#endif
diff --git a/drivers/hv/mshv_main.c b/drivers/hv/mshv_main.c
index d73b64ea1448..378bced4044c 100644
--- a/drivers/hv/mshv_main.c
+++ b/drivers/hv/mshv_main.c
@@ -12,15 +12,28 @@
 #include <linux/fs.h>
 #include <linux/miscdevice.h>
 #include <linux/slab.h>
+#include <linux/file.h>
+#include <linux/anon_inodes.h>
 #include <linux/mshv.h>
 
 MODULE_AUTHOR("Microsoft");
 MODULE_LICENSE("GPL");
 
+struct mshv mshv = {};
+
+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);
 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_partition_fops = {
+	.release = mshv_partition_release,
+	.unlocked_ioctl = mshv_partition_ioctl,
+	.llseek = noop_llseek,
+};
+
 static const struct file_operations mshv_dev_fops = {
 	.owner = THIS_MODULE,
 	.open = mshv_dev_open,
@@ -36,6 +49,130 @@ static struct miscdevice mshv_dev = {
 	.mode = 0600,
 };
 
+static long
+mshv_partition_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg)
+{
+	return -ENOTTY;
+}
+
+static void
+destroy_partition(struct mshv_partition *partition)
+{
+	unsigned long flags;
+	int i;
+
+	/* Remove from list of partitions */
+	spin_lock_irqsave(&mshv.partitions.lock, flags);
+
+	for (i = 0; i < MSHV_MAX_PARTITIONS; ++i) {
+		if (mshv.partitions.array[i] == partition)
+			break;
+	}
+
+	if (i == MSHV_MAX_PARTITIONS) {
+		pr_err("%s: failed to locate partition in array\n", __func__);
+	} else {
+		mshv.partitions.count--;
+		mshv.partitions.array[i] = NULL;
+	}
+
+	spin_unlock_irqrestore(&mshv.partitions.lock, flags);
+
+	kfree(partition);
+}
+
+static void
+mshv_partition_put(struct mshv_partition *partition)
+{
+	if (refcount_dec_and_test(&partition->ref_count))
+		destroy_partition(partition);
+}
+
+static int
+mshv_partition_release(struct inode *inode, struct file *filp)
+{
+	struct mshv_partition *partition = filp->private_data;
+
+	mshv_partition_put(partition);
+
+	return 0;
+}
+
+static int
+add_partition(struct mshv_partition *partition)
+{
+	unsigned long flags;
+	int i, ret = 0;
+
+	spin_lock_irqsave(&mshv.partitions.lock, flags);
+
+	if (mshv.partitions.count >= MSHV_MAX_PARTITIONS) {
+		pr_err("%s: too many partitions\n", __func__);
+		ret = -ENOSPC;
+		goto out_unlock;
+	}
+
+	for (i = 0; i < MSHV_MAX_PARTITIONS; ++i) {
+		if (!mshv.partitions.array[i])
+			break;
+	}
+
+	mshv.partitions.count++;
+	mshv.partitions.array[i] = partition;
+
+out_unlock:
+	spin_unlock_irqrestore(&mshv.partitions.lock, flags);
+
+	return ret;
+}
+
+static long
+mshv_ioctl_create_partition(void __user *user_arg)
+{
+	struct mshv_create_partition args;
+	struct mshv_partition *partition;
+	struct file *file;
+	int fd;
+	long ret;
+
+	if (copy_from_user(&args, user_arg, sizeof(args)))
+		return -EFAULT;
+
+	partition = kzalloc(sizeof(*partition), GFP_KERNEL);
+	if (!partition)
+		return -ENOMEM;
+
+	fd = get_unused_fd_flags(O_CLOEXEC);
+	if (fd < 0) {
+		ret = fd;
+		goto free_partition;
+	}
+
+	file = anon_inode_getfile("mshv_partition", &mshv_partition_fops,
+				  partition, O_RDWR);
+	if (IS_ERR(file)) {
+		ret = PTR_ERR(file);
+		goto put_fd;
+	}
+	refcount_set(&partition->ref_count, 1);
+
+	ret = add_partition(partition);
+	if (ret)
+		goto release_file;
+
+	fd_install(fd, file);
+
+	return fd;
+
+release_file:
+	file->f_op->release(file->f_inode, file);
+put_fd:
+	put_unused_fd(fd);
+free_partition:
+	kfree(partition);
+	return ret;
+}
+
 static long
 mshv_ioctl_check_extension(void __user *user_arg)
 {
@@ -58,6 +195,8 @@ mshv_dev_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg)
 	switch (ioctl) {
 	case MSHV_CHECK_EXTENSION:
 		return mshv_ioctl_check_extension((void __user *)arg);
+	case MSHV_CREATE_PARTITION:
+		return mshv_ioctl_create_partition((void __user *)arg);
 	}
 
 	return -ENOTTY;
@@ -87,6 +226,8 @@ __init mshv_init(void)
 	if (ret)
 		pr_err("%s: misc device register failed\n", __func__);
 
+	spin_lock_init(&mshv.partitions.lock);
+
 	return ret;
 }
 
diff --git a/include/asm-generic/hyperv-tlfs.h b/include/asm-generic/hyperv-tlfs.h
index 40ff7cdd4a2b..50dc6eafb6a6 100644
--- a/include/asm-generic/hyperv-tlfs.h
+++ b/include/asm-generic/hyperv-tlfs.h
@@ -12,6 +12,7 @@
 #include <linux/types.h>
 #include <linux/bits.h>
 #include <linux/time64.h>
+#include <uapi/asm-generic/hyperv-tlfs.h>
 
 /*
  * While not explicitly listed in the TLFS, Hyper-V always runs with a page size
diff --git a/include/linux/mshv.h b/include/linux/mshv.h
index a0982fe2c0b8..fc4f35089b2c 100644
--- a/include/linux/mshv.h
+++ b/include/linux/mshv.h
@@ -6,6 +6,22 @@
  * Microsoft Hypervisor root partition driver for /dev/mshv
  */
 
+#include <linux/spinlock.h>
 #include <uapi/linux/mshv.h>
 
+#define MSHV_MAX_PARTITIONS		128
+
+struct mshv_partition {
+	u64 id;
+	refcount_t ref_count;
+};
+
+struct mshv {
+	struct {
+		spinlock_t lock;
+		u64 count;
+		struct mshv_partition *array[MSHV_MAX_PARTITIONS];
+	} partitions;
+};
+
 #endif
diff --git a/include/uapi/asm-generic/hyperv-tlfs.h b/include/uapi/asm-generic/hyperv-tlfs.h
new file mode 100644
index 000000000000..7a858226a9c5
--- /dev/null
+++ b/include/uapi/asm-generic/hyperv-tlfs.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef _UAPI_ASM_GENERIC_HYPERV_TLFS_USER_H
+#define _UAPI_ASM_GENERIC_HYPERV_TLFS_USER_H
+
+#ifndef BIT
+#define BIT(X)	(1ULL << (X))
+#endif
+
+/* Userspace-visible partition creation flags */
+#define HV_PARTITION_CREATION_FLAG_SMT_ENABLED_GUEST                BIT(0)
+#define HV_PARTITION_CREATION_FLAG_GPA_LARGE_PAGES_DISABLED         BIT(3)
+#define HV_PARTITION_CREATION_FLAG_GPA_SUPER_PAGES_ENABLED          BIT(4)
+#define HV_PARTITION_CREATION_FLAG_LAPIC_ENABLED                    BIT(13)
+
+#endif
diff --git a/include/uapi/linux/mshv.h b/include/uapi/linux/mshv.h
index 3b84e3ea97be..03b1ed66245d 100644
--- a/include/uapi/linux/mshv.h
+++ b/include/uapi/linux/mshv.h
@@ -9,12 +9,20 @@
  */
 
 #include <linux/types.h>
+#include <asm/hyperv-tlfs.h>
+#include <asm-generic/hyperv-tlfs.h>
 
 #define MSHV_CAP_CORE_API_STABLE    0x0
 
+struct mshv_create_partition {
+	__u64 flags;
+	struct hv_partition_creation_properties partition_creation_properties;
+};
+
 #define MSHV_IOCTL 0xB8
 
 /* mshv device */
 #define MSHV_CHECK_EXTENSION    _IOW(MSHV_IOCTL, 0x00, __u32)
+#define MSHV_CREATE_PARTITION	_IOW(MSHV_IOCTL, 0x01, struct mshv_create_partition)
 
 #endif
-- 
2.23.4


  parent reply	other threads:[~2021-09-28 18:31 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 ` Nuno Das Neves [this message]
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 ` [PATCH v3 09/19] drivers/hv: create vcpu ioctl Nuno Das Neves
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-6-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.