--- /dev/null
+From f919dde0772a894c693a1eeabc77df69d6a9b937 Mon Sep 17 00:00:00 2001
+From: Mika Westerberg <mika.westerberg@linux.intel.com>
+Date: Thu, 11 Jan 2018 15:55:50 +0300
+Subject: ahci: Add Intel Cannon Lake PCH-H PCI ID
+
+From: Mika Westerberg <mika.westerberg@linux.intel.com>
+
+commit f919dde0772a894c693a1eeabc77df69d6a9b937 upstream.
+
+Add Intel Cannon Lake PCH-H PCI ID to the list of supported controllers.
+
+Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/ata/ahci.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/ata/ahci.c
++++ b/drivers/ata/ahci.c
+@@ -394,6 +394,7 @@ static const struct pci_device_id ahci_p
+ { PCI_VDEVICE(INTEL, 0xa206), board_ahci }, /* Lewisburg RAID*/
+ { PCI_VDEVICE(INTEL, 0xa252), board_ahci }, /* Lewisburg RAID*/
+ { PCI_VDEVICE(INTEL, 0xa256), board_ahci }, /* Lewisburg RAID*/
++ { PCI_VDEVICE(INTEL, 0xa356), board_ahci }, /* Cannon Lake PCH-H RAID */
+ { PCI_VDEVICE(INTEL, 0x0f22), board_ahci_mobile }, /* Bay Trail AHCI */
+ { PCI_VDEVICE(INTEL, 0x0f23), board_ahci_mobile }, /* Bay Trail AHCI */
+ { PCI_VDEVICE(INTEL, 0x22a3), board_ahci_mobile }, /* Cherry Tr. AHCI */
--- /dev/null
+From 998008b779e424bd7513c434d0ab9c1268459009 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+Date: Wed, 6 Dec 2017 16:41:09 +0100
+Subject: ahci: Add PCI ids for Intel Bay Trail, Cherry Trail and Apollo Lake AHCI
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+commit 998008b779e424bd7513c434d0ab9c1268459009 upstream.
+
+Add PCI ids for Intel Bay Trail, Cherry Trail and Apollo Lake AHCI
+SATA controllers. This commit is a preparation patch for allowing a
+different default sata link powermanagement policy for mobile chipsets.
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/ata/ahci.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/ata/ahci.c
++++ b/drivers/ata/ahci.c
+@@ -386,6 +386,10 @@ static const struct pci_device_id ahci_p
+ { PCI_VDEVICE(INTEL, 0xa206), board_ahci }, /* Lewisburg RAID*/
+ { PCI_VDEVICE(INTEL, 0xa252), board_ahci }, /* Lewisburg RAID*/
+ { PCI_VDEVICE(INTEL, 0xa256), board_ahci }, /* Lewisburg RAID*/
++ { PCI_VDEVICE(INTEL, 0x0f22), board_ahci }, /* Bay Trail AHCI */
++ { PCI_VDEVICE(INTEL, 0x0f23), board_ahci }, /* Bay Trail AHCI */
++ { PCI_VDEVICE(INTEL, 0x22a3), board_ahci }, /* Cherry Trail AHCI */
++ { PCI_VDEVICE(INTEL, 0x5ae3), board_ahci }, /* Apollo Lake AHCI */
+
+ /* JMicron 360/1/3/5/6, match class to avoid IDE function */
+ { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
--- /dev/null
+From ebb82e3c79d2a956366d0848304a53648bd6350b Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+Date: Mon, 11 Dec 2017 17:52:16 +0100
+Subject: ahci: Allow setting a default LPM policy for mobile chipsets
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+commit ebb82e3c79d2a956366d0848304a53648bd6350b upstream.
+
+On many laptops setting a different LPM policy then unknown /
+max_performance can lead to power-savings of 1.0 - 1.5 Watts (when idle).
+
+Modern ultrabooks idle around 6W (at 50% screen brightness), 1.0 - 1.5W
+is a significant chunk of this.
+
+There are some performance / latency costs to enabling LPM by default,
+so it is desirable to make it possible to set a different LPM policy
+for mobile / laptop variants of chipsets / "South Bridges" vs their
+desktop / server counterparts. Also enabling LPM by default is not
+entirely without risk of regressions. At least min_power is known to
+cause issues with some disks, including some reports of data corruption.
+
+This commits adds a new ahci.mobile_lpm_policy kernel cmdline option,
+which defaults to a new SATA_MOBILE_LPM_POLICY Kconfig option so that
+Linux distributions can choose to set a LPM policy for mobile chipsets
+by default.
+
+The reason to have both a kernel cmdline option and a Kconfig default
+value for it, is to allow easy overriding of the default to allow
+trouble-shooting without needing to rebuild the kernel.
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/ata/Kconfig | 19 ++++++++++
+ drivers/ata/ahci.c | 97 ++++++++++++++++++++++++++++++----------------------
+ drivers/ata/ahci.h | 3 +
+ 3 files changed, 78 insertions(+), 41 deletions(-)
+
+--- a/drivers/ata/Kconfig
++++ b/drivers/ata/Kconfig
+@@ -92,6 +92,25 @@ config SATA_AHCI
+
+ If unsure, say N.
+
++config SATA_MOBILE_LPM_POLICY
++ int "Default SATA Link Power Management policy for mobile chipsets"
++ range 0 4
++ default 0
++ depends on SATA_AHCI
++ help
++ Select the Default SATA Link Power Management (LPM) policy to use
++ for mobile / laptop variants of chipsets / "South Bridges".
++
++ The value set has the following meanings:
++ 0 => Keep firmware settings
++ 1 => Maximum performance
++ 2 => Medium power
++ 3 => Medium power with Device Initiated PM enabled
++ 4 => Minimum power
++
++ Note "Minimum power" is known to cause issues, including disk
++ corruption, with some disks and should not be used.
++
+ config SATA_AHCI_PLATFORM
+ tristate "Platform AHCI SATA support"
+ help
+--- a/drivers/ata/ahci.c
++++ b/drivers/ata/ahci.c
+@@ -65,6 +65,7 @@ enum board_ids {
+ /* board IDs by feature in alphabetical order */
+ board_ahci,
+ board_ahci_ign_iferr,
++ board_ahci_mobile,
+ board_ahci_nomsi,
+ board_ahci_noncq,
+ board_ahci_nosntf,
+@@ -140,6 +141,13 @@ static const struct ata_port_info ahci_p
+ .udma_mask = ATA_UDMA6,
+ .port_ops = &ahci_ops,
+ },
++ [board_ahci_mobile] = {
++ AHCI_HFLAGS (AHCI_HFLAG_IS_MOBILE),
++ .flags = AHCI_FLAG_COMMON,
++ .pio_mask = ATA_PIO4,
++ .udma_mask = ATA_UDMA6,
++ .port_ops = &ahci_ops,
++ },
+ [board_ahci_nomsi] = {
+ AHCI_HFLAGS (AHCI_HFLAG_NO_MSI),
+ .flags = AHCI_FLAG_COMMON,
+@@ -252,13 +260,13 @@ static const struct pci_device_id ahci_p
+ { PCI_VDEVICE(INTEL, 0x2924), board_ahci }, /* ICH9 */
+ { PCI_VDEVICE(INTEL, 0x2925), board_ahci }, /* ICH9 */
+ { PCI_VDEVICE(INTEL, 0x2927), board_ahci }, /* ICH9 */
+- { PCI_VDEVICE(INTEL, 0x2929), board_ahci }, /* ICH9M */
+- { PCI_VDEVICE(INTEL, 0x292a), board_ahci }, /* ICH9M */
+- { PCI_VDEVICE(INTEL, 0x292b), board_ahci }, /* ICH9M */
+- { PCI_VDEVICE(INTEL, 0x292c), board_ahci }, /* ICH9M */
+- { PCI_VDEVICE(INTEL, 0x292f), board_ahci }, /* ICH9M */
++ { PCI_VDEVICE(INTEL, 0x2929), board_ahci_mobile }, /* ICH9M */
++ { PCI_VDEVICE(INTEL, 0x292a), board_ahci_mobile }, /* ICH9M */
++ { PCI_VDEVICE(INTEL, 0x292b), board_ahci_mobile }, /* ICH9M */
++ { PCI_VDEVICE(INTEL, 0x292c), board_ahci_mobile }, /* ICH9M */
++ { PCI_VDEVICE(INTEL, 0x292f), board_ahci_mobile }, /* ICH9M */
+ { PCI_VDEVICE(INTEL, 0x294d), board_ahci }, /* ICH9 */
+- { PCI_VDEVICE(INTEL, 0x294e), board_ahci }, /* ICH9M */
++ { PCI_VDEVICE(INTEL, 0x294e), board_ahci_mobile }, /* ICH9M */
+ { PCI_VDEVICE(INTEL, 0x502a), board_ahci }, /* Tolapai */
+ { PCI_VDEVICE(INTEL, 0x502b), board_ahci }, /* Tolapai */
+ { PCI_VDEVICE(INTEL, 0x3a05), board_ahci }, /* ICH10 */
+@@ -268,9 +276,9 @@ static const struct pci_device_id ahci_p
+ { PCI_VDEVICE(INTEL, 0x3b23), board_ahci }, /* PCH AHCI */
+ { PCI_VDEVICE(INTEL, 0x3b24), board_ahci }, /* PCH RAID */
+ { PCI_VDEVICE(INTEL, 0x3b25), board_ahci }, /* PCH RAID */
+- { PCI_VDEVICE(INTEL, 0x3b29), board_ahci }, /* PCH M AHCI */
++ { PCI_VDEVICE(INTEL, 0x3b29), board_ahci_mobile }, /* PCH M AHCI */
+ { PCI_VDEVICE(INTEL, 0x3b2b), board_ahci }, /* PCH RAID */
+- { PCI_VDEVICE(INTEL, 0x3b2c), board_ahci }, /* PCH M RAID */
++ { PCI_VDEVICE(INTEL, 0x3b2c), board_ahci_mobile }, /* PCH M RAID */
+ { PCI_VDEVICE(INTEL, 0x3b2f), board_ahci }, /* PCH AHCI */
+ { PCI_VDEVICE(INTEL, 0x19b0), board_ahci }, /* DNV AHCI */
+ { PCI_VDEVICE(INTEL, 0x19b1), board_ahci }, /* DNV AHCI */
+@@ -293,9 +301,9 @@ static const struct pci_device_id ahci_p
+ { PCI_VDEVICE(INTEL, 0x19cE), board_ahci }, /* DNV AHCI */
+ { PCI_VDEVICE(INTEL, 0x19cF), board_ahci }, /* DNV AHCI */
+ { PCI_VDEVICE(INTEL, 0x1c02), board_ahci }, /* CPT AHCI */
+- { PCI_VDEVICE(INTEL, 0x1c03), board_ahci }, /* CPT M AHCI */
++ { PCI_VDEVICE(INTEL, 0x1c03), board_ahci_mobile }, /* CPT M AHCI */
+ { PCI_VDEVICE(INTEL, 0x1c04), board_ahci }, /* CPT RAID */
+- { PCI_VDEVICE(INTEL, 0x1c05), board_ahci }, /* CPT M RAID */
++ { PCI_VDEVICE(INTEL, 0x1c05), board_ahci_mobile }, /* CPT M RAID */
+ { PCI_VDEVICE(INTEL, 0x1c06), board_ahci }, /* CPT RAID */
+ { PCI_VDEVICE(INTEL, 0x1c07), board_ahci }, /* CPT RAID */
+ { PCI_VDEVICE(INTEL, 0x1d02), board_ahci }, /* PBG AHCI */
+@@ -304,28 +312,28 @@ static const struct pci_device_id ahci_p
+ { PCI_VDEVICE(INTEL, 0x2826), board_ahci }, /* PBG RAID */
+ { PCI_VDEVICE(INTEL, 0x2323), board_ahci }, /* DH89xxCC AHCI */
+ { PCI_VDEVICE(INTEL, 0x1e02), board_ahci }, /* Panther Point AHCI */
+- { PCI_VDEVICE(INTEL, 0x1e03), board_ahci }, /* Panther Point M AHCI */
++ { PCI_VDEVICE(INTEL, 0x1e03), board_ahci_mobile }, /* Panther M AHCI */
+ { PCI_VDEVICE(INTEL, 0x1e04), board_ahci }, /* Panther Point RAID */
+ { PCI_VDEVICE(INTEL, 0x1e05), board_ahci }, /* Panther Point RAID */
+ { PCI_VDEVICE(INTEL, 0x1e06), board_ahci }, /* Panther Point RAID */
+- { PCI_VDEVICE(INTEL, 0x1e07), board_ahci }, /* Panther Point M RAID */
++ { PCI_VDEVICE(INTEL, 0x1e07), board_ahci_mobile }, /* Panther M RAID */
+ { PCI_VDEVICE(INTEL, 0x1e0e), board_ahci }, /* Panther Point RAID */
+ { PCI_VDEVICE(INTEL, 0x8c02), board_ahci }, /* Lynx Point AHCI */
+- { PCI_VDEVICE(INTEL, 0x8c03), board_ahci }, /* Lynx Point M AHCI */
++ { PCI_VDEVICE(INTEL, 0x8c03), board_ahci_mobile }, /* Lynx M AHCI */
+ { PCI_VDEVICE(INTEL, 0x8c04), board_ahci }, /* Lynx Point RAID */
+- { PCI_VDEVICE(INTEL, 0x8c05), board_ahci }, /* Lynx Point M RAID */
++ { PCI_VDEVICE(INTEL, 0x8c05), board_ahci_mobile }, /* Lynx M RAID */
+ { PCI_VDEVICE(INTEL, 0x8c06), board_ahci }, /* Lynx Point RAID */
+- { PCI_VDEVICE(INTEL, 0x8c07), board_ahci }, /* Lynx Point M RAID */
++ { PCI_VDEVICE(INTEL, 0x8c07), board_ahci_mobile }, /* Lynx M RAID */
+ { PCI_VDEVICE(INTEL, 0x8c0e), board_ahci }, /* Lynx Point RAID */
+- { PCI_VDEVICE(INTEL, 0x8c0f), board_ahci }, /* Lynx Point M RAID */
+- { PCI_VDEVICE(INTEL, 0x9c02), board_ahci }, /* Lynx Point-LP AHCI */
+- { PCI_VDEVICE(INTEL, 0x9c03), board_ahci }, /* Lynx Point-LP AHCI */
+- { PCI_VDEVICE(INTEL, 0x9c04), board_ahci }, /* Lynx Point-LP RAID */
+- { PCI_VDEVICE(INTEL, 0x9c05), board_ahci }, /* Lynx Point-LP RAID */
+- { PCI_VDEVICE(INTEL, 0x9c06), board_ahci }, /* Lynx Point-LP RAID */
+- { PCI_VDEVICE(INTEL, 0x9c07), board_ahci }, /* Lynx Point-LP RAID */
+- { PCI_VDEVICE(INTEL, 0x9c0e), board_ahci }, /* Lynx Point-LP RAID */
+- { PCI_VDEVICE(INTEL, 0x9c0f), board_ahci }, /* Lynx Point-LP RAID */
++ { PCI_VDEVICE(INTEL, 0x8c0f), board_ahci_mobile }, /* Lynx M RAID */
++ { PCI_VDEVICE(INTEL, 0x9c02), board_ahci_mobile }, /* Lynx LP AHCI */
++ { PCI_VDEVICE(INTEL, 0x9c03), board_ahci_mobile }, /* Lynx LP AHCI */
++ { PCI_VDEVICE(INTEL, 0x9c04), board_ahci_mobile }, /* Lynx LP RAID */
++ { PCI_VDEVICE(INTEL, 0x9c05), board_ahci_mobile }, /* Lynx LP RAID */
++ { PCI_VDEVICE(INTEL, 0x9c06), board_ahci_mobile }, /* Lynx LP RAID */
++ { PCI_VDEVICE(INTEL, 0x9c07), board_ahci_mobile }, /* Lynx LP RAID */
++ { PCI_VDEVICE(INTEL, 0x9c0e), board_ahci_mobile }, /* Lynx LP RAID */
++ { PCI_VDEVICE(INTEL, 0x9c0f), board_ahci_mobile }, /* Lynx LP RAID */
+ { PCI_VDEVICE(INTEL, 0x1f22), board_ahci }, /* Avoton AHCI */
+ { PCI_VDEVICE(INTEL, 0x1f23), board_ahci }, /* Avoton AHCI */
+ { PCI_VDEVICE(INTEL, 0x1f24), board_ahci }, /* Avoton RAID */
+@@ -353,26 +361,26 @@ static const struct pci_device_id ahci_p
+ { PCI_VDEVICE(INTEL, 0x8d66), board_ahci }, /* Wellsburg RAID */
+ { PCI_VDEVICE(INTEL, 0x8d6e), board_ahci }, /* Wellsburg RAID */
+ { PCI_VDEVICE(INTEL, 0x23a3), board_ahci }, /* Coleto Creek AHCI */
+- { PCI_VDEVICE(INTEL, 0x9c83), board_ahci }, /* Wildcat Point-LP AHCI */
+- { PCI_VDEVICE(INTEL, 0x9c85), board_ahci }, /* Wildcat Point-LP RAID */
+- { PCI_VDEVICE(INTEL, 0x9c87), board_ahci }, /* Wildcat Point-LP RAID */
+- { PCI_VDEVICE(INTEL, 0x9c8f), board_ahci }, /* Wildcat Point-LP RAID */
++ { PCI_VDEVICE(INTEL, 0x9c83), board_ahci_mobile }, /* Wildcat LP AHCI */
++ { PCI_VDEVICE(INTEL, 0x9c85), board_ahci_mobile }, /* Wildcat LP RAID */
++ { PCI_VDEVICE(INTEL, 0x9c87), board_ahci_mobile }, /* Wildcat LP RAID */
++ { PCI_VDEVICE(INTEL, 0x9c8f), board_ahci_mobile }, /* Wildcat LP RAID */
+ { PCI_VDEVICE(INTEL, 0x8c82), board_ahci }, /* 9 Series AHCI */
+- { PCI_VDEVICE(INTEL, 0x8c83), board_ahci }, /* 9 Series M AHCI */
++ { PCI_VDEVICE(INTEL, 0x8c83), board_ahci_mobile }, /* 9 Series M AHCI */
+ { PCI_VDEVICE(INTEL, 0x8c84), board_ahci }, /* 9 Series RAID */
+- { PCI_VDEVICE(INTEL, 0x8c85), board_ahci }, /* 9 Series M RAID */
++ { PCI_VDEVICE(INTEL, 0x8c85), board_ahci_mobile }, /* 9 Series M RAID */
+ { PCI_VDEVICE(INTEL, 0x8c86), board_ahci }, /* 9 Series RAID */
+- { PCI_VDEVICE(INTEL, 0x8c87), board_ahci }, /* 9 Series M RAID */
++ { PCI_VDEVICE(INTEL, 0x8c87), board_ahci_mobile }, /* 9 Series M RAID */
+ { PCI_VDEVICE(INTEL, 0x8c8e), board_ahci }, /* 9 Series RAID */
+- { PCI_VDEVICE(INTEL, 0x8c8f), board_ahci }, /* 9 Series M RAID */
+- { PCI_VDEVICE(INTEL, 0x9d03), board_ahci }, /* Sunrise Point-LP AHCI */
+- { PCI_VDEVICE(INTEL, 0x9d05), board_ahci }, /* Sunrise Point-LP RAID */
+- { PCI_VDEVICE(INTEL, 0x9d07), board_ahci }, /* Sunrise Point-LP RAID */
++ { PCI_VDEVICE(INTEL, 0x8c8f), board_ahci_mobile }, /* 9 Series M RAID */
++ { PCI_VDEVICE(INTEL, 0x9d03), board_ahci_mobile }, /* Sunrise LP AHCI */
++ { PCI_VDEVICE(INTEL, 0x9d05), board_ahci_mobile }, /* Sunrise LP RAID */
++ { PCI_VDEVICE(INTEL, 0x9d07), board_ahci_mobile }, /* Sunrise LP RAID */
+ { PCI_VDEVICE(INTEL, 0xa102), board_ahci }, /* Sunrise Point-H AHCI */
+- { PCI_VDEVICE(INTEL, 0xa103), board_ahci }, /* Sunrise Point-H M AHCI */
++ { PCI_VDEVICE(INTEL, 0xa103), board_ahci_mobile }, /* Sunrise M AHCI */
+ { PCI_VDEVICE(INTEL, 0xa105), board_ahci }, /* Sunrise Point-H RAID */
+ { PCI_VDEVICE(INTEL, 0xa106), board_ahci }, /* Sunrise Point-H RAID */
+- { PCI_VDEVICE(INTEL, 0xa107), board_ahci }, /* Sunrise Point-H M RAID */
++ { PCI_VDEVICE(INTEL, 0xa107), board_ahci_mobile }, /* Sunrise M RAID */
+ { PCI_VDEVICE(INTEL, 0xa10f), board_ahci }, /* Sunrise Point-H RAID */
+ { PCI_VDEVICE(INTEL, 0x2822), board_ahci }, /* Lewisburg RAID*/
+ { PCI_VDEVICE(INTEL, 0x2823), board_ahci }, /* Lewisburg AHCI*/
+@@ -386,10 +394,10 @@ static const struct pci_device_id ahci_p
+ { PCI_VDEVICE(INTEL, 0xa206), board_ahci }, /* Lewisburg RAID*/
+ { PCI_VDEVICE(INTEL, 0xa252), board_ahci }, /* Lewisburg RAID*/
+ { PCI_VDEVICE(INTEL, 0xa256), board_ahci }, /* Lewisburg RAID*/
+- { PCI_VDEVICE(INTEL, 0x0f22), board_ahci }, /* Bay Trail AHCI */
+- { PCI_VDEVICE(INTEL, 0x0f23), board_ahci }, /* Bay Trail AHCI */
+- { PCI_VDEVICE(INTEL, 0x22a3), board_ahci }, /* Cherry Trail AHCI */
+- { PCI_VDEVICE(INTEL, 0x5ae3), board_ahci }, /* Apollo Lake AHCI */
++ { PCI_VDEVICE(INTEL, 0x0f22), board_ahci_mobile }, /* Bay Trail AHCI */
++ { PCI_VDEVICE(INTEL, 0x0f23), board_ahci_mobile }, /* Bay Trail AHCI */
++ { PCI_VDEVICE(INTEL, 0x22a3), board_ahci_mobile }, /* Cherry Tr. AHCI */
++ { PCI_VDEVICE(INTEL, 0x5ae3), board_ahci_mobile }, /* ApolloLake AHCI */
+
+ /* JMicron 360/1/3/5/6, match class to avoid IDE function */
+ { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+@@ -597,6 +605,9 @@ static int marvell_enable = 1;
+ module_param(marvell_enable, int, 0644);
+ MODULE_PARM_DESC(marvell_enable, "Marvell SATA via AHCI (1 = enabled)");
+
++static int mobile_lpm_policy = CONFIG_SATA_MOBILE_LPM_POLICY;
++module_param(mobile_lpm_policy, int, 0644);
++MODULE_PARM_DESC(mobile_lpm_policy, "Default LPM policy for mobile chipsets");
+
+ static void ahci_pci_save_initial_config(struct pci_dev *pdev,
+ struct ahci_host_priv *hpriv)
+@@ -1732,6 +1743,10 @@ static int ahci_init_one(struct pci_dev
+ if (ap->flags & ATA_FLAG_EM)
+ ap->em_message_type = hpriv->em_msg_type;
+
++ if ((hpriv->flags & AHCI_HFLAG_IS_MOBILE) &&
++ mobile_lpm_policy >= ATA_LPM_UNKNOWN &&
++ mobile_lpm_policy <= ATA_LPM_MIN_POWER)
++ ap->target_lpm_policy = mobile_lpm_policy;
+
+ /* disabled/not-implemented port */
+ if (!(hpriv->port_map & (1 << i)))
+--- a/drivers/ata/ahci.h
++++ b/drivers/ata/ahci.h
+@@ -251,6 +251,9 @@ enum {
+ AHCI_HFLAG_YES_ALPM = (1 << 23), /* force ALPM cap on */
+ AHCI_HFLAG_NO_WRITE_TO_RO = (1 << 24), /* don't write to read
+ only registers */
++ AHCI_HFLAG_IS_MOBILE = (1 << 25), /* mobile chipset, use
++ SATA_MOBILE_LPM_POLICY
++ as default lpm_policy */
+
+ /* ap->flags bits */
+
--- /dev/null
+From ca1b4974bd237f2373b0e980b11957aac3499b56 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+Date: Wed, 6 Dec 2017 16:41:08 +0100
+Subject: ahci: Annotate PCI ids for mobile Intel chipsets as such
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+commit ca1b4974bd237f2373b0e980b11957aac3499b56 upstream.
+
+Intel uses different SATA PCI ids for the Desktop and Mobile SKUs of their
+chipsets. For older models the comment describing which chipset the PCI id
+is for, aksi indicates when we're dealing with a mobile SKU. Extend the
+comments for recent chipsets to also indicate mobile SKUs.
+
+The information this commit adds comes from Intel's chipset datasheets.
+
+This commit is a preparation patch for allowing a different default
+sata link powermanagement policy for mobile chipsets.
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/ata/ahci.c | 32 ++++++++++++++++----------------
+ 1 file changed, 16 insertions(+), 16 deletions(-)
+
+--- a/drivers/ata/ahci.c
++++ b/drivers/ata/ahci.c
+@@ -268,9 +268,9 @@ static const struct pci_device_id ahci_p
+ { PCI_VDEVICE(INTEL, 0x3b23), board_ahci }, /* PCH AHCI */
+ { PCI_VDEVICE(INTEL, 0x3b24), board_ahci }, /* PCH RAID */
+ { PCI_VDEVICE(INTEL, 0x3b25), board_ahci }, /* PCH RAID */
+- { PCI_VDEVICE(INTEL, 0x3b29), board_ahci }, /* PCH AHCI */
++ { PCI_VDEVICE(INTEL, 0x3b29), board_ahci }, /* PCH M AHCI */
+ { PCI_VDEVICE(INTEL, 0x3b2b), board_ahci }, /* PCH RAID */
+- { PCI_VDEVICE(INTEL, 0x3b2c), board_ahci }, /* PCH RAID */
++ { PCI_VDEVICE(INTEL, 0x3b2c), board_ahci }, /* PCH M RAID */
+ { PCI_VDEVICE(INTEL, 0x3b2f), board_ahci }, /* PCH AHCI */
+ { PCI_VDEVICE(INTEL, 0x19b0), board_ahci }, /* DNV AHCI */
+ { PCI_VDEVICE(INTEL, 0x19b1), board_ahci }, /* DNV AHCI */
+@@ -293,9 +293,9 @@ static const struct pci_device_id ahci_p
+ { PCI_VDEVICE(INTEL, 0x19cE), board_ahci }, /* DNV AHCI */
+ { PCI_VDEVICE(INTEL, 0x19cF), board_ahci }, /* DNV AHCI */
+ { PCI_VDEVICE(INTEL, 0x1c02), board_ahci }, /* CPT AHCI */
+- { PCI_VDEVICE(INTEL, 0x1c03), board_ahci }, /* CPT AHCI */
++ { PCI_VDEVICE(INTEL, 0x1c03), board_ahci }, /* CPT M AHCI */
+ { PCI_VDEVICE(INTEL, 0x1c04), board_ahci }, /* CPT RAID */
+- { PCI_VDEVICE(INTEL, 0x1c05), board_ahci }, /* CPT RAID */
++ { PCI_VDEVICE(INTEL, 0x1c05), board_ahci }, /* CPT M RAID */
+ { PCI_VDEVICE(INTEL, 0x1c06), board_ahci }, /* CPT RAID */
+ { PCI_VDEVICE(INTEL, 0x1c07), board_ahci }, /* CPT RAID */
+ { PCI_VDEVICE(INTEL, 0x1d02), board_ahci }, /* PBG AHCI */
+@@ -304,20 +304,20 @@ static const struct pci_device_id ahci_p
+ { PCI_VDEVICE(INTEL, 0x2826), board_ahci }, /* PBG RAID */
+ { PCI_VDEVICE(INTEL, 0x2323), board_ahci }, /* DH89xxCC AHCI */
+ { PCI_VDEVICE(INTEL, 0x1e02), board_ahci }, /* Panther Point AHCI */
+- { PCI_VDEVICE(INTEL, 0x1e03), board_ahci }, /* Panther Point AHCI */
++ { PCI_VDEVICE(INTEL, 0x1e03), board_ahci }, /* Panther Point M AHCI */
+ { PCI_VDEVICE(INTEL, 0x1e04), board_ahci }, /* Panther Point RAID */
+ { PCI_VDEVICE(INTEL, 0x1e05), board_ahci }, /* Panther Point RAID */
+ { PCI_VDEVICE(INTEL, 0x1e06), board_ahci }, /* Panther Point RAID */
+- { PCI_VDEVICE(INTEL, 0x1e07), board_ahci }, /* Panther Point RAID */
++ { PCI_VDEVICE(INTEL, 0x1e07), board_ahci }, /* Panther Point M RAID */
+ { PCI_VDEVICE(INTEL, 0x1e0e), board_ahci }, /* Panther Point RAID */
+ { PCI_VDEVICE(INTEL, 0x8c02), board_ahci }, /* Lynx Point AHCI */
+- { PCI_VDEVICE(INTEL, 0x8c03), board_ahci }, /* Lynx Point AHCI */
++ { PCI_VDEVICE(INTEL, 0x8c03), board_ahci }, /* Lynx Point M AHCI */
+ { PCI_VDEVICE(INTEL, 0x8c04), board_ahci }, /* Lynx Point RAID */
+- { PCI_VDEVICE(INTEL, 0x8c05), board_ahci }, /* Lynx Point RAID */
++ { PCI_VDEVICE(INTEL, 0x8c05), board_ahci }, /* Lynx Point M RAID */
+ { PCI_VDEVICE(INTEL, 0x8c06), board_ahci }, /* Lynx Point RAID */
+- { PCI_VDEVICE(INTEL, 0x8c07), board_ahci }, /* Lynx Point RAID */
++ { PCI_VDEVICE(INTEL, 0x8c07), board_ahci }, /* Lynx Point M RAID */
+ { PCI_VDEVICE(INTEL, 0x8c0e), board_ahci }, /* Lynx Point RAID */
+- { PCI_VDEVICE(INTEL, 0x8c0f), board_ahci }, /* Lynx Point RAID */
++ { PCI_VDEVICE(INTEL, 0x8c0f), board_ahci }, /* Lynx Point M RAID */
+ { PCI_VDEVICE(INTEL, 0x9c02), board_ahci }, /* Lynx Point-LP AHCI */
+ { PCI_VDEVICE(INTEL, 0x9c03), board_ahci }, /* Lynx Point-LP AHCI */
+ { PCI_VDEVICE(INTEL, 0x9c04), board_ahci }, /* Lynx Point-LP RAID */
+@@ -358,21 +358,21 @@ static const struct pci_device_id ahci_p
+ { PCI_VDEVICE(INTEL, 0x9c87), board_ahci }, /* Wildcat Point-LP RAID */
+ { PCI_VDEVICE(INTEL, 0x9c8f), board_ahci }, /* Wildcat Point-LP RAID */
+ { PCI_VDEVICE(INTEL, 0x8c82), board_ahci }, /* 9 Series AHCI */
+- { PCI_VDEVICE(INTEL, 0x8c83), board_ahci }, /* 9 Series AHCI */
++ { PCI_VDEVICE(INTEL, 0x8c83), board_ahci }, /* 9 Series M AHCI */
+ { PCI_VDEVICE(INTEL, 0x8c84), board_ahci }, /* 9 Series RAID */
+- { PCI_VDEVICE(INTEL, 0x8c85), board_ahci }, /* 9 Series RAID */
++ { PCI_VDEVICE(INTEL, 0x8c85), board_ahci }, /* 9 Series M RAID */
+ { PCI_VDEVICE(INTEL, 0x8c86), board_ahci }, /* 9 Series RAID */
+- { PCI_VDEVICE(INTEL, 0x8c87), board_ahci }, /* 9 Series RAID */
++ { PCI_VDEVICE(INTEL, 0x8c87), board_ahci }, /* 9 Series M RAID */
+ { PCI_VDEVICE(INTEL, 0x8c8e), board_ahci }, /* 9 Series RAID */
+- { PCI_VDEVICE(INTEL, 0x8c8f), board_ahci }, /* 9 Series RAID */
++ { PCI_VDEVICE(INTEL, 0x8c8f), board_ahci }, /* 9 Series M RAID */
+ { PCI_VDEVICE(INTEL, 0x9d03), board_ahci }, /* Sunrise Point-LP AHCI */
+ { PCI_VDEVICE(INTEL, 0x9d05), board_ahci }, /* Sunrise Point-LP RAID */
+ { PCI_VDEVICE(INTEL, 0x9d07), board_ahci }, /* Sunrise Point-LP RAID */
+ { PCI_VDEVICE(INTEL, 0xa102), board_ahci }, /* Sunrise Point-H AHCI */
+- { PCI_VDEVICE(INTEL, 0xa103), board_ahci }, /* Sunrise Point-H AHCI */
++ { PCI_VDEVICE(INTEL, 0xa103), board_ahci }, /* Sunrise Point-H M AHCI */
+ { PCI_VDEVICE(INTEL, 0xa105), board_ahci }, /* Sunrise Point-H RAID */
+ { PCI_VDEVICE(INTEL, 0xa106), board_ahci }, /* Sunrise Point-H RAID */
+- { PCI_VDEVICE(INTEL, 0xa107), board_ahci }, /* Sunrise Point-H RAID */
++ { PCI_VDEVICE(INTEL, 0xa107), board_ahci }, /* Sunrise Point-H M RAID */
+ { PCI_VDEVICE(INTEL, 0xa10f), board_ahci }, /* Sunrise Point-H RAID */
+ { PCI_VDEVICE(INTEL, 0x2822), board_ahci }, /* Lewisburg RAID*/
+ { PCI_VDEVICE(INTEL, 0x2823), board_ahci }, /* Lewisburg AHCI*/
--- /dev/null
+From ba87977a49913129962af8ac35b0e13e0fa4382d Mon Sep 17 00:00:00 2001
+From: Ivan Vecera <ivecera@redhat.com>
+Date: Fri, 19 Jan 2018 09:18:54 +0100
+Subject: kernfs: fix regression in kernfs_fop_write caused by wrong type
+
+From: Ivan Vecera <ivecera@redhat.com>
+
+commit ba87977a49913129962af8ac35b0e13e0fa4382d upstream.
+
+Commit b7ce40cff0b9 ("kernfs: cache atomic_write_len in
+kernfs_open_file") changes type of local variable 'len' from ssize_t
+to size_t. This change caused that the *ppos value is updated also
+when the previous write callback failed.
+
+Mentioned snippet:
+...
+len = ops->write(...); <- return value can be negative
+...
+if (len > 0) <- true here in this case
+ *ppos += len;
+...
+
+Fixes: b7ce40cff0b9 ("kernfs: cache atomic_write_len in kernfs_open_file")
+Acked-by: Tejun Heo <tj@kernel.org>
+Signed-off-by: Ivan Vecera <ivecera@redhat.com>
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/kernfs/file.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/kernfs/file.c
++++ b/fs/kernfs/file.c
+@@ -275,7 +275,7 @@ static ssize_t kernfs_fop_write(struct f
+ {
+ struct kernfs_open_file *of = kernfs_of(file);
+ const struct kernfs_ops *ops;
+- size_t len;
++ ssize_t len;
+ char *buf;
+
+ if (of->atomic_write_len) {
--- /dev/null
+From 9e343e87d2c4c707ef8fae2844864d4dde3a2d13 Mon Sep 17 00:00:00 2001
+From: Arnd Bergmann <arnd@arndb.de>
+Date: Wed, 11 Oct 2017 15:54:10 +0200
+Subject: mtd: cfi: convert inline functions to macros
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+commit 9e343e87d2c4c707ef8fae2844864d4dde3a2d13 upstream.
+
+The map_word_() functions, dating back to linux-2.6.8, try to perform
+bitwise operations on a 'map_word' structure. This may have worked
+with compilers that were current then (gcc-3.4 or earlier), but end
+up being rather inefficient on any version I could try now (gcc-4.4 or
+higher). Specifically we hit a problem analyzed in gcc PR81715 where we
+fail to reuse the stack space for local variables.
+
+This can be seen immediately in the stack consumption for
+cfi_staa_erase_varsize() and other functions that (with CONFIG_KASAN)
+can be up to 2200 bytes. Changing the inline functions into macros brings
+this down to 1280 bytes. Without KASAN, the same problem exists, but
+the stack consumption is lower to start with, my patch shrinks it from
+920 to 496 bytes on with arm-linux-gnueabi-gcc-5.4, and saves around
+1KB in .text size for cfi_cmdset_0020.c, as it avoids copying map_word
+structures for each call to one of these helpers.
+
+With the latest gcc-8 snapshot, the problem is fixed in upstream gcc,
+but nobody uses that yet, so we should still work around it in mainline
+kernels and probably backport the workaround to stable kernels as well.
+We had a couple of other functions that suffered from the same gcc bug,
+and all of those had a simpler workaround involving dummy variables
+in the inline function. Unfortunately that did not work here, the
+macro hack was the best I could come up with.
+
+It would also be helpful to have someone to a little performance testing
+on the patch, to see how much it helps in terms of CPU utilitzation.
+
+Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81715
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Acked-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/linux/mtd/map.h | 130 ++++++++++++++++++++++--------------------------
+ 1 file changed, 61 insertions(+), 69 deletions(-)
+
+--- a/include/linux/mtd/map.h
++++ b/include/linux/mtd/map.h
+@@ -270,75 +270,67 @@ void map_destroy(struct mtd_info *mtd);
+ #define INVALIDATE_CACHED_RANGE(map, from, size) \
+ do { if (map->inval_cache) map->inval_cache(map, from, size); } while (0)
+
+-
+-static inline int map_word_equal(struct map_info *map, map_word val1, map_word val2)
+-{
+- int i;
+-
+- for (i = 0; i < map_words(map); i++) {
+- if (val1.x[i] != val2.x[i])
+- return 0;
+- }
+-
+- return 1;
+-}
+-
+-static inline map_word map_word_and(struct map_info *map, map_word val1, map_word val2)
+-{
+- map_word r;
+- int i;
+-
+- for (i = 0; i < map_words(map); i++)
+- r.x[i] = val1.x[i] & val2.x[i];
+-
+- return r;
+-}
+-
+-static inline map_word map_word_clr(struct map_info *map, map_word val1, map_word val2)
+-{
+- map_word r;
+- int i;
+-
+- for (i = 0; i < map_words(map); i++)
+- r.x[i] = val1.x[i] & ~val2.x[i];
+-
+- return r;
+-}
+-
+-static inline map_word map_word_or(struct map_info *map, map_word val1, map_word val2)
+-{
+- map_word r;
+- int i;
+-
+- for (i = 0; i < map_words(map); i++)
+- r.x[i] = val1.x[i] | val2.x[i];
+-
+- return r;
+-}
+-
+-static inline int map_word_andequal(struct map_info *map, map_word val1, map_word val2, map_word val3)
+-{
+- int i;
+-
+- for (i = 0; i < map_words(map); i++) {
+- if ((val1.x[i] & val2.x[i]) != val3.x[i])
+- return 0;
+- }
+-
+- return 1;
+-}
+-
+-static inline int map_word_bitsset(struct map_info *map, map_word val1, map_word val2)
+-{
+- int i;
+-
+- for (i = 0; i < map_words(map); i++) {
+- if (val1.x[i] & val2.x[i])
+- return 1;
+- }
+-
+- return 0;
+-}
++#define map_word_equal(map, val1, val2) \
++({ \
++ int i, ret = 1; \
++ for (i = 0; i < map_words(map); i++) \
++ if ((val1).x[i] != (val2).x[i]) { \
++ ret = 0; \
++ break; \
++ } \
++ ret; \
++})
++
++#define map_word_and(map, val1, val2) \
++({ \
++ map_word r; \
++ int i; \
++ for (i = 0; i < map_words(map); i++) \
++ r.x[i] = (val1).x[i] & (val2).x[i]; \
++ r; \
++})
++
++#define map_word_clr(map, val1, val2) \
++({ \
++ map_word r; \
++ int i; \
++ for (i = 0; i < map_words(map); i++) \
++ r.x[i] = (val1).x[i] & ~(val2).x[i]; \
++ r; \
++})
++
++#define map_word_or(map, val1, val2) \
++({ \
++ map_word r; \
++ int i; \
++ for (i = 0; i < map_words(map); i++) \
++ r.x[i] = (val1).x[i] | (val2).x[i]; \
++ r; \
++})
++
++#define map_word_andequal(map, val1, val2, val3) \
++({ \
++ int i, ret = 1; \
++ for (i = 0; i < map_words(map); i++) { \
++ if (((val1).x[i] & (val2).x[i]) != (val2).x[i]) { \
++ ret = 0; \
++ break; \
++ } \
++ } \
++ ret; \
++})
++
++#define map_word_bitsset(map, val1, val2) \
++({ \
++ int i, ret = 0; \
++ for (i = 0; i < map_words(map); i++) { \
++ if ((val1).x[i] & (val2).x[i]) { \
++ ret = 1; \
++ break; \
++ } \
++ } \
++ ret; \
++})
+
+ static inline map_word map_word_load(struct map_info *map, const void *ptr)
+ {
--- /dev/null
+From f953f0f89663c39f08f4baaa8a4a881401b65654 Mon Sep 17 00:00:00 2001
+From: Kamal Dasu <kdasu.kdev@gmail.com>
+Date: Mon, 8 Jan 2018 15:36:48 -0500
+Subject: mtd: nand: brcmnand: Disable prefetch by default
+
+From: Kamal Dasu <kdasu.kdev@gmail.com>
+
+commit f953f0f89663c39f08f4baaa8a4a881401b65654 upstream.
+
+Brcm nand controller prefetch feature needs to be disabled
+by default. Enabling affects performance on random reads as
+well as dma reads.
+
+Signed-off-by: Kamal Dasu <kdasu.kdev@gmail.com>
+Fixes: 27c5b17cd1b1 ("mtd: nand: add NAND driver "library" for Broadcom STB NAND controller")
+Acked-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/mtd/nand/brcmnand/brcmnand.c | 13 +++----------
+ 1 file changed, 3 insertions(+), 10 deletions(-)
+
+--- a/drivers/mtd/nand/brcmnand/brcmnand.c
++++ b/drivers/mtd/nand/brcmnand/brcmnand.c
+@@ -2193,16 +2193,9 @@ static int brcmnand_setup_dev(struct brc
+ if (ctrl->nand_version >= 0x0702)
+ tmp |= ACC_CONTROL_RD_ERASED;
+ tmp &= ~ACC_CONTROL_FAST_PGM_RDIN;
+- if (ctrl->features & BRCMNAND_HAS_PREFETCH) {
+- /*
+- * FIXME: Flash DMA + prefetch may see spurious erased-page ECC
+- * errors
+- */
+- if (has_flash_dma(ctrl))
+- tmp &= ~ACC_CONTROL_PREFETCH;
+- else
+- tmp |= ACC_CONTROL_PREFETCH;
+- }
++ if (ctrl->features & BRCMNAND_HAS_PREFETCH)
++ tmp &= ~ACC_CONTROL_PREFETCH;
++
+ nand_writereg(ctrl, offs, tmp);
+
+ return 0;
--- /dev/null
+From 87e89ce8d0d14f573c068c61bec2117751fb5103 Mon Sep 17 00:00:00 2001
+From: Miquel Raynal <miquel.raynal@free-electrons.com>
+Date: Fri, 12 Jan 2018 10:13:36 +0100
+Subject: mtd: nand: Fix nand_do_read_oob() return value
+
+From: Miquel Raynal <miquel.raynal@free-electrons.com>
+
+commit 87e89ce8d0d14f573c068c61bec2117751fb5103 upstream.
+
+Starting from commit 041e4575f034 ("mtd: nand: handle ECC errors in
+OOB"), nand_do_read_oob() (from the NAND core) did return 0 or a
+negative error, and the MTD layer expected it.
+
+However, the trend for the NAND layer is now to return an error or a
+positive number of bitflips. Deciding which status to return to the user
+belongs to the MTD layer.
+
+Commit e47f68587b82 ("mtd: check for max_bitflips in mtd_read_oob()")
+brought this logic to the mtd_read_oob() function while the return value
+coming from nand_do_read_oob() (called by the ->_read_oob() hook) was
+left unchanged.
+
+Fixes: e47f68587b82 ("mtd: check for max_bitflips in mtd_read_oob()")
+Signed-off-by: Miquel Raynal <miquel.raynal@free-electrons.com>
+Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/mtd/nand/nand_base.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/drivers/mtd/nand/nand_base.c
++++ b/drivers/mtd/nand/nand_base.c
+@@ -2199,6 +2199,7 @@ EXPORT_SYMBOL(nand_write_oob_syndrome);
+ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
+ struct mtd_oob_ops *ops)
+ {
++ unsigned int max_bitflips = 0;
+ int page, realpage, chipnr;
+ struct nand_chip *chip = mtd_to_nand(mtd);
+ struct mtd_ecc_stats stats;
+@@ -2256,6 +2257,8 @@ static int nand_do_read_oob(struct mtd_i
+ nand_wait_ready(mtd);
+ }
+
++ max_bitflips = max_t(unsigned int, max_bitflips, ret);
++
+ readlen -= len;
+ if (!readlen)
+ break;
+@@ -2281,7 +2284,7 @@ static int nand_do_read_oob(struct mtd_i
+ if (mtd->ecc_stats.failed - stats.failed)
+ return -EBADMSG;
+
+- return mtd->ecc_stats.corrected - stats.corrected ? -EUCLEAN : 0;
++ return max_bitflips;
+ }
+
+ /**
--- /dev/null
+From f4c6cd1a7f2275d5bc0e494b21fff26f8dde80f0 Mon Sep 17 00:00:00 2001
+From: Miquel Raynal <miquel.raynal@free-electrons.com>
+Date: Wed, 24 Jan 2018 23:49:31 +0100
+Subject: mtd: nand: sunxi: Fix ECC strength choice
+
+From: Miquel Raynal <miquel.raynal@free-electrons.com>
+
+commit f4c6cd1a7f2275d5bc0e494b21fff26f8dde80f0 upstream.
+
+When the requested ECC strength does not exactly match the strengths
+supported by the ECC engine, the driver is selecting the closest
+strength meeting the 'selected_strength > requested_strength'
+constraint. Fix the fact that, in this particular case, ecc->strength
+value was not updated to match the 'selected_strength'.
+
+For instance, one can encounter this issue when no ECC requirement is
+filled in the device tree while the NAND chip minimum requirement is not
+a strength/step_size combo natively supported by the ECC engine.
+
+Fixes: 1fef62c1423b ("mtd: nand: add sunxi NAND flash controller support")
+Suggested-by: Boris Brezillon <boris.brezillon@free-electrons.com>
+Signed-off-by: Miquel Raynal <miquel.raynal@free-electrons.com>
+Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/mtd/nand/sunxi_nand.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+--- a/drivers/mtd/nand/sunxi_nand.c
++++ b/drivers/mtd/nand/sunxi_nand.c
+@@ -1853,8 +1853,14 @@ static int sunxi_nand_hw_common_ecc_ctrl
+
+ /* Add ECC info retrieval from DT */
+ for (i = 0; i < ARRAY_SIZE(strengths); i++) {
+- if (ecc->strength <= strengths[i])
++ if (ecc->strength <= strengths[i]) {
++ /*
++ * Update ecc->strength value with the actual strength
++ * that will be used by the ECC engine.
++ */
++ ecc->strength = strengths[i];
+ break;
++ }
+ }
+
+ if (i >= ARRAY_SIZE(strengths)) {
--- /dev/null
+From 7f1bda447c9bd48b415acedba6b830f61591601f Mon Sep 17 00:00:00 2001
+From: Trond Myklebust <trond.myklebust@primarydata.com>
+Date: Mon, 18 Dec 2017 14:39:13 -0500
+Subject: NFS: Add a cond_resched() to nfs_commit_release_pages()
+
+From: Trond Myklebust <trond.myklebust@primarydata.com>
+
+commit 7f1bda447c9bd48b415acedba6b830f61591601f upstream.
+
+The commit list can get very large, and so we need a cond_resched()
+in nfs_commit_release_pages() in order to ensure we don't hog the CPU
+for excessive periods of time.
+
+Reported-by: Mike Galbraith <efault@gmx.de>
+Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/nfs/write.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/fs/nfs/write.c
++++ b/fs/nfs/write.c
+@@ -1837,6 +1837,8 @@ static void nfs_commit_release_pages(str
+ set_bit(NFS_CONTEXT_RESEND_WRITES, &req->wb_context->flags);
+ next:
+ nfs_unlock_and_release_request(req);
++ /* Latency breaker */
++ cond_resched();
+ }
+ nfss = NFS_SERVER(data->inode);
+ if (atomic_long_read(&nfss->writeback) < NFS_CONGESTION_OFF_THRESH)
--- /dev/null
+From 1b8d97b0a837beaf48a8449955b52c650a7114b4 Mon Sep 17 00:00:00 2001
+From: "J. Bruce Fields" <bfields@redhat.com>
+Date: Tue, 16 Jan 2018 10:08:00 -0500
+Subject: NFS: commit direct writes even if they fail partially
+
+From: J. Bruce Fields <bfields@redhat.com>
+
+commit 1b8d97b0a837beaf48a8449955b52c650a7114b4 upstream.
+
+If some of the WRITE calls making up an O_DIRECT write syscall fail,
+we neglect to commit, even if some of the WRITEs succeed.
+
+We also depend on the commit code to free the reference count on the
+nfs_page taken in the "if (request_commit)" case at the end of
+nfs_direct_write_completion(). The problem was originally noticed
+because ENOSPC's encountered partway through a write would result in a
+closed file being sillyrenamed when it should have been unlinked.
+
+Signed-off-by: J. Bruce Fields <bfields@redhat.com>
+Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/nfs/direct.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+--- a/fs/nfs/direct.c
++++ b/fs/nfs/direct.c
+@@ -775,10 +775,8 @@ static void nfs_direct_write_completion(
+
+ spin_lock(&dreq->lock);
+
+- if (test_bit(NFS_IOHDR_ERROR, &hdr->flags)) {
+- dreq->flags = 0;
++ if (test_bit(NFS_IOHDR_ERROR, &hdr->flags))
+ dreq->error = hdr->error;
+- }
+ if (dreq->error == 0) {
+ nfs_direct_good_bytes(dreq, hdr);
+ if (nfs_write_need_commit(hdr)) {
--- /dev/null
+From e231c6879cfd44e4fffd384bb6dd7d313249a523 Mon Sep 17 00:00:00 2001
+From: Trond Myklebust <trond.myklebust@primarydata.com>
+Date: Sun, 28 Jan 2018 09:29:41 -0500
+Subject: NFS: Fix a race between mmap() and O_DIRECT
+
+From: Trond Myklebust <trond.myklebust@primarydata.com>
+
+commit e231c6879cfd44e4fffd384bb6dd7d313249a523 upstream.
+
+When locking the file in order to do O_DIRECT on it, we must unmap
+any mmapped ranges on the pagecache so that we can flush out the
+dirty data.
+
+Fixes: a5864c999de67 ("NFS: Do not serialise O_DIRECT reads and writes")
+Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/nfs/io.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/nfs/io.c
++++ b/fs/nfs/io.c
+@@ -99,7 +99,7 @@ static void nfs_block_buffered(struct nf
+ {
+ if (!test_bit(NFS_INO_ODIRECT, &nfsi->flags)) {
+ set_bit(NFS_INO_ODIRECT, &nfsi->flags);
+- nfs_wb_all(inode);
++ nfs_sync_mapping(inode->i_mapping);
+ }
+ }
+
--- /dev/null
+From 8634ef5e05311f32d7f2aee06f6b27a8834a3bd6 Mon Sep 17 00:00:00 2001
+From: Trond Myklebust <trond.myklebust@primarydata.com>
+Date: Sat, 6 Jan 2018 09:53:49 -0500
+Subject: NFS: Fix nfsstat breakage due to LOOKUPP
+
+From: Trond Myklebust <trond.myklebust@primarydata.com>
+
+commit 8634ef5e05311f32d7f2aee06f6b27a8834a3bd6 upstream.
+
+The LOOKUPP operation was inserted into the nfs4_procedures array
+rather than being appended, which put /proc/net/rpc/nfs out of
+whack, and broke the nfsstat utility.
+Fix by moving the LOOKUPP operation to the end of the array, and
+by ensuring that it keeps the same length whether or not NFSV4.1
+and NFSv4.2 are compiled in.
+
+Fixes: 5b5faaf6df734 ("nfs4: add NFSv4 LOOKUPP handlers")
+Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/nfs/nfs4xdr.c | 64 ++++++++++++++++++++++++++++++---------------------
+ include/linux/nfs4.h | 12 ++++++---
+ 2 files changed, 46 insertions(+), 30 deletions(-)
+
+--- a/fs/nfs/nfs4xdr.c
++++ b/fs/nfs/nfs4xdr.c
+@@ -7678,6 +7678,22 @@ nfs4_stat_to_errno(int stat)
+ .p_name = #proc, \
+ }
+
++#if defined(CONFIG_NFS_V4_1)
++#define PROC41(proc, argtype, restype) \
++ PROC(proc, argtype, restype)
++#else
++#define PROC41(proc, argtype, restype) \
++ STUB(proc)
++#endif
++
++#if defined(CONFIG_NFS_V4_2)
++#define PROC42(proc, argtype, restype) \
++ PROC(proc, argtype, restype)
++#else
++#define PROC42(proc, argtype, restype) \
++ STUB(proc)
++#endif
++
+ const struct rpc_procinfo nfs4_procedures[] = {
+ PROC(READ, enc_read, dec_read),
+ PROC(WRITE, enc_write, dec_write),
+@@ -7698,7 +7714,6 @@ const struct rpc_procinfo nfs4_procedure
+ PROC(ACCESS, enc_access, dec_access),
+ PROC(GETATTR, enc_getattr, dec_getattr),
+ PROC(LOOKUP, enc_lookup, dec_lookup),
+- PROC(LOOKUPP, enc_lookupp, dec_lookupp),
+ PROC(LOOKUP_ROOT, enc_lookup_root, dec_lookup_root),
+ PROC(REMOVE, enc_remove, dec_remove),
+ PROC(RENAME, enc_rename, dec_rename),
+@@ -7717,33 +7732,30 @@ const struct rpc_procinfo nfs4_procedure
+ PROC(RELEASE_LOCKOWNER, enc_release_lockowner, dec_release_lockowner),
+ PROC(SECINFO, enc_secinfo, dec_secinfo),
+ PROC(FSID_PRESENT, enc_fsid_present, dec_fsid_present),
+-#if defined(CONFIG_NFS_V4_1)
+- PROC(EXCHANGE_ID, enc_exchange_id, dec_exchange_id),
+- PROC(CREATE_SESSION, enc_create_session, dec_create_session),
+- PROC(DESTROY_SESSION, enc_destroy_session, dec_destroy_session),
+- PROC(SEQUENCE, enc_sequence, dec_sequence),
+- PROC(GET_LEASE_TIME, enc_get_lease_time, dec_get_lease_time),
+- PROC(RECLAIM_COMPLETE, enc_reclaim_complete, dec_reclaim_complete),
+- PROC(GETDEVICEINFO, enc_getdeviceinfo, dec_getdeviceinfo),
+- PROC(LAYOUTGET, enc_layoutget, dec_layoutget),
+- PROC(LAYOUTCOMMIT, enc_layoutcommit, dec_layoutcommit),
+- PROC(LAYOUTRETURN, enc_layoutreturn, dec_layoutreturn),
+- PROC(SECINFO_NO_NAME, enc_secinfo_no_name, dec_secinfo_no_name),
+- PROC(TEST_STATEID, enc_test_stateid, dec_test_stateid),
+- PROC(FREE_STATEID, enc_free_stateid, dec_free_stateid),
++ PROC41(EXCHANGE_ID, enc_exchange_id, dec_exchange_id),
++ PROC41(CREATE_SESSION, enc_create_session, dec_create_session),
++ PROC41(DESTROY_SESSION, enc_destroy_session, dec_destroy_session),
++ PROC41(SEQUENCE, enc_sequence, dec_sequence),
++ PROC41(GET_LEASE_TIME, enc_get_lease_time, dec_get_lease_time),
++ PROC41(RECLAIM_COMPLETE,enc_reclaim_complete, dec_reclaim_complete),
++ PROC41(GETDEVICEINFO, enc_getdeviceinfo, dec_getdeviceinfo),
++ PROC41(LAYOUTGET, enc_layoutget, dec_layoutget),
++ PROC41(LAYOUTCOMMIT, enc_layoutcommit, dec_layoutcommit),
++ PROC41(LAYOUTRETURN, enc_layoutreturn, dec_layoutreturn),
++ PROC41(SECINFO_NO_NAME, enc_secinfo_no_name, dec_secinfo_no_name),
++ PROC41(TEST_STATEID, enc_test_stateid, dec_test_stateid),
++ PROC41(FREE_STATEID, enc_free_stateid, dec_free_stateid),
+ STUB(GETDEVICELIST),
+- PROC(BIND_CONN_TO_SESSION,
++ PROC41(BIND_CONN_TO_SESSION,
+ enc_bind_conn_to_session, dec_bind_conn_to_session),
+- PROC(DESTROY_CLIENTID, enc_destroy_clientid, dec_destroy_clientid),
+-#endif /* CONFIG_NFS_V4_1 */
+-#ifdef CONFIG_NFS_V4_2
+- PROC(SEEK, enc_seek, dec_seek),
+- PROC(ALLOCATE, enc_allocate, dec_allocate),
+- PROC(DEALLOCATE, enc_deallocate, dec_deallocate),
+- PROC(LAYOUTSTATS, enc_layoutstats, dec_layoutstats),
+- PROC(CLONE, enc_clone, dec_clone),
+- PROC(COPY, enc_copy, dec_copy),
+-#endif /* CONFIG_NFS_V4_2 */
++ PROC41(DESTROY_CLIENTID,enc_destroy_clientid, dec_destroy_clientid),
++ PROC42(SEEK, enc_seek, dec_seek),
++ PROC42(ALLOCATE, enc_allocate, dec_allocate),
++ PROC42(DEALLOCATE, enc_deallocate, dec_deallocate),
++ PROC42(LAYOUTSTATS, enc_layoutstats, dec_layoutstats),
++ PROC42(CLONE, enc_clone, dec_clone),
++ PROC42(COPY, enc_copy, dec_copy),
++ PROC(LOOKUPP, enc_lookupp, dec_lookupp),
+ };
+
+ static unsigned int nfs_version4_counts[ARRAY_SIZE(nfs4_procedures)];
+--- a/include/linux/nfs4.h
++++ b/include/linux/nfs4.h
+@@ -457,7 +457,12 @@ enum lock_type4 {
+
+ #define NFS4_DEBUG 1
+
+-/* Index of predefined Linux client operations */
++/*
++ * Index of predefined Linux client operations
++ *
++ * To ensure that /proc/net/rpc/nfs remains correctly ordered, please
++ * append only to this enum when adding new client operations.
++ */
+
+ enum {
+ NFSPROC4_CLNT_NULL = 0, /* Unused */
+@@ -480,7 +485,6 @@ enum {
+ NFSPROC4_CLNT_ACCESS,
+ NFSPROC4_CLNT_GETATTR,
+ NFSPROC4_CLNT_LOOKUP,
+- NFSPROC4_CLNT_LOOKUPP,
+ NFSPROC4_CLNT_LOOKUP_ROOT,
+ NFSPROC4_CLNT_REMOVE,
+ NFSPROC4_CLNT_RENAME,
+@@ -500,7 +504,6 @@ enum {
+ NFSPROC4_CLNT_SECINFO,
+ NFSPROC4_CLNT_FSID_PRESENT,
+
+- /* nfs41 */
+ NFSPROC4_CLNT_EXCHANGE_ID,
+ NFSPROC4_CLNT_CREATE_SESSION,
+ NFSPROC4_CLNT_DESTROY_SESSION,
+@@ -518,13 +521,14 @@ enum {
+ NFSPROC4_CLNT_BIND_CONN_TO_SESSION,
+ NFSPROC4_CLNT_DESTROY_CLIENTID,
+
+- /* nfs42 */
+ NFSPROC4_CLNT_SEEK,
+ NFSPROC4_CLNT_ALLOCATE,
+ NFSPROC4_CLNT_DEALLOCATE,
+ NFSPROC4_CLNT_LAYOUTSTATS,
+ NFSPROC4_CLNT_CLONE,
+ NFSPROC4_CLNT_COPY,
++
++ NFSPROC4_CLNT_LOOKUPP,
+ };
+
+ /* nfs41 types */
--- /dev/null
+From ba4a76f703ab7eb72941fdaac848502073d6e9ee Mon Sep 17 00:00:00 2001
+From: Scott Mayhew <smayhew@redhat.com>
+Date: Fri, 15 Dec 2017 16:12:32 -0500
+Subject: nfs/pnfs: fix nfs_direct_req ref leak when i/o falls back to the mds
+
+From: Scott Mayhew <smayhew@redhat.com>
+
+commit ba4a76f703ab7eb72941fdaac848502073d6e9ee upstream.
+
+Currently when falling back to doing I/O through the MDS (via
+pnfs_{read|write}_through_mds), the client frees the nfs_pgio_header
+without releasing the reference taken on the dreq
+via pnfs_generic_pg_{read|write}pages -> nfs_pgheader_init ->
+nfs_direct_pgio_init. It then takes another reference on the dreq via
+nfs_generic_pg_pgios -> nfs_pgheader_init -> nfs_direct_pgio_init and
+as a result the requester will become stuck in inode_dio_wait. Once
+that happens, other processes accessing the inode will become stuck as
+well.
+
+Ensure that pnfs_read_through_mds() and pnfs_write_through_mds() clean
+up correctly by calling hdr->completion_ops->completion() instead of
+calling hdr->release() directly.
+
+This can be reproduced (sometimes) by performing "storage failover
+takeover" commands on NetApp filer while doing direct I/O from a client.
+
+This can also be reproduced using SystemTap to simulate a failure while
+doing direct I/O from a client (from Dave Wysochanski
+<dwysocha@redhat.com>):
+
+stap -v -g -e 'probe module("nfs_layout_nfsv41_files").function("nfs4_fl_prepare_ds").return { $return=NULL; exit(); }'
+
+Suggested-by: Trond Myklebust <trond.myklebust@primarydata.com>
+Signed-off-by: Scott Mayhew <smayhew@redhat.com>
+Fixes: 1ca018d28d ("pNFS: Fix a memory leak when attempted pnfs fails")
+Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/nfs/pnfs.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/fs/nfs/pnfs.c
++++ b/fs/nfs/pnfs.c
+@@ -2255,7 +2255,7 @@ pnfs_write_through_mds(struct nfs_pageio
+ nfs_pageio_reset_write_mds(desc);
+ mirror->pg_recoalesce = 1;
+ }
+- hdr->release(hdr);
++ hdr->completion_ops->completion(hdr);
+ }
+
+ static enum pnfs_try_status
+@@ -2378,7 +2378,7 @@ pnfs_read_through_mds(struct nfs_pageio_
+ nfs_pageio_reset_read_mds(desc);
+ mirror->pg_recoalesce = 1;
+ }
+- hdr->release(hdr);
++ hdr->completion_ops->completion(hdr);
+ }
+
+ /*
--- /dev/null
+From 49686cbbb3ebafe42e63868222f269d8053ead00 Mon Sep 17 00:00:00 2001
+From: Eric Biggers <ebiggers@google.com>
+Date: Fri, 19 Jan 2018 15:15:34 -0800
+Subject: NFS: reject request for id_legacy key without auxdata
+
+From: Eric Biggers <ebiggers@google.com>
+
+commit 49686cbbb3ebafe42e63868222f269d8053ead00 upstream.
+
+nfs_idmap_legacy_upcall() is supposed to be called with 'aux' pointing
+to a 'struct idmap', via the call to request_key_with_auxdata() in
+nfs_idmap_request_key().
+
+However it can also be reached via the request_key() system call in
+which case 'aux' will be NULL, causing a NULL pointer dereference in
+nfs_idmap_prepare_pipe_upcall(), assuming that the key description is
+valid enough to get that far.
+
+Fix this by making nfs_idmap_legacy_upcall() negate the key if no
+auxdata is provided.
+
+As usual, this bug was found by syzkaller. A simple reproducer using
+the command-line keyctl program is:
+
+ keyctl request2 id_legacy uid:0 '' @s
+
+Fixes: 57e62324e469 ("NFS: Store the legacy idmapper result in the keyring")
+Reported-by: syzbot+5dfdbcf7b3eb5912abbb@syzkaller.appspotmail.com
+Signed-off-by: Eric Biggers <ebiggers@google.com>
+Signed-off-by: Trond Myklebust <trondmy@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/nfs/nfs4idmap.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/fs/nfs/nfs4idmap.c
++++ b/fs/nfs/nfs4idmap.c
+@@ -568,9 +568,13 @@ static int nfs_idmap_legacy_upcall(struc
+ struct idmap_msg *im;
+ struct idmap *idmap = (struct idmap *)aux;
+ struct key *key = cons->key;
+- int ret = -ENOMEM;
++ int ret = -ENOKEY;
++
++ if (!aux)
++ goto out1;
+
+ /* msg and im are freed in idmap_pipe_destroy_msg */
++ ret = -ENOMEM;
+ data = kzalloc(sizeof(*data), GFP_KERNEL);
+ if (!data)
+ goto out1;
--- /dev/null
+From 7ff4cff637aa0bd2abbd81f53b2a6206c50afd95 Mon Sep 17 00:00:00 2001
+From: Tigran Mkrtchyan <tigran.mkrtchyan@desy.de>
+Date: Tue, 16 Jan 2018 22:38:50 +0100
+Subject: nfs41: do not return ENOMEM on LAYOUTUNAVAILABLE
+
+From: Tigran Mkrtchyan <tigran.mkrtchyan@desy.de>
+
+commit 7ff4cff637aa0bd2abbd81f53b2a6206c50afd95 upstream.
+
+A pNFS server may return LAYOUTUNAVAILABLE error on LAYOUTGET for files
+which don't have any layout. In this situation pnfs_update_layout
+currently returns NULL. As this NULL is converted into ENOMEM, IO
+requests fails instead of falling back to MDS.
+
+Do not return ENOMEM on LAYOUTUNAVAILABLE and let client retry through
+MDS.
+
+Fixes 8d40b0f14846f. I will suggest to backport this fix to affected
+stable branches.
+
+Signed-off-by: Tigran Mkrtchyan <tigran.mkrtchyan@desy.de>
+[trondmy: Use IS_ERR_OR_NULL()]
+Fixes: 8d40b0f14846 ("NFS filelayout:call GETDEVICEINFO after...")
+Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/nfs/filelayout/filelayout.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+--- a/fs/nfs/filelayout/filelayout.c
++++ b/fs/nfs/filelayout/filelayout.c
+@@ -895,9 +895,7 @@ fl_pnfs_update_layout(struct inode *ino,
+
+ lseg = pnfs_update_layout(ino, ctx, pos, count, iomode, strict_iomode,
+ gfp_flags);
+- if (!lseg)
+- lseg = ERR_PTR(-ENOMEM);
+- if (IS_ERR(lseg))
++ if (IS_ERR_OR_NULL(lseg))
+ goto out;
+
+ lo = NFS_I(ino)->layout;
--- /dev/null
+From 4f1764172a0aa7395d12b96cae640ca1438c5085 Mon Sep 17 00:00:00 2001
+From: Trond Myklebust <trond.myklebust@primarydata.com>
+Date: Fri, 12 Jan 2018 17:42:30 -0500
+Subject: nfsd: Detect unhashed stids in nfsd4_verify_open_stid()
+
+From: Trond Myklebust <trond.myklebust@primarydata.com>
+
+commit 4f1764172a0aa7395d12b96cae640ca1438c5085 upstream.
+
+The state of the stid is guaranteed by 2 locks:
+- The nfs4_client 'cl_lock' spinlock
+- The nfs4_ol_stateid 'st_mutex' mutex
+
+so it is quite possible for the stid to be unhashed after lookup,
+but before calling nfsd4_lock_ol_stateid(). So we do need to check
+for a zero value for 'sc_type' in nfsd4_verify_open_stid().
+
+Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
+Tested-by: Checuk Lever <chuck.lever@oracle.com>
+Fixes: 659aefb68eca "nfsd: Ensure we don't recognise lock stateids..."
+Signed-off-by: J. Bruce Fields <bfields@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/nfsd/nfs4state.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/fs/nfsd/nfs4state.c
++++ b/fs/nfsd/nfs4state.c
+@@ -3590,6 +3590,7 @@ nfsd4_verify_open_stid(struct nfs4_stid
+ switch (s->sc_type) {
+ default:
+ break;
++ case 0:
+ case NFS4_CLOSED_STID:
+ case NFS4_CLOSED_DELEG_STID:
+ ret = nfserr_bad_stateid;
arm-arm64-smccc-implement-smccc-v1.1-inline-primitive.patch
arm64-add-arm_smccc_arch_workaround_1-bp-hardening-support.patch
arm64-kill-psci_get_version-as-a-variant-2-workaround.patch
+mtd-cfi-convert-inline-functions-to-macros.patch
+mtd-nand-brcmnand-disable-prefetch-by-default.patch
+mtd-nand-fix-nand_do_read_oob-return-value.patch
+mtd-nand-sunxi-fix-ecc-strength-choice.patch
+ubi-fix-race-condition-between-ubi-volume-creation-and-udev.patch
+ubi-fastmap-erase-outdated-anchor-pebs-during-attach.patch
+ubi-block-fix-locking-for-idr_alloc-idr_remove.patch
+ubifs-free-the-encrypted-symlink-target.patch
+nfs-pnfs-fix-nfs_direct_req-ref-leak-when-i-o-falls-back-to-the-mds.patch
+nfs41-do-not-return-enomem-on-layoutunavailable.patch
+nfs-add-a-cond_resched-to-nfs_commit_release_pages.patch
+nfs-fix-nfsstat-breakage-due-to-lookupp.patch
+nfs-commit-direct-writes-even-if-they-fail-partially.patch
+nfs-reject-request-for-id_legacy-key-without-auxdata.patch
+nfs-fix-a-race-between-mmap-and-o_direct.patch
+nfsd-detect-unhashed-stids-in-nfsd4_verify_open_stid.patch
+kernfs-fix-regression-in-kernfs_fop_write-caused-by-wrong-type.patch
+ahci-annotate-pci-ids-for-mobile-intel-chipsets-as-such.patch
+ahci-add-pci-ids-for-intel-bay-trail-cherry-trail-and-apollo-lake-ahci.patch
+ahci-allow-setting-a-default-lpm-policy-for-mobile-chipsets.patch
+ahci-add-intel-cannon-lake-pch-h-pci-id.patch
--- /dev/null
+From 7f29ae9f977bcdc3654e68bc36d170223c52fd48 Mon Sep 17 00:00:00 2001
+From: Bradley Bolen <bradleybolen@gmail.com>
+Date: Thu, 18 Jan 2018 08:55:20 -0500
+Subject: ubi: block: Fix locking for idr_alloc/idr_remove
+
+From: Bradley Bolen <bradleybolen@gmail.com>
+
+commit 7f29ae9f977bcdc3654e68bc36d170223c52fd48 upstream.
+
+This fixes a race with idr_alloc where gd->first_minor can be set to the
+same value for two simultaneous calls to ubiblock_create. Each instance
+calls device_add_disk with the same first_minor. device_add_disk calls
+bdi_register_owner which generates several warnings.
+
+WARNING: CPU: 1 PID: 179 at kernel-source/fs/sysfs/dir.c:31
+sysfs_warn_dup+0x68/0x88
+sysfs: cannot create duplicate filename '/devices/virtual/bdi/252:2'
+
+WARNING: CPU: 1 PID: 179 at kernel-source/lib/kobject.c:240
+kobject_add_internal+0x1ec/0x2f8
+kobject_add_internal failed for 252:2 with -EEXIST, don't try to
+register things with the same name in the same directory
+
+WARNING: CPU: 1 PID: 179 at kernel-source/fs/sysfs/dir.c:31
+sysfs_warn_dup+0x68/0x88
+sysfs: cannot create duplicate filename '/dev/block/252:2'
+
+However, device_add_disk does not error out when bdi_register_owner
+returns an error. Control continues until reaching blk_register_queue.
+It then BUGs.
+
+kernel BUG at kernel-source/fs/sysfs/group.c:113!
+[<c01e26cc>] (internal_create_group) from [<c01e2950>]
+(sysfs_create_group+0x20/0x24)
+[<c01e2950>] (sysfs_create_group) from [<c00e3d38>]
+(blk_trace_init_sysfs+0x18/0x20)
+[<c00e3d38>] (blk_trace_init_sysfs) from [<c02bdfbc>]
+(blk_register_queue+0xd8/0x154)
+[<c02bdfbc>] (blk_register_queue) from [<c02cec84>]
+(device_add_disk+0x194/0x44c)
+[<c02cec84>] (device_add_disk) from [<c0436ec8>]
+(ubiblock_create+0x284/0x2e0)
+[<c0436ec8>] (ubiblock_create) from [<c0427bb8>]
+(vol_cdev_ioctl+0x450/0x554)
+[<c0427bb8>] (vol_cdev_ioctl) from [<c0189110>] (vfs_ioctl+0x30/0x44)
+[<c0189110>] (vfs_ioctl) from [<c01892e0>] (do_vfs_ioctl+0xa0/0x790)
+[<c01892e0>] (do_vfs_ioctl) from [<c0189a14>] (SyS_ioctl+0x44/0x68)
+[<c0189a14>] (SyS_ioctl) from [<c0010640>] (ret_fast_syscall+0x0/0x34)
+
+Locking idr_alloc/idr_remove removes the race and keeps gd->first_minor
+unique.
+
+Fixes: 2bf50d42f3a4 ("UBI: block: Dynamically allocate minor numbers")
+Signed-off-by: Bradley Bolen <bradleybolen@gmail.com>
+Reviewed-by: Boris Brezillon <boris.brezillon@free-electrons.com>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/mtd/ubi/block.c | 42 ++++++++++++++++++++++++++----------------
+ 1 file changed, 26 insertions(+), 16 deletions(-)
+
+--- a/drivers/mtd/ubi/block.c
++++ b/drivers/mtd/ubi/block.c
+@@ -99,6 +99,8 @@ struct ubiblock {
+
+ /* Linked list of all ubiblock instances */
+ static LIST_HEAD(ubiblock_devices);
++static DEFINE_IDR(ubiblock_minor_idr);
++/* Protects ubiblock_devices and ubiblock_minor_idr */
+ static DEFINE_MUTEX(devices_mutex);
+ static int ubiblock_major;
+
+@@ -351,8 +353,6 @@ static const struct blk_mq_ops ubiblock_
+ .init_request = ubiblock_init_request,
+ };
+
+-static DEFINE_IDR(ubiblock_minor_idr);
+-
+ int ubiblock_create(struct ubi_volume_info *vi)
+ {
+ struct ubiblock *dev;
+@@ -365,14 +365,15 @@ int ubiblock_create(struct ubi_volume_in
+ /* Check that the volume isn't already handled */
+ mutex_lock(&devices_mutex);
+ if (find_dev_nolock(vi->ubi_num, vi->vol_id)) {
+- mutex_unlock(&devices_mutex);
+- return -EEXIST;
++ ret = -EEXIST;
++ goto out_unlock;
+ }
+- mutex_unlock(&devices_mutex);
+
+ dev = kzalloc(sizeof(struct ubiblock), GFP_KERNEL);
+- if (!dev)
+- return -ENOMEM;
++ if (!dev) {
++ ret = -ENOMEM;
++ goto out_unlock;
++ }
+
+ mutex_init(&dev->dev_mutex);
+
+@@ -437,14 +438,13 @@ int ubiblock_create(struct ubi_volume_in
+ goto out_free_queue;
+ }
+
+- mutex_lock(&devices_mutex);
+ list_add_tail(&dev->list, &ubiblock_devices);
+- mutex_unlock(&devices_mutex);
+
+ /* Must be the last step: anyone can call file ops from now on */
+ add_disk(dev->gd);
+ dev_info(disk_to_dev(dev->gd), "created from ubi%d:%d(%s)",
+ dev->ubi_num, dev->vol_id, vi->name);
++ mutex_unlock(&devices_mutex);
+ return 0;
+
+ out_free_queue:
+@@ -457,6 +457,8 @@ out_put_disk:
+ put_disk(dev->gd);
+ out_free_dev:
+ kfree(dev);
++out_unlock:
++ mutex_unlock(&devices_mutex);
+
+ return ret;
+ }
+@@ -478,30 +480,36 @@ static void ubiblock_cleanup(struct ubib
+ int ubiblock_remove(struct ubi_volume_info *vi)
+ {
+ struct ubiblock *dev;
++ int ret;
+
+ mutex_lock(&devices_mutex);
+ dev = find_dev_nolock(vi->ubi_num, vi->vol_id);
+ if (!dev) {
+- mutex_unlock(&devices_mutex);
+- return -ENODEV;
++ ret = -ENODEV;
++ goto out_unlock;
+ }
+
+ /* Found a device, let's lock it so we can check if it's busy */
+ mutex_lock(&dev->dev_mutex);
+ if (dev->refcnt > 0) {
+- mutex_unlock(&dev->dev_mutex);
+- mutex_unlock(&devices_mutex);
+- return -EBUSY;
++ ret = -EBUSY;
++ goto out_unlock_dev;
+ }
+
+ /* Remove from device list */
+ list_del(&dev->list);
+- mutex_unlock(&devices_mutex);
+-
+ ubiblock_cleanup(dev);
+ mutex_unlock(&dev->dev_mutex);
++ mutex_unlock(&devices_mutex);
++
+ kfree(dev);
+ return 0;
++
++out_unlock_dev:
++ mutex_unlock(&dev->dev_mutex);
++out_unlock:
++ mutex_unlock(&devices_mutex);
++ return ret;
+ }
+
+ static int ubiblock_resize(struct ubi_volume_info *vi)
+@@ -630,6 +638,7 @@ static void ubiblock_remove_all(void)
+ struct ubiblock *next;
+ struct ubiblock *dev;
+
++ mutex_lock(&devices_mutex);
+ list_for_each_entry_safe(dev, next, &ubiblock_devices, list) {
+ /* The module is being forcefully removed */
+ WARN_ON(dev->desc);
+@@ -638,6 +647,7 @@ static void ubiblock_remove_all(void)
+ ubiblock_cleanup(dev);
+ kfree(dev);
+ }
++ mutex_unlock(&devices_mutex);
+ }
+
+ int __init ubiblock_init(void)
--- /dev/null
+From f78e5623f45bab2b726eec29dc5cefbbab2d0b1c Mon Sep 17 00:00:00 2001
+From: Sascha Hauer <s.hauer@pengutronix.de>
+Date: Tue, 5 Dec 2017 16:01:20 +0100
+Subject: ubi: fastmap: Erase outdated anchor PEBs during attach
+
+From: Sascha Hauer <s.hauer@pengutronix.de>
+
+commit f78e5623f45bab2b726eec29dc5cefbbab2d0b1c upstream.
+
+The fastmap update code might erase the current fastmap anchor PEB
+in case it doesn't find any new free PEB. When a power cut happens
+in this situation we must not have any outdated fastmap anchor PEB
+on the device, because that would be used to attach during next
+boot.
+The easiest way to make that sure is to erase all outdated fastmap
+anchor PEBs synchronously during attach.
+
+Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
+Reviewed-by: Richard Weinberger <richard@nod.at>
+Fixes: dbb7d2a88d2a ("UBI: Add fastmap core")
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/mtd/ubi/wl.c | 77 +++++++++++++++++++++++++++++++++++++--------------
+ 1 file changed, 57 insertions(+), 20 deletions(-)
+
+--- a/drivers/mtd/ubi/wl.c
++++ b/drivers/mtd/ubi/wl.c
+@@ -1529,6 +1529,46 @@ static void shutdown_work(struct ubi_dev
+ }
+
+ /**
++ * erase_aeb - erase a PEB given in UBI attach info PEB
++ * @ubi: UBI device description object
++ * @aeb: UBI attach info PEB
++ * @sync: If true, erase synchronously. Otherwise schedule for erasure
++ */
++static int erase_aeb(struct ubi_device *ubi, struct ubi_ainf_peb *aeb, bool sync)
++{
++ struct ubi_wl_entry *e;
++ int err;
++
++ e = kmem_cache_alloc(ubi_wl_entry_slab, GFP_KERNEL);
++ if (!e)
++ return -ENOMEM;
++
++ e->pnum = aeb->pnum;
++ e->ec = aeb->ec;
++ ubi->lookuptbl[e->pnum] = e;
++
++ if (sync) {
++ err = sync_erase(ubi, e, false);
++ if (err)
++ goto out_free;
++
++ wl_tree_add(e, &ubi->free);
++ ubi->free_count++;
++ } else {
++ err = schedule_erase(ubi, e, aeb->vol_id, aeb->lnum, 0, false);
++ if (err)
++ goto out_free;
++ }
++
++ return 0;
++
++out_free:
++ wl_entry_destroy(ubi, e);
++
++ return err;
++}
++
++/**
+ * ubi_wl_init - initialize the WL sub-system using attaching information.
+ * @ubi: UBI device description object
+ * @ai: attaching information
+@@ -1566,17 +1606,9 @@ int ubi_wl_init(struct ubi_device *ubi,
+ list_for_each_entry_safe(aeb, tmp, &ai->erase, u.list) {
+ cond_resched();
+
+- e = kmem_cache_alloc(ubi_wl_entry_slab, GFP_KERNEL);
+- if (!e)
+- goto out_free;
+-
+- e->pnum = aeb->pnum;
+- e->ec = aeb->ec;
+- ubi->lookuptbl[e->pnum] = e;
+- if (schedule_erase(ubi, e, aeb->vol_id, aeb->lnum, 0, false)) {
+- wl_entry_destroy(ubi, e);
++ err = erase_aeb(ubi, aeb, false);
++ if (err)
+ goto out_free;
+- }
+
+ found_pebs++;
+ }
+@@ -1635,6 +1667,8 @@ int ubi_wl_init(struct ubi_device *ubi,
+ ubi_assert(!ubi->lookuptbl[e->pnum]);
+ ubi->lookuptbl[e->pnum] = e;
+ } else {
++ bool sync = false;
++
+ /*
+ * Usually old Fastmap PEBs are scheduled for erasure
+ * and we don't have to care about them but if we face
+@@ -1644,18 +1678,21 @@ int ubi_wl_init(struct ubi_device *ubi,
+ if (ubi->lookuptbl[aeb->pnum])
+ continue;
+
+- e = kmem_cache_alloc(ubi_wl_entry_slab, GFP_KERNEL);
+- if (!e)
+- goto out_free;
++ /*
++ * The fastmap update code might not find a free PEB for
++ * writing the fastmap anchor to and then reuses the
++ * current fastmap anchor PEB. When this PEB gets erased
++ * and a power cut happens before it is written again we
++ * must make sure that the fastmap attach code doesn't
++ * find any outdated fastmap anchors, hence we erase the
++ * outdated fastmap anchor PEBs synchronously here.
++ */
++ if (aeb->vol_id == UBI_FM_SB_VOLUME_ID)
++ sync = true;
+
+- e->pnum = aeb->pnum;
+- e->ec = aeb->ec;
+- ubi_assert(!ubi->lookuptbl[e->pnum]);
+- ubi->lookuptbl[e->pnum] = e;
+- if (schedule_erase(ubi, e, aeb->vol_id, aeb->lnum, 0, false)) {
+- wl_entry_destroy(ubi, e);
++ err = erase_aeb(ubi, aeb, sync);
++ if (err)
+ goto out_free;
+- }
+ }
+
+ found_pebs++;
--- /dev/null
+From a51a0c8d213594bc094cb8e54aad0cb6d7f7b9a6 Mon Sep 17 00:00:00 2001
+From: Clay McClure <clay@daemons.net>
+Date: Thu, 21 Sep 2017 19:01:34 -0700
+Subject: ubi: Fix race condition between ubi volume creation and udev
+
+From: Clay McClure <clay@daemons.net>
+
+commit a51a0c8d213594bc094cb8e54aad0cb6d7f7b9a6 upstream.
+
+Similar to commit 714fb87e8bc0 ("ubi: Fix race condition between ubi
+device creation and udev"), we should make the volume active before
+registering it.
+
+Signed-off-by: Clay McClure <clay@daemons.net>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/mtd/ubi/vmt.c | 15 ++++++++++-----
+ 1 file changed, 10 insertions(+), 5 deletions(-)
+
+--- a/drivers/mtd/ubi/vmt.c
++++ b/drivers/mtd/ubi/vmt.c
+@@ -270,6 +270,12 @@ int ubi_create_volume(struct ubi_device
+ vol->last_eb_bytes = vol->usable_leb_size;
+ }
+
++ /* Make volume "available" before it becomes accessible via sysfs */
++ spin_lock(&ubi->volumes_lock);
++ ubi->volumes[vol_id] = vol;
++ ubi->vol_count += 1;
++ spin_unlock(&ubi->volumes_lock);
++
+ /* Register character device for the volume */
+ cdev_init(&vol->cdev, &ubi_vol_cdev_operations);
+ vol->cdev.owner = THIS_MODULE;
+@@ -298,11 +304,6 @@ int ubi_create_volume(struct ubi_device
+ if (err)
+ goto out_sysfs;
+
+- spin_lock(&ubi->volumes_lock);
+- ubi->volumes[vol_id] = vol;
+- ubi->vol_count += 1;
+- spin_unlock(&ubi->volumes_lock);
+-
+ ubi_volume_notify(ubi, vol, UBI_VOLUME_ADDED);
+ self_check_volumes(ubi);
+ return err;
+@@ -315,6 +316,10 @@ out_sysfs:
+ */
+ cdev_device_del(&vol->cdev, &vol->dev);
+ out_mapping:
++ spin_lock(&ubi->volumes_lock);
++ ubi->volumes[vol_id] = NULL;
++ ubi->vol_count -= 1;
++ spin_unlock(&ubi->volumes_lock);
+ ubi_eba_destroy_table(eba_tbl);
+ out_acc:
+ spin_lock(&ubi->volumes_lock);
--- /dev/null
+From 6b46d444146eb8d0b99562795cea8086639d7282 Mon Sep 17 00:00:00 2001
+From: Eric Biggers <ebiggers@google.com>
+Date: Thu, 11 Jan 2018 23:27:00 -0500
+Subject: ubifs: free the encrypted symlink target
+
+From: Eric Biggers <ebiggers@google.com>
+
+commit 6b46d444146eb8d0b99562795cea8086639d7282 upstream.
+
+ubifs_symlink() forgot to free the kmalloc()'ed buffer holding the
+encrypted symlink target, creating a memory leak. Fix it.
+
+(UBIFS could actually encrypt directly into ui->data, removing the
+temporary buffer, but that is left for the patch that switches to use
+the symlink helper functions.)
+
+Fixes: ca7f85be8d6c ("ubifs: Add support for encrypted symlinks")
+Signed-off-by: Eric Biggers <ebiggers@google.com>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ubifs/dir.c | 10 ++++------
+ 1 file changed, 4 insertions(+), 6 deletions(-)
+
+--- a/fs/ubifs/dir.c
++++ b/fs/ubifs/dir.c
+@@ -1216,10 +1216,8 @@ static int ubifs_symlink(struct inode *d
+ ostr.len = disk_link.len;
+
+ err = fscrypt_fname_usr_to_disk(inode, &istr, &ostr);
+- if (err) {
+- kfree(sd);
++ if (err)
+ goto out_inode;
+- }
+
+ sd->len = cpu_to_le16(ostr.len);
+ disk_link.name = (char *)sd;
+@@ -1251,11 +1249,10 @@ static int ubifs_symlink(struct inode *d
+ goto out_cancel;
+ mutex_unlock(&dir_ui->ui_mutex);
+
+- ubifs_release_budget(c, &req);
+ insert_inode_hash(inode);
+ d_instantiate(dentry, inode);
+- fscrypt_free_filename(&nm);
+- return 0;
++ err = 0;
++ goto out_fname;
+
+ out_cancel:
+ dir->i_size -= sz_change;
+@@ -1268,6 +1265,7 @@ out_fname:
+ fscrypt_free_filename(&nm);
+ out_budg:
+ ubifs_release_budget(c, &req);
++ kfree(sd);
+ return err;
+ }
+