@ -319,6 +319,13 @@ static void vhost_vdpa_get_iova_range(struct vhost_vdpa *v)
v - > iova_range . last ) ;
}
static bool vhost_vdpa_one_time_request ( struct vhost_dev * dev )
{
struct vhost_vdpa * v = dev - > opaque ;
return v - > index ! = 0 ;
}
static int vhost_vdpa_init ( struct vhost_dev * dev , void * opaque , Error * * errp )
{
struct vhost_vdpa * v ;
@ -332,6 +339,11 @@ static int vhost_vdpa_init(struct vhost_dev *dev, void *opaque, Error **errp)
v - > msg_type = VHOST_IOTLB_MSG_V2 ;
vhost_vdpa_get_iova_range ( v ) ;
if ( vhost_vdpa_one_time_request ( dev ) ) {
return 0 ;
}
vhost_vdpa_add_status ( dev , VIRTIO_CONFIG_S_ACKNOWLEDGE |
VIRTIO_CONFIG_S_DRIVER ) ;
@ -442,6 +454,10 @@ static int vhost_vdpa_memslots_limit(struct vhost_dev *dev)
static int vhost_vdpa_set_mem_table ( struct vhost_dev * dev ,
struct vhost_memory * mem )
{
if ( vhost_vdpa_one_time_request ( dev ) ) {
return 0 ;
}
trace_vhost_vdpa_set_mem_table ( dev , mem - > nregions , mem - > padding ) ;
if ( trace_event_get_state_backends ( TRACE_VHOST_VDPA_SET_MEM_TABLE ) & &
trace_event_get_state_backends ( TRACE_VHOST_VDPA_DUMP_REGIONS ) ) {
@ -465,6 +481,11 @@ static int vhost_vdpa_set_features(struct vhost_dev *dev,
uint64_t features )
{
int ret ;
if ( vhost_vdpa_one_time_request ( dev ) ) {
return 0 ;
}
trace_vhost_vdpa_set_features ( dev , features ) ;
ret = vhost_vdpa_call ( dev , VHOST_SET_FEATURES , & features ) ;
uint8_t status = 0 ;
@ -489,9 +510,12 @@ static int vhost_vdpa_set_backend_cap(struct vhost_dev *dev)
}
features & = f ;
r = vhost_vdpa_call ( dev , VHOST_SET_BACKEND_FEATURES , & features ) ;
if ( r ) {
return - EFAULT ;
if ( vhost_vdpa_one_time_request ( dev ) ) {
r = vhost_vdpa_call ( dev , VHOST_SET_BACKEND_FEATURES , & features ) ;
if ( r ) {
return - EFAULT ;
}
}
dev - > backend_cap = features ;
@ -600,11 +624,21 @@ static int vhost_vdpa_dev_start(struct vhost_dev *dev, bool started)
{
struct vhost_vdpa * v = dev - > opaque ;
trace_vhost_vdpa_dev_start ( dev , started ) ;
if ( started ) {
uint8_t status = 0 ;
memory_listener_register ( & v - > listener , & address_space_memory ) ;
vhost_vdpa_host_notifiers_init ( dev ) ;
vhost_vdpa_set_vring_ready ( dev ) ;
} else {
vhost_vdpa_host_notifiers_uninit ( dev , dev - > nvqs ) ;
}
if ( vhost_vdpa_one_time_request ( dev ) ) {
return 0 ;
}
if ( started ) {
uint8_t status = 0 ;
memory_listener_register ( & v - > listener , & address_space_memory ) ;
vhost_vdpa_add_status ( dev , VIRTIO_CONFIG_S_DRIVER_OK ) ;
vhost_vdpa_call ( dev , VHOST_VDPA_GET_STATUS , & status ) ;
@ -613,7 +647,6 @@ static int vhost_vdpa_dev_start(struct vhost_dev *dev, bool started)
vhost_vdpa_reset_device ( dev ) ;
vhost_vdpa_add_status ( dev , VIRTIO_CONFIG_S_ACKNOWLEDGE |
VIRTIO_CONFIG_S_DRIVER ) ;
vhost_vdpa_host_notifiers_uninit ( dev , dev - > nvqs ) ;
memory_listener_unregister ( & v - > listener ) ;
return 0 ;
@ -623,6 +656,10 @@ static int vhost_vdpa_dev_start(struct vhost_dev *dev, bool started)
static int vhost_vdpa_set_log_base ( struct vhost_dev * dev , uint64_t base ,
struct vhost_log * log )
{
if ( vhost_vdpa_one_time_request ( dev ) ) {
return 0 ;
}
trace_vhost_vdpa_set_log_base ( dev , base , log - > size , log - > refcnt , log - > fd ,
log - > log ) ;
return vhost_vdpa_call ( dev , VHOST_SET_LOG_BASE , & base ) ;
@ -688,6 +725,10 @@ static int vhost_vdpa_get_features(struct vhost_dev *dev,
static int vhost_vdpa_set_owner ( struct vhost_dev * dev )
{
if ( vhost_vdpa_one_time_request ( dev ) ) {
return 0 ;
}
trace_vhost_vdpa_set_owner ( dev ) ;
return vhost_vdpa_call ( dev , VHOST_SET_OWNER , NULL ) ;
}