diff options
author | Paul Gortmaker <paul.gortmaker@windriver.com> | 2017-06-10 23:10:12 -0400 |
---|---|---|
committer | Paul Gortmaker <paul.gortmaker@windriver.com> | 2017-06-10 23:10:12 -0400 |
commit | 5505ce43e6acf9e5c6742085b77e1c2f1fc866d5 (patch) | |
tree | 16f7597d2e113725fe0bd0546274fff76053f25b | |
parent | de296dd3ed860c818d4c18a8cb635ce93b2e1e32 (diff) | |
download | longterm-queue-4.8-5505ce43e6acf9e5c6742085b77e1c2f1fc866d5.tar.gz |
raw import of mainline commits used in 4.9.22 --> 4.9.24
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
232 files changed, 18288 insertions, 0 deletions
diff --git a/queue/ACPI-EC-Use-busy-polling-mode-when-GPE-is-not-enable.patch b/queue/ACPI-EC-Use-busy-polling-mode-when-GPE-is-not-enable.patch new file mode 100644 index 0000000..0305a24 --- /dev/null +++ b/queue/ACPI-EC-Use-busy-polling-mode-when-GPE-is-not-enable.patch @@ -0,0 +1,163 @@ +From c3a696b6e8f8f75f9f75e556a9f9f6472eae2655 Mon Sep 17 00:00:00 2001 +From: Lv Zheng <lv.zheng@intel.com> +Date: Fri, 20 Jan 2017 16:42:48 +0800 +Subject: [PATCH] ACPI / EC: Use busy polling mode when GPE is not enabled + +commit c3a696b6e8f8f75f9f75e556a9f9f6472eae2655 upstream. + +When GPE is not enabled, it is not efficient to use the wait polling mode +as it introduces an unexpected scheduler delay. +So before the GPE handler is installed, this patch uses busy polling mode +for all EC(s) and the logic can be applied to non boot EC(s) during the +suspend/resume process. + +Link: https://bugzilla.kernel.org/show_bug.cgi?id=191561 +Tested-by: Jakobus Schurz <jakobus.schurz@gmail.com> +Tested-by: Chen Yu <yu.c.chen@intel.com> +Signed-off-by: Lv Zheng <lv.zheng@intel.com> +Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> + +diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c +index 6a32cd4ec9da..c24235d8fb52 100644 +--- a/drivers/acpi/ec.c ++++ b/drivers/acpi/ec.c +@@ -704,12 +704,12 @@ static void start_transaction(struct acpi_ec *ec) + + static int ec_guard(struct acpi_ec *ec) + { +- unsigned long guard = usecs_to_jiffies(ec_polling_guard); ++ unsigned long guard = usecs_to_jiffies(ec->polling_guard); + unsigned long timeout = ec->timestamp + guard; + + /* Ensure guarding period before polling EC status */ + do { +- if (ec_busy_polling) { ++ if (ec->busy_polling) { + /* Perform busy polling */ + if (ec_transaction_completed(ec)) + return 0; +@@ -973,6 +973,28 @@ static void acpi_ec_stop(struct acpi_ec *ec, bool suspending) + spin_unlock_irqrestore(&ec->lock, flags); + } + ++static void acpi_ec_enter_noirq(struct acpi_ec *ec) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&ec->lock, flags); ++ ec->busy_polling = true; ++ ec->polling_guard = 0; ++ ec_log_drv("interrupt blocked"); ++ spin_unlock_irqrestore(&ec->lock, flags); ++} ++ ++static void acpi_ec_leave_noirq(struct acpi_ec *ec) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&ec->lock, flags); ++ ec->busy_polling = ec_busy_polling; ++ ec->polling_guard = ec_polling_guard; ++ ec_log_drv("interrupt unblocked"); ++ spin_unlock_irqrestore(&ec->lock, flags); ++} ++ + void acpi_ec_block_transactions(void) + { + struct acpi_ec *ec = first_ec; +@@ -1253,7 +1275,7 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address, + if (function != ACPI_READ && function != ACPI_WRITE) + return AE_BAD_PARAMETER; + +- if (ec_busy_polling || bits > 8) ++ if (ec->busy_polling || bits > 8) + acpi_ec_burst_enable(ec); + + for (i = 0; i < bytes; ++i, ++address, ++value) +@@ -1261,7 +1283,7 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address, + acpi_ec_read(ec, address, value) : + acpi_ec_write(ec, address, *value); + +- if (ec_busy_polling || bits > 8) ++ if (ec->busy_polling || bits > 8) + acpi_ec_burst_disable(ec); + + switch (result) { +@@ -1304,6 +1326,8 @@ static struct acpi_ec *acpi_ec_alloc(void) + spin_lock_init(&ec->lock); + INIT_WORK(&ec->work, acpi_ec_event_handler); + ec->timestamp = jiffies; ++ ec->busy_polling = true; ++ ec->polling_guard = 0; + return ec; + } + +@@ -1365,6 +1389,7 @@ static int ec_install_handlers(struct acpi_ec *ec, bool handle_events) + acpi_ec_start(ec, false); + + if (!test_bit(EC_FLAGS_EC_HANDLER_INSTALLED, &ec->flags)) { ++ acpi_ec_enter_noirq(ec); + status = acpi_install_address_space_handler(ec->handle, + ACPI_ADR_SPACE_EC, + &acpi_ec_space_handler, +@@ -1404,6 +1429,7 @@ static int ec_install_handlers(struct acpi_ec *ec, bool handle_events) + /* This is not fatal as we can poll EC events */ + if (ACPI_SUCCESS(status)) { + set_bit(EC_FLAGS_GPE_HANDLER_INSTALLED, &ec->flags); ++ acpi_ec_leave_noirq(ec); + if (test_bit(EC_FLAGS_STARTED, &ec->flags) && + ec->reference_count >= 1) + acpi_ec_enable_gpe(ec, true); +@@ -1786,34 +1812,6 @@ error: + } + + #ifdef CONFIG_PM_SLEEP +-static void acpi_ec_enter_noirq(struct acpi_ec *ec) +-{ +- unsigned long flags; +- +- if (ec == first_ec) { +- spin_lock_irqsave(&ec->lock, flags); +- ec->saved_busy_polling = ec_busy_polling; +- ec->saved_polling_guard = ec_polling_guard; +- ec_busy_polling = true; +- ec_polling_guard = 0; +- ec_log_drv("interrupt blocked"); +- spin_unlock_irqrestore(&ec->lock, flags); +- } +-} +- +-static void acpi_ec_leave_noirq(struct acpi_ec *ec) +-{ +- unsigned long flags; +- +- if (ec == first_ec) { +- spin_lock_irqsave(&ec->lock, flags); +- ec_busy_polling = ec->saved_busy_polling; +- ec_polling_guard = ec->saved_polling_guard; +- ec_log_drv("interrupt unblocked"); +- spin_unlock_irqrestore(&ec->lock, flags); +- } +-} +- + static int acpi_ec_suspend_noirq(struct device *dev) + { + struct acpi_ec *ec = +diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h +index 0c452265c111..219b90bc0922 100644 +--- a/drivers/acpi/internal.h ++++ b/drivers/acpi/internal.h +@@ -172,8 +172,8 @@ struct acpi_ec { + struct work_struct work; + unsigned long timestamp; + unsigned long nr_pending_queries; +- bool saved_busy_polling; +- unsigned int saved_polling_guard; ++ bool busy_polling; ++ unsigned int polling_guard; + }; + + extern struct acpi_ec *first_ec; +-- +2.12.0 + diff --git a/queue/ACPI-button-Change-default-behavior-to-lid_init_stat.patch b/queue/ACPI-button-Change-default-behavior-to-lid_init_stat.patch new file mode 100644 index 0000000..86575d2 --- /dev/null +++ b/queue/ACPI-button-Change-default-behavior-to-lid_init_stat.patch @@ -0,0 +1,117 @@ +From 77e9a4aa9de10cc1418bf9a892366988802a8025 Mon Sep 17 00:00:00 2001 +From: Lv Zheng <lv.zheng@intel.com> +Date: Thu, 12 Jan 2017 15:47:34 +0800 +Subject: [PATCH] ACPI / button: Change default behavior to lid_init_state=open + +commit 77e9a4aa9de10cc1418bf9a892366988802a8025 upstream. + +More and more platforms need the button.lid_init_state=open quirk. This +patch sets it the default behavior. + +If a platform doesn't send lid open event or lid open event is lost due to +the underlying system problems, then we can compare various combinations: +1. systemd/acpid is used to suspend system or not, systemd has a special + logic forcing open event after resuming; +2. _LID returns a cached value or not. + +The result is as follows: + + 1. lid_init_state=method + 1. cached + 1. resumed by lid: + (x) event=close + (x) systemd=suspends again + (x) acpid=suspends again + (x) state=close + 2. resumed by other: + (o) event=close + (x) systemd=suspends again + (x) acpid=suspends again + (o) state=close + 2. non-cached + 1. resumed by lid: + (o) event=open + (o) systemd=resumes + (o) acpid=resumes + (o) state=open + 2. resumed by other: + (o) event=close + (x) systemd=suspends again + (x) acpid=suspends again + (o) state=close + 2. lid_init_state=open + 1. cached + 1. resumed by lid: + (o) event=open + (o) systemd=resumes + (o) acpid=resumes + (x) state=close + 2. resumed by other: + (x) event=open + (o) systemd=resumes + (o) acpid=resumes + (o) state=close + 2. non-cached + 1. resumed by lid: + (o) event=open + (o) systemd=resumes + (o) acpid=resumes + (o) state=open + 2. resumed by other: + (x) event=open + (o) systemd=resumes + (o) acpid=resumes + (o) state=close + 3. lid_init_state=ignore + 1. cached + 1. resumed by lid: + (o) event=none + (x) systemd=suspends again + (o) acpid=resumes + (x) state=close + 2. resumed by other: + (o) event=none + (x) systemd=suspends again + (o) acpid=resumes + (o) state=close + 2. non-cached + 1. resumed by lid: + (o) event=none + (x) systemd=suspends again + (o) acpid=resumes + (o) state=open + 2. resumed by other: + (o) event=none + (x) systemd=suspends again + (o) acpid=resumes + (o) state=close + +As a conclusion: + 1. With systemd changed, lid_init_state=ignore has only one problem and the + problem comes from an underlying issue, not userspace and kernel lid + handling. + 2. Without systemd changed, lid_init_state=open can be the default + behavior as the pass ratio is not much worse than lid_init_state=ignore. + 3. lid_init_state=method is buggy, we can have a separate patch to make it + deprectated. + +Link: https://bugzilla.kernel.org/show_bug.cgi?id=187271 +Signed-off-by: Lv Zheng <lv.zheng@intel.com> +Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> + +diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c +index e19f530f1083..6d5a8c1d3132 100644 +--- a/drivers/acpi/button.c ++++ b/drivers/acpi/button.c +@@ -113,7 +113,7 @@ struct acpi_button { + + static BLOCKING_NOTIFIER_HEAD(acpi_lid_notifier); + static struct acpi_device *lid_device; +-static u8 lid_init_state = ACPI_BUTTON_LID_INIT_METHOD; ++static u8 lid_init_state = ACPI_BUTTON_LID_INIT_OPEN; + + static unsigned long lid_report_interval __read_mostly = 500; + module_param(lid_report_interval, ulong, 0644); +-- +2.12.0 + diff --git a/queue/ACPI-gpio-do-not-fall-back-to-parsing-_CRS-when-we-g.patch b/queue/ACPI-gpio-do-not-fall-back-to-parsing-_CRS-when-we-g.patch new file mode 100644 index 0000000..9ee7b69 --- /dev/null +++ b/queue/ACPI-gpio-do-not-fall-back-to-parsing-_CRS-when-we-g.patch @@ -0,0 +1,37 @@ +From 693bdaa164b40b7aa6018b98af6f7e40dbd52457 Mon Sep 17 00:00:00 2001 +From: Dmitry Torokhov <dmitry.torokhov@gmail.com> +Date: Thu, 23 Mar 2017 13:21:38 -0700 +Subject: [PATCH] ACPI / gpio: do not fall back to parsing _CRS when we get a + deferral + +commit 693bdaa164b40b7aa6018b98af6f7e40dbd52457 upstream. + +If, while locating GPIOs by name, we get probe deferral, we should +immediately report it to caller rather than trying to fall back to parsing +unnamed GPIOs from _CRS block. + +Cc: stable@vger.kernel.org +Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> +Acked-by: Mika Westerberg <mika.westerberg@linux.intel.com> +Acked-and-Tested-by: Hans de Goede <hdegoede@redhat.com> +Signed-off-by: Linus Walleij <linus.walleij@linaro.org> + +diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c +index 8e318f449d23..2bd683e2be02 100644 +--- a/drivers/gpio/gpiolib-acpi.c ++++ b/drivers/gpio/gpiolib-acpi.c +@@ -577,8 +577,10 @@ struct gpio_desc *acpi_find_gpio(struct device *dev, + } + + desc = acpi_get_gpiod_by_index(adev, propname, idx, &info); +- if (!IS_ERR(desc) || (PTR_ERR(desc) == -EPROBE_DEFER)) ++ if (!IS_ERR(desc)) + break; ++ if (PTR_ERR(desc) == -EPROBE_DEFER) ++ return ERR_CAST(desc); + } + + /* Then from plain _CRS GPIOs */ +-- +2.12.0 + diff --git a/queue/ACPI-save-NVS-memory-for-Lenovo-G50-45.patch b/queue/ACPI-save-NVS-memory-for-Lenovo-G50-45.patch new file mode 100644 index 0000000..1c83145 --- /dev/null +++ b/queue/ACPI-save-NVS-memory-for-Lenovo-G50-45.patch @@ -0,0 +1,61 @@ +From cbc00c1310d34139a63946482b40a6b261a03fb9 Mon Sep 17 00:00:00 2001 +From: Zhang Rui <rui.zhang@intel.com> +Date: Mon, 16 Jan 2017 10:55:45 +0800 +Subject: [PATCH] ACPI: save NVS memory for Lenovo G50-45 + +commit cbc00c1310d34139a63946482b40a6b261a03fb9 upstream. + +In commit 821d6f0359b0 (ACPI / sleep: Do not save NVS for new machines to +accelerate S3), to optimize S3 suspend/resume speed, code is introduced +to ignore NVS memory saving during S3 for all the platforms later than +2012. + +But, Lenovo G50-45, a platform released in 2015, still needs NVS memory +saving during S3. A quirk is introduced for this platform. + +Link: https://bugzilla.kernel.org/show_bug.cgi?id=189431 +Tested-by: Przemek <soprwa@gmail.com> +Signed-off-by: Zhang Rui <rui.zhang@intel.com> +[ rjw: Drop unnecessary code ] +Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> + +diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c +index 54abb26b7366..a4327af676fe 100644 +--- a/drivers/acpi/sleep.c ++++ b/drivers/acpi/sleep.c +@@ -130,6 +130,12 @@ void __init acpi_nvs_nosave_s3(void) + nvs_nosave_s3 = true; + } + ++static int __init init_nvs_save_s3(const struct dmi_system_id *d) ++{ ++ nvs_nosave_s3 = false; ++ return 0; ++} ++ + /* + * ACPI 1.0 wants us to execute _PTS before suspending devices, so we allow the + * user to request that behavior by using the 'acpi_old_suspend_ordering' +@@ -324,6 +330,19 @@ static struct dmi_system_id acpisleep_dmi_table[] __initdata = { + DMI_MATCH(DMI_PRODUCT_NAME, "K54HR"), + }, + }, ++ /* ++ * https://bugzilla.kernel.org/show_bug.cgi?id=189431 ++ * Lenovo G50-45 is a platform later than 2012, but needs nvs memory ++ * saving during S3. ++ */ ++ { ++ .callback = init_nvs_save_s3, ++ .ident = "Lenovo G50-45", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "80E3"), ++ }, ++ }, + {}, + }; + +-- +2.12.0 + diff --git a/queue/ACPI-scan-Set-the-visited-flag-for-all-enumerated-de.patch b/queue/ACPI-scan-Set-the-visited-flag-for-all-enumerated-de.patch new file mode 100644 index 0000000..670f62a --- /dev/null +++ b/queue/ACPI-scan-Set-the-visited-flag-for-all-enumerated-de.patch @@ -0,0 +1,54 @@ +From f406270bf73d71ea7b35ee3f7a08a44f6594c9b1 Mon Sep 17 00:00:00 2001 +From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com> +Date: Tue, 11 Apr 2017 00:23:42 +0200 +Subject: [PATCH] ACPI / scan: Set the visited flag for all enumerated devices + +commit f406270bf73d71ea7b35ee3f7a08a44f6594c9b1 upstream. + +Commit 10c7e20b2ff3 (ACPI / scan: fix enumeration (visited) flags for +bus rescans) attempted to fix a problem with ACPI-based enumerateion +of I2C/SPI devices, but it forgot to ensure that the visited flag +will be set for all of the other enumerated devices, so fix that. + +Fixes: 10c7e20b2ff3 (ACPI / scan: fix enumeration (visited) flags for bus rescans) +Link: https://bugzilla.kernel.org/show_bug.cgi?id=194885 +Reported-and-tested-by: Kevin Locke <kevin@kevinlocke.name> +Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> +Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com> +Cc: 4.8+ <stable@vger.kernel.org> # 4.8+ + +diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c +index 192691880d55..2433569b02ef 100644 +--- a/drivers/acpi/scan.c ++++ b/drivers/acpi/scan.c +@@ -1857,15 +1857,20 @@ static void acpi_bus_attach(struct acpi_device *device) + return; + + device->flags.match_driver = true; +- if (!ret) { +- ret = device_attach(&device->dev); +- if (ret < 0) +- return; +- +- if (!ret && device->pnp.type.platform_id) +- acpi_default_enumeration(device); ++ if (ret > 0) { ++ acpi_device_set_enumerated(device); ++ goto ok; + } + ++ ret = device_attach(&device->dev); ++ if (ret < 0) ++ return; ++ ++ if (ret > 0 || !device->pnp.type.platform_id) ++ acpi_device_set_enumerated(device); ++ else ++ acpi_default_enumeration(device); ++ + ok: + list_for_each_entry(child, &device->children, node) + acpi_bus_attach(child); +-- +2.12.0 + diff --git a/queue/ACPI-sysfs-Provide-quirk-mechanism-to-prevent-GPE-fl.patch b/queue/ACPI-sysfs-Provide-quirk-mechanism-to-prevent-GPE-fl.patch new file mode 100644 index 0000000..12c1541 --- /dev/null +++ b/queue/ACPI-sysfs-Provide-quirk-mechanism-to-prevent-GPE-fl.patch @@ -0,0 +1,148 @@ +From 9c4aa1eecb48cfac18ed5e3aca9d9ae58fbafc11 Mon Sep 17 00:00:00 2001 +From: Lv Zheng <lv.zheng@intel.com> +Date: Fri, 16 Dec 2016 12:07:57 +0800 +Subject: [PATCH] ACPI / sysfs: Provide quirk mechanism to prevent GPE flooding + +commit 9c4aa1eecb48cfac18ed5e3aca9d9ae58fbafc11 upstream. + +Sometimes, the users may require a quirk to be provided from ACPI subsystem +core to prevent a GPE from flooding. +Normally, if a GPE cannot be dispatched, ACPICA core automatically prevents +the GPE from firing. But there are cases the GPE is dispatched by _Lxx/_Exx +provided via AML table, and OSPM is lacking of the knowledge to get +_Lxx/_Exx correctly executed to handle the GPE, thus the GPE flooding may +still occur. + +The existing quirk mechanism can be enabled/disabled using the following +commands to prevent such kind of GPE flooding during runtime: + # echo mask > /sys/firmware/acpi/interrupts/gpe00 + # echo unmask > /sys/firmware/acpi/interrupts/gpe00 +To avoid GPE flooding during boot, we need a boot stage mechanism. + +This patch provides such a boot stage quirk mechanism to stop this kind of +GPE flooding. This patch doesn't fix any feature gap but since the new +feature gaps could be found in the future endlessly, and can disappear if +the feature gaps are filled, providing a boot parameter rather than a DMI +table should suffice. + +Link: https://bugzilla.kernel.org/show_bug.cgi?id=53071 +Link: https://bugzilla.kernel.org/show_bug.cgi?id=117481 +Link: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/887793 +Signed-off-by: Lv Zheng <lv.zheng@intel.com> +Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> + +diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt +index 21e2d8863705..d1eec5ed1134 100644 +--- a/Documentation/admin-guide/kernel-parameters.txt ++++ b/Documentation/admin-guide/kernel-parameters.txt +@@ -106,6 +106,16 @@ + use by PCI + Format: <irq>,<irq>... + ++ acpi_mask_gpe= [HW,ACPI] ++ Due to the existence of _Lxx/_Exx, some GPEs triggered ++ by unsupported hardware/firmware features can result in ++ GPE floodings that cannot be automatically disabled by ++ the GPE dispatcher. ++ This facility can be used to prevent such uncontrolled ++ GPE floodings. ++ Format: <int> ++ Support masking of GPEs numbered from 0x00 to 0x7f. ++ + acpi_no_auto_serialize [HW,ACPI] + Disable auto-serialization of AML methods + AML control methods that contain the opcodes to create +diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h +index 1b41a2739dac..0c452265c111 100644 +--- a/drivers/acpi/internal.h ++++ b/drivers/acpi/internal.h +@@ -37,6 +37,7 @@ void acpi_amba_init(void); + static inline void acpi_amba_init(void) {} + #endif + int acpi_sysfs_init(void); ++void acpi_gpe_apply_masked_gpes(void); + void acpi_container_init(void); + void acpi_memory_hotplug_init(void); + #ifdef CONFIG_ACPI_HOTPLUG_IOAPIC +diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c +index 45dec874ea55..192691880d55 100644 +--- a/drivers/acpi/scan.c ++++ b/drivers/acpi/scan.c +@@ -2074,6 +2074,7 @@ int __init acpi_scan_init(void) + } + } + ++ acpi_gpe_apply_masked_gpes(); + acpi_update_all_gpes(); + acpi_ec_ecdt_start(); + +diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c +index 703c26e7022c..cf05ae973381 100644 +--- a/drivers/acpi/sysfs.c ++++ b/drivers/acpi/sysfs.c +@@ -708,6 +708,62 @@ end: + return result ? result : size; + } + ++/* ++ * A Quirk Mechanism for GPE Flooding Prevention: ++ * ++ * Quirks may be needed to prevent GPE flooding on a specific GPE. The ++ * flooding typically cannot be detected and automatically prevented by ++ * ACPI_GPE_DISPATCH_NONE check because there is a _Lxx/_Exx prepared in ++ * the AML tables. This normally indicates a feature gap in Linux, thus ++ * instead of providing endless quirk tables, we provide a boot parameter ++ * for those who want this quirk. For example, if the users want to prevent ++ * the GPE flooding for GPE 00, they need to specify the following boot ++ * parameter: ++ * acpi_mask_gpe=0x00 ++ * The masking status can be modified by the following runtime controlling ++ * interface: ++ * echo unmask > /sys/firmware/acpi/interrupts/gpe00 ++ */ ++ ++/* ++ * Currently, the GPE flooding prevention only supports to mask the GPEs ++ * numbered from 00 to 7f. ++ */ ++#define ACPI_MASKABLE_GPE_MAX 0x80 ++ ++static u64 __initdata acpi_masked_gpes; ++ ++static int __init acpi_gpe_set_masked_gpes(char *val) ++{ ++ u8 gpe; ++ ++ if (kstrtou8(val, 0, &gpe) || gpe > ACPI_MASKABLE_GPE_MAX) ++ return -EINVAL; ++ acpi_masked_gpes |= ((u64)1<<gpe); ++ ++ return 1; ++} ++__setup("acpi_mask_gpe=", acpi_gpe_set_masked_gpes); ++ ++void __init acpi_gpe_apply_masked_gpes(void) ++{ ++ acpi_handle handle; ++ acpi_status status; ++ u8 gpe; ++ ++ for (gpe = 0; ++ gpe < min_t(u8, ACPI_MASKABLE_GPE_MAX, acpi_current_gpe_count); ++ gpe++) { ++ if (acpi_masked_gpes & ((u64)1<<gpe)) { ++ status = acpi_get_gpe_device(gpe, &handle); ++ if (ACPI_SUCCESS(status)) { ++ pr_info("Masking GPE 0x%x.\n", gpe); ++ (void)acpi_mask_gpe(handle, gpe, TRUE); ++ } ++ } ++ } ++} ++ + void acpi_irq_stats_init(void) + { + acpi_status status; +-- +2.12.0 + diff --git a/queue/ALSA-usb-audio-Add-native-DSD-support-for-TEAC-501-5.patch b/queue/ALSA-usb-audio-Add-native-DSD-support-for-TEAC-501-5.patch new file mode 100644 index 0000000..7a7496b --- /dev/null +++ b/queue/ALSA-usb-audio-Add-native-DSD-support-for-TEAC-501-5.patch @@ -0,0 +1,85 @@ +From 7f38ca047b0cb54df7f6d9e4110e292e45dba6ad Mon Sep 17 00:00:00 2001 +From: Nobutaka Okabe <nob77413@gmail.com> +Date: Tue, 13 Dec 2016 01:24:08 +0900 +Subject: [PATCH] ALSA: usb-audio: Add native DSD support for TEAC 501/503 DAC + +commit 7f38ca047b0cb54df7f6d9e4110e292e45dba6ad upstream. + +This patch adds native DSD support for the following devices. + +- TEAC NT-503 +- TEAC UD-503 +- TEAC UD-501 + +(1) Add quirks for native DSD support for TEAC devices. +(2) A specific vendor command is needed to switch between PCM/DOP and + DSD mode, same as Denon/Marantz devices. + +Signed-off-by: Nobutaka Okabe <nob77413@gmail.com> +Signed-off-by: Takashi Iwai <tiwai@suse.de> + +diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c +index 2782155ae3ce..b3fd2382fdd9 100644 +--- a/sound/usb/quirks.c ++++ b/sound/usb/quirks.c +@@ -1165,6 +1165,18 @@ static bool is_marantz_denon_dac(unsigned int id) + return false; + } + ++/* TEAC UD-501/UD-503/NT-503 USB DACs need a vendor cmd to switch ++ * between PCM/DOP and native DSD mode ++ */ ++static bool is_teac_50X_dac(unsigned int id) ++{ ++ switch (id) { ++ case USB_ID(0x0644, 0x8043): /* TEAC UD-501/UD-503/NT-503 */ ++ return true; ++ } ++ return false; ++} ++ + int snd_usb_select_mode_quirk(struct snd_usb_substream *subs, + struct audioformat *fmt) + { +@@ -1192,6 +1204,26 @@ int snd_usb_select_mode_quirk(struct snd_usb_substream *subs, + break; + } + mdelay(20); ++ } else if (is_teac_50X_dac(subs->stream->chip->usb_id)) { ++ /* Vendor mode switch cmd is required. */ ++ switch (fmt->altsetting) { ++ case 3: /* DSD mode (DSD_U32) requested */ ++ err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), 0, ++ USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_INTERFACE, ++ 1, 1, NULL, 0); ++ if (err < 0) ++ return err; ++ break; ++ ++ case 2: /* PCM or DOP mode (S32) requested */ ++ case 1: /* PCM mode (S16) requested */ ++ err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), 0, ++ USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_INTERFACE, ++ 0, 1, NULL, 0); ++ if (err < 0) ++ return err; ++ break; ++ } + } + return 0; + } +@@ -1337,5 +1369,11 @@ u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip, + return SNDRV_PCM_FMTBIT_DSD_U32_BE; + } + ++ /* TEAC devices with USB DAC functionality */ ++ if (is_teac_50X_dac(chip->usb_id)) { ++ if (fp->altsetting == 3) ++ return SNDRV_PCM_FMTBIT_DSD_U32_BE; ++ } ++ + return 0; + } +-- +2.12.0 + diff --git a/queue/ALSA-usb-audio-add-implicit-fb-quirk-for-Axe-Fx-II.patch b/queue/ALSA-usb-audio-add-implicit-fb-quirk-for-Axe-Fx-II.patch new file mode 100644 index 0000000..0ece5ed --- /dev/null +++ b/queue/ALSA-usb-audio-add-implicit-fb-quirk-for-Axe-Fx-II.patch @@ -0,0 +1,38 @@ +From 17f08b0d9aafccdb10038ab6dbd9ddb6433c13e2 Mon Sep 17 00:00:00 2001 +From: Alberto Aguirre <albaguirre@gmail.com> +Date: Thu, 8 Dec 2016 00:36:48 -0600 +Subject: [PATCH] ALSA: usb-audio: add implicit fb quirk for Axe-Fx II + +commit 17f08b0d9aafccdb10038ab6dbd9ddb6433c13e2 upstream. + +The Axe-Fx II implicit feedback end point and the data sync endpoint +are in different interface descriptors. Add quirk to ensure a sync +endpoint is properly configured. + +Signed-off-by: Alberto Aguirre <albaguirre@gmail.com> +Signed-off-by: Takashi Iwai <tiwai@suse.de> + +diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c +index a522c9af1f34..34c6d4f2c0b6 100644 +--- a/sound/usb/pcm.c ++++ b/sound/usb/pcm.c +@@ -348,6 +348,16 @@ static int set_sync_ep_implicit_fb_quirk(struct snd_usb_substream *subs, + + alts = &iface->altsetting[1]; + goto add_sync_ep; ++ case USB_ID(0x2466, 0x8003): ++ ep = 0x86; ++ iface = usb_ifnum_to_if(dev, 2); ++ ++ if (!iface || iface->num_altsetting == 0) ++ return -EINVAL; ++ ++ alts = &iface->altsetting[1]; ++ goto add_sync_ep; ++ + } + if (attr == USB_ENDPOINT_SYNC_ASYNC && + altsd->bInterfaceClass == USB_CLASS_VENDOR_SPEC && +-- +2.12.0 + diff --git a/queue/ARM-davinci-PM-support-da8xx-DT-platforms.patch b/queue/ARM-davinci-PM-support-da8xx-DT-platforms.patch new file mode 100644 index 0000000..a923cc6 --- /dev/null +++ b/queue/ARM-davinci-PM-support-da8xx-DT-platforms.patch @@ -0,0 +1,27 @@ +From 7e431af8fa0b9ed9d74378c99514856211cb9db8 Mon Sep 17 00:00:00 2001 +From: Kevin Hilman <khilman@baylibre.com> +Date: Tue, 15 Nov 2016 11:54:21 -0800 +Subject: [PATCH] ARM: davinci: PM: support da8xx DT platforms + +commit 7e431af8fa0b9ed9d74378c99514856211cb9db8 upstream. + +Add PM support for DA850 device-tree boot. + +Signed-off-by: Kevin Hilman <khilman@baylibre.com> +Signed-off-by: Sekhar Nori <nsekhar@ti.com> + +diff --git a/arch/arm/mach-davinci/da8xx-dt.c b/arch/arm/mach-davinci/da8xx-dt.c +index 92ae093a2120..e87ff2b66f12 100644 +--- a/arch/arm/mach-davinci/da8xx-dt.c ++++ b/arch/arm/mach-davinci/da8xx-dt.c +@@ -61,6 +61,7 @@ static void __init da850_init_machine(void) + __func__, ret); + + of_platform_default_populate(NULL, da850_auxdata_lookup, NULL); ++ davinci_pm_init(); + } + + static const char *const da850_boards_compat[] __initconst = { +-- +2.12.0 + diff --git a/queue/ARM-dts-STiH407-family-set-snps-dis_u3_susphy_quirk.patch b/queue/ARM-dts-STiH407-family-set-snps-dis_u3_susphy_quirk.patch new file mode 100644 index 0000000..1c2cae9 --- /dev/null +++ b/queue/ARM-dts-STiH407-family-set-snps-dis_u3_susphy_quirk.patch @@ -0,0 +1,35 @@ +From 8413299cb3933dade6186bbee8363f190032107e Mon Sep 17 00:00:00 2001 +From: Patrice Chotard <patrice.chotard@st.com> +Date: Fri, 27 Jan 2017 15:45:11 +0100 +Subject: [PATCH] ARM: dts: STiH407-family: set snps,dis_u3_susphy_quirk + +commit 8413299cb3933dade6186bbee8363f190032107e upstream. + +Since v4.10-rc1, the following logs appears in loop : +[ 801.953836] usb usb6-port1: Cannot enable. Maybe the USB cable is bad? +[ 801.960455] xhci-hcd xhci-hcd.0.auto: Cannot set link state. +[ 801.966611] usb usb6-port1: cannot disable (err = -32) +[ 806.083772] usb usb6-port1: Cannot enable. Maybe the USB cable is bad? +[ 806.090370] xhci-hcd xhci-hcd.0.auto: Cannot set link state. +[ 806.096494] usb usb6-port1: cannot disable (err = -32) + +After analysis, xhci try to set link in U3 and returns an error. +Using snps,dis_u3_susphy_quirk fix this issue. + +Signed-off-by: Patrice Chotard <patrice.chotard@st.com> + +diff --git a/arch/arm/boot/dts/stih407-family.dtsi b/arch/arm/boot/dts/stih407-family.dtsi +index c8b2944e304a..ace97e8576db 100644 +--- a/arch/arm/boot/dts/stih407-family.dtsi ++++ b/arch/arm/boot/dts/stih407-family.dtsi +@@ -680,6 +680,7 @@ + phy-names = "usb2-phy", "usb3-phy"; + phys = <&usb2_picophy0>, + <&phy_port2 PHY_TYPE_USB3>; ++ snps,dis_u3_susphy_quirk; + }; + }; + +-- +2.12.0 + diff --git a/queue/ARM-smccc-Update-HVC-comment-to-describe-new-quirk-p.patch b/queue/ARM-smccc-Update-HVC-comment-to-describe-new-quirk-p.patch new file mode 100644 index 0000000..34476cf --- /dev/null +++ b/queue/ARM-smccc-Update-HVC-comment-to-describe-new-quirk-p.patch @@ -0,0 +1,30 @@ +From 3046ec674d441562c6bb3e4284cd866743042ef3 Mon Sep 17 00:00:00 2001 +From: Will Deacon <will.deacon@arm.com> +Date: Wed, 8 Feb 2017 14:54:12 +0000 +Subject: [PATCH] ARM: smccc: Update HVC comment to describe new quirk + parameter + +commit 3046ec674d441562c6bb3e4284cd866743042ef3 upstream. + +Commit 680a0873e193 ("arm: kernel: Add SMC structure parameter") added +a new "quirk" parameter to the SMC and HVC SMCCC backends, but only +updated the comment for the SMC version. This patch adds the new +paramater to the comment describing the HVC version too. + +Signed-off-by: Will Deacon <will.deacon@arm.com> + +diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h +index b67934164401..4c5bca38c653 100644 +--- a/include/linux/arm-smccc.h ++++ b/include/linux/arm-smccc.h +@@ -109,6 +109,7 @@ asmlinkage void __arm_smccc_smc(unsigned long a0, unsigned long a1, + * __arm_smccc_hvc() - make HVC calls + * @a0-a7: arguments passed in registers 0 to 7 + * @res: result values from registers 0 to 3 ++ * @quirk: points to an arm_smccc_quirk, or NULL when no quirks are required. + * + * This function is used to make HVC calls following SMC Calling + * Convention. The content of the supplied param are copied to registers 0 +-- +2.12.0 + diff --git a/queue/ASoC-Intel-Baytrail-add-quirk-for-Lenovo-Thinkpad-10.patch b/queue/ASoC-Intel-Baytrail-add-quirk-for-Lenovo-Thinkpad-10.patch new file mode 100644 index 0000000..3cc8246 --- /dev/null +++ b/queue/ASoC-Intel-Baytrail-add-quirk-for-Lenovo-Thinkpad-10.patch @@ -0,0 +1,86 @@ +From fd0138dc5d17c636477b371d99265c406437c583 Mon Sep 17 00:00:00 2001 +From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> +Date: Thu, 26 Jan 2017 14:09:35 -0600 +Subject: [PATCH] ASoC: Intel: Baytrail: add quirk for Lenovo Thinkpad 10 + +commit fd0138dc5d17c636477b371d99265c406437c583 upstream. + +the BIOS reports this codec as RT5640 but it's a rt5670. Use the +quirk mechanism to use the cht_bsw_rt5672 machine driver + +Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> +Signed-off-by: Mark Brown <broonie@kernel.org> + +diff --git a/sound/soc/intel/atom/sst/sst_acpi.c b/sound/soc/intel/atom/sst/sst_acpi.c +index 4c0b89ec42e0..8cc30dfbf87d 100644 +--- a/sound/soc/intel/atom/sst/sst_acpi.c ++++ b/sound/soc/intel/atom/sst/sst_acpi.c +@@ -400,6 +400,7 @@ static int sst_acpi_remove(struct platform_device *pdev) + static unsigned long cht_machine_id; + + #define CHT_SURFACE_MACH 1 ++#define BYT_THINKPAD_10 2 + + static int cht_surface_quirk_cb(const struct dmi_system_id *id) + { +@@ -407,6 +408,23 @@ static int cht_surface_quirk_cb(const struct dmi_system_id *id) + return 1; + } + ++static int byt_thinkpad10_quirk_cb(const struct dmi_system_id *id) ++{ ++ cht_machine_id = BYT_THINKPAD_10; ++ return 1; ++} ++ ++ ++static const struct dmi_system_id byt_table[] = { ++ { ++ .callback = byt_thinkpad10_quirk_cb, ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "20C3001VHH"), ++ }, ++ }, ++ { } ++}; + + static const struct dmi_system_id cht_table[] = { + { +@@ -424,6 +442,10 @@ static struct sst_acpi_mach cht_surface_mach = { + "10EC5640", "cht-bsw-rt5645", "intel/fw_sst_22a8.bin", "cht-bsw", NULL, + &chv_platform_data }; + ++static struct sst_acpi_mach byt_thinkpad_10 = { ++ "10EC5640", "cht-bsw-rt5672", "intel/fw_sst_0f28.bin", "cht-bsw", NULL, ++ &byt_rvp_platform_data }; ++ + static struct sst_acpi_mach *cht_quirk(void *arg) + { + struct sst_acpi_mach *mach = arg; +@@ -436,8 +458,21 @@ static struct sst_acpi_mach *cht_quirk(void *arg) + return mach; + } + ++static struct sst_acpi_mach *byt_quirk(void *arg) ++{ ++ struct sst_acpi_mach *mach = arg; ++ ++ dmi_check_system(byt_table); ++ ++ if (cht_machine_id == BYT_THINKPAD_10) ++ return &byt_thinkpad_10; ++ else ++ return mach; ++} ++ ++ + static struct sst_acpi_mach sst_acpi_bytcr[] = { +- {"10EC5640", "bytcr_rt5640", "intel/fw_sst_0f28.bin", "bytcr_rt5640", NULL, ++ {"10EC5640", "bytcr_rt5640", "intel/fw_sst_0f28.bin", "bytcr_rt5640", byt_quirk, + &byt_rvp_platform_data }, + {"10EC5642", "bytcr_rt5640", "intel/fw_sst_0f28.bin", "bytcr_rt5640", NULL, + &byt_rvp_platform_data }, +-- +2.12.0 + diff --git a/queue/ASoC-Intel-bytcr_rt5640-quirks-for-Insyde-devices.patch b/queue/ASoC-Intel-bytcr_rt5640-quirks-for-Insyde-devices.patch new file mode 100644 index 0000000..14d1aee --- /dev/null +++ b/queue/ASoC-Intel-bytcr_rt5640-quirks-for-Insyde-devices.patch @@ -0,0 +1,40 @@ +From 571800487837263e914ef68681e4ad6a57d49c7f Mon Sep 17 00:00:00 2001 +From: youling257 <youling257@gmail.com> +Date: Wed, 4 Jan 2017 15:44:53 -0600 +Subject: [PATCH] ASoC: Intel: bytcr_rt5640: quirks for Insyde devices + +commit 571800487837263e914ef68681e4ad6a57d49c7f upstream. + +There are literally dozens of Insyde devices with a different +name but with the same audio routing. Use a generic quirk to +match on vendor name only to avoid recurring edits of the +same thing. + +Signed-off-by: youling257 <youling257@gmail.com> +Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> +Signed-off-by: Mark Brown <broonie@kernel.org> + +diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c +index 507a86a5eafe..613e5286555a 100644 +--- a/sound/soc/intel/boards/bytcr_rt5640.c ++++ b/sound/soc/intel/boards/bytcr_rt5640.c +@@ -387,6 +387,16 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = { + BYT_RT5640_SSP0_AIF1), + + }, ++ { ++ .callback = byt_rt5640_quirk_cb, ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Insyde"), ++ }, ++ .driver_data = (unsigned long *)(BYT_RT5640_IN3_MAP | ++ BYT_RT5640_MCLK_EN | ++ BYT_RT5640_SSP0_AIF1), ++ ++ }, + {} + }; + +-- +2.12.0 + diff --git a/queue/ASoC-Intel-bytct_rt5640-change-default-capture-setti.patch b/queue/ASoC-Intel-bytct_rt5640-change-default-capture-setti.patch new file mode 100644 index 0000000..9f60576 --- /dev/null +++ b/queue/ASoC-Intel-bytct_rt5640-change-default-capture-setti.patch @@ -0,0 +1,46 @@ +From bf46241bee7bc3ec28703796f4fbd56085055fca Mon Sep 17 00:00:00 2001 +From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> +Date: Sat, 12 Nov 2016 18:07:46 -0600 +Subject: [PATCH] ASoC: Intel: bytct_rt5640: change default capture settings + +commit bf46241bee7bc3ec28703796f4fbd56085055fca upstream. + +Most Baytrail-CR devices use analog differential microphones, +modify capture default to avoid DMI quirks. Keep digital mics +for all other configurations. + +Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> +Signed-off-by: Mark Brown <broonie@kernel.org> + +diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c +index 32aeffc352ee..f9d73b55d2f7 100644 +--- a/sound/soc/intel/boards/bytcr_rt5640.c ++++ b/sound/soc/intel/boards/bytcr_rt5640.c +@@ -57,9 +57,7 @@ struct byt_rt5640_private { + struct clk *mclk; + }; + +-static unsigned long byt_rt5640_quirk = BYT_RT5640_DMIC1_MAP | +- BYT_RT5640_DMIC_EN | +- BYT_RT5640_MCLK_EN; ++static unsigned long byt_rt5640_quirk = BYT_RT5640_MCLK_EN; + + static void log_quirks(struct device *dev) + { +@@ -787,6 +785,13 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) + /* no BIOS indications, assume SSP0-AIF2 connection */ + byt_rt5640_quirk |= BYT_RT5640_SSP0_AIF2; + } ++ ++ /* change defaults for Baytrail-CR capture */ ++ byt_rt5640_quirk |= BYT_RT5640_IN1_MAP; ++ byt_rt5640_quirk |= BYT_RT5640_DIFF_MIC; ++ } else { ++ byt_rt5640_quirk |= (BYT_RT5640_DMIC1_MAP | ++ BYT_RT5640_DMIC_EN); + } + + /* check quirks before creating card */ +-- +2.12.0 + diff --git a/queue/ASoC-Intel-cht_bsw_rt5645-add-Baytrail-MCLK-support.patch b/queue/ASoC-Intel-cht_bsw_rt5645-add-Baytrail-MCLK-support.patch new file mode 100644 index 0000000..9392ac9 --- /dev/null +++ b/queue/ASoC-Intel-cht_bsw_rt5645-add-Baytrail-MCLK-support.patch @@ -0,0 +1,168 @@ +From a50477e55fff69e1028f25624ee9fc9182d59b1f Mon Sep 17 00:00:00 2001 +From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> +Date: Thu, 26 Jan 2017 14:09:38 -0600 +Subject: [PATCH] ASoC: Intel: cht_bsw_rt5645: add Baytrail MCLK support + +commit a50477e55fff69e1028f25624ee9fc9182d59b1f upstream. + +The existing code assumes a 19.2 MHz MCLK as the default +hardware configuration. This is valid for CherryTrail but +not for Baytrail. + +Add explicit MCLK configuration to set the 19.2 clock on/off +depending on DAPM events. + +This is a prerequisite step to enable devices with Baytrail +and RT5645 such as Asus X205TA + +Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> +Signed-off-by: Mark Brown <broonie@kernel.org> + +diff --git a/sound/soc/intel/boards/cht_bsw_rt5645.c b/sound/soc/intel/boards/cht_bsw_rt5645.c +index f504a0e18f91..468228b73b0b 100644 +--- a/sound/soc/intel/boards/cht_bsw_rt5645.c ++++ b/sound/soc/intel/boards/cht_bsw_rt5645.c +@@ -24,6 +24,9 @@ + #include <linux/acpi.h> + #include <linux/platform_device.h> + #include <linux/slab.h> ++#include <asm/cpu_device_id.h> ++#include <asm/platform_sst_audio.h> ++#include <linux/clk.h> + #include <sound/pcm.h> + #include <sound/pcm_params.h> + #include <sound/soc.h> +@@ -45,6 +48,7 @@ struct cht_mc_private { + struct snd_soc_jack jack; + struct cht_acpi_card *acpi_card; + char codec_name[16]; ++ struct clk *mclk; + }; + + static inline struct snd_soc_dai *cht_get_codec_dai(struct snd_soc_card *card) +@@ -65,6 +69,7 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w, + struct snd_soc_dapm_context *dapm = w->dapm; + struct snd_soc_card *card = dapm->card; + struct snd_soc_dai *codec_dai; ++ struct cht_mc_private *ctx = snd_soc_card_get_drvdata(card); + int ret; + + codec_dai = cht_get_codec_dai(card); +@@ -73,19 +78,30 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w, + return -EIO; + } + +- if (!SND_SOC_DAPM_EVENT_OFF(event)) +- return 0; ++ if (SND_SOC_DAPM_EVENT_ON(event)) { ++ if (ctx->mclk) { ++ ret = clk_prepare_enable(ctx->mclk); ++ if (ret < 0) { ++ dev_err(card->dev, ++ "could not configure MCLK state"); ++ return ret; ++ } ++ } ++ } else { ++ /* Set codec sysclk source to its internal clock because codec PLL will ++ * be off when idle and MCLK will also be off when codec is ++ * runtime suspended. Codec needs clock for jack detection and button ++ * press. MCLK is turned off with clock framework or ACPI. ++ */ ++ ret = snd_soc_dai_set_sysclk(codec_dai, RT5645_SCLK_S_RCCLK, ++ 48000 * 512, SND_SOC_CLOCK_IN); ++ if (ret < 0) { ++ dev_err(card->dev, "can't set codec sysclk: %d\n", ret); ++ return ret; ++ } + +- /* Set codec sysclk source to its internal clock because codec PLL will +- * be off when idle and MCLK will also be off by ACPI when codec is +- * runtime suspended. Codec needs clock for jack detection and button +- * press. +- */ +- ret = snd_soc_dai_set_sysclk(codec_dai, RT5645_SCLK_S_RCCLK, +- 0, SND_SOC_CLOCK_IN); +- if (ret < 0) { +- dev_err(card->dev, "can't set codec sysclk: %d\n", ret); +- return ret; ++ if (ctx->mclk) ++ clk_disable_unprepare(ctx->mclk); + } + + return 0; +@@ -97,7 +113,7 @@ static const struct snd_soc_dapm_widget cht_dapm_widgets[] = { + SND_SOC_DAPM_MIC("Int Mic", NULL), + SND_SOC_DAPM_SPK("Ext Spk", NULL), + SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0, +- platform_clock_control, SND_SOC_DAPM_POST_PMD), ++ platform_clock_control, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + }; + + static const struct snd_soc_dapm_route cht_rt5645_audio_map[] = { +@@ -225,6 +241,26 @@ static int cht_codec_init(struct snd_soc_pcm_runtime *runtime) + + rt5645_set_jack_detect(codec, &ctx->jack, &ctx->jack, &ctx->jack); + ++ if (ctx->mclk) { ++ /* ++ * The firmware might enable the clock at ++ * boot (this information may or may not ++ * be reflected in the enable clock register). ++ * To change the rate we must disable the clock ++ * first to cover these cases. Due to common ++ * clock framework restrictions that do not allow ++ * to disable a clock that has not been enabled, ++ * we need to enable the clock first. ++ */ ++ ret = clk_prepare_enable(ctx->mclk); ++ if (!ret) ++ clk_disable_unprepare(ctx->mclk); ++ ++ ret = clk_set_rate(ctx->mclk, CHT_PLAT_CLK_3_HZ); ++ ++ if (ret) ++ dev_err(runtime->dev, "unable to set MCLK rate\n"); ++ } + return ret; + } + +@@ -349,6 +385,18 @@ static struct cht_acpi_card snd_soc_cards[] = { + + static char cht_rt5640_codec_name[16]; /* i2c-<HID>:00 with HID being 8 chars */ + ++static bool is_valleyview(void) ++{ ++ static const struct x86_cpu_id cpu_ids[] = { ++ { X86_VENDOR_INTEL, 6, 55 }, /* Valleyview, Bay Trail */ ++ {} ++ }; ++ ++ if (!x86_match_cpu(cpu_ids)) ++ return false; ++ return true; ++} ++ + static int snd_cht_mc_probe(struct platform_device *pdev) + { + int ret_val = 0; +@@ -391,6 +439,16 @@ static int snd_cht_mc_probe(struct platform_device *pdev) + cht_dailink[dai_index].codec_name = cht_rt5640_codec_name; + } + ++ if (is_valleyview()) { ++ drv->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3"); ++ if (IS_ERR(drv->mclk)) { ++ dev_err(&pdev->dev, ++ "Failed to get MCLK from pmc_plt_clk_3: %ld\n", ++ PTR_ERR(drv->mclk)); ++ return PTR_ERR(drv->mclk); ++ } ++ } ++ + snd_soc_card_set_drvdata(card, drv); + ret_val = devm_snd_soc_register_card(&pdev->dev, card); + if (ret_val) { +-- +2.12.0 + diff --git a/queue/ASoC-Intel-cht_bsw_rt5645-harden-ACPI-device-detecti.patch b/queue/ASoC-Intel-cht_bsw_rt5645-harden-ACPI-device-detecti.patch new file mode 100644 index 0000000..62028d3 --- /dev/null +++ b/queue/ASoC-Intel-cht_bsw_rt5645-harden-ACPI-device-detecti.patch @@ -0,0 +1,57 @@ +From 42648c2270ca0c96935dfc5d0f5c4f8d2406cf75 Mon Sep 17 00:00:00 2001 +From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> +Date: Thu, 26 Jan 2017 14:09:41 -0600 +Subject: [PATCH] ASoC: Intel: cht_bsw_rt5645: harden ACPI device detection + +commit 42648c2270ca0c96935dfc5d0f5c4f8d2406cf75 upstream. + +Fix classic issue of having multiple codecs listed in DSDT +but a single one actually enabled. The previous code did +not handle such errors and could also lead to uninitalized +configurations + +Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> +Signed-off-by: Mark Brown <broonie@kernel.org> + +diff --git a/sound/soc/intel/boards/cht_bsw_rt5645.c b/sound/soc/intel/boards/cht_bsw_rt5645.c +index 3684bdbd8598..3461e4a88ba8 100644 +--- a/sound/soc/intel/boards/cht_bsw_rt5645.c ++++ b/sound/soc/intel/boards/cht_bsw_rt5645.c +@@ -407,22 +407,32 @@ static int snd_cht_mc_probe(struct platform_device *pdev) + struct sst_acpi_mach *mach; + const char *i2c_name = NULL; + int dai_index = 0; ++ bool found = false; + + drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_ATOMIC); + if (!drv) + return -ENOMEM; + ++ mach = (&pdev->dev)->platform_data; ++ + for (i = 0; i < ARRAY_SIZE(snd_soc_cards); i++) { +- if (acpi_dev_found(snd_soc_cards[i].codec_id)) { ++ if (acpi_dev_found(snd_soc_cards[i].codec_id) && ++ (!strncmp(snd_soc_cards[i].codec_id, mach->id, 8))) { + dev_dbg(&pdev->dev, + "found codec %s\n", snd_soc_cards[i].codec_id); + card = snd_soc_cards[i].soc_card; + drv->acpi_card = &snd_soc_cards[i]; ++ found = true; + break; + } + } ++ ++ if (!found) { ++ dev_err(&pdev->dev, "No matching HID found in supported list\n"); ++ return -ENODEV; ++ } ++ + card->dev = &pdev->dev; +- mach = card->dev->platform_data; + sprintf(drv->codec_name, "i2c-%s:00", drv->acpi_card->codec_id); + + /* set correct codec name */ +-- +2.12.0 + diff --git a/queue/ASoC-Intel-select-DW_DMAC_CORE-since-it-s-mandatory.patch b/queue/ASoC-Intel-select-DW_DMAC_CORE-since-it-s-mandatory.patch new file mode 100644 index 0000000..a81af73 --- /dev/null +++ b/queue/ASoC-Intel-select-DW_DMAC_CORE-since-it-s-mandatory.patch @@ -0,0 +1,110 @@ +From ebf79091bf85d9b2270ab29191de9cd3aaf888c5 Mon Sep 17 00:00:00 2001 +From: Andy Shevchenko <andriy.shevchenko@linux.intel.com> +Date: Mon, 16 Jan 2017 15:12:26 +0200 +Subject: [PATCH] ASoC: Intel: select DW_DMAC_CORE since it's mandatory + +commit ebf79091bf85d9b2270ab29191de9cd3aaf888c5 upstream. + +Select DW_DMAC_CORE like the rest of glue drivers do, e.g. +drivers/dma/dw/Kconfig. + +While here group selectors under SND_SOC_INTEL_HASWELL and +SND_SOC_INTEL_BAYTRAIL. + +Make platforms, which are using a common SST firmware driver, to be +dependent on DMADEVICES. + +Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> +Acked-by: Liam Girdwood <liam.r.girdwood@linux.intel.com> +Signed-off-by: Mark Brown <broonie@kernel.org> + +diff --git a/sound/soc/intel/Kconfig b/sound/soc/intel/Kconfig +index 9e3b25069de3..93c41b7219f2 100644 +--- a/sound/soc/intel/Kconfig ++++ b/sound/soc/intel/Kconfig +@@ -33,11 +33,9 @@ config SND_SOC_INTEL_SST + select SND_SOC_INTEL_SST_MATCH if ACPI + depends on (X86 || COMPILE_TEST) + +-# firmware stuff depends DW_DMAC_CORE; since there is no depends-on from +-# the reverse selection, each machine driver needs to select +-# SND_SOC_INTEL_SST_FIRMWARE carefully depending on DW_DMAC_CORE + config SND_SOC_INTEL_SST_FIRMWARE + tristate ++ select DW_DMAC_CORE + + config SND_SOC_INTEL_SST_ACPI + tristate +@@ -47,16 +45,18 @@ config SND_SOC_INTEL_SST_MATCH + + config SND_SOC_INTEL_HASWELL + tristate ++ select SND_SOC_INTEL_SST + select SND_SOC_INTEL_SST_FIRMWARE + + config SND_SOC_INTEL_BAYTRAIL + tristate ++ select SND_SOC_INTEL_SST ++ select SND_SOC_INTEL_SST_FIRMWARE + + config SND_SOC_INTEL_HASWELL_MACH + tristate "ASoC Audio DSP support for Intel Haswell Lynxpoint" + depends on X86_INTEL_LPSS && I2C && I2C_DESIGNWARE_PLATFORM +- depends on DW_DMAC_CORE +- select SND_SOC_INTEL_SST ++ depends on DMADEVICES + select SND_SOC_INTEL_HASWELL + select SND_SOC_RT5640 + help +@@ -97,9 +97,8 @@ config SND_SOC_INTEL_BXT_RT298_MACH + config SND_SOC_INTEL_BYT_RT5640_MACH + tristate "ASoC Audio driver for Intel Baytrail with RT5640 codec" + depends on X86_INTEL_LPSS && I2C +- depends on DW_DMAC_CORE && (SND_SST_IPC_ACPI = n) +- select SND_SOC_INTEL_SST +- select SND_SOC_INTEL_SST_FIRMWARE ++ depends on DMADEVICES ++ depends on SND_SST_IPC_ACPI = n + select SND_SOC_INTEL_BAYTRAIL + select SND_SOC_RT5640 + help +@@ -110,9 +109,8 @@ config SND_SOC_INTEL_BYT_RT5640_MACH + config SND_SOC_INTEL_BYT_MAX98090_MACH + tristate "ASoC Audio driver for Intel Baytrail with MAX98090 codec" + depends on X86_INTEL_LPSS && I2C +- depends on DW_DMAC_CORE && (SND_SST_IPC_ACPI = n) +- select SND_SOC_INTEL_SST +- select SND_SOC_INTEL_SST_FIRMWARE ++ depends on DMADEVICES ++ depends on SND_SST_IPC_ACPI = n + select SND_SOC_INTEL_BAYTRAIL + select SND_SOC_MAX98090 + help +@@ -121,9 +119,8 @@ config SND_SOC_INTEL_BYT_MAX98090_MACH + + config SND_SOC_INTEL_BDW_RT5677_MACH + tristate "ASoC Audio driver for Intel Broadwell with RT5677 codec" +- depends on X86_INTEL_LPSS && GPIOLIB && I2C && DW_DMAC +- depends on DW_DMAC_CORE=y +- select SND_SOC_INTEL_SST ++ depends on X86_INTEL_LPSS && GPIOLIB && I2C ++ depends on DMADEVICES + select SND_SOC_INTEL_HASWELL + select SND_SOC_RT5677 + help +@@ -132,10 +129,8 @@ config SND_SOC_INTEL_BDW_RT5677_MACH + + config SND_SOC_INTEL_BROADWELL_MACH + tristate "ASoC Audio DSP support for Intel Broadwell Wildcatpoint" +- depends on X86_INTEL_LPSS && I2C && DW_DMAC && \ +- I2C_DESIGNWARE_PLATFORM +- depends on DW_DMAC_CORE +- select SND_SOC_INTEL_SST ++ depends on X86_INTEL_LPSS && I2C && I2C_DESIGNWARE_PLATFORM ++ depends on DMADEVICES + select SND_SOC_INTEL_HASWELL + select SND_SOC_RT286 + help +-- +2.12.0 + diff --git a/queue/ASoC-codecs-rt5670-add-quirk-for-Lenovo-Thinkpad-10.patch b/queue/ASoC-codecs-rt5670-add-quirk-for-Lenovo-Thinkpad-10.patch new file mode 100644 index 0000000..36ea24b --- /dev/null +++ b/queue/ASoC-codecs-rt5670-add-quirk-for-Lenovo-Thinkpad-10.patch @@ -0,0 +1,28 @@ +From 93ffeaa8ee3f10a0628ad135b552a2497e0bef2c Mon Sep 17 00:00:00 2001 +From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> +Date: Thu, 26 Jan 2017 14:09:34 -0600 +Subject: [PATCH] ASoC: codecs: rt5670: add quirk for Lenovo Thinkpad 10 + +commit 93ffeaa8ee3f10a0628ad135b552a2497e0bef2c upstream. + +the BIOS incorrectly reports this codec as 5640 but it is +really a rt5670 + +Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> +Signed-off-by: Mark Brown <broonie@kernel.org> + +diff --git a/sound/soc/codecs/rt5670.c b/sound/soc/codecs/rt5670.c +index 97bafac3bc15..17d20b99f041 100644 +--- a/sound/soc/codecs/rt5670.c ++++ b/sound/soc/codecs/rt5670.c +@@ -2814,6 +2814,7 @@ MODULE_DEVICE_TABLE(i2c, rt5670_i2c_id); + static const struct acpi_device_id rt5670_acpi_match[] = { + { "10EC5670", 0}, + { "10EC5672", 0}, ++ { "10EC5640", 0}, /* quirk */ + { }, + }; + MODULE_DEVICE_TABLE(acpi, rt5670_acpi_match); +-- +2.12.0 + diff --git a/queue/ASoC-rt5670-Add-missing-10EC5072-ACPI-ID.patch b/queue/ASoC-rt5670-Add-missing-10EC5072-ACPI-ID.patch new file mode 100644 index 0000000..94b018a --- /dev/null +++ b/queue/ASoC-rt5670-Add-missing-10EC5072-ACPI-ID.patch @@ -0,0 +1,28 @@ +From d25280060835e1b2b84c242905da8334ab15c5b4 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai <tiwai@suse.de> +Date: Wed, 30 Nov 2016 14:55:29 +0100 +Subject: [PATCH] ASoC: rt5670: Add missing 10EC5072 ACPI ID + +commit d25280060835e1b2b84c242905da8334ab15c5b4 upstream. + +rt5670 driver supports also RT5672 codec, but its ACPI ID is missing. +This was found on Dell Wyse 3040 box. + +Signed-off-by: Takashi Iwai <tiwai@suse.de> +Signed-off-by: Mark Brown <broonie@kernel.org> + +diff --git a/sound/soc/codecs/rt5670.c b/sound/soc/codecs/rt5670.c +index d32ebe73c2c9..97bafac3bc15 100644 +--- a/sound/soc/codecs/rt5670.c ++++ b/sound/soc/codecs/rt5670.c +@@ -2813,6 +2813,7 @@ MODULE_DEVICE_TABLE(i2c, rt5670_i2c_id); + #ifdef CONFIG_ACPI + static const struct acpi_device_id rt5670_acpi_match[] = { + { "10EC5670", 0}, ++ { "10EC5672", 0}, + { }, + }; + MODULE_DEVICE_TABLE(acpi, rt5670_acpi_match); +-- +2.12.0 + diff --git a/queue/ASoC-sun4i-i2s-Add-quirks-to-handle-a31-compatible.patch b/queue/ASoC-sun4i-i2s-Add-quirks-to-handle-a31-compatible.patch new file mode 100644 index 0000000..c9be543 --- /dev/null +++ b/queue/ASoC-sun4i-i2s-Add-quirks-to-handle-a31-compatible.patch @@ -0,0 +1,150 @@ +From 2ad6f30de7087515a0bc2a718fca6681a57739a0 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Myl=C3=A8ne=20Josserand?= + <mylene.josserand@free-electrons.com> +Date: Thu, 2 Feb 2017 10:24:16 +0100 +Subject: [PATCH] ASoC: sun4i-i2s: Add quirks to handle a31 compatible +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit 2ad6f30de7087515a0bc2a718fca6681a57739a0 upstream. + +Some SoCs have a reset line that must be asserted/deasserted. +This patch adds a quirk to handle the new compatible +"allwinner,sun6i-a31-i2s" which will deassert the reset +line on probe function and assert it on remove's one. + +This new compatible is useful in case of A33 codec driver, for example. + +Signed-off-by: Mylène Josserand <mylene.josserand@free-electrons.com> +Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com> +Signed-off-by: Mark Brown <broonie@kernel.org> + +diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c +index f24d19526603..268f2bf691b3 100644 +--- a/sound/soc/sunxi/sun4i-i2s.c ++++ b/sound/soc/sunxi/sun4i-i2s.c +@@ -14,9 +14,11 @@ + #include <linux/clk.h> + #include <linux/dmaengine.h> + #include <linux/module.h> ++#include <linux/of_device.h> + #include <linux/platform_device.h> + #include <linux/pm_runtime.h> + #include <linux/regmap.h> ++#include <linux/reset.h> + + #include <sound/dmaengine_pcm.h> + #include <sound/pcm_params.h> +@@ -92,6 +94,7 @@ struct sun4i_i2s { + struct clk *bus_clk; + struct clk *mod_clk; + struct regmap *regmap; ++ struct reset_control *rst; + + unsigned int mclk_freq; + +@@ -651,9 +654,22 @@ static int sun4i_i2s_runtime_suspend(struct device *dev) + return 0; + } + ++struct sun4i_i2s_quirks { ++ bool has_reset; ++}; ++ ++static const struct sun4i_i2s_quirks sun4i_a10_i2s_quirks = { ++ .has_reset = false, ++}; ++ ++static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = { ++ .has_reset = true, ++}; ++ + static int sun4i_i2s_probe(struct platform_device *pdev) + { + struct sun4i_i2s *i2s; ++ const struct sun4i_i2s_quirks *quirks; + struct resource *res; + void __iomem *regs; + int irq, ret; +@@ -674,6 +690,12 @@ static int sun4i_i2s_probe(struct platform_device *pdev) + return irq; + } + ++ quirks = of_device_get_match_data(&pdev->dev); ++ if (!quirks) { ++ dev_err(&pdev->dev, "Failed to determine the quirks to use\n"); ++ return -ENODEV; ++ } ++ + i2s->bus_clk = devm_clk_get(&pdev->dev, "apb"); + if (IS_ERR(i2s->bus_clk)) { + dev_err(&pdev->dev, "Can't get our bus clock\n"); +@@ -692,7 +714,24 @@ static int sun4i_i2s_probe(struct platform_device *pdev) + dev_err(&pdev->dev, "Can't get our mod clock\n"); + return PTR_ERR(i2s->mod_clk); + } +- ++ ++ if (quirks->has_reset) { ++ i2s->rst = devm_reset_control_get(&pdev->dev, NULL); ++ if (IS_ERR(i2s->rst)) { ++ dev_err(&pdev->dev, "Failed to get reset control\n"); ++ return PTR_ERR(i2s->rst); ++ } ++ } ++ ++ if (!IS_ERR(i2s->rst)) { ++ ret = reset_control_deassert(i2s->rst); ++ if (ret) { ++ dev_err(&pdev->dev, ++ "Failed to deassert the reset control\n"); ++ return -EINVAL; ++ } ++ } ++ + i2s->playback_dma_data.addr = res->start + SUN4I_I2S_FIFO_TX_REG; + i2s->playback_dma_data.maxburst = 4; + +@@ -727,23 +766,37 @@ err_suspend: + sun4i_i2s_runtime_suspend(&pdev->dev); + err_pm_disable: + pm_runtime_disable(&pdev->dev); ++ if (!IS_ERR(i2s->rst)) ++ reset_control_assert(i2s->rst); + + return ret; + } + + static int sun4i_i2s_remove(struct platform_device *pdev) + { ++ struct sun4i_i2s *i2s = dev_get_drvdata(&pdev->dev); ++ + snd_dmaengine_pcm_unregister(&pdev->dev); + + pm_runtime_disable(&pdev->dev); + if (!pm_runtime_status_suspended(&pdev->dev)) + sun4i_i2s_runtime_suspend(&pdev->dev); + ++ if (!IS_ERR(i2s->rst)) ++ reset_control_assert(i2s->rst); ++ + return 0; + } + + static const struct of_device_id sun4i_i2s_match[] = { +- { .compatible = "allwinner,sun4i-a10-i2s", }, ++ { ++ .compatible = "allwinner,sun4i-a10-i2s", ++ .data = &sun4i_a10_i2s_quirks, ++ }, ++ { ++ .compatible = "allwinner,sun6i-a31-i2s", ++ .data = &sun6i_a31_i2s_quirks, ++ }, + {} + }; + MODULE_DEVICE_TABLE(of, sun4i_i2s_match); +-- +2.12.0 + diff --git a/queue/CIFS-reconnect-thread-reschedule-itself.patch b/queue/CIFS-reconnect-thread-reschedule-itself.patch new file mode 100644 index 0000000..34cc45e --- /dev/null +++ b/queue/CIFS-reconnect-thread-reschedule-itself.patch @@ -0,0 +1,52 @@ +From 18ea43113f5b74a97dd4be9bddbac10d68b1a6ce Mon Sep 17 00:00:00 2001 +From: Germano Percossi <germano.percossi@citrix.com> +Date: Fri, 7 Apr 2017 12:29:36 +0100 +Subject: [PATCH] CIFS: reconnect thread reschedule itself + +commit 18ea43113f5b74a97dd4be9bddbac10d68b1a6ce upstream. + +In case of error, smb2_reconnect_server reschedule itself +with a delay, to avoid being too aggressive. + +Signed-off-by: Germano Percossi <germano.percossi@citrix.com> +Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com> +CC: Stable <stable@vger.kernel.org> +Signed-off-by: Steve French <smfrench@gmail.com> + +diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c +index 66fa1b941cdf..d09e98bb8584 100644 +--- a/fs/cifs/smb2pdu.c ++++ b/fs/cifs/smb2pdu.c +@@ -2181,6 +2181,9 @@ void smb2_reconnect_server(struct work_struct *work) + struct cifs_tcon *tcon, *tcon2; + struct list_head tmp_list; + int tcon_exist = false; ++ int rc; ++ int resched = false; ++ + + /* Prevent simultaneous reconnects that can corrupt tcon->rlist list */ + mutex_lock(&server->reconnect_mutex); +@@ -2208,13 +2211,18 @@ void smb2_reconnect_server(struct work_struct *work) + spin_unlock(&cifs_tcp_ses_lock); + + list_for_each_entry_safe(tcon, tcon2, &tmp_list, rlist) { +- if (!smb2_reconnect(SMB2_INTERNAL_CMD, tcon)) ++ rc = smb2_reconnect(SMB2_INTERNAL_CMD, tcon); ++ if (!rc) + cifs_reopen_persistent_handles(tcon); ++ else ++ resched = true; + list_del_init(&tcon->rlist); + cifs_put_tcon(tcon); + } + + cifs_dbg(FYI, "Reconnecting tcons finished\n"); ++ if (resched) ++ queue_delayed_work(cifsiod_wq, &server->reconnect, 2 * HZ); + mutex_unlock(&server->reconnect_mutex); + + /* now we can safely release srv struct */ +-- +2.12.0 + diff --git a/queue/CIFS-store-results-of-cifs_reopen_file-to-avoid-infi.patch b/queue/CIFS-store-results-of-cifs_reopen_file-to-avoid-infi.patch new file mode 100644 index 0000000..97b75fc --- /dev/null +++ b/queue/CIFS-store-results-of-cifs_reopen_file-to-avoid-infi.patch @@ -0,0 +1,64 @@ +From 1fa839b4986d648b907d117275869a0e46c324b9 Mon Sep 17 00:00:00 2001 +From: Germano Percossi <germano.percossi@citrix.com> +Date: Fri, 7 Apr 2017 12:29:38 +0100 +Subject: [PATCH] CIFS: store results of cifs_reopen_file to avoid infinite + wait + +commit 1fa839b4986d648b907d117275869a0e46c324b9 upstream. + +This fixes Continuous Availability when errors during +file reopen are encountered. + +cifs_user_readv and cifs_user_writev would wait for ever if +results of cifs_reopen_file are not stored and for later inspection. + +In fact, results are checked and, in case of errors, a chain +of function calls leading to reads and writes to be scheduled in +a separate thread is skipped. +These threads will wake up the corresponding waiters once reads +and writes are done. + +However, given the return value is not stored, when rc is checked +for errors a previous one (always zero) is inspected instead. +This leads to pending reads/writes added to the list, making +cifs_user_readv and cifs_user_writev wait for ever. + +Signed-off-by: Germano Percossi <germano.percossi@citrix.com> +Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com> +CC: Stable <stable@vger.kernel.org> +Signed-off-by: Steve French <smfrench@gmail.com> + +diff --git a/fs/cifs/file.c b/fs/cifs/file.c +index aa3debbba826..21d404535739 100644 +--- a/fs/cifs/file.c ++++ b/fs/cifs/file.c +@@ -2597,7 +2597,7 @@ cifs_write_from_iter(loff_t offset, size_t len, struct iov_iter *from, + wdata->credits = credits; + + if (!wdata->cfile->invalidHandle || +- !cifs_reopen_file(wdata->cfile, false)) ++ !(rc = cifs_reopen_file(wdata->cfile, false))) + rc = server->ops->async_writev(wdata, + cifs_uncached_writedata_release); + if (rc) { +@@ -3022,7 +3022,7 @@ cifs_send_async_read(loff_t offset, size_t len, struct cifsFileInfo *open_file, + rdata->credits = credits; + + if (!rdata->cfile->invalidHandle || +- !cifs_reopen_file(rdata->cfile, true)) ++ !(rc = cifs_reopen_file(rdata->cfile, true))) + rc = server->ops->async_readv(rdata); + error: + if (rc) { +@@ -3617,7 +3617,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, + } + + if (!rdata->cfile->invalidHandle || +- !cifs_reopen_file(rdata->cfile, true)) ++ !(rc = cifs_reopen_file(rdata->cfile, true))) + rc = server->ops->async_readv(rdata); + if (rc) { + add_credits_and_wake_if(server, rdata->credits, 0); +-- +2.12.0 + diff --git a/queue/Documentation-stable-kernel-rules-fix-stable-tag-for.patch b/queue/Documentation-stable-kernel-rules-fix-stable-tag-for.patch new file mode 100644 index 0000000..ba11a7b --- /dev/null +++ b/queue/Documentation-stable-kernel-rules-fix-stable-tag-for.patch @@ -0,0 +1,35 @@ +From cf903e9d3a97f89b224d2d07be37c0f160db8192 Mon Sep 17 00:00:00 2001 +From: Johan Hovold <johan@kernel.org> +Date: Mon, 3 Apr 2017 15:53:34 +0200 +Subject: [PATCH] Documentation: stable-kernel-rules: fix stable-tag format + +commit cf903e9d3a97f89b224d2d07be37c0f160db8192 upstream. + +A patch documenting how to specify which kernels a particular fix should +be backported to (seemingly) inadvertently added a minus sign after the +kernel version. This particular stable-tag format had never been used +prior to this patch, and was neither present when the patch in question +was first submitted (it was added in v2 without any comment). + +Drop the minus sign to avoid any confusion. + +Fixes: fdc81b7910ad ("stable_kernel_rules: Add clause about specification of kernel versions to patch.") +Signed-off-by: Johan Hovold <johan@kernel.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> + +diff --git a/Documentation/process/stable-kernel-rules.rst b/Documentation/process/stable-kernel-rules.rst +index 11ec2d93a5e0..61e9c78bd6d1 100644 +--- a/Documentation/process/stable-kernel-rules.rst ++++ b/Documentation/process/stable-kernel-rules.rst +@@ -124,7 +124,7 @@ specified in the following format in the sign-off area: + + .. code-block:: none + +- Cc: <stable@vger.kernel.org> # 3.3.x- ++ Cc: <stable@vger.kernel.org> # 3.3.x + + The tag has the meaning of: + +-- +2.12.0 + diff --git a/queue/HID-i2c-hid-add-a-simple-quirk-to-fix-device-defects.patch b/queue/HID-i2c-hid-add-a-simple-quirk-to-fix-device-defects.patch new file mode 100644 index 0000000..2746453 --- /dev/null +++ b/queue/HID-i2c-hid-add-a-simple-quirk-to-fix-device-defects.patch @@ -0,0 +1,136 @@ +From 71af01a8c85ad89449209594133bdfdfaa9f1e2a Mon Sep 17 00:00:00 2001 +From: HungNien Chen <hn.chen@weidahitech.com> +Date: Thu, 10 Nov 2016 11:47:13 +0800 +Subject: [PATCH] HID: i2c-hid: add a simple quirk to fix device defects + +commit 71af01a8c85ad89449209594133bdfdfaa9f1e2a upstream. + +Certain devices produced by Weida Tech need to have a wakeup command sent to +them before powering on. The call itself will come back with error, but the +device can be powered on afterwards. + +[jkosina@suse.cz: rewrite changelog] +[jkosina@suse.cz: remove unused device ID addition] +Signed-off-by: HungNien Chen <hn.chen@weidahitech.com> +Reviewed-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> +Signed-off-by: Jiri Kosina <jkosina@suse.cz> + +diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h +index cd59c79eebdd..c36ec6d01b8b 100644 +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -1030,6 +1030,10 @@ + #define USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH 0x0500 + #define USB_DEVICE_ID_WALTOP_SIRIUS_BATTERY_FREE_TABLET 0x0502 + ++#define USB_VENDOR_ID_WEIDA 0x2575 ++#define USB_DEVICE_ID_WEIDA_8752 0xC300 ++#define USB_DEVICE_ID_WEIDA_8755 0xC301 ++ + #define USB_VENDOR_ID_WISEGROUP 0x0925 + #define USB_DEVICE_ID_SMARTJOY_PLUS 0x0005 + #define USB_DEVICE_ID_SUPER_JOY_BOX_3 0x8888 +diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c +index fe6b4e0eab4a..ce518795cb30 100644 +--- a/drivers/hid/i2c-hid/i2c-hid.c ++++ b/drivers/hid/i2c-hid/i2c-hid.c +@@ -40,6 +40,11 @@ + + #include <linux/i2c/i2c-hid.h> + ++#include "../hid-ids.h" ++ ++/* quirks to control the device */ ++#define I2C_HID_QUIRK_SET_PWR_WAKEUP_DEV BIT(0) ++ + /* flags */ + #define I2C_HID_STARTED 0 + #define I2C_HID_RESET_PENDING 1 +@@ -142,6 +147,7 @@ struct i2c_hid { + char *argsbuf; /* Command arguments buffer */ + + unsigned long flags; /* device flags */ ++ unsigned long quirks; /* Various quirks */ + + wait_queue_head_t wait; /* For waiting the interrupt */ + +@@ -151,6 +157,39 @@ struct i2c_hid { + struct mutex reset_lock; + }; + ++static const struct i2c_hid_quirks { ++ __u16 idVendor; ++ __u16 idProduct; ++ __u32 quirks; ++} i2c_hid_quirks[] = { ++ { USB_VENDOR_ID_WEIDA, USB_DEVICE_ID_WEIDA_8752, ++ I2C_HID_QUIRK_SET_PWR_WAKEUP_DEV }, ++ { USB_VENDOR_ID_WEIDA, USB_DEVICE_ID_WEIDA_8755, ++ I2C_HID_QUIRK_SET_PWR_WAKEUP_DEV }, ++ { 0, 0 } ++}; ++ ++/* ++ * i2c_hid_lookup_quirk: return any quirks associated with a I2C HID device ++ * @idVendor: the 16-bit vendor ID ++ * @idProduct: the 16-bit product ID ++ * ++ * Returns: a u32 quirks value. ++ */ ++static u32 i2c_hid_lookup_quirk(const u16 idVendor, const u16 idProduct) ++{ ++ u32 quirks = 0; ++ int n; ++ ++ for (n = 0; i2c_hid_quirks[n].idVendor; n++) ++ if (i2c_hid_quirks[n].idVendor == idVendor && ++ (i2c_hid_quirks[n].idProduct == (__u16)HID_ANY_ID || ++ i2c_hid_quirks[n].idProduct == idProduct)) ++ quirks = i2c_hid_quirks[n].quirks; ++ ++ return quirks; ++} ++ + static int __i2c_hid_command(struct i2c_client *client, + const struct i2c_hid_cmd *command, u8 reportID, + u8 reportType, u8 *args, int args_len, +@@ -343,11 +382,27 @@ static int i2c_hid_set_power(struct i2c_client *client, int power_state) + + i2c_hid_dbg(ihid, "%s\n", __func__); + ++ /* ++ * Some devices require to send a command to wakeup before power on. ++ * The call will get a return value (EREMOTEIO) but device will be ++ * triggered and activated. After that, it goes like a normal device. ++ */ ++ if (power_state == I2C_HID_PWR_ON && ++ ihid->quirks & I2C_HID_QUIRK_SET_PWR_WAKEUP_DEV) { ++ ret = i2c_hid_command(client, &hid_set_power_cmd, NULL, 0); ++ ++ /* Device was already activated */ ++ if (!ret) ++ goto set_pwr_exit; ++ } ++ + ret = __i2c_hid_command(client, &hid_set_power_cmd, power_state, + 0, NULL, 0, NULL, 0); ++ + if (ret) + dev_err(&client->dev, "failed to change power setting.\n"); + ++set_pwr_exit: + return ret; + } + +@@ -1032,6 +1087,8 @@ static int i2c_hid_probe(struct i2c_client *client, + client->name, hid->vendor, hid->product); + strlcpy(hid->phys, dev_name(&client->dev), sizeof(hid->phys)); + ++ ihid->quirks = i2c_hid_lookup_quirk(hid->vendor, hid->product); ++ + ret = hid_add_device(hid); + if (ret) { + if (ret != -ENODEV) +-- +2.12.0 + diff --git a/queue/HID-multitouch-do-not-retrieve-all-reports-for-all-d.patch b/queue/HID-multitouch-do-not-retrieve-all-reports-for-all-d.patch new file mode 100644 index 0000000..647f1a5 --- /dev/null +++ b/queue/HID-multitouch-do-not-retrieve-all-reports-for-all-d.patch @@ -0,0 +1,141 @@ +From b897f6db3ae2cd9a42377f8b1865450f34ceff0e Mon Sep 17 00:00:00 2001 +From: Benjamin Tissoires <benjamin.tissoires@redhat.com> +Date: Fri, 25 Nov 2016 14:27:22 +0100 +Subject: [PATCH] HID: multitouch: do not retrieve all reports for all devices + +commit b897f6db3ae2cd9a42377f8b1865450f34ceff0e upstream. + +We already have in place a quirk for Windows 8 devices, but it looks +like the Surface Cover are not conforming to it. +Given that we are only interested in 3 feature reports (the ones that +the Windows driver retrieves), we should be safe to unconditionally apply +the quirk to everybody. + +In case there is an issue with a controller, we can always mark it as such +in the transport driver, and hid-multitouch won't try to retrieve the +feature report. + +Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> +Signed-off-by: Jiri Kosina <jkosina@suse.cz> + +diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c +index 84c56e645fe8..89e9032ab1e7 100644 +--- a/drivers/hid/hid-multitouch.c ++++ b/drivers/hid/hid-multitouch.c +@@ -108,6 +108,7 @@ struct mt_device { + int cc_value_index; /* contact count value index in the field */ + unsigned last_slot_field; /* the last field of a slot */ + unsigned mt_report_id; /* the report ID of the multitouch device */ ++ unsigned long initial_quirks; /* initial quirks state */ + __s16 inputmode; /* InputMode HID feature, -1 if non-existent */ + __s16 inputmode_index; /* InputMode HID feature index in the report */ + __s16 maxcontact_report_id; /* Maximum Contact Number HID feature, +@@ -318,13 +319,10 @@ static void mt_get_feature(struct hid_device *hdev, struct hid_report *report) + u8 *buf; + + /* +- * Only fetch the feature report if initial reports are not already +- * been retrieved. Currently this is only done for Windows 8 touch +- * devices. ++ * Do not fetch the feature report if the device has been explicitly ++ * marked as non-capable. + */ +- if (!(hdev->quirks & HID_QUIRK_NO_INIT_REPORTS)) +- return; +- if (td->mtclass.name != MT_CLS_WIN_8) ++ if (td->initial_quirks & HID_QUIRK_NO_INIT_REPORTS) + return; + + buf = hid_alloc_report_buf(report, GFP_KERNEL); +@@ -1085,36 +1083,6 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) + } + } + +- /* This allows the driver to correctly support devices +- * that emit events over several HID messages. +- */ +- hdev->quirks |= HID_QUIRK_NO_INPUT_SYNC; +- +- /* +- * This allows the driver to handle different input sensors +- * that emits events through different reports on the same HID +- * device. +- */ +- hdev->quirks |= HID_QUIRK_MULTI_INPUT; +- hdev->quirks |= HID_QUIRK_NO_EMPTY_INPUT; +- +- /* +- * Handle special quirks for Windows 8 certified devices. +- */ +- if (id->group == HID_GROUP_MULTITOUCH_WIN_8) +- /* +- * Some multitouch screens do not like to be polled for input +- * reports. Fortunately, the Win8 spec says that all touches +- * should be sent during each report, making the initialization +- * of input reports unnecessary. +- * +- * In addition some touchpads do not behave well if we read +- * all feature reports from them. Instead we prevent +- * initial report fetching and then selectively fetch each +- * report we are interested in. +- */ +- hdev->quirks |= HID_QUIRK_NO_INIT_REPORTS; +- + td = devm_kzalloc(&hdev->dev, sizeof(struct mt_device), GFP_KERNEL); + if (!td) { + dev_err(&hdev->dev, "cannot allocate multitouch data\n"); +@@ -1138,6 +1106,39 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) + if (id->vendor == HID_ANY_ID && id->product == HID_ANY_ID) + td->serial_maybe = true; + ++ /* ++ * Store the initial quirk state ++ */ ++ td->initial_quirks = hdev->quirks; ++ ++ /* This allows the driver to correctly support devices ++ * that emit events over several HID messages. ++ */ ++ hdev->quirks |= HID_QUIRK_NO_INPUT_SYNC; ++ ++ /* ++ * This allows the driver to handle different input sensors ++ * that emits events through different reports on the same HID ++ * device. ++ */ ++ hdev->quirks |= HID_QUIRK_MULTI_INPUT; ++ hdev->quirks |= HID_QUIRK_NO_EMPTY_INPUT; ++ ++ /* ++ * Some multitouch screens do not like to be polled for input ++ * reports. Fortunately, the Win8 spec says that all touches ++ * should be sent during each report, making the initialization ++ * of input reports unnecessary. For Win7 devices, well, let's hope ++ * they will still be happy (this is only be a problem if a touch ++ * was already there while probing the device). ++ * ++ * In addition some touchpads do not behave well if we read ++ * all feature reports from them. Instead we prevent ++ * initial report fetching and then selectively fetch each ++ * report we are interested in. ++ */ ++ hdev->quirks |= HID_QUIRK_NO_INIT_REPORTS; ++ + ret = hid_parse(hdev); + if (ret != 0) + return ret; +@@ -1206,8 +1207,11 @@ static int mt_resume(struct hid_device *hdev) + + static void mt_remove(struct hid_device *hdev) + { ++ struct mt_device *td = hid_get_drvdata(hdev); ++ + sysfs_remove_group(&hdev->dev.kobj, &mt_attribute_group); + hid_hw_stop(hdev); ++ hdev->quirks = td->initial_quirks; + } + + /* +-- +2.12.0 + diff --git a/queue/HID-multitouch-enable-the-Surface-3-Type-Cover-to-re.patch b/queue/HID-multitouch-enable-the-Surface-3-Type-Cover-to-re.patch new file mode 100644 index 0000000..3c6e8d2 --- /dev/null +++ b/queue/HID-multitouch-enable-the-Surface-3-Type-Cover-to-re.patch @@ -0,0 +1,94 @@ +From 8fe89ef076fa104f514da6ef61d90f5bf93488e3 Mon Sep 17 00:00:00 2001 +From: Benjamin Tissoires <benjamin.tissoires@redhat.com> +Date: Fri, 25 Nov 2016 14:27:23 +0100 +Subject: [PATCH] HID: multitouch: enable the Surface 3 Type Cover to report + multitouch data + +commit 8fe89ef076fa104f514da6ef61d90f5bf93488e3 upstream. + +There is no reasons to filter out keyboard and consumer control collections +in hid-multitouch. +With the previous hid-input fix, there is now a full support of the Type +Cover and we can remove all specific bits from hid-core and hid-microsoft. + +hid-multitouch will automatically set HID_QUIRK_NO_INIT_REPORTS so we can +also remove it from the list of ushbid quirks. + +Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> +Signed-off-by: Jiri Kosina <jkosina@suse.cz> + +diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c +index 2b89c701076f..a5dd7e63ada3 100644 +--- a/drivers/hid/hid-core.c ++++ b/drivers/hid/hid-core.c +@@ -728,7 +728,6 @@ static void hid_scan_collection(struct hid_parser *parser, unsigned type) + hid->product == USB_DEVICE_ID_MS_TYPE_COVER_PRO_3_2 || + hid->product == USB_DEVICE_ID_MS_TYPE_COVER_PRO_3_JP || + hid->product == USB_DEVICE_ID_MS_TYPE_COVER_PRO_4_JP || +- hid->product == USB_DEVICE_ID_MS_TYPE_COVER_3 || + hid->product == USB_DEVICE_ID_MS_POWER_COVER) && + hid->group == HID_GROUP_MULTITOUCH) + hid->group = HID_GROUP_GENERIC; +@@ -1984,7 +1983,6 @@ static const struct hid_device_id hid_have_special_driver[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_PRO_3_2) }, + { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_PRO_3_JP) }, + { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_PRO_4_JP) }, +- { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3) }, + { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_7K) }, + { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_600) }, + { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_3KV1) }, +diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h +index 575aa65436d1..10d15359cbae 100644 +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -719,7 +719,6 @@ + #define USB_DEVICE_ID_MS_TYPE_COVER_PRO_3_2 0x07e2 + #define USB_DEVICE_ID_MS_TYPE_COVER_PRO_3_JP 0x07dd + #define USB_DEVICE_ID_MS_TYPE_COVER_PRO_4_JP 0x07e9 +-#define USB_DEVICE_ID_MS_TYPE_COVER_3 0x07de + #define USB_DEVICE_ID_MS_POWER_COVER 0x07da + + #define USB_VENDOR_ID_MOJO 0x8282 +diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c +index c6cd392e9f99..ba02667beb80 100644 +--- a/drivers/hid/hid-microsoft.c ++++ b/drivers/hid/hid-microsoft.c +@@ -282,8 +282,6 @@ static const struct hid_device_id ms_devices[] = { + .driver_data = MS_HIDINPUT }, + { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_PRO_4_JP), + .driver_data = MS_HIDINPUT }, +- { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3), +- .driver_data = MS_HIDINPUT }, + { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_POWER_COVER), + .driver_data = MS_HIDINPUT }, + { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_COMFORT_KEYBOARD), +diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c +index fb6f1f447279..84c56e645fe8 100644 +--- a/drivers/hid/hid-multitouch.c ++++ b/drivers/hid/hid-multitouch.c +@@ -842,7 +842,9 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, + if (!td->mtclass.export_all_inputs && + field->application != HID_DG_TOUCHSCREEN && + field->application != HID_DG_PEN && +- field->application != HID_DG_TOUCHPAD) ++ field->application != HID_DG_TOUCHPAD && ++ field->application != HID_GD_KEYBOARD && ++ field->application != HID_CP_CONSUMER_CONTROL) + return -1; + + /* +diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c +index e6cfd323babc..18ae71503309 100644 +--- a/drivers/hid/usbhid/hid-quirks.c ++++ b/drivers/hid/usbhid/hid-quirks.c +@@ -102,7 +102,6 @@ static const struct hid_blacklist { + { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_PRO_3_2, HID_QUIRK_NO_INIT_REPORTS }, + { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_PRO_3_JP, HID_QUIRK_NO_INIT_REPORTS }, + { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_PRO_4_JP, HID_QUIRK_NO_INIT_REPORTS }, +- { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3, HID_QUIRK_NO_INIT_REPORTS }, + { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_POWER_COVER, HID_QUIRK_NO_INIT_REPORTS }, + { USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GT683R_LED_PANEL, HID_QUIRK_NO_INIT_REPORTS }, + { USB_VENDOR_ID_NEXIO, USB_DEVICE_ID_NEXIO_MULTITOUCH_PTI0750, HID_QUIRK_NO_INIT_REPORTS }, +-- +2.12.0 + diff --git a/queue/HID-sensor-hub-add-quirk-for-Microchip-MM7150.patch b/queue/HID-sensor-hub-add-quirk-for-Microchip-MM7150.patch new file mode 100644 index 0000000..8192fc5 --- /dev/null +++ b/queue/HID-sensor-hub-add-quirk-for-Microchip-MM7150.patch @@ -0,0 +1,30 @@ +From 5cc5084dd9afa2f9bf953b0217bdb1b7c2158be1 Mon Sep 17 00:00:00 2001 +From: Benjamin Tissoires <benjamin.tissoires@redhat.com> +Date: Fri, 25 Nov 2016 11:03:44 +0100 +Subject: [PATCH] HID: sensor-hub: add quirk for Microchip MM7150 + +commit 5cc5084dd9afa2f9bf953b0217bdb1b7c2158be1 upstream. + +One more device requiring a quirk :/ + +Reported-by: Christian-Nils Boda <christian-nils.boda@gadz.org> +Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> +Signed-off-by: Jiri Kosina <jkosina@suse.cz> + +diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c +index 0646278db7b3..5c925228847c 100644 +--- a/drivers/hid/hid-sensor-hub.c ++++ b/drivers/hid/hid-sensor-hub.c +@@ -798,6 +798,9 @@ static const struct hid_device_id sensor_hub_devices[] = { + { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_MICROSOFT, + 0x07bd), /* Microsoft Surface 3 */ + .driver_data = HID_SENSOR_HUB_ENUM_QUIRK}, ++ { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_MICROCHIP, ++ 0x0f01), /* MM7150 */ ++ .driver_data = HID_SENSOR_HUB_ENUM_QUIRK}, + { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_STM_0, + USB_DEVICE_ID_STM_HID_SENSOR), + .driver_data = HID_SENSOR_HUB_ENUM_QUIRK}, +-- +2.12.0 + diff --git a/queue/HID-sensor-hub-add-quirk-for-Microsoft-Surface-3.patch b/queue/HID-sensor-hub-add-quirk-for-Microsoft-Surface-3.patch new file mode 100644 index 0000000..e618b5d --- /dev/null +++ b/queue/HID-sensor-hub-add-quirk-for-Microsoft-Surface-3.patch @@ -0,0 +1,31 @@ +From da809197a919942ab6ee0d008c20a011872181b1 Mon Sep 17 00:00:00 2001 +From: Benjamin Tissoires <benjamin.tissoires@redhat.com> +Date: Fri, 25 Nov 2016 11:03:43 +0100 +Subject: [PATCH] HID: sensor-hub add quirk for Microsoft Surface 3 + +commit da809197a919942ab6ee0d008c20a011872181b1 upstream. + +One more device requiring a quirk :/ + +[jkosina@suse.cz: update comment based on Bastien's remark] +Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> +Tested-by: Bastien Nocera <hadess@hadess.net> +Signed-off-by: Jiri Kosina <jkosina@suse.cz> + +diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c +index 60875625cbdf..0646278db7b3 100644 +--- a/drivers/hid/hid-sensor-hub.c ++++ b/drivers/hid/hid-sensor-hub.c +@@ -795,6 +795,9 @@ static const struct hid_device_id sensor_hub_devices[] = { + { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_MICROSOFT, + USB_DEVICE_ID_MS_TYPE_COVER_2), + .driver_data = HID_SENSOR_HUB_ENUM_QUIRK}, ++ { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_MICROSOFT, ++ 0x07bd), /* Microsoft Surface 3 */ ++ .driver_data = HID_SENSOR_HUB_ENUM_QUIRK}, + { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_STM_0, + USB_DEVICE_ID_STM_HID_SENSOR), + .driver_data = HID_SENSOR_HUB_ENUM_QUIRK}, +-- +2.12.0 + diff --git a/queue/HID-usbhid-Add-quirk-for-Mayflash-Dragonrise-Dolphin.patch b/queue/HID-usbhid-Add-quirk-for-Mayflash-Dragonrise-Dolphin.patch new file mode 100644 index 0000000..7ca934c --- /dev/null +++ b/queue/HID-usbhid-Add-quirk-for-Mayflash-Dragonrise-Dolphin.patch @@ -0,0 +1,42 @@ +From 8aa2cc7e747881d1fd52db28261b201d4e3e5565 Mon Sep 17 00:00:00 2001 +From: Marcel Hasler <mahasler@gmail.com> +Date: Tue, 20 Dec 2016 22:08:13 +0100 +Subject: [PATCH] HID: usbhid: Add quirk for Mayflash/Dragonrise DolphinBar. + +commit 8aa2cc7e747881d1fd52db28261b201d4e3e5565 upstream. + +The DolphinBar by Mayflash (identified as Dragonrise) needs +HID_QUIRK_MULTI_INPUT to split it up into four input devices. Without this +quirk the adapter is falsely recognized as a tablet. See also bug 115841 +(https://bugzilla.kernel.org/show_bug.cgi?id=115841). + +Signed-off-by: Marcel Hasler <mahasler@gmail.com> +Signed-off-by: Jiri Kosina <jkosina@suse.cz> + +diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h +index 62b03d53ecd1..54bd22dc1411 100644 +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -319,6 +319,7 @@ + #define USB_VENDOR_ID_DRAGONRISE 0x0079 + #define USB_DEVICE_ID_DRAGONRISE_WIIU 0x1800 + #define USB_DEVICE_ID_DRAGONRISE_PS3 0x1801 ++#define USB_DEVICE_ID_DRAGONRISE_DOLPHINBAR 0x1803 + #define USB_DEVICE_ID_DRAGONRISE_GAMECUBE 0x1843 + + #define USB_VENDOR_ID_DWAV 0x0eef +diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c +index 6fd49788fbe6..e9d6cc7cdfc5 100644 +--- a/drivers/hid/usbhid/hid-quirks.c ++++ b/drivers/hid/usbhid/hid-quirks.c +@@ -83,6 +83,7 @@ static const struct hid_blacklist { + { USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC, HID_QUIRK_NOGET }, + { USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_WIIU, HID_QUIRK_MULTI_INPUT }, + { USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_PS3, HID_QUIRK_MULTI_INPUT }, ++ { USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_DOLPHINBAR, HID_QUIRK_MULTI_INPUT }, + { USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE, HID_QUIRK_MULTI_INPUT }, + { USB_VENDOR_ID_ELAN, HID_ANY_ID, HID_QUIRK_ALWAYS_POLL }, + { USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET }, +-- +2.12.0 + diff --git a/queue/HID-usbhid-Add-quirk-for-the-Futaba-TOSD-5711BB-VFD.patch b/queue/HID-usbhid-Add-quirk-for-the-Futaba-TOSD-5711BB-VFD.patch new file mode 100644 index 0000000..8f214ad --- /dev/null +++ b/queue/HID-usbhid-Add-quirk-for-the-Futaba-TOSD-5711BB-VFD.patch @@ -0,0 +1,42 @@ +From f83f90cf7ba68deb09406ea9da80852a64c4db29 Mon Sep 17 00:00:00 2001 +From: Alex Wood <thetewood@gmail.com> +Date: Fri, 23 Dec 2016 12:50:13 +0000 +Subject: [PATCH] HID: usbhid: Add quirk for the Futaba TOSD-5711BB VFD + +commit f83f90cf7ba68deb09406ea9da80852a64c4db29 upstream. + +The Futaba TOSD-5711BB VFD crashes when the initial HID report is requested, +register the display in hid-ids and tell hid-quirks to not do the init. + +Signed-off-by: Alex Wood <thetewood@gmail.com> +Signed-off-by: Jiri Kosina <jkosina@suse.cz> + +diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h +index ec277b96eaa1..62b03d53ecd1 100644 +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -365,6 +365,9 @@ + #define USB_VENDOR_ID_FLATFROG 0x25b5 + #define USB_DEVICE_ID_MULTITOUCH_3200 0x0002 + ++#define USB_VENDOR_ID_FUTABA 0x0547 ++#define USB_DEVICE_ID_LED_DISPLAY 0x7000 ++ + #define USB_VENDOR_ID_ESSENTIAL_REALITY 0x0d7f + #define USB_DEVICE_ID_ESSENTIAL_REALITY_P5 0x0100 + +diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c +index b3e01c82af05..6fd49788fbe6 100644 +--- a/drivers/hid/usbhid/hid-quirks.c ++++ b/drivers/hid/usbhid/hid-quirks.c +@@ -88,6 +88,7 @@ static const struct hid_blacklist { + { USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET }, + { USB_VENDOR_ID_FORMOSA, USB_DEVICE_ID_FORMOSA_IR_RECEIVER, HID_QUIRK_NO_INIT_REPORTS }, + { USB_VENDOR_ID_FREESCALE, USB_DEVICE_ID_FREESCALE_MX28, HID_QUIRK_NOGET }, ++ { USB_VENDOR_ID_FUTABA, USB_DEVICE_ID_LED_DISPLAY, HID_QUIRK_NO_INIT_REPORTS }, + { USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0A4A, HID_QUIRK_ALWAYS_POLL }, + { USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0B4A, HID_QUIRK_ALWAYS_POLL }, + { USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE, HID_QUIRK_ALWAYS_POLL }, +-- +2.12.0 + diff --git a/queue/HID-usbhid-Add-quirks-for-Mayflash-Dragonrise-GameCu.patch b/queue/HID-usbhid-Add-quirks-for-Mayflash-Dragonrise-GameCu.patch new file mode 100644 index 0000000..21ca840 --- /dev/null +++ b/queue/HID-usbhid-Add-quirks-for-Mayflash-Dragonrise-GameCu.patch @@ -0,0 +1,50 @@ +From b2554000f5b5d2a3a368d09c6debf7da64901fcf Mon Sep 17 00:00:00 2001 +From: Marcel Hasler <mahasler@gmail.com> +Date: Thu, 3 Nov 2016 19:47:26 +0100 +Subject: [PATCH] HID: usbhid: Add quirks for Mayflash/Dragonrise GameCube and + PS3 adapters + +commit b2554000f5b5d2a3a368d09c6debf7da64901fcf upstream. + +All known gamepad adapters by Mayflash (identified as Dragonrise) need +HID_QUIRK_MULTI_INPUT to split them up into four input devices. Without this +quirk those adapters are falsely recognized as tablets. Fixes bug 115841 +(https://bugzilla.kernel.org/show_bug.cgi?id=115841). + +Signed-off-by: Marcel Hasler <mahasler@gmail.com> +Reviewed-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> +Signed-off-by: Jiri Kosina <jkosina@suse.cz> + +diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h +index 6cfb5cacc253..642e64861654 100644 +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -314,8 +314,10 @@ + #define USB_VENDOR_ID_DMI 0x0c0b + #define USB_DEVICE_ID_DMI_ENC 0x5fab + +-#define USB_VENDOR_ID_DRAGONRISE 0x0079 +-#define USB_DEVICE_ID_DRAGONRISE_WIIU 0x1800 ++#define USB_VENDOR_ID_DRAGONRISE 0x0079 ++#define USB_DEVICE_ID_DRAGONRISE_WIIU 0x1800 ++#define USB_DEVICE_ID_DRAGONRISE_PS3 0x1801 ++#define USB_DEVICE_ID_DRAGONRISE_GAMECUBE 0x1843 + + #define USB_VENDOR_ID_DWAV 0x0eef + #define USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER 0x0001 +diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c +index 354d49ea36dd..05f6f61f0213 100644 +--- a/drivers/hid/usbhid/hid-quirks.c ++++ b/drivers/hid/usbhid/hid-quirks.c +@@ -81,6 +81,8 @@ static const struct hid_blacklist { + { USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_CREATIVE_SB_OMNI_SURROUND_51, HID_QUIRK_NOGET }, + { USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC, HID_QUIRK_NOGET }, + { USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_WIIU, HID_QUIRK_MULTI_INPUT }, ++ { USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_PS3, HID_QUIRK_MULTI_INPUT }, ++ { USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE, HID_QUIRK_MULTI_INPUT }, + { USB_VENDOR_ID_ELAN, HID_ANY_ID, HID_QUIRK_ALWAYS_POLL }, + { USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET }, + { USB_VENDOR_ID_FORMOSA, USB_DEVICE_ID_FORMOSA_IR_RECEIVER, HID_QUIRK_NO_INIT_REPORTS }, +-- +2.12.0 + diff --git a/queue/HID-wacom-don-t-apply-generic-settings-to-old-device.patch b/queue/HID-wacom-don-t-apply-generic-settings-to-old-device.patch new file mode 100644 index 0000000..6a00f7c --- /dev/null +++ b/queue/HID-wacom-don-t-apply-generic-settings-to-old-device.patch @@ -0,0 +1,46 @@ +From e7deb1570a527d3c74be4e21a72b1b459605c501 Mon Sep 17 00:00:00 2001 +From: Ping Cheng <pinglinux@gmail.com> +Date: Mon, 30 Jan 2017 15:40:49 -0800 +Subject: [PATCH] HID: wacom: don't apply generic settings to old devices + +commit e7deb1570a527d3c74be4e21a72b1b459605c501 upstream. + +Non-generic devices have numbered_buttons set for both pen and +touch interfaces by default. The actual number of buttons on the +interface is normally manually decided later, which is different +from what those HID generic devices are processed, where number +of buttons are directly retrieved from HID descriptors. + +This patch adds the missed HID_GENERIC check and moves the statement +to wacom_setup_pad_input_capabilities since it's not a quirk anymore. + +Signed-off-by: Ping Cheng <ping.cheng@wacom.com> +Reviewed-by: Jason Gerecke <jason.gerecke@wacom.com> +Signed-off-by: Jiri Kosina <jkosina@suse.cz> + +diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c +index 0dad786d2135..d51daf581488 100644 +--- a/drivers/hid/wacom_wac.c ++++ b/drivers/hid/wacom_wac.c +@@ -2987,8 +2987,6 @@ void wacom_setup_device_quirks(struct wacom *wacom) + struct wacom_features *features = &wacom->wacom_wac.features; + + /* The pen and pad share the same interface on most devices */ +- if (features->numbered_buttons > 0) +- features->device_type |= WACOM_DEVICETYPE_PAD; + if (features->type == GRAPHIRE_BT || features->type == WACOM_G4 || + features->type == DTUS || + (features->type >= INTUOS3S && features->type <= WACOM_MO)) { +@@ -3527,6 +3525,9 @@ int wacom_setup_pad_input_capabilities(struct input_dev *input_dev, + { + struct wacom_features *features = &wacom_wac->features; + ++ if ((features->type == HID_GENERIC) && features->numbered_buttons > 0) ++ features->device_type |= WACOM_DEVICETYPE_PAD; ++ + if (!(features->device_type & WACOM_DEVICETYPE_PAD)) + return -ENODEV; + +-- +2.12.0 + diff --git a/queue/Input-gpio_keys-add-support-for-GPIO-descriptors.patch b/queue/Input-gpio_keys-add-support-for-GPIO-descriptors.patch new file mode 100644 index 0000000..10acd13 --- /dev/null +++ b/queue/Input-gpio_keys-add-support-for-GPIO-descriptors.patch @@ -0,0 +1,139 @@ +From 5feeca3c1e39c01f9ef5abc94dea94021ccf94fc Mon Sep 17 00:00:00 2001 +From: Geert Uytterhoeven <geert+renesas@glider.be> +Date: Wed, 19 Oct 2016 15:47:21 -0700 +Subject: [PATCH] Input: gpio_keys - add support for GPIO descriptors + +commit 5feeca3c1e39c01f9ef5abc94dea94021ccf94fc upstream. + +GPIO descriptors are the preferred way over legacy GPIO numbers +nowadays. Convert the driver to use GPIO descriptors internally but +still allow passing legacy GPIO numbers from platform data to support +existing platforms. + +Based on commits 633a21d80b4a2cd6 ("input: gpio_keys_polled: Add support +for GPIO descriptors") and 1ae5ddb6f8837558 ("Input: gpio_keys_polled - +request GPIO pin as input."). + +Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be> +Reviewed-by: Linus Walleij <linus.walleij@linaro.org> +Tested-by: Mika Westerberg <mika.westerberg@linux.intel.com> +Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> + +diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c +index d75a25c187ae..0f04cb1569a0 100644 +--- a/drivers/input/keyboard/gpio_keys.c ++++ b/drivers/input/keyboard/gpio_keys.c +@@ -26,6 +26,7 @@ + #include <linux/gpio_keys.h> + #include <linux/workqueue.h> + #include <linux/gpio.h> ++#include <linux/gpio/consumer.h> + #include <linux/of.h> + #include <linux/of_platform.h> + #include <linux/of_gpio.h> +@@ -35,6 +36,7 @@ + struct gpio_button_data { + const struct gpio_keys_button *button; + struct input_dev *input; ++ struct gpio_desc *gpiod; + + struct timer_list release_timer; + unsigned int release_delay; /* in msecs, for IRQ-only buttons */ +@@ -140,7 +142,7 @@ static void gpio_keys_disable_button(struct gpio_button_data *bdata) + */ + disable_irq(bdata->irq); + +- if (gpio_is_valid(bdata->button->gpio)) ++ if (bdata->gpiod) + cancel_delayed_work_sync(&bdata->work); + else + del_timer_sync(&bdata->release_timer); +@@ -358,19 +360,20 @@ static void gpio_keys_gpio_report_event(struct gpio_button_data *bdata) + const struct gpio_keys_button *button = bdata->button; + struct input_dev *input = bdata->input; + unsigned int type = button->type ?: EV_KEY; +- int state = gpio_get_value_cansleep(button->gpio); ++ int state; + ++ state = gpiod_get_value_cansleep(bdata->gpiod); + if (state < 0) { +- dev_err(input->dev.parent, "failed to get gpio state\n"); ++ dev_err(input->dev.parent, ++ "failed to get gpio state: %d\n", state); + return; + } + +- state = (state ? 1 : 0) ^ button->active_low; + if (type == EV_ABS) { + if (state) + input_event(input, type, button->code, button->value); + } else { +- input_event(input, type, button->code, !!state); ++ input_event(input, type, button->code, state); + } + input_sync(input); + } +@@ -456,7 +459,7 @@ static void gpio_keys_quiesce_key(void *data) + { + struct gpio_button_data *bdata = data; + +- if (gpio_is_valid(bdata->button->gpio)) ++ if (bdata->gpiod) + cancel_delayed_work_sync(&bdata->work); + else + del_timer_sync(&bdata->release_timer); +@@ -478,18 +481,30 @@ static int gpio_keys_setup_key(struct platform_device *pdev, + bdata->button = button; + spin_lock_init(&bdata->lock); + ++ /* ++ * Legacy GPIO number, so request the GPIO here and ++ * convert it to descriptor. ++ */ + if (gpio_is_valid(button->gpio)) { ++ unsigned flags = GPIOF_IN; ++ ++ if (button->active_low) ++ flags |= GPIOF_ACTIVE_LOW; + +- error = devm_gpio_request_one(&pdev->dev, button->gpio, +- GPIOF_IN, desc); ++ error = devm_gpio_request_one(&pdev->dev, button->gpio, flags, ++ desc); + if (error < 0) { + dev_err(dev, "Failed to request GPIO %d, error %d\n", + button->gpio, error); + return error; + } + ++ bdata->gpiod = gpio_to_desc(button->gpio); ++ if (!bdata->gpiod) ++ return -EINVAL; ++ + if (button->debounce_interval) { +- error = gpio_set_debounce(button->gpio, ++ error = gpiod_set_debounce(bdata->gpiod, + button->debounce_interval * 1000); + /* use timer if gpiolib doesn't provide debounce */ + if (error < 0) +@@ -500,7 +515,7 @@ static int gpio_keys_setup_key(struct platform_device *pdev, + if (button->irq) { + bdata->irq = button->irq; + } else { +- irq = gpio_to_irq(button->gpio); ++ irq = gpiod_to_irq(bdata->gpiod); + if (irq < 0) { + error = irq; + dev_err(dev, +@@ -575,7 +590,7 @@ static void gpio_keys_report_state(struct gpio_keys_drvdata *ddata) + + for (i = 0; i < ddata->pdata->nbuttons; i++) { + struct gpio_button_data *bdata = &ddata->data[i]; +- if (gpio_is_valid(bdata->button->gpio)) ++ if (bdata->gpiod) + gpio_keys_gpio_report_event(bdata); + } + input_sync(input); +-- +2.12.0 + diff --git a/queue/Input-xpad-add-support-for-Razer-Wildcat-gamepad.patch b/queue/Input-xpad-add-support-for-Razer-Wildcat-gamepad.patch new file mode 100644 index 0000000..560fb8f --- /dev/null +++ b/queue/Input-xpad-add-support-for-Razer-Wildcat-gamepad.patch @@ -0,0 +1,34 @@ +From 5376366886251e2f8f248704adb620a4bc4c0937 Mon Sep 17 00:00:00 2001 +From: Cameron Gutman <aicommander@gmail.com> +Date: Mon, 10 Apr 2017 20:44:25 -0700 +Subject: [PATCH] Input: xpad - add support for Razer Wildcat gamepad + +commit 5376366886251e2f8f248704adb620a4bc4c0937 upstream. + +Cc: stable@vger.kernel.org +Signed-off-by: Cameron Gutman <aicommander@gmail.com> +Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> + +diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c +index 155fcb3b6230..153b1ee13e03 100644 +--- a/drivers/input/joystick/xpad.c ++++ b/drivers/input/joystick/xpad.c +@@ -202,6 +202,7 @@ static const struct xpad_device { + { 0x1430, 0x8888, "TX6500+ Dance Pad (first generation)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, + { 0x146b, 0x0601, "BigBen Interactive XBOX 360 Controller", 0, XTYPE_XBOX360 }, + { 0x1532, 0x0037, "Razer Sabertooth", 0, XTYPE_XBOX360 }, ++ { 0x1532, 0x0a03, "Razer Wildcat", 0, XTYPE_XBOXONE }, + { 0x15e4, 0x3f00, "Power A Mini Pro Elite", 0, XTYPE_XBOX360 }, + { 0x15e4, 0x3f0a, "Xbox Airflo wired controller", 0, XTYPE_XBOX360 }, + { 0x15e4, 0x3f10, "Batarang Xbox 360 controller", 0, XTYPE_XBOX360 }, +@@ -326,6 +327,7 @@ static struct usb_device_id xpad_table[] = { + XPAD_XBOX360_VENDOR(0x1430), /* RedOctane X-Box 360 controllers */ + XPAD_XBOX360_VENDOR(0x146b), /* BigBen Interactive Controllers */ + XPAD_XBOX360_VENDOR(0x1532), /* Razer Sabertooth */ ++ XPAD_XBOXONE_VENDOR(0x1532), /* Razer Wildcat */ + XPAD_XBOX360_VENDOR(0x15e4), /* Numark X-Box 360 controllers */ + XPAD_XBOX360_VENDOR(0x162e), /* Joytech X-Box 360 controllers */ + XPAD_XBOX360_VENDOR(0x1689), /* Razer Onza */ +-- +2.12.0 + diff --git a/queue/Kbuild-use-cc-disable-warning-consistently-for-maybe.patch b/queue/Kbuild-use-cc-disable-warning-consistently-for-maybe.patch new file mode 100644 index 0000000..3bfca7a --- /dev/null +++ b/queue/Kbuild-use-cc-disable-warning-consistently-for-maybe.patch @@ -0,0 +1,53 @@ +From b334e19ae9381f12a7521976883022385d2b7eef Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann <arnd@arndb.de> +Date: Fri, 13 Jan 2017 16:40:01 +0100 +Subject: [PATCH] Kbuild: use cc-disable-warning consistently for + maybe-uninitialized + +commit b334e19ae9381f12a7521976883022385d2b7eef upstream. + +In commit a76bcf557ef4 ("Kbuild: enable -Wmaybe-uninitialized warning +for "make W=1""), I reverted another change that happened to fix a problem +with old compilers, and now we get this report again with old compilers +(prior to gcc-4.8) and GCOV enabled: + + cc1: warnings being treated as errors + drivers/gpu/drm/i915/intel_ringbuffer.c: In function 'intel_ring_setup_status_page': + drivers/gpu/drm/i915/intel_ringbuffer.c:438: error: 'mmio.reg' may be used uninitialized in this function + At top level: +>> cc1: error: unrecognized command line option "-Wno-maybe-uninitialized" + +The problem is that we turn off the warning conditionally in a number +of places as we should, but one of them does it unconditionally. +Instead, change it to call cc-disable-warning as we do elsewhere. + +The original patch that caused it was merged into linux-4.7, then +4.8 removed the change and 4.9 brought it back, so we probably want +a backport to 4.9 once this is merged. + +Use a ':=' assignment instead of '=' to force the cc-disable-warning +call to only be evaluated once instead of every time. + +Cc: stable@vger.kernel.org +Fixes: a76bcf557ef4 ("Kbuild: enable -Wmaybe-uninitialized warning for "make W=1"") +Fixes: e72e2dfe7c16 ("gcov: disable -Wmaybe-uninitialized warning") +Reported-by: kbuild test robot <fengguang.wu@intel.com> +Signed-off-by: Arnd Bergmann <arnd@arndb.de> +Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com> + +diff --git a/Makefile b/Makefile +index 165cf9783a5d..b8a6b862ed73 100644 +--- a/Makefile ++++ b/Makefile +@@ -372,7 +372,7 @@ LDFLAGS_MODULE = + CFLAGS_KERNEL = + AFLAGS_KERNEL = + LDFLAGS_vmlinux = +-CFLAGS_GCOV = -fprofile-arcs -ftest-coverage -fno-tree-loop-im -Wno-maybe-uninitialized ++CFLAGS_GCOV := -fprofile-arcs -ftest-coverage -fno-tree-loop-im $(call cc-disable-warning,maybe-uninitialized,) + CFLAGS_KCOV := $(call cc-option,-fsanitize-coverage=trace-pc,) + + +-- +2.12.0 + diff --git a/queue/MIPS-Add-MIPS_CPU_FTLB-for-Loongson-3A-R2.patch b/queue/MIPS-Add-MIPS_CPU_FTLB-for-Loongson-3A-R2.patch new file mode 100644 index 0000000..e9dcea3 --- /dev/null +++ b/queue/MIPS-Add-MIPS_CPU_FTLB-for-Loongson-3A-R2.patch @@ -0,0 +1,36 @@ +From 033cffeedbd11c140952b98e8639bf652091a17d Mon Sep 17 00:00:00 2001 +From: Huacai Chen <chenhc@lemote.com> +Date: Thu, 16 Mar 2017 21:00:25 +0800 +Subject: [PATCH] MIPS: Add MIPS_CPU_FTLB for Loongson-3A R2 + +commit 033cffeedbd11c140952b98e8639bf652091a17d upstream. + +Loongson-3A R2 and newer CPU have FTLB, but Config0.MT is 1, so add +MIPS_CPU_FTLB to the CPU options. + +Signed-off-by: Huacai Chen <chenhc@lemote.com> +Cc: John Crispin <john@phrozen.org> +Cc: Steven J . Hill <Steven.Hill@caviumnetworks.com> +Cc: Fuxin Zhang <zhangfx@lemote.com> +Cc: Zhangjin Wu <wuzhangjin@gmail.com> +Cc: linux-mips@linux-mips.org +Cc: stable@vger.kernel.org +Patchwork: https://patchwork.linux-mips.org/patch/15752/ +Signed-off-by: Ralf Baechle <ralf@linux-mips.org> + +diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c +index 07718bb5fc9d..12422fd4af23 100644 +--- a/arch/mips/kernel/cpu-probe.c ++++ b/arch/mips/kernel/cpu-probe.c +@@ -1824,7 +1824,7 @@ static inline void cpu_probe_loongson(struct cpuinfo_mips *c, unsigned int cpu) + } + + decode_configs(c); +- c->options |= MIPS_CPU_TLBINV | MIPS_CPU_LDPTE; ++ c->options |= MIPS_CPU_FTLB | MIPS_CPU_TLBINV | MIPS_CPU_LDPTE; + c->writecombine = _CACHE_UNCACHED_ACCELERATED; + break; + default: +-- +2.12.0 + diff --git a/queue/MIPS-Check-TLB-before-handle_ri_rdhwr-for-Loongson-3.patch b/queue/MIPS-Check-TLB-before-handle_ri_rdhwr-for-Loongson-3.patch new file mode 100644 index 0000000..9e2aea0 --- /dev/null +++ b/queue/MIPS-Check-TLB-before-handle_ri_rdhwr-for-Loongson-3.patch @@ -0,0 +1,98 @@ +From 5a34133167dce36666ea054e30a561b7f4413b7f Mon Sep 17 00:00:00 2001 +From: Huacai Chen <chenhc@lemote.com> +Date: Thu, 16 Mar 2017 21:00:26 +0800 +Subject: [PATCH] MIPS: Check TLB before handle_ri_rdhwr() for Loongson-3 + +commit 5a34133167dce36666ea054e30a561b7f4413b7f upstream. + +Loongson-3's micro TLB (ITLB) is not strictly a subset of JTLB. That +means: when a JTLB entry is replaced by hardware, there may be an old +valid entry exists in ITLB. So, a TLB miss exception may occur while +handle_ri_rdhwr() is running because it try to access EPC's content. +However, handle_ri_rdhwr() doesn't clear EXL, which makes a TLB Refill +exception be treated as a TLB Invalid exception and tlbp may fail. In +this case, if FTLB (which is usually set-associative instead of set- +associative) is enabled, a tlbp failure will cause an invalid tlbwi, +which will hang the whole system. + +This patch rename handle_ri_rdhwr_vivt to handle_ri_rdhwr_tlbp and use +it for Loongson-3. It try to solve the same problem described as below, +but more straightforwards. + +https://patchwork.linux-mips.org/patch/12591/ + +I think Loongson-2 has the same problem, but it has no FTLB, so we just +keep it as is. + +Signed-off-by: Huacai Chen <chenhc@lemote.com> +Cc: Rui Wang <wangr@lemote.com> +Cc: John Crispin <john@phrozen.org> +Cc: Steven J . Hill <Steven.Hill@caviumnetworks.com> +Cc: Fuxin Zhang <zhangfx@lemote.com> +Cc: Zhangjin Wu <wuzhangjin@gmail.com> +Cc: Huacai Chen <chenhc@lemote.com> +Cc: linux-mips@linux-mips.org +Cc: stable@vger.kernel.org +Patchwork: https://patchwork.linux-mips.org/patch/15753/ +Signed-off-by: Ralf Baechle <ralf@linux-mips.org> + +diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S +index 7ec9612cb007..2ac6c2625c13 100644 +--- a/arch/mips/kernel/genex.S ++++ b/arch/mips/kernel/genex.S +@@ -519,7 +519,7 @@ NESTED(nmi_handler, PT_SIZE, sp) + BUILD_HANDLER reserved reserved sti verbose /* others */ + + .align 5 +- LEAF(handle_ri_rdhwr_vivt) ++ LEAF(handle_ri_rdhwr_tlbp) + .set push + .set noat + .set noreorder +@@ -538,7 +538,7 @@ NESTED(nmi_handler, PT_SIZE, sp) + .set pop + bltz k1, handle_ri /* slow path */ + /* fall thru */ +- END(handle_ri_rdhwr_vivt) ++ END(handle_ri_rdhwr_tlbp) + + LEAF(handle_ri_rdhwr) + .set push +diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c +index c7d17cfb32f6..b49e7bf9f950 100644 +--- a/arch/mips/kernel/traps.c ++++ b/arch/mips/kernel/traps.c +@@ -83,7 +83,7 @@ extern asmlinkage void handle_dbe(void); + extern asmlinkage void handle_sys(void); + extern asmlinkage void handle_bp(void); + extern asmlinkage void handle_ri(void); +-extern asmlinkage void handle_ri_rdhwr_vivt(void); ++extern asmlinkage void handle_ri_rdhwr_tlbp(void); + extern asmlinkage void handle_ri_rdhwr(void); + extern asmlinkage void handle_cpu(void); + extern asmlinkage void handle_ov(void); +@@ -2408,9 +2408,18 @@ void __init trap_init(void) + + set_except_vector(EXCCODE_SYS, handle_sys); + set_except_vector(EXCCODE_BP, handle_bp); +- set_except_vector(EXCCODE_RI, rdhwr_noopt ? handle_ri : +- (cpu_has_vtag_icache ? +- handle_ri_rdhwr_vivt : handle_ri_rdhwr)); ++ ++ if (rdhwr_noopt) ++ set_except_vector(EXCCODE_RI, handle_ri); ++ else { ++ if (cpu_has_vtag_icache) ++ set_except_vector(EXCCODE_RI, handle_ri_rdhwr_tlbp); ++ else if (current_cpu_type() == CPU_LOONGSON3) ++ set_except_vector(EXCCODE_RI, handle_ri_rdhwr_tlbp); ++ else ++ set_except_vector(EXCCODE_RI, handle_ri_rdhwr); ++ } ++ + set_except_vector(EXCCODE_CPU, handle_cpu); + set_except_vector(EXCCODE_OV, handle_ov); + set_except_vector(EXCCODE_TR, handle_tr); +-- +2.12.0 + diff --git a/queue/MIPS-End-spinlocks-with-.insn.patch b/queue/MIPS-End-spinlocks-with-.insn.patch new file mode 100644 index 0000000..961a8a0 --- /dev/null +++ b/queue/MIPS-End-spinlocks-with-.insn.patch @@ -0,0 +1,76 @@ +From 4b5347a24a0f2d3272032c120664b484478455de Mon Sep 17 00:00:00 2001 +From: Paul Burton <paul.burton@imgtec.com> +Date: Thu, 23 Feb 2017 14:50:24 +0000 +Subject: [PATCH] MIPS: End spinlocks with .insn + +commit 4b5347a24a0f2d3272032c120664b484478455de upstream. + +When building for microMIPS we need to ensure that the assembler always +knows that there is code at the target of a branch or jump. Recent +toolchains will fail to link a microMIPS kernel when this isn't the case +due to what it thinks is a branch to non-microMIPS code. + +mips-mti-linux-gnu-ld kernel/built-in.o: .spinlock.text+0x2fc: Unsupported branch between ISA modes. +mips-mti-linux-gnu-ld final link failed: Bad value + +This is due to inline assembly labels in spinlock.h not being followed +by an instruction mnemonic, either due to a .subsection pseudo-op or the +end of the inline asm block. + +Fix this with a .insn direction after such labels. + +Signed-off-by: Paul Burton <paul.burton@imgtec.com> +Signed-off-by: James Hogan <james.hogan@imgtec.com> +Reviewed-by: Maciej W. Rozycki <macro@imgtec.com> +Cc: Ralf Baechle <ralf@linux-mips.org> +Cc: Peter Zijlstra <peterz@infradead.org> +Cc: Ingo Molnar <mingo@redhat.com> +Cc: linux-mips@linux-mips.org +Cc: linux-kernel@vger.kernel.org +Cc: <stable@vger.kernel.org> +Patchwork: https://patchwork.linux-mips.org/patch/15325/ +Signed-off-by: James Hogan <james.hogan@imgtec.com> + +diff --git a/arch/mips/include/asm/spinlock.h b/arch/mips/include/asm/spinlock.h +index f485afe51514..a8df44d60607 100644 +--- a/arch/mips/include/asm/spinlock.h ++++ b/arch/mips/include/asm/spinlock.h +@@ -127,7 +127,7 @@ static inline void arch_spin_lock(arch_spinlock_t *lock) + " andi %[ticket], %[ticket], 0xffff \n" + " bne %[ticket], %[my_ticket], 4f \n" + " subu %[ticket], %[my_ticket], %[ticket] \n" +- "2: \n" ++ "2: .insn \n" + " .subsection 2 \n" + "4: andi %[ticket], %[ticket], 0xffff \n" + " sll %[ticket], 5 \n" +@@ -202,7 +202,7 @@ static inline unsigned int arch_spin_trylock(arch_spinlock_t *lock) + " sc %[ticket], %[ticket_ptr] \n" + " beqz %[ticket], 1b \n" + " li %[ticket], 1 \n" +- "2: \n" ++ "2: .insn \n" + " .subsection 2 \n" + "3: b 2b \n" + " li %[ticket], 0 \n" +@@ -382,7 +382,7 @@ static inline int arch_read_trylock(arch_rwlock_t *rw) + " .set reorder \n" + __WEAK_LLSC_MB + " li %2, 1 \n" +- "2: \n" ++ "2: .insn \n" + : "=" GCC_OFF_SMALL_ASM() (rw->lock), "=&r" (tmp), "=&r" (ret) + : GCC_OFF_SMALL_ASM() (rw->lock) + : "memory"); +@@ -422,7 +422,7 @@ static inline int arch_write_trylock(arch_rwlock_t *rw) + " lui %1, 0x8000 \n" + " sc %1, %0 \n" + " li %2, 1 \n" +- "2: \n" ++ "2: .insn \n" + : "=" GCC_OFF_SMALL_ASM() (rw->lock), "=&r" (tmp), + "=&r" (ret) + : GCC_OFF_SMALL_ASM() (rw->lock) +-- +2.12.0 + diff --git a/queue/MIPS-Flush-wrong-invalid-FTLB-entry-for-huge-page.patch b/queue/MIPS-Flush-wrong-invalid-FTLB-entry-for-huge-page.patch new file mode 100644 index 0000000..2620c27 --- /dev/null +++ b/queue/MIPS-Flush-wrong-invalid-FTLB-entry-for-huge-page.patch @@ -0,0 +1,101 @@ +From 0115f6cbf26663c86496bc56eeea293f85b77897 Mon Sep 17 00:00:00 2001 +From: Huacai Chen <chenhc@lemote.com> +Date: Thu, 16 Mar 2017 21:00:27 +0800 +Subject: [PATCH] MIPS: Flush wrong invalid FTLB entry for huge page + +commit 0115f6cbf26663c86496bc56eeea293f85b77897 upstream. + +On VTLB+FTLB platforms (such as Loongson-3A R2), FTLB's pagesize is +usually configured the same as PAGE_SIZE. In such a case, Huge page +entry is not suitable to write in FTLB. + +Unfortunately, when a huge page is created, its page table entries +haven't created immediately. Then the TLB refill handler will fetch an +invalid page table entry which has no "HUGE" bit, and this entry may be +written to FTLB. Since it is invalid, TLB load/store handler will then +use tlbwi to write the valid entry at the same place. However, the +valid entry is a huge page entry which isn't suitable for FTLB. + +Our solution is to modify build_huge_handler_tail. Flush the invalid +old entry (whether it is in FTLB or VTLB, this is in order to reduce +branches) and use tlbwr to write the valid new entry. + +Signed-off-by: Rui Wang <wangr@lemote.com> +Signed-off-by: Huacai Chen <chenhc@lemote.com> +Cc: John Crispin <john@phrozen.org> +Cc: Steven J . Hill <Steven.Hill@caviumnetworks.com> +Cc: Fuxin Zhang <zhangfx@lemote.com> +Cc: Zhangjin Wu <wuzhangjin@gmail.com> +Cc: Huacai Chen <chenhc@lemote.com> +Cc: linux-mips@linux-mips.org +Cc: stable@vger.kernel.org +Patchwork: https://patchwork.linux-mips.org/patch/15754/ +Signed-off-by: Ralf Baechle <ralf@linux-mips.org> + +diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c +index 9bfee8988eaf..4f642e07c2b1 100644 +--- a/arch/mips/mm/tlbex.c ++++ b/arch/mips/mm/tlbex.c +@@ -760,7 +760,8 @@ static void build_huge_update_entries(u32 **p, unsigned int pte, + static void build_huge_handler_tail(u32 **p, struct uasm_reloc **r, + struct uasm_label **l, + unsigned int pte, +- unsigned int ptr) ++ unsigned int ptr, ++ unsigned int flush) + { + #ifdef CONFIG_SMP + UASM_i_SC(p, pte, 0, ptr); +@@ -769,6 +770,22 @@ static void build_huge_handler_tail(u32 **p, struct uasm_reloc **r, + #else + UASM_i_SW(p, pte, 0, ptr); + #endif ++ if (cpu_has_ftlb && flush) { ++ BUG_ON(!cpu_has_tlbinv); ++ ++ UASM_i_MFC0(p, ptr, C0_ENTRYHI); ++ uasm_i_ori(p, ptr, ptr, MIPS_ENTRYHI_EHINV); ++ UASM_i_MTC0(p, ptr, C0_ENTRYHI); ++ build_tlb_write_entry(p, l, r, tlb_indexed); ++ ++ uasm_i_xori(p, ptr, ptr, MIPS_ENTRYHI_EHINV); ++ UASM_i_MTC0(p, ptr, C0_ENTRYHI); ++ build_huge_update_entries(p, pte, ptr); ++ build_huge_tlb_write_entry(p, l, r, pte, tlb_random, 0); ++ ++ return; ++ } ++ + build_huge_update_entries(p, pte, ptr); + build_huge_tlb_write_entry(p, l, r, pte, tlb_indexed, 0); + } +@@ -2199,7 +2216,7 @@ static void build_r4000_tlb_load_handler(void) + uasm_l_tlbl_goaround2(&l, p); + } + uasm_i_ori(&p, wr.r1, wr.r1, (_PAGE_ACCESSED | _PAGE_VALID)); +- build_huge_handler_tail(&p, &r, &l, wr.r1, wr.r2); ++ build_huge_handler_tail(&p, &r, &l, wr.r1, wr.r2, 1); + #endif + + uasm_l_nopage_tlbl(&l, p); +@@ -2254,7 +2271,7 @@ static void build_r4000_tlb_store_handler(void) + build_tlb_probe_entry(&p); + uasm_i_ori(&p, wr.r1, wr.r1, + _PAGE_ACCESSED | _PAGE_MODIFIED | _PAGE_VALID | _PAGE_DIRTY); +- build_huge_handler_tail(&p, &r, &l, wr.r1, wr.r2); ++ build_huge_handler_tail(&p, &r, &l, wr.r1, wr.r2, 1); + #endif + + uasm_l_nopage_tlbs(&l, p); +@@ -2310,7 +2327,7 @@ static void build_r4000_tlb_modify_handler(void) + build_tlb_probe_entry(&p); + uasm_i_ori(&p, wr.r1, wr.r1, + _PAGE_ACCESSED | _PAGE_MODIFIED | _PAGE_VALID | _PAGE_DIRTY); +- build_huge_handler_tail(&p, &r, &l, wr.r1, wr.r2); ++ build_huge_handler_tail(&p, &r, &l, wr.r1, wr.r2, 0); + #endif + + uasm_l_nopage_tlbm(&l, p); +-- +2.12.0 + diff --git a/queue/MIPS-Force-o32-fp64-support-on-32bit-MIPS64r6-kernel.patch b/queue/MIPS-Force-o32-fp64-support-on-32bit-MIPS64r6-kernel.patch new file mode 100644 index 0000000..775e717 --- /dev/null +++ b/queue/MIPS-Force-o32-fp64-support-on-32bit-MIPS64r6-kernel.patch @@ -0,0 +1,45 @@ +From 2e6c7747730296a6d4fd700894286db1132598c4 Mon Sep 17 00:00:00 2001 +From: James Hogan <james.hogan@imgtec.com> +Date: Thu, 16 Feb 2017 12:39:01 +0000 +Subject: [PATCH] MIPS: Force o32 fp64 support on 32bit MIPS64r6 kernels + +commit 2e6c7747730296a6d4fd700894286db1132598c4 upstream. + +When a 32-bit kernel is configured to support MIPS64r6 (CPU_MIPS64_R6), +MIPS_O32_FP64_SUPPORT won't be selected as it should be because +MIPS32_O32 is disabled (o32 is already the default ABI available on +32-bit kernels). + +This results in userland FP breakage as CP0_Status.FR is read-only 1 +since r6 (when an FPU is present) so __enable_fpu() will fail to clear +FR. This causes the FPU emulator to get used which will incorrectly +emulate 32-bit FPU registers. + +Force o32 fp64 support in this case by also selecting +MIPS_O32_FP64_SUPPORT from CPU_MIPS64_R6 if 32BIT. + +Fixes: 4e9d324d4288 ("MIPS: Require O32 FP64 support for MIPS64 with O32 compat") +Signed-off-by: James Hogan <james.hogan@imgtec.com> +Reviewed-by: Paul Burton <paul.burton@imgtec.com> +Cc: Ralf Baechle <ralf@linux-mips.org> +Cc: linux-mips@linux-mips.org +Cc: <stable@vger.kernel.org> # 4.0.x- +Patchwork: https://patchwork.linux-mips.org/patch/15310/ +Signed-off-by: James Hogan <james.hogan@imgtec.com> + +diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig +index a008a9f03072..e0bb576410bb 100644 +--- a/arch/mips/Kconfig ++++ b/arch/mips/Kconfig +@@ -1531,7 +1531,7 @@ config CPU_MIPS64_R6 + select CPU_SUPPORTS_HIGHMEM + select CPU_SUPPORTS_MSA + select GENERIC_CSUM +- select MIPS_O32_FP64_SUPPORT if MIPS32_O32 ++ select MIPS_O32_FP64_SUPPORT if 32BIT || MIPS32_O32 + select HAVE_KVM + help + Choose this option to build a kernel for release 6 or later of the +-- +2.12.0 + diff --git a/queue/MIPS-IRQ-Stack-Fix-erroneous-jal-to-plat_irq_dispatc.patch b/queue/MIPS-IRQ-Stack-Fix-erroneous-jal-to-plat_irq_dispatc.patch new file mode 100644 index 0000000..1873e8e --- /dev/null +++ b/queue/MIPS-IRQ-Stack-Fix-erroneous-jal-to-plat_irq_dispatc.patch @@ -0,0 +1,39 @@ +From c25f8064c1d5731a2ce5664def890140dcdd3e5c Mon Sep 17 00:00:00 2001 +From: Matt Redfearn <matt.redfearn@imgtec.com> +Date: Wed, 25 Jan 2017 17:00:25 +0000 +Subject: [PATCH] MIPS: IRQ Stack: Fix erroneous jal to plat_irq_dispatch + +commit c25f8064c1d5731a2ce5664def890140dcdd3e5c upstream. + +Commit dda45f701c9d ("MIPS: Switch to the irq_stack in interrupts") +changed both the normal and vectored interrupt handlers. Unfortunately +the vectored version, "except_vec_vi_handler", was incorrectly modified +to unconditionally jal to plat_irq_dispatch, rather than doing a jalr to +the vectored handler that has been set up. This is ok for many platforms +which set the vectored handler to plat_irq_dispatch anyway, but will +cause problems with platforms that use other handlers. + +Fixes: dda45f701c9d ("MIPS: Switch to the irq_stack in interrupts") +Signed-off-by: Matt Redfearn <matt.redfearn@imgtec.com> +Cc: Ralf Baechle <ralf@linux-mips.org> +Cc: Paul Burton <paul.burton@imgtec.com> +Cc: linux-mips@linux-mips.org +Patchwork: https://patchwork.linux-mips.org/patch/15110/ +Signed-off-by: James Hogan <james.hogan@imgtec.com> + +diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S +index 0a7ba4b2f687..7ec9612cb007 100644 +--- a/arch/mips/kernel/genex.S ++++ b/arch/mips/kernel/genex.S +@@ -329,7 +329,7 @@ NESTED(except_vec_vi_handler, 0, sp) + PTR_ADD sp, t0, t1 + + 2: +- jal plat_irq_dispatch ++ jalr v0 + + /* Restore sp */ + move sp, s1 +-- +2.12.0 + diff --git a/queue/MIPS-Introduce-irq_stack.patch b/queue/MIPS-Introduce-irq_stack.patch new file mode 100644 index 0000000..117441c --- /dev/null +++ b/queue/MIPS-Introduce-irq_stack.patch @@ -0,0 +1,94 @@ +From fe8bd18ffea5327344d4ec2bf11f47951212abd0 Mon Sep 17 00:00:00 2001 +From: Matt Redfearn <matt.redfearn@imgtec.com> +Date: Mon, 19 Dec 2016 14:20:56 +0000 +Subject: [PATCH] MIPS: Introduce irq_stack + +commit fe8bd18ffea5327344d4ec2bf11f47951212abd0 upstream. + +Allocate a per-cpu irq stack for use within interrupt handlers. + +Also add a utility function on_irq_stack to determine if a given stack +pointer is within the irq stack for that cpu. + +Signed-off-by: Matt Redfearn <matt.redfearn@imgtec.com> +Acked-by: Jason A. Donenfeld <jason@zx2c4.com> +Cc: Thomas Gleixner <tglx@linutronix.de> +Cc: Paolo Bonzini <pbonzini@redhat.com> +Cc: Chris Metcalf <cmetcalf@mellanox.com> +Cc: Petr Mladek <pmladek@suse.com> +Cc: James Hogan <james.hogan@imgtec.com> +Cc: Paul Burton <paul.burton@imgtec.com> +Cc: Aaron Tomlin <atomlin@redhat.com> +Cc: Andrew Morton <akpm@linux-foundation.org> +Cc: linux-kernel@vger.kernel.org +Cc: linux-mips@linux-mips.org +Patchwork: https://patchwork.linux-mips.org/patch/14740/ +Signed-off-by: Ralf Baechle <ralf@linux-mips.org> + +diff --git a/arch/mips/include/asm/irq.h b/arch/mips/include/asm/irq.h +index 6bf10e796553..956db6e201d1 100644 +--- a/arch/mips/include/asm/irq.h ++++ b/arch/mips/include/asm/irq.h +@@ -17,6 +17,18 @@ + + #include <irq.h> + ++#define IRQ_STACK_SIZE THREAD_SIZE ++ ++extern void *irq_stack[NR_CPUS]; ++ ++static inline bool on_irq_stack(int cpu, unsigned long sp) ++{ ++ unsigned long low = (unsigned long)irq_stack[cpu]; ++ unsigned long high = low + IRQ_STACK_SIZE; ++ ++ return (low <= sp && sp <= high); ++} ++ + #ifdef CONFIG_I8259 + static inline int irq_canonicalize(int irq) + { +diff --git a/arch/mips/kernel/asm-offsets.c b/arch/mips/kernel/asm-offsets.c +index 6080582a26d1..a7277698d328 100644 +--- a/arch/mips/kernel/asm-offsets.c ++++ b/arch/mips/kernel/asm-offsets.c +@@ -102,6 +102,7 @@ void output_thread_info_defines(void) + OFFSET(TI_REGS, thread_info, regs); + DEFINE(_THREAD_SIZE, THREAD_SIZE); + DEFINE(_THREAD_MASK, THREAD_MASK); ++ DEFINE(_IRQ_STACK_SIZE, IRQ_STACK_SIZE); + BLANK(); + } + +diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c +index f8f5836eb3c1..ba150c755fcc 100644 +--- a/arch/mips/kernel/irq.c ++++ b/arch/mips/kernel/irq.c +@@ -25,6 +25,8 @@ + #include <linux/atomic.h> + #include <linux/uaccess.h> + ++void *irq_stack[NR_CPUS]; ++ + /* + * 'what should we do if we get a hw irq event on an illegal vector'. + * each architecture has to answer this themselves. +@@ -58,6 +60,15 @@ void __init init_IRQ(void) + clear_c0_status(ST0_IM); + + arch_init_irq(); ++ ++ for_each_possible_cpu(i) { ++ int irq_pages = IRQ_STACK_SIZE / PAGE_SIZE; ++ void *s = (void *)__get_free_pages(GFP_KERNEL, irq_pages); ++ ++ irq_stack[i] = s; ++ pr_debug("CPU%d IRQ stack at 0x%p - 0x%p\n", i, ++ irq_stack[i], irq_stack[i] + IRQ_STACK_SIZE); ++ } + } + + #ifdef CONFIG_DEBUG_STACKOVERFLOW +-- +2.12.0 + diff --git a/queue/MIPS-Lantiq-Fix-cascaded-IRQ-setup.patch b/queue/MIPS-Lantiq-Fix-cascaded-IRQ-setup.patch new file mode 100644 index 0000000..d689148 --- /dev/null +++ b/queue/MIPS-Lantiq-Fix-cascaded-IRQ-setup.patch @@ -0,0 +1,102 @@ +From 6c356eda225e3ee134ed4176b9ae3a76f793f4dd Mon Sep 17 00:00:00 2001 +From: Felix Fietkau <nbd@nbd.name> +Date: Thu, 19 Jan 2017 12:28:22 +0100 +Subject: [PATCH] MIPS: Lantiq: Fix cascaded IRQ setup + +commit 6c356eda225e3ee134ed4176b9ae3a76f793f4dd upstream. + +With the IRQ stack changes integrated, the XRX200 devices started +emitting a constant stream of kernel messages like this: + +[ 565.415310] Spurious IRQ: CAUSE=0x1100c300 + +This is caused by IP0 getting handled by plat_irq_dispatch() rather than +its vectored interrupt handler, which is fixed by commit de856416e714 +("MIPS: IRQ Stack: Fix erroneous jal to plat_irq_dispatch"). + +Fix plat_irq_dispatch() to handle non-vectored IPI interrupts correctly +by setting up IP2-6 as proper chained IRQ handlers and calling do_IRQ +for all MIPS CPU interrupts. + +Signed-off-by: Felix Fietkau <nbd@nbd.name> +Acked-by: John Crispin <john@phrozen.org> +Cc: linux-mips@linux-mips.org +Patchwork: https://patchwork.linux-mips.org/patch/15077/ +[james.hogan@imgtec.com: tweaked commit message] +Signed-off-by: James Hogan <james.hogan@imgtec.com> + +diff --git a/arch/mips/lantiq/irq.c b/arch/mips/lantiq/irq.c +index 8ac0e5994ed2..0ddf3698b85d 100644 +--- a/arch/mips/lantiq/irq.c ++++ b/arch/mips/lantiq/irq.c +@@ -269,6 +269,11 @@ static void ltq_hw5_irqdispatch(void) + DEFINE_HWx_IRQDISPATCH(5) + #endif + ++static void ltq_hw_irq_handler(struct irq_desc *desc) ++{ ++ ltq_hw_irqdispatch(irq_desc_get_irq(desc) - 2); ++} ++ + #ifdef CONFIG_MIPS_MT_SMP + void __init arch_init_ipiirq(int irq, struct irqaction *action) + { +@@ -313,23 +318,19 @@ static struct irqaction irq_call = { + asmlinkage void plat_irq_dispatch(void) + { + unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM; +- unsigned int i; +- +- if ((MIPS_CPU_TIMER_IRQ == 7) && (pending & CAUSEF_IP7)) { +- do_IRQ(MIPS_CPU_TIMER_IRQ); +- goto out; +- } else { +- for (i = 0; i < MAX_IM; i++) { +- if (pending & (CAUSEF_IP2 << i)) { +- ltq_hw_irqdispatch(i); +- goto out; +- } +- } ++ int irq; ++ ++ if (!pending) { ++ spurious_interrupt(); ++ return; + } +- pr_alert("Spurious IRQ: CAUSE=0x%08x\n", read_c0_status()); + +-out: +- return; ++ pending >>= CAUSEB_IP; ++ while (pending) { ++ irq = fls(pending) - 1; ++ do_IRQ(MIPS_CPU_IRQ_BASE + irq); ++ pending &= ~BIT(irq); ++ } + } + + static int icu_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw) +@@ -354,11 +355,6 @@ static const struct irq_domain_ops irq_domain_ops = { + .map = icu_map, + }; + +-static struct irqaction cascade = { +- .handler = no_action, +- .name = "cascade", +-}; +- + int __init icu_of_init(struct device_node *node, struct device_node *parent) + { + struct device_node *eiu_node; +@@ -390,7 +386,7 @@ int __init icu_of_init(struct device_node *node, struct device_node *parent) + mips_cpu_irq_init(); + + for (i = 0; i < MAX_IM; i++) +- setup_irq(i + 2, &cascade); ++ irq_set_chained_handler(i + 2, ltq_hw_irq_handler); + + if (cpu_has_vint) { + pr_info("Setting up vectored interrupts\n"); +-- +2.12.0 + diff --git a/queue/MIPS-Lantiq-fix-missing-xbar-kernel-panic.patch b/queue/MIPS-Lantiq-fix-missing-xbar-kernel-panic.patch new file mode 100644 index 0000000..3cf855b --- /dev/null +++ b/queue/MIPS-Lantiq-fix-missing-xbar-kernel-panic.patch @@ -0,0 +1,44 @@ +From 6ef90877eee63a0d03e83183bb44b64229b624e6 Mon Sep 17 00:00:00 2001 +From: Hauke Mehrtens <hauke@hauke-m.de> +Date: Wed, 15 Mar 2017 23:26:42 +0100 +Subject: [PATCH] MIPS: Lantiq: fix missing xbar kernel panic + +commit 6ef90877eee63a0d03e83183bb44b64229b624e6 upstream. + +Commit 08b3c894e565 ("MIPS: lantiq: Disable xbar fpi burst mode") +accidentally requested the resources from the pmu address region +instead of the xbar registers region, but the check for the return +value of request_mem_region() was wrong. Commit 98ea51cb0c8c ("MIPS: +Lantiq: Fix another request_mem_region() return code check") fixed the +check of the return value of request_mem_region() which made the kernel +panics. +This patch now makes use of the correct memory region for the cross bar. + +Fixes: 08b3c894e565 ("MIPS: lantiq: Disable xbar fpi burst mode") +Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> +Cc: John Crispin <john@phrozen.org> +Cc: james.hogan@imgtec.com +Cc: arnd@arndb.de +Cc: sergei.shtylyov@cogentembedded.com +Cc: john@phrozen.org +Cc: <stable@vger.kernel.org> # 4.4.x- +Cc: linux-mips@linux-mips.org +Patchwork: https://patchwork.linux-mips.org/patch/15751 +Signed-off-by: Ralf Baechle <ralf@linux-mips.org> + +diff --git a/arch/mips/lantiq/xway/sysctrl.c b/arch/mips/lantiq/xway/sysctrl.c +index 3c3aa05891dd..95bec460b651 100644 +--- a/arch/mips/lantiq/xway/sysctrl.c ++++ b/arch/mips/lantiq/xway/sysctrl.c +@@ -467,7 +467,7 @@ void __init ltq_soc_init(void) + + if (!np_xbar) + panic("Failed to load xbar nodes from devicetree"); +- if (of_address_to_resource(np_pmu, 0, &res_xbar)) ++ if (of_address_to_resource(np_xbar, 0, &res_xbar)) + panic("Failed to get xbar resources"); + if (!request_mem_region(res_xbar.start, resource_size(&res_xbar), + res_xbar.name)) +-- +2.12.0 + diff --git a/queue/MIPS-Only-change-28-to-thread_info-if-coming-from-us.patch b/queue/MIPS-Only-change-28-to-thread_info-if-coming-from-us.patch new file mode 100644 index 0000000..6a17ec1 --- /dev/null +++ b/queue/MIPS-Only-change-28-to-thread_info-if-coming-from-us.patch @@ -0,0 +1,61 @@ +From 510d86362a27577f5ee23f46cfb354ad49731e61 Mon Sep 17 00:00:00 2001 +From: Matt Redfearn <matt.redfearn@imgtec.com> +Date: Mon, 19 Dec 2016 14:20:58 +0000 +Subject: [PATCH] MIPS: Only change $28 to thread_info if coming from user mode + +commit 510d86362a27577f5ee23f46cfb354ad49731e61 upstream. + +The SAVE_SOME macro is used to save the execution context on all +exceptions. +If an exception occurs while executing user code, the stack is switched +to the kernel's stack for the current task, and register $28 is switched +to point to the current_thread_info, which is at the bottom of the stack +region. +If the exception occurs while executing kernel code, the stack is left, +and this change ensures that register $28 is not updated. This is the +correct behaviour when the kernel can be executing on the separate irq +stack, because the thread_info will not be at the base of it. + +With this change, register $28 is only switched to it's kernel +conventional usage of the currrent thread info pointer at the point at +which execution enters kernel space. Doing it on every exception was +redundant, but OK without an IRQ stack, but will be erroneous once that +is introduced. + +Signed-off-by: Matt Redfearn <matt.redfearn@imgtec.com> +Acked-by: Jason A. Donenfeld <jason@zx2c4.com> +Cc: Thomas Gleixner <tglx@linutronix.de> +Cc: James Hogan <james.hogan@imgtec.com> +Cc: Paul Burton <paul.burton@imgtec.com> +Cc: linux-mips@linux-mips.org +Cc: linux-kernel@vger.kernel.org +Patchwork: https://patchwork.linux-mips.org/patch/14742/ +Signed-off-by: Ralf Baechle <ralf@linux-mips.org> + +diff --git a/arch/mips/include/asm/stackframe.h b/arch/mips/include/asm/stackframe.h +index eebf39549606..2f182bdf024f 100644 +--- a/arch/mips/include/asm/stackframe.h ++++ b/arch/mips/include/asm/stackframe.h +@@ -216,12 +216,19 @@ + LONG_S $25, PT_R25(sp) + LONG_S $28, PT_R28(sp) + LONG_S $31, PT_R31(sp) ++ ++ /* Set thread_info if we're coming from user mode */ ++ mfc0 k0, CP0_STATUS ++ sll k0, 3 /* extract cu0 bit */ ++ bltz k0, 9f ++ + ori $28, sp, _THREAD_MASK + xori $28, _THREAD_MASK + #ifdef CONFIG_CPU_CAVIUM_OCTEON + .set mips64 + pref 0, 0($28) /* Prefetch the current pointer */ + #endif ++9: + .set pop + .endm + +-- +2.12.0 + diff --git a/queue/MIPS-Select-HAVE_IRQ_EXIT_ON_IRQ_STACK.patch b/queue/MIPS-Select-HAVE_IRQ_EXIT_ON_IRQ_STACK.patch new file mode 100644 index 0000000..f727711 --- /dev/null +++ b/queue/MIPS-Select-HAVE_IRQ_EXIT_ON_IRQ_STACK.patch @@ -0,0 +1,34 @@ +From 3cc3434fd6307d06b53b98ce83e76bf9807689b9 Mon Sep 17 00:00:00 2001 +From: Matt Redfearn <matt.redfearn@imgtec.com> +Date: Mon, 19 Dec 2016 14:21:00 +0000 +Subject: [PATCH] MIPS: Select HAVE_IRQ_EXIT_ON_IRQ_STACK + +commit 3cc3434fd6307d06b53b98ce83e76bf9807689b9 upstream. + +Since do_IRQ is now invoked on a separate IRQ stack, we select +HAVE_IRQ_EXIT_ON_IRQ_STACK so that softirq's may be invoked directly +from irq_exit(), rather than requiring do_softirq_own_stack. + +Signed-off-by: Matt Redfearn <matt.redfearn@imgtec.com> +Acked-by: Jason A. Donenfeld <jason@zx2c4.com> +Cc: Thomas Gleixner <tglx@linutronix.de> +Cc: linux-mips@linux-mips.org +Cc: linux-kernel@vger.kernel.org +Patchwork: https://patchwork.linux-mips.org/patch/14744/ +Signed-off-by: Ralf Baechle <ralf@linux-mips.org> + +diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig +index b3c5bde43d34..80832aa8e4fb 100644 +--- a/arch/mips/Kconfig ++++ b/arch/mips/Kconfig +@@ -9,6 +9,7 @@ config MIPS + select HAVE_CONTEXT_TRACKING + select HAVE_GENERIC_DMA_COHERENT + select HAVE_IDE ++ select HAVE_IRQ_EXIT_ON_IRQ_STACK + select HAVE_OPROFILE + select HAVE_PERF_EVENTS + select PERF_USE_VMALLOC +-- +2.12.0 + diff --git a/queue/MIPS-Stack-unwinding-while-on-IRQ-stack.patch b/queue/MIPS-Stack-unwinding-while-on-IRQ-stack.patch new file mode 100644 index 0000000..02a110f --- /dev/null +++ b/queue/MIPS-Stack-unwinding-while-on-IRQ-stack.patch @@ -0,0 +1,63 @@ +From d42d8d106b0275b027c1e8992c42aecf933436ea Mon Sep 17 00:00:00 2001 +From: Matt Redfearn <matt.redfearn@imgtec.com> +Date: Mon, 19 Dec 2016 14:20:57 +0000 +Subject: [PATCH] MIPS: Stack unwinding while on IRQ stack + +commit d42d8d106b0275b027c1e8992c42aecf933436ea upstream. + +Within unwind stack, check if the stack pointer being unwound is within +the CPU's irq_stack and if so use that page rather than the task's stack +page. + +Signed-off-by: Matt Redfearn <matt.redfearn@imgtec.com> +Acked-by: Jason A. Donenfeld <jason@zx2c4.com> +Cc: Thomas Gleixner <tglx@linutronix.de> +Cc: Adam Buchbinder <adam.buchbinder@gmail.com> +Cc: Maciej W. Rozycki <macro@imgtec.com> +Cc: Marcin Nowakowski <marcin.nowakowski@imgtec.com> +Cc: Chris Metcalf <cmetcalf@mellanox.com> +Cc: James Hogan <james.hogan@imgtec.com> +Cc: Paul Burton <paul.burton@imgtec.com> +Cc: Jiri Slaby <jslaby@suse.cz> +Cc: Andrew Morton <akpm@linux-foundation.org> +Cc: linux-mips@linux-mips.org +Cc: linux-kernel@vger.kernel.org +Patchwork: https://patchwork.linux-mips.org/patch/14741/ +Signed-off-by: Ralf Baechle <ralf@linux-mips.org> + +diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c +index 5142b1dfe8a7..48e30e0469ef 100644 +--- a/arch/mips/kernel/process.c ++++ b/arch/mips/kernel/process.c +@@ -33,6 +33,7 @@ + #include <asm/dsemul.h> + #include <asm/dsp.h> + #include <asm/fpu.h> ++#include <asm/irq.h> + #include <asm/msa.h> + #include <asm/pgtable.h> + #include <asm/mipsregs.h> +@@ -511,7 +512,19 @@ EXPORT_SYMBOL(unwind_stack_by_address); + unsigned long unwind_stack(struct task_struct *task, unsigned long *sp, + unsigned long pc, unsigned long *ra) + { +- unsigned long stack_page = (unsigned long)task_stack_page(task); ++ unsigned long stack_page = 0; ++ int cpu; ++ ++ for_each_possible_cpu(cpu) { ++ if (on_irq_stack(cpu, *sp)) { ++ stack_page = (unsigned long)irq_stack[cpu]; ++ break; ++ } ++ } ++ ++ if (!stack_page) ++ stack_page = (unsigned long)task_stack_page(task); ++ + return unwind_stack_by_address(stack_page, sp, pc, ra); + } + #endif +-- +2.12.0 + diff --git a/queue/MIPS-Switch-to-the-irq_stack-in-interrupts.patch b/queue/MIPS-Switch-to-the-irq_stack-in-interrupts.patch new file mode 100644 index 0000000..f1e4660 --- /dev/null +++ b/queue/MIPS-Switch-to-the-irq_stack-in-interrupts.patch @@ -0,0 +1,131 @@ +From dda45f701c9d7ad4ac0bb446e3a96f6df9a468d9 Mon Sep 17 00:00:00 2001 +From: Matt Redfearn <matt.redfearn@imgtec.com> +Date: Mon, 19 Dec 2016 14:20:59 +0000 +Subject: [PATCH] MIPS: Switch to the irq_stack in interrupts + +commit dda45f701c9d7ad4ac0bb446e3a96f6df9a468d9 upstream. + +When enterring interrupt context via handle_int or except_vec_vi, switch +to the irq_stack of the current CPU if it is not already in use. + +The current stack pointer is masked with the thread size and compared to +the base or the irq stack. If it does not match then the stack pointer +is set to the top of that stack, otherwise this is a nested irq being +handled on the irq stack so the stack pointer should be left as it was. + +The in-use stack pointer is placed in the callee saved register s1. It +will be saved to the stack when plat_irq_dispatch is invoked and can be +restored once control returns here. + +Signed-off-by: Matt Redfearn <matt.redfearn@imgtec.com> +Acked-by: Jason A. Donenfeld <jason@zx2c4.com> +Cc: Thomas Gleixner <tglx@linutronix.de> +Cc: James Hogan <james.hogan@imgtec.com> +Cc: Paul Burton <paul.burton@imgtec.com> +Cc: linux-mips@linux-mips.org +Cc: linux-kernel@vger.kernel.org +Patchwork: https://patchwork.linux-mips.org/patch/14743/ +Signed-off-by: Ralf Baechle <ralf@linux-mips.org> + +diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S +index dc0b29612891..0a7ba4b2f687 100644 +--- a/arch/mips/kernel/genex.S ++++ b/arch/mips/kernel/genex.S +@@ -187,9 +187,44 @@ NESTED(handle_int, PT_SIZE, sp) + + LONG_L s0, TI_REGS($28) + LONG_S sp, TI_REGS($28) +- PTR_LA ra, ret_from_irq +- PTR_LA v0, plat_irq_dispatch +- jr v0 ++ ++ /* ++ * SAVE_ALL ensures we are using a valid kernel stack for the thread. ++ * Check if we are already using the IRQ stack. ++ */ ++ move s1, sp # Preserve the sp ++ ++ /* Get IRQ stack for this CPU */ ++ ASM_CPUID_MFC0 k0, ASM_SMP_CPUID_REG ++#if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32) ++ lui k1, %hi(irq_stack) ++#else ++ lui k1, %highest(irq_stack) ++ daddiu k1, %higher(irq_stack) ++ dsll k1, 16 ++ daddiu k1, %hi(irq_stack) ++ dsll k1, 16 ++#endif ++ LONG_SRL k0, SMP_CPUID_PTRSHIFT ++ LONG_ADDU k1, k0 ++ LONG_L t0, %lo(irq_stack)(k1) ++ ++ # Check if already on IRQ stack ++ PTR_LI t1, ~(_THREAD_SIZE-1) ++ and t1, t1, sp ++ beq t0, t1, 2f ++ ++ /* Switch to IRQ stack */ ++ li t1, _IRQ_STACK_SIZE ++ PTR_ADD sp, t0, t1 ++ ++2: ++ jal plat_irq_dispatch ++ ++ /* Restore sp */ ++ move sp, s1 ++ ++ j ret_from_irq + #ifdef CONFIG_CPU_MICROMIPS + nop + #endif +@@ -262,8 +297,44 @@ NESTED(except_vec_vi_handler, 0, sp) + + LONG_L s0, TI_REGS($28) + LONG_S sp, TI_REGS($28) +- PTR_LA ra, ret_from_irq +- jr v0 ++ ++ /* ++ * SAVE_ALL ensures we are using a valid kernel stack for the thread. ++ * Check if we are already using the IRQ stack. ++ */ ++ move s1, sp # Preserve the sp ++ ++ /* Get IRQ stack for this CPU */ ++ ASM_CPUID_MFC0 k0, ASM_SMP_CPUID_REG ++#if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32) ++ lui k1, %hi(irq_stack) ++#else ++ lui k1, %highest(irq_stack) ++ daddiu k1, %higher(irq_stack) ++ dsll k1, 16 ++ daddiu k1, %hi(irq_stack) ++ dsll k1, 16 ++#endif ++ LONG_SRL k0, SMP_CPUID_PTRSHIFT ++ LONG_ADDU k1, k0 ++ LONG_L t0, %lo(irq_stack)(k1) ++ ++ # Check if already on IRQ stack ++ PTR_LI t1, ~(_THREAD_SIZE-1) ++ and t1, t1, sp ++ beq t0, t1, 2f ++ ++ /* Switch to IRQ stack */ ++ li t1, _IRQ_STACK_SIZE ++ PTR_ADD sp, t0, t1 ++ ++2: ++ jal plat_irq_dispatch ++ ++ /* Restore sp */ ++ move sp, s1 ++ ++ j ret_from_irq + END(except_vec_vi_handler) + + /* +-- +2.12.0 + diff --git a/queue/MIPS-c-r4k-Fix-Loongson-3-s-vcache-scache-waysize-ca.patch b/queue/MIPS-c-r4k-Fix-Loongson-3-s-vcache-scache-waysize-ca.patch new file mode 100644 index 0000000..dbd4b0e --- /dev/null +++ b/queue/MIPS-c-r4k-Fix-Loongson-3-s-vcache-scache-waysize-ca.patch @@ -0,0 +1,45 @@ +From 0be032c190abcdcfa948082b6a1e0d461184ba4d Mon Sep 17 00:00:00 2001 +From: Huacai Chen <chenhc@lemote.com> +Date: Thu, 16 Mar 2017 21:00:29 +0800 +Subject: [PATCH] MIPS: c-r4k: Fix Loongson-3's vcache/scache waysize + calculation + +commit 0be032c190abcdcfa948082b6a1e0d461184ba4d upstream. + +If scache.waysize is 0, r4k___flush_cache_all() will do nothing and +then cause bugs. BTW, though vcache.waysize isn't being used by now, +we also fix its calculation. + +Signed-off-by: Huacai Chen <chenhc@lemote.com> +Cc: John Crispin <john@phrozen.org> +Cc: Steven J . Hill <Steven.Hill@caviumnetworks.com> +Cc: Fuxin Zhang <zhangfx@lemote.com> +Cc: Zhangjin Wu <wuzhangjin@gmail.com> +Cc: linux-mips@linux-mips.org +Cc: stable@vger.kernel.org +Patchwork: https://patchwork.linux-mips.org/patch/15756/ +Signed-off-by: Ralf Baechle <ralf@linux-mips.org> + +diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c +index e7f798d55fbc..3fe99cb271a9 100644 +--- a/arch/mips/mm/c-r4k.c ++++ b/arch/mips/mm/c-r4k.c +@@ -1562,6 +1562,7 @@ static void probe_vcache(void) + vcache_size = c->vcache.sets * c->vcache.ways * c->vcache.linesz; + + c->vcache.waybit = 0; ++ c->vcache.waysize = vcache_size / c->vcache.ways; + + pr_info("Unified victim cache %ldkB %s, linesize %d bytes.\n", + vcache_size >> 10, way_string[c->vcache.ways], c->vcache.linesz); +@@ -1664,6 +1665,7 @@ static void __init loongson3_sc_init(void) + /* Loongson-3 has 4 cores, 1MB scache for each. scaches are shared */ + scache_size *= 4; + c->scache.waybit = 0; ++ c->scache.waysize = scache_size / c->scache.ways; + pr_info("Unified secondary cache %ldkB %s, linesize %d bytes.\n", + scache_size >> 10, way_string[c->scache.ways], c->scache.linesz); + if (scache_size) +-- +2.12.0 + diff --git a/queue/MIPS-ralink-Fix-typos-in-rt3883-pinctrl.patch b/queue/MIPS-ralink-Fix-typos-in-rt3883-pinctrl.patch new file mode 100644 index 0000000..e19d545 --- /dev/null +++ b/queue/MIPS-ralink-Fix-typos-in-rt3883-pinctrl.patch @@ -0,0 +1,43 @@ +From 7c5a3d813050ee235817b0220dd8c42359a9efd8 Mon Sep 17 00:00:00 2001 +From: John Crispin <john@phrozen.org> +Date: Sat, 25 Feb 2017 11:54:23 +0100 +Subject: [PATCH] MIPS: ralink: Fix typos in rt3883 pinctrl + +commit 7c5a3d813050ee235817b0220dd8c42359a9efd8 upstream. + +There are two copy & paste errors in the definition of the 5GHz LNA and +second ethernet pinmux. + +Fixes: f576fb6a0700 ("MIPS: ralink: cleanup the soc specific pinmux data") +Signed-off-by: John Crispin <john@phrozen.org> +Signed-off-by: Daniel Golle <daniel@makrotopia.org> +Cc: linux-mips@linux-mips.org +Cc: <stable@vger.kernel.org> # 3.19.x- +Patchwork: https://patchwork.linux-mips.org/patch/15328/ +Signed-off-by: James Hogan <james.hogan@imgtec.com> + +diff --git a/arch/mips/ralink/rt3883.c b/arch/mips/ralink/rt3883.c +index c4ffd43d3996..48ce701557a4 100644 +--- a/arch/mips/ralink/rt3883.c ++++ b/arch/mips/ralink/rt3883.c +@@ -35,7 +35,7 @@ static struct rt2880_pmx_func uartlite_func[] = { FUNC("uartlite", 0, 15, 2) }; + static struct rt2880_pmx_func jtag_func[] = { FUNC("jtag", 0, 17, 5) }; + static struct rt2880_pmx_func mdio_func[] = { FUNC("mdio", 0, 22, 2) }; + static struct rt2880_pmx_func lna_a_func[] = { FUNC("lna a", 0, 32, 3) }; +-static struct rt2880_pmx_func lna_g_func[] = { FUNC("lna a", 0, 35, 3) }; ++static struct rt2880_pmx_func lna_g_func[] = { FUNC("lna g", 0, 35, 3) }; + static struct rt2880_pmx_func pci_func[] = { + FUNC("pci-dev", 0, 40, 32), + FUNC("pci-host2", 1, 40, 32), +@@ -43,7 +43,7 @@ static struct rt2880_pmx_func pci_func[] = { + FUNC("pci-fnc", 3, 40, 32) + }; + static struct rt2880_pmx_func ge1_func[] = { FUNC("ge1", 0, 72, 12) }; +-static struct rt2880_pmx_func ge2_func[] = { FUNC("ge1", 0, 84, 12) }; ++static struct rt2880_pmx_func ge2_func[] = { FUNC("ge2", 0, 84, 12) }; + + static struct rt2880_pmx_group rt3883_pinmux_data[] = { + GRP("i2c", i2c_func, 1, RT3883_GPIO_MODE_I2C), +-- +2.12.0 + diff --git a/queue/PCI-Add-ACS-quirk-for-Intel-Union-Point.patch b/queue/PCI-Add-ACS-quirk-for-Intel-Union-Point.patch new file mode 100644 index 0000000..686204b --- /dev/null +++ b/queue/PCI-Add-ACS-quirk-for-Intel-Union-Point.patch @@ -0,0 +1,62 @@ +From 7184f5b451cf3dc61de79091d235b5d2bba2782d Mon Sep 17 00:00:00 2001 +From: Alex Williamson <alex.williamson@redhat.com> +Date: Thu, 19 Jan 2017 08:51:30 -0700 +Subject: [PATCH] PCI: Add ACS quirk for Intel Union Point + +commit 7184f5b451cf3dc61de79091d235b5d2bba2782d upstream. + +Intel 200-series chipsets have the same errata as 100-series: the ACS +capability doesn't follow the PCIe spec, the capability and control +registers are dwords rather than words. Add PCIe root port device IDs to +existing quirk. + +Signed-off-by: Alex Williamson <alex.williamson@redhat.com> +Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> + +diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c +index 1800befa8b8b..a0b3cd5726dc 100644 +--- a/drivers/pci/quirks.c ++++ b/drivers/pci/quirks.c +@@ -4150,15 +4150,35 @@ static int pci_quirk_intel_pch_acs(struct pci_dev *dev, u16 acs_flags) + * + * N.B. This doesn't fix what lspci shows. + * ++ * The 100 series chipset specification update includes this as errata #23[3]. ++ * ++ * The 200 series chipset (Union Point) has the same bug according to the ++ * specification update (Intel 200 Series Chipset Family Platform Controller ++ * Hub, Specification Update, January 2017, Revision 001, Document# 335194-001, ++ * Errata 22)[4]. Per the datasheet[5], root port PCI Device IDs for this ++ * chipset include: ++ * ++ * 0xa290-0xa29f PCI Express Root port #{0-16} ++ * 0xa2e7-0xa2ee PCI Express Root port #{17-24} ++ * + * [1] http://www.intel.com/content/www/us/en/chipsets/100-series-chipset-datasheet-vol-2.html + * [2] http://www.intel.com/content/www/us/en/chipsets/100-series-chipset-datasheet-vol-1.html ++ * [3] http://www.intel.com/content/www/us/en/chipsets/100-series-chipset-spec-update.html ++ * [4] http://www.intel.com/content/www/us/en/chipsets/200-series-chipset-pch-spec-update.html ++ * [5] http://www.intel.com/content/www/us/en/chipsets/200-series-chipset-pch-datasheet-vol-1.html + */ + static bool pci_quirk_intel_spt_pch_acs_match(struct pci_dev *dev) + { +- return pci_is_pcie(dev) && +- pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT && +- ((dev->device & ~0xf) == 0xa110 || +- (dev->device >= 0xa167 && dev->device <= 0xa16a)); ++ if (!pci_is_pcie(dev) || pci_pcie_type(dev) != PCI_EXP_TYPE_ROOT_PORT) ++ return false; ++ ++ switch (dev->device) { ++ case 0xa110 ... 0xa11f: case 0xa167 ... 0xa16a: /* Sunrise Point */ ++ case 0xa290 ... 0xa29f: case 0xa2e7 ... 0xa2ee: /* Union Point */ ++ return true; ++ } ++ ++ return false; + } + + #define INTEL_SPT_ACS_CTRL (PCI_ACS_CAP + 4) +-- +2.12.0 + diff --git a/queue/PCI-Add-ACS-quirk-for-Qualcomm-QDF2400-and-QDF2432.patch b/queue/PCI-Add-ACS-quirk-for-Qualcomm-QDF2400-and-QDF2432.patch new file mode 100644 index 0000000..554ee56 --- /dev/null +++ b/queue/PCI-Add-ACS-quirk-for-Qualcomm-QDF2400-and-QDF2432.patch @@ -0,0 +1,72 @@ +From 33be632b8443b6ac74aa293504f430604fb9abeb Mon Sep 17 00:00:00 2001 +From: Sinan Kaya <okaya@codeaurora.org> +Date: Thu, 16 Feb 2017 17:01:45 -0500 +Subject: [PATCH] PCI: Add ACS quirk for Qualcomm QDF2400 and QDF2432 + +commit 33be632b8443b6ac74aa293504f430604fb9abeb upstream. + +The Qualcomm QDF2xxx root ports don't advertise an ACS capability, but they +do provide ACS-like features to disable peer transactions and validate bus +numbers in requests. + +To be specific: +* Hardware supports source validation but it will report the issue as +Completer Abort instead of ACS Violation. + +* Hardware doesn't support peer-to-peer and each root port is a root +complex with unique segment numbers. + +* It is not possible for one root port to pass traffic to the other root +port. All PCIe transactions are terminated inside the root port. + +Add an ACS quirk for the QDF2400 and QDF2432 products. + +[bhelgaas: changelog] +Signed-off-by: Sinan Kaya <okaya@codeaurora.org> +Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> +Reviewed-by: Alex Williamson <alex.williamson@redhat.com> + +diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c +index a0b3cd5726dc..29b75d7057c4 100644 +--- a/drivers/pci/quirks.c ++++ b/drivers/pci/quirks.c +@@ -4136,6 +4136,26 @@ static int pci_quirk_intel_pch_acs(struct pci_dev *dev, u16 acs_flags) + } + + /* ++ * These QCOM root ports do provide ACS-like features to disable peer ++ * transactions and validate bus numbers in requests, but do not provide an ++ * actual PCIe ACS capability. Hardware supports source validation but it ++ * will report the issue as Completer Abort instead of ACS Violation. ++ * Hardware doesn't support peer-to-peer and each root port is a root ++ * complex with unique segment numbers. It is not possible for one root ++ * port to pass traffic to another root port. All PCIe transactions are ++ * terminated inside the root port. ++ */ ++static int pci_quirk_qcom_rp_acs(struct pci_dev *dev, u16 acs_flags) ++{ ++ u16 flags = (PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF | PCI_ACS_SV); ++ int ret = acs_flags & ~flags ? 0 : 1; ++ ++ dev_info(&dev->dev, "Using QCOM ACS Quirk (%d)\n", ret); ++ ++ return ret; ++} ++ ++/* + * Sunrise Point PCH root ports implement ACS, but unfortunately as shown in + * the datasheet (Intel 100 Series Chipset Family PCH Datasheet, Vol. 2, + * 12.1.46, 12.1.47)[1] this chipset uses dwords for the ACS capability and +@@ -4291,6 +4311,9 @@ static const struct pci_dev_acs_enabled { + /* I219 */ + { PCI_VENDOR_ID_INTEL, 0x15b7, pci_quirk_mf_endpoint_acs }, + { PCI_VENDOR_ID_INTEL, 0x15b8, pci_quirk_mf_endpoint_acs }, ++ /* QCOM QDF2xxx root ports */ ++ { 0x17cb, 0x400, pci_quirk_qcom_rp_acs }, ++ { 0x17cb, 0x401, pci_quirk_qcom_rp_acs }, + /* Intel PCH root ports */ + { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_quirk_intel_pch_acs }, + { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_quirk_intel_spt_pch_acs }, +-- +2.12.0 + diff --git a/queue/PCI-Add-Broadcom-Northstar2-PAXC-quirk-for-device-cl.patch b/queue/PCI-Add-Broadcom-Northstar2-PAXC-quirk-for-device-cl.patch new file mode 100644 index 0000000..e6de3bb --- /dev/null +++ b/queue/PCI-Add-Broadcom-Northstar2-PAXC-quirk-for-device-cl.patch @@ -0,0 +1,52 @@ +From ce709f86501a013e941e9986cb072eae375ddf3e Mon Sep 17 00:00:00 2001 +From: Jon Mason <jon.mason@broadcom.com> +Date: Fri, 27 Jan 2017 16:44:09 -0500 +Subject: [PATCH] PCI: Add Broadcom Northstar2 PAXC quirk for device class and + MPSS + +commit ce709f86501a013e941e9986cb072eae375ddf3e upstream. + +The Broadcom Northstar2 SoC has a number of quirks for the PAXC +(internal/fake) PCI bus. Specifically, the PCI config space is shared +between the root port and the first PF (ie., PF0), and a number of fields +are tied to zero (thus preventing them from being set). These cannot be +"fixed" in device firmware, so we must fix them with a quirk. + +Signed-off-by: Jon Mason <jon.mason@broadcom.com> +Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> + +diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c +index 1800befa8b8b..c5ef20a6c937 100644 +--- a/drivers/pci/quirks.c ++++ b/drivers/pci/quirks.c +@@ -2239,6 +2239,27 @@ DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_BROADCOM, + PCI_DEVICE_ID_TIGON3_5719, + quirk_brcm_5719_limit_mrrs); + ++#ifdef CONFIG_PCIE_IPROC_PLATFORM ++static void quirk_paxc_bridge(struct pci_dev *pdev) ++{ ++ /* The PCI config space is shared with the PAXC root port and the first ++ * Ethernet device. So, we need to workaround this by telling the PCI ++ * code that the bridge is not an Ethernet device. ++ */ ++ if (pdev->hdr_type == PCI_HEADER_TYPE_BRIDGE) ++ pdev->class = PCI_CLASS_BRIDGE_PCI << 8; ++ ++ /* MPSS is not being set properly (as it is currently 0). This is ++ * because that area of the PCI config space is hard coded to zero, and ++ * is not modifiable by firmware. Set this to 2 (e.g., 512 byte MPS) ++ * so that the MPS can be set to the real max value. ++ */ ++ pdev->pcie_mpss = 2; ++} ++DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0x16cd, quirk_paxc_bridge); ++DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0x16f0, quirk_paxc_bridge); ++#endif ++ + /* Originally in EDAC sources for i82875P: + * Intel tells BIOS developers to hide device 6 which + * configures the overflow device access containing +-- +2.12.0 + diff --git a/queue/PCI-Disable-MSI-for-HiSilicon-Hip06-Hip07-Root-Ports.patch b/queue/PCI-Disable-MSI-for-HiSilicon-Hip06-Hip07-Root-Ports.patch new file mode 100644 index 0000000..cfbb6ed --- /dev/null +++ b/queue/PCI-Disable-MSI-for-HiSilicon-Hip06-Hip07-Root-Ports.patch @@ -0,0 +1,47 @@ +From 72f2ff0deb870145a5a2d24cd75b4f9936159a62 Mon Sep 17 00:00:00 2001 +From: Dongdong Liu <liudongdong3@huawei.com> +Date: Fri, 3 Feb 2017 15:02:07 -0600 +Subject: [PATCH] PCI: Disable MSI for HiSilicon Hip06/Hip07 Root Ports + +commit 72f2ff0deb870145a5a2d24cd75b4f9936159a62 upstream. + +The PCIe Root Port in Hip06/Hip07 SoCs advertises an MSI capability, but it +cannot generate MSIs. It can transfer MSI/MSI-X from downstream devices, +but does not support MSI/MSI-X itself. + +Add a quirk to prevent use of MSI/MSI-X by the Root Port. + +[bhelgaas: changelog, sort vendor ID #define, drop device ID #define] +Signed-off-by: Dongdong Liu <liudongdong3@huawei.com> +Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> +Reviewed-by: Gabriele Paoloni <gabriele.paoloni@huawei.com> +Reviewed-by: Zhou Wang <wangzhou1@hisilicon.com> + +diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c +index 1800befa8b8b..c49ac99bda4b 100644 +--- a/drivers/pci/quirks.c ++++ b/drivers/pci/quirks.c +@@ -1634,6 +1634,7 @@ static void quirk_pcie_mch(struct pci_dev *pdev) + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7520_MCH, quirk_pcie_mch); + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7320_MCH, quirk_pcie_mch); + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7525_MCH, quirk_pcie_mch); ++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_HUAWEI, 0x1610, quirk_pcie_mch); + + + /* +diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h +index 73dda0edcb97..a4f77feecbb0 100644 +--- a/include/linux/pci_ids.h ++++ b/include/linux/pci_ids.h +@@ -2516,6 +2516,8 @@ + #define PCI_DEVICE_ID_KORENIX_JETCARDF2 0x1700 + #define PCI_DEVICE_ID_KORENIX_JETCARDF3 0x17ff + ++#define PCI_VENDOR_ID_HUAWEI 0x19e5 ++ + #define PCI_VENDOR_ID_NETRONOME 0x19ee + #define PCI_DEVICE_ID_NETRONOME_NFP3200 0x3200 + #define PCI_DEVICE_ID_NETRONOME_NFP3240 0x3240 +-- +2.12.0 + diff --git a/queue/PCI-Expand-VPD-access-disabled-quirk-message.patch b/queue/PCI-Expand-VPD-access-disabled-quirk-message.patch new file mode 100644 index 0000000..adcdf56 --- /dev/null +++ b/queue/PCI-Expand-VPD-access-disabled-quirk-message.patch @@ -0,0 +1,32 @@ +From 044bc425bb72ffdecfb2a66d50cb1d024ecb96d0 Mon Sep 17 00:00:00 2001 +From: Bjorn Helgaas <bhelgaas@google.com> +Date: Tue, 15 Nov 2016 08:01:17 -0600 +Subject: [PATCH] PCI: Expand "VPD access disabled" quirk message + +commit 044bc425bb72ffdecfb2a66d50cb1d024ecb96d0 upstream. + +It's not very enlightening to see + + pci 0000:07:00.0: [Firmware Bug]: VPD access disabled + +in the dmesg log because there's no clue about what the firmware bug is. +Expand the message to explain why we're disabling VPD. + +Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> + +diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c +index c232729f5b1b..7329796a896f 100644 +--- a/drivers/pci/quirks.c ++++ b/drivers/pci/quirks.c +@@ -2156,7 +2156,7 @@ static void quirk_blacklist_vpd(struct pci_dev *dev) + { + if (dev->vpd) { + dev->vpd->len = 0; +- dev_warn(&dev->dev, FW_BUG "VPD access disabled\n"); ++ dev_warn(&dev->dev, FW_BUG "disabling VPD access (can't determine size of non-standard VPD format)\n"); + } + } + +-- +2.12.0 + diff --git a/queue/PCI-Sort-the-list-of-devices-with-D3-delay-quirk-by-.patch b/queue/PCI-Sort-the-list-of-devices-with-D3-delay-quirk-by-.patch new file mode 100644 index 0000000..c807909 --- /dev/null +++ b/queue/PCI-Sort-the-list-of-devices-with-D3-delay-quirk-by-.patch @@ -0,0 +1,67 @@ +From cd3e2eb8905d14fe28a2fc75362b8ecec16f0fb6 Mon Sep 17 00:00:00 2001 +From: Andy Shevchenko <andriy.shevchenko@linux.intel.com> +Date: Tue, 14 Feb 2017 12:59:37 +0200 +Subject: [PATCH] PCI: Sort the list of devices with D3 delay quirk by ID + +commit cd3e2eb8905d14fe28a2fc75362b8ecec16f0fb6 upstream. + +Sort the list of Intel devices that have no PCI D3 delay by ID. Add a +comment for group of devices that had not been marked yet. + +There is no functional change. + +Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> +Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> + +diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c +index 1800befa8b8b..e2fd20d56add 100644 +--- a/drivers/pci/quirks.c ++++ b/drivers/pci/quirks.c +@@ -3113,30 +3113,32 @@ static void quirk_remove_d3_delay(struct pci_dev *dev) + { + dev->d3_delay = 0; + } +-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0c00, quirk_remove_d3_delay); ++/* C600 Series devices do not need 10ms d3_delay */ + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0412, quirk_remove_d3_delay); ++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0c00, quirk_remove_d3_delay); + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0c0c, quirk_remove_d3_delay); +-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c31, quirk_remove_d3_delay); +-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c3a, quirk_remove_d3_delay); +-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c3d, quirk_remove_d3_delay); +-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c2d, quirk_remove_d3_delay); +-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c20, quirk_remove_d3_delay); ++/* Lynxpoint-H PCH devices do not need 10ms d3_delay */ ++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c02, quirk_remove_d3_delay); + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c18, quirk_remove_d3_delay); + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c1c, quirk_remove_d3_delay); ++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c20, quirk_remove_d3_delay); ++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c22, quirk_remove_d3_delay); + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c26, quirk_remove_d3_delay); ++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c2d, quirk_remove_d3_delay); ++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c31, quirk_remove_d3_delay); ++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c3a, quirk_remove_d3_delay); ++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c3d, quirk_remove_d3_delay); + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c4e, quirk_remove_d3_delay); +-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c02, quirk_remove_d3_delay); +-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c22, quirk_remove_d3_delay); + /* Intel Cherrytrail devices do not need 10ms d3_delay */ + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x2280, quirk_remove_d3_delay); ++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x2298, quirk_remove_d3_delay); ++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x229c, quirk_remove_d3_delay); + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x22b0, quirk_remove_d3_delay); ++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x22b5, quirk_remove_d3_delay); ++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x22b7, quirk_remove_d3_delay); + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x22b8, quirk_remove_d3_delay); + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x22d8, quirk_remove_d3_delay); + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x22dc, quirk_remove_d3_delay); +-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x22b5, quirk_remove_d3_delay); +-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x22b7, quirk_remove_d3_delay); +-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x2298, quirk_remove_d3_delay); +-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x229c, quirk_remove_d3_delay); + + /* + * Some devices may pass our check in pci_intx_mask_supported() if +-- +2.12.0 + diff --git a/queue/PCI-thunder-pem-Factor-out-resource-lookup.patch b/queue/PCI-thunder-pem-Factor-out-resource-lookup.patch new file mode 100644 index 0000000..bf2bc30 --- /dev/null +++ b/queue/PCI-thunder-pem-Factor-out-resource-lookup.patch @@ -0,0 +1,93 @@ +From 0d414268fb8d0844030f87027e904f69d96706be Mon Sep 17 00:00:00 2001 +From: Bjorn Helgaas <bhelgaas@google.com> +Date: Wed, 30 Nov 2016 23:57:56 -0600 +Subject: [PATCH] PCI: thunder-pem: Factor out resource lookup + +commit 0d414268fb8d0844030f87027e904f69d96706be upstream. + +Pull the register resource lookup out of thunder_pem_init() so we can +easily add a corresponding lookup using ACPI. No functional change +intended. + +Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> + +diff --git a/drivers/pci/host/pci-thunder-pem.c b/drivers/pci/host/pci-thunder-pem.c +index 6abaf80ffb39..c3276eede82a 100644 +--- a/drivers/pci/host/pci-thunder-pem.c ++++ b/drivers/pci/host/pci-thunder-pem.c +@@ -284,35 +284,16 @@ static int thunder_pem_config_write(struct pci_bus *bus, unsigned int devfn, + return pci_generic_config_write(bus, devfn, where, size, val); + } + +-static int thunder_pem_init(struct pci_config_window *cfg) ++static int thunder_pem_init(struct device *dev, struct pci_config_window *cfg, ++ struct resource *res_pem) + { +- struct device *dev = cfg->parent; +- resource_size_t bar4_start; +- struct resource *res_pem; + struct thunder_pem_pci *pem_pci; +- struct platform_device *pdev; +- +- /* Only OF support for now */ +- if (!dev->of_node) +- return -EINVAL; ++ resource_size_t bar4_start; + + pem_pci = devm_kzalloc(dev, sizeof(*pem_pci), GFP_KERNEL); + if (!pem_pci) + return -ENOMEM; + +- pdev = to_platform_device(dev); +- +- /* +- * The second register range is the PEM bridge to the PCIe +- * bus. It has a different config access method than those +- * devices behind the bridge. +- */ +- res_pem = platform_get_resource(pdev, IORESOURCE_MEM, 1); +- if (!res_pem) { +- dev_err(dev, "missing \"reg[1]\"property\n"); +- return -EINVAL; +- } +- + pem_pci->pem_reg_base = devm_ioremap(dev, res_pem->start, 0x10000); + if (!pem_pci->pem_reg_base) + return -ENOMEM; +@@ -332,9 +313,32 @@ static int thunder_pem_init(struct pci_config_window *cfg) + return 0; + } + ++static int thunder_pem_platform_init(struct pci_config_window *cfg) ++{ ++ struct device *dev = cfg->parent; ++ struct platform_device *pdev = to_platform_device(dev); ++ struct resource *res_pem; ++ ++ if (!dev->of_node) ++ return -EINVAL; ++ ++ /* ++ * The second register range is the PEM bridge to the PCIe ++ * bus. It has a different config access method than those ++ * devices behind the bridge. ++ */ ++ res_pem = platform_get_resource(pdev, IORESOURCE_MEM, 1); ++ if (!res_pem) { ++ dev_err(dev, "missing \"reg[1]\"property\n"); ++ return -EINVAL; ++ } ++ ++ return thunder_pem_init(dev, cfg, res_pem); ++} ++ + static struct pci_ecam_ops pci_thunder_pem_ops = { + .bus_shift = 24, +- .init = thunder_pem_init, ++ .init = thunder_pem_platform_init, + .pci_ops = { + .map_bus = pci_ecam_map_bus, + .read = thunder_pem_config_read, +-- +2.12.0 + diff --git a/queue/Reset-TreeId-to-zero-on-SMB2-TREE_CONNECT.patch b/queue/Reset-TreeId-to-zero-on-SMB2-TREE_CONNECT.patch new file mode 100644 index 0000000..9783943 --- /dev/null +++ b/queue/Reset-TreeId-to-zero-on-SMB2-TREE_CONNECT.patch @@ -0,0 +1,37 @@ +From 806a28efe9b78ffae5e2757e1ee924b8e50c08ab Mon Sep 17 00:00:00 2001 +From: Jan-Marek Glogowski <glogow@fbihome.de> +Date: Mon, 20 Feb 2017 12:25:58 +0100 +Subject: [PATCH] Reset TreeId to zero on SMB2 TREE_CONNECT + +commit 806a28efe9b78ffae5e2757e1ee924b8e50c08ab upstream. + +Currently the cifs module breaks the CIFS specs on reconnect as +described in http://msdn.microsoft.com/en-us/library/cc246529.aspx: + +"TreeId (4 bytes): Uniquely identifies the tree connect for the +command. This MUST be 0 for the SMB2 TREE_CONNECT Request." + +Signed-off-by: Jan-Marek Glogowski <glogow@fbihome.de> +Reviewed-by: Aurelien Aptel <aaptel@suse.com> +Tested-by: Aurelien Aptel <aaptel@suse.com> +Signed-off-by: Steve French <smfrench@gmail.com> +CC: Stable <stable@vger.kernel.org> + +diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c +index 7446496850a3..66fa1b941cdf 100644 +--- a/fs/cifs/smb2pdu.c ++++ b/fs/cifs/smb2pdu.c +@@ -1185,6 +1185,10 @@ SMB2_tcon(const unsigned int xid, struct cifs_ses *ses, const char *tree, + return -EINVAL; + } + ++ /* SMB2 TREE_CONNECT request must be called with TreeId == 0 */ ++ if (tcon) ++ tcon->tid = 0; ++ + rc = small_smb2_init(SMB2_TREE_CONNECT, tcon, (void **) &req); + if (rc) { + kfree(unc_path); +-- +2.12.0 + diff --git a/queue/acpi-nfit-libnvdimm-fix-interleave-set-cookie-calcul.patch b/queue/acpi-nfit-libnvdimm-fix-interleave-set-cookie-calcul.patch new file mode 100644 index 0000000..0af495a --- /dev/null +++ b/queue/acpi-nfit-libnvdimm-fix-interleave-set-cookie-calcul.patch @@ -0,0 +1,42 @@ +From b03b99a329a14b7302f37c3ea6da3848db41c8c5 Mon Sep 17 00:00:00 2001 +From: Dan Williams <dan.j.williams@intel.com> +Date: Mon, 27 Mar 2017 21:53:38 -0700 +Subject: [PATCH] acpi, nfit, libnvdimm: fix interleave set cookie calculation + (64-bit comparison) + +commit b03b99a329a14b7302f37c3ea6da3848db41c8c5 upstream. + +While reviewing the -stable patch for commit 86ef58a4e35e "nfit, +libnvdimm: fix interleave set cookie calculation" Ben noted: + + "This is returning an int, thus it's effectively doing a 32-bit + comparison and not the 64-bit comparison you say is needed." + +Update the compare operation to be immune to this integer demotion problem. + +Cc: <stable@vger.kernel.org> +Cc: Nicholas Moulin <nicholas.w.moulin@linux.intel.com> +Fixes: 86ef58a4e35e ("nfit, libnvdimm: fix interleave set cookie calculation") +Reported-by: Ben Hutchings <ben@decadent.org.uk> +Signed-off-by: Dan Williams <dan.j.williams@intel.com> + +diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c +index 662036bdc65e..c8ea9d698cd0 100644 +--- a/drivers/acpi/nfit/core.c ++++ b/drivers/acpi/nfit/core.c +@@ -1617,7 +1617,11 @@ static int cmp_map(const void *m0, const void *m1) + const struct nfit_set_info_map *map0 = m0; + const struct nfit_set_info_map *map1 = m1; + +- return map0->region_offset - map1->region_offset; ++ if (map0->region_offset < map1->region_offset) ++ return -1; ++ else if (map0->region_offset > map1->region_offset) ++ return 1; ++ return 0; + } + + /* Retrieve the nth entry referencing this spa */ +-- +2.12.0 + diff --git a/queue/arm-arm64-KVM-Take-mmap_sem-in-kvm_arch_prepare_memo.patch b/queue/arm-arm64-KVM-Take-mmap_sem-in-kvm_arch_prepare_memo.patch new file mode 100644 index 0000000..94cbfe5 --- /dev/null +++ b/queue/arm-arm64-KVM-Take-mmap_sem-in-kvm_arch_prepare_memo.patch @@ -0,0 +1,66 @@ +From 72f310481a08db821b614e7b5d00febcc9064b36 Mon Sep 17 00:00:00 2001 +From: Marc Zyngier <marc.zyngier@arm.com> +Date: Thu, 16 Mar 2017 18:20:50 +0000 +Subject: [PATCH] arm/arm64: KVM: Take mmap_sem in + kvm_arch_prepare_memory_region + +commit 72f310481a08db821b614e7b5d00febcc9064b36 upstream. + +We don't hold the mmap_sem while searching for VMAs (via find_vma), in +kvm_arch_prepare_memory_region, which can end up in expected failures. + +Fixes: commit 8eef91239e57 ("arm/arm64: KVM: map MMIO regions at creation time") +Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org> +Cc: Eric Auger <eric.auger@rehat.com> +Cc: stable@vger.kernel.org # v3.18+ +Reviewed-by: Christoffer Dall <cdall@linaro.org> +[ Handle dirty page logging failure case ] +Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com> +Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> + +diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c +index f2e2e0c6d6fd..13b9c1fa8961 100644 +--- a/arch/arm/kvm/mmu.c ++++ b/arch/arm/kvm/mmu.c +@@ -1803,6 +1803,7 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm, + (KVM_PHYS_SIZE >> PAGE_SHIFT)) + return -EFAULT; + ++ down_read(¤t->mm->mmap_sem); + /* + * A memory region could potentially cover multiple VMAs, and any holes + * between them, so iterate over all of them to find out if we can map +@@ -1846,8 +1847,10 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm, + pa += vm_start - vma->vm_start; + + /* IO region dirty page logging not allowed */ +- if (memslot->flags & KVM_MEM_LOG_DIRTY_PAGES) +- return -EINVAL; ++ if (memslot->flags & KVM_MEM_LOG_DIRTY_PAGES) { ++ ret = -EINVAL; ++ goto out; ++ } + + ret = kvm_phys_addr_ioremap(kvm, gpa, pa, + vm_end - vm_start, +@@ -1859,7 +1862,7 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm, + } while (hva < reg_end); + + if (change == KVM_MR_FLAGS_ONLY) +- return ret; ++ goto out; + + spin_lock(&kvm->mmu_lock); + if (ret) +@@ -1867,6 +1870,8 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm, + else + stage2_flush_memslot(kvm, memslot); + spin_unlock(&kvm->mmu_lock); ++out: ++ up_read(¤t->mm->mmap_sem); + return ret; + } + +-- +2.12.0 + diff --git a/queue/arm-arm64-KVM-Take-mmap_sem-in-stage2_unmap_vm.patch b/queue/arm-arm64-KVM-Take-mmap_sem-in-stage2_unmap_vm.patch new file mode 100644 index 0000000..25642ac --- /dev/null +++ b/queue/arm-arm64-KVM-Take-mmap_sem-in-stage2_unmap_vm.patch @@ -0,0 +1,40 @@ +From 90f6e150e44a0dc3883110eeb3ab35d1be42b6bb Mon Sep 17 00:00:00 2001 +From: Marc Zyngier <marc.zyngier@arm.com> +Date: Thu, 16 Mar 2017 18:20:49 +0000 +Subject: [PATCH] arm/arm64: KVM: Take mmap_sem in stage2_unmap_vm + +commit 90f6e150e44a0dc3883110eeb3ab35d1be42b6bb upstream. + +We don't hold the mmap_sem while searching for the VMAs when +we try to unmap each memslot for a VM. Fix this properly to +avoid unexpected results. + +Fixes: commit 957db105c997 ("arm/arm64: KVM: Introduce stage2_unmap_vm") +Cc: stable@vger.kernel.org # v3.19+ +Reviewed-by: Christoffer Dall <cdall@linaro.org> +Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com> +Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> + +diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c +index 962616fd4ddd..f2e2e0c6d6fd 100644 +--- a/arch/arm/kvm/mmu.c ++++ b/arch/arm/kvm/mmu.c +@@ -803,6 +803,7 @@ void stage2_unmap_vm(struct kvm *kvm) + int idx; + + idx = srcu_read_lock(&kvm->srcu); ++ down_read(¤t->mm->mmap_sem); + spin_lock(&kvm->mmu_lock); + + slots = kvm_memslots(kvm); +@@ -810,6 +811,7 @@ void stage2_unmap_vm(struct kvm *kvm) + stage2_unmap_memslot(kvm, memslot); + + spin_unlock(&kvm->mmu_lock); ++ up_read(¤t->mm->mmap_sem); + srcu_read_unlock(&kvm->srcu, idx); + } + +-- +2.12.0 + diff --git a/queue/arm-kernel-Add-SMC-structure-parameter.patch b/queue/arm-kernel-Add-SMC-structure-parameter.patch new file mode 100644 index 0000000..94351ff --- /dev/null +++ b/queue/arm-kernel-Add-SMC-structure-parameter.patch @@ -0,0 +1,195 @@ +From 680a0873e193bae666439f4b5e32c758e68f114c Mon Sep 17 00:00:00 2001 +From: Andy Gross <andy.gross@linaro.org> +Date: Wed, 1 Feb 2017 11:28:27 -0600 +Subject: [PATCH] arm: kernel: Add SMC structure parameter + +commit 680a0873e193bae666439f4b5e32c758e68f114c upstream. + +This patch adds a quirk parameter to the arm_smccc_(smc/hvc) calls. +The quirk structure allows for specialized SMC operations due to SoC +specific requirements. The current arm_smccc_(smc/hvc) is renamed and +macros are used instead to specify the standard arm_smccc_(smc/hvc) or +the arm_smccc_(smc/hvc)_quirk function. + +This patch and partial implementation was suggested by Will Deacon. + +Signed-off-by: Andy Gross <andy.gross@linaro.org> +Reviewed-by: Will Deacon <will.deacon@arm.com> +Signed-off-by: Will Deacon <will.deacon@arm.com> + +diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c +index 7e45f69a0ddc..8e8d20cdbce7 100644 +--- a/arch/arm/kernel/armksyms.c ++++ b/arch/arm/kernel/armksyms.c +@@ -178,6 +178,6 @@ EXPORT_SYMBOL(__pv_offset); + #endif + + #ifdef CONFIG_HAVE_ARM_SMCCC +-EXPORT_SYMBOL(arm_smccc_smc); +-EXPORT_SYMBOL(arm_smccc_hvc); ++EXPORT_SYMBOL(__arm_smccc_smc); ++EXPORT_SYMBOL(__arm_smccc_hvc); + #endif +diff --git a/arch/arm/kernel/smccc-call.S b/arch/arm/kernel/smccc-call.S +index 2e48b674aab1..e5d43066b889 100644 +--- a/arch/arm/kernel/smccc-call.S ++++ b/arch/arm/kernel/smccc-call.S +@@ -46,17 +46,19 @@ UNWIND( .fnend) + /* + * void smccc_smc(unsigned long a0, unsigned long a1, unsigned long a2, + * unsigned long a3, unsigned long a4, unsigned long a5, +- * unsigned long a6, unsigned long a7, struct arm_smccc_res *res) ++ * unsigned long a6, unsigned long a7, struct arm_smccc_res *res, ++ * struct arm_smccc_quirk *quirk) + */ +-ENTRY(arm_smccc_smc) ++ENTRY(__arm_smccc_smc) + SMCCC SMCCC_SMC +-ENDPROC(arm_smccc_smc) ++ENDPROC(__arm_smccc_smc) + + /* + * void smccc_hvc(unsigned long a0, unsigned long a1, unsigned long a2, + * unsigned long a3, unsigned long a4, unsigned long a5, +- * unsigned long a6, unsigned long a7, struct arm_smccc_res *res) ++ * unsigned long a6, unsigned long a7, struct arm_smccc_res *res, ++ * struct arm_smccc_quirk *quirk) + */ +-ENTRY(arm_smccc_hvc) ++ENTRY(__arm_smccc_hvc) + SMCCC SMCCC_HVC +-ENDPROC(arm_smccc_hvc) ++ENDPROC(__arm_smccc_hvc) +diff --git a/arch/arm64/kernel/arm64ksyms.c b/arch/arm64/kernel/arm64ksyms.c +index 78f368039c79..e9c4dc9e0ada 100644 +--- a/arch/arm64/kernel/arm64ksyms.c ++++ b/arch/arm64/kernel/arm64ksyms.c +@@ -73,5 +73,5 @@ NOKPROBE_SYMBOL(_mcount); + #endif + + /* arm-smccc */ +-EXPORT_SYMBOL(arm_smccc_smc); +-EXPORT_SYMBOL(arm_smccc_hvc); ++EXPORT_SYMBOL(__arm_smccc_smc); ++EXPORT_SYMBOL(__arm_smccc_hvc); +diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c +index bc049afc73a7..b3bb7ef97bc8 100644 +--- a/arch/arm64/kernel/asm-offsets.c ++++ b/arch/arm64/kernel/asm-offsets.c +@@ -143,8 +143,11 @@ int main(void) + DEFINE(SLEEP_STACK_DATA_SYSTEM_REGS, offsetof(struct sleep_stack_data, system_regs)); + DEFINE(SLEEP_STACK_DATA_CALLEE_REGS, offsetof(struct sleep_stack_data, callee_saved_regs)); + #endif +- DEFINE(ARM_SMCCC_RES_X0_OFFS, offsetof(struct arm_smccc_res, a0)); +- DEFINE(ARM_SMCCC_RES_X2_OFFS, offsetof(struct arm_smccc_res, a2)); ++ DEFINE(ARM_SMCCC_RES_X0_OFFS, offsetof(struct arm_smccc_res, a0)); ++ DEFINE(ARM_SMCCC_RES_X2_OFFS, offsetof(struct arm_smccc_res, a2)); ++ DEFINE(ARM_SMCCC_QUIRK_ID_OFFS, offsetof(struct arm_smccc_quirk, id)); ++ DEFINE(ARM_SMCCC_QUIRK_STATE_OFFS, offsetof(struct arm_smccc_quirk, state)); ++ + BLANK(); + DEFINE(HIBERN_PBE_ORIG, offsetof(struct pbe, orig_address)); + DEFINE(HIBERN_PBE_ADDR, offsetof(struct pbe, address)); +diff --git a/arch/arm64/kernel/smccc-call.S b/arch/arm64/kernel/smccc-call.S +index ae0496fa4235..ba60a8cb07d2 100644 +--- a/arch/arm64/kernel/smccc-call.S ++++ b/arch/arm64/kernel/smccc-call.S +@@ -27,17 +27,19 @@ + /* + * void arm_smccc_smc(unsigned long a0, unsigned long a1, unsigned long a2, + * unsigned long a3, unsigned long a4, unsigned long a5, +- * unsigned long a6, unsigned long a7, struct arm_smccc_res *res) ++ * unsigned long a6, unsigned long a7, struct arm_smccc_res *res, ++ * struct arm_smccc_quirk *quirk) + */ +-ENTRY(arm_smccc_smc) ++ENTRY(__arm_smccc_smc) + SMCCC smc +-ENDPROC(arm_smccc_smc) ++ENDPROC(__arm_smccc_smc) + + /* + * void arm_smccc_hvc(unsigned long a0, unsigned long a1, unsigned long a2, + * unsigned long a3, unsigned long a4, unsigned long a5, +- * unsigned long a6, unsigned long a7, struct arm_smccc_res *res) ++ * unsigned long a6, unsigned long a7, struct arm_smccc_res *res, ++ * struct arm_smccc_quirk *quirk) + */ +-ENTRY(arm_smccc_hvc) ++ENTRY(__arm_smccc_hvc) + SMCCC hvc +-ENDPROC(arm_smccc_hvc) ++ENDPROC(__arm_smccc_hvc) +diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h +index b5abfda80465..c66f8ae94b5a 100644 +--- a/include/linux/arm-smccc.h ++++ b/include/linux/arm-smccc.h +@@ -72,33 +72,57 @@ struct arm_smccc_res { + }; + + /** +- * arm_smccc_smc() - make SMC calls ++ * struct arm_smccc_quirk - Contains quirk information ++ * @id: quirk identification ++ * @state: quirk specific information ++ * @a6: Qualcomm quirk entry for returning post-smc call contents of a6 ++ */ ++struct arm_smccc_quirk { ++ int id; ++ union { ++ unsigned long a6; ++ } state; ++}; ++ ++/** ++ * __arm_smccc_smc() - make SMC calls + * @a0-a7: arguments passed in registers 0 to 7 + * @res: result values from registers 0 to 3 ++ * @quirk: points to an arm_smccc_quirk, or NULL when no quirks are required. + * + * This function is used to make SMC calls following SMC Calling Convention. + * The content of the supplied param are copied to registers 0 to 7 prior + * to the SMC instruction. The return values are updated with the content +- * from register 0 to 3 on return from the SMC instruction. ++ * from register 0 to 3 on return from the SMC instruction. An optional ++ * quirk structure provides vendor specific behavior. + */ +-asmlinkage void arm_smccc_smc(unsigned long a0, unsigned long a1, ++asmlinkage void __arm_smccc_smc(unsigned long a0, unsigned long a1, + unsigned long a2, unsigned long a3, unsigned long a4, + unsigned long a5, unsigned long a6, unsigned long a7, +- struct arm_smccc_res *res); ++ struct arm_smccc_res *res, struct arm_smccc_quirk *quirk); + + /** +- * arm_smccc_hvc() - make HVC calls ++ * __arm_smccc_hvc() - make HVC calls + * @a0-a7: arguments passed in registers 0 to 7 + * @res: result values from registers 0 to 3 + * + * This function is used to make HVC calls following SMC Calling + * Convention. The content of the supplied param are copied to registers 0 + * to 7 prior to the HVC instruction. The return values are updated with +- * the content from register 0 to 3 on return from the HVC instruction. ++ * the content from register 0 to 3 on return from the HVC instruction. An ++ * optional quirk structure provides vendor specific behavior. + */ +-asmlinkage void arm_smccc_hvc(unsigned long a0, unsigned long a1, ++asmlinkage void __arm_smccc_hvc(unsigned long a0, unsigned long a1, + unsigned long a2, unsigned long a3, unsigned long a4, + unsigned long a5, unsigned long a6, unsigned long a7, +- struct arm_smccc_res *res); ++ struct arm_smccc_res *res, struct arm_smccc_quirk *quirk); ++ ++#define arm_smccc_smc(...) __arm_smccc_smc(__VA_ARGS__, NULL) ++ ++#define arm_smccc_smc_quirk(...) __arm_smccc_smc(__VA_ARGS__) ++ ++#define arm_smccc_hvc(...) __arm_smccc_hvc(__VA_ARGS__, NULL) ++ ++#define arm_smccc_hvc_quirk(...) __arm_smccc_hvc(__VA_ARGS__) + + #endif /*__LINUX_ARM_SMCCC_H*/ +-- +2.12.0 + diff --git a/queue/arm64-PCI-Add-local-struct-device-pointers.patch b/queue/arm64-PCI-Add-local-struct-device-pointers.patch new file mode 100644 index 0000000..64013f5 --- /dev/null +++ b/queue/arm64-PCI-Add-local-struct-device-pointers.patch @@ -0,0 +1,53 @@ +From dfd1972c2b464c10fb585c4c60b594e09d181a01 Mon Sep 17 00:00:00 2001 +From: Bjorn Helgaas <bhelgaas@google.com> +Date: Thu, 1 Dec 2016 11:33:57 -0600 +Subject: [PATCH] arm64: PCI: Add local struct device pointers + +commit dfd1972c2b464c10fb585c4c60b594e09d181a01 upstream. + +Use a local "struct device *dev" for brevity. No functional change +intended. + +Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> +Acked-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> + +diff --git a/arch/arm64/kernel/pci.c b/arch/arm64/kernel/pci.c +index acf38722457b..8183c9803206 100644 +--- a/arch/arm64/kernel/pci.c ++++ b/arch/arm64/kernel/pci.c +@@ -121,6 +121,7 @@ int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge) + static struct pci_config_window * + pci_acpi_setup_ecam_mapping(struct acpi_pci_root *root) + { ++ struct device *dev = &root->device->dev; + struct resource *bus_res = &root->secondary; + u16 seg = root->segment; + struct pci_config_window *cfg; +@@ -132,8 +133,7 @@ pci_acpi_setup_ecam_mapping(struct acpi_pci_root *root) + root->mcfg_addr = pci_mcfg_lookup(seg, bus_res); + + if (!root->mcfg_addr) { +- dev_err(&root->device->dev, "%04x:%pR ECAM region not found\n", +- seg, bus_res); ++ dev_err(dev, "%04x:%pR ECAM region not found\n", seg, bus_res); + return NULL; + } + +@@ -141,11 +141,10 @@ pci_acpi_setup_ecam_mapping(struct acpi_pci_root *root) + cfgres.start = root->mcfg_addr + bus_res->start * bsz; + cfgres.end = cfgres.start + resource_size(bus_res) * bsz - 1; + cfgres.flags = IORESOURCE_MEM; +- cfg = pci_ecam_create(&root->device->dev, &cfgres, bus_res, +- &pci_generic_ecam_ops); ++ cfg = pci_ecam_create(dev, &cfgres, bus_res, &pci_generic_ecam_ops); + if (IS_ERR(cfg)) { +- dev_err(&root->device->dev, "%04x:%pR error %ld mapping ECAM\n", +- seg, bus_res, PTR_ERR(cfg)); ++ dev_err(dev, "%04x:%pR error %ld mapping ECAM\n", seg, bus_res, ++ PTR_ERR(cfg)); + return NULL; + } + +-- +2.12.0 + diff --git a/queue/arm64-PCI-Manage-controller-specific-data-on-per-con.patch b/queue/arm64-PCI-Manage-controller-specific-data-on-per-con.patch new file mode 100644 index 0000000..03bf30c --- /dev/null +++ b/queue/arm64-PCI-Manage-controller-specific-data-on-per-con.patch @@ -0,0 +1,79 @@ +From 093d24a204425f71f4f106b7e62c8df4b456e1cc Mon Sep 17 00:00:00 2001 +From: Tomasz Nowicki <tn@semihalf.com> +Date: Thu, 24 Nov 2016 12:05:23 +0100 +Subject: [PATCH] arm64: PCI: Manage controller-specific data on per-controller + basis + +commit 093d24a204425f71f4f106b7e62c8df4b456e1cc upstream. + +Currently we use one shared global acpi_pci_root_ops structure to keep +controller-specific ops. We pass its pointer to acpi_pci_root_create() and +associate it with a host bridge instance for good. Such a design implies +serious drawback. Any potential manipulation on the single system-wide +acpi_pci_root_ops leads to kernel crash. The structure content is not +really changing even across multiple host bridges creation; thus it was not +an issue so far. + +In preparation for adding ECAM quirks mechanism (where controller-specific +PCI ops may be different for each host bridge) allocate new +acpi_pci_root_ops and fill in with data for each bridge. Now it is safe to +have different controller-specific info. As a consequence free +acpi_pci_root_ops when host bridge is released. + +No functional changes in this patch. + +Signed-off-by: Tomasz Nowicki <tn@semihalf.com> +Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> +Acked-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> + +diff --git a/arch/arm64/kernel/pci.c b/arch/arm64/kernel/pci.c +index 216dff6c5877..ac4509d2668a 100644 +--- a/arch/arm64/kernel/pci.c ++++ b/arch/arm64/kernel/pci.c +@@ -168,33 +168,36 @@ static void pci_acpi_generic_release_info(struct acpi_pci_root_info *ci) + + ri = container_of(ci, struct acpi_pci_generic_root_info, common); + pci_ecam_free(ri->cfg); ++ kfree(ci->ops); + kfree(ri); + } + +-static struct acpi_pci_root_ops acpi_pci_root_ops = { +- .release_info = pci_acpi_generic_release_info, +-}; +- + /* Interface called from ACPI code to setup PCI host controller */ + struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root) + { + int node = acpi_get_node(root->device->handle); + struct acpi_pci_generic_root_info *ri; + struct pci_bus *bus, *child; ++ struct acpi_pci_root_ops *root_ops; + + ri = kzalloc_node(sizeof(*ri), GFP_KERNEL, node); + if (!ri) + return NULL; + ++ root_ops = kzalloc_node(sizeof(*root_ops), GFP_KERNEL, node); ++ if (!root_ops) ++ return NULL; ++ + ri->cfg = pci_acpi_setup_ecam_mapping(root); + if (!ri->cfg) { + kfree(ri); ++ kfree(root_ops); + return NULL; + } + +- acpi_pci_root_ops.pci_ops = &ri->cfg->ops->pci_ops; +- bus = acpi_pci_root_create(root, &acpi_pci_root_ops, &ri->common, +- ri->cfg); ++ root_ops->release_info = pci_acpi_generic_release_info; ++ root_ops->pci_ops = &ri->cfg->ops->pci_ops; ++ bus = acpi_pci_root_create(root, root_ops, &ri->common, ri->cfg); + if (!bus) + return NULL; + +-- +2.12.0 + diff --git a/queue/arm64-dts-hisi-fix-hip06-sas-am-max-trans-quirk.patch b/queue/arm64-dts-hisi-fix-hip06-sas-am-max-trans-quirk.patch new file mode 100644 index 0000000..652deba --- /dev/null +++ b/queue/arm64-dts-hisi-fix-hip06-sas-am-max-trans-quirk.patch @@ -0,0 +1,30 @@ +From f65e786604b34d0b599b8c01ecca28be2d746290 Mon Sep 17 00:00:00 2001 +From: John Garry <john.garry@huawei.com> +Date: Tue, 8 Nov 2016 00:44:23 +0800 +Subject: [PATCH] arm64: dts: hisi: fix hip06 sas am-max-trans quirk + +commit f65e786604b34d0b599b8c01ecca28be2d746290 upstream. + +The string for the am max transmissions quirk property +is not correct -> fix it. + +Signed-off-by: John Garry <john.garry@huawei.com> +Reviewed-by: Xiang Chen <chenxiang66@hisilicon.com> +Signed-off-by: Wei Xu <xuwei5@hisilicon.com> + +diff --git a/arch/arm64/boot/dts/hisilicon/hip06.dtsi b/arch/arm64/boot/dts/hisilicon/hip06.dtsi +index da61e4384eeb..a05ad046cb9a 100644 +--- a/arch/arm64/boot/dts/hisilicon/hip06.dtsi ++++ b/arch/arm64/boot/dts/hisilicon/hip06.dtsi +@@ -590,7 +590,7 @@ + reg = <0 0xa2000000 0 0x10000>; + sas-addr = [50 01 88 20 16 00 00 00]; + hisilicon,sas-syscon = <&pcie_subctl>; +- am-max-trans; ++ hip06-sas-v2-quirk-amt; + ctrl-reset-reg = <0xa18>; + ctrl-reset-sts-reg = <0x5a0c>; + ctrl-clock-ena-reg = <0x318>; +-- +2.12.0 + diff --git a/queue/arm64-mm-unaligned-access-by-user-land-should-be-rec.patch b/queue/arm64-mm-unaligned-access-by-user-land-should-be-rec.patch new file mode 100644 index 0000000..811c5e1 --- /dev/null +++ b/queue/arm64-mm-unaligned-access-by-user-land-should-be-rec.patch @@ -0,0 +1,122 @@ +From 09a6adf53d42ca3088fa3fb41f40b768efc711ed Mon Sep 17 00:00:00 2001 +From: Victor Kamensky <kamensky@cisco.com> +Date: Mon, 3 Apr 2017 22:51:01 -0700 +Subject: [PATCH] arm64: mm: unaligned access by user-land should be received + as SIGBUS + +commit 09a6adf53d42ca3088fa3fb41f40b768efc711ed upstream. + +After 52d7523 (arm64: mm: allow the kernel to handle alignment faults on +user accesses) commit user-land accesses that produce unaligned exceptions +like in case of aarch32 ldm/stm/ldrd/strd instructions operating on +unaligned memory received by user-land as SIGSEGV. It is wrong, it should +be reported as SIGBUS as it was before 52d7523 commit. + +Changed do_bad_area function to take signal and code parameters out of esr +value using fault_info table, so in case of do_alignment_fault fault +user-land will receive SIGBUS. Wrapped access to fault_info table into +esr_to_fault_info function. + +Cc: <stable@vger.kernel.org> +Fixes: 52d7523 (arm64: mm: allow the kernel to handle alignment faults on user accesses) +Signed-off-by: Victor Kamensky <kamensky@cisco.com> +Signed-off-by: Will Deacon <will.deacon@arm.com> + +diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c +index 4bf899fb451b..1b35b8bddbfb 100644 +--- a/arch/arm64/mm/fault.c ++++ b/arch/arm64/mm/fault.c +@@ -42,7 +42,20 @@ + #include <asm/pgtable.h> + #include <asm/tlbflush.h> + +-static const char *fault_name(unsigned int esr); ++struct fault_info { ++ int (*fn)(unsigned long addr, unsigned int esr, ++ struct pt_regs *regs); ++ int sig; ++ int code; ++ const char *name; ++}; ++ ++static const struct fault_info fault_info[]; ++ ++static inline const struct fault_info *esr_to_fault_info(unsigned int esr) ++{ ++ return fault_info + (esr & 63); ++} + + #ifdef CONFIG_KPROBES + static inline int notify_page_fault(struct pt_regs *regs, unsigned int esr) +@@ -197,10 +210,12 @@ static void __do_user_fault(struct task_struct *tsk, unsigned long addr, + struct pt_regs *regs) + { + struct siginfo si; ++ const struct fault_info *inf; + + if (unhandled_signal(tsk, sig) && show_unhandled_signals_ratelimited()) { ++ inf = esr_to_fault_info(esr); + pr_info("%s[%d]: unhandled %s (%d) at 0x%08lx, esr 0x%03x\n", +- tsk->comm, task_pid_nr(tsk), fault_name(esr), sig, ++ tsk->comm, task_pid_nr(tsk), inf->name, sig, + addr, esr); + show_pte(tsk->mm, addr); + show_regs(regs); +@@ -219,14 +234,16 @@ static void do_bad_area(unsigned long addr, unsigned int esr, struct pt_regs *re + { + struct task_struct *tsk = current; + struct mm_struct *mm = tsk->active_mm; ++ const struct fault_info *inf; + + /* + * If we are in kernel mode at this point, we have no context to + * handle this fault with. + */ +- if (user_mode(regs)) +- __do_user_fault(tsk, addr, esr, SIGSEGV, SEGV_MAPERR, regs); +- else ++ if (user_mode(regs)) { ++ inf = esr_to_fault_info(esr); ++ __do_user_fault(tsk, addr, esr, inf->sig, inf->code, regs); ++ } else + __do_kernel_fault(mm, addr, esr, regs); + } + +@@ -488,12 +505,7 @@ static int do_bad(unsigned long addr, unsigned int esr, struct pt_regs *regs) + return 1; + } + +-static const struct fault_info { +- int (*fn)(unsigned long addr, unsigned int esr, struct pt_regs *regs); +- int sig; +- int code; +- const char *name; +-} fault_info[] = { ++static const struct fault_info fault_info[] = { + { do_bad, SIGBUS, 0, "ttbr address size fault" }, + { do_bad, SIGBUS, 0, "level 1 address size fault" }, + { do_bad, SIGBUS, 0, "level 2 address size fault" }, +@@ -560,19 +572,13 @@ static const struct fault_info { + { do_bad, SIGBUS, 0, "unknown 63" }, + }; + +-static const char *fault_name(unsigned int esr) +-{ +- const struct fault_info *inf = fault_info + (esr & 63); +- return inf->name; +-} +- + /* + * Dispatch a data abort to the relevant handler. + */ + asmlinkage void __exception do_mem_abort(unsigned long addr, unsigned int esr, + struct pt_regs *regs) + { +- const struct fault_info *inf = fault_info + (esr & 63); ++ const struct fault_info *inf = esr_to_fault_info(esr); + struct siginfo info; + + if (!inf->fn(addr, esr, regs)) +-- +2.12.0 + diff --git a/queue/ath9k-fix-NULL-pointer-dereference.patch b/queue/ath9k-fix-NULL-pointer-dereference.patch new file mode 100644 index 0000000..c5b04c2 --- /dev/null +++ b/queue/ath9k-fix-NULL-pointer-dereference.patch @@ -0,0 +1,78 @@ +From 40bea976c72b9ee60f8d097852deb53ccbeaffbe Mon Sep 17 00:00:00 2001 +From: Miaoqing Pan <miaoqing@codeaurora.org> +Date: Wed, 16 Nov 2016 17:23:08 +0800 +Subject: [PATCH] ath9k: fix NULL pointer dereference + +commit 40bea976c72b9ee60f8d097852deb53ccbeaffbe upstream. + +relay_open() may return NULL, check the return value to avoid the crash. + +BUG: unable to handle kernel NULL pointer dereference at 0000000000000040 +IP: [<ffffffffa01a95c5>] ath_cmn_process_fft+0xd5/0x700 [ath9k_common] +PGD 41cf28067 PUD 41be92067 PMD 0 +Oops: 0000 [#1] SMP +CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.8.6+ #35 +Hardware name: Hewlett-Packard h8-1080t/2A86, BIOS 6.15 07/04/2011 +task: ffffffff81e0c4c0 task.stack: ffffffff81e00000 +RIP: 0010:[<ffffffffa01a95c5>] [<ffffffffa01a95c5>] ath_cmn_process_fft+0xd5/0x700 [ath9k_common] +RSP: 0018:ffff88041f203ca0 EFLAGS: 00010293 +RAX: 0000000000000000 RBX: 000000000000059f RCX: 0000000000000000 +RDX: 0000000000000000 RSI: 0000000000000040 RDI: ffffffff81f0ca98 +RBP: ffff88041f203dc8 R08: ffffffffffffffff R09: 00000000000000ff +R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000 +R13: ffffffff81f0ca98 R14: 0000000000000000 R15: 0000000000000000 +FS: 0000000000000000(0000) GS:ffff88041f200000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 0000000000000040 CR3: 000000041b6ec000 CR4: 00000000000006f0 +Stack: +0000000000000363 00000000000003f3 00000000000003f3 00000000000001f9 +000000000000049a 0000000001252c04 ffff88041f203e44 ffff880417b4bfd0 +0000000000000008 ffff88041785b9c0 0000000000000002 ffff88041613dc60 + +Call Trace: +<IRQ> +[<ffffffffa01b6441>] ath9k_tasklet+0x1b1/0x220 [ath9k] +[<ffffffff8105d8dd>] tasklet_action+0x4d/0xf0 +[<ffffffff8105dde2>] __do_softirq+0x92/0x2a0 + +Reported-by: Devin Tuchsen <devin.tuchsen@gmail.com> +Tested-by: Devin Tuchsen <devin.tuchsen@gmail.com> +Signed-off-by: Miaoqing Pan <miaoqing@codeaurora.org> +Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com> + +diff --git a/drivers/net/wireless/ath/ath9k/common-spectral.c b/drivers/net/wireless/ath/ath9k/common-spectral.c +index e2512d5bc0e1..eedf86b67cf5 100644 +--- a/drivers/net/wireless/ath/ath9k/common-spectral.c ++++ b/drivers/net/wireless/ath/ath9k/common-spectral.c +@@ -528,6 +528,9 @@ int ath_cmn_process_fft(struct ath_spec_scan_priv *spec_priv, struct ieee80211_h + if (!(radar_info->pulse_bw_info & SPECTRAL_SCAN_BITMASK)) + return 0; + ++ if (!spec_priv->rfs_chan_spec_scan) ++ return 1; ++ + /* Output buffers are full, no need to process anything + * since there is no space to put the result anyway + */ +@@ -1072,7 +1075,7 @@ static struct rchan_callbacks rfs_spec_scan_cb = { + + void ath9k_cmn_spectral_deinit_debug(struct ath_spec_scan_priv *spec_priv) + { +- if (IS_ENABLED(CONFIG_ATH9K_DEBUGFS)) { ++ if (IS_ENABLED(CONFIG_ATH9K_DEBUGFS) && spec_priv->rfs_chan_spec_scan) { + relay_close(spec_priv->rfs_chan_spec_scan); + spec_priv->rfs_chan_spec_scan = NULL; + } +@@ -1086,6 +1089,9 @@ void ath9k_cmn_spectral_init_debug(struct ath_spec_scan_priv *spec_priv, + debugfs_phy, + 1024, 256, &rfs_spec_scan_cb, + NULL); ++ if (!spec_priv->rfs_chan_spec_scan) ++ return; ++ + debugfs_create_file("spectral_scan_ctl", + S_IRUSR | S_IWUSR, + debugfs_phy, spec_priv, +-- +2.12.0 + diff --git a/queue/blk-mq-Avoid-memory-reclaim-when-remapping-queues.patch b/queue/blk-mq-Avoid-memory-reclaim-when-remapping-queues.patch new file mode 100644 index 0000000..cd8c8b5 --- /dev/null +++ b/queue/blk-mq-Avoid-memory-reclaim-when-remapping-queues.patch @@ -0,0 +1,106 @@ +From 36e1f3d107867b25c616c2fd294f5a1c9d4e5d09 Mon Sep 17 00:00:00 2001 +From: Gabriel Krisman Bertazi <krisman@linux.vnet.ibm.com> +Date: Tue, 6 Dec 2016 13:31:44 -0200 +Subject: [PATCH] blk-mq: Avoid memory reclaim when remapping queues + +commit 36e1f3d107867b25c616c2fd294f5a1c9d4e5d09 upstream. + +While stressing memory and IO at the same time we changed SMT settings, +we were able to consistently trigger deadlocks in the mm system, which +froze the entire machine. + +I think that under memory stress conditions, the large allocations +performed by blk_mq_init_rq_map may trigger a reclaim, which stalls +waiting on the block layer remmaping completion, thus deadlocking the +system. The trace below was collected after the machine stalled, +waiting for the hotplug event completion. + +The simplest fix for this is to make allocations in this path +non-reclaimable, with GFP_NOIO. With this patch, We couldn't hit the +issue anymore. + +This should apply on top of Jens's for-next branch cleanly. + +Changes since v1: + - Use GFP_NOIO instead of GFP_NOWAIT. + + Call Trace: +[c000000f0160aaf0] [c000000f0160ab50] 0xc000000f0160ab50 (unreliable) +[c000000f0160acc0] [c000000000016624] __switch_to+0x2e4/0x430 +[c000000f0160ad20] [c000000000b1a880] __schedule+0x310/0x9b0 +[c000000f0160ae00] [c000000000b1af68] schedule+0x48/0xc0 +[c000000f0160ae30] [c000000000b1b4b0] schedule_preempt_disabled+0x20/0x30 +[c000000f0160ae50] [c000000000b1d4fc] __mutex_lock_slowpath+0xec/0x1f0 +[c000000f0160aed0] [c000000000b1d678] mutex_lock+0x78/0xa0 +[c000000f0160af00] [d000000019413cac] xfs_reclaim_inodes_ag+0x33c/0x380 [xfs] +[c000000f0160b0b0] [d000000019415164] xfs_reclaim_inodes_nr+0x54/0x70 [xfs] +[c000000f0160b0f0] [d0000000194297f8] xfs_fs_free_cached_objects+0x38/0x60 [xfs] +[c000000f0160b120] [c0000000003172c8] super_cache_scan+0x1f8/0x210 +[c000000f0160b190] [c00000000026301c] shrink_slab.part.13+0x21c/0x4c0 +[c000000f0160b2d0] [c000000000268088] shrink_zone+0x2d8/0x3c0 +[c000000f0160b380] [c00000000026834c] do_try_to_free_pages+0x1dc/0x520 +[c000000f0160b450] [c00000000026876c] try_to_free_pages+0xdc/0x250 +[c000000f0160b4e0] [c000000000251978] __alloc_pages_nodemask+0x868/0x10d0 +[c000000f0160b6f0] [c000000000567030] blk_mq_init_rq_map+0x160/0x380 +[c000000f0160b7a0] [c00000000056758c] blk_mq_map_swqueue+0x33c/0x360 +[c000000f0160b820] [c000000000567904] blk_mq_queue_reinit+0x64/0xb0 +[c000000f0160b850] [c00000000056a16c] blk_mq_queue_reinit_notify+0x19c/0x250 +[c000000f0160b8a0] [c0000000000f5d38] notifier_call_chain+0x98/0x100 +[c000000f0160b8f0] [c0000000000c5fb0] __cpu_notify+0x70/0xe0 +[c000000f0160b930] [c0000000000c63c4] notify_prepare+0x44/0xb0 +[c000000f0160b9b0] [c0000000000c52f4] cpuhp_invoke_callback+0x84/0x250 +[c000000f0160ba10] [c0000000000c570c] cpuhp_up_callbacks+0x5c/0x120 +[c000000f0160ba60] [c0000000000c7cb8] _cpu_up+0xf8/0x1d0 +[c000000f0160bac0] [c0000000000c7eb0] do_cpu_up+0x120/0x150 +[c000000f0160bb40] [c0000000006fe024] cpu_subsys_online+0x64/0xe0 +[c000000f0160bb90] [c0000000006f5124] device_online+0xb4/0x120 +[c000000f0160bbd0] [c0000000006f5244] online_store+0xb4/0xc0 +[c000000f0160bc20] [c0000000006f0a68] dev_attr_store+0x68/0xa0 +[c000000f0160bc60] [c0000000003ccc30] sysfs_kf_write+0x80/0xb0 +[c000000f0160bca0] [c0000000003cbabc] kernfs_fop_write+0x17c/0x250 +[c000000f0160bcf0] [c00000000030fe6c] __vfs_write+0x6c/0x1e0 +[c000000f0160bd90] [c000000000311490] vfs_write+0xd0/0x270 +[c000000f0160bde0] [c0000000003131fc] SyS_write+0x6c/0x110 +[c000000f0160be30] [c000000000009204] system_call+0x38/0xec + +Signed-off-by: Gabriel Krisman Bertazi <krisman@linux.vnet.ibm.com> +Cc: Brian King <brking@linux.vnet.ibm.com> +Cc: Douglas Miller <dougmill@linux.vnet.ibm.com> +Cc: linux-block@vger.kernel.org +Cc: linux-scsi@vger.kernel.org +Signed-off-by: Jens Axboe <axboe@fb.com> + +diff --git a/block/blk-mq.c b/block/blk-mq.c +index d79fdc11b1ee..7ad7c11fe01d 100644 +--- a/block/blk-mq.c ++++ b/block/blk-mq.c +@@ -1605,7 +1605,7 @@ static struct blk_mq_tags *blk_mq_init_rq_map(struct blk_mq_tag_set *set, + INIT_LIST_HEAD(&tags->page_list); + + tags->rqs = kzalloc_node(set->queue_depth * sizeof(struct request *), +- GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY, ++ GFP_NOIO | __GFP_NOWARN | __GFP_NORETRY, + set->numa_node); + if (!tags->rqs) { + blk_mq_free_tags(tags); +@@ -1631,7 +1631,7 @@ static struct blk_mq_tags *blk_mq_init_rq_map(struct blk_mq_tag_set *set, + + do { + page = alloc_pages_node(set->numa_node, +- GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY | __GFP_ZERO, ++ GFP_NOIO | __GFP_NOWARN | __GFP_NORETRY | __GFP_ZERO, + this_order); + if (page) + break; +@@ -1652,7 +1652,7 @@ static struct blk_mq_tags *blk_mq_init_rq_map(struct blk_mq_tag_set *set, + * Allow kmemleak to scan these pages as they contain pointers + * to additional allocations like via ops->init_request(). + */ +- kmemleak_alloc(p, order_to_size(this_order), 1, GFP_KERNEL); ++ kmemleak_alloc(p, order_to_size(this_order), 1, GFP_NOIO); + entries_per_page = order_to_size(this_order) / rq_size; + to_do = min(entries_per_page, set->queue_depth - i); + left -= to_do * rq_size; +-- +2.12.0 + diff --git a/queue/brcmfmac-use-local-iftype-avoiding-use-after-free-of.patch b/queue/brcmfmac-use-local-iftype-avoiding-use-after-free-of.patch new file mode 100644 index 0000000..7096cac --- /dev/null +++ b/queue/brcmfmac-use-local-iftype-avoiding-use-after-free-of.patch @@ -0,0 +1,65 @@ +From d77facb88448cdeaaa3adba5b9704a48ac2ac8d6 Mon Sep 17 00:00:00 2001 +From: Arend Van Spriel <arend.vanspriel@broadcom.com> +Date: Tue, 28 Mar 2017 09:11:30 +0100 +Subject: [PATCH] brcmfmac: use local iftype avoiding use-after-free of virtual + interface + +commit d77facb88448cdeaaa3adba5b9704a48ac2ac8d6 upstream. + +A use-after-free was found using KASAN. In brcmf_p2p_del_if() the virtual +interface is removed using call to brcmf_remove_interface(). After that +the virtual interface instance has been freed and should not be referenced. +Solve this by storing the nl80211 iftype in local variable, which is used +in a couple of places anyway. + +Cc: stable@vger.kernel.org # 4.10.x, 4.9.x +Reported-by: Daniel J Blueman <daniel@quora.org> +Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com> +Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com> +Reviewed-by: Franky Lin <franky.lin@broadcom.com> +Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> +Signed-off-by: Kalle Valo <kvalo@codeaurora.org> + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c +index de19c7c92bc6..85d949e03f79 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c +@@ -2238,14 +2238,16 @@ int brcmf_p2p_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev) + struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy); + struct brcmf_p2p_info *p2p = &cfg->p2p; + struct brcmf_cfg80211_vif *vif; ++ enum nl80211_iftype iftype; + bool wait_for_disable = false; + int err; + + brcmf_dbg(TRACE, "delete P2P vif\n"); + vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev); + ++ iftype = vif->wdev.iftype; + brcmf_cfg80211_arm_vif_event(cfg, vif); +- switch (vif->wdev.iftype) { ++ switch (iftype) { + case NL80211_IFTYPE_P2P_CLIENT: + if (test_bit(BRCMF_VIF_STATUS_DISCONNECTING, &vif->sme_state)) + wait_for_disable = true; +@@ -2275,7 +2277,7 @@ int brcmf_p2p_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev) + BRCMF_P2P_DISABLE_TIMEOUT); + + err = 0; +- if (vif->wdev.iftype != NL80211_IFTYPE_P2P_DEVICE) { ++ if (iftype != NL80211_IFTYPE_P2P_DEVICE) { + brcmf_vif_clear_mgmt_ies(vif); + err = brcmf_p2p_release_p2p_if(vif); + } +@@ -2291,7 +2293,7 @@ int brcmf_p2p_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev) + brcmf_remove_interface(vif->ifp, true); + + brcmf_cfg80211_arm_vif_event(cfg, NULL); +- if (vif->wdev.iftype != NL80211_IFTYPE_P2P_DEVICE) ++ if (iftype != NL80211_IFTYPE_P2P_DEVICE) + p2p->bss_idx[P2PAPI_BSSCFG_CONNECTION].vif = NULL; + + return err; +-- +2.12.0 + diff --git a/queue/can-ifi-use-correct-register-to-read-rx-status.patch b/queue/can-ifi-use-correct-register-to-read-rx-status.patch new file mode 100644 index 0000000..eb1e882 --- /dev/null +++ b/queue/can-ifi-use-correct-register-to-read-rx-status.patch @@ -0,0 +1,29 @@ +From 57c1d4c33e8f7ec90976d79127059c1919cc0651 Mon Sep 17 00:00:00 2001 +From: Markus Marb <markus@marb.org> +Date: Fri, 17 Mar 2017 23:14:47 +0100 +Subject: [PATCH] can: ifi: use correct register to read rx status + +commit 57c1d4c33e8f7ec90976d79127059c1919cc0651 upstream. + +The incorrect offset was used when trying to read the RXSTCMD register. + +Signed-off-by: Markus Marb <markus@marb.org> +Cc: linux-stable <stable@vger.kernel.org> +Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de> + +diff --git a/drivers/net/can/ifi_canfd/ifi_canfd.c b/drivers/net/can/ifi_canfd/ifi_canfd.c +index 138f5ae75c0b..4d1fe8d95042 100644 +--- a/drivers/net/can/ifi_canfd/ifi_canfd.c ++++ b/drivers/net/can/ifi_canfd/ifi_canfd.c +@@ -557,7 +557,7 @@ static int ifi_canfd_poll(struct napi_struct *napi, int quota) + int work_done = 0; + + u32 stcmd = readl(priv->base + IFI_CANFD_STCMD); +- u32 rxstcmd = readl(priv->base + IFI_CANFD_STCMD); ++ u32 rxstcmd = readl(priv->base + IFI_CANFD_RXSTCMD); + u32 errctr = readl(priv->base + IFI_CANFD_ERROR_CTR); + + /* Handle bus state changes */ +-- +2.12.0 + diff --git a/queue/cfg80211-check-rdev-resume-callback-only-for-registe.patch b/queue/cfg80211-check-rdev-resume-callback-only-for-registe.patch new file mode 100644 index 0000000..30c1d1b --- /dev/null +++ b/queue/cfg80211-check-rdev-resume-callback-only-for-registe.patch @@ -0,0 +1,133 @@ +From b3ef5520c1eabb56064474043c7c55a1a65b8708 Mon Sep 17 00:00:00 2001 +From: Arend Van Spriel <arend.vanspriel@broadcom.com> +Date: Tue, 28 Mar 2017 09:11:31 +0100 +Subject: [PATCH] cfg80211: check rdev resume callback only for registered + wiphy + +commit b3ef5520c1eabb56064474043c7c55a1a65b8708 upstream. + +We got the following use-after-free KASAN report: + + BUG: KASAN: use-after-free in wiphy_resume+0x591/0x5a0 [cfg80211] + at addr ffff8803fc244090 + Read of size 8 by task kworker/u16:24/2587 + CPU: 6 PID: 2587 Comm: kworker/u16:24 Tainted: G B 4.9.13-debug+ + Hardware name: Dell Inc. XPS 15 9550/0N7TVV, BIOS 1.2.19 12/22/2016 + Workqueue: events_unbound async_run_entry_fn + ffff880425d4f9d8 ffffffffaeedb541 ffff88042b80ef00 ffff8803fc244088 + ffff880425d4fa00 ffffffffae84d7a1 ffff880425d4fa98 ffff8803fc244080 + ffff88042b80ef00 ffff880425d4fa88 ffffffffae84da3a ffffffffc141f7d9 + Call Trace: + [<ffffffffaeedb541>] dump_stack+0x85/0xc4 + [<ffffffffae84d7a1>] kasan_object_err+0x21/0x70 + [<ffffffffae84da3a>] kasan_report_error+0x1fa/0x500 + [<ffffffffc141f7d9>] ? cfg80211_bss_age+0x39/0xc0 [cfg80211] + [<ffffffffc141f83a>] ? cfg80211_bss_age+0x9a/0xc0 [cfg80211] + [<ffffffffae48d46d>] ? trace_hardirqs_on+0xd/0x10 + [<ffffffffc13fb1c0>] ? wiphy_suspend+0xc70/0xc70 [cfg80211] + [<ffffffffae84def1>] __asan_report_load8_noabort+0x61/0x70 + [<ffffffffc13fb100>] ? wiphy_suspend+0xbb0/0xc70 [cfg80211] + [<ffffffffc13fb751>] ? wiphy_resume+0x591/0x5a0 [cfg80211] + [<ffffffffc13fb751>] wiphy_resume+0x591/0x5a0 [cfg80211] + [<ffffffffc13fb1c0>] ? wiphy_suspend+0xc70/0xc70 [cfg80211] + [<ffffffffaf3b206e>] dpm_run_callback+0x6e/0x4f0 + [<ffffffffaf3b31b2>] device_resume+0x1c2/0x670 + [<ffffffffaf3b367d>] async_resume+0x1d/0x50 + [<ffffffffae3ee84e>] async_run_entry_fn+0xfe/0x610 + [<ffffffffae3d0666>] process_one_work+0x716/0x1a50 + [<ffffffffae3d05c9>] ? process_one_work+0x679/0x1a50 + [<ffffffffafdd7b6d>] ? _raw_spin_unlock_irq+0x3d/0x60 + [<ffffffffae3cff50>] ? pwq_dec_nr_in_flight+0x2b0/0x2b0 + [<ffffffffae3d1a80>] worker_thread+0xe0/0x1460 + [<ffffffffae3d19a0>] ? process_one_work+0x1a50/0x1a50 + [<ffffffffae3e54c2>] kthread+0x222/0x2e0 + [<ffffffffae3e52a0>] ? kthread_park+0x80/0x80 + [<ffffffffae3e52a0>] ? kthread_park+0x80/0x80 + [<ffffffffae3e52a0>] ? kthread_park+0x80/0x80 + [<ffffffffafdd86aa>] ret_from_fork+0x2a/0x40 + Object at ffff8803fc244088, in cache kmalloc-1024 size: 1024 + Allocated: + PID = 71 + save_stack_trace+0x1b/0x20 + save_stack+0x46/0xd0 + kasan_kmalloc+0xad/0xe0 + kasan_slab_alloc+0x12/0x20 + __kmalloc_track_caller+0x134/0x360 + kmemdup+0x20/0x50 + brcmf_cfg80211_attach+0x10b/0x3a90 [brcmfmac] + brcmf_bus_start+0x19a/0x9a0 [brcmfmac] + brcmf_pcie_setup+0x1f1a/0x3680 [brcmfmac] + brcmf_fw_request_nvram_done+0x44c/0x11b0 [brcmfmac] + request_firmware_work_func+0x135/0x280 + process_one_work+0x716/0x1a50 + worker_thread+0xe0/0x1460 + kthread+0x222/0x2e0 + ret_from_fork+0x2a/0x40 + Freed: + PID = 2568 + save_stack_trace+0x1b/0x20 + save_stack+0x46/0xd0 + kasan_slab_free+0x71/0xb0 + kfree+0xe8/0x2e0 + brcmf_cfg80211_detach+0x62/0xf0 [brcmfmac] + brcmf_detach+0x14a/0x2b0 [brcmfmac] + brcmf_pcie_remove+0x140/0x5d0 [brcmfmac] + brcmf_pcie_pm_leave_D3+0x198/0x2e0 [brcmfmac] + pci_pm_resume+0x186/0x220 + dpm_run_callback+0x6e/0x4f0 + device_resume+0x1c2/0x670 + async_resume+0x1d/0x50 + async_run_entry_fn+0xfe/0x610 + process_one_work+0x716/0x1a50 + worker_thread+0xe0/0x1460 + kthread+0x222/0x2e0 + ret_from_fork+0x2a/0x40 + Memory state around the buggy address: + ffff8803fc243f80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc + ffff8803fc244000: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc + >ffff8803fc244080: fc fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb + ^ + ffff8803fc244100: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb + ffff8803fc244180: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb + +What is happening is that brcmf_pcie_resume() detects a device that +is no longer responsive and it decides to unbind resulting in a +wiphy_unregister() and wiphy_free() call. Now the wiphy instance +remains allocated, because PM needs to call wiphy_resume() for it. +However, brcmfmac already does a kfree() for the struct +cfg80211_registered_device::ops field. Change the checks in +wiphy_resume() to only access the struct cfg80211_registered_device::ops +if the wiphy instance is still registered at this time. + +Cc: stable@vger.kernel.org # 4.10.x, 4.9.x +Reported-by: Daniel J Blueman <daniel@quora.org> +Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com> +Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com> +Reviewed-by: Franky Lin <franky.lin@broadcom.com> +Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> +Signed-off-by: Johannes Berg <johannes.berg@intel.com> + +diff --git a/net/wireless/sysfs.c b/net/wireless/sysfs.c +index 16b6b5988be9..570a2b67ca10 100644 +--- a/net/wireless/sysfs.c ++++ b/net/wireless/sysfs.c +@@ -132,12 +132,10 @@ static int wiphy_resume(struct device *dev) + /* Age scan results with time spent in suspend */ + cfg80211_bss_age(rdev, get_seconds() - rdev->suspend_at); + +- if (rdev->ops->resume) { +- rtnl_lock(); +- if (rdev->wiphy.registered) +- ret = rdev_resume(rdev); +- rtnl_unlock(); +- } ++ rtnl_lock(); ++ if (rdev->wiphy.registered && rdev->ops->resume) ++ ret = rdev_resume(rdev); ++ rtnl_unlock(); + + return ret; + } +-- +2.12.0 + diff --git a/queue/cgroup-kthread-close-race-window-where-new-kthreads-.patch b/queue/cgroup-kthread-close-race-window-where-new-kthreads-.patch new file mode 100644 index 0000000..728da2e --- /dev/null +++ b/queue/cgroup-kthread-close-race-window-where-new-kthreads-.patch @@ -0,0 +1,168 @@ +From 77f88796cee819b9c4562b0b6b44691b3b7755b1 Mon Sep 17 00:00:00 2001 +From: Tejun Heo <tj@kernel.org> +Date: Thu, 16 Mar 2017 16:54:24 -0400 +Subject: [PATCH] cgroup, kthread: close race window where new kthreads can be + migrated to non-root cgroups + +commit 77f88796cee819b9c4562b0b6b44691b3b7755b1 upstream. + +Creation of a kthread goes through a couple interlocked stages between +the kthread itself and its creator. Once the new kthread starts +running, it initializes itself and wakes up the creator. The creator +then can further configure the kthread and then let it start doing its +job by waking it up. + +In this configuration-by-creator stage, the creator is the only one +that can wake it up but the kthread is visible to userland. When +altering the kthread's attributes from userland is allowed, this is +fine; however, for cases where CPU affinity is critical, +kthread_bind() is used to first disable affinity changes from userland +and then set the affinity. This also prevents the kthread from being +migrated into non-root cgroups as that can affect the CPU affinity and +many other things. + +Unfortunately, the cgroup side of protection is racy. While the +PF_NO_SETAFFINITY flag prevents further migrations, userland can win +the race before the creator sets the flag with kthread_bind() and put +the kthread in a non-root cgroup, which can lead to all sorts of +problems including incorrect CPU affinity and starvation. + +This bug got triggered by userland which periodically tries to migrate +all processes in the root cpuset cgroup to a non-root one. Per-cpu +workqueue workers got caught while being created and ended up with +incorrected CPU affinity breaking concurrency management and sometimes +stalling workqueue execution. + +This patch adds task->no_cgroup_migration which disallows the task to +be migrated by userland. kthreadd starts with the flag set making +every child kthread start in the root cgroup with migration +disallowed. The flag is cleared after the kthread finishes +initialization by which time PF_NO_SETAFFINITY is set if the kthread +should stay in the root cgroup. + +It'd be better to wait for the initialization instead of failing but I +couldn't think of a way of implementing that without adding either a +new PF flag, or sleeping and retrying from waiting side. Even if +userland depends on changing cgroup membership of a kthread, it either +has to be synchronized with kthread_create() or periodically repeat, +so it's unlikely that this would break anything. + +v2: Switch to a simpler implementation using a new task_struct bit + field suggested by Oleg. + +Signed-off-by: Tejun Heo <tj@kernel.org> +Suggested-by: Oleg Nesterov <oleg@redhat.com> +Cc: Linus Torvalds <torvalds@linux-foundation.org> +Cc: Andrew Morton <akpm@linux-foundation.org> +Cc: Peter Zijlstra (Intel) <peterz@infradead.org> +Cc: Thomas Gleixner <tglx@linutronix.de> +Reported-and-debugged-by: Chris Mason <clm@fb.com> +Cc: stable@vger.kernel.org # v4.3+ (we can't close the race on < v4.3) +Signed-off-by: Tejun Heo <tj@kernel.org> + +diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h +index f6b43fbb141c..af9c86e958bd 100644 +--- a/include/linux/cgroup.h ++++ b/include/linux/cgroup.h +@@ -570,6 +570,25 @@ static inline void pr_cont_cgroup_path(struct cgroup *cgrp) + pr_cont_kernfs_path(cgrp->kn); + } + ++static inline void cgroup_init_kthreadd(void) ++{ ++ /* ++ * kthreadd is inherited by all kthreads, keep it in the root so ++ * that the new kthreads are guaranteed to stay in the root until ++ * initialization is finished. ++ */ ++ current->no_cgroup_migration = 1; ++} ++ ++static inline void cgroup_kthread_ready(void) ++{ ++ /* ++ * This kthread finished initialization. The creator should have ++ * set PF_NO_SETAFFINITY if this kthread should stay in the root. ++ */ ++ current->no_cgroup_migration = 0; ++} ++ + #else /* !CONFIG_CGROUPS */ + + struct cgroup_subsys_state; +@@ -590,6 +609,8 @@ static inline void cgroup_free(struct task_struct *p) {} + + static inline int cgroup_init_early(void) { return 0; } + static inline int cgroup_init(void) { return 0; } ++static inline void cgroup_init_kthreadd(void) {} ++static inline void cgroup_kthread_ready(void) {} + + static inline bool task_under_cgroup_hierarchy(struct task_struct *task, + struct cgroup *ancestor) +diff --git a/include/linux/sched.h b/include/linux/sched.h +index d67eee84fd43..4cf9a59a4d08 100644 +--- a/include/linux/sched.h ++++ b/include/linux/sched.h +@@ -604,6 +604,10 @@ struct task_struct { + #ifdef CONFIG_COMPAT_BRK + unsigned brk_randomized:1; + #endif ++#ifdef CONFIG_CGROUPS ++ /* disallow userland-initiated cgroup migration */ ++ unsigned no_cgroup_migration:1; ++#endif + + unsigned long atomic_flags; /* Flags requiring atomic access. */ + +diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c +index 0125589c7428..638ef7568495 100644 +--- a/kernel/cgroup/cgroup.c ++++ b/kernel/cgroup/cgroup.c +@@ -2425,11 +2425,12 @@ ssize_t __cgroup_procs_write(struct kernfs_open_file *of, char *buf, + tsk = tsk->group_leader; + + /* +- * Workqueue threads may acquire PF_NO_SETAFFINITY and become +- * trapped in a cpuset, or RT worker may be born in a cgroup +- * with no rt_runtime allocated. Just say no. ++ * kthreads may acquire PF_NO_SETAFFINITY during initialization. ++ * If userland migrates such a kthread to a non-root cgroup, it can ++ * become trapped in a cpuset, or RT kthread may be born in a ++ * cgroup with no rt_runtime allocated. Just say no. + */ +- if (tsk == kthreadd_task || (tsk->flags & PF_NO_SETAFFINITY)) { ++ if (tsk->no_cgroup_migration || (tsk->flags & PF_NO_SETAFFINITY)) { + ret = -EINVAL; + goto out_unlock_rcu; + } +diff --git a/kernel/kthread.c b/kernel/kthread.c +index 2f26adea0f84..26db528c1d88 100644 +--- a/kernel/kthread.c ++++ b/kernel/kthread.c +@@ -20,6 +20,7 @@ + #include <linux/freezer.h> + #include <linux/ptrace.h> + #include <linux/uaccess.h> ++#include <linux/cgroup.h> + #include <trace/events/sched.h> + + static DEFINE_SPINLOCK(kthread_create_lock); +@@ -225,6 +226,7 @@ static int kthread(void *_create) + + ret = -EINTR; + if (!test_bit(KTHREAD_SHOULD_STOP, &self->flags)) { ++ cgroup_kthread_ready(); + __kthread_parkme(self); + ret = threadfn(data); + } +@@ -538,6 +540,7 @@ int kthreadd(void *unused) + set_mems_allowed(node_states[N_MEMORY]); + + current->flags |= PF_NOFREEZE; ++ cgroup_init_kthreadd(); + + for (;;) { + set_current_state(TASK_INTERRUPTIBLE); +-- +2.12.0 + diff --git a/queue/char-lack-of-bool-string-made-CONFIG_DEVPORT-always-.patch b/queue/char-lack-of-bool-string-made-CONFIG_DEVPORT-always-.patch new file mode 100644 index 0000000..89b48fd --- /dev/null +++ b/queue/char-lack-of-bool-string-made-CONFIG_DEVPORT-always-.patch @@ -0,0 +1,38 @@ +From f2cfa58b136e4b06a9b9db7af5ef62fbb5992f62 Mon Sep 17 00:00:00 2001 +From: Max Bires <jbires@google.com> +Date: Tue, 3 Jan 2017 08:18:07 -0800 +Subject: [PATCH] char: lack of bool string made CONFIG_DEVPORT always on + +commit f2cfa58b136e4b06a9b9db7af5ef62fbb5992f62 upstream. + +Without a bool string present, using "# CONFIG_DEVPORT is not set" in +defconfig files would not actually unset devport. This esnured that +/dev/port was always on, but there are reasons a user may wish to +disable it (smaller kernel, attack surface reduction) if it's not being +used. Adding a message here in order to make this user visible. + +Signed-off-by: Max Bires <jbires@google.com> +Acked-by: Arnd Bergmann <arnd@arndb.de> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> + +diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig +index fde005ef9d36..4ee2a10207d0 100644 +--- a/drivers/char/Kconfig ++++ b/drivers/char/Kconfig +@@ -571,9 +571,12 @@ config TELCLOCK + controlling the behavior of this hardware. + + config DEVPORT +- bool ++ bool "/dev/port character device" + depends on ISA || PCI + default y ++ help ++ Say Y here if you want to support the /dev/port device. The /dev/port ++ device is similar to /dev/mem, but for I/O ports. + + source "drivers/s390/char/Kconfig" + +-- +2.12.0 + diff --git a/queue/clk-lpc32xx-add-a-quirk-for-PWM-and-MS-clock-divider.patch b/queue/clk-lpc32xx-add-a-quirk-for-PWM-and-MS-clock-divider.patch new file mode 100644 index 0000000..2a38a78 --- /dev/null +++ b/queue/clk-lpc32xx-add-a-quirk-for-PWM-and-MS-clock-divider.patch @@ -0,0 +1,97 @@ +From f84d42a9cffc4ecd96f1ce3a038f841782142eb2 Mon Sep 17 00:00:00 2001 +From: Vladimir Zapolskiy <vz@mleia.com> +Date: Fri, 7 Oct 2016 04:16:55 +0300 +Subject: [PATCH] clk: lpc32xx: add a quirk for PWM and MS clock dividers + +commit f84d42a9cffc4ecd96f1ce3a038f841782142eb2 upstream. + +In common clock framework CLK_DIVIDER_ONE_BASED or'ed with +CLK_DIVIDER_ALLOW_ZERO flags indicates that +1) a divider clock may be set to zero value, +2) divider's zero value is interpreted as a non-divided clock. + +On the LPC32xx platform clock dividers of PWM and memory card clocks +comply with the first condition, but zero value means a gated clock, +thus it may happen that the divider value is not updated when +the clock is enabled and the clock remains gated. + +The change adds one-shot quirks, which check for zero value of divider +on initialization and set it to a non-zero value, therefore in runtime +a gate clock will work as expected. + +Signed-off-by: Vladimir Zapolskiy <vz@mleia.com> +Reviewed-by: Sylvain Lemieux <slemieux.tyco@gmail.com> +Signed-off-by: Stephen Boyd <sboyd@codeaurora.org> + +diff --git a/drivers/clk/nxp/clk-lpc32xx.c b/drivers/clk/nxp/clk-lpc32xx.c +index 34c97353cdeb..5b98ff9076f3 100644 +--- a/drivers/clk/nxp/clk-lpc32xx.c ++++ b/drivers/clk/nxp/clk-lpc32xx.c +@@ -1282,13 +1282,13 @@ static struct clk_hw_proto clk_hw_proto[LPC32XX_CLK_HW_MAX] = { + + LPC32XX_DEFINE_MUX(PWM1_MUX, PWMCLK_CTRL, 1, 0x1, NULL, 0), + LPC32XX_DEFINE_DIV(PWM1_DIV, PWMCLK_CTRL, 4, 4, NULL, +- CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO), ++ CLK_DIVIDER_ONE_BASED), + LPC32XX_DEFINE_GATE(PWM1_GATE, PWMCLK_CTRL, 0, 0), + LPC32XX_DEFINE_COMPOSITE(PWM1, PWM1_MUX, PWM1_DIV, PWM1_GATE), + + LPC32XX_DEFINE_MUX(PWM2_MUX, PWMCLK_CTRL, 3, 0x1, NULL, 0), + LPC32XX_DEFINE_DIV(PWM2_DIV, PWMCLK_CTRL, 8, 4, NULL, +- CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO), ++ CLK_DIVIDER_ONE_BASED), + LPC32XX_DEFINE_GATE(PWM2_GATE, PWMCLK_CTRL, 2, 0), + LPC32XX_DEFINE_COMPOSITE(PWM2, PWM2_MUX, PWM2_DIV, PWM2_GATE), + +@@ -1335,8 +1335,7 @@ static struct clk_hw_proto clk_hw_proto[LPC32XX_CLK_HW_MAX] = { + LPC32XX_DEFINE_GATE(USB_DIV_GATE, USB_CTRL, 17, 0), + LPC32XX_DEFINE_COMPOSITE(USB_DIV, _NULL, USB_DIV_DIV, USB_DIV_GATE), + +- LPC32XX_DEFINE_DIV(SD_DIV, MS_CTRL, 0, 4, NULL, +- CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO), ++ LPC32XX_DEFINE_DIV(SD_DIV, MS_CTRL, 0, 4, NULL, CLK_DIVIDER_ONE_BASED), + LPC32XX_DEFINE_CLK(SD_GATE, MS_CTRL, BIT(5) | BIT(9), BIT(5) | BIT(9), + 0x0, BIT(5) | BIT(9), 0x0, 0x0, clk_mask_ops), + LPC32XX_DEFINE_COMPOSITE(SD, _NULL, SD_DIV, SD_GATE), +@@ -1478,6 +1477,20 @@ static struct clk * __init lpc32xx_clk_register(u32 id) + return clk; + } + ++static void __init lpc32xx_clk_div_quirk(u32 reg, u32 div_mask, u32 gate) ++{ ++ u32 val; ++ ++ regmap_read(clk_regmap, reg, &val); ++ ++ if (!(val & div_mask)) { ++ val &= ~gate; ++ val |= BIT(__ffs(div_mask)); ++ } ++ ++ regmap_update_bits(clk_regmap, reg, gate | div_mask, val); ++} ++ + static void __init lpc32xx_clk_init(struct device_node *np) + { + unsigned int i; +@@ -1517,6 +1530,17 @@ static void __init lpc32xx_clk_init(struct device_node *np) + return; + } + ++ /* ++ * Divider part of PWM and MS clocks requires a quirk to avoid ++ * a misinterpretation of formally valid zero value in register ++ * bitfield, which indicates another clock gate. Instead of ++ * adding complexity to a gate clock ensure that zero value in ++ * divider clock is never met in runtime. ++ */ ++ lpc32xx_clk_div_quirk(LPC32XX_CLKPWR_PWMCLK_CTRL, 0xf0, BIT(0)); ++ lpc32xx_clk_div_quirk(LPC32XX_CLKPWR_PWMCLK_CTRL, 0xf00, BIT(2)); ++ lpc32xx_clk_div_quirk(LPC32XX_CLKPWR_MS_CTRL, 0xf, BIT(5) | BIT(9)); ++ + for (i = 1; i < LPC32XX_CLK_MAX; i++) { + clk[i] = lpc32xx_clk_register(i); + if (IS_ERR(clk[i])) { +-- +2.12.0 + diff --git a/queue/clocksource-drivers-arm_arch_timer-Don-t-assume-cloc.patch b/queue/clocksource-drivers-arm_arch_timer-Don-t-assume-cloc.patch new file mode 100644 index 0000000..e279a45 --- /dev/null +++ b/queue/clocksource-drivers-arm_arch_timer-Don-t-assume-cloc.patch @@ -0,0 +1,80 @@ +From d8ec7595a013237f82d965dcf981571aeb41855b Mon Sep 17 00:00:00 2001 +From: Brian Norris <briannorris@chromium.org> +Date: Tue, 4 Oct 2016 11:12:09 -0700 +Subject: [PATCH] clocksource/drivers/arm_arch_timer: Don't assume clock runs + in suspend + +commit d8ec7595a013237f82d965dcf981571aeb41855b upstream. + +The ARM specifies that the system counter "must be implemented in an +always-on power domain," and so we try to use the counter as a source of +timekeeping across suspend/resume. Unfortunately, some SoCs (e.g., +Rockchip's RK3399) do not keep the counter ticking properly when +switched from their high-power clock to the lower-power clock used in +system suspend. Support this quirk by adding a new device tree property. + +Signed-off-by: Brian Norris <briannorris@chromium.org> +Reviewed-by: Douglas Anderson <dianders@chromium.org> +Acked-by: Marc Zyngier <marc.zyngier@arm.com> +Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org> + +diff --git a/Documentation/devicetree/bindings/arm/arch_timer.txt b/Documentation/devicetree/bindings/arm/arch_timer.txt +index ef5fbe9a77c7..ad440a2b8051 100644 +--- a/Documentation/devicetree/bindings/arm/arch_timer.txt ++++ b/Documentation/devicetree/bindings/arm/arch_timer.txt +@@ -38,6 +38,11 @@ to deliver its interrupts via SPIs. + architecturally-defined reset values. Only supported for 32-bit + systems which follow the ARMv7 architected reset values. + ++- arm,no-tick-in-suspend : The main counter does not tick when the system is in ++ low-power system suspend on some SoCs. This behavior does not match the ++ Architecture Reference Manual's specification that the system counter "must ++ be implemented in an always-on power domain." ++ + + Example: + +diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c +index 73c487da6d2a..a2503db7e533 100644 +--- a/drivers/clocksource/arm_arch_timer.c ++++ b/drivers/clocksource/arm_arch_timer.c +@@ -81,6 +81,7 @@ static struct clock_event_device __percpu *arch_timer_evt; + static enum ppi_nr arch_timer_uses_ppi = VIRT_PPI; + static bool arch_timer_c3stop; + static bool arch_timer_mem_use_virtual; ++static bool arch_counter_suspend_stop; + + static bool evtstrm_enable = IS_ENABLED(CONFIG_ARM_ARCH_TIMER_EVTSTREAM); + +@@ -576,7 +577,7 @@ static struct clocksource clocksource_counter = { + .rating = 400, + .read = arch_counter_read, + .mask = CLOCKSOURCE_MASK(56), +- .flags = CLOCK_SOURCE_IS_CONTINUOUS | CLOCK_SOURCE_SUSPEND_NONSTOP, ++ .flags = CLOCK_SOURCE_IS_CONTINUOUS, + }; + + static struct cyclecounter cyclecounter = { +@@ -616,6 +617,8 @@ static void __init arch_counter_register(unsigned type) + arch_timer_read_counter = arch_counter_get_cntvct_mem; + } + ++ if (!arch_counter_suspend_stop) ++ clocksource_counter.flags |= CLOCK_SOURCE_SUSPEND_NONSTOP; + start_count = arch_timer_read_counter(); + clocksource_register_hz(&clocksource_counter, arch_timer_rate); + cyclecounter.mult = clocksource_counter.mult; +@@ -907,6 +910,10 @@ static int __init arch_timer_of_init(struct device_node *np) + of_property_read_bool(np, "arm,cpu-registers-not-fw-configured")) + arch_timer_uses_ppi = PHYS_SECURE_PPI; + ++ /* On some systems, the counter stops ticking when in suspend. */ ++ arch_counter_suspend_stop = of_property_read_bool(np, ++ "arm,no-tick-in-suspend"); ++ + return arch_timer_init(); + } + CLOCKSOURCE_OF_DECLARE(armv7_arch_timer, "arm,armv7-timer", arch_timer_of_init); +-- +2.12.0 + diff --git a/queue/cpufreq-Bring-CPUs-up-even-if-cpufreq_online-failed.patch b/queue/cpufreq-Bring-CPUs-up-even-if-cpufreq_online-failed.patch new file mode 100644 index 0000000..4fddb0d --- /dev/null +++ b/queue/cpufreq-Bring-CPUs-up-even-if-cpufreq_online-failed.patch @@ -0,0 +1,77 @@ +From c4a3fa261b16858416f1fd7db03a33d7ef5fc0b3 Mon Sep 17 00:00:00 2001 +From: Chen Yu <yu.c.chen@intel.com> +Date: Sun, 9 Apr 2017 13:45:16 +0800 +Subject: [PATCH] cpufreq: Bring CPUs up even if cpufreq_online() failed + +commit c4a3fa261b16858416f1fd7db03a33d7ef5fc0b3 upstream. + +There is a report that after commit 27622b061eb4 ("cpufreq: Convert +to hotplug state machine"), the normal CPU offline/online cycle +fails on some platforms. + +According to the ftrace result, this problem was triggered on +platforms using acpi-cpufreq as the default cpufreq driver, +and due to the lack of some ACPI freq method (eg. _PCT), +cpufreq_online() failed and returned a negative value, so the CPU +hotplug state machine rolled back the CPU online process. Actually, +from the user's perspective, the failure of cpufreq_online() should +not prevent that CPU from being brought up, although cpufreq might +not work on that CPU. + +BTW, during system startup cpufreq_online() is not invoked via CPU +online but by the cpufreq device creation process, so the APs can be +brought up even though cpufreq_online() fails in that stage. + +This patch ignores the return value of cpufreq_online/offline() and +lets the cpufreq framework deal with the failure. cpufreq_online() +itself will do a proper rollback in that case and if _PCT is missing, +the ACPI cpufreq driver will print a warning if the corresponding +debug options have been enabled. + +Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=194581 +Fixes: 27622b061eb4 ("cpufreq: Convert to hotplug state machine") +Reported-and-tested-by: Tomasz Maciej Nowak <tmn505@gmail.com> +Signed-off-by: Chen Yu <yu.c.chen@intel.com> +Acked-by: Viresh Kumar <viresh.kumar@linaro.org> +Cc: 4.9+ <stable@vger.kernel.org> # 4.9+ +Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> + +diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c +index bc96d423781a..0e3f6496524d 100644 +--- a/drivers/cpufreq/cpufreq.c ++++ b/drivers/cpufreq/cpufreq.c +@@ -2398,6 +2398,20 @@ EXPORT_SYMBOL_GPL(cpufreq_boost_enabled); + *********************************************************************/ + static enum cpuhp_state hp_online; + ++static int cpuhp_cpufreq_online(unsigned int cpu) ++{ ++ cpufreq_online(cpu); ++ ++ return 0; ++} ++ ++static int cpuhp_cpufreq_offline(unsigned int cpu) ++{ ++ cpufreq_offline(cpu); ++ ++ return 0; ++} ++ + /** + * cpufreq_register_driver - register a CPU Frequency driver + * @driver_data: A struct cpufreq_driver containing the values# +@@ -2460,8 +2474,8 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data) + } + + ret = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN, "cpufreq:online", +- cpufreq_online, +- cpufreq_offline); ++ cpuhp_cpufreq_online, ++ cpuhp_cpufreq_offline); + if (ret < 0) + goto err_if_unreg; + hp_online = ret; +-- +2.12.0 + diff --git a/queue/crypto-ahash-Fix-EINPROGRESS-notification-callback.patch b/queue/crypto-ahash-Fix-EINPROGRESS-notification-callback.patch new file mode 100644 index 0000000..9bc9732 --- /dev/null +++ b/queue/crypto-ahash-Fix-EINPROGRESS-notification-callback.patch @@ -0,0 +1,230 @@ +From ef0579b64e93188710d48667cb5e014926af9f1b Mon Sep 17 00:00:00 2001 +From: Herbert Xu <herbert@gondor.apana.org.au> +Date: Mon, 10 Apr 2017 17:27:57 +0800 +Subject: [PATCH] crypto: ahash - Fix EINPROGRESS notification callback + +commit ef0579b64e93188710d48667cb5e014926af9f1b upstream. + +The ahash API modifies the request's callback function in order +to clean up after itself in some corner cases (unaligned final +and missing finup). + +When the request is complete ahash will restore the original +callback and everything is fine. However, when the request gets +an EBUSY on a full queue, an EINPROGRESS callback is made while +the request is still ongoing. + +In this case the ahash API will incorrectly call its own callback. + +This patch fixes the problem by creating a temporary request +object on the stack which is used to relay EINPROGRESS back to +the original completion function. + +This patch also adds code to preserve the original flags value. + +Fixes: ab6bf4e5e5e4 ("crypto: hash - Fix the pointer voodoo in...") +Cc: <stable@vger.kernel.org> +Reported-by: Sabrina Dubroca <sd@queasysnail.net> +Tested-by: Sabrina Dubroca <sd@queasysnail.net> +Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> + +diff --git a/crypto/ahash.c b/crypto/ahash.c +index e58c4970c22b..826cd7ab4d4a 100644 +--- a/crypto/ahash.c ++++ b/crypto/ahash.c +@@ -32,6 +32,7 @@ struct ahash_request_priv { + crypto_completion_t complete; + void *data; + u8 *result; ++ u32 flags; + void *ubuf[] CRYPTO_MINALIGN_ATTR; + }; + +@@ -253,6 +254,8 @@ static int ahash_save_req(struct ahash_request *req, crypto_completion_t cplt) + priv->result = req->result; + priv->complete = req->base.complete; + priv->data = req->base.data; ++ priv->flags = req->base.flags; ++ + /* + * WARNING: We do not backup req->priv here! The req->priv + * is for internal use of the Crypto API and the +@@ -267,38 +270,44 @@ static int ahash_save_req(struct ahash_request *req, crypto_completion_t cplt) + return 0; + } + +-static void ahash_restore_req(struct ahash_request *req) ++static void ahash_restore_req(struct ahash_request *req, int err) + { + struct ahash_request_priv *priv = req->priv; + ++ if (!err) ++ memcpy(priv->result, req->result, ++ crypto_ahash_digestsize(crypto_ahash_reqtfm(req))); ++ + /* Restore the original crypto request. */ + req->result = priv->result; +- req->base.complete = priv->complete; +- req->base.data = priv->data; ++ ++ ahash_request_set_callback(req, priv->flags, ++ priv->complete, priv->data); + req->priv = NULL; + + /* Free the req->priv.priv from the ADJUSTED request. */ + kzfree(priv); + } + +-static void ahash_op_unaligned_finish(struct ahash_request *req, int err) ++static void ahash_notify_einprogress(struct ahash_request *req) + { + struct ahash_request_priv *priv = req->priv; ++ struct crypto_async_request oreq; + +- if (err == -EINPROGRESS) +- return; +- +- if (!err) +- memcpy(priv->result, req->result, +- crypto_ahash_digestsize(crypto_ahash_reqtfm(req))); ++ oreq.data = priv->data; + +- ahash_restore_req(req); ++ priv->complete(&oreq, -EINPROGRESS); + } + + static void ahash_op_unaligned_done(struct crypto_async_request *req, int err) + { + struct ahash_request *areq = req->data; + ++ if (err == -EINPROGRESS) { ++ ahash_notify_einprogress(areq); ++ return; ++ } ++ + /* + * Restore the original request, see ahash_op_unaligned() for what + * goes where. +@@ -309,7 +318,7 @@ static void ahash_op_unaligned_done(struct crypto_async_request *req, int err) + */ + + /* First copy req->result into req->priv.result */ +- ahash_op_unaligned_finish(areq, err); ++ ahash_restore_req(areq, err); + + /* Complete the ORIGINAL request. */ + areq->base.complete(&areq->base, err); +@@ -325,7 +334,12 @@ static int ahash_op_unaligned(struct ahash_request *req, + return err; + + err = op(req); +- ahash_op_unaligned_finish(req, err); ++ if (err == -EINPROGRESS || ++ (err == -EBUSY && (ahash_request_flags(req) & ++ CRYPTO_TFM_REQ_MAY_BACKLOG))) ++ return err; ++ ++ ahash_restore_req(req, err); + + return err; + } +@@ -360,25 +374,14 @@ int crypto_ahash_digest(struct ahash_request *req) + } + EXPORT_SYMBOL_GPL(crypto_ahash_digest); + +-static void ahash_def_finup_finish2(struct ahash_request *req, int err) ++static void ahash_def_finup_done2(struct crypto_async_request *req, int err) + { +- struct ahash_request_priv *priv = req->priv; ++ struct ahash_request *areq = req->data; + + if (err == -EINPROGRESS) + return; + +- if (!err) +- memcpy(priv->result, req->result, +- crypto_ahash_digestsize(crypto_ahash_reqtfm(req))); +- +- ahash_restore_req(req); +-} +- +-static void ahash_def_finup_done2(struct crypto_async_request *req, int err) +-{ +- struct ahash_request *areq = req->data; +- +- ahash_def_finup_finish2(areq, err); ++ ahash_restore_req(areq, err); + + areq->base.complete(&areq->base, err); + } +@@ -389,11 +392,15 @@ static int ahash_def_finup_finish1(struct ahash_request *req, int err) + goto out; + + req->base.complete = ahash_def_finup_done2; +- req->base.flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; ++ + err = crypto_ahash_reqtfm(req)->final(req); ++ if (err == -EINPROGRESS || ++ (err == -EBUSY && (ahash_request_flags(req) & ++ CRYPTO_TFM_REQ_MAY_BACKLOG))) ++ return err; + + out: +- ahash_def_finup_finish2(req, err); ++ ahash_restore_req(req, err); + return err; + } + +@@ -401,7 +408,16 @@ static void ahash_def_finup_done1(struct crypto_async_request *req, int err) + { + struct ahash_request *areq = req->data; + ++ if (err == -EINPROGRESS) { ++ ahash_notify_einprogress(areq); ++ return; ++ } ++ ++ areq->base.flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; ++ + err = ahash_def_finup_finish1(areq, err); ++ if (areq->priv) ++ return; + + areq->base.complete(&areq->base, err); + } +@@ -416,6 +432,11 @@ static int ahash_def_finup(struct ahash_request *req) + return err; + + err = tfm->update(req); ++ if (err == -EINPROGRESS || ++ (err == -EBUSY && (ahash_request_flags(req) & ++ CRYPTO_TFM_REQ_MAY_BACKLOG))) ++ return err; ++ + return ahash_def_finup_finish1(req, err); + } + +diff --git a/include/crypto/internal/hash.h b/include/crypto/internal/hash.h +index 1d4f365d8f03..f6d9af3efa45 100644 +--- a/include/crypto/internal/hash.h ++++ b/include/crypto/internal/hash.h +@@ -166,6 +166,16 @@ static inline struct ahash_instance *ahash_alloc_instance( + return crypto_alloc_instance2(name, alg, ahash_instance_headroom()); + } + ++static inline void ahash_request_complete(struct ahash_request *req, int err) ++{ ++ req->base.complete(&req->base, err); ++} ++ ++static inline u32 ahash_request_flags(struct ahash_request *req) ++{ ++ return req->base.flags; ++} ++ + static inline struct crypto_ahash *crypto_spawn_ahash( + struct crypto_ahash_spawn *spawn) + { +-- +2.12.0 + diff --git a/queue/crypto-algif_aead-Fix-bogus-request-dereference-in-c.patch b/queue/crypto-algif_aead-Fix-bogus-request-dereference-in-c.patch new file mode 100644 index 0000000..65c84f7 --- /dev/null +++ b/queue/crypto-algif_aead-Fix-bogus-request-dereference-in-c.patch @@ -0,0 +1,66 @@ +From e6534aebb26e32fbab14df9c713c65e8507d17e4 Mon Sep 17 00:00:00 2001 +From: Herbert Xu <herbert@gondor.apana.org.au> +Date: Mon, 10 Apr 2017 17:59:07 +0800 +Subject: [PATCH] crypto: algif_aead - Fix bogus request dereference in + completion function + +commit e6534aebb26e32fbab14df9c713c65e8507d17e4 upstream. + +The algif_aead completion function tries to deduce the aead_request +from the crypto_async_request argument. This is broken because +the API does not guarantee that the same request will be pased to +the completion function. Only the value of req->data can be used +in the completion function. + +This patch fixes it by storing a pointer to sk in areq and using +that instead of passing in sk through req->data. + +Fixes: 83094e5e9e49 ("crypto: af_alg - add async support to...") +Cc: <stable@vger.kernel.org> +Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> + +diff --git a/crypto/algif_aead.c b/crypto/algif_aead.c +index 5a8053758657..ef59d9926ee9 100644 +--- a/crypto/algif_aead.c ++++ b/crypto/algif_aead.c +@@ -40,6 +40,7 @@ struct aead_async_req { + struct aead_async_rsgl first_rsgl; + struct list_head list; + struct kiocb *iocb; ++ struct sock *sk; + unsigned int tsgls; + char iv[]; + }; +@@ -379,12 +380,10 @@ unlock: + + static void aead_async_cb(struct crypto_async_request *_req, int err) + { +- struct sock *sk = _req->data; +- struct alg_sock *ask = alg_sk(sk); +- struct aead_ctx *ctx = ask->private; +- struct crypto_aead *tfm = crypto_aead_reqtfm(&ctx->aead_req); +- struct aead_request *req = aead_request_cast(_req); ++ struct aead_request *req = _req->data; ++ struct crypto_aead *tfm = crypto_aead_reqtfm(req); + struct aead_async_req *areq = GET_ASYM_REQ(req, tfm); ++ struct sock *sk = areq->sk; + struct scatterlist *sg = areq->tsgl; + struct aead_async_rsgl *rsgl; + struct kiocb *iocb = areq->iocb; +@@ -447,11 +446,12 @@ static int aead_recvmsg_async(struct socket *sock, struct msghdr *msg, + memset(&areq->first_rsgl, '\0', sizeof(areq->first_rsgl)); + INIT_LIST_HEAD(&areq->list); + areq->iocb = msg->msg_iocb; ++ areq->sk = sk; + memcpy(areq->iv, ctx->iv, crypto_aead_ivsize(tfm)); + aead_request_set_tfm(req, tfm); + aead_request_set_ad(req, ctx->aead_assoclen); + aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, +- aead_async_cb, sk); ++ aead_async_cb, req); + used -= ctx->aead_assoclen; + + /* take over all tx sgls from ctx */ +-- +2.12.0 + diff --git a/queue/crypto-caam-fix-RNG-deinstantiation-error-checking.patch b/queue/crypto-caam-fix-RNG-deinstantiation-error-checking.patch new file mode 100644 index 0000000..656ca8e --- /dev/null +++ b/queue/crypto-caam-fix-RNG-deinstantiation-error-checking.patch @@ -0,0 +1,40 @@ +From 40c98cb57cdbc377456116ad4582c89e329721b0 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Horia=20Geant=C4=83?= <horia.geanta@nxp.com> +Date: Wed, 5 Apr 2017 11:41:03 +0300 +Subject: [PATCH] crypto: caam - fix RNG deinstantiation error checking +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit 40c98cb57cdbc377456116ad4582c89e329721b0 upstream. + +RNG instantiation was previously fixed by +commit 62743a4145bb9 ("crypto: caam - fix RNG init descriptor ret. code checking") +while deinstantiation was not addressed. + +Since the descriptors used are similar, in the sense that they both end +with a JUMP HALT command, checking for errors should be similar too, +i.e. status code 7000_0000h should be considered successful. + +Cc: <stable@vger.kernel.org> # 3.13+ +Fixes: 1005bccd7a4a6 ("crypto: caam - enable instantiation of all RNG4 state handles") +Signed-off-by: Horia Geantă <horia.geanta@nxp.com> +Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> + +diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c +index 220f94bd1635..5d7f73d60515 100644 +--- a/drivers/crypto/caam/ctrl.c ++++ b/drivers/crypto/caam/ctrl.c +@@ -281,7 +281,8 @@ static int deinstantiate_rng(struct device *ctrldev, int state_handle_mask) + /* Try to run it through DECO0 */ + ret = run_descriptor_deco0(ctrldev, desc, &status); + +- if (ret || status) { ++ if (ret || ++ (status && status != JRSTA_SSRC_JUMP_HALT_CC)) { + dev_err(ctrldev, + "Failed to deinstantiate RNG4 SH%d\n", + sh_idx); +-- +2.12.0 + diff --git a/queue/crypto-caam-fix-invalid-dereference-in-caam_rsa_init.patch b/queue/crypto-caam-fix-invalid-dereference-in-caam_rsa_init.patch new file mode 100644 index 0000000..ea23fed --- /dev/null +++ b/queue/crypto-caam-fix-invalid-dereference-in-caam_rsa_init.patch @@ -0,0 +1,34 @@ +From 33fa46d7b310e06d2cb2ab5417c100af120bfb65 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Horia=20Geant=C4=83?= <horia.geanta@nxp.com> +Date: Mon, 3 Apr 2017 18:30:07 +0300 +Subject: [PATCH] crypto: caam - fix invalid dereference in caam_rsa_init_tfm() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit 33fa46d7b310e06d2cb2ab5417c100af120bfb65 upstream. + +In case caam_jr_alloc() fails, ctx->dev carries the error code, +thus accessing it with dev_err() is incorrect. + +Cc: <stable@vger.kernel.org> # 4.8+ +Fixes: 8c419778ab57e ("crypto: caam - add support for RSA algorithm") +Signed-off-by: Horia Geantă <horia.geanta@nxp.com> +Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> + +diff --git a/drivers/crypto/caam/caampkc.c b/drivers/crypto/caam/caampkc.c +index 32100c4851dd..49cbdcba7883 100644 +--- a/drivers/crypto/caam/caampkc.c ++++ b/drivers/crypto/caam/caampkc.c +@@ -506,7 +506,7 @@ static int caam_rsa_init_tfm(struct crypto_akcipher *tfm) + ctx->dev = caam_jr_alloc(); + + if (IS_ERR(ctx->dev)) { +- dev_err(ctx->dev, "Job Ring Device allocation for transform failed\n"); ++ pr_err("Job Ring Device allocation for transform failed\n"); + return PTR_ERR(ctx->dev); + } + +-- +2.12.0 + diff --git a/queue/dm-raid-fix-NULL-pointer-dereference-for-raid1-witho.patch b/queue/dm-raid-fix-NULL-pointer-dereference-for-raid1-witho.patch new file mode 100644 index 0000000..09ad4d6 --- /dev/null +++ b/queue/dm-raid-fix-NULL-pointer-dereference-for-raid1-witho.patch @@ -0,0 +1,94 @@ +From 7a0c5c5b834fb60764b494b0e39c239da3b0774b Mon Sep 17 00:00:00 2001 +From: Dmitry Bilunov <kmeaw@yandex-team.ru> +Date: Thu, 30 Mar 2017 18:14:26 +0300 +Subject: [PATCH] dm raid: fix NULL pointer dereference for raid1 without + bitmap +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit 7a0c5c5b834fb60764b494b0e39c239da3b0774b upstream. + +Commit 4257e08 ("dm raid: support to change bitmap region size") +introduced a bitmap resize call during preresume phase. User can create +a DM device with "raid" target configured as raid1 with no metadata +devices to hold superblock/bitmap info. It can be achieved using the +following sequence: + + truncate -s 32M /dev/shm/raid-test + LOOP=$(losetup --show -f /dev/shm/raid-test) + dmsetup create raid-test-linear0 --table "0 1024 linear $LOOP 0" + dmsetup create raid-test-linear1 --table "0 1024 linear $LOOP 1024" + dmsetup create raid-test --table "0 1024 raid raid1 1 2048 2 - /dev/mapper/raid-test-linear0 - /dev/mapper/raid-test-linear1" + +This results in the following crash: + +[ 4029.110216] device-mapper: raid: Ignoring chunk size parameter for RAID 1 +[ 4029.110217] device-mapper: raid: Choosing default region size of 4MiB +[ 4029.111349] md/raid1:mdX: active with 2 out of 2 mirrors +[ 4029.114770] BUG: unable to handle kernel NULL pointer dereference at 0000000000000030 +[ 4029.114802] IP: bitmap_resize+0x25/0x7c0 [md_mod] +[ 4029.114816] PGD 0 +… +[ 4029.115059] Hardware name: Aquarius Pro P30 S85 BUY-866/B85M-E, BIOS 2304 05/25/2015 +[ 4029.115079] task: ffff88015cc29a80 task.stack: ffffc90001a5c000 +[ 4029.115097] RIP: 0010:bitmap_resize+0x25/0x7c0 [md_mod] +[ 4029.115112] RSP: 0018:ffffc90001a5fb68 EFLAGS: 00010246 +[ 4029.115127] RAX: 0000000000000005 RBX: 0000000000000000 RCX: 0000000000000000 +[ 4029.115146] RDX: 0000000000000000 RSI: 0000000000000400 RDI: 0000000000000000 +[ 4029.115166] RBP: ffffc90001a5fc28 R08: 0000000800000000 R09: 00000008ffffffff +[ 4029.115185] R10: ffffea0005661600 R11: ffff88015cc29a80 R12: ffff88021231f058 +[ 4029.115204] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000 +[ 4029.115223] FS: 00007fe73a6b4740(0000) GS:ffff88021ea80000(0000) knlGS:0000000000000000 +[ 4029.115245] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[ 4029.115261] CR2: 0000000000000030 CR3: 0000000159a74000 CR4: 00000000001426e0 +[ 4029.115281] Call Trace: +[ 4029.115291] ? raid_iterate_devices+0x63/0x80 [dm_raid] +[ 4029.115309] ? dm_table_all_devices_attribute.isra.23+0x41/0x70 [dm_mod] +[ 4029.115329] ? dm_table_set_restrictions+0x225/0x2d0 [dm_mod] +[ 4029.115346] raid_preresume+0x81/0x2e0 [dm_raid] +[ 4029.115361] dm_table_resume_targets+0x47/0xe0 [dm_mod] +[ 4029.115378] dm_resume+0xa8/0xd0 [dm_mod] +[ 4029.115391] dev_suspend+0x123/0x250 [dm_mod] +[ 4029.115405] ? table_load+0x350/0x350 [dm_mod] +[ 4029.115419] ctl_ioctl+0x1c2/0x490 [dm_mod] +[ 4029.115433] dm_ctl_ioctl+0xe/0x20 [dm_mod] +[ 4029.115447] do_vfs_ioctl+0x8d/0x5a0 +[ 4029.115459] ? ____fput+0x9/0x10 +[ 4029.115470] ? task_work_run+0x79/0xa0 +[ 4029.115481] SyS_ioctl+0x3c/0x70 +[ 4029.115493] entry_SYSCALL_64_fastpath+0x13/0x94 + +The raid_preresume() function incorrectly assumes that the raid_set has +a bitmap enabled if RT_FLAG_RS_BITMAP_LOADED is set. But +RT_FLAG_RS_BITMAP_LOADED is getting set in __load_dirty_region_bitmap() +even if there is no bitmap present (and bitmap_load() happily returns 0 +even if a bitmap isn't present). So the only way forward in the +near-term is to check if the bitmap is present by seeing if +mddev->bitmap is not NULL after bitmap_load() has been called. + +By doing so the above NULL pointer is avoided. + +Fixes: 4257e08 ("dm raid: support to change bitmap region size") +Cc: stable@vger.kernel.org # v4.8+ +Signed-off-by: Dmitry Bilunov <kmeaw@yandex-team.ru> +Signed-off-by: Andrey Smetanin <asmetanin@yandex-team.ru> +Acked-by: Heinz Mauelshagen <heinzm@redhat.com> +Signed-off-by: Mike Snitzer <snitzer@redhat.com> + +diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c +index f8564d63982f..1e217ba84d09 100644 +--- a/drivers/md/dm-raid.c ++++ b/drivers/md/dm-raid.c +@@ -3726,7 +3726,7 @@ static int raid_preresume(struct dm_target *ti) + return r; + + /* Resize bitmap to adjust to changed region size (aka MD bitmap chunksize) */ +- if (test_bit(RT_FLAG_RS_BITMAP_LOADED, &rs->runtime_flags) && ++ if (test_bit(RT_FLAG_RS_BITMAP_LOADED, &rs->runtime_flags) && mddev->bitmap && + mddev->bitmap_info.chunksize != to_bytes(rs->requested_bitmap_chunk_sectors)) { + r = bitmap_resize(mddev->bitmap, mddev->dev_sectors, + to_bytes(rs->requested_bitmap_chunk_sectors), 0); +-- +2.12.0 + diff --git a/queue/dm-verity-fec-fix-bufio-leaks.patch b/queue/dm-verity-fec-fix-bufio-leaks.patch new file mode 100644 index 0000000..915b012 --- /dev/null +++ b/queue/dm-verity-fec-fix-bufio-leaks.patch @@ -0,0 +1,48 @@ +From 86e3e83b443669dd2bcc5c8a83b23e3aa0694c0d Mon Sep 17 00:00:00 2001 +From: Sami Tolvanen <samitolvanen@google.com> +Date: Fri, 31 Mar 2017 12:32:45 -0700 +Subject: [PATCH] dm verity fec: fix bufio leaks + +commit 86e3e83b443669dd2bcc5c8a83b23e3aa0694c0d upstream. + +Buffers read through dm_bufio_read() were not released in all code paths. + +Fixes: a739ff3f543a ("dm verity: add support for forward error correction") +Cc: stable@vger.kernel.org # v4.5+ +Signed-off-by: Sami Tolvanen <samitolvanen@google.com> +Signed-off-by: Mike Snitzer <snitzer@redhat.com> + +diff --git a/drivers/md/dm-verity-fec.c b/drivers/md/dm-verity-fec.c +index c3cc04d89524..78f36012eaca 100644 +--- a/drivers/md/dm-verity-fec.c ++++ b/drivers/md/dm-verity-fec.c +@@ -146,8 +146,6 @@ static int fec_decode_bufs(struct dm_verity *v, struct dm_verity_fec_io *fio, + block = fec_buffer_rs_block(v, fio, n, i); + res = fec_decode_rs8(v, fio, block, &par[offset], neras); + if (res < 0) { +- dm_bufio_release(buf); +- + r = res; + goto error; + } +@@ -172,6 +170,8 @@ static int fec_decode_bufs(struct dm_verity *v, struct dm_verity_fec_io *fio, + done: + r = corrected; + error: ++ dm_bufio_release(buf); ++ + if (r < 0 && neras) + DMERR_LIMIT("%s: FEC %llu: failed to correct: %d", + v->data_dev->name, (unsigned long long)rsb, r); +@@ -269,7 +269,7 @@ static int fec_read_bufs(struct dm_verity *v, struct dm_verity_io *io, + &is_zero) == 0) { + /* skip known zero blocks entirely */ + if (is_zero) +- continue; ++ goto done; + + /* + * skip if we have already found the theoretical +-- +2.12.0 + diff --git a/queue/dm-verity-fec-limit-error-correction-recursion.patch b/queue/dm-verity-fec-limit-error-correction-recursion.patch new file mode 100644 index 0000000..d2c094f --- /dev/null +++ b/queue/dm-verity-fec-limit-error-correction-recursion.patch @@ -0,0 +1,86 @@ +From f1a880a93baaadb14c10a348fd199f1cdb6bcccd Mon Sep 17 00:00:00 2001 +From: Sami Tolvanen <samitolvanen@google.com> +Date: Wed, 15 Mar 2017 15:12:23 -0700 +Subject: [PATCH] dm verity fec: limit error correction recursion + +commit f1a880a93baaadb14c10a348fd199f1cdb6bcccd upstream. + +If the hash tree itself is sufficiently corrupt in addition to data blocks, +it's possible for error correction to end up in a deep recursive loop, +which eventually causes a kernel panic. This change limits the +recursion to a reasonable level during a single I/O operation. + +Fixes: a739ff3f543a ("dm verity: add support for forward error correction") +Signed-off-by: Sami Tolvanen <samitolvanen@google.com> +Signed-off-by: Mike Snitzer <snitzer@redhat.com> +Cc: stable@vger.kernel.org # v4.5+ + +diff --git a/drivers/md/dm-verity-fec.c b/drivers/md/dm-verity-fec.c +index 0f0eb8a3d922..c3cc04d89524 100644 +--- a/drivers/md/dm-verity-fec.c ++++ b/drivers/md/dm-verity-fec.c +@@ -439,6 +439,13 @@ int verity_fec_decode(struct dm_verity *v, struct dm_verity_io *io, + if (!verity_fec_is_enabled(v)) + return -EOPNOTSUPP; + ++ if (fio->level >= DM_VERITY_FEC_MAX_RECURSION) { ++ DMWARN_LIMIT("%s: FEC: recursion too deep", v->data_dev->name); ++ return -EIO; ++ } ++ ++ fio->level++; ++ + if (type == DM_VERITY_BLOCK_TYPE_METADATA) + block += v->data_blocks; + +@@ -470,7 +477,7 @@ int verity_fec_decode(struct dm_verity *v, struct dm_verity_io *io, + if (r < 0) { + r = fec_decode_rsb(v, io, fio, rsb, offset, true); + if (r < 0) +- return r; ++ goto done; + } + + if (dest) +@@ -480,6 +487,8 @@ int verity_fec_decode(struct dm_verity *v, struct dm_verity_io *io, + r = verity_for_bv_block(v, io, iter, fec_bv_copy); + } + ++done: ++ fio->level--; + return r; + } + +@@ -520,6 +529,7 @@ void verity_fec_init_io(struct dm_verity_io *io) + memset(fio->bufs, 0, sizeof(fio->bufs)); + fio->nbufs = 0; + fio->output = NULL; ++ fio->level = 0; + } + + /* +diff --git a/drivers/md/dm-verity-fec.h b/drivers/md/dm-verity-fec.h +index 7fa0298b995e..bb31ce87a933 100644 +--- a/drivers/md/dm-verity-fec.h ++++ b/drivers/md/dm-verity-fec.h +@@ -27,6 +27,9 @@ + #define DM_VERITY_FEC_BUF_MAX \ + (1 << (PAGE_SHIFT - DM_VERITY_FEC_BUF_RS_BITS)) + ++/* maximum recursion level for verity_fec_decode */ ++#define DM_VERITY_FEC_MAX_RECURSION 4 ++ + #define DM_VERITY_OPT_FEC_DEV "use_fec_from_device" + #define DM_VERITY_OPT_FEC_BLOCKS "fec_blocks" + #define DM_VERITY_OPT_FEC_START "fec_start" +@@ -58,6 +61,7 @@ struct dm_verity_fec_io { + unsigned nbufs; /* number of buffers allocated */ + u8 *output; /* buffer for corrected output */ + size_t output_pos; ++ unsigned level; /* recursion level */ + }; + + #ifdef CONFIG_DM_VERITY_FEC +-- +2.12.0 + diff --git a/queue/dma-buf-add-support-for-compat-ioctl.patch b/queue/dma-buf-add-support-for-compat-ioctl.patch new file mode 100644 index 0000000..ed01c35 --- /dev/null +++ b/queue/dma-buf-add-support-for-compat-ioctl.patch @@ -0,0 +1,38 @@ +From 888022c0473d079bff9b47fb50434b1f20f8f37f Mon Sep 17 00:00:00 2001 +From: Marek Szyprowski <m.szyprowski@samsung.com> +Date: Tue, 21 Feb 2017 14:21:01 +0100 +Subject: [PATCH] dma-buf: add support for compat ioctl +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit 888022c0473d079bff9b47fb50434b1f20f8f37f upstream. + +Add compat ioctl support to dma-buf. This lets one to use DMA_BUF_IOCTL_SYNC +ioctl from 32bit application on 64bit kernel. Data structures for both 32 +and 64bit modes are same, so there is no need for additional translation +layer. + +Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> +Reviewed-by: Christian König <christian.koenig@amd.com> +Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch> +Signed-off-by: Sumit Semwal <sumit.semwal@linaro.org> +Link: http://patchwork.freedesktop.org/patch/msgid/1487683261-2655-1-git-send-email-m.szyprowski@samsung.com + +diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c +index 718f832a5c71..0007b792827b 100644 +--- a/drivers/dma-buf/dma-buf.c ++++ b/drivers/dma-buf/dma-buf.c +@@ -325,6 +325,9 @@ static const struct file_operations dma_buf_fops = { + .llseek = dma_buf_llseek, + .poll = dma_buf_poll, + .unlocked_ioctl = dma_buf_ioctl, ++#ifdef CONFIG_COMPAT ++ .compat_ioctl = dma_buf_ioctl, ++#endif + }; + + /* +-- +2.12.0 + diff --git a/queue/drm-edid-constify-edid-quirk-list.patch b/queue/drm-edid-constify-edid-quirk-list.patch new file mode 100644 index 0000000..cbc56f4 --- /dev/null +++ b/queue/drm-edid-constify-edid-quirk-list.patch @@ -0,0 +1,47 @@ +From 23c4cfbdab494568600ae6073a2bf02be4b10f4e Mon Sep 17 00:00:00 2001 +From: Jani Nikula <jani.nikula@intel.com> +Date: Wed, 28 Dec 2016 13:06:26 +0200 +Subject: [PATCH] drm/edid: constify edid quirk list + +commit 23c4cfbdab494568600ae6073a2bf02be4b10f4e upstream. + +No reason not to be const. + +Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> +Signed-off-by: Jani Nikula <jani.nikula@intel.com> +Link: http://patchwork.freedesktop.org/patch/msgid/1482923186-22430-1-git-send-email-jani.nikula@intel.com + +diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c +index 67d6a73731d8..4ff04aa84dd0 100644 +--- a/drivers/gpu/drm/drm_edid.c ++++ b/drivers/gpu/drm/drm_edid.c +@@ -91,7 +91,7 @@ struct detailed_mode_closure { + #define LEVEL_GTF2 2 + #define LEVEL_CVT 3 + +-static struct edid_quirk { ++static const struct edid_quirk { + char vendor[4]; + int product_id; + u32 quirks; +@@ -1478,7 +1478,7 @@ EXPORT_SYMBOL(drm_edid_duplicate); + * + * Returns true if @vendor is in @edid, false otherwise + */ +-static bool edid_vendor(struct edid *edid, char *vendor) ++static bool edid_vendor(struct edid *edid, const char *vendor) + { + char edid_vendor[3]; + +@@ -1498,7 +1498,7 @@ static bool edid_vendor(struct edid *edid, char *vendor) + */ + static u32 edid_get_quirks(struct edid *edid) + { +- struct edid_quirk *quirk; ++ const struct edid_quirk *quirk; + int i; + + for (i = 0; i < ARRAY_SIZE(edid_quirk_list); i++) { +-- +2.12.0 + diff --git a/queue/drm-etnaviv-fix-missing-unlock-on-error-in-etnaviv_g.patch b/queue/drm-etnaviv-fix-missing-unlock-on-error-in-etnaviv_g.patch new file mode 100644 index 0000000..4fb58a3 --- /dev/null +++ b/queue/drm-etnaviv-fix-missing-unlock-on-error-in-etnaviv_g.patch @@ -0,0 +1,43 @@ +From 45abdf35cf82e4270328c7237e7812de960ac560 Mon Sep 17 00:00:00 2001 +From: Wei Yongjun <weiyongjun1@huawei.com> +Date: Wed, 12 Apr 2017 00:31:16 +0000 +Subject: [PATCH] drm/etnaviv: fix missing unlock on error in + etnaviv_gpu_submit() + +commit 45abdf35cf82e4270328c7237e7812de960ac560 upstream. + +Add the missing unlock before return from function etnaviv_gpu_submit() +in the error handling case. + +lst: fixed label name. + +Fixes: f3cd1b064f11 ("drm/etnaviv: (re-)protect fence allocation with +GPU mutex") +CC: stable@vger.kernel.org #4.9+ +Signed-off-by: Wei Yongjun <weiyongjun1@huawei.com> +Signed-off-by: Lucas Stach <l.stach@pengutronix.de> + +diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c +index da48819ff2e6..b78d9239e48f 100644 +--- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c ++++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c +@@ -1317,7 +1317,7 @@ int etnaviv_gpu_submit(struct etnaviv_gpu *gpu, + if (!fence) { + event_free(gpu, event); + ret = -ENOMEM; +- goto out_pm_put; ++ goto out_unlock; + } + + gpu->event[event].fence = fence; +@@ -1357,6 +1357,7 @@ int etnaviv_gpu_submit(struct etnaviv_gpu *gpu, + hangcheck_timer_reset(gpu); + ret = 0; + ++out_unlock: + mutex_unlock(&gpu->lock); + + out_pm_put: +-- +2.12.0 + diff --git a/queue/drm-i915-Avoid-rcu_barrier-from-reclaim-paths-shrink.patch b/queue/drm-i915-Avoid-rcu_barrier-from-reclaim-paths-shrink.patch new file mode 100644 index 0000000..0d99dd1 --- /dev/null +++ b/queue/drm-i915-Avoid-rcu_barrier-from-reclaim-paths-shrink.patch @@ -0,0 +1,273 @@ +From 3d3d18f086cdda72ee18a454db70ca72c6e3246c Mon Sep 17 00:00:00 2001 +From: Chris Wilson <chris@chris-wilson.co.uk> +Date: Tue, 21 Mar 2017 14:45:31 +0000 +Subject: [PATCH] drm/i915: Avoid rcu_barrier() from reclaim paths (shrinker) + +commit 3d3d18f086cdda72ee18a454db70ca72c6e3246c upstream. + +The rcu_barrier() takes the cpu_hotplug mutex which itself is not +reclaim-safe, and so rcu_barrier() is illegal from inside the shrinker. + +[ 309.661373] ========================================================= +[ 309.661376] [ INFO: possible irq lock inversion dependency detected ] +[ 309.661380] 4.11.0-rc1-CI-CI_DRM_2333+ #1 Tainted: G W +[ 309.661383] --------------------------------------------------------- +[ 309.661386] gem_exec_gttfil/6435 just changed the state of lock: +[ 309.661389] (rcu_preempt_state.barrier_mutex){+.+.-.}, at: [<ffffffff81100731>] _rcu_barrier+0x31/0x160 +[ 309.661399] but this lock took another, RECLAIM_FS-unsafe lock in the past: +[ 309.661402] (cpu_hotplug.lock){+.+.+.} +[ 309.661404] + + and interrupts could create inverse lock ordering between them. + +[ 309.661410] + other info that might help us debug this: +[ 309.661414] Possible interrupt unsafe locking scenario: + +[ 309.661417] CPU0 CPU1 +[ 309.661419] ---- ---- +[ 309.661421] lock(cpu_hotplug.lock); +[ 309.661425] local_irq_disable(); +[ 309.661432] lock(rcu_preempt_state.barrier_mutex); +[ 309.661441] lock(cpu_hotplug.lock); +[ 309.661446] <Interrupt> +[ 309.661448] lock(rcu_preempt_state.barrier_mutex); +[ 309.661453] + *** DEADLOCK *** + +[ 309.661460] 4 locks held by gem_exec_gttfil/6435: +[ 309.661464] #0: (sb_writers#10){.+.+.+}, at: [<ffffffff8120d83d>] vfs_write+0x17d/0x1f0 +[ 309.661475] #1: (debugfs_srcu){......}, at: [<ffffffff81320491>] debugfs_use_file_start+0x41/0xa0 +[ 309.661486] #2: (&attr->mutex){+.+.+.}, at: [<ffffffff8123a3e7>] simple_attr_write+0x37/0xe0 +[ 309.661495] #3: (&dev->struct_mutex){+.+.+.}, at: [<ffffffffa0091b4a>] i915_drop_caches_set+0x3a/0x150 [i915] +[ 309.661540] + the shortest dependencies between 2nd lock and 1st lock: +[ 309.661547] -> (cpu_hotplug.lock){+.+.+.} ops: 829 { +[ 309.661553] HARDIRQ-ON-W at: +[ 309.661560] __lock_acquire+0x5e5/0x1b50 +[ 309.661565] lock_acquire+0xc9/0x220 +[ 309.661572] __mutex_lock+0x6e/0x990 +[ 309.661576] mutex_lock_nested+0x16/0x20 +[ 309.661583] get_online_cpus+0x61/0x80 +[ 309.661590] kmem_cache_create+0x25/0x1d0 +[ 309.661596] debug_objects_mem_init+0x30/0x249 +[ 309.661602] start_kernel+0x341/0x3fe +[ 309.661607] x86_64_start_reservations+0x2a/0x2c +[ 309.661612] x86_64_start_kernel+0x173/0x186 +[ 309.661619] verify_cpu+0x0/0xfc +[ 309.661622] SOFTIRQ-ON-W at: +[ 309.661627] __lock_acquire+0x611/0x1b50 +[ 309.661632] lock_acquire+0xc9/0x220 +[ 309.661636] __mutex_lock+0x6e/0x990 +[ 309.661641] mutex_lock_nested+0x16/0x20 +[ 309.661646] get_online_cpus+0x61/0x80 +[ 309.661650] kmem_cache_create+0x25/0x1d0 +[ 309.661655] debug_objects_mem_init+0x30/0x249 +[ 309.661660] start_kernel+0x341/0x3fe +[ 309.661664] x86_64_start_reservations+0x2a/0x2c +[ 309.661669] x86_64_start_kernel+0x173/0x186 +[ 309.661674] verify_cpu+0x0/0xfc +[ 309.661677] RECLAIM_FS-ON-W at: +[ 309.661682] mark_held_locks+0x6f/0xa0 +[ 309.661687] lockdep_trace_alloc+0xb3/0x100 +[ 309.661693] kmem_cache_alloc_trace+0x31/0x2e0 +[ 309.661699] __smpboot_create_thread.part.1+0x27/0xe0 +[ 309.661704] smpboot_create_threads+0x61/0x90 +[ 309.661709] cpuhp_invoke_callback+0x9c/0x8a0 +[ 309.661713] cpuhp_up_callbacks+0x31/0xb0 +[ 309.661718] _cpu_up+0x7a/0xc0 +[ 309.661723] do_cpu_up+0x5f/0x80 +[ 309.661727] cpu_up+0xe/0x10 +[ 309.661734] smp_init+0x71/0xb3 +[ 309.661738] kernel_init_freeable+0x94/0x19e +[ 309.661743] kernel_init+0x9/0xf0 +[ 309.661748] ret_from_fork+0x2e/0x40 +[ 309.661752] INITIAL USE at: +[ 309.661757] __lock_acquire+0x234/0x1b50 +[ 309.661761] lock_acquire+0xc9/0x220 +[ 309.661766] __mutex_lock+0x6e/0x990 +[ 309.661771] mutex_lock_nested+0x16/0x20 +[ 309.661775] get_online_cpus+0x61/0x80 +[ 309.661780] __cpuhp_setup_state+0x44/0x170 +[ 309.661785] page_alloc_init+0x23/0x3a +[ 309.661790] start_kernel+0x124/0x3fe +[ 309.661794] x86_64_start_reservations+0x2a/0x2c +[ 309.661799] x86_64_start_kernel+0x173/0x186 +[ 309.661804] verify_cpu+0x0/0xfc +[ 309.661807] } +[ 309.661813] ... key at: [<ffffffff81e37690>] cpu_hotplug+0xb0/0x100 +[ 309.661817] ... acquired at: +[ 309.661821] lock_acquire+0xc9/0x220 +[ 309.661825] __mutex_lock+0x6e/0x990 +[ 309.661829] mutex_lock_nested+0x16/0x20 +[ 309.661833] get_online_cpus+0x61/0x80 +[ 309.661837] _rcu_barrier+0x9f/0x160 +[ 309.661841] rcu_barrier+0x10/0x20 +[ 309.661847] netdev_run_todo+0x5f/0x310 +[ 309.661852] rtnl_unlock+0x9/0x10 +[ 309.661856] default_device_exit_batch+0x133/0x150 +[ 309.661862] ops_exit_list.isra.0+0x4d/0x60 +[ 309.661866] cleanup_net+0x1d8/0x2c0 +[ 309.661872] process_one_work+0x1f4/0x6d0 +[ 309.661876] worker_thread+0x49/0x4a0 +[ 309.661881] kthread+0x107/0x140 +[ 309.661884] ret_from_fork+0x2e/0x40 + +[ 309.661890] -> (rcu_preempt_state.barrier_mutex){+.+.-.} ops: 179 { +[ 309.661896] HARDIRQ-ON-W at: +[ 309.661901] __lock_acquire+0x5e5/0x1b50 +[ 309.661905] lock_acquire+0xc9/0x220 +[ 309.661910] __mutex_lock+0x6e/0x990 +[ 309.661914] mutex_lock_nested+0x16/0x20 +[ 309.661919] _rcu_barrier+0x31/0x160 +[ 309.661923] rcu_barrier+0x10/0x20 +[ 309.661928] netdev_run_todo+0x5f/0x310 +[ 309.661932] rtnl_unlock+0x9/0x10 +[ 309.661936] default_device_exit_batch+0x133/0x150 +[ 309.661941] ops_exit_list.isra.0+0x4d/0x60 +[ 309.661946] cleanup_net+0x1d8/0x2c0 +[ 309.661951] process_one_work+0x1f4/0x6d0 +[ 309.661955] worker_thread+0x49/0x4a0 +[ 309.661960] kthread+0x107/0x140 +[ 309.661964] ret_from_fork+0x2e/0x40 +[ 309.661968] SOFTIRQ-ON-W at: +[ 309.661972] __lock_acquire+0x611/0x1b50 +[ 309.661977] lock_acquire+0xc9/0x220 +[ 309.661981] __mutex_lock+0x6e/0x990 +[ 309.661986] mutex_lock_nested+0x16/0x20 +[ 309.661990] _rcu_barrier+0x31/0x160 +[ 309.661995] rcu_barrier+0x10/0x20 +[ 309.661999] netdev_run_todo+0x5f/0x310 +[ 309.662003] rtnl_unlock+0x9/0x10 +[ 309.662008] default_device_exit_batch+0x133/0x150 +[ 309.662013] ops_exit_list.isra.0+0x4d/0x60 +[ 309.662017] cleanup_net+0x1d8/0x2c0 +[ 309.662022] process_one_work+0x1f4/0x6d0 +[ 309.662027] worker_thread+0x49/0x4a0 +[ 309.662031] kthread+0x107/0x140 +[ 309.662035] ret_from_fork+0x2e/0x40 +[ 309.662039] IN-RECLAIM_FS-W at: +[ 309.662043] __lock_acquire+0x638/0x1b50 +[ 309.662048] lock_acquire+0xc9/0x220 +[ 309.662053] __mutex_lock+0x6e/0x990 +[ 309.662058] mutex_lock_nested+0x16/0x20 +[ 309.662062] _rcu_barrier+0x31/0x160 +[ 309.662067] rcu_barrier+0x10/0x20 +[ 309.662089] i915_gem_shrink_all+0x33/0x40 [i915] +[ 309.662109] i915_drop_caches_set+0x141/0x150 [i915] +[ 309.662114] simple_attr_write+0xc7/0xe0 +[ 309.662119] full_proxy_write+0x4f/0x70 +[ 309.662124] __vfs_write+0x23/0x120 +[ 309.662128] vfs_write+0xc6/0x1f0 +[ 309.662133] SyS_write+0x44/0xb0 +[ 309.662138] entry_SYSCALL_64_fastpath+0x1c/0xb1 +[ 309.662142] INITIAL USE at: +[ 309.662147] __lock_acquire+0x234/0x1b50 +[ 309.662151] lock_acquire+0xc9/0x220 +[ 309.662156] __mutex_lock+0x6e/0x990 +[ 309.662160] mutex_lock_nested+0x16/0x20 +[ 309.662165] _rcu_barrier+0x31/0x160 +[ 309.662169] rcu_barrier+0x10/0x20 +[ 309.662174] netdev_run_todo+0x5f/0x310 +[ 309.662178] rtnl_unlock+0x9/0x10 +[ 309.662183] default_device_exit_batch+0x133/0x150 +[ 309.662188] ops_exit_list.isra.0+0x4d/0x60 +[ 309.662192] cleanup_net+0x1d8/0x2c0 +[ 309.662197] process_one_work+0x1f4/0x6d0 +[ 309.662202] worker_thread+0x49/0x4a0 +[ 309.662206] kthread+0x107/0x140 +[ 309.662210] ret_from_fork+0x2e/0x40 +[ 309.662214] } +[ 309.662220] ... key at: [<ffffffff81e4e1c8>] rcu_preempt_state+0x508/0x780 +[ 309.662225] ... acquired at: +[ 309.662229] check_usage_forwards+0x12b/0x130 +[ 309.662233] mark_lock+0x360/0x6f0 +[ 309.662237] __lock_acquire+0x638/0x1b50 +[ 309.662241] lock_acquire+0xc9/0x220 +[ 309.662245] __mutex_lock+0x6e/0x990 +[ 309.662249] mutex_lock_nested+0x16/0x20 +[ 309.662253] _rcu_barrier+0x31/0x160 +[ 309.662257] rcu_barrier+0x10/0x20 +[ 309.662279] i915_gem_shrink_all+0x33/0x40 [i915] +[ 309.662298] i915_drop_caches_set+0x141/0x150 [i915] +[ 309.662303] simple_attr_write+0xc7/0xe0 +[ 309.662307] full_proxy_write+0x4f/0x70 +[ 309.662311] __vfs_write+0x23/0x120 +[ 309.662315] vfs_write+0xc6/0x1f0 +[ 309.662319] SyS_write+0x44/0xb0 +[ 309.662323] entry_SYSCALL_64_fastpath+0x1c/0xb1 + +[ 309.662329] + stack backtrace: +[ 309.662335] CPU: 1 PID: 6435 Comm: gem_exec_gttfil Tainted: G W 4.11.0-rc1-CI-CI_DRM_2333+ #1 +[ 309.662342] Hardware name: Hewlett-Packard HP Compaq 8100 Elite SFF PC/304Ah, BIOS 786H1 v01.13 07/14/2011 +[ 309.662348] Call Trace: +[ 309.662354] dump_stack+0x67/0x92 +[ 309.662359] print_irq_inversion_bug.part.19+0x1a4/0x1b0 +[ 309.662365] check_usage_forwards+0x12b/0x130 +[ 309.662369] mark_lock+0x360/0x6f0 +[ 309.662374] ? print_shortest_lock_dependencies+0x1a0/0x1a0 +[ 309.662379] __lock_acquire+0x638/0x1b50 +[ 309.662383] ? __mutex_unlock_slowpath+0x3e/0x2e0 +[ 309.662388] ? trace_hardirqs_on+0xd/0x10 +[ 309.662392] ? _rcu_barrier+0x31/0x160 +[ 309.662396] lock_acquire+0xc9/0x220 +[ 309.662400] ? _rcu_barrier+0x31/0x160 +[ 309.662404] ? _rcu_barrier+0x31/0x160 +[ 309.662409] __mutex_lock+0x6e/0x990 +[ 309.662412] ? _rcu_barrier+0x31/0x160 +[ 309.662416] ? _rcu_barrier+0x31/0x160 +[ 309.662421] ? synchronize_rcu_expedited+0x35/0xb0 +[ 309.662426] ? _raw_spin_unlock_irqrestore+0x52/0x60 +[ 309.662434] mutex_lock_nested+0x16/0x20 +[ 309.662438] _rcu_barrier+0x31/0x160 +[ 309.662442] rcu_barrier+0x10/0x20 +[ 309.662464] i915_gem_shrink_all+0x33/0x40 [i915] +[ 309.662484] i915_drop_caches_set+0x141/0x150 [i915] +[ 309.662489] simple_attr_write+0xc7/0xe0 +[ 309.662494] full_proxy_write+0x4f/0x70 +[ 309.662498] __vfs_write+0x23/0x120 +[ 309.662503] ? rcu_read_lock_sched_held+0x75/0x80 +[ 309.662507] ? rcu_sync_lockdep_assert+0x2a/0x50 +[ 309.662512] ? __sb_start_write+0x102/0x210 +[ 309.662516] ? vfs_write+0x17d/0x1f0 +[ 309.662520] vfs_write+0xc6/0x1f0 +[ 309.662524] ? trace_hardirqs_on_caller+0xe7/0x200 +[ 309.662529] SyS_write+0x44/0xb0 +[ 309.662533] entry_SYSCALL_64_fastpath+0x1c/0xb1 +[ 309.662537] RIP: 0033:0x7f507eac24a0 +[ 309.662541] RSP: 002b:00007fffda8720e8 EFLAGS: 00000246 ORIG_RAX: 0000000000000001 +[ 309.662548] RAX: ffffffffffffffda RBX: ffffffff81482bd3 RCX: 00007f507eac24a0 +[ 309.662552] RDX: 0000000000000005 RSI: 00007fffda8720f0 RDI: 0000000000000005 +[ 309.662557] RBP: ffffc9000048bf88 R08: 0000000000000000 R09: 000000000000002c +[ 309.662561] R10: 0000000000000014 R11: 0000000000000246 R12: 00007fffda872230 +[ 309.662566] R13: 00007fffda872228 R14: 0000000000000201 R15: 00007fffda8720f0 +[ 309.662572] ? __this_cpu_preempt_check+0x13/0x20 + +Fixes: 0eafec6d3244 ("drm/i915: Enable lockless lookup of request tracking via RCU") +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=100192 +Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> +Cc: Daniel Vetter <daniel.vetter@ffwll.ch> +Cc: <stable@vger.kernel.org> # v4.9+ +Link: http://patchwork.freedesktop.org/patch/msgid/20170314115019.18127-1-chris@chris-wilson.co.uk +Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> +(cherry picked from commit bd784b7cc41af7a19cfb705fa6d800e511c4ab02) +Signed-off-by: Jani Nikula <jani.nikula@intel.com> +Link: http://patchwork.freedesktop.org/patch/msgid/20170321144531.12344-1-chris@chris-wilson.co.uk + +diff --git a/drivers/gpu/drm/i915/i915_gem_shrinker.c b/drivers/gpu/drm/i915/i915_gem_shrinker.c +index 401006b4c6a3..d5d2b4c6ed38 100644 +--- a/drivers/gpu/drm/i915/i915_gem_shrinker.c ++++ b/drivers/gpu/drm/i915/i915_gem_shrinker.c +@@ -263,7 +263,7 @@ unsigned long i915_gem_shrink_all(struct drm_i915_private *dev_priv) + I915_SHRINK_BOUND | + I915_SHRINK_UNBOUND | + I915_SHRINK_ACTIVE); +- rcu_barrier(); /* wait until our RCU delayed slab frees are completed */ ++ synchronize_rcu(); /* wait for our earlier RCU delayed slab frees */ + + return freed; + } +-- +2.12.0 + diff --git a/queue/drm-i915-Avoid-tweaking-evaluation-thresholds-on-Bay.patch b/queue/drm-i915-Avoid-tweaking-evaluation-thresholds-on-Bay.patch new file mode 100644 index 0000000..b96e409 --- /dev/null +++ b/queue/drm-i915-Avoid-tweaking-evaluation-thresholds-on-Bay.patch @@ -0,0 +1,94 @@ +From 34dc8993eef63681b062871413a9484008a2a78f Mon Sep 17 00:00:00 2001 +From: Mika Kuoppala <mika.kuoppala@linux.intel.com> +Date: Wed, 15 Feb 2017 15:52:59 +0200 +Subject: [PATCH] drm/i915: Avoid tweaking evaluation thresholds on Baytrail v3 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit 34dc8993eef63681b062871413a9484008a2a78f upstream. + +Certain Baytrails, namely the 4 cpu core variants, have been +plaqued by spurious system hangs, mostly occurring with light loads. + +Multiple bisects by various people point to a commit which changes the +reclocking strategy for Baytrail to follow its bigger brethen: +commit 8fb55197e64d ("drm/i915: Agressive downclocking on Baytrail") + +There is also a review comment attached to this commit from Deepak S +on avoiding punit access on Cherryview and thus it was excluded on +common reclocking path. By taking the same approach and omitting +the punit access by not tweaking the thresholds when the hardware +has been asked to move into different frequency, considerable gains +in stability have been observed. + +With J1900 box, light render/video load would end up in system hang +in usually less than 12 hours. With this patch applied, the cumulative +uptime has now been 34 days without issues. To provoke system hang, +light loads on both render and bsd engines in parallel have been used: +glxgears >/dev/null 2>/dev/null & +mpv --vo=vaapi --hwdec=vaapi --loop=inf vid.mp4 + +So far, author has not witnessed system hang with above load +and this patch applied. Reports from the tenacious people at +kernel bugzilla are also promising. + +Considering that the punit access frequency with this patch is +considerably less, there is a possibility that this will push +the, still unknown, root cause past the triggering point on most loads. + +But as we now can reliably reproduce the hang independently, +we can reduce the pain that users are having and use a +static thresholds until a root cause is found. + +v3: don't break debugfs and simplification (Chris Wilson) + +References: https://bugzilla.kernel.org/show_bug.cgi?id=109051 +Cc: Chris Wilson <chris@chris-wilson.co.uk> +Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> +Cc: Len Brown <len.brown@intel.com> +Cc: Daniel Vetter <daniel.vetter@ffwll.ch> +Cc: Jani Nikula <jani.nikula@intel.com> +Cc: fritsch@xbmc.org +Cc: miku@iki.fi +Cc: Ezequiel Garcia <ezequiel@vanguardiasur.com.ar> +CC: Michal Feix <michal@feix.cz> +Cc: Hans de Goede <hdegoede@redhat.com> +Cc: Deepak S <deepak.s@linux.intel.com> +Cc: Jarkko Nikula <jarkko.nikula@linux.intel.com> +Cc: <stable@vger.kernel.org> # v4.2+ +Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch> +Acked-by: Chris Wilson <chris@chris-wilson.co.uk> +Signed-off-by: Mika Kuoppala <mika.kuoppala@intel.com> +Link: http://patchwork.freedesktop.org/patch/msgid/1487166779-26945-1-git-send-email-mika.kuoppala@intel.com +(cherry picked from commit 6067a27d1f0184596d51decbac1c1fdc4acb012f) +Signed-off-by: Jani Nikula <jani.nikula@intel.com> + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 249623d45be0..65cd4c56c9dd 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -4891,6 +4891,12 @@ static void gen6_set_rps_thresholds(struct drm_i915_private *dev_priv, u8 val) + break; + } + ++ /* When byt can survive without system hang with dynamic ++ * sw freq adjustments, this restriction can be lifted. ++ */ ++ if (IS_VALLEYVIEW(dev_priv)) ++ goto skip_hw_write; ++ + I915_WRITE(GEN6_RP_UP_EI, + GT_INTERVAL_FROM_US(dev_priv, ei_up)); + I915_WRITE(GEN6_RP_UP_THRESHOLD, +@@ -4911,6 +4917,7 @@ static void gen6_set_rps_thresholds(struct drm_i915_private *dev_priv, u8 val) + GEN6_RP_UP_BUSY_AVG | + GEN6_RP_DOWN_IDLE_AVG); + ++skip_hw_write: + dev_priv->rps.power = new_power; + dev_priv->rps.up_threshold = threshold_up; + dev_priv->rps.down_threshold = threshold_down; +-- +2.12.0 + diff --git a/queue/drm-i915-Drop-support-for-I915_EXEC_CONSTANTS_-execb.patch b/queue/drm-i915-Drop-support-for-I915_EXEC_CONSTANTS_-execb.patch new file mode 100644 index 0000000..3e41581 --- /dev/null +++ b/queue/drm-i915-Drop-support-for-I915_EXEC_CONSTANTS_-execb.patch @@ -0,0 +1,177 @@ +From 0f5418e564ac6452b9086295646e602a9addc4bf Mon Sep 17 00:00:00 2001 +From: Kenneth Graunke <kenneth@whitecape.org> +Date: Mon, 13 Mar 2017 17:04:33 +0000 +Subject: [PATCH] drm/i915: Drop support for I915_EXEC_CONSTANTS_* execbuf + parameters. + +commit 0f5418e564ac6452b9086295646e602a9addc4bf upstream. + +This patch makes the I915_PARAM_HAS_EXEC_CONSTANTS getparam return 0 +(indicating the optional feature is not supported), and makes execbuf +always return -EINVAL if the flags are used. + +Apparently, no userspace ever shipped which used this optional feature: +I checked the git history of Mesa, xf86-video-intel, libva, and Beignet, +and there were zero commits showing a use of these flags. Kernel commit +72bfa19c8deb4 apparently introduced the feature prematurely. According +to Chris, the intention was to use this in cairo-drm, but "the use was +broken for gen6", so I don't think it ever happened. + +'relative_constants_mode' has always been tracked per-device, but this +has actually been wrong ever since hardware contexts were introduced, as +the INSTPM register is saved (and automatically restored) as part of the +render ring context. The software per-device value could therefore get +out of sync with the hardware per-context value. This meant that using +them is actually unsafe: a client which tried to use them could damage +the state of other clients, causing the GPU to interpret their BO +offsets as absolute pointers, leading to bogus memory reads. + +These flags were also never ported to execlist mode, making them no-ops +on Gen9+ (which requires execlists), and Gen8 in the default mode. + +On Gen8+, userspace can write these registers directly, achieving the +same effect. On Gen6-7.5, it likely makes sense to extend the command +parser to support them. I don't think anyone wants this on Gen4-5. + +Based on a patch by Dave Gordon. + +v3: Return -ENODEV for the getparam, as this is what we do for other + obsolete features. Suggested by Chris Wilson. + +Cc: stable@vger.kernel.org +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=92448 +Signed-off-by: Kenneth Graunke <kenneth@whitecape.org> +Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> +Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> +Link: http://patchwork.freedesktop.org/patch/msgid/20170215093446.21291-1-kenneth@whitecape.org +Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch> +Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> +Link: http://patchwork.freedesktop.org/patch/msgid/20170313170433.26843-1-chris@chris-wilson.co.uk +(cherry picked from commit ef0f411f51475f4eebf9fc1b19a85be698af19ff) +Signed-off-by: Jani Nikula <jani.nikula@intel.com> + +diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c +index 2093d203665d..6cd78bb2064d 100644 +--- a/drivers/gpu/drm/i915/i915_drv.c ++++ b/drivers/gpu/drm/i915/i915_drv.c +@@ -248,6 +248,7 @@ static int i915_getparam(struct drm_device *dev, void *data, + case I915_PARAM_IRQ_ACTIVE: + case I915_PARAM_ALLOW_BATCHBUFFER: + case I915_PARAM_LAST_DISPATCH: ++ case I915_PARAM_HAS_EXEC_CONSTANTS: + /* Reject all old ums/dri params. */ + return -ENODEV; + case I915_PARAM_CHIPSET_ID: +@@ -274,9 +275,6 @@ static int i915_getparam(struct drm_device *dev, void *data, + case I915_PARAM_HAS_BSD2: + value = !!dev_priv->engine[VCS2]; + break; +- case I915_PARAM_HAS_EXEC_CONSTANTS: +- value = INTEL_GEN(dev_priv) >= 4; +- break; + case I915_PARAM_HAS_LLC: + value = HAS_LLC(dev_priv); + break; +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 1d20c2d00f42..80be09831a52 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -2064,8 +2064,6 @@ struct drm_i915_private { + + const struct intel_device_info info; + +- int relative_constants_mode; +- + void __iomem *regs; + + struct intel_uncore uncore; +diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c +index 1051fdf37d20..67b1fc5a0331 100644 +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -4694,8 +4694,6 @@ i915_gem_load_init(struct drm_i915_private *dev_priv) + init_waitqueue_head(&dev_priv->gpu_error.wait_queue); + init_waitqueue_head(&dev_priv->gpu_error.reset_queue); + +- dev_priv->relative_constants_mode = I915_EXEC_CONSTANTS_REL_GENERAL; +- + init_waitqueue_head(&dev_priv->pending_flip_queue); + + dev_priv->mm.interruptible = true; +diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c +index d02cfaefe1c8..30e0675fd7da 100644 +--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c ++++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c +@@ -1408,10 +1408,7 @@ execbuf_submit(struct i915_execbuffer_params *params, + struct drm_i915_gem_execbuffer2 *args, + struct list_head *vmas) + { +- struct drm_i915_private *dev_priv = params->request->i915; + u64 exec_start, exec_len; +- int instp_mode; +- u32 instp_mask; + int ret; + + ret = i915_gem_execbuffer_move_to_gpu(params->request, vmas); +@@ -1422,56 +1419,11 @@ execbuf_submit(struct i915_execbuffer_params *params, + if (ret) + return ret; + +- instp_mode = args->flags & I915_EXEC_CONSTANTS_MASK; +- instp_mask = I915_EXEC_CONSTANTS_MASK; +- switch (instp_mode) { +- case I915_EXEC_CONSTANTS_REL_GENERAL: +- case I915_EXEC_CONSTANTS_ABSOLUTE: +- case I915_EXEC_CONSTANTS_REL_SURFACE: +- if (instp_mode != 0 && params->engine->id != RCS) { +- DRM_DEBUG("non-0 rel constants mode on non-RCS\n"); +- return -EINVAL; +- } +- +- if (instp_mode != dev_priv->relative_constants_mode) { +- if (INTEL_INFO(dev_priv)->gen < 4) { +- DRM_DEBUG("no rel constants on pre-gen4\n"); +- return -EINVAL; +- } +- +- if (INTEL_INFO(dev_priv)->gen > 5 && +- instp_mode == I915_EXEC_CONSTANTS_REL_SURFACE) { +- DRM_DEBUG("rel surface constants mode invalid on gen5+\n"); +- return -EINVAL; +- } +- +- /* The HW changed the meaning on this bit on gen6 */ +- if (INTEL_INFO(dev_priv)->gen >= 6) +- instp_mask &= ~I915_EXEC_CONSTANTS_REL_SURFACE; +- } +- break; +- default: +- DRM_DEBUG("execbuf with unknown constants: %d\n", instp_mode); ++ if (args->flags & I915_EXEC_CONSTANTS_MASK) { ++ DRM_DEBUG("I915_EXEC_CONSTANTS_* unsupported\n"); + return -EINVAL; + } + +- if (params->engine->id == RCS && +- instp_mode != dev_priv->relative_constants_mode) { +- struct intel_ring *ring = params->request->ring; +- +- ret = intel_ring_begin(params->request, 4); +- if (ret) +- return ret; +- +- intel_ring_emit(ring, MI_NOOP); +- intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1)); +- intel_ring_emit_reg(ring, INSTPM); +- intel_ring_emit(ring, instp_mask << 16 | instp_mode); +- intel_ring_advance(ring); +- +- dev_priv->relative_constants_mode = instp_mode; +- } +- + if (args->flags & I915_EXEC_GEN7_SOL_RESET) { + ret = i915_reset_gen7_sol_offsets(params->request); + if (ret) +-- +2.12.0 + diff --git a/queue/drm-i915-Nuke-debug-messages-from-the-pipe-update-cr.patch b/queue/drm-i915-Nuke-debug-messages-from-the-pipe-update-cr.patch new file mode 100644 index 0000000..2b39a2e --- /dev/null +++ b/queue/drm-i915-Nuke-debug-messages-from-the-pipe-update-cr.patch @@ -0,0 +1,73 @@ +From edd06b8353772dca7afcd4640dafa83b521edd55 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= <ville.syrjala@linux.intel.com> +Date: Tue, 7 Mar 2017 22:54:19 +0200 +Subject: [PATCH] drm/i915: Nuke debug messages from the pipe update critical + section +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit edd06b8353772dca7afcd4640dafa83b521edd55 upstream. + +printks are slow so we should not be doing them from the vblank evade +critical section. These could explain why we sometimes seem to +blow past our 100 usec deadline. + +The problem has been there ever since commit bfd16b2a23dc ("drm/i915: +Make updating pipe without modeset atomic.") but it may not have +been readily visible until commit e1edbd44e23b ("drm/i915: Complain +if we take too long under vblank evasion.") increased our chances +of noticing it. + +Cc: stable@vger.kernel.org +Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> +Fixes: bfd16b2a23dc ("drm/i915: Make updating pipe without modeset atomic.") +Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> +Link: http://patchwork.freedesktop.org/patch/msgid/20170307205419.19447-1-ville.syrjala@linux.intel.com +Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> +(cherry picked from commit c3f8ad57a01a31397e5a0349a226a32f35ddc19c) +Signed-off-by: Jani Nikula <jani.nikula@intel.com> + +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 9a8b6a13233d..b3e0cd133b49 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -3669,10 +3669,6 @@ static void intel_update_pipe_config(struct intel_crtc *crtc, + /* drm_atomic_helper_update_legacy_modeset_state might not be called. */ + crtc->base.mode = crtc->base.state->mode; + +- DRM_DEBUG_KMS("Updating pipe size %ix%i -> %ix%i\n", +- old_crtc_state->pipe_src_w, old_crtc_state->pipe_src_h, +- pipe_config->pipe_src_w, pipe_config->pipe_src_h); +- + /* + * Update pipe size and adjust fitter if needed: the reason for this is + * that in compute_mode_changes we check the native mode (not the pfit +@@ -4796,23 +4792,17 @@ static void skylake_pfit_enable(struct intel_crtc *crtc) + struct intel_crtc_scaler_state *scaler_state = + &crtc->config->scaler_state; + +- DRM_DEBUG_KMS("for crtc_state = %p\n", crtc->config); +- + if (crtc->config->pch_pfit.enabled) { + int id; + +- if (WARN_ON(crtc->config->scaler_state.scaler_id < 0)) { +- DRM_ERROR("Requesting pfit without getting a scaler first\n"); ++ if (WARN_ON(crtc->config->scaler_state.scaler_id < 0)) + return; +- } + + id = scaler_state->scaler_id; + I915_WRITE(SKL_PS_CTRL(pipe, id), PS_SCALER_EN | + PS_FILTER_MEDIUM | scaler_state->scalers[id].mode); + I915_WRITE(SKL_PS_WIN_POS(pipe, id), crtc->config->pch_pfit.pos); + I915_WRITE(SKL_PS_WIN_SZ(pipe, id), crtc->config->pch_pfit.size); +- +- DRM_DEBUG_KMS("for crtc_state = %p scaler_id = %d\n", crtc->config, id); + } + } + +-- +2.12.0 + diff --git a/queue/drm-i915-Only-enable-hotplug-interrupts-if-the-displ.patch b/queue/drm-i915-Only-enable-hotplug-interrupts-if-the-displ.patch new file mode 100644 index 0000000..6ba56e6 --- /dev/null +++ b/queue/drm-i915-Only-enable-hotplug-interrupts-if-the-displ.patch @@ -0,0 +1,142 @@ +From 35a3abfd198e6c69a6644784bb09a2d951fc6b21 Mon Sep 17 00:00:00 2001 +From: Chris Wilson <chris@chris-wilson.co.uk> +Date: Mon, 13 Mar 2017 17:02:31 +0000 +Subject: [PATCH] drm/i915: Only enable hotplug interrupts if the display + interrupts are enabled +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit 35a3abfd198e6c69a6644784bb09a2d951fc6b21 upstream. + +In order to prevent accessing the hpd registers outside of the display +power wells, we should refrain from writing to the registers before the +display interrupts are enabled. + +[ 4.740136] WARNING: CPU: 1 PID: 221 at drivers/gpu/drm/i915/intel_uncore.c:795 __unclaimed_reg_debug+0x44/0x50 [i915] +[ 4.740155] Unclaimed read from register 0x1e1110 +[ 4.740168] Modules linked in: i915(+) intel_gtt drm_kms_helper prime_numbers +[ 4.740190] CPU: 1 PID: 221 Comm: systemd-udevd Not tainted 4.10.0-rc6+ #384 +[ 4.740203] Hardware name: / , BIOS PYBSWCEL.86A.0027.2015.0507.1758 05/07/2015 +[ 4.740220] Call Trace: +[ 4.740236] dump_stack+0x4d/0x6f +[ 4.740251] __warn+0xc1/0xe0 +[ 4.740265] warn_slowpath_fmt+0x4a/0x50 +[ 4.740281] ? insert_work+0x77/0xc0 +[ 4.740355] ? fwtable_write32+0x90/0x130 [i915] +[ 4.740431] __unclaimed_reg_debug+0x44/0x50 [i915] +[ 4.740507] fwtable_read32+0xd8/0x130 [i915] +[ 4.740575] i915_hpd_irq_setup+0xa5/0x100 [i915] +[ 4.740649] intel_hpd_init+0x68/0x80 [i915] +[ 4.740716] i915_driver_load+0xe19/0x1380 [i915] +[ 4.740784] i915_pci_probe+0x32/0x90 [i915] +[ 4.740799] pci_device_probe+0x8b/0xf0 +[ 4.740815] driver_probe_device+0x2b6/0x450 +[ 4.740828] __driver_attach+0xda/0xe0 +[ 4.740841] ? driver_probe_device+0x450/0x450 +[ 4.740853] bus_for_each_dev+0x5b/0x90 +[ 4.740865] driver_attach+0x19/0x20 +[ 4.740878] bus_add_driver+0x166/0x260 +[ 4.740892] driver_register+0x5b/0xd0 +[ 4.740906] ? 0xffffffffa0166000 +[ 4.740920] __pci_register_driver+0x47/0x50 +[ 4.740985] i915_init+0x5c/0x5e [i915] +[ 4.740999] do_one_initcall+0x3e/0x160 +[ 4.741015] ? __vunmap+0x7c/0xc0 +[ 4.741029] ? kmem_cache_alloc+0xcf/0x120 +[ 4.741045] do_init_module+0x55/0x1c4 +[ 4.741060] load_module+0x1f3f/0x25b0 +[ 4.741073] ? __symbol_put+0x40/0x40 +[ 4.741086] ? kernel_read_file+0x100/0x190 +[ 4.741100] SYSC_finit_module+0xbc/0xf0 +[ 4.741112] SyS_finit_module+0x9/0x10 +[ 4.741125] entry_SYSCALL_64_fastpath+0x17/0x98 +[ 4.741135] RIP: 0033:0x7f8559a140f9 +[ 4.741145] RSP: 002b:00007fff7509a3e8 EFLAGS: 00000246 ORIG_RAX: 0000000000000139 +[ 4.741161] RAX: ffffffffffffffda RBX: 00007f855aba02d1 RCX: 00007f8559a140f9 +[ 4.741172] RDX: 0000000000000000 RSI: 000055b6db0914f0 RDI: 0000000000000011 +[ 4.741183] RBP: 0000000000020000 R08: 0000000000000000 R09: 000000000000000e +[ 4.741193] R10: 0000000000000011 R11: 0000000000000246 R12: 000055b6db0854d0 +[ 4.741204] R13: 000055b6db091150 R14: 0000000000000000 R15: 000055b6db035924 + +v2: Set dev_priv->display_irqs_enabled to true for all platforms other +than vlv/chv that manually control the display power domain. + +Fixes: 19625e85c6ec ("drm/i915: Enable polling when we don't have hpd") +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=97798 +Suggested-by: Ville Syrjälä <ville.syrjala@linux.intel.com> +Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> +Cc: Lyude <cpaul@redhat.com> +Cc: Daniel Vetter <daniel.vetter@ffwll.ch> +Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> +Cc: Hans de Goede <jwrdegoede@fedoraproject.org> +Cc: stable@vger.kernel.org +Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> +Link: http://patchwork.freedesktop.org/patch/msgid/20170215131547.5064-1-chris@chris-wilson.co.uk +Link: http://patchwork.freedesktop.org/patch/msgid/20170313170231.18633-1-chris@chris-wilson.co.uk +(cherry picked from commit 262fd485ac6b476479f41f00bb104f6a1766ae66) +Signed-off-by: Jani Nikula <jani.nikula@intel.com> + +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index e6ffef2f707a..4fc8973744b4 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -4266,6 +4266,16 @@ void intel_irq_init(struct drm_i915_private *dev_priv) + if (!IS_GEN2(dev_priv)) + dev->vblank_disable_immediate = true; + ++ /* Most platforms treat the display irq block as an always-on ++ * power domain. vlv/chv can disable it at runtime and need ++ * special care to avoid writing any of the display block registers ++ * outside of the power domain. We defer setting up the display irqs ++ * in this case to the runtime pm. ++ */ ++ dev_priv->display_irqs_enabled = true; ++ if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) ++ dev_priv->display_irqs_enabled = false; ++ + dev->driver->get_vblank_timestamp = i915_get_vblank_timestamp; + dev->driver->get_scanout_position = i915_get_crtc_scanoutpos; + +diff --git a/drivers/gpu/drm/i915/intel_hotplug.c b/drivers/gpu/drm/i915/intel_hotplug.c +index b62e3f8ad415..54208bef7a83 100644 +--- a/drivers/gpu/drm/i915/intel_hotplug.c ++++ b/drivers/gpu/drm/i915/intel_hotplug.c +@@ -219,7 +219,7 @@ static void intel_hpd_irq_storm_reenable_work(struct work_struct *work) + } + } + } +- if (dev_priv->display.hpd_irq_setup) ++ if (dev_priv->display_irqs_enabled && dev_priv->display.hpd_irq_setup) + dev_priv->display.hpd_irq_setup(dev_priv); + spin_unlock_irq(&dev_priv->irq_lock); + +@@ -425,7 +425,7 @@ void intel_hpd_irq_handler(struct drm_i915_private *dev_priv, + } + } + +- if (storm_detected) ++ if (storm_detected && dev_priv->display_irqs_enabled) + dev_priv->display.hpd_irq_setup(dev_priv); + spin_unlock(&dev_priv->irq_lock); + +@@ -471,10 +471,12 @@ void intel_hpd_init(struct drm_i915_private *dev_priv) + * Interrupt setup is already guaranteed to be single-threaded, this is + * just to make the assert_spin_locked checks happy. + */ +- spin_lock_irq(&dev_priv->irq_lock); +- if (dev_priv->display.hpd_irq_setup) +- dev_priv->display.hpd_irq_setup(dev_priv); +- spin_unlock_irq(&dev_priv->irq_lock); ++ if (dev_priv->display_irqs_enabled && dev_priv->display.hpd_irq_setup) { ++ spin_lock_irq(&dev_priv->irq_lock); ++ if (dev_priv->display_irqs_enabled) ++ dev_priv->display.hpd_irq_setup(dev_priv); ++ spin_unlock_irq(&dev_priv->irq_lock); ++ } + } + + static void i915_hpd_poll_init_work(struct work_struct *work) +-- +2.12.0 + diff --git a/queue/drm-i915-Stop-using-RP_DOWN_EI-on-Baytrail.patch b/queue/drm-i915-Stop-using-RP_DOWN_EI-on-Baytrail.patch new file mode 100644 index 0000000..2c2d067 --- /dev/null +++ b/queue/drm-i915-Stop-using-RP_DOWN_EI-on-Baytrail.patch @@ -0,0 +1,178 @@ +From 8f68d591d4765b2e1ce9d916ac7bc5583285c4ad Mon Sep 17 00:00:00 2001 +From: Chris Wilson <chris@chris-wilson.co.uk> +Date: Mon, 13 Mar 2017 17:06:17 +0000 +Subject: [PATCH] drm/i915: Stop using RP_DOWN_EI on Baytrail + +commit 8f68d591d4765b2e1ce9d916ac7bc5583285c4ad upstream. + +On Baytrail, we manually calculate busyness over the evaluation interval +to avoid issues with miscaluations with RC6 enabled. However, it turns +out that the DOWN_EI interrupt generator is completely bust - it +operates in two modes, continuous or never. Neither of which are +conducive to good behaviour. Stop unmask the DOWN_EI interrupt and just +compute everything from the UP_EI which does seem to correspond to the +desired interval. + +v2: Fixup gen6_rps_pm_mask() as well +v3: Inline vlv_c0_above() to combine the now identical elapsed +calculation for up/down and simplify the threshold testing + +Fixes: 43cf3bf084ba ("drm/i915: Improved w/a for rps on Baytrail") +Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> +Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com> +Cc: <stable@vger.kernel.org> # v4.1+ +Link: http://patchwork.freedesktop.org/patch/msgid/20170309211232.28878-1-chris@chris-wilson.co.uk +Reviewed-by: Mika Kuoppala <mika.kuoppala@linux.intel.com> +Link: http://patchwork.freedesktop.org/patch/msgid/20170313170617.31564-1-chris@chris-wilson.co.uk +(cherry picked from commit e0e8c7cb6eb68e9256de2d8cbeb481d3701c05ac) +Signed-off-by: Jani Nikula <jani.nikula@intel.com> + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index 80be09831a52..1e53c31b6826 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -1325,7 +1325,7 @@ struct intel_gen6_power_mgmt { + unsigned boosts; + + /* manual wa residency calculations */ +- struct intel_rps_ei up_ei, down_ei; ++ struct intel_rps_ei ei; + + /* + * Protects RPS/RC6 register access and PCU communication. +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index 4fc8973744b4..b6c886ac901b 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -1046,68 +1046,51 @@ static void vlv_c0_read(struct drm_i915_private *dev_priv, + ei->media_c0 = I915_READ(VLV_MEDIA_C0_COUNT); + } + +-static bool vlv_c0_above(struct drm_i915_private *dev_priv, +- const struct intel_rps_ei *old, +- const struct intel_rps_ei *now, +- int threshold) +-{ +- u64 time, c0; +- unsigned int mul = 100; +- +- if (old->cz_clock == 0) +- return false; +- +- if (I915_READ(VLV_COUNTER_CONTROL) & VLV_COUNT_RANGE_HIGH) +- mul <<= 8; +- +- time = now->cz_clock - old->cz_clock; +- time *= threshold * dev_priv->czclk_freq; +- +- /* Workload can be split between render + media, e.g. SwapBuffers +- * being blitted in X after being rendered in mesa. To account for +- * this we need to combine both engines into our activity counter. +- */ +- c0 = now->render_c0 - old->render_c0; +- c0 += now->media_c0 - old->media_c0; +- c0 *= mul * VLV_CZ_CLOCK_TO_MILLI_SEC; +- +- return c0 >= time; +-} +- + void gen6_rps_reset_ei(struct drm_i915_private *dev_priv) + { +- vlv_c0_read(dev_priv, &dev_priv->rps.down_ei); +- dev_priv->rps.up_ei = dev_priv->rps.down_ei; ++ memset(&dev_priv->rps.ei, 0, sizeof(dev_priv->rps.ei)); + } + + static u32 vlv_wa_c0_ei(struct drm_i915_private *dev_priv, u32 pm_iir) + { ++ const struct intel_rps_ei *prev = &dev_priv->rps.ei; + struct intel_rps_ei now; + u32 events = 0; + +- if ((pm_iir & (GEN6_PM_RP_DOWN_EI_EXPIRED | GEN6_PM_RP_UP_EI_EXPIRED)) == 0) ++ if ((pm_iir & GEN6_PM_RP_UP_EI_EXPIRED) == 0) + return 0; + + vlv_c0_read(dev_priv, &now); + if (now.cz_clock == 0) + return 0; + +- if (pm_iir & GEN6_PM_RP_DOWN_EI_EXPIRED) { +- if (!vlv_c0_above(dev_priv, +- &dev_priv->rps.down_ei, &now, +- dev_priv->rps.down_threshold)) +- events |= GEN6_PM_RP_DOWN_THRESHOLD; +- dev_priv->rps.down_ei = now; +- } ++ if (prev->cz_clock) { ++ u64 time, c0; ++ unsigned int mul; + +- if (pm_iir & GEN6_PM_RP_UP_EI_EXPIRED) { +- if (vlv_c0_above(dev_priv, +- &dev_priv->rps.up_ei, &now, +- dev_priv->rps.up_threshold)) +- events |= GEN6_PM_RP_UP_THRESHOLD; +- dev_priv->rps.up_ei = now; ++ mul = VLV_CZ_CLOCK_TO_MILLI_SEC * 100; /* scale to threshold% */ ++ if (I915_READ(VLV_COUNTER_CONTROL) & VLV_COUNT_RANGE_HIGH) ++ mul <<= 8; ++ ++ time = now.cz_clock - prev->cz_clock; ++ time *= dev_priv->czclk_freq; ++ ++ /* Workload can be split between render + media, ++ * e.g. SwapBuffers being blitted in X after being rendered in ++ * mesa. To account for this we need to combine both engines ++ * into our activity counter. ++ */ ++ c0 = now.render_c0 - prev->render_c0; ++ c0 += now.media_c0 - prev->media_c0; ++ c0 *= mul; ++ ++ if (c0 > time * dev_priv->rps.up_threshold) ++ events = GEN6_PM_RP_UP_THRESHOLD; ++ else if (c0 < time * dev_priv->rps.down_threshold) ++ events = GEN6_PM_RP_DOWN_THRESHOLD; + } + ++ dev_priv->rps.ei = now; + return events; + } + +@@ -4228,7 +4211,7 @@ void intel_irq_init(struct drm_i915_private *dev_priv) + /* Let's track the enabled rps events */ + if (IS_VALLEYVIEW(dev_priv)) + /* WaGsvRC0ResidencyMethod:vlv */ +- dev_priv->pm_rps_events = GEN6_PM_RP_DOWN_EI_EXPIRED | GEN6_PM_RP_UP_EI_EXPIRED; ++ dev_priv->pm_rps_events = GEN6_PM_RP_UP_EI_EXPIRED; + else + dev_priv->pm_rps_events = GEN6_PM_RPS_EVENTS; + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 940bab22d464..6a29784d2b41 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -4928,8 +4928,9 @@ static u32 gen6_rps_pm_mask(struct drm_i915_private *dev_priv, u8 val) + { + u32 mask = 0; + ++ /* We use UP_EI_EXPIRED interupts for both up/down in manual mode */ + if (val > dev_priv->rps.min_freq_softlimit) +- mask |= GEN6_PM_RP_DOWN_EI_EXPIRED | GEN6_PM_RP_DOWN_THRESHOLD | GEN6_PM_RP_DOWN_TIMEOUT; ++ mask |= GEN6_PM_RP_UP_EI_EXPIRED | GEN6_PM_RP_DOWN_THRESHOLD | GEN6_PM_RP_DOWN_TIMEOUT; + if (val < dev_priv->rps.max_freq_softlimit) + mask |= GEN6_PM_RP_UP_EI_EXPIRED | GEN6_PM_RP_UP_THRESHOLD; + +@@ -5039,7 +5040,7 @@ void gen6_rps_busy(struct drm_i915_private *dev_priv) + { + mutex_lock(&dev_priv->rps.hw_lock); + if (dev_priv->rps.enabled) { +- if (dev_priv->pm_rps_events & (GEN6_PM_RP_DOWN_EI_EXPIRED | GEN6_PM_RP_UP_EI_EXPIRED)) ++ if (dev_priv->pm_rps_events & GEN6_PM_RP_UP_EI_EXPIRED) + gen6_rps_reset_ei(dev_priv); + I915_WRITE(GEN6_PMINTRMSK, + gen6_rps_pm_mask(dev_priv, dev_priv->rps.cur_freq)); +-- +2.12.0 + diff --git a/queue/drm-i915-actually-drive-the-BDW-reserved-IDs.patch b/queue/drm-i915-actually-drive-the-BDW-reserved-IDs.patch new file mode 100644 index 0000000..a7b1096 --- /dev/null +++ b/queue/drm-i915-actually-drive-the-BDW-reserved-IDs.patch @@ -0,0 +1,56 @@ +From 98b2f01c8dfc8922a2af1fe82a1c40cac4911634 Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni <paulo.r.zanoni@intel.com> +Date: Tue, 3 Jan 2017 18:04:20 -0200 +Subject: [PATCH] drm/i915: actually drive the BDW reserved IDs + +commit 98b2f01c8dfc8922a2af1fe82a1c40cac4911634 upstream. + +Back in 2014, commit fb7023e0e248 ("drm/i915: BDW: Adding Reserved PCI +IDs.") added the reserved PCI IDs in order to try to make sure we had +working drivers in case we ever released products using these IDs +(since we had instances of this type of problem in the past). The +problem is that the patch only touched the macros used by +early-quirks.c and by the user space components that rely on +i915_pciids.h, it didn't touch the macros used by i915_pci.c. So we +correctly handled the stolen memory for these theoretical IDs, but we +didn't actually drive the devices from i915.ko. + +So this patch fixes the original commit by actually making i915.ko +drive these IDs, which was the goal. There's no information on what +would be the GT count on these IDs, so we just go with the safer +intel_broadwell_info, at the risk of ignoring a possibly inexistent +BSD2_RING. + +I did some checking, and it seems that these IDs are driven by +intel-gpu-tools, xf86-video-intel and libdrm (since they contain old +copies of i915_pciids.h), but they are not checked by mesa. + +The alternative to this patch would be to just assume we're actually +never going to use these IDs, and then remove them from our ID lists +and make sure our user space components sync the latest i915_pciids.h +copy. I'm fine with either approaches, as long as we make sure that +every component tries to drive the same list of PCI IDs. + +Fixes: fb7023e0e248 ("drm/i915: BDW: Adding Reserved PCI IDs.") +Cc: Rodrigo Vivi <rodrigo.vivi@intel.com> +Cc: Ben Widawsky <ben@bwidawsk.net> +Cc: Jani Nikula <jani.nikula@intel.com> +Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com> +Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> +Link: http://patchwork.freedesktop.org/patch/msgid/1483473860-17644-3-git-send-email-paulo.r.zanoni@intel.com + +diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c +index 7435a73f6bc6..ecb487b5356f 100644 +--- a/drivers/gpu/drm/i915/i915_pci.c ++++ b/drivers/gpu/drm/i915/i915_pci.c +@@ -456,6 +456,7 @@ static const struct pci_device_id pciidlist[] = { + INTEL_VLV_IDS(&intel_valleyview_info), + INTEL_BDW_GT12_IDS(&intel_broadwell_info), + INTEL_BDW_GT3_IDS(&intel_broadwell_gt3_info), ++ INTEL_BDW_RSVD_IDS(&intel_broadwell_info), + INTEL_CHV_IDS(&intel_cherryview_info), + INTEL_SKL_GT1_IDS(&intel_skylake_info), + INTEL_SKL_GT2_IDS(&intel_skylake_info), +-- +2.12.0 + diff --git a/queue/drm-i915-execlists-Reset-RING-registers-upon-resume.patch b/queue/drm-i915-execlists-Reset-RING-registers-upon-resume.patch new file mode 100644 index 0000000..7e15613 --- /dev/null +++ b/queue/drm-i915-execlists-Reset-RING-registers-upon-resume.patch @@ -0,0 +1,92 @@ +From bafb2f7d4755bf1571bd5e9a03b97f3fc4fe69ae Mon Sep 17 00:00:00 2001 +From: Chris Wilson <chris@chris-wilson.co.uk> +Date: Wed, 21 Sep 2016 14:51:08 +0100 +Subject: [PATCH] drm/i915/execlists: Reset RING registers upon resume + +commit bafb2f7d4755bf1571bd5e9a03b97f3fc4fe69ae upstream. + +There is a disparity in the context image saved to disk and our own +bookkeeping - that is we presume the RING_HEAD and RING_TAIL match our +stored ce->ring->tail value. However, as we emit WA_TAIL_DWORDS into the +ring but may not tell the GPU about them, the GPU may be lagging behind +our bookkeeping. Upon hibernation we do not save stolen pages, presuming +that their contents are volatile. This means that although we start +writing into the ring at tail, the GPU starts executing from its HEAD +and there may be some garbage in between and so the GPU promptly hangs +upon resume. + +Testcase: igt/gem_exec_suspend/basic-S4 +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=96526 +Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> +Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> +Link: http://patchwork.freedesktop.org/patch/msgid/20160921135108.29574-3-chris@chris-wilson.co.uk + +diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c +index 251143361f31..39417b77bff2 100644 +--- a/drivers/gpu/drm/i915/intel_lrc.c ++++ b/drivers/gpu/drm/i915/intel_lrc.c +@@ -2129,30 +2129,42 @@ error_deref_obj: + + void intel_lr_context_resume(struct drm_i915_private *dev_priv) + { +- struct i915_gem_context *ctx = dev_priv->kernel_context; + struct intel_engine_cs *engine; ++ struct i915_gem_context *ctx; ++ ++ /* Because we emit WA_TAIL_DWORDS there may be a disparity ++ * between our bookkeeping in ce->ring->head and ce->ring->tail and ++ * that stored in context. As we only write new commands from ++ * ce->ring->tail onwards, everything before that is junk. If the GPU ++ * starts reading from its RING_HEAD from the context, it may try to ++ * execute that junk and die. ++ * ++ * So to avoid that we reset the context images upon resume. For ++ * simplicity, we just zero everything out. ++ */ ++ list_for_each_entry(ctx, &dev_priv->context_list, link) { ++ for_each_engine(engine, dev_priv) { ++ struct intel_context *ce = &ctx->engine[engine->id]; ++ u32 *reg; + +- for_each_engine(engine, dev_priv) { +- struct intel_context *ce = &ctx->engine[engine->id]; +- void *vaddr; +- uint32_t *reg_state; +- +- if (!ce->state) +- continue; +- +- vaddr = i915_gem_object_pin_map(ce->state->obj, I915_MAP_WB); +- if (WARN_ON(IS_ERR(vaddr))) +- continue; ++ if (!ce->state) ++ continue; + +- reg_state = vaddr + LRC_STATE_PN * PAGE_SIZE; ++ reg = i915_gem_object_pin_map(ce->state->obj, ++ I915_MAP_WB); ++ if (WARN_ON(IS_ERR(reg))) ++ continue; + +- reg_state[CTX_RING_HEAD+1] = 0; +- reg_state[CTX_RING_TAIL+1] = 0; ++ reg += LRC_STATE_PN * PAGE_SIZE / sizeof(*reg); ++ reg[CTX_RING_HEAD+1] = 0; ++ reg[CTX_RING_TAIL+1] = 0; + +- ce->state->obj->dirty = true; +- i915_gem_object_unpin_map(ce->state->obj); ++ ce->state->obj->dirty = true; ++ i915_gem_object_unpin_map(ce->state->obj); + +- ce->ring->head = 0; +- ce->ring->tail = 0; ++ ce->ring->head = ce->ring->tail = 0; ++ ce->ring->last_retired_head = -1; ++ intel_ring_update_space(ce->ring); ++ } + } + } +-- +2.12.0 + diff --git a/queue/drm-i915-fix-INTEL_BDW_IDS-definition.patch b/queue/drm-i915-fix-INTEL_BDW_IDS-definition.patch new file mode 100644 index 0000000..621688f --- /dev/null +++ b/queue/drm-i915-fix-INTEL_BDW_IDS-definition.patch @@ -0,0 +1,34 @@ +From 7fbd995ce4241e98d30859405504c3fb279c4ccb Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni <paulo.r.zanoni@intel.com> +Date: Tue, 3 Jan 2017 18:04:18 -0200 +Subject: [PATCH] drm/i915: fix INTEL_BDW_IDS definition + +commit 7fbd995ce4241e98d30859405504c3fb279c4ccb upstream. + +Remove duplicated IDs from the list. Currently, this definition is +only used by early-quirks.c. From my understanding of the code, having +duplicated IDs shouldn't be causing any bugs. + +Fixes: 8d9c20e1d1e3 ("drm/i915: Remove .is_mobile field from platform struct") +Cc: Carlos Santa <carlos.santa@intel.com> +Cc: Rodrigo Vivi <rodrigo.vivi@intel.com> +Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com> +Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> +Link: http://patchwork.freedesktop.org/patch/msgid/1483473860-17644-1-git-send-email-paulo.r.zanoni@intel.com + +diff --git a/include/drm/i915_pciids.h b/include/drm/i915_pciids.h +index aeb36cb0854f..6588dd1d88c5 100644 +--- a/include/drm/i915_pciids.h ++++ b/include/drm/i915_pciids.h +@@ -240,8 +240,6 @@ + INTEL_BDW_GT12_IDS(info), \ + INTEL_BDW_GT3_IDS(info), \ + INTEL_BDW_RSVDM_IDS(info), \ +- INTEL_BDW_GT12_IDS(info), \ +- INTEL_BDW_GT3_IDS(info), \ + INTEL_BDW_RSVDD_IDS(info) + + #define INTEL_CHV_IDS(info) \ +-- +2.12.0 + diff --git a/queue/drm-i915-gen9-Increase-PCODE-request-timeout-to-50ms.patch b/queue/drm-i915-gen9-Increase-PCODE-request-timeout-to-50ms.patch new file mode 100644 index 0000000..202b650 --- /dev/null +++ b/queue/drm-i915-gen9-Increase-PCODE-request-timeout-to-50ms.patch @@ -0,0 +1,75 @@ +From d253371c4c2f5fc2d884ef25f64decd7549aff5a Mon Sep 17 00:00:00 2001 +From: Imre Deak <imre.deak@intel.com> +Date: Fri, 24 Feb 2017 16:32:10 +0200 +Subject: [PATCH] drm/i915/gen9: Increase PCODE request timeout to 50ms +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit d253371c4c2f5fc2d884ef25f64decd7549aff5a upstream. + +After +commit 2c7d0602c815277f7cb7c932b091288710d8aba7 +Author: Imre Deak <imre.deak@intel.com> +Date: Mon Dec 5 18:27:37 2016 +0200 + + drm/i915/gen9: Fix PCODE polling during CDCLK change notification + +there is still one report of the CDCLK-change request timing out on a +KBL machine, see the Reference link. On that machine the maximum time +the request took to succeed was 34ms, so increase the timeout to 50ms. + +v2: +- Change timeout from 100 to 50 ms to maintain the current 50 ms limit + for atomic waits in the driver. (Chris, Tvrtko) + +Reference: https://bugs.freedesktop.org/show_bug.cgi?id=99345 +Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> +Cc: Chris Wilson <chris@chris-wilson.co.uk> +Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com> +Cc: <stable@vger.kernel.org> +Signed-off-by: Imre Deak <imre.deak@intel.com> +Acked-by: Chris Wilson <chris@chris-wilson.co.uk> +Link: http://patchwork.freedesktop.org/patch/msgid/1487946730-17162-1-git-send-email-imre.deak@intel.com +(cherry picked from commit 0129936ddda26afd5d9d207c4e86b2425952579f) +Signed-off-by: Jani Nikula <jani.nikula@intel.com> + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 65cd4c56c9dd..940bab22d464 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -7923,10 +7923,10 @@ static bool skl_pcode_try_request(struct drm_i915_private *dev_priv, u32 mbox, + * @timeout_base_ms: timeout for polling with preemption enabled + * + * Keep resending the @request to @mbox until PCODE acknowledges it, PCODE +- * reports an error or an overall timeout of @timeout_base_ms+10 ms expires. ++ * reports an error or an overall timeout of @timeout_base_ms+50 ms expires. + * The request is acknowledged once the PCODE reply dword equals @reply after + * applying @reply_mask. Polling is first attempted with preemption enabled +- * for @timeout_base_ms and if this times out for another 10 ms with ++ * for @timeout_base_ms and if this times out for another 50 ms with + * preemption disabled. + * + * Returns 0 on success, %-ETIMEDOUT in case of a timeout, <0 in case of some +@@ -7962,14 +7962,15 @@ int skl_pcode_request(struct drm_i915_private *dev_priv, u32 mbox, u32 request, + * worst case) _and_ PCODE was busy for some reason even after a + * (queued) request and @timeout_base_ms delay. As a workaround retry + * the poll with preemption disabled to maximize the number of +- * requests. Increase the timeout from @timeout_base_ms to 10ms to ++ * requests. Increase the timeout from @timeout_base_ms to 50ms to + * account for interrupts that could reduce the number of these +- * requests. ++ * requests, and for any quirks of the PCODE firmware that delays ++ * the request completion. + */ + DRM_DEBUG_KMS("PCODE timeout, retrying with preemption disabled\n"); + WARN_ON_ONCE(timeout_base_ms > 3); + preempt_disable(); +- ret = wait_for_atomic(COND, 10); ++ ret = wait_for_atomic(COND, 50); + preempt_enable(); + + out: +-- +2.12.0 + diff --git a/queue/drm-i915-more-.is_mobile-cleanups-for-BDW.patch b/queue/drm-i915-more-.is_mobile-cleanups-for-BDW.patch new file mode 100644 index 0000000..d5a2004 --- /dev/null +++ b/queue/drm-i915-more-.is_mobile-cleanups-for-BDW.patch @@ -0,0 +1,52 @@ +From 0784bc624ae9be4269f8129572ee164ca680ca7c Mon Sep 17 00:00:00 2001 +From: Paulo Zanoni <paulo.r.zanoni@intel.com> +Date: Tue, 3 Jan 2017 18:04:19 -0200 +Subject: [PATCH] drm/i915: more .is_mobile cleanups for BDW + +commit 0784bc624ae9be4269f8129572ee164ca680ca7c upstream. + +Commit 8d9c20e1d1e3 ("drm/i915: Remove .is_mobile field from platform +struct") removed mobile vs desktop differences for HSW+, but forgot +the Broadwell reserved IDs, so do it now. + +It's interesting to notice that these IDs are used by early-quirks.c +but are *not* used by i915_pci.c. + +Cc: Carlos Santa <carlos.santa@intel.com> +Cc: Rodrigo Vivi <rodrigo.vivi@intel.com> +Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com> +Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> +Link: http://patchwork.freedesktop.org/patch/msgid/1483473860-17644-2-git-send-email-paulo.r.zanoni@intel.com + +diff --git a/include/drm/i915_pciids.h b/include/drm/i915_pciids.h +index 6588dd1d88c5..a1dd21d6b723 100644 +--- a/include/drm/i915_pciids.h ++++ b/include/drm/i915_pciids.h +@@ -226,21 +226,18 @@ + INTEL_VGA_DEVICE(0x162A, info), /* Server */ \ + INTEL_VGA_DEVICE(0x162D, info) /* Workstation */ + +-#define INTEL_BDW_RSVDM_IDS(info) \ ++#define INTEL_BDW_RSVD_IDS(info) \ + INTEL_VGA_DEVICE(0x1632, info), /* ULT */ \ + INTEL_VGA_DEVICE(0x1636, info), /* ULT */ \ + INTEL_VGA_DEVICE(0x163B, info), /* Iris */ \ +- INTEL_VGA_DEVICE(0x163E, info) /* ULX */ +- +-#define INTEL_BDW_RSVDD_IDS(info) \ ++ INTEL_VGA_DEVICE(0x163E, info), /* ULX */ \ + INTEL_VGA_DEVICE(0x163A, info), /* Server */ \ + INTEL_VGA_DEVICE(0x163D, info) /* Workstation */ + + #define INTEL_BDW_IDS(info) \ + INTEL_BDW_GT12_IDS(info), \ + INTEL_BDW_GT3_IDS(info), \ +- INTEL_BDW_RSVDM_IDS(info), \ +- INTEL_BDW_RSVDD_IDS(info) ++ INTEL_BDW_RSVD_IDS(info) + + #define INTEL_CHV_IDS(info) \ + INTEL_VGA_DEVICE(0x22b0, info), \ +-- +2.12.0 + diff --git a/queue/drm-mga-remove-device_is_agp-callback.patch b/queue/drm-mga-remove-device_is_agp-callback.patch new file mode 100644 index 0000000..7fec56e --- /dev/null +++ b/queue/drm-mga-remove-device_is_agp-callback.patch @@ -0,0 +1,114 @@ +From 858b2c1bf820ebfba89c5e2867ab882bdb5b2f5a Mon Sep 17 00:00:00 2001 +From: Daniel Vetter <daniel.vetter@ffwll.ch> +Date: Wed, 25 Jan 2017 07:26:51 +0100 +Subject: [PATCH] drm/mga: remove device_is_agp callback + +commit 858b2c1bf820ebfba89c5e2867ab882bdb5b2f5a upstream. + +It's only for a device quirk, and we might as well do that in the load +callback. + +Acked-by: Alex Deucher <alexander.deucher@amd.com> +Signed-off-by: Daniel Vetter <daniel.vetter@intel.com> +Link: http://patchwork.freedesktop.org/patch/msgid/20170125062657.19270-10-daniel.vetter@ffwll.ch + +diff --git a/drivers/gpu/drm/mga/mga_dma.c b/drivers/gpu/drm/mga/mga_dma.c +index a1d8dd15b131..1ffdafea27e4 100644 +--- a/drivers/gpu/drm/mga/mga_dma.c ++++ b/drivers/gpu/drm/mga/mga_dma.c +@@ -392,6 +392,24 @@ int mga_driver_load(struct drm_device *dev, unsigned long flags) + drm_mga_private_t *dev_priv; + int ret; + ++ /* There are PCI versions of the G450. These cards have the ++ * same PCI ID as the AGP G450, but have an additional PCI-to-PCI ++ * bridge chip. We detect these cards, which are not currently ++ * supported by this driver, by looking at the device ID of the ++ * bus the "card" is on. If vendor is 0x3388 (Hint Corp) and the ++ * device is 0x0021 (HB6 Universal PCI-PCI bridge), we reject the ++ * device. ++ */ ++ if ((dev->pdev->device == 0x0525) && dev->pdev->bus->self ++ && (dev->pdev->bus->self->vendor == 0x3388) ++ && (dev->pdev->bus->self->device == 0x0021) ++ && dev->agp) { ++ /* FIXME: This should be quirked in the pci core, but oh well ++ * the hw probably stopped existing. */ ++ arch_phys_wc_del(dev->agp->agp_mtrr); ++ kfree(dev->agp); ++ dev->agp = NULL; ++ } + dev_priv = kzalloc(sizeof(drm_mga_private_t), GFP_KERNEL); + if (!dev_priv) + return -ENOMEM; +@@ -698,7 +716,7 @@ static int mga_do_pci_dma_bootstrap(struct drm_device *dev, + static int mga_do_dma_bootstrap(struct drm_device *dev, + drm_mga_dma_bootstrap_t *dma_bs) + { +- const int is_agp = (dma_bs->agp_mode != 0) && drm_pci_device_is_agp(dev); ++ const int is_agp = (dma_bs->agp_mode != 0) && dev->agp; + int err; + drm_mga_private_t *const dev_priv = + (drm_mga_private_t *) dev->dev_private; +diff --git a/drivers/gpu/drm/mga/mga_drv.c b/drivers/gpu/drm/mga/mga_drv.c +index 25b2a1a424e6..63ba0699d107 100644 +--- a/drivers/gpu/drm/mga/mga_drv.c ++++ b/drivers/gpu/drm/mga/mga_drv.c +@@ -37,8 +37,6 @@ + + #include <drm/drm_pciids.h> + +-static int mga_driver_device_is_agp(struct drm_device *dev); +- + static struct pci_device_id pciidlist[] = { + mga_PCI_IDS + }; +@@ -66,7 +64,6 @@ static struct drm_driver driver = { + .lastclose = mga_driver_lastclose, + .set_busid = drm_pci_set_busid, + .dma_quiescent = mga_driver_dma_quiescent, +- .device_is_agp = mga_driver_device_is_agp, + .get_vblank_counter = mga_get_vblank_counter, + .enable_vblank = mga_enable_vblank, + .disable_vblank = mga_disable_vblank, +@@ -107,37 +104,3 @@ module_exit(mga_exit); + MODULE_AUTHOR(DRIVER_AUTHOR); + MODULE_DESCRIPTION(DRIVER_DESC); + MODULE_LICENSE("GPL and additional rights"); +- +-/** +- * Determine if the device really is AGP or not. +- * +- * In addition to the usual tests performed by \c drm_device_is_agp, this +- * function detects PCI G450 cards that appear to the system exactly like +- * AGP G450 cards. +- * +- * \param dev The device to be tested. +- * +- * \returns +- * If the device is a PCI G450, zero is returned. Otherwise 2 is returned. +- */ +-static int mga_driver_device_is_agp(struct drm_device *dev) +-{ +- const struct pci_dev *const pdev = dev->pdev; +- +- /* There are PCI versions of the G450. These cards have the +- * same PCI ID as the AGP G450, but have an additional PCI-to-PCI +- * bridge chip. We detect these cards, which are not currently +- * supported by this driver, by looking at the device ID of the +- * bus the "card" is on. If vendor is 0x3388 (Hint Corp) and the +- * device is 0x0021 (HB6 Universal PCI-PCI bridge), we reject the +- * device. +- */ +- +- if ((pdev->device == 0x0525) && pdev->bus->self +- && (pdev->bus->self->vendor == 0x3388) +- && (pdev->bus->self->device == 0x0021)) { +- return 0; +- } +- +- return 2; +-} +-- +2.12.0 + diff --git a/queue/drm-msm-adreno-move-function-declarations-to-header-.patch b/queue/drm-msm-adreno-move-function-declarations-to-header-.patch new file mode 100644 index 0000000..6ff1232 --- /dev/null +++ b/queue/drm-msm-adreno-move-function-declarations-to-header-.patch @@ -0,0 +1,50 @@ +From a5725ab0497ad91a2df7c01a78bf1a0cc5be4526 Mon Sep 17 00:00:00 2001 +From: Baoyou Xie <baoyou.xie@linaro.org> +Date: Sat, 22 Oct 2016 17:17:44 +0800 +Subject: [PATCH] drm/msm/adreno: move function declarations to header file + +commit a5725ab0497ad91a2df7c01a78bf1a0cc5be4526 upstream. + +We get 2 warnings when building kernel with W=1: +drivers/gpu/drm/msm/adreno/a3xx_gpu.c:535:17: warning: no previous prototype for 'a3xx_gpu_init' [-Wmissing-prototypes] +drivers/gpu/drm/msm/adreno/a4xx_gpu.c:624:17: warning: no previous prototype for 'a4xx_gpu_init' [-Wmissing-prototypes] + +In fact, both functions are declared in +drivers/gpu/drm/msm/adreno/adreno_device.c, but should be declared +in a header file. So this patch moves both function declarations to +drivers/gpu/drm/msm/adreno/adreno_gpu.h. + +Signed-off-by: Baoyou Xie <baoyou.xie@linaro.org> +Reviewed-by: Arnd Bergmann <arnd@arndb.de> +Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> +Link: http://patchwork.freedesktop.org/patch/msgid/1477127865-9381-1-git-send-email-baoyou.xie@linaro.org + +diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c +index 5127b75dbf40..7250ffc6322f 100644 +--- a/drivers/gpu/drm/msm/adreno/adreno_device.c ++++ b/drivers/gpu/drm/msm/adreno/adreno_device.c +@@ -25,9 +25,6 @@ bool hang_debug = false; + MODULE_PARM_DESC(hang_debug, "Dump registers when hang is detected (can be slow!)"); + module_param_named(hang_debug, hang_debug, bool, 0600); + +-struct msm_gpu *a3xx_gpu_init(struct drm_device *dev); +-struct msm_gpu *a4xx_gpu_init(struct drm_device *dev); +- + static const struct adreno_info gpulist[] = { + { + .rev = ADRENO_REV(3, 0, 5, ANY_ID), +diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h +index a54f6e036b4a..07d99bdf7c99 100644 +--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h ++++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h +@@ -311,4 +311,7 @@ static inline void adreno_gpu_write(struct adreno_gpu *gpu, + gpu_write(&gpu->base, reg - 1, data); + } + ++struct msm_gpu *a3xx_gpu_init(struct drm_device *dev); ++struct msm_gpu *a4xx_gpu_init(struct drm_device *dev); ++ + #endif /* __ADRENO_GPU_H__ */ +-- +2.12.0 + diff --git a/queue/drm-nouveau-disp-mcp7x-disable-dptmds-workaround.patch b/queue/drm-nouveau-disp-mcp7x-disable-dptmds-workaround.patch new file mode 100644 index 0000000..533a0b8 --- /dev/null +++ b/queue/drm-nouveau-disp-mcp7x-disable-dptmds-workaround.patch @@ -0,0 +1,29 @@ +From 7dfee6827780d4228148263545af936d0cae8930 Mon Sep 17 00:00:00 2001 +From: Ben Skeggs <bskeggs@redhat.com> +Date: Mon, 9 Jan 2017 10:22:15 +1000 +Subject: [PATCH] drm/nouveau/disp/mcp7x: disable dptmds workaround + +commit 7dfee6827780d4228148263545af936d0cae8930 upstream. + +The workaround appears to cause regressions on these boards, and from +inspection of RM traces, NVIDIA don't appear to do it on them either. + +Signed-off-by: Ben Skeggs <bskeggs@redhat.com> +Tested-by: Roy Spliet <nouveau@spliet.org> + +diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c +index 567466f93cd5..0db8efbf1c2e 100644 +--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c ++++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c +@@ -433,8 +433,6 @@ nv50_disp_dptmds_war(struct nvkm_device *device) + case 0x94: + case 0x96: + case 0x98: +- case 0xaa: +- case 0xac: + return true; + default: + break; +-- +2.12.0 + diff --git a/queue/drm-nouveau-mmu-nv4a-use-nv04-mmu-rather-than-the-nv.patch b/queue/drm-nouveau-mmu-nv4a-use-nv04-mmu-rather-than-the-nv.patch new file mode 100644 index 0000000..ac5f395 --- /dev/null +++ b/queue/drm-nouveau-mmu-nv4a-use-nv04-mmu-rather-than-the-nv.patch @@ -0,0 +1,39 @@ +From f94773b9f5ecd1df7c88c2e921924dd41d2020cc Mon Sep 17 00:00:00 2001 +From: Ilia Mirkin <imirkin@alum.mit.edu> +Date: Sat, 18 Mar 2017 16:23:10 -0400 +Subject: [PATCH] drm/nouveau/mmu/nv4a: use nv04 mmu rather than the nv44 one + +commit f94773b9f5ecd1df7c88c2e921924dd41d2020cc upstream. + +The NV4A (aka NV44A) is an oddity in the family. It only comes in AGP +and PCI varieties, rather than a core PCIE chip with a bridge for +AGP/PCI as necessary. As a result, it appears that the MMU is also +non-functional. For AGP cards, the vast majority of the NV4A lineup, +this worked out since we force AGP cards to use the nv04 mmu. However +for PCI variants, this did not work. + +Switching to the NV04 MMU makes it work like a charm. Thanks to mwk for +the suggestion. This should be a no-op for NV4A AGP boards, as they were +using it already. + +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=70388 +Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu> +Cc: stable@vger.kernel.org +Signed-off-by: Ben Skeggs <bskeggs@redhat.com> + +diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +index 273562dd6bbd..0fc41db34522 100644 +--- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c ++++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +@@ -714,7 +714,7 @@ nv4a_chipset = { + .i2c = nv04_i2c_new, + .imem = nv40_instmem_new, + .mc = nv44_mc_new, +- .mmu = nv44_mmu_new, ++ .mmu = nv04_mmu_new, + .pci = nv40_pci_new, + .therm = nv40_therm_new, + .timer = nv41_timer_new, +-- +2.12.0 + diff --git a/queue/drm-nouveau-mpeg-mthd-returns-true-on-success-now.patch b/queue/drm-nouveau-mpeg-mthd-returns-true-on-success-now.patch new file mode 100644 index 0000000..1644ef7 --- /dev/null +++ b/queue/drm-nouveau-mpeg-mthd-returns-true-on-success-now.patch @@ -0,0 +1,41 @@ +From 83bce9c2baa51e439480a713119a73d3c8b61083 Mon Sep 17 00:00:00 2001 +From: Ilia Mirkin <imirkin@alum.mit.edu> +Date: Sat, 18 Mar 2017 21:53:05 -0400 +Subject: [PATCH] drm/nouveau/mpeg: mthd returns true on success now + +commit 83bce9c2baa51e439480a713119a73d3c8b61083 upstream. + +Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu> +Fixes: 590801c1a3 ("drm/nouveau/mpeg: remove dependence on namedb/engctx lookup") +Cc: stable@vger.kernel.org # v4.3+ +Signed-off-by: Ben Skeggs <bskeggs@redhat.com> + +diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv31.c b/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv31.c +index 003ac915eaad..8a8895246d26 100644 +--- a/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv31.c ++++ b/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv31.c +@@ -198,7 +198,7 @@ nv31_mpeg_intr(struct nvkm_engine *engine) + } + + if (type == 0x00000010) { +- if (!nv31_mpeg_mthd(mpeg, mthd, data)) ++ if (nv31_mpeg_mthd(mpeg, mthd, data)) + show &= ~0x01000000; + } + } +diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv44.c b/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv44.c +index e536f37e24b0..c3cf02ed468e 100644 +--- a/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv44.c ++++ b/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv44.c +@@ -172,7 +172,7 @@ nv44_mpeg_intr(struct nvkm_engine *engine) + } + + if (type == 0x00000010) { +- if (!nv44_mpeg_mthd(subdev->device, mthd, data)) ++ if (nv44_mpeg_mthd(subdev->device, mthd, data)) + show &= ~0x01000000; + } + } +-- +2.12.0 + diff --git a/queue/drm-sun4i-Add-compatible-string-for-A31-A31s-TCON-ti.patch b/queue/drm-sun4i-Add-compatible-string-for-A31-A31s-TCON-ti.patch new file mode 100644 index 0000000..8b13937 --- /dev/null +++ b/queue/drm-sun4i-Add-compatible-string-for-A31-A31s-TCON-ti.patch @@ -0,0 +1,85 @@ +From 93a5ec14da24a8abbac5bcb953b45cc7a5d0198a Mon Sep 17 00:00:00 2001 +From: Chen-Yu Tsai <wens@csie.org> +Date: Thu, 20 Oct 2016 11:43:40 +0800 +Subject: [PATCH] drm/sun4i: Add compatible string for A31/A31s TCON (timing + controller) + +commit 93a5ec14da24a8abbac5bcb953b45cc7a5d0198a upstream. + +The A31 TCON has mux controls for how TCON outputs are routed to the +HDMI and MIPI DSI blocks. + +Since the A31s does not have MIPI DSI, it only has a mux for the HDMI +controller input. + +This patch only adds support for the compatible strings. Actual support +for the mux controls should be added with HDMI and MIPI DSI support. + +Signed-off-by: Chen-Yu Tsai <wens@csie.org> +Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> + +diff --git a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt +index 5368961cd727..15fdca8909f2 100644 +--- a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt ++++ b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt +@@ -28,6 +28,8 @@ The TCON acts as a timing controller for RGB, LVDS and TV interfaces. + Required properties: + - compatible: value must be either: + * allwinner,sun5i-a13-tcon ++ * allwinner,sun6i-a31-tcon ++ * allwinner,sun6i-a31s-tcon + * allwinner,sun8i-a33-tcon + - reg: base address and size of memory-mapped region + - interrupts: interrupt associated to this IP +@@ -50,7 +52,7 @@ Required properties: + second the block connected to the TCON channel 1 (usually the TV + encoder) + +-On the A13, there is one more clock required: ++On SoCs other than the A33, there is one more clock required: + - 'tcon-ch1': The clock driving the TCON channel 1 + + DRC +diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c +index 0da9862ad8ed..a15c231fbd59 100644 +--- a/drivers/gpu/drm/sun4i/sun4i_drv.c ++++ b/drivers/gpu/drm/sun4i/sun4i_drv.c +@@ -207,6 +207,8 @@ static bool sun4i_drv_node_is_frontend(struct device_node *node) + static bool sun4i_drv_node_is_tcon(struct device_node *node) + { + return of_device_is_compatible(node, "allwinner,sun5i-a13-tcon") || ++ of_device_is_compatible(node, "allwinner,sun6i-a31-tcon") || ++ of_device_is_compatible(node, "allwinner,sun6i-a31s-tcon") || + of_device_is_compatible(node, "allwinner,sun8i-a33-tcon"); + } + +diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c +index 7658f0337e0b..c6afb2448655 100644 +--- a/drivers/gpu/drm/sun4i/sun4i_tcon.c ++++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c +@@ -587,12 +587,22 @@ static const struct sun4i_tcon_quirks sun5i_a13_quirks = { + .has_channel_1 = true, + }; + ++static const struct sun4i_tcon_quirks sun6i_a31_quirks = { ++ .has_channel_1 = true, ++}; ++ ++static const struct sun4i_tcon_quirks sun6i_a31s_quirks = { ++ .has_channel_1 = true, ++}; ++ + static const struct sun4i_tcon_quirks sun8i_a33_quirks = { + /* nothing is supported */ + }; + + static const struct of_device_id sun4i_tcon_of_table[] = { + { .compatible = "allwinner,sun5i-a13-tcon", .data = &sun5i_a13_quirks }, ++ { .compatible = "allwinner,sun6i-a31-tcon", .data = &sun6i_a31_quirks }, ++ { .compatible = "allwinner,sun6i-a31s-tcon", .data = &sun6i_a31s_quirks }, + { .compatible = "allwinner,sun8i-a33-tcon", .data = &sun8i_a33_quirks }, + { } + }; +-- +2.12.0 + diff --git a/queue/drm-sun4i-Add-compatible-strings-for-A31-A31s-displa.patch b/queue/drm-sun4i-Add-compatible-strings-for-A31-A31s-displa.patch new file mode 100644 index 0000000..798be2b --- /dev/null +++ b/queue/drm-sun4i-Add-compatible-strings-for-A31-A31s-displa.patch @@ -0,0 +1,88 @@ +From 49c440e87cd6f547f93d0dc53571ae0e11d9ec8f Mon Sep 17 00:00:00 2001 +From: Chen-Yu Tsai <wens@csie.org> +Date: Thu, 20 Oct 2016 11:43:41 +0800 +Subject: [PATCH] drm/sun4i: Add compatible strings for A31/A31s display + pipelines + +commit 49c440e87cd6f547f93d0dc53571ae0e11d9ec8f upstream. + +The A31's display pipeline has 2 frontends, 2 backends, and 2 TCONs. It +also has new display enhancement blocks, such as the DRC (Dynamic Range +Controller), the DEU (Display Enhancement Unit), and the CMU (Color +Management Unit). It supports HDMI, MIPI DSI, and 2 LCD/LVDS channels. + +The A31s display pipeline is almost the same, just without MIPI DSI. +Only the TCON seems to be different, due to the missing mux for MIPI +DSI. + +Add compatible strings for both of them. + +Signed-off-by: Chen-Yu Tsai <wens@csie.org> +Acked-by: Rob Herring <robh@kernel.org> +Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> + +diff --git a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt +index 15fdca8909f2..b82c00449468 100644 +--- a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt ++++ b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt +@@ -91,6 +91,7 @@ system. + Required properties: + - compatible: value must be one of: + * allwinner,sun5i-a13-display-backend ++ * allwinner,sun6i-a31-display-backend + * allwinner,sun8i-a33-display-backend + - reg: base address and size of the memory-mapped region. + - clocks: phandles to the clocks feeding the frontend and backend +@@ -121,6 +122,7 @@ deinterlacing and color space conversion. + Required properties: + - compatible: value must be one of: + * allwinner,sun5i-a13-display-frontend ++ * allwinner,sun6i-a31-display-frontend + * allwinner,sun8i-a33-display-frontend + - reg: base address and size of the memory-mapped region. + - interrupts: interrupt associated to this IP +@@ -146,6 +148,8 @@ extra node. + Required properties: + - compatible: value must be one of: + * allwinner,sun5i-a13-display-engine ++ * allwinner,sun6i-a31-display-engine ++ * allwinner,sun6i-a31s-display-engine + * allwinner,sun8i-a33-display-engine + + - allwinner,pipelines: list of phandle to the display engine +diff --git a/drivers/gpu/drm/sun4i/sun4i_backend.c b/drivers/gpu/drm/sun4i/sun4i_backend.c +index 32c0584e3c35..6e6c59a661b6 100644 +--- a/drivers/gpu/drm/sun4i/sun4i_backend.c ++++ b/drivers/gpu/drm/sun4i/sun4i_backend.c +@@ -408,6 +408,7 @@ static int sun4i_backend_remove(struct platform_device *pdev) + + static const struct of_device_id sun4i_backend_of_table[] = { + { .compatible = "allwinner,sun5i-a13-display-backend" }, ++ { .compatible = "allwinner,sun6i-a31-display-backend" }, + { .compatible = "allwinner,sun8i-a33-display-backend" }, + { } + }; +diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c +index a15c231fbd59..fa6568e1822a 100644 +--- a/drivers/gpu/drm/sun4i/sun4i_drv.c ++++ b/drivers/gpu/drm/sun4i/sun4i_drv.c +@@ -201,6 +201,7 @@ static const struct component_master_ops sun4i_drv_master_ops = { + static bool sun4i_drv_node_is_frontend(struct device_node *node) + { + return of_device_is_compatible(node, "allwinner,sun5i-a13-display-frontend") || ++ of_device_is_compatible(node, "allwinner,sun6i-a31-display-frontend") || + of_device_is_compatible(node, "allwinner,sun8i-a33-display-frontend"); + } + +@@ -324,6 +325,8 @@ static int sun4i_drv_remove(struct platform_device *pdev) + + static const struct of_device_id sun4i_drv_of_table[] = { + { .compatible = "allwinner,sun5i-a13-display-engine" }, ++ { .compatible = "allwinner,sun6i-a31-display-engine" }, ++ { .compatible = "allwinner,sun6i-a31s-display-engine" }, + { .compatible = "allwinner,sun8i-a33-display-engine" }, + { } + }; +-- +2.12.0 + diff --git a/queue/drm-sun4i-tcon-Move-SoC-specific-quirks-to-a-DT-matc.patch b/queue/drm-sun4i-tcon-Move-SoC-specific-quirks-to-a-DT-matc.patch new file mode 100644 index 0000000..dcbe810 --- /dev/null +++ b/queue/drm-sun4i-tcon-Move-SoC-specific-quirks-to-a-DT-matc.patch @@ -0,0 +1,144 @@ +From 91ea2f29cba6a7fe035ea232e4f981211a9fce5d Mon Sep 17 00:00:00 2001 +From: Chen-Yu Tsai <wens@csie.org> +Date: Thu, 20 Oct 2016 11:43:39 +0800 +Subject: [PATCH] drm/sun4i: tcon: Move SoC specific quirks to a DT matched + data structure + +commit 91ea2f29cba6a7fe035ea232e4f981211a9fce5d upstream. + +We already have some differences between the 2 supported SoCs. +More will be added as we support other SoCs. To avoid bloating +the probe function with even more conditionals, move the quirks +to a separate data structure that's tied to the compatible string. + +Signed-off-by: Chen-Yu Tsai <wens@csie.org> +Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> + +diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c +index cadacb517f95..7658f0337e0b 100644 +--- a/drivers/gpu/drm/sun4i/sun4i_tcon.c ++++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c +@@ -20,6 +20,7 @@ + #include <linux/component.h> + #include <linux/ioport.h> + #include <linux/of_address.h> ++#include <linux/of_device.h> + #include <linux/of_graph.h> + #include <linux/of_irq.h> + #include <linux/regmap.h> +@@ -62,7 +63,7 @@ void sun4i_tcon_channel_disable(struct sun4i_tcon *tcon, int channel) + return; + } + +- WARN_ON(!tcon->has_channel_1); ++ WARN_ON(!tcon->quirks->has_channel_1); + regmap_update_bits(tcon->regs, SUN4I_TCON1_CTL_REG, + SUN4I_TCON1_CTL_TCON_ENABLE, 0); + clk_disable_unprepare(tcon->sclk1); +@@ -80,7 +81,7 @@ void sun4i_tcon_channel_enable(struct sun4i_tcon *tcon, int channel) + return; + } + +- WARN_ON(!tcon->has_channel_1); ++ WARN_ON(!tcon->quirks->has_channel_1); + regmap_update_bits(tcon->regs, SUN4I_TCON1_CTL_REG, + SUN4I_TCON1_CTL_TCON_ENABLE, + SUN4I_TCON1_CTL_TCON_ENABLE); +@@ -202,7 +203,7 @@ void sun4i_tcon1_mode_set(struct sun4i_tcon *tcon, + u8 clk_delay; + u32 val; + +- WARN_ON(!tcon->has_channel_1); ++ WARN_ON(!tcon->quirks->has_channel_1); + + /* Adjust clock delay */ + clk_delay = sun4i_tcon_get_clk_delay(mode, 1); +@@ -266,7 +267,7 @@ void sun4i_tcon1_mode_set(struct sun4i_tcon *tcon, + /* + * FIXME: Undocumented bits + */ +- if (tcon->has_mux) ++ if (tcon->quirks->has_unknown_mux) + regmap_write(tcon->regs, SUN4I_TCON_MUX_CTRL_REG, 1); + } + EXPORT_SYMBOL(sun4i_tcon1_mode_set); +@@ -327,7 +328,7 @@ static int sun4i_tcon_init_clocks(struct device *dev, + return PTR_ERR(tcon->sclk0); + } + +- if (tcon->has_channel_1) { ++ if (tcon->quirks->has_channel_1) { + tcon->sclk1 = devm_clk_get(dev, "tcon-ch1"); + if (IS_ERR(tcon->sclk1)) { + dev_err(dev, "Couldn't get the TCON channel 1 clock\n"); +@@ -487,14 +488,7 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master, + drv->tcon = tcon; + tcon->drm = drm; + tcon->dev = dev; +- +- if (of_device_is_compatible(dev->of_node, "allwinner,sun5i-a13-tcon")) { +- tcon->has_mux = true; +- tcon->has_channel_1 = true; +- } else { +- tcon->has_mux = false; +- tcon->has_channel_1 = false; +- } ++ tcon->quirks = of_device_get_match_data(dev); + + tcon->lcd_rst = devm_reset_control_get(dev, "lcd"); + if (IS_ERR(tcon->lcd_rst)) { +@@ -588,9 +582,18 @@ static int sun4i_tcon_remove(struct platform_device *pdev) + return 0; + } + ++static const struct sun4i_tcon_quirks sun5i_a13_quirks = { ++ .has_unknown_mux = true, ++ .has_channel_1 = true, ++}; ++ ++static const struct sun4i_tcon_quirks sun8i_a33_quirks = { ++ /* nothing is supported */ ++}; ++ + static const struct of_device_id sun4i_tcon_of_table[] = { +- { .compatible = "allwinner,sun5i-a13-tcon" }, +- { .compatible = "allwinner,sun8i-a33-tcon" }, ++ { .compatible = "allwinner,sun5i-a13-tcon", .data = &sun5i_a13_quirks }, ++ { .compatible = "allwinner,sun8i-a33-tcon", .data = &sun8i_a33_quirks }, + { } + }; + MODULE_DEVICE_TABLE(of, sun4i_tcon_of_table); +diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.h b/drivers/gpu/drm/sun4i/sun4i_tcon.h +index 12bd48925f4d..166064bafe2e 100644 +--- a/drivers/gpu/drm/sun4i/sun4i_tcon.h ++++ b/drivers/gpu/drm/sun4i/sun4i_tcon.h +@@ -142,6 +142,11 @@ + + #define SUN4I_TCON_MAX_CHANNELS 2 + ++struct sun4i_tcon_quirks { ++ bool has_unknown_mux; /* sun5i has undocumented mux */ ++ bool has_channel_1; /* a33 does not have channel 1 */ ++}; ++ + struct sun4i_tcon { + struct device *dev; + struct drm_device *drm; +@@ -160,12 +165,10 @@ struct sun4i_tcon { + /* Reset control */ + struct reset_control *lcd_rst; + +- /* Platform adjustments */ +- bool has_mux; +- + struct drm_panel *panel; + +- bool has_channel_1; ++ /* Platform adjustments */ ++ const struct sun4i_tcon_quirks *quirks; + }; + + struct drm_bridge *sun4i_tcon_find_bridge(struct device_node *node); +-- +2.12.0 + diff --git a/queue/drm-ttm-drm-vmwgfx-Relax-permission-checking-when-op.patch b/queue/drm-ttm-drm-vmwgfx-Relax-permission-checking-when-op.patch new file mode 100644 index 0000000..93d67b0 --- /dev/null +++ b/queue/drm-ttm-drm-vmwgfx-Relax-permission-checking-when-op.patch @@ -0,0 +1,176 @@ +From fe25deb7737ce6c0879ccf79c99fa1221d428bf2 Mon Sep 17 00:00:00 2001 +From: Thomas Hellstrom <thellstrom@vmware.com> +Date: Mon, 27 Mar 2017 11:21:25 +0200 +Subject: [PATCH] drm/ttm, drm/vmwgfx: Relax permission checking when opening + surfaces + +commit fe25deb7737ce6c0879ccf79c99fa1221d428bf2 upstream. + +Previously, when a surface was opened using a legacy (non prime) handle, +it was verified to have been created by a client in the same master realm. +Relax this so that opening is also allowed recursively if the client +already has the surface open. + +This works around a regression in svga mesa where opening of a shared +surface is used recursively to obtain surface information. + +Cc: <stable@vger.kernel.org> +Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com> +Reviewed-by: Sinclair Yeh <syeh@vmware.com> + +diff --git a/drivers/gpu/drm/ttm/ttm_object.c b/drivers/gpu/drm/ttm/ttm_object.c +index fdb451e3ec01..d750140bafbc 100644 +--- a/drivers/gpu/drm/ttm/ttm_object.c ++++ b/drivers/gpu/drm/ttm/ttm_object.c +@@ -179,7 +179,7 @@ int ttm_base_object_init(struct ttm_object_file *tfile, + if (unlikely(ret != 0)) + goto out_err0; + +- ret = ttm_ref_object_add(tfile, base, TTM_REF_USAGE, NULL); ++ ret = ttm_ref_object_add(tfile, base, TTM_REF_USAGE, NULL, false); + if (unlikely(ret != 0)) + goto out_err1; + +@@ -318,7 +318,8 @@ EXPORT_SYMBOL(ttm_ref_object_exists); + + int ttm_ref_object_add(struct ttm_object_file *tfile, + struct ttm_base_object *base, +- enum ttm_ref_type ref_type, bool *existed) ++ enum ttm_ref_type ref_type, bool *existed, ++ bool require_existed) + { + struct drm_open_hash *ht = &tfile->ref_hash[ref_type]; + struct ttm_ref_object *ref; +@@ -345,6 +346,9 @@ int ttm_ref_object_add(struct ttm_object_file *tfile, + } + + rcu_read_unlock(); ++ if (require_existed) ++ return -EPERM; ++ + ret = ttm_mem_global_alloc(mem_glob, sizeof(*ref), + false, false); + if (unlikely(ret != 0)) +@@ -635,7 +639,7 @@ int ttm_prime_fd_to_handle(struct ttm_object_file *tfile, + prime = (struct ttm_prime_object *) dma_buf->priv; + base = &prime->base; + *handle = base->hash.key; +- ret = ttm_ref_object_add(tfile, base, TTM_REF_USAGE, NULL); ++ ret = ttm_ref_object_add(tfile, base, TTM_REF_USAGE, NULL, false); + + dma_buf_put(dma_buf); + +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c +index 4076063e0fdd..6b2708b4eafe 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c +@@ -1075,10 +1075,8 @@ int vmw_fence_event_ioctl(struct drm_device *dev, void *data, + (void) vmw_fence_obj_reference(fence); + + if (user_fence_rep != NULL) { +- bool existed; +- +- ret = ttm_ref_object_add(tfile, base, +- TTM_REF_USAGE, &existed); ++ ret = ttm_ref_object_add(vmw_fp->tfile, base, ++ TTM_REF_USAGE, NULL, false); + if (unlikely(ret != 0)) { + DRM_ERROR("Failed to reference a fence " + "object.\n"); +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c +index 65b3f0369636..bf23153d4f55 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c +@@ -589,7 +589,7 @@ static int vmw_user_dmabuf_synccpu_grab(struct vmw_user_dma_buffer *user_bo, + return ret; + + ret = ttm_ref_object_add(tfile, &user_bo->prime.base, +- TTM_REF_SYNCCPU_WRITE, &existed); ++ TTM_REF_SYNCCPU_WRITE, &existed, false); + if (ret != 0 || existed) + ttm_bo_synccpu_write_release(&user_bo->dma.base); + +@@ -773,7 +773,7 @@ int vmw_user_dmabuf_reference(struct ttm_object_file *tfile, + + *handle = user_bo->prime.base.hash.key; + return ttm_ref_object_add(tfile, &user_bo->prime.base, +- TTM_REF_USAGE, NULL); ++ TTM_REF_USAGE, NULL, false); + } + + /* +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c +index f410502cb075..adc023fe67f3 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c +@@ -891,17 +891,16 @@ vmw_surface_handle_reference(struct vmw_private *dev_priv, + uint32_t handle; + struct ttm_base_object *base; + int ret; ++ bool require_exist = false; + + if (handle_type == DRM_VMW_HANDLE_PRIME) { + ret = ttm_prime_fd_to_handle(tfile, u_handle, &handle); + if (unlikely(ret != 0)) + return ret; + } else { +- if (unlikely(drm_is_render_client(file_priv))) { +- DRM_ERROR("Render client refused legacy " +- "surface reference.\n"); +- return -EACCES; +- } ++ if (unlikely(drm_is_render_client(file_priv))) ++ require_exist = true; ++ + if (ACCESS_ONCE(vmw_fpriv(file_priv)->locked_master)) { + DRM_ERROR("Locked master refused legacy " + "surface reference.\n"); +@@ -929,17 +928,14 @@ vmw_surface_handle_reference(struct vmw_private *dev_priv, + + /* + * Make sure the surface creator has the same +- * authenticating master. ++ * authenticating master, or is already registered with us. + */ + if (drm_is_primary_client(file_priv) && +- user_srf->master != file_priv->master) { +- DRM_ERROR("Trying to reference surface outside of" +- " master domain.\n"); +- ret = -EACCES; +- goto out_bad_resource; +- } ++ user_srf->master != file_priv->master) ++ require_exist = true; + +- ret = ttm_ref_object_add(tfile, base, TTM_REF_USAGE, NULL); ++ ret = ttm_ref_object_add(tfile, base, TTM_REF_USAGE, NULL, ++ require_exist); + if (unlikely(ret != 0)) { + DRM_ERROR("Could not add a reference to a surface.\n"); + goto out_bad_resource; +diff --git a/include/drm/ttm/ttm_object.h b/include/drm/ttm/ttm_object.h +index ed953f98f0e1..1487011fe057 100644 +--- a/include/drm/ttm/ttm_object.h ++++ b/include/drm/ttm/ttm_object.h +@@ -229,6 +229,8 @@ extern void ttm_base_object_unref(struct ttm_base_object **p_base); + * @ref_type: The type of reference. + * @existed: Upon completion, indicates that an identical reference object + * already existed, and the refcount was upped on that object instead. ++ * @require_existed: Fail with -EPERM if an identical ref object didn't ++ * already exist. + * + * Checks that the base object is shareable and adds a ref object to it. + * +@@ -243,7 +245,8 @@ extern void ttm_base_object_unref(struct ttm_base_object **p_base); + */ + extern int ttm_ref_object_add(struct ttm_object_file *tfile, + struct ttm_base_object *base, +- enum ttm_ref_type ref_type, bool *existed); ++ enum ttm_ref_type ref_type, bool *existed, ++ bool require_existed); + + extern bool ttm_ref_object_exists(struct ttm_object_file *tfile, + struct ttm_base_object *base); +-- +2.12.0 + diff --git a/queue/drm-vmwgfx-NULL-pointer-dereference-in-vmw_surface_d.patch b/queue/drm-vmwgfx-NULL-pointer-dereference-in-vmw_surface_d.patch new file mode 100644 index 0000000..a5234fa --- /dev/null +++ b/queue/drm-vmwgfx-NULL-pointer-dereference-in-vmw_surface_d.patch @@ -0,0 +1,36 @@ +From 36274ab8c596f1240c606bb514da329add2a1bcd Mon Sep 17 00:00:00 2001 +From: Murray McAllister <murray.mcallister@insomniasec.com> +Date: Mon, 27 Mar 2017 11:12:53 +0200 +Subject: [PATCH] drm/vmwgfx: NULL pointer dereference in + vmw_surface_define_ioctl() + +commit 36274ab8c596f1240c606bb514da329add2a1bcd upstream. + +Before memory allocations vmw_surface_define_ioctl() checks the +upper-bounds of a user-supplied size, but does not check if the +supplied size is 0. + +Add check to avoid NULL pointer dereferences. + +Cc: <stable@vger.kernel.org> +Signed-off-by: Murray McAllister <murray.mcallister@insomniasec.com> +Reviewed-by: Sinclair Yeh <syeh@vmware.com> + +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c +index b445ce9b9757..f410502cb075 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c +@@ -716,8 +716,8 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data, + for (i = 0; i < DRM_VMW_MAX_SURFACE_FACES; ++i) + num_sizes += req->mip_levels[i]; + +- if (num_sizes > DRM_VMW_MAX_SURFACE_FACES * +- DRM_VMW_MAX_MIP_LEVELS) ++ if (num_sizes > DRM_VMW_MAX_SURFACE_FACES * DRM_VMW_MAX_MIP_LEVELS || ++ num_sizes == 0) + return -EINVAL; + + size = vmw_user_surface_size + 128 + +-- +2.12.0 + diff --git a/queue/drm-vmwgfx-Remove-getparam-error-message.patch b/queue/drm-vmwgfx-Remove-getparam-error-message.patch new file mode 100644 index 0000000..d70f7d1 --- /dev/null +++ b/queue/drm-vmwgfx-Remove-getparam-error-message.patch @@ -0,0 +1,32 @@ +From 53e16798b0864464c5444a204e1bb93ae246c429 Mon Sep 17 00:00:00 2001 +From: Thomas Hellstrom <thellstrom@vmware.com> +Date: Mon, 27 Mar 2017 13:06:05 +0200 +Subject: [PATCH] drm/vmwgfx: Remove getparam error message + +commit 53e16798b0864464c5444a204e1bb93ae246c429 upstream. + +The mesa winsys sometimes uses unimplemented parameter requests to +check for features. Remove the error message to avoid bloating the +kernel log. + +Cc: <stable@vger.kernel.org> +Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com> +Reviewed-by: Brian Paul <brianp@vmware.com> +Reviewed-by: Sinclair Yeh <syeh@vmware.com> + +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c +index 1802d0e7fab8..5ec24fd801cd 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c +@@ -114,8 +114,6 @@ int vmw_getparam_ioctl(struct drm_device *dev, void *data, + param->value = dev_priv->has_dx; + break; + default: +- DRM_ERROR("Illegal vmwgfx get param request: %d\n", +- param->param); + return -EINVAL; + } + +-- +2.12.0 + diff --git a/queue/drm-vmwgfx-Type-check-lookups-of-fence-objects.patch b/queue/drm-vmwgfx-Type-check-lookups-of-fence-objects.patch new file mode 100644 index 0000000..7914ecc --- /dev/null +++ b/queue/drm-vmwgfx-Type-check-lookups-of-fence-objects.patch @@ -0,0 +1,157 @@ +From f7652afa8eadb416b23eb57dec6f158529942041 Mon Sep 17 00:00:00 2001 +From: Thomas Hellstrom <thellstrom@vmware.com> +Date: Mon, 27 Mar 2017 11:09:08 +0200 +Subject: [PATCH] drm/vmwgfx: Type-check lookups of fence objects + +commit f7652afa8eadb416b23eb57dec6f158529942041 upstream. + +A malicious caller could otherwise hand over handles to other objects +causing all sorts of interesting problems. + +Testing done: Ran a Fedora 25 desktop using both Xorg and +gnome-shell/Wayland. + +Cc: <stable@vger.kernel.org> +Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com> +Reviewed-by: Sinclair Yeh <syeh@vmware.com> + +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c +index 6541dd8b82dc..4076063e0fdd 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c +@@ -538,7 +538,7 @@ int vmw_fence_create(struct vmw_fence_manager *fman, + struct vmw_fence_obj **p_fence) + { + struct vmw_fence_obj *fence; +- int ret; ++ int ret; + + fence = kzalloc(sizeof(*fence), GFP_KERNEL); + if (unlikely(fence == NULL)) +@@ -701,6 +701,41 @@ void vmw_fence_fifo_up(struct vmw_fence_manager *fman) + } + + ++/** ++ * vmw_fence_obj_lookup - Look up a user-space fence object ++ * ++ * @tfile: A struct ttm_object_file identifying the caller. ++ * @handle: A handle identifying the fence object. ++ * @return: A struct vmw_user_fence base ttm object on success or ++ * an error pointer on failure. ++ * ++ * The fence object is looked up and type-checked. The caller needs ++ * to have opened the fence object first, but since that happens on ++ * creation and fence objects aren't shareable, that's not an ++ * issue currently. ++ */ ++static struct ttm_base_object * ++vmw_fence_obj_lookup(struct ttm_object_file *tfile, u32 handle) ++{ ++ struct ttm_base_object *base = ttm_base_object_lookup(tfile, handle); ++ ++ if (!base) { ++ pr_err("Invalid fence object handle 0x%08lx.\n", ++ (unsigned long)handle); ++ return ERR_PTR(-EINVAL); ++ } ++ ++ if (base->refcount_release != vmw_user_fence_base_release) { ++ pr_err("Invalid fence object handle 0x%08lx.\n", ++ (unsigned long)handle); ++ ttm_base_object_unref(&base); ++ return ERR_PTR(-EINVAL); ++ } ++ ++ return base; ++} ++ ++ + int vmw_fence_obj_wait_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) + { +@@ -726,13 +761,9 @@ int vmw_fence_obj_wait_ioctl(struct drm_device *dev, void *data, + arg->kernel_cookie = jiffies + wait_timeout; + } + +- base = ttm_base_object_lookup(tfile, arg->handle); +- if (unlikely(base == NULL)) { +- printk(KERN_ERR "Wait invalid fence object handle " +- "0x%08lx.\n", +- (unsigned long)arg->handle); +- return -EINVAL; +- } ++ base = vmw_fence_obj_lookup(tfile, arg->handle); ++ if (IS_ERR(base)) ++ return PTR_ERR(base); + + fence = &(container_of(base, struct vmw_user_fence, base)->fence); + +@@ -771,13 +802,9 @@ int vmw_fence_obj_signaled_ioctl(struct drm_device *dev, void *data, + struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile; + struct vmw_private *dev_priv = vmw_priv(dev); + +- base = ttm_base_object_lookup(tfile, arg->handle); +- if (unlikely(base == NULL)) { +- printk(KERN_ERR "Fence signaled invalid fence object handle " +- "0x%08lx.\n", +- (unsigned long)arg->handle); +- return -EINVAL; +- } ++ base = vmw_fence_obj_lookup(tfile, arg->handle); ++ if (IS_ERR(base)) ++ return PTR_ERR(base); + + fence = &(container_of(base, struct vmw_user_fence, base)->fence); + fman = fman_from_fence(fence); +@@ -1024,6 +1051,7 @@ int vmw_fence_event_ioctl(struct drm_device *dev, void *data, + (struct drm_vmw_fence_event_arg *) data; + struct vmw_fence_obj *fence = NULL; + struct vmw_fpriv *vmw_fp = vmw_fpriv(file_priv); ++ struct ttm_object_file *tfile = vmw_fp->tfile; + struct drm_vmw_fence_rep __user *user_fence_rep = + (struct drm_vmw_fence_rep __user *)(unsigned long) + arg->fence_rep; +@@ -1037,15 +1065,11 @@ int vmw_fence_event_ioctl(struct drm_device *dev, void *data, + */ + if (arg->handle) { + struct ttm_base_object *base = +- ttm_base_object_lookup_for_ref(dev_priv->tdev, +- arg->handle); +- +- if (unlikely(base == NULL)) { +- DRM_ERROR("Fence event invalid fence object handle " +- "0x%08lx.\n", +- (unsigned long)arg->handle); +- return -EINVAL; +- } ++ vmw_fence_obj_lookup(tfile, arg->handle); ++ ++ if (IS_ERR(base)) ++ return PTR_ERR(base); ++ + fence = &(container_of(base, struct vmw_user_fence, + base)->fence); + (void) vmw_fence_obj_reference(fence); +@@ -1053,7 +1077,7 @@ int vmw_fence_event_ioctl(struct drm_device *dev, void *data, + if (user_fence_rep != NULL) { + bool existed; + +- ret = ttm_ref_object_add(vmw_fp->tfile, base, ++ ret = ttm_ref_object_add(tfile, base, + TTM_REF_USAGE, &existed); + if (unlikely(ret != 0)) { + DRM_ERROR("Failed to reference a fence " +@@ -1097,8 +1121,7 @@ int vmw_fence_event_ioctl(struct drm_device *dev, void *data, + return 0; + out_no_create: + if (user_fence_rep != NULL) +- ttm_ref_object_base_unref(vmw_fpriv(file_priv)->tfile, +- handle, TTM_REF_USAGE); ++ ttm_ref_object_base_unref(tfile, handle, TTM_REF_USAGE); + out_no_ref_obj: + vmw_fence_obj_unreference(&fence); + return ret; +-- +2.12.0 + diff --git a/queue/drm-vmwgfx-avoid-calling-vzalloc-with-a-0-size-in-vm.patch b/queue/drm-vmwgfx-avoid-calling-vzalloc-with-a-0-size-in-vm.patch new file mode 100644 index 0000000..525f2b1 --- /dev/null +++ b/queue/drm-vmwgfx-avoid-calling-vzalloc-with-a-0-size-in-vm.patch @@ -0,0 +1,34 @@ +From 63774069d9527a1aeaa4aa20e929ef5e8e9ecc38 Mon Sep 17 00:00:00 2001 +From: Murray McAllister <murray.mcallister@insomniasec.com> +Date: Mon, 27 Mar 2017 11:15:12 +0200 +Subject: [PATCH] drm/vmwgfx: avoid calling vzalloc with a 0 size in + vmw_get_cap_3d_ioctl() + +commit 63774069d9527a1aeaa4aa20e929ef5e8e9ecc38 upstream. + +In vmw_get_cap_3d_ioctl(), a user can supply 0 for a size that is +used in vzalloc(). This eventually calls dump_stack() (in warn_alloc()), +which can leak useful addresses to dmesg. + +Add check to avoid a size of 0. + +Cc: <stable@vger.kernel.org> +Signed-off-by: Murray McAllister <murray.mcallister@insomniasec.com> +Reviewed-by: Sinclair Yeh <syeh@vmware.com> + +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c +index b8c6a03c8c54..1802d0e7fab8 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c +@@ -186,7 +186,7 @@ int vmw_get_cap_3d_ioctl(struct drm_device *dev, void *data, + bool gb_objects = !!(dev_priv->capabilities & SVGA_CAP_GBOBJECTS); + struct vmw_fpriv *vmw_fp = vmw_fpriv(file_priv); + +- if (unlikely(arg->pad64 != 0)) { ++ if (unlikely(arg->pad64 != 0 || arg->max_size == 0)) { + DRM_ERROR("Illegal GET_3D_CAP argument.\n"); + return -EINVAL; + } +-- +2.12.0 + diff --git a/queue/drm-vmwgfx-fix-integer-overflow-in-vmw_surface_defin.patch b/queue/drm-vmwgfx-fix-integer-overflow-in-vmw_surface_defin.patch new file mode 100644 index 0000000..be7d47b --- /dev/null +++ b/queue/drm-vmwgfx-fix-integer-overflow-in-vmw_surface_defin.patch @@ -0,0 +1,39 @@ +From e7e11f99564222d82f0ce84bd521e57d78a6b678 Mon Sep 17 00:00:00 2001 +From: Li Qiang <liq3ea@gmail.com> +Date: Mon, 27 Mar 2017 20:10:53 -0700 +Subject: [PATCH] drm/vmwgfx: fix integer overflow in + vmw_surface_define_ioctl() + +commit e7e11f99564222d82f0ce84bd521e57d78a6b678 upstream. + +In vmw_surface_define_ioctl(), the 'num_sizes' is the sum of the +'req->mip_levels' array. This array can be assigned any value from +the user space. As both the 'num_sizes' and the array is uint32_t, +it is easy to make 'num_sizes' overflow. The later 'mip_levels' is +used as the loop count. This can lead an oob write. Add the check of +'req->mip_levels' to avoid this. + +Cc: <stable@vger.kernel.org> +Signed-off-by: Li Qiang <liqiang6-s@360.cn> +Reviewed-by: Thomas Hellstrom <thellstrom@vmware.com> + +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c +index adc023fe67f3..05fa092c942b 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c +@@ -713,8 +713,11 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data, + 128; + + num_sizes = 0; +- for (i = 0; i < DRM_VMW_MAX_SURFACE_FACES; ++i) ++ for (i = 0; i < DRM_VMW_MAX_SURFACE_FACES; ++i) { ++ if (req->mip_levels[i] > DRM_VMW_MAX_MIP_LEVELS) ++ return -EINVAL; + num_sizes += req->mip_levels[i]; ++ } + + if (num_sizes > DRM_VMW_MAX_SURFACE_FACES * DRM_VMW_MAX_MIP_LEVELS || + num_sizes == 0) +-- +2.12.0 + diff --git a/queue/efi-fb-Avoid-reconfiguration-of-BAR-that-covers-the-.patch b/queue/efi-fb-Avoid-reconfiguration-of-BAR-that-covers-the-.patch new file mode 100644 index 0000000..ae95bfb --- /dev/null +++ b/queue/efi-fb-Avoid-reconfiguration-of-BAR-that-covers-the-.patch @@ -0,0 +1,136 @@ +From 55d728a40d368ba80443be85c02e641fc9082a3f Mon Sep 17 00:00:00 2001 +From: Ard Biesheuvel <ard.biesheuvel@linaro.org> +Date: Tue, 4 Apr 2017 16:27:44 +0100 +Subject: [PATCH] efi/fb: Avoid reconfiguration of BAR that covers the + framebuffer + +commit 55d728a40d368ba80443be85c02e641fc9082a3f upstream. + +On UEFI systems, the PCI subsystem is enumerated by the firmware, +and if a graphical framebuffer is exposed via a PCI device, its base +address and size are exposed to the OS via the Graphics Output +Protocol (GOP). + +On arm64 PCI systems, the entire PCI hierarchy is reconfigured from +scratch at boot. This may result in the GOP framebuffer address to +become stale, if the BAR covering the framebuffer is modified. This +will cause the framebuffer to become unresponsive, and may in some +cases result in unpredictable behavior if the range is reassigned to +another device. + +So add a non-x86 quirk to the EFI fb driver to find the BAR associated +with the GOP base address, and claim the BAR resource so that the PCI +core will not move it. + +Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> +Cc: <stable@vger.kernel.org> # v4.7+ +Cc: Linus Torvalds <torvalds@linux-foundation.org> +Cc: Matt Fleming <matt@codeblueprint.co.uk> +Cc: Peter Jones <pjones@redhat.com> +Cc: Peter Zijlstra <peterz@infradead.org> +Cc: Thomas Gleixner <tglx@linutronix.de> +Cc: leif.lindholm@linaro.org +Cc: linux-efi@vger.kernel.org +Cc: lorenzo.pieralisi@arm.com +Fixes: 9822504c1fa5 ("efifb: Enable the efi-framebuffer platform driver ...") +Link: http://lkml.kernel.org/r/20170404152744.26687-3-ard.biesheuvel@linaro.org +Signed-off-by: Ingo Molnar <mingo@kernel.org> + +diff --git a/drivers/video/fbdev/efifb.c b/drivers/video/fbdev/efifb.c +index 8c4dc1e1f94f..b827a8113e26 100644 +--- a/drivers/video/fbdev/efifb.c ++++ b/drivers/video/fbdev/efifb.c +@@ -10,6 +10,7 @@ + #include <linux/efi.h> + #include <linux/errno.h> + #include <linux/fb.h> ++#include <linux/pci.h> + #include <linux/platform_device.h> + #include <linux/screen_info.h> + #include <video/vga.h> +@@ -143,6 +144,8 @@ static struct attribute *efifb_attrs[] = { + }; + ATTRIBUTE_GROUPS(efifb); + ++static bool pci_dev_disabled; /* FB base matches BAR of a disabled device */ ++ + static int efifb_probe(struct platform_device *dev) + { + struct fb_info *info; +@@ -152,7 +155,7 @@ static int efifb_probe(struct platform_device *dev) + unsigned int size_total; + char *option = NULL; + +- if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI) ++ if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI || pci_dev_disabled) + return -ENODEV; + + if (fb_get_options("efifb", &option)) +@@ -360,3 +363,64 @@ static struct platform_driver efifb_driver = { + }; + + builtin_platform_driver(efifb_driver); ++ ++#if defined(CONFIG_PCI) && !defined(CONFIG_X86) ++ ++static bool pci_bar_found; /* did we find a BAR matching the efifb base? */ ++ ++static void claim_efifb_bar(struct pci_dev *dev, int idx) ++{ ++ u16 word; ++ ++ pci_bar_found = true; ++ ++ pci_read_config_word(dev, PCI_COMMAND, &word); ++ if (!(word & PCI_COMMAND_MEMORY)) { ++ pci_dev_disabled = true; ++ dev_err(&dev->dev, ++ "BAR %d: assigned to efifb but device is disabled!\n", ++ idx); ++ return; ++ } ++ ++ if (pci_claim_resource(dev, idx)) { ++ pci_dev_disabled = true; ++ dev_err(&dev->dev, ++ "BAR %d: failed to claim resource for efifb!\n", idx); ++ return; ++ } ++ ++ dev_info(&dev->dev, "BAR %d: assigned to efifb\n", idx); ++} ++ ++static void efifb_fixup_resources(struct pci_dev *dev) ++{ ++ u64 base = screen_info.lfb_base; ++ u64 size = screen_info.lfb_size; ++ int i; ++ ++ if (pci_bar_found || screen_info.orig_video_isVGA != VIDEO_TYPE_EFI) ++ return; ++ ++ if (screen_info.capabilities & VIDEO_CAPABILITY_64BIT_BASE) ++ base |= (u64)screen_info.ext_lfb_base << 32; ++ ++ if (!base) ++ return; ++ ++ for (i = 0; i < PCI_STD_RESOURCE_END; i++) { ++ struct resource *res = &dev->resource[i]; ++ ++ if (!(res->flags & IORESOURCE_MEM)) ++ continue; ++ ++ if (res->start <= base && res->end >= base + size - 1) { ++ claim_efifb_bar(dev, i); ++ break; ++ } ++ } ++} ++DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY, ++ 16, efifb_fixup_resources); ++ ++#endif +-- +2.12.0 + diff --git a/queue/efi-libstub-Skip-GOP-with-PIXEL_BLT_ONLY-format.patch b/queue/efi-libstub-Skip-GOP-with-PIXEL_BLT_ONLY-format.patch new file mode 100644 index 0000000..5b667c6 --- /dev/null +++ b/queue/efi-libstub-Skip-GOP-with-PIXEL_BLT_ONLY-format.patch @@ -0,0 +1,61 @@ +From 540f4c0e894f7e46a66dfa424b16424cbdc12c38 Mon Sep 17 00:00:00 2001 +From: "Cohen, Eugene" <eugene@hp.com> +Date: Tue, 4 Apr 2017 16:27:43 +0100 +Subject: [PATCH] efi/libstub: Skip GOP with PIXEL_BLT_ONLY format + +commit 540f4c0e894f7e46a66dfa424b16424cbdc12c38 upstream. + +The UEFI Specification permits Graphics Output Protocol (GOP) instances +without direct framebuffer access. This is indicated in the Mode structure +with a PixelFormat enumeration value of PIXEL_BLT_ONLY. Given that the +kernel does not know how to drive a Blt() only framebuffer (which is only +permitted before ExitBootServices() anyway), we should disregard such +framebuffers when looking for a GOP instance that is suitable for use as +the boot console. + +So modify the EFI GOP initialization to not use a PIXEL_BLT_ONLY instance, +preventing attempts later in boot to use an invalid screen_info.lfb_base +address. + +Signed-off-by: Eugene Cohen <eugene@hp.com> +[ Moved the Blt() only check into the loop and clarified that Blt() only GOPs are unusable by the kernel. ] +Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> +Cc: <stable@vger.kernel.org> # v4.7+ +Cc: Linus Torvalds <torvalds@linux-foundation.org> +Cc: Matt Fleming <matt@codeblueprint.co.uk> +Cc: Peter Zijlstra <peterz@infradead.org> +Cc: Thomas Gleixner <tglx@linutronix.de> +Cc: leif.lindholm@linaro.org +Cc: linux-efi@vger.kernel.org +Cc: lorenzo.pieralisi@arm.com +Fixes: 9822504c1fa5 ("efifb: Enable the efi-framebuffer platform driver ...") +Link: http://lkml.kernel.org/r/20170404152744.26687-2-ard.biesheuvel@linaro.org +Signed-off-by: Ingo Molnar <mingo@kernel.org> + +diff --git a/drivers/firmware/efi/libstub/gop.c b/drivers/firmware/efi/libstub/gop.c +index 932742e4cf23..24c461dea7af 100644 +--- a/drivers/firmware/efi/libstub/gop.c ++++ b/drivers/firmware/efi/libstub/gop.c +@@ -149,7 +149,8 @@ setup_gop32(efi_system_table_t *sys_table_arg, struct screen_info *si, + + status = __gop_query32(sys_table_arg, gop32, &info, &size, + ¤t_fb_base); +- if (status == EFI_SUCCESS && (!first_gop || conout_found)) { ++ if (status == EFI_SUCCESS && (!first_gop || conout_found) && ++ info->pixel_format != PIXEL_BLT_ONLY) { + /* + * Systems that use the UEFI Console Splitter may + * provide multiple GOP devices, not all of which are +@@ -266,7 +267,8 @@ setup_gop64(efi_system_table_t *sys_table_arg, struct screen_info *si, + + status = __gop_query64(sys_table_arg, gop64, &info, &size, + ¤t_fb_base); +- if (status == EFI_SUCCESS && (!first_gop || conout_found)) { ++ if (status == EFI_SUCCESS && (!first_gop || conout_found) && ++ info->pixel_format != PIXEL_BLT_ONLY) { + /* + * Systems that use the UEFI Console Splitter may + * provide multiple GOP devices, not all of which are +-- +2.12.0 + diff --git a/queue/ext4-fix-inode-checksum-calculation-problem-if-i_ext.patch b/queue/ext4-fix-inode-checksum-calculation-problem-if-i_ext.patch new file mode 100644 index 0000000..b05f30d --- /dev/null +++ b/queue/ext4-fix-inode-checksum-calculation-problem-if-i_ext.patch @@ -0,0 +1,41 @@ +From 05ac5aa18abd7db341e54df4ae2b4c98ea0e43b7 Mon Sep 17 00:00:00 2001 +From: Daeho Jeong <daeho.jeong@samsung.com> +Date: Thu, 1 Dec 2016 11:49:12 -0500 +Subject: [PATCH] ext4: fix inode checksum calculation problem if i_extra_size + is small + +commit 05ac5aa18abd7db341e54df4ae2b4c98ea0e43b7 upstream. + +We've fixed the race condition problem in calculating ext4 checksum +value in commit b47820edd163 ("ext4: avoid modifying checksum fields +directly during checksum veficationon"). However, by this change, +when calculating the checksum value of inode whose i_extra_size is +less than 4, we couldn't calculate the checksum value in a proper way. +This problem was found and reported by Nix, Thank you. + +Reported-by: Nix <nix@esperi.org.uk> +Signed-off-by: Daeho Jeong <daeho.jeong@samsung.com> +Signed-off-by: Youngjin Gil <youngjin.gil@samsung.com> +Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> +Signed-off-by: Theodore Ts'o <tytso@mit.edu> + +diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c +index 7d95b6174980..b48ca0392b9c 100644 +--- a/fs/ext4/inode.c ++++ b/fs/ext4/inode.c +@@ -72,10 +72,9 @@ static __u32 ext4_inode_csum(struct inode *inode, struct ext4_inode *raw, + csum = ext4_chksum(sbi, csum, (__u8 *)&dummy_csum, + csum_size); + offset += csum_size; +- csum = ext4_chksum(sbi, csum, (__u8 *)raw + offset, +- EXT4_INODE_SIZE(inode->i_sb) - +- offset); + } ++ csum = ext4_chksum(sbi, csum, (__u8 *)raw + offset, ++ EXT4_INODE_SIZE(inode->i_sb) - offset); + } + + return csum; +-- +2.12.0 + diff --git a/queue/firmware-qcom-scm-Fix-interrupted-SCM-calls.patch b/queue/firmware-qcom-scm-Fix-interrupted-SCM-calls.patch new file mode 100644 index 0000000..25cc981 --- /dev/null +++ b/queue/firmware-qcom-scm-Fix-interrupted-SCM-calls.patch @@ -0,0 +1,119 @@ +From 82bcd087029f6056506ea929f11af02622230901 Mon Sep 17 00:00:00 2001 +From: Andy Gross <andy.gross@linaro.org> +Date: Wed, 1 Feb 2017 11:28:28 -0600 +Subject: [PATCH] firmware: qcom: scm: Fix interrupted SCM calls + +commit 82bcd087029f6056506ea929f11af02622230901 upstream. + +This patch adds a Qualcomm specific quirk to the arm_smccc_smc call. + +On Qualcomm ARM64 platforms, the SMC call can return before it has +completed. If this occurs, the call can be restarted, but it requires +using the returned session ID value from the interrupted SMC call. + +The quirk stores off the session ID from the interrupted call in the +quirk structure so that it can be used by the caller. + +This patch folds in a fix given by Sricharan R: +https://lkml.org/lkml/2016/9/28/272 + +Signed-off-by: Andy Gross <andy.gross@linaro.org> +Reviewed-by: Will Deacon <will.deacon@arm.com> +Signed-off-by: Will Deacon <will.deacon@arm.com> + +diff --git a/arch/arm64/kernel/smccc-call.S b/arch/arm64/kernel/smccc-call.S +index ba60a8cb07d2..62522342e1e4 100644 +--- a/arch/arm64/kernel/smccc-call.S ++++ b/arch/arm64/kernel/smccc-call.S +@@ -12,6 +12,7 @@ + * + */ + #include <linux/linkage.h> ++#include <linux/arm-smccc.h> + #include <asm/asm-offsets.h> + + .macro SMCCC instr +@@ -20,7 +21,13 @@ + ldr x4, [sp] + stp x0, x1, [x4, #ARM_SMCCC_RES_X0_OFFS] + stp x2, x3, [x4, #ARM_SMCCC_RES_X2_OFFS] +- ret ++ ldr x4, [sp, #8] ++ cbz x4, 1f /* no quirk structure */ ++ ldr x9, [x4, #ARM_SMCCC_QUIRK_ID_OFFS] ++ cmp x9, #ARM_SMCCC_QUIRK_QCOM_A6 ++ b.ne 1f ++ str x6, [x4, ARM_SMCCC_QUIRK_STATE_OFFS] ++1: ret + .cfi_endproc + .endm + +diff --git a/drivers/firmware/qcom_scm-64.c b/drivers/firmware/qcom_scm-64.c +index 4a0f5ead4fb5..1e2e5198db53 100644 +--- a/drivers/firmware/qcom_scm-64.c ++++ b/drivers/firmware/qcom_scm-64.c +@@ -91,6 +91,7 @@ static int qcom_scm_call(struct device *dev, u32 svc_id, u32 cmd_id, + dma_addr_t args_phys = 0; + void *args_virt = NULL; + size_t alloc_len; ++ struct arm_smccc_quirk quirk = {.id = ARM_SMCCC_QUIRK_QCOM_A6}; + + if (unlikely(arglen > N_REGISTER_ARGS)) { + alloc_len = N_EXT_QCOM_SCM_ARGS * sizeof(u64); +@@ -131,10 +132,16 @@ static int qcom_scm_call(struct device *dev, u32 svc_id, u32 cmd_id, + qcom_smccc_convention, + ARM_SMCCC_OWNER_SIP, fn_id); + ++ quirk.state.a6 = 0; ++ + do { +- arm_smccc_smc(cmd, desc->arginfo, desc->args[0], +- desc->args[1], desc->args[2], x5, 0, 0, +- res); ++ arm_smccc_smc_quirk(cmd, desc->arginfo, desc->args[0], ++ desc->args[1], desc->args[2], x5, ++ quirk.state.a6, 0, res, &quirk); ++ ++ if (res->a0 == QCOM_SCM_INTERRUPTED) ++ cmd = res->a0; ++ + } while (res->a0 == QCOM_SCM_INTERRUPTED); + + mutex_unlock(&qcom_scm_lock); +diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h +index c66f8ae94b5a..b67934164401 100644 +--- a/include/linux/arm-smccc.h ++++ b/include/linux/arm-smccc.h +@@ -14,9 +14,6 @@ + #ifndef __LINUX_ARM_SMCCC_H + #define __LINUX_ARM_SMCCC_H + +-#include <linux/linkage.h> +-#include <linux/types.h> +- + /* + * This file provides common defines for ARM SMC Calling Convention as + * specified in +@@ -60,6 +57,13 @@ + #define ARM_SMCCC_OWNER_TRUSTED_OS 50 + #define ARM_SMCCC_OWNER_TRUSTED_OS_END 63 + ++#define ARM_SMCCC_QUIRK_NONE 0 ++#define ARM_SMCCC_QUIRK_QCOM_A6 1 /* Save/restore register a6 */ ++ ++#ifndef __ASSEMBLY__ ++ ++#include <linux/linkage.h> ++#include <linux/types.h> + /** + * struct arm_smccc_res - Result from SMC/HVC call + * @a0-a3 result values from registers 0 to 3 +@@ -125,4 +129,5 @@ asmlinkage void __arm_smccc_hvc(unsigned long a0, unsigned long a1, + + #define arm_smccc_hvc_quirk(...) __arm_smccc_hvc(__VA_ARGS__) + ++#endif /*__ASSEMBLY__*/ + #endif /*__LINUX_ARM_SMCCC_H*/ +-- +2.12.0 + diff --git a/queue/ftrace-Fix-function-pid-filter-on-instances.patch b/queue/ftrace-Fix-function-pid-filter-on-instances.patch new file mode 100644 index 0000000..0dff163 --- /dev/null +++ b/queue/ftrace-Fix-function-pid-filter-on-instances.patch @@ -0,0 +1,104 @@ +From d879d0b8c183aabeb9a65eba91f3f9e3c7e7b905 Mon Sep 17 00:00:00 2001 +From: Namhyung Kim <namhyung@kernel.org> +Date: Mon, 17 Apr 2017 11:44:27 +0900 +Subject: [PATCH] ftrace: Fix function pid filter on instances + +commit d879d0b8c183aabeb9a65eba91f3f9e3c7e7b905 upstream. + +When function tracer has a pid filter, it adds a probe to sched_switch +to track if current task can be ignored. The probe checks the +ftrace_ignore_pid from current tr to filter tasks. But it misses to +delete the probe when removing an instance so that it can cause a crash +due to the invalid tr pointer (use-after-free). + +This is easily reproducible with the following: + + # cd /sys/kernel/debug/tracing + # mkdir instances/buggy + # echo $$ > instances/buggy/set_ftrace_pid + # rmdir instances/buggy + + ============================================================================ + BUG: KASAN: use-after-free in ftrace_filter_pid_sched_switch_probe+0x3d/0x90 + Read of size 8 by task kworker/0:1/17 + CPU: 0 PID: 17 Comm: kworker/0:1 Tainted: G B 4.11.0-rc3 #198 + Call Trace: + dump_stack+0x68/0x9f + kasan_object_err+0x21/0x70 + kasan_report.part.1+0x22b/0x500 + ? ftrace_filter_pid_sched_switch_probe+0x3d/0x90 + kasan_report+0x25/0x30 + __asan_load8+0x5e/0x70 + ftrace_filter_pid_sched_switch_probe+0x3d/0x90 + ? fpid_start+0x130/0x130 + __schedule+0x571/0xce0 + ... + +To fix it, use ftrace_clear_pids() to unregister the probe. As +instance_rmdir() already updated ftrace codes, it can just free the +filter safely. + +Link: http://lkml.kernel.org/r/20170417024430.21194-2-namhyung@kernel.org + +Fixes: 0c8916c34203 ("tracing: Add rmdir to remove multibuffer instances") +Cc: Ingo Molnar <mingo@kernel.org> +Cc: stable@vger.kernel.org +Reviewed-by: Masami Hiramatsu <mhiramat@kernel.org> +Signed-off-by: Namhyung Kim <namhyung@kernel.org> +Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org> + +diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c +index 27bb2e61276e..dd3e91d68dc7 100644 +--- a/kernel/trace/ftrace.c ++++ b/kernel/trace/ftrace.c +@@ -5566,6 +5566,15 @@ static void clear_ftrace_pids(struct trace_array *tr) + trace_free_pid_list(pid_list); + } + ++void ftrace_clear_pids(struct trace_array *tr) ++{ ++ mutex_lock(&ftrace_lock); ++ ++ clear_ftrace_pids(tr); ++ ++ mutex_unlock(&ftrace_lock); ++} ++ + static void ftrace_pid_reset(struct trace_array *tr) + { + mutex_lock(&ftrace_lock); +diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c +index f35109514a01..d484452ae648 100644 +--- a/kernel/trace/trace.c ++++ b/kernel/trace/trace.c +@@ -7402,6 +7402,7 @@ static int instance_rmdir(const char *name) + + tracing_set_nop(tr); + event_trace_del_tracer(tr); ++ ftrace_clear_pids(tr); + ftrace_destroy_function_files(tr); + tracefs_remove_recursive(tr->dir); + free_trace_buffers(tr); +diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h +index ae1cce91fead..d19d52d600d6 100644 +--- a/kernel/trace/trace.h ++++ b/kernel/trace/trace.h +@@ -896,6 +896,7 @@ int using_ftrace_ops_list_func(void); + void ftrace_init_tracefs(struct trace_array *tr, struct dentry *d_tracer); + void ftrace_init_tracefs_toplevel(struct trace_array *tr, + struct dentry *d_tracer); ++void ftrace_clear_pids(struct trace_array *tr); + #else + static inline int ftrace_trace_task(struct trace_array *tr) + { +@@ -914,6 +915,7 @@ ftrace_init_global_array_ops(struct trace_array *tr) { } + static inline void ftrace_reset_array_ops(struct trace_array *tr) { } + static inline void ftrace_init_tracefs(struct trace_array *tr, struct dentry *d) { } + static inline void ftrace_init_tracefs_toplevel(struct trace_array *tr, struct dentry *d) { } ++static inline void ftrace_clear_pids(struct trace_array *tr) { } + /* ftace_func_t type is not defined, use macro instead of static inline */ + #define ftrace_init_array_ops(tr, func) do { } while (0) + #endif /* CONFIG_FUNCTION_TRACER */ +-- +2.12.0 + diff --git a/queue/ftrace-Fix-removing-of-second-function-probe.patch b/queue/ftrace-Fix-removing-of-second-function-probe.patch new file mode 100644 index 0000000..cfe0601 --- /dev/null +++ b/queue/ftrace-Fix-removing-of-second-function-probe.patch @@ -0,0 +1,173 @@ +From 82cc4fc2e70ec5baeff8f776f2773abc8b2cc0ae Mon Sep 17 00:00:00 2001 +From: "Steven Rostedt (VMware)" <rostedt@goodmis.org> +Date: Fri, 14 Apr 2017 17:45:45 -0400 +Subject: [PATCH] ftrace: Fix removing of second function probe + +commit 82cc4fc2e70ec5baeff8f776f2773abc8b2cc0ae upstream. + +When two function probes are added to set_ftrace_filter, and then one of +them is removed, the update to the function locations is not performed, and +the record keeping of the function states are corrupted, and causes an +ftrace_bug() to occur. + +This is easily reproducable by adding two probes, removing one, and then +adding it back again. + + # cd /sys/kernel/debug/tracing + # echo schedule:traceoff > set_ftrace_filter + # echo do_IRQ:traceoff > set_ftrace_filter + # echo \!do_IRQ:traceoff > /debug/tracing/set_ftrace_filter + # echo do_IRQ:traceoff > set_ftrace_filter + +Causes: + ------------[ cut here ]------------ + WARNING: CPU: 2 PID: 1098 at kernel/trace/ftrace.c:2369 ftrace_get_addr_curr+0x143/0x220 + Modules linked in: [...] + CPU: 2 PID: 1098 Comm: bash Not tainted 4.10.0-test+ #405 + Hardware name: Hewlett-Packard HP Compaq Pro 6300 SFF/339A, BIOS K01 v02.05 05/07/2012 + Call Trace: + dump_stack+0x68/0x9f + __warn+0x111/0x130 + ? trace_irq_work_interrupt+0xa0/0xa0 + warn_slowpath_null+0x1d/0x20 + ftrace_get_addr_curr+0x143/0x220 + ? __fentry__+0x10/0x10 + ftrace_replace_code+0xe3/0x4f0 + ? ftrace_int3_handler+0x90/0x90 + ? printk+0x99/0xb5 + ? 0xffffffff81000000 + ftrace_modify_all_code+0x97/0x110 + arch_ftrace_update_code+0x10/0x20 + ftrace_run_update_code+0x1c/0x60 + ftrace_run_modify_code.isra.48.constprop.62+0x8e/0xd0 + register_ftrace_function_probe+0x4b6/0x590 + ? ftrace_startup+0x310/0x310 + ? debug_lockdep_rcu_enabled.part.4+0x1a/0x30 + ? update_stack_state+0x88/0x110 + ? ftrace_regex_write.isra.43.part.44+0x1d3/0x320 + ? preempt_count_sub+0x18/0xd0 + ? mutex_lock_nested+0x104/0x800 + ? ftrace_regex_write.isra.43.part.44+0x1d3/0x320 + ? __unwind_start+0x1c0/0x1c0 + ? _mutex_lock_nest_lock+0x800/0x800 + ftrace_trace_probe_callback.isra.3+0xc0/0x130 + ? func_set_flag+0xe0/0xe0 + ? __lock_acquire+0x642/0x1790 + ? __might_fault+0x1e/0x20 + ? trace_get_user+0x398/0x470 + ? strcmp+0x35/0x60 + ftrace_trace_onoff_callback+0x48/0x70 + ftrace_regex_write.isra.43.part.44+0x251/0x320 + ? match_records+0x420/0x420 + ftrace_filter_write+0x2b/0x30 + __vfs_write+0xd7/0x330 + ? do_loop_readv_writev+0x120/0x120 + ? locks_remove_posix+0x90/0x2f0 + ? do_lock_file_wait+0x160/0x160 + ? __lock_is_held+0x93/0x100 + ? rcu_read_lock_sched_held+0x5c/0xb0 + ? preempt_count_sub+0x18/0xd0 + ? __sb_start_write+0x10a/0x230 + ? vfs_write+0x222/0x240 + vfs_write+0xef/0x240 + SyS_write+0xab/0x130 + ? SyS_read+0x130/0x130 + ? trace_hardirqs_on_caller+0x182/0x280 + ? trace_hardirqs_on_thunk+0x1a/0x1c + entry_SYSCALL_64_fastpath+0x18/0xad + RIP: 0033:0x7fe61c157c30 + RSP: 002b:00007ffe87890258 EFLAGS: 00000246 ORIG_RAX: 0000000000000001 + RAX: ffffffffffffffda RBX: ffffffff8114a410 RCX: 00007fe61c157c30 + RDX: 0000000000000010 RSI: 000055814798f5e0 RDI: 0000000000000001 + RBP: ffff8800c9027f98 R08: 00007fe61c422740 R09: 00007fe61ca53700 + R10: 0000000000000073 R11: 0000000000000246 R12: 0000558147a36400 + R13: 00007ffe8788f160 R14: 0000000000000024 R15: 00007ffe8788f15c + ? trace_hardirqs_off_caller+0xc0/0x110 + ---[ end trace 99fa09b3d9869c2c ]--- + Bad trampoline accounting at: ffffffff81cc3b00 (do_IRQ+0x0/0x150) + +Cc: stable@vger.kernel.org +Fixes: 59df055f1991 ("ftrace: trace different functions with a different tracer") +Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org> + +diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c +index b9691ee8f6c1..27bb2e61276e 100644 +--- a/kernel/trace/ftrace.c ++++ b/kernel/trace/ftrace.c +@@ -3755,23 +3755,24 @@ static void __enable_ftrace_function_probe(struct ftrace_ops_hash *old_hash) + ftrace_probe_registered = 1; + } + +-static void __disable_ftrace_function_probe(void) ++static bool __disable_ftrace_function_probe(void) + { + int i; + + if (!ftrace_probe_registered) +- return; ++ return false; + + for (i = 0; i < FTRACE_FUNC_HASHSIZE; i++) { + struct hlist_head *hhd = &ftrace_func_hash[i]; + if (hhd->first) +- return; ++ return false; + } + + /* no more funcs left */ + ftrace_shutdown(&trace_probe_ops, 0); + + ftrace_probe_registered = 0; ++ return true; + } + + +@@ -3901,6 +3902,7 @@ static void + __unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops, + void *data, int flags) + { ++ struct ftrace_ops_hash old_hash_ops; + struct ftrace_func_entry *rec_entry; + struct ftrace_func_probe *entry; + struct ftrace_func_probe *p; +@@ -3912,6 +3914,7 @@ __unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops, + struct hlist_node *tmp; + char str[KSYM_SYMBOL_LEN]; + int i, ret; ++ bool disabled; + + if (glob && (strcmp(glob, "*") == 0 || !strlen(glob))) + func_g.search = NULL; +@@ -3930,6 +3933,10 @@ __unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops, + + mutex_lock(&trace_probe_ops.func_hash->regex_lock); + ++ old_hash_ops.filter_hash = old_hash; ++ /* Probes only have filters */ ++ old_hash_ops.notrace_hash = NULL; ++ + hash = alloc_and_copy_ftrace_hash(FTRACE_HASH_DEFAULT_BITS, *orig_hash); + if (!hash) + /* Hmm, should report this somehow */ +@@ -3967,12 +3974,17 @@ __unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops, + } + } + mutex_lock(&ftrace_lock); +- __disable_ftrace_function_probe(); ++ disabled = __disable_ftrace_function_probe(); + /* + * Remove after the disable is called. Otherwise, if the last + * probe is removed, a null hash means *all enabled*. + */ + ret = ftrace_hash_move(&trace_probe_ops, 1, orig_hash, hash); ++ ++ /* still need to update the function call sites */ ++ if (ftrace_enabled && !disabled) ++ ftrace_run_modify_code(&trace_probe_ops, FTRACE_UPDATE_CALLS, ++ &old_hash_ops); + synchronize_sched(); + if (!ret) + free_ftrace_hash_rcu(old_hash); +-- +2.12.0 + diff --git a/queue/i2c-bcm2835-Fix-hang-for-writing-messages-larger-tha.patch b/queue/i2c-bcm2835-Fix-hang-for-writing-messages-larger-tha.patch new file mode 100644 index 0000000..a389adf --- /dev/null +++ b/queue/i2c-bcm2835-Fix-hang-for-writing-messages-larger-tha.patch @@ -0,0 +1,95 @@ +From e2474541032db65d02bf88b6a8c2f954654b443f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org> +Date: Mon, 3 Oct 2016 22:06:08 +0200 +Subject: [PATCH] i2c: bcm2835: Fix hang for writing messages larger than 16 + bytes +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit e2474541032db65d02bf88b6a8c2f954654b443f upstream. + +Writing messages larger than the FIFO size results in a hang, rendering +the machine unusable. This is because the RXD status flag is set on the +first interrupt which results in bcm2835_drain_rxfifo() stealing bytes +from the buffer. The controller continues to trigger interrupts waiting +for the missing bytes, but bcm2835_fill_txfifo() has none to give. +In this situation wait_for_completion_timeout() apparently is unable to +stop the madness. + +The BCM2835 ARM Peripherals datasheet has this to say about the flags: + TXD: is set when the FIFO has space for at least one byte of data. + RXD: is set when the FIFO contains at least one byte of data. + TXW: is set during a write transfer and the FIFO is less than full. + RXR: is set during a read transfer and the FIFO is or more full. + +Implementing the logic from the downstream i2c-bcm2708 driver solved +the hang problem. + +Signed-off-by: Noralf Trønnes <noralf@tronnes.org> +Reviewed-by: Eric Anholt <eric@anholt.net> +Reviewed-by: Martin Sperl <kernel@martin.sperl.org> +Signed-off-by: Wolfram Sang <wsa@the-dreams.de> + +diff --git a/drivers/i2c/busses/i2c-bcm2835.c b/drivers/i2c/busses/i2c-bcm2835.c +index d4f3239b5686..f283b714aa79 100644 +--- a/drivers/i2c/busses/i2c-bcm2835.c ++++ b/drivers/i2c/busses/i2c-bcm2835.c +@@ -64,6 +64,7 @@ struct bcm2835_i2c_dev { + int irq; + struct i2c_adapter adapter; + struct completion completion; ++ struct i2c_msg *curr_msg; + u32 msg_err; + u8 *msg_buf; + size_t msg_buf_remaining; +@@ -126,14 +127,13 @@ static irqreturn_t bcm2835_i2c_isr(int this_irq, void *data) + return IRQ_HANDLED; + } + +- if (val & BCM2835_I2C_S_RXD) { +- bcm2835_drain_rxfifo(i2c_dev); +- if (!(val & BCM2835_I2C_S_DONE)) +- return IRQ_HANDLED; +- } +- + if (val & BCM2835_I2C_S_DONE) { +- if (i2c_dev->msg_buf_remaining) ++ if (i2c_dev->curr_msg->flags & I2C_M_RD) { ++ bcm2835_drain_rxfifo(i2c_dev); ++ val = bcm2835_i2c_readl(i2c_dev, BCM2835_I2C_S); ++ } ++ ++ if ((val & BCM2835_I2C_S_RXD) || i2c_dev->msg_buf_remaining) + i2c_dev->msg_err = BCM2835_I2C_S_LEN; + else + i2c_dev->msg_err = 0; +@@ -141,11 +141,16 @@ static irqreturn_t bcm2835_i2c_isr(int this_irq, void *data) + return IRQ_HANDLED; + } + +- if (val & BCM2835_I2C_S_TXD) { ++ if (val & BCM2835_I2C_S_TXW) { + bcm2835_fill_txfifo(i2c_dev); + return IRQ_HANDLED; + } + ++ if (val & BCM2835_I2C_S_RXR) { ++ bcm2835_drain_rxfifo(i2c_dev); ++ return IRQ_HANDLED; ++ } ++ + return IRQ_NONE; + } + +@@ -155,6 +160,7 @@ static int bcm2835_i2c_xfer_msg(struct bcm2835_i2c_dev *i2c_dev, + u32 c; + unsigned long time_left; + ++ i2c_dev->curr_msg = msg; + i2c_dev->msg_buf = msg->buf; + i2c_dev->msg_buf_remaining = msg->len; + reinit_completion(&i2c_dev->completion); +-- +2.12.0 + diff --git a/queue/iio-bmg160-reset-chip-when-probing.patch b/queue/iio-bmg160-reset-chip-when-probing.patch new file mode 100644 index 0000000..41f7dd4 --- /dev/null +++ b/queue/iio-bmg160-reset-chip-when-probing.patch @@ -0,0 +1,62 @@ +From 4bdc9029685ac03be50b320b29691766d2326c2b Mon Sep 17 00:00:00 2001 +From: Quentin Schulz <quentin.schulz@free-electrons.com> +Date: Tue, 21 Mar 2017 16:52:14 +0100 +Subject: [PATCH] iio: bmg160: reset chip when probing + +commit 4bdc9029685ac03be50b320b29691766d2326c2b upstream. + +The gyroscope chip might need to be reset to be used. + +Without the chip being reset, the driver stopped at the first +regmap_read (to get the CHIP_ID) and failed to probe. + +The datasheet of the gyroscope says that a minimum wait of 30ms after +the reset has to be done. + +This patch has been checked on a BMX055 and the datasheet of the BMG160 +and the BMI055 give the same reset register and bits. + +Signed-off-by: Quentin Schulz <quentin.schulz@free-electrons.com> +Cc: <Stable@vger.kernel.org> +Signed-off-by: Jonathan Cameron <jic23@kernel.org> + +diff --git a/drivers/iio/gyro/bmg160_core.c b/drivers/iio/gyro/bmg160_core.c +index f7fcfa886f72..821919dd245b 100644 +--- a/drivers/iio/gyro/bmg160_core.c ++++ b/drivers/iio/gyro/bmg160_core.c +@@ -27,6 +27,7 @@ + #include <linux/iio/trigger_consumer.h> + #include <linux/iio/triggered_buffer.h> + #include <linux/regmap.h> ++#include <linux/delay.h> + #include "bmg160.h" + + #define BMG160_IRQ_NAME "bmg160_event" +@@ -52,6 +53,9 @@ + #define BMG160_DEF_BW 100 + #define BMG160_REG_PMU_BW_RES BIT(7) + ++#define BMG160_GYRO_REG_RESET 0x14 ++#define BMG160_GYRO_RESET_VAL 0xb6 ++ + #define BMG160_REG_INT_MAP_0 0x17 + #define BMG160_INT_MAP_0_BIT_ANY BIT(1) + +@@ -236,6 +240,14 @@ static int bmg160_chip_init(struct bmg160_data *data) + int ret; + unsigned int val; + ++ /* ++ * Reset chip to get it in a known good state. A delay of 30ms after ++ * reset is required according to the datasheet. ++ */ ++ regmap_write(data->regmap, BMG160_GYRO_REG_RESET, ++ BMG160_GYRO_RESET_VAL); ++ usleep_range(30000, 30700); ++ + ret = regmap_read(data->regmap, BMG160_REG_CHIP_ID, &val); + if (ret < 0) { + dev_err(dev, "Error reading reg_chip_id\n"); +-- +2.12.0 + diff --git a/queue/iov_iter-new-privimitive-iov_iter_revert.patch b/queue/iov_iter-new-privimitive-iov_iter_revert.patch new file mode 100644 index 0000000..4b9e5b0 --- /dev/null +++ b/queue/iov_iter-new-privimitive-iov_iter_revert.patch @@ -0,0 +1,121 @@ +From 27c0e3748e41ca79171ffa3e97415a20af6facd0 Mon Sep 17 00:00:00 2001 +From: Al Viro <viro@zeniv.linux.org.uk> +Date: Fri, 17 Feb 2017 18:42:24 -0500 +Subject: [PATCH] [iov_iter] new privimitive: iov_iter_revert() + +commit 27c0e3748e41ca79171ffa3e97415a20af6facd0 upstream. + +opposite to iov_iter_advance(); the caller is responsible for never +using it to move back past the initial position. + +Cc: stable@vger.kernel.org +Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> + +diff --git a/include/linux/uio.h b/include/linux/uio.h +index 804e34c6f981..f2d36a3d3005 100644 +--- a/include/linux/uio.h ++++ b/include/linux/uio.h +@@ -39,7 +39,10 @@ struct iov_iter { + }; + union { + unsigned long nr_segs; +- int idx; ++ struct { ++ int idx; ++ int start_idx; ++ }; + }; + }; + +@@ -81,6 +84,7 @@ unsigned long iov_shorten(struct iovec *iov, unsigned long nr_segs, size_t to); + size_t iov_iter_copy_from_user_atomic(struct page *page, + struct iov_iter *i, unsigned long offset, size_t bytes); + void iov_iter_advance(struct iov_iter *i, size_t bytes); ++void iov_iter_revert(struct iov_iter *i, size_t bytes); + int iov_iter_fault_in_readable(struct iov_iter *i, size_t bytes); + size_t iov_iter_single_seg_count(const struct iov_iter *i); + size_t copy_page_to_iter(struct page *page, size_t offset, size_t bytes, +diff --git a/lib/iov_iter.c b/lib/iov_iter.c +index e68604ae3ced..60abc44385b7 100644 +--- a/lib/iov_iter.c ++++ b/lib/iov_iter.c +@@ -786,6 +786,68 @@ void iov_iter_advance(struct iov_iter *i, size_t size) + } + EXPORT_SYMBOL(iov_iter_advance); + ++void iov_iter_revert(struct iov_iter *i, size_t unroll) ++{ ++ if (!unroll) ++ return; ++ i->count += unroll; ++ if (unlikely(i->type & ITER_PIPE)) { ++ struct pipe_inode_info *pipe = i->pipe; ++ int idx = i->idx; ++ size_t off = i->iov_offset; ++ while (1) { ++ size_t n = off - pipe->bufs[idx].offset; ++ if (unroll < n) { ++ off -= (n - unroll); ++ break; ++ } ++ unroll -= n; ++ if (!unroll && idx == i->start_idx) { ++ off = 0; ++ break; ++ } ++ if (!idx--) ++ idx = pipe->buffers - 1; ++ off = pipe->bufs[idx].offset + pipe->bufs[idx].len; ++ } ++ i->iov_offset = off; ++ i->idx = idx; ++ pipe_truncate(i); ++ return; ++ } ++ if (unroll <= i->iov_offset) { ++ i->iov_offset -= unroll; ++ return; ++ } ++ unroll -= i->iov_offset; ++ if (i->type & ITER_BVEC) { ++ const struct bio_vec *bvec = i->bvec; ++ while (1) { ++ size_t n = (--bvec)->bv_len; ++ i->nr_segs++; ++ if (unroll <= n) { ++ i->bvec = bvec; ++ i->iov_offset = n - unroll; ++ return; ++ } ++ unroll -= n; ++ } ++ } else { /* same logics for iovec and kvec */ ++ const struct iovec *iov = i->iov; ++ while (1) { ++ size_t n = (--iov)->iov_len; ++ i->nr_segs++; ++ if (unroll <= n) { ++ i->iov = iov; ++ i->iov_offset = n - unroll; ++ return; ++ } ++ unroll -= n; ++ } ++ } ++} ++EXPORT_SYMBOL(iov_iter_revert); ++ + /* + * Return the count of just the current iov_iter segment. + */ +@@ -839,6 +901,7 @@ void iov_iter_pipe(struct iov_iter *i, int direction, + i->idx = (pipe->curbuf + pipe->nrbufs) & (pipe->buffers - 1); + i->iov_offset = 0; + i->count = count; ++ i->start_idx = i->idx; + } + EXPORT_SYMBOL(iov_iter_pipe); + +-- +2.12.0 + diff --git a/queue/irqchip-irq-imx-gpcv2-Fix-spinlock-initialization.patch b/queue/irqchip-irq-imx-gpcv2-Fix-spinlock-initialization.patch new file mode 100644 index 0000000..7df8657 --- /dev/null +++ b/queue/irqchip-irq-imx-gpcv2-Fix-spinlock-initialization.patch @@ -0,0 +1,44 @@ +From 75eb5e1e7b4edbc8e8f930de59004d21cb46961f Mon Sep 17 00:00:00 2001 +From: Tyler Baker <tyler.baker@linaro.org> +Date: Thu, 13 Apr 2017 15:27:31 -0700 +Subject: [PATCH] irqchip/irq-imx-gpcv2: Fix spinlock initialization + +commit 75eb5e1e7b4edbc8e8f930de59004d21cb46961f upstream. + +The raw_spinlock in the IMX GPCV2 interupt chip is not initialized before +usage. That results in a lockdep splat: + + INFO: trying to register non-static key. + the code is fine but needs lockdep annotation. + turning off the locking correctness validator. + +Add the missing raw_spin_lock_init() to the setup code. + +Fixes: e324c4dc4a59 ("irqchip/imx-gpcv2: IMX GPCv2 driver for wakeup sources") +Signed-off-by: Tyler Baker <tyler.baker@linaro.org> +Reviewed-by: Fabio Estevam <fabio.estevam@nxp.com> +Cc: jason@lakedaemon.net +Cc: marc.zyngier@arm.com +Cc: shawnguo@kernel.org +Cc: andrew.smirnov@gmail.com +Cc: linux-arm-kernel@lists.infradead.org +Cc: stable@vger.kernel.org +Link: http://lkml.kernel.org/r/20170413222731.5917-1-tyler.baker@linaro.org +Signed-off-by: Thomas Gleixner <tglx@linutronix.de> + +diff --git a/drivers/irqchip/irq-imx-gpcv2.c b/drivers/irqchip/irq-imx-gpcv2.c +index 15af9a9753e5..2d203b422129 100644 +--- a/drivers/irqchip/irq-imx-gpcv2.c ++++ b/drivers/irqchip/irq-imx-gpcv2.c +@@ -230,6 +230,8 @@ static int __init imx_gpcv2_irqchip_init(struct device_node *node, + return -ENOMEM; + } + ++ raw_spin_lock_init(&cd->rlock); ++ + cd->gpc_base = of_iomap(node, 0); + if (!cd->gpc_base) { + pr_err("fsl-gpcv2: unable to map gpc registers\n"); +-- +2.12.0 + diff --git a/queue/iscsi-target-Drop-work-around-for-legacy-GlobalSAN-i.patch b/queue/iscsi-target-Drop-work-around-for-legacy-GlobalSAN-i.patch new file mode 100644 index 0000000..f80da25 --- /dev/null +++ b/queue/iscsi-target-Drop-work-around-for-legacy-GlobalSAN-i.patch @@ -0,0 +1,82 @@ +From 1c99de981f30b3e7868b8d20ce5479fa1c0fea46 Mon Sep 17 00:00:00 2001 +From: Nicholas Bellinger <nab@linux-iscsi.org> +Date: Sun, 2 Apr 2017 13:36:44 -0700 +Subject: [PATCH] iscsi-target: Drop work-around for legacy GlobalSAN initiator + +commit 1c99de981f30b3e7868b8d20ce5479fa1c0fea46 upstream. + +Once upon a time back in 2009, a work-around was added to support +the GlobalSAN iSCSI initiator v3.3 for MacOSX, which during login +did not propose nor respond to MaxBurstLength, FirstBurstLength, +DefaultTime2Wait and DefaultTime2Retain keys. + +The work-around in iscsi_check_proposer_for_optional_reply() +allowed the missing keys to be proposed, but did not require +waiting for a response before moving to full feature phase +operation. This allowed GlobalSAN v3.3 to work out-of-the +box, and for many years we didn't run into login interopt +issues with any other initiators.. + +Until recently, when Martin tried a QLogic 57840S iSCSI Offload +HBA on Windows 2016 which completed login, but subsequently +failed with: + + Got unknown iSCSI OpCode: 0x43 + +The issue was QLogic MSFT side did not propose DefaultTime2Wait + +DefaultTime2Retain, so LIO proposes them itself, and immediately +transitions to full feature phase because of the GlobalSAN hack. +However, the QLogic MSFT side still attempts to respond to +DefaultTime2Retain + DefaultTime2Wait, even though LIO has set +ISCSI_FLAG_LOGIN_NEXT_STAGE3 + ISCSI_FLAG_LOGIN_TRANSIT +in last login response. + +So while the QLogic MSFT side should have been proposing these +two keys to start, it was doing the correct thing per RFC-3720 +attempting to respond to proposed keys before transitioning to +full feature phase. + +All that said, recent versions of GlobalSAN iSCSI (v5.3.0.541) +does correctly propose the four keys during login, making the +original work-around moot. + +So in order to allow QLogic MSFT to run unmodified as-is, go +ahead and drop this long standing work-around. + +Reported-by: Martin Svec <martin.svec@zoner.cz> +Cc: Martin Svec <martin.svec@zoner.cz> +Cc: Himanshu Madhani <Himanshu.Madhani@cavium.com> +Cc: Arun Easi <arun.easi@cavium.com> +Cc: stable@vger.kernel.org # 3.1+ +Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org> + +diff --git a/drivers/target/iscsi/iscsi_target_parameters.c b/drivers/target/iscsi/iscsi_target_parameters.c +index e65bf78ceef3..fce627628200 100644 +--- a/drivers/target/iscsi/iscsi_target_parameters.c ++++ b/drivers/target/iscsi/iscsi_target_parameters.c +@@ -782,22 +782,6 @@ static void iscsi_check_proposer_for_optional_reply(struct iscsi_param *param) + if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH)) + SET_PSTATE_REPLY_OPTIONAL(param); + /* +- * The GlobalSAN iSCSI Initiator for MacOSX does +- * not respond to MaxBurstLength, FirstBurstLength, +- * DefaultTime2Wait or DefaultTime2Retain parameter keys. +- * So, we set them to 'reply optional' here, and assume the +- * the defaults from iscsi_parameters.h if the initiator +- * is not RFC compliant and the keys are not negotiated. +- */ +- if (!strcmp(param->name, MAXBURSTLENGTH)) +- SET_PSTATE_REPLY_OPTIONAL(param); +- if (!strcmp(param->name, FIRSTBURSTLENGTH)) +- SET_PSTATE_REPLY_OPTIONAL(param); +- if (!strcmp(param->name, DEFAULTTIME2WAIT)) +- SET_PSTATE_REPLY_OPTIONAL(param); +- if (!strcmp(param->name, DEFAULTTIME2RETAIN)) +- SET_PSTATE_REPLY_OPTIONAL(param); +- /* + * Required for gPXE iSCSI boot client + */ + if (!strcmp(param->name, MAXCONNECTIONS)) +-- +2.12.0 + diff --git a/queue/iscsi-target-Fix-TMR-reference-leak-during-session-s.patch b/queue/iscsi-target-Fix-TMR-reference-leak-during-session-s.patch new file mode 100644 index 0000000..42f7006 --- /dev/null +++ b/queue/iscsi-target-Fix-TMR-reference-leak-during-session-s.patch @@ -0,0 +1,78 @@ +From efb2ea770bb3b0f40007530bc8b0c22f36e1c5eb Mon Sep 17 00:00:00 2001 +From: Nicholas Bellinger <nab@linux-iscsi.org> +Date: Thu, 23 Mar 2017 17:19:24 -0700 +Subject: [PATCH] iscsi-target: Fix TMR reference leak during session shutdown + +commit efb2ea770bb3b0f40007530bc8b0c22f36e1c5eb upstream. + +This patch fixes a iscsi-target specific TMR reference leak +during session shutdown, that could occur when a TMR was +quiesced before the hand-off back to iscsi-target code +via transport_cmd_check_stop_to_fabric(). + +The reference leak happens because iscsit_free_cmd() was +incorrectly skipping the final target_put_sess_cmd() for +TMRs when transport_generic_free_cmd() returned zero because +the se_cmd->cmd_kref did not reach zero, due to the missing +se_cmd assignment in original code. + +The result was iscsi_cmd and it's associated se_cmd memory +would be freed once se_sess->sess_cmd_map where released, +but the associated se_tmr_req was leaked and remained part +of se_device->dev_tmr_list. + +This bug would manfiest itself as kernel paging request +OOPsen in core_tmr_lun_reset(), when a left-over se_tmr_req +attempted to dereference it's se_cmd pointer that had +already been released during normal session shutdown. + +To address this bug, go ahead and treat ISCSI_OP_SCSI_CMD +and ISCSI_OP_SCSI_TMFUNC the same when there is an extra +se_cmd->cmd_kref to drop in iscsit_free_cmd(), and use +op_scsi to signal __iscsit_free_cmd() when the former +needs to clear any further iscsi related I/O state. + +Reported-by: Rob Millner <rlm@daterainc.com> +Cc: Rob Millner <rlm@daterainc.com> +Reported-by: Chu Yuan Lin <cyl@datera.io> +Cc: Chu Yuan Lin <cyl@datera.io> +Tested-by: Chu Yuan Lin <cyl@datera.io> +Cc: stable@vger.kernel.org # 3.10+ +Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org> + +diff --git a/drivers/target/iscsi/iscsi_target_util.c b/drivers/target/iscsi/iscsi_target_util.c +index 5041a9c8bdcb..b4640338f8d8 100644 +--- a/drivers/target/iscsi/iscsi_target_util.c ++++ b/drivers/target/iscsi/iscsi_target_util.c +@@ -737,21 +737,23 @@ void iscsit_free_cmd(struct iscsi_cmd *cmd, bool shutdown) + { + struct se_cmd *se_cmd = NULL; + int rc; ++ bool op_scsi = false; + /* + * Determine if a struct se_cmd is associated with + * this struct iscsi_cmd. + */ + switch (cmd->iscsi_opcode) { + case ISCSI_OP_SCSI_CMD: +- se_cmd = &cmd->se_cmd; +- __iscsit_free_cmd(cmd, true, shutdown); ++ op_scsi = true; + /* + * Fallthrough + */ + case ISCSI_OP_SCSI_TMFUNC: +- rc = transport_generic_free_cmd(&cmd->se_cmd, shutdown); +- if (!rc && shutdown && se_cmd && se_cmd->se_sess) { +- __iscsit_free_cmd(cmd, true, shutdown); ++ se_cmd = &cmd->se_cmd; ++ __iscsit_free_cmd(cmd, op_scsi, shutdown); ++ rc = transport_generic_free_cmd(se_cmd, shutdown); ++ if (!rc && shutdown && se_cmd->se_sess) { ++ __iscsit_free_cmd(cmd, op_scsi, shutdown); + target_put_sess_cmd(se_cmd); + } + break; +-- +2.12.0 + diff --git a/queue/kvm-arm-arm64-Fix-locking-for-kvm_free_stage2_pgd.patch b/queue/kvm-arm-arm64-Fix-locking-for-kvm_free_stage2_pgd.patch new file mode 100644 index 0000000..1d98caa --- /dev/null +++ b/queue/kvm-arm-arm64-Fix-locking-for-kvm_free_stage2_pgd.patch @@ -0,0 +1,63 @@ +From 8b3405e345b5a098101b0c31b264c812bba045d9 Mon Sep 17 00:00:00 2001 +From: Suzuki K Poulose <suzuki.poulose@arm.com> +Date: Mon, 3 Apr 2017 15:12:43 +0100 +Subject: [PATCH] kvm: arm/arm64: Fix locking for kvm_free_stage2_pgd + +commit 8b3405e345b5a098101b0c31b264c812bba045d9 upstream. + +In kvm_free_stage2_pgd() we don't hold the kvm->mmu_lock while calling +unmap_stage2_range() on the entire memory range for the guest. This could +cause problems with other callers (e.g, munmap on a memslot) trying to +unmap a range. And since we have to unmap the entire Guest memory range +holding a spinlock, make sure we yield the lock if necessary, after we +unmap each PUD range. + +Fixes: commit d5d8184d35c9 ("KVM: ARM: Memory virtualization setup") +Cc: stable@vger.kernel.org # v3.10+ +Cc: Paolo Bonzini <pbonzin@redhat.com> +Cc: Marc Zyngier <marc.zyngier@arm.com> +Cc: Christoffer Dall <christoffer.dall@linaro.org> +Cc: Mark Rutland <mark.rutland@arm.com> +Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com> +[ Avoid vCPU starvation and lockup detector warnings ] +Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> +Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com> +Signed-off-by: Christoffer Dall <cdall@linaro.org> + +diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c +index 13b9c1fa8961..582a972371cf 100644 +--- a/arch/arm/kvm/mmu.c ++++ b/arch/arm/kvm/mmu.c +@@ -292,11 +292,18 @@ static void unmap_stage2_range(struct kvm *kvm, phys_addr_t start, u64 size) + phys_addr_t addr = start, end = start + size; + phys_addr_t next; + ++ assert_spin_locked(&kvm->mmu_lock); + pgd = kvm->arch.pgd + stage2_pgd_index(addr); + do { + next = stage2_pgd_addr_end(addr, end); + if (!stage2_pgd_none(*pgd)) + unmap_stage2_puds(kvm, pgd, addr, next); ++ /* ++ * If the range is too large, release the kvm->mmu_lock ++ * to prevent starvation and lockup detector warnings. ++ */ ++ if (next != end) ++ cond_resched_lock(&kvm->mmu_lock); + } while (pgd++, addr = next, addr != end); + } + +@@ -831,7 +838,10 @@ void kvm_free_stage2_pgd(struct kvm *kvm) + if (kvm->arch.pgd == NULL) + return; + ++ spin_lock(&kvm->mmu_lock); + unmap_stage2_range(kvm, 0, KVM_PHYS_SIZE); ++ spin_unlock(&kvm->mmu_lock); ++ + /* Free the HW pgd, one page at a time */ + free_pages_exact(kvm->arch.pgd, S2_PGD_SIZE); + kvm->arch.pgd = NULL; +-- +2.12.0 + diff --git a/queue/kvm-fix-page-struct-leak-in-handle_vmon.patch b/queue/kvm-fix-page-struct-leak-in-handle_vmon.patch new file mode 100644 index 0000000..cb36ab9 --- /dev/null +++ b/queue/kvm-fix-page-struct-leak-in-handle_vmon.patch @@ -0,0 +1,43 @@ +From 06ce521af9558814b8606c0476c54497cf83a653 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini <pbonzini@redhat.com> +Date: Tue, 24 Jan 2017 11:56:21 +0100 +Subject: [PATCH] kvm: fix page struct leak in handle_vmon + +commit 06ce521af9558814b8606c0476c54497cf83a653 upstream. + +handle_vmon gets a reference on VMXON region page, +but does not release it. Release the reference. + +Found by syzkaller; based on a patch by Dmitry. + +Reported-by: Dmitry Vyukov <dvyukov@google.com> +Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> + +diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c +index 9856b73a21ad..d13073c841ff 100644 +--- a/arch/x86/kvm/vmx.c ++++ b/arch/x86/kvm/vmx.c +@@ -6996,13 +6996,18 @@ static int nested_vmx_check_vmptr(struct kvm_vcpu *vcpu, int exit_reason, + } + + page = nested_get_page(vcpu, vmptr); +- if (page == NULL || +- *(u32 *)kmap(page) != VMCS12_REVISION) { ++ if (page == NULL) { + nested_vmx_failInvalid(vcpu); ++ return kvm_skip_emulated_instruction(vcpu); ++ } ++ if (*(u32 *)kmap(page) != VMCS12_REVISION) { + kunmap(page); ++ nested_release_page_clean(page); ++ nested_vmx_failInvalid(vcpu); + return kvm_skip_emulated_instruction(vcpu); + } + kunmap(page); ++ nested_release_page_clean(page); + vmx->nested.vmxon_ptr = vmptr; + break; + case EXIT_REASON_VMCLEAR: +-- +2.12.0 + diff --git a/queue/libnvdimm-fix-blk-free-space-accounting.patch b/queue/libnvdimm-fix-blk-free-space-accounting.patch new file mode 100644 index 0000000..55e64b4 --- /dev/null +++ b/queue/libnvdimm-fix-blk-free-space-accounting.patch @@ -0,0 +1,167 @@ +From fe514739d8538783749d3ce72f78e5a999ea5668 Mon Sep 17 00:00:00 2001 +From: Dan Williams <dan.j.williams@intel.com> +Date: Tue, 4 Apr 2017 15:08:36 -0700 +Subject: [PATCH] libnvdimm: fix blk free space accounting + +commit fe514739d8538783749d3ce72f78e5a999ea5668 upstream. + +Commit a1f3e4d6a0c3 "libnvdimm, region: update nd_region_available_dpa() +for multi-pmem support" reworked blk dpa (DIMM Physical Address) +accounting to comprehend multiple pmem namespace allocations aliasing +with a given blk-dpa range. + +The following call trace is a result of failing to account for allocated +blk capacity. + + WARNING: CPU: 1 PID: 2433 at tools/testing/nvdimm/../../../drivers/nvdimm/names +4 size_store+0x6f3/0x930 [libnvdimm] + nd_region region5: allocation underrun: 0x0 of 0x1000000 bytes + [..] + Call Trace: + dump_stack+0x86/0xc3 + __warn+0xcb/0xf0 + warn_slowpath_fmt+0x5f/0x80 + size_store+0x6f3/0x930 [libnvdimm] + dev_attr_store+0x18/0x30 + +If a given blk-dpa allocation does not alias with any pmem ranges then +the full allocation should be accounted as busy space, not the size of +the current pmem contribution to the region. + +The thinkos that led to this confusion was not realizing that the struct +resource management is already guaranteeing no collisions between pmem +allocations and blk allocations on the same dimm. Also, we do not try to +support blk allocations in aliased pmem holes. + +This patch also fixes a case where the available blk goes negative. + +Cc: <stable@vger.kernel.org> +Fixes: a1f3e4d6a0c3 ("libnvdimm, region: update nd_region_available_dpa() for multi-pmem support"). +Reported-by: Dariusz Dokupil <dariusz.dokupil@intel.com> +Reported-by: Dave Jiang <dave.jiang@intel.com> +Reported-by: Vishal Verma <vishal.l.verma@intel.com> +Tested-by: Dave Jiang <dave.jiang@intel.com> +Tested-by: Vishal Verma <vishal.l.verma@intel.com> +Signed-off-by: Dan Williams <dan.j.williams@intel.com> + +diff --git a/drivers/nvdimm/dimm_devs.c b/drivers/nvdimm/dimm_devs.c +index 0eedc49e0d47..8b721321be5b 100644 +--- a/drivers/nvdimm/dimm_devs.c ++++ b/drivers/nvdimm/dimm_devs.c +@@ -395,7 +395,7 @@ EXPORT_SYMBOL_GPL(nvdimm_create); + + int alias_dpa_busy(struct device *dev, void *data) + { +- resource_size_t map_end, blk_start, new, busy; ++ resource_size_t map_end, blk_start, new; + struct blk_alloc_info *info = data; + struct nd_mapping *nd_mapping; + struct nd_region *nd_region; +@@ -436,29 +436,19 @@ int alias_dpa_busy(struct device *dev, void *data) + retry: + /* + * Find the free dpa from the end of the last pmem allocation to +- * the end of the interleave-set mapping that is not already +- * covered by a blk allocation. ++ * the end of the interleave-set mapping. + */ +- busy = 0; + for_each_dpa_resource(ndd, res) { ++ if (strncmp(res->name, "pmem", 4) != 0) ++ continue; + if ((res->start >= blk_start && res->start < map_end) + || (res->end >= blk_start + && res->end <= map_end)) { +- if (strncmp(res->name, "pmem", 4) == 0) { +- new = max(blk_start, min(map_end + 1, +- res->end + 1)); +- if (new != blk_start) { +- blk_start = new; +- goto retry; +- } +- } else +- busy += min(map_end, res->end) +- - max(nd_mapping->start, res->start) + 1; +- } else if (nd_mapping->start > res->start +- && map_end < res->end) { +- /* total eclipse of the PMEM region mapping */ +- busy += nd_mapping->size; +- break; ++ new = max(blk_start, min(map_end + 1, res->end + 1)); ++ if (new != blk_start) { ++ blk_start = new; ++ goto retry; ++ } + } + } + +@@ -470,52 +460,11 @@ int alias_dpa_busy(struct device *dev, void *data) + return 1; + } + +- info->available -= blk_start - nd_mapping->start + busy; ++ info->available -= blk_start - nd_mapping->start; + + return 0; + } + +-static int blk_dpa_busy(struct device *dev, void *data) +-{ +- struct blk_alloc_info *info = data; +- struct nd_mapping *nd_mapping; +- struct nd_region *nd_region; +- resource_size_t map_end; +- int i; +- +- if (!is_nd_pmem(dev)) +- return 0; +- +- nd_region = to_nd_region(dev); +- for (i = 0; i < nd_region->ndr_mappings; i++) { +- nd_mapping = &nd_region->mapping[i]; +- if (nd_mapping->nvdimm == info->nd_mapping->nvdimm) +- break; +- } +- +- if (i >= nd_region->ndr_mappings) +- return 0; +- +- map_end = nd_mapping->start + nd_mapping->size - 1; +- if (info->res->start >= nd_mapping->start +- && info->res->start < map_end) { +- if (info->res->end <= map_end) { +- info->busy = 0; +- return 1; +- } else { +- info->busy -= info->res->end - map_end; +- return 0; +- } +- } else if (info->res->end >= nd_mapping->start +- && info->res->end <= map_end) { +- info->busy -= nd_mapping->start - info->res->start; +- return 0; +- } else { +- info->busy -= nd_mapping->size; +- return 0; +- } +-} +- + /** + * nd_blk_available_dpa - account the unused dpa of BLK region + * @nd_mapping: container of dpa-resource-root + labels +@@ -545,11 +494,7 @@ resource_size_t nd_blk_available_dpa(struct nd_region *nd_region) + for_each_dpa_resource(ndd, res) { + if (strncmp(res->name, "blk", 3) != 0) + continue; +- +- info.res = res; +- info.busy = resource_size(res); +- device_for_each_child(&nvdimm_bus->dev, &info, blk_dpa_busy); +- info.available -= info.busy; ++ info.available -= resource_size(res); + } + + return info.available; +-- +2.12.0 + diff --git a/queue/libnvdimm-fix-reconfig_mutex-mmap_sem-and-jbd2_handl.patch b/queue/libnvdimm-fix-reconfig_mutex-mmap_sem-and-jbd2_handl.patch new file mode 100644 index 0000000..106ff0a --- /dev/null +++ b/queue/libnvdimm-fix-reconfig_mutex-mmap_sem-and-jbd2_handl.patch @@ -0,0 +1,92 @@ +From 0beb2012a1722633515c8aaa263c73449636c893 Mon Sep 17 00:00:00 2001 +From: Dan Williams <dan.j.williams@intel.com> +Date: Fri, 7 Apr 2017 09:47:24 -0700 +Subject: [PATCH] libnvdimm: fix reconfig_mutex, mmap_sem, and jbd2_handle + lockdep splat + +commit 0beb2012a1722633515c8aaa263c73449636c893 upstream. + +Holding the reconfig_mutex over a potential userspace fault sets up a +lockdep dependency chain between filesystem-DAX and the libnvdimm ioctl +path. Move the user access outside of the lock. + + [ INFO: possible circular locking dependency detected ] + 4.11.0-rc3+ #13 Tainted: G W O + ------------------------------------------------------- + fallocate/16656 is trying to acquire lock: + (&nvdimm_bus->reconfig_mutex){+.+.+.}, at: [<ffffffffa00080b1>] nvdimm_bus_lock+0x21/0x30 [libnvdimm] + but task is already holding lock: + (jbd2_handle){++++..}, at: [<ffffffff813b4944>] start_this_handle+0x104/0x460 + + which lock already depends on the new lock. + + the existing dependency chain (in reverse order) is: + + -> #2 (jbd2_handle){++++..}: + lock_acquire+0xbd/0x200 + start_this_handle+0x16a/0x460 + jbd2__journal_start+0xe9/0x2d0 + __ext4_journal_start_sb+0x89/0x1c0 + ext4_dirty_inode+0x32/0x70 + __mark_inode_dirty+0x235/0x670 + generic_update_time+0x87/0xd0 + touch_atime+0xa9/0xd0 + ext4_file_mmap+0x90/0xb0 + mmap_region+0x370/0x5b0 + do_mmap+0x415/0x4f0 + vm_mmap_pgoff+0xd7/0x120 + SyS_mmap_pgoff+0x1c5/0x290 + SyS_mmap+0x22/0x30 + entry_SYSCALL_64_fastpath+0x1f/0xc2 + + -> #1 (&mm->mmap_sem){++++++}: + lock_acquire+0xbd/0x200 + __might_fault+0x70/0xa0 + __nd_ioctl+0x683/0x720 [libnvdimm] + nvdimm_ioctl+0x8b/0xe0 [libnvdimm] + do_vfs_ioctl+0xa8/0x740 + SyS_ioctl+0x79/0x90 + do_syscall_64+0x6c/0x200 + return_from_SYSCALL_64+0x0/0x7a + + -> #0 (&nvdimm_bus->reconfig_mutex){+.+.+.}: + __lock_acquire+0x16b6/0x1730 + lock_acquire+0xbd/0x200 + __mutex_lock+0x88/0x9b0 + mutex_lock_nested+0x1b/0x20 + nvdimm_bus_lock+0x21/0x30 [libnvdimm] + nvdimm_forget_poison+0x25/0x50 [libnvdimm] + nvdimm_clear_poison+0x106/0x140 [libnvdimm] + pmem_do_bvec+0x1c2/0x2b0 [nd_pmem] + pmem_make_request+0xf9/0x270 [nd_pmem] + generic_make_request+0x118/0x3b0 + submit_bio+0x75/0x150 + +Cc: <stable@vger.kernel.org> +Fixes: 62232e45f4a2 ("libnvdimm: control (ioctl) messages for nvdimm_bus and nvdimm devices") +Cc: Dave Jiang <dave.jiang@intel.com> +Reported-by: Vishal Verma <vishal.l.verma@intel.com> +Signed-off-by: Dan Williams <dan.j.williams@intel.com> + +diff --git a/drivers/nvdimm/bus.c b/drivers/nvdimm/bus.c +index 23d4a1728cdf..351bac8f6503 100644 +--- a/drivers/nvdimm/bus.c ++++ b/drivers/nvdimm/bus.c +@@ -934,8 +934,14 @@ static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm, + rc = nd_desc->ndctl(nd_desc, nvdimm, cmd, buf, buf_len, NULL); + if (rc < 0) + goto out_unlock; ++ nvdimm_bus_unlock(&nvdimm_bus->dev); ++ + if (copy_to_user(p, buf, buf_len)) + rc = -EFAULT; ++ ++ vfree(buf); ++ return rc; ++ + out_unlock: + nvdimm_bus_unlock(&nvdimm_bus->dev); + out: +-- +2.12.0 + diff --git a/queue/mac80211-unconditionally-start-new-netdev-queues-wit.patch b/queue/mac80211-unconditionally-start-new-netdev-queues-wit.patch new file mode 100644 index 0000000..fbac46b --- /dev/null +++ b/queue/mac80211-unconditionally-start-new-netdev-queues-wit.patch @@ -0,0 +1,36 @@ +From 7d65f82954dadbbe7b6e1aec7e07ad17bc6d958b Mon Sep 17 00:00:00 2001 +From: Johannes Berg <johannes.berg@intel.com> +Date: Wed, 29 Mar 2017 14:15:24 +0200 +Subject: [PATCH] mac80211: unconditionally start new netdev queues with iTXQ + support + +commit 7d65f82954dadbbe7b6e1aec7e07ad17bc6d958b upstream. + +When internal mac80211 TXQs aren't supported, netdev queues must +always started out started even when driver queues are stopped +while the interface is added. This is necessary because with the +internal TXQ support netdev queues are never stopped and packet +scheduling/dropping is done in mac80211. + +Cc: stable@vger.kernel.org # 4.9+ +Fixes: 80a83cfc434b1 ("mac80211: skip netdev queue control with software queuing") +Reported-and-tested-by: Sven Eckelmann <sven.eckelmann@openmesh.com> +Signed-off-by: Johannes Berg <johannes.berg@intel.com> + +diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c +index 40813dd3301c..5bb0c5012819 100644 +--- a/net/mac80211/iface.c ++++ b/net/mac80211/iface.c +@@ -718,7 +718,8 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) + ieee80211_recalc_ps(local); + + if (sdata->vif.type == NL80211_IFTYPE_MONITOR || +- sdata->vif.type == NL80211_IFTYPE_AP_VLAN) { ++ sdata->vif.type == NL80211_IFTYPE_AP_VLAN || ++ local->ops->wake_tx_queue) { + /* XXX: for AP_VLAN, actually track AP queues */ + netif_tx_start_all_queues(dev); + } else if (dev) { +-- +2.12.0 + diff --git a/queue/make-skb_copy_datagram_msg-et.al.-preserve-msg_iter-.patch b/queue/make-skb_copy_datagram_msg-et.al.-preserve-msg_iter-.patch new file mode 100644 index 0000000..2888a8a --- /dev/null +++ b/queue/make-skb_copy_datagram_msg-et.al.-preserve-msg_iter-.patch @@ -0,0 +1,136 @@ +From 3278682123811dd8ef07de5eb701fc4548fcebf2 Mon Sep 17 00:00:00 2001 +From: Al Viro <viro@zeniv.linux.org.uk> +Date: Fri, 17 Feb 2017 20:16:34 -0500 +Subject: [PATCH] make skb_copy_datagram_msg() et.al. preserve ->msg_iter on + error + +commit 3278682123811dd8ef07de5eb701fc4548fcebf2 upstream. + +Fixes the mess observed in e.g. rsync over a noisy link we'd been +seeing since last Summer. What happens is that we copy part of +a datagram before noticing a checksum mismatch. Datagram will be +resent, all right, but we want the next try go into the same place, +not after it... + +All this family of primitives (copy/checksum and copy a datagram +into destination) is "all or nothing" sort of interface - either +we get 0 (meaning that copy had been successful) or we get an +error (and no way to tell how much had been copied before we ran +into whatever error it had been). Make all of them leave iterator +unadvanced in case of errors - all callers must be able to cope +with that (an error might've been caught before the iterator had +been advanced), it costs very little to arrange, it's safer for +callers and actually fixes at least one bug in said callers. + +Cc: stable@vger.kernel.org +Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> + +diff --git a/net/core/datagram.c b/net/core/datagram.c +index ea633342ab0d..f4947e737f34 100644 +--- a/net/core/datagram.c ++++ b/net/core/datagram.c +@@ -398,7 +398,7 @@ int skb_copy_datagram_iter(const struct sk_buff *skb, int offset, + struct iov_iter *to, int len) + { + int start = skb_headlen(skb); +- int i, copy = start - offset; ++ int i, copy = start - offset, start_off = offset, n; + struct sk_buff *frag_iter; + + trace_skb_copy_datagram_iovec(skb, len); +@@ -407,11 +407,12 @@ int skb_copy_datagram_iter(const struct sk_buff *skb, int offset, + if (copy > 0) { + if (copy > len) + copy = len; +- if (copy_to_iter(skb->data + offset, copy, to) != copy) ++ n = copy_to_iter(skb->data + offset, copy, to); ++ offset += n; ++ if (n != copy) + goto short_copy; + if ((len -= copy) == 0) + return 0; +- offset += copy; + } + + /* Copy paged appendix. Hmm... why does this look so complicated? */ +@@ -425,13 +426,14 @@ int skb_copy_datagram_iter(const struct sk_buff *skb, int offset, + if ((copy = end - offset) > 0) { + if (copy > len) + copy = len; +- if (copy_page_to_iter(skb_frag_page(frag), ++ n = copy_page_to_iter(skb_frag_page(frag), + frag->page_offset + offset - +- start, copy, to) != copy) ++ start, copy, to); ++ offset += n; ++ if (n != copy) + goto short_copy; + if (!(len -= copy)) + return 0; +- offset += copy; + } + start = end; + } +@@ -463,6 +465,7 @@ int skb_copy_datagram_iter(const struct sk_buff *skb, int offset, + */ + + fault: ++ iov_iter_revert(to, offset - start_off); + return -EFAULT; + + short_copy: +@@ -613,7 +616,7 @@ static int skb_copy_and_csum_datagram(const struct sk_buff *skb, int offset, + __wsum *csump) + { + int start = skb_headlen(skb); +- int i, copy = start - offset; ++ int i, copy = start - offset, start_off = offset; + struct sk_buff *frag_iter; + int pos = 0; + int n; +@@ -623,11 +626,11 @@ static int skb_copy_and_csum_datagram(const struct sk_buff *skb, int offset, + if (copy > len) + copy = len; + n = csum_and_copy_to_iter(skb->data + offset, copy, csump, to); ++ offset += n; + if (n != copy) + goto fault; + if ((len -= copy) == 0) + return 0; +- offset += copy; + pos = copy; + } + +@@ -649,12 +652,12 @@ static int skb_copy_and_csum_datagram(const struct sk_buff *skb, int offset, + offset - start, copy, + &csum2, to); + kunmap(page); ++ offset += n; + if (n != copy) + goto fault; + *csump = csum_block_add(*csump, csum2, pos); + if (!(len -= copy)) + return 0; +- offset += copy; + pos += copy; + } + start = end; +@@ -687,6 +690,7 @@ static int skb_copy_and_csum_datagram(const struct sk_buff *skb, int offset, + return 0; + + fault: ++ iov_iter_revert(to, offset - start_off); + return -EFAULT; + } + +@@ -771,6 +775,7 @@ int skb_copy_and_csum_datagram_msg(struct sk_buff *skb, + } + return 0; + csum_error: ++ iov_iter_revert(&msg->msg_iter, chunk); + return -EINVAL; + fault: + return -EFAULT; +-- +2.12.0 + diff --git a/queue/media-cxusb-Use-a-dma-capable-buffer-also-for-readin.patch b/queue/media-cxusb-Use-a-dma-capable-buffer-also-for-readin.patch new file mode 100644 index 0000000..0a85659 --- /dev/null +++ b/queue/media-cxusb-Use-a-dma-capable-buffer-also-for-readin.patch @@ -0,0 +1,60 @@ +From 3f190e3aec212fc8c61e202c51400afa7384d4bc Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20Br=C3=BCns?= <stefan.bruens@rwth-aachen.de> +Date: Sun, 5 Feb 2017 12:57:59 -0200 +Subject: [PATCH] [media] cxusb: Use a dma capable buffer also for reading +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit 3f190e3aec212fc8c61e202c51400afa7384d4bc upstream. + +Commit 17ce039b4e54 ("[media] cxusb: don't do DMA on stack") +added a kmalloc'ed bounce buffer for writes, but missed to do the same +for reads. As the read only happens after the write is finished, we can +reuse the same buffer. + +As dvb_usb_generic_rw handles a read length of 0 by itself, avoid calling +it using the dvb_usb_generic_read wrapper function. + +Signed-off-by: Stefan Brüns <stefan.bruens@rwth-aachen.de> +Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com> + +diff --git a/drivers/media/usb/dvb-usb/cxusb.c b/drivers/media/usb/dvb-usb/cxusb.c +index 5d7b4eaa6a3c..51620e02292f 100644 +--- a/drivers/media/usb/dvb-usb/cxusb.c ++++ b/drivers/media/usb/dvb-usb/cxusb.c +@@ -59,23 +59,24 @@ static int cxusb_ctrl_msg(struct dvb_usb_device *d, + u8 cmd, u8 *wbuf, int wlen, u8 *rbuf, int rlen) + { + struct cxusb_state *st = d->priv; +- int ret, wo; ++ int ret; + + if (1 + wlen > MAX_XFER_SIZE) { + warn("i2c wr: len=%d is too big!\n", wlen); + return -EOPNOTSUPP; + } + +- wo = (rbuf == NULL || rlen == 0); /* write-only */ ++ if (rlen > MAX_XFER_SIZE) { ++ warn("i2c rd: len=%d is too big!\n", rlen); ++ return -EOPNOTSUPP; ++ } + + mutex_lock(&d->data_mutex); + st->data[0] = cmd; + memcpy(&st->data[1], wbuf, wlen); +- if (wo) +- ret = dvb_usb_generic_write(d, st->data, 1 + wlen); +- else +- ret = dvb_usb_generic_rw(d, st->data, 1 + wlen, +- rbuf, rlen, 0); ++ ret = dvb_usb_generic_rw(d, st->data, 1 + wlen, st->data, rlen, 0); ++ if (!ret && rbuf && rlen) ++ memcpy(rbuf, st->data, rlen); + + mutex_unlock(&d->data_mutex); + return ret; +-- +2.12.0 + diff --git a/queue/media-dvb-usb-don-t-use-stack-for-firmware-load.patch b/queue/media-dvb-usb-don-t-use-stack-for-firmware-load.patch new file mode 100644 index 0000000..e8acae2 --- /dev/null +++ b/queue/media-dvb-usb-don-t-use-stack-for-firmware-load.patch @@ -0,0 +1,133 @@ +From 43fab9793c1f44e665b4f98035a14942edf03ddc Mon Sep 17 00:00:00 2001 +From: Mauro Carvalho Chehab <mchehab@s-opensource.com> +Date: Tue, 24 Jan 2017 08:13:11 -0200 +Subject: [PATCH] [media] dvb-usb: don't use stack for firmware load + +commit 43fab9793c1f44e665b4f98035a14942edf03ddc upstream. + +As reported by Marc Duponcheel <marc@offline.be>, firmware load on +dvb-usb is using the stack, with is not allowed anymore on default +Kernel configurations: + +[ 1025.958836] dvb-usb: found a 'WideView WT-220U PenType Receiver (based on ZL353)' in cold state, will try to load a firmware +[ 1025.958853] dvb-usb: downloading firmware from file 'dvb-usb-wt220u-zl0353-01.fw' +[ 1025.958855] dvb-usb: could not stop the USB controller CPU. +[ 1025.958856] dvb-usb: error while transferring firmware (transferred size: -11, block size: 3) +[ 1025.958856] dvb-usb: firmware download failed at 8 with -22 +[ 1025.958867] usbcore: registered new interface driver dvb_usb_dtt200u + +[ 2.789902] dvb-usb: downloading firmware from file 'dvb-usb-wt220u-zl0353-01.fw' +[ 2.789905] ------------[ cut here ]------------ +[ 2.789911] WARNING: CPU: 3 PID: 2196 at drivers/usb/core/hcd.c:1584 usb_hcd_map_urb_for_dma+0x430/0x560 [usbcore] +[ 2.789912] transfer buffer not dma capable +[ 2.789912] Modules linked in: btusb dvb_usb_dtt200u(+) dvb_usb_af9035(+) btrtl btbcm dvb_usb dvb_usb_v2 btintel dvb_core bluetooth rc_core rfkill x86_pkg_temp_thermal intel_powerclamp coretemp crc32_pclmul aesni_intel aes_x86_64 glue_helper lrw gf128mul ablk_helper cryptd drm_kms_helper syscopyarea sysfillrect pcspkr i2c_i801 sysimgblt fb_sys_fops drm i2c_smbus i2c_core r8169 lpc_ich mfd_core mii thermal fan rtc_cmos video button acpi_cpufreq processor snd_hda_codec_realtek snd_hda_codec_generic snd_hda_intel snd_hda_codec snd_hwdep snd_hda_core snd_pcm snd_timer snd crc32c_intel ahci libahci libata xhci_pci ehci_pci xhci_hcd ehci_hcd usbcore usb_common dm_mirror dm_region_hash dm_log dm_mod +[ 2.789936] CPU: 3 PID: 2196 Comm: systemd-udevd Not tainted 4.9.0-gentoo #1 +[ 2.789937] Hardware name: ASUS All Series/H81I-PLUS, BIOS 0401 07/23/2013 +[ 2.789938] ffffc9000339b690 ffffffff812bd397 ffffc9000339b6e0 0000000000000000 +[ 2.789939] ffffc9000339b6d0 ffffffff81055c86 000006300339b6a0 ffff880116c0c000 +[ 2.789941] 0000000000000000 0000000000000000 0000000000000001 ffff880116c08000 +[ 2.789942] Call Trace: +[ 2.789945] [<ffffffff812bd397>] dump_stack+0x4d/0x66 +[ 2.789947] [<ffffffff81055c86>] __warn+0xc6/0xe0 +[ 2.789948] [<ffffffff81055cea>] warn_slowpath_fmt+0x4a/0x50 +[ 2.789952] [<ffffffffa006d460>] usb_hcd_map_urb_for_dma+0x430/0x560 [usbcore] +[ 2.789954] [<ffffffff814ed5a8>] ? io_schedule_timeout+0xd8/0x110 +[ 2.789956] [<ffffffffa006e09c>] usb_hcd_submit_urb+0x9c/0x980 [usbcore] +[ 2.789958] [<ffffffff812d0ebf>] ? copy_page_to_iter+0x14f/0x2b0 +[ 2.789960] [<ffffffff81126818>] ? pagecache_get_page+0x28/0x240 +[ 2.789962] [<ffffffff8118c2a0>] ? touch_atime+0x20/0xa0 +[ 2.789964] [<ffffffffa006f7c4>] usb_submit_urb+0x2c4/0x520 [usbcore] +[ 2.789967] [<ffffffffa006feca>] usb_start_wait_urb+0x5a/0xe0 [usbcore] +[ 2.789969] [<ffffffffa007000c>] usb_control_msg+0xbc/0xf0 [usbcore] +[ 2.789970] [<ffffffffa067903d>] usb_cypress_writemem+0x3d/0x40 [dvb_usb] +[ 2.789972] [<ffffffffa06791cf>] usb_cypress_load_firmware+0x4f/0x130 [dvb_usb] +[ 2.789973] [<ffffffff8109dbbe>] ? console_unlock+0x2fe/0x5d0 +[ 2.789974] [<ffffffff8109e10c>] ? vprintk_emit+0x27c/0x410 +[ 2.789975] [<ffffffff8109e40a>] ? vprintk_default+0x1a/0x20 +[ 2.789976] [<ffffffff81124d76>] ? printk+0x43/0x4b +[ 2.789977] [<ffffffffa0679310>] dvb_usb_download_firmware+0x60/0xd0 [dvb_usb] +[ 2.789979] [<ffffffffa0679898>] dvb_usb_device_init+0x3d8/0x610 [dvb_usb] +[ 2.789981] [<ffffffffa069e302>] dtt200u_usb_probe+0x92/0xd0 [dvb_usb_dtt200u] +[ 2.789984] [<ffffffffa007420c>] usb_probe_interface+0xfc/0x270 [usbcore] +[ 2.789985] [<ffffffff8138bf95>] driver_probe_device+0x215/0x2d0 +[ 2.789986] [<ffffffff8138c0e6>] __driver_attach+0x96/0xa0 +[ 2.789987] [<ffffffff8138c050>] ? driver_probe_device+0x2d0/0x2d0 +[ 2.789988] [<ffffffff81389ffb>] bus_for_each_dev+0x5b/0x90 +[ 2.789989] [<ffffffff8138b7b9>] driver_attach+0x19/0x20 +[ 2.789990] [<ffffffff8138b33c>] bus_add_driver+0x11c/0x220 +[ 2.789991] [<ffffffff8138c91b>] driver_register+0x5b/0xd0 +[ 2.789994] [<ffffffffa0072f6c>] usb_register_driver+0x7c/0x130 [usbcore] +[ 2.789994] [<ffffffffa06a5000>] ? 0xffffffffa06a5000 +[ 2.789996] [<ffffffffa06a501e>] dtt200u_usb_driver_init+0x1e/0x20 [dvb_usb_dtt200u] +[ 2.789997] [<ffffffff81000408>] do_one_initcall+0x38/0x140 +[ 2.789998] [<ffffffff8116001c>] ? __vunmap+0x7c/0xc0 +[ 2.789999] [<ffffffff81124fb0>] ? do_init_module+0x22/0x1d2 +[ 2.790000] [<ffffffff81124fe8>] do_init_module+0x5a/0x1d2 +[ 2.790002] [<ffffffff810c96b1>] load_module+0x1e11/0x2580 +[ 2.790003] [<ffffffff810c68b0>] ? show_taint+0x30/0x30 +[ 2.790004] [<ffffffff81177250>] ? kernel_read_file+0x100/0x190 +[ 2.790005] [<ffffffff810c9ffa>] SyS_finit_module+0xba/0xc0 +[ 2.790007] [<ffffffff814f13e0>] entry_SYSCALL_64_fastpath+0x13/0x94 +[ 2.790008] ---[ end trace c78a74e78baec6fc ]--- + +So, allocate the structure dynamically. + +Cc: stable@vger.kernel.org # Kernel 4.9+ +Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com> + +diff --git a/drivers/media/usb/dvb-usb/dvb-usb-firmware.c b/drivers/media/usb/dvb-usb/dvb-usb-firmware.c +index f0023dbb7276..ab9866024ec7 100644 +--- a/drivers/media/usb/dvb-usb/dvb-usb-firmware.c ++++ b/drivers/media/usb/dvb-usb/dvb-usb-firmware.c +@@ -35,28 +35,33 @@ static int usb_cypress_writemem(struct usb_device *udev,u16 addr,u8 *data, u8 le + + int usb_cypress_load_firmware(struct usb_device *udev, const struct firmware *fw, int type) + { +- struct hexline hx; ++ struct hexline *hx; + u8 reset; + int ret,pos=0; + ++ hx = kmalloc(sizeof(*hx), GFP_KERNEL); ++ if (!hx) ++ return -ENOMEM; ++ + /* stop the CPU */ + reset = 1; + if ((ret = usb_cypress_writemem(udev,cypress[type].cpu_cs_register,&reset,1)) != 1) + err("could not stop the USB controller CPU."); + +- while ((ret = dvb_usb_get_hexline(fw,&hx,&pos)) > 0) { +- deb_fw("writing to address 0x%04x (buffer: 0x%02x %02x)\n",hx.addr,hx.len,hx.chk); +- ret = usb_cypress_writemem(udev,hx.addr,hx.data,hx.len); ++ while ((ret = dvb_usb_get_hexline(fw, hx, &pos)) > 0) { ++ deb_fw("writing to address 0x%04x (buffer: 0x%02x %02x)\n", hx->addr, hx->len, hx->chk); ++ ret = usb_cypress_writemem(udev, hx->addr, hx->data, hx->len); + +- if (ret != hx.len) { ++ if (ret != hx->len) { + err("error while transferring firmware (transferred size: %d, block size: %d)", +- ret,hx.len); ++ ret, hx->len); + ret = -EINVAL; + break; + } + } + if (ret < 0) { + err("firmware download failed at %d with %d",pos,ret); ++ kfree(hx); + return ret; + } + +@@ -70,6 +75,8 @@ int usb_cypress_load_firmware(struct usb_device *udev, const struct firmware *fw + } else + ret = -EIO; + ++ kfree(hx); ++ + return ret; + } + EXPORT_SYMBOL(usb_cypress_load_firmware); +-- +2.12.0 + diff --git a/queue/media-dvb-usb-firmware-don-t-do-DMA-on-stack.patch b/queue/media-dvb-usb-firmware-don-t-do-DMA-on-stack.patch new file mode 100644 index 0000000..c56f173 --- /dev/null +++ b/queue/media-dvb-usb-firmware-don-t-do-DMA-on-stack.patch @@ -0,0 +1,77 @@ +From 67b0503db9c29b04eadfeede6bebbfe5ddad94ef Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20Br=C3=BCns?= <stefan.bruens@rwth-aachen.de> +Date: Sun, 12 Feb 2017 13:02:13 -0200 +Subject: [PATCH] [media] dvb-usb-firmware: don't do DMA on stack +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit 67b0503db9c29b04eadfeede6bebbfe5ddad94ef upstream. + +The buffer allocation for the firmware data was changed in +commit 43fab9793c1f ("[media] dvb-usb: don't use stack for firmware load") +but the same applies for the reset value. + +Fixes: 43fab9793c1f ("[media] dvb-usb: don't use stack for firmware load") +Cc: stable@vger.kernel.org +Signed-off-by: Stefan Brüns <stefan.bruens@rwth-aachen.de> +Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com> + +diff --git a/drivers/media/usb/dvb-usb/dvb-usb-firmware.c b/drivers/media/usb/dvb-usb/dvb-usb-firmware.c +index ab9866024ec7..04033efe7ad5 100644 +--- a/drivers/media/usb/dvb-usb/dvb-usb-firmware.c ++++ b/drivers/media/usb/dvb-usb/dvb-usb-firmware.c +@@ -36,16 +36,18 @@ static int usb_cypress_writemem(struct usb_device *udev,u16 addr,u8 *data, u8 le + int usb_cypress_load_firmware(struct usb_device *udev, const struct firmware *fw, int type) + { + struct hexline *hx; +- u8 reset; +- int ret,pos=0; ++ u8 *buf; ++ int ret, pos = 0; ++ u16 cpu_cs_register = cypress[type].cpu_cs_register; + +- hx = kmalloc(sizeof(*hx), GFP_KERNEL); +- if (!hx) ++ buf = kmalloc(sizeof(*hx), GFP_KERNEL); ++ if (!buf) + return -ENOMEM; ++ hx = (struct hexline *)buf; + + /* stop the CPU */ +- reset = 1; +- if ((ret = usb_cypress_writemem(udev,cypress[type].cpu_cs_register,&reset,1)) != 1) ++ buf[0] = 1; ++ if (usb_cypress_writemem(udev, cpu_cs_register, buf, 1) != 1) + err("could not stop the USB controller CPU."); + + while ((ret = dvb_usb_get_hexline(fw, hx, &pos)) > 0) { +@@ -61,21 +63,21 @@ int usb_cypress_load_firmware(struct usb_device *udev, const struct firmware *fw + } + if (ret < 0) { + err("firmware download failed at %d with %d",pos,ret); +- kfree(hx); ++ kfree(buf); + return ret; + } + + if (ret == 0) { + /* restart the CPU */ +- reset = 0; +- if (ret || usb_cypress_writemem(udev,cypress[type].cpu_cs_register,&reset,1) != 1) { ++ buf[0] = 0; ++ if (usb_cypress_writemem(udev, cpu_cs_register, buf, 1) != 1) { + err("could not restart the USB controller CPU."); + ret = -EINVAL; + } + } else + ret = -EIO; + +- kfree(hx); ++ kfree(buf); + + return ret; + } +-- +2.12.0 + diff --git a/queue/media-dvb-usb-v2-avoid-use-after-free.patch b/queue/media-dvb-usb-v2-avoid-use-after-free.patch new file mode 100644 index 0000000..25a8106 --- /dev/null +++ b/queue/media-dvb-usb-v2-avoid-use-after-free.patch @@ -0,0 +1,56 @@ +From 005145378c9ad7575a01b6ce1ba118fb427f583a Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann <arnd@arndb.de> +Date: Thu, 2 Feb 2017 12:36:01 -0200 +Subject: [PATCH] [media] dvb-usb-v2: avoid use-after-free + +commit 005145378c9ad7575a01b6ce1ba118fb427f583a upstream. + +I ran into a stack frame size warning because of the on-stack copy of +the USB device structure: + +drivers/media/usb/dvb-usb-v2/dvb_usb_core.c: In function 'dvb_usbv2_disconnect': +drivers/media/usb/dvb-usb-v2/dvb_usb_core.c:1029:1: error: the frame size of 1104 bytes is larger than 1024 bytes [-Werror=frame-larger-than=] + +Copying a device structure like this is wrong for a number of other reasons +too aside from the possible stack overflow. One of them is that the +dev_info() call will print the name of the device later, but AFAICT +we have only copied a pointer to the name earlier and the actual name +has been freed by the time it gets printed. + +This removes the on-stack copy of the device and instead copies the +device name using kstrdup(). I'm ignoring the possible failure here +as both printk() and kfree() are able to deal with NULL pointers. + +Signed-off-by: Arnd Bergmann <arnd@arndb.de> +Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com> + +diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c +index 298c91a6f1f9..955fb0d07507 100644 +--- a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c ++++ b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c +@@ -1012,8 +1012,8 @@ EXPORT_SYMBOL(dvb_usbv2_probe); + void dvb_usbv2_disconnect(struct usb_interface *intf) + { + struct dvb_usb_device *d = usb_get_intfdata(intf); +- const char *name = d->name; +- struct device dev = d->udev->dev; ++ const char *devname = kstrdup(dev_name(&d->udev->dev), GFP_KERNEL); ++ const char *drvname = d->name; + + dev_dbg(&d->udev->dev, "%s: bInterfaceNumber=%d\n", __func__, + intf->cur_altsetting->desc.bInterfaceNumber); +@@ -1023,8 +1023,9 @@ void dvb_usbv2_disconnect(struct usb_interface *intf) + + dvb_usbv2_exit(d); + +- dev_info(&dev, "%s: '%s' successfully deinitialized and disconnected\n", +- KBUILD_MODNAME, name); ++ pr_info("%s: '%s:%s' successfully deinitialized and disconnected\n", ++ KBUILD_MODNAME, drvname, devname); ++ kfree(devname); + } + EXPORT_SYMBOL(dvb_usbv2_disconnect); + +-- +2.12.0 + diff --git a/queue/metag-usercopy-Add-early-abort-to-copy_to_user.patch b/queue/metag-usercopy-Add-early-abort-to-copy_to_user.patch new file mode 100644 index 0000000..44c2b37 --- /dev/null +++ b/queue/metag-usercopy-Add-early-abort-to-copy_to_user.patch @@ -0,0 +1,102 @@ +From fb8ea062a8f2e85256e13f55696c5c5f0dfdcc8b Mon Sep 17 00:00:00 2001 +From: James Hogan <james.hogan@imgtec.com> +Date: Fri, 31 Mar 2017 13:35:01 +0100 +Subject: [PATCH] metag/usercopy: Add early abort to copy_to_user + +commit fb8ea062a8f2e85256e13f55696c5c5f0dfdcc8b upstream. + +When copying to userland on Meta, if any faults are encountered +immediately abort the copy instead of continuing on and repeatedly +faulting, and worse potentially copying further bytes successfully to +subsequent valid pages. + +Fixes: 373cd784d0fc ("metag: Memory handling") +Reported-by: Al Viro <viro@zeniv.linux.org.uk> +Signed-off-by: James Hogan <james.hogan@imgtec.com> +Cc: linux-metag@vger.kernel.org +Cc: stable@vger.kernel.org + +diff --git a/arch/metag/lib/usercopy.c b/arch/metag/lib/usercopy.c +index a6ced9691ddb..714d8562aa20 100644 +--- a/arch/metag/lib/usercopy.c ++++ b/arch/metag/lib/usercopy.c +@@ -538,23 +538,31 @@ unsigned long __copy_user(void __user *pdst, const void *psrc, + if ((unsigned long) src & 1) { + __asm_copy_to_user_1(dst, src, retn); + n--; ++ if (retn) ++ return retn + n; + } + if ((unsigned long) dst & 1) { + /* Worst case - byte copy */ + while (n > 0) { + __asm_copy_to_user_1(dst, src, retn); + n--; ++ if (retn) ++ return retn + n; + } + } + if (((unsigned long) src & 2) && n >= 2) { + __asm_copy_to_user_2(dst, src, retn); + n -= 2; ++ if (retn) ++ return retn + n; + } + if ((unsigned long) dst & 2) { + /* Second worst case - word copy */ + while (n >= 2) { + __asm_copy_to_user_2(dst, src, retn); + n -= 2; ++ if (retn) ++ return retn + n; + } + } + +@@ -569,6 +577,8 @@ unsigned long __copy_user(void __user *pdst, const void *psrc, + while (n >= 8) { + __asm_copy_to_user_8x64(dst, src, retn); + n -= 8; ++ if (retn) ++ return retn + n; + } + } + if (n >= RAPF_MIN_BUF_SIZE) { +@@ -581,6 +591,8 @@ unsigned long __copy_user(void __user *pdst, const void *psrc, + while (n >= 8) { + __asm_copy_to_user_8x64(dst, src, retn); + n -= 8; ++ if (retn) ++ return retn + n; + } + } + #endif +@@ -588,11 +600,15 @@ unsigned long __copy_user(void __user *pdst, const void *psrc, + while (n >= 16) { + __asm_copy_to_user_16(dst, src, retn); + n -= 16; ++ if (retn) ++ return retn + n; + } + + while (n >= 4) { + __asm_copy_to_user_4(dst, src, retn); + n -= 4; ++ if (retn) ++ return retn + n; + } + + switch (n) { +@@ -609,6 +625,10 @@ unsigned long __copy_user(void __user *pdst, const void *psrc, + break; + } + ++ /* ++ * If we get here, retn correctly reflects the number of failing ++ * bytes. ++ */ + return retn; + } + EXPORT_SYMBOL(__copy_user); +-- +2.12.0 + diff --git a/queue/metag-usercopy-Add-missing-fixups.patch b/queue/metag-usercopy-Add-missing-fixups.patch new file mode 100644 index 0000000..c5a3adf --- /dev/null +++ b/queue/metag-usercopy-Add-missing-fixups.patch @@ -0,0 +1,166 @@ +From b884a190afcecdbef34ca508ea5ee88bb7c77861 Mon Sep 17 00:00:00 2001 +From: James Hogan <james.hogan@imgtec.com> +Date: Tue, 4 Apr 2017 08:51:34 +0100 +Subject: [PATCH] metag/usercopy: Add missing fixups + +commit b884a190afcecdbef34ca508ea5ee88bb7c77861 upstream. + +The rapf copy loops in the Meta usercopy code is missing some extable +entries for HTP cores with unaligned access checking enabled, where +faults occur on the instruction immediately after the faulting access. + +Add the fixup labels and extable entries for these cases so that corner +case user copy failures don't cause kernel crashes. + +Fixes: 373cd784d0fc ("metag: Memory handling") +Signed-off-by: James Hogan <james.hogan@imgtec.com> +Cc: linux-metag@vger.kernel.org +Cc: stable@vger.kernel.org + +diff --git a/arch/metag/lib/usercopy.c b/arch/metag/lib/usercopy.c +index e09c95ba028c..2792fc621088 100644 +--- a/arch/metag/lib/usercopy.c ++++ b/arch/metag/lib/usercopy.c +@@ -259,27 +259,31 @@ + "MGETL D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ + "22:\n" \ + "MSETL [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ +- "SUB %3, %3, #32\n" \ + "23:\n" \ +- "MGETL D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ ++ "SUB %3, %3, #32\n" \ + "24:\n" \ ++ "MGETL D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ ++ "25:\n" \ + "MSETL [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ ++ "26:\n" \ + "SUB %3, %3, #32\n" \ + "DCACHE [%1+#-64], D0Ar6\n" \ + "BR $Lloop"id"\n" \ + \ + "MOV RAPF, %1\n" \ +- "25:\n" \ ++ "27:\n" \ + "MGETL D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ +- "26:\n" \ ++ "28:\n" \ + "MSETL [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ ++ "29:\n" \ + "SUB %3, %3, #32\n" \ +- "27:\n" \ ++ "30:\n" \ + "MGETL D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ +- "28:\n" \ ++ "31:\n" \ + "MSETL [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ ++ "32:\n" \ + "SUB %0, %0, #8\n" \ +- "29:\n" \ ++ "33:\n" \ + "SETL [%0++], D0.7, D1.7\n" \ + "SUB %3, %3, #32\n" \ + "1:" \ +@@ -311,7 +315,11 @@ + " .long 26b,3b\n" \ + " .long 27b,3b\n" \ + " .long 28b,3b\n" \ +- " .long 29b,4b\n" \ ++ " .long 29b,3b\n" \ ++ " .long 30b,3b\n" \ ++ " .long 31b,3b\n" \ ++ " .long 32b,3b\n" \ ++ " .long 33b,4b\n" \ + " .previous\n" \ + : "=r" (to), "=r" (from), "=r" (ret), "=d" (n) \ + : "0" (to), "1" (from), "2" (ret), "3" (n) \ +@@ -402,47 +410,55 @@ + "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ + "22:\n" \ + "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ +- "SUB %3, %3, #16\n" \ + "23:\n" \ +- "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ +- "24:\n" \ +- "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ + "SUB %3, %3, #16\n" \ +- "25:\n" \ ++ "24:\n" \ + "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ +- "26:\n" \ ++ "25:\n" \ + "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ ++ "26:\n" \ + "SUB %3, %3, #16\n" \ + "27:\n" \ + "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ + "28:\n" \ + "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ ++ "29:\n" \ ++ "SUB %3, %3, #16\n" \ ++ "30:\n" \ ++ "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ ++ "31:\n" \ ++ "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ ++ "32:\n" \ + "SUB %3, %3, #16\n" \ + "DCACHE [%1+#-64], D0Ar6\n" \ + "BR $Lloop"id"\n" \ + \ + "MOV RAPF, %1\n" \ +- "29:\n" \ ++ "33:\n" \ + "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ +- "30:\n" \ ++ "34:\n" \ + "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ ++ "35:\n" \ + "SUB %3, %3, #16\n" \ +- "31:\n" \ ++ "36:\n" \ + "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ +- "32:\n" \ ++ "37:\n" \ + "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ ++ "38:\n" \ + "SUB %3, %3, #16\n" \ +- "33:\n" \ ++ "39:\n" \ + "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ +- "34:\n" \ ++ "40:\n" \ + "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ ++ "41:\n" \ + "SUB %3, %3, #16\n" \ +- "35:\n" \ ++ "42:\n" \ + "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ +- "36:\n" \ ++ "43:\n" \ + "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ ++ "44:\n" \ + "SUB %0, %0, #4\n" \ +- "37:\n" \ ++ "45:\n" \ + "SETD [%0++], D0.7\n" \ + "SUB %3, %3, #16\n" \ + "1:" \ +@@ -482,7 +498,15 @@ + " .long 34b,3b\n" \ + " .long 35b,3b\n" \ + " .long 36b,3b\n" \ +- " .long 37b,4b\n" \ ++ " .long 37b,3b\n" \ ++ " .long 38b,3b\n" \ ++ " .long 39b,3b\n" \ ++ " .long 40b,3b\n" \ ++ " .long 41b,3b\n" \ ++ " .long 42b,3b\n" \ ++ " .long 43b,3b\n" \ ++ " .long 44b,3b\n" \ ++ " .long 45b,4b\n" \ + " .previous\n" \ + : "=r" (to), "=r" (from), "=r" (ret), "=d" (n) \ + : "0" (to), "1" (from), "2" (ret), "3" (n) \ +-- +2.12.0 + diff --git a/queue/metag-usercopy-Drop-unused-macros.patch b/queue/metag-usercopy-Drop-unused-macros.patch new file mode 100644 index 0000000..09bf277 --- /dev/null +++ b/queue/metag-usercopy-Drop-unused-macros.patch @@ -0,0 +1,143 @@ +From ef62a2d81f73d9cddef14bc3d9097a57010d551c Mon Sep 17 00:00:00 2001 +From: James Hogan <james.hogan@imgtec.com> +Date: Fri, 31 Mar 2017 10:37:44 +0100 +Subject: [PATCH] metag/usercopy: Drop unused macros + +commit ef62a2d81f73d9cddef14bc3d9097a57010d551c upstream. + +Metag's lib/usercopy.c has a bunch of copy_from_user macros for larger +copies between 5 and 16 bytes which are completely unused. Before fixing +zeroing lets drop these macros so there is less to fix. + +Signed-off-by: James Hogan <james.hogan@imgtec.com> +Cc: Al Viro <viro@zeniv.linux.org.uk> +Cc: linux-metag@vger.kernel.org +Cc: stable@vger.kernel.org + +diff --git a/arch/metag/lib/usercopy.c b/arch/metag/lib/usercopy.c +index b3ebfe9c8e88..b4eb1f17069f 100644 +--- a/arch/metag/lib/usercopy.c ++++ b/arch/metag/lib/usercopy.c +@@ -651,119 +651,6 @@ EXPORT_SYMBOL(__copy_user); + #define __asm_copy_from_user_4(to, from, ret) \ + __asm_copy_from_user_4x_cont(to, from, ret, "", "", "") + +-#define __asm_copy_from_user_5(to, from, ret) \ +- __asm_copy_from_user_4x_cont(to, from, ret, \ +- " GETB D1Ar1,[%1++]\n" \ +- "4: SETB [%0++],D1Ar1\n", \ +- "5: ADD %2,%2,#1\n" \ +- " SETB [%0++],D1Ar1\n", \ +- " .long 4b,5b\n") +- +-#define __asm_copy_from_user_6x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ +- __asm_copy_from_user_4x_cont(to, from, ret, \ +- " GETW D1Ar1,[%1++]\n" \ +- "4: SETW [%0++],D1Ar1\n" COPY, \ +- "5: ADD %2,%2,#2\n" \ +- " SETW [%0++],D1Ar1\n" FIXUP, \ +- " .long 4b,5b\n" TENTRY) +- +-#define __asm_copy_from_user_6(to, from, ret) \ +- __asm_copy_from_user_6x_cont(to, from, ret, "", "", "") +- +-#define __asm_copy_from_user_7(to, from, ret) \ +- __asm_copy_from_user_6x_cont(to, from, ret, \ +- " GETB D1Ar1,[%1++]\n" \ +- "6: SETB [%0++],D1Ar1\n", \ +- "7: ADD %2,%2,#1\n" \ +- " SETB [%0++],D1Ar1\n", \ +- " .long 6b,7b\n") +- +-#define __asm_copy_from_user_8x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ +- __asm_copy_from_user_4x_cont(to, from, ret, \ +- " GETD D1Ar1,[%1++]\n" \ +- "4: SETD [%0++],D1Ar1\n" COPY, \ +- "5: ADD %2,%2,#4\n" \ +- " SETD [%0++],D1Ar1\n" FIXUP, \ +- " .long 4b,5b\n" TENTRY) +- +-#define __asm_copy_from_user_8(to, from, ret) \ +- __asm_copy_from_user_8x_cont(to, from, ret, "", "", "") +- +-#define __asm_copy_from_user_9(to, from, ret) \ +- __asm_copy_from_user_8x_cont(to, from, ret, \ +- " GETB D1Ar1,[%1++]\n" \ +- "6: SETB [%0++],D1Ar1\n", \ +- "7: ADD %2,%2,#1\n" \ +- " SETB [%0++],D1Ar1\n", \ +- " .long 6b,7b\n") +- +-#define __asm_copy_from_user_10x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ +- __asm_copy_from_user_8x_cont(to, from, ret, \ +- " GETW D1Ar1,[%1++]\n" \ +- "6: SETW [%0++],D1Ar1\n" COPY, \ +- "7: ADD %2,%2,#2\n" \ +- " SETW [%0++],D1Ar1\n" FIXUP, \ +- " .long 6b,7b\n" TENTRY) +- +-#define __asm_copy_from_user_10(to, from, ret) \ +- __asm_copy_from_user_10x_cont(to, from, ret, "", "", "") +- +-#define __asm_copy_from_user_11(to, from, ret) \ +- __asm_copy_from_user_10x_cont(to, from, ret, \ +- " GETB D1Ar1,[%1++]\n" \ +- "8: SETB [%0++],D1Ar1\n", \ +- "9: ADD %2,%2,#1\n" \ +- " SETB [%0++],D1Ar1\n", \ +- " .long 8b,9b\n") +- +-#define __asm_copy_from_user_12x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ +- __asm_copy_from_user_8x_cont(to, from, ret, \ +- " GETD D1Ar1,[%1++]\n" \ +- "6: SETD [%0++],D1Ar1\n" COPY, \ +- "7: ADD %2,%2,#4\n" \ +- " SETD [%0++],D1Ar1\n" FIXUP, \ +- " .long 6b,7b\n" TENTRY) +- +-#define __asm_copy_from_user_12(to, from, ret) \ +- __asm_copy_from_user_12x_cont(to, from, ret, "", "", "") +- +-#define __asm_copy_from_user_13(to, from, ret) \ +- __asm_copy_from_user_12x_cont(to, from, ret, \ +- " GETB D1Ar1,[%1++]\n" \ +- "8: SETB [%0++],D1Ar1\n", \ +- "9: ADD %2,%2,#1\n" \ +- " SETB [%0++],D1Ar1\n", \ +- " .long 8b,9b\n") +- +-#define __asm_copy_from_user_14x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ +- __asm_copy_from_user_12x_cont(to, from, ret, \ +- " GETW D1Ar1,[%1++]\n" \ +- "8: SETW [%0++],D1Ar1\n" COPY, \ +- "9: ADD %2,%2,#2\n" \ +- " SETW [%0++],D1Ar1\n" FIXUP, \ +- " .long 8b,9b\n" TENTRY) +- +-#define __asm_copy_from_user_14(to, from, ret) \ +- __asm_copy_from_user_14x_cont(to, from, ret, "", "", "") +- +-#define __asm_copy_from_user_15(to, from, ret) \ +- __asm_copy_from_user_14x_cont(to, from, ret, \ +- " GETB D1Ar1,[%1++]\n" \ +- "10: SETB [%0++],D1Ar1\n", \ +- "11: ADD %2,%2,#1\n" \ +- " SETB [%0++],D1Ar1\n", \ +- " .long 10b,11b\n") +- +-#define __asm_copy_from_user_16x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ +- __asm_copy_from_user_12x_cont(to, from, ret, \ +- " GETD D1Ar1,[%1++]\n" \ +- "8: SETD [%0++],D1Ar1\n" COPY, \ +- "9: ADD %2,%2,#4\n" \ +- " SETD [%0++],D1Ar1\n" FIXUP, \ +- " .long 8b,9b\n" TENTRY) +- +-#define __asm_copy_from_user_16(to, from, ret) \ +- __asm_copy_from_user_16x_cont(to, from, ret, "", "", "") + + #define __asm_copy_from_user_8x64(to, from, ret) \ + asm volatile ( \ +-- +2.12.0 + diff --git a/queue/metag-usercopy-Fix-alignment-error-checking.patch b/queue/metag-usercopy-Fix-alignment-error-checking.patch new file mode 100644 index 0000000..3622718 --- /dev/null +++ b/queue/metag-usercopy-Fix-alignment-error-checking.patch @@ -0,0 +1,60 @@ +From 2257211942bbbf6c798ab70b487d7e62f7835a1a Mon Sep 17 00:00:00 2001 +From: James Hogan <james.hogan@imgtec.com> +Date: Fri, 31 Mar 2017 11:23:18 +0100 +Subject: [PATCH] metag/usercopy: Fix alignment error checking + +commit 2257211942bbbf6c798ab70b487d7e62f7835a1a upstream. + +Fix the error checking of the alignment adjustment code in +raw_copy_from_user(), which mistakenly considers it safe to skip the +error check when aligning the source buffer on a 2 or 4 byte boundary. + +If the destination buffer was unaligned it may have started to copy +using byte or word accesses, which could well be at the start of a new +(valid) source page. This would result in it appearing to have copied 1 +or 2 bytes at the end of the first (invalid) page rather than none at +all. + +Fixes: 373cd784d0fc ("metag: Memory handling") +Signed-off-by: James Hogan <james.hogan@imgtec.com> +Cc: linux-metag@vger.kernel.org +Cc: stable@vger.kernel.org + +diff --git a/arch/metag/lib/usercopy.c b/arch/metag/lib/usercopy.c +index b4eb1f17069f..a6ced9691ddb 100644 +--- a/arch/metag/lib/usercopy.c ++++ b/arch/metag/lib/usercopy.c +@@ -717,6 +717,8 @@ unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc, + if ((unsigned long) src & 1) { + __asm_copy_from_user_1(dst, src, retn); + n--; ++ if (retn) ++ goto copy_exception_bytes; + } + if ((unsigned long) dst & 1) { + /* Worst case - byte copy */ +@@ -730,6 +732,8 @@ unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc, + if (((unsigned long) src & 2) && n >= 2) { + __asm_copy_from_user_2(dst, src, retn); + n -= 2; ++ if (retn) ++ goto copy_exception_bytes; + } + if ((unsigned long) dst & 2) { + /* Second worst case - word copy */ +@@ -741,12 +745,6 @@ unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc, + } + } + +- /* We only need one check after the unalignment-adjustments, +- because if both adjustments were done, either both or +- neither reference had an exception. */ +- if (retn != 0) +- goto copy_exception_bytes; +- + #ifdef USE_RAPF + /* 64 bit copy loop */ + if (!(((unsigned long) src | (unsigned long) dst) & 7)) { +-- +2.12.0 + diff --git a/queue/metag-usercopy-Fix-src-fixup-in-from-user-rapf-loops.patch b/queue/metag-usercopy-Fix-src-fixup-in-from-user-rapf-loops.patch new file mode 100644 index 0000000..5762e82 --- /dev/null +++ b/queue/metag-usercopy-Fix-src-fixup-in-from-user-rapf-loops.patch @@ -0,0 +1,88 @@ +From 2c0b1df88b987a12d95ea1d6beaf01894f3cc725 Mon Sep 17 00:00:00 2001 +From: James Hogan <james.hogan@imgtec.com> +Date: Mon, 3 Apr 2017 17:41:40 +0100 +Subject: [PATCH] metag/usercopy: Fix src fixup in from user rapf loops + +commit 2c0b1df88b987a12d95ea1d6beaf01894f3cc725 upstream. + +The fixup code to rewind the source pointer in +__asm_copy_from_user_{32,64}bit_rapf_loop() always rewound the source by +a single unit (4 or 8 bytes), however this is insufficient if the fault +didn't occur on the first load in the loop, as the source pointer will +have been incremented but nothing will have been stored until all 4 +register [pairs] are loaded. + +Read the LSM_STEP field of TXSTATUS (which is already loaded into a +register), a bit like the copy_to_user versions, to determine how many +iterations of MGET[DL] have taken place, all of which need rewinding. + +Fixes: 373cd784d0fc ("metag: Memory handling") +Signed-off-by: James Hogan <james.hogan@imgtec.com> +Cc: linux-metag@vger.kernel.org +Cc: stable@vger.kernel.org + +diff --git a/arch/metag/lib/usercopy.c b/arch/metag/lib/usercopy.c +index 4422928a1746..e09c95ba028c 100644 +--- a/arch/metag/lib/usercopy.c ++++ b/arch/metag/lib/usercopy.c +@@ -687,29 +687,49 @@ EXPORT_SYMBOL(__copy_user); + * + * Rationale: + * A fault occurs while reading from user buffer, which is the +- * source. Since the fault is at a single address, we only +- * need to rewind by 8 bytes. ++ * source. + * Since we don't write to kernel buffer until we read first, + * the kernel buffer is at the right state and needn't be +- * corrected. ++ * corrected, but the source must be rewound to the beginning of ++ * the block, which is LSM_STEP*8 bytes. ++ * LSM_STEP is bits 10:8 in TXSTATUS which is already read ++ * and stored in D0Ar2 ++ * ++ * NOTE: If a fault occurs at the last operation in M{G,S}ETL ++ * LSM_STEP will be 0. ie: we do 4 writes in our case, if ++ * a fault happens at the 4th write, LSM_STEP will be 0 ++ * instead of 4. The code copes with that. + */ + #define __asm_copy_from_user_64bit_rapf_loop(to, from, ret, n, id) \ + __asm_copy_user_64bit_rapf_loop(to, from, ret, n, id, \ +- "SUB %1, %1, #8\n") ++ "LSR D0Ar2, D0Ar2, #5\n" \ ++ "ANDS D0Ar2, D0Ar2, #0x38\n" \ ++ "ADDZ D0Ar2, D0Ar2, #32\n" \ ++ "SUB %1, %1, D0Ar2\n") + + /* rewind 'from' pointer when a fault occurs + * + * Rationale: + * A fault occurs while reading from user buffer, which is the +- * source. Since the fault is at a single address, we only +- * need to rewind by 4 bytes. ++ * source. + * Since we don't write to kernel buffer until we read first, + * the kernel buffer is at the right state and needn't be +- * corrected. ++ * corrected, but the source must be rewound to the beginning of ++ * the block, which is LSM_STEP*4 bytes. ++ * LSM_STEP is bits 10:8 in TXSTATUS which is already read ++ * and stored in D0Ar2 ++ * ++ * NOTE: If a fault occurs at the last operation in M{G,S}ETL ++ * LSM_STEP will be 0. ie: we do 4 writes in our case, if ++ * a fault happens at the 4th write, LSM_STEP will be 0 ++ * instead of 4. The code copes with that. + */ + #define __asm_copy_from_user_32bit_rapf_loop(to, from, ret, n, id) \ + __asm_copy_user_32bit_rapf_loop(to, from, ret, n, id, \ +- "SUB %1, %1, #4\n") ++ "LSR D0Ar2, D0Ar2, #6\n" \ ++ "ANDS D0Ar2, D0Ar2, #0x1c\n" \ ++ "ADDZ D0Ar2, D0Ar2, #16\n" \ ++ "SUB %1, %1, D0Ar2\n") + + + /* +-- +2.12.0 + diff --git a/queue/metag-usercopy-Set-flags-before-ADDZ.patch b/queue/metag-usercopy-Set-flags-before-ADDZ.patch new file mode 100644 index 0000000..8de981c --- /dev/null +++ b/queue/metag-usercopy-Set-flags-before-ADDZ.patch @@ -0,0 +1,66 @@ +From fd40eee1290ad7add7aa665e3ce6b0f9fe9734b4 Mon Sep 17 00:00:00 2001 +From: James Hogan <james.hogan@imgtec.com> +Date: Tue, 4 Apr 2017 11:43:26 +0100 +Subject: [PATCH] metag/usercopy: Set flags before ADDZ + +commit fd40eee1290ad7add7aa665e3ce6b0f9fe9734b4 upstream. + +The fixup code for the copy_to_user rapf loops reads TXStatus.LSM_STEP +to decide how far to rewind the source pointer. There is a special case +for the last execution of an MGETL/MGETD, since it leaves LSM_STEP=0 +even though the number of MGETLs/MGETDs attempted was 4. This uses ADDZ +which is conditional upon the Z condition flag, but the AND instruction +which masked the TXStatus.LSM_STEP field didn't set the condition flags +based on the result. + +Fix that now by using ANDS which does set the flags, and also marking +the condition codes as clobbered by the inline assembly. + +Fixes: 373cd784d0fc ("metag: Memory handling") +Signed-off-by: James Hogan <james.hogan@imgtec.com> +Cc: linux-metag@vger.kernel.org +Cc: stable@vger.kernel.org + +diff --git a/arch/metag/lib/usercopy.c b/arch/metag/lib/usercopy.c +index e1d553872fd7..4422928a1746 100644 +--- a/arch/metag/lib/usercopy.c ++++ b/arch/metag/lib/usercopy.c +@@ -315,7 +315,7 @@ + " .previous\n" \ + : "=r" (to), "=r" (from), "=r" (ret), "=d" (n) \ + : "0" (to), "1" (from), "2" (ret), "3" (n) \ +- : "D1Ar1", "D0Ar2", "memory") ++ : "D1Ar1", "D0Ar2", "cc", "memory") + + /* rewind 'to' and 'from' pointers when a fault occurs + * +@@ -341,7 +341,7 @@ + #define __asm_copy_to_user_64bit_rapf_loop(to, from, ret, n, id)\ + __asm_copy_user_64bit_rapf_loop(to, from, ret, n, id, \ + "LSR D0Ar2, D0Ar2, #8\n" \ +- "AND D0Ar2, D0Ar2, #0x7\n" \ ++ "ANDS D0Ar2, D0Ar2, #0x7\n" \ + "ADDZ D0Ar2, D0Ar2, #4\n" \ + "SUB D0Ar2, D0Ar2, #1\n" \ + "MOV D1Ar1, #4\n" \ +@@ -486,7 +486,7 @@ + " .previous\n" \ + : "=r" (to), "=r" (from), "=r" (ret), "=d" (n) \ + : "0" (to), "1" (from), "2" (ret), "3" (n) \ +- : "D1Ar1", "D0Ar2", "memory") ++ : "D1Ar1", "D0Ar2", "cc", "memory") + + /* rewind 'to' and 'from' pointers when a fault occurs + * +@@ -512,7 +512,7 @@ + #define __asm_copy_to_user_32bit_rapf_loop(to, from, ret, n, id)\ + __asm_copy_user_32bit_rapf_loop(to, from, ret, n, id, \ + "LSR D0Ar2, D0Ar2, #8\n" \ +- "AND D0Ar2, D0Ar2, #0x7\n" \ ++ "ANDS D0Ar2, D0Ar2, #0x7\n" \ + "ADDZ D0Ar2, D0Ar2, #4\n" \ + "SUB D0Ar2, D0Ar2, #1\n" \ + "MOV D1Ar1, #4\n" \ +-- +2.12.0 + diff --git a/queue/metag-usercopy-Zero-rest-of-buffer-from-copy_from_us.patch b/queue/metag-usercopy-Zero-rest-of-buffer-from-copy_from_us.patch new file mode 100644 index 0000000..7dcba2c --- /dev/null +++ b/queue/metag-usercopy-Zero-rest-of-buffer-from-copy_from_us.patch @@ -0,0 +1,232 @@ +From 563ddc1076109f2b3f88e6d355eab7b6fd4662cb Mon Sep 17 00:00:00 2001 +From: James Hogan <james.hogan@imgtec.com> +Date: Fri, 31 Mar 2017 11:14:02 +0100 +Subject: [PATCH] metag/usercopy: Zero rest of buffer from copy_from_user + +commit 563ddc1076109f2b3f88e6d355eab7b6fd4662cb upstream. + +Currently we try to zero the destination for a failed read from userland +in fixup code in the usercopy.c macros. The rest of the destination +buffer is then zeroed from __copy_user_zeroing(), which is used for both +copy_from_user() and __copy_from_user(). + +Unfortunately we fail to zero in the fixup code as D1Ar1 is set to 0 +before the fixup code entry labels, and __copy_from_user() shouldn't even +be zeroing the rest of the buffer. + +Move the zeroing out into copy_from_user() and rename +__copy_user_zeroing() to raw_copy_from_user() since it no longer does +any zeroing. This also conveniently matches the name needed for +RAW_COPY_USER support in a later patch. + +Fixes: 373cd784d0fc ("metag: Memory handling") +Reported-by: Al Viro <viro@zeniv.linux.org.uk> +Signed-off-by: James Hogan <james.hogan@imgtec.com> +Cc: linux-metag@vger.kernel.org +Cc: stable@vger.kernel.org + +diff --git a/arch/metag/include/asm/uaccess.h b/arch/metag/include/asm/uaccess.h +index 273e61225c27..07238b39638c 100644 +--- a/arch/metag/include/asm/uaccess.h ++++ b/arch/metag/include/asm/uaccess.h +@@ -197,20 +197,21 @@ extern long __must_check strnlen_user(const char __user *src, long count); + + #define strlen_user(str) strnlen_user(str, 32767) + +-extern unsigned long __must_check __copy_user_zeroing(void *to, +- const void __user *from, +- unsigned long n); ++extern unsigned long raw_copy_from_user(void *to, const void __user *from, ++ unsigned long n); + + static inline unsigned long + copy_from_user(void *to, const void __user *from, unsigned long n) + { ++ unsigned long res = n; + if (likely(access_ok(VERIFY_READ, from, n))) +- return __copy_user_zeroing(to, from, n); +- memset(to, 0, n); +- return n; ++ res = raw_copy_from_user(to, from, n); ++ if (unlikely(res)) ++ memset(to + (n - res), 0, res); ++ return res; + } + +-#define __copy_from_user(to, from, n) __copy_user_zeroing(to, from, n) ++#define __copy_from_user(to, from, n) raw_copy_from_user(to, from, n) + #define __copy_from_user_inatomic __copy_from_user + + extern unsigned long __must_check __copy_user(void __user *to, +diff --git a/arch/metag/lib/usercopy.c b/arch/metag/lib/usercopy.c +index 714d8562aa20..e1d553872fd7 100644 +--- a/arch/metag/lib/usercopy.c ++++ b/arch/metag/lib/usercopy.c +@@ -29,7 +29,6 @@ + COPY \ + "1:\n" \ + " .section .fixup,\"ax\"\n" \ +- " MOV D1Ar1,#0\n" \ + FIXUP \ + " MOVT D1Ar1,#HI(1b)\n" \ + " JUMP D1Ar1,#LO(1b)\n" \ +@@ -637,16 +636,14 @@ EXPORT_SYMBOL(__copy_user); + __asm_copy_user_cont(to, from, ret, \ + " GETB D1Ar1,[%1++]\n" \ + "2: SETB [%0++],D1Ar1\n", \ +- "3: ADD %2,%2,#1\n" \ +- " SETB [%0++],D1Ar1\n", \ ++ "3: ADD %2,%2,#1\n", \ + " .long 2b,3b\n") + + #define __asm_copy_from_user_2x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ + __asm_copy_user_cont(to, from, ret, \ + " GETW D1Ar1,[%1++]\n" \ + "2: SETW [%0++],D1Ar1\n" COPY, \ +- "3: ADD %2,%2,#2\n" \ +- " SETW [%0++],D1Ar1\n" FIXUP, \ ++ "3: ADD %2,%2,#2\n" FIXUP, \ + " .long 2b,3b\n" TENTRY) + + #define __asm_copy_from_user_2(to, from, ret) \ +@@ -656,32 +653,26 @@ EXPORT_SYMBOL(__copy_user); + __asm_copy_from_user_2x_cont(to, from, ret, \ + " GETB D1Ar1,[%1++]\n" \ + "4: SETB [%0++],D1Ar1\n", \ +- "5: ADD %2,%2,#1\n" \ +- " SETB [%0++],D1Ar1\n", \ ++ "5: ADD %2,%2,#1\n", \ + " .long 4b,5b\n") + + #define __asm_copy_from_user_4x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ + __asm_copy_user_cont(to, from, ret, \ + " GETD D1Ar1,[%1++]\n" \ + "2: SETD [%0++],D1Ar1\n" COPY, \ +- "3: ADD %2,%2,#4\n" \ +- " SETD [%0++],D1Ar1\n" FIXUP, \ ++ "3: ADD %2,%2,#4\n" FIXUP, \ + " .long 2b,3b\n" TENTRY) + + #define __asm_copy_from_user_4(to, from, ret) \ + __asm_copy_from_user_4x_cont(to, from, ret, "", "", "") + +- + #define __asm_copy_from_user_8x64(to, from, ret) \ + asm volatile ( \ + " GETL D0Ar2,D1Ar1,[%1++]\n" \ + "2: SETL [%0++],D0Ar2,D1Ar1\n" \ + "1:\n" \ + " .section .fixup,\"ax\"\n" \ +- " MOV D1Ar1,#0\n" \ +- " MOV D0Ar2,#0\n" \ + "3: ADD %2,%2,#8\n" \ +- " SETL [%0++],D0Ar2,D1Ar1\n" \ + " MOVT D0Ar2,#HI(1b)\n" \ + " JUMP D0Ar2,#LO(1b)\n" \ + " .previous\n" \ +@@ -721,11 +712,12 @@ EXPORT_SYMBOL(__copy_user); + "SUB %1, %1, #4\n") + + +-/* Copy from user to kernel, zeroing the bytes that were inaccessible in +- userland. The return-value is the number of bytes that were +- inaccessible. */ +-unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc, +- unsigned long n) ++/* ++ * Copy from user to kernel. The return-value is the number of bytes that were ++ * inaccessible. ++ */ ++unsigned long raw_copy_from_user(void *pdst, const void __user *psrc, ++ unsigned long n) + { + register char *dst asm ("A0.2") = pdst; + register const char __user *src asm ("A1.2") = psrc; +@@ -738,7 +730,7 @@ unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc, + __asm_copy_from_user_1(dst, src, retn); + n--; + if (retn) +- goto copy_exception_bytes; ++ return retn + n; + } + if ((unsigned long) dst & 1) { + /* Worst case - byte copy */ +@@ -746,14 +738,14 @@ unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc, + __asm_copy_from_user_1(dst, src, retn); + n--; + if (retn) +- goto copy_exception_bytes; ++ return retn + n; + } + } + if (((unsigned long) src & 2) && n >= 2) { + __asm_copy_from_user_2(dst, src, retn); + n -= 2; + if (retn) +- goto copy_exception_bytes; ++ return retn + n; + } + if ((unsigned long) dst & 2) { + /* Second worst case - word copy */ +@@ -761,7 +753,7 @@ unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc, + __asm_copy_from_user_2(dst, src, retn); + n -= 2; + if (retn) +- goto copy_exception_bytes; ++ return retn + n; + } + } + +@@ -777,7 +769,7 @@ unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc, + __asm_copy_from_user_8x64(dst, src, retn); + n -= 8; + if (retn) +- goto copy_exception_bytes; ++ return retn + n; + } + } + +@@ -793,7 +785,7 @@ unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc, + __asm_copy_from_user_8x64(dst, src, retn); + n -= 8; + if (retn) +- goto copy_exception_bytes; ++ return retn + n; + } + } + #endif +@@ -803,7 +795,7 @@ unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc, + n -= 4; + + if (retn) +- goto copy_exception_bytes; ++ return retn + n; + } + + /* If we get here, there were no memory read faults. */ +@@ -829,21 +821,8 @@ unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc, + /* If we get here, retn correctly reflects the number of failing + bytes. */ + return retn; +- +- copy_exception_bytes: +- /* We already have "retn" bytes cleared, and need to clear the +- remaining "n" bytes. A non-optimized simple byte-for-byte in-line +- memset is preferred here, since this isn't speed-critical code and +- we'd rather have this a leaf-function than calling memset. */ +- { +- char *endp; +- for (endp = dst + n; dst < endp; dst++) +- *dst = 0; +- } +- +- return retn + n; + } +-EXPORT_SYMBOL(__copy_user_zeroing); ++EXPORT_SYMBOL(raw_copy_from_user); + + #define __asm_clear_8x64(to, ret) \ + asm volatile ( \ +-- +2.12.0 + diff --git a/queue/mm-Tighten-x86-dev-mem-with-zeroing-reads.patch b/queue/mm-Tighten-x86-dev-mem-with-zeroing-reads.patch new file mode 100644 index 0000000..03e4cab --- /dev/null +++ b/queue/mm-Tighten-x86-dev-mem-with-zeroing-reads.patch @@ -0,0 +1,208 @@ +From a4866aa812518ed1a37d8ea0c881dc946409de94 Mon Sep 17 00:00:00 2001 +From: Kees Cook <keescook@chromium.org> +Date: Wed, 5 Apr 2017 09:39:08 -0700 +Subject: [PATCH] mm: Tighten x86 /dev/mem with zeroing reads + +commit a4866aa812518ed1a37d8ea0c881dc946409de94 upstream. + +Under CONFIG_STRICT_DEVMEM, reading System RAM through /dev/mem is +disallowed. However, on x86, the first 1MB was always allowed for BIOS +and similar things, regardless of it actually being System RAM. It was +possible for heap to end up getting allocated in low 1MB RAM, and then +read by things like x86info or dd, which would trip hardened usercopy: + +usercopy: kernel memory exposure attempt detected from ffff880000090000 (dma-kmalloc-256) (4096 bytes) + +This changes the x86 exception for the low 1MB by reading back zeros for +System RAM areas instead of blindly allowing them. More work is needed to +extend this to mmap, but currently mmap doesn't go through usercopy, so +hardened usercopy won't Oops the kernel. + +Reported-by: Tommi Rantala <tommi.t.rantala@nokia.com> +Tested-by: Tommi Rantala <tommi.t.rantala@nokia.com> +Signed-off-by: Kees Cook <keescook@chromium.org> + +diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c +index 22af912d66d2..889e7619a091 100644 +--- a/arch/x86/mm/init.c ++++ b/arch/x86/mm/init.c +@@ -643,21 +643,40 @@ void __init init_mem_mapping(void) + * devmem_is_allowed() checks to see if /dev/mem access to a certain address + * is valid. The argument is a physical page number. + * +- * +- * On x86, access has to be given to the first megabyte of ram because that area +- * contains BIOS code and data regions used by X and dosemu and similar apps. +- * Access has to be given to non-kernel-ram areas as well, these contain the PCI +- * mmio resources as well as potential bios/acpi data regions. ++ * On x86, access has to be given to the first megabyte of RAM because that ++ * area traditionally contains BIOS code and data regions used by X, dosemu, ++ * and similar apps. Since they map the entire memory range, the whole range ++ * must be allowed (for mapping), but any areas that would otherwise be ++ * disallowed are flagged as being "zero filled" instead of rejected. ++ * Access has to be given to non-kernel-ram areas as well, these contain the ++ * PCI mmio resources as well as potential bios/acpi data regions. + */ + int devmem_is_allowed(unsigned long pagenr) + { +- if (pagenr < 256) +- return 1; +- if (iomem_is_exclusive(pagenr << PAGE_SHIFT)) ++ if (page_is_ram(pagenr)) { ++ /* ++ * For disallowed memory regions in the low 1MB range, ++ * request that the page be shown as all zeros. ++ */ ++ if (pagenr < 256) ++ return 2; ++ ++ return 0; ++ } ++ ++ /* ++ * This must follow RAM test, since System RAM is considered a ++ * restricted resource under CONFIG_STRICT_IOMEM. ++ */ ++ if (iomem_is_exclusive(pagenr << PAGE_SHIFT)) { ++ /* Low 1MB bypasses iomem restrictions. */ ++ if (pagenr < 256) ++ return 1; ++ + return 0; +- if (!page_is_ram(pagenr)) +- return 1; +- return 0; ++ } ++ ++ return 1; + } + + void free_init_pages(char *what, unsigned long begin, unsigned long end) +diff --git a/drivers/char/mem.c b/drivers/char/mem.c +index 6d9cc2d39d22..7e4a9d1296bb 100644 +--- a/drivers/char/mem.c ++++ b/drivers/char/mem.c +@@ -60,6 +60,10 @@ static inline int valid_mmap_phys_addr_range(unsigned long pfn, size_t size) + #endif + + #ifdef CONFIG_STRICT_DEVMEM ++static inline int page_is_allowed(unsigned long pfn) ++{ ++ return devmem_is_allowed(pfn); ++} + static inline int range_is_allowed(unsigned long pfn, unsigned long size) + { + u64 from = ((u64)pfn) << PAGE_SHIFT; +@@ -75,6 +79,10 @@ static inline int range_is_allowed(unsigned long pfn, unsigned long size) + return 1; + } + #else ++static inline int page_is_allowed(unsigned long pfn) ++{ ++ return 1; ++} + static inline int range_is_allowed(unsigned long pfn, unsigned long size) + { + return 1; +@@ -122,23 +130,31 @@ static ssize_t read_mem(struct file *file, char __user *buf, + + while (count > 0) { + unsigned long remaining; ++ int allowed; + + sz = size_inside_page(p, count); + +- if (!range_is_allowed(p >> PAGE_SHIFT, count)) ++ allowed = page_is_allowed(p >> PAGE_SHIFT); ++ if (!allowed) + return -EPERM; ++ if (allowed == 2) { ++ /* Show zeros for restricted memory. */ ++ remaining = clear_user(buf, sz); ++ } else { ++ /* ++ * On ia64 if a page has been mapped somewhere as ++ * uncached, then it must also be accessed uncached ++ * by the kernel or data corruption may occur. ++ */ ++ ptr = xlate_dev_mem_ptr(p); ++ if (!ptr) ++ return -EFAULT; + +- /* +- * On ia64 if a page has been mapped somewhere as uncached, then +- * it must also be accessed uncached by the kernel or data +- * corruption may occur. +- */ +- ptr = xlate_dev_mem_ptr(p); +- if (!ptr) +- return -EFAULT; ++ remaining = copy_to_user(buf, ptr, sz); ++ ++ unxlate_dev_mem_ptr(p, ptr); ++ } + +- remaining = copy_to_user(buf, ptr, sz); +- unxlate_dev_mem_ptr(p, ptr); + if (remaining) + return -EFAULT; + +@@ -181,30 +197,36 @@ static ssize_t write_mem(struct file *file, const char __user *buf, + #endif + + while (count > 0) { ++ int allowed; ++ + sz = size_inside_page(p, count); + +- if (!range_is_allowed(p >> PAGE_SHIFT, sz)) ++ allowed = page_is_allowed(p >> PAGE_SHIFT); ++ if (!allowed) + return -EPERM; + +- /* +- * On ia64 if a page has been mapped somewhere as uncached, then +- * it must also be accessed uncached by the kernel or data +- * corruption may occur. +- */ +- ptr = xlate_dev_mem_ptr(p); +- if (!ptr) { +- if (written) +- break; +- return -EFAULT; +- } ++ /* Skip actual writing when a page is marked as restricted. */ ++ if (allowed == 1) { ++ /* ++ * On ia64 if a page has been mapped somewhere as ++ * uncached, then it must also be accessed uncached ++ * by the kernel or data corruption may occur. ++ */ ++ ptr = xlate_dev_mem_ptr(p); ++ if (!ptr) { ++ if (written) ++ break; ++ return -EFAULT; ++ } + +- copied = copy_from_user(ptr, buf, sz); +- unxlate_dev_mem_ptr(p, ptr); +- if (copied) { +- written += sz - copied; +- if (written) +- break; +- return -EFAULT; ++ copied = copy_from_user(ptr, buf, sz); ++ unxlate_dev_mem_ptr(p, ptr); ++ if (copied) { ++ written += sz - copied; ++ if (written) ++ break; ++ return -EFAULT; ++ } + } + + buf += sz; +-- +2.12.0 + diff --git a/queue/mm-memcontrol-use-special-workqueue-for-creating-per.patch b/queue/mm-memcontrol-use-special-workqueue-for-creating-per.patch new file mode 100644 index 0000000..0a31934 --- /dev/null +++ b/queue/mm-memcontrol-use-special-workqueue-for-creating-per.patch @@ -0,0 +1,82 @@ +From 13583c3d3224508582ec03d881d0b68dd3ee8e10 Mon Sep 17 00:00:00 2001 +From: Vladimir Davydov <vdavydov.dev@gmail.com> +Date: Mon, 12 Dec 2016 16:41:29 -0800 +Subject: [PATCH] mm: memcontrol: use special workqueue for creating per-memcg + caches + +commit 13583c3d3224508582ec03d881d0b68dd3ee8e10 upstream. + +Creating a lot of cgroups at the same time might stall all worker +threads with kmem cache creation works, because kmem cache creation is +done with the slab_mutex held. The problem was amplified by commits +801faf0db894 ("mm/slab: lockless decision to grow cache") in case of +SLAB and 81ae6d03952c ("mm/slub.c: replace kick_all_cpus_sync() with +synchronize_sched() in kmem_cache_shrink()") in case of SLUB, which +increased the maximal time the slab_mutex can be held. + +To prevent that from happening, let's use a special ordered single +threaded workqueue for kmem cache creation. This shouldn't introduce +any functional changes regarding how kmem caches are created, as the +work function holds the global slab_mutex during its whole runtime +anyway, making it impossible to run more than one work at a time. By +using a single threaded workqueue, we just avoid creating a thread per +each work. Ordering is required to avoid a situation when a cgroup's +work is put off indefinitely because there are other cgroups to serve, +in other words to guarantee fairness. + +Link: https://bugzilla.kernel.org/show_bug.cgi?id=172981 +Link: http://lkml.kernel.org/r/20161004131417.GC1862@esperanza +Signed-off-by: Vladimir Davydov <vdavydov.dev@gmail.com> +Reported-by: Doug Smythies <dsmythies@telus.net> +Acked-by: Michal Hocko <mhocko@suse.com> +Cc: Christoph Lameter <cl@linux.com> +Cc: David Rientjes <rientjes@google.com> +Cc: Johannes Weiner <hannes@cmpxchg.org> +Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com> +Cc: Pekka Enberg <penberg@kernel.org> +Signed-off-by: Andrew Morton <akpm@linux-foundation.org> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> + +diff --git a/mm/memcontrol.c b/mm/memcontrol.c +index 0f870ba43942..91dfc7c5ce8f 100644 +--- a/mm/memcontrol.c ++++ b/mm/memcontrol.c +@@ -2154,6 +2154,8 @@ struct memcg_kmem_cache_create_work { + struct work_struct work; + }; + ++static struct workqueue_struct *memcg_kmem_cache_create_wq; ++ + static void memcg_kmem_cache_create_func(struct work_struct *w) + { + struct memcg_kmem_cache_create_work *cw = +@@ -2185,7 +2187,7 @@ static void __memcg_schedule_kmem_cache_create(struct mem_cgroup *memcg, + cw->cachep = cachep; + INIT_WORK(&cw->work, memcg_kmem_cache_create_func); + +- schedule_work(&cw->work); ++ queue_work(memcg_kmem_cache_create_wq, &cw->work); + } + + static void memcg_schedule_kmem_cache_create(struct mem_cgroup *memcg, +@@ -5783,6 +5785,17 @@ static int __init mem_cgroup_init(void) + { + int cpu, node; + ++#ifndef CONFIG_SLOB ++ /* ++ * Kmem cache creation is mostly done with the slab_mutex held, ++ * so use a special workqueue to avoid stalling all worker ++ * threads in case lots of cgroups are created simultaneously. ++ */ ++ memcg_kmem_cache_create_wq = ++ alloc_ordered_workqueue("memcg_kmem_cache_create", 0); ++ BUG_ON(!memcg_kmem_cache_create_wq); ++#endif ++ + hotcpu_notifier(memcg_cpu_hotplug_callback, 0); + + for_each_possible_cpu(cpu) +-- +2.12.0 + diff --git a/queue/mm-mempolicy.c-fix-error-handling-in-set_mempolicy-a.patch b/queue/mm-mempolicy.c-fix-error-handling-in-set_mempolicy-a.patch new file mode 100644 index 0000000..2d89573 --- /dev/null +++ b/queue/mm-mempolicy.c-fix-error-handling-in-set_mempolicy-a.patch @@ -0,0 +1,76 @@ +From cf01fb9985e8deb25ccf0ea54d916b8871ae0e62 Mon Sep 17 00:00:00 2001 +From: Chris Salls <salls@cs.ucsb.edu> +Date: Fri, 7 Apr 2017 23:48:11 -0700 +Subject: [PATCH] mm/mempolicy.c: fix error handling in set_mempolicy and + mbind. + +commit cf01fb9985e8deb25ccf0ea54d916b8871ae0e62 upstream. + +In the case that compat_get_bitmap fails we do not want to copy the +bitmap to the user as it will contain uninitialized stack data and leak +sensitive data. + +Signed-off-by: Chris Salls <salls@cs.ucsb.edu> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> + +diff --git a/mm/mempolicy.c b/mm/mempolicy.c +index 75b2745bac41..37d0b334bfe9 100644 +--- a/mm/mempolicy.c ++++ b/mm/mempolicy.c +@@ -1529,7 +1529,6 @@ COMPAT_SYSCALL_DEFINE5(get_mempolicy, int __user *, policy, + COMPAT_SYSCALL_DEFINE3(set_mempolicy, int, mode, compat_ulong_t __user *, nmask, + compat_ulong_t, maxnode) + { +- long err = 0; + unsigned long __user *nm = NULL; + unsigned long nr_bits, alloc_size; + DECLARE_BITMAP(bm, MAX_NUMNODES); +@@ -1538,14 +1537,13 @@ COMPAT_SYSCALL_DEFINE3(set_mempolicy, int, mode, compat_ulong_t __user *, nmask, + alloc_size = ALIGN(nr_bits, BITS_PER_LONG) / 8; + + if (nmask) { +- err = compat_get_bitmap(bm, nmask, nr_bits); ++ if (compat_get_bitmap(bm, nmask, nr_bits)) ++ return -EFAULT; + nm = compat_alloc_user_space(alloc_size); +- err |= copy_to_user(nm, bm, alloc_size); ++ if (copy_to_user(nm, bm, alloc_size)) ++ return -EFAULT; + } + +- if (err) +- return -EFAULT; +- + return sys_set_mempolicy(mode, nm, nr_bits+1); + } + +@@ -1553,7 +1551,6 @@ COMPAT_SYSCALL_DEFINE6(mbind, compat_ulong_t, start, compat_ulong_t, len, + compat_ulong_t, mode, compat_ulong_t __user *, nmask, + compat_ulong_t, maxnode, compat_ulong_t, flags) + { +- long err = 0; + unsigned long __user *nm = NULL; + unsigned long nr_bits, alloc_size; + nodemask_t bm; +@@ -1562,14 +1559,13 @@ COMPAT_SYSCALL_DEFINE6(mbind, compat_ulong_t, start, compat_ulong_t, len, + alloc_size = ALIGN(nr_bits, BITS_PER_LONG) / 8; + + if (nmask) { +- err = compat_get_bitmap(nodes_addr(bm), nmask, nr_bits); ++ if (compat_get_bitmap(nodes_addr(bm), nmask, nr_bits)) ++ return -EFAULT; + nm = compat_alloc_user_space(alloc_size); +- err |= copy_to_user(nm, nodes_addr(bm), alloc_size); ++ if (copy_to_user(nm, nodes_addr(bm), alloc_size)) ++ return -EFAULT; + } + +- if (err) +- return -EFAULT; +- + return sys_mbind(start, len, mode, nm, nr_bits+1, flags); + } + +-- +2.12.0 + diff --git a/queue/mm-page_alloc.c-fix-print-order-in-show_free_areas.patch b/queue/mm-page_alloc.c-fix-print-order-in-show_free_areas.patch new file mode 100644 index 0000000..0008f0a --- /dev/null +++ b/queue/mm-page_alloc.c-fix-print-order-in-show_free_areas.patch @@ -0,0 +1,39 @@ +From 1f06b81aea5ecba2c1f8afd87e0ba1b9f8f90160 Mon Sep 17 00:00:00 2001 +From: Alexander Polakov <apolyakov@beget.ru> +Date: Fri, 7 Apr 2017 16:04:45 -0700 +Subject: [PATCH] mm/page_alloc.c: fix print order in show_free_areas() + +commit 1f06b81aea5ecba2c1f8afd87e0ba1b9f8f90160 upstream. + +Fixes: 11fb998986a72a ("mm: move most file-based accounting to the node") +Link: http://lkml.kernel.org/r/1490377730.30219.2.camel@beget.ru +Signed-off-by: Alexander Polyakov <apolyakov@beget.com> +Acked-by: Michal Hocko <mhocko@suse.com> +Cc: Mel Gorman <mgorman@techsingularity.net> +Cc: Vlastimil Babka <vbabka@suse.cz> +Cc: <stable@vger.kernel.org> [4.8+] +Signed-off-by: Andrew Morton <akpm@linux-foundation.org> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> + +diff --git a/mm/page_alloc.c b/mm/page_alloc.c +index 6cbde310abed..d6a665057d61 100644 +--- a/mm/page_alloc.c ++++ b/mm/page_alloc.c +@@ -4519,13 +4519,13 @@ void show_free_areas(unsigned int filter, nodemask_t *nodemask) + K(node_page_state(pgdat, NR_FILE_MAPPED)), + K(node_page_state(pgdat, NR_FILE_DIRTY)), + K(node_page_state(pgdat, NR_WRITEBACK)), ++ K(node_page_state(pgdat, NR_SHMEM)), + #ifdef CONFIG_TRANSPARENT_HUGEPAGE + K(node_page_state(pgdat, NR_SHMEM_THPS) * HPAGE_PMD_NR), + K(node_page_state(pgdat, NR_SHMEM_PMDMAPPED) + * HPAGE_PMD_NR), + K(node_page_state(pgdat, NR_ANON_THPS) * HPAGE_PMD_NR), + #endif +- K(node_page_state(pgdat, NR_SHMEM)), + K(node_page_state(pgdat, NR_WRITEBACK_TEMP)), + K(node_page_state(pgdat, NR_UNSTABLE_NFS)), + node_page_state(pgdat, NR_PAGES_SCANNED), +-- +2.12.0 + diff --git a/queue/mmc-sdhci-msm-Enable-few-quirks.patch b/queue/mmc-sdhci-msm-Enable-few-quirks.patch new file mode 100644 index 0000000..8f8078c --- /dev/null +++ b/queue/mmc-sdhci-msm-Enable-few-quirks.patch @@ -0,0 +1,33 @@ +From a0e3142869d29688de6f77be31aa7a401a4a88f1 Mon Sep 17 00:00:00 2001 +From: Ritesh Harjani <riteshh@codeaurora.org> +Date: Mon, 21 Nov 2016 12:07:18 +0530 +Subject: [PATCH] mmc: sdhci-msm: Enable few quirks + +commit a0e3142869d29688de6f77be31aa7a401a4a88f1 upstream. + +sdhc-msm controller needs this SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN +& SDHCI_QUIRK2_PRESET_VALUE_BROKEN to be set. Hence setting it. + +Signed-off-by: Sahitya Tummala <stummala@codeaurora.org> +Signed-off-by: Ritesh Harjani <riteshh@codeaurora.org> +Acked-by: Adrian Hunter <adrian.hunter@intel.com> +Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> + +diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c +index aaeaf475e395..15a8b8e70ff9 100644 +--- a/drivers/mmc/host/sdhci-msm.c ++++ b/drivers/mmc/host/sdhci-msm.c +@@ -592,7 +592,9 @@ static const struct sdhci_ops sdhci_msm_ops = { + static const struct sdhci_pltfm_data sdhci_msm_pdata = { + .quirks = SDHCI_QUIRK_BROKEN_CARD_DETECTION | + SDHCI_QUIRK_NO_CARD_NO_RESET | +- SDHCI_QUIRK_SINGLE_POWER_WRITE, ++ SDHCI_QUIRK_SINGLE_POWER_WRITE | ++ SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN, ++ .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN, + .ops = &sdhci_msm_ops, + }; + +-- +2.12.0 + diff --git a/queue/mmc-sdhci-of-esdhc-remove-default-broken-cd-for-ARM.patch b/queue/mmc-sdhci-of-esdhc-remove-default-broken-cd-for-ARM.patch new file mode 100644 index 0000000..6adf9ca --- /dev/null +++ b/queue/mmc-sdhci-of-esdhc-remove-default-broken-cd-for-ARM.patch @@ -0,0 +1,66 @@ +From e9acc77dd046b22c7ebf70e35f68968978445f8b Mon Sep 17 00:00:00 2001 +From: yangbo lu <yangbo.lu@nxp.com> +Date: Mon, 26 Dec 2016 17:40:44 +0800 +Subject: [PATCH] mmc: sdhci-of-esdhc: remove default broken-cd for ARM + +commit e9acc77dd046b22c7ebf70e35f68968978445f8b upstream. + +Initially all QorIQ platforms were PowerPC architecture and they didn't +support card detection except several platforms. The driver added the +quirk SDHCI_QUIRK_BROKEN_CARD_DETECTION as default and this made broken-cd +property in dts node didn't work. Now QorIQ platform turns to ARM +architecture and most of them could support card detection. However it's +a large number of dts trees that need to be fixed with broken-cd if we +remove the default SDHCI_QUIRK_BROKEN_CARD_DETECTION in driver. And the +users don't want to see this. So this patch is to remove this default +quirk just for ARM and keep it for PowerPC.(Note, QorIQ PowerPC platform +only has big-endian eSDHC while QorIQ ARM platform has big-endian or +little-endian eSDHC) This makes broken-cd property work again for ARM. + +Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com> +Acked-by: Adrian Hunter <adrian.hunter@intel.com> +Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> + +diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c +index 9a6eb4492172..364f6b87a728 100644 +--- a/drivers/mmc/host/sdhci-of-esdhc.c ++++ b/drivers/mmc/host/sdhci-of-esdhc.c +@@ -569,16 +569,19 @@ static const struct sdhci_ops sdhci_esdhc_le_ops = { + }; + + static const struct sdhci_pltfm_data sdhci_esdhc_be_pdata = { +- .quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_BROKEN_CARD_DETECTION +- | SDHCI_QUIRK_NO_CARD_NO_RESET +- | SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC, ++ .quirks = ESDHC_DEFAULT_QUIRKS | ++#ifdef CONFIG_PPC ++ SDHCI_QUIRK_BROKEN_CARD_DETECTION | ++#endif ++ SDHCI_QUIRK_NO_CARD_NO_RESET | ++ SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC, + .ops = &sdhci_esdhc_be_ops, + }; + + static const struct sdhci_pltfm_data sdhci_esdhc_le_pdata = { +- .quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_BROKEN_CARD_DETECTION +- | SDHCI_QUIRK_NO_CARD_NO_RESET +- | SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC, ++ .quirks = ESDHC_DEFAULT_QUIRKS | ++ SDHCI_QUIRK_NO_CARD_NO_RESET | ++ SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC, + .ops = &sdhci_esdhc_le_ops, + }; + +@@ -643,8 +646,7 @@ static int sdhci_esdhc_probe(struct platform_device *pdev) + of_device_is_compatible(np, "fsl,p5020-esdhc") || + of_device_is_compatible(np, "fsl,p4080-esdhc") || + of_device_is_compatible(np, "fsl,p1020-esdhc") || +- of_device_is_compatible(np, "fsl,t1040-esdhc") || +- of_device_is_compatible(np, "fsl,ls1021a-esdhc")) ++ of_device_is_compatible(np, "fsl,t1040-esdhc")) + host->quirks &= ~SDHCI_QUIRK_BROKEN_CARD_DETECTION; + + if (of_device_is_compatible(np, "fsl,ls1021a-esdhc")) +-- +2.12.0 + diff --git a/queue/mtd-bcm47xxpart-fix-parsing-first-block-after-aligne.patch b/queue/mtd-bcm47xxpart-fix-parsing-first-block-after-aligne.patch new file mode 100644 index 0000000..d1bb01b --- /dev/null +++ b/queue/mtd-bcm47xxpart-fix-parsing-first-block-after-aligne.patch @@ -0,0 +1,44 @@ +From bd5d21310133921021d78995ad6346f908483124 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl> +Date: Sun, 20 Nov 2016 16:09:30 +0100 +Subject: [PATCH] mtd: bcm47xxpart: fix parsing first block after aligned TRX +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit bd5d21310133921021d78995ad6346f908483124 upstream. + +After parsing TRX we should skip to the first block placed behind it. +Our code was working only with TRX with length not aligned to the +blocksize. In other cases (length aligned) it was missing the block +places right after TRX. + +This fixes calculation and simplifies the comment. + +Signed-off-by: RafaÅ‚ MiÅ‚ecki <rafal@milecki.pl> +Signed-off-by: Brian Norris <computersforpeace@gmail.com> + +diff --git a/drivers/mtd/bcm47xxpart.c b/drivers/mtd/bcm47xxpart.c +index 377947580203..283ff7e17a0f 100644 +--- a/drivers/mtd/bcm47xxpart.c ++++ b/drivers/mtd/bcm47xxpart.c +@@ -229,12 +229,10 @@ static int bcm47xxpart_parse(struct mtd_info *master, + + last_trx_part = curr_part - 1; + +- /* +- * We have whole TRX scanned, skip to the next part. Use +- * roundown (not roundup), as the loop will increase +- * offset in next step. +- */ +- offset = rounddown(offset + trx->length, blocksize); ++ /* Jump to the end of TRX */ ++ offset = roundup(offset + trx->length, blocksize); ++ /* Next loop iteration will increase the offset */ ++ offset -= blocksize; + continue; + } + +-- +2.12.0 + diff --git a/queue/nbd-fix-64-bit-division.patch b/queue/nbd-fix-64-bit-division.patch new file mode 100644 index 0000000..cd74e62 --- /dev/null +++ b/queue/nbd-fix-64-bit-division.patch @@ -0,0 +1,35 @@ +From e88f72cb9f54f6d244e55f629fe5e2f34ca6f9ed Mon Sep 17 00:00:00 2001 +From: Jens Axboe <axboe@fb.com> +Date: Sat, 3 Dec 2016 12:08:03 -0700 +Subject: [PATCH] nbd: fix 64-bit division + +commit e88f72cb9f54f6d244e55f629fe5e2f34ca6f9ed upstream. + +We have this: + +ERROR: "__aeabi_ldivmod" [drivers/block/nbd.ko] undefined! +ERROR: "__divdi3" [drivers/block/nbd.ko] undefined! +nbd.c:(.text+0x247c72): undefined reference to `__divdi3' + +due to a recent commit, that did 64-bit division. Use the proper +divider function so that 32-bit compiles don't break. + +Fixes: ef77b515243b ("nbd: use loff_t for blocksize and nbd_set_size args") +Signed-off-by: Jens Axboe <axboe@fb.com> + +diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c +index 92f5400edbd3..bc78cbb2d18a 100644 +--- a/drivers/block/nbd.c ++++ b/drivers/block/nbd.c +@@ -729,7 +729,7 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd, + + case NBD_SET_SIZE: + return nbd_size_set(nbd, bdev, nbd->blksize, +- arg / nbd->blksize); ++ div_s64(arg, nbd->blksize)); + + case NBD_SET_SIZE_BLOCKS: + return nbd_size_set(nbd, bdev, nbd->blksize, arg); +-- +2.12.0 + diff --git a/queue/nbd-use-loff_t-for-blocksize-and-nbd_set_size-args.patch b/queue/nbd-use-loff_t-for-blocksize-and-nbd_set_size-args.patch new file mode 100644 index 0000000..4783069 --- /dev/null +++ b/queue/nbd-use-loff_t-for-blocksize-and-nbd_set_size-args.patch @@ -0,0 +1,58 @@ +From ef77b515243b3499d62cf446eda6ca7e0a0b079c Mon Sep 17 00:00:00 2001 +From: Josef Bacik <jbacik@fb.com> +Date: Fri, 2 Dec 2016 16:19:12 -0500 +Subject: [PATCH] nbd: use loff_t for blocksize and nbd_set_size args + +commit ef77b515243b3499d62cf446eda6ca7e0a0b079c upstream. + +If we have large devices (say like the 40t drive I was trying to test with) we +will end up overflowing the int arguments to nbd_set_size and not get the right +size for our device. Fix this by using loff_t everywhere so I don't have to +think about this again. Thanks, + +Signed-off-by: Josef Bacik <jbacik@fb.com> +Signed-off-by: Jens Axboe <axboe@fb.com> + +diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c +index dc722a7adf58..92f5400edbd3 100644 +--- a/drivers/block/nbd.c ++++ b/drivers/block/nbd.c +@@ -64,7 +64,7 @@ struct nbd_device { + int num_connections; + atomic_t recv_threads; + wait_queue_head_t recv_wq; +- int blksize; ++ loff_t blksize; + loff_t bytesize; + + struct task_struct *task_recv; +@@ -134,7 +134,7 @@ static void nbd_size_update(struct nbd_device *nbd, struct block_device *bdev) + } + + static int nbd_size_set(struct nbd_device *nbd, struct block_device *bdev, +- int blocksize, int nr_blocks) ++ loff_t blocksize, loff_t nr_blocks) + { + int ret; + +@@ -143,7 +143,7 @@ static int nbd_size_set(struct nbd_device *nbd, struct block_device *bdev, + return ret; + + nbd->blksize = blocksize; +- nbd->bytesize = (loff_t)blocksize * (loff_t)nr_blocks; ++ nbd->bytesize = blocksize * nr_blocks; + + nbd_size_update(nbd, bdev); + +@@ -930,7 +930,7 @@ static int nbd_dev_dbg_init(struct nbd_device *nbd) + debugfs_create_file("tasks", 0444, dir, nbd, &nbd_dbg_tasks_ops); + debugfs_create_u64("size_bytes", 0444, dir, &nbd->bytesize); + debugfs_create_u32("timeout", 0444, dir, &nbd->tag_set.timeout); +- debugfs_create_u32("blocksize", 0444, dir, &nbd->blksize); ++ debugfs_create_u64("blocksize", 0444, dir, &nbd->blksize); + debugfs_create_file("flags", 0444, dir, nbd, &nbd_dbg_flags_ops); + + return 0; +-- +2.12.0 + diff --git a/queue/net-ipv6-check-route-protocol-when-deleting-routes.patch b/queue/net-ipv6-check-route-protocol-when-deleting-routes.patch new file mode 100644 index 0000000..e49d339 --- /dev/null +++ b/queue/net-ipv6-check-route-protocol-when-deleting-routes.patch @@ -0,0 +1,35 @@ +From c2ed1880fd61a998e3ce40254a99a2ad000f1a7d Mon Sep 17 00:00:00 2001 +From: Mantas M <grawity@gmail.com> +Date: Fri, 16 Dec 2016 10:30:59 +0200 +Subject: [PATCH] net: ipv6: check route protocol when deleting routes +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit c2ed1880fd61a998e3ce40254a99a2ad000f1a7d upstream. + +The protocol field is checked when deleting IPv4 routes, but ignored for +IPv6, which causes problems with routing daemons accidentally deleting +externally set routes (observed by multiple bird6 users). + +This can be verified using `ip -6 route del <prefix> proto something`. + +Signed-off-by: Mantas MikulÄ—nas <grawity@gmail.com> +Signed-off-by: David S. Miller <davem@davemloft.net> + +diff --git a/net/ipv6/route.c b/net/ipv6/route.c +index 2413a0637d99..890acace01d0 100644 +--- a/net/ipv6/route.c ++++ b/net/ipv6/route.c +@@ -2174,6 +2174,8 @@ static int ip6_route_del(struct fib6_config *cfg) + continue; + if (cfg->fc_metric && cfg->fc_metric != rt->rt6i_metric) + continue; ++ if (cfg->fc_protocol && cfg->fc_protocol != rt->rt6i_protocol) ++ continue; + dst_hold(&rt->dst); + read_unlock_bh(&table->tb6_lock); + +-- +2.12.0 + diff --git a/queue/net-mlx4_core-Fix-racy-CQ-Completion-Queue-free.patch b/queue/net-mlx4_core-Fix-racy-CQ-Completion-Queue-free.patch new file mode 100644 index 0000000..3c6bb91 --- /dev/null +++ b/queue/net-mlx4_core-Fix-racy-CQ-Completion-Queue-free.patch @@ -0,0 +1,147 @@ +From 291c566a28910614ce42d0ffe82196eddd6346f4 Mon Sep 17 00:00:00 2001 +From: Jack Morgenstein <jackm@dev.mellanox.co.il> +Date: Mon, 16 Jan 2017 18:31:37 +0200 +Subject: [PATCH] net/mlx4_core: Fix racy CQ (Completion Queue) free + +commit 291c566a28910614ce42d0ffe82196eddd6346f4 upstream. + +In function mlx4_cq_completion() and mlx4_cq_event(), the +radix_tree_lookup requires a rcu_read_lock. +This is mandatory: if another core frees the CQ, it could +run the radix_tree_node_rcu_free() call_rcu() callback while +its being used by the radix tree lookup function. + +Additionally, in function mlx4_cq_event(), since we are adding +the rcu lock around the radix-tree lookup, we no longer need to take +the spinlock. Also, the synchronize_irq() call for the async event +eliminates the need for incrementing the cq reference count in +mlx4_cq_event(). + +Other changes: +1. In function mlx4_cq_free(), replace spin_lock_irq with spin_lock: + we no longer take this spinlock in the interrupt context. + The spinlock here, therefore, simply protects against different + threads simultaneously invoking mlx4_cq_free() for different cq's. + +2. In function mlx4_cq_free(), we move the radix tree delete to before + the synchronize_irq() calls. This guarantees that we will not + access this cq during any subsequent interrupts, and therefore can + safely free the CQ after the synchronize_irq calls. The rcu_read_lock + in the interrupt handlers only needs to protect against corrupting the + radix tree; the interrupt handlers may access the cq outside the + rcu_read_lock due to the synchronize_irq calls which protect against + premature freeing of the cq. + +3. In function mlx4_cq_event(), we change the mlx_warn message to mlx4_dbg. + +4. We leave the cq reference count mechanism in place, because it is + still needed for the cq completion tasklet mechanism. + +Fixes: 6d90aa5cf17b ("net/mlx4_core: Make sure there are no pending async events when freeing CQ") +Fixes: 225c7b1feef1 ("IB/mlx4: Add a driver Mellanox ConnectX InfiniBand adapters") +Signed-off-by: Jack Morgenstein <jackm@dev.mellanox.co.il> +Signed-off-by: Matan Barak <matanb@mellanox.com> +Signed-off-by: Tariq Toukan <tariqt@mellanox.com> +Signed-off-by: David S. Miller <davem@davemloft.net> + +diff --git a/drivers/net/ethernet/mellanox/mlx4/cq.c b/drivers/net/ethernet/mellanox/mlx4/cq.c +index a849da92f857..6b8635378f1f 100644 +--- a/drivers/net/ethernet/mellanox/mlx4/cq.c ++++ b/drivers/net/ethernet/mellanox/mlx4/cq.c +@@ -101,13 +101,19 @@ void mlx4_cq_completion(struct mlx4_dev *dev, u32 cqn) + { + struct mlx4_cq *cq; + ++ rcu_read_lock(); + cq = radix_tree_lookup(&mlx4_priv(dev)->cq_table.tree, + cqn & (dev->caps.num_cqs - 1)); ++ rcu_read_unlock(); ++ + if (!cq) { + mlx4_dbg(dev, "Completion event for bogus CQ %08x\n", cqn); + return; + } + ++ /* Acessing the CQ outside of rcu_read_lock is safe, because ++ * the CQ is freed only after interrupt handling is completed. ++ */ + ++cq->arm_sn; + + cq->comp(cq); +@@ -118,23 +124,19 @@ void mlx4_cq_event(struct mlx4_dev *dev, u32 cqn, int event_type) + struct mlx4_cq_table *cq_table = &mlx4_priv(dev)->cq_table; + struct mlx4_cq *cq; + +- spin_lock(&cq_table->lock); +- ++ rcu_read_lock(); + cq = radix_tree_lookup(&cq_table->tree, cqn & (dev->caps.num_cqs - 1)); +- if (cq) +- atomic_inc(&cq->refcount); +- +- spin_unlock(&cq_table->lock); ++ rcu_read_unlock(); + + if (!cq) { +- mlx4_warn(dev, "Async event for bogus CQ %08x\n", cqn); ++ mlx4_dbg(dev, "Async event for bogus CQ %08x\n", cqn); + return; + } + ++ /* Acessing the CQ outside of rcu_read_lock is safe, because ++ * the CQ is freed only after interrupt handling is completed. ++ */ + cq->event(cq, event_type); +- +- if (atomic_dec_and_test(&cq->refcount)) +- complete(&cq->free); + } + + static int mlx4_SW2HW_CQ(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox, +@@ -301,9 +303,9 @@ int mlx4_cq_alloc(struct mlx4_dev *dev, int nent, + if (err) + return err; + +- spin_lock_irq(&cq_table->lock); ++ spin_lock(&cq_table->lock); + err = radix_tree_insert(&cq_table->tree, cq->cqn, cq); +- spin_unlock_irq(&cq_table->lock); ++ spin_unlock(&cq_table->lock); + if (err) + goto err_icm; + +@@ -349,9 +351,9 @@ int mlx4_cq_alloc(struct mlx4_dev *dev, int nent, + return 0; + + err_radix: +- spin_lock_irq(&cq_table->lock); ++ spin_lock(&cq_table->lock); + radix_tree_delete(&cq_table->tree, cq->cqn); +- spin_unlock_irq(&cq_table->lock); ++ spin_unlock(&cq_table->lock); + + err_icm: + mlx4_cq_free_icm(dev, cq->cqn); +@@ -370,15 +372,15 @@ void mlx4_cq_free(struct mlx4_dev *dev, struct mlx4_cq *cq) + if (err) + mlx4_warn(dev, "HW2SW_CQ failed (%d) for CQN %06x\n", err, cq->cqn); + ++ spin_lock(&cq_table->lock); ++ radix_tree_delete(&cq_table->tree, cq->cqn); ++ spin_unlock(&cq_table->lock); ++ + synchronize_irq(priv->eq_table.eq[MLX4_CQ_TO_EQ_VECTOR(cq->vector)].irq); + if (priv->eq_table.eq[MLX4_CQ_TO_EQ_VECTOR(cq->vector)].irq != + priv->eq_table.eq[MLX4_EQ_ASYNC].irq) + synchronize_irq(priv->eq_table.eq[MLX4_EQ_ASYNC].irq); + +- spin_lock_irq(&cq_table->lock); +- radix_tree_delete(&cq_table->tree, cq->cqn); +- spin_unlock_irq(&cq_table->lock); +- + if (atomic_dec_and_test(&cq->refcount)) + complete(&cq->free); + wait_for_completion(&cq->free); +-- +2.12.0 + diff --git a/queue/net-mlx4_core-Fix-when-to-save-some-qp-context-flags.patch b/queue/net-mlx4_core-Fix-when-to-save-some-qp-context-flags.patch new file mode 100644 index 0000000..f386e25 --- /dev/null +++ b/queue/net-mlx4_core-Fix-when-to-save-some-qp-context-flags.patch @@ -0,0 +1,56 @@ +From 7c3945bc2073554bb2ecf983e073dee686679c53 Mon Sep 17 00:00:00 2001 +From: Jack Morgenstein <jackm@dev.mellanox.co.il> +Date: Mon, 16 Jan 2017 18:31:38 +0200 +Subject: [PATCH] net/mlx4_core: Fix when to save some qp context flags for + dynamic VST to VGT transitions + +commit 7c3945bc2073554bb2ecf983e073dee686679c53 upstream. + +Save the qp context flags byte containing the flag disabling vlan stripping +in the RESET to INIT qp transition, rather than in the INIT to RTR +transition. Per the firmware spec, the flags in this byte are active +in the RESET to INIT transition. + +As a result of saving the flags in the incorrect qp transition, when +switching dynamically from VGT to VST and back to VGT, the vlan +remained stripped (as is required for VST) and did not return to +not-stripped (as is required for VGT). + +Fixes: f0f829bf42cd ("net/mlx4_core: Add immediate activate for VGT->VST->VGT") +Signed-off-by: Jack Morgenstein <jackm@dev.mellanox.co.il> +Signed-off-by: Tariq Toukan <tariqt@mellanox.com> +Signed-off-by: David S. Miller <davem@davemloft.net> + +diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c +index 56185a0b827d..1822382212ee 100644 +--- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c ++++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c +@@ -2980,6 +2980,9 @@ int mlx4_RST2INIT_QP_wrapper(struct mlx4_dev *dev, int slave, + put_res(dev, slave, srqn, RES_SRQ); + qp->srq = srq; + } ++ ++ /* Save param3 for dynamic changes from VST back to VGT */ ++ qp->param3 = qpc->param3; + put_res(dev, slave, rcqn, RES_CQ); + put_res(dev, slave, mtt_base, RES_MTT); + res_end_move(dev, slave, RES_QP, qpn); +@@ -3772,7 +3775,6 @@ int mlx4_INIT2RTR_QP_wrapper(struct mlx4_dev *dev, int slave, + int qpn = vhcr->in_modifier & 0x7fffff; + struct res_qp *qp; + u8 orig_sched_queue; +- __be32 orig_param3 = qpc->param3; + u8 orig_vlan_control = qpc->pri_path.vlan_control; + u8 orig_fvl_rx = qpc->pri_path.fvl_rx; + u8 orig_pri_path_fl = qpc->pri_path.fl; +@@ -3814,7 +3816,6 @@ out: + */ + if (!err) { + qp->sched_queue = orig_sched_queue; +- qp->param3 = orig_param3; + qp->vlan_control = orig_vlan_control; + qp->fvl_rx = orig_fvl_rx; + qp->pri_path_fl = orig_pri_path_fl; +-- +2.12.0 + diff --git a/queue/net-mlx4_core-Use-device-ID-defines.patch b/queue/net-mlx4_core-Use-device-ID-defines.patch new file mode 100644 index 0000000..b01f34b --- /dev/null +++ b/queue/net-mlx4_core-Use-device-ID-defines.patch @@ -0,0 +1,114 @@ +From c19e4b9037fa8a0477525a64e93847f534e8cc17 Mon Sep 17 00:00:00 2001 +From: Bjorn Helgaas <bhelgaas@google.com> +Date: Thu, 17 Nov 2016 16:11:39 -0600 +Subject: [PATCH] net/mlx4_core: Use device ID defines + +commit c19e4b9037fa8a0477525a64e93847f534e8cc17 upstream. + +We added a bunch of new Mellanox device ID definitions because they'll be +used by INTx quirks. Use them in the mlx4 ID table also so grep can find +both places. No functional change intended. + +Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> +Acked-by: Tariq Toukan <tariqt@mellanox.com> + +diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c +index 7183ac4135d2..62788b7c728d 100644 +--- a/drivers/net/ethernet/mellanox/mlx4/main.c ++++ b/drivers/net/ethernet/mellanox/mlx4/main.c +@@ -4012,49 +4012,51 @@ int mlx4_restart_one(struct pci_dev *pdev) + return err; + } + ++#define MLX_SP(id) { PCI_VDEVICE(MELLANOX, id), MLX4_PCI_DEV_FORCE_SENSE_PORT } ++#define MLX_VF(id) { PCI_VDEVICE(MELLANOX, id), MLX4_PCI_DEV_IS_VF } ++#define MLX_GN(id) { PCI_VDEVICE(MELLANOX, id), 0 } ++ + static const struct pci_device_id mlx4_pci_table[] = { +- /* MT25408 "Hermon" SDR */ +- { PCI_VDEVICE(MELLANOX, 0x6340), MLX4_PCI_DEV_FORCE_SENSE_PORT }, +- /* MT25408 "Hermon" DDR */ +- { PCI_VDEVICE(MELLANOX, 0x634a), MLX4_PCI_DEV_FORCE_SENSE_PORT }, +- /* MT25408 "Hermon" QDR */ +- { PCI_VDEVICE(MELLANOX, 0x6354), MLX4_PCI_DEV_FORCE_SENSE_PORT }, +- /* MT25408 "Hermon" DDR PCIe gen2 */ +- { PCI_VDEVICE(MELLANOX, 0x6732), MLX4_PCI_DEV_FORCE_SENSE_PORT }, +- /* MT25408 "Hermon" QDR PCIe gen2 */ +- { PCI_VDEVICE(MELLANOX, 0x673c), MLX4_PCI_DEV_FORCE_SENSE_PORT }, +- /* MT25408 "Hermon" EN 10GigE */ +- { PCI_VDEVICE(MELLANOX, 0x6368), MLX4_PCI_DEV_FORCE_SENSE_PORT }, +- /* MT25408 "Hermon" EN 10GigE PCIe gen2 */ +- { PCI_VDEVICE(MELLANOX, 0x6750), MLX4_PCI_DEV_FORCE_SENSE_PORT }, +- /* MT25458 ConnectX EN 10GBASE-T 10GigE */ +- { PCI_VDEVICE(MELLANOX, 0x6372), MLX4_PCI_DEV_FORCE_SENSE_PORT }, +- /* MT25458 ConnectX EN 10GBASE-T+Gen2 10GigE */ +- { PCI_VDEVICE(MELLANOX, 0x675a), MLX4_PCI_DEV_FORCE_SENSE_PORT }, +- /* MT26468 ConnectX EN 10GigE PCIe gen2*/ +- { PCI_VDEVICE(MELLANOX, 0x6764), MLX4_PCI_DEV_FORCE_SENSE_PORT }, +- /* MT26438 ConnectX EN 40GigE PCIe gen2 5GT/s */ +- { PCI_VDEVICE(MELLANOX, 0x6746), MLX4_PCI_DEV_FORCE_SENSE_PORT }, +- /* MT26478 ConnectX2 40GigE PCIe gen2 */ +- { PCI_VDEVICE(MELLANOX, 0x676e), MLX4_PCI_DEV_FORCE_SENSE_PORT }, +- /* MT25400 Family [ConnectX-2 Virtual Function] */ +- { PCI_VDEVICE(MELLANOX, 0x1002), MLX4_PCI_DEV_IS_VF }, ++ /* MT25408 "Hermon" */ ++ MLX_SP(PCI_DEVICE_ID_MELLANOX_HERMON_SDR), /* SDR */ ++ MLX_SP(PCI_DEVICE_ID_MELLANOX_HERMON_DDR), /* DDR */ ++ MLX_SP(PCI_DEVICE_ID_MELLANOX_HERMON_QDR), /* QDR */ ++ MLX_SP(PCI_DEVICE_ID_MELLANOX_HERMON_DDR_GEN2), /* DDR Gen2 */ ++ MLX_SP(PCI_DEVICE_ID_MELLANOX_HERMON_QDR_GEN2), /* QDR Gen2 */ ++ MLX_SP(PCI_DEVICE_ID_MELLANOX_HERMON_EN), /* EN 10GigE */ ++ MLX_SP(PCI_DEVICE_ID_MELLANOX_HERMON_EN_GEN2), /* EN 10GigE Gen2 */ ++ /* MT25458 ConnectX EN 10GBASE-T */ ++ MLX_SP(PCI_DEVICE_ID_MELLANOX_CONNECTX_EN), ++ MLX_SP(PCI_DEVICE_ID_MELLANOX_CONNECTX_EN_T_GEN2), /* Gen2 */ ++ /* MT26468 ConnectX EN 10GigE PCIe Gen2*/ ++ MLX_SP(PCI_DEVICE_ID_MELLANOX_CONNECTX_EN_GEN2), ++ /* MT26438 ConnectX EN 40GigE PCIe Gen2 5GT/s */ ++ MLX_SP(PCI_DEVICE_ID_MELLANOX_CONNECTX_EN_5_GEN2), ++ /* MT26478 ConnectX2 40GigE PCIe Gen2 */ ++ MLX_SP(PCI_DEVICE_ID_MELLANOX_CONNECTX2), ++ /* MT25400 Family [ConnectX-2] */ ++ MLX_VF(0x1002), /* Virtual Function */ + /* MT27500 Family [ConnectX-3] */ +- { PCI_VDEVICE(MELLANOX, 0x1003), 0 }, +- /* MT27500 Family [ConnectX-3 Virtual Function] */ +- { PCI_VDEVICE(MELLANOX, 0x1004), MLX4_PCI_DEV_IS_VF }, +- { PCI_VDEVICE(MELLANOX, 0x1005), 0 }, /* MT27510 Family */ +- { PCI_VDEVICE(MELLANOX, 0x1006), 0 }, /* MT27511 Family */ +- { PCI_VDEVICE(MELLANOX, 0x1007), 0 }, /* MT27520 Family */ +- { PCI_VDEVICE(MELLANOX, 0x1008), 0 }, /* MT27521 Family */ +- { PCI_VDEVICE(MELLANOX, 0x1009), 0 }, /* MT27530 Family */ +- { PCI_VDEVICE(MELLANOX, 0x100a), 0 }, /* MT27531 Family */ +- { PCI_VDEVICE(MELLANOX, 0x100b), 0 }, /* MT27540 Family */ +- { PCI_VDEVICE(MELLANOX, 0x100c), 0 }, /* MT27541 Family */ +- { PCI_VDEVICE(MELLANOX, 0x100d), 0 }, /* MT27550 Family */ +- { PCI_VDEVICE(MELLANOX, 0x100e), 0 }, /* MT27551 Family */ +- { PCI_VDEVICE(MELLANOX, 0x100f), 0 }, /* MT27560 Family */ +- { PCI_VDEVICE(MELLANOX, 0x1010), 0 }, /* MT27561 Family */ ++ MLX_GN(PCI_DEVICE_ID_MELLANOX_CONNECTX3), ++ MLX_VF(0x1004), /* Virtual Function */ ++ MLX_GN(0x1005), /* MT27510 Family */ ++ MLX_GN(0x1006), /* MT27511 Family */ ++ MLX_GN(PCI_DEVICE_ID_MELLANOX_CONNECTX3_PRO), /* MT27520 Family */ ++ MLX_GN(0x1008), /* MT27521 Family */ ++ MLX_GN(0x1009), /* MT27530 Family */ ++ MLX_GN(0x100a), /* MT27531 Family */ ++ MLX_GN(0x100b), /* MT27540 Family */ ++ MLX_GN(0x100c), /* MT27541 Family */ ++ MLX_GN(0x100d), /* MT27550 Family */ ++ MLX_GN(0x100e), /* MT27551 Family */ ++ MLX_GN(0x100f), /* MT27560 Family */ ++ MLX_GN(0x1010), /* MT27561 Family */ ++ ++ /* ++ * See the mellanox_check_broken_intx_masking() quirk when ++ * adding devices ++ */ ++ + { 0, } + }; + +-- +2.12.0 + diff --git a/queue/net-mlx4_en-Fix-bad-WQE-issue.patch b/queue/net-mlx4_en-Fix-bad-WQE-issue.patch new file mode 100644 index 0000000..c9e620e --- /dev/null +++ b/queue/net-mlx4_en-Fix-bad-WQE-issue.patch @@ -0,0 +1,39 @@ +From 6496bbf0ec481966ef9ffe5b6660d8d1b55c60cc Mon Sep 17 00:00:00 2001 +From: Eugenia Emantayev <eugenia@mellanox.com> +Date: Thu, 29 Dec 2016 18:37:10 +0200 +Subject: [PATCH] net/mlx4_en: Fix bad WQE issue + +commit 6496bbf0ec481966ef9ffe5b6660d8d1b55c60cc upstream. + +Single send WQE in RX buffer should be stamped with software +ownership in order to prevent the flow of QP in error in FW +once UPDATE_QP is called. + +Fixes: 9f519f68cfff ('mlx4_en: Not using Shared Receive Queues') +Signed-off-by: Eugenia Emantayev <eugenia@mellanox.com> +Signed-off-by: Tariq Toukan <tariqt@mellanox.com> +Signed-off-by: David S. Miller <davem@davemloft.net> + +diff --git a/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/drivers/net/ethernet/mellanox/mlx4/en_rx.c +index 3c37e216bbf3..eac527e25ec9 100644 +--- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c ++++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c +@@ -445,8 +445,14 @@ int mlx4_en_activate_rx_rings(struct mlx4_en_priv *priv) + ring->cqn = priv->rx_cq[ring_ind]->mcq.cqn; + + ring->stride = stride; +- if (ring->stride <= TXBB_SIZE) ++ if (ring->stride <= TXBB_SIZE) { ++ /* Stamp first unused send wqe */ ++ __be32 *ptr = (__be32 *)ring->buf; ++ __be32 stamp = cpu_to_be32(1 << STAMP_SHIFT); ++ *ptr = stamp; ++ /* Move pointer to start of rx section */ + ring->buf += TXBB_SIZE; ++ } + + ring->log_stride = ffs(ring->stride) - 1; + ring->buf_size = ring->size * ring->stride; +-- +2.12.0 + diff --git a/queue/net-packet-fix-overflow-in-check-for-priv-area-size.patch b/queue/net-packet-fix-overflow-in-check-for-priv-area-size.patch new file mode 100644 index 0000000..ec99b93 --- /dev/null +++ b/queue/net-packet-fix-overflow-in-check-for-priv-area-size.patch @@ -0,0 +1,38 @@ +From 2b6867c2ce76c596676bec7d2d525af525fdc6e2 Mon Sep 17 00:00:00 2001 +From: Andrey Konovalov <andreyknvl@google.com> +Date: Wed, 29 Mar 2017 16:11:20 +0200 +Subject: [PATCH] net/packet: fix overflow in check for priv area size + +commit 2b6867c2ce76c596676bec7d2d525af525fdc6e2 upstream. + +Subtracting tp_sizeof_priv from tp_block_size and casting to int +to check whether one is less then the other doesn't always work +(both of them are unsigned ints). + +Compare them as is instead. + +Also cast tp_sizeof_priv to u64 before using BLK_PLUS_PRIV, as +it can overflow inside BLK_PLUS_PRIV otherwise. + +Signed-off-by: Andrey Konovalov <andreyknvl@google.com> +Acked-by: Eric Dumazet <edumazet@google.com> +Signed-off-by: David S. Miller <davem@davemloft.net> + +diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c +index a0dbe7ca8f72..2323ee35dc09 100644 +--- a/net/packet/af_packet.c ++++ b/net/packet/af_packet.c +@@ -4193,8 +4193,8 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u, + if (unlikely(!PAGE_ALIGNED(req->tp_block_size))) + goto out; + if (po->tp_version >= TPACKET_V3 && +- (int)(req->tp_block_size - +- BLK_PLUS_PRIV(req_u->req3.tp_sizeof_priv)) <= 0) ++ req->tp_block_size <= ++ BLK_PLUS_PRIV((u64)req_u->req3.tp_sizeof_priv)) + goto out; + if (unlikely(req->tp_frame_size < po->tp_hdrlen + + po->tp_reserve)) +-- +2.12.0 + diff --git a/queue/nios2-reserve-boot-memory-for-device-tree.patch b/queue/nios2-reserve-boot-memory-for-device-tree.patch new file mode 100644 index 0000000..ddab018 --- /dev/null +++ b/queue/nios2-reserve-boot-memory-for-device-tree.patch @@ -0,0 +1,71 @@ +From 921d701e6f31e1ffaca3560416af1aa04edb4c4f Mon Sep 17 00:00:00 2001 +From: Tobias Klauser <tklauser@distanz.ch> +Date: Sun, 2 Apr 2017 20:08:04 -0700 +Subject: [PATCH] nios2: reserve boot memory for device tree + +commit 921d701e6f31e1ffaca3560416af1aa04edb4c4f upstream. + +Make sure to reserve the boot memory for the flattened device tree. +Otherwise it might get overwritten, e.g. when initial_boot_params is +copied, leading to a corrupted FDT and a boot hang/crash: + + bootconsole [early0] enabled + Early console on uart16650 initialized at 0xf8001600 + OF: fdt: Error -11 processing FDT + Kernel panic - not syncing: setup_cpuinfo: No CPU found in devicetree! + + ---[ end Kernel panic - not syncing: setup_cpuinfo: No CPU found in devicetree! + +Guenter Roeck says: + +> I think I found the problem. In unflatten_and_copy_device_tree(), with added +> debug information: +> +> OF: fdt: initial_boot_params=c861e400, dt=c861f000 size=28874 (0x70ca) +> +> ... and then initial_boot_params is copied to dt, which results in corrupted +> fdt since the memory overlaps. Looks like the initial_boot_params memory +> is not reserved and (re-)allocated by early_init_dt_alloc_memory_arch(). + +Cc: stable@vger.kernel.org +Reported-by: Guenter Roeck <linux@roeck-us.net> +Reference: http://lkml.kernel.org/r/20170226210338.GA19476@roeck-us.net +Tested-by: Guenter Roeck <linux@roeck-us.net> +Signed-off-by: Tobias Klauser <tklauser@distanz.ch> +Acked-by: Ley Foon Tan <ley.foon.tan@intel.com> + +diff --git a/arch/nios2/kernel/prom.c b/arch/nios2/kernel/prom.c +index 367c5426157b..3901b80d4420 100644 +--- a/arch/nios2/kernel/prom.c ++++ b/arch/nios2/kernel/prom.c +@@ -48,6 +48,13 @@ void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align) + return alloc_bootmem_align(size, align); + } + ++int __init early_init_dt_reserve_memory_arch(phys_addr_t base, phys_addr_t size, ++ bool nomap) ++{ ++ reserve_bootmem(base, size, BOOTMEM_DEFAULT); ++ return 0; ++} ++ + void __init early_init_devtree(void *params) + { + __be32 *dtb = (u32 *)__dtb_start; +diff --git a/arch/nios2/kernel/setup.c b/arch/nios2/kernel/setup.c +index 6e57ffa5db27..6044d9be28b4 100644 +--- a/arch/nios2/kernel/setup.c ++++ b/arch/nios2/kernel/setup.c +@@ -201,6 +201,9 @@ void __init setup_arch(char **cmdline_p) + } + #endif /* CONFIG_BLK_DEV_INITRD */ + ++ early_init_fdt_reserve_self(); ++ early_init_fdt_scan_reserved_mem(); ++ + unflatten_and_copy_device_tree(); + + setup_cpuinfo(); +-- +2.12.0 + diff --git a/queue/nvme-simplify-stripe-quirk.patch b/queue/nvme-simplify-stripe-quirk.patch new file mode 100644 index 0000000..5543e06 --- /dev/null +++ b/queue/nvme-simplify-stripe-quirk.patch @@ -0,0 +1,72 @@ +From e6282aef7b89a11d26e731060c4409b7aac278bf Mon Sep 17 00:00:00 2001 +From: Keith Busch <keith.busch@intel.com> +Date: Mon, 19 Dec 2016 11:37:50 -0500 +Subject: [PATCH] nvme: simplify stripe quirk + +commit e6282aef7b89a11d26e731060c4409b7aac278bf upstream. + +Some OEMs believe they own the Identify Controller vendor specific +region and will repurpose it with their own values. While not common, +we can't rely on the PCI VID:DID to tell use how to decode the field +we reserved for this as the stripe size so we need to do something else +for the list of devices using this quirk. + +The field was supposed to allow flexibility on the device's back-end +striping, but it turned out that never materialized; the chunk is always +the same as MDTS in the products subscribing to this quirk, so this +patch removes the stripe_size field and sets the chunk to the max hw +transfer size for the devices using this quirk. + +Signed-off-by: Keith Busch <keith.busch@intel.com> +Signed-off-by: Christoph Hellwig <hch@lst.de> + +diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c +index b40cfb076f02..2fc86dc7a8df 100644 +--- a/drivers/nvme/host/core.c ++++ b/drivers/nvme/host/core.c +@@ -1193,8 +1193,8 @@ static void nvme_set_queue_limits(struct nvme_ctrl *ctrl, + blk_queue_max_hw_sectors(q, ctrl->max_hw_sectors); + blk_queue_max_segments(q, min_t(u32, max_segments, USHRT_MAX)); + } +- if (ctrl->stripe_size) +- blk_queue_chunk_sectors(q, ctrl->stripe_size >> 9); ++ if (ctrl->quirks & NVME_QUIRK_STRIPE_SIZE) ++ blk_queue_chunk_sectors(q, ctrl->max_hw_sectors); + blk_queue_virt_boundary(q, ctrl->page_size - 1); + if (ctrl->vwc & NVME_CTRL_VWC_PRESENT) + vwc = true; +@@ -1250,19 +1250,6 @@ int nvme_init_identify(struct nvme_ctrl *ctrl) + ctrl->max_hw_sectors = + min_not_zero(ctrl->max_hw_sectors, max_hw_sectors); + +- if ((ctrl->quirks & NVME_QUIRK_STRIPE_SIZE) && id->vs[3]) { +- unsigned int max_hw_sectors; +- +- ctrl->stripe_size = 1 << (id->vs[3] + page_shift); +- max_hw_sectors = ctrl->stripe_size >> (page_shift - 9); +- if (ctrl->max_hw_sectors) { +- ctrl->max_hw_sectors = min(max_hw_sectors, +- ctrl->max_hw_sectors); +- } else { +- ctrl->max_hw_sectors = max_hw_sectors; +- } +- } +- + nvme_set_queue_limits(ctrl, ctrl->admin_q); + ctrl->sgls = le32_to_cpu(id->sgls); + ctrl->kas = le16_to_cpu(id->kas); +diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h +index bd5321441d12..6377e14586dc 100644 +--- a/drivers/nvme/host/nvme.h ++++ b/drivers/nvme/host/nvme.h +@@ -135,7 +135,6 @@ struct nvme_ctrl { + + u32 page_size; + u32 max_hw_sectors; +- u32 stripe_size; + u16 oncs; + u16 vid; + atomic_t abort_limit; +-- +2.12.0 + diff --git a/queue/orangefs-Dan-Carpenter-influenced-cleanups.patch b/queue/orangefs-Dan-Carpenter-influenced-cleanups.patch new file mode 100644 index 0000000..4004b6c --- /dev/null +++ b/queue/orangefs-Dan-Carpenter-influenced-cleanups.patch @@ -0,0 +1,88 @@ +From 05973c2efb40122f2a9ecde2d065f7ea5068d024 Mon Sep 17 00:00:00 2001 +From: Mike Marshall <hubcap@omnibond.com> +Date: Thu, 9 Feb 2017 14:38:50 -0500 +Subject: [PATCH] orangefs: Dan Carpenter influenced cleanups... + +commit 05973c2efb40122f2a9ecde2d065f7ea5068d024 upstream. + +This patch is simlar to one Dan Carpenter sent me, cleans +up some return codes and whitespace errors. There was one +place where he thought inserting an error message into +the ring buffer might be too chatty, I hope I convinced him +othewise. As a consolation <g> I changed a truly chatty +error message in another location into a debug message, +system-admins had already yelled at me about that one... + +Signed-off-by: Mike Marshall <hubcap@omnibond.com> + +diff --git a/fs/orangefs/devorangefs-req.c b/fs/orangefs/devorangefs-req.c +index 516ffb4dc9a0..f419dd999581 100644 +--- a/fs/orangefs/devorangefs-req.c ++++ b/fs/orangefs/devorangefs-req.c +@@ -402,8 +402,9 @@ static ssize_t orangefs_devreq_write_iter(struct kiocb *iocb, + /* remove the op from the in progress hash table */ + op = orangefs_devreq_remove_op(head.tag); + if (!op) { +- gossip_err("WARNING: No one's waiting for tag %llu\n", +- llu(head.tag)); ++ gossip_debug(GOSSIP_DEV_DEBUG, ++ "%s: No one's waiting for tag %llu\n", ++ __func__, llu(head.tag)); + return ret; + } + +diff --git a/fs/orangefs/orangefs-debugfs.c b/fs/orangefs/orangefs-debugfs.c +index b5dbc9c6530c..0748a26598fc 100644 +--- a/fs/orangefs/orangefs-debugfs.c ++++ b/fs/orangefs/orangefs-debugfs.c +@@ -965,13 +965,13 @@ int orangefs_debugfs_new_client_string(void __user *arg) + int ret; + + ret = copy_from_user(&client_debug_array_string, +- (void __user *)arg, +- ORANGEFS_MAX_DEBUG_STRING_LEN); ++ (void __user *)arg, ++ ORANGEFS_MAX_DEBUG_STRING_LEN); + + if (ret != 0) { + pr_info("%s: CLIENT_STRING: copy_from_user failed\n", + __func__); +- return -EIO; ++ return -EFAULT; + } + + /* +@@ -986,17 +986,18 @@ int orangefs_debugfs_new_client_string(void __user *arg) + */ + client_debug_array_string[ORANGEFS_MAX_DEBUG_STRING_LEN - 1] = + '\0'; +- ++ + pr_info("%s: client debug array string has been received.\n", + __func__); + + if (!help_string_initialized) { + + /* Build a proper debug help string. */ +- if (orangefs_prepare_debugfs_help_string(0)) { ++ ret = orangefs_prepare_debugfs_help_string(0); ++ if (ret) { + gossip_err("%s: no debug help string \n", + __func__); +- return -EIO; ++ return ret; + } + + } +@@ -1009,7 +1010,7 @@ int orangefs_debugfs_new_client_string(void __user *arg) + + help_string_initialized++; + +- return ret; ++ return 0; + } + + int orangefs_debugfs_new_debug(void __user *arg) +-- +2.12.0 + diff --git a/queue/orangefs-fix-buffer-size-mis-match-between-kernel-sp.patch b/queue/orangefs-fix-buffer-size-mis-match-between-kernel-sp.patch new file mode 100644 index 0000000..d072613 --- /dev/null +++ b/queue/orangefs-fix-buffer-size-mis-match-between-kernel-sp.patch @@ -0,0 +1,36 @@ +From eb68d0324dc4d88ab0d6159bdcd98c247a3a8954 Mon Sep 17 00:00:00 2001 +From: Mike Marshall <hubcap@omnibond.com> +Date: Tue, 7 Feb 2017 12:41:02 -0500 +Subject: [PATCH] orangefs: fix buffer size mis-match between kernel space and + user space. + +commit eb68d0324dc4d88ab0d6159bdcd98c247a3a8954 upstream. + +The deamon through which the kernel module communicates with the userspace +part of Orangefs, the "client-core", sends initialization data to the +kernel module with ioctl. The initialization data was built by the +client-core in a 2k buffer and copy_from_user'd into a 1k buffer +in the kernel module. When more than 1k of initialization data needed +to be sent, some was lost, reducing the usability of the control by which +debug levels are set. This patch sets the kernel side buffer to 2K to +match the userspace side... + +Signed-off-by: Mike Marshall <hubcap@omnibond.com> + +diff --git a/fs/orangefs/orangefs-dev-proto.h b/fs/orangefs/orangefs-dev-proto.h +index a3d84ffee905..f380f9ed1b28 100644 +--- a/fs/orangefs/orangefs-dev-proto.h ++++ b/fs/orangefs/orangefs-dev-proto.h +@@ -50,8 +50,7 @@ + * Misc constants. Please retain them as multiples of 8! + * Otherwise 32-64 bit interactions will be messed up :) + */ +-#define ORANGEFS_MAX_DEBUG_STRING_LEN 0x00000400 +-#define ORANGEFS_MAX_DEBUG_ARRAY_LEN 0x00000800 ++#define ORANGEFS_MAX_DEBUG_STRING_LEN 0x00000800 + + /* + * The maximum number of directory entries in a single request is 96. +-- +2.12.0 + diff --git a/queue/orangefs-fix-memory-leak-of-string-new-on-exit-path.patch b/queue/orangefs-fix-memory-leak-of-string-new-on-exit-path.patch new file mode 100644 index 0000000..3c3c868 --- /dev/null +++ b/queue/orangefs-fix-memory-leak-of-string-new-on-exit-path.patch @@ -0,0 +1,34 @@ +From 4defb5f912a0ba60e07e91a4b62634814cd99b7f Mon Sep 17 00:00:00 2001 +From: Colin Ian King <colin.king@canonical.com> +Date: Fri, 2 Dec 2016 15:18:06 +0000 +Subject: [PATCH] orangefs: fix memory leak of string 'new' on exit path + +commit 4defb5f912a0ba60e07e91a4b62634814cd99b7f upstream. + +allocates string 'new' is not free'd on the exit path when +cdm_element_count <= 0. Fix this by kfree'ing it. + +Fixes CoverityScan CID#1375923 "Resource Leak" + +Signed-off-by: Colin Ian King <colin.king@canonical.com> +Signed-off-by: Mike Marshall <hubcap@omnibond.com> + +diff --git a/fs/orangefs/orangefs-debugfs.c b/fs/orangefs/orangefs-debugfs.c +index 38887cc5577f..b5dbc9c6530c 100644 +--- a/fs/orangefs/orangefs-debugfs.c ++++ b/fs/orangefs/orangefs-debugfs.c +@@ -671,8 +671,10 @@ int orangefs_prepare_debugfs_help_string(int at_boot) + */ + cdm_element_count = + orangefs_prepare_cdm_array(client_debug_array_string); +- if (cdm_element_count <= 0) ++ if (cdm_element_count <= 0) { ++ kfree(new); + goto out; ++ } + + for (i = 0; i < cdm_element_count; i++) { + strlcat(new, "\t", string_size); +-- +2.12.0 + diff --git a/queue/orangefs-free-superblock-when-mount-fails.patch b/queue/orangefs-free-superblock-when-mount-fails.patch new file mode 100644 index 0000000..4dbe619 --- /dev/null +++ b/queue/orangefs-free-superblock-when-mount-fails.patch @@ -0,0 +1,121 @@ +From 1ec1688c5360e14dde4094d6acbf7516bf6db37e Mon Sep 17 00:00:00 2001 +From: Martin Brandenburg <martin@omnibond.com> +Date: Fri, 14 Apr 2017 14:22:41 -0400 +Subject: [PATCH] orangefs: free superblock when mount fails + +commit 1ec1688c5360e14dde4094d6acbf7516bf6db37e upstream. + +Otherwise lockdep says: + +[ 1337.483798] ================================================ +[ 1337.483999] [ BUG: lock held when returning to user space! ] +[ 1337.484252] 4.11.0-rc6 #19 Not tainted +[ 1337.484423] ------------------------------------------------ +[ 1337.484626] mount/14766 is leaving the kernel with locks still held! +[ 1337.484841] 1 lock held by mount/14766: +[ 1337.485017] #0: (&type->s_umount_key#33/1){+.+.+.}, at: [<ffffffff8124171f>] sget_userns+0x2af/0x520 + +Caught by xfstests generic/413 which tried to mount with the unsupported +mount option dax. Then xfstests generic/422 ran sync which deadlocks. + +Signed-off-by: Martin Brandenburg <martin@omnibond.com> +Acked-by: Mike Marshall <hubcap@omnibond.com> +Cc: stable@vger.kernel.org +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> + +diff --git a/fs/orangefs/devorangefs-req.c b/fs/orangefs/devorangefs-req.c +index c4ab6fdf17a0..e1534c9bab16 100644 +--- a/fs/orangefs/devorangefs-req.c ++++ b/fs/orangefs/devorangefs-req.c +@@ -208,14 +208,19 @@ restart: + continue; + /* + * Skip ops whose filesystem we don't know about unless +- * it is being mounted. ++ * it is being mounted or unmounted. It is possible for ++ * a filesystem we don't know about to be unmounted if ++ * it fails to mount in the kernel after userspace has ++ * been sent the mount request. + */ + /* XXX: is there a better way to detect this? */ + } else if (ret == -1 && + !(op->upcall.type == + ORANGEFS_VFS_OP_FS_MOUNT || + op->upcall.type == +- ORANGEFS_VFS_OP_GETATTR)) { ++ ORANGEFS_VFS_OP_GETATTR || ++ op->upcall.type == ++ ORANGEFS_VFS_OP_FS_UMOUNT)) { + gossip_debug(GOSSIP_DEV_DEBUG, + "orangefs: skipping op tag %llu %s\n", + llu(op->tag), get_opname_string(op)); +diff --git a/fs/orangefs/orangefs-kernel.h b/fs/orangefs/orangefs-kernel.h +index 5e48a0be9761..8afac46fcc87 100644 +--- a/fs/orangefs/orangefs-kernel.h ++++ b/fs/orangefs/orangefs-kernel.h +@@ -249,6 +249,7 @@ struct orangefs_sb_info_s { + char devname[ORANGEFS_MAX_SERVER_ADDR_LEN]; + struct super_block *sb; + int mount_pending; ++ int no_list; + struct list_head list; + }; + +diff --git a/fs/orangefs/super.c b/fs/orangefs/super.c +index cd261c8de53a..629d8c917fa6 100644 +--- a/fs/orangefs/super.c ++++ b/fs/orangefs/super.c +@@ -493,7 +493,7 @@ struct dentry *orangefs_mount(struct file_system_type *fst, + + if (ret) { + d = ERR_PTR(ret); +- goto free_op; ++ goto free_sb_and_op; + } + + /* +@@ -519,6 +519,9 @@ struct dentry *orangefs_mount(struct file_system_type *fst, + spin_unlock(&orangefs_superblocks_lock); + op_release(new_op); + ++ /* Must be removed from the list now. */ ++ ORANGEFS_SB(sb)->no_list = 0; ++ + if (orangefs_userspace_version >= 20906) { + new_op = op_alloc(ORANGEFS_VFS_OP_FEATURES); + if (!new_op) +@@ -533,6 +536,10 @@ struct dentry *orangefs_mount(struct file_system_type *fst, + + return dget(sb->s_root); + ++free_sb_and_op: ++ /* Will call orangefs_kill_sb with sb not in list. */ ++ ORANGEFS_SB(sb)->no_list = 1; ++ deactivate_locked_super(sb); + free_op: + gossip_err("orangefs_mount: mount request failed with %d\n", ret); + if (ret == -EINVAL) { +@@ -558,12 +565,14 @@ void orangefs_kill_sb(struct super_block *sb) + */ + orangefs_unmount_sb(sb); + +- /* remove the sb from our list of orangefs specific sb's */ +- +- spin_lock(&orangefs_superblocks_lock); +- __list_del_entry(&ORANGEFS_SB(sb)->list); /* not list_del_init */ +- ORANGEFS_SB(sb)->list.prev = NULL; +- spin_unlock(&orangefs_superblocks_lock); ++ if (!ORANGEFS_SB(sb)->no_list) { ++ /* remove the sb from our list of orangefs specific sb's */ ++ spin_lock(&orangefs_superblocks_lock); ++ /* not list_del_init */ ++ __list_del_entry(&ORANGEFS_SB(sb)->list); ++ ORANGEFS_SB(sb)->list.prev = NULL; ++ spin_unlock(&orangefs_superblocks_lock); ++ } + + /* + * make sure that ORANGEFS_DEV_REMOUNT_ALL loop that might've seen us +-- +2.12.0 + diff --git a/queue/orangefs-move-features-validation-to-fix-filesystem-.patch b/queue/orangefs-move-features-validation-to-fix-filesystem-.patch new file mode 100644 index 0000000..2e817a5 --- /dev/null +++ b/queue/orangefs-move-features-validation-to-fix-filesystem-.patch @@ -0,0 +1,84 @@ +From cefdc26e86728812aea54248a534fd4a5da2a43d Mon Sep 17 00:00:00 2001 +From: Martin Brandenburg <martin@omnibond.com> +Date: Thu, 6 Apr 2017 18:11:00 -0400 +Subject: [PATCH] orangefs: move features validation to fix filesystem hang + +commit cefdc26e86728812aea54248a534fd4a5da2a43d upstream. + +Without this fix (and another to the userspace component itself +described later), the kernel will be unable to process any OrangeFS +requests after the userspace component is restarted (due to a crash or +at the administrator's behest). + +The bug here is that inside orangefs_remount, the orangefs_request_mutex +is locked. When the userspace component restarts while the filesystem +is mounted, it sends a ORANGEFS_DEV_REMOUNT_ALL ioctl to the device, +which causes the kernel to send it a few requests aimed at synchronizing +the state between the two. While this is happening the +orangefs_request_mutex is locked to prevent any other requests going +through. + +This is only half of the bugfix. The other half is in the userspace +component which outright ignores(!) requests made before it considers +the filesystem remounted, which is after the ioctl returns. Of course +the ioctl doesn't return until after the userspace component responds to +the request it ignores. The userspace component has been changed to +allow ORANGEFS_VFS_OP_FEATURES regardless of the mount status. + +Mike Marshall says: + "I've tested this patch against the fixed userspace part. This patch is + real important, I hope it can make it into 4.11... + + Here's what happens when the userspace daemon is restarted, without + the patch: + + ============================================= + [ INFO: possible recursive locking detected ] + [ 4.10.0-00007-ge98bdb3 #1 Not tainted ] + --------------------------------------------- + pvfs2-client-co/29032 is trying to acquire lock: + (orangefs_request_mutex){+.+.+.}, at: service_operation+0x3c7/0x7b0 [orangefs] + but task is already holding lock: + (orangefs_request_mutex){+.+.+.}, at: dispatch_ioctl_command+0x1bf/0x330 [orangefs] + + CPU: 0 PID: 29032 Comm: pvfs2-client-co Not tainted 4.10.0-00007-ge98bdb3 #1 + Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.9.3-1.fc25 04/01/2014 + Call Trace: + __lock_acquire+0x7eb/0x1290 + lock_acquire+0xe8/0x1d0 + mutex_lock_killable_nested+0x6f/0x6e0 + service_operation+0x3c7/0x7b0 [orangefs] + orangefs_remount+0xea/0x150 [orangefs] + dispatch_ioctl_command+0x227/0x330 [orangefs] + orangefs_devreq_ioctl+0x29/0x70 [orangefs] + do_vfs_ioctl+0xa3/0x6e0 + SyS_ioctl+0x79/0x90" + +Signed-off-by: Martin Brandenburg <martin@omnibond.com> +Acked-by: Mike Marshall <hubcap@omnibond.com> +Cc: stable@vger.kernel.org +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> + +diff --git a/fs/orangefs/super.c b/fs/orangefs/super.c +index 67c24351a67f..cd261c8de53a 100644 +--- a/fs/orangefs/super.c ++++ b/fs/orangefs/super.c +@@ -263,8 +263,13 @@ int orangefs_remount(struct orangefs_sb_info_s *orangefs_sb) + if (!new_op) + return -ENOMEM; + new_op->upcall.req.features.features = 0; +- ret = service_operation(new_op, "orangefs_features", 0); +- orangefs_features = new_op->downcall.resp.features.features; ++ ret = service_operation(new_op, "orangefs_features", ++ ORANGEFS_OP_PRIORITY | ORANGEFS_OP_NO_MUTEX); ++ if (!ret) ++ orangefs_features = ++ new_op->downcall.resp.features.features; ++ else ++ orangefs_features = 0; + op_release(new_op); + } else { + orangefs_features = 0; +-- +2.12.0 + diff --git a/queue/parisc-Fix-get_user-for-64-bit-value-on-32-bit-kerne.patch b/queue/parisc-Fix-get_user-for-64-bit-value-on-32-bit-kerne.patch new file mode 100644 index 0000000..00ad5d7 --- /dev/null +++ b/queue/parisc-Fix-get_user-for-64-bit-value-on-32-bit-kerne.patch @@ -0,0 +1,152 @@ +From 3f795cef0ecdf9bc980dd058d49bdab4b19af1d3 Mon Sep 17 00:00:00 2001 +From: Helge Deller <deller@gmx.de> +Date: Sun, 16 Apr 2017 10:00:14 +0200 +Subject: [PATCH] parisc: Fix get_user() for 64-bit value on 32-bit kernel + +commit 3f795cef0ecdf9bc980dd058d49bdab4b19af1d3 upstream. + +This fixes a bug in which the upper 32-bits of a 64-bit value which is +read by get_user() was lost on a 32-bit kernel. +While touching this code, split out pre-loading of %sr2 space register +and clean up code indent. + +Cc: <stable@vger.kernel.org> # v4.9+ +Signed-off-by: Helge Deller <deller@gmx.de> + +diff --git a/arch/parisc/include/asm/uaccess.h b/arch/parisc/include/asm/uaccess.h +index 8442727f28d2..cbd4f4af8108 100644 +--- a/arch/parisc/include/asm/uaccess.h ++++ b/arch/parisc/include/asm/uaccess.h +@@ -39,10 +39,10 @@ + #define get_user __get_user + + #if !defined(CONFIG_64BIT) +-#define LDD_USER(ptr) __get_user_asm64(ptr) ++#define LDD_USER(val, ptr) __get_user_asm64(val, ptr) + #define STD_USER(x, ptr) __put_user_asm64(x, ptr) + #else +-#define LDD_USER(ptr) __get_user_asm("ldd", ptr) ++#define LDD_USER(val, ptr) __get_user_asm(val, "ldd", ptr) + #define STD_USER(x, ptr) __put_user_asm("std", x, ptr) + #endif + +@@ -97,63 +97,87 @@ struct exception_data { + " mtsp %0,%%sr2\n\t" \ + : : "r"(get_fs()) : ) + +-#define __get_user(x, ptr) \ +-({ \ +- register long __gu_err __asm__ ("r8") = 0; \ +- register long __gu_val; \ +- \ +- load_sr2(); \ +- switch (sizeof(*(ptr))) { \ +- case 1: __get_user_asm("ldb", ptr); break; \ +- case 2: __get_user_asm("ldh", ptr); break; \ +- case 4: __get_user_asm("ldw", ptr); break; \ +- case 8: LDD_USER(ptr); break; \ +- default: BUILD_BUG(); break; \ +- } \ +- \ +- (x) = (__force __typeof__(*(ptr))) __gu_val; \ +- __gu_err; \ ++#define __get_user_internal(val, ptr) \ ++({ \ ++ register long __gu_err __asm__ ("r8") = 0; \ ++ \ ++ switch (sizeof(*(ptr))) { \ ++ case 1: __get_user_asm(val, "ldb", ptr); break; \ ++ case 2: __get_user_asm(val, "ldh", ptr); break; \ ++ case 4: __get_user_asm(val, "ldw", ptr); break; \ ++ case 8: LDD_USER(val, ptr); break; \ ++ default: BUILD_BUG(); \ ++ } \ ++ \ ++ __gu_err; \ + }) + +-#define __get_user_asm(ldx, ptr) \ ++#define __get_user(val, ptr) \ ++({ \ ++ load_sr2(); \ ++ __get_user_internal(val, ptr); \ ++}) ++ ++#define __get_user_asm(val, ldx, ptr) \ ++{ \ ++ register long __gu_val; \ ++ \ + __asm__("1: " ldx " 0(%%sr2,%2),%0\n" \ + "9:\n" \ + ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 9b) \ + : "=r"(__gu_val), "=r"(__gu_err) \ +- : "r"(ptr), "1"(__gu_err)); ++ : "r"(ptr), "1"(__gu_err)); \ ++ \ ++ (val) = (__force __typeof__(*(ptr))) __gu_val; \ ++} + + #if !defined(CONFIG_64BIT) + +-#define __get_user_asm64(ptr) \ ++#define __get_user_asm64(val, ptr) \ ++{ \ ++ union { \ ++ unsigned long long l; \ ++ __typeof__(*(ptr)) t; \ ++ } __gu_tmp; \ ++ \ + __asm__(" copy %%r0,%R0\n" \ + "1: ldw 0(%%sr2,%2),%0\n" \ + "2: ldw 4(%%sr2,%2),%R0\n" \ + "9:\n" \ + ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 9b) \ + ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 9b) \ +- : "=r"(__gu_val), "=r"(__gu_err) \ +- : "r"(ptr), "1"(__gu_err)); ++ : "=&r"(__gu_tmp.l), "=r"(__gu_err) \ ++ : "r"(ptr), "1"(__gu_err)); \ ++ \ ++ (val) = __gu_tmp.t; \ ++} + + #endif /* !defined(CONFIG_64BIT) */ + + +-#define __put_user(x, ptr) \ ++#define __put_user_internal(x, ptr) \ + ({ \ + register long __pu_err __asm__ ("r8") = 0; \ + __typeof__(*(ptr)) __x = (__typeof__(*(ptr)))(x); \ + \ +- load_sr2(); \ + switch (sizeof(*(ptr))) { \ +- case 1: __put_user_asm("stb", __x, ptr); break; \ +- case 2: __put_user_asm("sth", __x, ptr); break; \ +- case 4: __put_user_asm("stw", __x, ptr); break; \ +- case 8: STD_USER(__x, ptr); break; \ +- default: BUILD_BUG(); break; \ +- } \ ++ case 1: __put_user_asm("stb", __x, ptr); break; \ ++ case 2: __put_user_asm("sth", __x, ptr); break; \ ++ case 4: __put_user_asm("stw", __x, ptr); break; \ ++ case 8: STD_USER(__x, ptr); break; \ ++ default: BUILD_BUG(); \ ++ } \ + \ + __pu_err; \ + }) + ++#define __put_user(x, ptr) \ ++({ \ ++ load_sr2(); \ ++ __put_user_internal(x, ptr); \ ++}) ++ ++ + /* + * The "__put_user/kernel_asm()" macros tell gcc they read from memory + * instead of writing. This is because they do not write to any memory +-- +2.12.0 + diff --git a/queue/parisc-fix-bugs-in-pa_memcpy.patch b/queue/parisc-fix-bugs-in-pa_memcpy.patch new file mode 100644 index 0000000..f24a061 --- /dev/null +++ b/queue/parisc-fix-bugs-in-pa_memcpy.patch @@ -0,0 +1,147 @@ +From 409c1b250e30ad0e48b4d15d7319b4e18c046c4f Mon Sep 17 00:00:00 2001 +From: Mikulas Patocka <mpatocka@redhat.com> +Date: Fri, 14 Apr 2017 14:15:20 -0400 +Subject: [PATCH] parisc: fix bugs in pa_memcpy + +commit 409c1b250e30ad0e48b4d15d7319b4e18c046c4f upstream. + +The patch 554bfeceb8a22d448cd986fc9efce25e833278a1 ("parisc: Fix access +fault handling in pa_memcpy()") reimplements the pa_memcpy function. +Unfortunatelly, it makes the kernel unbootable. The crash happens in the +function ide_complete_cmd where memcpy is called with the same source +and destination address. + +This patch fixes a few bugs in pa_memcpy: + +* When jumping to .Lcopy_loop_16 for the first time, don't skip the + instruction "ldi 31,t0" (this bug made the kernel unbootable) +* Use the COND macro when comparing length, so that the comparison is + 64-bit (a theoretical issue, in case the length is greater than + 0xffffffff) +* Don't use the COND macro after the "extru" instruction (the PA-RISC + specification says that the upper 32-bits of extru result are undefined, + although they are set to zero in practice) +* Fix exception addresses in .Lcopy16_fault and .Lcopy8_fault +* Rename .Lcopy_loop_4 to .Lcopy_loop_8 (so that it is consistent with + .Lcopy8_fault) + +Cc: <stable@vger.kernel.org> # v4.9+ +Fixes: 554bfeceb8a2 ("parisc: Fix access fault handling in pa_memcpy()") +Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> +Signed-off-by: Helge Deller <deller@gmx.de> + +diff --git a/arch/parisc/lib/lusercopy.S b/arch/parisc/lib/lusercopy.S +index f01188c044ee..85c28bb80fb7 100644 +--- a/arch/parisc/lib/lusercopy.S ++++ b/arch/parisc/lib/lusercopy.S +@@ -201,7 +201,7 @@ ENTRY_CFI(pa_memcpy) + add dst,len,end + + /* short copy with less than 16 bytes? */ +- cmpib,>>=,n 15,len,.Lbyte_loop ++ cmpib,COND(>>=),n 15,len,.Lbyte_loop + + /* same alignment? */ + xor src,dst,t0 +@@ -216,7 +216,7 @@ ENTRY_CFI(pa_memcpy) + /* loop until we are 64-bit aligned */ + .Lalign_loop64: + extru dst,31,3,t1 +- cmpib,=,n 0,t1,.Lcopy_loop_16 ++ cmpib,=,n 0,t1,.Lcopy_loop_16_start + 20: ldb,ma 1(srcspc,src),t1 + 21: stb,ma t1,1(dstspc,dst) + b .Lalign_loop64 +@@ -225,6 +225,7 @@ ENTRY_CFI(pa_memcpy) + ASM_EXCEPTIONTABLE_ENTRY(20b,.Lcopy_done) + ASM_EXCEPTIONTABLE_ENTRY(21b,.Lcopy_done) + ++.Lcopy_loop_16_start: + ldi 31,t0 + .Lcopy_loop_16: + cmpb,COND(>>=),n t0,len,.Lword_loop +@@ -267,7 +268,7 @@ ENTRY_CFI(pa_memcpy) + /* loop until we are 32-bit aligned */ + .Lalign_loop32: + extru dst,31,2,t1 +- cmpib,=,n 0,t1,.Lcopy_loop_4 ++ cmpib,=,n 0,t1,.Lcopy_loop_8 + 20: ldb,ma 1(srcspc,src),t1 + 21: stb,ma t1,1(dstspc,dst) + b .Lalign_loop32 +@@ -277,7 +278,7 @@ ENTRY_CFI(pa_memcpy) + ASM_EXCEPTIONTABLE_ENTRY(21b,.Lcopy_done) + + +-.Lcopy_loop_4: ++.Lcopy_loop_8: + cmpib,COND(>>=),n 15,len,.Lbyte_loop + + 10: ldw 0(srcspc,src),t1 +@@ -299,7 +300,7 @@ ENTRY_CFI(pa_memcpy) + ASM_EXCEPTIONTABLE_ENTRY(16b,.Lcopy_done) + ASM_EXCEPTIONTABLE_ENTRY(17b,.Lcopy_done) + +- b .Lcopy_loop_4 ++ b .Lcopy_loop_8 + ldo -16(len),len + + .Lbyte_loop: +@@ -324,7 +325,7 @@ ENTRY_CFI(pa_memcpy) + .Lunaligned_copy: + /* align until dst is 32bit-word-aligned */ + extru dst,31,2,t1 +- cmpib,COND(=),n 0,t1,.Lcopy_dstaligned ++ cmpib,=,n 0,t1,.Lcopy_dstaligned + 20: ldb 0(srcspc,src),t1 + ldo 1(src),src + 21: stb,ma t1,1(dstspc,dst) +@@ -362,7 +363,7 @@ ENTRY_CFI(pa_memcpy) + cmpiclr,<> 1,t0,%r0 + b,n .Lcase1 + .Lcase0: +- cmpb,= %r0,len,.Lcda_finish ++ cmpb,COND(=) %r0,len,.Lcda_finish + nop + + 1: ldw,ma 4(srcspc,src), a3 +@@ -376,7 +377,7 @@ ENTRY_CFI(pa_memcpy) + 1: ldw,ma 4(srcspc,src), a3 + ASM_EXCEPTIONTABLE_ENTRY(1b,.Lcda_rdfault) + ldo -1(len),len +- cmpb,=,n %r0,len,.Ldo0 ++ cmpb,COND(=),n %r0,len,.Ldo0 + .Ldo4: + 1: ldw,ma 4(srcspc,src), a0 + ASM_EXCEPTIONTABLE_ENTRY(1b,.Lcda_rdfault) +@@ -402,7 +403,7 @@ ENTRY_CFI(pa_memcpy) + 1: stw,ma t0, 4(dstspc,dst) + ASM_EXCEPTIONTABLE_ENTRY(1b,.Lcopy_done) + ldo -4(len),len +- cmpb,<> %r0,len,.Ldo4 ++ cmpb,COND(<>) %r0,len,.Ldo4 + nop + .Ldo0: + shrpw a2, a3, %sar, t0 +@@ -436,14 +437,14 @@ ENTRY_CFI(pa_memcpy) + /* fault exception fixup handlers: */ + #ifdef CONFIG_64BIT + .Lcopy16_fault: +-10: b .Lcopy_done +- std,ma t1,8(dstspc,dst) ++ b .Lcopy_done ++10: std,ma t1,8(dstspc,dst) + ASM_EXCEPTIONTABLE_ENTRY(10b,.Lcopy_done) + #endif + + .Lcopy8_fault: +-10: b .Lcopy_done +- stw,ma t1,4(dstspc,dst) ++ b .Lcopy_done ++10: stw,ma t1,4(dstspc,dst) + ASM_EXCEPTIONTABLE_ENTRY(10b,.Lcopy_done) + + .exit +-- +2.12.0 + diff --git a/queue/perf-x86-Avoid-exposing-wrong-stale-data-in-intel_pm.patch b/queue/perf-x86-Avoid-exposing-wrong-stale-data-in-intel_pm.patch new file mode 100644 index 0000000..ba4a622 --- /dev/null +++ b/queue/perf-x86-Avoid-exposing-wrong-stale-data-in-intel_pm.patch @@ -0,0 +1,37 @@ +From f2200ac311302fcdca6556fd0c5127eab6c65a3e Mon Sep 17 00:00:00 2001 +From: Peter Zijlstra <peterz@infradead.org> +Date: Tue, 11 Apr 2017 10:10:28 +0200 +Subject: [PATCH] perf/x86: Avoid exposing wrong/stale data in + intel_pmu_lbr_read_32() + +commit f2200ac311302fcdca6556fd0c5127eab6c65a3e upstream. + +When the perf_branch_entry::{in_tx,abort,cycles} fields were added, +intel_pmu_lbr_read_32() wasn't updated to initialize them. + +Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> +Cc: Linus Torvalds <torvalds@linux-foundation.org> +Cc: Peter Zijlstra <peterz@infradead.org> +Cc: Thomas Gleixner <tglx@linutronix.de> +Cc: linux-kernel@vger.kernel.org +Cc: <stable@vger.kernel.org> +Fixes: 135c5612c460 ("perf/x86/intel: Support Haswell/v4 LBR format") +Signed-off-by: Ingo Molnar <mingo@kernel.org> + +diff --git a/arch/x86/events/intel/lbr.c b/arch/x86/events/intel/lbr.c +index 81b321ace8e0..f924629836a8 100644 +--- a/arch/x86/events/intel/lbr.c ++++ b/arch/x86/events/intel/lbr.c +@@ -507,6 +507,9 @@ static void intel_pmu_lbr_read_32(struct cpu_hw_events *cpuc) + cpuc->lbr_entries[i].to = msr_lastbranch.to; + cpuc->lbr_entries[i].mispred = 0; + cpuc->lbr_entries[i].predicted = 0; ++ cpuc->lbr_entries[i].in_tx = 0; ++ cpuc->lbr_entries[i].abort = 0; ++ cpuc->lbr_entries[i].cycles = 0; + cpuc->lbr_entries[i].reserved = 0; + } + cpuc->lbr_stack.nr = i; +-- +2.12.0 + diff --git a/queue/platform-x86-acer-wmi-Only-supports-AMW0_GUID1-on-ac.patch b/queue/platform-x86-acer-wmi-Only-supports-AMW0_GUID1-on-ac.patch new file mode 100644 index 0000000..6d7d602 --- /dev/null +++ b/queue/platform-x86-acer-wmi-Only-supports-AMW0_GUID1-on-ac.patch @@ -0,0 +1,120 @@ +From 5241b1938a4d33eee3d3b43f23067c8e5b96db45 Mon Sep 17 00:00:00 2001 +From: "Lee, Chun-Yi" <joeyli.kernel@gmail.com> +Date: Tue, 1 Nov 2016 12:30:58 +0800 +Subject: [PATCH] platform/x86: acer-wmi: Only supports AMW0_GUID1 on acer + family +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit 5241b1938a4d33eee3d3b43f23067c8e5b96db45 upstream. + +The AMW0_GUID1 wmi is not only found on Acer family but also other +machines like Lenovo, Fujitsu and Medion. In the past, acer-wmi handled +those non-Acer machines by quirks list. + +But actually acer-wmi driver was loaded on any machine that had +AMW0_GUID1. This behavior is strange because those machines should be +supported by appropriate wmi drivers. e.g. fujitsu-laptop, +ideapad-laptop. + +This patch adds the logic to check the machine that has AMW0_GUID1 +should be in Acer/Packard Bell/Gateway white list. But, it still keeps +the quirk list of those supported non-acer machines for backward +compatibility. + +Tested-by: Bjørn Mork <bjorn@mork.no> +Signed-off-by: Lee, Chun-Yi <jlee@suse.com> +Signed-off-by: Darren Hart <dvhart@linux.intel.com> + +diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c +index 79d64ea00bfb..a66192f692e3 100644 +--- a/drivers/platform/x86/acer-wmi.c ++++ b/drivers/platform/x86/acer-wmi.c +@@ -355,6 +355,32 @@ static const struct dmi_system_id acer_blacklist[] __initconst = { + {} + }; + ++static const struct dmi_system_id amw0_whitelist[] __initconst = { ++ { ++ .ident = "Acer", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Acer"), ++ }, ++ }, ++ { ++ .ident = "Gateway", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Gateway"), ++ }, ++ }, ++ { ++ .ident = "Packard Bell", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Packard Bell"), ++ }, ++ }, ++ {} ++}; ++ ++/* ++ * This quirk table is only for Acer/Gateway/Packard Bell family ++ * that those machines are supported by acer-wmi driver. ++ */ + static const struct dmi_system_id acer_quirks[] __initconst = { + { + .callback = dmi_matched, +@@ -464,6 +490,17 @@ static const struct dmi_system_id acer_quirks[] __initconst = { + }, + .driver_data = &quirk_acer_travelmate_2490, + }, ++ {} ++}; ++ ++/* ++ * This quirk list is for those non-acer machines that have AMW0_GUID1 ++ * but supported by acer-wmi in past days. Keeping this quirk list here ++ * is only for backward compatible. Please do not add new machine to ++ * here anymore. Those non-acer machines should be supported by ++ * appropriate wmi drivers. ++ */ ++static const struct dmi_system_id non_acer_quirks[] __initconst = { + { + .callback = dmi_matched, + .ident = "Fujitsu Siemens Amilo Li 1718", +@@ -598,6 +635,7 @@ static void __init find_quirks(void) + { + if (!force_series) { + dmi_check_system(acer_quirks); ++ dmi_check_system(non_acer_quirks); + } else if (force_series == 2490) { + quirks = &quirk_acer_travelmate_2490; + } +@@ -2108,6 +2146,24 @@ static int __init acer_wmi_init(void) + find_quirks(); + + /* ++ * The AMW0_GUID1 wmi is not only found on Acer family but also other ++ * machines like Lenovo, Fujitsu and Medion. In the past days, ++ * acer-wmi driver handled those non-Acer machines by quirks list. ++ * But actually acer-wmi driver was loaded on any machines that have ++ * AMW0_GUID1. This behavior is strange because those machines should ++ * be supported by appropriate wmi drivers. e.g. fujitsu-laptop, ++ * ideapad-laptop. So, here checks the machine that has AMW0_GUID1 ++ * should be in Acer/Gateway/Packard Bell white list, or it's already ++ * in the past quirk list. ++ */ ++ if (wmi_has_guid(AMW0_GUID1) && ++ !dmi_check_system(amw0_whitelist) && ++ quirks == &quirk_unknown) { ++ pr_err("Unsupported machine has AMW0_GUID1, unable to load\n"); ++ return -ENODEV; ++ } ++ ++ /* + * Detect which ACPI-WMI interface we're using. + */ + if (wmi_has_guid(AMW0_GUID1) && wmi_has_guid(WMID_GUID1)) +-- +2.12.0 + diff --git a/queue/platform-x86-acer-wmi-setup-accelerometer-when-machi.patch b/queue/platform-x86-acer-wmi-setup-accelerometer-when-machi.patch new file mode 100644 index 0000000..5176db6 --- /dev/null +++ b/queue/platform-x86-acer-wmi-setup-accelerometer-when-machi.patch @@ -0,0 +1,82 @@ +From 98d610c3739ac354319a6590b915f4624d9151e6 Mon Sep 17 00:00:00 2001 +From: "Lee, Chun-Yi" <joeyli.kernel@gmail.com> +Date: Thu, 3 Nov 2016 08:18:52 +0800 +Subject: [PATCH] platform/x86: acer-wmi: setup accelerometer when machine has + appropriate notify event +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit 98d610c3739ac354319a6590b915f4624d9151e6 upstream. + +The accelerometer event relies on the ACERWMID_EVENT_GUID notify. +So, this patch changes the codes to setup accelerometer input device +when detected ACERWMID_EVENT_GUID. It avoids that the accel input +device created on every Acer machines. + +In addition, patch adds a clearly parsing logic of accelerometer hid +to acer_wmi_get_handle_cb callback function. It is positive matching +the "SENR" name with "BST0001" device to avoid non-supported hardware. + +Reported-by: Bjørn Mork <bjorn@mork.no> +Cc: Darren Hart <dvhart@infradead.org> +Signed-off-by: Lee, Chun-Yi <jlee@suse.com> +[andy: slightly massage commit message] +Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> + +diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c +index a66192f692e3..c29b9b611ab2 100644 +--- a/drivers/platform/x86/acer-wmi.c ++++ b/drivers/platform/x86/acer-wmi.c +@@ -1846,11 +1846,24 @@ static int __init acer_wmi_enable_lm(void) + return status; + } + ++#define ACER_WMID_ACCEL_HID "BST0001" ++ + static acpi_status __init acer_wmi_get_handle_cb(acpi_handle ah, u32 level, + void *ctx, void **retval) + { ++ struct acpi_device *dev; ++ ++ if (!strcmp(ctx, "SENR")) { ++ if (acpi_bus_get_device(ah, &dev)) ++ return AE_OK; ++ if (!strcmp(ACER_WMID_ACCEL_HID, acpi_device_hid(dev))) ++ return AE_OK; ++ } else ++ return AE_OK; ++ + *(acpi_handle *)retval = ah; +- return AE_OK; ++ ++ return AE_CTRL_TERMINATE; + } + + static int __init acer_wmi_get_handle(const char *name, const char *prop, +@@ -1877,7 +1890,7 @@ static int __init acer_wmi_accel_setup(void) + { + int err; + +- err = acer_wmi_get_handle("SENR", "BST0001", &gsensor_handle); ++ err = acer_wmi_get_handle("SENR", ACER_WMID_ACCEL_HID, &gsensor_handle); + if (err) + return err; + +@@ -2233,10 +2246,11 @@ static int __init acer_wmi_init(void) + err = acer_wmi_input_setup(); + if (err) + return err; ++ err = acer_wmi_accel_setup(); ++ if (err) ++ return err; + } + +- acer_wmi_accel_setup(); +- + err = platform_driver_register(&acer_platform_driver); + if (err) { + pr_err("Unable to register platform driver\n"); +-- +2.12.0 + diff --git a/queue/platform-x86-asus-wmi-Detect-quirk_no_rfkill-from-th.patch b/queue/platform-x86-asus-wmi-Detect-quirk_no_rfkill-from-th.patch new file mode 100644 index 0000000..75e2d13 --- /dev/null +++ b/queue/platform-x86-asus-wmi-Detect-quirk_no_rfkill-from-th.patch @@ -0,0 +1,103 @@ +From 71050ae7bf83e4d71a859257d11adc5de517073e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jo=C3=A3o=20Paulo=20Rechi=20Vita?= <jprvita@gmail.com> +Date: Mon, 20 Feb 2017 14:50:22 -0500 +Subject: [PATCH] platform/x86: asus-wmi: Detect quirk_no_rfkill from the DSDT +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit 71050ae7bf83e4d71a859257d11adc5de517073e upstream. + +Some Asus laptops that have an airplane-mode indicator LED, also have +the WMI WLAN user bit set, and the following bits in their DSDT: + + Scope (_SB) + { + (...) + Device (ATKD) + { + (...) + Method (WMNB, 3, Serialized) + { + (...) + If (LEqual (IIA0, 0x00010002)) + { + OWGD (IIA1) + Return (One) + } + } + } + } + +So when asus-wmi uses ASUS_WMI_DEVID_WLAN_LED (0x00010002) to store the +wlan state, it drives the airplane-mode indicator LED (through the call +to OWGD) in an inverted fashion: the LED is ON when airplane mode is OFF +(since wlan is ON), and vice-versa. + +This commit skips registering RFKill switches at all for these laptops, +to allow the asus-wireless driver to drive the airplane mode LED +correctly through the ASHS ACPI device. Relying on the presence of ASHS +and ASUS_WMI_DSTS_USER_BIT avoids adding DMI-based quirks for at least +21 different laptops. + +Signed-off-by: João Paulo Rechi Vita <jprvita@endlessm.com> +Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> + +diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c +index 43cb680adbb4..8499d3ae4257 100644 +--- a/drivers/platform/x86/asus-wmi.c ++++ b/drivers/platform/x86/asus-wmi.c +@@ -159,6 +159,8 @@ MODULE_LICENSE("GPL"); + #define USB_INTEL_XUSB2PR 0xD0 + #define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI 0x9c31 + ++static const char * const ashs_ids[] = { "ATK4001", "ATK4002", NULL }; ++ + struct bios_args { + u32 arg0; + u32 arg1; +@@ -2051,6 +2053,16 @@ static int asus_wmi_fan_init(struct asus_wmi *asus) + return 0; + } + ++static bool ashs_present(void) ++{ ++ int i = 0; ++ while (ashs_ids[i]) { ++ if (acpi_dev_found(ashs_ids[i++])) ++ return true; ++ } ++ return false; ++} ++ + /* + * WMI Driver + */ +@@ -2095,6 +2107,13 @@ static int asus_wmi_add(struct platform_device *pdev) + if (err) + goto fail_leds; + ++ asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_WLAN, &result); ++ if (result & (ASUS_WMI_DSTS_PRESENCE_BIT | ASUS_WMI_DSTS_USER_BIT)) ++ asus->driver->wlan_ctrl_by_user = 1; ++ ++ if (asus->driver->wlan_ctrl_by_user && ashs_present()) ++ asus->driver->quirks->no_rfkill = 1; ++ + if (!asus->driver->quirks->no_rfkill) { + err = asus_wmi_rfkill_init(asus); + if (err) +@@ -2134,10 +2153,6 @@ static int asus_wmi_add(struct platform_device *pdev) + if (err) + goto fail_debugfs; + +- asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_WLAN, &result); +- if (result & (ASUS_WMI_DSTS_PRESENCE_BIT | ASUS_WMI_DSTS_USER_BIT)) +- asus->driver->wlan_ctrl_by_user = 1; +- + return 0; + + fail_debugfs: +-- +2.12.0 + diff --git a/queue/platform-x86-asus-wmi-Set-specified-XUSB2PR-value-fo.patch b/queue/platform-x86-asus-wmi-Set-specified-XUSB2PR-value-fo.patch new file mode 100644 index 0000000..37ace7f --- /dev/null +++ b/queue/platform-x86-asus-wmi-Set-specified-XUSB2PR-value-fo.patch @@ -0,0 +1,175 @@ +From 8023eff10e7b0327898f17f0b553d2e45c71cef3 Mon Sep 17 00:00:00 2001 +From: Kai-Chuan Hsieh <kai.chiuan@gmail.com> +Date: Thu, 1 Sep 2016 23:55:55 +0800 +Subject: [PATCH] platform/x86: asus-wmi: Set specified XUSB2PR value for + X550LB + +commit 8023eff10e7b0327898f17f0b553d2e45c71cef3 upstream. + +The bluetooth adapter Atheros AR3012 can't be enumerated +and make the bluetooth function broken. + +T: Bus=02 Lev=01 Prnt=01 Port=05 Cnt=02 Dev#= 5 Spd=12 MxCh= 0 +D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 +P: Vendor=13d3 ProdID=3362 Rev=00.02 +S: Manufacturer=Atheros Communications +S: Product=Bluetooth USB Host Controller +S: SerialNumber=Alaska Day 2006 +C: #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=100mA +I: If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +I: If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb + +The error is: + + usb 2-6: device not accepting address 7, error -62 + usb usb2-port6: unable to enumerate USB device + +It is caused by adapter's connected port is mapped to xHC +controller, but the xHCI is not supported by the usb device. + +The output of 'sudo lspci -nnxxx -s 00:14.0': + + 00:14.0 USB controller [0c03]: Intel Corporation 8 Series USB xHCI HC [8086:9c31] (rev 04) + 00: 86 80 31 9c 06 04 90 02 04 30 03 0c 00 00 00 00 + 10: 04 00 a0 f7 00 00 00 00 00 00 00 00 00 00 00 00 + 20: 00 00 00 00 00 00 00 00 00 00 00 00 43 10 1f 20 + 30: 00 00 00 00 70 00 00 00 00 00 00 00 0b 01 00 00 + 40: fd 01 36 80 89 c6 0f 80 00 00 00 00 00 00 00 00 + 50: 5f 2e ce 0f 00 00 00 00 00 00 00 00 00 00 00 00 + 60: 30 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 70: 01 80 c2 c1 08 00 00 00 00 00 00 00 00 00 00 00 + 80: 05 00 87 00 0c a0 e0 fe 00 00 00 00 a1 41 00 00 + 90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + a0: 00 01 04 00 00 00 00 00 00 00 00 00 00 00 00 00 + b0: 0f 00 03 00 00 00 00 00 00 00 00 00 00 00 00 00 + c0: 03 c0 30 00 00 00 00 00 03 0c 00 00 00 00 00 00 + d0: f9 01 00 00 f9 01 00 00 0f 00 00 00 0f 00 00 00 + e0: 00 08 00 00 00 00 00 00 00 00 00 00 d8 d8 00 00 + f0: 00 00 00 00 00 00 00 00 b1 0f 04 08 00 00 00 00 + +By referencing Intel Platform Controller Hub(PCH) datasheet, +the xHC USB 2.0 Port Routing(XUSB2PR) at offset 0xD0-0xD3h +decides the setting of mapping the port to EHCI controller or +xHC controller. And the port mapped to xHC will enable xHCI +during bus resume. + +The setting of disabling bluetooth adapter's connected port is +0x000001D9. The value can be obtained by few times 1 bit flip +operation. The suited configuration should have the 'lsusb -t' +result with bluetooth using ehci: + +/: Bus 03.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/4p, 5000M +/: Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/9p, 480M + |__ Port 5: Dev 2, If 0, Class=Video, Driver=uvcvideo, 480M + |__ Port 5: Dev 2, If 1, Class=Video, Driver=uvcvideo, 480M +/: Bus 01.Port 1: Dev 1, Class=root_hub, Driver=ehci-pci/2p, 480M + |__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/8p, 480M + |__ Port 6: Dev 3, If 0, Class=Wireless, Driver=btusb, 12M + |__ Port 6: Dev 3, If 1, Class=Wireless, Driver=btusb, 12M + +Signed-off-by: Kai-Chuan Hsieh <kai.chiuan@gmail.com> +Acked-by: Corentin Chary <corentin.chary@gmail.com> +Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> +[andy: resolve merge conflict in asus-wmi.h] +Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> + +diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c +index 26e4cbc34db8..3ac4f48895dd 100644 +--- a/drivers/platform/x86/asus-nb-wmi.c ++++ b/drivers/platform/x86/asus-nb-wmi.c +@@ -116,6 +116,10 @@ static struct quirk_entry quirk_asus_ux303ub = { + .wmi_backlight_native = true, + }; + ++static struct quirk_entry quirk_asus_x550lb = { ++ .xusb2pr = 0x01D9, ++}; ++ + static int dmi_matched(const struct dmi_system_id *dmi) + { + quirks = dmi->driver_data; +@@ -398,6 +402,15 @@ static const struct dmi_system_id asus_quirks[] = { + }, + .driver_data = &quirk_asus_ux303ub, + }, ++ { ++ .callback = dmi_matched, ++ .ident = "ASUSTeK COMPUTER INC. X550LB", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "X550LB"), ++ }, ++ .driver_data = &quirk_asus_x550lb, ++ }, + {}, + }; + +diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c +index ce6ca31a2d09..43cb680adbb4 100644 +--- a/drivers/platform/x86/asus-wmi.c ++++ b/drivers/platform/x86/asus-wmi.c +@@ -156,6 +156,9 @@ MODULE_LICENSE("GPL"); + #define ASUS_FAN_CTRL_MANUAL 1 + #define ASUS_FAN_CTRL_AUTO 2 + ++#define USB_INTEL_XUSB2PR 0xD0 ++#define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI 0x9c31 ++ + struct bios_args { + u32 arg0; + u32 arg1; +@@ -1080,6 +1083,29 @@ exit: + return result; + } + ++static void asus_wmi_set_xusb2pr(struct asus_wmi *asus) ++{ ++ struct pci_dev *xhci_pdev; ++ u32 orig_ports_available; ++ u32 ports_available = asus->driver->quirks->xusb2pr; ++ ++ xhci_pdev = pci_get_device(PCI_VENDOR_ID_INTEL, ++ PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI, ++ NULL); ++ ++ if (!xhci_pdev) ++ return; ++ ++ pci_read_config_dword(xhci_pdev, USB_INTEL_XUSB2PR, ++ &orig_ports_available); ++ ++ pci_write_config_dword(xhci_pdev, USB_INTEL_XUSB2PR, ++ cpu_to_le32(ports_available)); ++ ++ pr_info("set USB_INTEL_XUSB2PR old: 0x%04x, new: 0x%04x\n", ++ orig_ports_available, ports_available); ++} ++ + /* + * Hwmon device + */ +@@ -2087,6 +2113,9 @@ static int asus_wmi_add(struct platform_device *pdev) + if (asus->driver->quirks->wmi_backlight_native) + acpi_video_set_dmi_backlight_type(acpi_backlight_native); + ++ if (asus->driver->quirks->xusb2pr) ++ asus_wmi_set_xusb2pr(asus); ++ + if (acpi_video_get_backlight_type() == acpi_backlight_vendor) { + err = asus_wmi_backlight_init(asus); + if (err && err != -ENODEV) +diff --git a/drivers/platform/x86/asus-wmi.h b/drivers/platform/x86/asus-wmi.h +index 0e19014e9f54..fdff626c3b51 100644 +--- a/drivers/platform/x86/asus-wmi.h ++++ b/drivers/platform/x86/asus-wmi.h +@@ -53,6 +53,7 @@ struct quirk_entry { + * and let the ACPI interrupt to send out the key event. + */ + int no_display_toggle; ++ u32 xusb2pr; + + bool (*i8042_filter)(unsigned char data, unsigned char str, + struct serio *serio); +-- +2.12.0 + diff --git a/queue/powerpc-64-Fix-flush_-d-i-cache_range-called-from-mo.patch b/queue/powerpc-64-Fix-flush_-d-i-cache_range-called-from-mo.patch new file mode 100644 index 0000000..41f5a54 --- /dev/null +++ b/queue/powerpc-64-Fix-flush_-d-i-cache_range-called-from-mo.patch @@ -0,0 +1,50 @@ +From 8f5f525d5b83f7d76a6baf9c4e94d4bf312ea7f6 Mon Sep 17 00:00:00 2001 +From: Oliver O'Halloran <oohall@gmail.com> +Date: Mon, 3 Apr 2017 13:25:12 +1000 +Subject: [PATCH] powerpc/64: Fix flush_(d|i)cache_range() called from modules + +commit 8f5f525d5b83f7d76a6baf9c4e94d4bf312ea7f6 upstream. + +When the kernel is compiled to use 64bit ABIv2 the _GLOBAL() macro does +not include a global entry point. A function's global entry point is +used when the function is called from a different TOC context and in the +kernel this typically means a call from a module into the vmlinux (or +vice-versa). + +There are a few exported asm functions declared with _GLOBAL() and +calling them from a module will likely crash the kernel since any TOC +relative load will yield garbage. + +flush_icache_range() and flush_dcache_range() are both exported to +modules, and use the TOC, so must use _GLOBAL_TOC(). + +Fixes: 721aeaa9fdf3 ("powerpc: Build little endian ppc64 kernel with ABIv2") +Cc: stable@vger.kernel.org # v3.16+ +Signed-off-by: Oliver O'Halloran <oohall@gmail.com> +Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> + +diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S +index ae179cb1bb3c..c119044cad0d 100644 +--- a/arch/powerpc/kernel/misc_64.S ++++ b/arch/powerpc/kernel/misc_64.S +@@ -67,7 +67,7 @@ PPC64_CACHES: + * flush all bytes from start through stop-1 inclusive + */ + +-_GLOBAL(flush_icache_range) ++_GLOBAL_TOC(flush_icache_range) + BEGIN_FTR_SECTION + PURGE_PREFETCHED_INS + blr +@@ -120,7 +120,7 @@ EXPORT_SYMBOL(flush_icache_range) + * + * flush all bytes from start to stop-1 inclusive + */ +-_GLOBAL(flush_dcache_range) ++_GLOBAL_TOC(flush_dcache_range) + + /* + * Flush the data cache to memory +-- +2.12.0 + diff --git a/queue/powerpc-Disable-HFSCR-TM-if-TM-is-not-supported.patch b/queue/powerpc-Disable-HFSCR-TM-if-TM-is-not-supported.patch new file mode 100644 index 0000000..52af66d --- /dev/null +++ b/queue/powerpc-Disable-HFSCR-TM-if-TM-is-not-supported.patch @@ -0,0 +1,56 @@ +From 7ed23e1bae8bf7e37fd555066550a00b95a3a98b Mon Sep 17 00:00:00 2001 +From: Benjamin Herrenschmidt <benh@kernel.crashing.org> +Date: Mon, 20 Mar 2017 17:49:03 +1100 +Subject: [PATCH] powerpc: Disable HFSCR[TM] if TM is not supported + +commit 7ed23e1bae8bf7e37fd555066550a00b95a3a98b upstream. + +On Power8 & Power9 the early CPU inititialisation in __init_HFSCR() +turns on HFSCR[TM] (Hypervisor Facility Status and Control Register +[Transactional Memory]), but that doesn't take into account that TM +might be disabled by CPU features, or disabled by the kernel being built +with CONFIG_PPC_TRANSACTIONAL_MEM=n. + +So later in boot, when we have setup the CPU features, clear HSCR[TM] if +the TM CPU feature has been disabled. We use CPU_FTR_TM_COMP to account +for the CONFIG_PPC_TRANSACTIONAL_MEM=n case. + +Without this a KVM guest might try use TM, even if told not to, and +cause an oops in the host kernel. Typically the oops is seen in +__kvmppc_vcore_entry() and may or may not be fatal to the host, but is +always bad news. + +In practice all shipping CPU revisions do support TM, and all host +kernels we are aware of build with TM support enabled, so no one should +actually be able to hit this in the wild. + +Fixes: 2a3563b023e5 ("powerpc: Setup in HFSCR for POWER8") +Cc: stable@vger.kernel.org # v3.10+ +Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> +Tested-by: Sam Bobroff <sam.bobroff@au1.ibm.com> +[mpe: Rewrite change log with input from Sam, add Fixes/stable] +Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> + +diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c +index 9cfaa8b69b5f..f997154dfc41 100644 +--- a/arch/powerpc/kernel/setup_64.c ++++ b/arch/powerpc/kernel/setup_64.c +@@ -236,6 +236,15 @@ static void cpu_ready_for_interrupts(void) + mtspr(SPRN_LPCR, lpcr | LPCR_AIL_3); + } + ++ /* ++ * Fixup HFSCR:TM based on CPU features. The bit is set by our ++ * early asm init because at that point we haven't updated our ++ * CPU features from firmware and device-tree. Here we have, ++ * so let's do it. ++ */ ++ if (cpu_has_feature(CPU_FTR_HVMODE) && !cpu_has_feature(CPU_FTR_TM_COMP)) ++ mtspr(SPRN_HFSCR, mfspr(SPRN_HFSCR) & ~HFSCR_TM); ++ + /* Set IR and DR in PACA MSR */ + get_paca()->kernel_msr = MSR_KERNEL; + } +-- +2.12.0 + diff --git a/queue/powerpc-Don-t-try-to-fix-up-misaligned-load-with-res.patch b/queue/powerpc-Don-t-try-to-fix-up-misaligned-load-with-res.patch new file mode 100644 index 0000000..7db4b69 --- /dev/null +++ b/queue/powerpc-Don-t-try-to-fix-up-misaligned-load-with-res.patch @@ -0,0 +1,71 @@ +From 48fe9e9488743eec9b7c1addd3c93f12f2123d54 Mon Sep 17 00:00:00 2001 +From: Paul Mackerras <paulus@ozlabs.org> +Date: Tue, 4 Apr 2017 14:56:05 +1000 +Subject: [PATCH] powerpc: Don't try to fix up misaligned load-with-reservation + instructions + +commit 48fe9e9488743eec9b7c1addd3c93f12f2123d54 upstream. + +In the past, there was only one load-with-reservation instruction, +lwarx, and if a program attempted a lwarx on a misaligned address, it +would take an alignment interrupt and the kernel handler would emulate +it as though it was lwzx, which was not really correct, but benign since +it is loading the right amount of data, and the lwarx should be paired +with a stwcx. to the same address, which would also cause an alignment +interrupt which would result in a SIGBUS being delivered to the process. + +We now have 5 different sizes of load-with-reservation instruction. Of +those, lharx and ldarx cause an immediate SIGBUS by luck since their +entries in aligninfo[] overlap instructions which were not fixed up, but +lqarx overlaps with lhz and will be emulated as such. lbarx can never +generate an alignment interrupt since it only operates on 1 byte. + +To straighten this out and fix the lqarx case, this adds code to detect +the l[hwdq]arx instructions and return without fixing them up, resulting +in a SIGBUS being delivered to the process. + +Cc: stable@vger.kernel.org +Signed-off-by: Paul Mackerras <paulus@ozlabs.org> +Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> + +diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c +index cbc7c42cdb74..ec7a8b099dd9 100644 +--- a/arch/powerpc/kernel/align.c ++++ b/arch/powerpc/kernel/align.c +@@ -807,14 +807,25 @@ int fix_alignment(struct pt_regs *regs) + nb = aligninfo[instr].len; + flags = aligninfo[instr].flags; + +- /* ldbrx/stdbrx overlap lfs/stfs in the DSISR unfortunately */ +- if (IS_XFORM(instruction) && ((instruction >> 1) & 0x3ff) == 532) { +- nb = 8; +- flags = LD+SW; +- } else if (IS_XFORM(instruction) && +- ((instruction >> 1) & 0x3ff) == 660) { +- nb = 8; +- flags = ST+SW; ++ /* ++ * Handle some cases which give overlaps in the DSISR values. ++ */ ++ if (IS_XFORM(instruction)) { ++ switch (get_xop(instruction)) { ++ case 532: /* ldbrx */ ++ nb = 8; ++ flags = LD+SW; ++ break; ++ case 660: /* stdbrx */ ++ nb = 8; ++ flags = ST+SW; ++ break; ++ case 20: /* lwarx */ ++ case 84: /* ldarx */ ++ case 116: /* lharx */ ++ case 276: /* lqarx */ ++ return 0; /* not emulated ever */ ++ } + } + + /* Byteswap little endian loads and stores */ +-- +2.12.0 + diff --git a/queue/powerpc-crypto-crc32c-vpmsum-Fix-missing-preempt_dis.patch b/queue/powerpc-crypto-crc32c-vpmsum-Fix-missing-preempt_dis.patch new file mode 100644 index 0000000..9e6963c --- /dev/null +++ b/queue/powerpc-crypto-crc32c-vpmsum-Fix-missing-preempt_dis.patch @@ -0,0 +1,72 @@ +From 4749228f022893faf54a3dbc70796f78b7d4f342 Mon Sep 17 00:00:00 2001 +From: Michael Ellerman <mpe@ellerman.id.au> +Date: Thu, 6 Apr 2017 23:34:38 +1000 +Subject: [PATCH] powerpc/crypto/crc32c-vpmsum: Fix missing preempt_disable() + +commit 4749228f022893faf54a3dbc70796f78b7d4f342 upstream. + +In crc32c_vpmsum() we call enable_kernel_altivec() without first +disabling preemption, which is not allowed: + + WARNING: CPU: 9 PID: 2949 at ../arch/powerpc/kernel/process.c:277 enable_kernel_altivec+0x100/0x120 + Modules linked in: dm_thin_pool dm_persistent_data dm_bio_prison dm_bufio libcrc32c vmx_crypto ... + CPU: 9 PID: 2949 Comm: docker Not tainted 4.11.0-rc5-compiler_gcc-6.3.1-00033-g308ac7563944 #381 + ... + NIP [c00000000001e320] enable_kernel_altivec+0x100/0x120 + LR [d000000003df0910] crc32c_vpmsum+0x108/0x150 [crc32c_vpmsum] + Call Trace: + 0xc138fd09 (unreliable) + crc32c_vpmsum+0x108/0x150 [crc32c_vpmsum] + crc32c_vpmsum_update+0x3c/0x60 [crc32c_vpmsum] + crypto_shash_update+0x88/0x1c0 + crc32c+0x64/0x90 [libcrc32c] + dm_bm_checksum+0x48/0x80 [dm_persistent_data] + sb_check+0x84/0x120 [dm_thin_pool] + dm_bm_validate_buffer.isra.0+0xc0/0x1b0 [dm_persistent_data] + dm_bm_read_lock+0x80/0xf0 [dm_persistent_data] + __create_persistent_data_objects+0x16c/0x810 [dm_thin_pool] + dm_pool_metadata_open+0xb0/0x1a0 [dm_thin_pool] + pool_ctr+0x4cc/0xb60 [dm_thin_pool] + dm_table_add_target+0x16c/0x3c0 + table_load+0x184/0x400 + ctl_ioctl+0x2f0/0x560 + dm_ctl_ioctl+0x38/0x50 + do_vfs_ioctl+0xd8/0x920 + SyS_ioctl+0x68/0xc0 + system_call+0x38/0xfc + +It used to be sufficient just to call pagefault_disable(), because that +also disabled preemption. But the two were decoupled in commit 8222dbe21e79 +("sched/preempt, mm/fault: Decouple preemption from the page fault +logic") in mid 2015. + +So add the missing preempt_disable/enable(). We should also call +disable_kernel_fp(), although it does nothing by default, there is a +debug switch to make it active and all enables should be paired with +disables. + +Fixes: 6dd7a82cc54e ("crypto: powerpc - Add POWER8 optimised crc32c") +Cc: stable@vger.kernel.org # v4.8+ +Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> + +diff --git a/arch/powerpc/crypto/crc32c-vpmsum_glue.c b/arch/powerpc/crypto/crc32c-vpmsum_glue.c +index 411994551afc..f058e0c3e4d4 100644 +--- a/arch/powerpc/crypto/crc32c-vpmsum_glue.c ++++ b/arch/powerpc/crypto/crc32c-vpmsum_glue.c +@@ -33,10 +33,13 @@ static u32 crc32c_vpmsum(u32 crc, unsigned char const *p, size_t len) + } + + if (len & ~VMX_ALIGN_MASK) { ++ preempt_disable(); + pagefault_disable(); + enable_kernel_altivec(); + crc = __crc32c_vpmsum(crc, p, len & ~VMX_ALIGN_MASK); ++ disable_kernel_altivec(); + pagefault_enable(); ++ preempt_enable(); + } + + tail = len & VMX_ALIGN_MASK; +-- +2.12.0 + diff --git a/queue/powerpc-mm-Add-missing-global-TLB-invalidate-if-cxl-.patch b/queue/powerpc-mm-Add-missing-global-TLB-invalidate-if-cxl-.patch new file mode 100644 index 0000000..dc11d01 --- /dev/null +++ b/queue/powerpc-mm-Add-missing-global-TLB-invalidate-if-cxl-.patch @@ -0,0 +1,52 @@ +From 88b1bf7268f56887ca88eb09c6fb0f4fc970121a Mon Sep 17 00:00:00 2001 +From: Frederic Barrat <fbarrat@linux.vnet.ibm.com> +Date: Wed, 29 Mar 2017 19:19:42 +0200 +Subject: [PATCH] powerpc/mm: Add missing global TLB invalidate if cxl is + active + +commit 88b1bf7268f56887ca88eb09c6fb0f4fc970121a upstream. + +Commit 4c6d9acce1f4 ("powerpc/mm: Add hooks for cxl") converted local +TLB invalidates to global if the cxl driver is active. This is necessary +because the CAPP snoops invalidations to forward them to the PSL on the +cxl adapter. However one path was forgotten. native_flush_hash_range() +still does local TLB invalidates, as found out the hard way recently. + +This patch fixes it by following the same logic as previously: if the +cxl driver is active, the local TLB invalidates are 'upgraded' to +global. + +Fixes: 4c6d9acce1f4 ("powerpc/mm: Add hooks for cxl") +Cc: stable@vger.kernel.org # v3.18+ +Signed-off-by: Frederic Barrat <fbarrat@linux.vnet.ibm.com> +Reviewed-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> +Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> + +diff --git a/arch/powerpc/mm/hash_native_64.c b/arch/powerpc/mm/hash_native_64.c +index cc332608e656..65bb8f33b399 100644 +--- a/arch/powerpc/mm/hash_native_64.c ++++ b/arch/powerpc/mm/hash_native_64.c +@@ -638,6 +638,10 @@ static void native_flush_hash_range(unsigned long number, int local) + unsigned long psize = batch->psize; + int ssize = batch->ssize; + int i; ++ unsigned int use_local; ++ ++ use_local = local && mmu_has_feature(MMU_FTR_TLBIEL) && ++ mmu_psize_defs[psize].tlbiel && !cxl_ctx_in_use(); + + local_irq_save(flags); + +@@ -667,8 +671,7 @@ static void native_flush_hash_range(unsigned long number, int local) + } pte_iterate_hashed_end(); + } + +- if (mmu_has_feature(MMU_FTR_TLBIEL) && +- mmu_psize_defs[psize].tlbiel && local) { ++ if (use_local) { + asm volatile("ptesync":::"memory"); + for (i = 0; i < number; i++) { + vpn = batch->vpn[i]; +-- +2.12.0 + diff --git a/queue/ppdev-check-before-attaching-port.patch b/queue/ppdev-check-before-attaching-port.patch new file mode 100644 index 0000000..7705034 --- /dev/null +++ b/queue/ppdev-check-before-attaching-port.patch @@ -0,0 +1,69 @@ +From dd5c472a60e43549d789a17a8444513eec64bd7e Mon Sep 17 00:00:00 2001 +From: Sudip Mukherjee <sudipm.mukherjee@gmail.com> +Date: Sat, 12 Nov 2016 21:22:12 +0000 +Subject: [PATCH] ppdev: check before attaching port + +commit dd5c472a60e43549d789a17a8444513eec64bd7e upstream. + +After parport starts using the device model, all pardevice drivers +should decide in their match_port callback function if they want to +attach with that particulatr port. ppdev has been converted to use the +new parport device-model code but pp_attach() tried to attach with all +the ports. +Create a new array of pointer and use that to remember the ports we +have attached. And use that information to skip attaching ports which +we have already attached. + +Tested-by: Joe Lawrence <joe.lawrence@redhat.com> +Signed-off-by: Sudip Mukherjee <sudip.mukherjee@codethink.co.uk> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> + +diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c +index 85c63e49df7f..02819e0703c8 100644 +--- a/drivers/char/ppdev.c ++++ b/drivers/char/ppdev.c +@@ -86,6 +86,9 @@ struct pp_struct { + long default_inactivity; + }; + ++/* should we use PARDEVICE_MAX here? */ ++static struct device *devices[PARPORT_MAX]; ++ + /* pp_struct.flags bitfields */ + #define PP_CLAIMED (1<<0) + #define PP_EXCL (1<<1) +@@ -789,13 +792,29 @@ static const struct file_operations pp_fops = { + + static void pp_attach(struct parport *port) + { +- device_create(ppdev_class, port->dev, MKDEV(PP_MAJOR, port->number), +- NULL, "parport%d", port->number); ++ struct device *ret; ++ ++ if (devices[port->number]) ++ return; ++ ++ ret = device_create(ppdev_class, port->dev, ++ MKDEV(PP_MAJOR, port->number), NULL, ++ "parport%d", port->number); ++ if (IS_ERR(ret)) { ++ pr_err("Failed to create device parport%d\n", ++ port->number); ++ return; ++ } ++ devices[port->number] = ret; + } + + static void pp_detach(struct parport *port) + { ++ if (!devices[port->number]) ++ return; ++ + device_destroy(ppdev_class, MKDEV(PP_MAJOR, port->number)); ++ devices[port->number] = NULL; + } + + static int pp_probe(struct pardevice *par_dev) +-- +2.12.0 + diff --git a/queue/ppdev-fix-registering-same-device-name.patch b/queue/ppdev-fix-registering-same-device-name.patch new file mode 100644 index 0000000..ccc108b --- /dev/null +++ b/queue/ppdev-fix-registering-same-device-name.patch @@ -0,0 +1,93 @@ +From 9a69645dde1188723d80745c1bc6ee9af2cbe2a7 Mon Sep 17 00:00:00 2001 +From: Sudip Mukherjee <sudipm.mukherjee@gmail.com> +Date: Mon, 6 Mar 2017 23:23:43 +0000 +Subject: [PATCH] ppdev: fix registering same device name + +commit 9a69645dde1188723d80745c1bc6ee9af2cbe2a7 upstream. + +Usually every parallel port will have a single pardev registered with +it. But ppdev driver is an exception. This userspace parallel port +driver allows to create multiple parrallel port devices for a single +parallel port. And as a result we were having a big warning like: +"sysfs: cannot create duplicate filename '/devices/parport0/ppdev0.0'". +And with that many parallel port printers stopped working. + +We have been using the minor number as the id field while registering +a parralel port device with a parralel port. But when there are +multiple parrallel port device for one single parallel port, they all +tried to register with the same name like 'pardev0.0' and everything +started failing. +Use an incremented index as the id instead of the minor number. + +Fixes: 8b7d3a9d903e ("ppdev: use new parport device model") +Cc: stable <stable@vger.kernel.org> # v4.9+ +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1414656 +Bugzilla: https://bugs.archlinux.org/task/52322 +Tested-by: James Feeney <james@nurealm.net> +Signed-off-by: Sudip Mukherjee <sudip.mukherjee@codethink.co.uk> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> + +diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c +index 2a558c706581..3e73bcdf9e65 100644 +--- a/drivers/char/ppdev.c ++++ b/drivers/char/ppdev.c +@@ -84,11 +84,14 @@ struct pp_struct { + struct ieee1284_info state; + struct ieee1284_info saved_state; + long default_inactivity; ++ int index; + }; + + /* should we use PARDEVICE_MAX here? */ + static struct device *devices[PARPORT_MAX]; + ++static DEFINE_IDA(ida_index); ++ + /* pp_struct.flags bitfields */ + #define PP_CLAIMED (1<<0) + #define PP_EXCL (1<<1) +@@ -290,7 +293,7 @@ static int register_device(int minor, struct pp_struct *pp) + struct pardevice *pdev = NULL; + char *name; + struct pardev_cb ppdev_cb; +- int rc = 0; ++ int rc = 0, index; + + name = kasprintf(GFP_KERNEL, CHRDEV "%x", minor); + if (name == NULL) +@@ -303,20 +306,23 @@ static int register_device(int minor, struct pp_struct *pp) + goto err; + } + ++ index = ida_simple_get(&ida_index, 0, 0, GFP_KERNEL); + memset(&ppdev_cb, 0, sizeof(ppdev_cb)); + ppdev_cb.irq_func = pp_irq; + ppdev_cb.flags = (pp->flags & PP_EXCL) ? PARPORT_FLAG_EXCL : 0; + ppdev_cb.private = pp; +- pdev = parport_register_dev_model(port, name, &ppdev_cb, minor); ++ pdev = parport_register_dev_model(port, name, &ppdev_cb, index); + parport_put_port(port); + + if (!pdev) { + pr_warn("%s: failed to register device!\n", name); + rc = -ENXIO; ++ ida_simple_remove(&ida_index, index); + goto err; + } + + pp->pdev = pdev; ++ pp->index = index; + dev_dbg(&pdev->dev, "registered pardevice\n"); + err: + kfree(name); +@@ -755,6 +761,7 @@ static int pp_release(struct inode *inode, struct file *file) + + if (pp->pdev) { + parport_unregister_device(pp->pdev); ++ ida_simple_remove(&ida_index, pp->index); + pp->pdev = NULL; + pr_debug(CHRDEV "%x: unregistered pardevice\n", minor); + } +-- +2.12.0 + diff --git a/queue/ptrace-fix-PTRACE_LISTEN-race-corrupting-task-state.patch b/queue/ptrace-fix-PTRACE_LISTEN-race-corrupting-task-state.patch new file mode 100644 index 0000000..70b258a --- /dev/null +++ b/queue/ptrace-fix-PTRACE_LISTEN-race-corrupting-task-state.patch @@ -0,0 +1,60 @@ +From 5402e97af667e35e54177af8f6575518bf251d51 Mon Sep 17 00:00:00 2001 +From: "bsegall@google.com" <bsegall@google.com> +Date: Fri, 7 Apr 2017 16:04:51 -0700 +Subject: [PATCH] ptrace: fix PTRACE_LISTEN race corrupting task->state + +commit 5402e97af667e35e54177af8f6575518bf251d51 upstream. + +In PT_SEIZED + LISTEN mode STOP/CONT signals cause a wakeup against +__TASK_TRACED. If this races with the ptrace_unfreeze_traced at the end +of a PTRACE_LISTEN, this can wake the task /after/ the check against +__TASK_TRACED, but before the reset of state to TASK_TRACED. This +causes it to instead clobber TASK_WAKING, allowing a subsequent wakeup +against TRACED while the task is still on the rq wake_list, corrupting +it. + +Oleg said: + "The kernel can crash or this can lead to other hard-to-debug problems. + In short, "task->state = TASK_TRACED" in ptrace_unfreeze_traced() + assumes that nobody else can wake it up, but PTRACE_LISTEN breaks the + contract. Obviusly it is very wrong to manipulate task->state if this + task is already running, or WAKING, or it sleeps again" + +[akpm@linux-foundation.org: coding-style fixes] +Fixes: 9899d11f ("ptrace: ensure arch_ptrace/ptrace_request can never race with SIGKILL") +Link: http://lkml.kernel.org/r/xm26y3vfhmkp.fsf_-_@bsegall-linux.mtv.corp.google.com +Signed-off-by: Ben Segall <bsegall@google.com> +Acked-by: Oleg Nesterov <oleg@redhat.com> +Cc: <stable@vger.kernel.org> +Signed-off-by: Andrew Morton <akpm@linux-foundation.org> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> + +diff --git a/kernel/ptrace.c b/kernel/ptrace.c +index 0af928712174..266ddcc1d8bb 100644 +--- a/kernel/ptrace.c ++++ b/kernel/ptrace.c +@@ -184,11 +184,17 @@ static void ptrace_unfreeze_traced(struct task_struct *task) + + WARN_ON(!task->ptrace || task->parent != current); + ++ /* ++ * PTRACE_LISTEN can allow ptrace_trap_notify to wake us up remotely. ++ * Recheck state under the lock to close this race. ++ */ + spin_lock_irq(&task->sighand->siglock); +- if (__fatal_signal_pending(task)) +- wake_up_state(task, __TASK_TRACED); +- else +- task->state = TASK_TRACED; ++ if (task->state == __TASK_TRACED) { ++ if (__fatal_signal_pending(task)) ++ wake_up_state(task, __TASK_TRACED); ++ else ++ task->state = TASK_TRACED; ++ } + spin_unlock_irq(&task->sighand->siglock); + } + +-- +2.12.0 + diff --git a/queue/pwm-rockchip-State-of-PWM-clock-should-synchronize-w.patch b/queue/pwm-rockchip-State-of-PWM-clock-should-synchronize-w.patch new file mode 100644 index 0000000..998389e --- /dev/null +++ b/queue/pwm-rockchip-State-of-PWM-clock-should-synchronize-w.patch @@ -0,0 +1,97 @@ +From a900152b5c29aea8134cc7a4c5db25552b3cd8f7 Mon Sep 17 00:00:00 2001 +From: David Wu <david.wu@rock-chips.com> +Date: Wed, 1 Mar 2017 19:10:55 +0800 +Subject: [PATCH] pwm: rockchip: State of PWM clock should synchronize with PWM + enabled state + +commit a900152b5c29aea8134cc7a4c5db25552b3cd8f7 upstream. + +If the PWM was not enabled at U-Boot loader, PWM could not work for +clock always disabled at PWM driver. The PWM clock is enabled at +beginning of pwm_apply(), but disabled at end of pwm_apply(). + +If the PWM was enabled at U-Boot loader, PWM clock is always enabled +unless closed by ATF. The pwm-backlight might turn off the power at +early suspend, should disable PWM clock for saving power consume. + +It is important to provide opportunity to enable/disable clock at PWM +driver, the PWM consumer should ensure correct order to call PWM enable +and disable, and PWM driver ensure state of PWM clock synchronized with +PWM enabled state. + +Fixes: 2bf1c98aa5a4 ("pwm: rockchip: Add support for atomic update") +Cc: stable@vger.kernel.org +Signed-off-by: David Wu <david.wu@rock-chips.com> +Reviewed-by: Boris Brezillon <boris.brezillon@free-electrons.com> +Signed-off-by: Thierry Reding <thierry.reding@gmail.com> + +diff --git a/drivers/pwm/pwm-rockchip.c b/drivers/pwm/pwm-rockchip.c +index ef89df1f7336..744d56197286 100644 +--- a/drivers/pwm/pwm-rockchip.c ++++ b/drivers/pwm/pwm-rockchip.c +@@ -191,6 +191,28 @@ static int rockchip_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, + return 0; + } + ++static int rockchip_pwm_enable(struct pwm_chip *chip, ++ struct pwm_device *pwm, ++ bool enable, ++ enum pwm_polarity polarity) ++{ ++ struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip); ++ int ret; ++ ++ if (enable) { ++ ret = clk_enable(pc->clk); ++ if (ret) ++ return ret; ++ } ++ ++ pc->data->set_enable(chip, pwm, enable, polarity); ++ ++ if (!enable) ++ clk_disable(pc->clk); ++ ++ return 0; ++} ++ + static int rockchip_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, + struct pwm_state *state) + { +@@ -207,22 +229,26 @@ static int rockchip_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, + return ret; + + if (state->polarity != curstate.polarity && enabled) { +- pc->data->set_enable(chip, pwm, false, state->polarity); ++ ret = rockchip_pwm_enable(chip, pwm, false, state->polarity); ++ if (ret) ++ goto out; + enabled = false; + } + + ret = rockchip_pwm_config(chip, pwm, state->duty_cycle, state->period); + if (ret) { + if (enabled != curstate.enabled) +- pc->data->set_enable(chip, pwm, !enabled, +- state->polarity); +- ++ rockchip_pwm_enable(chip, pwm, !enabled, ++ state->polarity); + goto out; + } + +- if (state->enabled != enabled) +- pc->data->set_enable(chip, pwm, state->enabled, +- state->polarity); ++ if (state->enabled != enabled) { ++ ret = rockchip_pwm_enable(chip, pwm, state->enabled, ++ state->polarity); ++ if (ret) ++ goto out; ++ } + + /* + * Update the state with the real hardware, which can differ a bit +-- +2.12.0 + diff --git a/queue/random-use-chacha20-for-get_random_int-long.patch b/queue/random-use-chacha20-for-get_random_int-long.patch new file mode 100644 index 0000000..0fe8d76 --- /dev/null +++ b/queue/random-use-chacha20-for-get_random_int-long.patch @@ -0,0 +1,177 @@ +From f5b98461cb8167ba362ad9f74c41d126b7becea7 Mon Sep 17 00:00:00 2001 +From: "Jason A. Donenfeld" <Jason@zx2c4.com> +Date: Fri, 6 Jan 2017 19:32:01 +0100 +Subject: [PATCH] random: use chacha20 for get_random_int/long + +commit f5b98461cb8167ba362ad9f74c41d126b7becea7 upstream. + +Now that our crng uses chacha20, we can rely on its speedy +characteristics for replacing MD5, while simultaneously achieving a +higher security guarantee. Before the idea was to use these functions if +you wanted random integers that aren't stupidly insecure but aren't +necessarily secure either, a vague gray zone, that hopefully was "good +enough" for its users. With chacha20, we can strengthen this claim, +since either we're using an rdrand-like instruction, or we're using the +same crng as /dev/urandom. And it's faster than what was before. + +We could have chosen to replace this with a SipHash-derived function, +which might be slightly faster, but at the cost of having yet another +RNG construction in the kernel. By moving to chacha20, we have a single +RNG to analyze and verify, and we also already get good performance +improvements on all platforms. + +Implementation-wise, rather than use a generic buffer for both +get_random_int/long and memcpy based on the size needs, we use a +specific buffer for 32-bit reads and for 64-bit reads. This way, we're +guaranteed to always have aligned accesses on all platforms. While +slightly more verbose in C, the assembly this generates is a lot +simpler than otherwise. + +Finally, on 32-bit platforms where longs and ints are the same size, +we simply alias get_random_int to get_random_long. + +Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com> +Suggested-by: Theodore Ts'o <tytso@mit.edu> +Cc: Theodore Ts'o <tytso@mit.edu> +Cc: Hannes Frederic Sowa <hannes@stressinduktion.org> +Cc: Andy Lutomirski <luto@amacapital.net> +Signed-off-by: Theodore Ts'o <tytso@mit.edu> + +diff --git a/drivers/char/random.c b/drivers/char/random.c +index 9d147d456598..b800e5479b7d 100644 +--- a/drivers/char/random.c ++++ b/drivers/char/random.c +@@ -2016,63 +2016,65 @@ struct ctl_table random_table[] = { + }; + #endif /* CONFIG_SYSCTL */ + +-static u32 random_int_secret[MD5_MESSAGE_BYTES / 4] ____cacheline_aligned; +- +-int random_int_secret_init(void) +-{ +- get_random_bytes(random_int_secret, sizeof(random_int_secret)); +- return 0; +-} +- +-static DEFINE_PER_CPU(__u32 [MD5_DIGEST_WORDS], get_random_int_hash) +- __aligned(sizeof(unsigned long)); ++struct batched_entropy { ++ union { ++ unsigned long entropy_long[CHACHA20_BLOCK_SIZE / sizeof(unsigned long)]; ++ unsigned int entropy_int[CHACHA20_BLOCK_SIZE / sizeof(unsigned int)]; ++ }; ++ unsigned int position; ++}; + + /* +- * Get a random word for internal kernel use only. Similar to urandom but +- * with the goal of minimal entropy pool depletion. As a result, the random +- * value is not cryptographically secure but for several uses the cost of +- * depleting entropy is too high ++ * Get a random word for internal kernel use only. The quality of the random ++ * number is either as good as RDRAND or as good as /dev/urandom, with the ++ * goal of being quite fast and not depleting entropy. + */ +-unsigned int get_random_int(void) ++static DEFINE_PER_CPU(struct batched_entropy, batched_entropy_long); ++unsigned long get_random_long(void) + { +- __u32 *hash; +- unsigned int ret; ++ unsigned long ret; ++ struct batched_entropy *batch; + +- if (arch_get_random_int(&ret)) ++ if (arch_get_random_long(&ret)) + return ret; + +- hash = get_cpu_var(get_random_int_hash); +- +- hash[0] += current->pid + jiffies + random_get_entropy(); +- md5_transform(hash, random_int_secret); +- ret = hash[0]; +- put_cpu_var(get_random_int_hash); +- ++ batch = &get_cpu_var(batched_entropy_long); ++ if (batch->position % ARRAY_SIZE(batch->entropy_long) == 0) { ++ extract_crng((u8 *)batch->entropy_long); ++ batch->position = 0; ++ } ++ ret = batch->entropy_long[batch->position++]; ++ put_cpu_var(batched_entropy_long); + return ret; + } +-EXPORT_SYMBOL(get_random_int); ++EXPORT_SYMBOL(get_random_long); + +-/* +- * Same as get_random_int(), but returns unsigned long. +- */ +-unsigned long get_random_long(void) ++#if BITS_PER_LONG == 32 ++unsigned int get_random_int(void) + { +- __u32 *hash; +- unsigned long ret; ++ return get_random_long(); ++} ++#else ++static DEFINE_PER_CPU(struct batched_entropy, batched_entropy_int); ++unsigned int get_random_int(void) ++{ ++ unsigned int ret; ++ struct batched_entropy *batch; + +- if (arch_get_random_long(&ret)) ++ if (arch_get_random_int(&ret)) + return ret; + +- hash = get_cpu_var(get_random_int_hash); +- +- hash[0] += current->pid + jiffies + random_get_entropy(); +- md5_transform(hash, random_int_secret); +- ret = *(unsigned long *)hash; +- put_cpu_var(get_random_int_hash); +- ++ batch = &get_cpu_var(batched_entropy_int); ++ if (batch->position % ARRAY_SIZE(batch->entropy_int) == 0) { ++ extract_crng((u8 *)batch->entropy_int); ++ batch->position = 0; ++ } ++ ret = batch->entropy_int[batch->position++]; ++ put_cpu_var(batched_entropy_int); + return ret; + } +-EXPORT_SYMBOL(get_random_long); ++#endif ++EXPORT_SYMBOL(get_random_int); + + /** + * randomize_page - Generate a random, page aligned address +diff --git a/include/linux/random.h b/include/linux/random.h +index 7bd2403e4fef..16ab429735a7 100644 +--- a/include/linux/random.h ++++ b/include/linux/random.h +@@ -37,7 +37,6 @@ extern void get_random_bytes(void *buf, int nbytes); + extern int add_random_ready_callback(struct random_ready_callback *rdy); + extern void del_random_ready_callback(struct random_ready_callback *rdy); + extern void get_random_bytes_arch(void *buf, int nbytes); +-extern int random_int_secret_init(void); + + #ifndef MODULE + extern const struct file_operations random_fops, urandom_fops; +diff --git a/init/main.c b/init/main.c +index b0c9d6facef9..09beb7fc6e8c 100644 +--- a/init/main.c ++++ b/init/main.c +@@ -879,7 +879,6 @@ static void __init do_basic_setup(void) + do_ctors(); + usermodehelper_enable(); + do_initcalls(); +- random_int_secret_init(); + } + + static void __init do_pre_smp_initcalls(void) +-- +2.12.0 + diff --git a/queue/ring-buffer-Fix-return-value-check-in-test_ringbuffe.patch b/queue/ring-buffer-Fix-return-value-check-in-test_ringbuffe.patch new file mode 100644 index 0000000..89c2b35 --- /dev/null +++ b/queue/ring-buffer-Fix-return-value-check-in-test_ringbuffe.patch @@ -0,0 +1,49 @@ +From 62277de758b155dc04b78f195a1cb5208c37b2df Mon Sep 17 00:00:00 2001 +From: Wei Yongjun <yongjun_wei@trendmicro.com.cn> +Date: Fri, 17 Jun 2016 17:33:59 +0000 +Subject: [PATCH] ring-buffer: Fix return value check in test_ringbuffer() + +commit 62277de758b155dc04b78f195a1cb5208c37b2df upstream. + +In case of error, the function kthread_run() returns ERR_PTR() +and never returns NULL. The NULL test in the return value check +should be replaced with IS_ERR(). + +Link: http://lkml.kernel.org/r/1466184839-14927-1-git-send-email-weiyj_lk@163.com + +Cc: stable@vger.kernel.org +Fixes: 6c43e554a ("ring-buffer: Add ring buffer startup selftest") +Signed-off-by: Wei Yongjun <yongjun_wei@trendmicro.com.cn> +Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org> + +diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c +index 96fc3c043ad6..54e7a90db848 100644 +--- a/kernel/trace/ring_buffer.c ++++ b/kernel/trace/ring_buffer.c +@@ -4826,9 +4826,9 @@ static __init int test_ringbuffer(void) + rb_data[cpu].cnt = cpu; + rb_threads[cpu] = kthread_create(rb_test, &rb_data[cpu], + "rbtester/%d", cpu); +- if (WARN_ON(!rb_threads[cpu])) { ++ if (WARN_ON(IS_ERR(rb_threads[cpu]))) { + pr_cont("FAILED\n"); +- ret = -1; ++ ret = PTR_ERR(rb_threads[cpu]); + goto out_free; + } + +@@ -4838,9 +4838,9 @@ static __init int test_ringbuffer(void) + + /* Now create the rb hammer! */ + rb_hammer = kthread_run(rb_hammer_test, NULL, "rbhammer"); +- if (WARN_ON(!rb_hammer)) { ++ if (WARN_ON(IS_ERR(rb_hammer))) { + pr_cont("FAILED\n"); +- ret = -1; ++ ret = PTR_ERR(rb_hammer); + goto out_free; + } + +-- +2.12.0 + diff --git a/queue/rt2x00-Fix-incorrect-usage-of-CONFIG_RT2X00_LIB_USB.patch b/queue/rt2x00-Fix-incorrect-usage-of-CONFIG_RT2X00_LIB_USB.patch new file mode 100644 index 0000000..0eb3f02 --- /dev/null +++ b/queue/rt2x00-Fix-incorrect-usage-of-CONFIG_RT2X00_LIB_USB.patch @@ -0,0 +1,32 @@ +From a083c8fd277b4122c804f18ec8c84165f345c71c Mon Sep 17 00:00:00 2001 +From: Vishal Thanki <vishalthanki@gmail.com> +Date: Wed, 16 Nov 2016 17:01:54 +0100 +Subject: [PATCH] rt2x00: Fix incorrect usage of CONFIG_RT2X00_LIB_USB + +commit a083c8fd277b4122c804f18ec8c84165f345c71c upstream. + +In device removal routine, usage of "#ifdef CONFIG_RT2X00_LIB_USB" +will not cover the case when it is configured as module. This will +omit the entire if-block which does cleanup of URBs and cancellation +of pending work. Changing the #ifdef to #if IS_ENABLED() to fix it. + +Signed-off-by: Vishal Thanki <vishalthanki@gmail.com> +Acked-by: Stanislaw Gruszka <sgruszka@redhat.com> +Signed-off-by: Kalle Valo <kvalo@codeaurora.org> + +diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +index d65925061360..5071cf038466 100644 +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +@@ -1439,7 +1439,7 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev) + cancel_work_sync(&rt2x00dev->intf_work); + cancel_delayed_work_sync(&rt2x00dev->autowakeup_work); + cancel_work_sync(&rt2x00dev->sleep_work); +-#ifdef CONFIG_RT2X00_LIB_USB ++#if IS_ENABLED(CONFIG_RT2X00_LIB_USB) + if (rt2x00_is_usb(rt2x00dev)) { + usb_kill_anchored_urbs(rt2x00dev->anchor); + hrtimer_cancel(&rt2x00dev->txstatus_timer); +-- +2.12.0 + diff --git a/queue/rt2x00usb-do-not-anchor-rx-and-tx-urb-s.patch b/queue/rt2x00usb-do-not-anchor-rx-and-tx-urb-s.patch new file mode 100644 index 0000000..aab7cdf --- /dev/null +++ b/queue/rt2x00usb-do-not-anchor-rx-and-tx-urb-s.patch @@ -0,0 +1,60 @@ +From 93c7018ec16bb83399dd4db61c361a6d6aba0d5a Mon Sep 17 00:00:00 2001 +From: Stanislaw Gruszka <sgruszka@redhat.com> +Date: Wed, 8 Feb 2017 12:18:09 +0100 +Subject: [PATCH] rt2x00usb: do not anchor rx and tx urb's + +commit 93c7018ec16bb83399dd4db61c361a6d6aba0d5a upstream. + +We might kill TX or RX urb during rt2x00usb_flush_entry(), what can +cause anchor list corruption like shown below: + +[ 2074.035633] WARNING: CPU: 2 PID: 14480 at lib/list_debug.c:33 __list_add+0xac/0xc0 +[ 2074.035634] list_add corruption. prev->next should be next (ffff88020f362c28), but was dead000000000100. (prev=ffff8801d161bb70). +<snip> +[ 2074.035670] Call Trace: +[ 2074.035672] [<ffffffff813bde47>] dump_stack+0x63/0x8c +[ 2074.035674] [<ffffffff810a2231>] __warn+0xd1/0xf0 +[ 2074.035676] [<ffffffff810a22af>] warn_slowpath_fmt+0x5f/0x80 +[ 2074.035678] [<ffffffffa073855d>] ? rt2x00usb_register_write_lock+0x3d/0x60 [rt2800usb] +[ 2074.035679] [<ffffffff813dbe4c>] __list_add+0xac/0xc0 +[ 2074.035681] [<ffffffff81591c6c>] usb_anchor_urb+0x4c/0xa0 +[ 2074.035683] [<ffffffffa07322af>] rt2x00usb_kick_rx_entry+0xaf/0x100 [rt2x00usb] +[ 2074.035684] [<ffffffffa0732322>] rt2x00usb_clear_entry+0x22/0x30 [rt2x00usb] + +To fix do not anchor TX and RX urb's, it is not needed as during +shutdown we kill those urbs in rt2x00usb_free_entries(). + +Cc: Vishal Thanki <vishalthanki@gmail.com> +Fixes: 8b4c0009313f ("rt2x00usb: Use usb anchor to manage URB") +Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com> +Signed-off-by: Kalle Valo <kvalo@codeaurora.org> + +diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c b/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c +index 5a2bf9f63cd7..fe13dd07cc2a 100644 +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c +@@ -319,10 +319,8 @@ static bool rt2x00usb_kick_tx_entry(struct queue_entry *entry, void *data) + entry->skb->data, length, + rt2x00usb_interrupt_txdone, entry); + +- usb_anchor_urb(entry_priv->urb, rt2x00dev->anchor); + status = usb_submit_urb(entry_priv->urb, GFP_ATOMIC); + if (status) { +- usb_unanchor_urb(entry_priv->urb); + if (status == -ENODEV) + clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags); + set_bit(ENTRY_DATA_IO_FAILED, &entry->flags); +@@ -410,10 +408,8 @@ static bool rt2x00usb_kick_rx_entry(struct queue_entry *entry, void *data) + entry->skb->data, entry->skb->len, + rt2x00usb_interrupt_rxdone, entry); + +- usb_anchor_urb(entry_priv->urb, rt2x00dev->anchor); + status = usb_submit_urb(entry_priv->urb, GFP_ATOMIC); + if (status) { +- usb_unanchor_urb(entry_priv->urb); + if (status == -ENODEV) + clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags); + set_bit(ENTRY_DATA_IO_FAILED, &entry->flags); +-- +2.12.0 + diff --git a/queue/rt2x00usb-fix-anchor-initialization.patch b/queue/rt2x00usb-fix-anchor-initialization.patch new file mode 100644 index 0000000..680296f --- /dev/null +++ b/queue/rt2x00usb-fix-anchor-initialization.patch @@ -0,0 +1,74 @@ +From 0488a6121dfe6cbd44de15ea3627913b7549a1e9 Mon Sep 17 00:00:00 2001 +From: Stanislaw Gruszka <sgruszka@redhat.com> +Date: Wed, 8 Feb 2017 12:18:10 +0100 +Subject: [PATCH] rt2x00usb: fix anchor initialization + +commit 0488a6121dfe6cbd44de15ea3627913b7549a1e9 upstream. + +If device fail to initialize we can OOPS in rt2x00lib_remove_dev(), due +to using uninitialized usb_anchor structure: + +[ 855.435820] ieee80211 phy3: rt2x00usb_vendor_request: Error - Vendor Request 0x07 failed for offset 0x1000 with error -19 +[ 855.435826] ieee80211 phy3: rt2800_probe_rt: Error - Invalid RT chipset 0x0000, rev 0000 detected +[ 855.435829] ieee80211 phy3: rt2x00lib_probe_dev: Error - Failed to allocate device +[ 855.435845] BUG: unable to handle kernel NULL pointer dereference at 0000000000000028 +[ 855.435900] IP: _raw_spin_lock_irq+0xd/0x30 +[ 855.435926] PGD 0 +[ 855.435953] Oops: 0002 [#1] SMP +<snip> +[ 855.437011] Call Trace: +[ 855.437029] ? usb_kill_anchored_urbs+0x27/0xc0 +[ 855.437061] rt2x00lib_remove_dev+0x190/0x1c0 [rt2x00lib] +[ 855.437097] rt2x00lib_probe_dev+0x246/0x7a0 [rt2x00lib] +[ 855.437149] ? ieee80211_roc_setup+0x9e/0xd0 [mac80211] +[ 855.437183] ? __kmalloc+0x1af/0x1f0 +[ 855.437207] ? rt2x00usb_probe+0x13d/0xc50 [rt2x00usb] +[ 855.437240] rt2x00usb_probe+0x155/0xc50 [rt2x00usb] +[ 855.437273] rt2800usb_probe+0x15/0x20 [rt2800usb] +[ 855.437304] usb_probe_interface+0x159/0x2d0 +[ 855.437333] driver_probe_device+0x2bb/0x460 + +Patch changes initialization sequence to fix the problem. + +Cc: Vishal Thanki <vishalthanki@gmail.com> +Fixes: 8b4c0009313f ("rt2x00usb: Use usb anchor to manage URB") +Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com> +Signed-off-by: Kalle Valo <kvalo@codeaurora.org> + +diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c b/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c +index fe13dd07cc2a..c696f0ad6a68 100644 +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c +@@ -825,10 +825,6 @@ int rt2x00usb_probe(struct usb_interface *usb_intf, + if (retval) + goto exit_free_device; + +- retval = rt2x00lib_probe_dev(rt2x00dev); +- if (retval) +- goto exit_free_reg; +- + rt2x00dev->anchor = devm_kmalloc(&usb_dev->dev, + sizeof(struct usb_anchor), + GFP_KERNEL); +@@ -836,10 +832,17 @@ int rt2x00usb_probe(struct usb_interface *usb_intf, + retval = -ENOMEM; + goto exit_free_reg; + } +- + init_usb_anchor(rt2x00dev->anchor); ++ ++ retval = rt2x00lib_probe_dev(rt2x00dev); ++ if (retval) ++ goto exit_free_anchor; ++ + return 0; + ++exit_free_anchor: ++ usb_kill_anchored_urbs(rt2x00dev->anchor); ++ + exit_free_reg: + rt2x00usb_free_reg(rt2x00dev); + +-- +2.12.0 + diff --git a/queue/rtc-tegra-Implement-clock-handling.patch b/queue/rtc-tegra-Implement-clock-handling.patch new file mode 100644 index 0000000..8756c97 --- /dev/null +++ b/queue/rtc-tegra-Implement-clock-handling.patch @@ -0,0 +1,122 @@ +From 5fa4086987506b2ab8c92f8f99f2295db9918856 Mon Sep 17 00:00:00 2001 +From: Thierry Reding <treding@nvidia.com> +Date: Thu, 12 Jan 2017 17:07:43 +0100 +Subject: [PATCH] rtc: tegra: Implement clock handling + +commit 5fa4086987506b2ab8c92f8f99f2295db9918856 upstream. + +Accessing the registers of the RTC block on Tegra requires the module +clock to be enabled. This only works because the RTC module clock will +be enabled by default during early boot. However, because the clock is +unused, the CCF will disable it at late_init time. This causes the RTC +to become unusable afterwards. This can easily be reproduced by trying +to use the RTC: + + $ hwclock --rtc /dev/rtc1 + +This will hang the system. I ran into this by following up on a report +by Martin Michlmayr that reboot wasn't working on Tegra210 systems. It +turns out that the rtc-tegra driver's ->shutdown() implementation will +hang the CPU, because of the disabled clock, before the system can be +rebooted. + +What confused me for a while is that the same driver is used on prior +Tegra generations where the hang can not be observed. However, as Peter +De Schrijver pointed out, this is because on 32-bit Tegra chips the RTC +clock is enabled by the tegra20_timer.c clocksource driver, which uses +the RTC to provide a persistent clock. This code is never enabled on +64-bit Tegra because the persistent clock infrastructure does not exist +on 64-bit ARM. + +The proper fix for this is to add proper clock handling to the RTC +driver in order to ensure that the clock is enabled when the driver +requires it. All device trees contain the clock already, therefore +no additional changes are required. + +Reported-by: Martin Michlmayr <tbm@cyrius.com> +Acked-By Peter De Schrijver <pdeschrijver@nvidia.com> +Signed-off-by: Thierry Reding <treding@nvidia.com> +Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com> + +diff --git a/drivers/rtc/rtc-tegra.c b/drivers/rtc/rtc-tegra.c +index 38e662ff1a70..d30d57b048d3 100644 +--- a/drivers/rtc/rtc-tegra.c ++++ b/drivers/rtc/rtc-tegra.c +@@ -18,6 +18,7 @@ + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + ++#include <linux/clk.h> + #include <linux/delay.h> + #include <linux/init.h> + #include <linux/io.h> +@@ -60,6 +61,7 @@ struct tegra_rtc_info { + struct platform_device *pdev; + struct rtc_device *rtc_dev; + void __iomem *rtc_base; /* NULL if not initialized. */ ++ struct clk *clk; + int tegra_rtc_irq; /* alarm and periodic irq */ + spinlock_t tegra_rtc_lock; + }; +@@ -327,6 +329,14 @@ static int __init tegra_rtc_probe(struct platform_device *pdev) + if (info->tegra_rtc_irq <= 0) + return -EBUSY; + ++ info->clk = devm_clk_get(&pdev->dev, NULL); ++ if (IS_ERR(info->clk)) ++ return PTR_ERR(info->clk); ++ ++ ret = clk_prepare_enable(info->clk); ++ if (ret < 0) ++ return ret; ++ + /* set context info. */ + info->pdev = pdev; + spin_lock_init(&info->tegra_rtc_lock); +@@ -347,7 +357,7 @@ static int __init tegra_rtc_probe(struct platform_device *pdev) + ret = PTR_ERR(info->rtc_dev); + dev_err(&pdev->dev, "Unable to register device (err=%d).\n", + ret); +- return ret; ++ goto disable_clk; + } + + ret = devm_request_irq(&pdev->dev, info->tegra_rtc_irq, +@@ -357,12 +367,25 @@ static int __init tegra_rtc_probe(struct platform_device *pdev) + dev_err(&pdev->dev, + "Unable to request interrupt for device (err=%d).\n", + ret); +- return ret; ++ goto disable_clk; + } + + dev_notice(&pdev->dev, "Tegra internal Real Time Clock\n"); + + return 0; ++ ++disable_clk: ++ clk_disable_unprepare(info->clk); ++ return ret; ++} ++ ++static int tegra_rtc_remove(struct platform_device *pdev) ++{ ++ struct tegra_rtc_info *info = platform_get_drvdata(pdev); ++ ++ clk_disable_unprepare(info->clk); ++ ++ return 0; + } + + #ifdef CONFIG_PM_SLEEP +@@ -414,6 +437,7 @@ static void tegra_rtc_shutdown(struct platform_device *pdev) + + MODULE_ALIAS("platform:tegra_rtc"); + static struct platform_driver tegra_rtc_driver = { ++ .remove = tegra_rtc_remove, + .shutdown = tegra_rtc_shutdown, + .driver = { + .name = "tegra_rtc", +-- +2.12.0 + diff --git a/queue/s390-decompressor-fix-initrd-corruption-caused-by-bs.patch b/queue/s390-decompressor-fix-initrd-corruption-caused-by-bs.patch new file mode 100644 index 0000000..73b3a8b --- /dev/null +++ b/queue/s390-decompressor-fix-initrd-corruption-caused-by-bs.patch @@ -0,0 +1,84 @@ +From d82c0d12c92705ef468683c9b7a8298dd61ed191 Mon Sep 17 00:00:00 2001 +From: Marcelo Henrique Cerri <marcelo.cerri@canonical.com> +Date: Mon, 13 Mar 2017 12:14:58 -0300 +Subject: [PATCH] s390/decompressor: fix initrd corruption caused by bss clear + +commit d82c0d12c92705ef468683c9b7a8298dd61ed191 upstream. + +Reorder the operations in decompress_kernel() to ensure initrd is moved +to a safe location before the bss section is zeroed. + +During decompression bss can overlap with the initrd and this can +corrupt the initrd contents depending on the size of the compressed +kernel (which affects where the initrd is placed by the bootloader) and +the size of the bss section of the decompressor. + +Also use the correct initrd size when checking for overlaps with +parmblock. + +Fixes: 06c0dd72aea3 ([S390] fix boot failures with compressed kernels) +Cc: stable@vger.kernel.org +Reviewed-by: Joy Latten <joy.latten@canonical.com> +Reviewed-by: Vineetha HariPai <vineetha.hari.pai@canonical.com> +Signed-off-by: Marcelo Henrique Cerri <marcelo.cerri@canonical.com> +Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> +Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com> + +diff --git a/arch/s390/boot/compressed/misc.c b/arch/s390/boot/compressed/misc.c +index fa95041fa9f6..33ca29333e18 100644 +--- a/arch/s390/boot/compressed/misc.c ++++ b/arch/s390/boot/compressed/misc.c +@@ -141,31 +141,34 @@ static void check_ipl_parmblock(void *start, unsigned long size) + + unsigned long decompress_kernel(void) + { +- unsigned long output_addr; +- unsigned char *output; ++ void *output, *kernel_end; + +- output_addr = ((unsigned long) &_end + HEAP_SIZE + 4095UL) & -4096UL; +- check_ipl_parmblock((void *) 0, output_addr + SZ__bss_start); +- memset(&_bss, 0, &_ebss - &_bss); +- free_mem_ptr = (unsigned long)&_end; +- free_mem_end_ptr = free_mem_ptr + HEAP_SIZE; +- output = (unsigned char *) output_addr; ++ output = (void *) ALIGN((unsigned long) &_end + HEAP_SIZE, PAGE_SIZE); ++ kernel_end = output + SZ__bss_start; ++ check_ipl_parmblock((void *) 0, (unsigned long) kernel_end); + + #ifdef CONFIG_BLK_DEV_INITRD + /* + * Move the initrd right behind the end of the decompressed +- * kernel image. ++ * kernel image. This also prevents initrd corruption caused by ++ * bss clearing since kernel_end will always be located behind the ++ * current bss section.. + */ +- if (INITRD_START && INITRD_SIZE && +- INITRD_START < (unsigned long) output + SZ__bss_start) { +- check_ipl_parmblock(output + SZ__bss_start, +- INITRD_START + INITRD_SIZE); +- memmove(output + SZ__bss_start, +- (void *) INITRD_START, INITRD_SIZE); +- INITRD_START = (unsigned long) output + SZ__bss_start; ++ if (INITRD_START && INITRD_SIZE && kernel_end > (void *) INITRD_START) { ++ check_ipl_parmblock(kernel_end, INITRD_SIZE); ++ memmove(kernel_end, (void *) INITRD_START, INITRD_SIZE); ++ INITRD_START = (unsigned long) kernel_end; + } + #endif + ++ /* ++ * Clear bss section. free_mem_ptr and free_mem_end_ptr need to be ++ * initialized afterwards since they reside in bss. ++ */ ++ memset(&_bss, 0, &_ebss - &_bss); ++ free_mem_ptr = (unsigned long) &_end; ++ free_mem_end_ptr = free_mem_ptr + HEAP_SIZE; ++ + puts("Uncompressing Linux... "); + __decompress(input_data, input_len, NULL, NULL, output, 0, NULL, error); + puts("Ok, booting the kernel.\n"); +-- +2.12.0 + diff --git a/queue/s390-uaccess-get_user-should-zero-on-failure-again.patch b/queue/s390-uaccess-get_user-should-zero-on-failure-again.patch new file mode 100644 index 0000000..466dd9e --- /dev/null +++ b/queue/s390-uaccess-get_user-should-zero-on-failure-again.patch @@ -0,0 +1,43 @@ +From d09c5373e8e4eaaa09233552cbf75dc4c4f21203 Mon Sep 17 00:00:00 2001 +From: Heiko Carstens <heiko.carstens@de.ibm.com> +Date: Mon, 27 Mar 2017 09:48:04 +0200 +Subject: [PATCH] s390/uaccess: get_user() should zero on failure (again) + +commit d09c5373e8e4eaaa09233552cbf75dc4c4f21203 upstream. + +Commit fd2d2b191fe7 ("s390: get_user() should zero on failure") +intended to fix s390's get_user() implementation which did not zero +the target operand if the read from user space faulted. Unfortunately +the patch has no effect: the corresponding inline assembly specifies +that the operand is only written to ("=") and the previous value is +discarded. + +Therefore the compiler is free to and actually does omit the zero +initialization. + +To fix this simply change the contraint modifier to "+", so the +compiler cannot omit the initialization anymore. + +Fixes: c9ca78415ac1 ("s390/uaccess: provide inline variants of get_user/put_user") +Fixes: fd2d2b191fe7 ("s390: get_user() should zero on failure") +Cc: stable@vger.kernel.org +Cc: Al Viro <viro@zeniv.linux.org.uk> +Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> +Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com> + +diff --git a/arch/s390/include/asm/uaccess.h b/arch/s390/include/asm/uaccess.h +index 136932ff4250..3ea1554d04b3 100644 +--- a/arch/s390/include/asm/uaccess.h ++++ b/arch/s390/include/asm/uaccess.h +@@ -147,7 +147,7 @@ unsigned long __must_check __copy_to_user(void __user *to, const void *from, + " jg 2b\n" \ + ".popsection\n" \ + EX_TABLE(0b,3b) EX_TABLE(1b,3b) \ +- : "=d" (__rc), "=Q" (*(to)) \ ++ : "=d" (__rc), "+Q" (*(to)) \ + : "d" (size), "Q" (*(from)), \ + "d" (__reg0), "K" (-EFAULT) \ + : "cc"); \ +-- +2.12.0 + diff --git a/queue/sata-ahci-da850-implement-a-workaround-for-the-softr.patch b/queue/sata-ahci-da850-implement-a-workaround-for-the-softr.patch new file mode 100644 index 0000000..75c45b9 --- /dev/null +++ b/queue/sata-ahci-da850-implement-a-workaround-for-the-softr.patch @@ -0,0 +1,70 @@ +From f4d435f3265661d04e5290a0a0450e3a38898128 Mon Sep 17 00:00:00 2001 +From: Bartosz Golaszewski <bgolaszewski@baylibre.com> +Date: Mon, 30 Jan 2017 11:02:05 +0100 +Subject: [PATCH] sata: ahci-da850: implement a workaround for the softreset + quirk + +commit f4d435f3265661d04e5290a0a0450e3a38898128 upstream. + +There's an issue with the da850 SATA controller: if port multiplier +support is compiled in, but we're connecting the drive directly to +the SATA port on the board, the drive can't be detected. + +To make SATA work on the da850-lcdk board: first try to softreset +with pmp - if the operation fails with -EBUSY, retry without pmp. + +Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com> +Acked-by: Tejun Heo <tj@kernel.org> +Signed-off-by: Sekhar Nori <nsekhar@ti.com> + +diff --git a/drivers/ata/ahci_da850.c b/drivers/ata/ahci_da850.c +index 72126a0415fb..84c7805c0247 100644 +--- a/drivers/ata/ahci_da850.c ++++ b/drivers/ata/ahci_da850.c +@@ -54,11 +54,42 @@ static void da850_sata_init(struct device *dev, void __iomem *pwrdn_reg, + writel(val, ahci_base + SATA_P0PHYCR_REG); + } + ++static int ahci_da850_softreset(struct ata_link *link, ++ unsigned int *class, unsigned long deadline) ++{ ++ int pmp, ret; ++ ++ pmp = sata_srst_pmp(link); ++ ++ /* ++ * There's an issue with the SATA controller on da850 SoCs: if we ++ * enable Port Multiplier support, but the drive is connected directly ++ * to the board, it can't be detected. As a workaround: if PMP is ++ * enabled, we first call ahci_do_softreset() and pass it the result of ++ * sata_srst_pmp(). If this call fails, we retry with pmp = 0. ++ */ ++ ret = ahci_do_softreset(link, class, pmp, deadline, ahci_check_ready); ++ if (pmp && ret == -EBUSY) ++ return ahci_do_softreset(link, class, 0, ++ deadline, ahci_check_ready); ++ ++ return ret; ++} ++ ++static struct ata_port_operations ahci_da850_port_ops = { ++ .inherits = &ahci_platform_ops, ++ .softreset = ahci_da850_softreset, ++ /* ++ * No need to override .pmp_softreset - it's only used for actual ++ * PMP-enabled ports. ++ */ ++}; ++ + static const struct ata_port_info ahci_da850_port_info = { + .flags = AHCI_FLAG_COMMON, + .pio_mask = ATA_PIO4, + .udma_mask = ATA_UDMA6, +- .port_ops = &ahci_platform_ops, ++ .port_ops = &ahci_da850_port_ops, + }; + + static struct scsi_host_template ahci_platform_sht = { +-- +2.12.0 + diff --git a/queue/scsi-qla2xxx-Add-fix-to-read-correct-register-value-.patch b/queue/scsi-qla2xxx-Add-fix-to-read-correct-register-value-.patch new file mode 100644 index 0000000..5a6c946 --- /dev/null +++ b/queue/scsi-qla2xxx-Add-fix-to-read-correct-register-value-.patch @@ -0,0 +1,39 @@ +From bf6061b17a8d47ef0d9344d3ef576a4ff0edf793 Mon Sep 17 00:00:00 2001 +From: Sawan Chandak <sawan.chandak@cavium.com> +Date: Fri, 31 Mar 2017 14:37:03 -0700 +Subject: [PATCH] scsi: qla2xxx: Add fix to read correct register value for + ISP82xx. + +commit bf6061b17a8d47ef0d9344d3ef576a4ff0edf793 upstream. + +Add fix to read correct register value for ISP82xx, during check for +register disconnect.ISP82xx has different base register. + +Fixes: a465537ad1a4 ("qla2xxx: Disable the adapter and skip error recovery in case of register disconnect") +Signed-off-by: Sawan Chandak <sawan.chandak@cavium.com> +Signed-off-by: Himanshu Madhani <himanshu.madhani@cavium.com> +Cc: <stable@vger.kernel.org> +Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> + +diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c +index 579363a6f44f..c9e45d2befe5 100644 +--- a/drivers/scsi/qla2xxx/qla_os.c ++++ b/drivers/scsi/qla2xxx/qla_os.c +@@ -1126,8 +1126,13 @@ static inline + uint32_t qla2x00_isp_reg_stat(struct qla_hw_data *ha) + { + struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; ++ struct device_reg_82xx __iomem *reg82 = &ha->iobase->isp82; + +- return ((RD_REG_DWORD(®->host_status)) == ISP_REG_DISCONNECT); ++ if (IS_P3P_TYPE(ha)) ++ return ((RD_REG_DWORD(®82->host_int)) == ISP_REG_DISCONNECT); ++ else ++ return ((RD_REG_DWORD(®->host_status)) == ++ ISP_REG_DISCONNECT); + } + + /************************************************************************** +-- +2.12.0 + diff --git a/queue/scsi-sd-Consider-max_xfer_blocks-if-opt_xfer_blocks-.patch b/queue/scsi-sd-Consider-max_xfer_blocks-if-opt_xfer_blocks-.patch new file mode 100644 index 0000000..7edd804 --- /dev/null +++ b/queue/scsi-sd-Consider-max_xfer_blocks-if-opt_xfer_blocks-.patch @@ -0,0 +1,36 @@ +From 6780414519f91c2a84da9baa963a940ac916f803 Mon Sep 17 00:00:00 2001 +From: Fam Zheng <famz@redhat.com> +Date: Tue, 28 Mar 2017 12:41:26 +0800 +Subject: [PATCH] scsi: sd: Consider max_xfer_blocks if opt_xfer_blocks is + unusable + +commit 6780414519f91c2a84da9baa963a940ac916f803 upstream. + +If device reports a small max_xfer_blocks and a zero opt_xfer_blocks, we +end up using BLK_DEF_MAX_SECTORS, which is wrong and r/w of that size +may get error. + +[mkp: tweaked to avoid setting rw_max twice and added typecast] + +Cc: <stable@vger.kernel.org> # v4.4+ +Fixes: ca369d51b3e ("block/sd: Fix device-imposed transfer length limits") +Signed-off-by: Fam Zheng <famz@redhat.com> +Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> + +diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c +index fb9b4d29af0b..906cd6bfa2a9 100644 +--- a/drivers/scsi/sd.c ++++ b/drivers/scsi/sd.c +@@ -2956,7 +2956,8 @@ static int sd_revalidate_disk(struct gendisk *disk) + q->limits.io_opt = logical_to_bytes(sdp, sdkp->opt_xfer_blocks); + rw_max = logical_to_sectors(sdp, sdkp->opt_xfer_blocks); + } else +- rw_max = BLK_DEF_MAX_SECTORS; ++ rw_max = min_not_zero(logical_to_sectors(sdp, dev_max), ++ (sector_t)BLK_DEF_MAX_SECTORS); + + /* Combine with controller limits */ + q->limits.max_sectors = min(rw_max, queue_max_hw_sectors(q)); +-- +2.12.0 + diff --git a/queue/scsi-sd-Fix-capacity-calculation-with-32-bit-sector_.patch b/queue/scsi-sd-Fix-capacity-calculation-with-32-bit-sector_.patch new file mode 100644 index 0000000..5518f01 --- /dev/null +++ b/queue/scsi-sd-Fix-capacity-calculation-with-32-bit-sector_.patch @@ -0,0 +1,69 @@ +From 7c856152cb92f8eee2df29ef325a1b1f43161aff Mon Sep 17 00:00:00 2001 +From: "Martin K. Petersen" <martin.petersen@oracle.com> +Date: Tue, 4 Apr 2017 10:42:30 -0400 +Subject: [PATCH] scsi: sd: Fix capacity calculation with 32-bit sector_t + +commit 7c856152cb92f8eee2df29ef325a1b1f43161aff upstream. + +We previously made sure that the reported disk capacity was less than +0xffffffff blocks when the kernel was not compiled with large sector_t +support (CONFIG_LBDAF). However, this check assumed that the capacity +was reported in units of 512 bytes. + +Add a sanity check function to ensure that we only enable disks if the +entire reported capacity can be expressed in terms of sector_t. + +Cc: <stable@vger.kernel.org> +Reported-by: Steve Magnani <steve.magnani@digidescorp.com> +Cc: Bart Van Assche <Bart.VanAssche@sandisk.com> +Reviewed-by: Bart Van Assche <Bart.VanAssche@sandisk.com> +Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> + +diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c +index 906cd6bfa2a9..fe0f7997074e 100644 +--- a/drivers/scsi/sd.c ++++ b/drivers/scsi/sd.c +@@ -2102,6 +2102,22 @@ static void read_capacity_error(struct scsi_disk *sdkp, struct scsi_device *sdp, + + #define READ_CAPACITY_RETRIES_ON_RESET 10 + ++/* ++ * Ensure that we don't overflow sector_t when CONFIG_LBDAF is not set ++ * and the reported logical block size is bigger than 512 bytes. Note ++ * that last_sector is a u64 and therefore logical_to_sectors() is not ++ * applicable. ++ */ ++static bool sd_addressable_capacity(u64 lba, unsigned int sector_size) ++{ ++ u64 last_sector = (lba + 1ULL) << (ilog2(sector_size) - 9); ++ ++ if (sizeof(sector_t) == 4 && last_sector > U32_MAX) ++ return false; ++ ++ return true; ++} ++ + static int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp, + unsigned char *buffer) + { +@@ -2167,7 +2183,7 @@ static int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp, + return -ENODEV; + } + +- if ((sizeof(sdkp->capacity) == 4) && (lba >= 0xffffffffULL)) { ++ if (!sd_addressable_capacity(lba, sector_size)) { + sd_printk(KERN_ERR, sdkp, "Too big for this kernel. Use a " + "kernel compiled with support for large block " + "devices.\n"); +@@ -2256,7 +2272,7 @@ static int read_capacity_10(struct scsi_disk *sdkp, struct scsi_device *sdp, + return sector_size; + } + +- if ((sizeof(sdkp->capacity) == 4) && (lba == 0xffffffff)) { ++ if (!sd_addressable_capacity(lba, sector_size)) { + sd_printk(KERN_ERR, sdkp, "Too big for this kernel. Use a " + "kernel compiled with support for large block " + "devices.\n"); +-- +2.12.0 + diff --git a/queue/scsi-sr-Sanity-check-returned-mode-data.patch b/queue/scsi-sr-Sanity-check-returned-mode-data.patch new file mode 100644 index 0000000..b7f70be --- /dev/null +++ b/queue/scsi-sr-Sanity-check-returned-mode-data.patch @@ -0,0 +1,45 @@ +From a00a7862513089f17209b732f230922f1942e0b9 Mon Sep 17 00:00:00 2001 +From: "Martin K. Petersen" <martin.petersen@oracle.com> +Date: Fri, 17 Mar 2017 08:47:14 -0400 +Subject: [PATCH] scsi: sr: Sanity check returned mode data + +commit a00a7862513089f17209b732f230922f1942e0b9 upstream. + +Kefeng Wang discovered that old versions of the QEMU CD driver would +return mangled mode data causing us to walk off the end of the buffer in +an attempt to parse it. Sanity check the returned mode sense data. + +Cc: <stable@vger.kernel.org> +Reported-by: Kefeng Wang <wangkefeng.wang@huawei.com> +Tested-by: Kefeng Wang <wangkefeng.wang@huawei.com> +Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> + +diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c +index 0b29b9329b1c..a8f630213a1a 100644 +--- a/drivers/scsi/sr.c ++++ b/drivers/scsi/sr.c +@@ -836,6 +836,7 @@ static void get_capabilities(struct scsi_cd *cd) + unsigned char *buffer; + struct scsi_mode_data data; + struct scsi_sense_hdr sshdr; ++ unsigned int ms_len = 128; + int rc, n; + + static const char *loadmech[] = +@@ -862,10 +863,11 @@ static void get_capabilities(struct scsi_cd *cd) + scsi_test_unit_ready(cd->device, SR_TIMEOUT, MAX_RETRIES, &sshdr); + + /* ask for mode page 0x2a */ +- rc = scsi_mode_sense(cd->device, 0, 0x2a, buffer, 128, ++ rc = scsi_mode_sense(cd->device, 0, 0x2a, buffer, ms_len, + SR_TIMEOUT, 3, &data, NULL); + +- if (!scsi_status_is_good(rc)) { ++ if (!scsi_status_is_good(rc) || data.length > ms_len || ++ data.header_length + data.block_descriptor_length > data.length) { + /* failed, drive doesn't have capabilities mode page */ + cd->cdi.speed = 1; + cd->cdi.mask |= (CDC_CD_R | CDC_CD_RW | CDC_DVD_R | +-- +2.12.0 + diff --git a/queue/scsi-ufs-add-quirk-to-increase-host-PA_SaveConfigTim.patch b/queue/scsi-ufs-add-quirk-to-increase-host-PA_SaveConfigTim.patch new file mode 100644 index 0000000..106d520 --- /dev/null +++ b/queue/scsi-ufs-add-quirk-to-increase-host-PA_SaveConfigTim.patch @@ -0,0 +1,213 @@ +From 56d4a1866d748732fd8d690b2c2156bbc9c9eb02 Mon Sep 17 00:00:00 2001 +From: Subhash Jadavani <subhashj@codeaurora.org> +Date: Mon, 5 Dec 2016 19:25:32 -0800 +Subject: [PATCH] scsi: ufs: add quirk to increase host PA_SaveConfigTime + +commit 56d4a1866d748732fd8d690b2c2156bbc9c9eb02 upstream. + +The maximum value PA_SaveConfigTime is 250 (10us) but this is not enough +for some vendors. Gear switch from PWM to HS may fail even with this +max. PA_SaveConfigTime. Gear switch can be issued by host controller as +an error recovery and any software delay will not help on this case so +we need to increase PA_SaveConfigTime to >32us as per vendor +recommendation. This change adds a quirk to increase the +PA_SaveConfigTime parameter. + +Reviewed-by: Venkat Gopalakrishnan <venkatg@codeaurora.org> +Signed-off-by: Subhash Jadavani <subhashj@codeaurora.org> +Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> + +diff --git a/drivers/scsi/ufs/ufs-qcom.c b/drivers/scsi/ufs/ufs-qcom.c +index ff614613bf89..2943a68b6d69 100644 +--- a/drivers/scsi/ufs/ufs-qcom.c ++++ b/drivers/scsi/ufs/ufs-qcom.c +@@ -23,6 +23,7 @@ + #include "unipro.h" + #include "ufs-qcom.h" + #include "ufshci.h" ++#include "ufs_quirks.h" + #define UFS_QCOM_DEFAULT_DBG_PRINT_EN \ + (UFS_QCOM_DBG_PRINT_REGS_EN | UFS_QCOM_DBG_PRINT_TEST_BUS_EN) + +@@ -1031,6 +1032,34 @@ out: + return ret; + } + ++static int ufs_qcom_quirk_host_pa_saveconfigtime(struct ufs_hba *hba) ++{ ++ int err; ++ u32 pa_vs_config_reg1; ++ ++ err = ufshcd_dme_get(hba, UIC_ARG_MIB(PA_VS_CONFIG_REG1), ++ &pa_vs_config_reg1); ++ if (err) ++ goto out; ++ ++ /* Allow extension of MSB bits of PA_SaveConfigTime attribute */ ++ err = ufshcd_dme_set(hba, UIC_ARG_MIB(PA_VS_CONFIG_REG1), ++ (pa_vs_config_reg1 | (1 << 12))); ++ ++out: ++ return err; ++} ++ ++static int ufs_qcom_apply_dev_quirks(struct ufs_hba *hba) ++{ ++ int err = 0; ++ ++ if (hba->dev_quirks & UFS_DEVICE_QUIRK_HOST_PA_SAVECONFIGTIME) ++ err = ufs_qcom_quirk_host_pa_saveconfigtime(hba); ++ ++ return err; ++} ++ + static u32 ufs_qcom_get_ufs_hci_version(struct ufs_hba *hba) + { + struct ufs_qcom_host *host = ufshcd_get_variant(hba); +@@ -1618,6 +1647,7 @@ static struct ufs_hba_variant_ops ufs_hba_qcom_vops = { + .hce_enable_notify = ufs_qcom_hce_enable_notify, + .link_startup_notify = ufs_qcom_link_startup_notify, + .pwr_change_notify = ufs_qcom_pwr_change_notify, ++ .apply_dev_quirks = ufs_qcom_apply_dev_quirks, + .suspend = ufs_qcom_suspend, + .resume = ufs_qcom_resume, + .dbg_register_dump = ufs_qcom_dump_dbg_regs, +diff --git a/drivers/scsi/ufs/ufs-qcom.h b/drivers/scsi/ufs/ufs-qcom.h +index a19307a57ce2..fe517cd7dac3 100644 +--- a/drivers/scsi/ufs/ufs-qcom.h ++++ b/drivers/scsi/ufs/ufs-qcom.h +@@ -142,6 +142,7 @@ enum ufs_qcom_phy_init_type { + UFS_QCOM_DBG_PRINT_TEST_BUS_EN) + + /* QUniPro Vendor specific attributes */ ++#define PA_VS_CONFIG_REG1 0x9000 + #define DME_VS_CORE_CLK_CTRL 0xD002 + /* bit and mask definitions for DME_VS_CORE_CLK_CTRL attribute */ + #define DME_VS_CORE_CLK_CTRL_CORE_CLK_DIV_EN_BIT BIT(8) +diff --git a/drivers/scsi/ufs/ufs_quirks.h b/drivers/scsi/ufs/ufs_quirks.h +index f7983058f3f7..08b799d4efcc 100644 +--- a/drivers/scsi/ufs/ufs_quirks.h ++++ b/drivers/scsi/ufs/ufs_quirks.h +@@ -134,29 +134,17 @@ struct ufs_dev_fix { + */ + #define UFS_DEVICE_QUIRK_HOST_PA_TACTIVATE (1 << 7) + ++/* ++ * The max. value PA_SaveConfigTime is 250 (10us) but this is not enough for ++ * some vendors. ++ * Gear switch from PWM to HS may fail even with this max. PA_SaveConfigTime. ++ * Gear switch can be issued by host controller as an error recovery and any ++ * software delay will not help on this case so we need to increase ++ * PA_SaveConfigTime to >32us as per vendor recommendation. ++ */ ++#define UFS_DEVICE_QUIRK_HOST_PA_SAVECONFIGTIME (1 << 8) + + struct ufs_hba; + void ufs_advertise_fixup_device(struct ufs_hba *hba); + +-static struct ufs_dev_fix ufs_fixups[] = { +- /* UFS cards deviations table */ +- UFS_FIX(UFS_VENDOR_SAMSUNG, UFS_ANY_MODEL, +- UFS_DEVICE_QUIRK_DELAY_BEFORE_LPM), +- UFS_FIX(UFS_VENDOR_SAMSUNG, UFS_ANY_MODEL, UFS_DEVICE_NO_VCCQ), +- UFS_FIX(UFS_VENDOR_SAMSUNG, UFS_ANY_MODEL, +- UFS_DEVICE_QUIRK_RECOVERY_FROM_DL_NAC_ERRORS), +- UFS_FIX(UFS_VENDOR_SAMSUNG, UFS_ANY_MODEL, +- UFS_DEVICE_NO_FASTAUTO), +- UFS_FIX(UFS_VENDOR_SAMSUNG, UFS_ANY_MODEL, +- UFS_DEVICE_QUIRK_HOST_PA_TACTIVATE), +- UFS_FIX(UFS_VENDOR_TOSHIBA, UFS_ANY_MODEL, +- UFS_DEVICE_QUIRK_DELAY_BEFORE_LPM), +- UFS_FIX(UFS_VENDOR_TOSHIBA, "THGLF2G9C8KBADG", +- UFS_DEVICE_QUIRK_PA_TACTIVATE), +- UFS_FIX(UFS_VENDOR_TOSHIBA, "THGLF2G9D8KBADG", +- UFS_DEVICE_QUIRK_PA_TACTIVATE), +- UFS_FIX(UFS_VENDOR_SKHYNIX, UFS_ANY_MODEL, UFS_DEVICE_NO_VCCQ), +- +- END_FIX +-}; + #endif /* UFS_QUIRKS_H_ */ +diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c +index 7af70aa0b750..af7e0285f004 100644 +--- a/drivers/scsi/ufs/ufshcd.c ++++ b/drivers/scsi/ufs/ufshcd.c +@@ -185,6 +185,30 @@ ufs_get_pm_lvl_to_link_pwr_state(enum ufs_pm_level lvl) + return ufs_pm_lvl_states[lvl].link_state; + } + ++static struct ufs_dev_fix ufs_fixups[] = { ++ /* UFS cards deviations table */ ++ UFS_FIX(UFS_VENDOR_SAMSUNG, UFS_ANY_MODEL, ++ UFS_DEVICE_QUIRK_DELAY_BEFORE_LPM), ++ UFS_FIX(UFS_VENDOR_SAMSUNG, UFS_ANY_MODEL, UFS_DEVICE_NO_VCCQ), ++ UFS_FIX(UFS_VENDOR_SAMSUNG, UFS_ANY_MODEL, ++ UFS_DEVICE_QUIRK_RECOVERY_FROM_DL_NAC_ERRORS), ++ UFS_FIX(UFS_VENDOR_SAMSUNG, UFS_ANY_MODEL, ++ UFS_DEVICE_NO_FASTAUTO), ++ UFS_FIX(UFS_VENDOR_SAMSUNG, UFS_ANY_MODEL, ++ UFS_DEVICE_QUIRK_HOST_PA_TACTIVATE), ++ UFS_FIX(UFS_VENDOR_TOSHIBA, UFS_ANY_MODEL, ++ UFS_DEVICE_QUIRK_DELAY_BEFORE_LPM), ++ UFS_FIX(UFS_VENDOR_TOSHIBA, "THGLF2G9C8KBADG", ++ UFS_DEVICE_QUIRK_PA_TACTIVATE), ++ UFS_FIX(UFS_VENDOR_TOSHIBA, "THGLF2G9D8KBADG", ++ UFS_DEVICE_QUIRK_PA_TACTIVATE), ++ UFS_FIX(UFS_VENDOR_SKHYNIX, UFS_ANY_MODEL, UFS_DEVICE_NO_VCCQ), ++ UFS_FIX(UFS_VENDOR_SKHYNIX, UFS_ANY_MODEL, ++ UFS_DEVICE_QUIRK_HOST_PA_SAVECONFIGTIME), ++ ++ END_FIX ++}; ++ + static void ufshcd_tmc_handler(struct ufs_hba *hba); + static void ufshcd_async_scan(void *data, async_cookie_t cookie); + static int ufshcd_reset_and_restore(struct ufs_hba *hba); +@@ -5213,6 +5237,8 @@ static void ufshcd_tune_unipro_params(struct ufs_hba *hba) + + if (hba->dev_quirks & UFS_DEVICE_QUIRK_HOST_PA_TACTIVATE) + ufshcd_quirk_tune_host_pa_tactivate(hba); ++ ++ ufshcd_vops_apply_dev_quirks(hba); + } + + /** +diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h +index 7d9ff22acfea..08cd26ed2382 100644 +--- a/drivers/scsi/ufs/ufshcd.h ++++ b/drivers/scsi/ufs/ufshcd.h +@@ -266,7 +266,7 @@ struct ufs_pwr_mode_info { + * @setup_task_mgmt: called before any task management request is issued + * to set some things + * @hibern8_notify: called around hibern8 enter/exit +- * to configure some things ++ * @apply_dev_quirks: called to apply device specific quirks + * @suspend: called during host controller PM callback + * @resume: called during host controller PM callback + * @dbg_register_dump: used to dump controller debug information +@@ -293,7 +293,8 @@ struct ufs_hba_variant_ops { + void (*setup_xfer_req)(struct ufs_hba *, int, bool); + void (*setup_task_mgmt)(struct ufs_hba *, int, u8); + void (*hibern8_notify)(struct ufs_hba *, enum uic_cmd_dme, +- enum ufs_notify_change_status); ++ enum ufs_notify_change_status); ++ int (*apply_dev_quirks)(struct ufs_hba *); + int (*suspend)(struct ufs_hba *, enum ufs_pm_op); + int (*resume)(struct ufs_hba *, enum ufs_pm_op); + void (*dbg_register_dump)(struct ufs_hba *hba); +@@ -839,6 +840,13 @@ static inline void ufshcd_vops_hibern8_notify(struct ufs_hba *hba, + return hba->vops->hibern8_notify(hba, cmd, status); + } + ++static inline int ufshcd_vops_apply_dev_quirks(struct ufs_hba *hba) ++{ ++ if (hba->vops && hba->vops->apply_dev_quirks) ++ return hba->vops->apply_dev_quirks(hba); ++ return 0; ++} ++ + static inline int ufshcd_vops_suspend(struct ufs_hba *hba, enum ufs_pm_op op) + { + if (hba->vops && hba->vops->suspend) +-- +2.12.0 + diff --git a/queue/scsi-ufs-ensure-that-host-pa_tactivate-is-higher-tha.patch b/queue/scsi-ufs-ensure-that-host-pa_tactivate-is-higher-tha.patch new file mode 100644 index 0000000..76a4000 --- /dev/null +++ b/queue/scsi-ufs-ensure-that-host-pa_tactivate-is-higher-tha.patch @@ -0,0 +1,159 @@ +From c6a6db439868c7ba5cc90d4c461d9697ec731fa1 Mon Sep 17 00:00:00 2001 +From: "subhashj@codeaurora.org" <subhashj@codeaurora.org> +Date: Wed, 23 Nov 2016 16:32:08 -0800 +Subject: [PATCH] scsi: ufs: ensure that host pa_tactivate is higher than + device + +commit c6a6db439868c7ba5cc90d4c461d9697ec731fa1 upstream. + +Some UFS devices require host PA_TACTIVATE to be higher than +device PA_TACTIVATE otherwise it may get stuck during hibern8 sequence. +This change allows this by using quirk. + +Reviewed-by: Venkat Gopalakrishnan <venkatg@codeaurora.org> +Signed-off-by: Subhash Jadavani <subhashj@codeaurora.org> +Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> + +diff --git a/drivers/scsi/ufs/ufs_quirks.h b/drivers/scsi/ufs/ufs_quirks.h +index 22f881e9253a..f7983058f3f7 100644 +--- a/drivers/scsi/ufs/ufs_quirks.h ++++ b/drivers/scsi/ufs/ufs_quirks.h +@@ -128,6 +128,13 @@ struct ufs_dev_fix { + */ + #define UFS_DEVICE_QUIRK_DELAY_BEFORE_LPM (1 << 6) + ++/* ++ * Some UFS devices require host PA_TACTIVATE to be lower than device ++ * PA_TACTIVATE, enabling this quirk ensure this. ++ */ ++#define UFS_DEVICE_QUIRK_HOST_PA_TACTIVATE (1 << 7) ++ ++ + struct ufs_hba; + void ufs_advertise_fixup_device(struct ufs_hba *hba); + +@@ -140,6 +147,8 @@ static struct ufs_dev_fix ufs_fixups[] = { + UFS_DEVICE_QUIRK_RECOVERY_FROM_DL_NAC_ERRORS), + UFS_FIX(UFS_VENDOR_SAMSUNG, UFS_ANY_MODEL, + UFS_DEVICE_NO_FASTAUTO), ++ UFS_FIX(UFS_VENDOR_SAMSUNG, UFS_ANY_MODEL, ++ UFS_DEVICE_QUIRK_HOST_PA_TACTIVATE), + UFS_FIX(UFS_VENDOR_TOSHIBA, UFS_ANY_MODEL, + UFS_DEVICE_QUIRK_DELAY_BEFORE_LPM), + UFS_FIX(UFS_VENDOR_TOSHIBA, "THGLF2G9C8KBADG", +diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c +index 393f6d55df5a..28cbca21c4dd 100644 +--- a/drivers/scsi/ufs/ufshcd.c ++++ b/drivers/scsi/ufs/ufshcd.c +@@ -5089,6 +5089,76 @@ out: + return ret; + } + ++/** ++ * ufshcd_quirk_tune_host_pa_tactivate - Ensures that host PA_TACTIVATE is ++ * less than device PA_TACTIVATE time. ++ * @hba: per-adapter instance ++ * ++ * Some UFS devices require host PA_TACTIVATE to be lower than device ++ * PA_TACTIVATE, we need to enable UFS_DEVICE_QUIRK_HOST_PA_TACTIVATE quirk ++ * for such devices. ++ * ++ * Returns zero on success, non-zero error value on failure. ++ */ ++static int ufshcd_quirk_tune_host_pa_tactivate(struct ufs_hba *hba) ++{ ++ int ret = 0; ++ u32 granularity, peer_granularity; ++ u32 pa_tactivate, peer_pa_tactivate; ++ u32 pa_tactivate_us, peer_pa_tactivate_us; ++ u8 gran_to_us_table[] = {1, 4, 8, 16, 32, 100}; ++ ++ ret = ufshcd_dme_get(hba, UIC_ARG_MIB(PA_GRANULARITY), ++ &granularity); ++ if (ret) ++ goto out; ++ ++ ret = ufshcd_dme_peer_get(hba, UIC_ARG_MIB(PA_GRANULARITY), ++ &peer_granularity); ++ if (ret) ++ goto out; ++ ++ if ((granularity < PA_GRANULARITY_MIN_VAL) || ++ (granularity > PA_GRANULARITY_MAX_VAL)) { ++ dev_err(hba->dev, "%s: invalid host PA_GRANULARITY %d", ++ __func__, granularity); ++ return -EINVAL; ++ } ++ ++ if ((peer_granularity < PA_GRANULARITY_MIN_VAL) || ++ (peer_granularity > PA_GRANULARITY_MAX_VAL)) { ++ dev_err(hba->dev, "%s: invalid device PA_GRANULARITY %d", ++ __func__, peer_granularity); ++ return -EINVAL; ++ } ++ ++ ret = ufshcd_dme_get(hba, UIC_ARG_MIB(PA_TACTIVATE), &pa_tactivate); ++ if (ret) ++ goto out; ++ ++ ret = ufshcd_dme_peer_get(hba, UIC_ARG_MIB(PA_TACTIVATE), ++ &peer_pa_tactivate); ++ if (ret) ++ goto out; ++ ++ pa_tactivate_us = pa_tactivate * gran_to_us_table[granularity - 1]; ++ peer_pa_tactivate_us = peer_pa_tactivate * ++ gran_to_us_table[peer_granularity - 1]; ++ ++ if (pa_tactivate_us > peer_pa_tactivate_us) { ++ u32 new_peer_pa_tactivate; ++ ++ new_peer_pa_tactivate = pa_tactivate_us / ++ gran_to_us_table[peer_granularity - 1]; ++ new_peer_pa_tactivate++; ++ ret = ufshcd_dme_peer_set(hba, UIC_ARG_MIB(PA_TACTIVATE), ++ new_peer_pa_tactivate); ++ } ++ ++out: ++ return ret; ++} ++ + static void ufshcd_tune_unipro_params(struct ufs_hba *hba) + { + if (ufshcd_is_unipro_pa_params_tuning_req(hba)) { +@@ -5099,6 +5169,9 @@ static void ufshcd_tune_unipro_params(struct ufs_hba *hba) + if (hba->dev_quirks & UFS_DEVICE_QUIRK_PA_TACTIVATE) + /* set 1ms timeout for PA_TACTIVATE */ + ufshcd_dme_set(hba, UIC_ARG_MIB(PA_TACTIVATE), 10); ++ ++ if (hba->dev_quirks & UFS_DEVICE_QUIRK_HOST_PA_TACTIVATE) ++ ufshcd_quirk_tune_host_pa_tactivate(hba); + } + + /** +diff --git a/drivers/scsi/ufs/unipro.h b/drivers/scsi/ufs/unipro.h +index eff8b5675575..23129d7b2678 100644 +--- a/drivers/scsi/ufs/unipro.h ++++ b/drivers/scsi/ufs/unipro.h +@@ -123,6 +123,7 @@ + #define PA_MAXRXHSGEAR 0x1587 + #define PA_RXHSUNTERMCAP 0x15A5 + #define PA_RXLSTERMCAP 0x15A6 ++#define PA_GRANULARITY 0x15AA + #define PA_PACPREQTIMEOUT 0x1590 + #define PA_PACPREQEOBTIMEOUT 0x1591 + #define PA_HIBERN8TIME 0x15A7 +@@ -158,6 +159,9 @@ + #define VS_DEBUGOMC 0xD09E + #define VS_POWERSTATE 0xD083 + ++#define PA_GRANULARITY_MIN_VAL 1 ++#define PA_GRANULARITY_MAX_VAL 6 ++ + /* PHY Adapter Protocol Constants */ + #define PA_MAXDATALANES 4 + +-- +2.12.0 + diff --git a/queue/scsi-ufs-introduce-UFSHCD_QUIRK_PRDT_BYTE_GRAN-quirk.patch b/queue/scsi-ufs-introduce-UFSHCD_QUIRK_PRDT_BYTE_GRAN-quirk.patch new file mode 100644 index 0000000..1413f0c --- /dev/null +++ b/queue/scsi-ufs-introduce-UFSHCD_QUIRK_PRDT_BYTE_GRAN-quirk.patch @@ -0,0 +1,97 @@ +From 75b1cc4ad63afa28c1a045b5157c008f405f06a9 Mon Sep 17 00:00:00 2001 +From: Kiwoong Kim <kwmad.kim@samsung.com> +Date: Tue, 22 Nov 2016 17:06:59 +0900 +Subject: [PATCH] scsi: ufs: introduce UFSHCD_QUIRK_PRDT_BYTE_GRAN quirk + +commit 75b1cc4ad63afa28c1a045b5157c008f405f06a9 upstream. + +Some UFS host controllers may think granularities of PRDT length and +offset as bytes, not double words. + +Signed-off-by: Kiwoong Kim <kwmad.kim@samsung.com> +Reviewed-by: Subhash Jadavani <subhashj@codeaurora.org> +Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> + +diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c +index 421488161cf3..f91e50bf1a43 100644 +--- a/drivers/scsi/ufs/ufshcd.c ++++ b/drivers/scsi/ufs/ufshcd.c +@@ -1129,7 +1129,7 @@ ufshcd_send_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd) + * + * Returns 0 in case of success, non-zero value in case of failure + */ +-static int ufshcd_map_sg(struct ufshcd_lrb *lrbp) ++static int ufshcd_map_sg(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) + { + struct ufshcd_sg_entry *prd_table; + struct scatterlist *sg; +@@ -1143,8 +1143,13 @@ static int ufshcd_map_sg(struct ufshcd_lrb *lrbp) + return sg_segments; + + if (sg_segments) { +- lrbp->utr_descriptor_ptr->prd_table_length = +- cpu_to_le16((u16) (sg_segments)); ++ if (hba->quirks & UFSHCD_QUIRK_PRDT_BYTE_GRAN) ++ lrbp->utr_descriptor_ptr->prd_table_length = ++ cpu_to_le16((u16)(sg_segments * ++ sizeof(struct ufshcd_sg_entry))); ++ else ++ lrbp->utr_descriptor_ptr->prd_table_length = ++ cpu_to_le16((u16) (sg_segments)); + + prd_table = (struct ufshcd_sg_entry *)lrbp->ucd_prdt_ptr; + +@@ -1507,7 +1512,7 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) + + ufshcd_comp_scsi_upiu(hba, lrbp); + +- err = ufshcd_map_sg(lrbp); ++ err = ufshcd_map_sg(hba, lrbp); + if (err) { + lrbp->cmd = NULL; + clear_bit_unlock(tag, &hba->lrb_in_use); +@@ -2368,12 +2373,21 @@ static void ufshcd_host_memory_configure(struct ufs_hba *hba) + cpu_to_le32(upper_32_bits(cmd_desc_element_addr)); + + /* Response upiu and prdt offset should be in double words */ +- utrdlp[i].response_upiu_offset = ++ if (hba->quirks & UFSHCD_QUIRK_PRDT_BYTE_GRAN) { ++ utrdlp[i].response_upiu_offset = ++ cpu_to_le16(response_offset); ++ utrdlp[i].prd_table_offset = ++ cpu_to_le16(prdt_offset); ++ utrdlp[i].response_upiu_length = ++ cpu_to_le16(ALIGNED_UPIU_SIZE); ++ } else { ++ utrdlp[i].response_upiu_offset = + cpu_to_le16((response_offset >> 2)); +- utrdlp[i].prd_table_offset = ++ utrdlp[i].prd_table_offset = + cpu_to_le16((prdt_offset >> 2)); +- utrdlp[i].response_upiu_length = ++ utrdlp[i].response_upiu_length = + cpu_to_le16(ALIGNED_UPIU_SIZE >> 2); ++ } + + hba->lrb[i].utr_descriptor_ptr = (utrdlp + i); + hba->lrb[i].ucd_req_ptr = +diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h +index 8e76501144d6..7d9ff22acfea 100644 +--- a/drivers/scsi/ufs/ufshcd.h ++++ b/drivers/scsi/ufs/ufshcd.h +@@ -485,6 +485,12 @@ struct ufs_hba { + */ + #define UFSHCD_QUIRK_BROKEN_UFS_HCI_VERSION UFS_BIT(5) + ++ /* ++ * This quirk needs to be enabled if the host contoller regards ++ * resolution of the values of PRDTO and PRDTL in UTRD as byte. ++ */ ++ #define UFSHCD_QUIRK_PRDT_BYTE_GRAN UFS_BIT(7) ++ + unsigned int quirks; /* Deviations from standard UFSHCI spec. */ + + /* Device deviations from standard UFS device spec. */ +-- +2.12.0 + diff --git a/queue/scsi-ufs-introduce-a-new-ufshcd_statea-UFSHCD_STATE_.patch b/queue/scsi-ufs-introduce-a-new-ufshcd_statea-UFSHCD_STATE_.patch new file mode 100644 index 0000000..c6e8f70 --- /dev/null +++ b/queue/scsi-ufs-introduce-a-new-ufshcd_statea-UFSHCD_STATE_.patch @@ -0,0 +1,47 @@ +From 141f81651037ea109188a6bafdc5c9a318bd5a46 Mon Sep 17 00:00:00 2001 +From: Zang Leigang <zangleigang@hisilicon.com> +Date: Wed, 16 Nov 2016 11:29:37 +0800 +Subject: [PATCH] scsi: ufs: introduce a new ufshcd_statea + UFSHCD_STATE_EH_SCHEDULED + +commit 141f81651037ea109188a6bafdc5c9a318bd5a46 upstream. + +Add a new ufshcd_state, indicats that an err handler may get to run +immediately. Use UFSHCD_STATE_ERROR here looks not literaly correct. + +Signed-off-by: Zang Leigang <zangleigang@hisilicon.com> +Reviewed-by: Subhash Jadavani <subhashj@codeaurora.org> +Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> + +diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c +index 576b29c11d7a..421488161cf3 100644 +--- a/drivers/scsi/ufs/ufshcd.c ++++ b/drivers/scsi/ufs/ufshcd.c +@@ -125,6 +125,7 @@ enum { + UFSHCD_STATE_RESET, + UFSHCD_STATE_ERROR, + UFSHCD_STATE_OPERATIONAL, ++ UFSHCD_STATE_EH_SCHEDULED, + }; + + /* UFSHCD error handling flags */ +@@ -1450,6 +1451,7 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) + switch (hba->ufshcd_state) { + case UFSHCD_STATE_OPERATIONAL: + break; ++ case UFSHCD_STATE_EH_SCHEDULED: + case UFSHCD_STATE_RESET: + err = SCSI_MLQUEUE_HOST_BUSY; + goto out_unlock; +@@ -4212,7 +4214,7 @@ static void ufshcd_check_errors(struct ufs_hba *hba) + /* block commands from scsi mid-layer */ + scsi_block_requests(hba->host); + +- hba->ufshcd_state = UFSHCD_STATE_ERROR; ++ hba->ufshcd_state = UFSHCD_STATE_EH_SCHEDULED; + schedule_work(&hba->eh_work); + } + } +-- +2.12.0 + diff --git a/queue/scsi-ufs-issue-link-starup-2-times-if-device-isn-t-a.patch b/queue/scsi-ufs-issue-link-starup-2-times-if-device-isn-t-a.patch new file mode 100644 index 0000000..77f98dd --- /dev/null +++ b/queue/scsi-ufs-issue-link-starup-2-times-if-device-isn-t-a.patch @@ -0,0 +1,71 @@ +From 7caf489b99a42a9017ef3d733912aea8794677e7 Mon Sep 17 00:00:00 2001 +From: "subhashj@codeaurora.org" <subhashj@codeaurora.org> +Date: Wed, 23 Nov 2016 16:32:20 -0800 +Subject: [PATCH] scsi: ufs: issue link starup 2 times if device isn't active + +commit 7caf489b99a42a9017ef3d733912aea8794677e7 upstream. + +If we issue the link startup to the device while its UniPro state is +LinkDown (and device state is sleep/power-down) then link startup +will not move the device state to Active. Device will only move to +active state if the link starup is issued when its UniPro state is +LinkUp. So in this case, we would have to issue the link startup 2 +times to make sure that device moves to active state. + +Reviewed-by: Gilad Broner <gbroner@codeaurora.org> +Signed-off-by: Subhash Jadavani <subhashj@codeaurora.org> +Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> + +diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c +index 28cbca21c4dd..16c5c50d054d 100644 +--- a/drivers/scsi/ufs/ufshcd.c ++++ b/drivers/scsi/ufs/ufshcd.c +@@ -3185,7 +3185,16 @@ static int ufshcd_link_startup(struct ufs_hba *hba) + { + int ret; + int retries = DME_LINKSTARTUP_RETRIES; ++ bool link_startup_again = false; + ++ /* ++ * If UFS device isn't active then we will have to issue link startup ++ * 2 times to make sure the device state move to active. ++ */ ++ if (!ufshcd_is_ufs_dev_active(hba)) ++ link_startup_again = true; ++ ++link_startup: + do { + ufshcd_vops_link_startup_notify(hba, PRE_CHANGE); + +@@ -3211,6 +3220,12 @@ static int ufshcd_link_startup(struct ufs_hba *hba) + /* failed to get the link up... retire */ + goto out; + ++ if (link_startup_again) { ++ link_startup_again = false; ++ retries = DME_LINKSTARTUP_RETRIES; ++ goto link_startup; ++ } ++ + if (hba->quirks & UFSHCD_QUIRK_BROKEN_LCC) { + ret = ufshcd_disable_device_tx_lcc(hba); + if (ret) +@@ -6744,10 +6759,12 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) + pm_runtime_get_sync(dev); + + /* +- * The device-initialize-sequence hasn't been invoked yet. +- * Set the device to power-off state ++ * We are assuming that device wasn't put in sleep/power-down ++ * state exclusively during the boot stage before kernel. ++ * This assumption helps avoid doing link startup twice during ++ * ufshcd_probe_hba(). + */ +- ufshcd_set_ufs_dev_poweroff(hba); ++ ufshcd_set_ufs_dev_active(hba); + + async_schedule(ufshcd_async_scan, hba); + +-- +2.12.0 + diff --git a/queue/sctp-deny-peeloff-operation-on-asocs-with-threads-sl.patch b/queue/sctp-deny-peeloff-operation-on-asocs-with-threads-sl.patch new file mode 100644 index 0000000..95fb292 --- /dev/null +++ b/queue/sctp-deny-peeloff-operation-on-asocs-with-threads-sl.patch @@ -0,0 +1,65 @@ +From dfcb9f4f99f1e9a49e43398a7bfbf56927544af1 Mon Sep 17 00:00:00 2001 +From: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com> +Date: Thu, 23 Feb 2017 09:31:18 -0300 +Subject: [PATCH] sctp: deny peeloff operation on asocs with threads sleeping + on it + +commit dfcb9f4f99f1e9a49e43398a7bfbf56927544af1 upstream. + +commit 2dcab5984841 ("sctp: avoid BUG_ON on sctp_wait_for_sndbuf") +attempted to avoid a BUG_ON call when the association being used for a +sendmsg() is blocked waiting for more sndbuf and another thread did a +peeloff operation on such asoc, moving it to another socket. + +As Ben Hutchings noticed, then in such case it would return without +locking back the socket and would cause two unlocks in a row. + +Further analysis also revealed that it could allow a double free if the +application managed to peeloff the asoc that is created during the +sendmsg call, because then sctp_sendmsg() would try to free the asoc +that was created only for that call. + +This patch takes another approach. It will deny the peeloff operation +if there is a thread sleeping on the asoc, so this situation doesn't +exist anymore. This avoids the issues described above and also honors +the syscalls that are already being handled (it can be multiple sendmsg +calls). + +Joint work with Xin Long. + +Fixes: 2dcab5984841 ("sctp: avoid BUG_ON on sctp_wait_for_sndbuf") +Cc: Alexander Popov <alex.popov@linux.com> +Cc: Ben Hutchings <ben@decadent.org.uk> +Signed-off-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com> +Signed-off-by: Xin Long <lucien.xin@gmail.com> +Signed-off-by: David S. Miller <davem@davemloft.net> + +diff --git a/net/sctp/socket.c b/net/sctp/socket.c +index b5321486fbed..465a9c8464f9 100644 +--- a/net/sctp/socket.c ++++ b/net/sctp/socket.c +@@ -4862,6 +4862,12 @@ int sctp_do_peeloff(struct sock *sk, sctp_assoc_t id, struct socket **sockp) + if (!asoc) + return -EINVAL; + ++ /* If there is a thread waiting on more sndbuf space for ++ * sending on this asoc, it cannot be peeled. ++ */ ++ if (waitqueue_active(&asoc->wait)) ++ return -EBUSY; ++ + /* An association cannot be branched off from an already peeled-off + * socket, nor is this supported for tcp style sockets. + */ +@@ -7599,8 +7605,6 @@ static int sctp_wait_for_sndbuf(struct sctp_association *asoc, long *timeo_p, + */ + release_sock(sk); + current_timeo = schedule_timeout(current_timeo); +- if (sk != asoc->base.sk) +- goto do_error; + lock_sock(sk); + + *timeo_p = current_timeo; +-- +2.12.0 + diff --git a/queue/serial-8250_omap-Add-OMAP_DMA_TX_KICK-quirk-for-AM43.patch b/queue/serial-8250_omap-Add-OMAP_DMA_TX_KICK-quirk-for-AM43.patch new file mode 100644 index 0000000..d69c1f5 --- /dev/null +++ b/queue/serial-8250_omap-Add-OMAP_DMA_TX_KICK-quirk-for-AM43.patch @@ -0,0 +1,52 @@ +From b6ffcf21082300519bc4f9c3d24f61207cc9eae4 Mon Sep 17 00:00:00 2001 +From: Vignesh R <vigneshr@ti.com> +Date: Fri, 20 Jan 2017 13:46:53 +0530 +Subject: [PATCH] serial: 8250_omap: Add OMAP_DMA_TX_KICK quirk for AM437x + +commit b6ffcf21082300519bc4f9c3d24f61207cc9eae4 upstream. + +UART uses as EDMA as dma engine on AM437x SoC and therefore, requires +OMAP_DMA_TX_KICK quirk just like AM33xx. So, enable OMAP_DMA_TX_KICK +quirk for AM437x platform as well. While at that, drop use of +of_machine_is_compatible() and instead pass quirks via device data. + +Signed-off-by: Vignesh R <vigneshr@ti.com> +Acked-by: Tony Lindgren <tony@atomide.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> + +diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c +index 4ad1934ef6ed..97766dcd67d4 100644 +--- a/drivers/tty/serial/8250/8250_omap.c ++++ b/drivers/tty/serial/8250/8250_omap.c +@@ -1078,15 +1078,15 @@ static int omap8250_no_handle_irq(struct uart_port *port) + } + + static const u8 am3352_habit = OMAP_DMA_TX_KICK | UART_ERRATA_CLOCK_DISABLE; +-static const u8 am4372_habit = UART_ERRATA_CLOCK_DISABLE; ++static const u8 dra742_habit = UART_ERRATA_CLOCK_DISABLE; + + static const struct of_device_id omap8250_dt_ids[] = { + { .compatible = "ti,omap2-uart" }, + { .compatible = "ti,omap3-uart" }, + { .compatible = "ti,omap4-uart" }, + { .compatible = "ti,am3352-uart", .data = &am3352_habit, }, +- { .compatible = "ti,am4372-uart", .data = &am4372_habit, }, +- { .compatible = "ti,dra742-uart", .data = &am4372_habit, }, ++ { .compatible = "ti,am4372-uart", .data = &am3352_habit, }, ++ { .compatible = "ti,dra742-uart", .data = &dra742_habit, }, + {}, + }; + MODULE_DEVICE_TABLE(of, omap8250_dt_ids); +@@ -1221,9 +1221,6 @@ static int omap8250_probe(struct platform_device *pdev) + priv->omap8250_dma.rx_size = RX_TRIGGER; + priv->omap8250_dma.rxconf.src_maxburst = RX_TRIGGER; + priv->omap8250_dma.txconf.dst_maxburst = TX_TRIGGER; +- +- if (of_machine_is_compatible("ti,am33xx")) +- priv->habit |= OMAP_DMA_TX_KICK; + /* + * pause is currently not supported atleast on omap-sdma + * and edma on most earlier kernels. +-- +2.12.0 + diff --git a/queue/series b/queue/series new file mode 100644 index 0000000..5e11090 --- /dev/null +++ b/queue/series @@ -0,0 +1,231 @@ +ppdev-check-before-attaching-port.patch +ppdev-fix-registering-same-device-name.patch +drm-vmwgfx-Type-check-lookups-of-fence-objects.patch +drm-vmwgfx-NULL-pointer-dereference-in-vmw_surface_d.patch +drm-vmwgfx-avoid-calling-vzalloc-with-a-0-size-in-vm.patch +drm-ttm-drm-vmwgfx-Relax-permission-checking-when-op.patch +drm-vmwgfx-Remove-getparam-error-message.patch +drm-vmwgfx-fix-integer-overflow-in-vmw_surface_defin.patch +sysfs-be-careful-of-error-returns-from-ops-show.patch +staging-android-ashmem-lseek-failed-due-to-no-FMODE_.patch +arm-arm64-KVM-Take-mmap_sem-in-stage2_unmap_vm.patch +arm-arm64-KVM-Take-mmap_sem-in-kvm_arch_prepare_memo.patch +kvm-arm-arm64-Fix-locking-for-kvm_free_stage2_pgd.patch +iio-bmg160-reset-chip-when-probing.patch +arm64-mm-unaligned-access-by-user-land-should-be-rec.patch +cfg80211-check-rdev-resume-callback-only-for-registe.patch +Reset-TreeId-to-zero-on-SMB2-TREE_CONNECT.patch +mm-page_alloc.c-fix-print-order-in-show_free_areas.patch +ptrace-fix-PTRACE_LISTEN-race-corrupting-task-state.patch +dm-verity-fec-limit-error-correction-recursion.patch +dm-verity-fec-fix-bufio-leaks.patch +ACPI-gpio-do-not-fall-back-to-parsing-_CRS-when-we-g.patch +Kbuild-use-cc-disable-warning-consistently-for-maybe.patch +orangefs-move-features-validation-to-fix-filesystem-.patch +xfs-Honor-FALLOC_FL_KEEP_SIZE-when-punching-ends-of-.patch +ring-buffer-Fix-return-value-check-in-test_ringbuffe.patch +mac80211-unconditionally-start-new-netdev-queues-wit.patch +brcmfmac-use-local-iftype-avoiding-use-after-free-of.patch +metag-usercopy-Drop-unused-macros.patch +metag-usercopy-Fix-alignment-error-checking.patch +metag-usercopy-Add-early-abort-to-copy_to_user.patch +metag-usercopy-Zero-rest-of-buffer-from-copy_from_us.patch +metag-usercopy-Set-flags-before-ADDZ.patch +metag-usercopy-Fix-src-fixup-in-from-user-rapf-loops.patch +metag-usercopy-Add-missing-fixups.patch +powerpc-Disable-HFSCR-TM-if-TM-is-not-supported.patch +powerpc-mm-Add-missing-global-TLB-invalidate-if-cxl-.patch +powerpc-64-Fix-flush_-d-i-cache_range-called-from-mo.patch +powerpc-Don-t-try-to-fix-up-misaligned-load-with-res.patch +powerpc-crypto-crc32c-vpmsum-Fix-missing-preempt_dis.patch +dm-raid-fix-NULL-pointer-dereference-for-raid1-witho.patch +nios2-reserve-boot-memory-for-device-tree.patch +xtensa-make-__pa-work-with-uncached-KSEG-addresses.patch +s390-decompressor-fix-initrd-corruption-caused-by-bs.patch +s390-uaccess-get_user-should-zero-on-failure-again.patch +MIPS-Force-o32-fp64-support-on-32bit-MIPS64r6-kernel.patch +MIPS-ralink-Fix-typos-in-rt3883-pinctrl.patch +MIPS-End-spinlocks-with-.insn.patch +MIPS-Lantiq-fix-missing-xbar-kernel-panic.patch +MIPS-Check-TLB-before-handle_ri_rdhwr-for-Loongson-3.patch +MIPS-Add-MIPS_CPU_FTLB-for-Loongson-3A-R2.patch +MIPS-Flush-wrong-invalid-FTLB-entry-for-huge-page.patch +MIPS-c-r4k-Fix-Loongson-3-s-vcache-scache-waysize-ca.patch +Documentation-stable-kernel-rules-fix-stable-tag-for.patch +mm-mempolicy.c-fix-error-handling-in-set_mempolicy-a.patch +random-use-chacha20-for-get_random_int-long.patch +drm-sun4i-tcon-Move-SoC-specific-quirks-to-a-DT-matc.patch +drm-sun4i-Add-compatible-strings-for-A31-A31s-displa.patch +drm-sun4i-Add-compatible-string-for-A31-A31s-TCON-ti.patch +clk-lpc32xx-add-a-quirk-for-PWM-and-MS-clock-divider.patch +HID-usbhid-Add-quirks-for-Mayflash-Dragonrise-GameCu.patch +HID-i2c-hid-add-a-simple-quirk-to-fix-device-defects.patch +usb-dwc3-gadget-delay-unmap-of-bounced-requests.patch +ASoC-Intel-bytct_rt5640-change-default-capture-setti.patch +arm64-dts-hisi-fix-hip06-sas-am-max-trans-quirk.patch +net-mlx4_core-Use-device-ID-defines.patch +clocksource-drivers-arm_arch_timer-Don-t-assume-cloc.patch +scsi-ufs-introduce-UFSHCD_QUIRK_PRDT_BYTE_GRAN-quirk.patch +HID-sensor-hub-add-quirk-for-Microsoft-Surface-3.patch +HID-sensor-hub-add-quirk-for-Microchip-MM7150.patch +HID-multitouch-enable-the-Surface-3-Type-Cover-to-re.patch +HID-multitouch-do-not-retrieve-all-reports-for-all-d.patch +mmc-sdhci-msm-Enable-few-quirks.patch +scsi-ufs-ensure-that-host-pa_tactivate-is-higher-tha.patch +svcauth_gss-Close-connection-when-dropping-an-incomi.patch +x86-intel_idle-Add-CPU-model-0x4a-Atom-Z34xx-series.patch +arm64-PCI-Manage-controller-specific-data-on-per-con.patch +arm64-PCI-Add-local-struct-device-pointers.patch +PCI-thunder-pem-Factor-out-resource-lookup.patch +scsi-ufs-add-quirk-to-increase-host-PA_SaveConfigTim.patch +ALSA-usb-audio-add-implicit-fb-quirk-for-Axe-Fx-II.patch +PCI-Expand-VPD-access-disabled-quirk-message.patch +ALSA-usb-audio-Add-native-DSD-support-for-TEAC-501-5.patch +platform-x86-acer-wmi-Only-supports-AMW0_GUID1-on-ac.patch +nvme-simplify-stripe-quirk.patch +ACPI-sysfs-Provide-quirk-mechanism-to-prevent-GPE-fl.patch +HID-usbhid-Add-quirk-for-the-Futaba-TOSD-5711BB-VFD.patch +HID-usbhid-Add-quirk-for-Mayflash-Dragonrise-Dolphin.patch +drm-edid-constify-edid-quirk-list.patch +drm-i915-fix-INTEL_BDW_IDS-definition.patch +drm-i915-more-.is_mobile-cleanups-for-BDW.patch +drm-i915-actually-drive-the-BDW-reserved-IDs.patch +ASoC-Intel-bytcr_rt5640-quirks-for-Insyde-devices.patch +scsi-ufs-introduce-a-new-ufshcd_statea-UFSHCD_STATE_.patch +scsi-ufs-issue-link-starup-2-times-if-device-isn-t-a.patch +usb-chipidea-msm-Rely-on-core-to-override-AHBBURST.patch +serial-8250_omap-Add-OMAP_DMA_TX_KICK-quirk-for-AM43.patch +Input-gpio_keys-add-support-for-GPIO-descriptors.patch +ARM-davinci-PM-support-da8xx-DT-platforms.patch +usb-xhci-add-quirk-flag-for-broken-PED-bits.patch +usb-host-xhci-plat-enable-BROKEN_PED-quirk-if-platfo.patch +usb-dwc3-host-pass-quirk-broken-port-ped-property-fo.patch +drm-mga-remove-device_is_agp-callback.patch +ARM-dts-STiH407-family-set-snps-dis_u3_susphy_quirk.patch +PCI-Add-ACS-quirk-for-Intel-Union-Point.patch +sata-ahci-da850-implement-a-workaround-for-the-softr.patch +ACPI-button-Change-default-behavior-to-lid_init_stat.patch +ASoC-rt5670-Add-missing-10EC5072-ACPI-ID.patch +ASoC-codecs-rt5670-add-quirk-for-Lenovo-Thinkpad-10.patch +ASoC-Intel-Baytrail-add-quirk-for-Lenovo-Thinkpad-10.patch +ASoC-Intel-cht_bsw_rt5645-harden-ACPI-device-detecti.patch +ASoC-Intel-cht_bsw_rt5645-add-Baytrail-MCLK-support.patch +ACPI-save-NVS-memory-for-Lenovo-G50-45.patch +ASoC-sun4i-i2s-Add-quirks-to-handle-a31-compatible.patch +HID-wacom-don-t-apply-generic-settings-to-old-device.patch +arm-kernel-Add-SMC-structure-parameter.patch +firmware-qcom-scm-Fix-interrupted-SCM-calls.patch +drm-msm-adreno-move-function-declarations-to-header-.patch +ARM-smccc-Update-HVC-comment-to-describe-new-quirk-p.patch +PCI-Add-Broadcom-Northstar2-PAXC-quirk-for-device-cl.patch +PCI-Disable-MSI-for-HiSilicon-Hip06-Hip07-Root-Ports.patch +mmc-sdhci-of-esdhc-remove-default-broken-cd-for-ARM.patch +PCI-Sort-the-list-of-devices-with-D3-delay-quirk-by-.patch +PCI-Add-ACS-quirk-for-Qualcomm-QDF2400-and-QDF2432.patch +watchdog-s3c2410-Fix-infinite-interrupt-in-soft-mode.patch +platform-x86-asus-wmi-Set-specified-XUSB2PR-value-fo.patch +platform-x86-asus-wmi-Detect-quirk_no_rfkill-from-th.patch +x86-reboot-quirks-Add-ASUS-EeeBook-X205TA-reboot-qui.patch +x86-reboot-quirks-Add-ASUS-EeeBook-X205TA-W-reboot-q.patch +usb-storage-Add-ignore-residue-quirk-for-Initio-INIC.patch +x86-reboot-quirks-Fix-typo-in-ASUS-EeeBook-X205TA-re.patch +drm-i915-gen9-Increase-PCODE-request-timeout-to-50ms.patch +drm-i915-Nuke-debug-messages-from-the-pipe-update-cr.patch +drm-i915-Avoid-tweaking-evaluation-thresholds-on-Bay.patch +drm-i915-Only-enable-hotplug-interrupts-if-the-displ.patch +drm-i915-Drop-support-for-I915_EXEC_CONSTANTS_-execb.patch +drm-i915-Stop-using-RP_DOWN_EI-on-Baytrail.patch +drm-i915-Avoid-rcu_barrier-from-reclaim-paths-shrink.patch +orangefs-fix-memory-leak-of-string-new-on-exit-path.patch +orangefs-Dan-Carpenter-influenced-cleanups.patch +orangefs-fix-buffer-size-mis-match-between-kernel-sp.patch +i2c-bcm2835-Fix-hang-for-writing-messages-larger-tha.patch +rt2x00usb-fix-anchor-initialization.patch +rt2x00usb-do-not-anchor-rx-and-tx-urb-s.patch +rt2x00-Fix-incorrect-usage-of-CONFIG_RT2X00_LIB_USB.patch +mtd-bcm47xxpart-fix-parsing-first-block-after-aligne.patch +MIPS-Introduce-irq_stack.patch +MIPS-Stack-unwinding-while-on-IRQ-stack.patch +MIPS-Only-change-28-to-thread_info-if-coming-from-us.patch +MIPS-Switch-to-the-irq_stack-in-interrupts.patch +MIPS-Select-HAVE_IRQ_EXIT_ON_IRQ_STACK.patch +MIPS-IRQ-Stack-Fix-erroneous-jal-to-plat_irq_dispatc.patch +crypto-caam-fix-RNG-deinstantiation-error-checking.patch +crypto-caam-fix-invalid-dereference-in-caam_rsa_init.patch +Revert-drm-i915-execlists-Reset-RING-registers-upon-.patch +net-packet-fix-overflow-in-check-for-priv-area-size.patch +blk-mq-Avoid-memory-reclaim-when-remapping-queues.patch +usb-hub-Wait-for-connection-to-be-reestablished-afte.patch +net-mlx4_en-Fix-bad-WQE-issue.patch +net-mlx4_core-Fix-racy-CQ-Completion-Queue-free.patch +net-mlx4_core-Fix-when-to-save-some-qp-context-flags.patch +dma-buf-add-support-for-compat-ioctl.patch +cgroup-kthread-close-race-window-where-new-kthreads-.patch +tcmu-Fix-possible-overwrite-of-t_data_sg-s-last-iov.patch +tcmu-Fix-wrongly-calculating-of-the-base_command_siz.patch +tcmu-Skip-Data-Out-blocks-before-gathering-Data-In-b.patch +thp-fix-MADV_DONTNEED-vs.-MADV_FREE-race.patch +thp-fix-MADV_DONTNEED-vs-clear-soft-dirty-race.patch +zsmalloc-expand-class-bit.patch +orangefs-free-superblock-when-mount-fails.patch +drm-nouveau-mpeg-mthd-returns-true-on-success-now.patch +drm-nouveau-mmu-nv4a-use-nv04-mmu-rather-than-the-nv.patch +drm-etnaviv-fix-missing-unlock-on-error-in-etnaviv_g.patch +CIFS-reconnect-thread-reschedule-itself.patch +CIFS-store-results-of-cifs_reopen_file-to-avoid-infi.patch +Input-xpad-add-support-for-Razer-Wildcat-gamepad.patch +perf-x86-Avoid-exposing-wrong-stale-data-in-intel_pm.patch +x86-efi-Don-t-try-to-reserve-runtime-regions.patch +x86-signals-Fix-lower-upper-bound-reporting-in-compa.patch +x86-pmem-fix-broken-__copy_user_nocache-cache-bypass.patch +x86-vdso-Ensure-vdso32_enabled-gets-set-to-valid-val.patch +x86-vdso-Plug-race-between-mapping-and-ELF-header-se.patch +acpi-nfit-libnvdimm-fix-interleave-set-cookie-calcul.patch +ACPI-scan-Set-the-visited-flag-for-all-enumerated-de.patch +parisc-fix-bugs-in-pa_memcpy.patch +efi-libstub-Skip-GOP-with-PIXEL_BLT_ONLY-format.patch +efi-fb-Avoid-reconfiguration-of-BAR-that-covers-the-.patch +iscsi-target-Fix-TMR-reference-leak-during-session-s.patch +iscsi-target-Drop-work-around-for-legacy-GlobalSAN-i.patch +scsi-sr-Sanity-check-returned-mode-data.patch +scsi-sd-Consider-max_xfer_blocks-if-opt_xfer_blocks-.patch +scsi-qla2xxx-Add-fix-to-read-correct-register-value-.patch +scsi-sd-Fix-capacity-calculation-with-32-bit-sector_.patch +target-Avoid-mappedlun-symlink-creation-during-lun-s.patch +xen-fbfront-fix-connecting-to-backend.patch +new-privimitive-iov_iter_revert.patch +make-skb_copy_datagram_msg-et.al.-preserve-msg_iter-.patch +libnvdimm-fix-blk-free-space-accounting.patch +libnvdimm-fix-reconfig_mutex-mmap_sem-and-jbd2_handl.patch +can-ifi-use-correct-register-to-read-rx-status.patch +pwm-rockchip-State-of-PWM-clock-should-synchronize-w.patch +cpufreq-Bring-CPUs-up-even-if-cpufreq_online-failed.patch +irqchip-irq-imx-gpcv2-Fix-spinlock-initialization.patch +ftrace-Fix-removing-of-second-function-probe.patch +char-lack-of-bool-string-made-CONFIG_DEVPORT-always-.patch +Revert-MIPS-Lantiq-Fix-cascaded-IRQ-setup.patch +kvm-fix-page-struct-leak-in-handle_vmon.patch +zram-do-not-use-copy_page-with-non-page-aligned-addr.patch +ftrace-Fix-function-pid-filter-on-instances.patch +crypto-algif_aead-Fix-bogus-request-dereference-in-c.patch +crypto-ahash-Fix-EINPROGRESS-notification-callback.patch +parisc-Fix-get_user-for-64-bit-value-on-32-bit-kerne.patch +ath9k-fix-NULL-pointer-dereference.patch +dvb-usb-v2-avoid-use-after-free.patch +ext4-fix-inode-checksum-calculation-problem-if-i_ext.patch +mm-memcontrol-use-special-workqueue-for-creating-per.patch +drm-nouveau-disp-mcp7x-disable-dptmds-workaround.patch +nbd-use-loff_t-for-blocksize-and-nbd_set_size-args.patch +nbd-fix-64-bit-division.patch +ASoC-Intel-select-DW_DMAC_CORE-since-it-s-mandatory.patch +platform-x86-acer-wmi-setup-accelerometer-when-machi.patch +x86-xen-Fix-APIC-id-mismatch-warning-on-Intel.patch +ACPI-EC-Use-busy-polling-mode-when-GPE-is-not-enable.patch +rtc-tegra-Implement-clock-handling.patch +mm-Tighten-x86-dev-mem-with-zeroing-reads.patch +dvb-usb-don-t-use-stack-for-firmware-load.patch +dvb-usb-firmware-don-t-do-DMA-on-stack.patch +cxusb-Use-a-dma-capable-buffer-also-for-reading.patch +virtio-console-avoid-DMA-from-stack.patch +net-ipv6-check-route-protocol-when-deleting-routes.patch +sctp-deny-peeloff-operation-on-asocs-with-threads-sl.patch diff --git a/queue/staging-android-ashmem-lseek-failed-due-to-no-FMODE_.patch b/queue/staging-android-ashmem-lseek-failed-due-to-no-FMODE_.patch new file mode 100644 index 0000000..924b031 --- /dev/null +++ b/queue/staging-android-ashmem-lseek-failed-due-to-no-FMODE_.patch @@ -0,0 +1,39 @@ +From 97fbfef6bd597888485b653175fb846c6998b60c Mon Sep 17 00:00:00 2001 +From: Shuxiao Zhang <zhangshuxiao@xiaomi.com> +Date: Thu, 6 Apr 2017 22:30:29 +0800 +Subject: [PATCH] staging: android: ashmem: lseek failed due to no FMODE_LSEEK. + +commit 97fbfef6bd597888485b653175fb846c6998b60c upstream. + +vfs_llseek will check whether the file mode has +FMODE_LSEEK, no return failure. But ashmem can be +lseek, so add FMODE_LSEEK to ashmem file. + +Comment From Greg Hackmann: + ashmem_llseek() passes the llseek() call through to the backing + shmem file. 91360b02ab48 ("ashmem: use vfs_llseek()") changed + this from directly calling the file's llseek() op into a VFS + layer call. This also adds a check for the FMODE_LSEEK bit, so + without that bit ashmem_llseek() now always fails with -ESPIPE. + +Fixes: 91360b02ab48 ("ashmem: use vfs_llseek()") +Signed-off-by: Shuxiao Zhang <zhangshuxiao@xiaomi.com> +Tested-by: Greg Hackmann <ghackmann@google.com> +Cc: stable <stable@vger.kernel.org> # 3.18+ +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> + +diff --git a/drivers/staging/android/ashmem.c b/drivers/staging/android/ashmem.c +index 7cbad0d45b9c..6ba270e0494d 100644 +--- a/drivers/staging/android/ashmem.c ++++ b/drivers/staging/android/ashmem.c +@@ -409,6 +409,7 @@ static int ashmem_mmap(struct file *file, struct vm_area_struct *vma) + ret = PTR_ERR(vmfile); + goto out; + } ++ vmfile->f_mode |= FMODE_LSEEK; + asma->file = vmfile; + } + get_file(asma->file); +-- +2.12.0 + diff --git a/queue/svcauth_gss-Close-connection-when-dropping-an-incomi.patch b/queue/svcauth_gss-Close-connection-when-dropping-an-incomi.patch new file mode 100644 index 0000000..c073185 --- /dev/null +++ b/queue/svcauth_gss-Close-connection-when-dropping-an-incomi.patch @@ -0,0 +1,94 @@ +From 4d712ef1db05c3aa5c3b690a50c37ebad584c53f Mon Sep 17 00:00:00 2001 +From: Chuck Lever <chuck.lever@oracle.com> +Date: Tue, 29 Nov 2016 11:04:34 -0500 +Subject: [PATCH] svcauth_gss: Close connection when dropping an incoming + message + +commit 4d712ef1db05c3aa5c3b690a50c37ebad584c53f upstream. + +S5.3.3.1 of RFC 2203 requires that an incoming GSS-wrapped message +whose sequence number lies outside the current window is dropped. +The rationale is: + + The reason for discarding requests silently is that the server + is unable to determine if the duplicate or out of range request + was due to a sequencing problem in the client, network, or the + operating system, or due to some quirk in routing, or a replay + attack by an intruder. Discarding the request allows the client + to recover after timing out, if indeed the duplication was + unintentional or well intended. + +However, clients may rely on the server dropping the connection to +indicate that a retransmit is needed. Without a connection reset, a +client can wait forever without retransmitting, and the workload +just stops dead. I've reproduced this behavior by running xfstests +generic/323 on an NFSv4.0 mount with proto=rdma and sec=krb5i. + +To address this issue, have the server close the connection when it +silently discards an incoming message due to a GSS sequence number +problem. + +There are a few other places where the server will never reply. +Change those spots in a similar fashion. + +Signed-off-by: Chuck Lever <chuck.lever@oracle.com> +Signed-off-by: J. Bruce Fields <bfields@redhat.com> + +diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c +index 45662d7f0943..886e9d381771 100644 +--- a/net/sunrpc/auth_gss/svcauth_gss.c ++++ b/net/sunrpc/auth_gss/svcauth_gss.c +@@ -1548,7 +1548,7 @@ complete: + ret = SVC_COMPLETE; + goto out; + drop: +- ret = SVC_DROP; ++ ret = SVC_CLOSE; + out: + if (rsci) + cache_put(&rsci->h, sn->rsc_cache); +diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c +index 7c8070ec93c8..75f290bddca1 100644 +--- a/net/sunrpc/svc.c ++++ b/net/sunrpc/svc.c +@@ -1155,8 +1155,7 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv) + case SVC_DENIED: + goto err_bad_auth; + case SVC_CLOSE: +- if (test_bit(XPT_TEMP, &rqstp->rq_xprt->xpt_flags)) +- svc_close_xprt(rqstp->rq_xprt); ++ goto close; + case SVC_DROP: + goto dropit; + case SVC_COMPLETE: +@@ -1246,7 +1245,7 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv) + + sendit: + if (svc_authorise(rqstp)) +- goto dropit; ++ goto close; + return 1; /* Caller can now send it */ + + dropit: +@@ -1254,11 +1253,16 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv) + dprintk("svc: svc_process dropit\n"); + return 0; + ++ close: ++ if (test_bit(XPT_TEMP, &rqstp->rq_xprt->xpt_flags)) ++ svc_close_xprt(rqstp->rq_xprt); ++ dprintk("svc: svc_process close\n"); ++ return 0; ++ + err_short_len: + svc_printk(rqstp, "short len %Zd, dropping request\n", + argv->iov_len); +- +- goto dropit; /* drop request */ ++ goto close; + + err_bad_rpc: + serv->sv_stats->rpcbadfmt++; +-- +2.12.0 + diff --git a/queue/sysfs-be-careful-of-error-returns-from-ops-show.patch b/queue/sysfs-be-careful-of-error-returns-from-ops-show.patch new file mode 100644 index 0000000..9439262 --- /dev/null +++ b/queue/sysfs-be-careful-of-error-returns-from-ops-show.patch @@ -0,0 +1,80 @@ +From c8a139d001a1aab1ea8734db14b22dac9dd143b6 Mon Sep 17 00:00:00 2001 +From: NeilBrown <neilb@suse.com> +Date: Mon, 3 Apr 2017 11:30:34 +1000 +Subject: [PATCH] sysfs: be careful of error returns from ops->show() + +commit c8a139d001a1aab1ea8734db14b22dac9dd143b6 upstream. + +ops->show() can return a negative error code. +Commit 65da3484d9be ("sysfs: correctly handle short reads on PREALLOC attrs.") +(in v4.4) caused this to be stored in an unsigned 'size_t' variable, so errors +would look like large numbers. +As a result, if an error is returned, sysfs_kf_read() will return the +value of 'count', typically 4096. + +Commit 17d0774f8068 ("sysfs: correctly handle read offset on PREALLOC attrs") +(in v4.8) extended this error to use the unsigned large 'len' as a size for +memmove(). +Consequently, if ->show returns an error, then the first read() on the +sysfs file will return 4096 and could return uninitialized memory to +user-space. +If the application performs a subsequent read, this will trigger a memmove() +with extremely large count, and is likely to crash the machine is bizarre ways. + +This bug can currently only be triggered by reading from an md +sysfs attribute declared with __ATTR_PREALLOC() during the +brief period between when mddev_put() deletes an mddev from +the ->all_mddevs list, and when mddev_delayed_delete() - which is +scheduled on a workqueue - completes. +Before this, an error won't be returned by the ->show() +After this, the ->show() won't be called. + +I can reproduce it reliably only by putting delay like + usleep_range(500000,700000); +early in mddev_delayed_delete(). Then after creating an +md device md0 run + echo clear > /sys/block/md0/md/array_state; cat /sys/block/md0/md/array_state + +The bug can be triggered without the usleep. + +Fixes: 65da3484d9be ("sysfs: correctly handle short reads on PREALLOC attrs.") +Fixes: 17d0774f8068 ("sysfs: correctly handle read offset on PREALLOC attrs") +Cc: stable@vger.kernel.org +Signed-off-by: NeilBrown <neilb@suse.com> +Acked-by: Tejun Heo <tj@kernel.org> +Reported-and-tested-by: Miroslav Benes <mbenes@suse.cz> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> + +diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c +index b803213d1307..39c75a86c67f 100644 +--- a/fs/sysfs/file.c ++++ b/fs/sysfs/file.c +@@ -108,7 +108,7 @@ static ssize_t sysfs_kf_read(struct kernfs_open_file *of, char *buf, + { + const struct sysfs_ops *ops = sysfs_file_ops(of->kn); + struct kobject *kobj = of->kn->parent->priv; +- size_t len; ++ ssize_t len; + + /* + * If buf != of->prealloc_buf, we don't know how +@@ -117,13 +117,15 @@ static ssize_t sysfs_kf_read(struct kernfs_open_file *of, char *buf, + if (WARN_ON_ONCE(buf != of->prealloc_buf)) + return 0; + len = ops->show(kobj, of->kn->priv, buf); ++ if (len < 0) ++ return len; + if (pos) { + if (len <= pos) + return 0; + len -= pos; + memmove(buf, buf + pos, len); + } +- return min(count, len); ++ return min_t(ssize_t, count, len); + } + + /* kernfs write callback for regular sysfs files */ +-- +2.12.0 + diff --git a/queue/target-Avoid-mappedlun-symlink-creation-during-lun-s.patch b/queue/target-Avoid-mappedlun-symlink-creation-during-lun-s.patch new file mode 100644 index 0000000..b554999 --- /dev/null +++ b/queue/target-Avoid-mappedlun-symlink-creation-during-lun-s.patch @@ -0,0 +1,92 @@ +From 49cb77e297dc611a1b795cfeb79452b3002bd331 Mon Sep 17 00:00:00 2001 +From: Nicholas Bellinger <nab@linux-iscsi.org> +Date: Mon, 27 Mar 2017 16:12:43 -0700 +Subject: [PATCH] target: Avoid mappedlun symlink creation during lun shutdown + +commit 49cb77e297dc611a1b795cfeb79452b3002bd331 upstream. + +This patch closes a race between se_lun deletion during configfs +unlink in target_fabric_port_unlink() -> core_dev_del_lun() +-> core_tpg_remove_lun(), when transport_clear_lun_ref() blocks +waiting for percpu_ref RCU grace period to finish, but a new +NodeACL mappedlun is added before the RCU grace period has +completed. + +This can happen in target_fabric_mappedlun_link() because it +only checks for se_lun->lun_se_dev, which is not cleared until +after transport_clear_lun_ref() percpu_ref RCU grace period +finishes. + +This bug originally manifested as NULL pointer dereference +OOPsen in target_stat_scsi_att_intr_port_show_attr_dev() on +v4.1.y code, because it dereferences lun->lun_se_dev without +a explicit NULL pointer check. + +In post v4.1 code with target-core RCU conversion, the code +in target_stat_scsi_att_intr_port_show_attr_dev() no longer +uses se_lun->lun_se_dev, but the same race still exists. + +To address the bug, go ahead and set se_lun>lun_shutdown as +early as possible in core_tpg_remove_lun(), and ensure new +NodeACL mappedlun creation in target_fabric_mappedlun_link() +fails during se_lun shutdown. + +Reported-by: James Shen <jcs@datera.io> +Cc: James Shen <jcs@datera.io> +Tested-by: James Shen <jcs@datera.io> +Cc: stable@vger.kernel.org # 3.10+ +Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org> + +diff --git a/drivers/target/target_core_fabric_configfs.c b/drivers/target/target_core_fabric_configfs.c +index d8a16ca6baa5..d1e6cab8e3d3 100644 +--- a/drivers/target/target_core_fabric_configfs.c ++++ b/drivers/target/target_core_fabric_configfs.c +@@ -92,6 +92,11 @@ static int target_fabric_mappedlun_link( + pr_err("Source se_lun->lun_se_dev does not exist\n"); + return -EINVAL; + } ++ if (lun->lun_shutdown) { ++ pr_err("Unable to create mappedlun symlink because" ++ " lun->lun_shutdown=true\n"); ++ return -EINVAL; ++ } + se_tpg = lun->lun_tpg; + + nacl_ci = &lun_acl_ci->ci_parent->ci_group->cg_item; +diff --git a/drivers/target/target_core_tpg.c b/drivers/target/target_core_tpg.c +index 6fb191914f45..dfaef4d3b2d2 100644 +--- a/drivers/target/target_core_tpg.c ++++ b/drivers/target/target_core_tpg.c +@@ -642,6 +642,8 @@ void core_tpg_remove_lun( + */ + struct se_device *dev = rcu_dereference_raw(lun->lun_se_dev); + ++ lun->lun_shutdown = true; ++ + core_clear_lun_from_tpg(lun, tpg); + /* + * Wait for any active I/O references to percpu se_lun->lun_ref to +@@ -663,6 +665,8 @@ void core_tpg_remove_lun( + } + if (!(dev->se_hba->hba_flags & HBA_FLAGS_INTERNAL_USE)) + hlist_del_rcu(&lun->link); ++ ++ lun->lun_shutdown = false; + mutex_unlock(&tpg->tpg_lun_mutex); + + percpu_ref_exit(&lun->lun_ref); +diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h +index 4b784b6e21c0..2e282461cfa5 100644 +--- a/include/target/target_core_base.h ++++ b/include/target/target_core_base.h +@@ -705,6 +705,7 @@ struct se_lun { + u64 unpacked_lun; + #define SE_LUN_LINK_MAGIC 0xffff7771 + u32 lun_link_magic; ++ bool lun_shutdown; + bool lun_access_ro; + u32 lun_index; + +-- +2.12.0 + diff --git a/queue/tcmu-Fix-possible-overwrite-of-t_data_sg-s-last-iov.patch b/queue/tcmu-Fix-possible-overwrite-of-t_data_sg-s-last-iov.patch new file mode 100644 index 0000000..451b30e --- /dev/null +++ b/queue/tcmu-Fix-possible-overwrite-of-t_data_sg-s-last-iov.patch @@ -0,0 +1,95 @@ +From ab22d2604c86ceb01bb2725c9860b88a7dd383bb Mon Sep 17 00:00:00 2001 +From: Xiubo Li <lixiubo@cmss.chinamobile.com> +Date: Mon, 27 Mar 2017 17:07:40 +0800 +Subject: [PATCH] tcmu: Fix possible overwrite of t_data_sg's last iov[] + +commit ab22d2604c86ceb01bb2725c9860b88a7dd383bb upstream. + +If there has BIDI data, its first iov[] will overwrite the last +iov[] for se_cmd->t_data_sg. + +To fix this, we can just increase the iov pointer, but this may +introuduce a new memory leakage bug: If the se_cmd->data_length +and se_cmd->t_bidi_data_sg->length are all not aligned up to the +DATA_BLOCK_SIZE, the actual length needed maybe larger than just +sum of them. + +So, this could be avoided by rounding all the data lengthes up +to DATA_BLOCK_SIZE. + +Reviewed-by: Mike Christie <mchristi@redhat.com> +Tested-by: Ilias Tsitsimpis <iliastsi@arrikto.com> +Reviewed-by: Bryant G. Ly <bryantly@linux.vnet.ibm.com> +Signed-off-by: Xiubo Li <lixiubo@cmss.chinamobile.com> +Cc: stable@vger.kernel.org # 3.18+ +Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org> + +diff --git a/drivers/target/target_core_user.c b/drivers/target/target_core_user.c +index 6a17c78e4662..e58dfd4fe448 100644 +--- a/drivers/target/target_core_user.c ++++ b/drivers/target/target_core_user.c +@@ -394,6 +394,20 @@ static bool is_ring_space_avail(struct tcmu_dev *udev, size_t cmd_size, size_t d + return true; + } + ++static inline size_t tcmu_cmd_get_data_length(struct tcmu_cmd *tcmu_cmd) ++{ ++ struct se_cmd *se_cmd = tcmu_cmd->se_cmd; ++ size_t data_length = round_up(se_cmd->data_length, DATA_BLOCK_SIZE); ++ ++ if (se_cmd->se_cmd_flags & SCF_BIDI) { ++ BUG_ON(!(se_cmd->t_bidi_data_sg && se_cmd->t_bidi_data_nents)); ++ data_length += round_up(se_cmd->t_bidi_data_sg->length, ++ DATA_BLOCK_SIZE); ++ } ++ ++ return data_length; ++} ++ + static sense_reason_t + tcmu_queue_cmd_ring(struct tcmu_cmd *tcmu_cmd) + { +@@ -407,7 +421,7 @@ tcmu_queue_cmd_ring(struct tcmu_cmd *tcmu_cmd) + uint32_t cmd_head; + uint64_t cdb_off; + bool copy_to_data_area; +- size_t data_length; ++ size_t data_length = tcmu_cmd_get_data_length(tcmu_cmd); + DECLARE_BITMAP(old_bitmap, DATA_BLOCK_BITS); + + if (test_bit(TCMU_DEV_BIT_BROKEN, &udev->flags)) +@@ -433,11 +447,6 @@ tcmu_queue_cmd_ring(struct tcmu_cmd *tcmu_cmd) + + mb = udev->mb_addr; + cmd_head = mb->cmd_head % udev->cmdr_size; /* UAM */ +- data_length = se_cmd->data_length; +- if (se_cmd->se_cmd_flags & SCF_BIDI) { +- BUG_ON(!(se_cmd->t_bidi_data_sg && se_cmd->t_bidi_data_nents)); +- data_length += se_cmd->t_bidi_data_sg->length; +- } + if ((command_size > (udev->cmdr_size / 2)) || + data_length > udev->data_size) { + pr_warn("TCMU: Request of size %zu/%zu is too big for %u/%zu " +@@ -511,11 +520,14 @@ tcmu_queue_cmd_ring(struct tcmu_cmd *tcmu_cmd) + entry->req.iov_dif_cnt = 0; + + /* Handle BIDI commands */ +- iov_cnt = 0; +- alloc_and_scatter_data_area(udev, se_cmd->t_bidi_data_sg, +- se_cmd->t_bidi_data_nents, &iov, &iov_cnt, false); +- entry->req.iov_bidi_cnt = iov_cnt; +- ++ if (se_cmd->se_cmd_flags & SCF_BIDI) { ++ iov_cnt = 0; ++ iov++; ++ alloc_and_scatter_data_area(udev, se_cmd->t_bidi_data_sg, ++ se_cmd->t_bidi_data_nents, &iov, &iov_cnt, ++ false); ++ entry->req.iov_bidi_cnt = iov_cnt; ++ } + /* cmd's data_bitmap is what changed in process */ + bitmap_xor(tcmu_cmd->data_bitmap, old_bitmap, udev->data_bitmap, + DATA_BLOCK_BITS); +-- +2.12.0 + diff --git a/queue/tcmu-Fix-wrongly-calculating-of-the-base_command_siz.patch b/queue/tcmu-Fix-wrongly-calculating-of-the-base_command_siz.patch new file mode 100644 index 0000000..1a2239e --- /dev/null +++ b/queue/tcmu-Fix-wrongly-calculating-of-the-base_command_siz.patch @@ -0,0 +1,53 @@ +From abe342a5b4b5aa579f6bf40ba73447c699e6b579 Mon Sep 17 00:00:00 2001 +From: Xiubo Li <lixiubo@cmss.chinamobile.com> +Date: Mon, 27 Mar 2017 17:07:41 +0800 +Subject: [PATCH] tcmu: Fix wrongly calculating of the base_command_size + +commit abe342a5b4b5aa579f6bf40ba73447c699e6b579 upstream. + +The t_data_nents and t_bidi_data_nents are the numbers of the +segments, but it couldn't be sure the block size equals to size +of the segment. + +For the worst case, all the blocks are discontiguous and there +will need the same number of iovecs, that's to say: blocks == iovs. +So here just set the number of iovs to block count needed by tcmu +cmd. + +Tested-by: Ilias Tsitsimpis <iliastsi@arrikto.com> +Reviewed-by: Mike Christie <mchristi@redhat.com> +Signed-off-by: Xiubo Li <lixiubo@cmss.chinamobile.com> +Cc: stable@vger.kernel.org # 3.18+ +Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org> + +diff --git a/drivers/target/target_core_user.c b/drivers/target/target_core_user.c +index e58dfd4fe448..9885d1b521fe 100644 +--- a/drivers/target/target_core_user.c ++++ b/drivers/target/target_core_user.c +@@ -408,6 +408,13 @@ static inline size_t tcmu_cmd_get_data_length(struct tcmu_cmd *tcmu_cmd) + return data_length; + } + ++static inline uint32_t tcmu_cmd_get_block_cnt(struct tcmu_cmd *tcmu_cmd) ++{ ++ size_t data_length = tcmu_cmd_get_data_length(tcmu_cmd); ++ ++ return data_length / DATA_BLOCK_SIZE; ++} ++ + static sense_reason_t + tcmu_queue_cmd_ring(struct tcmu_cmd *tcmu_cmd) + { +@@ -435,8 +442,7 @@ tcmu_queue_cmd_ring(struct tcmu_cmd *tcmu_cmd) + * expensive to tell how many regions are freed in the bitmap + */ + base_command_size = max(offsetof(struct tcmu_cmd_entry, +- req.iov[se_cmd->t_bidi_data_nents + +- se_cmd->t_data_nents]), ++ req.iov[tcmu_cmd_get_block_cnt(tcmu_cmd)]), + sizeof(struct tcmu_cmd_entry)); + command_size = base_command_size + + round_up(scsi_command_size(se_cmd->t_task_cdb), TCMU_OP_ALIGN_SIZE); +-- +2.12.0 + diff --git a/queue/tcmu-Skip-Data-Out-blocks-before-gathering-Data-In-b.patch b/queue/tcmu-Skip-Data-Out-blocks-before-gathering-Data-In-b.patch new file mode 100644 index 0000000..9cd54d7 --- /dev/null +++ b/queue/tcmu-Skip-Data-Out-blocks-before-gathering-Data-In-b.patch @@ -0,0 +1,106 @@ +From a5d68ba85801a78c892a0eb8efb711e293ed314b Mon Sep 17 00:00:00 2001 +From: Xiubo Li <lixiubo@cmss.chinamobile.com> +Date: Fri, 31 Mar 2017 10:35:25 +0800 +Subject: [PATCH] tcmu: Skip Data-Out blocks before gathering Data-In buffer + for BIDI case + +commit a5d68ba85801a78c892a0eb8efb711e293ed314b upstream. + +For the bidirectional case, the Data-Out buffer blocks will always at +the head of the tcmu_cmd's bitmap, and before gathering the Data-In +buffer, first of all it should skip the Data-Out ones, or the device +supporting BIDI commands won't work. + +Fixed: 26418649eead ("target/user: Introduce data_bitmap, replace + data_length/data_head/data_tail") +Reported-by: Ilias Tsitsimpis <iliastsi@arrikto.com> +Tested-by: Ilias Tsitsimpis <iliastsi@arrikto.com> +Signed-off-by: Xiubo Li <lixiubo@cmss.chinamobile.com> +Cc: stable@vger.kernel.org # 4.6+ +Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org> + +diff --git a/drivers/target/target_core_user.c b/drivers/target/target_core_user.c +index 9885d1b521fe..f615c3bbb73e 100644 +--- a/drivers/target/target_core_user.c ++++ b/drivers/target/target_core_user.c +@@ -311,24 +311,50 @@ static void free_data_area(struct tcmu_dev *udev, struct tcmu_cmd *cmd) + DATA_BLOCK_BITS); + } + +-static void gather_data_area(struct tcmu_dev *udev, unsigned long *cmd_bitmap, +- struct scatterlist *data_sg, unsigned int data_nents) ++static void gather_data_area(struct tcmu_dev *udev, struct tcmu_cmd *cmd, ++ bool bidi) + { ++ struct se_cmd *se_cmd = cmd->se_cmd; + int i, block; + int block_remaining = 0; + void *from, *to; + size_t copy_bytes, from_offset; +- struct scatterlist *sg; ++ struct scatterlist *sg, *data_sg; ++ unsigned int data_nents; ++ DECLARE_BITMAP(bitmap, DATA_BLOCK_BITS); ++ ++ bitmap_copy(bitmap, cmd->data_bitmap, DATA_BLOCK_BITS); ++ ++ if (!bidi) { ++ data_sg = se_cmd->t_data_sg; ++ data_nents = se_cmd->t_data_nents; ++ } else { ++ uint32_t count; ++ ++ /* ++ * For bidi case, the first count blocks are for Data-Out ++ * buffer blocks, and before gathering the Data-In buffer ++ * the Data-Out buffer blocks should be discarded. ++ */ ++ count = DIV_ROUND_UP(se_cmd->data_length, DATA_BLOCK_SIZE); ++ while (count--) { ++ block = find_first_bit(bitmap, DATA_BLOCK_BITS); ++ clear_bit(block, bitmap); ++ } ++ ++ data_sg = se_cmd->t_bidi_data_sg; ++ data_nents = se_cmd->t_bidi_data_nents; ++ } + + for_each_sg(data_sg, sg, data_nents, i) { + int sg_remaining = sg->length; + to = kmap_atomic(sg_page(sg)) + sg->offset; + while (sg_remaining > 0) { + if (block_remaining == 0) { +- block = find_first_bit(cmd_bitmap, ++ block = find_first_bit(bitmap, + DATA_BLOCK_BITS); + block_remaining = DATA_BLOCK_SIZE; +- clear_bit(block, cmd_bitmap); ++ clear_bit(block, bitmap); + } + copy_bytes = min_t(size_t, sg_remaining, + block_remaining); +@@ -610,19 +636,11 @@ static void tcmu_handle_completion(struct tcmu_cmd *cmd, struct tcmu_cmd_entry * + se_cmd->scsi_sense_length); + free_data_area(udev, cmd); + } else if (se_cmd->se_cmd_flags & SCF_BIDI) { +- DECLARE_BITMAP(bitmap, DATA_BLOCK_BITS); +- + /* Get Data-In buffer before clean up */ +- bitmap_copy(bitmap, cmd->data_bitmap, DATA_BLOCK_BITS); +- gather_data_area(udev, bitmap, +- se_cmd->t_bidi_data_sg, se_cmd->t_bidi_data_nents); ++ gather_data_area(udev, cmd, true); + free_data_area(udev, cmd); + } else if (se_cmd->data_direction == DMA_FROM_DEVICE) { +- DECLARE_BITMAP(bitmap, DATA_BLOCK_BITS); +- +- bitmap_copy(bitmap, cmd->data_bitmap, DATA_BLOCK_BITS); +- gather_data_area(udev, bitmap, +- se_cmd->t_data_sg, se_cmd->t_data_nents); ++ gather_data_area(udev, cmd, false); + free_data_area(udev, cmd); + } else if (se_cmd->data_direction == DMA_TO_DEVICE) { + free_data_area(udev, cmd); +-- +2.12.0 + diff --git a/queue/thp-fix-MADV_DONTNEED-vs-clear-soft-dirty-race.patch b/queue/thp-fix-MADV_DONTNEED-vs-clear-soft-dirty-race.patch new file mode 100644 index 0000000..1be93e3 --- /dev/null +++ b/queue/thp-fix-MADV_DONTNEED-vs-clear-soft-dirty-race.patch @@ -0,0 +1,44 @@ +From 5b7abeae3af8c08c577e599dd0578b9e3ee6687b Mon Sep 17 00:00:00 2001 +From: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com> +Date: Thu, 13 Apr 2017 14:56:28 -0700 +Subject: [PATCH] thp: fix MADV_DONTNEED vs clear soft dirty race + +commit 5b7abeae3af8c08c577e599dd0578b9e3ee6687b upstream. + +Yet another instance of the same race. + +Fix is identical to change_huge_pmd(). + +See "thp: fix MADV_DONTNEED vs. numa balancing race" for more details. + +Link: http://lkml.kernel.org/r/20170302151034.27829-5-kirill.shutemov@linux.intel.com +Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> +Cc: Andrea Arcangeli <aarcange@redhat.com> +Cc: Hillf Danton <hillf.zj@alibaba-inc.com> +Cc: <stable@vger.kernel.org> +Signed-off-by: Andrew Morton <akpm@linux-foundation.org> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> + +diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c +index f08bd31c1081..312578089544 100644 +--- a/fs/proc/task_mmu.c ++++ b/fs/proc/task_mmu.c +@@ -900,7 +900,14 @@ static inline void clear_soft_dirty(struct vm_area_struct *vma, + static inline void clear_soft_dirty_pmd(struct vm_area_struct *vma, + unsigned long addr, pmd_t *pmdp) + { +- pmd_t pmd = pmdp_huge_get_and_clear(vma->vm_mm, addr, pmdp); ++ pmd_t pmd = *pmdp; ++ ++ /* See comment in change_huge_pmd() */ ++ pmdp_invalidate(vma, addr, pmdp); ++ if (pmd_dirty(*pmdp)) ++ pmd = pmd_mkdirty(pmd); ++ if (pmd_young(*pmdp)) ++ pmd = pmd_mkyoung(pmd); + + pmd = pmd_wrprotect(pmd); + pmd = pmd_clear_soft_dirty(pmd); +-- +2.12.0 + diff --git a/queue/thp-fix-MADV_DONTNEED-vs.-MADV_FREE-race.patch b/queue/thp-fix-MADV_DONTNEED-vs.-MADV_FREE-race.patch new file mode 100644 index 0000000..9ebcf72 --- /dev/null +++ b/queue/thp-fix-MADV_DONTNEED-vs.-MADV_FREE-race.patch @@ -0,0 +1,59 @@ +From 58ceeb6bec86d9140f9d91d71a710e963523d063 Mon Sep 17 00:00:00 2001 +From: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com> +Date: Thu, 13 Apr 2017 14:56:26 -0700 +Subject: [PATCH] thp: fix MADV_DONTNEED vs. MADV_FREE race + +commit 58ceeb6bec86d9140f9d91d71a710e963523d063 upstream. + +Both MADV_DONTNEED and MADV_FREE handled with down_read(mmap_sem). + +It's critical to not clear pmd intermittently while handling MADV_FREE +to avoid race with MADV_DONTNEED: + + CPU0: CPU1: + madvise_free_huge_pmd() + pmdp_huge_get_and_clear_full() +madvise_dontneed() + zap_pmd_range() + pmd_trans_huge(*pmd) == 0 (without ptl) + // skip the pmd + set_pmd_at(); + // pmd is re-established + +It results in MADV_DONTNEED skipping the pmd, leaving it not cleared. +It violates MADV_DONTNEED interface and can result is userspace +misbehaviour. + +Basically it's the same race as with numa balancing in +change_huge_pmd(), but a bit simpler to mitigate: we don't need to +preserve dirty/young flags here due to MADV_FREE functionality. + +[kirill.shutemov@linux.intel.com: Urgh... Power is special again] + Link: http://lkml.kernel.org/r/20170303102636.bhd2zhtpds4mt62a@black.fi.intel.com +Link: http://lkml.kernel.org/r/20170302151034.27829-4-kirill.shutemov@linux.intel.com +Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> +Acked-by: Minchan Kim <minchan@kernel.org> +Cc: Minchan Kim <minchan@kernel.org> +Cc: Andrea Arcangeli <aarcange@redhat.com> +Cc: Hillf Danton <hillf.zj@alibaba-inc.com> +Cc: <stable@vger.kernel.org> +Signed-off-by: Andrew Morton <akpm@linux-foundation.org> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> + +diff --git a/mm/huge_memory.c b/mm/huge_memory.c +index 26769465af63..f3c4f9d22821 100644 +--- a/mm/huge_memory.c ++++ b/mm/huge_memory.c +@@ -1568,8 +1568,7 @@ bool madvise_free_huge_pmd(struct mmu_gather *tlb, struct vm_area_struct *vma, + deactivate_page(page); + + if (pmd_young(orig_pmd) || pmd_dirty(orig_pmd)) { +- orig_pmd = pmdp_huge_get_and_clear_full(tlb->mm, addr, pmd, +- tlb->fullmm); ++ pmdp_invalidate(vma, addr, pmd); + orig_pmd = pmd_mkold(orig_pmd); + orig_pmd = pmd_mkclean(orig_pmd); + +-- +2.12.0 + diff --git a/queue/usb-chipidea-msm-Rely-on-core-to-override-AHBBURST.patch b/queue/usb-chipidea-msm-Rely-on-core-to-override-AHBBURST.patch new file mode 100644 index 0000000..60d3495 --- /dev/null +++ b/queue/usb-chipidea-msm-Rely-on-core-to-override-AHBBURST.patch @@ -0,0 +1,44 @@ +From dd3749099cfa2c80039193c438b90f3160eaf7f9 Mon Sep 17 00:00:00 2001 +From: Stephen Boyd <stephen.boyd@linaro.org> +Date: Wed, 28 Dec 2016 14:56:59 -0800 +Subject: [PATCH] usb: chipidea: msm: Rely on core to override AHBBURST + +commit dd3749099cfa2c80039193c438b90f3160eaf7f9 upstream. + +The core framework already handles setting this parameter with a +platform quirk. Add the appropriate flag so that we always set +AHBBURST to 0. Technically DT should be doing this, but we always +do it for msm chipidea devices so setting the flag in the driver +works just as well. If the burst needs to be anything besides 0, +we expect the 'ahb-burst-config' dts property to be present. + +Acked-by: Peter Chen <peter.chen@nxp.com> +Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org> +Signed-off-by: Peter Chen <peter.chen@nxp.com> + +diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c +index 89c1a02d69b5..719b20caf88e 100644 +--- a/drivers/usb/chipidea/ci_hdrc_msm.c ++++ b/drivers/usb/chipidea/ci_hdrc_msm.c +@@ -24,7 +24,6 @@ static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event) + switch (event) { + case CI_HDRC_CONTROLLER_RESET_EVENT: + dev_dbg(dev, "CI_HDRC_CONTROLLER_RESET_EVENT received\n"); +- writel(0, USB_AHBBURST); + /* use AHB transactor, allow posted data writes */ + writel(0x8, USB_AHBMODE); + usb_phy_init(ci->usb_phy); +@@ -47,7 +46,8 @@ static struct ci_hdrc_platform_data ci_hdrc_msm_platdata = { + .name = "ci_hdrc_msm", + .capoffset = DEF_CAPOFFSET, + .flags = CI_HDRC_REGS_SHARED | +- CI_HDRC_DISABLE_STREAMING, ++ CI_HDRC_DISABLE_STREAMING | ++ CI_HDRC_OVERRIDE_AHB_BURST, + + .notify_event = ci_hdrc_msm_notify_event, + }; +-- +2.12.0 + diff --git a/queue/usb-dwc3-gadget-delay-unmap-of-bounced-requests.patch b/queue/usb-dwc3-gadget-delay-unmap-of-bounced-requests.patch new file mode 100644 index 0000000..3a78353 --- /dev/null +++ b/queue/usb-dwc3-gadget-delay-unmap-of-bounced-requests.patch @@ -0,0 +1,65 @@ +From de288e36fe33f7e06fa272bc8e2f85aa386d99aa Mon Sep 17 00:00:00 2001 +From: Janusz Dziedzic <januszx.dziedzic@intel.com> +Date: Mon, 13 Mar 2017 14:11:32 +0200 +Subject: [PATCH] usb: dwc3: gadget: delay unmap of bounced requests + +commit de288e36fe33f7e06fa272bc8e2f85aa386d99aa upstream. + +In the case of bounced ep0 requests, we must delay DMA operation until +after ->complete() otherwise we might overwrite contents of req->buf. + +This caused problems with RNDIS gadget. + +Signed-off-by: Janusz Dziedzic <januszx.dziedzic@intel.com> +Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com> + +diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c +index 0d75158e43fe..79e7a3480d51 100644 +--- a/drivers/usb/dwc3/gadget.c ++++ b/drivers/usb/dwc3/gadget.c +@@ -171,6 +171,7 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req, + int status) + { + struct dwc3 *dwc = dep->dwc; ++ unsigned int unmap_after_complete = false; + + req->started = false; + list_del(&req->list); +@@ -180,11 +181,19 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req, + if (req->request.status == -EINPROGRESS) + req->request.status = status; + +- if (dwc->ep0_bounced && dep->number <= 1) ++ /* ++ * NOTICE we don't want to unmap before calling ->complete() if we're ++ * dealing with a bounced ep0 request. If we unmap it here, we would end ++ * up overwritting the contents of req->buf and this could confuse the ++ * gadget driver. ++ */ ++ if (dwc->ep0_bounced && dep->number <= 1) { + dwc->ep0_bounced = false; +- +- usb_gadget_unmap_request_by_dev(dwc->sysdev, +- &req->request, req->direction); ++ unmap_after_complete = true; ++ } else { ++ usb_gadget_unmap_request_by_dev(dwc->sysdev, ++ &req->request, req->direction); ++ } + + trace_dwc3_gadget_giveback(req); + +@@ -192,6 +201,10 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req, + usb_gadget_giveback_request(&dep->endpoint, &req->request); + spin_lock(&dwc->lock); + ++ if (unmap_after_complete) ++ usb_gadget_unmap_request_by_dev(dwc->sysdev, ++ &req->request, req->direction); ++ + if (dep->number > 1) + pm_runtime_put(dwc->dev); + } +-- +2.12.0 + diff --git a/queue/usb-dwc3-host-pass-quirk-broken-port-ped-property-fo.patch b/queue/usb-dwc3-host-pass-quirk-broken-port-ped-property-fo.patch new file mode 100644 index 0000000..b98e536 --- /dev/null +++ b/queue/usb-dwc3-host-pass-quirk-broken-port-ped-property-fo.patch @@ -0,0 +1,63 @@ +From e42a5dbb8a3d14f5a35bffa3bf7dcb87883f767a Mon Sep 17 00:00:00 2001 +From: Felipe Balbi <felipe.balbi@linux.intel.com> +Date: Thu, 26 Jan 2017 11:17:37 +0200 +Subject: [PATCH] usb: dwc3: host: pass quirk-broken-port-ped property for + known broken revisions + +commit e42a5dbb8a3d14f5a35bffa3bf7dcb87883f767a upstream. + +dwc3 revisions <=3.00a have a limitation where Port Disable command +doesn't work. Set the quirk-broken-port-ped property for such +controllers so XHCI core can do the necessary workaround. + +[rogerq@ti.com] Updated code from platform data to device property. + +Signed-off-by: Roger Quadros <rogerq@ti.com> +Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com> + +diff --git a/drivers/usb/dwc3/host.c b/drivers/usb/dwc3/host.c +index 487f0ff6ae25..76f0b0df37c1 100644 +--- a/drivers/usb/dwc3/host.c ++++ b/drivers/usb/dwc3/host.c +@@ -54,11 +54,12 @@ out: + + int dwc3_host_init(struct dwc3 *dwc) + { +- struct property_entry props[2]; ++ struct property_entry props[3]; + struct platform_device *xhci; + int ret, irq; + struct resource *res; + struct platform_device *dwc3_pdev = to_platform_device(dwc->dev); ++ int prop_idx = 0; + + irq = dwc3_host_get_irq(dwc); + if (irq < 0) +@@ -97,8 +98,22 @@ int dwc3_host_init(struct dwc3 *dwc) + + memset(props, 0, sizeof(struct property_entry) * ARRAY_SIZE(props)); + +- if (dwc->usb3_lpm_capable) { +- props[0].name = "usb3-lpm-capable"; ++ if (dwc->usb3_lpm_capable) ++ props[prop_idx++].name = "usb3-lpm-capable"; ++ ++ /** ++ * WORKAROUND: dwc3 revisions <=3.00a have a limitation ++ * where Port Disable command doesn't work. ++ * ++ * The suggested workaround is that we avoid Port Disable ++ * completely. ++ * ++ * This following flag tells XHCI to do just that. ++ */ ++ if (dwc->revision <= DWC3_REVISION_300A) ++ props[prop_idx++].name = "quirk-broken-port-ped"; ++ ++ if (prop_idx) { + ret = platform_device_add_properties(xhci, props); + if (ret) { + dev_err(dwc->dev, "failed to add properties to xHCI\n"); +-- +2.12.0 + diff --git a/queue/usb-host-xhci-plat-enable-BROKEN_PED-quirk-if-platfo.patch b/queue/usb-host-xhci-plat-enable-BROKEN_PED-quirk-if-platfo.patch new file mode 100644 index 0000000..82f4e50 --- /dev/null +++ b/queue/usb-host-xhci-plat-enable-BROKEN_PED-quirk-if-platfo.patch @@ -0,0 +1,48 @@ +From 21939f003ad09355d9c975735750bb22aa37d8de Mon Sep 17 00:00:00 2001 +From: Felipe Balbi <balbi@ti.com> +Date: Mon, 23 Jan 2017 14:19:59 +0200 +Subject: [PATCH] usb: host: xhci-plat: enable BROKEN_PED quirk if platform + requested + +commit 21939f003ad09355d9c975735750bb22aa37d8de upstream. + +In case 'quirk-broken-port-ped' property is passed in via device property, +we should enable the corresponding BROKEN_PED quirk flag for XHCI core. + +[rogerq@ti.com] Updated code from platform data to device property +and added DT binding. + +Signed-off-by: Felipe Balbi <balbi@ti.com> +Signed-off-by: Roger Quadros <rogerq@ti.com> +Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> + +diff --git a/Documentation/devicetree/bindings/usb/usb-xhci.txt b/Documentation/devicetree/bindings/usb/usb-xhci.txt +index 0b7d8576001c..2d80b60eeabe 100644 +--- a/Documentation/devicetree/bindings/usb/usb-xhci.txt ++++ b/Documentation/devicetree/bindings/usb/usb-xhci.txt +@@ -27,6 +27,7 @@ Required properties: + Optional properties: + - clocks: reference to a clock + - usb3-lpm-capable: determines if platform is USB3 LPM capable ++ - quirk-broken-port-ped: set if the controller has broken port disable mechanism + + Example: + usb@f0931000 { +diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c +index c0cd98e804a3..6d33b42ffcf5 100644 +--- a/drivers/usb/host/xhci-plat.c ++++ b/drivers/usb/host/xhci-plat.c +@@ -232,6 +232,9 @@ static int xhci_plat_probe(struct platform_device *pdev) + if (device_property_read_bool(&pdev->dev, "usb3-lpm-capable")) + xhci->quirks |= XHCI_LPM_SUPPORT; + ++ if (device_property_read_bool(&pdev->dev, "quirk-broken-port-ped")) ++ xhci->quirks |= XHCI_BROKEN_PORT_PED; ++ + hcd->usb_phy = devm_usb_get_phy_by_phandle(&pdev->dev, "usb-phy", 0); + if (IS_ERR(hcd->usb_phy)) { + ret = PTR_ERR(hcd->usb_phy); +-- +2.12.0 + diff --git a/queue/usb-hub-Wait-for-connection-to-be-reestablished-afte.patch b/queue/usb-hub-Wait-for-connection-to-be-reestablished-afte.patch new file mode 100644 index 0000000..66d8555 --- /dev/null +++ b/queue/usb-hub-Wait-for-connection-to-be-reestablished-afte.patch @@ -0,0 +1,64 @@ +From 22547c4cc4fe20698a6a85a55b8788859134b8e4 Mon Sep 17 00:00:00 2001 +From: Guenter Roeck <linux@roeck-us.net> +Date: Thu, 1 Dec 2016 13:49:59 -0800 +Subject: [PATCH] usb: hub: Wait for connection to be reestablished after port + reset + +commit 22547c4cc4fe20698a6a85a55b8788859134b8e4 upstream. + +On a system with a defective USB device connected to an USB hub, +an endless sequence of port connect events was observed. The sequence +of events as observed is as follows: + +- Port reports connected event (port status=USB_PORT_STAT_CONNECTION). +- Event handler debounces port and resets it by calling hub_port_reset(). +- hub_port_reset() calls hub_port_wait_reset() to wait for the reset + to complete. +- The reset completes, but USB_PORT_STAT_CONNECTION is not immediately + set in the port status register. +- hub_port_wait_reset() returns -ENOTCONN. +- Port initialization sequence is aborted. +- A few milliseconds later, the port again reports a connected event, + and the sequence repeats. + +This continues either forever or, randomly, stops if the connection +is already re-established when the port status is read. It results in +a high rate of udev events. This in turn destabilizes userspace since +the above sequence holds the device mutex pretty much continuously +and prevents userspace from actually reading the device status. + +To prevent the problem from happening, let's wait for the connection +to be re-established after a port reset. If the device was actually +disconnected, the code will still return an error, but it will do so +only after the long reset timeout. + +Cc: Douglas Anderson <dianders@chromium.org> +Signed-off-by: Guenter Roeck <linux@roeck-us.net> +Acked-by: Alan Stern <stern@rowland.harvard.edu> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> + +diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c +index 71bf1c7635de..143454ea385b 100644 +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -2681,8 +2681,15 @@ static int hub_port_wait_reset(struct usb_hub *hub, int port1, + if (ret < 0) + return ret; + +- /* The port state is unknown until the reset completes. */ +- if (!(portstatus & USB_PORT_STAT_RESET)) ++ /* ++ * The port state is unknown until the reset completes. ++ * ++ * On top of that, some chips may require additional time ++ * to re-establish a connection after the reset is complete, ++ * so also wait for the connection to be re-established. ++ */ ++ if (!(portstatus & USB_PORT_STAT_RESET) && ++ (portstatus & USB_PORT_STAT_CONNECTION)) + break; + + /* switch to the long delay after two short delay failures */ +-- +2.12.0 + diff --git a/queue/usb-storage-Add-ignore-residue-quirk-for-Initio-INIC.patch b/queue/usb-storage-Add-ignore-residue-quirk-for-Initio-INIC.patch new file mode 100644 index 0000000..9a23c2c --- /dev/null +++ b/queue/usb-storage-Add-ignore-residue-quirk-for-Initio-INIC.patch @@ -0,0 +1,47 @@ +From d595259fbb7a7afed241b1afb2c4fe4b47de47fa Mon Sep 17 00:00:00 2001 +From: Tobias Jakobi <tjakobi@math.uni-bielefeld.de> +Date: Tue, 28 Feb 2017 00:46:58 +0100 +Subject: [PATCH] usb-storage: Add ignore-residue quirk for Initio INIC-3619 + +commit d595259fbb7a7afed241b1afb2c4fe4b47de47fa upstream. + +This USB-SATA bridge chip is used in a StarTech enclosure for +optical drives. + +Without the quirk MakeMKV fails during the key exchange with an +installed BluRay drive: +> Error 'Scsi error - ILLEGAL REQUEST:COPY PROTECTION KEY EXCHANGE FAILURE - KEY NOT ESTABLISHED' +> occurred while issuing SCSI command AD010..080002400 to device 'SG:dev_11:2' + +Signed-off-by: Tobias Jakobi <tjakobi@math.uni-bielefeld.de> +Acked-by: Alan Stern <stern@rowland.harvard.edu> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> + +diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h +index 16cc18369111..9129f6cb8230 100644 +--- a/drivers/usb/storage/unusual_devs.h ++++ b/drivers/usb/storage/unusual_devs.h +@@ -2071,6 +2071,20 @@ UNUSUAL_DEV( 0x1370, 0x6828, 0x0110, 0x0110, + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_IGNORE_RESIDUE ), + ++/* ++ * Reported by Tobias Jakobi <tjakobi@math.uni-bielefeld.de> ++ * The INIC-3619 bridge is used in the StarTech SLSODDU33B ++ * SATA-USB enclosure for slimline optical drives. ++ * ++ * The quirk enables MakeMKV to properly exchange keys with ++ * an installed BD drive. ++ */ ++UNUSUAL_DEV( 0x13fd, 0x3609, 0x0209, 0x0209, ++ "Initio Corporation", ++ "INIC-3619", ++ USB_SC_DEVICE, USB_PR_DEVICE, NULL, ++ US_FL_IGNORE_RESIDUE ), ++ + /* Reported by Qinglin Ye <yestyle@gmail.com> */ + UNUSUAL_DEV( 0x13fe, 0x3600, 0x0100, 0x0100, + "Kingston", +-- +2.12.0 + diff --git a/queue/usb-xhci-add-quirk-flag-for-broken-PED-bits.patch b/queue/usb-xhci-add-quirk-flag-for-broken-PED-bits.patch new file mode 100644 index 0000000..1d607c5 --- /dev/null +++ b/queue/usb-xhci-add-quirk-flag-for-broken-PED-bits.patch @@ -0,0 +1,66 @@ +From 41135de1e7fd14c6fcb9158404ba5c8fb97bf259 Mon Sep 17 00:00:00 2001 +From: Felipe Balbi <balbi@ti.com> +Date: Mon, 23 Jan 2017 14:19:58 +0200 +Subject: [PATCH] usb: xhci: add quirk flag for broken PED bits +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit 41135de1e7fd14c6fcb9158404ba5c8fb97bf259 upstream. + +Some devices from Texas Instruments [1] suffer from +a silicon bug where Port Enabled/Disabled bit +should not be used to silence an erroneous device. + +The bug is so that if port is disabled with PED +bit, an IRQ for device removal (or attachment) +will never fire. + +Just for the sake of completeness, the actual +problem lies with SNPS USB IP and this affects +all known versions up to 3.00a. A separate +patch will be added to dwc3 to enabled this +quirk flag if version is <= 3.00a. + +[1] - AM572x Silicon Errata http://www.ti.com/lit/er/sprz429j/sprz429j.pdf +Section i896— USB xHCI Port Disable Feature Does Not Work + +Signed-off-by: Felipe Balbi <balbi@ti.com> +Signed-off-by: Roger Quadros <rogerq@ti.com> +Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> + +diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c +index 2d154e27c142..8b906c3683c3 100644 +--- a/drivers/usb/host/xhci-hub.c ++++ b/drivers/usb/host/xhci-hub.c +@@ -458,6 +458,12 @@ static void xhci_disable_port(struct usb_hcd *hcd, struct xhci_hcd *xhci, + return; + } + ++ if (xhci->quirks & XHCI_BROKEN_PORT_PED) { ++ xhci_dbg(xhci, ++ "Broken Port Enabled/Disabled, ignoring port disable request.\n"); ++ return; ++ } ++ + /* Write 1 to disable the port */ + writel(port_status | PORT_PE, addr); + port_status = readl(addr); +diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h +index 5bf9df25e2ea..b8474a2e6e5d 100644 +--- a/drivers/usb/host/xhci.h ++++ b/drivers/usb/host/xhci.h +@@ -1648,6 +1648,9 @@ struct xhci_hcd { + #define XHCI_SSIC_PORT_UNUSED (1 << 22) + #define XHCI_NO_64BIT_SUPPORT (1 << 23) + #define XHCI_MISSING_CAS (1 << 24) ++/* For controller with a broken Port Disable implementation */ ++#define XHCI_BROKEN_PORT_PED (1 << 25) ++ + unsigned int num_active_eps; + unsigned int limit_active_eps; + /* There are two roothubs to keep track of bus suspend info for */ +-- +2.12.0 + diff --git a/queue/virtio-console-avoid-DMA-from-stack.patch b/queue/virtio-console-avoid-DMA-from-stack.patch new file mode 100644 index 0000000..84e8614 --- /dev/null +++ b/queue/virtio-console-avoid-DMA-from-stack.patch @@ -0,0 +1,48 @@ +From c4baad50297d84bde1a7ad45e50c73adae4a2192 Mon Sep 17 00:00:00 2001 +From: Omar Sandoval <osandov@fb.com> +Date: Wed, 1 Feb 2017 00:02:27 -0800 +Subject: [PATCH] virtio-console: avoid DMA from stack + +commit c4baad50297d84bde1a7ad45e50c73adae4a2192 upstream. + +put_chars() stuffs the buffer it gets into an sg, but that buffer may be +on the stack. This breaks with CONFIG_VMAP_STACK=y (for me, it +manifested as printks getting turned into NUL bytes). + +Signed-off-by: Omar Sandoval <osandov@fb.com> +Signed-off-by: Michael S. Tsirkin <mst@redhat.com> +Reviewed-by: Amit Shah <amit.shah@redhat.com> + +diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c +index 6266c0568e1d..e9b7e0b3cabe 100644 +--- a/drivers/char/virtio_console.c ++++ b/drivers/char/virtio_console.c +@@ -1136,6 +1136,8 @@ static int put_chars(u32 vtermno, const char *buf, int count) + { + struct port *port; + struct scatterlist sg[1]; ++ void *data; ++ int ret; + + if (unlikely(early_put_chars)) + return early_put_chars(vtermno, buf, count); +@@ -1144,8 +1146,14 @@ static int put_chars(u32 vtermno, const char *buf, int count) + if (!port) + return -EPIPE; + +- sg_init_one(sg, buf, count); +- return __send_to_port(port, sg, 1, count, (void *)buf, false); ++ data = kmemdup(buf, count, GFP_ATOMIC); ++ if (!data) ++ return -ENOMEM; ++ ++ sg_init_one(sg, data, count); ++ ret = __send_to_port(port, sg, 1, count, data, false); ++ kfree(data); ++ return ret; + } + + /* +-- +2.12.0 + diff --git a/queue/watchdog-s3c2410-Fix-infinite-interrupt-in-soft-mode.patch b/queue/watchdog-s3c2410-Fix-infinite-interrupt-in-soft-mode.patch new file mode 100644 index 0000000..ae8e292 --- /dev/null +++ b/queue/watchdog-s3c2410-Fix-infinite-interrupt-in-soft-mode.patch @@ -0,0 +1,126 @@ +From 0b445549ea6f91ffea78a976fe89b932db6e077a Mon Sep 17 00:00:00 2001 +From: Krzysztof Kozlowski <krzk@kernel.org> +Date: Fri, 24 Feb 2017 17:11:16 +0200 +Subject: [PATCH] watchdog: s3c2410: Fix infinite interrupt in soft mode + +commit 0b445549ea6f91ffea78a976fe89b932db6e077a upstream. + +In soft (no-reboot) mode, the driver self-pings watchdog upon expiration +of an interrupt. However the interrupt itself was not cleared thus on +first hit, the system enters infinite interrupt handling loop. + +On Odroid U3 (Exynos4412), when booted with s3c2410_wdt.soft_noboot=1 +argument the console is flooded: + # killall -9 watchdog + [ 60.523760] s3c2410-wdt 10060000.watchdog: watchdog timer expired (irq) + [ 60.536744] s3c2410-wdt 10060000.watchdog: watchdog timer expired (irq) + +Fix this by writing something to the WTCLRINT register to clear the +interrupt. The register WTCLRINT however appeared in S3C6410 so a new +watchdog quirk and flavor are needed. + +Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org> +Reviewed-by: Guenter Roeck <linux@roeck-us.net> +Signed-off-by: Guenter Roeck <linux@roeck-us.net> + +diff --git a/Documentation/devicetree/bindings/watchdog/samsung-wdt.txt b/Documentation/devicetree/bindings/watchdog/samsung-wdt.txt +index 8f3d96af81d7..1f6e101e299a 100644 +--- a/Documentation/devicetree/bindings/watchdog/samsung-wdt.txt ++++ b/Documentation/devicetree/bindings/watchdog/samsung-wdt.txt +@@ -6,10 +6,11 @@ occurred. + + Required properties: + - compatible : should be one among the following +- (a) "samsung,s3c2410-wdt" for Exynos4 and previous SoCs +- (b) "samsung,exynos5250-wdt" for Exynos5250 +- (c) "samsung,exynos5420-wdt" for Exynos5420 +- (c) "samsung,exynos7-wdt" for Exynos7 ++ - "samsung,s3c2410-wdt" for S3C2410 ++ - "samsung,s3c6410-wdt" for S3C6410, S5PV210 and Exynos4 ++ - "samsung,exynos5250-wdt" for Exynos5250 ++ - "samsung,exynos5420-wdt" for Exynos5420 ++ - "samsung,exynos7-wdt" for Exynos7 + + - reg : base physical address of the controller and length of memory mapped + region. +diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c +index b305b8717d9f..558789b8805f 100644 +--- a/drivers/watchdog/s3c2410_wdt.c ++++ b/drivers/watchdog/s3c2410_wdt.c +@@ -46,6 +46,7 @@ + #define S3C2410_WTCON 0x00 + #define S3C2410_WTDAT 0x04 + #define S3C2410_WTCNT 0x08 ++#define S3C2410_WTCLRINT 0x0c + + #define S3C2410_WTCNT_MAXCNT 0xffff + +@@ -72,6 +73,7 @@ + #define EXYNOS5_WDT_MASK_RESET_REG_OFFSET 0x040c + #define QUIRK_HAS_PMU_CONFIG (1 << 0) + #define QUIRK_HAS_RST_STAT (1 << 1) ++#define QUIRK_HAS_WTCLRINT_REG (1 << 2) + + /* These quirks require that we have a PMU register map */ + #define QUIRKS_HAVE_PMUREG (QUIRK_HAS_PMU_CONFIG | \ +@@ -143,13 +145,18 @@ static const struct s3c2410_wdt_variant drv_data_s3c2410 = { + }; + + #ifdef CONFIG_OF ++static const struct s3c2410_wdt_variant drv_data_s3c6410 = { ++ .quirks = QUIRK_HAS_WTCLRINT_REG, ++}; ++ + static const struct s3c2410_wdt_variant drv_data_exynos5250 = { + .disable_reg = EXYNOS5_WDT_DISABLE_REG_OFFSET, + .mask_reset_reg = EXYNOS5_WDT_MASK_RESET_REG_OFFSET, + .mask_bit = 20, + .rst_stat_reg = EXYNOS5_RST_STAT_REG_OFFSET, + .rst_stat_bit = 20, +- .quirks = QUIRK_HAS_PMU_CONFIG | QUIRK_HAS_RST_STAT, ++ .quirks = QUIRK_HAS_PMU_CONFIG | QUIRK_HAS_RST_STAT \ ++ | QUIRK_HAS_WTCLRINT_REG, + }; + + static const struct s3c2410_wdt_variant drv_data_exynos5420 = { +@@ -158,7 +165,8 @@ static const struct s3c2410_wdt_variant drv_data_exynos5420 = { + .mask_bit = 0, + .rst_stat_reg = EXYNOS5_RST_STAT_REG_OFFSET, + .rst_stat_bit = 9, +- .quirks = QUIRK_HAS_PMU_CONFIG | QUIRK_HAS_RST_STAT, ++ .quirks = QUIRK_HAS_PMU_CONFIG | QUIRK_HAS_RST_STAT \ ++ | QUIRK_HAS_WTCLRINT_REG, + }; + + static const struct s3c2410_wdt_variant drv_data_exynos7 = { +@@ -167,12 +175,15 @@ static const struct s3c2410_wdt_variant drv_data_exynos7 = { + .mask_bit = 23, + .rst_stat_reg = EXYNOS5_RST_STAT_REG_OFFSET, + .rst_stat_bit = 23, /* A57 WDTRESET */ +- .quirks = QUIRK_HAS_PMU_CONFIG | QUIRK_HAS_RST_STAT, ++ .quirks = QUIRK_HAS_PMU_CONFIG | QUIRK_HAS_RST_STAT \ ++ | QUIRK_HAS_WTCLRINT_REG, + }; + + static const struct of_device_id s3c2410_wdt_match[] = { + { .compatible = "samsung,s3c2410-wdt", + .data = &drv_data_s3c2410 }, ++ { .compatible = "samsung,s3c6410-wdt", ++ .data = &drv_data_s3c6410 }, + { .compatible = "samsung,exynos5250-wdt", + .data = &drv_data_exynos5250 }, + { .compatible = "samsung,exynos5420-wdt", +@@ -418,6 +429,10 @@ static irqreturn_t s3c2410wdt_irq(int irqno, void *param) + dev_info(wdt->dev, "watchdog timer expired (irq)\n"); + + s3c2410wdt_keepalive(&wdt->wdt_device); ++ ++ if (wdt->drv_data->quirks & QUIRK_HAS_WTCLRINT_REG) ++ writel(0x1, wdt->reg_base + S3C2410_WTCLRINT); ++ + return IRQ_HANDLED; + } + +-- +2.12.0 + diff --git a/queue/x86-efi-Don-t-try-to-reserve-runtime-regions.patch b/queue/x86-efi-Don-t-try-to-reserve-runtime-regions.patch new file mode 100644 index 0000000..56d1a62 --- /dev/null +++ b/queue/x86-efi-Don-t-try-to-reserve-runtime-regions.patch @@ -0,0 +1,64 @@ +From 6f6266a561306e206e0e31a5038f029b6a7b1d89 Mon Sep 17 00:00:00 2001 +From: Omar Sandoval <osandov@fb.com> +Date: Wed, 12 Apr 2017 16:27:19 +0100 +Subject: [PATCH] x86/efi: Don't try to reserve runtime regions + +commit 6f6266a561306e206e0e31a5038f029b6a7b1d89 upstream. + +Reserving a runtime region results in splitting the EFI memory +descriptors for the runtime region. This results in runtime region +descriptors with bogus memory mappings, leading to interesting crashes +like the following during a kexec: + + general protection fault: 0000 [#1] SMP + Modules linked in: + CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.11.0-rc1 #53 + Hardware name: Wiwynn Leopard-Orv2/Leopard-DDR BW, BIOS LBM05 09/30/2016 + RIP: 0010:virt_efi_set_variable() + ... + Call Trace: + efi_delete_dummy_variable() + efi_enter_virtual_mode() + start_kernel() + ? set_init_arg() + x86_64_start_reservations() + x86_64_start_kernel() + start_cpu() + ... + Kernel panic - not syncing: Fatal exception + +Runtime regions will not be freed and do not need to be reserved, so +skip the memmap modification in this case. + +Signed-off-by: Omar Sandoval <osandov@fb.com> +Signed-off-by: Matt Fleming <matt@codeblueprint.co.uk> +Cc: <stable@vger.kernel.org> # v4.9+ +Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org> +Cc: Dave Young <dyoung@redhat.com> +Cc: Linus Torvalds <torvalds@linux-foundation.org> +Cc: Peter Jones <pjones@redhat.com> +Cc: Peter Zijlstra <peterz@infradead.org> +Cc: Thomas Gleixner <tglx@linutronix.de> +Cc: linux-efi@vger.kernel.org +Fixes: 8e80632fb23f ("efi/esrt: Use efi_mem_reserve() and avoid a kmalloc()") +Link: http://lkml.kernel.org/r/20170412152719.9779-2-matt@codeblueprint.co.uk +Signed-off-by: Ingo Molnar <mingo@kernel.org> + +diff --git a/arch/x86/platform/efi/quirks.c b/arch/x86/platform/efi/quirks.c +index 30031d5293c4..cdfe8c628959 100644 +--- a/arch/x86/platform/efi/quirks.c ++++ b/arch/x86/platform/efi/quirks.c +@@ -201,6 +201,10 @@ void __init efi_arch_mem_reserve(phys_addr_t addr, u64 size) + return; + } + ++ /* No need to reserve regions that will never be freed. */ ++ if (md.attribute & EFI_MEMORY_RUNTIME) ++ return; ++ + size += addr % EFI_PAGE_SIZE; + size = round_up(size, EFI_PAGE_SIZE); + addr = round_down(addr, EFI_PAGE_SIZE); +-- +2.12.0 + diff --git a/queue/x86-intel_idle-Add-CPU-model-0x4a-Atom-Z34xx-series.patch b/queue/x86-intel_idle-Add-CPU-model-0x4a-Atom-Z34xx-series.patch new file mode 100644 index 0000000..04981dd --- /dev/null +++ b/queue/x86-intel_idle-Add-CPU-model-0x4a-Atom-Z34xx-series.patch @@ -0,0 +1,91 @@ +From 5e7ec268fd48d63cfd0e3a9be6c6443f01673bd4 Mon Sep 17 00:00:00 2001 +From: Andy Shevchenko <andriy.shevchenko@linux.intel.com> +Date: Tue, 25 Oct 2016 17:11:39 +0300 +Subject: [PATCH] x86/intel_idle: Add CPU model 0x4a (Atom Z34xx series) + +commit 5e7ec268fd48d63cfd0e3a9be6c6443f01673bd4 upstream. + +Add CPU ID for Atom Z34xx processors. Datasheets indicate support for this, +detailed information about potential quirks or limitations are missing, though. +So we just reuse the definition from official BSP code. + +Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> +Signed-off-by: Len Brown <len.brown@intel.com> + +diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c +index 4466a2f969d7..5ded9b22b015 100644 +--- a/drivers/idle/intel_idle.c ++++ b/drivers/idle/intel_idle.c +@@ -724,6 +724,50 @@ static struct cpuidle_state atom_cstates[] = { + { + .enter = NULL } + }; ++static struct cpuidle_state tangier_cstates[] = { ++ { ++ .name = "C1-TNG", ++ .desc = "MWAIT 0x00", ++ .flags = MWAIT2flg(0x00), ++ .exit_latency = 1, ++ .target_residency = 4, ++ .enter = &intel_idle, ++ .enter_freeze = intel_idle_freeze, }, ++ { ++ .name = "C4-TNG", ++ .desc = "MWAIT 0x30", ++ .flags = MWAIT2flg(0x30) | CPUIDLE_FLAG_TLB_FLUSHED, ++ .exit_latency = 100, ++ .target_residency = 400, ++ .enter = &intel_idle, ++ .enter_freeze = intel_idle_freeze, }, ++ { ++ .name = "C6-TNG", ++ .desc = "MWAIT 0x52", ++ .flags = MWAIT2flg(0x52) | CPUIDLE_FLAG_TLB_FLUSHED, ++ .exit_latency = 140, ++ .target_residency = 560, ++ .enter = &intel_idle, ++ .enter_freeze = intel_idle_freeze, }, ++ { ++ .name = "C7-TNG", ++ .desc = "MWAIT 0x60", ++ .flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TLB_FLUSHED, ++ .exit_latency = 1200, ++ .target_residency = 4000, ++ .enter = &intel_idle, ++ .enter_freeze = intel_idle_freeze, }, ++ { ++ .name = "C9-TNG", ++ .desc = "MWAIT 0x64", ++ .flags = MWAIT2flg(0x64) | CPUIDLE_FLAG_TLB_FLUSHED, ++ .exit_latency = 10000, ++ .target_residency = 20000, ++ .enter = &intel_idle, ++ .enter_freeze = intel_idle_freeze, }, ++ { ++ .enter = NULL } ++}; + static struct cpuidle_state avn_cstates[] = { + { + .name = "C1-AVN", +@@ -978,6 +1022,10 @@ static const struct idle_cpu idle_cpu_atom = { + .state_table = atom_cstates, + }; + ++static const struct idle_cpu idle_cpu_tangier = { ++ .state_table = tangier_cstates, ++}; ++ + static const struct idle_cpu idle_cpu_lincroft = { + .state_table = atom_cstates, + .auto_demotion_disable_flags = ATM_LNC_C6_AUTO_DEMOTE, +@@ -1066,6 +1114,7 @@ static const struct x86_cpu_id intel_idle_ids[] __initconst = { + ICPU(INTEL_FAM6_SANDYBRIDGE_X, idle_cpu_snb), + ICPU(INTEL_FAM6_ATOM_CEDARVIEW, idle_cpu_atom), + ICPU(INTEL_FAM6_ATOM_SILVERMONT1, idle_cpu_byt), ++ ICPU(INTEL_FAM6_ATOM_MERRIFIELD, idle_cpu_tangier), + ICPU(INTEL_FAM6_ATOM_AIRMONT, idle_cpu_cht), + ICPU(INTEL_FAM6_IVYBRIDGE, idle_cpu_ivb), + ICPU(INTEL_FAM6_IVYBRIDGE_X, idle_cpu_ivt), +-- +2.12.0 + diff --git a/queue/x86-pmem-fix-broken-__copy_user_nocache-cache-bypass.patch b/queue/x86-pmem-fix-broken-__copy_user_nocache-cache-bypass.patch new file mode 100644 index 0000000..28db8fd --- /dev/null +++ b/queue/x86-pmem-fix-broken-__copy_user_nocache-cache-bypass.patch @@ -0,0 +1,106 @@ +From 11e63f6d920d6f2dfd3cd421e939a4aec9a58dcd Mon Sep 17 00:00:00 2001 +From: Dan Williams <dan.j.williams@intel.com> +Date: Thu, 6 Apr 2017 09:04:31 -0700 +Subject: [PATCH] x86, pmem: fix broken __copy_user_nocache cache-bypass + assumptions + +commit 11e63f6d920d6f2dfd3cd421e939a4aec9a58dcd upstream. + +Before we rework the "pmem api" to stop abusing __copy_user_nocache() +for memcpy_to_pmem() we need to fix cases where we may strand dirty data +in the cpu cache. The problem occurs when copy_from_iter_pmem() is used +for arbitrary data transfers from userspace. There is no guarantee that +these transfers, performed by dax_iomap_actor(), will have aligned +destinations or aligned transfer lengths. Backstop the usage +__copy_user_nocache() with explicit cache management in these unaligned +cases. + +Yes, copy_from_iter_pmem() is now too big for an inline, but addressing +that is saved for a later patch that moves the entirety of the "pmem +api" into the pmem driver directly. + +Fixes: 5de490daec8b ("pmem: add copy_from_iter_pmem() and clear_pmem()") +Cc: <stable@vger.kernel.org> +Cc: <x86@kernel.org> +Cc: Jan Kara <jack@suse.cz> +Cc: Jeff Moyer <jmoyer@redhat.com> +Cc: Ingo Molnar <mingo@redhat.com> +Cc: Christoph Hellwig <hch@lst.de> +Cc: "H. Peter Anvin" <hpa@zytor.com> +Cc: Al Viro <viro@zeniv.linux.org.uk> +Cc: Thomas Gleixner <tglx@linutronix.de> +Cc: Matthew Wilcox <mawilcox@microsoft.com> +Reviewed-by: Ross Zwisler <ross.zwisler@linux.intel.com> +Signed-off-by: Toshi Kani <toshi.kani@hpe.com> +Signed-off-by: Dan Williams <dan.j.williams@intel.com> + +diff --git a/arch/x86/include/asm/pmem.h b/arch/x86/include/asm/pmem.h +index 2c1ebeb4d737..529bb4a6487a 100644 +--- a/arch/x86/include/asm/pmem.h ++++ b/arch/x86/include/asm/pmem.h +@@ -55,7 +55,8 @@ static inline int arch_memcpy_from_pmem(void *dst, const void *src, size_t n) + * @size: number of bytes to write back + * + * Write back a cache range using the CLWB (cache line write back) +- * instruction. ++ * instruction. Note that @size is internally rounded up to be cache ++ * line size aligned. + */ + static inline void arch_wb_cache_pmem(void *addr, size_t size) + { +@@ -69,15 +70,6 @@ static inline void arch_wb_cache_pmem(void *addr, size_t size) + clwb(p); + } + +-/* +- * copy_from_iter_nocache() on x86 only uses non-temporal stores for iovec +- * iterators, so for other types (bvec & kvec) we must do a cache write-back. +- */ +-static inline bool __iter_needs_pmem_wb(struct iov_iter *i) +-{ +- return iter_is_iovec(i) == false; +-} +- + /** + * arch_copy_from_iter_pmem - copy data from an iterator to PMEM + * @addr: PMEM destination address +@@ -94,7 +86,35 @@ static inline size_t arch_copy_from_iter_pmem(void *addr, size_t bytes, + /* TODO: skip the write-back by always using non-temporal stores */ + len = copy_from_iter_nocache(addr, bytes, i); + +- if (__iter_needs_pmem_wb(i)) ++ /* ++ * In the iovec case on x86_64 copy_from_iter_nocache() uses ++ * non-temporal stores for the bulk of the transfer, but we need ++ * to manually flush if the transfer is unaligned. A cached ++ * memory copy is used when destination or size is not naturally ++ * aligned. That is: ++ * - Require 8-byte alignment when size is 8 bytes or larger. ++ * - Require 4-byte alignment when size is 4 bytes. ++ * ++ * In the non-iovec case the entire destination needs to be ++ * flushed. ++ */ ++ if (iter_is_iovec(i)) { ++ unsigned long flushed, dest = (unsigned long) addr; ++ ++ if (bytes < 8) { ++ if (!IS_ALIGNED(dest, 4) || (bytes != 4)) ++ arch_wb_cache_pmem(addr, 1); ++ } else { ++ if (!IS_ALIGNED(dest, 8)) { ++ dest = ALIGN(dest, boot_cpu_data.x86_clflush_size); ++ arch_wb_cache_pmem(addr, 1); ++ } ++ ++ flushed = dest - (unsigned long) addr; ++ if (bytes > flushed && !IS_ALIGNED(bytes - flushed, 8)) ++ arch_wb_cache_pmem(addr + bytes - 1, 1); ++ } ++ } else + arch_wb_cache_pmem(addr, bytes); + + return len; +-- +2.12.0 + diff --git a/queue/x86-reboot-quirks-Add-ASUS-EeeBook-X205TA-W-reboot-q.patch b/queue/x86-reboot-quirks-Add-ASUS-EeeBook-X205TA-W-reboot-q.patch new file mode 100644 index 0000000..48dcd39 --- /dev/null +++ b/queue/x86-reboot-quirks-Add-ASUS-EeeBook-X205TA-W-reboot-q.patch @@ -0,0 +1,37 @@ +From 3b3e78552d3077ec70d2640e629e07e3ab416a6a Mon Sep 17 00:00:00 2001 +From: Matjaz Hegedic <matjaz.hegedic@gmail.com> +Date: Sun, 5 Mar 2017 19:16:44 +0100 +Subject: [PATCH] x86/reboot/quirks: Add ASUS EeeBook X205TA/W reboot quirk + +commit 3b3e78552d3077ec70d2640e629e07e3ab416a6a upstream. + +Without the parameter reboot=a, ASUS EeeBook X205TA/W will hang +when it should reboot. This adds the appropriate quirk, thus +fixing the problem. + +Signed-off-by: Matjaz Hegedic <matjaz.hegedic@gmail.com> +Link: http://lkml.kernel.org/r/1488737804-20681-1-git-send-email-matjaz.hegedic@gmail.com +Signed-off-by: Thomas Gleixner <tglx@linutronix.de> + +diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c +index 01c9cda3e1b7..4194d6f9bb29 100644 +--- a/arch/x86/kernel/reboot.c ++++ b/arch/x86/kernel/reboot.c +@@ -231,6 +231,14 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = { + DMI_MATCH(DMI_PRODUCT_NAME, "X205TAW"), + }, + }, ++ { /* Handle problems with rebooting on ASUS EeeBook X205TAW */ ++ .callback = set_acpi_reboot, ++ .ident = "ASUS EeeBook X205TAW", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "X205TAW"), ++ }, ++ }, + + /* Certec */ + { /* Handle problems with rebooting on Certec BPC600 */ +-- +2.12.0 + diff --git a/queue/x86-reboot-quirks-Add-ASUS-EeeBook-X205TA-reboot-qui.patch b/queue/x86-reboot-quirks-Add-ASUS-EeeBook-X205TA-reboot-qui.patch new file mode 100644 index 0000000..9acd235 --- /dev/null +++ b/queue/x86-reboot-quirks-Add-ASUS-EeeBook-X205TA-reboot-qui.patch @@ -0,0 +1,45 @@ +From 90b28ded88dda8bea82b4a86923e73ba0746d884 Mon Sep 17 00:00:00 2001 +From: Matjaz Hegedic <matjaz.hegedic@gmail.com> +Date: Sun, 19 Feb 2017 19:32:48 +0100 +Subject: [PATCH] x86/reboot/quirks: Add ASUS EeeBook X205TA reboot quirk + +commit 90b28ded88dda8bea82b4a86923e73ba0746d884 upstream. + +Without the parameter reboot=a, ASUS EeeBook X205TA will hang when it should reboot. + +This adds the appropriate quirk, thus fixing the problem. + +Signed-off-by: Matjaz Hegedic <matjaz.hegedic@gmail.com> +Cc: Andy Lutomirski <luto@kernel.org> +Cc: Borislav Petkov <bp@alien8.de> +Cc: Brian Gerst <brgerst@gmail.com> +Cc: Denys Vlasenko <dvlasenk@redhat.com> +Cc: H. Peter Anvin <hpa@zytor.com> +Cc: Josh Poimboeuf <jpoimboe@redhat.com> +Cc: Linus Torvalds <torvalds@linux-foundation.org> +Cc: Peter Zijlstra <peterz@infradead.org> +Cc: Thomas Gleixner <tglx@linutronix.de> +Signed-off-by: Ingo Molnar <mingo@kernel.org> + +diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c +index e244c19a2451..01c9cda3e1b7 100644 +--- a/arch/x86/kernel/reboot.c ++++ b/arch/x86/kernel/reboot.c +@@ -223,6 +223,14 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = { + DMI_MATCH(DMI_BOARD_NAME, "P4S800"), + }, + }, ++ { /* Handle problems with rebooting on ASUS EeeBook X205TA */ ++ .callback = set_acpi_reboot, ++ .ident = "ASUS EeeBook X205TA", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "X205TAW"), ++ }, ++ }, + + /* Certec */ + { /* Handle problems with rebooting on Certec BPC600 */ +-- +2.12.0 + diff --git a/queue/x86-reboot-quirks-Fix-typo-in-ASUS-EeeBook-X205TA-re.patch b/queue/x86-reboot-quirks-Fix-typo-in-ASUS-EeeBook-X205TA-re.patch new file mode 100644 index 0000000..9a4dc8b --- /dev/null +++ b/queue/x86-reboot-quirks-Fix-typo-in-ASUS-EeeBook-X205TA-re.patch @@ -0,0 +1,36 @@ +From bba8376aea1dcbbe22bbda118c52abee317c7609 Mon Sep 17 00:00:00 2001 +From: Matjaz Hegedic <matjaz.hegedic@gmail.com> +Date: Thu, 9 Mar 2017 14:00:17 +0100 +Subject: [PATCH] x86/reboot/quirks: Fix typo in ASUS EeeBook X205TA reboot + quirk + +commit bba8376aea1dcbbe22bbda118c52abee317c7609 upstream. + +The reboot quirk for ASUS EeeBook X205TA contains a typo in +DMI_PRODUCT_NAME, improperly referring to X205TAW instead of +X205TA, which prevents the quirk from being triggered. The +model X205TAW already has a reboot quirk of its own. + +This fix simply removes the inappropriate final letter W. + +Fixes: 90b28ded88dd ("x86/reboot/quirks: Add ASUS EeeBook X205TA reboot quirk") +Signed-off-by: Matjaz Hegedic <matjaz.hegedic@gmail.com> +Link: http://lkml.kernel.org/r/1489064417-7445-1-git-send-email-matjaz.hegedic@gmail.com +Signed-off-by: Thomas Gleixner <tglx@linutronix.de> + +diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c +index 4194d6f9bb29..067f9813fd2c 100644 +--- a/arch/x86/kernel/reboot.c ++++ b/arch/x86/kernel/reboot.c +@@ -228,7 +228,7 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = { + .ident = "ASUS EeeBook X205TA", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), +- DMI_MATCH(DMI_PRODUCT_NAME, "X205TAW"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "X205TA"), + }, + }, + { /* Handle problems with rebooting on ASUS EeeBook X205TAW */ +-- +2.12.0 + diff --git a/queue/x86-signals-Fix-lower-upper-bound-reporting-in-compa.patch b/queue/x86-signals-Fix-lower-upper-bound-reporting-in-compa.patch new file mode 100644 index 0000000..c677187 --- /dev/null +++ b/queue/x86-signals-Fix-lower-upper-bound-reporting-in-compa.patch @@ -0,0 +1,49 @@ +From cfac6dfa42bddfa9711b20d486e521d1a41ab09f Mon Sep 17 00:00:00 2001 +From: Joerg Roedel <jroedel@suse.de> +Date: Tue, 4 Apr 2017 18:15:01 +0200 +Subject: [PATCH] x86/signals: Fix lower/upper bound reporting in compat + siginfo + +commit cfac6dfa42bddfa9711b20d486e521d1a41ab09f upstream. + +Put the right values from the original siginfo into the +userspace compat-siginfo. + +This fixes the 32-bit MPX "tabletest" testcase on 64-bit kernels. + +Signed-off-by: Joerg Roedel <jroedel@suse.de> +Acked-by: Dave Hansen <dave.hansen@linux.intel.com> +Cc: <stable@vger.kernel.org> # v4.8+ +Cc: Andy Lutomirski <luto@kernel.org> +Cc: Borislav Petkov <bp@alien8.de> +Cc: Borislav Petkov <bp@suse.de> +Cc: Brian Gerst <brgerst@gmail.com> +Cc: Denys Vlasenko <dvlasenk@redhat.com> +Cc: Dmitry Safonov <0x7f454c46@gmail.com> +Cc: H. Peter Anvin <hpa@zytor.com> +Cc: Josh Poimboeuf <jpoimboe@redhat.com> +Cc: Linus Torvalds <torvalds@linux-foundation.org> +Cc: Peter Zijlstra <peterz@infradead.org> +Cc: Thomas Gleixner <tglx@linutronix.de> +Fixes: a4455082dc6f0 ('x86/signals: Add missing signal_compat code for x86 features') +Link: http://lkml.kernel.org/r/1491322501-5054-1-git-send-email-joro@8bytes.org +Signed-off-by: Ingo Molnar <mingo@kernel.org> + +diff --git a/arch/x86/kernel/signal_compat.c b/arch/x86/kernel/signal_compat.c +index ec1f756f9dc9..71beb28600d4 100644 +--- a/arch/x86/kernel/signal_compat.c ++++ b/arch/x86/kernel/signal_compat.c +@@ -151,8 +151,8 @@ int __copy_siginfo_to_user32(compat_siginfo_t __user *to, const siginfo_t *from, + + if (from->si_signo == SIGSEGV) { + if (from->si_code == SEGV_BNDERR) { +- compat_uptr_t lower = (unsigned long)&to->si_lower; +- compat_uptr_t upper = (unsigned long)&to->si_upper; ++ compat_uptr_t lower = (unsigned long)from->si_lower; ++ compat_uptr_t upper = (unsigned long)from->si_upper; + put_user_ex(lower, &to->si_lower); + put_user_ex(upper, &to->si_upper); + } +-- +2.12.0 + diff --git a/queue/x86-vdso-Ensure-vdso32_enabled-gets-set-to-valid-val.patch b/queue/x86-vdso-Ensure-vdso32_enabled-gets-set-to-valid-val.patch new file mode 100644 index 0000000..c10b4ca --- /dev/null +++ b/queue/x86-vdso-Ensure-vdso32_enabled-gets-set-to-valid-val.patch @@ -0,0 +1,66 @@ +From c06989da39cdb10604d572c8c7ea8c8c97f3c483 Mon Sep 17 00:00:00 2001 +From: Mathias Krause <minipli@googlemail.com> +Date: Mon, 10 Apr 2017 17:14:27 +0200 +Subject: [PATCH] x86/vdso: Ensure vdso32_enabled gets set to valid values only + +commit c06989da39cdb10604d572c8c7ea8c8c97f3c483 upstream. + +vdso_enabled can be set to arbitrary integer values via the kernel command +line 'vdso32=' parameter or via 'sysctl abi.vsyscall32'. + +load_vdso32() only maps VDSO if vdso_enabled == 1, but ARCH_DLINFO_IA32 +merily checks for vdso_enabled != 0. As a consequence the AT_SYSINFO_EHDR +auxiliary vector for the VDSO_ENTRY is emitted with a NULL pointer which +causes a segfault when the application tries to use the VDSO. + +Restrict the valid arguments on the command line and the sysctl to 0 and 1. + +Fixes: b0b49f2673f0 ("x86, vdso: Remove compat vdso support") +Signed-off-by: Mathias Krause <minipli@googlemail.com> +Acked-by: Andy Lutomirski <luto@amacapital.net> +Cc: Peter Zijlstra <peterz@infradead.org> +Cc: stable@vger.kernel.org +Cc: Roland McGrath <roland@redhat.com> +Link: http://lkml.kernel.org/r/1491424561-7187-1-git-send-email-minipli@googlemail.com +Link: http://lkml.kernel.org/r/20170410151723.518412863@linutronix.de +Signed-off-by: Thomas Gleixner <tglx@linutronix.de> + +diff --git a/arch/x86/entry/vdso/vdso32-setup.c b/arch/x86/entry/vdso/vdso32-setup.c +index 7853b53959cd..3f9d1a83891a 100644 +--- a/arch/x86/entry/vdso/vdso32-setup.c ++++ b/arch/x86/entry/vdso/vdso32-setup.c +@@ -30,8 +30,10 @@ static int __init vdso32_setup(char *s) + { + vdso32_enabled = simple_strtoul(s, NULL, 0); + +- if (vdso32_enabled > 1) ++ if (vdso32_enabled > 1) { + pr_warn("vdso32 values other than 0 and 1 are no longer allowed; vdso disabled\n"); ++ vdso32_enabled = 0; ++ } + + return 1; + } +@@ -62,13 +64,18 @@ subsys_initcall(sysenter_setup); + /* Register vsyscall32 into the ABI table */ + #include <linux/sysctl.h> + ++static const int zero; ++static const int one = 1; ++ + static struct ctl_table abi_table2[] = { + { + .procname = "vsyscall32", + .data = &vdso32_enabled, + .maxlen = sizeof(int), + .mode = 0644, +- .proc_handler = proc_dointvec ++ .proc_handler = proc_dointvec_minmax, ++ .extra1 = (int *)&zero, ++ .extra2 = (int *)&one, + }, + {} + }; +-- +2.12.0 + diff --git a/queue/x86-vdso-Plug-race-between-mapping-and-ELF-header-se.patch b/queue/x86-vdso-Plug-race-between-mapping-and-ELF-header-se.patch new file mode 100644 index 0000000..5b9a28b --- /dev/null +++ b/queue/x86-vdso-Plug-race-between-mapping-and-ELF-header-se.patch @@ -0,0 +1,47 @@ +From 6fdc6dd90272ce7e75d744f71535cfbd8d77da81 Mon Sep 17 00:00:00 2001 +From: Thomas Gleixner <tglx@linutronix.de> +Date: Mon, 10 Apr 2017 17:14:28 +0200 +Subject: [PATCH] x86/vdso: Plug race between mapping and ELF header setup + +commit 6fdc6dd90272ce7e75d744f71535cfbd8d77da81 upstream. + +The vsyscall32 sysctl can racy against a concurrent fork when it switches +from disabled to enabled: + + arch_setup_additional_pages() + if (vdso32_enabled) + --> No mapping + sysctl.vsysscall32() + --> vdso32_enabled = true + create_elf_tables() + ARCH_DLINFO_IA32 + if (vdso32_enabled) { + --> Add VDSO entry with NULL pointer + +Make ARCH_DLINFO_IA32 check whether the VDSO mapping has been set up for +the newly forked process or not. + +Signed-off-by: Thomas Gleixner <tglx@linutronix.de> +Acked-by: Andy Lutomirski <luto@amacapital.net> +Cc: Peter Zijlstra <peterz@infradead.org> +Cc: Mathias Krause <minipli@googlemail.com> +Cc: stable@vger.kernel.org +Link: http://lkml.kernel.org/r/20170410151723.602367196@linutronix.de +Signed-off-by: Thomas Gleixner <tglx@linutronix.de> + +diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h +index 9d49c18b5ea9..3762536619f8 100644 +--- a/arch/x86/include/asm/elf.h ++++ b/arch/x86/include/asm/elf.h +@@ -287,7 +287,7 @@ struct task_struct; + + #define ARCH_DLINFO_IA32 \ + do { \ +- if (vdso32_enabled) { \ ++ if (VDSO_CURRENT_BASE) { \ + NEW_AUX_ENT(AT_SYSINFO, VDSO_ENTRY); \ + NEW_AUX_ENT(AT_SYSINFO_EHDR, VDSO_CURRENT_BASE); \ + } \ +-- +2.12.0 + diff --git a/queue/x86-xen-Fix-APIC-id-mismatch-warning-on-Intel.patch b/queue/x86-xen-Fix-APIC-id-mismatch-warning-on-Intel.patch new file mode 100644 index 0000000..aa2052e --- /dev/null +++ b/queue/x86-xen-Fix-APIC-id-mismatch-warning-on-Intel.patch @@ -0,0 +1,58 @@ +From cc272163ea554a97dac180fa8dd6cd54c2810bd1 Mon Sep 17 00:00:00 2001 +From: Mohit Gambhir <mohit.gambhir@oracle.com> +Date: Thu, 26 Jan 2017 13:12:27 -0500 +Subject: [PATCH] x86/xen: Fix APIC id mismatch warning on Intel + +commit cc272163ea554a97dac180fa8dd6cd54c2810bd1 upstream. + +This patch fixes the following warning message seen when booting the +kernel as Dom0 with Xen on Intel machines. + +[0.003000] [Firmware Bug]: CPU1: APIC id mismatch. Firmware: 0 APIC: 1] + +The code generating the warning in validate_apic_and_package_id() matches +cpu_data(cpu).apicid (initialized in init_intel()-> +detect_extended_topology() using cpuid) against the apicid returned from +xen_apic_read(). Now, xen_apic_read() makes a hypercall to retrieve apicid +for the boot cpu but returns 0 otherwise. Hence the warning gets thrown +for all but the boot cpu. + +The idea behind xen_apic_read() returning 0 for apicid is that the +guests (even Dom0) should not need to know what physical processor their +vcpus are running on. This is because we currently do not have topology +information in Xen and also because xen allows more vcpus than physical +processors. However, boot cpu's apicid is required for loading +xen-acpi-processor driver on AMD machines. Look at following patch for +details: + +commit 558daa289a40 ("xen/apic: Return the APIC ID (and version) for CPU +0.") + +So to get rid of the warning, this patch modifies +xen_cpu_present_to_apicid() to return cpu_data(cpu).apicid instead of +calling xen_apic_read(). + +The warning is not seen on AMD machines because init_amd() populates +cpu_data(cpu).apicid by calling hard_smp_processor_id()->xen_apic_read() +as opposed to using apicid from cpuid as is done on Intel machines. + +Signed-off-by: Mohit Gambhir <mohit.gambhir@oracle.com> +Reviewed-by: Juergen Gross <jgross@suse.com> +Signed-off-by: Boris Ostrovsky <boris.ostrovsky@oracle.com> + +diff --git a/arch/x86/xen/apic.c b/arch/x86/xen/apic.c +index 44c88ad1841a..bcea81f36fc5 100644 +--- a/arch/x86/xen/apic.c ++++ b/arch/x86/xen/apic.c +@@ -145,7 +145,7 @@ static void xen_silent_inquire(int apicid) + static int xen_cpu_present_to_apicid(int cpu) + { + if (cpu_present(cpu)) +- return xen_get_apic_id(xen_apic_read(APIC_ID)); ++ return cpu_data(cpu).apicid; + else + return BAD_APICID; + } +-- +2.12.0 + diff --git a/queue/xen-fbfront-fix-connecting-to-backend.patch b/queue/xen-fbfront-fix-connecting-to-backend.patch new file mode 100644 index 0000000..8def7c4 --- /dev/null +++ b/queue/xen-fbfront-fix-connecting-to-backend.patch @@ -0,0 +1,43 @@ +From 9121b15b5628b38b4695282dc18c553440e0f79b Mon Sep 17 00:00:00 2001 +From: Juergen Gross <jgross@suse.com> +Date: Fri, 7 Apr 2017 17:28:23 +0200 +Subject: [PATCH] xen, fbfront: fix connecting to backend + +commit 9121b15b5628b38b4695282dc18c553440e0f79b upstream. + +Connecting to the backend isn't working reliably in xen-fbfront: in +case XenbusStateInitWait of the backend has been missed the backend +transition to XenbusStateConnected will trigger the connected state +only without doing the actions required when the backend has +connected. + +Cc: stable@vger.kernel.org +Signed-off-by: Juergen Gross <jgross@suse.com> +Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com> +Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> + +diff --git a/drivers/video/fbdev/xen-fbfront.c b/drivers/video/fbdev/xen-fbfront.c +index d0115a7af0a9..3ee309c50b2d 100644 +--- a/drivers/video/fbdev/xen-fbfront.c ++++ b/drivers/video/fbdev/xen-fbfront.c +@@ -643,7 +643,6 @@ static void xenfb_backend_changed(struct xenbus_device *dev, + break; + + case XenbusStateInitWait: +-InitWait: + xenbus_switch_state(dev, XenbusStateConnected); + break; + +@@ -654,7 +653,8 @@ InitWait: + * get Connected twice here. + */ + if (dev->state != XenbusStateConnected) +- goto InitWait; /* no InitWait seen yet, fudge it */ ++ /* no InitWait seen yet, fudge it */ ++ xenbus_switch_state(dev, XenbusStateConnected); + + if (xenbus_read_unsigned(info->xbdev->otherend, + "request-update", 0)) +-- +2.12.0 + diff --git a/queue/xfs-Honor-FALLOC_FL_KEEP_SIZE-when-punching-ends-of-.patch b/queue/xfs-Honor-FALLOC_FL_KEEP_SIZE-when-punching-ends-of-.patch new file mode 100644 index 0000000..8e1f6e2 --- /dev/null +++ b/queue/xfs-Honor-FALLOC_FL_KEEP_SIZE-when-punching-ends-of-.patch @@ -0,0 +1,61 @@ +From 3dd09d5a8589c640abb49cfcf92b4ed669eafad1 Mon Sep 17 00:00:00 2001 +From: Calvin Owens <calvinowens@fb.com> +Date: Mon, 3 Apr 2017 12:22:29 -0700 +Subject: [PATCH] xfs: Honor FALLOC_FL_KEEP_SIZE when punching ends of files + +commit 3dd09d5a8589c640abb49cfcf92b4ed669eafad1 upstream. + +When punching past EOF on XFS, fallocate(mode=PUNCH_HOLE|KEEP_SIZE) will +round the file size up to the nearest multiple of PAGE_SIZE: + + calvinow@vm-disks/generic-xfs-1 ~$ dd if=/dev/urandom of=test bs=2048 count=1 + calvinow@vm-disks/generic-xfs-1 ~$ stat test + Size: 2048 Blocks: 8 IO Block: 4096 regular file + calvinow@vm-disks/generic-xfs-1 ~$ fallocate -n -l 2048 -o 2048 -p test + calvinow@vm-disks/generic-xfs-1 ~$ stat test + Size: 4096 Blocks: 8 IO Block: 4096 regular file + +Commit 3c2bdc912a1cc050 ("xfs: kill xfs_zero_remaining_bytes") replaced +xfs_zero_remaining_bytes() with calls to iomap helpers. The new helpers +don't enforce that [pos,offset) lies strictly on [0,i_size) when being +called from xfs_free_file_space(), so by "leaking" these ranges into +xfs_zero_range() we get this buggy behavior. + +Fix this by reintroducing the checks xfs_zero_remaining_bytes() did +against i_size at the bottom of xfs_free_file_space(). + +Reported-by: Aaron Gao <gzh@fb.com> +Fixes: 3c2bdc912a1cc050 ("xfs: kill xfs_zero_remaining_bytes") +Cc: Christoph Hellwig <hch@lst.de> +Cc: Brian Foster <bfoster@redhat.com> +Cc: <stable@vger.kernel.org> # 4.8+ +Signed-off-by: Calvin Owens <calvinowens@fb.com> +Reviewed-by: Christoph Hellwig <hch@lst.de> +Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com> +Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> + +diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c +index 8b75dcea5966..828532ce0adc 100644 +--- a/fs/xfs/xfs_bmap_util.c ++++ b/fs/xfs/xfs_bmap_util.c +@@ -1311,8 +1311,16 @@ xfs_free_file_space( + /* + * Now that we've unmap all full blocks we'll have to zero out any + * partial block at the beginning and/or end. xfs_zero_range is +- * smart enough to skip any holes, including those we just created. ++ * smart enough to skip any holes, including those we just created, ++ * but we must take care not to zero beyond EOF and enlarge i_size. + */ ++ ++ if (offset >= XFS_ISIZE(ip)) ++ return 0; ++ ++ if (offset + len > XFS_ISIZE(ip)) ++ len = XFS_ISIZE(ip) - offset; ++ + return xfs_zero_range(ip, offset, len, NULL); + } + +-- +2.12.0 + diff --git a/queue/xtensa-make-__pa-work-with-uncached-KSEG-addresses.patch b/queue/xtensa-make-__pa-work-with-uncached-KSEG-addresses.patch new file mode 100644 index 0000000..b1e870b --- /dev/null +++ b/queue/xtensa-make-__pa-work-with-uncached-KSEG-addresses.patch @@ -0,0 +1,53 @@ +From 2b83878dd74a7c73bedcb6600663c1c46836e8af Mon Sep 17 00:00:00 2001 +From: Max Filippov <jcmvbkbc@gmail.com> +Date: Wed, 29 Mar 2017 15:44:47 -0700 +Subject: [PATCH] xtensa: make __pa work with uncached KSEG addresses + +commit 2b83878dd74a7c73bedcb6600663c1c46836e8af upstream. + +When __pa is applied to virtual address in uncached KSEG region the +result is incorrect. Fix it by checking if the original address is in +the uncached KSEG and adjusting the result. It looks better than masking +off bits because pfn_valid would correctly work with new __pa results +and it may be made working in noMMU case, once we get definition for +uncached memory view. + +This is required for the dma_common_mmap and DMA debug code to work +correctly: they both indirectly use __pa with coherent DMA addresses. +In case of DMA debug the visible effect is false reports that an address +mapped for DMA is accessed by CPU. + +Cc: stable@vger.kernel.org +Tested-by: Boris Brezillon <boris.brezillon@free-electrons.com> +Reviewed-by: Boris Brezillon <boris.brezillon@free-electrons.com> +Signed-off-by: Max Filippov <jcmvbkbc@gmail.com> + +diff --git a/arch/xtensa/include/asm/page.h b/arch/xtensa/include/asm/page.h +index 976b1d70edbc..4ddbfd57a7c8 100644 +--- a/arch/xtensa/include/asm/page.h ++++ b/arch/xtensa/include/asm/page.h +@@ -164,8 +164,21 @@ void copy_user_highpage(struct page *to, struct page *from, + + #define ARCH_PFN_OFFSET (PHYS_OFFSET >> PAGE_SHIFT) + ++#ifdef CONFIG_MMU ++static inline unsigned long ___pa(unsigned long va) ++{ ++ unsigned long off = va - PAGE_OFFSET; ++ ++ if (off >= XCHAL_KSEG_SIZE) ++ off -= XCHAL_KSEG_SIZE; ++ ++ return off + PHYS_OFFSET; ++} ++#define __pa(x) ___pa((unsigned long)(x)) ++#else + #define __pa(x) \ + ((unsigned long) (x) - PAGE_OFFSET + PHYS_OFFSET) ++#endif + #define __va(x) \ + ((void *)((unsigned long) (x) - PHYS_OFFSET + PAGE_OFFSET)) + #define pfn_valid(pfn) \ +-- +2.12.0 + diff --git a/queue/zram-do-not-use-copy_page-with-non-page-aligned-addr.patch b/queue/zram-do-not-use-copy_page-with-non-page-aligned-addr.patch new file mode 100644 index 0000000..3addba4 --- /dev/null +++ b/queue/zram-do-not-use-copy_page-with-non-page-aligned-addr.patch @@ -0,0 +1,66 @@ +From d72e9a7a93e4f8e9e52491921d99e0c8aa89eb4e Mon Sep 17 00:00:00 2001 +From: Minchan Kim <minchan@kernel.org> +Date: Thu, 13 Apr 2017 14:56:37 -0700 +Subject: [PATCH] zram: do not use copy_page with non-page aligned address + +commit d72e9a7a93e4f8e9e52491921d99e0c8aa89eb4e upstream. + +The copy_page is optimized memcpy for page-alinged address. If it is +used with non-page aligned address, it can corrupt memory which means +system corruption. With zram, it can happen with + +1. 64K architecture +2. partial IO +3. slub debug + +Partial IO need to allocate a page and zram allocates it via kmalloc. +With slub debug, kmalloc(PAGE_SIZE) doesn't return page-size aligned +address. And finally, copy_page(mem, cmem) corrupts memory. + +So, this patch changes it to memcpy. + +Actuaully, we don't need to change zram_bvec_write part because zsmalloc +returns page-aligned address in case of PAGE_SIZE class but it's not +good to rely on the internal of zsmalloc. + +Note: + When this patch is merged to stable, clear_page should be fixed, too. + Unfortunately, recent zram removes it by "same page merge" feature so + it's hard to backport this patch to -stable tree. + +I will handle it when I receive the mail from stable tree maintainer to +merge this patch to backport. + +Fixes: 42e99bd ("zram: optimize memory operations with clear_page()/copy_page()") +Link: http://lkml.kernel.org/r/1492042622-12074-2-git-send-email-minchan@kernel.org +Signed-off-by: Minchan Kim <minchan@kernel.org> +Cc: Sergey Senozhatsky <sergey.senozhatsky@gmail.com> +Cc: <stable@vger.kernel.org> +Signed-off-by: Andrew Morton <akpm@linux-foundation.org> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> + +diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c +index 03a7408e090d..0c09d4256108 100644 +--- a/drivers/block/zram/zram_drv.c ++++ b/drivers/block/zram/zram_drv.c +@@ -523,7 +523,7 @@ static int zram_decompress_page(struct zram *zram, char *mem, u32 index) + + cmem = zs_map_object(meta->mem_pool, handle, ZS_MM_RO); + if (size == PAGE_SIZE) { +- copy_page(mem, cmem); ++ memcpy(mem, cmem, PAGE_SIZE); + } else { + struct zcomp_strm *zstrm = zcomp_stream_get(zram->comp); + +@@ -717,7 +717,7 @@ compress_again: + + if ((clen == PAGE_SIZE) && !is_partial_io(bvec)) { + src = kmap_atomic(page); +- copy_page(cmem, src); ++ memcpy(cmem, src, PAGE_SIZE); + kunmap_atomic(src); + } else { + memcpy(cmem, src, clen); +-- +2.12.0 + diff --git a/queue/zsmalloc-expand-class-bit.patch b/queue/zsmalloc-expand-class-bit.patch new file mode 100644 index 0000000..382e271 --- /dev/null +++ b/queue/zsmalloc-expand-class-bit.patch @@ -0,0 +1,45 @@ +From 85d492f28d056c40629fc25d79f54da618a29dc4 Mon Sep 17 00:00:00 2001 +From: Minchan Kim <minchan@kernel.org> +Date: Thu, 13 Apr 2017 14:56:40 -0700 +Subject: [PATCH] zsmalloc: expand class bit + +commit 85d492f28d056c40629fc25d79f54da618a29dc4 upstream. + +Now 64K page system, zsamlloc has 257 classes so 8 class bit is not +enough. With that, it corrupts the system when zsmalloc stores +65536byte data(ie, index number 256) so that this patch increases class +bit for simple fix for stable backport. We should clean up this mess +soon. + + index size + 0 32 + 1 288 + .. + .. + 204 52256 + 256 65536 + +Fixes: 3783689a1 ("zsmalloc: introduce zspage structure") +Link: http://lkml.kernel.org/r/1492042622-12074-3-git-send-email-minchan@kernel.org +Signed-off-by: Minchan Kim <minchan@kernel.org> +Cc: Sergey Senozhatsky <sergey.senozhatsky@gmail.com> +Cc: <stable@vger.kernel.org> +Signed-off-by: Andrew Morton <akpm@linux-foundation.org> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> + +diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c +index b7ee9c34dbd6..d41edd28298b 100644 +--- a/mm/zsmalloc.c ++++ b/mm/zsmalloc.c +@@ -276,7 +276,7 @@ struct zs_pool { + struct zspage { + struct { + unsigned int fullness:FULLNESS_BITS; +- unsigned int class:CLASS_BITS; ++ unsigned int class:CLASS_BITS + 1; + unsigned int isolated:ISOLATED_BITS; + unsigned int magic:MAGIC_VAL_BITS; + }; +-- +2.12.0 + |