@@ -36,6 +36,7 @@
#include <asm/cpregs.h>
#include <asm/psci.h>
+#include "decode.h"
#include "io.h"
#include "vtimer.h"
#include <asm/gic.h>
@@ -1229,6 +1230,17 @@ static void do_trap_data_abort_guest(struct cpu_user_regs *regs,
if ( !dabt.valid )
goto bad_data_abort;
+ /*
+ * Errata 766422: Thumb store translation fault to Hypervisor may
+ * not have correct HSR Rt value.
+ */
+ if ( cpu_has_errata_766422() && (regs->cpsr & PSR_THUMB) && dabt.write )
+ {
+ rc = decode_instruction(regs, &info.dabt);
+ if ( rc )
+ goto bad_data_abort;
+ }
+
if (handle_mmio(&info))
{
regs->pc += dabt.len ? 4 : 2;
@@ -111,6 +111,10 @@ struct cpu_user_regs
#define READ_SYSREG(R...) READ_SYSREG32(R)
#define WRITE_SYSREG(V, R...) WRITE_SYSREG32(V, R)
+/* Errata 766422: only Cortex A15 r0p4 is affected */
+#define cpu_has_errata_766422() \
+ (unlikely(current_cpu_data.midr.bits == 0x410fc0f4))
+
#endif /* __ASSEMBLY__ */
#endif /* __ASM_ARM_ARM32_PROCESSOR_H */
@@ -104,6 +104,8 @@ struct cpu_user_regs
#define READ_SYSREG(name) READ_SYSREG64(name)
#define WRITE_SYSREG(v, name) WRITE_SYSREG64(v, name)
+#define cpu_has_errata_766422() 0
+
#endif /* __ASSEMBLY__ */
#endif /* __ASM_ARM_ARM64_PROCESSOR_H */
From the errata document: When a non-secure non-hypervisor memory operation instruction generates a stage2 page table translation fault, a trap to the hypervisor will be triggered. For an architecturally defined subset of instructions, the Hypervisor Syndrome Register (HSR) will have the Instruction Syndrome Valid (ISV) bit set to 1’b1, and the Rt field should reflect the source register (for stores) or destination register for loads. On Cortex-A15, for Thumb and ThumbEE stores, the Rt value may be incorrect and should not be used, even if the ISV bit is set. All loads, and all ARM instruction set loads and stores, will have the correct Rt value if the ISV bit is set. To avoid this issue, Xen needs to decode thumb store instruction and update the transfer register. Signed-off-by: Julien Grall <julien.grall@linaro.org> --- Changes in v3: - Use unlikely to check if the processor is affected by the errata - Move the decoder in another patch and use it Changes in v2: - Only decode the instruction on affected processor - Handle ARM 32-bit instruction in read_instruction --- xen/arch/arm/traps.c | 12 ++++++++++++ xen/include/asm-arm/arm32/processor.h | 4 ++++ xen/include/asm-arm/arm64/processor.h | 2 ++ 3 files changed, 18 insertions(+)