lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Date:   Thu, 13 Sep 2018 07:47:45 +0200
From:   Gerd Hoffmann <kraxel@...hat.com>
To:     Kirti Wankhede <kwankhede@...dia.com>,
        intel-gvt-dev@...ts.freedesktop.org,
        Alex Williamson <alex.williamson@...hat.com>
Cc:     kvm@...r.kernel.org, Gerd Hoffmann <kraxel@...hat.com>,
        linux-kernel@...r.kernel.org (open list)
Subject: [PATCH 2/2] vfio: add edid support to mbochs sample driver

Signed-off-by: Gerd Hoffmann <kraxel@...hat.com>
---
 samples/vfio-mdev/mbochs.c | 54 ++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 52 insertions(+), 2 deletions(-)

diff --git a/samples/vfio-mdev/mbochs.c b/samples/vfio-mdev/mbochs.c
index 2535c3677c..6331871ff5 100644
--- a/samples/vfio-mdev/mbochs.c
+++ b/samples/vfio-mdev/mbochs.c
@@ -95,16 +95,24 @@ MODULE_PARM_DESC(mem, "megabytes available to " MBOCHS_NAME " devices");
 static const struct mbochs_type {
 	const char *name;
 	u32 mbytes;
+	u32 max_x;
+	u32 max_y;
 } mbochs_types[] = {
 	{
 		.name	= MBOCHS_CLASS_NAME "-" MBOCHS_TYPE_1,
 		.mbytes = 4,
+		.max_x  = 800,
+		.max_y  = 600,
 	}, {
 		.name	= MBOCHS_CLASS_NAME "-" MBOCHS_TYPE_2,
 		.mbytes = 16,
+		.max_x  = 1920,
+		.max_y  = 1440,
 	}, {
 		.name	= MBOCHS_CLASS_NAME "-" MBOCHS_TYPE_3,
 		.mbytes = 64,
+		.max_x  = 0,
+		.max_y  = 0,
 	},
 };
 
@@ -151,6 +159,7 @@ struct mdev_state {
 	u64 memsize;
 	struct page **pages;
 	pgoff_t pagecount;
+	u8 edid[512];
 
 	struct list_head dmabufs;
 	u32 active_id;
@@ -346,6 +355,11 @@ static void handle_mmio_read(struct mdev_state *mdev_state, u16 offset,
 	int index;
 
 	switch (offset) {
+	case 0x000 ... 0x3ff: /* edid block */
+		if (offset + count > sizeof(mdev_state->edid))
+			goto unhandled;
+		memcpy(buf, mdev_state->edid + offset, count);
+		break;
 	case 0x500 ... 0x515: /* bochs dispi interface */
 		if (count != 2)
 			goto unhandled;
@@ -983,9 +997,13 @@ static int mbochs_get_irq_info(struct mdev_device *mdev,
 static int mbochs_get_device_info(struct mdev_device *mdev,
 				  struct vfio_device_info *dev_info)
 {
+	struct mdev_state *mdev_state = mdev_get_drvdata(mdev);
+
 	dev_info->flags = VFIO_DEVICE_FLAGS_PCI;
 	dev_info->num_regions = VFIO_PCI_NUM_REGIONS;
 	dev_info->num_irqs = VFIO_PCI_NUM_IRQS;
+	dev_info->edid_max_x = mdev_state->type->max_x;
+	dev_info->edid_max_y = mdev_state->type->max_y;
 	return 0;
 }
 
@@ -1084,7 +1102,7 @@ static long mbochs_ioctl(struct mdev_device *mdev, unsigned int cmd,
 			unsigned long arg)
 {
 	int ret = 0;
-	unsigned long minsz;
+	unsigned long minsz, outsz;
 	struct mdev_state *mdev_state;
 
 	mdev_state = mdev_get_drvdata(mdev);
@@ -1095,6 +1113,7 @@ static long mbochs_ioctl(struct mdev_device *mdev, unsigned int cmd,
 		struct vfio_device_info info;
 
 		minsz = offsetofend(struct vfio_device_info, num_irqs);
+		outsz = offsetofend(struct vfio_device_info, edid_max_y);
 
 		if (copy_from_user(&info, (void __user *)arg, minsz))
 			return -EFAULT;
@@ -1108,7 +1127,9 @@ static long mbochs_ioctl(struct mdev_device *mdev, unsigned int cmd,
 
 		memcpy(&mdev_state->dev_info, &info, sizeof(info));
 
-		if (copy_to_user((void __user *)arg, &info, minsz))
+		if (outsz > info.argsz)
+			outsz = info.argsz;
+		if (copy_to_user((void __user *)arg, &info, outsz))
 			return -EFAULT;
 
 		return 0;
@@ -1194,6 +1215,35 @@ static long mbochs_ioctl(struct mdev_device *mdev, unsigned int cmd,
 		return mbochs_get_gfx_dmabuf(mdev, dmabuf_id);
 	}
 
+	case VFIO_DEVICE_SET_GFX_EDID:
+	{
+		struct vfio_device_set_gfx_edid *edid;
+
+		edid = kmalloc(sizeof(*edid), GFP_KERNEL);
+
+		minsz = offsetofend(struct vfio_device_set_gfx_edid,
+				    edid_blob);
+
+		if (copy_from_user(edid, (void __user *)arg, minsz)) {
+			kfree(edid);
+			return -EFAULT;
+		}
+
+		if (edid->argsz < minsz ||
+		    edid->edid_size > sizeof(mdev_state->edid)) {
+			kfree(edid);
+			return -EINVAL;
+		}
+
+		memset(mdev_state->edid, 0, sizeof(mdev_state->edid));
+		if (edid->link_state == VFIO_DEVICE_GFX_LINK_STATE_UP) {
+			memcpy(mdev_state->edid, edid->edid_blob, edid->edid_size);
+		}
+		kfree(edid);
+
+		return 0;
+	}
+
 	case VFIO_DEVICE_SET_IRQS:
 		return -EINVAL;
 
-- 
2.9.3

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