void page_dump(FILE *f);
int page_get_flags(target_ulong address);
void page_set_flags(target_ulong start, target_ulong end, int flags);
-void page_unprotect_range(target_ulong data, target_ulong data_size);
int page_check_range(target_ulong start, target_ulong len, int flags);
CPUState *cpu_copy(CPUState *env);
if( !(p->flags & PAGE_VALID) )
return -1;
- if (!(p->flags & PAGE_READ) && (flags & PAGE_READ) )
- return -1;
- if (!(p->flags & PAGE_WRITE) && (flags & PAGE_WRITE) )
+ if ((flags & PAGE_READ) && !(p->flags & PAGE_READ))
return -1;
+ if (flags & PAGE_WRITE) {
+ if (!(p->flags & PAGE_WRITE_ORG))
+ return -1;
+ /* unprotect the page if it was put read-only because it
+ contains translated code */
+ if (!(p->flags & PAGE_WRITE)) {
+ if (!page_unprotect(addr, 0, NULL))
+ return -1;
+ }
+ return 0;
+ }
}
return 0;
}
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)
{
#define VERIFY_READ 0
#define VERIFY_WRITE 1 /* implies read access */
-#define access_ok(type,addr,size) \
- (page_check_range((target_ulong)addr,size,(type==VERIFY_READ)?PAGE_READ:PAGE_WRITE)==0)
+static inline int access_ok(int type, abi_ulong addr, abi_ulong size)
+{
+ return page_check_range((target_ulong)addr, size,
+ (type == VERIFY_READ) ? PAGE_READ : (PAGE_READ | PAGE_WRITE)) == 0;
+}
/* NOTE __get_user and __put_user use host pointers and don't check access. */
/* These are usually used to access struct data members once the
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));
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));