From: Greg Kroah-Hartman Date: Mon, 3 Jul 2017 09:02:47 +0000 (+0200) Subject: 4.9-stable patches X-Git-Tag: v3.18.60~33 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8fff23acd5b81c795ef140d537146a7dbf407207;p=thirdparty%2Fkernel%2Fstable-queue.git 4.9-stable patches added patches: arm64-dts-meson-gxbb-odroidc2-fix-gbe-tx-link-breakage.patch dt-bindings-net-add-eee-capability-constants.patch dt-bindings-net-use-boolean-dt-properties-for-eee-broken-modes.patch net-ethtool-add-support-for-2500baset-and-5000baset-link-modes.patch net-phy-add-an-option-to-disable-eee-advertisement.patch net-phy-fix-sign-type-error-in-genphy_config_eee_advert.patch net-phy-use-boolean-dt-properties-for-eee-broken-modes.patch sparc64-handle-pio-mem-non-resumable-errors.patch sparc64-zero-pages-on-allocation-for-mondo-and-error-queues.patch --- diff --git a/queue-4.9/arm64-dts-meson-gxbb-odroidc2-fix-gbe-tx-link-breakage.patch b/queue-4.9/arm64-dts-meson-gxbb-odroidc2-fix-gbe-tx-link-breakage.patch new file mode 100644 index 00000000000..4af28487876 --- /dev/null +++ b/queue-4.9/arm64-dts-meson-gxbb-odroidc2-fix-gbe-tx-link-breakage.patch @@ -0,0 +1,48 @@ +From foo@baz Mon Jul 3 11:00:33 CEST 2017 +From: Jerome Brunet +Date: Fri, 20 Jan 2017 08:20:24 -0800 +Subject: ARM64: dts: meson-gxbb-odroidc2: fix GbE tx link breakage + +From: Jerome Brunet + + +[ Upstream commit feb3cbea0946c67060e2d5bcb7499b0a6f6700fe ] + +OdroidC2 GbE link breaks under heavy tx transfer. This happens even if the +MAC does not enable Energy Efficient Ethernet (No Low Power state Idle on +the Tx path). The problem seems to come from the phy Rx path, entering the +LPI state. + +Disabling EEE advertisement on the phy prevent this feature to be +negociated with the link partner and solve the issue. + +Signed-off-by: Jerome Brunet +Signed-off-by: Kevin Hilman +Signed-off-by: Arnd Bergmann +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts +@@ -85,6 +85,18 @@ + status = "okay"; + pinctrl-0 = <ð_pins>; + pinctrl-names = "default"; ++ phy-handle = <ð_phy0>; ++ ++ mdio { ++ compatible = "snps,dwmac-mdio"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ eth_phy0: ethernet-phy@0 { ++ reg = <0>; ++ eee-broken-1000t; ++ }; ++ }; + }; + + &ir { diff --git a/queue-4.9/dt-bindings-net-add-eee-capability-constants.patch b/queue-4.9/dt-bindings-net-add-eee-capability-constants.patch new file mode 100644 index 00000000000..5675758d13b --- /dev/null +++ b/queue-4.9/dt-bindings-net-add-eee-capability-constants.patch @@ -0,0 +1,43 @@ +From foo@baz Mon Jul 3 11:00:33 CEST 2017 +From: jbrunet +Date: Mon, 28 Nov 2016 10:46:47 +0100 +Subject: dt-bindings: net: add EEE capability constants + +From: jbrunet + + +[ Upstream commit 1fc31357ad194fb98691f3d122bcd47e59239e83 ] + +Signed-off-by: Jerome Brunet +Tested-by: Yegor Yefremov +Tested-by: Andreas Färber +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + include/dt-bindings/net/mdio.h | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + create mode 100644 include/dt-bindings/net/mdio.h + +--- /dev/null ++++ b/include/dt-bindings/net/mdio.h +@@ -0,0 +1,19 @@ ++/* ++ * This header provides generic constants for ethernet MDIO bindings ++ */ ++ ++#ifndef _DT_BINDINGS_NET_MDIO_H ++#define _DT_BINDINGS_NET_MDIO_H ++ ++/* ++ * EEE capability Advertisement ++ */ ++ ++#define MDIO_EEE_100TX 0x0002 /* 100TX EEE cap */ ++#define MDIO_EEE_1000T 0x0004 /* 1000T EEE cap */ ++#define MDIO_EEE_10GT 0x0008 /* 10GT EEE cap */ ++#define MDIO_EEE_1000KX 0x0010 /* 1000KX EEE cap */ ++#define MDIO_EEE_10GKX4 0x0020 /* 10G KX4 EEE cap */ ++#define MDIO_EEE_10GKR 0x0040 /* 10G KR EEE cap */ ++ ++#endif diff --git a/queue-4.9/dt-bindings-net-use-boolean-dt-properties-for-eee-broken-modes.patch b/queue-4.9/dt-bindings-net-use-boolean-dt-properties-for-eee-broken-modes.patch new file mode 100644 index 00000000000..1ec6f3a1ca1 --- /dev/null +++ b/queue-4.9/dt-bindings-net-use-boolean-dt-properties-for-eee-broken-modes.patch @@ -0,0 +1,72 @@ +From foo@baz Mon Jul 3 11:00:33 CEST 2017 +From: jbrunet +Date: Mon, 19 Dec 2016 16:05:38 +0100 +Subject: dt: bindings: net: use boolean dt properties for eee broken modes + +From: jbrunet + + +[ Upstream commit 308d3165d8b2b98d3dc3d97d6662062735daea67 ] + +The patches regarding eee-broken-modes was merged before all people +involved could find an agreement on the best way to move forward. + +While we agreed on having a DT property to mark particular modes as broken, +the value used for eee-broken-modes mapped the phy register in very direct +way. Because of this, the concern is that it could be used to implement +configuration policies instead of describing a broken HW. + +In the end, having a boolean property for each mode seems to be preferred +over one bit field value mapping the register (too) directly. + +Cc: Florian Fainelli +Signed-off-by: Jerome Brunet +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + Documentation/devicetree/bindings/net/phy.txt | 9 +++++++++ + include/dt-bindings/net/mdio.h | 19 ------------------- + 2 files changed, 9 insertions(+), 19 deletions(-) + delete mode 100644 include/dt-bindings/net/mdio.h + +--- a/Documentation/devicetree/bindings/net/phy.txt ++++ b/Documentation/devicetree/bindings/net/phy.txt +@@ -35,6 +35,15 @@ Optional Properties: + - broken-turn-around: If set, indicates the PHY device does not correctly + release the turn around line low at the end of a MDIO transaction. + ++- eee-broken-100tx: ++- eee-broken-1000t: ++- eee-broken-10gt: ++- eee-broken-1000kx: ++- eee-broken-10gkx4: ++- eee-broken-10gkr: ++ Mark the corresponding energy efficient ethernet mode as broken and ++ request the ethernet to stop advertising it. ++ + Example: + + ethernet-phy@0 { +--- a/include/dt-bindings/net/mdio.h ++++ /dev/null +@@ -1,19 +0,0 @@ +-/* +- * This header provides generic constants for ethernet MDIO bindings +- */ +- +-#ifndef _DT_BINDINGS_NET_MDIO_H +-#define _DT_BINDINGS_NET_MDIO_H +- +-/* +- * EEE capability Advertisement +- */ +- +-#define MDIO_EEE_100TX 0x0002 /* 100TX EEE cap */ +-#define MDIO_EEE_1000T 0x0004 /* 1000T EEE cap */ +-#define MDIO_EEE_10GT 0x0008 /* 10GT EEE cap */ +-#define MDIO_EEE_1000KX 0x0010 /* 1000KX EEE cap */ +-#define MDIO_EEE_10GKX4 0x0020 /* 10G KX4 EEE cap */ +-#define MDIO_EEE_10GKR 0x0040 /* 10G KR EEE cap */ +- +-#endif diff --git a/queue-4.9/mm-numa-avoid-waiting-on-freed-migrated-pages.patch b/queue-4.9/mm-numa-avoid-waiting-on-freed-migrated-pages.patch index caa7c9bae4f..487a9748f67 100644 --- a/queue-4.9/mm-numa-avoid-waiting-on-freed-migrated-pages.patch +++ b/queue-4.9/mm-numa-avoid-waiting-on-freed-migrated-pages.patch @@ -52,7 +52,6 @@ Acked-by: Steve Capper Acked-by: Kirill A. Shutemov Acked-by: Vlastimil Babka Cc: Mel Gorman -Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman diff --git a/queue-4.9/net-ethtool-add-support-for-2500baset-and-5000baset-link-modes.patch b/queue-4.9/net-ethtool-add-support-for-2500baset-and-5000baset-link-modes.patch new file mode 100644 index 00000000000..9b9e289293e --- /dev/null +++ b/queue-4.9/net-ethtool-add-support-for-2500baset-and-5000baset-link-modes.patch @@ -0,0 +1,41 @@ +From foo@baz Mon Jul 3 11:00:33 CEST 2017 +From: Pavel Belous +Date: Sat, 28 Jan 2017 22:53:28 +0300 +Subject: net: ethtool: add support for 2500BaseT and 5000BaseT link modes + +From: Pavel Belous + + +[ Upstream commit 94842b4fc4d6b1691cfc86c6f5251f299d27f4ba ] + +This patch introduce support for 2500BaseT and 5000BaseT link modes. +These modes are included in the new IEEE 802.3bz standard. + +Signed-off-by: Pavel Belous +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + include/uapi/linux/ethtool.h | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/include/uapi/linux/ethtool.h ++++ b/include/uapi/linux/ethtool.h +@@ -1368,6 +1368,8 @@ enum ethtool_link_mode_bit_indices { + ETHTOOL_LINK_MODE_10000baseLR_Full_BIT = 44, + ETHTOOL_LINK_MODE_10000baseLRM_Full_BIT = 45, + ETHTOOL_LINK_MODE_10000baseER_Full_BIT = 46, ++ ETHTOOL_LINK_MODE_2500baseT_Full_BIT = 47, ++ ETHTOOL_LINK_MODE_5000baseT_Full_BIT = 48, + + + /* Last allowed bit for __ETHTOOL_LINK_MODE_LEGACY_MASK is bit +@@ -1377,7 +1379,7 @@ enum ethtool_link_mode_bit_indices { + */ + + __ETHTOOL_LINK_MODE_LAST +- = ETHTOOL_LINK_MODE_10000baseER_Full_BIT, ++ = ETHTOOL_LINK_MODE_5000baseT_Full_BIT, + }; + + #define __ETHTOOL_LINK_MODE_LEGACY_MASK(base_name) \ diff --git a/queue-4.9/net-phy-add-an-option-to-disable-eee-advertisement.patch b/queue-4.9/net-phy-add-an-option-to-disable-eee-advertisement.patch new file mode 100644 index 00000000000..1ed45f1731d --- /dev/null +++ b/queue-4.9/net-phy-add-an-option-to-disable-eee-advertisement.patch @@ -0,0 +1,181 @@ +From foo@baz Mon Jul 3 11:00:33 CEST 2017 +From: jbrunet +Date: Mon, 28 Nov 2016 10:46:46 +0100 +Subject: net: phy: add an option to disable EEE advertisement + +From: jbrunet + + +[ Upstream commit d853d145ea3e63387a2ac759aa41d5e43876e561 ] + +This patch adds an option to disable EEE advertisement in the generic PHY +by providing a mask of prohibited modes corresponding to the value found in +the MDIO_AN_EEE_ADV register. + +On some platforms, PHY Low power idle seems to be causing issues, even +breaking the link some cases. The patch provides a convenient way for these +platforms to disable EEE advertisement and work around the issue. + +Signed-off-by: Jerome Brunet +Tested-by: Yegor Yefremov +Tested-by: Andreas Färber +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/phy/phy.c | 3 + + drivers/net/phy/phy_device.c | 80 ++++++++++++++++++++++++++++++++++++++----- + include/linux/phy.h | 3 + + 3 files changed, 77 insertions(+), 9 deletions(-) + +--- a/drivers/net/phy/phy.c ++++ b/drivers/net/phy/phy.c +@@ -1384,6 +1384,9 @@ int phy_ethtool_set_eee(struct phy_devic + { + int val = ethtool_adv_to_mmd_eee_adv_t(data->advertised); + ++ /* Mask prohibited EEE modes */ ++ val &= ~phydev->eee_broken_modes; ++ + phy_write_mmd_indirect(phydev, MDIO_AN_EEE_ADV, MDIO_MMD_AN, val); + + return 0; +--- a/drivers/net/phy/phy_device.c ++++ b/drivers/net/phy/phy_device.c +@@ -1146,6 +1146,43 @@ static int genphy_config_advert(struct p + } + + /** ++ * genphy_config_eee_advert - disable unwanted eee mode advertisement ++ * @phydev: target phy_device struct ++ * ++ * Description: Writes MDIO_AN_EEE_ADV after disabling unsupported energy ++ * efficent ethernet modes. Returns 0 if the PHY's advertisement hasn't ++ * changed, and 1 if it has changed. ++ */ ++static int genphy_config_eee_advert(struct phy_device *phydev) ++{ ++ u32 broken = phydev->eee_broken_modes; ++ u32 old_adv, adv; ++ ++ /* Nothing to disable */ ++ if (!broken) ++ return 0; ++ ++ /* If the following call fails, we assume that EEE is not ++ * supported by the phy. If we read 0, EEE is not advertised ++ * In both case, we don't need to continue ++ */ ++ adv = phy_read_mmd_indirect(phydev, MDIO_AN_EEE_ADV, MDIO_MMD_AN); ++ if (adv <= 0) ++ return 0; ++ ++ old_adv = adv; ++ adv &= ~broken; ++ ++ /* Advertising remains unchanged with the broken mask */ ++ if (old_adv == adv) ++ return 0; ++ ++ phy_write_mmd_indirect(phydev, MDIO_AN_EEE_ADV, MDIO_MMD_AN, adv); ++ ++ return 1; ++} ++ ++/** + * genphy_setup_forced - configures/forces speed/duplex from @phydev + * @phydev: target phy_device struct + * +@@ -1203,15 +1240,20 @@ EXPORT_SYMBOL(genphy_restart_aneg); + */ + int genphy_config_aneg(struct phy_device *phydev) + { +- int result; ++ int err, changed; ++ ++ changed = genphy_config_eee_advert(phydev); + + if (AUTONEG_ENABLE != phydev->autoneg) + return genphy_setup_forced(phydev); + +- result = genphy_config_advert(phydev); +- if (result < 0) /* error */ +- return result; +- if (result == 0) { ++ err = genphy_config_advert(phydev); ++ if (err < 0) /* error */ ++ return err; ++ ++ changed |= err; ++ ++ if (changed == 0) { + /* Advertisement hasn't changed, but maybe aneg was never on to + * begin with? Or maybe phy was isolated? + */ +@@ -1221,16 +1263,16 @@ int genphy_config_aneg(struct phy_device + return ctl; + + if (!(ctl & BMCR_ANENABLE) || (ctl & BMCR_ISOLATE)) +- result = 1; /* do restart aneg */ ++ changed = 1; /* do restart aneg */ + } + + /* Only restart aneg if we are advertising something different + * than we were before. + */ +- if (result > 0) +- result = genphy_restart_aneg(phydev); ++ if (changed > 0) ++ return genphy_restart_aneg(phydev); + +- return result; ++ return 0; + } + EXPORT_SYMBOL(genphy_config_aneg); + +@@ -1588,6 +1630,21 @@ static void of_set_phy_supported(struct + __set_phy_supported(phydev, max_speed); + } + ++static void of_set_phy_eee_broken(struct phy_device *phydev) ++{ ++ struct device_node *node = phydev->mdio.dev.of_node; ++ u32 broken; ++ ++ if (!IS_ENABLED(CONFIG_OF_MDIO)) ++ return; ++ ++ if (!node) ++ return; ++ ++ if (!of_property_read_u32(node, "eee-broken-modes", &broken)) ++ phydev->eee_broken_modes = broken; ++} ++ + /** + * phy_probe - probe and init a PHY device + * @dev: device to probe and init +@@ -1625,6 +1682,11 @@ static int phy_probe(struct device *dev) + of_set_phy_supported(phydev); + phydev->advertising = phydev->supported; + ++ /* Get the EEE modes we want to prohibit. We will ask ++ * the PHY stop advertising these mode later on ++ */ ++ of_set_phy_eee_broken(phydev); ++ + /* Set the state to READY by default */ + phydev->state = PHY_READY; + +--- a/include/linux/phy.h ++++ b/include/linux/phy.h +@@ -401,6 +401,9 @@ struct phy_device { + u32 advertising; + u32 lp_advertising; + ++ /* Energy efficient ethernet modes which should be prohibited */ ++ u32 eee_broken_modes; ++ + int autoneg; + + int link_timeout; diff --git a/queue-4.9/net-phy-fix-sign-type-error-in-genphy_config_eee_advert.patch b/queue-4.9/net-phy-fix-sign-type-error-in-genphy_config_eee_advert.patch new file mode 100644 index 00000000000..f63befc469c --- /dev/null +++ b/queue-4.9/net-phy-fix-sign-type-error-in-genphy_config_eee_advert.patch @@ -0,0 +1,38 @@ +From foo@baz Mon Jul 3 11:00:33 CEST 2017 +From: jbrunet +Date: Mon, 19 Dec 2016 16:05:36 +0100 +Subject: net: phy: fix sign type error in genphy_config_eee_advert + +From: jbrunet + + +[ Upstream commit 3bb9ab63276696988d8224f52db20e87194deb4b ] + +In genphy_config_eee_advert, the return value of phy_read_mmd_indirect is +checked to know if the register could be accessed but the result is +assigned to a 'u32'. +Changing to 'int' to correctly get errors from phy_read_mmd_indirect. + +Fixes: d853d145ea3e ("net: phy: add an option to disable EEE advertisement") +Reported-by: Julia Lawall +Signed-off-by: Jerome Brunet +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/phy/phy_device.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/net/phy/phy_device.c ++++ b/drivers/net/phy/phy_device.c +@@ -1155,8 +1155,8 @@ static int genphy_config_advert(struct p + */ + static int genphy_config_eee_advert(struct phy_device *phydev) + { +- u32 broken = phydev->eee_broken_modes; +- u32 old_adv, adv; ++ int broken = phydev->eee_broken_modes; ++ int old_adv, adv; + + /* Nothing to disable */ + if (!broken) diff --git a/queue-4.9/net-phy-use-boolean-dt-properties-for-eee-broken-modes.patch b/queue-4.9/net-phy-use-boolean-dt-properties-for-eee-broken-modes.patch new file mode 100644 index 00000000000..9f73807ac46 --- /dev/null +++ b/queue-4.9/net-phy-use-boolean-dt-properties-for-eee-broken-modes.patch @@ -0,0 +1,64 @@ +From foo@baz Mon Jul 3 11:00:33 CEST 2017 +From: jbrunet +Date: Mon, 19 Dec 2016 16:05:37 +0100 +Subject: net: phy: use boolean dt properties for eee broken modes + +From: jbrunet + + +[ Upstream commit 57f3986231bb2c69a55ccab1d2b30a00818027ac ] + +The patches regarding eee-broken-modes was merged before all people +involved could find an agreement on the best way to move forward. + +While we agreed on having a DT property to mark particular modes as broken, +the value used for eee-broken-modes mapped the phy register in very direct +way. Because of this, the concern is that it could be used to implement +configuration policies instead of describing a broken HW. + +In the end, having a boolean property for each mode seems to be preferred +over one bit field value mapping the register (too) directly. + +Cc: Florian Fainelli +Signed-off-by: Jerome Brunet +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/phy/phy_device.c | 18 +++++++++++++++--- + 1 file changed, 15 insertions(+), 3 deletions(-) + +--- a/drivers/net/phy/phy_device.c ++++ b/drivers/net/phy/phy_device.c +@@ -1633,7 +1633,7 @@ static void of_set_phy_supported(struct + static void of_set_phy_eee_broken(struct phy_device *phydev) + { + struct device_node *node = phydev->mdio.dev.of_node; +- u32 broken; ++ u32 broken = 0; + + if (!IS_ENABLED(CONFIG_OF_MDIO)) + return; +@@ -1641,8 +1641,20 @@ static void of_set_phy_eee_broken(struct + if (!node) + return; + +- if (!of_property_read_u32(node, "eee-broken-modes", &broken)) +- phydev->eee_broken_modes = broken; ++ if (of_property_read_bool(node, "eee-broken-100tx")) ++ broken |= MDIO_EEE_100TX; ++ if (of_property_read_bool(node, "eee-broken-1000t")) ++ broken |= MDIO_EEE_1000T; ++ if (of_property_read_bool(node, "eee-broken-10gt")) ++ broken |= MDIO_EEE_10GT; ++ if (of_property_read_bool(node, "eee-broken-1000kx")) ++ broken |= MDIO_EEE_1000KX; ++ if (of_property_read_bool(node, "eee-broken-10gkx4")) ++ broken |= MDIO_EEE_10GKX4; ++ if (of_property_read_bool(node, "eee-broken-10gkr")) ++ broken |= MDIO_EEE_10GKR; ++ ++ phydev->eee_broken_modes = broken; + } + + /** diff --git a/queue-4.9/series b/queue-4.9/series index fcf64b99e49..158505890e4 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -48,3 +48,12 @@ l2tp-fix-duplicate-session-creation.patch l2tp-hold-session-while-sending-creation-notifications.patch l2tp-take-a-reference-on-sessions-used-in-genetlink-handlers.patch mm-numa-avoid-waiting-on-freed-migrated-pages.patch +sparc64-handle-pio-mem-non-resumable-errors.patch +sparc64-zero-pages-on-allocation-for-mondo-and-error-queues.patch +net-ethtool-add-support-for-2500baset-and-5000baset-link-modes.patch +net-phy-add-an-option-to-disable-eee-advertisement.patch +dt-bindings-net-add-eee-capability-constants.patch +net-phy-fix-sign-type-error-in-genphy_config_eee_advert.patch +net-phy-use-boolean-dt-properties-for-eee-broken-modes.patch +dt-bindings-net-use-boolean-dt-properties-for-eee-broken-modes.patch +arm64-dts-meson-gxbb-odroidc2-fix-gbe-tx-link-breakage.patch diff --git a/queue-4.9/sparc64-handle-pio-mem-non-resumable-errors.patch b/queue-4.9/sparc64-handle-pio-mem-non-resumable-errors.patch new file mode 100644 index 00000000000..d361e6f8d63 --- /dev/null +++ b/queue-4.9/sparc64-handle-pio-mem-non-resumable-errors.patch @@ -0,0 +1,112 @@ +From foo@baz Mon Jul 3 11:00:33 CEST 2017 +From: "Liam R. Howlett" +Date: Tue, 23 May 2017 21:54:10 -0400 +Subject: sparc64: Handle PIO & MEM non-resumable errors. + +From: "Liam R. Howlett" + + +[ Upstream commit 047487241ff59374fded8c477f21453681f5995c ] + +User processes trying to access an invalid memory address via PIO will +receive a SIGBUS signal instead of causing a panic. Memory errors will +receive a SIGKILL since a SIGBUS may result in a coredump which may +attempt to repeat the faulting access. + +Signed-off-by: Liam R. Howlett +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + arch/sparc/kernel/traps_64.c | 73 +++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 73 insertions(+) + +--- a/arch/sparc/kernel/traps_64.c ++++ b/arch/sparc/kernel/traps_64.c +@@ -2051,6 +2051,73 @@ void sun4v_resum_overflow(struct pt_regs + atomic_inc(&sun4v_resum_oflow_cnt); + } + ++/* Given a set of registers, get the virtual addressi that was being accessed ++ * by the faulting instructions at tpc. ++ */ ++static unsigned long sun4v_get_vaddr(struct pt_regs *regs) ++{ ++ unsigned int insn; ++ ++ if (!copy_from_user(&insn, (void __user *)regs->tpc, 4)) { ++ return compute_effective_address(regs, insn, ++ (insn >> 25) & 0x1f); ++ } ++ return 0; ++} ++ ++/* Attempt to handle non-resumable errors generated from userspace. ++ * Returns true if the signal was handled, false otherwise. ++ */ ++bool sun4v_nonresum_error_user_handled(struct pt_regs *regs, ++ struct sun4v_error_entry *ent) { ++ ++ unsigned int attrs = ent->err_attrs; ++ ++ if (attrs & SUN4V_ERR_ATTRS_MEMORY) { ++ unsigned long addr = ent->err_raddr; ++ siginfo_t info; ++ ++ if (addr == ~(u64)0) { ++ /* This seems highly unlikely to ever occur */ ++ pr_emerg("SUN4V NON-RECOVERABLE ERROR: Memory error detected in unknown location!\n"); ++ } else { ++ unsigned long page_cnt = DIV_ROUND_UP(ent->err_size, ++ PAGE_SIZE); ++ ++ /* Break the unfortunate news. */ ++ pr_emerg("SUN4V NON-RECOVERABLE ERROR: Memory failed at %016lX\n", ++ addr); ++ pr_emerg("SUN4V NON-RECOVERABLE ERROR: Claiming %lu ages.\n", ++ page_cnt); ++ ++ while (page_cnt-- > 0) { ++ if (pfn_valid(addr >> PAGE_SHIFT)) ++ get_page(pfn_to_page(addr >> PAGE_SHIFT)); ++ addr += PAGE_SIZE; ++ } ++ } ++ info.si_signo = SIGKILL; ++ info.si_errno = 0; ++ info.si_trapno = 0; ++ force_sig_info(info.si_signo, &info, current); ++ ++ return true; ++ } ++ if (attrs & SUN4V_ERR_ATTRS_PIO) { ++ siginfo_t info; ++ ++ info.si_signo = SIGBUS; ++ info.si_code = BUS_ADRERR; ++ info.si_addr = (void __user *)sun4v_get_vaddr(regs); ++ force_sig_info(info.si_signo, &info, current); ++ ++ return true; ++ } ++ ++ /* Default to doing nothing */ ++ return false; ++} ++ + /* We run with %pil set to PIL_NORMAL_MAX and PSTATE_IE enabled in %pstate. + * Log the event, clear the first word of the entry, and die. + */ +@@ -2075,6 +2142,12 @@ void sun4v_nonresum_error(struct pt_regs + + put_cpu(); + ++ if (!(regs->tstate & TSTATE_PRIV) && ++ sun4v_nonresum_error_user_handled(regs, &local_copy)) { ++ /* DON'T PANIC: This userspace error was handled. */ ++ return; ++ } ++ + #ifdef CONFIG_PCI + /* Check for the special PCI poke sequence. */ + if (pci_poke_in_progress && pci_poke_cpu == cpu) { diff --git a/queue-4.9/sparc64-zero-pages-on-allocation-for-mondo-and-error-queues.patch b/queue-4.9/sparc64-zero-pages-on-allocation-for-mondo-and-error-queues.patch new file mode 100644 index 00000000000..923230ab31f --- /dev/null +++ b/queue-4.9/sparc64-zero-pages-on-allocation-for-mondo-and-error-queues.patch @@ -0,0 +1,40 @@ +From foo@baz Mon Jul 3 11:00:33 CEST 2017 +From: "Liam R. Howlett" +Date: Tue, 23 May 2017 21:54:11 -0400 +Subject: sparc64: Zero pages on allocation for mondo and error queues. + +From: "Liam R. Howlett" + + +[ Upstream commit 7a7dc961a28b965a0d0303c2e989df17b411708b ] + +Error queues use a non-zero first word to detect if the queues are full. +Using pages that have not been zeroed may result in false positive +overflow events. These queues are set up once during boot so zeroing +all mondo and error queue pages is safe. + +Note that the false positive overflow does not always occur because the +page allocation for these queues is so early in the boot cycle that +higher number CPUs get fresh pages. It is only when traps are serviced +with lower number CPUs who were given already used pages that this issue +is exposed. + +Signed-off-by: Liam R. Howlett +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + arch/sparc/kernel/irq_64.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/sparc/kernel/irq_64.c ++++ b/arch/sparc/kernel/irq_64.c +@@ -1021,7 +1021,7 @@ static void __init alloc_one_queue(unsig + unsigned long order = get_order(size); + unsigned long p; + +- p = __get_free_pages(GFP_KERNEL, order); ++ p = __get_free_pages(GFP_KERNEL | __GFP_ZERO, order); + if (!p) { + prom_printf("SUN4V: Error, cannot allocate queue.\n"); + prom_halt();