Merge tag 'driver-core-6.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 1 Apr 2025 18:02:03 +0000 (11:02 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 1 Apr 2025 18:02:03 +0000 (11:02 -0700)
Pull driver core updatesk from Greg KH:
 "Here is the big set of driver core updates for 6.15-rc1. Lots of stuff
  happened this development cycle, including:

   - kernfs scaling changes to make it even faster thanks to rcu

   - bin_attribute constify work in many subsystems

   - faux bus minor tweaks for the rust bindings

   - rust binding updates for driver core, pci, and platform busses,
     making more functionaliy available to rust drivers. These are all
     due to people actually trying to use the bindings that were in
     6.14.

   - make Rafael and Danilo full co-maintainers of the driver core
     codebase

   - other minor fixes and updates"

* tag 'driver-core-6.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core: (52 commits)
  rust: platform: require Send for Driver trait implementers
  rust: pci: require Send for Driver trait implementers
  rust: platform: impl Send + Sync for platform::Device
  rust: pci: impl Send + Sync for pci::Device
  rust: platform: fix unrestricted &mut platform::Device
  rust: pci: fix unrestricted &mut pci::Device
  rust: device: implement device context marker
  rust: pci: use to_result() in enable_device_mem()
  MAINTAINERS: driver core: mark Rafael and Danilo as co-maintainers
  rust/kernel/faux: mark Registration methods inline
  driver core: faux: only create the device if probe() succeeds
  rust/faux: Add missing parent argument to Registration::new()
  rust/faux: Drop #[repr(transparent)] from faux::Registration
  rust: io: fix devres test with new io accessor functions
  rust: io: rename `io::Io` accessors
  kernfs: Move dput() outside of the RCU section.
  efi: rci2: mark bin_attribute as __ro_after_init
  rapidio: constify 'struct bin_attribute'
  firmware: qemu_fw_cfg: constify 'struct bin_attribute'
  powerpc/perf/hv-24x7: Constify 'struct bin_attribute'
  ...

24 files changed:
1  2 
MAINTAINERS
arch/powerpc/platforms/powernv/opal-core.c
arch/x86/kernel/cpu/resctrl/internal.h
arch/x86/kernel/cpu/resctrl/pseudo_lock.c
arch/x86/kernel/cpu/resctrl/rdtgroup.c
drivers/base/component.c
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c
drivers/gpu/nova-core/driver.rs
drivers/gpu/nova-core/regs.rs
drivers/input/touchscreen/goodix_berlin_core.c
fs/kernfs/dir.c
include/linux/device.h
kernel/cgroup/cgroup-v1.c
kernel/cgroup/cgroup.c
rust/kernel/pci.rs
rust/kernel/platform.rs
samples/rust/rust_dma.rs
samples/rust/rust_driver_faux.rs
samples/rust/rust_driver_pci.rs
samples/rust/rust_driver_platform.rs
security/selinux/hooks.c

diff --cc MAINTAINERS
Simple merge
@@@ -401,8 -500,18 +401,13 @@@ static inline struct rdt_hw_resource *r
        return container_of(r, struct rdt_hw_resource, r_resctrl);
  }
  
 -int parse_cbm(struct rdt_parse_data *data, struct resctrl_schema *s,
 -            struct rdt_ctrl_domain *d);
 -int parse_bw(struct rdt_parse_data *data, struct resctrl_schema *s,
 -           struct rdt_ctrl_domain *d);
 -
  extern struct mutex rdtgroup_mutex;
  
+ static inline const char *rdt_kn_name(const struct kernfs_node *kn)
+ {
+       return rcu_dereference_check(kn->name, lockdep_is_held(&rdtgroup_mutex));
+ }
  extern struct rdt_hw_resource rdt_resources_all[];
  extern struct rdtgroup rdtgroup_default;
  extern struct dentry *debugfs_resctrl;
