Re: [PATCHv3 3/4] x86/64/kexec: Map original relocate_kernel() in init_transition_pgtable()
From: Huang, Kai
Date: Tue Aug 20 2024 - 07:06:52 EST
> >
> > So the (*) can actually access to the control page IIUC.
> >
> > Now if we change to map VA of relocate_kernel() to the original one, then (*)
> > won't be able to access the control page.
>
> No, it still will be able to access control page.
>
> So we call relocate_kernel() in normal kernel text (within
> __START_KERNEL_map).
>
> relocate_kernel() switches to identity mapping, VA is still the same.
>
> relocate_kernel() jumps to identity_mapped() in the control page:
>
>
> /*
> * get physical address of control page now
> * this is impossible after page table switch
> */
> movq PTR(PA_CONTROL_PAGE)(%rsi), %r8
>
> ...
>
> /* jump to identity mapped page */
> addq $(identity_mapped - relocate_kernel), %r8
> pushq %r8
> ANNOTATE_UNRET_SAFE
> ret
>
> The ADDQ finds offset of identity_mapped() in the control page.
>
> identity_mapping() finds start of the control page from *relative*
> position of relocate_page() to the current RIP in the control page:
>
> leaq relocate_kernel(%rip), %r8
>
> It looks like this in my kernel binary:
>
> lea -0xfa(%rip),%r8
Ah I see. I missed the *relative* addressing. :-)
>
> What PA is mapped at the normal kernel text VA of relocate_kernel() makes
> zero affect to the calculation.
Yeah.
>
> Does it make sense?
>
Yes. Thanks for explanation.
At later time:
call swap_pages
movq $virtual_mapped, %rax <---- (1)
pushq %rax
ANNOTATE_UNRET_SAFE
ret <---- (2)
(1) will load the VA which has __START_KERNEL_map to %rax, and after (2) the
kernel will run at VA of the original relocate_kernel() which maps to the PA
of the original relcoate_kernel(). But I think the memory page of the
original relocate_kernel() won't get corrupted after returning from the second
kernel, so should be safe to use?