1 /* SPDX-License-Identifier: GPL-2.0-only */
3 * Copyright (C) 2012 - Virtual Open Systems and Columbia University
4 * Author: Christoffer Dall <c.dall@virtualopensystems.com>
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>
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
23 * The init scenario is:
24 * - We jump in HYP with 3 parameters: runtime HYP pgd, runtime stack,
27 * - Set stack and vectors
28 * - Setup the page tables
30 * - Profit! (or eret, if you only care about the code).
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.
38 .pushsection .hyp.idmap.text,"ax"
43 @ Hyp-mode exception vector
54 @ Check for a stub hypercall
55 cmp r0, #HVC_STUB_HCALL_NR
56 blo __kvm_handle_stub_hvc
61 @ Set HVBAR to point to the HYP vectors
62 mcr p15, 4, r1, c12, c0, 0 @ HVBAR
64 @ Set the HTTBR to point to the hypervisor PGD pointer passed
65 mcrr p15, 4, rr_lo_hi(r2, r3), c2
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
72 mrc p15, 0, r1, c2, c0, 2 @ TTBCR
73 and r1, r1, #(HTCR_MASK & ~TTBCR_T0SZ)
75 mcr p15, 4, r0, c2, c0, 2 @ HTCR
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
84 @ Invalidate the stale TLBs from Bootloader
85 mcr p15, 4, r0, c8, c7, 0 @ TLBIALLH
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
99 mrc p15, 0, r1, c1, c0, 0 @ SCTLR
100 ldr r2, =(HSCTLR_EE | HSCTLR_FI | HSCTLR_I | HSCTLR_C)
102 ARM( ldr r2, =(HSCTLR_M) )
103 THUMB( ldr r2, =(HSCTLR_M | HSCTLR_TE) )
106 mcr p15, 4, r0, c1, c0, 0 @ HSCR
111 ENTRY(__kvm_handle_stub_hvc)
112 cmp r0, #HVC_SOFT_RESTART
115 /* The target is expected in r1 */
118 bic r0, r0, #MODE_MASK
119 orr r0, r0, #HYP_MODE
120 THUMB( orr r0, r0, #PSR_T_BIT )
124 1: cmp r0, #HVC_RESET_VECTORS
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)
132 mcr p15, 4, r1, c1, c0, 0 @ HSCTLR
135 * Install stub vectors, using ardb's VA->PA trick.
137 0: 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
144 1: ldr r0, =HVC_STUB_ERR
150 ENDPROC(__kvm_handle_stub_hvc)
154 .globl __kvm_hyp_init_end