From: Kunkun Jiang jiangkunkun@huawei.com
virt inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I8K89F CVE: NA
------------------------------------------------------------------
Disable gic_auto_clr when vcpu put and enable it when vcpu load. Add a parameter "gic_clr_enable" as a global switch instead of hardware switch.
Signed-off-by: Zenghui Yu yuzenghui@huawei.com Signed-off-by: Kunkun Jiang jiangkunkun@huawei.com Signed-off-by: Dongxu Sun sundongxu3@huawei.com --- arch/arm64/kvm/arch_timer.c | 20 ++++++++++++++++++-- drivers/irqchip/irq-mbigen.c | 25 +++++++++++++++++++++++++ include/clocksource/arm_arch_timer.h | 1 + 3 files changed, 44 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c index d0fd8200d130..ed148215108d 100644 --- a/arch/arm64/kvm/arch_timer.c +++ b/arch/arm64/kvm/arch_timer.c @@ -632,6 +632,13 @@ static void kvm_vtimer_mbigen_auto_clr_set(struct kvm_vcpu *vcpu, bool set) vtimer_mbigen_set_auto_clr(vcpu->cpu, set); }
+static void kvm_vtimer_gic_auto_clr_set(struct kvm_vcpu *vcpu, bool set) +{ + BUG_ON(!vtimer_is_irqbypass()); + + vtimer_gic_set_auto_clr(vcpu->cpu, set); +} + static void kvm_vtimer_mbigen_restore_stat(struct kvm_vcpu *vcpu) { struct vtimer_mbigen_context *mbigen_ctx = vcpu_vtimer_mbigen(vcpu); @@ -655,6 +662,9 @@ static void kvm_vtimer_mbigen_restore_stat(struct kvm_vcpu *vcpu) local_irq_restore(flags); }
+bool gic_clr_enable = true; +module_param(gic_clr_enable, bool, S_IRUGO | S_IWUSR); + void kvm_timer_vcpu_load(struct kvm_vcpu *vcpu) { struct arch_timer_cpu *timer = vcpu_timer(vcpu); @@ -686,8 +696,12 @@ void kvm_timer_vcpu_load(struct kvm_vcpu *vcpu)
timer_restore_state(map.direct_vtimer);
- if (vtimer_is_irqbypass()) + if (vtimer_is_irqbypass()) { kvm_vtimer_mbigen_auto_clr_set(vcpu, true); + if (gic_clr_enable) { + kvm_vtimer_gic_auto_clr_set(vcpu, true); + } + }
if (map.direct_ptimer) timer_restore_state(map.direct_ptimer); @@ -747,8 +761,10 @@ void kvm_timer_vcpu_put(struct kvm_vcpu *vcpu)
get_timer_map(vcpu, &map);
- if (vtimer_is_irqbypass()) + if (vtimer_is_irqbypass()) { kvm_vtimer_mbigen_auto_clr_set(vcpu, false); + kvm_vtimer_gic_auto_clr_set(vcpu, false); + }
timer_save_state(map.direct_vtimer);
diff --git a/drivers/irqchip/irq-mbigen.c b/drivers/irqchip/irq-mbigen.c index da77ef7d6198..7e6d8d33683b 100644 --- a/drivers/irqchip/irq-mbigen.c +++ b/drivers/irqchip/irq-mbigen.c @@ -87,6 +87,8 @@ #define REG_VTIMER_MBIGEN_TYPE_OFFSET 0x1000 #define REG_VTIMER_MBIGEN_SET_AUTO_CLR_OFFSET 0x1100 #define REG_VTIMER_MBIGEN_CLR_AUTO_CLR_OFFSET 0x1110 +#define REG_VTIMER_GIC_SET_AUTO_CLR_OFFSET 0x1150 +#define REG_VTIMER_GIC_CLR_AUTO_CLR_OFFSET 0x1160 #define REG_VTIMER_MBIGEN_ATV_STAT_OFFSET 0x1120 #define REG_VTIMER_MBIGEN_VEC_OFFSET 0x1200 #define REG_VTIMER_MBIGEN_ATV_CLR_OFFSET 0xa008 @@ -223,6 +225,29 @@ void vtimer_mbigen_set_auto_clr(int cpu_id, bool set) dsb(sy); }
+void vtimer_gic_set_auto_clr(int cpu_id, bool set) +{ + struct vtimer_mbigen_device *chip; + void __iomem *addr; + int cpu_abs_offset; + u64 offset; + u32 val; + + chip = get_vtimer_mbigen(cpu_id); + if (!chip) + return; + + cpu_abs_offset = get_abs_offset(cpu_id, chip->cpu_base); + offset = set ? REG_VTIMER_GIC_SET_AUTO_CLR_OFFSET : + REG_VTIMER_GIC_CLR_AUTO_CLR_OFFSET; + addr = chip->base + offset + + (cpu_abs_offset / PPIS_PER_MBIGEN_NODE) * REG_VTIMER_MBIGEN_WIDTH; + val = 1 << (cpu_abs_offset % PPIS_PER_MBIGEN_NODE); + + writel_relaxed(val, addr); + dsb(sy); +} + void vtimer_mbigen_set_active(int cpu_id, bool set) { struct vtimer_mbigen_device *chip; diff --git a/include/clocksource/arm_arch_timer.h b/include/clocksource/arm_arch_timer.h index ea2179cfe1c3..68c67ddd1dc0 100644 --- a/include/clocksource/arm_arch_timer.h +++ b/include/clocksource/arm_arch_timer.h @@ -121,6 +121,7 @@ static inline bool vtimer_irqbypass_hw_support(struct arch_timer_kvm_info *info) void vtimer_mbigen_set_vector(int cpu_id, u16 vpeid); bool vtimer_mbigen_get_active(int cpu_id); void vtimer_mbigen_set_auto_clr(int cpu_id, bool set); +void vtimer_gic_set_auto_clr(int cpu_id, bool set); void vtimer_mbigen_set_active(int cpu_id, bool set);
#endif