Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch kvm-arm64/pkvm-psci into kvmarm-master/next

* kvm-arm64/pkvm-psci:
: .
: Cleanup of the pKVM PSCI relay CPU entry code, making it slightly
: easier to follow, should someone have to wade into these waters
: ever again.
: .
KVM: arm64: Remove extra ISBs when using msr_hcr_el2
KVM: arm64: pkvm: Use direct function pointers for cpu_{on,resume}
KVM: arm64: pkvm: Turn __kvm_hyp_init_cpu into an inner label
KVM: arm64: pkvm: Simplify BTI handling on CPU boot
KVM: arm64: pkvm: Move error handling to the end of kvm_hyp_cpu_entry

Signed-off-by: Marc Zyngier <maz@kernel.org>

+43 -59
-2
arch/arm64/include/asm/el2_setup.h
··· 50 50 * effectively VHE-only or not. 51 51 */ 52 52 msr_hcr_el2 x0 // Setup HCR_EL2 as nVHE 53 - isb 54 53 mov x1, #1 // Write something to FAR_EL1 55 54 msr far_el1, x1 56 55 isb ··· 63 64 .LnE2H0_\@: 64 65 orr x0, x0, #HCR_E2H 65 66 msr_hcr_el2 x0 66 - isb 67 67 .LnVHE_\@: 68 68 .endm 69 69
+2 -1
arch/arm64/include/asm/kvm_asm.h
··· 301 301 asmlinkage void kvm_unexpected_el2_exception(void); 302 302 struct kvm_cpu_context; 303 303 void handle_trap(struct kvm_cpu_context *host_ctxt); 304 - asmlinkage void __noreturn __kvm_host_psci_cpu_entry(bool is_cpu_on); 304 + asmlinkage void __noreturn __kvm_host_psci_cpu_on_entry(void); 305 + asmlinkage void __noreturn __kvm_host_psci_cpu_resume_entry(void); 305 306 void __noreturn __pkvm_init_finalise(void); 306 307 void kvm_nvhe_prepare_backtrace(unsigned long fp, unsigned long pc); 307 308 void kvm_patch_vector_branch(struct alt_instr *alt,
+2 -4
arch/arm64/include/asm/sysreg.h
··· 1121 1121 .macro msr_hcr_el2, reg 1122 1122 #if IS_ENABLED(CONFIG_AMPERE_ERRATUM_AC04_CPU_23) 1123 1123 dsb nsh 1124 - msr hcr_el2, \reg 1125 - isb 1126 - #else 1127 - msr hcr_el2, \reg 1128 1124 #endif 1125 + msr hcr_el2, \reg 1126 + isb // Required by AMPERE_ERRATUM_AC04_CPU_23 1129 1127 .endm 1130 1128 #else 1131 1129
-1
arch/arm64/kernel/hyp-stub.S
··· 103 103 // Engage the VHE magic! 104 104 mov_q x0, HCR_HOST_VHE_FLAGS 105 105 msr_hcr_el2 x0 106 - isb 107 106 108 107 // Use the EL1 allocated stack, per-cpu offset 109 108 mrs x0, sp_el1
-11
arch/arm64/kvm/hyp/nvhe/host.S
··· 125 125 mrs x0, hcr_el2 126 126 bic x0, x0, #HCR_VM 127 127 msr_hcr_el2 x0 128 - isb 129 128 tlbi vmalls12e1 130 129 dsb nsh 131 130 #endif ··· 290 291 291 292 ret 292 293 SYM_CODE_END(__kvm_hyp_host_forward_smc) 293 - 294 - /* 295 - * kvm_host_psci_cpu_entry is called through br instruction, which requires 296 - * bti j instruction as compilers (gcc and llvm) doesn't insert bti j for external 297 - * functions, but bti c instead. 298 - */ 299 - SYM_CODE_START(kvm_host_psci_cpu_entry) 300 - bti j 301 - b __kvm_host_psci_cpu_entry 302 - SYM_CODE_END(kvm_host_psci_cpu_entry)
+15 -26
arch/arm64/kvm/hyp/nvhe/hyp-init.S
··· 173 173 * x0: struct kvm_nvhe_init_params PA 174 174 */ 175 175 SYM_CODE_START(kvm_hyp_cpu_entry) 176 - mov x1, #1 // is_cpu_on = true 176 + ldr x29, =__kvm_host_psci_cpu_on_entry 177 177 b __kvm_hyp_init_cpu 178 - SYM_CODE_END(kvm_hyp_cpu_entry) 179 178 180 179 /* 181 180 * PSCI CPU_SUSPEND / SYSTEM_SUSPEND entry point ··· 182 183 * x0: struct kvm_nvhe_init_params PA 183 184 */ 184 185 SYM_CODE_START(kvm_hyp_cpu_resume) 185 - mov x1, #0 // is_cpu_on = false 186 - b __kvm_hyp_init_cpu 187 - SYM_CODE_END(kvm_hyp_cpu_resume) 186 + ldr x29, =__kvm_host_psci_cpu_resume_entry 188 187 189 - /* 190 - * Common code for CPU entry points. Initializes EL2 state and 191 - * installs the hypervisor before handing over to a C handler. 192 - * 193 - * x0: struct kvm_nvhe_init_params PA 194 - * x1: bool is_cpu_on 195 - */ 196 - SYM_CODE_START_LOCAL(__kvm_hyp_init_cpu) 188 + SYM_INNER_LABEL(__kvm_hyp_init_cpu, SYM_L_LOCAL) 197 189 mov x28, x0 // Stash arguments 198 - mov x29, x1 199 190 200 191 /* Check that the core was booted in EL2. */ 201 192 mrs x0, CurrentEL 202 193 cmp x0, #CurrentEL_EL2 203 - b.eq 2f 194 + b.ne 1f 204 195 205 - /* The core booted in EL1. KVM cannot be initialized on it. */ 206 - 1: wfe 207 - wfi 208 - b 1b 209 - 210 - 2: msr SPsel, #1 // We want to use SP_EL{1,2} 196 + msr SPsel, #1 // We want to use SP_EL2 211 197 212 198 init_el2_hcr 0 213 199 ··· 202 218 mov x0, x28 203 219 bl ___kvm_hyp_init // Clobbers x0..x2 204 220 205 - /* Leave idmap. */ 206 - mov x0, x29 207 - ldr x1, =kvm_host_psci_cpu_entry 208 - br x1 209 - SYM_CODE_END(__kvm_hyp_init_cpu) 221 + /* Leave idmap -- using BLR is OK, LR is restored from host context */ 222 + blr x29 223 + 224 + // The core booted in EL1, or the C code unexpectedly returned. 225 + // Either way, KVM cannot be initialized on it. 226 + 1: wfe 227 + wfi 228 + b 1b 229 + SYM_CODE_END(kvm_hyp_cpu_resume) 230 + SYM_CODE_END(kvm_hyp_cpu_entry) 210 231 211 232 SYM_CODE_START(__kvm_handle_stub_hvc) 212 233 /*
+24 -14
arch/arm64/kvm/hyp/nvhe/psci-relay.c
··· 201 201 __hyp_pa(init_params), 0); 202 202 } 203 203 204 - asmlinkage void __noreturn __kvm_host_psci_cpu_entry(bool is_cpu_on) 204 + static void __noreturn __kvm_host_psci_cpu_entry(unsigned long pc, unsigned long r0) 205 205 { 206 - struct psci_boot_args *boot_args; 207 - struct kvm_cpu_context *host_ctxt; 206 + struct kvm_cpu_context *host_ctxt = host_data_ptr(host_ctxt); 208 207 209 - host_ctxt = host_data_ptr(host_ctxt); 210 208 trace_hyp_enter(host_ctxt, HYP_REASON_PSCI); 211 209 212 - if (is_cpu_on) 213 - boot_args = this_cpu_ptr(&cpu_on_args); 214 - else 215 - boot_args = this_cpu_ptr(&suspend_args); 216 - 217 - cpu_reg(host_ctxt, 0) = boot_args->r0; 218 - write_sysreg_el2(boot_args->pc, SYS_ELR); 219 - 220 - if (is_cpu_on) 221 - release_boot_args(boot_args); 210 + cpu_reg(host_ctxt, 0) = r0; 211 + write_sysreg_el2(pc, SYS_ELR); 222 212 223 213 write_sysreg_el1(INIT_SCTLR_EL1_MMU_OFF, SYS_SCTLR); 224 214 write_sysreg(INIT_PSTATE_EL1, SPSR_EL2); 225 215 226 216 trace_hyp_exit(host_ctxt, HYP_REASON_PSCI); 227 217 __host_enter(host_ctxt); 218 + } 219 + 220 + asmlinkage void __noreturn __kvm_host_psci_cpu_on_entry(void) 221 + { 222 + struct psci_boot_args *boot_args = this_cpu_ptr(&cpu_on_args); 223 + unsigned long pc, r0; 224 + 225 + pc = READ_ONCE(boot_args->pc); 226 + r0 = READ_ONCE(boot_args->r0); 227 + 228 + release_boot_args(boot_args); 229 + 230 + __kvm_host_psci_cpu_entry(pc, r0); 231 + } 232 + 233 + asmlinkage void __noreturn __kvm_host_psci_cpu_resume_entry(void) 234 + { 235 + struct psci_boot_args *boot_args = this_cpu_ptr(&suspend_args); 236 + 237 + __kvm_host_psci_cpu_entry(boot_args->pc, boot_args->r0); 228 238 } 229 239 230 240 static unsigned long psci_0_1_handler(u64 func_id, struct kvm_cpu_context *host_ctxt)