1/* SPDX-License-Identifier: GPL-2.0-only */ 2/* 3 * Copyright (C) 2020 - Google Inc 4 * Author: Andrew Scull <ascull@google.com> 5 */ 6 7#include <linux/linkage.h> 8 9#include <asm/assembler.h> 10#include <asm/kvm_asm.h> 11#include <asm/kvm_mmu.h> 12 13 .text 14 15SYM_FUNC_START(__hyp_do_panic) 16 mov lr, #(PSR_F_BIT | PSR_I_BIT | PSR_A_BIT | PSR_D_BIT |\ 17 PSR_MODE_EL1h) 18 msr spsr_el2, lr 19 ldr lr, =panic 20 msr elr_el2, lr 21 eret 22 sb 23SYM_FUNC_END(__hyp_do_panic) 24 25.macro host_el1_sync_vect 26 .align 7 27.L__vect_start\@: 28 esb 29 stp x0, x1, [sp, #-16]! 30 mrs x0, esr_el2 31 lsr x0, x0, #ESR_ELx_EC_SHIFT 32 cmp x0, #ESR_ELx_EC_HVC64 33 ldp x0, x1, [sp], #16 34 b.ne hyp_panic 35 36 /* Check for a stub HVC call */ 37 cmp x0, #HVC_STUB_HCALL_NR 38 b.hs 1f 39 40 /* 41 * Compute the idmap address of __kvm_handle_stub_hvc and 42 * jump there. Since we use kimage_voffset, do not use the 43 * HYP VA for __kvm_handle_stub_hvc, but the kernel VA instead 44 * (by loading it from the constant pool). 45 * 46 * Preserve x0-x4, which may contain stub parameters. 47 */ 48 ldr x5, =__kvm_handle_stub_hvc 49 ldr_l x6, kimage_voffset 50 51 /* x5 = __pa(x5) */ 52 sub x5, x5, x6 53 br x5 54 551: 56 /* 57 * Shuffle the parameters before calling the function 58 * pointed to in x0. Assumes parameters in x[1,2,3]. 59 */ 60 kern_hyp_va x0 61 str lr, [sp, #-16]! 62 mov lr, x0 63 mov x0, x1 64 mov x1, x2 65 mov x2, x3 66 blr lr 67 ldr lr, [sp], #16 68 69 eret 70 sb 71.L__vect_end\@: 72.if ((.L__vect_end\@ - .L__vect_start\@) > 0x80) 73 .error "host_el1_sync_vect larger than vector entry" 74.endif 75.endm 76 77.macro invalid_host_vect 78 .align 7 79 b hyp_panic 80.endm 81 82/* 83 * CONFIG_KVM_INDIRECT_VECTORS is not applied to the host vectors because the 84 * host knows about the EL2 vectors already, and there is no point in hiding 85 * them. 86 */ 87 .align 11 88SYM_CODE_START(__kvm_hyp_host_vector) 89 invalid_host_vect // Synchronous EL2t 90 invalid_host_vect // IRQ EL2t 91 invalid_host_vect // FIQ EL2t 92 invalid_host_vect // Error EL2t 93 94 invalid_host_vect // Synchronous EL2h 95 invalid_host_vect // IRQ EL2h 96 invalid_host_vect // FIQ EL2h 97 invalid_host_vect // Error EL2h 98 99 host_el1_sync_vect // Synchronous 64-bit EL1 100 invalid_host_vect // IRQ 64-bit EL1 101 invalid_host_vect // FIQ 64-bit EL1 102 invalid_host_vect // Error 64-bit EL1 103 104 invalid_host_vect // Synchronous 32-bit EL1 105 invalid_host_vect // IRQ 32-bit EL1 106 invalid_host_vect // FIQ 32-bit EL1 107 invalid_host_vect // Error 32-bit EL1 108SYM_CODE_END(__kvm_hyp_host_vector) 109