From: Vladimir Murzin <vladimir.murzin@arm.com>
To: Will Deacon <will@kernel.org>
Cc: Bradley Morgan <include@grrlz.net>,
Catalin Marinas <catalin.marinas@arm.com>,
Mark Rutland <mark.rutland@arm.com>,
Pasha Tatashin <pasha.tatashin@soleen.com>,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, maz@kernel.org,
james.morse@arm.com
Subject: Re: [PATCH] arm64: hibernate: pass HVC_SET_VECTORS args to the resume hvc
Date: Wed, 2 Sep 2026 14:07:17 +0100 [thread overview]
Message-ID: <5058854b-6e68-44b2-b4f7-6e2f666c4caf@arm.com> (raw)
In-Reply-To: <aoxl1ri43eEAsxlR@willie-the-truck>
Hi Will,
On 8/24/26 16:40, Will Deacon wrote:
> Hi Vladimir,
>
> On Mon, Aug 17, 2026 at 02:06:20PM +0100, Vladimir Murzin wrote:
>> On 8/11/26 15:37, Will Deacon wrote:
>>> I think I probably need to spend some time understanding how all this is
>>> supposed to work. I can't currently tell how we end up with the stub
>>> vectors installed to start with nor why we can't do all this from C code.
> I finally got back to this...
>
>> Here is my understanding of how things work. Assuming nVHE mode, we
>> restore the previously saved image X from the currently running kernel Y.
>> I’ll use the suffixes _X and _Y for addresses belonging to the respective
>> images.
> Nice, thanks for the walkthrough!
>
>> On the resume path, KVM teardown sets VBAR_EL2 to __hyp_stub_vectors_Y.
>>
>> swsusp_arch_resume() then temporarily (re)sets VBAR_EL2 to trans_pgd_stub_vectors
>> while transitioning to image X:
>>
>> | if (el2_reset_needed())
>> | __hyp_set_vectors(el2_vectors);
>>
>>
>> Currently, swsusp_arch_suspend_exit() attempts to restore VBAR_EL2 to
>> __hyp_stub_vectors_X:
>>
>>
>> | cbz x24, 3f /* Do we need to re-initialise EL2? */
>> | hvc #0
>>
>> where x24 is resume_hdr.__hyp_stub_vectors (in other words snapshot of
>> __hyp_stub_vectors from image X)
>>
>> However, that request is ignored, so VBAR_EL2 remains pointing to
>> trans_pgd_stub_vectors
>>
>> We re-enter the kernel X.
>>
>> During KVM initialisation, we call __hyp_reset_vectors(). This is
>> handled by trans_pgd_stub_vectors, but ignored since HVC_RESET_VECTORS
>> is not recognised. We then call __hyp_set_vectors(), which is also
>> handled by trans_pgd_stub_vectors, but this time VBAR_EL2 get set to
>> __kvm_hyp_init_X.
>>
>> From that point on, __kvm_hyp_init_X handles subsequent HVC calls,
>> including the later call that redirects VBAR_EL2 to
>> __kvm_hyp_host_vector_X during KVM setup.
>>
>> The memory containing trans_pgd_stub_vectors is freed later by
>> swsusp_free(). That perhaps explains why we do not see any crash.
> I was trying to figure out if we end up initialising VBAR_EL2 before we
> "return" from swsusp_arch_suspend() and free the reserved pages.
> However, it looks like we run _cpu_resume() instead of cpu_resume() so
> I still can't tell why this hasn't exploded. AFAICT, the active hyp
> vectors will have been freed (and possibly poisoned) long before KVM
> initialises.
>
My apologies. I managed to confuse myself (but hopefully not you) with the
order of operations. Indeed, swsups_free() happens *before* KVM initialisation
which eventually happens later via syscore_resume().
I can now reproduce the problem with CONFIG_PAGE_POISONING=y and page_poison=on
# swapon /dev/vdb
[ 55.330849] Adding 2097148k swap on /dev/vdb. Priority:-1 extents:1 across:2097148k
# echo test_resume > /sys/power/disk
# echo disk > /sys/power/state
[ 62.534444] PM: hibernation: hibernation entry
[ 62.578411] Filesystems sync: 0.021 seconds
[ 62.579550] Freezing user space processes
[ 62.585909] Freezing user space processes completed (elapsed 0.005 seconds)
[ 62.586835] OOM killer disabled.
[ 62.588332] Freezing remaining freezable tasks
[ 62.591318] Freezing remaining freezable tasks completed (elapsed 0.002 seconds)
[ 62.593983] PM: hibernation: Preallocating image memory
[ 62.972326] PM: hibernation: Allocated 25745 pages for snapshot
[ 62.973119] PM: hibernation: Allocated 102980 kbytes in 0.37 seconds (278.32 MB/s)
[ 63.011607] Disabling non-boot CPUs ...
[ 63.021633] virtio_blk virtio0: 1/0/0 default/read/poll queues
[ 63.025486] virtio_blk virtio3: 1/0/0 default/read/poll queues
[ 63.035080] hibernate: Hibernating on CPU 0 [mpidr:0x0]
[ 63.039859] PM: Using 1 thread(s) for lzo compression
[ 63.040459] PM: Compressing and saving image data (23314 pages)...
[ 63.041558] PM: Image saving progress: 0%
[ 63.247947] PM: Image saving progress: 10%
[ 63.455279] PM: Image saving progress: 20%
[ 63.619264] PM: Image saving progress: 30%
[ 63.785097] PM: Image saving progress: 40%
[ 63.924669] PM: Image saving progress: 50%
[ 64.018580] PM: Image saving progress: 60%
[ 64.116893] PM: Image saving progress: 70%
[ 64.286410] PM: Image saving progress: 80%
[ 64.490785] PM: Image saving progress: 90%
[ 64.618506] PM: Image saving progress: 100%
[ 64.621388] PM: hibernation: Wrote 93256 kbytes in 1.58 seconds (59.02 MB/s)
[ 64.622108] PM: Image size after compression: 32298 kbytes
[ 64.622702] PM: Image saving done
[ 64.624592] PM: S|
[ 64.777608] PM: Using 1 thread(s) for lzo decompression
[ 64.778448] PM: Loading and decompressing image data (23314 pages)...
[ 64.779237] hibernate: Hibernated on CPU 0 [mpidr:0x0]
[ 64.877435] PM: Image loading progress: 0%
[ 65.172066] PM: Image loading progress: 10%
[ 65.273214] PM: Image loading progress: 20%
[ 65.345142] PM: Image loading progress: 30%
[ 65.454007] PM: Image loading progress: 40%
[ 65.521889] PM: Image loading progress: 50%
[ 65.595804] PM: Image loading progress: 60%
[ 65.659942] PM: Image loading progress: 70%
[ 65.720256] PM: Image loading progress: 80%
[ 65.788729] PM: Image loading progress: 90%
[ 65.851162] PM: Image loading progress: 100%
[ 65.852057] PM: Image loading done
[ 65.853050] PM: hibernation: Read 93256 kbytes in 1.07 seconds (87.15 MB/s)
[ 65.900987] Disabling non-boot CPUs ...
[ 63.012805] hibernate: Restored 0 MTE pages
[ 63.012805] PM: hibernation: free pages cleared after restore
... hang here ...
GDB shows that we are executing code that looks like it came from the poisoned page.
Program received signal SIGINT, Interrupt.
0x000000004d158000 in ?? ()
1: x/i $pc
=> 0x4d158000: orn x10, x21, x10, asr #42
With the patch applied I do not see hang anymore so you can add
Tested-by: Vladimir Murzin <vladimir.murzin@arm.com>
> Speaking off-list to Mark R, he pointed me at some old rework he had for
> all of this:
>
> https://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git/log/?h=arm64/suspend/cleanup
>
> one of the patches there is very similar (identical?) to this one, but
> his series gets us to a point where we _do_ resume at cpu_resume() and,
> tbh, the whole thing ends up making a lot more sense.
>
> If somebody could dust off that two-year old (!) stack, that would be
> great.
>
> Will
>
next prev parent reply other threads:[~2026-09-02 13:07 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-09 21:36 Bradley Morgan
2026-08-11 10:18 ` Will Deacon
2026-08-11 12:50 ` Bradley Morgan
2026-08-11 14:37 ` Will Deacon
2026-08-11 15:49 ` Bradley Morgan
2026-08-17 13:06 ` Vladimir Murzin
2026-08-17 14:15 ` Bradley Morgan
2026-08-24 15:40 ` Will Deacon
2026-09-02 13:07 ` Vladimir Murzin [this message]
2026-09-09 16:15 ` Will Deacon
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=5058854b-6e68-44b2-b4f7-6e2f666c4caf@arm.com \
--to=vladimir.murzin@arm.com \
--cc=catalin.marinas@arm.com \
--cc=include@grrlz.net \
--cc=james.morse@arm.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mark.rutland@arm.com \
--cc=maz@kernel.org \
--cc=pasha.tatashin@soleen.com \
--cc=will@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®