[4/4,v6] drm/virtio: enqueue virtio_gpu_create_context after the first 3D ioctl
diff mbox series

Message ID 20200219223423.53319-4-gurchetansingh@chromium.org
State New
Headers show
Series
  • [1/4,v6] drm/virtio: use consistent names for drm_files
Related show

Commit Message

Gurchetan Singh Feb. 19, 2020, 10:34 p.m. UTC
For old userspace, initialization will still be implicit.

For backwards compatibility, enqueue virtio_gpu_cmd_context_create after
the first 3D ioctl.

v3: staticify virtio_gpu_create_context
    remove notify to batch vm-exit
v6: Remove nested 3D checks (emil.velikov):
      - unify 3D check in resource create
      - VIRTIO_GPU_CMD_GET_CAPSET is listed as a 2D ioctl, added a
        3D check there.

Reviewed-by: Chia-I Wu <olvaffe@gmail.com>
Reviewed-by: Emil Velikov <emil.velikov@collabora.com>
Signed-off-by: Gurchetan Singh <gurchetansingh@chromium.org>
---
 drivers/gpu/drm/virtio/virtgpu_drv.h   |  2 --
 drivers/gpu/drm/virtio/virtgpu_ioctl.c | 32 +++++++++++++++-----------
 drivers/gpu/drm/virtio/virtgpu_kms.c   |  1 -
 3 files changed, 19 insertions(+), 16 deletions(-)

Comments

Chia-I Wu Feb. 21, 2020, 11:06 p.m. UTC | #1
On Wed, Feb 19, 2020 at 2:34 PM Gurchetan Singh
<gurchetansingh@chromium.org> wrote:
>
> For old userspace, initialization will still be implicit.
>
> For backwards compatibility, enqueue virtio_gpu_cmd_context_create after
> the first 3D ioctl.
>
> v3: staticify virtio_gpu_create_context
>     remove notify to batch vm-exit
> v6: Remove nested 3D checks (emil.velikov):
>       - unify 3D check in resource create
>       - VIRTIO_GPU_CMD_GET_CAPSET is listed as a 2D ioctl, added a
>         3D check there.
I missed this change.  Why do we need a context to get capsets?  Is
this a workaround or something?

