aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZhang Xiantao <xiantao.zhang@intel.com>2007-11-29 02:35:39 -0500
committerAvi Kivity <avi@qumranet.com>2008-01-30 10:53:16 -0500
commitd23087847184a7417fc69bdfaa8a32834b447bef (patch)
tree84b436ab14ecf4d62107a030c2a0f7d5dc881c44
parentf77bc6a420eba845605ff1d53cadf55f94c5e8b7 (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>
-rw-r--r--drivers/kvm/kvm_main.c28
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
1371out_free: 1371out_free:
1372 kmem_cache_destroy(kvm_vcpu_cache); 1372 kmem_cache_destroy(kvm_vcpu_cache);
1373out_free_4: 1373out_free_5:
1374 sysdev_unregister(&kvm_sysdev); 1374 sysdev_unregister(&kvm_sysdev);
1375out_free_3: 1375out_free_4:
1376 sysdev_class_unregister(&kvm_sysdev_class); 1376 sysdev_class_unregister(&kvm_sysdev_class);
1377out_free_2: 1377out_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);
1380out_free_1: 1380out_free_2:
1381 on_each_cpu(hardware_disable, NULL, 0, 1); 1381 on_each_cpu(hardware_disable, NULL, 0, 1);
1382out_free_0: 1382out_free_1:
1383 kvm_arch_hardware_unsetup(); 1383 kvm_arch_hardware_unsetup();
1384out_free_0:
1385 __free_page(bad_page);
1384out: 1386out:
1385 kvm_arch_exit(); 1387 kvm_arch_exit();
1386 kvm_exit_debug(); 1388 kvm_exit_debug();
1387out4: 1389out_fail:
1388 return r; 1390 return r;
1389} 1391}
1390EXPORT_SYMBOL_GPL(kvm_init); 1392EXPORT_SYMBOL_GPL(kvm_init);