/** * Protects memory if heap is unsecured heap. Also ensures that we are in * the correct FMEM state if this heap is a reusable heap. * Must be called with heap->lock locked. */ static int ion_cp_protect(struct ion_heap *heap) { struct ion_cp_heap *cp_heap = container_of(heap, struct ion_cp_heap, heap); int ret_value = 0; if (cp_heap->heap_protected == HEAP_NOT_PROTECTED) { /* Make sure we are in C state when the heap is protected. */ if (cp_heap->reusable && !cp_heap->allocated_bytes) { ret_value = fmem_set_state(FMEM_C_STATE); if (ret_value) goto out; } ret_value = ion_cp_protect_mem(cp_heap->secure_base, cp_heap->secure_size, cp_heap->permission_type); if (ret_value) { pr_err("Failed to protect memory for heap %s - " "error code: %d\n", heap->name, ret_value); if (cp_heap->reusable && !cp_heap->allocated_bytes) { if (fmem_set_state(FMEM_T_STATE) != 0) pr_err("%s: unable to transition heap to T-state\n", __func__); } } else { cp_heap->heap_protected = HEAP_PROTECTED; pr_debug("Protected heap %s @ 0x%lx\n", heap->name, cp_heap->base); } } out: return ret_value; }
/* Must be protected by ion_cp_buffer lock */ static int __ion_cp_protect_buffer(struct ion_buffer *buffer, int version, void *data, int flags) { struct ion_cp_buffer *buf = buffer->priv_virt; int ret_value = 0; if (atomic_inc_return(&buf->secure_cnt) == 1) { ret_value = ion_cp_protect_mem(buf->buffer, buffer->size, 0, version, data); if (ret_value) { pr_err("Failed to secure buffer %p, error %d\n", buffer, ret_value); atomic_dec(&buf->secure_cnt); } else { pr_debug("Protected buffer %p from %pa (size %x)\n", buffer, &buf->buffer, buffer->size); buf->want_delayed_unsecure |= flags & ION_UNSECURE_DELAYED ? 1 : 0; buf->data = data; buf->version = version; } } pr_debug("buffer %p protect count %d\n", buffer, atomic_read(&buf->secure_cnt)); BUG_ON(atomic_read(&buf->secure_cnt) < 0); return ret_value; }
/** * Protects memory if heap is unsecured heap. Also ensures that we are in * the correct FMEM state if this heap is a reusable heap. * Must be called with heap->lock locked. */ static int ion_cp_protect(struct ion_heap *heap, int version, void *data) { struct ion_cp_heap *cp_heap = container_of(heap, struct ion_cp_heap, heap); int ret_value = 0; if (atomic_inc_return(&cp_heap->protect_cnt) == 1) { /* Make sure we are in C state when the heap is protected. */ if (cp_heap->reusable && !cp_heap->allocated_bytes) { ret_value = fmem_set_state(FMEM_C_STATE); if (ret_value) goto out; } ret_value = ion_cp_protect_mem(cp_heap->secure_base, cp_heap->secure_size, cp_heap->permission_type, version, data); if (ret_value) { pr_err("Failed to protect memory for heap %s - " "error code: %d\n", heap->name, ret_value); if (cp_heap->reusable && !cp_heap->allocated_bytes) { if (fmem_set_state(FMEM_T_STATE) != 0) pr_err("%s: unable to transition heap to T-state\n", __func__); } atomic_dec(&cp_heap->protect_cnt); } else { cp_heap->heap_protected = HEAP_PROTECTED; pr_debug("Protected heap %s @ 0x%lx\n", heap->name, cp_heap->base); } } out: pr_debug("%s: protect count is %d\n", __func__, atomic_read(&cp_heap->protect_cnt)); BUG_ON(atomic_read(&cp_heap->protect_cnt) < 0); return ret_value; }
static int ion_cp_protect(struct ion_heap *heap) { struct ion_cp_heap *cp_heap = container_of(heap, struct ion_cp_heap, heap); int ret_value = 0; if (atomic_inc_return(&cp_heap->protect_cnt) == 1) { ret_value = ion_cp_protect_mem(cp_heap->secure_base, cp_heap->secure_size, cp_heap->permission_type); if (ret_value) { pr_err("Failed to protect memory for heap %s - " "error code: %d\n", heap->name, ret_value); } else { cp_heap->heap_protected = HEAP_PROTECTED; pr_debug("Protected heap %s @ 0x%x\n", heap->name, (unsigned int) cp_heap->base); } } pr_debug("%s: protect count is %d\n", __func__, atomic_read(&cp_heap->protect_cnt)); BUG_ON(atomic_read(&cp_heap->protect_cnt) < 0); return ret_value; }