msm: smd_pkt: Verify edge during probe operation
Verify that both the platform id (SMD port edge) and the platform name
(SMD port name) match during driver binding to prevent registering for
the correct SMD port name, but the wrong SMD port edge.
An SMD Port can be uniquely identified in the system by its name and
edge and both of these must match for binding to ensure that the correct
port is being opened. Without this check, the driver could potentially
attach to the wrong processor resulting in undefined behavior.
Change-Id: I8a10d35f6462784f0b79a8cceee9ac92abb9e87a
Signed-off-by: Eric Holmberg <eholmber@codeaurora.org>
Signed-off-by: Karthikeyan Ramasubramanian <kramasub@codeaurora.org>
diff --git a/arch/arm/mach-msm/smd_pkt.c b/arch/arm/mach-msm/smd_pkt.c
index 8d567f8..b6f74f9 100644
--- a/arch/arm/mach-msm/smd_pkt.c
+++ b/arch/arm/mach-msm/smd_pkt.c
@@ -43,6 +43,7 @@
#define NUM_SMD_PKT_PORTS 15
#endif
+#define PDRIVER_NAME_MAX_SIZE 32
#define LOOPBACK_INX (NUM_SMD_PKT_PORTS - 1)
#define DEVICE_NAME "smdpkt"
@@ -52,6 +53,7 @@
struct cdev cdev;
struct device *devicep;
void *pil;
+ char pdriver_name[PDRIVER_NAME_MAX_SIZE];
struct platform_driver driver;
struct smd_channel *ch;
@@ -729,7 +731,10 @@
int i;
for (i = 0; i < NUM_SMD_PKT_PORTS; i++) {
- if (!strncmp(pdev->name, smd_ch_name[i], SMD_MAX_CH_NAME_LEN)) {
+ if (smd_ch_edge[i] == pdev->id
+ && !strncmp(pdev->name, smd_ch_name[i],
+ SMD_MAX_CH_NAME_LEN)
+ && smd_pkt_devp[i]->driver.probe) {
complete_all(&smd_pkt_devp[i]->ch_allocated);
D_STATUS("%s allocated SMD ch for smd_pkt_dev id:%d\n",
__func__, i);
@@ -772,8 +777,10 @@
if (smd_pkt_devp->ch == 0) {
init_completion(&smd_pkt_devp->ch_allocated);
smd_pkt_devp->driver.probe = smd_pkt_dummy_probe;
- smd_pkt_devp->driver.driver.name =
- smd_ch_name[smd_pkt_devp->i];
+ scnprintf(smd_pkt_devp->pdriver_name, PDRIVER_NAME_MAX_SIZE,
+ "%s.%d", smd_ch_name[smd_pkt_devp->i],
+ smd_ch_edge[smd_pkt_devp->i]);
+ smd_pkt_devp->driver.driver.name = smd_pkt_devp->pdriver_name;
smd_pkt_devp->driver.driver.owner = THIS_MODULE;
r = platform_driver_register(&smd_pkt_devp->driver);
if (r) {
@@ -870,8 +877,10 @@
pil_put(smd_pkt_devp->pil);
release_pd:
- if (r < 0)
+ if (r < 0) {
platform_driver_unregister(&smd_pkt_devp->driver);
+ smd_pkt_devp->driver.probe = NULL;
+ }
out:
mutex_unlock(&smd_pkt_devp->ch_lock);
@@ -904,6 +913,7 @@
smd_pkt_devp->blocking_write = 0;
smd_pkt_devp->poll_mode = 0;
platform_driver_unregister(&smd_pkt_devp->driver);
+ smd_pkt_devp->driver.probe = NULL;
if (smd_pkt_devp->pil)
pil_put(smd_pkt_devp->pil);
}