diff options
author | Hiroshi DOYU <Hiroshi.DOYU@nokia.com> | 2010-05-06 19:24:04 +0400 |
---|---|---|
committer | Hiroshi DOYU <Hiroshi.DOYU@nokia.com> | 2010-05-14 11:23:39 +0400 |
commit | 4abb761749abfb4ec403e4054f9dae2ee604e54f (patch) | |
tree | 9d1be52063ff53ef48be7d769db1c2153a31aa29 /arch/arm/plat-omap | |
parent | e0a42e4fcb6bf9f93c7e63246738333040263e3e (diff) | |
download | linux-4abb761749abfb4ec403e4054f9dae2ee604e54f.tar.xz |
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/arm/plat-omap')
-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) { u32 *iopgd = iopgd_offset(obj, da); + if ((da | pa) & ~IOSECTION_MASK) { + dev_err(obj->dev, "%s: %08x:%08x should aligned on %08lx\n", + __func__, da, pa, IOSECTION_SIZE); + return -EINVAL; + } + *iopgd = (pa & IOSECTION_MASK) | prot | IOPGD_SECTION; flush_iopgd_range(iopgd, iopgd); return 0; @@ -526,6 +532,12 @@ static int iopgd_alloc_super(struct iommu *obj, u32 da, u32 pa, u32 prot) u32 *iopgd = iopgd_offset(obj, da); int i; + if ((da | pa) & ~IOSUPER_MASK) { + dev_err(obj->dev, "%s: %08x:%08x should aligned on %08lx\n", + __func__, da, pa, IOSUPER_SIZE); + return -EINVAL; + } + for (i = 0; i < 16; i++) *(iopgd + i) = (pa & IOSUPER_MASK) | prot | IOPGD_SUPER; flush_iopgd_range(iopgd, iopgd + 15); @@ -555,6 +567,12 @@ static int iopte_alloc_large(struct iommu *obj, u32 da, u32 pa, u32 prot) u32 *iopte = iopte_alloc(obj, iopgd, da); int i; + if ((da | pa) & ~IOLARGE_MASK) { + dev_err(obj->dev, "%s: %08x:%08x should aligned on %08lx\n", + __func__, da, pa, IOLARGE_SIZE); + return -EINVAL; + } + if (IS_ERR(iopte)) return PTR_ERR(iopte); |