|
| 1 | +From afa9b48f327c9ef36bfba4c643a29385a633252b Mon Sep 17 00:00:00 2001 |
| 2 | +From: Marc Zyngier <maz@kernel.org> |
| 3 | +Date: Thu, 10 Oct 2024 16:13:26 +0100 |
| 4 | +Subject: KVM: arm64: Shave a few bytes from the EL2 idmap code |
| 5 | + |
| 6 | +Our idmap is becoming too big, to the point where it doesn't fit in |
| 7 | +a 4kB page anymore. |
| 8 | + |
| 9 | +There are some low-hanging fruits though, such as the el2_init_state |
| 10 | +horror that is expanded 3 times in the kernel. Let's at least limit |
| 11 | +ourselves to two copies, which makes the kernel link again. |
| 12 | + |
| 13 | +At some point, we'll have to have a better way of doing this. |
| 14 | + |
| 15 | +Reported-by: Nathan Chancellor <nathan@kernel.org> |
| 16 | +Signed-off-by: Marc Zyngier <maz@kernel.org> |
| 17 | +Link: https://lore.kernel.org/r/20241009204903.GA3353168@thelio-3990X |
| 18 | +--- |
| 19 | +Link: https://git.kernel.org/linus/afa9b48f327c9ef36bfba4c643a29385a633252b |
| 20 | +--- |
| 21 | + arch/arm64/include/asm/kvm_asm.h | 1 + |
| 22 | + arch/arm64/kernel/asm-offsets.c | 1 + |
| 23 | + arch/arm64/kvm/hyp/nvhe/hyp-init.S | 52 +++++++++++++++++++++----------------- |
| 24 | + 3 files changed, 31 insertions(+), 23 deletions(-) |
| 25 | + |
| 26 | +diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h |
| 27 | +index b36a3b6cc01169..67afac659231ed 100644 |
| 28 | +--- a/arch/arm64/include/asm/kvm_asm.h |
| 29 | ++++ b/arch/arm64/include/asm/kvm_asm.h |
| 30 | +@@ -178,6 +178,7 @@ struct kvm_nvhe_init_params { |
| 31 | + unsigned long hcr_el2; |
| 32 | + unsigned long vttbr; |
| 33 | + unsigned long vtcr; |
| 34 | ++ unsigned long tmp; |
| 35 | + }; |
| 36 | + |
| 37 | + /* |
| 38 | +diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c |
| 39 | +index 27de1dddb0abee..b21dd24b8efc3b 100644 |
| 40 | +--- a/arch/arm64/kernel/asm-offsets.c |
| 41 | ++++ b/arch/arm64/kernel/asm-offsets.c |
| 42 | +@@ -146,6 +146,7 @@ int main(void) |
| 43 | + DEFINE(NVHE_INIT_HCR_EL2, offsetof(struct kvm_nvhe_init_params, hcr_el2)); |
| 44 | + DEFINE(NVHE_INIT_VTTBR, offsetof(struct kvm_nvhe_init_params, vttbr)); |
| 45 | + DEFINE(NVHE_INIT_VTCR, offsetof(struct kvm_nvhe_init_params, vtcr)); |
| 46 | ++ DEFINE(NVHE_INIT_TMP, offsetof(struct kvm_nvhe_init_params, tmp)); |
| 47 | + #endif |
| 48 | + #ifdef CONFIG_CPU_PM |
| 49 | + DEFINE(CPU_CTX_SP, offsetof(struct cpu_suspend_ctx, sp)); |
| 50 | +diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-init.S b/arch/arm64/kvm/hyp/nvhe/hyp-init.S |
| 51 | +index 401af1835be6b7..fc186622606767 100644 |
| 52 | +--- a/arch/arm64/kvm/hyp/nvhe/hyp-init.S |
| 53 | ++++ b/arch/arm64/kvm/hyp/nvhe/hyp-init.S |
| 54 | +@@ -24,28 +24,25 @@ |
| 55 | + .align 11 |
| 56 | + |
| 57 | + SYM_CODE_START(__kvm_hyp_init) |
| 58 | +- ventry __invalid // Synchronous EL2t |
| 59 | +- ventry __invalid // IRQ EL2t |
| 60 | +- ventry __invalid // FIQ EL2t |
| 61 | +- ventry __invalid // Error EL2t |
| 62 | ++ ventry . // Synchronous EL2t |
| 63 | ++ ventry . // IRQ EL2t |
| 64 | ++ ventry . // FIQ EL2t |
| 65 | ++ ventry . // Error EL2t |
| 66 | + |
| 67 | +- ventry __invalid // Synchronous EL2h |
| 68 | +- ventry __invalid // IRQ EL2h |
| 69 | +- ventry __invalid // FIQ EL2h |
| 70 | +- ventry __invalid // Error EL2h |
| 71 | ++ ventry . // Synchronous EL2h |
| 72 | ++ ventry . // IRQ EL2h |
| 73 | ++ ventry . // FIQ EL2h |
| 74 | ++ ventry . // Error EL2h |
| 75 | + |
| 76 | + ventry __do_hyp_init // Synchronous 64-bit EL1 |
| 77 | +- ventry __invalid // IRQ 64-bit EL1 |
| 78 | +- ventry __invalid // FIQ 64-bit EL1 |
| 79 | +- ventry __invalid // Error 64-bit EL1 |
| 80 | ++ ventry . // IRQ 64-bit EL1 |
| 81 | ++ ventry . // FIQ 64-bit EL1 |
| 82 | ++ ventry . // Error 64-bit EL1 |
| 83 | + |
| 84 | +- ventry __invalid // Synchronous 32-bit EL1 |
| 85 | +- ventry __invalid // IRQ 32-bit EL1 |
| 86 | +- ventry __invalid // FIQ 32-bit EL1 |
| 87 | +- ventry __invalid // Error 32-bit EL1 |
| 88 | +- |
| 89 | +-__invalid: |
| 90 | +- b . |
| 91 | ++ ventry . // Synchronous 32-bit EL1 |
| 92 | ++ ventry . // IRQ 32-bit EL1 |
| 93 | ++ ventry . // FIQ 32-bit EL1 |
| 94 | ++ ventry . // Error 32-bit EL1 |
| 95 | + |
| 96 | + /* |
| 97 | + * Only uses x0..x3 so as to not clobber callee-saved SMCCC registers. |
| 98 | +@@ -76,6 +73,13 @@ __do_hyp_init: |
| 99 | + eret |
| 100 | + SYM_CODE_END(__kvm_hyp_init) |
| 101 | + |
| 102 | ++SYM_CODE_START_LOCAL(__kvm_init_el2_state) |
| 103 | ++ /* Initialize EL2 CPU state to sane values. */ |
| 104 | ++ init_el2_state // Clobbers x0..x2 |
| 105 | ++ finalise_el2_state |
| 106 | ++ ret |
| 107 | ++SYM_CODE_END(__kvm_init_el2_state) |
| 108 | ++ |
| 109 | + /* |
| 110 | + * Initialize the hypervisor in EL2. |
| 111 | + * |
| 112 | +@@ -102,9 +106,12 @@ SYM_CODE_START_LOCAL(___kvm_hyp_init) |
| 113 | + // TPIDR_EL2 is used to preserve x0 across the macro maze... |
| 114 | + isb |
| 115 | + msr tpidr_el2, x0 |
| 116 | +- init_el2_state |
| 117 | +- finalise_el2_state |
| 118 | ++ str lr, [x0, #NVHE_INIT_TMP] |
| 119 | ++ |
| 120 | ++ bl __kvm_init_el2_state |
| 121 | ++ |
| 122 | + mrs x0, tpidr_el2 |
| 123 | ++ ldr lr, [x0, #NVHE_INIT_TMP] |
| 124 | + |
| 125 | + 1: |
| 126 | + ldr x1, [x0, #NVHE_INIT_TPIDR_EL2] |
| 127 | +@@ -199,9 +206,8 @@ SYM_CODE_START_LOCAL(__kvm_hyp_init_cpu) |
| 128 | + |
| 129 | + 2: msr SPsel, #1 // We want to use SP_EL{1,2} |
| 130 | + |
| 131 | +- /* Initialize EL2 CPU state to sane values. */ |
| 132 | +- init_el2_state // Clobbers x0..x2 |
| 133 | +- finalise_el2_state |
| 134 | ++ bl __kvm_init_el2_state |
| 135 | ++ |
| 136 | + __init_el2_nvhe_prepare_eret |
| 137 | + |
| 138 | + /* Enable MMU, set vectors and stack. */ |
| 139 | +-- |
| 140 | +cgit 1.2.3-korg |
| 141 | + |
0 commit comments