drivers/infiniband/core/ib_core_uverbs.c
Source file repositories/reference/linux-study-clean/drivers/infiniband/core/ib_core_uverbs.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/infiniband/core/ib_core_uverbs.c- Extension
.c- Size
- 22354 bytes
- Lines
- 759
- Domain
- Driver Families
- Bucket
- drivers/infiniband
- Inferred role
- Driver Families: exported/initcall integration point
- Status
- integration implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Touches user memory; correctness depends on fault-safe copying and privilege boundary handling.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/xarray.hlinux/dma-buf.hlinux/dma-resv.huverbs.hcore_priv.hrdma_core.h
Detected Declarations
function rdma_umap_priv_initfunction rdma_user_mmap_iofunction rdma_user_mmap_entry_get_pgofffunction rdma_user_mmap_entry_getfunction rdma_user_mmap_entry_freefunction rdma_user_mmap_entry_putfunction rdma_user_mmap_entry_removefunction rdma_user_mmap_entry_insert_rangefunction rdma_user_mmap_entry_insertfunction uverbs_get_handler_fnfunction _ib_copy_validate_udata_infunction _ib_copy_validate_udata_cm_failfunction _ib_respond_udatafunction uverbs_destroy_def_handlerfunction _uverbs_allocfunction uverbs_copy_tofunction uverbs_copy_to_struct_or_zerofunction _uverbs_get_const_unsignedfunction _uverbs_get_const_signedfunction uverbs_get_flags64function uverbs_get_flags32function uverbs_copy_fromfunction uverbs_finalize_uobj_createexport rdma_umap_priv_initexport rdma_user_mmap_ioexport rdma_user_mmap_entry_get_pgoffexport rdma_user_mmap_entry_getexport rdma_user_mmap_entry_putexport rdma_user_mmap_entry_removeexport rdma_user_mmap_entry_insert_rangeexport rdma_user_mmap_entry_insertexport _ib_copy_validate_udata_inexport _ib_copy_validate_udata_cm_failexport _ib_respond_udataexport ib_uverbs_get_ucontext_fileexport uverbs_destroy_def_handlerexport _uverbs_allocexport uverbs_copy_toexport uverbs_copy_to_struct_or_zeroexport _uverbs_get_const_unsignedexport _uverbs_get_const_signedexport uverbs_get_flags64export uverbs_get_flags32export uverbs_get_buffer_descexport uverbs_finalize_uobj_create
Annotated Snippet
if (err == -E2BIG) {
ibdev_dbg(
rdma_udata_to_dev(udata),
"System call driver input udata not zero from %zu -> %zu for ioctl %ps called by %pSR\n",
minimum_size, udata->inlen,
uverbs_get_handler_fn(udata),
__builtin_return_address(0));
return -EOPNOTSUPP;
}
ibdev_dbg(
rdma_udata_to_dev(udata),
"System call driver input udata EFAULT for ioctl %ps called by %pSR\n",
uverbs_get_handler_fn(udata),
__builtin_return_address(0));
return err;
}
return 0;
}
EXPORT_SYMBOL(_ib_copy_validate_udata_in);
int _ib_copy_validate_udata_cm_fail(struct ib_udata *udata, u64 req_cm,
u64 valid_cm)
{
ibdev_dbg(
rdma_udata_to_dev(udata),
"System call driver input udata has unsupported comp_mask %llx & ~%llx = %llx for ioctl %ps called by %pSR\n",
req_cm, valid_cm, req_cm & ~valid_cm,
uverbs_get_handler_fn(udata), __builtin_return_address(0));
return -EOPNOTSUPP;
}
EXPORT_SYMBOL(_ib_copy_validate_udata_cm_fail);
int _ib_respond_udata(struct ib_udata *udata, const void *src, size_t len)
{
size_t copy_len;
/* 0 length copy_len is a NOP for copy_to_user() and doesn't fail. */
copy_len = min(len, udata->outlen);
if (copy_to_user(udata->outbuf, src, copy_len))
goto err_fault;
if (copy_len < udata->outlen) {
if (clear_user(udata->outbuf + copy_len,
udata->outlen - copy_len))
goto err_fault;
}
return 0;
err_fault:
ibdev_dbg(
rdma_udata_to_dev(udata),
"System call driver out udata has EFAULT (%zu into %zu) for ioctl %ps called by %pSR\n",
len, udata->outlen, uverbs_get_handler_fn(udata),
__builtin_return_address(0));
return -EFAULT;
}
EXPORT_SYMBOL(_ib_respond_udata);
/*
* Must be called with the ufile->device->disassociate_srcu held, and the lock
* must be held until use of the ucontext is finished.
*/
struct ib_ucontext *ib_uverbs_get_ucontext_file(struct ib_uverbs_file *ufile)
{
/*
* We do not hold the hw_destroy_rwsem lock for this flow, instead
* srcu is used. It does not matter if someone races this with
* get_context, we get NULL or valid ucontext.
*/
struct ib_ucontext *ucontext = smp_load_acquire(&ufile->ucontext);
if (!srcu_dereference(ufile->device->ib_dev,
&ufile->device->disassociate_srcu))
return ERR_PTR(-EIO);
if (!ucontext)
return ERR_PTR(-EINVAL);
return ucontext;
}
EXPORT_SYMBOL(ib_uverbs_get_ucontext_file);
int uverbs_destroy_def_handler(struct uverbs_attr_bundle *attrs)
{
return 0;
}
EXPORT_SYMBOL(uverbs_destroy_def_handler);
/*
* When calling a destroy function during an error unwind we need to pass in
* the udata that is sanitized of all user arguments. Ie from the driver
* perspective it looks like no udata was passed.
Annotation
- Immediate include surface: `linux/xarray.h`, `linux/dma-buf.h`, `linux/dma-resv.h`, `uverbs.h`, `core_priv.h`, `rdma_core.h`.
- Detected declarations: `function rdma_umap_priv_init`, `function rdma_user_mmap_io`, `function rdma_user_mmap_entry_get_pgoff`, `function rdma_user_mmap_entry_get`, `function rdma_user_mmap_entry_free`, `function rdma_user_mmap_entry_put`, `function rdma_user_mmap_entry_remove`, `function rdma_user_mmap_entry_insert_range`, `function rdma_user_mmap_entry_insert`, `function uverbs_get_handler_fn`.
- Atlas domain: Driver Families / drivers/infiniband.
- Implementation status: integration implementation candidate.
- This snippet crosses the user/kernel memory boundary; validate fault handling and access checks before translating the pattern.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.