Index: qemu/linux-user/syscall.c =================================================================== --- qemu.orig/linux-user/syscall.c 2007-11-12 09:56:01.000000000 -0700 +++ qemu/linux-user/syscall.c 2007-11-12 09:56:12.000000000 -0700 @@ -2745,7 +2745,6 @@ ret = 0; /* avoid warning */ break; case TARGET_NR_read: - page_unprotect_range(arg2, arg3); if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0))) goto efault; ret = get_errno(read(arg1, p, arg3)); @@ -4538,7 +4537,6 @@ break; #ifdef TARGET_NR_pread case TARGET_NR_pread: - page_unprotect_range(arg2, arg3); if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0))) goto efault; ret = get_errno(pread(arg1, p, arg3, arg4)); Index: qemu/exec.c =================================================================== --- qemu.orig/exec.c 2007-11-12 09:56:01.000000000 -0700 +++ qemu/exec.c 2007-11-12 10:00:41.000000000 -0700 @@ -1898,6 +1898,9 @@ return -1; if (!(p->flags & PAGE_WRITE) && (flags & PAGE_WRITE) ) return -1; + if ((p->flags & PAGE_EXEC) && (flags & PAGE_WRITE) + && page_unprotect(addr, 0, NULL)) + return -1; } return 0; } @@ -1942,21 +1945,6 @@ return 0; } -/* call this function when system calls directly modify a memory area */ -/* ??? This should be redundant now we have lock_user. */ -void page_unprotect_range(target_ulong data, target_ulong data_size) -{ - target_ulong start, end, addr; - - start = data; - end = start + data_size; - start &= TARGET_PAGE_MASK; - end = TARGET_PAGE_ALIGN(end); - for(addr = start; addr < end; addr += TARGET_PAGE_SIZE) { - page_unprotect(addr, 0, NULL); - } -} - static inline void tlb_set_dirty(CPUState *env, unsigned long addr, target_ulong vaddr) {