--- /dev/null
+From d319f344561de23e810515d109c7278919bff7b0 Mon Sep 17 00:00:00 2001
+From: Alexei Starovoitov <ast@kernel.org>
+Date: Mon, 10 Apr 2023 19:43:44 +0200
+Subject: mm: Fix copy_from_user_nofault().
+
+From: Alexei Starovoitov <ast@kernel.org>
+
+commit d319f344561de23e810515d109c7278919bff7b0 upstream.
+
+There are several issues with copy_from_user_nofault():
+
+- access_ok() is designed for user context only and for that reason
+it has WARN_ON_IN_IRQ() which triggers when bpf, kprobe, eprobe
+and perf on ppc are calling it from irq.
+
+- it's missing nmi_uaccess_okay() which is a nop on all architectures
+except x86 where it's required.
+The comment in arch/x86/mm/tlb.c explains the details why it's necessary.
+Calling copy_from_user_nofault() from bpf, [ke]probe without this check is not safe.
+
+- __copy_from_user_inatomic() under CONFIG_HARDENED_USERCOPY is calling
+check_object_size()->__check_object_size()->check_heap_object()->find_vmap_area()->spin_lock()
+which is not safe to do from bpf, [ke]probe and perf due to potential deadlock.
+
+Fix all three issues. At the end the copy_from_user_nofault() becomes
+equivalent to copy_from_user_nmi() from safety point of view with
+a difference in the return value.
+
+Reported-by: Hsin-Wei Hung <hsinweih@uci.edu>
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Florian Lehner <dev@der-flo.net>
+Tested-by: Hsin-Wei Hung <hsinweih@uci.edu>
+Tested-by: Florian Lehner <dev@der-flo.net>
+Link: https://lore.kernel.org/r/20230410174345.4376-2-dev@der-flo.net
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Cc: Javier Honduvilla Coto <javierhonduco@gmail.com>
+Cc: Daniel Borkmann <daniel@iogearbox.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/maccess.c | 16 +++++++++++-----
+ mm/usercopy.c | 2 +-
+ 2 files changed, 12 insertions(+), 6 deletions(-)
+
+--- a/mm/maccess.c
++++ b/mm/maccess.c
+@@ -5,6 +5,7 @@
+ #include <linux/export.h>
+ #include <linux/mm.h>
+ #include <linux/uaccess.h>
++#include <asm/tlb.h>
+
+ bool __weak copy_from_kernel_nofault_allowed(const void *unsafe_src,
+ size_t size)
+@@ -113,11 +114,16 @@ Efault:
+ long copy_from_user_nofault(void *dst, const void __user *src, size_t size)
+ {
+ long ret = -EFAULT;
+- if (access_ok(src, size)) {
+- pagefault_disable();
+- ret = __copy_from_user_inatomic(dst, src, size);
+- pagefault_enable();
+- }
++
++ if (!__access_ok(src, size))
++ return ret;
++
++ if (!nmi_uaccess_okay())
++ return ret;
++
++ pagefault_disable();
++ ret = __copy_from_user_inatomic(dst, src, size);
++ pagefault_enable();
+
+ if (ret)
+ return -EFAULT;
+--- a/mm/usercopy.c
++++ b/mm/usercopy.c
+@@ -172,7 +172,7 @@ static inline void check_heap_object(con
+ return;
+ }
+
+- if (is_vmalloc_addr(ptr)) {
++ if (is_vmalloc_addr(ptr) && !pagefault_disabled()) {
+ struct vmap_area *area = find_vmap_area(addr);
+
+ if (!area)
--- /dev/null
+From 4d2732882703791ea4b670df433f88fc4b40a5cb Mon Sep 17 00:00:00 2001
+From: Matthew Garrett <mjg59@srcf.ucam.org>
+Date: Sat, 31 Dec 2022 01:14:32 -0800
+Subject: tpm_crb: Add support for CRB devices based on Pluton
+
+From: Matthew Garrett <mjg59@srcf.ucam.org>
+
+commit 4d2732882703791ea4b670df433f88fc4b40a5cb upstream.
+
+Pluton is an integrated security processor present in some recent Ryzen
+parts. If it's enabled, it presents two devices - an MSFT0101 ACPI device
+that's broadly an implementation of a Command Response Buffer TPM2, and an
+MSFT0200 ACPI device whose functionality I haven't examined in detail yet.
+This patch only attempts to add support for the TPM device.
+
+There's a few things that need to be handled here. The first is that the
+TPM2 ACPI table uses a previously undefined start method identifier. The
+table format appears to include 16 bytes of startup data, which corresponds
+to one 64-bit address for a start message and one 64-bit address for a
+completion response. The second is that the ACPI tables on the Thinkpad Z13
+I'm testing this on don't define any memory windows in _CRS (or, more
+accurately, there are two empty memory windows). This check doesn't seem
+strictly necessary, so I've skipped that.
+
+Finally, it seems like chip needs to be explicitly asked to transition into
+ready status on every command. Failing to do this means that if two
+commands are sent in succession without an idle/ready transition in
+between, everything will appear to work fine but the response is simply the
+original command. I'm working without any docs here, so I'm not sure if
+this is actually the required behaviour or if I'm missing something
+somewhere else, but doing this results in the chip working reliably.
+
+Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
+Signed-off-by: Matthew Garrett <mjg59@srcf.ucam.org>
+Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
+Cc: "Limonciello, Mario" <mario.limonciello@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/char/tpm/tpm_crb.c | 100 ++++++++++++++++++++++++++++++++++++++++-----
+ include/acpi/actbl3.h | 1
+ 2 files changed, 91 insertions(+), 10 deletions(-)
+
+--- a/drivers/char/tpm/tpm_crb.c
++++ b/drivers/char/tpm/tpm_crb.c
+@@ -98,6 +98,8 @@ struct crb_priv {
+ u8 __iomem *rsp;
+ u32 cmd_size;
+ u32 smc_func_id;
++ u32 __iomem *pluton_start_addr;
++ u32 __iomem *pluton_reply_addr;
+ };
+
+ struct tpm2_crb_smc {
+@@ -108,6 +110,11 @@ struct tpm2_crb_smc {
+ u32 smc_func_id;
+ };
+
++struct tpm2_crb_pluton {
++ u64 start_addr;
++ u64 reply_addr;
++};
++
+ static bool crb_wait_for_reg_32(u32 __iomem *reg, u32 mask, u32 value,
+ unsigned long timeout)
+ {
+@@ -127,6 +134,25 @@ static bool crb_wait_for_reg_32(u32 __io
+ return ((ioread32(reg) & mask) == value);
+ }
+
++static int crb_try_pluton_doorbell(struct crb_priv *priv, bool wait_for_complete)
++{
++ if (priv->sm != ACPI_TPM2_COMMAND_BUFFER_WITH_PLUTON)
++ return 0;
++
++ if (!crb_wait_for_reg_32(priv->pluton_reply_addr, ~0, 1, TPM2_TIMEOUT_C))
++ return -ETIME;
++
++ iowrite32(1, priv->pluton_start_addr);
++ if (wait_for_complete == false)
++ return 0;
++
++ if (!crb_wait_for_reg_32(priv->pluton_start_addr,
++ 0xffffffff, 0, 200))
++ return -ETIME;
++
++ return 0;
++}
++
+ /**
+ * __crb_go_idle - request tpm crb device to go the idle state
+ *
+@@ -145,6 +171,8 @@ static bool crb_wait_for_reg_32(u32 __io
+ */
+ static int __crb_go_idle(struct device *dev, struct crb_priv *priv)
+ {
++ int rc;
++
+ if ((priv->sm == ACPI_TPM2_START_METHOD) ||
+ (priv->sm == ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD) ||
+ (priv->sm == ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC))
+@@ -152,6 +180,10 @@ static int __crb_go_idle(struct device *
+
+ iowrite32(CRB_CTRL_REQ_GO_IDLE, &priv->regs_t->ctrl_req);
+
++ rc = crb_try_pluton_doorbell(priv, true);
++ if (rc)
++ return rc;
++
+ if (!crb_wait_for_reg_32(&priv->regs_t->ctrl_req,
+ CRB_CTRL_REQ_GO_IDLE/* mask */,
+ 0, /* value */
+@@ -188,12 +220,19 @@ static int crb_go_idle(struct tpm_chip *
+ */
+ static int __crb_cmd_ready(struct device *dev, struct crb_priv *priv)
+ {
++ int rc;
++
+ if ((priv->sm == ACPI_TPM2_START_METHOD) ||
+ (priv->sm == ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD) ||
+ (priv->sm == ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC))
+ return 0;
+
+ iowrite32(CRB_CTRL_REQ_CMD_READY, &priv->regs_t->ctrl_req);
++
++ rc = crb_try_pluton_doorbell(priv, true);
++ if (rc)
++ return rc;
++
+ if (!crb_wait_for_reg_32(&priv->regs_t->ctrl_req,
+ CRB_CTRL_REQ_CMD_READY /* mask */,
+ 0, /* value */
+@@ -371,6 +410,10 @@ static int crb_send(struct tpm_chip *chi
+ return -E2BIG;
+ }
+
++ /* Seems to be necessary for every command */
++ if (priv->sm == ACPI_TPM2_COMMAND_BUFFER_WITH_PLUTON)
++ __crb_cmd_ready(&chip->dev, priv);
++
+ memcpy_toio(priv->cmd, buf, len);
+
+ /* Make sure that cmd is populated before issuing start. */
+@@ -394,7 +437,10 @@ static int crb_send(struct tpm_chip *chi
+ rc = tpm_crb_smc_start(&chip->dev, priv->smc_func_id);
+ }
+
+- return rc;
++ if (rc)
++ return rc;
++
++ return crb_try_pluton_doorbell(priv, false);
+ }
+
+ static void crb_cancel(struct tpm_chip *chip)
+@@ -524,15 +570,18 @@ static int crb_map_io(struct acpi_device
+ return ret;
+ acpi_dev_free_resource_list(&acpi_resource_list);
+
+- if (resource_type(iores_array) != IORESOURCE_MEM) {
+- dev_err(dev, FW_BUG "TPM2 ACPI table does not define a memory resource\n");
+- return -EINVAL;
+- } else if (resource_type(iores_array + TPM_CRB_MAX_RESOURCES) ==
+- IORESOURCE_MEM) {
+- dev_warn(dev, "TPM2 ACPI table defines too many memory resources\n");
+- memset(iores_array + TPM_CRB_MAX_RESOURCES,
+- 0, sizeof(*iores_array));
+- iores_array[TPM_CRB_MAX_RESOURCES].flags = 0;
++ /* Pluton doesn't appear to define ACPI memory regions */
++ if (priv->sm != ACPI_TPM2_COMMAND_BUFFER_WITH_PLUTON) {
++ if (resource_type(iores_array) != IORESOURCE_MEM) {
++ dev_err(dev, FW_BUG "TPM2 ACPI table does not define a memory resource\n");
++ return -EINVAL;
++ } else if (resource_type(iores_array + TPM_CRB_MAX_RESOURCES) ==
++ IORESOURCE_MEM) {
++ dev_warn(dev, "TPM2 ACPI table defines too many memory resources\n");
++ memset(iores_array + TPM_CRB_MAX_RESOURCES,
++ 0, sizeof(*iores_array));
++ iores_array[TPM_CRB_MAX_RESOURCES].flags = 0;
++ }
+ }
+
+ iores = NULL;
+@@ -656,6 +705,22 @@ out_relinquish_locality:
+ return ret;
+ }
+
++static int crb_map_pluton(struct device *dev, struct crb_priv *priv,
++ struct acpi_table_tpm2 *buf, struct tpm2_crb_pluton *crb_pluton)
++{
++ priv->pluton_start_addr = crb_map_res(dev, NULL, NULL,
++ crb_pluton->start_addr, 4);
++ if (IS_ERR(priv->pluton_start_addr))
++ return PTR_ERR(priv->pluton_start_addr);
++
++ priv->pluton_reply_addr = crb_map_res(dev, NULL, NULL,
++ crb_pluton->reply_addr, 4);
++ if (IS_ERR(priv->pluton_reply_addr))
++ return PTR_ERR(priv->pluton_reply_addr);
++
++ return 0;
++}
++
+ static int crb_acpi_add(struct acpi_device *device)
+ {
+ struct acpi_table_tpm2 *buf;
+@@ -663,6 +728,7 @@ static int crb_acpi_add(struct acpi_devi
+ struct tpm_chip *chip;
+ struct device *dev = &device->dev;
+ struct tpm2_crb_smc *crb_smc;
++ struct tpm2_crb_pluton *crb_pluton;
+ acpi_status status;
+ u32 sm;
+ int rc;
+@@ -700,6 +766,20 @@ static int crb_acpi_add(struct acpi_devi
+ priv->smc_func_id = crb_smc->smc_func_id;
+ }
+
++ if (sm == ACPI_TPM2_COMMAND_BUFFER_WITH_PLUTON) {
++ if (buf->header.length < (sizeof(*buf) + sizeof(*crb_pluton))) {
++ dev_err(dev,
++ FW_BUG "TPM2 ACPI table has wrong size %u for start method type %d\n",
++ buf->header.length,
++ ACPI_TPM2_COMMAND_BUFFER_WITH_PLUTON);
++ return -EINVAL;
++ }
++ crb_pluton = ACPI_ADD_PTR(struct tpm2_crb_pluton, buf, sizeof(*buf));
++ rc = crb_map_pluton(dev, priv, buf, crb_pluton);
++ if (rc)
++ return rc;
++ }
++
+ priv->sm = sm;
+ priv->hid = acpi_device_hid(device);
+
+--- a/include/acpi/actbl3.h
++++ b/include/acpi/actbl3.h
+@@ -443,6 +443,7 @@ struct acpi_tpm2_phy {
+ #define ACPI_TPM2_RESERVED10 10
+ #define ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC 11 /* V1.2 Rev 8 */
+ #define ACPI_TPM2_RESERVED 12
++#define ACPI_TPM2_COMMAND_BUFFER_WITH_PLUTON 13
+
+ /* Optional trailer appears after any start_method subtables */
+