Skip to content

Commit 8205c61

Browse files
committed
Merge tag 'drm-rust-next-2026-06-04' of https://gitlab.freedesktop.org/drm/rust/kernel into drm-next
DRM Rust changes for v7.2-rc1 - Driver Core (shared via signed tag dd-lifetimes-7.2-rc1): - Introduce Higher-Ranked Lifetime Types (HRT) for Rust device drivers, allowing driver structs to hold device resources like pci::Bar and IoMem directly with a lifetime tied to the binding scope, removing the need for Devres indirection and ARef<Device>. - Replace drvdata() with scoped registration data on the auxiliary bus, using the new ForLt trait to thread lifetimes through registrations. Remove drvdata() and driver_type. - DRM: - Add GPUVM immediate mode abstraction for Rust GPU drivers: - In immediate mode, GPU virtual address space state is updated during job execution (in the DMA fence signalling critical path), keeping the GPUVM and the GPU's address space always in sync. - Provide GpuVm, GpuVa, and GpuVmBo types for managing address spaces, virtual mappings, and GEM object backing respectively. - Provide split-merge map/unmap operations that handle partial overlaps with existing mappings. - drm_exec integration for dma_resv locking and GEM object validation based on the external/evicted object lists are not yet covered and planned as follow-up work. - Introduce DeviceContext type state for drm::Device, allowing drivers to restrict operations to contexts where the device is guaranteed to be registered (or not yet registered) with userspace. - Add FEAT_RENDER flag to the Driver trait for render node support. - Nova: - Hopper/Blackwell enablement: - Add GPU identification and architecture-based HAL selection for Hopper (GH100) and Blackwell (GB100, GB202). - Implement the FSP (Foundation Security Processor) boot path used by Hopper and Blackwell, including FSP falcon engine support, EMEM operations, MCTP/NVDM message infrastructure, and FSP Chain of Trust boot with GSP lockdown release. - Add support for 32-bit firmware images and auto-detection of firmware image format. - Add architecture-specific framebuffer, sysmem flush, PCI config mirror, DMA mask, and WPR/non-WPR heap sizing. - GSP boot and unload: - Refactor the GSP boot process into a chipset-specific HAL, keeping the SEC2 and FSP boot paths separated cleanly. - Implement proper driver unload: send UNLOADING_GUEST_DRIVER command, run Booter Unloader and FWSEC-SB upon unbinding, and run the unload bundle on Gsp::boot() failure. This removes the need for a manual GPU reset between driver unbind and re-probe. - GA100 support: - Add support for the GA100 GPU, including IFR header detection and skipping, correct fwsignature selection, conditional FRTS boot, and documentation of the IFR header layout. - VBIOS hardening and refactoring: - Harden VBIOS parsing with checked arithmetic, bounds-checked accesses, and FromBytes-based structure reads throughout the FWSEC and Falcon data paths. Simplify the overall VBIOS module structure. - HRT adoption: - Use lifetime-parameterized pci::Bar directly, replacing the Arc<Devres<Bar0>> indirection. Replace ARef<Device> with &'bound Device in SysmemFlush and the GSP sequencer. Separate the driver type from driver data. - Misc: - Rename module names to kebab-case (nova-drm, nova-core). - Require little-endian in Kconfig, making the existing assumption explicit. - Tyr: - Define comprehensive typed register blocks for GPU_CONTROL, JOB_CONTROL, MMU_CONTROL (including per-address-space registers), and DOORBELL_BLOCK using the kernel register!() macro. This replaces manual bit manipulation with typed register and field accessors. - Add shmem-backed GEM objects and set DMA mask based on GPU physical address width. - Adopt HRT: separate driver type from driver data, and use IoMem directly instead of Devres for register access during probe. - Move clock cleanup into a Drop implementation. Signed-off-by: Dave Airlie <airlied@redhat.com> From: "Danilo Krummrich" <dakr@kernel.org> Link: https://patch.msgid.link/DJ0IF39U9ETK.PCCUO7ZEQ4S0@kernel.org
2 parents 527b3f2 + 99676ae commit 8205c61

111 files changed

Lines changed: 7909 additions & 1793 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Documentation/gpu/nova/core/vbios.rst

Lines changed: 62 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,71 @@ region is only accessible to heavy-secure ucode.
4646
are of type 0xE0 and can be identified as such. This could be subject to change
4747
in future generations.
4848

