summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSammy He <r62914@freescale.com>2012-02-14 10:09:05 +0800
committerSammy He <r62914@freescale.com>2012-02-14 12:59:11 +0800
commit95b9c1b0f374328b29018f094b31cece0e72030c (patch)
tree250c197b7b7a4ac300d00ec602b7c0e8ad243b78
parent456c952d54d3f5abbcc0f419cb3454760cb7c123 (diff)
ENGR00174323 vpu: Fix system hang issue of multi-instances processing
VPU registers have been mapped with ioremap() at probe which L_PTE_XN is 1, and the same physical address must be mapped multiple times with same type when doing mmap() to user space, so also need to set it to 1. Otherwise, there may be unexpected result in video codec. Here, Use new defined pgprot_noncachedxn for vm_page_prot in mmap(). Signed-off-by: Sammy He <r62914@freescale.com>
-rw-r--r--drivers/mxc/vpu/mxc_vpu.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/drivers/mxc/vpu/mxc_vpu.c b/drivers/mxc/vpu/mxc_vpu.c
index 0e0e03835e87..20d523aac9e1 100644
--- a/drivers/mxc/vpu/mxc_vpu.c
+++ b/drivers/mxc/vpu/mxc_vpu.c
@@ -45,6 +45,10 @@
#include <mach/mxc_vpu.h>
+/* Define one new pgprot which combined uncached and XN(never executable) */
+#define pgprot_noncachedxn(prot) \
+ __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_UNCACHED | L_PTE_XN)
+
struct vpu_priv {
struct fasync_struct *async_queue;
struct work_struct work;
@@ -511,7 +515,13 @@ static int vpu_map_hwregs(struct file *fp, struct vm_area_struct *vm)
unsigned long pfn;
vm->vm_flags |= VM_IO | VM_RESERVED;
- vm->vm_page_prot = pgprot_noncached(vm->vm_page_prot);
+ /*
+ * Since vpu registers have been mapped with ioremap() at probe
+ * which L_PTE_XN is 1, and the same physical address must be
+ * mapped multiple times with same type, so set L_PTE_XN to 1 here.
+ * Otherwise, there may be unexpected result in video codec.
+ */
+ vm->vm_page_prot = pgprot_noncachedxn(vm->vm_page_prot);
pfn = phy_vpu_base_addr >> PAGE_SHIFT;
pr_debug("size=0x%x, page no.=0x%x\n",
(int)(vm->vm_end - vm->vm_start), (int)pfn);