--- /dev/null
+From a5951389e58d2e816eed3dbec5877de9327fd881 Mon Sep 17 00:00:00 2001
+From: Douglas Anderson <dianders@chromium.org>
+Date: Tue, 7 Jan 2025 12:06:02 -0800
+Subject: arm64: errata: Add newer ARM cores to the spectre_bhb_loop_affected() lists
+
+From: Douglas Anderson <dianders@chromium.org>
+
+commit a5951389e58d2e816eed3dbec5877de9327fd881 upstream.
+
+When comparing to the ARM list [1], it appears that several ARM cores
+were missing from the lists in spectre_bhb_loop_affected(). Add them.
+
+NOTE: for some of these cores it may not matter since other ways of
+clearing the BHB may be used (like the CLRBHB instruction or ECBHB),
+but it still seems good to have all the info from ARM's whitepaper
+included.
+
+[1] https://developer.arm.com/Arm%20Security%20Center/Spectre-BHB
+
+Fixes: 558c303c9734 ("arm64: Mitigate spectre style branch history side channels")
+Cc: stable@vger.kernel.org
+Signed-off-by: Douglas Anderson <dianders@chromium.org>
+Reviewed-by: James Morse <james.morse@arm.com>
+Link: https://lore.kernel.org/r/20250107120555.v4.5.I4a9a527e03f663040721c5401c41de587d015c82@changeid
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm64/kernel/proton-pack.c | 15 ++++++++++++++-
+ 1 file changed, 14 insertions(+), 1 deletion(-)
+
+--- a/arch/arm64/kernel/proton-pack.c
++++ b/arch/arm64/kernel/proton-pack.c
+@@ -876,6 +876,14 @@ static u8 spectre_bhb_loop_affected(void
+ {
+ u8 k = 0;
+
++ static const struct midr_range spectre_bhb_k132_list[] = {
++ MIDR_ALL_VERSIONS(MIDR_CORTEX_X3),
++ MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V2),
++ };
++ static const struct midr_range spectre_bhb_k38_list[] = {
++ MIDR_ALL_VERSIONS(MIDR_CORTEX_A715),
++ MIDR_ALL_VERSIONS(MIDR_CORTEX_A720),
++ };
+ static const struct midr_range spectre_bhb_k32_list[] = {
+ MIDR_ALL_VERSIONS(MIDR_CORTEX_A78),
+ MIDR_ALL_VERSIONS(MIDR_CORTEX_A78AE),
+@@ -889,6 +897,7 @@ static u8 spectre_bhb_loop_affected(void
+ };
+ static const struct midr_range spectre_bhb_k24_list[] = {
+ MIDR_ALL_VERSIONS(MIDR_CORTEX_A76),
++ MIDR_ALL_VERSIONS(MIDR_CORTEX_A76AE),
+ MIDR_ALL_VERSIONS(MIDR_CORTEX_A77),
+ MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1),
+ MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_4XX_GOLD),
+@@ -904,7 +913,11 @@ static u8 spectre_bhb_loop_affected(void
+ {},
+ };
+
+- if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k32_list))
++ if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k132_list))
++ k = 132;
++ else if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k38_list))
++ k = 38;
++ else if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k32_list))
+ k = 32;
+ else if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k24_list))
+ k = 24;
--- /dev/null
+From 55c85fa7579dc2e3f5399ef5bad67a44257c1a48 Mon Sep 17 00:00:00 2001
+From: Yi Liu <yi.l.liu@intel.com>
+Date: Wed, 5 Mar 2025 19:48:42 -0800
+Subject: iommufd: Fail replace if device has not been attached
+
+From: Yi Liu <yi.l.liu@intel.com>
+
+commit 55c85fa7579dc2e3f5399ef5bad67a44257c1a48 upstream.
+
+The current implementation of iommufd_device_do_replace() implicitly
+assumes that the input device has already been attached. However, there
+is no explicit check to verify this assumption. If another device within
+the same group has been attached, the replace operation might succeed,
+but the input device itself may not have been attached yet.
+
+As a result, the input device might not be tracked in the
+igroup->device_list, and its reserved IOVA might not be added. Despite
+this, the caller might incorrectly assume that the device has been
+successfully replaced, which could lead to unexpected behavior or errors.
+
+To address this issue, add a check to ensure that the input device has
+been attached before proceeding with the replace operation. This check
+will help maintain the integrity of the device tracking system and prevent
+potential issues arising from incorrect assumptions about the device's
+attachment status.
+
+Fixes: e88d4ec154a8 ("iommufd: Add iommufd_device_replace()")
+Link: https://patch.msgid.link/r/20250306034842.5950-1-yi.l.liu@intel.com
+Cc: stable@vger.kernel.org
+Reviewed-by: Kevin Tian <kevin.tian@intel.com>
+Signed-off-by: Yi Liu <yi.l.liu@intel.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iommu/iommufd/device.c | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+--- a/drivers/iommu/iommufd/device.c
++++ b/drivers/iommu/iommufd/device.c
+@@ -354,6 +354,17 @@ iommufd_device_attach_reserved_iova(stru
+
+ /* The device attach/detach/replace helpers for attach_handle */
+
++/* Check if idev is attached to igroup->hwpt */
++static bool iommufd_device_is_attached(struct iommufd_device *idev)
++{
++ struct iommufd_device *cur;
++
++ list_for_each_entry(cur, &idev->igroup->device_list, group_item)
++ if (cur == idev)
++ return true;
++ return false;
++}
++
+ static int iommufd_hwpt_attach_device(struct iommufd_hw_pagetable *hwpt,
+ struct iommufd_device *idev)
+ {
+@@ -592,6 +603,11 @@ iommufd_device_do_replace(struct iommufd
+ rc = -EINVAL;
+ goto err_unlock;
+ }
++
++ if (!iommufd_device_is_attached(idev)) {
++ rc = -EINVAL;
++ goto err_unlock;
++ }
+
+ if (hwpt == igroup->hwpt) {
+ mutex_unlock(&idev->igroup->lock);
--- /dev/null
+From fb21b1568adaa76af7a8c853f37c60fba8b28661 Mon Sep 17 00:00:00 2001
+From: Nicolin Chen <nicolinc@nvidia.com>
+Date: Mon, 3 Feb 2025 21:00:54 -0800
+Subject: iommufd: Make attach_handle generic than fault specific
+
+From: Nicolin Chen <nicolinc@nvidia.com>
+
+commit fb21b1568adaa76af7a8c853f37c60fba8b28661 upstream.
+
+"attach_handle" was added exclusively for the iommufd_fault_iopf_handler()
+used by IOPF/PRI use cases. Now, both the MSI and PASID series require to
+reuse the attach_handle for non-fault cases.
+
+Add a set of new attach/detach/replace helpers that does the attach_handle
+allocation/releasing/replacement in the common path and also handles those
+fault specific routines such as iopf enabling/disabling and auto response.
+
+This covers both non-fault and fault cases in a clean way, replacing those
+inline helpers in the header. The following patch will clean up those old
+helpers in the fault.c file.
+
+Link: https://patch.msgid.link/r/32687df01c02291d89986a9fca897bbbe2b10987.1738645017.git.nicolinc@nvidia.com
+Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
+Reviewed-by: Yi Liu <yi.l.liu@intel.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iommu/iommufd/device.c | 105 ++++++++++++++++++++++++++++++++
+ drivers/iommu/iommufd/fault.c | 8 +-
+ drivers/iommu/iommufd/iommufd_private.h | 33 +---------
+ 3 files changed, 113 insertions(+), 33 deletions(-)
+
+--- a/drivers/iommu/iommufd/device.c
++++ b/drivers/iommu/iommufd/device.c
+@@ -352,6 +352,111 @@ iommufd_device_attach_reserved_iova(stru
+ return 0;
+ }
+
++/* The device attach/detach/replace helpers for attach_handle */
++
++static int iommufd_hwpt_attach_device(struct iommufd_hw_pagetable *hwpt,
++ struct iommufd_device *idev)
++{
++ struct iommufd_attach_handle *handle;
++ int rc;
++
++ lockdep_assert_held(&idev->igroup->lock);
++
++ handle = kzalloc(sizeof(*handle), GFP_KERNEL);
++ if (!handle)
++ return -ENOMEM;
++
++ if (hwpt->fault) {
++ rc = iommufd_fault_iopf_enable(idev);
++ if (rc)
++ goto out_free_handle;
++ }
++
++ handle->idev = idev;
++ rc = iommu_attach_group_handle(hwpt->domain, idev->igroup->group,
++ &handle->handle);
++ if (rc)
++ goto out_disable_iopf;
++
++ return 0;
++
++out_disable_iopf:
++ if (hwpt->fault)
++ iommufd_fault_iopf_disable(idev);
++out_free_handle:
++ kfree(handle);
++ return rc;
++}
++
++static struct iommufd_attach_handle *
++iommufd_device_get_attach_handle(struct iommufd_device *idev)
++{
++ struct iommu_attach_handle *handle;
++
++ lockdep_assert_held(&idev->igroup->lock);
++
++ handle =
++ iommu_attach_handle_get(idev->igroup->group, IOMMU_NO_PASID, 0);
++ if (IS_ERR(handle))
++ return NULL;
++ return to_iommufd_handle(handle);
++}
++
++static void iommufd_hwpt_detach_device(struct iommufd_hw_pagetable *hwpt,
++ struct iommufd_device *idev)
++{
++ struct iommufd_attach_handle *handle;
++
++ handle = iommufd_device_get_attach_handle(idev);
++ iommu_detach_group_handle(hwpt->domain, idev->igroup->group);
++ if (hwpt->fault) {
++ iommufd_auto_response_faults(hwpt, handle);
++ iommufd_fault_iopf_disable(idev);
++ }
++ kfree(handle);
++}
++
++static int iommufd_hwpt_replace_device(struct iommufd_device *idev,
++ struct iommufd_hw_pagetable *hwpt,
++ struct iommufd_hw_pagetable *old)
++{
++ struct iommufd_attach_handle *handle, *old_handle =
++ iommufd_device_get_attach_handle(idev);
++ int rc;
++
++ handle = kzalloc(sizeof(*handle), GFP_KERNEL);
++ if (!handle)
++ return -ENOMEM;
++
++ if (hwpt->fault && !old->fault) {
++ rc = iommufd_fault_iopf_enable(idev);
++ if (rc)
++ goto out_free_handle;
++ }
++
++ handle->idev = idev;
++ rc = iommu_replace_group_handle(idev->igroup->group, hwpt->domain,
++ &handle->handle);
++ if (rc)
++ goto out_disable_iopf;
++
++ if (old->fault) {
++ iommufd_auto_response_faults(hwpt, old_handle);
++ if (!hwpt->fault)
++ iommufd_fault_iopf_disable(idev);
++ }
++ kfree(old_handle);
++
++ return 0;
++
++out_disable_iopf:
++ if (hwpt->fault && !old->fault)
++ iommufd_fault_iopf_disable(idev);
++out_free_handle:
++ kfree(handle);
++ return rc;
++}
++
+ int iommufd_hw_pagetable_attach(struct iommufd_hw_pagetable *hwpt,
+ struct iommufd_device *idev)
+ {
+--- a/drivers/iommu/iommufd/fault.c
++++ b/drivers/iommu/iommufd/fault.c
+@@ -17,7 +17,7 @@
+ #include "../iommu-priv.h"
+ #include "iommufd_private.h"
+
+-static int iommufd_fault_iopf_enable(struct iommufd_device *idev)
++int iommufd_fault_iopf_enable(struct iommufd_device *idev)
+ {
+ struct device *dev = idev->dev;
+ int ret;
+@@ -50,7 +50,7 @@ static int iommufd_fault_iopf_enable(str
+ return ret;
+ }
+
+-static void iommufd_fault_iopf_disable(struct iommufd_device *idev)
++void iommufd_fault_iopf_disable(struct iommufd_device *idev)
+ {
+ mutex_lock(&idev->iopf_lock);
+ if (!WARN_ON(idev->iopf_enabled == 0)) {
+@@ -98,8 +98,8 @@ int iommufd_fault_domain_attach_dev(stru
+ return ret;
+ }
+
+-static void iommufd_auto_response_faults(struct iommufd_hw_pagetable *hwpt,
+- struct iommufd_attach_handle *handle)
++void iommufd_auto_response_faults(struct iommufd_hw_pagetable *hwpt,
++ struct iommufd_attach_handle *handle)
+ {
+ struct iommufd_fault *fault = hwpt->fault;
+ struct iopf_group *group, *next;
+--- a/drivers/iommu/iommufd/iommufd_private.h
++++ b/drivers/iommu/iommufd/iommufd_private.h
+@@ -504,35 +504,10 @@ int iommufd_fault_domain_replace_dev(str
+ struct iommufd_hw_pagetable *hwpt,
+ struct iommufd_hw_pagetable *old);
+
+-static inline int iommufd_hwpt_attach_device(struct iommufd_hw_pagetable *hwpt,
+- struct iommufd_device *idev)
+-{
+- if (hwpt->fault)
+- return iommufd_fault_domain_attach_dev(hwpt, idev);
+-
+- return iommu_attach_group(hwpt->domain, idev->igroup->group);
+-}
+-
+-static inline void iommufd_hwpt_detach_device(struct iommufd_hw_pagetable *hwpt,
+- struct iommufd_device *idev)
+-{
+- if (hwpt->fault) {
+- iommufd_fault_domain_detach_dev(hwpt, idev);
+- return;
+- }
+-
+- iommu_detach_group(hwpt->domain, idev->igroup->group);
+-}
+-
+-static inline int iommufd_hwpt_replace_device(struct iommufd_device *idev,
+- struct iommufd_hw_pagetable *hwpt,
+- struct iommufd_hw_pagetable *old)
+-{
+- if (old->fault || hwpt->fault)
+- return iommufd_fault_domain_replace_dev(idev, hwpt, old);
+-
+- return iommu_group_replace_domain(idev->igroup->group, hwpt->domain);
+-}
++int iommufd_fault_iopf_enable(struct iommufd_device *idev);
++void iommufd_fault_iopf_disable(struct iommufd_device *idev);
++void iommufd_auto_response_faults(struct iommufd_hw_pagetable *hwpt,
++ struct iommufd_attach_handle *handle);
+
+ static inline struct iommufd_viommu *
+ iommufd_get_viommu(struct iommufd_ucmd *ucmd, u32 id)