summaryrefslogtreecommitdiff
path: root/drivers/pci/host
diff options
context:
space:
mode:
authorTony Truong <truong@codeaurora.org>2015-02-27 15:18:31 -0800
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-22 11:09:09 -0700
commit5e37fdc3f1d2f3b6f3057fb3763209e36483566f (patch)
tree3f722e03e8675871002c67ca463c7498b90965f9 /drivers/pci/host
parent3dabd56768212753e48d76bad64f0a82c20c26d3 (diff)
msm: pcie: sanity check when calculating EP CAP offset
When searching for the endpoint's capabilities register, check that the value from the register read is valid. Change-Id: Ia64de3c75618ca0a51aa4588ac97f2fcb26d8829 Signed-off-by: Tony Truong <truong@codeaurora.org>
Diffstat (limited to 'drivers/pci/host')
-rw-r--r--drivers/pci/host/pci-msm.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/drivers/pci/host/pci-msm.c b/drivers/pci/host/pci-msm.c
index 744291eea457..4a53e7eb5a30 100644
--- a/drivers/pci/host/pci-msm.c
+++ b/drivers/pci/host/pci-msm.c
@@ -1057,6 +1057,19 @@ static int msm_pcie_restore_sec_config(struct msm_pcie_dev_t *dev)
return 0;
}
+static inline int msm_pcie_check_align(struct msm_pcie_dev_t *dev,
+ u32 offset)
+{
+ if (offset % 4) {
+ PCIE_ERR(dev,
+ "PCIe: RC%d: offset 0x%x is not correctly aligned\n",
+ dev->rc_idx, offset);
+ return MSM_PCIE_ERROR;
+ }
+
+ return 0;
+}
+
static bool msm_pcie_confirm_linkup(struct msm_pcie_dev_t *dev,
bool check_sw_stts,
bool check_ep)
@@ -2762,6 +2775,9 @@ static void msm_pcie_config_link_state(struct msm_pcie_dev_t *dev)
current_offset = readl_relaxed(dev->conf + PCIE_CAP_PTR_OFFSET) & 0xff;
while (current_offset) {
+ if (msm_pcie_check_align(dev, current_offset))
+ return;
+
val = readl_relaxed(dev->conf + current_offset);
if ((val & 0xff) == PCIE20_CAP_ID) {
ep_link_cap_offset = current_offset + 0x0c;
@@ -2867,6 +2883,9 @@ static void msm_pcie_config_link_state(struct msm_pcie_dev_t *dev)
if (dev->l1ss_supported) {
current_offset = PCIE_EXT_CAP_OFFSET;
while (current_offset) {
+ if (msm_pcie_check_align(dev, current_offset))
+ return;
+
val = readl_relaxed(dev->conf + current_offset);
if ((val & 0xffff) == L1SUB_CAP_ID) {
ep_l1sub_cap_reg1_offset = current_offset + 0x4;
@@ -3506,6 +3525,9 @@ static void msm_pcie_config_ep_aer(struct msm_pcie_dev_t *dev,
0xff;
while (current_offset) {
+ if (msm_pcie_check_align(dev, current_offset))
+ return;
+
val = readl_relaxed(ep_base + current_offset);
if ((val & 0xff) == PCIE20_CAP_ID) {
ep_dev_info->dev_ctrlstts_offset =