@@ -721,7 +721,7 @@ void qemu_cpu_kick(void *_env)
CPUState *env = _env;
qemu_cond_broadcast(env->halt_cond);
- if (kvm_enabled() && !env->thread_kicked) {
+ if (!env->thread_kicked) {
qemu_cpu_kick_thread(env);
env->thread_kicked = true;
}
@@ -750,17 +750,7 @@ int qemu_cpu_is_self(void *_env)
void qemu_mutex_lock_iothread(void)
{
- if (kvm_enabled()) {
- qemu_mutex_lock(&qemu_global_mutex);
- } else {
- iothread_requesting_mutex = true;
- if (qemu_mutex_trylock(&qemu_global_mutex)) {
- qemu_cpu_kick_thread(first_cpu);
- qemu_mutex_lock(&qemu_global_mutex);
- }
- iothread_requesting_mutex = false;
- qemu_cond_broadcast(&qemu_io_proceeded_cond);
- }
+ qemu_mutex_lock(&qemu_global_mutex);
}
void qemu_mutex_unlock_iothread(void)
@@ -912,7 +902,11 @@ static int tcg_cpu_exec(CPUState *env)
env->icount_decr.u16.low = decr;
env->icount_extra = count;
}
+ qemu_mutex_unlock(&qemu_global_mutex);
+
ret = cpu_exec(env);
+
+ qemu_mutex_lock(&qemu_global_mutex);
#ifdef CONFIG_PROFILER
qemu_time += profile_getclock() - ti;
#endif
@@ -1118,6 +1118,7 @@ void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end,
#endif
#ifdef TARGET_HAS_PRECISE_SMC
if (current_tb_modified) {
+ qemu_mutex_unlock_iothread();
/* we generate a block containing just the instruction
modifying the memory. It will ensure that it cannot modify
itself */
@@ -1205,6 +1206,7 @@ static void tb_invalidate_phys_page(tb_page_addr_t addr,
p->first_tb = NULL;
#ifdef TARGET_HAS_PRECISE_SMC
if (current_tb_modified) {
+ qemu_mutex_unlock_iothread();
/* we generate a block containing just the instruction
modifying the memory. It will ensure that it cannot modify
itself */
@@ -2061,9 +2063,11 @@ void tlb_flush_page(CPUState *env, target_ulong addr)
can be detected */
static void tlb_protect_code(ram_addr_t ram_addr)
{
+ qemu_mutex_lock_iothread();
cpu_physical_memory_reset_dirty(ram_addr,
ram_addr + TARGET_PAGE_SIZE,
CODE_DIRTY_FLAG);
+ qemu_mutex_unlock_iothread();
}
/* update the TLB so that writes in physical page 'phys_addr' are no longer
@@ -3122,11 +3126,13 @@ void *qemu_get_ram_ptr(ram_addr_t addr)
QLIST_FOREACH(block, &ram_list.blocks, next) {
if (addr - block->offset < block->length) {
+#if 0 /* requires RCU - and like also a smarter balancing algorithm */
/* Move this entry to to start of the list. */
if (block != QLIST_FIRST(&ram_list.blocks)) {
QLIST_REMOVE(block, next);
QLIST_INSERT_HEAD(&ram_list.blocks, block, next);
}
+#endif
if (xen_enabled()) {
/* We need to check if the requested address is in the RAM
* because we don't want to map the entire memory in QEMU.
@@ -3417,6 +3423,7 @@ static void check_watchpoint(int offset, int len_mask, int flags)
(vaddr & wp->len_mask) == wp->vaddr) && (wp->flags & flags)) {
wp->flags |= BP_WATCHPOINT_HIT;
if (!env->watchpoint_hit) {
+ qemu_mutex_unlock_iothread();
env->watchpoint_hit = wp;
tb = tb_find_pc(env->mem_io_pc);
if (!tb) {
@@ -4194,6 +4201,7 @@ static inline uint32_t ldl_phys_internal(target_phys_addr_t addr,
io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
if (p)
addr = (addr & ~TARGET_PAGE_MASK) + p->region_offset;
+ qemu_mutex_lock_iothread();
val = io_mem_read[io_index][2](io_mem_opaque[io_index], addr);
#if defined(TARGET_WORDS_BIGENDIAN)
if (endian == DEVICE_LITTLE_ENDIAN) {
@@ -4204,6 +4212,7 @@ static inline uint32_t ldl_phys_internal(target_phys_addr_t addr,
val = bswap32(val);
}
#endif
+ qemu_mutex_unlock_iothread();
} else {
/* RAM case */
ptr = qemu_get_ram_ptr(pd & TARGET_PAGE_MASK) +
@@ -4264,6 +4273,7 @@ static inline uint64_t ldq_phys_internal(target_phys_addr_t addr,
/* XXX This is broken when device endian != cpu endian.
Fix and add "endian" variable check */
+ qemu_mutex_lock_iothread();
#ifdef TARGET_WORDS_BIGENDIAN
val = (uint64_t)io_mem_read[io_index][2](io_mem_opaque[io_index], addr) << 32;
val |= io_mem_read[io_index][2](io_mem_opaque[io_index], addr + 4);
@@ -4271,6 +4281,7 @@ static inline uint64_t ldq_phys_internal(target_phys_addr_t addr,
val = io_mem_read[io_index][2](io_mem_opaque[io_index], addr);
val |= (uint64_t)io_mem_read[io_index][2](io_mem_opaque[io_index], addr + 4) << 32;
#endif
+ qemu_mutex_unlock_iothread();
} else {
/* RAM case */
ptr = qemu_get_ram_ptr(pd & TARGET_PAGE_MASK) +
@@ -4336,6 +4347,7 @@ static inline uint32_t lduw_phys_internal(target_phys_addr_t addr,
io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
if (p)
addr = (addr & ~TARGET_PAGE_MASK) + p->region_offset;
+ qemu_mutex_lock_iothread();
val = io_mem_read[io_index][1](io_mem_opaque[io_index], addr);
#if defined(TARGET_WORDS_BIGENDIAN)
if (endian == DEVICE_LITTLE_ENDIAN) {
@@ -4346,6 +4358,7 @@ static inline uint32_t lduw_phys_internal(target_phys_addr_t addr,
val = bswap16(val);
}
#endif
+ qemu_mutex_unlock_iothread();
} else {
/* RAM case */
ptr = qemu_get_ram_ptr(pd & TARGET_PAGE_MASK) +
@@ -4401,7 +4414,9 @@ void stl_phys_notdirty(target_phys_addr_t addr, uint32_t val)
io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
if (p)
addr = (addr & ~TARGET_PAGE_MASK) + p->region_offset;
+ qemu_mutex_lock_iothread();
io_mem_write[io_index][2](io_mem_opaque[io_index], addr, val);
+ qemu_mutex_unlock_iothread();
} else {
unsigned long addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK);
ptr = qemu_get_ram_ptr(addr1);
@@ -4409,11 +4424,13 @@ void stl_phys_notdirty(target_phys_addr_t addr, uint32_t val)
if (unlikely(in_migration)) {
if (!cpu_physical_memory_is_dirty(addr1)) {
+ qemu_mutex_lock_iothread();
/* invalidate code */
tb_invalidate_phys_page_range(addr1, addr1 + 4, 0);
/* set dirty bit */
cpu_physical_memory_set_dirty_flags(
addr1, (0xff & ~CODE_DIRTY_FLAG));
+ qemu_mutex_unlock_iothread();
}
}
}
@@ -4437,6 +4454,7 @@ void stq_phys_notdirty(target_phys_addr_t addr, uint64_t val)
io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
if (p)
addr = (addr & ~TARGET_PAGE_MASK) + p->region_offset;
+ qemu_mutex_lock_iothread();
#ifdef TARGET_WORDS_BIGENDIAN
io_mem_write[io_index][2](io_mem_opaque[io_index], addr, val >> 32);
io_mem_write[io_index][2](io_mem_opaque[io_index], addr + 4, val);
@@ -4444,6 +4462,7 @@ void stq_phys_notdirty(target_phys_addr_t addr, uint64_t val)
io_mem_write[io_index][2](io_mem_opaque[io_index], addr, val);
io_mem_write[io_index][2](io_mem_opaque[io_index], addr + 4, val >> 32);
#endif
+ qemu_mutex_unlock_iothread();
} else {
ptr = qemu_get_ram_ptr(pd & TARGET_PAGE_MASK) +
(addr & ~TARGET_PAGE_MASK);
@@ -4480,7 +4499,9 @@ static inline void stl_phys_internal(target_phys_addr_t addr, uint32_t val,
val = bswap32(val);
}
#endif
+ qemu_mutex_lock_iothread();
io_mem_write[io_index][2](io_mem_opaque[io_index], addr, val);
+ qemu_mutex_unlock_iothread();
} else {
unsigned long addr1;
addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK);
@@ -4498,11 +4519,13 @@ static inline void stl_phys_internal(target_phys_addr_t addr, uint32_t val,
break;
}
if (!cpu_physical_memory_is_dirty(addr1)) {
+ qemu_mutex_lock_iothread();
/* invalidate code */
tb_invalidate_phys_page_range(addr1, addr1 + 4, 0);
/* set dirty bit */
cpu_physical_memory_set_dirty_flags(addr1,
(0xff & ~CODE_DIRTY_FLAG));
+ qemu_mutex_unlock_iothread();
}
}
}
@@ -4558,7 +4581,9 @@ static inline void stw_phys_internal(target_phys_addr_t addr, uint32_t val,
val = bswap16(val);
}
#endif
+ qemu_mutex_lock_iothread();
io_mem_write[io_index][1](io_mem_opaque[io_index], addr, val);
+ qemu_mutex_unlock_iothread();
} else {
unsigned long addr1;
addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK);
@@ -4576,11 +4601,13 @@ static inline void stw_phys_internal(target_phys_addr_t addr, uint32_t val,
break;
}
if (!cpu_physical_memory_is_dirty(addr1)) {
+ qemu_mutex_lock_iothread();
/* invalidate code */
tb_invalidate_phys_page_range(addr1, addr1 + 2, 0);
/* set dirty bit */
cpu_physical_memory_set_dirty_flags(addr1,
(0xff & ~CODE_DIRTY_FLAG));
+ qemu_mutex_unlock_iothread();
}
}
}
@@ -4604,19 +4631,25 @@ void stw_be_phys(target_phys_addr_t addr, uint32_t val)
void stq_phys(target_phys_addr_t addr, uint64_t val)
{
val = tswap64(val);
+ qemu_mutex_lock_iothread();
cpu_physical_memory_write(addr, &val, 8);
+ qemu_mutex_unlock_iothread();
}
void stq_le_phys(target_phys_addr_t addr, uint64_t val)
{
val = cpu_to_le64(val);
+ qemu_mutex_lock_iothread();
cpu_physical_memory_write(addr, &val, 8);
+ qemu_mutex_unlock_iothread();
}
void stq_be_phys(target_phys_addr_t addr, uint64_t val)
{
val = cpu_to_be64(val);
+ qemu_mutex_lock_iothread();
cpu_physical_memory_write(addr, &val, 8);
+ qemu_mutex_unlock_iothread();
}
/* virtual memory access for debug (includes writing to ROM) */
@@ -96,6 +96,14 @@ static inline char *realpath(const char *path, char *resolved_path)
}
#endif
+#ifndef CONFIG_USER_ONLY
+void qemu_mutex_lock_iothread(void);
+void qemu_mutex_unlock_iothread(void);
+#else
+static inline void qemu_mutex_lock_iothread(void) { }
+static inline void qemu_mutex_unlock_iothread(void) { }
+#endif
+
/* FIXME: Remove NEED_CPU_H. */
#ifndef NEED_CPU_H
@@ -183,9 +191,6 @@ const char *path(const char *pathname);
void *qemu_oom_check(void *ptr);
-void qemu_mutex_lock_iothread(void);
-void qemu_mutex_unlock_iothread(void);
-
int qemu_open(const char *name, int flags, ...);
ssize_t qemu_write_full(int fd, const void *buf, size_t count)
QEMU_WARN_UNUSED_RESULT;
@@ -65,6 +65,8 @@ static inline DATA_TYPE glue(io_read, SUFFIX)(target_phys_addr_t physaddr,
cpu_io_recompile(env, retaddr);
}
+ qemu_mutex_lock_iothread();
+
env->mem_io_vaddr = addr;
#if SHIFT <= 2
res = io_mem_read[index][SHIFT](io_mem_opaque[index], physaddr);
@@ -77,6 +79,8 @@ 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 */
+
+ qemu_mutex_unlock_iothread();
return res;
}
@@ -207,6 +211,8 @@ static inline void glue(io_write, SUFFIX)(target_phys_addr_t physaddr,
cpu_io_recompile(env, retaddr);
}
+ qemu_mutex_lock_iothread();
+
env->mem_io_vaddr = addr;
env->mem_io_pc = (unsigned long)retaddr;
#if SHIFT <= 2
@@ -220,6 +226,8 @@ 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 */
+
+ qemu_mutex_unlock_iothread();
}
void REGPARM glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr,
@@ -662,32 +662,53 @@ void helper_check_iol(uint32_t t0)
void helper_outb(uint32_t port, uint32_t data)
{
+ qemu_mutex_lock_iothread();
cpu_outb(port, data & 0xff);
+ qemu_mutex_unlock_iothread();
}
target_ulong helper_inb(uint32_t port)
{
- return cpu_inb(port);
+ target_ulong ret;
+
+ qemu_mutex_lock_iothread();
+ ret = cpu_inb(port);
+ qemu_mutex_unlock_iothread();
+ return ret;
}
void helper_outw(uint32_t port, uint32_t data)
{
+ qemu_mutex_lock_iothread();
cpu_outw(port, data & 0xffff);
+ qemu_mutex_unlock_iothread();
}
target_ulong helper_inw(uint32_t port)
{
- return cpu_inw(port);
+ target_ulong ret;
+
+ qemu_mutex_lock_iothread();
+ ret = cpu_inw(port);
+ qemu_mutex_unlock_iothread();
+ return ret;
}
void helper_outl(uint32_t port, uint32_t data)
{
+ qemu_mutex_lock_iothread();
cpu_outl(port, data);
+ qemu_mutex_unlock_iothread();
}
target_ulong helper_inl(uint32_t port)
{
- return cpu_inl(port);
+ target_ulong ret;
+
+ qemu_mutex_lock_iothread();
+ ret = cpu_inl(port);
+ qemu_mutex_unlock_iothread();
+ return ret;
}
static inline unsigned int get_sp_mask(unsigned int e2)