|
@@ -15,6 +15,7 @@
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
*/
|
|
|
|
|
|
+#include <linux/arm-smccc.h>
|
|
|
#include <linux/linkage.h>
|
|
|
|
|
|
#include <asm/alternative.h>
|
|
@@ -64,10 +65,11 @@ alternative_endif
|
|
|
lsr x0, x1, #ESR_ELx_EC_SHIFT
|
|
|
|
|
|
cmp x0, #ESR_ELx_EC_HVC64
|
|
|
+ ccmp x0, #ESR_ELx_EC_HVC32, #4, ne
|
|
|
b.ne el1_trap
|
|
|
|
|
|
- mrs x1, vttbr_el2 // If vttbr is valid, the 64bit guest
|
|
|
- cbnz x1, el1_trap // called HVC
|
|
|
+ mrs x1, vttbr_el2 // If vttbr is valid, the guest
|
|
|
+ cbnz x1, el1_hvc_guest // called HVC
|
|
|
|
|
|
/* Here, we're pretty sure the host called HVC. */
|
|
|
ldp x0, x1, [sp], #16
|
|
@@ -100,6 +102,20 @@ alternative_endif
|
|
|
|
|
|
eret
|
|
|
|
|
|
+el1_hvc_guest:
|
|
|
+ /*
|
|
|
+ * Fastest possible path for ARM_SMCCC_ARCH_WORKAROUND_1.
|
|
|
+ * The workaround has already been applied on the host,
|
|
|
+ * so let's quickly get back to the guest. We don't bother
|
|
|
+ * restoring x1, as it can be clobbered anyway.
|
|
|
+ */
|
|
|
+ ldr x1, [sp] // Guest's x0
|
|
|
+ eor w1, w1, #ARM_SMCCC_ARCH_WORKAROUND_1
|
|
|
+ cbnz w1, el1_trap
|
|
|
+ mov x0, x1
|
|
|
+ add sp, sp, #16
|
|
|
+ eret
|
|
|
+
|
|
|
el1_trap:
|
|
|
/*
|
|
|
* x0: ESR_EC
|