lib: trusty: Add `HSET_DEL_GET_COOKIE` Adds a handle set operation that deletes the matching member handle, and returns its cookie. Test: aosp/3506455 Bug: 382291660 Change-Id: If0da8d830768218b9264cf2491c3b68ab0932ae0
diff --git a/lib/trusty/include/lib/trusty/handle_set.h b/lib/trusty/include/lib/trusty/handle_set.h index c192170..9836a9b 100644 --- a/lib/trusty/include/lib/trusty/handle_set.h +++ b/lib/trusty/include/lib/trusty/handle_set.h
@@ -29,6 +29,7 @@ #define HSET_ADD 0 #define HSET_DEL 1 #define HSET_MOD 2 +#define HSET_DEL_GET_COOKIE 3 __BEGIN_CDECLS
diff --git a/lib/trusty/uctx.c b/lib/trusty/uctx.c index d9c6716..b3a775f 100644 --- a/lib/trusty/uctx.c +++ b/lib/trusty/uctx.c
@@ -711,7 +711,9 @@ item->ref_list.prev); } -static int _hset_del_item(struct handle* hset, struct htbl_entry* item) { +static int _hset_del_item(struct handle* hset, + struct htbl_entry* item, + struct uevent* uevent) { uint del_cnt = 0; struct handle_ref* ref; struct handle_ref* tmp; @@ -721,6 +723,9 @@ if (ref->parent == hset) { del_cnt++; LTRACEF("%p: %p\n", ref->parent, ref->handle); + if (uevent) { + uevent->cookie = (user_addr_t)(uintptr_t)ref->cookie; + } list_delete(&ref->uctx_node); handle_set_detach_ref(ref); handle_decref(ref->handle); @@ -750,37 +755,42 @@ } static int _hset_ctrl_locked(handle_id_t hset_id, - handle_id_t h_id, uint32_t cmd, - uint32_t event, - void* cookie) { + struct uevent* uevent) { int ret; int h_idx, hset_idx; struct uctx* ctx = current_uctx(); - LTRACEF("%d: %d: cmd=%d\n", hset_id, h_id, cmd); + LTRACEF("%d: %d: cmd=%d\n", hset_id, uevent->handle, cmd); hset_idx = _check_handle_id(ctx, hset_id); if (hset_idx < 0) return hset_idx; - h_idx = _check_handle_id(ctx, h_id); + h_idx = _check_handle_id(ctx, uevent->handle); if (h_idx < 0) return h_idx; switch (cmd) { case HSET_ADD: ret = _hset_add_item(ctx->htbl[hset_idx].handle, &ctx->htbl[h_idx], - h_id, event, cookie); + uevent->handle, uevent->event, + (void*)(uintptr_t)uevent->cookie); break; case HSET_DEL: - ret = _hset_del_item(ctx->htbl[hset_idx].handle, &ctx->htbl[h_idx]); + ret = _hset_del_item(ctx->htbl[hset_idx].handle, &ctx->htbl[h_idx], + NULL); + break; + + case HSET_DEL_GET_COOKIE: + ret = _hset_del_item(ctx->htbl[hset_idx].handle, &ctx->htbl[h_idx], + uevent); break; case HSET_MOD: ret = _hset_mod_item(ctx->htbl[hset_idx].handle, &ctx->htbl[h_idx], - event, cookie); + uevent->event, (void*)(uintptr_t)uevent->cookie); break; default: @@ -803,9 +813,12 @@ return ret; mutex_acquire(&ctx->mlock); - ret = _hset_ctrl_locked(hset_id, uevent.handle, cmd, uevent.event, - (void*)(uintptr_t)uevent.cookie); + ret = _hset_ctrl_locked(hset_id, cmd, &uevent); mutex_release(&ctx->mlock); + if (ret < 0) + return ret; + if (cmd == HSET_DEL_GET_COOKIE) + ret = copy_to_user(user_event, &uevent, sizeof(uevent)); return ret; }