Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 656a4139 authored by Liam Mark's avatar Liam Mark
Browse files

ion: skip unwanted cache maintenance



We don't want to do cache maintenance on uncached buffers or on
buffers for which we don't have HLOS access.

Change-Id: Ib0dfdcfa4cf9c727b1b288cea11af87e11126bb4
Signed-off-by: default avatarLiam Mark <lmark@codeaurora.org>
parent 3e921e11
Loading
Loading
Loading
Loading
+62 −7
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@
#include <soc/qcom/secure_buffer.h>

#include "ion.h"
#include "ion_secure_util.h"

static struct ion_device *internal_dev;

@@ -298,9 +299,14 @@ static struct sg_table *ion_map_dma_buf(struct dma_buf_attachment *attachment,
	struct ion_dma_buf_attachment *a = attachment->priv;
	struct sg_table *table;
	int ret, count, map_attrs;
	struct ion_buffer *buffer = attachment->dmabuf->priv;

	table = a->table;

	map_attrs = attachment->dma_map_attrs;
	if (!(buffer->flags & ION_FLAG_CACHED) ||
	    !hlos_accessible_buffer(buffer))
		map_attrs |= DMA_ATTR_SKIP_CPU_SYNC;

	if (map_attrs & DMA_ATTR_DELAYED_UNMAP) {
		count = msm_dma_map_sg_attrs(attachment->dev, table->sgl,
@@ -316,6 +322,7 @@ static struct sg_table *ion_map_dma_buf(struct dma_buf_attachment *attachment,
		ret = -ENOMEM;
		goto err;
	}

	return table;

err:
@@ -327,14 +334,22 @@ static void ion_unmap_dma_buf(struct dma_buf_attachment *attachment,
			      struct sg_table *table,
			      enum dma_data_direction direction)
{
	if (attachment->dma_map_attrs & DMA_ATTR_DELAYED_UNMAP)
	int map_attrs;
	struct ion_buffer *buffer = attachment->dmabuf->priv;

	map_attrs = attachment->dma_map_attrs;
	if (!(buffer->flags & ION_FLAG_CACHED) ||
	    !hlos_accessible_buffer(buffer))
		map_attrs |= DMA_ATTR_SKIP_CPU_SYNC;

	if (map_attrs & DMA_ATTR_DELAYED_UNMAP)
		msm_dma_unmap_sg_attrs(attachment->dev, table->sgl,
				       table->nents, direction,
				       attachment->dmabuf,
				       attachment->dma_map_attrs);
				       map_attrs);
	else
		dma_unmap_sg_attrs(attachment->dev, table->sgl, table->nents,
				   direction, attachment->dma_map_attrs);
				   direction, map_attrs);
}

void ion_pages_sync_for_device(struct device *dev, struct page *page,
@@ -493,6 +508,12 @@ static int __ion_dma_buf_begin_cpu_access(struct dma_buf *dmabuf,
	struct ion_buffer *buffer = dmabuf->priv;
	void *vaddr;
	struct ion_dma_buf_attachment *a;
	int ret = 0;

	if (!hlos_accessible_buffer(buffer)) {
		ret = -EPERM;
		goto out;
	}

	/*
	 * TODO: Move this elsewhere because we don't always need a vaddr
@@ -503,6 +524,9 @@ static int __ion_dma_buf_begin_cpu_access(struct dma_buf *dmabuf,
		mutex_unlock(&buffer->lock);
	}

	if (!(buffer->flags & ION_FLAG_CACHED))
		goto out;

	mutex_lock(&buffer->lock);
	list_for_each_entry(a, &buffer->attachments, list) {
		if (sync_only_mapped)
@@ -515,7 +539,8 @@ static int __ion_dma_buf_begin_cpu_access(struct dma_buf *dmabuf,
	}
	mutex_unlock(&buffer->lock);

	return 0;
out:
	return ret;
}

static int __ion_dma_buf_end_cpu_access(struct dma_buf *dmabuf,
@@ -524,6 +549,12 @@ static int __ion_dma_buf_end_cpu_access(struct dma_buf *dmabuf,
{
	struct ion_buffer *buffer = dmabuf->priv;
	struct ion_dma_buf_attachment *a;
	int ret = 0;

	if (!hlos_accessible_buffer(buffer)) {
		ret = -EPERM;
		goto out;
	}

	if (buffer->heap->ops->map_kernel) {
		mutex_lock(&buffer->lock);
@@ -531,6 +562,9 @@ static int __ion_dma_buf_end_cpu_access(struct dma_buf *dmabuf,
		mutex_unlock(&buffer->lock);
	}

	if (!(buffer->flags & ION_FLAG_CACHED))
		goto out;

	mutex_lock(&buffer->lock);
	list_for_each_entry(a, &buffer->attachments, list) {
		if (sync_only_mapped)
@@ -543,7 +577,8 @@ static int __ion_dma_buf_end_cpu_access(struct dma_buf *dmabuf,
	}
	mutex_unlock(&buffer->lock);

	return 0;
out:
	return ret;
}

static int ion_dma_buf_begin_cpu_access(struct dma_buf *dmabuf,
@@ -578,6 +613,12 @@ static int ion_dma_buf_begin_cpu_access_partial(struct dma_buf *dmabuf,
	struct ion_buffer *buffer = dmabuf->priv;
	void *vaddr;
	struct ion_dma_buf_attachment *a;
	int ret = 0;

	if (!hlos_accessible_buffer(buffer)) {
		ret = -EPERM;
		goto out;
	}

	/*
	 * TODO: Move this elsewhere because we don't always need a vaddr
@@ -588,6 +629,9 @@ static int ion_dma_buf_begin_cpu_access_partial(struct dma_buf *dmabuf,
		mutex_unlock(&buffer->lock);
	}

	if (!(buffer->flags & ION_FLAG_CACHED))
		goto out;

	mutex_lock(&buffer->lock);
	list_for_each_entry(a, &buffer->attachments, list) {
		ion_sgl_sync_range(a->dev, a->table->sgl, a->table->nents,
@@ -595,7 +639,8 @@ static int ion_dma_buf_begin_cpu_access_partial(struct dma_buf *dmabuf,
	}
	mutex_unlock(&buffer->lock);

	return 0;
out:
	return ret;
}

static int ion_dma_buf_end_cpu_access_partial(struct dma_buf *dmabuf,
@@ -605,6 +650,12 @@ static int ion_dma_buf_end_cpu_access_partial(struct dma_buf *dmabuf,
{
	struct ion_buffer *buffer = dmabuf->priv;
	struct ion_dma_buf_attachment *a;
	int ret = 0;

	if (!hlos_accessible_buffer(buffer)) {
		ret = -EPERM;
		goto out;
	}

	if (buffer->heap->ops->map_kernel) {
		mutex_lock(&buffer->lock);
@@ -612,6 +663,9 @@ static int ion_dma_buf_end_cpu_access_partial(struct dma_buf *dmabuf,
		mutex_unlock(&buffer->lock);
	}

	if (!(buffer->flags & ION_FLAG_CACHED))
		goto out;

	mutex_lock(&buffer->lock);
	list_for_each_entry(a, &buffer->attachments, list) {
		ion_sgl_sync_range(a->dev, a->table->sgl, a->table->nents,
@@ -619,7 +673,8 @@ static int ion_dma_buf_end_cpu_access_partial(struct dma_buf *dmabuf,
	}
	mutex_unlock(&buffer->lock);

	return 0;
out:
	return ret;
}

static int ion_dma_buf_get_flags(struct dma_buf *dmabuf,
+15 −1
Original line number Diff line number Diff line
/*
 *
 * Copyright (c) 2017, The Linux Foundation. All rights reserved.
 * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -202,3 +202,17 @@ int ion_hyp_assign_sg_from_flags(struct sg_table *sgt, unsigned long flags,
out:
	return ret;
}

bool hlos_accessible_buffer(struct ion_buffer *buffer)
{
	if ((buffer->flags & ION_FLAG_SECURE) &&
	    !(buffer->flags & ION_FLAG_CP_HLOS) &&
	    !(buffer->flags & ION_FLAG_CP_SPSS_HLOS_SHARED))
		return false;
	else if ((get_secure_vmid(buffer->flags) > 0) &&
		 !(buffer->flags & ION_FLAG_CP_HLOS) &&
		 !(buffer->flags & ION_FLAG_CP_SPSS_HLOS_SHARED))
		return false;

	return true;
}
+5 −1
Original line number Diff line number Diff line
/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -10,6 +10,8 @@
 * GNU General Public License for more details.
 */

#include "ion.h"

#ifndef _ION_SECURE_UTIL_H
#define _ION_SECURE_UTIL_H

@@ -24,4 +26,6 @@ int ion_hyp_unassign_sg_from_flags(struct sg_table *sgt, unsigned long flags,
int ion_hyp_assign_sg_from_flags(struct sg_table *sgt, unsigned long flags,
				 bool set_page_private);

bool hlos_accessible_buffer(struct ion_buffer *buffer);

#endif /* _ION_SECURE_UTIL_H */