Index: sys/arm64/arm64/hyp_stub.S =================================================================== --- /dev/null +++ sys/arm64/arm64/hyp_stub.S @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2017 Alexandru Elisei + * Copyright (c) 2020 Andrew Turner + * + * This work was supported by Innovate UK project 105694, "Digital Security + * by Design (DSbD) Technology Platform Prototype". + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +__FBSDID("$FreeBSD$"); + +#include + + .text + +ENTRY(bad_hyp_trap) + adr x0, .Lbad_hyp_trap_msg + bl panic + brk #0 +END(bad_hyp_trap) + +.Lbad_hyp_trap_msg: + .asciz "Unhandled EL2 exception: %lx %lx %lx" + +.align 3 +.Laddr_bad_hyp_trap: + .quad bad_hyp_trap + +.macro vector_tail load_esr = 1 +.if \load_esr == 1 + mrs x1, esr_el2 +.endif + mrs x2, elr_el2 + mrs x3, far_el2 + + /* Load the bad EL2 trap handler to return to */ + ldr x4, .Laddr_bad_hyp_trap + msr elr_el2, x4 + + ERET +.endm + +.macro vempty + .align 7 + vector_tail +.endm + +.macro vector_el1h_sync + .align 7 + + mrs x1, esr_el2 + /* Extract the EC field from esr_el2 */ + lsr x2, x1, #ESR_ELx_EC_SHIFT + cmp x2, #EXCP_HVC + b.ne 1f + + msr vbar_el2, x0 + ERET + +1: + vector_tail 0 +.endm + + .text + .align 11 + .globl hyp_stub_vectors +hyp_stub_vectors: + vempty /* Synchronous EL2t */ + vempty /* IRQ EL2t */ + vempty /* FIQ EL2t */ + vempty /* SError EL2t */ + + vempty /* Synchronous EL2h */ + vempty /* IRQ EL2h */ + vempty /* FIQ EL2h */ + vempty /* SError EL2h */ + + vector_el1h_sync /* Synchronous 64-bit EL1 */ + vempty /* IRQ 64-bit EL1 */ + vempty /* FIQ 64-bit EL1 */ + vempty /* SError 64-bit EL1 */ + + vempty /* Synchronous 32-bit EL1 */ + vempty /* IRQ 32-bit EL1 */ + vempty /* FIQ 32-bit EL1 */ + vempty /* SError 32-bit EL1 */ Index: sys/arm64/arm64/locore.S =================================================================== --- sys/arm64/arm64/locore.S +++ sys/arm64/arm64/locore.S @@ -62,7 +62,6 @@ * but in this case the code to find where we are running from * would have also failed. */ - dsb sy mrs x2, sctlr_el1 bic x2, x2, SCTLR_M msr sctlr_el1, x2 @@ -224,8 +223,22 @@ b.eq 1f ret 1: - /* Configure the Hypervisor */ - mov x2, #(HCR_RW) + /* + * If the MMU is active, then it is using a page table where VA == PA. + * But the page table won't have entries for the hypervisor EL2 + * initialization code which is loaded into memory with the vmm module. + * + * So we disable the MMU in EL2 to make the vmm hypervisor code run + * successfully. + */ + dsb sy + mrs x2, sctlr_el2 + bic x2, x2, SCTLR_M + msr sctlr_el2, x2 + isb + + /* Enable the HVC Instruction and Make EL1 aarch64 */ + ldr x2, hcr msr hcr_el2, x2 /* Load the Virtualization Process ID Register */ @@ -255,11 +268,15 @@ /* Set the counter offset to a known value */ msr cntvoff_el2, xzr - /* Hypervisor trap functions */ - adrp x2, hyp_vectors - add x2, x2, :lo12:hyp_vectors + /* Install hypervisor trap functions */ + adrp x2, hyp_stub_vectors + add x2, x2, :lo12:hyp_stub_vectors msr vbar_el2, x2 + /* Use the host VTTBR_EL2 to tell the host and the guests apart */ + mov x2, #VTTBR_HOST + msr vttbr_el2, x2 + mov x2, #(PSR_F | PSR_I | PSR_A | PSR_D | PSR_M_EL1h) msr spsr_el2, x2 @@ -288,31 +305,9 @@ .quad SCTLR_RES1 LEND(drop_to_el1) -#define VECT_EMPTY \ - .align 7; \ - 1: b 1b - - .align 11 -hyp_vectors: - VECT_EMPTY /* Synchronous EL2t */ - VECT_EMPTY /* IRQ EL2t */ - VECT_EMPTY /* FIQ EL2t */ - VECT_EMPTY /* Error EL2t */ - - VECT_EMPTY /* Synchronous EL2h */ - VECT_EMPTY /* IRQ EL2h */ - VECT_EMPTY /* FIQ EL2h */ - VECT_EMPTY /* Error EL2h */ - - VECT_EMPTY /* Synchronous 64-bit EL1 */ - VECT_EMPTY /* IRQ 64-bit EL1 */ - VECT_EMPTY /* FIQ 64-bit EL1 */ - VECT_EMPTY /* Error 64-bit EL1 */ - - VECT_EMPTY /* Synchronous 32-bit EL1 */ - VECT_EMPTY /* IRQ 32-bit EL1 */ - VECT_EMPTY /* FIQ 32-bit EL1 */ - VECT_EMPTY /* Error 32-bit EL1 */ +hcr: + /* Make sure the HVC instruction is not disabled */ + .quad (HCR_RW & ~HCR_HCD) /* * Get the delta between the physical address we were loaded to and the Index: sys/conf/files.arm64 =================================================================== --- sys/conf/files.arm64 +++ sys/conf/files.arm64 @@ -173,6 +173,7 @@ arm64/arm64/gic_v3.c standard arm64/arm64/gic_v3_acpi.c optional acpi arm64/arm64/gic_v3_fdt.c optional fdt +arm64/arm64/hyp_stub.S standard arm64/arm64/identcpu.c standard arm64/arm64/in_cksum.c optional inet | inet6 arm64/arm64/locore.S standard no-obj