From nobody Sat Feb 7 10:16:24 2026 Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 514A12FE58D; Wed, 28 Jan 2026 18:11:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=13.77.154.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769623909; cv=none; b=rfqH2eyZ1qZu+GjI2xfpAqxsRAyP4RLQdcwnaCBLG+uBbKZ07dlZkxDzDsGk6D6OtTfYEbdNZ1zz/ux6uzHz4Lsn75JmvqIKI4GjNeJuMV0Lay/7NMAguEftwl4VfOaE0H6SirAlvk8pKil6uAF+WDMNfr5xIM+nB6tZs47KNz4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769623909; c=relaxed/simple; bh=XoWr9E6GpJVfiqW5j7TGfpouzFnYRVdh59ggwDHSzrU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=TQyZWTWuNS/a+7Cno5qaKHj4Sp7h/6rbTtrT+dF+kQBYoL2+hfHyhh6ARXQHUf7eZLYz6YNFsmRDuBokJBEwAih3vNRYdKWYCVhollmaDv+zKM9wfe/ZiMtLdEAiiMkji3vgovSd80EUkqw8+XgcFZFohvyOXq3MgncSjZOp5Q4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com; spf=pass smtp.mailfrom=linux.microsoft.com; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b=HYkCrrRk; arc=none smtp.client-ip=13.77.154.182 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.microsoft.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b="HYkCrrRk" Received: by linux.microsoft.com (Postfix, from userid 1032) id 685AA20B7169; Wed, 28 Jan 2026 10:11:48 -0800 (PST) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 685AA20B7169 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1769623908; bh=LLskYnn36sZloCu/fmiglMXyDQHLYorP70jSLnEIhig=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=HYkCrrRkHwd+9RpnENrKsrlQbUQSPB9zSzP0onXiqxkfx65V8dfl0A9DZyLc27NH8 1DBRBZe+uGEYOJdqC9FNKVySGREVFzZTtwNptg7GnqEJ1u1tY/JWLDeIAPfehQ8FAM c/DR9Ae30X78JUfCG3aPvcZtuNfcR+Y05HbLkZNs= From: Nuno Das Neves To: linux-hyperv@vger.kernel.org, linux-kernel@vger.kernel.org, mhklinux@outlook.com, skinsburskii@linux.microsoft.com Cc: kys@microsoft.com, haiyangz@microsoft.com, wei.liu@kernel.org, decui@microsoft.com, longli@microsoft.com, prapal@linux.microsoft.com, mrathor@linux.microsoft.com, paekkaladevi@linux.microsoft.com, Nuno Das Neves Subject: [PATCH v6 3/7] mshv: Improve mshv_vp_stats_map/unmap(), add them to mshv_root.h Date: Wed, 28 Jan 2026 10:11:42 -0800 Message-ID: <20260128181146.517708-4-nunodasneves@linux.microsoft.com> X-Mailer: git-send-email 2.43.7 In-Reply-To: <20260128181146.517708-1-nunodasneves@linux.microsoft.com> References: <20260128181146.517708-1-nunodasneves@linux.microsoft.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Stanislav Kinsburskii These functions are currently only used to map child partition VP stats, on root partition. However, they will soon be used on L1VH, and also 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 Signed-off-by: Nuno Das Neves --- 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(R= CU); =20 +static inline bool is_l1vh_parent(u64 partition_id) +{ + return hv_l1vh_partition() && (partition_id =3D=3D 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 */ =20 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 *fil= p) return 0; } =20 -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 =3D { .vp.partition_id =3D partition_id, .vp.vp_index =3D vp_index, }; + int err; =20 identity.vp.stats_area_type =3D HV_STATS_AREA_SELF; - hv_unmap_stats_page(HV_STATS_OBJECT_VP, NULL, &identity); - - identity.vp.stats_area_type =3D HV_STATS_AREA_PARENT; - hv_unmap_stats_page(HV_STATS_OBJECT_VP, NULL, &identity); + err =3D 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] !=3D stats_pages[HV_STATS_AREA_SELF= ]) { + identity.vp.stats_area_type =3D HV_STATS_AREA_PARENT; + err =3D 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); + } } =20 -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 =3D { .vp.partition_id =3D partition_id, @@ -983,23 +996,37 @@ static int mshv_vp_stats_map(u64 partition_id, u32 vp= _index, identity.vp.stats_area_type =3D HV_STATS_AREA_SELF; err =3D 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; + } =20 - identity.vp.stats_area_type =3D HV_STATS_AREA_PARENT; - err =3D 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] =3D stats_pages[HV_STATS_AREA_SELF]; + } else { + identity.vp.stats_area_type =3D HV_STATS_AREA_PARENT; + err =3D 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] =3D stats_pages[HV_STATS_AREA_SELF]; + } =20 return 0; =20 unmap_self: identity.vp.stats_area_type =3D 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; } =20 --=20 2.34.1