KVM: switch irq injection/acking data structures to irq_lock
[pandora-kernel.git] / arch / x86 / kvm / x86.c
index a93ba37..05cbe83 100644 (file)
@@ -246,6 +246,10 @@ int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3)
        ret = 1;
 
        memcpy(vcpu->arch.pdptrs, pdpte, sizeof(vcpu->arch.pdptrs));
+       __set_bit(VCPU_EXREG_PDPTR,
+                 (unsigned long *)&vcpu->arch.regs_avail);
+       __set_bit(VCPU_EXREG_PDPTR,
+                 (unsigned long *)&vcpu->arch.regs_dirty);
 out:
 
        return ret;
@@ -261,6 +265,10 @@ static bool pdptrs_changed(struct kvm_vcpu *vcpu)
        if (is_long_mode(vcpu) || !is_pae(vcpu))
                return false;
 
+       if (!test_bit(VCPU_EXREG_PDPTR,
+                     (unsigned long *)&vcpu->arch.regs_avail))
+               return true;
+
        r = kvm_read_guest(vcpu->kvm, vcpu->arch.cr3 & ~31u, pdpte, sizeof(pdpte));
        if (r < 0)
                goto out;
@@ -1126,6 +1134,8 @@ int kvm_dev_ioctl_check_extension(long ext)
        case KVM_CAP_REINJECT_CONTROL:
        case KVM_CAP_IRQ_INJECT_STATUS:
        case KVM_CAP_ASSIGN_DEV_IRQ:
+       case KVM_CAP_IRQFD:
+       case KVM_CAP_PIT2:
                r = 1;
                break;
        case KVM_CAP_COALESCED_MMIO:
@@ -1506,6 +1516,10 @@ static int kvm_dev_ioctl_get_supported_cpuid(struct kvm_cpuid2 *cpuid,
        for (func = 0x80000001; func <= limit && nent < cpuid->nent; ++func)
                do_cpuid_ent(&cpuid_entries[nent], func, 0,
                             &nent, cpuid->nent);
+       r = -E2BIG;
+       if (nent >= cpuid->nent)
+               goto out_free;
+
        r = -EFAULT;
        if (copy_to_user(entries, cpuid_entries,
                         nent * sizeof(struct kvm_cpuid_entry2)))
@@ -2033,6 +2047,7 @@ long kvm_arch_vm_ioctl(struct file *filp,
        union {
                struct kvm_pit_state ps;
                struct kvm_memory_alias alias;
+               struct kvm_pit_config pit_config;
        } u;
 
        switch (ioctl) {
@@ -2093,12 +2108,20 @@ long kvm_arch_vm_ioctl(struct file *filp,
                }
                break;
        case KVM_CREATE_PIT:
+               u.pit_config.flags = KVM_PIT_SPEAKER_DUMMY;
+               goto create_pit;
+       case KVM_CREATE_PIT2:
+               r = -EFAULT;
+               if (copy_from_user(&u.pit_config, argp,
+                                  sizeof(struct kvm_pit_config)))
+                       goto out;
+       create_pit:
                mutex_lock(&kvm->lock);
                r = -EEXIST;
                if (kvm->arch.vpit)
                        goto create_pit_unlock;
                r = -ENOMEM;
-               kvm->arch.vpit = kvm_create_pit(kvm);
+               kvm->arch.vpit = kvm_create_pit(kvm, u.pit_config.flags);
                if (kvm->arch.vpit)
                        r = 0;
        create_pit_unlock:
@@ -2113,10 +2136,10 @@ long kvm_arch_vm_ioctl(struct file *filp,
                        goto out;
                if (irqchip_in_kernel(kvm)) {
                        __s32 status;
-                       mutex_lock(&kvm->lock);
+                       mutex_lock(&kvm->irq_lock);
                        status = kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID,
                                        irq_event.irq, irq_event.level);
-                       mutex_unlock(&kvm->lock);
+                       mutex_unlock(&kvm->irq_lock);
                        if (ioctl == KVM_IRQ_LINE_STATUS) {
                                irq_event.status = status;
                                if (copy_to_user(argp, &irq_event,
@@ -2249,7 +2272,7 @@ static struct kvm_io_device *vcpu_find_pervcpu_dev(struct kvm_vcpu *vcpu,
 
        if (vcpu->arch.apic) {
                dev = &vcpu->arch.apic->dev;
-               if (dev->in_range(dev, addr, len, is_write))
+               if (kvm_iodevice_in_range(dev, addr, len, is_write))
                        return dev;
        }
        return NULL;
@@ -2362,12 +2385,11 @@ mmio:
         */
        mutex_lock(&vcpu->kvm->lock);
        mmio_dev = vcpu_find_mmio_dev(vcpu, gpa, bytes, 0);
+       mutex_unlock(&vcpu->kvm->lock);
        if (mmio_dev) {
                kvm_iodevice_read(mmio_dev, gpa, bytes, val);
-               mutex_unlock(&vcpu->kvm->lock);
                return X86EMUL_CONTINUE;
        }
-       mutex_unlock(&vcpu->kvm->lock);
 
        vcpu->mmio_needed = 1;
        vcpu->mmio_phys_addr = gpa;
@@ -2417,12 +2439,11 @@ mmio:
         */
        mutex_lock(&vcpu->kvm->lock);
        mmio_dev = vcpu_find_mmio_dev(vcpu, gpa, bytes, 1);
+       mutex_unlock(&vcpu->kvm->lock);
        if (mmio_dev) {
                kvm_iodevice_write(mmio_dev, gpa, bytes, val);
-               mutex_unlock(&vcpu->kvm->lock);
                return X86EMUL_CONTINUE;
        }
-       mutex_unlock(&vcpu->kvm->lock);
 
        vcpu->mmio_needed = 1;
        vcpu->mmio_phys_addr = gpa;
@@ -2745,7 +2766,6 @@ static void kernel_pio(struct kvm_io_device *pio_dev,
 {
        /* TODO: String I/O for in kernel device */
 
-       mutex_lock(&vcpu->kvm->lock);
        if (vcpu->arch.pio.in)
                kvm_iodevice_read(pio_dev, vcpu->arch.pio.port,
                                  vcpu->arch.pio.size,
@@ -2754,7 +2774,6 @@ static void kernel_pio(struct kvm_io_device *pio_dev,
                kvm_iodevice_write(pio_dev, vcpu->arch.pio.port,
                                   vcpu->arch.pio.size,
                                   pd);
-       mutex_unlock(&vcpu->kvm->lock);
 }
 
 static void pio_string_write(struct kvm_io_device *pio_dev,
@@ -2764,14 +2783,12 @@ static void pio_string_write(struct kvm_io_device *pio_dev,
        void *pd = vcpu->arch.pio_data;
        int i;
 
-       mutex_lock(&vcpu->kvm->lock);
        for (i = 0; i < io->cur_count; i++) {
                kvm_iodevice_write(pio_dev, io->port,
                                   io->size,
                                   pd);
                pd += io->size;
        }
-       mutex_unlock(&vcpu->kvm->lock);
 }
 
 static struct kvm_io_device *vcpu_find_pio_dev(struct kvm_vcpu *vcpu,
@@ -2808,7 +2825,9 @@ int kvm_emulate_pio(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
        val = kvm_register_read(vcpu, VCPU_REGS_RAX);
        memcpy(vcpu->arch.pio_data, &val, 4);
 
+       mutex_lock(&vcpu->kvm->lock);
        pio_dev = vcpu_find_pio_dev(vcpu, port, size, !in);
+       mutex_unlock(&vcpu->kvm->lock);
        if (pio_dev) {
                kernel_pio(pio_dev, vcpu, vcpu->arch.pio_data);
                complete_pio(vcpu);
@@ -2872,9 +2891,12 @@ int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
 
        vcpu->arch.pio.guest_gva = address;
 
+       mutex_lock(&vcpu->kvm->lock);
        pio_dev = vcpu_find_pio_dev(vcpu, port,
                                    vcpu->arch.pio.cur_count,
                                    !vcpu->arch.pio.in);
+       mutex_unlock(&vcpu->kvm->lock);
+
        if (!vcpu->arch.pio.in) {
                /* string PIO write */
                ret = pio_copy_data(vcpu);
@@ -3357,9 +3379,6 @@ static void update_cr8_intercept(struct kvm_vcpu *vcpu)
 
 static void inject_pending_irq(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 {
-       if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP)
-               kvm_x86_ops->set_interrupt_shadow(vcpu, 0);
-
        /* try to reinject previous events if any */
        if (vcpu->arch.nmi_injected) {
                kvm_x86_ops->set_nmi(vcpu);