diff options
author | Neal H. Walfield <neal@gnu.org> | 2009-02-20 22:18:24 +0100 |
---|---|---|
committer | Neal H. Walfield <neal@gnu.org> | 2009-02-20 22:18:24 +0100 |
commit | 4febc506cb97a99a2aa48ec91d76494394efd273 (patch) | |
tree | eb67a4734d3f9e8599cb6fca54155a17fdc5567c /viengoos | |
parent | 9a2505aa673e3b001d18985eee0793c4647b3237 (diff) |
Correctly update access and dirty bits.
Diffstat (limited to 'viengoos')
-rw-r--r-- | viengoos/sysdeps/x86_64/vm.c | 58 | ||||
-rw-r--r-- | viengoos/vm.h | 6 |
2 files changed, 41 insertions, 23 deletions
diff --git a/viengoos/sysdeps/x86_64/vm.c b/viengoos/sysdeps/x86_64/vm.c index 33e931e..94a58f1 100644 --- a/viengoos/sysdeps/x86_64/vm.c +++ b/viengoos/sysdeps/x86_64/vm.c @@ -508,6 +508,28 @@ vm_as_destroy (struct thread *thread) } static void +update_access_dirty_bits (struct vm_mapping *mapping) +{ + struct pte *pte = mapping->pte; + assert (pte); + if (pte->accessed) + { + mapping->desc->recently_referenced = 1; + mapping->desc->referenced = 1; + mapping->desc->user_referenced = 1; + pte->accessed = 0; + } + if (pte->dirty) + { + mapping->desc->recently_dirty = 1; + mapping->desc->dirty = 1; + mapping->desc->user_dirty = 1; + pte->dirty = 0; + } + +} + +static void mapping_destroy (struct vm_mapping *mapping) { debug (5, OBJECT_NAME_FMT": %"PRIxPTR @@ -535,18 +557,10 @@ mapping_destroy (struct vm_mapping *mapping) pte_shootdown (mapping->address); } - if (pte->accessed) - { - mapping->desc->recently_referenced = 1; - mapping->desc->referenced = 1; - mapping->desc->user_referenced = 1; - } - if (pte->dirty) - { - mapping->desc->recently_dirty = 1; - mapping->desc->dirty = 1; - mapping->desc->user_dirty = 1; - } + /* Now that the PTE's present bit has been clear and the PTE flushed + from the TLB, the access bits and dirty bits represent the final + use state. */ + update_access_dirty_bits (mapping); struct page_table *pt = (void *) ((uintptr_t) pte & ~(PAGESIZE - 1)); pt->allocated --; @@ -602,7 +616,7 @@ void vm_thread_revoke (struct thread *thread, uintptr_t start, uintptr_t end, uintptr_t access) { - debug (5, OBJECT_NAME_FMT": %"PRIxPTR" - %"PRIxPTR", "PTE_ACCESS_FMT, + debug (0, OBJECT_NAME_FMT": %"PRIxPTR" - %"PRIxPTR", "PTE_ACCESS_FMT, OBJECT_NAME_PRINTF ((struct vg_object *) (thread)), start, end, PTE_ACCESS_PRINTF (access)); @@ -647,12 +661,6 @@ vm_thread_revoke (struct thread *thread, void vm_object_revoke (struct object_desc *desc, uintptr_t access) { - debug (5, "Revoking %s%s%s access to object " VG_OID_FMT, - access & MEM_READABLE ? "r" : "", - access & MEM_WRITABLE ? "w" : "", - access & MEM_EXECUTABLE ? "x" : "", - desc->oid); - assert (! (access & ~MEM_RWX)); struct vm_mapping *mapping; @@ -670,8 +678,11 @@ vm_object_revoke (struct object_desc *desc, uintptr_t access) /* All access has been removed. Free the mapping. */ mapping_destroy (mapping); else if (mapping->thread == current_as && clears) - /* This clears some access. */ + /* This clears some access but not all. */ pte_shootdown (mapping->address); + else if (! access) + /* Save the access bits. */ + update_access_dirty_bits (mapping); } } @@ -815,6 +826,13 @@ page_table_dump (int argc, char *argv[]) printf ("page-tables [process [start [end]]]"); return; } + + /* Round down. */ + start &= ~(PAGESIZE - 1); + + /* Set end such that if no end is specified, only the specified + page is shown. */ + end = start; } if (argc > 3) { diff --git a/viengoos/vm.h b/viengoos/vm.h index 597d851..b04c7d0 100644 --- a/viengoos/vm.h +++ b/viengoos/vm.h @@ -121,9 +121,9 @@ extern void vm_as_destroy (struct thread *thread); /* Revoke the access specified in ACCESS to the object designed by DESC (i.e., any extant mappings with the access described in ACCESS are downgraded and potentially destroyed if they no longer grant - any access). Access bit and dirty bits are collected. - DESC->REFERENCED, DESC->DIRTY, DESC->USER_REFERENCED and - DESC->USER_DIRTY are updated appropriately. */ + any access). If ACCESS is 0 or the ACCESS causes an object to be + unmapped, updates the access bits (DESC->REFERENCED, DESC->DIRTY, + DESC->USER_REFERENCED and DESC->USER_DIRTY) appropriately. */ extern void vm_object_revoke (struct object_desc *desc, uintptr_t access); /* Install thread THREAD's address space, i.e., make it the active |