summaryrefslogtreecommitdiff
path: root/libhurd-mm/anonymous.c
diff options
context:
space:
mode:
Diffstat (limited to 'libhurd-mm/anonymous.c')
-rw-r--r--libhurd-mm/anonymous.c43
1 files changed, 30 insertions, 13 deletions
diff --git a/libhurd-mm/anonymous.c b/libhurd-mm/anonymous.c
index 656711b..c679507 100644
--- a/libhurd-mm/anonymous.c
+++ b/libhurd-mm/anonymous.c
@@ -31,6 +31,7 @@
#include <hurd/rm.h>
#include <profile.h>
+#include <backtrace.h>
#include "anonymous.h"
#include "pager.h"
@@ -132,18 +133,23 @@ static struct hurd_slab_space anonymous_pager_slab
static bool
fault (struct pager *pager, uintptr_t offset, int count, bool read_only,
- uintptr_t fault_addr, uintptr_t ip, struct exception_info info)
+ uintptr_t fault_addr, uintptr_t ip, struct activation_fault_info info)
{
struct anonymous_pager *anon = (struct anonymous_pager *) pager;
+ assert (anon->magic == ANONYMOUS_MAGIC);
- debug (5, "Fault at %p, %d pages (%d kb); pager at " ADDR_FMT "+%d",
- fault_addr, count, count * PAGESIZE / 1024,
- ADDR_PRINTF (anon->map_area), offset);
+ debug (5, "%p: fault at %p, spans %d pg (%d kb); "
+ "pager: %p-%p (%d pages; %d kb), offset: %x",
+ anon, (void *) fault_addr, count, count * PAGESIZE / 1024,
+ (void *) (uintptr_t) addr_prefix (anon->map_area),
+ (void *) (uintptr_t) addr_prefix (anon->map_area) + anon->pager.length,
+ anon->pager.length / PAGESIZE, anon->pager.length / 1024,
+ offset);
ss_mutex_lock (&anon->lock);
bool recursive = false;
- void *pages[count];
+ void **pages;
profile_region (count > 1 ? ">1" : "=1");
@@ -204,17 +210,20 @@ fault (struct pager *pager, uintptr_t offset, int count, bool read_only,
fault_addr -= left;
offset -= left;
- count += (left + right) / PAGESIZE;
+ count = (left + PAGESIZE + right) / PAGESIZE;
assertx (offset + count * PAGESIZE <= pager->length,
"%x + %d pages <= %x",
offset, count, pager->length);
- debug (5, "Fault at %p, %d pages (%d kb); pager at " ADDR_FMT "+%d",
- fault_addr, count, count * PAGESIZE / 1024,
+ debug (5, "Faulting %p - %p (%d pages; %d kb); pager at " ADDR_FMT "+%d",
+ (void *) fault_addr, (void *) fault_addr + count * PAGE_SIZE,
+ count, count * PAGESIZE / 1024,
ADDR_PRINTF (anon->map_area), offset);
}
+ pages = __builtin_alloca (sizeof (void *) * count);
+
if (! (anon->flags & ANONYMOUS_NO_ALLOC))
{
hurd_btree_storage_desc_t *storage_descs;
@@ -244,7 +253,7 @@ fault (struct pager *pager, uintptr_t offset, int count, bool read_only,
storage address as object_discarded_clear also
returns a mapping and we are likely to access the
data at the fault address. */
- err = rm_object_discarded_clear (ADDR_VOID,
+ err = rm_object_discarded_clear (ADDR_VOID, ADDR_VOID,
storage_desc->storage);
assertx (err == 0, "%d", err);
@@ -326,6 +335,7 @@ fault (struct pager *pager, uintptr_t offset, int count, bool read_only,
#endif
}
+ assert (anon->magic == ANONYMOUS_MAGIC);
ss_mutex_unlock (&anon->lock);
profile_region_end ();
@@ -367,6 +377,8 @@ fault (struct pager *pager, uintptr_t offset, int count, bool read_only,
debug (5, "Fault at %x resolved", fault_addr);
+ assert (anon->magic == ANONYMOUS_MAGIC);
+
return r;
}
@@ -374,6 +386,7 @@ static void
mdestroy (struct map *map)
{
struct anonymous_pager *anon = (struct anonymous_pager *) map->pager;
+ assert (anon->magic == ANONYMOUS_MAGIC);
/* XXX: We assume that every byte is mapped by at most one mapping.
We may have to reexamine this assumption if we allow multiple
@@ -468,6 +481,7 @@ destroy (struct pager *pager)
assert (! pager->maps);
struct anonymous_pager *anon = (struct anonymous_pager *) pager;
+ assert (anon->magic == ANONYMOUS_MAGIC);
/* Wait any fill function returns. */
ss_mutex_lock (&anon->fill_lock);
@@ -498,6 +512,7 @@ advise (struct pager *pager,
uintptr_t start, uintptr_t length, uintptr_t advice)
{
struct anonymous_pager *anon = (struct anonymous_pager *) pager;
+ assert (anon->magic == ANONYMOUS_MAGIC);
switch (advice)
{
@@ -541,7 +556,7 @@ advise (struct pager *pager,
case pager_advice_normal:
{
- struct exception_info info;
+ struct activation_fault_info info;
info.discarded = anon->policy.discardable;
info.type = cap_page;
/* XXX: What should we set info.access to? */
@@ -585,6 +600,8 @@ anonymous_pager_alloc (addr_t activity,
struct anonymous_pager *anon = buffer;
memset (anon, 0, sizeof (*anon));
+ anon->magic = ANONYMOUS_MAGIC;
+
anon->pager.length = length;
anon->pager.fault = fault;
anon->pager.no_refs = destroy;
@@ -650,7 +667,7 @@ anonymous_pager_alloc (addr_t activity,
{
if ((flags & ANONYMOUS_FIXED))
{
- debug (0, "(%x, %x (%x)): Specified range " ADDR_FMT "+%d "
+ debug (0, "(%p, %x (%p)): Specified range " ADDR_FMT "+%d "
"in use and ANONYMOUS_FIXED specified",
hint, length, hint + length - 1,
ADDR_PRINTF (anon->map_area), count);
@@ -668,7 +685,7 @@ anonymous_pager_alloc (addr_t activity,
anon->map_area = as_alloc (width, count, true);
if (ADDR_IS_VOID (anon->map_area))
{
- debug (0, "(%x, %x (%x)): No VA available",
+ debug (0, "(%p, %x (%p)): No VA available",
hint, length, hint + length - 1);
goto error_with_buffer;
}
@@ -699,7 +716,7 @@ anonymous_pager_alloc (addr_t activity,
panic ("Memory exhausted.");
- debug (5, "Installed pager at %x spanning %d pages",
+ debug (5, "Installed pager at %p spanning %d pages",
*addr_out, length / PAGESIZE);
return anon;