Patch "PCI: qcom: Enable BDF to SID translation properly" has been added to the 6.1-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    PCI: qcom: Enable BDF to SID translation properly

to the 6.1-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     pci-qcom-enable-bdf-to-sid-translation-properly.patch
and it can be found in the queue-6.1 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit d35f50d901ddfb88ef34bb2107bced64ba786346
Author: Manivannan Sadhasivam <manivannan.sadhasivam@xxxxxxxxxx>
Date:   Thu Mar 7 16:35:15 2024 +0530

    PCI: qcom: Enable BDF to SID translation properly
    
    [ Upstream commit bf79e33cdd89db498e00a6131e937259de5f2705 ]
    
    Qcom SoCs making use of ARM SMMU require BDF to SID translation table in
    the driver to properly map the SID for the PCIe devices based on their BDF
    identifier. This is currently achieved with the help of
    qcom_pcie_config_sid_1_9_0() function for SoCs supporting the 1_9_0 config.
    
    But With newer Qcom SoCs starting from SM8450, BDF to SID translation is
    set to bypass mode by default in hardware. Due to this, the translation
    table that is set in the qcom_pcie_config_sid_1_9_0() is essentially
    unused and the default SID is used for all endpoints in SoCs starting from
    SM8450.
    
    This is a security concern and also warrants swapping the DeviceID in DT
    while using the GIC ITS to handle MSIs from endpoints. The swapping is
    currently done like below in DT when using GIC ITS:
    
          /*
            * MSIs for BDF (1:0.0) only works with Device ID 0x5980.
            * Hence, the IDs are swapped.
            */
          msi-map = <0x0 &gic_its 0x5981 0x1>,
                    <0x100 &gic_its 0x5980 0x1>;
    
    Here, swapping of the DeviceIDs ensure that the endpoint with BDF (1:0.0)
    gets the DeviceID 0x5980 which is associated with the default SID as per
    the iommu mapping in DT. So MSIs were delivered with IDs swapped so far.
    But this also means the Root Port (0:0.0) won't receive any MSIs (for PME,
    AER etc...)
    
    So let's fix these issues by clearing the BDF to SID bypass mode for all
    SoCs making use of the 1_9_0 config. This allows the PCIe devices to use
    the correct SID, thus avoiding the DeviceID swapping hack in DT and also
    achieving the isolation between devices.
    
    Fixes: 4c9398822106 ("PCI: qcom: Add support for configuring BDF to SID mapping for SM8250")
    Link: https://lore.kernel.org/linux-pci/20240307-pci-bdf-sid-fix-v1-1-9423a7e2d63c@xxxxxxxxxx
    Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@xxxxxxxxxx>
    Signed-off-by: Krzysztof Wilczyński <kwilczynski@xxxxxxxxxx>
    Cc: stable@xxxxxxxxxxxxxxx # 5.11
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
index 9202d2395b507..0bad23ec53ee8 100644
--- a/drivers/pci/controller/dwc/pcie-qcom.c
+++ b/drivers/pci/controller/dwc/pcie-qcom.c
@@ -50,6 +50,7 @@
 #define PARF_SLV_ADDR_SPACE_SIZE		0x358
 #define PARF_DEVICE_TYPE			0x1000
 #define PARF_BDF_TO_SID_TABLE_N			0x2000
+#define PARF_BDF_TO_SID_CFG			0x2c00
 
 /* ELBI registers */
 #define ELBI_SYS_CTRL				0x04
@@ -102,6 +103,9 @@
 /* PARF_DEVICE_TYPE register fields */
 #define DEVICE_TYPE_RC				0x4
 
+/* PARF_BDF_TO_SID_CFG fields */
+#define BDF_TO_SID_BYPASS			BIT(0)
+
 /* ELBI_SYS_CTRL register fields */
 #define ELBI_SYS_CTRL_LT_ENABLE			BIT(0)
 
@@ -1326,11 +1330,17 @@ static int qcom_pcie_config_sid_1_9_0(struct qcom_pcie *pcie)
 	u8 qcom_pcie_crc8_table[CRC8_TABLE_SIZE];
 	int i, nr_map, size = 0;
 	u32 smmu_sid_base;
+	u32 val;
 
 	of_get_property(dev->of_node, "iommu-map", &size);
 	if (!size)
 		return 0;
 
+	/* Enable BDF to SID translation by disabling bypass mode (default) */
+	val = readl(pcie->parf + PARF_BDF_TO_SID_CFG);
+	val &= ~BDF_TO_SID_BYPASS;
+	writel(val, pcie->parf + PARF_BDF_TO_SID_CFG);
+
 	map = kzalloc(size, GFP_KERNEL);
 	if (!map)
 		return -ENOMEM;




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux