All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 0/32] New shot at accelerators
@ 2008-10-23 14:18 Glauber Costa
  2008-10-23 13:35 ` [Qemu-devel] " Jan Kiszka
                   ` (33 more replies)
  0 siblings, 34 replies; 80+ messages in thread
From: Glauber Costa @ 2008-10-23 14:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: jan.kiszka, aliguori, jes, avi, dmitry.baryshkov

Hi guys,
 
I'm sending here a new version of the accel patch. It comprises
the cleaned up version I've last sent, plus a few additions

You may want to pay special attention to the additions, since
they are newcomers to the series. To ease your job, they are:

0001-use-anonymous-memory-for-kqemu.patch
0002-protect-exec-all.h-frm-multiple-inclusion.patch
0003-change-definition-of-FILE-for-linux.patch
0005-use-more-meaningful-values-for-kqemu_cpu_exec.patch
0025-provide-accel-hook-for-cpu_exec.patch
0026-provide-two-accelerators-for-kqemu.patch
0027-arch-specific-hooks-for-accelerator.patch
0028-iret-arch-specific-accelerator.patch
0029-sysret-sysexit-arch-specific-accelerator.patch
0030-lcall-lret-arch-specific-accel-hooks.patch
0031-remove-kqemu_is_ok-tests.patch
0032-clean-up-kqemu-code.patch

git users can get a snapshot of it located at

git://git.kernel.org/pub/scm/virt/glommer/qemu-accel.git accel-v2

diffstat and OBP (One Big Patch ;-)) attached.

------
 Makefile.target         |    2 +-
 accel.c                 |   51 +++++++++
 accel.h                 |  171 ++++++++++++++++++++++++++++
 cpu-all.h               |    9 +-
 cpu-exec.c              |   47 +++-----
 dyngen-exec.h           |    6 +
 exec-all.h              |   34 +-----
 exec.c                  |  115 ++++++++++----------
 hw/pc.c                 |   13 +--
 kqemu.c                 |  284 +++++++++++++++++++++++++++++++++++++++++++----
 kqemu.h                 |   21 ++++
 monitor.c               |   70 +++++-------
 osdep.c                 |  111 ------------------
 softmmu_template.h      |   10 +-
 sysemu.h                |    5 -
 target-i386/accel86.h   |   60 ++++++++++
 target-i386/cpu.h       |   13 --
 target-i386/helper.c    |    8 +-
 target-i386/op_helper.c |   52 ++-------
 vl.c                    |   93 ++++++----------
 20 files changed, 736 insertions(+), 439 deletions(-)
diff --git a/Makefile.target b/Makefile.target
index e2edf9d..623ecd8 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -188,7 +188,7 @@ all: $(PROGS)
 #########################################################
 # cpu emulator library
 LIBOBJS=exec.o kqemu.o translate-all.o cpu-exec.o\
-        translate.o host-utils.o
+        translate.o host-utils.o accel.o
 ifdef CONFIG_DYNGEN_OP
 exec.o: dyngen-opc.h
 LIBOBJS+=op.o
diff --git a/accel.c b/accel.c
new file mode 100644
index 0000000..8d635f0
--- /dev/null
+++ b/accel.c
@@ -0,0 +1,51 @@
+#include "hw/hw.h"
+#include "exec-all.h"
+#include "accel.h"
+
+QEMUAccel *current_accel;
+QEMUCont *head = NULL;
+
+int _accel_nop(void)
+{
+    return 0;
+}
+
+int noaccel_info(CPUState *env, char *buf)
+{
+    return snprintf(buf, MAX_INFO_BUF, "no accelerator present.\n");
+}
+
+CPUState *noaccel_get_env(void)
+{
+    return qemu_mallocz(sizeof(CPUState));
+}
+
+int noaccel_cpu_exec(CPUState *env)
+{
+    return EXEC_EXIT_SOFTMMU;
+}
+
+#define accel_nop ((void *)_accel_nop)
+
+/* Accelerator wrapper for the no-accel (raw qemu) case */
+QEMUAccel noaccel = {
+    .name = "none",
+    .cpu_interrupt = accel_nop,
+    .init_env = accel_nop,
+    .get_env = noaccel_get_env,
+    .start = accel_nop,
+    .flush_cache = accel_nop,
+    .flush_page = accel_nop,
+    .info = noaccel_info,
+    .profile = accel_nop,
+    .set_notdirty = accel_nop,
+    .modify_page = accel_nop,
+#ifndef CONFIG_USER_ONLY
+    .get_real_ticks = cpu_get_ticks,
+#endif
+    .register_physical_memory = accel_nop,
+    .trace_io = accel_nop,
+    .break_loop = accel_nop,
+    .cpu_exec = noaccel_cpu_exec,
+};
+
diff --git a/accel.h b/accel.h
new file mode 100644
index 0000000..00a495c
--- /dev/null
+++ b/accel.h
@@ -0,0 +1,171 @@
+#ifndef _ACCEL_H_
+#define _ACCEL_H_
+
+#define MAX_INFO_BUF 1024
+
+typedef struct QEMUAccel {
+    char *name;
+    void (*cpu_interrupt)(CPUState *env);
+    CPUState *(*get_env)(void);
+    void (*init_env)(CPUState *env);
+    int (*start)(int cpus);
+    void (*flush_cache)(CPUState *env, int global);
+    void (*flush_page)(CPUState *env, target_ulong addr);
+    int (*info)(CPUState *env, char *buf);
+    int (*profile)(CPUState *env, char *buf);
+    void (*set_notdirty)(ram_addr_t addr);
+    void (*modify_page)(ram_addr_t addr, int dirty_flags);
+#ifndef CONFIG_USER_ONLY
+    uint64_t (*get_real_ticks)(void);
+#endif
+    void (*register_physical_memory)(uint64_t start_addr,
+                                     ram_addr_t size, ram_addr_t phys_offset);
+    void (*trace_io)(CPUState *env);
+    int (*break_loop)(CPUState *env);
+    int (*cpu_exec)(CPUState *env);
+    void *arch; /* arch-specific accel functions */
+} QEMUAccel;
+
+typedef struct QEMUCont {
+    QEMUAccel *acc;
+    int active;
+    struct QEMUCont *next;
+} QEMUCont;
+
+extern QEMUAccel *current_accel;
+extern QEMUAccel noaccel;
+#ifdef USE_KQEMU
+extern QEMUAccel kqemu_accel;
+extern QEMUAccel kqemu_kernel_accel;
+#endif
+
+extern QEMUCont *head;
+void *qemu_mallocz(size_t size);
+extern CPUState *noaccel_get_env(void);
+
+static inline int register_qemu_accel(QEMUAccel *accel)
+{
+    QEMUCont *new, *tmp, *last = NULL;
+
+    for (tmp = head, last; tmp; tmp = tmp->next) {
+        /* we disallow registering the same accelerator twice */
+        if (tmp->acc ==  accel)
+            return -1;
+
+        if (!tmp->next)
+            last = tmp;
+    }
+
+    new = qemu_mallocz(sizeof(*head));
+
+    new->acc = accel;
+    new->active = 0;
+    new->next = NULL;
+
+    if (!head)
+        head = new;
+    else
+        last->next = new;
+
+    return 0;
+}
+
+static inline QEMUCont *get_accel_head(void)
+{
+    return head;
+}
+
+static inline void accel_cpu_interrupt(CPUState *env)
+{
+    current_accel->cpu_interrupt(env);
+}
+
+static inline int accel_start(int cpus)
+{
+    int status = -1;
+    /* The top accelerator in the list gets tried first, but if it fails,
+     * keep trying until one of them succeeds or we exhaust the list */
+    QEMUCont *tmp = head;
+    while (tmp) {
+        if (tmp->acc && tmp->acc->start && (!(tmp->acc->start(cpus))) ) {
+            tmp->active = 1;
+            current_accel = tmp->acc;
+            status = 0;
+            break;
+        }
+        tmp = tmp->next;
+    }
+    return status;
+}
+
+static inline CPUState *accel_get_env(void)
+{
+    return current_accel->get_env();
+}
+
+static inline void accel_init_env(CPUState *env)
+{
+    current_accel->init_env(env);
+}
+
+static inline void accel_flush_cache(CPUState *env, int global)
+{
+    current_accel->flush_cache(env, global);
+}
+
+static inline void accel_flush_page(CPUState *env, target_ulong addr)
+{
+    current_accel->flush_page(env, addr);
+}
+
+static inline int accel_info(CPUState *env, char *buf)
+{
+    return current_accel->info(env, buf);
+}
+
+static inline int accel_profile(CPUState *env, char *buf)
+{
+   return current_accel->profile(env, buf);
+}
+
+static inline void accel_set_notdirty(target_ulong addr)
+{
+    current_accel->set_notdirty(addr);
+}
+
+static inline void accel_modify_page(target_ulong addr, int dirty_flags)
+{
+    current_accel->modify_page(addr, dirty_flags);
+}
+
+int64_t cpu_get_ticks(void);
+
+#ifndef CONFIG_USER_ONLY
+static inline uint64_t accel_get_real_ticks(void)
+{
+   return current_accel->get_real_ticks();
+}
+#endif
+
+static inline void accel_register_phys_mem(uint64_t start_addr,
+                                           ram_addr_t size,
+                                           ram_addr_t phys_offset)
+{
+    current_accel->register_physical_memory(start_addr, size, phys_offset);
+}
+
+static inline void accel_trace_io(CPUState *env)
+{
+    current_accel->trace_io(env);
+}
+
+static inline int accel_break_loop(CPUState *env)
+{
+    return current_accel->break_loop(env);
+}
+
+static inline int accel_cpu_exec(CPUState *env)
+{
+    return current_accel->cpu_exec(env);
+}
+#endif
diff --git a/cpu-all.h b/cpu-all.h
index cdd79bc..edefb45 100644
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -863,6 +863,10 @@ extern ram_addr_t ram_size;
 typedef void CPUWriteMemoryFunc(void *opaque, target_phys_addr_t addr, uint32_t value);
 typedef uint32_t CPUReadMemoryFunc(void *opaque, target_phys_addr_t addr);
 
