Re: [PATCH] arm64: hibernate: pass HVC_SET_VECTORS args to the resume hvc

Will Deacon <[email protected]>
Newsgroups org.infradead.lists.linux-arm-kernel,org.kernel.vger.linux-kernel
Message-ID <aoxl1ri43eEAsxlR@willie-the-truck>
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.

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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.