In the function intel_vgpu_reg_rw_edid of gvt/kvmgt.c, pos can get equal to NULL for GPUs that do not properly support EDID. In those cases, when pos gets passed to the handle_edid functions, it gets added a short offset then it's dereferenced in memcpy's, leading to a kernel oops: null pointer dereference. More concretely, that kernel oops renders Broadwell GPUs users completely unable to set up virtual machines with virtual GPU passthrough (virtual machines hang indefinitely when trying to make use of the virtual GPU), and make them have huge problems when trying to remove the virtual GPUs once the kernel oops has happened (writing 1 in the vGPU remove file just makes the operation hang undefinitely, again, and the kernel is unable to shutdown since the vGPU removing hangs indefinitely). More information on the issues that this causes are described in details in this github issue post: https://github.com/intel/gvt-linux/issues/170#issuecomment-685806160 This patch solves this problem by checking is pos is equal to NULL, and if it is, it sets ret to a nagative value, making the module simply indicate that the access to EDID region has failed, without any fatal repercussion. When this patch is applied, Broadwell GPU users do not suffer from that kernel oops anymore, and thus do not encounter any of the described problems and get able to set up virtual machines with GPU passthrough without problems. Users of GPUs with proper EDID support, are of course, still able to benefit from the EDID features. Signed-off-by: Alejandro W. Sior <aho@xxxxxxx> --- drivers/gpu/drm/i915/gvt/kvmgt.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c index ad8a9df49f29..49163363ba4a 100644 --- a/drivers/gpu/drm/i915/gvt/kvmgt.c +++ b/drivers/gpu/drm/i915/gvt/kvmgt.c @@ -557,7 +557,9 @@ static size_t intel_vgpu_reg_rw_edid(struct intel_vgpu *vgpu, char *buf, (struct vfio_edid_region *)kvmgt_vdev(vgpu)->region[i].data; loff_t pos = *ppos & VFIO_PCI_OFFSET_MASK; - if (pos < region->vfio_edid_regs.edid_offset) { + if (pos == NULL) { + ret = -EINVAL; + } else if (pos < region->vfio_edid_regs.edid_offset) { ret = handle_edid_regs(vgpu, region, buf, count, pos, iswrite); } else { pos -= EDID_BLOB_OFFSET; -- 2.28.0 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel