linux-hyperv.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/5] mshv: Fixes for stats and vp state page mappings
@ 2025-09-10 23:14 Nuno Das Neves
  2025-09-10 23:14 ` [PATCH v2 1/5] mshv: Only map vp->vp_stats_pages if on root scheduler Nuno Das Neves
                   ` (4 more replies)
  0 siblings, 5 replies; 10+ messages in thread
From: Nuno Das Neves @ 2025-09-10 23:14 UTC (permalink / raw)
  To: linux-hyperv, linux-kernel, prapal, easwar.hariharan, tiala,
	anirudh, paekkaladevi
  Cc: kys, haiyangz, wei.liu, decui, Nuno Das Neves

There are some differences in how L1VH partitions must map stats and vp
state pages, some of which are due to differences across hypervisor
versions. Detect and handle these cases.

Patch 1:
Fix for the logic of when to map the vp stats page for the root scheduler.

Patch 2-3:
Add HVCALL_GET_PARTITION_PROPERTY_EX and use it to query "vmm capabilities" on
module init.

Patches 4-5:
Check a feature bit in vmm capabilities, to take a new code path for mapping
stats and vp state pages. In this case, the stats and vp state pages must be
allocated by Linux, and a new hypercall HVCALL_MAP_VP_STATS_PAGE2 must be used
to map the stats page.

---
v2:
- Removed patch falling back to SELF page if PARENT mapping fails [Easwar]
  (To be included in a future series)
- Fix formatting of function definitions [Easwar]
- Fix some wording in commit messages [Praveen]
- Proceed with driver init even if getting vmm capabilities fails [Anirudh]

v1:
https://lore.kernel.org/linux-hyperv/1756428230-3599-1-git-send-email-nunodasneves@linux.microsoft.com/T/#t

---
Jinank Jain (2):
  mshv: Allocate vp state page for HVCALL_MAP_VP_STATE_PAGE on L1VH
  mshv: Introduce new hypercall to map stats page for L1VH partitions

Nuno Das Neves (1):
  mshv: Only map vp->vp_stats_pages if on root scheduler

Purna Pavan Chandra Aekkaladevi (2):
  mshv: Add the HVCALL_GET_PARTITION_PROPERTY_EX hypercall
  mshv: Get the vmm capabilities offered by the hypervisor

 drivers/hv/mshv_root.h         |  24 +++--
 drivers/hv/mshv_root_hv_call.c | 181 +++++++++++++++++++++++++++++++--
 drivers/hv/mshv_root_main.c    | 131 ++++++++++++++----------
 include/hyperv/hvgdk_mini.h    |   2 +
 include/hyperv/hvhdk.h         |  40 ++++++++
 include/hyperv/hvhdk_mini.h    |  33 ++++++
 6 files changed, 339 insertions(+), 72 deletions(-)

-- 
2.34.1


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH v2 1/5] mshv: Only map vp->vp_stats_pages if on root scheduler
  2025-09-10 23:14 [PATCH v2 0/5] mshv: Fixes for stats and vp state page mappings Nuno Das Neves
@ 2025-09-10 23:14 ` Nuno Das Neves
  2025-09-10 23:14 ` [PATCH v2 2/5] mshv: Add the HVCALL_GET_PARTITION_PROPERTY_EX hypercall Nuno Das Neves
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 10+ messages in thread
From: Nuno Das Neves @ 2025-09-10 23:14 UTC (permalink / raw)
  To: linux-hyperv, linux-kernel, prapal, easwar.hariharan, tiala,
	anirudh, paekkaladevi
  Cc: kys, haiyangz, wei.liu, decui, Nuno Das Neves

This mapping is only used for checking if the dispatch thread is
blocked. This is only relevant for the root scheduler, so check the
scheduler type to determine whether to map/unmap these pages, instead of
the current check, which is incorrect.

Signed-off-by: Nuno Das Neves <nunodasneves@linux.microsoft.com>
Reviewed-by: Anirudh Rayabharam <anirudh@anirudhrb.com>
Reviewed-by: Praveen K Paladugu <prapal@linux.microsoft.com>
Reviewed-by: Easwar Hariharan <easwar.hariharan@linux.microsoft.com>
Reviewed-by: Tianyu Lan <tiala@microsoft.com>
---
 drivers/hv/mshv_root_main.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/hv/mshv_root_main.c b/drivers/hv/mshv_root_main.c
index e3b2bd417c46..24df47726363 100644
--- a/drivers/hv/mshv_root_main.c
+++ b/drivers/hv/mshv_root_main.c
@@ -934,7 +934,11 @@ mshv_partition_ioctl_create_vp(struct mshv_partition *partition,
 			goto unmap_register_page;
 	}
 
