From: Luca Di Maio <luca@edera.dev>
To: xen-devel@lists.xenproject.org
Cc: "Luca Di Maio" <luca@edera.dev>,
"Jan Beulich" <jbeulich@suse.com>,
"Andrew Cooper" <andrew.cooper3@citrix.com>,
"Roger Pau Monné" <roger@xenproject.org>,
"Teddy Astie" <teddy.astie@vates.tech>,
"Stefano Stabellini" <sstabellini@kernel.org>,
"Julien Grall" <julien@xen.org>,
"Bertrand Marquis" <bertrand.marquis@arm.com>,
"Michal Orzel" <michal.orzel@amd.com>,
"Volodymyr Babchuk" <Volodymyr_Babchuk@epam.com>,
"Anthony PERARD" <anthony.perard@vates.tech>
Subject: [PATCH 1/3] IOMMU: record the flushes skipped under iommu_dont_flush_iotlb
Date: Fri, 30 Oct 2026 17:50:08 +0100 [thread overview]
Message-ID: <20261030165031.2560020-2-luca@edera.dev> (raw)
In-Reply-To: <20261030165031.2560020-1-luca@edera.dev>
While iommu_dont_flush_iotlb is set, iommu_legacy_unmap() and the
shared-EPT path of ept_set_entry() skip their IOTLB flush and drop the
flags it would have used. Accumulate them in the per-CPU
iommu_skipped_flush_flags, so that a caller deferring the flush can
issue it with the same flags. The next patch does so for grant unmaps.
Use a uint8_t, as a fixed width is meant: a byte holds every flag and
fits in the padding after iommu_dont_flush_iotlb, so the per-CPU data
that follows doesn't move.
Assisted-by: Claude Code:claude-opus-5-5
Signed-off-by: Luca Di Maio <luca@edera.dev>
---
xen/arch/x86/mm/p2m-ept.c | 4 ++++
xen/drivers/passthrough/iommu.c | 12 +++++++++++-
xen/include/xen/iommu.h | 1 +
3 files changed, 16 insertions(+), 1 deletion(-)
diff --git a/xen/arch/x86/mm/p2m-ept.c b/xen/arch/x86/mm/p2m-ept.c
index 204bdb054a..1a87b25d94 100644
--- a/xen/arch/x86/mm/p2m-ept.c
+++ b/xen/arch/x86/mm/p2m-ept.c
@@ -981,6 +981,10 @@ out:
(iommu_flags ? IOMMU_FLUSHF_added : 0) |
(vtd_pte_present ? IOMMU_FLUSHF_modified
: 0));
+ else if ( iommu_use_hap_pt(d) )
+ this_cpu(iommu_skipped_flush_flags) |=
+ (iommu_flags ? IOMMU_FLUSHF_added : 0) |
+ (vtd_pte_present ? IOMMU_FLUSHF_modified : 0);
else if ( need_iommu_pt_sync(d) )
rc = iommu_flags ?
iommu_legacy_map(d, _dfn(gfn), mfn, 1ul << order, iommu_flags) :
diff --git a/xen/drivers/passthrough/iommu.c b/xen/drivers/passthrough/iommu.c
index 4b22ecfe65..70ee45afb9 100644
--- a/xen/drivers/passthrough/iommu.c
+++ b/xen/drivers/passthrough/iommu.c
@@ -64,6 +64,11 @@ bool __read_mostly iommu_hap_pt_share = true;
bool __read_mostly iommu_debug;
DEFINE_PER_CPU(bool, iommu_dont_flush_iotlb);
+/*
+ * A byte holds every IOMMU_FLUSHF_*, and fits in the alignment padding the
+ * bool above leaves, instead of shifting the per-CPU data that follows.
+ */
+DEFINE_PER_CPU(uint8_t, iommu_skipped_flush_flags);
static int __init cf_check parse_iommu_param(const char *s)
{
@@ -458,7 +463,12 @@ int iommu_legacy_unmap(struct domain *d, dfn_t dfn, unsigned long page_count)
unsigned int flush_flags = 0;
int rc = iommu_unmap(d, dfn, page_count, 0, &flush_flags);
- if ( !this_cpu(iommu_dont_flush_iotlb) && !rc )
+ if ( this_cpu(iommu_dont_flush_iotlb) )
+ {
+ BUILD_BUG_ON(IOMMU_FLUSHF_all > UINT8_MAX);
+ this_cpu(iommu_skipped_flush_flags) |= flush_flags;
+ }
+ else if ( !rc )
rc = iommu_iotlb_flush(d, dfn, page_count, flush_flags);
return rc;
diff --git a/xen/include/xen/iommu.h b/xen/include/xen/iommu.h
index 37c4a1dc82..028f41bc15 100644
--- a/xen/include/xen/iommu.h
+++ b/xen/include/xen/iommu.h
@@ -501,6 +501,7 @@ void iommu_dev_iotlb_flush_timeout(struct domain *d, struct pci_dev *pdev);
* the caller.
*/
DECLARE_PER_CPU(bool, iommu_dont_flush_iotlb);
+DECLARE_PER_CPU(uint8_t, iommu_skipped_flush_flags);
bool arch_iommu_use_permitted(const struct domain *d);
--
2.54.0
next prev parent reply other threads:[~2026-10-30 16:51 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-30 16:50 [PATCH 0/3] x86/HVM: batch the flushes of grant unmaps Luca Di Maio
2026-10-30 16:50 ` Luca Di Maio [this message]
2026-10-30 16:50 ` [PATCH 2/3] x86/HVM: defer IOTLB flushes across a grant unmap batch Luca Di Maio
2026-10-30 16:50 ` [PATCH 3/3] x86/HVM: defer p2m TLB " Luca Di Maio
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=20261030165031.2560020-2-luca@edera.dev \
--to=luca@edera.dev \
--cc=Volodymyr_Babchuk@epam.com \
--cc=andrew.cooper3@citrix.com \
--cc=anthony.perard@vates.tech \
--cc=bertrand.marquis@arm.com \
--cc=jbeulich@suse.com \
--cc=julien@xen.org \
--cc=michal.orzel@amd.com \
--cc=roger@xenproject.org \
--cc=sstabellini@kernel.org \
--cc=teddy.astie@vates.tech \
--cc=xen-devel@lists.xenproject.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.