aboutsummaryrefslogtreecommitdiffstats
path: root/samples
diff options
context:
space:
mode:
authorGerd Hoffmann <kraxel@redhat.com>2018-05-11 11:05:04 -0400
committerAlex Williamson <alex.williamson@redhat.com>2018-06-08 12:24:16 -0400
commita5e6e6505f38f7bce1d3576503a2bffff3fa888c (patch)
treeb211d78579f7056b73a05f927e2e96d58ca8278e /samples
parentcacade1946a41b38dcdf3defb0f931453587eac9 (diff)
sample: vfio bochs vbe display (host device for bochs-drm)
Display device, demo-ing the vfio dmabuf display interface (VFIO_GFX_PLANE_TYPE_DMABUF). Compatible enough to qemu stdvga that bochs-drm.ko can be used as guest driver. Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
Diffstat (limited to 'samples')
-rw-r--r--samples/Kconfig13
-rw-r--r--samples/vfio-mdev/Makefile1
-rw-r--r--samples/vfio-mdev/mbochs.c1406
3 files changed, 1420 insertions, 0 deletions
diff --git a/samples/Kconfig b/samples/Kconfig
index a6ff147d8744..3aeaaca77831 100644
--- a/samples/Kconfig
+++ b/samples/Kconfig
@@ -132,6 +132,19 @@ config SAMPLE_VFIO_MDEV_MDPY_FB
132 help 132 help
133 Guest fbdev driver for the virtual display sample driver. 133 Guest fbdev driver for the virtual display sample driver.
134 134
135config SAMPLE_VFIO_MDEV_MBOCHS
136 tristate "Build VFIO mdpy example mediated device sample code -- loadable modules only"
137 depends on VFIO_MDEV_DEVICE && m
138 help
139 Build a virtual display sample driver for use as a VFIO
140 mediated device. It supports the region display interface
141 (VFIO_GFX_PLANE_TYPE_DMABUF).
142 Emulate enough of qemu stdvga to make bochs-drm.ko happy.
143 That is basically the vram memory bar and the bochs dispi
144 interface vbe registers in the mmio register bar.
145 Specifically it does *not* include any legacy vga stuff.
146 Device looks a lot like "qemu -device secondary-vga".
147
135config SAMPLE_STATX 148config SAMPLE_STATX
136 bool "Build example extended-stat using code" 149 bool "Build example extended-stat using code"
137 depends on BROKEN 150 depends on BROKEN
diff --git a/samples/vfio-mdev/Makefile b/samples/vfio-mdev/Makefile
index 7a5790aaec9c..7db889ca135c 100644
--- a/samples/vfio-mdev/Makefile
+++ b/samples/vfio-mdev/Makefile
@@ -1,3 +1,4 @@
1obj-$(CONFIG_SAMPLE_VFIO_MDEV_MTTY) += mtty.o 1obj-$(CONFIG_SAMPLE_VFIO_MDEV_MTTY) += mtty.o
2obj-$(CONFIG_SAMPLE_VFIO_MDEV_MDPY) += mdpy.o 2obj-$(CONFIG_SAMPLE_VFIO_MDEV_MDPY) += mdpy.o
3obj-$(CONFIG_SAMPLE_VFIO_MDEV_MDPY_FB) += mdpy-fb.o 3obj-$(CONFIG_SAMPLE_VFIO_MDEV_MDPY_FB) += mdpy-fb.o
4obj-$(CONFIG_SAMPLE_VFIO_MDEV_MBOCHS) += mbochs.o
diff --git a/samples/vfio-mdev/mbochs.c b/samples/vfio-mdev/mbochs.c
new file mode 100644
index 000000000000..2960e26c6ea4
--- /dev/null
+++ b/samples/vfio-mdev/mbochs.c
@@ -0,0 +1,1406 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Mediated virtual PCI display host device driver
4 *
5 * Emulate enough of qemu stdvga to make bochs-drm.ko happy. That is
6 * basically the vram memory bar and the bochs dispi interface vbe
7 * registers in the mmio register bar. Specifically it does *not*
8 * include any legacy vga stuff. Device looks a lot like "qemu -device
9 * secondary-vga".
10 *
11 * (c) Gerd Hoffmann <kraxel@redhat.com>
12 *
13 * based on mtty driver which is:
14 * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
15 * Author: Neo Jia <cjia@nvidia.com>
16 * Kirti Wankhede <kwankhede@nvidia.com>
17 *
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License version 2 as
20 * published by the Free Software Foundation.
21 */
22#include <linux/init.h>
23#include <linux/module.h>
24#include <linux/device.h>
25#include <linux/kernel.h>
26#include <linux/slab.h>
27#include <linux/vmalloc.h>
28#include <linux/cdev.h>
29#include <linux/vfio.h>
30#include <linux/iommu.h>
31#include <linux/sysfs.h>
32#include <linux/mdev.h>
33#include <linux/pci.h>
34#include <linux/dma-buf.h>
35#include <linux/highmem.h>
36#include <drm/drm_fourcc.h>
37#include <drm/drm_rect.h>
38#include <drm/drm_modeset_lock.h>
39#include <drm/drm_property.h>
40#include <drm/drm_plane.h>
41
42
43#define VBE_DISPI_INDEX_ID 0x0
44#define VBE_DISPI_INDEX_XRES 0x1
45#define VBE_DISPI_INDEX_YRES 0x2
46#define VBE_DISPI_INDEX_BPP 0x3
47#define VBE_DISPI_INDEX_ENABLE 0x4
48#define VBE_DISPI_INDEX_BANK 0x5
49#define VBE_DISPI_INDEX_VIRT_WIDTH 0x6
50#define VBE_DISPI_INDEX_VIRT_HEIGHT 0x7
51#define VBE_DISPI_INDEX_X_OFFSET 0x8
52#define VBE_DISPI_INDEX_Y_OFFSET 0x9
53#define VBE_DISPI_INDEX_VIDEO_MEMORY_64K 0xa
54#define VBE_DISPI_INDEX_COUNT 0xb
55
56#define VBE_DISPI_ID0 0xB0C0
57#define VBE_DISPI_ID1 0xB0C1
58#define VBE_DISPI_ID2 0xB0C2
59#define VBE_DISPI_ID3 0xB0C3
60#define VBE_DISPI_ID4 0xB0C4
61#define VBE_DISPI_ID5 0xB0C5
62
63#define VBE_DISPI_DISABLED 0x00
64#define VBE_DISPI_ENABLED 0x01
65#define VBE_DISPI_GETCAPS 0x02
66#define VBE_DISPI_8BIT_DAC 0x20
67#define VBE_DISPI_LFB_ENABLED 0x40
68#define VBE_DISPI_NOCLEARMEM 0x80
69
70
71#define MBOCHS_NAME "mbochs"
72#define MBOCHS_CLASS_NAME "mbochs"
73
74#define MBOCHS_CONFIG_SPACE_SIZE 0xff
75#define MBOCHS_MMIO_BAR_OFFSET PAGE_SIZE
76#define MBOCHS_MMIO_BAR_SIZE PAGE_SIZE
77#define MBOCHS_MEMORY_BAR_OFFSET (MBOCHS_MMIO_BAR_OFFSET + \
78 MBOCHS_MMIO_BAR_SIZE)
79
80#define STORE_LE16(addr, val) (*(u16 *)addr = val)
81#define STORE_LE32(addr, val) (*(u32 *)addr = val)
82
83
84MODULE_LICENSE("GPL v2");
85
86static int max_mbytes = 256;
87module_param_named(count, max_mbytes, int, 0444);
88MODULE_PARM_DESC(mem, "megabytes available to " MBOCHS_NAME " devices");
89
90
91#define MBOCHS_TYPE_1 "small"
92#define MBOCHS_TYPE_2 "medium"
93#define MBOCHS_TYPE_3 "large"
94
95static const struct mbochs_type {
96 const char *name;
97 u32 mbytes;
98} mbochs_types[] = {
99 {
100 .name = MBOCHS_CLASS_NAME "-" MBOCHS_TYPE_1,
101 .mbytes = 4,
102 }, {
103 .name = MBOCHS_CLASS_NAME "-" MBOCHS_TYPE_2,
104 .mbytes = 16,
105 }, {
106 .name = MBOCHS_CLASS_NAME "-" MBOCHS_TYPE_3,
107 .mbytes = 64,
108 },
109};
110
111
112static dev_t mbochs_devt;
113static struct class *mbochs_class;
114static struct cdev mbochs_cdev;
115static struct device mbochs_dev;
116static int mbochs_used_mbytes;
117
118struct mbochs_mode {
119 u32 drm_format;
120 u32 bytepp;
121 u32 width;
122 u32 height;
123 u32 stride;
124 u32 __pad;
125 u64 offset;
126 u64 size;
127};
128
129struct mbochs_dmabuf {
130 struct mbochs_mode mode;
131 u32 id;
132 struct page **pages;
133 pgoff_t pagecount;
134 struct dma_buf *buf;
135 struct mdev_state *mdev_state;
136 struct list_head next;
137 bool unlinked;
138};
139
140/* State of each mdev device */
141struct mdev_state {
142 u8 *vconfig;
143 u64 bar_mask[3];
144 u32 memory_bar_mask;
145 struct mutex ops_lock;
146 struct mdev_device *mdev;
147 struct vfio_device_info dev_info;
148
149 const struct mbochs_type *type;
150 u16 vbe[VBE_DISPI_INDEX_COUNT];
151 u64 memsize;
152 struct page **pages;
153 pgoff_t pagecount;
154
155 struct list_head dmabufs;
156 u32 active_id;
157 u32 next_id;
158};
159
160static const char *vbe_name_list[VBE_DISPI_INDEX_COUNT] = {
161 [VBE_DISPI_INDEX_ID] = "id",
162 [VBE_DISPI_INDEX_XRES] = "xres",
163 [VBE_DISPI_INDEX_YRES] = "yres",
164 [VBE_DISPI_INDEX_BPP] = "bpp",
165 [VBE_DISPI_INDEX_ENABLE] = "enable",
166 [VBE_DISPI_INDEX_BANK] = "bank",
167 [VBE_DISPI_INDEX_VIRT_WIDTH] = "virt-width",
168 [VBE_DISPI_INDEX_VIRT_HEIGHT] = "virt-height",
169 [VBE_DISPI_INDEX_X_OFFSET] = "x-offset",
170 [VBE_DISPI_INDEX_Y_OFFSET] = "y-offset",
171 [VBE_DISPI_INDEX_VIDEO_MEMORY_64K] = "video-mem",
172};
173
174static const char *vbe_name(u32 index)
175{
176 if (index < ARRAY_SIZE(vbe_name_list))