* [PATCH 1/2] KVM: guest_memfd: Always use order 0 when allocating for guest_memfd [not found] <cover.1770148108.git.ackerleytng@google.com> @ 2026-02-03 22:50 ` Ackerley Tng 2026-02-03 22:00 ` [syzbot] [kvm?] WARNING in kvm_gmem_fault_user_mapping syzbot 2026-02-04 12:36 ` [PATCH 1/2] KVM: guest_memfd: Always use order 0 when allocating for guest_memfd Deepanshu Kartikey 0 siblings, 2 replies; 4+ messages in thread From: Ackerley Tng @ 2026-02-03 22:50 UTC (permalink / raw) To: syzbot+33a04338019ac7e43a44 Cc: kartikey406, linux-kernel, syzkaller-bugs, Ackerley Tng #syz test: git://git.kernel.org/pub/scm/virt/kvm/kvm.git next filemap_{grab,get}_folio() and related functions, used since the early stages of guest_memfd have determined the order of the folio to be allocated by looking up mapping_min_folio_order(mapping). As identified by syzbot, MADV_HUGEPAGE can be used to set the result of mapping_min_folio_order() to a value greater than 0, leading to the allocation of a huge page and subsequent WARNing. Refactor the allocation code of guest_memfd to directly use filemap_add_folio(), specifying an order of 0. This refactoring replaces the original functionality where FGP_LOCK and FGP_CREAT are requested. Opportunistically drop functionality provided by FGP_ACCESSED. guest_memfd folios don't care about accessed flags because guest_memfd memory is unevictable and there is no storage to write back to. Reported-by: syzbot+33a04338019ac7e43a44@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=33a04338019ac7e43a44 Tested-by: syzbot+33a04338019ac7e43a44@syzkaller.appspotmail.com Signed-off-by: Ackerley Tng <ackerleytng@google.com> --- virt/kvm/guest_memfd.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c index fdaea3422c30..0c58f6aa5609 100644 --- a/virt/kvm/guest_memfd.c +++ b/virt/kvm/guest_memfd.c @@ -135,23 +135,35 @@ static struct folio *kvm_gmem_get_folio(struct inode *inode, pgoff_t index) /* TODO: Support huge pages. */ struct mempolicy *policy; struct folio *folio; + gfp_t gfp; + int ret; /* * Fast-path: See if folio is already present in mapping to avoid * policy_lookup. */ +repeat: folio = __filemap_get_folio(inode->i_mapping, index, FGP_LOCK | FGP_ACCESSED, 0); if (!IS_ERR(folio)) return folio; + gfp = mapping_gfp_mask(inode->i_mapping); + policy = mpol_shared_policy_lookup(&GMEM_I(inode)->policy, index); - folio = __filemap_get_folio_mpol(inode->i_mapping, index, - FGP_LOCK | FGP_ACCESSED | FGP_CREAT, - mapping_gfp_mask(inode->i_mapping), policy); + folio = filemap_alloc_folio(gfp, 0, policy); mpol_cond_put(policy); + if (!folio) + return ERR_PTR(-ENOMEM); - return folio; + ret = filemap_add_folio(inode->i_mapping, folio, index, gfp); + if (ret) + folio_put(folio); + + if (ret == -EEXIST) + goto repeat; + + return ret ? ERR_PTR(ret) : folio; } static enum kvm_gfn_range_filter kvm_gmem_get_invalidate_filter(struct inode *inode) -- 2.53.0.rc2.204.g2597b5adb4-goog ^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [syzbot] [kvm?] WARNING in kvm_gmem_fault_user_mapping 2026-02-03 22:50 ` [PATCH 1/2] KVM: guest_memfd: Always use order 0 when allocating for guest_memfd Ackerley Tng @ 2026-02-03 22:00 ` syzbot 2026-02-04 12:36 ` [PATCH 1/2] KVM: guest_memfd: Always use order 0 when allocating for guest_memfd Deepanshu Kartikey 1 sibling, 0 replies; 4+ messages in thread From: syzbot @ 2026-02-03 22:00 UTC (permalink / raw) To: ackerleytng, linux-kernel, syzkaller-bugs Hello, syzbot tried to test the proposed patch but the build/boot failed: [ T5892] bridge0: port 1(bridge_slave_0) entered disabled state [ 81.250782][ T5892] bridge_slave_0: entered allmulticast mode [ 81.258962][ T5892] bridge_slave_0: entered promiscuous mode [ 81.278262][ T5892] bridge0: port 2(bridge_slave_1) entered blocking state [ 81.285839][ T5892] bridge0: port 2(bridge_slave_1) entered disabled state [ 81.293092][ T5892] bridge_slave_1: entered allmulticast mode [ 81.300579][ T5892] bridge_slave_1: entered promiscuous mode [ 81.323935][ T5892] bond0: (slave bond_slave_0): Enslaving as an active interface with an up link [ 81.334917][ T5892] bond0: (slave bond_slave_1): Enslaving as an active interface with an up link [ 81.359447][ T5892] team0: Port device team_slave_0 added [ 81.367513][ T5892] team0: Port device team_slave_1 added [ 81.408524][ T5892] batman_adv: batadv0: Adding interface: batadv_slave_0 [ 81.415517][ T5892] batman_adv: batadv0: The MTU of interface batadv_slave_0 is too small (1500) to handle the transport of batman-adv packets. Packets going over this interface will be fragmented on layer2 which could impact the performance. Setting the MTU to 1532 would solve the problem. [ 81.441455][ T5892] batman_adv: batadv0: Not using interface batadv_slave_0 (retrying later): interface not active [ 81.453632][ T5892] batman_adv: batadv0: Adding interface: batadv_slave_1 [ 81.460613][ T5892] batman_adv: batadv0: The MTU of interface batadv_slave_1 is too small (1500) to handle the transport of batman-adv packets. Packets going over this interface will be fragmented on layer2 which could impact the performance. Setting the MTU to 1532 would solve the problem. [ 81.488313][ T925] cfg80211: failed to load regulatory.db [ 81.495132][ T5892] batman_adv: batadv0: Not using interface batadv_slave_1 (retrying later): interface not active [ 81.579848][ T5892] hsr_slave_0: entered promiscuous mode [ 81.586459][ T5892] hsr_slave_1: entered promiscuous mode [ 81.772551][ T5892] netdevsim netdevsim1 netdevsim0: renamed from eth0 [ 81.785274][ T5892] netdevsim netdevsim1 netdevsim1: renamed from eth1 [ 81.794987][ T5892] netdevsim netdevsim1 netdevsim2: renamed from eth2 [ 81.804459][ T5892] netdevsim netdevsim1 netdevsim3: renamed from eth3 [ 81.830752][ T5892] bridge0: port 2(bridge_slave_1) entered blocking state [ 81.837931][ T5892] bridge0: port 2(bridge_slave_1) entered forwarding state [ 81.846102][ T5892] bridge0: port 1(bridge_slave_0) entered blocking state [ 81.853188][ T5892] bridge0: port 1(bridge_slave_0) entered forwarding state [ 81.897540][ T5892] 8021q: adding VLAN 0 to HW filter on device bond0 [ 81.910890][ T1309] bridge0: port 1(bridge_slave_0) entered disabled state [ 81.920082][ T1309] bridge0: port 2(bridge_slave_1) entered disabled state [ 81.938230][ T5892] 8021q: adding VLAN 0 to HW filter on device team0 [ 81.950068][ T4559] bridge0: port 1(bridge_slave_0) entered blocking state [ 81.957340][ T4559] bridge0: port 1(bridge_slave_0) entered forwarding state [ 81.970244][ T1309] bridge0: port 2(bridge_slave_1) entered blocking state [ 81.977416][ T1309] bridge0: port 2(bridge_slave_1) entered forwarding state [ 82.117812][ T5892] 8021q: adding VLAN 0 to HW filter on device batadv0 [ 82.154991][ T5892] veth0_vlan: entered promiscuous mode [ 82.165350][ T5892] veth1_vlan: entered promiscuous mode [ 82.191094][ T5892] veth0_macvtap: entered promiscuous mode [ 82.199927][ T5892] veth1_macvtap: entered promiscuous mode [ 82.216210][ T5892] batman_adv: batadv0: Interface activated: batadv_slave_0 [ 82.231786][ T5892] batman_adv: batadv0: Interface activated: batadv_slave_1 [ 82.244797][ T1309] netdevsim netdevsim1 netdevsim0: set [1, 0] type 2 family 0 port 6081 - 0 [ 82.261190][ T1309] netdevsim netdevsim1 netdevsim1: set [1, 0] type 2 family 0 port 6081 - 0 [ 82.270821][ T1309] netdevsim netdevsim1 netdevsim2: set [1, 0] type 2 family 0 port 6081 - 0 [ 82.284641][ T1309] netdevsim netdevsim1 netdevsim3: set [1, 0] type 2 family 0 port 6081 - 0 2026/02/03 21:59:31 executed programs: 0 [ 82.372872][ T5875] Bluetooth: hci0: unexpected cc 0x0c03 length: 249 > 1 [ 82.382293][ T5875] Bluetooth: hci0: unexpected cc 0x1003 length: 249 > 9 [ 82.390483][ T5875] Bluetooth: hci0: unexpected cc 0x1001 length: 249 > 9 [ 82.399377][ T5875] Bluetooth: hci0: unexpected cc 0x0c23 length: 249 > 4 [ 82.407179][ T5875] Bluetooth: hci0: unexpected cc 0x0c38 length: 249 > 2 [ 82.532003][ T5934] chnl_net:caif_netlink_parms(): no params data found [ 82.594483][ T5934] bridge0: port 1(bridge_slave_0) entered blocking state [ 82.602243][ T5934] bridge0: port 1(bridge_slave_0) entered disabled state [ 82.609657][ T5934] bridge_slave_0: entered allmulticast mode [ 82.616572][ T5934] bridge_slave_0: entered promiscuous mode [ 82.626770][ T5934] bridge0: port 2(bridge_slave_1) entered blocking state [ 82.634336][ T5934] bridge0: port 2(bridge_slave_1) entered disabled state [ 82.641777][ T5934] bridge_slave_1: entered allmulticast mode [ 82.648703][ T5934] bridge_slave_1: entered promiscuous mode [ 82.680172][ T5934] bond0: (slave bond_slave_0): Enslaving as an active interface with an up link [ 82.691594][ T5934] bond0: (slave bond_slave_1): Enslaving as an active interface with an up link [ 82.716205][ T5934] team0: Port device team_slave_0 added [ 82.723696][ T5934] team0: Port device team_slave_1 added [ 82.743136][ T5934] batman_adv: batadv0: Adding interface: batadv_slave_0 [ 82.750263][ T5934] batman_adv: batadv0: The MTU of interface batadv_slave_0 is too small (1500) to handle the transport of batman-adv packets. Packets going over this interface will be fragmented on layer2 which could impact the performance. Setting the MTU to 1532 would solve the problem. [ 82.777401][ T5934] batman_adv: batadv0: Not using interface batadv_slave_0 (retrying later): interface not active [ 82.789795][ T5934] batman_adv: batadv0: Adding interface: batadv_slave_1 [ 82.796831][ T5934] batman_adv: batadv0: The MTU of interface batadv_slave_1 is too small (1500) to handle the transport of batman-adv packets. Packets going over this interface will be fragmented on layer2 which could impact the performance. Setting the MTU to 1532 would solve the problem. [ 82.822826][ T5934] batman_adv: batadv0: Not using interface batadv_slave_1 (retrying later): interface not active [ 82.861709][ T5934] hsr_slave_0: entered promiscuous mode [ 82.868122][ T5934] hsr_slave_1: entered promiscuous mode [ 82.874061][ T5934] debugfs: 'hsr0' already exists in 'hsr' [ 82.879937][ T5934] Cannot create hsr debugfs directory [ 82.991829][ T5934] netdevsim netdevsim0 netdevsim0: renamed from eth0 [ 83.001861][ T5934] netdevsim netdevsim0 netdevsim1: renamed from eth1 [ 83.013215][ T5934] netdevsim netdevsim0 netdevsim2: renamed from eth2 [ 83.023136][ T5934] netdevsim netdevsim0 netdevsim3: renamed from eth3 [ 83.050741][ T5934] bridge0: port 2(bridge_slave_1) entered blocking state [ 83.057927][ T5934] bridge0: port 2(bridge_slave_1) entered forwarding state [ 83.065345][ T5934] bridge0: port 1(bridge_slave_0) entered blocking state [ 83.072413][ T5934] bridge0: port 1(bridge_slave_0) entered forwarding state [ 83.120031][ T5934] 8021q: adding VLAN 0 to HW filter on device bond0 [ 83.134601][ T13] bridge0: port 1(bridge_slave_0) entered disabled state [ 83.142944][ T13] bridge0: port 2(bridge_slave_1) entered disabled state [ 83.158979][ T5934] 8021q: adding VLAN 0 to HW filter on device team0 [ 83.170550][ T13] bridge0: port 1(bridge_slave_0) entered blocking state [ 83.177700][ T13] bridge0: port 1(bridge_slave_0) entered forwarding state [ 83.190625][ T13] bridge0: port 2(bridge_slave_1) entered blocking state [ 83.197827][ T13] bridge0: port 2(bridge_slave_1) entered forwarding state [ 83.341329][ T5934] 8021q: adding VLAN 0 to HW filter on device batadv0 [ 83.378958][ T5934] veth0_vlan: entered promiscuous mode [ 83.389241][ T5934] veth1_vlan: entered promiscuous mode [ 83.415371][ T5934] veth0_macvtap: entered promiscuous mode [ 83.427514][ T5934] veth1_macvtap: entered promiscuous mode [ 83.442500][ T5934] batman_adv: batadv0: Interface activated: batadv_slave_0 [ 83.457848][ T5934] batman_adv: batadv0: Interface activated: batadv_slave_1 [ 83.470032][ T13] netdevsim netdevsim0 netdevsim0: set [1, 0] type 2 family 0 port 6081 - 0 [ 83.481273][ T13] netdevsim netdevsim0 netdevsim1: set [1, 0] type 2 family 0 port 6081 - 0 [ 83.491068][ T1309] netdevsim netdevsim0 netdevsim2: set [1, 0] type 2 family 0 port 6081 - 0 [ 83.503898][ T1309] netdevsim netdevsim0 netdevsim3: set [1, 0] type 2 family 0 port 6081 - 0 [ 83.557255][ T13] wlan0: Created IBSS using preconfigured BSSID 50:50:50:50:50:50 [ 83.570502][ T13] wlan0: Creating new IBSS network, BSSID 50:50:50:50:50:50 [ 83.593580][ T4559] wlan1: Created IBSS using preconfigured BSSID 50:50:50:50:50:50 [ 83.602431][ T4559] wlan1: Creating new IBSS network, BSSID 50:50:50:50:50:50 [ 84.168287][ T4559] netdevsim netdevsim1 netdevsim3 (unregistering): unset [1, 0] type 2 family 0 port 6081 - 0 [ 85.956893][ T4559] netdevsim netdevsim1 netdevsim2 (unregistering): unset [1, 0] type 2 family 0 port 6081 - 0 [ 86.015502][ T4559] netdevsim netdevsim1 netdevsim1 (unregistering): unset [1, 0] type 2 family 0 port 6081 - 0 [ 86.093966][ T4559] netdevsim netdevsim1 netdevsim0 (unregistering): unset [1, 0] type 2 family 0 port 6081 - 0 [ 86.188820][ T4559] bridge_slave_1: left allmulticast mode [ 86.194577][ T4559] bridge_slave_1: left promiscuous mode [ 86.202899][ T4559] bridge0: port 2(bridge_slave_1) entered disabled state [ 86.214213][ T4559] bridge_slave_0: left allmulticast mode [ 86.220656][ T4559] bridge_slave_0: left promiscuous mode [ 86.226590][ T4559] bridge0: port 1(bridge_slave_0) entered disabled state [ 86.433971][ T4559] bond0 (unregistering): (slave bond_slave_0): Releasing backup interface [ 86.445424][ T4559] bond0 (unregistering): (slave bond_slave_1): Releasing backup interface [ 86.454915][ T4559] bond0 (unregistering): Released all slaves [ 86.751537][ T4559] hsr_slave_0: left promiscuous mode [ 86.759187][ T4559] hsr_slave_1: left promiscuous mode [ 86.765628][ T4559] batman_adv: batadv0: Interface deactivated: batadv_slave_0 [ 86.773100][ T4559] batman_adv: batadv0: Removing interface: batadv_slave_0 [ 86.782377][ T4559] batman_adv: batadv0: Interface deactivated: batadv_slave_1 [ 86.790070][ T4559] batman_adv: batadv0: Removing interface: batadv_slave_1 [ 86.810811][ T4559] veth1_macvtap: left promiscuous mode [ 86.816685][ T4559] veth0_macvtap: left promiscuous mode [ 86.822409][ T4559] veth1_vlan: left promiscuous mode [ 86.828558][ T4559] veth0_vlan: left promiscuous mode [ 87.103965][ T4559] team0 (unregistering): Port device team_slave_1 removed [ 87.133637][ T4559] team0 (unregistering): Port device team_slave_0 removed [ 87.695499][ T4559] netdevsim netdevsim0 netdevsim3 (unregistering): unset [1, 0] type 2 family 0 port 6081 - 0 [ 87.754614][ T4559] netdevsim netdevsim0 netdevsim2 (unregistering): unset [1, 0] type 2 family 0 port 6081 - 0 [ 87.833906][ T4559] netdevsim netdevsim0 netdevsim1 (unregistering): unset [1, 0] type 2 family 0 port 6081 - 0 [ 87.903519][ T4559] netdevsim netdevsim0 netdevsim0 (unregistering): unset [1, 0] type 2 family 0 port 6081 - 0 [ 88.019657][ T4559] bridge_slave_1: left allmulticast mode [ 88.026013][ T4559] bridge_slave_1: left promiscuous mode [ 88.031763][ T4559] bridge0: port 2(bridge_slave_1) entered disabled state [ 88.040560][ T4559] bridge_slave_0: left allmulticast mode [ 88.047223][ T4559] bridge_slave_0: left promiscuous mode [ 88.052958][ T4559] bridge0: port 1(bridge_slave_0) entered disabled state [ 88.234049][ T4559] bond0 (unregistering): (slave bond_slave_0): Releasing backup interface [ 88.244910][ T4559] bond0 (unregistering): (slave bond_slave_1): Releasing backup interface [ 88.254681][ T4559] bond0 (unregistering): Released all slaves [ 88.503276][ T4559] hsr_slave_0: left promiscuous mode [ 88.515190][ T4559] hsr_slave_1: left promiscuous mode [ 88.521144][ T4559] batman_adv: batadv0: Interface deactivated: batadv_slave_0 [ 88.533055][ T4559] batman_adv: batadv0: Removing interface: batadv_slave_0 [ 88.541418][ T4559] batman_adv: batadv0: Interface deactivated: batadv_slave_1 [ 88.549624][ T4559] batman_adv: batadv0: Removing interface: batadv_slave_1 [ 88.566813][ T4559] veth1_macvtap: left promiscuous mode [ 88.572380][ T4559] veth0_macvtap: left promiscuous mode [ 88.578459][ T4559] veth1_vlan: left promiscuous mode [ 88.583771][ T4559] veth0_vlan: left promiscuous mode [ 88.850925][ T4559] team0 (unregistering): Port device team_slave_1 removed [ 88.879924][ T4559] team0 (unregistering): Port device team_slave_0 removed syzkaller build log: go env (err=<nil>) AR='ar' CC='gcc' CGO_CFLAGS='-O2 -g' CGO_CPPFLAGS='' CGO_CXXFLAGS='-O2 -g' CGO_ENABLED='1' CGO_FFLAGS='-O2 -g' CGO_LDFLAGS='-O2 -g' CXX='g++' GCCGO='gccgo' GO111MODULE='auto' GOAMD64='v1' GOARCH='amd64' GOAUTH='netrc' GOBIN='' GOCACHE='/syzkaller/.cache/go-build' GOCACHEPROG='' GODEBUG='' GOENV='/syzkaller/.config/go/env' GOEXE='' GOEXPERIMENT='' GOFIPS140='off' GOFLAGS='' GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build2311833903=/tmp/go-build -gno-record-gcc-switches' GOHOSTARCH='amd64' GOHOSTOS='linux' GOINSECURE='' GOMOD='/syzkaller/jobs-2/linux/gopath/src/github.com/google/syzkaller/go.mod' GOMODCACHE='/syzkaller/jobs-2/linux/gopath/pkg/mod' GONOPROXY='' GONOSUMDB='' GOOS='linux' GOPATH='/syzkaller/jobs-2/linux/gopath' GOPRIVATE='' GOPROXY='https://proxy.golang.org,direct' GOROOT='/usr/local/go' GOSUMDB='sum.golang.org' GOTELEMETRY='local' GOTELEMETRYDIR='/syzkaller/.config/go/telemetry' GOTMPDIR='' GOTOOLCHAIN='auto' GOTOOLDIR='/usr/local/go/pkg/tool/linux_amd64' GOVCS='' GOVERSION='go1.24.4' GOWORK='' PKG_CONFIG='pkg-config' git status (err=<nil>) HEAD detached at 004c195c04 nothing to commit, working tree clean tput: No value for $TERM and no -T specified tput: No value for $TERM and no -T specified Makefile:31: run command via tools/syz-env for best compatibility, see: Makefile:32: https://github.com/google/syzkaller/blob/master/docs/contributing.md#using-syz-env go list -f '{{.Stale}}' -ldflags="-s -w -X github.com/google/syzkaller/prog.GitRevision=004c195c04b03dc0333690d4eef6f935ab80f739 -X github.com/google/syzkaller/prog.gitRevisionDate=20260128-101947" ./sys/syz-sysgen | grep -q false || go install -ldflags="-s -w -X github.com/google/syzkaller/prog.GitRevision=004c195c04b03dc0333690d4eef6f935ab80f739 -X github.com/google/syzkaller/prog.gitRevisionDate=20260128-101947" ./sys/syz-sysgen make .descriptions tput: No value for $TERM and no -T specified tput: No value for $TERM and no -T specified Makefile:31: run command via tools/syz-env for best compatibility, see: Makefile:32: https://github.com/google/syzkaller/blob/master/docs/contributing.md#using-syz-env bin/syz-sysgen touch .descriptions GOOS=linux GOARCH=amd64 go build -ldflags="-s -w -X github.com/google/syzkaller/prog.GitRevision=004c195c04b03dc0333690d4eef6f935ab80f739 -X github.com/google/syzkaller/prog.gitRevisionDate=20260128-101947" -o ./bin/linux_amd64/syz-execprog github.com/google/syzkaller/tools/syz-execprog mkdir -p ./bin/linux_amd64 g++ -o ./bin/linux_amd64/syz-executor executor/executor.cc \ -m64 -O2 -pthread -Wall -Werror -Wparentheses -Wunused-const-variable -Wframe-larger-than=16384 -Wno-stringop-overflow -Wno-array-bounds -Wno-format-overflow -Wno-unused-but-set-variable -Wno-unused-command-line-argument -static-pie -std=c++17 -I. -Iexecutor/_include -DGOOS_linux=1 -DGOARCH_amd64=1 \ -DHOSTGOOS_linux=1 -DGIT_REVISION=\"004c195c04b03dc0333690d4eef6f935ab80f739\" /usr/bin/ld: /tmp/ccMi1lE0.o: in function `Connection::Connect(char const*, char const*)': executor.cc:(.text._ZN10Connection7ConnectEPKcS1_[_ZN10Connection7ConnectEPKcS1_]+0x386): warning: Using 'gethostbyname' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking ./tools/check-syzos.sh 2>/dev/null Error text is too large and was truncated, full error text is at: https://syzkaller.appspot.com/x/error.txt?x=1676e25a580000 Tested on: commit: 0499add8 Merge tag 'kvm-x86-fixes-6.19-rc1' of https:/.. git tree: git://git.kernel.org/pub/scm/virt/kvm/kvm.git next kernel config: https://syzkaller.appspot.com/x/.config?x=3aec2f7e1730a8eb dashboard link: https://syzkaller.appspot.com/bug?extid=33a04338019ac7e43a44 compiler: gcc (Debian 14.2.0-19) 14.2.0, GNU ld (GNU Binutils for Debian) 2.44 patch: https://syzkaller.appspot.com/x/patch.diff?x=15dae25a580000 ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH 1/2] KVM: guest_memfd: Always use order 0 when allocating for guest_memfd 2026-02-03 22:50 ` [PATCH 1/2] KVM: guest_memfd: Always use order 0 when allocating for guest_memfd Ackerley Tng 2026-02-03 22:00 ` [syzbot] [kvm?] WARNING in kvm_gmem_fault_user_mapping syzbot @ 2026-02-04 12:36 ` Deepanshu Kartikey 2026-02-04 16:30 ` Ackerley Tng 1 sibling, 1 reply; 4+ messages in thread From: Deepanshu Kartikey @ 2026-02-04 12:36 UTC (permalink / raw) To: Ackerley Tng; +Cc: syzbot+33a04338019ac7e43a44, linux-kernel, syzkaller-bugs On Wed, Feb 4, 2026 at 4:21 AM Ackerley Tng <ackerleytng@google.com> wrote: > > #syz test: git://git.kernel.org/pub/scm/virt/kvm/kvm.git next > > filemap_{grab,get}_folio() and related functions, used since the early > stages of guest_memfd have determined the order of the folio to be > allocated by looking up mapping_min_folio_order(mapping). As identified by > syzbot, MADV_HUGEPAGE can be used to set the result of > mapping_min_folio_order() to a value greater than 0, leading to the > allocation of a huge page and subsequent WARNing. > > Refactor the allocation code of guest_memfd to directly use > filemap_add_folio(), specifying an order of 0. > > This refactoring replaces the original functionality where FGP_LOCK and > FGP_CREAT are requested. Opportunistically drop functionality provided by > FGP_ACCESSED. guest_memfd folios don't care about accessed flags because > guest_memfd memory is unevictable and there is no storage to write back to. > > Reported-by: syzbot+33a04338019ac7e43a44@syzkaller.appspotmail.com > Closes: https://syzkaller.appspot.com/bug?extid=33a04338019ac7e43a44 > Tested-by: syzbot+33a04338019ac7e43a44@syzkaller.appspotmail.com > Signed-off-by: Ackerley Tng <ackerleytng@google.com> > --- > virt/kvm/guest_memfd.c | 20 ++++++++++++++++---- > 1 file changed, 16 insertions(+), 4 deletions(-) > > diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c > index fdaea3422c30..0c58f6aa5609 100644 > --- a/virt/kvm/guest_memfd.c > +++ b/virt/kvm/guest_memfd.c > @@ -135,23 +135,35 @@ static struct folio *kvm_gmem_get_folio(struct inode *inode, pgoff_t index) > /* TODO: Support huge pages. */ > struct mempolicy *policy; > struct folio *folio; > + gfp_t gfp; > + int ret; > > /* > * Fast-path: See if folio is already present in mapping to avoid > * policy_lookup. > */ > +repeat: > folio = __filemap_get_folio(inode->i_mapping, index, > FGP_LOCK | FGP_ACCESSED, 0); > if (!IS_ERR(folio)) > return folio; > > + gfp = mapping_gfp_mask(inode->i_mapping); > + > policy = mpol_shared_policy_lookup(&GMEM_I(inode)->policy, index); > - folio = __filemap_get_folio_mpol(inode->i_mapping, index, > - FGP_LOCK | FGP_ACCESSED | FGP_CREAT, > - mapping_gfp_mask(inode->i_mapping), policy); > + folio = filemap_alloc_folio(gfp, 0, policy); > mpol_cond_put(policy); Hi Ackerley, Thanks for working on this bug! I've been investigating the same issue and have a concern about the fast-path in your patch. In kvm_gmem_get_folio(), the fast-path returns any existing folio from the page cache without checking if it's a large folio: folio = __filemap_get_folio(inode->i_mapping, index, FGP_LOCK | FGP_ACCESSED, 0); if (!IS_ERR(folio)) return folio; // <-- No size check here This means if a large folio was previously allocated (e.g., via madvise(MADV_HUGEPAGE)), subsequent faults will find and return it from the fast-path, still triggering the WARN_ON_ONCE at line 416 in kvm_gmem_fault_user_mapping(). The issue is that while your patch prevents *new* large folio allocations by hardcoding order=0 in filemap_alloc_folio(), it doesn't handle large folios that already exist in the page cache. Shouldn't we add a check for folio_test_large() on both the fast-path and slow-path to ensure we reject large folios regardless of how they were allocated? Something like: folio = __filemap_get_folio(...); if (!IS_ERR(folio)) goto check_folio; // ... allocation code ... check_folio: if (folio_test_large(folio)) { folio_unlock(folio); folio_put(folio); return ERR_PTR(-E2BIG); } Or am I missing something about how the page cache handles this case? Thanks, Deepanshu Kartikey ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH 1/2] KVM: guest_memfd: Always use order 0 when allocating for guest_memfd 2026-02-04 12:36 ` [PATCH 1/2] KVM: guest_memfd: Always use order 0 when allocating for guest_memfd Deepanshu Kartikey @ 2026-02-04 16:30 ` Ackerley Tng 0 siblings, 0 replies; 4+ messages in thread From: Ackerley Tng @ 2026-02-04 16:30 UTC (permalink / raw) To: Deepanshu Kartikey Cc: syzbot+33a04338019ac7e43a44, linux-kernel, syzkaller-bugs Deepanshu Kartikey <kartikey406@gmail.com> writes: > On Wed, Feb 4, 2026 at 4:21 AM Ackerley Tng <ackerleytng@google.com> wrote: >> >> #syz test: git://git.kernel.org/pub/scm/virt/kvm/kvm.git next >> >> filemap_{grab,get}_folio() and related functions, used since the early >> stages of guest_memfd have determined the order of the folio to be >> allocated by looking up mapping_min_folio_order(mapping). As identified by >> syzbot, MADV_HUGEPAGE can be used to set the result of >> mapping_min_folio_order() to a value greater than 0, leading to the I was wrong here, MADV_HUGEPAGE does not actually update mapping->flags AFAICT, so it doesn't update the result of mapping_min_folio_order(). MADV_HUGEPAGE only operates on the VMA and doesn't update the mapping's min or max order, which is a inode/mapping property. >> allocation of a huge page and subsequent WARNing. >> >> Refactor the allocation code of guest_memfd to directly use >> filemap_add_folio(), specifying an order of 0. >> This refactoring is not actually required, since IIUC guest_memfd never tries to update mapping->flags, and so mapping_min_folio_order() and mapping_max_folio_order() return the default of 0. >> This refactoring replaces the original functionality where FGP_LOCK and >> FGP_CREAT are requested. Opportunistically drop functionality provided by >> FGP_ACCESSED. guest_memfd folios don't care about accessed flags because >> guest_memfd memory is unevictable and there is no storage to write back to. >> >> Reported-by: syzbot+33a04338019ac7e43a44@syzkaller.appspotmail.com >> Closes: https://syzkaller.appspot.com/bug?extid=33a04338019ac7e43a44 >> Tested-by: syzbot+33a04338019ac7e43a44@syzkaller.appspotmail.com >> Signed-off-by: Ackerley Tng <ackerleytng@google.com> >> --- >> virt/kvm/guest_memfd.c | 20 ++++++++++++++++---- >> 1 file changed, 16 insertions(+), 4 deletions(-) >> >> diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c >> index fdaea3422c30..0c58f6aa5609 100644 >> --- a/virt/kvm/guest_memfd.c >> +++ b/virt/kvm/guest_memfd.c >> @@ -135,23 +135,35 @@ static struct folio *kvm_gmem_get_folio(struct inode *inode, pgoff_t index) >> /* TODO: Support huge pages. */ >> struct mempolicy *policy; >> struct folio *folio; >> + gfp_t gfp; >> + int ret; >> >> /* >> * Fast-path: See if folio is already present in mapping to avoid >> * policy_lookup. >> */ >> +repeat: >> folio = __filemap_get_folio(inode->i_mapping, index, >> FGP_LOCK | FGP_ACCESSED, 0); >> if (!IS_ERR(folio)) >> return folio; >> >> + gfp = mapping_gfp_mask(inode->i_mapping); >> + >> policy = mpol_shared_policy_lookup(&GMEM_I(inode)->policy, index); >> - folio = __filemap_get_folio_mpol(inode->i_mapping, index, >> - FGP_LOCK | FGP_ACCESSED | FGP_CREAT, >> - mapping_gfp_mask(inode->i_mapping), policy); >> + folio = filemap_alloc_folio(gfp, 0, policy); >> mpol_cond_put(policy); > > Hi Ackerley, > > Thanks for working on this bug! I've been investigating the same issue Thank you for working on this bug too! > and have a concern about the fast-path in your patch. > > In kvm_gmem_get_folio(), the fast-path returns any existing folio from > the page cache without checking if it's a large folio: > > folio = __filemap_get_folio(inode->i_mapping, index, > FGP_LOCK | FGP_ACCESSED, 0); > if (!IS_ERR(folio)) > return folio; // <-- No size check here > > This means if a large folio was previously allocated (e.g., via This is true, but I tried the above patch because back then I believed that the filemap_add_folio() within the original __filemap_get_folio_mpol() was the only place where folios get added to the filemap. I'm trying out another patch locally to disable khugepaged. I believe the issue is that when MADV_HUGEPAGE is used on a guest_memfd vma, it indirectly enabled khugepaged to work on guest_memfd folios, which we don't want anyway. I'm guessing now that the root cause is to disable khugepaged for guest_memfd, and I will be trying out a few options through the rest of today. My first thought was to set VM_NO_KHUGEPAGED (semantically suitable), but looks like it's triggering some hugetlb-related weirdness. I'm going to try VM_DONTEXPAND next. Other notes: I trimmed the repro down by disabling calls 4, 5, 6, 9, those are not necessary for repro. Calls 0, 1, 2, 3 is part of a regular usage pattern of guest_memfd, so the uncommon usages are call 7 (MADV_HUGEPAGE) (likely culprit), or call 8. I believe call 8 is just the trigger, since mlock() actually faults in the page to userspace through gup. > madvise(MADV_HUGEPAGE)), subsequent faults will find and return it madvise(MADV_HUGEPAGE) does not allocate folios, it only marks the VMA to allow huge pages > from the fast-path, still triggering the WARN_ON_ONCE at line 416 in > kvm_gmem_fault_user_mapping(). > > The issue is that while your patch prevents *new* large folio > allocations by hardcoding order=0 in filemap_alloc_folio(), it doesn't > handle large folios that already exist in the page cache. > > Shouldn't we add a check for folio_test_large() on both the fast-path > and slow-path to ensure we reject large folios regardless of how they > were allocated? Something like: > > folio = __filemap_get_folio(...); > if (!IS_ERR(folio)) > goto check_folio; > // ... allocation code ... > check_folio: > if (folio_test_large(folio)) { > folio_unlock(folio); > folio_put(folio); > return ERR_PTR(-E2BIG); I saw your patch, I feel that returning -E2BIG doesn't address the root cause of the issue. > } > > Or am I missing something about how the page cache handles this case? > > Thanks, > Deepanshu Kartikey ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-02-04 16:30 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <cover.1770148108.git.ackerleytng@google.com>
2026-02-03 22:50 ` [PATCH 1/2] KVM: guest_memfd: Always use order 0 when allocating for guest_memfd Ackerley Tng
2026-02-03 22:00 ` [syzbot] [kvm?] WARNING in kvm_gmem_fault_user_mapping syzbot
2026-02-04 12:36 ` [PATCH 1/2] KVM: guest_memfd: Always use order 0 when allocating for guest_memfd Deepanshu Kartikey
2026-02-04 16:30 ` Ackerley Tng
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox