# HG changeset patch # User Paul Boddie # Date 1705856196 -3600 # Node ID 09a9290aea31db8aed4b4d60b7b4dbc513e689fe # Parent bb13d118f8024c47486f8d4826c930c71b3a900d Fixed message item consumption, taking the first available item for each capability actually transferred. This is significant where a void or invalid capability is received: instead of the corresponding item in the buffer registers being skipped, the kernel takes this item for any valid subsequent capability, potentially leaving other items untouched. diff -r bb13d118f802 -r 09a9290aea31 libipc/include/ipc/message.h --- a/libipc/include/ipc/message.h Sun Jan 21 17:35:01 2024 +0100 +++ b/libipc/include/ipc/message.h Sun Jan 21 17:56:36 2024 +0100 @@ -50,6 +50,10 @@ unsigned int receive_items; + /* Imported item counter. */ + + unsigned int import_item; + /* Output details. */ unsigned int words; @@ -149,3 +153,6 @@ l4_msgtag_t ipc_message_request_tag(ipc_message_t *msg, int op); EXTERN_C_END + +/* vim: tabstop=2 expandtab shiftwidth=2 +*/ diff -r bb13d118f802 -r 09a9290aea31 libipc/include/ipc/util_ipc.h --- a/libipc/include/ipc/util_ipc.h Sun Jan 21 17:35:01 2024 +0100 +++ b/libipc/include/ipc/util_ipc.h Sun Jan 21 17:56:36 2024 +0100 @@ -1,7 +1,7 @@ /* * Interprocess communication abstractions. * - * Copyright (C) 2018, 2019, 2021, 2022, 2023 Paul Boddie + * Copyright (C) 2018-2024 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, 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_capability(l4_msgtag_t tag, l4_buf_regs_t *bregs, l4_msg_regs_t *mregs, int item, int buf_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, int buf_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 bb13d118f802 -r 09a9290aea31 libipc/lib/src/message.c --- a/libipc/lib/src/message.c Sun Jan 21 17:35:01 2024 +0100 +++ b/libipc/lib/src/message.c Sun Jan 21 17:56:36 2024 +0100 @@ -213,6 +213,7 @@ msg->discarded_items = 0; msg->words = 0; msg->items = 0; + msg->import_item = 0; /* Message label overriding. */ @@ -279,7 +280,7 @@ void ipc_message_add_receive_capability(ipc_message_t *msg, l4_cap_idx_t cap) { (void) cap; - return _expect_capability(&msg->bregs, msg->receive_items++); + _expect_capability(&msg->bregs, msg->receive_items++); } /* Add a receive window flexpage item to the message. */ @@ -502,14 +503,16 @@ long err; int local; - err = _import_capability(msg->tag, &msg->bregs, &msg->mregs, item, ref, &local); + err = _import_capability(msg->tag, &msg->bregs, &msg->mregs, item, msg->import_item, ref, &local); if (err) return err; if (local) return L4_EOK; - return ipc_message_expect_capability(msg, item); + err = ipc_message_expect_capability(msg, msg->import_item); + msg->import_item += 1; + return err; } /* Import from the message a dataspace, mapping it to an address, updating the @@ -520,14 +523,16 @@ long err; int local; - err = _import_dataspace(msg->tag, &msg->bregs, &msg->mregs, item, mem, addr, &local); + err = _import_dataspace(msg->tag, &msg->bregs, &msg->mregs, item, msg->import_item, mem, addr, &local); if (err) return err; if (local) return L4_EOK; - return ipc_message_expect_capability(msg, item); + err = ipc_message_expect_capability(msg, msg->import_item); + msg->import_item += 1; + return err; } /* Import from the message the capability at the given item position. */ @@ -535,8 +540,14 @@ long ipc_message_import_capability(ipc_message_t *msg, int item, l4_cap_idx_t *ref) { int local; + long err; - return _import_capability(msg->tag, &msg->bregs, &msg->mregs, item, ref, &local); + err = _import_capability(msg->tag, &msg->bregs, &msg->mregs, item, msg->import_item, ref, &local); + if (err) + return err; + + msg->import_item += local ? 0 : 1; + return L4_EOK; } /* Import from the message a dataspace, mapping it to an address. */ @@ -544,8 +555,14 @@ long ipc_message_import_dataspace(ipc_message_t *msg, int item, l4re_ds_t *mem, l4_addr_t *addr) { int local; + long err; - return _import_dataspace(msg->tag, &msg->bregs, &msg->mregs, item, mem, addr, &local); + err = _import_dataspace(msg->tag, &msg->bregs, &msg->mregs, item, msg->import_item, mem, addr, &local); + if (err) + return err; + + msg->import_item += local ? 0 : 1; + return L4_EOK; } /* Import from the message the flexpage at the given item position. */ diff -r bb13d118f802 -r 09a9290aea31 libipc/lib/src/util_ipc.c --- a/libipc/lib/src/util_ipc.c Sun Jan 21 17:35:01 2024 +0100 +++ b/libipc/lib/src/util_ipc.c Sun Jan 21 17:56:36 2024 +0100 @@ -1,7 +1,7 @@ /* * Interprocess communication abstractions. * - * Copyright (C) 2018, 2019, 2021, 2022, 2023 Paul Boddie + * Copyright (C) 2018-2024 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 @@ -126,8 +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, - int *local) + l4_msg_regs_t *mregs, int item, int buf_item, + l4_cap_idx_t *ref, int *local) { l4_snd_fpage_t fpage; long err = _import_fpage(tag, bregs, mregs, item, &fpage); @@ -142,7 +142,7 @@ if ((fpage.snd_base & 0x3e) == 0x38) { - *ref = bregs->br[item] & L4_CAP_MASK; + *ref = bregs->br[buf_item] & L4_CAP_MASK; *local = 0; } @@ -165,15 +165,15 @@ /* Import from the message a dataspace, mapping it to an address. */ 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) + l4_msg_regs_t *mregs, int item, int buf_item, + l4re_ds_t *mem, l4_addr_t *addr, int *local) { long err; unsigned long size; *mem = ipc_cap_alloc(); - err = _import_capability(tag, bregs, mregs, item, mem, local); + err = _import_capability(tag, bregs, mregs, item, buf_item, mem, local); if (err) {