summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAchal Verma <achalv@nvidia.com>2020-03-27 07:52:59 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2020-03-31 11:39:03 -0400
commit4313f4cf073dffd094dfb31fe5416dcc32b73462 (patch)
tree2fc36ab35d11086f0ccc412f92d1f7457033c48e
parent92f6db5e541437fbc3cfea3ee3d426c274a16b59 (diff)
pcie-tegra-dw-ep:fix 'out of bound access'
correct range in find_first_bit. This fixes coverity issue: 5755194 Bug 2028892 Change-Id: I73d83aa667290f4b39a7fece92eafbedab572763 Signed-off-by: Achal Verma <achalv@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvidia/+/2319434 Reviewed-by: automaticguardword <automaticguardword@nvidia.com> Reviewed-by: Dmitry Pervushin <dpervushin@nvidia.com> Reviewed-by: Phoenix Jung <pjung@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
-rw-r--r--drivers/pci/ep/pcie-tegra-dw-ep.c27
1 files changed, 26 insertions, 1 deletions
diff --git a/drivers/pci/ep/pcie-tegra-dw-ep.c b/drivers/pci/ep/pcie-tegra-dw-ep.c
index 2ea27adff..d9e599544 100644
--- a/drivers/pci/ep/pcie-tegra-dw-ep.c
+++ b/drivers/pci/ep/pcie-tegra-dw-ep.c
@@ -892,10 +892,29 @@ static void pex_ep_event_hot_rst_done(struct tegra_pcie_dw_ep *pcie)
892 writel(val, pcie->appl_base + APPL_CTRL); 892 writel(val, pcie->appl_base + APPL_CTRL);
893} 893}
894 894
895static inline int find_width_index(unsigned long width)
896{
897 if (width & (width-1))
898 return -1;
899 switch (width) {
900 case PCIE_LNK_X1:
901 return 0;
902 case PCIE_LNK_X2:
903 return 1;
904 case PCIE_LNK_X4:
905 return 2;
906 case PCIE_LNK_X8:
907 return 3;
908 default :
909 return -1;
910 }
911}
912
895static void pex_ep_event_bme_change(struct tegra_pcie_dw_ep *pcie) 913static void pex_ep_event_bme_change(struct tegra_pcie_dw_ep *pcie)
896{ 914{
897 u32 val = 0, speed = 0; 915 u32 val = 0, speed = 0;
898 unsigned long freq, width = 0; 916 unsigned long freq, width = 0;
917 int width_index;
899 918
900 /* If EP doesn't advertise L1SS, just return */ 919 /* If EP doesn't advertise L1SS, just return */
901 val = readl(pcie->dbi_base + pcie->cfg_link_cap_l1sub); 920 val = readl(pcie->dbi_base + pcie->cfg_link_cap_l1sub);
@@ -932,7 +951,13 @@ static void pex_ep_event_bme_change(struct tegra_pcie_dw_ep *pcie)
932 /* Make EMC FLOOR freq request based on link width and speed */ 951 /* Make EMC FLOOR freq request based on link width and speed */
933 val = readl(pcie->dbi_base + CFG_LINK_STATUS_CONTROL); 952 val = readl(pcie->dbi_base + CFG_LINK_STATUS_CONTROL);
934 width = ((val >> 16) & PCI_EXP_LNKSTA_NLW) >> 4; 953 width = ((val >> 16) & PCI_EXP_LNKSTA_NLW) >> 4;
935 width = find_first_bit(&width, sizeof(width)); 954 width_index = find_width_index(width);
955 if (width_index == -1) {
956 dev_err(pcie->dev, "error in %s", __func__);
957 dev_err(pcie->dev, "width in CFG_LINK_STATUS_CONTROL is"
958 "wrong\n");
959 return;
960 }
936 speed = ((val >> 16) & PCI_EXP_LNKSTA_CLS); 961 speed = ((val >> 16) & PCI_EXP_LNKSTA_CLS);
937 freq = pcie->dvfs_tbl[width][speed - 1]; 962 freq = pcie->dvfs_tbl[width][speed - 1];
938 dev_dbg(pcie->dev, "EMC Freq requested = %lu\n", freq); 963 dev_dbg(pcie->dev, "EMC Freq requested = %lu\n", freq);