Thread (18 messages) 18 messages, 5 authors, 27m ago
HOTtoday

[PATCH 1/6] generic_pt: allow missing sw bit in DMA_INCOHERENT case

From: Daniel Drake <hidden>
Date: 2026-07-12 21:19:43
Also in: linux-devicetree, linux-iommu, lkml
Subsystem: iommu subsystem, the rest · Maintainers: Joerg Roedel, Will Deacon, Linus Torvalds

When working with a iommu with PT_FEAT_DMA_INCOHERENT set, generic_pt
will attempt to use a spare "SW" bit in the hardware page tables to
denote when a thread has flushed the CPU cache after modifying an entry.

This means that other threads know that they are not working with
cached/unflushed data, if they come across the same entry.

In the case where no SW bit is available, two things happen:

1. __map_range() defensively flushes every time it reads the PT.
   This ensures all data that may have just been manipulated by another
   thread gets flushed and made iommu-visible immediately.

2. An undefined reference to __pt_no_sw_bit() is created, causing a
   linker error in order to alert the developer that they are going
   to suffer a performance penalty in the previous point.

The BCM2712 IOMMU appears to be the first device supported by generic_pt
that hits this case. The prod to check for sw bits is appreciated,
but in this case there are no known bits that can be used, so we need
to acknowledge and accept the performance penalty without a linker error.

Adding an empty __pt_no_sw_bit() symbol to iommu_bcm2712 would be
problematic because if a second IOMMU were to have the same constraint,
this would result in a symbol clash in the global namespace. Also, the
kunit build creates and builds a 2nd variant of the same code and hits
this exact collision.

Add an opt-in PT_SW_BIT_NOT_PRESENT flag to avoid this. This prevents
the undefined reference from being created, allowing drivers like bcm2712
to acknowledge the situation and accept the performance penalty of the
defensive flushing.

Signed-off-by: Daniel Drake <redacted>
---
 drivers/iommu/generic_pt/pt_fmt_defaults.h | 13 +++++++++++++
 1 file changed, 13 insertions(+)
diff --git a/drivers/iommu/generic_pt/pt_fmt_defaults.h b/drivers/iommu/generic_pt/pt_fmt_defaults.h
index 69fb7c2314ca..cc57106c87d1 100644
--- a/drivers/iommu/generic_pt/pt_fmt_defaults.h
+++ b/drivers/iommu/generic_pt/pt_fmt_defaults.h
@@ -249,7 +249,20 @@ static inline unsigned int pt_max_sw_bit(struct pt_common *common)
 	return 0;
 }
 
+/*
+ * In the DMA_INCOHERENT case, if no SW bit has been defined, produce a linker
+ * error (undefined symbol __pt_no_sw_bit) to alert the developer that they
+ * will suffer a performance penalty due to defensive flushing. The driver
+ * can either implement pt_sw_bit (if supported by the hardware) for optimal
+ * performance, or otherwise set PT_SW_BIT_NOT_PRESENT to acknowledge the
+ * performance penalty.
+ */
+#ifdef PT_SW_BIT_NOT_PRESENT
+static inline void __pt_no_sw_bit(void) {}
+#else
 extern void __pt_no_sw_bit(void);
+#endif
+
 static inline bool pt_test_sw_bit_acquire(struct pt_state *pts,
 					  unsigned int bitnr)
 {
-- 
2.55.0

Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help