# HG changeset patch # User Paul Boddie # Date 1678386442 -3600 # Node ID c47fb183300dcf0f789c0bb94c12f4f8a18196e7 # Parent ec186bf44106023806842ee75c3c5db629c9717b Attempt to handle local capabilities in messages sent within tasks. diff -r ec186bf44106 -r c47fb183300d libipc/include/ipc/util_ipc.h --- a/libipc/include/ipc/util_ipc.h Tue Mar 07 19:10:40 2023 +0100 +++ b/libipc/include/ipc/util_ipc.h Thu Mar 09 19:27:22 2023 +0100 @@ -1,7 +1,7 @@ /* * Interprocess communication abstractions. * - * Copyright (C) 2018, 2019, 2021, 2022 Paul Boddie + * Copyright (C) 2018, 2019, 2021, 2022, 2023 Paul Boddie * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -41,8 +41,8 @@ void _export_fpage(l4_msgtag_t tag, l4_msg_regs_t *mregs, int item, l4_snd_fpage_t fpage); void _export_page(l4_msgtag_t tag, l4_msg_regs_t *mregs, int item, l4_umword_t hot_spot, l4_fpage_t fpage); void _free_expected_capabilities(l4_buf_regs_t *bregs, int number); -long _import_capability(l4_msgtag_t tag, l4_buf_regs_t *bregs, l4_msg_regs_t *mregs, int item, l4_cap_idx_t *ref); -long _import_dataspace(l4_msgtag_t tag, l4_buf_regs_t *bregs, l4_msg_regs_t *mregs, int item, l4re_ds_t *mem, l4_addr_t *addr); +long _import_capability(l4_msgtag_t tag, l4_buf_regs_t *bregs, l4_msg_regs_t *mregs, int item, l4_cap_idx_t *ref, int *local); +long _import_dataspace(l4_msgtag_t tag, l4_buf_regs_t *bregs, l4_msg_regs_t *mregs, int item, l4re_ds_t *mem, l4_addr_t *addr, int *local); long _import_fpage(l4_msgtag_t tag, l4_buf_regs_t *bregs, l4_msg_regs_t *mregs, int item, l4_snd_fpage_t *fpage); /* Convenience operations. */ diff -r ec186bf44106 -r c47fb183300d libipc/lib/src/direct.c --- a/libipc/lib/src/direct.c Tue Mar 07 19:10:40 2023 +0100 +++ b/libipc/lib/src/direct.c Thu Mar 09 19:27:22 2023 +0100 @@ -1,7 +1,7 @@ /* * Interprocess communication abstractions. * - * Copyright (C) 2018, 2019 Paul Boddie + * Copyright (C) 2018, 2019, 2021, 2023 Paul Boddie * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -54,7 +54,16 @@ long ipc_import_capability(l4_msgtag_t tag, int item, l4_cap_idx_t *ref) { - return _import_capability(tag, l4_utcb_br(), l4_utcb_mr(), item, ref); + int local; + long err = _import_capability(tag, l4_utcb_br(), l4_utcb_mr(), item, ref, &local); + + if (err) + return err; + + if (local) + return L4_EOK; + + return ipc_expect_capability(item); } /* Import a dataspace, mapping it to an address, updating the buffer registers @@ -62,5 +71,17 @@ long ipc_import_dataspace(l4_msgtag_t tag, int item, l4re_ds_t *mem, l4_addr_t *addr) { - return _import_dataspace(tag, l4_utcb_br(), l4_utcb_mr(), item, mem, addr); + int local; + long err = _import_dataspace(tag, l4_utcb_br(), l4_utcb_mr(), item, mem, addr, &local); + + if (err) + return err; + + if (local) + return L4_EOK; + + return ipc_expect_capability(item); } + +/* vim: tabstop=2 expandtab shiftwidth=2 +*/ diff -r ec186bf44106 -r c47fb183300d libipc/lib/src/message.c --- a/libipc/lib/src/message.c Tue Mar 07 19:10:40 2023 +0100 +++ b/libipc/lib/src/message.c Thu Mar 09 19:27:22 2023 +0100 @@ -481,11 +481,15 @@ long ipc_message_import_capability(ipc_message_t *msg, int item, l4_cap_idx_t *ref) { long err; + int local; - err = _import_capability(msg->tag, &msg->bregs, &msg->mregs, item, ref); + err = _import_capability(msg->tag, &msg->bregs, &msg->mregs, item, ref, &local); if (err) return err; + if (local) + return L4_EOK; + return ipc_message_expect_capability(msg, item); } @@ -495,11 +499,15 @@ long ipc_message_import_dataspace(ipc_message_t *msg, int item, l4re_ds_t *mem, l4_addr_t *addr) { long err; + int local; - err = _import_dataspace(msg->tag, &msg->bregs, &msg->mregs, item, mem, addr); + err = _import_dataspace(msg->tag, &msg->bregs, &msg->mregs, item, mem, addr, &local); if (err) return err; + if (local) + return L4_EOK; + return ipc_message_expect_capability(msg, item); } diff -r ec186bf44106 -r c47fb183300d libipc/lib/src/util_ipc.c --- a/libipc/lib/src/util_ipc.c Tue Mar 07 19:10:40 2023 +0100 +++ b/libipc/lib/src/util_ipc.c Thu Mar 09 19:27:22 2023 +0100 @@ -61,7 +61,7 @@ /* Indicate the expectation of a capability in return. */ bregs->bdr = 0; - bregs->br[item] = L4_RCV_ITEM_SINGLE_CAP | future; + bregs->br[item] = L4_RCV_ITEM_SINGLE_CAP | future | L4_RCV_ITEM_LOCAL_ID; return L4_EOK; } @@ -126,7 +126,8 @@ /* Import from the message the capability at the given item position. */ long _import_capability(l4_msgtag_t tag, l4_buf_regs_t *bregs, - l4_msg_regs_t *mregs, int item, l4_cap_idx_t *ref) + l4_msg_regs_t *mregs, int item, l4_cap_idx_t *ref, + int *local) { l4_snd_fpage_t fpage; long err = _import_fpage(tag, bregs, mregs, item, &fpage); @@ -134,15 +135,30 @@ if (err) return err; - /* Check for a received capability. */ + /* Check for a received capability and update the supplied capability + index. */ + + /* Inter-task capability transfer. */ + + if ((fpage.snd_base & 0x3e) == 0x38) + { + *ref = bregs->br[item] & L4_CAP_MASK; + *local = 0; + } - if ((fpage.snd_base & 0x3e) != 0x38) + /* Local capability transfer. */ + + else if ((fpage.snd_base & 0x3e) == 0x3e) + { + *ref = l4_fpage_obj(fpage.fpage); + *local = 1; + } + + /* Unsupported item. */ + + else return -L4_EIO; - /* Update the supplied capability index. */ - - *ref = bregs->br[item] & L4_CAP_MASK; - return L4_EOK; } @@ -150,18 +166,19 @@ long _import_dataspace(l4_msgtag_t tag, l4_buf_regs_t *bregs, l4_msg_regs_t *mregs, int item, l4re_ds_t *mem, - l4_addr_t *addr) + l4_addr_t *addr, int *local) { long err; unsigned long size; *mem = ipc_cap_alloc(); - err = _import_capability(tag, bregs, mregs, item, mem); + err = _import_capability(tag, bregs, mregs, item, mem, local); if (err) { - ipc_cap_free_um(*mem); + if (!*local) + ipc_cap_free_um(*mem); return err; }