From: Greg Kroah-Hartman Date: Wed, 19 Apr 2017 12:49:43 +0000 (+0200) Subject: 4.10-stable patches X-Git-Tag: v4.4.63~12 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=7ced62b1ea4951ad81a69dea22e99b496ee6b9c5;p=thirdparty%2Fkernel%2Fstable-queue.git 4.10-stable patches added patches: acpi-ec-use-busy-polling-mode-when-gpe-is-not-enabled.patch asoc-intel-select-dw_dmac_core-since-it-s-mandatory.patch crypto-ahash-fix-einprogress-notification-callback.patch crypto-algif_aead-fix-bogus-request-dereference-in-completion-function.patch crypto-lrw-fix-use-after-free-on-einprogress.patch crypto-xts-fix-use-after-free-on-einprogress.patch cxusb-use-a-dma-capable-buffer-also-for-reading.patch dvb-usb-v2-avoid-use-after-free.patch ftrace-fix-function-pid-filter-on-instances.patch mm-tighten-x86-dev-mem-with-zeroing-reads.patch parisc-fix-get_user-for-64-bit-value-on-32-bit-kernel.patch platform-x86-acer-wmi-setup-accelerometer-when-machine-has-appropriate-notify-event.patch rtc-tegra-implement-clock-handling.patch virtio-console-avoid-dma-from-stack.patch x86-xen-fix-apic-id-mismatch-warning-on-intel.patch --- diff --git a/queue-4.10/acpi-ec-use-busy-polling-mode-when-gpe-is-not-enabled.patch b/queue-4.10/acpi-ec-use-busy-polling-mode-when-gpe-is-not-enabled.patch new file mode 100644 index 00000000000..1370cc923db --- /dev/null +++ b/queue-4.10/acpi-ec-use-busy-polling-mode-when-gpe-is-not-enabled.patch @@ -0,0 +1,165 @@ +From c3a696b6e8f8f75f9f75e556a9f9f6472eae2655 Mon Sep 17 00:00:00 2001 +From: Lv Zheng +Date: Fri, 20 Jan 2017 16:42:48 +0800 +Subject: ACPI / EC: Use busy polling mode when GPE is not enabled + +From: Lv Zheng + +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 +Tested-by: Chen Yu +Signed-off-by: Lv Zheng +Signed-off-by: Rafael J. Wysocki +Cc: Ben Hutchings +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/acpi/ec.c | 62 +++++++++++++++++++++++------------------------- + drivers/acpi/internal.h | 4 +-- + 2 files changed, 32 insertions(+), 34 deletions(-) + +--- a/drivers/acpi/ec.c ++++ b/drivers/acpi/ec.c +@@ -729,12 +729,12 @@ static void start_transaction(struct acp + + 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; +@@ -998,6 +998,28 @@ static void acpi_ec_stop(struct acpi_ec + 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; +@@ -1278,7 +1300,7 @@ acpi_ec_space_handler(u32 function, acpi + 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) +@@ -1286,7 +1308,7 @@ acpi_ec_space_handler(u32 function, acpi + 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) { +@@ -1329,6 +1351,8 @@ static struct acpi_ec *acpi_ec_alloc(voi + 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; + } + +@@ -1390,6 +1414,7 @@ static int ec_install_handlers(struct ac + 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, +@@ -1429,6 +1454,7 @@ static int ec_install_handlers(struct ac + /* 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); +@@ -1839,34 +1865,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 = +--- 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; diff --git a/queue-4.10/asoc-intel-select-dw_dmac_core-since-it-s-mandatory.patch b/queue-4.10/asoc-intel-select-dw_dmac_core-since-it-s-mandatory.patch new file mode 100644 index 00000000000..90e799e85cc --- /dev/null +++ b/queue-4.10/asoc-intel-select-dw_dmac_core-since-it-s-mandatory.patch @@ -0,0 +1,113 @@ +From ebf79091bf85d9b2270ab29191de9cd3aaf888c5 Mon Sep 17 00:00:00 2001 +From: Andy Shevchenko +Date: Mon, 16 Jan 2017 15:12:26 +0200 +Subject: ASoC: Intel: select DW_DMAC_CORE since it's mandatory + +From: Andy Shevchenko + +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 +Acked-by: Liam Girdwood +Signed-off-by: Mark Brown +Cc: Ben Hutchings +Signed-off-by: Greg Kroah-Hartman + +--- + sound/soc/intel/Kconfig | 31 +++++++++++++------------------ + 1 file changed, 13 insertions(+), 18 deletions(-) + +--- 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 +@@ -99,9 +99,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 +@@ -112,9 +111,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 +@@ -123,9 +121,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 +@@ -134,10 +131,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 diff --git a/queue-4.10/crypto-ahash-fix-einprogress-notification-callback.patch b/queue-4.10/crypto-ahash-fix-einprogress-notification-callback.patch new file mode 100644 index 00000000000..b0c0234732f --- /dev/null +++ b/queue-4.10/crypto-ahash-fix-einprogress-notification-callback.patch @@ -0,0 +1,230 @@ +From ef0579b64e93188710d48667cb5e014926af9f1b Mon Sep 17 00:00:00 2001 +From: Herbert Xu +Date: Mon, 10 Apr 2017 17:27:57 +0800 +Subject: crypto: ahash - Fix EINPROGRESS notification callback + +From: Herbert Xu + +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...") +Reported-by: Sabrina Dubroca +Tested-by: Sabrina Dubroca +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman + +--- + crypto/ahash.c | 79 +++++++++++++++++++++++++---------------- + include/crypto/internal/hash.h | 10 +++++ + 2 files changed, 60 insertions(+), 29 deletions(-) + +--- a/crypto/ahash.c ++++ b/crypto/ahash.c +@@ -31,6 +31,7 @@ struct ahash_request_priv { + crypto_completion_t complete; + void *data; + u8 *result; ++ u32 flags; + void *ubuf[] CRYPTO_MINALIGN_ATTR; + }; + +@@ -252,6 +253,8 @@ static int ahash_save_req(struct ahash_r + 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 +@@ -266,38 +269,44 @@ static int ahash_save_req(struct ahash_r + 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. +@@ -308,7 +317,7 @@ static void ahash_op_unaligned_done(stru + */ + + /* 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); +@@ -324,7 +333,12 @@ static int ahash_op_unaligned(struct aha + 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; + } +@@ -359,25 +373,14 @@ int crypto_ahash_digest(struct ahash_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); + } +@@ -388,11 +391,15 @@ static int ahash_def_finup_finish1(struc + 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; + } + +@@ -400,7 +407,16 @@ static void ahash_def_finup_done1(struct + { + 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); + } +@@ -415,6 +431,11 @@ static int ahash_def_finup(struct ahash_ + 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); + } + +--- a/include/crypto/internal/hash.h ++++ b/include/crypto/internal/hash.h +@@ -166,6 +166,16 @@ static inline struct ahash_instance *aha + 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) + { diff --git a/queue-4.10/crypto-algif_aead-fix-bogus-request-dereference-in-completion-function.patch b/queue-4.10/crypto-algif_aead-fix-bogus-request-dereference-in-completion-function.patch new file mode 100644 index 00000000000..3f145d35671 --- /dev/null +++ b/queue-4.10/crypto-algif_aead-fix-bogus-request-dereference-in-completion-function.patch @@ -0,0 +1,66 @@ +From e6534aebb26e32fbab14df9c713c65e8507d17e4 Mon Sep 17 00:00:00 2001 +From: Herbert Xu +Date: Mon, 10 Apr 2017 17:59:07 +0800 +Subject: crypto: algif_aead - Fix bogus request dereference in completion function + +From: Herbert Xu + +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...") +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman + +--- + crypto/algif_aead.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +--- a/crypto/algif_aead.c ++++ b/crypto/algif_aead.c +@@ -39,6 +39,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[]; + }; +@@ -378,12 +379,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; +@@ -446,11 +445,12 @@ static int aead_recvmsg_async(struct soc + 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 */ diff --git a/queue-4.10/crypto-lrw-fix-use-after-free-on-einprogress.patch b/queue-4.10/crypto-lrw-fix-use-after-free-on-einprogress.patch new file mode 100644 index 00000000000..7b0b934168d --- /dev/null +++ b/queue-4.10/crypto-lrw-fix-use-after-free-on-einprogress.patch @@ -0,0 +1,67 @@ +From 4702bbeefb490e315189636a5588628c1151223d Mon Sep 17 00:00:00 2001 +From: Herbert Xu +Date: Mon, 10 Apr 2017 17:15:48 +0800 +Subject: crypto: lrw - Fix use-after-free on EINPROGRESS + +From: Herbert Xu + +commit 4702bbeefb490e315189636a5588628c1151223d upstream. + +When we get an EINPROGRESS completion in lrw, we will end up marking +the request as done and freeing it. This then blows up when the +request is really completed as we've already freed the memory. + +Fixes: 700cb3f5fe75 ("crypto: lrw - Convert to skcipher") +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman + +--- + crypto/lrw.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +--- a/crypto/lrw.c ++++ b/crypto/lrw.c +@@ -345,6 +345,13 @@ static void encrypt_done(struct crypto_a + struct rctx *rctx; + + rctx = skcipher_request_ctx(req); ++ ++ if (err == -EINPROGRESS) { ++ if (rctx->left != req->cryptlen) ++ return; ++ goto out; ++ } ++ + subreq = &rctx->subreq; + subreq->base.flags &= CRYPTO_TFM_REQ_MAY_BACKLOG; + +@@ -352,6 +359,7 @@ static void encrypt_done(struct crypto_a + if (rctx->left) + return; + ++out: + skcipher_request_complete(req, err); + } + +@@ -389,6 +397,13 @@ static void decrypt_done(struct crypto_a + struct rctx *rctx; + + rctx = skcipher_request_ctx(req); ++ ++ if (err == -EINPROGRESS) { ++ if (rctx->left != req->cryptlen) ++ return; ++ goto out; ++ } ++ + subreq = &rctx->subreq; + subreq->base.flags &= CRYPTO_TFM_REQ_MAY_BACKLOG; + +@@ -396,6 +411,7 @@ static void decrypt_done(struct crypto_a + if (rctx->left) + return; + ++out: + skcipher_request_complete(req, err); + } + diff --git a/queue-4.10/crypto-xts-fix-use-after-free-on-einprogress.patch b/queue-4.10/crypto-xts-fix-use-after-free-on-einprogress.patch new file mode 100644 index 00000000000..bf9878dd2d3 --- /dev/null +++ b/queue-4.10/crypto-xts-fix-use-after-free-on-einprogress.patch @@ -0,0 +1,70 @@ +From aa4a829bdaced81e70c215a84ef6595ce8bd4308 Mon Sep 17 00:00:00 2001 +From: Herbert Xu +Date: Sat, 8 Apr 2017 10:02:46 +0800 +Subject: crypto: xts - Fix use-after-free on EINPROGRESS + +From: Herbert Xu + +commit aa4a829bdaced81e70c215a84ef6595ce8bd4308 upstream. + +When we get an EINPROGRESS completion in xts, we will end up marking +the request as done and freeing it. This then blows up when the +request is really completed as we've already freed the memory. + +Fixes: f1c131b45410 ("crypto: xts - Convert to skcipher") +Reported-by: Nathan Royce +Reported-by: Krzysztof Kozlowski +Signed-off-by: Herbert Xu +Tested-by: Krzysztof Kozlowski +Signed-off-by: Greg Kroah-Hartman + +--- + crypto/xts.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +--- a/crypto/xts.c ++++ b/crypto/xts.c +@@ -286,6 +286,13 @@ static void encrypt_done(struct crypto_a + struct rctx *rctx; + + rctx = skcipher_request_ctx(req); ++ ++ if (err == -EINPROGRESS) { ++ if (rctx->left != req->cryptlen) ++ return; ++ goto out; ++ } ++ + subreq = &rctx->subreq; + subreq->base.flags &= CRYPTO_TFM_REQ_MAY_BACKLOG; + +@@ -293,6 +300,7 @@ static void encrypt_done(struct crypto_a + if (rctx->left) + return; + ++out: + skcipher_request_complete(req, err); + } + +@@ -330,6 +338,13 @@ static void decrypt_done(struct crypto_a + struct rctx *rctx; + + rctx = skcipher_request_ctx(req); ++ ++ if (err == -EINPROGRESS) { ++ if (rctx->left != req->cryptlen) ++ return; ++ goto out; ++ } ++ + subreq = &rctx->subreq; + subreq->base.flags &= CRYPTO_TFM_REQ_MAY_BACKLOG; + +@@ -337,6 +352,7 @@ static void decrypt_done(struct crypto_a + if (rctx->left) + return; + ++out: + skcipher_request_complete(req, err); + } + diff --git a/queue-4.10/cxusb-use-a-dma-capable-buffer-also-for-reading.patch b/queue-4.10/cxusb-use-a-dma-capable-buffer-also-for-reading.patch new file mode 100644 index 00000000000..601028b6b85 --- /dev/null +++ b/queue-4.10/cxusb-use-a-dma-capable-buffer-also-for-reading.patch @@ -0,0 +1,64 @@ +From 3f190e3aec212fc8c61e202c51400afa7384d4bc Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20Br=C3=BCns?= +Date: Sun, 5 Feb 2017 12:57:59 -0200 +Subject: [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 + +From: Stefan Brüns + +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 +Signed-off-by: Mauro Carvalho Chehab +Cc: Ben Hutchings +Cc: Brad Spengler +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/media/usb/dvb-usb/cxusb.c | 15 ++++++++------- + 1 file changed, 8 insertions(+), 7 deletions(-) + +--- 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 + 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; diff --git a/queue-4.10/dvb-usb-v2-avoid-use-after-free.patch b/queue-4.10/dvb-usb-v2-avoid-use-after-free.patch new file mode 100644 index 00000000000..d600bce7ad9 --- /dev/null +++ b/queue-4.10/dvb-usb-v2-avoid-use-after-free.patch @@ -0,0 +1,59 @@ +From 005145378c9ad7575a01b6ce1ba118fb427f583a Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Thu, 2 Feb 2017 12:36:01 -0200 +Subject: [media] dvb-usb-v2: avoid use-after-free + +From: Arnd Bergmann + +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 +Signed-off-by: Mauro Carvalho Chehab +Cc: Ben Hutchings +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/media/usb/dvb-usb-v2/dvb_usb_core.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +--- a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c ++++ b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c +@@ -1013,8 +1013,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); +@@ -1024,8 +1024,9 @@ void dvb_usbv2_disconnect(struct usb_int + + 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); + diff --git a/queue-4.10/ftrace-fix-function-pid-filter-on-instances.patch b/queue-4.10/ftrace-fix-function-pid-filter-on-instances.patch new file mode 100644 index 00000000000..3c74a40bb6d --- /dev/null +++ b/queue-4.10/ftrace-fix-function-pid-filter-on-instances.patch @@ -0,0 +1,103 @@ +From d879d0b8c183aabeb9a65eba91f3f9e3c7e7b905 Mon Sep 17 00:00:00 2001 +From: Namhyung Kim +Date: Mon, 17 Apr 2017 11:44:27 +0900 +Subject: ftrace: Fix function pid filter on instances + +From: Namhyung Kim + +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 +Reviewed-by: Masami Hiramatsu +Signed-off-by: Namhyung Kim +Signed-off-by: Steven Rostedt (VMware) +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/trace/ftrace.c | 9 +++++++++ + kernel/trace/trace.c | 1 + + kernel/trace/trace.h | 2 ++ + 3 files changed, 12 insertions(+) + +--- a/kernel/trace/ftrace.c ++++ b/kernel/trace/ftrace.c +@@ -5422,6 +5422,15 @@ static void clear_ftrace_pids(struct tra + 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); +--- a/kernel/trace/trace.c ++++ b/kernel/trace/trace.c +@@ -7409,6 +7409,7 @@ static int instance_rmdir(const char *na + + 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); +--- a/kernel/trace/trace.h ++++ b/kernel/trace/trace.h +@@ -884,6 +884,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) + { +@@ -902,6 +903,7 @@ ftrace_init_global_array_ops(struct trac + 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 */ diff --git a/queue-4.10/mm-tighten-x86-dev-mem-with-zeroing-reads.patch b/queue-4.10/mm-tighten-x86-dev-mem-with-zeroing-reads.patch new file mode 100644 index 00000000000..59d141348fa --- /dev/null +++ b/queue-4.10/mm-tighten-x86-dev-mem-with-zeroing-reads.patch @@ -0,0 +1,210 @@ +From a4866aa812518ed1a37d8ea0c881dc946409de94 Mon Sep 17 00:00:00 2001 +From: Kees Cook +Date: Wed, 5 Apr 2017 09:39:08 -0700 +Subject: mm: Tighten x86 /dev/mem with zeroing reads + +From: Kees Cook + +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 +Tested-by: Tommi Rantala +Signed-off-by: Kees Cook +Cc: Brad Spengler +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/mm/init.c | 41 +++++++++++++++++++------- + drivers/char/mem.c | 82 +++++++++++++++++++++++++++++++++-------------------- + 2 files changed, 82 insertions(+), 41 deletions(-) + +--- 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) +--- a/drivers/char/mem.c ++++ b/drivers/char/mem.c +@@ -60,6 +60,10 @@ static inline int valid_mmap_phys_addr_r + #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(unsig + 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 *fil + + 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 *fi + #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; diff --git a/queue-4.10/parisc-fix-get_user-for-64-bit-value-on-32-bit-kernel.patch b/queue-4.10/parisc-fix-get_user-for-64-bit-value-on-32-bit-kernel.patch new file mode 100644 index 00000000000..3130467a2fe --- /dev/null +++ b/queue-4.10/parisc-fix-get_user-for-64-bit-value-on-32-bit-kernel.patch @@ -0,0 +1,153 @@ +From 3f795cef0ecdf9bc980dd058d49bdab4b19af1d3 Mon Sep 17 00:00:00 2001 +From: Helge Deller +Date: Sun, 16 Apr 2017 10:00:14 +0200 +Subject: parisc: Fix get_user() for 64-bit value on 32-bit kernel + +From: Helge Deller + +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. + +Signed-off-by: Helge Deller +Signed-off-by: Greg Kroah-Hartman + +--- + arch/parisc/include/asm/uaccess.h | 86 ++++++++++++++++++++++++-------------- + 1 file changed, 55 insertions(+), 31 deletions(-) + +--- a/arch/parisc/include/asm/uaccess.h ++++ b/arch/parisc/include/asm/uaccess.h +@@ -42,10 +42,10 @@ static inline long access_ok(int type, c + #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 + +@@ -100,63 +100,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 diff --git a/queue-4.10/platform-x86-acer-wmi-setup-accelerometer-when-machine-has-appropriate-notify-event.patch b/queue-4.10/platform-x86-acer-wmi-setup-accelerometer-when-machine-has-appropriate-notify-event.patch new file mode 100644 index 00000000000..7e971316004 --- /dev/null +++ b/queue-4.10/platform-x86-acer-wmi-setup-accelerometer-when-machine-has-appropriate-notify-event.patch @@ -0,0 +1,84 @@ +From 98d610c3739ac354319a6590b915f4624d9151e6 Mon Sep 17 00:00:00 2001 +From: "Lee, Chun-Yi" +Date: Thu, 3 Nov 2016 08:18:52 +0800 +Subject: 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 + +From: Lee, Chun-Yi + +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 +Cc: Darren Hart +Signed-off-by: Lee, Chun-Yi +[andy: slightly massage commit message] +Signed-off-by: Andy Shevchenko +Cc: Ben Hutchings +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/platform/x86/acer-wmi.c | 22 ++++++++++++++++++---- + 1 file changed, 18 insertions(+), 4 deletions(-) + +--- 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(voi + 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(v + { + 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"); diff --git a/queue-4.10/rtc-tegra-implement-clock-handling.patch b/queue-4.10/rtc-tegra-implement-clock-handling.patch new file mode 100644 index 00000000000..7d7605599f4 --- /dev/null +++ b/queue-4.10/rtc-tegra-implement-clock-handling.patch @@ -0,0 +1,125 @@ +From 5fa4086987506b2ab8c92f8f99f2295db9918856 Mon Sep 17 00:00:00 2001 +From: Thierry Reding +Date: Thu, 12 Jan 2017 17:07:43 +0100 +Subject: rtc: tegra: Implement clock handling + +From: Thierry Reding + +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 +Acked-By Peter De Schrijver +Signed-off-by: Thierry Reding +Signed-off-by: Alexandre Belloni +[bwh: Backported to 4.9: adjust context] +Signed-off-by: Ben Hutchings +Signed-off-by: Greg Kroah-Hartman +--- + drivers/rtc/rtc-tegra.c | 28 ++++++++++++++++++++++++++-- + 1 file changed, 26 insertions(+), 2 deletions(-) + +--- 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 ++#include + #include + #include + #include +@@ -59,6 +60,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; + }; +@@ -326,6 +328,14 @@ static int __init tegra_rtc_probe(struct + 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); +@@ -346,7 +356,7 @@ static int __init tegra_rtc_probe(struct + 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, +@@ -356,12 +366,25 @@ static int __init tegra_rtc_probe(struct + 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 +@@ -413,6 +436,7 @@ static void tegra_rtc_shutdown(struct pl + + MODULE_ALIAS("platform:tegra_rtc"); + static struct platform_driver tegra_rtc_driver = { ++ .remove = tegra_rtc_remove, + .shutdown = tegra_rtc_shutdown, + .driver = { + .name = "tegra_rtc", diff --git a/queue-4.10/series b/queue-4.10/series index e63ef201ab4..8837bda3b88 100644 --- a/queue-4.10/series +++ b/queue-4.10/series @@ -52,3 +52,18 @@ drm-i915-gvt-set-the-correct-default-value-of-ctx-status-ptr.patch char-lack-of-bool-string-made-config_devport-always-on.patch revert-mips-lantiq-fix-cascaded-irq-setup.patch zram-do-not-use-copy_page-with-non-page-aligned-address.patch +ftrace-fix-function-pid-filter-on-instances.patch +crypto-algif_aead-fix-bogus-request-dereference-in-completion-function.patch +crypto-xts-fix-use-after-free-on-einprogress.patch +crypto-ahash-fix-einprogress-notification-callback.patch +crypto-lrw-fix-use-after-free-on-einprogress.patch +parisc-fix-get_user-for-64-bit-value-on-32-bit-kernel.patch +dvb-usb-v2-avoid-use-after-free.patch +asoc-intel-select-dw_dmac_core-since-it-s-mandatory.patch +platform-x86-acer-wmi-setup-accelerometer-when-machine-has-appropriate-notify-event.patch +x86-xen-fix-apic-id-mismatch-warning-on-intel.patch +acpi-ec-use-busy-polling-mode-when-gpe-is-not-enabled.patch +rtc-tegra-implement-clock-handling.patch +mm-tighten-x86-dev-mem-with-zeroing-reads.patch +cxusb-use-a-dma-capable-buffer-also-for-reading.patch +virtio-console-avoid-dma-from-stack.patch diff --git a/queue-4.10/virtio-console-avoid-dma-from-stack.patch b/queue-4.10/virtio-console-avoid-dma-from-stack.patch new file mode 100644 index 00000000000..9e1cda8fcca --- /dev/null +++ b/queue-4.10/virtio-console-avoid-dma-from-stack.patch @@ -0,0 +1,52 @@ +From c4baad50297d84bde1a7ad45e50c73adae4a2192 Mon Sep 17 00:00:00 2001 +From: Omar Sandoval +Date: Wed, 1 Feb 2017 00:02:27 -0800 +Subject: virtio-console: avoid DMA from stack + +From: Omar Sandoval + +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 +Signed-off-by: Michael S. Tsirkin +Reviewed-by: Amit Shah +Cc: Ben Hutchings +Cc: Brad Spengler +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/char/virtio_console.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +--- a/drivers/char/virtio_console.c ++++ b/drivers/char/virtio_console.c +@@ -1136,6 +1136,8 @@ static int put_chars(u32 vtermno, const + { + 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 + 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; + } + + /* diff --git a/queue-4.10/x86-xen-fix-apic-id-mismatch-warning-on-intel.patch b/queue-4.10/x86-xen-fix-apic-id-mismatch-warning-on-intel.patch new file mode 100644 index 00000000000..3882e156691 --- /dev/null +++ b/queue-4.10/x86-xen-fix-apic-id-mismatch-warning-on-intel.patch @@ -0,0 +1,61 @@ +From cc272163ea554a97dac180fa8dd6cd54c2810bd1 Mon Sep 17 00:00:00 2001 +From: Mohit Gambhir +Date: Thu, 26 Jan 2017 13:12:27 -0500 +Subject: x86/xen: Fix APIC id mismatch warning on Intel + +From: Mohit Gambhir + +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 +Reviewed-by: Juergen Gross +Signed-off-by: Boris Ostrovsky +Cc: Ben Hutchings +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/xen/apic.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/x86/xen/apic.c ++++ b/arch/x86/xen/apic.c +@@ -145,7 +145,7 @@ static void xen_silent_inquire(int apici + 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; + }