Skip to content
Snippets Groups Projects
  1. Jul 04, 2024
  2. Jul 03, 2024
  3. Jul 02, 2024
    • Lyude Paul's avatar
      drm/panic: Fix uninitialized spinlock acquisition with CONFIG_DRM_PANIC=n · 0e8d8c38
      Lyude Paul authored
      
      It turns out that if you happen to have a kernel config where
      CONFIG_DRM_PANIC is disabled and spinlock debugging is enabled, along with
      KMS being enabled - we'll end up trying to acquire an uninitialized
      spin_lock with drm_panic_lock() when we try to do a commit:
      
        rvkms rvkms.0: [drm:drm_atomic_commit] committing 0000000068d2ade1
        INFO: trying to register non-static key.
        The code is fine but needs lockdep annotation, or maybe
        you didn't initialize this object before use?
        turning off the locking correctness validator.
        CPU: 4 PID: 1347 Comm: modprobe Not tainted 6.10.0-rc1Lyude-Test+ #272
        Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS edk2-20240524-3.fc40 05/24/2024
        Call Trace:
         <TASK>
         dump_stack_lvl+0x77/0xa0
         assign_lock_key+0x114/0x120
         register_lock_class+0xa8/0x2c0
         __lock_acquire+0x7d/0x2bd0
         ? __vmap_pages_range_noflush+0x3a8/0x550
         ? drm_atomic_helper_swap_state+0x2ad/0x3a0
         lock_acquire+0xec/0x290
         ? drm_atomic_helper_swap_state+0x2ad/0x3a0
         ? lock_release+0xee/0x310
         _raw_spin_lock_irqsave+0x4e/0x70
         ? drm_atomic_helper_swap_state+0x2ad/0x3a0
         drm_atomic_helper_swap_state+0x2ad/0x3a0
         drm_atomic_helper_commit+0xb1/0x270
         drm_atomic_commit+0xaf/0xe0
         ? __pfx___drm_printfn_info+0x10/0x10
         drm_client_modeset_commit_atomic+0x1a1/0x250
         drm_client_modeset_commit_locked+0x4b/0x180
         drm_client_modeset_commit+0x27/0x50
         __drm_fb_helper_restore_fbdev_mode_unlocked+0x76/0x90
         drm_fb_helper_set_par+0x38/0x40
         fbcon_init+0x3c4/0x690
         visual_init+0xc0/0x120
         do_bind_con_driver+0x409/0x4c0
         do_take_over_console+0x233/0x280
         do_fb_registered+0x11f/0x210
         fbcon_fb_registered+0x2c/0x60
         register_framebuffer+0x248/0x2a0
         __drm_fb_helper_initial_config_and_unlock+0x58a/0x720
         drm_fbdev_generic_client_hotplug+0x6e/0xb0
         drm_client_register+0x76/0xc0
         _RNvXs_CsHeezP08sTT_5rvkmsNtB4_5RvkmsNtNtCs1cdwasc6FUb_6kernel8platform6Driver5probe+0xed2/0x1060 [rvkms]
         ? _RNvMs_NtCs1cdwasc6FUb_6kernel8platformINtB4_7AdapterNtCsHeezP08sTT_5rvkms5RvkmsE14probe_callbackBQ_+0x2b/0x70 [rvkms]
         ? acpi_dev_pm_attach+0x25/0x110
         ? platform_probe+0x6a/0xa0
         ? really_probe+0x10b/0x400
         ? __driver_probe_device+0x7c/0x140
         ? driver_probe_device+0x22/0x1b0
         ? __device_attach_driver+0x13a/0x1c0
         ? __pfx___device_attach_driver+0x10/0x10
         ? bus_for_each_drv+0x114/0x170
         ? __device_attach+0xd6/0x1b0
         ? bus_probe_device+0x9e/0x120
         ? device_add+0x288/0x4b0
         ? platform_device_add+0x75/0x230
         ? platform_device_register_full+0x141/0x180
         ? rust_helper_platform_device_register_simple+0x85/0xb0
         ? _RNvMs2_NtCs1cdwasc6FUb_6kernel8platformNtB5_6Device13create_simple+0x1d/0x60
         ? _RNvXs0_CsHeezP08sTT_5rvkmsNtB5_5RvkmsNtCs1cdwasc6FUb_6kernel6Module4init+0x11e/0x160 [rvkms]
         ? 0xffffffffc083f000
         ? init_module+0x20/0x1000 [rvkms]
         ? kernfs_xattr_get+0x3e/0x80
         ? do_one_initcall+0x148/0x3f0
         ? __lock_acquire+0x5ef/0x2bd0
         ? __lock_acquire+0x5ef/0x2bd0
         ? __lock_acquire+0x5ef/0x2bd0
         ? put_cpu_partial+0x51/0x1d0
         ? lock_acquire+0xec/0x290
         ? put_cpu_partial+0x51/0x1d0
         ? lock_release+0xee/0x310
         ? put_cpu_partial+0x51/0x1d0
         ? fs_reclaim_acquire+0x69/0xf0
         ? lock_acquire+0xec/0x290
         ? fs_reclaim_acquire+0x69/0xf0
         ? kfree+0x22f/0x340
         ? lock_release+0xee/0x310
         ? kmalloc_trace_noprof+0x48/0x340
         ? do_init_module+0x22/0x240
         ? kmalloc_trace_noprof+0x155/0x340
         ? do_init_module+0x60/0x240
         ? __se_sys_finit_module+0x2e0/0x3f0
         ? do_syscall_64+0xa4/0x180
         ? syscall_exit_to_user_mode+0x108/0x140
         ? do_syscall_64+0xb0/0x180
         ? vma_end_read+0xd0/0xe0
         ? do_user_addr_fault+0x309/0x640
         ? clear_bhb_loop+0x45/0xa0
         ? clear_bhb_loop+0x45/0xa0
         ? clear_bhb_loop+0x45/0xa0
         ? entry_SYSCALL_64_after_hwframe+0x76/0x7e
         </TASK>
      
      Fix this by stubbing these macros out when this config option isn't
      enabled, along with fixing the unused variable warning that introduces.
      
      Signed-off-by: Lyude Paul's avatarLyude Paul <lyude@redhat.com>
      0e8d8c38
    • Lyude Paul's avatar
      WIP SPLIT ME: Update our CRTC bindings for DRM's true drm_crtc_state data model · 73dbe7e6
      Lyude Paul authored
      Sima pointed out that drm_crtc_state violates some of the guarantees that
      other atomic states have, in that the structure can be mutated even after
      being swapped in. As a result, we need to update our bindings to not assume
      that this structure follows rust's data aliasing rules like the rest of the
      KMS atomic states.
      73dbe7e6
    • Lyude Paul's avatar
    • Lyude Paul's avatar
      drm: Introduce RVKMS! · 9b11cf71
      Lyude Paul authored
      
      Now that we've added all of the bits that we need for the KMS API, it's
      time to Bring The Beef and introduce RVKMS!
      
      TODO: write something more here I guess?
      
      Signed-off-by: Lyude Paul's avatarLyude Paul <lyude@redhat.com>
      9b11cf71
    • Lyude Paul's avatar
      rust: Add device::Device::name() · 25102dc7
      Lyude Paul authored
      
      Just a simple binding for retrieving the name of the device through
      dev_name().
      
      Signed-off-by: Lyude Paul's avatarLyude Paul <lyude@redhat.com>
      25102dc7
    • Lyude Paul's avatar
      WIP: Add simple registration of platform devices · 63078f17
      Lyude Paul authored
      TODO:
      * The idea for this came from Maíra originally, and they should probably be
        the commit author (we'll fix that before final submission because credit
        is important :3, right now it's just a bit easier to rewrite the commit)
      63078f17
    • Lyude Paul's avatar
      rust/drm/kms: Add RawPlaneState::rotation() · c8783cc0
      Lyude Paul authored
      
      A binding for retrieving the current rotation of a DRM plane state.
      
      Signed-off-by: Lyude Paul's avatarLyude Paul <lyude@redhat.com>
      c8783cc0
    • Lyude Paul's avatar
      rust/drm/kms: Add simplify_rotation() binding · ee655259
      Lyude Paul authored
      
      Just a binding for drm_simplify_rotation(). We add this in a new module
      blend.rs in order to match the layout of the C side of things.
      
      Signed-off-by: Lyude Paul's avatarLyude Paul <lyude@redhat.com>
      ee655259
    • Lyude Paul's avatar
      rust/drm/kms: Add aliases for ROTATE_* and REFLECT_* · ca3783a9
      Lyude Paul authored
      
      Just add some short-hand aliases to the raw bindings, since that's
      basically all we need. We put this in a new mode.rs module to match the
      layout of the C side of KMS.
      
      Signed-off-by: Lyude Paul's avatarLyude Paul <lyude@redhat.com>
      ca3783a9
    • Lyude Paul's avatar
      rust/drm/kms: Add RawPlaneState::src() and dst() · 655c48b3
      Lyude Paul authored
      
      Bindings for returning the src and dst rectangles for an atomic plane
      state.
      
      Signed-off-by: Lyude Paul's avatarLyude Paul <lyude@redhat.com>
      655c48b3
    • Lyude Paul's avatar
      rust/drm/kms: Add KmsDriver::mode_config_reset() · 5940dc6b
      Lyude Paul authored
      
      This is just a binding around drm_mode_config_reset(), which should be
      called during initialization of a modesetting driver if it doesn't
      read-back hardware state.
      
      Signed-off-by: Lyude Paul's avatarLyude Paul <lyude@redhat.com>
      5940dc6b
    • Lyude Paul's avatar
      WIP: rust/drm/kms: Add ShadowPlaneState<T> · d5b7d4fb
      Lyude Paul authored
      
      Since RVKMS uses drm_shadow_plane_state instead of the normal
      drm_plane_state, let's add bindings to allow drivers to use this using the
      PlaneStateHelper trait that we introduced before.
      
      Of course, all of the normal methods available to DRM planes are also
      available on shadow planes through the use of AsRawPlaneState and friends.
      
      Signed-off-by: Lyude Paul's avatarLyude Paul <lyude@redhat.com>
      
      TODO:
      * Make sure that documentation is consistent and finished
      d5b7d4fb
    • Lyude Paul's avatar
      WIP: rust/drm/kms: Add DriverPlane::prepare_fb() and cleanup_fb() · 791203c0
      Lyude Paul authored
      
      Add optional trait methods for DRM's prepare_fb() and cleanup_fb()
      callbacks now that we have proper Framebuffer bindings. As well, introduce
      a new PlaneState mutator: PlaneStateMutator. The purpose of this mutator
      type is for callbacks where we want the implementor to be able to modify
      the atomic plane state, without providing access to the rest of the atomic
      state.
      
      TODO:
      * Write documentation
      
      Signed-off-by: Lyude Paul's avatarLyude Paul <lyude@redhat.com>
      791203c0
    • Lyude Paul's avatar
      rust/drm/kms: Add RawPlane::framebuffer() · 6ecb031f
      Lyude Paul authored
      
      Returns the Framebuffer currently assigned in an atomic plane state.
      
      Signed-off-by: Lyude Paul's avatarLyude Paul <lyude@redhat.com>
      6ecb031f
    • Lyude Paul's avatar
      WIP: rust/drm/kms: Add basic framebuffer bindings · 10cc2476
      Lyude Paul authored
      
      We're about to add some FB related callbacks to planes now, so let's
      introduce our bindings for Framebuffer objects. Just like Connectors, these
      use RcModeObject.
      
      Signed-off-by: Lyude Paul's avatarLyude Paul <lyude@redhat.com>
      10cc2476
    • Lyude Paul's avatar
      WIP: rust/drm/kms: Add DriverPlane::atomic_update() · eb1585a9
      Lyude Paul authored
      A mandatory trait method used for implementing DRM's atomic plane update
      callback. This is currently only mandatory because with our current
      bindings, DRM will crash without this.
      
      TODO: See if we can fix that and make it only mandatory in certain
      situations.
      eb1585a9
    • Lyude Paul's avatar
      WIP: rust/kms/drm: Add RawPlaneState::atomic_helper_check() · d12220fb
      Lyude Paul authored
      
      Add a binding for DRM's plane state atomic check helper.
      
      TODO:
      * Finish up documentation (we need to document parameters too! I think?)
      
      Signed-off-by: Lyude Paul's avatarLyude Paul <lyude@redhat.com>
      d12220fb
    • Lyude Paul's avatar
      rust/drm/kms: Add RawPlaneState::crtc() · 22c1e4e1
      Lyude Paul authored
      
      Add a binding for retrieving an opaque reference to the CRTC currently set
      for an atomic plane state.
      
      Signed-off-by: Lyude Paul's avatarLyude Paul <lyude@redhat.com>
      22c1e4e1
    • Lyude Paul's avatar
      WIP: rust/drm/kms: Add DriverPlane::atomic_check() · 13371e23
      Lyude Paul authored
      
      Optional trait method for implementing a plane's atomic_check().
      
      TODO:
      * Documentation
      * Figure out if we can make this non-mandatory?
      
      Signed-off-by: Lyude Paul's avatarLyude Paul <lyude@redhat.com>
      13371e23
    • Lyude Paul's avatar
      WIP: rust/drm/kms: Introduce DriverCrtc::atomic_check() · 305bec18
      Lyude Paul authored
      
      An optional trait method for implementing a CRTC's atomic state check.
      
      TODO: Write documentation
      
      Signed-off-by: Lyude Paul's avatarLyude Paul <lyude@redhat.com>
      305bec18
    • Lyude Paul's avatar
      WIP: rust/drm/kms: Add atomic state bindings · fdeef1b1
      Lyude Paul authored
      
      Next up is introducing bindings that we can use to represent the global DRM
      atomic state, along with all of the various object states contained within.
      We do this by introducing a few new concepts: borrowed states, atomic state
      mutators, and atomic state composers.
      
      To understand these, we need to quickly touch upon the general life of an
      atomic commit. Assuming a driver does its own internal atomic commit, the
      procedure looks something like this:
      
      * Allocate a new atomic state
      * Duplicate the atomic state of each mode object we want to mutate, and add
        the duplicated state to the new atomic state
      * Check (possibly more then once) the atomic state, possibly modifying it
        along the way
      * Commit the atomic state to software (we'll call this commit time). At
        this point no new objects can be added to the state
      * Finish committing the atomic state to hardware asynchronously
      
      With this in mind, we introduce AtomicStateMutator and AtomicStateComposer
      (along with leaky variants intended for uses in FFI calls). An
      AtomicStateMutator allows mutating an atomic state but does not allow for
      adding new objects to the state. Subsequently, an AtomicStateComposer
      allows for both mutating an atomic state and adding new mode objects. We
      control when we expose each of these types in order to implement the
      limitations required by the aforementioned example.
      
      Note as well that AtomicStateComposer is intended to eventually be usable
      directly by drivers. In this scenario, a driver will be able to create an
      AtomicStateComposer (the equivalent of allocating an atomic state in C) and
      then commit it by passing it to our DRM bindings by-value, insuring that
      once the commit process begins it is impossible to keep using the
      AtomicStateComposer.
      
      The next part of this is allowing users to modify the atomic states of all
      of the objects contained within an atomic state. Since it's an extremely
      common usecase for objects to mutate the atomic state of multiple objects
      at once in an unpredictable order, we need a mechanism that will allow us
      to hand out &mut references to each state while ensuring at runtime that we
      do not break rust's data aliasing rules (which disallow us from ever having
      more then one &mut reference to the same piece of data).
      
      We do this by introducing the concept of a "borrowed" state. This is a very
      similar concept to RefCell, where it is ensured during runtime that when a
      &mut reference is taken out another one cannot be created until the
      corresponding Ref object has been dropped. Our equivalent Ref types are
      BorrowedConnectorState, BorrowedCrtcState, and BorrowedPlaneState.
      
      Each one of these types can be used in the same manner as a Ref - no
      additional borrows for an atomic state may be taken until the existing one
      has been dropped. Subsequently, all of these types implement their
      respective AsRaw* and FromRaw* counter-parts - and allow dereferencing to
      each driver-private data structure for fully qualified borrows (like
      BorrowedCrtcState<'a, CrtcState<T>>. This allows a pretty clean way of
      mutating multiple states at once without ever breaking rust's mutability
      rules.
      
      We'll use all of these types over the next few commits to begin introducing
      various atomic modeset callbacks to each mode object type.
      
      Signed-off-by: Lyude Paul's avatarLyude Paul <lyude@redhat.com>
      
      TODO:
      * Make sure we have documentation everywhere
      * Make sure that we also eventually add upcasting capabilities to borrowed
        types
      fdeef1b1
    • Lyude Paul's avatar
      rust/drm/kms: Introduce OpaqueEncoder · cd3bec30
      Lyude Paul authored
      
      Same thing as OpaquePlane, but for encoders now.
      
      Signed-off-by: Lyude Paul's avatarLyude Paul <lyude@redhat.com>
      cd3bec30
    • Lyude Paul's avatar
      WIP: rust/drm/kms: Add RawPlane and RawPlaneState · fb8198be
      Lyude Paul authored
      Same thing as RawCrtc and RawCrtcState, but for DRM planes now
      fb8198be
    • Lyude Paul's avatar
      WIP: rust/drm/kms: Add RawCrtc and RawCrtcState · 15af38a3
      Lyude Paul authored
      
      Same thing as RawConnector and RawConnectorState, just for CRTCs now.
      
      TODO:
      * Complete documentation
      
      Signed-off-by: Lyude Paul's avatarLyude Paul <lyude@redhat.com>
      15af38a3
    • Lyude Paul's avatar
      WIP: rust/drm/kms: Add RawConnector and RawConnectorState · 481e8d98
      Lyude Paul authored
      
      Now that we have more then one way to refer to connectors, we also want to
      ensure that any methods which are common to any kind of connector type can
      be used on all connector representations. This is where RawConnector and
      RawConnectorState come in: we implement these traits for any type which
      implements AsRawConnector or AsRawConnectorState respectively.
      
      TODO:
      * Documentation
      
      Signed-off-by: Lyude Paul's avatarLyude Paul <lyude@redhat.com>
      481e8d98
    • Lyude Paul's avatar
      WIP: rust/drm/kms: Add OpaquePlane and OpaquePlaneState · 94a4d4f1
      Lyude Paul authored
      
      Same thing as OpaqueCrtc and OpaqueCrtcState, but for plane states now.
      
      TODO:
      * Make sure that we have conversion functions to go back and forth from the
        Opaque versions and non-opaque versions. Currently we only have this for
        upcasting from OpaquePlane
      
      Signed-off-by: Lyude Paul's avatarLyude Paul <lyude@redhat.com>
      94a4d4f1
    • Lyude Paul's avatar
      WIP: rust/drm/kms: Add OpaqueCrtc and OpaqueCrtcState · 888ea997
      Lyude Paul authored
      
      This is the same thing as OpaqueConnector and OpaqueConnectorState, but for
      CRTCs now.
      
      TODO:
      * Add some of the missing functions we currently mention in documentation,
        mainly from_opaque()
      
      Signed-off-by: Lyude Paul's avatarLyude Paul <lyude@redhat.com>
      888ea997
    • Lyude Paul's avatar
      rust/drm/kms: Add OpaqueConnector and OpaqueConnectorState · e1fd75a5
      Lyude Paul authored
      
      Since we allow drivers to have multiple implementations of DriverConnector
      and DriverConnectorState (in C, the equivalent of this is having multiple
      structs which embed drm_connector) - there are some situations we will run
      into where it's not possible for us to know the corresponding
      DriverConnector or DriverConnectorState for a given connector. The most
      obvious one is iterating through all connectors on a KMS device.
      
      So, take advantage of the various connector traits we added to introduce
      OpaqueConnector<> and OpaqueConnectorState<> which both can be used as a
      DRM connector and connector state respectively without needing to know the
      corresponding traits.
      
      Signed-off-by: Lyude Paul's avatarLyude Paul <lyude@redhat.com>
      e1fd75a5
    • Lyude Paul's avatar
      WIP: rust/kernel/drm: Add ConnectorGuard::set_preferred_mode · 2109da3b
      Lyude Paul authored
      
      Add a wrapper for `drm_set_preferred_mode()` for our new
      `ConnectorGuard` type so we can set the preferred mode for RVKMS
      connectors.
      
      Signed-off-by: Lyude Paul's avatarLyude Paul <lyude@redhat.com>
      2109da3b
    • Lyude Paul's avatar
      rust/drm/kms: Add ModeConfigGuard and ConnectorGuard types · 09cfffc9
      Lyude Paul authored
      
      Next up is filling out some of the basic connector hotplugging callbacks -
      which we'll need for setting up the fbdev helpers for KMS devices. Note
      that connector hotplugging in DRM follows a BFL scheme: pretty much all
      probing is protected under the mighty drm_device->mode_config.lock, which
      of course is a bit counter-intuitive to rust's locking schemes where data
      is always associated with its lock.
      
      Since that lock is embedded in an FFI type and not a rust type, we need to
      introduce our own wrapper type that acts as a lock acquisition for this.
      This brings us to introducing a few new types:
      
      * ModeConfigGuard - the most basic lock guard, as long as this object is
        alive we are guaranteed to be holding drm_device->mode_config.lock. This
        object doesn't do much else on its own currently.
      * UnsafeModeConfigGuard - exactly the same as ModeConfigGuard, but does not
        lock or unlock drm_device->mode_config.lock on its own and relies on the
        caller to do it. This is only useful for FFI callbacks, and can be used
        as a ModeConfigGuard through it's Deref implementation
      * ConnectorGuard - an object which corresponds to a specific typed DRM
        connector. This can only be acquired with a ModeConfigGuard, and will be
        used to allow calling methods that are only safe to call with
        drm_device->mode_config.lock held. Since it implements
        Deref<Target=Connector<T>> as well, it can also be used for any other
        operations that would normally be available on a DRM connector.
      
      And finally, we add the DriverConnector::get_modes() trait method which
      drivers can use to implement the drm_connector_helper_funcs.get_modes
      callback. Note that while we make this trait method mandatory, we only do
      so for the time being since VKMS doesn't do very much with DRM connectors -
      and as such we have no need yet to implement alternative connector probing
      schemes outside of get_modes().
      
      Signed-off-by: Lyude Paul's avatarLyude Paul <lyude@redhat.com>
      09cfffc9
    • Lyude Paul's avatar
      rust/drm/kms/connector: Add .attach_encoder() · f92c9cac
      Lyude Paul authored
      
      This adds a simple binding for completing the last step of creating a DRM
      connector - attaching its encoder. This function should only be called
      before the connector is registered, and DRM should enforce this itself by
      returning an error if a driver tries to add an encoder to an
      already-registered DRM connector.
      
      Note that unlike most of the methods we'll be adding to DRM mode objects,
      this is directly implemented on the Connector<T> type since I don't really
      think it would make sense for us to allow this operation on an
      OpaqueConnector (a DRM connector without a known DriverConnector
      implementation, something we'll be adding in the next few commits).
      
      Signed-off-by: Lyude Paul's avatarLyude Paul <lyude@redhat.com>
      f92c9cac
    • Lyude Paul's avatar
      WIP: rust/drm: Add super basic fourcc bindings · 3757873e
      Lyude Paul authored
      While we don't have proper bindings for specifying more then literally one
      fourcc format, this is just enough to get us by for the time being.
      
      TODO:
      * Better commit message
      * Come up with some way of automating this, there's a heck of a lot of
        fourcc formats and I think trying to manually add bindings for each one
        is a bad idea
      * Documentation
      3757873e
Loading