+/* this is a private version, meant for internal use of accelerators */
+void __cpu_register_physical_memory(target_phys_addr_t start_addr,
+                                  ram_addr_t size,
+                                  ram_addr_t phys_offset);
 void cpu_register_physical_memory(target_phys_addr_t start_addr,
                                   ram_addr_t size,
                                   ram_addr_t phys_offset);
@@ -1077,14 +1081,9 @@ static inline int64_t profile_getclock(void)
     return cpu_get_real_ticks();
 }
 
-extern int64_t kqemu_time, kqemu_time_start;
 extern int64_t qemu_time, qemu_time_start;
 extern int64_t tlb_flush_time;
-extern int64_t kqemu_exec_count;
 extern int64_t dev_time;
-extern int64_t kqemu_ret_int_count;
-extern int64_t kqemu_ret_excp_count;
-extern int64_t kqemu_ret_intr_count;
 #endif
 
 #endif /* CPU_ALL_H */
diff --git a/cpu-exec.c b/cpu-exec.c
index 6d4dcdd..a0b6055 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -36,6 +36,7 @@
 #include <signal.h>
 #include <sys/ucontext.h>
 #endif
+#include "accel.h"
 
 #if defined(__sparc__) && !defined(HOST_SOLARIS)
 // Work around ugly bugs in glibc that mangle global register contents
@@ -335,31 +336,23 @@ int cpu_exec(CPUState *env1)
                 }
                 env->exception_index = -1;
             }
-#ifdef USE_KQEMU
-            if (kqemu_is_ok(env) && env->interrupt_request == 0) {
-                int ret;
-                env->eflags = env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK);
-                ret = kqemu_cpu_exec(env);
-                /* put eflags in CPU temporary format */
-                CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
-                DF = 1 - (2 * ((env->eflags >> 10) & 1));
-                CC_OP = CC_OP_EFLAGS;
-                env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
-                if (ret == 1) {
-                    /* exception */
-                    longjmp(env->jmp_env, 1);
-                } else if (ret == 2) {
-                    /* softmmu execution needed */
+
+            env->eflags = env->eflags | cc_table[CC_OP].compute_all()  | (DF & DF_MASK);
+            ret = accel_cpu_exec(env);
+            env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
+            if (ret == EXEC_EXIT_INTR) {
+                /* exception */
+                longjmp(env->jmp_env, 1);
+            } else if (ret == EXEC_EXIT_SOFTMMU) {
+                /* softmmu execution needed */
+            } else {
+                if (env->interrupt_request != 0) {
+                    /* hardware interrupt will be executed just after */
                 } else {
-                    if (env->interrupt_request != 0) {
-                        /* hardware interrupt will be executed just after */
-                    } else {
-                        /* otherwise, we restart */
-                        longjmp(env->jmp_env, 1);
-                    }
+                    /* otherwise, we restart */
+                    longjmp(env->jmp_env, 1);
                 }
             }
-#endif
 
             next_tb = 0; /* force lookup of first TB */
             for(;;) {
@@ -605,7 +598,7 @@ int cpu_exec(CPUState *env1)
                 {
                     if (next_tb != 0 &&
 #ifdef USE_KQEMU
-                        (env->kqemu_enabled != 2) &&
+                        (!kqemu_kernel_enabled(env)) &&
 #endif
                         tb->page_addr[1] == -1) {
                     tb_add_jump((TranslationBlock *)(next_tb & ~3), next_tb & 3, tb);
@@ -653,13 +646,7 @@ int cpu_exec(CPUState *env1)
                 }
                 /* reset soft MMU for next block (it can currently
                    only be set by a memory fault) */
-#if defined(USE_KQEMU)
-#define MIN_CYCLE_BEFORE_SWITCH (100 * 1000)
-                if (kqemu_is_ok(env) &&
-                    (cpu_get_time_fast() - env->last_io_time) >= MIN_CYCLE_BEFORE_SWITCH) {
-                    cpu_loop_exit();
-                }
-#endif
+                accel_break_loop(env);
             } /* for(;;) */
         } else {
             env_to_regs();
diff --git a/dyngen-exec.h b/dyngen-exec.h
index 9260b6f..826ff46 100644
--- a/dyngen-exec.h
+++ b/dyngen-exec.h
@@ -27,6 +27,10 @@
 #define _FILEDEFED
 #endif
 
+#ifdef __linux__
+#define __FILE_defined
+#endif
+
 /* NOTE: standard headers should be used with special care at this
    point because host CPU registers are used as global variables. Some
    host headers do not allow that. */
@@ -84,6 +88,8 @@ typedef void * host_reg_t;
 
 #ifdef _BSD
 typedef struct __sFILE FILE;
+#elif defined(__linux__)
+typedef struct _IO_FILE FILE;
 #else
 typedef struct FILE FILE;
 #endif
diff --git a/exec-all.h b/exec-all.h
index 6609c9a..fa4a4eb 100644
--- a/exec-all.h
+++ b/exec-all.h
@@ -18,6 +18,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#ifndef _EXEC_ALL_H_
+#define _EXEC_ALL_H_
 /* allow to see translation results - the slowdown should be negligible, so we leave it */
 #define DEBUG_DISAS
 
@@ -354,34 +356,8 @@ static inline int can_do_io(CPUState *env)
 }
 #endif
 
-#ifdef USE_KQEMU
-#define KQEMU_MODIFY_PAGE_MASK (0xff & ~(VGA_DIRTY_FLAG | CODE_DIRTY_FLAG))
-
-#define MSR_QPI_COMMBASE 0xfabe0010
-
-int kqemu_init(CPUState *env);
-int kqemu_cpu_exec(CPUState *env);
-void kqemu_flush_page(CPUState *env, target_ulong addr);
-void kqemu_flush(CPUState *env, int global);
-void kqemu_set_notdirty(CPUState *env, ram_addr_t ram_addr);
-void kqemu_modify_page(CPUState *env, ram_addr_t ram_addr);
-void kqemu_set_phys_mem(uint64_t start_addr, ram_addr_t size, 
-                        ram_addr_t phys_offset);
-void kqemu_cpu_interrupt(CPUState *env);
-void kqemu_record_dump(void);
-
-extern uint32_t kqemu_comm_base;
-
-static inline int kqemu_is_ok(CPUState *env)
-{
-    return(env->kqemu_enabled &&
-           (env->cr[0] & CR0_PE_MASK) &&
-           !(env->hflags & HF_INHIBIT_IRQ_MASK) &&
-           (env->eflags & IF_MASK) &&
-           !(env->eflags & VM_MASK) &&
-           (env->kqemu_enabled == 2 ||
-            ((env->hflags & HF_CPL_MASK) == 3 &&
-             (env->eflags & IOPL_MASK) != IOPL_MASK)));
-}
+#define EXEC_EXIT_DONE 0
+#define EXEC_EXIT_INTR 1
+#define EXEC_EXIT_SOFTMMU 2
 
 #endif
diff --git a/exec.c b/exec.c
index f1fcec8..7fe7eeb 100644
--- a/exec.c
+++ b/exec.c
@@ -43,6 +43,8 @@
 #include <qemu.h>
 #endif
 
+#include "accel.h"
+
 //#define DEBUG_TB_INVALIDATE
 //#define DEBUG_FLUSH
 //#define DEBUG_TLB
@@ -524,25 +526,31 @@ static int cpu_common_load(QEMUFile *f, void *opaque, int version_id)
 }
 #endif
 
-void cpu_exec_init(CPUState *env)
+int next_cpu_index(void)
 {
     CPUState **penv;
-    int cpu_index;
+    int cpu_index = 0;
 
-    env->next_cpu = NULL;
     penv = &first_cpu;
-    cpu_index = 0;
+
     while (*penv != NULL) {
         penv = (CPUState **)&(*penv)->next_cpu;
         cpu_index++;
     }
-    env->cpu_index = cpu_index;
+    return cpu_index;
+}
+
+void cpu_exec_init(CPUState *env)
+{
+    env->next_cpu = NULL;
+    env->cpu_index = next_cpu_index();
     env->nb_watchpoints = 0;
-    *penv = env;
+    if (env->cpu_index == 0)
+        first_cpu = env;
 #if defined(CPU_SAVE_VERSION) && !defined(CONFIG_USER_ONLY)
-    register_savevm("cpu_common", cpu_index, CPU_COMMON_SAVE_VERSION,
+    register_savevm("cpu_common", env->cpu_index, CPU_COMMON_SAVE_VERSION,
                     cpu_common_save, cpu_common_load, env);
-    register_savevm("cpu", cpu_index, CPU_SAVE_VERSION,
+    register_savevm("cpu", env->cpu_index, CPU_SAVE_VERSION,
                     cpu_save, cpu_load, env);
 #endif
 }
@@ -1427,6 +1435,7 @@ void cpu_single_step(CPUState *env, int enabled)
         tb_flush(env);
     }
 #endif
+    accel_cpu_interrupt(env);
 }
 
 /* enable or disable low levels log */
@@ -1678,11 +1687,8 @@ void tlb_flush(CPUState *env, int flush_global)
 
     memset (env->tb_jmp_cache, 0, TB_JMP_CACHE_SIZE * sizeof (void *));
 
