Skip to content

Commit 20ca7c7

Browse files
committed
fix(core/remio): add device ready flag
This commit adds a device-ready flag to ensure that both backend and frontend Remote I/O devices are fully initialized before the frontend initiates any MMIO access. This flag prevents missed CPU messages from the frontend to the backend in cases where the frontend (e.g., a bare-metal guest) initializes and starts execution before the backend Remote I/O device is fully set up. Signed-off-by: João Peixoto <[email protected]>
1 parent b9425a5 commit 20ca7c7

File tree

1 file changed

+14
-1
lines changed

1 file changed

+14
-1
lines changed

src/core/remio.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ struct remio_request_event {
9595

9696
/**
9797
* @struct remio_device_config
98-
* @brief This structure holds the static information regarding a Remote I/O device
98+
* @brief This structure holds the configuration of a Remote I/O device
9999
*/
100100
struct remio_device_config {
101101
struct {
@@ -104,13 +104,15 @@ struct remio_device_config {
104104
vmid_t vm_id; /**< Backend VM ID */
105105
irqid_t interrupt; /**< Backend interrupt ID */
106106
struct remio_shmem shmem; /**< Backend shared memory region */
107+
bool ready; /**< Backend ready flag */
107108
} backend;
108109
struct {
109110
remio_bind_key_t bind_key; /**< Frontend bind key */
110111
cpuid_t cpu_id; /**< Frontend VM CPU ID */
111112
vmid_t vm_id; /**< Frontend VM ID */
112113
irqid_t interrupt; /**< Frontend interrupt ID */
113114
struct remio_shmem shmem; /**< Frontend shared memory region */
115+
bool ready; /**< Frontend ready flag */
114116
} frontend;
115117
};
116118

@@ -120,6 +122,7 @@ struct remio_device_config {
120122
*/
121123
struct remio_device {
122124
node_t node; /**< Node */
125+
volatile bool ready; /**< Remote I/O device ready flag */
123126
remio_bind_key_t bind_key; /**< Remote I/O bind key */
124127
struct remio_device_config config; /**< Remote I/O device configuration */
125128
struct list request_event_list; /**< List of pending I/O requests events */
@@ -425,6 +428,7 @@ void remio_init(void)
425428
if (device == NULL) {
426429
ERROR("Failed creating Remote I/O device %d", dev->bind_key);
427430
}
431+
device->ready = false;
428432
device->bind_key = dev->bind_key;
429433
device->config.backend.bind_key = (remio_bind_key_t)-1;
430434
device->config.frontend.bind_key = (remio_bind_key_t)-1;
@@ -434,9 +438,11 @@ void remio_init(void)
434438
if (dev->type == REMIO_DEV_BACKEND) {
435439
device->config.backend.bind_key = dev->bind_key;
436440
device->config.backend.shmem = dev->shmem;
441+
device->config.backend.ready = false;
437442
} else if (dev->type == REMIO_DEV_FRONTEND) {
438443
device->config.frontend.bind_key = dev->bind_key;
439444
device->config.frontend.shmem = dev->shmem;
445+
device->config.frontend.ready = false;
440446
} else {
441447
ERROR("Unknown Remote I/O device type");
442448
}
@@ -496,9 +502,12 @@ void remio_assign_vm_cpus(struct vm* vm)
496502
list_foreach (remio_device_list, struct remio_device, dev) {
497503
if (vm->id == dev->config.backend.vm_id) {
498504
dev->config.backend.cpu_id = min(dev->config.backend.cpu_id, cpu()->id);
505+
dev->config.backend.ready = true;
499506
} else if (vm->id == dev->config.frontend.vm_id) {
500507
dev->config.frontend.cpu_id = min(dev->config.frontend.cpu_id, cpu()->id);
508+
dev->config.frontend.ready = true;
501509
}
510+
dev->ready = dev->config.backend.ready && dev->config.frontend.ready;
502511
}
503512
}
504513

@@ -671,6 +680,10 @@ bool remio_mmio_emul_handler(struct emul_access* acc)
671680
return false;
672681
}
673682

683+
/** Wait until the Remote I/O device is ready */
684+
while (!device->ready)
685+
;
686+
674687
/** Create a new Remote I/O request based on the MMIO access information */
675688
remio_create_request(acc, &request);
676689

0 commit comments

Comments
 (0)