Alternatively, the kernel could avoid the problem by only accessing user
data through the user virtual address.
+Other aliases should only arise if you implement sharing, as extra
+credit (@pxref{VM Extra Credit}), or as bugs elsewhere in your code.
+
@deftypefun bool pagedir_is_dirty (uint32_t *@var{pd}, const void *@var{vpage})
@deftypefunx bool pagedir_is_accessed (uint32_t *@var{pd}, const void *@var{vpage})
Returns true if page directory @var{pd} contains a page table entry for
Implement stack growth. In project 2, the stack was a single page at
the top of the user virtual address space, and programs were limited to
that much stack. Now, if the stack grows past its current size,
-allocate additional page as necessary.
+allocate additional pages as necessary.
Allocate additional pages only if they ``appear'' to be stack accesses.
Devise a heuristic that attempts to distinguish stack accesses from
-other accesses. You can retrieve the user program's current stack
-pointer from the @struct{intr_frame}'s @code{esp} member.
+other accesses.
User programs are buggy if they write to the stack below the stack
pointer, because typical real OSes may interrupt a process at any time
@code{PUSHA} instruction pushes 32 bytes at once, so it can fault 32
bytes below the stack pointer.
+You will need to be able to obtain the current value of the user
+program's stack pointer. Within a system call or a page fault generated
+by a user program, you can retrieve it from @code{esp} member of the
+@struct{intr_frame} passed to @func{syscall_handler} or
+@func{page_fault}, respectively. If you verify user pointers before
+accessing them (@pxref{Accessing User Memory}), these are the only cases
+you need to handle. On the other hand, if you depend on page faults to
+detect invalid memory access, you will need to handle another case,
+where a page fault occurs in the kernel. Reading @code{esp} out of the
+@struct{intr_frame} passed to @func{page_fault} in that case will obtain
+the kernel stack pointer, not the user stack pointer. You will need to
+arrange another way, e.g.@: by saving @code{esp} into @struct{thread} on
+the initial transition from user to kernel mode.
+
You may impose some absolute limit on stack size, as do most OSes.
-(Some OSes make the limit user-adjustable, e.g.@: with the
-@command{ulimit} command on many Unix systems.)
+Some OSes make the limit user-adjustable, e.g.@: with the
+@command{ulimit} command on many Unix systems. On many GNU/Linux systems,
+the default limit is 8 MB.
The first stack page need not be allocated lazily. You can initialize
it with the command line arguments at load time, with no need to wait
@command{diffstat} program. The final row gives total lines inserted
and deleted; a changed line counts as both an insertion and a deletion.
-This summary is relative to the Pintos base code, but we started from
-the reference solution to project 2. @xref{Project 2 FAQ}, for the
-summary of project 2.
+This summary is relative to the Pintos base code, but the reference
+solution for project 3 starts from the reference solution to project 2.
+@xref{Project 2 FAQ}, for the summary of project 2.
+
+The reference solution represents just one possible solution. Many
+other solutions are also possible and many of those differ greatly from
+the reference solution. Some excellent solutions may not modify all the
+files modified by the reference solution, and some may modify files not
+modified by the reference solution.
@verbatim
Makefile.build | 4
17 files changed, 1532 insertions(+), 104 deletions(-)
@end verbatim
-@item Do we need a working HW 2 to implement HW 3?
+@item Do we need a working Project 2 to implement Project 3?
Yes.
@item What extra credit is available?
+@anchor{VM Extra Credit}
You may implement sharing: when multiple processes are created that use
the same executable file, share read-only pages among those processes
Also, you can use the @option{-u} option to @command{pintos} to limit
the size of the user pool, which makes it easy to test your VM
implementation with various user memory sizes.
+
+@item Data pages might need swap space. Can I swap them out at process load?
+
+No. Reading data pages from the executable and writing them to swap
+immediately at program startup is not demand paging. You need to demand
+page everything (except partial pages).
@end table
@node Memory Mapped File FAQ