On Thu, Jul 2, 2026 at 7:58 AM Thierry Reding <thierry.reding(a)kernel.org> wrote:
>
> On Wed, Jul 01, 2026 at 02:53:10PM -0500, Rob Herring (Arm) wrote:
> >
> > On Wed, 01 Jul 2026 18:08:12 +0200, Thierry Reding wrote:
> > > From: Thierry Reding <treding(a)nvidia.com>
> > >
> > > The Video Protection Region (VPR) found on NVIDIA Tegra chips is a
> > > region of memory that is protected from CPU accesses. It is used to
> > > decode and play back DRM protected content.
> > >
> > > It is a standard reserved memory region that can exist in two forms:
> > > static VPR where the base address and size are fixed (uses the "reg"
> > > property to describe the memory) and a resizable VPR where only the
> > > size is known upfront and the OS can allocate it wherever it can be
> > > accomodated.
> > >
> > > Reviewed-by: Rob Herring (Arm) <robh(a)kernel.org>
> > > Signed-off-by: Thierry Reding <treding(a)nvidia.com>
> > > ---
> > > Changes in v2:
> > > - add examples for fixed and resizable VPR
> > > ---
> > > .../nvidia,tegra-video-protection-region.yaml | 76 ++++++++++++++++++++++
> > > 1 file changed, 76 insertions(+)
> > >
> >
> > My bot found errors running 'make dt_binding_check' on your patch:
> >
> > yamllint warnings/errors:
> >
> > dtschema/dtc warnings/errors:
> > /builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/reserved-memory/nvidia,tegra-video-protection-region.example.dtb: protected@2a8000000 (nvidia,tegra-video-protection-region): reg: [[2, 2818572288], [0, 1879048192]] is too long
> > from schema $id: http://devicetree.org/schemas/reserved-memory/nvidia,tegra-video-protection…
> > /builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/reserved-memory/nvidia,tegra-video-protection-region.example.dtb: protected@2a8000000 (nvidia,tegra-video-protection-region): Unevaluated properties are not allowed ('no-map', 'reg' were unexpected)
> > from schema $id: http://devicetree.org/schemas/reserved-memory/nvidia,tegra-video-protection…
>
> Any ideas why that second error shows up? It turns out that it goes away
> when the first one is fixed (which admittedly is a stupid mistake), but
> I spent quite a bit of time looking for a fix before realizing that it's
> only a side-effect of the first.
If a property fails validation in a referenced schema, then everything
in that referenced schema is considered not evaluated. So then
unevaluatedProperties is applied to the properties only in the
referenced schema. That's why 'no-map' is also unevaluated. Just a
quirk of how json-schema works...
Rob
Looking for a professional [url=https://www.assignmenthelpcanada.ca/essay-writing-service/]Essay Writing Service[/url]? AssignmentHelpCanada.ca provides custom-written essays that meet Canadian university standards. Every paper is plagiarism-free, well-researched, and delivered before the deadline.
Changes since v4:
- Fix an uninitialized memory bug for FenceCbRegistration with
ManuallyDrop.
- Return FenceCtx as impl PinInit
- Make FenceCtx return an impl PinInit<T, Error> (Danilo)
- Reformat some comments
- Adjust the docu for rcu_barrier(), so that it matches the C side's
docu and our docu for rcu::synchronize_rcu().
Changes since v3:
- Add a FIXME for an encountered Rust compiler bug. (Gary)
- Add new Rust files also to DRM drivers & common infrastructure
MAINTAINERS file. (Danilo)
- Reposition ECANCELED error code. (Miguel)
- Replace refcounted FenceCtx in DriverFenceData with a reference plus
life time. (Boris)
- Re-add rcu_barrier() patch, since we now can use it for dropping the
fence context. (Danilo)
- Add forgotten R-b from Alice, and Acks for MAINTAINERS from
Christian and Sumit.
Changes since v2:
- Don't drop DriverFenceData as a whole, but only the members we
really want to drop. Gives more robustness. (Gary).
- Break apart large pin_init_from_closure(). (Danilo, Onur)
- Remove rcu_barrier() and synchronize_rcu() from FenceCtx::drop().
FenceCtx might drop in atomic context, where you must not perform
those operations. With the current way C dma_fence is designed, the
driver must wait for a grace period manually until it unloads.
- Repair the DriverFenceBorrow implementation, properly injecting a
life time into it. (Danilo)
- Fix memory layout bug for rcu_head. (Onur)
- Drop RCU patches, since this series doesn't need them anymore.
Changes since v1:
- Remove unnecessary mutable references (Alice)
- Split up unsafe comments where possible (Danilo)
- Remove PhantomData + implement FenceCtx ops trait (Boris)
- Consistently call FenceCtx generic data `T`. FenceDataType is
derived from that. (Boris)
- Add abstractions for call_rcu() and synchronize_rcu() (Danilo)
- Add ECANCELED error code in Rust (Alice)
- Remove the rcu_barrier() from FenceCtx::drop() – because we now use
call_rcu(), there can be no UAF access to the FenceCtx anymore. In
any case, it is illegal to use either call_rcu() or
synchronize_rcu() in FenceCtx::drop(), because our new
drop_driver_fence_data() can run in atomic context and might put the
last fence_ctx reference.
So we now only have to guard against module unload, which it seems
either the driver or Rust driver-core / module unload infrastructure
must solve.
- Minor formatting etc. changes
- Add C helpers to MAINTAINERS. (Danilo)
- Ensure that `Fence::is_signaled()` is fully synchronized, i.e., all
callbacks really have run. See [1] and [2]. (Myself, Christian
König)
Changes since the RFCs:
- Include support for ForeignOwnable for ARef, so that a Fence can be
stuffed into an XArray et al. (Code by Danilo)
- Implement ForeignOwnable (with new borrow type) for DriverFence, so
that it can be stuffed into an XArray.
- Include the rcu::RcuBox data type to defer dropping data with RCU
(Cody by Alice)
- Port DmaFence to RcuBox to make UAF bugs through later, new dma_fence
callbacks (backend_ops) impossible.
- Force users to pass their fence data in an RcuBox (or have it not
need drop()) through a Sealed trait.
- Document the rules for the user's DriverFence::data's drop
implementation very clearly (deadlock danger).
- rustfmt, Clippy.
- Various style suggestions, safety comments, etc. (Önur)
- Add __rust_helper prefix to helper functions. (Önur)
Changes in RFC v3:
- Omit JobQueue patches for now
- Completely redesign the memory layout: Instead of a Fence
refcounting a DriverFence, both now live in the same allocation to
allow for future support the dma_fence backend_ops callbacks which
need to do container_of. (mostly Boris's feedback)
- Allow for pre-allocating fences to avoid deadlocks when submitting
jobs to a GPU. (Boris)
- Simultaneously, allow for pre-preparing fence callback objects, so
the driver can allocate them when it sees fit. (code largely stolen
and inspired by Daniel).
- Signal fences on drop, ensure synchronization.
- Force users to set an error code when signalling.
- Write more documentation
- A ton of minor other changes.
[1] https://lore.kernel.org/dri-devel/20260608142436.265820-2-phasta@kernel.org/
[2] https://lore.kernel.org/dri-devel/20260612104251.2264707-2-phasta@kernel.or…
Alright, so since the last RFCs did not reveal significant design
issues, I decided to transition this series to a v1 and hope that we can
get it upstream.
This now includes code for more common infrastructure that dma_fence
needs, contributed by Danilo and Alice.
---
Old cover letter for RFC:
So, this is the spiritual successor of the first / second RFC [1]. v2
also contained code for drm::JobQueue, but mostly to show how the fence
code would be used. JobQueue is under heavy rework right now, so I don't
want to bother your eyes with it. The docstring examples should show how
Rust fences are supposed to be used, though.
This v3 contains a huge amount of highly valuable feedback from a
variety of people, notably Boris, but also from Alice, Gary and Danilo.
There are some TODOs open (a better trait for fence backend_ops and RCU
support), but my hope is that this effort is now finally approaching its
end.
I would greatly appreciate feedback and especially more information
about what might be missing to make this usable, which is obviously
where Daniel's and Boris's feedback will be valuable once more.
Please regard this patch just as what it's titled: an RFC, to discuss a
bit more and to inform a broader community about what the current state
is and where this is heading at.
Many regards,
Philipp
[1] https://lore.kernel.org/rust-for-linux/20260203081403.68733-2-phasta@kernel…
Danilo Krummrich (1):
rust: types: implement ForeignOwnable for ARef<T>
Philipp Stanner (4):
rust: error: Add ECANCELED error code
rust: sync: Add abstraction for rcu_barrier()
rust: Add dma_fence abstractions
MAINTAINERS: Add entry for Rust dma-buf
MAINTAINERS | 5 +
rust/bindings/bindings_helper.h | 1 +
rust/helpers/dma_fence.c | 48 ++
rust/helpers/helpers.c | 1 +
rust/kernel/dma_buf/dma_fence.rs | 894 +++++++++++++++++++++++++++++++
rust/kernel/dma_buf/mod.rs | 14 +
rust/kernel/error.rs | 1 +
rust/kernel/lib.rs | 1 +
rust/kernel/sync/aref.rs | 40 ++
rust/kernel/sync/rcu.rs | 20 +
10 files changed, 1025 insertions(+)
create mode 100644 rust/helpers/dma_fence.c
create mode 100644 rust/kernel/dma_buf/dma_fence.rs
create mode 100644 rust/kernel/dma_buf/mod.rs
base-commit: a73a398a68ca9b9e5116a617562471f16b8310c4
--
2.54.0
https://geometrydash-pc.com/
If you've ever tapped your foot to a beat and thought, "I bet I could time a square's mid-air landing to this," then you're ready for the world of rhythm-based platformers—specifically, the wild, colorful, and frustratingly addictive universe of Geometry Dash. At its core, it's simple: a square moves forward automatically, and you tap to jump. In practice, it's a full-body workout for your brain's timing center. Let's break down how to actually experience—and eventually enjoy—this kind of geometric jump challenge without throwing your keyboard across the room.
Part One: What Even Is This?
Before we talk about tricks, let's set the stage. The core experience of Geometry Dash revolves around a single action: tap to jump. The square—or spider, or ball, or UFO, or wave—moves on its own, sliding across a track filled with spikes, blocks, and gravity portals. Your job is to tap at exactly the right moment to avoid instant death. Sounds easy? It's not. But that's also the point.
The beauty of this kind of gameplay—a "geometry jump" style, where everything is angles, symmetry, and sudden death—is that it strips away complexity. There's no health bar. No power-ups. No second chances. You die in one hit and restart immediately. This design forces you into a flow state: your eyes lock onto the screen, your ears lock onto the beat, and your thumb becomes a metronome.
The key insight? You're not playing a platformer. You're playing a song with visual obstacles. Every spike, every jump, every gravity flip is mapped to the rhythm. If you're tapping without hearing the music, you will fail. If you're listening but not watching the trail ahead, you will also fail. True mastery happens when both senses merge.
Part Two: The Gameplay Loop – Death, Respawning, and the Grind
Here's what a typical round looks like for a beginner:
1. You press play. The music starts. Your square begins moving.
2. First obstacle appears. You jump over it. You feel like a god.
3. Second obstacle appears. You jump. You die.
4. You respawn instantly.
5. Repeat steps 1-4 about forty-seven times.
6. You make it past the second obstacle.
7. Third obstacle kills you.
8. You realize you've been playing for thirty minutes and have progressed exactly 2% of the level.
This loop sounds miserable on paper, but in practice, it's hypnotic. The instant restart is the secret sauce. There's no loading screen, no "Game Over" animation, no time wasted. You die, you're back in under a second, and the music is still playing. This keeps your brain in a learning groove. Each death teaches your fingers something—a slightly earlier tap, a slightly shorter hold.
As you play more levels, you'll encounter different game modes within the same geometry jump framework:
The Cube: Basic. Tap to jump. Land on platforms.
The Ship: Hold to fly up, release to drop. Think of it as a gravity-defying seesaw.
The Ball: Tap to flip gravity. Stay on ceilings or floors.
The UFO: Tap to do a small hop. Needs rapid, rhythmic tapping.
The Wave: Hold and release to move diagonally. Pure chaos.
The Spider: Tap to teleport from floor to ceiling.
Each mode demands a different kind of timing, but the core rule remains: the music tells you when. The beat of the song is your guide—the spikes are almost always placed on the downbeat or the offbeat.
Part Three: Tips for Surviving (and Maybe Even Enjoying)
You will die. A lot. That's not a failure; that's the game working as intended. But here's how to make the experience less "angry quitting" and more "addictive progression."
1. Listen First, Watch Second
Before you even try a level, just listen to the song. The best Geometry Jump levels are designed by people who choreographed obstacles to the track. If you know when the drop hits, you'll know when a tricky section is coming. Let the rhythm enter your bones.
2. Memorize, Don't React
Beginners try to react to obstacles. That doesn't work. By the time you see a spike, it's too late. Instead, memorize the level in chunks. "Okay, after the blue portal, there are three jumps in quick succession, then a short gap." Play the same ten-second section over and over until your fingers move automatically. You're building muscle memory, not reflexes.
3. Use Practice Mode (Seriously)
Every level has a practice mode with checkpoints. Use it. There's no shame in placing a checkpoint right before a hard section and practicing it twenty times in a row. The pros do the same thing. "Practicing" isn't cheating—it's learning.
4. Calibrate Your Offset
If you feel like you're tapping exactly on the beat but still dying, check your audio/visual offset. Every setup has a tiny delay between when the game processes your tap and when you hear the sound. Adjusting this can turn an impossible level into a challenging one.
5. Take Breaks
There's a phenomenon called "nervous fatigue" where, after playing for an hour, your timing gets worse, not better. Your hands shake. You tap too early. Walk away for ten minutes. Make tea. Stretch. Come back fresh. Often, the section that killed you fifty times will click on your first attempt after a break.
6. Recognize the "Flow Zone"
When you hit the sweet spot, something magical happens: time slows down. Your taps become effortless. You're not thinking about the obstacles anymore—you're just dancing through them. This is the flow state. It's rare at first, but the more you practice, the easier it is to access. The key is to relax your hand. A death grip on the mouse or keyboard tenses your whole arm and messes up your timing. Breathe.
7. Don't Compare Yourself
You'll see people online beating the hardest levels in minutes. Ignore them. They have thousands of hours. Your journey is your own. Celebrate small wins: making it 10% further, beating a level that took you an hour, finally nailing that one jump. Every player, even the best, started exactly where you are: dying on the first obstacle.
Conclusion: The Joy of the Jump
At first glance, a geometry jump game like Geometry Dash looks like a simple time-waster. A square. Some spikes. A song. How deep could it possibly be? But if you give it real time—not just ten minutes, but an afternoon, a week, a month—you'll discover something surprising. It's not about finishing the level. It's about the moment when your brain and the music and the visual pattern finally click into alignment. That fraction of a second where you're not thinking, you're just doing. That's the real reward.
So open up the game, put on headphones, and let the beat guide you. Fail spectacularly. Restart instantly. And when you finally clear that one impossible section, you'll realize why people keep coming back. Because sometimes, the only way forward is a well-timed jump into the unknown.
Exploring the World of Vehicle Engineering in Drive Mad
Drive Mad changes how we think about traditional racing games. You are not just pushing a gas pedal to win. You are managing the weight and the center of gravity of your machine. Every car has a different personality in this game. Some are heavy and stable while others are light and bouncy. Choosing the right vehicle for the level is your first strategic step.
The levels in Drive Mad are more like mechanical puzzles than race tracks. You have to understand the triggers that move the obstacles. A platform might drop only when you reach a certain point. You must time your approach to avoid the trap. It requires you to observe the environment before you take action. This brain work makes the game much more satisfying than simple racing titles.
You will encounter many moments of frustration during your progress. This is the main appeal of the game for many players. You learn from every mistake you make on the road. Eventually you find the perfect rhythm to clear the most difficult gaps. The feeling of success after a hard level is unmatched. Keep your focus sharp and your hands ready to drive.
https://drivinggames.io
Hi all,
This series is based on previous RFCs/discussions:
Tech topic: https://lore.kernel.org/linux-iommu/20250918214425.2677057-1-amastro@fb.com/
RFCv1: https://lore.kernel.org/all/20260226202211.929005-1-mattev@meta.com/
RFCv2: https://lore.kernel.org/kvm/20260312184613.3710705-1-mattev@meta.com/
The background/rationale is covered in more detail in the RFC cover
letters. The TL;DR is:
The goal is to enable userspace driver designs that use VFIO to export
DMABUFs representing subsets of PCI device BARs, and "vend" those
buffers from a primary process to other subordinate processes by fd.
These processes then mmap() the buffers and their access to the device
is isolated to the exported ranges. This is an improvement on sharing
the VFIO device fd to subordinate processes, which would allow
unfettered access.
This is achieved by enabling mmap() of vfio-pci DMABUFs, passed by fd
to subordinate processes. Second, a new revocation mechanism is added
to allow the primary process to forcibly revoke access to
previously-shared BAR spans, even if the subordinate processes haven't
cleanly exited.
(The related topic of safe delegation of iommufd control to the
subordinate processes is not addressed here, and is follow-up work.)
As well as isolation and revocation, another advantage to accessing a
BAR through a VMA backed by a DMABUF is that it's straightforward to
mmap() the buffer with access attributes, such as write-combining.
Feedback from the RFCs requested that, instead of creating
DMABUF-specific vm_ops and .fault paths, to go the whole way and
migrate the existing VFIO PCI BAR mmap() to be backed by a DMABUF too,
resulting in a common vm_ops and fault handler for mmap()s of both the
VFIO device and explicitly-exported DMABUFs. This will help future
iommufd emulation of VFIO Type1 peer-to-peer, making it easier to get
a DMABUF for a VFIO BAR as a DMA target.
mmap() conversion to use DMABUF underneath has been done for vfio-pci,
but not sub-drivers:
nvgrace-gpu's mmap() override path is unchanged; I kept this out of
scope for now not least because I don't have a thorough test setup
for this system. I would prefer to help the nvgrace-gpu maintainers
enable BAR mmap() DMABUFs themselves.
Notes on patches
================
PCI/P2PDMA: Split pool-related cleanup out of pci_p2pdma_release()
PCI/P2PDMA: Add CONFIG_PCI_P2PDMA_CORE
Later in the series, vfio-pci's mmap() is going to depend on
pcim_p2pdma_provider() which depended on CONFIG_PCI_P2PDMA, which
in turn depended on ZONE_DEVICE. That isn't available on 32-bit
and some archs, because they lack MEMORY_HOTPLUG and friends.
VFIO does _not_ require actual P2P to be present for basic mmap()
functionality, only for the optional CONFIG_DMA_SHARED_BUFFER
feature.
These split out p2pdma_core.c under CONFIG_PCI_P2PDMA_CORE (which
currently contains pcim_p2pdma_provider()), and an optional
CONFIG_PCI_P2PDMA which depends on ZONE_DEVICE etc. providing
P2P functionality in the existing p2pdma.c. The first splits
out pool cleanup from the release path, and the second does the
refactor/code move to the new file.
vfio/pci: Add a helper to look up PFNs for DMABUFs
vfio/pci: Add a helper to create a DMABUF for a BAR-map VMA
The first adds a DMABUF VMA fault handler helper to determine
arbitrary-sized PFNs from ranges in DMABUF. Secondly, refactor
DMABUF export for use by the existing export feature and add a
helper that creates a DMABUF corresponding to a VFIO BAR mmap()
request.
vfio/pci: Convert BAR mmap() to use a DMABUF
The vfio-pci core mmap() creates a DMABUF with the helper, and the
vm_ops fault handler uses the other helper to resolve the fault.
Because this depends on DMABUF structs/code, CONFIG_VFIO_PCI_CORE
needs to depend on CONFIG_DMA_SHARED_BUFFER. The
CONFIG_VFIO_PCI_DMABUF still conditionally enables the export
support code.
NOTE: The user mmap()s a device fd, but the resulting VMA's vm_file
becomes that of the DMABUF. The DMABUF takes ownership of the
device file and put()s it on release, which maintains the existing
behaviour of a VMA keeping the VFIO device open.
BAR zapping then happens via the existing vfio_pci_dma_buf_move()
path, which now needs to unmap PTEs in the DMABUF's address_space.
vfio/pci: Provide a user-facing name for BAR mappings
There was a request for decent debug naming in /proc/<pid>/maps
etc. comparable to the existing VFIO names: since the VMAs are
DMABUFs, they have a "dmabuf:" prefix and can't be 100% identical
to before. This is a user-visible change, but this patch at least
now gives us extra info on the BDF & BAR being mapped.
vfio/pci: Clean up BAR zap and revocation
In general (see NOTE!) the vfio_pci_zap_bars() is now obsolete,
since it unmaps PTEs in the VFIO device address_space which is now
unused. This consolidates all calls (e.g. around reset) with the
neighbouring vfio_pci_dma_buf_move()s into new functions, to
revoke/unrevoke (making the steps clearer).
NOTE: Because drivers can use their own vm_ops and override .mmap,
the core must conservatively assume an overridden .mmap might still
add PTEs to the VFIO device address_space and therefore still does
the zap. A new flag, zap_bars_on_revoke, enables the zap when
.mmap is overridden. A driver that does not need the zap can clear
this to opt-out, e.g. if the driver calls down to the common mmap
(and so uses DMABUFs).
vfio/pci: Support mmap() of a VFIO DMABUF
Adds mmap() for a DMABUF fd exported from vfio-pci.
It was a goal to keep the VFIO device fd lifetime behaviour
unchanged with respect to the DMABUFs. An application can close
all device fds, and this will revoke/clean up all DMABUFs; no
mappings or other access can be performed now. When enabling
mmap() of the DMABUFs, this means access through the VMA is also
revoked. This complicates the fault handler because whilst the
DMABUF exists, it has no guarantee that the corresponding VFIO
device is still alive. Adds synchronisation ensuring the vdev is
available before vdev->memory_lock is touched; this holds the
device registration so that even if the buffer has been cleaned up,
vdev hasn't been freed and so the lock can be safely taken.
vfio/pci: Permanently revoke a DMABUF on request
By weight, this is mostly a rename of revoked to an enum, status.
There are now 3 states for a buffer, usable and revoked
temporary/permanent. A new VFIO feature is added,
VFIO_DEVICE_FEATURE_DMA_BUF_REVOKE, which takes a DMABUF (exported
from the same device) and permanently revokes it. Thus a userspace
driver can guarantee any downstream consumers of a shared fd are
prevented from accessing a BAR range, and that range can be reused.
NOTE: This might block userspace, waiting on importers to detach.
The code doing revocation in vfio_pci_dma_buf_move() is moved, to a
common function for use by ..._move() and this new feature.
NOTE: See changelog, by request v4 added a condition to the
existing code to elide the unnecessary invalidation/sync on the
un-revoke path.)
vfio/pci: Add mmap() attributes to DMABUF feature
Adds a new VFIO feature, VFIO_DEVICE_FEATURE_DMA_BUF_MEMATTR.
After a DMABUF is exported, this feature is used to set a memory
attribute that will be used by future mmap()s of the DMABUF fd. It
doesn't affect existing maps.
The default is UC, and via the feature one can specify CPU access
as WC. The attribute is an enum/scalar rather than
bitmap/cumulative. The attributes follow a "try-fail" model where
a client can request an attribute and either succeed or fail with
ENOENT if it's unknown; if future attributes are platform-specific
then their support can be probed.
Since it's just UC/WC for now, there is no reservation or numeric
structure to the namespace yet, but we could support
system/arch-specific values in future by carving out base +
arch-specific + IMPDEF ranges.
Testing
=======
(The [RFC ONLY] userspace test program, for QEMU edu-plus, can be
found in the GitHub branch below. It at least illustrates how the
export, map, revoke, attribute, and close semantics interoperate.)
This code has been tested in mapping DMABUFs of single/multiple ranges
from multiple BARs, aliasing mmap()s, aliasing ranges across DMABUFs,
vm_pgoff > 0, revocation, shutdown/cleanup scenarios, and hugepage
mappings. I've lightly tested WC mappings also (by observing
resulting PTEs as having the correct attributes...). No regressions
observed on the VFIO selftests, or on our internal vfio-pci
applications. VFIO on i386 has been build-tested.
Dear Reviewers,
===============
I was grateful for the reviews and Reviewed-Bys on previous versions
from several of you; I've added some Reviewed-Bys.
But, various changes were also requested and I'm erring on the
conservative side: I have NOT included your Reviewed-Bys where the
patch has changed after your review (or where requested changes ended
up more than super-trivial). I hope that's okay.
End
===
This is based on v7.1.
These commits are on GitHub for easier browsing, along with
"[RFC ONLY] selftests: vfio: Add standalone vfio_dmabuf_mmap_test":
https://github.com/metamev/linux/compare/8cd9520d35a6...dev/mev/vfio-dmabuf…
Thanks for reading,
Matt
================================================================================
Changelog:
v4:
- Rebased on v7.1
- 1/9: Split the p2pdma.c pool release code into a new patch, making
the second patch a pure code-move exercise. Reworded the commit
messages, comment cleanups.
- 2/9 Look up PFNs helper: renamed DMABUF range search loop variables
for clarity, and simplified search loop and fallthrough/exit logic.
Moved WARN to ratelimited warnings. Rearranged pfn arithmetic to
avoid potential overflow. Clarified comments, better explanation
of vma_pgoff_adjust, spelling.
- 4/9 convert BAR mmap(): Trivial comment change, move. Used 'true'
instead of '1' for unmap_mapping_range() arg, consistent with
elsewhere in vfio-pci.
- 5/9 User-facing name for mappings: Uses kasprintf() instead.
- 6/9 Clean up BAR zap: Renamed functions to simplify/shorten names,
emphasising "revoke/unrevoke" actions. (Then internally this will
do a DMABUF revoke and possibly a PTE zap.)
NOTE: We debated ordering of a previous zap before a transition
to D0 before reset. The conclusion was the current patch is OK.
- 7/9 mmap() of a DMABUF: Added helper vfio_pci_set_vma_ops() to keep
ops struct static/local. Squashed vfio_pci_dma_buf_mmap() comments
for space/clarity.
- 8/9 DMABUF revoke: Fix typos in commit message. Implement request
to add a condition to revocation path to only invalidate/wait when
a buffer is being revoked (avoiding it on un-revoke).
NOTE: This means a (small) change to the code moved from
vfio_pci_dma_buf_move.
NOTE: Also, we discussed adding warnings for setting a state
matching the existing state; I didn't add them after all, because
these situations can occur in normal usage (e.g. a revoke of a
buffer from a device in D3, or a cleanup of a lingering
user-revoked buffer).
v3:
https://lore.kernel.org/all/20260610154327.37758-1-matt@ozlabs.org/
- Refactor p2pdma.c: split out pcim_p2pdma_provider() into a new
p2pdma_core.c under CONFIG_PCI_P2PDMA_CORE.
- vfio_pci_dma_buf_find_pfn() cleanups: Rename parameter to priv,
remove bad WARN, move unnecessary addition out of inner loop.
- vfio_pci_core_mmap_prep_dmabuf() cleanups: Remove uint32_t, remove
unnecessary const variable.
- Conversion of BAR mmap() to DMABUF: VFIO_PCI_DMABUF depends on
VFIO_PCI_CORE. vfio_pci_mmap_huge_fault(): move dev_dbg() outside
of lock (argh), remove READ_ONCE(vdev)/move priv->vdev read and
improve comment explanation.
- On revoke, BAR zap defaults to on if .mmap is overridden by a
driver (and implements an opt-out for the hisi_acc_vfio_pci driver,
which overrides mmap() with a simple wrapper that ends up using the
common DMABUF mmap() rather than custom mappings).
- Reworded commit "vfio/pci: Support mmap() of a VFIO DMABUF" message
for clarity. Reworded vfio_pci_mmap_huge_fault() comment for
accuracy (vdev validity depends on not being revoked).
Added comment in mmap() explaining belt-and-braces approach for
early detecting a map of a revoked buffer.
- Revoke now uses VFIO_DEVICE_FEATURE_DMA_BUF rather than a new
ioctl(); instead of the revoke helper taking 'revoked/permanently'
bools, it's become vfio_pci_dma_buf_set_status() taking a single
status enum. Added a READ_ONCE() for the lockless test of
priv->vdev (flags it as intentional, even if it's in practice going
to be a single-copy atomic read).
- Removed GET on vfio_pci_core_feature_dma_buf_memattr(), removed
unnecessary taking of memory_lock, fixed error return values. In
particular, removes ENOTSUPP, and uses ENOENT to indicate an
unknown attribute enum value was passed to SET. In the discussion
here,
https://lore.kernel.org/all/20260602131417.41366391@shazbot.org/
we'd agreed on EOPNOTSUPP before I realised that's already used
elsewhere. ENOENT uniquely indicates an unknown attribute.
v2:
https://lore.kernel.org/all/20260527102319.100128-1-mattev@meta.com/
- Rebase on VFIO next, picking up Alex's
vfio_pci_dma_buf_move()/vfio_pci_dma_buf_cleanup() fixes, and
dropping "vfio/pci: Fix vfio_pci_dma_buf_cleanup() double-put"
- Added "PCI/P2PDMA: Add CONFIG_PCI_P2PDMA_CORE" so that the
newly-added vfio-pci hard dependency on the P2PDMA provider instead
pulls in the _CORE variant and not the full-fat CONFIG_PCI_P2PDMA.
This means that the core of vfio-pci does not need ZONE_DEVICE, but
if it's available then enabling P2PDMA in turn enables DMABUF
export. Fixes basic VFIO operation on 32b or other platforms without
ZONE_DEVICE.
- Fixed comment inaccuracy in vfio_pci_dma_buf_revoke() and cleaned
up vdev validity test.
- vfio_pci_dma_buf_find_pfn(): use PAGE_ALIGN(), better span variable
naming, OVF check
- Made vm_pgoffs use consistent (keeping the resource index at the
top and masking where offset is used). For BAR mmap, use new
vma_pgoff_adjust to create the DMABUF with the exact mmap()ed span
instead of from the start of the BAR with an invisible portion
before the mapping.
- Added VFIO_DEVICE_FEATURE_DMA_BUF_MEMATTR to set memory attributes,
instead of using the export `flags` field.
- vfio_pci_ioctl_reset: Moved vfio_pci_zap_revoke_bars()
(effectively, vfio_pci_dma_buf_move()) back after D0 transition.
Note, if a BAR zap is needed, it's done in this function so now
happens after this D0 transition with the _move; it was done before
it at the time of the memory_lock taking.
- Minimised vfio_pci_dma_buf_mmap() (removed redundant span check),
added READ_ONCE for memattr
- Misc fixes: comment in DMABUF name generation, removed superfluous
READ_ONCE from faulthandler
v1:
https://lore.kernel.org/kvm/20260416131815.2729131-1-mattev@meta.com/
- Cleanup of the common DMABUF-aware VMA vm_ops fault handler and
export code.
- Fixed a lot of races, particularly faults racing with DMABUF
cleanup (if the VFIO device fds close, for example).
- Added nicer human-readable names for VFIO mmap() VMAs
RFCv2: Respin based on the feedback/suggestions:
https://lore.kernel.org/kvm/20260312184613.3710705-1-mattev@meta.com/
- Transform the existing VFIO BAR mmap path to also use DMABUFs
behind the scenes, and then simply share that code for
explicitly-mapped DMABUFs. Jason wanted to go that direction to
enable iommufd VFIO type 1 emulation to pick up a DMABUF for an IO
mapping.
- Revoke buffers using a VFIO device fd ioctl
RFCv1:
https://lore.kernel.org/all/20260226202211.929005-1-mattev@meta.com/
Matt Evans (10):
PCI/P2PDMA: Split pool-related cleanup out of pci_p2pdma_release()
PCI/P2PDMA: Add CONFIG_PCI_P2PDMA_CORE
vfio/pci: Add a helper to look up PFNs for DMABUFs
vfio/pci: Add a helper to create a DMABUF for a BAR-map VMA
vfio/pci: Convert BAR mmap() to use a DMABUF
vfio/pci: Provide a user-facing name for BAR mappings
vfio/pci: Clean up BAR zap and revocation
vfio/pci: Support mmap() of a VFIO DMABUF
vfio/pci: Permanently revoke a DMABUF on request
vfio/pci: Add mmap() attributes to DMABUF feature
MAINTAINERS | 2 +-
drivers/pci/Kconfig | 10 +-
drivers/pci/Makefile | 1 +
drivers/pci/p2pdma.c | 109 +---
drivers/pci/p2pdma.h | 29 +
drivers/pci/p2pdma_core.c | 118 ++++
drivers/vfio/pci/Kconfig | 5 +-
drivers/vfio/pci/Makefile | 3 +-
.../vfio/pci/hisilicon/hisi_acc_vfio_pci.c | 8 +
drivers/vfio/pci/vfio_pci_config.c | 30 +-
drivers/vfio/pci/vfio_pci_core.c | 211 +++++--
drivers/vfio/pci/vfio_pci_dmabuf.c | 568 +++++++++++++++---
drivers/vfio/pci/vfio_pci_priv.h | 63 +-
include/linux/pci-p2pdma.h | 24 +-
include/linux/pci.h | 2 +-
include/linux/vfio_pci_core.h | 1 +
include/uapi/linux/vfio.h | 47 ++
17 files changed, 960 insertions(+), 271 deletions(-)
create mode 100644 drivers/pci/p2pdma.h
create mode 100644 drivers/pci/p2pdma_core.c
--
2.50.1 (Apple Git-155)
We recently had another incident where two drivers put pages they got from
get_user_pages() into a DMA-buf and cause quite a number of problems.
Explicitely document that this is not something exporters can do.
Signed-off-by: Christian König <christian.koenig(a)amd.com>
---
drivers/dma-buf/dma-buf.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
index 71f37544a5c6..aa5af4f439c2 100644
--- a/drivers/dma-buf/dma-buf.c
+++ b/drivers/dma-buf/dma-buf.c
@@ -685,6 +685,14 @@ static struct file *dma_buf_getfile(size_t size, int flags)
*
* For the detailed semantics exporters are expected to implement see
* &dma_buf_ops.
+ *
+ * It is explicitely forbidden for exporters to expose buffers they don't "own"
+ * as DMA-buf. This includes pages acquired by get_user_pages() or other import
+ * mechanism. Not following this rule can create numerous security problems.
+ *
+ * It is also strongly discouraged to expose the same backing store through
+ * multiple DMA-bufs at the same time. This eventually creates aliasing and
+ * cache coherency problems which are extremely hard to debug and fix.
*/
/**
--
2.43.0