[PATCH v5 1/9] mshv: Provide a way to get partition ID if running in a VMM process

From: Mukesh R

Date: Fri Jul 31 2026 - 18:35:11 EST


Many PCI passthru related hypercalls require partition ID of the target
guest. Guests are actually managed by MSHV driver and the partition ID
is only maintained there. Add a field in the partition struct in MSHV
driver to save the tgid of the VMM process creating the partition, and
add a function there to retrieve partition ID if the current process is
a VMM process. Furthermore, enforce one partition per VMM instance.

Signed-off-by: Mukesh R <mrathor@xxxxxxxxxxxxxxxxxxx>
Reviewed-by: Anirudh Rayabharam (Microsoft) <anirudh@xxxxxxxxxxxxx>
---
drivers/hv/mshv_root.h | 1 +
drivers/hv/mshv_root_main.c | 33 ++++++++++++++++++++++++++++++++-
include/asm-generic/mshyperv.h | 5 +++++
3 files changed, 38 insertions(+), 1 deletion(-)

diff --git a/drivers/hv/mshv_root.h b/drivers/hv/mshv_root.h
index 1f086dcb7aa1..a85c24dcc701 100644
--- a/drivers/hv/mshv_root.h
+++ b/drivers/hv/mshv_root.h
@@ -138,6 +138,7 @@ struct mshv_partition {

struct mshv_girq_routing_table __rcu *pt_girq_tbl;
u64 isolation_type;
+ pid_t pt_vmm_tgid;
bool import_completed;
bool pt_initialized;
#if IS_ENABLED(CONFIG_DEBUG_FS)
diff --git a/drivers/hv/mshv_root_main.c b/drivers/hv/mshv_root_main.c
index bd1359eb58dd..9b53c476bd83 100644
--- a/drivers/hv/mshv_root_main.c
+++ b/drivers/hv/mshv_root_main.c
@@ -1908,17 +1908,48 @@ mshv_partition_release(struct inode *inode, struct file *filp)
return 0;
}

+/* Given a process tgid, return partition id if it is a VMM process */
+u64 mshv_current_partid(void)
+{
+ struct mshv_partition *pt;
+ int i;
+ u64 ret_ptid = HV_PARTITION_ID_INVALID;
+
+ rcu_read_lock();
+
+ hash_for_each_rcu(mshv_root.pt_htable, i, pt, pt_hnode) {
+ if (pt->pt_vmm_tgid == current->tgid) {
+ ret_ptid = pt->pt_id;
+ break;
+ }
+ }
+
+ rcu_read_unlock();
+ return ret_ptid;
+}
+EXPORT_SYMBOL_GPL(mshv_current_partid);
+
+/* At present, we only allow one partition per VMM instance */
static int
add_partition(struct mshv_partition *partition)
{
+ int rc = 0;
+
spin_lock(&mshv_root.pt_ht_lock);

+ if (mshv_current_partid() != HV_PARTITION_ID_INVALID) {
+ rc = -EEXIST;
+ goto out;
+ }
+
+ partition->pt_vmm_tgid = current->tgid;
hash_add_rcu(mshv_root.pt_htable, &partition->pt_hnode,
partition->pt_id);

+out:
spin_unlock(&mshv_root.pt_ht_lock);

- return 0;
+ return rc;
}

static_assert(MSHV_NUM_CPU_FEATURES_BANKS ==
diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h
index bf601d67cecb..e8cbc4e3f7ad 100644
--- a/include/asm-generic/mshyperv.h
+++ b/include/asm-generic/mshyperv.h
@@ -350,6 +350,7 @@ int hv_call_add_logical_proc(int node, u32 lp_index, u32 acpi_id);
int hv_call_notify_all_processors_started(void);
bool hv_lp_exists(u32 lp_index);
int hv_call_create_vp(int node, u64 partition_id, u32 vp_index, u32 flags);
+u64 mshv_current_partid(void);

#else /* CONFIG_MSHV_ROOT */
static inline bool hv_root_partition(void) { return false; }
@@ -380,6 +381,10 @@ static inline int hv_call_create_vp(int node, u64 partition_id, u32 vp_index, u3
{
return -EOPNOTSUPP;
}
+static inline u64 mshv_current_partid(void)
+{
+ return HV_PARTITION_ID_INVALID;
+}
#endif /* CONFIG_MSHV_ROOT */

static inline int hv_deposit_memory(u64 partition_id, u64 status)
--
2.51.2.vfs.0.1