From 4abb761749abfb4ec403e4054f9dae2ee604e54f Mon Sep 17 00:00:00 2001 From: Hiroshi DOYU Date: Thu, 6 May 2010 18:24:04 +0300 Subject: [PATCH] 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 Cc: Hari Kanigeri --- arch/arm/plat-omap/iommu.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) 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);