All of lore.kernel.org
 help / color / mirror / Atom feed
* [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.