From: Christoffer Dall Date: Fri, 19 Sep 2014 01:15:32 +0000 (-0700) Subject: Merge remote-tracking branch 'kvm/next' into queue X-Git-Tag: v3.18-rc1~13^2~29 X-Git-Url: http://git.cascardo.info/?a=commitdiff_plain;h=a875dafcf9b6b266c855e1f9b0aa060ef585d38a;p=cascardo%2Flinux.git Merge remote-tracking branch 'kvm/next' into queue Conflicts: arch/arm64/include/asm/kvm_host.h virt/kvm/arm/vgic.c --- a875dafcf9b6b266c855e1f9b0aa060ef585d38a diff --cc arch/arm/include/asm/kvm_host.h index fcb12a6f7db5,032a8538318a..46e5d4da1989 --- a/arch/arm/include/asm/kvm_host.h +++ b/arch/arm/include/asm/kvm_host.h @@@ -40,9 -42,8 +42,8 @@@ #include - struct kvm_vcpu; u32 *kvm_vcpu_reg(struct kvm_vcpu *vcpu, u8 reg_num, u32 mode); -int kvm_target_cpu(void); +int __attribute_const__ kvm_target_cpu(void); int kvm_reset_vcpu(struct kvm_vcpu *vcpu); void kvm_reset_coprocs(struct kvm_vcpu *vcpu); diff --cc arch/arm64/include/asm/kvm_host.h index 50431d36732b,be9970a59497..bcde41905746 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@@ -41,8 -43,7 +43,7 @@@ #define KVM_VCPU_MAX_FEATURES 3 - struct kvm_vcpu; -int kvm_target_cpu(void); +int __attribute_const__ kvm_target_cpu(void); int kvm_reset_vcpu(struct kvm_vcpu *vcpu); int kvm_arch_dev_ioctl_check_extension(long ext); diff --cc virt/kvm/arm/vgic.c index efe6eee2e7eb,3ee3ce06bbec..eeb23b37f87c --- a/virt/kvm/arm/vgic.c +++ b/virt/kvm/arm/vgic.c @@@ -2070,3 -1993,81 +1993,81 @@@ static struct kvm_device_ops kvm_arm_vg .get_attr = vgic_get_attr, .has_attr = vgic_has_attr, }; + + static void vgic_init_maintenance_interrupt(void *info) + { + enable_percpu_irq(vgic->maint_irq, 0); + } + + static int vgic_cpu_notify(struct notifier_block *self, + unsigned long action, void *cpu) + { + switch (action) { + case CPU_STARTING: + case CPU_STARTING_FROZEN: + vgic_init_maintenance_interrupt(NULL); + break; + case CPU_DYING: + case CPU_DYING_FROZEN: + disable_percpu_irq(vgic->maint_irq); + break; + } + + return NOTIFY_OK; + } + + static struct notifier_block vgic_cpu_nb = { + .notifier_call = vgic_cpu_notify, + }; + + static const struct of_device_id vgic_ids[] = { + { .compatible = "arm,cortex-a15-gic", .data = vgic_v2_probe, }, + { .compatible = "arm,gic-v3", .data = vgic_v3_probe, }, + {}, + }; + + int kvm_vgic_hyp_init(void) + { + const struct of_device_id *matched_id; - int (*vgic_probe)(struct device_node *,const struct vgic_ops **, - const struct vgic_params **); ++ const int (*vgic_probe)(struct device_node *,const struct vgic_ops **, ++ const struct vgic_params **); + struct device_node *vgic_node; + int ret; + + vgic_node = of_find_matching_node_and_match(NULL, + vgic_ids, &matched_id); + if (!vgic_node) { + kvm_err("error: no compatible GIC node found\n"); + return -ENODEV; + } + + vgic_probe = matched_id->data; + ret = vgic_probe(vgic_node, &vgic_ops, &vgic); + if (ret) + return ret; + + ret = request_percpu_irq(vgic->maint_irq, vgic_maintenance_handler, + "vgic", kvm_get_running_vcpus()); + if (ret) { + kvm_err("Cannot register interrupt %d\n", vgic->maint_irq); + return ret; + } + + ret = __register_cpu_notifier(&vgic_cpu_nb); + if (ret) { + kvm_err("Cannot register vgic CPU notifier\n"); + goto out_free_irq; + } + + /* Callback into for arch code for setup */ + vgic_arch_setup(vgic); + + on_each_cpu(vgic_init_maintenance_interrupt, NULL, 1); + + return kvm_register_device_ops(&kvm_arm_vgic_v2_ops, + KVM_DEV_TYPE_ARM_VGIC_V2); + + out_free_irq: + free_percpu_irq(vgic->maint_irq, kvm_get_running_vcpus()); + return ret; + }