@ -192,7 +192,6 @@ static void vhost_kernel_iotlb_read(void *opaque)
ssize_t len ;
while ( ( len = read ( ( uintptr_t ) dev - > opaque , & msg , sizeof msg ) ) > 0 ) {
struct vhost_iotlb_msg * imsg = & msg . iotlb ;
if ( len < sizeof msg ) {
error_report ( " Wrong vhost message len: %d " , ( int ) len ) ;
break ;
@ -201,70 +200,21 @@ static void vhost_kernel_iotlb_read(void *opaque)
error_report ( " Unknown vhost iotlb message type " ) ;
break ;
}
switch ( imsg - > type ) {
case VHOST_IOTLB_MISS :
vhost_device_iotlb_miss ( dev , imsg - > iova ,
imsg - > perm ! = VHOST_ACCESS_RO ) ;
break ;
case VHOST_IOTLB_UPDATE :
case VHOST_IOTLB_INVALIDATE :
error_report ( " Unexpected IOTLB message type " ) ;
break ;
case VHOST_IOTLB_ACCESS_FAIL :
/* FIXME: report device iotlb error */
break ;
default :
break ;
}
}
}
static int vhost_kernel_update_device_iotlb ( struct vhost_dev * dev ,
uint64_t iova , uint64_t uaddr ,
uint64_t len ,
IOMMUAccessFlags perm )
{
struct vhost_msg msg ;
msg . type = VHOST_IOTLB_MSG ;
msg . iotlb . iova = iova ;
msg . iotlb . uaddr = uaddr ;
msg . iotlb . size = len ;
msg . iotlb . type = VHOST_IOTLB_UPDATE ;
switch ( perm ) {
case IOMMU_RO :
msg . iotlb . perm = VHOST_ACCESS_RO ;
break ;
case IOMMU_WO :
msg . iotlb . perm = VHOST_ACCESS_WO ;
break ;
case IOMMU_RW :
msg . iotlb . perm = VHOST_ACCESS_RW ;
break ;
default :
g_assert_not_reached ( ) ;
}
if ( write ( ( uintptr_t ) dev - > opaque , & msg , sizeof msg ) ! = sizeof msg ) {
error_report ( " Fail to update device iotlb " ) ;
return - EFAULT ;
vhost_backend_handle_iotlb_msg ( dev , & msg . iotlb ) ;
}
return 0 ;
}
static int vhost_kernel_invalidate_device_iotlb ( struct vhost_dev * dev ,
uint64_t iova , uint64_t len )
static int vhost_kernel_send_device_iotlb_msg ( struct vhost_dev * dev ,
struct vhost_iotlb_msg * imsg )
{
struct vhost_msg msg ;
msg . type = VHOST_IOTLB_MSG ;
msg . iotlb . iova = iova ;
msg . iotlb . size = len ;
msg . iotlb . type = VHOST_IOTLB_INVALIDATE ;
msg . iotlb = * imsg ;
if ( write ( ( uintptr_t ) dev - > opaque , & msg , sizeof msg ) ! = sizeof msg ) {
error_report ( " Fail to invali date device iotlb " ) ;
error_report ( " Fail to update device iotlb " ) ;
return - EFAULT ;
}
@ -311,8 +261,7 @@ static const VhostOps kernel_ops = {
. vhost_vsock_set_running = vhost_kernel_vsock_set_running ,
# endif /* CONFIG_VHOST_VSOCK */
. vhost_set_iotlb_callback = vhost_kernel_set_iotlb_callback ,
. vhost_update_device_iotlb = vhost_kernel_update_device_iotlb ,
. vhost_invalidate_device_iotlb = vhost_kernel_invalidate_device_iotlb ,
. vhost_send_device_iotlb_msg = vhost_kernel_send_device_iotlb_msg ,
} ;
int vhost_set_backend_type ( struct vhost_dev * dev , VhostBackendType backend_type )
@ -333,3 +282,70 @@ int vhost_set_backend_type(struct vhost_dev *dev, VhostBackendType backend_type)
return r ;
}
int vhost_backend_update_device_iotlb ( struct vhost_dev * dev ,
uint64_t iova , uint64_t uaddr ,
uint64_t len ,
IOMMUAccessFlags perm )
{
struct vhost_iotlb_msg imsg ;
imsg . iova = iova ;
imsg . uaddr = uaddr ;
imsg . size = len ;
imsg . type = VHOST_IOTLB_UPDATE ;
switch ( perm ) {
case IOMMU_RO :
imsg . perm = VHOST_ACCESS_RO ;
break ;
case IOMMU_WO :
imsg . perm = VHOST_ACCESS_WO ;
break ;
case IOMMU_RW :
imsg . perm = VHOST_ACCESS_RW ;
break ;
default :
return - EINVAL ;
}
return dev - > vhost_ops - > vhost_send_device_iotlb_msg ( dev , & imsg ) ;
}
int vhost_backend_invalidate_device_iotlb ( struct vhost_dev * dev ,
uint64_t iova , uint64_t len )
{
struct vhost_iotlb_msg imsg ;
imsg . iova = iova ;
imsg . size = len ;
imsg . type = VHOST_IOTLB_INVALIDATE ;
return dev - > vhost_ops - > vhost_send_device_iotlb_msg ( dev , & imsg ) ;
}
int vhost_backend_handle_iotlb_msg ( struct vhost_dev * dev ,
struct vhost_iotlb_msg * imsg )
{
int ret = 0 ;
switch ( imsg - > type ) {
case VHOST_IOTLB_MISS :
ret = vhost_device_iotlb_miss ( dev , imsg - > iova ,
imsg - > perm ! = VHOST_ACCESS_RO ) ;
break ;
case VHOST_IOTLB_ACCESS_FAIL :
/* FIXME: report device iotlb error */
error_report ( " Access failure IOTLB message type not supported " ) ;
ret = - ENOTSUP ;
break ;
case VHOST_IOTLB_UPDATE :
case VHOST_IOTLB_INVALIDATE :
default :
error_report ( " Unexpected IOTLB message type " ) ;
ret = - EINVAL ;
break ;
}
return ret ;
}