Skip to contentSkip to conversation

Architecture independence layer - v1 - split_generic_x86_change

PATCH In review Christian Ehrhardt 1 participant 1 message Aug 24, 2007 KVM

lore
Share & tools
lore
#0 lore raw

PATCH 5/5 Architecture independence layer - v1 - split_generic_x86_change

from Christian Ehrhardt

This contains the major changes done mostly in kvm_main.c to implement the generic handling of the ioctls with the mapping to arch functions as needed.

---
 kvm.h      |   20 ++
 kvm_arch.h |   34 ++++
 kvm_main.c |  431 
+++++++------------------------------------------------------
 3 files changed, 104 insertions(+), 381 deletions(-)
drivers/kvm/kvm.h +0 -0
index ff07e64..9bdb408 100644
@@ -681,4 +681,24 @@ static inline u32 get_rdx_init_val(void)
 #define TSS_REDIRECTION_SIZE (256 / 8)
 #define RMODE_TSS_SIZE (TSS_BASE_SIZE + TSS_REDIRECTION_SIZE + 

TSS_IOPB_SIZE + 1)

+/* generic functions provided to arch module part by kvm_main code after split */
+extern __read_mostly struct preempt_ops kvm_preempt_ops; +
+void kvm_destroy_vm(struct kvm *kvm);
+void kvm_free_physmem_slot(struct kvm_memory_slot *free,
+ struct kvm_memory_slot *dont);
+
+struct kvm_io_device *vcpu_find_mmio_dev(struct kvm_vcpu *vcpu,
+ gpa_t addr);
+int complete_pio(struct kvm_vcpu *vcpu);
+
+__init void kvm_init_debug(void);
+void kvm_exit_debug(void);
+
+int kvm_init_generic(unsigned int vcpu_size, struct module *module); +void kvm_exit_generic(void);
+
+void vcpu_load(struct kvm_vcpu *vcpu);
+void vcpu_put(struct kvm_vcpu *vcpu);
+
#endif

drivers/kvm/kvm_arch.h +34 -0
index 6658948..8e4759f 100644
@@ -11,4 +11,38 @@
 
 #include <linux/module.h>
 
+long kvm_arch_dev_ioctl(struct file *filp, unsigned int ioctl,
+                        unsigned long arg);
+void kvm_arch_free_vcpus(struct kvm *kvm);
+
+long kvm_arch_vm_ioctl(struct file *filp, unsigned int ioctl,
+                       unsigned long arg);
+struct kvm_vcpu* kvm_arch_vcpu_create(struct kvm *kvm, unsigned id);
+void kvm_arch_vcpu_free(struct kvm_vcpu *vcpu);
+void kvm_arch_vcpu_decache(struct kvm_vcpu *vcpu);
+
+void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu);
+void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu);
+void kvm_arch_cache_regs(struct kvm_vcpu *vcpu);
+void kvm_arch_decache_regs(struct kvm_vcpu *vcpu);
+
+void kvm_arch_skip_emulated_instruction(struct kvm_vcpu *vcpu);
+void kvm_arch_inject_gp(struct kvm_vcpu *vcpu);
+
+long kvm_arch_vcpu_ioctl(struct file *filp, unsigned int ioctl,
+                         unsigned long arg);
+int kvm_arch_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run);
+int kvm_arch_vcpu_debug_guest(struct kvm_vcpu *vcpu,
+                                      struct kvm_debug_guest *dbg);
+int kvm_arch_vcpu_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs);
+int kvm_arch_vcpu_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs);
+int kvm_arch_vcpu_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu);
+int kvm_arch_vcpu_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu);
+
+void kvm_arch_hardware_enable(void *junk);
+void kvm_arch_hardware_disable(void *junk);
+
+__exit void kvm_arch_exit(void);
+__init int kvm_arch_init(void);
+
 #endif
drivers/kvm/kvm_main.c +16 -190

292 lines not on this page · raw message

kvm_run *run, int in,

     vcpu->pio.guest_page_offset = 0;
     vcpu->pio.rep = 0;

- kvm_x86_ops->cache_regs(vcpu);

