From: Greg Kroah-Hartman Date: Thu, 6 Feb 2020 19:24:25 +0000 (+0100) Subject: 4.19-stable patches X-Git-Tag: v4.19.103~120 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=923bc77e9892db5b558cf2a877d15319112f10a3;p=thirdparty%2Fkernel%2Fstable-queue.git 4.19-stable patches added patches: acpi-battery-deal-better-with-neither-design-nor-full-capacity-not-being-reported.patch acpi-battery-deal-with-design-or-full-capacity-being-reported-as-1.patch acpi-battery-use-design-cap-for-capacity-calculations-if-full-cap-is-not-available.patch acpi-video-do-not-export-a-non-working-backlight-interface-on-msi-ms-7721-boards.patch alarmtimer-unregister-wakeup-source-when-module-get-fails.patch crypto-geode-aes-convert-to-skcipher-api-and-make-thread-safe.patch mmc-spi-toggle-spi-polarity-do-not-hardcode-it.patch pci-tegra-fix-return-value-check-of-pm_runtime_get_sync.patch ubifs-don-t-trigger-assertion-on-invalid-no-key-filename.patch ubifs-fix-deadlock-in-concurrent-bulk-read-and-writepage.patch ubifs-fix-fs_ioc_setflags-unexpectedly-clearing-encrypt-flag.patch ubifs-reject-unsupported-ioctl-flags-explicitly.patch --- diff --git a/queue-4.19/acpi-battery-deal-better-with-neither-design-nor-full-capacity-not-being-reported.patch b/queue-4.19/acpi-battery-deal-better-with-neither-design-nor-full-capacity-not-being-reported.patch new file mode 100644 index 00000000000..857296902ad --- /dev/null +++ b/queue-4.19/acpi-battery-deal-better-with-neither-design-nor-full-capacity-not-being-reported.patch @@ -0,0 +1,115 @@ +From ff3154d1d89a2343fd5f82e65bc0cf1d4e6659b3 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Tue, 10 Dec 2019 10:57:52 +0100 +Subject: ACPI / battery: Deal better with neither design nor full capacity not being reported + +From: Hans de Goede + +commit ff3154d1d89a2343fd5f82e65bc0cf1d4e6659b3 upstream. + +Commit b41901a2cf06 ("ACPI / battery: Do not export energy_full[_design] on +devices without full_charge_capacity") added support for some (broken) +devices which always report 0 for both design_capacity and +full_charge_capacity. + +Since the device that commit was written as a fix for is not reporting any +form of "full" capacity we cannot calculate the value for the +POWER_SUPPLY_PROP_CAPACITY, this is worked around by using an alternative +array of available properties which does not contain this property. + +This is necessary because userspace (upower) treats us returning -ENODEV +as 0 and then typically will trigger an emergency shutdown because of that. +Userspace does not do this if the capacity sysfs attribute is not present +at all. + +There are two potential problems with that commit: + 1) It assumes that both full_charge- and design-capacity are broken at the + same time and only checks if full_charge- is broken. + 2) It assumes that this only ever happens for devices which report energy + units rather then charge units. + +This commit fixes both issues by only using the alternative +array of available properties if both full_charge- and design-capacity are +broken and by also adding an alternative array of available properties for +devices using mA units. + +Fixes: b41901a2cf06 ("ACPI / battery: Do not export energy_full[_design] on devices without full_charge_capacity") +Cc: 4.19+ # 4.19+ +Signed-off-by: Hans de Goede +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/acpi/battery.c | 51 +++++++++++++++++++++++++++++++++++++------------ + 1 file changed, 39 insertions(+), 12 deletions(-) + +--- a/drivers/acpi/battery.c ++++ b/drivers/acpi/battery.c +@@ -355,6 +355,20 @@ static enum power_supply_property charge + POWER_SUPPLY_PROP_SERIAL_NUMBER, + }; + ++static enum power_supply_property charge_battery_full_cap_broken_props[] = { ++ POWER_SUPPLY_PROP_STATUS, ++ POWER_SUPPLY_PROP_PRESENT, ++ POWER_SUPPLY_PROP_TECHNOLOGY, ++ POWER_SUPPLY_PROP_CYCLE_COUNT, ++ POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, ++ POWER_SUPPLY_PROP_VOLTAGE_NOW, ++ POWER_SUPPLY_PROP_CURRENT_NOW, ++ POWER_SUPPLY_PROP_CHARGE_NOW, ++ POWER_SUPPLY_PROP_MODEL_NAME, ++ POWER_SUPPLY_PROP_MANUFACTURER, ++ POWER_SUPPLY_PROP_SERIAL_NUMBER, ++}; ++ + static enum power_supply_property energy_battery_props[] = { + POWER_SUPPLY_PROP_STATUS, + POWER_SUPPLY_PROP_PRESENT, +@@ -816,21 +830,34 @@ static void __exit battery_hook_exit(voi + static int sysfs_add_battery(struct acpi_battery *battery) + { + struct power_supply_config psy_cfg = { .drv_data = battery, }; ++ bool full_cap_broken = false; ++ ++ if (!ACPI_BATTERY_CAPACITY_VALID(battery->full_charge_capacity) && ++ !ACPI_BATTERY_CAPACITY_VALID(battery->design_capacity)) ++ full_cap_broken = true; + + if (battery->power_unit == ACPI_BATTERY_POWER_UNIT_MA) { +- battery->bat_desc.properties = charge_battery_props; +- battery->bat_desc.num_properties = +- ARRAY_SIZE(charge_battery_props); +- } else if (!ACPI_BATTERY_CAPACITY_VALID( +- battery->full_charge_capacity)) { +- battery->bat_desc.properties = +- energy_battery_full_cap_broken_props; +- battery->bat_desc.num_properties = +- ARRAY_SIZE(energy_battery_full_cap_broken_props); ++ if (full_cap_broken) { ++ battery->bat_desc.properties = ++ charge_battery_full_cap_broken_props; ++ battery->bat_desc.num_properties = ++ ARRAY_SIZE(charge_battery_full_cap_broken_props); ++ } else { ++ battery->bat_desc.properties = charge_battery_props; ++ battery->bat_desc.num_properties = ++ ARRAY_SIZE(charge_battery_props); ++ } + } else { +- battery->bat_desc.properties = energy_battery_props; +- battery->bat_desc.num_properties = +- ARRAY_SIZE(energy_battery_props); ++ if (full_cap_broken) { ++ battery->bat_desc.properties = ++ energy_battery_full_cap_broken_props; ++ battery->bat_desc.num_properties = ++ ARRAY_SIZE(energy_battery_full_cap_broken_props); ++ } else { ++ battery->bat_desc.properties = energy_battery_props; ++ battery->bat_desc.num_properties = ++ ARRAY_SIZE(energy_battery_props); ++ } + } + + battery->bat_desc.name = acpi_device_bid(battery->device); diff --git a/queue-4.19/acpi-battery-deal-with-design-or-full-capacity-being-reported-as-1.patch b/queue-4.19/acpi-battery-deal-with-design-or-full-capacity-being-reported-as-1.patch new file mode 100644 index 00000000000..454028af179 --- /dev/null +++ b/queue-4.19/acpi-battery-deal-with-design-or-full-capacity-being-reported-as-1.patch @@ -0,0 +1,96 @@ +From cc99f0ad52467028cb1251160f23ad4bb65baf20 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Tue, 10 Dec 2019 10:57:50 +0100 +Subject: ACPI / battery: Deal with design or full capacity being reported as -1 + +From: Hans de Goede + +commit cc99f0ad52467028cb1251160f23ad4bb65baf20 upstream. + +Commit b41901a2cf06 ("ACPI / battery: Do not export energy_full[_design] +on devices without full_charge_capacity") added support for some (broken) +devices which always report 0 for both design- and full_charge-capacity. + +This assumes that if the capacity is not being reported it is 0. The +ThunderSoft TS178 tablet's _BIX implementation falsifies this assumption. +It reports ACPI_BATTERY_VALUE_UNKNOWN (-1) as full_charge_capacity, which +we treat as a valid value which causes several problems. + +This commit fixes this by adding a new ACPI_BATTERY_CAPACITY_VALID() helper +which checks that the value is not 0 and not -1; and using this whenever we +need to test if either design_capacity or full_charge_capacity is valid. + +Fixes: b41901a2cf06 ("ACPI / battery: Do not export energy_full[_design] on devices without full_charge_capacity") +Cc: 4.19+ # 4.19+ +Signed-off-by: Hans de Goede +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/acpi/battery.c | 19 ++++++++++++------- + 1 file changed, 12 insertions(+), 7 deletions(-) + +--- a/drivers/acpi/battery.c ++++ b/drivers/acpi/battery.c +@@ -51,6 +51,8 @@ + #define PREFIX "ACPI: " + + #define ACPI_BATTERY_VALUE_UNKNOWN 0xFFFFFFFF ++#define ACPI_BATTERY_CAPACITY_VALID(capacity) \ ++ ((capacity) != 0 && (capacity) != ACPI_BATTERY_VALUE_UNKNOWN) + + #define ACPI_BATTERY_DEVICE_NAME "Battery" + +@@ -205,7 +207,8 @@ static int acpi_battery_is_charged(struc + + static bool acpi_battery_is_degraded(struct acpi_battery *battery) + { +- return battery->full_charge_capacity && battery->design_capacity && ++ return ACPI_BATTERY_CAPACITY_VALID(battery->full_charge_capacity) && ++ ACPI_BATTERY_CAPACITY_VALID(battery->design_capacity) && + battery->full_charge_capacity < battery->design_capacity; + } + +@@ -276,14 +279,14 @@ static int acpi_battery_get_property(str + break; + case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: + case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN: +- if (battery->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN) ++ if (!ACPI_BATTERY_CAPACITY_VALID(battery->design_capacity)) + ret = -ENODEV; + else + val->intval = battery->design_capacity * 1000; + break; + case POWER_SUPPLY_PROP_CHARGE_FULL: + case POWER_SUPPLY_PROP_ENERGY_FULL: +- if (battery->full_charge_capacity == ACPI_BATTERY_VALUE_UNKNOWN) ++ if (!ACPI_BATTERY_CAPACITY_VALID(battery->full_charge_capacity)) + ret = -ENODEV; + else + val->intval = battery->full_charge_capacity * 1000; +@@ -296,11 +299,12 @@ static int acpi_battery_get_property(str + val->intval = battery->capacity_now * 1000; + break; + case POWER_SUPPLY_PROP_CAPACITY: +- if (battery->capacity_now && battery->full_charge_capacity) ++ if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN || ++ !ACPI_BATTERY_CAPACITY_VALID(battery->full_charge_capacity)) ++ ret = -ENODEV; ++ else + val->intval = battery->capacity_now * 100/ + battery->full_charge_capacity; +- else +- val->intval = 0; + break; + case POWER_SUPPLY_PROP_CAPACITY_LEVEL: + if (battery->state & ACPI_BATTERY_STATE_CRITICAL) +@@ -812,7 +816,8 @@ static int sysfs_add_battery(struct acpi + battery->bat_desc.properties = charge_battery_props; + battery->bat_desc.num_properties = + ARRAY_SIZE(charge_battery_props); +- } else if (battery->full_charge_capacity == 0) { ++ } else if (!ACPI_BATTERY_CAPACITY_VALID( ++ battery->full_charge_capacity)) { + battery->bat_desc.properties = + energy_battery_full_cap_broken_props; + battery->bat_desc.num_properties = diff --git a/queue-4.19/acpi-battery-use-design-cap-for-capacity-calculations-if-full-cap-is-not-available.patch b/queue-4.19/acpi-battery-use-design-cap-for-capacity-calculations-if-full-cap-is-not-available.patch new file mode 100644 index 00000000000..c32cd1dc101 --- /dev/null +++ b/queue-4.19/acpi-battery-use-design-cap-for-capacity-calculations-if-full-cap-is-not-available.patch @@ -0,0 +1,65 @@ +From 5b74d1d16e2f5753fcbdecd6771b2d8370dda414 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Tue, 10 Dec 2019 10:57:51 +0100 +Subject: ACPI / battery: Use design-cap for capacity calculations if full-cap is not available + +From: Hans de Goede + +commit 5b74d1d16e2f5753fcbdecd6771b2d8370dda414 upstream. + +The ThunderSoft TS178 tablet's _BIX implementation reports design_capacity +but not full_charge_capacity. + +Before this commit this would cause us to return -ENODEV for the capacity +attribute, which userspace does not like. Specifically upower does this: + + if (sysfs_file_exists (native_path, "capacity")) { + percentage = sysfs_get_double (native_path, "capacity"); + +Where the sysfs_get_double() helper returns 0 when we return -ENODEV, +so the battery always reads 0% if we return -ENODEV. + +This commit fixes this by using the design-capacity instead of the +full-charge-capacity when the full-charge-capacity is not available. + +Fixes: b41901a2cf06 ("ACPI / battery: Do not export energy_full[_design] on devices without full_charge_capacity") +Cc: 4.19+ # 4.19+ +Signed-off-by: Hans de Goede +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/acpi/battery.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +--- a/drivers/acpi/battery.c ++++ b/drivers/acpi/battery.c +@@ -230,7 +230,7 @@ static int acpi_battery_get_property(str + enum power_supply_property psp, + union power_supply_propval *val) + { +- int ret = 0; ++ int full_capacity = ACPI_BATTERY_VALUE_UNKNOWN, ret = 0; + struct acpi_battery *battery = to_acpi_battery(psy); + + if (acpi_battery_present(battery)) { +@@ -299,12 +299,17 @@ static int acpi_battery_get_property(str + val->intval = battery->capacity_now * 1000; + break; + case POWER_SUPPLY_PROP_CAPACITY: ++ if (ACPI_BATTERY_CAPACITY_VALID(battery->full_charge_capacity)) ++ full_capacity = battery->full_charge_capacity; ++ else if (ACPI_BATTERY_CAPACITY_VALID(battery->design_capacity)) ++ full_capacity = battery->design_capacity; ++ + if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN || +- !ACPI_BATTERY_CAPACITY_VALID(battery->full_charge_capacity)) ++ full_capacity == ACPI_BATTERY_VALUE_UNKNOWN) + ret = -ENODEV; + else + val->intval = battery->capacity_now * 100/ +- battery->full_charge_capacity; ++ full_capacity; + break; + case POWER_SUPPLY_PROP_CAPACITY_LEVEL: + if (battery->state & ACPI_BATTERY_STATE_CRITICAL) diff --git a/queue-4.19/acpi-video-do-not-export-a-non-working-backlight-interface-on-msi-ms-7721-boards.patch b/queue-4.19/acpi-video-do-not-export-a-non-working-backlight-interface-on-msi-ms-7721-boards.patch new file mode 100644 index 00000000000..5f72c5632e8 --- /dev/null +++ b/queue-4.19/acpi-video-do-not-export-a-non-working-backlight-interface-on-msi-ms-7721-boards.patch @@ -0,0 +1,59 @@ +From d21a91629f4b8e794fc4c0e0c17c85cedf1d806c Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Tue, 17 Dec 2019 20:08:11 +0100 +Subject: ACPI: video: Do not export a non working backlight interface on MSI MS-7721 boards + +From: Hans de Goede + +commit d21a91629f4b8e794fc4c0e0c17c85cedf1d806c upstream. + +Despite our heuristics to not wrongly export a non working ACPI backlight +interface on desktop machines, we still end up exporting one on desktops +using a motherboard from the MSI MS-7721 series. + +I've looked at improving the heuristics, but in this case a quirk seems +to be the only way to solve this. + +While at it also add a comment to separate the video_detect_force_none +entries in the video_detect_dmi_table from other type of entries, as we +already do for the other entry types. + +Cc: All applicable +BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1783786 +Signed-off-by: Hans de Goede +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/acpi/video_detect.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +--- a/drivers/acpi/video_detect.c ++++ b/drivers/acpi/video_detect.c +@@ -328,6 +328,11 @@ static const struct dmi_system_id video_ + DMI_MATCH(DMI_PRODUCT_NAME, "Precision 7510"), + }, + }, ++ ++ /* ++ * Desktops which falsely report a backlight and which our heuristics ++ * for this do not catch. ++ */ + { + .callback = video_detect_force_none, + .ident = "Dell OptiPlex 9020M", +@@ -336,6 +341,14 @@ static const struct dmi_system_id video_ + DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 9020M"), + }, + }, ++ { ++ .callback = video_detect_force_none, ++ .ident = "MSI MS-7721", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "MSI"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "MS-7721"), ++ }, ++ }, + { }, + }; + diff --git a/queue-4.19/alarmtimer-unregister-wakeup-source-when-module-get-fails.patch b/queue-4.19/alarmtimer-unregister-wakeup-source-when-module-get-fails.patch new file mode 100644 index 00000000000..8a01b5d5dc1 --- /dev/null +++ b/queue-4.19/alarmtimer-unregister-wakeup-source-when-module-get-fails.patch @@ -0,0 +1,64 @@ +From 6b6d188aae79a630957aefd88ff5c42af6553ee3 Mon Sep 17 00:00:00 2001 +From: Stephen Boyd +Date: Thu, 9 Jan 2020 07:59:07 -0800 +Subject: alarmtimer: Unregister wakeup source when module get fails + +From: Stephen Boyd + +commit 6b6d188aae79a630957aefd88ff5c42af6553ee3 upstream. + +The alarmtimer_rtc_add_device() function creates a wakeup source and then +tries to grab a module reference. If that fails the function returns early +with an error code, but fails to remove the wakeup source. + +Cleanup this exit path so there is no dangling wakeup source, which is +named 'alarmtime' left allocated which will conflict with another RTC +device that may be registered later. + +Fixes: 51218298a25e ("alarmtimer: Ensure RTC module is not unloaded") +Signed-off-by: Stephen Boyd +Signed-off-by: Thomas Gleixner +Reviewed-by: Douglas Anderson +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20200109155910.907-2-swboyd@chromium.org +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/time/alarmtimer.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +--- a/kernel/time/alarmtimer.c ++++ b/kernel/time/alarmtimer.c +@@ -91,6 +91,7 @@ static int alarmtimer_rtc_add_device(str + unsigned long flags; + struct rtc_device *rtc = to_rtc_device(dev); + struct wakeup_source *__ws; ++ int ret = 0; + + if (rtcdev) + return -EBUSY; +@@ -105,8 +106,8 @@ static int alarmtimer_rtc_add_device(str + spin_lock_irqsave(&rtcdev_lock, flags); + if (!rtcdev) { + if (!try_module_get(rtc->owner)) { +- spin_unlock_irqrestore(&rtcdev_lock, flags); +- return -1; ++ ret = -1; ++ goto unlock; + } + + rtcdev = rtc; +@@ -115,11 +116,12 @@ static int alarmtimer_rtc_add_device(str + ws = __ws; + __ws = NULL; + } ++unlock: + spin_unlock_irqrestore(&rtcdev_lock, flags); + + wakeup_source_unregister(__ws); + +- return 0; ++ return ret; + } + + static inline void alarmtimer_rtc_timer_init(void) diff --git a/queue-4.19/crypto-geode-aes-convert-to-skcipher-api-and-make-thread-safe.patch b/queue-4.19/crypto-geode-aes-convert-to-skcipher-api-and-make-thread-safe.patch new file mode 100644 index 00000000000..929d6b98a19 --- /dev/null +++ b/queue-4.19/crypto-geode-aes-convert-to-skcipher-api-and-make-thread-safe.patch @@ -0,0 +1,705 @@ +From 4549f7e5aa27ffc2cba63b5db8842a3b486f5688 Mon Sep 17 00:00:00 2001 +From: Eric Biggers +Date: Thu, 10 Oct 2019 21:51:32 -0700 +Subject: crypto: geode-aes - convert to skcipher API and make thread-safe + +From: Eric Biggers + +commit 4549f7e5aa27ffc2cba63b5db8842a3b486f5688 upstream. + +The geode AES driver is heavily broken because it stores per-request +state in the transform context. So it will crash or produce the wrong +result if used by any of the many places in the kernel that issue +concurrent requests for the same transform object. + +This driver is also implemented using the deprecated blkcipher API, +which makes it difficult to fix, and puts it among the drivers +preventing that API from being removed. + +Convert this driver to use the skcipher API, and change it to not store +per-request state in the transform context. + +Fixes: 9fe757b0cfce ("[PATCH] crypto: Add support for the Geode LX AES hardware") +Signed-off-by: Eric Biggers +Signed-off-by: Herbert Xu +Signed-off-by: Florian Bezdeka +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/crypto/geode-aes.c | 450 +++++++++++++++------------------------------ + drivers/crypto/geode-aes.h | 15 - + 2 files changed, 153 insertions(+), 312 deletions(-) + +--- a/drivers/crypto/geode-aes.c ++++ b/drivers/crypto/geode-aes.c +@@ -14,7 +14,7 @@ + #include + #include + #include +-#include ++#include + + #include + #include +@@ -28,12 +28,12 @@ static spinlock_t lock; + + /* Write a 128 bit field (either a writable key or IV) */ + static inline void +-_writefield(u32 offset, void *value) ++_writefield(u32 offset, const void *value) + { + int i; + + for (i = 0; i < 4; i++) +- iowrite32(((u32 *) value)[i], _iobase + offset + (i * 4)); ++ iowrite32(((const u32 *) value)[i], _iobase + offset + (i * 4)); + } + + /* Read a 128 bit field (either a writable key or IV) */ +@@ -47,12 +47,12 @@ _readfield(u32 offset, void *value) + } + + static int +-do_crypt(void *src, void *dst, int len, u32 flags) ++do_crypt(const void *src, void *dst, u32 len, u32 flags) + { + u32 status; + u32 counter = AES_OP_TIMEOUT; + +- iowrite32(virt_to_phys(src), _iobase + AES_SOURCEA_REG); ++ iowrite32(virt_to_phys((void *)src), _iobase + AES_SOURCEA_REG); + iowrite32(virt_to_phys(dst), _iobase + AES_DSTA_REG); + iowrite32(len, _iobase + AES_LENA_REG); + +@@ -69,16 +69,14 @@ do_crypt(void *src, void *dst, int len, + return counter ? 0 : 1; + } + +-static unsigned int +-geode_aes_crypt(struct geode_aes_op *op) ++static void ++geode_aes_crypt(const struct geode_aes_tfm_ctx *tctx, const void *src, ++ void *dst, u32 len, u8 *iv, int mode, int dir) + { + u32 flags = 0; + unsigned long iflags; + int ret; + +- if (op->len == 0) +- return 0; +- + /* If the source and destination is the same, then + * we need to turn on the coherent flags, otherwise + * we don't need to worry +@@ -86,32 +84,28 @@ geode_aes_crypt(struct geode_aes_op *op) + + flags |= (AES_CTRL_DCA | AES_CTRL_SCA); + +- if (op->dir == AES_DIR_ENCRYPT) ++ if (dir == AES_DIR_ENCRYPT) + flags |= AES_CTRL_ENCRYPT; + + /* Start the critical section */ + + spin_lock_irqsave(&lock, iflags); + +- if (op->mode == AES_MODE_CBC) { ++ if (mode == AES_MODE_CBC) { + flags |= AES_CTRL_CBC; +- _writefield(AES_WRITEIV0_REG, op->iv); ++ _writefield(AES_WRITEIV0_REG, iv); + } + +- if (!(op->flags & AES_FLAGS_HIDDENKEY)) { +- flags |= AES_CTRL_WRKEY; +- _writefield(AES_WRITEKEY0_REG, op->key); +- } ++ flags |= AES_CTRL_WRKEY; ++ _writefield(AES_WRITEKEY0_REG, tctx->key); + +- ret = do_crypt(op->src, op->dst, op->len, flags); ++ ret = do_crypt(src, dst, len, flags); + BUG_ON(ret); + +- if (op->mode == AES_MODE_CBC) +- _readfield(AES_WRITEIV0_REG, op->iv); ++ if (mode == AES_MODE_CBC) ++ _readfield(AES_WRITEIV0_REG, iv); + + spin_unlock_irqrestore(&lock, iflags); +- +- return op->len; + } + + /* CRYPTO-API Functions */ +@@ -119,13 +113,13 @@ geode_aes_crypt(struct geode_aes_op *op) + static int geode_setkey_cip(struct crypto_tfm *tfm, const u8 *key, + unsigned int len) + { +- struct geode_aes_op *op = crypto_tfm_ctx(tfm); ++ struct geode_aes_tfm_ctx *tctx = crypto_tfm_ctx(tfm); + unsigned int ret; + +- op->keylen = len; ++ tctx->keylen = len; + + if (len == AES_KEYSIZE_128) { +- memcpy(op->key, key, len); ++ memcpy(tctx->key, key, len); + return 0; + } + +@@ -138,132 +132,93 @@ static int geode_setkey_cip(struct crypt + /* + * The requested key size is not supported by HW, do a fallback + */ +- op->fallback.cip->base.crt_flags &= ~CRYPTO_TFM_REQ_MASK; +- op->fallback.cip->base.crt_flags |= (tfm->crt_flags & CRYPTO_TFM_REQ_MASK); ++ tctx->fallback.cip->base.crt_flags &= ~CRYPTO_TFM_REQ_MASK; ++ tctx->fallback.cip->base.crt_flags |= ++ (tfm->crt_flags & CRYPTO_TFM_REQ_MASK); + +- ret = crypto_cipher_setkey(op->fallback.cip, key, len); ++ ret = crypto_cipher_setkey(tctx->fallback.cip, key, len); + if (ret) { + tfm->crt_flags &= ~CRYPTO_TFM_RES_MASK; +- tfm->crt_flags |= (op->fallback.cip->base.crt_flags & CRYPTO_TFM_RES_MASK); ++ tfm->crt_flags |= (tctx->fallback.cip->base.crt_flags & ++ CRYPTO_TFM_RES_MASK); + } + return ret; + } + +-static int geode_setkey_blk(struct crypto_tfm *tfm, const u8 *key, +- unsigned int len) ++static int geode_setkey_skcipher(struct crypto_skcipher *tfm, const u8 *key, ++ unsigned int len) + { +- struct geode_aes_op *op = crypto_tfm_ctx(tfm); ++ struct geode_aes_tfm_ctx *tctx = crypto_skcipher_ctx(tfm); + unsigned int ret; + +- op->keylen = len; ++ tctx->keylen = len; + + if (len == AES_KEYSIZE_128) { +- memcpy(op->key, key, len); ++ memcpy(tctx->key, key, len); + return 0; + } + + if (len != AES_KEYSIZE_192 && len != AES_KEYSIZE_256) { + /* not supported at all */ +- tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; ++ crypto_skcipher_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); + return -EINVAL; + } + + /* + * The requested key size is not supported by HW, do a fallback + */ +- crypto_skcipher_clear_flags(op->fallback.blk, CRYPTO_TFM_REQ_MASK); +- crypto_skcipher_set_flags(op->fallback.blk, +- tfm->crt_flags & CRYPTO_TFM_REQ_MASK); +- +- ret = crypto_skcipher_setkey(op->fallback.blk, key, len); +- if (ret) { +- tfm->crt_flags &= ~CRYPTO_TFM_RES_MASK; +- tfm->crt_flags |= crypto_skcipher_get_flags(op->fallback.blk) & +- CRYPTO_TFM_RES_MASK; +- } ++ crypto_skcipher_clear_flags(tctx->fallback.skcipher, ++ CRYPTO_TFM_REQ_MASK); ++ crypto_skcipher_set_flags(tctx->fallback.skcipher, ++ crypto_skcipher_get_flags(tfm) & ++ CRYPTO_TFM_REQ_MASK); ++ ret = crypto_skcipher_setkey(tctx->fallback.skcipher, key, len); ++ crypto_skcipher_set_flags(tfm, ++ crypto_skcipher_get_flags(tctx->fallback.skcipher) & ++ CRYPTO_TFM_RES_MASK); + return ret; + } + +-static int fallback_blk_dec(struct blkcipher_desc *desc, +- struct scatterlist *dst, struct scatterlist *src, +- unsigned int nbytes) +-{ +- struct geode_aes_op *op = crypto_blkcipher_ctx(desc->tfm); +- SKCIPHER_REQUEST_ON_STACK(req, op->fallback.blk); +- +- skcipher_request_set_tfm(req, op->fallback.blk); +- skcipher_request_set_callback(req, 0, NULL, NULL); +- skcipher_request_set_crypt(req, src, dst, nbytes, desc->info); +- +- return crypto_skcipher_decrypt(req); +-} +- +-static int fallback_blk_enc(struct blkcipher_desc *desc, +- struct scatterlist *dst, struct scatterlist *src, +- unsigned int nbytes) +-{ +- struct geode_aes_op *op = crypto_blkcipher_ctx(desc->tfm); +- SKCIPHER_REQUEST_ON_STACK(req, op->fallback.blk); +- +- skcipher_request_set_tfm(req, op->fallback.blk); +- skcipher_request_set_callback(req, 0, NULL, NULL); +- skcipher_request_set_crypt(req, src, dst, nbytes, desc->info); +- +- return crypto_skcipher_encrypt(req); +-} +- + static void + geode_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) + { +- struct geode_aes_op *op = crypto_tfm_ctx(tfm); ++ const struct geode_aes_tfm_ctx *tctx = crypto_tfm_ctx(tfm); + +- if (unlikely(op->keylen != AES_KEYSIZE_128)) { +- crypto_cipher_encrypt_one(op->fallback.cip, out, in); ++ if (unlikely(tctx->keylen != AES_KEYSIZE_128)) { ++ crypto_cipher_encrypt_one(tctx->fallback.cip, out, in); + return; + } + +- op->src = (void *) in; +- op->dst = (void *) out; +- op->mode = AES_MODE_ECB; +- op->flags = 0; +- op->len = AES_BLOCK_SIZE; +- op->dir = AES_DIR_ENCRYPT; +- +- geode_aes_crypt(op); ++ geode_aes_crypt(tctx, in, out, AES_BLOCK_SIZE, NULL, ++ AES_MODE_ECB, AES_DIR_ENCRYPT); + } + + + static void + geode_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) + { +- struct geode_aes_op *op = crypto_tfm_ctx(tfm); ++ const struct geode_aes_tfm_ctx *tctx = crypto_tfm_ctx(tfm); + +- if (unlikely(op->keylen != AES_KEYSIZE_128)) { +- crypto_cipher_decrypt_one(op->fallback.cip, out, in); ++ if (unlikely(tctx->keylen != AES_KEYSIZE_128)) { ++ crypto_cipher_decrypt_one(tctx->fallback.cip, out, in); + return; + } + +- op->src = (void *) in; +- op->dst = (void *) out; +- op->mode = AES_MODE_ECB; +- op->flags = 0; +- op->len = AES_BLOCK_SIZE; +- op->dir = AES_DIR_DECRYPT; +- +- geode_aes_crypt(op); ++ geode_aes_crypt(tctx, in, out, AES_BLOCK_SIZE, NULL, ++ AES_MODE_ECB, AES_DIR_DECRYPT); + } + + static int fallback_init_cip(struct crypto_tfm *tfm) + { + const char *name = crypto_tfm_alg_name(tfm); +- struct geode_aes_op *op = crypto_tfm_ctx(tfm); ++ struct geode_aes_tfm_ctx *tctx = crypto_tfm_ctx(tfm); + +- op->fallback.cip = crypto_alloc_cipher(name, 0, +- CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK); ++ tctx->fallback.cip = crypto_alloc_cipher(name, 0, ++ CRYPTO_ALG_NEED_FALLBACK); + +- if (IS_ERR(op->fallback.cip)) { ++ if (IS_ERR(tctx->fallback.cip)) { + printk(KERN_ERR "Error allocating fallback algo %s\n", name); +- return PTR_ERR(op->fallback.cip); ++ return PTR_ERR(tctx->fallback.cip); + } + + return 0; +@@ -271,10 +226,9 @@ static int fallback_init_cip(struct cryp + + static void fallback_exit_cip(struct crypto_tfm *tfm) + { +- struct geode_aes_op *op = crypto_tfm_ctx(tfm); ++ struct geode_aes_tfm_ctx *tctx = crypto_tfm_ctx(tfm); + +- crypto_free_cipher(op->fallback.cip); +- op->fallback.cip = NULL; ++ crypto_free_cipher(tctx->fallback.cip); + } + + static struct crypto_alg geode_alg = { +@@ -287,7 +241,7 @@ static struct crypto_alg geode_alg = { + .cra_init = fallback_init_cip, + .cra_exit = fallback_exit_cip, + .cra_blocksize = AES_BLOCK_SIZE, +- .cra_ctxsize = sizeof(struct geode_aes_op), ++ .cra_ctxsize = sizeof(struct geode_aes_tfm_ctx), + .cra_module = THIS_MODULE, + .cra_u = { + .cipher = { +@@ -300,222 +254,126 @@ static struct crypto_alg geode_alg = { + } + }; + +-static int +-geode_cbc_decrypt(struct blkcipher_desc *desc, +- struct scatterlist *dst, struct scatterlist *src, +- unsigned int nbytes) +-{ +- struct geode_aes_op *op = crypto_blkcipher_ctx(desc->tfm); +- struct blkcipher_walk walk; +- int err, ret; +- +- if (nbytes % AES_BLOCK_SIZE) +- return -EINVAL; +- +- if (unlikely(op->keylen != AES_KEYSIZE_128)) +- return fallback_blk_dec(desc, dst, src, nbytes); +- +- blkcipher_walk_init(&walk, dst, src, nbytes); +- err = blkcipher_walk_virt(desc, &walk); +- op->iv = walk.iv; +- +- while ((nbytes = walk.nbytes)) { +- op->src = walk.src.virt.addr, +- op->dst = walk.dst.virt.addr; +- op->mode = AES_MODE_CBC; +- op->len = nbytes - (nbytes % AES_BLOCK_SIZE); +- op->dir = AES_DIR_DECRYPT; +- +- ret = geode_aes_crypt(op); +- +- nbytes -= ret; +- err = blkcipher_walk_done(desc, &walk, nbytes); +- } +- +- return err; +-} +- +-static int +-geode_cbc_encrypt(struct blkcipher_desc *desc, +- struct scatterlist *dst, struct scatterlist *src, +- unsigned int nbytes) +-{ +- struct geode_aes_op *op = crypto_blkcipher_ctx(desc->tfm); +- struct blkcipher_walk walk; +- int err, ret; +- +- if (nbytes % AES_BLOCK_SIZE) +- return -EINVAL; +- +- if (unlikely(op->keylen != AES_KEYSIZE_128)) +- return fallback_blk_enc(desc, dst, src, nbytes); +- +- blkcipher_walk_init(&walk, dst, src, nbytes); +- err = blkcipher_walk_virt(desc, &walk); +- op->iv = walk.iv; +- +- while ((nbytes = walk.nbytes)) { +- op->src = walk.src.virt.addr, +- op->dst = walk.dst.virt.addr; +- op->mode = AES_MODE_CBC; +- op->len = nbytes - (nbytes % AES_BLOCK_SIZE); +- op->dir = AES_DIR_ENCRYPT; +- +- ret = geode_aes_crypt(op); +- nbytes -= ret; +- err = blkcipher_walk_done(desc, &walk, nbytes); +- } +- +- return err; +-} +- +-static int fallback_init_blk(struct crypto_tfm *tfm) ++static int geode_init_skcipher(struct crypto_skcipher *tfm) + { +- const char *name = crypto_tfm_alg_name(tfm); +- struct geode_aes_op *op = crypto_tfm_ctx(tfm); +- +- op->fallback.blk = crypto_alloc_skcipher(name, 0, +- CRYPTO_ALG_ASYNC | +- CRYPTO_ALG_NEED_FALLBACK); ++ const char *name = crypto_tfm_alg_name(&tfm->base); ++ struct geode_aes_tfm_ctx *tctx = crypto_skcipher_ctx(tfm); + +- if (IS_ERR(op->fallback.blk)) { ++ tctx->fallback.skcipher = ++ crypto_alloc_skcipher(name, 0, CRYPTO_ALG_NEED_FALLBACK | ++ CRYPTO_ALG_ASYNC); ++ if (IS_ERR(tctx->fallback.skcipher)) { + printk(KERN_ERR "Error allocating fallback algo %s\n", name); +- return PTR_ERR(op->fallback.blk); ++ return PTR_ERR(tctx->fallback.skcipher); + } + ++ crypto_skcipher_set_reqsize(tfm, sizeof(struct skcipher_request) + ++ crypto_skcipher_reqsize(tctx->fallback.skcipher)); + return 0; + } + +-static void fallback_exit_blk(struct crypto_tfm *tfm) ++static void geode_exit_skcipher(struct crypto_skcipher *tfm) + { +- struct geode_aes_op *op = crypto_tfm_ctx(tfm); ++ struct geode_aes_tfm_ctx *tctx = crypto_skcipher_ctx(tfm); + +- crypto_free_skcipher(op->fallback.blk); +- op->fallback.blk = NULL; ++ crypto_free_skcipher(tctx->fallback.skcipher); + } + +-static struct crypto_alg geode_cbc_alg = { +- .cra_name = "cbc(aes)", +- .cra_driver_name = "cbc-aes-geode", +- .cra_priority = 400, +- .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER | +- CRYPTO_ALG_KERN_DRIVER_ONLY | +- CRYPTO_ALG_NEED_FALLBACK, +- .cra_init = fallback_init_blk, +- .cra_exit = fallback_exit_blk, +- .cra_blocksize = AES_BLOCK_SIZE, +- .cra_ctxsize = sizeof(struct geode_aes_op), +- .cra_alignmask = 15, +- .cra_type = &crypto_blkcipher_type, +- .cra_module = THIS_MODULE, +- .cra_u = { +- .blkcipher = { +- .min_keysize = AES_MIN_KEY_SIZE, +- .max_keysize = AES_MAX_KEY_SIZE, +- .setkey = geode_setkey_blk, +- .encrypt = geode_cbc_encrypt, +- .decrypt = geode_cbc_decrypt, +- .ivsize = AES_BLOCK_SIZE, +- } +- } +-}; +- +-static int +-geode_ecb_decrypt(struct blkcipher_desc *desc, +- struct scatterlist *dst, struct scatterlist *src, +- unsigned int nbytes) +-{ +- struct geode_aes_op *op = crypto_blkcipher_ctx(desc->tfm); +- struct blkcipher_walk walk; +- int err, ret; ++static int geode_skcipher_crypt(struct skcipher_request *req, int mode, int dir) ++{ ++ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); ++ const struct geode_aes_tfm_ctx *tctx = crypto_skcipher_ctx(tfm); ++ struct skcipher_walk walk; ++ unsigned int nbytes; ++ int err; + +- if (nbytes % AES_BLOCK_SIZE) +- return -EINVAL; ++ if (unlikely(tctx->keylen != AES_KEYSIZE_128)) { ++ struct skcipher_request *subreq = skcipher_request_ctx(req); + +- if (unlikely(op->keylen != AES_KEYSIZE_128)) +- return fallback_blk_dec(desc, dst, src, nbytes); ++ *subreq = *req; ++ skcipher_request_set_tfm(subreq, tctx->fallback.skcipher); ++ if (dir == AES_DIR_DECRYPT) ++ return crypto_skcipher_decrypt(subreq); ++ else ++ return crypto_skcipher_encrypt(subreq); ++ } + +- blkcipher_walk_init(&walk, dst, src, nbytes); +- err = blkcipher_walk_virt(desc, &walk); ++ err = skcipher_walk_virt(&walk, req, false); + +- while ((nbytes = walk.nbytes)) { +- op->src = walk.src.virt.addr, +- op->dst = walk.dst.virt.addr; +- op->mode = AES_MODE_ECB; +- op->len = nbytes - (nbytes % AES_BLOCK_SIZE); +- op->dir = AES_DIR_DECRYPT; +- +- ret = geode_aes_crypt(op); +- nbytes -= ret; +- err = blkcipher_walk_done(desc, &walk, nbytes); ++ while ((nbytes = walk.nbytes) != 0) { ++ geode_aes_crypt(tctx, walk.src.virt.addr, walk.dst.virt.addr, ++ round_down(nbytes, AES_BLOCK_SIZE), ++ walk.iv, mode, dir); ++ err = skcipher_walk_done(&walk, nbytes % AES_BLOCK_SIZE); + } + + return err; + } + +-static int +-geode_ecb_encrypt(struct blkcipher_desc *desc, +- struct scatterlist *dst, struct scatterlist *src, +- unsigned int nbytes) +-{ +- struct geode_aes_op *op = crypto_blkcipher_ctx(desc->tfm); +- struct blkcipher_walk walk; +- int err, ret; +- +- if (nbytes % AES_BLOCK_SIZE) +- return -EINVAL; +- +- if (unlikely(op->keylen != AES_KEYSIZE_128)) +- return fallback_blk_enc(desc, dst, src, nbytes); +- +- blkcipher_walk_init(&walk, dst, src, nbytes); +- err = blkcipher_walk_virt(desc, &walk); +- +- while ((nbytes = walk.nbytes)) { +- op->src = walk.src.virt.addr, +- op->dst = walk.dst.virt.addr; +- op->mode = AES_MODE_ECB; +- op->len = nbytes - (nbytes % AES_BLOCK_SIZE); +- op->dir = AES_DIR_ENCRYPT; +- +- ret = geode_aes_crypt(op); +- nbytes -= ret; +- ret = blkcipher_walk_done(desc, &walk, nbytes); +- } ++static int geode_cbc_encrypt(struct skcipher_request *req) ++{ ++ return geode_skcipher_crypt(req, AES_MODE_CBC, AES_DIR_ENCRYPT); ++} + +- return err; ++static int geode_cbc_decrypt(struct skcipher_request *req) ++{ ++ return geode_skcipher_crypt(req, AES_MODE_CBC, AES_DIR_DECRYPT); + } + +-static struct crypto_alg geode_ecb_alg = { +- .cra_name = "ecb(aes)", +- .cra_driver_name = "ecb-aes-geode", +- .cra_priority = 400, +- .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER | +- CRYPTO_ALG_KERN_DRIVER_ONLY | +- CRYPTO_ALG_NEED_FALLBACK, +- .cra_init = fallback_init_blk, +- .cra_exit = fallback_exit_blk, +- .cra_blocksize = AES_BLOCK_SIZE, +- .cra_ctxsize = sizeof(struct geode_aes_op), +- .cra_alignmask = 15, +- .cra_type = &crypto_blkcipher_type, +- .cra_module = THIS_MODULE, +- .cra_u = { +- .blkcipher = { +- .min_keysize = AES_MIN_KEY_SIZE, +- .max_keysize = AES_MAX_KEY_SIZE, +- .setkey = geode_setkey_blk, +- .encrypt = geode_ecb_encrypt, +- .decrypt = geode_ecb_decrypt, +- } +- } ++static int geode_ecb_encrypt(struct skcipher_request *req) ++{ ++ return geode_skcipher_crypt(req, AES_MODE_ECB, AES_DIR_ENCRYPT); ++} ++ ++static int geode_ecb_decrypt(struct skcipher_request *req) ++{ ++ return geode_skcipher_crypt(req, AES_MODE_ECB, AES_DIR_DECRYPT); ++} ++ ++static struct skcipher_alg geode_skcipher_algs[] = { ++ { ++ .base.cra_name = "cbc(aes)", ++ .base.cra_driver_name = "cbc-aes-geode", ++ .base.cra_priority = 400, ++ .base.cra_flags = CRYPTO_ALG_KERN_DRIVER_ONLY | ++ CRYPTO_ALG_NEED_FALLBACK, ++ .base.cra_blocksize = AES_BLOCK_SIZE, ++ .base.cra_ctxsize = sizeof(struct geode_aes_tfm_ctx), ++ .base.cra_alignmask = 15, ++ .base.cra_module = THIS_MODULE, ++ .init = geode_init_skcipher, ++ .exit = geode_exit_skcipher, ++ .setkey = geode_setkey_skcipher, ++ .encrypt = geode_cbc_encrypt, ++ .decrypt = geode_cbc_decrypt, ++ .min_keysize = AES_MIN_KEY_SIZE, ++ .max_keysize = AES_MAX_KEY_SIZE, ++ .ivsize = AES_BLOCK_SIZE, ++ }, { ++ .base.cra_name = "ecb(aes)", ++ .base.cra_driver_name = "ecb-aes-geode", ++ .base.cra_priority = 400, ++ .base.cra_flags = CRYPTO_ALG_KERN_DRIVER_ONLY | ++ CRYPTO_ALG_NEED_FALLBACK, ++ .base.cra_blocksize = AES_BLOCK_SIZE, ++ .base.cra_ctxsize = sizeof(struct geode_aes_tfm_ctx), ++ .base.cra_alignmask = 15, ++ .base.cra_module = THIS_MODULE, ++ .init = geode_init_skcipher, ++ .exit = geode_exit_skcipher, ++ .setkey = geode_setkey_skcipher, ++ .encrypt = geode_ecb_encrypt, ++ .decrypt = geode_ecb_decrypt, ++ .min_keysize = AES_MIN_KEY_SIZE, ++ .max_keysize = AES_MAX_KEY_SIZE, ++ }, + }; + + static void geode_aes_remove(struct pci_dev *dev) + { + crypto_unregister_alg(&geode_alg); +- crypto_unregister_alg(&geode_ecb_alg); +- crypto_unregister_alg(&geode_cbc_alg); ++ crypto_unregister_skciphers(geode_skcipher_algs, ++ ARRAY_SIZE(geode_skcipher_algs)); + + pci_iounmap(dev, _iobase); + _iobase = NULL; +@@ -553,20 +411,14 @@ static int geode_aes_probe(struct pci_de + if (ret) + goto eiomap; + +- ret = crypto_register_alg(&geode_ecb_alg); ++ ret = crypto_register_skciphers(geode_skcipher_algs, ++ ARRAY_SIZE(geode_skcipher_algs)); + if (ret) + goto ealg; + +- ret = crypto_register_alg(&geode_cbc_alg); +- if (ret) +- goto eecb; +- + dev_notice(&dev->dev, "GEODE AES engine enabled.\n"); + return 0; + +- eecb: +- crypto_unregister_alg(&geode_ecb_alg); +- + ealg: + crypto_unregister_alg(&geode_alg); + +--- a/drivers/crypto/geode-aes.h ++++ b/drivers/crypto/geode-aes.h +@@ -50,21 +50,10 @@ + + #define AES_OP_TIMEOUT 0x50000 + +-struct geode_aes_op { +- +- void *src; +- void *dst; +- +- u32 mode; +- u32 dir; +- u32 flags; +- int len; +- ++struct geode_aes_tfm_ctx { + u8 key[AES_KEYSIZE_128]; +- u8 *iv; +- + union { +- struct crypto_skcipher *blk; ++ struct crypto_skcipher *skcipher; + struct crypto_cipher *cip; + } fallback; + u32 keylen; diff --git a/queue-4.19/mmc-spi-toggle-spi-polarity-do-not-hardcode-it.patch b/queue-4.19/mmc-spi-toggle-spi-polarity-do-not-hardcode-it.patch new file mode 100644 index 00000000000..7adc9bf7316 --- /dev/null +++ b/queue-4.19/mmc-spi-toggle-spi-polarity-do-not-hardcode-it.patch @@ -0,0 +1,64 @@ +From af3ed119329cf9690598c5a562d95dfd128e91d6 Mon Sep 17 00:00:00 2001 +From: Linus Walleij +Date: Wed, 4 Dec 2019 16:27:49 +0100 +Subject: mmc: spi: Toggle SPI polarity, do not hardcode it + +From: Linus Walleij + +commit af3ed119329cf9690598c5a562d95dfd128e91d6 upstream. + +The code in mmc_spi_initsequence() tries to send a burst with +high chipselect and for this reason hardcodes the device into +SPI_CS_HIGH. + +This is not good because the SPI_CS_HIGH flag indicates +logical "asserted" CS not always the physical level. In +some cases the signal is inverted in the GPIO library and +in that case SPI_CS_HIGH is already set, and enforcing +SPI_CS_HIGH again will actually drive it low. + +Instead of hard-coding this, toggle the polarity so if the +default is LOW it goes high to assert chipselect but if it +is already high then toggle it low instead. + +Cc: Phil Elwell +Reported-by: Mark Brown +Signed-off-by: Linus Walleij +Reviewed-by: Mark Brown +Link: https://lore.kernel.org/r/20191204152749.12652-1-linus.walleij@linaro.org +Cc: stable@vger.kernel.org +Signed-off-by: Ulf Hansson +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/mmc/host/mmc_spi.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +--- a/drivers/mmc/host/mmc_spi.c ++++ b/drivers/mmc/host/mmc_spi.c +@@ -1154,17 +1154,22 @@ static void mmc_spi_initsequence(struct + * SPI protocol. Another is that when chipselect is released while + * the card returns BUSY status, the clock must issue several cycles + * with chipselect high before the card will stop driving its output. ++ * ++ * SPI_CS_HIGH means "asserted" here. In some cases like when using ++ * GPIOs for chip select, SPI_CS_HIGH is set but this will be logically ++ * inverted by gpiolib, so if we want to ascertain to drive it high ++ * we should toggle the default with an XOR as we do here. + */ +- host->spi->mode |= SPI_CS_HIGH; ++ host->spi->mode ^= SPI_CS_HIGH; + if (spi_setup(host->spi) != 0) { + /* Just warn; most cards work without it. */ + dev_warn(&host->spi->dev, + "can't change chip-select polarity\n"); +- host->spi->mode &= ~SPI_CS_HIGH; ++ host->spi->mode ^= SPI_CS_HIGH; + } else { + mmc_spi_readbytes(host, 18); + +- host->spi->mode &= ~SPI_CS_HIGH; ++ host->spi->mode ^= SPI_CS_HIGH; + if (spi_setup(host->spi) != 0) { + /* Wot, we can't get the same setup we had before? */ + dev_err(&host->spi->dev, diff --git a/queue-4.19/pci-tegra-fix-return-value-check-of-pm_runtime_get_sync.patch b/queue-4.19/pci-tegra-fix-return-value-check-of-pm_runtime_get_sync.patch new file mode 100644 index 00000000000..ba4f1f865cd --- /dev/null +++ b/queue-4.19/pci-tegra-fix-return-value-check-of-pm_runtime_get_sync.patch @@ -0,0 +1,38 @@ +From 885199148442f56b880995d703d2ed03b6481a3c Mon Sep 17 00:00:00 2001 +From: David Engraf +Date: Mon, 16 Dec 2019 12:18:25 +0100 +Subject: PCI: tegra: Fix return value check of pm_runtime_get_sync() + +From: David Engraf + +commit 885199148442f56b880995d703d2ed03b6481a3c upstream. + +pm_runtime_get_sync() returns the device's usage counter. This might +be >0 if the device is already powered up or CONFIG_PM is disabled. + +Abort probe function on real error only. + +Fixes: da76ba50963b ("PCI: tegra: Add power management support") +Link: https://lore.kernel.org/r/20191216111825.28136-1-david.engraf@sysgo.com +Signed-off-by: David Engraf +Signed-off-by: Bjorn Helgaas +Signed-off-by: Lorenzo Pieralisi +Acked-by: Andrew Murray +Cc: stable@vger.kernel.org # v4.17+ +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/pci/controller/pci-tegra.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/pci/controller/pci-tegra.c ++++ b/drivers/pci/controller/pci-tegra.c +@@ -2398,7 +2398,7 @@ static int tegra_pcie_probe(struct platf + + pm_runtime_enable(pcie->dev); + err = pm_runtime_get_sync(pcie->dev); +- if (err) { ++ if (err < 0) { + dev_err(dev, "fail to enable pcie controller: %d\n", err); + goto teardown_msi; + } diff --git a/queue-4.19/series b/queue-4.19/series index f6078346e3b..2c355ec4cdd 100644 --- a/queue-4.19/series +++ b/queue-4.19/series @@ -54,3 +54,15 @@ s390-mm-fix-dynamic-pagetable-upgrade-for-hugetlbfs.patch powerpc-xmon-don-t-access-asdr-in-vms.patch powerpc-pseries-advance-pfn-if-section-is-not-present-in-lmb_is_removable.patch smb3-fix-signing-verification-of-large-reads.patch +crypto-geode-aes-convert-to-skcipher-api-and-make-thread-safe.patch +pci-tegra-fix-return-value-check-of-pm_runtime_get_sync.patch +mmc-spi-toggle-spi-polarity-do-not-hardcode-it.patch +acpi-video-do-not-export-a-non-working-backlight-interface-on-msi-ms-7721-boards.patch +acpi-battery-deal-with-design-or-full-capacity-being-reported-as-1.patch +acpi-battery-use-design-cap-for-capacity-calculations-if-full-cap-is-not-available.patch +acpi-battery-deal-better-with-neither-design-nor-full-capacity-not-being-reported.patch +alarmtimer-unregister-wakeup-source-when-module-get-fails.patch +ubifs-reject-unsupported-ioctl-flags-explicitly.patch +ubifs-don-t-trigger-assertion-on-invalid-no-key-filename.patch +ubifs-fix-fs_ioc_setflags-unexpectedly-clearing-encrypt-flag.patch +ubifs-fix-deadlock-in-concurrent-bulk-read-and-writepage.patch diff --git a/queue-4.19/smb3-fix-signing-verification-of-large-reads.patch b/queue-4.19/smb3-fix-signing-verification-of-large-reads.patch index f066c2dfaf7..5239a29920b 100644 --- a/queue-4.19/smb3-fix-signing-verification-of-large-reads.patch +++ b/queue-4.19/smb3-fix-signing-verification-of-large-reads.patch @@ -22,14 +22,12 @@ Signed-off-by: Steve French Reviewed-by: Ronnie Sahlberg Signed-off-by: Sasha Levin --- - fs/cifs/smb2pdu.c | 4 ++-- + fs/cifs/smb2pdu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) -diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c -index 43f29621e51ff..93ef1d8e82c75 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c -@@ -3130,8 +3130,8 @@ smb2_readv_callback(struct mid_q_entry *mid) +@@ -3130,8 +3130,8 @@ smb2_readv_callback(struct mid_q_entry * struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)rdata->iov[0].iov_base; unsigned int credits_received = 0; @@ -40,6 +38,3 @@ index 43f29621e51ff..93ef1d8e82c75 100644 .rq_pages = rdata->pages, .rq_offset = rdata->page_offset, .rq_npages = rdata->nr_pages, --- -2.20.1 - diff --git a/queue-4.19/ubifs-don-t-trigger-assertion-on-invalid-no-key-filename.patch b/queue-4.19/ubifs-don-t-trigger-assertion-on-invalid-no-key-filename.patch new file mode 100644 index 00000000000..992fe1f67cd --- /dev/null +++ b/queue-4.19/ubifs-don-t-trigger-assertion-on-invalid-no-key-filename.patch @@ -0,0 +1,49 @@ +From f0d07a98a070bb5e443df19c3aa55693cbca9341 Mon Sep 17 00:00:00 2001 +From: Eric Biggers +Date: Mon, 20 Jan 2020 14:31:59 -0800 +Subject: ubifs: don't trigger assertion on invalid no-key filename + +From: Eric Biggers + +commit f0d07a98a070bb5e443df19c3aa55693cbca9341 upstream. + +If userspace provides an invalid fscrypt no-key filename which encodes a +hash value with any of the UBIFS node type bits set (i.e. the high 3 +bits), gracefully report ENOENT rather than triggering ubifs_assert(). + +Test case with kvm-xfstests shell: + + . fs/ubifs/config + . ~/xfstests/common/encrypt + dev=$(__blkdev_to_ubi_volume /dev/vdc) + ubiupdatevol $dev -t + mount $dev /mnt -t ubifs + mkdir /mnt/edir + xfs_io -c set_encpolicy /mnt/edir + rm /mnt/edir/_,,,,,DAAAAAAAAAAAAAAAAAAAAAAAAAA + +With the bug, the following assertion fails on the 'rm' command: + + [ 19.066048] UBIFS error (ubi0:0 pid 379): ubifs_assert_failed: UBIFS assert failed: !(hash & ~UBIFS_S_KEY_HASH_MASK), in fs/ubifs/key.h:170 + +Fixes: f4f61d2cc6d8 ("ubifs: Implement encrypted filenames") +Cc: # v4.10+ +Link: https://lore.kernel.org/r/20200120223201.241390-5-ebiggers@kernel.org +Signed-off-by: Eric Biggers +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ubifs/dir.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/fs/ubifs/dir.c ++++ b/fs/ubifs/dir.c +@@ -242,6 +242,8 @@ static struct dentry *ubifs_lookup(struc + if (nm.hash) { + ubifs_assert(c, fname_len(&nm) == 0); + ubifs_assert(c, fname_name(&nm) == NULL); ++ if (nm.hash & ~UBIFS_S_KEY_HASH_MASK) ++ goto done; /* ENOENT */ + dent_key_init_hash(c, &key, dir->i_ino, nm.hash); + err = ubifs_tnc_lookup_dh(c, &key, dent, nm.minor_hash); + } else { diff --git a/queue-4.19/ubifs-fix-deadlock-in-concurrent-bulk-read-and-writepage.patch b/queue-4.19/ubifs-fix-deadlock-in-concurrent-bulk-read-and-writepage.patch new file mode 100644 index 00000000000..546deb027e8 --- /dev/null +++ b/queue-4.19/ubifs-fix-deadlock-in-concurrent-bulk-read-and-writepage.patch @@ -0,0 +1,59 @@ +From f5de5b83303e61b1f3fb09bd77ce3ac2d7a475f2 Mon Sep 17 00:00:00 2001 +From: Zhihao Cheng +Date: Sat, 11 Jan 2020 17:50:36 +0800 +Subject: ubifs: Fix deadlock in concurrent bulk-read and writepage +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Zhihao Cheng + +commit f5de5b83303e61b1f3fb09bd77ce3ac2d7a475f2 upstream. + +In ubifs, concurrent execution of writepage and bulk read on the same file +may cause ABBA deadlock, for example (Reproduce method see Link): + +Process A(Bulk-read starts from page4) Process B(write page4 back) + vfs_read wb_workfn or fsync + ... ... + generic_file_buffered_read write_cache_pages + ubifs_readpage LOCK(page4) + + ubifs_bulk_read ubifs_writepage + LOCK(ui->ui_mutex) ubifs_write_inode + + ubifs_do_bulk_read LOCK(ui->ui_mutex) + find_or_create_page(alloc page4) ↑ + LOCK(page4) <-- ABBA deadlock occurs! + +In order to ensure the serialization execution of bulk read, we can't +remove the big lock 'ui->ui_mutex' in ubifs_bulk_read(). Instead, we +allow ubifs_do_bulk_read() to lock page failed by replacing +find_or_create_page(FGP_LOCK) with +pagecache_get_page(FGP_LOCK | FGP_NOWAIT). + +Signed-off-by: Zhihao Cheng +Suggested-by: zhangyi (F) +Cc: +Fixes: 4793e7c5e1c ("UBIFS: add bulk-read facility") +Link: https://bugzilla.kernel.org/show_bug.cgi?id=206153 +Signed-off-by: Richard Weinberger +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ubifs/file.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/fs/ubifs/file.c ++++ b/fs/ubifs/file.c +@@ -798,7 +798,9 @@ static int ubifs_do_bulk_read(struct ubi + + if (page_offset > end_index) + break; +- page = find_or_create_page(mapping, page_offset, ra_gfp_mask); ++ page = pagecache_get_page(mapping, page_offset, ++ FGP_LOCK|FGP_ACCESSED|FGP_CREAT|FGP_NOWAIT, ++ ra_gfp_mask); + if (!page) + break; + if (!PageUptodate(page)) diff --git a/queue-4.19/ubifs-fix-fs_ioc_setflags-unexpectedly-clearing-encrypt-flag.patch b/queue-4.19/ubifs-fix-fs_ioc_setflags-unexpectedly-clearing-encrypt-flag.patch new file mode 100644 index 00000000000..3d58ae8e6d2 --- /dev/null +++ b/queue-4.19/ubifs-fix-fs_ioc_setflags-unexpectedly-clearing-encrypt-flag.patch @@ -0,0 +1,57 @@ +From 2b57067a7778484c10892fa191997bfda29fea13 Mon Sep 17 00:00:00 2001 +From: Eric Biggers +Date: Mon, 9 Dec 2019 14:23:24 -0800 +Subject: ubifs: Fix FS_IOC_SETFLAGS unexpectedly clearing encrypt flag + +From: Eric Biggers + +commit 2b57067a7778484c10892fa191997bfda29fea13 upstream. + +UBIFS's implementation of FS_IOC_SETFLAGS fails to preserve existing +inode flags that aren't settable by FS_IOC_SETFLAGS, namely the encrypt +flag. This causes the encrypt flag to be unexpectedly cleared. + +Fix it by preserving existing unsettable flags, like ext4 and f2fs do. + +Test case with kvm-xfstests shell: + + FSTYP=ubifs KEYCTL_PROG=keyctl + . fs/ubifs/config + . ~/xfstests/common/encrypt + dev=$(__blkdev_to_ubi_volume /dev/vdc) + ubiupdatevol -t $dev + mount $dev /mnt -t ubifs + k=$(_generate_session_encryption_key) + mkdir /mnt/edir + xfs_io -c "set_encpolicy $k" /mnt/edir + echo contents > /mnt/edir/file + chattr +i /mnt/edir/file + chattr -i /mnt/edir/file + +With the bug, the following errors occur on the last command: + + [ 18.081559] fscrypt (ubifs, inode 67): Inconsistent encryption context (parent directory: 65) + chattr: Operation not permitted while reading flags on /mnt/edir/file + +Fixes: d475a507457b ("ubifs: Add skeleton for fscrypto") +Cc: # v4.10+ +Signed-off-by: Eric Biggers +Signed-off-by: Richard Weinberger +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ubifs/ioctl.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/fs/ubifs/ioctl.c ++++ b/fs/ubifs/ioctl.c +@@ -132,7 +132,8 @@ static int setflags(struct inode *inode, + } + } + +- ui->flags = ioctl2ubifs(flags); ++ ui->flags &= ~ioctl2ubifs(UBIFS_SUPPORTED_IOCTL_FLAGS); ++ ui->flags |= ioctl2ubifs(flags); + ubifs_set_inode_flags(inode); + inode->i_ctime = current_time(inode); + release = ui->dirty; diff --git a/queue-4.19/ubifs-reject-unsupported-ioctl-flags-explicitly.patch b/queue-4.19/ubifs-reject-unsupported-ioctl-flags-explicitly.patch new file mode 100644 index 00000000000..7539a33278a --- /dev/null +++ b/queue-4.19/ubifs-reject-unsupported-ioctl-flags-explicitly.patch @@ -0,0 +1,47 @@ +From 2fe8b2d5578d7d142982e3bf62e4c0caf8b8fe02 Mon Sep 17 00:00:00 2001 +From: Hou Tao +Date: Sat, 9 Feb 2019 16:54:20 +0800 +Subject: ubifs: Reject unsupported ioctl flags explicitly + +From: Hou Tao + +commit 2fe8b2d5578d7d142982e3bf62e4c0caf8b8fe02 upstream. + +Reject unsupported ioctl flags explicitly, so the following command +on a regular ubifs file will fail: + chattr +d ubifs_file + +And xfstests generic/424 will pass. + +Signed-off-by: Hou Tao +Signed-off-by: Richard Weinberger +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ubifs/ioctl.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/fs/ubifs/ioctl.c ++++ b/fs/ubifs/ioctl.c +@@ -28,6 +28,11 @@ + #include + #include "ubifs.h" + ++/* Need to be kept consistent with checked flags in ioctl2ubifs() */ ++#define UBIFS_SUPPORTED_IOCTL_FLAGS \ ++ (FS_COMPR_FL | FS_SYNC_FL | FS_APPEND_FL | \ ++ FS_IMMUTABLE_FL | FS_DIRSYNC_FL) ++ + /** + * ubifs_set_inode_flags - set VFS inode flags. + * @inode: VFS inode to set flags for +@@ -169,6 +174,9 @@ long ubifs_ioctl(struct file *file, unsi + if (get_user(flags, (int __user *) arg)) + return -EFAULT; + ++ if (flags & ~UBIFS_SUPPORTED_IOCTL_FLAGS) ++ return -EOPNOTSUPP; ++ + if (!S_ISDIR(inode->i_mode)) + flags &= ~FS_DIRSYNC_FL; +