From nobody Tue Dec 16 07:27:11 2025 Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by smtp.subspace.kernel.org (Postfix) with ESMTP id D2A63303A31; Fri, 10 Oct 2025 21:55:54 +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=1760133356; cv=none; b=kO423dSHwqrvYh6+W1R0aVKgi47b1GS0Q2yp+x8+0dM0l57VlGg1CCA1CFTCZwaDTlVU6B6+sy6Hf/1Ipz+8oGUpvC+s7Ej1HZSHnxGFxwwyLct8WgySTs4sB36WHW2KV8r5vtTinc333q/jDqbwwNhXefPWKAH24uxCtZ16thE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760133356; c=relaxed/simple; bh=rYuclI6H2pgLBJCrCodRbO4Nwzob+vO7dbysl+fbkgo=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=N0u0gUMoh40BfR2ITGsKGQAAL7IS3aXFiEHV4iyehzPhPKAWJNCctBhdEefby7trXkVlTO/MVfagVvrUqQMXr5AFLLklIIEgjtRNXZrsJVekJ42tcqhxWRps/8nAHVHVsBKZmjOmICBL/q8MWZ6Oh9tou5KhRpCEeRzikP8MNvk= 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=UhlKn64F; 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="UhlKn64F" Received: by linux.microsoft.com (Postfix, from userid 1032) id 7862B2038B68; Fri, 10 Oct 2025 14:55:54 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 7862B2038B68 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1760133354; bh=Wjdr5YIOLFpVlaG0LHMyJq1K9oNDoFxiKDO4QpFJ3Ds=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=UhlKn64F7bBFoISYeuGXC3FBQwHrOsmRVAJF0jRYisDCM0fh1YTtqXhAn6WVyP4yF IcxT/u5NkOSe+lp5fs9mVv/rpOX3vZ2hoWyo+rVhqDFszDBKWo7i6qyGGs/4hsGKjg BpH6Zg8KdsZTKR9q1Y2KY523iGAyZKVrPwrU1c9E= From: Nuno Das Neves To: linux-hyperv@vger.kernel.org, linux-kernel@vger.kernel.org, prapal@linux.microsoft.com, easwar.hariharan@linux.microsoft.com, tiala@microsoft.com, anirudh@anirudhrb.com, paekkaladevi@linux.microsoft.com, skinsburskii@linux.microsoft.com, mhklinux@outlook.com Cc: kys@microsoft.com, haiyangz@microsoft.com, wei.liu@kernel.org, decui@microsoft.com, Nuno Das Neves Subject: [PATCH v5 1/5] mshv: Only map vp->vp_stats_pages if on root scheduler Date: Fri, 10 Oct 2025 14:55:47 -0700 Message-Id: <1760133351-6643-2-git-send-email-nunodasneves@linux.microsoft.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1760133351-6643-1-git-send-email-nunodasneves@linux.microsoft.com> References: <1760133351-6643-1-git-send-email-nunodasneves@linux.microsoft.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" 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 Reviewed-by: Anirudh Rayabharam Reviewed-by: Praveen K Paladugu Reviewed-by: Easwar Hariharan Reviewed-by: Tianyu Lan Acked-by: Stanislav Kinsburskii --- 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; } =20 - 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 =3D=3D HV_SCHEDULER_TYPE_ROOT) { ret =3D 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 *p= artition, if (mshv_partition_encrypted(partition) && is_ghcb_mapping_available()) vp->vp_ghcb_page =3D page_to_virt(ghcb_page); =20 - if (hv_parent_partition()) + if (hv_scheduler_type =3D=3D HV_SCHEDULER_TYPE_ROOT) memcpy(vp->vp_stats_pages, stats_pages, sizeof(stats_pages)); =20 /* @@ -986,7 +990,7 @@ mshv_partition_ioctl_create_vp(struct mshv_partition *p= artition, free_vp: kfree(vp); unmap_stats_pages: - if (hv_parent_partition()) + if (hv_scheduler_type =3D=3D 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; =20 - if (hv_parent_partition()) + if (hv_scheduler_type =3D=3D HV_SCHEDULER_TYPE_ROOT) mshv_vp_stats_unmap(partition->pt_id, vp->vp_index); =20 if (vp->vp_register_page) { --=20 2.34.1 From nobody Tue Dec 16 07:27:11 2025 Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 15047303A3C; Fri, 10 Oct 2025 21:55:55 +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=1760133356; cv=none; b=izpBBbvJ1p7lWPhEP7RfLa4wi+7N2p2rZolxAMChiTLhRiUDLf//951WZj9po/GRbP86wdraGcz2IvoPKy6A73JYZe1QgMoJX1JupHhA02RKkQPydImDoIrS0f7jjuG5pOvd9+dy8baVXQqyUyvjMvpxi4lTosAsANdfDJaKb/U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760133356; c=relaxed/simple; bh=nDG+FqHEF2uWfERwfxdlFG79+fDu1fcON8lIsJ+tKS8=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=IfDj92ksCPha07WYA2GhI6UNCrG2ZtuNCbZZYk1cQcn51M/3Xe3xVMLvWEk53+ktAd6tdQW913WreUavqW0qKenok+3FSEFMgFIgFiugk1WbAo+bMWyrvpnfLv187B0yyCRgVmEY9m2O5aTMiOIWjuCaFTC8k/3/LCeGn65r3rY= 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=n+jxr/A1; 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="n+jxr/A1" Received: by linux.microsoft.com (Postfix, from userid 1032) id C193B211CE0E; Fri, 10 Oct 2025 14:55:54 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com C193B211CE0E DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1760133354; bh=khNI2QfJhxIYESS2MZZhw2efQWlG80GW8tmxjQrDVM8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=n+jxr/A1dgo3bcXaGApMDZn2ouXqWVnyWBIhmCtIESQxdOZX6Dk7S3Z16lOG3qMX2 dns8HNgbX1ccJkerbyhJYdny/QaDzzUR3heXFdpXYAyrESZqIsv+OMivoEWKShETrK eIwlK+VifJYYCgAvrLutH/veaIy4gVFd1rtoa3vQ= From: Nuno Das Neves To: linux-hyperv@vger.kernel.org, linux-kernel@vger.kernel.org, prapal@linux.microsoft.com, easwar.hariharan@linux.microsoft.com, tiala@microsoft.com, anirudh@anirudhrb.com, paekkaladevi@linux.microsoft.com, skinsburskii@linux.microsoft.com, mhklinux@outlook.com Cc: kys@microsoft.com, haiyangz@microsoft.com, wei.liu@kernel.org, decui@microsoft.com, Nuno Das Neves Subject: [PATCH v5 2/5] mshv: Add the HVCALL_GET_PARTITION_PROPERTY_EX hypercall Date: Fri, 10 Oct 2025 14:55:48 -0700 Message-Id: <1760133351-6643-3-git-send-email-nunodasneves@linux.microsoft.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1760133351-6643-1-git-send-email-nunodasneves@linux.microsoft.com> References: <1760133351-6643-1-git-send-email-nunodasneves@linux.microsoft.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Purna Pavan Chandra Aekkaladevi 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 Signed-off-by: Nuno Das Neves Reviewed-by: Anirudh Rayabharam Reviewed-by: Praveen K Paladugu Reviewed-by: Easwar Hariharan Reviewed-by: Tianyu Lan --- 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 t= ype, 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); =20 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..8049e51c45dc 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); } =20 +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 =3D *this_cpu_ptr(hyperv_pcpu_input_arg); + output =3D *this_cpu_ptr(hyperv_pcpu_output_arg); + + memset(input, 0, sizeof(*input)); + input->partition_id =3D partition_id; + input->property_code =3D property_code; + input->arg =3D arg; + status =3D hv_do_hypercall(HVCALL_GET_PARTITION_PROPERTY_EX, input, outpu= t); + + if (!hv_result_success(status)) { + local_irq_restore(flags); + hv_status_debug(status, "\n"); + 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 77abddfc750e..2914fdb24f84 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_AS= SIST_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 =20 diff --git a/include/hyperv/hvhdk.h b/include/hyperv/hvhdk.h index b4067ada02cf..416c0d45b793 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; =20 +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 t= his + * 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 */ +}; + +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 =3D 0, HV_VP_STATE_PAGE_INTERCEPT_MESSAGE =3D 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 =3D 0x00060007, HV_PARTITION_PROPERTY_MAX_XSAVE_DATA_SIZE =3D 0x00060008, HV_PARTITION_PROPERTY_PROCESSOR_CLOCK_FREQUENCY =3D 0x00060009, + + /* Extended properties with larger property values */ + HV_PARTITION_PROPERTY_VMM_CAPABILITIES =3D 0x00090007, }; =20 +#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 =3D 0, HV_SNP_STATUS_AVAILABLE =3D 1, --=20 2.34.1 From nobody Tue Dec 16 07:27:11 2025 Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 630C8303C87; Fri, 10 Oct 2025 21:55:55 +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=1760133356; cv=none; b=NTolcHrrsQcCP8DcZEs89V96UFrd9zvI7JnYY2r0pqO+dywTiWntlkGZ46ZGp/cTiUzRtA5RG7quQ8punqgXSbGnTwyO3hoPmW5jBpoZQ9M74FIocTVX3ivZbtW9ziMB5kke+d3RwQNgCtS422KqjMGp5/9T9tPgA7Er1Dc0uaM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760133356; c=relaxed/simple; bh=8qXBCsPX0os3fZTIyeifEQ3tY/cGqU8KItsMFrLORWc=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=ZSHCkqBIhUwoLo1u0EpBo+gK7/ucKRwVL7Wi3BwYfZAbx2WWb6PxkuAUxXFwbBvPTclHuarCaGmzs8rp1kPbNBsoMezmyck8MIKz9SKJBd6FQcvsuxyBcI2+GeceBZKQO40yjeo80UXuUCxcLqqIokj5IBZJ/oHu5kuJ7wI7Rl0= 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=L/Hki0z0; 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="L/Hki0z0" Received: by linux.microsoft.com (Postfix, from userid 1032) id 0D9D6211C26C; Fri, 10 Oct 2025 14:55:55 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 0D9D6211C26C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1760133355; bh=nnUwJWljs6FM3DFsilZMh5du+IY+KgoQsHP4KO1Cbn8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=L/Hki0z08XOw/08KbRb9bmt/yqgLTgXS6gYwiLwG+aP6i+IHYEUXvKskI05+I6Y77 QUc7P5hEtMTZYBUdQktO9xh7co28FiZGP/Ix91//s3M7YlAvDd7+fT0m6cA7+cjb/j 1djNbp/ZPdJjTWbR+D06x2GFdLY+UsvHf9PZ1mHI= From: Nuno Das Neves To: linux-hyperv@vger.kernel.org, linux-kernel@vger.kernel.org, prapal@linux.microsoft.com, easwar.hariharan@linux.microsoft.com, tiala@microsoft.com, anirudh@anirudhrb.com, paekkaladevi@linux.microsoft.com, skinsburskii@linux.microsoft.com, mhklinux@outlook.com Cc: kys@microsoft.com, haiyangz@microsoft.com, wei.liu@kernel.org, decui@microsoft.com, Nuno Das Neves Subject: [PATCH v5 3/5] mshv: Get the vmm capabilities offered by the hypervisor Date: Fri, 10 Oct 2025 14:55:49 -0700 Message-Id: <1760133351-6643-4-git-send-email-nunodasneves@linux.microsoft.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1760133351-6643-1-git-send-email-nunodasneves@linux.microsoft.com> References: <1760133351-6643-1-git-send-email-nunodasneves@linux.microsoft.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Purna Pavan Chandra Aekkaladevi 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 Signed-off-by: Nuno Das Neves Reviewed-by: Praveen K Paladugu Reviewed-by: Easwar Hariharan Reviewed-by: Tianyu Lan --- drivers/hv/mshv_root.h | 1 + drivers/hv/mshv_root_main.c | 18 ++++++++++++++++++ 2 files changed, 19 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; }; =20 /* diff --git a/drivers/hv/mshv_root_main.c b/drivers/hv/mshv_root_main.c index 24df47726363..94cc482c6c26 100644 --- a/drivers/hv/mshv_root_main.c +++ b/drivers/hv/mshv_root_main.c @@ -2201,6 +2201,22 @@ static int __init mshv_root_partition_init(struct de= vice *dev) return err; } =20 +static void mshv_init_vmm_caps(struct device *dev) +{ + /* + * This can only fail here if HVCALL_GET_PARTITION_PROPERTY_EX or + * HV_PARTITION_PROPERTY_VMM_CAPABILITIES are not supported. In that + * case it's valid to proceed as if all vmm_caps are disabled (zero). + */ + if (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))) + dev_warn(dev, "Unable to get VMM capabilities\n"); + + dev_dbg(dev, "vmm_caps =3D %#llx\n", mshv_root.vmm_caps.as_uint64[0]); +} + static int __init mshv_parent_partition_init(void) { int ret; @@ -2253,6 +2269,8 @@ static int __init mshv_parent_partition_init(void) if (ret) goto remove_cpu_state; =20 + mshv_init_vmm_caps(dev); + ret =3D mshv_irqfd_wq_init(); if (ret) goto exit_partition; --=20 2.34.1 From nobody Tue Dec 16 07:27:11 2025 Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by smtp.subspace.kernel.org (Postfix) with ESMTP id A650E303C8A; Fri, 10 Oct 2025 21:55:55 +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=1760133357; cv=none; b=Bg+haUX8Gu0YsFsgxxT8BKw7g7a4uylwtZ6GnhSBXBg6WZa5XWrkNsWJSxVHhBIVBtIlI3Qs2z2a19Jb5+Fl2Xr+3ZzgkSfUzA/ymCwD5iok/X5bxvGfjz5vZgNuveuTQExHcVk5yCJwc25hsxvfioPVGIOQBu1h7mGaxY0G108= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760133357; c=relaxed/simple; bh=9rrJHvRgmXC67zR+UHTWB0z6NpSq+N1W2ZQpD+kvowg=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=aYY3TOKFMi5hwRgwZzsyllFAQgfJSjcazwWUBmFE5ySr8XIMLP9lm7ia+Nr4UwdA9FmDfCWEHR5NErth6b/PNm/fZT0vc0a0/9DsoD5WxLeSlRIWl88d2D628dX7ZLYto8t1iMBYWf8+/uP9j5AB0MB36/oVqoKO44oVHf3+9Bc= 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=g8+5SZv/; 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="g8+5SZv/" Received: by linux.microsoft.com (Postfix, from userid 1032) id 50ACC211C294; Fri, 10 Oct 2025 14:55:55 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 50ACC211C294 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1760133355; bh=0wZLCYx2re7dQlIHFbC0ynLKs/8/btxDPHcbxVyIPGY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=g8+5SZv/oH/cQi9DiZ8LDILzYgZgGVznCmcBsJplhRE6pnTw+J1JUger15mD/mnsh ELas9eWTWxisU6zpLKB6LYeETVNAwetsb5qkU7LDZC3JDVr1GHw8EWkg+DTlAGiWp3 as6TrrjXxOwIm/dEMuy5F3dpgo/Wuube1hZufxUc= From: Nuno Das Neves To: linux-hyperv@vger.kernel.org, linux-kernel@vger.kernel.org, prapal@linux.microsoft.com, easwar.hariharan@linux.microsoft.com, tiala@microsoft.com, anirudh@anirudhrb.com, paekkaladevi@linux.microsoft.com, skinsburskii@linux.microsoft.com, mhklinux@outlook.com Cc: kys@microsoft.com, haiyangz@microsoft.com, wei.liu@kernel.org, decui@microsoft.com, Jinank Jain , Nuno Das Neves Subject: [PATCH v5 4/5] mshv: Allocate vp state page for HVCALL_MAP_VP_STATE_PAGE on L1VH Date: Fri, 10 Oct 2025 14:55:50 -0700 Message-Id: <1760133351-6643-5-git-send-email-nunodasneves@linux.microsoft.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1760133351-6643-1-git-send-email-nunodasneves@linux.microsoft.com> References: <1760133351-6643-1-git-send-email-nunodasneves@linux.microsoft.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Jinank Jain 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 Signed-off-by: Nuno Das Neves Reviewed-by: Praveen K Paladugu Reviewed-by: Easwar Hariharan Reviewed-by: Stanislav Kinsburskii Reviewed-by: Anirudh Rayabharam Reviewed-by: Tianyu Lan --- drivers/hv/mshv_root.h | 11 ++--- drivers/hv/mshv_root_hv_call.c | 64 +++++++++++++++++++++++++--- drivers/hv/mshv_root_main.c | 76 +++++++++++++++++----------------- 3 files changed, 101 insertions(+), 50 deletions(-) diff --git a/drivers/hv/mshv_root.h b/drivers/hv/mshv_root.h index 0cb1e2589fe1..dbe2d1d0b22f 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, + struct page *state_page, + 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 8049e51c45dc..6dac9fcc092c 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; } =20 -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 t= ype, + 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; @@ -542,12 +542,20 @@ int hv_call_map_vp_state_page(u64 partition_id, u32 v= p_index, u32 type, input =3D *this_cpu_ptr(hyperv_pcpu_input_arg); output =3D *this_cpu_ptr(hyperv_pcpu_output_arg); =20 + memset(input, 0, sizeof(*input)); input->partition_id =3D partition_id; input->vp_index =3D vp_index; input->type =3D type; input->input_vtl =3D input_vtl; =20 - status =3D hv_do_hypercall(HVCALL_MAP_VP_STATE_PAGE, input, output); + if (*state_page) { + input->flags.map_location_provided =3D 1; + input->requested_map_location =3D + page_to_pfn(*state_page); + } + + status =3D hv_do_hypercall(HVCALL_MAP_VP_STATE_PAGE, input, + output); =20 if (hv_result(status) !=3D HV_STATUS_INSUFFICIENT_MEMORY) { if (hv_result_success(status)) @@ -565,8 +573,41 @@ int hv_call_map_vp_state_page(u64 partition_id, u32 vp= _index, u32 type, return ret; } =20 -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 =3D 0; + struct page *allocated_page =3D NULL; + + if (mshv_use_overlay_gpfn()) { + allocated_page =3D alloc_page(GFP_KERNEL); + if (!allocated_page) + return -ENOMEM; + *state_page =3D allocated_page; + } else { + *state_page =3D NULL; + } + + ret =3D hv_call_map_vp_state_page(partition_id, vp_index, type, input_vtl, + state_page); + + if (ret && allocated_page) { + __free_page(allocated_page); + *state_page =3D NULL; + } + + 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 +631,17 @@ int hv_call_unmap_vp_state_page(u64 partition_id, u32 = vp_index, u32 type, return hv_result_to_errno(status); } =20 +int hv_unmap_vp_state_page(u64 partition_id, u32 vp_index, u32 type, + struct page *state_page, union hv_input_vtl input_vtl) +{ + int ret =3D hv_call_unmap_vp_state_page(partition_id, vp_index, type, inp= ut_vtl); + + if (mshv_use_overlay_gpfn() && state_page) + __free_page(state_page); + + 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 94cc482c6c26..b1bd3e2a15ef 100644 --- a/drivers/hv/mshv_root_main.c +++ b/drivers/hv/mshv_root_main.c @@ -890,7 +890,7 @@ mshv_partition_ioctl_create_vp(struct mshv_partition *p= artition, { struct mshv_create_vp args; struct mshv_vp *vp; - struct page *intercept_message_page, *register_page, *ghcb_page; + struct page *intercept_msg_page, *register_page, *ghcb_page; void *stats_pages[2]; long ret; =20 @@ -908,28 +908,25 @@ mshv_partition_ioctl_create_vp(struct mshv_partition = *partition, if (ret) return ret; =20 - ret =3D 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 =3D hv_map_vp_state_page(partition->pt_id, args.vp_index, + HV_VP_STATE_PAGE_INTERCEPT_MESSAGE, + input_vtl_zero, &intercept_msg_page); if (ret) goto destroy_vp; =20 if (!mshv_partition_encrypted(partition)) { - ret =3D hv_call_map_vp_state_page(partition->pt_id, args.vp_index, - HV_VP_STATE_PAGE_REGISTERS, - input_vtl_zero, - ®ister_page); + ret =3D hv_map_vp_state_page(partition->pt_id, args.vp_index, + HV_VP_STATE_PAGE_REGISTERS, + input_vtl_zero, ®ister_page); if (ret) goto unmap_intercept_message_page; } =20 if (mshv_partition_encrypted(partition) && is_ghcb_mapping_available()) { - ret =3D hv_call_map_vp_state_page(partition->pt_id, args.vp_index, - HV_VP_STATE_PAGE_GHCB, - input_vtl_normal, - &ghcb_page); + ret =3D 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; } @@ -960,7 +957,7 @@ mshv_partition_ioctl_create_vp(struct mshv_partition *p= artition, atomic64_set(&vp->run.vp_signaled_count, 0); =20 vp->vp_index =3D args.vp_index; - vp->vp_intercept_msg_page =3D page_to_virt(intercept_message_page); + vp->vp_intercept_msg_page =3D page_to_virt(intercept_msg_page); if (!mshv_partition_encrypted(partition)) vp->vp_register_page =3D page_to_virt(register_page); =20 @@ -993,21 +990,19 @@ mshv_partition_ioctl_create_vp(struct mshv_partition = *partition, if (hv_scheduler_type =3D=3D 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, 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, + 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, + 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); =20 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, + virt_to_page(vp->vp_register_page), + input_vtl_zero); vp->vp_register_page =3D NULL; } =20 - (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, + virt_to_page(vp->vp_intercept_msg_page), + input_vtl_zero); vp->vp_intercept_msg_page =3D NULL; =20 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, + virt_to_page(vp->vp_ghcb_page), + input_vtl_normal); vp->vp_ghcb_page =3D NULL; } =20 --=20 2.34.1 From nobody Tue Dec 16 07:27:11 2025 Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 39450303C9D; Fri, 10 Oct 2025 21:55:56 +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=1760133357; cv=none; b=erojcMvJxeRUno/gkaCXLx8X7R5aObxmKDofJBXzakjmyeFA6fhobgII7etdZzDEvE5PxcM1nPuWbHVPSGqAkY0Au+w3MuPRZZsphD5qS4i4s9el8NtM+SBmtbv0FAxMHvjoCHAqgg4s3S5CSoqQIKtuYXmCEIYQmn7aYE/bYVg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760133357; c=relaxed/simple; bh=OPXqYyZa+uMtY0jw6cNavP6J1J+so/02ZINuC4/9e9M=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=Zft75m7RxKZjgZ6RwQumCvn0FZ+5ypA2i7JzazWIL/zA9LJDLLeKEUx064jCxwqIG6jtfvEj8CtgNyx5GayPMzny43+92IIdrf5uTyp5noIgp1OeVZ31TNKxW/TQ+O3xLDm9otrfF+4Zx9+QwILyB8xTs8G4LNBzaCb+dNEzGgQ= 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=UlneHCcB; 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="UlneHCcB" Received: by linux.microsoft.com (Postfix, from userid 1032) id 8CB7E211CE05; Fri, 10 Oct 2025 14:55:55 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 8CB7E211CE05 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1760133355; bh=j4+GYu5/5yerJ1eNY5p2mTRnm922ZNyEK/pcv9byijs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=UlneHCcBgnTVjtNXgicGKpDIJ7qH4r5BzWvYsFcxsbUw8mfMsM1bhE4297bZRbt7A lGofp8qoVMCSyoQOQnc2KiEO4OrLLpISJXMA6zsd4Ov9GFUicVNNm8eyViPEioXWt9 kG55WMM6dOSoG79kO287SYoD5JbyAdUzjvVRD6pQ= From: Nuno Das Neves To: linux-hyperv@vger.kernel.org, linux-kernel@vger.kernel.org, prapal@linux.microsoft.com, easwar.hariharan@linux.microsoft.com, tiala@microsoft.com, anirudh@anirudhrb.com, paekkaladevi@linux.microsoft.com, skinsburskii@linux.microsoft.com, mhklinux@outlook.com Cc: kys@microsoft.com, haiyangz@microsoft.com, wei.liu@kernel.org, decui@microsoft.com, Jinank Jain , Nuno Das Neves Subject: [PATCH v5 5/5] mshv: Introduce new hypercall to map stats page for L1VH partitions Date: Fri, 10 Oct 2025 14:55:51 -0700 Message-Id: <1760133351-6643-6-git-send-email-nunodasneves@linux.microsoft.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1760133351-6643-1-git-send-email-nunodasneves@linux.microsoft.com> References: <1760133351-6643-1-git-send-email-nunodasneves@linux.microsoft.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Jinank Jain 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 Signed-off-by: Nuno Das Neves Reviewed-by: Easwar Hariharan --- drivers/hv/mshv_root.h | 10 ++-- drivers/hv/mshv_root_hv_call.c | 95 ++++++++++++++++++++++++++++++++-- drivers/hv/mshv_root_main.c | 22 ++++---- include/hyperv/hvgdk_mini.h | 1 + include/hyperv/hvhdk_mini.h | 7 +++ 5 files changed, 115 insertions(+), 20 deletions(-) diff --git a/drivers/hv/mshv_root.h b/drivers/hv/mshv_root.h index dbe2d1d0b22f..0dfccfbe6123 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 6dac9fcc092c..caf02cfa49c9 100644 --- a/drivers/hv/mshv_root_hv_call.c +++ b/drivers/hv/mshv_root_hv_call.c @@ -807,9 +807,51 @@ hv_call_notify_port_ring_empty(u32 sint_index) return hv_result_to_errno(status); } =20 -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 =3D *this_cpu_ptr(hyperv_pcpu_input_arg); + + memset(input, 0, sizeof(*input)); + input->type =3D type; + input->identity =3D *identity; + input->map_location =3D map_location; + + status =3D hv_do_hypercall(HVCALL_MAP_STATS_PAGE2, input, NULL); + + local_irq_restore(flags); + + ret =3D hv_result_to_errno(status); + + if (!ret) + break; + + if (hv_result(status) !=3D HV_STATUS_INSUFFICIENT_MEMORY) { + hv_status_debug(status, "\n"); + break; + } + + ret =3D 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; @@ -848,8 +890,38 @@ int hv_call_map_stat_page(enum hv_stats_object_type ty= pe, return ret; } =20 -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 =3D NULL; + + if (!addr) + return -EINVAL; + + if (mshv_use_overlay_gpfn()) { + allocated_page =3D alloc_page(GFP_KERNEL); + if (!allocated_page) + return -ENOMEM; + + ret =3D hv_call_map_stats_page2(type, identity, + page_to_pfn(allocated_page)); + *addr =3D page_address(allocated_page); + } else { + ret =3D hv_call_map_stats_page(type, identity, addr); + } + + if (ret && allocated_page) { + __free_page(allocated_page); + *addr =3D NULL; + } + + 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; @@ -868,6 +940,19 @@ int hv_call_unmap_stat_page(enum hv_stats_object_type = type, return hv_result_to_errno(status); } =20 +int hv_unmap_stats_page(enum hv_stats_object_type type, void *page_addr, + const union hv_stats_object_identity *identity) +{ + int ret; + + ret =3D 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 b1bd3e2a15ef..9ae67c6e9f60 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; } =20 -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 =3D { .vp.partition_id =3D partition_id, @@ -849,10 +850,10 @@ static void mshv_vp_stats_unmap(u64 partition_id, u32= vp_index) }; =20 identity.vp.stats_area_type =3D HV_STATS_AREA_SELF; - hv_call_unmap_stat_page(HV_STATS_OBJECT_VP, &identity); + hv_unmap_stats_page(HV_STATS_OBJECT_VP, NULL, &identity); =20 identity.vp.stats_area_type =3D HV_STATS_AREA_PARENT; - hv_call_unmap_stat_page(HV_STATS_OBJECT_VP, &identity); + hv_unmap_stats_page(HV_STATS_OBJECT_VP, NULL, &identity); } =20 static int mshv_vp_stats_map(u64 partition_id, u32 vp_index, @@ -865,14 +866,14 @@ static int mshv_vp_stats_map(u64 partition_id, u32 vp= _index, int err; =20 identity.vp.stats_area_type =3D HV_STATS_AREA_SELF; - err =3D hv_call_map_stat_page(HV_STATS_OBJECT_VP, &identity, - &stats_pages[HV_STATS_AREA_SELF]); + err =3D hv_map_stats_page(HV_STATS_OBJECT_VP, &identity, + &stats_pages[HV_STATS_AREA_SELF]); if (err) return err; =20 identity.vp.stats_area_type =3D HV_STATS_AREA_PARENT; - err =3D hv_call_map_stat_page(HV_STATS_OBJECT_VP, &identity, - &stats_pages[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; =20 @@ -880,7 +881,7 @@ static int mshv_vp_stats_map(u64 partition_id, u32 vp_i= ndex, =20 unmap_self: identity.vp.stats_area_type =3D 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; } =20 @@ -988,7 +989,7 @@ mshv_partition_ioctl_create_vp(struct mshv_partition *p= artition, kfree(vp); unmap_stats_pages: if (hv_scheduler_type =3D=3D 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 +1741,8 @@ static void destroy_partition(struct mshv_partition *= partition) continue; =20 if (hv_scheduler_type =3D=3D 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); =20 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 2914fdb24f84..5b42688d4747 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_AS= SIST_PAGE */ #define HVCALL_GET_PARTITION_PROPERTY_EX 0x0101 #define HVCALL_MMIO_READ 0x0106 #define HVCALL_MMIO_WRITE 0x0107 +#define HVCALL_MAP_STATS_PAGE2 0x0131 =20 /* 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; =20 +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; --=20 2.34.1