drivers/accel/amdxdna/amdxdna_ubuf.c
Source file repositories/reference/linux-study-clean/drivers/accel/amdxdna/amdxdna_ubuf.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/accel/amdxdna/amdxdna_ubuf.c- Extension
.c- Size
- 4346 bytes
- Lines
- 188
- Domain
- Driver Families
- Bucket
- drivers/accel
- Inferred role
- Driver Families: implementation source
- Status
- source 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.
- Touches user memory; correctness depends on fault-safe copying and privilege boundary handling.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- 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
drm/amdxdna_accel.hdrm/drm_device.hdrm/drm_print.hlinux/dma-buf.hlinux/overflow.hlinux/pagemap.hlinux/vmalloc.hamdxdna_pci_drv.hamdxdna_ubuf.h
Detected Declarations
struct amdxdna_ubuf_privfunction amdxdna_ubuf_unmapfunction amdxdna_ubuf_release
Annotated Snippet
struct amdxdna_ubuf_priv {
struct page **pages;
u64 nr_pages;
struct mm_struct *mm;
};
static struct sg_table *amdxdna_ubuf_map(struct dma_buf_attachment *attach,
enum dma_data_direction direction)
{
struct amdxdna_ubuf_priv *ubuf = attach->dmabuf->priv;
struct sg_table *sg;
int ret;
sg = kzalloc_obj(*sg);
if (!sg)
return ERR_PTR(-ENOMEM);
ret = sg_alloc_table_from_pages(sg, ubuf->pages, ubuf->nr_pages, 0,
ubuf->nr_pages << PAGE_SHIFT, GFP_KERNEL);
if (ret)
goto err_free_sg;
ret = dma_map_sgtable(attach->dev, sg, direction, 0);
if (ret)
goto err_free_table;
return sg;
err_free_table:
sg_free_table(sg);
err_free_sg:
kfree(sg);
return ERR_PTR(ret);
}
static void amdxdna_ubuf_unmap(struct dma_buf_attachment *attach,
struct sg_table *sg,
enum dma_data_direction direction)
{
dma_unmap_sgtable(attach->dev, sg, direction, 0);
sg_free_table(sg);
kfree(sg);
}
static void amdxdna_ubuf_release(struct dma_buf *dbuf)
{
struct amdxdna_ubuf_priv *ubuf = dbuf->priv;
unpin_user_pages(ubuf->pages, ubuf->nr_pages);
kvfree(ubuf->pages);
atomic64_sub(ubuf->nr_pages, &ubuf->mm->pinned_vm);
mmdrop(ubuf->mm);
kfree(ubuf);
}
static const struct dma_buf_ops amdxdna_ubuf_dmabuf_ops = {
.map_dma_buf = amdxdna_ubuf_map,
.unmap_dma_buf = amdxdna_ubuf_unmap,
.release = amdxdna_ubuf_release,
};
struct dma_buf *amdxdna_get_ubuf(struct drm_device *dev,
u32 num_entries, void __user *va_entries)
{
struct amdxdna_dev *xdna = to_xdna_dev(dev);
unsigned long lock_limit, new_pinned;
struct amdxdna_drm_va_entry *va_ent;
struct amdxdna_ubuf_priv *ubuf;
u32 npages, start = 0;
struct dma_buf *dbuf;
int i, ret;
DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
if (!can_do_mlock())
return ERR_PTR(-EPERM);
ubuf = kzalloc_obj(*ubuf);
if (!ubuf)
return ERR_PTR(-ENOMEM);
ubuf->mm = current->mm;
mmgrab(ubuf->mm);
va_ent = kvzalloc_objs(*va_ent, num_entries);
if (!va_ent) {
ret = -ENOMEM;
goto free_ubuf;
}
if (copy_from_user(va_ent, va_entries, sizeof(*va_ent) * num_entries)) {
Annotation
- Immediate include surface: `drm/amdxdna_accel.h`, `drm/drm_device.h`, `drm/drm_print.h`, `linux/dma-buf.h`, `linux/overflow.h`, `linux/pagemap.h`, `linux/vmalloc.h`, `amdxdna_pci_drv.h`.
- Detected declarations: `struct amdxdna_ubuf_priv`, `function amdxdna_ubuf_unmap`, `function amdxdna_ubuf_release`.
- Atlas domain: Driver Families / drivers/accel.
- Implementation status: source implementation candidate.
- This snippet crosses the user/kernel memory boundary; validate fault handling and access checks before translating the pattern.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
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.