summaryrefslogtreecommitdiff
path: root/drivers/gpu/msm
diff options
context:
space:
mode:
authorMichael Bestas <mkbestas@lineageos.org>2022-11-05 17:51:13 +0200
committerMichael Bestas <mkbestas@lineageos.org>2022-11-05 17:51:13 +0200
commit7dbda95466d5447b89c0209f0086815bbecc5e2f (patch)
tree706dcb52841614b589db43dbc4d9b62d6a6c4c79 /drivers/gpu/msm
parent369119e5df4e48f1e737791e781da185b7810921 (diff)
parent67887f6ac3f11fd5ee1639e18d854e6071e58c51 (diff)
Merge tag 'LA.UM.8.4.c25-06600-8x98.0' of https://git.codelinaro.org/clo/la/kernel/msm-4.4 into android13-4.4-msm8998
"LA.UM.8.4.c25-06600-8x98.0" * tag 'LA.UM.8.4.c25-06600-8x98.0' of https://git.codelinaro.org/clo/la/kernel/msm-4.4: diag: Prevent out of bound write while sending dci pkt to remote diag: Ensure dci entry is valid before sending the packet ion: Fix integer overflow in msm_ion_custom_ioctl diag: Use valid data_source for a valid token msm: kgsl: Remove 'fd' dependency to get dma_buf handle msm: kgsl: Fix gpuaddr_in_range() to check upper bound msm: adsprpc: Handle UAF in fastrpc debugfs read msm: kgsl: Add a sysfs node to control performance counter reads msm: kgsl: Perform cache flush on the pages obtained using get_user_pages() soc: qcom: hab: Add sanity check for payload_count msm: kgsl: Fix out of bound write in adreno_profile_submit_time futex: Fix inode life-time issue futex: Handle faults correctly for PI futexes futex: Simplify fixup_pi_state_owner() futex: Use pi_state_update_owner() in put_pi_state() rtmutex: Remove unused argument from rt_mutex_proxy_unlock() futex: Provide and use pi_state_update_owner() futex: Replace pointless printk in fixup_owner() futex: Avoid violating the 10th rule of futex futex: Rework inconsistent rt_mutex/futex_q state futex: Remove rt_mutex_deadlock_account_*() futex,rt_mutex: Provide futex specific rt_mutex API msm: adsprpc: Handle UAF in process shell memory Disable TRACER Check to improve Camera Performance msm: kgsl: Deregister gpu address on memdesc_sg_virt failure crypto: Fix possible stack out-of-bound error msm: kgsl: Correct the refcount on current process PID. msm: kgsl: Compare pid pointer instead of TGID for a new process qcom,max-freq-level change for trial msm: kgsl: Protect the memdesc->gpuaddr in SVM use cases. msm: kgsl: Stop using memdesc->usermem. Conflicts: drivers/char/adsprpc.c drivers/char/diag/diag_dci.c drivers/gpu/msm/kgsl.c drivers/gpu/msm/kgsl_debugfs.c drivers/gpu/msm/kgsl_iommu.c drivers/gpu/msm/kgsl_mmu.c drivers/gpu/msm/kgsl_sharedmem.c drivers/gpu/msm/kgsl_trace.h kernel/futex.c kernel/locking/rtmutex.c kernel/locking/rtmutex_common.h Change-Id: I777ee96b855e2967ef6733e603d12f40174974d0
Diffstat (limited to 'drivers/gpu/msm')
-rw-r--r--drivers/gpu/msm/adreno.c3
-rw-r--r--drivers/gpu/msm/adreno.h7
-rw-r--r--drivers/gpu/msm/adreno_compat.c9
-rw-r--r--drivers/gpu/msm/adreno_dispatch.c4
-rw-r--r--drivers/gpu/msm/adreno_ioctl.c9
-rw-r--r--drivers/gpu/msm/adreno_sysfs.c33
-rw-r--r--drivers/gpu/msm/kgsl.c34
-rw-r--r--drivers/gpu/msm/kgsl_iommu.c10
-rw-r--r--drivers/gpu/msm/kgsl_mmu.c8
-rw-r--r--drivers/gpu/msm/kgsl_mmu.h7
10 files changed, 97 insertions, 27 deletions
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index 172d8a2c6136..a2249cda051e 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -1,4 +1,5 @@
/* Copyright (c) 2002,2007-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. 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
@@ -1016,6 +1017,8 @@ static int adreno_probe(struct platform_device *pdev)
adreno_debugfs_init(adreno_dev);
adreno_profile_init(adreno_dev);
+ adreno_dev->perfcounter = false;
+
adreno_sysfs_init(adreno_dev);
kgsl_pwrscale_init(&pdev->dev, CONFIG_QCOM_ADRENO_DEFAULT_GOVERNOR);
diff --git a/drivers/gpu/msm/adreno.h b/drivers/gpu/msm/adreno.h
index 5434cfb4083b..1868b0d5ec0a 100644
--- a/drivers/gpu/msm/adreno.h
+++ b/drivers/gpu/msm/adreno.h
@@ -1,4 +1,5 @@
/* Copyright (c) 2008-2018,2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. 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
@@ -439,6 +440,12 @@ struct adreno_device {
struct list_head active_list;
spinlock_t active_list_lock;
+
+ /*
+ * @perfcounter: Flag to clear perfcounters across contexts and
+ * controls perfcounter ioctl read
+ */
+ bool perfcounter;
};
/**
diff --git a/drivers/gpu/msm/adreno_compat.c b/drivers/gpu/msm/adreno_compat.c
index 5a8d587d4536..faaec90ba74a 100644
--- a/drivers/gpu/msm/adreno_compat.c
+++ b/drivers/gpu/msm/adreno_compat.c
@@ -1,4 +1,5 @@
/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. 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
@@ -229,6 +230,14 @@ static long adreno_ioctl_perfcounter_read_compat(
struct kgsl_perfcounter_read_compat *read32 = data;
struct kgsl_perfcounter_read read;
+ /*
+ * When performance counter zapping is enabled, the counters are cleared
+ * across context switches. Reading the counters when they are zapped is
+ * not permitted.
+ */
+ if (!adreno_dev->perfcounter)
+ return -EPERM;
+
read.reads = (struct kgsl_perfcounter_read_group __user *)
(uintptr_t)read32->reads;
read.count = read32->count;
diff --git a/drivers/gpu/msm/adreno_dispatch.c b/drivers/gpu/msm/adreno_dispatch.c
index 5209f1b2a2e6..3c804ca09371 100644
--- a/drivers/gpu/msm/adreno_dispatch.c
+++ b/drivers/gpu/msm/adreno_dispatch.c
@@ -1,4 +1,5 @@
/* Copyright (c) 2013-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. 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
@@ -1149,7 +1150,8 @@ static inline bool _verify_ib(struct kgsl_device_private *dev_priv,
}
/* Make sure that the address is mapped */
- if (!kgsl_mmu_gpuaddr_in_range(private->pagetable, ib->gpuaddr)) {
+ if (!kgsl_mmu_gpuaddr_in_range(private->pagetable, ib->gpuaddr,
+ ib->size)) {
pr_context(device, context, "ctxt %d invalid ib gpuaddr %llX\n",
context->id, ib->gpuaddr);
return false;
diff --git a/drivers/gpu/msm/adreno_ioctl.c b/drivers/gpu/msm/adreno_ioctl.c
index 0d5e3e094c36..579ba2b61863 100644
--- a/drivers/gpu/msm/adreno_ioctl.c
+++ b/drivers/gpu/msm/adreno_ioctl.c
@@ -1,4 +1,5 @@
/* Copyright (c) 2002,2007-2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. 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
@@ -76,6 +77,14 @@ static long adreno_ioctl_perfcounter_read(struct kgsl_device_private *dev_priv,
struct adreno_device *adreno_dev = ADRENO_DEVICE(dev_priv->device);
struct kgsl_perfcounter_read *read = data;
+ /*
+ * When performance counter zapping is enabled, the counters are cleared
+ * across context switches. Reading the counters when they are zapped is
+ * not permitted.
+ */
+ if (!adreno_dev->perfcounter)
+ return -EPERM;
+
return (long) adreno_perfcounter_read_group(adreno_dev, read->reads,
read->count);
}
diff --git a/drivers/gpu/msm/adreno_sysfs.c b/drivers/gpu/msm/adreno_sysfs.c
index f893b29e816e..a6c179f7c932 100644
--- a/drivers/gpu/msm/adreno_sysfs.c
+++ b/drivers/gpu/msm/adreno_sysfs.c
@@ -1,4 +1,5 @@
/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. 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
@@ -233,6 +234,31 @@ static unsigned int _lm_show(struct adreno_device *adreno_dev)
return test_bit(ADRENO_LM_CTRL, &adreno_dev->pwrctrl_flag);
}
+static unsigned int _perfcounter_show(struct adreno_device *adreno_dev)
+{
+ return adreno_dev->perfcounter;
+}
+
+static int _perfcounter_store(struct adreno_device *adreno_dev,
+ unsigned int val)
+{
+ struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
+
+ if (adreno_dev->perfcounter == val)
+ return 0;
+
+ mutex_lock(&device->mutex);
+
+ /* Power down the GPU before changing the state */
+ kgsl_pwrctrl_change_state(device, KGSL_STATE_SUSPEND);
+ adreno_dev->perfcounter = val;
+ kgsl_pwrctrl_change_state(device, KGSL_STATE_SLUMBER);
+
+ mutex_unlock(&device->mutex);
+
+ return 0;
+}
+
static ssize_t _sysfs_store_u32(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
@@ -327,6 +353,7 @@ static ADRENO_SYSFS_BOOL(lm);
static ADRENO_SYSFS_BOOL(preemption);
static ADRENO_SYSFS_BOOL(hwcg);
static ADRENO_SYSFS_BOOL(throttling);
+static ADRENO_SYSFS_BOOL(perfcounter);
@@ -343,6 +370,7 @@ static const struct device_attribute *_attr_list[] = {
&adreno_attr_preemption.attr,
&adreno_attr_hwcg.attr,
&adreno_attr_throttling.attr,
+ &adreno_attr_perfcounter.attr,
NULL,
};
@@ -499,8 +527,11 @@ int adreno_sysfs_init(struct adreno_device *adreno_dev)
ret = kgsl_create_device_sysfs_files(device->dev, _attr_list);
/* Add the PPD directory and files */
- if (ret == 0)
+ if (ret == 0) {
+ /* Notify userspace */
+ kobject_uevent(&device->dev->kobj, KOBJ_ADD);
ppd_sysfs_init(adreno_dev);
+ }
return 0;
}
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index bda0afed50b6..fc6ab898ccaa 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -1,4 +1,5 @@
/* Copyright (c) 2008-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. 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
@@ -1273,7 +1274,7 @@ kgsl_sharedmem_find(struct kgsl_process_private *private, uint64_t gpuaddr)
if (!private)
return NULL;
- if (!kgsl_mmu_gpuaddr_in_range(private->pagetable, gpuaddr))
+ if (!kgsl_mmu_gpuaddr_in_range(private->pagetable, gpuaddr, 0))
return NULL;
spin_lock(&private->mem_lock);
@@ -2183,6 +2184,15 @@ static int memdesc_sg_virt(struct kgsl_memdesc *memdesc, unsigned long useraddr)
ret = sg_alloc_table_from_pages(memdesc->sgt, pages, npages,
0, memdesc->size, GFP_KERNEL);
+
+ if (ret)
+ goto out;
+
+ ret = kgsl_cache_range_op(memdesc, 0, memdesc->size,
+ KGSL_CACHE_OP_FLUSH);
+
+ if (ret)
+ sg_free_table(memdesc->sgt);
out:
if (ret) {
for (i = 0; i < npages; i++)
@@ -2231,15 +2241,6 @@ static int kgsl_setup_anon_useraddr(struct kgsl_pagetable *pagetable,
return ret;
}
-static int match_file(const void *p, struct file *file, unsigned int fd)
-{
- /*
- * We must return fd + 1 because iterate_fd stops searching on
- * non-zero return, but 0 is a valid fd.
- */
- return (p == file) ? (fd + 1) : 0;
-}
-
static void _setup_cache_mode(struct kgsl_mem_entry *entry,
struct vm_area_struct *vma)
{
@@ -2278,8 +2279,6 @@ static int kgsl_setup_dmabuf_useraddr(struct kgsl_device *device,
vma = find_vma(current->mm, hostptr);
if (vma && vma->vm_file) {
- int fd;
-
ret = check_vma_flags(vma, entry->memdesc.flags);
if (ret) {
up_read(&current->mm->mmap_sem);
@@ -2295,10 +2294,13 @@ static int kgsl_setup_dmabuf_useraddr(struct kgsl_device *device,
return -EFAULT;
}
- /* Look for the fd that matches this the vma file */
- fd = iterate_fd(current->files, 0, match_file, vma->vm_file);
- if (fd != 0)
- dmabuf = dma_buf_get(fd - 1);
+ /*
+ * Take a refcount because dma_buf_put() decrements the
+ * refcount
+ */
+ get_file(vma->vm_file);
+
+ dmabuf = vma->vm_file->private_data;
}
if (IS_ERR_OR_NULL(dmabuf)) {
diff --git a/drivers/gpu/msm/kgsl_iommu.c b/drivers/gpu/msm/kgsl_iommu.c
index 98537730cbc9..31e8a7ea5f65 100644
--- a/drivers/gpu/msm/kgsl_iommu.c
+++ b/drivers/gpu/msm/kgsl_iommu.c
@@ -1,4 +1,5 @@
/* Copyright (c) 2011-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. 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
@@ -2525,20 +2526,21 @@ static int kgsl_iommu_svm_range(struct kgsl_pagetable *pagetable,
}
static bool kgsl_iommu_addr_in_range(struct kgsl_pagetable *pagetable,
- uint64_t gpuaddr)
+ uint64_t gpuaddr, uint64_t size)
{
struct kgsl_iommu_pt *pt = pagetable->priv;
if (gpuaddr == 0)
return false;
- if (gpuaddr >= pt->va_start && gpuaddr < pt->va_end)
+ if (gpuaddr >= pt->va_start && (gpuaddr + size) < pt->va_end)
return true;
- if (gpuaddr >= pt->compat_va_start && gpuaddr < pt->compat_va_end)
+ if (gpuaddr >= pt->compat_va_start &&
+ (gpuaddr + size) < pt->compat_va_end)
return true;
- if (gpuaddr >= pt->svm_start && gpuaddr < pt->svm_end)
+ if (gpuaddr >= pt->svm_start && (gpuaddr + size) < pt->svm_end)
return true;
return false;
diff --git a/drivers/gpu/msm/kgsl_mmu.c b/drivers/gpu/msm/kgsl_mmu.c
index d0a45e713d0d..228f3396ae90 100644
--- a/drivers/gpu/msm/kgsl_mmu.c
+++ b/drivers/gpu/msm/kgsl_mmu.c
@@ -1,4 +1,5 @@
/* Copyright (c) 2002,2007-2017,2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. 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
@@ -606,10 +607,11 @@ enum kgsl_mmutype kgsl_mmu_get_mmutype(struct kgsl_device *device)
EXPORT_SYMBOL(kgsl_mmu_get_mmutype);
bool kgsl_mmu_gpuaddr_in_range(struct kgsl_pagetable *pagetable,
- uint64_t gpuaddr)
+ uint64_t gpuaddr, uint64_t size)
{
if (PT_OP_VALID(pagetable, addr_in_range))
- return pagetable->pt_ops->addr_in_range(pagetable, gpuaddr);
+ return pagetable->pt_ops->addr_in_range(pagetable,
+ gpuaddr, size);
return false;
}
@@ -645,7 +647,7 @@ EXPORT_SYMBOL(kgsl_mmu_get_qtimer_global_entry);
*/
static bool nommu_gpuaddr_in_range(struct kgsl_pagetable *pagetable,
- uint64_t gpuaddr)
+ uint64_t gpuaddr, uint64_t size)
{
return (gpuaddr != 0) ? true : false;
}
diff --git a/drivers/gpu/msm/kgsl_mmu.h b/drivers/gpu/msm/kgsl_mmu.h
index 505fe591a53e..fcf3b188f9f7 100644
--- a/drivers/gpu/msm/kgsl_mmu.h
+++ b/drivers/gpu/msm/kgsl_mmu.h
@@ -1,4 +1,5 @@
/* Copyright (c) 2002,2007-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. 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
@@ -99,7 +100,8 @@ struct kgsl_mmu_pt_ops {
int (*set_svm_region)(struct kgsl_pagetable *, uint64_t, uint64_t);
int (*svm_range)(struct kgsl_pagetable *, uint64_t *, uint64_t *,
uint64_t);
- bool (*addr_in_range)(struct kgsl_pagetable *pagetable, uint64_t);
+ bool (*addr_in_range)(struct kgsl_pagetable *pagetable,
+ uint64_t, uint64_t);
int (*mmu_map_offset)(struct kgsl_pagetable *pt,
uint64_t virtaddr, uint64_t virtoffset,
struct kgsl_memdesc *memdesc, uint64_t physoffset,
@@ -187,7 +189,8 @@ unsigned int kgsl_virtaddr_to_physaddr(void *virtaddr);
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);
-bool kgsl_mmu_gpuaddr_in_range(struct kgsl_pagetable *pt, uint64_t gpuaddr);
+bool kgsl_mmu_gpuaddr_in_range(struct kgsl_pagetable *pt, uint64_t gpuaddr,
+ uint64_t size);
int kgsl_mmu_get_region(struct kgsl_pagetable *pagetable,
uint64_t gpuaddr, uint64_t size);