-#ifdef USE_KQEMU
-    if (env->kqemu_enabled) {
-        kqemu_flush(env, flush_global);
-    }
-#endif
+    accel_flush_cache(env, flush_global);
+
     tlb_flush_count++;
 }
 
@@ -1724,11 +1730,7 @@ void tlb_flush_page(CPUState *env, target_ulong addr)
 
     tlb_flush_jmp_cache(env, addr);
 
-#ifdef USE_KQEMU
-    if (env->kqemu_enabled) {
-        kqemu_flush_page(env, addr);
-    }
-#endif
+    accel_flush_page(env, addr);
 }
 
 /* update the TLBs so that writes to code in the virtual page 'addr'
@@ -1775,18 +1777,14 @@ void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end,
     if (length == 0)
         return;
     len = length >> TARGET_PAGE_BITS;
-#ifdef USE_KQEMU
-    /* XXX: should not depend on cpu context */
-    env = first_cpu;
-    if (env->kqemu_enabled) {
-        ram_addr_t addr;
-        addr = start;
-        for(i = 0; i < len; i++) {
-            kqemu_set_notdirty(env, addr);
-            addr += TARGET_PAGE_SIZE;
-        }
+
+    ram_addr_t addr;
+    addr = start;
+    for(i = 0; i < len; i++) {
+        accel_set_notdirty(addr);
+        addr += TARGET_PAGE_SIZE;
     }
-#endif
+
     mask = ~dirty_flags;
     p = phys_ram_dirty + (start >> TARGET_PAGE_BITS);
     for(i = 0; i < len; i++)
@@ -2191,12 +2189,13 @@ static void *subpage_init (target_phys_addr_t base, ram_addr_t *phys,
         }                                                               \
     } while (0)
 
-/* register physical memory. 'size' must be a multiple of the target
-   page size. If (phys_offset & ~TARGET_PAGE_MASK) != 0, then it is an
-   io memory page */
-void cpu_register_physical_memory(target_phys_addr_t start_addr,
-                                  ram_addr_t size,
-                                  ram_addr_t phys_offset)
+/* Use this version of cpu registering physical memory in accel-specific code. It exists
+ * to avoid chicken and egg problems with code that might need to register memory in qemu,
+ * but not with the underlying accelerator
+ */
+void __cpu_register_physical_memory(target_phys_addr_t start_addr,
+                                    ram_addr_t size,
+                                    ram_addr_t phys_offset)
 {
     target_phys_addr_t addr, end_addr;
     PhysPageDesc *p;
@@ -2204,13 +2203,6 @@ void cpu_register_physical_memory(target_phys_addr_t start_addr,
     ram_addr_t orig_size = size;
     void *subpage;
 
-#ifdef USE_KQEMU
-    /* XXX: should not depend on cpu context */
-    env = first_cpu;
-    if (env->kqemu_enabled) {
-        kqemu_set_phys_mem(start_addr, size, phys_offset);
-    }
-#endif
     size = (size + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK;
     end_addr = start_addr + (target_phys_addr_t)size;
     for(addr = start_addr; addr != end_addr; addr += TARGET_PAGE_SIZE) {
@@ -2268,6 +2260,18 @@ void cpu_register_physical_memory(target_phys_addr_t start_addr,
     }
 }
 
+/* register physical memory. 'size' must be a multiple of the target
+   page size. If (phys_offset & ~TARGET_PAGE_MASK) != 0, then it is an
+   io memory page */
+void cpu_register_physical_memory(target_phys_addr_t start_addr,
+                                  ram_addr_t size,
+                                  ram_addr_t phys_offset)
+{
+    accel_register_phys_mem(start_addr, size, phys_offset);
+
+    __cpu_register_physical_memory(start_addr, size, phys_offset);
+}
+
 /* XXX: temporary until new memory mapping API */
 ram_addr_t cpu_get_physical_page_desc(target_phys_addr_t addr)
 {
@@ -2383,12 +2387,11 @@ static void notdirty_mem_writeb(void *opaque, target_phys_addr_t ram_addr,
         dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS];
 #endif
     }
+
     stb_p(phys_ram_base + ram_addr, val);
-#ifdef USE_KQEMU
-    if (cpu_single_env->kqemu_enabled &&
-        (dirty_flags & KQEMU_MODIFY_PAGE_MASK) != KQEMU_MODIFY_PAGE_MASK)
-        kqemu_modify_page(cpu_single_env, ram_addr);
-#endif
+
+    accel_modify_page(ram_addr, dirty_flags);
+
     dirty_flags |= (0xff & ~CODE_DIRTY_FLAG);
     phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS] = dirty_flags;
     /* we remove the notdirty callback only if the code has been
@@ -2408,12 +2411,11 @@ static void notdirty_mem_writew(void *opaque, target_phys_addr_t ram_addr,
         dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS];
 #endif
     }
+
     stw_p(phys_ram_base + ram_addr, val);
-#ifdef USE_KQEMU
-    if (cpu_single_env->kqemu_enabled &&
-        (dirty_flags & KQEMU_MODIFY_PAGE_MASK) != KQEMU_MODIFY_PAGE_MASK)
-        kqemu_modify_page(cpu_single_env, ram_addr);
-#endif
+
+    accel_modify_page(ram_addr, dirty_flags);
+
     dirty_flags |= (0xff & ~CODE_DIRTY_FLAG);
     phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS] = dirty_flags;
     /* we remove the notdirty callback only if the code has been
@@ -2433,12 +2435,11 @@ static void notdirty_mem_writel(void *opaque, target_phys_addr_t ram_addr,
         dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS];
 #endif
     }
+
     stl_p(phys_ram_base + ram_addr, val);
-#ifdef USE_KQEMU
-    if (cpu_single_env->kqemu_enabled &&
-        (dirty_flags & KQEMU_MODIFY_PAGE_MASK) != KQEMU_MODIFY_PAGE_MASK)
-        kqemu_modify_page(cpu_single_env, ram_addr);
-#endif
+
+    accel_modify_page(ram_addr, dirty_flags);
+
     dirty_flags |= (0xff & ~CODE_DIRTY_FLAG);
     phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS] = dirty_flags;
     /* we remove the notdirty callback only if the code has been
diff --git a/hw/pc.c b/hw/pc.c
index 34683e7..2f56c1f 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -33,6 +33,7 @@
 #include "boards.h"
 #include "console.h"
 #include "fw_cfg.h"
+#include "accel.h"
 
 /* output Bochs bios info messages */
 //#define DEBUG_BIOS
@@ -75,17 +76,7 @@ static void ioportF0_write(void *opaque, uint32_t addr, uint32_t data)
 /* TSC handling */
 uint64_t cpu_get_tsc(CPUX86State *env)
 {
-    /* Note: when using kqemu, it is more logical to return the host TSC
-       because kqemu does not trap the RDTSC instruction for
-       performance reasons */
-#ifdef USE_KQEMU
-    if (env->kqemu_enabled) {
-        return cpu_get_real_ticks();
-    } else
-#endif
-    {
-        return cpu_get_ticks();
-    }
+    return accel_get_real_ticks();
 }
 
 /* SMM support */
diff --git a/kqemu.c b/kqemu.c
index 4783aa2..58a149b 100644
--- a/kqemu.c
+++ b/kqemu.c
@@ -30,6 +30,7 @@
 #ifdef HOST_SOLARIS
 #include <sys/ioccom.h>
 #endif
+#include "exec.h"
 #include <stdlib.h>
 #include <stdio.h>
 #include <stdarg.h>
@@ -44,12 +45,21 @@
 
 #ifdef USE_KQEMU
 
+#define KQEMU_USER 1
+#define KQEMU_KERNEL 2
+
+static int kqemu_state;
 #define DEBUG
 //#define PROFILE
 
 #include <unistd.h>
 #include <fcntl.h>
 #include "kqemu.h"
+#include "accel86.h"
+
+#ifdef CONFIG_PROFILER
+#include "qemu-timer.h" /* for ticks_per_sec */
+#endif
 
 #ifdef _WIN32
 #define KQEMU_DEVICE "\\\\.\\kqemu"
@@ -69,11 +79,6 @@ int kqemu_fd = KQEMU_INVALID_FD;
 #define kqemu_closefd(x) close(x)
 #endif
 
-/* 0 = not allowed
-   1 = user kqemu
-   2 = kernel kqemu
-*/
-int kqemu_allowed = 1;
 uint64_t *pages_to_flush;
 unsigned int nb_pages_to_flush;
 uint64_t *ram_pages_to_update;
@@ -84,6 +89,13 @@ uint8_t *modified_ram_pages_table;
 int qpi_io_memory;
 uint32_t kqemu_comm_base; /* physical address of the QPI communication page */
 
+static inline int cpu_get_time_fast(void)
+{
+    int low, high;
+    asm volatile("rdtsc" : "=a" (low), "=d" (high));
+    return low;
+}
+
 #define cpuid(index, eax, ebx, ecx, edx) \
   asm volatile ("cpuid" \
                 : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) \
@@ -113,6 +125,19 @@ static int is_cpuid_supported(void)
 }
 #endif
 
+/* FIXME: Should not be needed, since ideally, QEMUAccel would avoid all kqemu tests
+ * altogether
+ */
+int kqemu_is_enabled(CPUState *env)
+{
+    return kqemu_state == KQEMU_USER;
+}
+
+int kqemu_kernel_enabled(CPUState *env)
+{
+    return kqemu_state == KQEMU_KERNEL;
+}
+
 static void kqemu_update_cpuid(CPUState *env)
 {
     int critical_features_mask, features, ext_features, ext_features_mask;
@@ -150,7 +175,9 @@ static void kqemu_update_cpuid(CPUState *env)
        accelerated code */
 }
 
-int kqemu_init(CPUState *env)
+QEMUAccel kqemu_accel;
+
+static int kqemu_do_start(int cpus)
 {
     struct kqemu_init kinit;
     int ret, version;
@@ -158,7 +185,7 @@ int kqemu_init(CPUState *env)
     DWORD temp;
 #endif
 
-    if (!kqemu_allowed)
+    if (cpus > 1)
         return -1;
 
 #ifdef _WIN32
@@ -230,8 +257,6 @@ int kqemu_init(CPUState *env)
         kqemu_fd = KQEMU_INVALID_FD;
         return -1;
     }
-    kqemu_update_cpuid(env);
-    env->kqemu_enabled = kqemu_allowed;
     nb_pages_to_flush = 0;
     nb_ram_pages_to_update = 0;
 
@@ -239,7 +264,24 @@ int kqemu_init(CPUState *env)
     return 0;
 }
 
