1/*
2 * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <arch.h>
8#include <asm_macros.S>
9#include <context.h>
10#include <services/arm_arch_svc.h>
11
12	.globl	wa_cve_2017_5715_mmu_vbar
13
14#define ESR_EL3_A64_SMC0	0x5e000000
15#define ESR_EL3_A32_SMC0	0x4e000000
16
17vector_base wa_cve_2017_5715_mmu_vbar
18
19	.macro	apply_cve_2017_5715_wa _is_sync_exception _esr_el3_val
20	stp	x0, x1, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X0]
21	mrs	x1, sctlr_el3
22	/* Disable MMU */
23	bic	x1, x1, #SCTLR_M_BIT
24	msr	sctlr_el3, x1
25	isb
26	/* Enable MMU */
27	orr	x1, x1, #SCTLR_M_BIT
28	msr	sctlr_el3, x1
29	/*
30	 * Defer ISB to avoid synchronizing twice in case we hit
31	 * the workaround SMC call which will implicitly synchronize
32	 * because of the ERET instruction.
33	 */
34
35	/*
36	 * Ensure SMC is coming from A64/A32 state on #0
37	 * with W0 = SMCCC_ARCH_WORKAROUND_1 or W0 = SMCCC_ARCH_WORKAROUND_3
38	 *
39	 * This sequence evaluates as:
40	 *    (W0==SMCCC_ARCH_WORKAROUND_1) || (W0==SMCCC_ARCH_WORKAROUND_3) ?
41	 *    (ESR_EL3==SMC#0) : (NE)
42	 * allowing use of a single branch operation
43	 */
44	.if \_is_sync_exception
45		orr	w1, wzr, #SMCCC_ARCH_WORKAROUND_1
46		cmp	w0, w1
47		orr	w1, wzr, #SMCCC_ARCH_WORKAROUND_3
48		ccmp	w0, w1, #4, ne
49		mrs	x0, esr_el3
50		mov_imm	w1, \_esr_el3_val
51		ccmp	w0, w1, #0, eq
52		/* Static predictor will predict a fall through */
53		bne	1f
54		exception_return
551:
56	.endif
57
58	/*
59	 * Synchronize now to enable the MMU.  This is required
60	 * to ensure the load pair below reads the data stored earlier.
61	 */
62	isb
63	ldp	x0, x1, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X0]
64	.endm
65
66	/* ---------------------------------------------------------------------
67	 * Current EL with SP_EL0 : 0x0 - 0x200
68	 * ---------------------------------------------------------------------
69	 */
70vector_entry mmu_sync_exception_sp_el0
71	b	sync_exception_sp_el0
72end_vector_entry mmu_sync_exception_sp_el0
73
74vector_entry mmu_irq_sp_el0
75	b	irq_sp_el0
76end_vector_entry mmu_irq_sp_el0
77
78vector_entry mmu_fiq_sp_el0
79	b	fiq_sp_el0
80end_vector_entry mmu_fiq_sp_el0
81
82vector_entry mmu_serror_sp_el0
83	b	serror_sp_el0
84end_vector_entry mmu_serror_sp_el0
85
86	/* ---------------------------------------------------------------------
87	 * Current EL with SP_ELx: 0x200 - 0x400
88	 * ---------------------------------------------------------------------
89	 */
90vector_entry mmu_sync_exception_sp_elx
91	b	sync_exception_sp_elx
92end_vector_entry mmu_sync_exception_sp_elx
93
94vector_entry mmu_irq_sp_elx
95	b	irq_sp_elx
96end_vector_entry mmu_irq_sp_elx
97
98vector_entry mmu_fiq_sp_elx
99	b	fiq_sp_elx
100end_vector_entry mmu_fiq_sp_elx
101
102vector_entry mmu_serror_sp_elx
103	b	serror_sp_elx
104end_vector_entry mmu_serror_sp_elx
105
106	/* ---------------------------------------------------------------------
107	 * Lower EL using AArch64 : 0x400 - 0x600
108	 * ---------------------------------------------------------------------
109	 */
110vector_entry mmu_sync_exception_aarch64
111	apply_cve_2017_5715_wa _is_sync_exception=1 _esr_el3_val=ESR_EL3_A64_SMC0
112	b	sync_exception_aarch64
113end_vector_entry mmu_sync_exception_aarch64
114
115vector_entry mmu_irq_aarch64
116	apply_cve_2017_5715_wa _is_sync_exception=0 _esr_el3_val=ESR_EL3_A64_SMC0
117	b	irq_aarch64
118end_vector_entry mmu_irq_aarch64
119
120vector_entry mmu_fiq_aarch64
121	apply_cve_2017_5715_wa _is_sync_exception=0 _esr_el3_val=ESR_EL3_A64_SMC0
122	b	fiq_aarch64
123end_vector_entry mmu_fiq_aarch64
124
125vector_entry mmu_serror_aarch64
126	apply_cve_2017_5715_wa _is_sync_exception=0 _esr_el3_val=ESR_EL3_A64_SMC0
127	b	serror_aarch64
128end_vector_entry mmu_serror_aarch64
129
130	/* ---------------------------------------------------------------------
131	 * Lower EL using AArch32 : 0x600 - 0x800
132	 * ---------------------------------------------------------------------
133	 */
134vector_entry mmu_sync_exception_aarch32
135	apply_cve_2017_5715_wa _is_sync_exception=1 _esr_el3_val=ESR_EL3_A32_SMC0
136	b	sync_exception_aarch32
137end_vector_entry mmu_sync_exception_aarch32
138
139vector_entry mmu_irq_aarch32
140	apply_cve_2017_5715_wa _is_sync_exception=0 _esr_el3_val=ESR_EL3_A32_SMC0
141	b	irq_aarch32
142end_vector_entry mmu_irq_aarch32
143
144vector_entry mmu_fiq_aarch32
145	apply_cve_2017_5715_wa _is_sync_exception=0 _esr_el3_val=ESR_EL3_A32_SMC0
146	b	fiq_aarch32
147end_vector_entry mmu_fiq_aarch32
148
149vector_entry mmu_serror_aarch32
150	apply_cve_2017_5715_wa _is_sync_exception=0 _esr_el3_val=ESR_EL3_A32_SMC0
151	b	serror_aarch32
152end_vector_entry mmu_serror_aarch32
153