49+
IFR Header
50+
----------
51+
On Kepler and later GPUs, the ROM begins with an Init-from-ROM (IFR) header
52+
rather than a standard PCI ROM signature (0xAA55). The driver must parse the
53+
IFR header to find where the PCI ROM images actually start.
54+
55+
Init-from-ROM (IFR) is a special GPU feature used for power management
56+
on some Nvidia GPUs. It references data in the VBIOS for its operation,
57+
but for drivers the important piece is a header that precedes the
58+
VBIOS PCI Expansion ROM.
59+
60+
Most such GPUs do not need to parse the IFR header in order to find the
61+
VBIOS, but the Nvidia GA100 is the exception. GA100 lacks a display engine,
62+
so the PRAMIN method (which reads the VBIOS from VRAM via display hardware)
63+
is unavailable, forcing the driver to read the ROM directly via PROM.
64+
On other similar GPUs, either PRAMIN succeeds before PROM is tried, or the
65+
IFR hardware has already applied the ROM offset so that PROM reads
66+
transparently skip the IFR header.
67+
68+
The driver should first check for the standard 0xAA55 signature at offset 0.
69+
If found, there is no IFR header and the PCI ROM images start at
70+
offset 0. If not found, check for the IFR signature and parse the header to
71+
determine the PCI ROM image offset.
72+
73+
Fixed Header Format
74+
~~~~~~~~~~~~~~~~~~~
75+
76+
The IFR header begins with four 32-bit words at fixed offsets::
77+
78+
Offset Name Fields
79+
------ ------- ------
80+
0x00 FIXED0 bits 31:0 - Signature (must be 0x4947564E, ASCII "NVGI")
81+
0x04 FIXED1 bit 31 - Reserved
82+
bits 30:16 - FIXED_DATA_SIZE Fixed data size (offset to extended section)
83+
bits 15:8 - VERSIONSW Software version
84+
bits 7:0 - Reserved
85+
0x08 FIXED2 bit 31 - Reserved
86+
bits 30:20 - Reserved (zero)
87+
bits 19:0 - TOTAL_DATA_SIZE Total data size
88+
89+
Finding the PCI ROM Image Offset
90+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
91+
92+
The method to find this offset depends on `VERSIONSW`.
93+
94+
- **Version 1 and 2**: Read `FIXED_DATA_SIZE` from `FIXED1` to get the extended
95+
section offset. The PCI ROM image is the 32-bit value at `FIXED_DATA_SIZE + 4`.
96+
97+
- **Version 3**: Read `TOTAL_DATA_SIZE` from `FIXED2`. The 32-bit value at that
98+
offset is a flash status offset. Add 4096 to get the ROM directory offset,
99+
`ROM_DIRECTORY_OFFSET`. The ROM directory must have signature 0x44524652
100+
(ASCII "RFRD"). The PCI ROM image offset is the 32-bit value at
101+
`ROM_DIRECTORY_OFFSET + 8`.
102+
103+
The PCI ROM image offset must be 4-byte aligned. All offsets are relative to the
104+
start of ROM (BAR0 + 0x300000).
105+
49106
VBIOS ROM Layout
50107
----------------
51-
The VBIOS layout is roughly a series of concatenated images laid out as follows::
108+
The VBIOS (PCI Expansion ROM) is a series of concatenated images laid out as
109+
follows. On GPUs with an IFR header, this layout begins at the image offset
110+
determined by parsing the IFR header. On older GPUs, it begins at offset 0::
52111

53112
+----------------------------------------------------------------------------+
54-
| VBIOS (Starting at ROM_OFFSET: 0x300000) |
113+
| VBIOS (Starting at ROM_OFFSET: 0x300000 + IFR image offset) |
55114
+----------------------------------------------------------------------------+
56115
| +-----------------------------------------------+ |
57116
| | PciAt Image (Type 0x00) | |
@@ -173,7 +232,7 @@ Falcon data in the VBIOS which contains the PMU lookup table. This lookup table
173232
used to find the required Falcon ucode based on an application ID.
174233