-void kqemu_flush_page(CPUState *env, target_ulong addr)
+static int kqemu_start(int cpus)
+{
+    kqemu_state = KQEMU_USER;
+    return kqemu_do_start(cpus);
+}
+
+static int kqemu_start_kernel(int cpus)
+{
+    kqemu_state = KQEMU_KERNEL;
+    return kqemu_do_start(cpus);
+}
+
+static void kqemu_init_env(CPUState *env)
+{
+    kqemu_update_cpuid(env);
+}
+
+static void kqemu_flush_page(CPUState *env, target_ulong addr)
 {
 #if defined(DEBUG)
     if (loglevel & CPU_LOG_INT) {
@@ -252,7 +294,7 @@ void kqemu_flush_page(CPUState *env, target_ulong addr)
         pages_to_flush[nb_pages_to_flush++] = addr;
 }
 
-void kqemu_flush(CPUState *env, int global)
+static void kqemu_flush(CPUState *env, int global)
 {
 #ifdef DEBUG
     if (loglevel & CPU_LOG_INT) {
@@ -262,7 +304,7 @@ void kqemu_flush(CPUState *env, int global)
     nb_pages_to_flush = KQEMU_FLUSH_ALL;
 }
 
-void kqemu_set_notdirty(CPUState *env, ram_addr_t ram_addr)
+static void kqemu_set_notdirty(ram_addr_t ram_addr)
 {
 #ifdef DEBUG
     if (loglevel & CPU_LOG_INT) {
@@ -291,7 +333,7 @@ static void kqemu_reset_modified_ram_pages(void)
     nb_modified_ram_pages = 0;
 }
 
-void kqemu_modify_page(CPUState *env, ram_addr_t ram_addr)
+static void kqemu_modify_page(ram_addr_t ram_addr, int dirty_flags)
 {
     unsigned long page_index;
     int ret;
@@ -299,6 +341,8 @@ void kqemu_modify_page(CPUState *env, ram_addr_t ram_addr)
     DWORD temp;
 #endif
 
+    if ((dirty_flags & KQEMU_MODIFY_PAGE_MASK) != KQEMU_MODIFY_PAGE_MASK)
+        return;
     page_index = ram_addr >> TARGET_PAGE_BITS;
     if (!modified_ram_pages_table[page_index]) {
 #if 0
@@ -689,7 +733,7 @@ static inline void kqemu_save_seg(SegmentCache *sc,
     sc->base = ksc->base;
 }
 
-int kqemu_cpu_exec(CPUState *env)
+static int kqemu_do_cpu_exec(CPUState *env)
 {
     struct kqemu_cpu_state kcpu_state, *kenv = &kcpu_state;
     int ret, cpl, i;
@@ -749,7 +793,7 @@ int kqemu_cpu_exec(CPUState *env)
     cpl = (env->hflags & HF_CPL_MASK);
     kenv->cpl = cpl;
     kenv->nb_pages_to_flush = nb_pages_to_flush;
-    kenv->user_only = (env->kqemu_enabled == 1);
+    kenv->user_only = kqemu_is_enabled(env);
     kenv->nb_ram_pages_to_update = nb_ram_pages_to_update;
     nb_ram_pages_to_update = 0;
     kenv->nb_modified_ram_pages = nb_modified_ram_pages;
@@ -891,7 +935,7 @@ int kqemu_cpu_exec(CPUState *env)
             cpu_dump_state(env, logfile, fprintf, 0);
         }
 #endif
-        return 1;
+        return EXEC_EXIT_INTR;
     } else if ((ret & 0xff00) == KQEMU_RET_EXCEPTION) {
         env->exception_index = ret & 0xff;
         env->error_code = kenv->error_code;
@@ -907,7 +951,7 @@ int kqemu_cpu_exec(CPUState *env)
             cpu_dump_state(env, logfile, fprintf, 0);
         }
 #endif
-        return 1;
+        return EXEC_EXIT_INTR;
     } else if (ret == KQEMU_RET_INTR) {
 #ifdef CONFIG_PROFILER
         kqemu_ret_intr_count++;
@@ -917,7 +961,7 @@ int kqemu_cpu_exec(CPUState *env)
             cpu_dump_state(env, logfile, fprintf, 0);
         }
 #endif
-        return 0;
+        return EXEC_EXIT_DONE;
     } else if (ret == KQEMU_RET_SOFTMMU) {
 #ifdef CONFIG_PROFILER
         {
@@ -930,16 +974,31 @@ int kqemu_cpu_exec(CPUState *env)
             cpu_dump_state(env, logfile, fprintf, 0);
         }
 #endif
-        return 2;
+        return EXEC_EXIT_SOFTMMU;
     } else {
         cpu_dump_state(env, stderr, fprintf, 0);
         fprintf(stderr, "Unsupported return value: 0x%x\n", ret);
         exit(1);
     }
-    return 0;
+    return EXEC_EXIT_DONE;
 }
 
-void kqemu_cpu_interrupt(CPUState *env)
+static int kqemu_cpu_exec(CPUState *env)
+{
+
+    int ret = EXEC_EXIT_SOFTMMU;
+    if (kqemu_kernel_flags_ok(env) && env->interrupt_request == 0) {
+        ret = kqemu_do_cpu_exec(env);
+        /* put eflags in CPU temporary format */
+        CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
+        DF = 1 - (2 * ((env->eflags >> 10) & 1));
+        CC_OP = CC_OP_EFLAGS;
+    }
+    return ret;
+}
+
+
+static void kqemu_cpu_interrupt(CPUState *env)
 {
 #if defined(_WIN32)
     /* cancelling the I/O request causes KQEMU to finish executing the
@@ -1019,7 +1078,188 @@ static void qpi_init(void)
     qpi_io_memory = cpu_register_io_memory(0, 
                                            qpi_mem_read, 
                                            qpi_mem_write, NULL);
-    cpu_register_physical_memory(kqemu_comm_base & ~0xfff, 
+    __cpu_register_physical_memory(kqemu_comm_base & ~0xfff,
                                  0x1000, qpi_io_memory);
 }
+
+static int kqemu_info(CPUState *env, char *buf)
+{
+    return snprintf(buf, MAX_INFO_BUF, "kqemu support: enabled for user code\n");
+}
+
+static int kqemu_kernel_info(CPUState *env, char *buf)
+{
+    return snprintf(buf, MAX_INFO_BUF, "kqemu support: enabled for user and kernel code\n");
+}
+
+int64_t kqemu_time;
+int64_t kqemu_exec_count;
+int64_t kqemu_ret_int_count;
+int64_t kqemu_ret_excp_count;
+int64_t kqemu_ret_intr_count;
+extern int64_t qemu_time;
+
+static int kqemu_profile(CPUState *env, char *buf)
+{
+    int len = 0;
+#ifdef CONFIG_PROFILER
+    len = sprintf(buf, "kqemu time  %" PRId64 " (%0.3f %0.1f%%) count=%" PRId64
+                        " int=%" PRId64 " excp=%" PRId64 " intr=%" PRId64 "\n",
+                kqemu_time, kqemu_time / (double)ticks_per_sec,
+                kqemu_time / qemu_time * 100.0,
+                kqemu_exec_count,
+                kqemu_ret_int_count,
+                kqemu_ret_excp_count,
+                kqemu_ret_intr_count);
+
+    kqemu_time = 0;
+    kqemu_exec_count = 0;
+    kqemu_ret_int_count = 0;
+    kqemu_ret_excp_count = 0;
+    kqemu_ret_intr_count = 0;
+    kqemu_record_dump();
+#endif
+    return len;
+}
+
+static void kqemu_trace_io(CPUState *env)
+{
+    if (env)
+        kqemu_cpu_field(env,last_io_time) = cpu_get_time_fast();
+}
+
+#define MIN_CYCLE_BEFORE_SWITCH (100 * 1000)
+
+static inline int kqemu_flags_ok(CPUState *env)
+{
+    return((env->cr[0] & CR0_PE_MASK) &&
+           !(env->hflags & HF_INHIBIT_IRQ_MASK) &&
+           (env->eflags & IF_MASK) &&
+           !(env->eflags & VM_MASK));
+}
+
+static inline int kqemu_kernel_flags_ok(CPUState *env)
+{
+    return (kqemu_flags_ok(env) && (kqemu_kernel_enabled(env) ||
+            ((env->hflags & HF_CPL_MASK) == 3 &&
+             (env->eflags & IOPL_MASK) != IOPL_MASK)));
+
+}
+
+static int kqemu_break_loop(CPUState *env)
+{
+    if (kqemu_kernel_flags_ok(env) &&
+        (cpu_get_time_fast() - kqemu_cpu_field(env,last_io_time)) >= MIN_CYCLE_BEFORE_SWITCH) {
+        return 1;
+    }
+    return 0;
+}
+
+static CPUState *kqemu_get_env(void)
+{
+    KQEMUCPUState *kenv;
+    kenv = qemu_mallocz(sizeof(KQEMUCPUState));
+    return &kenv->env;
+}
+
+static int kqemu_get_msr(int msr, uint64_t *val)
+{
+    int ret = -1;
+    switch (msr) {
+    case MSR_QPI_COMMBASE:
+        val = kqemu_comm_base;
+        ret = 0;
+        break;
+    }
+    return ret;
+}
+
+static int kqemu_set_msr(int msr, target_ulong val)
+{
+    return -1;
+}
+
+static void kqemu_interrupt_return(CPUState *env)
+{
+    if (kqemu_kernel_flags_ok(env)) {
+        CC_OP = CC_OP_EFLAGS;
+        env->exception_index = -1;
+        cpu_loop_exit();
+    }
+}
+
+static void kqemu_syscall_return(CPUState *env)
+{
+    if (kqemu_kernel_flags_ok(env)) {
+        if (env->hflags & HF_LMA_MASK)
+            CC_OP = CC_OP_EFLAGS;
+        env->exception_index = -1;
+        cpu_loop_exit();
+    }
+}
+
+static void kqemu_long_exit_loop(CPUState *env)
+{
+    if (kqemu_kernel_flags_ok(env)) {
+        env->exception_index = -1;
+        cpu_loop_exit();
+    }
+}
+
+QEMUAccel86 kqemu_accel86 = {
+    .get_msr = kqemu_get_msr,
+    .set_msr = kqemu_set_msr,
+    .interrupt_return = kqemu_interrupt_return,
+    .syscall_return = kqemu_syscall_return,
+    .long_call = kqemu_long_exit_loop,
+    .long_ret = kqemu_long_exit_loop,
+};
+
+QEMUAccel kqemu_accel = {
+    .name = "KQEMU",
+    .cpu_interrupt = kqemu_cpu_interrupt,
+    .init_env = kqemu_init_env,
+    .get_env = kqemu_get_env,
+    .start = kqemu_start,
+    .flush_cache = kqemu_flush,
+    .flush_page = kqemu_flush_page,
+    .info = kqemu_info,
+    .profile = kqemu_profile,
+    .set_notdirty = kqemu_set_notdirty,
+    .modify_page = kqemu_modify_page,
+#ifndef CONFIG_USER_ONLY
+    /* Note: when using kqemu, it is more logical to return the host TSC
+       because kqemu does not trap the RDTSC instruction for
+       performance reasons */
+    .get_real_ticks = cpu_get_real_ticks,
+#endif
+    .register_physical_memory = kqemu_set_phys_mem,
+    .trace_io = kqemu_trace_io,
+    .break_loop = kqemu_break_loop,
+    .cpu_exec = kqemu_cpu_exec,
+    .arch = &kqemu_accel86,
+};
+
+QEMUAccel kqemu_kernel_accel = {
+    .name = "kernel-KQEMU",
+    .cpu_interrupt = kqemu_cpu_interrupt,
+    .init_env = kqemu_init_env,
+    .get_env = kqemu_get_env,
+    .start = kqemu_start_kernel,
+    .flush_cache = kqemu_flush,
+    .flush_page = kqemu_flush_page,
+    .info = kqemu_kernel_info,
+    .profile = kqemu_profile,
+    .set_notdirty = kqemu_set_notdirty,
+    .modify_page = kqemu_modify_page,
+#ifndef CONFIG_USER_ONLY
+    .get_real_ticks = cpu_get_real_ticks,
+#endif
+    .register_physical_memory = kqemu_set_phys_mem,
+    .trace_io = kqemu_trace_io,
+    .break_loop = kqemu_break_loop,
+    .cpu_exec = kqemu_cpu_exec,
+    .arch = &kqemu_accel86,
+};
+
 #endif
diff --git a/kqemu.h b/kqemu.h
index ed25c75..4152fbd 100644
--- a/kqemu.h
+++ b/kqemu.h
@@ -32,6 +32,12 @@
 
 #define KQEMU_VERSION 0x010400
 
+extern int64_t kqemu_time, kqemu_time_start;
+extern int64_t kqemu_exec_count;
+extern int64_t kqemu_ret_int_count;
+extern int64_t kqemu_ret_excp_count;
+extern int64_t kqemu_ret_intr_count;
+
 struct kqemu_segment_cache {
     uint16_t selector;
     uint16_t padding1;
@@ -151,4 +157,19 @@ struct kqemu_phys_mem {
 #define KQEMU_SET_PHYS_MEM     _IOW('q', 5, struct kqemu_phys_mem)
 #endif
 
+int kqemu_is_enabled(CPUState *env);
+int kqemu_kernel_enabled(CPUState *env);
+
+typedef struct KQEMUCPUstate {
+    int last_io_time;
+    CPUState env;
+} KQEMUCPUState;
+
+#define kqemu_cpu_field(env, field) (*({ \
+    KQEMUCPUState *__c = container_of(env, KQEMUCPUState, env); \
+    &__c->field; }))
+
+#define KQEMU_MODIFY_PAGE_MASK (0xff & ~(VGA_DIRTY_FLAG | CODE_DIRTY_FLAG))
+
+#define MSR_QPI_COMMBASE 0xfabe0010
 #endif /* KQEMU_H */
