Unbreak large mem support by removing kqemu

kqemu introduces a number of restrictions on the i386 target.  The worst is that
it prevents large memory from working in the default build.

Furthermore, kqemu is fundamentally flawed in a number of ways.  It relies on
the TSC as a time source which will not be reliable on a multiple processor
system in userspace.  Since most modern processors are multicore, this severely
limits the utility of kqemu.

kvm is a viable alternative for people looking to accelerate qemu and has the
benefit of being supported by the upstream Linux kernel.  If someone can
implement work arounds to remove the restrictions introduced by kqemu, I'm
happy to avoid and/or revert this patch.

N.B. kqemu will still function in the 0.11 series but this patch removes it from
the 0.12 series.

Paul, please Ack or Nack this patch.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
Anthony Liguori
2009-08-10 17:07:24 -05:00
parent 0953a80f04
commit 4a1418e07b
24 changed files with 8 additions and 1722 deletions

91
exec.c
View File

@@ -70,12 +70,11 @@
#define TARGET_VIRT_ADDR_SPACE_BITS 42
#elif defined(TARGET_PPC64)
#define TARGET_PHYS_ADDR_SPACE_BITS 42
#elif defined(TARGET_X86_64) && !defined(CONFIG_KQEMU)
#elif defined(TARGET_X86_64)
#define TARGET_PHYS_ADDR_SPACE_BITS 42
#elif defined(TARGET_I386) && !defined(CONFIG_KQEMU)
#elif defined(TARGET_I386)
#define TARGET_PHYS_ADDR_SPACE_BITS 36
#else
/* Note: for compatibility with kqemu, we use 32 bits for x86_64 */
#define TARGET_PHYS_ADDR_SPACE_BITS 32
#endif
@@ -1763,11 +1762,6 @@ void tlb_flush(CPUState *env, int flush_global)
memset (env->tb_jmp_cache, 0, TB_JMP_CACHE_SIZE * sizeof (void *));
#ifdef CONFIG_KQEMU
if (env->kqemu_enabled) {
kqemu_flush(env, flush_global);
}
#endif
tlb_flush_count++;
}
@@ -1801,12 +1795,6 @@ void tlb_flush_page(CPUState *env, target_ulong addr)
tlb_flush_entry(&env->tlb_table[mmu_idx][i], addr);
tlb_flush_jmp_cache(env, addr);
#ifdef CONFIG_KQEMU
if (env->kqemu_enabled) {
kqemu_flush_page(env, addr);
}
#endif
}
/* update the TLBs so that writes to code in the virtual page 'addr'
@@ -1854,18 +1842,6 @@ void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end,
if (length == 0)
return;
len = length >> TARGET_PAGE_BITS;
#ifdef CONFIG_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;
}
}
#endif
mask = ~dirty_flags;
p = phys_ram_dirty + (start >> TARGET_PAGE_BITS);
for(i = 0; i < len; i++)
@@ -2322,13 +2298,6 @@ void cpu_register_physical_memory_offset(target_phys_addr_t start_addr,
ram_addr_t orig_size = size;
void *subpage;
#ifdef CONFIG_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
if (kvm_enabled())
kvm_set_phys_mem(start_addr, size, phys_offset);
@@ -2423,32 +2392,10 @@ void qemu_unregister_coalesced_mmio(target_phys_addr_t addr, ram_addr_t size)
kvm_uncoalesce_mmio_region(addr, size);
}
#ifdef CONFIG_KQEMU
/* XXX: better than nothing */
static ram_addr_t kqemu_ram_alloc(ram_addr_t size)
{
ram_addr_t addr;
if ((last_ram_offset + size) > kqemu_phys_ram_size) {
fprintf(stderr, "Not enough memory (requested_size = %" PRIu64 ", max memory = %" PRIu64 ")\n",
(uint64_t)size, (uint64_t)kqemu_phys_ram_size);
abort();
}
addr = last_ram_offset;
last_ram_offset = TARGET_PAGE_ALIGN(last_ram_offset + size);
return addr;
}
#endif
ram_addr_t qemu_ram_alloc(ram_addr_t size)
{
RAMBlock *new_block;
#ifdef CONFIG_KQEMU
if (kqemu_phys_ram_base) {
return kqemu_ram_alloc(size);
}
#endif
size = TARGET_PAGE_ALIGN(size);
new_block = qemu_malloc(sizeof(*new_block));
@@ -2491,12 +2438,6 @@ void *qemu_get_ram_ptr(ram_addr_t addr)
RAMBlock **prevp;
RAMBlock *block;
#ifdef CONFIG_KQEMU
if (kqemu_phys_ram_base) {
return kqemu_phys_ram_base + addr;
}
#endif
prev = NULL;
prevp = &ram_blocks;
block = ram_blocks;
@@ -2529,12 +2470,6 @@ ram_addr_t qemu_ram_addr_from_host(void *ptr)
RAMBlock *block;
uint8_t *host = ptr;
#ifdef CONFIG_KQEMU
if (kqemu_phys_ram_base) {
return host - kqemu_phys_ram_base;
}
#endif
prev = NULL;
prevp = &ram_blocks;
block = ram_blocks;
@@ -2639,11 +2574,6 @@ static void notdirty_mem_writeb(void *opaque, target_phys_addr_t ram_addr,
#endif
}
stb_p(qemu_get_ram_ptr(ram_addr), val);
#ifdef CONFIG_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
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
@@ -2664,11 +2594,6 @@ static void notdirty_mem_writew(void *opaque, target_phys_addr_t ram_addr,
#endif
}
stw_p(qemu_get_ram_ptr(ram_addr), val);
#ifdef CONFIG_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
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
@@ -2689,11 +2614,6 @@ static void notdirty_mem_writel(void *opaque, target_phys_addr_t ram_addr,
#endif
}
stl_p(qemu_get_ram_ptr(ram_addr), val);
#ifdef CONFIG_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
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
@@ -3044,13 +2964,6 @@ static void io_mem_init(void)
io_mem_watch = cpu_register_io_memory(watch_mem_read,
watch_mem_write, NULL);
#ifdef CONFIG_KQEMU
if (kqemu_phys_ram_base) {
/* alloc dirty bits array */
phys_ram_dirty = qemu_vmalloc(kqemu_phys_ram_size >> TARGET_PAGE_BITS);
memset(phys_ram_dirty, 0xff, kqemu_phys_ram_size >> TARGET_PAGE_BITS);
}
#endif
}
#endif /* !defined(CONFIG_USER_ONLY) */