diff mbox series

[v4,2/5] drm/virtio: Add a helper to map and note the dma addrs and lengths

Message ID 20241125073313.3361612-3-vivek.kasireddy@intel.com (mailing list archive)
State New
Headers show
Series drm/virtio: Import scanout buffers from other devices | expand

Commit Message

Kasireddy, Vivek Nov. 25, 2024, 7:31 a.m. UTC
This helper would be used when first initializing the object as
part of import and also when updating the plane where we need to
ensure that the imported object's backing is valid.

Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Dmitry Osipenko <dmitry.osipenko@collabora.com>
Cc: Rob Clark <robdclark@gmail.com>
Cc: Gurchetan Singh <gurchetansingh@chromium.org>
Cc: Chia-I Wu <olvaffe@gmail.com>
Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
---
 drivers/gpu/drm/virtio/virtgpu_drv.h   |  5 +++
 drivers/gpu/drm/virtio/virtgpu_prime.c | 43 ++++++++++++++++++++++++++
 2 files changed, 48 insertions(+)

Comments

Dmitry Osipenko Nov. 25, 2024, 11:41 a.m. UTC | #1
On 11/25/24 10:31, Vivek Kasireddy wrote:
> +int virtgpu_dma_buf_import_sgt(struct virtio_gpu_mem_entry **ents,
> +			       unsigned int *nents,
> +			       struct virtio_gpu_object *bo,
> +			       struct dma_buf_attachment *attach)
> +{
> +	struct scatterlist *sl;
> +	struct sg_table *sgt;
> +	long i, ret;
> +
> +	dma_resv_assert_held(attach->dmabuf->resv);
> +
> +	ret = dma_resv_wait_timeout(attach->dmabuf->resv,
> +				    DMA_RESV_USAGE_KERNEL,
> +				    false, MAX_SCHEDULE_TIMEOUT);
> +	if (ret <= 0)
> +		return ret < 0 ? ret : -ETIMEDOUT;
> +
> +	sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL);
> +	if (IS_ERR(sgt))
> +		return PTR_ERR(sgt);
> +
> +	*ents = kvmalloc_array(sgt->nents,
> +			       sizeof(struct virtio_gpu_mem_entry),
> +			       GFP_KERNEL);
> +	if (!(*ents)) {
> +		dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL);
> +		return -ENOMEM;
> +	}
> +
> +	*nents = sgt->nents;
> +	for_each_sgtable_dma_sg(sgt, sl, i) {
> +		(*ents)[i].addr = cpu_to_le64(sg_dma_address(sl));
> +		(*ents)[i].length = cpu_to_le32(sg_dma_len(sl));
> +		(*ents)[i].padding = 0;
> +	}
> +
> +	bo->sgt = sgt;
> +	bo->detached = false;

This bo->detached=false was missing in v3 and it fixes the flickering
problem, as expected. \o/

The DG2+virtio-gpu still don't work for me in guest using both i915 and
Xe drivers like before:

Invalid read at addr 0x7200005014, size 1, region '(null)', reason: rejected
Invalid write at addr 0x7200005014, size 1, region '(null)', reason:
rejected
Invalid write at addr 0x7200005000, size 4, region '(null)', reason:
rejected
Invalid read at addr 0x7200005004, size 4, region '(null)', reason: rejected
Invalid write at addr 0x7200005000, size 4, region '(null)', reason:
rejected
Invalid read at addr 0x7200005004, size 4, region '(null)', reason: rejected
[    0.876189] virtio_gpu virtio1: virtio: device uses modern interface
but does not have VIRTIO_F_VERSION_1
Invalid read at addr 0x7200005014, size 1, region '(null)', reason: rejected
Invalid write at addr 0x7200005014, size 1, region '(null)', reason:
rejected
[    0.876597] virtio_gpu virtio1: probe with driver virtio_gpu failed
with error -22

Wondering if it could be a problem with my guest kernel config. I
attached my config to the email, please try to boot guest with my config
if you'll have time.

I'm almost ready to apply the patches after a small code improvement.
Let's move bo->detached=false into virtio_gpu_object_attach() and
replace bo->detached with bo->attached. I can apply this change while
merging patches, otherwise please make v5 if you agree with the suggestion:

diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h
b/drivers/gpu/drm/virtio/virtgpu_drv.h
index ad6960aa464e..8328107edf78 100644
--- a/drivers/gpu/drm/virtio/virtgpu_drv.h
+++ b/drivers/gpu/drm/virtio/virtgpu_drv.h
@@ -93,7 +93,7 @@ struct virtio_gpu_object {
 	uint32_t hw_res_handle;
 	bool dumb;
 	bool created;
-	bool detached;
+	bool attached;
 	bool host3d_blob, guest_blob;
 	uint32_t blob_mem, blob_flags;

diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c
b/drivers/gpu/drm/virtio/virtgpu_object.c
index 2b19bb8c6ec3..5517cff8715c 100644
--- a/drivers/gpu/drm/virtio/virtgpu_object.c
+++ b/drivers/gpu/drm/virtio/virtgpu_object.c
@@ -105,7 +105,7 @@ int virtio_gpu_detach_object_fenced(struct
virtio_gpu_object *bo)
 	struct virtio_gpu_device *vgdev = bo->base.base.dev->dev_private;
 	struct virtio_gpu_fence *fence;

-	if (bo->detached)
+	if (!bo->attached)
 		return 0;

 	fence = virtio_gpu_fence_alloc(vgdev, vgdev->fence_drv.context, 0);
@@ -118,8 +118,6 @@ int virtio_gpu_detach_object_fenced(struct
virtio_gpu_object *bo)
 	dma_fence_wait(&fence->f, false);
 	dma_fence_put(&fence->f);

-	bo->detached = true;
-
 	return 0;
 }

diff --git a/drivers/gpu/drm/virtio/virtgpu_prime.c
b/drivers/gpu/drm/virtio/virtgpu_prime.c
index 5031b800c521..3c4ea592e23c 100644
--- a/drivers/gpu/drm/virtio/virtgpu_prime.c
+++ b/drivers/gpu/drm/virtio/virtgpu_prime.c
@@ -181,7 +181,6 @@ int virtgpu_dma_buf_import_sgt(struct
virtio_gpu_mem_entry **ents,
 	}

 	bo->sgt = sgt;
-	bo->detached = false;
 	return 0;
 }

diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c
b/drivers/gpu/drm/virtio/virtgpu_vq.c
index b8b296b912a1..ad91624df42d 100644
--- a/drivers/gpu/drm/virtio/virtgpu_vq.c
+++ b/drivers/gpu/drm/virtio/virtgpu_vq.c
@@ -1120,16 +1120,26 @@ void virtio_gpu_object_attach(struct
virtio_gpu_device *vgdev,
 			      struct virtio_gpu_mem_entry *ents,
 			      unsigned int nents)
 {
+	if (obj->attached)
+		return;
+
 	virtio_gpu_cmd_resource_attach_backing(vgdev, obj->hw_res_handle,
 					       ents, nents, NULL);
+
+	obj->attached = true;
 }

 void virtio_gpu_object_detach(struct virtio_gpu_device *vgdev,
 			      struct virtio_gpu_object *obj,
 			      struct virtio_gpu_fence *fence)
 {
+	if (!obj->attached)
+		return;
+
 	virtio_gpu_cmd_resource_detach_backing(vgdev, obj->hw_res_handle,
 					       fence);
+
+	obj->attached = false;
 }

 void virtio_gpu_cursor_ping(struct virtio_gpu_device *vgdev,
Kasireddy, Vivek Nov. 26, 2024, 3:16 a.m. UTC | #2
Hi Dmitry,

> Subject: Re: [PATCH v4 2/5] drm/virtio: Add a helper to map and note the
> dma addrs and lengths
> 
> > +int virtgpu_dma_buf_import_sgt(struct virtio_gpu_mem_entry **ents,
> > +			       unsigned int *nents,
> > +			       struct virtio_gpu_object *bo,
> > +			       struct dma_buf_attachment *attach)
> > +{
> > +	struct scatterlist *sl;
> > +	struct sg_table *sgt;
> > +	long i, ret;
> > +
> > +	dma_resv_assert_held(attach->dmabuf->resv);
> > +
> > +	ret = dma_resv_wait_timeout(attach->dmabuf->resv,
> > +				    DMA_RESV_USAGE_KERNEL,
> > +				    false, MAX_SCHEDULE_TIMEOUT);
> > +	if (ret <= 0)
> > +		return ret < 0 ? ret : -ETIMEDOUT;
> > +
> > +	sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL);
> > +	if (IS_ERR(sgt))
> > +		return PTR_ERR(sgt);
> > +
> > +	*ents = kvmalloc_array(sgt->nents,
> > +			       sizeof(struct virtio_gpu_mem_entry),
> > +			       GFP_KERNEL);
> > +	if (!(*ents)) {
> > +		dma_buf_unmap_attachment(attach, sgt,
> DMA_BIDIRECTIONAL);
> > +		return -ENOMEM;
> > +	}
> > +
> > +	*nents = sgt->nents;
> > +	for_each_sgtable_dma_sg(sgt, sl, i) {
> > +		(*ents)[i].addr = cpu_to_le64(sg_dma_address(sl));
> > +		(*ents)[i].length = cpu_to_le32(sg_dma_len(sl));
> > +		(*ents)[i].padding = 0;
> > +	}
> > +
> > +	bo->sgt = sgt;
> > +	bo->detached = false;
> 
> This bo->detached=false was missing in v3 and it fixes the flickering
> problem, as expected. \o/
> 
> The DG2+virtio-gpu still don't work for me in guest using both i915 and
> Xe drivers like before:
> 
> Invalid read at addr 0x7200005014, size 1, region '(null)', reason: rejected
> Invalid write at addr 0x7200005014, size 1, region '(null)', reason:
> rejected
> Invalid write at addr 0x7200005000, size 4, region '(null)', reason:
> rejected
> Invalid read at addr 0x7200005004, size 4, region '(null)', reason: rejected
> Invalid write at addr 0x7200005000, size 4, region '(null)', reason:
> rejected
> Invalid read at addr 0x7200005004, size 4, region '(null)', reason: rejected
> [    0.876189] virtio_gpu virtio1: virtio: device uses modern interface
> but does not have VIRTIO_F_VERSION_1
> Invalid read at addr 0x7200005014, size 1, region '(null)', reason: rejected
> Invalid write at addr 0x7200005014, size 1, region '(null)', reason:
> rejected
> [    0.876597] virtio_gpu virtio1: probe with driver virtio_gpu failed
> with error -22
> 
> Wondering if it could be a problem with my guest kernel config. I
> attached my config to the email, please try to boot guest with my config
> if you'll have time.
Sure, let me try to test with your config. Could you also please share your
Qemu launch parameters?

> 
> I'm almost ready to apply the patches after a small code improvement.
> Let's move bo->detached=false into virtio_gpu_object_attach() and
> replace bo->detached with bo->attached. I can apply this change while
> merging patches, otherwise please make v5 if you agree with the suggestion:
I definitely agree with your suggestion; attached is much more intuitive than
detached. I'll include the following changes (along with your other suggestions) in v5.

Thanks,
Vivek

> 
> diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h
> b/drivers/gpu/drm/virtio/virtgpu_drv.h
> index ad6960aa464e..8328107edf78 100644
> --- a/drivers/gpu/drm/virtio/virtgpu_drv.h
> +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h
> @@ -93,7 +93,7 @@ struct virtio_gpu_object {
>  	uint32_t hw_res_handle;
>  	bool dumb;
>  	bool created;
> -	bool detached;
> +	bool attached;
>  	bool host3d_blob, guest_blob;
>  	uint32_t blob_mem, blob_flags;
> 
> diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c
> b/drivers/gpu/drm/virtio/virtgpu_object.c
> index 2b19bb8c6ec3..5517cff8715c 100644
> --- a/drivers/gpu/drm/virtio/virtgpu_object.c
> +++ b/drivers/gpu/drm/virtio/virtgpu_object.c
> @@ -105,7 +105,7 @@ int virtio_gpu_detach_object_fenced(struct
> virtio_gpu_object *bo)
>  	struct virtio_gpu_device *vgdev = bo->base.base.dev->dev_private;
>  	struct virtio_gpu_fence *fence;
> 
> -	if (bo->detached)
> +	if (!bo->attached)
>  		return 0;
> 
>  	fence = virtio_gpu_fence_alloc(vgdev, vgdev->fence_drv.context, 0);
> @@ -118,8 +118,6 @@ int virtio_gpu_detach_object_fenced(struct
> virtio_gpu_object *bo)
>  	dma_fence_wait(&fence->f, false);
>  	dma_fence_put(&fence->f);
> 
> -	bo->detached = true;
> -
>  	return 0;
>  }
> 
> diff --git a/drivers/gpu/drm/virtio/virtgpu_prime.c
> b/drivers/gpu/drm/virtio/virtgpu_prime.c
> index 5031b800c521..3c4ea592e23c 100644
> --- a/drivers/gpu/drm/virtio/virtgpu_prime.c
> +++ b/drivers/gpu/drm/virtio/virtgpu_prime.c
> @@ -181,7 +181,6 @@ int virtgpu_dma_buf_import_sgt(struct
> virtio_gpu_mem_entry **ents,
>  	}
> 
>  	bo->sgt = sgt;
> -	bo->detached = false;
>  	return 0;
>  }
> 
> diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c
> b/drivers/gpu/drm/virtio/virtgpu_vq.c
> index b8b296b912a1..ad91624df42d 100644
> --- a/drivers/gpu/drm/virtio/virtgpu_vq.c
> +++ b/drivers/gpu/drm/virtio/virtgpu_vq.c
> @@ -1120,16 +1120,26 @@ void virtio_gpu_object_attach(struct
> virtio_gpu_device *vgdev,
>  			      struct virtio_gpu_mem_entry *ents,
>  			      unsigned int nents)
>  {
> +	if (obj->attached)
> +		return;
> +
>  	virtio_gpu_cmd_resource_attach_backing(vgdev, obj-
> >hw_res_handle,
>  					       ents, nents, NULL);
> +
> +	obj->attached = true;
>  }
> 
>  void virtio_gpu_object_detach(struct virtio_gpu_device *vgdev,
>  			      struct virtio_gpu_object *obj,
>  			      struct virtio_gpu_fence *fence)
>  {
> +	if (!obj->attached)
> +		return;
> +
>  	virtio_gpu_cmd_resource_detach_backing(vgdev, obj-
> >hw_res_handle,
>  					       fence);
> +
> +	obj->attached = false;
>  }
> 
>  void virtio_gpu_cursor_ping(struct virtio_gpu_device *vgdev,
> 
> 
> 
> --
> Best regards,
> Dmitry
Dmitry Osipenko Nov. 26, 2024, 9:39 a.m. UTC | #3
On 11/26/24 06:16, Kasireddy, Vivek wrote:
>> Wondering if it could be a problem with my guest kernel config. I
>> attached my config to the email, please try to boot guest with my config
>> if you'll have time.
> Sure, let me try to test with your config. Could you also please share your
> Qemu launch parameters?

Recap of the DG2 problem:

The virtio-gpu PCIe accesses in guest are becoming rejected as soon as Intel driver (either i915 or Xe) is probed. My theory is that Intel driver causes PCIe config change that indirectly breaks virtio-gpu PCIe. This problem isn't observed by swapping DG2 card with AMD card. AMD setup works perfectly fine on the same machine with GPU card plugged into the same PCIe slot as DG2 was on host.

$ lspci | grep DG2
0c:00.0 VGA compatible controller: Intel Corporation DG2 [Arc A750] (rev 08)
0d:00.0 Audio device: Intel Corporation DG2 Audio Controller

qemu-system-x86_64 \
-kernel linux-guest/arch/x86_64/boot/bzImage \
-append "console=ttyS0 nokaslr root=/dev/sda init=/lib/systemd/systemd vt.global_cursor_default=0 log_buf_len=16M" \
-netdev user,id=u1,hostfwd=tcp::10022-:22 \
-device virtio-net-pci,netdev=u1 \
-serial mon:stdio -m 24G \
--enable-kvm \
-cpu host,host-phys-bits=on,host-phys-bits-limit=39 \
-device virtio-vga,max_outputs=1,xres=1920,yres=1080,blob=true \
-device virtio-tablet-pci \
-device virtio-balloon \
-device virtio-keyboard-pci \
-display gtk,gl=on \
-smp 16 \
-machine q35,accel=kvm,kernel-irqchip=split,memory-backend=mem1 \
-object memory-backend-memfd,id=mem1,size=24G \
-d guest_errors \
-drive file=disk.img,format=raw \
-device pcie-root-port,id=pcie.1,bus=pcie.0,addr=1c.0,slot=1,chassis=1,multifunction=on \
-device vfio-pci,host=0c:00.0,bus=pcie.1,addr=00.0,x-vga=on,multifunction=on \
-device vfio-pci,host=0d:00.0,bus=pcie.1,addr=00.1

Guest kernel boot log is attached to this email.
Kasireddy, Vivek Nov. 27, 2024, 6:20 a.m. UTC | #4
Hi Dmitry,

> >> Wondering if it could be a problem with my guest kernel config. I
> >> attached my config to the email, please try to boot guest with my config
> >> if you'll have time.
> > Sure, let me try to test with your config. Could you also please share your
> > Qemu launch parameters?
> 
> Recap of the DG2 problem:
> 
> The virtio-gpu PCIe accesses in guest are becoming rejected as soon as Intel
> driver (either i915 or Xe) is probed. My theory is that Intel driver causes PCIe
> config change that indirectly breaks virtio-gpu PCIe. This problem isn't
> observed by swapping DG2 card with AMD card. AMD setup works perfectly
> fine on the same machine with GPU card plugged into the same PCIe slot as
> DG2 was on host.
> 
> $ lspci | grep DG2
> 0c:00.0 VGA compatible controller: Intel Corporation DG2 [Arc A750] (rev 08)
> 0d:00.0 Audio device: Intel Corporation DG2 Audio Controller
Looks like the GPU and the audio devices are on different buses (I see the same
in my setup as well) but you are making them appear as different functions of
the same device in Guest VM:
01:00.0 VGA compatible controller [0300]: Intel Corporation DG2 [Intel Graphics] [8086:56bd] (rev 05) (prog-if 00 [VGA controller])
        Subsystem: Intel Corporation Device [8086:1211]
        Physical Slot: 0
        Kernel driver in use: i915
        Kernel modules: i915, xe
01:00.1 Audio device [0403]: Intel Corporation DG2 Audio Controller [8086:4f92]
        Subsystem: Intel Corporation Device [8086:1211]
        Physical Slot: 0

I am not sure if this a valid config or not. Regardless, the presence of i915 preventing
virtio-gpu from probing correctly in this situation is indeed a problem that I am able
to see in my setup as well (with your Qemu parameters, especially the pcie-port ones).
I'll definitely take a look at this issue next week. 

> 
> qemu-system-x86_64 \
> -kernel linux-guest/arch/x86_64/boot/bzImage \
> -append "console=ttyS0 nokaslr root=/dev/sda init=/lib/systemd/systemd
> vt.global_cursor_default=0 log_buf_len=16M" \
> -netdev user,id=u1,hostfwd=tcp::10022-:22 \
> -device virtio-net-pci,netdev=u1 \
> -serial mon:stdio -m 24G \
> --enable-kvm \
> -cpu host,host-phys-bits=on,host-phys-bits-limit=39 \
> -device virtio-vga,max_outputs=1,xres=1920,yres=1080,blob=true \
> -device virtio-tablet-pci \
> -device virtio-balloon \
> -device virtio-keyboard-pci \
> -display gtk,gl=on \
> -smp 16 \
> -machine q35,accel=kvm,kernel-irqchip=split,memory-backend=mem1 \
> -object memory-backend-memfd,id=mem1,size=24G \
> -d guest_errors \
> -drive file=disk.img,format=raw \
> -device pcie-root-
> port,id=pcie.1,bus=pcie.0,addr=1c.0,slot=1,chassis=1,multifunction=on \
> -device vfio-pci,host=0c:00.0,bus=pcie.1,addr=00.0,x-
> vga=on,multifunction=on \
> -device vfio-pci,host=0d:00.0,bus=pcie.1,addr=00.1
Passthrough'ng the devices directly instead of creating a new pcie root port
enables virtio-gpu to work correctly in my setup. That is, having just
-device vfio-pci,host=0c:00.0,x-vga=on -device vfio-pci,host=0d:00.0

instead of the last few lines in your Qemu parameters list makes virtio-gpu
to work as expected. Could you please try it out and let me know if it works?

Thanks,
Vivek

> 
> Guest kernel boot log is attached to this email.
> 
> --
> Best regards,
> Dmitry
Dmitry Osipenko Nov. 27, 2024, 11:49 a.m. UTC | #5
On 11/27/24 09:20, Kasireddy, Vivek wrote:
...
>> Recap of the DG2 problem:
>>
>> The virtio-gpu PCIe accesses in guest are becoming rejected as soon as Intel
>> driver (either i915 or Xe) is probed. My theory is that Intel driver causes PCIe
>> config change that indirectly breaks virtio-gpu PCIe. This problem isn't
>> observed by swapping DG2 card with AMD card. AMD setup works perfectly
>> fine on the same machine with GPU card plugged into the same PCIe slot as
>> DG2 was on host.
>>
>> $ lspci | grep DG2
>> 0c:00.0 VGA compatible controller: Intel Corporation DG2 [Arc A750] (rev 08)
>> 0d:00.0 Audio device: Intel Corporation DG2 Audio Controller
> Looks like the GPU and the audio devices are on different buses (I see the same
> in my setup as well) but you are making them appear as different functions of
> the same device in Guest VM:
> 01:00.0 VGA compatible controller [0300]: Intel Corporation DG2 [Intel Graphics] [8086:56bd] (rev 05) (prog-if 00 [VGA controller])
>         Subsystem: Intel Corporation Device [8086:1211]
>         Physical Slot: 0
>         Kernel driver in use: i915
>         Kernel modules: i915, xe
> 01:00.1 Audio device [0403]: Intel Corporation DG2 Audio Controller [8086:4f92]
>         Subsystem: Intel Corporation Device [8086:1211]
>         Physical Slot: 0
> 
> I am not sure if this a valid config or not. Regardless, the presence of i915 preventing
> virtio-gpu from probing correctly in this situation is indeed a problem that I am able
> to see in my setup as well (with your Qemu parameters, especially the pcie-port ones).
> I'll definitely take a look at this issue next week. 

Great, thank you

>> qemu-system-x86_64 \
>> -kernel linux-guest/arch/x86_64/boot/bzImage \
>> -append "console=ttyS0 nokaslr root=/dev/sda init=/lib/systemd/systemd
>> vt.global_cursor_default=0 log_buf_len=16M" \
>> -netdev user,id=u1,hostfwd=tcp::10022-:22 \
>> -device virtio-net-pci,netdev=u1 \
>> -serial mon:stdio -m 24G \
>> --enable-kvm \
>> -cpu host,host-phys-bits=on,host-phys-bits-limit=39 \
>> -device virtio-vga,max_outputs=1,xres=1920,yres=1080,blob=true \
>> -device virtio-tablet-pci \
>> -device virtio-balloon \
>> -device virtio-keyboard-pci \
>> -display gtk,gl=on \
>> -smp 16 \
>> -machine q35,accel=kvm,kernel-irqchip=split,memory-backend=mem1 \
>> -object memory-backend-memfd,id=mem1,size=24G \
>> -d guest_errors \
>> -drive file=disk.img,format=raw \
>> -device pcie-root-
>> port,id=pcie.1,bus=pcie.0,addr=1c.0,slot=1,chassis=1,multifunction=on \
>> -device vfio-pci,host=0c:00.0,bus=pcie.1,addr=00.0,x-
>> vga=on,multifunction=on \
>> -device vfio-pci,host=0d:00.0,bus=pcie.1,addr=00.1
> Passthrough'ng the devices directly instead of creating a new pcie root port
> enables virtio-gpu to work correctly in my setup. That is, having just
> -device vfio-pci,host=0c:00.0,x-vga=on -device vfio-pci,host=0d:00.0
> 
> instead of the last few lines in your Qemu parameters list makes virtio-gpu
> to work as expected. Could you please try it out and let me know if it works?

Indeed, that worked! With AMD card all GPU devices are on the same bus
and I was re-using same QEMU command without noticing it. Good catch :)
diff mbox series