-	if (hv_parent_partition()) {
+	/*
+	 * This mapping of the stats page is for detecting if dispatch thread
+	 * is blocked - only relevant for root scheduler
+	 */
+	if (hv_scheduler_type == HV_SCHEDULER_TYPE_ROOT) {
 		ret = mshv_vp_stats_map(partition->pt_id, args.vp_index,
 					stats_pages);
 		if (ret)
@@ -963,7 +967,7 @@ mshv_partition_ioctl_create_vp(struct mshv_partition *partition,
 	if (mshv_partition_encrypted(partition) && is_ghcb_mapping_available())
 		vp->vp_ghcb_page = page_to_virt(ghcb_page);
 
-	if (hv_parent_partition())
+	if (hv_scheduler_type == HV_SCHEDULER_TYPE_ROOT)
 		memcpy(vp->vp_stats_pages, stats_pages, sizeof(stats_pages));
 
 	/*
@@ -986,7 +990,7 @@ mshv_partition_ioctl_create_vp(struct mshv_partition *partition,
 free_vp:
 	kfree(vp);
 unmap_stats_pages:
-	if (hv_parent_partition())
+	if (hv_scheduler_type == HV_SCHEDULER_TYPE_ROOT)
 		mshv_vp_stats_unmap(partition->pt_id, args.vp_index);
 unmap_ghcb_page:
 	if (mshv_partition_encrypted(partition) && is_ghcb_mapping_available()) {
@@ -1740,7 +1744,7 @@ static void destroy_partition(struct mshv_partition *partition)
 			if (!vp)
 				continue;
 
-			if (hv_parent_partition())
+			if (hv_scheduler_type == HV_SCHEDULER_TYPE_ROOT)
 				mshv_vp_stats_unmap(partition->pt_id, vp->vp_index);
 
 			if (vp->vp_register_page) {
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v2 2/5] mshv: Add the HVCALL_GET_PARTITION_PROPERTY_EX hypercall
  2025-09-10 23:14 [PATCH v2 0/5] mshv: Fixes for stats and vp state page mappings Nuno Das Neves
  2025-09-10 23:14 ` [PATCH v2 1/5] mshv: Only map vp->vp_stats_pages if on root scheduler Nuno Das Neves
@ 2025-09-10 23:14 ` Nuno Das Neves
  2025-09-11 16:21   ` Easwar Hariharan
  2025-09-10 23:14 ` [PATCH v2 3/5] mshv: Get the vmm capabilities offered by the hypervisor Nuno Das Neves
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 10+ messages in thread
From: Nuno Das Neves @ 2025-09-10 23:14 UTC (permalink / raw)
  To: linux-hyperv, linux-kernel, prapal, easwar.hariharan, tiala,
	anirudh, paekkaladevi
  Cc: kys, haiyangz, wei.liu, decui, Nuno Das Neves

From: Purna Pavan Chandra Aekkaladevi <paekkaladevi@linux.microsoft.com>

This hypercall can be used to fetch extended properties of a
partition. Extended properties are properties with values larger than
a u64. Some of these also need additional input arguments.

Add helper function for using the hypercall in the mshv_root driver.

Signed-off-by: Purna Pavan Chandra Aekkaladevi <paekkaladevi@linux.microsoft.com>
Signed-off-by: Nuno Das Neves <nunodasneves@linux.microsoft.com>
Reviewed-by: Anirudh Rayabharam <anirudh@anirudhrb.com>
Reviewed-by: Praveen K Paladugu <prapal@linux.microsoft.com>
---
 drivers/hv/mshv_root.h         |  2 ++
 drivers/hv/mshv_root_hv_call.c | 31 ++++++++++++++++++++++++++
 include/hyperv/hvgdk_mini.h    |  1 +
 include/hyperv/hvhdk.h         | 40 ++++++++++++++++++++++++++++++++++
 include/hyperv/hvhdk_mini.h    | 26 ++++++++++++++++++++++
 5 files changed, 100 insertions(+)

diff --git a/drivers/hv/mshv_root.h b/drivers/hv/mshv_root.h
index e3931b0f1269..4aeb03bea6b6 100644
--- a/drivers/hv/mshv_root.h
+++ b/drivers/hv/mshv_root.h
@@ -303,6 +303,8 @@ int hv_call_unmap_stat_page(enum hv_stats_object_type type,
 int hv_call_modify_spa_host_access(u64 partition_id, struct page **pages,
 				   u64 page_struct_count, u32 host_access,
 				   u32 flags, u8 acquire);
+int hv_call_get_partition_property_ex(u64 partition_id, u64 property_code, u64 arg,
+				      void *property_value, size_t property_value_sz);
 
 extern struct mshv_root mshv_root;
 extern enum hv_scheduler_type hv_scheduler_type;
diff --git a/drivers/hv/mshv_root_hv_call.c b/drivers/hv/mshv_root_hv_call.c
index c9c274f29c3c..3fd3cce23f69 100644
--- a/drivers/hv/mshv_root_hv_call.c
+++ b/drivers/hv/mshv_root_hv_call.c
@@ -590,6 +590,37 @@ int hv_call_unmap_vp_state_page(u64 partition_id, u32 vp_index, u32 type,
 	return hv_result_to_errno(status);
 }
 
+int hv_call_get_partition_property_ex(u64 partition_id, u64 property_code,
+				      u64 arg, void *property_value,
+				      size_t property_value_sz)
+{
+	u64 status;
+	unsigned long flags;
+	struct hv_input_get_partition_property_ex *input;
+	struct hv_output_get_partition_property_ex *output;
+
+	local_irq_save(flags);
+	input = *this_cpu_ptr(hyperv_pcpu_input_arg);
+	output = *this_cpu_ptr(hyperv_pcpu_output_arg);
+
+	memset(input, 0, sizeof(*input));
+	input->partition_id = partition_id;
+	input->property_code = property_code;
+	input->arg = arg;
+	status = hv_do_hypercall(HVCALL_GET_PARTITION_PROPERTY_EX, input, output);
+
+	if (!hv_result_success(status)) {
+		hv_status_debug(status, "\n");
+		local_irq_restore(flags);
+		return hv_result_to_errno(status);
+	}
+	memcpy(property_value, &output->property_value, property_value_sz);
+
+	local_irq_restore(flags);
+
+	return 0;
+}
+
 int
 hv_call_clear_virtual_interrupt(u64 partition_id)
 {
diff --git a/include/hyperv/hvgdk_mini.h b/include/hyperv/hvgdk_mini.h
index 1be7f6a02304..ff4325fb623a 100644
--- a/include/hyperv/hvgdk_mini.h
+++ b/include/hyperv/hvgdk_mini.h
@@ -490,6 +490,7 @@ union hv_vp_assist_msr_contents {	 /* HV_REGISTER_VP_ASSIST_PAGE */
 #define HVCALL_GET_VP_STATE				0x00e3
 #define HVCALL_SET_VP_STATE				0x00e4
 #define HVCALL_GET_VP_CPUID_VALUES			0x00f4
+#define HVCALL_GET_PARTITION_PROPERTY_EX		0x0101
 #define HVCALL_MMIO_READ				0x0106
 #define HVCALL_MMIO_WRITE				0x0107
 
diff --git a/include/hyperv/hvhdk.h b/include/hyperv/hvhdk.h
index b4067ada02cf..b91358b9c929 100644
--- a/include/hyperv/hvhdk.h
+++ b/include/hyperv/hvhdk.h
@@ -376,6 +376,46 @@ struct hv_input_set_partition_property {
 	u64 property_value;
 } __packed;
 
+union hv_partition_property_arg {
+	u64 as_uint64;
+	struct {
+		union {
+			u32 arg;
+			u32 vp_index;
+		};
+		u16 reserved0;
+		u8 reserved1;
+		u8 object_type;
+	};
+} __packed;
+
+struct hv_input_get_partition_property_ex {
+	u64 partition_id;
+	u32 property_code; /* enum hv_partition_property_code */
+	u32 padding;
+	union {
+		union hv_partition_property_arg arg_data;
+		u64 arg;
+	};
+} __packed;
+
+/*
+ * NOTE: Should use hv_input_set_partition_property_ex_header to compute this
+ * size, but hv_input_get_partition_property_ex is identical so it suffices
+ */
+#define HV_PARTITION_PROPERTY_EX_MAX_VAR_SIZE \
+	(HV_HYP_PAGE_SIZE - sizeof(struct hv_input_get_partition_property_ex))
+
+union hv_partition_property_ex {
+	u8 buffer[HV_PARTITION_PROPERTY_EX_MAX_VAR_SIZE];
+	struct hv_partition_property_vmm_capabilities vmm_capabilities;
+	/* More fields to be filled in when needed */
+} __packed;
+
+struct hv_output_get_partition_property_ex {
+	union hv_partition_property_ex property_value;
+} __packed;
+
 enum hv_vp_state_page_type {
 	HV_VP_STATE_PAGE_REGISTERS = 0,
 	HV_VP_STATE_PAGE_INTERCEPT_MESSAGE = 1,
diff --git a/include/hyperv/hvhdk_mini.h b/include/hyperv/hvhdk_mini.h
index 858f6a3925b3..bf2ce27dfcc5 100644
--- a/include/hyperv/hvhdk_mini.h
+++ b/include/hyperv/hvhdk_mini.h
@@ -96,8 +96,34 @@ enum hv_partition_property_code {
 	HV_PARTITION_PROPERTY_XSAVE_STATES                      = 0x00060007,
 	HV_PARTITION_PROPERTY_MAX_XSAVE_DATA_SIZE		= 0x00060008,
 	HV_PARTITION_PROPERTY_PROCESSOR_CLOCK_FREQUENCY		= 0x00060009,
+
+	/* Extended properties with larger property values */
+	HV_PARTITION_PROPERTY_VMM_CAPABILITIES			= 0x00090007,
 };
 
+#define HV_PARTITION_VMM_CAPABILITIES_BANK_COUNT		1
+#define HV_PARTITION_VMM_CAPABILITIES_RESERVED_BITFIELD_COUNT	59
+
+struct hv_partition_property_vmm_capabilities {
+	u16 bank_count;
+	u16 reserved[3];
+	union {
+		u64 as_uint64[HV_PARTITION_VMM_CAPABILITIES_BANK_COUNT];
+		struct {
+			u64 map_gpa_preserve_adjustable: 1;
+			u64 vmm_can_provide_overlay_gpfn: 1;
+			u64 vp_affinity_property: 1;
+#if IS_ENABLED(CONFIG_ARM64)
+			u64 vmm_can_provide_gic_overlay_locations: 1;
+#else
+			u64 reservedbit3: 1;
+#endif
+			u64 assignable_synthetic_proc_features: 1;
+			u64 reserved0: HV_PARTITION_VMM_CAPABILITIES_RESERVED_BITFIELD_COUNT;
+		} __packed;
+	};
+} __packed;
+
 enum hv_snp_status {
 	HV_SNP_STATUS_NONE = 0,
 	HV_SNP_STATUS_AVAILABLE = 1,
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v2 3/5] mshv: Get the vmm capabilities offered by the hypervisor
  2025-09-10 23:14 [PATCH v2 0/5] mshv: Fixes for stats and vp state page mappings Nuno Das Neves
  2025-09-10 23:14 ` [PATCH v2 1/5] mshv: Only map vp->vp_stats_pages if on root scheduler Nuno Das Neves
  2025-09-10 23:14 ` [PATCH v2 2/5] mshv: Add the HVCALL_GET_PARTITION_PROPERTY_EX hypercall Nuno Das Neves
@ 2025-09-10 23:14 ` Nuno Das Neves
  2025-09-10 23:14 ` [PATCH v2 4/5] mshv: Allocate vp state page for HVCALL_MAP_VP_STATE_PAGE on L1VH Nuno Das Neves
  2025-09-10 23:14 ` [PATCH v2 5/5] mshv: Introduce new hypercall to map stats page for L1VH partitions Nuno Das Neves
  4 siblings, 0 replies; 10+ messages in thread
From: Nuno Das Neves @ 2025-09-10 23:14 UTC (permalink / raw)
  To: linux-hyperv, linux-kernel, prapal, easwar.hariharan, tiala,
	anirudh, paekkaladevi
  Cc: kys, haiyangz, wei.liu, decui, Nuno Das Neves

From: Purna Pavan Chandra Aekkaladevi <paekkaladevi@linux.microsoft.com>

Some hypervisor APIs are gated by feature bits in the
"vmm capabilities" partition property. Store the capabilities on
mshv_root module init, using HVCALL_GET_PARTITION_PROPERTY_EX.

This is not supported on all hypervisors. In that case, just set the
capabilities to 0 and proceed as normal.

Signed-off-by: Purna Pavan Chandra Aekkaladevi <paekkaladevi@linux.microsoft.com>
Signed-off-by: Nuno Das Neves <nunodasneves@linux.microsoft.com>
Reviewed-by: Praveen K Paladugu <prapal@linux.microsoft.com>
Reviewed-by: Easwar Hariharan <easwar.hariharan@linux.microsoft.com>
Reviewed-by: Tianyu Lan <tiala@microsoft.com>
---
 drivers/hv/mshv_root.h      |  1 +
 drivers/hv/mshv_root_main.c | 22 ++++++++++++++++++++++
 2 files changed, 23 insertions(+)

diff --git a/drivers/hv/mshv_root.h b/drivers/hv/mshv_root.h
index 4aeb03bea6b6..0cb1e2589fe1 100644
--- a/drivers/hv/mshv_root.h
+++ b/drivers/hv/mshv_root.h
@@ -178,6 +178,7 @@ struct mshv_root {
 	struct hv_synic_pages __percpu *synic_pages;
 	spinlock_t pt_ht_lock;
 	DECLARE_HASHTABLE(pt_htable, MSHV_PARTITIONS_HASH_BITS);
+	struct hv_partition_property_vmm_capabilities vmm_caps;
 };
 
 /*
diff --git a/drivers/hv/mshv_root_main.c b/drivers/hv/mshv_root_main.c
index 24df47726363..f7738cefbdf3 100644
--- a/drivers/hv/mshv_root_main.c
+++ b/drivers/hv/mshv_root_main.c
@@ -2201,6 +2201,26 @@ static int __init mshv_root_partition_init(struct device *dev)
 	return err;
 }
 
+static void mshv_init_vmm_caps(struct device *dev)
+{
+	int ret;
+
+	memset(&mshv_root.vmm_caps, 0, sizeof(mshv_root.vmm_caps));
+	ret = hv_call_get_partition_property_ex(HV_PARTITION_ID_SELF,
+						HV_PARTITION_PROPERTY_VMM_CAPABILITIES,
+						0, &mshv_root.vmm_caps,
+						sizeof(mshv_root.vmm_caps));
+
+	/*
+	 * HVCALL_GET_PARTITION_PROPERTY_EX or HV_PARTITION_PROPERTY_VMM_CAPABILITIES
+	 * may not be supported. Leave them as 0 in that case.
+	 */
+	if (ret)
+		dev_warn(dev, "Unable to get VMM capabilities\n");
+
+	dev_dbg(dev, "vmm_caps=0x%llx\n", mshv_root.vmm_caps.as_uint64[0]);
+}
+
 static int __init mshv_parent_partition_init(void)
 {
 	int ret;
@@ -2253,6 +2273,8 @@ static int __init mshv_parent_partition_init(void)
 	if (ret)
 		goto remove_cpu_state;
 
+	mshv_init_vmm_caps(dev);
+
 	ret = mshv_irqfd_wq_init();
 	if (ret)
 		goto exit_partition;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v2 4/5] mshv: Allocate vp state page for HVCALL_MAP_VP_STATE_PAGE on L1VH
  2025-09-10 23:14 [PATCH v2 0/5] mshv: Fixes for stats and vp state page mappings Nuno Das Neves
                   ` (2 preceding siblings ...)
  2025-09-10 23:14 ` [PATCH v2 3/5] mshv: Get the vmm capabilities offered by the hypervisor Nuno Das Neves
@ 2025-09-10 23:14 ` Nuno Das Neves
  2025-09-11 19:05   ` kernel test robot
  2025-09-10 23:14 ` [PATCH v2 5/5] mshv: Introduce new hypercall to map stats page for L1VH partitions Nuno Das Neves
  4 siblings, 1 reply; 10+ messages in thread
From: Nuno Das Neves @ 2025-09-10 23:14 UTC (permalink / raw)
  To: linux-hyperv, linux-kernel, prapal, easwar.hariharan, tiala,
	anirudh, paekkaladevi
  Cc: kys, haiyangz, wei.liu, decui, Jinank Jain, Nuno Das Neves

From: Jinank Jain <jinankjain@linux.microsoft.com>

Introduce mshv_use_overlay_gpfn() to check if a page needs to be
allocated and passed to the hypervisor to map VP state pages. This is
only needed on L1VH, and only on some (newer) versions of the
hypervisor, hence the need to check vmm_capabilities.

Introduce functions hv_map/unmap_vp_state_page() to handle the
allocation and freeing.

Signed-off-by: Jinank Jain <jinankjain@linux.microsoft.com>
Signed-off-by: Nuno Das Neves <nunodasneves@linux.microsoft.com>
Reviewed-by: Praveen K Paladugu <prapal@linux.microsoft.com>
Reviewed-by: Easwar Hariharan <easwar.hariharan@linux.microsoft.com>
---
 drivers/hv/mshv_root.h         | 11 +++---
 drivers/hv/mshv_root_hv_call.c | 61 +++++++++++++++++++++++++---
 drivers/hv/mshv_root_main.c    | 72 +++++++++++++++++-----------------
 3 files changed, 96 insertions(+), 48 deletions(-)

diff --git a/drivers/hv/mshv_root.h b/drivers/hv/mshv_root.h
index 0cb1e2589fe1..d7c9520ef788 100644
--- a/drivers/hv/mshv_root.h
+++ b/drivers/hv/mshv_root.h
@@ -279,11 +279,12 @@ int hv_call_set_vp_state(u32 vp_index, u64 partition_id,
 			 /* Choose between pages and bytes */
 			 struct hv_vp_state_data state_data, u64 page_count,
 			 struct page **pages, u32 num_bytes, u8 *bytes);
-int hv_call_map_vp_state_page(u64 partition_id, u32 vp_index, u32 type,
-			      union hv_input_vtl input_vtl,
-			      struct page **state_page);
-int hv_call_unmap_vp_state_page(u64 partition_id, u32 vp_index, u32 type,
-				union hv_input_vtl input_vtl);
+int hv_map_vp_state_page(u64 partition_id, u32 vp_index, u32 type,
+			 union hv_input_vtl input_vtl,
+			 struct page **state_page);
+int hv_unmap_vp_state_page(u64 partition_id, u32 vp_index, u32 type,
+			   void *page_addr,
+			   union hv_input_vtl input_vtl);
 int hv_call_create_port(u64 port_partition_id, union hv_port_id port_id,
 			u64 connection_partition_id, struct hv_port_info *port_info,
 			u8 port_vtl, u8 min_connection_vtl, int node);
diff --git a/drivers/hv/mshv_root_hv_call.c b/drivers/hv/mshv_root_hv_call.c
index 3fd3cce23f69..1132ba7b2399 100644
--- a/drivers/hv/mshv_root_hv_call.c
+++ b/drivers/hv/mshv_root_hv_call.c
@@ -526,9 +526,9 @@ int hv_call_set_vp_state(u32 vp_index, u64 partition_id,
 	return ret;
 }
 
-int hv_call_map_vp_state_page(u64 partition_id, u32 vp_index, u32 type,
-			      union hv_input_vtl input_vtl,
-			      struct page **state_page)
+static int hv_call_map_vp_state_page(u64 partition_id, u32 vp_index, u32 type,
+				     union hv_input_vtl input_vtl,
+				     struct page **state_page)
 {
 	struct hv_input_map_vp_state_page *input;
 	struct hv_output_map_vp_state_page *output;
@@ -547,7 +547,14 @@ int hv_call_map_vp_state_page(u64 partition_id, u32 vp_index, u32 type,
 		input->type = type;
 		input->input_vtl = input_vtl;
 
-		status = hv_do_hypercall(HVCALL_MAP_VP_STATE_PAGE, input, output);
+		if (*state_page) {
+			input->flags.map_location_provided = 1;
+			input->requested_map_location =
+				page_to_pfn(*state_page);
+		}
+
+		status = hv_do_hypercall(HVCALL_MAP_VP_STATE_PAGE, input,
+					 output);
 
 		if (hv_result(status) != HV_STATUS_INSUFFICIENT_MEMORY) {
 			if (hv_result_success(status))
@@ -565,8 +572,39 @@ int hv_call_map_vp_state_page(u64 partition_id, u32 vp_index, u32 type,
 	return ret;
 }
 
-int hv_call_unmap_vp_state_page(u64 partition_id, u32 vp_index, u32 type,
-				union hv_input_vtl input_vtl)
+static bool mshv_use_overlay_gpfn(void)
+{
+	return hv_l1vh_partition() &&
+	       mshv_root.vmm_caps.vmm_can_provide_overlay_gpfn;
+}
+
+int hv_map_vp_state_page(u64 partition_id, u32 vp_index, u32 type,
+			 union hv_input_vtl input_vtl,
+			 struct page **state_page)
+{
+	int ret = 0;
+	struct page *allocated_page = NULL;
+
+	if (mshv_use_overlay_gpfn()) {
+		allocated_page = alloc_page(GFP_KERNEL);
+		if (!allocated_page)
+			return -ENOMEM;
+		*state_page = allocated_page;
+	} else {
+		*state_page = NULL;
+	}
+
+	ret = hv_call_map_vp_state_page(partition_id, vp_index, type, input_vtl,
+					state_page);
+
+	if (ret && allocated_page)
+		__free_page(allocated_page);
+
+	return ret;
+}
+
+static int hv_call_unmap_vp_state_page(u64 partition_id, u32 vp_index, u32 type,
+				       union hv_input_vtl input_vtl)
 {
 	unsigned long flags;
 	u64 status;
@@ -590,6 +628,17 @@ int hv_call_unmap_vp_state_page(u64 partition_id, u32 vp_index, u32 type,
 	return hv_result_to_errno(status);
 }
 
+int hv_unmap_vp_state_page(u64 partition_id, u32 vp_index, u32 type,
+			   void *page_addr, union hv_input_vtl input_vtl)
+{
+	int ret = hv_call_unmap_vp_state_page(partition_id, vp_index, type, input_vtl);
+
+	if (mshv_use_overlay_gpfn() && page_addr)
+		__free_page(virt_to_page(page_addr));
+
+	return ret;
+}
+
 int hv_call_get_partition_property_ex(u64 partition_id, u64 property_code,
 				      u64 arg, void *property_value,
 				      size_t property_value_sz)
diff --git a/drivers/hv/mshv_root_main.c b/drivers/hv/mshv_root_main.c
index f7738cefbdf3..7352c4f9652e 100644
--- a/drivers/hv/mshv_root_main.c
+++ b/drivers/hv/mshv_root_main.c
@@ -908,28 +908,25 @@ mshv_partition_ioctl_create_vp(struct mshv_partition *partition,
 	if (ret)
 		return ret;
 
-	ret = hv_call_map_vp_state_page(partition->pt_id, args.vp_index,
-					HV_VP_STATE_PAGE_INTERCEPT_MESSAGE,
-					input_vtl_zero,
-					&intercept_message_page);
+	ret = hv_map_vp_state_page(partition->pt_id, args.vp_index,
+				   HV_VP_STATE_PAGE_INTERCEPT_MESSAGE,
+				   input_vtl_zero, &intercept_message_page);
 	if (ret)
 		goto destroy_vp;
 
 	if (!mshv_partition_encrypted(partition)) {
-		ret = hv_call_map_vp_state_page(partition->pt_id, args.vp_index,
-						HV_VP_STATE_PAGE_REGISTERS,
-						input_vtl_zero,
-						&register_page);
+		ret = hv_map_vp_state_page(partition->pt_id, args.vp_index,
+					   HV_VP_STATE_PAGE_REGISTERS,
+					   input_vtl_zero, &register_page);
 		if (ret)
 			goto unmap_intercept_message_page;
 	}
 
 	if (mshv_partition_encrypted(partition) &&
 	    is_ghcb_mapping_available()) {
-		ret = hv_call_map_vp_state_page(partition->pt_id, args.vp_index,
-						HV_VP_STATE_PAGE_GHCB,
-						input_vtl_normal,
-						&ghcb_page);
+		ret = hv_map_vp_state_page(partition->pt_id, args.vp_index,
+					   HV_VP_STATE_PAGE_GHCB,
+					   input_vtl_normal, &ghcb_page);
 		if (ret)
 			goto unmap_register_page;
 	}
@@ -993,21 +990,19 @@ mshv_partition_ioctl_create_vp(struct mshv_partition *partition,
 	if (hv_scheduler_type == HV_SCHEDULER_TYPE_ROOT)
 		mshv_vp_stats_unmap(partition->pt_id, args.vp_index);
 unmap_ghcb_page:
-	if (mshv_partition_encrypted(partition) && is_ghcb_mapping_available()) {
-		hv_call_unmap_vp_state_page(partition->pt_id, args.vp_index,
-					    HV_VP_STATE_PAGE_GHCB,
-					    input_vtl_normal);
-	}
+	if (mshv_partition_encrypted(partition) && is_ghcb_mapping_available())
+		hv_unmap_vp_state_page(partition->pt_id, args.vp_index,
+				       HV_VP_STATE_PAGE_GHCB, vp->vp_ghcb_page,
+				       input_vtl_normal);
 unmap_register_page:
-	if (!mshv_partition_encrypted(partition)) {
-		hv_call_unmap_vp_state_page(partition->pt_id, args.vp_index,
-					    HV_VP_STATE_PAGE_REGISTERS,
-					    input_vtl_zero);
-	}
+	if (!mshv_partition_encrypted(partition))
+		hv_unmap_vp_state_page(partition->pt_id, args.vp_index,
+				       HV_VP_STATE_PAGE_REGISTERS,
+				       vp->vp_register_page, input_vtl_zero);
 unmap_intercept_message_page:
-	hv_call_unmap_vp_state_page(partition->pt_id, args.vp_index,
-				    HV_VP_STATE_PAGE_INTERCEPT_MESSAGE,
-				    input_vtl_zero);
+	hv_unmap_vp_state_page(partition->pt_id, args.vp_index,
+			       HV_VP_STATE_PAGE_INTERCEPT_MESSAGE,
+			       vp->vp_intercept_msg_page, input_vtl_zero);
 destroy_vp:
 	hv_call_delete_vp(partition->pt_id, args.vp_index);
 	return ret;
@@ -1748,24 +1743,27 @@ static void destroy_partition(struct mshv_partition *partition)
 				mshv_vp_stats_unmap(partition->pt_id, vp->vp_index);
 
 			if (vp->vp_register_page) {
-				(void)hv_call_unmap_vp_state_page(partition->pt_id,
-								  vp->vp_index,
-								  HV_VP_STATE_PAGE_REGISTERS,
-								  input_vtl_zero);
+				(void)hv_unmap_vp_state_page(partition->pt_id,
+							     vp->vp_index,
+							     HV_VP_STATE_PAGE_REGISTERS,
+							     vp->vp_register_page,
+							     input_vtl_zero);
 				vp->vp_register_page = NULL;
 			}
 
-			(void)hv_call_unmap_vp_state_page(partition->pt_id,
-							  vp->vp_index,
-							  HV_VP_STATE_PAGE_INTERCEPT_MESSAGE,
-							  input_vtl_zero);
+			(void)hv_unmap_vp_state_page(partition->pt_id,
+						     vp->vp_index,
+						     HV_VP_STATE_PAGE_INTERCEPT_MESSAGE,
+						     vp->vp_intercept_msg_page,
+						     input_vtl_zero);
 			vp->vp_intercept_msg_page = NULL;
 
 			if (vp->vp_ghcb_page) {
-				(void)hv_call_unmap_vp_state_page(partition->pt_id,
-								  vp->vp_index,
-								  HV_VP_STATE_PAGE_GHCB,
-								  input_vtl_normal);
+				(void)hv_unmap_vp_state_page(partition->pt_id,
+							     vp->vp_index,
+							     HV_VP_STATE_PAGE_GHCB,
+							     vp->vp_ghcb_page,
+							     input_vtl_normal);
 				vp->vp_ghcb_page = NULL;
 			}
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v2 5/5] mshv: Introduce new hypercall to map stats page for L1VH partitions
  2025-09-10 23:14 [PATCH v2 0/5] mshv: Fixes for stats and vp state page mappings Nuno Das Neves
                   ` (3 preceding siblings ...)
  2025-09-10 23:14 ` [PATCH v2 4/5] mshv: Allocate vp state page for HVCALL_MAP_VP_STATE_PAGE on L1VH Nuno Das Neves
@ 2025-09-10 23:14 ` Nuno Das Neves
  2025-09-11 16:32   ` Easwar Hariharan
  4 siblings, 1 reply; 10+ messages in thread
From: Nuno Das Neves @ 2025-09-10 23:14 UTC (permalink / raw)
  To: linux-hyperv, linux-kernel, prapal, easwar.hariharan, tiala,
	anirudh, paekkaladevi
  Cc: kys, haiyangz, wei.liu, decui, Jinank Jain, Nuno Das Neves

From: Jinank Jain <jinankjain@linux.microsoft.com>

Introduce HVCALL_MAP_STATS_PAGE2 which provides a map location (GPFN)
to map the stats to. This hypercall is required for L1VH partitions,
depending on the hypervisor version. This uses the same check as the
state page map location; mshv_use_overlay_gpfn().

Add mshv_map_vp_state_page() helpers to use this new hypercall or the
old one depending on availability.

For unmapping, the original HVCALL_UNMAP_STATS_PAGE works for both
cases.

Signed-off-by: Jinank Jain <jinankjain@linux.microsoft.com>
Signed-off-by: Nuno Das Neves <nunodasneves@linux.microsoft.com>
---
 drivers/hv/mshv_root.h         | 10 ++--
 drivers/hv/mshv_root_hv_call.c | 89 ++++++++++++++++++++++++++++++++--
 drivers/hv/mshv_root_main.c    | 25 ++++++----
 include/hyperv/hvgdk_mini.h    |  1 +
 include/hyperv/hvhdk_mini.h    |  7 +++
 5 files changed, 112 insertions(+), 20 deletions(-)

diff --git a/drivers/hv/mshv_root.h b/drivers/hv/mshv_root.h
index d7c9520ef788..d16a020ae0ee 100644
--- a/drivers/hv/mshv_root.h
+++ b/drivers/hv/mshv_root.h
@@ -297,11 +297,11 @@ int hv_call_connect_port(u64 port_partition_id, union hv_port_id port_id,
 int hv_call_disconnect_port(u64 connection_partition_id,
 			    union hv_connection_id connection_id);
 int hv_call_notify_port_ring_empty(u32 sint_index);
-int hv_call_map_stat_page(enum hv_stats_object_type type,
-			  const union hv_stats_object_identity *identity,
-			  void **addr);
-int hv_call_unmap_stat_page(enum hv_stats_object_type type,
-			    const union hv_stats_object_identity *identity);
+int hv_map_stats_page(enum hv_stats_object_type type,
+		      const union hv_stats_object_identity *identity,
+		      void **addr);
+int hv_unmap_stats_page(enum hv_stats_object_type type, void *page_addr,
+			const union hv_stats_object_identity *identity);
 int hv_call_modify_spa_host_access(u64 partition_id, struct page **pages,
 				   u64 page_struct_count, u32 host_access,
 				   u32 flags, u8 acquire);
diff --git a/drivers/hv/mshv_root_hv_call.c b/drivers/hv/mshv_root_hv_call.c
index 1132ba7b2399..a8cb91ce11cc 100644
--- a/drivers/hv/mshv_root_hv_call.c
+++ b/drivers/hv/mshv_root_hv_call.c
@@ -804,9 +804,47 @@ hv_call_notify_port_ring_empty(u32 sint_index)
 	return hv_result_to_errno(status);
 }
 
-int hv_call_map_stat_page(enum hv_stats_object_type type,
-			  const union hv_stats_object_identity *identity,
-			  void **addr)
+static int hv_call_map_stats_page2(enum hv_stats_object_type type,
+				   const union hv_stats_object_identity *identity,
+				   u64 map_location)
+{
+	unsigned long flags;
+	struct hv_input_map_stats_page2 *input;
+	u64 status;
+	int ret;
+
+	if (!map_location || !mshv_use_overlay_gpfn())
+		return -EINVAL;
+
+	do {
+		local_irq_save(flags);
+		input = *this_cpu_ptr(hyperv_pcpu_input_arg);
+
+		memset(input, 0, sizeof(*input));
+		input->type = type;
+		input->identity = *identity;
+		input->map_location = map_location;
+
+		status = hv_do_hypercall(HVCALL_MAP_STATS_PAGE2, input, NULL);
+
+		local_irq_restore(flags);
+		if (hv_result(status) != HV_STATUS_INSUFFICIENT_MEMORY) {
+			if (hv_result_success(status))
+				break;
+			hv_status_debug(status, "\n");
+			return hv_result_to_errno(status);
+		}
+
+		ret = hv_call_deposit_pages(NUMA_NO_NODE,
+					    hv_current_partition_id, 1);
+	} while (!ret);
+
+	return ret;
+}
+
+static int hv_call_map_stats_page(enum hv_stats_object_type type,
+				  const union hv_stats_object_identity *identity,
+				  void **addr)
 {
 	unsigned long flags;
 	struct hv_input_map_stats_page *input;
@@ -845,8 +883,36 @@ int hv_call_map_stat_page(enum hv_stats_object_type type,
 	return ret;
 }
 
-int hv_call_unmap_stat_page(enum hv_stats_object_type type,
-			    const union hv_stats_object_identity *identity)
+int hv_map_stats_page(enum hv_stats_object_type type,
+		      const union hv_stats_object_identity *identity,
+		      void **addr)
+{
+	int ret;
+	struct page *allocated_page = NULL;
+
+	if (!addr)
+		return -EINVAL;
+
+	if (mshv_use_overlay_gpfn()) {
+		allocated_page = alloc_page(GFP_KERNEL);
+		if (!allocated_page)
+			return -ENOMEM;
+
+		ret = hv_call_map_stats_page2(type, identity,
+					      page_to_pfn(allocated_page));
+		*addr = page_address(allocated_page);
+	} else {
+		ret = hv_call_map_stats_page(type, identity, addr);
+	}
+
+	if (ret && allocated_page)
+		__free_page(allocated_page);
+
+	return ret;
+}
+
+static int hv_call_unmap_stats_page(enum hv_stats_object_type type,
+				    const union hv_stats_object_identity *identity)
 {
 	unsigned long flags;
 	struct hv_input_unmap_stats_page *input;
@@ -865,6 +931,19 @@ int hv_call_unmap_stat_page(enum hv_stats_object_type type,
 	return hv_result_to_errno(status);
 }
 
+int hv_unmap_stats_page(enum hv_stats_object_type type, void *page_addr,
+			const union hv_stats_object_identity *identity)
+{
+	int ret;
+
+	ret = hv_call_unmap_stats_page(type, identity);
+
+	if (mshv_use_overlay_gpfn() && page_addr)
+		__free_page(virt_to_page(page_addr));
+
+	return ret;
+}
+
 int hv_call_modify_spa_host_access(u64 partition_id, struct page **pages,
 				   u64 page_struct_count, u32 host_access,
 				   u32 flags, u8 acquire)
diff --git a/drivers/hv/mshv_root_main.c b/drivers/hv/mshv_root_main.c
index 7352c4f9652e..27fcf8a13faa 100644
--- a/drivers/hv/mshv_root_main.c
+++ b/drivers/hv/mshv_root_main.c
@@ -841,7 +841,8 @@ mshv_vp_release(struct inode *inode, struct file *filp)
 	return 0;
 }
 
-static void mshv_vp_stats_unmap(u64 partition_id, u32 vp_index)
+static void mshv_vp_stats_unmap(u64 partition_id, u32 vp_index,
+				void *stats_pages[])
 {
 	union hv_stats_object_identity identity = {
 		.vp.partition_id = partition_id,
@@ -849,10 +850,13 @@ static void mshv_vp_stats_unmap(u64 partition_id, u32 vp_index)
 	};
 
 	identity.vp.stats_area_type = HV_STATS_AREA_SELF;
-	hv_call_unmap_stat_page(HV_STATS_OBJECT_VP, &identity);
+	hv_unmap_stats_page(HV_STATS_OBJECT_VP, NULL, &identity);
+
+	if (stats_pages[HV_STATS_AREA_PARENT] == stats_pages[HV_STATS_AREA_SELF])
+		return;
 
 	identity.vp.stats_area_type = HV_STATS_AREA_PARENT;
-	hv_call_unmap_stat_page(HV_STATS_OBJECT_VP, &identity);
+	hv_unmap_stats_page(HV_STATS_OBJECT_VP, NULL, &identity);
 }
 
 static int mshv_vp_stats_map(u64 partition_id, u32 vp_index,
@@ -865,14 +869,14 @@ static int mshv_vp_stats_map(u64 partition_id, u32 vp_index,
 	int err;
 
 	identity.vp.stats_area_type = HV_STATS_AREA_SELF;
-	err = hv_call_map_stat_page(HV_STATS_OBJECT_VP, &identity,
-				    &stats_pages[HV_STATS_AREA_SELF]);
+	err = hv_map_stats_page(HV_STATS_OBJECT_VP, &identity,
+				&stats_pages[HV_STATS_AREA_SELF]);
 	if (err)
 		return err;
 
 	identity.vp.stats_area_type = HV_STATS_AREA_PARENT;
-	err = hv_call_map_stat_page(HV_STATS_OBJECT_VP, &identity,
-				    &stats_pages[HV_STATS_AREA_PARENT]);
+	err = hv_map_stats_page(HV_STATS_OBJECT_VP, &identity,
+				&stats_pages[HV_STATS_AREA_PARENT]);
 	if (err)
 		goto unmap_self;
 
@@ -880,7 +884,7 @@ static int mshv_vp_stats_map(u64 partition_id, u32 vp_index,
 
 unmap_self:
 	identity.vp.stats_area_type = HV_STATS_AREA_SELF;
-	hv_call_unmap_stat_page(HV_STATS_OBJECT_VP, &identity);
+	hv_unmap_stats_page(HV_STATS_OBJECT_VP, NULL, &identity);
 	return err;
 }
 
@@ -988,7 +992,7 @@ mshv_partition_ioctl_create_vp(struct mshv_partition *partition,
 	kfree(vp);
 unmap_stats_pages:
 	if (hv_scheduler_type == HV_SCHEDULER_TYPE_ROOT)
-		mshv_vp_stats_unmap(partition->pt_id, args.vp_index);
+		mshv_vp_stats_unmap(partition->pt_id, args.vp_index, stats_pages);
 unmap_ghcb_page:
 	if (mshv_partition_encrypted(partition) && is_ghcb_mapping_available())
 		hv_unmap_vp_state_page(partition->pt_id, args.vp_index,
@@ -1740,7 +1744,8 @@ static void destroy_partition(struct mshv_partition *partition)
 				continue;
 
 			if (hv_scheduler_type == HV_SCHEDULER_TYPE_ROOT)
-				mshv_vp_stats_unmap(partition->pt_id, vp->vp_index);
+				mshv_vp_stats_unmap(partition->pt_id, vp->vp_index,
+						    (void **)vp->vp_stats_pages);
 
 			if (vp->vp_register_page) {
 				(void)hv_unmap_vp_state_page(partition->pt_id,
diff --git a/include/hyperv/hvgdk_mini.h b/include/hyperv/hvgdk_mini.h
index ff4325fb623a..f66565106d21 100644
--- a/include/hyperv/hvgdk_mini.h
+++ b/include/hyperv/hvgdk_mini.h
@@ -493,6 +493,7 @@ union hv_vp_assist_msr_contents {	 /* HV_REGISTER_VP_ASSIST_PAGE */
 #define HVCALL_GET_PARTITION_PROPERTY_EX		0x0101
 #define HVCALL_MMIO_READ				0x0106
 #define HVCALL_MMIO_WRITE				0x0107
+#define HVCALL_MAP_STATS_PAGE2				0x0131
 
 /* HV_HYPERCALL_INPUT */
 #define HV_HYPERCALL_RESULT_MASK	GENMASK_ULL(15, 0)
diff --git a/include/hyperv/hvhdk_mini.h b/include/hyperv/hvhdk_mini.h
index bf2ce27dfcc5..064bf735cab6 100644
--- a/include/hyperv/hvhdk_mini.h
+++ b/include/hyperv/hvhdk_mini.h
@@ -177,6 +177,13 @@ struct hv_input_map_stats_page {
 	union hv_stats_object_identity identity;
 } __packed;
 
+struct hv_input_map_stats_page2 {
+	u32 type; /* enum hv_stats_object_type */
+	u32 padding;
+	union hv_stats_object_identity identity;
+	u64 map_location;
+} __packed;
+
 struct hv_output_map_stats_page {
 	u64 map_location;
 } __packed;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH v2 2/5] mshv: Add the HVCALL_GET_PARTITION_PROPERTY_EX hypercall
  2025-09-10 23:14 ` [PATCH v2 2/5] mshv: Add the HVCALL_GET_PARTITION_PROPERTY_EX hypercall Nuno Das Neves
@ 2025-09-11 16:21   ` Easwar Hariharan
  0 siblings, 0 replies; 10+ messages in thread
From: Easwar Hariharan @ 2025-09-11 16:21 UTC (permalink / raw)
  To: Nuno Das Neves
  Cc: linux-hyperv, linux-kernel, prapal, tiala, anirudh, paekkaladevi,
	easwar.hariharan, kys, haiyangz, wei.liu, decui

On 9/10/2025 4:14 PM, Nuno Das Neves wrote:
> From: Purna Pavan Chandra Aekkaladevi <paekkaladevi@linux.microsoft.com>
> 
> This hypercall can be used to fetch extended properties of a
> partition. Extended properties are properties with values larger than
> a u64. Some of these also need additional input arguments.
> 
> Add helper function for using the hypercall in the mshv_root driver.
> 
> Signed-off-by: Purna Pavan Chandra Aekkaladevi <paekkaladevi@linux.microsoft.com>
> Signed-off-by: Nuno Das Neves <nunodasneves@linux.microsoft.com>
> Reviewed-by: Anirudh Rayabharam <anirudh@anirudhrb.com>
> Reviewed-by: Praveen K Paladugu <prapal@linux.microsoft.com>
> ---
>  drivers/hv/mshv_root.h         |  2 ++
>  drivers/hv/mshv_root_hv_call.c | 31 ++++++++++++++++++++++++++
>  include/hyperv/hvgdk_mini.h    |  1 +
>  include/hyperv/hvhdk.h         | 40 ++++++++++++++++++++++++++++++++++
>  include/hyperv/hvhdk_mini.h    | 26 ++++++++++++++++++++++
>  5 files changed, 100 insertions(+)

<snip>

Reviewed-by: Easwar Hariharan <easwar.hariharan@linux.microsoft.com>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2 5/5] mshv: Introduce new hypercall to map stats page for L1VH partitions
  2025-09-10 23:14 ` [PATCH v2 5/5] mshv: Introduce new hypercall to map stats page for L1VH partitions Nuno Das Neves
@ 2025-09-11 16:32   ` Easwar Hariharan
  2025-09-11 18:00     ` Nuno Das Neves
  0 siblings, 1 reply; 10+ messages in thread
From: Easwar Hariharan @ 2025-09-11 16:32 UTC (permalink / raw)
  To: Nuno Das Neves
  Cc: linux-hyperv, linux-kernel, prapal, tiala, anirudh, paekkaladevi,
	easwar.hariharan, kys, haiyangz, wei.liu, decui, Jinank Jain

On 9/10/2025 4:14 PM, Nuno Das Neves wrote:
> From: Jinank Jain <jinankjain@linux.microsoft.com>
> 
> Introduce HVCALL_MAP_STATS_PAGE2 which provides a map location (GPFN)
> to map the stats to. This hypercall is required for L1VH partitions,
> depending on the hypervisor version. This uses the same check as the
> state page map location; mshv_use_overlay_gpfn().
> 
> Add mshv_map_vp_state_page() helpers to use this new hypercall or the
> old one depending on availability.
> 
> For unmapping, the original HVCALL_UNMAP_STATS_PAGE works for both
> cases.
> 
> Signed-off-by: Jinank Jain <jinankjain@linux.microsoft.com>
> Signed-off-by: Nuno Das Neves <nunodasneves@linux.microsoft.com>
> ---
>  drivers/hv/mshv_root.h         | 10 ++--
>  drivers/hv/mshv_root_hv_call.c | 89 ++++++++++++++++++++++++++++++++--
>  drivers/hv/mshv_root_main.c    | 25 ++++++----
>  include/hyperv/hvgdk_mini.h    |  1 +
>  include/hyperv/hvhdk_mini.h    |  7 +++
>  5 files changed, 112 insertions(+), 20 deletions(-)
> 
<snip>

> @@ -849,10 +850,13 @@ static void mshv_vp_stats_unmap(u64 partition_id, u32 vp_index)
>  	};
>  
>  	identity.vp.stats_area_type = HV_STATS_AREA_SELF;
> -	hv_call_unmap_stat_page(HV_STATS_OBJECT_VP, &identity);
> +	hv_unmap_stats_page(HV_STATS_OBJECT_VP, NULL, &identity);
> +
> +	if (stats_pages[HV_STATS_AREA_PARENT] == stats_pages[HV_STATS_AREA_SELF])
> +		return;

Nit, without patch 2, this hunk is a no-op. Despite that, looks good to me.

Reviewed-by: Easwar Hariharan <easwar.hariharan@linux.microsoft.com>

>  
>  	identity.vp.stats_area_type = HV_STATS_AREA_PARENT;
> -	hv_call_unmap_stat_page(HV_STATS_OBJECT_VP, &identity);
> +	hv_unmap_stats_page(HV_STATS_OBJECT_VP, NULL, &identity);
>  }

<snip>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2 5/5] mshv: Introduce new hypercall to map stats page for L1VH partitions
  2025-09-11 16:32   ` Easwar Hariharan
@ 2025-09-11 18:00     ` Nuno Das Neves
  0 siblings, 0 replies; 10+ messages in thread
From: Nuno Das Neves @ 2025-09-11 18:00 UTC (permalink / raw)
  To: Easwar Hariharan
  Cc: linux-hyperv, linux-kernel, prapal, tiala, anirudh, paekkaladevi,
	kys, haiyangz, wei.liu, decui, Jinank Jain

On 9/11/2025 9:32 AM, Easwar Hariharan wrote:
> On 9/10/2025 4:14 PM, Nuno Das Neves wrote:
>> From: Jinank Jain <jinankjain@linux.microsoft.com>
>>
>> Introduce HVCALL_MAP_STATS_PAGE2 which provides a map location (GPFN)
>> to map the stats to. This hypercall is required for L1VH partitions,
>> depending on the hypervisor version. This uses the same check as the
>> state page map location; mshv_use_overlay_gpfn().
>>
>> Add mshv_map_vp_state_page() helpers to use this new hypercall or the
>> old one depending on availability.
>>
>> For unmapping, the original HVCALL_UNMAP_STATS_PAGE works for both
>> cases.
>>
>> Signed-off-by: Jinank Jain <jinankjain@linux.microsoft.com>
>> Signed-off-by: Nuno Das Neves <nunodasneves@linux.microsoft.com>
>> ---
>>  drivers/hv/mshv_root.h         | 10 ++--
>>  drivers/hv/mshv_root_hv_call.c | 89 ++++++++++++++++++++++++++++++++--
>>  drivers/hv/mshv_root_main.c    | 25 ++++++----
>>  include/hyperv/hvgdk_mini.h    |  1 +
>>  include/hyperv/hvhdk_mini.h    |  7 +++
>>  5 files changed, 112 insertions(+), 20 deletions(-)
>>
> <snip>
> 
>> @@ -849,10 +850,13 @@ static void mshv_vp_stats_unmap(u64 partition_id, u32 vp_index)
>>  	};
>>  
>>  	identity.vp.stats_area_type = HV_STATS_AREA_SELF;
>> -	hv_call_unmap_stat_page(HV_STATS_OBJECT_VP, &identity);
>> +	hv_unmap_stats_page(HV_STATS_OBJECT_VP, NULL, &identity);
>> +
>> +	if (stats_pages[HV_STATS_AREA_PARENT] == stats_pages[HV_STATS_AREA_SELF])
>> +		return;
> 
> Nit, without patch 2, this hunk is a no-op. Despite that, looks good to me.
> 
Ah, thanks - in fact it probably should have been in that patch instead of
this one in the first place.

> Reviewed-by: Easwar Hariharan <easwar.hariharan@linux.microsoft.com>
> 
>>  
>>  	identity.vp.stats_area_type = HV_STATS_AREA_PARENT;
>> -	hv_call_unmap_stat_page(HV_STATS_OBJECT_VP, &identity);
>> +	hv_unmap_stats_page(HV_STATS_OBJECT_VP, NULL, &identity);
>>  }
> 
> <snip>


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2 4/5] mshv: Allocate vp state page for HVCALL_MAP_VP_STATE_PAGE on L1VH
  2025-09-10 23:14 ` [PATCH v2 4/5] mshv: Allocate vp state page for HVCALL_MAP_VP_STATE_PAGE on L1VH Nuno Das Neves
@ 2025-09-11 19:05   ` kernel test robot
  0 siblings, 0 replies; 10+ messages in thread
From: kernel test robot @ 2025-09-11 19:05 UTC (permalink / raw)
  To: Nuno Das Neves, linux-hyperv, linux-kernel, prapal,
	easwar.hariharan, tiala, anirudh, paekkaladevi
  Cc: llvm, oe-kbuild-all, kys, haiyangz, wei.liu, decui, Jinank Jain,
	Nuno Das Neves

Hi Nuno,

kernel test robot noticed the following build warnings:

[auto build test WARNING on linus/master]
[also build test WARNING on v6.17-rc5 next-20250911]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Nuno-Das-Neves/mshv-Only-map-vp-vp_stats_pages-if-on-root-scheduler/20250911-071732
base:   linus/master
patch link:    https://lore.kernel.org/r/1757546089-2002-5-git-send-email-nunodasneves%40linux.microsoft.com
patch subject: [PATCH v2 4/5] mshv: Allocate vp state page for HVCALL_MAP_VP_STATE_PAGE on L1VH
config: x86_64-randconfig-072-20250911 (https://download.01.org/0day-ci/archive/20250912/202509120214.YMomVkdP-lkp@intel.com/config)
compiler: clang version 20.1.8 (https://github.com/llvm/llvm-project 87f0227cb60147a26a1eeb4fb06e3b505e9c7261)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250912/202509120214.YMomVkdP-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202509120214.YMomVkdP-lkp@intel.com/

All warnings (new ones prefixed by >>):

>> drivers/hv/mshv_root_main.c:966:7: warning: variable 'vp' is used uninitialized whenever 'if' condition is true [-Wsometimes-uninitialized]
     966 |                 if (ret)
         |                     ^~~
   drivers/hv/mshv_root_main.c:1030:11: note: uninitialized use occurs here
    1030 |                                vp->vp_intercept_msg_page, input_vtl_zero);
         |                                ^~
   drivers/hv/mshv_root_main.c:966:3: note: remove the 'if' if its condition is always false
     966 |                 if (ret)
         |                 ^~~~~~~~
     967 |                         goto unmap_ghcb_page;
         |                         ~~~~~~~~~~~~~~~~~~~~
   drivers/hv/mshv_root_main.c:955:7: warning: variable 'vp' is used uninitialized whenever 'if' condition is true [-Wsometimes-uninitialized]
     955 |                 if (ret)
         |                     ^~~
   drivers/hv/mshv_root_main.c:1030:11: note: uninitialized use occurs here
    1030 |                                vp->vp_intercept_msg_page, input_vtl_zero);
         |                                ^~
   drivers/hv/mshv_root_main.c:955:3: note: remove the 'if' if its condition is always false
     955 |                 if (ret)
         |                 ^~~~~~~~
     956 |                         goto unmap_register_page;
         |                         ~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/hv/mshv_root_main.c:946:7: warning: variable 'vp' is used uninitialized whenever 'if' condition is true [-Wsometimes-uninitialized]
     946 |                 if (ret)
         |                     ^~~
   drivers/hv/mshv_root_main.c:1030:11: note: uninitialized use occurs here
    1030 |                                vp->vp_intercept_msg_page, input_vtl_zero);
         |                                ^~
   drivers/hv/mshv_root_main.c:946:3: note: remove the 'if' if its condition is always false
     946 |                 if (ret)
         |                 ^~~~~~~~
     947 |                         goto unmap_intercept_message_page;
         |                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/hv/mshv_root_main.c:917:20: note: initialize the variable 'vp' to silence this warning
     917 |         struct mshv_vp *vp;
         |                           ^
         |                            = NULL
   drivers/hv/mshv_root_main.c:41:20: warning: unused function 'hv_parent_partition' [-Wunused-function]
      41 | static inline bool hv_parent_partition(void)
         |                    ^~~~~~~~~~~~~~~~~~~
   4 warnings generated.


vim +966 drivers/hv/mshv_root_main.c

621191d709b1488 Nuno Das Neves 2025-03-14   911  
621191d709b1488 Nuno Das Neves 2025-03-14   912  static long
621191d709b1488 Nuno Das Neves 2025-03-14   913  mshv_partition_ioctl_create_vp(struct mshv_partition *partition,
621191d709b1488 Nuno Das Neves 2025-03-14   914  			       void __user *arg)
621191d709b1488 Nuno Das Neves 2025-03-14   915  {
621191d709b1488 Nuno Das Neves 2025-03-14   916  	struct mshv_create_vp args;
621191d709b1488 Nuno Das Neves 2025-03-14   917  	struct mshv_vp *vp;
621191d709b1488 Nuno Das Neves 2025-03-14   918  	struct page *intercept_message_page, *register_page, *ghcb_page;
621191d709b1488 Nuno Das Neves 2025-03-14   919  	void *stats_pages[2];
621191d709b1488 Nuno Das Neves 2025-03-14   920  	long ret;
621191d709b1488 Nuno Das Neves 2025-03-14   921  
621191d709b1488 Nuno Das Neves 2025-03-14   922  	if (copy_from_user(&args, arg, sizeof(args)))
621191d709b1488 Nuno Das Neves 2025-03-14   923  		return -EFAULT;
621191d709b1488 Nuno Das Neves 2025-03-14   924  
621191d709b1488 Nuno Das Neves 2025-03-14   925  	if (args.vp_index >= MSHV_MAX_VPS)
621191d709b1488 Nuno Das Neves 2025-03-14   926  		return -EINVAL;
621191d709b1488 Nuno Das Neves 2025-03-14   927  
621191d709b1488 Nuno Das Neves 2025-03-14   928  	if (partition->pt_vp_array[args.vp_index])
621191d709b1488 Nuno Das Neves 2025-03-14   929  		return -EEXIST;
621191d709b1488 Nuno Das Neves 2025-03-14   930  
621191d709b1488 Nuno Das Neves 2025-03-14   931  	ret = hv_call_create_vp(NUMA_NO_NODE, partition->pt_id, args.vp_index,
621191d709b1488 Nuno Das Neves 2025-03-14   932  				0 /* Only valid for root partition VPs */);
621191d709b1488 Nuno Das Neves 2025-03-14   933  	if (ret)
621191d709b1488 Nuno Das Neves 2025-03-14   934  		return ret;
621191d709b1488 Nuno Das Neves 2025-03-14   935  
debba2f23756254 Jinank Jain    2025-09-10   936  	ret = hv_map_vp_state_page(partition->pt_id, args.vp_index,
621191d709b1488 Nuno Das Neves 2025-03-14   937  				   HV_VP_STATE_PAGE_INTERCEPT_MESSAGE,
debba2f23756254 Jinank Jain    2025-09-10   938  				   input_vtl_zero, &intercept_message_page);
621191d709b1488 Nuno Das Neves 2025-03-14   939  	if (ret)
621191d709b1488 Nuno Das Neves 2025-03-14   940  		goto destroy_vp;
621191d709b1488 Nuno Das Neves 2025-03-14   941  
621191d709b1488 Nuno Das Neves 2025-03-14   942  	if (!mshv_partition_encrypted(partition)) {
debba2f23756254 Jinank Jain    2025-09-10   943  		ret = hv_map_vp_state_page(partition->pt_id, args.vp_index,
621191d709b1488 Nuno Das Neves 2025-03-14   944  					   HV_VP_STATE_PAGE_REGISTERS,
debba2f23756254 Jinank Jain    2025-09-10   945  					   input_vtl_zero, &register_page);
621191d709b1488 Nuno Das Neves 2025-03-14   946  		if (ret)
621191d709b1488 Nuno Das Neves 2025-03-14   947  			goto unmap_intercept_message_page;
621191d709b1488 Nuno Das Neves 2025-03-14   948  	}
621191d709b1488 Nuno Das Neves 2025-03-14   949  
621191d709b1488 Nuno Das Neves 2025-03-14   950  	if (mshv_partition_encrypted(partition) &&
621191d709b1488 Nuno Das Neves 2025-03-14   951  	    is_ghcb_mapping_available()) {
debba2f23756254 Jinank Jain    2025-09-10   952  		ret = hv_map_vp_state_page(partition->pt_id, args.vp_index,
621191d709b1488 Nuno Das Neves 2025-03-14   953  					   HV_VP_STATE_PAGE_GHCB,
debba2f23756254 Jinank Jain    2025-09-10   954  					   input_vtl_normal, &ghcb_page);
621191d709b1488 Nuno Das Neves 2025-03-14   955  		if (ret)
621191d709b1488 Nuno Das Neves 2025-03-14   956  			goto unmap_register_page;
621191d709b1488 Nuno Das Neves 2025-03-14   957  	}
621191d709b1488 Nuno Das Neves 2025-03-14   958  
1af6cc3b10421f1 Nuno Das Neves 2025-09-10   959  	/*
1af6cc3b10421f1 Nuno Das Neves 2025-09-10   960  	 * This mapping of the stats page is for detecting if dispatch thread
1af6cc3b10421f1 Nuno Das Neves 2025-09-10   961  	 * is blocked - only relevant for root scheduler
1af6cc3b10421f1 Nuno Das Neves 2025-09-10   962  	 */
1af6cc3b10421f1 Nuno Das Neves 2025-09-10   963  	if (hv_scheduler_type == HV_SCHEDULER_TYPE_ROOT) {
621191d709b1488 Nuno Das Neves 2025-03-14   964  		ret = mshv_vp_stats_map(partition->pt_id, args.vp_index,
621191d709b1488 Nuno Das Neves 2025-03-14   965  					stats_pages);
621191d709b1488 Nuno Das Neves 2025-03-14  @966  		if (ret)
621191d709b1488 Nuno Das Neves 2025-03-14   967  			goto unmap_ghcb_page;
621191d709b1488 Nuno Das Neves 2025-03-14   968  	}
621191d709b1488 Nuno Das Neves 2025-03-14   969  
621191d709b1488 Nuno Das Neves 2025-03-14   970  	vp = kzalloc(sizeof(*vp), GFP_KERNEL);
621191d709b1488 Nuno Das Neves 2025-03-14   971  	if (!vp)
621191d709b1488 Nuno Das Neves 2025-03-14   972  		goto unmap_stats_pages;
621191d709b1488 Nuno Das Neves 2025-03-14   973  
621191d709b1488 Nuno Das Neves 2025-03-14   974  	vp->vp_partition = mshv_partition_get(partition);
621191d709b1488 Nuno Das Neves 2025-03-14   975  	if (!vp->vp_partition) {
621191d709b1488 Nuno Das Neves 2025-03-14   976  		ret = -EBADF;
621191d709b1488 Nuno Das Neves 2025-03-14   977  		goto free_vp;
621191d709b1488 Nuno Das Neves 2025-03-14   978  	}
621191d709b1488 Nuno Das Neves 2025-03-14   979  
621191d709b1488 Nuno Das Neves 2025-03-14   980  	mutex_init(&vp->vp_mutex);
621191d709b1488 Nuno Das Neves 2025-03-14   981  	init_waitqueue_head(&vp->run.vp_suspend_queue);
621191d709b1488 Nuno Das Neves 2025-03-14   982  	atomic64_set(&vp->run.vp_signaled_count, 0);
621191d709b1488 Nuno Das Neves 2025-03-14   983  
621191d709b1488 Nuno Das Neves 2025-03-14   984  	vp->vp_index = args.vp_index;
621191d709b1488 Nuno Das Neves 2025-03-14   985  	vp->vp_intercept_msg_page = page_to_virt(intercept_message_page);
621191d709b1488 Nuno Das Neves 2025-03-14   986  	if (!mshv_partition_encrypted(partition))
621191d709b1488 Nuno Das Neves 2025-03-14   987  		vp->vp_register_page = page_to_virt(register_page);
621191d709b1488 Nuno Das Neves 2025-03-14   988  
621191d709b1488 Nuno Das Neves 2025-03-14   989  	if (mshv_partition_encrypted(partition) && is_ghcb_mapping_available())
621191d709b1488 Nuno Das Neves 2025-03-14   990  		vp->vp_ghcb_page = page_to_virt(ghcb_page);
621191d709b1488 Nuno Das Neves 2025-03-14   991  
1af6cc3b10421f1 Nuno Das Neves 2025-09-10   992  	if (hv_scheduler_type == HV_SCHEDULER_TYPE_ROOT)
621191d709b1488 Nuno Das Neves 2025-03-14   993  		memcpy(vp->vp_stats_pages, stats_pages, sizeof(stats_pages));
621191d709b1488 Nuno Das Neves 2025-03-14   994  
621191d709b1488 Nuno Das Neves 2025-03-14   995  	/*
621191d709b1488 Nuno Das Neves 2025-03-14   996  	 * Keep anon_inode_getfd last: it installs fd in the file struct and
621191d709b1488 Nuno Das Neves 2025-03-14   997  	 * thus makes the state accessible in user space.
621191d709b1488 Nuno Das Neves 2025-03-14   998  	 */
621191d709b1488 Nuno Das Neves 2025-03-14   999  	ret = anon_inode_getfd("mshv_vp", &mshv_vp_fops, vp,
621191d709b1488 Nuno Das Neves 2025-03-14  1000  			       O_RDWR | O_CLOEXEC);
621191d709b1488 Nuno Das Neves 2025-03-14  1001  	if (ret < 0)
621191d709b1488 Nuno Das Neves 2025-03-14  1002  		goto put_partition;
621191d709b1488 Nuno Das Neves 2025-03-14  1003  
621191d709b1488 Nuno Das Neves 2025-03-14  1004  	/* already exclusive with the partition mutex for all ioctls */
621191d709b1488 Nuno Das Neves 2025-03-14  1005  	partition->pt_vp_count++;
621191d709b1488 Nuno Das Neves 2025-03-14  1006  	partition->pt_vp_array[args.vp_index] = vp;
621191d709b1488 Nuno Das Neves 2025-03-14  1007  
621191d709b1488 Nuno Das Neves 2025-03-14  1008  	return ret;
621191d709b1488 Nuno Das Neves 2025-03-14  1009  
621191d709b1488 Nuno Das Neves 2025-03-14  1010  put_partition:
621191d709b1488 Nuno Das Neves 2025-03-14  1011  	mshv_partition_put(partition);
621191d709b1488 Nuno Das Neves 2025-03-14  1012  free_vp:
621191d709b1488 Nuno Das Neves 2025-03-14  1013  	kfree(vp);
621191d709b1488 Nuno Das Neves 2025-03-14  1014  unmap_stats_pages:
1af6cc3b10421f1 Nuno Das Neves 2025-09-10  1015  	if (hv_scheduler_type == HV_SCHEDULER_TYPE_ROOT)
621191d709b1488 Nuno Das Neves 2025-03-14  1016  		mshv_vp_stats_unmap(partition->pt_id, args.vp_index);
621191d709b1488 Nuno Das Neves 2025-03-14  1017  unmap_ghcb_page:
debba2f23756254 Jinank Jain    2025-09-10  1018  	if (mshv_partition_encrypted(partition) && is_ghcb_mapping_available())
debba2f23756254 Jinank Jain    2025-09-10  1019  		hv_unmap_vp_state_page(partition->pt_id, args.vp_index,
debba2f23756254 Jinank Jain    2025-09-10  1020  				       HV_VP_STATE_PAGE_GHCB, vp->vp_ghcb_page,
621191d709b1488 Nuno Das Neves 2025-03-14  1021  				       input_vtl_normal);
621191d709b1488 Nuno Das Neves 2025-03-14  1022  unmap_register_page:
debba2f23756254 Jinank Jain    2025-09-10  1023  	if (!mshv_partition_encrypted(partition))
debba2f23756254 Jinank Jain    2025-09-10  1024  		hv_unmap_vp_state_page(partition->pt_id, args.vp_index,
621191d709b1488 Nuno Das Neves 2025-03-14  1025  				       HV_VP_STATE_PAGE_REGISTERS,
debba2f23756254 Jinank Jain    2025-09-10  1026  				       vp->vp_register_page, input_vtl_zero);
621191d709b1488 Nuno Das Neves 2025-03-14  1027  unmap_intercept_message_page:
debba2f23756254 Jinank Jain    2025-09-10  1028  	hv_unmap_vp_state_page(partition->pt_id, args.vp_index,
621191d709b1488 Nuno Das Neves 2025-03-14  1029  			       HV_VP_STATE_PAGE_INTERCEPT_MESSAGE,
debba2f23756254 Jinank Jain    2025-09-10  1030  			       vp->vp_intercept_msg_page, input_vtl_zero);
621191d709b1488 Nuno Das Neves 2025-03-14  1031  destroy_vp:
621191d709b1488 Nuno Das Neves 2025-03-14  1032  	hv_call_delete_vp(partition->pt_id, args.vp_index);
621191d709b1488 Nuno Das Neves 2025-03-14  1033  	return ret;
621191d709b1488 Nuno Das Neves 2025-03-14  1034  }
621191d709b1488 Nuno Das Neves 2025-03-14  1035  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2025-09-11 19:05 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-09-10 23:14 [PATCH v2 0/5] mshv: Fixes for stats and vp state page mappings Nuno Das Neves
2025-09-10 23:14 ` [PATCH v2 1/5] mshv: Only map vp->vp_stats_pages if on root scheduler Nuno Das Neves
2025-09-10 23:14 ` [PATCH v2 2/5] mshv: Add the HVCALL_GET_PARTITION_PROPERTY_EX hypercall Nuno Das Neves
2025-09-11 16:21   ` Easwar Hariharan
2025-09-10 23:14 ` [PATCH v2 3/5] mshv: Get the vmm capabilities offered by the hypervisor Nuno Das Neves
2025-09-10 23:14 ` [PATCH v2 4/5] mshv: Allocate vp state page for HVCALL_MAP_VP_STATE_PAGE on L1VH Nuno Das Neves
2025-09-11 19:05   ` kernel test robot
2025-09-10 23:14 ` [PATCH v2 5/5] mshv: Introduce new hypercall to map stats page for L1VH partitions Nuno Das Neves
2025-09-11 16:32   ` Easwar Hariharan
2025-09-11 18:00     ` Nuno Das Neves

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).