/* session->memory_lock must be held when calling this function */ static void mali_mem_release(mali_mem_allocation *descriptor) { MALI_DEBUG_ASSERT_POINTER(descriptor); MALI_DEBUG_ASSERT_LOCK_HELD(descriptor->session->memory_lock); MALI_DEBUG_ASSERT(MALI_MEM_ALLOCATION_VALID_MAGIC == descriptor->magic); switch (descriptor->type) { case MALI_MEM_OS: mali_mem_os_release(descriptor); break; case MALI_MEM_DMA_BUF: #if defined(CONFIG_DMA_SHARED_BUFFER) mali_mem_dma_buf_release(descriptor); #endif break; case MALI_MEM_UMP: #if defined(CONFIG_MALI400_UMP) mali_mem_ump_release(descriptor); #endif break; case MALI_MEM_EXTERNAL: mali_mem_external_release(descriptor); break; case MALI_MEM_BLOCK: mali_mem_block_release(descriptor); break; default: MALI_DEBUG_PRINT(1, ("mem type %d is not in the mali_mem_type enum.\n", descriptor->type)); break; } }
/** @note munmap handler is done by vma close handler */ int mali_mmap(struct file *filp, struct vm_area_struct *vma) { struct mali_session_data *session; mali_mem_allocation *descriptor; u32 size = vma->vm_end - vma->vm_start; u32 mali_addr = vma->vm_pgoff << PAGE_SHIFT; session = (struct mali_session_data *)filp->private_data; if (NULL == session) { MALI_PRINT_ERROR(("mmap called without any session data available\n")); return -EFAULT; } MALI_DEBUG_PRINT(4, ("MMap() handler: start=0x%08X, phys=0x%08X, size=0x%08X vma->flags 0x%08x\n", (unsigned int)vma->vm_start, (unsigned int)(vma->vm_pgoff << PAGE_SHIFT), (unsigned int)(vma->vm_end - vma->vm_start), vma->vm_flags)); /* Set some bits which indicate that, the memory is IO memory, meaning * that no paging is to be performed and the memory should not be * included in crash dumps. And that the memory is reserved, meaning * that it's present and can never be paged out (see also previous * entry) */ vma->vm_flags |= VM_IO; vma->vm_flags |= VM_DONTCOPY; vma->vm_flags |= VM_PFNMAP; #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 0) vma->vm_flags |= VM_RESERVED; #else vma->vm_flags |= VM_DONTDUMP; vma->vm_flags |= VM_DONTEXPAND; #endif vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); vma->vm_ops = &mali_kernel_vm_ops; /* Operations used on any memory system */ descriptor = mali_mem_block_alloc(mali_addr, size, vma, session); if (NULL == descriptor) { descriptor = mali_mem_os_alloc(mali_addr, size, vma, session); if (NULL == descriptor) { MALI_DEBUG_PRINT(3, ("MMAP failed\n")); return -ENOMEM; } } MALI_DEBUG_ASSERT(MALI_MEM_ALLOCATION_VALID_MAGIC == descriptor->magic); vma->vm_private_data = (void *)descriptor; /* Put on descriptor map */ if (_MALI_OSK_ERR_OK != mali_descriptor_mapping_allocate_mapping(session->descriptor_mapping, descriptor, &descriptor->id)) { _mali_osk_mutex_wait(session->memory_lock); mali_mem_os_release(descriptor); _mali_osk_mutex_signal(session->memory_lock); return -EFAULT; } return 0; }