drivers/xen/grant-dma-ops.c
Source file repositories/reference/linux-study-clean/drivers/xen/grant-dma-ops.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/xen/grant-dma-ops.c- Extension
.c- Size
- 10362 bytes
- Lines
- 423
- Domain
- Driver Families
- Bucket
- drivers/xen
- 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 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
linux/module.hlinux/dma-map-ops.hlinux/of.hlinux/pci.hlinux/pfn.hlinux/xarray.hlinux/virtio_anchor.hlinux/virtio.hxen/xen.hxen/xen-ops.hxen/grant_table.h
Detected Declarations
struct xen_grant_dma_datafunction grant_to_dmafunction dma_to_grantfunction store_xen_grant_dma_datafunction frontendsfunction xen_grant_dma_freefunction xen_grant_dma_free_pagesfunction xen_grant_dma_map_physfunction xen_grant_dma_unmap_physfunction xen_grant_dma_unmap_sgfunction xen_grant_dma_map_sgfunction for_each_sgfunction xen_grant_dma_supportedfunction xen_dt_grant_init_backend_domidfunction xen_grant_init_backend_domidfunction xen_grant_setup_dma_opsfunction xen_virtio_restricted_mem_acc
Annotated Snippet
struct xen_grant_dma_data {
/* The ID of backend domain */
domid_t backend_domid;
/* Is device behaving sane? */
bool broken;
};
static DEFINE_XARRAY_FLAGS(xen_grant_dma_devices, XA_FLAGS_LOCK_IRQ);
#define XEN_GRANT_DMA_ADDR_OFF (1ULL << 63)
static inline dma_addr_t grant_to_dma(grant_ref_t grant)
{
return XEN_GRANT_DMA_ADDR_OFF | ((dma_addr_t)grant << XEN_PAGE_SHIFT);
}
static inline grant_ref_t dma_to_grant(dma_addr_t dma)
{
return (grant_ref_t)((dma & ~XEN_GRANT_DMA_ADDR_OFF) >> XEN_PAGE_SHIFT);
}
static struct xen_grant_dma_data *find_xen_grant_dma_data(struct device *dev)
{
struct xen_grant_dma_data *data;
unsigned long flags;
xa_lock_irqsave(&xen_grant_dma_devices, flags);
data = xa_load(&xen_grant_dma_devices, (unsigned long)dev);
xa_unlock_irqrestore(&xen_grant_dma_devices, flags);
return data;
}
static int store_xen_grant_dma_data(struct device *dev,
struct xen_grant_dma_data *data)
{
unsigned long flags;
int ret;
xa_lock_irqsave(&xen_grant_dma_devices, flags);
ret = xa_err(__xa_store(&xen_grant_dma_devices, (unsigned long)dev, data,
GFP_ATOMIC));
xa_unlock_irqrestore(&xen_grant_dma_devices, flags);
return ret;
}
/*
* DMA ops for Xen frontends (e.g. virtio).
*
* Used to act as a kind of software IOMMU for Xen guests by using grants as
* DMA addresses.
* Such a DMA address is formed by using the grant reference as a frame
* number and setting the highest address bit (this bit is for the backend
* to be able to distinguish it from e.g. a mmio address).
*/
static void *xen_grant_dma_alloc(struct device *dev, size_t size,
dma_addr_t *dma_handle, gfp_t gfp,
unsigned long attrs)
{
struct xen_grant_dma_data *data;
unsigned int i, n_pages = XEN_PFN_UP(size);
unsigned long pfn;
grant_ref_t grant;
void *ret;
data = find_xen_grant_dma_data(dev);
if (!data)
return NULL;
if (unlikely(data->broken))
return NULL;
ret = alloc_pages_exact(n_pages * XEN_PAGE_SIZE, gfp);
if (!ret)
return NULL;
pfn = virt_to_pfn(ret);
if (gnttab_alloc_grant_reference_seq(n_pages, &grant)) {
free_pages_exact(ret, n_pages * XEN_PAGE_SIZE);
return NULL;
}
for (i = 0; i < n_pages; i++) {
gnttab_grant_foreign_access_ref(grant + i, data->backend_domid,
pfn_to_gfn(pfn + i), 0);
}
*dma_handle = grant_to_dma(grant);
Annotation
- Immediate include surface: `linux/module.h`, `linux/dma-map-ops.h`, `linux/of.h`, `linux/pci.h`, `linux/pfn.h`, `linux/xarray.h`, `linux/virtio_anchor.h`, `linux/virtio.h`.
- Detected declarations: `struct xen_grant_dma_data`, `function grant_to_dma`, `function dma_to_grant`, `function store_xen_grant_dma_data`, `function frontends`, `function xen_grant_dma_free`, `function xen_grant_dma_free_pages`, `function xen_grant_dma_map_phys`, `function xen_grant_dma_unmap_phys`, `function xen_grant_dma_unmap_sg`.
- Atlas domain: Driver Families / drivers/xen.
- Implementation status: source implementation candidate.
- 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.