summaryrefslogtreecommitdiff
path: root/viengoos/as.c
diff options
context:
space:
mode:
authorneal <neal>2008-02-06 15:55:28 +0000
committerneal <neal>2008-02-06 15:55:28 +0000
commitb9a03ef381d1b7c92b96537515829a06ad7360be (patch)
treefcc680f3496d3f65d50108994b766e5a6d1e144d /viengoos/as.c
parent3355d3b116a2ce1d1e3220bbcca42dc0ced68aae (diff)
hurd/
2008-02-06 Neal H. Walfield <neal@gnu.org> * folio.h (folio_object_cap): New function. viengoos/ 2008-02-06 Neal H. Walfield <neal@gnu.org> * as.c (do_index): New function. (as_build_internal): Don't index a page table directly. Instead, use the above new function.
Diffstat (limited to 'viengoos/as.c')
-rw-r--r--viengoos/as.c172
1 files changed, 80 insertions, 92 deletions
diff --git a/viengoos/as.c b/viengoos/as.c
index 3c856a4..1b0ff7d 100644
--- a/viengoos/as.c
+++ b/viengoos/as.c
@@ -69,6 +69,51 @@ ensure_stack(int i)
#endif
+/* Index the object designed by PTE, which is at address ADDR return
+ the location of the idx'th capability slot. If the capability is
+ implicit, return a fabricated capability in *FAKE_SLOT and return
+ FAKE_SLOT. Return NULL on failure. */
+static inline struct cap *
+do_index (activity_t activity, addr_t addr, struct cap *pte, int idx,
+ struct cap *fake_slot)
+{
+ assert (pte->type == cap_cappage || pte->type == cap_rcappage
+ || pte->type == cap_folio);
+
+ /* Load the referenced object. */
+ struct object *pt = cap_to_object (activity, pte);
+ if (! pt)
+ /* PTE's type was not void but its designation was invalid. This
+ can only happen if we inserted an object and subsequently
+ destroyed it. */
+ {
+ /* The type should now have been set to cap_void. */
+ assert (pte->type == cap_void);
+ panic ("No object at " ADDR_FMT, ADDR_PRINTF (addr));
+ }
+
+ switch (pte->type)
+ {
+ case cap_cappage:
+ case cap_rcappage:
+ return &pt->caps[CAP_SUBPAGE_OFFSET (pte) + idx];
+
+ case cap_folio:;
+ struct folio *folio = (struct folio *) pt;
+
+ if (folio_object_type (folio, idx) == cap_void)
+ panic ("Can't use void object at " ADDR_FMT " for address translation",
+ ADDR_PRINTF (addr));
+
+ *fake_slot = folio_object_cap (folio, idx);
+
+ return fake_slot;
+
+ default:
+ return NULL;
+ }
+}
+
/* Build up the address space at AS_ROOT_ADDR such that there is a
capability slot at address ADDR. Returns the address of the
capability slot.
@@ -109,8 +154,6 @@ as_build_internal (activity_t activity,
do
{
- struct object *pt = NULL;
-
uint64_t pte_guard = CAP_GUARD (pte);
int pte_gbits = CAP_GUARD_BITS (pte);
@@ -154,87 +197,7 @@ as_build_internal (activity_t activity,
addr_prefix (addr), addr_depth (addr));
}
- switch (pte->type)
- {
- case cap_cappage:
- case cap_rcappage:
- /* Load the referenced object. */
- pt = cap_to_object (activity, pte);
- if (! pt)
- /* PTE's type was not void but its designation was
- invalid. This can only happen if we inserted an object
- and subsequently destroyed it. */
- {
- /* The type should now have been set to cap_void. */
- assert (pte->type == cap_void);
- AS_DUMP;
- panic ("Lost object at %llx/%d",
- addr_prefix (addr), addr_depth (addr) - remaining);
- }
-
- /* We index PT below. */
- break;
-
- case cap_folio:
- {
- if (remaining < FOLIO_OBJECTS_LOG2)
- panic ("Translating " ADDR_FMT "; not enough bits (%d) "
- "to index folio at " ADDR_FMT,
- ADDR_PRINTF (addr), remaining,
- ADDR_PRINTF (addr_chop (addr, remaining)));
-
- struct object *object = cap_to_object (activity, pte);
-#ifdef RM_INTERN
- if (! object)
- {
- debug (1, "Failed to get object with OID " OID_FMT,
- OID_PRINTF (pte->oid));
- return false;
- }
-#else
- assert (object);
-#endif
-
- struct folio *folio = (struct folio *) object;
-
- int i = extract_bits64_inv (prefix,
- remaining - 1, FOLIO_OBJECTS_LOG2);
- if (folio_object_type (folio, i) == cap_void)
- panic ("Translating " ADDR_FMT "; indexed folio at "
- ADDR_FMT ": void object",
- ADDR_PRINTF (addr),
- ADDR_PRINTF (addr_chop (addr, remaining)));
-
- pte = &fake_slot;
-
-#ifdef RM_INTERN
- struct object_desc *fdesc;
- fdesc = object_to_object_desc (object);
-
- object = object_find (activity, fdesc->oid + 1 + i,
- folio_object_policy (folio, i));
- assert (object);
- *pte = object_to_cap (object);
-#else
- /* We don't use cap_copy as we just need a byte
- copy. */
- *pte = folio->objects[i];
-#endif
-
- remaining -= FOLIO_OBJECTS_LOG2;
-
- /* Fall through means we index PT. But we just did
- that. Continue at the start of the loop. */
- continue;
- }
-
- default:
- AS_DUMP;
- panic ("Can't insert object at " ADDR_FMT ": "
- "%s at " ADDR_FMT " does not translate address bits",
- ADDR_PRINTF (addr), cap_type_string (pte->type),
- ADDR_PRINTF (addr_chop (addr, remaining)));
- }
+ /* We index the object designated by PTE below. */
}
else
/* There are two scenarios that lead us here: (1) the pte is
@@ -386,14 +349,16 @@ as_build_internal (activity_t activity,
/* No memory. */
return NULL;
- pt = cap_to_object (activity, &rt.cap);
-
/* Indirect access to the object designated by PTE via the
appropriate slot in new cappage (the pivot). */
int pivot_idx = extract_bits_inv (pte_guard,
pte_gbits - gbits - 1,
subpage_bits);
+ struct cap *pivot_cap = do_index (activity, cappage_addr,
+ &rt.cap, pivot_idx, &fake_slot);
+ assert (pivot_cap != &fake_slot);
+
addr_t pivot_addr = addr_extend (rt.storage,
pivot_idx,
CAPPAGE_SLOTS_LOG2);
@@ -405,7 +370,7 @@ as_build_internal (activity_t activity,
extract_bits64 (pte_guard, 0, d), d);
bool r = cap_copy_x (activity,
- ADDR_VOID, &pt->caps[pivot_idx], pivot_addr,
+ ADDR_VOID, pivot_cap, pivot_addr,
as_root_addr, *pte, pte_addr,
CAP_COPY_COPY_ADDR_TRANS_GUARD,
CAP_PROPERTIES (OBJECT_POLICY_DEFAULT,
@@ -414,7 +379,7 @@ as_build_internal (activity_t activity,
/* Finally, set the slot at PTE to point to PT. */
pte_guard = extract_bits64_inv (pte_guard,
- pte_gbits - 1, gbits);
+ pte_gbits - 1, gbits);
r = CAP_ADDR_TRANS_SET_GUARD_SUBPAGE (&addr_trans,
pte_guard, gbits,
0 /* We always use the
@@ -429,14 +394,31 @@ as_build_internal (activity_t activity,
CAP_COPY_COPY_ADDR_TRANS_SUBPAGE
| CAP_COPY_COPY_ADDR_TRANS_GUARD,
CAP_PROPERTIES (OBJECT_POLICY_DEFAULT, addr_trans));
-
assert (r);
}
- /* Index PT finding the next PTE. */
+ /* Index the object designated by PTE to find the next PTE. The
+ guard has already been translated. */
+ int width;
+ switch (pte->type)
+ {
+ case cap_cappage:
+ case cap_rcappage:
+ width = CAP_SUBPAGE_SIZE_LOG2 (pte);
+ break;
+
+ case cap_folio:
+ width = FOLIO_OBJECTS_LOG2;
+ break;
+
+ default:
+ AS_DUMP;
+ panic ("Can't insert object at " ADDR_FMT ": "
+ "%s at " ADDR_FMT " does not translate address bits",
+ ADDR_PRINTF (addr), cap_type_string (pte->type),
+ ADDR_PRINTF (addr_chop (addr, remaining)));
+ }
- /* The cappage referenced by PTE translates WIDTH bits. */
- int width = CAP_SUBPAGE_SIZE_LOG2 (pte);
/* That should not be more than we have left to translate. */
if (width > remaining)
{
@@ -445,8 +427,14 @@ as_build_internal (activity_t activity,
"not enough bits (%d)",
ADDR_PRINTF (addr), width, remaining);
}
+
int idx = extract_bits64_inv (prefix, remaining - 1, width);
- pte = &pt->caps[CAP_SUBPAGE_OFFSET (pte) + idx];
+
+ pte = do_index (activity, addr_chop (addr, remaining), pte, idx,
+ &fake_slot);
+ if (! pte)
+ panic ("Failed to index object at " ADDR_FMT,
+ ADDR_PRINTF (addr_chop (addr, remaining)));
remaining -= width;
}