staging: vc-sm-cma: Fix up for 64bit builds
authorDave Stevenson <dave.stevenson@raspberrypi.org>
Tue, 29 Jan 2019 16:32:57 +0000 (16:32 +0000)
committerpopcornmix <popcornmix@gmail.com>
Mon, 13 May 2019 23:08:20 +0000 (00:08 +0100)
There were a number of logging lines that were using
inappropriate formatting under 64bit kernels.

The kernel_id field passed to/from the VPU was being
abused for storing the struct vc_sm_buffer *.
This breaks with 64bit kernels, so change to using an IDR.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org>
drivers/staging/vc04_services/vc-sm-cma/vc_sm.c
drivers/staging/vc04_services/vc-sm-cma/vc_sm_cma_vchi.c

index 84cab85..7ac6b80 100644 (file)
@@ -75,6 +75,9 @@ struct sm_state_t {
        struct miscdevice dev;
        struct sm_instance *sm_handle;  /* Handle for videocore service. */
 
+       spinlock_t kernelid_map_lock;   /* Spinlock protecting kernelid_map */
+       struct idr kernelid_map;
+
        struct mutex map_lock;          /* Global map lock. */
        struct list_head buffer_list;   /* List of buffer. */
 
@@ -97,6 +100,29 @@ static int sm_inited;
 
 /* ---- Private Functions ------------------------------------------------ */
 
+static int get_kernel_id(struct vc_sm_buffer *buffer)
+{
+       int handle;
+
+       spin_lock(&sm_state->kernelid_map_lock);
+       handle = idr_alloc(&sm_state->kernelid_map, buffer, 0, 0, GFP_KERNEL);
+       spin_unlock(&sm_state->kernelid_map_lock);
+
+       return handle;
+}
+
+static struct vc_sm_buffer *lookup_kernel_id(int handle)
+{
+       return idr_find(&sm_state->kernelid_map, handle);
+}
+
+static void free_kernel_id(int handle)
+{
+       spin_lock(&sm_state->kernelid_map_lock);
+       idr_remove(&sm_state->kernelid_map, handle);
+       spin_unlock(&sm_state->kernelid_map_lock);
+}
+
 static int vc_sm_cma_seq_file_show(struct seq_file *s, void *v)
 {
        struct sm_pde_t *sm_pde;
@@ -129,8 +155,7 @@ static int vc_sm_cma_global_state_show(struct seq_file *s, void *v)
        if (!sm_state)
                return 0;
 
-       seq_printf(s, "\nVC-ServiceHandle     0x%x\n",
-                  (unsigned int)sm_state->sm_handle);
+       seq_printf(s, "\nVC-ServiceHandle     %p\n", sm_state->sm_handle);
 
        /* Log all applicable mapping(s). */
 
@@ -145,7 +170,7 @@ static int vc_sm_cma_global_state_show(struct seq_file *s, void *v)
                                   resource);
                        seq_printf(s, "           NAME         %s\n",
                                   resource->name);
-                       seq_printf(s, "           SIZE         %d\n",
+                       seq_printf(s, "           SIZE         %zu\n",
                                   resource->size);
                        seq_printf(s, "           DMABUF       %p\n",
                                   resource->dma_buf);
@@ -181,7 +206,7 @@ static void vc_sm_add_resource(struct vc_sm_privdata_t *privdata,
        list_add(&buffer->global_buffer_list, &sm_state->buffer_list);
        mutex_unlock(&sm_state->map_lock);
 
-       pr_debug("[%s]: added buffer %p (name %s, size %d)\n",
+       pr_debug("[%s]: added buffer %p (name %s, size %zu)\n",
                 __func__, buffer, buffer->name, buffer->size);
 }
 
@@ -194,7 +219,7 @@ static void vc_sm_release_resource(struct vc_sm_buffer *buffer, int force)
        mutex_lock(&sm_state->map_lock);
        mutex_lock(&buffer->lock);
 
-       pr_debug("[%s]: buffer %p (name %s, size %d)\n",
+       pr_debug("[%s]: buffer %p (name %s, size %zu)\n",
                 __func__, buffer, buffer->name, buffer->size);
 
        if (buffer->vc_handle && buffer->vpu_state == VPU_MAPPED) {
@@ -443,6 +468,7 @@ vc_sm_cma_import_dmabuf_internal(struct vc_sm_privdata_t *private,
        struct vc_sm_import_result result = { };
        struct dma_buf_attachment *attach = NULL;
        struct sg_table *sgt = NULL;
+       dma_addr_t dma_addr;
        int ret = 0;
        int status;
 
@@ -478,21 +504,22 @@ vc_sm_cma_import_dmabuf_internal(struct vc_sm_privdata_t *private,
        }
 
        import.type = VC_SM_ALLOC_NON_CACHED;
-       import.addr = (uint32_t)sg_dma_address(sgt->sgl);
+       dma_addr = sg_dma_address(sgt->sgl);
+       import.addr = (uint32_t)dma_addr;
        if ((import.addr & 0xC0000000) != 0xC0000000) {
-               pr_err("%s: Expecting an uncached alias for dma_addr %08x\n",
-                      __func__, import.addr);
+               pr_err("%s: Expecting an uncached alias for dma_addr %pad\n",
+                      __func__, &dma_addr);
                import.addr |= 0xC0000000;
        }
        import.size = sg_dma_len(sgt->sgl);
        import.allocator = current->tgid;
-       import.kernel_id = (uint32_t)buffer;    //FIXME: 64 bit support needed.
+       import.kernel_id = get_kernel_id(buffer);
 
        memcpy(import.name, VC_SM_RESOURCE_NAME_DEFAULT,
               sizeof(VC_SM_RESOURCE_NAME_DEFAULT));
 
-       pr_debug("[%s]: attempt to import \"%s\" data - type %u, addr %p, size %u\n",
-                __func__, import.name, import.type, (void *)import.addr,
+       pr_debug("[%s]: attempt to import \"%s\" data - type %u, addr %pad, size %u\n",
+                __func__, import.name, import.type, &dma_addr,
                 import.size);
 
        /* Allocate the videocore buffer. */
@@ -527,7 +554,7 @@ vc_sm_cma_import_dmabuf_internal(struct vc_sm_privdata_t *private,
 
        buffer->attach = attach;
        buffer->sgt = sgt;
-       buffer->dma_addr = sg_dma_address(sgt->sgl);
+       buffer->dma_addr = dma_addr;
        buffer->in_use = 1;
 
        /*
@@ -559,6 +586,7 @@ error:
                vc_sm_cma_vchi_free(sm_state->sm_handle, &free,
                                    &sm_state->int_trans_id);
        }
+       free_kernel_id(import.kernel_id);
        kfree(buffer);
        if (sgt)
                dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL);
@@ -586,7 +614,7 @@ vc_sm_vpu_event(struct sm_instance *instance, struct vc_sm_result_t *reply,
        {
                struct vc_sm_released *release = (struct vc_sm_released *)reply;
                struct vc_sm_buffer *buffer =
-                               (struct vc_sm_buffer *)release->kernel_id;
+                                       lookup_kernel_id(release->kernel_id);
 
                /*
                 * FIXME: Need to check buffer is still valid and allocated
@@ -599,6 +627,7 @@ vc_sm_vpu_event(struct sm_instance *instance, struct vc_sm_result_t *reply,
                buffer->vc_handle = 0;
                buffer->vpu_state = VPU_NOT_MAPPED;
                mutex_unlock(&buffer->lock);
+               free_kernel_id(release->kernel_id);
 
                vc_sm_release_resource(buffer, 0);
        }
@@ -711,6 +740,9 @@ static int bcm2835_vc_sm_cma_probe(struct platform_device *pdev)
        sm_state->pdev = pdev;
        mutex_init(&sm_state->map_lock);
 
+       spin_lock_init(&sm_state->kernelid_map_lock);
+       idr_init_base(&sm_state->kernelid_map, 1);
+
        pdev->dev.dma_parms = devm_kzalloc(&pdev->dev,
                                           sizeof(*pdev->dev.dma_parms),
                                           GFP_KERNEL);
@@ -735,6 +767,8 @@ static int bcm2835_vc_sm_cma_remove(struct platform_device *pdev)
                /* Stop the videocore shared memory service. */
                vc_sm_cma_vchi_stop(&sm_state->sm_handle);
 
+               idr_destroy(&sm_state->kernelid_map);
+
                /* Free the memory for the state structure. */
                mutex_destroy(&sm_state->map_lock);
                kfree(sm_state);
index cc5b31a..711f2a3 100644 (file)
@@ -356,8 +356,7 @@ struct sm_instance *vc_sm_cma_vchi_init(VCHI_INSTANCE_T vchi_instance,
        set_user_nice(instance->io_thread, -10);
        wake_up_process(instance->io_thread);
 
-       pr_debug("%s: success - instance 0x%x", __func__,
-                (unsigned int)instance);
+       pr_debug("%s: success - instance %p", __func__, instance);
        return instance;
 
 err_close_services: