summaryrefslogtreecommitdiff
path: root/exec.c
diff options
context:
space:
mode:
authorAlexander Graf <agraf@suse.de>2012-05-10 22:40:10 +0000
committerBlue Swirl <blauwirbel@gmail.com>2012-05-19 15:49:40 +0000
commit77a8f1a5125457d845fac6aa0c2e1e2681d94f07 (patch)
tree48ebe6991720d75db8c9b952dc4ed474ef586acd /exec.c
parent4636b9d1466adde156d469c92d6e7cae7311b81e (diff)
downloadqemu-77a8f1a5125457d845fac6aa0c2e1e2681d94f07.tar.gz
qemu-77a8f1a5125457d845fac6aa0c2e1e2681d94f07.tar.bz2
qemu-77a8f1a5125457d845fac6aa0c2e1e2681d94f07.zip
linux-user: Fix stale tbs after mmap
If we execute linux-user code that does the following: * A = mmap() * execute code in A * munmap(A) * B = mmap(), but mmap returns the same address as A * execute code in B we end up executing a stale cached tb that contains translated code from A, while we want new code from B. This patch adds a TB flush for mmap'ed regions, before we return them, avoiding the whole issue. It also adds a flush for munmap, so that we don't execute stale TBs instead of getting a segfault. Reported-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Alexander Graf <agraf@suse.de> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Acked-by: Riku Voipio <riku.voipio@linaro.org> Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
Diffstat (limited to 'exec.c')
-rw-r--r--exec.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/exec.c b/exec.c
index 0607c9b6aa..a0494c72bf 100644
--- a/exec.c
+++ b/exec.c
@@ -1075,6 +1075,23 @@ TranslationBlock *tb_gen_code(CPUArchState *env,
return tb;
}
+/*
+ * invalidate all TBs which intersect with the target physical pages
+ * starting in range [start;end[. NOTE: start and end may refer to
+ * different physical pages. 'is_cpu_write_access' should be true if called
+ * from a real cpu write access: the virtual CPU will exit the current
+ * TB if code is modified inside this TB.
+ */
+void tb_invalidate_phys_range(tb_page_addr_t start, tb_page_addr_t end,
+ int is_cpu_write_access)
+{
+ while (start < end) {
+ tb_invalidate_phys_page_range(start, end, is_cpu_write_access);
+ start &= TARGET_PAGE_MASK;
+ start += TARGET_PAGE_SIZE;
+ }
+}
+
/* invalidate all TBs which intersect with the target physical page
starting in range [start;end[. NOTE: start and end must refer to
the same physical page. 'is_cpu_write_access' should be true if called