11/*
2+ * Copyright(c) 2020 Cornelis Networks, Inc.
23 * Copyright(c) 2016 - 2017 Intel Corporation.
34 *
45 * This file is provided under a dual BSD/GPLv2 license. When using or
4849#include <linux/rculist.h>
4950#include <linux/mmu_notifier.h>
5051#include <linux/interval_tree_generic.h>
52+ #include <linux/sched/mm.h>
5153
5254#include "mmu_rb.h"
5355#include "trace.h"
5456
55- struct mmu_rb_handler {
56- struct mmu_notifier mn ;
57- struct rb_root_cached root ;
58- void * ops_arg ;
59- spinlock_t lock ; /* protect the RB tree */
60- struct mmu_rb_ops * ops ;
61- struct mm_struct * mm ;
62- struct list_head lru_list ;
63- struct work_struct del_work ;
64- struct list_head del_list ;
65- struct workqueue_struct * wq ;
66- };
67-
6857static unsigned long mmu_node_start (struct mmu_rb_node * );
6958static unsigned long mmu_node_last (struct mmu_rb_node * );
7059static int mmu_notifier_range_start (struct mmu_notifier * ,
@@ -92,37 +81,36 @@ static unsigned long mmu_node_last(struct mmu_rb_node *node)
9281 return PAGE_ALIGN (node -> addr + node -> len ) - 1 ;
9382}
9483
95- int hfi1_mmu_rb_register (void * ops_arg , struct mm_struct * mm ,
84+ int hfi1_mmu_rb_register (void * ops_arg ,
9685 struct mmu_rb_ops * ops ,
9786 struct workqueue_struct * wq ,
9887 struct mmu_rb_handler * * handler )
9988{
100- struct mmu_rb_handler * handlr ;
89+ struct mmu_rb_handler * h ;
10190 int ret ;
10291
103- handlr = kmalloc (sizeof (* handlr ), GFP_KERNEL );
104- if (!handlr )
92+ h = kmalloc (sizeof (* h ), GFP_KERNEL );
93+ if (!h )
10594 return - ENOMEM ;
10695
107- handlr -> root = RB_ROOT_CACHED ;
108- handlr -> ops = ops ;
109- handlr -> ops_arg = ops_arg ;
110- INIT_HLIST_NODE (& handlr -> mn .hlist );
111- spin_lock_init (& handlr -> lock );
112- handlr -> mn .ops = & mn_opts ;
113- handlr -> mm = mm ;
114- INIT_WORK (& handlr -> del_work , handle_remove );
115- INIT_LIST_HEAD (& handlr -> del_list );
116- INIT_LIST_HEAD (& handlr -> lru_list );
117- handlr -> wq = wq ;
118-
119- ret = mmu_notifier_register (& handlr -> mn , handlr -> mm );
96+ h -> root = RB_ROOT_CACHED ;
97+ h -> ops = ops ;
98+ h -> ops_arg = ops_arg ;
99+ INIT_HLIST_NODE (& h -> mn .hlist );
100+ spin_lock_init (& h -> lock );
101+ h -> mn .ops = & mn_opts ;
102+ INIT_WORK (& h -> del_work , handle_remove );
103+ INIT_LIST_HEAD (& h -> del_list );
104+ INIT_LIST_HEAD (& h -> lru_list );
105+ h -> wq = wq ;
106+
107+ ret = mmu_notifier_register (& h -> mn , current -> mm );
120108 if (ret ) {
121- kfree (handlr );
109+ kfree (h );
122110 return ret ;
123111 }
124112
125- * handler = handlr ;
113+ * handler = h ;
126114 return 0 ;
127115}
128116
@@ -134,7 +122,7 @@ void hfi1_mmu_rb_unregister(struct mmu_rb_handler *handler)
134122 struct list_head del_list ;
135123
136124 /* Unregister first so we don't get any more notifications. */
137- mmu_notifier_unregister (& handler -> mn , handler -> mm );
125+ mmu_notifier_unregister (& handler -> mn , handler -> mn . mm );
138126
139127 /*
140128 * Make sure the wq delete handler is finished running. It will not
@@ -166,6 +154,10 @@ int hfi1_mmu_rb_insert(struct mmu_rb_handler *handler,
166154 int ret = 0 ;
167155
168156 trace_hfi1_mmu_rb_insert (mnode -> addr , mnode -> len );
157+
158+ if (current -> mm != handler -> mn .mm )
159+ return - EPERM ;
160+
169161 spin_lock_irqsave (& handler -> lock , flags );
170162 node = __mmu_rb_search (handler , mnode -> addr , mnode -> len );
171163 if (node ) {
@@ -180,6 +172,7 @@ int hfi1_mmu_rb_insert(struct mmu_rb_handler *handler,
180172 __mmu_int_rb_remove (mnode , & handler -> root );
181173 list_del (& mnode -> list ); /* remove from LRU list */
182174 }
175+ mnode -> handler = handler ;
183176unlock :
184177 spin_unlock_irqrestore (& handler -> lock , flags );
185178 return ret ;
@@ -217,6 +210,9 @@ bool hfi1_mmu_rb_remove_unless_exact(struct mmu_rb_handler *handler,
217210 unsigned long flags ;
218211 bool ret = false;
219212
213+ if (current -> mm != handler -> mn .mm )
214+ return ret ;
215+
220216 spin_lock_irqsave (& handler -> lock , flags );
221217 node = __mmu_rb_search (handler , addr , len );
222218 if (node ) {
@@ -239,6 +235,9 @@ void hfi1_mmu_rb_evict(struct mmu_rb_handler *handler, void *evict_arg)
239235 unsigned long flags ;
240236 bool stop = false;
241237
238+ if (current -> mm != handler -> mn .mm )
239+ return ;
240+
242241 INIT_LIST_HEAD (& del_list );
243242
244243 spin_lock_irqsave (& handler -> lock , flags );
@@ -272,6 +271,9 @@ void hfi1_mmu_rb_remove(struct mmu_rb_handler *handler,
272271{
273272 unsigned long flags ;
274273
274+ if (current -> mm != handler -> mn .mm )
275+ return ;
276+
275277 /* Validity of handler and node pointers has been checked by caller. */
276278 trace_hfi1_mmu_rb_remove (node -> addr , node -> len );
277279 spin_lock_irqsave (& handler -> lock , flags );
0 commit comments