STRUCT DRM_XE_VM_BIND_OP(9)
π struct drm_xe_vm_bind_op(9) π
okay bestie, welcome to the Kernel API Manual β this is the page for struct drm_xe_vm_bind_op, and it's literally the "run bind operations" struct for the Xe driver. Buckle up, we're doing GPU virtual memory today and it's gonna eat. π₯
β¨ NAME β¨
struct drm_xe_vm_bind_op β run bind operations π«Ά
πΈ SYNOPSIS πΈ
struct drm_xe_vm_bind_op {
__u64 extensions;
__u32 obj;
__u16 pat_index;
__u16 pad;
union {
__u64 obj_offset;
__u64 userptr;
__s64 cpu_addr_mirror_offset;
};
__u64 range;
__u64 addr;
#define DRM_XE_VM_BIND_OP_MAP 0x0;
#define DRM_XE_VM_BIND_OP_UNMAP 0x1;
#define DRM_XE_VM_BIND_OP_MAP_USERPTR 0x2;
#define DRM_XE_VM_BIND_OP_UNMAP_ALL 0x3;
#define DRM_XE_VM_BIND_OP_PREFETCH 0x4;
__u32 op;
#define DRM_XE_VM_BIND_FLAG_READONLY (1 << 0);
#define DRM_XE_VM_BIND_FLAG_IMMEDIATE (1 << 1);
#define DRM_XE_VM_BIND_FLAG_NULL (1 << 2);
#define DRM_XE_VM_BIND_FLAG_DUMPABLE (1 << 3);
#define DRM_XE_VM_BIND_FLAG_CHECK_PXP (1 << 4);
#define DRM_XE_VM_BIND_FLAG_CPU_ADDR_MIRROR (1 << 5);
#define DRM_XE_VM_BIND_FLAG_MADVISE_AUTORESET (1 << 6);
#define DRM_XE_VM_BIND_FLAG_DECOMPRESS (1 << 7);
__u32 flags;
#define DRM_XE_CONSULT_MEM_ADVISE_PREF_LOC -1;
__u32 prefetch_mem_region_instance;
__u32 pad2;
__u64 reserved[3];
};
π«Ά Members π«Ά
extensionsβ pointer to the first extension struct, if there even is one. no extensions? fine, no cap. β¨objβ the GEM object we're operating on. MBZ forMAP_USERPTR, and MBZ forUNMAPtoo. πpat_indexβ the platform-definedpat_indexto use for this mapping. like, the index basically maps to some predefined memory attributes β caching, coherency, compression, the whole vibe. the exact meaning ofpat_indexis platform specific and defined in the Bspec and the PRMs. when the KMD sets up the binding, the index here gets encoded into the ppGTT PTE. π
for coherency, pat_index needs to be at least 1way coherent when drm_xe_gem_create.cpu_caching is DRM_XE_GEM_CPU_CACHING_WB. the KMD will extract the coherency mode from the pat_index and reject if there's a mismatch (peep the note below for pre-MTL platforms, iykyk).
Note: on pre-MTL platforms there's only a caching mode and no explicit coherency mode β but on that hardware there's always a shared-LLC (or it's a dgpu), so all GT memory accesses are coherent with CPU caches even with the caching mode set as uncached. it's only the display engine that's incoherent (on a dgpu it must be in VRAM, which is always mapped as WC on the CPU). however, to keep the uapi somewhat consistent with newer platforms, the KMD groups the different cache levels into the following coherency buckets on all pre-MTL platforms:
ppGTT UC -> COH_NONEppGTT WC -> COH_NONEppGTT WT -> COH_NONEppGTT WB -> COH_AT_LEAST_1WAY
in practice UC/WC/WT should only ever be used for scanout surfaces on such platforms (or maybe in general for dma-buf if it's shared with another device), since it's only the display engine that's actually incoherent. everything else should typically use WB, given that we have a shared-LLC. on MTL+ this completely changes and the HW defines the coherency mode as part of the pat_index, where incoherent GT access is possible. π
Note: for userptr and externally imported dma-buf, the kernel expects either 1WAY or 2WAY for thepat_index. starting from NVL-P, for userptr, svm, madvise and externally imported dma-buf, the kernel expects either 2WAY or 1WAY and XApat_index. π¦
for DRM_XE_VM_BIND_FLAG_NULL bindings there are no KMD restrictions on the pat_index. for such mappings there's no actual memory being mapped (the address in the PTE is invalid), so the various PAT memory attributes likely don't apply. simply leaving it as zero is one option (still a valid pat_index). same applies to DRM_XE_VM_BIND_FLAG_CPU_ADDR_MIRROR bindings, since for such a mapping there's no actual memory being mapped. π
padβ MBZ π«Ά{unnamed_union}β anonymous, mysterious, iconic. β¨obj_offsetβ offset into the object. MBZ forCLEAR_RANGE, ignored for unbind.userptrβ user pointer to bind on. π§cpu_addr_mirror_offsetβ offset from the GPU addr, used to create CPU address mirror mappings. MBZ with the current level of support (like, only 1 to 1 mapping between GPU and CPU mappings is supported rn).rangeβ number of bytes from the object to bind toaddr. MBZ forUNMAP_ALL. πaddrβ the address to operate on. MBZ forUNMAP_ALL. πopβ which bind operation to perform. π¬flagsβ the bind flags. π©prefetch_mem_region_instanceβ memory region to prefetch the VMA to. it's a region instance, not a mask (say it louder for the people in the back). to be used only with theDRM_XE_VM_BIND_OP_PREFETCHoperation. πpad2β MBZ. πreservedβ reserved. that's it, that's the whole note. π€«
π₯ Description π₯
so, the op can be any of these besties:
DRM_XE_VM_BIND_OP_MAPDRM_XE_VM_BIND_OP_UNMAPDRM_XE_VM_BIND_OP_MAP_USERPTRDRM_XE_VM_BIND_OP_UNMAP_ALLDRM_XE_VM_BIND_OP_PREFETCH
aaaand the flags can be:
DRM_XE_VM_BIND_FLAG_READONLYβ sets up the page tables as read-only so write protection is, like, enforced. πDRM_XE_VM_BIND_FLAG_IMMEDIATEβ on a faulting VM, do the MAP operation immediately instead of deferring the MAP to the page fault handler. this is implied on a non-faulting VM, because there's no fault handler to defer to. no cap. β‘DRM_XE_VM_BIND_FLAG_NULLβ when the NULL flag is set, the page tables get set up with a special bit that indicates writes are dropped and all reads return zero. in the future, the NULL flags will only be valid forDRM_XE_VM_BIND_OP_MAPoperations, the BO handle MBZ, and the BO offset MBZ. this flag is intended to implement VK sparse bindings. π³οΈDRM_XE_VM_BIND_FLAG_CHECK_PXPβ if the object is encrypted via PXP, reject the binding if the encryption key is no longer valid. this flag has no effect on BOs that aren't marked as using PXP. πDRM_XE_VM_BIND_FLAG_CPU_ADDR_MIRRORβ when the CPU address mirror flag is set, no mappings are created β instead the range is reserved for CPU address mirroring, which will get populated on GPU page faults or prefetches. only valid on VMs withDRM_XE_VM_CREATE_FLAG_FAULT_MODEset. the CPU address mirror flag is only valid forDRM_XE_VM_BIND_OP_MAPoperations, the BO handle MBZ, and the BO offset MBZ. πͺDRM_XE_VM_BIND_FLAG_MADVISE_AUTORESETβ can be used in combination withDRM_XE_VM_BIND_FLAG_CPU_ADDR_MIRRORto reset madvises when the underlying CPU address space range is unmapped (typically withmunmap(2)orbrk(2)). the madvise values set withDRM_IOCTL_XE_MADVISEare reset to the values that were present immediately after theDRM_IOCTL_XE_VM_BIND. the reset GPU virtual address range is the intersection of the range bound usingDRM_IOCTL_XE_VM_BINDand the virtual CPU address space range unmapped. this functionality exists to mimic the behaviour of CPU address space madvises set usingmadvise(2), which are typically reset on unmap. π§
π Note π
free(3) may or may not call munmap(2) and/or brk(2), and may thus not invoke autoreset. neither will stack variables going out of scope. therefore it's recommended to always explicitly reset the madvises when freeing the memory backing a region used in a DRM_IOCTL_XE_MADVISE call. fr fr, don't skip this one. π
DRM_XE_VM_BIND_FLAG_DECOMPRESSβ request on-device decompression for a MAP. when set on a MAP bind operation, request the driver schedule an on-device in-place decompression (via the migrate/resolve path) for the GPU mapping created by this bind. only valid forDRM_XE_VM_BIND_OP_MAP; usage on other ops is rejected. the bind'spat_indexmust select the device's "no-compression" PAT. only meaningful for VRAM-backed BOs on devices that support Flat CCS and the required HW generation XE2+. ποΈ
the prefetch_mem_region_instance for DRM_XE_VM_BIND_OP_PREFETCH can also be:
DRM_XE_CONSULT_MEM_ADVISE_PREF_LOCβ which ensures prefetching occurs in the memory region advised by madvise. π
π SEE ALSO π
kernel file ./include/uapi/drm/xe_drm.h, plus the whole squad:
Xe Device Block Diagram(9)Xe uAPI Overview(9)Xe IOCTL Extensions(9)struct drm_xe_user_extension(9)struct drm_xe_ext_set_property(9)struct drm_xe_engine_class_instance(9)struct drm_xe_engine(9)struct drm_xe_query_engines(9)enum drm_xe_memory_class(9)struct drm_xe_mem_region(9)struct drm_xe_query_mem_regions(9)struct drm_xe_query_config(9)struct drm_xe_gt(9)struct drm_xe_query_gt_list(9)struct drm_xe_query_topology_mask(9)struct drm_xe_query_engine_cycles(9)struct drm_xe_query_uc_fw_version(9)struct drm_xe_query_pxp_status(9)struct drm_xe_device_query(9)struct drm_xe_gem_create(9)struct drm_xe_gem_mmap_offset(9)struct drm_xe_vm_create(9)struct drm_xe_vm_destroy(9)struct drm_xe_vm_bind(9)struct drm_xe_vm_get_property(9)struct drm_xe_exec_queue_create(9)struct drm_xe_exec_queue_destroy(9)struct drm_xe_exec_queue_get_property(9)struct drm_xe_sync(9)struct drm_xe_exec(9)struct drm_xe_wait_user_fence(9)enum drm_xe_observation_type(9)enum drm_xe_observation_op(9)struct drm_xe_observation_param(9)enum drm_xe_observation_ioctls(9)enum drm_xe_oa_unit_type(9)struct drm_xe_oa_unit(9)struct drm_xe_query_oa_units(9)enum drm_xe_oa_format_type(9)enum drm_xe_oa_property_id(9)struct drm_xe_oa_config(9)struct drm_xe_oa_stream_status(9)struct drm_xe_oa_stream_info(9)enum drm_xe_pxp_session_type(9)enum drm_xe_eu_stall_property_id(9)struct drm_xe_query_eu_stall(9)struct drm_xe_madvise(9)struct drm_xe_mem_range_attr(9)struct drm_xe_vm_query_mem_range_attr(9)struct drm_xe_exec_queue_set_property(9)Xe DRM RAS(9)enum drm_xe_ras_error_severity(9)enum drm_xe_ras_error_component(9)
and that's the whole page, bestie! π this one shipped out of ./include/uapi/drm, dated October 2026, and it's struct drm_xe_vm_bind_op(9) forever and always. go bind something iconic. π π
π¦ where this page comes from
- nixpkgs unstable: linux-manual 7.3.1
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms