summaryrefslogtreecommitdiff
path: root/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c')
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c82
1 files changed, 74 insertions, 8 deletions
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c
index c07ded8f54a0..9c2bae63da7a 100644
--- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c
@@ -869,6 +869,60 @@ _UnmapUserLogical(
#endif
}
+gceSTATUS
+_QueryProcessPageTable(
+ IN gctPOINTER Logical,
+ OUT gctUINT32 * Address
+ )
+{
+ spinlock_t *lock;
+ gctUINTPTR_T logical = (gctUINTPTR_T)Logical;
+ pgd_t *pgd;
+ pud_t *pud;
+ pmd_t *pmd;
+ pte_t *pte;
+
+ if (!current->mm)
+ {
+ return gcvSTATUS_NOT_FOUND;
+ }
+
+ pgd = pgd_offset(current->mm, logical);
+ if (pgd_none(*pgd) || pgd_bad(*pgd))
+ {
+ return gcvSTATUS_NOT_FOUND;
+ }
+
+ pud = pud_offset(pgd, logical);
+ if (pud_none(*pud) || pud_bad(*pud))
+ {
+ return gcvSTATUS_NOT_FOUND;
+ }
+
+ pmd = pmd_offset(pud, logical);
+ if (pmd_none(*pmd) || pmd_bad(*pmd))
+ {
+ return gcvSTATUS_NOT_FOUND;
+ }
+
+ pte = pte_offset_map_lock(current->mm, pmd, logical, &lock);
+ if (!pte)
+ {
+ return gcvSTATUS_NOT_FOUND;
+ }
+
+ if (!pte_present(*pte))
+ {
+ pte_unmap_unlock(pte, lock);
+ return gcvSTATUS_NOT_FOUND;
+ }
+
+ *Address = (pte_pfn(*pte) << PAGE_SHIFT) | (logical & ~PAGE_MASK);
+ pte_unmap_unlock(pte, lock);
+
+ return gcvSTATUS_OK;
+}
+
/*******************************************************************************
**
** gckOS_Construct
@@ -1106,6 +1160,9 @@ _CreateKernelVirtualMapping(
numPages,
0,
PAGE_KERNEL);
+
+ /* Trigger a page fault. */
+ memset(addr, 0, numPages * PAGE_SIZE);
}
#else
struct page ** pages;
@@ -1136,6 +1193,9 @@ _CreateKernelVirtualMapping(
/* ioremap() can't work on system memory since 2.6.38. */
addr = vmap(pages, numPages, 0, gcmkNONPAGED_MEMROY_PROT(PAGE_KERNEL));
+ /* Trigger a page fault. */
+ memset(addr, 0, numPages * PAGE_SIZE);
+
if (free)
{
kfree(pages);
@@ -1540,7 +1600,7 @@ gckOS_MapMemory(
#else
#if !gcdPAGED_MEMORY_CACHEABLE
mdlMap->vma->vm_page_prot = gcmkPAGED_MEMROY_PROT(mdlMap->vma->vm_page_prot);
- mdlMap->vma->vm_flags |= VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_RESERVED;
+ mdlMap->vma->vm_flags |= gcdVM_FLAGS;
# endif
mdlMap->vma->vm_pgoff = 0;
@@ -1987,7 +2047,7 @@ gckOS_AllocateNonPagedMemory(
}
#else
mdlMap->vma->vm_page_prot = gcmkNONPAGED_MEMROY_PROT(mdlMap->vma->vm_page_prot);
- mdlMap->vma->vm_flags |= VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_RESERVED;
+ mdlMap->vma->vm_flags |= gcdVM_FLAGS;
mdlMap->vma->vm_pgoff = 0;
if (remap_pfn_range(mdlMap->vma,
@@ -2367,12 +2427,18 @@ gckOS_GetPhysicalAddress(
gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
gcmkVERIFY_ARGUMENT(Address != gcvNULL);
- /* Get current process ID. */
- processID = _GetProcessID();
+ /* Query page table of current process first. */
+ status = _QueryProcessPageTable(Logical, Address);
- /* Route through other function. */
- gcmkONERROR(
- gckOS_GetPhysicalAddressProcess(Os, Logical, processID, Address));
+ if (gcmIS_ERROR(status))
+ {
+ /* Get current process ID. */
+ processID = _GetProcessID();
+
+ /* Route through other function. */
+ gcmkONERROR(
+ gckOS_GetPhysicalAddressProcess(Os, Logical, processID, Address));
+ }
/* Success. */
gcmkFOOTER_ARG("*Address=0x%08x", *Address);
@@ -4139,7 +4205,7 @@ gckOS_LockPages(
return gcvSTATUS_OUT_OF_RESOURCES;
}
- mdlMap->vma->vm_flags |= VM_RESERVED;
+ mdlMap->vma->vm_flags |= gcdVM_FLAGS;
#if !gcdPAGED_MEMORY_CACHEABLE
if (Cacheable == gcvFALSE)
{