[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v2 15/17] arm: Hook workaround handler from traps.c based on Cavium workaround_30115
Function vgic_v3_handle_cpuif_access is called from do_trap_guest_sync if ARM64_WORKAROUND_CAVIUM_30115 capability is found. A flag skip_hyp_tail is introduced in struct cpu_info. This flag is used to skip leave_hypervisor_tail when enter_hypervisor_head is not invoked. enter_hypervisor_head andleave_hypervisor_tail are invoked in sync, if one is not called other one should be skipped, otherwise guest vGIC state be out-of-date. Signed-off-by: Manish Jaggi <manish.jaggi@xxxxxxxxxx> --- xen/arch/arm/arm64/Makefile | 1 + xen/arch/arm/traps.c | 31 +++++++++++++++++++++++++++++++ xen/include/asm-arm/current.h | 3 ++- 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/xen/arch/arm/arm64/Makefile b/xen/arch/arm/arm64/Makefile index 718fe44455..eed3c9e913 100644 --- a/xen/arch/arm/arm64/Makefile +++ b/xen/arch/arm/arm64/Makefile @@ -11,3 +11,4 @@ obj-y += smpboot.o obj-y += traps.o obj-y += vfp.o obj-y += vsysreg.o +obj-$(CONFIG_CAVIUM_ERRATUM_30115) += vgic-v3-sr.o diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c index f6f6de3691..1dc34275b3 100644 --- a/xen/arch/arm/traps.c +++ b/xen/arch/arm/traps.c @@ -2103,6 +2103,27 @@ void do_trap_guest_sync(struct cpu_user_regs *regs) { const union hsr hsr = { .bits = regs->hsr }; + if ( check_workaround_cavium_30115() ) + { + if ( vgic_v3_handle_cpuif_access(regs) ) + { + /* + * if true, g0/g1 vgic register trap is emulated for errata + * so rest of handling of do_trap_guest_sync is not required. + */ + advance_pc(regs, hsr); + /* + * enter_hypervisor_head is not invoked when workaround 30115 + * is in place. enter_hypervisor_head and leave_hypervisor_tail + * are invoked in sync, if one is not called other one should be + * skipped, otherwise guest vGIC state be out-of-date. + */ + get_cpu_info()->skip_hyp_tail = true; + + return; + } + } + enter_hypervisor_head(regs); switch (hsr.ec) { @@ -2295,6 +2316,16 @@ void do_trap_fiq(struct cpu_user_regs *regs) void leave_hypervisor_tail(void) { + /* + * if skip_hyp_tail is set simply retrun; + */ + if ( unlikely(get_cpu_info()->skip_hyp_tail) ) + { + /* clear it, so that it is false when not handling g0/g1 traps */ + get_cpu_info()->skip_hyp_tail = false; + return; + } + while (1) { local_irq_disable(); diff --git a/xen/include/asm-arm/current.h b/xen/include/asm-arm/current.h index 7a0971fdea..63b7e68f0b 100644 --- a/xen/include/asm-arm/current.h +++ b/xen/include/asm-arm/current.h @@ -21,7 +21,14 @@ DECLARE_PER_CPU(struct vcpu *, curr_vcpu); struct cpu_info { struct cpu_user_regs guest_cpu_user_regs; unsigned long elr; - unsigned int pad; +/* + * Flag is used to skip leave_hypervisor_tail when enter_hypervisor_head + * is not invoked. enter_hypervisor_head andleave_hypervisor_tail are + * invoked in sync, if one is not called other one should be skipped, + * otherwise guest vGIC state be out-of-date. + */ + bool skip_hyp_tail:1; + unsigned int pad:31; }; static inline struct cpu_info *get_cpu_info(void) -- 2.14.1 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |