/* * * (C) COPYRIGHT 2008-2013 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the * GNU General Public License version 2 as published by the Free Software * Foundation, and any use by you of this program is subject to the terms * of such GNU licence. * * A copy of the licence is included with the program, and can also be obtained * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef _UMP_KERNEL_CORE_H_ #define _UMP_KERNEL_CORE_H_ #include #include #include #include #include #include #include #ifdef CONFIG_KDS #include #endif #include #include /* forward decl */ struct umpp_session; /** * UMP handle metadata. * Tracks various data about a handle not of any use to user space */ typedef enum { UMP_MGMT_EXTERNAL = (1ul << 0) /**< Handle created via the ump_dd_create_from_phys_blocks interface */ /* (1ul << 31) not to be used */ } umpp_management_flags; /** * Structure tracking the single global UMP device. * Holds global data like the ID map */ typedef struct umpp_device { struct mutex secure_id_map_lock; /**< Lock protecting access to the map */ umpp_descriptor_mapping * secure_id_map; /**< Map of all known secure IDs on the system */ } umpp_device; /** * Structure tracking all memory allocations of a UMP allocation. * Tracks info about an mapping so we can verify cache maintenace * operations and help in the unmap cleanup. */ typedef struct umpp_cpu_mapping { struct list_head link; /**< link to list of mappings for an allocation */ void *vaddr_start; /**< CPU VA start of the mapping */ size_t nr_pages; /**< Size (in pages) of the mapping */ uint64_t page_off; /**< Offset (in pages) from start of the allocation where the mapping starts */ ump_dd_handle handle; /**< Which handle this mapping is linked to */ struct umpp_session * session; /**< Which session created the mapping */ } umpp_cpu_mapping; /** * Structure tracking UMP allocation. * Represent a memory allocation with its ID. * Tracks all needed meta-data about an allocation. * */ typedef struct umpp_allocation { ump_secure_id id; /**< Secure ID of the allocation */ atomic_t refcount; /**< Usage count */ ump_alloc_flags flags; /**< Flags for all supported devices */ uint32_t management_flags; /**< Managment flags tracking */ pid_t owner; /**< The process ID owning the memory if not sharable */ ump_dd_security_filter filter_func; /**< Hook to verify use, called during retains from new clients */ ump_dd_final_release_callback final_release_func; /**< Hook called when the last reference is removed */ void* callback_data; /**< Additional data given to release hook */ uint64_t size; /**< Size (in bytes) of the allocation */ uint64_t blocksCount; /**< Number of physsical blocks the allocation is built up of */ ump_dd_physical_block_64 * block_array; /**< Array, one entry per block, describing block start and length */ struct mutex map_list_lock; /**< Lock protecting the map_list */ struct list_head map_list; /**< Tracks all CPU VA mappings of this allocation */ #ifdef CONFIG_KDS struct kds_resource kds_res; /**< The KDS resource controlling access to this allocation */ #endif void * backendData; /**< Physical memory backend meta-data */ } umpp_allocation; /** * Structure tracking use of UMP memory by a session. * Tracks the use of an allocation by a session so session termination can clean up any outstanding references. * Also protects agains non-matched release calls from user space. */ typedef struct umpp_session_memory_usage { ump_secure_id id; /**< ID being used. For quick look-up */ ump_dd_handle mem; /**< Handle being used. */ /** * Track how many times has the process retained this handle in the kernel. * This should usually just be 1(allocated or resolved) or 2(mapped), * but could be more if someone is playing with the low-level API * */ atomic_t process_usage_count; struct list_head link; /**< link to other usage trackers for a session */ } umpp_session_memory_usage; /** * Structure representing a session/client. * Tracks the UMP allocations being used by this client. */ typedef struct umpp_session { struct mutex session_lock; /**< Lock for memory usage manipulation */ struct list_head memory_usage; /**< list of memory currently being used by the this session */ void* import_handler_data[UMPP_EXTERNAL_MEM_COUNT]; /**< Import modules per-session data pointer */ } umpp_session; /** * UMP core setup. * Called by any OS specific startup function to initialize the common part. * @return UMP_OK if core initialized correctly, any other value for errors */ ump_result umpp_core_constructor(void); /** * UMP core teardown. * Called by any OS specific unload function to clean up the common part. */ void umpp_core_destructor(void); /** * UMP session start. * Called by any OS specific session handler when a new session is detected * @return Non-NULL if a matching core session could be set up. NULL on failure */ umpp_session *umpp_core_session_start(void); /** * UMP session end. * Called by any OS specific session handler when a session is ended/terminated. * @param session The core session object returned by ump_core_session_start */ void umpp_core_session_end(umpp_session *session); /** * Find a mapping object (if any) for this allocation. * Called by any function needing to identify a mapping from a user virtual address. * Verifies that the whole range to be within a mapping object. * @param alloc The UMP allocation to find a matching mapping object of * @param uaddr User mapping address to find the mapping object for * @param size Length of the mapping * @return NULL on error (no match found), pointer to mapping object if match found */ umpp_cpu_mapping * umpp_dd_find_enclosing_mapping(umpp_allocation * alloc, void* uaddr, size_t size); /** * Register a new mapping of an allocation. * Called by functions creating a new mapping of an allocation, typically OS specific handlers. * @param alloc The allocation object which has been mapped * @param map Info about the mapping */ void umpp_dd_add_cpu_mapping(umpp_allocation * alloc, umpp_cpu_mapping * map); /** * Remove and free mapping object from an allocation. * @param alloc The allocation object to remove the mapping info from * @param target The mapping object to remove */ void umpp_dd_remove_cpu_mapping(umpp_allocation * alloc, umpp_cpu_mapping * target); /** * Helper to find a block in the blockArray which holds a given byte offset. * @param alloc The allocation object to find the block in * @param offset Offset (in bytes) from allocation start to find the block of * @param[out] block_index Pointer to the index of the block matching * @param[out] block_internal_offset Offset within the returned block of the searched offset * @return 0 if a matching block was found, any other value for error */ int umpp_dd_find_start_block(const umpp_allocation * alloc, uint64_t offset, uint64_t * const block_index, uint64_t * const block_internal_offset); /** * Cache maintenance helper. * Performs the requested cache operation on the given handle. * @param mem Allocation handle * @param op Cache maintenance operation to perform * @param address User mapping at which to do the operation * @param size Length (in bytes) of the range to do the operation on */ void umpp_dd_cpu_msync_now(ump_dd_handle mem, ump_cpu_msync_op op, void * address, size_t size); /** * Import module session early init. * Calls session_begin on all installed import modules. * @param session The core session object to initialized the import handler for * */ void umpp_import_handlers_init(umpp_session * session); /** * Import module session cleanup. * Calls session_end on all import modules bound to the session. * @param session The core session object to initialized the import handler for */ void umpp_import_handlers_term(umpp_session * session); #endif /* _UMP_KERNEL_CORE_H_ */