[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v3 6/7] xen/arm: Add CP10 exception support to handle MVFR
On Wed, 9 Dec 2020, Bertrand Marquis wrote: > Add support for cp10 exceptions decoding to be able to emulate the > values for MVFR0, MVFR1 and MVFR2 when TID3 bit of HSR is activated. > This is required for aarch32 guests accessing MVFR registers using > vmrs and vmsr instructions. > > Signed-off-by: Bertrand Marquis <bertrand.marquis@xxxxxxx> > --- > Changes in V2: Rebase > Changes in V3: > Add case for MVFR2, fix typo VMFR <-> MVFR. > > --- > xen/arch/arm/traps.c | 5 ++++ > xen/arch/arm/vcpreg.c | 39 +++++++++++++++++++++++++++++++- > xen/include/asm-arm/perfc_defn.h | 1 + > xen/include/asm-arm/traps.h | 1 + > 4 files changed, 45 insertions(+), 1 deletion(-) > > diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c > index 22bd1bd4c6..28d9d64558 100644 > --- a/xen/arch/arm/traps.c > +++ b/xen/arch/arm/traps.c > @@ -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); > diff --git a/xen/arch/arm/vcpreg.c b/xen/arch/arm/vcpreg.c > index d371a1c38c..da4e22a467 100644 > --- a/xen/arch/arm/vcpreg.c > +++ b/xen/arch/arm/vcpreg.c > @@ -319,7 +319,7 @@ void do_cp15_32(struct cpu_user_regs *regs, const union > hsr hsr) > GENERATE_TID3_INFO(ID_ISAR4, isa32, 4) > GENERATE_TID3_INFO(ID_ISAR5, isa32, 5) > GENERATE_TID3_INFO(ID_ISAR6, isa32, 6) > - /* MVFR registers are in cp10 no cp15 */ > + /* MVFR registers are in cp10 not cp15 */ > > HSR_CPREG32_TID3_RESERVED_CASE: > /* Handle all reserved registers as RAZ */ > @@ -638,6 +638,43 @@ 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 ^ HCR > + * VFP/Simd using VMRS/VMSR instructions. > + * 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) > + GENERATE_TID3_INFO(MVFR2, mvfr, 2) > + > + 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; I take we are sure there are no other cp10 registers of interest? > + } > + > + advance_pc(regs, hsr); > +} > + > void do_cp(struct cpu_user_regs *regs, const union hsr hsr) > { > const struct hsr_cp cp = hsr.cp; > diff --git a/xen/include/asm-arm/perfc_defn.h > b/xen/include/asm-arm/perfc_defn.h > index 6a83185163..31f071222b 100644 > --- a/xen/include/asm-arm/perfc_defn.h > +++ b/xen/include/asm-arm/perfc_defn.h > @@ -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") > diff --git a/xen/include/asm-arm/traps.h b/xen/include/asm-arm/traps.h > index 997c37884e..c4a3d0fb1b 100644 > --- a/xen/include/asm-arm/traps.h > +++ b/xen/include/asm-arm/traps.h > @@ -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 */ > -- > 2.17.1 >
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |