从这一篇起进入具体用例。第 3 篇讲了 foreign 映射——把另一个域的页装进本域 physmap。hmem 就是 foreign 映射的一个用例:host→guest方向的共享——把host(dom0)侧的内存映射进 guest 的物理地址空间,让 guest 与 host 共享同一份物理页(零拷贝)。对称预告:反方向的guest→host共享(把 guest 的地址交给 host 用)是第 9 篇的 userptr。两者是 foreign 思路在两个方向上的用例。前置:已读 01(三层地址 / EPT)、02(EPT violation + IOREQ)、03(p2m 类型 + foreign 映射)。1. 定位与触发链先说清 hmem 为什么存在——一句话:给 Xen 补上 KVM 早就有的"把 host 用户态内存映射进 guest"的能力。要把 dom0 用户态的一段内存映射进 guest 的物理地址空间,两个平台待遇不同:KVM 天生支持:qemu 用KVM_SET_USER_MEMORY_REGION就能把自己的一段用户内存直接挂进 guest physmap,virtio-gpu 的 host 内存 blob 顺理成章。Xen 没有对应原生接口:guest 的 p2m 由 hypervisor 独占,最接近的只有 foreign 映射(把另一个域的页装进来),并没有"把 dom0 用户态内存一键映射进 guest"的现成能力。hmem 就是在 foreign 映射之上,做出 KVMKVM_SET_USER_MEMORY_REGION的等价物,专门给 virtio-gpu 的 host 内存 blob BAR 兜底。guest 侧应用通过一段 host-visible 窗口零拷贝直接读写 host GPU 资源(blob:dmabuf / shmem / ROCm 显存),典型场景:drm_native_context:guest 里的原生 GPU 驱动把 host GPU 的 BO 映射进窗口做零拷贝渲染。rocm:guest 的 ROCm/HIP 经 hsakmt 把 host GPU 显存 blob 暴露给 guest 做 compute。venus (Vulkan):VkDeviceMemory的 host-visible 堆走同一窗口。关键设计目标:窗口可以很大(数十 GB),但物理内存按需占用——采用 demand-paged(缺页按需映射)而非一次性 populate。这条“窗口大、物理按需”正是下面hmem.c要实现的核心。本篇范围:只讲 hmem 在dom0 内核侧的映射器实现(hmem.c)——数据结构、取页、一致性、slot 管理。它上游的 QEMU 建窗口/BAR、virglrenderer 导出 blob、ROCm、配置参数,以及guest→QEMU→Xen→dom0 的全栈端到端时序,见 第 6 篇 hostmem。接着第 3 篇的定位——hmem = foreign 映射的host→guest用例,并在其上加四样东西:新入口XENMAPSPACE_gmfn_host、懒映射(IOREQ_TYPE_HMEM)、mmu_interval_notifier一致性、按 domid+GFN 区间管理。hmem.c就是它在dom0 内核侧的实现——一个"按 domid + GFN 区间管理的 p2m 映射器":让 guest 的 GFN 直接映射到 dom0 某段 HVA 背后的真实页(HFN/MFN),并在 host 页变动时同步撤销。它怎么被触发?把第 2 篇的通用 IOREQ 路径实例化到 hmem:dom0 hmem.cdom0 QEMUXenGuest (CPU)dom0 hmem.cdom0 QEMUXenGuest (CPU)
