This first part contains the additions to the existing infrastructure
needed to implement the new interfaces used in the rest of the patch.

In exec.c, page_check_range() has been added to take an address and a
size and and check to see if it is contained in a valid page that
belongs to the target. A flag is passed t indicate wether read or write
access should be checked.

In qemu.h, the access_ok macro has been given a real implemention, and
implementations of copy_from_user() and copy_to_user() have been added.


                                Stuart

Stuart R. Anderson                               [EMAIL PROTECTED]
Network & Software Engineering                   http://www.netsweng.com/
1024D/37A79149:                                  0791 D3B8 9A4C 2CDC A31F
                                                 BD03 0A62 E534 37A7 9149
Index: qemu/exec.c
===================================================================
--- qemu.orig/exec.c    2007-08-07 21:44:10.000000000 -0400
+++ qemu/exec.c 2007-08-07 21:44:16.000000000 -0400
@@ -1862,6 +1862,29 @@
     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 ) return -1;  /* we've wrapped around */
+    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)
Index: qemu/cpu-all.h
===================================================================
--- qemu.orig/cpu-all.h 2007-08-07 21:44:10.000000000 -0400
+++ qemu/cpu-all.h      2007-08-07 21:44:16.000000000 -0400
@@ -691,6 +691,7 @@
 int page_get_flags(target_ulong address);
 void page_set_flags(target_ulong start, target_ulong end, int flags);
 void page_unprotect_range(target_ulong data, target_ulong data_size);
+int page_check_range(target_ulong start, target_ulong len, int flags);
 
 CPUState *cpu_copy(CPUState *env);
 
Index: qemu/linux-user/qemu.h
===================================================================
--- qemu.orig/linux-user/qemu.h 2007-08-07 21:44:10.000000000 -0400
+++ qemu/linux-user/qemu.h      2007-08-08 17:54:18.000000000 -0400
@@ -171,7 +171,8 @@
 #define VERIFY_READ 0
 #define VERIFY_WRITE 1
 
-#define access_ok(type,addr,size) (1)
+#define access_ok(type,addr,size) \
+    
(page_check_range((target_ulong)addr,size,(type==VERIFY_READ)?PAGE_READ:PAGE_WRITE)==0)
 
 /* NOTE get_user and put_user use host addresses.  */
 #define __put_user(x,ptr)\
@@ -238,6 +239,26 @@
     __ret;\
 })
 
+#define copy_from_user(hptr, gptr, len) \
+({ \
+    int __cfu_ret=0;\
+    if( access_ok(VERIFY_READ, gptr, (len) ) )\
+        memcpy(hptr,gptr,(len)); \
+    else \
+        __cfu_ret=1;\
+    __cfu_ret; \
+})
+
+#define copy_to_user(gptr, hptr, len) \
+({ \
+    int __ctu_ret=0;\
+    if( access_ok(VERIFY_WRITE, gptr, (len)) )\
+        memcpy(gptr,hptr,(len)); \
+    else \
+        __ctu_ret=1;\
+    __ctu_ret; \
+})
+
 /* Functions for accessing guest memory.  The tget and tput functions
    read/write single values, byteswapping as neccessary.  The lock_user
    gets a pointer to a contiguous area of guest memory, but does not perform

Reply via email to