* [BUG] alloc_tag: GPF in __pgalloc_tag_sub() during hibernation snapshot, page tag ref points into .orc_unwind_ip
@ 2026-11-09 8:45 Konstantin Yagola
2026-11-12 9:49 ` Hao Ge
0 siblings, 1 reply; 3+ messages in thread
From: Konstantin Yagola @ 2026-11-09 8:45 UTC (permalink / raw)
To: Suren Baghdasaryan, Hao Ge; +Cc: linux-mm, Rafael J. Wysocki, linux-pm
Hi,
my laptop sometimes fails to hibernate: the screen goes dark, the fans
keep spinning and only a forced power-off helps. It happened twice this
week on 7.3. Both times pstore caught the same crash: a GPF in
__pgalloc_tag_sub() while hibernate_preallocate_memory() reclaims
memory for the image. Both times it was the second or third hibernation
of the same boot, after successful S4 resumes. It is not every time:
one boot went through six hibernate/resume cycles without a problem.
Taint first, honestly: P (nvidia), O (openrazer) and S (CPU undervolt
via MSR). I know S makes any report suspicious, so here is why I think
this is a software bug and not random corruption:
- RCX is fe20d545fe20d545 in BOTH crashes, byte for byte, across two
different boots with different KASLR offsets;
- RDX (the codetag pointer taken from the page) minus the KASLR
offset is the same in both crashes: 0xffffffff835ac1f0;
- in vmlinux of this build that address is inside .orc_unwind_ip,
not an alloc_tag. The faulting code is
mov rcx, [rdx+0x20] ; tag->counters
add gs:[rcx], rax ; <-- GPF
so "counters" is just ORC table bytes read as a percpu pointer.
So a page's tag reference ends up as a valid, KASLR-adjusted kernel
pointer to the wrong place. My guess is that page tag refs get out of
sync with the tags across a hibernate/resume cycle, but I have not
verified that.
Setup: Razer Blade 16 (RZ09-0483, BIOS 2.03), i9-13950HX, 32 GB RAM,
NixOS, kernel 7.3.0 (nixpkgs build, CONFIG_MEM_ALLOC_PROFILING=y,
..._ENABLED_BY_DEFAULT=y, not compressed, no _DEBUG), hibernation to a
48 GB swapfile on btrfs inside dm-crypt, /sys/power/disk = platform.
Workaround: sysctl.vm.mem_profiling=never on the command line. I cannot
reproduce this on an untainted kernel: it happens about once a week,
and with the workaround I will not see it at all. If there is something
cheaper to collect (a debug option, a printk, a check right after
resume), I am happy to run it.
Crash 1 (2026-11-09), assembled from pstore:
Oops: general protection fault, probably for non-canonical address
0xfe20646ff042c545: 0000 [#1] SMP NOPTI
CPU: 3 UID: 0 PID: 458460 Comm: systemd-sleep Tainted: P S O
7.3.0 #1-NixOS PREEMPT(lazy)
Tainted: [P]=PROPRIETARY_MODULE, [S]=CPU_OUT_OF_SPEC, [O]=OOT_MODULE
Hardware name: Razer Blade 16 - RZ09-0483/SO690, BIOS 2.03 06/04/2024
RIP: 0010:__pgalloc_tag_sub+0xcc/0x170
Code: e8 79 f4 08 00 48 85 c0 74 eb 48 03 05 9d 09 d2 01 48 8b 10 48
89 c3 48 85 d2 74 1b 44 89 f0 48 8b 4a 20 48 c1 e0 0c 48 f7 d8 <65> 48
01 01 48 8b 42 20 65 48 ff 48 08 48 c7 c7 00 19 c3 ac e8 fb
RSP: 0018:ffffcfcdc517b4d8 EFLAGS: 00010287
RAX: fffffffffffff000 RBX: ffff8f220292fbc0 RCX: fe20d545fe20d545
RDX: ffffffffac3ac1f0 RSI: 0000000000000001 RDI: 0000000002bafbc0
RBP: 0000000000000001 R08: 0000000000000000 R09: 0000000000000000
R10: ffff8f299ed9d260 R11: 0000000000000000 R12: fffff39ed5d7de00
R13: 0000000000000000 R14: 0000000000000001 R15: ffffcfcdc517b5e8
Call Trace:
<TASK>
free_unref_folios+0x18f/0x830
shrink_folio_list+0x63e/0x1090
evict_folios+0x154/0x5f0
try_to_shrink_lruvec+0x132/0x260
shrink_one+0xc0/0x1a0
shrink_node+0xb9e/0xdd0
do_try_to_free_pages+0xbf/0x480
try_to_free_pages+0xf6/0x1f0
__alloc_frozen_pages_noprof+0xa00/0x18d0
alloc_pages_mpol+0xbc/0x180
alloc_pages_noprof+0x3b/0x90
alloc_image_page+0x2d/0xb0
preallocate_image_memory+0x30/0x64
hibernate_preallocate_memory+0x257/0x391
hibernation_snapshot+0x9c/0x4c0
hibernate.cold+0x10d/0x495
state_store+0xc3/0xd0
kernfs_fop_write_iter+0x18a/0x230
vfs_write+0x25d/0x470
ksys_write+0x73/0xf0
do_syscall_64+0x114/0x5c0
entry_SYSCALL_64_after_hwframe+0x77/0x7f
</TASK>
Kernel panic - not syncing: Fatal exception
Kernel Offset: 0x28e00000 from 0xffffffff81000000
Earlier in that boot: "ACPI: PM: Waking up from system sleep state S4"
at 28492 s, crash at 83620 s.
Crash 2 (2026-11-07): same RIP, same RCX, RDX ffffffffbc1ac1f0 with
Kernel Offset 0x38c00000 (same address after subtracting it), but this
time in kswapd0, 7 s after "PM: hibernation: hibernation entry". Two
successful S4 resumes earlier in that boot (121257 s, 192472 s).
Full pstore dumps and the vmlinux of this build are available if
useful.
Thanks, KY.
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [BUG] alloc_tag: GPF in __pgalloc_tag_sub() during hibernation snapshot, page tag ref points into .orc_unwind_ip
2026-11-09 8:45 [BUG] alloc_tag: GPF in __pgalloc_tag_sub() during hibernation snapshot, page tag ref points into .orc_unwind_ip Konstantin Yagola
@ 2026-11-12 9:49 ` Hao Ge
2026-11-12 21:29 ` Konstantin Yagola
0 siblings, 1 reply; 3+ messages in thread
From: Hao Ge @ 2026-11-12 9:49 UTC (permalink / raw)
To: Konstantin Yagola
Cc: linux-mm, Rafael J. Wysocki, linux-pm, Suren Baghdasaryan
Hi Konstantin
On 2026/11/9 16:45, Konstantin Yagola wrote:
> Hi,
>
> my laptop sometimes fails to hibernate: the screen goes dark, the fans
> keep spinning and only a forced power-off helps. It happened twice this
> week on 7.3. Both times pstore caught the same crash: a GPF in
> __pgalloc_tag_sub() while hibernate_preallocate_memory() reclaims
> memory for the image. Both times it was the second or third hibernation
> of the same boot, after successful S4 resumes. It is not every time:
> one boot went through six hibernate/resume cycles without a problem.
>
> Taint first, honestly: P (nvidia), O (openrazer) and S (CPU undervolt
> via MSR). I know S makes any report suspicious, so here is why I think
> this is a software bug and not random corruption:
>
> - RCX is fe20d545fe20d545 in BOTH crashes, byte for byte, across two
> different boots with different KASLR offsets;
> - RDX (the codetag pointer taken from the page) minus the KASLR
> offset is the same in both crashes: 0xffffffff835ac1f0;
> - in vmlinux of this build that address is inside .orc_unwind_ip,
> not an alloc_tag. The faulting code is
>
> mov rcx, [rdx+0x20] ; tag->counters
> add gs:[rcx], rax ; <-- GPF
>
> so "counters" is just ORC table bytes read as a percpu pointer.
>
> So a page's tag reference ends up as a valid, KASLR-adjusted kernel
> pointer to the wrong place. My guess is that page tag refs get out of
> sync with the tags across a hibernate/resume cycle, but I have not
> verified that.
>
> Setup: Razer Blade 16 (RZ09-0483, BIOS 2.03), i9-13950HX, 32 GB RAM,
> NixOS, kernel 7.3.0 (nixpkgs build, CONFIG_MEM_ALLOC_PROFILING=y,
> ..._ENABLED_BY_DEFAULT=y, not compressed, no _DEBUG), hibernation to a
> 48 GB swapfile on btrfs inside dm-crypt, /sys/power/disk = platform.
Thanks for the excellent report and especially for the disassembly work;
Sorry for the delayed reply.
Based on your configuration, we are using page_ext mode: the codetag pointer
is stored in page_ext. page_ext is allocated via the page allocator as well.
From your disassembly analysis above, we can see the issue is triggered because
the address stored in a page_ext has been overwritten.
Where those 8 bytes live page_ext (normal pages from the buddy, GFP_ZERO'd at early
boot, before any driver loads), layout as below:
+---------------+---------------+-------------+-------------+
| ref(pfn1) | ref(pfn2) | ... | ref(pfn k) |
+---------------+---------------+-------------+-------------+
| &tag_a | &tag_b | | &tag_k |
+---------------+---------------+-------------+-------------+
I'm wondering whether an out-of-bounds write from an adjacent page might have clobbered it.
Are there any other clues available? Could you share where I can get the matching vmlinux,
kernel config and dmesg?
Thanks
Best Regards
Hao
>
> Workaround: sysctl.vm.mem_profiling=never on the command line. I cannot
> reproduce this on an untainted kernel: it happens about once a week,
> and with the workaround I will not see it at all. If there is something
> cheaper to collect (a debug option, a printk, a check right after
> resume), I am happy to run it.
>
> Crash 1 (2026-11-09), assembled from pstore:
>
> Oops: general protection fault, probably for non-canonical address
> 0xfe20646ff042c545: 0000 [#1] SMP NOPTI
> CPU: 3 UID: 0 PID: 458460 Comm: systemd-sleep Tainted: P S O
> 7.3.0 #1-NixOS PREEMPT(lazy)
> Tainted: [P]=PROPRIETARY_MODULE, [S]=CPU_OUT_OF_SPEC, [O]=OOT_MODULE
> Hardware name: Razer Blade 16 - RZ09-0483/SO690, BIOS 2.03 06/04/2024
> RIP: 0010:__pgalloc_tag_sub+0xcc/0x170
> Code: e8 79 f4 08 00 48 85 c0 74 eb 48 03 05 9d 09 d2 01 48 8b 10 48
> 89 c3 48 85 d2 74 1b 44 89 f0 48 8b 4a 20 48 c1 e0 0c 48 f7 d8 <65> 48
> 01 01 48 8b 42 20 65 48 ff 48 08 48 c7 c7 00 19 c3 ac e8 fb
> RSP: 0018:ffffcfcdc517b4d8 EFLAGS: 00010287
> RAX: fffffffffffff000 RBX: ffff8f220292fbc0 RCX: fe20d545fe20d545
> RDX: ffffffffac3ac1f0 RSI: 0000000000000001 RDI: 0000000002bafbc0
> RBP: 0000000000000001 R08: 0000000000000000 R09: 0000000000000000
> R10: ffff8f299ed9d260 R11: 0000000000000000 R12: fffff39ed5d7de00
> R13: 0000000000000000 R14: 0000000000000001 R15: ffffcfcdc517b5e8
> Call Trace:
> <TASK>
> free_unref_folios+0x18f/0x830
> shrink_folio_list+0x63e/0x1090
> evict_folios+0x154/0x5f0
> try_to_shrink_lruvec+0x132/0x260
> shrink_one+0xc0/0x1a0
> shrink_node+0xb9e/0xdd0
> do_try_to_free_pages+0xbf/0x480
> try_to_free_pages+0xf6/0x1f0
> __alloc_frozen_pages_noprof+0xa00/0x18d0
> alloc_pages_mpol+0xbc/0x180
> alloc_pages_noprof+0x3b/0x90
> alloc_image_page+0x2d/0xb0
> preallocate_image_memory+0x30/0x64
> hibernate_preallocate_memory+0x257/0x391
> hibernation_snapshot+0x9c/0x4c0
> hibernate.cold+0x10d/0x495
> state_store+0xc3/0xd0
> kernfs_fop_write_iter+0x18a/0x230
> vfs_write+0x25d/0x470
> ksys_write+0x73/0xf0
> do_syscall_64+0x114/0x5c0
> entry_SYSCALL_64_after_hwframe+0x77/0x7f
> </TASK>
> Kernel panic - not syncing: Fatal exception
> Kernel Offset: 0x28e00000 from 0xffffffff81000000
>
> Earlier in that boot: "ACPI: PM: Waking up from system sleep state S4"
> at 28492 s, crash at 83620 s.
>
> Crash 2 (2026-11-07): same RIP, same RCX, RDX ffffffffbc1ac1f0 with
> Kernel Offset 0x38c00000 (same address after subtracting it), but this
> time in kswapd0, 7 s after "PM: hibernation: hibernation entry". Two
> successful S4 resumes earlier in that boot (121257 s, 192472 s).
>
> Full pstore dumps and the vmlinux of this build are available if
> useful.
>
> Thanks, KY.
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [BUG] alloc_tag: GPF in __pgalloc_tag_sub() during hibernation snapshot, page tag ref points into .orc_unwind_ip
2026-11-12 9:49 ` Hao Ge
@ 2026-11-12 21:29 ` Konstantin Yagola
0 siblings, 0 replies; 3+ messages in thread
From: Konstantin Yagola @ 2026-11-12 21:29 UTC (permalink / raw)
To: Hao Ge; +Cc: linux-mm, Rafael J. Wysocki, linux-pm, Suren Baghdasaryan
Hi Hao,
thanks a lot for looking into this.
vmlinux: the crashing kernel is a NixOS build and is bit-for-bit
reproducible. With Nix installed:
nix build github:NixOS/nixpkgs/08d3a97586f6b6343b3b5e799980773629432610#linuxPackages_latest.kernel.dev
./result-dev/vmlinux is the exact file (with debug_info,
BuildID 8ceb20655c1e3f720b1b317dd5153cfe47001db2). It is prebuilt in
cache.nixos.org, so it downloads (~256 MB) instead of compiling. If you
don't use Nix, tell me and I'll upload the file somewhere.
Config and dmesg: I'm sending you a tarball off-list (too big for the
lists): the kernel .config, the full kernel log of both crash boots up
to "hibernation entry", and the assembled pstore records. MAC addresses
and USB serial numbers are redacted, nothing else is changed.
Other clues:
1. A correction to my first mail: the 2026-11-07 boot had four
successful hibernate/resume cycles, not two (pstore only kept the
last ones). It crashed on the fifth hibernation. The 2026-11-09 boot
crashed on the second. No crash has ever happened on the first
hibernation of a boot.
2. The overwritten entry is not random. In both boots it is a valid,
KASLR-relocated kernel pointer to the same image offset
(0xffffffff835ac1f0 after subtracting the offset, inside
.orc_unwind_ip). Whatever writes it seems to write a real kernel
address, the same one twice.
With debug_info the registers read as follows (faulting line
include/linux/alloc_tag.h:222, inlined into mm/page_alloc.c:1288):
RBX = address of the ref slot in page_ext:
ffff8f220292fbc0 (11-09), ffff8c3003325680 (11-07)
RDX = the stored codetag pointer (the bad value above)
RCX = [RDX+0x20], i.e. ORC table bytes read as tag->counters
RAX = -4096, so an order-0 page was being freed.
I don't have a memory image, so I can't tell whether neighbouring
slots around RBX were overwritten too.
3. A suspect from the tainted side: the proprietary nvidia driver
(595.112.07) takes part in every hibernation with
NVreg_PreserveVideoMemoryAllocations=1. nvidia-hibernate.service saves
VRAM before the snapshot (about 770 MB written, 2.3 GB peak memory).
I can't rule it out as the writer.
4. Every S4 resume logs "spd5118 ...: PM: failed to restore async:
error -6". Probably unrelated, but it happens on every resume.
5. Since booting with sysctl.vm.mem_profiling=never there were three
hibernate cycles in one boot without a crash. Given point 1 that is
weak evidence.
The crash is rare (once a week or less), so I can't reproduce it on
demand. But I'm happy to run a debug kernel or extra options (for
example MEM_ALLOC_PROFILING_DEBUG or page_owner) for a few weeks of
normal use, if that helps.
Thanks, KY.
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-11-12 21:30 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-09 8:45 [BUG] alloc_tag: GPF in __pgalloc_tag_sub() during hibernation snapshot, page tag ref points into .orc_unwind_ip Konstantin Yagola
2026-11-12 9:49 ` Hao Ge
2026-11-12 21:29 ` Konstantin Yagola
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.