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)\ | ... | ... |