+    kvm_arch_cache_regs(vcpu);
     memcpy(vcpu->pio_data, &vcpu->regs[VCPU_REGS_RAX], 4);

- kvm_x86_ops->decache_regs(vcpu);
+ kvm_arch_decache_regs(vcpu);

     pio_dev = vcpu_find_pio_dev(vcpu, port);
     if (pio_dev) {
@@ -800,7 +626,7 @@ int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, 
struct kvm_run *run, int in,
     vcpu->pio.rep = rep;
 
     if (!count) {
-        kvm_x86_ops->skip_emulated_instruction(vcpu);
+        kvm_arch_skip_emulated_instruction(vcpu);
         return 1;
     }

@@ -823,7 +649,7 @@ int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,

          * String I/O in reverse.  Yuck.  Kill the guest, fix later.
          */
         pr_unimpl(vcpu, "guest string pio down\n");
-        inject_gp(vcpu);
+        kvm_arch_inject_gp(vcpu);
         return 1;
     }
     vcpu->run->io.count = now;
@@ -837,7 +663,7 @@ int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, 
struct kvm_run *run, int in,
         vcpu->pio.guest_pages[i] = page;
         mutex_unlock(&vcpu->kvm->lock);
         if (!page) {
-            inject_gp(vcpu);
+            kvm_arch_inject_gp(vcpu);
             free_pio_guest_pages(vcpu);
             return 1;
         }
@@ -974,7 +800,7 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm, 
int n)
     if (!valid_vcpu(n))
         return -EINVAL;

- vcpu = kvm_x86_ops->vcpu_create(kvm, n);

+    vcpu = kvm_arch_vcpu_create(kvm, n);
     if (IS_ERR(vcpu))
         return PTR_ERR(vcpu);

@@ -1015,49 +841,7 @@ mmu_unload:

     vcpu_put(vcpu);

free_vcpu:
- kvm_x86_ops->vcpu_free(vcpu);
- return r;
-}
-
-static void cpuid_fix_nx_cap(struct kvm_vcpu *vcpu) -{

-    u64 efer;
-    int i;
-    struct kvm_cpuid_entry *e, *entry;
-
-    rdmsrl(MSR_EFER, efer);
-    entry = NULL;
-    for (i = 0; i < vcpu->cpuid_nent; ++i) {

- e = &vcpu->cpuid_entries[i];
- if (e->function == 0x80000001) {
- entry = e;
- break;
- }
- }
- if (entry && (entry->edx & (1 << 20)) && !(efer & EFER_NX)) {
- entry->edx &= ~(1 << 20);
- printk(KERN_INFO "kvm: guest NX capability removed\n");
- }
-}
-
-static int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu,
- struct kvm_cpuid *cpuid,
- struct kvm_cpuid_entry __user *entries)
-{
- int r;
-
- r = -E2BIG;
- if (cpuid->nent > KVM_MAX_CPUID_ENTRIES)
- goto out;
- r = -EFAULT;
- if (copy_from_user(&vcpu->cpuid_entries, entries,
- cpuid->nent * sizeof(struct kvm_cpuid_entry)))
- goto out;

-    vcpu->cpuid_nent = cpuid->nent;
-    cpuid_fix_nx_cap(vcpu);
-    return 0;
-
-out:
+    kvm_arch_vcpu_free(vcpu);
     return r;

}

@@ -1084,13 +868,13 @@ static long kvm_vcpu_ioctl(struct file *filp,

         r = -EINVAL;
         if (arg)
             goto out;
-        r = kvm_vcpu_ioctl_run(vcpu, vcpu->run);
+        r = kvm_arch_vcpu_run(vcpu, vcpu->run);
         break;
     case KVM_GET_REGS: {
         struct kvm_regs kvm_regs;
 
         memset(&kvm_regs, 0, sizeof kvm_regs);
-        r = kvm_vcpu_ioctl_get_regs(vcpu, &kvm_regs);
+        r = kvm_arch_vcpu_get_regs(vcpu, &kvm_regs);
         if (r)
             goto out;
         r = -EFAULT;
@@ -1105,32 +889,7 @@ static long kvm_vcpu_ioctl(struct file *filp,
         r = -EFAULT;
         if (copy_from_user(&kvm_regs, argp, sizeof kvm_regs))
             goto out;

- r = kvm_vcpu_ioctl_set_regs(vcpu, &kvm_regs);
- if (r)
- goto out;
- r = 0;
- break;
- }
- case KVM_GET_SREGS: {
- struct kvm_sregs kvm_sregs;
-

-        memset(&kvm_sregs, 0, sizeof kvm_sregs);
-        r = kvm_vcpu_ioctl_get_sregs(vcpu, &kvm_sregs);
-        if (r)

- goto out;
- r = -EFAULT;
- if (copy_to_user(argp, &kvm_sregs, sizeof kvm_sregs))
- goto out;
- r = 0;
- break;
- }
- case KVM_SET_SREGS: {
- struct kvm_sregs kvm_sregs;
-
- r = -EFAULT;
- if (copy_from_user(&kvm_sregs, argp, sizeof kvm_sregs))
- goto out;
- r = kvm_vcpu_ioctl_set_sregs(vcpu, &kvm_sregs);

+        r = kvm_arch_vcpu_set_regs(vcpu, &kvm_regs);
         if (r)
             goto out;
         r = 0;
@@ -1169,30 +928,12 @@ static long kvm_vcpu_ioctl(struct file *filp,
         r = -EFAULT;
         if (copy_from_user(&dbg, argp, sizeof dbg))
             goto out;
-        r = kvm_vcpu_ioctl_debug_guest(vcpu, &dbg);
+        r = kvm_arch_vcpu_debug_guest(vcpu, &dbg);
         if (r)
             goto out;
         r = 0;
         break;
     }

- case KVM_GET_MSRS:
- r = msr_io(vcpu, argp, kvm_get_msr, 1);
- break;
- case KVM_SET_MSRS:
- r = msr_io(vcpu, argp, do_set_msr, 0);
- break;
- case KVM_SET_CPUID: {
- struct kvm_cpuid __user *cpuid_arg = argp;
- struct kvm_cpuid cpuid;
-
- r = -EFAULT;
- if (copy_from_user(&cpuid, cpuid_arg, sizeof cpuid))
- goto out;
- r = kvm_vcpu_ioctl_set_cpuid(vcpu, &cpuid, cpuid_arg->entries);
- if (r)
- goto out;
- break;
- }

     case KVM_SET_SIGNAL_MASK: {
         struct kvm_signal_mask __user *sigmask_arg = argp;
         struct kvm_signal_mask kvm_sigmask;
@@ -1220,7 +961,7 @@ static long kvm_vcpu_ioctl(struct file *filp,
         struct kvm_fpu fpu;
 
         memset(&fpu, 0, sizeof fpu);
-        r = kvm_vcpu_ioctl_get_fpu(vcpu, &fpu);
+        r = kvm_arch_vcpu_get_fpu(vcpu, &fpu);
         if (r)
             goto out;
         r = -EFAULT;
@@ -1235,14 +976,14 @@ static long kvm_vcpu_ioctl(struct file *filp,
         r = -EFAULT;
         if (copy_from_user(&fpu, argp, sizeof fpu))
             goto out;
-        r = kvm_vcpu_ioctl_set_fpu(vcpu, &fpu);
+        r = kvm_arch_vcpu_set_fpu(vcpu, &fpu);
         if (r)
             goto out;
         r = 0;
         break;
     }
     default:
-        ;
+        r = kvm_arch_vcpu_ioctl(filp, ioctl, arg);
     }
 out:
     return r;
@@ -1295,7 +1036,7 @@ static long kvm_vm_ioctl(struct file *filp,
         break;
     }
     default:
-        ;
+        r = kvm_arch_vm_ioctl(filp, ioctl, arg);
     }
 out:
     return r;

@@ -1361,7 +1102,6 @@ static int kvm_dev_ioctl_create_vm(void)
static long kvm_dev_ioctl(struct file *filp,
unsigned int ioctl, unsigned long arg)
{

-    void __user *argp = (void __user *)arg;
     long r = -EINVAL;
 
     switch (ioctl) {
@@ -1377,33 +1117,6 @@ static long kvm_dev_ioctl(struct file *filp,
             goto out;
         r = kvm_dev_ioctl_create_vm();
         break;
-    case KVM_GET_MSR_INDEX_LIST: {
-        struct kvm_msr_list __user *user_msr_list = argp;
-        struct kvm_msr_list msr_list;
-        unsigned n;

-
- r = -EFAULT;
- if (copy_from_user(&msr_list, user_msr_list, sizeof msr_list))
- goto out;

-        n = msr_list.nmsrs;
-        msr_list.nmsrs = num_msrs_to_save + ARRAY_SIZE(emulated_msrs);
-        if (copy_to_user(user_msr_list, &msr_list, sizeof msr_list))

- goto out;
- r = -E2BIG;
- if (n < num_msrs_to_save)
- goto out;
- r = -EFAULT;
- if (copy_to_user(user_msr_list->indices, &msrs_to_save,
- num_msrs_to_save * sizeof(u32)))
- goto out;
- if (copy_to_user(user_msr_list->indices

-                 + num_msrs_to_save * sizeof(u32),
-                 &emulated_msrs,
-                 ARRAY_SIZE(emulated_msrs) * sizeof(u32)))

- goto out;
- r = 0;
- break;
- }
case KVM_CHECK_EXTENSION:
/*
* No extensions defined at present.
@@ -1417,7 +1130,7 @@ static long kvm_dev_ioctl(struct file *filp,

         r = 2 * PAGE_SIZE;
         break;
     default:
-        ;
+        r = kvm_arch_dev_ioctl(filp, ioctl, arg);
     }
 out:
     return r;
@@ -1460,7 +1173,7 @@ static void decache_vcpus_on_cpu(int cpu)
              */
             if (mutex_trylock(&vcpu->mutex)) {
                 if (vcpu->cpu == cpu) {
-                    kvm_x86_ops->vcpu_decache(vcpu);
+                    kvm_arch_vcpu_decache(vcpu);
                     vcpu->cpu = -1;
                 }
                 mutex_unlock(&vcpu->mutex);
@@ -1476,7 +1189,7 @@ static void hardware_enable(void *junk)
     if (cpu_isset(cpu, cpus_hardware_enabled))
         return;
     cpu_set(cpu, cpus_hardware_enabled);

- kvm_x86_ops->hardware_enable(NULL);
+ kvm_arch_hardware_enable(NULL);
}

static void hardware_disable(void *junk)
@@ -1487,7 +1200,7 @@ static void hardware_disable(void *junk)

         return;
     cpu_clear(cpu, cpus_hardware_enabled);
     decache_vcpus_on_cpu(cpu);

- kvm_x86_ops->hardware_disable(NULL);
+ kvm_arch_hardware_disable(NULL);
}

static int kvm_cpu_hotplug(struct notifier_block *notifier, unsigned
long val,
@@ -1596,7 +1309,7 @@ static u64 stat_get(void *_offset)

DEFINE_SIMPLE_ATTRIBUTE(stat_fops, stat_get, NULL, "%llu\n");

-static __init void kvm_init_debug(void)
+__init void kvm_init_debug(void)

 {
     struct kvm_stats_debugfs_item *p;

@@ -1607,7 +1320,7 @@ static __init void kvm_init_debug(void)

                         &stat_fops);

}

-static void kvm_exit_debug(void)
+void kvm_exit_debug(void)

 {
     struct kvm_stats_debugfs_item *p;

@@ -1651,7 +1364,7 @@ static void kvm_sched_in(struct preempt_notifier *pn, int cpu)

 {
     struct kvm_vcpu *vcpu = preempt_notifier_to_vcpu(pn);

- kvm_x86_ops->vcpu_load(vcpu, cpu);
+ kvm_arch_vcpu_load(vcpu, cpu);
}

static void kvm_sched_out(struct preempt_notifier *pn,
@@ -1659,42 +1372,11 @@ static void kvm_sched_out(struct preempt_notifier *pn,

 {
     struct kvm_vcpu *vcpu = preempt_notifier_to_vcpu(pn);

- kvm_x86_ops->vcpu_put(vcpu);
+ kvm_arch_vcpu_put(vcpu);
}

-int kvm_init_x86(struct kvm_x86_ops *ops, unsigned int vcpu_size,
- struct module *module)
-{

+int kvm_init_generic(unsigned int vcpu_size, struct module *module) {
     int r;

- int cpu;
-
- if (kvm_x86_ops) {
- printk(KERN_ERR "kvm: already loaded the other module\n");
- return -EEXIST;
- }
-
- if (!ops->cpu_has_kvm_support()) {
- printk(KERN_ERR "kvm: no hardware support\n");
- return -EOPNOTSUPP;
- }
- if (ops->disabled_by_bios()) {
- printk(KERN_ERR "kvm: disabled by bios\n");
- return -EOPNOTSUPP;
- }
-
- kvm_x86_ops = ops;
-
- r = kvm_x86_ops->hardware_setup();
- if (r < 0)
- goto out;
-
- for_each_online_cpu(cpu) {
- smp_call_function_single(cpu,
- kvm_x86_ops->check_processor_compatibility,
- &r, 0, 1);
- if (r < 0)
- goto out_free_0;
- }

     on_each_cpu(hardware_enable, NULL, 0, 1);
     r = register_cpu_notifier(&kvm_cpu_notifier);
@@ -1742,15 +1424,10 @@ out_free_2:
     unregister_cpu_notifier(&kvm_cpu_notifier);
 out_free_1:
     on_each_cpu(hardware_disable, NULL, 0, 1);
-out_free_0:
-    kvm_x86_ops->hardware_unsetup();
-out:
-    kvm_x86_ops = NULL;
     return r;

}

-void kvm_exit_x86(void)
-{

+void kvm_exit_generic(void) {
     misc_deregister(&kvm_dev);
     kmem_cache_destroy(kvm_vcpu_cache);
     sysdev_unregister(&kvm_sysdev);
@@ -1758,22 +1435,16 @@ void kvm_exit_x86(void)
     unregister_reboot_notifier(&kvm_reboot_notifier);
     unregister_cpu_notifier(&kvm_cpu_notifier);
     on_each_cpu(hardware_disable, NULL, 0, 1);

- kvm_x86_ops->hardware_unsetup();
- kvm_x86_ops = NULL;
}

static __init int kvm_init(void)
{

-    static struct page *bad_page;
     int r;

+ static struct page *bad_page;

- r = kvm_mmu_module_init();
- if (r)
- goto out4;
-
- kvm_init_debug();
-
- kvm_init_msr_list();
+ r = kvm_arch_init();
+ if (r)
+ goto out2;

     if ((bad_page = alloc_page(GFP_KERNEL)) == NULL) {
         r = -ENOMEM;
@@ -1786,21 +1457,19 @@ static __init int kvm_init(void)
     return 0;

out:
- kvm_exit_debug();
- kvm_mmu_module_exit();
-out4:
+ kvm_arch_exit();
+out2:

     return r;

}

static __exit void kvm_exit(void)
{
- kvm_exit_debug();

+    kvm_arch_exit();
     __free_page(pfn_to_page(bad_page_address >> PAGE_SHIFT));

- kvm_mmu_module_exit();
}

module_init(kvm_init)
module_exit(kvm_exit)

-EXPORT_SYMBOL_GPL(kvm_init_x86);
-EXPORT_SYMBOL_GPL(kvm_exit_x86);
+EXPORT_SYMBOL_GPL(kvm_init);
+EXPORT_SYMBOL_GPL(kvm_exit);

Signature · 20 lines
Grüsse / regards, 
Christian Ehrhardt

IBM Linux Technology Center, Open Virtualization
+49 7031/16-3385
[email protected]
[email protected]

IBM Deutschland Entwicklung GmbH
Vorsitzender des Aufsichtsrats: Johann Weihen 
Geschäftsführung: Herbert Kircher 
Sitz der Gesellschaft: Böblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294


-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/