kvm_gmem_get_policy() sets *ilx to the full page offset (vm_pgoff + vma offset). But get_vma_policy() adds the page offset on top of *ilx, so the offset is counted twice. This causes NUMA interleaving to skip nodes: for order-0 pages the effective index jumps by 2 for each consecutive page. The get_policy vm_op should return only a per-file bias in *ilx (like shmem_get_policy does with inode->i_ino), letting get_vma_policy() add the page-offset component. Fix by setting *ilx to inode->i_ino instead of the full page offset. The page offset is computed by get_vma_policy() in mm/mempolicy.c. The full offset is still computed in kvm_gmem_get_policy() for mpol_shared_policy_lookup(). shmem_get_policy() follows the same pattern. Found by Sashiko (sashiko.dev) AI code review. Fixes: ed1ffa810bd6 ("KVM: guest_memfd: Enforce NUMA mempolicy using shared policy") Cc: Sean Christopherson Cc: Paolo Bonzini Assisted-by: Claude:claude-opus-4-6 Signed-off-by: Michael S. Tsirkin --- virt/kvm/guest_memfd.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c index 69c9d6d546b2..0bcf6fc08e2d 100644 --- a/virt/kvm/guest_memfd.c +++ b/virt/kvm/guest_memfd.c @@ -438,11 +438,12 @@ static int kvm_gmem_set_policy(struct vm_area_struct *vma, struct mempolicy *mpo } static struct mempolicy *kvm_gmem_get_policy(struct vm_area_struct *vma, - unsigned long addr, pgoff_t *pgoff) + unsigned long addr, pgoff_t *ilx) { struct inode *inode = file_inode(vma->vm_file); + pgoff_t pgoff = vma->vm_pgoff + ((addr - vma->vm_start) >> PAGE_SHIFT); - *pgoff = vma->vm_pgoff + ((addr - vma->vm_start) >> PAGE_SHIFT); + *ilx = inode->i_ino; /* * Return the memory policy for this index, or NULL if none is set. @@ -453,7 +454,7 @@ static struct mempolicy *kvm_gmem_get_policy(struct vm_area_struct *vma, * can then replace NULL with the default memory policy instead of the * current task's memory policy. */ - return mpol_shared_policy_lookup(&GMEM_I(inode)->policy, *pgoff); + return mpol_shared_policy_lookup(&GMEM_I(inode)->policy, pgoff); } #endif /* CONFIG_NUMA */ -- MST