@@ -2097,6 +2097,11 @@ void do_trap_guest_sync(struct cpu_user_regs *regs)
perfc_incr(trap_cp14_dbg);
do_cp14_dbg(regs, hsr);
break;
+ case HSR_EC_CP10:
+ GUEST_BUG_ON(!psr_mode_is_32bit(regs));
+ perfc_incr(trap_cp10);
+ do_cp10(regs, hsr);
+ break;
case HSR_EC_CP:
GUEST_BUG_ON(!psr_mode_is_32bit(regs));
perfc_incr(trap_cp);
@@ -634,6 +634,44 @@ void do_cp14_dbg(struct cpu_user_regs *regs, const union hsr hsr)
inject_undef_exception(regs, hsr);
}
+void do_cp10(struct cpu_user_regs *regs, const union hsr hsr)
+{
+ const struct hsr_cp32 cp32 = hsr.cp32;
+ int regidx = cp32.reg;
+
+ if ( !check_conditional_instr(regs, hsr) )
+ {
+ advance_pc(regs, hsr);
+ return;
+ }
+
+ switch ( hsr.bits & HSR_CP32_REGS_MASK )
+ {
+ /*
+ * HSR.TID3 is trapping access to MVFR register used to identify the
+ * VFP/Simd using VMRS/VMSR instructions.
+ * In this case MVFR2 is not supported as the instruction does not support
+ * it.
+ * Exception encoding is using MRC/MCR standard with the reg field in Crn
+ * as are declared MVFR0 and MVFR1 in cpregs.h
+ */
+ GENERATE_TID3_INFO(MVFR0, mvfr, 0)
+ GENERATE_TID3_INFO(MVFR1, mvfr, 1)
+
+ default:
+ gdprintk(XENLOG_ERR,
+ "%s p10, %d, r%d, cr%d, cr%d, %d @ 0x%"PRIregister"\n",
+ cp32.read ? "mrc" : "mcr",
+ cp32.op1, cp32.reg, cp32.crn, cp32.crm, cp32.op2, regs->pc);
+ gdprintk(XENLOG_ERR, "unhandled 32-bit CP10 access %#x\n",
+ hsr.bits & HSR_CP32_REGS_MASK);
+ inject_undef_exception(regs, hsr);
+ return;
+ }
+
+ advance_pc(regs, hsr);
+}
+
void do_cp(struct cpu_user_regs *regs, const union hsr hsr)
{
const struct hsr_cp cp = hsr.cp;
@@ -11,6 +11,7 @@ PERFCOUNTER(trap_cp15_64, "trap: cp15 64-bit access")
PERFCOUNTER(trap_cp14_32, "trap: cp14 32-bit access")
PERFCOUNTER(trap_cp14_64, "trap: cp14 64-bit access")
PERFCOUNTER(trap_cp14_dbg, "trap: cp14 dbg access")
+PERFCOUNTER(trap_cp10, "trap: cp10 access")
PERFCOUNTER(trap_cp, "trap: cp access")
PERFCOUNTER(trap_smc32, "trap: 32-bit smc")
PERFCOUNTER(trap_hvc32, "trap: 32-bit hvc")
@@ -62,6 +62,7 @@ void do_cp15_64(struct cpu_user_regs *regs, const union hsr hsr);
void do_cp14_32(struct cpu_user_regs *regs, const union hsr hsr);
void do_cp14_64(struct cpu_user_regs *regs, const union hsr hsr);
void do_cp14_dbg(struct cpu_user_regs *regs, const union hsr hsr);
+void do_cp10(struct cpu_user_regs *regs, const union hsr hsr);
void do_cp(struct cpu_user_regs *regs, const union hsr hsr);
/* SMCCC handling */
Add support for cp10 exceptions decoding to be able to emulate the values for VMFR0 and VMFR1 when TID3 bit of HSR is activated. This is required for aarch32 guests accessing VMFR0 and VMFR1 using vmrs and vmsr instructions. Signed-off-by: Bertrand Marquis <bertrand.marquis@arm.com> --- xen/arch/arm/traps.c | 5 +++++ xen/arch/arm/vcpreg.c | 38 ++++++++++++++++++++++++++++++++ xen/include/asm-arm/perfc_defn.h | 1 + xen/include/asm-arm/traps.h | 1 + 4 files changed, 45 insertions(+)