mirror of
https://github.com/raspberrypi/linux.git
synced 2025-12-06 10:00:17 +00:00
staging: vc-sm-cma: Fix up for 64bit builds
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>
This commit is contained in:
committed by
Phil Elwell
parent
089ca52135
commit
bf9f5a3dde
@@ -75,6 +75,9 @@ struct sm_state_t {
|
|||||||
struct miscdevice dev;
|
struct miscdevice dev;
|
||||||
struct sm_instance *sm_handle; /* Handle for videocore service. */
|
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 mutex map_lock; /* Global map lock. */
|
||||||
struct list_head buffer_list; /* List of buffer. */
|
struct list_head buffer_list; /* List of buffer. */
|
||||||
|
|
||||||
@@ -97,6 +100,29 @@ static int sm_inited;
|
|||||||
|
|
||||||
/* ---- Private Functions ------------------------------------------------ */
|
/* ---- 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)
|
static int vc_sm_cma_seq_file_show(struct seq_file *s, void *v)
|
||||||
{
|
{
|
||||||
struct sm_pde_t *sm_pde;
|
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)
|
if (!sm_state)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
seq_printf(s, "\nVC-ServiceHandle 0x%x\n",
|
seq_printf(s, "\nVC-ServiceHandle %p\n", sm_state->sm_handle);
|
||||||
(unsigned int)sm_state->sm_handle);
|
|
||||||
|
|
||||||
/* Log all applicable mapping(s). */
|
/* Log all applicable mapping(s). */
|
||||||
|
|
||||||
@@ -145,7 +170,7 @@ static int vc_sm_cma_global_state_show(struct seq_file *s, void *v)
|
|||||||
resource);
|
resource);
|
||||||
seq_printf(s, " NAME %s\n",
|
seq_printf(s, " NAME %s\n",
|
||||||
resource->name);
|
resource->name);
|
||||||
seq_printf(s, " SIZE %d\n",
|
seq_printf(s, " SIZE %zu\n",
|
||||||
resource->size);
|
resource->size);
|
||||||
seq_printf(s, " DMABUF %p\n",
|
seq_printf(s, " DMABUF %p\n",
|
||||||
resource->dma_buf);
|
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);
|
list_add(&buffer->global_buffer_list, &sm_state->buffer_list);
|
||||||
mutex_unlock(&sm_state->map_lock);
|
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);
|
__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(&sm_state->map_lock);
|
||||||
mutex_lock(&buffer->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);
|
__func__, buffer, buffer->name, buffer->size);
|
||||||
|
|
||||||
if (buffer->vc_handle && buffer->vpu_state == VPU_MAPPED) {
|
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 vc_sm_import_result result = { };
|
||||||
struct dma_buf_attachment *attach = NULL;
|
struct dma_buf_attachment *attach = NULL;
|
||||||
struct sg_table *sgt = NULL;
|
struct sg_table *sgt = NULL;
|
||||||
|
dma_addr_t dma_addr;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int status;
|
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.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) {
|
if ((import.addr & 0xC0000000) != 0xC0000000) {
|
||||||
pr_err("%s: Expecting an uncached alias for dma_addr %08x\n",
|
pr_err("%s: Expecting an uncached alias for dma_addr %pad\n",
|
||||||
__func__, import.addr);
|
__func__, &dma_addr);
|
||||||
import.addr |= 0xC0000000;
|
import.addr |= 0xC0000000;
|
||||||
}
|
}
|
||||||
import.size = sg_dma_len(sgt->sgl);
|
import.size = sg_dma_len(sgt->sgl);
|
||||||
import.allocator = current->tgid;
|
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,
|
memcpy(import.name, VC_SM_RESOURCE_NAME_DEFAULT,
|
||||||
sizeof(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",
|
pr_debug("[%s]: attempt to import \"%s\" data - type %u, addr %pad, size %u\n",
|
||||||
__func__, import.name, import.type, (void *)import.addr,
|
__func__, import.name, import.type, &dma_addr,
|
||||||
import.size);
|
import.size);
|
||||||
|
|
||||||
/* Allocate the videocore buffer. */
|
/* Allocate the videocore buffer. */
|
||||||
@@ -527,7 +554,7 @@ vc_sm_cma_import_dmabuf_internal(struct vc_sm_privdata_t *private,
|
|||||||
|
|
||||||
buffer->attach = attach;
|
buffer->attach = attach;
|
||||||
buffer->sgt = sgt;
|
buffer->sgt = sgt;
|
||||||
buffer->dma_addr = sg_dma_address(sgt->sgl);
|
buffer->dma_addr = dma_addr;
|
||||||
buffer->in_use = 1;
|
buffer->in_use = 1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -559,6 +586,7 @@ error:
|
|||||||
vc_sm_cma_vchi_free(sm_state->sm_handle, &free,
|
vc_sm_cma_vchi_free(sm_state->sm_handle, &free,
|
||||||
&sm_state->int_trans_id);
|
&sm_state->int_trans_id);
|
||||||
}
|
}
|
||||||
|
free_kernel_id(import.kernel_id);
|
||||||
kfree(buffer);
|
kfree(buffer);
|
||||||
if (sgt)
|
if (sgt)
|
||||||
dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL);
|
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_released *release = (struct vc_sm_released *)reply;
|
||||||
struct vc_sm_buffer *buffer =
|
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
|
* 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->vc_handle = 0;
|
||||||
buffer->vpu_state = VPU_NOT_MAPPED;
|
buffer->vpu_state = VPU_NOT_MAPPED;
|
||||||
mutex_unlock(&buffer->lock);
|
mutex_unlock(&buffer->lock);
|
||||||
|
free_kernel_id(release->kernel_id);
|
||||||
|
|
||||||
vc_sm_release_resource(buffer, 0);
|
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;
|
sm_state->pdev = pdev;
|
||||||
mutex_init(&sm_state->map_lock);
|
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,
|
pdev->dev.dma_parms = devm_kzalloc(&pdev->dev,
|
||||||
sizeof(*pdev->dev.dma_parms),
|
sizeof(*pdev->dev.dma_parms),
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
@@ -735,6 +767,8 @@ static int bcm2835_vc_sm_cma_remove(struct platform_device *pdev)
|
|||||||
/* Stop the videocore shared memory service. */
|
/* Stop the videocore shared memory service. */
|
||||||
vc_sm_cma_vchi_stop(&sm_state->sm_handle);
|
vc_sm_cma_vchi_stop(&sm_state->sm_handle);
|
||||||
|
|
||||||
|
idr_destroy(&sm_state->kernelid_map);
|
||||||
|
|
||||||
/* Free the memory for the state structure. */
|
/* Free the memory for the state structure. */
|
||||||
mutex_destroy(&sm_state->map_lock);
|
mutex_destroy(&sm_state->map_lock);
|
||||||
kfree(sm_state);
|
kfree(sm_state);
|
||||||
|
|||||||
@@ -351,8 +351,7 @@ struct sm_instance *vc_sm_cma_vchi_init(VCHI_INSTANCE_T vchi_instance,
|
|||||||
set_user_nice(instance->io_thread, -10);
|
set_user_nice(instance->io_thread, -10);
|
||||||
wake_up_process(instance->io_thread);
|
wake_up_process(instance->io_thread);
|
||||||
|
|
||||||
pr_debug("%s: success - instance 0x%x", __func__,
|
pr_debug("%s: success - instance %p", __func__, instance);
|
||||||
(unsigned int)instance);
|
|
||||||
return instance;
|
return instance;
|
||||||
|
|
||||||
err_close_services:
|
err_close_services:
|
||||||
|
|||||||
Reference in New Issue
Block a user