From: Greg Kroah-Hartman Date: Wed, 7 Jun 2023 18:12:44 +0000 (+0200) Subject: 5.10-stable patches X-Git-Tag: v4.14.317~24 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f343fb1d0397255522000704d49b3f28036124b3;p=thirdparty%2Fkernel%2Fstable-queue.git 5.10-stable patches added patches: crypto-ccp-play-nice-with-vmalloc-d-memory-for-sev-command-structs.patch crypto-ccp-reject-sev-commands-with-mismatching-command-buffer.patch drm-rcar-stop-using-imply-for-dependencies.patch media-ti-vpe-cal-avoid-field_get-assertion.patch scsi-dpt_i2o-do-not-process-completions-with-invalid-addresses.patch scsi-dpt_i2o-remove-broken-pass-through-ioctl-i2ousercmd.patch tpm-tpm_tis-request-threaded-interrupt-handler.patch --- diff --git a/queue-5.10/crypto-ccp-play-nice-with-vmalloc-d-memory-for-sev-command-structs.patch b/queue-5.10/crypto-ccp-play-nice-with-vmalloc-d-memory-for-sev-command-structs.patch new file mode 100644 index 00000000000..fd0a0e975c0 --- /dev/null +++ b/queue-5.10/crypto-ccp-play-nice-with-vmalloc-d-memory-for-sev-command-structs.patch @@ -0,0 +1,124 @@ +From 8347b99473a313be6549a5b940bc3c56a71be81c Mon Sep 17 00:00:00 2001 +From: Sean Christopherson +Date: Tue, 6 Apr 2021 15:49:48 -0700 +Subject: crypto: ccp: Play nice with vmalloc'd memory for SEV command structs + +From: Sean Christopherson + +commit 8347b99473a313be6549a5b940bc3c56a71be81c upstream. + +Copy the incoming @data comman to an internal buffer so that callers can +put SEV command buffers on the stack without running afoul of +CONFIG_VMAP_STACK=y, i.e. without bombing on vmalloc'd pointers. As of +today, the largest supported command takes a 68 byte buffer, i.e. pretty +much every command can be put on the stack. Because sev_cmd_mutex is +held for the entirety of a transaction, only a single bounce buffer is +required. + +Use the internal buffer unconditionally, as the majority of in-kernel +users will soon switch to using the stack. At that point, checking +virt_addr_valid() becomes (negligible) overhead in most cases, and +supporting both paths slightly increases complexity. Since the commands +are all quite small, the cost of the copies is insignificant compared to +the latency of communicating with the PSP. + +Allocate a full page for the buffer as opportunistic preparation for +SEV-SNP, which requires the command buffer to be in firmware state for +commands that trigger memory writes from the PSP firmware. Using a full +page now will allow SEV-SNP support to simply transition the page as +needed. + +Cc: Brijesh Singh +Cc: Borislav Petkov +Cc: Tom Lendacky +Cc: Christophe Leroy +Signed-off-by: Sean Christopherson +Message-Id: <20210406224952.4177376-5-seanjc@google.com> +Reviewed-by: Brijesh Singh +Acked-by: Tom Lendacky +Signed-off-by: Paolo Bonzini +Cc: Ben Hutchings +Signed-off-by: Greg Kroah-Hartman +--- + drivers/crypto/ccp/sev-dev.c | 28 +++++++++++++++++++++++----- + drivers/crypto/ccp/sev-dev.h | 2 ++ + 2 files changed, 25 insertions(+), 5 deletions(-) + +--- a/drivers/crypto/ccp/sev-dev.c ++++ b/drivers/crypto/ccp/sev-dev.c +@@ -170,12 +170,17 @@ static int __sev_do_cmd_locked(int cmd, + if (WARN_ON_ONCE(!data != !buf_len)) + return -EINVAL; + +- if (data && WARN_ON_ONCE(!virt_addr_valid(data))) +- return -EINVAL; ++ /* ++ * Copy the incoming data to driver's scratch buffer as __pa() will not ++ * work for some memory, e.g. vmalloc'd addresses, and @data may not be ++ * physically contiguous. ++ */ ++ if (data) ++ memcpy(sev->cmd_buf, data, buf_len); + + /* Get the physical address of the command buffer */ +- phys_lsb = data ? lower_32_bits(__psp_pa(data)) : 0; +- phys_msb = data ? upper_32_bits(__psp_pa(data)) : 0; ++ phys_lsb = data ? lower_32_bits(__psp_pa(sev->cmd_buf)) : 0; ++ phys_msb = data ? upper_32_bits(__psp_pa(sev->cmd_buf)) : 0; + + dev_dbg(sev->dev, "sev command id %#x buffer 0x%08x%08x timeout %us\n", + cmd, phys_msb, phys_lsb, psp_timeout); +@@ -219,6 +224,13 @@ static int __sev_do_cmd_locked(int cmd, + print_hex_dump_debug("(out): ", DUMP_PREFIX_OFFSET, 16, 2, data, + buf_len, false); + ++ /* ++ * Copy potential output from the PSP back to data. Do this even on ++ * failure in case the caller wants to glean something from the error. ++ */ ++ if (data) ++ memcpy(data, sev->cmd_buf, buf_len); ++ + return ret; + } + +@@ -979,6 +991,10 @@ int sev_dev_init(struct psp_device *psp) + if (!sev) + goto e_err; + ++ sev->cmd_buf = (void *)devm_get_free_pages(dev, GFP_KERNEL, 0); ++ if (!sev->cmd_buf) ++ goto e_sev; ++ + psp->sev_data = sev; + + sev->dev = dev; +@@ -990,7 +1006,7 @@ int sev_dev_init(struct psp_device *psp) + if (!sev->vdata) { + ret = -ENODEV; + dev_err(dev, "sev: missing driver data\n"); +- goto e_sev; ++ goto e_buf; + } + + psp_set_sev_irq_handler(psp, sev_irq_handler, sev); +@@ -1005,6 +1021,8 @@ int sev_dev_init(struct psp_device *psp) + + e_irq: + psp_clear_sev_irq_handler(psp); ++e_buf: ++ devm_free_pages(dev, (unsigned long)sev->cmd_buf); + e_sev: + devm_kfree(dev, sev); + e_err: +--- a/drivers/crypto/ccp/sev-dev.h ++++ b/drivers/crypto/ccp/sev-dev.h +@@ -51,6 +51,8 @@ struct sev_device { + u8 api_major; + u8 api_minor; + u8 build; ++ ++ void *cmd_buf; + }; + + int sev_dev_init(struct psp_device *psp); diff --git a/queue-5.10/crypto-ccp-reject-sev-commands-with-mismatching-command-buffer.patch b/queue-5.10/crypto-ccp-reject-sev-commands-with-mismatching-command-buffer.patch new file mode 100644 index 00000000000..628265520a3 --- /dev/null +++ b/queue-5.10/crypto-ccp-reject-sev-commands-with-mismatching-command-buffer.patch @@ -0,0 +1,75 @@ +From d5760dee127bf6f390b05e747369d7c37ae1a7b8 Mon Sep 17 00:00:00 2001 +From: Sean Christopherson +Date: Tue, 6 Apr 2021 15:49:47 -0700 +Subject: crypto: ccp: Reject SEV commands with mismatching command buffer + +From: Sean Christopherson + +commit d5760dee127bf6f390b05e747369d7c37ae1a7b8 upstream. + +WARN on and reject SEV commands that provide a valid data pointer, but do +not have a known, non-zero length. And conversely, reject commands that +take a command buffer but none is provided (data is null). + +Aside from sanity checking input, disallowing a non-null pointer without +a non-zero size will allow a future patch to cleanly handle vmalloc'd +data by copying the data to an internal __pa() friendly buffer. + +Note, this also effectively prevents callers from using commands that +have a non-zero length and are not known to the kernel. This is not an +explicit goal, but arguably the side effect is a good thing from the +kernel's perspective. + +Cc: Brijesh Singh +Cc: Borislav Petkov +Cc: Tom Lendacky +Signed-off-by: Sean Christopherson +Message-Id: <20210406224952.4177376-4-seanjc@google.com> +Reviewed-by: Brijesh Singh +Acked-by: Tom Lendacky +Signed-off-by: Paolo Bonzini +Cc: Ben Hutchings +Signed-off-by: Greg Kroah-Hartman +--- + drivers/crypto/ccp/sev-dev.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +--- a/drivers/crypto/ccp/sev-dev.c ++++ b/drivers/crypto/ccp/sev-dev.c +@@ -156,6 +156,7 @@ static int __sev_do_cmd_locked(int cmd, + struct sev_device *sev; + unsigned int phys_lsb, phys_msb; + unsigned int reg, ret = 0; ++ int buf_len; + + if (!psp || !psp->sev_data) + return -ENODEV; +@@ -165,6 +166,10 @@ static int __sev_do_cmd_locked(int cmd, + + sev = psp->sev_data; + ++ buf_len = sev_cmd_buffer_len(cmd); ++ if (WARN_ON_ONCE(!data != !buf_len)) ++ return -EINVAL; ++ + if (data && WARN_ON_ONCE(!virt_addr_valid(data))) + return -EINVAL; + +@@ -176,7 +181,7 @@ static int __sev_do_cmd_locked(int cmd, + cmd, phys_msb, phys_lsb, psp_timeout); + + print_hex_dump_debug("(in): ", DUMP_PREFIX_OFFSET, 16, 2, data, +- sev_cmd_buffer_len(cmd), false); ++ buf_len, false); + + iowrite32(phys_lsb, sev->io_regs + sev->vdata->cmdbuff_addr_lo_reg); + iowrite32(phys_msb, sev->io_regs + sev->vdata->cmdbuff_addr_hi_reg); +@@ -212,7 +217,7 @@ static int __sev_do_cmd_locked(int cmd, + } + + print_hex_dump_debug("(out): ", DUMP_PREFIX_OFFSET, 16, 2, data, +- sev_cmd_buffer_len(cmd), false); ++ buf_len, false); + + return ret; + } diff --git a/queue-5.10/drm-rcar-stop-using-imply-for-dependencies.patch b/queue-5.10/drm-rcar-stop-using-imply-for-dependencies.patch new file mode 100644 index 00000000000..b6a7aec8591 --- /dev/null +++ b/queue-5.10/drm-rcar-stop-using-imply-for-dependencies.patch @@ -0,0 +1,98 @@ +From 42d95d1b3a9c649bf5ee881fee5938e00126479a Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Mon, 27 Sep 2021 16:26:23 +0200 +Subject: drm/rcar: stop using 'imply' for dependencies + +From: Arnd Bergmann + +commit 42d95d1b3a9c649bf5ee881fee5938e00126479a upstream. + +The meaning of the 'imply' keyword has changed recently, and neither the +old meaning (select the symbol if its dependencies are met) nor the new +meaning (enable it by default, but let the user set any other setting) +is what we want here. + +Work around this by adding two more Kconfig options that lead to +the correct behavior: if DRM_RCAR_USE_CMM and DRM_RCAR_USE_LVDS +are enabled, that portion of the driver becomes usable, and no +configuration results in a link error. + +This avoids a link failure: + +arm-linux-gnueabi-ld: drivers/gpu/drm/rcar-du/rcar_du_crtc.o: in function `rcar_du_crtc_atomic_begin': +rcar_du_crtc.c:(.text+0x1444): undefined reference to `rcar_cmm_setup' +arm-linux-gnueabi-ld: drivers/gpu/drm/rcar-du/rcar_du_crtc.o: in function `rcar_du_crtc_atomic_enable': +rcar_du_crtc.c:(.text+0x14d4): undefined reference to `rcar_cmm_enable' +arm-linux-gnueabi-ld: rcar_du_crtc.c:(.text+0x1548): undefined reference to `rcar_cmm_setup' +arm-linux-gnueabi-ld: drivers/gpu/drm/rcar-du/rcar_du_crtc.o: in function `rcar_du_crtc_atomic_disable': +rcar_du_crtc.c:(.text+0x18b8): undefined reference to `rcar_cmm_disable' +arm-linux-gnueabi-ld: drivers/gpu/drm/rcar-du/rcar_du_kms.o: in function `rcar_du_modeset_init': + +Link: https://lore.kernel.org/all/20200417155553.675905-5-arnd@arndb.de/ +Signed-off-by: Arnd Bergmann +Reviewed-by: Laurent Pinchart +Reviewed-by: Randy Dunlap +Signed-off-by: Laurent Pinchart +Cc: Dan Carpenter +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/rcar-du/Kconfig | 25 ++++++++++++++++--------- + 1 file changed, 16 insertions(+), 9 deletions(-) + +--- a/drivers/gpu/drm/rcar-du/Kconfig ++++ b/drivers/gpu/drm/rcar-du/Kconfig +@@ -4,8 +4,6 @@ config DRM_RCAR_DU + depends on DRM && OF + depends on ARM || ARM64 + depends on ARCH_RENESAS || COMPILE_TEST +- imply DRM_RCAR_CMM +- imply DRM_RCAR_LVDS + select DRM_KMS_HELPER + select DRM_KMS_CMA_HELPER + select DRM_GEM_CMA_HELPER +@@ -14,13 +12,17 @@ config DRM_RCAR_DU + Choose this option if you have an R-Car chipset. + If M is selected the module will be called rcar-du-drm. + +-config DRM_RCAR_CMM +- tristate "R-Car DU Color Management Module (CMM) Support" +- depends on DRM && OF ++config DRM_RCAR_USE_CMM ++ bool "R-Car DU Color Management Module (CMM) Support" + depends on DRM_RCAR_DU ++ default DRM_RCAR_DU + help + Enable support for R-Car Color Management Module (CMM). + ++config DRM_RCAR_CMM ++ def_tristate DRM_RCAR_DU ++ depends on DRM_RCAR_USE_CMM ++ + config DRM_RCAR_DW_HDMI + tristate "R-Car Gen3 and RZ/G2 DU HDMI Encoder Support" + depends on DRM && OF +@@ -28,15 +30,20 @@ config DRM_RCAR_DW_HDMI + help + Enable support for R-Car Gen3 or RZ/G2 internal HDMI encoder. + ++config DRM_RCAR_USE_LVDS ++ bool "R-Car DU LVDS Encoder Support" ++ depends on DRM_BRIDGE && OF ++ default DRM_RCAR_DU ++ help ++ Enable support for the R-Car Display Unit embedded LVDS encoders. ++ + config DRM_RCAR_LVDS +- tristate "R-Car DU LVDS Encoder Support" +- depends on DRM && DRM_BRIDGE && OF ++ def_tristate DRM_RCAR_DU ++ depends on DRM_RCAR_USE_LVDS + select DRM_KMS_HELPER + select DRM_PANEL + select OF_FLATTREE + select OF_OVERLAY +- help +- Enable support for the R-Car Display Unit embedded LVDS encoders. + + config DRM_RCAR_VSP + bool "R-Car DU VSP Compositor Support" if ARM diff --git a/queue-5.10/media-ti-vpe-cal-avoid-field_get-assertion.patch b/queue-5.10/media-ti-vpe-cal-avoid-field_get-assertion.patch new file mode 100644 index 00000000000..0a3c11cbb52 --- /dev/null +++ b/queue-5.10/media-ti-vpe-cal-avoid-field_get-assertion.patch @@ -0,0 +1,45 @@ +From d7a7d721064c548042b019cd0d4d62e0bb878d71 Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Fri, 4 Dec 2020 00:07:30 +0100 +Subject: media: ti-vpe: cal: avoid FIELD_GET assertion + +From: Arnd Bergmann + +commit d7a7d721064c548042b019cd0d4d62e0bb878d71 upstream. + +FIELD_GET() must only be used with a mask that is a compile-time +constant: + +drivers/media/platform/ti-vpe/cal.h: In function 'cal_read_field': +include/linux/compiler_types.h:320:38: error: call to '__compiletime_assert_247' declared with attribute error: FIELD_GET: mask is not constant +include/linux/bitfield.h:46:3: note: in expansion of macro 'BUILD_BUG_ON_MSG' + 46 | BUILD_BUG_ON_MSG(!__builtin_constant_p(_mask), \ + | ^~~~~~~~~~~~~~~~ +drivers/media/platform/ti-vpe/cal.h:220:9: note: in expansion of macro 'FIELD_GET' + 220 | return FIELD_GET(mask, cal_read(cal, offset)); + | ^~~~~~~~~ + +The problem here is that the function is not always inlined. Mark it +__always_inline to avoid the problem. + +Signed-off-by: Arnd Bergmann +Reviewed-by: Laurent Pinchart +Signed-off-by: Hans Verkuil +Signed-off-by: Mauro Carvalho Chehab +Cc: Dan Carpenter +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/platform/ti-vpe/cal.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/media/platform/ti-vpe/cal.h ++++ b/drivers/media/platform/ti-vpe/cal.h +@@ -215,7 +215,7 @@ static inline void cal_write(struct cal_ + iowrite32(val, cal->base + offset); + } + +-static inline u32 cal_read_field(struct cal_dev *cal, u32 offset, u32 mask) ++static __always_inline u32 cal_read_field(struct cal_dev *cal, u32 offset, u32 mask) + { + return FIELD_GET(mask, cal_read(cal, offset)); + } diff --git a/queue-5.10/scsi-dpt_i2o-do-not-process-completions-with-invalid-addresses.patch b/queue-5.10/scsi-dpt_i2o-do-not-process-completions-with-invalid-addresses.patch new file mode 100644 index 00000000000..5ee71afa880 --- /dev/null +++ b/queue-5.10/scsi-dpt_i2o-do-not-process-completions-with-invalid-addresses.patch @@ -0,0 +1,59 @@ +From 157298ea77a54f7793b370cb8cdfa967811adb66 Mon Sep 17 00:00:00 2001 +From: Ben Hutchings +Date: Sat, 27 May 2023 15:52:48 +0200 +Subject: scsi: dpt_i2o: Do not process completions with invalid addresses + +From: Ben Hutchings + +adpt_isr() reads reply addresses from a hardware register, which +should always be within the DMA address range of the device's pool of +reply address buffers. In case the address is out of range, it tries +to muddle on, converting to a virtual address using bus_to_virt(). + +bus_to_virt() does not take DMA addresses, and it doesn't make sense +to try to handle the completion in this case. Ignore it and continue +looping to service the interrupt. If a completion has been lost then +the SCSI core should eventually time-out and trigger a reset. + +There is no corresponding upstream commit, because this driver was +removed upstream. + +Fixes: 67af2b060e02 ("[SCSI] dpt_i2o: move from virt_to_bus/bus_to_virt ...") +Signed-off-by: Ben Hutchings +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/Kconfig | 2 +- + drivers/scsi/dpt_i2o.c | 4 ++-- + 2 files changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/scsi/Kconfig ++++ b/drivers/scsi/Kconfig +@@ -444,7 +444,7 @@ config SCSI_MVUMI + + config SCSI_DPT_I2O + tristate "Adaptec I2O RAID support " +- depends on SCSI && PCI && VIRT_TO_BUS ++ depends on SCSI && PCI + help + This driver supports all of Adaptec's I2O based RAID controllers as + well as the DPT SmartRaid V cards. This is an Adaptec maintained +--- a/drivers/scsi/dpt_i2o.c ++++ b/drivers/scsi/dpt_i2o.c +@@ -56,7 +56,7 @@ MODULE_DESCRIPTION("Adaptec I2O RAID Dri + #include + + #include /* for boot_cpu_data */ +-#include /* for virt_to_bus, etc. */ ++#include + + #include + #include +@@ -1865,7 +1865,7 @@ static irqreturn_t adpt_isr(int irq, voi + } else { + /* Ick, we should *never* be here */ + printk(KERN_ERR "dpti: reply frame not from pool\n"); +- reply = (u8 *)bus_to_virt(m); ++ continue; + } + + if (readl(reply) & MSG_FAIL) { diff --git a/queue-5.10/scsi-dpt_i2o-remove-broken-pass-through-ioctl-i2ousercmd.patch b/queue-5.10/scsi-dpt_i2o-remove-broken-pass-through-ioctl-i2ousercmd.patch new file mode 100644 index 00000000000..31bdab6900b --- /dev/null +++ b/queue-5.10/scsi-dpt_i2o-remove-broken-pass-through-ioctl-i2ousercmd.patch @@ -0,0 +1,360 @@ +From f4b327796d84579bea47fdaaaba2c9900b881237 Mon Sep 17 00:00:00 2001 +From: Ben Hutchings +Date: Sat, 27 May 2023 15:34:30 +0200 +Subject: scsi: dpt_i2o: Remove broken pass-through ioctl (I2OUSERCMD) + +From: Ben Hutchings + +adpt_i2o_passthru() takes a user-provided message and passes it +through to the hardware with appropriate translation of addresses +and message IDs. It has a number of bugs: + +- When a message requires scatter/gather, it doesn't verify that the + offset to the scatter/gather list is less than the message size. +- When a message requires scatter/gather, it overwrites the DMA + addresses with the user-space virtual addresses before unmapping the + DMA buffers. +- It reads the message from user memory multiple times. This allows + user-space to change the message and bypass validation. +- It assumes that the message is at least 4 words long, but doesn't + check that. + +I tried fixing these, but even the maintainer of the corresponding +user-space in Debian doesn't have the hardware any more. + +Instead, remove the pass-through ioctl (I2OUSRCMD) and supporting +code. + +There is no corresponding upstream commit, because this driver was +removed upstream. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Fixes: 67af2b060e02 ("[SCSI] dpt_i2o: move from virt_to_bus/bus_to_virt ...") +Signed-off-by: Ben Hutchings +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/dpt_i2o.c | 274 +------------------------------------------------ + drivers/scsi/dpti.h | 1 + 2 files changed, 8 insertions(+), 267 deletions(-) + +--- a/drivers/scsi/dpt_i2o.c ++++ b/drivers/scsi/dpt_i2o.c +@@ -582,51 +582,6 @@ static int adpt_show_info(struct seq_fil + return 0; + } + +-/* +- * Turn a pointer to ioctl reply data into an u32 'context' +- */ +-static u32 adpt_ioctl_to_context(adpt_hba * pHba, void *reply) +-{ +-#if BITS_PER_LONG == 32 +- return (u32)(unsigned long)reply; +-#else +- ulong flags = 0; +- u32 nr, i; +- +- spin_lock_irqsave(pHba->host->host_lock, flags); +- nr = ARRAY_SIZE(pHba->ioctl_reply_context); +- for (i = 0; i < nr; i++) { +- if (pHba->ioctl_reply_context[i] == NULL) { +- pHba->ioctl_reply_context[i] = reply; +- break; +- } +- } +- spin_unlock_irqrestore(pHba->host->host_lock, flags); +- if (i >= nr) { +- printk(KERN_WARNING"%s: Too many outstanding " +- "ioctl commands\n", pHba->name); +- return (u32)-1; +- } +- +- return i; +-#endif +-} +- +-/* +- * Go from an u32 'context' to a pointer to ioctl reply data. +- */ +-static void *adpt_ioctl_from_context(adpt_hba *pHba, u32 context) +-{ +-#if BITS_PER_LONG == 32 +- return (void *)(unsigned long)context; +-#else +- void *p = pHba->ioctl_reply_context[context]; +- pHba->ioctl_reply_context[context] = NULL; +- +- return p; +-#endif +-} +- + /*=========================================================================== + * Error Handling routines + *=========================================================================== +@@ -1648,208 +1603,6 @@ static int adpt_close(struct inode *inod + return 0; + } + +- +-static int adpt_i2o_passthru(adpt_hba* pHba, u32 __user *arg) +-{ +- u32 msg[MAX_MESSAGE_SIZE]; +- u32* reply = NULL; +- u32 size = 0; +- u32 reply_size = 0; +- u32 __user *user_msg = arg; +- u32 __user * user_reply = NULL; +- void **sg_list = NULL; +- u32 sg_offset = 0; +- u32 sg_count = 0; +- int sg_index = 0; +- u32 i = 0; +- u32 rcode = 0; +- void *p = NULL; +- dma_addr_t addr; +- ulong flags = 0; +- +- memset(&msg, 0, MAX_MESSAGE_SIZE*4); +- // get user msg size in u32s +- if(get_user(size, &user_msg[0])){ +- return -EFAULT; +- } +- size = size>>16; +- +- user_reply = &user_msg[size]; +- if(size > MAX_MESSAGE_SIZE){ +- return -EFAULT; +- } +- size *= 4; // Convert to bytes +- +- /* Copy in the user's I2O command */ +- if(copy_from_user(msg, user_msg, size)) { +- return -EFAULT; +- } +- get_user(reply_size, &user_reply[0]); +- reply_size = reply_size>>16; +- if(reply_size > REPLY_FRAME_SIZE){ +- reply_size = REPLY_FRAME_SIZE; +- } +- reply_size *= 4; +- reply = kzalloc(REPLY_FRAME_SIZE*4, GFP_KERNEL); +- if(reply == NULL) { +- printk(KERN_WARNING"%s: Could not allocate reply buffer\n",pHba->name); +- return -ENOMEM; +- } +- sg_offset = (msg[0]>>4)&0xf; +- msg[2] = 0x40000000; // IOCTL context +- msg[3] = adpt_ioctl_to_context(pHba, reply); +- if (msg[3] == (u32)-1) { +- rcode = -EBUSY; +- goto free; +- } +- +- sg_list = kcalloc(pHba->sg_tablesize, sizeof(*sg_list), GFP_KERNEL); +- if (!sg_list) { +- rcode = -ENOMEM; +- goto free; +- } +- if(sg_offset) { +- // TODO add 64 bit API +- struct sg_simple_element *sg = (struct sg_simple_element*) (msg+sg_offset); +- sg_count = (size - sg_offset*4) / sizeof(struct sg_simple_element); +- if (sg_count > pHba->sg_tablesize){ +- printk(KERN_DEBUG"%s:IOCTL SG List too large (%u)\n", pHba->name,sg_count); +- rcode = -EINVAL; +- goto free; +- } +- +- for(i = 0; i < sg_count; i++) { +- int sg_size; +- +- if (!(sg[i].flag_count & 0x10000000 /*I2O_SGL_FLAGS_SIMPLE_ADDRESS_ELEMENT*/)) { +- printk(KERN_DEBUG"%s:Bad SG element %d - not simple (%x)\n",pHba->name,i, sg[i].flag_count); +- rcode = -EINVAL; +- goto cleanup; +- } +- sg_size = sg[i].flag_count & 0xffffff; +- /* Allocate memory for the transfer */ +- p = dma_alloc_coherent(&pHba->pDev->dev, sg_size, &addr, GFP_KERNEL); +- if(!p) { +- printk(KERN_DEBUG"%s: Could not allocate SG buffer - size = %d buffer number %d of %d\n", +- pHba->name,sg_size,i,sg_count); +- rcode = -ENOMEM; +- goto cleanup; +- } +- sg_list[sg_index++] = p; // sglist indexed with input frame, not our internal frame. +- /* Copy in the user's SG buffer if necessary */ +- if(sg[i].flag_count & 0x04000000 /*I2O_SGL_FLAGS_DIR*/) { +- // sg_simple_element API is 32 bit +- if (copy_from_user(p,(void __user *)(ulong)sg[i].addr_bus, sg_size)) { +- printk(KERN_DEBUG"%s: Could not copy SG buf %d FROM user\n",pHba->name,i); +- rcode = -EFAULT; +- goto cleanup; +- } +- } +- /* sg_simple_element API is 32 bit, but addr < 4GB */ +- sg[i].addr_bus = addr; +- } +- } +- +- do { +- /* +- * Stop any new commands from enterring the +- * controller while processing the ioctl +- */ +- if (pHba->host) { +- scsi_block_requests(pHba->host); +- spin_lock_irqsave(pHba->host->host_lock, flags); +- } +- rcode = adpt_i2o_post_wait(pHba, msg, size, FOREVER); +- if (rcode != 0) +- printk("adpt_i2o_passthru: post wait failed %d %p\n", +- rcode, reply); +- if (pHba->host) { +- spin_unlock_irqrestore(pHba->host->host_lock, flags); +- scsi_unblock_requests(pHba->host); +- } +- } while (rcode == -ETIMEDOUT); +- +- if(rcode){ +- goto cleanup; +- } +- +- if(sg_offset) { +- /* Copy back the Scatter Gather buffers back to user space */ +- u32 j; +- // TODO add 64 bit API +- struct sg_simple_element* sg; +- int sg_size; +- +- // re-acquire the original message to handle correctly the sg copy operation +- memset(&msg, 0, MAX_MESSAGE_SIZE*4); +- // get user msg size in u32s +- if(get_user(size, &user_msg[0])){ +- rcode = -EFAULT; +- goto cleanup; +- } +- size = size>>16; +- size *= 4; +- if (size > MAX_MESSAGE_SIZE) { +- rcode = -EINVAL; +- goto cleanup; +- } +- /* Copy in the user's I2O command */ +- if (copy_from_user (msg, user_msg, size)) { +- rcode = -EFAULT; +- goto cleanup; +- } +- sg_count = (size - sg_offset*4) / sizeof(struct sg_simple_element); +- +- // TODO add 64 bit API +- sg = (struct sg_simple_element*)(msg + sg_offset); +- for (j = 0; j < sg_count; j++) { +- /* Copy out the SG list to user's buffer if necessary */ +- if(! (sg[j].flag_count & 0x4000000 /*I2O_SGL_FLAGS_DIR*/)) { +- sg_size = sg[j].flag_count & 0xffffff; +- // sg_simple_element API is 32 bit +- if (copy_to_user((void __user *)(ulong)sg[j].addr_bus,sg_list[j], sg_size)) { +- printk(KERN_WARNING"%s: Could not copy %p TO user %x\n",pHba->name, sg_list[j], sg[j].addr_bus); +- rcode = -EFAULT; +- goto cleanup; +- } +- } +- } +- } +- +- /* Copy back the reply to user space */ +- if (reply_size) { +- // we wrote our own values for context - now restore the user supplied ones +- if(copy_from_user(reply+2, user_msg+2, sizeof(u32)*2)) { +- printk(KERN_WARNING"%s: Could not copy message context FROM user\n",pHba->name); +- rcode = -EFAULT; +- } +- if(copy_to_user(user_reply, reply, reply_size)) { +- printk(KERN_WARNING"%s: Could not copy reply TO user\n",pHba->name); +- rcode = -EFAULT; +- } +- } +- +- +-cleanup: +- if (rcode != -ETIME && rcode != -EINTR) { +- struct sg_simple_element *sg = +- (struct sg_simple_element*) (msg +sg_offset); +- while(sg_index) { +- if(sg_list[--sg_index]) { +- dma_free_coherent(&pHba->pDev->dev, +- sg[sg_index].flag_count & 0xffffff, +- sg_list[sg_index], +- sg[sg_index].addr_bus); +- } +- } +- } +- +-free: +- kfree(sg_list); +- kfree(reply); +- return rcode; +-} +- + #if defined __ia64__ + static void adpt_ia64_info(sysInfo_S* si) + { +@@ -1976,8 +1729,6 @@ static int adpt_ioctl(struct inode *inod + return -EFAULT; + } + break; +- case I2OUSRCMD: +- return adpt_i2o_passthru(pHba, argp); + + case DPT_CTRLINFO:{ + drvrHBAinfo_S HbaInfo; +@@ -2134,13 +1885,6 @@ static irqreturn_t adpt_isr(int irq, voi + adpt_send_nop(pHba, old_m); + } + context = readl(reply+8); +- if(context & 0x40000000){ // IOCTL +- void *p = adpt_ioctl_from_context(pHba, readl(reply+12)); +- if( p != NULL) { +- memcpy_fromio(p, reply, REPLY_FRAME_SIZE * 4); +- } +- // All IOCTLs will also be post wait +- } + if(context & 0x80000000){ // Post wait message + status = readl(reply+16); + if(status >> 24){ +@@ -2148,16 +1892,14 @@ static irqreturn_t adpt_isr(int irq, voi + } else { + status = I2O_POST_WAIT_OK; + } +- if(!(context & 0x40000000)) { +- /* +- * The request tag is one less than the command tag +- * as the firmware might treat a 0 tag as invalid +- */ +- cmd = scsi_host_find_tag(pHba->host, +- readl(reply + 12) - 1); +- if(cmd != NULL) { +- printk(KERN_WARNING"%s: Apparent SCSI cmd in Post Wait Context - cmd=%p context=%x\n", pHba->name, cmd, context); +- } ++ /* ++ * The request tag is one less than the command tag ++ * as the firmware might treat a 0 tag as invalid ++ */ ++ cmd = scsi_host_find_tag(pHba->host, ++ readl(reply + 12) - 1); ++ if(cmd != NULL) { ++ printk(KERN_WARNING"%s: Apparent SCSI cmd in Post Wait Context - cmd=%p context=%x\n", pHba->name, cmd, context); + } + adpt_i2o_post_wait_complete(context, status); + } else { // SCSI message +--- a/drivers/scsi/dpti.h ++++ b/drivers/scsi/dpti.h +@@ -248,7 +248,6 @@ typedef struct _adpt_hba { + void __iomem *FwDebugBLEDflag_P;// Virtual Addr Of FW Debug BLED + void __iomem *FwDebugBLEDvalue_P;// Virtual Addr Of FW Debug BLED + u32 FwDebugFlags; +- u32 *ioctl_reply_context[4]; + } adpt_hba; + + struct sg_simple_element { diff --git a/queue-5.10/series b/queue-5.10/series index 2fdc9edcda5..97d7fd2c913 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -109,3 +109,10 @@ test_firmware-fix-the-memory-leak-of-the-allocated-firmware-buffer.patch kvm-x86-account-fastpath-only-vm-exits-in-vcpu-stats.patch keys-asymmetric-copy-sig-and-digest-in-public_key_verify_signature.patch regmap-account-for-register-length-when-chunking.patch +tpm-tpm_tis-request-threaded-interrupt-handler.patch +media-ti-vpe-cal-avoid-field_get-assertion.patch +drm-rcar-stop-using-imply-for-dependencies.patch +scsi-dpt_i2o-remove-broken-pass-through-ioctl-i2ousercmd.patch +scsi-dpt_i2o-do-not-process-completions-with-invalid-addresses.patch +crypto-ccp-reject-sev-commands-with-mismatching-command-buffer.patch +crypto-ccp-play-nice-with-vmalloc-d-memory-for-sev-command-structs.patch diff --git a/queue-5.10/tpm-tpm_tis-request-threaded-interrupt-handler.patch b/queue-5.10/tpm-tpm_tis-request-threaded-interrupt-handler.patch new file mode 100644 index 00000000000..cc2d4f84127 --- /dev/null +++ b/queue-5.10/tpm-tpm_tis-request-threaded-interrupt-handler.patch @@ -0,0 +1,45 @@ +From 0c7e66e5fd69bf21034c9a9b081d7de7c3eb2cea Mon Sep 17 00:00:00 2001 +From: Lino Sanfilippo +Date: Thu, 24 Nov 2022 14:55:34 +0100 +Subject: tpm, tpm_tis: Request threaded interrupt handler +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Lino Sanfilippo + +commit 0c7e66e5fd69bf21034c9a9b081d7de7c3eb2cea upstream. + +The TIS interrupt handler at least has to read and write the interrupt +status register. In case of SPI both operations result in a call to +tpm_tis_spi_transfer() which uses the bus_lock_mutex of the spi device +and thus must only be called from a sleepable context. + +To ensure this request a threaded interrupt handler. + +Signed-off-by: Lino Sanfilippo +Tested-by: Michael Niewöhner +Tested-by: Jarkko Sakkinen +Reviewed-by: Jarkko Sakkinen +Signed-off-by: Jarkko Sakkinen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/char/tpm/tpm_tis_core.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +--- a/drivers/char/tpm/tpm_tis_core.c ++++ b/drivers/char/tpm/tpm_tis_core.c +@@ -764,8 +764,11 @@ static int tpm_tis_probe_irq_single(stru + int rc; + u32 int_status; + +- if (devm_request_irq(chip->dev.parent, irq, tis_int_handler, flags, +- dev_name(&chip->dev), chip) != 0) { ++ ++ rc = devm_request_threaded_irq(chip->dev.parent, irq, NULL, ++ tis_int_handler, IRQF_ONESHOT | flags, ++ dev_name(&chip->dev), chip); ++ if (rc) { + dev_info(&chip->dev, "Unable to request irq: %d for probe\n", + irq); + return -1;