@ -112,13 +112,6 @@ typedef struct IVShmemState {
/* migration stuff */
OnOffAuto master ;
Error * migration_blocker ;
/* legacy cruft */
char * role ;
char * shmobj ;
char * sizearg ;
size_t legacy_size ;
uint32_t not_legacy_32bit ;
} IVShmemState ;
/* registers for the Inter-VM shared memory device */
@ -529,17 +522,6 @@ static void process_msg_shmem(IVShmemState *s, int fd, Error **errp)
size = buf . st_size ;
/* Legacy cruft */
if ( s - > legacy_size ! = SIZE_MAX ) {
if ( size < s - > legacy_size ) {
error_setg ( errp , " server sent only %zd bytes of shared memory " ,
( size_t ) buf . st_size ) ;
close ( fd ) ;
return ;
}
size = s - > legacy_size ;
}
/* mmap the region and map into the BAR2 */
memory_region_init_ram_from_fd ( & s - > server_bar2 , OBJECT ( s ) ,
" ivshmem.bar2 " , size , true , fd , & local_err ) ;
@ -882,8 +864,6 @@ static void ivshmem_common_realize(PCIDevice *dev, Error **errp)
IVShmemState * s = IVSHMEM_COMMON ( dev ) ;
Error * err = NULL ;
uint8_t * pci_conf ;
uint8_t attr = PCI_BASE_ADDRESS_SPACE_MEMORY |
PCI_BASE_ADDRESS_MEM_PREFETCH ;
Error * local_err = NULL ;
/* IRQFD requires MSI */
@ -903,10 +883,6 @@ static void ivshmem_common_realize(PCIDevice *dev, Error **errp)
pci_register_bar ( dev , 0 , PCI_BASE_ADDRESS_SPACE_MEMORY ,
& s - > ivshmem_mmio ) ;
if ( s - > not_legacy_32bit ) {
attr | = PCI_BASE_ADDRESS_MEM_TYPE_64 ;
}
if ( s - > hostmem ! = NULL ) {
IVSHMEM_DPRINTF ( " using hostmem \n " ) ;
@ -964,7 +940,11 @@ static void ivshmem_common_realize(PCIDevice *dev, Error **errp)
}
vmstate_register_ram ( s - > ivshmem_bar2 , DEVICE ( s ) ) ;
pci_register_bar ( PCI_DEVICE ( s ) , 2 , attr , s - > ivshmem_bar2 ) ;
pci_register_bar ( PCI_DEVICE ( s ) , 2 ,
PCI_BASE_ADDRESS_SPACE_MEMORY |
PCI_BASE_ADDRESS_MEM_PREFETCH |
PCI_BASE_ADDRESS_MEM_TYPE_64 ,
s - > ivshmem_bar2 ) ;
}
static void ivshmem_exit ( PCIDevice * dev )
@ -1084,13 +1064,6 @@ static Property ivshmem_plain_properties[] = {
DEFINE_PROP_END_OF_LIST ( ) ,
} ;
static void ivshmem_plain_init ( Object * obj )
{
IVShmemState * s = IVSHMEM_PLAIN ( obj ) ;
s - > not_legacy_32bit = 1 ;
}
static void ivshmem_plain_realize ( PCIDevice * dev , Error * * errp )
{
IVShmemState * s = IVSHMEM_COMMON ( dev ) ;
@ -1122,7 +1095,6 @@ static const TypeInfo ivshmem_plain_info = {
. name = TYPE_IVSHMEM_PLAIN ,
. parent = TYPE_IVSHMEM_COMMON ,
. instance_size = sizeof ( IVShmemState ) ,
. instance_init = ivshmem_plain_init ,
. class_init = ivshmem_plain_class_init ,
} ;
@ -1155,8 +1127,6 @@ static void ivshmem_doorbell_init(Object *obj)
IVShmemState * s = IVSHMEM_DOORBELL ( obj ) ;
s - > features | = ( 1 < < IVSHMEM_MSI ) ;
s - > legacy_size = SIZE_MAX ; /* whatever the server sends */
s - > not_legacy_32bit = 1 ;
}
static void ivshmem_doorbell_realize ( PCIDevice * dev , Error * * errp )
@ -1189,181 +1159,11 @@ static const TypeInfo ivshmem_doorbell_info = {
. class_init = ivshmem_doorbell_class_init ,
} ;
static int ivshmem_load_old ( QEMUFile * f , void * opaque , int version_id )
{
IVShmemState * s = opaque ;
PCIDevice * pdev = PCI_DEVICE ( s ) ;
int ret ;
IVSHMEM_DPRINTF ( " ivshmem_load_old \n " ) ;
if ( version_id ! = 0 ) {
return - EINVAL ;
}
ret = ivshmem_pre_load ( s ) ;
if ( ret ) {
return ret ;
}
ret = pci_device_load ( pdev , f ) ;
if ( ret ) {
return ret ;
}
if ( ivshmem_has_feature ( s , IVSHMEM_MSI ) ) {
msix_load ( pdev , f ) ;
ivshmem_msix_vector_use ( s ) ;
} else {
s - > intrstatus = qemu_get_be32 ( f ) ;
s - > intrmask = qemu_get_be32 ( f ) ;
}
return 0 ;
}
static bool test_msix ( void * opaque , int version_id )
{
IVShmemState * s = opaque ;
return ivshmem_has_feature ( s , IVSHMEM_MSI ) ;
}
static bool test_no_msix ( void * opaque , int version_id )
{
return ! test_msix ( opaque , version_id ) ;
}
static const VMStateDescription ivshmem_vmsd = {
. name = " ivshmem " ,
. version_id = 1 ,
. minimum_version_id = 1 ,
. pre_load = ivshmem_pre_load ,
. post_load = ivshmem_post_load ,
. fields = ( VMStateField [ ] ) {
VMSTATE_PCI_DEVICE ( parent_obj , IVShmemState ) ,
VMSTATE_MSIX_TEST ( parent_obj , IVShmemState , test_msix ) ,
VMSTATE_UINT32_TEST ( intrstatus , IVShmemState , test_no_msix ) ,
VMSTATE_UINT32_TEST ( intrmask , IVShmemState , test_no_msix ) ,
VMSTATE_END_OF_LIST ( )
} ,
. load_state_old = ivshmem_load_old ,
. minimum_version_id_old = 0
} ;
static Property ivshmem_properties [ ] = {
DEFINE_PROP_CHR ( " chardev " , IVShmemState , server_chr ) ,
DEFINE_PROP_STRING ( " size " , IVShmemState , sizearg ) ,
DEFINE_PROP_UINT32 ( " vectors " , IVShmemState , vectors , 1 ) ,
DEFINE_PROP_BIT ( " ioeventfd " , IVShmemState , features , IVSHMEM_IOEVENTFD ,
false ) ,
DEFINE_PROP_BIT ( " msi " , IVShmemState , features , IVSHMEM_MSI , true ) ,
DEFINE_PROP_STRING ( " shm " , IVShmemState , shmobj ) ,
DEFINE_PROP_STRING ( " role " , IVShmemState , role ) ,
DEFINE_PROP_UINT32 ( " use64 " , IVShmemState , not_legacy_32bit , 1 ) ,
DEFINE_PROP_END_OF_LIST ( ) ,
} ;
static void desugar_shm ( IVShmemState * s )
{
Object * obj ;
char * path ;
obj = object_new ( " memory-backend-file " ) ;
path = g_strdup_printf ( " /dev/shm/%s " , s - > shmobj ) ;
object_property_set_str ( obj , path , " mem-path " , & error_abort ) ;
g_free ( path ) ;
object_property_set_int ( obj , s - > legacy_size , " size " , & error_abort ) ;
object_property_set_bool ( obj , true , " share " , & error_abort ) ;
object_property_add_child ( OBJECT ( s ) , " internal-shm-backend " , obj ,
& error_abort ) ;
object_unref ( obj ) ;
user_creatable_complete ( USER_CREATABLE ( obj ) , & error_abort ) ;
s - > hostmem = MEMORY_BACKEND ( obj ) ;
}
static void ivshmem_realize ( PCIDevice * dev , Error * * errp )
{
IVShmemState * s = IVSHMEM_COMMON ( dev ) ;
if ( ! qtest_enabled ( ) ) {
warn_report ( " ivshmem is deprecated, please use ivshmem-plain "
" or ivshmem-doorbell instead " ) ;
}
if ( qemu_chr_fe_backend_connected ( & s - > server_chr ) + ! ! s - > shmobj ! = 1 ) {
error_setg ( errp , " You must specify either 'shm' or 'chardev' " ) ;
return ;
}
if ( s - > sizearg = = NULL ) {
s - > legacy_size = 4 * MiB ; /* 4 MB default */
} else {
int ret ;
uint64_t size ;
ret = qemu_strtosz_MiB ( s - > sizearg , NULL , & size ) ;
if ( ret < 0 | | ( size_t ) size ! = size | | ! is_power_of_2 ( size ) ) {
error_setg ( errp , " Invalid size %s " , s - > sizearg ) ;
return ;
}
s - > legacy_size = size ;
}
/* check that role is reasonable */
if ( s - > role ) {
if ( strncmp ( s - > role , " peer " , 5 ) = = 0 ) {
s - > master = ON_OFF_AUTO_OFF ;
} else if ( strncmp ( s - > role , " master " , 7 ) = = 0 ) {
s - > master = ON_OFF_AUTO_ON ;
} else {
error_setg ( errp , " 'role' must be 'peer' or 'master' " ) ;
return ;
}
} else {
s - > master = ON_OFF_AUTO_AUTO ;
}
if ( s - > shmobj ) {
desugar_shm ( s ) ;
}
/*
* Note : we don ' t use INTx with IVSHMEM_MSI at all , so this is a
* bald - faced lie then . But it ' s a backwards compatible lie .
*/
pci_config_set_interrupt_pin ( dev - > config , 1 ) ;
ivshmem_common_realize ( dev , errp ) ;
}
static void ivshmem_class_init ( ObjectClass * klass , void * data )
{
DeviceClass * dc = DEVICE_CLASS ( klass ) ;
PCIDeviceClass * k = PCI_DEVICE_CLASS ( klass ) ;
k - > realize = ivshmem_realize ;
k - > revision = 0 ;
dc - > desc = " Inter-VM shared memory (legacy) " ;
dc - > props = ivshmem_properties ;
dc - > vmsd = & ivshmem_vmsd ;
}
static const TypeInfo ivshmem_info = {
. name = TYPE_IVSHMEM ,
. parent = TYPE_IVSHMEM_COMMON ,
. instance_size = sizeof ( IVShmemState ) ,
. class_init = ivshmem_class_init ,
} ;
static void ivshmem_register_types ( void )
{
type_register_static ( & ivshmem_common_info ) ;
type_register_static ( & ivshmem_plain_info ) ;
type_register_static ( & ivshmem_doorbell_info ) ;
type_register_static ( & ivshmem_info ) ;
}
type_init ( ivshmem_register_types )