[dpdk-dev,12/21] vhost: introduce guest IOVA to backend VA helper
Checks
Commit Message
This patch introduces vhost_iova_to_vva() function to translate
guest's IO virtual addresses to backend's virtual addresses.
When IOMMU is enabled, the IOTLB cache is queried to get the
translation. If missing from the IOTLB cache, an IOTLB_MISS request
is sent to Qemu, and IOTLB cache is queried again on IOTLB event
notification.
When IOMMU is disabled, the passed address is a guest's physical
address, so the legacy rte_vhost_gpa_to_vva() API is used.
Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
---
lib/librte_vhost/vhost.c | 27 +++++++++++++++++++++++++++
lib/librte_vhost/vhost.h | 3 +++
2 files changed, 30 insertions(+)
Comments
On Thu, Aug 31, 2017 at 11:50:14AM +0200, Maxime Coquelin wrote:
> This patch introduces vhost_iova_to_vva() function to translate
> guest's IO virtual addresses to backend's virtual addresses.
>
> When IOMMU is enabled, the IOTLB cache is queried to get the
> translation. If missing from the IOTLB cache, an IOTLB_MISS request
> is sent to Qemu, and IOTLB cache is queried again on IOTLB event
> notification.
>
> When IOMMU is disabled, the passed address is a guest's physical
> address, so the legacy rte_vhost_gpa_to_vva() API is used.
>
> Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
> ---
> lib/librte_vhost/vhost.c | 27 +++++++++++++++++++++++++++
> lib/librte_vhost/vhost.h | 3 +++
> 2 files changed, 30 insertions(+)
>
> diff --git a/lib/librte_vhost/vhost.c b/lib/librte_vhost/vhost.c
> index bae98b02d..0e8c0386a 100644
> --- a/lib/librte_vhost/vhost.c
> +++ b/lib/librte_vhost/vhost.c
> @@ -48,9 +48,11 @@
> #include <rte_malloc.h>
> #include <rte_rwlock.h>
> #include <rte_vhost.h>
> +#include <rte_rwlock.h>
This header isn't needed.
Best regards,
Tiwei Bie
On 09/05/2017 06:14 AM, Tiwei Bie wrote:
> On Thu, Aug 31, 2017 at 11:50:14AM +0200, Maxime Coquelin wrote:
>> This patch introduces vhost_iova_to_vva() function to translate
>> guest's IO virtual addresses to backend's virtual addresses.
>>
>> When IOMMU is enabled, the IOTLB cache is queried to get the
>> translation. If missing from the IOTLB cache, an IOTLB_MISS request
>> is sent to Qemu, and IOTLB cache is queried again on IOTLB event
>> notification.
>>
>> When IOMMU is disabled, the passed address is a guest's physical
>> address, so the legacy rte_vhost_gpa_to_vva() API is used.
>>
>> Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
>> ---
>> lib/librte_vhost/vhost.c | 27 +++++++++++++++++++++++++++
>> lib/librte_vhost/vhost.h | 3 +++
>> 2 files changed, 30 insertions(+)
>>
>> diff --git a/lib/librte_vhost/vhost.c b/lib/librte_vhost/vhost.c
>> index bae98b02d..0e8c0386a 100644
>> --- a/lib/librte_vhost/vhost.c
>> +++ b/lib/librte_vhost/vhost.c
>> @@ -48,9 +48,11 @@
>> #include <rte_malloc.h>
>> #include <rte_rwlock.h>
>> #include <rte_vhost.h>
>> +#include <rte_rwlock.h>
>
> This header isn't needed.
Right, I'll remove it.
Thanks,
Maxime
>
> Best regards,
> Tiwei Bie
>
@@ -48,9 +48,11 @@
#include <rte_malloc.h>
#include <rte_rwlock.h>
#include <rte_vhost.h>
+#include <rte_rwlock.h>
#include "iotlb.h"
#include "vhost.h"
+#include "vhost_user.h"
struct vhost_device {
struct virtio_net *dev;
@@ -60,6 +62,31 @@ struct vhost_device {
/* Declared as static so that .lock is initialized */
static struct vhost_device vhost_devices[MAX_VHOST_DEVICE];
+uint64_t vhost_iova_to_vva(struct virtio_net *dev, struct vhost_virtqueue *vq,
+ uint64_t iova, uint64_t size, uint8_t perm)
+{
+ uint64_t vva, tmp_size;
+
+ if (unlikely(!size))
+ return 0;
+
+ if (!(dev->features & (1ULL << VIRTIO_F_IOMMU_PLATFORM)))
+ return rte_vhost_gpa_to_vva(dev->mem, iova);
+
+ tmp_size = size;
+
+ vva = vhost_user_iotlb_cache_find(vq, iova, &tmp_size, perm);
+ if (tmp_size == size)
+ return vva;
+
+ if (!vhost_user_iotlb_pending_miss(vq, iova + tmp_size, perm)) {
+ vhost_user_iotlb_pending_insert(vq, iova + tmp_size, perm);
+ vhost_user_iotlb_miss(dev, iova + tmp_size, perm);
+ }
+
+ return 0;
+}
+
static inline struct virtio_net *
__get_device(int vid)
{
@@ -352,4 +352,7 @@ struct vhost_device_ops const *vhost_driver_callback_get(const char *path);
*/
void vhost_backend_cleanup(struct virtio_net *dev);
+uint64_t vhost_iova_to_vva(struct virtio_net *dev, struct vhost_virtqueue *vq,
+ uint64_t iova, uint64_t size, uint8_t perm);
+
#endif /* _VHOST_NET_CDEV_H_ */