LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* [PATCH v18 0/6] drm/i915/gvt: Dma-buf support for GVT-g
@ 2017-11-15 9:11 Tina Zhang
2017-11-15 9:11 ` [PATCH v18 1/6] drm/i915/gvt: Add framebuffer decoder support Tina Zhang
` (6 more replies)
0 siblings, 7 replies; 19+ messages in thread
From: Tina Zhang @ 2017-11-15 9:11 UTC (permalink / raw)
To: alex.williamson, kraxel, chris, joonas.lahtinen, zhenyuw,
zhiyuan.lv, zhi.a.wang, kevin.tian, daniel, kwankhede, hang.yuan
Cc: Tina Zhang, intel-gfx, intel-gvt-dev, linux-kernel
v17->v18:
1) unmap vgpu's opregion when destroying vgpu.
2) update comments for VFIO_DEVICE_GET_GFX_DMABUF. (Alex)
v16->v17:
1) modify VFIO_DEVICE_GET_GFX_DMABUF interface. (Alex)
2) add comments for x_hot/y_hot. (Gerd)
v15->v16:
1) add cursor hotspot fields in struct vfio_device_gfx_plane_info. (Gerd)
2) clean up some typos and add comments for VFIO_DEVICE_QUERY_GFX_PLANE. (Alex)
3) seperate the GEM Proxy part to another patch-set. (Joonas and Chris)
https://lists.freedesktop.org/archives/intel-gvt-dev/2017-November/002377.html
4) please note that this patch-set needs 3) to be applied first.
5) rebase to 4.14.0-rc6.
v14->15:
1) add VFIO_DEVICE_GET_GFX_DMABUF ABI. (Gerd)
2) add intel_vgpu_dmabuf_cleanup() to clean up the vGPU's dmabuf. (Gerd)
v13->v14:
1) add PROBE, DMABUF and REGION flags. (Alex)
2) return -ENXIO when gem proxy object is banned by ioctl.
(Chris) (Daniel)
3) add some details about the float pixel format. (Daniel)
4) add F suffix to the defined name. (Daniel)
5) refine pixel format table. (Zhenyu)
v12->v13:
1) add comments to GEM proxy. (Chris)
2) don't ban GEM proxy in i915_gem_sw_finish_ioctl. (Chris)
3) check GEM proxy bar after finishing i915_gem_object_wait. (Chris)
4) remove GEM proxy bar in i915_gem_madvise_ioctl.
v11->v12:
1) add drm_format_mod back. (Gerd and Zhenyu)
2) add region_index. (Gerd)
3) refine the lifecycle of dmabuf.
4) send to dri-devel at lists.freedesktop.org. (Ville)
v10->v11:
1) rename plane_type to drm_plane_type. (Gerd)
2) move fields of vfio_device_query_gfx_plane to
vfio_device_gfx_plane_info. (Gerd)
3) remove drm_format_mod, start fields. (Daniel)
4) remove plane_id.
v9->v10:
1) remove dma-buf management
2) refine the ABI API VFIO_DEVICE_QUERY_GFX_PLANE
3) track the dma-buf create and release in kernel mode
v8->v9:
1) refine the dma-buf ioctl definition
2) add a lock to protect the dmabuf list
3) move drm format change to a separate patch
4) codes cleanup
v7->v8:
1) refine framebuffer decoder code
2) fix a bug in decoding primary plane
v6->v7:
1) release dma-buf related allocations in dma-buf's associated release
function.
2) refine ioctl interface for querying plane info or create dma-buf
3) refine framebuffer decoder code
4) the patch series is based on 4.12.0-rc1
v5->v6:
1) align the dma-buf life cycle with the vfio device.
2) add the dma-buf related operations in a separate patch.
3) i915 releated changes.
v4->v5:
1) fix bug while checking whether the gem obj is gvt's dma-buf when user
change caching mode or domains. Add a helper function to do it.
2) add definition for the query plane and create dma-buf.
v3->v4:
1) fix bug while checking whether the gem obj is gvt's dma-buf when set
caching mode or doamins.
v2->v3:
1) add a field gvt_plane_info in the drm_i915_gem_obj structure to save
the decoded plane information to avoid look up while need the plane info.
2) declare a new flag I915_GEM_OBJECT_IS_GVT_DMABUF in drm_i915_gem_object
to represent the gem obj for gvt's dma-buf. The tiling mode, caching mode
and domains can not be changed for this kind of gem object.
3) change dma-buf related information to be more generic. So other vendor
can use the same interface.
v1->v2:
1) create a management fd for dma-buf operations.
2) alloc gem object's backing storage in gem obj's get_pages() callback.
This patch set adds the dma-buf support for intel GVT-g.
dma-buf is an uniform mechanism to share DMA buffers across different
devices and subsystems. dma-buf for intel GVT-g is mainly used to share
the vgpu's framebuffer to userspace to leverage userspace graphics stacks
to render the framebuffer to the display monitor.
The main idea is that we create a gem object and set vgpu's framebuffer as
its backing storage. Then, export a dma-buf associated with this gem object.
With the fd of this dma-buf, userspace can directly handle this buffer.
This patch set can be tried with the following example:
git://git.kraxel.org/qemu branch: work/intel-vgpu
A topic branch with the latest patch set is:
https://github.com/intel/gvt-linux.git branch: topic/dmabuf
Tina Zhang (6):
drm/i915/gvt: Add framebuffer decoder support
drm: Introduce RGB 64-bit 16:16:16:16 float format
drm/i915/gvt: Add RGB 64-bit 16:16:16:16 float format
drm/i915/gvt: Add opregion support
vfio: ABI for mdev display dma-buf operation
drm/i915/gvt: Dmabuf support for GVT-g
drivers/gpu/drm/i915/gvt/Makefile | 3 +-
drivers/gpu/drm/i915/gvt/display.c | 2 +-
drivers/gpu/drm/i915/gvt/display.h | 2 +
drivers/gpu/drm/i915/gvt/dmabuf.c | 523 +++++++++++++++++++++++++++++++++
drivers/gpu/drm/i915/gvt/dmabuf.h | 67 +++++
drivers/gpu/drm/i915/gvt/fb_decoder.c | 521 ++++++++++++++++++++++++++++++++
drivers/gpu/drm/i915/gvt/fb_decoder.h | 169 +++++++++++
drivers/gpu/drm/i915/gvt/gvt.c | 2 +
drivers/gpu/drm/i915/gvt/gvt.h | 12 +
drivers/gpu/drm/i915/gvt/hypercall.h | 3 +
drivers/gpu/drm/i915/gvt/kvmgt.c | 157 +++++++++-
drivers/gpu/drm/i915/gvt/mpt.h | 45 +++
drivers/gpu/drm/i915/gvt/opregion.c | 29 +-
drivers/gpu/drm/i915/gvt/vgpu.c | 9 +-
drivers/gpu/drm/i915/i915_gem_object.h | 2 +
include/uapi/drm/drm_fourcc.h | 4 +
include/uapi/linux/vfio.h | 62 ++++
17 files changed, 1600 insertions(+), 12 deletions(-)
create mode 100644 drivers/gpu/drm/i915/gvt/dmabuf.c
create mode 100644 drivers/gpu/drm/i915/gvt/dmabuf.h
create mode 100644 drivers/gpu/drm/i915/gvt/fb_decoder.c
create mode 100644 drivers/gpu/drm/i915/gvt/fb_decoder.h
--
2.7.4
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH v18 1/6] drm/i915/gvt: Add framebuffer decoder support
2017-11-15 9:11 [PATCH v18 0/6] drm/i915/gvt: Dma-buf support for GVT-g Tina Zhang
@ 2017-11-15 9:11 ` Tina Zhang
2017-11-15 9:11 ` [PATCH v18 2/6] drm: Introduce RGB 64-bit 16:16:16:16 float format Tina Zhang
` (5 subsequent siblings)
6 siblings, 0 replies; 19+ messages in thread
From: Tina Zhang @ 2017-11-15 9:11 UTC (permalink / raw)
To: alex.williamson, kraxel, chris, joonas.lahtinen, zhenyuw,
zhiyuan.lv, zhi.a.wang, kevin.tian, daniel, kwankhede, hang.yuan
Cc: Tina Zhang, intel-gfx, intel-gvt-dev, linux-kernel
This patch is to introduce the framebuffer decoder which can decode guest
OS's framebuffer information, including primary, cursor and sprite plane.
v16:
- rebase to 4.14.0-rc6.
v14:
- refine pixel format table. (Zhenyu)
v9:
- move drm format change to a separate patch. (Xiaoguang)
v8:
- fix a bug in decoding primary plane. (Tina)
v7:
- refine framebuffer decoder code. (Zhenyu)
Signed-off-by: Tina Zhang <tina.zhang@intel.com>
Cc: Zhenyu Wang <zhenyuw@linux.intel.com>
---
drivers/gpu/drm/i915/gvt/Makefile | 3 +-
drivers/gpu/drm/i915/gvt/display.c | 2 +-
drivers/gpu/drm/i915/gvt/display.h | 2 +
drivers/gpu/drm/i915/gvt/fb_decoder.c | 507 ++++++++++++++++++++++++++++++++++
drivers/gpu/drm/i915/gvt/fb_decoder.h | 169 ++++++++++++
drivers/gpu/drm/i915/gvt/gvt.h | 1 +
6 files changed, 682 insertions(+), 2 deletions(-)
create mode 100644 drivers/gpu/drm/i915/gvt/fb_decoder.c
create mode 100644 drivers/gpu/drm/i915/gvt/fb_decoder.h
diff --git a/drivers/gpu/drm/i915/gvt/Makefile b/drivers/gpu/drm/i915/gvt/Makefile
index 7100240..54d70df 100644
--- a/drivers/gpu/drm/i915/gvt/Makefile
+++ b/drivers/gpu/drm/i915/gvt/Makefile
@@ -1,7 +1,8 @@
GVT_DIR := gvt
GVT_SOURCE := gvt.o aperture_gm.o handlers.o vgpu.o trace_points.o firmware.o \
interrupt.o gtt.o cfg_space.o opregion.o mmio.o display.o edid.o \
- execlist.o scheduler.o sched_policy.o render.o cmd_parser.o debugfs.o
+ execlist.o scheduler.o sched_policy.o render.o cmd_parser.o debugfs.o \
+ fb_decoder.o
ccflags-y += -I$(src) -I$(src)/$(GVT_DIR)
i915-y += $(addprefix $(GVT_DIR)/, $(GVT_SOURCE))
diff --git a/drivers/gpu/drm/i915/gvt/display.c b/drivers/gpu/drm/i915/gvt/display.c
index 3c31843..fb7fdba 100644
--- a/drivers/gpu/drm/i915/gvt/display.c
+++ b/drivers/gpu/drm/i915/gvt/display.c
@@ -67,7 +67,7 @@ static int edp_pipe_is_enabled(struct intel_vgpu *vgpu)
return 1;
}
-static int pipe_is_enabled(struct intel_vgpu *vgpu, int pipe)
+int pipe_is_enabled(struct intel_vgpu *vgpu, int pipe)
{
struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
diff --git a/drivers/gpu/drm/i915/gvt/display.h b/drivers/gpu/drm/i915/gvt/display.h
index d73de22..b46b868 100644
--- a/drivers/gpu/drm/i915/gvt/display.h
+++ b/drivers/gpu/drm/i915/gvt/display.h
@@ -179,4 +179,6 @@ int intel_vgpu_init_display(struct intel_vgpu *vgpu, u64 resolution);
void intel_vgpu_reset_display(struct intel_vgpu *vgpu);
void intel_vgpu_clean_display(struct intel_vgpu *vgpu);
+int pipe_is_enabled(struct intel_vgpu *vgpu, int pipe);
+
#endif
diff --git a/drivers/gpu/drm/i915/gvt/fb_decoder.c b/drivers/gpu/drm/i915/gvt/fb_decoder.c
new file mode 100644
index 0000000..6c99c64
--- /dev/null
+++ b/drivers/gpu/drm/i915/gvt/fb_decoder.c
@@ -0,0 +1,507 @@
+/*
+ * Copyright(c) 2011-2016 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Kevin Tian <kevin.tian@intel.com>
+ *
+ * Contributors:
+ * Bing Niu <bing.niu@intel.com>
+ * Xu Han <xu.han@intel.com>
+ * Ping Gao <ping.a.gao@intel.com>
+ * Xiaoguang Chen <xiaoguang.chen@intel.com>
+ * Yang Liu <yang2.liu@intel.com>
+ * Tina Zhang <tina.zhang@intel.com>
+ *
+ */
+
+#include <uapi/drm/drm_fourcc.h>
+#include "i915_drv.h"
+#include "gvt.h"
+
+#define PRIMARY_FORMAT_NUM 16
+struct pixel_format {
+ int drm_format; /* Pixel format in DRM definition */
+ int bpp; /* Bits per pixel, 0 indicates invalid */
+ char *desc; /* The description */
+};
+
+static struct pixel_format bdw_pixel_formats[] = {
+ {DRM_FORMAT_C8, 8, "8-bit Indexed"},
+ {DRM_FORMAT_RGB565, 16, "16-bit BGRX (5:6:5 MSB-R:G:B)"},
+ {DRM_FORMAT_XRGB8888, 32, "32-bit BGRX (8:8:8:8 MSB-X:R:G:B)"},
+ {DRM_FORMAT_XBGR2101010, 32, "32-bit RGBX (2:10:10:10 MSB-X:B:G:R)"},
+
+ {DRM_FORMAT_XRGB2101010, 32, "32-bit BGRX (2:10:10:10 MSB-X:R:G:B)"},
+ {DRM_FORMAT_XBGR8888, 32, "32-bit RGBX (8:8:8:8 MSB-X:B:G:R)"},
+
+ /* non-supported format has bpp default to 0 */
+ {0, 0, NULL},
+};
+
+static struct pixel_format skl_pixel_formats[] = {
+ {DRM_FORMAT_YUYV, 16, "16-bit packed YUYV (8:8:8:8 MSB-V:Y2:U:Y1)"},
+ {DRM_FORMAT_UYVY, 16, "16-bit packed UYVY (8:8:8:8 MSB-Y2:V:Y1:U)"},
+ {DRM_FORMAT_YVYU, 16, "16-bit packed YVYU (8:8:8:8 MSB-U:Y2:V:Y1)"},
+ {DRM_FORMAT_VYUY, 16, "16-bit packed VYUY (8:8:8:8 MSB-Y2:U:Y1:V)"},
+
+ {DRM_FORMAT_C8, 8, "8-bit Indexed"},
+ {DRM_FORMAT_RGB565, 16, "16-bit BGRX (5:6:5 MSB-R:G:B)"},
+ {DRM_FORMAT_ABGR8888, 32, "32-bit RGBA (8:8:8:8 MSB-A:B:G:R)"},
+ {DRM_FORMAT_XBGR8888, 32, "32-bit RGBX (8:8:8:8 MSB-X:B:G:R)"},
+
+ {DRM_FORMAT_ARGB8888, 32, "32-bit BGRA (8:8:8:8 MSB-A:R:G:B)"},
+ {DRM_FORMAT_XRGB8888, 32, "32-bit BGRX (8:8:8:8 MSB-X:R:G:B)"},
+ {DRM_FORMAT_XBGR2101010, 32, "32-bit RGBX (2:10:10:10 MSB-X:B:G:R)"},
+ {DRM_FORMAT_XRGB2101010, 32, "32-bit BGRX (2:10:10:10 MSB-X:R:G:B)"},
+
+ /* non-supported format has bpp default to 0 */
+ {0, 0, NULL},
+};
+
+static int bdw_format_to_drm(int format)
+{
+ int bdw_pixel_formats_index = 6;
+
+ switch (format) {
+ case DISPPLANE_8BPP:
+ bdw_pixel_formats_index = 0;
+ break;
+ case DISPPLANE_BGRX565:
+ bdw_pixel_formats_index = 1;
+ break;
+ case DISPPLANE_BGRX888:
+ bdw_pixel_formats_index = 2;
+ break;
+ case DISPPLANE_RGBX101010:
+ bdw_pixel_formats_index = 3;
+ break;
+ case DISPPLANE_BGRX101010:
+ bdw_pixel_formats_index = 4;
+ break;
+ case DISPPLANE_RGBX888:
+ bdw_pixel_formats_index = 5;
+ break;
+
+ default:
+ break;
+ }
+
+ return bdw_pixel_formats_index;
+}
+
+static int skl_format_to_drm(int format, bool rgb_order, bool alpha,
+ int yuv_order)
+{
+ int skl_pixel_formats_index = 12;
+
+ switch (format) {
+ case PLANE_CTL_FORMAT_INDEXED:
+ skl_pixel_formats_index = 4;
+ break;
+ case PLANE_CTL_FORMAT_RGB_565:
+ skl_pixel_formats_index = 5;
+ break;
+ case PLANE_CTL_FORMAT_XRGB_8888:
+ if (rgb_order)
+ skl_pixel_formats_index = alpha ? 6 : 7;
+ else
+ skl_pixel_formats_index = alpha ? 8 : 9;
+ break;
+ case PLANE_CTL_FORMAT_XRGB_2101010:
+ skl_pixel_formats_index = rgb_order ? 10 : 11;
+ break;
+ case PLANE_CTL_FORMAT_YUV422:
+ skl_pixel_formats_index = yuv_order >> 16;
+ if (skl_pixel_formats_index > 3)
+ return -EINVAL;
+ break;
+
+ default:
+ break;
+ }
+
+ return skl_pixel_formats_index;
+}
+
+static u32 intel_vgpu_get_stride(struct intel_vgpu *vgpu, int pipe,
+ u32 tiled, int stride_mask, int bpp)
+{
+ struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
+
+ u32 stride_reg = vgpu_vreg(vgpu, DSPSTRIDE(pipe)) & stride_mask;
+ u32 stride = stride_reg;
+
+ if (IS_SKYLAKE(dev_priv)) {
+ switch (tiled) {
+ case PLANE_CTL_TILED_LINEAR:
+ stride = stride_reg * 64;
+ break;
+ case PLANE_CTL_TILED_X:
+ stride = stride_reg * 512;
+ break;
+ case PLANE_CTL_TILED_Y:
+ stride = stride_reg * 128;
+ break;
+ case PLANE_CTL_TILED_YF:
+ if (bpp == 8)
+ stride = stride_reg * 64;
+ else if (bpp == 16 || bpp == 32 || bpp == 64)
+ stride = stride_reg * 128;
+ else
+ gvt_dbg_core("skl: unsupported bpp:%d\n", bpp);
+ break;
+ default:
+ gvt_dbg_core("skl: unsupported tile format:%x\n",
+ tiled);
+ }
+ }
+
+ return stride;
+}
+
+static int get_active_pipe(struct intel_vgpu *vgpu)
+{
+ int i;
+
+ for (i = 0; i < I915_MAX_PIPES; i++)
+ if (pipe_is_enabled(vgpu, i))
+ break;
+
+ return i;
+}
+
+/**
+ * intel_vgpu_decode_primary_plane - Decode primary plane
+ * @vgpu: input vgpu
+ * @plane: primary plane to save decoded info
+ * This function is called for decoding plane
+ *
+ * Returns:
+ * 0 on success, non-zero if failed.
+ */
+int intel_vgpu_decode_primary_plane(struct intel_vgpu *vgpu,
+ struct intel_vgpu_primary_plane_format *plane)
+{
+ u32 val, fmt;
+ struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
+ int pipe;
+
+ pipe = get_active_pipe(vgpu);
+ if (pipe >= I915_MAX_PIPES)
+ return -ENODEV;
+
+ val = vgpu_vreg(vgpu, DSPCNTR(pipe));
+ plane->enabled = !!(val & DISPLAY_PLANE_ENABLE);
+ if (!plane->enabled)
+ return -ENODEV;
+
+ if (IS_SKYLAKE(dev_priv)) {
+ plane->tiled = (val & PLANE_CTL_TILED_MASK) >>
+ _PLANE_CTL_TILED_SHIFT;
+ fmt = skl_format_to_drm(
+ val & PLANE_CTL_FORMAT_MASK,
+ val & PLANE_CTL_ORDER_RGBX,
+ val & PLANE_CTL_ALPHA_MASK,
+ val & PLANE_CTL_YUV422_ORDER_MASK);
+ plane->bpp = skl_pixel_formats[fmt].bpp;
+ plane->drm_format = skl_pixel_formats[fmt].drm_format;
+ } else {
+ plane->tiled = !!(val & DISPPLANE_TILED);
+ fmt = bdw_format_to_drm(val & DISPPLANE_PIXFORMAT_MASK);
+ plane->bpp = bdw_pixel_formats[fmt].bpp;
+ plane->drm_format = bdw_pixel_formats[fmt].drm_format;
+ }
+
+ if (!plane->bpp) {
+ gvt_vgpu_err("Non-supported pixel format (0x%x)\n", fmt);
+ return -EINVAL;
+ }
+
+ plane->hw_format = fmt;
+
+ plane->base = vgpu_vreg(vgpu, DSPSURF(pipe)) & I915_GTT_PAGE_MASK;
+ if (!intel_gvt_ggtt_validate_range(vgpu, plane->base, 0)) {
+ gvt_vgpu_err("invalid gma address: %lx\n",
+ (unsigned long)plane->base);
+ return -EINVAL;
+ }
+
+ plane->base_gpa = intel_vgpu_gma_to_gpa(vgpu->gtt.ggtt_mm, plane->base);
+ if (plane->base_gpa == INTEL_GVT_INVALID_ADDR) {
+ gvt_vgpu_err("invalid gma address: %lx\n",
+ (unsigned long)plane->base);
+ return -EINVAL;
+ }
+
+ plane->stride = intel_vgpu_get_stride(vgpu, pipe, (plane->tiled << 10),
+ (IS_SKYLAKE(dev_priv)) ? (_PRI_PLANE_STRIDE_MASK >> 6) :
+ _PRI_PLANE_STRIDE_MASK, plane->bpp);
+
+ plane->width = (vgpu_vreg(vgpu, PIPESRC(pipe)) & _PIPE_H_SRCSZ_MASK) >>
+ _PIPE_H_SRCSZ_SHIFT;
+ plane->width += 1;
+ plane->height = (vgpu_vreg(vgpu, PIPESRC(pipe)) &
+ _PIPE_V_SRCSZ_MASK) >> _PIPE_V_SRCSZ_SHIFT;
+ plane->height += 1; /* raw height is one minus the real value */
+
+ val = vgpu_vreg(vgpu, DSPTILEOFF(pipe));
+ plane->x_offset = (val & _PRI_PLANE_X_OFF_MASK) >>
+ _PRI_PLANE_X_OFF_SHIFT;
+ plane->y_offset = (val & _PRI_PLANE_Y_OFF_MASK) >>
+ _PRI_PLANE_Y_OFF_SHIFT;
+
+ return 0;
+}
+
+#define CURSOR_FORMAT_NUM (1 << 6)
+struct cursor_mode_format {
+ int drm_format; /* Pixel format in DRM definition */
+ u8 bpp; /* Bits per pixel; 0 indicates invalid */
+ u32 width; /* In pixel */
+ u32 height; /* In lines */
+ char *desc; /* The description */
+};
+
+static struct cursor_mode_format cursor_pixel_formats[] = {
+ {DRM_FORMAT_ARGB8888, 32, 128, 128, "128x128 32bpp ARGB"},
+ {DRM_FORMAT_ARGB8888, 32, 256, 256, "256x256 32bpp ARGB"},
+ {DRM_FORMAT_ARGB8888, 32, 64, 64, "64x64 32bpp ARGB"},
+ {DRM_FORMAT_ARGB8888, 32, 64, 64, "64x64 32bpp ARGB"},
+
+ /* non-supported format has bpp default to 0 */
+ {0, 0, 0, 0, NULL},
+};
+
+static int cursor_mode_to_drm(int mode)
+{
+ int cursor_pixel_formats_index = 4;
+
+ switch (mode) {
+ case CURSOR_MODE_128_ARGB_AX:
+ cursor_pixel_formats_index = 0;
+ break;
+ case CURSOR_MODE_256_ARGB_AX:
+ cursor_pixel_formats_index = 1;
+ break;
+ case CURSOR_MODE_64_ARGB_AX:
+ cursor_pixel_formats_index = 2;
+ break;
+ case CURSOR_MODE_64_32B_AX:
+ cursor_pixel_formats_index = 3;
+ break;
+
+ default:
+ break;
+ }
+
+ return cursor_pixel_formats_index;
+}
+
+/**
+ * intel_vgpu_decode_cursor_plane - Decode sprite plane
+ * @vgpu: input vgpu
+ * @plane: cursor plane to save decoded info
+ * This function is called for decoding plane
+ *
+ * Returns:
+ * 0 on success, non-zero if failed.
+ */
+int intel_vgpu_decode_cursor_plane(struct intel_vgpu *vgpu,
+ struct intel_vgpu_cursor_plane_format *plane)
+{
+ u32 val, mode, index;
+ u32 alpha_plane, alpha_force;
+ struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
+ int pipe;
+
+ pipe = get_active_pipe(vgpu);
+ if (pipe >= I915_MAX_PIPES)
+ return -ENODEV;
+
+ val = vgpu_vreg(vgpu, CURCNTR(pipe));
+ mode = val & CURSOR_MODE;
+ plane->enabled = (mode != CURSOR_MODE_DISABLE);
+ if (!plane->enabled)
+ return -ENODEV;
+
+ index = cursor_mode_to_drm(mode);
+
+ if (!cursor_pixel_formats[index].bpp) {
+ gvt_vgpu_err("Non-supported cursor mode (0x%x)\n", mode);
+ return -EINVAL;
+ }
+ plane->mode = mode;
+ plane->bpp = cursor_pixel_formats[index].bpp;
+ plane->drm_format = cursor_pixel_formats[index].drm_format;
+ plane->width = cursor_pixel_formats[index].width;
+ plane->height = cursor_pixel_formats[index].height;
+
+ alpha_plane = (val & _CURSOR_ALPHA_PLANE_MASK) >>
+ _CURSOR_ALPHA_PLANE_SHIFT;
+ alpha_force = (val & _CURSOR_ALPHA_FORCE_MASK) >>
+ _CURSOR_ALPHA_FORCE_SHIFT;
+ if (alpha_plane || alpha_force)
+ gvt_dbg_core("alpha_plane=0x%x, alpha_force=0x%x\n",
+ alpha_plane, alpha_force);
+
+ plane->base = vgpu_vreg(vgpu, CURBASE(pipe)) & I915_GTT_PAGE_MASK;
+ if (!intel_gvt_ggtt_validate_range(vgpu, plane->base, 0)) {
+ gvt_vgpu_err("invalid gma address: %lx\n",
+ (unsigned long)plane->base);
+ return -EINVAL;
+ }
+
+ plane->base_gpa = intel_vgpu_gma_to_gpa(vgpu->gtt.ggtt_mm, plane->base);
+ if (plane->base_gpa == INTEL_GVT_INVALID_ADDR) {
+ gvt_vgpu_err("invalid gma address: %lx\n",
+ (unsigned long)plane->base);
+ return -EINVAL;
+ }
+
+ val = vgpu_vreg(vgpu, CURPOS(pipe));
+ plane->x_pos = (val & _CURSOR_POS_X_MASK) >> _CURSOR_POS_X_SHIFT;
+ plane->x_sign = (val & _CURSOR_SIGN_X_MASK) >> _CURSOR_SIGN_X_SHIFT;
+ plane->y_pos = (val & _CURSOR_POS_Y_MASK) >> _CURSOR_POS_Y_SHIFT;
+ plane->y_sign = (val & _CURSOR_SIGN_Y_MASK) >> _CURSOR_SIGN_Y_SHIFT;
+
+ return 0;
+}
+
+#define SPRITE_FORMAT_NUM (1 << 3)
+
+static struct pixel_format sprite_pixel_formats[SPRITE_FORMAT_NUM] = {
+ [0x0] = {DRM_FORMAT_YUV422, 16, "YUV 16-bit 4:2:2 packed"},
+ [0x1] = {DRM_FORMAT_XRGB2101010, 32, "RGB 32-bit 2:10:10:10"},
+ [0x2] = {DRM_FORMAT_XRGB8888, 32, "RGB 32-bit 8:8:8:8"},
+ [0x4] = {DRM_FORMAT_AYUV, 32,
+ "YUV 32-bit 4:4:4 packed (8:8:8:8 MSB-X:Y:U:V)"},
+};
+
+/**
+ * intel_vgpu_decode_sprite_plane - Decode sprite plane
+ * @vgpu: input vgpu
+ * @plane: sprite plane to save decoded info
+ * This function is called for decoding plane
+ *
+ * Returns:
+ * 0 on success, non-zero if failed.
+ */
+int intel_vgpu_decode_sprite_plane(struct intel_vgpu *vgpu,
+ struct intel_vgpu_sprite_plane_format *plane)
+{
+ u32 val, fmt;
+ u32 color_order, yuv_order;
+ int drm_format;
+ int pipe;
+
+ pipe = get_active_pipe(vgpu);
+ if (pipe >= I915_MAX_PIPES)
+ return -ENODEV;
+
+ val = vgpu_vreg(vgpu, SPRCTL(pipe));
+ plane->enabled = !!(val & SPRITE_ENABLE);
+ if (!plane->enabled)
+ return -ENODEV;
+
+ plane->tiled = !!(val & SPRITE_TILED);
+ color_order = !!(val & SPRITE_RGB_ORDER_RGBX);
+ yuv_order = (val & SPRITE_YUV_BYTE_ORDER_MASK) >>
+ _SPRITE_YUV_ORDER_SHIFT;
+
+ fmt = (val & SPRITE_PIXFORMAT_MASK) >> _SPRITE_FMT_SHIFT;
+ if (!sprite_pixel_formats[fmt].bpp) {
+ gvt_vgpu_err("Non-supported pixel format (0x%x)\n", fmt);
+ return -EINVAL;
+ }
+ plane->hw_format = fmt;
+ plane->bpp = sprite_pixel_formats[fmt].bpp;
+ drm_format = sprite_pixel_formats[fmt].drm_format;
+
+ /* Order of RGB values in an RGBxxx buffer may be ordered RGB or
+ * BGR depending on the state of the color_order field
+ */
+ if (!color_order) {
+ if (drm_format == DRM_FORMAT_XRGB2101010)
+ drm_format = DRM_FORMAT_XBGR2101010;
+ else if (drm_format == DRM_FORMAT_XRGB8888)
+ drm_format = DRM_FORMAT_XBGR8888;
+ }
+
+ if (drm_format == DRM_FORMAT_YUV422) {
+ switch (yuv_order) {
+ case 0:
+ drm_format = DRM_FORMAT_YUYV;
+ break;
+ case 1:
+ drm_format = DRM_FORMAT_UYVY;
+ break;
+ case 2:
+ drm_format = DRM_FORMAT_YVYU;
+ break;
+ case 3:
+ drm_format = DRM_FORMAT_VYUY;
+ break;
+ default:
+ /* yuv_order has only 2 bits */
+ break;
+ }
+ }
+
+ plane->drm_format = drm_format;
+
+ plane->base = vgpu_vreg(vgpu, SPRSURF(pipe)) & I915_GTT_PAGE_MASK;
+ if (!intel_gvt_ggtt_validate_range(vgpu, plane->base, 0)) {
+ gvt_vgpu_err("invalid gma address: %lx\n",
+ (unsigned long)plane->base);
+ return -EINVAL;
+ }
+
+ plane->base_gpa = intel_vgpu_gma_to_gpa(vgpu->gtt.ggtt_mm, plane->base);
+ if (plane->base_gpa == INTEL_GVT_INVALID_ADDR) {
+ gvt_vgpu_err("invalid gma address: %lx\n",
+ (unsigned long)plane->base);
+ return -EINVAL;
+ }
+
+ plane->stride = vgpu_vreg(vgpu, SPRSTRIDE(pipe)) &
+ _SPRITE_STRIDE_MASK;
+
+ val = vgpu_vreg(vgpu, SPRSIZE(pipe));
+ plane->height = (val & _SPRITE_SIZE_HEIGHT_MASK) >>
+ _SPRITE_SIZE_HEIGHT_SHIFT;
+ plane->width = (val & _SPRITE_SIZE_WIDTH_MASK) >>
+ _SPRITE_SIZE_WIDTH_SHIFT;
+ plane->height += 1; /* raw height is one minus the real value */
+ plane->width += 1; /* raw width is one minus the real value */
+
+ val = vgpu_vreg(vgpu, SPRPOS(pipe));
+ plane->x_pos = (val & _SPRITE_POS_X_MASK) >> _SPRITE_POS_X_SHIFT;
+ plane->y_pos = (val & _SPRITE_POS_Y_MASK) >> _SPRITE_POS_Y_SHIFT;
+
+ val = vgpu_vreg(vgpu, SPROFFSET(pipe));
+ plane->x_offset = (val & _SPRITE_OFFSET_START_X_MASK) >>
+ _SPRITE_OFFSET_START_X_SHIFT;
+ plane->y_offset = (val & _SPRITE_OFFSET_START_Y_MASK) >>
+ _SPRITE_OFFSET_START_Y_SHIFT;
+
+ return 0;
+}
diff --git a/drivers/gpu/drm/i915/gvt/fb_decoder.h b/drivers/gpu/drm/i915/gvt/fb_decoder.h
new file mode 100644
index 0000000..cb055f3
--- /dev/null
+++ b/drivers/gpu/drm/i915/gvt/fb_decoder.h
@@ -0,0 +1,169 @@
+/*
+ * Copyright(c) 2011-2016 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Kevin Tian <kevin.tian@intel.com>
+ *
+ * Contributors:
+ * Bing Niu <bing.niu@intel.com>
+ * Xu Han <xu.han@intel.com>
+ * Ping Gao <ping.a.gao@intel.com>
+ * Xiaoguang Chen <xiaoguang.chen@intel.com>
+ * Yang Liu <yang2.liu@intel.com>
+ * Tina Zhang <tina.zhang@intel.com>
+ *
+ */
+
+#ifndef _GVT_FB_DECODER_H_
+#define _GVT_FB_DECODER_H_
+
+#define _PLANE_CTL_FORMAT_SHIFT 24
+#define _PLANE_CTL_TILED_SHIFT 10
+#define _PIPE_V_SRCSZ_SHIFT 0
+#define _PIPE_V_SRCSZ_MASK (0xfff << _PIPE_V_SRCSZ_SHIFT)
+#define _PIPE_H_SRCSZ_SHIFT 16
+#define _PIPE_H_SRCSZ_MASK (0x1fff << _PIPE_H_SRCSZ_SHIFT)
+
+#define _PRI_PLANE_FMT_SHIFT 26
+#define _PRI_PLANE_STRIDE_MASK (0x3ff << 6)
+#define _PRI_PLANE_X_OFF_SHIFT 0
+#define _PRI_PLANE_X_OFF_MASK (0x1fff << _PRI_PLANE_X_OFF_SHIFT)
+#define _PRI_PLANE_Y_OFF_SHIFT 16
+#define _PRI_PLANE_Y_OFF_MASK (0xfff << _PRI_PLANE_Y_OFF_SHIFT)
+
+#define _CURSOR_MODE 0x3f
+#define _CURSOR_ALPHA_FORCE_SHIFT 8
+#define _CURSOR_ALPHA_FORCE_MASK (0x3 << _CURSOR_ALPHA_FORCE_SHIFT)
+#define _CURSOR_ALPHA_PLANE_SHIFT 10
+#define _CURSOR_ALPHA_PLANE_MASK (0x3 << _CURSOR_ALPHA_PLANE_SHIFT)
+#define _CURSOR_POS_X_SHIFT 0
+#define _CURSOR_POS_X_MASK (0x1fff << _CURSOR_POS_X_SHIFT)
+#define _CURSOR_SIGN_X_SHIFT 15
+#define _CURSOR_SIGN_X_MASK (1 << _CURSOR_SIGN_X_SHIFT)
+#define _CURSOR_POS_Y_SHIFT 16
+#define _CURSOR_POS_Y_MASK (0xfff << _CURSOR_POS_Y_SHIFT)
+#define _CURSOR_SIGN_Y_SHIFT 31
+#define _CURSOR_SIGN_Y_MASK (1 << _CURSOR_SIGN_Y_SHIFT)
+
+#define _SPRITE_FMT_SHIFT 25
+#define _SPRITE_COLOR_ORDER_SHIFT 20
+#define _SPRITE_YUV_ORDER_SHIFT 16
+#define _SPRITE_STRIDE_SHIFT 6
+#define _SPRITE_STRIDE_MASK (0x1ff << _SPRITE_STRIDE_SHIFT)
+#define _SPRITE_SIZE_WIDTH_SHIFT 0
+#define _SPRITE_SIZE_HEIGHT_SHIFT 16
+#define _SPRITE_SIZE_WIDTH_MASK (0x1fff << _SPRITE_SIZE_WIDTH_SHIFT)
+#define _SPRITE_SIZE_HEIGHT_MASK (0xfff << _SPRITE_SIZE_HEIGHT_SHIFT)
+#define _SPRITE_POS_X_SHIFT 0
+#define _SPRITE_POS_Y_SHIFT 16
+#define _SPRITE_POS_X_MASK (0x1fff << _SPRITE_POS_X_SHIFT)
+#define _SPRITE_POS_Y_MASK (0xfff << _SPRITE_POS_Y_SHIFT)
+#define _SPRITE_OFFSET_START_X_SHIFT 0
+#define _SPRITE_OFFSET_START_Y_SHIFT 16
+#define _SPRITE_OFFSET_START_X_MASK (0x1fff << _SPRITE_OFFSET_START_X_SHIFT)
+#define _SPRITE_OFFSET_START_Y_MASK (0xfff << _SPRITE_OFFSET_START_Y_SHIFT)
+
+enum GVT_FB_EVENT {
+ FB_MODE_SET_START = 1,
+ FB_MODE_SET_END,
+ FB_DISPLAY_FLIP,
+};
+
+enum DDI_PORT {
+ DDI_PORT_NONE = 0,
+ DDI_PORT_B = 1,
+ DDI_PORT_C = 2,
+ DDI_PORT_D = 3,
+ DDI_PORT_E = 4
+};
+
+struct intel_gvt;
+
+/* color space conversion and gamma correction are not included */
+struct intel_vgpu_primary_plane_format {
+ u8 enabled; /* plane is enabled */
+ u8 tiled; /* X-tiled */
+ u8 bpp; /* bits per pixel */
+ u32 hw_format; /* format field in the PRI_CTL register */
+ u32 drm_format; /* format in DRM definition */
+ u32 base; /* framebuffer base in graphics memory */
+ u64 base_gpa;
+ u32 x_offset; /* in pixels */
+ u32 y_offset; /* in lines */
+ u32 width; /* in pixels */
+ u32 height; /* in lines */
+ u32 stride; /* in bytes */
+};
+
+struct intel_vgpu_sprite_plane_format {
+ u8 enabled; /* plane is enabled */
+ u8 tiled; /* X-tiled */
+ u8 bpp; /* bits per pixel */
+ u32 hw_format; /* format field in the SPR_CTL register */
+ u32 drm_format; /* format in DRM definition */
+ u32 base; /* sprite base in graphics memory */
+ u64 base_gpa;
+ u32 x_pos; /* in pixels */
+ u32 y_pos; /* in lines */
+ u32 x_offset; /* in pixels */
+ u32 y_offset; /* in lines */
+ u32 width; /* in pixels */
+ u32 height; /* in lines */
+ u32 stride; /* in bytes */
+};
+
+struct intel_vgpu_cursor_plane_format {
+ u8 enabled;
+ u8 mode; /* cursor mode select */
+ u8 bpp; /* bits per pixel */
+ u32 drm_format; /* format in DRM definition */
+ u32 base; /* cursor base in graphics memory */
+ u64 base_gpa;
+ u32 x_pos; /* in pixels */
+ u32 y_pos; /* in lines */
+ u8 x_sign; /* X Position Sign */
+ u8 y_sign; /* Y Position Sign */
+ u32 width; /* in pixels */
+ u32 height; /* in lines */
+ u32 x_hot; /* in pixels */
+ u32 y_hot; /* in pixels */
+};
+
+struct intel_vgpu_pipe_format {
+ struct intel_vgpu_primary_plane_format primary;
+ struct intel_vgpu_sprite_plane_format sprite;
+ struct intel_vgpu_cursor_plane_format cursor;
+ enum DDI_PORT ddi_port; /* the DDI port that pipe is connected to */
+};
+
+struct intel_vgpu_fb_format {
+ struct intel_vgpu_pipe_format pipes[I915_MAX_PIPES];
+};
+
+int intel_vgpu_decode_primary_plane(struct intel_vgpu *vgpu,
+ struct intel_vgpu_primary_plane_format *plane);
+int intel_vgpu_decode_cursor_plane(struct intel_vgpu *vgpu,
+ struct intel_vgpu_cursor_plane_format *plane);
+int intel_vgpu_decode_sprite_plane(struct intel_vgpu *vgpu,
+ struct intel_vgpu_sprite_plane_format *plane);
+
+#endif
diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h
index 27e8186..c8e496c 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.h
+++ b/drivers/gpu/drm/i915/gvt/gvt.h
@@ -46,6 +46,7 @@
#include "sched_policy.h"
#include "render.h"
#include "cmd_parser.h"
+#include "fb_decoder.h"
#define GVT_MAX_VGPU 8
--
2.7.4
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH v18 2/6] drm: Introduce RGB 64-bit 16:16:16:16 float format
2017-11-15 9:11 [PATCH v18 0/6] drm/i915/gvt: Dma-buf support for GVT-g Tina Zhang
2017-11-15 9:11 ` [PATCH v18 1/6] drm/i915/gvt: Add framebuffer decoder support Tina Zhang
@ 2017-11-15 9:11 ` Tina Zhang
2017-11-15 9:11 ` [PATCH v18 3/6] drm/i915/gvt: Add " Tina Zhang
` (4 subsequent siblings)
6 siblings, 0 replies; 19+ messages in thread
From: Tina Zhang @ 2017-11-15 9:11 UTC (permalink / raw)
To: alex.williamson, kraxel, chris, joonas.lahtinen, zhenyuw,
zhiyuan.lv, zhi.a.wang, kevin.tian, daniel, kwankhede, hang.yuan
Cc: Tina Zhang, intel-gfx, intel-gvt-dev, linux-kernel,
Ville Syrjälä,
Dave Airlie, Daniel Vetter
The RGB 64-bit 16:16:16:16 float pixel format is needed by some Apps in
windows. The float format in each component is 1:5:10 MSb-sign:exponent:
fraction.
This patch is to introduce the format to drm, so that the windows guest's
framebuffer in this kind of format can be recognized and used by linux
host.
v14:
- add some details about the float pixel format. (Daniel)
- add F suffix to the defined name. (Daniel)
v12:
- send to dri-devel at lists.freedesktop.org. (Ville)
v9:
- separated from framebuffer decoder patch. (Zhenyu) (Xiaoguang)
Signed-off-by: Tina Zhang <tina.zhang@intel.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Dave Airlie <airlied@redhat.com>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
---
include/uapi/drm/drm_fourcc.h | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
index 3ad838d..391d2e6 100644
--- a/include/uapi/drm/drm_fourcc.h
+++ b/include/uapi/drm/drm_fourcc.h
@@ -113,6 +113,10 @@ extern "C" {
#define DRM_FORMAT_AYUV fourcc_code('A', 'Y', 'U', 'V') /* [31:0] A:Y:Cb:Cr 8:8:8:8 little endian */
+/* 64 bpp RGB 16:16:16:16 Floating Point */
+#define DRM_FORMAT_XRGB161616F fourcc_code('X', 'R', '3', 'F') /* [63:0] x:R:G:B 16:16:16:16 little endian */
+#define DRM_FORMAT_XBGR161616F fourcc_code('X', 'B', '3', 'F') /* [63:0] x:B:G:R 16:16:16:16 little endian */
+
/*
* 2 plane RGB + A
* index 0 = RGB plane, same format as the corresponding non _A8 format has
--
2.7.4
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH v18 3/6] drm/i915/gvt: Add RGB 64-bit 16:16:16:16 float format
2017-11-15 9:11 [PATCH v18 0/6] drm/i915/gvt: Dma-buf support for GVT-g Tina Zhang
2017-11-15 9:11 ` [PATCH v18 1/6] drm/i915/gvt: Add framebuffer decoder support Tina Zhang
2017-11-15 9:11 ` [PATCH v18 2/6] drm: Introduce RGB 64-bit 16:16:16:16 float format Tina Zhang
@ 2017-11-15 9:11 ` Tina Zhang
2017-11-15 9:11 ` [PATCH v18 4/6] drm/i915/gvt: Add opregion support Tina Zhang
` (3 subsequent siblings)
6 siblings, 0 replies; 19+ messages in thread
From: Tina Zhang @ 2017-11-15 9:11 UTC (permalink / raw)
To: alex.williamson, kraxel, chris, joonas.lahtinen, zhenyuw,
zhiyuan.lv, zhi.a.wang, kevin.tian, daniel, kwankhede, hang.yuan
Cc: Tina Zhang, intel-gfx, intel-gvt-dev, linux-kernel
The RGB 64-bit 16:16:16:16 float pixel format is needed by windows 10
guest VM. This patch is to add this pixel format support to gvt device
model. Without this patch, some Apps, e.g. "DXGIGammaVM.exe", will crash
and make guest screen black.
Signed-off-by: Tina Zhang <tina.zhang@intel.com>
---
drivers/gpu/drm/i915/gvt/fb_decoder.c | 28 +++++++++++++++++++++-------
1 file changed, 21 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/i915/gvt/fb_decoder.c b/drivers/gpu/drm/i915/gvt/fb_decoder.c
index 6c99c64..b9e0d8e 100644
--- a/drivers/gpu/drm/i915/gvt/fb_decoder.c
+++ b/drivers/gpu/drm/i915/gvt/fb_decoder.c
@@ -52,6 +52,8 @@ static struct pixel_format bdw_pixel_formats[] = {
{DRM_FORMAT_XRGB2101010, 32, "32-bit BGRX (2:10:10:10 MSB-X:R:G:B)"},
{DRM_FORMAT_XBGR8888, 32, "32-bit RGBX (8:8:8:8 MSB-X:B:G:R)"},
+ {DRM_FORMAT_XRGB161616F, 64,
+ "64-bit XRGB Floating Point (16:16:16:16 MSB-X:R:G:B)"},
/* non-supported format has bpp default to 0 */
{0, 0, NULL},
@@ -73,13 +75,18 @@ static struct pixel_format skl_pixel_formats[] = {
{DRM_FORMAT_XBGR2101010, 32, "32-bit RGBX (2:10:10:10 MSB-X:B:G:R)"},
{DRM_FORMAT_XRGB2101010, 32, "32-bit BGRX (2:10:10:10 MSB-X:R:G:B)"},
+ {DRM_FORMAT_XRGB161616F, 64,
+ "64-bit XRGB Floating Point (16:16:16:16 MSB-X:R:G:B)"},
+ {DRM_FORMAT_XBGR161616F, 64,
+ "64-bit XBGR Floating Point (16:16:16:16 MSB-X:B:G:R)"},
+
/* non-supported format has bpp default to 0 */
{0, 0, NULL},
};
static int bdw_format_to_drm(int format)
{
- int bdw_pixel_formats_index = 6;
+ int bdw_pixel_formats_index = 7;
switch (format) {
case DISPPLANE_8BPP:
@@ -100,7 +107,9 @@ static int bdw_format_to_drm(int format)
case DISPPLANE_RGBX888:
bdw_pixel_formats_index = 5;
break;
-
+ case DISPPLANE_RGBX161616:
+ bdw_pixel_formats_index = 6;
+ break;
default:
break;
}
@@ -111,7 +120,7 @@ static int bdw_format_to_drm(int format)
static int skl_format_to_drm(int format, bool rgb_order, bool alpha,
int yuv_order)
{
- int skl_pixel_formats_index = 12;
+ int skl_pixel_formats_index = 14;
switch (format) {
case PLANE_CTL_FORMAT_INDEXED:
@@ -129,6 +138,9 @@ static int skl_format_to_drm(int format, bool rgb_order, bool alpha,
case PLANE_CTL_FORMAT_XRGB_2101010:
skl_pixel_formats_index = rgb_order ? 10 : 11;
break;
+ case PLANE_CTL_FORMAT_XRGB_16161616F:
+ skl_pixel_formats_index = rgb_order ? 12 : 13;
+ break;
case PLANE_CTL_FORMAT_YUV422:
skl_pixel_formats_index = yuv_order >> 16;
if (skl_pixel_formats_index > 3)
@@ -389,11 +401,13 @@ int intel_vgpu_decode_cursor_plane(struct intel_vgpu *vgpu,
#define SPRITE_FORMAT_NUM (1 << 3)
static struct pixel_format sprite_pixel_formats[SPRITE_FORMAT_NUM] = {
- [0x0] = {DRM_FORMAT_YUV422, 16, "YUV 16-bit 4:2:2 packed"},
- [0x1] = {DRM_FORMAT_XRGB2101010, 32, "RGB 32-bit 2:10:10:10"},
- [0x2] = {DRM_FORMAT_XRGB8888, 32, "RGB 32-bit 8:8:8:8"},
+ [0x0] = {DRM_FORMAT_YUV422, 16, "16-bit YUV 4:2:2 packed"},
+ [0x1] = {DRM_FORMAT_XRGB2101010, 32, "32-bit BGRX (2:10:10:10 MSB-X:R:G:B)"},
+ [0x2] = {DRM_FORMAT_XRGB8888, 32, "32-bit RGBX (8:8:8:8 MSB-X:B:G:R)"},
+ [0x3] = {DRM_FORMAT_XRGB161616F, 64,
+ "64-bit XRGB Floating Point (16:16:16:16 MSB-X:R:G:B)"},
[0x4] = {DRM_FORMAT_AYUV, 32,
- "YUV 32-bit 4:4:4 packed (8:8:8:8 MSB-X:Y:U:V)"},
+ "32-bit YUV 4:4:4 packed (8:8:8:8 MSB-X:Y:U:V)"},
};
/**
--
2.7.4
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH v18 4/6] drm/i915/gvt: Add opregion support
2017-11-15 9:11 [PATCH v18 0/6] drm/i915/gvt: Dma-buf support for GVT-g Tina Zhang
` (2 preceding siblings ...)
2017-11-15 9:11 ` [PATCH v18 3/6] drm/i915/gvt: Add " Tina Zhang
@ 2017-11-15 9:11 ` Tina Zhang
2017-11-15 9:11 ` [PATCH v18 5/6] vfio: ABI for mdev display dma-buf operation Tina Zhang
` (2 subsequent siblings)
6 siblings, 0 replies; 19+ messages in thread
From: Tina Zhang @ 2017-11-15 9:11 UTC (permalink / raw)
To: alex.williamson, kraxel, chris, joonas.lahtinen, zhenyuw,
zhiyuan.lv, zhi.a.wang, kevin.tian, daniel, kwankhede, hang.yuan
Cc: Tina Zhang, intel-gfx, intel-gvt-dev, linux-kernel, Bing Niu
Windows guest driver needs vbt in opregion, to configure the setting
for display. Without opregion support, the display registers won't
be set and this blocks display model to get the correct information
of the guest display plane.
This patch is to provide a virtual opregion for guest. Current
implementation is to fill the virtual opregion with the content in
host's opregion. The original author of this patch is Xiaoguang Chen.
v18:
- unmap vgpu's opregion when destroying vgpu.
v16:
- rebase to 4.14.0-rc6.
Signed-off-by: Bing Niu <bing.niu@intel.com>
Signed-off-by: Tina Zhang <tina.zhang@intel.com>
---
drivers/gpu/drm/i915/gvt/hypercall.h | 1 +
drivers/gpu/drm/i915/gvt/kvmgt.c | 104 ++++++++++++++++++++++++++++++++++-
drivers/gpu/drm/i915/gvt/mpt.h | 15 +++++
drivers/gpu/drm/i915/gvt/opregion.c | 29 ++++++++--
drivers/gpu/drm/i915/gvt/vgpu.c | 4 ++
5 files changed, 144 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/i915/gvt/hypercall.h b/drivers/gpu/drm/i915/gvt/hypercall.h
index df7f33a..32c345c 100644
--- a/drivers/gpu/drm/i915/gvt/hypercall.h
+++ b/drivers/gpu/drm/i915/gvt/hypercall.h
@@ -55,6 +55,7 @@ struct intel_gvt_mpt {
unsigned long mfn, unsigned int nr, bool map);
int (*set_trap_area)(unsigned long handle, u64 start, u64 end,
bool map);
+ int (*set_opregion)(void *vgpu);
};
extern struct intel_gvt_mpt xengt_mpt;
diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 110f07e..7875bc0 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -53,11 +53,23 @@ static const struct intel_gvt_ops *intel_gvt_ops;
#define VFIO_PCI_INDEX_TO_OFFSET(index) ((u64)(index) << VFIO_PCI_OFFSET_SHIFT)
#define VFIO_PCI_OFFSET_MASK (((u64)(1) << VFIO_PCI_OFFSET_SHIFT) - 1)
+#define OPREGION_SIGNATURE "IntelGraphicsMem"
+
+struct vfio_region;
+struct intel_vgpu_regops {
+ size_t (*rw)(struct intel_vgpu *vgpu, char *buf,
+ size_t count, loff_t *ppos, bool iswrite);
+ void (*release)(struct intel_vgpu *vgpu,
+ struct vfio_region *region);
+};
+
struct vfio_region {
u32 type;
u32 subtype;
size_t size;
u32 flags;
+ const struct intel_vgpu_regops *ops;
+ void *data;
};
struct kvmgt_pgfn {
@@ -316,6 +328,86 @@ static void kvmgt_protect_table_del(struct kvmgt_guest_info *info,
}
}
+static size_t intel_vgpu_reg_rw_opregion(struct intel_vgpu *vgpu, char *buf,
+ size_t count, loff_t *ppos, bool iswrite)
+{
+ unsigned int i = VFIO_PCI_OFFSET_TO_INDEX(*ppos) -
+ VFIO_PCI_NUM_REGIONS;
+ void *base = vgpu->vdev.region[i].data;
+ loff_t pos = *ppos & VFIO_PCI_OFFSET_MASK;
+
+ if (pos >= vgpu->vdev.region[i].size || iswrite) {
+ gvt_vgpu_err("invalid op or offset for Intel vgpu OpRegion\n");
+ return -EINVAL;
+ }
+ count = min(count, (size_t)(vgpu->vdev.region[i].size - pos));
+ memcpy(buf, base + pos, count);
+
+ return count;
+}
+
+static void intel_vgpu_reg_release_opregion(struct intel_vgpu *vgpu,
+ struct vfio_region *region)
+{
+ memunmap(region->data);
+}
+
+static const struct intel_vgpu_regops intel_vgpu_regops_opregion = {
+ .rw = intel_vgpu_reg_rw_opregion,
+ .release = intel_vgpu_reg_release_opregion,
+};
+
+static int intel_vgpu_register_reg(struct intel_vgpu *vgpu,
+ unsigned int type, unsigned int subtype,
+ const struct intel_vgpu_regops *ops,
+ size_t size, u32 flags, void *data)
+{
+ struct vfio_region *region;
+
+ region = krealloc(vgpu->vdev.region,
+ (vgpu->vdev.num_regions + 1) * sizeof(*region),
+ GFP_KERNEL);
+ if (!region)
+ return -ENOMEM;
+
+ vgpu->vdev.region = region;
+ vgpu->vdev.region[vgpu->vdev.num_regions].type = type;
+ vgpu->vdev.region[vgpu->vdev.num_regions].subtype = subtype;
+ vgpu->vdev.region[vgpu->vdev.num_regions].ops = ops;
+ vgpu->vdev.region[vgpu->vdev.num_regions].size = size;
+ vgpu->vdev.region[vgpu->vdev.num_regions].flags = flags;
+ vgpu->vdev.region[vgpu->vdev.num_regions].data = data;
+ vgpu->vdev.num_regions++;
+
+ return 0;
+}
+
+static int kvmgt_set_opregion(void *p_vgpu)
+{
+ struct intel_vgpu *vgpu = (struct intel_vgpu *)p_vgpu;
+ void *base;
+ int ret;
+
+ base = vgpu->gvt->opregion.opregion_va;
+ if (!base)
+ return -ENOMEM;
+
+ if (memcmp(base, OPREGION_SIGNATURE, 16)) {
+ memunmap(base);
+ return -EINVAL;
+ }
+
+ ret = intel_vgpu_register_reg(vgpu,
+ PCI_VENDOR_ID_INTEL | VFIO_REGION_TYPE_PCI_VENDOR_TYPE,
+ VFIO_REGION_SUBTYPE_INTEL_IGD_OPREGION,
+ &intel_vgpu_regops_opregion, OPREGION_SIZE,
+ VFIO_REGION_INFO_FLAG_READ, base);
+ if (ret)
+ memunmap(base);
+
+ return ret;
+}
+
static int intel_vgpu_create(struct kobject *kobj, struct mdev_device *mdev)
{
struct intel_vgpu *vgpu = NULL;
@@ -546,7 +638,7 @@ static ssize_t intel_vgpu_rw(struct mdev_device *mdev, char *buf,
int ret = -EINVAL;
- if (index >= VFIO_PCI_NUM_REGIONS) {
+ if (index >= VFIO_PCI_NUM_REGIONS + vgpu->vdev.num_regions) {
gvt_vgpu_err("invalid index: %u\n", index);
return -EINVAL;
}
@@ -574,8 +666,11 @@ static ssize_t intel_vgpu_rw(struct mdev_device *mdev, char *buf,
case VFIO_PCI_BAR5_REGION_INDEX:
case VFIO_PCI_VGA_REGION_INDEX:
case VFIO_PCI_ROM_REGION_INDEX:
+ break;
default:
- gvt_vgpu_err("unsupported region: %u\n", index);
+ index -= VFIO_PCI_NUM_REGIONS;
+ return vgpu->vdev.region[index].ops->rw(vgpu, buf, count,
+ ppos, is_write);
}
return ret == 0 ? count : ret;
@@ -838,7 +933,8 @@ static long intel_vgpu_ioctl(struct mdev_device *mdev, unsigned int cmd,
info.flags = VFIO_DEVICE_FLAGS_PCI;
info.flags |= VFIO_DEVICE_FLAGS_RESET;
- info.num_regions = VFIO_PCI_NUM_REGIONS;
+ info.num_regions = VFIO_PCI_NUM_REGIONS +
+ vgpu->vdev.num_regions;
info.num_irqs = VFIO_PCI_NUM_IRQS;
return copy_to_user((void __user *)arg, &info, minsz) ?
@@ -959,6 +1055,7 @@ static long intel_vgpu_ioctl(struct mdev_device *mdev, unsigned int cmd,
}
if (caps.size) {
+ info.flags |= VFIO_REGION_INFO_FLAG_CAPS;
if (info.argsz < sizeof(info) + caps.size) {
info.argsz = sizeof(info) + caps.size;
info.cap_offset = 0;
@@ -1426,6 +1523,7 @@ struct intel_gvt_mpt kvmgt_mpt = {
.read_gpa = kvmgt_read_gpa,
.write_gpa = kvmgt_write_gpa,
.gfn_to_mfn = kvmgt_gfn_to_pfn,
+ .set_opregion = kvmgt_set_opregion,
};
EXPORT_SYMBOL_GPL(kvmgt_mpt);
diff --git a/drivers/gpu/drm/i915/gvt/mpt.h b/drivers/gpu/drm/i915/gvt/mpt.h
index c436e20..c99e796 100644
--- a/drivers/gpu/drm/i915/gvt/mpt.h
+++ b/drivers/gpu/drm/i915/gvt/mpt.h
@@ -294,4 +294,19 @@ static inline int intel_gvt_hypervisor_set_trap_area(
return intel_gvt_host.mpt->set_trap_area(vgpu->handle, start, end, map);
}
+/**
+ * intel_gvt_hypervisor_set_opregion - Set opregion for guest
+ * @vgpu: a vGPU
+ *
+ * Returns:
+ * Zero on success, negative error code if failed.
+ */
+static inline int intel_gvt_hypervisor_set_opregion(struct intel_vgpu *vgpu)
+{
+ if (!intel_gvt_host.mpt->set_opregion)
+ return 0;
+
+ return intel_gvt_host.mpt->set_opregion(vgpu);
+}
+
#endif /* _GVT_MPT_H_ */
diff --git a/drivers/gpu/drm/i915/gvt/opregion.c b/drivers/gpu/drm/i915/gvt/opregion.c
index 2533d1e..7f4b549 100644
--- a/drivers/gpu/drm/i915/gvt/opregion.c
+++ b/drivers/gpu/drm/i915/gvt/opregion.c
@@ -272,6 +272,9 @@ void intel_vgpu_clean_opregion(struct intel_vgpu *vgpu)
get_order(INTEL_GVT_OPREGION_SIZE));
vgpu_opregion(vgpu)->va = NULL;
+ } else if (intel_gvt_host.hypervisor_type == INTEL_GVT_HYPERVISOR_KVM) {
+ memunmap(vgpu_opregion(vgpu)->va);
+ vgpu_opregion(vgpu)->va = NULL;
}
}
@@ -285,23 +288,37 @@ void intel_vgpu_clean_opregion(struct intel_vgpu *vgpu)
*/
int intel_vgpu_init_opregion(struct intel_vgpu *vgpu, u32 gpa)
{
- int ret;
+ int ret = 0;
+ unsigned long pfn;
gvt_dbg_core("vgpu%d: init vgpu opregion\n", vgpu->id);
- if (intel_gvt_host.hypervisor_type == INTEL_GVT_HYPERVISOR_XEN) {
+ switch (intel_gvt_host.hypervisor_type) {
+ case INTEL_GVT_HYPERVISOR_KVM:
+ pfn = intel_gvt_hypervisor_gfn_to_mfn(vgpu, gpa >> PAGE_SHIFT);
+ vgpu_opregion(vgpu)->va = memremap(pfn << PAGE_SHIFT,
+ INTEL_GVT_OPREGION_SIZE,
+ MEMREMAP_WB);
+ if (!vgpu_opregion(vgpu)->va) {
+ gvt_vgpu_err("failed to map guest opregion\n");
+ ret = -EFAULT;
+ }
+ break;
+ case INTEL_GVT_HYPERVISOR_XEN:
gvt_dbg_core("emulate opregion from kernel\n");
ret = init_vgpu_opregion(vgpu, gpa);
if (ret)
- return ret;
+ break;
ret = map_vgpu_opregion(vgpu, true);
- if (ret)
- return ret;
+ break;
+ default:
+ ret = -EINVAL;
+ gvt_vgpu_err("not supported hypervisor\n");
}
- return 0;
+ return ret;
}
/**
diff --git a/drivers/gpu/drm/i915/gvt/vgpu.c b/drivers/gpu/drm/i915/gvt/vgpu.c
index c6b82d1..42aee6b 100644
--- a/drivers/gpu/drm/i915/gvt/vgpu.c
+++ b/drivers/gpu/drm/i915/gvt/vgpu.c
@@ -386,6 +386,10 @@ static struct intel_vgpu *__intel_gvt_create_vgpu(struct intel_gvt *gvt,
if (ret)
goto out_clean_sched_policy;
+ ret = intel_gvt_hypervisor_set_opregion(vgpu);
+ if (ret)
+ goto out_clean_sched_policy;
+
mutex_unlock(&gvt->lock);
return vgpu;
--
2.7.4
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH v18 5/6] vfio: ABI for mdev display dma-buf operation
2017-11-15 9:11 [PATCH v18 0/6] drm/i915/gvt: Dma-buf support for GVT-g Tina Zhang
` (3 preceding siblings ...)
2017-11-15 9:11 ` [PATCH v18 4/6] drm/i915/gvt: Add opregion support Tina Zhang
@ 2017-11-15 9:11 ` Tina Zhang
2017-11-15 10:47 ` Gerd Hoffmann
2017-11-15 18:48 ` Alex Williamson
2017-11-15 9:11 ` [PATCH v18 6/6] drm/i915/gvt: Dmabuf support for GVT-g Tina Zhang
2017-11-15 10:49 ` [PATCH v18 0/6] drm/i915/gvt: Dma-buf " Gerd Hoffmann
6 siblings, 2 replies; 19+ messages in thread
From: Tina Zhang @ 2017-11-15 9:11 UTC (permalink / raw)
To: alex.williamson, kraxel, chris, joonas.lahtinen, zhenyuw,
zhiyuan.lv, zhi.a.wang, kevin.tian, daniel, kwankhede, hang.yuan
Cc: Tina Zhang, intel-gfx, intel-gvt-dev, linux-kernel, Daniel Vetter
Add VFIO_DEVICE_QUERY_GFX_PLANE ioctl command to let user query and get
a plane and its information. So far, two types of buffers are supported:
buffers based on dma-buf and buffers based on region.
This ioctl can be invoked with:
1) Either DMABUF or REGION flag. Vendor driver returns a plane_info
successfully only when the specific kind of buffer is supported.
2) Flag PROBE. And at the same time either DMABUF or REGION must be set,
so that vendor driver returns success only when the specific kind of
buffer is supported.
Add VFIO_DEVICE_GET_GFX_DMABUF ioctl command to let user get a specific
dma-buf fd of an exposed MDEV buffer provided by dmabuf_id which was
returned in VFIO_DEVICE_QUERY_GFX_PLANE ioctl command.
The life cycle of an exposed MDEV buffer is handled by userspace and
tracked by kernel space. The returned dmabuf_id in struct vfio_device_
query_gfx_plane can be a new id of a new exposed buffer or an old id of
a re-exported buffer. Host user can check the value of dmabuf_id to see
if it needs to create new resources according to the new exposed buffer
or just re-use the existing resource related to the old buffer.
v18:
- update comments for VFIO_DEVICE_GET_GFX_DMABUF. (Alex)
v17:
- modify VFIO_DEVICE_GET_GFX_DMABUF interface. (Alex)
v16:
- add x_hot and y_hot fields. (Gerd)
- add comments for VFIO_DEVICE_GET_GFX_DMABUF. (Alex)
- rebase to 4.14.0-rc6.
v15:
- add a ioctl to get a dmabuf for a given dmabuf id. (Gerd)
v14:
- add PROBE, DMABUF and REGION flags. (Alex)
v12:
- add drm_format_mod back. (Gerd and Zhenyu)
- add region_index. (Gerd)
v11:
- rename plane_type to drm_plane_type. (Gerd)
- move fields of vfio_device_query_gfx_plane to vfio_device_gfx_plane_info.
(Gerd)
- remove drm_format_mod, start fields. (Daniel)
- remove plane_id.
v10:
- refine the ABI API VFIO_DEVICE_QUERY_GFX_PLANE. (Alex) (Gerd)
v3:
- add a field gvt_plane_info in the drm_i915_gem_obj structure to save
the decoded plane information to avoid look up while need the plane
info. (Gerd)
Signed-off-by: Tina Zhang <tina.zhang@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Alex Williamson <alex.williamson@redhat.com>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
---
include/uapi/linux/vfio.h | 62 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 62 insertions(+)
diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h
index ae46105..5c1cca2 100644
--- a/include/uapi/linux/vfio.h
+++ b/include/uapi/linux/vfio.h
@@ -502,6 +502,68 @@ struct vfio_pci_hot_reset {
#define VFIO_DEVICE_PCI_HOT_RESET _IO(VFIO_TYPE, VFIO_BASE + 13)
+/**
+ * VFIO_DEVICE_QUERY_GFX_PLANE - _IOW(VFIO_TYPE, VFIO_BASE + 14,
+ * struct vfio_device_query_gfx_plane)
+ *
+ * Set the drm_plane_type and flags, then retrieve the gfx plane info.
+ *
+ * flags supported:
+ * - VFIO_GFX_PLANE_TYPE_PROBE and VFIO_GFX_PLANE_TYPE_DMABUF are set
+ * to ask if the mdev supports dma-buf. 0 on support, -EINVAL on no
+ * support for dma-buf.
+ * - VFIO_GFX_PLANE_TYPE_PROBE and VFIO_GFX_PLANE_TYPE_REGION are set
+ * to ask if the mdev supports region. 0 on support, -EINVAL on no
+ * support for region.
+ * - VFIO_GFX_PLANE_TYPE_DMABUF or VFIO_GFX_PLANE_TYPE_REGION is set
+ * with each call to query the plane info.
+ * - Others are invalid and return -EINVAL.
+ *
+ * Note:
+ * 1. Plane could be disabled by guest. In that case, success will be
+ * returned with zero-initialized drm_format, size, width and height
+ * fields.
+ * 2. x_hot/y_hot is set to 0xFFFFFFFF if no hotspot information available
+ *
+ * Return: 0 on success, -errno on other failure.
+ */
+struct vfio_device_gfx_plane_info {
+ __u32 argsz;
+ __u32 flags;
+#define VFIO_GFX_PLANE_TYPE_PROBE (1 << 0)
+#define VFIO_GFX_PLANE_TYPE_DMABUF (1 << 1)
+#define VFIO_GFX_PLANE_TYPE_REGION (1 << 2)
+ /* in */
+ __u32 drm_plane_type; /* type of plane: DRM_PLANE_TYPE_* */
+ /* out */
+ __u32 drm_format; /* drm format of plane */
+ __u64 drm_format_mod; /* tiled mode */
+ __u32 width; /* width of plane */
+ __u32 height; /* height of plane */
+ __u32 stride; /* stride of plane */
+ __u32 size; /* size of plane in bytes, align on page*/
+ __u32 x_pos; /* horizontal position of cursor plane */
+ __u32 y_pos; /* vertical position of cursor plane*/
+ __u32 x_hot; /* horizontal position of cursor hotspot */
+ __u32 y_hot; /* vertical position of cursor hotspot */
+ union {
+ __u32 region_index; /* region index */
+ __u32 dmabuf_id; /* dma-buf id */
+ };
+};
+
+#define VFIO_DEVICE_QUERY_GFX_PLANE _IO(VFIO_TYPE, VFIO_BASE + 14)
+
+/**
+ * VFIO_DEVICE_GET_GFX_DMABUF - _IOW(VFIO_TYPE, VFIO_BASE + 15, __u32)
+ *
+ * Return a new dma-buf file descriptor for an exposed guest framebuffer
+ * described by the provided dmabuf_id. The dmabuf_id is returned from VFIO_
+ * DEVICE_QUERY_GFX_PLANE as a token of the exposed guest framebuffer.
+ */
+
+#define VFIO_DEVICE_GET_GFX_DMABUF _IO(VFIO_TYPE, VFIO_BASE + 15)
+
/* -------- API for Type1 VFIO IOMMU -------- */
/**
--
2.7.4
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH v18 6/6] drm/i915/gvt: Dmabuf support for GVT-g
2017-11-15 9:11 [PATCH v18 0/6] drm/i915/gvt: Dma-buf support for GVT-g Tina Zhang
` (4 preceding siblings ...)
2017-11-15 9:11 ` [PATCH v18 5/6] vfio: ABI for mdev display dma-buf operation Tina Zhang
@ 2017-11-15 9:11 ` Tina Zhang
2017-11-15 10:49 ` [PATCH v18 0/6] drm/i915/gvt: Dma-buf " Gerd Hoffmann
6 siblings, 0 replies; 19+ messages in thread
From: Tina Zhang @ 2017-11-15 9:11 UTC (permalink / raw)
To: alex.williamson, kraxel, chris, joonas.lahtinen, zhenyuw,
zhiyuan.lv, zhi.a.wang, kevin.tian, daniel, kwankhede, hang.yuan
Cc: Tina Zhang, intel-gfx, intel-gvt-dev, linux-kernel, Daniel Vetter
This patch introduces a guest's framebuffer sharing mechanism based on
dma-buf subsystem. With this sharing mechanism, guest's framebuffer can
be shared between guest VM and host.
v17:
- modify VFIO_DEVICE_GET_GFX_DMABUF interface. (Alex)
v16:
- add x_hot and y_hot. (Gerd)
- add flag validation for VFIO_DEVICE_GET_GFX_DMABUF. (Alex)
- rebase 4.14.0-rc6.
v15:
- add VFIO_DEVICE_GET_GFX_DMABUF ABI. (Gerd)
- add intel_vgpu_dmabuf_cleanup() to clean up the vGPU's dmabuf. (Gerd)
v14:
- add PROBE, DMABUF and REGION flags. (Alex)
v12:
- refine the lifecycle of dmabuf.
v9:
- remove dma-buf management. (Alex)
- track the dma-buf create and release in kernel mode. (Gerd) (Daniel)
v8:
- refine the dma-buf ioctl definition.(Alex)
- add a lock to protect the dmabuf list. (Alex)
v7:
- release dma-buf related allocations in dma-buf's associated release
function. (Alex)
- refine ioctl interface for querying plane info or create dma-buf.
(Alex)
v6:
- align the dma-buf life cycle with the vfio device. (Alex)
- add the dma-buf related operations in a separate patch. (Gerd)
- i915 related changes. (Chris)
v5:
- fix bug while checking whether the gem obj is gvt's dma-buf when user
change caching mode or domains. Add a helper function to do it.
(Xiaoguang)
- add definition for the query plane and create dma-buf. (Xiaoguang)
v4:
- fix bug while checking whether the gem obj is gvt's dma-buf when set
caching mode or doamins. (Xiaoguang)
v3:
- declare a new flag I915_GEM_OBJECT_IS_GVT_DMABUF in drm_i915_gem_object
to represent the gem obj for gvt's dma-buf. The tiling mode, caching
mode and domains can not be changed for this kind of gem object. (Alex)
- change dma-buf related information to be more generic. So other vendor
can use the same interface. (Alex)
v2:
- create a management fd for dma-buf operations. (Alex)
- alloc gem object's backing storage in gem obj's get_pages() callback.
(Chris)
Signed-off-by: Tina Zhang <tina.zhang@intel.com>
Cc: Alex Williamson <alex.williamson@redhat.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: Gerd Hoffmann <kraxel@redhat.com>
---
drivers/gpu/drm/i915/gvt/Makefile | 2 +-
drivers/gpu/drm/i915/gvt/dmabuf.c | 523 +++++++++++++++++++++++++++++++++
drivers/gpu/drm/i915/gvt/dmabuf.h | 67 +++++
drivers/gpu/drm/i915/gvt/gvt.c | 2 +
drivers/gpu/drm/i915/gvt/gvt.h | 11 +
drivers/gpu/drm/i915/gvt/hypercall.h | 2 +
drivers/gpu/drm/i915/gvt/kvmgt.c | 53 ++++
drivers/gpu/drm/i915/gvt/mpt.h | 30 ++
drivers/gpu/drm/i915/gvt/vgpu.c | 5 +-
drivers/gpu/drm/i915/i915_gem_object.h | 2 +
10 files changed, 695 insertions(+), 2 deletions(-)
create mode 100644 drivers/gpu/drm/i915/gvt/dmabuf.c
create mode 100644 drivers/gpu/drm/i915/gvt/dmabuf.h
diff --git a/drivers/gpu/drm/i915/gvt/Makefile b/drivers/gpu/drm/i915/gvt/Makefile
index 54d70df..cae06c1 100644
--- a/drivers/gpu/drm/i915/gvt/Makefile
+++ b/drivers/gpu/drm/i915/gvt/Makefile
@@ -2,7 +2,7 @@ GVT_DIR := gvt
GVT_SOURCE := gvt.o aperture_gm.o handlers.o vgpu.o trace_points.o firmware.o \
interrupt.o gtt.o cfg_space.o opregion.o mmio.o display.o edid.o \
execlist.o scheduler.o sched_policy.o render.o cmd_parser.o debugfs.o \
- fb_decoder.o
+ fb_decoder.o dmabuf.o
ccflags-y += -I$(src) -I$(src)/$(GVT_DIR)
i915-y += $(addprefix $(GVT_DIR)/, $(GVT_SOURCE))
diff --git a/drivers/gpu/drm/i915/gvt/dmabuf.c b/drivers/gpu/drm/i915/gvt/dmabuf.c
new file mode 100644
index 0000000..190710c
--- /dev/null
+++ b/drivers/gpu/drm/i915/gvt/dmabuf.c
@@ -0,0 +1,523 @@
+/*
+ * Copyright 2017 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Zhiyuan Lv <zhiyuan.lv@intel.com>
+ *
+ * Contributors:
+ * Xiaoguang Chen
+ * Tina Zhang <tina.zhang@intel.com>
+ */
+
+#include <linux/dma-buf.h>
+#include <drm/drmP.h>
+#include <linux/vfio.h>
+
+#include "i915_drv.h"
+#include "gvt.h"
+
+#define GEN8_DECODE_PTE(pte) (pte & GENMASK_ULL(63, 12))
+
+static int vgpu_gem_get_pages(
+ struct drm_i915_gem_object *obj)
+{
+ struct drm_i915_private *dev_priv = to_i915(obj->base.dev);
+ struct sg_table *st;
+ struct scatterlist *sg;
+ int i, ret;
+ gen8_pte_t __iomem *gtt_entries;
+ struct intel_vgpu_fb_info *fb_info;
+
+ fb_info = (struct intel_vgpu_fb_info *)obj->gvt_info;
+ if (WARN_ON(!fb_info))
+ return -ENODEV;
+
+ st = kmalloc(sizeof(*st), GFP_KERNEL);
+ if (unlikely(!st))
+ return -ENOMEM;
+
+ ret = sg_alloc_table(st, fb_info->size, GFP_KERNEL);
+ if (ret) {
+ kfree(st);
+ return ret;
+ }
+ gtt_entries = (gen8_pte_t __iomem *)dev_priv->ggtt.gsm +
+ (fb_info->start >> PAGE_SHIFT);
+ for_each_sg(st->sgl, sg, fb_info->size, i) {
+ sg->offset = 0;
+ sg->length = PAGE_SIZE;
+ sg_dma_address(sg) =
+ GEN8_DECODE_PTE(readq(>t_entries[i]));
+ sg_dma_len(sg) = PAGE_SIZE;
+ }
+
+ __i915_gem_object_set_pages(obj, st, PAGE_SIZE);
+
+ return 0;
+}
+
+static void vgpu_gem_put_pages(struct drm_i915_gem_object *obj,
+ struct sg_table *pages)
+{
+ sg_free_table(pages);
+ kfree(pages);
+}
+
+static void dmabuf_gem_object_free(struct kref *kref)
+{
+ struct intel_vgpu_dmabuf_obj *obj =
+ container_of(kref, struct intel_vgpu_dmabuf_obj, kref);
+ struct intel_vgpu *vgpu = obj->vgpu;
+ struct list_head *pos;
+
+ struct intel_vgpu_dmabuf_obj *dmabuf_obj;
+
+ list_for_each(pos, &vgpu->dmabuf_obj_list_head) {
+ dmabuf_obj = container_of(pos, struct intel_vgpu_dmabuf_obj,
+ list);
+ if (dmabuf_obj == obj) {
+ idr_remove(&vgpu->object_idr, dmabuf_obj->dmabuf_id);
+ kfree(dmabuf_obj->info);
+ kfree(dmabuf_obj);
+ list_del(pos);
+ break;
+ }
+ }
+}
+
+
+static inline void dmabuf_obj_get(struct intel_vgpu_dmabuf_obj *obj)
+{
+ kref_get(&obj->kref);
+}
+
+static inline void dmabuf_obj_put(struct intel_vgpu_dmabuf_obj *obj)
+{
+ kref_put(&obj->kref, dmabuf_gem_object_free);
+}
+
+static void vgpu_gem_release(struct drm_i915_gem_object *gem_obj)
+{
+
+ struct intel_vgpu_fb_info *fb_info = gem_obj->gvt_info;
+ struct intel_vgpu_dmabuf_obj *obj = fb_info->obj;
+ struct intel_vgpu *vgpu = obj->vgpu;
+
+ mutex_lock(&vgpu->dmabuf_lock);
+ gem_obj->base.dma_buf = NULL;
+ dmabuf_obj_put(obj);
+ intel_gvt_hypervisor_put_vfio_device(vgpu);
+ mutex_unlock(&vgpu->dmabuf_lock);
+}
+
+static const struct drm_i915_gem_object_ops intel_vgpu_gem_ops = {
+ .flags = I915_GEM_OBJECT_IS_PROXY,
+ .get_pages = vgpu_gem_get_pages,
+ .put_pages = vgpu_gem_put_pages,
+ .release = vgpu_gem_release,
+};
+
+static struct drm_i915_gem_object *vgpu_create_gem(struct drm_device *dev,
+ struct intel_vgpu_fb_info *info)
+{
+ struct drm_i915_private *dev_priv = to_i915(dev);
+ struct drm_i915_gem_object *obj;
+
+ obj = i915_gem_object_alloc(dev_priv);
+ if (obj == NULL)
+ return NULL;
+
+ drm_gem_private_object_init(dev, &obj->base,
+ info->size << PAGE_SHIFT);
+ i915_gem_object_init(obj, &intel_vgpu_gem_ops);
+
+ obj->base.read_domains = I915_GEM_DOMAIN_GTT;
+ obj->base.write_domain = 0;
+ if (IS_SKYLAKE(dev_priv)) {
+ unsigned int tiling_mode = 0;
+ unsigned int stride = 0;
+
+ switch (info->drm_format_mod << 10) {
+ case PLANE_CTL_TILED_LINEAR:
+ tiling_mode = I915_TILING_NONE;
+ break;
+ case PLANE_CTL_TILED_X:
+ tiling_mode = I915_TILING_X;
+ stride = info->stride;
+ break;
+ case PLANE_CTL_TILED_Y:
+ tiling_mode = I915_TILING_Y;
+ stride = info->stride;
+ break;
+ default:
+ gvt_dbg_core("not supported tiling mode\n");
+ }
+ obj->tiling_and_stride = tiling_mode | stride;
+ } else {
+ obj->tiling_and_stride = info->drm_format_mod ?
+ I915_TILING_X : 0;
+ }
+
+ return obj;
+}
+
+static int vgpu_get_plane_info(struct drm_device *dev,
+ struct intel_vgpu *vgpu,
+ struct intel_vgpu_fb_info *info,
+ int plane_id)
+{
+ struct drm_i915_private *dev_priv = to_i915(dev);
+ struct intel_vgpu_primary_plane_format p;
+ struct intel_vgpu_cursor_plane_format c;
+ int ret;
+
+ if (plane_id == DRM_PLANE_TYPE_PRIMARY) {
+ ret = intel_vgpu_decode_primary_plane(vgpu, &p);
+ if (ret)
+ return ret;
+ info->start = p.base;
+ info->start_gpa = p.base_gpa;
+ info->width = p.width;
+ info->height = p.height;
+ info->stride = p.stride;
+ info->drm_format = p.drm_format;
+ info->drm_format_mod = p.tiled;
+ info->size = (((p.stride * p.height * p.bpp) / 8) +
+ (PAGE_SIZE - 1)) >> PAGE_SHIFT;
+ } else if (plane_id == DRM_PLANE_TYPE_CURSOR) {
+ ret = intel_vgpu_decode_cursor_plane(vgpu, &c);
+ if (ret)
+ return ret;
+ info->start = c.base;
+ info->start_gpa = c.base_gpa;
+ info->width = c.width;
+ info->height = c.height;
+ info->stride = c.width * (c.bpp / 8);
+ info->drm_format = c.drm_format;
+ info->drm_format_mod = 0;
+ info->x_pos = c.x_pos;
+ info->y_pos = c.y_pos;
+
+ /* The invalid cursor hotspot value is delivered to host
+ * until we find a way to get the cursor hotspot info of
+ * guest OS.
+ */
+ info->x_hot = UINT_MAX;
+ info->y_hot = UINT_MAX;
+ info->size = (((info->stride * c.height * c.bpp) / 8)
+ + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
+ } else {
+ gvt_vgpu_err("invalid plane id:%d\n", plane_id);
+ return -EINVAL;
+ }
+
+ if (info->size == 0) {
+ gvt_vgpu_err("fb size is zero\n");
+ return -EINVAL;
+ }
+
+ if (info->start & (PAGE_SIZE - 1)) {
+ gvt_vgpu_err("Not aligned fb address:0x%llx\n", info->start);
+ return -EFAULT;
+ }
+ if (((info->start >> PAGE_SHIFT) + info->size) >
+ ggtt_total_entries(&dev_priv->ggtt)) {
+ gvt_vgpu_err("Invalid GTT offset or size\n");
+ return -EFAULT;
+ }
+
+ if (!intel_gvt_ggtt_validate_range(vgpu, info->start, info->size)) {
+ gvt_vgpu_err("invalid gma addr\n");
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+static struct intel_vgpu_dmabuf_obj *
+pick_dmabuf_by_info(struct intel_vgpu *vgpu,
+ struct intel_vgpu_fb_info *latest_info)
+{
+ struct list_head *pos;
+ struct intel_vgpu_fb_info *fb_info;
+ struct intel_vgpu_dmabuf_obj *dmabuf_obj = NULL;
+ struct intel_vgpu_dmabuf_obj *ret = NULL;
+
+ list_for_each(pos, &vgpu->dmabuf_obj_list_head) {
+ dmabuf_obj = container_of(pos, struct intel_vgpu_dmabuf_obj,
+ list);
+ if ((dmabuf_obj == NULL) ||
+ (dmabuf_obj->info == NULL))
+ continue;
+
+ fb_info = (struct intel_vgpu_fb_info *)dmabuf_obj->info;
+ if ((fb_info->start == latest_info->start) &&
+ (fb_info->start_gpa == latest_info->start_gpa) &&
+ (fb_info->size == latest_info->size) &&
+ (fb_info->drm_format_mod == latest_info->drm_format_mod) &&
+ (fb_info->drm_format == latest_info->drm_format) &&
+ (fb_info->width == latest_info->width) &&
+ (fb_info->height == latest_info->height)) {
+ ret = dmabuf_obj;
+ break;
+ }
+ }
+
+ return ret;
+}
+
+static struct intel_vgpu_dmabuf_obj *
+pick_dmabuf_by_num(struct intel_vgpu *vgpu, u32 id)
+{
+ struct list_head *pos;
+ struct intel_vgpu_dmabuf_obj *dmabuf_obj = NULL;
+ struct intel_vgpu_dmabuf_obj *ret = NULL;
+
+ list_for_each(pos, &vgpu->dmabuf_obj_list_head) {
+ dmabuf_obj = container_of(pos, struct intel_vgpu_dmabuf_obj,
+ list);
+ if (!dmabuf_obj)
+ continue;
+
+ if (dmabuf_obj->dmabuf_id == id) {
+ ret = dmabuf_obj;
+ break;
+ }
+ }
+
+ return ret;
+}
+
+static void update_fb_info(struct vfio_device_gfx_plane_info *gvt_dmabuf,
+ struct intel_vgpu_fb_info *fb_info)
+{
+ gvt_dmabuf->drm_format = fb_info->drm_format;
+ gvt_dmabuf->width = fb_info->width;
+ gvt_dmabuf->height = fb_info->height;
+ gvt_dmabuf->stride = fb_info->stride;
+ gvt_dmabuf->size = fb_info->size;
+ gvt_dmabuf->x_pos = fb_info->x_pos;
+ gvt_dmabuf->y_pos = fb_info->y_pos;
+ gvt_dmabuf->x_hot = fb_info->x_hot;
+ gvt_dmabuf->y_hot = fb_info->y_hot;
+}
+
+int intel_vgpu_query_plane(struct intel_vgpu *vgpu, void *args)
+{
+ struct drm_device *dev = &vgpu->gvt->dev_priv->drm;
+ struct vfio_device_gfx_plane_info *gfx_plane_info = args;
+ struct intel_vgpu_dmabuf_obj *dmabuf_obj;
+ struct intel_vgpu_fb_info fb_info;
+ int ret = 0;
+
+ if (gfx_plane_info->flags == (VFIO_GFX_PLANE_TYPE_DMABUF |
+ VFIO_GFX_PLANE_TYPE_PROBE))
+ return ret;
+ else if ((gfx_plane_info->flags & ~VFIO_GFX_PLANE_TYPE_DMABUF) ||
+ (!gfx_plane_info->flags))
+ return -EINVAL;
+
+ ret = vgpu_get_plane_info(dev, vgpu, &fb_info,
+ gfx_plane_info->drm_plane_type);
+ if (ret != 0)
+ goto out;
+
+ mutex_lock(&vgpu->dmabuf_lock);
+ /* If exists, pick up the exposed dmabuf_obj */
+ dmabuf_obj = pick_dmabuf_by_info(vgpu, &fb_info);
+ if (dmabuf_obj) {
+ update_fb_info(gfx_plane_info, &fb_info);
+ gfx_plane_info->dmabuf_id = dmabuf_obj->dmabuf_id;
+
+ /* This buffer may be released between query_plane ioctl and
+ * get_dmabuf ioctl. Add the refcount to make sure it won't
+ * be released between the two ioctls.
+ */
+ if (!dmabuf_obj->initref) {
+ dmabuf_obj->initref = true;
+ dmabuf_obj_get(dmabuf_obj);
+ }
+ ret = 0;
+ gvt_dbg_dpy("vgpu%d: re-use dmabuf_obj ref %d, id %d\n",
+ vgpu->id, kref_read(&dmabuf_obj->kref),
+ gfx_plane_info->dmabuf_id);
+ mutex_unlock(&vgpu->dmabuf_lock);
+ goto out;
+ }
+
+ mutex_unlock(&vgpu->dmabuf_lock);
+
+ /* Need to allocate a new one*/
+ dmabuf_obj = kmalloc(sizeof(struct intel_vgpu_dmabuf_obj), GFP_KERNEL);
+ if (unlikely(!dmabuf_obj)) {
+ gvt_vgpu_err("alloc dmabuf_obj failed\n");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ dmabuf_obj->info = kmalloc(sizeof(struct intel_vgpu_fb_info),
+ GFP_KERNEL);
+ if (unlikely(!dmabuf_obj->info)) {
+ gvt_vgpu_err("allocate intel vgpu fb info failed\n");
+ ret = -ENOMEM;
+ goto out_free_dmabuf;
+ }
+ memcpy(dmabuf_obj->info, &fb_info, sizeof(struct intel_vgpu_fb_info));
+
+ ((struct intel_vgpu_fb_info *)dmabuf_obj->info)->obj = dmabuf_obj;
+
+ dmabuf_obj->vgpu = vgpu;
+
+ ret = idr_alloc(&vgpu->object_idr, dmabuf_obj, 1, 0, GFP_NOWAIT);
+ if (ret < 0)
+ goto out_free_info;
+ gfx_plane_info->dmabuf_id = ret;
+ dmabuf_obj->dmabuf_id = ret;
+
+ dmabuf_obj->initref = true;
+
+ kref_init(&dmabuf_obj->kref);
+
+ mutex_lock(&vgpu->dmabuf_lock);
+ if (intel_gvt_hypervisor_get_vfio_device(vgpu)) {
+ gvt_vgpu_err("get vfio device failed\n");
+ mutex_unlock(&vgpu->dmabuf_lock);
+ goto out_free_info;
+ }
+ mutex_unlock(&vgpu->dmabuf_lock);
+
+ update_fb_info(gfx_plane_info, &fb_info);
+
+ INIT_LIST_HEAD(&dmabuf_obj->list);
+ mutex_lock(&vgpu->dmabuf_lock);
+ list_add_tail(&dmabuf_obj->list, &vgpu->dmabuf_obj_list_head);
+ mutex_unlock(&vgpu->dmabuf_lock);
+
+ gvt_dbg_dpy("vgpu%d: %s new dmabuf_obj ref %d, id %d\n", vgpu->id,
+ __func__, kref_read(&dmabuf_obj->kref), ret);
+
+ return 0;
+
+out_free_info:
+ kfree(dmabuf_obj->info);
+out_free_dmabuf:
+ kfree(dmabuf_obj);
+out:
+ /* ENODEV means plane isn't ready, which might be a normal case. */
+ return (ret == -ENODEV) ? 0 : ret;
+}
+
+/* To associate an exposed dmabuf with the dmabuf_obj */
+int intel_vgpu_get_dmabuf(struct intel_vgpu *vgpu, unsigned int dmabuf_id)
+{
+ struct drm_device *dev = &vgpu->gvt->dev_priv->drm;
+ struct intel_vgpu_dmabuf_obj *dmabuf_obj;
+ struct drm_i915_gem_object *obj;
+ struct dma_buf *dmabuf;
+ int dmabuf_fd;
+ int ret = 0;
+
+ mutex_lock(&vgpu->dmabuf_lock);
+
+ dmabuf_obj = pick_dmabuf_by_num(vgpu, dmabuf_id);
+ if (dmabuf_obj == NULL) {
+ gvt_vgpu_err("invalid dmabuf id:%d\n", dmabuf_id);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ obj = vgpu_create_gem(dev, dmabuf_obj->info);
+ if (obj == NULL) {
+ gvt_vgpu_err("create gvt gem obj failed:%d\n", vgpu->id);
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ obj->gvt_info = dmabuf_obj->info;
+
+ dmabuf = i915_gem_prime_export(dev, &obj->base, DRM_CLOEXEC | DRM_RDWR);
+ if (IS_ERR(dmabuf)) {
+ gvt_vgpu_err("export dma-buf failed\n");
+ ret = PTR_ERR(dmabuf);
+ goto out_free_gem;
+ }
+ obj->base.dma_buf = dmabuf;
+
+ i915_gem_object_put(obj);
+
+ ret = dma_buf_fd(dmabuf, DRM_CLOEXEC | DRM_RDWR);
+ if (ret < 0) {
+ gvt_vgpu_err("create dma-buf fd failed ret:%d\n", ret);
+ goto out_free_dmabuf;
+ }
+ dmabuf_fd = ret;
+
+ if (intel_gvt_hypervisor_get_vfio_device(vgpu)) {
+ gvt_vgpu_err("get vfio device failed\n");
+ put_unused_fd(ret);
+ goto out_free_dmabuf;
+ }
+
+ dmabuf_obj_get(dmabuf_obj);
+
+ if (dmabuf_obj->initref) {
+ dmabuf_obj->initref = false;
+ dmabuf_obj_put(dmabuf_obj);
+ }
+
+ mutex_unlock(&vgpu->dmabuf_lock);
+
+ gvt_dbg_dpy("vgpu%d: dmabuf:%d, dmabuf ref %d, fd:%d\n"
+ " file count: %ld, GEM ref: %d\n",
+ vgpu->id, dmabuf_obj->dmabuf_id,
+ kref_read(&dmabuf_obj->kref),
+ dmabuf_fd,
+ file_count(dmabuf->file),
+ kref_read(&obj->base.refcount));
+
+ return dmabuf_fd;
+
+out_free_dmabuf:
+ dma_buf_put(dmabuf);
+out_free_gem:
+ i915_gem_object_put(obj);
+out:
+ mutex_unlock(&vgpu->dmabuf_lock);
+ return ret;
+}
+
+void intel_vgpu_dmabuf_cleanup(struct intel_vgpu *vgpu)
+{
+ struct list_head *pos, *n;
+ struct intel_vgpu_dmabuf_obj *dmabuf_obj;
+
+ mutex_lock(&vgpu->dmabuf_lock);
+ list_for_each_safe(pos, n, &vgpu->dmabuf_obj_list_head) {
+ dmabuf_obj = container_of(pos, struct intel_vgpu_dmabuf_obj,
+ list);
+ if (dmabuf_obj->initref) {
+ dmabuf_obj->initref = false;
+ dmabuf_obj_put(dmabuf_obj);
+ }
+ }
+ mutex_unlock(&vgpu->dmabuf_lock);
+}
diff --git a/drivers/gpu/drm/i915/gvt/dmabuf.h b/drivers/gpu/drm/i915/gvt/dmabuf.h
new file mode 100644
index 0000000..5f8f03f
--- /dev/null
+++ b/drivers/gpu/drm/i915/gvt/dmabuf.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright(c) 2017 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Zhiyuan Lv <zhiyuan.lv@intel.com>
+ *
+ * Contributors:
+ * Xiaoguang Chen
+ * Tina Zhang <tina.zhang@intel.com>
+ */
+
+#ifndef _GVT_DMABUF_H_
+#define _GVT_DMABUF_H_
+#include <linux/vfio.h>
+
+struct intel_vgpu_fb_info {
+ __u64 start;
+ __u64 start_gpa;
+ __u64 drm_format_mod;
+ __u32 drm_format; /* drm format of plane */
+ __u32 width; /* width of plane */
+ __u32 height; /* height of plane */
+ __u32 stride; /* stride of plane */
+ __u32 size; /* size of plane in bytes, align on page */
+ __u32 x_pos; /* horizontal position of cursor plane */
+ __u32 y_pos; /* vertical position of cursor plane */
+ __u32 x_hot; /* horizontal position of cursor hotspot */
+ __u32 y_hot; /* vertical position of cursor hotspot */
+ struct intel_vgpu_dmabuf_obj *obj;
+};
+
+/**
+ * struct intel_vgpu_dmabuf_obj- Intel vGPU device buffer object
+ */
+struct intel_vgpu_dmabuf_obj {
+ struct intel_vgpu *vgpu;
+ struct intel_vgpu_fb_info *info;
+ __u32 dmabuf_id;
+ struct kref kref;
+ bool initref;
+ struct list_head list;
+};
+
+int intel_vgpu_query_plane(struct intel_vgpu *vgpu, void *args);
+int intel_vgpu_get_dmabuf(struct intel_vgpu *vgpu, unsigned int dmabuf_id);
+void intel_vgpu_dmabuf_cleanup(struct intel_vgpu *vgpu);
+
+#endif
diff --git a/drivers/gpu/drm/i915/gvt/gvt.c b/drivers/gpu/drm/i915/gvt/gvt.c
index cef06d5..2b050ff 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.c
+++ b/drivers/gpu/drm/i915/gvt/gvt.c
@@ -181,6 +181,8 @@ static const struct intel_gvt_ops intel_gvt_ops = {
.vgpu_deactivate = intel_gvt_deactivate_vgpu,
.gvt_find_vgpu_type = intel_gvt_find_vgpu_type,
.get_gvt_attrs = intel_get_gvt_attrs,
+ .vgpu_query_plane = intel_vgpu_query_plane,
+ .vgpu_get_dmabuf = intel_vgpu_get_dmabuf,
};
/**
diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h
index c8e496c..8e5a4ea 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.h
+++ b/drivers/gpu/drm/i915/gvt/gvt.h
@@ -47,6 +47,7 @@
#include "render.h"
#include "cmd_parser.h"
#include "fb_decoder.h"
+#include "dmabuf.h"
#define GVT_MAX_VGPU 8
@@ -208,8 +209,16 @@ struct intel_vgpu {
struct kvm *kvm;
struct work_struct release_work;
atomic_t released;
+ struct vfio_device *vfio_device;
} vdev;
#endif
+
+ struct list_head dmabuf_obj_list_head;
+ struct mutex dmabuf_lock;
+ struct idr object_idr;
+
+ struct completion vblank_done;
+
};
/* validating GM healthy status*/
@@ -543,6 +552,8 @@ struct intel_gvt_ops {
const char *name);
bool (*get_gvt_attrs)(struct attribute ***type_attrs,
struct attribute_group ***intel_vgpu_type_groups);
+ int (*vgpu_query_plane)(struct intel_vgpu *vgpu, void *);
+ int (*vgpu_get_dmabuf)(struct intel_vgpu *vgpu, unsigned int);
};
diff --git a/drivers/gpu/drm/i915/gvt/hypercall.h b/drivers/gpu/drm/i915/gvt/hypercall.h
index 32c345c..a1bd82f 100644
--- a/drivers/gpu/drm/i915/gvt/hypercall.h
+++ b/drivers/gpu/drm/i915/gvt/hypercall.h
@@ -56,6 +56,8 @@ struct intel_gvt_mpt {
int (*set_trap_area)(unsigned long handle, u64 start, u64 end,
bool map);
int (*set_opregion)(void *vgpu);
+ int (*get_vfio_device)(void *vgpu);
+ void (*put_vfio_device)(void *vgpu);
};
extern struct intel_gvt_mpt xengt_mpt;
diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 7875bc0..5cc166c 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -378,10 +378,23 @@ static int intel_vgpu_register_reg(struct intel_vgpu *vgpu,
vgpu->vdev.region[vgpu->vdev.num_regions].flags = flags;
vgpu->vdev.region[vgpu->vdev.num_regions].data = data;
vgpu->vdev.num_regions++;
+ return 0;
+}
+
+static int kvmgt_get_vfio_device(void *p_vgpu)
+{
+ struct intel_vgpu *vgpu = (struct intel_vgpu *)p_vgpu;
+ vgpu->vdev.vfio_device = vfio_device_get_from_dev(
+ mdev_dev(vgpu->vdev.mdev));
+ if (!vgpu->vdev.vfio_device) {
+ gvt_vgpu_err("failed to get vfio device\n");
+ return -ENODEV;
+ }
return 0;
}
+
static int kvmgt_set_opregion(void *p_vgpu)
{
struct intel_vgpu *vgpu = (struct intel_vgpu *)p_vgpu;
@@ -408,6 +421,14 @@ static int kvmgt_set_opregion(void *p_vgpu)
return ret;
}
+static void kvmgt_put_vfio_device(void *vgpu)
+{
+ if (WARN_ON(!((struct intel_vgpu *)vgpu)->vdev.vfio_device))
+ return;
+
+ vfio_device_put(((struct intel_vgpu *)vgpu)->vdev.vfio_device);
+}
+
static int intel_vgpu_create(struct kobject *kobj, struct mdev_device *mdev)
{
struct intel_vgpu *vgpu = NULL;
@@ -1142,6 +1163,33 @@ static long intel_vgpu_ioctl(struct mdev_device *mdev, unsigned int cmd,
} else if (cmd == VFIO_DEVICE_RESET) {
intel_gvt_ops->vgpu_reset(vgpu);
return 0;
+ } else if (cmd == VFIO_DEVICE_QUERY_GFX_PLANE) {
+ struct vfio_device_gfx_plane_info dmabuf;
+ int ret = 0;
+
+ minsz = offsetofend(struct vfio_device_gfx_plane_info,
+ dmabuf_id);
+ if (copy_from_user(&dmabuf, (void __user *)arg, minsz))
+ return -EFAULT;
+ if (dmabuf.argsz < minsz)
+ return -EINVAL;
+
+ ret = intel_gvt_ops->vgpu_query_plane(vgpu, &dmabuf);
+ if (ret != 0)
+ return ret;
+
+ return copy_to_user((void __user *)arg, &dmabuf, minsz) ?
+ -EFAULT : 0;
+ } else if (cmd == VFIO_DEVICE_GET_GFX_DMABUF) {
+ __u32 dmabuf_id;
+ __s32 dmabuf_fd;
+
+ if (get_user(dmabuf_id, (__u32 __user *)arg))
+ return -EFAULT;
+
+ dmabuf_fd = intel_gvt_ops->vgpu_get_dmabuf(vgpu, dmabuf_id);
+ return dmabuf_fd;
+
}
return 0;
@@ -1383,6 +1431,9 @@ static int kvmgt_guest_init(struct mdev_device *mdev)
kvmgt_protect_table_init(info);
gvt_cache_init(vgpu);
+ mutex_init(&vgpu->dmabuf_lock);
+ init_completion(&vgpu->vblank_done);
+
info->track_node.track_write = kvmgt_page_track_write;
info->track_node.track_flush_slot = kvmgt_page_track_flush_slot;
kvm_page_track_register_notifier(kvm, &info->track_node);
@@ -1524,6 +1575,8 @@ struct intel_gvt_mpt kvmgt_mpt = {
.write_gpa = kvmgt_write_gpa,
.gfn_to_mfn = kvmgt_gfn_to_pfn,
.set_opregion = kvmgt_set_opregion,
+ .get_vfio_device = kvmgt_get_vfio_device,
+ .put_vfio_device = kvmgt_put_vfio_device,
};
EXPORT_SYMBOL_GPL(kvmgt_mpt);
diff --git a/drivers/gpu/drm/i915/gvt/mpt.h b/drivers/gpu/drm/i915/gvt/mpt.h
index c99e796..ca8005a 100644
--- a/drivers/gpu/drm/i915/gvt/mpt.h
+++ b/drivers/gpu/drm/i915/gvt/mpt.h
@@ -309,4 +309,34 @@ static inline int intel_gvt_hypervisor_set_opregion(struct intel_vgpu *vgpu)
return intel_gvt_host.mpt->set_opregion(vgpu);
}
+/**
+ * intel_gvt_hypervisor_get_vfio_device - increase vfio device ref count
+ * @vgpu: a vGPU
+ *
+ * Returns:
+ * Zero on success, negative error code if failed.
+ */
+static inline int intel_gvt_hypervisor_get_vfio_device(struct intel_vgpu *vgpu)
+{
+ if (!intel_gvt_host.mpt->get_vfio_device)
+ return 0;
+
+ return intel_gvt_host.mpt->get_vfio_device(vgpu);
+}
+
+/**
+ * intel_gvt_hypervisor_put_vfio_device - decrease vfio device ref count
+ * @vgpu: a vGPU
+ *
+ * Returns:
+ * Zero on success, negative error code if failed.
+ */
+static inline void intel_gvt_hypervisor_put_vfio_device(struct intel_vgpu *vgpu)
+{
+ if (!intel_gvt_host.mpt->put_vfio_device)
+ return;
+
+ intel_gvt_host.mpt->put_vfio_device(vgpu);
+}
+
#endif /* _GVT_MPT_H_ */
diff --git a/drivers/gpu/drm/i915/gvt/vgpu.c b/drivers/gpu/drm/i915/gvt/vgpu.c
index 42aee6b..b964848 100644
--- a/drivers/gpu/drm/i915/gvt/vgpu.c
+++ b/drivers/gpu/drm/i915/gvt/vgpu.c
@@ -236,6 +236,7 @@ void intel_gvt_deactivate_vgpu(struct intel_vgpu *vgpu)
}
intel_vgpu_stop_schedule(vgpu);
+ intel_vgpu_dmabuf_cleanup(vgpu);
mutex_unlock(&gvt->lock);
}
@@ -265,6 +266,7 @@ void intel_gvt_destroy_vgpu(struct intel_vgpu *vgpu)
intel_gvt_hypervisor_detach_vgpu(vgpu);
intel_vgpu_free_resource(vgpu);
intel_vgpu_clean_mmio(vgpu);
+ intel_vgpu_dmabuf_cleanup(vgpu);
vfree(vgpu);
intel_gvt_update_vgpu_types(gvt);
@@ -349,7 +351,8 @@ static struct intel_vgpu *__intel_gvt_create_vgpu(struct intel_gvt *gvt,
vgpu->handle = param->handle;
vgpu->gvt = gvt;
vgpu->sched_ctl.weight = param->weight;
-
+ INIT_LIST_HEAD(&vgpu->dmabuf_obj_list_head);
+ idr_init(&vgpu->object_idr);
intel_vgpu_init_cfg_space(vgpu, param->primary);
ret = intel_vgpu_init_mmio(vgpu);
diff --git a/drivers/gpu/drm/i915/i915_gem_object.h b/drivers/gpu/drm/i915/i915_gem_object.h
index 63ce38c..3773155 100644
--- a/drivers/gpu/drm/i915/i915_gem_object.h
+++ b/drivers/gpu/drm/i915/i915_gem_object.h
@@ -260,6 +260,8 @@ struct drm_i915_gem_object {
} userptr;
unsigned long scratch;
+
+ void *gvt_info;
};
/** for phys allocated objects */
--
2.7.4
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v18 5/6] vfio: ABI for mdev display dma-buf operation
2017-11-15 9:11 ` [PATCH v18 5/6] vfio: ABI for mdev display dma-buf operation Tina Zhang
@ 2017-11-15 10:47 ` Gerd Hoffmann
2017-11-15 18:48 ` Alex Williamson
1 sibling, 0 replies; 19+ messages in thread
From: Gerd Hoffmann @ 2017-11-15 10:47 UTC (permalink / raw)
To: Tina Zhang
Cc: alex.williamson, chris, joonas.lahtinen, zhenyuw, zhiyuan.lv,
zhi.a.wang, kevin.tian, daniel, kwankhede, hang.yuan, intel-gfx,
intel-gvt-dev, linux-kernel, Daniel Vetter
On Wed, Nov 15, 2017 at 05:11:54PM +0800, Tina Zhang wrote:
> Add VFIO_DEVICE_QUERY_GFX_PLANE ioctl command to let user query and get
> a plane and its information. So far, two types of buffers are supported:
> buffers based on dma-buf and buffers based on region.
>
> This ioctl can be invoked with:
> 1) Either DMABUF or REGION flag. Vendor driver returns a plane_info
> successfully only when the specific kind of buffer is supported.
> 2) Flag PROBE. And at the same time either DMABUF or REGION must be set,
> so that vendor driver returns success only when the specific kind of
> buffer is supported.
>
> Add VFIO_DEVICE_GET_GFX_DMABUF ioctl command to let user get a specific
> dma-buf fd of an exposed MDEV buffer provided by dmabuf_id which was
> returned in VFIO_DEVICE_QUERY_GFX_PLANE ioctl command.
>
> The life cycle of an exposed MDEV buffer is handled by userspace and
> tracked by kernel space. The returned dmabuf_id in struct vfio_device_
> query_gfx_plane can be a new id of a new exposed buffer or an old id of
> a re-exported buffer. Host user can check the value of dmabuf_id to see
> if it needs to create new resources according to the new exposed buffer
> or just re-use the existing resource related to the old buffer.
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v18 0/6] drm/i915/gvt: Dma-buf support for GVT-g
2017-11-15 9:11 [PATCH v18 0/6] drm/i915/gvt: Dma-buf support for GVT-g Tina Zhang
` (5 preceding siblings ...)
2017-11-15 9:11 ` [PATCH v18 6/6] drm/i915/gvt: Dmabuf support for GVT-g Tina Zhang
@ 2017-11-15 10:49 ` Gerd Hoffmann
2017-11-15 22:48 ` Alex Williamson
2017-11-23 6:12 ` Zhenyu Wang
6 siblings, 2 replies; 19+ messages in thread
From: Gerd Hoffmann @ 2017-11-15 10:49 UTC (permalink / raw)
To: Tina Zhang
Cc: alex.williamson, chris, joonas.lahtinen, zhenyuw, zhiyuan.lv,
zhi.a.wang, kevin.tian, daniel, kwankhede, hang.yuan, intel-gfx,
intel-gvt-dev, linux-kernel
On Wed, Nov 15, 2017 at 05:11:49PM +0800, Tina Zhang wrote:
> v17->v18:
> 1) unmap vgpu's opregion when destroying vgpu.
> 2) update comments for VFIO_DEVICE_GET_GFX_DMABUF. (Alex)
> This patch set adds the dma-buf support for intel GVT-g.
>
> dma-buf is an uniform mechanism to share DMA buffers across different
> devices and subsystems. dma-buf for intel GVT-g is mainly used to share
> the vgpu's framebuffer to userspace to leverage userspace graphics stacks
> to render the framebuffer to the display monitor.
>
> The main idea is that we create a gem object and set vgpu's framebuffer as
> its backing storage. Then, export a dma-buf associated with this gem object.
> With the fd of this dma-buf, userspace can directly handle this buffer.
>
> This patch set can be tried with the following example:
> git://git.kraxel.org/qemu branch: work/intel-vgpu
>
> A topic branch with the latest patch set is:
> https://github.com/intel/gvt-linux.git branch: topic/dmabuf
Tested-by: Gerd Hoffmann <kraxel@redhat.com>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v18 5/6] vfio: ABI for mdev display dma-buf operation
2017-11-15 9:11 ` [PATCH v18 5/6] vfio: ABI for mdev display dma-buf operation Tina Zhang
2017-11-15 10:47 ` Gerd Hoffmann
@ 2017-11-15 18:48 ` Alex Williamson
2017-11-16 3:21 ` Zhenyu Wang
1 sibling, 1 reply; 19+ messages in thread
From: Alex Williamson @ 2017-11-15 18:48 UTC (permalink / raw)
To: Tina Zhang
Cc: kraxel, chris, joonas.lahtinen, zhenyuw, zhiyuan.lv, zhi.a.wang,
kevin.tian, daniel, kwankhede, hang.yuan, intel-gfx,
intel-gvt-dev, linux-kernel, Daniel Vetter
On Wed, 15 Nov 2017 17:11:54 +0800
Tina Zhang <tina.zhang@intel.com> wrote:
> Add VFIO_DEVICE_QUERY_GFX_PLANE ioctl command to let user query and get
> a plane and its information. So far, two types of buffers are supported:
> buffers based on dma-buf and buffers based on region.
>
> This ioctl can be invoked with:
> 1) Either DMABUF or REGION flag. Vendor driver returns a plane_info
> successfully only when the specific kind of buffer is supported.
> 2) Flag PROBE. And at the same time either DMABUF or REGION must be set,
> so that vendor driver returns success only when the specific kind of
> buffer is supported.
>
> Add VFIO_DEVICE_GET_GFX_DMABUF ioctl command to let user get a specific
> dma-buf fd of an exposed MDEV buffer provided by dmabuf_id which was
> returned in VFIO_DEVICE_QUERY_GFX_PLANE ioctl command.
>
> The life cycle of an exposed MDEV buffer is handled by userspace and
> tracked by kernel space. The returned dmabuf_id in struct vfio_device_
> query_gfx_plane can be a new id of a new exposed buffer or an old id of
> a re-exported buffer. Host user can check the value of dmabuf_id to see
> if it needs to create new resources according to the new exposed buffer
> or just re-use the existing resource related to the old buffer.
>
> v18:
> - update comments for VFIO_DEVICE_GET_GFX_DMABUF. (Alex)
>
> v17:
> - modify VFIO_DEVICE_GET_GFX_DMABUF interface. (Alex)
>
> v16:
> - add x_hot and y_hot fields. (Gerd)
> - add comments for VFIO_DEVICE_GET_GFX_DMABUF. (Alex)
> - rebase to 4.14.0-rc6.
>
> v15:
> - add a ioctl to get a dmabuf for a given dmabuf id. (Gerd)
>
> v14:
> - add PROBE, DMABUF and REGION flags. (Alex)
>
> v12:
> - add drm_format_mod back. (Gerd and Zhenyu)
> - add region_index. (Gerd)
>
> v11:
> - rename plane_type to drm_plane_type. (Gerd)
> - move fields of vfio_device_query_gfx_plane to vfio_device_gfx_plane_info.
> (Gerd)
> - remove drm_format_mod, start fields. (Daniel)
> - remove plane_id.
>
> v10:
> - refine the ABI API VFIO_DEVICE_QUERY_GFX_PLANE. (Alex) (Gerd)
>
> v3:
> - add a field gvt_plane_info in the drm_i915_gem_obj structure to save
> the decoded plane information to avoid look up while need the plane
> info. (Gerd)
>
> Signed-off-by: Tina Zhang <tina.zhang@intel.com>
> Cc: Gerd Hoffmann <kraxel@redhat.com>
> Cc: Alex Williamson <alex.williamson@redhat.com>
> Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
> ---
> include/uapi/linux/vfio.h | 62 +++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 62 insertions(+)
>
> diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h
> index ae46105..5c1cca2 100644
> --- a/include/uapi/linux/vfio.h
> +++ b/include/uapi/linux/vfio.h
> @@ -502,6 +502,68 @@ struct vfio_pci_hot_reset {
>
> #define VFIO_DEVICE_PCI_HOT_RESET _IO(VFIO_TYPE, VFIO_BASE + 13)
>
> +/**
> + * VFIO_DEVICE_QUERY_GFX_PLANE - _IOW(VFIO_TYPE, VFIO_BASE + 14,
> + * struct vfio_device_query_gfx_plane)
> + *
> + * Set the drm_plane_type and flags, then retrieve the gfx plane info.
> + *
> + * flags supported:
> + * - VFIO_GFX_PLANE_TYPE_PROBE and VFIO_GFX_PLANE_TYPE_DMABUF are set
> + * to ask if the mdev supports dma-buf. 0 on support, -EINVAL on no
> + * support for dma-buf.
> + * - VFIO_GFX_PLANE_TYPE_PROBE and VFIO_GFX_PLANE_TYPE_REGION are set
> + * to ask if the mdev supports region. 0 on support, -EINVAL on no
> + * support for region.
> + * - VFIO_GFX_PLANE_TYPE_DMABUF or VFIO_GFX_PLANE_TYPE_REGION is set
> + * with each call to query the plane info.
> + * - Others are invalid and return -EINVAL.
> + *
> + * Note:
> + * 1. Plane could be disabled by guest. In that case, success will be
> + * returned with zero-initialized drm_format, size, width and height
> + * fields.
> + * 2. x_hot/y_hot is set to 0xFFFFFFFF if no hotspot information available
> + *
> + * Return: 0 on success, -errno on other failure.
> + */
> +struct vfio_device_gfx_plane_info {
> + __u32 argsz;
> + __u32 flags;
> +#define VFIO_GFX_PLANE_TYPE_PROBE (1 << 0)
> +#define VFIO_GFX_PLANE_TYPE_DMABUF (1 << 1)
> +#define VFIO_GFX_PLANE_TYPE_REGION (1 << 2)
> + /* in */
> + __u32 drm_plane_type; /* type of plane: DRM_PLANE_TYPE_* */
> + /* out */
> + __u32 drm_format; /* drm format of plane */
> + __u64 drm_format_mod; /* tiled mode */
> + __u32 width; /* width of plane */
> + __u32 height; /* height of plane */
> + __u32 stride; /* stride of plane */
> + __u32 size; /* size of plane in bytes, align on page*/
> + __u32 x_pos; /* horizontal position of cursor plane */
> + __u32 y_pos; /* vertical position of cursor plane*/
> + __u32 x_hot; /* horizontal position of cursor hotspot */
> + __u32 y_hot; /* vertical position of cursor hotspot */
> + union {
> + __u32 region_index; /* region index */
> + __u32 dmabuf_id; /* dma-buf id */
> + };
> +};
> +
> +#define VFIO_DEVICE_QUERY_GFX_PLANE _IO(VFIO_TYPE, VFIO_BASE + 14)
> +
> +/**
> + * VFIO_DEVICE_GET_GFX_DMABUF - _IOW(VFIO_TYPE, VFIO_BASE + 15, __u32)
> + *
> + * Return a new dma-buf file descriptor for an exposed guest framebuffer
> + * described by the provided dmabuf_id. The dmabuf_id is returned from VFIO_
> + * DEVICE_QUERY_GFX_PLANE as a token of the exposed guest framebuffer.
> + */
> +
> +#define VFIO_DEVICE_GET_GFX_DMABUF _IO(VFIO_TYPE, VFIO_BASE + 15)
> +
> /* -------- API for Type1 VFIO IOMMU -------- */
>
> /**
Looks good to me. Kirti, have you had a chance yet to verify this is
sufficient for your region-based approach? It would be great to get
confirmation of that ASAP so we can get this in. Thanks,
Alex
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v18 0/6] drm/i915/gvt: Dma-buf support for GVT-g
2017-11-15 10:49 ` [PATCH v18 0/6] drm/i915/gvt: Dma-buf " Gerd Hoffmann
@ 2017-11-15 22:48 ` Alex Williamson
2017-11-16 9:33 ` Gerd Hoffmann
2017-11-23 6:12 ` Zhenyu Wang
1 sibling, 1 reply; 19+ messages in thread
From: Alex Williamson @ 2017-11-15 22:48 UTC (permalink / raw)
To: Gerd Hoffmann
Cc: Tina Zhang, chris, joonas.lahtinen, zhenyuw, zhiyuan.lv,
zhi.a.wang, kevin.tian, daniel, kwankhede, hang.yuan, intel-gfx,
intel-gvt-dev, linux-kernel
On Wed, 15 Nov 2017 11:49:00 +0100
Gerd Hoffmann <kraxel@redhat.com> wrote:
> On Wed, Nov 15, 2017 at 05:11:49PM +0800, Tina Zhang wrote:
> > v17->v18:
> > 1) unmap vgpu's opregion when destroying vgpu.
> > 2) update comments for VFIO_DEVICE_GET_GFX_DMABUF. (Alex)
>
> > This patch set adds the dma-buf support for intel GVT-g.
> >
> > dma-buf is an uniform mechanism to share DMA buffers across different
> > devices and subsystems. dma-buf for intel GVT-g is mainly used to share
> > the vgpu's framebuffer to userspace to leverage userspace graphics stacks
> > to render the framebuffer to the display monitor.
> >
> > The main idea is that we create a gem object and set vgpu's framebuffer as
> > its backing storage. Then, export a dma-buf associated with this gem object.
> > With the fd of this dma-buf, userspace can directly handle this buffer.
> >
> > This patch set can be tried with the following example:
> > git://git.kraxel.org/qemu branch: work/intel-vgpu
> >
> > A topic branch with the latest patch set is:
> > https://github.com/intel/gvt-linux.git branch: topic/dmabuf
>
> Tested-by: Gerd Hoffmann <kraxel@redhat.com>
Hi Gerd,
Can you share the xml snippets required for the VM to make this work?
Last I tried I couldn't get the display/video/hostdev configuration to
get any enhanced behavior through the dmabuf. Thanks,
Alex
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v18 5/6] vfio: ABI for mdev display dma-buf operation
2017-11-15 18:48 ` Alex Williamson
@ 2017-11-16 3:21 ` Zhenyu Wang
2017-11-16 4:11 ` Alex Williamson
0 siblings, 1 reply; 19+ messages in thread
From: Zhenyu Wang @ 2017-11-16 3:21 UTC (permalink / raw)
To: Alex Williamson
Cc: Tina Zhang, kevin.tian, Daniel Vetter, intel-gfx,
joonas.lahtinen, linux-kernel, zhenyuw, chris, kwankhede,
zhiyuan.lv, daniel, hang.yuan, intel-gvt-dev, zhi.a.wang, kraxel
[-- Attachment #1: Type: text/plain, Size: 6340 bytes --]
On 2017.11.15 11:48:42 -0700, Alex Williamson wrote:
> On Wed, 15 Nov 2017 17:11:54 +0800
> Tina Zhang <tina.zhang@intel.com> wrote:
>
> > Add VFIO_DEVICE_QUERY_GFX_PLANE ioctl command to let user query and get
> > a plane and its information. So far, two types of buffers are supported:
> > buffers based on dma-buf and buffers based on region.
> >
> > This ioctl can be invoked with:
> > 1) Either DMABUF or REGION flag. Vendor driver returns a plane_info
> > successfully only when the specific kind of buffer is supported.
> > 2) Flag PROBE. And at the same time either DMABUF or REGION must be set,
> > so that vendor driver returns success only when the specific kind of
> > buffer is supported.
> >
> > Add VFIO_DEVICE_GET_GFX_DMABUF ioctl command to let user get a specific
> > dma-buf fd of an exposed MDEV buffer provided by dmabuf_id which was
> > returned in VFIO_DEVICE_QUERY_GFX_PLANE ioctl command.
> >
> > The life cycle of an exposed MDEV buffer is handled by userspace and
> > tracked by kernel space. The returned dmabuf_id in struct vfio_device_
> > query_gfx_plane can be a new id of a new exposed buffer or an old id of
> > a re-exported buffer. Host user can check the value of dmabuf_id to see
> > if it needs to create new resources according to the new exposed buffer
> > or just re-use the existing resource related to the old buffer.
> >
> > v18:
> > - update comments for VFIO_DEVICE_GET_GFX_DMABUF. (Alex)
> >
> > v17:
> > - modify VFIO_DEVICE_GET_GFX_DMABUF interface. (Alex)
> >
> > v16:
> > - add x_hot and y_hot fields. (Gerd)
> > - add comments for VFIO_DEVICE_GET_GFX_DMABUF. (Alex)
> > - rebase to 4.14.0-rc6.
> >
> > v15:
> > - add a ioctl to get a dmabuf for a given dmabuf id. (Gerd)
> >
> > v14:
> > - add PROBE, DMABUF and REGION flags. (Alex)
> >
> > v12:
> > - add drm_format_mod back. (Gerd and Zhenyu)
> > - add region_index. (Gerd)
> >
> > v11:
> > - rename plane_type to drm_plane_type. (Gerd)
> > - move fields of vfio_device_query_gfx_plane to vfio_device_gfx_plane_info.
> > (Gerd)
> > - remove drm_format_mod, start fields. (Daniel)
> > - remove plane_id.
> >
> > v10:
> > - refine the ABI API VFIO_DEVICE_QUERY_GFX_PLANE. (Alex) (Gerd)
> >
> > v3:
> > - add a field gvt_plane_info in the drm_i915_gem_obj structure to save
> > the decoded plane information to avoid look up while need the plane
> > info. (Gerd)
> >
> > Signed-off-by: Tina Zhang <tina.zhang@intel.com>
> > Cc: Gerd Hoffmann <kraxel@redhat.com>
> > Cc: Alex Williamson <alex.williamson@redhat.com>
> > Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
> > ---
> > include/uapi/linux/vfio.h | 62 +++++++++++++++++++++++++++++++++++++++++++++++
> > 1 file changed, 62 insertions(+)
> >
> > diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h
> > index ae46105..5c1cca2 100644
> > --- a/include/uapi/linux/vfio.h
> > +++ b/include/uapi/linux/vfio.h
> > @@ -502,6 +502,68 @@ struct vfio_pci_hot_reset {
> >
> > #define VFIO_DEVICE_PCI_HOT_RESET _IO(VFIO_TYPE, VFIO_BASE + 13)
> >
> > +/**
> > + * VFIO_DEVICE_QUERY_GFX_PLANE - _IOW(VFIO_TYPE, VFIO_BASE + 14,
> > + * struct vfio_device_query_gfx_plane)
> > + *
> > + * Set the drm_plane_type and flags, then retrieve the gfx plane info.
> > + *
> > + * flags supported:
> > + * - VFIO_GFX_PLANE_TYPE_PROBE and VFIO_GFX_PLANE_TYPE_DMABUF are set
> > + * to ask if the mdev supports dma-buf. 0 on support, -EINVAL on no
> > + * support for dma-buf.
> > + * - VFIO_GFX_PLANE_TYPE_PROBE and VFIO_GFX_PLANE_TYPE_REGION are set
> > + * to ask if the mdev supports region. 0 on support, -EINVAL on no
> > + * support for region.
> > + * - VFIO_GFX_PLANE_TYPE_DMABUF or VFIO_GFX_PLANE_TYPE_REGION is set
> > + * with each call to query the plane info.
> > + * - Others are invalid and return -EINVAL.
> > + *
> > + * Note:
> > + * 1. Plane could be disabled by guest. In that case, success will be
> > + * returned with zero-initialized drm_format, size, width and height
> > + * fields.
> > + * 2. x_hot/y_hot is set to 0xFFFFFFFF if no hotspot information available
> > + *
> > + * Return: 0 on success, -errno on other failure.
> > + */
> > +struct vfio_device_gfx_plane_info {
> > + __u32 argsz;
> > + __u32 flags;
> > +#define VFIO_GFX_PLANE_TYPE_PROBE (1 << 0)
> > +#define VFIO_GFX_PLANE_TYPE_DMABUF (1 << 1)
> > +#define VFIO_GFX_PLANE_TYPE_REGION (1 << 2)
> > + /* in */
> > + __u32 drm_plane_type; /* type of plane: DRM_PLANE_TYPE_* */
> > + /* out */
> > + __u32 drm_format; /* drm format of plane */
> > + __u64 drm_format_mod; /* tiled mode */
> > + __u32 width; /* width of plane */
> > + __u32 height; /* height of plane */
> > + __u32 stride; /* stride of plane */
> > + __u32 size; /* size of plane in bytes, align on page*/
> > + __u32 x_pos; /* horizontal position of cursor plane */
> > + __u32 y_pos; /* vertical position of cursor plane*/
> > + __u32 x_hot; /* horizontal position of cursor hotspot */
> > + __u32 y_hot; /* vertical position of cursor hotspot */
> > + union {
> > + __u32 region_index; /* region index */
> > + __u32 dmabuf_id; /* dma-buf id */
> > + };
> > +};
> > +
> > +#define VFIO_DEVICE_QUERY_GFX_PLANE _IO(VFIO_TYPE, VFIO_BASE + 14)
> > +
> > +/**
> > + * VFIO_DEVICE_GET_GFX_DMABUF - _IOW(VFIO_TYPE, VFIO_BASE + 15, __u32)
> > + *
> > + * Return a new dma-buf file descriptor for an exposed guest framebuffer
> > + * described by the provided dmabuf_id. The dmabuf_id is returned from VFIO_
> > + * DEVICE_QUERY_GFX_PLANE as a token of the exposed guest framebuffer.
> > + */
> > +
> > +#define VFIO_DEVICE_GET_GFX_DMABUF _IO(VFIO_TYPE, VFIO_BASE + 15)
> > +
> > /* -------- API for Type1 VFIO IOMMU -------- */
> >
> > /**
>
> Looks good to me. Kirti, have you had a chance yet to verify this is
> sufficient for your region-based approach? It would be great to get
> confirmation of that ASAP so we can get this in. Thanks,
>
Alex, do you mind by merging this just through gvt tree? Or you would
like to merge this then send pull request for us then we can apply left?
--
Open Source Technology Center, Intel ltd.
$gpg --keyserver wwwkeys.pgp.net --recv-keys 4D781827
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v18 5/6] vfio: ABI for mdev display dma-buf operation
2017-11-16 3:21 ` Zhenyu Wang
@ 2017-11-16 4:11 ` Alex Williamson
2017-11-18 15:30 ` Alex Williamson
0 siblings, 1 reply; 19+ messages in thread
From: Alex Williamson @ 2017-11-16 4:11 UTC (permalink / raw)
To: Zhenyu Wang
Cc: Tina Zhang, kevin.tian, Daniel Vetter, intel-gfx,
joonas.lahtinen, linux-kernel, chris, kwankhede, zhiyuan.lv,
daniel, hang.yuan, intel-gvt-dev, zhi.a.wang, kraxel
On Thu, 16 Nov 2017 11:21:56 +0800
Zhenyu Wang <zhenyuw@linux.intel.com> wrote:
> On 2017.11.15 11:48:42 -0700, Alex Williamson wrote:
> > On Wed, 15 Nov 2017 17:11:54 +0800
> > Tina Zhang <tina.zhang@intel.com> wrote:
> >
> > > Add VFIO_DEVICE_QUERY_GFX_PLANE ioctl command to let user query and get
> > > a plane and its information. So far, two types of buffers are supported:
> > > buffers based on dma-buf and buffers based on region.
> > >
> > > This ioctl can be invoked with:
> > > 1) Either DMABUF or REGION flag. Vendor driver returns a plane_info
> > > successfully only when the specific kind of buffer is supported.
> > > 2) Flag PROBE. And at the same time either DMABUF or REGION must be set,
> > > so that vendor driver returns success only when the specific kind of
> > > buffer is supported.
> > >
> > > Add VFIO_DEVICE_GET_GFX_DMABUF ioctl command to let user get a specific
> > > dma-buf fd of an exposed MDEV buffer provided by dmabuf_id which was
> > > returned in VFIO_DEVICE_QUERY_GFX_PLANE ioctl command.
> > >
> > > The life cycle of an exposed MDEV buffer is handled by userspace and
> > > tracked by kernel space. The returned dmabuf_id in struct vfio_device_
> > > query_gfx_plane can be a new id of a new exposed buffer or an old id of
> > > a re-exported buffer. Host user can check the value of dmabuf_id to see
> > > if it needs to create new resources according to the new exposed buffer
> > > or just re-use the existing resource related to the old buffer.
> > >
> > > v18:
> > > - update comments for VFIO_DEVICE_GET_GFX_DMABUF. (Alex)
> > >
> > > v17:
> > > - modify VFIO_DEVICE_GET_GFX_DMABUF interface. (Alex)
> > >
> > > v16:
> > > - add x_hot and y_hot fields. (Gerd)
> > > - add comments for VFIO_DEVICE_GET_GFX_DMABUF. (Alex)
> > > - rebase to 4.14.0-rc6.
> > >
> > > v15:
> > > - add a ioctl to get a dmabuf for a given dmabuf id. (Gerd)
> > >
> > > v14:
> > > - add PROBE, DMABUF and REGION flags. (Alex)
> > >
> > > v12:
> > > - add drm_format_mod back. (Gerd and Zhenyu)
> > > - add region_index. (Gerd)
> > >
> > > v11:
> > > - rename plane_type to drm_plane_type. (Gerd)
> > > - move fields of vfio_device_query_gfx_plane to vfio_device_gfx_plane_info.
> > > (Gerd)
> > > - remove drm_format_mod, start fields. (Daniel)
> > > - remove plane_id.
> > >
> > > v10:
> > > - refine the ABI API VFIO_DEVICE_QUERY_GFX_PLANE. (Alex) (Gerd)
> > >
> > > v3:
> > > - add a field gvt_plane_info in the drm_i915_gem_obj structure to save
> > > the decoded plane information to avoid look up while need the plane
> > > info. (Gerd)
> > >
> > > Signed-off-by: Tina Zhang <tina.zhang@intel.com>
> > > Cc: Gerd Hoffmann <kraxel@redhat.com>
> > > Cc: Alex Williamson <alex.williamson@redhat.com>
> > > Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
> > > ---
> > > include/uapi/linux/vfio.h | 62 +++++++++++++++++++++++++++++++++++++++++++++++
> > > 1 file changed, 62 insertions(+)
> > >
> > > diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h
> > > index ae46105..5c1cca2 100644
> > > --- a/include/uapi/linux/vfio.h
> > > +++ b/include/uapi/linux/vfio.h
> > > @@ -502,6 +502,68 @@ struct vfio_pci_hot_reset {
> > >
> > > #define VFIO_DEVICE_PCI_HOT_RESET _IO(VFIO_TYPE, VFIO_BASE + 13)
> > >
> > > +/**
> > > + * VFIO_DEVICE_QUERY_GFX_PLANE - _IOW(VFIO_TYPE, VFIO_BASE + 14,
> > > + * struct vfio_device_query_gfx_plane)
> > > + *
> > > + * Set the drm_plane_type and flags, then retrieve the gfx plane info.
> > > + *
> > > + * flags supported:
> > > + * - VFIO_GFX_PLANE_TYPE_PROBE and VFIO_GFX_PLANE_TYPE_DMABUF are set
> > > + * to ask if the mdev supports dma-buf. 0 on support, -EINVAL on no
> > > + * support for dma-buf.
> > > + * - VFIO_GFX_PLANE_TYPE_PROBE and VFIO_GFX_PLANE_TYPE_REGION are set
> > > + * to ask if the mdev supports region. 0 on support, -EINVAL on no
> > > + * support for region.
> > > + * - VFIO_GFX_PLANE_TYPE_DMABUF or VFIO_GFX_PLANE_TYPE_REGION is set
> > > + * with each call to query the plane info.
> > > + * - Others are invalid and return -EINVAL.
> > > + *
> > > + * Note:
> > > + * 1. Plane could be disabled by guest. In that case, success will be
> > > + * returned with zero-initialized drm_format, size, width and height
> > > + * fields.
> > > + * 2. x_hot/y_hot is set to 0xFFFFFFFF if no hotspot information available
> > > + *
> > > + * Return: 0 on success, -errno on other failure.
> > > + */
> > > +struct vfio_device_gfx_plane_info {
> > > + __u32 argsz;
> > > + __u32 flags;
> > > +#define VFIO_GFX_PLANE_TYPE_PROBE (1 << 0)
> > > +#define VFIO_GFX_PLANE_TYPE_DMABUF (1 << 1)
> > > +#define VFIO_GFX_PLANE_TYPE_REGION (1 << 2)
> > > + /* in */
> > > + __u32 drm_plane_type; /* type of plane: DRM_PLANE_TYPE_* */
> > > + /* out */
> > > + __u32 drm_format; /* drm format of plane */
> > > + __u64 drm_format_mod; /* tiled mode */
> > > + __u32 width; /* width of plane */
> > > + __u32 height; /* height of plane */
> > > + __u32 stride; /* stride of plane */
> > > + __u32 size; /* size of plane in bytes, align on page*/
> > > + __u32 x_pos; /* horizontal position of cursor plane */
> > > + __u32 y_pos; /* vertical position of cursor plane*/
> > > + __u32 x_hot; /* horizontal position of cursor hotspot */
> > > + __u32 y_hot; /* vertical position of cursor hotspot */
> > > + union {
> > > + __u32 region_index; /* region index */
> > > + __u32 dmabuf_id; /* dma-buf id */
> > > + };
> > > +};
> > > +
> > > +#define VFIO_DEVICE_QUERY_GFX_PLANE _IO(VFIO_TYPE, VFIO_BASE + 14)
> > > +
> > > +/**
> > > + * VFIO_DEVICE_GET_GFX_DMABUF - _IOW(VFIO_TYPE, VFIO_BASE + 15, __u32)
> > > + *
> > > + * Return a new dma-buf file descriptor for an exposed guest framebuffer
> > > + * described by the provided dmabuf_id. The dmabuf_id is returned from VFIO_
> > > + * DEVICE_QUERY_GFX_PLANE as a token of the exposed guest framebuffer.
> > > + */
> > > +
> > > +#define VFIO_DEVICE_GET_GFX_DMABUF _IO(VFIO_TYPE, VFIO_BASE + 15)
> > > +
> > > /* -------- API for Type1 VFIO IOMMU -------- */
> > >
> > > /**
> >
> > Looks good to me. Kirti, have you had a chance yet to verify this is
> > sufficient for your region-based approach? It would be great to get
> > confirmation of that ASAP so we can get this in. Thanks,
> >
>
> Alex, do you mind by merging this just through gvt tree? Or you would
> like to merge this then send pull request for us then we can apply left?
I'm fine with this going through the gvt tree, but I want some
confirmation from nvidia that this meets their needs as well before I
provide an ack. Thanks,
Alex
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v18 0/6] drm/i915/gvt: Dma-buf support for GVT-g
2017-11-15 22:48 ` Alex Williamson
@ 2017-11-16 9:33 ` Gerd Hoffmann
0 siblings, 0 replies; 19+ messages in thread
From: Gerd Hoffmann @ 2017-11-16 9:33 UTC (permalink / raw)
To: Alex Williamson
Cc: Tina Zhang, chris, joonas.lahtinen, zhenyuw, zhiyuan.lv,
zhi.a.wang, kevin.tian, daniel, kwankhede, hang.yuan, intel-gfx,
intel-gvt-dev, linux-kernel
> > > This patch set can be tried with the following example:
> > > git://git.kraxel.org/qemu branch: work/intel-vgpu
> > >
> >
> > Tested-by: Gerd Hoffmann <kraxel@redhat.com>
>
> Hi Gerd,
>
> Can you share the xml snippets required for the VM to make this work?
> Last I tried I couldn't get the display/video/hostdev configuration to
> get any enhanced behavior through the dmabuf. Thanks,
qemu built from the branch listed above.
Testing with a shell script right now, see below. First argument is the
mode. "vgpu-gtk" works fine. "vgpu-spice-remote" works too, even
remotely, but it's not very efficient (grabs display data via opengl
ReadPixels, then sends it over classic spice protocol).
For the latter I have a libvirt snippet too, which has to jump through a
few loops due to libvirt not having support for vgou display yet, with
the most annonying issue being that libvirt insists adding a emulated
vga to the guest if you configure spice.
HTH,
Gerd
====================== cut here ====================
#!/bin/sh
# args
mode="${1-vga}"; shift
# config
vers="26"
live="$(ls -t $HOME/iso/Fedora*Live*${vers}*.iso | head -1)"
name="$(basename $live)"
qemu="/usr/local/bin/qemu-system-x86_64"
uuid="aca92d96-6654-43d9-8f45-544c19e89f20"
path="/sys/bus/mdev/devices/${uuid}"
###########################################################################
# tweaks
case "$mode" in
vga)
args="-vga std"
;;
virtio)
args="-vga virtio"
;;
virtio-gl)
args=""
args="$args -vga virtio"
args="$args -display gtk,gl=on"
;;
vgpu-gtk)
args=""
args="$args -vga none"
args="$args -display gtk,gl=on"
args="$args -device vfio-pci,sysfsdev=${path},addr=0x5,x-display=on"
qemu="sudo $qemu"
;;
vgpu-sdl)
# intel sdl 1.2 patches ...
args=""
args="$args -vga none"
args="$args -display sdl"
args="$args -device vfio-pci,sysfsdev=${path},addr=0x5"
qemu="sudo $qemu"
;;
vgpu-spice-local)
# using spice, passing around dma-bufs
# FIXME: launch remote-viewer on unix socket
args=""
args="$args -vga none"
args="$args -spice disable-ticketing,gl=on,unix,addr=/tmp/spice-vgpu"
args="$args -device vfio-pci,sysfsdev=${path},addr=0x5,x-display=on"
qemu="sudo $qemu"
;;
vgpu-spice-remote)
# using spice, readpixels dmabuf,
# send traditional spice display updates
(sleep 1; remote-viewer spice://localhost:5909) &
args=""
args="$args -vga none"
args="$args -display egl-headless"
args="$args -spice disable-ticketing,gl=off,port=5909"
args="$args -device vfio-pci,sysfsdev=${path},addr=0x5,x-display=on"
qemu="sudo $qemu"
;;
*)
echo "unknown mode: $mode"
echo "valid modes:"
echo " vga virtio virtio-gl vgpu-gtk vgpu-sdl"
echo " vgpu-spice-local vgpu-spice-remote"
exit 1
;;
esac
###########################################################################
# go!
set -ex
exec $qemu -enable-kvm -name "$name" \
-boot menu=on -m 2G -usb \
-drive if=none,id=live,media=cdrom,file="$live" \
-netdev user,id=unet \
\
-device virtio-net-pci,addr=0x08,netdev=unet \
-device virtio-scsi-pci,addr=0x09 \
-device scsi-cd,drive=live,scsi-id=4,bootindex=1 \
-device usb-tablet \
\
$args "$@"
====================== cut here ====================
<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
<name>liveiso-vgpu-remote</name>
<uuid>a2fc1e5e-8370-44b2-a31f-140f441e0355</uuid>
<memory unit='KiB'>1048576</memory>
<currentMemory unit='KiB'>1048576</currentMemory>
<vcpu placement='static'>2</vcpu>
<os>
<type arch='x86_64' machine='pc-i440fx-2.8'>hvm</type>
<bootmenu enable='yes'/>
<bios useserial='yes'/>
</os>
<features>
<acpi/>
<apic/>
<vmport state='off'/>
</features>
<cpu mode='custom' match='exact' check='partial'>
<model fallback='allow'>Broadwell</model>
</cpu>
<clock offset='utc'>
<timer name='rtc' tickpolicy='catchup'/>
<timer name='pit' tickpolicy='delay'/>
<timer name='hpet' present='no'/>
</clock>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>restart</on_crash>
<devices>
<emulator>/usr/local/bin/qemu-system-x86_64</emulator>
<disk type='file' device='cdrom'>
<driver name='qemu' type='raw' cache='none' io='native'/>
<source file='/home/kraxel/iso/Fedora-Workstation-Live-x86_64-26-1.5.iso'/>
<target dev='sda' bus='scsi'/>
<readonly/>
<boot order='1'/>
<address type='drive' controller='0' bus='0' target='4' unit='0'/>
</disk>
<controller type='pci' index='0' model='pci-root'/>
<controller type='scsi' index='0' model='virtio-scsi'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x08' function='0x0'/>
</controller>
<controller type='usb' index='0' model='nec-xhci'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x14' function='0x0'/>
</controller>
<controller type='virtio-serial' index='0'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x0a' function='0x0'/>
</controller>
<interface type='network'>
<mac address='52:54:00:28:99:99'/>
<source network='bios'/>
<model type='virtio'/>
<boot order='2'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x09' function='0x0'/>
</interface>
<serial type='pty'>
<target port='0'/>
</serial>
<console type='pty'>
<target type='serial' port='0'/>
</console>
<channel type='unix'>
<target type='virtio' name='org.qemu.guest_agent.0'/>
<address type='virtio-serial' controller='0' bus='0' port='1'/>
</channel>
<input type='tablet' bus='usb'>
<address type='usb' bus='0' port='1'/>
</input>
<input type='mouse' bus='ps2'/>
<input type='keyboard' bus='ps2'/>
<graphics type='spice' autoport='yes'>
<listen type='address'/>
</graphics>
<sound model='ich6'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x19' function='0x0'/>
</sound>
<video>
<model type='cirrus' vram='16384' heads='1' primary='yes'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
</video>
<hostdev mode='subsystem' type='mdev' managed='no' model='vfio-pci'>
<source>
<address uuid='aca92d96-6654-43d9-8f45-544c19e89f20'/>
</source>
<address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/>
</hostdev>
<memballoon model='virtio'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x0b' function='0x0'/>
</memballoon>
</devices>
<qemu:commandline>
<qemu:arg value='-set'/>
<qemu:arg value='device.video0.driver=ne2k_pci'/>
<qemu:arg value='-set'/>
<qemu:arg value='device.hostdev0.x-display=yes'/>
<qemu:arg value='-display'/>
<qemu:arg value='egl-headless'/>
</qemu:commandline>
</domain>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v18 5/6] vfio: ABI for mdev display dma-buf operation
2017-11-16 4:11 ` Alex Williamson
@ 2017-11-18 15:30 ` Alex Williamson
2017-11-18 17:59 ` Kirti Wankhede
0 siblings, 1 reply; 19+ messages in thread
From: Alex Williamson @ 2017-11-18 15:30 UTC (permalink / raw)
To: Zhenyu Wang
Cc: Tina Zhang, kevin.tian, Daniel Vetter, intel-gfx,
joonas.lahtinen, linux-kernel, chris, kwankhede, zhiyuan.lv,
daniel, hang.yuan, intel-gvt-dev, zhi.a.wang, kraxel
Kirti?
On Wed, 15 Nov 2017 21:11:42 -0700
Alex Williamson <alex.williamson@redhat.com> wrote:
> On Thu, 16 Nov 2017 11:21:56 +0800
> Zhenyu Wang <zhenyuw@linux.intel.com> wrote:
>
> > On 2017.11.15 11:48:42 -0700, Alex Williamson wrote:
> > > On Wed, 15 Nov 2017 17:11:54 +0800
> > > Tina Zhang <tina.zhang@intel.com> wrote:
> > >
> > > > Add VFIO_DEVICE_QUERY_GFX_PLANE ioctl command to let user query and get
> > > > a plane and its information. So far, two types of buffers are supported:
> > > > buffers based on dma-buf and buffers based on region.
> > > >
> > > > This ioctl can be invoked with:
> > > > 1) Either DMABUF or REGION flag. Vendor driver returns a plane_info
> > > > successfully only when the specific kind of buffer is supported.
> > > > 2) Flag PROBE. And at the same time either DMABUF or REGION must be set,
> > > > so that vendor driver returns success only when the specific kind of
> > > > buffer is supported.
> > > >
> > > > Add VFIO_DEVICE_GET_GFX_DMABUF ioctl command to let user get a specific
> > > > dma-buf fd of an exposed MDEV buffer provided by dmabuf_id which was
> > > > returned in VFIO_DEVICE_QUERY_GFX_PLANE ioctl command.
> > > >
> > > > The life cycle of an exposed MDEV buffer is handled by userspace and
> > > > tracked by kernel space. The returned dmabuf_id in struct vfio_device_
> > > > query_gfx_plane can be a new id of a new exposed buffer or an old id of
> > > > a re-exported buffer. Host user can check the value of dmabuf_id to see
> > > > if it needs to create new resources according to the new exposed buffer
> > > > or just re-use the existing resource related to the old buffer.
> > > >
> > > > v18:
> > > > - update comments for VFIO_DEVICE_GET_GFX_DMABUF. (Alex)
> > > >
> > > > v17:
> > > > - modify VFIO_DEVICE_GET_GFX_DMABUF interface. (Alex)
> > > >
> > > > v16:
> > > > - add x_hot and y_hot fields. (Gerd)
> > > > - add comments for VFIO_DEVICE_GET_GFX_DMABUF. (Alex)
> > > > - rebase to 4.14.0-rc6.
> > > >
> > > > v15:
> > > > - add a ioctl to get a dmabuf for a given dmabuf id. (Gerd)
> > > >
> > > > v14:
> > > > - add PROBE, DMABUF and REGION flags. (Alex)
> > > >
> > > > v12:
> > > > - add drm_format_mod back. (Gerd and Zhenyu)
> > > > - add region_index. (Gerd)
> > > >
> > > > v11:
> > > > - rename plane_type to drm_plane_type. (Gerd)
> > > > - move fields of vfio_device_query_gfx_plane to vfio_device_gfx_plane_info.
> > > > (Gerd)
> > > > - remove drm_format_mod, start fields. (Daniel)
> > > > - remove plane_id.
> > > >
> > > > v10:
> > > > - refine the ABI API VFIO_DEVICE_QUERY_GFX_PLANE. (Alex) (Gerd)
> > > >
> > > > v3:
> > > > - add a field gvt_plane_info in the drm_i915_gem_obj structure to save
> > > > the decoded plane information to avoid look up while need the plane
> > > > info. (Gerd)
> > > >
> > > > Signed-off-by: Tina Zhang <tina.zhang@intel.com>
> > > > Cc: Gerd Hoffmann <kraxel@redhat.com>
> > > > Cc: Alex Williamson <alex.williamson@redhat.com>
> > > > Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
> > > > ---
> > > > include/uapi/linux/vfio.h | 62 +++++++++++++++++++++++++++++++++++++++++++++++
> > > > 1 file changed, 62 insertions(+)
> > > >
> > > > diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h
> > > > index ae46105..5c1cca2 100644
> > > > --- a/include/uapi/linux/vfio.h
> > > > +++ b/include/uapi/linux/vfio.h
> > > > @@ -502,6 +502,68 @@ struct vfio_pci_hot_reset {
> > > >
> > > > #define VFIO_DEVICE_PCI_HOT_RESET _IO(VFIO_TYPE, VFIO_BASE + 13)
> > > >
> > > > +/**
> > > > + * VFIO_DEVICE_QUERY_GFX_PLANE - _IOW(VFIO_TYPE, VFIO_BASE + 14,
> > > > + * struct vfio_device_query_gfx_plane)
> > > > + *
> > > > + * Set the drm_plane_type and flags, then retrieve the gfx plane info.
> > > > + *
> > > > + * flags supported:
> > > > + * - VFIO_GFX_PLANE_TYPE_PROBE and VFIO_GFX_PLANE_TYPE_DMABUF are set
> > > > + * to ask if the mdev supports dma-buf. 0 on support, -EINVAL on no
> > > > + * support for dma-buf.
> > > > + * - VFIO_GFX_PLANE_TYPE_PROBE and VFIO_GFX_PLANE_TYPE_REGION are set
> > > > + * to ask if the mdev supports region. 0 on support, -EINVAL on no
> > > > + * support for region.
> > > > + * - VFIO_GFX_PLANE_TYPE_DMABUF or VFIO_GFX_PLANE_TYPE_REGION is set
> > > > + * with each call to query the plane info.
> > > > + * - Others are invalid and return -EINVAL.
> > > > + *
> > > > + * Note:
> > > > + * 1. Plane could be disabled by guest. In that case, success will be
> > > > + * returned with zero-initialized drm_format, size, width and height
> > > > + * fields.
> > > > + * 2. x_hot/y_hot is set to 0xFFFFFFFF if no hotspot information available
> > > > + *
> > > > + * Return: 0 on success, -errno on other failure.
> > > > + */
> > > > +struct vfio_device_gfx_plane_info {
> > > > + __u32 argsz;
> > > > + __u32 flags;
> > > > +#define VFIO_GFX_PLANE_TYPE_PROBE (1 << 0)
> > > > +#define VFIO_GFX_PLANE_TYPE_DMABUF (1 << 1)
> > > > +#define VFIO_GFX_PLANE_TYPE_REGION (1 << 2)
> > > > + /* in */
> > > > + __u32 drm_plane_type; /* type of plane: DRM_PLANE_TYPE_* */
> > > > + /* out */
> > > > + __u32 drm_format; /* drm format of plane */
> > > > + __u64 drm_format_mod; /* tiled mode */
> > > > + __u32 width; /* width of plane */
> > > > + __u32 height; /* height of plane */
> > > > + __u32 stride; /* stride of plane */
> > > > + __u32 size; /* size of plane in bytes, align on page*/
> > > > + __u32 x_pos; /* horizontal position of cursor plane */
> > > > + __u32 y_pos; /* vertical position of cursor plane*/
> > > > + __u32 x_hot; /* horizontal position of cursor hotspot */
> > > > + __u32 y_hot; /* vertical position of cursor hotspot */
> > > > + union {
> > > > + __u32 region_index; /* region index */
> > > > + __u32 dmabuf_id; /* dma-buf id */
> > > > + };
> > > > +};
> > > > +
> > > > +#define VFIO_DEVICE_QUERY_GFX_PLANE _IO(VFIO_TYPE, VFIO_BASE + 14)
> > > > +
> > > > +/**
> > > > + * VFIO_DEVICE_GET_GFX_DMABUF - _IOW(VFIO_TYPE, VFIO_BASE + 15, __u32)
> > > > + *
> > > > + * Return a new dma-buf file descriptor for an exposed guest framebuffer
> > > > + * described by the provided dmabuf_id. The dmabuf_id is returned from VFIO_
> > > > + * DEVICE_QUERY_GFX_PLANE as a token of the exposed guest framebuffer.
> > > > + */
> > > > +
> > > > +#define VFIO_DEVICE_GET_GFX_DMABUF _IO(VFIO_TYPE, VFIO_BASE + 15)
> > > > +
> > > > /* -------- API for Type1 VFIO IOMMU -------- */
> > > >
> > > > /**
> > >
> > > Looks good to me. Kirti, have you had a chance yet to verify this is
> > > sufficient for your region-based approach? It would be great to get
> > > confirmation of that ASAP so we can get this in. Thanks,
> > >
> >
> > Alex, do you mind by merging this just through gvt tree? Or you would
> > like to merge this then send pull request for us then we can apply left?
>
> I'm fine with this going through the gvt tree, but I want some
> confirmation from nvidia that this meets their needs as well before I
> provide an ack. Thanks,
>
> Alex
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v18 5/6] vfio: ABI for mdev display dma-buf operation
2017-11-18 15:30 ` Alex Williamson
@ 2017-11-18 17:59 ` Kirti Wankhede
2017-11-18 18:13 ` Alex Williamson
0 siblings, 1 reply; 19+ messages in thread
From: Kirti Wankhede @ 2017-11-18 17:59 UTC (permalink / raw)
To: Alex Williamson, Zhenyu Wang
Cc: Tina Zhang, kevin.tian, Daniel Vetter, intel-gfx,
joonas.lahtinen, linux-kernel, chris, zhiyuan.lv, daniel,
hang.yuan, intel-gvt-dev, zhi.a.wang, kraxel
Extremely sorry for the delay.
This works for VFIO_GFX_PLANE_TYPE_REGION. Tested with local changes.
Reviewed-by: Kirti Wankhede <kwankhede@nvidia.com>
Thanks,
Kirti
On 11/18/2017 9:00 PM, Alex Williamson wrote:
>
> Kirti?
>
> On Wed, 15 Nov 2017 21:11:42 -0700
> Alex Williamson <alex.williamson@redhat.com> wrote:
>
>> On Thu, 16 Nov 2017 11:21:56 +0800
>> Zhenyu Wang <zhenyuw@linux.intel.com> wrote:
>>
>>> On 2017.11.15 11:48:42 -0700, Alex Williamson wrote:
>>>> On Wed, 15 Nov 2017 17:11:54 +0800
>>>> Tina Zhang <tina.zhang@intel.com> wrote:
>>>>
>>>>> Add VFIO_DEVICE_QUERY_GFX_PLANE ioctl command to let user query and get
>>>>> a plane and its information. So far, two types of buffers are supported:
>>>>> buffers based on dma-buf and buffers based on region.
>>>>>
>>>>> This ioctl can be invoked with:
>>>>> 1) Either DMABUF or REGION flag. Vendor driver returns a plane_info
>>>>> successfully only when the specific kind of buffer is supported.
>>>>> 2) Flag PROBE. And at the same time either DMABUF or REGION must be set,
>>>>> so that vendor driver returns success only when the specific kind of
>>>>> buffer is supported.
>>>>>
>>>>> Add VFIO_DEVICE_GET_GFX_DMABUF ioctl command to let user get a specific
>>>>> dma-buf fd of an exposed MDEV buffer provided by dmabuf_id which was
>>>>> returned in VFIO_DEVICE_QUERY_GFX_PLANE ioctl command.
>>>>>
>>>>> The life cycle of an exposed MDEV buffer is handled by userspace and
>>>>> tracked by kernel space. The returned dmabuf_id in struct vfio_device_
>>>>> query_gfx_plane can be a new id of a new exposed buffer or an old id of
>>>>> a re-exported buffer. Host user can check the value of dmabuf_id to see
>>>>> if it needs to create new resources according to the new exposed buffer
>>>>> or just re-use the existing resource related to the old buffer.
>>>>>
>>>>> v18:
>>>>> - update comments for VFIO_DEVICE_GET_GFX_DMABUF. (Alex)
>>>>>
>>>>> v17:
>>>>> - modify VFIO_DEVICE_GET_GFX_DMABUF interface. (Alex)
>>>>>
>>>>> v16:
>>>>> - add x_hot and y_hot fields. (Gerd)
>>>>> - add comments for VFIO_DEVICE_GET_GFX_DMABUF. (Alex)
>>>>> - rebase to 4.14.0-rc6.
>>>>>
>>>>> v15:
>>>>> - add a ioctl to get a dmabuf for a given dmabuf id. (Gerd)
>>>>>
>>>>> v14:
>>>>> - add PROBE, DMABUF and REGION flags. (Alex)
>>>>>
>>>>> v12:
>>>>> - add drm_format_mod back. (Gerd and Zhenyu)
>>>>> - add region_index. (Gerd)
>>>>>
>>>>> v11:
>>>>> - rename plane_type to drm_plane_type. (Gerd)
>>>>> - move fields of vfio_device_query_gfx_plane to vfio_device_gfx_plane_info.
>>>>> (Gerd)
>>>>> - remove drm_format_mod, start fields. (Daniel)
>>>>> - remove plane_id.
>>>>>
>>>>> v10:
>>>>> - refine the ABI API VFIO_DEVICE_QUERY_GFX_PLANE. (Alex) (Gerd)
>>>>>
>>>>> v3:
>>>>> - add a field gvt_plane_info in the drm_i915_gem_obj structure to save
>>>>> the decoded plane information to avoid look up while need the plane
>>>>> info. (Gerd)
>>>>>
>>>>> Signed-off-by: Tina Zhang <tina.zhang@intel.com>
>>>>> Cc: Gerd Hoffmann <kraxel@redhat.com>
>>>>> Cc: Alex Williamson <alex.williamson@redhat.com>
>>>>> Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
>>>>> ---
>>>>> include/uapi/linux/vfio.h | 62 +++++++++++++++++++++++++++++++++++++++++++++++
>>>>> 1 file changed, 62 insertions(+)
>>>>>
>>>>> diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h
>>>>> index ae46105..5c1cca2 100644
>>>>> --- a/include/uapi/linux/vfio.h
>>>>> +++ b/include/uapi/linux/vfio.h
>>>>> @@ -502,6 +502,68 @@ struct vfio_pci_hot_reset {
>>>>>
>>>>> #define VFIO_DEVICE_PCI_HOT_RESET _IO(VFIO_TYPE, VFIO_BASE + 13)
>>>>>
>>>>> +/**
>>>>> + * VFIO_DEVICE_QUERY_GFX_PLANE - _IOW(VFIO_TYPE, VFIO_BASE + 14,
>>>>> + * struct vfio_device_query_gfx_plane)
>>>>> + *
>>>>> + * Set the drm_plane_type and flags, then retrieve the gfx plane info.
>>>>> + *
>>>>> + * flags supported:
>>>>> + * - VFIO_GFX_PLANE_TYPE_PROBE and VFIO_GFX_PLANE_TYPE_DMABUF are set
>>>>> + * to ask if the mdev supports dma-buf. 0 on support, -EINVAL on no
>>>>> + * support for dma-buf.
>>>>> + * - VFIO_GFX_PLANE_TYPE_PROBE and VFIO_GFX_PLANE_TYPE_REGION are set
>>>>> + * to ask if the mdev supports region. 0 on support, -EINVAL on no
>>>>> + * support for region.
>>>>> + * - VFIO_GFX_PLANE_TYPE_DMABUF or VFIO_GFX_PLANE_TYPE_REGION is set
>>>>> + * with each call to query the plane info.
>>>>> + * - Others are invalid and return -EINVAL.
>>>>> + *
>>>>> + * Note:
>>>>> + * 1. Plane could be disabled by guest. In that case, success will be
>>>>> + * returned with zero-initialized drm_format, size, width and height
>>>>> + * fields.
>>>>> + * 2. x_hot/y_hot is set to 0xFFFFFFFF if no hotspot information available
>>>>> + *
>>>>> + * Return: 0 on success, -errno on other failure.
>>>>> + */
>>>>> +struct vfio_device_gfx_plane_info {
>>>>> + __u32 argsz;
>>>>> + __u32 flags;
>>>>> +#define VFIO_GFX_PLANE_TYPE_PROBE (1 << 0)
>>>>> +#define VFIO_GFX_PLANE_TYPE_DMABUF (1 << 1)
>>>>> +#define VFIO_GFX_PLANE_TYPE_REGION (1 << 2)
>>>>> + /* in */
>>>>> + __u32 drm_plane_type; /* type of plane: DRM_PLANE_TYPE_* */
>>>>> + /* out */
>>>>> + __u32 drm_format; /* drm format of plane */
>>>>> + __u64 drm_format_mod; /* tiled mode */
>>>>> + __u32 width; /* width of plane */
>>>>> + __u32 height; /* height of plane */
>>>>> + __u32 stride; /* stride of plane */
>>>>> + __u32 size; /* size of plane in bytes, align on page*/
>>>>> + __u32 x_pos; /* horizontal position of cursor plane */
>>>>> + __u32 y_pos; /* vertical position of cursor plane*/
>>>>> + __u32 x_hot; /* horizontal position of cursor hotspot */
>>>>> + __u32 y_hot; /* vertical position of cursor hotspot */
>>>>> + union {
>>>>> + __u32 region_index; /* region index */
>>>>> + __u32 dmabuf_id; /* dma-buf id */
>>>>> + };
>>>>> +};
>>>>> +
>>>>> +#define VFIO_DEVICE_QUERY_GFX_PLANE _IO(VFIO_TYPE, VFIO_BASE + 14)
>>>>> +
>>>>> +/**
>>>>> + * VFIO_DEVICE_GET_GFX_DMABUF - _IOW(VFIO_TYPE, VFIO_BASE + 15, __u32)
>>>>> + *
>>>>> + * Return a new dma-buf file descriptor for an exposed guest framebuffer
>>>>> + * described by the provided dmabuf_id. The dmabuf_id is returned from VFIO_
>>>>> + * DEVICE_QUERY_GFX_PLANE as a token of the exposed guest framebuffer.
>>>>> + */
>>>>> +
>>>>> +#define VFIO_DEVICE_GET_GFX_DMABUF _IO(VFIO_TYPE, VFIO_BASE + 15)
>>>>> +
>>>>> /* -------- API for Type1 VFIO IOMMU -------- */
>>>>>
>>>>> /**
>>>>
>>>> Looks good to me. Kirti, have you had a chance yet to verify this is
>>>> sufficient for your region-based approach? It would be great to get
>>>> confirmation of that ASAP so we can get this in. Thanks,
>>>>
>>>
>>> Alex, do you mind by merging this just through gvt tree? Or you would
>>> like to merge this then send pull request for us then we can apply left?
>>
>> I'm fine with this going through the gvt tree, but I want some
>> confirmation from nvidia that this meets their needs as well before I
>> provide an ack. Thanks,
>>
>> Alex
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v18 5/6] vfio: ABI for mdev display dma-buf operation
2017-11-18 17:59 ` Kirti Wankhede
@ 2017-11-18 18:13 ` Alex Williamson
0 siblings, 0 replies; 19+ messages in thread
From: Alex Williamson @ 2017-11-18 18:13 UTC (permalink / raw)
To: Kirti Wankhede
Cc: Zhenyu Wang, Tina Zhang, kevin.tian, Daniel Vetter, intel-gfx,
joonas.lahtinen, linux-kernel, chris, zhiyuan.lv, daniel,
hang.yuan, intel-gvt-dev, zhi.a.wang, kraxel
On Sat, 18 Nov 2017 23:29:31 +0530
Kirti Wankhede <kwankhede@nvidia.com> wrote:
> Extremely sorry for the delay.
> This works for VFIO_GFX_PLANE_TYPE_REGION. Tested with local changes.
>
> Reviewed-by: Kirti Wankhede <kwankhede@nvidia.com>
With that,
Acked-by: Alex Williamson <alex.williamson@redhat.com>
> On 11/18/2017 9:00 PM, Alex Williamson wrote:
> >
> > Kirti?
> >
> > On Wed, 15 Nov 2017 21:11:42 -0700
> > Alex Williamson <alex.williamson@redhat.com> wrote:
> >
> >> On Thu, 16 Nov 2017 11:21:56 +0800
> >> Zhenyu Wang <zhenyuw@linux.intel.com> wrote:
> >>
> >>> On 2017.11.15 11:48:42 -0700, Alex Williamson wrote:
> >>>> On Wed, 15 Nov 2017 17:11:54 +0800
> >>>> Tina Zhang <tina.zhang@intel.com> wrote:
> >>>>
> >>>>> Add VFIO_DEVICE_QUERY_GFX_PLANE ioctl command to let user query and get
> >>>>> a plane and its information. So far, two types of buffers are supported:
> >>>>> buffers based on dma-buf and buffers based on region.
> >>>>>
> >>>>> This ioctl can be invoked with:
> >>>>> 1) Either DMABUF or REGION flag. Vendor driver returns a plane_info
> >>>>> successfully only when the specific kind of buffer is supported.
> >>>>> 2) Flag PROBE. And at the same time either DMABUF or REGION must be set,
> >>>>> so that vendor driver returns success only when the specific kind of
> >>>>> buffer is supported.
> >>>>>
> >>>>> Add VFIO_DEVICE_GET_GFX_DMABUF ioctl command to let user get a specific
> >>>>> dma-buf fd of an exposed MDEV buffer provided by dmabuf_id which was
> >>>>> returned in VFIO_DEVICE_QUERY_GFX_PLANE ioctl command.
> >>>>>
> >>>>> The life cycle of an exposed MDEV buffer is handled by userspace and
> >>>>> tracked by kernel space. The returned dmabuf_id in struct vfio_device_
> >>>>> query_gfx_plane can be a new id of a new exposed buffer or an old id of
> >>>>> a re-exported buffer. Host user can check the value of dmabuf_id to see
> >>>>> if it needs to create new resources according to the new exposed buffer
> >>>>> or just re-use the existing resource related to the old buffer.
> >>>>>
> >>>>> v18:
> >>>>> - update comments for VFIO_DEVICE_GET_GFX_DMABUF. (Alex)
> >>>>>
> >>>>> v17:
> >>>>> - modify VFIO_DEVICE_GET_GFX_DMABUF interface. (Alex)
> >>>>>
> >>>>> v16:
> >>>>> - add x_hot and y_hot fields. (Gerd)
> >>>>> - add comments for VFIO_DEVICE_GET_GFX_DMABUF. (Alex)
> >>>>> - rebase to 4.14.0-rc6.
> >>>>>
> >>>>> v15:
> >>>>> - add a ioctl to get a dmabuf for a given dmabuf id. (Gerd)
> >>>>>
> >>>>> v14:
> >>>>> - add PROBE, DMABUF and REGION flags. (Alex)
> >>>>>
> >>>>> v12:
> >>>>> - add drm_format_mod back. (Gerd and Zhenyu)
> >>>>> - add region_index. (Gerd)
> >>>>>
> >>>>> v11:
> >>>>> - rename plane_type to drm_plane_type. (Gerd)
> >>>>> - move fields of vfio_device_query_gfx_plane to vfio_device_gfx_plane_info.
> >>>>> (Gerd)
> >>>>> - remove drm_format_mod, start fields. (Daniel)
> >>>>> - remove plane_id.
> >>>>>
> >>>>> v10:
> >>>>> - refine the ABI API VFIO_DEVICE_QUERY_GFX_PLANE. (Alex) (Gerd)
> >>>>>
> >>>>> v3:
> >>>>> - add a field gvt_plane_info in the drm_i915_gem_obj structure to save
> >>>>> the decoded plane information to avoid look up while need the plane
> >>>>> info. (Gerd)
> >>>>>
> >>>>> Signed-off-by: Tina Zhang <tina.zhang@intel.com>
> >>>>> Cc: Gerd Hoffmann <kraxel@redhat.com>
> >>>>> Cc: Alex Williamson <alex.williamson@redhat.com>
> >>>>> Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
> >>>>> ---
> >>>>> include/uapi/linux/vfio.h | 62 +++++++++++++++++++++++++++++++++++++++++++++++
> >>>>> 1 file changed, 62 insertions(+)
> >>>>>
> >>>>> diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h
> >>>>> index ae46105..5c1cca2 100644
> >>>>> --- a/include/uapi/linux/vfio.h
> >>>>> +++ b/include/uapi/linux/vfio.h
> >>>>> @@ -502,6 +502,68 @@ struct vfio_pci_hot_reset {
> >>>>>
> >>>>> #define VFIO_DEVICE_PCI_HOT_RESET _IO(VFIO_TYPE, VFIO_BASE + 13)
> >>>>>
> >>>>> +/**
> >>>>> + * VFIO_DEVICE_QUERY_GFX_PLANE - _IOW(VFIO_TYPE, VFIO_BASE + 14,
> >>>>> + * struct vfio_device_query_gfx_plane)
> >>>>> + *
> >>>>> + * Set the drm_plane_type and flags, then retrieve the gfx plane info.
> >>>>> + *
> >>>>> + * flags supported:
> >>>>> + * - VFIO_GFX_PLANE_TYPE_PROBE and VFIO_GFX_PLANE_TYPE_DMABUF are set
> >>>>> + * to ask if the mdev supports dma-buf. 0 on support, -EINVAL on no
> >>>>> + * support for dma-buf.
> >>>>> + * - VFIO_GFX_PLANE_TYPE_PROBE and VFIO_GFX_PLANE_TYPE_REGION are set
> >>>>> + * to ask if the mdev supports region. 0 on support, -EINVAL on no
> >>>>> + * support for region.
> >>>>> + * - VFIO_GFX_PLANE_TYPE_DMABUF or VFIO_GFX_PLANE_TYPE_REGION is set
> >>>>> + * with each call to query the plane info.
> >>>>> + * - Others are invalid and return -EINVAL.
> >>>>> + *
> >>>>> + * Note:
> >>>>> + * 1. Plane could be disabled by guest. In that case, success will be
> >>>>> + * returned with zero-initialized drm_format, size, width and height
> >>>>> + * fields.
> >>>>> + * 2. x_hot/y_hot is set to 0xFFFFFFFF if no hotspot information available
> >>>>> + *
> >>>>> + * Return: 0 on success, -errno on other failure.
> >>>>> + */
> >>>>> +struct vfio_device_gfx_plane_info {
> >>>>> + __u32 argsz;
> >>>>> + __u32 flags;
> >>>>> +#define VFIO_GFX_PLANE_TYPE_PROBE (1 << 0)
> >>>>> +#define VFIO_GFX_PLANE_TYPE_DMABUF (1 << 1)
> >>>>> +#define VFIO_GFX_PLANE_TYPE_REGION (1 << 2)
> >>>>> + /* in */
> >>>>> + __u32 drm_plane_type; /* type of plane: DRM_PLANE_TYPE_* */
> >>>>> + /* out */
> >>>>> + __u32 drm_format; /* drm format of plane */
> >>>>> + __u64 drm_format_mod; /* tiled mode */
> >>>>> + __u32 width; /* width of plane */
> >>>>> + __u32 height; /* height of plane */
> >>>>> + __u32 stride; /* stride of plane */
> >>>>> + __u32 size; /* size of plane in bytes, align on page*/
> >>>>> + __u32 x_pos; /* horizontal position of cursor plane */
> >>>>> + __u32 y_pos; /* vertical position of cursor plane*/
> >>>>> + __u32 x_hot; /* horizontal position of cursor hotspot */
> >>>>> + __u32 y_hot; /* vertical position of cursor hotspot */
> >>>>> + union {
> >>>>> + __u32 region_index; /* region index */
> >>>>> + __u32 dmabuf_id; /* dma-buf id */
> >>>>> + };
> >>>>> +};
> >>>>> +
> >>>>> +#define VFIO_DEVICE_QUERY_GFX_PLANE _IO(VFIO_TYPE, VFIO_BASE + 14)
> >>>>> +
> >>>>> +/**
> >>>>> + * VFIO_DEVICE_GET_GFX_DMABUF - _IOW(VFIO_TYPE, VFIO_BASE + 15, __u32)
> >>>>> + *
> >>>>> + * Return a new dma-buf file descriptor for an exposed guest framebuffer
> >>>>> + * described by the provided dmabuf_id. The dmabuf_id is returned from VFIO_
> >>>>> + * DEVICE_QUERY_GFX_PLANE as a token of the exposed guest framebuffer.
> >>>>> + */
> >>>>> +
> >>>>> +#define VFIO_DEVICE_GET_GFX_DMABUF _IO(VFIO_TYPE, VFIO_BASE + 15)
> >>>>> +
> >>>>> /* -------- API for Type1 VFIO IOMMU -------- */
> >>>>>
> >>>>> /**
> >>>>
> >>>> Looks good to me. Kirti, have you had a chance yet to verify this is
> >>>> sufficient for your region-based approach? It would be great to get
> >>>> confirmation of that ASAP so we can get this in. Thanks,
> >>>>
> >>>
> >>> Alex, do you mind by merging this just through gvt tree? Or you would
> >>> like to merge this then send pull request for us then we can apply left?
> >>
> >> I'm fine with this going through the gvt tree, but I want some
> >> confirmation from nvidia that this meets their needs as well before I
> >> provide an ack. Thanks,
> >>
> >> Alex
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v18 0/6] drm/i915/gvt: Dma-buf support for GVT-g
2017-11-15 10:49 ` [PATCH v18 0/6] drm/i915/gvt: Dma-buf " Gerd Hoffmann
2017-11-15 22:48 ` Alex Williamson
@ 2017-11-23 6:12 ` Zhenyu Wang
2017-11-23 7:51 ` Zhang, Tina
1 sibling, 1 reply; 19+ messages in thread
From: Zhenyu Wang @ 2017-11-23 6:12 UTC (permalink / raw)
To: Gerd Hoffmann
Cc: Tina Zhang, kevin.tian, linux-kernel, intel-gfx, joonas.lahtinen,
kwankhede, zhenyuw, chris, alex.williamson, zhiyuan.lv, daniel,
hang.yuan, intel-gvt-dev, zhi.a.wang
[-- Attachment #1: Type: text/plain, Size: 2287 bytes --]
On 2017.11.15 11:49:00 +0100, Gerd Hoffmann wrote:
> On Wed, Nov 15, 2017 at 05:11:49PM +0800, Tina Zhang wrote:
> > v17->v18:
> > 1) unmap vgpu's opregion when destroying vgpu.
> > 2) update comments for VFIO_DEVICE_GET_GFX_DMABUF. (Alex)
>
> > This patch set adds the dma-buf support for intel GVT-g.
> >
> > dma-buf is an uniform mechanism to share DMA buffers across different
> > devices and subsystems. dma-buf for intel GVT-g is mainly used to share
> > the vgpu's framebuffer to userspace to leverage userspace graphics stacks
> > to render the framebuffer to the display monitor.
> >
> > The main idea is that we create a gem object and set vgpu's framebuffer as
> > its backing storage. Then, export a dma-buf associated with this gem object.
> > With the fd of this dma-buf, userspace can directly handle this buffer.
> >
> > This patch set can be tried with the following example:
> > git://git.kraxel.org/qemu branch: work/intel-vgpu
> >
> > A topic branch with the latest patch set is:
> > https://github.com/intel/gvt-linux.git branch: topic/dmabuf
>
> Tested-by: Gerd Hoffmann <kraxel@redhat.com>
>
After debugging with Tina on one left race that fixed by
https://lists.freedesktop.org/archives/intel-gvt-dev/2017-November/002505.html
I still need below qemu fix for proper cursor handling, otherwise qemu
just crashed when I click in my terminal program which hides cursor then.
diff --git a/hw/vfio/display.c b/hw/vfio/display.c
index e500ec2cb1..d9a044b080 100644
--- a/hw/vfio/display.c
+++ b/hw/vfio/display.c
@@ -169,8 +169,9 @@ static void vfio_display_dmabuf_update(void *opaque)
cursor = vfio_display_get_dmabuf(vdev, DRM_PLANE_TYPE_CURSOR);
if (vdev->cursor != cursor) {
vdev->cursor = cursor;
- dpy_gl_cursor_dmabuf(vdev->display_con,
- &cursor->buf);
+ if (cursor)
+ dpy_gl_cursor_dmabuf(vdev->display_con,
+ &cursor->buf);
free_bufs = true;
}
if (cursor != NULL) {
And with these it seems pretty fine now that I'll queue them up for -next pull.
thanks
--
Open Source Technology Center, Intel ltd.
$gpg --keyserver wwwkeys.pgp.net --recv-keys 4D781827
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]
^ permalink raw reply [flat|nested] 19+ messages in thread
* RE: [PATCH v18 0/6] drm/i915/gvt: Dma-buf support for GVT-g
2017-11-23 6:12 ` Zhenyu Wang
@ 2017-11-23 7:51 ` Zhang, Tina
0 siblings, 0 replies; 19+ messages in thread
From: Zhang, Tina @ 2017-11-23 7:51 UTC (permalink / raw)
To: Zhenyu Wang, Gerd Hoffmann
Cc: Tian, Kevin, alex.williamson, intel-gfx, joonas.lahtinen, Wang,
Zhi A, linux-kernel, kwankhede, Lv, Zhiyuan, daniel, chris,
intel-gvt-dev, Yuan, Hang
> -----Original Message-----
> From: intel-gvt-dev [mailto:intel-gvt-dev-bounces@lists.freedesktop.org] On
> Behalf Of Zhenyu Wang
> Sent: Thursday, November 23, 2017 2:13 PM
> To: Gerd Hoffmann <kraxel@redhat.com>
> Cc: Tian, Kevin <kevin.tian@intel.com>; alex.williamson@redhat.com; intel-
> gfx@lists.freedesktop.org; joonas.lahtinen@linux.intel.com; Wang, Zhi A
> <zhi.a.wang@intel.com>; linux-kernel@vger.kernel.org;
> zhenyuw@linux.intel.com; Zhang, Tina <tina.zhang@intel.com>;
> kwankhede@nvidia.com; Lv, Zhiyuan <zhiyuan.lv@intel.com>; daniel@ffwll.ch;
> chris@chris-wilson.co.uk; intel-gvt-dev@lists.freedesktop.org; Yuan, Hang
> <hang.yuan@intel.com>
> Subject: Re: [PATCH v18 0/6] drm/i915/gvt: Dma-buf support for GVT-g
>
> On 2017.11.15 11:49:00 +0100, Gerd Hoffmann wrote:
> > On Wed, Nov 15, 2017 at 05:11:49PM +0800, Tina Zhang wrote:
> > > v17->v18:
> > > 1) unmap vgpu's opregion when destroying vgpu.
> > > 2) update comments for VFIO_DEVICE_GET_GFX_DMABUF. (Alex)
> >
> > > This patch set adds the dma-buf support for intel GVT-g.
> > >
> > > dma-buf is an uniform mechanism to share DMA buffers across
> > > different devices and subsystems. dma-buf for intel GVT-g is mainly
> > > used to share the vgpu's framebuffer to userspace to leverage
> > > userspace graphics stacks to render the framebuffer to the display monitor.
> > >
> > > The main idea is that we create a gem object and set vgpu's
> > > framebuffer as its backing storage. Then, export a dma-buf associated with
> this gem object.
> > > With the fd of this dma-buf, userspace can directly handle this buffer.
> > >
> > > This patch set can be tried with the following example:
> > > git://git.kraxel.org/qemu branch: work/intel-vgpu
> > >
> > > A topic branch with the latest patch set is:
> > > https://github.com/intel/gvt-linux.git branch: topic/dmabuf
> >
> > Tested-by: Gerd Hoffmann <kraxel@redhat.com>
> >
>
> After debugging with Tina on one left race that fixed by
> https://lists.freedesktop.org/archives/intel-gvt-dev/2017-
> November/002505.html
The next version of this patch set will include this patch.
Thanks.
BR,
Tina
>
> I still need below qemu fix for proper cursor handling, otherwise qemu just
> crashed when I click in my terminal program which hides cursor then.
>
> diff --git a/hw/vfio/display.c b/hw/vfio/display.c index
> e500ec2cb1..d9a044b080 100644
> --- a/hw/vfio/display.c
> +++ b/hw/vfio/display.c
> @@ -169,8 +169,9 @@ static void vfio_display_dmabuf_update(void *opaque)
> cursor = vfio_display_get_dmabuf(vdev, DRM_PLANE_TYPE_CURSOR);
> if (vdev->cursor != cursor) {
> vdev->cursor = cursor;
> - dpy_gl_cursor_dmabuf(vdev->display_con,
> - &cursor->buf);
> + if (cursor)
> + dpy_gl_cursor_dmabuf(vdev->display_con,
> + &cursor->buf);
> free_bufs = true;
> }
> if (cursor != NULL) {
>
> And with these it seems pretty fine now that I'll queue them up for -next pull.
>
> thanks
>
> --
> Open Source Technology Center, Intel ltd.
>
> $gpg --keyserver wwwkeys.pgp.net --recv-keys 4D781827
^ permalink raw reply [flat|nested] 19+ messages in thread
end of thread, other threads:[~2017-11-23 7:51 UTC | newest]
Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-11-15 9:11 [PATCH v18 0/6] drm/i915/gvt: Dma-buf support for GVT-g Tina Zhang
2017-11-15 9:11 ` [PATCH v18 1/6] drm/i915/gvt: Add framebuffer decoder support Tina Zhang
2017-11-15 9:11 ` [PATCH v18 2/6] drm: Introduce RGB 64-bit 16:16:16:16 float format Tina Zhang
2017-11-15 9:11 ` [PATCH v18 3/6] drm/i915/gvt: Add " Tina Zhang
2017-11-15 9:11 ` [PATCH v18 4/6] drm/i915/gvt: Add opregion support Tina Zhang
2017-11-15 9:11 ` [PATCH v18 5/6] vfio: ABI for mdev display dma-buf operation Tina Zhang
2017-11-15 10:47 ` Gerd Hoffmann
2017-11-15 18:48 ` Alex Williamson
2017-11-16 3:21 ` Zhenyu Wang
2017-11-16 4:11 ` Alex Williamson
2017-11-18 15:30 ` Alex Williamson
2017-11-18 17:59 ` Kirti Wankhede
2017-11-18 18:13 ` Alex Williamson
2017-11-15 9:11 ` [PATCH v18 6/6] drm/i915/gvt: Dmabuf support for GVT-g Tina Zhang
2017-11-15 10:49 ` [PATCH v18 0/6] drm/i915/gvt: Dma-buf " Gerd Hoffmann
2017-11-15 22:48 ` Alex Williamson
2017-11-16 9:33 ` Gerd Hoffmann
2017-11-23 6:12 ` Zhenyu Wang
2017-11-23 7:51 ` Zhang, Tina
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).