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,
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;
}