>
> Reviewed-by: Chia-I Wu <olvaffe@gmail.com>
> Reviewed-by: Emil Velikov <emil.velikov@collabora.com>
> Signed-off-by: Gurchetan Singh <gurchetansingh@chromium.org>
> ---
>  drivers/gpu/drm/virtio/virtgpu_drv.h   |  2 --
>  drivers/gpu/drm/virtio/virtgpu_ioctl.c | 32 +++++++++++++++-----------
>  drivers/gpu/drm/virtio/virtgpu_kms.c   |  1 -
>  3 files changed, 19 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h
> index 76b7b7c30e10..95a7443baaba 100644
> --- a/drivers/gpu/drm/virtio/virtgpu_drv.h
> +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h
> @@ -216,8 +216,6 @@ struct virtio_gpu_fpriv {
>  /* virtio_ioctl.c */
>  #define DRM_VIRTIO_NUM_IOCTLS 10
>  extern struct drm_ioctl_desc virtio_gpu_ioctls[DRM_VIRTIO_NUM_IOCTLS];
> -void virtio_gpu_create_context(struct drm_device *dev,
> -                              struct drm_file *file);
>
>  /* virtio_kms.c */
>  int virtio_gpu_init(struct drm_device *dev);
> diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
> index ec38cf5573aa..c36faa572caa 100644
> --- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c
> +++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
> @@ -33,8 +33,8 @@
>
>  #include "virtgpu_drv.h"
>
> -void virtio_gpu_create_context(struct drm_device *dev,
> -                              struct drm_file *file)
> +static void virtio_gpu_create_context(struct drm_device *dev,
> +                                     struct drm_file *file)
>  {
>         struct virtio_gpu_device *vgdev = dev->dev_private;
>         struct virtio_gpu_fpriv *vfpriv = file->driver_priv;
> @@ -95,6 +95,7 @@ static int virtio_gpu_execbuffer_ioctl(struct drm_device *dev, void *data,
>
>         exbuf->fence_fd = -1;
>
> +       virtio_gpu_create_context(dev, file);
>         if (exbuf->flags & VIRTGPU_EXECBUF_FENCE_FD_IN) {
>                 struct dma_fence *in_fence;
>
> @@ -233,7 +234,17 @@ static int virtio_gpu_resource_create_ioctl(struct drm_device *dev, void *data,
>         uint32_t handle = 0;
>         struct virtio_gpu_object_params params = { 0 };
>
> -       if (vgdev->has_virgl_3d == false) {
> +       if (vgdev->has_virgl_3d) {
> +               virtio_gpu_create_context(dev, file);
> +               params.virgl = true;
> +               params.target = rc->target;
> +               params.bind = rc->bind;
> +               params.depth = rc->depth;
> +               params.array_size = rc->array_size;
> +               params.last_level = rc->last_level;
> +               params.nr_samples = rc->nr_samples;
> +               params.flags = rc->flags;
> +       } else {
>                 if (rc->depth > 1)
>                         return -EINVAL;
>                 if (rc->nr_samples > 1)
> @@ -250,16 +261,6 @@ static int virtio_gpu_resource_create_ioctl(struct drm_device *dev, void *data,
>         params.width = rc->width;
>         params.height = rc->height;
>         params.size = rc->size;
> -       if (vgdev->has_virgl_3d) {
> -               params.virgl = true;
> -               params.target = rc->target;
> -               params.bind = rc->bind;
> -               params.depth = rc->depth;
> -               params.array_size = rc->array_size;
> -               params.last_level = rc->last_level;
> -               params.nr_samples = rc->nr_samples;
> -               params.flags = rc->flags;
> -       }
>         /* allocate a single page size object */
>         if (params.size == 0)
>                 params.size = PAGE_SIZE;
> @@ -319,6 +320,7 @@ static int virtio_gpu_transfer_from_host_ioctl(struct drm_device *dev,
>         if (vgdev->has_virgl_3d == false)
>                 return -ENOSYS;
>
> +       virtio_gpu_create_context(dev, file);
>         objs = virtio_gpu_array_from_handles(file, &args->bo_handle, 1);
>         if (objs == NULL)
>                 return -ENOENT;
> @@ -367,6 +369,7 @@ static int virtio_gpu_transfer_to_host_ioctl(struct drm_device *dev, void *data,
>                          args->box.w, args->box.h, args->box.x, args->box.y,
>                          objs, NULL);
>         } else {
> +               virtio_gpu_create_context(dev, file);
>                 ret = virtio_gpu_array_lock_resv(objs);
>                 if (ret != 0)
>                         goto err_put_free;
> @@ -466,6 +469,9 @@ static int virtio_gpu_get_caps_ioctl(struct drm_device *dev,
>         }
>         spin_unlock(&vgdev->display_info_lock);
>
> +       if (vgdev->has_virgl_3d)
> +               virtio_gpu_create_context(dev, file);
> +
>         /* not in cache - need to talk to hw */
>         virtio_gpu_cmd_get_capset(vgdev, found_valid, args->cap_set_ver,
>                                   &cache_ent);
> diff --git a/drivers/gpu/drm/virtio/virtgpu_kms.c b/drivers/gpu/drm/virtio/virtgpu_kms.c
> index 424729cb81d1..023a030ca7b9 100644
> --- a/drivers/gpu/drm/virtio/virtgpu_kms.c
> +++ b/drivers/gpu/drm/virtio/virtgpu_kms.c
> @@ -268,7 +268,6 @@ int virtio_gpu_driver_open(struct drm_device *dev, struct drm_file *file)
>
>         vfpriv->ctx_id = handle + 1;
>         file->driver_priv = vfpriv;
> -       virtio_gpu_create_context(dev, file);
>         return 0;
>  }
>
> --
> 2.25.0.265.gbab2e86ba0-goog
>
Gurchetan Singh Feb. 22, 2020, 12:54 a.m. UTC | #2
On Fri, Feb 21, 2020 at 3:06 PM Chia-I Wu <olvaffe@gmail.com> wrote:
>
> On Wed, Feb 19, 2020 at 2:34 PM Gurchetan Singh
> <gurchetansingh@chromium.org> wrote:
> >
> > For old userspace, initialization will still be implicit.
> >
> > For backwards compatibility, enqueue virtio_gpu_cmd_context_create after
> > the first 3D ioctl.
> >
> > v3: staticify virtio_gpu_create_context
> >     remove notify to batch vm-exit
> > v6: Remove nested 3D checks (emil.velikov):
> >       - unify 3D check in resource create
> >       - VIRTIO_GPU_CMD_GET_CAPSET is listed as a 2D ioctl, added a
> >         3D check there.
> I missed this change.  Why do we need a context to get capsets?  Is
> this a workaround or something?

No, don't need a context to get a capset.  The patch tries to create a
context when a 3D userspace first talks to the host, not when a 3D
userspace first needs a context ID.  If the latter is preferred, we
can do that too.

>
> >
> > Reviewed-by: Chia-I Wu <olvaffe@gmail.com>
> > Reviewed-by: Emil Velikov <emil.velikov@collabora.com>
> > Signed-off-by: Gurchetan Singh <gurchetansingh@chromium.org>
> > ---
> >  drivers/gpu/drm/virtio/virtgpu_drv.h   |  2 --
> >  drivers/gpu/drm/virtio/virtgpu_ioctl.c | 32 +++++++++++++++-----------
> >  drivers/gpu/drm/virtio/virtgpu_kms.c   |  1 -
> >  3 files changed, 19 insertions(+), 16 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h
> > index 76b7b7c30e10..95a7443baaba 100644
> > --- a/drivers/gpu/drm/virtio/virtgpu_drv.h
> > +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h
> > @@ -216,8 +216,6 @@ struct virtio_gpu_fpriv {
> >  /* virtio_ioctl.c */
> >  #define DRM_VIRTIO_NUM_IOCTLS 10
> >  extern struct drm_ioctl_desc virtio_gpu_ioctls[DRM_VIRTIO_NUM_IOCTLS];
> > -void virtio_gpu_create_context(struct drm_device *dev,
> > -                              struct drm_file *file);
> >
> >  /* virtio_kms.c */
> >  int virtio_gpu_init(struct drm_device *dev);
> > diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
> > index ec38cf5573aa..c36faa572caa 100644
> > --- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c
> > +++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
> > @@ -33,8 +33,8 @@
> >
> >  #include "virtgpu_drv.h"
> >
> > -void virtio_gpu_create_context(struct drm_device *dev,
> > -                              struct drm_file *file)
> > +static void virtio_gpu_create_context(struct drm_device *dev,
> > +                                     struct drm_file *file)
> >  {
> >         struct virtio_gpu_device *vgdev = dev->dev_private;
> >         struct virtio_gpu_fpriv *vfpriv = file->driver_priv;
> > @@ -95,6 +95,7 @@ static int virtio_gpu_execbuffer_ioctl(struct drm_device *dev, void *data,
> >
> >         exbuf->fence_fd = -1;
> >
> > +       virtio_gpu_create_context(dev, file);
> >         if (exbuf->flags & VIRTGPU_EXECBUF_FENCE_FD_IN) {
> >                 struct dma_fence *in_fence;
> >
> > @@ -233,7 +234,17 @@ static int virtio_gpu_resource_create_ioctl(struct drm_device *dev, void *data,
> >         uint32_t handle = 0;
> >         struct virtio_gpu_object_params params = { 0 };
> >
> > -       if (vgdev->has_virgl_3d == false) {
> > +       if (vgdev->has_virgl_3d) {
> > +               virtio_gpu_create_context(dev, file);
> > +               params.virgl = true;
> > +               params.target = rc->target;
> > +               params.bind = rc->bind;
> > +               params.depth = rc->depth;
> > +               params.array_size = rc->array_size;
> > +               params.last_level = rc->last_level;
> > +               params.nr_samples = rc->nr_samples;
> > +               params.flags = rc->flags;
> > +       } else {
> >                 if (rc->depth > 1)
> >                         return -EINVAL;
> >                 if (rc->nr_samples > 1)
> > @@ -250,16 +261,6 @@ static int virtio_gpu_resource_create_ioctl(struct drm_device *dev, void *data,
> >         params.width = rc->width;
> >         params.height = rc->height;
> >         params.size = rc->size;
> > -       if (vgdev->has_virgl_3d) {
> > -               params.virgl = true;
> > -               params.target = rc->target;
> > -               params.bind = rc->bind;
> > -               params.depth = rc->depth;
> > -               params.array_size = rc->array_size;
> > -               params.last_level = rc->last_level;
> > -               params.nr_samples = rc->nr_samples;
> > -               params.flags = rc->flags;
> > -       }
> >         /* allocate a single page size object */
> >         if (params.size == 0)
> >                 params.size = PAGE_SIZE;
> > @@ -319,6 +320,7 @@ static int virtio_gpu_transfer_from_host_ioctl(struct drm_device *dev,
> >         if (vgdev->has_virgl_3d == false)
> >                 return -ENOSYS;
> >
> > +       virtio_gpu_create_context(dev, file);
> >         objs = virtio_gpu_array_from_handles(file, &args->bo_handle, 1);
> >         if (objs == NULL)
> >                 return -ENOENT;
> > @@ -367,6 +369,7 @@ static int virtio_gpu_transfer_to_host_ioctl(struct drm_device *dev, void *data,
> >                          args->box.w, args->box.h, args->box.x, args->box.y,
> >                          objs, NULL);
> >         } else {
> > +               virtio_gpu_create_context(dev, file);
> >                 ret = virtio_gpu_array_lock_resv(objs);
> >                 if (ret != 0)
> >                         goto err_put_free;
> > @@ -466,6 +469,9 @@ static int virtio_gpu_get_caps_ioctl(struct drm_device *dev,
> >         }
> >         spin_unlock(&vgdev->display_info_lock);
> >
> > +       if (vgdev->has_virgl_3d)
> > +               virtio_gpu_create_context(dev, file);
> > +
> >         /* not in cache - need to talk to hw */
> >         virtio_gpu_cmd_get_capset(vgdev, found_valid, args->cap_set_ver,
> >                                   &cache_ent);
> > diff --git a/drivers/gpu/drm/virtio/virtgpu_kms.c b/drivers/gpu/drm/virtio/virtgpu_kms.c
> > index 424729cb81d1..023a030ca7b9 100644
> > --- a/drivers/gpu/drm/virtio/virtgpu_kms.c
> > +++ b/drivers/gpu/drm/virtio/virtgpu_kms.c
> > @@ -268,7 +268,6 @@ int virtio_gpu_driver_open(struct drm_device *dev, struct drm_file *file)
> >
> >         vfpriv->ctx_id = handle + 1;
> >         file->driver_priv = vfpriv;
> > -       virtio_gpu_create_context(dev, file);
> >         return 0;
> >  }
> >
> > --
> > 2.25.0.265.gbab2e86ba0-goog
> >
Gerd Hoffmann Feb. 24, 2020, 11:06 a.m. UTC | #3
On Fri, Feb 21, 2020 at 04:54:02PM -0800, Gurchetan Singh wrote:
> On Fri, Feb 21, 2020 at 3:06 PM Chia-I Wu <olvaffe@gmail.com> wrote:
> >
> > On Wed, Feb 19, 2020 at 2:34 PM Gurchetan Singh
> > <gurchetansingh@chromium.org> wrote:
> > >
> > > For old userspace, initialization will still be implicit.
> > >
> > > For backwards compatibility, enqueue virtio_gpu_cmd_context_create after
> > > the first 3D ioctl.
> > >
> > > v3: staticify virtio_gpu_create_context
> > >     remove notify to batch vm-exit
> > > v6: Remove nested 3D checks (emil.velikov):
> > >       - unify 3D check in resource create
> > >       - VIRTIO_GPU_CMD_GET_CAPSET is listed as a 2D ioctl, added a
> > >         3D check there.
> > I missed this change.  Why do we need a context to get capsets?  Is
> > this a workaround or something?
> 
> No, don't need a context to get a capset.  The patch tries to create a
> context when a 3D userspace first talks to the host, not when a 3D
> userspace first needs a context ID.  If the latter is preferred, we
> can do that too.

I think it makes sense to exclude the capset ioctls here.

Possibly they are used for non-3d-related capabilities at some
point in the future.

Also userspace gets capsets while checking device capabilities
and possibly does so before deciding how to drive the device.

cheers,
  Gerd
Emil Velikov Feb. 24, 2020, 1:23 p.m. UTC | #4
On Mon, 24 Feb 2020 at 11:06, Gerd Hoffmann <kraxel@redhat.com> wrote:
>
> On Fri, Feb 21, 2020 at 04:54:02PM -0800, Gurchetan Singh wrote:
> > On Fri, Feb 21, 2020 at 3:06 PM Chia-I Wu <olvaffe@gmail.com> wrote:
> > >
> > > On Wed, Feb 19, 2020 at 2:34 PM Gurchetan Singh
> > > <gurchetansingh@chromium.org> wrote:
> > > >
> > > > For old userspace, initialization will still be implicit.
> > > >
> > > > For backwards compatibility, enqueue virtio_gpu_cmd_context_create after
> > > > the first 3D ioctl.
> > > >
> > > > v3: staticify virtio_gpu_create_context
> > > >     remove notify to batch vm-exit
> > > > v6: Remove nested 3D checks (emil.velikov):
> > > >       - unify 3D check in resource create
> > > >       - VIRTIO_GPU_CMD_GET_CAPSET is listed as a 2D ioctl, added a
> > > >         3D check there.
> > > I missed this change.  Why do we need a context to get capsets?  Is
> > > this a workaround or something?
> >
> > No, don't need a context to get a capset.  The patch tries to create a
> > context when a 3D userspace first talks to the host, not when a 3D
> > userspace first needs a context ID.  If the latter is preferred, we
> > can do that too.
>
> I think it makes sense to exclude the capset ioctls here.
>
> Possibly they are used for non-3d-related capabilities at some
> point in the future.
>
> Also userspace gets capsets while checking device capabilities
> and possibly does so before deciding how to drive the device.
>
Virglrenderer creates the internal/base GL* context during
virgl_renderer_init().
Based upon which the caps are populated.

Personally I don't have a preference for/against dropping the
virtio_gpu_create_context().
Yet it does seems safe to omit.

HTH
Emil
Chia-I Wu Feb. 24, 2020, 6:47 p.m. UTC | #5
On Mon, Feb 24, 2020 at 5:24 AM Emil Velikov <emil.l.velikov@gmail.com> wrote:
>
> On Mon, 24 Feb 2020 at 11:06, Gerd Hoffmann <kraxel@redhat.com> wrote:
> >
> > On Fri, Feb 21, 2020 at 04:54:02PM -0800, Gurchetan Singh wrote:
> > > On Fri, Feb 21, 2020 at 3:06 PM Chia-I Wu <olvaffe@gmail.com> wrote:
> > > >
> > > > On Wed, Feb 19, 2020 at 2:34 PM Gurchetan Singh
> > > > <gurchetansingh@chromium.org> wrote:
> > > > >
> > > > > For old userspace, initialization will still be implicit.
> > > > >
> > > > > For backwards compatibility, enqueue virtio_gpu_cmd_context_create after
> > > > > the first 3D ioctl.
> > > > >
> > > > > v3: staticify virtio_gpu_create_context
> > > > >     remove notify to batch vm-exit
> > > > > v6: Remove nested 3D checks (emil.velikov):
> > > > >       - unify 3D check in resource create
> > > > >       - VIRTIO_GPU_CMD_GET_CAPSET is listed as a 2D ioctl, added a
> > > > >         3D check there.
> > > > I missed this change.  Why do we need a context to get capsets?  Is
> > > > this a workaround or something?
> > >
> > > No, don't need a context to get a capset.  The patch tries to create a
> > > context when a 3D userspace first talks to the host, not when a 3D
> > > userspace first needs a context ID.  If the latter is preferred, we
> > > can do that too.
> >
> > I think it makes sense to exclude the capset ioctls here.
> >
> > Possibly they are used for non-3d-related capabilities at some
> > point in the future.
> >
> > Also userspace gets capsets while checking device capabilities
> > and possibly does so before deciding how to drive the device.
> >
> Virglrenderer creates the internal/base GL* context during
> virgl_renderer_init().
> Based upon which the caps are populated.
>
> Personally I don't have a preference for/against dropping the
> virtio_gpu_create_context().
> Yet it does seems safe to omit.
Yeah, it should be safe to omit.  The userspace might want to decide
the "context type" based on the capsets.  It should also be better to
omit.


>
> HTH
> Emil

Patch
diff mbox series

diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h
index 76b7b7c30e10..95a7443baaba 100644
--- a/drivers/gpu/drm/virtio/virtgpu_drv.h
+++ b/drivers/gpu/drm/virtio/virtgpu_drv.h
@@ -216,8 +216,6 @@  struct virtio_gpu_fpriv {
 /* virtio_ioctl.c */
 #define DRM_VIRTIO_NUM_IOCTLS 10
 extern struct drm_ioctl_desc virtio_gpu_ioctls[DRM_VIRTIO_NUM_IOCTLS];
-void virtio_gpu_create_context(struct drm_device *dev,
-			       struct drm_file *file);
 
 /* virtio_kms.c */
 int virtio_gpu_init(struct drm_device *dev);
diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
index ec38cf5573aa..c36faa572caa 100644
--- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c
+++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
@@ -33,8 +33,8 @@ 
 
 #include "virtgpu_drv.h"
 
-void virtio_gpu_create_context(struct drm_device *dev,
-			       struct drm_file *file)
+static void virtio_gpu_create_context(struct drm_device *dev,
+				      struct drm_file *file)
 {
 	struct virtio_gpu_device *vgdev = dev->dev_private;
 	struct virtio_gpu_fpriv *vfpriv = file->driver_priv;
@@ -95,6 +95,7 @@  static int virtio_gpu_execbuffer_ioctl(struct drm_device *dev, void *data,
 
 	exbuf->fence_fd = -1;
 
+	virtio_gpu_create_context(dev, file);
 	if (exbuf->flags & VIRTGPU_EXECBUF_FENCE_FD_IN) {
 		struct dma_fence *in_fence;
 
@@ -233,7 +234,17 @@  static int virtio_gpu_resource_create_ioctl(struct drm_device *dev, void *data,
 	uint32_t handle = 0;
 	struct virtio_gpu_object_params params = { 0 };
 
-	if (vgdev->has_virgl_3d == false) {
+	if (vgdev->has_virgl_3d) {
+		virtio_gpu_create_context(dev, file);
+		params.virgl = true;
+		params.target = rc->target;
+		params.bind = rc->bind;
+		params.depth = rc->depth;
+		params.array_size = rc->array_size;
+		params.last_level = rc->last_level;
+		params.nr_samples = rc->nr_samples;
+		params.flags = rc->flags;
+	} else {
 		if (rc->depth > 1)
 			return -EINVAL;
 		if (rc->nr_samples > 1)
@@ -250,16 +261,6 @@  static int virtio_gpu_resource_create_ioctl(struct drm_device *dev, void *data,
 	params.width = rc->width;
 	params.height = rc->height;
 	params.size = rc->size;
-	if (vgdev->has_virgl_3d) {
-		params.virgl = true;
-		params.target = rc->target;
-		params.bind = rc->bind;
-		params.depth = rc->depth;
-		params.array_size = rc->array_size;
-		params.last_level = rc->last_level;
-		params.nr_samples = rc->nr_samples;
-		params.flags = rc->flags;
-	}
 	/* allocate a single page size object */
 	if (params.size == 0)
 		params.size = PAGE_SIZE;
@@ -319,6 +320,7 @@  static int virtio_gpu_transfer_from_host_ioctl(struct drm_device *dev,
 	if (vgdev->has_virgl_3d == false)
 		return -ENOSYS;
 
+	virtio_gpu_create_context(dev, file);
 	objs = virtio_gpu_array_from_handles(file, &args->bo_handle, 1);
 	if (objs == NULL)
 		return -ENOENT;
@@ -367,6 +369,7 @@  static int virtio_gpu_transfer_to_host_ioctl(struct drm_device *dev, void *data,
 			 args->box.w, args->box.h, args->box.x, args->box.y,
 			 objs, NULL);
 	} else {
+		virtio_gpu_create_context(dev, file);
 		ret = virtio_gpu_array_lock_resv(objs);
 		if (ret != 0)
 			goto err_put_free;
@@ -466,6 +469,9 @@  static int virtio_gpu_get_caps_ioctl(struct drm_device *dev,
 	}
 	spin_unlock(&vgdev->display_info_lock);
 
+	if (vgdev->has_virgl_3d)
+		virtio_gpu_create_context(dev, file);
+
 	/* not in cache - need to talk to hw */
 	virtio_gpu_cmd_get_capset(vgdev, found_valid, args->cap_set_ver,
 				  &cache_ent);
diff --git a/drivers/gpu/drm/virtio/virtgpu_kms.c b/drivers/gpu/drm/virtio/virtgpu_kms.c
index 424729cb81d1..023a030ca7b9 100644
--- a/drivers/gpu/drm/virtio/virtgpu_kms.c
+++ b/drivers/gpu/drm/virtio/virtgpu_kms.c
@@ -268,7 +268,6 @@  int virtio_gpu_driver_open(struct drm_device *dev, struct drm_file *file)
 
 	vfpriv->ctx_id = handle + 1;
 	file->driver_priv = vfpriv;
-	virtio_gpu_create_context(dev, file);
 	return 0;
 }