aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorAvi Kivity <avi@redhat.com>2009-01-05 08:21:42 -0500
committerAvi Kivity <avi@redhat.com>2009-03-24 05:03:01 -0400
commit269e05e48502f1cc06802e9fba90f5100dd6bb0d (patch)
tree9b3501dc1f5e137c2dca7eacf15c0353f627be97 /arch
parenta77ab5ead5c1fef2c6c5a9b3cf3765e52643a2aa (diff)
KVM: Properly lock PIT creation
Otherwise, two threads can create a PIT in parallel and cause a memory leak. Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/kvm/i8254.c2
-rw-r--r--arch/x86/kvm/x86.c6
2 files changed, 6 insertions, 2 deletions
diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c
index 528daadeba49..69d1bbff3fd3 100644
--- a/arch/x86/kvm/i8254.c
+++ b/arch/x86/kvm/i8254.c
@@ -548,9 +548,7 @@ struct kvm_pit *kvm_create_pit(struct kvm *kvm)
548 if (!pit) 548 if (!pit)
549 return NULL; 549 return NULL;
550 550
551 mutex_lock(&kvm->lock);
552 pit->irq_source_id = kvm_request_irq_source_id(kvm); 551 pit->irq_source_id = kvm_request_irq_source_id(kvm);
553 mutex_unlock(&kvm->lock);
554 if (pit->irq_source_id < 0) { 552 if (pit->irq_source_id < 0) {
555 kfree(pit); 553 kfree(pit);
556 return NULL; 554 return NULL;
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index a1f14611f4b9..6fbc34603375 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -1837,10 +1837,16 @@ long kvm_arch_vm_ioctl(struct file *filp,
1837 goto out; 1837 goto out;
1838 break; 1838 break;
1839 case KVM_CREATE_PIT: 1839 case KVM_CREATE_PIT:
1840 mutex_lock(&kvm->lock);
1841 r = -EEXIST;
1842 if (kvm->arch.vpit)
1843 goto create_pit_unlock;
1840 r = -ENOMEM; 1844 r = -ENOMEM;
1841 kvm->arch.vpit = kvm_create_pit(kvm); 1845 kvm->arch.vpit = kvm_create_pit(kvm);
1842 if (kvm->arch.vpit) 1846 if (kvm->arch.vpit)
1843 r = 0; 1847 r = 0;
1848 create_pit_unlock:
1849 mutex_unlock(&kvm->lock);
1844 break; 1850 break;
1845 case KVM_IRQ_LINE: { 1851 case KVM_IRQ_LINE: {
1846 struct kvm_irq_level irq_event; 1852 struct kvm_irq_level irq_event;