Blame SOURCES/kvm-hw-usb-dev-smartcard-reader-Handle-64-B-USB-packets.patch

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