Commit 526b78ad authored by Avi Kivity's avatar Avi Kivity

KVM: x86: Lock arch specific vcpu ioctls centrally

Signed-off-by: default avatarAvi Kivity <avi@redhat.com>
parent 2122ff5e
...@@ -1541,16 +1541,12 @@ static int __msr_io(struct kvm_vcpu *vcpu, struct kvm_msrs *msrs, ...@@ -1541,16 +1541,12 @@ static int __msr_io(struct kvm_vcpu *vcpu, struct kvm_msrs *msrs,
{ {
int i, idx; int i, idx;
vcpu_load(vcpu);
idx = srcu_read_lock(&vcpu->kvm->srcu); idx = srcu_read_lock(&vcpu->kvm->srcu);
for (i = 0; i < msrs->nmsrs; ++i) for (i = 0; i < msrs->nmsrs; ++i)
if (do_msr(vcpu, entries[i].index, &entries[i].data)) if (do_msr(vcpu, entries[i].index, &entries[i].data))
break; break;
srcu_read_unlock(&vcpu->kvm->srcu, idx); srcu_read_unlock(&vcpu->kvm->srcu, idx);
vcpu_put(vcpu);
return i; return i;
} }
...@@ -1798,7 +1794,6 @@ static int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu, ...@@ -1798,7 +1794,6 @@ static int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu,
if (copy_from_user(cpuid_entries, entries, if (copy_from_user(cpuid_entries, entries,
cpuid->nent * sizeof(struct kvm_cpuid_entry))) cpuid->nent * sizeof(struct kvm_cpuid_entry)))
goto out_free; goto out_free;
vcpu_load(vcpu);
for (i = 0; i < cpuid->nent; i++) { for (i = 0; i < cpuid->nent; i++) {
vcpu->arch.cpuid_entries[i].function = cpuid_entries[i].function; vcpu->arch.cpuid_entries[i].function = cpuid_entries[i].function;
vcpu->arch.cpuid_entries[i].eax = cpuid_entries[i].eax; vcpu->arch.cpuid_entries[i].eax = cpuid_entries[i].eax;
...@@ -1816,7 +1811,6 @@ static int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu, ...@@ -1816,7 +1811,6 @@ static int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu,
r = 0; r = 0;
kvm_apic_set_version(vcpu); kvm_apic_set_version(vcpu);
kvm_x86_ops->cpuid_update(vcpu); kvm_x86_ops->cpuid_update(vcpu);
vcpu_put(vcpu);
out_free: out_free:
vfree(cpuid_entries); vfree(cpuid_entries);
...@@ -1837,11 +1831,9 @@ static int kvm_vcpu_ioctl_set_cpuid2(struct kvm_vcpu *vcpu, ...@@ -1837,11 +1831,9 @@ static int kvm_vcpu_ioctl_set_cpuid2(struct kvm_vcpu *vcpu,
if (copy_from_user(&vcpu->arch.cpuid_entries, entries, if (copy_from_user(&vcpu->arch.cpuid_entries, entries,
cpuid->nent * sizeof(struct kvm_cpuid_entry2))) cpuid->nent * sizeof(struct kvm_cpuid_entry2)))
goto out; goto out;
vcpu_load(vcpu);
vcpu->arch.cpuid_nent = cpuid->nent; vcpu->arch.cpuid_nent = cpuid->nent;
kvm_apic_set_version(vcpu); kvm_apic_set_version(vcpu);
kvm_x86_ops->cpuid_update(vcpu); kvm_x86_ops->cpuid_update(vcpu);
vcpu_put(vcpu);
return 0; return 0;
out: out:
...@@ -1854,7 +1846,6 @@ static int kvm_vcpu_ioctl_get_cpuid2(struct kvm_vcpu *vcpu, ...@@ -1854,7 +1846,6 @@ static int kvm_vcpu_ioctl_get_cpuid2(struct kvm_vcpu *vcpu,
{ {
int r; int r;
vcpu_load(vcpu);
r = -E2BIG; r = -E2BIG;
if (cpuid->nent < vcpu->arch.cpuid_nent) if (cpuid->nent < vcpu->arch.cpuid_nent)
goto out; goto out;
...@@ -1866,7 +1857,6 @@ static int kvm_vcpu_ioctl_get_cpuid2(struct kvm_vcpu *vcpu, ...@@ -1866,7 +1857,6 @@ static int kvm_vcpu_ioctl_get_cpuid2(struct kvm_vcpu *vcpu,
out: out:
cpuid->nent = vcpu->arch.cpuid_nent; cpuid->nent = vcpu->arch.cpuid_nent;
vcpu_put(vcpu);
return r; return r;
} }
...@@ -2098,9 +2088,7 @@ static int kvm_dev_ioctl_get_supported_cpuid(struct kvm_cpuid2 *cpuid, ...@@ -2098,9 +2088,7 @@ static int kvm_dev_ioctl_get_supported_cpuid(struct kvm_cpuid2 *cpuid,
static int kvm_vcpu_ioctl_get_lapic(struct kvm_vcpu *vcpu, static int kvm_vcpu_ioctl_get_lapic(struct kvm_vcpu *vcpu,
struct kvm_lapic_state *s) struct kvm_lapic_state *s)
{ {
vcpu_load(vcpu);
memcpy(s->regs, vcpu->arch.apic->regs, sizeof *s); memcpy(s->regs, vcpu->arch.apic->regs, sizeof *s);
vcpu_put(vcpu);
return 0; return 0;
} }
...@@ -2108,11 +2096,9 @@ static int kvm_vcpu_ioctl_get_lapic(struct kvm_vcpu *vcpu, ...@@ -2108,11 +2096,9 @@ static int kvm_vcpu_ioctl_get_lapic(struct kvm_vcpu *vcpu,
static int kvm_vcpu_ioctl_set_lapic(struct kvm_vcpu *vcpu, static int kvm_vcpu_ioctl_set_lapic(struct kvm_vcpu *vcpu,
struct kvm_lapic_state *s) struct kvm_lapic_state *s)
{ {
vcpu_load(vcpu);
memcpy(vcpu->arch.apic->regs, s->regs, sizeof *s); memcpy(vcpu->arch.apic->regs, s->regs, sizeof *s);
kvm_apic_post_state_restore(vcpu); kvm_apic_post_state_restore(vcpu);
update_cr8_intercept(vcpu); update_cr8_intercept(vcpu);
vcpu_put(vcpu);
return 0; return 0;
} }
...@@ -2124,20 +2110,15 @@ static int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, ...@@ -2124,20 +2110,15 @@ static int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu,
return -EINVAL; return -EINVAL;
if (irqchip_in_kernel(vcpu->kvm)) if (irqchip_in_kernel(vcpu->kvm))
return -ENXIO; return -ENXIO;
vcpu_load(vcpu);
kvm_queue_interrupt(vcpu, irq->irq, false); kvm_queue_interrupt(vcpu, irq->irq, false);
vcpu_put(vcpu);
return 0; return 0;
} }
static int kvm_vcpu_ioctl_nmi(struct kvm_vcpu *vcpu) static int kvm_vcpu_ioctl_nmi(struct kvm_vcpu *vcpu)
{ {
vcpu_load(vcpu);
kvm_inject_nmi(vcpu); kvm_inject_nmi(vcpu);
vcpu_put(vcpu);
return 0; return 0;
} }
...@@ -2157,7 +2138,6 @@ static int kvm_vcpu_ioctl_x86_setup_mce(struct kvm_vcpu *vcpu, ...@@ -2157,7 +2138,6 @@ static int kvm_vcpu_ioctl_x86_setup_mce(struct kvm_vcpu *vcpu,
int r; int r;
unsigned bank_num = mcg_cap & 0xff, bank; unsigned bank_num = mcg_cap & 0xff, bank;
vcpu_load(vcpu);
r = -EINVAL; r = -EINVAL;
if (!bank_num || bank_num >= KVM_MAX_MCE_BANKS) if (!bank_num || bank_num >= KVM_MAX_MCE_BANKS)
goto out; goto out;
...@@ -2172,7 +2152,6 @@ static int kvm_vcpu_ioctl_x86_setup_mce(struct kvm_vcpu *vcpu, ...@@ -2172,7 +2152,6 @@ static int kvm_vcpu_ioctl_x86_setup_mce(struct kvm_vcpu *vcpu,
for (bank = 0; bank < bank_num; bank++) for (bank = 0; bank < bank_num; bank++)
vcpu->arch.mce_banks[bank*4] = ~(u64)0; vcpu->arch.mce_banks[bank*4] = ~(u64)0;
out: out:
vcpu_put(vcpu);
return r; return r;
} }
...@@ -2230,8 +2209,6 @@ static int kvm_vcpu_ioctl_x86_set_mce(struct kvm_vcpu *vcpu, ...@@ -2230,8 +2209,6 @@ static int kvm_vcpu_ioctl_x86_set_mce(struct kvm_vcpu *vcpu,
static void kvm_vcpu_ioctl_x86_get_vcpu_events(struct kvm_vcpu *vcpu, static void kvm_vcpu_ioctl_x86_get_vcpu_events(struct kvm_vcpu *vcpu,
struct kvm_vcpu_events *events) struct kvm_vcpu_events *events)
{ {
vcpu_load(vcpu);
events->exception.injected = events->exception.injected =
vcpu->arch.exception.pending && vcpu->arch.exception.pending &&
!kvm_exception_is_soft(vcpu->arch.exception.nr); !kvm_exception_is_soft(vcpu->arch.exception.nr);
...@@ -2256,8 +2233,6 @@ static void kvm_vcpu_ioctl_x86_get_vcpu_events(struct kvm_vcpu *vcpu, ...@@ -2256,8 +2233,6 @@ static void kvm_vcpu_ioctl_x86_get_vcpu_events(struct kvm_vcpu *vcpu,
events->flags = (KVM_VCPUEVENT_VALID_NMI_PENDING events->flags = (KVM_VCPUEVENT_VALID_NMI_PENDING
| KVM_VCPUEVENT_VALID_SIPI_VECTOR | KVM_VCPUEVENT_VALID_SIPI_VECTOR
| KVM_VCPUEVENT_VALID_SHADOW); | KVM_VCPUEVENT_VALID_SHADOW);
vcpu_put(vcpu);
} }
static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu, static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu,
...@@ -2268,8 +2243,6 @@ static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu, ...@@ -2268,8 +2243,6 @@ static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu,
| KVM_VCPUEVENT_VALID_SHADOW)) | KVM_VCPUEVENT_VALID_SHADOW))
return -EINVAL; return -EINVAL;
vcpu_load(vcpu);
vcpu->arch.exception.pending = events->exception.injected; vcpu->arch.exception.pending = events->exception.injected;
vcpu->arch.exception.nr = events->exception.nr; vcpu->arch.exception.nr = events->exception.nr;
vcpu->arch.exception.has_error_code = events->exception.has_error_code; vcpu->arch.exception.has_error_code = events->exception.has_error_code;
...@@ -2292,22 +2265,16 @@ static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu, ...@@ -2292,22 +2265,16 @@ static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu,
if (events->flags & KVM_VCPUEVENT_VALID_SIPI_VECTOR) if (events->flags & KVM_VCPUEVENT_VALID_SIPI_VECTOR)
vcpu->arch.sipi_vector = events->sipi_vector; vcpu->arch.sipi_vector = events->sipi_vector;
vcpu_put(vcpu);
return 0; return 0;
} }
static void kvm_vcpu_ioctl_x86_get_debugregs(struct kvm_vcpu *vcpu, static void kvm_vcpu_ioctl_x86_get_debugregs(struct kvm_vcpu *vcpu,
struct kvm_debugregs *dbgregs) struct kvm_debugregs *dbgregs)
{ {
vcpu_load(vcpu);
memcpy(dbgregs->db, vcpu->arch.db, sizeof(vcpu->arch.db)); memcpy(dbgregs->db, vcpu->arch.db, sizeof(vcpu->arch.db));
dbgregs->dr6 = vcpu->arch.dr6; dbgregs->dr6 = vcpu->arch.dr6;
dbgregs->dr7 = vcpu->arch.dr7; dbgregs->dr7 = vcpu->arch.dr7;
dbgregs->flags = 0; dbgregs->flags = 0;
vcpu_put(vcpu);
} }
static int kvm_vcpu_ioctl_x86_set_debugregs(struct kvm_vcpu *vcpu, static int kvm_vcpu_ioctl_x86_set_debugregs(struct kvm_vcpu *vcpu,
...@@ -2316,14 +2283,10 @@ static int kvm_vcpu_ioctl_x86_set_debugregs(struct kvm_vcpu *vcpu, ...@@ -2316,14 +2283,10 @@ static int kvm_vcpu_ioctl_x86_set_debugregs(struct kvm_vcpu *vcpu,
if (dbgregs->flags) if (dbgregs->flags)
return -EINVAL; return -EINVAL;
vcpu_load(vcpu);
memcpy(vcpu->arch.db, dbgregs->db, sizeof(vcpu->arch.db)); memcpy(vcpu->arch.db, dbgregs->db, sizeof(vcpu->arch.db));
vcpu->arch.dr6 = dbgregs->dr6; vcpu->arch.dr6 = dbgregs->dr6;
vcpu->arch.dr7 = dbgregs->dr7; vcpu->arch.dr7 = dbgregs->dr7;
vcpu_put(vcpu);
return 0; return 0;
} }
...@@ -2335,6 +2298,7 @@ long kvm_arch_vcpu_ioctl(struct file *filp, ...@@ -2335,6 +2298,7 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
int r; int r;
struct kvm_lapic_state *lapic = NULL; struct kvm_lapic_state *lapic = NULL;
vcpu_load(vcpu);
switch (ioctl) { switch (ioctl) {
case KVM_GET_LAPIC: { case KVM_GET_LAPIC: {
r = -EINVAL; r = -EINVAL;
...@@ -2481,9 +2445,7 @@ long kvm_arch_vcpu_ioctl(struct file *filp, ...@@ -2481,9 +2445,7 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
r = -EFAULT; r = -EFAULT;
if (copy_from_user(&mce, argp, sizeof mce)) if (copy_from_user(&mce, argp, sizeof mce))
goto out; goto out;
vcpu_load(vcpu);
r = kvm_vcpu_ioctl_x86_set_mce(vcpu, &mce); r = kvm_vcpu_ioctl_x86_set_mce(vcpu, &mce);
vcpu_put(vcpu);
break; break;
} }
case KVM_GET_VCPU_EVENTS: { case KVM_GET_VCPU_EVENTS: {
...@@ -2534,6 +2496,7 @@ long kvm_arch_vcpu_ioctl(struct file *filp, ...@@ -2534,6 +2496,7 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
r = -EINVAL; r = -EINVAL;
} }
out: out:
vcpu_put(vcpu);
kfree(lapic); kfree(lapic);
return r; return r;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment