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 |
> 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
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 --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)