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

Commit 5f127b54 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "iommu: msm: add access_control feature"

parents b2234b52 287e9b7a
Loading
Loading
Loading
Loading
+63 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@
#include <linux/export.h>
#include <linux/iommu.h>
#include <linux/qcom_iommu.h>
#include <asm/sections.h>

static DEFINE_MUTEX(iommu_list_lock);
static LIST_HEAD(iommu_list);
@@ -68,6 +69,68 @@ int msm_iommu_bus_register(void)
}
#endif

void msm_access_control(void)
{
	int ret;
	struct device *cb_dev;
	struct iommu_domain *domain;
	unsigned long start, kernel_start, kernel_end, end;

	start = 0;
	kernel_start = ALIGN(__pa(_stext), SZ_2M);
	kernel_end = ALIGN(__pa(_etext), SZ_2M);
	end = 0xFFFFFFFF;

	/*
	 * If a target doesn't have the access control feature
	 * it won't have CB and that's okay
	 */
	cb_dev = msm_iommu_get_ctx("access_control");

	domain = iommu_domain_alloc(msm_iommu_non_sec_bus_type);
	if (!domain) {
		pr_err("Couldn't get domain for access control\n");
		goto err;
	}

	/*
	 * Map the region from start to kernel_start
	 */
	if (start < kernel_start) {
		ret = iommu_map(domain, start, start, kernel_start - start,
				IOMMU_READ | IOMMU_WRITE | IOMMU_DEVICE);

		if (ret) {
			pr_err("Mapping failed for region lower than kernel\n");
			goto free_dom;
		}
	}

	/*
	 * Map the region from kernel_end to end of DDR
	 */
	ret = iommu_map(domain, kernel_end, kernel_end, end - kernel_end + 1,
				IOMMU_READ | IOMMU_WRITE);

	if (ret) {
		pr_err("Mapping failed for region above kernel\n");
		goto free_dom;
	}

	ret = iommu_attach_device(domain, cb_dev);
	if (ret) {
		pr_err("Attach of access_control CB failed\n");
		goto free_dom;
	}

	return;

free_dom:
	iommu_domain_free(domain);
err:
	BUG();
}

/**
 * Pass the context bank device here. Based on the context bank
 * device, the bus is chosen and hence the respective IOMMU ops.
+3 −0
Original line number Diff line number Diff line
@@ -666,6 +666,9 @@ static int msm_iommu_ctx_probe(struct platform_device *pdev)

		dev_info(&pdev->dev, "context %s using bank %d\n",
			 ctx_drvdata->name, ctx_drvdata->num);

		if (strcmp(ctx_drvdata->name, "access_control") == 0)
			msm_access_control();
	}

	return ret;
+5 −0
Original line number Diff line number Diff line
@@ -338,6 +338,7 @@ void msm_iommu_remote_p0_spin_unlock(unsigned int need_lock);
struct device *msm_iommu_get_ctx(const char *ctx_name);
struct bus_type *msm_iommu_get_bus(struct device *dev);
int msm_iommu_bus_register(void);
void msm_access_control(void);
#else
static inline struct device *msm_iommu_get_ctx(const char *ctx_name)
{
@@ -348,6 +349,10 @@ static inline struct bus_type *msm_iommu_get_bus(struct device *dev)
{
	return &platform_bus_type;
}

static inline void msm_access_control(void)
{
}
#endif

/*