diff --git a/xen/arch/arm/arm64/entry.S b/xen/arch/arm/arm64/entry.S index 9cda8f1342..0ed0073267 100644 --- a/xen/arch/arm/arm64/entry.S +++ b/xen/arch/arm/arm64/entry.S @@ -204,9 +204,12 @@ guest_fiq_invalid: entry hyp=0, compat=0 invalid BAD_FIQ -guest_error_invalid: +guest_error: entry hyp=0, compat=0 - invalid BAD_ERROR + msr daifclr, #2 + mov x0, sp + bl do_trap_guest_error + exit hyp=0, compat=0 guest_sync_compat: entry hyp=0, compat=1 @@ -225,9 +228,12 @@ guest_fiq_invalid_compat: entry hyp=0, compat=1 invalid BAD_FIQ -guest_error_invalid_compat: +guest_error_compat: entry hyp=0, compat=1 - invalid BAD_ERROR + msr daifclr, #2 + mov x0, sp + bl do_trap_guest_error + exit hyp=0, compat=1 ENTRY(return_to_new_vcpu32) exit hyp=0, compat=1 @@ -286,12 +292,12 @@ ENTRY(hyp_traps_vector) ventry guest_sync // Synchronous 64-bit EL0/EL1 ventry guest_irq // IRQ 64-bit EL0/EL1 ventry guest_fiq_invalid // FIQ 64-bit EL0/EL1 - ventry guest_error_invalid // Error 64-bit EL0/EL1 + ventry guest_error // Error 64-bit EL0/EL1 ventry guest_sync_compat // Synchronous 32-bit EL0/EL1 ventry guest_irq_compat // IRQ 32-bit EL0/EL1 ventry guest_fiq_invalid_compat // FIQ 32-bit EL0/EL1 - ventry guest_error_invalid_compat // Error 32-bit EL0/EL1 + ventry guest_error_compat // Error 32-bit EL0/EL1 /* * struct vcpu *__context_switch(struct vcpu *prev, struct vcpu *next) diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c index aa3e3c2bfb..b9cfdaee7f 100644 --- a/xen/arch/arm/traps.c +++ b/xen/arch/arm/traps.c @@ -2645,6 +2645,21 @@ asmlinkage void do_trap_hypervisor(struct cpu_user_regs *regs) } } +asmlinkage void do_trap_guest_error(struct cpu_user_regs *regs) +{ + enter_hypervisor_head(regs); + + /* + * Currently, to ensure hypervisor safety, when we received a + * guest-generated vSerror/vAbort, we just crash the guest to protect + * the hypervisor. In future we can better handle this by injecting + * a vSerror/vAbort to the guest. + */ + gdprintk(XENLOG_WARNING, "Guest(Dom-%u) will be crashed by vSError\n", + current->domain->domain_id); + domain_crash_synchronous(); +} + asmlinkage void do_trap_irq(struct cpu_user_regs *regs) { enter_hypervisor_head(regs);