All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Lyude Paul" <lyude@redhat.com>
Cc: dri-devel@lists.freedesktop.org, ojeda@kernel.org
Subject: Re: [PATCH v20 2/4] rust: drm: gem: shmem: Add vmap functions
Date: Wed, 10 Jun 2026 16:39:45 +0000	[thread overview]
Message-ID: <20260610163946.4120B1F00893@smtp.kernel.org> (raw)
In-Reply-To: <20260610162433.923550-3-lyude@redhat.com>

Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [High] VMap unconditionally implements Send and Sync without requiring its generic parameter R to be Send or Sync.
- [High] The Sync implementation for VMap combined with its IoCapable trait implementations allows safe concurrent volatile writes to the same memory location, causing a data race.
- [Medium] Off-by-one error in vmap_io kunit test loop prematurely terminates the test, preventing verification of the final byte.
- [Low] Struct VMap fails to compile due to unused generic type parameters D and C.
--

commit 2c1f27a93b4873be7178ca4b1861ef62ac59a6b1
Author: Lyude Paul <lyude@redhat.com>

rust: drm: gem: shmem: Add vmap functions

This commit hooks up vmap creation for gem shmem objects in the Rust bindings,
allowing mappings to be created for their contents.

> diff --git a/rust/kernel/drm/gem/shmem.rs b/rust/kernel/drm/gem/shmem.rs
> index bfbf2bb25eac1..d4afc06d1be50 100644
> --- a/rust/kernel/drm/gem/shmem.rs
> +++ b/rust/kernel/drm/gem/shmem.rs

[ ... ]

> +/// A reference to a virtual mapping for an shmem-based GEM object in kernel address space.
> +///
> +/// # Invariants
> +///
> +/// - The size of `owner` is >= SIZE.
> +/// - The memory pointed to by `addr` remains valid at least until this object is dropped.
> +pub struct VMap<D, R, C = Registered, const SIZE: usize = 0>
> +where
> +    D: DriverObject,
> +    C: DeviceContext,
> +    R: Deref<Target = Object<D, C>>,
> +{
> +    addr: *mut c_void,
> +    owner: R,
> +}

[Severity: Low]
Does this struct compile successfully?

The generic type parameters D and C are used in the where clause but not in
any fields. Would this trigger a compiler error (E0392) requiring a
PhantomData field to compute variance?

[ ... ]

> +// SAFETY: VMaps are safe to send across threads.
> +unsafe impl<D, R, C, const SIZE: usize> Send for VMap<D, R, C, SIZE>
> +where
> +    D: DriverObject,
> +    C: DeviceContext,
> +    R: Deref<Target = Object<D, C>>,
> +{
> +}
> +
> +// SAFETY: VMaps are safe to access from multiple threads.
> +unsafe impl<D, R, C, const SIZE: usize> Sync for VMap<D, R, C, SIZE>
> +where
> +    D: DriverObject,
> +    C: DeviceContext,
> +    R: Deref<Target = Object<D, C>>,
> +{
> +}

[Severity: High]
Are these unconditional Send and Sync implementations sound?

If a caller provides a custom type for R that implements Deref but is !Send
or !Sync (such as a type using non-atomic reference counting), VMap would
still be allowed across threads. When the VMap is dropped on another thread,
the !Send R would be dropped there, resulting in a data race.

Should these implementations require explicit Send and Sync bounds on R?

[ ... ]

> +macro_rules! impl_vmap_io_capable {
> +    ($ty:ty) => {
> +        impl<D, R, C, const SIZE: usize> IoCapable<$ty> for VMap<D, R, C, SIZE>
> +        where
> +            D: DriverObject,
> +            C: DeviceContext,
> +            R: Deref<Target = Object<D, C>>,
> +        {
> +            #[inline]
> +            unsafe fn io_read(&self, address: usize) -> $ty {
> +                let ptr = address as *mut $ty;
> +
> +                // SAFETY: The safety contract of `io_read` guarantees that address is a valid
> +                // address within the bounds of `Self` of at least the size of $ty, and is properly
> +                // aligned.
> +                unsafe { ptr::read_volatile(ptr) }
> +            }
> +
> +            #[inline]
> +            unsafe fn io_write(&self, value: $ty, address: usize) {
> +                let ptr = address as *mut $ty;
> +
> +                // SAFETY: The safety contract of `io_write` guarantees that address is a valid
> +                // address within the bounds of `Self` of at least the size of $ty, and is properly
> +                // aligned.
> +                unsafe { ptr::write_volatile(ptr, value) }
> +            }
> +        }
> +    };
> +}

[Severity: High]
Can this result in a data race?

Since VMap implements the Sync trait, shared references (&VMap) can be safely
sent to multiple threads. This IoCapable implementation powers safe Io trait
accessors (like write8) using ptr::write_volatile, which is not atomic.

According to the Rust memory model, concurrent volatile writes from multiple
threads to the same memory location constitute a data race. Should this
synchronize access to avoid undefined behavior?

[ ... ]

> +    #[test]
> +    fn vmap_io() -> Result {
> +        let (_dev, drm) = create_drm_dev()?;
> +
> +        let obj = Object::<KunitObject, _>::new(&drm, PAGE_SIZE, ObjectConfig::default(), ())?;
> +
> +        let vmap = obj.vmap::<PAGE_SIZE>()?;
> +
> +        vmap.write8(0xDE, 0x0);
> +        assert_eq!(vmap.read8(0x0), 0xDE);
> +        vmap.write32(0xFEDCBA98, 0x20);
> +
> +        assert_eq!(vmap.read32(0x20), 0xFEDCBA98);
> +
> +        // Ensure the ordering in memory is correct
> +        let offsets = (0x20..0x23).into_iter();
> +        let expected = 0xFEDCBA98_u32.to_ne_bytes().into_iter();
> +        for (offset, expected) in offsets.zip(expected) {
> +            assert_eq!(vmap.read8(offset), expected);
> +        }
> +
> +        Ok(())
> +    }
> +}

[Severity: Medium]
Does this loop skip the 4th byte verification?

The offsets iterator (0x20..0x23) produces exactly 3 elements (0x20, 0x21,
and 0x22). Because zip stops when the shortest iterator is exhausted, it
appears the 4th byte at offset 0x23 is silently skipped and never verified.

Should this be (0x20..=0x23) or (0x20..0x24) instead?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260610162433.923550-1-lyude@redhat.com?part=2

  reply	other threads:[~2026-06-10 16:39 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-10 16:21 [PATCH v20 0/4] Rust bindings for gem shmem Lyude Paul
2026-06-10 16:21 ` Lyude Paul
2026-06-10 16:21 ` [PATCH v20 1/4] rust: drm: gem: shmem: Add DmaResvGuard helper Lyude Paul
2026-06-10 16:21   ` Lyude Paul
2026-06-10 16:21 ` [PATCH v20 2/4] rust: drm: gem: shmem: Add vmap functions Lyude Paul
2026-06-10 16:21   ` Lyude Paul
2026-06-10 16:39   ` sashiko-bot [this message]
2026-06-10 16:21 ` [PATCH v20 3/4] rust: faux: Allow retrieving a bound Device Lyude Paul
2026-06-10 16:21   ` Lyude Paul
2026-06-10 16:37   ` sashiko-bot
2026-06-10 16:21 ` [PATCH v20 4/4] rust: drm: gem: Introduce shmem::Object::sg_table() Lyude Paul
2026-06-10 16:21   ` Lyude Paul
2026-06-10 16:46   ` sashiko-bot

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=20260610163946.4120B1F00893@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=lyude@redhat.com \
    --cc=ojeda@kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /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.