From 93106f28ab7c610c7d32aa013aa0b271cf770e7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Peixoto?= Date: Mon, 28 Oct 2024 14:57:16 +0000 Subject: [PATCH] fix(core/remio): allow bind_key to accept any value MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit removes the previous restriction on the `bind_key` field, which required 0 < bind_key < REMIO_MAX_DEVICES. Signed-off-by: João Peixoto --- src/core/remio.c | 91 +++++++++++++++++++++++++----------------------- 1 file changed, 47 insertions(+), 44 deletions(-) diff --git a/src/core/remio.c b/src/core/remio.c index f01842a4..0f27931b 100644 --- a/src/core/remio.c +++ b/src/core/remio.c @@ -16,10 +16,8 @@ #include #include -#define REMIO_MAX_DEVICES 32 -#define REMIO_DEVICE_UNINITIALIZED -1 -#define REMIO_VCPU_NUM PLAT_CPU_NUM -#define REMIO_NUM_DEV_TYPES (REMIO_DEV_BACKEND - REMIO_DEV_FRONTEND + 1) +#define REMIO_VCPU_NUM PLAT_CPU_NUM +#define REMIO_NUM_DEV_TYPES (REMIO_DEV_BACKEND - REMIO_DEV_FRONTEND + 1) /** * @enum REMIO_HYP_EVENT @@ -101,14 +99,18 @@ struct remio_request_event { */ struct remio_device_config { struct { - cpuid_t cpu_id; /**< Backend VM CPU ID */ - vmid_t vm_id; /**< Backend VM ID */ - irqid_t interrupt; /**< Backend interrupt ID */ + remio_bind_key_t bind_key; /**< Backend bind key */ + cpuid_t cpu_id; /**< Backend VM CPU ID */ + vmid_t vm_id; /**< Backend VM ID */ + irqid_t interrupt; /**< Backend interrupt ID */ + struct remio_shmem shmem; /**< Backend shared memory region */ } backend; struct { - cpuid_t cpu_id; /**< Frontend VM CPU ID */ - vmid_t vm_id; /**< Frontend VM ID */ - irqid_t interrupt; /**< Frontend interrupt ID */ + remio_bind_key_t bind_key; /**< Frontend bind key */ + cpuid_t cpu_id; /**< Frontend VM CPU ID */ + vmid_t vm_id; /**< Frontend VM ID */ + irqid_t interrupt; /**< Frontend interrupt ID */ + struct remio_shmem shmem; /**< Frontend shared memory region */ } frontend; }; @@ -385,9 +387,7 @@ static void remio_cpu_send_msg(enum REMIO_CPU_MSG_EVENT event, unsigned long tar void remio_init(void) { - size_t frontend_cnt = 0, backend_cnt = 0; - int devices[REMIO_MAX_DEVICES][REMIO_NUM_DEV_TYPES]; - struct remio_shmem shmem[REMIO_MAX_DEVICES][REMIO_NUM_DEV_TYPES]; + size_t counter[REMIO_NUM_DEV_TYPES] = { 0 }; /** Only execute the Remote I/O initialization routine on the master CPU */ if (!cpu_is_master()) { @@ -398,60 +398,63 @@ void remio_init(void) objpool_init(&remio_request_event_pool); list_init(&remio_device_list); - for (size_t i = 0; i < REMIO_MAX_DEVICES; i++) { - devices[i][REMIO_DEV_FRONTEND] = REMIO_DEVICE_UNINITIALIZED; - devices[i][REMIO_DEV_BACKEND] = REMIO_DEVICE_UNINITIALIZED; - shmem[i][REMIO_DEV_FRONTEND] = (struct remio_shmem){ 0 }; - shmem[i][REMIO_DEV_BACKEND] = (struct remio_shmem){ 0 }; - } - /** Create the Remote I/O devices based on the VM configuration */ for (size_t vm_id = 0; vm_id < config.vmlist_size; vm_id++) { struct vm_config* vm_config = &config.vmlist[vm_id]; for (size_t i = 0; i < vm_config->platform.remio_dev_num; i++) { struct remio_dev* dev = &vm_config->platform.remio_devs[i]; - if (devices[dev->bind_key][dev->type] != REMIO_DEVICE_UNINITIALIZED) { - ERROR("Failed to link backend to the frontend, more than one %s was " - "atributed to the Remote I/O device %d", - dev->type == REMIO_DEV_BACKEND ? "backend" : "frontend", dev->bind_key); + struct remio_device* device = NULL; + list_foreach (remio_device_list, struct remio_device, remio_device) { + if ((dev->bind_key == remio_device->config.backend.bind_key && + dev->type == REMIO_DEV_BACKEND) || + (dev->bind_key == remio_device->config.frontend.bind_key && + dev->type == REMIO_DEV_FRONTEND)) { + ERROR("Failed to link backend to the frontend, more than one %s was " + "atributed to the Remote I/O device %d", + dev->type == REMIO_DEV_BACKEND ? "backend" : "frontend", dev->bind_key); + } else if ((dev->type == REMIO_DEV_BACKEND && + dev->bind_key == remio_device->config.frontend.bind_key) || + (dev->type == REMIO_DEV_FRONTEND && + dev->bind_key == remio_device->config.backend.bind_key)) { + device = remio_device; + break; + } } - if (dev->type == REMIO_DEV_BACKEND) { - struct remio_device* device = objpool_alloc(&remio_device_pool); + if (device == NULL) { + device = objpool_alloc(&remio_device_pool); if (device == NULL) { - ERROR("Failed allocating Remote I/O device node"); + ERROR("Failed creating Remote I/O device %d", dev->bind_key); } device->bind_key = dev->bind_key; list_init(&device->request_event_list); list_push(&remio_device_list, (node_t*)device); - backend_cnt++; - devices[dev->bind_key][REMIO_DEV_BACKEND] = (int)vm_id; - shmem[dev->bind_key][REMIO_DEV_BACKEND] = dev->shmem; + } + if (dev->type == REMIO_DEV_BACKEND) { + device->config.backend.bind_key = dev->bind_key; + device->config.backend.shmem = dev->shmem; } else if (dev->type == REMIO_DEV_FRONTEND) { - frontend_cnt++; - devices[dev->bind_key][REMIO_DEV_FRONTEND] = (int)vm_id; - shmem[dev->bind_key][REMIO_DEV_FRONTEND] = dev->shmem; + device->config.frontend.bind_key = dev->bind_key; + device->config.frontend.shmem = dev->shmem; } else { ERROR("Unknown Remote I/O device type"); } + counter[dev->type]++; } } /** Check if there is a 1-to-1 mapping between a Remote I/O backend and Remote I/O frontend */ - if (backend_cnt != frontend_cnt) { + if (counter[REMIO_DEV_FRONTEND] != counter[REMIO_DEV_BACKEND]) { ERROR("There is no 1-to-1 mapping between a Remote I/O backend and Remote I/O frontend"); } /** Check if the shared memory regions are correctly configured */ - for (size_t i = 0; i < REMIO_MAX_DEVICES; i++) { - if (devices[i][REMIO_DEV_FRONTEND] != REMIO_DEVICE_UNINITIALIZED && - devices[i][REMIO_DEV_BACKEND] != REMIO_DEVICE_UNINITIALIZED) { - if (shmem[i][REMIO_DEV_FRONTEND].base != shmem[i][REMIO_DEV_BACKEND].base || - shmem[i][REMIO_DEV_FRONTEND].size != shmem[i][REMIO_DEV_BACKEND].size || - shmem[i][REMIO_DEV_FRONTEND].shmem_id != shmem[i][REMIO_DEV_BACKEND].shmem_id) { - ERROR("Invalid shared memory region configuration for Remote I/O device %d.\n" - "The frontend and backend shared memory regions must be the aligned.", - i); - } + list_foreach (remio_device_list, struct remio_device, dev) { + if (dev->config.backend.shmem.base != dev->config.frontend.shmem.base || + dev->config.backend.shmem.size != dev->config.frontend.shmem.size || + dev->config.backend.shmem.shmem_id != dev->config.frontend.shmem.shmem_id) { + ERROR("Invalid shared memory region configuration for Remote I/O device %d.\n" + "The frontend and backend shared memory regions must be the aligned.", + dev->bind_key); } }