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

arm: KVM: Simplify HYP init

Just like for arm64, we can now make the HYP setup a lot simpler,
and we can now initialise it in one go (instead of the two
phases we currently have).

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>

authored by

Marc Zyngier and committed by
Christoffer Dall
cd602a37 26781f9c

+14 -50
+5 -10
arch/arm/include/asm/kvm_host.h
··· 250 250 * code. The init code doesn't need to preserve these 251 251 * registers as r0-r3 are already callee saved according to 252 252 * the AAPCS. 253 - * Note that we slightly misuse the prototype by casing the 253 + * Note that we slightly misuse the prototype by casting the 254 254 * stack pointer to a void *. 255 - * 256 - * We don't have enough registers to perform the full init in 257 - * one go. Install the boot PGD first, and then install the 258 - * runtime PGD, stack pointer and vectors. The PGDs are always 259 - * passed as the third argument, in order to be passed into 260 - * r2-r3 to the init code (yes, this is compliant with the 261 - * PCS!). 262 - */ 263 255 264 - kvm_call_hyp(NULL, 0, boot_pgd_ptr); 256 + * The PGDs are always passed as the third argument, in order 257 + * to be passed into r2-r3 to the init code (yes, this is 258 + * compliant with the PCS!). 259 + */ 265 260 266 261 kvm_call_hyp((void*)hyp_stack_ptr, vector_ptr, pgd_ptr); 267 262 }
+9 -40
arch/arm/kvm/init.S
··· 32 32 * r2,r3 = Hypervisor pgd pointer 33 33 * 34 34 * The init scenario is: 35 - * - We jump in HYP with four parameters: boot HYP pgd, runtime HYP pgd, 36 - * runtime stack, runtime vectors 37 - * - Enable the MMU with the boot pgd 38 - * - Jump to a target into the trampoline page (remember, this is the same 39 - * physical page!) 40 - * - Now switch to the runtime pgd (same VA, and still the same physical 41 - * page!) 35 + * - We jump in HYP with 3 parameters: runtime HYP pgd, runtime stack, 36 + * runtime vectors 42 37 * - Invalidate TLBs 43 38 * - Set stack and vectors 39 + * - Setup the page tables 40 + * - Enable the MMU 44 41 * - Profit! (or eret, if you only care about the code). 45 - * 46 - * As we only have four registers available to pass parameters (and we 47 - * need six), we split the init in two phases: 48 - * - Phase 1: r0 = 0, r1 = 0, r2,r3 contain the boot PGD. 49 - * Provides the basic HYP init, and enable the MMU. 50 - * - Phase 2: r0 = ToS, r1 = vectors, r2,r3 contain the runtime PGD. 51 - * Switches to the runtime PGD, set stack and vectors. 52 42 */ 53 43 54 44 .text ··· 58 68 W(b) . 59 69 60 70 __do_hyp_init: 61 - cmp r0, #0 @ We have a SP? 62 - bne phase2 @ Yes, second stage init 71 + @ Set stack pointer 72 + mov sp, r0 73 + 74 + @ Set HVBAR to point to the HYP vectors 75 + mcr p15, 4, r1, c12, c0, 0 @ HVBAR 63 76 64 77 @ Set the HTTBR to point to the hypervisor PGD pointer passed 65 78 mcrr p15, 4, rr_lo_hi(r2, r3), c2 ··· 107 114 THUMB( ldr r2, =(HSCTLR_M | HSCTLR_A | HSCTLR_TE) ) 108 115 orr r1, r1, r2 109 116 orr r0, r0, r1 110 - isb 111 117 mcr p15, 4, r0, c1, c0, 0 @ HSCR 112 - 113 - @ End of init phase-1 114 - eret 115 - 116 - phase2: 117 - @ Set stack pointer 118 - mov sp, r0 119 - 120 - @ Set HVBAR to point to the HYP vectors 121 - mcr p15, 4, r1, c12, c0, 0 @ HVBAR 122 - 123 - @ Jump to the trampoline page 124 - ldr r0, =TRAMPOLINE_VA 125 - adr r1, target 126 - bfi r0, r1, #0, #PAGE_SHIFT 127 - ret r0 128 - 129 - target: @ We're now in the trampoline code, switch page tables 130 - mcrr p15, 4, rr_lo_hi(r2, r3), c2 131 118 isb 132 - 133 - @ Invalidate the old TLBs 134 - mcr p15, 4, r0, c8, c7, 0 @ TLBIALLH 135 - dsb ish 136 119 137 120 eret 138 121