175234
The location of the PMU lookup table is found by scanning the BIT (`BIOS Information Table`_)
176-
tokens for a token with the id `BIT_TOKEN_ID_FALCON_DATA` (0x70) which indicates the
235+
tokens for a token with the Falcon data token id (0x70) which indicates the
177236
offset of the same from the start of the VBIOS image. Unfortunately, the offset
178237
does not account for the EFI image located between the PciAt and FwSec images.
179238
The `vbios.rs` code compensates for this with appropriate arithmetic.

MAINTAINERS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8902,6 +8902,8 @@ S: Supported
89028902
T: git https://gitlab.freedesktop.org/drm/misc/kernel.git
89038903
F: drivers/gpu/drm/drm_gpuvm.c
89048904
F: include/drm/drm_gpuvm.h
8905+
F: rust/helpers/drm_gpuvm.c
8906+
F: rust/kernel/drm/gpuvm/
89058907

89068908
DRM LOG
89078909
M: Jocelyn Falempe <jfalempe@redhat.com>

drivers/base/base.h

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -86,18 +86,6 @@ struct driver_private {
8686
};
8787
#define to_driver(obj) container_of(obj, struct driver_private, kobj)
8888

89-
#ifdef CONFIG_RUST
90-
/**
91-
* struct driver_type - Representation of a Rust driver type.
92-
*/
93-
struct driver_type {
94-
/**
95-
* @id: Representation of core::any::TypeId.
96-
*/
97-
u8 id[16];
98-
} __packed;
99-
#endif
100-
10189
/**
10290
* struct device_private - structure to hold the private to the driver core
10391
* portions of the device structure.
@@ -115,7 +103,6 @@ struct driver_type {
115103
* dev_err_probe() for later retrieval via debugfs
116104
* @device: pointer back to the struct device that this structure is
117105
* associated with.
118-
* @driver_type: The type of the bound Rust driver.
119106
* @dead: This device is currently either in the process of or has been
120107
* removed from the system. Any asynchronous events scheduled for this
121108
* device should exit without taking any action.
@@ -132,9 +119,6 @@ struct device_private {
132119
const struct device_driver *async_driver;
133120
char *deferred_probe_reason;
134121
struct device *device;
135-
#ifdef CONFIG_RUST
136-
struct driver_type driver_type;
137-
#endif
138122
u8 dead:1;
139123
};
140124
#define to_device_private_parent(obj) \

drivers/base/dd.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -595,9 +595,9 @@ static DEVICE_ATTR_RW(state_synced);
595595

596596
static void device_unbind_cleanup(struct device *dev)
597597
{
598-
devres_release_all(dev);
599598
if (dev->driver->p_cb.post_unbind_rust)
600599
dev->driver->p_cb.post_unbind_rust(dev);
600+
devres_release_all(dev);
601601
arch_teardown_dma_ops(dev);
602602
kfree(dev->dma_range_map);
603603
dev->dma_range_map = NULL;

drivers/cpufreq/rcpufreq_dt.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -201,12 +201,13 @@ kernel::of_device_table!(
201201

202202
impl platform::Driver for CPUFreqDTDriver {
203203
type IdInfo = ();
204+
type Data<'bound> = Self;
204205
const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = Some(&OF_TABLE);
205206

206-
fn probe(
207-
pdev: &platform::Device<Core>,
208-
_id_info: Option<&Self::IdInfo>,
209-
) -> impl PinInit<Self, Error> {
207+
fn probe<'bound>(
208+
pdev: &'bound platform::Device<Core<'_>>,
209+
_id_info: Option<&'bound Self::IdInfo>,
210+
) -> impl PinInit<Self, Error> + 'bound {
210211
cpufreq::Registration::<CPUFreqDTDriver>::new_foreign_owned(pdev.as_ref())?;
211212
Ok(Self {})
212213
}

drivers/gpu/drm/Kconfig

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,13 @@ config DRM_GPUVM
218218
GPU-VM representation providing helpers to manage a GPUs virtual
219219
address space
220220

221+
config RUST_DRM_GPUVM
222+
bool
223+
depends on DRM
224+
select DRM_GPUVM
225+
help
226+
Choose this if you need GPUVM functions in Rust
227+
221228
config DRM_GPUSVM
222229
tristate
223230
depends on DRM

drivers/gpu/drm/drm_gem_shmem_helper.c

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,30 @@ struct drm_gem_shmem_object *drm_gem_shmem_create(struct drm_device *dev, size_t
158158
}
159159
EXPORT_SYMBOL_GPL(drm_gem_shmem_create);
160160

161+
/**
162+
* __drm_gem_shmem_release_sgt_locked - Unpin and DMA unmap pages, and release the
163+
* cached scatter/gather table for an shmem GEM object.
164+
* @shmem: shmem GEM object
165+
*
166+
* If the passed shmem object has an active scatter/gather table for driver
167+
* usage, this function will unmap it and release the memory associated with it.
168+
* It is the responsibility of the caller to ensure it holds the dma_resv_lock
169+
* for this object.
170+
*
171+
* Drivers should not need to call this function themselves, it is mainly
172+
* intended for usage in the Rust shmem bindings.
173+
*/
174+
void __drm_gem_shmem_free_sgt_locked(struct drm_gem_shmem_object *shmem)
175+
{
176+
dma_resv_assert_held(shmem->base.resv);
177+
178+
dma_unmap_sgtable(shmem->base.dev->dev, shmem->sgt, DMA_BIDIRECTIONAL, 0);
179+
sg_free_table(shmem->sgt);
180+
kfree(shmem->sgt);
181+
shmem->sgt = NULL;
182+
}
183+
EXPORT_SYMBOL_GPL(__drm_gem_shmem_free_sgt_locked);
184+
161185
/**
162186
* drm_gem_shmem_release - Release resources associated with a shmem GEM object.
163187
* @shmem: shmem GEM object
@@ -176,12 +200,8 @@ void drm_gem_shmem_release(struct drm_gem_shmem_object *shmem)
176200

177201
drm_WARN_ON(obj->dev, refcount_read(&shmem->vmap_use_count));
178202

179-
if (shmem->sgt) {
180-
dma_unmap_sgtable(obj->dev->dev, shmem->sgt,
181-
DMA_BIDIRECTIONAL, 0);
182-
sg_free_table(shmem->sgt);
183-
kfree(shmem->sgt);
184-
}
203+
if (shmem->sgt)
204+
__drm_gem_shmem_free_sgt_locked(shmem);
185205
if (shmem->pages)
186206
drm_gem_shmem_put_pages_locked(shmem);
187207

drivers/gpu/drm/drm_gpuvm.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
*
2626
*/
2727

