|
|
357786 |
From a05d849be393110a4efacb148197434c095e06e2 Mon Sep 17 00:00:00 2001
|
|
|
357786 |
From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com>
|
|
|
357786 |
Date: Thu, 16 Aug 2018 10:41:54 +0200
|
|
|
357786 |
Subject: [PATCH 3/5] hw/usb/dev-smartcard-reader: Handle 64 B USB packets
|
|
|
357786 |
MIME-Version: 1.0
|
|
|
357786 |
Content-Type: text/plain; charset=UTF-8
|
|
|
357786 |
Content-Transfer-Encoding: 8bit
|
|
|
357786 |
|
|
|
357786 |
RH-Author: Marc-André Lureau <marcandre.lureau@redhat.com>
|
|
|
357786 |
Message-id: <20180816104154.18782-1-marcandre.lureau@redhat.com>
|
|
|
357786 |
Patchwork-id: 81855
|
|
|
357786 |
O-Subject: [RHEL-7.6 qemu-kvm-rhev PATCH] hw/usb/dev-smartcard-reader: Handle 64 B USB packets
|
|
|
357786 |
Bugzilla: 1589147
|
|
|
357786 |
RH-Acked-by: Gerd Hoffmann <kraxel@redhat.com>
|
|
|
357786 |
RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
|
|
|
357786 |
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
357786 |
|
|
|
357786 |
From: Jakub Jelen <jjelen@redhat.com>
|
|
|
357786 |
|
|
|
357786 |
The current code was not correctly handling 64 B (Max USB 1.1 payload size)
|
|
|
357786 |
packets and therefore preventing some of the messages from smart card to
|
|
|
357786 |
pass through to the guest.
|
|
|
357786 |
|
|
|
357786 |
If the smart card in host responded with 34 B of data in APDU layer, the
|
|
|
357786 |
CCID headers added up to 64 B. The packet was send, but not correctly
|
|
|
357786 |
committed per USB specification (8.5.3.2 Variable-length Data Stage):
|
|
|
357786 |
|
|
|
357786 |
> When all of the data structure is returned to the host, the function
|
|
|
357786 |
> should indicate that the Data stage is ended by returning a packet
|
|
|
357786 |
> that is shorter than the MaxPacketSize for the pipe. If the data
|
|
|
357786 |
> structure is an exact multiple of wMaxPacketSize for the pipe, the
|
|
|
357786 |
> function will return a zero-length packet to indicate the end of the
|
|
|
357786 |
> Data stage.
|
|
|
357786 |
|
|
|
357786 |
This lead the guest applications to timeout while waiting for the rest
|
|
|
357786 |
of data (the emulation layer is answering with NAK until the timeout).
|
|
|
357786 |
|
|
|
357786 |
This patch is checking the current maximum packet size and if the
|
|
|
357786 |
payload of this size is detected, the message buffer is not yet released.
|
|
|
357786 |
With the next call, the empty buffer is sent and the message buffer
|
|
|
357786 |
is finally released.
|
|
|
357786 |
|
|
|
357786 |
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
|
|
|
357786 |
Message-id: 20180516115544.3897-2-jjelen@redhat.com
|
|
|
357786 |
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
|
|
357786 |
|
|
|
357786 |
(cherry picked from commit 8030dca376fa1bc4d8a6be7628196578f8783ab3)
|
|
|
357786 |
|
|
|
357786 |
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
|
|
|
357786 |
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
357786 |
---
|
|
|
357786 |
hw/usb/dev-smartcard-reader.c | 14 +++++++++-----
|
|
|
357786 |
1 file changed, 9 insertions(+), 5 deletions(-)
|
|
|
357786 |
|
|
|
357786 |
diff --git a/hw/usb/dev-smartcard-reader.c b/hw/usb/dev-smartcard-reader.c
|
|
|
357786 |
index e646805..214d3e9 100644
|
|
|
357786 |
--- a/hw/usb/dev-smartcard-reader.c
|
|
|
357786 |
+++ b/hw/usb/dev-smartcard-reader.c
|
|
|
357786 |
@@ -1064,7 +1064,8 @@ err:
|
|
|
357786 |
return;
|
|
|
357786 |
}
|
|
|
357786 |
|
|
|
357786 |
-static void ccid_bulk_in_copy_to_guest(USBCCIDState *s, USBPacket *p)
|
|
|
357786 |
+static void ccid_bulk_in_copy_to_guest(USBCCIDState *s, USBPacket *p,
|
|
|
357786 |
+ unsigned int max_packet_size)
|
|
|
357786 |
{
|
|
|
357786 |
int len = 0;
|
|
|
357786 |
|
|
|
357786 |
@@ -1072,10 +1073,13 @@ static void ccid_bulk_in_copy_to_guest(USBCCIDState *s, USBPacket *p)
|
|
|
357786 |
if (s->current_bulk_in != NULL) {
|
|
|
357786 |
len = MIN(s->current_bulk_in->len - s->current_bulk_in->pos,
|
|
|
357786 |
p->iov.size);
|
|
|
357786 |
- usb_packet_copy(p, s->current_bulk_in->data +
|
|
|
357786 |
- s->current_bulk_in->pos, len);
|
|
|
357786 |
+ if (len) {
|
|
|
357786 |
+ usb_packet_copy(p, s->current_bulk_in->data +
|
|
|
357786 |
+ s->current_bulk_in->pos, len);
|
|
|
357786 |
+ }
|
|
|
357786 |
s->current_bulk_in->pos += len;
|
|
|
357786 |
- if (s->current_bulk_in->pos == s->current_bulk_in->len) {
|
|
|
357786 |
+ if (s->current_bulk_in->pos == s->current_bulk_in->len
|
|
|
357786 |
+ && len != max_packet_size) {
|
|
|
357786 |
ccid_bulk_in_release(s);
|
|
|
357786 |
}
|
|
|
357786 |
} else {
|
|
|
357786 |
@@ -1107,7 +1111,7 @@ static void ccid_handle_data(USBDevice *dev, USBPacket *p)
|
|
|
357786 |
case USB_TOKEN_IN:
|
|
|
357786 |
switch (p->ep->nr) {
|
|
|
357786 |
case CCID_BULK_IN_EP:
|
|
|
357786 |
- ccid_bulk_in_copy_to_guest(s, p);
|
|
|
357786 |
+ ccid_bulk_in_copy_to_guest(s, p, dev->ep_ctl.max_packet_size);
|
|
|
357786 |
break;
|
|
|
357786 |
case CCID_INT_IN_EP:
|
|
|
357786 |
if (s->notify_slot_change) {
|
|
|
357786 |
--
|
|
|
357786 |
1.8.3.1
|
|
|
357786 |
|