On Mon, 13 Mar 2017, Wei Chen wrote: > Currently, ARM32 and ARM64 has different SError exception handlers. > These handlers include lots of code to check SError handle options > and code to distinguish guest-generated SErrors from hypervisor > SErrors. > > The new helpers: do_trap_guest_serror and do_trap_hyp_serror are > wrappers of __do_trap_serror with constant guest/hyp parameters. > __do_trap_serror moves the option checking code and SError checking > code from assembly to C source. This will make the code become more > readable and avoid placing check code in too many places. > > These two helpers only handle the following 3 types of SErrors: > 1) Guest-generated SError and had been delivered in EL1 and then > been forwarded to EL2. > 2) Guest-generated SError but hadn't been delivered in EL1 before > trapping to EL2. This SError would be caught in EL2 as soon as > we just unmasked the PSTATE.A bit. > 3) Hypervisor generated native SError, that would be a bug. > > In the new helpers, we have used the function "inject_vabt_exception" > which was disabled by "#if 0" before. Now, we can remove the "#if 0" > to make this function to be available. > > Signed-off-by: Wei Chen <wei.c...@arm.com>
Reviewed-by: Stefano Stabellini <sstabell...@kernel.org> > --- > xen/arch/arm/traps.c | 69 > +++++++++++++++++++++++++++++++++++++++-- > xen/include/asm-arm/processor.h | 4 +++ > 2 files changed, 71 insertions(+), 2 deletions(-) > > diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c > index 053b7fc..48cfc8e 100644 > --- a/xen/arch/arm/traps.c > +++ b/xen/arch/arm/traps.c > @@ -646,7 +646,6 @@ static void inject_dabt_exception(struct cpu_user_regs > *regs, > #endif > } > > -#if 0 > /* Inject a virtual Abort/SError into the guest. */ > static void inject_vabt_exception(struct cpu_user_regs *regs) > { > @@ -676,7 +675,59 @@ static void inject_vabt_exception(struct cpu_user_regs > *regs) > > current->arch.hcr_el2 |= HCR_VA; > } > -#endif > + > +/* > + * SError exception handler. We only handle the following 3 types of SErrors: > + * 1) Guest-generated SError and had been delivered in EL1 and then > + * been forwarded to EL2. > + * 2) Guest-generated SError but hadn't been delivered in EL1 before > + * trapping to EL2. This SError would be caught in EL2 as soon as > + * we just unmasked the PSTATE.A bit. > + * 3) Hypervisor generated native SError, that would be a bug. > + * > + * A true parameter "guest" means that the SError is type#1 or type#2. > + */ > +static void __do_trap_serror(struct cpu_user_regs *regs, bool guest) > +{ > + /* > + * Only "DIVERSE" option needs to distinguish the guest-generated SErrors > + * from hypervisor SErrors. > + */ > + if ( serrors_op == SERRORS_DIVERSE ) > + { > + /* Forward the type#1 and type#2 SErrors to guests. */ > + if ( guest ) > + return inject_vabt_exception(regs); > + > + /* Type#3 SErrors will panic the whole system */ > + goto crash_system; > + } > + > + /* > + * The "FORWARD" option will forward all SErrors to the guests, except > + * idle domain generated SErrors. > + */ > + if ( serrors_op == SERRORS_FORWARD ) > + { > + /* > + * Because the idle domain doesn't have the ability to handle the > + * SErrors, we have to crash the whole system while we get a SError > + * generated by idle domain. > + */ > + if ( is_idle_vcpu(current) ) > + goto crash_system; > + > + return inject_vabt_exception(regs); > + } > + > +crash_system: > + /* Three possibilities to crash the whole system: > + * 1) "DIVERSE" option with Hypervisor generated SErrors. > + * 2) "FORWARD" option with Idle Domain generated SErrors. > + * 3) "PANIC" option with all SErrors. > + */ > + do_unexpected_trap("SError", regs); > +} > > struct reg_ctxt { > /* Guest-side state */ > @@ -2863,6 +2914,20 @@ asmlinkage void do_trap_guest_error(struct > cpu_user_regs *regs) > domain_crash_synchronous(); > } > > +asmlinkage void do_trap_hyp_serror(struct cpu_user_regs *regs) > +{ > + enter_hypervisor_head(regs); > + > + __do_trap_serror(regs, VABORT_GEN_BY_GUEST(regs)); > +} > + > +asmlinkage void do_trap_guest_serror(struct cpu_user_regs *regs) > +{ > + enter_hypervisor_head(regs); > + > + __do_trap_serror(regs, true); > +} > + > asmlinkage void do_trap_irq(struct cpu_user_regs *regs) > { > enter_hypervisor_head(regs); > diff --git a/xen/include/asm-arm/processor.h b/xen/include/asm-arm/processor.h > index 148cc6f..885dbca 100644 > --- a/xen/include/asm-arm/processor.h > +++ b/xen/include/asm-arm/processor.h > @@ -709,6 +709,10 @@ int call_smc(register_t function_id, register_t arg0, > register_t arg1, > > void do_trap_guest_error(struct cpu_user_regs *regs); > > +void do_trap_hyp_serror(struct cpu_user_regs *regs); > + > +void do_trap_guest_serror(struct cpu_user_regs *regs); > + > /* Functions for pending virtual abort checking window. */ > void abort_guest_exit_start(void); > void abort_guest_exit_end(void); > -- > 2.7.4 > > > _______________________________________________ > Xen-devel mailing list > Xen-devel@lists.xen.org > https://lists.xen.org/xen-devel > _______________________________________________ Xen-devel mailing list Xen-devel@lists.xen.org https://lists.xen.org/xen-devel