Merge tag 'iwlwifi-next-for-kalle-2014-12-30' of https://git.kernel.org/pub/scm/linux...
[cascardo/linux.git] / arch / arm / kvm / arm.c
index c5a05f2..2d6d910 100644 (file)
@@ -213,6 +213,11 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, unsigned int id)
        int err;
        struct kvm_vcpu *vcpu;
 
+       if (irqchip_in_kernel(kvm) && vgic_initialized(kvm)) {
+               err = -EBUSY;
+               goto out;
+       }
+
        vcpu = kmem_cache_zalloc(kvm_vcpu_cache, GFP_KERNEL);
        if (!vcpu) {
                err = -ENOMEM;
@@ -420,6 +425,7 @@ static void update_vttbr(struct kvm *kvm)
 
 static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu)
 {
+       struct kvm *kvm = vcpu->kvm;
        int ret;
 
        if (likely(vcpu->arch.has_run_once))
@@ -431,12 +437,20 @@ static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu)
         * Map the VGIC hardware resources before running a vcpu the first
         * time on this VM.
         */
-       if (unlikely(!vgic_ready(vcpu->kvm))) {
-               ret = kvm_vgic_map_resources(vcpu->kvm);
+       if (unlikely(!vgic_ready(kvm))) {
+               ret = kvm_vgic_map_resources(kvm);
                if (ret)
                        return ret;
        }
 
+       /*
+        * Enable the arch timers only if we have an in-kernel VGIC
+        * and it has been properly initialized, since we cannot handle
+        * interrupts from the virtual timer with a userspace gic.
+        */
+       if (irqchip_in_kernel(kvm) && vgic_initialized(kvm))
+               kvm_timer_enable(kvm);
+
        return 0;
 }