Changeset 26a6ed4 in mainline


Ignore:
Timestamp:
2018-03-11T07:35:05Z (6 years ago)
Author:
Jakub Jermar <jakub@…>
Children:
bbf38ad
Parents:
813fc8c
git-author:
Jakub Jermar <jakub@…> (2018-03-10 18:18:12)
git-committer:
Jakub Jermar <jakub@…> (2018-03-11 07:35:05)
Message:

Allow phone_alloc to not publish the capability

This makes it possible and race-free to defer publishing the new
capability until the phone object is connected.

Location:
kernel/generic
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/include/ipc/ipcrsc.h

    r813fc8c r26a6ed4  
    4040#include <cap/cap.h>
    4141
    42 extern errno_t phone_alloc(task_t *, cap_handle_t *);
     42extern errno_t phone_alloc(task_t *, bool, cap_handle_t *, kobject_t **);
    4343extern bool phone_connect(cap_handle_t, answerbox_t *);
    4444extern void phone_dealloc(cap_handle_t);
  • kernel/generic/src/ipc/ipcrsc.c

    r813fc8c r26a6ed4  
    150150/** Allocate new phone in the specified task.
    151151 *
    152  * @param task  Task for which to allocate a new phone.
    153  *
    154  * @param[out] out_handle  New phone capability handle.
     152 * @param[in]  task     Task for which to allocate a new phone.
     153 * @param[in]  publish  If true, the new capability will be published.
     154 * @param[out] phandle  New phone capability handle.
     155 * @param[out] kobject  New phone kobject.
    155156 *
    156157 * @return  An error code if a new capability cannot be allocated.
    157158 */
    158 errno_t phone_alloc(task_t *task, cap_handle_t *out_handle)
     159errno_t phone_alloc(task_t *task, bool publish, cap_handle_t *phandle,
     160    kobject_t **kobject)
    159161{
    160162        cap_handle_t handle;
     
    166168                        return ENOMEM;
    167169                }
    168                 kobject_t *kobject = malloc(sizeof(kobject_t), FRAME_ATOMIC);
    169                 if (!kobject) {
     170                kobject_t *kobj = malloc(sizeof(kobject_t), FRAME_ATOMIC);
     171                if (!kobj) {
    170172                        cap_free(TASK, handle);
    171173                        slab_free(phone_cache, phone);
     
    176178                phone->state = IPC_PHONE_CONNECTING;
    177179
    178                 kobject_initialize(kobject, KOBJECT_TYPE_PHONE, phone,
     180                kobject_initialize(kobj, KOBJECT_TYPE_PHONE, phone,
    179181                    &phone_kobject_ops);
    180                 phone->kobject = kobject;
    181 
    182                 cap_publish(task, handle, kobject);
    183 
    184                 *out_handle = handle;
     182                phone->kobject = kobj;
     183
     184                if (publish)
     185                        cap_publish(task, handle, kobj);
     186
     187                *phandle = handle;
     188                if (kobject)
     189                        *kobject = kobj;
    185190        }
    186191        return rc;
  • kernel/generic/src/ipc/kbox.c

    r813fc8c r26a6ed4  
    253253        /* Allocate a new phone. */
    254254        cap_handle_t phone_handle;
    255         errno_t rc = phone_alloc(TASK, &phone_handle);
     255        errno_t rc = phone_alloc(TASK, true, &phone_handle, NULL);
    256256        if (rc != EOK) {
    257257                mutex_unlock(&task->kb.cleanup_lock);
  • kernel/generic/src/ipc/ops/conctmeto.c

    r813fc8c r26a6ed4  
    4242static errno_t request_preprocess(call_t *call, phone_t *phone)
    4343{
     44        /*
     45         * Create the new phone and capability, but don't publish them yet.
     46         * That will be done once the phone is connected.
     47         */
    4448        cap_handle_t phone_handle;
    45         errno_t rc = phone_alloc(TASK, &phone_handle);
     49        kobject_t *phone_obj;
     50        errno_t rc = phone_alloc(TASK, false, &phone_handle, &phone_obj);
    4651        if (rc != EOK) {
    4752                call->priv = -1;
    4853                return rc;
    49         }
    50 
    51         /*
    52          * The capability is now published, but the phone is not connected yet.
    53          * The user cannot use it to send anything over it, in fact the
    54          * userspace can only unpublish and free the capability at this point.
    55          *
    56          * We now proceed to test the capability is still there. We don't care
    57          * if the user destroyed the old one and recreated a new published one
    58          * of the same type under the same handle.
    59          *
    60          * If the capability is in place we temporarily unpublish it to make
    61          * sure the user cannot fiddle with it while we are connecting.
    62          */
    63 
    64         kobject_t *phone_obj = cap_unpublish(TASK, phone_handle,
    65             KOBJECT_TYPE_PHONE);
    66         if (!phone_obj) {
    67                 /*
    68                  * Another thread of the same task can destroy the new
    69                  * capability before we manage to get a reference from it.
    70                  */
    71                 call->priv = -1;
    72                 return ENOENT;
    7354        }
    7455
  • kernel/generic/src/ipc/ops/concttome.c

    r813fc8c r26a6ed4  
    4343{
    4444        cap_handle_t phone_handle;
    45         errno_t rc = phone_alloc(TASK, &phone_handle);
     45        errno_t rc = phone_alloc(TASK, true, &phone_handle, NULL);
    4646        IPC_SET_ARG5(call->data, (rc == EOK) ? phone_handle : -1);
    4747        return 0;
  • kernel/generic/src/proc/task.c

    r813fc8c r26a6ed4  
    246246            (container_check(ipc_box_0->task->container, task->container))) {
    247247                cap_handle_t phone_handle;
    248                 errno_t rc = phone_alloc(task, &phone_handle);
     248                errno_t rc = phone_alloc(task, true, &phone_handle, NULL);
    249249                if (rc != EOK) {
    250250                        task->as = NULL;
Note: See TracChangeset for help on using the changeset viewer.