From: Mukesh R <mrathor@linux.microsoft.com>
To: linux-hyperv@vger.kernel.org, linux-kernel@vger.kernel.org
Cc: haiyangz@microsoft.com, wei.liu@kernel.org, decui@microsoft.com,
mhkelley58@gmail.com
Subject: [PATCH] mshv: Do pre-commit before mapping a guest VM GPA
Date: Fri, 6 Nov 2026 18:48:42 -0800 [thread overview]
Message-ID: <20261107024842.3929415-1-mrathor@linux.microsoft.com> (raw)
Pre commit reduces TLB flush overheads in the hypervisor. On systems
with large number of CPUs, there is signficant advantage to doing
this. Pre-commit allows the hypervisor to build all data structs needed
in anticipation of the map gpa hypercall, thus reducing or eliminating
deposit page returns from the map gpa hypercall, and as a result reducing
TLB flushes. In some performance benchmarks, it made the maps of large
ranges almost 30% faster.
Signed-off-by: Mukesh R <mrathor@linux.microsoft.com>
---
drivers/hv/mshv_root_hv_call.c | 52 ++++++++++++++++++++++++++++++++++
include/asm-generic/mshyperv.h | 3 ++
include/hyperv/hvgdk_mini.h | 1 +
include/hyperv/hvhdk.h | 7 +++++
4 files changed, 63 insertions(+)
diff --git a/drivers/hv/mshv_root_hv_call.c b/drivers/hv/mshv_root_hv_call.c
index bf0f90515dad..5c44ba8f72b0 100644
--- a/drivers/hv/mshv_root_hv_call.c
+++ b/drivers/hv/mshv_root_hv_call.c
@@ -181,6 +181,54 @@ int hv_call_delete_partition(u64 partition_id)
return hv_result_to_errno(status);
}
+/*
+ * Pre commit to reduce TLB flush overheads in the hypervisor. On systems with
+ * large CPUs, there is signficant advantage to doing this. Pre-commit allows
+ * the hypervisor to build all data structs needed in anticipation of the map
+ * gpa hypercall, thus reducing or eliminating deposit page returns from the
+ * map gpa hypercall, and as a result reducing TLB flushes.
+ */
+static int hv_pre_commit_gpa(u64 pt_id, u64 gfn, u64 num_pages)
+{
+ ulong irq_flags;
+ struct hv_input_precommit_gpa_pages *input_page;
+ int rc = 0;
+ u64 status, done = 0;
+
+ while (done < num_pages) {
+ u16 rep_count = min(num_pages - done, HV_REP_COUNT_MAX);
+
+ local_irq_save(irq_flags);
+ input_page = *this_cpu_ptr(hyperv_pcpu_input_arg);
+ memset(input_page, 0, sizeof(*input_page));
+
+ input_page->partition_id = pt_id;
+ input_page->target_gpa_base = gfn;
+
+ status = hv_do_rep_hypercall(HVCALL_PRECOMMIT_GPA_PAGES,
+ rep_count, 0, input_page, NULL);
+ local_irq_restore(irq_flags);
+
+ done += hv_repcomp(status);
+ gfn += hv_repcomp(status);
+
+ if (hv_result_needs_memory(status)) {
+ rc = hv_deposit_memory(pt_id, status);
+ if (rc)
+ break;
+
+ } else if (!hv_result_success(status)) {
+ pr_err("%s: failed to pre commit for gfn %#llx done %llu/%llu, status=%#llx (%s)\n",
+ __func__, gfn, done, num_pages, status,
+ hv_result_to_string(hv_result(status)));
+ rc = hv_result_to_errno(status);
+ break;
+ }
+ }
+
+ return rc;
+}
+
/* Ask the hypervisor to map guest ram pages or the guest mmio space */
static int hv_do_map_gpa_hcall(u64 partition_id, u64 gfn, u64 page_struct_count,
u32 flags, struct page **pages, u64 mmio_spa)
@@ -205,6 +253,10 @@ static int hv_do_map_gpa_hcall(u64 partition_id, u64 gfn, u64 page_struct_count,
page_count >>= large_shift;
}
+ ret = hv_pre_commit_gpa(partition_id, gfn, page_struct_count);
+ if (ret)
+ return ret;
+
while (done < page_count) {
ulong i, completed, remain = page_count - done;
int rep_count = min(remain, HV_MAP_GPA_BATCH_SIZE);
diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h
index 4c9f3353074a..a3d497d99b0b 100644
--- a/include/asm-generic/mshyperv.h
+++ b/include/asm-generic/mshyperv.h
@@ -28,6 +28,9 @@
#define VTPM_BASE_ADDRESS 0xfed40000
+#define HV_REP_COUNT_MAX \
+ (HV_HYPERCALL_REP_COMP_MASK >> HV_HYPERCALL_REP_COMP_OFFSET)
+
enum hv_partition_type {
HV_PARTITION_TYPE_GUEST,
HV_PARTITION_TYPE_ROOT,
diff --git a/include/hyperv/hvgdk_mini.h b/include/hyperv/hvgdk_mini.h
index 966945f0504f..16c41ee5079a 100644
--- a/include/hyperv/hvgdk_mini.h
+++ b/include/hyperv/hvgdk_mini.h
@@ -489,6 +489,7 @@ union hv_vp_assist_msr_contents { /* HV_REGISTER_VP_ASSIST_PAGE */
#define HVCALL_FLUSH_GUEST_PHYSICAL_ADDRESS_LIST 0x00b0
#define HVCALL_CREATE_DEVICE_DOMAIN 0x00b1
#define HVCALL_ATTACH_DEVICE_DOMAIN 0x00b2
+#define HVCALL_PRECOMMIT_GPA_PAGES 0x00be
#define HVCALL_SIGNAL_EVENT_DIRECT 0x00c0
#define HVCALL_POST_MESSAGE_DIRECT 0x00c1
#define HVCALL_DISPATCH_VP 0x00c2
diff --git a/include/hyperv/hvhdk.h b/include/hyperv/hvhdk.h
index 0c89c62c9706..3944e51d0a2d 100644
--- a/include/hyperv/hvhdk.h
+++ b/include/hyperv/hvhdk.h
@@ -953,4 +953,11 @@ struct hv_input_modify_sparse_spa_page_host_access {
#define HV_MODIFY_SPA_PAGE_HOST_ACCESS_LARGE_PAGE 0x4
#define HV_MODIFY_SPA_PAGE_HOST_ACCESS_HUGE_PAGE 0x8
+struct hv_input_precommit_gpa_pages { /* HV_INPUT_PRECOMMIT_GPA_PAGES */
+ u64 partition_id;
+ u32 flags;
+ u32 reserved;
+ u64 target_gpa_base;
+} __packed;
+
#endif /* _HV_HVHDK_H */
--
2.51.2.vfs.0.1
reply other threads:[~2026-11-07 2:48 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261107024842.3929415-1-mrathor@linux.microsoft.com \
--to=mrathor@linux.microsoft.com \
--cc=decui@microsoft.com \
--cc=haiyangz@microsoft.com \
--cc=linux-hyperv@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mhkelley58@gmail.com \
--cc=wei.liu@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®