diff options
author | neal <neal> | 2008-06-06 08:21:46 +0000 |
---|---|---|
committer | neal <neal> | 2008-06-06 08:21:46 +0000 |
commit | b40c4d5e4d857b3cbe886501754bc5e3656fb234 (patch) | |
tree | 1494d389129279c98d0b106ba0edb2c69d9db1c0 /libhurd-mm/as.c | |
parent | b37705b41546f273724ea74a90f542a3254bd610 (diff) |
2008-06-06 Neal H. Walfield <neal@gnu.org>
* as.c (as_init): Configure a capability's shadow when we process
the capability, not when we process its containing cappage or
folio.
* storage.c (storage_check_reserve_internal): Only set up the
shadow object if AS_INIT_DONE is true.
Diffstat (limited to 'libhurd-mm/as.c')
-rw-r--r-- | libhurd-mm/as.c | 157 |
1 files changed, 50 insertions, 107 deletions
diff --git a/libhurd-mm/as.c b/libhurd-mm/as.c index b484ca4..8fc9bb3 100644 --- a/libhurd-mm/as.c +++ b/libhurd-mm/as.c @@ -427,8 +427,6 @@ as_alloc_slow (int width) panic ("Failed to find a free slot!"); assert (! ADDR_IS_VOID (slot)); - debug (3, "Using slot %llx/%d", addr_prefix (slot), addr_depth (slot)); - /* Set the guard on the slot. */ int gbits = ADDR_BITS - addr_depth (slot) - width; assert (gbits >= 0); @@ -486,8 +484,8 @@ as_init (void) hurd_btree_free_space_tree_init (&free_spaces); - /* We start with a tabula rasa and then remove the regions that are - actually in use. */ + /* We start with a tabula rasa and then "allocate" the regions that + are actually in use. */ as_free (ADDR (0, 0), 1); /* Then, we create the shadow page tables and mark the allocation @@ -496,56 +494,53 @@ as_init (void) void add (struct hurd_object_desc *desc, addr_t addr) { error_t err; - int i; - struct object *shadow; - - debug (5, "Adding object %llx/%d", - addr_prefix (addr), addr_depth (addr)); - /* We know that the slot that contains the capability that - designates this object is already shadowed as we shadow depth - first. */ - struct cap *cap = NULL; - /* Normally, this would not be kosher as it violates the locking - scheme, however, we know that we are the only thread. */ - as_slot_lookup_use (addr, ({ cap = slot; })); + debug (5, "Adding object " ADDR_FMT " (%s)", + ADDR_PRINTF (addr), cap_type_string (desc->type)); - assert (cap); - assertx (cap_types_compatible (cap->type, desc->type), - ADDR_FMT ": type mismatch; kernel says %s, desc says %s", - ADDR_PRINTF (addr), - cap_type_string (cap->type), cap_type_string (desc->type)); - - int slots_log2; + l4_word_t type; + struct cap_properties properties; + err = rm_cap_read (meta_data_activity, ADDR_VOID, addr, + &type, &properties); + assert (! err); + assertx (cap_types_compatible (type, desc->type), + "%s != %s", + cap_type_string (type), + cap_type_string (desc->type)); + + int gbits = CAP_ADDR_TRANS_GUARD_BITS (properties.addr_trans); + addr_t slot_addr = addr_chop (addr, gbits); + + as_slot_lookup_use (slot_addr, + ({ + slot->type = type; + CAP_PROPERTIES_SET (slot, properties); + })); switch (desc->type) { - case cap_page: - case cap_rpage: - as_alloc_at (addr, 1); - return; + default: + /* Don't allocate the AS associated with the storage. It is + dominated by its containing folio. */ + if (! ADDR_EQ (addr, desc->storage)) + as_alloc_at (addr, 1); + break; case cap_void: assert (! "void descriptor?"); return; - default: - /* This object's address was already reserved when its - parent cap page was added. */ - return; - case cap_cappage: - case cap_rcappage:; - /* We shadow the content of cappages. */ - + case cap_rcappage: if (ADDR_BITS - addr_depth (addr) - < CAP_SUBPAGE_SIZE_LOG2 (cap)) - /* The cappage is unusable for addressing. */ - return; - else - /* We release the addresses used by ADDR and will fill it - in appropriately. */ - as_free (addr, 1); + < CAP_ADDR_TRANS_SUBPAGE_SIZE_LOG2 (properties.addr_trans)) + /* The cappage is unusable for addressing, assuming it is + in-use. */ + { + if (! ADDR_EQ (addr, desc->storage)) + as_alloc_at (addr, 1); + return; + } struct storage shadow_storage = storage_alloc (meta_data_activity, @@ -553,80 +548,28 @@ as_init (void) OBJECT_POLICY_DEFAULT, ADDR_VOID); if (ADDR_IS_VOID (shadow_storage.addr)) panic ("Out of space."); - shadow = ADDR_TO_PTR (addr_extend (shadow_storage.addr, - 0, PAGESIZE_LOG2)); - cap_set_shadow (cap, shadow); - - slots_log2 = CAP_SUBPAGE_SIZE_LOG2 (cap); - + struct object *shadow + = ADDR_TO_PTR (addr_extend (shadow_storage.addr, + 0, PAGESIZE_LOG2)); + as_slot_lookup_use (addr, + ({ + cap_set_shadow (slot, shadow); + })); break; case cap_folio: - if (ADDR_BITS - addr_depth (addr) < FOLIO_OBJECTS_LOG2) - /* The folio is unusable for addressing. */ - return; - - storage_shadow_setup (cap, addr); - shadow = cap_get_shadow (cap); - - slots_log2 = FOLIO_OBJECTS_LOG2; - + /* Folios are not available for use. */ + as_alloc_at (addr, 1); + as_slot_lookup_use (addr, + ({ + storage_shadow_setup (slot, addr); + })); break; } - /* We expect at least one non-void capability per - cappage. */ - bool have_one = false; - - /* XXX: Would be nice to have syscall bundling here. */ - for (i = 0; i < (1 << slots_log2); i ++) - { - struct cap *slot = &shadow->caps[i]; - - addr_t slot_addr = addr_extend (addr, i, slots_log2); - l4_word_t type; - struct cap_properties properties; - err = rm_cap_read (meta_data_activity, ADDR_VOID, slot_addr, - &type, &properties); - if (err) - panic ("Error reading cap %d: %d", i, err); - slot->type = type; - CAP_PROPERTIES_SET (slot, properties); - - if (type != cap_void) - /* Mark the slot as free--unless we are in a folio. */ - { - have_one = true; - - if (desc->type != cap_folio - && (addr_depth (slot_addr) + CAP_GUARD_BITS (slot) - <= ADDR_BITS)) - { - addr_t object = addr_extend (slot_addr, CAP_GUARD (slot), - CAP_GUARD_BITS (slot)); - as_alloc_at (object, 1); - } - } - } - - assert (have_one); return; } - /* Shadow the root capability. */ - l4_word_t type; - struct cap_properties properties; - err = rm_cap_read (meta_data_activity, ADDR_VOID, ADDR (0, 0), - &type, &properties); - assert (err == 0); - shadow_root.type = type; - CAP_PROPERTIES_SET (&shadow_root, properties); - - if (type != cap_void) - as_alloc_at (ADDR (CAP_GUARD (&shadow_root), - CAP_GUARD_BITS (&shadow_root)), - 1); - /* We assume that the address space is well-formed and that all objects in the address space are described by hurd object descriptors. |