From: wanghaibin <wanghaibin.wang@huawei.com> The "first run" part of the vgic init is pretty cumbersome, as it leaks all over the place. Reduce its footprint by moving it to an actual per-vcpu "first run" callback, and let it deal with the resource mapping. This allows the vgic_ready() macro to be made vgic-private, and placed in the common vgic code instead of the architecture backends. Signed-off-by: Marc Zyngier <maz@kernel.org> Signed-off-by: wanghaibin <wanghaibin.wang@huawei.com> --- arch/arm64/include/asm/kvm_irq.h | 4 ++++ arch/arm64/kvm/arm.c | 6 +----- arch/arm64/kvm/vgic/vgic-init.c | 12 ++++++------ arch/arm64/kvm/vgic/vgic.h | 2 ++ include/kvm/arm_vgic.h | 2 -- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/arch/arm64/include/asm/kvm_irq.h b/arch/arm64/include/asm/kvm_irq.h index 00debef7c2ed..460e32d89d0f 100644 --- a/arch/arm64/include/asm/kvm_irq.h +++ b/arch/arm64/include/asm/kvm_irq.h @@ -26,6 +26,7 @@ struct kvm_irqchip_flow { void (*irqchip_vcpu_load)(struct kvm_vcpu *); void (*irqchip_vcpu_put)(struct kvm_vcpu *); int (*irqchip_vcpu_pending_irq)(struct kvm_vcpu *); + int (*irqchip_vcpu_first_run)(struct kvm_vcpu *); }; /* @@ -79,4 +80,7 @@ struct kvm_irqchip_flow { #define kvm_irqchip_vcpu_pending_irq(v) \ __vcpu_irqchip_action_ret((v), vcpu_pending_irq, (v)) +#define kvm_irqchip_vcpu_first_run(v) \ + __vcpu_irqchip_action_ret((v), vcpu_first_run, (v)) + #endif diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index 89c5c3b9403c..cfd0c5034c04 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -916,11 +916,7 @@ int kvm_arch_vcpu_run_pid_change(struct kvm_vcpu *vcpu) #endif if (likely(irqchip_in_kernel(kvm))) { - /* - * Map the VGIC hardware resources before running a vcpu the - * first time on this VM. - */ - ret = kvm_vgic_map_resources(kvm); + ret = kvm_irqchip_vcpu_first_run(vcpu); if (ret) return ret; } diff --git a/arch/arm64/kvm/vgic/vgic-init.c b/arch/arm64/kvm/vgic/vgic-init.c index d63989cca594..a58855f485ae 100644 --- a/arch/arm64/kvm/vgic/vgic-init.c +++ b/arch/arm64/kvm/vgic/vgic-init.c @@ -18,6 +18,7 @@ #include "hisilicon/hisi_virt.h" #endif +static int kvm_vgic_vcpu_first_run(struct kvm_vcpu *vcpu); static int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu); static void kvm_vgic_destroy(struct kvm *kvm); static void kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu); @@ -31,6 +32,7 @@ static struct kvm_irqchip_flow vgic_irqchip_flow = { .irqchip_vcpu_load = kvm_vgic_load, .irqchip_vcpu_put = kvm_vgic_put, .irqchip_vcpu_pending_irq = kvm_vgic_vcpu_pending_irq, + .irqchip_vcpu_first_run = kvm_vgic_vcpu_first_run, }; /* @@ -527,10 +529,11 @@ int vgic_lazy_init(struct kvm *kvm) * v2 calls vgic_init() if not already done. * v3 and derivatives return an error if the VGIC is not initialized. * vgic_ready() returns true if this function has succeeded. - * @kvm: kvm struct pointer - */ -int kvm_vgic_map_resources(struct kvm *kvm) + * @vcpu: vcpu struct pointer +*/ +static int kvm_vgic_vcpu_first_run(struct kvm_vcpu *vcpu) { + struct kvm *kvm = vcpu->kvm; struct vgic_dist *dist = &kvm->arch.vgic; enum vgic_type type; gpa_t dist_base; @@ -544,9 +547,6 @@ int kvm_vgic_map_resources(struct kvm *kvm) if (vgic_ready(kvm)) goto out; - if (!irqchip_in_kernel(kvm)) - goto out; - if (irqchip_is_gic_v2(kvm)) { ret = vgic_v2_map_resources(kvm); type = VGIC_V2; diff --git a/arch/arm64/kvm/vgic/vgic.h b/arch/arm64/kvm/vgic/vgic.h index 6858d233c05c..3f2b8236ebcd 100644 --- a/arch/arm64/kvm/vgic/vgic.h +++ b/arch/arm64/kvm/vgic/vgic.h @@ -104,6 +104,8 @@ static inline u32 vgic_get_implementation_rev(struct kvm_vcpu *vcpu) return vcpu->kvm->arch.vgic.implementation_rev; } +#define vgic_ready(k) ((k)->arch.vgic.ready) + /* Requires the irq_lock to be held by the caller. */ static inline bool irq_is_pending(struct vgic_irq *irq) { diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h index 9c2573e3d35f..b260f4064aab 100644 --- a/include/kvm/arm_vgic.h +++ b/include/kvm/arm_vgic.h @@ -443,7 +443,6 @@ extern struct static_key_false vgic_v3_cpuif_trap; int kvm_set_legacy_vgic_v2_addr(struct kvm *kvm, struct kvm_arm_device_addr *dev_addr); int kvm_vgic_create(struct kvm *kvm, u32 type); -int kvm_vgic_map_resources(struct kvm *kvm); int kvm_vgic_hyp_init(void); void kvm_vgic_init_cpu_hardware(void); @@ -456,7 +455,6 @@ 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_ready(k) ((k)->arch.vgic.ready) #define vgic_valid_spi(k, i) (((i) >= VGIC_NR_PRIVATE_IRQS) && \ ((i) < (k)->arch.vgic.nr_spis + VGIC_NR_PRIVATE_IRQS)) -- 2.33.0