aboutsummaryrefslogtreecommitdiff
path: root/exec.c
diff options
context:
space:
mode:
authorths <ths@c046a42c-6fe2-441c-8c8c-71466251a162>2007-11-02 19:02:07 +0000
committerths <ths@c046a42c-6fe2-441c-8c8c-71466251a162>2007-11-02 19:02:07 +0000
commit3d97b40b05c61d6d85ad1ab9cbb72a076db2aa74 (patch)
tree7f1c36162cf20e120f67b742207ef6d6bd23264c /exec.c
parent7c829863fb83e39a77859cfc263441670d9f058a (diff)
EFAULT - verify pages are in cache and are read/write, by Thayne Harbaugh.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3506 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'exec.c')
-rw-r--r--exec.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/exec.c b/exec.c
index 0daeaabe25..7c8864c8b7 100644
--- a/exec.c
+++ b/exec.c
@@ -1875,6 +1875,33 @@ void page_set_flags(target_ulong start, target_ulong end, int flags)
spin_unlock(&tb_lock);
}
+int page_check_range(target_ulong start, target_ulong len, int flags)
+{
+ PageDesc *p;
+ target_ulong end;
+ target_ulong addr;
+
+ end = TARGET_PAGE_ALIGN(start+len); /* must do before we loose bits in the next step */
+ start = start & TARGET_PAGE_MASK;
+
+ if( end < start )
+ /* we've wrapped around */
+ return -1;
+ for(addr = start; addr < end; addr += TARGET_PAGE_SIZE) {
+ p = page_find(addr >> TARGET_PAGE_BITS);
+ if( !p )
+ return -1;
+ 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) )
+ return -1;
+ }
+ return 0;
+}
+
/* called from signal handler: invalidate the code and unprotect the
page. Return TRUE if the fault was succesfully handled. */
int page_unprotect(target_ulong address, unsigned long pc, void *puc)