28+
#include <drm/drm_drv.h>
2829
#include <drm/drm_gpuvm.h>
2930
#include <drm/drm_print.h>
3031

@@ -1117,6 +1118,7 @@ drm_gpuvm_init(struct drm_gpuvm *gpuvm, const char *name,
11171118
gpuvm->drm = drm;
11181119
gpuvm->r_obj = r_obj;
11191120

1121+
drm_dev_get(drm);
11201122
drm_gem_object_get(r_obj);
11211123

11221124
drm_gpuvm_warn_check_overflow(gpuvm, start_offset, range);
@@ -1160,13 +1162,15 @@ static void
11601162
drm_gpuvm_free(struct kref *kref)
11611163
{
11621164
struct drm_gpuvm *gpuvm = container_of(kref, struct drm_gpuvm, kref);
1165+
struct drm_device *drm = gpuvm->drm;
11631166

11641167
drm_gpuvm_fini(gpuvm);
11651168

1166-
if (drm_WARN_ON(gpuvm->drm, !gpuvm->ops->vm_free))
1169+
if (drm_WARN_ON(drm, !gpuvm->ops->vm_free))
11671170
return;
11681171

11691172
gpuvm->ops->vm_free(gpuvm);
1173+
drm_dev_put(drm);
11701174
}
11711175

11721176
/**

drivers/gpu/drm/nova/Kconfig

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ config DRM_NOVA
44
depends on DRM=y
55
depends on PCI
66
depends on RUST
7+
depends on !CPU_BIG_ENDIAN
78
select AUXILIARY_BUS
89
select NOVA_CORE
910
default n
@@ -13,4 +14,4 @@ config DRM_NOVA
1314

1415
This driver is work in progress and may not be functional.
1516

16-
If M is selected, the module will be called nova.
17+
If M is selected, the module will be called nova-drm.

drivers/gpu/drm/nova/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
# SPDX-License-Identifier: GPL-2.0
22

3-
obj-$(CONFIG_DRM_NOVA) += nova.o
3+
obj-$(CONFIG_DRM_NOVA) += nova-drm.o
4+
nova-drm-y := nova.o

0 commit comments

Comments
 (0)