From 0d27b4b351493cb2fe1f87cd152856704d4e141d Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Wed, 20 May 2026 11:01:56 +0100 Subject: KVM: arm64: Simplify userspace notification of interrupt state The userspace notification of interrupts is has a few problems: - it is utterly pointless - it is annoyingly split between detecting the need for notification and the population of the interrupts in the run structure We can't do anything about the former (yet), but the latter can be addressed. If we detect that we must notify userspace, we know that we are going to exit, as we populate the exit status. Which means we can also populate the interrupt state at this stage and be done with it. This simplifies the structure of the code. Reviewed-by: Oliver Upton Link: https://patch.msgid.link/20260520100200.543845-3-maz@kernel.org Signed-off-by: Marc Zyngier --- include/kvm/arm_arch_timer.h | 2 +- include/kvm/arm_pmu.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/kvm/arm_arch_timer.h b/include/kvm/arm_arch_timer.h index bf8cc9589bd0..9e4076eebd29 100644 --- a/include/kvm/arm_arch_timer.h +++ b/include/kvm/arm_arch_timer.h @@ -104,7 +104,7 @@ void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu); void kvm_timer_sync_nested(struct kvm_vcpu *vcpu); void kvm_timer_sync_user(struct kvm_vcpu *vcpu); bool kvm_timer_should_notify_user(struct kvm_vcpu *vcpu); -void kvm_timer_update_run(struct kvm_vcpu *vcpu); +bool kvm_timer_update_run(struct kvm_vcpu *vcpu); void kvm_timer_vcpu_terminate(struct kvm_vcpu *vcpu); void kvm_timer_init_vm(struct kvm *kvm); diff --git a/include/kvm/arm_pmu.h b/include/kvm/arm_pmu.h index 0a36a3d5c894..3e844c5ee917 100644 --- a/include/kvm/arm_pmu.h +++ b/include/kvm/arm_pmu.h @@ -54,7 +54,7 @@ void kvm_pmu_reprogram_counter_mask(struct kvm_vcpu *vcpu, u64 val); void kvm_pmu_flush_hwstate(struct kvm_vcpu *vcpu); void kvm_pmu_sync_hwstate(struct kvm_vcpu *vcpu); bool kvm_pmu_should_notify_user(struct kvm_vcpu *vcpu); -void kvm_pmu_update_run(struct kvm_vcpu *vcpu); +bool kvm_pmu_update_run(struct kvm_vcpu *vcpu); void kvm_pmu_software_increment(struct kvm_vcpu *vcpu, u64 val); void kvm_pmu_handle_pmcr(struct kvm_vcpu *vcpu, u64 val); void kvm_pmu_set_counter_event_type(struct kvm_vcpu *vcpu, u64 data, @@ -131,7 +131,7 @@ static inline bool kvm_pmu_should_notify_user(struct kvm_vcpu *vcpu) { return false; } -static inline void kvm_pmu_update_run(struct kvm_vcpu *vcpu) {} +static inline bool kvm_pmu_update_run(struct kvm_vcpu *vcpu) { return false; } static inline void kvm_pmu_software_increment(struct kvm_vcpu *vcpu, u64 val) {} static inline void kvm_pmu_handle_pmcr(struct kvm_vcpu *vcpu, u64 val) {} static inline void kvm_pmu_set_counter_event_type(struct kvm_vcpu *vcpu, -- cgit v1.2.3 From ac7002031852ab8f75b3debb1a4c4b2d1ff5a26c Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Wed, 20 May 2026 11:01:57 +0100 Subject: KVM: arm64: timer: Kill the per-timer irq level cache The timer code makes use of a per-timer irq level cache, which looks like a very minor optimisation to avoid taking a lock upon updating the GIC view of the interrupt when it is unchanged from the previous state. This is coming in the way of more important correctness issues, so get rid of the cache, which simplifies a couple of minor things. Reviewed-by: Oliver Upton Link: https://patch.msgid.link/20260520100200.543845-4-maz@kernel.org Signed-off-by: Marc Zyngier --- include/kvm/arm_arch_timer.h | 5 ----- 1 file changed, 5 deletions(-) (limited to 'include') diff --git a/include/kvm/arm_arch_timer.h b/include/kvm/arm_arch_timer.h index 9e4076eebd29..15a4f97f8105 100644 --- a/include/kvm/arm_arch_timer.h +++ b/include/kvm/arm_arch_timer.h @@ -66,11 +66,6 @@ struct arch_timer_context { */ bool loaded; - /* Output level of the timer IRQ */ - struct { - bool level; - } irq; - /* Who am I? */ enum kvm_arch_timers timer_id; -- cgit v1.2.3 From 2772383afc5c65d6242f62947b5c184ffb049359 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Wed, 20 May 2026 11:01:58 +0100 Subject: KVM: arm64: pmu: Kill the PMU interrupt level cache Just like the timer, the PMU has an interrupt cache that serves little purpose. Drop it. Reviewed-by: Oliver Upton Link: https://patch.msgid.link/20260520100200.543845-5-maz@kernel.org Signed-off-by: Marc Zyngier --- include/kvm/arm_pmu.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include') diff --git a/include/kvm/arm_pmu.h b/include/kvm/arm_pmu.h index 3e844c5ee917..b5e5942204fc 100644 --- a/include/kvm/arm_pmu.h +++ b/include/kvm/arm_pmu.h @@ -32,7 +32,6 @@ struct kvm_pmu { struct kvm_pmc pmc[KVM_ARMV8_PMU_MAX_COUNTERS]; int irq_num; bool created; - bool irq_level; }; struct arm_pmu_entry { -- cgit v1.2.3 From 2e83ac3b3b1a1b3b248a4af07efb19a1acb29845 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Wed, 20 May 2026 10:19:33 +0100 Subject: KVM: arm64: vgic-v5: Move PPI caps into kvm_vgic_global_state Constant vgic properties are usually kept in kvm_vgic_global_state, but the vgic-v5 code does its own thing. Move the ppi_caps data into the global structure, which has the modest additional advantage of making it ro_after_init. Link: https://lore.kernel.org/r/20260520091949.542365-3-maz@kernel.org Signed-off-by: Marc Zyngier --- include/kvm/arm_vgic.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'include') diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h index 1388dc6028a9..ea793479ab25 100644 --- a/include/kvm/arm_vgic.h +++ b/include/kvm/arm_vgic.h @@ -177,6 +177,11 @@ struct vgic_global { bool has_gcie_v3_compat; u32 ich_vtr_el2; + + /* GICv5 PPI capabilities */ + struct { + DECLARE_BITMAP(impl_ppi_mask, VGIC_V5_NR_PRIVATE_IRQS); + } vgic_v5_ppi_caps; }; extern struct vgic_global kvm_vgic_global_state; @@ -492,11 +497,6 @@ struct vgic_v5_cpu_if { struct gicv5_vpe gicv5_vpe; }; -/* What PPI capabilities does a GICv5 host have */ -struct vgic_v5_ppi_caps { - DECLARE_BITMAP(impl_ppi_mask, VGIC_V5_NR_PRIVATE_IRQS); -}; - struct vgic_cpu { /* CPU vif control registers for world switch */ union { -- cgit v1.2.3 From c4a1191f802792fe22fc261fa0e918d048915911 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Wed, 20 May 2026 10:19:36 +0100 Subject: KVM: arm64: vgic: Constify struct irq_ops usage vgic-v5 has introduced much more prevalent usage of the struct irq_ops mechanism. In the process, it becomes evident that suffers from two related problems: - it contains flags, rather than only callbacks - it is mutable, because we need to update the above flags Swap the flags for a helper retrieving the flags, and make all irq_ops const, something that is slightly satisfying. Reviewed-by: Joey Gouly Link: https://lore.kernel.org/r/20260520091949.542365-6-maz@kernel.org Signed-off-by: Marc Zyngier --- include/kvm/arm_vgic.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h index ea793479ab25..fe49fb56dc3c 100644 --- a/include/kvm/arm_vgic.h +++ b/include/kvm/arm_vgic.h @@ -205,7 +205,7 @@ struct vgic_irq; */ struct irq_ops { /* Per interrupt flags for special-cased interrupts */ - unsigned long flags; + unsigned long (*get_flags)(void); #define VGIC_IRQ_SW_RESAMPLE BIT(0) /* Clear the active state for resampling */ @@ -271,7 +271,7 @@ struct vgic_irq { u8 priority; u8 group; /* 0 == group 0, 1 == group 1 */ - struct irq_ops *ops; + const struct irq_ops *ops; void *owner; /* Opaque pointer to reserve an interrupt for in-kernel devices. */ @@ -279,7 +279,8 @@ struct vgic_irq { static inline bool vgic_irq_needs_resampling(struct vgic_irq *irq) { - return irq->ops && (irq->ops->flags & VGIC_IRQ_SW_RESAMPLE); + return irq->ops && irq->ops->get_flags && + (irq->ops->get_flags() & VGIC_IRQ_SW_RESAMPLE); } struct vgic_register_region; @@ -557,7 +558,7 @@ void kvm_vgic_init_cpu_hardware(void); int kvm_vgic_inject_irq(struct kvm *kvm, struct kvm_vcpu *vcpu, unsigned int intid, bool level, void *owner); void kvm_vgic_set_irq_ops(struct kvm_vcpu *vcpu, u32 vintid, - struct irq_ops *ops); + const struct irq_ops *ops); void kvm_vgic_clear_irq_ops(struct kvm_vcpu *vcpu, u32 vintid); int kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu, unsigned int host_irq, u32 vintid); -- cgit v1.2.3