From: Nuno Das Neves <[email protected]> Sent: Monday, January 26, 2026 12:56 PM > > From: Stanislav Kinsburskii <[email protected]> > > These functions are currently only used to map child partition VP stats, > on root partition. However, they will soon be used on L1VH, and and also
Duplicate word "and". Remember to run checkpatch.pl over your patches -- this duplicate word was flagged by checkpatch. Michael > used for mapping the host's own VP stats. > > Introduce a helper is_l1vh_parent() to determine whether we are mapping > our own VP stats. In this case, do not attempt to map the PARENT area. > Note this is a different case than mapping PARENT on an older hypervisor > where it is not available at all, so must be handled separately. > > On unmap, pass the stats pages since on L1VH the kernel allocates them > and they must be freed in hv_unmap_stats_page(). > > Signed-off-by: Stanislav Kinsburskii <[email protected]> > Signed-off-by: Nuno Das Neves <[email protected]> > --- > drivers/hv/mshv_root.h | 10 ++++++ > drivers/hv/mshv_root_main.c | 61 ++++++++++++++++++++++++++----------- > 2 files changed, 54 insertions(+), 17 deletions(-) > > diff --git a/drivers/hv/mshv_root.h b/drivers/hv/mshv_root.h > index 05ba1f716f9e..e4912b0618fa 100644 > --- a/drivers/hv/mshv_root.h > +++ b/drivers/hv/mshv_root.h > @@ -254,6 +254,16 @@ struct mshv_partition *mshv_partition_get(struct > mshv_partition *partition); > void mshv_partition_put(struct mshv_partition *partition); > struct mshv_partition *mshv_partition_find(u64 partition_id) > __must_hold(RCU); > > +static inline bool is_l1vh_parent(u64 partition_id) > +{ > + return hv_l1vh_partition() && (partition_id == HV_PARTITION_ID_SELF); > +} > + > +int mshv_vp_stats_map(u64 partition_id, u32 vp_index, > + struct hv_stats_page **stats_pages); > +void mshv_vp_stats_unmap(u64 partition_id, u32 vp_index, > + struct hv_stats_page **stats_pages); > + > /* hypercalls */ > > int hv_call_withdraw_memory(u64 count, int node, u64 partition_id); > diff --git a/drivers/hv/mshv_root_main.c b/drivers/hv/mshv_root_main.c > index be5ad0fbfbee..faca3cc63e79 100644 > --- a/drivers/hv/mshv_root_main.c > +++ b/drivers/hv/mshv_root_main.c > @@ -956,23 +956,36 @@ mshv_vp_release(struct inode *inode, struct file *filp) > return 0; > } > > -static void mshv_vp_stats_unmap(u64 partition_id, u32 vp_index, > - struct hv_stats_page *stats_pages[]) > +void mshv_vp_stats_unmap(u64 partition_id, u32 vp_index, > + struct hv_stats_page *stats_pages[]) > { > union hv_stats_object_identity identity = { > .vp.partition_id = partition_id, > .vp.vp_index = vp_index, > }; > + int err; > > identity.vp.stats_area_type = HV_STATS_AREA_SELF; > - hv_unmap_stats_page(HV_STATS_OBJECT_VP, NULL, &identity); > - > - identity.vp.stats_area_type = HV_STATS_AREA_PARENT; > - hv_unmap_stats_page(HV_STATS_OBJECT_VP, NULL, &identity); > + err = hv_unmap_stats_page(HV_STATS_OBJECT_VP, > + stats_pages[HV_STATS_AREA_SELF], > + &identity); > + if (err) > + pr_err("%s: failed to unmap partition %llu vp %u self stats, > err: %d\n", > + __func__, partition_id, vp_index, err); > + > + if (stats_pages[HV_STATS_AREA_PARENT] != > stats_pages[HV_STATS_AREA_SELF]) { > + identity.vp.stats_area_type = HV_STATS_AREA_PARENT; > + err = hv_unmap_stats_page(HV_STATS_OBJECT_VP, > + stats_pages[HV_STATS_AREA_PARENT], > + &identity); > + if (err) > + pr_err("%s: failed to unmap partition %llu vp %u parent > stats, > err: %d\n", > + __func__, partition_id, vp_index, err); > + } > } > > -static int mshv_vp_stats_map(u64 partition_id, u32 vp_index, > - struct hv_stats_page *stats_pages[]) > +int mshv_vp_stats_map(u64 partition_id, u32 vp_index, > + struct hv_stats_page *stats_pages[]) > { > union hv_stats_object_identity identity = { > .vp.partition_id = partition_id, > @@ -983,23 +996,37 @@ static int mshv_vp_stats_map(u64 partition_id, u32 > vp_index, > identity.vp.stats_area_type = HV_STATS_AREA_SELF; > err = hv_map_stats_page(HV_STATS_OBJECT_VP, &identity, > &stats_pages[HV_STATS_AREA_SELF]); > - if (err) > + if (err) { > + pr_err("%s: failed to map partition %llu vp %u self stats, err: > %d\n", > + __func__, partition_id, vp_index, err); > return err; > + } > > - identity.vp.stats_area_type = 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; > - > - if (!stats_pages[HV_STATS_AREA_PARENT]) > + /* > + * L1VH partition cannot access its vp stats in parent area. > + */ > + if (is_l1vh_parent(partition_id)) { > stats_pages[HV_STATS_AREA_PARENT] = > stats_pages[HV_STATS_AREA_SELF]; > + } else { > + identity.vp.stats_area_type = HV_STATS_AREA_PARENT; > + err = hv_map_stats_page(HV_STATS_OBJECT_VP, &identity, > + &stats_pages[HV_STATS_AREA_PARENT]); > + if (err) { > + pr_err("%s: failed to map partition %llu vp %u parent > stats, err: > %d\n", > + __func__, partition_id, vp_index, err); > + goto unmap_self; > + } > + if (!stats_pages[HV_STATS_AREA_PARENT]) > + stats_pages[HV_STATS_AREA_PARENT] = > stats_pages[HV_STATS_AREA_SELF]; > + } > > return 0; > > unmap_self: > identity.vp.stats_area_type = HV_STATS_AREA_SELF; > - hv_unmap_stats_page(HV_STATS_OBJECT_VP, NULL, &identity); > + hv_unmap_stats_page(HV_STATS_OBJECT_VP, > + stats_pages[HV_STATS_AREA_SELF], > + &identity); > return err; > } > > -- > 2.34.1
