diff options
author | Zhang Xiantao <xiantao.zhang@intel.com> | 2007-11-29 02:35:39 -0500 |
---|---|---|
committer | Avi Kivity <avi@qumranet.com> | 2008-01-30 10:53:16 -0500 |
commit | d23087847184a7417fc69bdfaa8a32834b447bef (patch) | |
tree | 84b436ab14ecf4d62107a030c2a0f7d5dc881c44 /drivers/kvm/kvm_main.c | |
parent | f77bc6a420eba845605ff1d53cadf55f94c5e8b7 (diff) |
KVM: Correct kvm_init() error paths not freeing bad_pge.
Signed-off-by: Zhang Xiantao <xiantao.zhang@intel.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Diffstat (limited to 'drivers/kvm/kvm_main.c')
-rw-r--r-- | drivers/kvm/kvm_main.c | 28 |
1 files changed, 15 insertions, 13 deletions
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c index c74fb44dd87b..058366f480dc 100644 --- a/drivers/kvm/kvm_main.c +++ b/drivers/kvm/kvm_main.c | |||
@@ -1311,7 +1311,7 @@ int kvm_init(void *opaque, unsigned int vcpu_size, | |||
1311 | 1311 | ||
1312 | r = kvm_arch_init(opaque); | 1312 | r = kvm_arch_init(opaque); |
1313 | if (r) | 1313 | if (r) |
1314 | goto out4; | 1314 | goto out_fail; |
1315 | 1315 | ||
1316 | bad_page = alloc_page(GFP_KERNEL | __GFP_ZERO); | 1316 | bad_page = alloc_page(GFP_KERNEL | __GFP_ZERO); |
1317 | 1317 | ||
@@ -1322,29 +1322,29 @@ int kvm_init(void *opaque, unsigned int vcpu_size, | |||
1322 | 1322 | ||
1323 | r = kvm_arch_hardware_setup(); | 1323 | r = kvm_arch_hardware_setup(); |
1324 | if (r < 0) | 1324 | if (r < 0) |
1325 | goto out; | 1325 | goto out_free_0; |
1326 | 1326 | ||
1327 | for_each_online_cpu(cpu) { | 1327 | for_each_online_cpu(cpu) { |
1328 | smp_call_function_single(cpu, | 1328 | smp_call_function_single(cpu, |
1329 | kvm_arch_check_processor_compat, | 1329 | kvm_arch_check_processor_compat, |
1330 | &r, 0, 1); | 1330 | &r, 0, 1); |
1331 | if (r < 0) | 1331 | if (r < 0) |
1332 | goto out_free_0; | 1332 | goto out_free_1; |
1333 | } | 1333 | } |
1334 | 1334 | ||
1335 | on_each_cpu(hardware_enable, NULL, 0, 1); | 1335 | on_each_cpu(hardware_enable, NULL, 0, 1); |
1336 | r = register_cpu_notifier(&kvm_cpu_notifier); | 1336 | r = register_cpu_notifier(&kvm_cpu_notifier); |
1337 | if (r) | 1337 | if (r) |
1338 | goto out_free_1; | 1338 | goto out_free_2; |
1339 | register_reboot_notifier(&kvm_reboot_notifier); | 1339 | register_reboot_notifier(&kvm_reboot_notifier); |
1340 | 1340 | ||
1341 | r = sysdev_class_register(&kvm_sysdev_class); | 1341 | r = sysdev_class_register(&kvm_sysdev_class); |
1342 | if (r) | 1342 | if (r) |
1343 | goto out_free_2; | 1343 | goto out_free_3; |
1344 | 1344 | ||
1345 | r = sysdev_register(&kvm_sysdev); | 1345 | r = sysdev_register(&kvm_sysdev); |
1346 | if (r) | 1346 | if (r) |
1347 | goto out_free_3; | 1347 | goto out_free_4; |
1348 | 1348 | ||
1349 | /* A kmem cache lets us meet the alignment requirements of fx_save. */ | 1349 | /* A kmem cache lets us meet the alignment requirements of fx_save. */ |
1350 | kvm_vcpu_cache = kmem_cache_create("kvm_vcpu", vcpu_size, | 1350 | kvm_vcpu_cache = kmem_cache_create("kvm_vcpu", vcpu_size, |
@@ -1352,7 +1352,7 @@ int kvm_init(void *opaque, unsigned int vcpu_size, | |||
1352 | 0, NULL); | 1352 | 0, NULL); |
1353 | if (!kvm_vcpu_cache) { | 1353 | if (!kvm_vcpu_cache) { |
1354 | r = -ENOMEM; | 1354 | r = -ENOMEM; |
1355 | goto out_free_4; | 1355 | goto out_free_5; |
1356 | } | 1356 | } |
1357 | 1357 | ||
1358 | kvm_chardev_ops.owner = module; | 1358 | kvm_chardev_ops.owner = module; |
@@ -1370,21 +1370,23 @@ int kvm_init(void *opaque, unsigned int vcpu_size, | |||
1370 | 1370 | ||
1371 | out_free: | 1371 | out_free: |
1372 | kmem_cache_destroy(kvm_vcpu_cache); | 1372 | kmem_cache_destroy(kvm_vcpu_cache); |
1373 | out_free_4: | 1373 | out_free_5: |
1374 | sysdev_unregister(&kvm_sysdev); | 1374 | sysdev_unregister(&kvm_sysdev); |
1375 | out_free_3: | 1375 | out_free_4: |
1376 | sysdev_class_unregister(&kvm_sysdev_class); | 1376 | sysdev_class_unregister(&kvm_sysdev_class); |
1377 | out_free_2: | 1377 | out_free_3: |
1378 | unregister_reboot_notifier(&kvm_reboot_notifier); | 1378 | unregister_reboot_notifier(&kvm_reboot_notifier); |
1379 | unregister_cpu_notifier(&kvm_cpu_notifier); | 1379 | unregister_cpu_notifier(&kvm_cpu_notifier); |
1380 | out_free_1: | 1380 | out_free_2: |
1381 | on_each_cpu(hardware_disable, NULL, 0, 1); | 1381 | on_each_cpu(hardware_disable, NULL, 0, 1); |
1382 | out_free_0: | 1382 | out_free_1: |
1383 | kvm_arch_hardware_unsetup(); | 1383 | kvm_arch_hardware_unsetup(); |
1384 | out_free_0: | ||
1385 | __free_page(bad_page); | ||
1384 | out: | 1386 | out: |
1385 | kvm_arch_exit(); | 1387 | kvm_arch_exit(); |
1386 | kvm_exit_debug(); | 1388 | kvm_exit_debug(); |
1387 | out4: | 1389 | out_fail: |
1388 | return r; | 1390 | return r; |
1389 | } | 1391 | } |
1390 | EXPORT_SYMBOL_GPL(kvm_init); | 1392 | EXPORT_SYMBOL_GPL(kvm_init); |