]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blobdiff - arch/arm/kvm/arm.c
Merge tag 'kvm-arm-for-3.14' of git://git.linaro.org/people/christoffer.dall/linux...
[mirror_ubuntu-artful-kernel.git] / arch / arm / kvm / arm.c
index 2a700e00528d0a3cc9d78a58f7d38dddf2297611..2d4b4a8068c82ca843d69c6a07b712cbb8d21226 100644 (file)
@@ -137,6 +137,8 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
        if (ret)
                goto out_free_stage2_pgd;
 
+       kvm_timer_init(kvm);
+
        /* Mark the initial VMID generation invalid */
        kvm->arch.vmid_gen = 0;
 
@@ -188,6 +190,7 @@ int kvm_dev_ioctl_check_extension(long ext)
        case KVM_CAP_IRQCHIP:
                r = vgic_present;
                break;
+       case KVM_CAP_DEVICE_CTRL:
        case KVM_CAP_USER_MEMORY:
        case KVM_CAP_SYNC_MMU:
        case KVM_CAP_DESTROY_MEMORY_REGION_WORKS:
@@ -339,6 +342,13 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 
 void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
 {
+       /*
+        * The arch-generic KVM code expects the cpu field of a vcpu to be -1
+        * if the vcpu is no longer assigned to a cpu.  This is used for the
+        * optimized make_all_cpus_request path.
+        */
+       vcpu->cpu = -1;
+
        kvm_arm_set_running_vcpu(NULL);
 }
 
@@ -462,6 +472,8 @@ static void update_vttbr(struct kvm *kvm)
 
 static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu)
 {
+       int ret;
+
        if (likely(vcpu->arch.has_run_once))
                return 0;
 
@@ -471,22 +483,12 @@ static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu)
         * Initialize the VGIC before running a vcpu the first time on
         * this VM.
         */
-       if (irqchip_in_kernel(vcpu->kvm) &&
-           unlikely(!vgic_initialized(vcpu->kvm))) {
-               int ret = kvm_vgic_init(vcpu->kvm);
+       if (unlikely(!vgic_initialized(vcpu->kvm))) {
+               ret = kvm_vgic_init(vcpu->kvm);
                if (ret)
                        return ret;
        }
 
-       /*
-        * Handle the "start in power-off" case by calling into the
-        * PSCI code.
-        */
-       if (test_and_clear_bit(KVM_ARM_VCPU_POWER_OFF, vcpu->arch.features)) {
-               *vcpu_reg(vcpu, 0) = KVM_PSCI_FN_CPU_OFF;
-               kvm_psci_call(vcpu);
-       }
-
        return 0;
 }
 
@@ -700,6 +702,24 @@ int kvm_vm_ioctl_irq_line(struct kvm *kvm, struct kvm_irq_level *irq_level,
        return -EINVAL;
 }
 
+static int kvm_arch_vcpu_ioctl_vcpu_init(struct kvm_vcpu *vcpu,
+                                        struct kvm_vcpu_init *init)
+{
+       int ret;
+
+       ret = kvm_vcpu_set_target(vcpu, init);
+       if (ret)
+               return ret;
+
+       /*
+        * Handle the "start in power-off" case by marking the VCPU as paused.
+        */
+       if (__test_and_clear_bit(KVM_ARM_VCPU_POWER_OFF, vcpu->arch.features))
+               vcpu->arch.pause = true;
+
+       return 0;
+}
+
 long kvm_arch_vcpu_ioctl(struct file *filp,
                         unsigned int ioctl, unsigned long arg)
 {
@@ -713,8 +733,7 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
                if (copy_from_user(&init, argp, sizeof(init)))
                        return -EFAULT;
 
-               return kvm_vcpu_set_target(vcpu, &init);
-
+               return kvm_arch_vcpu_ioctl_vcpu_init(vcpu, &init);
        }
        case KVM_SET_ONE_REG:
        case KVM_GET_ONE_REG: {
@@ -772,7 +791,7 @@ static int kvm_vm_ioctl_set_device_addr(struct kvm *kvm,
        case KVM_ARM_DEVICE_VGIC_V2:
                if (!vgic_present)
                        return -ENXIO;
-               return kvm_vgic_set_addr(kvm, type, dev_addr->addr);
+               return kvm_vgic_addr(kvm, type, &dev_addr->addr, true);
        default:
                return -ENODEV;
        }