summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorAndrea Arcangeli <andrea@qumranet.com>2008-05-20 21:25:06 +0200
committerAvi Kivity <avi@qumranet.com>2008-05-21 19:26:19 +0300
commit7913795342296f74ac7ca52e77bf53064f402b9e (patch)
tree213e170199a81f167c969efdf477e4bf959c782e /kernel
parent2a6928da42550f4481ad570a35a76dc711047729 (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/Makefile2
-rw-r--r--kernel/external-module-compat.c7
-rw-r--r--kernel/external-module-compat.h66
-rw-r--r--kernel/hack-module.awk15
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);"
+}