diff --git a/monitor.c b/monitor.c
index f0a0bc3..fe915d8 100644
--- a/monitor.c
+++ b/monitor.c
@@ -34,6 +34,7 @@
 #include "block.h"
 #include "audio/audio.h"
 #include "disas.h"
+#include "accel.h"
 #include <dirent.h>
 #include "qemu-timer.h"
 #include "migration.h"
@@ -1233,49 +1234,42 @@ static void mem_info(void)
 }
 #endif
 
-static void do_info_kqemu(void)
+static int do_accel_do_list(void)
 {
-#ifdef USE_KQEMU
+    QEMUCont *tmp;
+    for (tmp= get_accel_head(); tmp != NULL; tmp = tmp->next)
+    {
+        term_printf("%c %s\n", tmp->active ? '*' : ' ', tmp->acc->name);
+    }
+}
+
+static void do_info_accelerator(void)
+{
+    char buf[MAX_INFO_BUF];
     CPUState *env;
-    int val;
-    val = 0;
+
     env = mon_get_cpu();
+
     if (!env) {
         term_printf("No cpu initialized yet");
         return;
     }
-    val = env->kqemu_enabled;
-    term_printf("kqemu support: ");
-    switch(val) {
-    default:
-    case 0:
-        term_printf("disabled\n");
-        break;
-    case 1:
-        term_printf("enabled for user code\n");
-        break;
-    case 2:
-        term_printf("enabled for user and kernel code\n");
-        break;
-    }
-#else
-    term_printf("kqemu support: not compiled\n");
-#endif
+
+    do_accel_do_list();
+    if (accel_info(env, buf))
+        term_printf(buf);
 }
 
 #ifdef CONFIG_PROFILER
 
-int64_t kqemu_time;
 int64_t qemu_time;
-int64_t kqemu_exec_count;
 int64_t dev_time;
-int64_t kqemu_ret_int_count;
-int64_t kqemu_ret_excp_count;
-int64_t kqemu_ret_intr_count;
-
 static void do_info_profile(void)
 {
     int64_t total;
+    char buf[MAX_BUF];
+    CPUState *env = mon_get_cpu();
+
     total = qemu_time;
     if (total == 0)
         total = 1;
@@ -1283,24 +1277,12 @@ static void do_info_profile(void)
                 dev_time, dev_time / (double)ticks_per_sec);
     term_printf("qemu time   %" PRId64 " (%0.3f)\n",
                 qemu_time, qemu_time / (double)ticks_per_sec);
-    term_printf("kqemu time  %" PRId64 " (%0.3f %0.1f%%) count=%" PRId64 " int=%" PRId64 " excp=%" PRId64 " intr=%" PRId64 "\n",
-                kqemu_time, kqemu_time / (double)ticks_per_sec,
-                kqemu_time / (double)total * 100.0,
-                kqemu_exec_count,
-                kqemu_ret_int_count,
-                kqemu_ret_excp_count,
-                kqemu_ret_intr_count);
+    if (accel_profile(env, buf))
+        term_printf(buf);
     qemu_time = 0;
-    kqemu_time = 0;
-    kqemu_exec_count = 0;
     dev_time = 0;
-    kqemu_ret_int_count = 0;
-    kqemu_ret_excp_count = 0;
-    kqemu_ret_intr_count = 0;
-#ifdef USE_KQEMU
-    kqemu_record_dump();
-#endif
 }
+
 #else
 static void do_info_profile(void)
 {
@@ -1493,8 +1475,8 @@ static const term_cmd_t info_cmds[] = {
 #endif
     { "jit", "", do_info_jit,
       "", "show dynamic compiler info", },
-    { "kqemu", "", do_info_kqemu,
-      "", "show kqemu information", },
+    { "accelerator", "", do_info_accelerator,
+      "", "show accelerator information", },
     { "usb", "", usb_info,
       "", "show guest USB devices", },
     { "usbhost", "", usb_host_info,
diff --git a/osdep.c b/osdep.c
index 683aad0..31c96e6 100644
--- a/osdep.c
+++ b/osdep.c
@@ -68,112 +68,9 @@ void qemu_vfree(void *ptr)
 
 #else
 
-#if defined(USE_KQEMU)
-
-#ifdef __OpenBSD__
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/mount.h>
-#else
-#include <sys/vfs.h>
-#endif
-
 #include <sys/mman.h>
 #include <fcntl.h>
 
-static void *kqemu_vmalloc(size_t size)
-{
-    static int phys_ram_fd = -1;
-    static int phys_ram_size = 0;
-    void *ptr;
-
-#ifdef __OpenBSD__ /* no need (?) for a dummy file on OpenBSD */
-    int map_anon = MAP_ANON;
-#else
-    int map_anon = 0;
-    const char *tmpdir;
-    char phys_ram_file[1024];
-#ifdef HOST_SOLARIS
-    struct statvfs stfs;
-#else
-    struct statfs stfs;
-#endif
-
-    if (phys_ram_fd < 0) {
-        tmpdir = getenv("QEMU_TMPDIR");
-        if (!tmpdir)
-#ifdef HOST_SOLARIS
-            tmpdir = "/tmp";
-        if (statvfs(tmpdir, &stfs) == 0) {
-#else
-            tmpdir = "/dev/shm";
-        if (statfs(tmpdir, &stfs) == 0) {
-#endif
-            int64_t free_space;
-            int ram_mb;
-
-            free_space = (int64_t)stfs.f_bavail * stfs.f_bsize;
-            if ((ram_size + 8192 * 1024) >= free_space) {
-                ram_mb = (ram_size / (1024 * 1024));
-                fprintf(stderr,
-                        "You do not have enough space in '%s' for the %d MB of QEMU virtual RAM.\n",
-                        tmpdir, ram_mb);
-                if (strcmp(tmpdir, "/dev/shm") == 0) {
-                    fprintf(stderr, "To have more space available provided you have enough RAM and swap, do as root:\n"
-                            "mount -o remount,size=%dm /dev/shm\n",
-                            ram_mb + 16);
-                } else {
-                    fprintf(stderr,
-                            "Use the '-m' option of QEMU to diminish the amount of virtual RAM or use the\n"
-                            "QEMU_TMPDIR environment variable to set another directory where the QEMU\n"
-                            "temporary RAM file will be opened.\n");
-                }
-                fprintf(stderr, "Or disable the accelerator module with -no-kqemu\n");
-                exit(1);
-            }
-        }
-        snprintf(phys_ram_file, sizeof(phys_ram_file), "%s/qemuXXXXXX",
-                 tmpdir);
-        phys_ram_fd = mkstemp(phys_ram_file);
-        if (phys_ram_fd < 0) {
-            fprintf(stderr,
-                    "warning: could not create temporary file in '%s'.\n"
-                    "Use QEMU_TMPDIR to select a directory in a tmpfs filesystem.\n"
-                    "Using '/tmp' as fallback.\n",
-                    tmpdir);
-            snprintf(phys_ram_file, sizeof(phys_ram_file), "%s/qemuXXXXXX",
-                     "/tmp");
-            phys_ram_fd = mkstemp(phys_ram_file);
-            if (phys_ram_fd < 0) {
-                fprintf(stderr, "Could not create temporary memory file '%s'\n",
-                        phys_ram_file);
-                exit(1);
-            }
-        }
-        unlink(phys_ram_file);
-    }
-    size = (size + 4095) & ~4095;
-    ftruncate(phys_ram_fd, phys_ram_size + size);
-#endif /* !__OpenBSD__ */
-    ptr = mmap(NULL,
-               size,
-               PROT_WRITE | PROT_READ, map_anon | MAP_SHARED,
-               phys_ram_fd, phys_ram_size);
-    if (ptr == MAP_FAILED) {
-        fprintf(stderr, "Could not map physical memory\n");
-        exit(1);
-    }
-    phys_ram_size += size;
-    return ptr;
-}
-
-static void kqemu_vfree(void *ptr)
-{
-    /* may be useful some day, but currently we do not need to free */
-}
-
-#endif
-
 void *qemu_memalign(size_t alignment, size_t size)
 {
 #if defined(_POSIX_C_SOURCE)
@@ -193,10 +90,6 @@ void *qemu_memalign(size_t alignment, size_t size)
 /* alloc shared memory pages */
 void *qemu_vmalloc(size_t size)
 {
-#if defined(USE_KQEMU)
-    if (kqemu_allowed)
-        return kqemu_vmalloc(size);
-#endif
 #ifdef _BSD
     return valloc(size);
 #else
@@ -206,10 +99,6 @@ void *qemu_vmalloc(size_t size)
 
 void qemu_vfree(void *ptr)
 {
-#if defined(USE_KQEMU)
-    if (kqemu_allowed)
-        kqemu_vfree(ptr);
-#endif
     free(ptr);
 }
 
diff --git a/softmmu_template.h b/softmmu_template.h
index 98dd378..4945352 100644
--- a/softmmu_template.h
+++ b/softmmu_template.h
@@ -47,6 +47,8 @@
 #define ADDR_READ addr_read
 #endif
 
+#include "accel.h"
+
 static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
                                                         int mmu_idx,
                                                         void *retaddr);
@@ -75,9 +77,7 @@ static inline DATA_TYPE glue(io_read, SUFFIX)(target_phys_addr_t physaddr,
     res |= (uint64_t)io_mem_read[index][2](io_mem_opaque[index], physaddr + 4) << 32;
 #endif
 #endif /* SHIFT > 2 */
-#ifdef USE_KQEMU
-    env->last_io_time = cpu_get_time_fast();
-#endif
+    accel_trace_io(env);
     return res;
 }
 
@@ -220,9 +220,7 @@ static inline void glue(io_write, SUFFIX)(target_phys_addr_t physaddr,
     io_mem_write[index][2](io_mem_opaque[index], physaddr + 4, val >> 32);
 #endif
 #endif /* SHIFT > 2 */
-#ifdef USE_KQEMU
-    env->last_io_time = cpu_get_time_fast();
-#endif
+    accel_trace_io(env);
 }
 
 void REGPARM glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr,
diff --git a/sysemu.h b/sysemu.h
index 976fecc..5a19626 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -99,11 +99,6 @@ extern int semihosting_enabled;
 extern int old_param;
 extern const char *bootp_filename;
 
-
-#ifdef USE_KQEMU
-extern int kqemu_allowed;
-#endif
-
 #define MAX_OPTION_ROMS 16
 extern const char *option_rom[MAX_OPTION_ROMS];
 extern int nb_option_roms;
diff --git a/target-i386/accel86.h b/target-i386/accel86.h
new file mode 100644
index 0000000..a7ba39b
--- /dev/null
+++ b/target-i386/accel86.h
@@ -0,0 +1,60 @@
+#ifndef _ACCEL_86_H_
+#define _ACCEL_86_H_
+
+#include "accel.h"
+
+typedef struct QEMUAccel86 {
+	int (*get_msr)(int msr, uint64_t *value);
+	int (*set_msr)(int msr, uint64_t value);
+    void (*interrupt_return)(CPUState *env);
+    void (*syscall_return)(CPUState *env);
+    void (*long_call)(CPUState *env);
+    void (*long_ret)(CPUState *env);
+} QEMUAccel86;
+
+#define accel86_call_func ((QEMUAccel86 *)(current_accel->arch))
+
+static inline int accel_get_msr(int msr, uint64_t *value)
+{
+    if (!current_accel->arch)
+        return -1;
+    return accel86_call_func->get_msr(msr, value);
+}
+
+static inline int accel_set_msr(int msr, uint64_t value)
+{
+    if (!current_accel->arch)
+        return -1;
+    return accel86_call_func->set_msr(msr, value);
+}
+
+static inline void accel_interrupt_return(CPUState *env)
+{
+    if (!current_accel->arch)
+        return;
+    accel86_call_func->interrupt_return(env);
+}
+
+static inline void accel_syscall_return(CPUState *env)
+{
+    if (!current_accel->arch)
+        return;
+    accel86_call_func->syscall_return(env);
+}
+
+static inline void accel_long_call(CPUState *env)
+{
+    if (!current_accel->arch)
+        return;
+    accel86_call_func->syscall_return(env);
+}
+
+static inline void accel_long_ret(CPUState *env)
+{
+    if (!current_accel->arch)
+        return;
+    accel86_call_func->syscall_return(env);
+}
+
+#endif
+
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 3c11e0f..e5e91cc 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -606,10 +606,6 @@ typedef struct CPUX86State {
     uint32_t cpuid_ext3_features;
     uint32_t cpuid_apic_id;
 
-#ifdef USE_KQEMU
-    int kqemu_enabled;
-    int last_io_time;
-#endif
     /* in order to simplify APIC support, we leave this pointer to the
        user */
     struct APICState *apic_state;
@@ -727,15 +723,6 @@ void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0);
 #define X86_DUMP_FPU  0x0001 /* dump FPU state too */
 #define X86_DUMP_CCOP 0x0002 /* dump qemu flag cache */
 
-#ifdef USE_KQEMU
-static inline int cpu_get_time_fast(void)
-{
-    int low, high;
-    asm volatile("rdtsc" : "=a" (low), "=d" (high));
-    return low;
-}
-#endif
-
 #define TARGET_PAGE_BITS 12
 
 #define CPUState CPUX86State
diff --git a/target-i386/helper.c b/target-i386/helper.c
index c2e1a88..5ff051f 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -30,6 +30,8 @@
 #include "svm.h"
 #include "qemu-common.h"
 
+#include "accel.h"
+
 //#define DEBUG_MMU
 
 static int cpu_x86_register (CPUX86State *env, const char *cpu_model);
@@ -96,7 +98,7 @@ CPUX86State *cpu_x86_init(const char *cpu_model)
     CPUX86State *env;
     static int inited;
 
-    env = qemu_mallocz(sizeof(CPUX86State));
+    env = accel_get_env();
     if (!env)
         return NULL;
     cpu_exec_init(env);
@@ -112,9 +114,7 @@ CPUX86State *cpu_x86_init(const char *cpu_model)
         return NULL;
     }
     cpu_reset(env);
-#ifdef USE_KQEMU
-    kqemu_init(env);
-#endif
+    accel_init_env(env);
     return env;
 }
 
diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c
index ebb5824..addd42a 100644
--- a/target-i386/op_helper.c
+++ b/target-i386/op_helper.c
@@ -20,6 +20,7 @@
 #define CPU_NO_GLOBAL_REGS
 #include "exec.h"
 #include "host-utils.h"
+#include "accel86.h"
 
 //#define DEBUG_PCALL
 
@@ -1103,14 +1104,7 @@ void helper_sysret(int dflag)
         env->eflags |= IF_MASK;
         cpu_x86_set_cpl(env, 3);
     }
-#ifdef USE_KQEMU
-    if (kqemu_is_ok(env)) {
-        if (env->hflags & HF_LMA_MASK)
-            CC_OP = CC_OP_EFLAGS;
-        env->exception_index = -1;
-        cpu_loop_exit();
-    }
-#endif
+    accel_syscall_return(env);
 }
 
 /* real mode interrupt */
@@ -2623,12 +2617,7 @@ void helper_lcall_protected(int new_cs, target_ulong new_eip,
         SET_ESP(sp, sp_mask);
         EIP = offset;
     }
-#ifdef USE_KQEMU
-    if (kqemu_is_ok(env)) {
-        env->exception_index = -1;
-        cpu_loop_exit();
-    }
-#endif
+    accel_long_call(env);
 }
 
 /* real and vm86 mode iret */
@@ -2917,24 +2906,14 @@ void helper_iret_protected(int shift, int next_eip)
         helper_ret_protected(shift, 1, 0);
     }
     env->hflags2 &= ~HF2_NMI_MASK;
-#ifdef USE_KQEMU
-    if (kqemu_is_ok(env)) {
-        CC_OP = CC_OP_EFLAGS;
-        env->exception_index = -1;
-        cpu_loop_exit();
-    }
-#endif
+
+    accel_interrupt_return(env);
 }
 
 void helper_lret_protected(int shift, int addend)
 {
     helper_ret_protected(shift, 0, addend);
-#ifdef USE_KQEMU
-    if (kqemu_is_ok(env)) {
-        env->exception_index = -1;
-        cpu_loop_exit();
-    }
-#endif
+    accel_long_ret(env);
 }
 
 void helper_sysenter(void)
@@ -3007,12 +2986,6 @@ void helper_sysexit(int dflag)
     }
     ESP = ECX;
     EIP = EDX;
-#ifdef USE_KQEMU
-    if (kqemu_is_ok(env)) {
-        env->exception_index = -1;
-        cpu_loop_exit();
-    }
-#endif
 }
 
 #if defined(CONFIG_USER_ONLY)
@@ -3262,18 +3235,9 @@ void helper_rdmsr(void)
         val = env->kernelgsbase;
         break;
 #endif
-#ifdef USE_KQEMU
-    case MSR_QPI_COMMBASE:
-        if (env->kqemu_enabled) {
-            val = kqemu_comm_base;
-        } else {
-            val = 0;
-        }
-        break;
-#endif
     default:
-        /* XXX: exception ? */
-        val = 0;
+        if (accel_get_msr((uint32_t)ECX, &val) < 0)
+            val = 0;
         break;
     }
     EAX = (uint32_t)(val);
diff --git a/vl.c b/vl.c
index c0e43ac..42720e8 100644
--- a/vl.c
+++ b/vl.c
@@ -140,6 +140,7 @@
 #include "disas.h"
 
 #include "exec-all.h"
+#include "accel.h"
 
 #define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup"
 #define DEFAULT_NETWORK_DOWN_SCRIPT "/etc/qemu-ifdown"
@@ -149,6 +150,8 @@
 #define SMBD_COMMAND "/usr/sbin/smbd"
 #endif
 
+#include "accel.h"
+
 //#define DEBUG_UNUSED_IOPORT
 //#define DEBUG_IOPORT
 //#define DEBUG_NET
@@ -252,6 +255,14 @@ static QEMUTimer *icount_vm_timer;
 
 uint8_t qemu_uuid[16];
 
+QEMUAccel *available_accels[] = {
+/* list of available accelerators */
+#ifdef USE_KQEMU
+    &kqemu_accel,
+    &kqemu_kernel_accel,
+#endif
+};
+
 #define TFR(expr) do { if ((expr) != -1) break; } while (errno == EINTR)
 
 /***********************************************************/
@@ -410,10 +421,7 @@ void cpu_outb(CPUState *env, int addr, int val)
         fprintf(logfile, "outb: %04x %02x\n", addr, val);
 #endif
     ioport_write(0, addr, val);
-#ifdef USE_KQEMU
-    if (env)
-        env->last_io_time = cpu_get_time_fast();
-#endif
+    accel_trace_io(env);
 }
 
 void cpu_outw(CPUState *env, int addr, int val)
@@ -423,10 +431,7 @@ void cpu_outw(CPUState *env, int addr, int val)
         fprintf(logfile, "outw: %04x %04x\n", addr, val);
 #endif
     ioport_write(1, addr, val);
-#ifdef USE_KQEMU
-    if (env)
-        env->last_io_time = cpu_get_time_fast();
-#endif
+    accel_trace_io(env);
 }
 
 void cpu_outl(CPUState *env, int addr, int val)
@@ -436,10 +441,7 @@ void cpu_outl(CPUState *env, int addr, int val)
         fprintf(logfile, "outl: %04x %08x\n", addr, val);
 #endif
     ioport_write(2, addr, val);
-#ifdef USE_KQEMU
-    if (env)
-        env->last_io_time = cpu_get_time_fast();
-#endif
+    accel_trace_io(env);
 }
 
 int cpu_inb(CPUState *env, int addr)
@@ -450,10 +452,7 @@ int cpu_inb(CPUState *env, int addr)
     if (loglevel & CPU_LOG_IOPORT)
         fprintf(logfile, "inb : %04x %02x\n", addr, val);
 #endif
-#ifdef USE_KQEMU
-    if (env)
-        env->last_io_time = cpu_get_time_fast();
-#endif
+    accel_trace_io(env);
     return val;
 }
 
@@ -465,10 +464,7 @@ int cpu_inw(CPUState *env, int addr)
     if (loglevel & CPU_LOG_IOPORT)
         fprintf(logfile, "inw : %04x %04x\n", addr, val);
 #endif
-#ifdef USE_KQEMU
-    if (env)
-        env->last_io_time = cpu_get_time_fast();
-#endif
+    accel_trace_io(env);
     return val;
 }
 
@@ -480,10 +476,7 @@ int cpu_inl(CPUState *env, int addr)
     if (loglevel & CPU_LOG_IOPORT)
         fprintf(logfile, "inl : %04x %08x\n", addr, val);
 #endif
-#ifdef USE_KQEMU
-    if (env)
-        env->last_io_time = cpu_get_time_fast();
-#endif
+    accel_trace_io(env);
     return val;
 }
 
@@ -1317,11 +1310,6 @@ static void host_alarm_handler(int host_signum)
         if (env) {
             /* stop the currently executing cpu because a timer occured */
             cpu_interrupt(env, CPU_INTERRUPT_EXIT);
-#ifdef USE_KQEMU
-            if (env->kqemu_enabled) {
-                kqemu_cpu_interrupt(env);
-            }
-#endif
         }
         event_pending = 1;
     }
@@ -7560,14 +7548,8 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id)
 void qemu_service_io(void)
 {
     CPUState *env = cpu_single_env;
-    if (env) {
+    if (env)
         cpu_interrupt(env, CPU_INTERRUPT_EXIT);
-#ifdef USE_KQEMU
-        if (env->kqemu_enabled) {
-            kqemu_cpu_interrupt(env);
-        }
-#endif
-    }
 }
 
 /***********************************************************/
@@ -8255,10 +8237,6 @@ static void help(int exitcode)
            "-hdachs c,h,s[,t]  force hard disk 0 physical geometry and the optional BIOS\n"
            "                translation (t=none or lba) (usually qemu can guess them)\n"
            "-L path         set the directory for the BIOS, VGA BIOS and keymaps\n"
-#ifdef USE_KQEMU
-           "-kernel-kqemu   enable KQEMU full virtualization (default is user mode only)\n"
-           "-no-kqemu       disable KQEMU kernel module usage\n"
-#endif
 #ifdef TARGET_I386
            "-no-acpi        disable ACPI\n"
 #endif
