1*67730e6cSSean Christopherson/* SPDX-License-Identifier: GPL-2.0 */ 2*67730e6cSSean Christopherson.macro save_registers 3*67730e6cSSean Christopherson add sp, sp, #-16 * 17 4*67730e6cSSean Christopherson 5*67730e6cSSean Christopherson stp x0, x1, [sp, #16 * 0] 6*67730e6cSSean Christopherson stp x2, x3, [sp, #16 * 1] 7*67730e6cSSean Christopherson stp x4, x5, [sp, #16 * 2] 8*67730e6cSSean Christopherson stp x6, x7, [sp, #16 * 3] 9*67730e6cSSean Christopherson stp x8, x9, [sp, #16 * 4] 10*67730e6cSSean Christopherson stp x10, x11, [sp, #16 * 5] 11*67730e6cSSean Christopherson stp x12, x13, [sp, #16 * 6] 12*67730e6cSSean Christopherson stp x14, x15, [sp, #16 * 7] 13*67730e6cSSean Christopherson stp x16, x17, [sp, #16 * 8] 14*67730e6cSSean Christopherson stp x18, x19, [sp, #16 * 9] 15*67730e6cSSean Christopherson stp x20, x21, [sp, #16 * 10] 16*67730e6cSSean Christopherson stp x22, x23, [sp, #16 * 11] 17*67730e6cSSean Christopherson stp x24, x25, [sp, #16 * 12] 18*67730e6cSSean Christopherson stp x26, x27, [sp, #16 * 13] 19*67730e6cSSean Christopherson stp x28, x29, [sp, #16 * 14] 20*67730e6cSSean Christopherson 21*67730e6cSSean Christopherson /* 22*67730e6cSSean Christopherson * This stores sp_el1 into ex_regs.sp so exception handlers can "look" 23*67730e6cSSean Christopherson * at it. It will _not_ be used to restore the sp on return from the 24*67730e6cSSean Christopherson * exception so handlers can not update it. 25*67730e6cSSean Christopherson */ 26*67730e6cSSean Christopherson add x1, sp, #16 * 17 27*67730e6cSSean Christopherson stp x30, x1, [sp, #16 * 15] /* x30, SP */ 28*67730e6cSSean Christopherson 29*67730e6cSSean Christopherson mrs x1, elr_el1 30*67730e6cSSean Christopherson mrs x2, spsr_el1 31*67730e6cSSean Christopherson stp x1, x2, [sp, #16 * 16] /* PC, PSTATE */ 32*67730e6cSSean Christopherson.endm 33*67730e6cSSean Christopherson 34*67730e6cSSean Christopherson.macro restore_registers 35*67730e6cSSean Christopherson ldp x1, x2, [sp, #16 * 16] /* PC, PSTATE */ 36*67730e6cSSean Christopherson msr elr_el1, x1 37*67730e6cSSean Christopherson msr spsr_el1, x2 38*67730e6cSSean Christopherson 39*67730e6cSSean Christopherson /* sp is not restored */ 40*67730e6cSSean Christopherson ldp x30, xzr, [sp, #16 * 15] /* x30, SP */ 41*67730e6cSSean Christopherson 42*67730e6cSSean Christopherson ldp x28, x29, [sp, #16 * 14] 43*67730e6cSSean Christopherson ldp x26, x27, [sp, #16 * 13] 44*67730e6cSSean Christopherson ldp x24, x25, [sp, #16 * 12] 45*67730e6cSSean Christopherson ldp x22, x23, [sp, #16 * 11] 46*67730e6cSSean Christopherson ldp x20, x21, [sp, #16 * 10] 47*67730e6cSSean Christopherson ldp x18, x19, [sp, #16 * 9] 48*67730e6cSSean Christopherson ldp x16, x17, [sp, #16 * 8] 49*67730e6cSSean Christopherson ldp x14, x15, [sp, #16 * 7] 50*67730e6cSSean Christopherson ldp x12, x13, [sp, #16 * 6] 51*67730e6cSSean Christopherson ldp x10, x11, [sp, #16 * 5] 52*67730e6cSSean Christopherson ldp x8, x9, [sp, #16 * 4] 53*67730e6cSSean Christopherson ldp x6, x7, [sp, #16 * 3] 54*67730e6cSSean Christopherson ldp x4, x5, [sp, #16 * 2] 55*67730e6cSSean Christopherson ldp x2, x3, [sp, #16 * 1] 56*67730e6cSSean Christopherson ldp x0, x1, [sp, #16 * 0] 57*67730e6cSSean Christopherson 58*67730e6cSSean Christopherson add sp, sp, #16 * 17 59*67730e6cSSean Christopherson 60*67730e6cSSean Christopherson eret 61*67730e6cSSean Christopherson.endm 62*67730e6cSSean Christopherson 63*67730e6cSSean Christopherson.pushsection ".entry.text", "ax" 64*67730e6cSSean Christopherson.balign 0x800 65*67730e6cSSean Christopherson.global vectors 66*67730e6cSSean Christophersonvectors: 67*67730e6cSSean Christopherson.popsection 68*67730e6cSSean Christopherson 69*67730e6cSSean Christopherson.set vector, 0 70*67730e6cSSean Christopherson 71*67730e6cSSean Christopherson/* 72*67730e6cSSean Christopherson * Build an exception handler for vector and append a jump to it into 73*67730e6cSSean Christopherson * vectors (while making sure that it's 0x80 aligned). 74*67730e6cSSean Christopherson */ 75*67730e6cSSean Christopherson.macro HANDLER, label 76*67730e6cSSean Christophersonhandler_\label: 77*67730e6cSSean Christopherson save_registers 78*67730e6cSSean Christopherson mov x0, sp 79*67730e6cSSean Christopherson mov x1, #vector 80*67730e6cSSean Christopherson bl route_exception 81*67730e6cSSean Christopherson restore_registers 82*67730e6cSSean Christopherson 83*67730e6cSSean Christopherson.pushsection ".entry.text", "ax" 84*67730e6cSSean Christopherson.balign 0x80 85*67730e6cSSean Christopherson b handler_\label 86*67730e6cSSean Christopherson.popsection 87*67730e6cSSean Christopherson 88*67730e6cSSean Christopherson.set vector, vector + 1 89*67730e6cSSean Christopherson.endm 90*67730e6cSSean Christopherson 91*67730e6cSSean Christopherson.macro HANDLER_INVALID 92*67730e6cSSean Christopherson.pushsection ".entry.text", "ax" 93*67730e6cSSean Christopherson.balign 0x80 94*67730e6cSSean Christopherson/* This will abort so no need to save and restore registers. */ 95*67730e6cSSean Christopherson mov x0, #vector 96*67730e6cSSean Christopherson mov x1, #0 /* ec */ 97*67730e6cSSean Christopherson mov x2, #0 /* valid_ec */ 98*67730e6cSSean Christopherson b kvm_exit_unexpected_exception 99*67730e6cSSean Christopherson.popsection 100*67730e6cSSean Christopherson 101*67730e6cSSean Christopherson.set vector, vector + 1 102*67730e6cSSean Christopherson.endm 103*67730e6cSSean Christopherson 104*67730e6cSSean Christopherson/* 105*67730e6cSSean Christopherson * Caution: be sure to not add anything between the declaration of vectors 106*67730e6cSSean Christopherson * above and these macro calls that will build the vectors table below it. 107*67730e6cSSean Christopherson */ 108*67730e6cSSean Christopherson HANDLER_INVALID // Synchronous EL1t 109*67730e6cSSean Christopherson HANDLER_INVALID // IRQ EL1t 110*67730e6cSSean Christopherson HANDLER_INVALID // FIQ EL1t 111*67730e6cSSean Christopherson HANDLER_INVALID // Error EL1t 112*67730e6cSSean Christopherson 113*67730e6cSSean Christopherson HANDLER el1h_sync // Synchronous EL1h 114*67730e6cSSean Christopherson HANDLER el1h_irq // IRQ EL1h 115*67730e6cSSean Christopherson HANDLER el1h_fiq // FIQ EL1h 116*67730e6cSSean Christopherson HANDLER el1h_error // Error EL1h 117*67730e6cSSean Christopherson 118*67730e6cSSean Christopherson HANDLER el0_sync_64 // Synchronous 64-bit EL0 119*67730e6cSSean Christopherson HANDLER el0_irq_64 // IRQ 64-bit EL0 120*67730e6cSSean Christopherson HANDLER el0_fiq_64 // FIQ 64-bit EL0 121*67730e6cSSean Christopherson HANDLER el0_error_64 // Error 64-bit EL0 122*67730e6cSSean Christopherson 123*67730e6cSSean Christopherson HANDLER el0_sync_32 // Synchronous 32-bit EL0 124*67730e6cSSean Christopherson HANDLER el0_irq_32 // IRQ 32-bit EL0 125*67730e6cSSean Christopherson HANDLER el0_fiq_32 // FIQ 32-bit EL0 126*67730e6cSSean Christopherson HANDLER el0_error_32 // Error 32-bit EL0 127