linux/arch
Nikolay Kuratov 0d5c7fcfa5 KVM: x86/mmu: Ensure that kvm_release_pfn_clean() takes exact pfn from kvm_faultin_pfn()
Since 5.16 and prior to 6.13 KVM can't be used with FSDAX
guest memory (PMD pages). To reproduce the issue you need to reserve
guest memory with `memmap=` cmdline, create and mount FS in DAX mode
(tested both XFS and ext4), see doc link below. ndctl command for test:
ndctl create-namespace -v -e namespace1.0 --map=dev --mode=fsdax -a 2M
Then pass memory object to qemu like:
-m 8G -object memory-backend-file,id=ram0,size=8G,\
mem-path=/mnt/pmem/guestmem,share=on,prealloc=on,dump=off,align=2097152 \
-numa node,memdev=ram0,cpus=0-1
QEMU fails to run guest with error: kvm run failed Bad address
and there are two warnings in dmesg:
WARN_ON_ONCE(!page_count(page)) in kvm_is_zone_device_page() and
WARN_ON_ONCE(folio_ref_count(folio) <= 0) in try_grab_folio() (v6.6.63)

It looks like in the past assumption was made that pfn won't change from
faultin_pfn() to release_pfn_clean(), e.g. see
commit 4cd071d13c ("KVM: x86/mmu: Move calls to thp_adjust() down a level")
But kvm_page_fault structure made pfn part of mutable state, so
now release_pfn_clean() can take hugepage-adjusted pfn.
And it works for all cases (/dev/shm, hugetlb, devdax) except fsdax.
Apparently in fsdax mode faultin-pfn and adjusted-pfn may refer to
different folios, so we're getting get_page/put_page imbalance.

To solve this preserve faultin pfn in separate local variable
and pass it in kvm_release_pfn_clean().

Patch tested for all mentioned guest memory backends with tdp_mmu={0,1}.

No bug in upstream as it was solved fundamentally by
commit 8dd861cc07 ("KVM: x86/mmu: Put refcounted pages instead of blindly releasing pfns")
and related patch series.

Link: https://nvdimm.docs.kernel.org/2mib_fs_dax.html
Fixes: 2f6305dd56 ("KVM: MMU: change kvm_tdp_mmu_map() arguments to kvm_page_fault")
Co-developed-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Sean Christopherson <seanjc@google.com>
Reviewed-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Nikolay Kuratov <kniv@yandex-team.ru>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
History 2024-12-14 20:00:21 +01:00
..
alpha Revert "change alloc_pages name in dma_map_ops to avoid name conflicts" 2024-09-04 13:28:24 +02:00
arc of/fdt: add dt_phys arg to early_init_dt_scan and early_init_dt_verify 2024-12-09 10:31:56 +01:00
arm ARM: 9431/1: mm: Pair atomic_set_release() with _read_acquire() 2024-12-09 10:33:06 +01:00
arm64 arm64: ptrace: fix partial SETREGSET for NT_ARM_TAGGED_ADDR_CTRL 2024-12-14 19:59:52 +01:00
csky of/fdt: add dt_phys arg to early_init_dt_scan and early_init_dt_verify 2024-12-09 10:31:56 +01:00
hexagon hexagon: fix fadvise64_64 calling conventions 2024-07-05 09:34:02 +02:00
ia64 vgacon: rework screen_info #ifdef checks 2024-06-27 13:49:15 +02:00
loongarch LoongArch: Fix sleeping in atomic context for PREEMPT_RT 2024-12-14 20:00:15 +01:00
m68k m68k: coldfire/device.c: only build FEC when HW macros are defined 2024-12-09 10:32:28 +01:00
microblaze of/fdt: add dt_phys arg to early_init_dt_scan and early_init_dt_verify 2024-12-09 10:31:56 +01:00
mips MIPS: Loongson64: DTS: Really fix PCIe port nodes for ls7a 2024-12-14 20:00:16 +01:00
nios2 of/fdt: add dt_phys arg to early_init_dt_scan and early_init_dt_verify 2024-12-09 10:31:56 +01:00
openrisc openrisc: Use asm-generic's version of fix_to_virt() & virt_to_fix() 2024-12-11 16:13:43 +01:00
parisc parisc/ftrace: Fix function graph tracing disablement 2024-12-09 10:32:48 +01:00
powerpc powerpc/prom_init: Fixup missing powermac #size-cells 2024-12-14 20:00:16 +01:00
riscv RISC-V: KVM: Fix APLIC in_clrip and clripnum write emulation 2024-12-09 10:32:16 +01:00
s390 s390/cpum_sf: Handle CPU hotplug remove during sampling 2024-12-14 19:59:58 +01:00
sh sh: cpuinfo: Fix a warning for CONFIG_CPUMASK_OFFSTACK 2024-12-09 10:32:50 +01:00
sparc sparc64: Fix incorrect function signature and add prototype for prom_cif_init 2024-08-03 08:53:55 +02:00
um um: Always dump trace for specified task in show_stack 2024-12-09 10:32:54 +01:00
x86 KVM: x86/mmu: Ensure that kvm_release_pfn_clean() takes exact pfn from kvm_faultin_pfn() 2024-12-14 20:00:21 +01:00
xtensa of/fdt: add dt_phys arg to early_init_dt_scan and early_init_dt_verify 2024-12-09 10:31:56 +01:00
.gitignore .gitignore: prefix local generated files with a slash 2021-05-02 00:43:35 +09:00
Kconfig Revert "mm: mmap: allow for the maximum number of bits for randomizing mmap_base by default" 2024-06-27 13:49:15 +02:00