Commit afa9b48f authored by Marc Zyngier's avatar Marc Zyngier

KVM: arm64: Shave a few bytes from the EL2 idmap code

Our idmap is becoming too big, to the point where it doesn't fit in
a 4kB page anymore.

There are some low-hanging fruits though, such as the el2_init_state
horror that is expanded 3 times in the kernel. Let's at least limit
ourselves to two copies, which makes the kernel link again.

At some point, we'll have to have a better way of doing this.
Reported-by: default avatarNathan Chancellor <nathan@kernel.org>
Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20241009204903.GA3353168@thelio-3990X
parent df5fd75e
...@@ -178,6 +178,7 @@ struct kvm_nvhe_init_params { ...@@ -178,6 +178,7 @@ struct kvm_nvhe_init_params {
unsigned long hcr_el2; unsigned long hcr_el2;
unsigned long vttbr; unsigned long vttbr;
unsigned long vtcr; unsigned long vtcr;
unsigned long tmp;
}; };
/* /*
......
...@@ -146,6 +146,7 @@ int main(void) ...@@ -146,6 +146,7 @@ int main(void)
DEFINE(NVHE_INIT_HCR_EL2, offsetof(struct kvm_nvhe_init_params, hcr_el2)); DEFINE(NVHE_INIT_HCR_EL2, offsetof(struct kvm_nvhe_init_params, hcr_el2));
DEFINE(NVHE_INIT_VTTBR, offsetof(struct kvm_nvhe_init_params, vttbr)); DEFINE(NVHE_INIT_VTTBR, offsetof(struct kvm_nvhe_init_params, vttbr));
DEFINE(NVHE_INIT_VTCR, offsetof(struct kvm_nvhe_init_params, vtcr)); DEFINE(NVHE_INIT_VTCR, offsetof(struct kvm_nvhe_init_params, vtcr));
DEFINE(NVHE_INIT_TMP, offsetof(struct kvm_nvhe_init_params, tmp));
#endif #endif
#ifdef CONFIG_CPU_PM #ifdef CONFIG_CPU_PM
DEFINE(CPU_CTX_SP, offsetof(struct cpu_suspend_ctx, sp)); DEFINE(CPU_CTX_SP, offsetof(struct cpu_suspend_ctx, sp));
......
...@@ -24,28 +24,25 @@ ...@@ -24,28 +24,25 @@
.align 11 .align 11
SYM_CODE_START(__kvm_hyp_init) SYM_CODE_START(__kvm_hyp_init)
ventry __invalid // Synchronous EL2t ventry . // Synchronous EL2t
ventry __invalid // IRQ EL2t ventry . // IRQ EL2t
ventry __invalid // FIQ EL2t ventry . // FIQ EL2t
ventry __invalid // Error EL2t ventry . // Error EL2t
ventry __invalid // Synchronous EL2h ventry . // Synchronous EL2h
ventry __invalid // IRQ EL2h ventry . // IRQ EL2h
ventry __invalid // FIQ EL2h ventry . // FIQ EL2h
ventry __invalid // Error EL2h ventry . // Error EL2h
ventry __do_hyp_init // Synchronous 64-bit EL1 ventry __do_hyp_init // Synchronous 64-bit EL1
ventry __invalid // IRQ 64-bit EL1 ventry . // IRQ 64-bit EL1
ventry __invalid // FIQ 64-bit EL1 ventry . // FIQ 64-bit EL1
ventry __invalid // Error 64-bit EL1 ventry . // Error 64-bit EL1
ventry __invalid // Synchronous 32-bit EL1 ventry . // Synchronous 32-bit EL1
ventry __invalid // IRQ 32-bit EL1 ventry . // IRQ 32-bit EL1
ventry __invalid // FIQ 32-bit EL1 ventry . // FIQ 32-bit EL1
ventry __invalid // Error 32-bit EL1 ventry . // Error 32-bit EL1
__invalid:
b .
/* /*
* Only uses x0..x3 so as to not clobber callee-saved SMCCC registers. * Only uses x0..x3 so as to not clobber callee-saved SMCCC registers.
...@@ -76,6 +73,13 @@ __do_hyp_init: ...@@ -76,6 +73,13 @@ __do_hyp_init:
eret eret
SYM_CODE_END(__kvm_hyp_init) SYM_CODE_END(__kvm_hyp_init)
SYM_CODE_START_LOCAL(__kvm_init_el2_state)
/* Initialize EL2 CPU state to sane values. */
init_el2_state // Clobbers x0..x2
finalise_el2_state
ret
SYM_CODE_END(__kvm_init_el2_state)
/* /*
* Initialize the hypervisor in EL2. * Initialize the hypervisor in EL2.
* *
...@@ -102,9 +106,12 @@ SYM_CODE_START_LOCAL(___kvm_hyp_init) ...@@ -102,9 +106,12 @@ SYM_CODE_START_LOCAL(___kvm_hyp_init)
// TPIDR_EL2 is used to preserve x0 across the macro maze... // TPIDR_EL2 is used to preserve x0 across the macro maze...
isb isb
msr tpidr_el2, x0 msr tpidr_el2, x0
init_el2_state str lr, [x0, #NVHE_INIT_TMP]
finalise_el2_state
bl __kvm_init_el2_state
mrs x0, tpidr_el2 mrs x0, tpidr_el2
ldr lr, [x0, #NVHE_INIT_TMP]
1: 1:
ldr x1, [x0, #NVHE_INIT_TPIDR_EL2] ldr x1, [x0, #NVHE_INIT_TPIDR_EL2]
...@@ -199,9 +206,8 @@ SYM_CODE_START_LOCAL(__kvm_hyp_init_cpu) ...@@ -199,9 +206,8 @@ SYM_CODE_START_LOCAL(__kvm_hyp_init_cpu)
2: msr SPsel, #1 // We want to use SP_EL{1,2} 2: msr SPsel, #1 // We want to use SP_EL{1,2}
/* Initialize EL2 CPU state to sane values. */ bl __kvm_init_el2_state
init_el2_state // Clobbers x0..x2
finalise_el2_state
__init_el2_nvhe_prepare_eret __init_el2_nvhe_prepare_eret
/* Enable MMU, set vectors and stack. */ /* Enable MMU, set vectors and stack. */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment