1/* SPDX-License-Identifier: GPL-2.0-only */ 2/* 3 * Copyright (C) 2012 - Virtual Open Systems and Columbia University 4 * Author: Christoffer Dall <c.dall@virtualopensystems.com> 5 */ 6 7#include <linux/linkage.h> 8#include <asm/assembler.h> 9#include <asm/unified.h> 10#include <asm/asm-offsets.h> 11#include <asm/kvm_asm.h> 12#include <asm/kvm_arm.h> 13#include <asm/kvm_mmu.h> 14#include <asm/virt.h> 15 16/******************************************************************** 17 * Hypervisor initialization 18 * - should be called with: 19 * r0 = top of Hyp stack (kernel VA) 20 * r1 = pointer to hyp vectors 21 * r2,r3 = Hypervisor pgd pointer 22 * 23 * The init scenario is: 24 * - We jump in HYP with 3 parameters: runtime HYP pgd, runtime stack, 25 * runtime vectors 26 * - Invalidate TLBs 27 * - Set stack and vectors 28 * - Setup the page tables 29 * - Enable the MMU 30 * - Profit! (or eret, if you only care about the code). 31 * 32 * Another possibility is to get a HYP stub hypercall. 33 * We discriminate between the two by checking if r0 contains a value 34 * that is less than HVC_STUB_HCALL_NR. 35 */ 36 37 .text 38 .pushsection .hyp.idmap.text,"ax" 39 .align 5 40__kvm_hyp_init: 41 .globl __kvm_hyp_init 42 43 @ Hyp-mode exception vector 44 W(b) . 45 W(b) . 46 W(b) . 47 W(b) . 48 W(b) . 49 W(b) __do_hyp_init 50 W(b) . 51 W(b) . 52 53__do_hyp_init: 54 @ Check for a stub hypercall 55 cmp r0, #HVC_STUB_HCALL_NR 56 blo __kvm_handle_stub_hvc 57 58 @ Set stack pointer 59 mov sp, r0 60 61 @ Set HVBAR to point to the HYP vectors 62 mcr p15, 4, r1, c12, c0, 0 @ HVBAR 63 64 @ Set the HTTBR to point to the hypervisor PGD pointer passed 65 mcrr p15, 4, rr_lo_hi(r2, r3), c2 66 67 @ Set the HTCR and VTCR to the same shareability and cacheability 68 @ settings as the non-secure TTBCR and with T0SZ == 0. 69 mrc p15, 4, r0, c2, c0, 2 @ HTCR 70 ldr r2, =HTCR_MASK 71 bic r0, r0, r2 72 mrc p15, 0, r1, c2, c0, 2 @ TTBCR 73 and r1, r1, #(HTCR_MASK & ~TTBCR_T0SZ) 74 orr r0, r0, r1 75 mcr p15, 4, r0, c2, c0, 2 @ HTCR 76 77 @ Use the same memory attributes for hyp. accesses as the kernel 78 @ (copy MAIRx ro HMAIRx). 79 mrc p15, 0, r0, c10, c2, 0 80 mcr p15, 4, r0, c10, c2, 0 81 mrc p15, 0, r0, c10, c2, 1 82 mcr p15, 4, r0, c10, c2, 1 83 84 @ Invalidate the stale TLBs from Bootloader 85 mcr p15, 4, r0, c8, c7, 0 @ TLBIALLH 86 dsb ish 87 88 @ Set the HSCTLR to: 89 @ - ARM/THUMB exceptions: Kernel config (Thumb-2 kernel) 90 @ - Endianness: Kernel config 91 @ - Fast Interrupt Features: Kernel config 92 @ - Write permission implies XN: disabled 93 @ - Instruction cache: enabled 94 @ - Data/Unified cache: enabled 95 @ - MMU: enabled (this code must be run from an identity mapping) 96 mrc p15, 4, r0, c1, c0, 0 @ HSCR 97 ldr r2, =HSCTLR_MASK 98 bic r0, r0, r2 99 mrc p15, 0, r1, c1, c0, 0 @ SCTLR 100 ldr r2, =(HSCTLR_EE | HSCTLR_FI | HSCTLR_I | HSCTLR_C) 101 and r1, r1, r2 102 ARM( ldr r2, =(HSCTLR_M) ) 103 THUMB( ldr r2, =(HSCTLR_M | HSCTLR_TE) ) 104 orr r1, r1, r2 105 orr r0, r0, r1 106 mcr p15, 4, r0, c1, c0, 0 @ HSCR 107 isb 108 109 eret 110 111ENTRY(__kvm_handle_stub_hvc) 112 cmp r0, #HVC_SOFT_RESTART 113 bne 1f 114 115 /* The target is expected in r1 */ 116 msr ELR_hyp, r1 117 mrs r0, cpsr 118 bic r0, r0, #MODE_MASK 119 orr r0, r0, #HYP_MODE 120THUMB( orr r0, r0, #PSR_T_BIT ) 121 msr spsr_cxsf, r0 122 b reset 123 1241: cmp r0, #HVC_RESET_VECTORS 125 bne 1f 126 127reset: 128 /* We're now in idmap, disable MMU */ 129 mrc p15, 4, r1, c1, c0, 0 @ HSCTLR 130 ldr r0, =(HSCTLR_M | HSCTLR_A | HSCTLR_C | HSCTLR_I) 131 bic r1, r1, r0 132 mcr p15, 4, r1, c1, c0, 0 @ HSCTLR 133 134 /* 135 * Install stub vectors, using ardb's VA->PA trick. 136 */ 1370: adr r0, 0b @ PA(0) 138 movw r1, #:lower16:__hyp_stub_vectors - 0b @ VA(stub) - VA(0) 139 movt r1, #:upper16:__hyp_stub_vectors - 0b 140 add r1, r1, r0 @ PA(stub) 141 mcr p15, 4, r1, c12, c0, 0 @ HVBAR 142 b exit 143 1441: ldr r0, =HVC_STUB_ERR 145 eret 146 147exit: 148 mov r0, #0 149 eret 150ENDPROC(__kvm_handle_stub_hvc) 151 152 .ltorg 153 154 .globl __kvm_hyp_init_end 155__kvm_hyp_init_end: 156 157 .popsection 158