]> git.proxmox.com Git - pve-qemu.git/blame - debian/patches/extra/0009-e1000e-Fix-ICR-Other-causes-clear-logic.patch
add CVE fixes
[pve-qemu.git] / debian / patches / extra / 0009-e1000e-Fix-ICR-Other-causes-clear-logic.patch
CommitLineData
e74c0f31 1From 02b34affd75f205f50445217ad28ef28002e0bf0 Mon Sep 17 00:00:00 2001
90a6d957
WB
2From: Sameeh Jubran <sameeh@daynix.com>
3Date: Mon, 22 May 2017 14:26:22 +0300
e74c0f31 4Subject: [PATCH 09/23] e1000e: Fix ICR "Other" causes clear logic
90a6d957
WB
5
6This commit fixes a bug which causes the guest to hang. The bug was
7observed upon a "receive overrun" (bit #6 of the ICR register)
8interrupt which could be triggered post migration in a heavy traffic
9environment. Even though the "receive overrun" bit (#6) is masked out
10by the IMS register (refer to the log below) the driver still receives
11an interrupt as the "receive overrun" bit (#6) causes the "Other" -
12bit #24 of the ICR register - bit to be set as documented below. The
13driver handles the interrupt and clears the "Other" bit (#24) but
14doesn't clear the "receive overrun" bit (#6) which leads to an
15infinite loop. Apparently the Windows driver expects that the "receive
16overrun" bit and other ones - documented below - to be cleared when
17the "Other" bit (#24) is cleared.
18
19So to sum that up:
201. Bit #6 of the ICR register is set by heavy traffic
212. As a results of setting bit #6, bit #24 is set
223. The driver receives an interrupt for bit 24 (it doesn't receieve an
23 interrupt for bit #6 as it is masked out by IMS)
244. The driver handles and clears the interrupt of bit #24
255. Bit #6 is still set.
266. 2 happens all over again
27
28The Interrupt Cause Read - ICR register:
29
30The ICR has the "Other" bit - bit #24 - that is set when one or more
31of the following ICR register's bits are set:
32
33LSC - bit #2, RXO - bit #6, MDAC - bit #9, SRPD - bit #16, ACK - bit
34#17, MNG - bit #18
35
36This bug can occur with any of these bits depending on the driver's
37behaviour and the way it configures the device. However, trying to
38reproduce it with any bit other than RX0 is challenging and came to
39failure as the drivers don't implement most of these bits, trying to
40reproduce it with LSC (Link Status Change - bit #2) bit didn't succeed
41too as it seems that Windows handles this bit differently.
42
43Log sample of the storm:
44
4527563@1494850819.411877:e1000e_irq_pending_interrupts ICR PENDING: 0x1000000 (ICR: 0x815000c2, IMS: 0x1a00004)
4627563@1494850819.411900:e1000e_irq_pending_interrupts ICR PENDING: 0x0 (ICR: 0x815000c2, IMS: 0xa00004)
4727563@1494850819.411915:e1000e_irq_pending_interrupts ICR PENDING: 0x0 (ICR: 0x815000c2, IMS: 0xa00004)
4827563@1494850819.412380:e1000e_irq_pending_interrupts ICR PENDING: 0x0 (ICR: 0x815000c2, IMS: 0xa00004)
4927563@1494850819.412395:e1000e_irq_pending_interrupts ICR PENDING: 0x0 (ICR: 0x815000c2, IMS: 0xa00004)
5027563@1494850819.412436:e1000e_irq_pending_interrupts ICR PENDING: 0x0 (ICR: 0x815000c2, IMS: 0xa00004)
5127563@1494850819.412441:e1000e_irq_pending_interrupts ICR PENDING: 0x0 (ICR: 0x815000c2, IMS: 0xa00004)
5227563@1494850819.412998:e1000e_irq_pending_interrupts ICR PENDING: 0x1000000 (ICR: 0x815000c2, IMS: 0x1a00004)
53
54* This bug behaviour wasn't observed with the Linux driver.
55
56This commit solves:
57https://bugzilla.redhat.com/show_bug.cgi?id=1447935
58https://bugzilla.redhat.com/show_bug.cgi?id=1449490
59
60Cc: qemu-stable@nongnu.org
61Signed-off-by: Sameeh Jubran <sjubran@redhat.com>
62Signed-off-by: Jason Wang <jasowang@redhat.com>
63---
64 hw/net/e1000e_core.c | 10 ++++++++--
65 1 file changed, 8 insertions(+), 2 deletions(-)
66
67diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c
68index 28c5be1506..81405640f0 100644
69--- a/hw/net/e1000e_core.c
70+++ b/hw/net/e1000e_core.c
71@@ -2454,14 +2454,20 @@ e1000e_set_ics(E1000ECore *core, int index, uint32_t val)
72 static void
73 e1000e_set_icr(E1000ECore *core, int index, uint32_t val)
74 {
75+ uint32_t icr = 0;
76 if ((core->mac[ICR] & E1000_ICR_ASSERTED) &&
77 (core->mac[CTRL_EXT] & E1000_CTRL_EXT_IAME)) {
78 trace_e1000e_irq_icr_process_iame();
79 e1000e_clear_ims_bits(core, core->mac[IAM]);
80 }
81
82- trace_e1000e_irq_icr_write(val, core->mac[ICR], core->mac[ICR] & ~val);
83- core->mac[ICR] &= ~val;
84+ icr = core->mac[ICR] & ~val;
85+ /* Windows driver expects that the "receive overrun" bit and other
86+ * ones to be cleared when the "Other" bit (#24) is cleared.
87+ */
88+ icr = (val & E1000_ICR_OTHER) ? (icr & ~E1000_ICR_OTHER_CAUSES) : icr;
89+ trace_e1000e_irq_icr_write(val, core->mac[ICR], icr);
90+ core->mac[ICR] = icr;
91 e1000e_update_interrupt_state(core);
92 }
93
94--
952.11.0
96