diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c | 16 |
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 | ||