From bdfefda72c3042c5d0781ecfcf73458b76c6866d Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 24 Sep 2018 13:12:21 +0200 Subject: [PATCH] 4.9-stable patches added patches: e1000e-avoid-missed-interrupts-following-icr-read.patch e1000e-fix-link-check-race-condition.patch e1000e-fix-queue-interrupt-re-raising-in-other-interrupt.patch e1000e-remove-other-from-eiac.patch mei-bus-type-promotion-bug-in-mei_nfc_if_version.patch mips-vdso-drop-gic_get_usm_range-usage.patch mips-vdso-match-data-page-cache-colouring-when-d-aliases.patch partial-revert-e1000e-avoid-receiver-overrun-interrupt-bursts.patch revert-e1000e-separate-signaling-for-link-check-link-up.patch --- ...missed-interrupts-following-icr-read.patch | 125 +++++++++++ ...e1000e-fix-link-check-race-condition.patch | 206 ++++++++++++++++++ ...errupt-re-raising-in-other-interrupt.patch | 42 ++++ queue-4.9/e1000e-remove-other-from-eiac.patch | 60 +++++ ...-promotion-bug-in-mei_nfc_if_version.patch | 37 ++++ ...ps-vdso-drop-gic_get_usm_range-usage.patch | 84 +++++++ ...-page-cache-colouring-when-d-aliases.patch | 90 ++++++++ ...id-receiver-overrun-interrupt-bursts.patch | 76 +++++++ ...ate-signaling-for-link-check-link-up.patch | 143 ++++++++++++ queue-4.9/series | 9 + 10 files changed, 872 insertions(+) create mode 100644 queue-4.9/e1000e-avoid-missed-interrupts-following-icr-read.patch create mode 100644 queue-4.9/e1000e-fix-link-check-race-condition.patch create mode 100644 queue-4.9/e1000e-fix-queue-interrupt-re-raising-in-other-interrupt.patch create mode 100644 queue-4.9/e1000e-remove-other-from-eiac.patch create mode 100644 queue-4.9/mei-bus-type-promotion-bug-in-mei_nfc_if_version.patch create mode 100644 queue-4.9/mips-vdso-drop-gic_get_usm_range-usage.patch create mode 100644 queue-4.9/mips-vdso-match-data-page-cache-colouring-when-d-aliases.patch create mode 100644 queue-4.9/partial-revert-e1000e-avoid-receiver-overrun-interrupt-bursts.patch create mode 100644 queue-4.9/revert-e1000e-separate-signaling-for-link-check-link-up.patch diff --git a/queue-4.9/e1000e-avoid-missed-interrupts-following-icr-read.patch b/queue-4.9/e1000e-avoid-missed-interrupts-following-icr-read.patch new file mode 100644 index 00000000000..34c09e6e0e8 --- /dev/null +++ b/queue-4.9/e1000e-avoid-missed-interrupts-following-icr-read.patch @@ -0,0 +1,125 @@ +From foo@baz Mon Sep 24 13:08:20 CEST 2018 +From: Benjamin Poirier +Date: Thu, 8 Feb 2018 15:47:14 +0900 +Subject: e1000e: Avoid missed interrupts following ICR read + +From: Benjamin Poirier + +commit 116f4a640b3197401bc93b8adc6c35040308ceff upstream. + +The 82574 specification update errata 12 states that interrupts may be +missed if ICR is read while INT_ASSERTED is not set. Avoid that problem by +setting all bits related to events that can trigger the Other interrupt in +IMS. + +The Other interrupt is raised for such events regardless of whether or not +they are set in IMS. However, only when they are set is the INT_ASSERTED +bit also set in ICR. + +By doing this, we ensure that INT_ASSERTED is always set when we read ICR +in e1000_msix_other() and steer clear of the errata. This also ensures that +ICR will automatically be cleared on read, therefore we no longer need to +clear bits explicitly. + +Signed-off-by: Benjamin Poirier +Acked-by: Alexander Duyck +Tested-by: Aaron Brown +Signed-off-by: Jeff Kirsher +[bwh: Backported to 4.9: adjust context] +Cc: Yanhui He +Signed-off-by: Ben Hutchings +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/intel/e1000e/defines.h | 21 ++++++++++++++++++++- + drivers/net/ethernet/intel/e1000e/netdev.c | 11 ++++------- + 2 files changed, 24 insertions(+), 8 deletions(-) + +--- a/drivers/net/ethernet/intel/e1000e/defines.h ++++ b/drivers/net/ethernet/intel/e1000e/defines.h +@@ -400,6 +400,10 @@ + #define E1000_ICR_RXDMT0 0x00000010 /* Rx desc min. threshold (0) */ + #define E1000_ICR_RXO 0x00000040 /* Receiver Overrun */ + #define E1000_ICR_RXT0 0x00000080 /* Rx timer intr (ring 0) */ ++#define E1000_ICR_MDAC 0x00000200 /* MDIO Access Complete */ ++#define E1000_ICR_SRPD 0x00010000 /* Small Receive Packet Detected */ ++#define E1000_ICR_ACK 0x00020000 /* Receive ACK Frame Detected */ ++#define E1000_ICR_MNG 0x00040000 /* Manageability Event Detected */ + #define E1000_ICR_ECCER 0x00400000 /* Uncorrectable ECC Error */ + /* If this bit asserted, the driver should claim the interrupt */ + #define E1000_ICR_INT_ASSERTED 0x80000000 +@@ -407,7 +411,7 @@ + #define E1000_ICR_RXQ1 0x00200000 /* Rx Queue 1 Interrupt */ + #define E1000_ICR_TXQ0 0x00400000 /* Tx Queue 0 Interrupt */ + #define E1000_ICR_TXQ1 0x00800000 /* Tx Queue 1 Interrupt */ +-#define E1000_ICR_OTHER 0x01000000 /* Other Interrupts */ ++#define E1000_ICR_OTHER 0x01000000 /* Other Interrupt */ + + /* PBA ECC Register */ + #define E1000_PBA_ECC_COUNTER_MASK 0xFFF00000 /* ECC counter mask */ +@@ -431,12 +435,27 @@ + E1000_IMS_RXSEQ | \ + E1000_IMS_LSC) + ++/* These are all of the events related to the OTHER interrupt. ++ */ ++#define IMS_OTHER_MASK ( \ ++ E1000_IMS_LSC | \ ++ E1000_IMS_RXO | \ ++ E1000_IMS_MDAC | \ ++ E1000_IMS_SRPD | \ ++ E1000_IMS_ACK | \ ++ E1000_IMS_MNG) ++ + /* Interrupt Mask Set */ + #define E1000_IMS_TXDW E1000_ICR_TXDW /* Transmit desc written back */ + #define E1000_IMS_LSC E1000_ICR_LSC /* Link Status Change */ + #define E1000_IMS_RXSEQ E1000_ICR_RXSEQ /* Rx sequence error */ + #define E1000_IMS_RXDMT0 E1000_ICR_RXDMT0 /* Rx desc min. threshold */ ++#define E1000_IMS_RXO E1000_ICR_RXO /* Receiver Overrun */ + #define E1000_IMS_RXT0 E1000_ICR_RXT0 /* Rx timer intr */ ++#define E1000_IMS_MDAC E1000_ICR_MDAC /* MDIO Access Complete */ ++#define E1000_IMS_SRPD E1000_ICR_SRPD /* Small Receive Packet */ ++#define E1000_IMS_ACK E1000_ICR_ACK /* Receive ACK Frame Detected */ ++#define E1000_IMS_MNG E1000_ICR_MNG /* Manageability Event */ + #define E1000_IMS_ECCER E1000_ICR_ECCER /* Uncorrectable ECC Error */ + #define E1000_IMS_RXQ0 E1000_ICR_RXQ0 /* Rx Queue 0 Interrupt */ + #define E1000_IMS_RXQ1 E1000_ICR_RXQ1 /* Rx Queue 1 Interrupt */ +--- a/drivers/net/ethernet/intel/e1000e/netdev.c ++++ b/drivers/net/ethernet/intel/e1000e/netdev.c +@@ -1911,16 +1911,12 @@ static irqreturn_t e1000_msix_other(int + struct net_device *netdev = data; + struct e1000_adapter *adapter = netdev_priv(netdev); + struct e1000_hw *hw = &adapter->hw; +- u32 icr; +- +- icr = er32(ICR); +- ew32(ICR, E1000_ICR_OTHER); ++ u32 icr = er32(ICR); + + if (icr & adapter->eiac_mask) + ew32(ICS, (icr & adapter->eiac_mask)); + + if (icr & E1000_ICR_LSC) { +- ew32(ICR, E1000_ICR_LSC); + hw->mac.get_link_status = true; + /* guard against interrupt when we're going down */ + if (!test_bit(__E1000_DOWN, &adapter->state)) +@@ -1928,7 +1924,7 @@ static irqreturn_t e1000_msix_other(int + } + + if (!test_bit(__E1000_DOWN, &adapter->state)) +- ew32(IMS, E1000_IMS_OTHER); ++ ew32(IMS, E1000_IMS_OTHER | IMS_OTHER_MASK); + + return IRQ_HANDLED; + } +@@ -2255,7 +2251,8 @@ static void e1000_irq_enable(struct e100 + + if (adapter->msix_entries) { + ew32(EIAC_82574, adapter->eiac_mask & E1000_EIAC_MASK_82574); +- ew32(IMS, adapter->eiac_mask | E1000_IMS_OTHER | E1000_IMS_LSC); ++ ew32(IMS, adapter->eiac_mask | E1000_IMS_OTHER | ++ IMS_OTHER_MASK); + } else if ((hw->mac.type == e1000_pch_lpt) || + (hw->mac.type == e1000_pch_spt)) { + ew32(IMS, IMS_ENABLE_MASK | E1000_IMS_ECCER); diff --git a/queue-4.9/e1000e-fix-link-check-race-condition.patch b/queue-4.9/e1000e-fix-link-check-race-condition.patch new file mode 100644 index 00000000000..4dec0f22df1 --- /dev/null +++ b/queue-4.9/e1000e-fix-link-check-race-condition.patch @@ -0,0 +1,206 @@ +From foo@baz Mon Sep 24 13:08:20 CEST 2018 +From: Benjamin Poirier +Date: Tue, 6 Mar 2018 10:55:53 +0900 +Subject: e1000e: Fix link check race condition + +From: Benjamin Poirier + +commit e2710dbf0dc1e37d85368e2404049dadda848d5a upstream. + +Alex reported the following race condition: + +/* link goes up... interrupt... schedule watchdog */ +\ e1000_watchdog_task + \ e1000e_has_link + \ hw->mac.ops.check_for_link() === e1000e_check_for_copper_link + \ e1000e_phy_has_link_generic(..., &link) + link = true + + /* link goes down... interrupt */ + \ e1000_msix_other + hw->mac.get_link_status = true + + /* link is up */ + mac->get_link_status = false + + link_active = true + /* link_active is true, wrongly, and stays so because + * get_link_status is false */ + +Avoid this problem by making sure that we don't set get_link_status = false +after having checked the link. + +It seems this problem has been present since the introduction of e1000e. + +Link: https://lkml.org/lkml/2018/1/29/338 +Reported-by: Alexander Duyck +Signed-off-by: Benjamin Poirier +Acked-by: Alexander Duyck +Tested-by: Aaron Brown +Signed-off-by: Jeff Kirsher +Cc: Yanhui He +Signed-off-by: Ben Hutchings +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/intel/e1000e/ich8lan.c | 31 +++++++++++++++------------- + drivers/net/ethernet/intel/e1000e/mac.c | 14 ++++++------ + 2 files changed, 24 insertions(+), 21 deletions(-) + +--- a/drivers/net/ethernet/intel/e1000e/ich8lan.c ++++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c +@@ -1380,6 +1380,7 @@ static s32 e1000_check_for_copper_link_i + */ + if (!mac->get_link_status) + return 0; ++ mac->get_link_status = false; + + /* First we want to see if the MII Status Register reports + * link. If so, then we want to get the current speed/duplex +@@ -1387,12 +1388,12 @@ static s32 e1000_check_for_copper_link_i + */ + ret_val = e1000e_phy_has_link_generic(hw, 1, 0, &link); + if (ret_val) +- return ret_val; ++ goto out; + + if (hw->mac.type == e1000_pchlan) { + ret_val = e1000_k1_gig_workaround_hv(hw, link); + if (ret_val) +- return ret_val; ++ goto out; + } + + /* When connected at 10Mbps half-duplex, some parts are excessively +@@ -1427,7 +1428,7 @@ static s32 e1000_check_for_copper_link_i + + ret_val = hw->phy.ops.acquire(hw); + if (ret_val) +- return ret_val; ++ goto out; + + if (hw->mac.type == e1000_pch2lan) + emi_addr = I82579_RX_CONFIG; +@@ -1450,7 +1451,7 @@ static s32 e1000_check_for_copper_link_i + hw->phy.ops.release(hw); + + if (ret_val) +- return ret_val; ++ goto out; + + if (hw->mac.type == e1000_pch_spt) { + u16 data; +@@ -1459,14 +1460,14 @@ static s32 e1000_check_for_copper_link_i + if (speed == SPEED_1000) { + ret_val = hw->phy.ops.acquire(hw); + if (ret_val) +- return ret_val; ++ goto out; + + ret_val = e1e_rphy_locked(hw, + PHY_REG(776, 20), + &data); + if (ret_val) { + hw->phy.ops.release(hw); +- return ret_val; ++ goto out; + } + + ptr_gap = (data & (0x3FF << 2)) >> 2; +@@ -1480,18 +1481,18 @@ static s32 e1000_check_for_copper_link_i + } + hw->phy.ops.release(hw); + if (ret_val) +- return ret_val; ++ goto out; + } else { + ret_val = hw->phy.ops.acquire(hw); + if (ret_val) +- return ret_val; ++ goto out; + + ret_val = e1e_wphy_locked(hw, + PHY_REG(776, 20), + 0xC023); + hw->phy.ops.release(hw); + if (ret_val) +- return ret_val; ++ goto out; + + } + } +@@ -1518,7 +1519,7 @@ static s32 e1000_check_for_copper_link_i + (hw->adapter->pdev->device == E1000_DEV_ID_PCH_I218_V3)) { + ret_val = e1000_k1_workaround_lpt_lp(hw, link); + if (ret_val) +- return ret_val; ++ goto out; + } + if ((hw->mac.type == e1000_pch_lpt) || + (hw->mac.type == e1000_pch_spt)) { +@@ -1527,7 +1528,7 @@ static s32 e1000_check_for_copper_link_i + */ + ret_val = e1000_platform_pm_pch_lpt(hw, link); + if (ret_val) +- return ret_val; ++ goto out; + } + + /* Clear link partner's EEE ability */ +@@ -1547,9 +1548,7 @@ static s32 e1000_check_for_copper_link_i + } + + if (!link) +- return 0; /* No link detected */ +- +- mac->get_link_status = false; ++ goto out; + + switch (hw->mac.type) { + case e1000_pch2lan: +@@ -1615,6 +1614,10 @@ static s32 e1000_check_for_copper_link_i + e_dbg("Error configuring flow control\n"); + + return ret_val; ++ ++out: ++ mac->get_link_status = true; ++ return ret_val; + } + + static s32 e1000_get_variants_ich8lan(struct e1000_adapter *adapter) +--- a/drivers/net/ethernet/intel/e1000e/mac.c ++++ b/drivers/net/ethernet/intel/e1000e/mac.c +@@ -424,19 +424,15 @@ s32 e1000e_check_for_copper_link(struct + */ + if (!mac->get_link_status) + return 0; ++ mac->get_link_status = false; + + /* First we want to see if the MII Status Register reports + * link. If so, then we want to get the current speed/duplex + * of the PHY. + */ + ret_val = e1000e_phy_has_link_generic(hw, 1, 0, &link); +- if (ret_val) +- return ret_val; +- +- if (!link) +- return 0; /* No link detected */ +- +- mac->get_link_status = false; ++ if (ret_val || !link) ++ goto out; + + /* Check if there was DownShift, must be checked + * immediately after link-up +@@ -465,6 +461,10 @@ s32 e1000e_check_for_copper_link(struct + e_dbg("Error configuring flow control\n"); + + return ret_val; ++ ++out: ++ mac->get_link_status = true; ++ return ret_val; + } + + /** diff --git a/queue-4.9/e1000e-fix-queue-interrupt-re-raising-in-other-interrupt.patch b/queue-4.9/e1000e-fix-queue-interrupt-re-raising-in-other-interrupt.patch new file mode 100644 index 00000000000..43c2691c2d3 --- /dev/null +++ b/queue-4.9/e1000e-fix-queue-interrupt-re-raising-in-other-interrupt.patch @@ -0,0 +1,42 @@ +From foo@baz Mon Sep 24 13:08:20 CEST 2018 +From: Benjamin Poirier +Date: Thu, 8 Feb 2018 15:47:13 +0900 +Subject: e1000e: Fix queue interrupt re-raising in Other interrupt + +From: Benjamin Poirier + +commit 361a954e6a7215de11a6179ad9bdc07d7e394b04 upstream. + +Restores the ICS write for Rx/Tx queue interrupts which was present before +commit 16ecba59bc33 ("e1000e: Do not read ICR in Other interrupt", v4.5-rc1) +but was not restored in commit 4aea7a5c5e94 +("e1000e: Avoid receiver overrun interrupt bursts", v4.15-rc1). + +This re-raises the queue interrupts in case the txq or rxq bits were set in +ICR and the Other interrupt handler read and cleared ICR before the queue +interrupt was raised. + +Fixes: 4aea7a5c5e94 ("e1000e: Avoid receiver overrun interrupt bursts") +Signed-off-by: Benjamin Poirier +Acked-by: Alexander Duyck +Tested-by: Aaron Brown +Signed-off-by: Jeff Kirsher +Cc: Yanhui He +Signed-off-by: Ben Hutchings +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/intel/e1000e/netdev.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/net/ethernet/intel/e1000e/netdev.c ++++ b/drivers/net/ethernet/intel/e1000e/netdev.c +@@ -1916,6 +1916,9 @@ static irqreturn_t e1000_msix_other(int + icr = er32(ICR); + ew32(ICR, E1000_ICR_OTHER); + ++ if (icr & adapter->eiac_mask) ++ ew32(ICS, (icr & adapter->eiac_mask)); ++ + if (icr & E1000_ICR_LSC) { + ew32(ICR, E1000_ICR_LSC); + hw->mac.get_link_status = true; diff --git a/queue-4.9/e1000e-remove-other-from-eiac.patch b/queue-4.9/e1000e-remove-other-from-eiac.patch new file mode 100644 index 00000000000..ca6391434b4 --- /dev/null +++ b/queue-4.9/e1000e-remove-other-from-eiac.patch @@ -0,0 +1,60 @@ +From foo@baz Mon Sep 24 13:08:20 CEST 2018 +From: Benjamin Poirier +Date: Wed, 31 Jan 2018 16:26:27 +0900 +Subject: e1000e: Remove Other from EIAC + +From: Benjamin Poirier + +commit 745d0bd3af99ccc8c5f5822f808cd133eadad6ac upstream. + +It was reported that emulated e1000e devices in vmware esxi 6.5 Build +7526125 do not link up after commit 4aea7a5c5e94 ("e1000e: Avoid receiver +overrun interrupt bursts", v4.15-rc1). Some tracing shows that after +e1000e_trigger_lsc() is called, ICR reads out as 0x0 in e1000_msix_other() +on emulated e1000e devices. In comparison, on real e1000e 82574 hardware, +icr=0x80000004 (_INT_ASSERTED | _LSC) in the same situation. + +Some experimentation showed that this flaw in vmware e1000e emulation can +be worked around by not setting Other in EIAC. This is how it was before +16ecba59bc33 ("e1000e: Do not read ICR in Other interrupt", v4.5-rc1). + +Fixes: 4aea7a5c5e94 ("e1000e: Avoid receiver overrun interrupt bursts") +Signed-off-by: Benjamin Poirier +Tested-by: Aaron Brown +Signed-off-by: Jeff Kirsher +[bwh: Backported to 4.9: adjust context] +Cc: Yanhui He +Signed-off-by: Ben Hutchings +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/intel/e1000e/netdev.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/drivers/net/ethernet/intel/e1000e/netdev.c ++++ b/drivers/net/ethernet/intel/e1000e/netdev.c +@@ -1915,6 +1915,8 @@ static irqreturn_t e1000_msix_other(int + bool enable = true; + + icr = er32(ICR); ++ ew32(ICR, E1000_ICR_OTHER); ++ + if (icr & E1000_ICR_RXO) { + ew32(ICR, E1000_ICR_RXO); + enable = false; +@@ -2037,7 +2039,6 @@ static void e1000_configure_msix(struct + hw->hw_addr + E1000_EITR_82574(vector)); + else + writel(1, hw->hw_addr + E1000_EITR_82574(vector)); +- adapter->eiac_mask |= E1000_IMS_OTHER; + + /* Cause Tx interrupts on every write back */ + ivar |= BIT(31); +@@ -2262,7 +2263,7 @@ static void e1000_irq_enable(struct e100 + + if (adapter->msix_entries) { + ew32(EIAC_82574, adapter->eiac_mask & E1000_EIAC_MASK_82574); +- ew32(IMS, adapter->eiac_mask | E1000_IMS_LSC); ++ ew32(IMS, adapter->eiac_mask | E1000_IMS_OTHER | E1000_IMS_LSC); + } else if ((hw->mac.type == e1000_pch_lpt) || + (hw->mac.type == e1000_pch_spt)) { + ew32(IMS, IMS_ENABLE_MASK | E1000_IMS_ECCER); diff --git a/queue-4.9/mei-bus-type-promotion-bug-in-mei_nfc_if_version.patch b/queue-4.9/mei-bus-type-promotion-bug-in-mei_nfc_if_version.patch new file mode 100644 index 00000000000..f446b4b8ce4 --- /dev/null +++ b/queue-4.9/mei-bus-type-promotion-bug-in-mei_nfc_if_version.patch @@ -0,0 +1,37 @@ +From b40b3e9358fbafff6a4ba0f4b9658f6617146f9c Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Wed, 11 Jul 2018 15:29:31 +0300 +Subject: mei: bus: type promotion bug in mei_nfc_if_version() + +From: Dan Carpenter + +commit b40b3e9358fbafff6a4ba0f4b9658f6617146f9c upstream. + +We accidentally removed the check for negative returns +without considering the issue of type promotion. +The "if_version_length" variable is type size_t so if __mei_cl_recv() +returns a negative then "bytes_recv" is type promoted +to a high positive value and treated as success. + +Cc: +Fixes: 582ab27a063a ("mei: bus: fix received data size check in NFC fixup") +Signed-off-by: Dan Carpenter +Signed-off-by: Tomas Winkler +Signed-off-by: Greg Kroah-Hartman + + +--- + drivers/misc/mei/bus-fixup.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/misc/mei/bus-fixup.c ++++ b/drivers/misc/mei/bus-fixup.c +@@ -178,7 +178,7 @@ static int mei_nfc_if_version(struct mei + + ret = 0; + bytes_recv = __mei_cl_recv(cl, (u8 *)reply, if_version_length); +- if (bytes_recv < if_version_length) { ++ if (bytes_recv < 0 || bytes_recv < if_version_length) { + dev_err(bus->dev, "Could not read IF version\n"); + ret = -EIO; + goto err; diff --git a/queue-4.9/mips-vdso-drop-gic_get_usm_range-usage.patch b/queue-4.9/mips-vdso-drop-gic_get_usm_range-usage.patch new file mode 100644 index 00000000000..9163c7848a8 --- /dev/null +++ b/queue-4.9/mips-vdso-drop-gic_get_usm_range-usage.patch @@ -0,0 +1,84 @@ +From 00578cd864d45ae4b8fa3f684f8d6f783dd8d15d Mon Sep 17 00:00:00 2001 +From: Paul Burton +Date: Sat, 12 Aug 2017 21:36:30 -0700 +Subject: MIPS: VDSO: Drop gic_get_usm_range() usage + +From: Paul Burton + +commit 00578cd864d45ae4b8fa3f684f8d6f783dd8d15d upstream. + +We don't really need gic_get_usm_range() to abstract discovery of the +address of the GIC user-visible section now that we have access to its +base address globally. + +Switch to calculating it ourselves, which will allow us to stop +requiring the irqchip driver to care about a counter exposed to userland +for use via the VDSO. + +Signed-off-by: Paul Burton +Cc: Jason Cooper +Cc: Marc Zyngier +Cc: Thomas Gleixner +Cc: linux-mips@linux-mips.org +Patchwork: https://patchwork.linux-mips.org/patch/17040/ +Signed-off-by: Ralf Baechle +Signed-off-by: SZ Lin (林上智) +Signed-off-by: Greg Kroah-Hartman +--- + arch/mips/kernel/vdso.c | 15 +++++---------- + 1 file changed, 5 insertions(+), 10 deletions(-) + +--- a/arch/mips/kernel/vdso.c ++++ b/arch/mips/kernel/vdso.c +@@ -13,7 +13,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -21,6 +20,7 @@ + #include + + #include ++#include + #include + #include + +@@ -101,9 +101,8 @@ int arch_setup_additional_pages(struct l + { + struct mips_vdso_image *image = current->thread.abi->vdso; + struct mm_struct *mm = current->mm; +- unsigned long gic_size, vvar_size, size, base, data_addr, vdso_addr; ++ unsigned long gic_size, vvar_size, size, base, data_addr, vdso_addr, gic_pfn; + struct vm_area_struct *vma; +- struct resource gic_res; + int ret; + + if (down_write_killable(&mm->mmap_sem)) +@@ -127,7 +126,7 @@ int arch_setup_additional_pages(struct l + * only map a page even though the total area is 64K, as we only need + * the counter registers at the start. + */ +- gic_size = gic_present ? PAGE_SIZE : 0; ++ gic_size = mips_gic_present() ? PAGE_SIZE : 0; + vvar_size = gic_size + PAGE_SIZE; + size = vvar_size + image->size; + +@@ -168,13 +167,9 @@ int arch_setup_additional_pages(struct l + + /* Map GIC user page. */ + if (gic_size) { +- ret = gic_get_usm_range(&gic_res); +- if (ret) +- goto out; ++ gic_pfn = virt_to_phys(mips_gic_base + MIPS_GIC_USER_OFS) >> PAGE_SHIFT; + +- ret = io_remap_pfn_range(vma, base, +- gic_res.start >> PAGE_SHIFT, +- gic_size, ++ ret = io_remap_pfn_range(vma, base, gic_pfn, gic_size, + pgprot_noncached(PAGE_READONLY)); + if (ret) + goto out; diff --git a/queue-4.9/mips-vdso-match-data-page-cache-colouring-when-d-aliases.patch b/queue-4.9/mips-vdso-match-data-page-cache-colouring-when-d-aliases.patch new file mode 100644 index 00000000000..31f40828d7c --- /dev/null +++ b/queue-4.9/mips-vdso-match-data-page-cache-colouring-when-d-aliases.patch @@ -0,0 +1,90 @@ +From 0f02cfbc3d9e413d450d8d0fd660077c23f67eff Mon Sep 17 00:00:00 2001 +From: Paul Burton +Date: Thu, 30 Aug 2018 11:01:21 -0700 +Subject: MIPS: VDSO: Match data page cache colouring when D$ aliases + +From: Paul Burton + +commit 0f02cfbc3d9e413d450d8d0fd660077c23f67eff upstream. + +When a system suffers from dcache aliasing a user program may observe +stale VDSO data from an aliased cache line. Notably this can break the +expectation that clock_gettime(CLOCK_MONOTONIC, ...) is, as its name +suggests, monotonic. + +In order to ensure that users observe updates to the VDSO data page as +intended, align the user mappings of the VDSO data page such that their +cache colouring matches that of the virtual address range which the +kernel will use to update the data page - typically its unmapped address +within kseg0. + +This ensures that we don't introduce aliasing cache lines for the VDSO +data page, and therefore that userland will observe updates without +requiring cache invalidation. + +Signed-off-by: Paul Burton +Reported-by: Hauke Mehrtens +Reported-by: Rene Nielsen +Reported-by: Alexandre Belloni +Fixes: ebb5e78cc634 ("MIPS: Initial implementation of a VDSO") +Patchwork: https://patchwork.linux-mips.org/patch/20344/ +Tested-by: Alexandre Belloni +Tested-by: Hauke Mehrtens +Cc: James Hogan +Cc: linux-mips@linux-mips.org +Cc: stable@vger.kernel.org # v4.4+ +Signed-off-by: Greg Kroah-Hartman + + +--- + arch/mips/kernel/vdso.c | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + +--- a/arch/mips/kernel/vdso.c ++++ b/arch/mips/kernel/vdso.c +@@ -14,12 +14,14 @@ + #include + #include + #include ++#include + #include + #include + #include + #include + + #include ++#include + #include + + /* Kernel-provided data used by the VDSO. */ +@@ -129,12 +131,30 @@ int arch_setup_additional_pages(struct l + vvar_size = gic_size + PAGE_SIZE; + size = vvar_size + image->size; + ++ /* ++ * Find a region that's large enough for us to perform the ++ * colour-matching alignment below. ++ */ ++ if (cpu_has_dc_aliases) ++ size += shm_align_mask + 1; ++ + base = get_unmapped_area(NULL, 0, size, 0, 0); + if (IS_ERR_VALUE(base)) { + ret = base; + goto out; + } + ++ /* ++ * If we suffer from dcache aliasing, ensure that the VDSO data page ++ * mapping is coloured the same as the kernel's mapping of that memory. ++ * This ensures that when the kernel updates the VDSO data userland ++ * will observe it without requiring cache invalidations. ++ */ ++ if (cpu_has_dc_aliases) { ++ base = __ALIGN_MASK(base, shm_align_mask); ++ base += ((unsigned long)&vdso_data - gic_size) & shm_align_mask; ++ } ++ + data_addr = base + gic_size; + vdso_addr = data_addr + PAGE_SIZE; + diff --git a/queue-4.9/partial-revert-e1000e-avoid-receiver-overrun-interrupt-bursts.patch b/queue-4.9/partial-revert-e1000e-avoid-receiver-overrun-interrupt-bursts.patch new file mode 100644 index 00000000000..6ccdea45fe2 --- /dev/null +++ b/queue-4.9/partial-revert-e1000e-avoid-receiver-overrun-interrupt-bursts.patch @@ -0,0 +1,76 @@ +From foo@baz Mon Sep 24 13:08:20 CEST 2018 +From: Benjamin Poirier +Date: Thu, 8 Feb 2018 15:47:12 +0900 +Subject: Partial revert "e1000e: Avoid receiver overrun interrupt bursts" + +From: Benjamin Poirier + +commit 1f0ea19722ef9dfa229a9540f70b8d1c34a98a6a upstream. + +This partially reverts commit 4aea7a5c5e940c1723add439f4088844cd26196d. + +We keep the fix for the first part of the problem (1) described in the log +of that commit, that is to read ICR in the other interrupt handler. We +remove the fix for the second part of the problem (2), Other interrupt +throttling. + +Bursts of "Other" interrupts may once again occur during rxo (receive +overflow) traffic conditions. This is deemed acceptable in the interest of +avoiding unforeseen fallout from changes that are not strictly necessary. +As discussed, the e1000e driver should be in "maintenance mode". + +Link: https://www.spinics.net/lists/netdev/msg480675.html +Signed-off-by: Benjamin Poirier +Acked-by: Alexander Duyck +Tested-by: Aaron Brown +Signed-off-by: Jeff Kirsher +Cc: Yanhui He +Signed-off-by: Ben Hutchings +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/intel/e1000e/netdev.c | 16 ++-------------- + 1 file changed, 2 insertions(+), 14 deletions(-) + +--- a/drivers/net/ethernet/intel/e1000e/netdev.c ++++ b/drivers/net/ethernet/intel/e1000e/netdev.c +@@ -1912,21 +1912,10 @@ static irqreturn_t e1000_msix_other(int + struct e1000_adapter *adapter = netdev_priv(netdev); + struct e1000_hw *hw = &adapter->hw; + u32 icr; +- bool enable = true; + + icr = er32(ICR); + ew32(ICR, E1000_ICR_OTHER); + +- if (icr & E1000_ICR_RXO) { +- ew32(ICR, E1000_ICR_RXO); +- enable = false; +- /* napi poll will re-enable Other, make sure it runs */ +- if (napi_schedule_prep(&adapter->napi)) { +- adapter->total_rx_bytes = 0; +- adapter->total_rx_packets = 0; +- __napi_schedule(&adapter->napi); +- } +- } + if (icr & E1000_ICR_LSC) { + ew32(ICR, E1000_ICR_LSC); + hw->mac.get_link_status = true; +@@ -1935,7 +1924,7 @@ static irqreturn_t e1000_msix_other(int + mod_timer(&adapter->watchdog_timer, jiffies + 1); + } + +- if (enable && !test_bit(__E1000_DOWN, &adapter->state)) ++ if (!test_bit(__E1000_DOWN, &adapter->state)) + ew32(IMS, E1000_IMS_OTHER); + + return IRQ_HANDLED; +@@ -2706,8 +2695,7 @@ static int e1000e_poll(struct napi_struc + napi_complete_done(napi, work_done); + if (!test_bit(__E1000_DOWN, &adapter->state)) { + if (adapter->msix_entries) +- ew32(IMS, adapter->rx_ring->ims_val | +- E1000_IMS_OTHER); ++ ew32(IMS, adapter->rx_ring->ims_val); + else + e1000_irq_enable(adapter); + } diff --git a/queue-4.9/revert-e1000e-separate-signaling-for-link-check-link-up.patch b/queue-4.9/revert-e1000e-separate-signaling-for-link-check-link-up.patch new file mode 100644 index 00000000000..fddf218cdeb --- /dev/null +++ b/queue-4.9/revert-e1000e-separate-signaling-for-link-check-link-up.patch @@ -0,0 +1,143 @@ +From foo@baz Mon Sep 24 13:08:20 CEST 2018 +From: Benjamin Poirier +Date: Tue, 6 Mar 2018 10:55:52 +0900 +Subject: Revert "e1000e: Separate signaling for link check/link up" + +From: Benjamin Poirier + +commit 3016e0a0c91246e55418825ba9aae271be267522 upstream. + +This reverts commit 19110cfbb34d4af0cdfe14cd243f3b09dc95b013. +This reverts commit 4110e02eb45ea447ec6f5459c9934de0a273fb91. +This reverts commit d3604515c9eda464a92e8e67aae82dfe07fe3c98. + +Commit 19110cfbb34d ("e1000e: Separate signaling for link check/link up") +changed what happens to the link status when there is an error which +happens after "get_link_status = false" in the copper check_for_link +callbacks. Previously, such an error would be ignored and the link +considered up. After that commit, any error implies that the link is down. + +Revert commit 19110cfbb34d ("e1000e: Separate signaling for link check/link +up") and its followups. After reverting, the race condition described in +the log of commit 19110cfbb34d is reintroduced. It may still be triggered +by LSC events but this should keep the link down in case the link is +electrically unstable, as discussed. The race may no longer be +triggered by RXO events because commit 4aea7a5c5e94 ("e1000e: Avoid +receiver overrun interrupt bursts") restored reading icr in the Other +handler. + +Link: https://lkml.org/lkml/2018/3/1/789 +Signed-off-by: Benjamin Poirier +Acked-by: Alexander Duyck +Tested-by: Aaron Brown +Signed-off-by: Jeff Kirsher +Cc: Yanhui He +Signed-off-by: Ben Hutchings +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/intel/e1000e/ich8lan.c | 13 ++++--------- + drivers/net/ethernet/intel/e1000e/mac.c | 13 ++++--------- + drivers/net/ethernet/intel/e1000e/netdev.c | 2 +- + 3 files changed, 9 insertions(+), 19 deletions(-) + +--- a/drivers/net/ethernet/intel/e1000e/ich8lan.c ++++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c +@@ -1364,9 +1364,6 @@ out: + * Checks to see of the link status of the hardware has changed. If a + * change in link status has been detected, then we read the PHY registers + * to get the current speed/duplex if link exists. +- * +- * Returns a negative error code (-E1000_ERR_*) or 0 (link down) or 1 (link +- * up). + **/ + static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw) + { +@@ -1382,7 +1379,7 @@ static s32 e1000_check_for_copper_link_i + * Change or Rx Sequence Error interrupt. + */ + if (!mac->get_link_status) +- return 1; ++ return 0; + + /* First we want to see if the MII Status Register reports + * link. If so, then we want to get the current speed/duplex +@@ -1600,7 +1597,7 @@ static s32 e1000_check_for_copper_link_i + * we have already determined whether we have link or not. + */ + if (!mac->autoneg) +- return 1; ++ return -E1000_ERR_CONFIG; + + /* Auto-Neg is enabled. Auto Speed Detection takes care + * of MAC speed/duplex configuration. So we only need to +@@ -1614,12 +1611,10 @@ static s32 e1000_check_for_copper_link_i + * different link partner. + */ + ret_val = e1000e_config_fc_after_link_up(hw); +- if (ret_val) { ++ if (ret_val) + e_dbg("Error configuring flow control\n"); +- return ret_val; +- } + +- return 1; ++ return ret_val; + } + + static s32 e1000_get_variants_ich8lan(struct e1000_adapter *adapter) +--- a/drivers/net/ethernet/intel/e1000e/mac.c ++++ b/drivers/net/ethernet/intel/e1000e/mac.c +@@ -410,9 +410,6 @@ void e1000e_clear_hw_cntrs_base(struct e + * Checks to see of the link status of the hardware has changed. If a + * change in link status has been detected, then we read the PHY registers + * to get the current speed/duplex if link exists. +- * +- * Returns a negative error code (-E1000_ERR_*) or 0 (link down) or 1 (link +- * up). + **/ + s32 e1000e_check_for_copper_link(struct e1000_hw *hw) + { +@@ -426,7 +423,7 @@ s32 e1000e_check_for_copper_link(struct + * Change or Rx Sequence Error interrupt. + */ + if (!mac->get_link_status) +- return 1; ++ return 0; + + /* First we want to see if the MII Status Register reports + * link. If so, then we want to get the current speed/duplex +@@ -450,7 +447,7 @@ s32 e1000e_check_for_copper_link(struct + * we have already determined whether we have link or not. + */ + if (!mac->autoneg) +- return 1; ++ return -E1000_ERR_CONFIG; + + /* Auto-Neg is enabled. Auto Speed Detection takes care + * of MAC speed/duplex configuration. So we only need to +@@ -464,12 +461,10 @@ s32 e1000e_check_for_copper_link(struct + * different link partner. + */ + ret_val = e1000e_config_fc_after_link_up(hw); +- if (ret_val) { ++ if (ret_val) + e_dbg("Error configuring flow control\n"); +- return ret_val; +- } + +- return 1; ++ return ret_val; + } + + /** +--- a/drivers/net/ethernet/intel/e1000e/netdev.c ++++ b/drivers/net/ethernet/intel/e1000e/netdev.c +@@ -5074,7 +5074,7 @@ static bool e1000e_has_link(struct e1000 + case e1000_media_type_copper: + if (hw->mac.get_link_status) { + ret_val = hw->mac.ops.check_for_link(hw); +- link_active = ret_val > 0; ++ link_active = !hw->mac.get_link_status; + } else { + link_active = true; + } diff --git a/queue-4.9/series b/queue-4.9/series index 7f569f3f6ee..fa171d23e18 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -100,3 +100,12 @@ drm-panel-type-promotion-bug-in-s6e8aa0_read_mtp_id.patch ib-nes-fix-a-compiler-warning.patch gpiolib-respect-error-code-of-get_direction.patch pinctrl-qcom-spmi-gpio-fix-pmic_gpio_config_get-to-be-compliant.patch +mei-bus-type-promotion-bug-in-mei_nfc_if_version.patch +mips-vdso-match-data-page-cache-colouring-when-d-aliases.patch +e1000e-remove-other-from-eiac.patch +partial-revert-e1000e-avoid-receiver-overrun-interrupt-bursts.patch +e1000e-fix-queue-interrupt-re-raising-in-other-interrupt.patch +e1000e-avoid-missed-interrupts-following-icr-read.patch +revert-e1000e-separate-signaling-for-link-check-link-up.patch +e1000e-fix-link-check-race-condition.patch +mips-vdso-drop-gic_get_usm_range-usage.patch -- 2.47.3