From: Greg Kroah-Hartman Date: Sun, 23 Jan 2022 14:52:16 +0000 (+0100) Subject: 5.16-stable patches X-Git-Tag: v4.4.300~138 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0f390c312d0cb83bafca7f22a716a8800bb83d5c;p=thirdparty%2Fkernel%2Fstable-queue.git 5.16-stable patches added patches: arm-dts-at91-update-alternate-function-of-signal-pd20.patch arm64-errata-fix-exec-handling-in-erratum-1418040-workaround.patch ath11k-add-string-type-to-search-board-data-in-board-2.bin-for-wcn6855.patch bus-mhi-core-fix-race-while-handling-sys_err-at-power-up.patch bus-mhi-core-fix-reading-wake_capable-channel-configuration.patch bus-mhi-pci_generic-graceful-shutdown-on-freeze.patch can-softing_cs-softingcs_probe-fix-memleak-on-registration-failure.patch crypto-x86-aesni-don-t-require-alignment-of-data.patch cxl-pmem-fix-module-reload-vs-workqueue-state.patch cxl-pmem-fix-reference-counting-for-delayed-work.patch dma-pool-create-dma-atomic-pool-only-if-dma-zone-has-managed-pages.patch dma_fence_array-fix-pending_error-leak-in-dma_fence_array_signaled.patch drm-rockchip-dsi-hold-pm-runtime-across-bind-unbind.patch drm-rockchip-dsi-reconfigure-hardware-on-resume.patch drm-tegra-add-back-arm_iommu_detach_device.patch drm-ttm-put-bo-in-its-memory-manager-s-lru-list.patch gpu-host1x-add-back-arm_iommu_detach_device.patch iio-adc-ti-adc081c-partial-revert-of-removal-of-acpi-ids.patch iio-trigger-fix-a-scheduling-whilst-atomic-issue-seen-on-tsc2046.patch io_uring-fix-no-lock-protection-for-ctx-cq_extra.patch iommu-io-pgtable-arm-v7s-add-error-handle-for-page-table-allocation-failure.patch ksmbd-add-reserved-room-in-ipc-request-response.patch ksmbd-add-support-for-smb2-max-credit-parameter.patch ksmbd-fix-guest-connection-failure-with-nautilus.patch ksmbd-limits-exceeding-the-maximum-allowable-outstanding-requests.patch ksmbd-move-credit-charge-deduction-under-processing-request.patch ksmbd-uninitialized-variable-in-create_socket.patch lkdtm-fix-content-of-section-containing-lkdtm_rodata_do_nothing.patch media-cec-fix-a-deadlock-situation.patch media-cec-pin-fix-interrupt-en-disable-handling.patch media-cpia2-fix-control-message-timeouts.patch media-dib0700-fix-undefined-behavior-in-tuner-shutdown.patch media-em28xx-fix-control-message-timeouts.patch media-flexcop-usb-fix-control-message-timeouts.patch media-mceusb-fix-control-message-timeouts.patch media-ov8865-disable-only-enabled-regulators-on-error-path.patch media-pvrusb2-fix-control-message-timeouts.patch media-redrat3-fix-control-message-timeouts.patch media-s2255-fix-control-message-timeouts.patch media-stk1160-fix-control-message-timeouts.patch media-v4l2-ioctl.c-readbuffers-depends-on-v4l2_cap_readwrite.patch mei-hbm-fix-client-dma-reply-status.patch mm-page_alloc.c-do-not-warn-allocation-failure-on-zone-dma-if-no-managed-pages.patch mm_zone-add-function-to-check-if-managed-dma-zone-exists.patch mtd-rawnand-davinci-avoid-duplicated-page-read.patch mtd-rawnand-davinci-don-t-calculate-ecc-when-reading-page.patch mtd-rawnand-davinci-rewrite-function-description.patch mtd-rawnand-export-nand_read_page_hwecc_oob_first.patch mtd-rawnand-ingenic-jz4740-needs-oob_first-read-page-function.patch net-phy-marvell-add-marvell-specific-phy-loopback.patch pci-add-function-1-dma-alias-quirk-for-marvell-88se9125-sata-controller.patch risc-v-use-common-riscv_cpuid_to_hartid_mask-for-both-smp-y-and-smp-n.patch riscv-don-t-use-va_pa_offset-on-kdump.patch riscv-get-rid-of-maxphysmem-configs.patch riscv-mm-fix-wrong-phys_ram_base-value-for-rv64.patch riscv-try-to-allocate-crashkern-region-from-32bit-addressible-memory.patch riscv-use-hart-id-instead-of-cpu-id-on-machine_kexec.patch rtc-cmos-take-rtc_lock-while-reading-from-cmos.patch shmem-fix-a-race-between-shmem_unused_huge_shrink-and-shmem_evict_inode.patch thermal-drivers-int340x-fix-rfim-mailbox-write-commands.patch tools-nolibc-fix-incorrect-truncation-of-exit-code.patch tools-nolibc-i386-fix-initial-stack-alignment.patch tools-nolibc-x86-64-fix-startup-code-bug.patch virtio-virtio_mem-handle-a-possible-null-as-a-memcpy-parameter.patch x86-gpu-reserve-stolen-memory-for-first-integrated-intel-gpu.patch --- diff --git a/queue-5.16/arm-dts-at91-update-alternate-function-of-signal-pd20.patch b/queue-5.16/arm-dts-at91-update-alternate-function-of-signal-pd20.patch new file mode 100644 index 00000000000..ea2d58551ee --- /dev/null +++ b/queue-5.16/arm-dts-at91-update-alternate-function-of-signal-pd20.patch @@ -0,0 +1,33 @@ +From 12f332d2dd3187472f595b678246adb10d886bd0 Mon Sep 17 00:00:00 2001 +From: Hari Prasath +Date: Wed, 8 Dec 2021 12:05:53 +0530 +Subject: ARM: dts: at91: update alternate function of signal PD20 + +From: Hari Prasath + +commit 12f332d2dd3187472f595b678246adb10d886bd0 upstream. + +The alternate function of PD20 is 4 as per the datasheet of +sama7g5 and not 5 as defined earlier. + +Signed-off-by: Hari Prasath +Fixes: 7540629e2fc7 ("ARM: dts: at91: add sama7g5 SoC DT and sama7g5-ek") +Cc: # v5.15+ +Signed-off-by: Nicolas Ferre +Link: https://lore.kernel.org/r/20211208063553.19807-1-Hari.PrasathGE@microchip.com +Signed-off-by: Greg Kroah-Hartman +--- + arch/arm/boot/dts/sama7g5-pinfunc.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/arm/boot/dts/sama7g5-pinfunc.h ++++ b/arch/arm/boot/dts/sama7g5-pinfunc.h +@@ -765,7 +765,7 @@ + #define PIN_PD20__PCK0 PINMUX_PIN(PIN_PD20, 1, 3) + #define PIN_PD20__FLEXCOM2_IO3 PINMUX_PIN(PIN_PD20, 2, 2) + #define PIN_PD20__PWMH3 PINMUX_PIN(PIN_PD20, 3, 4) +-#define PIN_PD20__CANTX4 PINMUX_PIN(PIN_PD20, 5, 2) ++#define PIN_PD20__CANTX4 PINMUX_PIN(PIN_PD20, 4, 2) + #define PIN_PD20__FLEXCOM5_IO0 PINMUX_PIN(PIN_PD20, 6, 5) + #define PIN_PD21 117 + #define PIN_PD21__GPIO PINMUX_PIN(PIN_PD21, 0, 0) diff --git a/queue-5.16/arm64-errata-fix-exec-handling-in-erratum-1418040-workaround.patch b/queue-5.16/arm64-errata-fix-exec-handling-in-erratum-1418040-workaround.patch new file mode 100644 index 00000000000..83f169d60d4 --- /dev/null +++ b/queue-5.16/arm64-errata-fix-exec-handling-in-erratum-1418040-workaround.patch @@ -0,0 +1,102 @@ +From 38e0257e0e6f4fef2aa2966b089b56a8b1cfb75c Mon Sep 17 00:00:00 2001 +From: D Scott Phillips +Date: Mon, 20 Dec 2021 15:41:14 -0800 +Subject: arm64: errata: Fix exec handling in erratum 1418040 workaround + +From: D Scott Phillips + +commit 38e0257e0e6f4fef2aa2966b089b56a8b1cfb75c upstream. + +The erratum 1418040 workaround enables CNTVCT_EL1 access trapping in EL0 +when executing compat threads. The workaround is applied when switching +between tasks, but the need for the workaround could also change at an +exec(), when a non-compat task execs a compat binary or vice versa. Apply +the workaround in arch_setup_new_exec(). + +This leaves a small window of time between SET_PERSONALITY and +arch_setup_new_exec where preemption could occur and confuse the old +workaround logic that compares TIF_32BIT between prev and next. Instead, we +can just read cntkctl to make sure it's in the state that the next task +needs. I measured cntkctl read time to be about the same as a mov from a +general-purpose register on N1. Update the workaround logic to examine the +current value of cntkctl instead of the previous task's compat state. + +Fixes: d49f7d7376d0 ("arm64: Move handling of erratum 1418040 into C code") +Cc: # 5.9.x +Signed-off-by: D Scott Phillips +Reviewed-by: Marc Zyngier +Link: https://lore.kernel.org/r/20211220234114.3926-1-scott@os.amperecomputing.com +Signed-off-by: Catalin Marinas +Signed-off-by: Greg Kroah-Hartman +--- + arch/arm64/kernel/process.c | 39 ++++++++++++++++----------------------- + 1 file changed, 16 insertions(+), 23 deletions(-) + +--- a/arch/arm64/kernel/process.c ++++ b/arch/arm64/kernel/process.c +@@ -439,34 +439,26 @@ static void entry_task_switch(struct tas + + /* + * ARM erratum 1418040 handling, affecting the 32bit view of CNTVCT. +- * Assuming the virtual counter is enabled at the beginning of times: +- * +- * - disable access when switching from a 64bit task to a 32bit task +- * - enable access when switching from a 32bit task to a 64bit task ++ * Ensure access is disabled when switching to a 32bit task, ensure ++ * access is enabled when switching to a 64bit task. + */ +-static void erratum_1418040_thread_switch(struct task_struct *prev, +- struct task_struct *next) ++static void erratum_1418040_thread_switch(struct task_struct *next) + { +- bool prev32, next32; +- u64 val; +- +- if (!IS_ENABLED(CONFIG_ARM64_ERRATUM_1418040)) +- return; +- +- prev32 = is_compat_thread(task_thread_info(prev)); +- next32 = is_compat_thread(task_thread_info(next)); +- +- if (prev32 == next32 || !this_cpu_has_cap(ARM64_WORKAROUND_1418040)) ++ if (!IS_ENABLED(CONFIG_ARM64_ERRATUM_1418040) || ++ !this_cpu_has_cap(ARM64_WORKAROUND_1418040)) + return; + +- val = read_sysreg(cntkctl_el1); +- +- if (!next32) +- val |= ARCH_TIMER_USR_VCT_ACCESS_EN; ++ if (is_compat_thread(task_thread_info(next))) ++ sysreg_clear_set(cntkctl_el1, ARCH_TIMER_USR_VCT_ACCESS_EN, 0); + else +- val &= ~ARCH_TIMER_USR_VCT_ACCESS_EN; ++ sysreg_clear_set(cntkctl_el1, 0, ARCH_TIMER_USR_VCT_ACCESS_EN); ++} + +- write_sysreg(val, cntkctl_el1); ++static void erratum_1418040_new_exec(void) ++{ ++ preempt_disable(); ++ erratum_1418040_thread_switch(current); ++ preempt_enable(); + } + + /* +@@ -501,7 +493,7 @@ __notrace_funcgraph struct task_struct * + contextidr_thread_switch(next); + entry_task_switch(next); + ssbs_thread_switch(next); +- erratum_1418040_thread_switch(prev, next); ++ erratum_1418040_thread_switch(next); + ptrauth_thread_switch_user(next); + + /* +@@ -611,6 +603,7 @@ void arch_setup_new_exec(void) + current->mm->context.flags = mmflags; + ptrauth_thread_init_user(); + mte_thread_init_user(); ++ erratum_1418040_new_exec(); + + if (task_spec_ssb_noexec(current)) { + arch_prctl_spec_ctrl_set(current, PR_SPEC_STORE_BYPASS, diff --git a/queue-5.16/ath11k-add-string-type-to-search-board-data-in-board-2.bin-for-wcn6855.patch b/queue-5.16/ath11k-add-string-type-to-search-board-data-in-board-2.bin-for-wcn6855.patch new file mode 100644 index 00000000000..b708f48fe53 --- /dev/null +++ b/queue-5.16/ath11k-add-string-type-to-search-board-data-in-board-2.bin-for-wcn6855.patch @@ -0,0 +1,135 @@ +From fc95d10ac41d75c14a81afcc8722333d8b2cf80f Mon Sep 17 00:00:00 2001 +From: Wen Gong +Date: Mon, 15 Nov 2021 11:29:55 +0200 +Subject: ath11k: add string type to search board data in board-2.bin for WCN6855 + +From: Wen Gong + +commit fc95d10ac41d75c14a81afcc8722333d8b2cf80f upstream. + +Currently ath11k only support string type with bus, chip id and board id +such as "bus=ahb,qmi-chip-id=1,qmi-board-id=4" for ahb bus chip and +"bus=pci,qmi-chip-id=0,qmi-board-id=255" for PCIe bus chip in +board-2.bin. For WCN6855, it is not enough to distinguish all different +chips. + +This is to add a new string type which include bus, chip id, board id, +vendor, device, subsystem-vendor and subsystem-device for WCN6855. + +ath11k will first load board-2.bin and search in it for the board data +with the above parameters, if matched one board data, then download it +to firmware, if not matched any one, then ath11k will download the file +board.bin to firmware. + +Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-01720.1-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1 + +Signed-off-by: Wen Gong +Signed-off-by: Jouni Malinen +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20211111065340.20187-1-quic_wgong@quicinc.com +Cc: "Limonciello, Mario" +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/wireless/ath/ath11k/core.c | 27 +++++++++++++++++++++------ + drivers/net/wireless/ath/ath11k/core.h | 13 +++++++++++++ + drivers/net/wireless/ath/ath11k/pci.c | 10 ++++++++++ + 3 files changed, 44 insertions(+), 6 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/core.c ++++ b/drivers/net/wireless/ath/ath11k/core.c +@@ -392,11 +392,26 @@ static int ath11k_core_create_board_name + scnprintf(variant, sizeof(variant), ",variant=%s", + ab->qmi.target.bdf_ext); + +- scnprintf(name, name_len, +- "bus=%s,qmi-chip-id=%d,qmi-board-id=%d%s", +- ath11k_bus_str(ab->hif.bus), +- ab->qmi.target.chip_id, +- ab->qmi.target.board_id, variant); ++ switch (ab->id.bdf_search) { ++ case ATH11K_BDF_SEARCH_BUS_AND_BOARD: ++ scnprintf(name, name_len, ++ "bus=%s,vendor=%04x,device=%04x,subsystem-vendor=%04x,subsystem-device=%04x,qmi-chip-id=%d,qmi-board-id=%d%s", ++ ath11k_bus_str(ab->hif.bus), ++ ab->id.vendor, ab->id.device, ++ ab->id.subsystem_vendor, ++ ab->id.subsystem_device, ++ ab->qmi.target.chip_id, ++ ab->qmi.target.board_id, ++ variant); ++ break; ++ default: ++ scnprintf(name, name_len, ++ "bus=%s,qmi-chip-id=%d,qmi-board-id=%d%s", ++ ath11k_bus_str(ab->hif.bus), ++ ab->qmi.target.chip_id, ++ ab->qmi.target.board_id, variant); ++ break; ++ } + + ath11k_dbg(ab, ATH11K_DBG_BOOT, "boot using board name '%s'\n", name); + +@@ -633,7 +648,7 @@ static int ath11k_core_fetch_board_data_ + return 0; + } + +-#define BOARD_NAME_SIZE 100 ++#define BOARD_NAME_SIZE 200 + int ath11k_core_fetch_bdf(struct ath11k_base *ab, struct ath11k_board_data *bd) + { + char boardname[BOARD_NAME_SIZE]; +--- a/drivers/net/wireless/ath/ath11k/core.h ++++ b/drivers/net/wireless/ath/ath11k/core.h +@@ -47,6 +47,11 @@ enum ath11k_supported_bw { + ATH11K_BW_160 = 3, + }; + ++enum ath11k_bdf_search { ++ ATH11K_BDF_SEARCH_DEFAULT, ++ ATH11K_BDF_SEARCH_BUS_AND_BOARD, ++}; ++ + enum wme_ac { + WME_AC_BE, + WME_AC_BK, +@@ -759,6 +764,14 @@ struct ath11k_base { + + struct completion htc_suspend; + ++ struct { ++ enum ath11k_bdf_search bdf_search; ++ u32 vendor; ++ u32 device; ++ u32 subsystem_vendor; ++ u32 subsystem_device; ++ } id; ++ + /* must be last */ + u8 drv_priv[0] __aligned(sizeof(void *)); + }; +--- a/drivers/net/wireless/ath/ath11k/pci.c ++++ b/drivers/net/wireless/ath/ath11k/pci.c +@@ -1251,6 +1251,15 @@ static int ath11k_pci_probe(struct pci_d + goto err_free_core; + } + ++ ath11k_dbg(ab, ATH11K_DBG_BOOT, "pci probe %04x:%04x %04x:%04x\n", ++ pdev->vendor, pdev->device, ++ pdev->subsystem_vendor, pdev->subsystem_device); ++ ++ ab->id.vendor = pdev->vendor; ++ ab->id.device = pdev->device; ++ ab->id.subsystem_vendor = pdev->subsystem_vendor; ++ ab->id.subsystem_device = pdev->subsystem_device; ++ + switch (pci_dev->device) { + case QCA6390_DEVICE_ID: + ath11k_pci_read_hw_version(ab, &soc_hw_version_major, +@@ -1273,6 +1282,7 @@ static int ath11k_pci_probe(struct pci_d + ab->hw_rev = ATH11K_HW_QCN9074_HW10; + break; + case WCN6855_DEVICE_ID: ++ ab->id.bdf_search = ATH11K_BDF_SEARCH_BUS_AND_BOARD; + ath11k_pci_read_hw_version(ab, &soc_hw_version_major, + &soc_hw_version_minor); + switch (soc_hw_version_major) { diff --git a/queue-5.16/bus-mhi-core-fix-race-while-handling-sys_err-at-power-up.patch b/queue-5.16/bus-mhi-core-fix-race-while-handling-sys_err-at-power-up.patch new file mode 100644 index 00000000000..bcabffc0830 --- /dev/null +++ b/queue-5.16/bus-mhi-core-fix-race-while-handling-sys_err-at-power-up.patch @@ -0,0 +1,116 @@ +From d651ce8e917fa1bf6cfab8dca74c512edffc35d3 Mon Sep 17 00:00:00 2001 +From: Manivannan Sadhasivam +Date: Thu, 16 Dec 2021 13:42:24 +0530 +Subject: bus: mhi: core: Fix race while handling SYS_ERR at power up + +From: Manivannan Sadhasivam + +commit d651ce8e917fa1bf6cfab8dca74c512edffc35d3 upstream. + +During SYS_ERR condition, as a response to the MHI_RESET from host, some +devices tend to issue BHI interrupt without clearing the SYS_ERR state in +the device. This creates a race condition and causes a failure in booting +up the device. + +The issue is seen on the Sierra Wireless EM9191 modem during SYS_ERR +handling in mhi_async_power_up(). Once the host detects that the device +is in SYS_ERR state, it issues MHI_RESET and waits for the device to +process the reset request. During this time, the device triggers the BHI +interrupt to the host without clearing SYS_ERR condition. So the host +starts handling the SYS_ERR condition again. + +To fix this issue, let's register the IRQ handler only after handling the +SYS_ERR check to avoid getting spurious IRQs from the device. + +Fixes: e18d4e9fa79b ("bus: mhi: core: Handle syserr during power_up") +Cc: stable@vger.kernel.org +Reported-by: Aleksander Morgado +Tested-by: Aleksander Morgado +Tested-by: Thomas Perrot +Signed-off-by: Manivannan Sadhasivam +Link: https://lore.kernel.org/r/20211216081227.237749-8-manivannan.sadhasivam@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/bus/mhi/core/pm.c | 35 ++++++++++++----------------------- + 1 file changed, 12 insertions(+), 23 deletions(-) + +--- a/drivers/bus/mhi/core/pm.c ++++ b/drivers/bus/mhi/core/pm.c +@@ -1053,7 +1053,7 @@ int mhi_async_power_up(struct mhi_contro + enum mhi_ee_type current_ee; + enum dev_st_transition next_state; + struct device *dev = &mhi_cntrl->mhi_dev->dev; +- u32 val; ++ u32 interval_us = 25000; /* poll register field every 25 milliseconds */ + int ret; + + dev_info(dev, "Requested to power ON\n"); +@@ -1070,10 +1070,6 @@ int mhi_async_power_up(struct mhi_contro + mutex_lock(&mhi_cntrl->pm_mutex); + mhi_cntrl->pm_state = MHI_PM_DISABLE; + +- ret = mhi_init_irq_setup(mhi_cntrl); +- if (ret) +- goto error_setup_irq; +- + /* Setup BHI INTVEC */ + write_lock_irq(&mhi_cntrl->pm_lock); + mhi_write_reg(mhi_cntrl, mhi_cntrl->bhi, BHI_INTVEC, 0); +@@ -1087,7 +1083,7 @@ int mhi_async_power_up(struct mhi_contro + dev_err(dev, "%s is not a valid EE for power on\n", + TO_MHI_EXEC_STR(current_ee)); + ret = -EIO; +- goto error_async_power_up; ++ goto error_exit; + } + + state = mhi_get_mhi_state(mhi_cntrl); +@@ -1096,20 +1092,12 @@ int mhi_async_power_up(struct mhi_contro + + if (state == MHI_STATE_SYS_ERR) { + mhi_set_mhi_state(mhi_cntrl, MHI_STATE_RESET); +- ret = wait_event_timeout(mhi_cntrl->state_event, +- MHI_PM_IN_FATAL_STATE(mhi_cntrl->pm_state) || +- mhi_read_reg_field(mhi_cntrl, +- mhi_cntrl->regs, +- MHICTRL, +- MHICTRL_RESET_MASK, +- MHICTRL_RESET_SHIFT, +- &val) || +- !val, +- msecs_to_jiffies(mhi_cntrl->timeout_ms)); +- if (!ret) { +- ret = -EIO; ++ ret = mhi_poll_reg_field(mhi_cntrl, mhi_cntrl->regs, MHICTRL, ++ MHICTRL_RESET_MASK, MHICTRL_RESET_SHIFT, 0, ++ interval_us); ++ if (ret) { + dev_info(dev, "Failed to reset MHI due to syserr state\n"); +- goto error_async_power_up; ++ goto error_exit; + } + + /* +@@ -1119,6 +1107,10 @@ int mhi_async_power_up(struct mhi_contro + mhi_write_reg(mhi_cntrl, mhi_cntrl->bhi, BHI_INTVEC, 0); + } + ++ ret = mhi_init_irq_setup(mhi_cntrl); ++ if (ret) ++ goto error_exit; ++ + /* Transition to next state */ + next_state = MHI_IN_PBL(current_ee) ? + DEV_ST_TRANSITION_PBL : DEV_ST_TRANSITION_READY; +@@ -1131,10 +1123,7 @@ int mhi_async_power_up(struct mhi_contro + + return 0; + +-error_async_power_up: +- mhi_deinit_free_irq(mhi_cntrl); +- +-error_setup_irq: ++error_exit: + mhi_cntrl->pm_state = MHI_PM_DISABLE; + mutex_unlock(&mhi_cntrl->pm_mutex); + diff --git a/queue-5.16/bus-mhi-core-fix-reading-wake_capable-channel-configuration.patch b/queue-5.16/bus-mhi-core-fix-reading-wake_capable-channel-configuration.patch new file mode 100644 index 00000000000..e4621b642ba --- /dev/null +++ b/queue-5.16/bus-mhi-core-fix-reading-wake_capable-channel-configuration.patch @@ -0,0 +1,36 @@ +From 42c4668f7efe1485dfc382517b412c0c6ab102b8 Mon Sep 17 00:00:00 2001 +From: Bhaumik Bhatt +Date: Thu, 16 Dec 2021 13:42:23 +0530 +Subject: bus: mhi: core: Fix reading wake_capable channel configuration + +From: Bhaumik Bhatt + +commit 42c4668f7efe1485dfc382517b412c0c6ab102b8 upstream. + +The 'wake-capable' entry in channel configuration is not set when +parsing the configuration specified by the controller driver. Add +the missing entry to ensure channel is correctly specified as a +'wake-capable' channel. + +Link: https://lore.kernel.org/r/1638320491-13382-1-git-send-email-quic_bbhatt@quicinc.com +Fixes: 0cbf260820fa ("bus: mhi: core: Add support for registering MHI controllers") +Cc: stable@vger.kernel.org +Reviewed-by: Manivannan Sadhasivam +Signed-off-by: Bhaumik Bhatt +Signed-off-by: Manivannan Sadhasivam +Link: https://lore.kernel.org/r/20211216081227.237749-7-manivannan.sadhasivam@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/bus/mhi/core/init.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/bus/mhi/core/init.c ++++ b/drivers/bus/mhi/core/init.c +@@ -788,6 +788,7 @@ static int parse_ch_cfg(struct mhi_contr + mhi_chan->offload_ch = ch_cfg->offload_channel; + mhi_chan->db_cfg.reset_req = ch_cfg->doorbell_mode_switch; + mhi_chan->pre_alloc = ch_cfg->auto_queue; ++ mhi_chan->wake_capable = ch_cfg->wake_capable; + + /* + * If MHI host allocates buffers, then the channel direction diff --git a/queue-5.16/bus-mhi-pci_generic-graceful-shutdown-on-freeze.patch b/queue-5.16/bus-mhi-pci_generic-graceful-shutdown-on-freeze.patch new file mode 100644 index 00000000000..f9f84a3fd4e --- /dev/null +++ b/queue-5.16/bus-mhi-pci_generic-graceful-shutdown-on-freeze.patch @@ -0,0 +1,40 @@ +From f77097ec8c0141a4b5cf3722a246be0cb5677e29 Mon Sep 17 00:00:00 2001 +From: Loic Poulain +Date: Thu, 16 Dec 2021 13:42:19 +0530 +Subject: bus: mhi: pci_generic: Graceful shutdown on freeze + +From: Loic Poulain + +commit f77097ec8c0141a4b5cf3722a246be0cb5677e29 upstream. + +There is no reason for shutting down MHI ungracefully on freeze, +this causes the MHI host stack & device stack to not be aligned +anymore since the proper MHI reset sequence is not performed for +ungraceful shutdown. + +Link: https://lore.kernel.org/r/1635268180-13699-1-git-send-email-loic.poulain@linaro.org +Fixes: 5f0c2ee1fe8d ("bus: mhi: pci-generic: Fix hibernation") +Cc: stable@vger.kernel.org +Suggested-by: Bhaumik Bhatt +Reviewed-by: Bhaumik Bhatt +Reviewed-by: Hemant Kumar +Reviewed-by: Manivannan Sadhasivam +Signed-off-by: Loic Poulain +Signed-off-by: Manivannan Sadhasivam +Link: https://lore.kernel.org/r/20211216081227.237749-3-manivannan.sadhasivam@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/bus/mhi/pci_generic.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/bus/mhi/pci_generic.c ++++ b/drivers/bus/mhi/pci_generic.c +@@ -1018,7 +1018,7 @@ static int __maybe_unused mhi_pci_freeze + * context. + */ + if (test_and_clear_bit(MHI_PCI_DEV_STARTED, &mhi_pdev->status)) { +- mhi_power_down(mhi_cntrl, false); ++ mhi_power_down(mhi_cntrl, true); + mhi_unprepare_after_power_down(mhi_cntrl); + } + diff --git a/queue-5.16/can-softing_cs-softingcs_probe-fix-memleak-on-registration-failure.patch b/queue-5.16/can-softing_cs-softingcs_probe-fix-memleak-on-registration-failure.patch new file mode 100644 index 00000000000..6c9b6a91a6c --- /dev/null +++ b/queue-5.16/can-softing_cs-softingcs_probe-fix-memleak-on-registration-failure.patch @@ -0,0 +1,36 @@ +From ced4913efb0acc844ed65cc01d091a85d83a2082 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Wed, 22 Dec 2021 11:48:43 +0100 +Subject: can: softing_cs: softingcs_probe(): fix memleak on registration failure + +From: Johan Hovold + +commit ced4913efb0acc844ed65cc01d091a85d83a2082 upstream. + +In case device registration fails during probe, the driver state and +the embedded platform device structure needs to be freed using +platform_device_put() to properly free all resources (e.g. the device +name). + +Fixes: 0a0b7a5f7a04 ("can: add driver for Softing card") +Link: https://lore.kernel.org/all/20211222104843.6105-1-johan@kernel.org +Cc: stable@vger.kernel.org # 2.6.38 +Signed-off-by: Johan Hovold +Reviewed-by: Greg Kroah-Hartman +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/can/softing/softing_cs.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/can/softing/softing_cs.c ++++ b/drivers/net/can/softing/softing_cs.c +@@ -293,7 +293,7 @@ static int softingcs_probe(struct pcmcia + return 0; + + platform_failed: +- kfree(dev); ++ platform_device_put(pdev); + mem_failed: + pcmcia_bad: + pcmcia_failed: diff --git a/queue-5.16/crypto-x86-aesni-don-t-require-alignment-of-data.patch b/queue-5.16/crypto-x86-aesni-don-t-require-alignment-of-data.patch new file mode 100644 index 00000000000..0daf2658553 --- /dev/null +++ b/queue-5.16/crypto-x86-aesni-don-t-require-alignment-of-data.patch @@ -0,0 +1,51 @@ +From d480a26bdf872529919e7c30e17f79d0d7b8c4da Mon Sep 17 00:00:00 2001 +From: Jakub Kicinski +Date: Tue, 21 Dec 2021 07:06:11 -0800 +Subject: crypto: x86/aesni - don't require alignment of data + +From: Jakub Kicinski + +commit d480a26bdf872529919e7c30e17f79d0d7b8c4da upstream. + +x86 AES-NI routines can deal with unaligned data. Crypto context +(key, iv etc.) have to be aligned but we take care of that separately +by copying it onto the stack. We were feeding unaligned data into +crypto routines up until commit 83c83e658863 ("crypto: aesni - +refactor scatterlist processing") switched to use the full +skcipher API which uses cra_alignmask to decide data alignment. + +This fixes 21% performance regression in kTLS. + +Tested by booting with CONFIG_CRYPTO_MANAGER_EXTRA_TESTS=y +(and running thru various kTLS packets). + +CC: stable@vger.kernel.org # 5.15+ +Fixes: 83c83e658863 ("crypto: aesni - refactor scatterlist processing") +Signed-off-by: Jakub Kicinski +Acked-by: Ard Biesheuvel +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/crypto/aesni-intel_glue.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/arch/x86/crypto/aesni-intel_glue.c ++++ b/arch/x86/crypto/aesni-intel_glue.c +@@ -1107,7 +1107,7 @@ static struct aead_alg aesni_aeads[] = { + .cra_flags = CRYPTO_ALG_INTERNAL, + .cra_blocksize = 1, + .cra_ctxsize = sizeof(struct aesni_rfc4106_gcm_ctx), +- .cra_alignmask = AESNI_ALIGN - 1, ++ .cra_alignmask = 0, + .cra_module = THIS_MODULE, + }, + }, { +@@ -1124,7 +1124,7 @@ static struct aead_alg aesni_aeads[] = { + .cra_flags = CRYPTO_ALG_INTERNAL, + .cra_blocksize = 1, + .cra_ctxsize = sizeof(struct generic_gcmaes_ctx), +- .cra_alignmask = AESNI_ALIGN - 1, ++ .cra_alignmask = 0, + .cra_module = THIS_MODULE, + }, + } }; diff --git a/queue-5.16/cxl-pmem-fix-module-reload-vs-workqueue-state.patch b/queue-5.16/cxl-pmem-fix-module-reload-vs-workqueue-state.patch new file mode 100644 index 00000000000..c64cd1de3bd --- /dev/null +++ b/queue-5.16/cxl-pmem-fix-module-reload-vs-workqueue-state.patch @@ -0,0 +1,168 @@ +From 53989fad1286e652ea3655ae3367ba698da8d2ff Mon Sep 17 00:00:00 2001 +From: Dan Williams +Date: Thu, 11 Nov 2021 10:19:05 -0800 +Subject: cxl/pmem: Fix module reload vs workqueue state + +From: Dan Williams + +commit 53989fad1286e652ea3655ae3367ba698da8d2ff upstream. + +A test of the form: + + while true; do modprobe -r cxl_pmem; modprobe cxl_pmem; done + +May lead to a crash signature of the form: + + BUG: unable to handle page fault for address: ffffffffc0660030 + #PF: supervisor instruction fetch in kernel mode + #PF: error_code(0x0010) - not-present page + [..] + Workqueue: cxl_pmem 0xffffffffc0660030 + RIP: 0010:0xffffffffc0660030 + Code: Unable to access opcode bytes at RIP 0xffffffffc0660006. + [..] + Call Trace: + ? process_one_work+0x4ec/0x9c0 + ? pwq_dec_nr_in_flight+0x100/0x100 + ? rwlock_bug.part.0+0x60/0x60 + ? worker_thread+0x2eb/0x700 + +In that report the 0xffffffffc0660030 address corresponds to the former +function address of cxl_nvb_update_state() from a previous load of the +module, not the current address. Fix that by arranging for ->state_work +in the 'struct cxl_nvdimm_bridge' object to be reinitialized on cxl_pmem +module reload. + +Details: + +Recall that CXL subsystem wants to link a CXL memory expander device to +an NVDIMM sub-hierarchy when both a persistent memory range has been +registered by the CXL platform driver (cxl_acpi) *and* when that CXL +memory expander has published persistent memory capacity (Get Partition +Info). To this end the cxl_nvdimm_bridge driver arranges to rescan the +CXL bus when either of those conditions change. The helper +bus_rescan_devices() can not be called underneath the device_lock() for +any device on that bus, so the cxl_nvdimm_bridge driver uses a workqueue +for the rescan. + +Typically a driver allocates driver data to hold a 'struct work_struct' +for a driven device, but for a workqueue that may run after ->remove() +returns, driver data will have been freed. The 'struct +cxl_nvdimm_bridge' object holds the state and work_struct directly. +Unfortunately it was only arranging for that infrastructure to be +initialized once per device creation rather than the necessary once per +workqueue (cxl_pmem_wq) creation. + +Introduce is_cxl_nvdimm_bridge() and cxl_nvdimm_bridge_reset() in +support of invalidating stale references to a recently destroyed +cxl_pmem_wq. + +Cc: +Fixes: 8fdcb1704f61 ("cxl/pmem: Add initial infrastructure for pmem support") +Reported-by: Vishal Verma +Tested-by: Vishal Verma +Link: https://lore.kernel.org/r/163665474585.3505991.8397182770066720755.stgit@dwillia2-desk3.amr.corp.intel.com +Signed-off-by: Dan Williams +Signed-off-by: Greg Kroah-Hartman +--- + drivers/cxl/core/pmem.c | 8 +++++++- + drivers/cxl/cxl.h | 8 ++++++++ + drivers/cxl/pmem.c | 29 +++++++++++++++++++++++++++-- + 3 files changed, 42 insertions(+), 3 deletions(-) + +--- a/drivers/cxl/core/pmem.c ++++ b/drivers/cxl/core/pmem.c +@@ -51,10 +51,16 @@ struct cxl_nvdimm_bridge *to_cxl_nvdimm_ + } + EXPORT_SYMBOL_GPL(to_cxl_nvdimm_bridge); + +-__mock int match_nvdimm_bridge(struct device *dev, const void *data) ++bool is_cxl_nvdimm_bridge(struct device *dev) + { + return dev->type == &cxl_nvdimm_bridge_type; + } ++EXPORT_SYMBOL_NS_GPL(is_cxl_nvdimm_bridge, CXL); ++ ++__mock int match_nvdimm_bridge(struct device *dev, const void *data) ++{ ++ return is_cxl_nvdimm_bridge(dev); ++} + + struct cxl_nvdimm_bridge *cxl_find_nvdimm_bridge(struct cxl_nvdimm *cxl_nvd) + { +--- a/drivers/cxl/cxl.h ++++ b/drivers/cxl/cxl.h +@@ -196,6 +196,13 @@ struct cxl_decoder { + }; + + ++/** ++ * enum cxl_nvdimm_brige_state - state machine for managing bus rescans ++ * @CXL_NVB_NEW: Set at bridge create and after cxl_pmem_wq is destroyed ++ * @CXL_NVB_DEAD: Set at brige unregistration to preclude async probing ++ * @CXL_NVB_ONLINE: Target state after successful ->probe() ++ * @CXL_NVB_OFFLINE: Target state after ->remove() or failed ->probe() ++ */ + enum cxl_nvdimm_brige_state { + CXL_NVB_NEW, + CXL_NVB_DEAD, +@@ -308,6 +315,7 @@ struct cxl_nvdimm_bridge *devm_cxl_add_n + struct cxl_port *port); + struct cxl_nvdimm *to_cxl_nvdimm(struct device *dev); + bool is_cxl_nvdimm(struct device *dev); ++bool is_cxl_nvdimm_bridge(struct device *dev); + int devm_cxl_add_nvdimm(struct device *host, struct cxl_memdev *cxlmd); + struct cxl_nvdimm_bridge *cxl_find_nvdimm_bridge(struct cxl_nvdimm *cxl_nvd); + +--- a/drivers/cxl/pmem.c ++++ b/drivers/cxl/pmem.c +@@ -316,6 +316,31 @@ static struct cxl_driver cxl_nvdimm_brid + .id = CXL_DEVICE_NVDIMM_BRIDGE, + }; + ++/* ++ * Return all bridges to the CXL_NVB_NEW state to invalidate any ++ * ->state_work referring to the now destroyed cxl_pmem_wq. ++ */ ++static int cxl_nvdimm_bridge_reset(struct device *dev, void *data) ++{ ++ struct cxl_nvdimm_bridge *cxl_nvb; ++ ++ if (!is_cxl_nvdimm_bridge(dev)) ++ return 0; ++ ++ cxl_nvb = to_cxl_nvdimm_bridge(dev); ++ device_lock(dev); ++ cxl_nvb->state = CXL_NVB_NEW; ++ device_unlock(dev); ++ ++ return 0; ++} ++ ++static void destroy_cxl_pmem_wq(void) ++{ ++ destroy_workqueue(cxl_pmem_wq); ++ bus_for_each_dev(&cxl_bus_type, NULL, NULL, cxl_nvdimm_bridge_reset); ++} ++ + static __init int cxl_pmem_init(void) + { + int rc; +@@ -341,7 +366,7 @@ static __init int cxl_pmem_init(void) + err_nvdimm: + cxl_driver_unregister(&cxl_nvdimm_bridge_driver); + err_bridge: +- destroy_workqueue(cxl_pmem_wq); ++ destroy_cxl_pmem_wq(); + return rc; + } + +@@ -349,7 +374,7 @@ static __exit void cxl_pmem_exit(void) + { + cxl_driver_unregister(&cxl_nvdimm_driver); + cxl_driver_unregister(&cxl_nvdimm_bridge_driver); +- destroy_workqueue(cxl_pmem_wq); ++ destroy_cxl_pmem_wq(); + } + + MODULE_LICENSE("GPL v2"); diff --git a/queue-5.16/cxl-pmem-fix-reference-counting-for-delayed-work.patch b/queue-5.16/cxl-pmem-fix-reference-counting-for-delayed-work.patch new file mode 100644 index 00000000000..b2ea40fffc7 --- /dev/null +++ b/queue-5.16/cxl-pmem-fix-reference-counting-for-delayed-work.patch @@ -0,0 +1,65 @@ +From 08b9e0ab8af48895337192e683de44ab1e1b7427 Mon Sep 17 00:00:00 2001 +From: Dan Williams +Date: Fri, 29 Oct 2021 12:55:47 -0700 +Subject: cxl/pmem: Fix reference counting for delayed work + +From: Dan Williams + +commit 08b9e0ab8af48895337192e683de44ab1e1b7427 upstream. + +There is a potential race between queue_work() returning and the +queued-work running that could result in put_device() running before +get_device(). Introduce the cxl_nvdimm_bridge_state_work() helper that +takes the reference unconditionally, but drops it if no new work was +queued, to keep the references balanced. + +Fixes: 8fdcb1704f61 ("cxl/pmem: Add initial infrastructure for pmem support") +Cc: +Reviewed-by: Jonathan Cameron +Reviewed-by: Ben Widawsky +Link: https://lore.kernel.org/r/163553734757.2509761.3305231863616785470.stgit@dwillia2-desk3.amr.corp.intel.com +Signed-off-by: Dan Williams +Signed-off-by: Greg Kroah-Hartman +--- + drivers/cxl/pmem.c | 17 +++++++++++++---- + 1 file changed, 13 insertions(+), 4 deletions(-) + +--- a/drivers/cxl/pmem.c ++++ b/drivers/cxl/pmem.c +@@ -266,14 +266,24 @@ static void cxl_nvb_update_state(struct + put_device(&cxl_nvb->dev); + } + ++static void cxl_nvdimm_bridge_state_work(struct cxl_nvdimm_bridge *cxl_nvb) ++{ ++ /* ++ * Take a reference that the workqueue will drop if new work ++ * gets queued. ++ */ ++ get_device(&cxl_nvb->dev); ++ if (!queue_work(cxl_pmem_wq, &cxl_nvb->state_work)) ++ put_device(&cxl_nvb->dev); ++} ++ + static void cxl_nvdimm_bridge_remove(struct device *dev) + { + struct cxl_nvdimm_bridge *cxl_nvb = to_cxl_nvdimm_bridge(dev); + + if (cxl_nvb->state == CXL_NVB_ONLINE) + cxl_nvb->state = CXL_NVB_OFFLINE; +- if (queue_work(cxl_pmem_wq, &cxl_nvb->state_work)) +- get_device(&cxl_nvb->dev); ++ cxl_nvdimm_bridge_state_work(cxl_nvb); + } + + static int cxl_nvdimm_bridge_probe(struct device *dev) +@@ -294,8 +304,7 @@ static int cxl_nvdimm_bridge_probe(struc + } + + cxl_nvb->state = CXL_NVB_ONLINE; +- if (queue_work(cxl_pmem_wq, &cxl_nvb->state_work)) +- get_device(&cxl_nvb->dev); ++ cxl_nvdimm_bridge_state_work(cxl_nvb); + + return 0; + } diff --git a/queue-5.16/dma-pool-create-dma-atomic-pool-only-if-dma-zone-has-managed-pages.patch b/queue-5.16/dma-pool-create-dma-atomic-pool-only-if-dma-zone-has-managed-pages.patch new file mode 100644 index 00000000000..0bcf92aa6da --- /dev/null +++ b/queue-5.16/dma-pool-create-dma-atomic-pool-only-if-dma-zone-has-managed-pages.patch @@ -0,0 +1,88 @@ +From a674e48c5443d12a8a43c3ac42367aa39505d506 Mon Sep 17 00:00:00 2001 +From: Baoquan He +Date: Fri, 14 Jan 2022 14:07:41 -0800 +Subject: dma/pool: create dma atomic pool only if dma zone has managed pages + +From: Baoquan He + +commit a674e48c5443d12a8a43c3ac42367aa39505d506 upstream. + +Currently three dma atomic pools are initialized as long as the relevant +kernel codes are built in. While in kdump kernel of x86_64, this is not +right when trying to create atomic_pool_dma, because there's no managed +pages in DMA zone. In the case, DMA zone only has low 1M memory +presented and locked down by memblock allocator. So no pages are added +into buddy of DMA zone. Please check commit f1d4d47c5851 ("x86/setup: +Always reserve the first 1M of RAM"). + +Then in kdump kernel of x86_64, it always prints below failure message: + + DMA: preallocated 128 KiB GFP_KERNEL pool for atomic allocations + swapper/0: page allocation failure: order:5, mode:0xcc1(GFP_KERNEL|GFP_DMA), nodemask=(null),cpuset=/,mems_allowed=0 + CPU: 0 PID: 1 Comm: swapper/0 Not tainted 5.13.0-0.rc5.20210611git929d931f2b40.42.fc35.x86_64 #1 + Hardware name: Dell Inc. PowerEdge R910/0P658H, BIOS 2.12.0 06/04/2018 + Call Trace: + dump_stack+0x7f/0xa1 + warn_alloc.cold+0x72/0xd6 + __alloc_pages_slowpath.constprop.0+0xf29/0xf50 + __alloc_pages+0x24d/0x2c0 + alloc_page_interleave+0x13/0xb0 + atomic_pool_expand+0x118/0x210 + __dma_atomic_pool_init+0x45/0x93 + dma_atomic_pool_init+0xdb/0x176 + do_one_initcall+0x67/0x320 + kernel_init_freeable+0x290/0x2dc + kernel_init+0xa/0x111 + ret_from_fork+0x22/0x30 + Mem-Info: + ...... + DMA: failed to allocate 128 KiB GFP_KERNEL|GFP_DMA pool for atomic allocation + DMA: preallocated 128 KiB GFP_KERNEL|GFP_DMA32 pool for atomic allocations + +Here, let's check if DMA zone has managed pages, then create +atomic_pool_dma if yes. Otherwise just skip it. + +Link: https://lkml.kernel.org/r/20211223094435.248523-3-bhe@redhat.com +Fixes: 6f599d84231f ("x86/kdump: Always reserve the low 1M when the crashkernel option is specified") +Signed-off-by: Baoquan He +Reviewed-by: Christoph Hellwig +Acked-by: John Donnelly +Reviewed-by: David Hildenbrand +Cc: Marek Szyprowski +Cc: Robin Murphy +Cc: Borislav Petkov +Cc: Christoph Lameter +Cc: David Laight +Cc: David Rientjes +Cc: Hyeonggon Yoo <42.hyeyoo@gmail.com> +Cc: Joonsoo Kim +Cc: Pekka Enberg +Cc: Vlastimil Babka +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman +--- + kernel/dma/pool.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/kernel/dma/pool.c ++++ b/kernel/dma/pool.c +@@ -203,7 +203,7 @@ static int __init dma_atomic_pool_init(v + GFP_KERNEL); + if (!atomic_pool_kernel) + ret = -ENOMEM; +- if (IS_ENABLED(CONFIG_ZONE_DMA)) { ++ if (has_managed_dma()) { + atomic_pool_dma = __dma_atomic_pool_init(atomic_pool_size, + GFP_KERNEL | GFP_DMA); + if (!atomic_pool_dma) +@@ -226,7 +226,7 @@ static inline struct gen_pool *dma_guess + if (prev == NULL) { + if (IS_ENABLED(CONFIG_ZONE_DMA32) && (gfp & GFP_DMA32)) + return atomic_pool_dma32; +- if (IS_ENABLED(CONFIG_ZONE_DMA) && (gfp & GFP_DMA)) ++ if (atomic_pool_dma && (gfp & GFP_DMA)) + return atomic_pool_dma; + return atomic_pool_kernel; + } diff --git a/queue-5.16/dma_fence_array-fix-pending_error-leak-in-dma_fence_array_signaled.patch b/queue-5.16/dma_fence_array-fix-pending_error-leak-in-dma_fence_array_signaled.patch new file mode 100644 index 00000000000..8e7dd1b422c --- /dev/null +++ b/queue-5.16/dma_fence_array-fix-pending_error-leak-in-dma_fence_array_signaled.patch @@ -0,0 +1,54 @@ +From 95d35838880fb040ccb9fe4a48816bd0c8b62df5 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Thomas=20Hellstr=C3=B6m?= +Date: Mon, 29 Nov 2021 16:27:27 +0100 +Subject: dma_fence_array: Fix PENDING_ERROR leak in dma_fence_array_signaled() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Thomas Hellström + +commit 95d35838880fb040ccb9fe4a48816bd0c8b62df5 upstream. + +If a dma_fence_array is reported signaled by a call to +dma_fence_is_signaled(), it may leak the PENDING_ERROR status. + +Fix this by clearing the PENDING_ERROR status if we return true in +dma_fence_array_signaled(). + +v2: +- Update Cc list, and add R-b. + +Fixes: 1f70b8b812f3 ("dma-fence: Propagate errors to dma-fence-array container") +Cc: Chris Wilson +Cc: Sumit Semwal +Cc: Gustavo Padovan +Cc: Christian König +Cc: "Christian König" +Cc: linux-media@vger.kernel.org +Cc: dri-devel@lists.freedesktop.org +Cc: linaro-mm-sig@lists.linaro.org +Cc: # v5.4+ +Signed-off-by: Thomas Hellström +Reviewed-by: Christian König +Link: https://patchwork.freedesktop.org/patch/msgid/20211129152727.448908-1-thomas.hellstrom@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/dma-buf/dma-fence-array.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/drivers/dma-buf/dma-fence-array.c ++++ b/drivers/dma-buf/dma-fence-array.c +@@ -104,7 +104,11 @@ static bool dma_fence_array_signaled(str + { + struct dma_fence_array *array = to_dma_fence_array(fence); + +- return atomic_read(&array->num_pending) <= 0; ++ if (atomic_read(&array->num_pending) > 0) ++ return false; ++ ++ dma_fence_array_clear_pending_error(array); ++ return true; + } + + static void dma_fence_array_release(struct dma_fence *fence) diff --git a/queue-5.16/drm-rockchip-dsi-hold-pm-runtime-across-bind-unbind.patch b/queue-5.16/drm-rockchip-dsi-hold-pm-runtime-across-bind-unbind.patch new file mode 100644 index 00000000000..2b81cb5f0d2 --- /dev/null +++ b/queue-5.16/drm-rockchip-dsi-hold-pm-runtime-across-bind-unbind.patch @@ -0,0 +1,151 @@ +From 514db871922f103886ad4d221cf406b4fcc5e74a Mon Sep 17 00:00:00 2001 +From: Brian Norris +Date: Tue, 28 Sep 2021 14:35:49 -0700 +Subject: drm/rockchip: dsi: Hold pm-runtime across bind/unbind +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Brian Norris + +commit 514db871922f103886ad4d221cf406b4fcc5e74a upstream. + +In commit 43c2de1002d2 ("drm/rockchip: dsi: move all lane config except +LCDC mux to bind()"), we moved most HW configuration to bind(), but we +didn't move the runtime PM management. Therefore, depending on initial +boot state, runtime-PM workqueue delays, and other timing factors, we +may disable our power domain in between the hardware configuration +(bind()) and when we enable the display. This can cause us to lose +hardware state and fail to configure our display. For example: + + dw-mipi-dsi-rockchip ff968000.mipi: failed to write command FIFO + panel-innolux-p079zca ff960000.mipi.0: failed to write command 0 + +or: + + dw-mipi-dsi-rockchip ff968000.mipi: failed to write command FIFO + panel-kingdisplay-kd097d04 ff960000.mipi.0: failed write init cmds: -110 + +We should match the runtime PM to the lifetime of the bind()/unbind() +cycle. + +Tested on Acer Chrometab 10 (RK3399 Gru-Scarlet), with panel drivers +built either as modules or built-in. + +Side notes: it seems one is more likely to see this problem when the +panel driver is built into the kernel. I've also seen this problem +bisect down to commits that simply changed Kconfig dependencies, because +it changed the order in which driver init functions were compiled into +the kernel, and therefore the ordering and timing of built-in device +probe. + +Fixes: 43c2de1002d2 ("drm/rockchip: dsi: move all lane config except LCDC mux to bind()") +Link: https://lore.kernel.org/linux-rockchip/9aedfb528600ecf871885f7293ca4207c84d16c1.camel@gmail.com/ +Reported-by: +Cc: +Signed-off-by: Brian Norris +Tested-by: Nícolas F. R. A. Prado +Reviewed-by: Chen-Yu Tsai +Signed-off-by: Heiko Stuebner +Link: https://patchwork.freedesktop.org/patch/msgid/20210928143413.v3.1.Ic2904d37f30013a7f3d8476203ad3733c186827e@changeid +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c | 37 ++++++++++++------------ + 1 file changed, 19 insertions(+), 18 deletions(-) + +--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c ++++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c +@@ -772,10 +772,6 @@ static void dw_mipi_dsi_encoder_enable(s + if (mux < 0) + return; + +- pm_runtime_get_sync(dsi->dev); +- if (dsi->slave) +- pm_runtime_get_sync(dsi->slave->dev); +- + /* + * For the RK3399, the clk of grf must be enabled before writing grf + * register. And for RK3288 or other soc, this grf_clk must be NULL, +@@ -794,20 +790,10 @@ static void dw_mipi_dsi_encoder_enable(s + clk_disable_unprepare(dsi->grf_clk); + } + +-static void dw_mipi_dsi_encoder_disable(struct drm_encoder *encoder) +-{ +- struct dw_mipi_dsi_rockchip *dsi = to_dsi(encoder); +- +- if (dsi->slave) +- pm_runtime_put(dsi->slave->dev); +- pm_runtime_put(dsi->dev); +-} +- + static const struct drm_encoder_helper_funcs + dw_mipi_dsi_encoder_helper_funcs = { + .atomic_check = dw_mipi_dsi_encoder_atomic_check, + .enable = dw_mipi_dsi_encoder_enable, +- .disable = dw_mipi_dsi_encoder_disable, + }; + + static int rockchip_dsi_drm_create_encoder(struct dw_mipi_dsi_rockchip *dsi, +@@ -937,10 +923,14 @@ static int dw_mipi_dsi_rockchip_bind(str + put_device(second); + } + ++ pm_runtime_get_sync(dsi->dev); ++ if (dsi->slave) ++ pm_runtime_get_sync(dsi->slave->dev); ++ + ret = clk_prepare_enable(dsi->pllref_clk); + if (ret) { + DRM_DEV_ERROR(dev, "Failed to enable pllref_clk: %d\n", ret); +- return ret; ++ goto out_pm_runtime; + } + + /* +@@ -952,7 +942,7 @@ static int dw_mipi_dsi_rockchip_bind(str + ret = clk_prepare_enable(dsi->grf_clk); + if (ret) { + DRM_DEV_ERROR(dsi->dev, "Failed to enable grf_clk: %d\n", ret); +- return ret; ++ goto out_pm_runtime; + } + + dw_mipi_dsi_rockchip_config(dsi); +@@ -964,16 +954,23 @@ static int dw_mipi_dsi_rockchip_bind(str + ret = rockchip_dsi_drm_create_encoder(dsi, drm_dev); + if (ret) { + DRM_DEV_ERROR(dev, "Failed to create drm encoder\n"); +- return ret; ++ goto out_pm_runtime; + } + + ret = dw_mipi_dsi_bind(dsi->dmd, &dsi->encoder); + if (ret) { + DRM_DEV_ERROR(dev, "Failed to bind: %d\n", ret); +- return ret; ++ goto out_pm_runtime; + } + + return 0; ++ ++out_pm_runtime: ++ pm_runtime_put(dsi->dev); ++ if (dsi->slave) ++ pm_runtime_put(dsi->slave->dev); ++ ++ return ret; + } + + static void dw_mipi_dsi_rockchip_unbind(struct device *dev, +@@ -988,6 +985,10 @@ static void dw_mipi_dsi_rockchip_unbind( + dw_mipi_dsi_unbind(dsi->dmd); + + clk_disable_unprepare(dsi->pllref_clk); ++ ++ pm_runtime_put(dsi->dev); ++ if (dsi->slave) ++ pm_runtime_put(dsi->slave->dev); + } + + static const struct component_ops dw_mipi_dsi_rockchip_ops = { diff --git a/queue-5.16/drm-rockchip-dsi-reconfigure-hardware-on-resume.patch b/queue-5.16/drm-rockchip-dsi-reconfigure-hardware-on-resume.patch new file mode 100644 index 00000000000..1495dd628ac --- /dev/null +++ b/queue-5.16/drm-rockchip-dsi-reconfigure-hardware-on-resume.patch @@ -0,0 +1,115 @@ +From e584cdc1549932f87a2707b56bc588cfac5d89e0 Mon Sep 17 00:00:00 2001 +From: Brian Norris +Date: Tue, 28 Sep 2021 14:35:50 -0700 +Subject: drm/rockchip: dsi: Reconfigure hardware on resume() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Brian Norris + +commit e584cdc1549932f87a2707b56bc588cfac5d89e0 upstream. + +Since commit 43c2de1002d2 ("drm/rockchip: dsi: move all lane config except +LCDC mux to bind()"), we perform most HW configuration in the bind() +function. This configuration may be lost on suspend/resume, so we +need to call it again. That may lead to errors like this after system +suspend/resume: + + dw-mipi-dsi-rockchip ff968000.mipi: failed to write command FIFO + panel-kingdisplay-kd097d04 ff960000.mipi.0: failed write init cmds: -110 + +Tested on Acer Chromebook Tab 10 (RK3399 Gru-Scarlet). + +Note that early mailing list versions of this driver borrowed Rockchip's +downstream/BSP solution, to do HW configuration in mode_set() (which +*is* called at the appropriate pre-enable() times), but that was +discarded along the way. I've avoided that still, because mode_set() +documentation doesn't suggest this kind of purpose as far as I can tell. + +Fixes: 43c2de1002d2 ("drm/rockchip: dsi: move all lane config except LCDC mux to bind()") +Cc: +Signed-off-by: Brian Norris +Reviewed-by: Chen-Yu Tsai +Tested-by: Nícolas F. R. A. Prado +Signed-off-by: Heiko Stuebner +Link: https://patchwork.freedesktop.org/patch/msgid/20210928143413.v3.2.I4e9d93aadb00b1ffc7d506e3186a25492bf0b732@changeid +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c | 37 ++++++++++++++++++++++++ + 1 file changed, 37 insertions(+) + +--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c ++++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c +@@ -267,6 +267,8 @@ struct dw_mipi_dsi_rockchip { + struct dw_mipi_dsi *dmd; + const struct rockchip_dw_dsi_chip_data *cdata; + struct dw_mipi_dsi_plat_data pdata; ++ ++ bool dsi_bound; + }; + + struct dphy_pll_parameter_map { +@@ -963,6 +965,8 @@ static int dw_mipi_dsi_rockchip_bind(str + goto out_pm_runtime; + } + ++ dsi->dsi_bound = true; ++ + return 0; + + out_pm_runtime: +@@ -982,6 +986,8 @@ static void dw_mipi_dsi_rockchip_unbind( + if (dsi->is_slave) + return; + ++ dsi->dsi_bound = false; ++ + dw_mipi_dsi_unbind(dsi->dmd); + + clk_disable_unprepare(dsi->pllref_clk); +@@ -1276,6 +1282,36 @@ static const struct phy_ops dw_mipi_dsi_ + .exit = dw_mipi_dsi_dphy_exit, + }; + ++static int __maybe_unused dw_mipi_dsi_rockchip_resume(struct device *dev) ++{ ++ struct dw_mipi_dsi_rockchip *dsi = dev_get_drvdata(dev); ++ int ret; ++ ++ /* ++ * Re-configure DSI state, if we were previously initialized. We need ++ * to do this before rockchip_drm_drv tries to re-enable() any panels. ++ */ ++ if (dsi->dsi_bound) { ++ ret = clk_prepare_enable(dsi->grf_clk); ++ if (ret) { ++ DRM_DEV_ERROR(dsi->dev, "Failed to enable grf_clk: %d\n", ret); ++ return ret; ++ } ++ ++ dw_mipi_dsi_rockchip_config(dsi); ++ if (dsi->slave) ++ dw_mipi_dsi_rockchip_config(dsi->slave); ++ ++ clk_disable_unprepare(dsi->grf_clk); ++ } ++ ++ return 0; ++} ++ ++static const struct dev_pm_ops dw_mipi_dsi_rockchip_pm_ops = { ++ SET_LATE_SYSTEM_SLEEP_PM_OPS(NULL, dw_mipi_dsi_rockchip_resume) ++}; ++ + static int dw_mipi_dsi_rockchip_probe(struct platform_device *pdev) + { + struct device *dev = &pdev->dev; +@@ -1593,6 +1629,7 @@ struct platform_driver dw_mipi_dsi_rockc + .remove = dw_mipi_dsi_rockchip_remove, + .driver = { + .of_match_table = dw_mipi_dsi_rockchip_dt_ids, ++ .pm = &dw_mipi_dsi_rockchip_pm_ops, + .name = "dw-mipi-dsi-rockchip", + }, + }; diff --git a/queue-5.16/drm-tegra-add-back-arm_iommu_detach_device.patch b/queue-5.16/drm-tegra-add-back-arm_iommu_detach_device.patch new file mode 100644 index 00000000000..96a9ce95cb4 --- /dev/null +++ b/queue-5.16/drm-tegra-add-back-arm_iommu_detach_device.patch @@ -0,0 +1,57 @@ +From d210919dbdc8a82c676cc3e3c370b1802be63124 Mon Sep 17 00:00:00 2001 +From: Dmitry Osipenko +Date: Sat, 4 Dec 2021 17:58:49 +0300 +Subject: drm/tegra: Add back arm_iommu_detach_device() + +From: Dmitry Osipenko + +commit d210919dbdc8a82c676cc3e3c370b1802be63124 upstream. + +DMA buffers of 2D/3D engines aren't mapped properly when +CONFIG_ARM_DMA_USE_IOMMU=y. The memory management code of Tegra DRM driver +has a longstanding overhaul overdue and it's not obvious where the problem +is in this case. Hence let's add back the old workaround which we already +had sometime before. It explicitly detaches DRM devices from the offending +implicit IOMMU domain. This fixes a completely broken 2d/3d drivers in +case of ARM32 multiplatform kernel config. + +Cc: stable@vger.kernel.org +Fixes: fa6661b7aa0b ("drm/tegra: Optionally attach clients to the IOMMU") +Signed-off-by: Dmitry Osipenko +Signed-off-by: Thierry Reding +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/tegra/drm.c | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +--- a/drivers/gpu/drm/tegra/drm.c ++++ b/drivers/gpu/drm/tegra/drm.c +@@ -21,6 +21,10 @@ + #include + #include + ++#if IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU) ++#include ++#endif ++ + #include "dc.h" + #include "drm.h" + #include "gem.h" +@@ -936,6 +940,17 @@ int host1x_client_iommu_attach(struct ho + struct iommu_group *group = NULL; + int err; + ++#if IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU) ++ if (client->dev->archdata.mapping) { ++ struct dma_iommu_mapping *mapping = ++ to_dma_iommu_mapping(client->dev); ++ arm_iommu_detach_device(client->dev); ++ arm_iommu_release_mapping(mapping); ++ ++ domain = iommu_get_domain_for_dev(client->dev); ++ } ++#endif ++ + /* + * If the host1x client is already attached to an IOMMU domain that is + * not the shared IOMMU domain, don't try to attach it to a different diff --git a/queue-5.16/drm-ttm-put-bo-in-its-memory-manager-s-lru-list.patch b/queue-5.16/drm-ttm-put-bo-in-its-memory-manager-s-lru-list.patch new file mode 100644 index 00000000000..7b3f50223bb --- /dev/null +++ b/queue-5.16/drm-ttm-put-bo-in-its-memory-manager-s-lru-list.patch @@ -0,0 +1,36 @@ +From 781050b0a3164934857c300bb0bc291e38c26b6f Mon Sep 17 00:00:00 2001 +From: xinhui pan +Date: Wed, 10 Nov 2021 12:31:48 +0800 +Subject: drm/ttm: Put BO in its memory manager's lru list +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: xinhui pan + +commit 781050b0a3164934857c300bb0bc291e38c26b6f upstream. + +After we move BO to a new memory region, we should put it to +the new memory manager's lru list regardless we unlock the resv or not. + +Cc: stable@vger.kernel.org +Reviewed-by: Christian König +Signed-off-by: xinhui pan +Link: https://patchwork.freedesktop.org/patch/msgid/20211110043149.57554-1-xinhui.pan@amd.com +Signed-off-by: Christian König +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/ttm/ttm_bo.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/gpu/drm/ttm/ttm_bo.c ++++ b/drivers/gpu/drm/ttm/ttm_bo.c +@@ -727,6 +727,8 @@ int ttm_mem_evict_first(struct ttm_devic + ret = ttm_bo_evict(bo, ctx); + if (locked) + ttm_bo_unreserve(bo); ++ else ++ ttm_bo_move_to_lru_tail_unlocked(bo); + + ttm_bo_put(bo); + return ret; diff --git a/queue-5.16/gpu-host1x-add-back-arm_iommu_detach_device.patch b/queue-5.16/gpu-host1x-add-back-arm_iommu_detach_device.patch new file mode 100644 index 00000000000..79306caa0da --- /dev/null +++ b/queue-5.16/gpu-host1x-add-back-arm_iommu_detach_device.patch @@ -0,0 +1,57 @@ +From d5185965c3b59073c4520bad7dd2adf725b9abba Mon Sep 17 00:00:00 2001 +From: Dmitry Osipenko +Date: Sat, 4 Dec 2021 17:58:48 +0300 +Subject: gpu: host1x: Add back arm_iommu_detach_device() + +From: Dmitry Osipenko + +commit d5185965c3b59073c4520bad7dd2adf725b9abba upstream. + +Host1x DMA buffer isn't mapped properly when CONFIG_ARM_DMA_USE_IOMMU=y. +The memory management code of Host1x driver has a longstanding overhaul +overdue and it's not obvious where the problem is in this case. Hence +let's add back the old workaround which we already had sometime before. +It explicitly detaches Host1x device from the offending implicit IOMMU +domain. This fixes a completely broken Host1x DMA in case of ARM32 +multiplatform kernel config. + +Cc: stable@vger.kernel.org +Fixes: af1cbfb9bf0f ("gpu: host1x: Support DMA mapping of buffers") +Signed-off-by: Dmitry Osipenko +Signed-off-by: Thierry Reding +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/host1x/dev.c | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +--- a/drivers/gpu/host1x/dev.c ++++ b/drivers/gpu/host1x/dev.c +@@ -18,6 +18,10 @@ + #include + #undef CREATE_TRACE_POINTS + ++#if IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU) ++#include ++#endif ++ + #include "bus.h" + #include "channel.h" + #include "debug.h" +@@ -238,6 +242,17 @@ static struct iommu_domain *host1x_iommu + struct iommu_domain *domain = iommu_get_domain_for_dev(host->dev); + int err; + ++#if IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU) ++ if (host->dev->archdata.mapping) { ++ struct dma_iommu_mapping *mapping = ++ to_dma_iommu_mapping(host->dev); ++ arm_iommu_detach_device(host->dev); ++ arm_iommu_release_mapping(mapping); ++ ++ domain = iommu_get_domain_for_dev(host->dev); ++ } ++#endif ++ + /* + * We may not always want to enable IOMMU support (for example if the + * host1x firewall is already enabled and we don't support addressing diff --git a/queue-5.16/iio-adc-ti-adc081c-partial-revert-of-removal-of-acpi-ids.patch b/queue-5.16/iio-adc-ti-adc081c-partial-revert-of-removal-of-acpi-ids.patch new file mode 100644 index 00000000000..9ef1d13d8d6 --- /dev/null +++ b/queue-5.16/iio-adc-ti-adc081c-partial-revert-of-removal-of-acpi-ids.patch @@ -0,0 +1,88 @@ +From c9791a94384af07592d29504004d2255dbaf8663 Mon Sep 17 00:00:00 2001 +From: Jonathan Cameron +Date: Sun, 5 Dec 2021 17:27:28 +0000 +Subject: iio: adc: ti-adc081c: Partial revert of removal of ACPI IDs + +From: Jonathan Cameron + +commit c9791a94384af07592d29504004d2255dbaf8663 upstream. + +Unfortuanately a non standards compliant ACPI ID is known to be +in the wild on some AAEON boards. + +Partly revert the removal of these IDs so that ADC081C will again +work + add a comment to that affect for future reference. + +Whilst here use generic firmware properties rather than the ACPI +specific handling previously found in this driver. + +Reported-by: Kunyang Fan +Fixes: c458b7ca3fd0 ("iio:adc:ti-adc081c: Drop ACPI ids that seem very unlikely to be official.") +Signed-off-by: Jonathan Cameron +Cc: Andy Shevchenko +Tested-by: Kunyang Fan #UP-extremei11 +Link: https://lore.kernel.org/r/20211205172728.2826512-1-jic23@kernel.org +Cc: +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iio/adc/ti-adc081c.c | 22 +++++++++++++++++----- + 1 file changed, 17 insertions(+), 5 deletions(-) + +--- a/drivers/iio/adc/ti-adc081c.c ++++ b/drivers/iio/adc/ti-adc081c.c +@@ -19,6 +19,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -156,13 +157,16 @@ static int adc081c_probe(struct i2c_clie + { + struct iio_dev *iio; + struct adc081c *adc; +- struct adcxx1c_model *model; ++ const struct adcxx1c_model *model; + int err; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA)) + return -EOPNOTSUPP; + +- model = &adcxx1c_models[id->driver_data]; ++ if (dev_fwnode(&client->dev)) ++ model = device_get_match_data(&client->dev); ++ else ++ model = &adcxx1c_models[id->driver_data]; + + iio = devm_iio_device_alloc(&client->dev, sizeof(*adc)); + if (!iio) +@@ -210,10 +214,17 @@ static const struct i2c_device_id adc081 + }; + MODULE_DEVICE_TABLE(i2c, adc081c_id); + ++static const struct acpi_device_id adc081c_acpi_match[] = { ++ /* Used on some AAEON boards */ ++ { "ADC081C", (kernel_ulong_t)&adcxx1c_models[ADC081C] }, ++ { } ++}; ++MODULE_DEVICE_TABLE(acpi, adc081c_acpi_match); ++ + static const struct of_device_id adc081c_of_match[] = { +- { .compatible = "ti,adc081c" }, +- { .compatible = "ti,adc101c" }, +- { .compatible = "ti,adc121c" }, ++ { .compatible = "ti,adc081c", .data = &adcxx1c_models[ADC081C] }, ++ { .compatible = "ti,adc101c", .data = &adcxx1c_models[ADC101C] }, ++ { .compatible = "ti,adc121c", .data = &adcxx1c_models[ADC121C] }, + { } + }; + MODULE_DEVICE_TABLE(of, adc081c_of_match); +@@ -222,6 +233,7 @@ static struct i2c_driver adc081c_driver + .driver = { + .name = "adc081c", + .of_match_table = adc081c_of_match, ++ .acpi_match_table = adc081c_acpi_match, + }, + .probe = adc081c_probe, + .id_table = adc081c_id, diff --git a/queue-5.16/iio-trigger-fix-a-scheduling-whilst-atomic-issue-seen-on-tsc2046.patch b/queue-5.16/iio-trigger-fix-a-scheduling-whilst-atomic-issue-seen-on-tsc2046.patch new file mode 100644 index 00000000000..87c96c4fc76 --- /dev/null +++ b/queue-5.16/iio-trigger-fix-a-scheduling-whilst-atomic-issue-seen-on-tsc2046.patch @@ -0,0 +1,121 @@ +From 9020ef659885f2622cfb386cc229b6d618362895 Mon Sep 17 00:00:00 2001 +From: Jonathan Cameron +Date: Sun, 17 Oct 2021 18:22:09 +0100 +Subject: iio: trigger: Fix a scheduling whilst atomic issue seen on tsc2046 + +From: Jonathan Cameron + +commit 9020ef659885f2622cfb386cc229b6d618362895 upstream. + +IIO triggers are software IRQ chips that split an incoming IRQ into +separate IRQs routed to all devices using the trigger. +When all consumers are done then a trigger callback reenable() is +called. There are a few circumstances under which this can happen +in atomic context. + +1) A single user of the trigger that calls the iio_trigger_done() +function from interrupt context. +2) A race between disconnecting the last device from a trigger and +the trigger itself sucessfully being disabled. + +To avoid a resulting scheduling whilst atomic, close this second corner +by using schedule_work() to ensure the reenable is not done in atomic +context. + +Note that drivers must be careful to manage the interaction of +set_state() and reenable() callbacks to ensure appropriate reference +counting if they are relying on the same hardware controls. + +Deliberately taking this the slow path rather than via a fixes tree +because the error has hard to hit and I would like it to soak for a while +before hitting a release kernel. + +Signed-off-by: Jonathan Cameron +Cc: Pengutronix Kernel Team +Cc: Dmitry Torokhov +Tested-by: Oleksij Rempel +Cc: +Link: https://lore.kernel.org/r/20211017172209.112387-1-jic23@kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iio/industrialio-trigger.c | 36 +++++++++++++++++++++++++++++++++++- + include/linux/iio/trigger.h | 2 ++ + 2 files changed, 37 insertions(+), 1 deletion(-) + +--- a/drivers/iio/industrialio-trigger.c ++++ b/drivers/iio/industrialio-trigger.c +@@ -162,6 +162,39 @@ static struct iio_trigger *iio_trigger_a + return trig; + } + ++static void iio_reenable_work_fn(struct work_struct *work) ++{ ++ struct iio_trigger *trig = container_of(work, struct iio_trigger, ++ reenable_work); ++ ++ /* ++ * This 'might' occur after the trigger state is set to disabled - ++ * in that case the driver should skip reenabling. ++ */ ++ trig->ops->reenable(trig); ++} ++ ++/* ++ * In general, reenable callbacks may need to sleep and this path is ++ * not performance sensitive, so just queue up a work item ++ * to reneable the trigger for us. ++ * ++ * Races that can cause this. ++ * 1) A handler occurs entirely in interrupt context so the counter ++ * the final decrement is still in this interrupt. ++ * 2) The trigger has been removed, but one last interrupt gets through. ++ * ++ * For (1) we must call reenable, but not in atomic context. ++ * For (2) it should be safe to call reenanble, if drivers never blindly ++ * reenable after state is off. ++ */ ++static void iio_trigger_notify_done_atomic(struct iio_trigger *trig) ++{ ++ if (atomic_dec_and_test(&trig->use_count) && trig->ops && ++ trig->ops->reenable) ++ schedule_work(&trig->reenable_work); ++} ++ + void iio_trigger_poll(struct iio_trigger *trig) + { + int i; +@@ -173,7 +206,7 @@ void iio_trigger_poll(struct iio_trigger + if (trig->subirqs[i].enabled) + generic_handle_irq(trig->subirq_base + i); + else +- iio_trigger_notify_done(trig); ++ iio_trigger_notify_done_atomic(trig); + } + } + } +@@ -535,6 +568,7 @@ struct iio_trigger *viio_trigger_alloc(s + trig->dev.type = &iio_trig_type; + trig->dev.bus = &iio_bus_type; + device_initialize(&trig->dev); ++ INIT_WORK(&trig->reenable_work, iio_reenable_work_fn); + + mutex_init(&trig->pool_lock); + trig->subirq_base = irq_alloc_descs(-1, 0, +--- a/include/linux/iio/trigger.h ++++ b/include/linux/iio/trigger.h +@@ -55,6 +55,7 @@ struct iio_trigger_ops { + * @attached_own_device:[INTERN] if we are using our own device as trigger, + * i.e. if we registered a poll function to the same + * device as the one providing the trigger. ++ * @reenable_work: [INTERN] work item used to ensure reenable can sleep. + **/ + struct iio_trigger { + const struct iio_trigger_ops *ops; +@@ -74,6 +75,7 @@ struct iio_trigger { + unsigned long pool[BITS_TO_LONGS(CONFIG_IIO_CONSUMERS_PER_TRIGGER)]; + struct mutex pool_lock; + bool attached_own_device; ++ struct work_struct reenable_work; + }; + + diff --git a/queue-5.16/io_uring-fix-no-lock-protection-for-ctx-cq_extra.patch b/queue-5.16/io_uring-fix-no-lock-protection-for-ctx-cq_extra.patch new file mode 100644 index 00000000000..f97e60544b1 --- /dev/null +++ b/queue-5.16/io_uring-fix-no-lock-protection-for-ctx-cq_extra.patch @@ -0,0 +1,39 @@ +From e302f1046f4c209291b07ff7bc4d15ca26891f16 Mon Sep 17 00:00:00 2001 +From: Hao Xu +Date: Thu, 25 Nov 2021 17:21:02 +0800 +Subject: io_uring: fix no lock protection for ctx->cq_extra + +From: Hao Xu + +commit e302f1046f4c209291b07ff7bc4d15ca26891f16 upstream. + +ctx->cq_extra should be protected by completion lock so that the +req_need_defer() does the right check. + +Cc: stable@vger.kernel.org +Signed-off-by: Hao Xu +Link: https://lore.kernel.org/r/20211125092103.224502-2-haoxu@linux.alibaba.com +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman +--- + fs/io_uring.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/fs/io_uring.c ++++ b/fs/io_uring.c +@@ -6544,12 +6544,15 @@ static __cold void io_drain_req(struct i + u32 seq = io_get_sequence(req); + + /* Still need defer if there is pending req in defer list. */ ++ spin_lock(&ctx->completion_lock); + if (!req_need_defer(req, seq) && list_empty_careful(&ctx->defer_list)) { ++ spin_unlock(&ctx->completion_lock); + queue: + ctx->drain_active = false; + io_req_task_queue(req); + return; + } ++ spin_unlock(&ctx->completion_lock); + + ret = io_req_prep_async(req); + if (ret) { diff --git a/queue-5.16/iommu-io-pgtable-arm-v7s-add-error-handle-for-page-table-allocation-failure.patch b/queue-5.16/iommu-io-pgtable-arm-v7s-add-error-handle-for-page-table-allocation-failure.patch new file mode 100644 index 00000000000..11a1984fa88 --- /dev/null +++ b/queue-5.16/iommu-io-pgtable-arm-v7s-add-error-handle-for-page-table-allocation-failure.patch @@ -0,0 +1,49 @@ +From a556cfe4cabc6d79cbb7733f118bbb420b376fe6 Mon Sep 17 00:00:00 2001 +From: Yunfei Wang +Date: Tue, 7 Dec 2021 19:33:15 +0800 +Subject: iommu/io-pgtable-arm-v7s: Add error handle for page table allocation failure + +From: Yunfei Wang + +commit a556cfe4cabc6d79cbb7733f118bbb420b376fe6 upstream. + +In __arm_v7s_alloc_table function: +iommu call kmem_cache_alloc to allocate page table, this function +allocate memory may fail, when kmem_cache_alloc fails to allocate +table, call virt_to_phys will be abnomal and return unexpected phys +and goto out_free, then call kmem_cache_free to release table will +trigger KE, __get_free_pages and free_pages have similar problem, +so add error handle for page table allocation failure. + +Fixes: 29859aeb8a6e ("iommu/io-pgtable-arm-v7s: Abort allocation when table address overflows the PTE") +Signed-off-by: Yunfei Wang +Cc: # 5.10.* +Acked-by: Robin Murphy +Link: https://lore.kernel.org/r/20211207113315.29109-1-yf.wang@mediatek.com +Signed-off-by: Will Deacon +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iommu/io-pgtable-arm-v7s.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/drivers/iommu/io-pgtable-arm-v7s.c ++++ b/drivers/iommu/io-pgtable-arm-v7s.c +@@ -246,13 +246,17 @@ static void *__arm_v7s_alloc_table(int l + __GFP_ZERO | ARM_V7S_TABLE_GFP_DMA, get_order(size)); + else if (lvl == 2) + table = kmem_cache_zalloc(data->l2_tables, gfp); ++ ++ if (!table) ++ return NULL; ++ + phys = virt_to_phys(table); + if (phys != (arm_v7s_iopte)phys) { + /* Doesn't fit in PTE */ + dev_err(dev, "Page table does not fit in PTE: %pa", &phys); + goto out_free; + } +- if (table && !cfg->coherent_walk) { ++ if (!cfg->coherent_walk) { + dma = dma_map_single(dev, table, size, DMA_TO_DEVICE); + if (dma_mapping_error(dev, dma)) + goto out_free; diff --git a/queue-5.16/ksmbd-add-reserved-room-in-ipc-request-response.patch b/queue-5.16/ksmbd-add-reserved-room-in-ipc-request-response.patch new file mode 100644 index 00000000000..8b4707530c7 --- /dev/null +++ b/queue-5.16/ksmbd-add-reserved-room-in-ipc-request-response.patch @@ -0,0 +1,104 @@ +From 41dbda16a0902798e732abc6599de256b9dc3b27 Mon Sep 17 00:00:00 2001 +From: Namjae Jeon +Date: Thu, 6 Jan 2022 10:30:31 +0900 +Subject: ksmbd: add reserved room in ipc request/response + +From: Namjae Jeon + +commit 41dbda16a0902798e732abc6599de256b9dc3b27 upstream. + +Whenever new parameter is added to smb configuration, It is possible +to break the execution of the IPC daemon by mismatch size of +request/response. This patch tries to reserve space in ipc request/response +in advance to prevent that. + +Signed-off-by: Namjae Jeon +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman +--- + fs/ksmbd/ksmbd_netlink.h | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +--- a/fs/ksmbd/ksmbd_netlink.h ++++ b/fs/ksmbd/ksmbd_netlink.h +@@ -104,6 +104,7 @@ struct ksmbd_startup_request { + */ + __u32 sub_auth[3]; /* Subauth value for Security ID */ + __u32 smb2_max_credits; /* MAX credits */ ++ __u32 reserved[128]; /* Reserved room */ + __u32 ifc_list_sz; /* interfaces list size */ + __s8 ____payload[]; + }; +@@ -114,7 +115,7 @@ struct ksmbd_startup_request { + * IPC request to shutdown ksmbd server. + */ + struct ksmbd_shutdown_request { +- __s32 reserved; ++ __s32 reserved[16]; + }; + + /* +@@ -123,6 +124,7 @@ struct ksmbd_shutdown_request { + struct ksmbd_login_request { + __u32 handle; + __s8 account[KSMBD_REQ_MAX_ACCOUNT_NAME_SZ]; /* user account name */ ++ __u32 reserved[16]; /* Reserved room */ + }; + + /* +@@ -136,6 +138,7 @@ struct ksmbd_login_response { + __u16 status; + __u16 hash_sz; /* hash size */ + __s8 hash[KSMBD_REQ_MAX_HASH_SZ]; /* password hash */ ++ __u32 reserved[16]; /* Reserved room */ + }; + + /* +@@ -144,6 +147,7 @@ struct ksmbd_login_response { + struct ksmbd_share_config_request { + __u32 handle; + __s8 share_name[KSMBD_REQ_MAX_SHARE_NAME]; /* share name */ ++ __u32 reserved[16]; /* Reserved room */ + }; + + /* +@@ -158,6 +162,7 @@ struct ksmbd_share_config_response { + __u16 force_directory_mode; + __u16 force_uid; + __u16 force_gid; ++ __u32 reserved[128]; /* Reserved room */ + __u32 veto_list_sz; + __s8 ____payload[]; + }; +@@ -188,6 +193,7 @@ struct ksmbd_tree_connect_request { + __s8 account[KSMBD_REQ_MAX_ACCOUNT_NAME_SZ]; + __s8 share[KSMBD_REQ_MAX_SHARE_NAME]; + __s8 peer_addr[64]; ++ __u32 reserved[16]; /* Reserved room */ + }; + + /* +@@ -197,6 +203,7 @@ struct ksmbd_tree_connect_response { + __u32 handle; + __u16 status; + __u16 connection_flags; ++ __u32 reserved[16]; /* Reserved room */ + }; + + /* +@@ -205,6 +212,7 @@ struct ksmbd_tree_connect_response { + struct ksmbd_tree_disconnect_request { + __u64 session_id; /* session id */ + __u64 connect_id; /* tree connection id */ ++ __u32 reserved[16]; /* Reserved room */ + }; + + /* +@@ -213,6 +221,7 @@ struct ksmbd_tree_disconnect_request { + struct ksmbd_logout_request { + __s8 account[KSMBD_REQ_MAX_ACCOUNT_NAME_SZ]; /* user account name */ + __u32 account_flags; ++ __u32 reserved[16]; /* Reserved room */ + }; + + /* diff --git a/queue-5.16/ksmbd-add-support-for-smb2-max-credit-parameter.patch b/queue-5.16/ksmbd-add-support-for-smb2-max-credit-parameter.patch new file mode 100644 index 00000000000..cd9a19a586d --- /dev/null +++ b/queue-5.16/ksmbd-add-support-for-smb2-max-credit-parameter.patch @@ -0,0 +1,193 @@ +From 004443b3f6d722b455cf963ed7c3edd7f4772405 Mon Sep 17 00:00:00 2001 +From: Namjae Jeon +Date: Wed, 29 Dec 2021 23:08:46 +0900 +Subject: ksmbd: add support for smb2 max credit parameter + +From: Namjae Jeon + +commit 004443b3f6d722b455cf963ed7c3edd7f4772405 upstream. + +Add smb2 max credits parameter to adjust maximum credits value to limit +number of outstanding requests. + +Signed-off-by: Namjae Jeon +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman +--- + fs/ksmbd/connection.h | 1 - + fs/ksmbd/ksmbd_netlink.h | 1 + + fs/ksmbd/smb2misc.c | 2 +- + fs/ksmbd/smb2ops.c | 16 ++++++++++++---- + fs/ksmbd/smb2pdu.c | 8 ++++---- + fs/ksmbd/smb2pdu.h | 1 + + fs/ksmbd/smb_common.h | 1 + + fs/ksmbd/transport_ipc.c | 2 ++ + 8 files changed, 22 insertions(+), 10 deletions(-) + +--- a/fs/ksmbd/connection.h ++++ b/fs/ksmbd/connection.h +@@ -62,7 +62,6 @@ struct ksmbd_conn { + /* References which are made for this Server object*/ + atomic_t r_count; + unsigned short total_credits; +- unsigned short max_credits; + spinlock_t credits_lock; + wait_queue_head_t req_running_q; + /* Lock to protect requests list*/ +--- a/fs/ksmbd/ksmbd_netlink.h ++++ b/fs/ksmbd/ksmbd_netlink.h +@@ -103,6 +103,7 @@ struct ksmbd_startup_request { + * we set the SPARSE_FILES bit (0x40). + */ + __u32 sub_auth[3]; /* Subauth value for Security ID */ ++ __u32 smb2_max_credits; /* MAX credits */ + __u32 ifc_list_sz; /* interfaces list size */ + __s8 ____payload[]; + }; +--- a/fs/ksmbd/smb2misc.c ++++ b/fs/ksmbd/smb2misc.c +@@ -326,7 +326,7 @@ static int smb2_validate_credit_charge(s + ksmbd_debug(SMB, "Insufficient credit charge, given: %d, needed: %d\n", + credit_charge, calc_credit_num); + return 1; +- } else if (credit_charge > conn->max_credits) { ++ } else if (credit_charge > conn->vals->max_credits) { + ksmbd_debug(SMB, "Too large credit charge: %d\n", credit_charge); + return 1; + } +--- a/fs/ksmbd/smb2ops.c ++++ b/fs/ksmbd/smb2ops.c +@@ -19,6 +19,7 @@ static struct smb_version_values smb21_s + .max_read_size = SMB21_DEFAULT_IOSIZE, + .max_write_size = SMB21_DEFAULT_IOSIZE, + .max_trans_size = SMB21_DEFAULT_IOSIZE, ++ .max_credits = SMB2_MAX_CREDITS, + .large_lock_type = 0, + .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE, + .shared_lock_type = SMB2_LOCKFLAG_SHARED, +@@ -44,6 +45,7 @@ static struct smb_version_values smb30_s + .max_read_size = SMB3_DEFAULT_IOSIZE, + .max_write_size = SMB3_DEFAULT_IOSIZE, + .max_trans_size = SMB3_DEFAULT_TRANS_SIZE, ++ .max_credits = SMB2_MAX_CREDITS, + .large_lock_type = 0, + .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE, + .shared_lock_type = SMB2_LOCKFLAG_SHARED, +@@ -70,6 +72,7 @@ static struct smb_version_values smb302_ + .max_read_size = SMB3_DEFAULT_IOSIZE, + .max_write_size = SMB3_DEFAULT_IOSIZE, + .max_trans_size = SMB3_DEFAULT_TRANS_SIZE, ++ .max_credits = SMB2_MAX_CREDITS, + .large_lock_type = 0, + .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE, + .shared_lock_type = SMB2_LOCKFLAG_SHARED, +@@ -96,6 +99,7 @@ static struct smb_version_values smb311_ + .max_read_size = SMB3_DEFAULT_IOSIZE, + .max_write_size = SMB3_DEFAULT_IOSIZE, + .max_trans_size = SMB3_DEFAULT_TRANS_SIZE, ++ .max_credits = SMB2_MAX_CREDITS, + .large_lock_type = 0, + .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE, + .shared_lock_type = SMB2_LOCKFLAG_SHARED, +@@ -197,7 +201,6 @@ void init_smb2_1_server(struct ksmbd_con + conn->ops = &smb2_0_server_ops; + conn->cmds = smb2_0_server_cmds; + conn->max_cmds = ARRAY_SIZE(smb2_0_server_cmds); +- conn->max_credits = SMB2_MAX_CREDITS; + conn->signing_algorithm = SIGNING_ALG_HMAC_SHA256_LE; + + if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_LEASES) +@@ -215,7 +218,6 @@ void init_smb3_0_server(struct ksmbd_con + conn->ops = &smb3_0_server_ops; + conn->cmds = smb2_0_server_cmds; + conn->max_cmds = ARRAY_SIZE(smb2_0_server_cmds); +- conn->max_credits = SMB2_MAX_CREDITS; + conn->signing_algorithm = SIGNING_ALG_AES_CMAC_LE; + + if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_LEASES) +@@ -240,7 +242,6 @@ void init_smb3_02_server(struct ksmbd_co + conn->ops = &smb3_0_server_ops; + conn->cmds = smb2_0_server_cmds; + conn->max_cmds = ARRAY_SIZE(smb2_0_server_cmds); +- conn->max_credits = SMB2_MAX_CREDITS; + conn->signing_algorithm = SIGNING_ALG_AES_CMAC_LE; + + if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_LEASES) +@@ -265,7 +266,6 @@ int init_smb3_11_server(struct ksmbd_con + conn->ops = &smb3_11_server_ops; + conn->cmds = smb2_0_server_cmds; + conn->max_cmds = ARRAY_SIZE(smb2_0_server_cmds); +- conn->max_credits = SMB2_MAX_CREDITS; + conn->signing_algorithm = SIGNING_ALG_AES_CMAC_LE; + + if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_LEASES) +@@ -304,3 +304,11 @@ void init_smb2_max_trans_size(unsigned i + smb302_server_values.max_trans_size = sz; + smb311_server_values.max_trans_size = sz; + } ++ ++void init_smb2_max_credits(unsigned int sz) ++{ ++ smb21_server_values.max_credits = sz; ++ smb30_server_values.max_credits = sz; ++ smb302_server_values.max_credits = sz; ++ smb311_server_values.max_credits = sz; ++} +--- a/fs/ksmbd/smb2pdu.c ++++ b/fs/ksmbd/smb2pdu.c +@@ -308,7 +308,7 @@ int smb2_set_rsp_credits(struct ksmbd_wo + + hdr->CreditCharge = req_hdr->CreditCharge; + +- if (conn->total_credits > conn->max_credits) { ++ if (conn->total_credits > conn->vals->max_credits) { + hdr->CreditRequest = 0; + pr_err("Total credits overflow: %d\n", conn->total_credits); + return -EINVAL; +@@ -329,12 +329,12 @@ int smb2_set_rsp_credits(struct ksmbd_wo + if (hdr->Command == SMB2_NEGOTIATE) + aux_max = 0; + else +- aux_max = conn->max_credits - credit_charge; ++ aux_max = conn->vals->max_credits - credit_charge; + aux_credits = min_t(unsigned short, aux_credits, aux_max); + credits_granted = credit_charge + aux_credits; + +- if (conn->max_credits - conn->total_credits < credits_granted) +- credits_granted = conn->max_credits - ++ if (conn->vals->max_credits - conn->total_credits < credits_granted) ++ credits_granted = conn->vals->max_credits - + conn->total_credits; + + conn->total_credits += credits_granted; +--- a/fs/ksmbd/smb2pdu.h ++++ b/fs/ksmbd/smb2pdu.h +@@ -980,6 +980,7 @@ int init_smb3_11_server(struct ksmbd_con + void init_smb2_max_read_size(unsigned int sz); + void init_smb2_max_write_size(unsigned int sz); + void init_smb2_max_trans_size(unsigned int sz); ++void init_smb2_max_credits(unsigned int sz); + + bool is_smb2_neg_cmd(struct ksmbd_work *work); + bool is_smb2_rsp(struct ksmbd_work *work); +--- a/fs/ksmbd/smb_common.h ++++ b/fs/ksmbd/smb_common.h +@@ -365,6 +365,7 @@ struct smb_version_values { + __u32 max_read_size; + __u32 max_write_size; + __u32 max_trans_size; ++ __u32 max_credits; + __u32 large_lock_type; + __u32 exclusive_lock_type; + __u32 shared_lock_type; +--- a/fs/ksmbd/transport_ipc.c ++++ b/fs/ksmbd/transport_ipc.c +@@ -301,6 +301,8 @@ static int ipc_server_config_on_startup( + init_smb2_max_write_size(req->smb2_max_write); + if (req->smb2_max_trans) + init_smb2_max_trans_size(req->smb2_max_trans); ++ if (req->smb2_max_credits) ++ init_smb2_max_credits(req->smb2_max_credits); + + ret = ksmbd_set_netbios_name(req->netbios_name); + ret |= ksmbd_set_server_string(req->server_string); diff --git a/queue-5.16/ksmbd-fix-guest-connection-failure-with-nautilus.patch b/queue-5.16/ksmbd-fix-guest-connection-failure-with-nautilus.patch new file mode 100644 index 00000000000..f0f023b414c --- /dev/null +++ b/queue-5.16/ksmbd-fix-guest-connection-failure-with-nautilus.patch @@ -0,0 +1,115 @@ +From ac090d9c90b087d6fb714e54b2a6dd1e6c373ed6 Mon Sep 17 00:00:00 2001 +From: Namjae Jeon +Date: Mon, 17 Jan 2022 22:16:01 +0900 +Subject: ksmbd: fix guest connection failure with nautilus + +From: Namjae Jeon + +commit ac090d9c90b087d6fb714e54b2a6dd1e6c373ed6 upstream. + +MS-SMB2 describe session sign like the following. +Session.SigningRequired MUST be set to TRUE under the following conditions: + - If the SMB2_NEGOTIATE_SIGNING_REQUIRED bit is set in the SecurityMode + field of the client request. + - If the SMB2_SESSION_FLAG_IS_GUEST bit is not set in the SessionFlags + field and Session.IsAnonymous is FALSE and either Connection.ShouldSign + or global RequireMessageSigning is TRUE. + +When trying guest account connection using nautilus, The login failure +happened on session setup. ksmbd does not allow this connection +when the user is a guest and the connection sign is set. Just do not set +session sign instead of error response as described in the specification. +And this change improves the guest connection in Nautilus. + +Fixes: e2f34481b24d ("cifsd: add server-side procedures for SMB3") +Cc: stable@vger.kernel.org # v5.15+ +Signed-off-by: Namjae Jeon +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman +--- + fs/ksmbd/smb2pdu.c | 64 ++++++++++++++++++++++++----------------------------- + 1 file changed, 30 insertions(+), 34 deletions(-) + +--- a/fs/ksmbd/smb2pdu.c ++++ b/fs/ksmbd/smb2pdu.c +@@ -1455,11 +1455,6 @@ static int ntlm_authenticate(struct ksmb + + sess->user = user; + if (user_guest(sess->user)) { +- if (conn->sign) { +- ksmbd_debug(SMB, "Guest login not allowed when signing enabled\n"); +- return -EPERM; +- } +- + rsp->SessionFlags = SMB2_SESSION_FLAG_IS_GUEST_LE; + } else { + struct authenticate_message *authblob; +@@ -1472,38 +1467,39 @@ static int ntlm_authenticate(struct ksmb + ksmbd_debug(SMB, "authentication failed\n"); + return -EPERM; + } ++ } + +- /* +- * If session state is SMB2_SESSION_VALID, We can assume +- * that it is reauthentication. And the user/password +- * has been verified, so return it here. +- */ +- if (sess->state == SMB2_SESSION_VALID) { +- if (conn->binding) +- goto binding_session; +- return 0; +- } ++ /* ++ * If session state is SMB2_SESSION_VALID, We can assume ++ * that it is reauthentication. And the user/password ++ * has been verified, so return it here. ++ */ ++ if (sess->state == SMB2_SESSION_VALID) { ++ if (conn->binding) ++ goto binding_session; ++ return 0; ++ } + +- if ((conn->sign || server_conf.enforced_signing) || +- (req->SecurityMode & SMB2_NEGOTIATE_SIGNING_REQUIRED)) +- sess->sign = true; +- +- if (smb3_encryption_negotiated(conn) && +- !(req->Flags & SMB2_SESSION_REQ_FLAG_BINDING)) { +- rc = conn->ops->generate_encryptionkey(sess); +- if (rc) { +- ksmbd_debug(SMB, +- "SMB3 encryption key generation failed\n"); +- return -EINVAL; +- } +- sess->enc = true; +- rsp->SessionFlags = SMB2_SESSION_FLAG_ENCRYPT_DATA_LE; +- /* +- * signing is disable if encryption is enable +- * on this session +- */ +- sess->sign = false; ++ if ((rsp->SessionFlags != SMB2_SESSION_FLAG_IS_GUEST_LE && ++ (conn->sign || server_conf.enforced_signing)) || ++ (req->SecurityMode & SMB2_NEGOTIATE_SIGNING_REQUIRED)) ++ sess->sign = true; ++ ++ if (smb3_encryption_negotiated(conn) && ++ !(req->Flags & SMB2_SESSION_REQ_FLAG_BINDING)) { ++ rc = conn->ops->generate_encryptionkey(sess); ++ if (rc) { ++ ksmbd_debug(SMB, ++ "SMB3 encryption key generation failed\n"); ++ return -EINVAL; + } ++ sess->enc = true; ++ rsp->SessionFlags = SMB2_SESSION_FLAG_ENCRYPT_DATA_LE; ++ /* ++ * signing is disable if encryption is enable ++ * on this session ++ */ ++ sess->sign = false; + } + + binding_session: diff --git a/queue-5.16/ksmbd-limits-exceeding-the-maximum-allowable-outstanding-requests.patch b/queue-5.16/ksmbd-limits-exceeding-the-maximum-allowable-outstanding-requests.patch new file mode 100644 index 00000000000..4874e54b0cb --- /dev/null +++ b/queue-5.16/ksmbd-limits-exceeding-the-maximum-allowable-outstanding-requests.patch @@ -0,0 +1,74 @@ +From b589f5db6d4af8f14d70e31e1276b4c017668a26 Mon Sep 17 00:00:00 2001 +From: Namjae Jeon +Date: Fri, 31 Dec 2021 09:26:25 +0900 +Subject: ksmbd: limits exceeding the maximum allowable outstanding requests + +From: Namjae Jeon + +commit b589f5db6d4af8f14d70e31e1276b4c017668a26 upstream. + +If the client ignores the CreditResponse received from the server and +continues to send the request, ksmbd limits the requests if it exceeds +smb2 max credits. + +Signed-off-by: Namjae Jeon +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman +--- + fs/ksmbd/connection.c | 1 + + fs/ksmbd/connection.h | 3 ++- + fs/ksmbd/smb2misc.c | 9 +++++++++ + fs/ksmbd/smb2pdu.c | 1 + + 4 files changed, 13 insertions(+), 1 deletion(-) + +--- a/fs/ksmbd/connection.c ++++ b/fs/ksmbd/connection.c +@@ -62,6 +62,7 @@ struct ksmbd_conn *ksmbd_conn_alloc(void + atomic_set(&conn->req_running, 0); + atomic_set(&conn->r_count, 0); + conn->total_credits = 1; ++ conn->outstanding_credits = 1; + + init_waitqueue_head(&conn->req_running_q); + INIT_LIST_HEAD(&conn->conns_list); +--- a/fs/ksmbd/connection.h ++++ b/fs/ksmbd/connection.h +@@ -61,7 +61,8 @@ struct ksmbd_conn { + atomic_t req_running; + /* References which are made for this Server object*/ + atomic_t r_count; +- unsigned short total_credits; ++ unsigned int total_credits; ++ unsigned int outstanding_credits; + spinlock_t credits_lock; + wait_queue_head_t req_running_q; + /* Lock to protect requests list*/ +--- a/fs/ksmbd/smb2misc.c ++++ b/fs/ksmbd/smb2misc.c +@@ -337,7 +337,16 @@ static int smb2_validate_credit_charge(s + credit_charge, conn->total_credits); + ret = 1; + } ++ ++ if ((u64)conn->outstanding_credits + credit_charge > conn->vals->max_credits) { ++ ksmbd_debug(SMB, "Limits exceeding the maximum allowable outstanding requests, given : %u, pending : %u\n", ++ credit_charge, conn->outstanding_credits); ++ ret = 1; ++ } else ++ conn->outstanding_credits += credit_charge; ++ + spin_unlock(&conn->credits_lock); ++ + return ret; + } + +--- a/fs/ksmbd/smb2pdu.c ++++ b/fs/ksmbd/smb2pdu.c +@@ -322,6 +322,7 @@ int smb2_set_rsp_credits(struct ksmbd_wo + } + + conn->total_credits -= credit_charge; ++ conn->outstanding_credits -= credit_charge; + credits_requested = max_t(unsigned short, + le16_to_cpu(req_hdr->CreditRequest), 1); + diff --git a/queue-5.16/ksmbd-move-credit-charge-deduction-under-processing-request.patch b/queue-5.16/ksmbd-move-credit-charge-deduction-under-processing-request.patch new file mode 100644 index 00000000000..7f7303795df --- /dev/null +++ b/queue-5.16/ksmbd-move-credit-charge-deduction-under-processing-request.patch @@ -0,0 +1,87 @@ +From 914d7e5709ac59ded70bea7956d408fe2acd7c3c Mon Sep 17 00:00:00 2001 +From: Namjae Jeon +Date: Wed, 29 Dec 2021 23:10:03 +0900 +Subject: ksmbd: move credit charge deduction under processing request + +From: Namjae Jeon + +commit 914d7e5709ac59ded70bea7956d408fe2acd7c3c upstream. + +Moves the credit charge deduction from total_credits under the processing +a request. When repeating smb2 lock request and other command request, +there will be a problem that ->total_credits does not decrease. + +Signed-off-by: Namjae Jeon +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman +--- + fs/ksmbd/smb2misc.c | 7 ++----- + fs/ksmbd/smb2pdu.c | 16 ++++++++++------ + 2 files changed, 12 insertions(+), 11 deletions(-) + +--- a/fs/ksmbd/smb2misc.c ++++ b/fs/ksmbd/smb2misc.c +@@ -289,7 +289,7 @@ static int smb2_validate_credit_charge(s + unsigned int req_len = 0, expect_resp_len = 0, calc_credit_num, max_len; + unsigned short credit_charge = le16_to_cpu(hdr->CreditCharge); + void *__hdr = hdr; +- int ret; ++ int ret = 0; + + switch (hdr->Command) { + case SMB2_QUERY_INFO: +@@ -332,10 +332,7 @@ static int smb2_validate_credit_charge(s + } + + spin_lock(&conn->credits_lock); +- if (credit_charge <= conn->total_credits) { +- conn->total_credits -= credit_charge; +- ret = 0; +- } else { ++ if (credit_charge > conn->total_credits) { + ksmbd_debug(SMB, "Insufficient credits granted, given: %u, granted: %u\n", + credit_charge, conn->total_credits); + ret = 1; +--- a/fs/ksmbd/smb2pdu.c ++++ b/fs/ksmbd/smb2pdu.c +@@ -299,9 +299,8 @@ int smb2_set_rsp_credits(struct ksmbd_wo + struct smb2_hdr *req_hdr = ksmbd_req_buf_next(work); + struct smb2_hdr *hdr = ksmbd_resp_buf_next(work); + struct ksmbd_conn *conn = work->conn; +- unsigned short credits_requested; ++ unsigned short credits_requested, aux_max; + unsigned short credit_charge, credits_granted = 0; +- unsigned short aux_max, aux_credits; + + if (work->send_no_response) + return 0; +@@ -316,6 +315,13 @@ int smb2_set_rsp_credits(struct ksmbd_wo + + credit_charge = max_t(unsigned short, + le16_to_cpu(req_hdr->CreditCharge), 1); ++ if (credit_charge > conn->total_credits) { ++ ksmbd_debug(SMB, "Insufficient credits granted, given: %u, granted: %u\n", ++ credit_charge, conn->total_credits); ++ return -EINVAL; ++ } ++ ++ conn->total_credits -= credit_charge; + credits_requested = max_t(unsigned short, + le16_to_cpu(req_hdr->CreditRequest), 1); + +@@ -325,13 +331,11 @@ int smb2_set_rsp_credits(struct ksmbd_wo + * TODO: Need to adjuct CreditRequest value according to + * current cpu load + */ +- aux_credits = credits_requested - 1; + if (hdr->Command == SMB2_NEGOTIATE) +- aux_max = 0; ++ aux_max = 1; + else + aux_max = conn->vals->max_credits - credit_charge; +- aux_credits = min_t(unsigned short, aux_credits, aux_max); +- credits_granted = credit_charge + aux_credits; ++ credits_granted = min_t(unsigned short, credits_requested, aux_max); + + if (conn->vals->max_credits - conn->total_credits < credits_granted) + credits_granted = conn->vals->max_credits - diff --git a/queue-5.16/ksmbd-uninitialized-variable-in-create_socket.patch b/queue-5.16/ksmbd-uninitialized-variable-in-create_socket.patch new file mode 100644 index 00000000000..089e5f62293 --- /dev/null +++ b/queue-5.16/ksmbd-uninitialized-variable-in-create_socket.patch @@ -0,0 +1,40 @@ +From b207602fb04537cb21ac38fabd7577eca2fa05ae Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Sat, 15 Jan 2022 14:49:00 +0300 +Subject: ksmbd: uninitialized variable in create_socket() + +From: Dan Carpenter + +commit b207602fb04537cb21ac38fabd7577eca2fa05ae upstream. + +The "ksmbd_socket" variable is not initialized on this error path. + +Cc: stable@vger.kernel.org +Fixes: 0626e6641f6b ("cifsd: add server handler for central processing and tranport layers") +Signed-off-by: Dan Carpenter +Acked-by: Namjae Jeon +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman +--- + fs/ksmbd/transport_tcp.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/fs/ksmbd/transport_tcp.c ++++ b/fs/ksmbd/transport_tcp.c +@@ -404,7 +404,7 @@ static int create_socket(struct interfac + &ksmbd_socket); + if (ret) { + pr_err("Can't create socket for ipv4: %d\n", ret); +- goto out_error; ++ goto out_clear; + } + + sin.sin_family = PF_INET; +@@ -462,6 +462,7 @@ static int create_socket(struct interfac + + out_error: + tcp_destroy_socket(ksmbd_socket); ++out_clear: + iface->ksmbd_socket = NULL; + return ret; + } diff --git a/queue-5.16/lkdtm-fix-content-of-section-containing-lkdtm_rodata_do_nothing.patch b/queue-5.16/lkdtm-fix-content-of-section-containing-lkdtm_rodata_do_nothing.patch new file mode 100644 index 00000000000..ce13f51f328 --- /dev/null +++ b/queue-5.16/lkdtm-fix-content-of-section-containing-lkdtm_rodata_do_nothing.patch @@ -0,0 +1,55 @@ +From bc93a22a19eb2b68a16ecf04cdf4b2ed65aaf398 Mon Sep 17 00:00:00 2001 +From: Christophe Leroy +Date: Fri, 8 Oct 2021 18:58:40 +0200 +Subject: lkdtm: Fix content of section containing lkdtm_rodata_do_nothing() + +From: Christophe Leroy + +commit bc93a22a19eb2b68a16ecf04cdf4b2ed65aaf398 upstream. + +On a kernel without CONFIG_STRICT_KERNEL_RWX, running EXEC_RODATA +test leads to "Illegal instruction" failure. + +Looking at the content of rodata_objcopy.o, we see that the +function content zeroes only: + + Disassembly of section .rodata: + + 0000000000000000 <.lkdtm_rodata_do_nothing>: + 0: 00 00 00 00 .long 0x0 + +Add the contents flag in order to keep the content of the section +while renaming it. + + Disassembly of section .rodata: + + 0000000000000000 <.lkdtm_rodata_do_nothing>: + 0: 4e 80 00 20 blr + +Fixes: e9e08a07385e ("lkdtm: support llvm-objcopy") +Cc: stable@vger.kernel.org +Cc: Kees Cook +Cc: Arnd Bergmann +Cc: Greg Kroah-Hartman +Cc: Nick Desaulniers +Cc: Nathan Chancellor +Signed-off-by: Christophe Leroy +Reviewed-by: Nick Desaulniers +Signed-off-by: Kees Cook +Link: https://lore.kernel.org/r/8900731fbc05fb8b0de18af7133a8fc07c3c53a1.1633712176.git.christophe.leroy@csgroup.eu +Signed-off-by: Greg Kroah-Hartman +--- + drivers/misc/lkdtm/Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/misc/lkdtm/Makefile ++++ b/drivers/misc/lkdtm/Makefile +@@ -20,7 +20,7 @@ CFLAGS_REMOVE_rodata.o += $(CC_FLAGS_LT + + OBJCOPYFLAGS := + OBJCOPYFLAGS_rodata_objcopy.o := \ +- --rename-section .noinstr.text=.rodata,alloc,readonly,load ++ --rename-section .noinstr.text=.rodata,alloc,readonly,load,contents + targets += rodata.o rodata_objcopy.o + $(obj)/rodata_objcopy.o: $(obj)/rodata.o FORCE + $(call if_changed,objcopy) diff --git a/queue-5.16/media-cec-fix-a-deadlock-situation.patch b/queue-5.16/media-cec-fix-a-deadlock-situation.patch new file mode 100644 index 00000000000..017f83658a6 --- /dev/null +++ b/queue-5.16/media-cec-fix-a-deadlock-situation.patch @@ -0,0 +1,259 @@ +From a9e6107616bb8108aa4fc22584a05e69761a91f7 Mon Sep 17 00:00:00 2001 +From: Hans Verkuil +Date: Wed, 1 Dec 2021 13:41:26 +0100 +Subject: media: cec: fix a deadlock situation + +From: Hans Verkuil + +commit a9e6107616bb8108aa4fc22584a05e69761a91f7 upstream. + +The cec_devnode struct has a lock meant to serialize access +to the fields of this struct. This lock is taken during +device node (un)registration and when opening or releasing a +filehandle to the device node. When the last open filehandle +is closed the cec adapter might be disabled by calling the +adap_enable driver callback with the devnode.lock held. + +However, if during that callback a message or event arrives +then the driver will call one of the cec_queue_event() +variants in cec-adap.c, and those will take the same devnode.lock +to walk the open filehandle list. + +This obviously causes a deadlock. + +This is quite easy to reproduce with the cec-gpio driver since that +uses the cec-pin framework which generated lots of events and uses +a kernel thread for the processing, so when adap_enable is called +the thread is still running and can generate events. + +But I suspect that it might also happen with other drivers if an +interrupt arrives signaling e.g. a received message before adap_enable +had a chance to disable the interrupts. + +This patch adds a new mutex to serialize access to the fhs list. +When adap_enable() is called the devnode.lock mutex is held, but +not devnode.lock_fhs. The event functions in cec-adap.c will now +use devnode.lock_fhs instead of devnode.lock, ensuring that it is +safe to call those functions from the adap_enable callback. + +This specific issue only happens if the last open filehandle is closed +and the physical address is invalid. This is not something that +happens during normal operation, but it does happen when monitoring +CEC traffic (e.g. cec-ctl --monitor) with an unconfigured CEC adapter. + +Signed-off-by: Hans Verkuil +Cc: # for v5.13 and up +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/cec/core/cec-adap.c | 38 +++++++++++++++++++++----------------- + drivers/media/cec/core/cec-api.c | 6 ++++++ + drivers/media/cec/core/cec-core.c | 3 +++ + include/media/cec.h | 11 +++++++++-- + 4 files changed, 39 insertions(+), 19 deletions(-) + +--- a/drivers/media/cec/core/cec-adap.c ++++ b/drivers/media/cec/core/cec-adap.c +@@ -161,10 +161,10 @@ static void cec_queue_event(struct cec_a + u64 ts = ktime_get_ns(); + struct cec_fh *fh; + +- mutex_lock(&adap->devnode.lock); ++ mutex_lock(&adap->devnode.lock_fhs); + list_for_each_entry(fh, &adap->devnode.fhs, list) + cec_queue_event_fh(fh, ev, ts); +- mutex_unlock(&adap->devnode.lock); ++ mutex_unlock(&adap->devnode.lock_fhs); + } + + /* Notify userspace that the CEC pin changed state at the given time. */ +@@ -178,11 +178,12 @@ void cec_queue_pin_cec_event(struct cec_ + }; + struct cec_fh *fh; + +- mutex_lock(&adap->devnode.lock); +- list_for_each_entry(fh, &adap->devnode.fhs, list) ++ mutex_lock(&adap->devnode.lock_fhs); ++ list_for_each_entry(fh, &adap->devnode.fhs, list) { + if (fh->mode_follower == CEC_MODE_MONITOR_PIN) + cec_queue_event_fh(fh, &ev, ktime_to_ns(ts)); +- mutex_unlock(&adap->devnode.lock); ++ } ++ mutex_unlock(&adap->devnode.lock_fhs); + } + EXPORT_SYMBOL_GPL(cec_queue_pin_cec_event); + +@@ -195,10 +196,10 @@ void cec_queue_pin_hpd_event(struct cec_ + }; + struct cec_fh *fh; + +- mutex_lock(&adap->devnode.lock); ++ mutex_lock(&adap->devnode.lock_fhs); + list_for_each_entry(fh, &adap->devnode.fhs, list) + cec_queue_event_fh(fh, &ev, ktime_to_ns(ts)); +- mutex_unlock(&adap->devnode.lock); ++ mutex_unlock(&adap->devnode.lock_fhs); + } + EXPORT_SYMBOL_GPL(cec_queue_pin_hpd_event); + +@@ -211,10 +212,10 @@ void cec_queue_pin_5v_event(struct cec_a + }; + struct cec_fh *fh; + +- mutex_lock(&adap->devnode.lock); ++ mutex_lock(&adap->devnode.lock_fhs); + list_for_each_entry(fh, &adap->devnode.fhs, list) + cec_queue_event_fh(fh, &ev, ktime_to_ns(ts)); +- mutex_unlock(&adap->devnode.lock); ++ mutex_unlock(&adap->devnode.lock_fhs); + } + EXPORT_SYMBOL_GPL(cec_queue_pin_5v_event); + +@@ -286,12 +287,12 @@ static void cec_queue_msg_monitor(struct + u32 monitor_mode = valid_la ? CEC_MODE_MONITOR : + CEC_MODE_MONITOR_ALL; + +- mutex_lock(&adap->devnode.lock); ++ mutex_lock(&adap->devnode.lock_fhs); + list_for_each_entry(fh, &adap->devnode.fhs, list) { + if (fh->mode_follower >= monitor_mode) + cec_queue_msg_fh(fh, msg); + } +- mutex_unlock(&adap->devnode.lock); ++ mutex_unlock(&adap->devnode.lock_fhs); + } + + /* +@@ -302,12 +303,12 @@ static void cec_queue_msg_followers(stru + { + struct cec_fh *fh; + +- mutex_lock(&adap->devnode.lock); ++ mutex_lock(&adap->devnode.lock_fhs); + list_for_each_entry(fh, &adap->devnode.fhs, list) { + if (fh->mode_follower == CEC_MODE_FOLLOWER) + cec_queue_msg_fh(fh, msg); + } +- mutex_unlock(&adap->devnode.lock); ++ mutex_unlock(&adap->devnode.lock_fhs); + } + + /* Notify userspace of an adapter state change. */ +@@ -1573,6 +1574,7 @@ void __cec_s_phys_addr(struct cec_adapte + /* Disabling monitor all mode should always succeed */ + if (adap->monitor_all_cnt) + WARN_ON(call_op(adap, adap_monitor_all_enable, false)); ++ /* serialize adap_enable */ + mutex_lock(&adap->devnode.lock); + if (adap->needs_hpd || list_empty(&adap->devnode.fhs)) { + WARN_ON(adap->ops->adap_enable(adap, false)); +@@ -1584,14 +1586,16 @@ void __cec_s_phys_addr(struct cec_adapte + return; + } + ++ /* serialize adap_enable */ + mutex_lock(&adap->devnode.lock); + adap->last_initiator = 0xff; + adap->transmit_in_progress = false; + +- if ((adap->needs_hpd || list_empty(&adap->devnode.fhs)) && +- adap->ops->adap_enable(adap, true)) { +- mutex_unlock(&adap->devnode.lock); +- return; ++ if (adap->needs_hpd || list_empty(&adap->devnode.fhs)) { ++ if (adap->ops->adap_enable(adap, true)) { ++ mutex_unlock(&adap->devnode.lock); ++ return; ++ } + } + + if (adap->monitor_all_cnt && +--- a/drivers/media/cec/core/cec-api.c ++++ b/drivers/media/cec/core/cec-api.c +@@ -586,6 +586,7 @@ static int cec_open(struct inode *inode, + return err; + } + ++ /* serialize adap_enable */ + mutex_lock(&devnode->lock); + if (list_empty(&devnode->fhs) && + !adap->needs_hpd && +@@ -624,7 +625,9 @@ static int cec_open(struct inode *inode, + } + #endif + ++ mutex_lock(&devnode->lock_fhs); + list_add(&fh->list, &devnode->fhs); ++ mutex_unlock(&devnode->lock_fhs); + mutex_unlock(&devnode->lock); + + return 0; +@@ -653,8 +656,11 @@ static int cec_release(struct inode *ino + cec_monitor_all_cnt_dec(adap); + mutex_unlock(&adap->lock); + ++ /* serialize adap_enable */ + mutex_lock(&devnode->lock); ++ mutex_lock(&devnode->lock_fhs); + list_del(&fh->list); ++ mutex_unlock(&devnode->lock_fhs); + if (cec_is_registered(adap) && list_empty(&devnode->fhs) && + !adap->needs_hpd && adap->phys_addr == CEC_PHYS_ADDR_INVALID) { + WARN_ON(adap->ops->adap_enable(adap, false)); +--- a/drivers/media/cec/core/cec-core.c ++++ b/drivers/media/cec/core/cec-core.c +@@ -169,8 +169,10 @@ static void cec_devnode_unregister(struc + devnode->registered = false; + devnode->unregistered = true; + ++ mutex_lock(&devnode->lock_fhs); + list_for_each_entry(fh, &devnode->fhs, list) + wake_up_interruptible(&fh->wait); ++ mutex_unlock(&devnode->lock_fhs); + + mutex_unlock(&devnode->lock); + +@@ -272,6 +274,7 @@ struct cec_adapter *cec_allocate_adapter + + /* adap->devnode initialization */ + INIT_LIST_HEAD(&adap->devnode.fhs); ++ mutex_init(&adap->devnode.lock_fhs); + mutex_init(&adap->devnode.lock); + + adap->kthread = kthread_run(cec_thread_func, adap, "cec-%s", name); +--- a/include/media/cec.h ++++ b/include/media/cec.h +@@ -26,13 +26,17 @@ + * @dev: cec device + * @cdev: cec character device + * @minor: device node minor number ++ * @lock: lock to serialize open/release and registration + * @registered: the device was correctly registered + * @unregistered: the device was unregistered ++ * @lock_fhs: lock to control access to @fhs + * @fhs: the list of open filehandles (cec_fh) +- * @lock: lock to control access to this structure + * + * This structure represents a cec-related device node. + * ++ * To add or remove filehandles from @fhs the @lock must be taken first, ++ * followed by @lock_fhs. It is safe to access @fhs if either lock is held. ++ * + * The @parent is a physical device. It must be set by core or device drivers + * before registering the node. + */ +@@ -43,10 +47,13 @@ struct cec_devnode { + + /* device info */ + int minor; ++ /* serialize open/release and registration */ ++ struct mutex lock; + bool registered; + bool unregistered; ++ /* protect access to fhs */ ++ struct mutex lock_fhs; + struct list_head fhs; +- struct mutex lock; + }; + + struct cec_adapter; diff --git a/queue-5.16/media-cec-pin-fix-interrupt-en-disable-handling.patch b/queue-5.16/media-cec-pin-fix-interrupt-en-disable-handling.patch new file mode 100644 index 00000000000..54b75fe5fd9 --- /dev/null +++ b/queue-5.16/media-cec-pin-fix-interrupt-en-disable-handling.patch @@ -0,0 +1,119 @@ +From 713bdfa10b5957053811470d298def9537d9ff13 Mon Sep 17 00:00:00 2001 +From: Hans Verkuil +Date: Wed, 1 Dec 2021 13:41:25 +0100 +Subject: media: cec-pin: fix interrupt en/disable handling + +From: Hans Verkuil + +commit 713bdfa10b5957053811470d298def9537d9ff13 upstream. + +The en/disable_irq() functions keep track of the 'depth': i.e. if +interrupts are disabled twice, then it needs to enable_irq() calls to +enable them again. The cec-pin framework didn't take this into accound +and could disable irqs multiple times, and it expected that a single +enable_irq() would enable them again. + +Move all calls to en/disable_irq() to the kthread where it is easy +to keep track of the current irq state and ensure that multiple +en/disable_irq calls never happen. + +If interrupts where disabled twice, then they would never turn on +again, leaving the CEC adapter in a dead state. + +Signed-off-by: Hans Verkuil +Fixes: 865463fc03ed (media: cec-pin: add error injection support) +Cc: +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/cec/core/cec-pin.c | 31 ++++++++++++++++++------------- + 1 file changed, 18 insertions(+), 13 deletions(-) + +--- a/drivers/media/cec/core/cec-pin.c ++++ b/drivers/media/cec/core/cec-pin.c +@@ -1033,6 +1033,7 @@ static int cec_pin_thread_func(void *_ad + { + struct cec_adapter *adap = _adap; + struct cec_pin *pin = adap->pin; ++ bool irq_enabled = false; + + for (;;) { + wait_event_interruptible(pin->kthread_waitq, +@@ -1060,6 +1061,7 @@ static int cec_pin_thread_func(void *_ad + ns_to_ktime(pin->work_rx_msg.rx_ts)); + msg->len = 0; + } ++ + if (pin->work_tx_status) { + unsigned int tx_status = pin->work_tx_status; + +@@ -1083,27 +1085,39 @@ static int cec_pin_thread_func(void *_ad + switch (atomic_xchg(&pin->work_irq_change, + CEC_PIN_IRQ_UNCHANGED)) { + case CEC_PIN_IRQ_DISABLE: +- pin->ops->disable_irq(adap); ++ if (irq_enabled) { ++ pin->ops->disable_irq(adap); ++ irq_enabled = false; ++ } + cec_pin_high(pin); + cec_pin_to_idle(pin); + hrtimer_start(&pin->timer, ns_to_ktime(0), + HRTIMER_MODE_REL); + break; + case CEC_PIN_IRQ_ENABLE: ++ if (irq_enabled) ++ break; + pin->enable_irq_failed = !pin->ops->enable_irq(adap); + if (pin->enable_irq_failed) { + cec_pin_to_idle(pin); + hrtimer_start(&pin->timer, ns_to_ktime(0), + HRTIMER_MODE_REL); ++ } else { ++ irq_enabled = true; + } + break; + default: + break; + } +- + if (kthread_should_stop()) + break; + } ++ if (pin->ops->disable_irq && irq_enabled) ++ pin->ops->disable_irq(adap); ++ hrtimer_cancel(&pin->timer); ++ cec_pin_read(pin); ++ cec_pin_to_idle(pin); ++ pin->state = CEC_ST_OFF; + return 0; + } + +@@ -1130,13 +1144,7 @@ static int cec_pin_adap_enable(struct ce + hrtimer_start(&pin->timer, ns_to_ktime(0), + HRTIMER_MODE_REL); + } else { +- if (pin->ops->disable_irq) +- pin->ops->disable_irq(adap); +- hrtimer_cancel(&pin->timer); + kthread_stop(pin->kthread); +- cec_pin_read(pin); +- cec_pin_to_idle(pin); +- pin->state = CEC_ST_OFF; + } + return 0; + } +@@ -1157,11 +1165,8 @@ void cec_pin_start_timer(struct cec_pin + if (pin->state != CEC_ST_RX_IRQ) + return; + +- atomic_set(&pin->work_irq_change, CEC_PIN_IRQ_UNCHANGED); +- pin->ops->disable_irq(pin->adap); +- cec_pin_high(pin); +- cec_pin_to_idle(pin); +- hrtimer_start(&pin->timer, ns_to_ktime(0), HRTIMER_MODE_REL); ++ atomic_set(&pin->work_irq_change, CEC_PIN_IRQ_DISABLE); ++ wake_up_interruptible(&pin->kthread_waitq); + } + + static int cec_pin_adap_transmit(struct cec_adapter *adap, u8 attempts, diff --git a/queue-5.16/media-cpia2-fix-control-message-timeouts.patch b/queue-5.16/media-cpia2-fix-control-message-timeouts.patch new file mode 100644 index 00000000000..2c7f1de1ff7 --- /dev/null +++ b/queue-5.16/media-cpia2-fix-control-message-timeouts.patch @@ -0,0 +1,42 @@ +From 10729be03327f53258cb196362015ad5c6eabe02 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Mon, 25 Oct 2021 13:16:37 +0100 +Subject: media: cpia2: fix control-message timeouts + +From: Johan Hovold + +commit 10729be03327f53258cb196362015ad5c6eabe02 upstream. + +USB control-message timeouts are specified in milliseconds and should +specifically not vary with CONFIG_HZ. + +Fixes: ab33d5071de7 ("V4L/DVB (3376): Add cpia2 camera support") +Cc: stable@vger.kernel.org # 2.6.17 +Signed-off-by: Johan Hovold +Signed-off-by: Hans Verkuil +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/usb/cpia2/cpia2_usb.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/media/usb/cpia2/cpia2_usb.c ++++ b/drivers/media/usb/cpia2/cpia2_usb.c +@@ -550,7 +550,7 @@ static int write_packet(struct usb_devic + 0, /* index */ + buf, /* buffer */ + size, +- HZ); ++ 1000); + + kfree(buf); + return ret; +@@ -582,7 +582,7 @@ static int read_packet(struct usb_device + 0, /* index */ + buf, /* buffer */ + size, +- HZ); ++ 1000); + + if (ret >= 0) + memcpy(registers, buf, size); diff --git a/queue-5.16/media-dib0700-fix-undefined-behavior-in-tuner-shutdown.patch b/queue-5.16/media-dib0700-fix-undefined-behavior-in-tuner-shutdown.patch new file mode 100644 index 00000000000..2757c887952 --- /dev/null +++ b/queue-5.16/media-dib0700-fix-undefined-behavior-in-tuner-shutdown.patch @@ -0,0 +1,51 @@ +From f7b77ebe6d2f49c7747b2d619586d1aa33f9ea91 Mon Sep 17 00:00:00 2001 +From: Michael Kuron +Date: Sun, 26 Sep 2021 21:51:26 +0100 +Subject: media: dib0700: fix undefined behavior in tuner shutdown + +From: Michael Kuron + +commit f7b77ebe6d2f49c7747b2d619586d1aa33f9ea91 upstream. + +This fixes a problem where closing the tuner would leave it in a state +where it would not tune to any channel when reopened. This problem was +discovered as part of https://github.com/hselasky/webcamd/issues/16. + +Since adap->id is 0 or 1, this bit-shift overflows, which is undefined +behavior. The driver still worked in practice as the overflow would in +most environments result in 0, which rendered the line a no-op. When +running the driver as part of webcamd however, the overflow could lead +to 0xff due to optimizations by the compiler, which would, in the end, +improperly shut down the tuner. + +The bug is a regression introduced in the commit referenced below. The +present patch causes identical behavior to before that commit for +adap->id equal to 0 or 1. The driver does not contain support for +dib0700 devices with more adapters, assuming such even exist. + +Tests have been performed with the Xbox One Digital TV Tuner on amd64. +Not all dib0700 devices are expected to be affected by the regression; +this code path is only taken by those with incorrect endpoint numbers. + +Link: https://lore.kernel.org/linux-media/1d2fc36d94ced6f67c7cc21dcc469d5e5bdd8201.1632689033.git.mchehab+huawei@kernel.org + +Cc: stable@vger.kernel.org +Fixes: 7757ddda6f4f ("[media] DiB0700: add function to change I2C-speed") +Signed-off-by: Michael Kuron +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/usb/dvb-usb/dib0700_core.c | 2 -- + 1 file changed, 2 deletions(-) + +--- a/drivers/media/usb/dvb-usb/dib0700_core.c ++++ b/drivers/media/usb/dvb-usb/dib0700_core.c +@@ -618,8 +618,6 @@ int dib0700_streaming_ctrl(struct dvb_us + deb_info("the endpoint number (%i) is not correct, use the adapter id instead", adap->fe_adap[0].stream.props.endpoint); + if (onoff) + st->channel_state |= 1 << (adap->id); +- else +- st->channel_state |= 1 << ~(adap->id); + } else { + if (onoff) + st->channel_state |= 1 << (adap->fe_adap[0].stream.props.endpoint-2); diff --git a/queue-5.16/media-em28xx-fix-control-message-timeouts.patch b/queue-5.16/media-em28xx-fix-control-message-timeouts.patch new file mode 100644 index 00000000000..4ce3744ba3d --- /dev/null +++ b/queue-5.16/media-em28xx-fix-control-message-timeouts.patch @@ -0,0 +1,42 @@ +From d9b7e8df3aa9b8c10708aab60e72e79ac08237e4 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Mon, 25 Oct 2021 13:16:38 +0100 +Subject: media: em28xx: fix control-message timeouts + +From: Johan Hovold + +commit d9b7e8df3aa9b8c10708aab60e72e79ac08237e4 upstream. + +USB control-message timeouts are specified in milliseconds and should +specifically not vary with CONFIG_HZ. + +Fixes: a6c2ba283565 ("[PATCH] v4l: 716: support for em28xx board family") +Cc: stable@vger.kernel.org # 2.6.16 +Signed-off-by: Johan Hovold +Signed-off-by: Hans Verkuil +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/usb/em28xx/em28xx-core.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/media/usb/em28xx/em28xx-core.c ++++ b/drivers/media/usb/em28xx/em28xx-core.c +@@ -89,7 +89,7 @@ int em28xx_read_reg_req_len(struct em28x + mutex_lock(&dev->ctrl_urb_lock); + ret = usb_control_msg(udev, pipe, req, + USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, +- 0x0000, reg, dev->urb_buf, len, HZ); ++ 0x0000, reg, dev->urb_buf, len, 1000); + if (ret < 0) { + em28xx_regdbg("(pipe 0x%08x): IN: %02x %02x %02x %02x %02x %02x %02x %02x failed with error %i\n", + pipe, +@@ -158,7 +158,7 @@ int em28xx_write_regs_req(struct em28xx + memcpy(dev->urb_buf, buf, len); + ret = usb_control_msg(udev, pipe, req, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, +- 0x0000, reg, dev->urb_buf, len, HZ); ++ 0x0000, reg, dev->urb_buf, len, 1000); + mutex_unlock(&dev->ctrl_urb_lock); + + if (ret < 0) { diff --git a/queue-5.16/media-flexcop-usb-fix-control-message-timeouts.patch b/queue-5.16/media-flexcop-usb-fix-control-message-timeouts.patch new file mode 100644 index 00000000000..e984278899b --- /dev/null +++ b/queue-5.16/media-flexcop-usb-fix-control-message-timeouts.patch @@ -0,0 +1,95 @@ +From cd1798a387825cc4a51282f5a611ad05bb1ad75f Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Mon, 25 Oct 2021 13:16:36 +0100 +Subject: media: flexcop-usb: fix control-message timeouts + +From: Johan Hovold + +commit cd1798a387825cc4a51282f5a611ad05bb1ad75f upstream. + +USB control-message timeouts are specified in milliseconds and should +specifically not vary with CONFIG_HZ. + +Note that the driver was multiplying some of the timeout values with HZ +twice resulting in 3000-second timeouts with HZ=1000. + +Also note that two of the timeout defines are currently unused. + +Fixes: 2154be651b90 ("[media] redrat3: new rc-core IR transceiver device driver") +Cc: stable@vger.kernel.org # 3.0 +Signed-off-by: Johan Hovold +Signed-off-by: Hans Verkuil +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/usb/b2c2/flexcop-usb.c | 10 +++++----- + drivers/media/usb/b2c2/flexcop-usb.h | 12 ++++++------ + 2 files changed, 11 insertions(+), 11 deletions(-) + +--- a/drivers/media/usb/b2c2/flexcop-usb.c ++++ b/drivers/media/usb/b2c2/flexcop-usb.c +@@ -87,7 +87,7 @@ static int flexcop_usb_readwrite_dw(stru + 0, + fc_usb->data, + sizeof(u32), +- B2C2_WAIT_FOR_OPERATION_RDW * HZ); ++ B2C2_WAIT_FOR_OPERATION_RDW); + + if (ret != sizeof(u32)) { + err("error while %s dword from %d (%d).", read ? "reading" : +@@ -155,7 +155,7 @@ static int flexcop_usb_v8_memory_req(str + wIndex, + fc_usb->data, + buflen, +- nWaitTime * HZ); ++ nWaitTime); + if (ret != buflen) + ret = -EIO; + +@@ -248,13 +248,13 @@ static int flexcop_usb_i2c_req(struct fl + /* DKT 020208 - add this to support special case of DiSEqC */ + case USB_FUNC_I2C_CHECKWRITE: + pipe = B2C2_USB_CTRL_PIPE_OUT; +- nWaitTime = 2; ++ nWaitTime = 2000; + request_type |= USB_DIR_OUT; + break; + case USB_FUNC_I2C_READ: + case USB_FUNC_I2C_REPEATREAD: + pipe = B2C2_USB_CTRL_PIPE_IN; +- nWaitTime = 2; ++ nWaitTime = 2000; + request_type |= USB_DIR_IN; + break; + default: +@@ -281,7 +281,7 @@ static int flexcop_usb_i2c_req(struct fl + wIndex, + fc_usb->data, + buflen, +- nWaitTime * HZ); ++ nWaitTime); + + if (ret != buflen) + ret = -EIO; +--- a/drivers/media/usb/b2c2/flexcop-usb.h ++++ b/drivers/media/usb/b2c2/flexcop-usb.h +@@ -91,13 +91,13 @@ typedef enum { + UTILITY_SRAM_TESTVERIFY = 0x16, + } flexcop_usb_utility_function_t; + +-#define B2C2_WAIT_FOR_OPERATION_RW (1*HZ) +-#define B2C2_WAIT_FOR_OPERATION_RDW (3*HZ) +-#define B2C2_WAIT_FOR_OPERATION_WDW (1*HZ) ++#define B2C2_WAIT_FOR_OPERATION_RW 1000 ++#define B2C2_WAIT_FOR_OPERATION_RDW 3000 ++#define B2C2_WAIT_FOR_OPERATION_WDW 1000 + +-#define B2C2_WAIT_FOR_OPERATION_V8READ (3*HZ) +-#define B2C2_WAIT_FOR_OPERATION_V8WRITE (3*HZ) +-#define B2C2_WAIT_FOR_OPERATION_V8FLASH (3*HZ) ++#define B2C2_WAIT_FOR_OPERATION_V8READ 3000 ++#define B2C2_WAIT_FOR_OPERATION_V8WRITE 3000 ++#define B2C2_WAIT_FOR_OPERATION_V8FLASH 3000 + + typedef enum { + V8_MEMORY_PAGE_DVB_CI = 0x20, diff --git a/queue-5.16/media-mceusb-fix-control-message-timeouts.patch b/queue-5.16/media-mceusb-fix-control-message-timeouts.patch new file mode 100644 index 00000000000..5053f2f0497 --- /dev/null +++ b/queue-5.16/media-mceusb-fix-control-message-timeouts.patch @@ -0,0 +1,57 @@ +From 16394e998cbb050730536bdf7e89f5a70efbd974 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Mon, 25 Oct 2021 13:16:34 +0100 +Subject: media: mceusb: fix control-message timeouts + +From: Johan Hovold + +commit 16394e998cbb050730536bdf7e89f5a70efbd974 upstream. + +USB control-message timeouts are specified in milliseconds and should +specifically not vary with CONFIG_HZ. + +Fixes: 66e89522aff7 ("V4L/DVB: IR: add mceusb IR receiver driver") +Cc: stable@vger.kernel.org # 2.6.36 +Signed-off-by: Johan Hovold +Signed-off-by: Hans Verkuil +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/rc/mceusb.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/media/rc/mceusb.c ++++ b/drivers/media/rc/mceusb.c +@@ -1430,7 +1430,7 @@ static void mceusb_gen1_init(struct mceu + */ + ret = usb_control_msg(ir->usbdev, usb_rcvctrlpipe(ir->usbdev, 0), + USB_REQ_SET_ADDRESS, USB_TYPE_VENDOR, 0, 0, +- data, USB_CTRL_MSG_SZ, HZ * 3); ++ data, USB_CTRL_MSG_SZ, 3000); + dev_dbg(dev, "set address - ret = %d", ret); + dev_dbg(dev, "set address - data[0] = %d, data[1] = %d", + data[0], data[1]); +@@ -1438,20 +1438,20 @@ static void mceusb_gen1_init(struct mceu + /* set feature: bit rate 38400 bps */ + ret = usb_control_msg(ir->usbdev, usb_sndctrlpipe(ir->usbdev, 0), + USB_REQ_SET_FEATURE, USB_TYPE_VENDOR, +- 0xc04e, 0x0000, NULL, 0, HZ * 3); ++ 0xc04e, 0x0000, NULL, 0, 3000); + + dev_dbg(dev, "set feature - ret = %d", ret); + + /* bRequest 4: set char length to 8 bits */ + ret = usb_control_msg(ir->usbdev, usb_sndctrlpipe(ir->usbdev, 0), + 4, USB_TYPE_VENDOR, +- 0x0808, 0x0000, NULL, 0, HZ * 3); ++ 0x0808, 0x0000, NULL, 0, 3000); + dev_dbg(dev, "set char length - retB = %d", ret); + + /* bRequest 2: set handshaking to use DTR/DSR */ + ret = usb_control_msg(ir->usbdev, usb_sndctrlpipe(ir->usbdev, 0), + 2, USB_TYPE_VENDOR, +- 0x0000, 0x0100, NULL, 0, HZ * 3); ++ 0x0000, 0x0100, NULL, 0, 3000); + dev_dbg(dev, "set handshake - retC = %d", ret); + + /* device resume */ diff --git a/queue-5.16/media-ov8865-disable-only-enabled-regulators-on-error-path.patch b/queue-5.16/media-ov8865-disable-only-enabled-regulators-on-error-path.patch new file mode 100644 index 00000000000..82fa7dc05e3 --- /dev/null +++ b/queue-5.16/media-ov8865-disable-only-enabled-regulators-on-error-path.patch @@ -0,0 +1,77 @@ +From cbe0b3af73bf72fad197756f026084404e2bcdc7 Mon Sep 17 00:00:00 2001 +From: Sakari Ailus +Date: Wed, 15 Dec 2021 09:38:48 +0100 +Subject: media: ov8865: Disable only enabled regulators on error path + +From: Sakari Ailus + +commit cbe0b3af73bf72fad197756f026084404e2bcdc7 upstream. + +If powering on the sensor failed, the entire power-off sequence was run +independently of how far the power-on sequence proceeded before the error. +This lead to disabling regulators and/or clock that was not enabled. + +Fix this by disabling only clocks and regulators that were enabled +previously. + +Fixes: 11c0d8fdccc5 ("media: i2c: Add support for the OV8865 image sensor") +Cc: stable@vger.kernel.org +Signed-off-by: Sakari Ailus +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/i2c/ov8865.c | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +--- a/drivers/media/i2c/ov8865.c ++++ b/drivers/media/i2c/ov8865.c +@@ -2330,27 +2330,27 @@ static int ov8865_sensor_power(struct ov + if (ret) { + dev_err(sensor->dev, + "failed to enable DOVDD regulator\n"); +- goto disable; ++ return ret; + } + + ret = regulator_enable(sensor->avdd); + if (ret) { + dev_err(sensor->dev, + "failed to enable AVDD regulator\n"); +- goto disable; ++ goto disable_dovdd; + } + + ret = regulator_enable(sensor->dvdd); + if (ret) { + dev_err(sensor->dev, + "failed to enable DVDD regulator\n"); +- goto disable; ++ goto disable_avdd; + } + + ret = clk_prepare_enable(sensor->extclk); + if (ret) { + dev_err(sensor->dev, "failed to enable EXTCLK clock\n"); +- goto disable; ++ goto disable_dvdd; + } + + gpiod_set_value_cansleep(sensor->reset, 0); +@@ -2359,14 +2359,16 @@ static int ov8865_sensor_power(struct ov + /* Time to enter streaming mode according to power timings. */ + usleep_range(10000, 12000); + } else { +-disable: + gpiod_set_value_cansleep(sensor->powerdown, 1); + gpiod_set_value_cansleep(sensor->reset, 1); + + clk_disable_unprepare(sensor->extclk); + ++disable_dvdd: + regulator_disable(sensor->dvdd); ++disable_avdd: + regulator_disable(sensor->avdd); ++disable_dovdd: + regulator_disable(sensor->dovdd); + } + diff --git a/queue-5.16/media-pvrusb2-fix-control-message-timeouts.patch b/queue-5.16/media-pvrusb2-fix-control-message-timeouts.patch new file mode 100644 index 00000000000..5348712a556 --- /dev/null +++ b/queue-5.16/media-pvrusb2-fix-control-message-timeouts.patch @@ -0,0 +1,60 @@ +From b82bf9b9dc305d7d3d93eab106d70dbf2171b43e Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Mon, 25 Oct 2021 13:16:39 +0100 +Subject: media: pvrusb2: fix control-message timeouts + +From: Johan Hovold + +commit b82bf9b9dc305d7d3d93eab106d70dbf2171b43e upstream. + +USB control-message timeouts are specified in milliseconds and should +specifically not vary with CONFIG_HZ. + +Fixes: d855497edbfb ("V4L/DVB (4228a): pvrusb2 to kernel 2.6.18") +Cc: stable@vger.kernel.org # 2.6.18 +Signed-off-by: Johan Hovold +Signed-off-by: Hans Verkuil +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/usb/pvrusb2/pvrusb2-hdw.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c ++++ b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c +@@ -1467,7 +1467,7 @@ static int pvr2_upload_firmware1(struct + for (address = 0; address < fwsize; address += 0x800) { + memcpy(fw_ptr, fw_entry->data + address, 0x800); + ret += usb_control_msg(hdw->usb_dev, pipe, 0xa0, 0x40, address, +- 0, fw_ptr, 0x800, HZ); ++ 0, fw_ptr, 0x800, 1000); + } + + trace_firmware("Upload done, releasing device's CPU"); +@@ -1605,7 +1605,7 @@ int pvr2_upload_firmware2(struct pvr2_hd + ((u32 *)fw_ptr)[icnt] = swab32(((u32 *)fw_ptr)[icnt]); + + ret |= usb_bulk_msg(hdw->usb_dev, pipe, fw_ptr,bcnt, +- &actual_length, HZ); ++ &actual_length, 1000); + ret |= (actual_length != bcnt); + if (ret) break; + fw_done += bcnt; +@@ -3438,7 +3438,7 @@ void pvr2_hdw_cpufw_set_enabled(struct p + 0xa0,0xc0, + address,0, + hdw->fw_buffer+address, +- 0x800,HZ); ++ 0x800,1000); + if (ret < 0) break; + } + +@@ -3977,7 +3977,7 @@ void pvr2_hdw_cpureset_assert(struct pvr + /* Write the CPUCS register on the 8051. The lsb of the register + is the reset bit; a 1 asserts reset while a 0 clears it. */ + pipe = usb_sndctrlpipe(hdw->usb_dev, 0); +- ret = usb_control_msg(hdw->usb_dev,pipe,0xa0,0x40,0xe600,0,da,1,HZ); ++ ret = usb_control_msg(hdw->usb_dev,pipe,0xa0,0x40,0xe600,0,da,1,1000); + if (ret < 0) { + pvr2_trace(PVR2_TRACE_ERROR_LEGS, + "cpureset_assert(%d) error=%d",val,ret); diff --git a/queue-5.16/media-redrat3-fix-control-message-timeouts.patch b/queue-5.16/media-redrat3-fix-control-message-timeouts.patch new file mode 100644 index 00000000000..8c4ce6e06a9 --- /dev/null +++ b/queue-5.16/media-redrat3-fix-control-message-timeouts.patch @@ -0,0 +1,115 @@ +From 2adc965c8bfa224e11ecccf9c92fd458c4236428 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Mon, 25 Oct 2021 13:16:35 +0100 +Subject: media: redrat3: fix control-message timeouts + +From: Johan Hovold + +commit 2adc965c8bfa224e11ecccf9c92fd458c4236428 upstream. + +USB control-message timeouts are specified in milliseconds and should +specifically not vary with CONFIG_HZ. + +Fixes: 2154be651b90 ("[media] redrat3: new rc-core IR transceiver device driver") +Cc: stable@vger.kernel.org # 3.0 +Signed-off-by: Johan Hovold +Signed-off-by: Hans Verkuil +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/rc/redrat3.c | 22 +++++++++++----------- + 1 file changed, 11 insertions(+), 11 deletions(-) + +--- a/drivers/media/rc/redrat3.c ++++ b/drivers/media/rc/redrat3.c +@@ -404,7 +404,7 @@ static int redrat3_send_cmd(int cmd, str + udev = rr3->udev; + res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), cmd, + USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, +- 0x0000, 0x0000, data, sizeof(u8), HZ * 10); ++ 0x0000, 0x0000, data, sizeof(u8), 10000); + + if (res < 0) { + dev_err(rr3->dev, "%s: Error sending rr3 cmd res %d, data %d", +@@ -480,7 +480,7 @@ static u32 redrat3_get_timeout(struct re + pipe = usb_rcvctrlpipe(rr3->udev, 0); + ret = usb_control_msg(rr3->udev, pipe, RR3_GET_IR_PARAM, + USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, +- RR3_IR_IO_SIG_TIMEOUT, 0, tmp, len, HZ * 5); ++ RR3_IR_IO_SIG_TIMEOUT, 0, tmp, len, 5000); + if (ret != len) + dev_warn(rr3->dev, "Failed to read timeout from hardware\n"); + else { +@@ -510,7 +510,7 @@ static int redrat3_set_timeout(struct rc + ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), RR3_SET_IR_PARAM, + USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, + RR3_IR_IO_SIG_TIMEOUT, 0, timeout, sizeof(*timeout), +- HZ * 25); ++ 25000); + dev_dbg(dev, "set ir parm timeout %d ret 0x%02x\n", + be32_to_cpu(*timeout), ret); + +@@ -542,32 +542,32 @@ static void redrat3_reset(struct redrat3 + *val = 0x01; + rc = usb_control_msg(udev, rxpipe, RR3_RESET, + USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, +- RR3_CPUCS_REG_ADDR, 0, val, len, HZ * 25); ++ RR3_CPUCS_REG_ADDR, 0, val, len, 25000); + dev_dbg(dev, "reset returned 0x%02x\n", rc); + + *val = length_fuzz; + rc = usb_control_msg(udev, txpipe, RR3_SET_IR_PARAM, + USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, +- RR3_IR_IO_LENGTH_FUZZ, 0, val, len, HZ * 25); ++ RR3_IR_IO_LENGTH_FUZZ, 0, val, len, 25000); + dev_dbg(dev, "set ir parm len fuzz %d rc 0x%02x\n", *val, rc); + + *val = (65536 - (minimum_pause * 2000)) / 256; + rc = usb_control_msg(udev, txpipe, RR3_SET_IR_PARAM, + USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, +- RR3_IR_IO_MIN_PAUSE, 0, val, len, HZ * 25); ++ RR3_IR_IO_MIN_PAUSE, 0, val, len, 25000); + dev_dbg(dev, "set ir parm min pause %d rc 0x%02x\n", *val, rc); + + *val = periods_measure_carrier; + rc = usb_control_msg(udev, txpipe, RR3_SET_IR_PARAM, + USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, +- RR3_IR_IO_PERIODS_MF, 0, val, len, HZ * 25); ++ RR3_IR_IO_PERIODS_MF, 0, val, len, 25000); + dev_dbg(dev, "set ir parm periods measure carrier %d rc 0x%02x", *val, + rc); + + *val = RR3_DRIVER_MAXLENS; + rc = usb_control_msg(udev, txpipe, RR3_SET_IR_PARAM, + USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, +- RR3_IR_IO_MAX_LENGTHS, 0, val, len, HZ * 25); ++ RR3_IR_IO_MAX_LENGTHS, 0, val, len, 25000); + dev_dbg(dev, "set ir parm max lens %d rc 0x%02x\n", *val, rc); + + kfree(val); +@@ -585,7 +585,7 @@ static void redrat3_get_firmware_rev(str + rc = usb_control_msg(rr3->udev, usb_rcvctrlpipe(rr3->udev, 0), + RR3_FW_VERSION, + USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, +- 0, 0, buffer, RR3_FW_VERSION_LEN, HZ * 5); ++ 0, 0, buffer, RR3_FW_VERSION_LEN, 5000); + + if (rc >= 0) + dev_info(rr3->dev, "Firmware rev: %s", buffer); +@@ -825,14 +825,14 @@ static int redrat3_transmit_ir(struct rc + + pipe = usb_sndbulkpipe(rr3->udev, rr3->ep_out->bEndpointAddress); + ret = usb_bulk_msg(rr3->udev, pipe, irdata, +- sendbuf_len, &ret_len, 10 * HZ); ++ sendbuf_len, &ret_len, 10000); + dev_dbg(dev, "sent %d bytes, (ret %d)\n", ret_len, ret); + + /* now tell the hardware to transmit what we sent it */ + pipe = usb_rcvctrlpipe(rr3->udev, 0); + ret = usb_control_msg(rr3->udev, pipe, RR3_TX_SEND_SIGNAL, + USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, +- 0, 0, irdata, 2, HZ * 10); ++ 0, 0, irdata, 2, 10000); + + if (ret < 0) + dev_err(dev, "Error: control msg send failed, rc %d\n", ret); diff --git a/queue-5.16/media-s2255-fix-control-message-timeouts.patch b/queue-5.16/media-s2255-fix-control-message-timeouts.patch new file mode 100644 index 00000000000..1d929588515 --- /dev/null +++ b/queue-5.16/media-s2255-fix-control-message-timeouts.patch @@ -0,0 +1,45 @@ +From f71d272ad4e354097020a4e6b1dc6e4b59feb50f Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Mon, 25 Oct 2021 13:16:40 +0100 +Subject: media: s2255: fix control-message timeouts + +From: Johan Hovold + +commit f71d272ad4e354097020a4e6b1dc6e4b59feb50f upstream. + +USB control-message timeouts are specified in milliseconds and should +specifically not vary with CONFIG_HZ. + +Use the common control-message timeout define for the five-second +timeouts. + +Fixes: 38f993ad8b1f ("V4L/DVB (8125): This driver adds support for the Sensoray 2255 devices.") +Cc: stable@vger.kernel.org # 2.6.27 +Signed-off-by: Johan Hovold +Signed-off-by: Hans Verkuil +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/usb/s2255/s2255drv.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/media/usb/s2255/s2255drv.c ++++ b/drivers/media/usb/s2255/s2255drv.c +@@ -1882,7 +1882,7 @@ static long s2255_vendor_req(struct s225 + USB_TYPE_VENDOR | USB_RECIP_DEVICE | + USB_DIR_IN, + Value, Index, buf, +- TransferBufferLength, HZ * 5); ++ TransferBufferLength, USB_CTRL_SET_TIMEOUT); + + if (r >= 0) + memcpy(TransferBuffer, buf, TransferBufferLength); +@@ -1891,7 +1891,7 @@ static long s2255_vendor_req(struct s225 + r = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), + Request, USB_TYPE_VENDOR | USB_RECIP_DEVICE, + Value, Index, buf, +- TransferBufferLength, HZ * 5); ++ TransferBufferLength, USB_CTRL_SET_TIMEOUT); + } + kfree(buf); + return r; diff --git a/queue-5.16/media-stk1160-fix-control-message-timeouts.patch b/queue-5.16/media-stk1160-fix-control-message-timeouts.patch new file mode 100644 index 00000000000..18eeb6f44e4 --- /dev/null +++ b/queue-5.16/media-stk1160-fix-control-message-timeouts.patch @@ -0,0 +1,42 @@ +From 6aa6e70cdb5b863a57bad61310bf89b6617a5d2d Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Mon, 25 Oct 2021 13:16:41 +0100 +Subject: media: stk1160: fix control-message timeouts + +From: Johan Hovold + +commit 6aa6e70cdb5b863a57bad61310bf89b6617a5d2d upstream. + +USB control-message timeouts are specified in milliseconds and should +specifically not vary with CONFIG_HZ. + +Fixes: 9cb2173e6ea8 ("[media] media: Add stk1160 new driver (easycap replacement)") +Cc: stable@vger.kernel.org # 3.7 +Signed-off-by: Johan Hovold +Signed-off-by: Hans Verkuil +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/usb/stk1160/stk1160-core.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/media/usb/stk1160/stk1160-core.c ++++ b/drivers/media/usb/stk1160/stk1160-core.c +@@ -65,7 +65,7 @@ int stk1160_read_reg(struct stk1160 *dev + return -ENOMEM; + ret = usb_control_msg(dev->udev, pipe, 0x00, + USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, +- 0x00, reg, buf, sizeof(u8), HZ); ++ 0x00, reg, buf, sizeof(u8), 1000); + if (ret < 0) { + stk1160_err("read failed on reg 0x%x (%d)\n", + reg, ret); +@@ -85,7 +85,7 @@ int stk1160_write_reg(struct stk1160 *de + + ret = usb_control_msg(dev->udev, pipe, 0x01, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, +- value, reg, NULL, 0, HZ); ++ value, reg, NULL, 0, 1000); + if (ret < 0) { + stk1160_err("write failed on reg 0x%x (%d)\n", + reg, ret); diff --git a/queue-5.16/media-v4l2-ioctl.c-readbuffers-depends-on-v4l2_cap_readwrite.patch b/queue-5.16/media-v4l2-ioctl.c-readbuffers-depends-on-v4l2_cap_readwrite.patch new file mode 100644 index 00000000000..b1e5fa5aec6 --- /dev/null +++ b/queue-5.16/media-v4l2-ioctl.c-readbuffers-depends-on-v4l2_cap_readwrite.patch @@ -0,0 +1,46 @@ +From cd9d9377ed235b294a492a094e1666178a5e78fd Mon Sep 17 00:00:00 2001 +From: Hans Verkuil +Date: Wed, 3 Nov 2021 12:28:31 +0000 +Subject: media: v4l2-ioctl.c: readbuffers depends on V4L2_CAP_READWRITE + +From: Hans Verkuil + +commit cd9d9377ed235b294a492a094e1666178a5e78fd upstream. + +If V4L2_CAP_READWRITE is not set, then readbuffers must be set to 0, +otherwise v4l2-compliance will complain. + +A note on the Fixes tag below: this patch does not really fix that commit, +but it can be applied from that commit onwards. For older code there is no +guarantee that device_caps is set, so even though this patch would apply, +it will not work reliably. + +Signed-off-by: Hans Verkuil +Fixes: 049e684f2de9 (media: v4l2-dev: fix WARN_ON(!vdev->device_caps)) +Cc: +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/v4l2-core/v4l2-ioctl.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/media/v4l2-core/v4l2-ioctl.c ++++ b/drivers/media/v4l2-core/v4l2-ioctl.c +@@ -2090,6 +2090,7 @@ static int v4l_prepare_buf(const struct + static int v4l_g_parm(const struct v4l2_ioctl_ops *ops, + struct file *file, void *fh, void *arg) + { ++ struct video_device *vfd = video_devdata(file); + struct v4l2_streamparm *p = arg; + v4l2_std_id std; + int ret = check_fmt(file, p->type); +@@ -2101,7 +2102,8 @@ static int v4l_g_parm(const struct v4l2_ + if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && + p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) + return -EINVAL; +- p->parm.capture.readbuffers = 2; ++ if (vfd->device_caps & V4L2_CAP_READWRITE) ++ p->parm.capture.readbuffers = 2; + ret = ops->vidioc_g_std(file, fh, &std); + if (ret == 0) + v4l2_video_std_frame_period(std, &p->parm.capture.timeperframe); diff --git a/queue-5.16/mei-hbm-fix-client-dma-reply-status.patch b/queue-5.16/mei-hbm-fix-client-dma-reply-status.patch new file mode 100644 index 00000000000..5746ef23b78 --- /dev/null +++ b/queue-5.16/mei-hbm-fix-client-dma-reply-status.patch @@ -0,0 +1,67 @@ +From 6b0b80ac103b2a40c72a47c301745fd1f4ef4697 Mon Sep 17 00:00:00 2001 +From: Alexander Usyskin +Date: Tue, 28 Dec 2021 10:20:47 +0200 +Subject: mei: hbm: fix client dma reply status + +From: Alexander Usyskin + +commit 6b0b80ac103b2a40c72a47c301745fd1f4ef4697 upstream. + +Don't blindly copy status value received from the firmware +into internal client status field, +It may be positive and ERR_PTR(ret) will translate it +into an invalid address and the caller will crash. + +Put the error code into the client status on failure. + +Fixes: 369aea845951 ("mei: implement client dma setup.") +Cc: # v5.11+ +Reported-by: Emmanuel Grumbach +Tested-by: : Emmanuel Grumbach +Acked-by: Tomas Winkler +Signed-off-by: Alexander Usyskin +Signed-off-by: Tomas Winkler +Link: https://lore.kernel.org/r/20211228082047.378115-1-tomas.winkler@intel.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/misc/mei/hbm.c | 20 ++++++++++++++------ + 1 file changed, 14 insertions(+), 6 deletions(-) + +--- a/drivers/misc/mei/hbm.c ++++ b/drivers/misc/mei/hbm.c +@@ -672,10 +672,14 @@ static void mei_hbm_cl_dma_map_res(struc + if (!cl) + return; + +- dev_dbg(dev->dev, "cl dma map result = %d\n", res->status); +- cl->status = res->status; +- if (!cl->status) ++ if (res->status) { ++ dev_err(dev->dev, "cl dma map failed %d\n", res->status); ++ cl->status = -EFAULT; ++ } else { ++ dev_dbg(dev->dev, "cl dma map succeeded\n"); + cl->dma_mapped = 1; ++ cl->status = 0; ++ } + wake_up(&cl->wait); + } + +@@ -698,10 +702,14 @@ static void mei_hbm_cl_dma_unmap_res(str + if (!cl) + return; + +- dev_dbg(dev->dev, "cl dma unmap result = %d\n", res->status); +- cl->status = res->status; +- if (!cl->status) ++ if (res->status) { ++ dev_err(dev->dev, "cl dma unmap failed %d\n", res->status); ++ cl->status = -EFAULT; ++ } else { ++ dev_dbg(dev->dev, "cl dma unmap succeeded\n"); + cl->dma_mapped = 0; ++ cl->status = 0; ++ } + wake_up(&cl->wait); + } + diff --git a/queue-5.16/mm-page_alloc.c-do-not-warn-allocation-failure-on-zone-dma-if-no-managed-pages.patch b/queue-5.16/mm-page_alloc.c-do-not-warn-allocation-failure-on-zone-dma-if-no-managed-pages.patch new file mode 100644 index 00000000000..c7578b9f14b --- /dev/null +++ b/queue-5.16/mm-page_alloc.c-do-not-warn-allocation-failure-on-zone-dma-if-no-managed-pages.patch @@ -0,0 +1,98 @@ +From c4dc63f0032c77464fbd4e7a6afc22fa6913c4a7 Mon Sep 17 00:00:00 2001 +From: Baoquan He +Date: Fri, 14 Jan 2022 14:07:44 -0800 +Subject: mm/page_alloc.c: do not warn allocation failure on zone DMA if no managed pages + +From: Baoquan He + +commit c4dc63f0032c77464fbd4e7a6afc22fa6913c4a7 upstream. + +In kdump kernel of x86_64, page allocation failure is observed: + + kworker/u2:2: page allocation failure: order:0, mode:0xcc1(GFP_KERNEL|GFP_DMA), nodemask=(null),cpuset=/,mems_allowed=0 + CPU: 0 PID: 55 Comm: kworker/u2:2 Not tainted 5.16.0-rc4+ #5 + Hardware name: AMD Dinar/Dinar, BIOS RDN1505B 06/05/2013 + Workqueue: events_unbound async_run_entry_fn + Call Trace: + + dump_stack_lvl+0x48/0x5e + warn_alloc.cold+0x72/0xd6 + __alloc_pages_slowpath.constprop.0+0xc69/0xcd0 + __alloc_pages+0x1df/0x210 + new_slab+0x389/0x4d0 + ___slab_alloc+0x58f/0x770 + __slab_alloc.constprop.0+0x4a/0x80 + kmem_cache_alloc_trace+0x24b/0x2c0 + sr_probe+0x1db/0x620 + ...... + device_add+0x405/0x920 + ...... + __scsi_add_device+0xe5/0x100 + ata_scsi_scan_host+0x97/0x1d0 + async_run_entry_fn+0x30/0x130 + process_one_work+0x1e8/0x3c0 + worker_thread+0x50/0x3b0 + ? rescuer_thread+0x350/0x350 + kthread+0x16b/0x190 + ? set_kthread_struct+0x40/0x40 + ret_from_fork+0x22/0x30 + + Mem-Info: + ...... + +The above failure happened when calling kmalloc() to allocate buffer with +GFP_DMA. It requests to allocate slab page from DMA zone while no managed +pages at all in there. + + sr_probe() + --> get_capabilities() + --> buffer = kmalloc(512, GFP_KERNEL | GFP_DMA); + +Because in the current kernel, dma-kmalloc will be created as long as +CONFIG_ZONE_DMA is enabled. However, kdump kernel of x86_64 doesn't have +managed pages on DMA zone since commit 6f599d84231f ("x86/kdump: Always +reserve the low 1M when the crashkernel option is specified"). The +failure can be always reproduced. + +For now, let's mute the warning of allocation failure if requesting pages +from DMA zone while no managed pages. + +[akpm@linux-foundation.org: fix warning] + +Link: https://lkml.kernel.org/r/20211223094435.248523-4-bhe@redhat.com +Fixes: 6f599d84231f ("x86/kdump: Always reserve the low 1M when the crashkernel option is specified") +Signed-off-by: Baoquan He +Acked-by: John Donnelly +Reviewed-by: Hyeonggon Yoo <42.hyeyoo@gmail.com> +Cc: Christoph Lameter +Cc: Pekka Enberg +Cc: David Rientjes +Cc: Joonsoo Kim +Cc: Vlastimil Babka +Cc: Borislav Petkov +Cc: Christoph Hellwig +Cc: David Hildenbrand +Cc: David Laight +Cc: Marek Szyprowski +Cc: Robin Murphy +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman +--- + mm/page_alloc.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/mm/page_alloc.c ++++ b/mm/page_alloc.c +@@ -4204,7 +4204,9 @@ void warn_alloc(gfp_t gfp_mask, nodemask + va_list args; + static DEFINE_RATELIMIT_STATE(nopage_rs, 10*HZ, 1); + +- if ((gfp_mask & __GFP_NOWARN) || !__ratelimit(&nopage_rs)) ++ if ((gfp_mask & __GFP_NOWARN) || ++ !__ratelimit(&nopage_rs) || ++ ((gfp_mask & __GFP_DMA) && !has_managed_dma())) + return; + + va_start(args, fmt); diff --git a/queue-5.16/mm_zone-add-function-to-check-if-managed-dma-zone-exists.patch b/queue-5.16/mm_zone-add-function-to-check-if-managed-dma-zone-exists.patch new file mode 100644 index 00000000000..3907b74c04d --- /dev/null +++ b/queue-5.16/mm_zone-add-function-to-check-if-managed-dma-zone-exists.patch @@ -0,0 +1,169 @@ +From 62b3107073646e0946bd97ff926832bafb846d17 Mon Sep 17 00:00:00 2001 +From: Baoquan He +Date: Fri, 14 Jan 2022 14:07:37 -0800 +Subject: mm_zone: add function to check if managed dma zone exists + +From: Baoquan He + +commit 62b3107073646e0946bd97ff926832bafb846d17 upstream. + +Patch series "Handle warning of allocation failure on DMA zone w/o +managed pages", v4. + +**Problem observed: +On x86_64, when crash is triggered and entering into kdump kernel, page +allocation failure can always be seen. + + --------------------------------- + DMA: preallocated 128 KiB GFP_KERNEL pool for atomic allocations + swapper/0: page allocation failure: order:5, mode:0xcc1(GFP_KERNEL|GFP_DMA), nodemask=(null),cpuset=/,mems_allowed=0 + CPU: 0 PID: 1 Comm: swapper/0 + Call Trace: + dump_stack+0x7f/0xa1 + warn_alloc.cold+0x72/0xd6 + ...... + __alloc_pages+0x24d/0x2c0 + ...... + dma_atomic_pool_init+0xdb/0x176 + do_one_initcall+0x67/0x320 + ? rcu_read_lock_sched_held+0x3f/0x80 + kernel_init_freeable+0x290/0x2dc + ? rest_init+0x24f/0x24f + kernel_init+0xa/0x111 + ret_from_fork+0x22/0x30 + Mem-Info: + ------------------------------------ + +***Root cause: +In the current kernel, it assumes that DMA zone must have managed pages +and try to request pages if CONFIG_ZONE_DMA is enabled. While this is not +always true. E.g in kdump kernel of x86_64, only low 1M is presented and +locked down at very early stage of boot, so that this low 1M won't be +added into buddy allocator to become managed pages of DMA zone. This +exception will always cause page allocation failure if page is requested +from DMA zone. + +***Investigation: +This failure happens since below commit merged into linus's tree. + 1a6a9044b967 x86/setup: Remove CONFIG_X86_RESERVE_LOW and reservelow= options + 23721c8e92f7 x86/crash: Remove crash_reserve_low_1M() + f1d4d47c5851 x86/setup: Always reserve the first 1M of RAM + 7c321eb2b843 x86/kdump: Remove the backup region handling + 6f599d84231f x86/kdump: Always reserve the low 1M when the crashkernel option is specified + +Before them, on x86_64, the low 640K area will be reused by kdump kernel. +So in kdump kernel, the content of low 640K area is copied into a backup +region for dumping before jumping into kdump. Then except of those firmware +reserved region in [0, 640K], the left area will be added into buddy +allocator to become available managed pages of DMA zone. + +However, after above commits applied, in kdump kernel of x86_64, the low +1M is reserved by memblock, but not released to buddy allocator. So any +later page allocation requested from DMA zone will fail. + +At the beginning, if crashkernel is reserved, the low 1M need be locked +down because AMD SME encrypts memory making the old backup region +mechanims impossible when switching into kdump kernel. + +Later, it was also observed that there are BIOSes corrupting memory +under 1M. To solve this, in commit f1d4d47c5851, the entire region of +low 1M is always reserved after the real mode trampoline is allocated. + +Besides, recently, Intel engineer mentioned their TDX (Trusted domain +extensions) which is under development in kernel also needs to lock down +the low 1M. So we can't simply revert above commits to fix the page allocation +failure from DMA zone as someone suggested. + +***Solution: +Currently, only DMA atomic pool and dma-kmalloc will initialize and +request page allocation with GFP_DMA during bootup. + +So only initializ DMA atomic pool when DMA zone has available managed +pages, otherwise just skip the initialization. + +For dma-kmalloc(), for the time being, let's mute the warning of +allocation failure if requesting pages from DMA zone while no manged +pages. Meanwhile, change code to use dma_alloc_xx/dma_map_xx API to +replace kmalloc(GFP_DMA), or do not use GFP_DMA when calling kmalloc() if +not necessary. Christoph is posting patches to fix those under +drivers/scsi/. Finally, we can remove the need of dma-kmalloc() as people +suggested. + +This patch (of 3): + +In some places of the current kernel, it assumes that dma zone must have +managed pages if CONFIG_ZONE_DMA is enabled. While this is not always +true. E.g in kdump kernel of x86_64, only low 1M is presented and locked +down at very early stage of boot, so that there's no managed pages at all +in DMA zone. This exception will always cause page allocation failure if +page is requested from DMA zone. + +Here add function has_managed_dma() and the relevant helper functions to +check if there's DMA zone with managed pages. It will be used in later +patches. + +Link: https://lkml.kernel.org/r/20211223094435.248523-1-bhe@redhat.com +Link: https://lkml.kernel.org/r/20211223094435.248523-2-bhe@redhat.com +Fixes: 6f599d84231f ("x86/kdump: Always reserve the low 1M when the crashkernel option is specified") +Signed-off-by: Baoquan He +Reviewed-by: David Hildenbrand +Acked-by: John Donnelly +Cc: Christoph Hellwig +Cc: Christoph Lameter +Cc: Hyeonggon Yoo <42.hyeyoo@gmail.com> +Cc: Pekka Enberg +Cc: David Rientjes +Cc: Joonsoo Kim +Cc: Vlastimil Babka +Cc: David Laight +Cc: Borislav Petkov +Cc: Marek Szyprowski +Cc: Robin Murphy +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/mmzone.h | 9 +++++++++ + mm/page_alloc.c | 15 +++++++++++++++ + 2 files changed, 24 insertions(+) + +--- a/include/linux/mmzone.h ++++ b/include/linux/mmzone.h +@@ -1047,6 +1047,15 @@ static inline int is_highmem_idx(enum zo + #endif + } + ++#ifdef CONFIG_ZONE_DMA ++bool has_managed_dma(void); ++#else ++static inline bool has_managed_dma(void) ++{ ++ return false; ++} ++#endif ++ + /** + * is_highmem - helper function to quickly check if a struct zone is a + * highmem zone or not. This is an attempt to keep references +--- a/mm/page_alloc.c ++++ b/mm/page_alloc.c +@@ -9460,3 +9460,18 @@ bool take_page_off_buddy(struct page *pa + return ret; + } + #endif ++ ++#ifdef CONFIG_ZONE_DMA ++bool has_managed_dma(void) ++{ ++ struct pglist_data *pgdat; ++ ++ for_each_online_pgdat(pgdat) { ++ struct zone *zone = &pgdat->node_zones[ZONE_DMA]; ++ ++ if (managed_zone(zone)) ++ return true; ++ } ++ return false; ++} ++#endif /* CONFIG_ZONE_DMA */ diff --git a/queue-5.16/mtd-rawnand-davinci-avoid-duplicated-page-read.patch b/queue-5.16/mtd-rawnand-davinci-avoid-duplicated-page-read.patch new file mode 100644 index 00000000000..4b55ce0fd1f --- /dev/null +++ b/queue-5.16/mtd-rawnand-davinci-avoid-duplicated-page-read.patch @@ -0,0 +1,42 @@ +From 9c9d709965385de5a99f84b14bd5860e1541729e Mon Sep 17 00:00:00 2001 +From: Paul Cercueil +Date: Sat, 16 Oct 2021 14:22:25 +0100 +Subject: mtd: rawnand: davinci: Avoid duplicated page read + +From: Paul Cercueil + +commit 9c9d709965385de5a99f84b14bd5860e1541729e upstream. + +The function nand_davinci_read_page_hwecc_oob_first() first reads the +OOB data, extracts the ECC information, programs the ECC hardware before +reading the actual data in a loop. + +Right after the OOB data was read, it called nand_read_page_op() to +reset the read cursor to the beginning of the page. This caused the +first page to be read twice: in that call, and later in the loop. + +Address that issue by changing the call to nand_read_page_op() to +nand_change_read_column_op(), which will only reset the read cursor. + +Cc: # v5.2 +Fixes: a0ac778eb82c ("mtd: rawnand: ingenic: Add support for the JZ4740") +Signed-off-by: Paul Cercueil +Signed-off-by: Miquel Raynal +Link: https://lore.kernel.org/linux-mtd/20211016132228.40254-2-paul@crapouillou.net +Signed-off-by: Greg Kroah-Hartman +--- + drivers/mtd/nand/raw/davinci_nand.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/mtd/nand/raw/davinci_nand.c ++++ b/drivers/mtd/nand/raw/davinci_nand.c +@@ -401,7 +401,8 @@ static int nand_davinci_read_page_hwecc_ + if (ret) + return ret; + +- ret = nand_read_page_op(chip, page, 0, NULL, 0); ++ /* Move read cursor to start of page */ ++ ret = nand_change_read_column_op(chip, 0, NULL, 0, false); + if (ret) + return ret; + diff --git a/queue-5.16/mtd-rawnand-davinci-don-t-calculate-ecc-when-reading-page.patch b/queue-5.16/mtd-rawnand-davinci-don-t-calculate-ecc-when-reading-page.patch new file mode 100644 index 00000000000..01a1ede7971 --- /dev/null +++ b/queue-5.16/mtd-rawnand-davinci-don-t-calculate-ecc-when-reading-page.patch @@ -0,0 +1,42 @@ +From 71e89591502d737c10db2bd4d8fcfaa352552afb Mon Sep 17 00:00:00 2001 +From: Paul Cercueil +Date: Sat, 16 Oct 2021 14:22:24 +0100 +Subject: mtd: rawnand: davinci: Don't calculate ECC when reading page + +From: Paul Cercueil + +commit 71e89591502d737c10db2bd4d8fcfaa352552afb upstream. + +The function nand_davinci_read_page_hwecc_oob_first() does read the ECC +data from the OOB area. Therefore it does not need to calculate the ECC +as it is already available. + +Cc: # v5.2 +Fixes: a0ac778eb82c ("mtd: rawnand: ingenic: Add support for the JZ4740") +Signed-off-by: Paul Cercueil +Signed-off-by: Miquel Raynal +Link: https://lore.kernel.org/linux-mtd/20211016132228.40254-1-paul@crapouillou.net +Signed-off-by: Greg Kroah-Hartman +--- + drivers/mtd/nand/raw/davinci_nand.c | 3 --- + 1 file changed, 3 deletions(-) + +--- a/drivers/mtd/nand/raw/davinci_nand.c ++++ b/drivers/mtd/nand/raw/davinci_nand.c +@@ -394,7 +394,6 @@ static int nand_davinci_read_page_hwecc_ + int eccsteps = chip->ecc.steps; + uint8_t *p = buf; + uint8_t *ecc_code = chip->ecc.code_buf; +- uint8_t *ecc_calc = chip->ecc.calc_buf; + unsigned int max_bitflips = 0; + + /* Read the OOB area first */ +@@ -420,8 +419,6 @@ static int nand_davinci_read_page_hwecc_ + if (ret) + return ret; + +- chip->ecc.calculate(chip, p, &ecc_calc[i]); +- + stat = chip->ecc.correct(chip, p, &ecc_code[i], NULL); + if (stat == -EBADMSG && + (chip->ecc.options & NAND_ECC_GENERIC_ERASED_CHECK)) { diff --git a/queue-5.16/mtd-rawnand-davinci-rewrite-function-description.patch b/queue-5.16/mtd-rawnand-davinci-rewrite-function-description.patch new file mode 100644 index 00000000000..79427fbcd66 --- /dev/null +++ b/queue-5.16/mtd-rawnand-davinci-rewrite-function-description.patch @@ -0,0 +1,47 @@ +From 0697f8441faad552fbeb02d74454b5e7bcc956a2 Mon Sep 17 00:00:00 2001 +From: Paul Cercueil +Date: Sat, 16 Oct 2021 14:22:26 +0100 +Subject: mtd: rawnand: davinci: Rewrite function description + +From: Paul Cercueil + +commit 0697f8441faad552fbeb02d74454b5e7bcc956a2 upstream. + +The original comment that describes the function +nand_davinci_read_page_hwecc_oob_first() is very obscure and it is hard +to understand what it is for. + +Cc: # v5.2 +Fixes: a0ac778eb82c ("mtd: rawnand: ingenic: Add support for the JZ4740") +Signed-off-by: Paul Cercueil +Signed-off-by: Miquel Raynal +Link: https://lore.kernel.org/linux-mtd/20211016132228.40254-3-paul@crapouillou.net +Signed-off-by: Greg Kroah-Hartman +--- + drivers/mtd/nand/raw/davinci_nand.c | 10 ++++------ + 1 file changed, 4 insertions(+), 6 deletions(-) + +--- a/drivers/mtd/nand/raw/davinci_nand.c ++++ b/drivers/mtd/nand/raw/davinci_nand.c +@@ -372,17 +372,15 @@ correct: + } + + /** +- * nand_read_page_hwecc_oob_first - hw ecc, read oob first ++ * nand_davinci_read_page_hwecc_oob_first - Hardware ECC page read with ECC ++ * data read from OOB area + * @chip: nand chip info structure + * @buf: buffer to store read data + * @oob_required: caller requires OOB data read to chip->oob_poi + * @page: page number to read + * +- * Hardware ECC for large page chips, require OOB to be read first. For this +- * ECC mode, the write_page method is re-used from ECC_HW. These methods +- * read/write ECC from the OOB area, unlike the ECC_HW_SYNDROME support with +- * multiple ECC steps, follows the "infix ECC" scheme and reads/writes ECC from +- * the data area, by overwriting the NAND manufacturer bad block markings. ++ * Hardware ECC for large page chips, which requires the ECC data to be ++ * extracted from the OOB before the actual data is read. + */ + static int nand_davinci_read_page_hwecc_oob_first(struct nand_chip *chip, + uint8_t *buf, diff --git a/queue-5.16/mtd-rawnand-export-nand_read_page_hwecc_oob_first.patch b/queue-5.16/mtd-rawnand-export-nand_read_page_hwecc_oob_first.patch new file mode 100644 index 00000000000..4839d38ae45 --- /dev/null +++ b/queue-5.16/mtd-rawnand-export-nand_read_page_hwecc_oob_first.patch @@ -0,0 +1,197 @@ +From d8466f73010faf71effb21228ae1cbf577dab130 Mon Sep 17 00:00:00 2001 +From: Paul Cercueil +Date: Sat, 16 Oct 2021 14:22:27 +0100 +Subject: mtd: rawnand: Export nand_read_page_hwecc_oob_first() + +From: Paul Cercueil + +commit d8466f73010faf71effb21228ae1cbf577dab130 upstream. + +Move the function nand_read_page_hwecc_oob_first() (previously +nand_davinci_read_page_hwecc_oob_first()) to nand_base.c, and export it +as a GPL symbol, so that it can be used by more modules. + +Cc: # v5.2 +Fixes: a0ac778eb82c ("mtd: rawnand: ingenic: Add support for the JZ4740") +Signed-off-by: Paul Cercueil +Signed-off-by: Miquel Raynal +Link: https://lore.kernel.org/linux-mtd/20211016132228.40254-4-paul@crapouillou.net +Signed-off-by: Greg Kroah-Hartman +--- + drivers/mtd/nand/raw/davinci_nand.c | 69 ------------------------------------ + drivers/mtd/nand/raw/nand_base.c | 67 ++++++++++++++++++++++++++++++++++ + include/linux/mtd/rawnand.h | 2 + + 3 files changed, 70 insertions(+), 68 deletions(-) + +--- a/drivers/mtd/nand/raw/davinci_nand.c ++++ b/drivers/mtd/nand/raw/davinci_nand.c +@@ -371,73 +371,6 @@ correct: + return corrected; + } + +-/** +- * nand_davinci_read_page_hwecc_oob_first - Hardware ECC page read with ECC +- * data read from OOB area +- * @chip: nand chip info structure +- * @buf: buffer to store read data +- * @oob_required: caller requires OOB data read to chip->oob_poi +- * @page: page number to read +- * +- * Hardware ECC for large page chips, which requires the ECC data to be +- * extracted from the OOB before the actual data is read. +- */ +-static int nand_davinci_read_page_hwecc_oob_first(struct nand_chip *chip, +- uint8_t *buf, +- int oob_required, int page) +-{ +- struct mtd_info *mtd = nand_to_mtd(chip); +- int i, eccsize = chip->ecc.size, ret; +- int eccbytes = chip->ecc.bytes; +- int eccsteps = chip->ecc.steps; +- uint8_t *p = buf; +- uint8_t *ecc_code = chip->ecc.code_buf; +- unsigned int max_bitflips = 0; +- +- /* Read the OOB area first */ +- ret = nand_read_oob_op(chip, page, 0, chip->oob_poi, mtd->oobsize); +- if (ret) +- return ret; +- +- /* Move read cursor to start of page */ +- ret = nand_change_read_column_op(chip, 0, NULL, 0, false); +- if (ret) +- return ret; +- +- ret = mtd_ooblayout_get_eccbytes(mtd, ecc_code, chip->oob_poi, 0, +- chip->ecc.total); +- if (ret) +- return ret; +- +- for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) { +- int stat; +- +- chip->ecc.hwctl(chip, NAND_ECC_READ); +- +- ret = nand_read_data_op(chip, p, eccsize, false, false); +- if (ret) +- return ret; +- +- stat = chip->ecc.correct(chip, p, &ecc_code[i], NULL); +- if (stat == -EBADMSG && +- (chip->ecc.options & NAND_ECC_GENERIC_ERASED_CHECK)) { +- /* check for empty pages with bitflips */ +- stat = nand_check_erased_ecc_chunk(p, eccsize, +- &ecc_code[i], +- eccbytes, NULL, 0, +- chip->ecc.strength); +- } +- +- if (stat < 0) { +- mtd->ecc_stats.failed++; +- } else { +- mtd->ecc_stats.corrected += stat; +- max_bitflips = max_t(unsigned int, max_bitflips, stat); +- } +- } +- return max_bitflips; +-} +- + /*----------------------------------------------------------------------*/ + + /* An ECC layout for using 4-bit ECC with small-page flash, storing +@@ -647,7 +580,7 @@ static int davinci_nand_attach_chip(stru + } else if (chunks == 4 || chunks == 8) { + mtd_set_ooblayout(mtd, + nand_get_large_page_ooblayout()); +- chip->ecc.read_page = nand_davinci_read_page_hwecc_oob_first; ++ chip->ecc.read_page = nand_read_page_hwecc_oob_first; + } else { + return -EIO; + } +--- a/drivers/mtd/nand/raw/nand_base.c ++++ b/drivers/mtd/nand/raw/nand_base.c +@@ -3161,6 +3161,73 @@ static int nand_read_page_hwecc(struct n + } + + /** ++ * nand_read_page_hwecc_oob_first - Hardware ECC page read with ECC ++ * data read from OOB area ++ * @chip: nand chip info structure ++ * @buf: buffer to store read data ++ * @oob_required: caller requires OOB data read to chip->oob_poi ++ * @page: page number to read ++ * ++ * Hardware ECC for large page chips, which requires the ECC data to be ++ * extracted from the OOB before the actual data is read. ++ */ ++int nand_read_page_hwecc_oob_first(struct nand_chip *chip, uint8_t *buf, ++ int oob_required, int page) ++{ ++ struct mtd_info *mtd = nand_to_mtd(chip); ++ int i, eccsize = chip->ecc.size, ret; ++ int eccbytes = chip->ecc.bytes; ++ int eccsteps = chip->ecc.steps; ++ uint8_t *p = buf; ++ uint8_t *ecc_code = chip->ecc.code_buf; ++ unsigned int max_bitflips = 0; ++ ++ /* Read the OOB area first */ ++ ret = nand_read_oob_op(chip, page, 0, chip->oob_poi, mtd->oobsize); ++ if (ret) ++ return ret; ++ ++ /* Move read cursor to start of page */ ++ ret = nand_change_read_column_op(chip, 0, NULL, 0, false); ++ if (ret) ++ return ret; ++ ++ ret = mtd_ooblayout_get_eccbytes(mtd, ecc_code, chip->oob_poi, 0, ++ chip->ecc.total); ++ if (ret) ++ return ret; ++ ++ for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) { ++ int stat; ++ ++ chip->ecc.hwctl(chip, NAND_ECC_READ); ++ ++ ret = nand_read_data_op(chip, p, eccsize, false, false); ++ if (ret) ++ return ret; ++ ++ stat = chip->ecc.correct(chip, p, &ecc_code[i], NULL); ++ if (stat == -EBADMSG && ++ (chip->ecc.options & NAND_ECC_GENERIC_ERASED_CHECK)) { ++ /* check for empty pages with bitflips */ ++ stat = nand_check_erased_ecc_chunk(p, eccsize, ++ &ecc_code[i], ++ eccbytes, NULL, 0, ++ chip->ecc.strength); ++ } ++ ++ if (stat < 0) { ++ mtd->ecc_stats.failed++; ++ } else { ++ mtd->ecc_stats.corrected += stat; ++ max_bitflips = max_t(unsigned int, max_bitflips, stat); ++ } ++ } ++ return max_bitflips; ++} ++EXPORT_SYMBOL_GPL(nand_read_page_hwecc_oob_first); ++ ++/** + * nand_read_page_syndrome - [REPLACEABLE] hardware ECC syndrome based page read + * @chip: nand chip info structure + * @buf: buffer to store read data +--- a/include/linux/mtd/rawnand.h ++++ b/include/linux/mtd/rawnand.h +@@ -1539,6 +1539,8 @@ int nand_read_data_op(struct nand_chip * + bool force_8bit, bool check_only); + int nand_write_data_op(struct nand_chip *chip, const void *buf, + unsigned int len, bool force_8bit); ++int nand_read_page_hwecc_oob_first(struct nand_chip *chip, uint8_t *buf, ++ int oob_required, int page); + + /* Scan and identify a NAND device */ + int nand_scan_with_ids(struct nand_chip *chip, unsigned int max_chips, diff --git a/queue-5.16/mtd-rawnand-ingenic-jz4740-needs-oob_first-read-page-function.patch b/queue-5.16/mtd-rawnand-ingenic-jz4740-needs-oob_first-read-page-function.patch new file mode 100644 index 00000000000..23f7a87d248 --- /dev/null +++ b/queue-5.16/mtd-rawnand-ingenic-jz4740-needs-oob_first-read-page-function.patch @@ -0,0 +1,59 @@ +From 0171480007d64f663aae9226303f1b1e4621229e Mon Sep 17 00:00:00 2001 +From: Paul Cercueil +Date: Sat, 16 Oct 2021 14:22:28 +0100 +Subject: mtd: rawnand: ingenic: JZ4740 needs 'oob_first' read page function + +From: Paul Cercueil + +commit 0171480007d64f663aae9226303f1b1e4621229e upstream. + +The ECC engine on the JZ4740 SoC requires the ECC data to be read before +the page; using the default page reading function does not work. Indeed, +the old JZ4740 NAND driver (removed in 5.4) did use the 'OOB first' flag +that existed back then. + +Use the newly created nand_read_page_hwecc_oob_first() to address this +issue. + +This issue was not found when the new ingenic-nand driver was developed, +most likely because the Device Tree used had the nand-ecc-mode set to +"hw_oob_first", which seems to not be supported anymore. + +Cc: # v5.2 +Fixes: a0ac778eb82c ("mtd: rawnand: ingenic: Add support for the JZ4740") +Signed-off-by: Paul Cercueil +Signed-off-by: Miquel Raynal +Link: https://lore.kernel.org/linux-mtd/20211016132228.40254-5-paul@crapouillou.net +Signed-off-by: Greg Kroah-Hartman +--- + drivers/mtd/nand/raw/ingenic/ingenic_nand_drv.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/drivers/mtd/nand/raw/ingenic/ingenic_nand_drv.c ++++ b/drivers/mtd/nand/raw/ingenic/ingenic_nand_drv.c +@@ -32,6 +32,7 @@ struct jz_soc_info { + unsigned long addr_offset; + unsigned long cmd_offset; + const struct mtd_ooblayout_ops *oob_layout; ++ bool oob_first; + }; + + struct ingenic_nand_cs { +@@ -240,6 +241,9 @@ static int ingenic_nand_attach_chip(stru + if (chip->bbt_options & NAND_BBT_USE_FLASH) + chip->bbt_options |= NAND_BBT_NO_OOB; + ++ if (nfc->soc_info->oob_first) ++ chip->ecc.read_page = nand_read_page_hwecc_oob_first; ++ + /* For legacy reasons we use a different layout on the qi,lb60 board. */ + if (of_machine_is_compatible("qi,lb60")) + mtd_set_ooblayout(mtd, &qi_lb60_ooblayout_ops); +@@ -534,6 +538,7 @@ static const struct jz_soc_info jz4740_s + .data_offset = 0x00000000, + .cmd_offset = 0x00008000, + .addr_offset = 0x00010000, ++ .oob_first = true, + }; + + static const struct jz_soc_info jz4725b_soc_info = { diff --git a/queue-5.16/net-phy-marvell-add-marvell-specific-phy-loopback.patch b/queue-5.16/net-phy-marvell-add-marvell-specific-phy-loopback.patch new file mode 100644 index 00000000000..c533461db69 --- /dev/null +++ b/queue-5.16/net-phy-marvell-add-marvell-specific-phy-loopback.patch @@ -0,0 +1,108 @@ +From 020a45aff1190c32b1087cd75b57fbf6bff46ea6 Mon Sep 17 00:00:00 2001 +From: Mohammad Athari Bin Ismail +Date: Sat, 15 Jan 2022 17:25:15 +0800 +Subject: net: phy: marvell: add Marvell specific PHY loopback + +From: Mohammad Athari Bin Ismail + +commit 020a45aff1190c32b1087cd75b57fbf6bff46ea6 upstream. + +Existing genphy_loopback() is not applicable for Marvell PHY. Besides +configuring bit-6 and bit-13 in Page 0 Register 0 (Copper Control +Register), it is also required to configure same bits in Page 2 +Register 21 (MAC Specific Control Register 2) according to speed of +the loopback is operating. + +Tested working on Marvell88E1510 PHY for all speeds (1000/100/10Mbps). + +FIXME: Based on trial and error test, it seem 1G need to have delay between +soft reset and loopback enablement. + +Fixes: 014068dcb5b1 ("net: phy: genphy_loopback: add link speed configuration") +Cc: # 5.15.x +Signed-off-by: Mohammad Athari Bin Ismail +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/phy/marvell.c | 56 +++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 55 insertions(+), 1 deletion(-) + +--- a/drivers/net/phy/marvell.c ++++ b/drivers/net/phy/marvell.c +@@ -189,6 +189,8 @@ + #define MII_88E1510_GEN_CTRL_REG_1_MODE_RGMII_SGMII 0x4 + #define MII_88E1510_GEN_CTRL_REG_1_RESET 0x8000 /* Soft reset */ + ++#define MII_88E1510_MSCR_2 0x15 ++ + #define MII_VCT5_TX_RX_MDI0_COUPLING 0x10 + #define MII_VCT5_TX_RX_MDI1_COUPLING 0x11 + #define MII_VCT5_TX_RX_MDI2_COUPLING 0x12 +@@ -1932,6 +1934,58 @@ static void marvell_get_stats(struct phy + data[i] = marvell_get_stat(phydev, i); + } + ++static int m88e1510_loopback(struct phy_device *phydev, bool enable) ++{ ++ int err; ++ ++ if (enable) { ++ u16 bmcr_ctl = 0, mscr2_ctl = 0; ++ ++ if (phydev->speed == SPEED_1000) ++ bmcr_ctl = BMCR_SPEED1000; ++ else if (phydev->speed == SPEED_100) ++ bmcr_ctl = BMCR_SPEED100; ++ ++ if (phydev->duplex == DUPLEX_FULL) ++ bmcr_ctl |= BMCR_FULLDPLX; ++ ++ err = phy_write(phydev, MII_BMCR, bmcr_ctl); ++ if (err < 0) ++ return err; ++ ++ if (phydev->speed == SPEED_1000) ++ mscr2_ctl = BMCR_SPEED1000; ++ else if (phydev->speed == SPEED_100) ++ mscr2_ctl = BMCR_SPEED100; ++ ++ err = phy_modify_paged(phydev, MII_MARVELL_MSCR_PAGE, ++ MII_88E1510_MSCR_2, BMCR_SPEED1000 | ++ BMCR_SPEED100, mscr2_ctl); ++ if (err < 0) ++ return err; ++ ++ /* Need soft reset to have speed configuration takes effect */ ++ err = genphy_soft_reset(phydev); ++ if (err < 0) ++ return err; ++ ++ /* FIXME: Based on trial and error test, it seem 1G need to have ++ * delay between soft reset and loopback enablement. ++ */ ++ if (phydev->speed == SPEED_1000) ++ msleep(1000); ++ ++ return phy_modify(phydev, MII_BMCR, BMCR_LOOPBACK, ++ BMCR_LOOPBACK); ++ } else { ++ err = phy_modify(phydev, MII_BMCR, BMCR_LOOPBACK, 0); ++ if (err < 0) ++ return err; ++ ++ return phy_config_aneg(phydev); ++ } ++} ++ + static int marvell_vct5_wait_complete(struct phy_device *phydev) + { + int i; +@@ -3078,7 +3132,7 @@ static struct phy_driver marvell_drivers + .get_sset_count = marvell_get_sset_count, + .get_strings = marvell_get_strings, + .get_stats = marvell_get_stats, +- .set_loopback = genphy_loopback, ++ .set_loopback = m88e1510_loopback, + .get_tunable = m88e1011_get_tunable, + .set_tunable = m88e1011_set_tunable, + .cable_test_start = marvell_vct7_cable_test_start, diff --git a/queue-5.16/pci-add-function-1-dma-alias-quirk-for-marvell-88se9125-sata-controller.patch b/queue-5.16/pci-add-function-1-dma-alias-quirk-for-marvell-88se9125-sata-controller.patch new file mode 100644 index 00000000000..8532902a36a --- /dev/null +++ b/queue-5.16/pci-add-function-1-dma-alias-quirk-for-marvell-88se9125-sata-controller.patch @@ -0,0 +1,57 @@ +From e445375882883f69018aa669b67cbb37ec873406 Mon Sep 17 00:00:00 2001 +From: Yifeng Li +Date: Thu, 2 Dec 2021 06:35:21 +0000 +Subject: PCI: Add function 1 DMA alias quirk for Marvell 88SE9125 SATA controller +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Yifeng Li + +commit e445375882883f69018aa669b67cbb37ec873406 upstream. + +Like other SATA controller chips in the Marvell 88SE91xx series, the +Marvell 88SE9125 has the same DMA requester ID hardware bug that prevents +it from working under IOMMU. Add it to the list of devices that need the +quirk. + +Without this patch, device initialization fails with DMA errors: + + ata8: softreset failed (1st FIS failed) + DMAR: DRHD: handling fault status reg 2 + DMAR: [DMA Write NO_PASID] Request device [03:00.1] fault addr 0xfffc0000 [fault reason 0x02] Present bit in context entry is clear + DMAR: DRHD: handling fault status reg 2 + DMAR: [DMA Read NO_PASID] Request device [03:00.1] fault addr 0xfffc0000 [fault reason 0x02] Present bit in context entry is clear + +After applying the patch, the controller can be successfully initialized: + + ata8: SATA link up 1.5 Gbps (SStatus 113 SControl 330) + ata8.00: ATAPI: PIONEER BD-RW BDR-207M, 1.21, max UDMA/100 + ata8.00: configured for UDMA/100 + scsi 7:0:0:0: CD-ROM PIONEER BD-RW BDR-207M 1.21 PQ: 0 ANSI: 5 + +Link: https://lore.kernel.org/r/YahpKVR+McJVDdkD@work +Reported-by: Sam Bingner +Tested-by: Sam Bingner +Tested-by: Yifeng Li +Signed-off-by: Yifeng Li +Signed-off-by: Bjorn Helgaas +Reviewed-by: Krzysztof Wilczyński +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/quirks.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/pci/quirks.c ++++ b/drivers/pci/quirks.c +@@ -4103,6 +4103,9 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_M + quirk_dma_func1_alias); + DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9123, + quirk_dma_func1_alias); ++/* https://bugzilla.kernel.org/show_bug.cgi?id=42679#c136 */ ++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9125, ++ quirk_dma_func1_alias); + DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9128, + quirk_dma_func1_alias); + /* https://bugzilla.kernel.org/show_bug.cgi?id=42679#c14 */ diff --git a/queue-5.16/risc-v-use-common-riscv_cpuid_to_hartid_mask-for-both-smp-y-and-smp-n.patch b/queue-5.16/risc-v-use-common-riscv_cpuid_to_hartid_mask-for-both-smp-y-and-smp-n.patch new file mode 100644 index 00000000000..53f9dcc37a7 --- /dev/null +++ b/queue-5.16/risc-v-use-common-riscv_cpuid_to_hartid_mask-for-both-smp-y-and-smp-n.patch @@ -0,0 +1,100 @@ +From 869c70609248102f3a2e95a39b6233ff6ea2c932 Mon Sep 17 00:00:00 2001 +From: Sean Christopherson +Date: Mon, 29 Nov 2021 21:43:42 +0000 +Subject: RISC-V: Use common riscv_cpuid_to_hartid_mask() for both SMP=y and SMP=n + +From: Sean Christopherson + +commit 869c70609248102f3a2e95a39b6233ff6ea2c932 upstream. + +Use what is currently the SMP=y version of riscv_cpuid_to_hartid_mask() +for both SMP=y and SMP=n to fix a build failure with KVM=m and SMP=n due +to boot_cpu_hartid not being exported. This also fixes a second bug +where the SMP=n version assumes the sole CPU in the system is in the +incoming mask, which may not hold true in kvm_riscv_vcpu_sbi_ecall() if +the KVM guest VM has multiple vCPUs (on a SMP=n system). + +Fixes: 1ef46c231df4 ("RISC-V: Implement new SBI v0.2 extensions") +Reported-by: Adam Borowski +Reviewed-by: Anup Patel +Signed-off-by: Sean Christopherson +Cc: stable@vger.kernel.org +Signed-off-by: Palmer Dabbelt +Signed-off-by: Greg Kroah-Hartman +--- + arch/riscv/include/asm/smp.h | 10 ++-------- + arch/riscv/kernel/setup.c | 10 ++++++++++ + arch/riscv/kernel/smp.c | 10 ---------- + 3 files changed, 12 insertions(+), 18 deletions(-) + +--- a/arch/riscv/include/asm/smp.h ++++ b/arch/riscv/include/asm/smp.h +@@ -43,7 +43,6 @@ void arch_send_call_function_ipi_mask(st + void arch_send_call_function_single_ipi(int cpu); + + int riscv_hartid_to_cpuid(int hartid); +-void riscv_cpuid_to_hartid_mask(const struct cpumask *in, struct cpumask *out); + + /* Set custom IPI operations */ + void riscv_set_ipi_ops(const struct riscv_ipi_ops *ops); +@@ -85,13 +84,6 @@ static inline unsigned long cpuid_to_har + return boot_cpu_hartid; + } + +-static inline void riscv_cpuid_to_hartid_mask(const struct cpumask *in, +- struct cpumask *out) +-{ +- cpumask_clear(out); +- cpumask_set_cpu(boot_cpu_hartid, out); +-} +- + static inline void riscv_set_ipi_ops(const struct riscv_ipi_ops *ops) + { + } +@@ -102,6 +94,8 @@ static inline void riscv_clear_ipi(void) + + #endif /* CONFIG_SMP */ + ++void riscv_cpuid_to_hartid_mask(const struct cpumask *in, struct cpumask *out); ++ + #if defined(CONFIG_HOTPLUG_CPU) && (CONFIG_SMP) + bool cpu_has_hotplug(unsigned int cpu); + #else +--- a/arch/riscv/kernel/setup.c ++++ b/arch/riscv/kernel/setup.c +@@ -59,6 +59,16 @@ atomic_t hart_lottery __section(".sdata" + unsigned long boot_cpu_hartid; + static DEFINE_PER_CPU(struct cpu, cpu_devices); + ++void riscv_cpuid_to_hartid_mask(const struct cpumask *in, struct cpumask *out) ++{ ++ int cpu; ++ ++ cpumask_clear(out); ++ for_each_cpu(cpu, in) ++ cpumask_set_cpu(cpuid_to_hartid_map(cpu), out); ++} ++EXPORT_SYMBOL_GPL(riscv_cpuid_to_hartid_mask); ++ + /* + * Place kernel memory regions on the resource tree so that + * kexec-tools can retrieve them from /proc/iomem. While there +--- a/arch/riscv/kernel/smp.c ++++ b/arch/riscv/kernel/smp.c +@@ -59,16 +59,6 @@ int riscv_hartid_to_cpuid(int hartid) + return -ENOENT; + } + +-void riscv_cpuid_to_hartid_mask(const struct cpumask *in, struct cpumask *out) +-{ +- int cpu; +- +- cpumask_clear(out); +- for_each_cpu(cpu, in) +- cpumask_set_cpu(cpuid_to_hartid_map(cpu), out); +-} +-EXPORT_SYMBOL_GPL(riscv_cpuid_to_hartid_mask); +- + bool arch_match_cpu_phys_id(int cpu, u64 phys_id) + { + return phys_id == cpuid_to_hartid_map(cpu); diff --git a/queue-5.16/riscv-don-t-use-va_pa_offset-on-kdump.patch b/queue-5.16/riscv-don-t-use-va_pa_offset-on-kdump.patch new file mode 100644 index 00000000000..a1c0a5d6915 --- /dev/null +++ b/queue-5.16/riscv-don-t-use-va_pa_offset-on-kdump.patch @@ -0,0 +1,81 @@ +From a11c07f032a0e9a562a32ece73af96b0e754c4b3 Mon Sep 17 00:00:00 2001 +From: Nick Kossifidis +Date: Fri, 26 Nov 2021 20:04:09 +0200 +Subject: riscv: Don't use va_pa_offset on kdump + +From: Nick Kossifidis + +commit a11c07f032a0e9a562a32ece73af96b0e754c4b3 upstream. + +On kdump instead of using an intermediate step to relocate the kernel, +that lives in a "control buffer" outside the current kernel's mapping, +we jump to the crash kernel directly by calling riscv_kexec_norelocate(). +The current implementation uses va_pa_offset while switching to physical +addressing, however since we moved the kernel outside the linear mapping +this won't work anymore since riscv_kexec_norelocate() is part of the +kernel mapping and we should use kernel_map.va_kernel_pa_offset, and also +take XIP kernel into account. + +We don't really need to use va_pa_offset on riscv_kexec_norelocate, we +can just set STVEC to the physical address of the new kernel instead and +let the hart jump to the new kernel on the next instruction after setting +SATP to zero. This fixes kdump and is also simpler/cleaner. + +I tested this on the latest qemu and HiFive Unmatched and works as +expected. + +Fixes: 2bfc6cd81bd1 ("riscv: Move kernel mapping outside of linear mapping") +Signed-off-by: Nick Kossifidis +Reviewed-by: Alexandre Ghiti +Cc: stable@vger.kernel.org +Signed-off-by: Palmer Dabbelt +Signed-off-by: Greg Kroah-Hartman +--- + arch/riscv/kernel/kexec_relocate.S | 20 +++++++++----------- + 1 file changed, 9 insertions(+), 11 deletions(-) + +--- a/arch/riscv/kernel/kexec_relocate.S ++++ b/arch/riscv/kernel/kexec_relocate.S +@@ -159,25 +159,15 @@ SYM_CODE_START(riscv_kexec_norelocate) + * s0: (const) Phys address to jump to + * s1: (const) Phys address of the FDT image + * s2: (const) The hartid of the current hart +- * s3: (const) kernel_map.va_pa_offset, used when switching MMU off + */ + mv s0, a1 + mv s1, a2 + mv s2, a3 +- mv s3, a4 + + /* Disable / cleanup interrupts */ + csrw CSR_SIE, zero + csrw CSR_SIP, zero + +- /* Switch to physical addressing */ +- la s4, 1f +- sub s4, s4, s3 +- csrw CSR_STVEC, s4 +- csrw CSR_SATP, zero +- +-.align 2 +-1: + /* Pass the arguments to the next kernel / Cleanup*/ + mv a0, s2 + mv a1, s1 +@@ -214,7 +204,15 @@ SYM_CODE_START(riscv_kexec_norelocate) + csrw CSR_SCAUSE, zero + csrw CSR_SSCRATCH, zero + +- jalr zero, a2, 0 ++ /* ++ * Switch to physical addressing ++ * This will also trigger a jump to CSR_STVEC ++ * which in this case is the address of the new ++ * kernel. ++ */ ++ csrw CSR_STVEC, a2 ++ csrw CSR_SATP, zero ++ + SYM_CODE_END(riscv_kexec_norelocate) + + .section ".rodata" diff --git a/queue-5.16/riscv-get-rid-of-maxphysmem-configs.patch b/queue-5.16/riscv-get-rid-of-maxphysmem-configs.patch new file mode 100644 index 00000000000..d6395b325fd --- /dev/null +++ b/queue-5.16/riscv-get-rid-of-maxphysmem-configs.patch @@ -0,0 +1,104 @@ +From db1503d355a79d1d4255a9996f20e72848b74a56 Mon Sep 17 00:00:00 2001 +From: Alexandre Ghiti +Date: Mon, 17 Jan 2022 10:57:16 +0100 +Subject: riscv: Get rid of MAXPHYSMEM configs + +From: Alexandre Ghiti + +commit db1503d355a79d1d4255a9996f20e72848b74a56 upstream. + +CONFIG_MAXPHYSMEM_* are actually never used, even the nommu defconfigs +selecting the MAXPHYSMEM_2GB had no effects on PAGE_OFFSET since it was +preempted by !MMU case right before. + +In addition, the move of the kernel mapping at the end of the address +space broke the use of MAXPHYSMEM_2G with MMU since it defines PAGE_OFFSET +at the same address as the kernel mapping. + +Reported-by: Geert Uytterhoeven +Fixes: 2bfc6cd81bd1 ("riscv: Move kernel mapping outside of linear mapping") +Signed-off-by: Alexandre Ghiti +Tested-by: Geert Uytterhoeven +Tested-by: Conor Dooley +Cc: stable@vger.kernel.org +Signed-off-by: Palmer Dabbelt +Signed-off-by: Greg Kroah-Hartman +--- + arch/riscv/Kconfig | 23 ++--------------------- + arch/riscv/configs/nommu_k210_defconfig | 2 -- + arch/riscv/configs/nommu_k210_sdcard_defconfig | 2 -- + arch/riscv/configs/nommu_virt_defconfig | 1 - + 4 files changed, 2 insertions(+), 26 deletions(-) + +--- a/arch/riscv/Kconfig ++++ b/arch/riscv/Kconfig +@@ -158,10 +158,9 @@ config PA_BITS + + config PAGE_OFFSET + hex +- default 0xC0000000 if 32BIT && MAXPHYSMEM_1GB ++ default 0xC0000000 if 32BIT + default 0x80000000 if 64BIT && !MMU +- default 0xffffffff80000000 if 64BIT && MAXPHYSMEM_2GB +- default 0xffffffe000000000 if 64BIT && MAXPHYSMEM_128GB ++ default 0xffffffe000000000 if 64BIT + + config KASAN_SHADOW_OFFSET + hex +@@ -270,24 +269,6 @@ config MODULE_SECTIONS + bool + select HAVE_MOD_ARCH_SPECIFIC + +-choice +- prompt "Maximum Physical Memory" +- default MAXPHYSMEM_1GB if 32BIT +- default MAXPHYSMEM_2GB if 64BIT && CMODEL_MEDLOW +- default MAXPHYSMEM_128GB if 64BIT && CMODEL_MEDANY +- +- config MAXPHYSMEM_1GB +- depends on 32BIT +- bool "1GiB" +- config MAXPHYSMEM_2GB +- depends on 64BIT && CMODEL_MEDLOW +- bool "2GiB" +- config MAXPHYSMEM_128GB +- depends on 64BIT && CMODEL_MEDANY +- bool "128GiB" +-endchoice +- +- + config SMP + bool "Symmetric Multi-Processing" + help +--- a/arch/riscv/configs/nommu_k210_defconfig ++++ b/arch/riscv/configs/nommu_k210_defconfig +@@ -29,8 +29,6 @@ CONFIG_EMBEDDED=y + CONFIG_SLOB=y + # CONFIG_MMU is not set + CONFIG_SOC_CANAAN=y +-CONFIG_SOC_CANAAN_K210_DTB_SOURCE="k210_generic" +-CONFIG_MAXPHYSMEM_2GB=y + CONFIG_SMP=y + CONFIG_NR_CPUS=2 + CONFIG_CMDLINE="earlycon console=ttySIF0" +--- a/arch/riscv/configs/nommu_k210_sdcard_defconfig ++++ b/arch/riscv/configs/nommu_k210_sdcard_defconfig +@@ -21,8 +21,6 @@ CONFIG_EMBEDDED=y + CONFIG_SLOB=y + # CONFIG_MMU is not set + CONFIG_SOC_CANAAN=y +-CONFIG_SOC_CANAAN_K210_DTB_SOURCE="k210_generic" +-CONFIG_MAXPHYSMEM_2GB=y + CONFIG_SMP=y + CONFIG_NR_CPUS=2 + CONFIG_CMDLINE="earlycon console=ttySIF0 rootdelay=2 root=/dev/mmcblk0p1 ro" +--- a/arch/riscv/configs/nommu_virt_defconfig ++++ b/arch/riscv/configs/nommu_virt_defconfig +@@ -27,7 +27,6 @@ CONFIG_SLOB=y + # CONFIG_SLAB_MERGE_DEFAULT is not set + # CONFIG_MMU is not set + CONFIG_SOC_VIRT=y +-CONFIG_MAXPHYSMEM_2GB=y + CONFIG_SMP=y + CONFIG_CMDLINE="root=/dev/vda rw earlycon=uart8250,mmio,0x10000000,115200n8 console=ttyS0" + CONFIG_CMDLINE_FORCE=y diff --git a/queue-5.16/riscv-mm-fix-wrong-phys_ram_base-value-for-rv64.patch b/queue-5.16/riscv-mm-fix-wrong-phys_ram_base-value-for-rv64.patch new file mode 100644 index 00000000000..0e800157914 --- /dev/null +++ b/queue-5.16/riscv-mm-fix-wrong-phys_ram_base-value-for-rv64.patch @@ -0,0 +1,36 @@ +From b0fd4b1bf995172b9efcee23600d4f69571c321c Mon Sep 17 00:00:00 2001 +From: Jisheng Zhang +Date: Thu, 2 Dec 2021 23:36:41 +0800 +Subject: riscv: mm: fix wrong phys_ram_base value for RV64 + +From: Jisheng Zhang + +commit b0fd4b1bf995172b9efcee23600d4f69571c321c upstream. + +Currently, if 64BIT and !XIP_KERNEL, the phys_ram_base is always 0, +no matter the real start of dram reported by memblock is. + +Fixes: 6d7f91d914bc ("riscv: Get rid of CONFIG_PHYS_RAM_BASE in kernel physical address conversion") +Signed-off-by: Jisheng Zhang +Reviewed-by: Alexandre Ghiti +Cc: stable@vger.kernel.org +Signed-off-by: Palmer Dabbelt +Signed-off-by: Greg Kroah-Hartman +--- + arch/riscv/mm/init.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/riscv/mm/init.c ++++ b/arch/riscv/mm/init.c +@@ -187,10 +187,10 @@ static void __init setup_bootmem(void) + + + phys_ram_end = memblock_end_of_DRAM(); +-#ifndef CONFIG_64BIT + #ifndef CONFIG_XIP_KERNEL + phys_ram_base = memblock_start_of_DRAM(); + #endif ++#ifndef CONFIG_64BIT + /* + * memblock allocator is not aware of the fact that last 4K bytes of + * the addressable memory can not be mapped because of IS_ERR_VALUE diff --git a/queue-5.16/riscv-try-to-allocate-crashkern-region-from-32bit-addressible-memory.patch b/queue-5.16/riscv-try-to-allocate-crashkern-region-from-32bit-addressible-memory.patch new file mode 100644 index 00000000000..e98e061051b --- /dev/null +++ b/queue-5.16/riscv-try-to-allocate-crashkern-region-from-32bit-addressible-memory.patch @@ -0,0 +1,62 @@ +From decf89f86ecd3c3c3de81c562010d5797bea3de1 Mon Sep 17 00:00:00 2001 +From: Nick Kossifidis +Date: Fri, 26 Nov 2021 20:04:11 +0200 +Subject: riscv: try to allocate crashkern region from 32bit addressible memory + +From: Nick Kossifidis + +commit decf89f86ecd3c3c3de81c562010d5797bea3de1 upstream. + +When allocating crash kernel region without explicitly specifying its +base address/size, memblock_phys_alloc_range will attempt to allocate +memory top to bottom (memblock.bottom_up is false), so the crash +kernel region will end up in highmem on 64bit systems. This way +swiotlb can't work on the crash kernel, since there won't be any +32bit addressible memory available for the bounce buffers. + +Try to allocate 32bit addressible memory if available, for the +crash kernel by restricting the top search address to be less +than SZ_4G. If that fails fallback to the previous behavior. + +I tested this on HiFive Unmatched where the pci-e controller needs +swiotlb to work, with this patch it's possible to access the pci-e +controller on crash kernel and mount the rootfs from the nvme. + +Signed-off-by: Nick Kossifidis +Fixes: e53d28180d4d ("RISC-V: Add kdump support") +Cc: stable@vger.kernel.org +Signed-off-by: Palmer Dabbelt +Signed-off-by: Greg Kroah-Hartman +--- + arch/riscv/mm/init.c | 17 +++++++++++++---- + 1 file changed, 13 insertions(+), 4 deletions(-) + +--- a/arch/riscv/mm/init.c ++++ b/arch/riscv/mm/init.c +@@ -812,13 +812,22 @@ static void __init reserve_crashkernel(v + /* + * Current riscv boot protocol requires 2MB alignment for + * RV64 and 4MB alignment for RV32 (hugepage size) ++ * ++ * Try to alloc from 32bit addressible physical memory so that ++ * swiotlb can work on the crash kernel. + */ + crash_base = memblock_phys_alloc_range(crash_size, PMD_SIZE, +- search_start, search_end); ++ search_start, ++ min(search_end, (unsigned long) SZ_4G)); + if (crash_base == 0) { +- pr_warn("crashkernel: couldn't allocate %lldKB\n", +- crash_size >> 10); +- return; ++ /* Try again without restricting region to 32bit addressible memory */ ++ crash_base = memblock_phys_alloc_range(crash_size, PMD_SIZE, ++ search_start, search_end); ++ if (crash_base == 0) { ++ pr_warn("crashkernel: couldn't allocate %lldKB\n", ++ crash_size >> 10); ++ return; ++ } + } + + pr_info("crashkernel: reserved 0x%016llx - 0x%016llx (%lld MB)\n", diff --git a/queue-5.16/riscv-use-hart-id-instead-of-cpu-id-on-machine_kexec.patch b/queue-5.16/riscv-use-hart-id-instead-of-cpu-id-on-machine_kexec.patch new file mode 100644 index 00000000000..799c63aaa2e --- /dev/null +++ b/queue-5.16/riscv-use-hart-id-instead-of-cpu-id-on-machine_kexec.patch @@ -0,0 +1,36 @@ +From 0e105f1d0037d677dff3c697d22f9551e6c39af8 Mon Sep 17 00:00:00 2001 +From: Nick Kossifidis +Date: Fri, 26 Nov 2021 20:04:10 +0200 +Subject: riscv: use hart id instead of cpu id on machine_kexec + +From: Nick Kossifidis + +commit 0e105f1d0037d677dff3c697d22f9551e6c39af8 upstream. + +raw_smp_processor_id() doesn't return the hart id as stated in +arch/riscv/include/asm/smp.h, use smp_processor_id() instead +to get the cpu id, and cpuid_to_hartid_map() to pass the hart id +to the next kernel. This fixes kexec on HiFive Unleashed/Unmatched +where cpu ids and hart ids don't match (on qemu-virt they match). + +Fixes: fba8a8674f68 ("RISC-V: Add kexec support") +Signed-off-by: Nick Kossifidis +Cc: stable@vger.kernel.org +Signed-off-by: Palmer Dabbelt +Signed-off-by: Greg Kroah-Hartman +--- + arch/riscv/kernel/machine_kexec.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/arch/riscv/kernel/machine_kexec.c ++++ b/arch/riscv/kernel/machine_kexec.c +@@ -169,7 +169,8 @@ machine_kexec(struct kimage *image) + struct kimage_arch *internal = &image->arch; + unsigned long jump_addr = (unsigned long) image->start; + unsigned long first_ind_entry = (unsigned long) &image->head; +- unsigned long this_hart_id = raw_smp_processor_id(); ++ unsigned long this_cpu_id = smp_processor_id(); ++ unsigned long this_hart_id = cpuid_to_hartid_map(this_cpu_id); + unsigned long fdt_addr = internal->fdt_addr; + void *control_code_buffer = page_address(image->control_code_page); + riscv_kexec_method kexec_method = NULL; diff --git a/queue-5.16/rtc-cmos-take-rtc_lock-while-reading-from-cmos.patch b/queue-5.16/rtc-cmos-take-rtc_lock-while-reading-from-cmos.patch new file mode 100644 index 00000000000..fb0b63f28f0 --- /dev/null +++ b/queue-5.16/rtc-cmos-take-rtc_lock-while-reading-from-cmos.patch @@ -0,0 +1,49 @@ +From 454f47ff464325223129b9b5b8d0b61946ec704d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Mateusz=20Jo=C5=84czyk?= +Date: Fri, 10 Dec 2021 21:01:23 +0100 +Subject: rtc: cmos: take rtc_lock while reading from CMOS +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Mateusz Jończyk + +commit 454f47ff464325223129b9b5b8d0b61946ec704d upstream. + +Reading from the CMOS involves writing to the index register and then +reading from the data register. Therefore access to the CMOS has to be +serialized with rtc_lock. This invocation of CMOS_READ was not +serialized, which could cause trouble when other code is accessing CMOS +at the same time. + +Use spin_lock_irq() like the rest of the function. + +Nothing in kernel modifies the RTC_DM_BINARY bit, so there could be a +separate pair of spin_lock_irq() / spin_unlock_irq() before doing the +math. + +Signed-off-by: Mateusz Jończyk +Reviewed-by: Nobuhiro Iwamatsu +Cc: Alessandro Zummo +Cc: Alexandre Belloni +Cc: stable@vger.kernel.org +Signed-off-by: Alexandre Belloni +Link: https://lore.kernel.org/r/20211210200131.153887-2-mat.jonczyk@o2.pl +Signed-off-by: Greg Kroah-Hartman +--- + drivers/rtc/rtc-cmos.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/rtc/rtc-cmos.c ++++ b/drivers/rtc/rtc-cmos.c +@@ -457,7 +457,10 @@ static int cmos_set_alarm(struct device + min = t->time.tm_min; + sec = t->time.tm_sec; + ++ spin_lock_irq(&rtc_lock); + rtc_control = CMOS_READ(RTC_CONTROL); ++ spin_unlock_irq(&rtc_lock); ++ + if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { + /* Writing 0xff means "don't care" or "match all". */ + mon = (mon <= 12) ? bin2bcd(mon) : 0xff; diff --git a/queue-5.16/series b/queue-5.16/series index 6c5c37ac442..11cf5b1736c 100644 --- a/queue-5.16/series +++ b/queue-5.16/series @@ -15,3 +15,68 @@ nfc-llcp-fix-null-error-pointer-dereference-on-sendmsg-after-failed-bind.patch mtd-rawnand-gpmi-add-err007117-protection-for-nfc_apply_timings.patch mtd-rawnand-gpmi-remove-explicit-default-gpmi-clock-setting-for-i.mx6.patch mtd-fixed-breaking-list-in-__mtd_del_partition.patch +mtd-rawnand-davinci-don-t-calculate-ecc-when-reading-page.patch +mtd-rawnand-davinci-avoid-duplicated-page-read.patch +mtd-rawnand-davinci-rewrite-function-description.patch +mtd-rawnand-export-nand_read_page_hwecc_oob_first.patch +mtd-rawnand-ingenic-jz4740-needs-oob_first-read-page-function.patch +riscv-get-rid-of-maxphysmem-configs.patch +risc-v-use-common-riscv_cpuid_to_hartid_mask-for-both-smp-y-and-smp-n.patch +riscv-try-to-allocate-crashkern-region-from-32bit-addressible-memory.patch +riscv-don-t-use-va_pa_offset-on-kdump.patch +riscv-use-hart-id-instead-of-cpu-id-on-machine_kexec.patch +riscv-mm-fix-wrong-phys_ram_base-value-for-rv64.patch +x86-gpu-reserve-stolen-memory-for-first-integrated-intel-gpu.patch +tools-nolibc-x86-64-fix-startup-code-bug.patch +crypto-x86-aesni-don-t-require-alignment-of-data.patch +tools-nolibc-i386-fix-initial-stack-alignment.patch +tools-nolibc-fix-incorrect-truncation-of-exit-code.patch +rtc-cmos-take-rtc_lock-while-reading-from-cmos.patch +net-phy-marvell-add-marvell-specific-phy-loopback.patch +ksmbd-uninitialized-variable-in-create_socket.patch +ksmbd-fix-guest-connection-failure-with-nautilus.patch +ksmbd-add-support-for-smb2-max-credit-parameter.patch +ksmbd-move-credit-charge-deduction-under-processing-request.patch +ksmbd-limits-exceeding-the-maximum-allowable-outstanding-requests.patch +ksmbd-add-reserved-room-in-ipc-request-response.patch +media-cec-fix-a-deadlock-situation.patch +media-ov8865-disable-only-enabled-regulators-on-error-path.patch +media-v4l2-ioctl.c-readbuffers-depends-on-v4l2_cap_readwrite.patch +media-flexcop-usb-fix-control-message-timeouts.patch +media-mceusb-fix-control-message-timeouts.patch +media-em28xx-fix-control-message-timeouts.patch +media-cpia2-fix-control-message-timeouts.patch +media-s2255-fix-control-message-timeouts.patch +media-dib0700-fix-undefined-behavior-in-tuner-shutdown.patch +media-redrat3-fix-control-message-timeouts.patch +media-pvrusb2-fix-control-message-timeouts.patch +media-stk1160-fix-control-message-timeouts.patch +media-cec-pin-fix-interrupt-en-disable-handling.patch +can-softing_cs-softingcs_probe-fix-memleak-on-registration-failure.patch +mei-hbm-fix-client-dma-reply-status.patch +iio-adc-ti-adc081c-partial-revert-of-removal-of-acpi-ids.patch +iio-trigger-fix-a-scheduling-whilst-atomic-issue-seen-on-tsc2046.patch +lkdtm-fix-content-of-section-containing-lkdtm_rodata_do_nothing.patch +bus-mhi-pci_generic-graceful-shutdown-on-freeze.patch +bus-mhi-core-fix-reading-wake_capable-channel-configuration.patch +bus-mhi-core-fix-race-while-handling-sys_err-at-power-up.patch +cxl-pmem-fix-reference-counting-for-delayed-work.patch +cxl-pmem-fix-module-reload-vs-workqueue-state.patch +thermal-drivers-int340x-fix-rfim-mailbox-write-commands.patch +arm64-errata-fix-exec-handling-in-erratum-1418040-workaround.patch +arm-dts-at91-update-alternate-function-of-signal-pd20.patch +iommu-io-pgtable-arm-v7s-add-error-handle-for-page-table-allocation-failure.patch +gpu-host1x-add-back-arm_iommu_detach_device.patch +drm-tegra-add-back-arm_iommu_detach_device.patch +io_uring-fix-no-lock-protection-for-ctx-cq_extra.patch +virtio-virtio_mem-handle-a-possible-null-as-a-memcpy-parameter.patch +dma_fence_array-fix-pending_error-leak-in-dma_fence_array_signaled.patch +pci-add-function-1-dma-alias-quirk-for-marvell-88se9125-sata-controller.patch +mm_zone-add-function-to-check-if-managed-dma-zone-exists.patch +dma-pool-create-dma-atomic-pool-only-if-dma-zone-has-managed-pages.patch +mm-page_alloc.c-do-not-warn-allocation-failure-on-zone-dma-if-no-managed-pages.patch +ath11k-add-string-type-to-search-board-data-in-board-2.bin-for-wcn6855.patch +shmem-fix-a-race-between-shmem_unused_huge_shrink-and-shmem_evict_inode.patch +drm-rockchip-dsi-hold-pm-runtime-across-bind-unbind.patch +drm-rockchip-dsi-reconfigure-hardware-on-resume.patch +drm-ttm-put-bo-in-its-memory-manager-s-lru-list.patch diff --git a/queue-5.16/shmem-fix-a-race-between-shmem_unused_huge_shrink-and-shmem_evict_inode.patch b/queue-5.16/shmem-fix-a-race-between-shmem_unused_huge_shrink-and-shmem_evict_inode.patch new file mode 100644 index 00000000000..1d7c9a4d4ac --- /dev/null +++ b/queue-5.16/shmem-fix-a-race-between-shmem_unused_huge_shrink-and-shmem_evict_inode.patch @@ -0,0 +1,172 @@ +From 62c9827cbb996c2c04f615ecd783ce28bcea894b Mon Sep 17 00:00:00 2001 +From: Gang Li +Date: Fri, 14 Jan 2022 14:05:23 -0800 +Subject: shmem: fix a race between shmem_unused_huge_shrink and shmem_evict_inode + +From: Gang Li + +commit 62c9827cbb996c2c04f615ecd783ce28bcea894b upstream. + +Fix a data race in commit 779750d20b93 ("shmem: split huge pages beyond +i_size under memory pressure"). + +Here are call traces causing race: + + Call Trace 1: + shmem_unused_huge_shrink+0x3ae/0x410 + ? __list_lru_walk_one.isra.5+0x33/0x160 + super_cache_scan+0x17c/0x190 + shrink_slab.part.55+0x1ef/0x3f0 + shrink_node+0x10e/0x330 + kswapd+0x380/0x740 + kthread+0xfc/0x130 + ? mem_cgroup_shrink_node+0x170/0x170 + ? kthread_create_on_node+0x70/0x70 + ret_from_fork+0x1f/0x30 + + Call Trace 2: + shmem_evict_inode+0xd8/0x190 + evict+0xbe/0x1c0 + do_unlinkat+0x137/0x330 + do_syscall_64+0x76/0x120 + entry_SYSCALL_64_after_hwframe+0x3d/0xa2 + +A simple explanation: + +Image there are 3 items in the local list (@list). In the first +traversal, A is not deleted from @list. + + 1) A->B->C + ^ + | + pos (leave) + +In the second traversal, B is deleted from @list. Concurrently, A is +deleted from @list through shmem_evict_inode() since last reference +counter of inode is dropped by other thread. Then the @list is corrupted. + + 2) A->B->C + ^ ^ + | | + evict pos (drop) + +We should make sure the inode is either on the global list or deleted from +any local list before iput(). + +Fixed by moving inodes back to global list before we put them. + +[akpm@linux-foundation.org: coding style fixes] + +Link: https://lkml.kernel.org/r/20211125064502.99983-1-ligang.bdlg@bytedance.com +Fixes: 779750d20b93 ("shmem: split huge pages beyond i_size under memory pressure") +Signed-off-by: Gang Li +Reviewed-by: Muchun Song +Acked-by: Kirill A. Shutemov +Cc: Hugh Dickins +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman +--- + mm/shmem.c | 37 +++++++++++++++++++++---------------- + 1 file changed, 21 insertions(+), 16 deletions(-) + +--- a/mm/shmem.c ++++ b/mm/shmem.c +@@ -554,7 +554,7 @@ static unsigned long shmem_unused_huge_s + struct shmem_inode_info *info; + struct page *page; + unsigned long batch = sc ? sc->nr_to_scan : 128; +- int removed = 0, split = 0; ++ int split = 0; + + if (list_empty(&sbinfo->shrinklist)) + return SHRINK_STOP; +@@ -569,7 +569,6 @@ static unsigned long shmem_unused_huge_s + /* inode is about to be evicted */ + if (!inode) { + list_del_init(&info->shrinklist); +- removed++; + goto next; + } + +@@ -577,12 +576,12 @@ static unsigned long shmem_unused_huge_s + if (round_up(inode->i_size, PAGE_SIZE) == + round_up(inode->i_size, HPAGE_PMD_SIZE)) { + list_move(&info->shrinklist, &to_remove); +- removed++; + goto next; + } + + list_move(&info->shrinklist, &list); + next: ++ sbinfo->shrinklist_len--; + if (!--batch) + break; + } +@@ -602,7 +601,7 @@ next: + inode = &info->vfs_inode; + + if (nr_to_split && split >= nr_to_split) +- goto leave; ++ goto move_back; + + page = find_get_page(inode->i_mapping, + (inode->i_size & HPAGE_PMD_MASK) >> PAGE_SHIFT); +@@ -616,38 +615,44 @@ next: + } + + /* +- * Leave the inode on the list if we failed to lock +- * the page at this time. ++ * Move the inode on the list back to shrinklist if we failed ++ * to lock the page at this time. + * + * Waiting for the lock may lead to deadlock in the + * reclaim path. + */ + if (!trylock_page(page)) { + put_page(page); +- goto leave; ++ goto move_back; + } + + ret = split_huge_page(page); + unlock_page(page); + put_page(page); + +- /* If split failed leave the inode on the list */ ++ /* If split failed move the inode on the list back to shrinklist */ + if (ret) +- goto leave; ++ goto move_back; + + split++; + drop: + list_del_init(&info->shrinklist); +- removed++; +-leave: ++ goto put; ++move_back: ++ /* ++ * Make sure the inode is either on the global list or deleted ++ * from any local list before iput() since it could be deleted ++ * in another thread once we put the inode (then the local list ++ * is corrupted). ++ */ ++ spin_lock(&sbinfo->shrinklist_lock); ++ list_move(&info->shrinklist, &sbinfo->shrinklist); ++ sbinfo->shrinklist_len++; ++ spin_unlock(&sbinfo->shrinklist_lock); ++put: + iput(inode); + } + +- spin_lock(&sbinfo->shrinklist_lock); +- list_splice_tail(&list, &sbinfo->shrinklist); +- sbinfo->shrinklist_len -= removed; +- spin_unlock(&sbinfo->shrinklist_lock); +- + return split; + } + diff --git a/queue-5.16/thermal-drivers-int340x-fix-rfim-mailbox-write-commands.patch b/queue-5.16/thermal-drivers-int340x-fix-rfim-mailbox-write-commands.patch new file mode 100644 index 00000000000..aa57087b690 --- /dev/null +++ b/queue-5.16/thermal-drivers-int340x-fix-rfim-mailbox-write-commands.patch @@ -0,0 +1,298 @@ +From 2685c77b80a80c57e2a25a726b82fb31e6e212ab Mon Sep 17 00:00:00 2001 +From: Sumeet Pawnikar +Date: Thu, 23 Dec 2021 15:12:36 +0530 +Subject: thermal/drivers/int340x: Fix RFIM mailbox write commands + +From: Sumeet Pawnikar + +commit 2685c77b80a80c57e2a25a726b82fb31e6e212ab upstream. + +The existing mail mechanism only supports writing of workload types. + +However, mailbox command for RFIM (cmd = 0x08) also requires write +operation which is ignored. This results in failing to store RFI +restriction. + +Fixint this requires enhancing mailbox writes for non workload +commands too, so remove the check for MBOX_CMD_WORKLOAD_TYPE_WRITE +in mailbox write to allow this other write commands to be supoorted. + +At the same time, however, we have to make sure that there is no +impact on read commands, by avoiding to write anything into the +mailbox data register. + +To properly implement that, add two separate functions for mbox read +and write commands for the processor thermal workload command type. +This helps to distinguish the read and write workload command types +from each other while sending mbox commands. + +Fixes: 5d6fbc96bd36 ("thermal/drivers/int340x: processor_thermal: Export additional attributes") +Signed-off-by: Sumeet Pawnikar +Cc: 5.14+ # 5.14+ +Acked-by: Srinivas Pandruvada +[ rjw: Changelog edits ] +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman +--- + drivers/thermal/intel/int340x_thermal/processor_thermal_device.h | 3 + drivers/thermal/intel/int340x_thermal/processor_thermal_mbox.c | 100 +++++----- + drivers/thermal/intel/int340x_thermal/processor_thermal_rfim.c | 23 +- + 3 files changed, 73 insertions(+), 53 deletions(-) + +--- a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.h ++++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.h +@@ -80,7 +80,8 @@ void proc_thermal_rfim_remove(struct pci + int proc_thermal_mbox_add(struct pci_dev *pdev, struct proc_thermal_device *proc_priv); + void proc_thermal_mbox_remove(struct pci_dev *pdev); + +-int processor_thermal_send_mbox_cmd(struct pci_dev *pdev, u16 cmd_id, u32 cmd_data, u64 *cmd_resp); ++int processor_thermal_send_mbox_read_cmd(struct pci_dev *pdev, u16 id, u64 *resp); ++int processor_thermal_send_mbox_write_cmd(struct pci_dev *pdev, u16 id, u32 data); + int proc_thermal_add(struct device *dev, struct proc_thermal_device *priv); + void proc_thermal_remove(struct proc_thermal_device *proc_priv); + int proc_thermal_suspend(struct device *dev); +--- a/drivers/thermal/intel/int340x_thermal/processor_thermal_mbox.c ++++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_mbox.c +@@ -24,19 +24,15 @@ + + static DEFINE_MUTEX(mbox_lock); + +-static int send_mbox_cmd(struct pci_dev *pdev, u16 cmd_id, u32 cmd_data, u64 *cmd_resp) ++static int wait_for_mbox_ready(struct proc_thermal_device *proc_priv) + { +- struct proc_thermal_device *proc_priv; + u32 retries, data; + int ret; + +- mutex_lock(&mbox_lock); +- proc_priv = pci_get_drvdata(pdev); +- + /* Poll for rb bit == 0 */ + retries = MBOX_RETRY_COUNT; + do { +- data = readl((void __iomem *) (proc_priv->mmio_base + MBOX_OFFSET_INTERFACE)); ++ data = readl(proc_priv->mmio_base + MBOX_OFFSET_INTERFACE); + if (data & BIT_ULL(MBOX_BUSY_BIT)) { + ret = -EBUSY; + continue; +@@ -45,53 +41,78 @@ static int send_mbox_cmd(struct pci_dev + break; + } while (--retries); + ++ return ret; ++} ++ ++static int send_mbox_write_cmd(struct pci_dev *pdev, u16 id, u32 data) ++{ ++ struct proc_thermal_device *proc_priv; ++ u32 reg_data; ++ int ret; ++ ++ proc_priv = pci_get_drvdata(pdev); ++ ++ mutex_lock(&mbox_lock); ++ ++ ret = wait_for_mbox_ready(proc_priv); + if (ret) + goto unlock_mbox; + +- if (cmd_id == MBOX_CMD_WORKLOAD_TYPE_WRITE) +- writel(cmd_data, (void __iomem *) ((proc_priv->mmio_base + MBOX_OFFSET_DATA))); +- ++ writel(data, (proc_priv->mmio_base + MBOX_OFFSET_DATA)); + /* Write command register */ +- data = BIT_ULL(MBOX_BUSY_BIT) | cmd_id; +- writel(data, (void __iomem *) ((proc_priv->mmio_base + MBOX_OFFSET_INTERFACE))); ++ reg_data = BIT_ULL(MBOX_BUSY_BIT) | id; ++ writel(reg_data, (proc_priv->mmio_base + MBOX_OFFSET_INTERFACE)); + +- /* Poll for rb bit == 0 */ +- retries = MBOX_RETRY_COUNT; +- do { +- data = readl((void __iomem *) (proc_priv->mmio_base + MBOX_OFFSET_INTERFACE)); +- if (data & BIT_ULL(MBOX_BUSY_BIT)) { +- ret = -EBUSY; +- continue; +- } ++ ret = wait_for_mbox_ready(proc_priv); + +- if (data) { +- ret = -ENXIO; +- goto unlock_mbox; +- } ++unlock_mbox: ++ mutex_unlock(&mbox_lock); ++ return ret; ++} + +- ret = 0; ++static int send_mbox_read_cmd(struct pci_dev *pdev, u16 id, u64 *resp) ++{ ++ struct proc_thermal_device *proc_priv; ++ u32 reg_data; ++ int ret; + +- if (!cmd_resp) +- break; ++ proc_priv = pci_get_drvdata(pdev); + +- if (cmd_id == MBOX_CMD_WORKLOAD_TYPE_READ) +- *cmd_resp = readl((void __iomem *) (proc_priv->mmio_base + MBOX_OFFSET_DATA)); +- else +- *cmd_resp = readq((void __iomem *) (proc_priv->mmio_base + MBOX_OFFSET_DATA)); ++ mutex_lock(&mbox_lock); + +- break; +- } while (--retries); ++ ret = wait_for_mbox_ready(proc_priv); ++ if (ret) ++ goto unlock_mbox; ++ ++ /* Write command register */ ++ reg_data = BIT_ULL(MBOX_BUSY_BIT) | id; ++ writel(reg_data, (proc_priv->mmio_base + MBOX_OFFSET_INTERFACE)); ++ ++ ret = wait_for_mbox_ready(proc_priv); ++ if (ret) ++ goto unlock_mbox; ++ ++ if (id == MBOX_CMD_WORKLOAD_TYPE_READ) ++ *resp = readl(proc_priv->mmio_base + MBOX_OFFSET_DATA); ++ else ++ *resp = readq(proc_priv->mmio_base + MBOX_OFFSET_DATA); + + unlock_mbox: + mutex_unlock(&mbox_lock); + return ret; + } + +-int processor_thermal_send_mbox_cmd(struct pci_dev *pdev, u16 cmd_id, u32 cmd_data, u64 *cmd_resp) ++int processor_thermal_send_mbox_read_cmd(struct pci_dev *pdev, u16 id, u64 *resp) + { +- return send_mbox_cmd(pdev, cmd_id, cmd_data, cmd_resp); ++ return send_mbox_read_cmd(pdev, id, resp); + } +-EXPORT_SYMBOL_GPL(processor_thermal_send_mbox_cmd); ++EXPORT_SYMBOL_NS_GPL(processor_thermal_send_mbox_read_cmd, INT340X_THERMAL); ++ ++int processor_thermal_send_mbox_write_cmd(struct pci_dev *pdev, u16 id, u32 data) ++{ ++ return send_mbox_write_cmd(pdev, id, data); ++} ++EXPORT_SYMBOL_NS_GPL(processor_thermal_send_mbox_write_cmd, INT340X_THERMAL); + + /* List of workload types */ + static const char * const workload_types[] = { +@@ -104,7 +125,6 @@ static const char * const workload_types + NULL + }; + +- + static ssize_t workload_available_types_show(struct device *dev, + struct device_attribute *attr, + char *buf) +@@ -146,7 +166,7 @@ static ssize_t workload_type_store(struc + + data |= ret; + +- ret = send_mbox_cmd(pdev, MBOX_CMD_WORKLOAD_TYPE_WRITE, data, NULL); ++ ret = send_mbox_write_cmd(pdev, MBOX_CMD_WORKLOAD_TYPE_WRITE, data); + if (ret) + return false; + +@@ -161,7 +181,7 @@ static ssize_t workload_type_show(struct + u64 cmd_resp; + int ret; + +- ret = send_mbox_cmd(pdev, MBOX_CMD_WORKLOAD_TYPE_READ, 0, &cmd_resp); ++ ret = send_mbox_read_cmd(pdev, MBOX_CMD_WORKLOAD_TYPE_READ, &cmd_resp); + if (ret) + return false; + +@@ -186,8 +206,6 @@ static const struct attribute_group work + .name = "workload_request" + }; + +- +- + static bool workload_req_created; + + int proc_thermal_mbox_add(struct pci_dev *pdev, struct proc_thermal_device *proc_priv) +@@ -196,7 +214,7 @@ int proc_thermal_mbox_add(struct pci_dev + int ret; + + /* Check if there is a mailbox support, if fails return success */ +- ret = send_mbox_cmd(pdev, MBOX_CMD_WORKLOAD_TYPE_READ, 0, &cmd_resp); ++ ret = send_mbox_read_cmd(pdev, MBOX_CMD_WORKLOAD_TYPE_READ, &cmd_resp); + if (ret) + return 0; + +--- a/drivers/thermal/intel/int340x_thermal/processor_thermal_rfim.c ++++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_rfim.c +@@ -9,6 +9,8 @@ + #include + #include "processor_thermal_device.h" + ++MODULE_IMPORT_NS(INT340X_THERMAL); ++ + struct mmio_reg { + int read_only; + u32 offset; +@@ -194,8 +196,7 @@ static ssize_t rfi_restriction_store(str + struct device_attribute *attr, + const char *buf, size_t count) + { +- u16 cmd_id = 0x0008; +- u64 cmd_resp; ++ u16 id = 0x0008; + u32 input; + int ret; + +@@ -203,7 +204,7 @@ static ssize_t rfi_restriction_store(str + if (ret) + return ret; + +- ret = processor_thermal_send_mbox_cmd(to_pci_dev(dev), cmd_id, input, &cmd_resp); ++ ret = processor_thermal_send_mbox_write_cmd(to_pci_dev(dev), id, input); + if (ret) + return ret; + +@@ -214,30 +215,30 @@ static ssize_t rfi_restriction_show(stru + struct device_attribute *attr, + char *buf) + { +- u16 cmd_id = 0x0007; +- u64 cmd_resp; ++ u16 id = 0x0007; ++ u64 resp; + int ret; + +- ret = processor_thermal_send_mbox_cmd(to_pci_dev(dev), cmd_id, 0, &cmd_resp); ++ ret = processor_thermal_send_mbox_read_cmd(to_pci_dev(dev), id, &resp); + if (ret) + return ret; + +- return sprintf(buf, "%llu\n", cmd_resp); ++ return sprintf(buf, "%llu\n", resp); + } + + static ssize_t ddr_data_rate_show(struct device *dev, + struct device_attribute *attr, + char *buf) + { +- u16 cmd_id = 0x0107; +- u64 cmd_resp; ++ u16 id = 0x0107; ++ u64 resp; + int ret; + +- ret = processor_thermal_send_mbox_cmd(to_pci_dev(dev), cmd_id, 0, &cmd_resp); ++ ret = processor_thermal_send_mbox_read_cmd(to_pci_dev(dev), id, &resp); + if (ret) + return ret; + +- return sprintf(buf, "%llu\n", cmd_resp); ++ return sprintf(buf, "%llu\n", resp); + } + + static DEVICE_ATTR_RW(rfi_restriction); diff --git a/queue-5.16/tools-nolibc-fix-incorrect-truncation-of-exit-code.patch b/queue-5.16/tools-nolibc-fix-incorrect-truncation-of-exit-code.patch new file mode 100644 index 00000000000..f362408cbe4 --- /dev/null +++ b/queue-5.16/tools-nolibc-fix-incorrect-truncation-of-exit-code.patch @@ -0,0 +1,91 @@ +From de0244ae40ae91145faaf164a4252347607c3711 Mon Sep 17 00:00:00 2001 +From: Willy Tarreau +Date: Sun, 24 Oct 2021 19:28:16 +0200 +Subject: tools/nolibc: fix incorrect truncation of exit code + +From: Willy Tarreau + +commit de0244ae40ae91145faaf164a4252347607c3711 upstream. + +Ammar Faizi reported that our exit code handling is wrong. We truncate +it to the lowest 8 bits but the syscall itself is expected to take a +regular 32-bit signed integer, not an unsigned char. It's the kernel +that later truncates it to the lowest 8 bits. The difference is visible +in strace, where the program below used to show exit(255) instead of +exit(-1): + + int main(void) + { + return -1; + } + +This patch applies the fix to all archs. x86_64, i386, arm64, armv7 and +mips were all tested and confirmed to work fine now. Risc-v was not +tested but the change is trivial and exactly the same as for other archs. + +Reported-by: Ammar Faizi +Cc: stable@vger.kernel.org +Signed-off-by: Willy Tarreau +Signed-off-by: Paul E. McKenney +Signed-off-by: Greg Kroah-Hartman +--- + tools/include/nolibc/nolibc.h | 13 +++++-------- + 1 file changed, 5 insertions(+), 8 deletions(-) + +--- a/tools/include/nolibc/nolibc.h ++++ b/tools/include/nolibc/nolibc.h +@@ -414,7 +414,7 @@ asm(".section .text\n" + "xor %ebp, %ebp\n" // zero the stack frame + "and $-16, %rsp\n" // x86 ABI : esp must be 16-byte aligned before call + "call main\n" // main() returns the status code, we'll exit with it. +- "movzb %al, %rdi\n" // retrieve exit code from 8 lower bits ++ "mov %eax, %edi\n" // retrieve exit code (32 bit) + "mov $60, %rax\n" // NR_exit == 60 + "syscall\n" // really exit + "hlt\n" // ensure it does not return +@@ -602,9 +602,9 @@ asm(".section .text\n" + "push %ebx\n" // support both regparm and plain stack modes + "push %eax\n" + "call main\n" // main() returns the status code in %eax +- "movzbl %al, %ebx\n" // retrieve exit code from lower 8 bits +- "movl $1, %eax\n" // NR_exit == 1 +- "int $0x80\n" // exit now ++ "mov %eax, %ebx\n" // retrieve exit code (32-bit int) ++ "movl $1, %eax\n" // NR_exit == 1 ++ "int $0x80\n" // exit now + "hlt\n" // ensure it does not + ""); + +@@ -788,7 +788,6 @@ asm(".section .text\n" + "and %r3, %r1, $-8\n" // AAPCS : sp must be 8-byte aligned in the + "mov %sp, %r3\n" // callee, an bl doesn't push (lr=pc) + "bl main\n" // main() returns the status code, we'll exit with it. +- "and %r0, %r0, $0xff\n" // limit exit code to 8 bits + "movs r7, $1\n" // NR_exit == 1 + "svc $0x00\n" + ""); +@@ -985,7 +984,6 @@ asm(".section .text\n" + "add x2, x2, x1\n" // + argv + "and sp, x1, -16\n" // sp must be 16-byte aligned in the callee + "bl main\n" // main() returns the status code, we'll exit with it. +- "and x0, x0, 0xff\n" // limit exit code to 8 bits + "mov x8, 93\n" // NR_exit == 93 + "svc #0\n" + ""); +@@ -1190,7 +1188,7 @@ asm(".section .text\n" + "addiu $sp,$sp,-16\n" // the callee expects to save a0..a3 there! + "jal main\n" // main() returns the status code, we'll exit with it. + "nop\n" // delayed slot +- "and $a0, $v0, 0xff\n" // limit exit code to 8 bits ++ "move $a0, $v0\n" // retrieve 32-bit exit code from v0 + "li $v0, 4001\n" // NR_exit == 4001 + "syscall\n" + ".end __start\n" +@@ -1388,7 +1386,6 @@ asm(".section .text\n" + "add a2,a2,a1\n" // + argv + "andi sp,a1,-16\n" // sp must be 16-byte aligned + "call main\n" // main() returns the status code, we'll exit with it. +- "andi a0, a0, 0xff\n" // limit exit code to 8 bits + "li a7, 93\n" // NR_exit == 93 + "ecall\n" + ""); diff --git a/queue-5.16/tools-nolibc-i386-fix-initial-stack-alignment.patch b/queue-5.16/tools-nolibc-i386-fix-initial-stack-alignment.patch new file mode 100644 index 00000000000..c11bb526094 --- /dev/null +++ b/queue-5.16/tools-nolibc-i386-fix-initial-stack-alignment.patch @@ -0,0 +1,51 @@ +From ebbe0d8a449d183fa43b42d84fcb248e25303985 Mon Sep 17 00:00:00 2001 +From: Willy Tarreau +Date: Sun, 24 Oct 2021 19:28:15 +0200 +Subject: tools/nolibc: i386: fix initial stack alignment + +From: Willy Tarreau + +commit ebbe0d8a449d183fa43b42d84fcb248e25303985 upstream. + +After re-checking in the spec and comparing stack offsets with glibc, +The last pushed argument must be 16-byte aligned (i.e. aligned before the +call) so that in the callee esp+4 is multiple of 16, so the principle is +the 32-bit equivalent to what Ammar fixed for x86_64. It's possible that +32-bit code using SSE2 or MMX could have been affected. In addition the +frame pointer ought to be zero at the deepest level. + +Link: https://gitlab.com/x86-psABIs/i386-ABI/-/wikis/Intel386-psABI +Cc: Ammar Faizi +Cc: stable@vger.kernel.org +Signed-off-by: Willy Tarreau +Signed-off-by: Paul E. McKenney +Signed-off-by: Greg Kroah-Hartman +--- + tools/include/nolibc/nolibc.h | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +--- a/tools/include/nolibc/nolibc.h ++++ b/tools/include/nolibc/nolibc.h +@@ -583,13 +583,21 @@ struct sys_stat_struct { + }) + + /* startup code */ ++/* ++ * i386 System V ABI mandates: ++ * 1) last pushed argument must be 16-byte aligned. ++ * 2) The deepest stack frame should be set to zero ++ * ++ */ + asm(".section .text\n" + ".global _start\n" + "_start:\n" + "pop %eax\n" // argc (first arg, %eax) + "mov %esp, %ebx\n" // argv[] (second arg, %ebx) + "lea 4(%ebx,%eax,4),%ecx\n" // then a NULL then envp (third arg, %ecx) +- "and $-16, %esp\n" // x86 ABI : esp must be 16-byte aligned when ++ "xor %ebp, %ebp\n" // zero the stack frame ++ "and $-16, %esp\n" // x86 ABI : esp must be 16-byte aligned before ++ "sub $4, %esp\n" // the call instruction (args are aligned) + "push %ecx\n" // push all registers on the stack so that we + "push %ebx\n" // support both regparm and plain stack modes + "push %eax\n" diff --git a/queue-5.16/tools-nolibc-x86-64-fix-startup-code-bug.patch b/queue-5.16/tools-nolibc-x86-64-fix-startup-code-bug.patch new file mode 100644 index 00000000000..916dc77e18c --- /dev/null +++ b/queue-5.16/tools-nolibc-x86-64-fix-startup-code-bug.patch @@ -0,0 +1,97 @@ +From 937ed91c712273131de6d2a02caafd3ee84e0c72 Mon Sep 17 00:00:00 2001 +From: Ammar Faizi +Date: Sun, 24 Oct 2021 19:28:14 +0200 +Subject: tools/nolibc: x86-64: Fix startup code bug + +From: Ammar Faizi + +commit 937ed91c712273131de6d2a02caafd3ee84e0c72 upstream. + +Before this patch, the `_start` function looks like this: +``` +0000000000001170 <_start>: + 1170: pop %rdi + 1171: mov %rsp,%rsi + 1174: lea 0x8(%rsi,%rdi,8),%rdx + 1179: and $0xfffffffffffffff0,%rsp + 117d: sub $0x8,%rsp + 1181: call 1000
+ 1186: movzbq %al,%rdi + 118a: mov $0x3c,%rax + 1191: syscall + 1193: hlt + 1194: data16 cs nopw 0x0(%rax,%rax,1) + 119f: nop +``` +Note the "and" to %rsp with $-16, it makes the %rsp be 16-byte aligned, +but then there is a "sub" with $0x8 which makes the %rsp no longer +16-byte aligned, then it calls main. That's the bug! + +What actually the x86-64 System V ABI mandates is that right before the +"call", the %rsp must be 16-byte aligned, not after the "call". So the +"sub" with $0x8 here breaks the alignment. Remove it. + +An example where this rule matters is when the callee needs to align +its stack at 16-byte for aligned move instruction, like `movdqa` and +`movaps`. If the callee can't align its stack properly, it will result +in segmentation fault. + +x86-64 System V ABI also mandates the deepest stack frame should be +zero. Just to be safe, let's zero the %rbp on startup as the content +of %rbp may be unspecified when the program starts. Now it looks like +this: +``` +0000000000001170 <_start>: + 1170: pop %rdi + 1171: mov %rsp,%rsi + 1174: lea 0x8(%rsi,%rdi,8),%rdx + 1179: xor %ebp,%ebp # zero the %rbp + 117b: and $0xfffffffffffffff0,%rsp # align the %rsp + 117f: call 1000
+ 1184: movzbq %al,%rdi + 1188: mov $0x3c,%rax + 118f: syscall + 1191: hlt + 1192: data16 cs nopw 0x0(%rax,%rax,1) + 119d: nopl (%rax) +``` + +Cc: Bedirhan KURT +Cc: Louvian Lyndal +Reported-by: Peter Cordes +Signed-off-by: Ammar Faizi +[wt: I did this on purpose due to a misunderstanding of the spec, other + archs will thus have to be rechecked, particularly i386] +Cc: stable@vger.kernel.org +Signed-off-by: Willy Tarreau +Signed-off-by: Paul E. McKenney +Signed-off-by: Greg Kroah-Hartman +--- + tools/include/nolibc/nolibc.h | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +--- a/tools/include/nolibc/nolibc.h ++++ b/tools/include/nolibc/nolibc.h +@@ -399,14 +399,20 @@ struct stat { + }) + + /* startup code */ ++/* ++ * x86-64 System V ABI mandates: ++ * 1) %rsp must be 16-byte aligned right before the function call. ++ * 2) The deepest stack frame should be zero (the %rbp). ++ * ++ */ + asm(".section .text\n" + ".global _start\n" + "_start:\n" + "pop %rdi\n" // argc (first arg, %rdi) + "mov %rsp, %rsi\n" // argv[] (second arg, %rsi) + "lea 8(%rsi,%rdi,8),%rdx\n" // then a NULL then envp (third arg, %rdx) +- "and $-16, %rsp\n" // x86 ABI : esp must be 16-byte aligned when +- "sub $8, %rsp\n" // entering the callee ++ "xor %ebp, %ebp\n" // zero the stack frame ++ "and $-16, %rsp\n" // x86 ABI : esp must be 16-byte aligned before call + "call main\n" // main() returns the status code, we'll exit with it. + "movzb %al, %rdi\n" // retrieve exit code from 8 lower bits + "mov $60, %rax\n" // NR_exit == 60 diff --git a/queue-5.16/virtio-virtio_mem-handle-a-possible-null-as-a-memcpy-parameter.patch b/queue-5.16/virtio-virtio_mem-handle-a-possible-null-as-a-memcpy-parameter.patch new file mode 100644 index 00000000000..99d43e9f9c9 --- /dev/null +++ b/queue-5.16/virtio-virtio_mem-handle-a-possible-null-as-a-memcpy-parameter.patch @@ -0,0 +1,33 @@ +From cf4a4493ff70874f8af26d75d4346c591c298e89 Mon Sep 17 00:00:00 2001 +From: Peng Hao +Date: Wed, 22 Dec 2021 09:12:25 +0800 +Subject: virtio/virtio_mem: handle a possible NULL as a memcpy parameter + +From: Peng Hao + +commit cf4a4493ff70874f8af26d75d4346c591c298e89 upstream. + +There is a check for vm->sbm.sb_states before, and it should check +it here as well. + +Signed-off-by: Peng Hao +Link: https://lore.kernel.org/r/20211222011225.40573-1-flyingpeng@tencent.com +Signed-off-by: Michael S. Tsirkin +Fixes: 5f1f79bbc9e2 ("virtio-mem: Paravirtualized memory hotplug") +Cc: stable@vger.kernel.org # v5.8+ +Signed-off-by: Greg Kroah-Hartman +--- + drivers/virtio/virtio_mem.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/virtio/virtio_mem.c ++++ b/drivers/virtio/virtio_mem.c +@@ -592,7 +592,7 @@ static int virtio_mem_sbm_sb_states_prep + return -ENOMEM; + + mutex_lock(&vm->hotplug_mutex); +- if (new_bitmap) ++ if (vm->sbm.sb_states) + memcpy(new_bitmap, vm->sbm.sb_states, old_pages * PAGE_SIZE); + + old_bitmap = vm->sbm.sb_states; diff --git a/queue-5.16/x86-gpu-reserve-stolen-memory-for-first-integrated-intel-gpu.patch b/queue-5.16/x86-gpu-reserve-stolen-memory-for-first-integrated-intel-gpu.patch new file mode 100644 index 00000000000..26d93c6991a --- /dev/null +++ b/queue-5.16/x86-gpu-reserve-stolen-memory-for-first-integrated-intel-gpu.patch @@ -0,0 +1,76 @@ +From 9c494ca4d3a535f9ca11ad6af1813983c1c6cbdd Mon Sep 17 00:00:00 2001 +From: Lucas De Marchi +Date: Thu, 13 Jan 2022 16:28:39 -0800 +Subject: x86/gpu: Reserve stolen memory for first integrated Intel GPU + +From: Lucas De Marchi + +commit 9c494ca4d3a535f9ca11ad6af1813983c1c6cbdd upstream. + +"Stolen memory" is memory set aside for use by an Intel integrated GPU. +The intel_graphics_quirks() early quirk reserves this memory when it is +called for a GPU that appears in the intel_early_ids[] table of integrated +GPUs. + +Previously intel_graphics_quirks() was marked as QFLAG_APPLY_ONCE, so it +was called only for the first Intel GPU found. If a discrete GPU happened +to be enumerated first, intel_graphics_quirks() was called for it but not +for any integrated GPU found later. Therefore, stolen memory for such an +integrated GPU was never reserved. + +For example, this problem occurs in this Alderlake-P (integrated) + DG2 +(discrete) topology where the DG2 is found first, but stolen memory is +associated with the integrated GPU: + + - 00:01.0 Bridge + `- 03:00.0 DG2 discrete GPU + - 00:02.0 Integrated GPU (with stolen memory) + +Remove the QFLAG_APPLY_ONCE flag and call intel_graphics_quirks() for every +Intel GPU. Reserve stolen memory for the first GPU that appears in +intel_early_ids[]. + +[bhelgaas: commit log, add code comment, squash in +https://lore.kernel.org/r/20220118190558.2ququ4vdfjuahicm@ldmartin-desk2] +Link: https://lore.kernel.org/r/20220114002843.2083382-1-lucas.demarchi@intel.com +Signed-off-by: Lucas De Marchi +Signed-off-by: Bjorn Helgaas +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/kernel/early-quirks.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +--- a/arch/x86/kernel/early-quirks.c ++++ b/arch/x86/kernel/early-quirks.c +@@ -515,6 +515,7 @@ static const struct intel_early_ops gen1 + .stolen_size = gen9_stolen_size, + }; + ++/* Intel integrated GPUs for which we need to reserve "stolen memory" */ + static const struct pci_device_id intel_early_ids[] __initconst = { + INTEL_I830_IDS(&i830_early_ops), + INTEL_I845G_IDS(&i845_early_ops), +@@ -591,6 +592,13 @@ static void __init intel_graphics_quirks + u16 device; + int i; + ++ /* ++ * Reserve "stolen memory" for an integrated GPU. If we've already ++ * found one, there's nothing to do for other (discrete) GPUs. ++ */ ++ if (resource_size(&intel_graphics_stolen_res)) ++ return; ++ + device = read_pci_config_16(num, slot, func, PCI_DEVICE_ID); + + for (i = 0; i < ARRAY_SIZE(intel_early_ids); i++) { +@@ -703,7 +711,7 @@ static struct chipset early_qrk[] __init + { PCI_VENDOR_ID_INTEL, 0x3406, PCI_CLASS_BRIDGE_HOST, + PCI_BASE_CLASS_BRIDGE, 0, intel_remapping_check }, + { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA, PCI_ANY_ID, +- QFLAG_APPLY_ONCE, intel_graphics_quirks }, ++ 0, intel_graphics_quirks }, + /* + * HPET on the current version of the Baytrail platform has accuracy + * problems: it will halt in deep idle state - so we disable it.