[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v3 15/17] arm: Hook workaround handler from traps.c based on Cavium workaround_30115
From: Manish Jaggi <manish.jaggi@xxxxxxxxxx> 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> diff --git a/xen/arch/arm/arm64/Makefile b/xen/arch/arm/arm64/Makefile index bb5c610b2a..904bf48703 100644 --- a/xen/arch/arm/arm64/Makefile +++ b/xen/arch/arm/arm64/Makefile @@ -12,3 +12,4 @@ obj-y += smpboot.o obj-y += traps.o obj-y += vfp.o obj-y += vsysreg.o +obj-y += vgic-v3-sr.o diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c index 5c18e918b0..bc851d5e26 100644 --- a/xen/arch/arm/traps.c +++ b/xen/arch/arm/traps.c @@ -2044,6 +2044,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) { @@ -2242,6 +2263,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..6dce06289f 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 |