Patch

diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h
index 6584f7984b1e..ad6960aa464e 100644
--- a/drivers/gpu/drm/virtio/virtgpu_drv.h
+++ b/drivers/gpu/drm/virtio/virtgpu_drv.h
@@ -89,6 +89,7 @@  struct virtio_gpu_object_params {
 
 struct virtio_gpu_object {
 	struct drm_gem_shmem_object base;
+	struct sg_table *sgt;
 	uint32_t hw_res_handle;
 	bool dumb;
 	bool created;
@@ -477,6 +478,10 @@  struct drm_gem_object *virtgpu_gem_prime_import(struct drm_device *dev,
 struct drm_gem_object *virtgpu_gem_prime_import_sg_table(
 	struct drm_device *dev, struct dma_buf_attachment *attach,
 	struct sg_table *sgt);
+int virtgpu_dma_buf_import_sgt(struct virtio_gpu_mem_entry **ents,
+			       unsigned int *nents,
+			       struct virtio_gpu_object *bo,
+			       struct dma_buf_attachment *attach);
 
 /* virtgpu_debugfs.c */
 void virtio_gpu_debugfs_init(struct drm_minor *minor);
diff --git a/drivers/gpu/drm/virtio/virtgpu_prime.c b/drivers/gpu/drm/virtio/virtgpu_prime.c
index 44425f20d91a..2d644240a2b7 100644
--- a/drivers/gpu/drm/virtio/virtgpu_prime.c
+++ b/drivers/gpu/drm/virtio/virtgpu_prime.c
@@ -27,6 +27,8 @@ 
 
 #include "virtgpu_drv.h"
 
+MODULE_IMPORT_NS(DMA_BUF);
+
 static int virtgpu_virtio_get_uuid(struct dma_buf *buf,
 				   uuid_t *uuid)
 {
@@ -142,6 +144,47 @@  struct dma_buf *virtgpu_gem_prime_export(struct drm_gem_object *obj,
 	return buf;
 }
 
+int virtgpu_dma_buf_import_sgt(struct virtio_gpu_mem_entry **ents,
+			       unsigned int *nents,
+			       struct virtio_gpu_object *bo,
+			       struct dma_buf_attachment *attach)
+{
+	struct scatterlist *sl;
+	struct sg_table *sgt;
+	long i, ret;
+
+	dma_resv_assert_held(attach->dmabuf->resv);
+
+	ret = dma_resv_wait_timeout(attach->dmabuf->resv,
+				    DMA_RESV_USAGE_KERNEL,
+				    false, MAX_SCHEDULE_TIMEOUT);
+	if (ret <= 0)
+		return ret < 0 ? ret : -ETIMEDOUT;
+
+	sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL);
+	if (IS_ERR(sgt))
+		return PTR_ERR(sgt);
+
+	*ents = kvmalloc_array(sgt->nents,
+			       sizeof(struct virtio_gpu_mem_entry),
+			       GFP_KERNEL);
+	if (!(*ents)) {
+		dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL);
+		return -ENOMEM;
+	}
+
+	*nents = sgt->nents;
+	for_each_sgtable_dma_sg(sgt, sl, i) {
+		(*ents)[i].addr = cpu_to_le64(sg_dma_address(sl));
+		(*ents)[i].length = cpu_to_le32(sg_dma_len(sl));
+		(*ents)[i].padding = 0;
+	}
+
+	bo->sgt = sgt;
+	bo->detached = false;
+	return 0;
+}
+
 struct drm_gem_object *virtgpu_gem_prime_import(struct drm_device *dev,
 						struct dma_buf *buf)
 {