diff mbox series

[v2] drm/hyperv: Fix double mouse pointers

Message ID 20210916193644.45650-1-decui@microsoft.com (mailing list archive)
State New, archived
Headers show
Series [v2] drm/hyperv: Fix double mouse pointers | expand

Commit Message

Dexuan Cui Sept. 16, 2021, 7:36 p.m. UTC
Hyper-V supports a hardware cursor feature. It is not used by Linux VM,
but the Hyper-V host still draws a point as an extra mouse pointer,
which is unwanted, especially when Xorg is running.

The hyperv_fb driver uses synthvid_send_ptr() to hide the unwanted pointer.
When the hyperv_drm driver was developed, the function synthvid_send_ptr()
was not copied from the hyperv_fb driver. Fix the issue by adding the
function into hyperv_drm.

Fixes: 76c56a5affeb ("drm/hyperv: Add DRM driver for hyperv synthetic video device")
Signed-off-by: Dexuan Cui <decui@microsoft.com>
Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
Reviewed-by: Deepak Rawat <drawat.floss@gmail.com>
---

Changes in v2:
	Renamed hyperv_send_ptr() to hyperv_hide_hw_ptr().
	Improved the comments and the git commit message.
	Added Reviewed-by's from Haiyang and Deepak.

 drivers/gpu/drm/hyperv/hyperv_drm.h         |  1 +
 drivers/gpu/drm/hyperv/hyperv_drm_modeset.c |  1 +
 drivers/gpu/drm/hyperv/hyperv_drm_proto.c   | 54 ++++++++++++++++++++-
 3 files changed, 55 insertions(+), 1 deletion(-)

Comments

