diff options
author | Andrea Arcangeli <andrea@qumranet.com> | 2008-05-20 21:25:06 +0200 |
---|---|---|
committer | Avi Kivity <avi@qumranet.com> | 2008-05-21 19:26:19 +0300 |
commit | 7913795342296f74ac7ca52e77bf53064f402b9e (patch) | |
tree | 213e170199a81f167c969efdf477e4bf959c782e /kernel | |
parent | 2a6928da42550f4481ad570a35a76dc711047729 (diff) |
kvm: external module: support for 2.6.16 hosts
This allows building and running kvm.git/kvm-userspace.git on top of
2.6.16 host kernels, including SLES 10 hosts.
Signed-off-by: Andrea Arcangeli <andrea@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/Makefile | 2 | ||||
-rw-r--r-- | kernel/external-module-compat.c | 7 | ||||
-rw-r--r-- | kernel/external-module-compat.h | 66 | ||||
-rw-r--r-- | kernel/hack-module.awk | 15 |
4 files changed, 89 insertions, 1 deletions
diff --git a/kernel/Makefile b/kernel/Makefile index e26d3fd2..69b4981c 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -26,7 +26,7 @@ unifdef = mv $1 $1.orig && \ hack = $(call _hack,$T/$(strip $1)) -hack-files-x86 = kvm_main.c mmu.c vmx.c svm.c x86.c irq.h +hack-files-x86 = kvm_main.c mmu.c vmx.c svm.c x86.c irq.h lapic.c i8254.c hack-files = $(hack-files-$(ARCH_DIR)) diff --git a/kernel/external-module-compat.c b/kernel/external-module-compat.c index 5b199408..2a221195 100644 --- a/kernel/external-module-compat.c +++ b/kernel/external-module-compat.c @@ -191,3 +191,10 @@ out: } #endif + +/* manually export hrtimer_init/start/cancel */ +void (*hrtimer_init_p)(struct hrtimer *timer, clockid_t which_clock, + enum hrtimer_mode mode); +int (*hrtimer_start_p)(struct hrtimer *timer, ktime_t tim, + const enum hrtimer_mode mode); +int (*hrtimer_cancel_p)(struct hrtimer *timer); diff --git a/kernel/external-module-compat.h b/kernel/external-module-compat.h index 21546b40..642f4058 100644 --- a/kernel/external-module-compat.h +++ b/kernel/external-module-compat.h @@ -624,3 +624,69 @@ static inline void unregister_shrinker(struct kvm_shrinker *shrinker) #define shrinker kvm_shrinker #endif + +/* undefine lapic */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) + +#undef lapic + +#endif + +/* clocksource */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) +static inline u32 clocksource_khz2mult(u32 khz, u32 shift_constant) +{ + /* khz = cyc/(Million ns) + * mult/2^shift = ns/cyc + * mult = ns/cyc * 2^shift + * mult = 1Million/khz * 2^shift + * mult = 1000000 * 2^shift / khz + * mult = (1000000<<shift) / khz + */ + u64 tmp = ((u64)1000000) << shift_constant; + + tmp += khz/2; /* round for do_div */ + do_div(tmp, khz); + + return (u32)tmp; +} +#else +#include <linux/clocksource.h> +#endif + +/* manually export hrtimer_init/start/cancel */ +#include <linux/kallsyms.h> +extern void (*hrtimer_init_p)(struct hrtimer *timer, clockid_t which_clock, + enum hrtimer_mode mode); +extern int (*hrtimer_start_p)(struct hrtimer *timer, ktime_t tim, + const enum hrtimer_mode mode); +extern int (*hrtimer_cancel_p)(struct hrtimer *timer); + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) && defined(CONFIG_KALLSYMS) +static inline void hrtimer_kallsyms_resolve(void) +{ + hrtimer_init_p = (void *) kallsyms_lookup_name("hrtimer_init"); + BUG_ON(!hrtimer_init_p); + hrtimer_start_p = (void *) kallsyms_lookup_name("hrtimer_start"); + BUG_ON(!hrtimer_start_p); + hrtimer_cancel_p = (void *) kallsyms_lookup_name("hrtimer_cancel"); + BUG_ON(!hrtimer_cancel_p); +} +#else +static inline void hrtimer_kallsyms_resolve(void) +{ + hrtimer_init_p = hrtimer_init; + hrtimer_start_p = hrtimer_start; + hrtimer_cancel_p = hrtimer_cancel; +} +#endif + +/* handle old hrtimer API with data pointer */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17) +static inline void hrtimer_data_pointer(struct hrtimer *timer) +{ + timer->data = (void *)timer; +} +#else +static inline void hrtimer_data_pointer(struct hrtimer *timer) {} +#endif diff --git a/kernel/hack-module.awk b/kernel/hack-module.awk index 455e662c..aa21d5f6 100644 --- a/kernel/hack-module.awk +++ b/kernel/hack-module.awk @@ -61,6 +61,11 @@ /^\t\.name = "kvm"/ { $0 = "\tset_kset_name(\"kvm\")," } /#include <linux\/compiler.h>/ { $0 = "" } +/#include <linux\/clocksource.h>/ { $0 = "" } + +{ sub(/hrtimer_init/, "hrtimer_init_p") } +{ sub(/hrtimer_start/, "hrtimer_start_p") } +{ sub(/hrtimer_cancel/, "hrtimer_cancel_p") } { print } @@ -75,3 +80,13 @@ /local_irq_save/ && vmx_load_host_state { print "\t\tgsbase = vmcs_readl(HOST_GS_BASE);" } + +/\tkvm_init_debug/ { + print "\thrtimer_kallsyms_resolve();" +} +/apic->timer.dev.function =/ { + print "\thrtimer_data_pointer(&apic->timer.dev);" +} +/pt->timer.function =/ { + print "\thrtimer_data_pointer(&pt->timer);" +} |