diff options
author | Andy Gross <andy.gross@ti.com> | 2011-12-19 09:49:58 -0600 |
---|---|---|
committer | Ziyann <jaraidaniel@gmail.com> | 2014-10-01 12:57:24 +0200 |
commit | ca988ca5f01e92761591ba4e688aceed630db794 (patch) | |
tree | 2a734819d0e825c32c6fd67e46d5a34ae953b229 | |
parent | 3c2aa3669bae3e05d79290fc5b4dfd687a69ee4b (diff) | |
download | kernel_samsung_tuna-ca988ca5f01e92761591ba4e688aceed630db794.zip kernel_samsung_tuna-ca988ca5f01e92761591ba4e688aceed630db794.tar.gz kernel_samsung_tuna-ca988ca5f01e92761591ba4e688aceed630db794.tar.bz2 |
OMAP4: TILER: Add variable alignment allocation API
Added tiler_alloc_block_area_aligned API to allow
for variable alignment when allocating when using the kernel
APIs.
Change-Id: I2f3c44675a3fa1b2c6dfef21ccdd9bcac2f1d0e5
Signed-off-by: Andy Gross <andy.gross@ti.com>
Signed-off-by: Tony Zlatinski <x0146664@ti.com>
Signed-off-by: Atanas (Tony) Zlatinski <zlatinski@gmail.com>
-rw-r--r-- | arch/arm/mach-omap2/include/mach/tiler.h | 22 | ||||
-rw-r--r-- | drivers/media/video/tiler/_tiler.h | 44 | ||||
-rw-r--r-- | drivers/media/video/tiler/tiler-iface.c | 94 | ||||
-rw-r--r-- | drivers/media/video/tiler/tiler-ioctl.c | 71 | ||||
-rw-r--r-- | drivers/media/video/tiler/tiler-main.c | 101 | ||||
-rw-r--r-- | drivers/media/video/tiler/tiler-nv12.c | 4 | ||||
-rw-r--r-- | drivers/media/video/tiler/tiler-reserve.c | 8 |
7 files changed, 204 insertions, 140 deletions
diff --git a/arch/arm/mach-omap2/include/mach/tiler.h b/arch/arm/mach-omap2/include/mach/tiler.h index 0fdb6eb..ff2e7eb 100644 --- a/arch/arm/mach-omap2/include/mach/tiler.h +++ b/arch/arm/mach-omap2/include/mach/tiler.h @@ -410,6 +410,28 @@ tiler_blk_handle tiler_alloc_block_area(enum tiler_fmt fmt, u32 width, u32 *virt_array); /** + * Allocate an area of container space in the Tiler with a specific alignment + * and user specified security token + * + * @param fmt Tiler bpp mode + * @param width Width in pixels + * @param height Height in pixels + * @param ssptr Value of tiler physical address of allocation + * @param virt_array Array of physical address for the start of each virtual + page + * @align Alignment in bytes + * @token Security token + * + * @return handle Handle to tiler block information. NULL on error. + * + * NOTE: For 1D allocations, specify the full size in the width field, and + * specify a height of 1. + */ +tiler_blk_handle tiler_alloc_block_area_aligned(enum tiler_fmt fmt, u32 width, + u32 height, u32 *ssptr, u32 *virt_array, u32 align, + u32 token); + +/** * Free a reserved area in the Tiler * * @param handle Handle to tiler block information diff --git a/drivers/media/video/tiler/_tiler.h b/drivers/media/video/tiler/_tiler.h index 9da70d0..784e66b 100644 --- a/drivers/media/video/tiler/_tiler.h +++ b/drivers/media/video/tiler/_tiler.h @@ -45,37 +45,44 @@ #define TILER_FORMATS (TILFMT_MAX - TILFMT_MIN + 1) -/* per process (thread group) info */ -struct process_info { +enum secure_id_type { + SECURE_BY_PID = 0, + SECURE_BY_TOKEN +}; + +/* security info */ +struct security_info { struct list_head list; /* other processes */ struct list_head groups; /* my groups */ struct list_head bufs; /* my registered buffers */ - pid_t pid; /* really: thread group ID */ + int token; /* really: thread group ID or user + provided token */ u32 refs; /* open tiler devices, 0 for processes tracked via kernel APIs */ bool kernel; /* tracking kernel objects */ + enum secure_id_type sec_type; /* security type, by pid or by token */ }; struct __buf_info { - struct list_head by_pid; /* list of buffers per pid */ + struct list_head by_sid; /* list of buffers per sid */ struct tiler_buf_info buf_info; struct mem_info *mi[TILER_MAX_NUM_BLOCKS]; /* blocks */ }; /* per group info (within a process) */ struct gid_info { - struct list_head by_pid; /* other groups */ - struct list_head areas; /* all areas in this pid/gid */ + struct list_head by_sid; /* other groups */ + struct list_head areas; /* all areas in this sid/gid */ struct list_head reserved; /* areas pre-reserved */ - struct list_head onedim; /* all 1D areas in this pid/gid */ + struct list_head onedim; /* all 1D areas in this sid/gid */ u32 gid; /* group ID */ int refs; /* instances directly using this ptr */ - struct process_info *pi; /* parent */ + struct security_info *si; /* parent */ }; /* info for an area reserved from a container */ struct area_info { - struct list_head by_gid; /* areas in this pid/gid */ + struct list_head by_gid; /* areas in this sid/gid */ struct list_head blocks; /* blocks in this area */ u32 nblocks; /* # of blocks in this area */ @@ -111,16 +118,16 @@ struct tiler_ops { /* block operations */ s32 (*alloc) (enum tiler_fmt fmt, u32 width, u32 height, u32 key, - u32 gid, struct process_info *pi, + u32 gid, struct security_info *si, struct mem_info **info); s32 (*pin) (enum tiler_fmt fmt, u32 width, u32 height, - u32 key, u32 gid, struct process_info *pi, + u32 key, u32 gid, struct security_info *si, struct mem_info **info, u32 usr_addr); void (*reserve_nv12) (u32 n, u32 width, u32 height, - u32 gid, struct process_info *pi); + u32 gid, struct security_info *si); void (*reserve) (u32 n, enum tiler_fmt fmt, u32 width, u32 height, - u32 gid, struct process_info *pi); - void (*unreserve) (u32 gid, struct process_info *pi); + u32 gid, struct security_info *si); + void (*unreserve) (u32 gid, struct security_info *si); /* block access operations */ struct mem_info * (*lock) (u32 key, u32 id, struct gid_info *gi); @@ -136,7 +143,7 @@ struct tiler_ops { u8 *p); #endif /* group operations */ - struct gid_info * (*get_gi) (struct process_info *pi, u32 gid); + struct gid_info * (*get_gi) (struct security_info *si, u32 gid); void (*release_gi) (struct gid_info *gi); void (*destroy_group) (struct gid_info *pi); @@ -174,11 +181,10 @@ void tiler_reserve_init(struct tiler_ops *tiler); void tiler_nv12_init(struct tiler_ops *tiler); u32 tiler_best2pack(u16 o, u16 a, u16 b, u16 w, u16 *n, u16 *_area); void tiler_ioctl_init(struct tiler_ops *tiler); -struct process_info *__get_pi(pid_t pid, bool kernel); +struct security_info *__get_si(int token, bool kernel, + enum secure_id_type sec_type); void _m_unregister_buf(struct __buf_info *_b); s32 tiler_notify_event(int event, void *data); -void _m_free_process_info(struct process_info *pi); - -struct process_info *__get_pi(pid_t pid, bool kernel); +void _m_free_security_info(struct security_info *pi); #endif diff --git a/drivers/media/video/tiler/tiler-iface.c b/drivers/media/video/tiler/tiler-iface.c index b7d84d5..8d81f91 100644 --- a/drivers/media/video/tiler/tiler-iface.c +++ b/drivers/media/video/tiler/tiler-iface.c @@ -33,20 +33,21 @@ static bool security = CONFIG_TILER_SECURITY; module_param(security, bool, 0644); MODULE_PARM_DESC(security, - "Separate allocations by different processes into different pages"); + "Separate allocations by different security ids (pid or token)"); static struct list_head procs; /* list of process info structs */ static struct tiler_ops *ops; /* shared methods and variables */ /* - * process_info handling methods + * security_info handling methods * ========================================================================== */ -/* get process info, and increment refs for device tracking */ -struct process_info *__get_pi(pid_t pid, bool kernel) +/* get security info, and increment refs for device tracking */ +struct security_info *__get_si(int token, bool kernel, + enum secure_id_type sec_type) { - struct process_info *pi; + struct security_info *si; /* * treat all processes as the same, kernel processes are still treated @@ -54,32 +55,35 @@ struct process_info *__get_pi(pid_t pid, bool kernel) * closes the tiler driver */ if (!security) - pid = 0; + token = 0; /* find process context */ mutex_lock(&ops->mtx); - list_for_each_entry(pi, &procs, list) { - if (pi->pid == pid && pi->kernel == kernel) + list_for_each_entry(si, &procs, list) { + if (si->token == token && + si->kernel == kernel && + si->sec_type == sec_type) goto done; } /* create process context */ - pi = kmalloc(sizeof(*pi), GFP_KERNEL); - if (!pi) + si = kmalloc(sizeof(*si), GFP_KERNEL); + if (!si) goto done; - memset(pi, 0, sizeof(*pi)); - - pi->pid = pid; - pi->kernel = kernel; - INIT_LIST_HEAD(&pi->groups); - INIT_LIST_HEAD(&pi->bufs); - list_add(&pi->list, &procs); + memset(si, 0, sizeof(*si)); + + si->token = token; + si->sec_type = sec_type; + si->kernel = kernel; + INIT_LIST_HEAD(&si->groups); + INIT_LIST_HEAD(&si->bufs); + list_add(&si->list, &procs); done: /* increment reference count */ - if (pi && !kernel) - pi->refs++; + if (si && !kernel) + si->refs++; mutex_unlock(&ops->mtx); - return pi; + return si; } /** @@ -89,38 +93,38 @@ done: * * caller MUST already have mtx */ -void _m_free_process_info(struct process_info *pi) +void _m_free_security_info(struct security_info *si) { struct gid_info *gi, *gi_; #ifdef CONFIG_TILER_ENABLE_USERSPACE struct __buf_info *_b = NULL, *_b_ = NULL; - if (!list_empty(&pi->bufs)) + if (!list_empty(&si->bufs)) tiler_notify_event(TILER_DEVICE_CLOSE, NULL); /* unregister all buffers */ - list_for_each_entry_safe(_b, _b_, &pi->bufs, by_pid) + list_for_each_entry_safe(_b, _b_, &si->bufs, by_sid) _m_unregister_buf(_b); #endif - BUG_ON(!list_empty(&pi->bufs)); + BUG_ON(!list_empty(&si->bufs)); /* free all allocated blocks, and remove unreferenced ones */ - list_for_each_entry_safe(gi, gi_, &pi->groups, by_pid) + list_for_each_entry_safe(gi, gi_, &si->groups, by_sid) ops->destroy_group(gi); - BUG_ON(!list_empty(&pi->groups)); - list_del(&pi->list); - kfree(pi); + BUG_ON(!list_empty(&si->groups)); + list_del(&si->list); + kfree(si); } static void destroy_processes(void) { - struct process_info *pi, *pi_; + struct security_info *si, *si_; mutex_lock(&ops->mtx); - list_for_each_entry_safe(pi, pi_, &procs, list) - _m_free_process_info(pi); + list_for_each_entry_safe(si, si_, &procs, list) + _m_free_security_info(si); BUG_ON(!list_empty(&procs)); mutex_unlock(&ops->mtx); @@ -168,10 +172,10 @@ EXPORT_SYMBOL(tiler_virt2phys); void tiler_reservex(u32 n, enum tiler_fmt fmt, u32 width, u32 height, u32 gid, pid_t pid) { - struct process_info *pi = __get_pi(pid, true); + struct security_info *si = __get_si(pid, true, SECURE_BY_PID); - if (pi) - ops->reserve(n, fmt, width, height, gid, pi); + if (si) + ops->reserve(n, fmt, width, height, gid, si); } EXPORT_SYMBOL(tiler_reservex); @@ -185,10 +189,10 @@ EXPORT_SYMBOL(tiler_reserve); void tiler_reservex_nv12(u32 n, u32 width, u32 height, u32 gid, pid_t pid) { - struct process_info *pi = __get_pi(pid, true); + struct security_info *si = __get_si(0, true, SECURE_BY_PID); - if (pi) - ops->reserve_nv12(n, width, height, gid, pi); + if (si) + ops->reserve_nv12(n, width, height, gid, si); } EXPORT_SYMBOL(tiler_reservex_nv12); @@ -203,16 +207,16 @@ s32 tiler_allocx(struct tiler_block_t *blk, enum tiler_fmt fmt, u32 gid, pid_t pid) { struct mem_info *mi; - struct process_info *pi; + struct security_info *si; s32 res; BUG_ON(!blk || blk->phys); - pi = __get_pi(pid, true); - if (!pi) + si = __get_si(pid, true, SECURE_BY_PID); + if (!si) return -ENOMEM; - res = ops->alloc(fmt, blk->width, blk->height, blk->key, gid, pi, &mi); + res = ops->alloc(fmt, blk->width, blk->height, blk->key, gid, si, &mi); if (mi) { blk->phys = mi->blk.phys; blk->id = mi->blk.id; @@ -231,16 +235,16 @@ s32 tiler_mapx(struct tiler_block_t *blk, enum tiler_fmt fmt, u32 gid, pid_t pid, u32 usr_addr) { struct mem_info *mi; - struct process_info *pi; + struct security_info *si; s32 res; BUG_ON(!blk || blk->phys); - pi = __get_pi(pid, true); - if (!pi) + si = __get_si(pid, true, SECURE_BY_PID); + if (!si) return -ENOMEM; - res = ops->pin(fmt, blk->width, blk->height, blk->key, gid, pi, &mi, + res = ops->pin(fmt, blk->width, blk->height, blk->key, gid, si, &mi, usr_addr); if (mi) { blk->phys = mi->blk.phys; diff --git a/drivers/media/video/tiler/tiler-ioctl.c b/drivers/media/video/tiler/tiler-ioctl.c index 0d5f063..c39dd0f 100644 --- a/drivers/media/video/tiler/tiler-ioctl.c +++ b/drivers/media/video/tiler/tiler-ioctl.c @@ -58,11 +58,11 @@ s32 tiler_notify_event(int event, void *data) */ /* check if an offset is used */ -static bool _m_offs_in_use(u32 offs, u32 length, struct process_info *pi) +static bool _m_offs_in_use(u32 offs, u32 length, struct security_info *si) { struct __buf_info *_b; /* have mutex */ - list_for_each_entry(_b, &pi->bufs, by_pid) + list_for_each_entry(_b, &si->bufs, by_sid) if (_b->buf_info.offset < offs + length && _b->buf_info.offset + _b->buf_info.length > offs) return 1; @@ -70,13 +70,13 @@ static bool _m_offs_in_use(u32 offs, u32 length, struct process_info *pi) } /* get an offset */ -static u32 _m_get_offs(struct process_info *pi, u32 length) +static u32 _m_get_offs(struct security_info *si, u32 length) { static u32 offs = 0xda7a; /* ensure no-one is using this offset */ while ((offs << PAGE_SHIFT) + length < length || - _m_offs_in_use(offs << PAGE_SHIFT, length, pi)) { + _m_offs_in_use(offs << PAGE_SHIFT, length, si)) { /* use a pseudo-random generator to get a new offset to try */ /* Galois LSF: 20, 17 */ @@ -86,18 +86,18 @@ static u32 _m_get_offs(struct process_info *pi, u32 length) return offs << PAGE_SHIFT; } -/* find and lock a block. process_info is optional */ +/* find and lock a block. security_info is optional */ static struct mem_info * -_m_lock_block(u32 key, u32 id, struct process_info *pi) { +_m_lock_block(u32 key, u32 id, struct security_info *si) { struct gid_info *gi; struct mem_info *mi; - /* if process_info is given, look there first */ - if (pi) { + /* if security_info is given, look there first */ + if (si) { /* have mutex */ - /* find block in process list and free it */ - list_for_each_entry(gi, &pi->groups, by_pid) { + /* find block in security list and free it */ + list_for_each_entry(gi, &si->groups, by_sid) { mi = ops->lock(key, id, gi); if (mi) return mi; @@ -109,7 +109,7 @@ _m_lock_block(u32 key, u32 id, struct process_info *pi) { } /* register a buffer */ -static s32 _m_register_buf(struct __buf_info *_b, struct process_info *pi) +static s32 _m_register_buf(struct __buf_info *_b, struct security_info *si) { struct mem_info *mi; struct tiler_buf_info *b = &_b->buf_info; @@ -122,7 +122,7 @@ static s32 _m_register_buf(struct __buf_info *_b, struct process_info *pi) /* find each block */ b->length = 0; for (i = 0; i < num; i++) { - mi = _m_lock_block(b->blocks[i].key, b->blocks[i].id, pi); + mi = _m_lock_block(b->blocks[i].key, b->blocks[i].id, si); if (!mi) { /* unlock any blocks already found */ while (i--) @@ -141,11 +141,11 @@ static s32 _m_register_buf(struct __buf_info *_b, struct process_info *pi) /* if found all, register buffer */ offs = _b->mi[0]->blk.phys & ~PAGE_MASK; - b->offset = _m_get_offs(pi, b->length) + offs; + b->offset = _m_get_offs(si, b->length) + offs; b->length -= offs; /* have mutex */ - list_add(&_b->by_pid, &pi->bufs); + list_add(&_b->by_sid, &si->bufs); return 0; } @@ -156,7 +156,7 @@ void _m_unregister_buf(struct __buf_info *_b) u32 i; /* unregister */ - list_del(&_b->by_pid); + list_del(&_b->by_sid); /* no longer using the blocks */ for (i = 0; i < _b->buf_info.num_blocks; i++) @@ -178,7 +178,7 @@ static s32 tiler_mmap(struct file *filp, struct vm_area_struct *vma) struct __buf_info *_b; struct tiler_buf_info *b = NULL; u32 i, map_offs, map_size, blk_offs, blk_size, mapped_size; - struct process_info *pi = filp->private_data; + struct security_info *si = filp->private_data; u32 offs = vma->vm_pgoff << PAGE_SHIFT; u32 size = vma->vm_end - vma->vm_start; @@ -186,7 +186,7 @@ static s32 tiler_mmap(struct file *filp, struct vm_area_struct *vma) /* find tiler buffer to mmap */ mutex_lock(&ops->mtx); - list_for_each_entry(_b, &pi->bufs, by_pid) { + list_for_each_entry(_b, &si->bufs, by_sid) { /* we support partial mmaping of a whole tiler buffer */ if (offs >= (_b->buf_info.offset & PAGE_MASK) && offs + size <= PAGE_ALIGN(_b->buf_info.offset + @@ -231,7 +231,7 @@ static long tiler_ioctl(struct file *filp, u32 cmd, unsigned long arg) { s32 r; void __user *data = (void __user *)arg; - struct process_info *pi = filp->private_data; + struct security_info *si = filp->private_data; struct __buf_info *_b; struct tiler_buf_info buf_info = {0}; struct tiler_block_info block_info = {0}; @@ -248,7 +248,7 @@ static long tiler_ioctl(struct file *filp, u32 cmd, unsigned long arg) case TILFMT_PAGE: r = ops->alloc(block_info.fmt, block_info.dim.len, 1, block_info.key, block_info.group_id, - pi, &mi); + si, &mi); break; case TILFMT_8BIT: case TILFMT_16BIT: @@ -257,7 +257,7 @@ static long tiler_ioctl(struct file *filp, u32 cmd, unsigned long arg) block_info.dim.area.width, block_info.dim.area.height, block_info.key, block_info.group_id, - pi, &mi); + si, &mi); break; default: return -EINVAL; @@ -282,7 +282,7 @@ static long tiler_ioctl(struct file *filp, u32 cmd, unsigned long arg) /* search current process first, then all processes */ mutex_lock(&ops->mtx); - mi = _m_lock_block(block_info.key, block_info.id, pi); + mi = _m_lock_block(block_info.key, block_info.id, si); mutex_unlock(&ops->mtx); if (mi) ops->unlock_free(mi, true); @@ -305,7 +305,7 @@ static long tiler_ioctl(struct file *filp, u32 cmd, unsigned long arg) return -EFAULT; r = ops->pin(block_info.fmt, block_info.dim.len, 1, - block_info.key, block_info.group_id, pi, + block_info.key, block_info.group_id, si, &mi, (u32)block_info.ptr); if (r) return r; @@ -330,7 +330,7 @@ static long tiler_ioctl(struct file *filp, u32 cmd, unsigned long arg) mutex_lock(&ops->mtx); r = -ENOENT; /* buffer registration is per process */ - list_for_each_entry(_b, &pi->bufs, by_pid) { + list_for_each_entry(_b, &si->bufs, by_sid) { if (buf_info.offset == _b->buf_info.offset) { memcpy(&buf_info, &_b->buf_info, sizeof(buf_info)); @@ -361,7 +361,7 @@ static long tiler_ioctl(struct file *filp, u32 cmd, unsigned long arg) } mutex_lock(&ops->mtx); - r = _m_register_buf(_b, pi); + r = _m_register_buf(_b, si); mutex_unlock(&ops->mtx); if (r) { @@ -386,7 +386,7 @@ static long tiler_ioctl(struct file *filp, u32 cmd, unsigned long arg) r = -EFAULT; mutex_lock(&ops->mtx); /* buffer registration is per process */ - list_for_each_entry(_b, &pi->bufs, by_pid) { + list_for_each_entry(_b, &si->bufs, by_sid) { if (buf_info.offset == _b->buf_info.offset) { /* only retrieve buffer length */ buf_info.length = _b->buf_info.length; @@ -413,7 +413,7 @@ static long tiler_ioctl(struct file *filp, u32 cmd, unsigned long arg) ops->reserve_nv12(block_info.key, block_info.dim.area.width, block_info.dim.area.height, - block_info.group_id, pi); + block_info.group_id, si); #else return -EINVAL; #endif @@ -422,11 +422,11 @@ static long tiler_ioctl(struct file *filp, u32 cmd, unsigned long arg) block_info.fmt, block_info.dim.area.width, block_info.dim.area.height, - block_info.group_id, pi); + block_info.group_id, si); break; /* unreserve blocks */ case TILIOC_URBLK: - ops->unreserve(arg, pi); + ops->unreserve(arg, si); break; /* query a tiler block */ case TILIOC_QBLK: @@ -436,7 +436,7 @@ static long tiler_ioctl(struct file *filp, u32 cmd, unsigned long arg) if (block_info.id) { /* look up by id if specified */ mutex_lock(&ops->mtx); - mi = _m_lock_block(block_info.key, block_info.id, pi); + mi = _m_lock_block(block_info.key, block_info.id, si); mutex_unlock(&ops->mtx); } else #ifndef CONFIG_TILER_SECURE @@ -469,23 +469,24 @@ static long tiler_ioctl(struct file *filp, u32 cmd, unsigned long arg) /* open tiler driver */ static s32 tiler_open(struct inode *ip, struct file *filp) { - struct process_info *pi = __get_pi(current->tgid, false); - if (!pi) + struct security_info *si = __get_si(current->tgid, false, + SECURE_BY_PID); + if (!si) return -ENOMEM; - filp->private_data = pi; + filp->private_data = si; return 0; } /* close tiler driver */ static s32 tiler_release(struct inode *ip, struct file *filp) { - struct process_info *pi = filp->private_data; + struct security_info *si = filp->private_data; mutex_lock(&ops->mtx); /* free resources if last device in this process */ - if (0 == --pi->refs) - _m_free_process_info(pi); + if (0 == --si->refs) + _m_free_security_info(si); mutex_unlock(&ops->mtx); diff --git a/drivers/media/video/tiler/tiler-main.c b/drivers/media/video/tiler/tiler-main.c index 2befe0e..0c28166 100644 --- a/drivers/media/video/tiler/tiler-main.c +++ b/drivers/media/video/tiler/tiler-main.c @@ -343,14 +343,14 @@ static const struct file_operations tiler_debug_fops = { */ /* get or create new gid_info object */ -static struct gid_info *_m_get_gi(struct process_info *pi, u32 gid) +static struct gid_info *_m_get_gi(struct security_info *si, u32 gid) { struct gid_info *gi; /* have mutex */ /* see if group already exist */ - list_for_each_entry(gi, &pi->groups, by_pid) { + list_for_each_entry(gi, &si->groups, by_sid) { if (gi->gid == gid) goto done; } @@ -364,9 +364,9 @@ static struct gid_info *_m_get_gi(struct process_info *pi, u32 gid) INIT_LIST_HEAD(&gi->areas); INIT_LIST_HEAD(&gi->onedim); INIT_LIST_HEAD(&gi->reserved); - gi->pi = pi; + gi->si = si; gi->gid = gid; - list_add(&gi->by_pid, &pi->groups); + list_add(&gi->by_sid, &si->groups); done: /* * Once area is allocated, the group info's ref count will be @@ -384,13 +384,14 @@ static void _m_try_free_group(struct gid_info *gi) /* also ensure noone is still using this group */ !gi->refs) { BUG_ON(!list_empty(&gi->reserved)); - list_del(&gi->by_pid); + list_del(&gi->by_sid); /* if group is tracking kernel objects, we may free even the process info */ - if (gi->pi->kernel && list_empty(&gi->pi->groups)) { - list_del(&gi->pi->list); - kfree(gi->pi); + if (gi->si->kernel && + list_empty(&gi->si->groups)) { + list_del(&gi->si->list); + kfree(gi->si); } kfree(gi); @@ -399,11 +400,11 @@ static void _m_try_free_group(struct gid_info *gi) /* --- external versions --- */ -static struct gid_info *get_gi(struct process_info *pi, u32 gid) +static struct gid_info *get_gi(struct security_info *si, u32 gid) { struct gid_info *gi; mutex_lock(&mtx); - gi = _m_get_gi(pi, gid); + gi = _m_get_gi(si, gid); mutex_unlock(&mtx); return gi; } @@ -456,19 +457,15 @@ static inline void _m_area_free(struct area_info *ai) } static s32 __analize_area(enum tiler_fmt fmt, u32 width, u32 height, - u16 *x_area, u16 *y_area, u16 *band, - u16 *align) + u16 *x_area, u16 *y_area, u16 *band, u16 *align) { - /* input: width, height is in pixels */ - /* output: x_area, y_area, band, align */ + /* input: width, height is in pixels, align */ + /* output: x_area, y_area, band */ /* slot width, height, and row size */ u32 slot_row, min_align; const struct tiler_geom *g; - /* set alignment to page size */ - *align = PAGE_SIZE; - /* width and height must be positive */ if (!width || !height) return -EINVAL; @@ -478,6 +475,9 @@ static s32 __analize_area(enum tiler_fmt fmt, u32 width, u32 height, return -EINVAL; if (fmt == TILFMT_PAGE) { + /* adjust size to accomodate offset, only do page alignment */ + *align = PAGE_SIZE; + /* for 1D area keep the height (1), width is in tiler slots */ *x_area = DIV_ROUND_UP(width, tiler.page); *y_area = *band = 1; @@ -500,7 +500,10 @@ static s32 __analize_area(enum tiler_fmt fmt, u32 width, u32 height, /* minimum alignment is at least 1 slot */ min_align = max(slot_row, granularity); - *align = ALIGN(*align, min_align); + + /* set alignment to page size by default and enforce minumum cache + line size */ + *align = ALIGN(*align ? : PAGE_SIZE, min_align); /* adjust to slots */ *x_area = DIV_ROUND_UP(width, g->slot_w); @@ -956,7 +959,7 @@ static void unlock_n_free(struct mem_info *mi, bool free) * * allocated blocks, and unreferenced blocks. Any blocks/areas still referenced * will move to the orphaned lists to avoid issues if a new process is created - * with the same pid. + * with the same sid. * * (must have mutex) */ @@ -1092,9 +1095,9 @@ static void fill_block_info(struct mem_info *i, struct tiler_block_info *blk) * ========================================================================== */ static struct mem_info *alloc_area(enum tiler_fmt fmt, u32 width, u32 height, - struct gid_info *gi) + struct gid_info *gi, u16 align) { - u16 x, y, band, align; + u16 x, y, band; struct mem_info *mi = NULL; const struct tiler_geom *g = tiler.geom(fmt); @@ -1143,25 +1146,25 @@ static struct mem_info *alloc_area(enum tiler_fmt fmt, u32 width, u32 height, static struct mem_info *alloc_block_area(enum tiler_fmt fmt, u32 width, u32 height, u32 key, u32 gid, - struct process_info *pi) + struct security_info *si, u16 align) { struct mem_info *mi = NULL; struct gid_info *gi = NULL; /* validate parameters */ - if (!pi) + if (!si) return ERR_PTR(-EINVAL); /* get group context */ mutex_lock(&mtx); - gi = _m_get_gi(pi, gid); + gi = _m_get_gi(si, gid); mutex_unlock(&mtx); if (!gi) return ERR_PTR(-ENOMEM); /* reserve area in tiler container */ - mi = alloc_area(fmt, width, height, gi); + mi = alloc_area(fmt, width, height, gi, align); if (!mi) { mutex_lock(&mtx); gi->refs--; @@ -1242,7 +1245,7 @@ static struct tiler_pa_info *get_new_pa(struct tmm *tmm, u32 num_pg) } static s32 alloc_block(enum tiler_fmt fmt, u32 width, u32 height, - u32 key, u32 gid, struct process_info *pi, + u32 key, u32 gid, struct security_info *si, struct mem_info **info) { struct mem_info *mi; @@ -1252,7 +1255,7 @@ static s32 alloc_block(enum tiler_fmt fmt, u32 width, u32 height, *info = NULL; /* allocate tiler container area */ - mi = alloc_block_area(fmt, width, height, key, gid, pi); + mi = alloc_block_area(fmt, width, height, key, gid, si, PAGE_SIZE); if (IS_ERR_OR_NULL(mi)) return mi ? -ENOMEM : PTR_ERR(mi); @@ -1382,7 +1385,7 @@ EXPORT_SYMBOL(user_block_to_pa); /* allocate area from container and pin memory */ static s32 pin_any_block(enum tiler_fmt fmt, u32 width, u32 height, - u32 key, u32 gid, struct process_info *pi, + u32 key, u32 gid, struct security_info *si, struct mem_info **info, struct tiler_pa_info *pa) { s32 res = -EPERM; @@ -1395,7 +1398,7 @@ static s32 pin_any_block(enum tiler_fmt fmt, u32 width, u32 height, goto done; /* get allocation area */ - mi = alloc_block_area(fmt, width, height, key, gid, pi); + mi = alloc_block_area(fmt, width, height, key, gid, si, PAGE_SIZE); if (IS_ERR_OR_NULL(mi)) { res = mi ? PTR_ERR(mi) : -ENOMEM; goto done; @@ -1418,7 +1421,7 @@ done: } static s32 pin_block(enum tiler_fmt fmt, u32 width, u32 height, - u32 key, u32 gid, struct process_info *pi, + u32 key, u32 gid, struct security_info *si, struct mem_info **info, u32 usr_addr) { struct tiler_pa_info *pa = NULL; @@ -1432,7 +1435,7 @@ static s32 pin_block(enum tiler_fmt fmt, u32 width, u32 height, if (IS_ERR_OR_NULL(pa)) return pa ? PTR_ERR(pa) : -ENOMEM; - return pin_any_block(fmt, width, height, key, gid, pi, info, pa); + return pin_any_block(fmt, width, height, key, gid, si, info, pa); } s32 tiler_pin_block(tiler_blk_handle block, u32 *addr_array, u32 nents) @@ -1708,7 +1711,8 @@ tiler_blk_handle tiler_map_1d_block(struct tiler_pa_info *pa) struct mem_info *mi = NULL; struct tiler_pa_info *pa_tmp = kmemdup(pa, sizeof(*pa), GFP_KERNEL); s32 res = pin_any_block(TILFMT_PAGE, pa->num_pg << PAGE_SHIFT, 1, 0, 0, - __get_pi(0, true), &mi, pa_tmp); + __get_si(0, true, SECURE_BY_PID), &mi, + pa_tmp); return res ? ERR_PTR(res) : mi; } EXPORT_SYMBOL(tiler_map_1d_block); @@ -1731,7 +1735,8 @@ tiler_blk_handle tiler_alloc_block_area(enum tiler_fmt fmt, u32 width, if (!tilerdev_class) return NULL; - mi = alloc_block_area(fmt, width, height, 0, 0, __get_pi(0, true)); + mi = alloc_block_area(fmt, width, height, 0, 0, + __get_si(0, true, SECURE_BY_PID), PAGE_SIZE); if (IS_ERR_OR_NULL(mi)) goto done; @@ -1744,6 +1749,31 @@ done: } EXPORT_SYMBOL(tiler_alloc_block_area); +tiler_blk_handle tiler_alloc_block_area_aligned(enum tiler_fmt fmt, u32 width, + u32 height, u32 *ssptr, u32 *virt_array, u32 align, + u32 token) +{ + struct mem_info *mi; + *ssptr = 0; + + /* if tiler is not initialized fail gracefully */ + if (!tilerdev_class) + return NULL; + + mi = alloc_block_area(fmt, width, height, 0, 0, __get_si(token, true, + SECURE_BY_TOKEN), align); + + if (IS_ERR_OR_NULL(mi)) + goto done; + + fill_virt_array(&mi->blk, virt_array); + *ssptr = mi->blk.phys; + +done: + return mi; +} +EXPORT_SYMBOL(tiler_alloc_block_area_aligned); + void tiler_unpin_block(tiler_blk_handle block) { mutex_lock(&mtx); @@ -1755,13 +1785,13 @@ EXPORT_SYMBOL(tiler_unpin_block); s32 tiler_memsize(enum tiler_fmt fmt, u32 width, u32 height, u32 *alloc_pages, u32 *virt_pages) { - u16 x, y, band, align; + u16 x, y, band, align = PAGE_SIZE; int res; struct tiler_block_t blk; *alloc_pages = *virt_pages = 0; - res = tiler.analize(fmt, width, height, &x, &y, &align, &band); + res = tiler.analize(fmt, width, height, &x, &y, &band, &align); if (!res) { blk.height = height; @@ -1772,6 +1802,7 @@ s32 tiler_memsize(enum tiler_fmt fmt, u32 width, u32 height, u32 *alloc_pages, } return res; + } EXPORT_SYMBOL(tiler_memsize); diff --git a/drivers/media/video/tiler/tiler-nv12.c b/drivers/media/video/tiler/tiler-nv12.c index e166122..f208275 100644 --- a/drivers/media/video/tiler/tiler-nv12.c +++ b/drivers/media/video/tiler/tiler-nv12.c @@ -334,7 +334,7 @@ static u16 nv12_together(u16 o, u16 a, u16 w, u16 n, u16 *area, u8 *packing) /* reserve nv12 blocks */ static void reserve_nv12(u32 n, u32 width, u32 height, - u32 gid, struct process_info *pi) + u32 gid, struct security_info *si) { u16 w, h, band, a, o = 0; struct gid_info *gi; @@ -353,7 +353,7 @@ static void reserve_nv12(u32 n, u32 width, u32 height, return; /* get group context */ - gi = ops->get_gi(pi, gid); + gi = ops->get_gi(si, gid); if (!gi) return; diff --git a/drivers/media/video/tiler/tiler-reserve.c b/drivers/media/video/tiler/tiler-reserve.c index fbabc6d..c5a4f9c 100644 --- a/drivers/media/video/tiler/tiler-reserve.c +++ b/drivers/media/video/tiler/tiler-reserve.c @@ -78,7 +78,7 @@ u32 tiler_best2pack(u16 o, u16 a, u16 b, u16 w, u16 *n, u16 *_area) /* reserve 2d blocks */ static void reserve_blocks(u32 n, enum tiler_fmt fmt, u32 width, u32 height, u32 gid, - struct process_info *pi) + struct security_info *si) { u32 bpt, res = 0, i; u16 a, band, w, h, n_try; @@ -103,7 +103,7 @@ static void reserve_blocks(u32 n, enum tiler_fmt fmt, u32 width, u32 height, return; /* get group id */ - gi = ops->get_gi(pi, gid); + gi = ops->get_gi(si, gid); if (!gi) return; @@ -131,11 +131,11 @@ static void reserve_blocks(u32 n, enum tiler_fmt fmt, u32 width, u32 height, } /* unreserve blocks for a group id */ -static void unreserve_blocks(u32 gid, struct process_info *pi) +static void unreserve_blocks(u32 gid, struct security_info *si) { struct gid_info *gi; - gi = ops->get_gi(pi, gid); + gi = ops->get_gi(si, gid); if (!gi) return; |