STRUCT DRM_XE_VM_BIND_OP(9)

πŸ“¦ version 7.3.1, in nixpkgs unstable

πŸ’… 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 for MAP_USERPTR, and MBZ for UNMAP too. πŸ’…
  • pat_index β€” the platform-defined pat_index to use for this mapping. like, the index basically maps to some predefined memory attributes β€” caching, coherency, compression, the whole vibe. the exact meaning of pat_index is 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_NONE
  • ppGTT WC -> COH_NONE
  • ppGTT WT -> COH_NONE
  • ppGTT 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 the pat_index. starting from NVL-P, for userptr, svm, madvise and externally imported dma-buf, the kernel expects either 2WAY or 1WAY and XA pat_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 for CLEAR_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 to addr. MBZ for UNMAP_ALL. πŸ“
  • addr β€” the address to operate on. MBZ for UNMAP_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 the DRM_XE_VM_BIND_OP_PREFETCH operation. πŸ’œ
  • 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_MAP
  • DRM_XE_VM_BIND_OP_UNMAP
  • DRM_XE_VM_BIND_OP_MAP_USERPTR
  • DRM_XE_VM_BIND_OP_UNMAP_ALL
  • DRM_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 for DRM_XE_VM_BIND_OP_MAP operations, 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 with DRM_XE_VM_CREATE_FLAG_FAULT_MODE set. the CPU address mirror flag is only valid for DRM_XE_VM_BIND_OP_MAP operations, the BO handle MBZ, and the BO offset MBZ. πŸͺž
  • DRM_XE_VM_BIND_FLAG_MADVISE_AUTORESET β€” can be used in combination with DRM_XE_VM_BIND_FLAG_CPU_ADDR_MIRROR to reset madvises when the underlying CPU address space range is unmapped (typically with munmap(2) or brk(2)). the madvise values set with DRM_IOCTL_XE_MADVISE are reset to the values that were present immediately after the DRM_IOCTL_XE_VM_BIND. the reset GPU virtual address range is the intersection of the range bound using DRM_IOCTL_XE_VM_BIND and the virtual CPU address space range unmapped. this functionality exists to mimic the behaviour of CPU address space madvises set using madvise(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 for DRM_XE_VM_BIND_OP_MAP; usage on other ops is rejected. the bind's pat_index must 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