diff options
author | Hiroshi DOYU <Hiroshi.DOYU@nokia.com> | 2010-05-06 11:24:04 -0400 |
---|---|---|
committer | Hiroshi DOYU <Hiroshi.DOYU@nokia.com> | 2010-05-14 03:23:39 -0400 |
commit | 4abb761749abfb4ec403e4054f9dae2ee604e54f (patch) | |
tree | 9d1be52063ff53ef48be7d769db1c2153a31aa29 /arch | |
parent | e0a42e4fcb6bf9f93c7e63246738333040263e3e (diff) |
omap iommu: Reject unaligned addresses at setting page table entry
This rejects unaligned device virtual address('da') and physical
address('pa') and informs error to caller when a page table entry is
set. Otherwise, a wrong address can be used by IO device.
Signed-off-by: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
Cc: Hari Kanigeri <h-kanigeri2@ti.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/plat-omap/iommu.c | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/arch/arm/plat-omap/iommu.c b/arch/arm/plat-omap/iommu.c index 9598d40e2763..bc094dbacee6 100644 --- a/arch/arm/plat-omap/iommu.c +++ b/arch/arm/plat-omap/iommu.c | |||
@@ -516,6 +516,12 @@ static int iopgd_alloc_section(struct iommu *obj, u32 da, u32 pa, u32 prot) | |||
516 | { | 516 | { |
517 | u32 *iopgd = iopgd_offset(obj, da); | 517 | u32 *iopgd = iopgd_offset(obj, da); |
518 | 518 | ||
519 | if ((da | pa) & ~IOSECTION_MASK) { | ||
520 | dev_err(obj->dev, "%s: %08x:%08x should aligned on %08lx\n", | ||
521 | __func__, da, pa, IOSECTION_SIZE); | ||
522 | return -EINVAL; | ||
523 | } | ||
524 | |||
519 | *iopgd = (pa & IOSECTION_MASK) | prot | IOPGD_SECTION; | 525 | *iopgd = (pa & IOSECTION_MASK) | prot | IOPGD_SECTION; |
520 | flush_iopgd_range(iopgd, iopgd); | 526 | flush_iopgd_range(iopgd, iopgd); |
521 | return 0; | 527 | return 0; |
@@ -526,6 +532,12 @@ static int iopgd_alloc_super(struct iommu *obj, u32 da, u32 pa, u32 prot) | |||
526 | u32 *iopgd = iopgd_offset(obj, da); | 532 | u32 *iopgd = iopgd_offset(obj, da); |
527 | int i; | 533 | int i; |
528 | 534 | ||
535 | if ((da | pa) & ~IOSUPER_MASK) { | ||
536 | dev_err(obj->dev, "%s: %08x:%08x should aligned on %08lx\n", | ||
537 | __func__, da, pa, IOSUPER_SIZE); | ||
538 | return -EINVAL; | ||
539 | } | ||
540 | |||
529 | for (i = 0; i < 16; i++) | 541 | for (i = 0; i < 16; i++) |
530 | *(iopgd + i) = (pa & IOSUPER_MASK) | prot | IOPGD_SUPER; | 542 | *(iopgd + i) = (pa & IOSUPER_MASK) | prot | IOPGD_SUPER; |
531 | flush_iopgd_range(iopgd, iopgd + 15); | 543 | flush_iopgd_range(iopgd, iopgd + 15); |
@@ -555,6 +567,12 @@ static int iopte_alloc_large(struct iommu *obj, u32 da, u32 pa, u32 prot) | |||
555 | u32 *iopte = iopte_alloc(obj, iopgd, da); | 567 | u32 *iopte = iopte_alloc(obj, iopgd, da); |
556 | int i; | 568 | int i; |
557 | 569 | ||
570 | if ((da | pa) & ~IOLARGE_MASK) { | ||
571 | dev_err(obj->dev, "%s: %08x:%08x should aligned on %08lx\n", | ||
572 | __func__, da, pa, IOLARGE_SIZE); | ||
573 | return -EINVAL; | ||
574 | } | ||
575 | |||
558 | if (IS_ERR(iopte)) | 576 | if (IS_ERR(iopte)) |
559 | return PTR_ERR(iopte); | 577 | return PTR_ERR(iopte); |
560 | 578 | ||