@@ -8362,8 +8340,7 @@ enum {
     QEMU_OPTION_alt_grab,
     QEMU_OPTION_no_quit,
     QEMU_OPTION_pidfile,
-    QEMU_OPTION_no_kqemu,
-    QEMU_OPTION_kernel_kqemu,
+    QEMU_OPTION_accel,
     QEMU_OPTION_win2k_hack,
     QEMU_OPTION_usb,
     QEMU_OPTION_usbdevice,
@@ -8446,10 +8423,7 @@ static const QEMUOption qemu_options[] = {
     { "hdachs", HAS_ARG, QEMU_OPTION_hdachs },
     { "L", HAS_ARG, QEMU_OPTION_L },
     { "bios", HAS_ARG, QEMU_OPTION_bios },
-#ifdef USE_KQEMU
-    { "no-kqemu", 0, QEMU_OPTION_no_kqemu },
-    { "kernel-kqemu", 0, QEMU_OPTION_kernel_kqemu },
-#endif
+    { "accel", HAS_ARG, QEMU_OPTION_accel},
 #if defined(TARGET_PPC) || defined(TARGET_SPARC)
     { "g", 1, QEMU_OPTION_g },
 #endif
@@ -9264,14 +9238,15 @@ int main(int argc, char **argv)
                 win2k_install_hack = 1;
                 break;
 #endif
-#ifdef USE_KQEMU
-            case QEMU_OPTION_no_kqemu:
-                kqemu_allowed = 0;
-                break;
-            case QEMU_OPTION_kernel_kqemu:
-                kqemu_allowed = 2;
+            case QEMU_OPTION_accel:
+                {
+                    int i;
+                    for (i = 0; i < ARRAY_SIZE(available_accels); i++) {
+                        if (!strcasecmp(optarg, available_accels[i]->name))
+                            register_qemu_accel(available_accels[i]);
+                    }
+                }
                 break;
-#endif
             case QEMU_OPTION_usb:
                 usb_enabled = 1;
                 break;
@@ -9413,6 +9388,9 @@ int main(int argc, char **argv)
         exit(1);
     }
 
+    /* Basic handler for the noaccel case */
+    register_qemu_accel(&noaccel);
+
     if (nographic) {
        if (serial_device_index == 0)
            serial_devices[0] = "stdio";
@@ -9476,10 +9454,6 @@ int main(int argc, char **argv)
         exit(1);
     }
 
-#ifdef USE_KQEMU
-    if (smp_cpus > 1)
-        kqemu_allowed = 0;
-#endif
     linux_boot = (kernel_filename != NULL);
     net_boot = (boot_devices_bitmap >> ('n' - 'a')) & 0xF;
 
@@ -9600,6 +9574,11 @@ int main(int argc, char **argv)
     /* init the dynamic translator */
     cpu_exec_init_all(tb_size * 1024 * 1024);
 
+    if (accel_start(smp_cpus)) {
+	    fprintf(stderr, "qemu: error, no suitable accelerator found\n");
+	    exit(1);
+    }
+
     bdrv_init();
 
     /* we always create the cdrom drive, even if no disk is there */

^ permalink raw reply related	[flat|nested] 80+ messages in thread

end of thread, other threads:[~2008-10-25 11:14 UTC | newest]

Thread overview: 80+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-10-23 14:18 [Qemu-devel] [PATCH 0/32] New shot at accelerators Glauber Costa
2008-10-23 13:35 ` [Qemu-devel] " Jan Kiszka
2008-10-23 14:07   ` Glauber Costa
2008-10-23 14:15     ` Avi Kivity
2008-10-23 13:44 ` Anthony Liguori
2008-10-23 14:18 ` [Qemu-devel] [PATCH 01/32] use anonymous memory for kqemu Glauber Costa
2008-10-23 13:35   ` [Qemu-devel] " Jan Kiszka
2008-10-23 13:48   ` Anthony Liguori
2008-10-23 14:17     ` Jan Kiszka
2008-10-23 14:25       ` Anthony Liguori
2008-10-23 15:08         ` Leonardo Reiter
2008-10-23 15:20           ` Leonardo Reiter
2008-10-24 19:30             ` Andreas Färber
2008-10-24 19:59               ` Ben Taylor
2008-10-25 10:17                 ` [Qemu-devel] QEMU on Solaris 10 (was: [PATCH 01/32] use anonymous memory for kqemu.) Andreas Färber
2008-10-25 10:27                   ` Andreas Färber
2008-10-25 10:45                     ` Blue Swirl
2008-10-24 15:37         ` [Qemu-devel] Re: [PATCH 01/32] use anonymous memory for kqemu Glauber Costa
2008-10-23 14:18 ` [Qemu-devel] [PATCH 02/32] protect exec-all.h frm multiple inclusion Glauber Costa
2008-10-23 13:52   ` [Qemu-devel] " Anthony Liguori
2008-10-23 14:18 ` [Qemu-devel] [PATCH 03/32] change definition of FILE for linux Glauber Costa
2008-10-23 13:52   ` [Qemu-devel] " Anthony Liguori
2008-10-23 14:13     ` Glauber Costa
2008-10-23 14:18 ` [Qemu-devel] [PATCH 04/32] move kqemu_cpu_exec to kqemu.c Glauber Costa
2008-10-23 13:55   ` [Qemu-devel] " Anthony Liguori
2008-10-23 14:21     ` Glauber Costa
2008-10-23 14:18 ` [Qemu-devel] [PATCH 05/32] use more meaningful values for kqemu_cpu_exec Glauber Costa
2008-10-23 13:57   ` [Qemu-devel] " Anthony Liguori
2008-10-23 14:23     ` Glauber Costa
2008-10-23 14:18 ` [Qemu-devel] [PATCH 06/32] split kqemu_init into two Glauber Costa
2008-10-23 13:58   ` [Qemu-devel] " Anthony Liguori
2008-10-23 14:28     ` Glauber Costa
2008-10-23 14:18 ` [Qemu-devel] [PATCH 07/32] introduce QEMUAccel and fill it with interrupt specific driver Glauber Costa
2008-10-23 14:00   ` [Qemu-devel] " Anthony Liguori
2008-10-23 14:18 ` [Qemu-devel] [PATCH 08/32] init env made accel driver Glauber Costa
2008-10-23 14:18 ` [Qemu-devel] [PATCH 09/32] wrap cache flushing functions into accel drivers Glauber Costa
2008-10-23 14:18 ` [Qemu-devel] [PATCH 10/32] turn info kqemu into generic info accelerator Glauber Costa
2008-10-23 14:03   ` [Qemu-devel] " Anthony Liguori
2008-10-23 14:24     ` Glauber Costa
2008-10-23 14:18 ` [Qemu-devel] [PATCH 11/32] separate accelerator part of info profiler Glauber Costa
2008-10-23 14:18 ` [Qemu-devel] [PATCH 12/32] move kqemu externs to kqemu.h Glauber Costa
2008-10-23 14:18 ` [Qemu-devel] [PATCH 13/32] move disabling code to kqemu.c instead of vl.c Glauber Costa
2008-10-23 14:18 ` [Qemu-devel] [PATCH 14/32] set_notdirty goes through accel wrapper Glauber Costa
2008-10-23 14:18 ` [Qemu-devel] [PATCH 15/32] wrap modify_page through accel calls Glauber Costa
2008-10-23 14:19 ` [Qemu-devel] [PATCH 16/32] remove kqemu reference from hw/pc.c Glauber Costa
2008-10-23 14:19 ` [Qemu-devel] [PATCH 17/32] build list of available accelerators Glauber Costa
2008-10-23 13:45   ` [Qemu-devel] " Avi Kivity
2008-10-23 15:09     ` Glauber Costa
2008-10-23 15:15       ` Avi Kivity
2008-10-23 14:19 ` [Qemu-devel] [PATCH 18/32] provide --accel option Glauber Costa
2008-10-23 14:19 ` [Qemu-devel] [PATCH 19/32] add hook to cpu_register_physical_memory Glauber Costa
2008-10-23 14:19 ` [Qemu-devel] [PATCH 20/32] accel_trace_io Glauber Costa
2008-10-23 14:20   ` [Qemu-devel] " Anthony Liguori
2008-10-23 17:26     ` Glauber de Oliveira Costa
2008-10-25 11:10   ` [Qemu-devel] " andrzej zaborowski
2008-10-25 11:14     ` Glauber Costa
2008-10-23 14:19 ` [Qemu-devel] [PATCH 21/32] get_env accel wrapper Glauber Costa
2008-10-23 13:36   ` [Qemu-devel] " Avi Kivity
2008-10-23 14:19 ` [Qemu-devel] [PATCH 22/32] add next_cpu_index Glauber Costa
2008-10-23 14:21   ` [Qemu-devel] " Anthony Liguori
2008-10-23 14:37     ` Glauber Costa
2008-10-23 14:40       ` Jan Kiszka
2008-10-23 14:55         ` Glauber Costa
2008-10-23 14:19 ` [Qemu-devel] [PATCH 23/32] move cpu_get_time_fast to kqemu.c Glauber Costa
2008-10-23 14:19 ` [Qemu-devel] [PATCH 24/32] check wether kqemu is enabled in open code Glauber Costa
2008-10-23 13:38   ` [Qemu-devel] " Jan Kiszka
2008-10-23 14:49     ` Glauber Costa
2008-10-23 14:23   ` Anthony Liguori
2008-10-23 14:31     ` Glauber Costa
2008-10-23 14:19 ` [Qemu-devel] [PATCH 25/32] provide accel hook for cpu_exec Glauber Costa
2008-10-23 14:19 ` [Qemu-devel] [PATCH 26/32] provide two accelerators for kqemu Glauber Costa
2008-10-23 14:19 ` [Qemu-devel] [PATCH 27/32] arch-specific hooks for accelerator Glauber Costa
2008-10-23 13:30   ` [Qemu-devel] " Avi Kivity
2008-10-23 13:35     ` Jan Kiszka
2008-10-23 13:47       ` Avi Kivity
2008-10-23 14:19 ` [Qemu-devel] [PATCH 28/32] iret arch specific accelerator Glauber Costa
2008-10-23 14:19 ` [Qemu-devel] [PATCH 29/32] sysret/sysexit " Glauber Costa
2008-10-23 14:19 ` [Qemu-devel] [PATCH 30/32] lcall/lret arch specific accel hooks Glauber Costa
2008-10-23 14:19 ` [Qemu-devel] [PATCH 31/32] remove kqemu_is_ok tests Glauber Costa
2008-10-23 14:19 ` [Qemu-devel] [PATCH 32/32] clean up kqemu code Glauber Costa

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.