If the user adds "kvm-arm.vtimer_irqbypass=1" to enable vtimer but does not enable GICv4.1, "vtimer_mbigen_device_probe" will still attempt to configure the mbigen register of vtimer, which may lead to unexpected behavior. This patch adds a check to ensure that vtimer is only enabled when GICv4.1 is enabled. Fixes: d306753c582d ("KVM: arm64: arch_timer: Probe vtimer irqbypass capability") Signed-off-by: Jinqian Yang <yangjinqian1@huawei.com> --- arch/arm64/kvm/vgic/vgic-v3.c | 2 +- drivers/irqchip/irq-gic-v3.c | 8 ++++++++ drivers/irqchip/irq-mbigen.c | 16 ++++++++++++++-- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/arch/arm64/kvm/vgic/vgic-v3.c b/arch/arm64/kvm/vgic/vgic-v3.c index fa02b0cb1497..8600b443df42 100644 --- a/arch/arm64/kvm/vgic/vgic-v3.c +++ b/arch/arm64/kvm/vgic/vgic-v3.c @@ -20,7 +20,7 @@ static bool group0_trap; static bool group1_trap; static bool common_trap; static bool dir_trap; -static bool gicv4_enable; +bool gicv4_enable; void vgic_v3_set_underflow(struct kvm_vcpu *vcpu) { diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index 849d2e0db4fd..8ab2dcb942db 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c @@ -1368,6 +1368,14 @@ static int __gic_update_rdist_properties(struct redist_region *region, return 1; } +#ifdef CONFIG_VIRT_VTIMER_IRQ_BYPASS +bool is_vtimer_supported(void) +{ + return gic_data.rdists.has_vtimer; +} +EXPORT_SYMBOL(is_vtimer_supported); +#endif + static void gic_update_rdist_properties(void) { gic_data.ppi_nr = UINT_MAX; diff --git a/drivers/irqchip/irq-mbigen.c b/drivers/irqchip/irq-mbigen.c index a6aba60df599..d80e4195ddc3 100644 --- a/drivers/irqchip/irq-mbigen.c +++ b/drivers/irqchip/irq-mbigen.c @@ -706,6 +706,18 @@ static bool vtimer_mbigen_should_probe(struct mbigen_device *mgn_chip) #define CHIP1_TB_PERI_PHY_BASE 0x20c614002018 extern bool vtimer_irqbypass; +extern bool gicv4_enable; +extern bool is_vtimer_supported(void); + +static bool is_vtimer_enabled(void) +{ + /* + * 'gicv4_enable' indicates whether the user enables GICv4. + * 'is_vtimer_supported()' check whether vtimer is supported. + * 'vtimer_irqbypass' indicates whether the user enables vtimer. + */ + return gicv4_enable && is_vtimer_supported() && vtimer_irqbypass; +} static int vtimer_mbigen_set_regs(struct platform_device *pdev) { @@ -716,7 +728,7 @@ static int vtimer_mbigen_set_regs(struct platform_device *pdev) u32 val; struct vtimer_mbigen_device *chip; - if (!vtimer_irqbypass) + if (!is_vtimer_enabled()) return 0; if (!mgn_chip) @@ -796,7 +808,7 @@ static int vtimer_mbigen_device_probe(struct platform_device *pdev) struct vtimer_mbigen_device *vtimer_mgn_chip; int err; - if (!vtimer_irqbypass) + if (!is_vtimer_enabled()) return 0; err = vtimer_mbigen_set_regs(pdev); -- 2.33.0