[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 2/5] linux-user: fix page_unprotect when host page s
From: |
Aurelien Jarno |
Subject: |
[Qemu-devel] [PATCH 2/5] linux-user: fix page_unprotect when host page size > target page size |
Date: |
Mon, 29 Mar 2010 02:25:51 +0200 |
When the host page size is bigger that the target one, unprotecting a
page should:
- mark all the target pages corresponding to the host page as writable
- invalidate all tb corresponding to the host page (and not the target
page)
Signed-off-by: Aurelien Jarno <address@hidden>
---
exec.c | 45 ++++++++++++++++++++++-----------------------
1 files changed, 22 insertions(+), 23 deletions(-)
diff --git a/exec.c b/exec.c
index 0916208..1b0fe52 100644
--- a/exec.c
+++ b/exec.c
@@ -2447,8 +2447,8 @@ int page_check_range(target_ulong start, target_ulong
len, int flags)
page. Return TRUE if the fault was successfully handled. */
int page_unprotect(target_ulong address, unsigned long pc, void *puc)
{
- unsigned int page_index, prot, pindex;
- PageDesc *p, *p1;
+ unsigned int prot;
+ PageDesc *p;
target_ulong host_start, host_end, addr;
/* Technically this isn't safe inside a signal handler. However we
@@ -2456,37 +2456,36 @@ int page_unprotect(target_ulong address, unsigned long
pc, void *puc)
practice it seems to be ok. */
mmap_lock();
- host_start = address & qemu_host_page_mask;
- page_index = host_start >> TARGET_PAGE_BITS;
- p1 = page_find(page_index);
- if (!p1) {
+ p = page_find(address >> TARGET_PAGE_BITS);
+ if (!p) {
mmap_unlock();
return 0;
}
- host_end = host_start + qemu_host_page_size;
- p = p1;
- prot = 0;
- for(addr = host_start;addr < host_end; addr += TARGET_PAGE_SIZE) {
- prot |= p->flags;
- p++;
- }
+
/* if the page was really writable, then we change its
protection back to writable */
- if (prot & PAGE_WRITE_ORG) {
- pindex = (address - host_start) >> TARGET_PAGE_BITS;
- if (!(p1[pindex].flags & PAGE_WRITE)) {
- mprotect((void *)g2h(host_start), qemu_host_page_size,
- (prot & PAGE_BITS) | PAGE_WRITE);
- p1[pindex].flags |= PAGE_WRITE;
+ 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;
+ 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. */
- tb_invalidate_phys_page(address, pc, puc);
+ tb_invalidate_phys_page(addr, pc, puc);
#ifdef DEBUG_TB_CHECK
- tb_invalidate_check(address);
+ tb_invalidate_check(addr);
#endif
- mmap_unlock();
- return 1;
}
+ mprotect((void *)g2h(host_start), qemu_host_page_size,
+ prot & PAGE_BITS);
+
+ mmap_unlock();
+ return 1;
}
mmap_unlock();
return 0;
--
1.7.0.2
[Qemu-devel] [PATCH 5/5] tcg: initial ia64 support, Aurelien Jarno, 2010/03/28
[Qemu-devel] [PATCH 3/5] ia64 disas support, Aurelien Jarno, 2010/03/28