Commit 3d97b40b05c61d6d85ad1ab9cbb72a076db2aa74
1 parent
7c829863
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
Showing
3 changed files
with
30 additions
and
1 deletions
cpu-all.h
| ... | ... | @@ -691,6 +691,7 @@ void page_dump(FILE *f); |
| 691 | 691 | int page_get_flags(target_ulong address); |
| 692 | 692 | void page_set_flags(target_ulong start, target_ulong end, int flags); |
| 693 | 693 | void page_unprotect_range(target_ulong data, target_ulong data_size); |
| 694 | +int page_check_range(target_ulong start, target_ulong len, int flags); | |
| 694 | 695 | |
| 695 | 696 | CPUState *cpu_copy(CPUState *env); |
| 696 | 697 | ... | ... |
exec.c
| ... | ... | @@ -1875,6 +1875,33 @@ void page_set_flags(target_ulong start, target_ulong end, int flags) |
| 1875 | 1875 | spin_unlock(&tb_lock); |
| 1876 | 1876 | } |
| 1877 | 1877 | |
| 1878 | +int page_check_range(target_ulong start, target_ulong len, int flags) | |
| 1879 | +{ | |
| 1880 | + PageDesc *p; | |
| 1881 | + target_ulong end; | |
| 1882 | + target_ulong addr; | |
| 1883 | + | |
| 1884 | + end = TARGET_PAGE_ALIGN(start+len); /* must do before we loose bits in the next step */ | |
| 1885 | + start = start & TARGET_PAGE_MASK; | |
| 1886 | + | |
| 1887 | + if( end < start ) | |
| 1888 | + /* we've wrapped around */ | |
| 1889 | + return -1; | |
| 1890 | + for(addr = start; addr < end; addr += TARGET_PAGE_SIZE) { | |
| 1891 | + p = page_find(addr >> TARGET_PAGE_BITS); | |
| 1892 | + if( !p ) | |
| 1893 | + return -1; | |
| 1894 | + if( !(p->flags & PAGE_VALID) ) | |
| 1895 | + return -1; | |
| 1896 | + | |
| 1897 | + if (!(p->flags & PAGE_READ) && (flags & PAGE_READ) ) | |
| 1898 | + return -1; | |
| 1899 | + if (!(p->flags & PAGE_WRITE) && (flags & PAGE_WRITE) ) | |
| 1900 | + return -1; | |
| 1901 | + } | |
| 1902 | + return 0; | |
| 1903 | +} | |
| 1904 | + | |
| 1878 | 1905 | /* called from signal handler: invalidate the code and unprotect the |
| 1879 | 1906 | page. Return TRUE if the fault was succesfully handled. */ |
| 1880 | 1907 | int page_unprotect(target_ulong address, unsigned long pc, void *puc) | ... | ... |
linux-user/qemu.h
| ... | ... | @@ -203,7 +203,8 @@ int target_msync(abi_ulong start, abi_ulong len, int flags); |
| 203 | 203 | #define VERIFY_READ 0 |
| 204 | 204 | #define VERIFY_WRITE 1 |
| 205 | 205 | |
| 206 | -#define access_ok(type,addr,size) (1) | |
| 206 | +#define access_ok(type,addr,size) \ | |
| 207 | + (page_check_range((target_ulong)addr,size,(type==VERIFY_READ)?PAGE_READ:PAGE_WRITE)==0) | |
| 207 | 208 | |
| 208 | 209 | /* NOTE get_user and put_user use host addresses. */ |
| 209 | 210 | #define __put_user(x,ptr)\ | ... | ... |