Skip to content

Commit 94dadc1

Browse files
chejianjlijinxia
authored andcommitted
dm: virtio-input: ignore MSC_TIMESTAMP from guest
(EV_MSC, MSC_TIMESTAMP) is added to each frame just before the SYN event since kernel 4.15. EV_MSC is configured as INPUT_PASS_TO_ALL. In the use case of virtio-input, there is a loop as follows: - A mt frame with (EV_MSC, MSC_TIMESTAMP) is passed to FE. - FE will call virtinput_status to pass (EV_MSC, MSC_TIMESTAMP) back to BE. - BE writes this event to evdev. Because (EV_MSC, MSC_TIMESTAMP) is configured as INPUT_PASS_TO_ALL, it will be written into the event buffer of evdev then be read out by BE without SYN followed. - Each mt frame will introduce one (EV_MSC, MSC_TIMESTAMP). Later the frame becomes larger and larger... This patch fixed above issue by ignoring MSC_TIMESTAMP from guest. Besides that timestamp is added for every status event from guest before writing to evdev. Tracked-On: #1670 Signed-off-by: Jian Jun Chen <jian.jun.chen@intel.com> Acked-by: Yu Wang <yu1.wang@intel.com>
1 parent ed113f5 commit 94dadc1

File tree

1 file changed

+44
-8
lines changed

1 file changed

+44
-8
lines changed

devicemodel/hw/pci/virtio/virtio_input.c

Lines changed: 44 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,33 @@ virtio_input_cfgwrite(void *vdev, int offset, int size, uint32_t val)
208208
return 0;
209209
}
210210

211+
static bool
212+
virtio_input_ignore_event(struct virtio_input_event *event)
213+
{
214+
if (!event)
215+
return true;
216+
217+
/* kernel commit 29cc309d8bf19a36c5196bf626662319af6e3c0b
218+
* (HID: hid-multitouch: forward MSC_TIMESTAMP)
219+
* since kernel 4.15
220+
* (EV_MSC, MSC_TIMESTAMP) is added to each frame just before
221+
* the SYN event. EV_MSC is configured as INPUT_PASS_TO_ALL.
222+
* In the use case of virtio-input, there is a loop as follows:
223+
* - A mt frame with (EV_MSC, MSC_TIMESTAMP) is passed to FE.
224+
* - FE will call virtinput_status to pass (EV_MSC, MSC_TIMESTAMP)
225+
* back to BE.
226+
* - BE writes this event to evdev. Because (EV_MSC, MSC_TIMESTAMP)
227+
* is configured as INPUT_PASS_TO_ALL, it will be written into
228+
* the event buffer of evdev then be read out by BE without
229+
* SYN followed.
230+
* - Each mt frame will introduce one (EV_MSC, MSC_TIMESTAMP).
231+
* Later the frame becomes larger and larger...
232+
*/
233+
if ((event->type == EV_MSC) && (event->code == MSC_TIMESTAMP))
234+
return true;
235+
return false;
236+
}
237+
211238
static void
212239
virtio_input_notify_event_vq(void *vdev, struct virtio_vq_info *vq)
213240
{
@@ -230,14 +257,23 @@ virtio_input_notify_status_vq(void *vdev, struct virtio_vq_info *vq)
230257
n = vq_getchain(vq, &idx, &iov, 1, NULL);
231258
assert(n == 1);
232259

233-
memcpy(&event, iov.iov_base, sizeof(event));
234-
host_event.type = event.type;
235-
host_event.code = event.code;
236-
host_event.value = event.value;
237-
len = write(vi->fd, &host_event, sizeof(host_event));
238-
if (len == -1)
239-
WPRINTF(("%s: write failed, len = %d, errno = %d\n",
240-
__func__, len, errno));
260+
if (vi->fd > 0) {
261+
memcpy(&event, iov.iov_base, sizeof(event));
262+
if (!virtio_input_ignore_event(&event)) {
263+
host_event.type = event.type;
264+
host_event.code = event.code;
265+
host_event.value = event.value;
266+
if (gettimeofday(&host_event.time, NULL)) {
267+
WPRINTF(("vtinput: gettimeofday failed\n"));
268+
break;
269+
}
270+
len = write(vi->fd, &host_event, sizeof(host_event));
271+
if (len == -1)
272+
WPRINTF(("%s: write failed, len = %d, "
273+
"errno = %d\n",
274+
__func__, len, errno));
275+
}
276+
}
241277
vq_relchain(vq, idx, sizeof(event)); /* Release the chain */
242278
}
243279
vq_endchains(vq, 1); /* Generate interrupt if appropriate. */

0 commit comments

Comments
 (0)