Introduce safe Rust wrappers around struct fwctl_device and struct
fwctl_uctx. This lets Rust drivers register fwctl devices and implement
firmware RPC callbacks through a typed trait interface.
The abstraction keeps lifetime and reference-count handling inside the
wrapper, exposes pinned per-FD user contexts to drivers, and validates the
layout assumptions required by the C fwctl allocation model. Allocation
sizes are padded so the kmalloc-backed C allocations also satisfy Rust
alignment requirements.
Registration owns driver private data with a lifetime tied to the bound
parent device and verifies the parent identity before registration.
Callbacks access that data through a higher-ranked closure, preventing its
erased lifetime from escaping, while Device remains only the refcounted
fwctl object. This avoids requiring Rust drop glue from the fwctl_device
release path after unregister or module teardown.
RPC callbacks receive typed scope information, a mutable request/response
buffer, and the userspace output-buffer size. Response pointer conversion,
length validation, and raw output-length handling remain inside the
abstraction.
Add the Rust sources to the FWCTL MAINTAINERS entry and add myself as the
maintainer for the Rust abstractions.
Link: https://patch.msgid.link/r/[email protected]
Co-developed-by: Danilo Krummrich <[email protected]>
Signed-off-by: Danilo Krummrich <[email protected]>
Signed-off-by: Zhi Wang <[email protected]>
Reviewed-by: Alexandre Courbot <[email protected]>
Signed-off-by: Jason Gunthorpe <[email protected]>
Several HWRM commands carry __le64 DMA address fields in their input
structures; firmware reads from or writes to the memory those addresses
point to.
Have a static per-command descriptor table in the driver that records
the details of the DMA fields in each supported HWRM input struct. When
a DMA-bearing HWRM command arrives, the driver reads the userspace
pointer out of each declared address field and clears the field, allocates
a DMA-coherent kernel buffer sized from the command's own length
information, copies data to/from the userspace pointer, and patches the
field with the real DMA bus address before the command is sent to firmware.
Responses are copied back to the original userspace pointer afterward.
Scope-gated allow-list and timeout value list are updated with the new
the commands.
Signed-off-by: Pavan Chebbi <[email protected]>
Link: https://patch.msgid.link/[email protected]
Signed-off-by: Jason Gunthorpe <[email protected]>
The fwctl core allocates the device-specific RPC input buffer with
fwctl_rpc.in_len and passes that buffer to the driver callback.
pdsfc_fw_rpc() casts the buffer to struct fwctl_rpc_pds and then calls
pdsfc_validate_rpc(), which reads fields from that structure before
checking that the input buffer is large enough to contain it. A short
in_len can make pds_fwctl read beyond the allocation.
Reject pds RPC buffers that are smaller than struct fwctl_rpc_pds before
parsing any pds-specific fields.
Fixes: 92c66ee829 ("pds_fwctl: add rpc and query support")
Link: https://patch.msgid.link/r/[email protected]
Cc: [email protected] # v6.15+
Signed-off-by: Heechan Kang <[email protected]>
Reviewed-by: Dave Jiang <[email protected]>
Signed-off-by: Jason Gunthorpe <[email protected]>
CXL is linked before fwctl in drivers/Makefile. Both use `module_init, so
`cxl_pci_driver_init()` runs first. When `cxl_pci_probe()` calls
`fwctl_register()` and then `device_add()`, fwctl_class is not yet
registered because fwctl_init() hasn't run, causing `class_to_subsys()` to
return NULL and skip knode_class initialization.
On device removal, `class_to_subsys()` returns non-NULL, and
`device_del()` calls `klist_del()` on the uninitialized knode, triggering
a NULL pointer dereference.
Fixes: 858ce2f56b ("cxl: Add FWCTL support to CXL")
Link: https://patch.msgid.link/r/[email protected]
Signed-off-by: Richard Cheng <[email protected]>
Reviewed-by: Kai-Heng Feng <[email protected]>
Reviewed-by: Dave Jiang <[email protected]>
Signed-off-by: Jason Gunthorpe <[email protected]>
This was done entirely with mindless brute force, using
git grep -l '\<k[vmz]*alloc_objs*(.*, GFP_KERNEL)' |
xargs sed -i 's/\(alloc_objs*(.*\), GFP_KERNEL)/\1)/'
to convert the new alloc_obj() users that had a simple GFP_KERNEL
argument to just drop that argument.
Note that due to the extreme simplicity of the scripting, any slightly
more complex cases spread over multiple lines would not be triggered:
they definitely exist, but this covers the vast bulk of the cases, and
the resulting diff is also then easier to check automatically.
For the same reason the 'flex' versions will be done as a separate
conversion.
Signed-off-by: Linus Torvalds <[email protected]>
This is the result of running the Coccinelle script from
scripts/coccinelle/api/kmalloc_objs.cocci. The script is designed to
avoid scalar types (which need careful case-by-case checking), and
instead replace kmalloc-family calls that allocate struct or union
object instances:
Single allocations: kmalloc(sizeof(TYPE), ...)
are replaced with: kmalloc_obj(TYPE, ...)
Array allocations: kmalloc_array(COUNT, sizeof(TYPE), ...)
are replaced with: kmalloc_objs(TYPE, COUNT, ...)
Flex array allocations: kmalloc(struct_size(PTR, FAM, COUNT), ...)
are replaced with: kmalloc_flex(*PTR, FAM, COUNT, ...)
(where TYPE may also be *VAR)
The resulting allocations no longer return "void *", instead returning
"TYPE *".
Signed-off-by: Kees Cook <[email protected]>
MLX5_CMD_OP_QUERY_ADJACENT_FUNCTIONS_ID:
- Query Adjacent functions (PFs/VFs) of the function calling FW.
MLX5_CMD_OP_DELEGATE_VHCA_MANAGEMENT:
- Delegates own VFs to be managed/seen by other adjacent PFs
MLX5_CMD_OP_QUERY_DELEGATED_VHCA:
- Query current function delegation state.
Link: https://patch.msgid.link/r/[email protected]
Signed-off-by: Saeed Mahameed <[email protected]>
Reviewed-by: Dave Jiang <[email protected]>
Signed-off-by: Jason Gunthorpe <[email protected]>
MODIFY_CONG_STATUS command is used to enable or disable congestion control
according to a given priority and protocol.
Add MODIFY_CONG_STATUS to the allowed commands under configuration scope.
Link: https://patch.msgid.link/r/[email protected]
Signed-off-by: Avihai Horon <[email protected]>
Reviewed-by: Dave Jiang <[email protected]>
Signed-off-by: Jason Gunthorpe <[email protected]>
Use kvfree() to free memory allocated by kvzalloc() instead of kfree().
Avoid potential memory management issue considering kvzalloc() can
internally choose to use either kmalloc() or vmalloc() based on memory
request and current system memory state. Hence, use more appropriate
kvfree() which automatically determines correct free method to avoid
potential hard to debug memory issues. Fix this issue discovered by
running spatch static analysis tool using coccinelle script -
scripts/coccinelle/api/kfree_mismatch.cocci
Fixes: 52929c2142 ("fwctl/mlx5: Support for communicating with mlx5 fw")
Link: https://patch.msgid.link/r/[email protected]
Signed-off-by: Akhilesh Patil <[email protected]>
Reviewed-by: Dave Jiang <[email protected]>
Reviewed-by: Alison Schofield <[email protected]>
Signed-off-by: Jason Gunthorpe <[email protected]>
The pds_fwctl driver doesn't know what RPC operations are available
in the firmware, so also doesn't know what scope they might have. The
userland utility supplies the firmware "endpoint" and "operation" id values
and this driver queries the firmware for endpoints and their available
operations. The operation descriptions include the scope information
which the driver uses for scope testing.
Link: https://patch.msgid.link/r/[email protected]
Reviewed-by: Leon Romanovsky <[email protected]>
Signed-off-by: Brett Creeley <[email protected]>
Reviewed-by: Jonathan Cameron <[email protected]>
Signed-off-by: Shannon Nelson <[email protected]>
Signed-off-by: Jason Gunthorpe <[email protected]>
Initial files for adding a new fwctl driver for the AMD/Pensando PDS
devices. This sets up a simple auxiliary_bus driver that registers
with fwctl subsystem. It expects that a pds_core device has set up
the auxiliary_device pds_core.fwctl
Link: https://patch.msgid.link/r/[email protected]
Reviewed-by: Leon Romanovsky <[email protected]>
Reviewed-by: Dave Jiang <[email protected]>
Reviewed-by: Jonathan Cameron <[email protected]>
Signed-off-by: Shannon Nelson <[email protected]>
Signed-off-by: Jason Gunthorpe <[email protected]>
mlx5 FW has a built in security context called UID. Each UID has a set of
permissions controlled by the kernel when it is created and every command
is tagged by the kernel with a particular UID. In general commands cannot
reach objects outside of their UID and commands cannot exceed their UID's
permissions. These restrictions are enforced by FW.
This mechanism has long been used in RDMA for the devx interface where
RDMA will sent commands directly to the FW and the UID limitations
restrict those commands to a ib_device/verbs security domain. For instance
commands that would effect other VFs, or global device resources. The
model is suitable for unprivileged userspace to operate the RDMA
functionality.
The UID has been extended with a "tools resources" permission which allows
additional commands and sub-commands that are intended to match with the
scope limitations set in FWCTL. This is an alternative design to the
"command intent log" where the FW does the enforcement rather than having
the FW report the enforcement the kernel should do.
Consistent with the fwctl definitions the "tools resources" security
context is limited to the FWCTL_RPC_CONFIGURATION,
FWCTL_RPC_DEBUG_READ_ONLY, FWCTL_RPC_DEBUG_WRITE, and
FWCTL_RPC_DEBUG_WRITE_FULL security scopes.
Like RDMA devx, each opened fwctl file descriptor will get a unique UID
associated with each file descriptor.
The fwctl driver is kept simple and we reject commands that can create
objects as the UID mechanism relies on the kernel to track and destroy
objects prior to detroying the UID. Filtering into fwctl sub scopes is
done inside the driver with a switch statement. This substantially limits
what is possible to primarily query functions ad a few limited set
operations.
mlx5 already has a robust infrastructure for delivering RPC messages to
fw. Trivially connect fwctl's RPC mechanism to mlx5_cmd_do(). Enforce the
User Context ID in every RPC header accepted from the FD so the FW knows
the security context of the issuing ID.
Link: https://patch.msgid.link/r/[email protected]
Reviewed-by: Jonathan Cameron <[email protected]>
Signed-off-by: Saeed Mahameed <[email protected]>
Reviewed-by: Leon Romanovsky <[email protected]>
Signed-off-by: Jason Gunthorpe <[email protected]>
Add the FWCTL_RPC ioctl which allows a request/response RPC call to device
firmware. Drivers implementing this call must follow the security
guidelines under Documentation/userspace-api/fwctl.rst
The core code provides some memory management helpers to get the messages
copied from and back to userspace. The driver is responsible for
allocating the output message memory and delivering the message to the
device.
Link: https://patch.msgid.link/r/[email protected]
Reviewed-by: Jonathan Cameron <[email protected]>
Reviewed-by: Dave Jiang <[email protected]>
Reviewed-by: Shannon Nelson <[email protected]>
Tested-by: Dave Jiang <[email protected]>
Tested-by: Shannon Nelson <[email protected]>
Signed-off-by: Jason Gunthorpe <[email protected]>
Userspace will need to know some details about the fwctl interface being
used to locate the correct userspace code to communicate with the
kernel. Provide a simple device_type enum indicating what the kernel
driver is.
Allow the device to provide a device specific info struct that contains
any additional information that the driver may need to provide to
userspace.
Link: https://patch.msgid.link/r/[email protected]
Reviewed-by: Jonathan Cameron <[email protected]>
Reviewed-by: Dave Jiang <[email protected]>
Reviewed-by: Shannon Nelson <[email protected]>
Tested-by: Dave Jiang <[email protected]>
Tested-by: Shannon Nelson <[email protected]>
Signed-off-by: Jason Gunthorpe <[email protected]>
Each file descriptor gets a chunk of per-FD driver specific context that
allows the driver to attach a device specific struct to. The core code
takes care of the memory lifetime for this structure.
The ioctl dispatch and design is based on what was built for iommufd. The
ioctls have a struct which has a combined in/out behavior with a typical
'zero pad' scheme for future extension and backwards compatibility.
Like iommufd some shared logic does most of the ioctl marshaling and
compatibility work and table dispatches to some function pointers for
each unique ioctl.
This approach has proven to work quite well in the iommufd and rdma
subsystems.
Allocate an ioctl number space for the subsystem.
Link: https://patch.msgid.link/r/[email protected]
Reviewed-by: Jonathan Cameron <[email protected]>
Reviewed-by: Dave Jiang <[email protected]>
Reviewed-by: Shannon Nelson <[email protected]>
Tested-by: Dave Jiang <[email protected]>
Tested-by: Shannon Nelson <[email protected]>
Signed-off-by: Jason Gunthorpe <[email protected]>
Create the class, character device and functions for a fwctl driver to
un/register to the subsystem.
A typical fwctl driver has a sysfs presence like:
$ ls -l /dev/fwctl/fwctl0
crw------- 1 root root 250, 0 Apr 25 19:16 /dev/fwctl/fwctl0
$ ls /sys/class/fwctl/fwctl0
dev device power subsystem uevent
$ ls /sys/class/fwctl/fwctl0/device/infiniband/
ibp0s10f0
$ ls /sys/class/infiniband/ibp0s10f0/device/fwctl/
fwctl0/
$ ls /sys/devices/pci0000:00/0000:00:0a.0/fwctl/fwctl0
dev device power subsystem uevent
Which allows userspace to link all the multi-subsystem driver components
together and learn the subsystem specific names for the device's
components.
Link: https://patch.msgid.link/r/[email protected]
Reviewed-by: Jonathan Cameron <[email protected]>
Reviewed-by: Dan Williams <[email protected]>
Reviewed-by: Dave Jiang <[email protected]>
Reviewed-by: Shannon Nelson <[email protected]>
Tested-by: Dave Jiang <[email protected]>
Tested-by: Shannon Nelson <[email protected]>
Signed-off-by: Jason Gunthorpe <[email protected]>