aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFelipe Contreras <felipe.contreras@nokia.com>2011-03-11 19:29:06 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2011-03-14 15:22:27 -0400
commitab42abf33a3efdf754710a0a513c00c40854cd61 (patch)
treea8c7a9aa9b6cab93b767caed5bfaf4b318711e8b
parent17e2a542032f3ab735352d1d4b5d2ca3c154158a (diff)
staging: tidspbridge: protect dmm_map properly
We need to protect not only the dmm_map list, but the individual map_obj's, otherwise, we might be building the scatter-gather list with garbage. So, use the existing proc_lock for that. I observed race conditions which caused kernel panics while running stress tests, also, Tuomas Kulve found it happening quite often in Gumstix Over. This patch fixes those. Cc: Tuomas Kulve <tuomas@kulve.fi> Signed-off-by: Felipe Contreras <felipe.contreras@nokia.com> Signed-off-by: Omar Ramirez Luna <omar.ramirez@ti.com> Cc: stable <stable@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/staging/tidspbridge/rmgr/proc.c19
1 files changed, 14 insertions, 5 deletions
diff --git a/drivers/staging/tidspbridge/rmgr/proc.c b/drivers/staging/tidspbridge/rmgr/proc.c
index 54f61336d778..c4e5c4e0d71c 100644
--- a/drivers/staging/tidspbridge/rmgr/proc.c
+++ b/drivers/staging/tidspbridge/rmgr/proc.c
@@ -779,12 +779,14 @@ int proc_begin_dma(void *hprocessor, void *pmpu_addr, u32 ul_size,
779 (u32)pmpu_addr, 779 (u32)pmpu_addr,
780 ul_size, dir); 780 ul_size, dir);
781 781
782 mutex_lock(&proc_lock);
783
782 /* find requested memory are in cached mapping information */ 784 /* find requested memory are in cached mapping information */
783 map_obj = find_containing_mapping(pr_ctxt, (u32) pmpu_addr, ul_size); 785 map_obj = find_containing_mapping(pr_ctxt, (u32) pmpu_addr, ul_size);
784 if (!map_obj) { 786 if (!map_obj) {
785 pr_err("%s: find_containing_mapping failed\n", __func__); 787 pr_err("%s: find_containing_mapping failed\n", __func__);
786 status = -EFAULT; 788 status = -EFAULT;
787 goto err_out; 789 goto no_map;
788 } 790 }
789 791
790 if (memory_give_ownership(map_obj, (u32) pmpu_addr, ul_size, dir)) { 792 if (memory_give_ownership(map_obj, (u32) pmpu_addr, ul_size, dir)) {
@@ -793,6 +795,8 @@ int proc_begin_dma(void *hprocessor, void *pmpu_addr, u32 ul_size,
793 status = -EFAULT; 795 status = -EFAULT;
794 } 796 }
795 797
798no_map:
799 mutex_unlock(&proc_lock);
796err_out: 800err_out:
797 801
798 return status; 802 return status;
@@ -817,21 +821,24 @@ int proc_end_dma(void *hprocessor, void *pmpu_addr, u32 ul_size,
817 (u32)pmpu_addr, 821 (u32)pmpu_addr,
818 ul_size, dir); 822 ul_size, dir);
819 823
824 mutex_lock(&proc_lock);
825
820 /* find requested memory are in cached mapping information */ 826 /* find requested memory are in cached mapping information */
821 map_obj = find_containing_mapping(pr_ctxt, (u32) pmpu_addr, ul_size); 827 map_obj = find_containing_mapping(pr_ctxt, (u32) pmpu_addr, ul_size);
822 if (!map_obj) { 828 if (!map_obj) {
823 pr_err("%s: find_containing_mapping failed\n", __func__); 829 pr_err("%s: find_containing_mapping failed\n", __func__);
824 status = -EFAULT; 830 status = -EFAULT;
825 goto err_out; 831 goto no_map;
826 } 832 }
827 833
828 if (memory_regain_ownership(map_obj, (u32) pmpu_addr, ul_size, dir)) { 834 if (memory_regain_ownership(map_obj, (u32) pmpu_addr, ul_size, dir)) {
829 pr_err("%s: InValid address parameters %p %x\n", 835 pr_err("%s: InValid address parameters %p %x\n",
830 __func__, pmpu_addr, ul_size); 836 __func__, pmpu_addr, ul_size);
831 status = -EFAULT; 837 status = -EFAULT;
832 goto err_out;
833 } 838 }
834 839
840no_map:
841 mutex_unlock(&proc_lock);
835err_out: 842err_out:
836 return status; 843 return status;
837} 844}
@@ -1724,9 +1731,8 @@ int proc_un_map(void *hprocessor, void *map_addr,
1724 (p_proc_object->bridge_context, va_align, size_align); 1731 (p_proc_object->bridge_context, va_align, size_align);
1725 } 1732 }
1726 1733
1727 mutex_unlock(&proc_lock);
1728 if (status) 1734 if (status)
1729 goto func_end; 1735 goto unmap_failed;
1730 1736
1731 /* 1737 /*
1732 * A successful unmap should be followed by removal of map_obj 1738 * A successful unmap should be followed by removal of map_obj
@@ -1735,6 +1741,9 @@ int proc_un_map(void *hprocessor, void *map_addr,
1735 */ 1741 */
1736 remove_mapping_information(pr_ctxt, (u32) map_addr, size_align); 1742 remove_mapping_information(pr_ctxt, (u32) map_addr, size_align);
1737 1743
1744unmap_failed:
1745 mutex_unlock(&proc_lock);
1746
1738func_end: 1747func_end:
1739 dev_dbg(bridge, "%s: hprocessor: 0x%p map_addr: 0x%p status: 0x%x\n", 1748 dev_dbg(bridge, "%s: hprocessor: 0x%p map_addr: 0x%p status: 0x%x\n",
1740 __func__, hprocessor, map_addr, status); 1749 __func__, hprocessor, map_addr, status);