diff --git a/Makefile.target b/Makefile.target
index aeda3fe..bab1318 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -44,7 +44,7 @@ all: $(PROGS)
 # cpu emulator library
 libobj-y = exec.o cpu-exec.o host-utils.o
 ifeq ($(NO_CPU_EMULATION), 1)
-libobj-y += fack-exec.o
+libobj-y += fake-exec.o
 else
 libobj-y += translate-all.o translate.o 
 endif
@@ -57,7 +57,12 @@ libobj-$(CONFIG_NOSOFTFLOAT) += fpu/softfloat-native.o
 libobj-y += op_helper.o helper.o
 libobj-$(CONFIG_NEED_MMU) += mmu.o
 
+ifeq ($(TARGET_ARCH), i386)
 libobj-$(CONFIG_KVM) += kvm-tpr-opt.o
+endif
+ifeq ($(TARGET_ARCH), ia64)
+libobj-$(CONFIG_KVM) += firmware.o
+endif
 libobj-$(CONFIG_KVM) += qemu-kvm-helper.o
 
 libobj-$(TARGET_ARM) += neon_helper.o iwmmxt_helper.o
@@ -220,7 +225,7 @@ LIBS+=-lpci
 endif
 
 # Hardware support
-obj-ia64-y += ide.o pckbd.o vga.o $(SOUND_HW) dma.o $(AUDIODRV)
+obj-ia64-y += ide.o pckbd.o vga.o $(sound-obj-y) dma.o isa-bus.o
 obj-ia64-y += fdc.o mc146818rtc.o serial.o i8259.o ipf.o
 obj-ia64-y += cirrus_vga.o parallel.o acpi.o piix_pci.o
 obj-ia64-y += usb-uhci.o
@@ -322,11 +327,6 @@ obj-sh4-y += ide.o
 obj-m68k-y = an5206.o mcf5206.o mcf_uart.o mcf_intc.o mcf5208.o mcf_fec.o
 obj-m68k-y += m68k-semi.o dummy_m68k.o
 
-ifeq ($(TARGET_ARCH), ia64)
-firmware.o: firmware.c
-	$(CC) $(HELPER_CFLAGS) $(CPPFLAGS) $(BASE_CFLAGS) -c -o $@ $<
-endif
-
 main.o vl.o: QEMU_CFLAGS+=$(GPROF_CFLAGS)
 
 vl.o: QEMU_CFLAGS+=$(SDL_CFLAGS)
diff --git a/configure b/configure
index 719d26a..509d851 100755
--- a/configure
+++ b/configure
@@ -2198,7 +2198,7 @@ case "$target_arch2" in
     fi
 esac
 case "$target_arch2" in