@@@ -996,10 -978,10 +1006,10 @@@ static int rdt_num_closids_show(struct 
  static int rdt_default_ctrl_show(struct kernfs_open_file *of,
                             struct seq_file *seq, void *v)
  {
-       struct resctrl_schema *s = of->kn->parent->priv;
+       struct resctrl_schema *s = rdt_kn_parent_priv(of->kn);
        struct rdt_resource *r = s->res;
  
 -      seq_printf(seq, "%x\n", r->default_ctrl);
 +      seq_printf(seq, "%x\n", resctrl_get_default_ctrl(r));
        return 0;
  }
  
@@@ -1185,22 -1167,13 +1195,22 @@@ static int max_threshold_occ_show(struc
  static int rdt_thread_throttle_mode_show(struct kernfs_open_file *of,
                                         struct seq_file *seq, void *v)
  {
-       struct resctrl_schema *s = of->kn->parent->priv;
+       struct resctrl_schema *s = rdt_kn_parent_priv(of->kn);
        struct rdt_resource *r = s->res;
  
 -      if (r->membw.throttle_mode == THREAD_THROTTLE_PER_THREAD)
 +      switch (r->membw.throttle_mode) {
 +      case THREAD_THROTTLE_PER_THREAD:
                seq_puts(seq, "per-thread\n");
 -      else
 +              return 0;
 +      case THREAD_THROTTLE_MAX:
                seq_puts(seq, "max\n");
 +              return 0;
 +      case THREAD_THROTTLE_UNDEFINED:
 +              seq_puts(seq, "undefined\n");
 +              return 0;
 +      }
 +
 +      WARN_ON_ONCE(1);
  
        return 0;
  }
Simple merge
@@@ -227,26 -224,8 +227,26 @@@ static ssize_t amdgpu_device_get_pcie_r
  static DEVICE_ATTR(pcie_replay_count, 0444,
                amdgpu_device_get_pcie_replay_count, NULL);
  
 +static int amdgpu_device_attr_sysfs_init(struct amdgpu_device *adev)
 +{
 +      int ret = 0;
 +
 +      if (!amdgpu_sriov_vf(adev))
 +              ret = sysfs_create_file(&adev->dev->kobj,
 +                                      &dev_attr_pcie_replay_count.attr);
 +
 +      return ret;
 +}
 +
 +static void amdgpu_device_attr_sysfs_fini(struct amdgpu_device *adev)
 +{
 +      if (!amdgpu_sriov_vf(adev))
 +              sysfs_remove_file(&adev->dev->kobj,
 +                                &dev_attr_pcie_replay_count.attr);
 +}
 +
  static ssize_t amdgpu_sysfs_reg_state_get(struct file *f, struct kobject *kobj,
-                                         struct bin_attribute *attr, char *buf,
+                                         const struct bin_attribute *attr, char *buf,
                                          loff_t ppos, size_t count)
  {
        struct device *dev = kobj_to_dev(kobj);
index 63c19f1,0000000..a08fb65
mode 100644,000000..100644
--- /dev/null
@@@ -1,47 -1,0 +1,47 @@@
- use kernel::{bindings, c_str, pci, prelude::*};
 +// SPDX-License-Identifier: GPL-2.0
 +
-     fn probe(pdev: &mut pci::Device, _info: &Self::IdInfo) -> Result<Pin<KBox<Self>>> {
++use kernel::{bindings, c_str, device::Core, pci, prelude::*};
 +
 +use crate::gpu::Gpu;
 +
 +#[pin_data]
 +pub(crate) struct NovaCore {
 +    #[pin]
 +    pub(crate) gpu: Gpu,
 +}
 +
 +const BAR0_SIZE: usize = 8;
 +pub(crate) type Bar0 = pci::Bar<BAR0_SIZE>;
 +
 +kernel::pci_device_table!(
 +    PCI_TABLE,
 +    MODULE_PCI_TABLE,
 +    <NovaCore as pci::Driver>::IdInfo,
 +    [(
 +        pci::DeviceId::from_id(bindings::PCI_VENDOR_ID_NVIDIA, bindings::PCI_ANY_ID as _),
 +        ()
 +    )]
 +);
 +
 +impl pci::Driver for NovaCore {
 +    type IdInfo = ();
 +    const ID_TABLE: pci::IdTable<Self::IdInfo> = &PCI_TABLE;
 +
++    fn probe(pdev: &pci::Device<Core>, _info: &Self::IdInfo) -> Result<Pin<KBox<Self>>> {
 +        dev_dbg!(pdev.as_ref(), "Probe Nova Core GPU driver.\n");
 +
 +        pdev.enable_device_mem()?;
 +        pdev.set_master();
 +
 +        let bar = pdev.iomap_region_sized::<BAR0_SIZE>(0, c_str!("nova-core/bar0"))?;
 +
 +        let this = KBox::pin_init(
 +            try_pin_init!(Self {
 +                gpu <- Gpu::new(pdev, bar)?,
 +            }),
 +            GFP_KERNEL,
 +        )?;
 +
 +        Ok(this)
 +    }
 +}
index 50aefb1,0000000..b1a25b8
mode 100644,000000..100644
--- /dev/null
@@@ -1,55 -1,0 +1,55 @@@
-         Self(bar.readl(BOOT0_OFFSET))
 +// SPDX-License-Identifier: GPL-2.0
 +
 +use crate::driver::Bar0;
 +
 +// TODO
 +//
 +// Create register definitions via generic macros. See task "Generic register
 +// abstraction" in Documentation/gpu/nova/core/todo.rst.
 +
 +const BOOT0_OFFSET: usize = 0x00000000;
 +
 +// 3:0 - chipset minor revision
 +const BOOT0_MINOR_REV_SHIFT: u8 = 0;
 +const BOOT0_MINOR_REV_MASK: u32 = 0x0000000f;
 +
 +// 7:4 - chipset major revision
 +const BOOT0_MAJOR_REV_SHIFT: u8 = 4;
 +const BOOT0_MAJOR_REV_MASK: u32 = 0x000000f0;
 +
 +// 23:20 - chipset implementation Identifier (depends on architecture)
 +const BOOT0_IMPL_SHIFT: u8 = 20;
 +const BOOT0_IMPL_MASK: u32 = 0x00f00000;
 +
 +// 28:24 - chipset architecture identifier
 +const BOOT0_ARCH_MASK: u32 = 0x1f000000;
 +
 +// 28:20 - chipset identifier (virtual register field combining BOOT0_IMPL and
 +//         BOOT0_ARCH)
 +const BOOT0_CHIPSET_SHIFT: u8 = BOOT0_IMPL_SHIFT;
 +const BOOT0_CHIPSET_MASK: u32 = BOOT0_IMPL_MASK | BOOT0_ARCH_MASK;
 +
 +#[derive(Copy, Clone)]
 +pub(crate) struct Boot0(u32);
 +
 +impl Boot0 {
 +    #[inline]
 +    pub(crate) fn read(bar: &Bar0) -> Self {
++        Self(bar.read32(BOOT0_OFFSET))
 +    }
 +
 +    #[inline]
 +    pub(crate) fn chipset(&self) -> u32 {
 +        (self.0 & BOOT0_CHIPSET_MASK) >> BOOT0_CHIPSET_SHIFT
 +    }
 +
 +    #[inline]
 +    pub(crate) fn minor_rev(&self) -> u8 {
 +        ((self.0 & BOOT0_MINOR_REV_MASK) >> BOOT0_MINOR_REV_SHIFT) as u8
 +    }
 +
 +    #[inline]
 +    pub(crate) fn major_rev(&self) -> u8 {
 +        ((self.0 & BOOT0_MAJOR_REV_MASK) >> BOOT0_MAJOR_REV_SHIFT) as u8
 +    }
 +}
diff --cc fs/kernfs/dir.c
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index 908acd3,0000000..874c2c9
mode 100644,000000..100644
--- /dev/null
@@@ -1,97 -1,0 +1,97 @@@
- use kernel::{bindings, dma::CoherentAllocation, pci, prelude::*};
 +// SPDX-License-Identifier: GPL-2.0
 +
 +//! Rust DMA api test (based on QEMU's `pci-testdev`).
 +//!
 +//! To make this driver probe, QEMU must be run with `-device pci-testdev`.
 +
-     pdev: pci::Device,
++use kernel::{bindings, device::Core, dma::CoherentAllocation, pci, prelude::*, types::ARef};
 +
 +struct DmaSampleDriver {
-     fn probe(pdev: &mut pci::Device, _info: &Self::IdInfo) -> Result<Pin<KBox<Self>>> {
++    pdev: ARef<pci::Device>,
 +    ca: CoherentAllocation<MyStruct>,
 +}
 +
 +const TEST_VALUES: [(u32, u32); 5] = [
 +    (0xa, 0xb),
 +    (0xc, 0xd),
 +    (0xe, 0xf),
 +    (0xab, 0xba),
 +    (0xcd, 0xef),
 +];
 +
 +struct MyStruct {
 +    h: u32,
 +    b: u32,
 +}
 +
 +impl MyStruct {
 +    fn new(h: u32, b: u32) -> Self {
 +        Self { h, b }
 +    }
 +}
 +// SAFETY: All bit patterns are acceptable values for `MyStruct`.
 +unsafe impl kernel::transmute::AsBytes for MyStruct {}
 +// SAFETY: Instances of `MyStruct` have no uninitialized portions.
 +unsafe impl kernel::transmute::FromBytes for MyStruct {}
 +
 +kernel::pci_device_table!(
 +    PCI_TABLE,
 +    MODULE_PCI_TABLE,
 +    <DmaSampleDriver as pci::Driver>::IdInfo,
 +    [(
 +        pci::DeviceId::from_id(bindings::PCI_VENDOR_ID_REDHAT, 0x5),
 +        ()
 +    )]
 +);
 +
 +impl pci::Driver for DmaSampleDriver {
 +    type IdInfo = ();
 +    const ID_TABLE: pci::IdTable<Self::IdInfo> = &PCI_TABLE;
 +
-                 pdev: pdev.clone(),
++    fn probe(pdev: &pci::Device<Core>, _info: &Self::IdInfo) -> Result<Pin<KBox<Self>>> {
 +        dev_info!(pdev.as_ref(), "Probe DMA test driver.\n");
 +
 +        let ca: CoherentAllocation<MyStruct> =
 +            CoherentAllocation::alloc_coherent(pdev.as_ref(), TEST_VALUES.len(), GFP_KERNEL)?;
 +
 +        || -> Result {
 +            for (i, value) in TEST_VALUES.into_iter().enumerate() {
 +                kernel::dma_write!(ca[i] = MyStruct::new(value.0, value.1));
 +            }
 +
 +            Ok(())
 +        }()?;
 +
 +        let drvdata = KBox::new(
 +            Self {
++                pdev: pdev.into(),
 +                ca,
 +            },
 +            GFP_KERNEL,
 +        )?;
 +
 +        Ok(drvdata.into())
 +    }
 +}
 +
 +impl Drop for DmaSampleDriver {
 +    fn drop(&mut self) {
 +        dev_info!(self.pdev.as_ref(), "Unload DMA test driver.\n");
 +
 +        let _ = || -> Result {
 +            for (i, value) in TEST_VALUES.into_iter().enumerate() {
 +                assert_eq!(kernel::dma_read!(self.ca[i].h), value.0);
 +                assert_eq!(kernel::dma_read!(self.ca[i].b), value.1);
 +            }
 +            Ok(())
 +        }();
 +    }
 +}
 +
 +kernel::module_pci_driver! {
 +    type: DmaSampleDriver,
 +    name: "rust_dma",
 +    authors: ["Abdiel Janulgue"],
 +    description: "Rust DMA test",
 +    license: "GPL v2",
 +}
Simple merge
Simple merge
Simple merge
Simple merge