summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hurd/ChangeLog46
-rw-r--r--hurd/cap.h537
-rw-r--r--hurd/folio.h42
-rw-r--r--hurd/thread.h26
-rw-r--r--libhurd-mm/ChangeLog16
-rw-r--r--libhurd-mm/as.c97
-rw-r--r--libhurd-mm/as.h11
-rw-r--r--libhurd-mm/storage.c17
-rw-r--r--ruth/ChangeLog6
-rw-r--r--ruth/ruth.c27
-rw-r--r--viengoos/ChangeLog26
-rw-r--r--viengoos/as.c10
-rw-r--r--viengoos/object.c3
-rw-r--r--viengoos/object.h8
-rw-r--r--viengoos/server.c124
-rw-r--r--viengoos/t-activity.c9
-rw-r--r--viengoos/t-as.c3
-rw-r--r--viengoos/thread.c4
-rw-r--r--viengoos/thread.h2
-rw-r--r--viengoos/viengoos.c5
20 files changed, 636 insertions, 383 deletions
diff --git a/hurd/ChangeLog b/hurd/ChangeLog
index 3aefacf..6ff740e 100644
--- a/hurd/ChangeLog
+++ b/hurd/ChangeLog
@@ -1,3 +1,49 @@
+2007-12-25 Neal H. Walfield <neal@gnu.org>
+
+ * cap.h: Include <stdint.h>.
+ (OBJECT_PRIORITY_BITS): Define.
+ (OBJECT_PRIORITY_MAX): Likewise.
+ (OBJECT_PRIORITY_LRU): Likewise.
+ (OBJECT_PRIORITY_MIN): Likewise.
+ (struct object_policy): New structure.
+ (OBJECT_POLICY_INIT): Define.
+ (OBJECT_POLICY): Likewise.
+ (OBJECT_POLICY_VOID): Likewise.
+ (OBJECT_POLICY_DEFAULT): Likewise.
+ (struct cap_properties): New structure.
+ (CAP_PROPERTIES_INIT): Define.
+ (CAP_PROPERTIES): Likewise.
+ (CAP_PROPERTIES_VOID): Likewise.
+ (CAP_PROPERTIES_DEFAULT): Likewise.
+ (struct cap): Add fields discardable and priority.
+ [RM_INTERN]: Reduce OID to 54 bits.
+ [! RM_INTERN]: Allow the shadow field an entire word.
+ (CAP_PROPERTIES_GET): Define.
+ (CAP_PROPERTIES_SET): Likewise.
+ (CAP_COPY_DISCARDABLE_SET): Likewise.
+ (CAP_COPY_PRIORITY_SET): Likewise.
+ (cap_copy): Remove the stuct cap_addr_trans parameter and replace
+ with a struct cap_properties. Update callers.
+ (cap_read): Likewise.
+ (object_slot_copy_out): Likewise.
+ (object_slot_copy_in): Likewise.
+ (object_slot_read): Likewise.
+ (cap_copy_x): Likewise. Save the object policies in the shadow
+ capability.
+ (cap_get_shadow): Don't munge the address.
+ (cap_set_shadow): Likewise.
+ * thread.h: Include <hurd/cap.h>.
+ (struct hurd_thread_exregs_in): Remove field aspace_addr_trans.
+ Add field aspace_cap_properties. Rename field
+ aspace_addr_trans_flags to aspace_cap_properties_flags.
+ * folio.h (struct folio): Remove field discardable. Add field
+ policy.
+ (folio_object_alloc): Take an additional argument, a struct
+ object_policy. Update users.
+
+ * cap.h (cap_is_a): Remove dead code.
+ (cap_is_a_page): Remove dead code.
+
2007-12-24 Neal H. Walfield <neal@gnu.org>
* addr-trans.h (CAP_ADDR_TRANS_INIT): Define.
diff --git a/hurd/cap.h b/hurd/cap.h
index 90049af..cbbf8fd 100644
--- a/hurd/cap.h
+++ b/hurd/cap.h
@@ -4,8 +4,6 @@
This file is part of the GNU Hurd.
- This file is part of the GNU Hurd.
-
GNU Hurd is free software: you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3 of the
@@ -28,19 +26,186 @@
#include <hurd/addr-trans.h>
#include <hurd/startup.h>
#include <errno.h>
+#include <stdint.h>
-#ifndef RM_INTERN
-#include <pthread.h>
+/* Capabilities.
-/* When reading or modifying the address space metadata, this
- lock must be held. */
-extern pthread_rwlock_t as_lock;
-#endif
+ Capabilities have three functions: a capability can designate an
+ object, it can participate in address translation, and it can be
+ used to control how the designated object should be managed. */
+
+/* The types of objects designated by capabilities. */
+enum cap_type
+ {
+#define CAP_TYPE_MIN cap_void
+ cap_void,
+ cap_page,
+ cap_rpage,
+ cap_cappage,
+ cap_rcappage,
+ cap_folio,
+ cap_activity,
+ cap_activity_control,
+ cap_thread,
+#define CAP_TYPE_MAX cap_thread
+ };
+
+static inline const char *
+cap_type_string (enum cap_type type)
+{
+ switch (type)
+ {
+ case cap_void:
+ return "void";
+ case cap_page:
+ return "page";
+ case cap_rpage:
+ return "rpage";
+ case cap_cappage:
+ return "cappage";
+ case cap_rcappage:
+ return "rcappage";
+ case cap_folio:
+ return "folio";
+ case cap_activity:
+ return "activity";
+ case cap_activity_control:
+ return "activity_control";
+ case cap_thread:
+ return "thread";
+ default:
+ return "unknown cap type";
+ };
+}
+
+/* Return whether two types are compatible in the sense that two caps
+ with the given types can designate the same object. */
+static inline bool
+cap_types_compatible (enum cap_type a, enum cap_type b)
+{
+ if (a == b)
+ return true;
+
+ if (a == cap_page && b == cap_rpage)
+ return true;
+ if (a == cap_rpage && b == cap_page)
+ return true;
+
+ if (a == cap_cappage && b == cap_rcappage)
+ return true;
+ if (a == cap_rcappage && b == cap_cappage)
+ return true;
+
+ if (a == cap_activity && b == cap_activity_control)
+ return true;
+ if (a == cap_activity_control && b == cap_activity)
+ return true;
+
+ return false;
+}
+
+/* Returns weather TYPE corresponds to a weak type. */
+static inline bool
+cap_type_weak_p (enum cap_type type)
+{
+ switch (type)
+ {
+ case cap_rpage:
+ case cap_rcappage:
+ case cap_activity:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+/* Returns the weakened type corresponding to TYPE. If type is
+ already a weak type, returns TYPE. */
+static inline enum cap_type
+cap_type_weaken (enum cap_type type)
+{
+ switch (type)
+ {
+ case cap_page:
+ case cap_rpage:
+ return cap_rpage;
+
+ case cap_cappage:
+ case cap_rcappage:
+ return cap_rcappage;
+
+ case cap_activity_control:
+ case cap_activity:
+ return cap_activity;
+
+ default:
+ return cap_void;
+ }
+}
-/* A capability. */
+/* Object policy. */
+
+/* The object priority is a signed 10-bit number. A lower numeric
+ value corresponds to a higher priority. */
+#define OBJECT_PRIORITY_BITS 10
+#define OBJECT_PRIORITY_MAX (-(1 << (OBJECT_PRIORITY_BITS - 1)))
+#define OBJECT_PRIORITY_LRU (0)
+#define OBJECT_PRIORITY_MIN ((1 << (OBJECT_PRIORITY_BITS - 1)) - 1)
+
+struct object_policy
+{
+ union
+ {
+ struct
+ {
+ int16_t pad0 : 5;
+
+ /* Whether a page is discardable (if so and the page is not
+ zero, trying to read the page from disk generates a first
+ fault fault). */
+ int16_t discardable : 1;
+
+ /* An object's priority. If can be used to override LRU
+ eviction. When a memory object is to be evicted, we select
+ the object with the lowest priority (higher value = lower
+ priority). */
+ int16_t priority : OBJECT_PRIORITY_BITS;
+ };
+ uint16_t raw;
+ };
+};
+
+#define OBJECT_POLICY_INIT { { raw: 0 } }
+#define OBJECT_POLICY(__op_discardable, __op_priority) \
+ (struct object_policy) { { { 0, (__op_discardable), (__op_priority) } } }
+/* The default object policy: not discardable, managed by LRU. */
+#define OBJECT_POLICY_VOID \
+ OBJECT_POLICY (false, OBJECT_PRIORITY_LRU)
+/* Synonym for OBJECT_POLICY_VOID. */
+#define OBJECT_POLICY_DEFAULT OBJECT_POLICY_VOID
+
+/* Capability properties. */
+
+struct cap_properties
+{
+ struct object_policy policy;
+ struct cap_addr_trans addr_trans;
+};
+
+#define CAP_PROPERTIES_INIT \
+ { OBJECT_POLICY_INIT, CAP_ADDR_TRANS_INIT }
+#define CAP_PROPERTIES(__op_object_policy, __op_addr_trans) \
+ (struct cap_properties) { __op_object_policy, __op_addr_trans }
+#define CAP_PROPERTIES_VOID \
+ CAP_PROPERTIES (OBJECT_POLICY_INIT, CAP_ADDR_TRANS_INIT)
+#define CAP_PROPERTIES_DEFAULT CAP_PROPERTIES_VOID
+
+/* Capability representation. */
#ifdef RM_INTERN
-/* An OID corresponds to a page on a volume. */
+/* An OID corresponds to a page on a volume. Only the least 54 bits
+ are significant. */
typedef l4_uint64_t oid_t;
#define OID_FMT "%llx"
#define OID_PRINTF(__op_oid) ((oid_t) (__op_oid))
@@ -54,27 +219,64 @@ struct cap
#ifdef RM_INTERN
/* For a description of how versioning works, refer to the comment
titled "Object versioning" in object.h. */
- l4_uint32_t version : CAP_VERSION_BITS;
-
- l4_uint32_t pad0 : 32 - CAP_VERSION_BITS - CAP_TYPE_BITS;
- l4_uint32_t type : CAP_TYPE_BITS;
+ uint32_t version : CAP_VERSION_BITS;
+ uint32_t type : CAP_TYPE_BITS;
+ uint32_t discardable : 1;
+ uint32_t pad0 : 32 - CAP_VERSION_BITS - CAP_TYPE_BITS - 1;
struct cap_addr_trans addr_trans;
- /* If the capability names an object, the object id. */
- oid_t oid;
+ /* The designated object's priority. */
+ uint64_t priority : OBJECT_PRIORITY_BITS;
+ /* If the capability designates an object, the object id. */
+ uint64_t oid : 54;
#else
- /* The shadow object (only for cappages). Maximal address is
- 256G. */
- l4_uint32_t shadow : 32 - CAP_TYPE_BITS;
+ /* The shadow object (only for cappages and folios). */
+ struct object *shadow;
+
+ uint32_t discardable : 1;
+ uint32_t priority : OBJECT_PRIORITY_BITS;
- l4_uint32_t type : CAP_TYPE_BITS;
+ uint32_t type : CAP_TYPE_BITS;
+
+ uint32_t pad0 : 32 - 1 - OBJECT_PRIORITY_BITS - CAP_TYPE_BITS;
/* This capability's address description. */
struct cap_addr_trans addr_trans;
#endif
};
+/* Collect __CPG_CAP's properties. */
+#define CAP_PROPERTIES_GET(__cpg_cap) \
+ CAP_PROPERTIES (OBJECT_POLICY ((__cpg_cap).discardable, \
+ (__cpg_cap).priority), \
+ (__cpg_cap).addr_trans)
+/* Set *__CPS_CAP's properties to __CPS_PROPERTIES. */
+#define CAP_PROPERTIES_SET(__cps_cap, __cps_properties) \
+ do \
+ { \
+ (__cps_cap)->discardable = (__cps_properties).policy.discardable; \
+ (__cps_cap)->priority = (__cps_properties).policy.priority; \
+ (__cps_cap)->addr_trans = (__cps_properties).addr_trans; \
+ } \
+ while (0)
+
+/* Convenience macros for printing capabilities. */
+
+#ifdef RM_INTERN
+#define CAP_FMT "{ " OID_FMT ".%d:%s %llx/%d; %d/%d }"
+#define CAP_PRINTF(cap) \
+ OID_PRINTF ((cap)->oid), (cap)->version, cap_type_string ((cap)->type), \
+ CAP_GUARD ((cap)), CAP_GUARD_BITS ((cap)), \
+ CAP_SUBPAGE ((cap)), CAP_SUBPAGES ((cap))
+#else
+#define CAP_FMT "{ %s %llx/%d; %d/%d }"
+#define CAP_PRINTF(cap) \
+ cap_type_string ((cap)->type), \
+ CAP_GUARD ((cap)), CAP_GUARD_BITS ((cap)), \
+ CAP_SUBPAGE ((cap)), CAP_SUBPAGES ((cap))
+#endif
+
/* Accessors corresponding to the CAP_ADDR_TRANS macros. */
#define CAP_SUBPAGES_LOG2(cap_) \
CAP_ADDR_TRANS_SUBPAGES_LOG2((cap_)->addr_trans)
@@ -113,22 +315,8 @@ struct cap
CAP_SET_GUARD_SUBPAGE ((cap_), CAP_GUARD (cap_), CAP_GUARD_BITS (cap_), \
(subpage_), (subpages_))
-/* The types of objects designated by capabilities. */
-enum cap_type
- {
-#define CAP_TYPE_MIN cap_void
- cap_void,
- cap_page,
- cap_rpage,
- cap_cappage,
- cap_rcappage,
- cap_folio,
- cap_activity,
- cap_activity_control,
- cap_thread,
-#define CAP_TYPE_MAX cap_thread
- };
-
+/* Capability-related methods. */
+
#define RPC_STUB_PREFIX rm
#define RPC_ID_PREFIX RM
#undef RPC_TARGET_NEED_ARG
@@ -161,173 +349,71 @@ enum
CAP_COPY_COPY_SOURCE_GUARD = 1 << 2,
/* When copying the capability copies a weakened reference. */
- CAP_COPY_WEAKEN = 1 << 3
+ CAP_COPY_WEAKEN = 1 << 3,
+
+ /* Set the discardable bit on the capability. */
+ CAP_COPY_DISCARDABLE_SET = 1 << 4,
+
+ /* Set the priority of the object. */
+ CAP_COPY_PRIORITY_SET = 1 << 5,
};
-/* Copy capability SOURCE to the capability slot TARGET.
- ADDR_TRANS_FLAGS is a subset of CAP_COPY_GUARD, CAP_COPY_SUBPAGE,
- and CAP_COPY_PRESERVE_GUARD, bitwise-ored. If CAP_COPY_GUARD is
- set, the guard descriptor in CAP_ADDR_TRANS is used, if
- CAP_COPY_PRESERVE_GUARD, the guard descriptor in TARGET, otherwise,
- the guard descriptor is copied from SOURCE. If CAP_COPY_SUBPAGE is
- set, the subpage descriptor in CAP_ADDR_TRANS is used, otherwise,
- the subpage descriptor is copied from SOURCE. */
+/* Copy the capability in capability slot SOURCE to the slot TARGET.
+
+ By default, preserves SOURCE's subpage specification and TARGET's
+ guard.
+
+ If CAP_COPY_COPY_SUBPAGE is set, then uses the subpage
+ specification in CAP_PROPERTIES. If CAP_COPY_COPY_ADDR_TRANS_GUARD
+ is set, uses the guard description in CAP_PROPERTIES.
+
+ If CAP_COPY_COPY_SOURCE_GUARD is set, uses the guard description in
+ source. Otherwise, preserves the guard in TARGET.
+
+ If CAP_COPY_WEAKEN is set, saves a weakened version of SOURCE in
+ *TARGET (e.g., if SOURCE's type is cap_page, *TARGET's type is set
+ to cap_rpage).
+
+ If CAP_COPY_DISCARDABLE_SET is set, then sets the discardable bit
+ based on the value in PROPERTIES. Otherwise, copies SOURCE's
+ value.
+
+ If CAP_COPY_PRIORITY_SET is set, then sets the priority based on
+ the value in properties. Otherwise, copies SOURCE's value. */
RPC(cap_copy, 5, 0, addr_t, principal, addr_t, target, addr_t, source,
- l4_word_t, addr_trans_flags, struct cap_addr_trans, cap_addr_trans)
+ l4_word_t, flags, struct cap_properties, properties)
-/* Store the public bits of the capability CAP in *TYPE and
- *CAP_ADDR_TRANS. */
+/* Returns the public bits of the capability CAP in TYPE and
+ CAP_PROPERTIES. */
RPC(cap_read, 2, 2, addr_t, principal, addr_t, cap,
/* Out: */
- l4_word_t, type, struct cap_addr_trans, cap_addr_trans)
+ l4_word_t, type, struct cap_properties, properties)
/* Copy the capability from slot SLOT of the object OBJECT (relative
- to the start of the object's subpage) to slot TARGET. */
+ to the start of the object's subpage) to slot TARGET. PROPERTIES
+ are interpreted as per cap_copy. */
RPC(object_slot_copy_out, 6, 0, addr_t, principal,
addr_t, object, l4_word_t, slot, addr_t, target,
- l4_word_t, flags, struct cap_addr_trans, cap_addr_trans)
+ l4_word_t, flags, struct cap_properties, properties)
/* Copy the capability from slot SOURCE to slot INDEX of the object
- OBJECT (relative to the start of the object's subpage). */
+ OBJECT (relative to the start of the object's subpage). PROPERTIES
+ are interpreted as per cap_copy. */
RPC(object_slot_copy_in, 6, 0, addr_t, principal,
addr_t, object, l4_word_t, index, addr_t, source,
- l4_word_t, flags, struct cap_addr_trans, cap_addr_trans)
+ l4_word_t, flags, struct cap_properties, properties)
-/* Store the public bits of the capability slot SLOT of object
- OBJECT in *TYPE and *CAP_ADDR. */
+/* Store the public bits of the capability slot SLOT of object OBJECT
+ in TYPE and CAP_PROPERTIES. */
RPC(object_slot_read, 3, 2, addr_t, principal,
addr_t, object, l4_word_t, slot,
/* Out: */
- l4_word_t, type, struct cap_addr_trans, cap_addr_trans)
+ l4_word_t, type, struct cap_properties, properties)
#undef RPC_STUB_PREFIX
#undef RPC_ID_PREFIX
#undef RPC_TARGET
-/* Return whether cap CAP is of type TYPE. */
-static inline bool
-cap_is_a (struct cap *cap, enum cap_type type)
-{
- return cap->type == type;
-}
-
-/* Return whether capability CAP allegedly designates a page
- object. */
-static inline bool
-cap_is_a_page (struct cap *cap)
-{
- return cap_is_a (cap, cap_page) || cap_is_a (cap, cap_rpage)
- || cap_is_a (cap, cap_cappage) || cap_is_a (cap, cap_rcappage);
-}
-
-/* Return whether two types are compatible in the sense that two caps
- with the given types can designate the same object. */
-static inline bool
-cap_types_compatible (enum cap_type a, enum cap_type b)
-{
- if (a == b)
- return true;
-
- if (a == cap_page && b == cap_rpage)
- return true;
- if (a == cap_rpage && b == cap_page)
- return true;
-
- if (a == cap_cappage && b == cap_rcappage)
- return true;
- if (a == cap_rcappage && b == cap_cappage)
- return true;
-
- if (a == cap_activity && b == cap_activity_control)
- return true;
- if (a == cap_activity_control && b == cap_activity)
- return true;
-
- return false;
-}
-
-/* Returns weather TYPE corresponds to a weak type. */
-static inline bool
-cap_type_weak_p (enum cap_type type)
-{
- switch (type)
- {
- case cap_rpage:
- case cap_rcappage:
- case cap_activity:
- return true;
-
- default:
- return false;
- }
-}
-
-/* Returns the weakened type corresponding to TYPE. If type is
- already a weak type, returns TYPE. */
-static inline enum cap_type
-cap_type_weaken (enum cap_type type)
-{
- switch (type)
- {
- case cap_page:
- case cap_rpage:
- return cap_rpage;
-
- case cap_cappage:
- case cap_rcappage:
- return cap_rcappage;
-
- case cap_activity_control:
- case cap_activity:
- return cap_activity;
-
- default:
- return cap_void;
- }
-}
-
-static inline const char *
-cap_type_string (enum cap_type type)
-{
- switch (type)
- {
- case cap_void:
- return "void";
- case cap_page:
- return "page";
- case cap_rpage:
- return "rpage";
- case cap_cappage:
- return "cappage";
- case cap_rcappage:
- return "rcappage";
- case cap_folio:
- return "folio";
- case cap_activity:
- return "activity";
- case cap_activity_control:
- return "activity_control";
- case cap_thread:
- return "thread";
- default:
- return "unknown cap type";
- };
-}
-
-#ifdef RM_INTERN
-#define CAP_FMT "{ %lld.%d:%s %llx/%d; %d/%d }"
-#define CAP_PRINTF(cap) \
- (cap)->oid, (cap)->version, cap_type_string ((cap)->type), \
- CAP_GUARD ((cap)), CAP_GUARD_BITS ((cap)), \
- CAP_SUBPAGE ((cap)), CAP_SUBPAGES ((cap))
-#else
-#define CAP_FMT "{ %s %llx/%d; %d/%d }"
-#define CAP_PRINTF(cap) \
- cap_type_string ((cap)->type), \
- CAP_GUARD ((cap)), CAP_GUARD_BITS ((cap)), \
- CAP_SUBPAGE ((cap)), CAP_SUBPAGES ((cap))
-#endif
-
/* An object. */
/* The number of capabilities per page. */
@@ -361,24 +447,21 @@ typedef addr_t activity_t;
static inline void *
cap_get_shadow (const struct cap *cap)
{
- return (void *) ((l4_word_t) cap->shadow << PAGESIZE_LOG2);
+ return cap->shadow;
}
/* Set CAP's shadow object to SHADOW. */
static inline void
cap_set_shadow (struct cap *cap, void *shadow)
{
- assert (((uintptr_t) shadow & (PAGESIZE - 1)) == 0);
- cap->shadow = (uintptr_t) shadow >> PAGESIZE_LOG2;
- assert (cap_get_shadow (cap) == shadow);
+ cap->shadow = shadow;
}
#endif
/* Given cap CAP, return the corresponding object, or NULL, if there
is none. */
#ifdef RM_INTERN
-extern struct object *cap_to_object (activity_t activity,
- struct cap *cap);
+extern struct object *cap_to_object (activity_t activity, struct cap *cap);
#else
static inline struct object *
cap_to_object (activity_t activity, struct cap *cap)
@@ -387,18 +470,13 @@ cap_to_object (activity_t activity, struct cap *cap)
}
#endif
-/* Copy the capability SOURCE to capability TARGET. By default,
- preserves SOURCE's subpage specification and TARGET's guard. If
- CAP_COPY_COPY_SUBPAGE is set, then uses the subpage specification
- in CAP_ADDR_TRANS. If CAP_COPY_COPY_ADDR_TRANS_GUARD is set, uses
- the guard description in CAP_ADDR_TRANS. If
- CAP_COPY_COPY_SOURCE_GUARD is set, uses the guard description in
- source. Otherwise, preserves the guard in TARGET. */
+/* Wrapper for the cap_copy method. Also updates shadow
+ capabilities. */
static inline bool
cap_copy_x (activity_t activity,
struct cap *target, addr_t target_addr,
struct cap source, addr_t source_addr,
- int flags, struct cap_addr_trans cap_addr_trans)
+ int flags, struct cap_properties properties)
{
/* By default, we preserve SOURCE's subpage
specification. */
@@ -406,9 +484,9 @@ cap_copy_x (activity_t activity,
int subpages = CAP_SUBPAGES (&source);
if ((flags & CAP_COPY_COPY_ADDR_TRANS_SUBPAGE))
- /* Copy the subpage descriptor from CAP_ADDR_TRANS. */
+ /* Copy the subpage descriptor from PROPERTIES.ADDR_TRANS. */
{
- if (CAP_ADDR_TRANS_SUBPAGES (cap_addr_trans) != 1
+ if (CAP_ADDR_TRANS_SUBPAGES (properties.addr_trans) != 1
&& (source.type != cap_cappage
&& source.type != cap_rcappage))
/* A subpage descriptor is only valid for
@@ -416,35 +494,35 @@ cap_copy_x (activity_t activity,
{
debug (1, "subpages (%d) specified for non-cappage "
"cap " CAP_FMT,
- CAP_ADDR_TRANS_SUBPAGES (cap_addr_trans),
+ CAP_ADDR_TRANS_SUBPAGES (properties.addr_trans),
CAP_PRINTF (&source));
return false;
}
-
+
if (!
- (/* Start of CAP_ADDR_TRANS must be at or after start of
+ (/* Start of PROPERTIES.ADDR_TRANS must be at or after start of
SOURCE. */
subpage * (256 / subpages)
- <= (CAP_ADDR_TRANS_SUBPAGE (cap_addr_trans) *
- (256 / CAP_ADDR_TRANS_SUBPAGES (cap_addr_trans)))
- /* End of CAP_ADDR_TRANS must be before or at end of
+ <= (CAP_ADDR_TRANS_SUBPAGE (properties.addr_trans) *
+ (256 / CAP_ADDR_TRANS_SUBPAGES (properties.addr_trans)))
+ /* End of PROPERTIES.ADDR_TRANS must be before or at end of
SOURCE. */
- && (((CAP_ADDR_TRANS_SUBPAGE (cap_addr_trans) + 1) *
- (256 / CAP_ADDR_TRANS_SUBPAGES (cap_addr_trans)))
+ && (((CAP_ADDR_TRANS_SUBPAGE (properties.addr_trans) + 1) *
+ (256 / CAP_ADDR_TRANS_SUBPAGES (properties.addr_trans)))
<= (subpage + 1) * (256 / subpages))))
/* The subpage descriptor does not narrow the
rights. */
{
debug (1, "specified subpage (%d/%d) not a subset "
" of source " CAP_FMT,
- CAP_ADDR_TRANS_SUBPAGE (cap_addr_trans),
- CAP_ADDR_TRANS_SUBPAGES (cap_addr_trans),
+ CAP_ADDR_TRANS_SUBPAGE (properties.addr_trans),
+ CAP_ADDR_TRANS_SUBPAGES (properties.addr_trans),
CAP_PRINTF (&source));
return false;
}
- subpage = CAP_ADDR_TRANS_SUBPAGE (cap_addr_trans);
- subpages = CAP_ADDR_TRANS_SUBPAGES (cap_addr_trans);
+ subpage = CAP_ADDR_TRANS_SUBPAGE (properties.addr_trans);
+ subpages = CAP_ADDR_TRANS_SUBPAGES (properties.addr_trans);
}
/* By default, we preserve the guard in TARGET. */
@@ -452,10 +530,10 @@ cap_copy_x (activity_t activity,
int gbits = CAP_GUARD_BITS (target);
if ((flags & CAP_COPY_COPY_ADDR_TRANS_GUARD))
- /* Copy guard from CAP_ADDR_TRANS. */
+ /* Copy guard from PROPERTIES.ADDR_TRANS. */
{
- guard = CAP_ADDR_TRANS_GUARD (cap_addr_trans);
- gbits = CAP_ADDR_TRANS_GUARD_BITS (cap_addr_trans);
+ guard = CAP_ADDR_TRANS_GUARD (properties.addr_trans);
+ gbits = CAP_ADDR_TRANS_GUARD_BITS (properties.addr_trans);
}
else if ((flags & CAP_COPY_COPY_SOURCE_GUARD))
/* Copy guard from SOURCE. */
@@ -507,6 +585,14 @@ cap_copy_x (activity_t activity,
changes_translation = true;
}
+ if (target->type != source.type
+ && ! ((flags & CAP_COPY_WEAKEN)
+ && cap_type_weaken (source.type) == target->type))
+ {
+ debug (5, "Type changed, invalidating translation");
+ changes_translation = true;
+ }
+
if (changes_translation)
{
extern void cap_shootdown (struct activity *activity, struct cap *cap);
@@ -515,7 +601,7 @@ cap_copy_x (activity_t activity,
}
#endif
- if (! CAP_ADDR_TRANS_SET_GUARD_SUBPAGE (&cap_addr_trans,
+ if (! CAP_ADDR_TRANS_SET_GUARD_SUBPAGE (&properties.addr_trans,
guard, gbits,
subpage, subpages))
return false;
@@ -524,18 +610,23 @@ cap_copy_x (activity_t activity,
assert (! ADDR_IS_VOID (target_addr));
assert (! ADDR_IS_VOID (source_addr));
- error_t err = rm_cap_copy (activity, target_addr,
- source_addr, flags,
- cap_addr_trans);
+ error_t err = rm_cap_copy (activity, target_addr, source_addr,
+ flags, properties);
assert (err == 0);
#endif
*target = source;
- target->addr_trans = cap_addr_trans;
+ target->addr_trans = properties.addr_trans;
if ((flags & CAP_COPY_WEAKEN))
target->type = cap_type_weaken (target->type);
+ if ((flags & CAP_COPY_DISCARDABLE_SET))
+ target->discardable = properties.policy.discardable;
+
+ if ((flags & CAP_COPY_PRIORITY_SET))
+ target->priority = properties.policy.priority;
+
return true;
}
@@ -547,9 +638,21 @@ cap_copy (activity_t activity,
struct cap source, addr_t source_addr)
{
return cap_copy_x (activity, target, target_addr,
- source, source_addr, 0, CAP_ADDR_TRANS_VOID);
+ source, source_addr, 0, CAP_PROPERTIES_VOID);
}
+#ifndef RM_INTERN
+#include <pthread.h>
+
+/* When reading or modifying the address space metadata, this
+ lock must be held. */
+extern pthread_rwlock_t as_lock;
+#endif
+
+/* Dump an address space where ROOT is a ROOT. */
+extern void as_dump_from (activity_t activity, struct cap *root,
+ const char *prefix);
+
/* Return the value of the capability at ADDR or, if an object, the
value of the capability designating the object, in the address
space rooted by ROOT.
diff --git a/hurd/folio.h b/hurd/folio.h
index 8eb9308..bbfe7af 100644
--- a/hurd/folio.h
+++ b/hurd/folio.h
@@ -4,28 +4,27 @@
This file is part of the GNU Hurd.
- The GNU Hurd is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
+ GNU Hurd is free software: you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation, either version 3 of the
+ License, or (at your option) any later version.
- The GNU Hurd is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
+ GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA. */
+ License along with GNU Hurd. If not, see
+ <http://www.gnu.org/licenses/>. */
#ifndef _HURD_FOLIO_H
#define _HURD_FOLIO_H 1
#include <hurd/types.h>
#include <hurd/addr.h>
-#include <hurd/startup.h>
#include <hurd/cap.h>
+#include <hurd/startup.h>
#include <stdint.h>
/* Number of user objects per folio. */
@@ -37,6 +36,7 @@ enum
{
FOLIO_OBJECTS_LOG2 = 7,
};
+
/* User settable folio policy. */
/* The range of valid folio priorities. A lower numerical value
@@ -113,15 +113,10 @@ struct folio
/* The type Page type. */
l4_uint32_t type : CAP_TYPE_BITS;
- /* Whether a page is has any content (i.e., if it is not
+ /* Whether a page has any content (i.e., if it is not
uninitialized). */
l4_uint32_t content : 1;
- /* Whether a page is discardable (if so and the page is not zero,
- trying to read the page from disk generates a first fault
- fault). */
- l4_uint32_t discardable : 1;
-
/* We only need to bump the object's version when we can't easily
reclaim all references. If there are no references or if the
only references are in memory and thus easy to find, we can just
@@ -137,6 +132,8 @@ struct folio
are only in-memory. */
l4_uint32_t mhazard : 1;
+ struct object_policy policy;
+
/* 128-bit md5sum of each object. */
l4_uint64_t checksum[2];
@@ -167,7 +164,7 @@ enum
RM_folio_alloc = 200,
RM_folio_free,
RM_folio_object_alloc,
- RM_folio_policy,
+ RM_folio_policy
};
/* Allocate a folio against PRINCIPAL. Store a capability in the
@@ -180,12 +177,13 @@ RPC(folio_alloc, 3, 0, addr_t, principal, addr_t, folio,
RPC(folio_free, 2, 0, addr_t, principal, addr_t, folio)
/* Allocate INDEXth object in folio FOLIO as an object of type TYPE.
- PRINCIPAL is charged. If OBJECT_SLOT is not ADDR_VOID, then stores
- a capability to the allocated object in OBJECT_SLOT. If
- OBJECT_WEAK_SLOT is not ADDR_VOID, stores a weaken reference to the
- created object. */
-RPC(folio_object_alloc, 6, 0, addr_t, principal,
+ POLICY specifies the object's policy when accessed via the folio.
+ If OBJECT_SLOT is not ADDR_VOID, then stores a capability to the
+ allocated object in OBJECT_SLOT. If OBJECT_WEAK_SLOT is not
+ ADDR_VOID, stores a weaken reference to the created object. */
+RPC(folio_object_alloc, 7, 0, addr_t, principal,
addr_t, folio, l4_word_t, index, l4_word_t, type,
+ struct object_policy, policy,
addr_t, object_slot, addr_t, object_weak_slot)
/* Flags for folio_policy. */
diff --git a/hurd/thread.h b/hurd/thread.h
index 4f9bd12..a963d1b 100644
--- a/hurd/thread.h
+++ b/hurd/thread.h
@@ -2,29 +2,27 @@
Copyright (C) 2007 Free Software Foundation, Inc.
Written by Neal H. Walfield <neal@gnu.org>.
- This file is part of the GNU Hurd.
+ GNU Hurd is free software: you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation, either version 3 of the
+ License, or (at your option) any later version.
- The GNU Hurd is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU Hurd is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
+ GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA. */
+ License along with GNU Hurd. If not, see
+ <http://www.gnu.org/licenses/>. */
#ifndef _HURD_THREAD_H
#define _HURD_THREAD_H 1
#include <hurd/types.h>
-#include <hurd/startup.h>
#include <hurd/addr-trans.h>
+#include <hurd/cap.h>
+#include <hurd/startup.h>
#include <l4/syscall.h>
#include <l4/ipc.h>
@@ -151,8 +149,8 @@ struct hurd_thread_exregs_in
l4_word_t control;
addr_t aspace;
- l4_word_t aspace_addr_trans_flags;
- struct cap_addr_trans aspace_addr_trans;
+ uintptr_t aspace_cap_properties_flags;
+ struct cap_properties aspace_cap_properties;
addr_t activity;
diff --git a/libhurd-mm/ChangeLog b/libhurd-mm/ChangeLog
index b8ba468..5fbfb56 100644
--- a/libhurd-mm/ChangeLog
+++ b/libhurd-mm/ChangeLog
@@ -1,3 +1,19 @@
+2007-12-25 Neal H. Walfield <neal@gnu.org>
+
+ * as.h: Change VISIT's signature: pass a struct cap_properties
+ instead of a struct cap_addr_trans. Update callers.
+ * as.c (as_walk): Change VISIT's signature: pass a struct
+ cap_properties instead of a struct cap_addr_trans. Call VISIT
+ appropriately.
+ (as_alloc_slow): Update rm_cap_read use to reflect API changes.
+ (as_init): Update rm_cap_read use to reflect API changes. Use
+ CAP_PROPERTIES_SET to set shadow capability properties.
+ * storage.c (shadow_setup): Update rm_folio_object_alloc use to
+ reflect API changes. Also save the object policy in the shadow
+ capability.
+ (storage_alloc_): Likewise.
+ (storage_free_): Likewise.
+
2007-12-22 Neal H. Walfield <neal@gnu.org>
* storage.c (storage_alloc_): Update rm_folio_alloc use to reflect
diff --git a/libhurd-mm/as.c b/libhurd-mm/as.c
index 7c529c4..3618802 100644
--- a/libhurd-mm/as.c
+++ b/libhurd-mm/as.c
@@ -393,7 +393,7 @@ as_alloc_slow (int width)
addr_t slot = ADDR_VOID;
int find_free_slot (addr_t addr,
- l4_word_t type, struct cap_addr_trans addr_trans,
+ l4_word_t type, struct cap_properties properties,
bool writable,
void *cookie)
{
@@ -425,13 +425,14 @@ as_alloc_slow (int width)
/* Overlaps the UTCB. */
return 0;
- /* Be sure we haven't already given this addrss out. */
+ /* Be sure we haven't already given this address out. */
int i;
for (i = 0; i < desc_additional_count; i ++)
{
struct hurd_object_desc *desc = &desc_additional[i];
if (ADDR_EQ (addr, addr_chop (desc->object,
- CAP_ADDR_TRANS_GUARD_BITS (addr_trans))))
+ CAP_ADDR_TRANS_GUARD_BITS
+ (properties.addr_trans))))
return 0;
}
@@ -452,10 +453,10 @@ as_alloc_slow (int width)
int gbits = ADDR_BITS - addr_depth (slot) - width;
assert (gbits >= 0);
- struct cap_addr_trans cap_addr_trans = CAP_ADDR_TRANS_VOID;
- CAP_ADDR_TRANS_SET_GUARD (&cap_addr_trans, 0, gbits);
+ struct cap_properties properties = CAP_PROPERTIES_DEFAULT;
+ CAP_ADDR_TRANS_SET_GUARD (&properties.addr_trans, 0, gbits);
err = rm_cap_copy (meta_data_activity, slot, slot,
- CAP_COPY_COPY_ADDR_TRANS_GUARD, cap_addr_trans);
+ CAP_COPY_COPY_ADDR_TRANS_GUARD, properties);
if (err)
panic ("failed to copy capability: %d", err);
@@ -572,18 +573,20 @@ as_init (void)
cappage. */
bool have_one = false;
- /* XXX: Would be nice have syscall bundling here. */
+ /* 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, slot_addr,
- &type, &slot->addr_trans);
+ &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. */
@@ -607,10 +610,12 @@ as_init (void)
/* Shadow the root capability. */
l4_word_t type;
+ struct cap_properties properties;
err = rm_cap_read (meta_data_activity, ADDR (0, 0),
- &type, &shadow_root.addr_trans);
+ &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),
@@ -690,7 +695,7 @@ as_init (void)
/* Walk the address space the hard way and make sure that we've got
everything. */
int visit (addr_t addr,
- l4_word_t type, struct cap_addr_trans addr_trans,
+ l4_word_t type, struct cap_properties properties,
bool writable, void *cookie)
{
struct cap *cap = slot_lookup_rel (meta_data_activity,
@@ -699,7 +704,14 @@ as_init (void)
ADDR_PRINTF (addr), cap_type_string (type));
assert (cap->type == type);
- assert (cap->addr_trans.raw == addr_trans.raw);
+
+ struct cap_properties properties2 = CAP_PROPERTIES_GET (*cap);
+ assert (properties.policy.discardable == properties2.policy.discardable);
+ assertx (properties.policy.priority == properties2.policy.priority,
+ ADDR_FMT "(%s) %d != %d",
+ ADDR_PRINTF (addr), cap_type_string (type),
+ properties.policy.priority, properties2.policy.priority);
+ assert (properties.addr_trans.raw == properties2.addr_trans.raw);
return 0;
}
@@ -752,14 +764,13 @@ slot_lookup (activity_t activity,
/* Walk the address space, depth first. VISIT is called for each
*slot* for which (1 << reported capability type) & TYPES is
non-zero. TYPE is the reported type of the capability and
- CAP_ADDR_TRANS the value of its address translation fields.
- WRITABLE is whether the slot is writable. If VISIT returns -1, the
- current sub-tree is exited. For other non-zero values, the walk is
- aborted and that value is returned. If the walk is not aborted, 0
- is returned. */
+ PROPERTIES the value of its properties. WRITABLE is whether the
+ slot is writable. If VISIT returns -1, the current sub-tree is
+ exited. For other non-zero values, the walk is aborted and that
+ value is returned. If the walk is not aborted, 0 is returned. */
int
as_walk (int (*visit) (addr_t addr,
- l4_word_t type, struct cap_addr_trans cap_addr_trans,
+ l4_word_t type, struct cap_properties properties,
bool writable,
void *cookie),
int types,
@@ -781,16 +792,16 @@ as_walk (int (*visit) (addr_t addr,
child[0] = 0;
error_t err;
- struct cap_addr_trans addr_trans;
+ struct cap_properties properties;
l4_word_t type;
/* Just caching the root capability cuts the number of RPCs by
about 25%. */
- struct cap_addr_trans root_addr_trans;
+ struct cap_properties root_properties;
l4_word_t root_type;
err = rm_cap_read (meta_data_activity,
- ADDR (0, 0), &root_type, &root_addr_trans);
+ ADDR (0, 0), &root_type, &root_properties);
assert (err == 0);
restart:
@@ -807,17 +818,18 @@ as_walk (int (*visit) (addr_t addr,
if (d == 0)
{
type = root_type;
- addr_trans = root_addr_trans;
+ properties = root_properties;
}
else
{
err = rm_cap_read (meta_data_activity,
- addr, &type, &addr_trans);
+ addr, &type, &properties);
assert (err == 0);
}
- addr = addr_extend (addr, CAP_ADDR_TRANS_GUARD (addr_trans),
- CAP_ADDR_TRANS_GUARD_BITS (addr_trans));
+ addr
+ = addr_extend (addr, CAP_ADDR_TRANS_GUARD (properties.addr_trans),
+ CAP_ADDR_TRANS_GUARD_BITS (properties.addr_trans));
switch (type)
{
@@ -825,7 +837,8 @@ as_walk (int (*visit) (addr_t addr,
writable = false;
/* Fall through. */
case cap_cappage:
- slots_log2 = CAP_ADDR_TRANS_SUBPAGE_SIZE_LOG2 (addr_trans);
+ slots_log2
+ = CAP_ADDR_TRANS_SUBPAGE_SIZE_LOG2 (properties.addr_trans);
break;
case cap_folio:
slots_log2 = FOLIO_OBJECTS_LOG2;
@@ -857,14 +870,14 @@ as_walk (int (*visit) (addr_t addr,
addr = addr_extend (addr, child[d], slots_log2);
err = rm_cap_read (meta_data_activity,
- addr, &type, &addr_trans);
+ addr, &type, &properties);
assert (err == 0);
}
for (;;)
{
err = rm_cap_read (meta_data_activity,
- addr, &type, &addr_trans);
+ addr, &type, &properties);
if (err)
/* Dangling pointer. */
{
@@ -888,7 +901,7 @@ as_walk (int (*visit) (addr_t addr,
if (((1 << type) & types))
{
- int r = visit (addr, type, addr_trans, writable, cookie);
+ int r = visit (addr, type, properties, writable, cookie);
if (r == -1)
{
/* Pop. */
@@ -907,21 +920,24 @@ as_walk (int (*visit) (addr_t addr,
return r;
}
- if (addr_depth (addr) + CAP_ADDR_TRANS_GUARD_BITS (addr_trans)
+ if (addr_depth (addr)
+ + CAP_ADDR_TRANS_GUARD_BITS (properties.addr_trans)
> ADDR_BITS)
{
child[depth - 1] ++;
goto restart;
}
- addr = addr_extend (addr, CAP_ADDR_TRANS_GUARD (addr_trans),
- CAP_ADDR_TRANS_GUARD_BITS (addr_trans));
+ addr
+ = addr_extend (addr, CAP_ADDR_TRANS_GUARD (properties.addr_trans),
+ CAP_ADDR_TRANS_GUARD_BITS (properties.addr_trans));
switch (type)
{
case cap_rcappage:
case cap_cappage:
- slots_log2 = CAP_ADDR_TRANS_SUBPAGE_SIZE_LOG2 (addr_trans);
+ slots_log2
+ = CAP_ADDR_TRANS_SUBPAGE_SIZE_LOG2 (properties.addr_trans);
break;
case cap_folio:
slots_log2 = FOLIO_OBJECTS_LOG2;
@@ -952,17 +968,17 @@ as_walk (int (*visit) (addr_t addr,
int do_walk (struct cap *cap, addr_t addr, bool writable)
{
l4_word_t type;
- struct cap_addr_trans cap_addr_trans;
+ struct cap_properties cap_properties;
type = cap->type;
- cap_addr_trans = cap->addr_trans;
+ cap_properties = CAP_PROPERTIES_GET (*cap);
debug (5, ADDR_FMT " (%s)", ADDR_PRINTF (addr), cap_type_string (type));
int r;
if (((1 << type) & types))
{
- r = visit (addr, type, cap_addr_trans, writable, cookie);
+ r = visit (addr, type, cap_properties, writable, cookie);
if (r == -1)
/* Don't go deeper. */
return 0;
@@ -970,12 +986,14 @@ as_walk (int (*visit) (addr_t addr,
return r;
}
- if (addr_depth (addr) + CAP_ADDR_TRANS_GUARD_BITS (cap_addr_trans)
+ if (addr_depth (addr)
+ + CAP_ADDR_TRANS_GUARD_BITS (cap_properties.addr_trans)
> ADDR_BITS)
return 0;
- addr = addr_extend (addr, CAP_ADDR_TRANS_GUARD (cap_addr_trans),
- CAP_ADDR_TRANS_GUARD_BITS (cap_addr_trans));
+ addr
+ = addr_extend (addr, CAP_ADDR_TRANS_GUARD (cap_properties.addr_trans),
+ CAP_ADDR_TRANS_GUARD_BITS (cap_properties.addr_trans));
int slots_log2 = 0;
switch (type)
@@ -985,7 +1003,8 @@ as_walk (int (*visit) (addr_t addr,
if (type == cap_rcappage)
writable = false;
- slots_log2 = CAP_ADDR_TRANS_SUBPAGE_SIZE_LOG2 (cap_addr_trans);
+ slots_log2
+ = CAP_ADDR_TRANS_SUBPAGE_SIZE_LOG2 (cap_properties.addr_trans);
break;
case cap_folio:
diff --git a/libhurd-mm/as.h b/libhurd-mm/as.h
index 591988e..ba5a816 100644
--- a/libhurd-mm/as.h
+++ b/libhurd-mm/as.h
@@ -128,14 +128,13 @@ extern struct cap object_lookup (activity_t activity,
/* Walk the address space (without using the shadow page tables),
depth first. VISIT is called for each slot for which (1 <<
reported capability type) & TYPES is non-zero. TYPE is the
- reported type of the capability and CAP_ADDR_TRANS the value of its
- address translation fields. WRITABLE is whether the slot is
- writable. If VISIT returns a non-zero value, the walk is aborted
- and that value is returned. If the walk is not aborted, 0 is
- returned. */
+ reported type of the capability and PROPERTIES the value of its
+ properties. WRITABLE is whether the slot is writable. If VISIT
+ returns a non-zero value, the walk is aborted and that value is
+ returned. If the walk is not aborted, 0 is returned. */
extern int as_walk (int (*visit) (addr_t cap,
l4_word_t type,
- struct cap_addr_trans cap_addr_trans,
+ struct cap_properties properties,
bool writable,
void *cookie),
int types,
diff --git a/libhurd-mm/storage.c b/libhurd-mm/storage.c
index 7ab79cc..96e46d1 100644
--- a/libhurd-mm/storage.c
+++ b/libhurd-mm/storage.c
@@ -269,6 +269,7 @@ shadow_setup (struct cap *cap, struct storage_desc *storage)
error_t err = rm_folio_object_alloc (meta_data_activity,
storage->folio, idx, cap_page,
+ OBJECT_POLICY_DEFAULT,
ADDR_VOID, ADDR_VOID);
assert (err == 0);
shadow = ADDR_TO_PTR (addr_extend (addr_extend (storage->folio,
@@ -311,7 +312,9 @@ shadow_setup (struct cap *cap, struct storage_desc *storage)
cap_set_shadow (cap, shadow);
shadow->caps[idx].type = cap_page;
- shadow->caps[idx].addr_trans = CAP_ADDR_TRANS_VOID;
+ CAP_PROPERTIES_SET (&shadow->caps[idx],
+ CAP_PROPERTIES (OBJECT_POLICY_DEFAULT,
+ CAP_ADDR_TRANS_VOID));
}
void
@@ -506,14 +509,17 @@ storage_alloc_ (addr_t activity,
if (likely (!! shadow))
{
cap = &shadow->caps[idx];
- cap->addr_trans = CAP_ADDR_TRANS_VOID;
+ CAP_PROPERTIES_SET (cap, CAP_PROPERTIES (OBJECT_POLICY_DEFAULT,
+ CAP_ADDR_TRANS_VOID));
cap->type = type;
}
else
assert (! as_init_done);
error_t err = rm_folio_object_alloc (meta_data_activity,
- folio, idx, type, addr, ADDR_VOID);
+ folio, idx, type,
+ OBJECT_POLICY_DEFAULT,
+ addr, ADDR_VOID);
assert (! err);
/* We drop DESC->LOCK. */
@@ -646,13 +652,16 @@ storage_free_ (addr_t object, bool unmap_now)
error_t err = rm_folio_object_alloc (meta_data_activity,
folio, idx, cap_void,
+ OBJECT_POLICY_DEFAULT,
ADDR_VOID, ADDR_VOID);
assert (err == 0);
if (likely (!! shadow))
{
shadow->caps[idx].type = cap_void;
- shadow->caps[idx].addr_trans = CAP_ADDR_TRANS_VOID;
+ CAP_PROPERTIES_SET (&shadow->caps[idx],
+ CAP_PROPERTIES (OBJECT_POLICY_DEFAULT,
+ CAP_ADDR_TRANS_VOID));
}
else
assert (! as_init_done);
diff --git a/ruth/ChangeLog b/ruth/ChangeLog
index 01e1e87..fbab39d 100644
--- a/ruth/ChangeLog
+++ b/ruth/ChangeLog
@@ -1,3 +1,9 @@
+2007-12-25 Neal H. Walfield <neal@gnu.org>
+
+ * ruth.c (main): Change visit to be consistent with as_walk's
+ expected function signature. Update rm_folio_object_alloc use to
+ reflect API changes.
+
2007-12-24 Neal H. Walfield <neal@gnu.org>
* ia32-cmain.c (exit): Declare.
diff --git a/ruth/ruth.c b/ruth/ruth.c
index d65e1c7..522b5aa 100644
--- a/ruth/ruth.c
+++ b/ruth/ruth.c
@@ -98,7 +98,7 @@ main (int argc, char *argv[])
int processing_folio = -1;
int visit (addr_t addr,
- l4_word_t type, struct cap_addr_trans cap_addr_trans,
+ l4_word_t type, struct cap_properties properties,
bool writable,
void *cookie)
{
@@ -149,14 +149,15 @@ main (int argc, char *argv[])
panic ("capalloc");
err = rm_folio_object_alloc (activity, folio, i, cap_page,
+ OBJECT_POLICY_DEFAULT,
addr, ADDR_VOID);
assert ((err == 0) == (0 <= i && i < FOLIO_OBJECTS));
if (0 <= i && i < FOLIO_OBJECTS)
{
l4_word_t type;
- struct cap_addr_trans cap_addr_trans;
- err = rm_cap_read (activity, addr, &type, &cap_addr_trans);
+ struct cap_properties properties;
+ err = rm_cap_read (activity, addr, &type, &properties);
assert (! err);
assert (type == cap_page);
}
@@ -203,10 +204,10 @@ main (int argc, char *argv[])
for (j = 0; j <= i; j ++)
{
l4_word_t type;
- struct cap_addr_trans addr_trans;
+ struct cap_properties properties;
error_t err = rm_cap_read (activity, addr_extend (root, j, bits),
- &type, &addr_trans);
+ &type, &properties);
assert (! err);
assert (type == cap_folio);
@@ -318,8 +319,8 @@ main (int argc, char *argv[])
struct hurd_thread_exregs_in in;
in.aspace = ADDR (0, 0);
- in.aspace_addr_trans = CAP_ADDR_TRANS_VOID;
- in.aspace_addr_trans_flags = CAP_COPY_COPY_SOURCE_GUARD;
+ in.aspace_cap_properties = CAP_PROPERTIES_DEFAULT;
+ in.aspace_cap_properties_flags = CAP_COPY_COPY_SOURCE_GUARD;
in.activity = activity;
@@ -393,7 +394,7 @@ main (int argc, char *argv[])
{
debug (5, "Creating thread %d", i);
error_t err = pthread_create (&threads[i], NULL, start,
- (uintptr_t) i);
+ (void *) (uintptr_t) i);
assert (err == 0);
}
@@ -403,7 +404,7 @@ main (int argc, char *argv[])
debug (5, "Waiting on thread %d", i);
error_t err = pthread_join (threads[i], &status);
assert (err == 0);
- assert (status == (uintptr_t) i);
+ assert ((uintptr_t) status == (uintptr_t) i);
debug (5, "Joined %d", i);
}
@@ -415,6 +416,7 @@ main (int argc, char *argv[])
{
printf ("Checking activity creation... ");
+#undef N
#define N 10
void test (addr_t activity, addr_t folio, int depth)
{
@@ -435,6 +437,7 @@ main (int argc, char *argv[])
a[i].child = capalloc ();
err = rm_folio_object_alloc (activity, folio, obj ++,
cap_activity_control,
+ OBJECT_POLICY_DEFAULT,
a[i].child, ADDR_VOID);
assert (err == 0);
@@ -445,13 +448,14 @@ main (int argc, char *argv[])
a[i].page = capalloc ();
err = rm_folio_object_alloc (a[i].child, a[i].folio, 0, cap_page,
+ OBJECT_POLICY_DEFAULT,
a[i].page, ADDR_VOID);
assert (err == 0);
l4_word_t type;
- struct cap_addr_trans addr_trans;
+ struct cap_properties properties;
- err = rm_cap_read (a[i].child, a[i].page, &type, &addr_trans);
+ err = rm_cap_read (a[i].child, a[i].page, &type, &properties);
assert (err == 0);
assert (type == cap_page);
}
@@ -475,6 +479,7 @@ main (int argc, char *argv[])
use the object. If this fails, we assume that the folio was
destroyed. */
err = rm_folio_object_alloc (a[i].child, a[i].folio, 1, cap_page,
+ OBJECT_POLICY_DEFAULT,
a[i].page, ADDR_VOID);
assert (err);
diff --git a/viengoos/ChangeLog b/viengoos/ChangeLog
index 8ec837d..c6229ae 100644
--- a/viengoos/ChangeLog
+++ b/viengoos/ChangeLog
@@ -1,3 +1,29 @@
+2007-12-25 Neal H. Walfield <neal@gnu.org>
+
+ * object.h (struct object_desc): Add field policy.
+ (object_desc_to_cap): Also return the discardable bit and the
+ priority.
+ (folio_object_alloc): Take additional parameter, the object's
+ policy. Update callers.
+ * object.c (folio_object_alloc): Take additional parameter, the
+ object policy. Save it in the folio header.
+ * as.c (as_build_internal): Update cap_copy_x use to reflect API
+ changes.
+ * thread.h: Remove parameter addr_trans and replace with a
+ parameter that includes it and the object policy. Update users.
+ * thread.c (thread_exregs): Remove parameter addr_trans and
+ replace with a parameter that includes it and the object policy.
+ Pass it to cap_copy_x as appropriate.
+ * server.c: Include "output.h".
+ (server_loop): Update the folio_object_alloc,
+ object_slot_copy_out, object_slot_copy_in, and cap_copy
+ implementations to set the allocated object's policy consistent
+ with the API changes. Update the object_slot_read and cap_read
+ implementations to return the object policy consistent with the
+ API changes. Update the thread_exregs implementation to handle
+ the address space capability's object policy consistent with the
+ API changes.
+
2007-12-24 Neal H. Walfield <neal@gnu.org>
* as.c (as_build_internal): Include "output.h".
diff --git a/viengoos/as.c b/viengoos/as.c
index 047c548..2f4572f 100644
--- a/viengoos/as.c
+++ b/viengoos/as.c
@@ -365,7 +365,9 @@ as_build_internal (activity_t activity,
bool r = cap_copy_x (activity,
&cappage->caps[pivot_idx], pivot_addr,
*root, root_addr,
- CAP_COPY_COPY_ADDR_TRANS_GUARD, addr_trans);
+ CAP_COPY_COPY_ADDR_TRANS_GUARD,
+ CAP_PROPERTIES (OBJECT_POLICY_DEFAULT,
+ addr_trans));
assert (r);
/* Finally, set the slot at ROOT to point to CAPPAGE. */
@@ -383,7 +385,8 @@ as_build_internal (activity_t activity,
r = cap_copy_x (activity, root, root_addr, rt.cap, rt.storage,
CAP_COPY_COPY_ADDR_TRANS_SUBPAGE
| CAP_COPY_COPY_ADDR_TRANS_GUARD,
- addr_trans);
+ CAP_PROPERTIES (OBJECT_POLICY_DEFAULT, addr_trans));
+
assert (r);
}
@@ -419,7 +422,8 @@ as_build_internal (activity_t activity,
assert (r);
r = cap_copy_x (activity, root, addr_chop (a, gbits),
*root, addr_chop (a, gbits),
- CAP_COPY_COPY_ADDR_TRANS_GUARD, addr_trans);
+ CAP_COPY_COPY_ADDR_TRANS_GUARD,
+ CAP_PROPERTIES (OBJECT_POLICY_DEFAULT, addr_trans));
assert (r);
}
diff --git a/viengoos/object.c b/viengoos/object.c
index 95f78b5..ba11055 100644
--- a/viengoos/object.c
+++ b/viengoos/object.c
@@ -462,6 +462,7 @@ folio_object_alloc (struct activity *activity,
struct folio *folio,
int idx,
enum cap_type type,
+ struct object_policy policy,
struct object **objectp)
{
debug (4, "allocating %s at %d", cap_type_string (type), idx);
@@ -552,6 +553,8 @@ folio_object_alloc (struct activity *activity,
/* Mark it as being empty. */
folio->objects[idx].content = 0;
+ folio->objects[idx].policy = policy;
+
switch (type)
{
case cap_activity_control:
diff --git a/viengoos/object.h b/viengoos/object.h
index ed3a7ea..8ea385e 100644
--- a/viengoos/object.h
+++ b/viengoos/object.h
@@ -127,6 +127,8 @@ struct object_desc
l4_word_t dirty: 1;
+ struct object_policy policy;
+
/* The object's age. */
unsigned short age;
@@ -222,6 +224,8 @@ object_desc_to_cap (struct object_desc *desc)
cap.oid = desc->oid;
cap.version = desc->version;
cap.addr_trans = CAP_ADDR_TRANS_VOID;
+ cap.discardable = desc->policy.discardable;
+ cap.priority = desc->policy.priority;
return cap;
}
@@ -408,6 +412,7 @@ extern void folio_free (struct activity *activity, struct folio *folio);
extern void folio_object_alloc (struct activity *activity,
struct folio *folio, int page,
enum cap_type type,
+ struct object_policy policy,
struct object **objectp);
/* Deallocate the object stored in page PAGE of folio FOLIO. */
@@ -415,7 +420,8 @@ static inline void
folio_object_free (struct activity *activity,
struct folio *folio, int page)
{
- folio_object_alloc (activity, folio, page, cap_void, NULL);
+ folio_object_alloc (activity, folio, page, cap_void,
+ OBJECT_POLICY_VOID, NULL);
}
/* Deallocate the object OBJECT. */
diff --git a/viengoos/server.c b/viengoos/server.c
index b0f341c..d76027e 100644
--- a/viengoos/server.c
+++ b/viengoos/server.c
@@ -30,6 +30,7 @@
#include "rm.h"
+#include "output.h"
#include "cap.h"
#include "object.h"
#include "thread.h"
@@ -358,7 +359,7 @@ server_loop (void)
addr_t target_addr;
struct cap *target;
l4_word_t flags;
- struct cap_addr_trans addr_trans;
+ struct cap_properties properties;
DEBUG (5, "");
@@ -400,56 +401,63 @@ server_loop (void)
break;
case RM_folio_object_alloc:
- err = rm_folio_object_alloc_send_unmarshal (&msg, &principal_addr,
- &folio_addr, &idx,
- &type, &object_addr,
- &object_weak_addr);
- if (err)
- REPLY (err);
+ {
+ struct object_policy policy;
+
+ err = rm_folio_object_alloc_send_unmarshal (&msg, &principal_addr,
+ &folio_addr, &idx,
+ &type,
+ &policy,
+ &object_addr,
+ &object_weak_addr);
+ if (err)
+ REPLY (err);
- folio = (struct folio *) OBJECT (folio_addr, cap_folio, true);
+ folio = (struct folio *) OBJECT (folio_addr, cap_folio, true);
- if (idx >= FOLIO_OBJECTS)
- REPLY (EINVAL);
+ if (idx >= FOLIO_OBJECTS)
+ REPLY (EINVAL);
- if (! (CAP_TYPE_MIN <= type && type <= CAP_TYPE_MAX))
- REPLY (EINVAL);
+ if (! (CAP_TYPE_MIN <= type && type <= CAP_TYPE_MAX))
+ REPLY (EINVAL);
- object_slot = NULL;
- if (! ADDR_IS_VOID (object_addr))
- object_slot = SLOT (object_addr);
+ object_slot = NULL;
+ if (! ADDR_IS_VOID (object_addr))
+ object_slot = SLOT (object_addr);
- object_weak_slot = NULL;
- if (! ADDR_IS_VOID (object_weak_addr))
- object_weak_slot = SLOT (object_weak_addr);
+ object_weak_slot = NULL;
+ if (! ADDR_IS_VOID (object_weak_addr))
+ object_weak_slot = SLOT (object_weak_addr);
- DEBUG (4, "(folio: %llx/%d, idx: %d, type: %s, target: %llx/%d)",
- addr_prefix (folio_addr), addr_depth (folio_addr),
- idx, cap_type_string (type),
- addr_prefix (object_addr), addr_depth (object_addr));
+ DEBUG (4, "(folio: %llx/%d, idx: %d, type: %s, target: %llx/%d)",
+ addr_prefix (folio_addr), addr_depth (folio_addr),
+ idx, cap_type_string (type),
+ addr_prefix (object_addr), addr_depth (object_addr));
- folio_object_alloc (principal, folio, idx, type,
- type == cap_void ? NULL : &object);
+ folio_object_alloc (principal, folio, idx, type, policy,
+ type == cap_void ? NULL : &object);
- if (type != cap_void)
- {
- if (object_slot)
- {
- r = cap_set (principal, object_slot, object_to_cap (object));
- assert (r);
- }
- if (object_weak_slot)
- {
- r = cap_set (principal, object_weak_slot,
- object_to_cap (object));
- assert (r);
- object_weak_slot->type
- = cap_type_weaken (object_weak_slot->type);
- }
- }
+ if (type != cap_void)
+ {
+ if (object_slot)
+ {
+ r = cap_set (principal,
+ object_slot, object_to_cap (object));
+ assert (r);
+ }
+ if (object_weak_slot)
+ {
+ r = cap_set (principal, object_weak_slot,
+ object_to_cap (object));
+ assert (r);
+ object_weak_slot->type
+ = cap_type_weaken (object_weak_slot->type);
+ }
+ }
- rm_folio_object_alloc_reply_marshal (&msg);
- break;
+ rm_folio_object_alloc_reply_marshal (&msg);
+ break;
+ }
case RM_folio_policy:
{
@@ -473,7 +481,7 @@ server_loop (void)
case RM_object_slot_copy_out:
err = rm_object_slot_copy_out_send_unmarshal
(&msg, &principal_addr,
- &source_addr, &idx, &target_addr, &flags, &addr_trans);
+ &source_addr, &idx, &target_addr, &flags, &properties);
if (err)
REPLY (err);
@@ -486,7 +494,7 @@ server_loop (void)
{
err = rm_object_slot_copy_in_send_unmarshal
(&msg, &principal_addr,
- &target_addr, &idx, &source_addr, &flags, &addr_trans);
+ &target_addr, &idx, &source_addr, &flags, &properties);
if (err)
REPLY (err);
@@ -532,7 +540,7 @@ server_loop (void)
case RM_cap_copy:
err = rm_cap_copy_send_unmarshal (&msg, &principal_addr,
&target_addr, &source_addr,
- &flags, &addr_trans);
+ &flags, &properties);
if (err)
REPLY (err);
@@ -544,7 +552,9 @@ server_loop (void)
if ((flags & ~(CAP_COPY_COPY_ADDR_TRANS_SUBPAGE
| CAP_COPY_COPY_ADDR_TRANS_GUARD
| CAP_COPY_COPY_SOURCE_GUARD
- | CAP_COPY_WEAKEN)))
+ | CAP_COPY_WEAKEN
+ | CAP_COPY_DISCARDABLE_SET
+ | CAP_COPY_PRIORITY_SET)))
REPLY (EINVAL);
DEBUG (4, "(target: %llx/%d, source: %llx/%d, "
@@ -557,15 +567,14 @@ server_loop (void)
flags & CAP_COPY_COPY_ADDR_TRANS_SUBPAGE ? "copy"
: "preserve",
flags & CAP_COPY_WEAKEN ? "weaken" : "no weaken",
- CAP_ADDR_TRANS_GUARD (addr_trans),
- CAP_ADDR_TRANS_GUARD_BITS (addr_trans),
- CAP_ADDR_TRANS_SUBPAGE (addr_trans),
- CAP_ADDR_TRANS_SUBPAGES (addr_trans));
+ CAP_ADDR_TRANS_GUARD (properties.addr_trans),
+ CAP_ADDR_TRANS_GUARD_BITS (properties.addr_trans),
+ CAP_ADDR_TRANS_SUBPAGE (properties.addr_trans),
+ CAP_ADDR_TRANS_SUBPAGES (properties.addr_trans));
bool r = cap_copy_x (principal,
- target, ADDR_VOID,
- source, ADDR_VOID,
- flags, addr_trans);
+ target, ADDR_VOID, source, ADDR_VOID,
+ flags, properties);
if (! r)
REPLY (EINVAL);
@@ -613,7 +622,7 @@ server_loop (void)
source = ((struct cap *) object)[idx];
rm_object_slot_read_reply_marshal (&msg, source.type,
- source.addr_trans);
+ CAP_PROPERTIES_GET (source));
break;
@@ -623,7 +632,8 @@ server_loop (void)
source = CAP (source_addr, -1, false);
- rm_cap_read_reply_marshal (&msg, source.type, source.addr_trans);
+ rm_cap_read_reply_marshal (&msg, source.type,
+ CAP_PROPERTIES_GET (source));
break;
case RM_thread_exregs:
@@ -691,8 +701,8 @@ server_loop (void)
out.user_handle = in.user_handle;
err = thread_exregs (principal, t, control,
- aspace, in.aspace_addr_trans_flags,
- in.aspace_addr_trans, a, exception_page,
+ aspace, in.aspace_cap_properties_flags,
+ in.aspace_cap_properties, a, exception_page,
&out.sp, &out.ip,
&out.eflags, &out.user_handle,
aspace_out, activity_out,
diff --git a/viengoos/t-activity.c b/viengoos/t-activity.c
index ac30023..4382606 100644
--- a/viengoos/t-activity.c
+++ b/viengoos/t-activity.c
@@ -26,7 +26,8 @@ allocate_object (enum cap_type type, addr_t addr)
}
struct object *o;
- folio_object_alloc (root_activity, folio, object ++, type, &o);
+ folio_object_alloc (root_activity, folio, object ++,
+ type, OBJECT_POLICY_DEFAULT, &o);
struct as_insert_rt rt;
rt.cap = object_to_cap (o);
@@ -80,14 +81,16 @@ test (void)
/* Allocate a new activity. */
folio_object_alloc (activity, folio, obj ++,
- cap_activity_control, &object);
+ cap_activity_control, OBJECT_POLICY_DEFAULT,
+ &object);
a[i].child = (struct activity *) object;
/* Allocate a folio against the activity and use it. */
a[i].folio = folio_alloc (a[i].child, FOLIO_POLICY_DEFAULT);
assert (a[i].folio);
- folio_object_alloc (a[i].child, a[i].folio, 0, cap_page, &a[i].page);
+ folio_object_alloc (a[i].child, a[i].folio, 0,
+ cap_page, OBJECT_POLICY_DEFAULT, &a[i].page);
assert (object_type (a[i].page) == cap_page);
}
diff --git a/viengoos/t-as.c b/viengoos/t-as.c
index 4797b20..9425c4d 100644
--- a/viengoos/t-as.c
+++ b/viengoos/t-as.c
@@ -26,7 +26,8 @@ allocate_object (enum cap_type type, addr_t addr)
}
struct object *o;
- folio_object_alloc (root_activity, folio, object ++, type, &o);
+ folio_object_alloc (root_activity, folio, object ++,
+ type, OBJECT_POLICY_DEFAULT, &o);
struct as_insert_rt rt;
rt.cap = object_to_cap (o);
diff --git a/viengoos/thread.c b/viengoos/thread.c
index 73768df..6e5c168 100644
--- a/viengoos/thread.c
+++ b/viengoos/thread.c
@@ -237,7 +237,7 @@ error_t
thread_exregs (struct activity *principal,
struct thread *thread, l4_word_t control,
struct cap *aspace,
- l4_word_t flags, struct cap_addr_trans addr_trans,
+ l4_word_t flags, struct cap_properties properties,
struct cap *activity,
struct cap *exception_page,
l4_word_t *sp, l4_word_t *ip,
@@ -260,7 +260,7 @@ thread_exregs (struct activity *principal,
if ((control & HURD_EXREGS_SET_ASPACE))
cap_copy_x (principal, &thread->aspace, ADDR_VOID, *aspace, ADDR_VOID,
- flags, addr_trans);
+ flags, properties);
if ((control & HURD_EXREGS_GET_REGS) && activity_out)
cap_copy (principal, activity_out, ADDR_VOID, thread->activity, ADDR_VOID);
diff --git a/viengoos/thread.h b/viengoos/thread.h
index db0b5ca..f99a0cc 100644
--- a/viengoos/thread.h
+++ b/viengoos/thread.h
@@ -92,7 +92,7 @@ extern void thread_decommission (struct thread *thread);
extern error_t thread_exregs (struct activity *principal,
struct thread *thread, l4_word_t control,
struct cap *aspace,
- l4_word_t flags, struct cap_addr_trans addr_trans,
+ l4_word_t flags, struct cap_properties properties,
struct cap *activity,
struct cap *exception_page,
l4_word_t *sp, l4_word_t *ip,
diff --git a/viengoos/viengoos.c b/viengoos/viengoos.c
index b4ddf57..7c50336 100644
--- a/viengoos/viengoos.c
+++ b/viengoos/viengoos.c
@@ -253,7 +253,8 @@ system_task_load (void)
struct object *object;
int index = folio_index ++;
- folio_object_alloc (root_activity, folio, index, type, &object);
+ folio_object_alloc (root_activity, folio, index, type,
+ OBJECT_POLICY_VOID, &object);
if (! (desc_count < desc_max))
panic ("Initial task too large.");
@@ -371,7 +372,7 @@ system_task_load (void)
err = thread_exregs (root_activity, thread,
HURD_EXREGS_SET_SP_IP
| HURD_EXREGS_START | HURD_EXREGS_ABORT_IPC,
- NULL, 0, (struct cap_addr_trans) CAP_ADDR_TRANS_VOID,
+ NULL, 0, CAP_PROPERTIES_VOID,
NULL, NULL, &thread->sp, &thread->ip, NULL, NULL,
NULL, NULL, NULL);
if (err)