From: wanghaibin <wanghaibin.wang@huawei.com> As we continue cutting a VGIC-shaped hole in KVM, let's indirect all of the handling of mapped interrupts into the bit irqchip_flow bucket. Signed-off-by: Marc Zyngier <maz@kernel.org> Signed-off-by: wanghaibin <wanghaibin.wang@huawei.com> --- arch/arm64/include/asm/kvm_irq.h | 18 +++++++++++++ arch/arm64/kvm/arch_timer.c | 44 ++++++++++++++++---------------- arch/arm64/kvm/vgic/vgic-init.c | 4 +++ arch/arm64/kvm/vgic/vgic.h | 8 ++++++ include/kvm/arm_vgic.h | 6 ----- 5 files changed, 52 insertions(+), 28 deletions(-) diff --git a/arch/arm64/include/asm/kvm_irq.h b/arch/arm64/include/asm/kvm_irq.h index 4b5e4a280395..40fe9e826ee4 100644 --- a/arch/arm64/include/asm/kvm_irq.h +++ b/arch/arm64/include/asm/kvm_irq.h @@ -6,6 +6,7 @@ #ifndef __ARM64_KVM_IRQ_H__ #define __ARM64_KVM_IRQ_H__ +#include <kvm/arm_vgic.h> /* fix */ enum kvm_irqchip_type { IRQCHIP_USER, /* Implemented in userspace */ @@ -34,6 +35,11 @@ struct kvm_irqchip_flow { int (*irqchip_inject_userspace_irq)(struct kvm *, unsigned int type, unsigned int cpu, unsigned int intid, bool); + bool (*irqchip_map_is_active)(struct kvm_vcpu *, unsigned in); + void (*irqchip_reset_mapped_irq)(struct kvm_vcpu *, u32); + int (*irqchip_map_phys_irq)(struct kvm_vcpu *, unsigned int, + u32, struct irq_ops *); + int (*irqchip_unmap_phys_irq)(struct kvm_vcpu *, unsigned int); }; /* @@ -102,4 +108,16 @@ struct kvm_irqchip_flow { #define kvm_irqchip_inject_userspace_irq(k, ...) \ __kvm_irqchip_action_ret((k), inject_userspace_irq, (k), __VA_ARGS__) +#define kvm_irqchip_map_is_active(v, ...) \ + __vcpu_irqchip_action_ret((v), map_is_active, (v), __VA_ARGS__) + +#define kvm_irqchip_reset_mapped_irq(v, ...) \ + __vcpu_irqchip_action((v), reset_mapped_irq, (v), __VA_ARGS__) + +#define kvm_irqchip_map_phys_irq(v, ...) \ + __vcpu_irqchip_action_ret((v), map_phys_irq, (v), __VA_ARGS__) + +#define kvm_irqchip_unmap_phys_irq(v, ...) \ + __vcpu_irqchip_action_ret((v), unmap_phys_irq, (v), __VA_ARGS__) + #endif diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c index d02c7414c4da..cb652edb04a7 100644 --- a/arch/arm64/kvm/arch_timer.c +++ b/arch/arm64/kvm/arch_timer.c @@ -811,7 +811,7 @@ static void kvm_timer_vcpu_load_gic(struct arch_timer_context *ctx) kvm_timer_update_irq(ctx->vcpu, kvm_timer_should_fire(ctx), ctx); if (irqchip_in_kernel(vcpu->kvm)) - phys_active = kvm_vgic_map_is_active(vcpu, timer_irq(ctx)); + phys_active = kvm_irqchip_map_is_active(vcpu, timer_irq(ctx)); phys_active |= ctx->irq.level; @@ -875,18 +875,18 @@ static void kvm_timer_vcpu_load_nested_switch(struct kvm_vcpu *vcpu, */ hw = kvm_vgic_get_map(vcpu, timer_irq(map->direct_vtimer)); if (hw < 0) { - kvm_vgic_unmap_phys_irq(vcpu, timer_irq(map->emul_vtimer)); - kvm_vgic_unmap_phys_irq(vcpu, timer_irq(map->emul_ptimer)); + kvm_irqchip_unmap_phys_irq(vcpu, timer_irq(map->emul_vtimer)); + kvm_irqchip_unmap_phys_irq(vcpu, timer_irq(map->emul_ptimer)); - ret = kvm_vgic_map_phys_irq(vcpu, - map->direct_vtimer->host_timer_irq, - timer_irq(map->direct_vtimer), - &arch_timer_irq_ops); + ret = kvm_irqchip_map_phys_irq(vcpu, + map->direct_vtimer->host_timer_irq, + timer_irq(map->direct_vtimer), + &arch_timer_irq_ops); WARN_ON_ONCE(ret); - ret = kvm_vgic_map_phys_irq(vcpu, - map->direct_ptimer->host_timer_irq, - timer_irq(map->direct_ptimer), - &arch_timer_irq_ops); + ret = kvm_irqchip_map_phys_irq(vcpu, + map->direct_ptimer->host_timer_irq, + timer_irq(map->direct_ptimer), + &arch_timer_irq_ops); WARN_ON_ONCE(ret); /* @@ -1190,7 +1190,7 @@ int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu) kvm_timer_update_irq(vcpu, false, vcpu_ptimer(vcpu)); if (irqchip_in_kernel(vcpu->kvm) && map.direct_ptimer) - kvm_vgic_reset_mapped_irq(vcpu, timer_irq(map.direct_ptimer)); + kvm_irqchip_reset_mapped_irq(vcpu, timer_irq(map.direct_ptimer)); goto skip_reset_vtimer; } @@ -1200,9 +1200,9 @@ int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu) vcpu_get_timer(vcpu, i)); if (irqchip_in_kernel(vcpu->kvm)) { - kvm_vgic_reset_mapped_irq(vcpu, timer_irq(map.direct_vtimer)); + kvm_irqchip_reset_mapped_irq(vcpu, timer_irq(map.direct_vtimer)); if (map.direct_ptimer) - kvm_vgic_reset_mapped_irq(vcpu, timer_irq(map.direct_ptimer)); + kvm_irqchip_reset_mapped_irq(vcpu, timer_irq(map.direct_ptimer)); } } @@ -1901,10 +1901,10 @@ int kvm_timer_enable(struct kvm_vcpu *vcpu) if (vtimer_is_irqbypass()) goto skip_map_vtimer; #endif - ret = kvm_vgic_map_phys_irq(vcpu, - map.direct_vtimer->host_timer_irq, - timer_irq(map.direct_vtimer), - &arch_timer_irq_ops); + ret = kvm_irqchip_map_phys_irq(vcpu, + map.direct_vtimer->host_timer_irq, + timer_irq(map.direct_vtimer), + &arch_timer_irq_ops); if (ret) return ret; @@ -1912,10 +1912,10 @@ int kvm_timer_enable(struct kvm_vcpu *vcpu) skip_map_vtimer: #endif if (map.direct_ptimer) { - ret = kvm_vgic_map_phys_irq(vcpu, - map.direct_ptimer->host_timer_irq, - timer_irq(map.direct_ptimer), - &arch_timer_irq_ops); + ret = kvm_irqchip_map_phys_irq(vcpu, + map.direct_ptimer->host_timer_irq, + timer_irq(map.direct_ptimer), + &arch_timer_irq_ops); } if (ret) diff --git a/arch/arm64/kvm/vgic/vgic-init.c b/arch/arm64/kvm/vgic/vgic-init.c index 71fb7b6b1a1b..e2667f8c5002 100644 --- a/arch/arm64/kvm/vgic/vgic-init.c +++ b/arch/arm64/kvm/vgic/vgic-init.c @@ -37,6 +37,10 @@ static struct kvm_irqchip_flow vgic_irqchip_flow = { .irqchip_vcpu_sync_hwstate = kvm_vgic_sync_hwstate, .irqchip_inject_irq = kvm_vgic_inject_irq, .irqchip_inject_userspace_irq = kvm_vgic_inject_userspace_irq, + .irqchip_map_is_active = kvm_vgic_map_is_active, + .irqchip_reset_mapped_irq = kvm_vgic_reset_mapped_irq, + .irqchip_map_phys_irq = kvm_vgic_map_phys_irq, + .irqchip_unmap_phys_irq = kvm_vgic_unmap_phys_irq, }; /* diff --git a/arch/arm64/kvm/vgic/vgic.h b/arch/arm64/kvm/vgic/vgic.h index ec149e8dd59b..612d161dc409 100644 --- a/arch/arm64/kvm/vgic/vgic.h +++ b/arch/arm64/kvm/vgic/vgic.h @@ -377,6 +377,14 @@ static inline bool kvm_has_gicv3(struct kvm *kvm) irqchip_is_gic_v3(kvm)); } +bool kvm_vgic_map_is_active(struct kvm_vcpu *vcpu, unsigned int vintid); +void kvm_vgic_reset_mapped_irq(struct kvm_vcpu *vcpu, u32 vintid); + +int kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu, unsigned int host_irq, + u32 vintid, struct irq_ops *ops); +int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, unsigned int vintid); + + int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu); void kvm_vgic_load(struct kvm_vcpu *vcpu); diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h index 53a0c3d20fc6..9bd83bc8e1aa 100644 --- a/include/kvm/arm_vgic.h +++ b/include/kvm/arm_vgic.h @@ -446,18 +446,12 @@ int kvm_vgic_create(struct kvm *kvm, u32 type); int kvm_vgic_hyp_init(void); void kvm_vgic_init_cpu_hardware(void); -int kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu, unsigned int host_irq, - u32 vintid, struct irq_ops *ops); -int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, unsigned int vintid); int kvm_vgic_get_map(struct kvm_vcpu *vcpu, unsigned int vintid); -bool kvm_vgic_map_is_active(struct kvm_vcpu *vcpu, unsigned int vintid); #define vgic_initialized(k) ((k)->arch.vgic.initialized) #define vgic_valid_spi(k, i) (((i) >= VGIC_NR_PRIVATE_IRQS) && \ ((i) < (k)->arch.vgic.nr_spis + VGIC_NR_PRIVATE_IRQS)) -void kvm_vgic_reset_mapped_irq(struct kvm_vcpu *vcpu, u32 vintid); - void vgic_v3_dispatch_sgi(struct kvm_vcpu *vcpu, u64 reg, bool allow_group1); #ifdef CONFIG_VIRT_VTIMER_IRQ_BYPASS -- 2.33.0