Dexuan Cui Oct. 6, 2021, 6:43 p.m. UTC | #1
> From: Dexuan Cui <decui@microsoft.com>
> Sent: Thursday, September 16, 2021 12:37 PM
> To: drawat.floss@gmail.com; Haiyang Zhang <haiyangz@microsoft.com>;
> airlied@linux.ie; daniel@ffwll.ch; tzimmermann@suse.de;
> dri-devel@lists.freedesktop.org
> Cc: linux-hyperv@vger.kernel.org; linux-kernel@vger.kernel.org; Dexuan Cui
> <decui@microsoft.com>
> Subject: [PATCH v2] drm/hyperv: Fix double mouse pointers
> 
> Hyper-V supports a hardware cursor feature. It is not used by Linux VM,
> but the Hyper-V host still draws a point as an extra mouse pointer,
> which is unwanted, especially when Xorg is running.
> 
> The hyperv_fb driver uses synthvid_send_ptr() to hide the unwanted pointer.
> When the hyperv_drm driver was developed, the function synthvid_send_ptr()
> was not copied from the hyperv_fb driver. Fix the issue by adding the
> function into hyperv_drm.
> 
> Fixes: 76c56a5affeb ("drm/hyperv: Add DRM driver for hyperv synthetic video
> device")
> Signed-off-by: Dexuan Cui <decui@microsoft.com>
> Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
> Reviewed-by: Deepak Rawat <drawat.floss@gmail.com>
> ---
> 
> Changes in v2:
> 	Renamed hyperv_send_ptr() to hyperv_hide_hw_ptr().
> 	Improved the comments and the git commit message.
> 	Added Reviewed-by's from Haiyang and Deepak.
> 
>  drivers/gpu/drm/hyperv/hyperv_drm.h         |  1 +
>  drivers/gpu/drm/hyperv/hyperv_drm_modeset.c |  1 +
>  drivers/gpu/drm/hyperv/hyperv_drm_proto.c   | 54
> ++++++++++++++++++++-
>  3 files changed, 55 insertions(+), 1 deletion(-)

Hi DRM maintainers,
Could you please take a look at the patch?

Thanks,
-- Dexuan
Thomas Zimmermann Oct. 7, 2021, 2:33 p.m. UTC | #2
Hi

Am 06.10.21 um 20:43 schrieb Dexuan Cui:
>> From: Dexuan Cui <decui@microsoft.com>
>> Sent: Thursday, September 16, 2021 12:37 PM
>> To: drawat.floss@gmail.com; Haiyang Zhang <haiyangz@microsoft.com>;
>> airlied@linux.ie; daniel@ffwll.ch; tzimmermann@suse.de;
>> dri-devel@lists.freedesktop.org
>> Cc: linux-hyperv@vger.kernel.org; linux-kernel@vger.kernel.org; Dexuan Cui
>> <decui@microsoft.com>
>> Subject: [PATCH v2] drm/hyperv: Fix double mouse pointers
>>
>> Hyper-V supports a hardware cursor feature. It is not used by Linux VM,
>> but the Hyper-V host still draws a point as an extra mouse pointer,
>> which is unwanted, especially when Xorg is running.
>>
>> The hyperv_fb driver uses synthvid_send_ptr() to hide the unwanted pointer.
>> When the hyperv_drm driver was developed, the function synthvid_send_ptr()
>> was not copied from the hyperv_fb driver. Fix the issue by adding the
>> function into hyperv_drm.
>>
>> Fixes: 76c56a5affeb ("drm/hyperv: Add DRM driver for hyperv synthetic video
>> device")
>> Signed-off-by: Dexuan Cui <decui@microsoft.com>
>> Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
>> Reviewed-by: Deepak Rawat <drawat.floss@gmail.com>
>> ---
>>
>> Changes in v2:
>> 	Renamed hyperv_send_ptr() to hyperv_hide_hw_ptr().
>> 	Improved the comments and the git commit message.
>> 	Added Reviewed-by's from Haiyang and Deepak.
>>
>>   drivers/gpu/drm/hyperv/hyperv_drm.h         |  1 +
>>   drivers/gpu/drm/hyperv/hyperv_drm_modeset.c |  1 +
>>   drivers/gpu/drm/hyperv/hyperv_drm_proto.c   | 54
>> ++++++++++++++++++++-
>>   3 files changed, 55 insertions(+), 1 deletion(-)
> 
> Hi DRM maintainers,
> Could you please take a look at the patch?

I pushed the patch into drm-misc-fixes. It should reach upstream sooned.

Best regards
Thomas

> 
> Thanks,
> -- Dexuan
>
diff mbox series

Patch

diff --git a/drivers/gpu/drm/hyperv/hyperv_drm.h b/drivers/gpu/drm/hyperv/hyperv_drm.h
index 886add4f9cd0..d2d8582b36df 100644
--- a/drivers/gpu/drm/hyperv/hyperv_drm.h
+++ b/drivers/gpu/drm/hyperv/hyperv_drm.h
@@ -46,6 +46,7 @@  int hyperv_mode_config_init(struct hyperv_drm_device *hv);
 int hyperv_update_vram_location(struct hv_device *hdev, phys_addr_t vram_pp);
 int hyperv_update_situation(struct hv_device *hdev, u8 active, u32 bpp,
 			    u32 w, u32 h, u32 pitch);
+int hyperv_hide_hw_ptr(struct hv_device *hdev);
 int hyperv_update_dirt(struct hv_device *hdev, struct drm_rect *rect);
 int hyperv_connect_vsp(struct hv_device *hdev);
 
diff --git a/drivers/gpu/drm/hyperv/hyperv_drm_modeset.c b/drivers/gpu/drm/hyperv/hyperv_drm_modeset.c
index 3aaee4730ec6..5f01ca817517 100644
--- a/drivers/gpu/drm/hyperv/hyperv_drm_modeset.c
+++ b/drivers/gpu/drm/hyperv/hyperv_drm_modeset.c
@@ -101,6 +101,7 @@  static void hyperv_pipe_enable(struct drm_simple_display_pipe *pipe,
 	struct hyperv_drm_device *hv = to_hv(pipe->crtc.dev);
 	struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state);
 
+	hyperv_hide_hw_ptr(hv->hdev);
 	hyperv_update_situation(hv->hdev, 1,  hv->screen_depth,
 				crtc_state->mode.hdisplay,
 				crtc_state->mode.vdisplay,
diff --git a/drivers/gpu/drm/hyperv/hyperv_drm_proto.c b/drivers/gpu/drm/hyperv/hyperv_drm_proto.c
index 6d4bdccfbd1a..c0155c6271bf 100644
--- a/drivers/gpu/drm/hyperv/hyperv_drm_proto.c
+++ b/drivers/gpu/drm/hyperv/hyperv_drm_proto.c
@@ -299,6 +299,55 @@  int hyperv_update_situation(struct hv_device *hdev, u8 active, u32 bpp,
 	return 0;
 }
 
+/*
+ * Hyper-V supports a hardware cursor feature. It's not used by Linux VM,
+ * but the Hyper-V host still draws a point as an extra mouse pointer,
+ * which is unwanted, especially when Xorg is running.
+ *
+ * The hyperv_fb driver uses synthvid_send_ptr() to hide the unwanted
+ * pointer, by setting msg.ptr_pos.is_visible = 1 and setting the
+ * msg.ptr_shape.data. Note: setting msg.ptr_pos.is_visible to 0 doesn't
+ * work in tests.
+ *
+ * Copy synthvid_send_ptr() to hyperv_drm and rename it to
+ * hyperv_hide_hw_ptr(). Note: hyperv_hide_hw_ptr() is also called in the
+ * handler of the SYNTHVID_FEATURE_CHANGE event, otherwise the host still
+ * draws an extra unwanted mouse pointer after the VM Connection window is
+ * closed and reopened.
+ */
+int hyperv_hide_hw_ptr(struct hv_device *hdev)
+{
+	struct synthvid_msg msg;
+
+	memset(&msg, 0, sizeof(struct synthvid_msg));
+	msg.vid_hdr.type = SYNTHVID_POINTER_POSITION;
+	msg.vid_hdr.size = sizeof(struct synthvid_msg_hdr) +
+		sizeof(struct synthvid_pointer_position);
+	msg.ptr_pos.is_visible = 1;
+	msg.ptr_pos.video_output = 0;
+	msg.ptr_pos.image_x = 0;
+	msg.ptr_pos.image_y = 0;
+	hyperv_sendpacket(hdev, &msg);
+
+	memset(&msg, 0, sizeof(struct synthvid_msg));
+	msg.vid_hdr.type = SYNTHVID_POINTER_SHAPE;
+	msg.vid_hdr.size = sizeof(struct synthvid_msg_hdr) +
+		sizeof(struct synthvid_pointer_shape);
+	msg.ptr_shape.part_idx = SYNTHVID_CURSOR_COMPLETE;
+	msg.ptr_shape.is_argb = 1;
+	msg.ptr_shape.width = 1;
+	msg.ptr_shape.height = 1;
+	msg.ptr_shape.hot_x = 0;
+	msg.ptr_shape.hot_y = 0;
+	msg.ptr_shape.data[0] = 0;
+	msg.ptr_shape.data[1] = 1;
+	msg.ptr_shape.data[2] = 1;
+	msg.ptr_shape.data[3] = 1;
+	hyperv_sendpacket(hdev, &msg);
+
+	return 0;
+}
+
 int hyperv_update_dirt(struct hv_device *hdev, struct drm_rect *rect)
 {
 	struct hyperv_drm_device *hv = hv_get_drvdata(hdev);
@@ -392,8 +441,11 @@  static void hyperv_receive_sub(struct hv_device *hdev)
 		return;
 	}
 
-	if (msg->vid_hdr.type == SYNTHVID_FEATURE_CHANGE)
+	if (msg->vid_hdr.type == SYNTHVID_FEATURE_CHANGE) {
 		hv->dirt_needed = msg->feature_chg.is_dirt_needed;
+		if (hv->dirt_needed)
+			hyperv_hide_hw_ptr(hv->hdev);
+	}
 }
 
 static void hyperv_receive(void *ctx)