Commit bc3ac9f31642fb4697b313c2eb575c5286f35c2a

Authored by Sekhar Nori
Committed by Kevin Hilman
1 parent f027512db7

davinci: edma: provide ability to detect insufficient CC info data

This patch modifies the EDMA driver to expect the channel
controller (CC) infomation passed on by the platform as a fixed
size (EDMA_MAX_CC) array of pointers to structures.

Doing so helps catch errors of the sort where the resource
structure has information for more channel controllers than
the number channel controller info structures defined.

Such insufficient platform data would lead to illegal memory
accesses.

Signed-off-by: Sekhar Nori <nsekhar@ti.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>

Showing 8 changed files with 92 additions and 74 deletions Side-by-side Diff

arch/arm/mach-davinci/devices-da8xx.c
... ... @@ -111,19 +111,21 @@
111 111 {-1, -1}
112 112 };
113 113  
114   -static struct edma_soc_info da830_edma_info[] = {
115   - {
116   - .n_channel = 32,
117   - .n_region = 4,
118   - .n_slot = 128,
119   - .n_tc = 2,
120   - .n_cc = 1,
121   - .queue_tc_mapping = da8xx_queue_tc_mapping,
122   - .queue_priority_mapping = da8xx_queue_priority_mapping,
123   - },
  114 +static struct edma_soc_info da830_edma_cc0_info = {
  115 + .n_channel = 32,
  116 + .n_region = 4,
  117 + .n_slot = 128,
  118 + .n_tc = 2,
  119 + .n_cc = 1,
  120 + .queue_tc_mapping = da8xx_queue_tc_mapping,
  121 + .queue_priority_mapping = da8xx_queue_priority_mapping,
124 122 };
125 123  
126   -static struct edma_soc_info da850_edma_info[] = {
  124 +static struct edma_soc_info *da830_edma_info[EDMA_MAX_CC] = {
  125 + &da830_edma_cc0_info,
  126 +};
  127 +
  128 +static struct edma_soc_info da850_edma_cc_info[] = {
127 129 {
128 130 .n_channel = 32,
129 131 .n_region = 4,
... ... @@ -142,6 +144,11 @@
142 144 .queue_tc_mapping = da850_queue_tc_mapping,
143 145 .queue_priority_mapping = da850_queue_priority_mapping,
144 146 },
  147 +};
  148 +
  149 +static struct edma_soc_info *da850_edma_info[EDMA_MAX_CC] = {
  150 + &da850_edma_cc_info[0],
  151 + &da850_edma_cc_info[1],
145 152 };
146 153  
147 154 static struct resource da830_edma_resources[] = {
arch/arm/mach-davinci/devices-tnetv107x.c
... ... @@ -69,18 +69,20 @@
69 69 { -1, -1 }
70 70 };
71 71  
72   -static struct edma_soc_info edma_info[] = {
73   - {
74   - .n_channel = EDMA_TNETV107X_NUM_DMACH,
75   - .n_region = EDMA_TNETV107X_NUM_REGIONS,
76   - .n_slot = EDMA_TNETV107X_NUM_PARAMENTRY,
77   - .n_tc = EDMA_TNETV107X_NUM_TC,
78   - .n_cc = 1,
79   - .queue_tc_mapping = edma_tc_mapping,
80   - .queue_priority_mapping = edma_priority_mapping,
81   - },
  72 +static struct edma_soc_info edma_cc0_info = {
  73 + .n_channel = EDMA_TNETV107X_NUM_DMACH,
  74 + .n_region = EDMA_TNETV107X_NUM_REGIONS,
  75 + .n_slot = EDMA_TNETV107X_NUM_PARAMENTRY,
  76 + .n_tc = EDMA_TNETV107X_NUM_TC,
  77 + .n_cc = 1,
  78 + .queue_tc_mapping = edma_tc_mapping,
  79 + .queue_priority_mapping = edma_priority_mapping,
82 80 };
83 81  
  82 +static struct edma_soc_info *tnetv107x_edma_info[EDMA_MAX_CC] = {
  83 + &edma_cc0_info,
  84 +};
  85 +
84 86 static struct resource edma_resources[] = {
85 87 {
86 88 .name = "edma_cc0",
... ... @@ -117,7 +119,7 @@
117 119 .id = -1,
118 120 .num_resources = ARRAY_SIZE(edma_resources),
119 121 .resource = edma_resources,
120   - .dev.platform_data = edma_info,
  122 + .dev.platform_data = tnetv107x_edma_info,
121 123 };
122 124  
123 125 static struct plat_serial8250_port serial_data[] = {
arch/arm/mach-davinci/dm355.c
... ... @@ -591,16 +591,18 @@
591 591 {-1, -1},
592 592 };
593 593  
594   -static struct edma_soc_info dm355_edma_info[] = {
595   - {
596   - .n_channel = 64,
597   - .n_region = 4,
598   - .n_slot = 128,
599   - .n_tc = 2,
600   - .n_cc = 1,
601   - .queue_tc_mapping = queue_tc_mapping,
602   - .queue_priority_mapping = queue_priority_mapping,
603   - },
  594 +static struct edma_soc_info edma_cc0_info = {
  595 + .n_channel = 64,
  596 + .n_region = 4,
  597 + .n_slot = 128,
  598 + .n_tc = 2,
  599 + .n_cc = 1,
  600 + .queue_tc_mapping = queue_tc_mapping,
  601 + .queue_priority_mapping = queue_priority_mapping,
  602 +};
  603 +
  604 +static struct edma_soc_info *dm355_edma_info[EDMA_MAX_CC] = {
  605 + &edma_cc0_info,
604 606 };
605 607  
606 608 static struct resource edma_resources[] = {
arch/arm/mach-davinci/dm365.c
... ... @@ -822,17 +822,19 @@
822 822 {-1, -1},
823 823 };
824 824  
825   -static struct edma_soc_info dm365_edma_info[] = {
826   - {
827   - .n_channel = 64,
828   - .n_region = 4,
829   - .n_slot = 256,
830   - .n_tc = 4,
831   - .n_cc = 1,
832   - .queue_tc_mapping = dm365_queue_tc_mapping,
833   - .queue_priority_mapping = dm365_queue_priority_mapping,
834   - .default_queue = EVENTQ_3,
835   - },
  825 +static struct edma_soc_info edma_cc0_info = {
  826 + .n_channel = 64,
  827 + .n_region = 4,
  828 + .n_slot = 256,
  829 + .n_tc = 4,
  830 + .n_cc = 1,
  831 + .queue_tc_mapping = dm365_queue_tc_mapping,
  832 + .queue_priority_mapping = dm365_queue_priority_mapping,
  833 + .default_queue = EVENTQ_3,
  834 +};
  835 +
  836 +static struct edma_soc_info *dm365_edma_info[EDMA_MAX_CC] = {
  837 + &edma_cc0_info,
836 838 };
837 839  
838 840 static struct resource edma_resources[] = {
arch/arm/mach-davinci/dm644x.c
... ... @@ -492,16 +492,18 @@
492 492 {-1, -1},
493 493 };
494 494  
495   -static struct edma_soc_info dm644x_edma_info[] = {
496   - {
497   - .n_channel = 64,
498   - .n_region = 4,
499   - .n_slot = 128,
500   - .n_tc = 2,
501   - .n_cc = 1,
502   - .queue_tc_mapping = queue_tc_mapping,
503   - .queue_priority_mapping = queue_priority_mapping,
504   - },
  495 +static struct edma_soc_info edma_cc0_info = {
  496 + .n_channel = 64,
  497 + .n_region = 4,
  498 + .n_slot = 128,
  499 + .n_tc = 2,
  500 + .n_cc = 1,
  501 + .queue_tc_mapping = queue_tc_mapping,
  502 + .queue_priority_mapping = queue_priority_mapping,
  503 +};
  504 +
  505 +static struct edma_soc_info *dm644x_edma_info[EDMA_MAX_CC] = {
  506 + &edma_cc0_info,
505 507 };
506 508  
507 509 static struct resource edma_resources[] = {
arch/arm/mach-davinci/dm646x.c
... ... @@ -529,16 +529,18 @@
529 529 {-1, -1},
530 530 };
531 531  
532   -static struct edma_soc_info dm646x_edma_info[] = {
533   - {
534   - .n_channel = 64,
535   - .n_region = 6, /* 0-1, 4-7 */
536   - .n_slot = 512,
537   - .n_tc = 4,
538   - .n_cc = 1,
539   - .queue_tc_mapping = dm646x_queue_tc_mapping,
540   - .queue_priority_mapping = dm646x_queue_priority_mapping,
541   - },
  532 +static struct edma_soc_info edma_cc0_info = {
  533 + .n_channel = 64,
  534 + .n_region = 6, /* 0-1, 4-7 */
  535 + .n_slot = 512,
  536 + .n_tc = 4,
  537 + .n_cc = 1,
  538 + .queue_tc_mapping = dm646x_queue_tc_mapping,
  539 + .queue_priority_mapping = dm646x_queue_priority_mapping,
  540 +};
  541 +
  542 +static struct edma_soc_info *dm646x_edma_info[EDMA_MAX_CC] = {
  543 + &edma_cc0_info,
542 544 };
543 545  
544 546 static struct resource edma_resources[] = {
arch/arm/mach-davinci/dma.c
... ... @@ -99,9 +99,7 @@
99 99  
100 100 #define EDMA_MAX_DMACH 64
101 101 #define EDMA_MAX_PARAMENTRY 512
102   -#define EDMA_MAX_CC 2
103 102  
104   -
105 103 /*****************************************************************************/
106 104  
107 105 static void __iomem *edmacc_regs_base[EDMA_MAX_CC];
... ... @@ -1376,7 +1374,7 @@
1376 1374  
1377 1375 static int __init edma_probe(struct platform_device *pdev)
1378 1376 {
1379   - struct edma_soc_info *info = pdev->dev.platform_data;
  1377 + struct edma_soc_info **info = pdev->dev.platform_data;
1380 1378 const s8 (*queue_priority_mapping)[2];
1381 1379 const s8 (*queue_tc_mapping)[2];
1382 1380 int i, j, found = 0;
... ... @@ -1395,7 +1393,7 @@
1395 1393 sprintf(res_name, "edma_cc%d", j);
1396 1394 r[j] = platform_get_resource_byname(pdev, IORESOURCE_MEM,
1397 1395 res_name);
1398   - if (!r[j]) {
  1396 + if (!r[j] || !info[j]) {
1399 1397 if (found)
1400 1398 break;
1401 1399 else
1402 1400  
1403 1401  
1404 1402  
... ... @@ -1426,13 +1424,14 @@
1426 1424 }
1427 1425 memset(edma_cc[j], 0, sizeof(struct edma));
1428 1426  
1429   - edma_cc[j]->num_channels = min_t(unsigned, info[j].n_channel,
  1427 + edma_cc[j]->num_channels = min_t(unsigned, info[j]->n_channel,
1430 1428 EDMA_MAX_DMACH);
1431   - edma_cc[j]->num_slots = min_t(unsigned, info[j].n_slot,
  1429 + edma_cc[j]->num_slots = min_t(unsigned, info[j]->n_slot,
1432 1430 EDMA_MAX_PARAMENTRY);
1433   - edma_cc[j]->num_cc = min_t(unsigned, info[j].n_cc, EDMA_MAX_CC);
  1431 + edma_cc[j]->num_cc = min_t(unsigned, info[j]->n_cc,
  1432 + EDMA_MAX_CC);
1434 1433  
1435   - edma_cc[j]->default_queue = info[j].default_queue;
  1434 + edma_cc[j]->default_queue = info[j]->default_queue;
1436 1435 if (!edma_cc[j]->default_queue)
1437 1436 edma_cc[j]->default_queue = EVENTQ_1;
1438 1437  
... ... @@ -1476,8 +1475,8 @@
1476 1475 for (i = 0; i < edma_cc[j]->num_channels; i++)
1477 1476 map_dmach_queue(j, i, EVENTQ_1);
1478 1477  
1479   - queue_tc_mapping = info[j].queue_tc_mapping;
1480   - queue_priority_mapping = info[j].queue_priority_mapping;
  1478 + queue_tc_mapping = info[j]->queue_tc_mapping;
  1479 + queue_priority_mapping = info[j]->queue_priority_mapping;
1481 1480  
1482 1481 /* Event queue to TC mapping */
1483 1482 for (i = 0; queue_tc_mapping[i][0] != -1; i++)
... ... @@ -1496,7 +1495,7 @@
1496 1495 if (edma_read(j, EDMA_CCCFG) & CHMAP_EXIST)
1497 1496 map_dmach_param(j);
1498 1497  
1499   - for (i = 0; i < info[j].n_region; i++) {
  1498 + for (i = 0; i < info[j]->n_region; i++) {
1500 1499 edma_write_array2(j, EDMA_DRAE, i, 0, 0x0);
1501 1500 edma_write_array2(j, EDMA_DRAE, i, 1, 0x0);
1502 1501 edma_write_array(j, EDMA_QRAE, i, 0x0);
arch/arm/mach-davinci/include/mach/edma.h
... ... @@ -230,6 +230,8 @@
230 230 #define EDMA_CONT_PARAMS_FIXED_EXACT 1002
231 231 #define EDMA_CONT_PARAMS_FIXED_NOT_EXACT 1003
232 232  
  233 +#define EDMA_MAX_CC 2
  234 +
233 235 /* alloc/free DMA channels and their dedicated parameter RAM slots */
234 236 int edma_alloc_channel(int channel,
235 237 void (*callback)(unsigned channel, u16 ch_status, void *data),