1616#include <config.h>
1717#include <spinlock.h>
1818
19- #define REMIO_MAX_DEVICES 32
20- #define REMIO_DEVICE_UNINITIALIZED -1
21- #define REMIO_VCPU_NUM PLAT_CPU_NUM
22- #define REMIO_NUM_DEV_TYPES (REMIO_DEV_BACKEND - REMIO_DEV_FRONTEND + 1)
19+ #define REMIO_VCPU_NUM PLAT_CPU_NUM
20+ #define REMIO_NUM_DEV_TYPES (REMIO_DEV_BACKEND - REMIO_DEV_FRONTEND + 1)
2321
2422/**
2523 * @enum REMIO_HYP_EVENT
@@ -101,14 +99,18 @@ struct remio_request_event {
10199 */
102100struct remio_device_config {
103101 struct {
104- cpuid_t cpu_id ; /**< Backend VM CPU ID */
105- vmid_t vm_id ; /**< Backend VM ID */
106- irqid_t interrupt ; /**< Backend interrupt ID */
102+ remio_bind_key_t bind_key ; /**< Backend bind key */
103+ cpuid_t cpu_id ; /**< Backend VM CPU ID */
104+ vmid_t vm_id ; /**< Backend VM ID */
105+ irqid_t interrupt ; /**< Backend interrupt ID */
106+ struct remio_shmem shmem ; /**< Backend shared memory region */
107107 } backend ;
108108 struct {
109- cpuid_t cpu_id ; /**< Frontend VM CPU ID */
110- vmid_t vm_id ; /**< Frontend VM ID */
111- irqid_t interrupt ; /**< Frontend interrupt ID */
109+ remio_bind_key_t bind_key ; /**< Frontend bind key */
110+ cpuid_t cpu_id ; /**< Frontend VM CPU ID */
111+ vmid_t vm_id ; /**< Frontend VM ID */
112+ irqid_t interrupt ; /**< Frontend interrupt ID */
113+ struct remio_shmem shmem ; /**< Frontend shared memory region */
112114 } frontend ;
113115};
114116
@@ -385,9 +387,7 @@ static void remio_cpu_send_msg(enum REMIO_CPU_MSG_EVENT event, unsigned long tar
385387
386388void remio_init (void )
387389{
388- size_t frontend_cnt = 0 , backend_cnt = 0 ;
389- int devices [REMIO_MAX_DEVICES ][REMIO_NUM_DEV_TYPES ];
390- struct remio_shmem shmem [REMIO_MAX_DEVICES ][REMIO_NUM_DEV_TYPES ];
390+ size_t counter [REMIO_NUM_DEV_TYPES ] = { 0 };
391391
392392 /** Only execute the Remote I/O initialization routine on the master CPU */
393393 if (!cpu_is_master ()) {
@@ -398,60 +398,65 @@ void remio_init(void)
398398 objpool_init (& remio_request_event_pool );
399399 list_init (& remio_device_list );
400400
401- for (size_t i = 0 ; i < REMIO_MAX_DEVICES ; i ++ ) {
402- devices [i ][REMIO_DEV_FRONTEND ] = REMIO_DEVICE_UNINITIALIZED ;
403- devices [i ][REMIO_DEV_BACKEND ] = REMIO_DEVICE_UNINITIALIZED ;
404- shmem [i ][REMIO_DEV_FRONTEND ] = (struct remio_shmem ){ 0 };
405- shmem [i ][REMIO_DEV_BACKEND ] = (struct remio_shmem ){ 0 };
406- }
407-
408401 /** Create the Remote I/O devices based on the VM configuration */
409402 for (size_t vm_id = 0 ; vm_id < config .vmlist_size ; vm_id ++ ) {
410403 struct vm_config * vm_config = & config .vmlist [vm_id ];
411404 for (size_t i = 0 ; i < vm_config -> platform .remio_dev_num ; i ++ ) {
412405 struct remio_dev * dev = & vm_config -> platform .remio_devs [i ];
413- if (devices [dev -> bind_key ][dev -> type ] != REMIO_DEVICE_UNINITIALIZED ) {
414- ERROR ("Failed to link backend to the frontend, more than one %s was "
415- "atributed to the Remote I/O device %d" ,
416- dev -> type == REMIO_DEV_BACKEND ? "backend" : "frontend" , dev -> bind_key );
406+ struct remio_device * device = NULL ;
407+ list_foreach (remio_device_list , struct remio_device , remio_device ) {
408+ if ((dev -> bind_key == remio_device -> config .backend .bind_key &&
409+ dev -> type == REMIO_DEV_BACKEND ) ||
410+ (dev -> bind_key == remio_device -> config .frontend .bind_key &&
411+ dev -> type == REMIO_DEV_FRONTEND )) {
412+ ERROR ("Failed to link backend to the frontend, more than one %s was "
413+ "atributed to the Remote I/O device %d" ,
414+ dev -> type == REMIO_DEV_BACKEND ? "backend" : "frontend" , dev -> bind_key );
415+ } else if ((dev -> type == REMIO_DEV_BACKEND &&
416+ dev -> bind_key == remio_device -> config .frontend .bind_key ) ||
417+ (dev -> type == REMIO_DEV_FRONTEND &&
418+ dev -> bind_key == remio_device -> config .backend .bind_key )) {
419+ device = remio_device ;
420+ break ;
421+ }
417422 }
418- if (dev -> type == REMIO_DEV_BACKEND ) {
419- struct remio_device * device = objpool_alloc (& remio_device_pool );
423+ if (device == NULL ) {
424+ device = objpool_alloc (& remio_device_pool );
420425 if (device == NULL ) {
421- ERROR ("Failed allocating Remote I/O device node" );
426+ ERROR ("Failed creating Remote I/O device %d" , dev -> bind_key );
422427 }
423428 device -> bind_key = dev -> bind_key ;
429+ device -> config .backend .bind_key = (remio_bind_key_t )- 1 ;
430+ device -> config .frontend .bind_key = (remio_bind_key_t )- 1 ;
424431 list_init (& device -> request_event_list );
425432 list_push (& remio_device_list , (node_t * )device );
426- backend_cnt ++ ;
427- devices [dev -> bind_key ][REMIO_DEV_BACKEND ] = (int )vm_id ;
428- shmem [dev -> bind_key ][REMIO_DEV_BACKEND ] = dev -> shmem ;
433+ }
434+ if (dev -> type == REMIO_DEV_BACKEND ) {
435+ device -> config .backend .bind_key = dev -> bind_key ;
436+ device -> config .backend .shmem = dev -> shmem ;
429437 } else if (dev -> type == REMIO_DEV_FRONTEND ) {
430- frontend_cnt ++ ;
431- devices [dev -> bind_key ][REMIO_DEV_FRONTEND ] = (int )vm_id ;
432- shmem [dev -> bind_key ][REMIO_DEV_FRONTEND ] = dev -> shmem ;
438+ device -> config .frontend .bind_key = dev -> bind_key ;
439+ device -> config .frontend .shmem = dev -> shmem ;
433440 } else {
434441 ERROR ("Unknown Remote I/O device type" );
435442 }
443+ counter [dev -> type ]++ ;
436444 }
437445 }
438446
439447 /** Check if there is a 1-to-1 mapping between a Remote I/O backend and Remote I/O frontend */
440- if (backend_cnt != frontend_cnt ) {
448+ if (counter [ REMIO_DEV_FRONTEND ] != counter [ REMIO_DEV_BACKEND ] ) {
441449 ERROR ("There is no 1-to-1 mapping between a Remote I/O backend and Remote I/O frontend" );
442450 }
443451
444452 /** Check if the shared memory regions are correctly configured */
445- for (size_t i = 0 ; i < REMIO_MAX_DEVICES ; i ++ ) {
446- if (devices [i ][REMIO_DEV_FRONTEND ] != REMIO_DEVICE_UNINITIALIZED &&
447- devices [i ][REMIO_DEV_BACKEND ] != REMIO_DEVICE_UNINITIALIZED ) {
448- if (shmem [i ][REMIO_DEV_FRONTEND ].base != shmem [i ][REMIO_DEV_BACKEND ].base ||
449- shmem [i ][REMIO_DEV_FRONTEND ].size != shmem [i ][REMIO_DEV_BACKEND ].size ||
450- shmem [i ][REMIO_DEV_FRONTEND ].shmem_id != shmem [i ][REMIO_DEV_BACKEND ].shmem_id ) {
451- ERROR ("Invalid shared memory region configuration for Remote I/O device %d.\n"
452- "The frontend and backend shared memory regions must be the aligned." ,
453- i );
454- }
453+ list_foreach (remio_device_list , struct remio_device , dev ) {
454+ if (dev -> config .backend .shmem .base != dev -> config .frontend .shmem .base ||
455+ dev -> config .backend .shmem .size != dev -> config .frontend .shmem .size ||
456+ dev -> config .backend .shmem .shmem_id != dev -> config .frontend .shmem .shmem_id ) {
457+ ERROR ("Invalid shared memory region configuration for Remote I/O device %d.\n"
458+ "The frontend and backend shared memory regions must be the aligned." ,
459+ dev -> bind_key );
455460 }
456461 }
457462
0 commit comments