Skip to content

implement COW on ghost memory#24

Open
XiaowanDong wants to merge 16 commits intojtcriswell:masterfrom
XiaowanDong:master
Open

implement COW on ghost memory#24
XiaowanDong wants to merge 16 commits intojtcriswell:masterfrom
XiaowanDong:master

Conversation

@XiaowanDong
Copy link
Copy Markdown
Contributor

  1. ghostmemCOW(): Invoked at fork. It copies the page table entries of ghost memory from the parent to the child. Also, it write-protects these page table entries.
  2. Modify sva_ghost_fault() to check whether the page fault is due to a write access to a read-only ghost memory page. If yes, COW that ghost memory page.
  3. Create a new field called flags in SVAThread to save the decision regarding whether to do COW on ghost memory or not at fork. The decision is made based on the arguments of the fork family syscalls, which are extracted in SVASyscall handler.
  4. Pull out previous inline functions such as get_pml4eVaddr() from SVA/lib/mmu.c to SVA/include/sva/mmu.h so that they could be called in other files such as SVA/lib/secmem.c

@jtcriswell
Copy link
Copy Markdown
Owner

Xiaowan, can you remind me why you added the cr3 argument to sva_init_stack()? I don't recall why you needed it. I'd like to avoid adding it if possible because it requires us to update the FreeBSD kernel patch (which I'm currently trying to update with other changes you've made).

@jtcriswell
Copy link
Copy Markdown
Owner

Also, for future refactoring, it's best to make incremental commits and pull requests. For example, if you need to refactor some of the code, first do that, commit it, and make a pull request. After that, you can make more commits that add the feature, commit, and create a pull request. That allows me to review and merge your changes in smaller pieces and allows you to get more of your code merged in if some of it needs some additional discussion or modification.

@XiaowanDong
Copy link
Copy Markdown
Contributor Author

XiaowanDong commented Sep 29, 2017 via email

@XiaowanDong
Copy link
Copy Markdown
Contributor Author

XiaowanDong commented Sep 29, 2017 via email

@jtcriswell
Copy link
Copy Markdown
Owner

I think the question is whether you need the CR3 value. The SVAThread already has the PML4E that maps ghost memory into the process's virtual address space. Can that be used to write-protect the memory instead of using CR3?

Copy link
Copy Markdown
Owner

@jtcriswell jtcriswell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added some comments below. In addition to these changes, the kernel patch must be updated to reflect the new APIs. I'm working on getting some of your fixes from the FreeBSD90 repository into the patch; I think I can have that finished by end of day Monday. After that, I can merge in whatever changes you need to have to make this patch work. If you can modify the master branch in FreeBSD90 with the changes that go along with this patch, that will make it much easier for me to merge the code in.

Comment thread SVA/lib/handlers.S Outdated
* code).
* According to the type of fork and the flags, we make a decision about
* whether to COW on ghost memory or not, and save the decision in the flags
* filed of the current SVAThread. (1 is COW, and 0 is not COW.)
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick: you misspelled "field" as "filed." FWIW, I make this mistake all the time (in fact, I made it and had to correct it while writing this comment. :)

Comment thread SVA/lib/handlers.S Outdated
/* Find the flags field of the current SVAThread */
movq %gs:0x260, %r14
movq CPU_THREAD(%r14), %r14
movq $0, 0x7d80(%r14)
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should create a macro for the 0x7d80 constant. I assume it's some offset into a C structure.

Comment thread SVA/lib/handlers.S Outdated
cmoveq %r13, %r12
jne NEXT_TEST_FORK
movq %r13, %r12
/* test the syscall argument flags, whether
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like you're testing the flags argument to see if the ghost memory should be copy-on-write. Is that correct? If so, we're adding overhead to the critical path (system call dispatch). The flags argument of the system call is already saved in the Interrupt Context; we could have sva_init_stack() just check the flags there to determine if the ghost memory should be marked copy-on-write. Adding overhead to sva_init_stack would be better than adding overhead to system call dispatch.

Comment thread SVA/lib/mmu.c Outdated
* table, add one.
*/
sva_integer_state_t integerState = newThread->integerState;
pml4e_t * pml4e = (pml4e_t *) getVirtual(integerState.cr3 + secmemOffset);
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this where you're using the CR3 field of the Integer State? If so, why not use the secmemPML4e in the SVAThread to find the page table entries that map ghost memory?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ghostmemCOW() is called by sva_init_stack() at fork, where the new thread (child)'s SVAThread->secmemPML4e is set to be equal to the old thread's. The new thread's secmemPML4e is not set until in sva_ghost_fault() or ghostMalloc() when the ghost memory is allocated at the first time. Therefore I am not able to know the new child's pml4 at fork without passing it from the OS.

Comment thread SVA/lib/mmu.c Outdated

unprotect_paging();
if (!isPresent (pml4e)) {
/* Page table page index */
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please be sure to indent code within blocks. It looks like the code within the "if" clause isn't indented as it should be.

Please also be sure to indent using two spaces instead of using tabs and to wrap lines at 80 columns. We are (kind of) following the LLVM Coding Standards in SVA.

Comment thread SVA/lib/secmem.c

void
sva_ghost_fault (uintptr_t vaddr) {
sva_ghost_fault (uintptr_t vaddr, unsigned long code) {
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add a function-level comment for sva_ghost_fault()? I neglected to write one when I added sva_ghost_fault(). :(

Comment thread SVA/lib/secmem.c Outdated
else
{
uintptr_t vaddr_old = (uintptr_t) getVirtual(paddr);
uintptr_t paddr_new = provideSVAMemory (X86_PAGE_SIZE);
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this code should use the new frame cache that Zhuojia added instead of calling the OS callback function directly. That will enable us to use cached frames; it will also make it easier to mitigate side channels made possible via the copy-on-write mechanism.

Comment thread SVA/lib/state.c Outdated
icontextp->valid |= IC_is_valid;
}

if(vg && (oldThread->secmemSize) && (oldThread->flags & 1))
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code should have a comment explaining what it is doing. Also, the constant should be replaced with a const global variable that makes it clear what the constant represents.

@XiaowanDong
Copy link
Copy Markdown
Contributor Author

XiaowanDong commented Oct 2, 2017 via email

@jtcriswell
Copy link
Copy Markdown
Owner

jtcriswell commented Oct 2, 2017 via email

@XiaowanDong
Copy link
Copy Markdown
Contributor Author

I have modified the code according to John's comments above. This pull request is ready to be reviewed again.

@XiaowanDong
Copy link
Copy Markdown
Contributor Author

The changes have been made as requested. It is now ready to be reviewed again.

@XiaowanDong XiaowanDong reopened this Oct 11, 2017
Comment thread SVA/lib/secmem.c Outdated
}


memcpy(getVirtual(paddr_new), (void *) vaddr_old, X86_PAGE_SIZE);
Copy link
Copy Markdown
Contributor Author

@XiaowanDong XiaowanDong Oct 18, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line would not work since provideSVAMemory() has already removed the kernel's direct mapping for this page when it becomes a ghost page. The only way to deal with this problem is to port the SVA DMAP from SVAMPX/mmu-devel branch to the main branch. Please let me know what you think @jtcriswell .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants