Changeset 6636fb19 in mainline
- Timestamp:
- 2017-09-29T22:56:31Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 91b60499
- Parents:
- 48bcf49
- Location:
- kernel/generic
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/include/cap/cap.h
r48bcf49 r6636fb19 67 67 } kobject_ops_t; 68 68 69 /* 70 * Everything in kobject_t except for the atomic reference count is imutable. 71 */ 69 72 typedef struct kobject { 70 73 kobject_type_t type; … … 80 83 } kobject_t; 81 84 85 /* 86 * A cap_t may only be accessed under the protection of the cap_info_t lock. 87 */ 82 88 typedef struct cap { 83 89 cap_state_t state; … … 115 121 kobject_ops_t *); 116 122 extern kobject_t *kobject_get(struct task *, cap_handle_t, kobject_type_t); 123 extern void kobject_add_ref(kobject_t *); 117 124 extern void kobject_put(kobject_t *); 118 125 -
kernel/generic/src/cap/cap.c
r48bcf49 r6636fb19 33 33 */ 34 34 35 /* 36 * HelenOS capabilities are task-local names for references to kernel objects. 37 * Kernel objects are reference-counted wrappers for a select group of objects 38 * allocated in and by the kernel that can be made accessible to userspace in a 39 * controlled way via integer handles. 40 * 41 * A kernel object (kobject_t) encapsulates one of the following raw objects: 42 * 43 * - IPC phone 44 * - IRQ object 45 * 46 * A capability (cap_t) is either free, allocated or published. Free 47 * capabilities can be allocated, which reserves the capability handle in the 48 * task-local capability space. Allocated capabilities can be published, which 49 * associates them with an existing kernel object. Userspace can only access 50 * published capabilities. 51 * 52 * A published capability may get unpublished, which disassociates it from the 53 * underlying kernel object and puts it back into the allocated state. An 54 * allocated capability can be freed to become available for future use. 55 * 56 * There is a 1:1 correspondence between a kernel object (kobject_t) and the 57 * actual raw object it encapsulates. A kernel object (kobject_t) may have 58 * multiple references, either implicit from one or more capabilities (cap_t), 59 * even from capabilities in different tasks, or explicit as a result of 60 * creating a new reference from a capability handle using kobject_get(), or 61 * creating a new reference from an already existing reference by 62 * kobject_add_ref() or as a result of unpublishing a capability and 63 * disassociating it from its kobject_t using cap_unpublish(). 64 * 65 * As kernel objects are reference-counted, they get automatically destroyed 66 * when their last reference is dropped in kobject_put(). The idea is that 67 * whenever a kernel object is inserted into some sort of a container (e.g. a 68 * list or hash table), its reference count should be incremented via 69 * kobject_get() or kobject_add_ref(). When the kernel object is removed from 70 * the container, the reference count should go down via a call to 71 * kobject_put(). 72 */ 73 35 74 #include <cap/cap.h> 36 75 #include <proc/task.h> … … 42 81 static kobject_t *cap_unpublish_locked(task_t *, cap_handle_t, kobject_type_t); 43 82 83 /** Initialize capability and associate it with its handle 84 * 85 * @param cap Address of the capability. 86 * @param handle Capability handle. 87 */ 44 88 void cap_initialize(cap_t *cap, cap_handle_t handle) 45 89 { … … 49 93 } 50 94 95 /** Allocate the capability info structure 96 * 97 * @param task Task for which to allocate the info structure. 98 */ 51 99 void caps_task_alloc(task_t *task) 52 100 { … … 55 103 } 56 104 105 /** Initialize the capability info structure 106 * 107 * @param task Task for which to initialize the info structure. 108 */ 57 109 void caps_task_init(task_t *task) 58 110 { … … 66 118 } 67 119 120 /** Deallocate the capability info structure 121 * 122 * @param task Task from which to deallocate the info structure. 123 */ 68 124 void caps_task_free(task_t *task) 69 125 { … … 72 128 } 73 129 130 /** Invoke callback function on task's capabilites of given type 131 * 132 * @param task Task where the invocation should take place. 133 * @param type Kernel object type of the task's capabilities that will be 134 * subject to the callback invocation. 135 * @param cb Callback function. 136 * @param arg Argument for the callback function. 137 * 138 * @return True if the callback was called on all matching capabilities. 139 * @return False if the callback was applied only partially. 140 */ 74 141 bool caps_apply_to_kobject_type(task_t *task, kobject_type_t type, 75 142 bool (*cb)(cap_t *, void *), void *arg) … … 89 156 } 90 157 158 /** Get capability using capability handle 159 * 160 * @param task Task whose capability to get. 161 * @param handle Capability handle of the desired capability. 162 * @param state State in which the capability must be. 163 * 164 * @return Address of the desired capability if it exists and its state matches. 165 * @return NULL if no such capability exists or it's in a different state. 166 */ 91 167 static cap_t *cap_get(task_t *task, cap_handle_t handle, cap_state_t state) 92 168 { … … 100 176 } 101 177 178 /** Allocate new capability 179 * 180 * @param task Task for which to allocate the new capability. 181 * 182 * @return New capability handle on success. 183 * @return Negative error code in case of error. 184 */ 102 185 cap_handle_t cap_alloc(task_t *task) 103 186 { … … 125 208 } 126 209 210 /** Publish allocated capability 211 * 212 * The kernel object is moved into the capability. In other words, its reference 213 * is handed over to the capability. Once published, userspace can access and 214 * manipulate the capability. 215 * 216 * @param task Task in which to publish the capability. 217 * @param handle Capability handle. 218 * @param kobj Kernel object. 219 */ 127 220 void 128 221 cap_publish(task_t *task, cap_handle_t handle, kobject_t *kobj) … … 156 249 return kobj; 157 250 } 251 252 /** Unpublish published capability 253 * 254 * The kernel object is moved out of the capability. In other words, the 255 * capability's reference to the objects is handed over to the kernel object 256 * pointer returned by this function. Once unpublished, the capability does not 257 * refer to any kernel object anymore. 258 * 259 * @param task Task in which to unpublish the capability. 260 * @param handle Capability handle. 261 * @param type Kernel object type of the object associated with the 262 * capability. 263 */ 158 264 kobject_t *cap_unpublish(task_t *task, cap_handle_t handle, kobject_type_t type) 159 265 { … … 166 272 } 167 273 274 /** Free allocated capability 275 * 276 * @param task Task in which to free the capability. 277 * @param handle Capability handle. 278 */ 168 279 void cap_free(task_t *task, cap_handle_t handle) 169 280 { … … 177 288 } 178 289 290 /** Initialize kernel object 291 * 292 * @param kobj Kernel object to initialize. 293 * @param type Type of the kernel object. 294 * @param raw Raw pointer to the encapsulated object. 295 * @param ops Pointer to kernel object operations for the respective type. 296 */ 179 297 void kobject_initialize(kobject_t *kobj, kobject_type_t type, void *raw, 180 298 kobject_ops_t *ops) … … 186 304 } 187 305 306 /** Get new reference to kernel object from capability 307 * 308 * @param task Task from which to get the reference. 309 * @param handle Capability handle. 310 * @param type Kernel object type of the object associated with the 311 * capability referenced by handle. 312 * 313 * @return Kernel object with incremented reference count on success. 314 * @return NULL if there is no matching capability or kernel object. 315 */ 188 316 kobject_t * 189 317 kobject_get(struct task *task, cap_handle_t handle, kobject_type_t type) … … 204 332 } 205 333 334 /** Record new reference 335 * 336 * @param kobj Kernel object from which the new reference is created. 337 */ 338 void kobject_add_ref(kobject_t *kobj) 339 { 340 atomic_inc(&kobj->refcnt); 341 } 342 343 /** Drop reference to kernel object 344 * 345 * The encapsulated object and the kobject_t wrapper are both destroyed when the 346 * last reference is dropped. 347 * 348 * @param kobj Kernel object whose reference to drop. 349 */ 206 350 void kobject_put(kobject_t *kobj) 207 351 {
Note:
See TracChangeset
for help on using the changeset viewer.