diff options
author | Alexander Graf <agraf@suse.de> | 2012-05-10 22:40:10 +0000 |
---|---|---|
committer | Blue Swirl <blauwirbel@gmail.com> | 2012-05-19 15:49:40 +0000 |
commit | 77a8f1a5125457d845fac6aa0c2e1e2681d94f07 (patch) | |
tree | 48ebe6991720d75db8c9b952dc4ed474ef586acd /exec.c | |
parent | 4636b9d1466adde156d469c92d6e7cae7311b81e (diff) | |
download | qemu-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.c | 17 |
1 files changed, 17 insertions, 0 deletions
@@ -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 |