--- /dev/null
+From 5effc09c4907901f0e71e68e5f2e14211d9a203f Mon Sep 17 00:00:00 2001
+From: Alexey Brodkin <Alexey.Brodkin@synopsys.com>
+Date: Tue, 22 Oct 2019 17:04:11 +0300
+Subject: ARC: perf: Accommodate big-endian CPU
+
+From: Alexey Brodkin <Alexey.Brodkin@synopsys.com>
+
+commit 5effc09c4907901f0e71e68e5f2e14211d9a203f upstream.
+
+8-letter strings representing ARC perf events are stores in two
+32-bit registers as ASCII characters like that: "IJMP", "IALL", "IJMPTAK" etc.
+
+And the same order of bytes in the word is used regardless CPU endianness.
+
+Which means in case of big-endian CPU core we need to swap bytes to get
+the same order as if it was on little-endian CPU.
+
+Otherwise we're seeing the following error message on boot:
+------------------------->8----------------------
+ARC perf : 8 counters (32 bits), 40 conditions, [overflow IRQ support]
+sysfs: cannot create duplicate filename '/devices/arc_pct/events/pmji'
+CPU: 0 PID: 1 Comm: swapper/0 Not tainted 5.2.18 #3
+Stack Trace:
+ arc_unwind_core+0xd4/0xfc
+ dump_stack+0x64/0x80
+ sysfs_warn_dup+0x46/0x58
+ sysfs_add_file_mode_ns+0xb2/0x168
+ create_files+0x70/0x2a0
+------------[ cut here ]------------
+WARNING: CPU: 0 PID: 1 at kernel/events/core.c:12144 perf_event_sysfs_init+0x70/0xa0
+Failed to register pmu: arc_pct, reason -17
+Modules linked in:
+CPU: 0 PID: 1 Comm: swapper/0 Not tainted 5.2.18 #3
+Stack Trace:
+ arc_unwind_core+0xd4/0xfc
+ dump_stack+0x64/0x80
+ __warn+0x9c/0xd4
+ warn_slowpath_fmt+0x22/0x2c
+ perf_event_sysfs_init+0x70/0xa0
+---[ end trace a75fb9a9837bd1ec ]---
+------------------------->8----------------------
+
+What happens here we're trying to register more than one raw perf event
+with the same name "PMJI". Why? Because ARC perf events are 4 to 8 letters
+and encoded into two 32-bit words. In this particular case we deal with 2
+events:
+ * "IJMP____" which counts all jump & branch instructions
+ * "IJMPC___" which counts only conditional jumps & branches
+
+Those strings are split in two 32-bit words this way "IJMP" + "____" &
+"IJMP" + "C___" correspondingly. Now if we read them swapped due to CPU core
+being big-endian then we read "PMJI" + "____" & "PMJI" + "___C".
+
+And since we interpret read array of ASCII letters as a null-terminated string
+on big-endian CPU we end up with 2 events of the same name "PMJI".
+
+Signed-off-by: Alexey Brodkin <abrodkin@synopsys.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arc/kernel/perf_event.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/arch/arc/kernel/perf_event.c
++++ b/arch/arc/kernel/perf_event.c
+@@ -614,8 +614,8 @@ static int arc_pmu_device_probe(struct p
+ /* loop thru all available h/w condition indexes */
+ for (i = 0; i < cc_bcr.c; i++) {
+ write_aux_reg(ARC_REG_CC_INDEX, i);
+- cc_name.indiv.word0 = read_aux_reg(ARC_REG_CC_NAME0);
+- cc_name.indiv.word1 = read_aux_reg(ARC_REG_CC_NAME1);
++ cc_name.indiv.word0 = le32_to_cpu(read_aux_reg(ARC_REG_CC_NAME0));
++ cc_name.indiv.word1 = le32_to_cpu(read_aux_reg(ARC_REG_CC_NAME1));
+
+ arc_pmu_map_hw_event(i, cc_name.str);
+ arc_pmu_add_raw_event_attr(i, cc_name.str);
--- /dev/null
+From d4af3c4b81f4cd5662baa6f1492f998d89783318 Mon Sep 17 00:00:00 2001
+From: Bjorn Andersson <bjorn.andersson@linaro.org>
+Date: Tue, 29 Oct 2019 10:15:39 -0700
+Subject: arm64: cpufeature: Enable Qualcomm Falkor/Kryo errata 1003
+
+From: Bjorn Andersson <bjorn.andersson@linaro.org>
+
+commit d4af3c4b81f4cd5662baa6f1492f998d89783318 upstream.
+
+With the introduction of 'cce360b54ce6 ("arm64: capabilities: Filter the
+entries based on a given mask")' the Qualcomm Falkor/Kryo errata 1003 is
+no long applied.
+
+The result of not applying errata 1003 is that MSM8996 runs into various
+RCU stalls and fails to boot most of the times.
+
+Give 1003 a "type" to ensure they are not filtered out in
+update_cpu_capabilities().
+
+Fixes: cce360b54ce6 ("arm64: capabilities: Filter the entries based on a given mask")
+Cc: stable@vger.kernel.org
+Reported-by: Mark Brown <broonie@kernel.org>
+Suggested-by: Will Deacon <will@kernel.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm64/kernel/cpu_errata.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/arch/arm64/kernel/cpu_errata.c
++++ b/arch/arm64/kernel/cpu_errata.c
+@@ -816,6 +816,7 @@ const struct arm64_cpu_capabilities arm6
+ {
+ .desc = "Qualcomm Technologies Falkor/Kryo erratum 1003",
+ .capability = ARM64_WORKAROUND_QCOM_FALKOR_E1003,
++ .type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM,
+ .matches = cpucap_multi_entry_cap_matches,
+ .match_list = qcom_erratum_1003_list,
+ },
--- /dev/null
+From aa57157be69fb599bd4c38a4b75c5aad74a60ec0 Mon Sep 17 00:00:00 2001
+From: Catalin Marinas <catalin.marinas@arm.com>
+Date: Tue, 29 Oct 2019 15:30:51 +0000
+Subject: arm64: Ensure VM_WRITE|VM_SHARED ptes are clean by default
+
+From: Catalin Marinas <catalin.marinas@arm.com>
+
+commit aa57157be69fb599bd4c38a4b75c5aad74a60ec0 upstream.
+
+Shared and writable mappings (__S.1.) should be clean (!dirty) initially
+and made dirty on a subsequent write either through the hardware DBM
+(dirty bit management) mechanism or through a write page fault. A clean
+pte for the arm64 kernel is one that has PTE_RDONLY set and PTE_DIRTY
+clear.
+
+The PAGE_SHARED{,_EXEC} attributes have PTE_WRITE set (PTE_DBM) and
+PTE_DIRTY clear. Prior to commit 73e86cb03cf2 ("arm64: Move PTE_RDONLY
+bit handling out of set_pte_at()"), it was the responsibility of
+set_pte_at() to set the PTE_RDONLY bit and mark the pte clean if the
+software PTE_DIRTY bit was not set. However, the above commit removed
+the pte_sw_dirty() check and the subsequent setting of PTE_RDONLY in
+set_pte_at() while leaving the PAGE_SHARED{,_EXEC} definitions
+unchanged. The result is that shared+writable mappings are now dirty by
+default
+
+Fix the above by explicitly setting PTE_RDONLY in PAGE_SHARED{,_EXEC}.
+In addition, remove the superfluous PTE_DIRTY bit from the kernel PROT_*
+attributes.
+
+Fixes: 73e86cb03cf2 ("arm64: Move PTE_RDONLY bit handling out of set_pte_at()")
+Cc: <stable@vger.kernel.org> # 4.14.x-
+Cc: Will Deacon <will@kernel.org>
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm64/include/asm/pgtable-prot.h | 15 ++++++++-------
+ 1 file changed, 8 insertions(+), 7 deletions(-)
+
+--- a/arch/arm64/include/asm/pgtable-prot.h
++++ b/arch/arm64/include/asm/pgtable-prot.h
+@@ -32,11 +32,11 @@
+ #define PROT_DEFAULT (_PROT_DEFAULT | PTE_MAYBE_NG)
+ #define PROT_SECT_DEFAULT (_PROT_SECT_DEFAULT | PMD_MAYBE_NG)
+
+-#define PROT_DEVICE_nGnRnE (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_ATTRINDX(MT_DEVICE_nGnRnE))
+-#define PROT_DEVICE_nGnRE (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_ATTRINDX(MT_DEVICE_nGnRE))
+-#define PROT_NORMAL_NC (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL_NC))
+-#define PROT_NORMAL_WT (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL_WT))
+-#define PROT_NORMAL (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL))
++#define PROT_DEVICE_nGnRnE (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_WRITE | PTE_ATTRINDX(MT_DEVICE_nGnRnE))
++#define PROT_DEVICE_nGnRE (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_WRITE | PTE_ATTRINDX(MT_DEVICE_nGnRE))
++#define PROT_NORMAL_NC (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL_NC))
++#define PROT_NORMAL_WT (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL_WT))
++#define PROT_NORMAL (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL))
+
+ #define PROT_SECT_DEVICE_nGnRE (PROT_SECT_DEFAULT | PMD_SECT_PXN | PMD_SECT_UXN | PMD_ATTRINDX(MT_DEVICE_nGnRE))
+ #define PROT_SECT_NORMAL (PROT_SECT_DEFAULT | PMD_SECT_PXN | PMD_SECT_UXN | PMD_ATTRINDX(MT_NORMAL))
+@@ -80,8 +80,9 @@
+ #define PAGE_S2_DEVICE __pgprot(_PROT_DEFAULT | PAGE_S2_MEMATTR(DEVICE_nGnRE) | PTE_S2_RDONLY | PAGE_S2_XN)
+
+ #define PAGE_NONE __pgprot(((_PAGE_DEFAULT) & ~PTE_VALID) | PTE_PROT_NONE | PTE_RDONLY | PTE_NG | PTE_PXN | PTE_UXN)
+-#define PAGE_SHARED __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_WRITE)
+-#define PAGE_SHARED_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_WRITE)
++/* shared+writable pages are clean by default, hence PTE_RDONLY|PTE_WRITE */
++#define PAGE_SHARED __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_RDONLY | PTE_NG | PTE_PXN | PTE_UXN | PTE_WRITE)
++#define PAGE_SHARED_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_RDONLY | PTE_NG | PTE_PXN | PTE_WRITE)
+ #define PAGE_READONLY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_RDONLY | PTE_NG | PTE_PXN | PTE_UXN)
+ #define PAGE_READONLY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_RDONLY | PTE_NG | PTE_PXN)
+ #define PAGE_EXECONLY __pgprot(_PAGE_DEFAULT | PTE_RDONLY | PTE_NG | PTE_PXN)
--- /dev/null
+From bacdcb6675e170bb2e8d3824da220e10274f42a7 Mon Sep 17 00:00:00 2001
+From: Tony Lindgren <tony@atomide.com>
+Date: Wed, 23 Oct 2019 08:31:38 -0700
+Subject: dmaengine: cppi41: Fix cppi41_dma_prep_slave_sg() when idle
+
+From: Tony Lindgren <tony@atomide.com>
+
+commit bacdcb6675e170bb2e8d3824da220e10274f42a7 upstream.
+
+Yegor Yefremov <yegorslists@googlemail.com> reported that musb and ftdi
+uart can fail for the first open of the uart unless connected using
+a hub.
+
+This is because the first dma call done by musb_ep_program() must wait
+if cppi41 is PM runtime suspended. Otherwise musb_ep_program() continues
+with other non-dma packets before the DMA transfer is started causing at
+least ftdi uarts to fail to receive data.
+
+Let's fix the issue by waking up cppi41 with PM runtime calls added to
+cppi41_dma_prep_slave_sg() and return NULL if still idled. This way we
+have musb_ep_program() continue with PIO until cppi41 is awake.
+
+Fixes: fdea2d09b997 ("dmaengine: cppi41: Add basic PM runtime support")
+Reported-by: Yegor Yefremov <yegorslists@googlemail.com>
+Signed-off-by: Tony Lindgren <tony@atomide.com>
+Cc: stable@vger.kernel.org # v4.9+
+Link: https://lore.kernel.org/r/20191023153138.23442-1-tony@atomide.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/dma/ti/cppi41.c | 21 ++++++++++++++++++++-
+ 1 file changed, 20 insertions(+), 1 deletion(-)
+
+--- a/drivers/dma/ti/cppi41.c
++++ b/drivers/dma/ti/cppi41.c
+@@ -586,9 +586,22 @@ static struct dma_async_tx_descriptor *c
+ enum dma_transfer_direction dir, unsigned long tx_flags, void *context)
+ {
+ struct cppi41_channel *c = to_cpp41_chan(chan);
++ struct dma_async_tx_descriptor *txd = NULL;
++ struct cppi41_dd *cdd = c->cdd;
+ struct cppi41_desc *d;
+ struct scatterlist *sg;
+ unsigned int i;
++ int error;
++
++ error = pm_runtime_get(cdd->ddev.dev);
++ if (error < 0) {
++ pm_runtime_put_noidle(cdd->ddev.dev);
++
++ return NULL;
++ }
++
++ if (cdd->is_suspended)
++ goto err_out_not_ready;
+
+ d = c->desc;
+ for_each_sg(sgl, sg, sg_len, i) {
+@@ -611,7 +624,13 @@ static struct dma_async_tx_descriptor *c
+ d++;
+ }
+
+- return &c->txd;
++ txd = &c->txd;
++
++err_out_not_ready:
++ pm_runtime_mark_last_busy(cdd->ddev.dev);
++ pm_runtime_put_autosuspend(cdd->ddev.dev);
++
++ return txd;
+ }
+
+ static void cppi41_compute_td_desc(struct cppi41_desc *d)
--- /dev/null
+From bd73dfabdda280fc5f05bdec79b6721b4b2f035f Mon Sep 17 00:00:00 2001
+From: Robin Gong <yibin.gong@nxp.com>
+Date: Tue, 24 Sep 2019 09:49:18 +0000
+Subject: dmaengine: imx-sdma: fix size check for sdma script_number
+
+From: Robin Gong <yibin.gong@nxp.com>
+
+commit bd73dfabdda280fc5f05bdec79b6721b4b2f035f upstream.
+
+Illegal memory will be touch if SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V3
+(41) exceed the size of structure sdma_script_start_addrs(40),
+thus cause memory corrupt such as slob block header so that kernel
+trap into while() loop forever in slob_free(). Please refer to below
+code piece in imx-sdma.c:
+for (i = 0; i < sdma->script_number; i++)
+ if (addr_arr[i] > 0)
+ saddr_arr[i] = addr_arr[i]; /* memory corrupt here */
+That issue was brought by commit a572460be9cf ("dmaengine: imx-sdma: Add
+support for version 3 firmware") because SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V3
+(38->41 3 scripts added) not align with script number added in
+sdma_script_start_addrs(2 scripts).
+
+Fixes: a572460be9cf ("dmaengine: imx-sdma: Add support for version 3 firmware")
+Cc: stable@vger.kernel
+Link: https://www.spinics.net/lists/arm-kernel/msg754895.html
+Signed-off-by: Robin Gong <yibin.gong@nxp.com>
+Reported-by: Jurgen Lambrecht <J.Lambrecht@TELEVIC.com>
+Link: https://lore.kernel.org/r/1569347584-3478-1-git-send-email-yibin.gong@nxp.com
+[vkoul: update the patch title]
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/dma/imx-sdma.c | 8 ++++++++
+ include/linux/platform_data/dma-imx-sdma.h | 3 +++
+ 2 files changed, 11 insertions(+)
+
+--- a/drivers/dma/imx-sdma.c
++++ b/drivers/dma/imx-sdma.c
+@@ -1707,6 +1707,14 @@ static void sdma_add_scripts(struct sdma
+ if (!sdma->script_number)
+ sdma->script_number = SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V1;
+
++ if (sdma->script_number > sizeof(struct sdma_script_start_addrs)
++ / sizeof(s32)) {
++ dev_err(sdma->dev,
++ "SDMA script number %d not match with firmware.\n",
++ sdma->script_number);
++ return;
++ }
++
+ for (i = 0; i < sdma->script_number; i++)
+ if (addr_arr[i] > 0)
+ saddr_arr[i] = addr_arr[i];
+--- a/include/linux/platform_data/dma-imx-sdma.h
++++ b/include/linux/platform_data/dma-imx-sdma.h
+@@ -51,7 +51,10 @@ struct sdma_script_start_addrs {
+ /* End of v2 array */
+ s32 zcanfd_2_mcu_addr;
+ s32 zqspi_2_mcu_addr;
++ s32 mcu_2_ecspi_addr;
+ /* End of v3 array */
++ s32 mcu_2_zqspi_addr;
++ /* End of v4 array */
+ };
+
+ /**
--- /dev/null
+From 7667819385457b4aeb5fac94f67f52ab52cc10d5 Mon Sep 17 00:00:00 2001
+From: Jeffrey Hugo <jeffrey.l.hugo@gmail.com>
+Date: Thu, 17 Oct 2019 08:26:06 -0700
+Subject: dmaengine: qcom: bam_dma: Fix resource leak
+
+From: Jeffrey Hugo <jeffrey.l.hugo@gmail.com>
+
+commit 7667819385457b4aeb5fac94f67f52ab52cc10d5 upstream.
+
+bam_dma_terminate_all() will leak resources if any of the transactions are
+committed to the hardware (present in the desc fifo), and not complete.
+Since bam_dma_terminate_all() does not cause the hardware to be updated,
+the hardware will still operate on any previously committed transactions.
+This can cause memory corruption if the memory for the transaction has been
+reassigned, and will cause a sync issue between the BAM and its client(s).
+
+Fix this by properly updating the hardware in bam_dma_terminate_all().
+
+Fixes: e7c0fe2a5c84 ("dmaengine: add Qualcomm BAM dma driver")
+Signed-off-by: Jeffrey Hugo <jeffrey.l.hugo@gmail.com>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20191017152606.34120-1-jeffrey.l.hugo@gmail.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/dma/qcom/bam_dma.c | 19 +++++++++++++++++++
+ 1 file changed, 19 insertions(+)
+
+--- a/drivers/dma/qcom/bam_dma.c
++++ b/drivers/dma/qcom/bam_dma.c
+@@ -694,6 +694,25 @@ static int bam_dma_terminate_all(struct
+
+ /* remove all transactions, including active transaction */
+ spin_lock_irqsave(&bchan->vc.lock, flag);
++ /*
++ * If we have transactions queued, then some might be committed to the
++ * hardware in the desc fifo. The only way to reset the desc fifo is
++ * to do a hardware reset (either by pipe or the entire block).
++ * bam_chan_init_hw() will trigger a pipe reset, and also reinit the
++ * pipe. If the pipe is left disabled (default state after pipe reset)
++ * and is accessed by a connected hardware engine, a fatal error in
++ * the BAM will occur. There is a small window where this could happen
++ * with bam_chan_init_hw(), but it is assumed that the caller has
++ * stopped activity on any attached hardware engine. Make sure to do
++ * this first so that the BAM hardware doesn't cause memory corruption
++ * by accessing freed resources.
++ */
++ if (!list_empty(&bchan->desc_list)) {
++ async_desc = list_first_entry(&bchan->desc_list,
++ struct bam_async_desc, desc_node);
++ bam_chan_init_hw(bchan, async_desc->dir);
++ }
++
+ list_for_each_entry_safe(async_desc, tmp,
+ &bchan->desc_list, desc_node) {
+ list_add(&async_desc->vd.node, &bchan->vc.desc_issued);
--- /dev/null
+From 9ec691f48b5ef741a48af8932ccaec859c67e8f1 Mon Sep 17 00:00:00 2001
+From: Sameer Pujar <spujar@nvidia.com>
+Date: Mon, 16 Sep 2019 15:05:13 +0530
+Subject: dmaengine: tegra210-adma: fix transfer failure
+
+From: Sameer Pujar <spujar@nvidia.com>
+
+commit 9ec691f48b5ef741a48af8932ccaec859c67e8f1 upstream.
+
+>From Tegra186 onwards OUTSTANDING_REQUESTS field is added in channel
+configuration register(bits 7:4) which defines the maximum number of reads
+from the source and writes to the destination that may be outstanding at
+any given point of time. This field must be programmed with a value
+between 1 and 8. A value of 0 will prevent any transfers from happening.
+
+Thus added 'has_outstanding_reqs' bool member in chip data structure and is
+set to false for Tegra210, since the field is not applicable. For Tegra186
+it is set to true and channel configuration is updated with maximum
+outstanding requests.
+
+Fixes: 433de642a76c ("dmaengine: tegra210-adma: add support for Tegra186/Tegra194")
+Cc: stable@vger.kernel.org
+Signed-off-by: Sameer Pujar <spujar@nvidia.com>
+Acked-by: Jon Hunter <jonathanh@nvidia.com>
+Link: https://lore.kernel.org/r/1568626513-16541-1-git-send-email-spujar@nvidia.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/dma/tegra210-adma.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/drivers/dma/tegra210-adma.c
++++ b/drivers/dma/tegra210-adma.c
+@@ -40,6 +40,7 @@
+ #define ADMA_CH_CONFIG_MAX_BURST_SIZE 16
+ #define ADMA_CH_CONFIG_WEIGHT_FOR_WRR(val) ((val) & 0xf)
+ #define ADMA_CH_CONFIG_MAX_BUFS 8
++#define TEGRA186_ADMA_CH_CONFIG_OUTSTANDING_REQS(reqs) (reqs << 4)
+
+ #define ADMA_CH_FIFO_CTRL 0x2c
+ #define TEGRA210_ADMA_CH_FIFO_CTRL_OFLWTHRES(val) (((val) & 0xf) << 24)
+@@ -85,6 +86,7 @@ struct tegra_adma;
+ * @ch_req_tx_shift: Register offset for AHUB transmit channel select.
+ * @ch_req_rx_shift: Register offset for AHUB receive channel select.
+ * @ch_base_offset: Register offset of DMA channel registers.
++ * @has_outstanding_reqs: If DMA channel can have outstanding requests.
+ * @ch_fifo_ctrl: Default value for channel FIFO CTRL register.
+ * @ch_req_mask: Mask for Tx or Rx channel select.
+ * @ch_req_max: Maximum number of Tx or Rx channels available.
+@@ -103,6 +105,7 @@ struct tegra_adma_chip_data {
+ unsigned int ch_req_max;
+ unsigned int ch_reg_size;
+ unsigned int nr_channels;
++ bool has_outstanding_reqs;
+ };
+
+ /*
+@@ -602,6 +605,8 @@ static int tegra_adma_set_xfer_params(st
+ ADMA_CH_CTRL_FLOWCTRL_EN;
+ ch_regs->config |= cdata->adma_get_burst_config(burst_size);
+ ch_regs->config |= ADMA_CH_CONFIG_WEIGHT_FOR_WRR(1);
++ if (cdata->has_outstanding_reqs)
++ ch_regs->config |= TEGRA186_ADMA_CH_CONFIG_OUTSTANDING_REQS(8);
+ ch_regs->fifo_ctrl = cdata->ch_fifo_ctrl;
+ ch_regs->tc = desc->period_len & ADMA_CH_TC_COUNT_MASK;
+
+@@ -786,6 +791,7 @@ static const struct tegra_adma_chip_data
+ .ch_req_tx_shift = 28,
+ .ch_req_rx_shift = 24,
+ .ch_base_offset = 0,
++ .has_outstanding_reqs = false,
+ .ch_fifo_ctrl = TEGRA210_FIFO_CTRL_DEFAULT,
+ .ch_req_mask = 0xf,
+ .ch_req_max = 10,
+@@ -800,6 +806,7 @@ static const struct tegra_adma_chip_data
+ .ch_req_tx_shift = 27,
+ .ch_req_rx_shift = 22,
+ .ch_base_offset = 0x10000,
++ .has_outstanding_reqs = true,
+ .ch_fifo_ctrl = TEGRA186_FIFO_CTRL_DEFAULT,
+ .ch_req_mask = 0x1f,
+ .ch_req_max = 20,
--- /dev/null
+From e5574f61e9d8274c49e9a5d943abde8e938d57e1 Mon Sep 17 00:00:00 2001
+From: chen gong <curry.gong@amd.com>
+Date: Wed, 23 Oct 2019 13:54:32 +0800
+Subject: drm/amdgpu: Fix SDMA hang when performing VKexample test
+
+From: chen gong <curry.gong@amd.com>
+
+commit e5574f61e9d8274c49e9a5d943abde8e938d57e1 upstream.
+
+VKexample test hang during Occlusion/SDMA/Varia runs.
+Clear XNACK_WATERMK in reg SDMA0_UTCL1_WATERMK to fix this issue.
+
+Signed-off-by: chen gong <curry.gong@amd.com>
+Reviewed-by: Aaron Liu <aaron.liu@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
+@@ -159,6 +159,7 @@ static const struct soc15_reg_golden gol
+ SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_RLC7_RB_RPTR_ADDR_LO, 0xfffffffd, 0x00000001),
+ SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_RLC7_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
+ SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_UTCL1_PAGE, 0x000003ff, 0x000003c0),
++ SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_UTCL1_WATERMK, 0xfc000000, 0x00000000)
+ };
+
+ static const struct soc15_reg_golden golden_settings_sdma1_4_2[] = {
--- /dev/null
+From f52ebe1f888dfae68d7cffabf5ac898f8cb64fb3 Mon Sep 17 00:00:00 2001
+From: "Tianci.Yin" <tianci.yin@amd.com>
+Date: Thu, 24 Oct 2019 18:03:17 +0800
+Subject: drm/amdgpu/gfx10: update gfx golden settings
+
+From: Tianci.Yin <tianci.yin@amd.com>
+
+commit f52ebe1f888dfae68d7cffabf5ac898f8cb64fb3 upstream.
+
+update registers: mmCGTT_SPI_CLK_CTRL
+
+Reviewed-by: Feifei Xu <Feifei.Xu@amd.com>
+Signed-off-by: Tianci.Yin <tianci.yin@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
+@@ -67,7 +67,7 @@ static const struct soc15_reg_golden gol
+ {
+ SOC15_REG_GOLDEN_VALUE(GC, 0, mmCB_HW_CONTROL_4, 0xffffffff, 0x00400014),
+ SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_CPF_CLK_CTRL, 0xfcff8fff, 0xf8000100),
+- SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_SPI_CLK_CTRL, 0xc0000000, 0xc0000100),
++ SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_SPI_CLK_CTRL, 0xcd000000, 0x0d000100),
+ SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_SQ_CLK_CTRL, 0x60000ff0, 0x60000100),
+ SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_SQG_CLK_CTRL, 0x40000000, 0x40000100),
+ SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_VGT_CLK_CTRL, 0xffff8fff, 0xffff8100),
--- /dev/null
+From 30ef5c7eaba0ddafc6c23eca65ebe52169dfcc60 Mon Sep 17 00:00:00 2001
+From: Alex Deucher <alexander.deucher@amd.com>
+Date: Tue, 29 Oct 2019 17:14:15 -0400
+Subject: drm/amdgpu/gmc10: properly set BANK_SELECT and FRAGMENT_SIZE
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+commit 30ef5c7eaba0ddafc6c23eca65ebe52169dfcc60 upstream.
+
+These were not aligned for optimal performance for GPUVM.
+
+Acked-by: Christian König <christian.koenig@amd.com>
+Reviewed-by: Tianci Yin <tianci.yin@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/amd/amdgpu/gfxhub_v2_0.c | 9 +++++++++
+ drivers/gpu/drm/amd/amdgpu/mmhub_v2_0.c | 9 +++++++++
+ 2 files changed, 18 insertions(+)
+
+--- a/drivers/gpu/drm/amd/amdgpu/gfxhub_v2_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/gfxhub_v2_0.c
+@@ -151,6 +151,15 @@ static void gfxhub_v2_0_init_cache_regs(
+ WREG32_SOC15(GC, 0, mmGCVM_L2_CNTL2, tmp);
+
+ tmp = mmGCVM_L2_CNTL3_DEFAULT;
++ if (adev->gmc.translate_further) {
++ tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL3, BANK_SELECT, 12);
++ tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL3,
++ L2_CACHE_BIGK_FRAGMENT_SIZE, 9);
++ } else {
++ tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL3, BANK_SELECT, 9);
++ tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL3,
++ L2_CACHE_BIGK_FRAGMENT_SIZE, 6);
++ }
+ WREG32_SOC15(GC, 0, mmGCVM_L2_CNTL3, tmp);
+
+ tmp = mmGCVM_L2_CNTL4_DEFAULT;
+--- a/drivers/gpu/drm/amd/amdgpu/mmhub_v2_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v2_0.c
+@@ -137,6 +137,15 @@ static void mmhub_v2_0_init_cache_regs(s
+ WREG32_SOC15(MMHUB, 0, mmMMVM_L2_CNTL2, tmp);
+
+ tmp = mmMMVM_L2_CNTL3_DEFAULT;
++ if (adev->gmc.translate_further) {
++ tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL3, BANK_SELECT, 12);
++ tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL3,
++ L2_CACHE_BIGK_FRAGMENT_SIZE, 9);
++ } else {
++ tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL3, BANK_SELECT, 9);
++ tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL3,
++ L2_CACHE_BIGK_FRAGMENT_SIZE, 6);
++ }
+ WREG32_SOC15(MMHUB, 0, mmMMVM_L2_CNTL3, tmp);
+
+ tmp = mmMMVM_L2_CNTL4_DEFAULT;
--- /dev/null
+From e6f4e274c1e52d1f0bfe293fb44ddf59de6c0374 Mon Sep 17 00:00:00 2001
+From: Pelle van Gils <pelle@vangils.xyz>
+Date: Thu, 24 Oct 2019 16:04:31 +0200
+Subject: drm/amdgpu/powerplay/vega10: allow undervolting in p7
+
+From: Pelle van Gils <pelle@vangils.xyz>
+
+commit e6f4e274c1e52d1f0bfe293fb44ddf59de6c0374 upstream.
+
+The vega10_odn_update_soc_table() function does not allow the SCLK
+dependent voltage to be set for power-state 7 to a value below the default
+in pptable. Change the for-loop condition to allow undervolting in the
+highest state.
+
+Bug: https://bugzilla.kernel.org/show_bug.cgi?id=205277
+Signed-off-by: Pelle van Gils <pelle@vangils.xyz>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c
++++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c
+@@ -5097,9 +5097,7 @@ static void vega10_odn_update_soc_table(
+
+ if (type == PP_OD_EDIT_SCLK_VDDC_TABLE) {
+ podn_vdd_dep = &data->odn_dpm_table.vdd_dep_on_sclk;
+- for (i = 0; i < podn_vdd_dep->count - 1; i++)
+- od_vddc_lookup_table->entries[i].us_vdd = podn_vdd_dep->entries[i].vddc;
+- if (od_vddc_lookup_table->entries[i].us_vdd < podn_vdd_dep->entries[i].vddc)
++ for (i = 0; i < podn_vdd_dep->count; i++)
+ od_vddc_lookup_table->entries[i].us_vdd = podn_vdd_dep->entries[i].vddc;
+ } else if (type == PP_OD_EDIT_MCLK_VDDC_TABLE) {
+ podn_vdd_dep = &data->odn_dpm_table.vdd_dep_on_mclk;
--- /dev/null
+From 59cd826fb5e7889515bf5771e295e0624c348571 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= <ville.syrjala@linux.intel.com>
+Date: Tue, 22 Oct 2019 21:56:43 +0300
+Subject: drm/i915: Fix PCH reference clock for FDI on HSW/BDW
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ville Syrjälä <ville.syrjala@linux.intel.com>
+
+commit 59cd826fb5e7889515bf5771e295e0624c348571 upstream.
+
+The change to skip the PCH reference initialization during fastboot
+did end up breaking FDI. To fix that let's try to do the PCH reference
+init whenever we're disabling a DPLL that was using said reference
+previously.
+
+Cc: stable@vger.kernel.org
+Tested-by: Andrija <akijo97@gmail.com>
+Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=112084
+Fixes: b16c7ed95caf ("drm/i915: Do not touch the PCH SSC reference if a PLL is using it")
+Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20191022185643.1483-1-ville.syrjala@linux.intel.com
+Reviewed-by: Imre Deak <imre.deak@intel.com>
+(cherry picked from commit dd5279c71405533d4ddbb9453effc60f0f5bf211)
+Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/i915/display/intel_display.c | 11 ++++++-----
+ drivers/gpu/drm/i915/display/intel_dpll_mgr.c | 15 +++++++++++++++
+ drivers/gpu/drm/i915/i915_drv.h | 2 ++
+ 3 files changed, 23 insertions(+), 5 deletions(-)
+
+--- a/drivers/gpu/drm/i915/display/intel_display.c
++++ b/drivers/gpu/drm/i915/display/intel_display.c
+@@ -9186,7 +9186,6 @@ static bool wrpll_uses_pch_ssc(struct dr
+ static void lpt_init_pch_refclk(struct drm_i915_private *dev_priv)
+ {
+ struct intel_encoder *encoder;
+- bool pch_ssc_in_use = false;
+ bool has_fdi = false;
+
+ for_each_intel_encoder(&dev_priv->drm, encoder) {
+@@ -9214,22 +9213,24 @@ static void lpt_init_pch_refclk(struct d
+ * clock hierarchy. That would also allow us to do
+ * clock bending finally.
+ */
++ dev_priv->pch_ssc_use = 0;
++
+ if (spll_uses_pch_ssc(dev_priv)) {
+ DRM_DEBUG_KMS("SPLL using PCH SSC\n");
+- pch_ssc_in_use = true;
++ dev_priv->pch_ssc_use |= BIT(DPLL_ID_SPLL);
+ }
+
+ if (wrpll_uses_pch_ssc(dev_priv, DPLL_ID_WRPLL1)) {
+ DRM_DEBUG_KMS("WRPLL1 using PCH SSC\n");
+- pch_ssc_in_use = true;
++ dev_priv->pch_ssc_use |= BIT(DPLL_ID_WRPLL1);
+ }
+
+ if (wrpll_uses_pch_ssc(dev_priv, DPLL_ID_WRPLL2)) {
+ DRM_DEBUG_KMS("WRPLL2 using PCH SSC\n");
+- pch_ssc_in_use = true;
++ dev_priv->pch_ssc_use |= BIT(DPLL_ID_WRPLL2);
+ }
+
+- if (pch_ssc_in_use)
++ if (dev_priv->pch_ssc_use)
+ return;
+
+ if (has_fdi) {
+--- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
++++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
+@@ -498,16 +498,31 @@ static void hsw_ddi_wrpll_disable(struct
+ val = I915_READ(WRPLL_CTL(id));
+ I915_WRITE(WRPLL_CTL(id), val & ~WRPLL_PLL_ENABLE);
+ POSTING_READ(WRPLL_CTL(id));
++
++ /*
++ * Try to set up the PCH reference clock once all DPLLs
++ * that depend on it have been shut down.
++ */
++ if (dev_priv->pch_ssc_use & BIT(id))
++ intel_init_pch_refclk(dev_priv);
+ }
+
+ static void hsw_ddi_spll_disable(struct drm_i915_private *dev_priv,
+ struct intel_shared_dpll *pll)
+ {
++ enum intel_dpll_id id = pll->info->id;
+ u32 val;
+
+ val = I915_READ(SPLL_CTL);
+ I915_WRITE(SPLL_CTL, val & ~SPLL_PLL_ENABLE);
+ POSTING_READ(SPLL_CTL);
++
++ /*
++ * Try to set up the PCH reference clock once all DPLLs
++ * that depend on it have been shut down.
++ */
++ if (dev_priv->pch_ssc_use & BIT(id))
++ intel_init_pch_refclk(dev_priv);
+ }
+
+ static bool hsw_ddi_wrpll_get_hw_state(struct drm_i915_private *dev_priv,
+--- a/drivers/gpu/drm/i915/i915_drv.h
++++ b/drivers/gpu/drm/i915/i915_drv.h
+@@ -1881,6 +1881,8 @@ struct drm_i915_private {
+ struct work_struct idle_work;
+ } gem;
+
++ u8 pch_ssc_use;
++
+ /* For i945gm vblank irq vs. C3 workaround */
+ struct {
+ struct work_struct work;
--- /dev/null
+From 08c453f6d073f069cf8e30e03cd3c16262c9b953 Mon Sep 17 00:00:00 2001
+From: Andrey Smirnov <andrew.smirnov@gmail.com>
+Date: Thu, 17 Oct 2019 21:45:17 -0700
+Subject: HID: logitech-hidpp: do all FF cleanup in hidpp_ff_destroy()
+
+From: Andrey Smirnov <andrew.smirnov@gmail.com>
+
+commit 08c453f6d073f069cf8e30e03cd3c16262c9b953 upstream.
+
+All of the FF-related resources belong to corresponding FF device, so
+they should be freed as a part of hidpp_ff_destroy() to avoid
+potential race condidions.
+
+Fixes: ff21a635dd1a ("HID: logitech-hidpp: Force feedback support for the Logitech G920")
+Suggested-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
+Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
+Cc: Jiri Kosina <jikos@kernel.org>
+Cc: Benjamin Tissoires <benjamin.tissoires@redhat.com>
+Cc: Henrik Rydberg <rydberg@bitmath.org>
+Cc: Pierre-Loup A. Griffais <pgriffais@valvesoftware.com>
+Cc: Austin Palmer <austinp@valvesoftware.com>
+Cc: linux-input@vger.kernel.org
+Cc: linux-kernel@vger.kernel.org
+Cc: stable@vger.kernel.org # 5.2+
+Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/hid/hid-logitech-hidpp.c | 33 +++++----------------------------
+ 1 file changed, 5 insertions(+), 28 deletions(-)
+
+--- a/drivers/hid/hid-logitech-hidpp.c
++++ b/drivers/hid/hid-logitech-hidpp.c
+@@ -2078,7 +2078,12 @@ static DEVICE_ATTR(range, S_IRUSR | S_IW
+ static void hidpp_ff_destroy(struct ff_device *ff)
+ {
+ struct hidpp_ff_private_data *data = ff->private;
++ struct hid_device *hid = data->hidpp->hid_dev;
+
++ hid_info(hid, "Unloading HID++ force feedback.\n");
++
++ device_remove_file(&hid->dev, &dev_attr_range);
++ destroy_workqueue(data->wq);
+ kfree(data->effect_ids);
+ }
+
+@@ -2170,31 +2175,6 @@ static int hidpp_ff_init(struct hidpp_de
+ return 0;
+ }
+
+-static int hidpp_ff_deinit(struct hid_device *hid)
+-{
+- struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list);
+- struct input_dev *dev = hidinput->input;
+- struct hidpp_ff_private_data *data;
+-
+- if (!dev) {
+- hid_err(hid, "Struct input_dev not found!\n");
+- return -EINVAL;
+- }
+-
+- hid_info(hid, "Unloading HID++ force feedback.\n");
+- data = dev->ff->private;
+- if (!data) {
+- hid_err(hid, "Private data not found!\n");
+- return -EINVAL;
+- }
+-
+- destroy_workqueue(data->wq);
+- device_remove_file(&hid->dev, &dev_attr_range);
+-
+- return 0;
+-}
+-
+-
+ /* ************************************************************************** */
+ /* */
+ /* Device Support */
+@@ -3713,9 +3693,6 @@ static void hidpp_remove(struct hid_devi
+
+ sysfs_remove_group(&hdev->dev.kobj, &ps_attribute_group);
+
+- if (hidpp->quirks & HIDPP_QUIRK_CLASS_G920)
+- hidpp_ff_deinit(hdev);
+-
+ hid_hw_stop(hdev);
+ cancel_work_sync(&hidpp->work);
+ mutex_destroy(&hidpp->send_mutex);
--- /dev/null
+From 905d754c53a522aacf806ea1d3e7c929148c1910 Mon Sep 17 00:00:00 2001
+From: Andrey Smirnov <andrew.smirnov@gmail.com>
+Date: Thu, 17 Oct 2019 21:45:16 -0700
+Subject: HID: logitech-hidpp: rework device validation
+
+From: Andrey Smirnov <andrew.smirnov@gmail.com>
+
+commit 905d754c53a522aacf806ea1d3e7c929148c1910 upstream.
+
+G920 device only advertises REPORT_ID_HIDPP_LONG and
+REPORT_ID_HIDPP_VERY_LONG in its HID report descriptor, so querying
+for REPORT_ID_HIDPP_SHORT with optional=false will always fail and
+prevent G920 to be recognized as a valid HID++ device.
+
+To fix this and improve some other aspects, modify
+hidpp_validate_device() as follows:
+
+ - Inline the code of hidpp_validate_report() to simplify
+ distingushing between non-present and invalid report descriptors
+
+ - Drop the check for id >= HID_MAX_IDS || id < 0 since all of our
+ IDs are static and known to satisfy that at compile time
+
+ - Change the algorithms to check all possible report
+ types (including very long report) and deem the device as a valid
+ HID++ device if it supports at least one
+
+ - Treat invalid report length as a hard stop for the validation
+ algorithm, meaning that if any of the supported reports has
+ invalid length we assume the worst and treat the device as a
+ generic HID device.
+
+ - Fold initialization of hidpp->very_long_report_length into
+ hidpp_validate_device() since it already fetches very long report
+ length and validates its value
+
+Fixes: fe3ee1ec007b ("HID: logitech-hidpp: allow non HID++ devices to be handled by this module")
+Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=204191
+Reported-by: Sam Bazely <sambazley@fastmail.com>
+Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
+Cc: Jiri Kosina <jikos@kernel.org>
+Cc: Benjamin Tissoires <benjamin.tissoires@redhat.com>
+Cc: Henrik Rydberg <rydberg@bitmath.org>
+Cc: Pierre-Loup A. Griffais <pgriffais@valvesoftware.com>
+Cc: Austin Palmer <austinp@valvesoftware.com>
+Cc: linux-input@vger.kernel.org
+Cc: linux-kernel@vger.kernel.org
+Cc: stable@vger.kernel.org # 5.2+
+Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/hid/hid-logitech-hidpp.c | 54 +++++++++++++++++++++------------------
+ 1 file changed, 30 insertions(+), 24 deletions(-)
+
+--- a/drivers/hid/hid-logitech-hidpp.c
++++ b/drivers/hid/hid-logitech-hidpp.c
+@@ -3498,34 +3498,45 @@ static int hidpp_get_report_length(struc
+ return report->field[0]->report_count + 1;
+ }
+
+-static bool hidpp_validate_report(struct hid_device *hdev, int id,
+- int expected_length, bool optional)
++static bool hidpp_validate_device(struct hid_device *hdev)
+ {
+- int report_length;
++ struct hidpp_device *hidpp = hid_get_drvdata(hdev);
++ int id, report_length, supported_reports = 0;
++
++ id = REPORT_ID_HIDPP_SHORT;
++ report_length = hidpp_get_report_length(hdev, id);
++ if (report_length) {
++ if (report_length < HIDPP_REPORT_SHORT_LENGTH)
++ goto bad_device;
+
+- if (id >= HID_MAX_IDS || id < 0) {
+- hid_err(hdev, "invalid HID report id %u\n", id);
+- return false;
++ supported_reports++;
+ }
+
++ id = REPORT_ID_HIDPP_LONG;
+ report_length = hidpp_get_report_length(hdev, id);
+- if (!report_length)
+- return optional;
++ if (report_length) {
++ if (report_length < HIDPP_REPORT_LONG_LENGTH)
++ goto bad_device;
+
+- if (report_length < expected_length) {
+- hid_warn(hdev, "not enough values in hidpp report %d\n", id);
+- return false;
++ supported_reports++;
+ }
+
+- return true;
+-}
++ id = REPORT_ID_HIDPP_VERY_LONG;
++ report_length = hidpp_get_report_length(hdev, id);
++ if (report_length) {
++ if (report_length < HIDPP_REPORT_LONG_LENGTH ||
++ report_length > HIDPP_REPORT_VERY_LONG_MAX_LENGTH)
++ goto bad_device;
+
+-static bool hidpp_validate_device(struct hid_device *hdev)
+-{
+- return hidpp_validate_report(hdev, REPORT_ID_HIDPP_SHORT,
+- HIDPP_REPORT_SHORT_LENGTH, false) &&
+- hidpp_validate_report(hdev, REPORT_ID_HIDPP_LONG,
+- HIDPP_REPORT_LONG_LENGTH, true);
++ supported_reports++;
++ hidpp->very_long_report_length = report_length;
++ }
++
++ return supported_reports;
++
++bad_device:
++ hid_warn(hdev, "not enough values in hidpp report %d\n", id);
++ return false;
+ }
+
+ static bool hidpp_application_equals(struct hid_device *hdev,
+@@ -3572,11 +3583,6 @@ static int hidpp_probe(struct hid_device
+ return hid_hw_start(hdev, HID_CONNECT_DEFAULT);
+ }
+
+- hidpp->very_long_report_length =
+- hidpp_get_report_length(hdev, REPORT_ID_HIDPP_VERY_LONG);
+- if (hidpp->very_long_report_length > HIDPP_REPORT_VERY_LONG_MAX_LENGTH)
+- hidpp->very_long_report_length = HIDPP_REPORT_VERY_LONG_MAX_LENGTH;
+-
+ if (id->group == HID_GROUP_LOGITECH_DJ_DEVICE)
+ hidpp->quirks |= HIDPP_QUIRK_UNIFYING;
+
--- /dev/null
+From abdd3d0b344fdf72a4904d09b97bc964d74c4419 Mon Sep 17 00:00:00 2001
+From: Andrey Smirnov <andrew.smirnov@gmail.com>
+Date: Thu, 17 Oct 2019 21:45:15 -0700
+Subject: HID: logitech-hidpp: split g920_get_config()
+
+From: Andrey Smirnov <andrew.smirnov@gmail.com>
+
+commit abdd3d0b344fdf72a4904d09b97bc964d74c4419 upstream.
+
+Original version of g920_get_config() contained two kind of actions:
+
+ 1. Device specific communication to query/set some parameters
+ which requires active communication channel with the device,
+ or, put in other way, for the call to be sandwiched between
+ hid_device_io_start() and hid_device_io_stop().
+
+ 2. Input subsystem specific FF controller initialization which, in
+ order to access a valid 'struct hid_input' via
+ 'hid->inputs.next', requires claimed hidinput which means be
+ executed after the call to hid_hw_start() with connect_mask
+ containing HID_CONNECT_HIDINPUT.
+
+Location of g920_get_config() can only fulfill requirements for #1 and
+not #2, which might result in following backtrace:
+
+[ 88.312258] logitech-hidpp-device 0003:046D:C262.0005: HID++ 4.2 device connected.
+[ 88.320298] BUG: kernel NULL pointer dereference, address: 0000000000000018
+[ 88.320304] #PF: supervisor read access in kernel mode
+[ 88.320307] #PF: error_code(0x0000) - not-present page
+[ 88.320309] PGD 0 P4D 0
+[ 88.320315] Oops: 0000 [#1] SMP PTI
+[ 88.320320] CPU: 1 PID: 3080 Comm: systemd-udevd Not tainted 5.4.0-rc1+ #31
+[ 88.320322] Hardware name: Apple Inc. MacBookPro11,1/Mac-189A3D4F975D5FFC, BIOS 149.0.0.0.0 09/17/2018
+[ 88.320334] RIP: 0010:hidpp_probe+0x61f/0x948 [hid_logitech_hidpp]
+[ 88.320338] Code: 81 00 00 48 89 ef e8 f0 d6 ff ff 41 89 c6 85 c0 75 b5 0f b6 44 24 28 48 8b 5d 00 88 44 24 1e 89 44 24 0c 48 8b 83 18 1c 00 00 <48> 8b 48 18 48 8b 83 10 19 00 00 48 8b 40 40 48 89 0c 24 0f b7 80
+[ 88.320341] RSP: 0018:ffffb0a6824aba68 EFLAGS: 00010246
+[ 88.320345] RAX: 0000000000000000 RBX: ffff93a50756e000 RCX: 0000000000010408
+[ 88.320347] RDX: 0000000000000000 RSI: ffff93a51f0ad0a0 RDI: 000000000002d0a0
+[ 88.320350] RBP: ffff93a50416da28 R08: ffff93a50416da70 R09: ffff93a50416da70
+[ 88.320352] R10: 000000148ae9e60c R11: 00000000000f1525 R12: ffff93a50756e000
+[ 88.320354] R13: ffff93a50756f8d0 R14: 0000000000000000 R15: ffff93a50756fc38
+[ 88.320358] FS: 00007f8d8c1e0940(0000) GS:ffff93a51f080000(0000) knlGS:0000000000000000
+[ 88.320361] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[ 88.320363] CR2: 0000000000000018 CR3: 00000003996d8003 CR4: 00000000001606e0
+[ 88.320366] Call Trace:
+[ 88.320377] ? _cond_resched+0x15/0x30
+[ 88.320387] ? create_pinctrl+0x2f/0x3c0
+[ 88.320393] ? kernfs_link_sibling+0x94/0xe0
+[ 88.320398] ? _cond_resched+0x15/0x30
+[ 88.320402] ? kernfs_activate+0x5f/0x80
+[ 88.320406] ? kernfs_add_one+0xe2/0x130
+[ 88.320411] hid_device_probe+0x106/0x170
+[ 88.320419] really_probe+0x147/0x3c0
+[ 88.320424] driver_probe_device+0xb6/0x100
+[ 88.320428] device_driver_attach+0x53/0x60
+[ 88.320433] __driver_attach+0x8a/0x150
+[ 88.320437] ? device_driver_attach+0x60/0x60
+[ 88.320440] bus_for_each_dev+0x78/0xc0
+[ 88.320445] bus_add_driver+0x14d/0x1f0
+[ 88.320450] driver_register+0x6c/0xc0
+[ 88.320453] ? 0xffffffffc0d67000
+[ 88.320457] __hid_register_driver+0x4c/0x80
+[ 88.320464] do_one_initcall+0x46/0x1f4
+[ 88.320469] ? _cond_resched+0x15/0x30
+[ 88.320474] ? kmem_cache_alloc_trace+0x162/0x220
+[ 88.320481] ? do_init_module+0x23/0x230
+[ 88.320486] do_init_module+0x5c/0x230
+[ 88.320491] load_module+0x26e1/0x2990
+[ 88.320502] ? ima_post_read_file+0xf0/0x100
+[ 88.320508] ? __do_sys_finit_module+0xaa/0x110
+[ 88.320512] __do_sys_finit_module+0xaa/0x110
+[ 88.320520] do_syscall_64+0x5b/0x180
+[ 88.320525] entry_SYSCALL_64_after_hwframe+0x44/0xa9
+[ 88.320528] RIP: 0033:0x7f8d8d1f01fd
+[ 88.320532] Code: 00 c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 5b 8c 0c 00 f7 d8 64 89 01 48
+[ 88.320535] RSP: 002b:00007ffefa3bb068 EFLAGS: 00000246 ORIG_RAX: 0000000000000139
+[ 88.320539] RAX: ffffffffffffffda RBX: 000055922040cb40 RCX: 00007f8d8d1f01fd
+[ 88.320541] RDX: 0000000000000000 RSI: 00007f8d8ce4984d RDI: 0000000000000006
+[ 88.320543] RBP: 0000000000020000 R08: 0000000000000000 R09: 0000000000000007
+[ 88.320545] R10: 0000000000000006 R11: 0000000000000246 R12: 00007f8d8ce4984d
+[ 88.320547] R13: 0000000000000000 R14: 000055922040efc0 R15: 000055922040cb40
+[ 88.320551] Modules linked in: hid_logitech_hidpp(+) fuse rfcomm ccm xt_CHECKSUM xt_MASQUERADE bridge stp llc nf_nat_tftp nf_conntrack_tftp nf_conntrack_netbios_ns nf_conntrack_broadcast xt_CT ip6t_rpfilter ip6t_REJECT nf_reject_ipv6 xt_conntrack ebtable_nat ip6table_nat ip6table_mangle ip6table_raw ip6table_security iptable_nat nf_nat tun iptable_mangle iptable_raw iptable_security nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 libcrc32c ip_set nfnetlink ebtable_filter ebtables ip6table_filter ip6_tables cmac bnep sunrpc dm_crypt nls_utf8 hfsplus intel_rapl_msr intel_rapl_common ath9k_htc ath9k_common x86_pkg_temp_thermal intel_powerclamp b43 ath9k_hw coretemp snd_hda_codec_hdmi cordic kvm_intel snd_hda_codec_cirrus mac80211 snd_hda_codec_generic ledtrig_audio kvm snd_hda_intel snd_intel_nhlt irqbypass snd_hda_codec btusb btrtl snd_hda_core ath btbcm ssb snd_hwdep btintel snd_seq crct10dif_pclmul iTCO_wdt snd_seq_device crc32_pclmul bluetooth mmc_core iTCO_vendor_support joydev cfg80211
+[ 88.320602] applesmc ghash_clmulni_intel ecdh_generic snd_pcm input_polldev intel_cstate ecc intel_uncore thunderbolt snd_timer i2c_i801 libarc4 rfkill intel_rapl_perf lpc_ich mei_me pcspkr bcm5974 snd bcma mei soundcore acpi_als sbs kfifo_buf sbshc industrialio apple_bl i915 i2c_algo_bit drm_kms_helper drm uas crc32c_intel usb_storage video hid_apple
+[ 88.320630] CR2: 0000000000000018
+[ 88.320633] ---[ end trace 933491c8a4fadeb7 ]---
+[ 88.320642] RIP: 0010:hidpp_probe+0x61f/0x948 [hid_logitech_hidpp]
+[ 88.320645] Code: 81 00 00 48 89 ef e8 f0 d6 ff ff 41 89 c6 85 c0 75 b5 0f b6 44 24 28 48 8b 5d 00 88 44 24 1e 89 44 24 0c 48 8b 83 18 1c 00 00 <48> 8b 48 18 48 8b 83 10 19 00 00 48 8b 40 40 48 89 0c 24 0f b7 80
+[ 88.320647] RSP: 0018:ffffb0a6824aba68 EFLAGS: 00010246
+[ 88.320650] RAX: 0000000000000000 RBX: ffff93a50756e000 RCX: 0000000000010408
+[ 88.320652] RDX: 0000000000000000 RSI: ffff93a51f0ad0a0 RDI: 000000000002d0a0
+[ 88.320655] RBP: ffff93a50416da28 R08: ffff93a50416da70 R09: ffff93a50416da70
+[ 88.320657] R10: 000000148ae9e60c R11: 00000000000f1525 R12: ffff93a50756e000
+[ 88.320659] R13: ffff93a50756f8d0 R14: 0000000000000000 R15: ffff93a50756fc38
+[ 88.320662] FS: 00007f8d8c1e0940(0000) GS:ffff93a51f080000(0000) knlGS:0000000000000000
+[ 88.320664] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[ 88.320667] CR2: 0000000000000018 CR3: 00000003996d8003 CR4: 00000000001606e0
+
+To solve this issue:
+
+ 1. Split g920_get_config() such that all of the device specific
+ communication remains a part of the function and input subsystem
+ initialization bits go to hidpp_ff_init()
+
+ 2. Move call to hidpp_ff_init() from being a part of
+ g920_get_config() to be the last step of .probe(), right after a
+ call to hid_hw_start() with connect_mask containing
+ HID_CONNECT_HIDINPUT.
+
+Fixes: 91cf9a98ae41 ("HID: logitech-hidpp: make .probe usbhid capable")
+Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
+Tested-by: Sam Bazley <sambazley@fastmail.com>
+Cc: Jiri Kosina <jikos@kernel.org>
+Cc: Benjamin Tissoires <benjamin.tissoires@redhat.com>
+Cc: Henrik Rydberg <rydberg@bitmath.org>
+Cc: Pierre-Loup A. Griffais <pgriffais@valvesoftware.com>
+Cc: Austin Palmer <austinp@valvesoftware.com>
+Cc: linux-input@vger.kernel.org
+Cc: linux-kernel@vger.kernel.org
+Cc: stable@vger.kernel.org # 5.2+
+Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/hid/hid-logitech-hidpp.c | 150 ++++++++++++++++++++++++---------------
+ 1 file changed, 96 insertions(+), 54 deletions(-)
+
+--- a/drivers/hid/hid-logitech-hidpp.c
++++ b/drivers/hid/hid-logitech-hidpp.c
+@@ -1669,6 +1669,7 @@ static void hidpp_touchpad_raw_xy_event(
+
+ #define HIDPP_FF_EFFECTID_NONE -1
+ #define HIDPP_FF_EFFECTID_AUTOCENTER -2
++#define HIDPP_AUTOCENTER_PARAMS_LENGTH 18
+
+ #define HIDPP_FF_MAX_PARAMS 20
+ #define HIDPP_FF_RESERVED_SLOTS 1
+@@ -2009,7 +2010,7 @@ static int hidpp_ff_erase_effect(struct
+ static void hidpp_ff_set_autocenter(struct input_dev *dev, u16 magnitude)
+ {
+ struct hidpp_ff_private_data *data = dev->ff->private;
+- u8 params[18];
++ u8 params[HIDPP_AUTOCENTER_PARAMS_LENGTH];
+
+ dbg_hid("Setting autocenter to %d.\n", magnitude);
+
+@@ -2081,7 +2082,8 @@ static void hidpp_ff_destroy(struct ff_d
+ kfree(data->effect_ids);
+ }
+
+-static int hidpp_ff_init(struct hidpp_device *hidpp, u8 feature_index)
++static int hidpp_ff_init(struct hidpp_device *hidpp,
++ struct hidpp_ff_private_data *data)
+ {
+ struct hid_device *hid = hidpp->hid_dev;
+ struct hid_input *hidinput;
+@@ -2089,9 +2091,7 @@ static int hidpp_ff_init(struct hidpp_de
+ const struct usb_device_descriptor *udesc = &(hid_to_usb_dev(hid)->descriptor);
+ const u16 bcdDevice = le16_to_cpu(udesc->bcdDevice);
+ struct ff_device *ff;
+- struct hidpp_report response;
+- struct hidpp_ff_private_data *data;
+- int error, j, num_slots;
++ int error, j, num_slots = data->num_effects;
+ u8 version;
+
+ if (list_empty(&hid->inputs)) {
+@@ -2116,27 +2116,17 @@ static int hidpp_ff_init(struct hidpp_de
+ for (j = 0; hidpp_ff_effects_v2[j] >= 0; j++)
+ set_bit(hidpp_ff_effects_v2[j], dev->ffbit);
+
+- /* Read number of slots available in device */
+- error = hidpp_send_fap_command_sync(hidpp, feature_index,
+- HIDPP_FF_GET_INFO, NULL, 0, &response);
+- if (error) {
+- if (error < 0)
+- return error;
+- hid_err(hidpp->hid_dev, "%s: received protocol error 0x%02x\n",
+- __func__, error);
+- return -EPROTO;
+- }
+-
+- num_slots = response.fap.params[0] - HIDPP_FF_RESERVED_SLOTS;
+-
+ error = input_ff_create(dev, num_slots);
+
+ if (error) {
+ hid_err(dev, "Failed to create FF device!\n");
+ return error;
+ }
+-
+- data = kzalloc(sizeof(*data), GFP_KERNEL);
++ /*
++ * Create a copy of passed data, so we can transfer memory
++ * ownership to FF core
++ */
++ data = kmemdup(data, sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+ data->effect_ids = kcalloc(num_slots, sizeof(int), GFP_KERNEL);
+@@ -2152,10 +2142,7 @@ static int hidpp_ff_init(struct hidpp_de
+ }
+
+ data->hidpp = hidpp;
+- data->feature_index = feature_index;
+ data->version = version;
+- data->slot_autocenter = 0;
+- data->num_effects = num_slots;
+ for (j = 0; j < num_slots; j++)
+ data->effect_ids[j] = -1;
+
+@@ -2169,37 +2156,14 @@ static int hidpp_ff_init(struct hidpp_de
+ ff->set_autocenter = hidpp_ff_set_autocenter;
+ ff->destroy = hidpp_ff_destroy;
+
+-
+- /* reset all forces */
+- error = hidpp_send_fap_command_sync(hidpp, feature_index,
+- HIDPP_FF_RESET_ALL, NULL, 0, &response);
+-
+- /* Read current Range */
+- error = hidpp_send_fap_command_sync(hidpp, feature_index,
+- HIDPP_FF_GET_APERTURE, NULL, 0, &response);
+- if (error)
+- hid_warn(hidpp->hid_dev, "Failed to read range from device!\n");
+- data->range = error ? 900 : get_unaligned_be16(&response.fap.params[0]);
+-
+ /* Create sysfs interface */
+ error = device_create_file(&(hidpp->hid_dev->dev), &dev_attr_range);
+ if (error)
+ hid_warn(hidpp->hid_dev, "Unable to create sysfs interface for \"range\", errno %d!\n", error);
+
+- /* Read the current gain values */
+- error = hidpp_send_fap_command_sync(hidpp, feature_index,
+- HIDPP_FF_GET_GLOBAL_GAINS, NULL, 0, &response);
+- if (error)
+- hid_warn(hidpp->hid_dev, "Failed to read gain values from device!\n");
+- data->gain = error ? 0xffff : get_unaligned_be16(&response.fap.params[0]);
+- /* ignore boost value at response.fap.params[2] */
+-
+ /* init the hardware command queue */
+ atomic_set(&data->workqueue_size, 0);
+
+- /* initialize with zero autocenter to get wheel in usable state */
+- hidpp_ff_set_autocenter(dev, 0);
+-
+ hid_info(hid, "Force feedback support loaded (firmware release %d).\n",
+ version);
+
+@@ -2732,24 +2696,93 @@ static int k400_connect(struct hid_devic
+
+ #define HIDPP_PAGE_G920_FORCE_FEEDBACK 0x8123
+
+-static int g920_get_config(struct hidpp_device *hidpp)
++static int g920_ff_set_autocenter(struct hidpp_device *hidpp,
++ struct hidpp_ff_private_data *data)
+ {
++ struct hidpp_report response;
++ u8 params[HIDPP_AUTOCENTER_PARAMS_LENGTH] = {
++ [1] = HIDPP_FF_EFFECT_SPRING | HIDPP_FF_EFFECT_AUTOSTART,
++ };
++ int ret;
++
++ /* initialize with zero autocenter to get wheel in usable state */
++
++ dbg_hid("Setting autocenter to 0.\n");
++ ret = hidpp_send_fap_command_sync(hidpp, data->feature_index,
++ HIDPP_FF_DOWNLOAD_EFFECT,
++ params, ARRAY_SIZE(params),
++ &response);
++ if (ret)
++ hid_warn(hidpp->hid_dev, "Failed to autocenter device!\n");
++ else
++ data->slot_autocenter = response.fap.params[0];
++
++ return ret;
++}
++
++static int g920_get_config(struct hidpp_device *hidpp,
++ struct hidpp_ff_private_data *data)
++{
++ struct hidpp_report response;
+ u8 feature_type;
+- u8 feature_index;
+ int ret;
+
++ memset(data, 0, sizeof(*data));
++
+ /* Find feature and store for later use */
+ ret = hidpp_root_get_feature(hidpp, HIDPP_PAGE_G920_FORCE_FEEDBACK,
+- &feature_index, &feature_type);
++ &data->feature_index, &feature_type);
+ if (ret)
+ return ret;
+
+- ret = hidpp_ff_init(hidpp, feature_index);
++ /* Read number of slots available in device */
++ ret = hidpp_send_fap_command_sync(hidpp, data->feature_index,
++ HIDPP_FF_GET_INFO,
++ NULL, 0,
++ &response);
++ if (ret) {
++ if (ret < 0)
++ return ret;
++ hid_err(hidpp->hid_dev,
++ "%s: received protocol error 0x%02x\n", __func__, ret);
++ return -EPROTO;
++ }
++
++ data->num_effects = response.fap.params[0] - HIDPP_FF_RESERVED_SLOTS;
++
++ /* reset all forces */
++ ret = hidpp_send_fap_command_sync(hidpp, data->feature_index,
++ HIDPP_FF_RESET_ALL,
++ NULL, 0,
++ &response);
+ if (ret)
+- hid_warn(hidpp->hid_dev, "Unable to initialize force feedback support, errno %d\n",
+- ret);
++ hid_warn(hidpp->hid_dev, "Failed to reset all forces!\n");
+
+- return 0;
++ ret = hidpp_send_fap_command_sync(hidpp, data->feature_index,
++ HIDPP_FF_GET_APERTURE,
++ NULL, 0,
++ &response);
++ if (ret) {
++ hid_warn(hidpp->hid_dev,
++ "Failed to read range from device!\n");
++ }
++ data->range = ret ?
++ 900 : get_unaligned_be16(&response.fap.params[0]);
++
++ /* Read the current gain values */
++ ret = hidpp_send_fap_command_sync(hidpp, data->feature_index,
++ HIDPP_FF_GET_GLOBAL_GAINS,
++ NULL, 0,
++ &response);
++ if (ret)
++ hid_warn(hidpp->hid_dev,
++ "Failed to read gain values from device!\n");
++ data->gain = ret ?
++ 0xffff : get_unaligned_be16(&response.fap.params[0]);
++
++ /* ignore boost value at response.fap.params[2] */
++
++ return g920_ff_set_autocenter(hidpp, data);
+ }
+
+ /* -------------------------------------------------------------------------- */
+@@ -3512,6 +3545,7 @@ static int hidpp_probe(struct hid_device
+ int ret;
+ bool connected;
+ unsigned int connect_mask = HID_CONNECT_DEFAULT;
++ struct hidpp_ff_private_data data;
+
+ /* report_fixup needs drvdata to be set before we call hid_parse */
+ hidpp = devm_kzalloc(&hdev->dev, sizeof(*hidpp), GFP_KERNEL);
+@@ -3621,7 +3655,7 @@ static int hidpp_probe(struct hid_device
+ if (ret)
+ goto hid_hw_init_fail;
+ } else if (connected && (hidpp->quirks & HIDPP_QUIRK_CLASS_G920)) {
+- ret = g920_get_config(hidpp);
++ ret = g920_get_config(hidpp, &data);
+ if (ret)
+ goto hid_hw_init_fail;
+ }
+@@ -3643,6 +3677,14 @@ static int hidpp_probe(struct hid_device
+ goto hid_hw_start_fail;
+ }
+
++ if (hidpp->quirks & HIDPP_QUIRK_CLASS_G920) {
++ ret = hidpp_ff_init(hidpp, &data);
++ if (ret)
++ hid_warn(hidpp->hid_dev,
++ "Unable to initialize force feedback support, errno %d\n",
++ ret);
++ }
++
+ return ret;
+
+ hid_hw_init_fail:
--- /dev/null
+From 9ed5bd7d22241ad232fd3a5be404e83eb6cadc04 Mon Sep 17 00:00:00 2001
+From: Kaike Wan <kaike.wan@intel.com>
+Date: Fri, 4 Oct 2019 16:40:35 -0400
+Subject: IB/hfi1: Avoid excessive retry for TID RDMA READ request
+
+From: Kaike Wan <kaike.wan@intel.com>
+
+commit 9ed5bd7d22241ad232fd3a5be404e83eb6cadc04 upstream.
+
+A TID RDMA READ request could be retried under one of the following
+conditions:
+- The RC retry timer expires;
+- A later TID RDMA READ RESP packet is received before the next
+ expected one.
+For the latter, under normal conditions, the PSN in IB space is used
+for comparison. More specifically, the IB PSN in the incoming TID RDMA
+READ RESP packet is compared with the last IB PSN of a given TID RDMA
+READ request to determine if the request should be retried. This is
+similar to the retry logic for noraml RDMA READ request.
+
+However, if a TID RDMA READ RESP packet is lost due to congestion,
+header suppresion will be disabled and each incoming packet will raise
+an interrupt until the hardware flow is reloaded. Under this condition,
+each packet KDETH PSN will be checked by software against r_next_psn
+and a retry will be requested if the packet KDETH PSN is later than
+r_next_psn. Since each TID RDMA READ segment could have up to 64
+packets and each TID RDMA READ request could have many segments, we
+could make far more retries under such conditions, and thus leading to
+RETRY_EXC_ERR status.
+
+This patch fixes the issue by removing the retry when the incoming
+packet KDETH PSN is later than r_next_psn. Instead, it resorts to
+RC timer and normal IB PSN comparison for any request retry.
+
+Fixes: 9905bf06e890 ("IB/hfi1: Add functions to receive TID RDMA READ response")
+Cc: <stable@vger.kernel.org>
+Reviewed-by: Mike Marciniszyn <mike.marciniszyn@intel.com>
+Signed-off-by: Kaike Wan <kaike.wan@intel.com>
+Signed-off-by: Dennis Dalessandro <dennis.dalessandro@intel.com>
+Link: https://lore.kernel.org/r/20191004204035.26542.41684.stgit@awfm-01.aw.intel.com
+Signed-off-by: Doug Ledford <dledford@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/infiniband/hw/hfi1/tid_rdma.c | 5 -----
+ 1 file changed, 5 deletions(-)
+
+--- a/drivers/infiniband/hw/hfi1/tid_rdma.c
++++ b/drivers/infiniband/hw/hfi1/tid_rdma.c
+@@ -2728,11 +2728,6 @@ static bool handle_read_kdeth_eflags(str
+ diff = cmp_psn(psn,
+ flow->flow_state.r_next_psn);
+ if (diff > 0) {
+- if (!(qp->r_flags & RVT_R_RDMAR_SEQ))
+- restart_tid_rdma_read_req(rcd,
+- qp,
+- wqe);
+-
+ /* Drop the packet.*/
+ goto s_unlock;
+ } else if (diff < 0) {
--- /dev/null
+From 6873e0bd6a9cb14ecfadd89d9ed9698ff1761902 Mon Sep 17 00:00:00 2001
+From: Jens Axboe <axboe@kernel.dk>
+Date: Wed, 30 Oct 2019 13:53:09 -0600
+Subject: io_uring: ensure we clear io_kiocb->result before each issue
+
+From: Jens Axboe <axboe@kernel.dk>
+
+commit 6873e0bd6a9cb14ecfadd89d9ed9698ff1761902 upstream.
+
+We use io_kiocb->result == -EAGAIN as a way to know if we need to
+re-submit a polled request, as -EAGAIN reporting happens out-of-line
+for IO submission failures. This field is cleared when we originally
+allocate the request, but it isn't reset when we retry the submission
+from async context. This can cause issues where we think something
+needs a re-issue, but we're really just reading stale data.
+
+Reset ->result whenever we re-prep a request for polled submission.
+
+Cc: stable@vger.kernel.org
+Fixes: 9e645e1105ca ("io_uring: add support for sqe links")
+Reported-by: Bijan Mottahedeh <bijan.mottahedeh@oracle.com>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/io_uring.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/fs/io_uring.c
++++ b/fs/io_uring.c
+@@ -1078,6 +1078,7 @@ static int io_prep_rw(struct io_kiocb *r
+
+ kiocb->ki_flags |= IOCB_HIPRI;
+ kiocb->ki_complete = io_complete_rw_iopoll;
++ req->result = 0;
+ } else {
+ if (kiocb->ki_flags & IOCB_HIPRI)
+ return -EINVAL;
--- /dev/null
+From 160c63f909ffbc797c0bbe23310ac1eaf2349d2f Mon Sep 17 00:00:00 2001
+From: John Donnelly <John.P.Donnelly@Oracle.com>
+Date: Mon, 21 Oct 2019 21:48:10 -0500
+Subject: iommu/vt-d: Fix panic after kexec -p for kdump
+
+From: John Donnelly <John.P.Donnelly@Oracle.com>
+
+commit 160c63f909ffbc797c0bbe23310ac1eaf2349d2f upstream.
+
+This cures a panic on restart after a kexec operation on 5.3 and 5.4
+kernels.
+
+The underlying state of the iommu registers (iommu->flags &
+VTD_FLAG_TRANS_PRE_ENABLED) on a restart results in a domain being marked as
+"DEFER_DEVICE_DOMAIN_INFO" that produces an Oops in identity_mapping().
+
+[ 43.654737] BUG: kernel NULL pointer dereference, address:
+0000000000000056
+[ 43.655720] #PF: supervisor read access in kernel mode
+[ 43.655720] #PF: error_code(0x0000) - not-present page
+[ 43.655720] PGD 0 P4D 0
+[ 43.655720] Oops: 0000 [#1] SMP PTI
+[ 43.655720] CPU: 0 PID: 1 Comm: swapper/0 Not tainted
+5.3.2-1940.el8uek.x86_64 #1
+[ 43.655720] Hardware name: Oracle Corporation ORACLE SERVER
+X5-2/ASM,MOTHERBOARD,1U, BIOS 30140300 09/20/2018
+[ 43.655720] RIP: 0010:iommu_need_mapping+0x29/0xd0
+[ 43.655720] Code: 00 0f 1f 44 00 00 48 8b 97 70 02 00 00 48 83 fa ff
+74 53 48 8d 4a ff b8 01 00 00 00 48 83 f9 fd 76 01 c3 48 8b 35 7f 58 e0
+01 <48> 39 72 58 75 f2 55 48 89 e5 41 54 53 48 8b 87 28 02 00 00 4c 8b
+[ 43.655720] RSP: 0018:ffffc9000001b9b0 EFLAGS: 00010246
+[ 43.655720] RAX: 0000000000000001 RBX: 0000000000001000 RCX:
+fffffffffffffffd
+[ 43.655720] RDX: fffffffffffffffe RSI: ffff8880719b8000 RDI:
+ffff8880477460b0
+[ 43.655720] RBP: ffffc9000001b9e8 R08: 0000000000000000 R09:
+ffff888047c01700
+[ 43.655720] R10: 00002194036fc692 R11: 0000000000000000 R12:
+0000000000000000
+[ 43.655720] R13: ffff8880477460b0 R14: 0000000000000cc0 R15:
+ffff888072d2b558
+[ 43.655720] FS: 0000000000000000(0000) GS:ffff888071c00000(0000)
+knlGS:0000000000000000
+[ 43.655720] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[ 43.655720] CR2: 0000000000000056 CR3: 000000007440a002 CR4:
+00000000001606b0
+[ 43.655720] Call Trace:
+[ 43.655720] ? intel_alloc_coherent+0x2a/0x180
+[ 43.655720] ? __schedule+0x2c2/0x650
+[ 43.655720] dma_alloc_attrs+0x8c/0xd0
+[ 43.655720] dma_pool_alloc+0xdf/0x200
+[ 43.655720] ehci_qh_alloc+0x58/0x130
+[ 43.655720] ehci_setup+0x287/0x7ba
+[ 43.655720] ? _dev_info+0x6c/0x83
+[ 43.655720] ehci_pci_setup+0x91/0x436
+[ 43.655720] usb_add_hcd.cold.48+0x1d4/0x754
+[ 43.655720] usb_hcd_pci_probe+0x2bc/0x3f0
+[ 43.655720] ehci_pci_probe+0x39/0x40
+[ 43.655720] local_pci_probe+0x47/0x80
+[ 43.655720] pci_device_probe+0xff/0x1b0
+[ 43.655720] really_probe+0xf5/0x3a0
+[ 43.655720] driver_probe_device+0xbb/0x100
+[ 43.655720] device_driver_attach+0x58/0x60
+[ 43.655720] __driver_attach+0x8f/0x150
+[ 43.655720] ? device_driver_attach+0x60/0x60
+[ 43.655720] bus_for_each_dev+0x74/0xb0
+[ 43.655720] driver_attach+0x1e/0x20
+[ 43.655720] bus_add_driver+0x151/0x1f0
+[ 43.655720] ? ehci_hcd_init+0xb2/0xb2
+[ 43.655720] ? do_early_param+0x95/0x95
+[ 43.655720] driver_register+0x70/0xc0
+[ 43.655720] ? ehci_hcd_init+0xb2/0xb2
+[ 43.655720] __pci_register_driver+0x57/0x60
+[ 43.655720] ehci_pci_init+0x6a/0x6c
+[ 43.655720] do_one_initcall+0x4a/0x1fa
+[ 43.655720] ? do_early_param+0x95/0x95
+[ 43.655720] kernel_init_freeable+0x1bd/0x262
+[ 43.655720] ? rest_init+0xb0/0xb0
+[ 43.655720] kernel_init+0xe/0x110
+[ 43.655720] ret_from_fork+0x24/0x50
+
+Fixes: 8af46c784ecfe ("iommu/vt-d: Implement is_attach_deferred iommu ops entry")
+Cc: stable@vger.kernel.org # v5.3+
+
+Signed-off-by: John Donnelly <john.p.donnelly@oracle.com>
+Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com>
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iommu/intel-iommu.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/iommu/intel-iommu.c
++++ b/drivers/iommu/intel-iommu.c
+@@ -2783,7 +2783,7 @@ static int identity_mapping(struct devic
+ struct device_domain_info *info;
+
+ info = dev->archdata.iommu;
+- if (info && info != DUMMY_DEVICE_DOMAIN_INFO)
++ if (info && info != DUMMY_DEVICE_DOMAIN_INFO && info != DEFER_DEVICE_DOMAIN_INFO)
+ return (info->domain == si_domain);
+
+ return 0;
--- /dev/null
+From 9167ab79936206118cc60e47dcb926c3489f3bd5 Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Sun, 27 Oct 2019 16:23:23 +0100
+Subject: KVM: vmx, svm: always run with EFER.NXE=1 when shadow paging is active
+
+From: Paolo Bonzini <pbonzini@redhat.com>
+
+commit 9167ab79936206118cc60e47dcb926c3489f3bd5 upstream.
+
+VMX already does so if the host has SMEP, in order to support the combination of
+CR0.WP=1 and CR4.SMEP=1. However, it is perfectly safe to always do so, and in
+fact VMX already ends up running with EFER.NXE=1 on old processors that lack the
+"load EFER" controls, because it may help avoiding a slow MSR write. Removing
+all the conditionals simplifies the code.
+
+SVM does not have similar code, but it should since recent AMD processors do
+support SMEP. So this patch also makes the code for the two vendors more similar
+while fixing NPT=0, CR0.WP=1 and CR4.SMEP=1 on AMD processors.
+
+Cc: stable@vger.kernel.org
+Cc: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/kvm/svm.c | 10 ++++++++--
+ arch/x86/kvm/vmx/vmx.c | 14 +++-----------
+ 2 files changed, 11 insertions(+), 13 deletions(-)
+
+--- a/arch/x86/kvm/svm.c
++++ b/arch/x86/kvm/svm.c
+@@ -736,8 +736,14 @@ static int get_npt_level(struct kvm_vcpu
+ static void svm_set_efer(struct kvm_vcpu *vcpu, u64 efer)
+ {
+ vcpu->arch.efer = efer;
+- if (!npt_enabled && !(efer & EFER_LMA))
+- efer &= ~EFER_LME;
++
++ if (!npt_enabled) {
++ /* Shadow paging assumes NX to be available. */
++ efer |= EFER_NX;
++
++ if (!(efer & EFER_LMA))
++ efer &= ~EFER_LME;
++ }
+
+ to_svm(vcpu)->vmcb->save.efer = efer | EFER_SVME;
+ mark_dirty(to_svm(vcpu)->vmcb, VMCB_CR);
+--- a/arch/x86/kvm/vmx/vmx.c
++++ b/arch/x86/kvm/vmx/vmx.c
+@@ -897,17 +897,9 @@ static bool update_transition_efer(struc
+ u64 guest_efer = vmx->vcpu.arch.efer;
+ u64 ignore_bits = 0;
+
+- if (!enable_ept) {
+- /*
+- * NX is needed to handle CR0.WP=1, CR4.SMEP=1. Testing
+- * host CPUID is more efficient than testing guest CPUID
+- * or CR4. Host SMEP is anyway a requirement for guest SMEP.
+- */
+- if (boot_cpu_has(X86_FEATURE_SMEP))
+- guest_efer |= EFER_NX;
+- else if (!(guest_efer & EFER_NX))
+- ignore_bits |= EFER_NX;
+- }
++ /* Shadow paging assumes NX to be available. */
++ if (!enable_ept)
++ guest_efer |= EFER_NX;
+
+ /*
+ * LMA and LME handled by hardware; SCE meaningless outside long mode.
--- /dev/null
+From 79cc55422ce99be5964bde208ba8557174720893 Mon Sep 17 00:00:00 2001
+From: Trond Myklebust <trondmy@gmail.com>
+Date: Thu, 31 Oct 2019 18:40:33 -0400
+Subject: NFS: Fix an RCU lock leak in nfs4_refresh_delegation_stateid()
+
+From: Trond Myklebust <trondmy@gmail.com>
+
+commit 79cc55422ce99be5964bde208ba8557174720893 upstream.
+
+A typo in nfs4_refresh_delegation_stateid() means we're leaking an
+RCU lock, and always returning a value of 'false'. As the function
+description states, we were always supposed to return 'true' if a
+matching delegation was found.
+
+Fixes: 12f275cdd163 ("NFSv4: Retry CLOSE and DELEGRETURN on NFS4ERR_OLD_STATEID.")
+Cc: stable@vger.kernel.org # v4.15+
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/nfs/delegation.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/nfs/delegation.c
++++ b/fs/nfs/delegation.c
+@@ -1181,7 +1181,7 @@ bool nfs4_refresh_delegation_stateid(nfs
+ if (delegation != NULL &&
+ nfs4_stateid_match_other(dst, &delegation->stateid)) {
+ dst->seqid = delegation->stateid.seqid;
+- return ret;
++ ret = true;
+ }
+ rcu_read_unlock();
+ out:
--- /dev/null
+From 8c55dedb795be8ec0cf488f98c03a1c2176f7fb1 Mon Sep 17 00:00:00 2001
+From: Laura Abbott <labbott@redhat.com>
+Date: Fri, 18 Oct 2019 07:43:21 -0400
+Subject: rtlwifi: Fix potential overflow on P2P code
+
+From: Laura Abbott <labbott@redhat.com>
+
+commit 8c55dedb795be8ec0cf488f98c03a1c2176f7fb1 upstream.
+
+Nicolas Waisman noticed that even though noa_len is checked for
+a compatible length it's still possible to overrun the buffers
+of p2pinfo since there's no check on the upper bound of noa_num.
+Bound noa_num against P2P_MAX_NOA_NUM.
+
+Reported-by: Nicolas Waisman <nico@semmle.com>
+Signed-off-by: Laura Abbott <labbott@redhat.com>
+Acked-by: Ping-Ke Shih <pkshih@realtek.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/realtek/rtlwifi/ps.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/drivers/net/wireless/realtek/rtlwifi/ps.c
++++ b/drivers/net/wireless/realtek/rtlwifi/ps.c
+@@ -754,6 +754,9 @@ static void rtl_p2p_noa_ie(struct ieee80
+ return;
+ } else {
+ noa_num = (noa_len - 2) / 13;
++ if (noa_num > P2P_MAX_NOA_NUM)
++ noa_num = P2P_MAX_NOA_NUM;
++
+ }
+ noa_index = ie[3];
+ if (rtlpriv->psc.p2p_ps_info.p2p_ps_mode ==
+@@ -848,6 +851,9 @@ static void rtl_p2p_action_ie(struct iee
+ return;
+ } else {
+ noa_num = (noa_len - 2) / 13;
++ if (noa_num > P2P_MAX_NOA_NUM)
++ noa_num = P2P_MAX_NOA_NUM;
++
+ }
+ noa_index = ie[3];
+ if (rtlpriv->psc.p2p_ps_info.p2p_ps_mode ==
--- /dev/null
+From b43f4a169f220e459edf3ea8f8cd3ec4ae7fa82d Mon Sep 17 00:00:00 2001
+From: Larry Finger <Larry.Finger@lwfinger.net>
+Date: Sun, 20 Oct 2019 19:56:58 -0500
+Subject: rtlwifi: rtl_pci: Fix problem of too small skb->len
+
+From: Larry Finger <Larry.Finger@lwfinger.net>
+
+commit b43f4a169f220e459edf3ea8f8cd3ec4ae7fa82d upstream.
+
+In commit 8020919a9b99 ("mac80211: Properly handle SKB with radiotap
+only"), buffers whose length is too short cause a WARN_ON(1) to be
+executed. This change exposed a fault in rtlwifi drivers, which is fixed
+by regarding packets with skb->len <= FCS_LEN as though they are in error
+and dropping them. The test is now annotated as likely.
+
+Cc: Stable <stable@vger.kernel.org> # v5.0+
+Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/realtek/rtlwifi/pci.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/realtek/rtlwifi/pci.c
++++ b/drivers/net/wireless/realtek/rtlwifi/pci.c
+@@ -822,7 +822,7 @@ static void _rtl_pci_rx_interrupt(struct
+ hdr = rtl_get_hdr(skb);
+ fc = rtl_get_fc(skb);
+
+- if (!stats.crc && !stats.hwerror) {
++ if (!stats.crc && !stats.hwerror && (skb->len > FCS_LEN)) {
+ memcpy(IEEE80211_SKB_RXCB(skb), &rx_status,
+ sizeof(rx_status));
+
+@@ -859,6 +859,7 @@ static void _rtl_pci_rx_interrupt(struct
+ _rtl_pci_rx_to_mac80211(hw, skb, rx_status);
+ }
+ } else {
++ /* drop packets with errors or those too short */
+ dev_kfree_skb_any(skb);
+ }
+ new_trx_end:
--- /dev/null
+From b8e51a6a9db94bc1fb18ae831b3dab106b5a4b5f Mon Sep 17 00:00:00 2001
+From: Yihui ZENG <yzeng56@asu.edu>
+Date: Fri, 25 Oct 2019 12:31:48 +0300
+Subject: s390/cmm: fix information leak in cmm_timeout_handler()
+
+From: Yihui ZENG <yzeng56@asu.edu>
+
+commit b8e51a6a9db94bc1fb18ae831b3dab106b5a4b5f upstream.
+
+The problem is that we were putting the NUL terminator too far:
+
+ buf[sizeof(buf) - 1] = '\0';
+
+If the user input isn't NUL terminated and they haven't initialized the
+whole buffer then it leads to an info leak. The NUL terminator should
+be:
+
+ buf[len - 1] = '\0';
+
+Signed-off-by: Yihui Zeng <yzeng56@asu.edu>
+Cc: stable@vger.kernel.org
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+[heiko.carstens@de.ibm.com: keep semantics of how *lenp and *ppos are handled]
+Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
+Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/s390/mm/cmm.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+--- a/arch/s390/mm/cmm.c
++++ b/arch/s390/mm/cmm.c
+@@ -298,16 +298,16 @@ static int cmm_timeout_handler(struct ct
+ }
+
+ if (write) {
+- len = *lenp;
+- if (copy_from_user(buf, buffer,
+- len > sizeof(buf) ? sizeof(buf) : len))
++ len = min(*lenp, sizeof(buf));
++ if (copy_from_user(buf, buffer, len))
+ return -EFAULT;
+- buf[sizeof(buf) - 1] = '\0';
++ buf[len - 1] = '\0';
+ cmm_skip_blanks(buf, &p);
+ nr = simple_strtoul(p, &p, 0);
+ cmm_skip_blanks(p, &p);
+ seconds = simple_strtoul(p, &p, 0);
+ cmm_set_timeout(nr, seconds);
++ *ppos += *lenp;
+ } else {
+ len = sprintf(buf, "%ld %ld\n",
+ cmm_timeout_pages, cmm_timeout_seconds);
+@@ -315,9 +315,9 @@ static int cmm_timeout_handler(struct ct
+ len = *lenp;
+ if (copy_to_user(buffer, buf, len))
+ return -EFAULT;
++ *lenp = len;
++ *ppos += len;
+ }
+- *lenp = len;
+- *ppos += len;
+ return 0;
+ }
+
--- /dev/null
+From 3d7efa4edd07be5c5c3ffa95ba63e97e070e1f3f Mon Sep 17 00:00:00 2001
+From: Heiko Carstens <heiko.carstens@de.ibm.com>
+Date: Mon, 28 Oct 2019 11:03:27 +0100
+Subject: s390/idle: fix cpu idle time calculation
+
+From: Heiko Carstens <heiko.carstens@de.ibm.com>
+
+commit 3d7efa4edd07be5c5c3ffa95ba63e97e070e1f3f upstream.
+
+The idle time reported in /proc/stat sometimes incorrectly contains
+huge values on s390. This is caused by a bug in arch_cpu_idle_time().
+
+The kernel tries to figure out when a different cpu entered idle by
+accessing its per-cpu data structure. There is an ordering problem: if
+the remote cpu has an idle_enter value which is not zero, and an
+idle_exit value which is zero, it is assumed it is idle since
+"now". The "now" timestamp however is taken before the idle_enter
+value is read.
+
+Which in turn means that "now" can be smaller than idle_enter of the
+remote cpu. Unconditionally subtracting idle_enter from "now" can thus
+lead to a negative value (aka large unsigned value).
+
+Fix this by moving the get_tod_clock() invocation out of the
+loop. While at it also make the code a bit more readable.
+
+A similar bug also exists for show_idle_time(). Fix this is as well.
+
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
+Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/s390/kernel/idle.c | 29 ++++++++++++++++++++++-------
+ 1 file changed, 22 insertions(+), 7 deletions(-)
+
+--- a/arch/s390/kernel/idle.c
++++ b/arch/s390/kernel/idle.c
+@@ -69,18 +69,26 @@ DEVICE_ATTR(idle_count, 0444, show_idle_
+ static ssize_t show_idle_time(struct device *dev,
+ struct device_attribute *attr, char *buf)
+ {
++ unsigned long long now, idle_time, idle_enter, idle_exit, in_idle;
+ struct s390_idle_data *idle = &per_cpu(s390_idle, dev->id);
+- unsigned long long now, idle_time, idle_enter, idle_exit;
+ unsigned int seq;
+
+ do {
+- now = get_tod_clock();
+ seq = read_seqcount_begin(&idle->seqcount);
+ idle_time = READ_ONCE(idle->idle_time);
+ idle_enter = READ_ONCE(idle->clock_idle_enter);
+ idle_exit = READ_ONCE(idle->clock_idle_exit);
+ } while (read_seqcount_retry(&idle->seqcount, seq));
+- idle_time += idle_enter ? ((idle_exit ? : now) - idle_enter) : 0;
++ in_idle = 0;
++ now = get_tod_clock();
++ if (idle_enter) {
++ if (idle_exit) {
++ in_idle = idle_exit - idle_enter;
++ } else if (now > idle_enter) {
++ in_idle = now - idle_enter;
++ }
++ }
++ idle_time += in_idle;
+ return sprintf(buf, "%llu\n", idle_time >> 12);
+ }
+ DEVICE_ATTR(idle_time_us, 0444, show_idle_time, NULL);
+@@ -88,17 +96,24 @@ DEVICE_ATTR(idle_time_us, 0444, show_idl
+ u64 arch_cpu_idle_time(int cpu)
+ {
+ struct s390_idle_data *idle = &per_cpu(s390_idle, cpu);
+- unsigned long long now, idle_enter, idle_exit;
++ unsigned long long now, idle_enter, idle_exit, in_idle;
+ unsigned int seq;
+
+ do {
+- now = get_tod_clock();
+ seq = read_seqcount_begin(&idle->seqcount);
+ idle_enter = READ_ONCE(idle->clock_idle_enter);
+ idle_exit = READ_ONCE(idle->clock_idle_exit);
+ } while (read_seqcount_retry(&idle->seqcount, seq));
+-
+- return cputime_to_nsecs(idle_enter ? ((idle_exit ?: now) - idle_enter) : 0);
++ in_idle = 0;
++ now = get_tod_clock();
++ if (idle_enter) {
++ if (idle_exit) {
++ in_idle = idle_exit - idle_enter;
++ } else if (now > idle_enter) {
++ in_idle = now - idle_enter;
++ }
++ }
++ return cputime_to_nsecs(in_idle);
+ }
+
+ void arch_cpu_idle_enter(void)
--- /dev/null
+From a1d863ac3e1085e1fea9caafd87252d08731de2e Mon Sep 17 00:00:00 2001
+From: Ilya Leoshkevich <iii@linux.ibm.com>
+Date: Wed, 2 Oct 2019 13:29:57 +0200
+Subject: s390/unwind: fix mixing regs and sp
+
+From: Ilya Leoshkevich <iii@linux.ibm.com>
+
+commit a1d863ac3e1085e1fea9caafd87252d08731de2e upstream.
+
+unwind_for_each_frame stops after the first frame if regs->gprs[15] <=
+sp.
+
+The reason is that in case regs are specified, the first frame should be
+regs->psw.addr and the second frame should be sp->gprs[8]. However,
+currently the second frame is regs->gprs[15], which confuses
+outside_of_stack().
+
+Fix by introducing a flag to distinguish this special case from
+unwinding the interrupt handler, for which the current behavior is
+appropriate.
+
+Fixes: 78c98f907413 ("s390/unwind: introduce stack unwind API")
+Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
+Cc: stable@vger.kernel.org # v5.2+
+Reviewed-by: Heiko Carstens <heiko.carstens@de.ibm.com>
+Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/s390/include/asm/unwind.h | 1 +
+ arch/s390/kernel/unwind_bc.c | 18 +++++++++++++-----
+ 2 files changed, 14 insertions(+), 5 deletions(-)
+
+--- a/arch/s390/include/asm/unwind.h
++++ b/arch/s390/include/asm/unwind.h
+@@ -35,6 +35,7 @@ struct unwind_state {
+ struct task_struct *task;
+ struct pt_regs *regs;
+ unsigned long sp, ip;
++ bool reuse_sp;
+ int graph_idx;
+ bool reliable;
+ bool error;
+--- a/arch/s390/kernel/unwind_bc.c
++++ b/arch/s390/kernel/unwind_bc.c
+@@ -46,10 +46,15 @@ bool unwind_next_frame(struct unwind_sta
+
+ regs = state->regs;
+ if (unlikely(regs)) {
+- sp = READ_ONCE_NOCHECK(regs->gprs[15]);
+- if (unlikely(outside_of_stack(state, sp))) {
+- if (!update_stack_info(state, sp))
+- goto out_err;
++ if (state->reuse_sp) {
++ sp = state->sp;
++ state->reuse_sp = false;
++ } else {
++ sp = READ_ONCE_NOCHECK(regs->gprs[15]);
++ if (unlikely(outside_of_stack(state, sp))) {
++ if (!update_stack_info(state, sp))
++ goto out_err;
++ }
+ }
+ sf = (struct stack_frame *) sp;
+ ip = READ_ONCE_NOCHECK(sf->gprs[8]);
+@@ -107,9 +112,9 @@ void __unwind_start(struct unwind_state
+ {
+ struct stack_info *info = &state->stack_info;
+ unsigned long *mask = &state->stack_mask;
++ bool reliable, reuse_sp;
+ struct stack_frame *sf;
+ unsigned long ip;
+- bool reliable;
+
+ memset(state, 0, sizeof(*state));
+ state->task = task;
+@@ -134,10 +139,12 @@ void __unwind_start(struct unwind_state
+ if (regs) {
+ ip = READ_ONCE_NOCHECK(regs->psw.addr);
+ reliable = true;
++ reuse_sp = true;
+ } else {
+ sf = (struct stack_frame *) sp;
+ ip = READ_ONCE_NOCHECK(sf->gprs[8]);
+ reliable = false;
++ reuse_sp = false;
+ }
+
+ #ifdef CONFIG_FUNCTION_GRAPH_TRACER
+@@ -151,5 +158,6 @@ void __unwind_start(struct unwind_state
+ state->sp = sp;
+ state->ip = ip;
+ state->reliable = reliable;
++ state->reuse_sp = reuse_sp;
+ }
+ EXPORT_SYMBOL_GPL(__unwind_start);
hid-i2c-hid-add-trekstor-primebook-c11b-to-descriptor-override.patch
hid-fix-assumption-that-devices-have-inputs.patch
hid-fix-error-message-in-hid_open_report.patch
+hid-logitech-hidpp-split-g920_get_config.patch
+hid-logitech-hidpp-rework-device-validation.patch
+hid-logitech-hidpp-do-all-ff-cleanup-in-hidpp_ff_destroy.patch
+um-ubd-entrust-re-queue-to-the-upper-layers.patch
+s390-unwind-fix-mixing-regs-and-sp.patch
+s390-cmm-fix-information-leak-in-cmm_timeout_handler.patch
+s390-idle-fix-cpu-idle-time-calculation.patch
+arc-perf-accommodate-big-endian-cpu.patch
+ib-hfi1-avoid-excessive-retry-for-tid-rdma-read-request.patch
+arm64-ensure-vm_write-vm_shared-ptes-are-clean-by-default.patch
+arm64-cpufeature-enable-qualcomm-falkor-kryo-errata-1003.patch
+virtio_ring-fix-stalls-for-packed-rings.patch
+rtlwifi-rtl_pci-fix-problem-of-too-small-skb-len.patch
+rtlwifi-fix-potential-overflow-on-p2p-code.patch
+kvm-vmx-svm-always-run-with-efer.nxe-1-when-shadow-paging-is-active.patch
+dmaengine-qcom-bam_dma-fix-resource-leak.patch
+dmaengine-tegra210-adma-fix-transfer-failure.patch
+dmaengine-imx-sdma-fix-size-check-for-sdma-script_number.patch
+dmaengine-cppi41-fix-cppi41_dma_prep_slave_sg-when-idle.patch
+drm-amdgpu-gmc10-properly-set-bank_select-and-fragment_size.patch
+drm-i915-fix-pch-reference-clock-for-fdi-on-hsw-bdw.patch
+drm-amdgpu-gfx10-update-gfx-golden-settings.patch
+drm-amdgpu-powerplay-vega10-allow-undervolting-in-p7.patch
+drm-amdgpu-fix-sdma-hang-when-performing-vkexample-test.patch
+nfs-fix-an-rcu-lock-leak-in-nfs4_refresh_delegation_stateid.patch
+io_uring-ensure-we-clear-io_kiocb-result-before-each-issue.patch
+iommu-vt-d-fix-panic-after-kexec-p-for-kdump.patch
--- /dev/null
+From d848074b2f1eb11a38691285f7366bce83087014 Mon Sep 17 00:00:00 2001
+From: Anton Ivanov <anton.ivanov@cambridgegreys.com>
+Date: Tue, 29 Oct 2019 09:13:34 +0000
+Subject: um-ubd: Entrust re-queue to the upper layers
+
+From: Anton Ivanov <anton.ivanov@cambridgegreys.com>
+
+commit d848074b2f1eb11a38691285f7366bce83087014 upstream.
+
+Fixes crashes due to ubd requeue logic conflicting with the block-mq
+logic. Crash is reproducible in 5.0 - 5.3.
+
+Fixes: 53766defb8c8 ("um: Clean-up command processing in UML UBD driver")
+Cc: stable@vger.kernel.org # v5.0+
+Signed-off-by: Anton Ivanov <anton.ivanov@cambridgegreys.com>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/um/drivers/ubd_kern.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+--- a/arch/um/drivers/ubd_kern.c
++++ b/arch/um/drivers/ubd_kern.c
+@@ -1403,8 +1403,12 @@ static blk_status_t ubd_queue_rq(struct
+
+ spin_unlock_irq(&ubd_dev->lock);
+
+- if (ret < 0)
+- blk_mq_requeue_request(req, true);
++ if (ret < 0) {
++ if (ret == -ENOMEM)
++ res = BLK_STS_RESOURCE;
++ else
++ res = BLK_STS_DEV_RESOURCE;
++ }
+
+ return res;
+ }
--- /dev/null
+From 40ce7919d8730f5936da2bc8a21b46bd07db6411 Mon Sep 17 00:00:00 2001
+From: Marvin Liu <yong.liu@intel.com>
+Date: Tue, 22 Oct 2019 01:10:04 +0800
+Subject: virtio_ring: fix stalls for packed rings
+
+From: Marvin Liu <yong.liu@intel.com>
+
+commit 40ce7919d8730f5936da2bc8a21b46bd07db6411 upstream.
+
+When VIRTIO_F_RING_EVENT_IDX is negotiated, virtio devices can
+use virtqueue_enable_cb_delayed_packed to reduce the number of device
+interrupts. At the moment, this is the case for virtio-net when the
+napi_tx module parameter is set to false.
+
+In this case, the virtio driver selects an event offset and expects that
+the device will send a notification when rolling over the event offset
+in the ring. However, if this roll-over happens before the event
+suppression structure update, the notification won't be sent. To address
+this race condition the driver needs to check wether the device rolled
+over the offset after updating the event suppression structure.
+
+With VIRTIO_F_RING_PACKED, the virtio driver did this by reading the
+flags field of the descriptor at the specified offset.
+
+Unfortunately, checking at the event offset isn't reliable: if
+descriptors are chained (e.g. when INDIRECT is off) not all descriptors
+are overwritten by the device, so it's possible that the device skipped
+the specific descriptor driver is checking when writing out used
+descriptors. If this happens, the driver won't detect the race condition
+and will incorrectly expect the device to send a notification.
+
+For virtio-net, the result will be a TX queue stall, with the
+transmission getting blocked forever.
+
+With the packed ring, it isn't easy to find a location which is
+guaranteed to change upon the roll-over, except the next device
+descriptor, as described in the spec:
+
+ Writes of device and driver descriptors can generally be
+ reordered, but each side (driver and device) are only required to
+ poll (or test) a single location in memory: the next device descriptor after
+ the one they processed previously, in circular order.
+
+while this might be sub-optimal, let's do exactly this for now.
+
+Cc: stable@vger.kernel.org
+Cc: Jason Wang <jasowang@redhat.com>
+Fixes: f51f982682e2a ("virtio_ring: leverage event idx in packed ring")
+Signed-off-by: Marvin Liu <yong.liu@intel.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/virtio/virtio_ring.c | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+--- a/drivers/virtio/virtio_ring.c
++++ b/drivers/virtio/virtio_ring.c
+@@ -1499,9 +1499,6 @@ static bool virtqueue_enable_cb_delayed_
+ * counter first before updating event flags.
+ */
+ virtio_wmb(vq->weak_barriers);
+- } else {
+- used_idx = vq->last_used_idx;
+- wrap_counter = vq->packed.used_wrap_counter;
+ }
+
+ if (vq->packed.event_flags_shadow == VRING_PACKED_EVENT_FLAG_DISABLE) {
+@@ -1518,7 +1515,9 @@ static bool virtqueue_enable_cb_delayed_
+ */
+ virtio_mb(vq->weak_barriers);
+
+- if (is_used_desc_packed(vq, used_idx, wrap_counter)) {
++ if (is_used_desc_packed(vq,
++ vq->last_used_idx,
++ vq->packed.used_wrap_counter)) {
+ END_USE(vq);
+ return false;
+ }