]>
Commit | Line | Data |
---|---|---|
3c19fc53 WB |
1 | From b5ef1754de94247de307044b19e6bc3fa0ad5ba8 Mon Sep 17 00:00:00 2001 |
2 | From: Gerd Hoffmann <kraxel@redhat.com> | |
3 | Date: Mon, 10 Oct 2016 12:46:22 +0200 | |
4 | Subject: [PATCH 2/4] xhci: limit the number of link trbs we are willing to | |
5 | process | |
6 | ||
7 | Needed to avoid we run in circles forever in case the guest builds | |
8 | an endless loop with link trbs. | |
9 | ||
10 | Reported-by: Li Qiang <liqiang6-s@360.cn> | |
11 | Tested-by: P J P <ppandit@redhat.com> | |
12 | Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> | |
13 | Message-id: 1476096382-7981-1-git-send-email-kraxel@redhat.com | |
14 | --- | |
15 | hw/usb/hcd-xhci.c | 10 ++++++++++ | |
16 | 1 file changed, 10 insertions(+) | |
17 | ||
18 | diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c | |
19 | index 281a2a5..8a9a31a 100644 | |
20 | --- a/hw/usb/hcd-xhci.c | |
21 | +++ b/hw/usb/hcd-xhci.c | |
22 | @@ -54,6 +54,8 @@ | |
23 | * to the specs when it gets them */ | |
24 | #define ER_FULL_HACK | |
25 | ||
26 | +#define TRB_LINK_LIMIT 4 | |
27 | + | |
28 | #define LEN_CAP 0x40 | |
29 | #define LEN_OPER (0x400 + 0x10 * MAXPORTS) | |
30 | #define LEN_RUNTIME ((MAXINTRS + 1) * 0x20) | |
31 | @@ -1000,6 +1002,7 @@ static TRBType xhci_ring_fetch(XHCIState *xhci, XHCIRing *ring, XHCITRB *trb, | |
32 | dma_addr_t *addr) | |
33 | { | |
34 | PCIDevice *pci_dev = PCI_DEVICE(xhci); | |
35 | + uint32_t link_cnt = 0; | |
36 | ||
37 | while (1) { | |
38 | TRBType type; | |
39 | @@ -1026,6 +1029,9 @@ static TRBType xhci_ring_fetch(XHCIState *xhci, XHCIRing *ring, XHCITRB *trb, | |
40 | ring->dequeue += TRB_SIZE; | |
41 | return type; | |
42 | } else { | |
43 | + if (++link_cnt > TRB_LINK_LIMIT) { | |
44 | + return 0; | |
45 | + } | |
46 | ring->dequeue = xhci_mask64(trb->parameter); | |
47 | if (trb->control & TRB_LK_TC) { | |
48 | ring->ccs = !ring->ccs; | |
49 | @@ -1043,6 +1049,7 @@ static int xhci_ring_chain_length(XHCIState *xhci, const XHCIRing *ring) | |
50 | bool ccs = ring->ccs; | |
51 | /* hack to bundle together the two/three TDs that make a setup transfer */ | |
52 | bool control_td_set = 0; | |
53 | + uint32_t link_cnt = 0; | |
54 | ||
55 | while (1) { | |
56 | TRBType type; | |
57 | @@ -1058,6 +1065,9 @@ static int xhci_ring_chain_length(XHCIState *xhci, const XHCIRing *ring) | |
58 | type = TRB_TYPE(trb); | |
59 | ||
60 | if (type == TR_LINK) { | |
61 | + if (++link_cnt > TRB_LINK_LIMIT) { | |
62 | + return -length; | |
63 | + } | |
64 | dequeue = xhci_mask64(trb.parameter); | |
65 | if (trb.control & TRB_LK_TC) { | |
66 | ccs = !ccs; | |
67 | -- | |
68 | 2.1.4 | |
69 |