summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDebarshi Dutta <ddutta@nvidia.com>2019-10-31 06:33:33 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2020-01-24 06:41:52 -0500
commitf0fca24ffb03c14647e03d611b901bf02426c37a (patch)
tree8882758b169918d444fe30747233d9da8863f76b
parent9e9046f03cf3125067666dc652499a4b7f39d9c0 (diff)
gpu: nvgpu: avoid double mapping of usermode mmap region
gk20a_pm_runtime_suspend can fail and invoke gk20a_pm_finalize_poweron that can cause double mapping of the usermode mmap region via io_remap_pfn_range(). Avoid this by using a boolean variable to track whether the region is already mapped. Bug 2707416 Bug 200582208 Change-Id: I4d8cbe427400a5b986348a19af145367cc08ffc6 Signed-off-by: Debarshi Dutta <ddutta@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2229312 Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2283801 Reviewed-by: Kajetan Dutka <kdutka@nvidia.com> Reviewed-by: Thomas Fleury <tfleury@nvidia.com> Reviewed-by: Amulya Yarlagadda <ayarlagadda@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: Kajetan Dutka <kdutka@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
-rw-r--r--drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c b/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c
index 9b4f50a5..dfa9edf3 100644
--- a/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c
+++ b/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c
@@ -60,6 +60,7 @@ struct gk20a_ctrl_priv {
60 struct { 60 struct {
61 struct vm_area_struct *vma; 61 struct vm_area_struct *vma;
62 unsigned long flags; 62 unsigned long flags;
63 bool vma_mapped;
63 } usermode_vma; 64 } usermode_vma;
64}; 65};
65 66
@@ -1925,6 +1926,7 @@ static void usermode_vma_close(struct vm_area_struct *vma)
1925 1926
1926 nvgpu_mutex_acquire(&l->ctrl.privs_lock); 1927 nvgpu_mutex_acquire(&l->ctrl.privs_lock);
1927 priv->usermode_vma.vma = NULL; 1928 priv->usermode_vma.vma = NULL;
1929 priv->usermode_vma.vma_mapped = false;
1928 nvgpu_mutex_release(&l->ctrl.privs_lock); 1930 nvgpu_mutex_release(&l->ctrl.privs_lock);
1929} 1931}
1930 1932
@@ -1974,6 +1976,7 @@ int gk20a_ctrl_dev_mmap(struct file *filp, struct vm_area_struct *vma)
1974 priv->usermode_vma.vma = vma; 1976 priv->usermode_vma.vma = vma;
1975 priv->usermode_vma.flags = vma->vm_flags; 1977 priv->usermode_vma.flags = vma->vm_flags;
1976 vma->vm_private_data = priv; 1978 vma->vm_private_data = priv;
1979 priv->usermode_vma.vma_mapped = true;
1977 } 1980 }
1978 nvgpu_mutex_release(&l->ctrl.privs_lock); 1981 nvgpu_mutex_release(&l->ctrl.privs_lock);
1979 1982
@@ -1988,6 +1991,7 @@ static void alter_usermode_mapping(struct gk20a *g,
1988{ 1991{
1989 struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); 1992 struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
1990 struct vm_area_struct *vma = priv->usermode_vma.vma; 1993 struct vm_area_struct *vma = priv->usermode_vma.vma;
1994 bool vma_mapped = priv->usermode_vma.vma_mapped;
1991 u64 addr; 1995 u64 addr;
1992 int err; 1996 int err;
1993 1997
@@ -2000,14 +2004,20 @@ static void alter_usermode_mapping(struct gk20a *g,
2000 2004
2001 down_write(&vma->vm_mm->mmap_sem); 2005 down_write(&vma->vm_mm->mmap_sem);
2002 2006
2003 if (poweroff) { 2007 /*
2008 * This is a no-op for the below cases
2009 * a) poweroff and !vma_mapped - > do nothing as no map exists
2010 * b) !poweroff and vmap_mapped -> do nothing as already mapped
2011 */
2012 if (poweroff && vma_mapped) {
2004 err = zap_vma_ptes(vma, vma->vm_start, SZ_4K); 2013 err = zap_vma_ptes(vma, vma->vm_start, SZ_4K);
2005 if (err == 0) { 2014 if (err == 0) {
2006 vma->vm_flags = VM_NONE; 2015 vma->vm_flags = VM_NONE;
2016 priv->usermode_vma.vma_mapped = false;
2007 } else { 2017 } else {
2008 nvgpu_err(g, "can't remove usermode mapping"); 2018 nvgpu_err(g, "can't remove usermode mapping");
2009 } 2019 }
2010 } else { 2020 } else if (!poweroff && !vma_mapped) {
2011 vma->vm_flags = priv->usermode_vma.flags; 2021 vma->vm_flags = priv->usermode_vma.flags;
2012 err = io_remap_pfn_range(vma, vma->vm_start, 2022 err = io_remap_pfn_range(vma, vma->vm_start,
2013 addr >> PAGE_SHIFT, 2023 addr >> PAGE_SHIFT,
@@ -2015,6 +2025,8 @@ static void alter_usermode_mapping(struct gk20a *g,
2015 if (err != 0) { 2025 if (err != 0) {
2016 nvgpu_err(g, "can't restore usermode mapping"); 2026 nvgpu_err(g, "can't restore usermode mapping");
2017 vma->vm_flags = VM_NONE; 2027 vma->vm_flags = VM_NONE;
2028 } else {
2029 priv->usermode_vma.vma_mapped = true;
2018 } 2030 }
2019 } 2031 }
2020 2032