12c3a1078SDimitris Papastamos/* 2*4c700c15SGovindraj Raja * Copyright (c) 2017-2022, Arm Limited and Contributors. All rights reserved. 32c3a1078SDimitris Papastamos * 42c3a1078SDimitris Papastamos * SPDX-License-Identifier: BSD-3-Clause 52c3a1078SDimitris Papastamos */ 62c3a1078SDimitris Papastamos 72c3a1078SDimitris Papastamos#include <arch.h> 82c3a1078SDimitris Papastamos#include <asm_macros.S> 92c3a1078SDimitris Papastamos#include <context.h> 1009d40e0eSAntonio Nino Diaz#include <services/arm_arch_svc.h> 112c3a1078SDimitris Papastamos 122c3a1078SDimitris Papastamos .globl wa_cve_2017_5715_bpiall_vbar 132c3a1078SDimitris Papastamos 142c3a1078SDimitris Papastamos#define EMIT_BPIALL 0xee070fd5 152c3a1078SDimitris Papastamos#define EMIT_SMC 0xe1600070 162c3a1078SDimitris Papastamos#define ESR_EL3_A64_SMC0 0x5e000000 172c3a1078SDimitris Papastamos 182c3a1078SDimitris Papastamos .macro apply_cve_2017_5715_wa _from_vector 192c3a1078SDimitris Papastamos /* 202c3a1078SDimitris Papastamos * Save register state to enable a call to AArch32 S-EL1 and return 212c3a1078SDimitris Papastamos * Identify the original calling vector in w2 (==_from_vector) 222c3a1078SDimitris Papastamos * Use w3-w6 for additional register state preservation while in S-EL1 232c3a1078SDimitris Papastamos */ 242c3a1078SDimitris Papastamos 252c3a1078SDimitris Papastamos /* Save GP regs */ 262c3a1078SDimitris Papastamos stp x0, x1, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X0] 272c3a1078SDimitris Papastamos stp x2, x3, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X2] 282c3a1078SDimitris Papastamos stp x4, x5, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X4] 292c3a1078SDimitris Papastamos stp x6, x7, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X6] 302c3a1078SDimitris Papastamos stp x8, x9, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X8] 312c3a1078SDimitris Papastamos stp x10, x11, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X10] 322c3a1078SDimitris Papastamos stp x12, x13, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X12] 332c3a1078SDimitris Papastamos stp x14, x15, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X14] 342c3a1078SDimitris Papastamos stp x16, x17, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X16] 352c3a1078SDimitris Papastamos stp x18, x19, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X18] 362c3a1078SDimitris Papastamos stp x20, x21, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X20] 372c3a1078SDimitris Papastamos stp x22, x23, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X22] 382c3a1078SDimitris Papastamos stp x24, x25, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X24] 392c3a1078SDimitris Papastamos stp x26, x27, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X26] 402c3a1078SDimitris Papastamos stp x28, x29, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X28] 412c3a1078SDimitris Papastamos 422c3a1078SDimitris Papastamos /* Identify the original exception vector */ 432c3a1078SDimitris Papastamos mov w2, \_from_vector 442c3a1078SDimitris Papastamos 452c3a1078SDimitris Papastamos /* Preserve 32-bit system registers in GP registers through the workaround */ 462c3a1078SDimitris Papastamos mrs x3, esr_el3 472c3a1078SDimitris Papastamos mrs x4, spsr_el3 482c3a1078SDimitris Papastamos mrs x5, scr_el3 492c3a1078SDimitris Papastamos mrs x6, sctlr_el1 502c3a1078SDimitris Papastamos 512c3a1078SDimitris Papastamos /* 522c3a1078SDimitris Papastamos * Preserve LR and ELR_EL3 registers in the GP regs context. 532c3a1078SDimitris Papastamos * Temporarily use the CTX_GPREG_SP_EL0 slot to preserve ELR_EL3 542c3a1078SDimitris Papastamos * through the workaround. This is OK because at this point the 552c3a1078SDimitris Papastamos * current state for this context's SP_EL0 is in the live system 562c3a1078SDimitris Papastamos * register, which is unmodified by the workaround. 572c3a1078SDimitris Papastamos */ 582c3a1078SDimitris Papastamos mrs x7, elr_el3 592c3a1078SDimitris Papastamos stp x30, x7, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR] 602c3a1078SDimitris Papastamos 612c3a1078SDimitris Papastamos /* 622c3a1078SDimitris Papastamos * Load system registers for entry to S-EL1. 632c3a1078SDimitris Papastamos */ 642c3a1078SDimitris Papastamos 652c3a1078SDimitris Papastamos /* Mask all interrupts and set AArch32 Supervisor mode */ 662c3a1078SDimitris Papastamos movz w8, SPSR_MODE32(MODE32_svc, SPSR_T_ARM, SPSR_E_LITTLE, SPSR_AIF_MASK) 672c3a1078SDimitris Papastamos 682c3a1078SDimitris Papastamos /* Switch EL3 exception vectors while the workaround is executing. */ 692c3a1078SDimitris Papastamos adr x9, wa_cve_2017_5715_bpiall_ret_vbar 702c3a1078SDimitris Papastamos 712c3a1078SDimitris Papastamos /* Setup SCTLR_EL1 with MMU off and I$ on */ 722c3a1078SDimitris Papastamos ldr x10, stub_sel1_sctlr 732c3a1078SDimitris Papastamos 742c3a1078SDimitris Papastamos /* Land at the S-EL1 workaround stub */ 752c3a1078SDimitris Papastamos adr x11, aarch32_stub 762c3a1078SDimitris Papastamos 772c3a1078SDimitris Papastamos /* 782c3a1078SDimitris Papastamos * Setting SCR_EL3 to all zeroes means that the NS, RW 792c3a1078SDimitris Papastamos * and SMD bits are configured as expected. 802c3a1078SDimitris Papastamos */ 812c3a1078SDimitris Papastamos msr scr_el3, xzr 822c3a1078SDimitris Papastamos msr spsr_el3, x8 832c3a1078SDimitris Papastamos msr vbar_el3, x9 842c3a1078SDimitris Papastamos msr sctlr_el1, x10 852c3a1078SDimitris Papastamos msr elr_el3, x11 862c3a1078SDimitris Papastamos 872c3a1078SDimitris Papastamos eret 882c3a1078SDimitris Papastamos .endm 892c3a1078SDimitris Papastamos 902c3a1078SDimitris Papastamos /* --------------------------------------------------------------------- 912c3a1078SDimitris Papastamos * This vector table is used at runtime to enter the workaround at 922c3a1078SDimitris Papastamos * AArch32 S-EL1 for Sync/IRQ/FIQ/SError exceptions. If the workaround 932c3a1078SDimitris Papastamos * is not enabled, the existing runtime exception vector table is used. 942c3a1078SDimitris Papastamos * --------------------------------------------------------------------- 952c3a1078SDimitris Papastamos */ 962c3a1078SDimitris Papastamosvector_base wa_cve_2017_5715_bpiall_vbar 972c3a1078SDimitris Papastamos 982c3a1078SDimitris Papastamos /* --------------------------------------------------------------------- 992c3a1078SDimitris Papastamos * Current EL with SP_EL0 : 0x0 - 0x200 1002c3a1078SDimitris Papastamos * --------------------------------------------------------------------- 1012c3a1078SDimitris Papastamos */ 1022c3a1078SDimitris Papastamosvector_entry bpiall_sync_exception_sp_el0 1032c3a1078SDimitris Papastamos b sync_exception_sp_el0 1042c3a1078SDimitris Papastamos nop /* to force 8 byte alignment for the following stub */ 1052c3a1078SDimitris Papastamos 1062c3a1078SDimitris Papastamos /* 1072c3a1078SDimitris Papastamos * Since each vector table entry is 128 bytes, we can store the 1082c3a1078SDimitris Papastamos * stub context in the unused space to minimize memory footprint. 1092c3a1078SDimitris Papastamos */ 1102c3a1078SDimitris Papastamosstub_sel1_sctlr: 1112c3a1078SDimitris Papastamos .quad SCTLR_AARCH32_EL1_RES1 | SCTLR_I_BIT 1122c3a1078SDimitris Papastamos 1132c3a1078SDimitris Papastamosaarch32_stub: 1142c3a1078SDimitris Papastamos .word EMIT_BPIALL 1152c3a1078SDimitris Papastamos .word EMIT_SMC 1162c3a1078SDimitris Papastamos 117a9203edaSRoberto Vargasend_vector_entry bpiall_sync_exception_sp_el0 1182c3a1078SDimitris Papastamos 1192c3a1078SDimitris Papastamosvector_entry bpiall_irq_sp_el0 1202c3a1078SDimitris Papastamos b irq_sp_el0 121a9203edaSRoberto Vargasend_vector_entry bpiall_irq_sp_el0 1222c3a1078SDimitris Papastamos 1232c3a1078SDimitris Papastamosvector_entry bpiall_fiq_sp_el0 1242c3a1078SDimitris Papastamos b fiq_sp_el0 125a9203edaSRoberto Vargasend_vector_entry bpiall_fiq_sp_el0 1262c3a1078SDimitris Papastamos 1272c3a1078SDimitris Papastamosvector_entry bpiall_serror_sp_el0 1282c3a1078SDimitris Papastamos b serror_sp_el0 129a9203edaSRoberto Vargasend_vector_entry bpiall_serror_sp_el0 1302c3a1078SDimitris Papastamos 1312c3a1078SDimitris Papastamos /* --------------------------------------------------------------------- 1322c3a1078SDimitris Papastamos * Current EL with SP_ELx: 0x200 - 0x400 1332c3a1078SDimitris Papastamos * --------------------------------------------------------------------- 1342c3a1078SDimitris Papastamos */ 1352c3a1078SDimitris Papastamosvector_entry bpiall_sync_exception_sp_elx 1362c3a1078SDimitris Papastamos b sync_exception_sp_elx 137a9203edaSRoberto Vargasend_vector_entry bpiall_sync_exception_sp_elx 1382c3a1078SDimitris Papastamos 1392c3a1078SDimitris Papastamosvector_entry bpiall_irq_sp_elx 1402c3a1078SDimitris Papastamos b irq_sp_elx 141a9203edaSRoberto Vargasend_vector_entry bpiall_irq_sp_elx 1422c3a1078SDimitris Papastamos 1432c3a1078SDimitris Papastamosvector_entry bpiall_fiq_sp_elx 1442c3a1078SDimitris Papastamos b fiq_sp_elx 145a9203edaSRoberto Vargasend_vector_entry bpiall_fiq_sp_elx 1462c3a1078SDimitris Papastamos 1472c3a1078SDimitris Papastamosvector_entry bpiall_serror_sp_elx 1482c3a1078SDimitris Papastamos b serror_sp_elx 149a9203edaSRoberto Vargasend_vector_entry bpiall_serror_sp_elx 1502c3a1078SDimitris Papastamos 1512c3a1078SDimitris Papastamos /* --------------------------------------------------------------------- 1522c3a1078SDimitris Papastamos * Lower EL using AArch64 : 0x400 - 0x600 1532c3a1078SDimitris Papastamos * --------------------------------------------------------------------- 1542c3a1078SDimitris Papastamos */ 1552c3a1078SDimitris Papastamosvector_entry bpiall_sync_exception_aarch64 1562c3a1078SDimitris Papastamos apply_cve_2017_5715_wa 1 157a9203edaSRoberto Vargasend_vector_entry bpiall_sync_exception_aarch64 1582c3a1078SDimitris Papastamos 1592c3a1078SDimitris Papastamosvector_entry bpiall_irq_aarch64 1602c3a1078SDimitris Papastamos apply_cve_2017_5715_wa 2 161a9203edaSRoberto Vargasend_vector_entry bpiall_irq_aarch64 1622c3a1078SDimitris Papastamos 1632c3a1078SDimitris Papastamosvector_entry bpiall_fiq_aarch64 1642c3a1078SDimitris Papastamos apply_cve_2017_5715_wa 4 165a9203edaSRoberto Vargasend_vector_entry bpiall_fiq_aarch64 1662c3a1078SDimitris Papastamos 1672c3a1078SDimitris Papastamosvector_entry bpiall_serror_aarch64 1682c3a1078SDimitris Papastamos apply_cve_2017_5715_wa 8 169a9203edaSRoberto Vargasend_vector_entry bpiall_serror_aarch64 1702c3a1078SDimitris Papastamos 1712c3a1078SDimitris Papastamos /* --------------------------------------------------------------------- 1722c3a1078SDimitris Papastamos * Lower EL using AArch32 : 0x600 - 0x800 1732c3a1078SDimitris Papastamos * --------------------------------------------------------------------- 1742c3a1078SDimitris Papastamos */ 1752c3a1078SDimitris Papastamosvector_entry bpiall_sync_exception_aarch32 1762c3a1078SDimitris Papastamos apply_cve_2017_5715_wa 1 177a9203edaSRoberto Vargasend_vector_entry bpiall_sync_exception_aarch32 1782c3a1078SDimitris Papastamos 1792c3a1078SDimitris Papastamosvector_entry bpiall_irq_aarch32 1802c3a1078SDimitris Papastamos apply_cve_2017_5715_wa 2 181a9203edaSRoberto Vargasend_vector_entry bpiall_irq_aarch32 1822c3a1078SDimitris Papastamos 1832c3a1078SDimitris Papastamosvector_entry bpiall_fiq_aarch32 1842c3a1078SDimitris Papastamos apply_cve_2017_5715_wa 4 185a9203edaSRoberto Vargasend_vector_entry bpiall_fiq_aarch32 1862c3a1078SDimitris Papastamos 1872c3a1078SDimitris Papastamosvector_entry bpiall_serror_aarch32 1882c3a1078SDimitris Papastamos apply_cve_2017_5715_wa 8 189a9203edaSRoberto Vargasend_vector_entry bpiall_serror_aarch32 1902c3a1078SDimitris Papastamos 1912c3a1078SDimitris Papastamos /* --------------------------------------------------------------------- 1922c3a1078SDimitris Papastamos * This vector table is used while the workaround is executing. It 1932c3a1078SDimitris Papastamos * installs a simple SMC handler to allow the Sync/IRQ/FIQ/SError 1942c3a1078SDimitris Papastamos * workaround stubs to enter EL3 from S-EL1. It restores the previous 1952c3a1078SDimitris Papastamos * EL3 state before proceeding with the normal runtime exception vector. 1962c3a1078SDimitris Papastamos * --------------------------------------------------------------------- 1972c3a1078SDimitris Papastamos */ 1982c3a1078SDimitris Papastamosvector_base wa_cve_2017_5715_bpiall_ret_vbar 1992c3a1078SDimitris Papastamos 2002c3a1078SDimitris Papastamos /* --------------------------------------------------------------------- 2012c3a1078SDimitris Papastamos * Current EL with SP_EL0 : 0x0 - 0x200 (UNUSED) 2022c3a1078SDimitris Papastamos * --------------------------------------------------------------------- 2032c3a1078SDimitris Papastamos */ 2042c3a1078SDimitris Papastamosvector_entry bpiall_ret_sync_exception_sp_el0 2052c3a1078SDimitris Papastamos b report_unhandled_exception 206a9203edaSRoberto Vargasend_vector_entry bpiall_ret_sync_exception_sp_el0 2072c3a1078SDimitris Papastamos 2082c3a1078SDimitris Papastamosvector_entry bpiall_ret_irq_sp_el0 2092c3a1078SDimitris Papastamos b report_unhandled_interrupt 210a9203edaSRoberto Vargasend_vector_entry bpiall_ret_irq_sp_el0 2112c3a1078SDimitris Papastamos 2122c3a1078SDimitris Papastamosvector_entry bpiall_ret_fiq_sp_el0 2132c3a1078SDimitris Papastamos b report_unhandled_interrupt 214a9203edaSRoberto Vargasend_vector_entry bpiall_ret_fiq_sp_el0 2152c3a1078SDimitris Papastamos 2162c3a1078SDimitris Papastamosvector_entry bpiall_ret_serror_sp_el0 2172c3a1078SDimitris Papastamos b report_unhandled_exception 218a9203edaSRoberto Vargasend_vector_entry bpiall_ret_serror_sp_el0 2192c3a1078SDimitris Papastamos 2202c3a1078SDimitris Papastamos /* --------------------------------------------------------------------- 2212c3a1078SDimitris Papastamos * Current EL with SP_ELx: 0x200 - 0x400 (UNUSED) 2222c3a1078SDimitris Papastamos * --------------------------------------------------------------------- 2232c3a1078SDimitris Papastamos */ 2242c3a1078SDimitris Papastamosvector_entry bpiall_ret_sync_exception_sp_elx 2252c3a1078SDimitris Papastamos b report_unhandled_exception 226a9203edaSRoberto Vargasend_vector_entry bpiall_ret_sync_exception_sp_elx 2272c3a1078SDimitris Papastamos 2282c3a1078SDimitris Papastamosvector_entry bpiall_ret_irq_sp_elx 2292c3a1078SDimitris Papastamos b report_unhandled_interrupt 230a9203edaSRoberto Vargasend_vector_entry bpiall_ret_irq_sp_elx 2312c3a1078SDimitris Papastamos 2322c3a1078SDimitris Papastamosvector_entry bpiall_ret_fiq_sp_elx 2332c3a1078SDimitris Papastamos b report_unhandled_interrupt 234a9203edaSRoberto Vargasend_vector_entry bpiall_ret_fiq_sp_elx 2352c3a1078SDimitris Papastamos 2362c3a1078SDimitris Papastamosvector_entry bpiall_ret_serror_sp_elx 2372c3a1078SDimitris Papastamos b report_unhandled_exception 238a9203edaSRoberto Vargasend_vector_entry bpiall_ret_serror_sp_elx 2392c3a1078SDimitris Papastamos 2402c3a1078SDimitris Papastamos /* --------------------------------------------------------------------- 2412c3a1078SDimitris Papastamos * Lower EL using AArch64 : 0x400 - 0x600 (UNUSED) 2422c3a1078SDimitris Papastamos * --------------------------------------------------------------------- 2432c3a1078SDimitris Papastamos */ 2442c3a1078SDimitris Papastamosvector_entry bpiall_ret_sync_exception_aarch64 2452c3a1078SDimitris Papastamos b report_unhandled_exception 246a9203edaSRoberto Vargasend_vector_entry bpiall_ret_sync_exception_aarch64 2472c3a1078SDimitris Papastamos 2482c3a1078SDimitris Papastamosvector_entry bpiall_ret_irq_aarch64 2492c3a1078SDimitris Papastamos b report_unhandled_interrupt 250a9203edaSRoberto Vargasend_vector_entry bpiall_ret_irq_aarch64 2512c3a1078SDimitris Papastamos 2522c3a1078SDimitris Papastamosvector_entry bpiall_ret_fiq_aarch64 2532c3a1078SDimitris Papastamos b report_unhandled_interrupt 254a9203edaSRoberto Vargasend_vector_entry bpiall_ret_fiq_aarch64 2552c3a1078SDimitris Papastamos 2562c3a1078SDimitris Papastamosvector_entry bpiall_ret_serror_aarch64 2572c3a1078SDimitris Papastamos b report_unhandled_exception 258a9203edaSRoberto Vargasend_vector_entry bpiall_ret_serror_aarch64 2592c3a1078SDimitris Papastamos 2602c3a1078SDimitris Papastamos /* --------------------------------------------------------------------- 2612c3a1078SDimitris Papastamos * Lower EL using AArch32 : 0x600 - 0x800 2622c3a1078SDimitris Papastamos * --------------------------------------------------------------------- 2632c3a1078SDimitris Papastamos */ 2642c3a1078SDimitris Papastamosvector_entry bpiall_ret_sync_exception_aarch32 2652c3a1078SDimitris Papastamos /* 2662c3a1078SDimitris Papastamos * w2 indicates which SEL1 stub was run and thus which original vector was used 2672c3a1078SDimitris Papastamos * w3-w6 contain saved system register state (esr_el3 in w3) 2682c3a1078SDimitris Papastamos * Restore LR and ELR_EL3 register state from the GP regs context 2692c3a1078SDimitris Papastamos */ 2702c3a1078SDimitris Papastamos ldp x30, x7, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR] 2712c3a1078SDimitris Papastamos 2722c3a1078SDimitris Papastamos /* Apply the restored system register state */ 2732c3a1078SDimitris Papastamos msr esr_el3, x3 2742c3a1078SDimitris Papastamos msr spsr_el3, x4 2752c3a1078SDimitris Papastamos msr scr_el3, x5 2762c3a1078SDimitris Papastamos msr sctlr_el1, x6 2772c3a1078SDimitris Papastamos msr elr_el3, x7 2782c3a1078SDimitris Papastamos 2792c3a1078SDimitris Papastamos /* 2802c3a1078SDimitris Papastamos * Workaround is complete, so swap VBAR_EL3 to point 2812c3a1078SDimitris Papastamos * to workaround entry table in preparation for subsequent 2822c3a1078SDimitris Papastamos * Sync/IRQ/FIQ/SError exceptions. 2832c3a1078SDimitris Papastamos */ 2842c3a1078SDimitris Papastamos adr x0, wa_cve_2017_5715_bpiall_vbar 2852c3a1078SDimitris Papastamos msr vbar_el3, x0 2862c3a1078SDimitris Papastamos 2872c3a1078SDimitris Papastamos /* 2882c3a1078SDimitris Papastamos * Restore all GP regs except x2 and x3 (esr). The value in x2 2892c3a1078SDimitris Papastamos * indicates the type of the original exception. 2902c3a1078SDimitris Papastamos */ 2912c3a1078SDimitris Papastamos ldp x0, x1, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X0] 2922c3a1078SDimitris Papastamos ldp x4, x5, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X4] 2932c3a1078SDimitris Papastamos ldp x6, x7, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X6] 2942c3a1078SDimitris Papastamos ldp x8, x9, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X8] 2952c3a1078SDimitris Papastamos ldp x10, x11, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X10] 2962c3a1078SDimitris Papastamos ldp x12, x13, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X12] 2972c3a1078SDimitris Papastamos ldp x14, x15, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X14] 2982c3a1078SDimitris Papastamos ldp x16, x17, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X16] 2992c3a1078SDimitris Papastamos ldp x18, x19, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X18] 3002c3a1078SDimitris Papastamos ldp x20, x21, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X20] 3012c3a1078SDimitris Papastamos ldp x22, x23, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X22] 3022c3a1078SDimitris Papastamos ldp x24, x25, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X24] 3032c3a1078SDimitris Papastamos ldp x26, x27, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X26] 3042c3a1078SDimitris Papastamos ldp x28, x29, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X28] 3052c3a1078SDimitris Papastamos 3062c3a1078SDimitris Papastamos /* Fast path Sync exceptions. Static predictor will fall through. */ 3072c3a1078SDimitris Papastamos tbz w2, #0, workaround_not_sync 3082c3a1078SDimitris Papastamos 3092c3a1078SDimitris Papastamos /* 3102c3a1078SDimitris Papastamos * Check if SMC is coming from A64 state on #0 3119b2510b6SBipin Ravi * with W0 = SMCCC_ARCH_WORKAROUND_1 or W0 = SMCCC_ARCH_WORKAROUND_3 3122c3a1078SDimitris Papastamos * 3132c3a1078SDimitris Papastamos * This sequence evaluates as: 3149b2510b6SBipin Ravi * (W0==SMCCC_ARCH_WORKAROUND_1) || (W0==SMCCC_ARCH_WORKAROUND_3) ? 3159b2510b6SBipin Ravi * (ESR_EL3==SMC#0) : (NE) 3162c3a1078SDimitris Papastamos * allowing use of a single branch operation 3172c3a1078SDimitris Papastamos */ 3182c3a1078SDimitris Papastamos orr w2, wzr, #SMCCC_ARCH_WORKAROUND_1 3192c3a1078SDimitris Papastamos cmp w0, w2 3209b2510b6SBipin Ravi orr w2, wzr, #SMCCC_ARCH_WORKAROUND_3 3219b2510b6SBipin Ravi ccmp w0, w2, #4, ne 3222c3a1078SDimitris Papastamos mov_imm w2, ESR_EL3_A64_SMC0 3232c3a1078SDimitris Papastamos ccmp w3, w2, #0, eq 3242c3a1078SDimitris Papastamos /* Static predictor will predict a fall through */ 3252c3a1078SDimitris Papastamos bne 1f 3262c3a1078SDimitris Papastamos eret 3272c3a1078SDimitris Papastamos1: 3289b2510b6SBipin Ravi /* restore x2 and x3 and continue sync exception handling */ 3299b2510b6SBipin Ravi b bpiall_ret_sync_exception_aarch32_tail 330a9203edaSRoberto Vargasend_vector_entry bpiall_ret_sync_exception_aarch32 3312c3a1078SDimitris Papastamos 3322c3a1078SDimitris Papastamosvector_entry bpiall_ret_irq_aarch32 3332c3a1078SDimitris Papastamos b report_unhandled_interrupt 3342c3a1078SDimitris Papastamos 3352c3a1078SDimitris Papastamos /* 3362c3a1078SDimitris Papastamos * Post-workaround fan-out for non-sync exceptions 3372c3a1078SDimitris Papastamos */ 3382c3a1078SDimitris Papastamosworkaround_not_sync: 3392c3a1078SDimitris Papastamos tbnz w2, #3, bpiall_ret_serror 3402c3a1078SDimitris Papastamos tbnz w2, #2, bpiall_ret_fiq 3412c3a1078SDimitris Papastamos /* IRQ */ 3422c3a1078SDimitris Papastamos ldp x2, x3, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X2] 3432c3a1078SDimitris Papastamos b irq_aarch64 3442c3a1078SDimitris Papastamos 3452c3a1078SDimitris Papastamosbpiall_ret_fiq: 3462c3a1078SDimitris Papastamos ldp x2, x3, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X2] 3472c3a1078SDimitris Papastamos b fiq_aarch64 3482c3a1078SDimitris Papastamos 3492c3a1078SDimitris Papastamosbpiall_ret_serror: 3502c3a1078SDimitris Papastamos ldp x2, x3, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X2] 3512c3a1078SDimitris Papastamos b serror_aarch64 352a9203edaSRoberto Vargasend_vector_entry bpiall_ret_irq_aarch32 3532c3a1078SDimitris Papastamos 3542c3a1078SDimitris Papastamosvector_entry bpiall_ret_fiq_aarch32 3552c3a1078SDimitris Papastamos b report_unhandled_interrupt 356a9203edaSRoberto Vargasend_vector_entry bpiall_ret_fiq_aarch32 3572c3a1078SDimitris Papastamos 3582c3a1078SDimitris Papastamosvector_entry bpiall_ret_serror_aarch32 3592c3a1078SDimitris Papastamos b report_unhandled_exception 360a9203edaSRoberto Vargasend_vector_entry bpiall_ret_serror_aarch32 3619b2510b6SBipin Ravi 3629b2510b6SBipin Ravi /* 3639b2510b6SBipin Ravi * Part of bpiall_ret_sync_exception_aarch32 to save vector space 3649b2510b6SBipin Ravi */ 3659b2510b6SBipin Ravifunc bpiall_ret_sync_exception_aarch32_tail 3669b2510b6SBipin Ravi ldp x2, x3, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X2] 3679b2510b6SBipin Ravi b sync_exception_aarch64 3689b2510b6SBipin Raviendfunc bpiall_ret_sync_exception_aarch32_tail 369