Replace get_user(), put_user() routines by versions that don't do
authorBen Pfaff <blp@cs.stanford.edu>
Tue, 16 May 2006 16:13:55 +0000 (16:13 +0000)
committerBen Pfaff <blp@cs.stanford.edu>
Tue, 16 May 2006 16:13:55 +0000 (16:13 +0000)
"copying", which scares off students because they think of copying as
inefficient.

doc/userprog.texi

index a9a84b2dcd854609cbd40bd82648cf96b1a9773c..655c5be8691dcb0bf6e167283c7b9c427de02c76 100644 (file)
@@ -430,29 +430,37 @@ Therefore, for those who want to try the latter technique, we'll
 provide a little bit of helpful code:
 
 @verbatim
-/* Tries to copy a byte from user address USRC to kernel address KDST.
-   Returns true if successful, false if USRC is invalid. */
-static inline bool get_user (uint8_t *kdst, const uint8_t *usrc) {
-  int eax;
-  asm ("movl $1f, %%eax; movb %2, %%al; movb %%al, %0; 1:"
-       : "=m" (*kdst), "=&a" (eax) : "m" (*usrc));
-  return eax != 0;
+/* Reads a byte at user virtual address UADDR.
+   UADDR must be below PHYS_BASE.
+   Returns the byte value if successful, -1 if a segfault
+   occurred. */
+static int
+get_user (const uint8_t *uaddr)
+{
+  int result;
+  asm ("movl $1f, %0; movzbl %1, %0; 1:"
+       : "=&a" (result) : "m" (*uaddr));
+  return result;
 }
-
-/* Tries to write BYTE to user address UDST.
-   Returns true if successful, false if UDST is invalid. */
-static inline bool put_user (uint8_t *udst, uint8_t byte) {
-  int eax;
-  asm ("movl $1f, %%eax; movb %b2, %0; 1:"
-       : "=m" (*udst), "=&a" (eax) : "r" (byte));
-  return eax != 0;
+/* Writes BYTE to user address UDST.
+   UDST must be below PHYS_BASE.
+   Returns true if successful, false if a segfault occurred. */
+static bool
+put_user (uint8_t *udst, uint8_t byte)
+{
+  int error_code;
+  asm ("movl $1f, %0; movb %b2, %1; 1:"
+       : "=&a" (error_code), "=m" (*udst) : "r" (byte));
+  return error_code != -1;
 }
 @end verbatim
 
 Each of these functions assumes that the user address has already been
 verified to be below @code{PHYS_BASE}.  They also assume that you've
-modified @func{page_fault} so that a page fault in the kernel merely sets
-@code{eax} to 0 and copies its former value into @code{eip}.
+modified @func{page_fault} so that a page fault in the kernel merely
+sets @code{eax} to @t{0xffffffff} and copies its former value
+into @code{eip}.
 
 @node Project 2 Suggested Order of Implementation
 @section Suggested Order of Implementation