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

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

Merge "msm: kgsl: Enable guard page for GPUOBJ_IMPORT ioctl"

parents c650b665 a4c4bff1
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -2252,6 +2252,7 @@ long kgsl_ioctl_gpuobj_import(struct kgsl_device_private *dev_priv,
	struct kgsl_gpuobj_import *param = data;
	struct kgsl_mem_entry *entry;
	int ret, fd = -1;
	struct kgsl_mmu *mmu = &dev_priv->device->mmu;

	entry = kgsl_mem_entry_create();
	if (entry == NULL)
@@ -2266,6 +2267,9 @@ long kgsl_ioctl_gpuobj_import(struct kgsl_device_private *dev_priv,

	entry->memdesc.flags = param->flags;

	if (MMU_FEATURE(mmu, KGSL_MMU_NEED_GUARD_PAGE))
		entry->memdesc.priv |= KGSL_MEMDESC_GUARD_PAGE;

	if (param->type == KGSL_USER_MEM_TYPE_ADDR)
		ret = _gpuobj_map_useraddr(dev_priv->device, private->pagetable,
			entry, param);
+12 −26
Original line number Diff line number Diff line
@@ -390,11 +390,10 @@ static void _get_entries(struct kgsl_process_private *private,
}

static void _find_mem_entries(struct kgsl_mmu *mmu, uint64_t faultaddr,
	phys_addr_t ptbase, struct _mem_entry *preventry,
	struct _mem_entry *nextentry)
		struct _mem_entry *preventry, struct _mem_entry *nextentry,
		struct kgsl_context *context)
{
	struct kgsl_process_private *private = NULL, *p;
	int id = kgsl_mmu_get_ptname_from_ptbase(mmu, ptbase);
	struct kgsl_process_private *private;

	memset(preventry, 0, sizeof(*preventry));
	memset(nextentry, 0, sizeof(*nextentry));
@@ -402,22 +401,11 @@ static void _find_mem_entries(struct kgsl_mmu *mmu, uint64_t faultaddr,
	/* Set the maximum possible size as an initial value */
	nextentry->gpuaddr = (uint64_t) -1;

	mutex_lock(&kgsl_driver.process_mutex);
	list_for_each_entry(p, &kgsl_driver.process_list, list) {
		if (p->pagetable && (p->pagetable->name == id)) {
			if (kgsl_process_private_get(p))
				private = p;
			break;
		}
	}
	mutex_unlock(&kgsl_driver.process_mutex);

	if (private != NULL) {
	if (context) {
		private = context->proc_priv;
		spin_lock(&private->mem_lock);
		_get_entries(private, faultaddr, preventry, nextentry);
		spin_unlock(&private->mem_lock);

		kgsl_process_private_put(private);
	}
}

@@ -467,6 +455,7 @@ static int kgsl_iommu_fault_handler(struct iommu_domain *domain,
	struct kgsl_iommu_context *ctx;
	u64 ptbase;
	u32 contextidr;
	pid_t tid = 0;
	pid_t ptname;
	struct _mem_entry prev, next;
	int write;
@@ -507,9 +496,7 @@ static int kgsl_iommu_fault_handler(struct iommu_domain *domain,
	if (context != NULL) {
		/* save pagefault timestamp for GFT */
		set_bit(KGSL_CONTEXT_PRIV_PAGEFAULT, &context->priv);

		kgsl_context_put(context);
		context = NULL;
		tid = context->tid;
	}

	ctx->fault = 1;
@@ -535,7 +522,8 @@ static int kgsl_iommu_fault_handler(struct iommu_domain *domain,
	ptbase = KGSL_IOMMU_GET_CTX_REG_Q(ctx, TTBR0);
	contextidr = KGSL_IOMMU_GET_CTX_REG(ctx, CONTEXTIDR);

	ptname = kgsl_mmu_get_ptname_from_ptbase(mmu, ptbase);
	ptname = MMU_FEATURE(mmu, KGSL_MMU_GLOBAL_PAGETABLE) ?
		KGSL_MMU_GLOBAL_PT : tid;

	if (test_bit(KGSL_FT_PAGEFAULT_LOG_ONE_PER_PAGE,
		&adreno_dev->ft_pf_policy))
@@ -556,8 +544,7 @@ static int kgsl_iommu_fault_handler(struct iommu_domain *domain,
			KGSL_LOG_DUMP(ctx->kgsldev,
				"---- nearby memory ----\n");

			_find_mem_entries(mmu, addr, ptbase, &prev, &next);

			_find_mem_entries(mmu, addr, &prev, &next, context);
			if (prev.gpuaddr)
				_print_entry(ctx->kgsldev, &prev);
			else
@@ -570,13 +557,11 @@ static int kgsl_iommu_fault_handler(struct iommu_domain *domain,
				_print_entry(ctx->kgsldev, &next);
			else
				KGSL_LOG_DUMP(ctx->kgsldev, "*EMPTY*\n");

		}
	}

	trace_kgsl_mmu_pagefault(ctx->kgsldev, addr,
			kgsl_mmu_get_ptname_from_ptbase(mmu, ptbase),
			write ? "write" : "read");
			ptname, write ? "write" : "read");

	/*
	 * We do not want the h/w to resume fetching data from an iommu
@@ -602,6 +587,7 @@ static int kgsl_iommu_fault_handler(struct iommu_domain *domain,
		adreno_dispatcher_schedule(device);
	}

	kgsl_context_put(context);
	return ret;
}

+0 −22
Original line number Diff line number Diff line
@@ -217,28 +217,6 @@ kgsl_mmu_detach_pagetable(struct kgsl_pagetable *pagetable)
	pagetable_remove_sysfs_objects(pagetable);
}

int
kgsl_mmu_get_ptname_from_ptbase(struct kgsl_mmu *mmu, u64 pt_base)
{
	struct kgsl_pagetable *pt;
	int ptid = -1;

	if (!MMU_OP_VALID(mmu, mmu_pt_equal))
		return KGSL_MMU_GLOBAL_PT;

	spin_lock(&kgsl_driver.ptlock);
	list_for_each_entry(pt, &kgsl_driver.pagetable_list, list) {
		if (mmu->mmu_ops->mmu_pt_equal(mmu, pt, pt_base)) {
			ptid = (int) pt->name;
			break;
		}
	}
	spin_unlock(&kgsl_driver.ptlock);

	return ptid;
}
EXPORT_SYMBOL(kgsl_mmu_get_ptname_from_ptbase);

struct kgsl_pagetable *kgsl_mmu_get_pt_from_ptname(struct kgsl_mmu *mmu,
						int ptname)
{
+0 −1
Original line number Diff line number Diff line
@@ -166,7 +166,6 @@ int kgsl_mmu_unmap(struct kgsl_pagetable *pagetable,
void kgsl_mmu_put_gpuaddr(struct kgsl_pagetable *pagetable,
		 struct kgsl_memdesc *memdesc);
unsigned int kgsl_virtaddr_to_physaddr(void *virtaddr);
int kgsl_mmu_get_ptname_from_ptbase(struct kgsl_mmu *mmu, u64 pt_base);
unsigned int kgsl_mmu_log_fault_addr(struct kgsl_mmu *mmu,
		u64 ttbr0, uint64_t addr);
enum kgsl_mmutype kgsl_mmu_get_mmutype(struct kgsl_device *device);
+9 −9
Original line number Diff line number Diff line
@@ -129,11 +129,10 @@ static size_t snapshot_os(struct kgsl_device *device,
{
	struct kgsl_snapshot_linux *header = (struct kgsl_snapshot_linux *)buf;
	struct kgsl_pwrctrl *pwr = &device->pwrctrl;
	struct task_struct *task;
	pid_t pid;
	int ctxtcount = 0;
	size_t size = sizeof(*header);
	u64 temp_ptbase;
	struct kgsl_context *context;

	/* Figure out how many active contexts there are - these will
	 * be appended on the end of the structure */
@@ -176,19 +175,20 @@ static size_t snapshot_os(struct kgsl_device *device,
	kgsl_sharedmem_readl(&device->memstore, &header->current_context,
		KGSL_MEMSTORE_OFFSET(KGSL_MEMSTORE_GLOBAL, current_context));

	context = kgsl_context_get(device, header->current_context);

	/* Get the current PT base */
	temp_ptbase = kgsl_mmu_get_current_ttbr0(&device->mmu);
	/* Truncate to 32 bits in case LPAE is used */
	header->ptbase = (__u32)temp_ptbase;
	/* And the PID for the task leader */
	pid = header->pid = kgsl_mmu_get_ptname_from_ptbase(&device->mmu,
								temp_ptbase);

	task = find_task_by_vpid(pid);

	if (task)
		get_task_comm(header->comm, task);
	if (context) {
		header->pid = context->tid;
		strlcpy(header->comm, context->proc_priv->comm,
				sizeof(header->comm));
		kgsl_context_put(context);
		context = NULL;
	}

	header->ctxtcount = ctxtcount;