hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/drivers/misc/sgi-gru/grufault.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * SN Platform GRU Driver
34 *
....@@ -8,20 +9,6 @@
89 * the user CB.
910 *
1011 * Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved.
11
- *
12
- * This program is free software; you can redistribute it and/or modify
13
- * it under the terms of the GNU General Public License as published by
14
- * the Free Software Foundation; either version 2 of the License, or
15
- * (at your option) any later version.
16
- *
17
- * This program is distributed in the hope that it will be useful,
18
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20
- * GNU General Public License for more details.
21
- *
22
- * You should have received a copy of the GNU General Public License
23
- * along with this program; if not, write to the Free Software
24
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2512 */
2613
2714 #include <linux/kernel.h>
....@@ -33,8 +20,8 @@
3320 #include <linux/io.h>
3421 #include <linux/uaccess.h>
3522 #include <linux/security.h>
23
+#include <linux/sync_core.h>
3624 #include <linux/prefetch.h>
37
-#include <asm/pgtable.h>
3825 #include "gru.h"
3926 #include "grutables.h"
4027 #include "grulib.h"
....@@ -56,7 +43,7 @@
5643 }
5744
5845 /*
59
- * Find the vma of a GRU segment. Caller must hold mmap_sem.
46
+ * Find the vma of a GRU segment. Caller must hold mmap_lock.
6047 */
6148 struct vm_area_struct *gru_find_vma(unsigned long vaddr)
6249 {
....@@ -72,7 +59,7 @@
7259 * Find and lock the gts that contains the specified user vaddr.
7360 *
7461 * Returns:
75
- * - *gts with the mmap_sem locked for read and the GTS locked.
62
+ * - *gts with the mmap_lock locked for read and the GTS locked.
7663 * - NULL if vaddr invalid OR is not a valid GSEG vaddr.
7764 */
7865
....@@ -82,14 +69,14 @@
8269 struct vm_area_struct *vma;
8370 struct gru_thread_state *gts = NULL;
8471
85
- down_read(&mm->mmap_sem);
72
+ mmap_read_lock(mm);
8673 vma = gru_find_vma(vaddr);
8774 if (vma)
8875 gts = gru_find_thread_state(vma, TSID(vaddr, vma));
8976 if (gts)
9077 mutex_lock(&gts->ts_ctxlock);
9178 else
92
- up_read(&mm->mmap_sem);
79
+ mmap_read_unlock(mm);
9380 return gts;
9481 }
9582
....@@ -99,7 +86,7 @@
9986 struct vm_area_struct *vma;
10087 struct gru_thread_state *gts = ERR_PTR(-EINVAL);
10188
102
- down_write(&mm->mmap_sem);
89
+ mmap_write_lock(mm);
10390 vma = gru_find_vma(vaddr);
10491 if (!vma)
10592 goto err;
....@@ -108,11 +95,11 @@
10895 if (IS_ERR(gts))
10996 goto err;
11097 mutex_lock(&gts->ts_ctxlock);
111
- downgrade_write(&mm->mmap_sem);
98
+ mmap_write_downgrade(mm);
11299 return gts;
113100
114101 err:
115
- up_write(&mm->mmap_sem);
102
+ mmap_write_unlock(mm);
116103 return gts;
117104 }
118105
....@@ -122,7 +109,7 @@
122109 static void gru_unlock_gts(struct gru_thread_state *gts)
123110 {
124111 mutex_unlock(&gts->ts_ctxlock);
125
- up_read(&current->mm->mmap_sem);
112
+ mmap_read_unlock(current->mm);
126113 }
127114
128115 /*
....@@ -212,7 +199,7 @@
212199 * Only supports Intel large pages (2MB only) on x86_64.
213200 * ZZZ - hugepage support is incomplete
214201 *
215
- * NOTE: mmap_sem is already held on entry to this function. This
202
+ * NOTE: mmap_lock is already held on entry to this function. This
216203 * guarantees existence of the page tables.
217204 */
218205 static int atomic_pte_lookup(struct vm_area_struct *vma, unsigned long vaddr,
....@@ -583,14 +570,14 @@
583570 }
584571
585572 /*
586
- * This is running in interrupt context. Trylock the mmap_sem.
573
+ * This is running in interrupt context. Trylock the mmap_lock.
587574 * If it fails, retry the fault in user context.
588575 */
589576 gts->ustats.fmm_tlbmiss++;
590577 if (!gts->ts_force_cch_reload &&
591
- down_read_trylock(&gts->ts_mm->mmap_sem)) {
578
+ mmap_read_trylock(gts->ts_mm)) {
592579 gru_try_dropin(gru, gts, tfh, NULL);
593
- up_read(&gts->ts_mm->mmap_sem);
580
+ mmap_read_unlock(gts->ts_mm);
594581 } else {
595582 tfh_user_polling_mode(tfh);
596583 STAT(intr_mm_lock_failed);
....@@ -616,8 +603,8 @@
616603 for_each_possible_blade(blade) {
617604 if (uv_blade_nr_possible_cpus(blade))
618605 continue;
619
- gru_intr(0, blade);
620
- gru_intr(1, blade);
606
+ gru_intr(0, blade);
607
+ gru_intr(1, blade);
621608 }
622609 return IRQ_HANDLED;
623610 }
....@@ -661,6 +648,7 @@
661648 if ((cb & (GRU_HANDLE_STRIDE - 1)) || ucbnum >= GRU_NUM_CB)
662649 return -EINVAL;
663650
651
+again:
664652 gts = gru_find_lock_gts(cb);
665653 if (!gts)
666654 return -EINVAL;
....@@ -669,7 +657,11 @@
669657 if (ucbnum >= gts->ts_cbr_au_count * GRU_CBR_AU_SIZE)
670658 goto exit;
671659
672
- gru_check_context_placement(gts);
660
+ if (gru_check_context_placement(gts)) {
661
+ gru_unlock_gts(gts);
662
+ gru_unload_context(gts, 1);
663
+ goto again;
664
+ }
673665
674666 /*
675667 * CCH may contain stale data if ts_force_cch_reload is set.
....@@ -887,7 +879,11 @@
887879 } else {
888880 gts->ts_user_blade_id = req.val1;
889881 gts->ts_user_chiplet_id = req.val0;
890
- gru_check_context_placement(gts);
882
+ if (gru_check_context_placement(gts)) {
883
+ gru_unlock_gts(gts);
884
+ gru_unload_context(gts, 1);
885
+ return ret;
886
+ }
891887 }
892888 break;
893889 case sco_gseg_owner: