diff options
| author | Peter Maydell <peter.maydell@linaro.org> | 2018-01-25 09:53:53 +0000 |
|---|---|---|
| committer | Peter Maydell <peter.maydell@linaro.org> | 2018-01-25 09:53:53 +0000 |
| commit | 0f79bfe38a2cf0f43c7ea4959da7f8ebd7858f3d (patch) | |
| tree | 80981403f3a897a1e20808e3c7a76fe082ddfc30 /accel/tcg/translate-all.c | |
| parent | f78b6f9b1161fb67f3ac54e73f7f37464cbff76f (diff) | |
| parent | 95d0307cc10ca3df879c1be519f1ad650efb20a8 (diff) | |
| download | focaccia-qemu-0f79bfe38a2cf0f43c7ea4959da7f8ebd7858f3d.tar.gz focaccia-qemu-0f79bfe38a2cf0f43c7ea4959da7f8ebd7858f3d.zip | |
Merge remote-tracking branch 'remotes/vivier2/tags/linux-user-for-2.12-pull-request' into staging
# gpg: Signature made Tue 23 Jan 2018 14:47:41 GMT # gpg: using RSA key 0xF30C38BD3F2FBE3C # gpg: Good signature from "Laurent Vivier <lvivier@redhat.com>" # gpg: aka "Laurent Vivier <laurent@vivier.eu>" # gpg: aka "Laurent Vivier (Red Hat) <lvivier@redhat.com>" # Primary key fingerprint: CD2F 75DD C8E3 A4DC 2E4F 5173 F30C 38BD 3F2F BE3C * remotes/vivier2/tags/linux-user-for-2.12-pull-request: linux-user: implement renameat2 page_unprotect(): handle calls to pages that are PAGE_WRITE linux-user: Propagate siginfo_t through to handle_cpu_signal() linux-user: remove nmi.c and fw-path-provider.c linux-user: Add getcpu() support linux-user: Add AT_SECURE auxval linux-user: Fix sched_get/setaffinity conversion linux-user/mmap.c: Avoid choosing NULL as start address linux-user: Translate flags argument to dup3 syscall linux-user: Don't use CMSG_ALIGN(sizeof struct cmsghdr) linux-user: Fix length calculations in host_to_target_cmsg() linux-user: wrap fork() in a start/end exclusive section linux-user: Fix locking order in fork_start() Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'accel/tcg/translate-all.c')
| -rw-r--r-- | accel/tcg/translate-all.c | 50 |
1 files changed, 31 insertions, 19 deletions
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c index 7736257085..67795cd78c 100644 --- a/accel/tcg/translate-all.c +++ b/accel/tcg/translate-all.c @@ -2181,29 +2181,41 @@ int page_unprotect(target_ulong address, uintptr_t pc) /* if the page was really writable, then we change its protection back to writable */ - if ((p->flags & PAGE_WRITE_ORG) && !(p->flags & PAGE_WRITE)) { - host_start = address & qemu_host_page_mask; - host_end = host_start + qemu_host_page_size; - - prot = 0; + if (p->flags & PAGE_WRITE_ORG) { current_tb_invalidated = false; - for (addr = host_start ; addr < host_end ; addr += TARGET_PAGE_SIZE) { - p = page_find(addr >> TARGET_PAGE_BITS); - p->flags |= PAGE_WRITE; - prot |= p->flags; - - /* and since the content will be modified, we must invalidate - the corresponding translated code. */ - current_tb_invalidated |= tb_invalidate_phys_page(addr, pc); -#ifdef CONFIG_USER_ONLY - if (DEBUG_TB_CHECK_GATE) { - tb_invalidate_check(addr); + if (p->flags & PAGE_WRITE) { + /* If the page is actually marked WRITE then assume this is because + * this thread raced with another one which got here first and + * set the page to PAGE_WRITE and did the TB invalidate for us. + */ +#ifdef TARGET_HAS_PRECISE_SMC + TranslationBlock *current_tb = tb_find_pc(pc); + if (current_tb) { + current_tb_invalidated = tb_cflags(current_tb) & CF_INVALID; } #endif + } else { + host_start = address & qemu_host_page_mask; + host_end = host_start + qemu_host_page_size; + + prot = 0; + for (addr = host_start; addr < host_end; addr += TARGET_PAGE_SIZE) { + p = page_find(addr >> TARGET_PAGE_BITS); + p->flags |= PAGE_WRITE; + prot |= p->flags; + + /* and since the content will be modified, we must invalidate + the corresponding translated code. */ + current_tb_invalidated |= tb_invalidate_phys_page(addr, pc); +#ifdef CONFIG_USER_ONLY + if (DEBUG_TB_CHECK_GATE) { + tb_invalidate_check(addr); + } +#endif + } + mprotect((void *)g2h(host_start), qemu_host_page_size, + prot & PAGE_BITS); } - mprotect((void *)g2h(host_start), qemu_host_page_size, - prot & PAGE_BITS); - mmap_unlock(); /* If current TB was invalidated return to main loop */ return current_tb_invalidated ? 2 : 1; |