vcsm: Provide flag to map pages up front
authorpopcornmix <popcornmix@gmail.com>
Fri, 18 Aug 2017 17:45:36 +0000 (18:45 +0100)
committerRaspbian kernel package updater <root@raspbian.org>
Sun, 8 Oct 2017 01:08:26 +0000 (01:08 +0000)
drivers/char/broadcom/vc_sm/vmcs_sm.c

index ee4e05948c439a9045e0b65566d57587177a32e2..7d417214f4288cb24e6f20c840aef1b69dc9eb0b 100644 (file)
@@ -142,6 +142,7 @@ struct SM_RESOURCE_T {
        struct list_head map_list;      /* Maps associated with a resource. */
 
        struct SM_PRIV_DATA_T *private;
+       bool map;               /* whether to map pages up front */
 };
 
 /* Private file data associated with each opened device.
@@ -1376,6 +1377,20 @@ static int vc_sm_mmap(struct file *file, struct vm_area_struct *vma)
        vcsm_vma_open(vma);
        resource->res_stats[MAP]++;
        vmcs_sm_release_resource(resource, 0);
+
+       if (resource->map) {
+               /* We don't use vmf->pgoff since that has the fake offset */
+               unsigned long addr;
+               for (addr = vma->vm_start; addr < vma->vm_end; addr += PAGE_SIZE) {
+                       /* Finally, remap it */
+                       unsigned long pfn = (unsigned long)resource->res_base_mem & 0x3FFFFFFF;
+                       pfn += mm_vc_mem_phys_addr;
+                       pfn += addr - vma->vm_start;
+                       pfn >>= PAGE_SHIFT;
+                       ret = vm_insert_pfn(vma, addr, pfn);
+               }
+       }
+
        return 0;
 
 error:
@@ -1394,10 +1409,18 @@ int vc_sm_ioctl_alloc(struct SM_PRIV_DATA_T *private,
        struct SM_RESOURCE_T *resource;
        VC_SM_ALLOC_T alloc = { 0 };
        VC_SM_ALLOC_RESULT_T result = { 0 };
+       enum vmcs_sm_cache_e cached = ioparam->cached;
+       bool map = false;
+
+       /* flag to requst buffer is mapped up front, rather than lazily */
+       if (cached & 0x80 ) {
+               map = true;
+               cached &= ~0x80;
+       }
 
        /* Setup our allocation parameters */
-       alloc.type = ((ioparam->cached == VMCS_SM_CACHE_VC)
-                     || (ioparam->cached ==
+       alloc.type = ((cached == VMCS_SM_CACHE_VC)
+                     || (cached ==
                          VMCS_SM_CACHE_BOTH)) ? VC_SM_ALLOC_CACHED :
            VC_SM_ALLOC_NON_CACHED;
        alloc.base_unit = ioparam->size;
@@ -1455,7 +1478,8 @@ int vc_sm_ioctl_alloc(struct SM_PRIV_DATA_T *private,
        resource->res_handle = result.res_handle;
        resource->res_base_mem = result.res_mem;
        resource->res_size = alloc.base_unit * alloc.num_unit;
-       resource->res_cached = ioparam->cached;
+       resource->res_cached = cached;
+       resource->map = map;
 
        /* Kernel/user GUID.  This global identifier is used for mmap'ing the
         * allocated region from user space, it is passed as the mmap'ing