From: Wei Chen Date: Wed, 5 Apr 2017 09:09:07 +0000 (+0800) Subject: xen/arm: Save HCR_EL2 when a guest took the SError X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=04ff92f4537f8f47ebd4eb95808619443979b2b9;p=people%2Froyger%2Fxen.git xen/arm: Save HCR_EL2 when a guest took the SError The HCR_EL2.VSE (HCR.VA for aarch32) bit can be used to generate a virtual abort to guest. The HCR_EL2.VSE bit has a peculiar feature of getting cleared when the guest has taken the abort (this is the only bit that behaves as such in HCR_EL2 register). This means that if we set the HCR_EL2.VSE bit to signal such an abort, we must preserve it in the guest context until it disappears from HCR_EL2, and at which point it must be cleared from the context. This is achieved by reading back from HCR_EL2 until the guest takes the fault. If we preserved a pending VSE in guest context, we have to restore it to HCR_EL2 when context switch to this guest. This is achieved by writing saved HCR_EL2 value in guest context back to HCR_EL2 register before return to guest. This had been done by the patch of "Restore HCR_EL2 register". Signed-off-by: Wei Chen Reviewed-by: Stefano Stabellini --- diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c index ebe25c6d1e..35ca0edd89 100644 --- a/xen/arch/arm/traps.c +++ b/xen/arch/arm/traps.c @@ -2694,7 +2694,18 @@ static void do_trap_smc(struct cpu_user_regs *regs, const union hsr hsr) static void enter_hypervisor_head(struct cpu_user_regs *regs) { if ( guest_mode(regs) ) + { + /* + * If we pended a virtual abort, preserve it until it gets cleared. + * See ARM ARM DDI 0487A.j D1.14.3 (Virtual Interrupts) for details, + * but the crucial bit is "On taking a vSError interrupt, HCR_EL2.VSE + * (alias of HCR.VA) is cleared to 0." + */ + if ( current->arch.hcr_el2 & HCR_VA ) + current->arch.hcr_el2 = READ_SYSREG(HCR_EL2); + gic_clear_lrs(current); + } } asmlinkage void do_trap_hypervisor(struct cpu_user_regs *regs)