summaryrefslogtreecommitdiff
path: root/viengoos
diff options
context:
space:
mode:
authorNeal H. Walfield <neal@gnu.org>2009-02-20 22:18:24 +0100
committerNeal H. Walfield <neal@gnu.org>2009-02-20 22:18:24 +0100
commit4febc506cb97a99a2aa48ec91d76494394efd273 (patch)
treeeb67a4734d3f9e8599cb6fca54155a17fdc5567c /viengoos
parent9a2505aa673e3b001d18985eee0793c4647b3237 (diff)
Correctly update access and dirty bits.
Diffstat (limited to 'viengoos')
-rw-r--r--viengoos/sysdeps/x86_64/vm.c58
-rw-r--r--viengoos/vm.h6
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