drivers/vhost/vringh.c
Source file repositories/reference/linux-study-clean/drivers/vhost/vringh.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/vhost/vringh.c- Extension
.c- Size
- 39568 bytes
- Lines
- 1500
- Domain
- Driver Families
- Bucket
- drivers/vhost
- 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/compiler.hlinux/module.hlinux/vringh.hlinux/virtio_ring.hlinux/kernel.hlinux/ratelimit.hlinux/uaccess.hlinux/slab.hlinux/export.hlinux/bvec.hlinux/highmem.hlinux/vhost_iotlb.huapi/linux/virtio_config.h
Detected Declarations
struct iotlb_vecfunction __printffunction __vringh_get_headfunction vringh_kiov_advancefunction vringh_iov_xferfunction range_checkfunction no_range_checkfunction move_to_indirectfunction resize_iovecfunction return_from_indirectfunction slow_copyfunction __vringh_iovfunction __vringh_completefunction __vringh_need_notifyfunction __vringh_notify_enablefunction __vringh_notify_disablefunction getu16_userfunction putu16_userfunction copydesc_userfunction putused_userfunction xfer_from_userfunction xfer_to_userfunction vringh_init_userfunction vringh_iov_cleanupfunction vringh_iov_pull_userfunction vringh_iov_push_userfunction vringh_need_notify_userfunction vringh_need_notify_userfunction vringh_notify_enable_userfunction vringh_notify_disable_userfunction vringh_need_notify_userfunction getu16_kernfunction putu16_kernfunction copydesc_kernfunction putused_kernfunction vringh_init_kernfunction vringh_kiov_cleanupfunction vringh_need_notify_kernfunction vringh_notify_enable_kernfunction vringh_notify_disable_kernfunction vringh_need_notify_kernfunction iotlb_translatefunction copy_from_iotlbfunction copy_to_iotlbfunction getu16_iotlbfunction putu16_iotlbfunction copydesc_iotlbfunction xfer_from_iotlb
Annotated Snippet
struct iotlb_vec {
union {
struct iovec *iovec;
struct bio_vec *bvec;
} iov;
size_t count;
};
static int iotlb_translate(const struct vringh *vrh,
u64 addr, u64 len, u64 *translated,
struct iotlb_vec *ivec, u32 perm)
{
struct vhost_iotlb_map *map;
struct vhost_iotlb *iotlb = vrh->iotlb;
int ret = 0;
u64 s = 0, last = addr + len - 1;
spin_lock(vrh->iotlb_lock);
while (len > s) {
uintptr_t io_addr;
size_t io_len;
u64 size;
if (unlikely(ret >= ivec->count)) {
ret = -ENOBUFS;
break;
}
map = vhost_iotlb_itree_first(iotlb, addr, last);
if (!map || map->start > addr) {
ret = -EINVAL;
break;
} else if (!(map->perm & perm)) {
ret = -EPERM;
break;
}
size = map->size - addr + map->start;
io_len = min(len - s, size);
io_addr = map->addr - map->start + addr;
if (vrh->use_va) {
struct iovec *iovec = ivec->iov.iovec;
iovec[ret].iov_len = io_len;
iovec[ret].iov_base = (void __user *)io_addr;
} else {
u64 pfn = io_addr >> PAGE_SHIFT;
struct bio_vec *bvec = ivec->iov.bvec;
bvec_set_page(&bvec[ret], pfn_to_page(pfn), io_len,
io_addr & (PAGE_SIZE - 1));
}
s += size;
addr += size;
++ret;
}
spin_unlock(vrh->iotlb_lock);
if (translated)
*translated = min(len, s);
return ret;
}
#define IOTLB_IOV_STRIDE 16
static inline int copy_from_iotlb(const struct vringh *vrh, void *dst,
void *src, size_t len)
{
struct iotlb_vec ivec;
union {
struct iovec iovec[IOTLB_IOV_STRIDE];
struct bio_vec bvec[IOTLB_IOV_STRIDE];
} iov;
u64 total_translated = 0;
ivec.iov.iovec = iov.iovec;
ivec.count = IOTLB_IOV_STRIDE;
while (total_translated < len) {
struct iov_iter iter;
u64 translated;
int ret;
size_t size;
ret = iotlb_translate(vrh, (u64)(uintptr_t)src,
Annotation
- Immediate include surface: `linux/compiler.h`, `linux/module.h`, `linux/vringh.h`, `linux/virtio_ring.h`, `linux/kernel.h`, `linux/ratelimit.h`, `linux/uaccess.h`, `linux/slab.h`.
- Detected declarations: `struct iotlb_vec`, `function __printf`, `function __vringh_get_head`, `function vringh_kiov_advance`, `function vringh_iov_xfer`, `function range_check`, `function no_range_check`, `function move_to_indirect`, `function resize_iovec`, `function return_from_indirect`.
- Atlas domain: Driver Families / drivers/vhost.
- 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.