-  i386|x86_64|ppcemb|ppc|ppc64)
+  i386|x86_64|ia64|ppcemb|ppc|ppc64)
     # Make sure the target and host cpus are compatible
     if test "$kvm" = "yes" -a "$target_softmmu" = "yes" -a \
       \( "$target_arch2" = "$cpu" -o \
diff --git a/qemu-kvm-ia64.c b/qemu-kvm-ia64.c
index 062fbd4..e6e8884 100644
--- a/qemu-kvm-ia64.c
+++ b/qemu-kvm-ia64.c
@@ -1,147 +1,81 @@
-#include "config.h"
-#include "config-host.h"
-
+/*
+ * libkvm-ia64.c :Kernel-based Virtual Machine control library for ia64.
+ *
+ * This library provides an API to control the kvm hardware virtualization
+ * module.
+ *
+ * Copyright (C) 2006 Qumranet
+ *
+ * Authors:
+ *
+ *  Avi Kivity <avi@qumranet.com>
+ *  Yaniv Kamay <yaniv@qumranet.com>
+ *
+ * Copyright (C) 2007 Intel
+ * Added by : Zhang Xiantao <xiantao.zhang@intel.com>
+ *
+ * This work is licensed under the GNU LGPL license, version 2.
+ *
+ */
+
+#include "libkvm.h"
+#include <errno.h>
+#include <sys/ioctl.h>
 #include <string.h>
+#include <unistd.h>
+#include <stropts.h>
+#include <sys/mman.h>
+#include <stdio.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdlib.h>
 
-#include "hw/hw.h"
-#include "qemu-kvm.h"
-#include <pthread.h>
-#include <sys/utsname.h>
-#include <sys/io.h>
-
-
-
-int kvm_arch_qemu_create_context(void)
-{
-    return 0;
-}
-
-void kvm_arch_load_regs(CPUState *env)
+int kvm_arch_create(kvm_context_t kvm, unsigned long phys_mem_bytes,
+			void **vm_mem)
 {
-}
+	int r;
 
+	r = kvm_init_coalesced_mmio(kvm);
+	if (r < 0)
+		return r;
 
-void kvm_arch_save_regs(CPUState *env)
-{
+	return 0;
 }
 
-int kvm_arch_init_vcpu(CPUState *cenv)
+int kvm_arch_run(kvm_vcpu_context_t vcpu)
 {
-    return 0;
-}
+	int r = 0;
 
-int kvm_arch_halt(void *opaque, kvm_vcpu_context_t vcpu)
-{
-    CPUState *env = cpu_single_env;
-    env->hflags |= HF_HALTED_MASK;
-    return 1;
-}
+	switch (vcpu->run->exit_reason) {
+		default:
+			r = 1;
+			break;
+	}
 
-void kvm_arch_pre_kvm_run(void *opaque, CPUState *env)
-{
-}
-
-void kvm_arch_post_kvm_run(void *opaque, CPUState *env)
-{
-}
-
-int kvm_arch_has_work(CPUState *env)
-{
-    return 1;
-}
-
-int kvm_arch_try_push_interrupts(void *opaque)
-{
-    return 1;
-}
-
-void kvm_arch_update_regs_for_sipi(CPUState *env)
-{
+	return r;
 }
 
-int kvm_arch_insert_sw_breakpoint(CPUState *current_env,
-                                  struct kvm_sw_breakpoint *bp)
+void kvm_show_code(kvm_vcpu_context_t vcpu)
 {
-    return -EINVAL;
+	fprintf(stderr, "kvm_show_code not supported yet!\n");
 }
 
-int kvm_arch_remove_sw_breakpoint(CPUState *current_env,
-                                  struct kvm_sw_breakpoint *bp)
+void kvm_show_regs(kvm_vcpu_context_t vcpu)
 {
-    return -EINVAL;
+	fprintf(stderr,"kvm_show_regs not supportted today!\n");
 }
 
-int kvm_arch_insert_hw_breakpoint(target_ulong addr,
-				  target_ulong len, int type)
-{
-    return -ENOSYS;
-}
-
-int kvm_arch_remove_hw_breakpoint(target_ulong addr,
-				  target_ulong len, int type)
-{
-    return -ENOSYS;
-}
-
-void kvm_arch_remove_all_hw_breakpoints(void)
-{
-}
-
-int kvm_arch_debug(struct kvm_debug_exit_arch *arch_info)
+int kvm_create_memory_alias(kvm_context_t kvm,
+			    uint64_t phys_start,
+			    uint64_t len,
+			    uint64_t target_phys)
 {
     return 0;
 }
 
-void kvm_arch_update_guest_debug(CPUState *env, struct kvm_guest_debug *dbg)
-{
-}
-
-void kvm_arch_save_mpstate(CPUState *env)
-{
-#ifdef KVM_CAP_MP_STATE
-    int r;
-    struct kvm_mp_state mp_state;
-
-    r = kvm_get_mpstate(env->kvm_cpu_state.vcpu_ctx, &mp_state);
-    if (r < 0)
-        env->mp_state = -1;
-    else
-        env->mp_state = mp_state.mp_state;
-#endif
-}
-
-void kvm_arch_load_mpstate(CPUState *env)
-{
-#ifdef KVM_CAP_MP_STATE
-    struct kvm_mp_state mp_state = { .mp_state = env->mp_state };
-
-    /*
-     * -1 indicates that the host did not support GET_MP_STATE ioctl,
-     *  so don't touch it.
-     */
-    if (env->mp_state != -1)
-        kvm_set_mpstate(env->kvm_cpu_state.vcpu_ctx, &mp_state);
-#endif
-}
-
-void kvm_arch_cpu_reset(CPUState *env)
-{
-    if (kvm_irqchip_in_kernel(kvm_context)) {
-#ifdef KVM_CAP_MP_STATE
-	kvm_reset_mpstate(env->kvm_cpu_state.vcpu_ctx);
-#endif
-    } else {
-	env->interrupt_request &= ~CPU_INTERRUPT_HARD;
-	env->halted = 1;
-    }
-}
-
-void kvm_arch_do_ioperm(void *_data)
-{
-    struct ioperm_data *data = _data;
-    ioperm(data->start_port, data->num, data->turn_on);
-}
-
-void kvm_arch_process_irqchip_events(CPUState *env)
+int kvm_destroy_memory_alias(kvm_context_t kvm, uint64_t phys_start)
 {
+	return 0;
 }
diff --git a/qemu-kvm.c b/qemu-kvm.c
index b59e403..a4e314a 100644
--- a/qemu-kvm.c
+++ b/qemu-kvm.c
@@ -2171,7 +2171,6 @@ void kvm_set_phys_mem(target_phys_addr_t start_addr, ram_addr_t size,
         }
         if (must_use_aliases_target(start_addr))
             return;
-#endif
         while (size > 0) {
             p = find_mapping(start_addr);
             if (p) {
@@ -2186,6 +2185,7 @@ void kvm_set_phys_mem(target_phys_addr_t start_addr, ram_addr_t size,
             }
         }
         return;
+#endif
     }
 
     r = kvm_is_containing_region(kvm_context, start_addr, size);
diff --git a/target-ia64/kvm.c b/target-ia64/kvm.c
new file mode 100644
index 0000000..d01f634
--- /dev/null
+++ b/target-ia64/kvm.c
@@ -0,0 +1,154 @@
+#include "config.h"
+#include "config-host.h"
+
+#include <string.h>
+
+#include "hw/hw.h"
+#include "qemu-kvm.h"
+#include <pthread.h>
+#include <sys/utsname.h>
+#include <sys/io.h>
+
+
+
+int kvm_arch_qemu_create_context(void)
+{
+    return 0;
+}
+
+void kvm_arch_load_regs(CPUState *env)
+{
+}
+
+
+void kvm_arch_save_regs(CPUState *env)
+{
+}
+
+int kvm_arch_qemu_init_env(CPUState *cenv)
+{
+    return 0;
+}
+
+int kvm_arch_halt(void *opaque, kvm_vcpu_context_t vcpu)
+{
+    CPUState *env = cpu_single_env;
+    env->hflags |= HF_HALTED_MASK;
+    return 1;
+}
+
+void kvm_arch_pre_kvm_run(void *opaque, CPUState *env)
+{
+}
+
+void kvm_arch_post_kvm_run(void *opaque, CPUState *env)
+{
+}
+
+int kvm_arch_has_work(CPUState *env)
+{
+    return 1;
+}
+
+int kvm_arch_try_push_interrupts(void *opaque)
+{
+    return 1;
+}
+
+void kvm_arch_update_regs_for_sipi(CPUState *env)
+{
+}
+
+int kvm_arch_insert_sw_breakpoint(CPUState *current_env,
+                                  struct kvm_sw_breakpoint *bp)
+{
+    return -EINVAL;
+}
+
+int kvm_arch_remove_sw_breakpoint(CPUState *current_env,
+                                  struct kvm_sw_breakpoint *bp)
+{
+    return -EINVAL;
+}
+
+int kvm_arch_insert_hw_breakpoint(target_ulong addr,
+				  target_ulong len, int type)
+{
+    return -ENOSYS;
+}
+
+int kvm_arch_remove_hw_breakpoint(target_ulong addr,
+				  target_ulong len, int type)
+{
+    return -ENOSYS;
+}
+
+void kvm_arch_remove_all_hw_breakpoints(void)
+{
+}
+
+int kvm_arch_debug(struct kvm_debug_exit_arch *arch_info)
+{
+    return 0;
+}
+
+void kvm_arch_update_guest_debug(CPUState *env, struct kvm_guest_debug *dbg)
+{
+}
+
+void kvm_arch_save_mpstate(CPUState *env)
+{
+#ifdef KVM_CAP_MP_STATE
+    int r;
+    struct kvm_mp_state mp_state;
+
+    r = kvm_get_mpstate(env->kvm_cpu_state.vcpu_ctx, &mp_state);
+    if (r < 0)
+        env->mp_state = -1;
+    else
+        env->mp_state = mp_state.mp_state;
+#endif
+}
+
+void kvm_arch_load_mpstate(CPUState *env)
+{
+#ifdef KVM_CAP_MP_STATE
+    struct kvm_mp_state mp_state = { .mp_state = env->mp_state };
+
+    /*
+     * -1 indicates that the host did not support GET_MP_STATE ioctl,
+     *  so don't touch it.
+     */
+    if (env->mp_state != -1)
+        kvm_set_mpstate(env->kvm_cpu_state.vcpu_ctx, &mp_state);
+#endif
+}
+
+void kvm_arch_cpu_reset(CPUState *env)
+{
+    if (kvm_irqchip_in_kernel(kvm_context)) {
+#ifdef KVM_CAP_MP_STATE
+	kvm_reset_mpstate(env->kvm_cpu_state.vcpu_ctx);
+#endif
+    } else {
+	env->interrupt_request &= ~CPU_INTERRUPT_HARD;
+	env->halted = 1;
+    }
+}
+
+void kvm_arch_do_ioperm(void *_data)
+{
+    struct ioperm_data *data = _data;
+    ioperm(data->start_port, data->num, data->turn_on);
+}
+
+void kvm_arch_process_irqchip_events(CPUState *env)
+{
+}
+
+int kvm_arch_init_vcpu(CPUState *env)
+{
+    return 0;
+}
+
+#include"qemu-kvm-ia64.c"
diff --git a/target-ia64/libkvm.h b/target-ia64/libkvm.h
index 417f7f1..8e2d413 100644
--- a/target-ia64/libkvm.h
+++ b/target-ia64/libkvm.h
@@ -18,8 +18,6 @@
 #ifndef KVM_IA64_H
 #define KVM_IA64_H
 
-#include "libkvm-all.h"
-
 extern int kvm_page_size;
 
 #define PAGE_SIZE kvm_page_size
diff --git a/target-ia64/op_helper.c b/target-ia64/op_helper.c
index d51525a..3c2e1a2 100644
--- a/target-ia64/op_helper.c
+++ b/target-ia64/op_helper.c
@@ -42,7 +42,6 @@ CPUState *cpu_ia64_init(const char *cpu_model)
     cpu_exec_init(env);
     cpu_reset(env);
     if (kvm_enabled()) {
-        kvm_qemu_init_env(env);
         kvm_init_vcpu(env);
     }
     return env;
@@ -102,3 +101,7 @@ void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr)
 {
     return;
 }
+
+void helper_cpuid(void)
+{
+}
