mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-02 23:27:06 +00:00
KVM: x86: make pic setup code look like ioapic setup
We don't treat kvm->arch.vpic specially anymore, so the setup can look like ioapic. This gets a bit more information out of return values. Reviewed-by: Paolo Bonzini <pbonzini@redhat.com> Reviewed-by: David Hildenbrand <david@redhat.com> Signed-off-by: Radim Krčmář <rkrcmar@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
49776faf93
commit
099413664c
3 changed files with 28 additions and 22 deletions
|
@ -598,14 +598,14 @@ static const struct kvm_io_device_ops picdev_eclr_ops = {
|
||||||
.write = picdev_eclr_write,
|
.write = picdev_eclr_write,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct kvm_pic *kvm_create_pic(struct kvm *kvm)
|
int kvm_pic_init(struct kvm *kvm)
|
||||||
{
|
{
|
||||||
struct kvm_pic *s;
|
struct kvm_pic *s;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
s = kzalloc(sizeof(struct kvm_pic), GFP_KERNEL);
|
s = kzalloc(sizeof(struct kvm_pic), GFP_KERNEL);
|
||||||
if (!s)
|
if (!s)
|
||||||
return NULL;
|
return -ENOMEM;
|
||||||
spin_lock_init(&s->lock);
|
spin_lock_init(&s->lock);
|
||||||
s->kvm = kvm;
|
s->kvm = kvm;
|
||||||
s->pics[0].elcr_mask = 0xf8;
|
s->pics[0].elcr_mask = 0xf8;
|
||||||
|
@ -635,7 +635,9 @@ struct kvm_pic *kvm_create_pic(struct kvm *kvm)
|
||||||
|
|
||||||
mutex_unlock(&kvm->slots_lock);
|
mutex_unlock(&kvm->slots_lock);
|
||||||
|
|
||||||
return s;
|
kvm->arch.vpic = s;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
fail_unreg_1:
|
fail_unreg_1:
|
||||||
kvm_io_bus_unregister_dev(kvm, KVM_PIO_BUS, &s->dev_slave);
|
kvm_io_bus_unregister_dev(kvm, KVM_PIO_BUS, &s->dev_slave);
|
||||||
|
@ -648,13 +650,17 @@ struct kvm_pic *kvm_create_pic(struct kvm *kvm)
|
||||||
|
|
||||||
kfree(s);
|
kfree(s);
|
||||||
|
|
||||||
return NULL;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void kvm_destroy_pic(struct kvm_pic *vpic)
|
void kvm_pic_destroy(struct kvm *kvm)
|
||||||
{
|
{
|
||||||
|
struct kvm_pic *vpic = kvm->arch.vpic;
|
||||||
|
|
||||||
kvm_io_bus_unregister_dev(vpic->kvm, KVM_PIO_BUS, &vpic->dev_master);
|
kvm_io_bus_unregister_dev(vpic->kvm, KVM_PIO_BUS, &vpic->dev_master);
|
||||||
kvm_io_bus_unregister_dev(vpic->kvm, KVM_PIO_BUS, &vpic->dev_slave);
|
kvm_io_bus_unregister_dev(vpic->kvm, KVM_PIO_BUS, &vpic->dev_slave);
|
||||||
kvm_io_bus_unregister_dev(vpic->kvm, KVM_PIO_BUS, &vpic->dev_eclr);
|
kvm_io_bus_unregister_dev(vpic->kvm, KVM_PIO_BUS, &vpic->dev_eclr);
|
||||||
|
|
||||||
|
kvm->arch.vpic = NULL;
|
||||||
kfree(vpic);
|
kfree(vpic);
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,8 +73,8 @@ struct kvm_pic {
|
||||||
unsigned long irq_states[PIC_NUM_PINS];
|
unsigned long irq_states[PIC_NUM_PINS];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct kvm_pic *kvm_create_pic(struct kvm *kvm);
|
int kvm_pic_init(struct kvm *kvm);
|
||||||
void kvm_destroy_pic(struct kvm_pic *vpic);
|
void kvm_pic_destroy(struct kvm *kvm);
|
||||||
int kvm_pic_read_irq(struct kvm *kvm);
|
int kvm_pic_read_irq(struct kvm *kvm);
|
||||||
void kvm_pic_update_irq(struct kvm_pic *s);
|
void kvm_pic_update_irq(struct kvm_pic *s);
|
||||||
|
|
||||||
|
|
|
@ -3957,33 +3957,34 @@ long kvm_arch_vm_ioctl(struct file *filp,
|
||||||
r = kvm_vm_ioctl_get_nr_mmu_pages(kvm);
|
r = kvm_vm_ioctl_get_nr_mmu_pages(kvm);
|
||||||
break;
|
break;
|
||||||
case KVM_CREATE_IRQCHIP: {
|
case KVM_CREATE_IRQCHIP: {
|
||||||
struct kvm_pic *vpic;
|
|
||||||
|
|
||||||
mutex_lock(&kvm->lock);
|
mutex_lock(&kvm->lock);
|
||||||
|
|
||||||
r = -EEXIST;
|
r = -EEXIST;
|
||||||
if (irqchip_in_kernel(kvm))
|
if (irqchip_in_kernel(kvm))
|
||||||
goto create_irqchip_unlock;
|
goto create_irqchip_unlock;
|
||||||
|
|
||||||
r = -EINVAL;
|
r = -EINVAL;
|
||||||
if (kvm->created_vcpus)
|
if (kvm->created_vcpus)
|
||||||
goto create_irqchip_unlock;
|
goto create_irqchip_unlock;
|
||||||
r = -ENOMEM;
|
|
||||||
vpic = kvm_create_pic(kvm);
|
r = kvm_pic_init(kvm);
|
||||||
if (vpic) {
|
if (r)
|
||||||
r = kvm_ioapic_init(kvm);
|
|
||||||
if (r) {
|
|
||||||
mutex_lock(&kvm->slots_lock);
|
|
||||||
kvm_destroy_pic(vpic);
|
|
||||||
mutex_unlock(&kvm->slots_lock);
|
|
||||||
goto create_irqchip_unlock;
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
goto create_irqchip_unlock;
|
goto create_irqchip_unlock;
|
||||||
|
|
||||||
|
r = kvm_ioapic_init(kvm);
|
||||||
|
if (r) {
|
||||||
|
mutex_lock(&kvm->slots_lock);
|
||||||
|
kvm_pic_destroy(kvm);
|
||||||
|
mutex_unlock(&kvm->slots_lock);
|
||||||
|
goto create_irqchip_unlock;
|
||||||
|
}
|
||||||
|
|
||||||
r = kvm_setup_default_irq_routing(kvm);
|
r = kvm_setup_default_irq_routing(kvm);
|
||||||
if (r) {
|
if (r) {
|
||||||
mutex_lock(&kvm->slots_lock);
|
mutex_lock(&kvm->slots_lock);
|
||||||
mutex_lock(&kvm->irq_lock);
|
mutex_lock(&kvm->irq_lock);
|
||||||
kvm_ioapic_destroy(kvm);
|
kvm_ioapic_destroy(kvm);
|
||||||
kvm_destroy_pic(vpic);
|
kvm_pic_destroy(kvm);
|
||||||
mutex_unlock(&kvm->irq_lock);
|
mutex_unlock(&kvm->irq_lock);
|
||||||
mutex_unlock(&kvm->slots_lock);
|
mutex_unlock(&kvm->slots_lock);
|
||||||
goto create_irqchip_unlock;
|
goto create_irqchip_unlock;
|
||||||
|
@ -3991,7 +3992,6 @@ long kvm_arch_vm_ioctl(struct file *filp,
|
||||||
/* Write kvm->irq_routing before enabling irqchip_in_kernel. */
|
/* Write kvm->irq_routing before enabling irqchip_in_kernel. */
|
||||||
smp_wmb();
|
smp_wmb();
|
||||||
kvm->arch.irqchip_mode = KVM_IRQCHIP_KERNEL;
|
kvm->arch.irqchip_mode = KVM_IRQCHIP_KERNEL;
|
||||||
kvm->arch.vpic = vpic;
|
|
||||||
create_irqchip_unlock:
|
create_irqchip_unlock:
|
||||||
mutex_unlock(&kvm->lock);
|
mutex_unlock(&kvm->lock);
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in a new issue