]> Pileus Git - ~andy/linux/blobdiff - drivers/kvm/kvm_main.c
[PATCH] KVM: Recover after an arch module load failure
[~andy/linux] / drivers / kvm / kvm_main.c
index 0e618bcfe1dad5076f431ec8c412fd43f1cbb22c..b54caf0ceeb1305a2129177234a745cf079897a5 100644 (file)
@@ -245,7 +245,8 @@ static void kvm_free_physmem_slot(struct kvm_memory_slot *free,
        if (!dont || free->phys_mem != dont->phys_mem)
                if (free->phys_mem) {
                        for (i = 0; i < free->npages; ++i)
-                               __free_page(free->phys_mem[i]);
+                               if (free->phys_mem[i])
+                                       __free_page(free->phys_mem[i]);
                        vfree(free->phys_mem);
                }
 
@@ -521,12 +522,14 @@ static int kvm_dev_ioctl_create_vcpu(struct kvm *kvm, int n)
        if (r < 0)
                goto out_free_vcpus;
 
-       kvm_arch_ops->vcpu_load(vcpu);
+       r = kvm_mmu_create(vcpu);
+       if (r < 0)
+               goto out_free_vcpus;
 
-       r = kvm_arch_ops->vcpu_setup(vcpu);
+       kvm_arch_ops->vcpu_load(vcpu);
+       r = kvm_mmu_setup(vcpu);
        if (r >= 0)
-               r = kvm_mmu_init(vcpu);
-
+               r = kvm_arch_ops->vcpu_setup(vcpu);
        vcpu_put(vcpu);
 
        if (r < 0)
@@ -1941,17 +1944,17 @@ int kvm_init_arch(struct kvm_arch_ops *ops, struct module *module)
                return -EEXIST;
        }
 
-       kvm_arch_ops = ops;
-
-       if (!kvm_arch_ops->cpu_has_kvm_support()) {
+       if (!ops->cpu_has_kvm_support()) {
                printk(KERN_ERR "kvm: no hardware support\n");
                return -EOPNOTSUPP;
        }
-       if (kvm_arch_ops->disabled_by_bios()) {
+       if (ops->disabled_by_bios()) {
                printk(KERN_ERR "kvm: disabled by bios\n");
                return -EOPNOTSUPP;
        }
 
+       kvm_arch_ops = ops;
+
        r = kvm_arch_ops->hardware_setup();
        if (r < 0)
            return r;