diff options
author | ths <ths@c046a42c-6fe2-441c-8c8c-71466251a162> | 2007-11-02 19:02:07 +0000 |
---|---|---|
committer | ths <ths@c046a42c-6fe2-441c-8c8c-71466251a162> | 2007-11-02 19:02:07 +0000 |
commit | 3d97b40b05c61d6d85ad1ab9cbb72a076db2aa74 (patch) | |
tree | 7f1c36162cf20e120f67b742207ef6d6bd23264c /exec.c | |
parent | 7c829863fb83e39a77859cfc263441670d9f058a (diff) | |
download | qemu-3d97b40b05c61d6d85ad1ab9cbb72a076db2aa74.zip |
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.c | 27 |
1 files changed, 27 insertions, 0 deletions
@@ -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) |