Commit 3d97b40b05c61d6d85ad1ab9cbb72a076db2aa74

Authored by ths
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
cpu-all.h
@@ -691,6 +691,7 @@ void page_dump(FILE *f); @@ -691,6 +691,7 @@ void page_dump(FILE *f);
691 int page_get_flags(target_ulong address); 691 int page_get_flags(target_ulong address);
692 void page_set_flags(target_ulong start, target_ulong end, int flags); 692 void page_set_flags(target_ulong start, target_ulong end, int flags);
693 void page_unprotect_range(target_ulong data, target_ulong data_size); 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 CPUState *cpu_copy(CPUState *env); 696 CPUState *cpu_copy(CPUState *env);
696 697
@@ -1875,6 +1875,33 @@ void page_set_flags(target_ulong start, target_ulong end, int flags) @@ -1875,6 +1875,33 @@ void page_set_flags(target_ulong start, target_ulong end, int flags)
1875 spin_unlock(&tb_lock); 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 /* called from signal handler: invalidate the code and unprotect the 1905 /* called from signal handler: invalidate the code and unprotect the
1879 page. Return TRUE if the fault was succesfully handled. */ 1906 page. Return TRUE if the fault was succesfully handled. */
1880 int page_unprotect(target_ulong address, unsigned long pc, void *puc) 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,7 +203,8 @@ int target_msync(abi_ulong start, abi_ulong len, int flags);
203 #define VERIFY_READ 0 203 #define VERIFY_READ 0
204 #define VERIFY_WRITE 1 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 /* NOTE get_user and put_user use host addresses. */ 209 /* NOTE get_user and put_user use host addresses. */
209 #define __put_user(x,ptr)\ 210 #define __put_user(x,ptr)\