Skip to content

Commit

Permalink
ref(core/remio): replace Remote I/O ID by a bind key
Browse files Browse the repository at this point in the history
Since the unique identifier is solely used to connect the
Remote I/O device frontend with its corresponding backend,
a named link bind key is more appropriate than an ID for
this purpose.

Signed-off-by: João Peixoto <[email protected]>
  • Loading branch information
joaopeixoto13 committed Oct 31, 2024
1 parent efef183 commit 99fe2a9
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 51 deletions.
12 changes: 6 additions & 6 deletions src/core/inc/remio.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,12 @@ enum REMIO_DEV_TYPE {
* @note The device can be either a frontend (driver) or a backend (device)
*/
struct remio_dev {
vaddr_t va; /**< Frontend MMIO base virtual address */
size_t size; /**< Frontend MMIO size */
irqid_t interrupt; /**< Frontend/backend interrupt number */
remio_id_t id; /**< Remote I/O ID */
enum REMIO_DEV_TYPE type; /**< Type of the Remote I/O device */
struct remio_shmem shmem; /**< Shared memory region */
vaddr_t va; /**< Frontend MMIO base virtual address */
size_t size; /**< Frontend MMIO size */
irqid_t interrupt; /**< Frontend/backend interrupt number */
remio_bind_key_t bind_key; /**< Remote I/O bind key */
enum REMIO_DEV_TYPE type; /**< Type of the Remote I/O device */
struct remio_shmem shmem; /**< Shared memory region */
};

/**
Expand Down
2 changes: 1 addition & 1 deletion src/core/inc/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ typedef unsigned irqid_t;

typedef unsigned deviceid_t;

typedef size_t remio_id_t;
typedef size_t remio_bind_key_t;

typedef size_t objpool_id_t;

Expand Down
85 changes: 42 additions & 43 deletions src/core/remio.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,11 @@ enum REMIO_STATE {
*/
union remio_cpu_msg_data {
struct {
uint8_t remio_id; /**< Remote I/O ID */
uint8_t request_id; /**< Remote I/O request ID */
uint8_t interrupt; /**< Interrupt ID */
uint8_t remio_bind_key; /**< Remote I/O bind key */
uint8_t request_id; /**< Remote I/O request ID */
uint8_t interrupt; /**< Interrupt ID */
};
uint64_t raw; /**< Raw data */
uint64_t raw; /**< Raw data */
};

/**
Expand Down Expand Up @@ -118,7 +118,7 @@ struct remio_device_config {
*/
struct remio_device {
node_t node; /**< Node */
remio_id_t id; /**< Remote I/O device ID */
remio_bind_key_t bind_key; /**< Remote I/O bind key */
struct remio_device_config config; /**< Remote I/O device configuration */
struct list request_event_list; /**< List of pending I/O requests events */
struct remio_request requests[REMIO_VCPU_NUM]; /**< Array of Remote I/O requests */
Expand Down Expand Up @@ -280,15 +280,15 @@ static inline size_t remio_get_request_event_count(struct remio_device* device)
}

/**
* @brief Finds the Remote I/O device based on the Remote I/O device ID
* @param id Remote I/O device ID
* @brief Finds the Remote I/O device based on the Remote I/O bind key
* @param bind_key Remote I/O bind key
* @return Returns the Remote I/O device or NULL if the device was not found
*/
static struct remio_device* remio_find_dev_by_id(remio_id_t id)
static struct remio_device* remio_find_dev_by_bind_key(remio_bind_key_t bind_key)
{
struct remio_device* device = NULL;
list_foreach (remio_device_list, struct remio_device, dev) {
if (id == dev->id) {
if (bind_key == dev->bind_key) {
device = dev;
break;
}
Expand All @@ -297,21 +297,21 @@ static struct remio_device* remio_find_dev_by_id(remio_id_t id)
}

/**
* @brief Finds the Remote I/O device associated with a VM based on the Remote I/O device ID
* @brief Finds the Remote I/O device associated with a VM based on the Remote I/O bind key
* @param vm Pointer to the VM structure
* @param id Remote I/O device ID
* @param bind_key Remote I/O bind key
* @return Returns the Remote I/O device or NULL if the device was not found
*/
static struct remio_device* remio_find_vm_dev_by_id(struct vm* vm, unsigned long id)
static struct remio_device* remio_find_vm_dev_by_bind_key(struct vm* vm, unsigned long bind_key)
{
struct remio_dev* dev = NULL;
struct remio_device* device = NULL;

/** Find the Remote I/O device VM configuration based on the Remote I/O device ID */
/** Find the Remote I/O device VM configuration based on the Remote I/O bind key */
struct vm_config* vm_config = &config.vmlist[vm->id];
for (size_t i = 0; i < vm_config->platform.remio_dev_num; i++) {
dev = &vm_config->platform.remio_devs[i];
if (dev->id == id) {
if (dev->bind_key == bind_key) {
break;
}
}
Expand All @@ -320,8 +320,8 @@ static struct remio_device* remio_find_vm_dev_by_id(struct vm* vm, unsigned long
return NULL;
}

/** Find the Remote I/O device based on the Remote I/O device ID */
device = remio_find_dev_by_id(id);
/** Find the Remote I/O device based on the Remote I/O bind key */
device = remio_find_dev_by_bind_key(bind_key);
if (device == NULL) {
return NULL;
}
Expand Down Expand Up @@ -360,22 +360,22 @@ static struct remio_device* remio_find_vm_dev_by_addr(struct vm* vm, unsigned lo
return NULL;
}

return remio_find_vm_dev_by_id(vm, dev->id);
return remio_find_vm_dev_by_bind_key(vm, dev->bind_key);
}

/**
* @brief Sends a Remote I/O CPU message to the target CPU
* @param event Message event (REMIO_CPU_MSG_*)
* @param target_cpu Target CPU ID
* @param remio_id Remote I/O device ID
* @param remio_bind_key Remote I/O bind key
* @param request_id Remote I/O request ID
* @param interrupt Interrupt ID
*/
static void remio_cpu_send_msg(enum REMIO_CPU_MSG_EVENT event, unsigned long target_cpu,
unsigned long remio_id, unsigned long request_id, unsigned long interrupt)
unsigned long remio_bind_key, unsigned long request_id, unsigned long interrupt)
{
union remio_cpu_msg_data data = {
.remio_id = (uint8_t)remio_id,
.remio_bind_key = (uint8_t)remio_bind_key,
.request_id = (uint8_t)request_id,
.interrupt = (uint8_t)interrupt,
};
Expand Down Expand Up @@ -410,26 +410,26 @@ void remio_init(void)
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->id][dev->type] != REMIO_DEVICE_UNINITIALIZED) {
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->id);
dev->type == REMIO_DEV_BACKEND ? "backend" : "frontend", dev->bind_key);
}
if (dev->type == REMIO_DEV_BACKEND) {
struct remio_device* device = objpool_alloc(&remio_device_pool);
if (device == NULL) {
ERROR("Failed allocating Remote I/O device node");
}
device->id = dev->id;
device->bind_key = dev->bind_key;
list_init(&device->request_event_list);
list_push(&remio_device_list, (node_t*)device);
backend_cnt++;
devices[dev->id][REMIO_DEV_BACKEND] = (int)vm_id;
shmem[dev->id][REMIO_DEV_BACKEND] = dev->shmem;
devices[dev->bind_key][REMIO_DEV_BACKEND] = (int)vm_id;
shmem[dev->bind_key][REMIO_DEV_BACKEND] = dev->shmem;
} else if (dev->type == REMIO_DEV_FRONTEND) {
frontend_cnt++;
devices[dev->id][REMIO_DEV_FRONTEND] = (int)vm_id;
shmem[dev->id][REMIO_DEV_FRONTEND] = dev->shmem;
devices[dev->bind_key][REMIO_DEV_FRONTEND] = (int)vm_id;
shmem[dev->bind_key][REMIO_DEV_FRONTEND] = dev->shmem;
} else {
ERROR("Unknown Remote I/O device type");
}
Expand Down Expand Up @@ -460,9 +460,9 @@ void remio_init(void)
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];
struct remio_device* device = remio_find_dev_by_id(dev->id);
struct remio_device* device = remio_find_dev_by_bind_key(dev->bind_key);
if (device == NULL) {
ERROR("Failed to find Remote I/O device %d", dev->id);
ERROR("Failed to find Remote I/O device %d", dev->bind_key);
}
if (dev->type == REMIO_DEV_BACKEND) {
device->config.backend.vm_id = vm_id;
Expand Down Expand Up @@ -565,13 +565,13 @@ static bool remio_handle_rw(unsigned long value, unsigned long request_id,
* @note This function is executed by the frontend VM and is responsible for updating the
* vCPU register in case of a read operation and activating the frontend vCPU
* @param event Message event (REMIO_CPU_MSG_*)
* @param remio_id Remote I/O device ID
* @param remio_bind_key Remote I/O bind key
* @param request_id Remote I/O request ID
* @return Returns true if the operation was successful, false otherwise
*/
static bool remio_cpu_post_work(uint32_t event, uint8_t remio_id, uint8_t request_id)
static bool remio_cpu_post_work(uint32_t event, uint8_t remio_bind_key, uint8_t request_id)
{
struct remio_device* device = remio_find_dev_by_id(remio_id);
struct remio_device* device = remio_find_dev_by_bind_key(remio_bind_key);

if (remio_get_request_state(device, request_id) != REMIO_STATE_COMPLETE) {
return false;
Expand Down Expand Up @@ -602,30 +602,29 @@ static bool remio_cpu_post_work(uint32_t event, uint8_t remio_id, uint8_t reques
long int remio_hypercall(unsigned long arg0, unsigned long arg1, unsigned long arg2)
{
long int ret = -HC_E_SUCCESS;
unsigned long virt_remio_dev_id = arg0;
unsigned long dm_id = arg0;
unsigned long addr = arg1;
unsigned long op = arg2;
unsigned long value = vcpu_readreg(cpu()->vcpu, HYPCALL_IN_ARG_REG(3));
unsigned long request_id = vcpu_readreg(cpu()->vcpu, HYPCALL_IN_ARG_REG(4));
struct remio_device* device = NULL;
struct vm* vm = cpu()->vcpu->vm;

/** Check if the virtual Remote I/O device ID is within the valid range */
if (virt_remio_dev_id >= config.vmlist[vm->id].platform.remio_dev_num) {
ERROR("Remote I/O ID (%d) exceeds the valid range for backend VM (%d)", virt_remio_dev_id,
vm->id);
/** Check if the device model ID is within the valid range */
if (dm_id >= config.vmlist[vm->id].platform.remio_dev_num) {
ERROR("Device model ID (%d) exceeds the valid range for backend VM (%d)", dm_id, vm->id);
return -HC_E_FAILURE;
}

/** Get the Remote I/O device ID based on the virtual Remote I/O device ID */
unsigned long remio_dev_id = config.vmlist[vm->id].platform.remio_devs[virt_remio_dev_id].id;
/** Get the Remote I/O bind key based on the device model ID */
unsigned long remio_dev_bind_key = config.vmlist[vm->id].platform.remio_devs[dm_id].bind_key;

/** Find the Remote I/O device associated with the current backend VM */
device = remio_find_vm_dev_by_id(vm, remio_dev_id);
device = remio_find_vm_dev_by_bind_key(vm, remio_dev_bind_key);
if (device == NULL) {
ERROR("The Remote I/O backend device (%d) is not associated with the current backend VM "
"(%d)",
virt_remio_dev_id, vm->id);
dm_id, vm->id);
return -HC_E_FAILURE;
}

Expand All @@ -637,7 +636,7 @@ long int remio_hypercall(unsigned long arg0, unsigned long arg1, unsigned long a
} else {
/** Send a CPU message to the backend VM to execute the post work */
remio_cpu_send_msg(op == REMIO_HYP_WRITE ? REMIO_CPU_MSG_WRITE : REMIO_CPU_MSG_READ,
device->requests[request_id].cpu_id, remio_dev_id, request_id, 0);
device->requests[request_id].cpu_id, remio_dev_bind_key, request_id, 0);
}
break;
case REMIO_HYP_ASK:
Expand Down Expand Up @@ -695,7 +694,7 @@ static void remio_cpu_handler(uint32_t event, uint64_t data)
switch (event) {
case REMIO_CPU_MSG_WRITE:
case REMIO_CPU_MSG_READ:
if (!remio_cpu_post_work(event, msg.remio_id, msg.request_id)) {
if (!remio_cpu_post_work(event, msg.remio_bind_key, msg.request_id)) {
ERROR("Failed to perform the post work after the completion of the I/O request");
}
break;
Expand Down
2 changes: 1 addition & 1 deletion src/core/vm.c
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ static void vm_init_remio_dev(struct vm* vm, struct remio_dev* remio_dev)
struct shmem* shmem = shmem_get(remio_dev->shmem.shmem_id);
if (shmem == NULL) {
ERROR("Invalid shmem id (%d) in the Remote I/O device (%d) configuration",
remio_dev->shmem.shmem_id, remio_dev->id);
remio_dev->shmem.shmem_id, remio_dev->bind_key);
}
size_t shmem_size = remio_dev->shmem.size;
if (shmem_size > shmem->size) {
Expand Down

0 comments on commit 99fe2a9

Please sign in to comment.