xref: /OK3568_Linux_fs/kernel/drivers/gpu/arm/midgard/mali_kbase_mem.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  *
3*4882a593Smuzhiyun  * (C) COPYRIGHT 2010-2017 ARM Limited. All rights reserved.
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * This program is free software and is provided to you under the terms of the
6*4882a593Smuzhiyun  * GNU General Public License version 2 as published by the Free Software
7*4882a593Smuzhiyun  * Foundation, and any use by you of this program is subject to the terms
8*4882a593Smuzhiyun  * of such GNU licence.
9*4882a593Smuzhiyun  *
10*4882a593Smuzhiyun  * A copy of the licence is included with the program, and can also be obtained
11*4882a593Smuzhiyun  * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
12*4882a593Smuzhiyun  * Boston, MA  02110-1301, USA.
13*4882a593Smuzhiyun  *
14*4882a593Smuzhiyun  */
15*4882a593Smuzhiyun 
16*4882a593Smuzhiyun 
17*4882a593Smuzhiyun 
18*4882a593Smuzhiyun 
19*4882a593Smuzhiyun 
20*4882a593Smuzhiyun /**
21*4882a593Smuzhiyun  * @file mali_kbase_mem.c
22*4882a593Smuzhiyun  * Base kernel memory APIs
23*4882a593Smuzhiyun  */
24*4882a593Smuzhiyun #ifdef CONFIG_DMA_SHARED_BUFFER
25*4882a593Smuzhiyun #include <linux/dma-buf.h>
26*4882a593Smuzhiyun #endif				/* CONFIG_DMA_SHARED_BUFFER */
27*4882a593Smuzhiyun #ifdef CONFIG_UMP
28*4882a593Smuzhiyun #include <linux/ump.h>
29*4882a593Smuzhiyun #endif				/* CONFIG_UMP */
30*4882a593Smuzhiyun #include <linux/kernel.h>
31*4882a593Smuzhiyun #include <linux/bug.h>
32*4882a593Smuzhiyun #include <linux/compat.h>
33*4882a593Smuzhiyun #include <linux/version.h>
34*4882a593Smuzhiyun #include <linux/sched/mm.h>
35*4882a593Smuzhiyun 
36*4882a593Smuzhiyun #include <mali_kbase_config.h>
37*4882a593Smuzhiyun #include <mali_kbase.h>
38*4882a593Smuzhiyun #include <mali_midg_regmap.h>
39*4882a593Smuzhiyun #include <mali_kbase_cache_policy.h>
40*4882a593Smuzhiyun #include <mali_kbase_hw.h>
41*4882a593Smuzhiyun #include <mali_kbase_hwaccess_time.h>
42*4882a593Smuzhiyun #include <mali_kbase_tlstream.h>
43*4882a593Smuzhiyun 
44*4882a593Smuzhiyun /* This function finds out which RB tree the given GPU VA region belongs to
45*4882a593Smuzhiyun  * based on the region zone */
kbase_reg_flags_to_rbtree(struct kbase_context * kctx,struct kbase_va_region * reg)46*4882a593Smuzhiyun static struct rb_root *kbase_reg_flags_to_rbtree(struct kbase_context *kctx,
47*4882a593Smuzhiyun 						    struct kbase_va_region *reg)
48*4882a593Smuzhiyun {
49*4882a593Smuzhiyun 	struct rb_root *rbtree = NULL;
50*4882a593Smuzhiyun 
51*4882a593Smuzhiyun 	switch (reg->flags & KBASE_REG_ZONE_MASK) {
52*4882a593Smuzhiyun 	case KBASE_REG_ZONE_CUSTOM_VA:
53*4882a593Smuzhiyun 		rbtree = &kctx->reg_rbtree_custom;
54*4882a593Smuzhiyun 		break;
55*4882a593Smuzhiyun 	case KBASE_REG_ZONE_EXEC:
56*4882a593Smuzhiyun 		rbtree = &kctx->reg_rbtree_exec;
57*4882a593Smuzhiyun 		break;
58*4882a593Smuzhiyun 	case KBASE_REG_ZONE_SAME_VA:
59*4882a593Smuzhiyun 		rbtree = &kctx->reg_rbtree_same;
60*4882a593Smuzhiyun 		/* fall through */
61*4882a593Smuzhiyun 	default:
62*4882a593Smuzhiyun 		rbtree = &kctx->reg_rbtree_same;
63*4882a593Smuzhiyun 		break;
64*4882a593Smuzhiyun 	}
65*4882a593Smuzhiyun 
66*4882a593Smuzhiyun 	return rbtree;
67*4882a593Smuzhiyun }
68*4882a593Smuzhiyun 
69*4882a593Smuzhiyun /* This function finds out which RB tree the given pfn from the GPU VA belongs
70*4882a593Smuzhiyun  * to based on the memory zone the pfn refers to */
kbase_gpu_va_to_rbtree(struct kbase_context * kctx,u64 gpu_pfn)71*4882a593Smuzhiyun static struct rb_root *kbase_gpu_va_to_rbtree(struct kbase_context *kctx,
72*4882a593Smuzhiyun 								    u64 gpu_pfn)
73*4882a593Smuzhiyun {
74*4882a593Smuzhiyun 	struct rb_root *rbtree = NULL;
75*4882a593Smuzhiyun 
76*4882a593Smuzhiyun #ifdef CONFIG_64BIT
77*4882a593Smuzhiyun 	if (kbase_ctx_flag(kctx, KCTX_COMPAT)) {
78*4882a593Smuzhiyun #endif /* CONFIG_64BIT */
79*4882a593Smuzhiyun 		if (gpu_pfn >= KBASE_REG_ZONE_CUSTOM_VA_BASE)
80*4882a593Smuzhiyun 			rbtree = &kctx->reg_rbtree_custom;
81*4882a593Smuzhiyun 		else if (gpu_pfn >= KBASE_REG_ZONE_EXEC_BASE)
82*4882a593Smuzhiyun 			rbtree = &kctx->reg_rbtree_exec;
83*4882a593Smuzhiyun 		else
84*4882a593Smuzhiyun 			rbtree = &kctx->reg_rbtree_same;
85*4882a593Smuzhiyun #ifdef CONFIG_64BIT
86*4882a593Smuzhiyun 	} else {
87*4882a593Smuzhiyun 		if (gpu_pfn >= kctx->same_va_end)
88*4882a593Smuzhiyun 			rbtree = &kctx->reg_rbtree_custom;
89*4882a593Smuzhiyun 		else
90*4882a593Smuzhiyun 			rbtree = &kctx->reg_rbtree_same;
91*4882a593Smuzhiyun 	}
92*4882a593Smuzhiyun #endif /* CONFIG_64BIT */
93*4882a593Smuzhiyun 
94*4882a593Smuzhiyun 	return rbtree;
95*4882a593Smuzhiyun }
96*4882a593Smuzhiyun 
97*4882a593Smuzhiyun /* This function inserts a region into the tree. */
kbase_region_tracker_insert(struct kbase_context * kctx,struct kbase_va_region * new_reg)98*4882a593Smuzhiyun static void kbase_region_tracker_insert(struct kbase_context *kctx,
99*4882a593Smuzhiyun 						struct kbase_va_region *new_reg)
100*4882a593Smuzhiyun {
101*4882a593Smuzhiyun 	u64 start_pfn = new_reg->start_pfn;
102*4882a593Smuzhiyun 	struct rb_node **link = NULL;
103*4882a593Smuzhiyun 	struct rb_node *parent = NULL;
104*4882a593Smuzhiyun 	struct rb_root *rbtree = NULL;
105*4882a593Smuzhiyun 
106*4882a593Smuzhiyun 	rbtree = kbase_reg_flags_to_rbtree(kctx, new_reg);
107*4882a593Smuzhiyun 
108*4882a593Smuzhiyun 	link = &(rbtree->rb_node);
109*4882a593Smuzhiyun 	/* Find the right place in the tree using tree search */
110*4882a593Smuzhiyun 	while (*link) {
111*4882a593Smuzhiyun 		struct kbase_va_region *old_reg;
112*4882a593Smuzhiyun 
113*4882a593Smuzhiyun 		parent = *link;
114*4882a593Smuzhiyun 		old_reg = rb_entry(parent, struct kbase_va_region, rblink);
115*4882a593Smuzhiyun 
116*4882a593Smuzhiyun 		/* RBTree requires no duplicate entries. */
117*4882a593Smuzhiyun 		KBASE_DEBUG_ASSERT(old_reg->start_pfn != start_pfn);
118*4882a593Smuzhiyun 
119*4882a593Smuzhiyun 		if (old_reg->start_pfn > start_pfn)
120*4882a593Smuzhiyun 			link = &(*link)->rb_left;
121*4882a593Smuzhiyun 		else
122*4882a593Smuzhiyun 			link = &(*link)->rb_right;
123*4882a593Smuzhiyun 	}
124*4882a593Smuzhiyun 
125*4882a593Smuzhiyun 	/* Put the new node there, and rebalance tree */
126*4882a593Smuzhiyun 	rb_link_node(&(new_reg->rblink), parent, link);
127*4882a593Smuzhiyun 
128*4882a593Smuzhiyun 	rb_insert_color(&(new_reg->rblink), rbtree);
129*4882a593Smuzhiyun }
130*4882a593Smuzhiyun 
131*4882a593Smuzhiyun /* Find allocated region enclosing free range. */
kbase_region_tracker_find_region_enclosing_range_free(struct kbase_context * kctx,u64 start_pfn,size_t nr_pages)132*4882a593Smuzhiyun static struct kbase_va_region *kbase_region_tracker_find_region_enclosing_range_free(
133*4882a593Smuzhiyun 		struct kbase_context *kctx, u64 start_pfn, size_t nr_pages)
134*4882a593Smuzhiyun {
135*4882a593Smuzhiyun 	struct rb_node *rbnode = NULL;
136*4882a593Smuzhiyun 	struct kbase_va_region *reg = NULL;
137*4882a593Smuzhiyun 	struct rb_root *rbtree = NULL;
138*4882a593Smuzhiyun 
139*4882a593Smuzhiyun 	u64 end_pfn = start_pfn + nr_pages;
140*4882a593Smuzhiyun 
141*4882a593Smuzhiyun 	rbtree = kbase_gpu_va_to_rbtree(kctx, start_pfn);
142*4882a593Smuzhiyun 
143*4882a593Smuzhiyun 	rbnode = rbtree->rb_node;
144*4882a593Smuzhiyun 
145*4882a593Smuzhiyun 	while (rbnode) {
146*4882a593Smuzhiyun 		u64 tmp_start_pfn, tmp_end_pfn;
147*4882a593Smuzhiyun 
148*4882a593Smuzhiyun 		reg = rb_entry(rbnode, struct kbase_va_region, rblink);
149*4882a593Smuzhiyun 		tmp_start_pfn = reg->start_pfn;
150*4882a593Smuzhiyun 		tmp_end_pfn = reg->start_pfn + reg->nr_pages;
151*4882a593Smuzhiyun 
152*4882a593Smuzhiyun 		/* If start is lower than this, go left. */
153*4882a593Smuzhiyun 		if (start_pfn < tmp_start_pfn)
154*4882a593Smuzhiyun 			rbnode = rbnode->rb_left;
155*4882a593Smuzhiyun 		/* If end is higher than this, then go right. */
156*4882a593Smuzhiyun 		else if (end_pfn > tmp_end_pfn)
157*4882a593Smuzhiyun 			rbnode = rbnode->rb_right;
158*4882a593Smuzhiyun 		else	/* Enclosing */
159*4882a593Smuzhiyun 			return reg;
160*4882a593Smuzhiyun 	}
161*4882a593Smuzhiyun 
162*4882a593Smuzhiyun 	return NULL;
163*4882a593Smuzhiyun }
164*4882a593Smuzhiyun 
165*4882a593Smuzhiyun /* Find region enclosing given address. */
kbase_region_tracker_find_region_enclosing_address(struct kbase_context * kctx,u64 gpu_addr)166*4882a593Smuzhiyun struct kbase_va_region *kbase_region_tracker_find_region_enclosing_address(struct kbase_context *kctx, u64 gpu_addr)
167*4882a593Smuzhiyun {
168*4882a593Smuzhiyun 	struct rb_node *rbnode;
169*4882a593Smuzhiyun 	struct kbase_va_region *reg;
170*4882a593Smuzhiyun 	u64 gpu_pfn = gpu_addr >> PAGE_SHIFT;
171*4882a593Smuzhiyun 	struct rb_root *rbtree = NULL;
172*4882a593Smuzhiyun 
173*4882a593Smuzhiyun 	KBASE_DEBUG_ASSERT(NULL != kctx);
174*4882a593Smuzhiyun 
175*4882a593Smuzhiyun 	lockdep_assert_held(&kctx->reg_lock);
176*4882a593Smuzhiyun 
177*4882a593Smuzhiyun 	rbtree = kbase_gpu_va_to_rbtree(kctx, gpu_pfn);
178*4882a593Smuzhiyun 
179*4882a593Smuzhiyun 	rbnode = rbtree->rb_node;
180*4882a593Smuzhiyun 
181*4882a593Smuzhiyun 	while (rbnode) {
182*4882a593Smuzhiyun 		u64 tmp_start_pfn, tmp_end_pfn;
183*4882a593Smuzhiyun 
184*4882a593Smuzhiyun 		reg = rb_entry(rbnode, struct kbase_va_region, rblink);
185*4882a593Smuzhiyun 		tmp_start_pfn = reg->start_pfn;
186*4882a593Smuzhiyun 		tmp_end_pfn = reg->start_pfn + reg->nr_pages;
187*4882a593Smuzhiyun 
188*4882a593Smuzhiyun 		/* If start is lower than this, go left. */
189*4882a593Smuzhiyun 		if (gpu_pfn < tmp_start_pfn)
190*4882a593Smuzhiyun 			rbnode = rbnode->rb_left;
191*4882a593Smuzhiyun 		/* If end is higher than this, then go right. */
192*4882a593Smuzhiyun 		else if (gpu_pfn >= tmp_end_pfn)
193*4882a593Smuzhiyun 			rbnode = rbnode->rb_right;
194*4882a593Smuzhiyun 		else	/* Enclosing */
195*4882a593Smuzhiyun 			return reg;
196*4882a593Smuzhiyun 	}
197*4882a593Smuzhiyun 
198*4882a593Smuzhiyun 	return NULL;
199*4882a593Smuzhiyun }
200*4882a593Smuzhiyun 
201*4882a593Smuzhiyun KBASE_EXPORT_TEST_API(kbase_region_tracker_find_region_enclosing_address);
202*4882a593Smuzhiyun 
203*4882a593Smuzhiyun /* Find region with given base address */
kbase_region_tracker_find_region_base_address(struct kbase_context * kctx,u64 gpu_addr)204*4882a593Smuzhiyun struct kbase_va_region *kbase_region_tracker_find_region_base_address(struct kbase_context *kctx, u64 gpu_addr)
205*4882a593Smuzhiyun {
206*4882a593Smuzhiyun 	u64 gpu_pfn = gpu_addr >> PAGE_SHIFT;
207*4882a593Smuzhiyun 	struct rb_node *rbnode = NULL;
208*4882a593Smuzhiyun 	struct kbase_va_region *reg = NULL;
209*4882a593Smuzhiyun 	struct rb_root *rbtree = NULL;
210*4882a593Smuzhiyun 
211*4882a593Smuzhiyun 	KBASE_DEBUG_ASSERT(NULL != kctx);
212*4882a593Smuzhiyun 
213*4882a593Smuzhiyun 	lockdep_assert_held(&kctx->reg_lock);
214*4882a593Smuzhiyun 
215*4882a593Smuzhiyun 	rbtree = kbase_gpu_va_to_rbtree(kctx, gpu_pfn);
216*4882a593Smuzhiyun 
217*4882a593Smuzhiyun 	rbnode = rbtree->rb_node;
218*4882a593Smuzhiyun 
219*4882a593Smuzhiyun 	while (rbnode) {
220*4882a593Smuzhiyun 		reg = rb_entry(rbnode, struct kbase_va_region, rblink);
221*4882a593Smuzhiyun 		if (reg->start_pfn > gpu_pfn)
222*4882a593Smuzhiyun 			rbnode = rbnode->rb_left;
223*4882a593Smuzhiyun 		else if (reg->start_pfn < gpu_pfn)
224*4882a593Smuzhiyun 			rbnode = rbnode->rb_right;
225*4882a593Smuzhiyun 		else
226*4882a593Smuzhiyun 			return reg;
227*4882a593Smuzhiyun 
228*4882a593Smuzhiyun 	}
229*4882a593Smuzhiyun 
230*4882a593Smuzhiyun 	return NULL;
231*4882a593Smuzhiyun }
232*4882a593Smuzhiyun 
233*4882a593Smuzhiyun KBASE_EXPORT_TEST_API(kbase_region_tracker_find_region_base_address);
234*4882a593Smuzhiyun 
235*4882a593Smuzhiyun /* Find region meeting given requirements */
kbase_region_tracker_find_region_meeting_reqs(struct kbase_context * kctx,struct kbase_va_region * reg_reqs,size_t nr_pages,size_t align)236*4882a593Smuzhiyun static struct kbase_va_region *kbase_region_tracker_find_region_meeting_reqs(struct kbase_context *kctx, struct kbase_va_region *reg_reqs, size_t nr_pages, size_t align)
237*4882a593Smuzhiyun {
238*4882a593Smuzhiyun 	struct rb_node *rbnode = NULL;
239*4882a593Smuzhiyun 	struct kbase_va_region *reg = NULL;
240*4882a593Smuzhiyun 	struct rb_root *rbtree = NULL;
241*4882a593Smuzhiyun 
242*4882a593Smuzhiyun 	/* Note that this search is a linear search, as we do not have a target
243*4882a593Smuzhiyun 	   address in mind, so does not benefit from the rbtree search */
244*4882a593Smuzhiyun 
245*4882a593Smuzhiyun 	rbtree = kbase_reg_flags_to_rbtree(kctx, reg_reqs);
246*4882a593Smuzhiyun 
247*4882a593Smuzhiyun 	rbnode = rb_first(rbtree);
248*4882a593Smuzhiyun 
249*4882a593Smuzhiyun 	while (rbnode) {
250*4882a593Smuzhiyun 		reg = rb_entry(rbnode, struct kbase_va_region, rblink);
251*4882a593Smuzhiyun 		if ((reg->nr_pages >= nr_pages) &&
252*4882a593Smuzhiyun 				(reg->flags & KBASE_REG_FREE)) {
253*4882a593Smuzhiyun 			/* Check alignment */
254*4882a593Smuzhiyun 			u64 start_pfn = (reg->start_pfn + align - 1) & ~(align - 1);
255*4882a593Smuzhiyun 
256*4882a593Smuzhiyun 			if ((start_pfn >= reg->start_pfn) &&
257*4882a593Smuzhiyun 					(start_pfn <= (reg->start_pfn + reg->nr_pages - 1)) &&
258*4882a593Smuzhiyun 					((start_pfn + nr_pages - 1) <= (reg->start_pfn + reg->nr_pages - 1)))
259*4882a593Smuzhiyun 				return reg;
260*4882a593Smuzhiyun 		}
261*4882a593Smuzhiyun 		rbnode = rb_next(rbnode);
262*4882a593Smuzhiyun 	}
263*4882a593Smuzhiyun 
264*4882a593Smuzhiyun 	return NULL;
265*4882a593Smuzhiyun }
266*4882a593Smuzhiyun 
267*4882a593Smuzhiyun /**
268*4882a593Smuzhiyun  * @brief Remove a region object from the global list.
269*4882a593Smuzhiyun  *
270*4882a593Smuzhiyun  * The region reg is removed, possibly by merging with other free and
271*4882a593Smuzhiyun  * compatible adjacent regions.  It must be called with the context
272*4882a593Smuzhiyun  * region lock held. The associated memory is not released (see
273*4882a593Smuzhiyun  * kbase_free_alloced_region). Internal use only.
274*4882a593Smuzhiyun  */
kbase_remove_va_region(struct kbase_context * kctx,struct kbase_va_region * reg)275*4882a593Smuzhiyun static int kbase_remove_va_region(struct kbase_context *kctx, struct kbase_va_region *reg)
276*4882a593Smuzhiyun {
277*4882a593Smuzhiyun 	struct rb_node *rbprev;
278*4882a593Smuzhiyun 	struct kbase_va_region *prev = NULL;
279*4882a593Smuzhiyun 	struct rb_node *rbnext;
280*4882a593Smuzhiyun 	struct kbase_va_region *next = NULL;
281*4882a593Smuzhiyun 	struct rb_root *reg_rbtree = NULL;
282*4882a593Smuzhiyun 
283*4882a593Smuzhiyun 	int merged_front = 0;
284*4882a593Smuzhiyun 	int merged_back = 0;
285*4882a593Smuzhiyun 	int err = 0;
286*4882a593Smuzhiyun 
287*4882a593Smuzhiyun 	reg_rbtree = kbase_reg_flags_to_rbtree(kctx, reg);
288*4882a593Smuzhiyun 
289*4882a593Smuzhiyun 	/* Try to merge with the previous block first */
290*4882a593Smuzhiyun 	rbprev = rb_prev(&(reg->rblink));
291*4882a593Smuzhiyun 	if (rbprev) {
292*4882a593Smuzhiyun 		prev = rb_entry(rbprev, struct kbase_va_region, rblink);
293*4882a593Smuzhiyun 		if (prev->flags & KBASE_REG_FREE) {
294*4882a593Smuzhiyun 			/* We're compatible with the previous VMA,
295*4882a593Smuzhiyun 			 * merge with it */
296*4882a593Smuzhiyun 			WARN_ON((prev->flags & KBASE_REG_ZONE_MASK) !=
297*4882a593Smuzhiyun 					    (reg->flags & KBASE_REG_ZONE_MASK));
298*4882a593Smuzhiyun 			prev->nr_pages += reg->nr_pages;
299*4882a593Smuzhiyun 			rb_erase(&(reg->rblink), reg_rbtree);
300*4882a593Smuzhiyun 			reg = prev;
301*4882a593Smuzhiyun 			merged_front = 1;
302*4882a593Smuzhiyun 		}
303*4882a593Smuzhiyun 	}
304*4882a593Smuzhiyun 
305*4882a593Smuzhiyun 	/* Try to merge with the next block second */
306*4882a593Smuzhiyun 	/* Note we do the lookup here as the tree may have been rebalanced. */
307*4882a593Smuzhiyun 	rbnext = rb_next(&(reg->rblink));
308*4882a593Smuzhiyun 	if (rbnext) {
309*4882a593Smuzhiyun 		/* We're compatible with the next VMA, merge with it */
310*4882a593Smuzhiyun 		next = rb_entry(rbnext, struct kbase_va_region, rblink);
311*4882a593Smuzhiyun 		if (next->flags & KBASE_REG_FREE) {
312*4882a593Smuzhiyun 			WARN_ON((next->flags & KBASE_REG_ZONE_MASK) !=
313*4882a593Smuzhiyun 					    (reg->flags & KBASE_REG_ZONE_MASK));
314*4882a593Smuzhiyun 			next->start_pfn = reg->start_pfn;
315*4882a593Smuzhiyun 			next->nr_pages += reg->nr_pages;
316*4882a593Smuzhiyun 			rb_erase(&(reg->rblink), reg_rbtree);
317*4882a593Smuzhiyun 			merged_back = 1;
318*4882a593Smuzhiyun 			if (merged_front) {
319*4882a593Smuzhiyun 				/* We already merged with prev, free it */
320*4882a593Smuzhiyun 				kbase_free_alloced_region(reg);
321*4882a593Smuzhiyun 			}
322*4882a593Smuzhiyun 		}
323*4882a593Smuzhiyun 	}
324*4882a593Smuzhiyun 
325*4882a593Smuzhiyun 	/* If we failed to merge then we need to add a new block */
326*4882a593Smuzhiyun 	if (!(merged_front || merged_back)) {
327*4882a593Smuzhiyun 		/*
328*4882a593Smuzhiyun 		 * We didn't merge anything. Add a new free
329*4882a593Smuzhiyun 		 * placeholder and remove the original one.
330*4882a593Smuzhiyun 		 */
331*4882a593Smuzhiyun 		struct kbase_va_region *free_reg;
332*4882a593Smuzhiyun 
333*4882a593Smuzhiyun 		free_reg = kbase_alloc_free_region(kctx, reg->start_pfn, reg->nr_pages, reg->flags & KBASE_REG_ZONE_MASK);
334*4882a593Smuzhiyun 		if (!free_reg) {
335*4882a593Smuzhiyun 			err = -ENOMEM;
336*4882a593Smuzhiyun 			goto out;
337*4882a593Smuzhiyun 		}
338*4882a593Smuzhiyun 		rb_replace_node(&(reg->rblink), &(free_reg->rblink), reg_rbtree);
339*4882a593Smuzhiyun 	}
340*4882a593Smuzhiyun 
341*4882a593Smuzhiyun  out:
342*4882a593Smuzhiyun 	return err;
343*4882a593Smuzhiyun }
344*4882a593Smuzhiyun 
345*4882a593Smuzhiyun KBASE_EXPORT_TEST_API(kbase_remove_va_region);
346*4882a593Smuzhiyun 
347*4882a593Smuzhiyun /**
348*4882a593Smuzhiyun  * @brief Insert a VA region to the list, replacing the current at_reg.
349*4882a593Smuzhiyun  */
kbase_insert_va_region_nolock(struct kbase_context * kctx,struct kbase_va_region * new_reg,struct kbase_va_region * at_reg,u64 start_pfn,size_t nr_pages)350*4882a593Smuzhiyun static int kbase_insert_va_region_nolock(struct kbase_context *kctx, struct kbase_va_region *new_reg, struct kbase_va_region *at_reg, u64 start_pfn, size_t nr_pages)
351*4882a593Smuzhiyun {
352*4882a593Smuzhiyun 	struct rb_root *reg_rbtree = NULL;
353*4882a593Smuzhiyun 	int err = 0;
354*4882a593Smuzhiyun 
355*4882a593Smuzhiyun 	reg_rbtree = kbase_reg_flags_to_rbtree(kctx, at_reg);
356*4882a593Smuzhiyun 
357*4882a593Smuzhiyun 	/* Must be a free region */
358*4882a593Smuzhiyun 	KBASE_DEBUG_ASSERT((at_reg->flags & KBASE_REG_FREE) != 0);
359*4882a593Smuzhiyun 	/* start_pfn should be contained within at_reg */
360*4882a593Smuzhiyun 	KBASE_DEBUG_ASSERT((start_pfn >= at_reg->start_pfn) && (start_pfn < at_reg->start_pfn + at_reg->nr_pages));
361*4882a593Smuzhiyun 	/* at least nr_pages from start_pfn should be contained within at_reg */
362*4882a593Smuzhiyun 	KBASE_DEBUG_ASSERT(start_pfn + nr_pages <= at_reg->start_pfn + at_reg->nr_pages);
363*4882a593Smuzhiyun 
364*4882a593Smuzhiyun 	new_reg->start_pfn = start_pfn;
365*4882a593Smuzhiyun 	new_reg->nr_pages = nr_pages;
366*4882a593Smuzhiyun 
367*4882a593Smuzhiyun 	/* Regions are a whole use, so swap and delete old one. */
368*4882a593Smuzhiyun 	if (at_reg->start_pfn == start_pfn && at_reg->nr_pages == nr_pages) {
369*4882a593Smuzhiyun 		rb_replace_node(&(at_reg->rblink), &(new_reg->rblink),
370*4882a593Smuzhiyun 								reg_rbtree);
371*4882a593Smuzhiyun 		kbase_free_alloced_region(at_reg);
372*4882a593Smuzhiyun 	}
373*4882a593Smuzhiyun 	/* New region replaces the start of the old one, so insert before. */
374*4882a593Smuzhiyun 	else if (at_reg->start_pfn == start_pfn) {
375*4882a593Smuzhiyun 		at_reg->start_pfn += nr_pages;
376*4882a593Smuzhiyun 		KBASE_DEBUG_ASSERT(at_reg->nr_pages >= nr_pages);
377*4882a593Smuzhiyun 		at_reg->nr_pages -= nr_pages;
378*4882a593Smuzhiyun 
379*4882a593Smuzhiyun 		kbase_region_tracker_insert(kctx, new_reg);
380*4882a593Smuzhiyun 	}
381*4882a593Smuzhiyun 	/* New region replaces the end of the old one, so insert after. */
382*4882a593Smuzhiyun 	else if ((at_reg->start_pfn + at_reg->nr_pages) == (start_pfn + nr_pages)) {
383*4882a593Smuzhiyun 		at_reg->nr_pages -= nr_pages;
384*4882a593Smuzhiyun 
385*4882a593Smuzhiyun 		kbase_region_tracker_insert(kctx, new_reg);
386*4882a593Smuzhiyun 	}
387*4882a593Smuzhiyun 	/* New region splits the old one, so insert and create new */
388*4882a593Smuzhiyun 	else {
389*4882a593Smuzhiyun 		struct kbase_va_region *new_front_reg;
390*4882a593Smuzhiyun 
391*4882a593Smuzhiyun 		new_front_reg = kbase_alloc_free_region(kctx,
392*4882a593Smuzhiyun 				at_reg->start_pfn,
393*4882a593Smuzhiyun 				start_pfn - at_reg->start_pfn,
394*4882a593Smuzhiyun 				at_reg->flags & KBASE_REG_ZONE_MASK);
395*4882a593Smuzhiyun 
396*4882a593Smuzhiyun 		if (new_front_reg) {
397*4882a593Smuzhiyun 			at_reg->nr_pages -= nr_pages + new_front_reg->nr_pages;
398*4882a593Smuzhiyun 			at_reg->start_pfn = start_pfn + nr_pages;
399*4882a593Smuzhiyun 
400*4882a593Smuzhiyun 			kbase_region_tracker_insert(kctx, new_front_reg);
401*4882a593Smuzhiyun 			kbase_region_tracker_insert(kctx, new_reg);
402*4882a593Smuzhiyun 		} else {
403*4882a593Smuzhiyun 			err = -ENOMEM;
404*4882a593Smuzhiyun 		}
405*4882a593Smuzhiyun 	}
406*4882a593Smuzhiyun 
407*4882a593Smuzhiyun 	return err;
408*4882a593Smuzhiyun }
409*4882a593Smuzhiyun 
410*4882a593Smuzhiyun /**
411*4882a593Smuzhiyun  * @brief Add a VA region to the list.
412*4882a593Smuzhiyun  */
kbase_add_va_region(struct kbase_context * kctx,struct kbase_va_region * reg,u64 addr,size_t nr_pages,size_t align)413*4882a593Smuzhiyun int kbase_add_va_region(struct kbase_context *kctx,
414*4882a593Smuzhiyun 		struct kbase_va_region *reg, u64 addr,
415*4882a593Smuzhiyun 		size_t nr_pages, size_t align)
416*4882a593Smuzhiyun {
417*4882a593Smuzhiyun 	struct kbase_va_region *tmp;
418*4882a593Smuzhiyun 	u64 gpu_pfn = addr >> PAGE_SHIFT;
419*4882a593Smuzhiyun 	int err = 0;
420*4882a593Smuzhiyun 
421*4882a593Smuzhiyun 	KBASE_DEBUG_ASSERT(NULL != kctx);
422*4882a593Smuzhiyun 	KBASE_DEBUG_ASSERT(NULL != reg);
423*4882a593Smuzhiyun 
424*4882a593Smuzhiyun 	lockdep_assert_held(&kctx->reg_lock);
425*4882a593Smuzhiyun 
426*4882a593Smuzhiyun 	if (!align)
427*4882a593Smuzhiyun 		align = 1;
428*4882a593Smuzhiyun 
429*4882a593Smuzhiyun 	/* must be a power of 2 */
430*4882a593Smuzhiyun 	KBASE_DEBUG_ASSERT((align & (align - 1)) == 0);
431*4882a593Smuzhiyun 	KBASE_DEBUG_ASSERT(nr_pages > 0);
432*4882a593Smuzhiyun 
433*4882a593Smuzhiyun 	/* Path 1: Map a specific address. Find the enclosing region, which *must* be free. */
434*4882a593Smuzhiyun 	if (gpu_pfn) {
435*4882a593Smuzhiyun 		struct device *dev = kctx->kbdev->dev;
436*4882a593Smuzhiyun 
437*4882a593Smuzhiyun 		KBASE_DEBUG_ASSERT(!(gpu_pfn & (align - 1)));
438*4882a593Smuzhiyun 
439*4882a593Smuzhiyun 		tmp = kbase_region_tracker_find_region_enclosing_range_free(kctx, gpu_pfn, nr_pages);
440*4882a593Smuzhiyun 		if (!tmp) {
441*4882a593Smuzhiyun 			dev_warn(dev, "Enclosing region not found: 0x%08llx gpu_pfn, %zu nr_pages", gpu_pfn, nr_pages);
442*4882a593Smuzhiyun 			err = -ENOMEM;
443*4882a593Smuzhiyun 			goto exit;
444*4882a593Smuzhiyun 		}
445*4882a593Smuzhiyun 		if (!(tmp->flags & KBASE_REG_FREE)) {
446*4882a593Smuzhiyun 			dev_warn(dev, "Zone mismatch: %lu != %lu", tmp->flags & KBASE_REG_ZONE_MASK, reg->flags & KBASE_REG_ZONE_MASK);
447*4882a593Smuzhiyun 			dev_warn(dev, "!(tmp->flags & KBASE_REG_FREE): tmp->start_pfn=0x%llx tmp->flags=0x%lx tmp->nr_pages=0x%zx gpu_pfn=0x%llx nr_pages=0x%zx\n", tmp->start_pfn, tmp->flags, tmp->nr_pages, gpu_pfn, nr_pages);
448*4882a593Smuzhiyun 			dev_warn(dev, "in function %s (%p, %p, 0x%llx, 0x%zx, 0x%zx)\n", __func__, kctx, reg, addr, nr_pages, align);
449*4882a593Smuzhiyun 			err = -ENOMEM;
450*4882a593Smuzhiyun 			goto exit;
451*4882a593Smuzhiyun 		}
452*4882a593Smuzhiyun 
453*4882a593Smuzhiyun 		err = kbase_insert_va_region_nolock(kctx, reg, tmp, gpu_pfn, nr_pages);
454*4882a593Smuzhiyun 		if (err) {
455*4882a593Smuzhiyun 			dev_warn(dev, "Failed to insert va region");
456*4882a593Smuzhiyun 			err = -ENOMEM;
457*4882a593Smuzhiyun 			goto exit;
458*4882a593Smuzhiyun 		}
459*4882a593Smuzhiyun 
460*4882a593Smuzhiyun 		goto exit;
461*4882a593Smuzhiyun 	}
462*4882a593Smuzhiyun 
463*4882a593Smuzhiyun 	/* Path 2: Map any free address which meets the requirements.  */
464*4882a593Smuzhiyun 	{
465*4882a593Smuzhiyun 		u64 start_pfn;
466*4882a593Smuzhiyun 
467*4882a593Smuzhiyun 		/*
468*4882a593Smuzhiyun 		 * Depending on the zone the allocation request is for
469*4882a593Smuzhiyun 		 * we might need to retry it.
470*4882a593Smuzhiyun 		 */
471*4882a593Smuzhiyun 		do {
472*4882a593Smuzhiyun 			tmp = kbase_region_tracker_find_region_meeting_reqs(
473*4882a593Smuzhiyun 					kctx, reg, nr_pages, align);
474*4882a593Smuzhiyun 			if (tmp) {
475*4882a593Smuzhiyun 				start_pfn = (tmp->start_pfn + align - 1) &
476*4882a593Smuzhiyun 						~(align - 1);
477*4882a593Smuzhiyun 				err = kbase_insert_va_region_nolock(kctx, reg,
478*4882a593Smuzhiyun 						tmp, start_pfn, nr_pages);
479*4882a593Smuzhiyun 				break;
480*4882a593Smuzhiyun 			}
481*4882a593Smuzhiyun 
482*4882a593Smuzhiyun 			/*
483*4882a593Smuzhiyun 			 * If the allocation is not from the same zone as JIT
484*4882a593Smuzhiyun 			 * then don't retry, we're out of VA and there is
485*4882a593Smuzhiyun 			 * nothing which can be done about it.
486*4882a593Smuzhiyun 			 */
487*4882a593Smuzhiyun 			if ((reg->flags & KBASE_REG_ZONE_MASK) !=
488*4882a593Smuzhiyun 					KBASE_REG_ZONE_CUSTOM_VA)
489*4882a593Smuzhiyun 				break;
490*4882a593Smuzhiyun 		} while (kbase_jit_evict(kctx));
491*4882a593Smuzhiyun 
492*4882a593Smuzhiyun 		if (!tmp)
493*4882a593Smuzhiyun 			err = -ENOMEM;
494*4882a593Smuzhiyun 	}
495*4882a593Smuzhiyun 
496*4882a593Smuzhiyun  exit:
497*4882a593Smuzhiyun 	return err;
498*4882a593Smuzhiyun }
499*4882a593Smuzhiyun 
500*4882a593Smuzhiyun KBASE_EXPORT_TEST_API(kbase_add_va_region);
501*4882a593Smuzhiyun 
502*4882a593Smuzhiyun /**
503*4882a593Smuzhiyun  * @brief Initialize the internal region tracker data structure.
504*4882a593Smuzhiyun  */
kbase_region_tracker_ds_init(struct kbase_context * kctx,struct kbase_va_region * same_va_reg,struct kbase_va_region * exec_reg,struct kbase_va_region * custom_va_reg)505*4882a593Smuzhiyun static void kbase_region_tracker_ds_init(struct kbase_context *kctx,
506*4882a593Smuzhiyun 		struct kbase_va_region *same_va_reg,
507*4882a593Smuzhiyun 		struct kbase_va_region *exec_reg,
508*4882a593Smuzhiyun 		struct kbase_va_region *custom_va_reg)
509*4882a593Smuzhiyun {
510*4882a593Smuzhiyun 	kctx->reg_rbtree_same = RB_ROOT;
511*4882a593Smuzhiyun 	kbase_region_tracker_insert(kctx, same_va_reg);
512*4882a593Smuzhiyun 
513*4882a593Smuzhiyun 	/* Although exec and custom_va_reg don't always exist,
514*4882a593Smuzhiyun 	 * initialize unconditionally because of the mem_view debugfs
515*4882a593Smuzhiyun 	 * implementation which relies on these being empty */
516*4882a593Smuzhiyun 	kctx->reg_rbtree_exec = RB_ROOT;
517*4882a593Smuzhiyun 	kctx->reg_rbtree_custom = RB_ROOT;
518*4882a593Smuzhiyun 
519*4882a593Smuzhiyun 	if (exec_reg)
520*4882a593Smuzhiyun 		kbase_region_tracker_insert(kctx, exec_reg);
521*4882a593Smuzhiyun 	if (custom_va_reg)
522*4882a593Smuzhiyun 		kbase_region_tracker_insert(kctx, custom_va_reg);
523*4882a593Smuzhiyun }
524*4882a593Smuzhiyun 
kbase_region_tracker_erase_rbtree(struct rb_root * rbtree)525*4882a593Smuzhiyun static void kbase_region_tracker_erase_rbtree(struct rb_root *rbtree)
526*4882a593Smuzhiyun {
527*4882a593Smuzhiyun 	struct rb_node *rbnode;
528*4882a593Smuzhiyun 	struct kbase_va_region *reg;
529*4882a593Smuzhiyun 
530*4882a593Smuzhiyun 	do {
531*4882a593Smuzhiyun 		rbnode = rb_first(rbtree);
532*4882a593Smuzhiyun 		if (rbnode) {
533*4882a593Smuzhiyun 			rb_erase(rbnode, rbtree);
534*4882a593Smuzhiyun 			reg = rb_entry(rbnode, struct kbase_va_region, rblink);
535*4882a593Smuzhiyun 			kbase_free_alloced_region(reg);
536*4882a593Smuzhiyun 		}
537*4882a593Smuzhiyun 	} while (rbnode);
538*4882a593Smuzhiyun }
539*4882a593Smuzhiyun 
kbase_region_tracker_term(struct kbase_context * kctx)540*4882a593Smuzhiyun void kbase_region_tracker_term(struct kbase_context *kctx)
541*4882a593Smuzhiyun {
542*4882a593Smuzhiyun 	kbase_region_tracker_erase_rbtree(&kctx->reg_rbtree_same);
543*4882a593Smuzhiyun 	kbase_region_tracker_erase_rbtree(&kctx->reg_rbtree_exec);
544*4882a593Smuzhiyun 	kbase_region_tracker_erase_rbtree(&kctx->reg_rbtree_custom);
545*4882a593Smuzhiyun }
546*4882a593Smuzhiyun 
547*4882a593Smuzhiyun /**
548*4882a593Smuzhiyun  * Initialize the region tracker data structure.
549*4882a593Smuzhiyun  */
kbase_region_tracker_init(struct kbase_context * kctx)550*4882a593Smuzhiyun int kbase_region_tracker_init(struct kbase_context *kctx)
551*4882a593Smuzhiyun {
552*4882a593Smuzhiyun 	struct kbase_va_region *same_va_reg;
553*4882a593Smuzhiyun 	struct kbase_va_region *exec_reg = NULL;
554*4882a593Smuzhiyun 	struct kbase_va_region *custom_va_reg = NULL;
555*4882a593Smuzhiyun 	size_t same_va_bits = sizeof(void *) * BITS_PER_BYTE;
556*4882a593Smuzhiyun 	u64 custom_va_size = KBASE_REG_ZONE_CUSTOM_VA_SIZE;
557*4882a593Smuzhiyun 	u64 gpu_va_limit = (1ULL << kctx->kbdev->gpu_props.mmu.va_bits) >> PAGE_SHIFT;
558*4882a593Smuzhiyun 	u64 same_va_pages;
559*4882a593Smuzhiyun 	int err;
560*4882a593Smuzhiyun 
561*4882a593Smuzhiyun 	/* Take the lock as kbase_free_alloced_region requires it */
562*4882a593Smuzhiyun 	kbase_gpu_vm_lock(kctx);
563*4882a593Smuzhiyun 
564*4882a593Smuzhiyun #if defined(CONFIG_ARM64)
565*4882a593Smuzhiyun 	same_va_bits = VA_BITS;
566*4882a593Smuzhiyun #elif defined(CONFIG_X86_64)
567*4882a593Smuzhiyun 	same_va_bits = 47;
568*4882a593Smuzhiyun #elif defined(CONFIG_64BIT)
569*4882a593Smuzhiyun #error Unsupported 64-bit architecture
570*4882a593Smuzhiyun #endif
571*4882a593Smuzhiyun 
572*4882a593Smuzhiyun #ifdef CONFIG_64BIT
573*4882a593Smuzhiyun 	if (kbase_ctx_flag(kctx, KCTX_COMPAT))
574*4882a593Smuzhiyun 		same_va_bits = 32;
575*4882a593Smuzhiyun 	else if (kbase_hw_has_feature(kctx->kbdev, BASE_HW_FEATURE_33BIT_VA))
576*4882a593Smuzhiyun 		same_va_bits = 33;
577*4882a593Smuzhiyun #endif
578*4882a593Smuzhiyun 
579*4882a593Smuzhiyun 	if (kctx->kbdev->gpu_props.mmu.va_bits < same_va_bits) {
580*4882a593Smuzhiyun 		err = -EINVAL;
581*4882a593Smuzhiyun 		goto fail_unlock;
582*4882a593Smuzhiyun 	}
583*4882a593Smuzhiyun 
584*4882a593Smuzhiyun 	same_va_pages = (1ULL << (same_va_bits - PAGE_SHIFT)) - 1;
585*4882a593Smuzhiyun 	/* all have SAME_VA */
586*4882a593Smuzhiyun 	same_va_reg = kbase_alloc_free_region(kctx, 1,
587*4882a593Smuzhiyun 			same_va_pages,
588*4882a593Smuzhiyun 			KBASE_REG_ZONE_SAME_VA);
589*4882a593Smuzhiyun 
590*4882a593Smuzhiyun 	if (!same_va_reg) {
591*4882a593Smuzhiyun 		err = -ENOMEM;
592*4882a593Smuzhiyun 		goto fail_unlock;
593*4882a593Smuzhiyun 	}
594*4882a593Smuzhiyun 
595*4882a593Smuzhiyun #ifdef CONFIG_64BIT
596*4882a593Smuzhiyun 	/* 32-bit clients have exec and custom VA zones */
597*4882a593Smuzhiyun 	if (kbase_ctx_flag(kctx, KCTX_COMPAT)) {
598*4882a593Smuzhiyun #endif
599*4882a593Smuzhiyun 		if (gpu_va_limit <= KBASE_REG_ZONE_CUSTOM_VA_BASE) {
600*4882a593Smuzhiyun 			err = -EINVAL;
601*4882a593Smuzhiyun 			goto fail_free_same_va;
602*4882a593Smuzhiyun 		}
603*4882a593Smuzhiyun 		/* If the current size of TMEM is out of range of the
604*4882a593Smuzhiyun 		 * virtual address space addressable by the MMU then
605*4882a593Smuzhiyun 		 * we should shrink it to fit
606*4882a593Smuzhiyun 		 */
607*4882a593Smuzhiyun 		if ((KBASE_REG_ZONE_CUSTOM_VA_BASE + KBASE_REG_ZONE_CUSTOM_VA_SIZE) >= gpu_va_limit)
608*4882a593Smuzhiyun 			custom_va_size = gpu_va_limit - KBASE_REG_ZONE_CUSTOM_VA_BASE;
609*4882a593Smuzhiyun 
610*4882a593Smuzhiyun 		exec_reg = kbase_alloc_free_region(kctx,
611*4882a593Smuzhiyun 				KBASE_REG_ZONE_EXEC_BASE,
612*4882a593Smuzhiyun 				KBASE_REG_ZONE_EXEC_SIZE,
613*4882a593Smuzhiyun 				KBASE_REG_ZONE_EXEC);
614*4882a593Smuzhiyun 
615*4882a593Smuzhiyun 		if (!exec_reg) {
616*4882a593Smuzhiyun 			err = -ENOMEM;
617*4882a593Smuzhiyun 			goto fail_free_same_va;
618*4882a593Smuzhiyun 		}
619*4882a593Smuzhiyun 
620*4882a593Smuzhiyun 		custom_va_reg = kbase_alloc_free_region(kctx,
621*4882a593Smuzhiyun 				KBASE_REG_ZONE_CUSTOM_VA_BASE,
622*4882a593Smuzhiyun 				custom_va_size, KBASE_REG_ZONE_CUSTOM_VA);
623*4882a593Smuzhiyun 
624*4882a593Smuzhiyun 		if (!custom_va_reg) {
625*4882a593Smuzhiyun 			err = -ENOMEM;
626*4882a593Smuzhiyun 			goto fail_free_exec;
627*4882a593Smuzhiyun 		}
628*4882a593Smuzhiyun #ifdef CONFIG_64BIT
629*4882a593Smuzhiyun 	}
630*4882a593Smuzhiyun #endif
631*4882a593Smuzhiyun 
632*4882a593Smuzhiyun 	kbase_region_tracker_ds_init(kctx, same_va_reg, exec_reg, custom_va_reg);
633*4882a593Smuzhiyun 
634*4882a593Smuzhiyun 	kctx->same_va_end = same_va_pages + 1;
635*4882a593Smuzhiyun 
636*4882a593Smuzhiyun 	kbase_gpu_vm_unlock(kctx);
637*4882a593Smuzhiyun 	return 0;
638*4882a593Smuzhiyun 
639*4882a593Smuzhiyun fail_free_exec:
640*4882a593Smuzhiyun 	kbase_free_alloced_region(exec_reg);
641*4882a593Smuzhiyun fail_free_same_va:
642*4882a593Smuzhiyun 	kbase_free_alloced_region(same_va_reg);
643*4882a593Smuzhiyun fail_unlock:
644*4882a593Smuzhiyun 	kbase_gpu_vm_unlock(kctx);
645*4882a593Smuzhiyun 	return err;
646*4882a593Smuzhiyun }
647*4882a593Smuzhiyun 
kbase_region_tracker_init_jit(struct kbase_context * kctx,u64 jit_va_pages)648*4882a593Smuzhiyun int kbase_region_tracker_init_jit(struct kbase_context *kctx, u64 jit_va_pages)
649*4882a593Smuzhiyun {
650*4882a593Smuzhiyun #ifdef CONFIG_64BIT
651*4882a593Smuzhiyun 	struct kbase_va_region *same_va;
652*4882a593Smuzhiyun 	struct kbase_va_region *custom_va_reg;
653*4882a593Smuzhiyun 	u64 same_va_bits;
654*4882a593Smuzhiyun 	u64 total_va_size;
655*4882a593Smuzhiyun 	int err;
656*4882a593Smuzhiyun 
657*4882a593Smuzhiyun 	/*
658*4882a593Smuzhiyun 	 * Nothing to do for 32-bit clients, JIT uses the existing
659*4882a593Smuzhiyun 	 * custom VA zone.
660*4882a593Smuzhiyun 	 */
661*4882a593Smuzhiyun 	if (kbase_ctx_flag(kctx, KCTX_COMPAT))
662*4882a593Smuzhiyun 		return 0;
663*4882a593Smuzhiyun 
664*4882a593Smuzhiyun #if defined(CONFIG_ARM64)
665*4882a593Smuzhiyun 	same_va_bits = VA_BITS;
666*4882a593Smuzhiyun #elif defined(CONFIG_X86_64)
667*4882a593Smuzhiyun 	same_va_bits = 47;
668*4882a593Smuzhiyun #elif defined(CONFIG_64BIT)
669*4882a593Smuzhiyun #error Unsupported 64-bit architecture
670*4882a593Smuzhiyun #endif
671*4882a593Smuzhiyun 
672*4882a593Smuzhiyun 	if (kbase_hw_has_feature(kctx->kbdev, BASE_HW_FEATURE_33BIT_VA))
673*4882a593Smuzhiyun 		same_va_bits = 33;
674*4882a593Smuzhiyun 
675*4882a593Smuzhiyun 	total_va_size = (1ULL << (same_va_bits - PAGE_SHIFT)) - 1;
676*4882a593Smuzhiyun 
677*4882a593Smuzhiyun 	kbase_gpu_vm_lock(kctx);
678*4882a593Smuzhiyun 
679*4882a593Smuzhiyun 	/*
680*4882a593Smuzhiyun 	 * Modify the same VA free region after creation. Be careful to ensure
681*4882a593Smuzhiyun 	 * that allocations haven't been made as they could cause an overlap
682*4882a593Smuzhiyun 	 * to happen with existing same VA allocations and the custom VA zone.
683*4882a593Smuzhiyun 	 */
684*4882a593Smuzhiyun 	same_va = kbase_region_tracker_find_region_base_address(kctx,
685*4882a593Smuzhiyun 			PAGE_SIZE);
686*4882a593Smuzhiyun 	if (!same_va) {
687*4882a593Smuzhiyun 		err = -ENOMEM;
688*4882a593Smuzhiyun 		goto fail_unlock;
689*4882a593Smuzhiyun 	}
690*4882a593Smuzhiyun 
691*4882a593Smuzhiyun 	/* The region flag or region size has changed since creation so bail. */
692*4882a593Smuzhiyun 	if ((!(same_va->flags & KBASE_REG_FREE)) ||
693*4882a593Smuzhiyun 			(same_va->nr_pages != total_va_size)) {
694*4882a593Smuzhiyun 		err = -ENOMEM;
695*4882a593Smuzhiyun 		goto fail_unlock;
696*4882a593Smuzhiyun 	}
697*4882a593Smuzhiyun 
698*4882a593Smuzhiyun 	if (same_va->nr_pages < jit_va_pages ||
699*4882a593Smuzhiyun 			kctx->same_va_end < jit_va_pages) {
700*4882a593Smuzhiyun 		err = -ENOMEM;
701*4882a593Smuzhiyun 		goto fail_unlock;
702*4882a593Smuzhiyun 	}
703*4882a593Smuzhiyun 
704*4882a593Smuzhiyun 	/* It's safe to adjust the same VA zone now */
705*4882a593Smuzhiyun 	same_va->nr_pages -= jit_va_pages;
706*4882a593Smuzhiyun 	kctx->same_va_end -= jit_va_pages;
707*4882a593Smuzhiyun 
708*4882a593Smuzhiyun 	/*
709*4882a593Smuzhiyun 	 * Create a custom VA zone at the end of the VA for allocations which
710*4882a593Smuzhiyun 	 * JIT can use so it doesn't have to allocate VA from the kernel.
711*4882a593Smuzhiyun 	 */
712*4882a593Smuzhiyun 	custom_va_reg = kbase_alloc_free_region(kctx,
713*4882a593Smuzhiyun 				kctx->same_va_end,
714*4882a593Smuzhiyun 				jit_va_pages,
715*4882a593Smuzhiyun 				KBASE_REG_ZONE_CUSTOM_VA);
716*4882a593Smuzhiyun 
717*4882a593Smuzhiyun 	if (!custom_va_reg) {
718*4882a593Smuzhiyun 		/*
719*4882a593Smuzhiyun 		 * The context will be destroyed if we fail here so no point
720*4882a593Smuzhiyun 		 * reverting the change we made to same_va.
721*4882a593Smuzhiyun 		 */
722*4882a593Smuzhiyun 		err = -ENOMEM;
723*4882a593Smuzhiyun 		goto fail_unlock;
724*4882a593Smuzhiyun 	}
725*4882a593Smuzhiyun 
726*4882a593Smuzhiyun 	kbase_region_tracker_insert(kctx, custom_va_reg);
727*4882a593Smuzhiyun 
728*4882a593Smuzhiyun 	kbase_gpu_vm_unlock(kctx);
729*4882a593Smuzhiyun 	return 0;
730*4882a593Smuzhiyun 
731*4882a593Smuzhiyun fail_unlock:
732*4882a593Smuzhiyun 	kbase_gpu_vm_unlock(kctx);
733*4882a593Smuzhiyun 	return err;
734*4882a593Smuzhiyun #else
735*4882a593Smuzhiyun 	return 0;
736*4882a593Smuzhiyun #endif
737*4882a593Smuzhiyun }
738*4882a593Smuzhiyun 
kbase_mem_init(struct kbase_device * kbdev)739*4882a593Smuzhiyun int kbase_mem_init(struct kbase_device *kbdev)
740*4882a593Smuzhiyun {
741*4882a593Smuzhiyun 	struct kbasep_mem_device *memdev;
742*4882a593Smuzhiyun 
743*4882a593Smuzhiyun 	KBASE_DEBUG_ASSERT(kbdev);
744*4882a593Smuzhiyun 
745*4882a593Smuzhiyun 	memdev = &kbdev->memdev;
746*4882a593Smuzhiyun 	kbdev->mem_pool_max_size_default = KBASE_MEM_POOL_MAX_SIZE_KCTX;
747*4882a593Smuzhiyun 
748*4882a593Smuzhiyun 	/* Initialize memory usage */
749*4882a593Smuzhiyun 	atomic_set(&memdev->used_pages, 0);
750*4882a593Smuzhiyun 
751*4882a593Smuzhiyun 	return kbase_mem_pool_init(&kbdev->mem_pool,
752*4882a593Smuzhiyun 			KBASE_MEM_POOL_MAX_SIZE_KBDEV, kbdev, NULL);
753*4882a593Smuzhiyun }
754*4882a593Smuzhiyun 
kbase_mem_halt(struct kbase_device * kbdev)755*4882a593Smuzhiyun void kbase_mem_halt(struct kbase_device *kbdev)
756*4882a593Smuzhiyun {
757*4882a593Smuzhiyun 	CSTD_UNUSED(kbdev);
758*4882a593Smuzhiyun }
759*4882a593Smuzhiyun 
kbase_mem_term(struct kbase_device * kbdev)760*4882a593Smuzhiyun void kbase_mem_term(struct kbase_device *kbdev)
761*4882a593Smuzhiyun {
762*4882a593Smuzhiyun 	struct kbasep_mem_device *memdev;
763*4882a593Smuzhiyun 	int pages;
764*4882a593Smuzhiyun 
765*4882a593Smuzhiyun 	KBASE_DEBUG_ASSERT(kbdev);
766*4882a593Smuzhiyun 
767*4882a593Smuzhiyun 	memdev = &kbdev->memdev;
768*4882a593Smuzhiyun 
769*4882a593Smuzhiyun 	pages = atomic_read(&memdev->used_pages);
770*4882a593Smuzhiyun 	if (pages != 0)
771*4882a593Smuzhiyun 		dev_warn(kbdev->dev, "%s: %d pages in use!\n", __func__, pages);
772*4882a593Smuzhiyun 
773*4882a593Smuzhiyun 	kbase_mem_pool_term(&kbdev->mem_pool);
774*4882a593Smuzhiyun }
775*4882a593Smuzhiyun 
776*4882a593Smuzhiyun KBASE_EXPORT_TEST_API(kbase_mem_term);
777*4882a593Smuzhiyun 
778*4882a593Smuzhiyun 
779*4882a593Smuzhiyun 
780*4882a593Smuzhiyun 
781*4882a593Smuzhiyun /**
782*4882a593Smuzhiyun  * @brief Allocate a free region object.
783*4882a593Smuzhiyun  *
784*4882a593Smuzhiyun  * The allocated object is not part of any list yet, and is flagged as
785*4882a593Smuzhiyun  * KBASE_REG_FREE. No mapping is allocated yet.
786*4882a593Smuzhiyun  *
787*4882a593Smuzhiyun  * zone is KBASE_REG_ZONE_CUSTOM_VA, KBASE_REG_ZONE_SAME_VA, or KBASE_REG_ZONE_EXEC
788*4882a593Smuzhiyun  *
789*4882a593Smuzhiyun  */
kbase_alloc_free_region(struct kbase_context * kctx,u64 start_pfn,size_t nr_pages,int zone)790*4882a593Smuzhiyun struct kbase_va_region *kbase_alloc_free_region(struct kbase_context *kctx, u64 start_pfn, size_t nr_pages, int zone)
791*4882a593Smuzhiyun {
792*4882a593Smuzhiyun 	struct kbase_va_region *new_reg;
793*4882a593Smuzhiyun 
794*4882a593Smuzhiyun 	KBASE_DEBUG_ASSERT(kctx != NULL);
795*4882a593Smuzhiyun 
796*4882a593Smuzhiyun 	/* zone argument should only contain zone related region flags */
797*4882a593Smuzhiyun 	KBASE_DEBUG_ASSERT((zone & ~KBASE_REG_ZONE_MASK) == 0);
798*4882a593Smuzhiyun 	KBASE_DEBUG_ASSERT(nr_pages > 0);
799*4882a593Smuzhiyun 	/* 64-bit address range is the max */
800*4882a593Smuzhiyun 	KBASE_DEBUG_ASSERT(start_pfn + nr_pages <= (U64_MAX / PAGE_SIZE));
801*4882a593Smuzhiyun 
802*4882a593Smuzhiyun 	new_reg = kzalloc(sizeof(*new_reg), GFP_KERNEL);
803*4882a593Smuzhiyun 
804*4882a593Smuzhiyun 	if (!new_reg)
805*4882a593Smuzhiyun 		return NULL;
806*4882a593Smuzhiyun 
807*4882a593Smuzhiyun 	new_reg->cpu_alloc = NULL; /* no alloc bound yet */
808*4882a593Smuzhiyun 	new_reg->gpu_alloc = NULL; /* no alloc bound yet */
809*4882a593Smuzhiyun 	new_reg->kctx = kctx;
810*4882a593Smuzhiyun 	new_reg->flags = zone | KBASE_REG_FREE;
811*4882a593Smuzhiyun 
812*4882a593Smuzhiyun 	new_reg->flags |= KBASE_REG_GROWABLE;
813*4882a593Smuzhiyun 
814*4882a593Smuzhiyun 	new_reg->start_pfn = start_pfn;
815*4882a593Smuzhiyun 	new_reg->nr_pages = nr_pages;
816*4882a593Smuzhiyun 
817*4882a593Smuzhiyun 	return new_reg;
818*4882a593Smuzhiyun }
819*4882a593Smuzhiyun 
820*4882a593Smuzhiyun KBASE_EXPORT_TEST_API(kbase_alloc_free_region);
821*4882a593Smuzhiyun 
822*4882a593Smuzhiyun /**
823*4882a593Smuzhiyun  * @brief Free a region object.
824*4882a593Smuzhiyun  *
825*4882a593Smuzhiyun  * The described region must be freed of any mapping.
826*4882a593Smuzhiyun  *
827*4882a593Smuzhiyun  * If the region is not flagged as KBASE_REG_FREE, the region's
828*4882a593Smuzhiyun  * alloc object will be released.
829*4882a593Smuzhiyun  * It is a bug if no alloc object exists for non-free regions.
830*4882a593Smuzhiyun  *
831*4882a593Smuzhiyun  */
kbase_free_alloced_region(struct kbase_va_region * reg)832*4882a593Smuzhiyun void kbase_free_alloced_region(struct kbase_va_region *reg)
833*4882a593Smuzhiyun {
834*4882a593Smuzhiyun 	if (!(reg->flags & KBASE_REG_FREE)) {
835*4882a593Smuzhiyun 		/*
836*4882a593Smuzhiyun 		 * The physical allocation should have been removed from the
837*4882a593Smuzhiyun 		 * eviction list before this function is called. However, in the
838*4882a593Smuzhiyun 		 * case of abnormal process termination or the app leaking the
839*4882a593Smuzhiyun 		 * memory kbase_mem_free_region is not called so it can still be
840*4882a593Smuzhiyun 		 * on the list at termination time of the region tracker.
841*4882a593Smuzhiyun 		 */
842*4882a593Smuzhiyun 		if (!list_empty(&reg->gpu_alloc->evict_node)) {
843*4882a593Smuzhiyun 			/*
844*4882a593Smuzhiyun 			 * Unlink the physical allocation before unmaking it
845*4882a593Smuzhiyun 			 * evictable so that the allocation isn't grown back to
846*4882a593Smuzhiyun 			 * its last backed size as we're going to unmap it
847*4882a593Smuzhiyun 			 * anyway.
848*4882a593Smuzhiyun 			 */
849*4882a593Smuzhiyun 			reg->cpu_alloc->reg = NULL;
850*4882a593Smuzhiyun 			if (reg->cpu_alloc != reg->gpu_alloc)
851*4882a593Smuzhiyun 				reg->gpu_alloc->reg = NULL;
852*4882a593Smuzhiyun 
853*4882a593Smuzhiyun 			/*
854*4882a593Smuzhiyun 			 * If a region has been made evictable then we must
855*4882a593Smuzhiyun 			 * unmake it before trying to free it.
856*4882a593Smuzhiyun 			 * If the memory hasn't been reclaimed it will be
857*4882a593Smuzhiyun 			 * unmapped and freed below, if it has been reclaimed
858*4882a593Smuzhiyun 			 * then the operations below are no-ops.
859*4882a593Smuzhiyun 			 */
860*4882a593Smuzhiyun 			if (reg->flags & KBASE_REG_DONT_NEED) {
861*4882a593Smuzhiyun 				KBASE_DEBUG_ASSERT(reg->cpu_alloc->type ==
862*4882a593Smuzhiyun 						   KBASE_MEM_TYPE_NATIVE);
863*4882a593Smuzhiyun 				kbase_mem_evictable_unmake(reg->gpu_alloc);
864*4882a593Smuzhiyun 			}
865*4882a593Smuzhiyun 		}
866*4882a593Smuzhiyun 
867*4882a593Smuzhiyun 		/*
868*4882a593Smuzhiyun 		 * Remove the region from the sticky resource metadata
869*4882a593Smuzhiyun 		 * list should it be there.
870*4882a593Smuzhiyun 		 */
871*4882a593Smuzhiyun 		kbase_sticky_resource_release(reg->kctx, NULL,
872*4882a593Smuzhiyun 				reg->start_pfn << PAGE_SHIFT);
873*4882a593Smuzhiyun 
874*4882a593Smuzhiyun 		kbase_mem_phy_alloc_put(reg->cpu_alloc);
875*4882a593Smuzhiyun 		kbase_mem_phy_alloc_put(reg->gpu_alloc);
876*4882a593Smuzhiyun 		/* To detect use-after-free in debug builds */
877*4882a593Smuzhiyun 		KBASE_DEBUG_CODE(reg->flags |= KBASE_REG_FREE);
878*4882a593Smuzhiyun 	}
879*4882a593Smuzhiyun 	kfree(reg);
880*4882a593Smuzhiyun }
881*4882a593Smuzhiyun 
882*4882a593Smuzhiyun KBASE_EXPORT_TEST_API(kbase_free_alloced_region);
883*4882a593Smuzhiyun 
kbase_gpu_mmap(struct kbase_context * kctx,struct kbase_va_region * reg,u64 addr,size_t nr_pages,size_t align)884*4882a593Smuzhiyun int kbase_gpu_mmap(struct kbase_context *kctx, struct kbase_va_region *reg, u64 addr, size_t nr_pages, size_t align)
885*4882a593Smuzhiyun {
886*4882a593Smuzhiyun 	int err;
887*4882a593Smuzhiyun 	size_t i = 0;
888*4882a593Smuzhiyun 	unsigned long attr;
889*4882a593Smuzhiyun 	unsigned long mask = ~KBASE_REG_MEMATTR_MASK;
890*4882a593Smuzhiyun 
891*4882a593Smuzhiyun 	if ((kctx->kbdev->system_coherency == COHERENCY_ACE) &&
892*4882a593Smuzhiyun 		(reg->flags & KBASE_REG_SHARE_BOTH))
893*4882a593Smuzhiyun 		attr = KBASE_REG_MEMATTR_INDEX(AS_MEMATTR_INDEX_OUTER_WA);
894*4882a593Smuzhiyun 	else
895*4882a593Smuzhiyun 		attr = KBASE_REG_MEMATTR_INDEX(AS_MEMATTR_INDEX_WRITE_ALLOC);
896*4882a593Smuzhiyun 
897*4882a593Smuzhiyun 	KBASE_DEBUG_ASSERT(NULL != kctx);
898*4882a593Smuzhiyun 	KBASE_DEBUG_ASSERT(NULL != reg);
899*4882a593Smuzhiyun 
900*4882a593Smuzhiyun 	err = kbase_add_va_region(kctx, reg, addr, nr_pages, align);
901*4882a593Smuzhiyun 	if (err)
902*4882a593Smuzhiyun 		return err;
903*4882a593Smuzhiyun 
904*4882a593Smuzhiyun 	if (reg->gpu_alloc->type == KBASE_MEM_TYPE_ALIAS) {
905*4882a593Smuzhiyun 		u64 stride;
906*4882a593Smuzhiyun 		struct kbase_mem_phy_alloc *alloc;
907*4882a593Smuzhiyun 
908*4882a593Smuzhiyun 		alloc = reg->gpu_alloc;
909*4882a593Smuzhiyun 		stride = alloc->imported.alias.stride;
910*4882a593Smuzhiyun 		KBASE_DEBUG_ASSERT(alloc->imported.alias.aliased);
911*4882a593Smuzhiyun 		for (i = 0; i < alloc->imported.alias.nents; i++) {
912*4882a593Smuzhiyun 			if (alloc->imported.alias.aliased[i].alloc) {
913*4882a593Smuzhiyun 				err = kbase_mmu_insert_pages(kctx,
914*4882a593Smuzhiyun 						reg->start_pfn + (i * stride),
915*4882a593Smuzhiyun 						alloc->imported.alias.aliased[i].alloc->pages + alloc->imported.alias.aliased[i].offset,
916*4882a593Smuzhiyun 						alloc->imported.alias.aliased[i].length,
917*4882a593Smuzhiyun 						reg->flags);
918*4882a593Smuzhiyun 				if (err)
919*4882a593Smuzhiyun 					goto bad_insert;
920*4882a593Smuzhiyun 
921*4882a593Smuzhiyun 				kbase_mem_phy_alloc_gpu_mapped(alloc->imported.alias.aliased[i].alloc);
922*4882a593Smuzhiyun 			} else {
923*4882a593Smuzhiyun 				err = kbase_mmu_insert_single_page(kctx,
924*4882a593Smuzhiyun 					reg->start_pfn + i * stride,
925*4882a593Smuzhiyun 					page_to_phys(kctx->aliasing_sink_page),
926*4882a593Smuzhiyun 					alloc->imported.alias.aliased[i].length,
927*4882a593Smuzhiyun 					(reg->flags & mask) | attr);
928*4882a593Smuzhiyun 
929*4882a593Smuzhiyun 				if (err)
930*4882a593Smuzhiyun 					goto bad_insert;
931*4882a593Smuzhiyun 			}
932*4882a593Smuzhiyun 		}
933*4882a593Smuzhiyun 	} else {
934*4882a593Smuzhiyun 		err = kbase_mmu_insert_pages(kctx, reg->start_pfn,
935*4882a593Smuzhiyun 				kbase_get_gpu_phy_pages(reg),
936*4882a593Smuzhiyun 				kbase_reg_current_backed_size(reg),
937*4882a593Smuzhiyun 				reg->flags);
938*4882a593Smuzhiyun 		if (err)
939*4882a593Smuzhiyun 			goto bad_insert;
940*4882a593Smuzhiyun 		kbase_mem_phy_alloc_gpu_mapped(reg->gpu_alloc);
941*4882a593Smuzhiyun 	}
942*4882a593Smuzhiyun 
943*4882a593Smuzhiyun 	return err;
944*4882a593Smuzhiyun 
945*4882a593Smuzhiyun bad_insert:
946*4882a593Smuzhiyun 	if (reg->gpu_alloc->type == KBASE_MEM_TYPE_ALIAS) {
947*4882a593Smuzhiyun 		u64 stride;
948*4882a593Smuzhiyun 
949*4882a593Smuzhiyun 		stride = reg->gpu_alloc->imported.alias.stride;
950*4882a593Smuzhiyun 		KBASE_DEBUG_ASSERT(reg->gpu_alloc->imported.alias.aliased);
951*4882a593Smuzhiyun 		while (i--)
952*4882a593Smuzhiyun 			if (reg->gpu_alloc->imported.alias.aliased[i].alloc) {
953*4882a593Smuzhiyun 				kbase_mmu_teardown_pages(kctx, reg->start_pfn + (i * stride), reg->gpu_alloc->imported.alias.aliased[i].length);
954*4882a593Smuzhiyun 				kbase_mem_phy_alloc_gpu_unmapped(reg->gpu_alloc->imported.alias.aliased[i].alloc);
955*4882a593Smuzhiyun 			}
956*4882a593Smuzhiyun 	}
957*4882a593Smuzhiyun 
958*4882a593Smuzhiyun 	kbase_remove_va_region(kctx, reg);
959*4882a593Smuzhiyun 
960*4882a593Smuzhiyun 	return err;
961*4882a593Smuzhiyun }
962*4882a593Smuzhiyun 
963*4882a593Smuzhiyun KBASE_EXPORT_TEST_API(kbase_gpu_mmap);
964*4882a593Smuzhiyun 
965*4882a593Smuzhiyun static void kbase_jd_user_buf_unmap(struct kbase_context *kctx,
966*4882a593Smuzhiyun 		struct kbase_mem_phy_alloc *alloc, bool writeable);
967*4882a593Smuzhiyun 
kbase_gpu_munmap(struct kbase_context * kctx,struct kbase_va_region * reg)968*4882a593Smuzhiyun int kbase_gpu_munmap(struct kbase_context *kctx, struct kbase_va_region *reg)
969*4882a593Smuzhiyun {
970*4882a593Smuzhiyun 	int err;
971*4882a593Smuzhiyun 
972*4882a593Smuzhiyun 	if (reg->start_pfn == 0)
973*4882a593Smuzhiyun 		return 0;
974*4882a593Smuzhiyun 
975*4882a593Smuzhiyun 	if (reg->gpu_alloc && reg->gpu_alloc->type == KBASE_MEM_TYPE_ALIAS) {
976*4882a593Smuzhiyun 		size_t i;
977*4882a593Smuzhiyun 
978*4882a593Smuzhiyun 		err = kbase_mmu_teardown_pages(kctx, reg->start_pfn, reg->nr_pages);
979*4882a593Smuzhiyun 		KBASE_DEBUG_ASSERT(reg->gpu_alloc->imported.alias.aliased);
980*4882a593Smuzhiyun 		for (i = 0; i < reg->gpu_alloc->imported.alias.nents; i++)
981*4882a593Smuzhiyun 			if (reg->gpu_alloc->imported.alias.aliased[i].alloc)
982*4882a593Smuzhiyun 				kbase_mem_phy_alloc_gpu_unmapped(reg->gpu_alloc->imported.alias.aliased[i].alloc);
983*4882a593Smuzhiyun 	} else {
984*4882a593Smuzhiyun 		err = kbase_mmu_teardown_pages(kctx, reg->start_pfn, kbase_reg_current_backed_size(reg));
985*4882a593Smuzhiyun 		kbase_mem_phy_alloc_gpu_unmapped(reg->gpu_alloc);
986*4882a593Smuzhiyun 	}
987*4882a593Smuzhiyun 
988*4882a593Smuzhiyun 	if (reg->gpu_alloc && reg->gpu_alloc->type ==
989*4882a593Smuzhiyun 			KBASE_MEM_TYPE_IMPORTED_USER_BUF) {
990*4882a593Smuzhiyun 		struct kbase_alloc_import_user_buf *user_buf =
991*4882a593Smuzhiyun 			&reg->gpu_alloc->imported.user_buf;
992*4882a593Smuzhiyun 
993*4882a593Smuzhiyun 		if (user_buf->current_mapping_usage_count & PINNED_ON_IMPORT) {
994*4882a593Smuzhiyun 			user_buf->current_mapping_usage_count &=
995*4882a593Smuzhiyun 				~PINNED_ON_IMPORT;
996*4882a593Smuzhiyun 
997*4882a593Smuzhiyun 			kbase_jd_user_buf_unmap(kctx, reg->gpu_alloc,
998*4882a593Smuzhiyun 					(reg->flags & KBASE_REG_GPU_WR));
999*4882a593Smuzhiyun 		}
1000*4882a593Smuzhiyun 	}
1001*4882a593Smuzhiyun 
1002*4882a593Smuzhiyun 	if (err)
1003*4882a593Smuzhiyun 		return err;
1004*4882a593Smuzhiyun 
1005*4882a593Smuzhiyun 	err = kbase_remove_va_region(kctx, reg);
1006*4882a593Smuzhiyun 	return err;
1007*4882a593Smuzhiyun }
1008*4882a593Smuzhiyun 
kbasep_find_enclosing_cpu_mapping(struct kbase_context * kctx,unsigned long uaddr,size_t size,u64 * offset)1009*4882a593Smuzhiyun static struct kbase_cpu_mapping *kbasep_find_enclosing_cpu_mapping(
1010*4882a593Smuzhiyun 		struct kbase_context *kctx,
1011*4882a593Smuzhiyun 		unsigned long uaddr, size_t size, u64 *offset)
1012*4882a593Smuzhiyun {
1013*4882a593Smuzhiyun 	struct vm_area_struct *vma;
1014*4882a593Smuzhiyun 	struct kbase_cpu_mapping *map;
1015*4882a593Smuzhiyun 	unsigned long vm_pgoff_in_region;
1016*4882a593Smuzhiyun 	unsigned long vm_off_in_region;
1017*4882a593Smuzhiyun 	unsigned long map_start;
1018*4882a593Smuzhiyun 	size_t map_size;
1019*4882a593Smuzhiyun 
1020*4882a593Smuzhiyun 	lockdep_assert_held(&current->mm->mmap_lock);
1021*4882a593Smuzhiyun 
1022*4882a593Smuzhiyun 	if ((uintptr_t) uaddr + size < (uintptr_t) uaddr) /* overflow check */
1023*4882a593Smuzhiyun 		return NULL;
1024*4882a593Smuzhiyun 
1025*4882a593Smuzhiyun 	vma = find_vma_intersection(current->mm, uaddr, uaddr+size);
1026*4882a593Smuzhiyun 
1027*4882a593Smuzhiyun 	if (!vma || vma->vm_start > uaddr)
1028*4882a593Smuzhiyun 		return NULL;
1029*4882a593Smuzhiyun 	if (vma->vm_ops != &kbase_vm_ops)
1030*4882a593Smuzhiyun 		/* Not ours! */
1031*4882a593Smuzhiyun 		return NULL;
1032*4882a593Smuzhiyun 
1033*4882a593Smuzhiyun 	map = vma->vm_private_data;
1034*4882a593Smuzhiyun 
1035*4882a593Smuzhiyun 	if (map->kctx != kctx)
1036*4882a593Smuzhiyun 		/* Not from this context! */
1037*4882a593Smuzhiyun 		return NULL;
1038*4882a593Smuzhiyun 
1039*4882a593Smuzhiyun 	vm_pgoff_in_region = vma->vm_pgoff - map->region->start_pfn;
1040*4882a593Smuzhiyun 	vm_off_in_region = vm_pgoff_in_region << PAGE_SHIFT;
1041*4882a593Smuzhiyun 	map_start = vma->vm_start - vm_off_in_region;
1042*4882a593Smuzhiyun 	map_size = map->region->nr_pages << PAGE_SHIFT;
1043*4882a593Smuzhiyun 
1044*4882a593Smuzhiyun 	if ((uaddr + size) > (map_start + map_size))
1045*4882a593Smuzhiyun 		/* Not within the CPU mapping */
1046*4882a593Smuzhiyun 		return NULL;
1047*4882a593Smuzhiyun 
1048*4882a593Smuzhiyun 	*offset = (uaddr - vma->vm_start) + vm_off_in_region;
1049*4882a593Smuzhiyun 
1050*4882a593Smuzhiyun 	return map;
1051*4882a593Smuzhiyun }
1052*4882a593Smuzhiyun 
kbasep_find_enclosing_cpu_mapping_offset(struct kbase_context * kctx,unsigned long uaddr,size_t size,u64 * offset)1053*4882a593Smuzhiyun int kbasep_find_enclosing_cpu_mapping_offset(
1054*4882a593Smuzhiyun 		struct kbase_context *kctx,
1055*4882a593Smuzhiyun 		unsigned long uaddr, size_t size, u64 *offset)
1056*4882a593Smuzhiyun {
1057*4882a593Smuzhiyun 	struct kbase_cpu_mapping *map;
1058*4882a593Smuzhiyun 
1059*4882a593Smuzhiyun 	kbase_os_mem_map_lock(kctx);
1060*4882a593Smuzhiyun 
1061*4882a593Smuzhiyun 	map = kbasep_find_enclosing_cpu_mapping(kctx, uaddr, size, offset);
1062*4882a593Smuzhiyun 
1063*4882a593Smuzhiyun 	kbase_os_mem_map_unlock(kctx);
1064*4882a593Smuzhiyun 
1065*4882a593Smuzhiyun 	if (!map)
1066*4882a593Smuzhiyun 		return -EINVAL;
1067*4882a593Smuzhiyun 
1068*4882a593Smuzhiyun 	return 0;
1069*4882a593Smuzhiyun }
1070*4882a593Smuzhiyun 
1071*4882a593Smuzhiyun KBASE_EXPORT_TEST_API(kbasep_find_enclosing_cpu_mapping_offset);
1072*4882a593Smuzhiyun 
kbase_sync_single(struct kbase_context * kctx,phys_addr_t cpu_pa,phys_addr_t gpu_pa,off_t offset,size_t size,enum kbase_sync_type sync_fn)1073*4882a593Smuzhiyun void kbase_sync_single(struct kbase_context *kctx,
1074*4882a593Smuzhiyun 		phys_addr_t cpu_pa, phys_addr_t gpu_pa,
1075*4882a593Smuzhiyun 		off_t offset, size_t size, enum kbase_sync_type sync_fn)
1076*4882a593Smuzhiyun {
1077*4882a593Smuzhiyun 	struct page *cpu_page;
1078*4882a593Smuzhiyun 
1079*4882a593Smuzhiyun 	cpu_page = pfn_to_page(PFN_DOWN(cpu_pa));
1080*4882a593Smuzhiyun 
1081*4882a593Smuzhiyun 	if (likely(cpu_pa == gpu_pa)) {
1082*4882a593Smuzhiyun 		dma_addr_t dma_addr;
1083*4882a593Smuzhiyun 
1084*4882a593Smuzhiyun 		BUG_ON(!cpu_page);
1085*4882a593Smuzhiyun 		BUG_ON(offset + size > PAGE_SIZE);
1086*4882a593Smuzhiyun 
1087*4882a593Smuzhiyun 		dma_addr = kbase_dma_addr(cpu_page) + offset;
1088*4882a593Smuzhiyun 		if (sync_fn == KBASE_SYNC_TO_CPU)
1089*4882a593Smuzhiyun 			dma_sync_single_for_cpu(kctx->kbdev->dev, dma_addr,
1090*4882a593Smuzhiyun 					size, DMA_BIDIRECTIONAL);
1091*4882a593Smuzhiyun 		else if (sync_fn == KBASE_SYNC_TO_DEVICE)
1092*4882a593Smuzhiyun 			dma_sync_single_for_device(kctx->kbdev->dev, dma_addr,
1093*4882a593Smuzhiyun 					size, DMA_BIDIRECTIONAL);
1094*4882a593Smuzhiyun 	} else {
1095*4882a593Smuzhiyun 		void *src = NULL;
1096*4882a593Smuzhiyun 		void *dst = NULL;
1097*4882a593Smuzhiyun 		struct page *gpu_page;
1098*4882a593Smuzhiyun 
1099*4882a593Smuzhiyun 		if (WARN(!gpu_pa, "No GPU PA found for infinite cache op"))
1100*4882a593Smuzhiyun 			return;
1101*4882a593Smuzhiyun 
1102*4882a593Smuzhiyun 		gpu_page = pfn_to_page(PFN_DOWN(gpu_pa));
1103*4882a593Smuzhiyun 
1104*4882a593Smuzhiyun 		if (sync_fn == KBASE_SYNC_TO_DEVICE) {
1105*4882a593Smuzhiyun 			src = ((unsigned char *)kmap(cpu_page)) + offset;
1106*4882a593Smuzhiyun 			dst = ((unsigned char *)kmap(gpu_page)) + offset;
1107*4882a593Smuzhiyun 		} else if (sync_fn == KBASE_SYNC_TO_CPU) {
1108*4882a593Smuzhiyun 			dma_sync_single_for_cpu(kctx->kbdev->dev,
1109*4882a593Smuzhiyun 					kbase_dma_addr(gpu_page) + offset,
1110*4882a593Smuzhiyun 					size, DMA_BIDIRECTIONAL);
1111*4882a593Smuzhiyun 			src = ((unsigned char *)kmap(gpu_page)) + offset;
1112*4882a593Smuzhiyun 			dst = ((unsigned char *)kmap(cpu_page)) + offset;
1113*4882a593Smuzhiyun 		}
1114*4882a593Smuzhiyun 		memcpy(dst, src, size);
1115*4882a593Smuzhiyun 		kunmap(gpu_page);
1116*4882a593Smuzhiyun 		kunmap(cpu_page);
1117*4882a593Smuzhiyun 		if (sync_fn == KBASE_SYNC_TO_DEVICE)
1118*4882a593Smuzhiyun 			dma_sync_single_for_device(kctx->kbdev->dev,
1119*4882a593Smuzhiyun 					kbase_dma_addr(gpu_page) + offset,
1120*4882a593Smuzhiyun 					size, DMA_BIDIRECTIONAL);
1121*4882a593Smuzhiyun 	}
1122*4882a593Smuzhiyun }
1123*4882a593Smuzhiyun 
kbase_do_syncset(struct kbase_context * kctx,struct basep_syncset * sset,enum kbase_sync_type sync_fn)1124*4882a593Smuzhiyun static int kbase_do_syncset(struct kbase_context *kctx,
1125*4882a593Smuzhiyun 		struct basep_syncset *sset, enum kbase_sync_type sync_fn)
1126*4882a593Smuzhiyun {
1127*4882a593Smuzhiyun 	int err = 0;
1128*4882a593Smuzhiyun 	struct kbase_va_region *reg;
1129*4882a593Smuzhiyun 	struct kbase_cpu_mapping *map;
1130*4882a593Smuzhiyun 	unsigned long start;
1131*4882a593Smuzhiyun 	size_t size;
1132*4882a593Smuzhiyun 	phys_addr_t *cpu_pa;
1133*4882a593Smuzhiyun 	phys_addr_t *gpu_pa;
1134*4882a593Smuzhiyun 	u64 page_off, page_count;
1135*4882a593Smuzhiyun 	u64 i;
1136*4882a593Smuzhiyun 	u64 offset;
1137*4882a593Smuzhiyun 
1138*4882a593Smuzhiyun 	kbase_os_mem_map_lock(kctx);
1139*4882a593Smuzhiyun 	kbase_gpu_vm_lock(kctx);
1140*4882a593Smuzhiyun 
1141*4882a593Smuzhiyun 	/* find the region where the virtual address is contained */
1142*4882a593Smuzhiyun 	reg = kbase_region_tracker_find_region_enclosing_address(kctx,
1143*4882a593Smuzhiyun 			sset->mem_handle.basep.handle);
1144*4882a593Smuzhiyun 	if (!reg) {
1145*4882a593Smuzhiyun 		dev_warn(kctx->kbdev->dev, "Can't find region at VA 0x%016llX",
1146*4882a593Smuzhiyun 				sset->mem_handle.basep.handle);
1147*4882a593Smuzhiyun 		err = -EINVAL;
1148*4882a593Smuzhiyun 		goto out_unlock;
1149*4882a593Smuzhiyun 	}
1150*4882a593Smuzhiyun 
1151*4882a593Smuzhiyun 	if (!(reg->flags & KBASE_REG_CPU_CACHED))
1152*4882a593Smuzhiyun 		goto out_unlock;
1153*4882a593Smuzhiyun 
1154*4882a593Smuzhiyun 	start = (uintptr_t)sset->user_addr;
1155*4882a593Smuzhiyun 	size = (size_t)sset->size;
1156*4882a593Smuzhiyun 
1157*4882a593Smuzhiyun 	map = kbasep_find_enclosing_cpu_mapping(kctx, start, size, &offset);
1158*4882a593Smuzhiyun 	if (!map) {
1159*4882a593Smuzhiyun 		dev_warn(kctx->kbdev->dev, "Can't find CPU mapping 0x%016lX for VA 0x%016llX",
1160*4882a593Smuzhiyun 				start, sset->mem_handle.basep.handle);
1161*4882a593Smuzhiyun 		err = -EINVAL;
1162*4882a593Smuzhiyun 		goto out_unlock;
1163*4882a593Smuzhiyun 	}
1164*4882a593Smuzhiyun 
1165*4882a593Smuzhiyun 	page_off = offset >> PAGE_SHIFT;
1166*4882a593Smuzhiyun 	offset &= ~PAGE_MASK;
1167*4882a593Smuzhiyun 	page_count = (size + offset + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
1168*4882a593Smuzhiyun 	cpu_pa = kbase_get_cpu_phy_pages(reg);
1169*4882a593Smuzhiyun 	gpu_pa = kbase_get_gpu_phy_pages(reg);
1170*4882a593Smuzhiyun 
1171*4882a593Smuzhiyun 	if (page_off > reg->nr_pages ||
1172*4882a593Smuzhiyun 			page_off + page_count > reg->nr_pages) {
1173*4882a593Smuzhiyun 		/* Sync overflows the region */
1174*4882a593Smuzhiyun 		err = -EINVAL;
1175*4882a593Smuzhiyun 		goto out_unlock;
1176*4882a593Smuzhiyun 	}
1177*4882a593Smuzhiyun 
1178*4882a593Smuzhiyun 	/* Sync first page */
1179*4882a593Smuzhiyun 	if (cpu_pa[page_off]) {
1180*4882a593Smuzhiyun 		size_t sz = MIN(((size_t) PAGE_SIZE - offset), size);
1181*4882a593Smuzhiyun 
1182*4882a593Smuzhiyun 		kbase_sync_single(kctx, cpu_pa[page_off], gpu_pa[page_off],
1183*4882a593Smuzhiyun 				offset, sz, sync_fn);
1184*4882a593Smuzhiyun 	}
1185*4882a593Smuzhiyun 
1186*4882a593Smuzhiyun 	/* Sync middle pages (if any) */
1187*4882a593Smuzhiyun 	for (i = 1; page_count > 2 && i < page_count - 1; i++) {
1188*4882a593Smuzhiyun 		/* we grow upwards, so bail on first non-present page */
1189*4882a593Smuzhiyun 		if (!cpu_pa[page_off + i])
1190*4882a593Smuzhiyun 			break;
1191*4882a593Smuzhiyun 
1192*4882a593Smuzhiyun 		kbase_sync_single(kctx, cpu_pa[page_off + i],
1193*4882a593Smuzhiyun 				gpu_pa[page_off + i], 0, PAGE_SIZE, sync_fn);
1194*4882a593Smuzhiyun 	}
1195*4882a593Smuzhiyun 
1196*4882a593Smuzhiyun 	/* Sync last page (if any) */
1197*4882a593Smuzhiyun 	if (page_count > 1 && cpu_pa[page_off + page_count - 1]) {
1198*4882a593Smuzhiyun 		size_t sz = ((start + size - 1) & ~PAGE_MASK) + 1;
1199*4882a593Smuzhiyun 
1200*4882a593Smuzhiyun 		kbase_sync_single(kctx, cpu_pa[page_off + page_count - 1],
1201*4882a593Smuzhiyun 				gpu_pa[page_off + page_count - 1], 0, sz,
1202*4882a593Smuzhiyun 				sync_fn);
1203*4882a593Smuzhiyun 	}
1204*4882a593Smuzhiyun 
1205*4882a593Smuzhiyun out_unlock:
1206*4882a593Smuzhiyun 	kbase_gpu_vm_unlock(kctx);
1207*4882a593Smuzhiyun 	kbase_os_mem_map_unlock(kctx);
1208*4882a593Smuzhiyun 	return err;
1209*4882a593Smuzhiyun }
1210*4882a593Smuzhiyun 
kbase_sync_now(struct kbase_context * kctx,struct basep_syncset * sset)1211*4882a593Smuzhiyun int kbase_sync_now(struct kbase_context *kctx, struct basep_syncset *sset)
1212*4882a593Smuzhiyun {
1213*4882a593Smuzhiyun 	int err = -EINVAL;
1214*4882a593Smuzhiyun 
1215*4882a593Smuzhiyun 	KBASE_DEBUG_ASSERT(kctx != NULL);
1216*4882a593Smuzhiyun 	KBASE_DEBUG_ASSERT(sset != NULL);
1217*4882a593Smuzhiyun 
1218*4882a593Smuzhiyun 	if (sset->mem_handle.basep.handle & ~PAGE_MASK) {
1219*4882a593Smuzhiyun 		dev_warn(kctx->kbdev->dev,
1220*4882a593Smuzhiyun 				"mem_handle: passed parameter is invalid");
1221*4882a593Smuzhiyun 		return -EINVAL;
1222*4882a593Smuzhiyun 	}
1223*4882a593Smuzhiyun 
1224*4882a593Smuzhiyun 	switch (sset->type) {
1225*4882a593Smuzhiyun 	case BASE_SYNCSET_OP_MSYNC:
1226*4882a593Smuzhiyun 		err = kbase_do_syncset(kctx, sset, KBASE_SYNC_TO_DEVICE);
1227*4882a593Smuzhiyun 		break;
1228*4882a593Smuzhiyun 
1229*4882a593Smuzhiyun 	case BASE_SYNCSET_OP_CSYNC:
1230*4882a593Smuzhiyun 		err = kbase_do_syncset(kctx, sset, KBASE_SYNC_TO_CPU);
1231*4882a593Smuzhiyun 		break;
1232*4882a593Smuzhiyun 
1233*4882a593Smuzhiyun 	default:
1234*4882a593Smuzhiyun 		dev_warn(kctx->kbdev->dev, "Unknown msync op %d\n", sset->type);
1235*4882a593Smuzhiyun 		break;
1236*4882a593Smuzhiyun 	}
1237*4882a593Smuzhiyun 
1238*4882a593Smuzhiyun 	return err;
1239*4882a593Smuzhiyun }
1240*4882a593Smuzhiyun 
1241*4882a593Smuzhiyun KBASE_EXPORT_TEST_API(kbase_sync_now);
1242*4882a593Smuzhiyun 
1243*4882a593Smuzhiyun /* vm lock must be held */
kbase_mem_free_region(struct kbase_context * kctx,struct kbase_va_region * reg)1244*4882a593Smuzhiyun int kbase_mem_free_region(struct kbase_context *kctx, struct kbase_va_region *reg)
1245*4882a593Smuzhiyun {
1246*4882a593Smuzhiyun 	int err;
1247*4882a593Smuzhiyun 
1248*4882a593Smuzhiyun 	KBASE_DEBUG_ASSERT(NULL != kctx);
1249*4882a593Smuzhiyun 	KBASE_DEBUG_ASSERT(NULL != reg);
1250*4882a593Smuzhiyun 	lockdep_assert_held(&kctx->reg_lock);
1251*4882a593Smuzhiyun 
1252*4882a593Smuzhiyun 	/*
1253*4882a593Smuzhiyun 	 * Unlink the physical allocation before unmaking it evictable so
1254*4882a593Smuzhiyun 	 * that the allocation isn't grown back to its last backed size
1255*4882a593Smuzhiyun 	 * as we're going to unmap it anyway.
1256*4882a593Smuzhiyun 	 */
1257*4882a593Smuzhiyun 	reg->cpu_alloc->reg = NULL;
1258*4882a593Smuzhiyun 	if (reg->cpu_alloc != reg->gpu_alloc)
1259*4882a593Smuzhiyun 		reg->gpu_alloc->reg = NULL;
1260*4882a593Smuzhiyun 
1261*4882a593Smuzhiyun 	/*
1262*4882a593Smuzhiyun 	 * If a region has been made evictable then we must unmake it
1263*4882a593Smuzhiyun 	 * before trying to free it.
1264*4882a593Smuzhiyun 	 * If the memory hasn't been reclaimed it will be unmapped and freed
1265*4882a593Smuzhiyun 	 * below, if it has been reclaimed then the operations below are no-ops.
1266*4882a593Smuzhiyun 	 */
1267*4882a593Smuzhiyun 	if (reg->flags & KBASE_REG_DONT_NEED) {
1268*4882a593Smuzhiyun 		KBASE_DEBUG_ASSERT(reg->cpu_alloc->type ==
1269*4882a593Smuzhiyun 				   KBASE_MEM_TYPE_NATIVE);
1270*4882a593Smuzhiyun 		kbase_mem_evictable_unmake(reg->gpu_alloc);
1271*4882a593Smuzhiyun 	}
1272*4882a593Smuzhiyun 
1273*4882a593Smuzhiyun 	err = kbase_gpu_munmap(kctx, reg);
1274*4882a593Smuzhiyun 	if (err) {
1275*4882a593Smuzhiyun 		dev_warn(reg->kctx->kbdev->dev, "Could not unmap from the GPU...\n");
1276*4882a593Smuzhiyun 		goto out;
1277*4882a593Smuzhiyun 	}
1278*4882a593Smuzhiyun 
1279*4882a593Smuzhiyun 	/* This will also free the physical pages */
1280*4882a593Smuzhiyun 	kbase_free_alloced_region(reg);
1281*4882a593Smuzhiyun 
1282*4882a593Smuzhiyun  out:
1283*4882a593Smuzhiyun 	return err;
1284*4882a593Smuzhiyun }
1285*4882a593Smuzhiyun 
1286*4882a593Smuzhiyun KBASE_EXPORT_TEST_API(kbase_mem_free_region);
1287*4882a593Smuzhiyun 
1288*4882a593Smuzhiyun /**
1289*4882a593Smuzhiyun  * @brief Free the region from the GPU and unregister it.
1290*4882a593Smuzhiyun  *
1291*4882a593Smuzhiyun  * This function implements the free operation on a memory segment.
1292*4882a593Smuzhiyun  * It will loudly fail if called with outstanding mappings.
1293*4882a593Smuzhiyun  */
kbase_mem_free(struct kbase_context * kctx,u64 gpu_addr)1294*4882a593Smuzhiyun int kbase_mem_free(struct kbase_context *kctx, u64 gpu_addr)
1295*4882a593Smuzhiyun {
1296*4882a593Smuzhiyun 	int err = 0;
1297*4882a593Smuzhiyun 	struct kbase_va_region *reg;
1298*4882a593Smuzhiyun 
1299*4882a593Smuzhiyun 	KBASE_DEBUG_ASSERT(kctx != NULL);
1300*4882a593Smuzhiyun 
1301*4882a593Smuzhiyun 	if ((gpu_addr & ~PAGE_MASK) && (gpu_addr >= PAGE_SIZE)) {
1302*4882a593Smuzhiyun 		dev_warn(kctx->kbdev->dev, "kbase_mem_free: gpu_addr parameter is invalid");
1303*4882a593Smuzhiyun 		return -EINVAL;
1304*4882a593Smuzhiyun 	}
1305*4882a593Smuzhiyun 
1306*4882a593Smuzhiyun 	if (0 == gpu_addr) {
1307*4882a593Smuzhiyun 		dev_warn(kctx->kbdev->dev, "gpu_addr 0 is reserved for the ringbuffer and it's an error to try to free it using kbase_mem_free\n");
1308*4882a593Smuzhiyun 		return -EINVAL;
1309*4882a593Smuzhiyun 	}
1310*4882a593Smuzhiyun 	kbase_gpu_vm_lock(kctx);
1311*4882a593Smuzhiyun 
1312*4882a593Smuzhiyun 	if (gpu_addr >= BASE_MEM_COOKIE_BASE &&
1313*4882a593Smuzhiyun 	    gpu_addr < BASE_MEM_FIRST_FREE_ADDRESS) {
1314*4882a593Smuzhiyun 		int cookie = PFN_DOWN(gpu_addr - BASE_MEM_COOKIE_BASE);
1315*4882a593Smuzhiyun 
1316*4882a593Smuzhiyun 		reg = kctx->pending_regions[cookie];
1317*4882a593Smuzhiyun 		if (!reg) {
1318*4882a593Smuzhiyun 			err = -EINVAL;
1319*4882a593Smuzhiyun 			goto out_unlock;
1320*4882a593Smuzhiyun 		}
1321*4882a593Smuzhiyun 
1322*4882a593Smuzhiyun 		/* ask to unlink the cookie as we'll free it */
1323*4882a593Smuzhiyun 
1324*4882a593Smuzhiyun 		kctx->pending_regions[cookie] = NULL;
1325*4882a593Smuzhiyun 		kctx->cookies |= (1UL << cookie);
1326*4882a593Smuzhiyun 
1327*4882a593Smuzhiyun 		kbase_free_alloced_region(reg);
1328*4882a593Smuzhiyun 	} else {
1329*4882a593Smuzhiyun 		/* A real GPU va */
1330*4882a593Smuzhiyun 		/* Validate the region */
1331*4882a593Smuzhiyun 		reg = kbase_region_tracker_find_region_base_address(kctx, gpu_addr);
1332*4882a593Smuzhiyun 		if (!reg || (reg->flags & KBASE_REG_FREE)) {
1333*4882a593Smuzhiyun 			dev_warn(kctx->kbdev->dev, "kbase_mem_free called with nonexistent gpu_addr 0x%llX",
1334*4882a593Smuzhiyun 					gpu_addr);
1335*4882a593Smuzhiyun 			err = -EINVAL;
1336*4882a593Smuzhiyun 			goto out_unlock;
1337*4882a593Smuzhiyun 		}
1338*4882a593Smuzhiyun 
1339*4882a593Smuzhiyun 		if ((reg->flags & KBASE_REG_ZONE_MASK) == KBASE_REG_ZONE_SAME_VA) {
1340*4882a593Smuzhiyun 			/* SAME_VA must be freed through munmap */
1341*4882a593Smuzhiyun 			dev_warn(kctx->kbdev->dev, "%s called on SAME_VA memory 0x%llX", __func__,
1342*4882a593Smuzhiyun 					gpu_addr);
1343*4882a593Smuzhiyun 			err = -EINVAL;
1344*4882a593Smuzhiyun 			goto out_unlock;
1345*4882a593Smuzhiyun 		}
1346*4882a593Smuzhiyun 		err = kbase_mem_free_region(kctx, reg);
1347*4882a593Smuzhiyun 	}
1348*4882a593Smuzhiyun 
1349*4882a593Smuzhiyun  out_unlock:
1350*4882a593Smuzhiyun 	kbase_gpu_vm_unlock(kctx);
1351*4882a593Smuzhiyun 	return err;
1352*4882a593Smuzhiyun }
1353*4882a593Smuzhiyun 
1354*4882a593Smuzhiyun KBASE_EXPORT_TEST_API(kbase_mem_free);
1355*4882a593Smuzhiyun 
kbase_update_region_flags(struct kbase_context * kctx,struct kbase_va_region * reg,unsigned long flags)1356*4882a593Smuzhiyun int kbase_update_region_flags(struct kbase_context *kctx,
1357*4882a593Smuzhiyun 		struct kbase_va_region *reg, unsigned long flags)
1358*4882a593Smuzhiyun {
1359*4882a593Smuzhiyun 	KBASE_DEBUG_ASSERT(NULL != reg);
1360*4882a593Smuzhiyun 	KBASE_DEBUG_ASSERT((flags & ~((1ul << BASE_MEM_FLAGS_NR_BITS) - 1)) == 0);
1361*4882a593Smuzhiyun 
1362*4882a593Smuzhiyun 	reg->flags |= kbase_cache_enabled(flags, reg->nr_pages);
1363*4882a593Smuzhiyun 	/* all memory is now growable */
1364*4882a593Smuzhiyun 	reg->flags |= KBASE_REG_GROWABLE;
1365*4882a593Smuzhiyun 
1366*4882a593Smuzhiyun 	if (flags & BASE_MEM_GROW_ON_GPF)
1367*4882a593Smuzhiyun 		reg->flags |= KBASE_REG_PF_GROW;
1368*4882a593Smuzhiyun 
1369*4882a593Smuzhiyun 	if (flags & BASE_MEM_PROT_CPU_WR)
1370*4882a593Smuzhiyun 		reg->flags |= KBASE_REG_CPU_WR;
1371*4882a593Smuzhiyun 
1372*4882a593Smuzhiyun 	if (flags & BASE_MEM_PROT_CPU_RD)
1373*4882a593Smuzhiyun 		reg->flags |= KBASE_REG_CPU_RD;
1374*4882a593Smuzhiyun 
1375*4882a593Smuzhiyun 	if (flags & BASE_MEM_PROT_GPU_WR)
1376*4882a593Smuzhiyun 		reg->flags |= KBASE_REG_GPU_WR;
1377*4882a593Smuzhiyun 
1378*4882a593Smuzhiyun 	if (flags & BASE_MEM_PROT_GPU_RD)
1379*4882a593Smuzhiyun 		reg->flags |= KBASE_REG_GPU_RD;
1380*4882a593Smuzhiyun 
1381*4882a593Smuzhiyun 	if (0 == (flags & BASE_MEM_PROT_GPU_EX))
1382*4882a593Smuzhiyun 		reg->flags |= KBASE_REG_GPU_NX;
1383*4882a593Smuzhiyun 
1384*4882a593Smuzhiyun 	if (!kbase_device_is_cpu_coherent(kctx->kbdev)) {
1385*4882a593Smuzhiyun 		if (flags & BASE_MEM_COHERENT_SYSTEM_REQUIRED)
1386*4882a593Smuzhiyun 			return -EINVAL;
1387*4882a593Smuzhiyun 	} else if (flags & (BASE_MEM_COHERENT_SYSTEM |
1388*4882a593Smuzhiyun 			BASE_MEM_COHERENT_SYSTEM_REQUIRED)) {
1389*4882a593Smuzhiyun 		reg->flags |= KBASE_REG_SHARE_BOTH;
1390*4882a593Smuzhiyun 	}
1391*4882a593Smuzhiyun 
1392*4882a593Smuzhiyun 	if (!(reg->flags & KBASE_REG_SHARE_BOTH) &&
1393*4882a593Smuzhiyun 			flags & BASE_MEM_COHERENT_LOCAL) {
1394*4882a593Smuzhiyun 		reg->flags |= KBASE_REG_SHARE_IN;
1395*4882a593Smuzhiyun 	}
1396*4882a593Smuzhiyun 
1397*4882a593Smuzhiyun 	/* Set up default MEMATTR usage */
1398*4882a593Smuzhiyun 	if (kctx->kbdev->system_coherency == COHERENCY_ACE &&
1399*4882a593Smuzhiyun 		(reg->flags & KBASE_REG_SHARE_BOTH)) {
1400*4882a593Smuzhiyun 		reg->flags |=
1401*4882a593Smuzhiyun 			KBASE_REG_MEMATTR_INDEX(AS_MEMATTR_INDEX_DEFAULT_ACE);
1402*4882a593Smuzhiyun 	} else {
1403*4882a593Smuzhiyun 		reg->flags |=
1404*4882a593Smuzhiyun 			KBASE_REG_MEMATTR_INDEX(AS_MEMATTR_INDEX_DEFAULT);
1405*4882a593Smuzhiyun 	}
1406*4882a593Smuzhiyun 
1407*4882a593Smuzhiyun 	return 0;
1408*4882a593Smuzhiyun }
1409*4882a593Smuzhiyun 
kbase_alloc_phy_pages_helper(struct kbase_mem_phy_alloc * alloc,size_t nr_pages_requested)1410*4882a593Smuzhiyun int kbase_alloc_phy_pages_helper(
1411*4882a593Smuzhiyun 	struct kbase_mem_phy_alloc *alloc,
1412*4882a593Smuzhiyun 	size_t nr_pages_requested)
1413*4882a593Smuzhiyun {
1414*4882a593Smuzhiyun 	int new_page_count __maybe_unused;
1415*4882a593Smuzhiyun 	size_t old_page_count = alloc->nents;
1416*4882a593Smuzhiyun 
1417*4882a593Smuzhiyun 	KBASE_DEBUG_ASSERT(alloc->type == KBASE_MEM_TYPE_NATIVE);
1418*4882a593Smuzhiyun 	KBASE_DEBUG_ASSERT(alloc->imported.kctx);
1419*4882a593Smuzhiyun 
1420*4882a593Smuzhiyun 	if (nr_pages_requested == 0)
1421*4882a593Smuzhiyun 		goto done; /*nothing to do*/
1422*4882a593Smuzhiyun 
1423*4882a593Smuzhiyun 	new_page_count = kbase_atomic_add_pages(
1424*4882a593Smuzhiyun 			nr_pages_requested, &alloc->imported.kctx->used_pages);
1425*4882a593Smuzhiyun 	kbase_atomic_add_pages(nr_pages_requested, &alloc->imported.kctx->kbdev->memdev.used_pages);
1426*4882a593Smuzhiyun 
1427*4882a593Smuzhiyun 	/* Increase mm counters before we allocate pages so that this
1428*4882a593Smuzhiyun 	 * allocation is visible to the OOM killer */
1429*4882a593Smuzhiyun 	kbase_process_page_usage_inc(alloc->imported.kctx, nr_pages_requested);
1430*4882a593Smuzhiyun 
1431*4882a593Smuzhiyun 	if (kbase_mem_pool_alloc_pages(&alloc->imported.kctx->mem_pool,
1432*4882a593Smuzhiyun 			nr_pages_requested, alloc->pages + old_page_count) != 0)
1433*4882a593Smuzhiyun 		goto no_alloc;
1434*4882a593Smuzhiyun 
1435*4882a593Smuzhiyun 	KBASE_TLSTREAM_AUX_PAGESALLOC(
1436*4882a593Smuzhiyun 			(u32)alloc->imported.kctx->id,
1437*4882a593Smuzhiyun 			(u64)new_page_count);
1438*4882a593Smuzhiyun 
1439*4882a593Smuzhiyun 	alloc->nents += nr_pages_requested;
1440*4882a593Smuzhiyun done:
1441*4882a593Smuzhiyun 	return 0;
1442*4882a593Smuzhiyun 
1443*4882a593Smuzhiyun no_alloc:
1444*4882a593Smuzhiyun 	kbase_process_page_usage_dec(alloc->imported.kctx, nr_pages_requested);
1445*4882a593Smuzhiyun 	kbase_atomic_sub_pages(nr_pages_requested, &alloc->imported.kctx->used_pages);
1446*4882a593Smuzhiyun 	kbase_atomic_sub_pages(nr_pages_requested, &alloc->imported.kctx->kbdev->memdev.used_pages);
1447*4882a593Smuzhiyun 
1448*4882a593Smuzhiyun 	return -ENOMEM;
1449*4882a593Smuzhiyun }
1450*4882a593Smuzhiyun 
kbase_free_phy_pages_helper(struct kbase_mem_phy_alloc * alloc,size_t nr_pages_to_free)1451*4882a593Smuzhiyun int kbase_free_phy_pages_helper(
1452*4882a593Smuzhiyun 	struct kbase_mem_phy_alloc *alloc,
1453*4882a593Smuzhiyun 	size_t nr_pages_to_free)
1454*4882a593Smuzhiyun {
1455*4882a593Smuzhiyun 	struct kbase_context *kctx = alloc->imported.kctx;
1456*4882a593Smuzhiyun 	bool syncback;
1457*4882a593Smuzhiyun 	bool reclaimed = (alloc->evicted != 0);
1458*4882a593Smuzhiyun 	phys_addr_t *start_free;
1459*4882a593Smuzhiyun 	int new_page_count __maybe_unused;
1460*4882a593Smuzhiyun 
1461*4882a593Smuzhiyun 	KBASE_DEBUG_ASSERT(alloc->type == KBASE_MEM_TYPE_NATIVE);
1462*4882a593Smuzhiyun 	KBASE_DEBUG_ASSERT(alloc->imported.kctx);
1463*4882a593Smuzhiyun 	KBASE_DEBUG_ASSERT(alloc->nents >= nr_pages_to_free);
1464*4882a593Smuzhiyun 
1465*4882a593Smuzhiyun 	/* early out if nothing to do */
1466*4882a593Smuzhiyun 	if (0 == nr_pages_to_free)
1467*4882a593Smuzhiyun 		return 0;
1468*4882a593Smuzhiyun 
1469*4882a593Smuzhiyun 	start_free = alloc->pages + alloc->nents - nr_pages_to_free;
1470*4882a593Smuzhiyun 
1471*4882a593Smuzhiyun 	syncback = alloc->properties & KBASE_MEM_PHY_ALLOC_ACCESSED_CACHED;
1472*4882a593Smuzhiyun 
1473*4882a593Smuzhiyun 	kbase_mem_pool_free_pages(&kctx->mem_pool,
1474*4882a593Smuzhiyun 				  nr_pages_to_free,
1475*4882a593Smuzhiyun 				  start_free,
1476*4882a593Smuzhiyun 				  syncback,
1477*4882a593Smuzhiyun 				  reclaimed);
1478*4882a593Smuzhiyun 
1479*4882a593Smuzhiyun 	alloc->nents -= nr_pages_to_free;
1480*4882a593Smuzhiyun 
1481*4882a593Smuzhiyun 	/*
1482*4882a593Smuzhiyun 	 * If the allocation was not evicted (i.e. evicted == 0) then
1483*4882a593Smuzhiyun 	 * the page accounting needs to be done.
1484*4882a593Smuzhiyun 	 */
1485*4882a593Smuzhiyun 	if (!reclaimed) {
1486*4882a593Smuzhiyun 		kbase_process_page_usage_dec(kctx, nr_pages_to_free);
1487*4882a593Smuzhiyun 		new_page_count = kbase_atomic_sub_pages(nr_pages_to_free,
1488*4882a593Smuzhiyun 							&kctx->used_pages);
1489*4882a593Smuzhiyun 		kbase_atomic_sub_pages(nr_pages_to_free,
1490*4882a593Smuzhiyun 				       &kctx->kbdev->memdev.used_pages);
1491*4882a593Smuzhiyun 
1492*4882a593Smuzhiyun 		KBASE_TLSTREAM_AUX_PAGESALLOC(
1493*4882a593Smuzhiyun 				(u32)kctx->id,
1494*4882a593Smuzhiyun 				(u64)new_page_count);
1495*4882a593Smuzhiyun 	}
1496*4882a593Smuzhiyun 
1497*4882a593Smuzhiyun 	return 0;
1498*4882a593Smuzhiyun }
1499*4882a593Smuzhiyun 
kbase_mem_kref_free(struct kref * kref)1500*4882a593Smuzhiyun void kbase_mem_kref_free(struct kref *kref)
1501*4882a593Smuzhiyun {
1502*4882a593Smuzhiyun 	struct kbase_mem_phy_alloc *alloc;
1503*4882a593Smuzhiyun 
1504*4882a593Smuzhiyun 	alloc = container_of(kref, struct kbase_mem_phy_alloc, kref);
1505*4882a593Smuzhiyun 
1506*4882a593Smuzhiyun 	switch (alloc->type) {
1507*4882a593Smuzhiyun 	case KBASE_MEM_TYPE_NATIVE: {
1508*4882a593Smuzhiyun 		WARN_ON(!alloc->imported.kctx);
1509*4882a593Smuzhiyun 		/*
1510*4882a593Smuzhiyun 		 * The physical allocation must have been removed from the
1511*4882a593Smuzhiyun 		 * eviction list before trying to free it.
1512*4882a593Smuzhiyun 		 */
1513*4882a593Smuzhiyun 		WARN_ON(!list_empty(&alloc->evict_node));
1514*4882a593Smuzhiyun 		kbase_free_phy_pages_helper(alloc, alloc->nents);
1515*4882a593Smuzhiyun 		break;
1516*4882a593Smuzhiyun 	}
1517*4882a593Smuzhiyun 	case KBASE_MEM_TYPE_ALIAS: {
1518*4882a593Smuzhiyun 		/* just call put on the underlying phy allocs */
1519*4882a593Smuzhiyun 		size_t i;
1520*4882a593Smuzhiyun 		struct kbase_aliased *aliased;
1521*4882a593Smuzhiyun 
1522*4882a593Smuzhiyun 		aliased = alloc->imported.alias.aliased;
1523*4882a593Smuzhiyun 		if (aliased) {
1524*4882a593Smuzhiyun 			for (i = 0; i < alloc->imported.alias.nents; i++)
1525*4882a593Smuzhiyun 				if (aliased[i].alloc)
1526*4882a593Smuzhiyun 					kbase_mem_phy_alloc_put(aliased[i].alloc);
1527*4882a593Smuzhiyun 			vfree(aliased);
1528*4882a593Smuzhiyun 		}
1529*4882a593Smuzhiyun 		break;
1530*4882a593Smuzhiyun 	}
1531*4882a593Smuzhiyun 	case KBASE_MEM_TYPE_RAW:
1532*4882a593Smuzhiyun 		/* raw pages, external cleanup */
1533*4882a593Smuzhiyun 		break;
1534*4882a593Smuzhiyun  #ifdef CONFIG_UMP
1535*4882a593Smuzhiyun 	case KBASE_MEM_TYPE_IMPORTED_UMP:
1536*4882a593Smuzhiyun 		ump_dd_release(alloc->imported.ump_handle);
1537*4882a593Smuzhiyun 		break;
1538*4882a593Smuzhiyun #endif
1539*4882a593Smuzhiyun #ifdef CONFIG_DMA_SHARED_BUFFER
1540*4882a593Smuzhiyun 	case KBASE_MEM_TYPE_IMPORTED_UMM:
1541*4882a593Smuzhiyun 		dma_buf_detach(alloc->imported.umm.dma_buf,
1542*4882a593Smuzhiyun 			       alloc->imported.umm.dma_attachment);
1543*4882a593Smuzhiyun 		dma_buf_put(alloc->imported.umm.dma_buf);
1544*4882a593Smuzhiyun 		break;
1545*4882a593Smuzhiyun #endif
1546*4882a593Smuzhiyun 	case KBASE_MEM_TYPE_IMPORTED_USER_BUF:
1547*4882a593Smuzhiyun 		if (alloc->imported.user_buf.mm)
1548*4882a593Smuzhiyun 			mmdrop(alloc->imported.user_buf.mm);
1549*4882a593Smuzhiyun 		kfree(alloc->imported.user_buf.pages);
1550*4882a593Smuzhiyun 		break;
1551*4882a593Smuzhiyun 	case KBASE_MEM_TYPE_TB:{
1552*4882a593Smuzhiyun 		void *tb;
1553*4882a593Smuzhiyun 
1554*4882a593Smuzhiyun 		tb = alloc->imported.kctx->jctx.tb;
1555*4882a593Smuzhiyun 		kbase_device_trace_buffer_uninstall(alloc->imported.kctx);
1556*4882a593Smuzhiyun 		vfree(tb);
1557*4882a593Smuzhiyun 		break;
1558*4882a593Smuzhiyun 	}
1559*4882a593Smuzhiyun 	default:
1560*4882a593Smuzhiyun 		WARN(1, "Unexecpted free of type %d\n", alloc->type);
1561*4882a593Smuzhiyun 		break;
1562*4882a593Smuzhiyun 	}
1563*4882a593Smuzhiyun 
1564*4882a593Smuzhiyun 	/* Free based on allocation type */
1565*4882a593Smuzhiyun 	if (alloc->properties & KBASE_MEM_PHY_ALLOC_LARGE)
1566*4882a593Smuzhiyun 		vfree(alloc);
1567*4882a593Smuzhiyun 	else
1568*4882a593Smuzhiyun 		kfree(alloc);
1569*4882a593Smuzhiyun }
1570*4882a593Smuzhiyun 
1571*4882a593Smuzhiyun KBASE_EXPORT_TEST_API(kbase_mem_kref_free);
1572*4882a593Smuzhiyun 
kbase_alloc_phy_pages(struct kbase_va_region * reg,size_t vsize,size_t size)1573*4882a593Smuzhiyun int kbase_alloc_phy_pages(struct kbase_va_region *reg, size_t vsize, size_t size)
1574*4882a593Smuzhiyun {
1575*4882a593Smuzhiyun 	KBASE_DEBUG_ASSERT(NULL != reg);
1576*4882a593Smuzhiyun 	KBASE_DEBUG_ASSERT(vsize > 0);
1577*4882a593Smuzhiyun 
1578*4882a593Smuzhiyun 	/* validate user provided arguments */
1579*4882a593Smuzhiyun 	if (size > vsize || vsize > reg->nr_pages)
1580*4882a593Smuzhiyun 		goto out_term;
1581*4882a593Smuzhiyun 
1582*4882a593Smuzhiyun 	/* Prevent vsize*sizeof from wrapping around.
1583*4882a593Smuzhiyun 	 * For instance, if vsize is 2**29+1, we'll allocate 1 byte and the alloc won't fail.
1584*4882a593Smuzhiyun 	 */
1585*4882a593Smuzhiyun 	if ((size_t) vsize > ((size_t) -1 / sizeof(*reg->cpu_alloc->pages)))
1586*4882a593Smuzhiyun 		goto out_term;
1587*4882a593Smuzhiyun 
1588*4882a593Smuzhiyun 	KBASE_DEBUG_ASSERT(0 != vsize);
1589*4882a593Smuzhiyun 
1590*4882a593Smuzhiyun 	if (kbase_alloc_phy_pages_helper(reg->cpu_alloc, size) != 0)
1591*4882a593Smuzhiyun 		goto out_term;
1592*4882a593Smuzhiyun 
1593*4882a593Smuzhiyun 	reg->cpu_alloc->reg = reg;
1594*4882a593Smuzhiyun 	if (reg->cpu_alloc != reg->gpu_alloc) {
1595*4882a593Smuzhiyun 		if (kbase_alloc_phy_pages_helper(reg->gpu_alloc, size) != 0)
1596*4882a593Smuzhiyun 			goto out_rollback;
1597*4882a593Smuzhiyun 		reg->gpu_alloc->reg = reg;
1598*4882a593Smuzhiyun 	}
1599*4882a593Smuzhiyun 
1600*4882a593Smuzhiyun 	return 0;
1601*4882a593Smuzhiyun 
1602*4882a593Smuzhiyun out_rollback:
1603*4882a593Smuzhiyun 	kbase_free_phy_pages_helper(reg->cpu_alloc, size);
1604*4882a593Smuzhiyun out_term:
1605*4882a593Smuzhiyun 	return -1;
1606*4882a593Smuzhiyun }
1607*4882a593Smuzhiyun 
1608*4882a593Smuzhiyun KBASE_EXPORT_TEST_API(kbase_alloc_phy_pages);
1609*4882a593Smuzhiyun 
kbase_check_alloc_flags(unsigned long flags)1610*4882a593Smuzhiyun bool kbase_check_alloc_flags(unsigned long flags)
1611*4882a593Smuzhiyun {
1612*4882a593Smuzhiyun 	/* Only known input flags should be set. */
1613*4882a593Smuzhiyun 	if (flags & ~BASE_MEM_FLAGS_INPUT_MASK)
1614*4882a593Smuzhiyun 		return false;
1615*4882a593Smuzhiyun 
1616*4882a593Smuzhiyun 	/* At least one flag should be set */
1617*4882a593Smuzhiyun 	if (flags == 0)
1618*4882a593Smuzhiyun 		return false;
1619*4882a593Smuzhiyun 
1620*4882a593Smuzhiyun 	/* Either the GPU or CPU must be reading from the allocated memory */
1621*4882a593Smuzhiyun 	if ((flags & (BASE_MEM_PROT_CPU_RD | BASE_MEM_PROT_GPU_RD)) == 0)
1622*4882a593Smuzhiyun 		return false;
1623*4882a593Smuzhiyun 
1624*4882a593Smuzhiyun 	/* Either the GPU or CPU must be writing to the allocated memory */
1625*4882a593Smuzhiyun 	if ((flags & (BASE_MEM_PROT_CPU_WR | BASE_MEM_PROT_GPU_WR)) == 0)
1626*4882a593Smuzhiyun 		return false;
1627*4882a593Smuzhiyun 
1628*4882a593Smuzhiyun 	/* GPU cannot be writing to GPU executable memory and cannot grow the memory on page fault. */
1629*4882a593Smuzhiyun 	if ((flags & BASE_MEM_PROT_GPU_EX) && (flags & (BASE_MEM_PROT_GPU_WR | BASE_MEM_GROW_ON_GPF)))
1630*4882a593Smuzhiyun 		return false;
1631*4882a593Smuzhiyun 
1632*4882a593Smuzhiyun 	/* GPU should have at least read or write access otherwise there is no
1633*4882a593Smuzhiyun 	   reason for allocating. */
1634*4882a593Smuzhiyun 	if ((flags & (BASE_MEM_PROT_GPU_RD | BASE_MEM_PROT_GPU_WR)) == 0)
1635*4882a593Smuzhiyun 		return false;
1636*4882a593Smuzhiyun 
1637*4882a593Smuzhiyun 	/* BASE_MEM_IMPORT_SHARED is only valid for imported memory */
1638*4882a593Smuzhiyun 	if ((flags & BASE_MEM_IMPORT_SHARED) == BASE_MEM_IMPORT_SHARED)
1639*4882a593Smuzhiyun 		return false;
1640*4882a593Smuzhiyun 
1641*4882a593Smuzhiyun 	return true;
1642*4882a593Smuzhiyun }
1643*4882a593Smuzhiyun 
kbase_check_import_flags(unsigned long flags)1644*4882a593Smuzhiyun bool kbase_check_import_flags(unsigned long flags)
1645*4882a593Smuzhiyun {
1646*4882a593Smuzhiyun 	/* Only known input flags should be set. */
1647*4882a593Smuzhiyun 	if (flags & ~BASE_MEM_FLAGS_INPUT_MASK)
1648*4882a593Smuzhiyun 		return false;
1649*4882a593Smuzhiyun 
1650*4882a593Smuzhiyun 	/* At least one flag should be set */
1651*4882a593Smuzhiyun 	if (flags == 0)
1652*4882a593Smuzhiyun 		return false;
1653*4882a593Smuzhiyun 
1654*4882a593Smuzhiyun 	/* Imported memory cannot be GPU executable */
1655*4882a593Smuzhiyun 	if (flags & BASE_MEM_PROT_GPU_EX)
1656*4882a593Smuzhiyun 		return false;
1657*4882a593Smuzhiyun 
1658*4882a593Smuzhiyun 	/* Imported memory cannot grow on page fault */
1659*4882a593Smuzhiyun 	if (flags & BASE_MEM_GROW_ON_GPF)
1660*4882a593Smuzhiyun 		return false;
1661*4882a593Smuzhiyun 
1662*4882a593Smuzhiyun 	/* GPU should have at least read or write access otherwise there is no
1663*4882a593Smuzhiyun 	   reason for importing. */
1664*4882a593Smuzhiyun 	if ((flags & (BASE_MEM_PROT_GPU_RD | BASE_MEM_PROT_GPU_WR)) == 0)
1665*4882a593Smuzhiyun 		return false;
1666*4882a593Smuzhiyun 
1667*4882a593Smuzhiyun 	/* Secure memory cannot be read by the CPU */
1668*4882a593Smuzhiyun 	if ((flags & BASE_MEM_SECURE) && (flags & BASE_MEM_PROT_CPU_RD))
1669*4882a593Smuzhiyun 		return false;
1670*4882a593Smuzhiyun 
1671*4882a593Smuzhiyun 	return true;
1672*4882a593Smuzhiyun }
1673*4882a593Smuzhiyun 
1674*4882a593Smuzhiyun /**
1675*4882a593Smuzhiyun  * @brief Acquire the per-context region list lock
1676*4882a593Smuzhiyun  */
kbase_gpu_vm_lock(struct kbase_context * kctx)1677*4882a593Smuzhiyun void kbase_gpu_vm_lock(struct kbase_context *kctx)
1678*4882a593Smuzhiyun {
1679*4882a593Smuzhiyun 	KBASE_DEBUG_ASSERT(kctx != NULL);
1680*4882a593Smuzhiyun 	mutex_lock(&kctx->reg_lock);
1681*4882a593Smuzhiyun }
1682*4882a593Smuzhiyun 
1683*4882a593Smuzhiyun KBASE_EXPORT_TEST_API(kbase_gpu_vm_lock);
1684*4882a593Smuzhiyun 
1685*4882a593Smuzhiyun /**
1686*4882a593Smuzhiyun  * @brief Release the per-context region list lock
1687*4882a593Smuzhiyun  */
kbase_gpu_vm_unlock(struct kbase_context * kctx)1688*4882a593Smuzhiyun void kbase_gpu_vm_unlock(struct kbase_context *kctx)
1689*4882a593Smuzhiyun {
1690*4882a593Smuzhiyun 	KBASE_DEBUG_ASSERT(kctx != NULL);
1691*4882a593Smuzhiyun 	mutex_unlock(&kctx->reg_lock);
1692*4882a593Smuzhiyun }
1693*4882a593Smuzhiyun 
1694*4882a593Smuzhiyun KBASE_EXPORT_TEST_API(kbase_gpu_vm_unlock);
1695*4882a593Smuzhiyun 
1696*4882a593Smuzhiyun #ifdef CONFIG_DEBUG_FS
1697*4882a593Smuzhiyun struct kbase_jit_debugfs_data {
1698*4882a593Smuzhiyun 	int (*func)(struct kbase_jit_debugfs_data *);
1699*4882a593Smuzhiyun 	struct mutex lock;
1700*4882a593Smuzhiyun 	struct kbase_context *kctx;
1701*4882a593Smuzhiyun 	u64 active_value;
1702*4882a593Smuzhiyun 	u64 pool_value;
1703*4882a593Smuzhiyun 	u64 destroy_value;
1704*4882a593Smuzhiyun 	char buffer[50];
1705*4882a593Smuzhiyun };
1706*4882a593Smuzhiyun 
kbase_jit_debugfs_common_open(struct inode * inode,struct file * file,int (* func)(struct kbase_jit_debugfs_data *))1707*4882a593Smuzhiyun static int kbase_jit_debugfs_common_open(struct inode *inode,
1708*4882a593Smuzhiyun 		struct file *file, int (*func)(struct kbase_jit_debugfs_data *))
1709*4882a593Smuzhiyun {
1710*4882a593Smuzhiyun 	struct kbase_jit_debugfs_data *data;
1711*4882a593Smuzhiyun 
1712*4882a593Smuzhiyun 	data = kzalloc(sizeof(*data), GFP_KERNEL);
1713*4882a593Smuzhiyun 	if (!data)
1714*4882a593Smuzhiyun 		return -ENOMEM;
1715*4882a593Smuzhiyun 
1716*4882a593Smuzhiyun 	data->func = func;
1717*4882a593Smuzhiyun 	mutex_init(&data->lock);
1718*4882a593Smuzhiyun 	data->kctx = (struct kbase_context *) inode->i_private;
1719*4882a593Smuzhiyun 
1720*4882a593Smuzhiyun 	file->private_data = data;
1721*4882a593Smuzhiyun 
1722*4882a593Smuzhiyun 	return nonseekable_open(inode, file);
1723*4882a593Smuzhiyun }
1724*4882a593Smuzhiyun 
kbase_jit_debugfs_common_read(struct file * file,char __user * buf,size_t len,loff_t * ppos)1725*4882a593Smuzhiyun static ssize_t kbase_jit_debugfs_common_read(struct file *file,
1726*4882a593Smuzhiyun 		char __user *buf, size_t len, loff_t *ppos)
1727*4882a593Smuzhiyun {
1728*4882a593Smuzhiyun 	struct kbase_jit_debugfs_data *data;
1729*4882a593Smuzhiyun 	size_t size;
1730*4882a593Smuzhiyun 	int ret;
1731*4882a593Smuzhiyun 
1732*4882a593Smuzhiyun 	data = (struct kbase_jit_debugfs_data *) file->private_data;
1733*4882a593Smuzhiyun 	mutex_lock(&data->lock);
1734*4882a593Smuzhiyun 
1735*4882a593Smuzhiyun 	if (*ppos) {
1736*4882a593Smuzhiyun 		size = strnlen(data->buffer, sizeof(data->buffer));
1737*4882a593Smuzhiyun 	} else {
1738*4882a593Smuzhiyun 		if (!data->func) {
1739*4882a593Smuzhiyun 			ret = -EACCES;
1740*4882a593Smuzhiyun 			goto out_unlock;
1741*4882a593Smuzhiyun 		}
1742*4882a593Smuzhiyun 
1743*4882a593Smuzhiyun 		if (data->func(data)) {
1744*4882a593Smuzhiyun 			ret = -EACCES;
1745*4882a593Smuzhiyun 			goto out_unlock;
1746*4882a593Smuzhiyun 		}
1747*4882a593Smuzhiyun 
1748*4882a593Smuzhiyun 		size = scnprintf(data->buffer, sizeof(data->buffer),
1749*4882a593Smuzhiyun 				"%llu,%llu,%llu", data->active_value,
1750*4882a593Smuzhiyun 				data->pool_value, data->destroy_value);
1751*4882a593Smuzhiyun 	}
1752*4882a593Smuzhiyun 
1753*4882a593Smuzhiyun 	ret = simple_read_from_buffer(buf, len, ppos, data->buffer, size);
1754*4882a593Smuzhiyun 
1755*4882a593Smuzhiyun out_unlock:
1756*4882a593Smuzhiyun 	mutex_unlock(&data->lock);
1757*4882a593Smuzhiyun 	return ret;
1758*4882a593Smuzhiyun }
1759*4882a593Smuzhiyun 
kbase_jit_debugfs_common_release(struct inode * inode,struct file * file)1760*4882a593Smuzhiyun static int kbase_jit_debugfs_common_release(struct inode *inode,
1761*4882a593Smuzhiyun 		struct file *file)
1762*4882a593Smuzhiyun {
1763*4882a593Smuzhiyun 	kfree(file->private_data);
1764*4882a593Smuzhiyun 	return 0;
1765*4882a593Smuzhiyun }
1766*4882a593Smuzhiyun 
1767*4882a593Smuzhiyun #define KBASE_JIT_DEBUGFS_DECLARE(__fops, __func) \
1768*4882a593Smuzhiyun static int __fops ## _open(struct inode *inode, struct file *file) \
1769*4882a593Smuzhiyun { \
1770*4882a593Smuzhiyun 	return kbase_jit_debugfs_common_open(inode, file, __func); \
1771*4882a593Smuzhiyun } \
1772*4882a593Smuzhiyun static const struct file_operations __fops = { \
1773*4882a593Smuzhiyun 	.owner = THIS_MODULE, \
1774*4882a593Smuzhiyun 	.open = __fops ## _open, \
1775*4882a593Smuzhiyun 	.release = kbase_jit_debugfs_common_release, \
1776*4882a593Smuzhiyun 	.read = kbase_jit_debugfs_common_read, \
1777*4882a593Smuzhiyun 	.write = NULL, \
1778*4882a593Smuzhiyun 	.llseek = generic_file_llseek, \
1779*4882a593Smuzhiyun }
1780*4882a593Smuzhiyun 
kbase_jit_debugfs_count_get(struct kbase_jit_debugfs_data * data)1781*4882a593Smuzhiyun static int kbase_jit_debugfs_count_get(struct kbase_jit_debugfs_data *data)
1782*4882a593Smuzhiyun {
1783*4882a593Smuzhiyun 	struct kbase_context *kctx = data->kctx;
1784*4882a593Smuzhiyun 	struct list_head *tmp;
1785*4882a593Smuzhiyun 
1786*4882a593Smuzhiyun 	mutex_lock(&kctx->jit_evict_lock);
1787*4882a593Smuzhiyun 	list_for_each(tmp, &kctx->jit_active_head) {
1788*4882a593Smuzhiyun 		data->active_value++;
1789*4882a593Smuzhiyun 	}
1790*4882a593Smuzhiyun 
1791*4882a593Smuzhiyun 	list_for_each(tmp, &kctx->jit_pool_head) {
1792*4882a593Smuzhiyun 		data->pool_value++;
1793*4882a593Smuzhiyun 	}
1794*4882a593Smuzhiyun 
1795*4882a593Smuzhiyun 	list_for_each(tmp, &kctx->jit_destroy_head) {
1796*4882a593Smuzhiyun 		data->destroy_value++;
1797*4882a593Smuzhiyun 	}
1798*4882a593Smuzhiyun 	mutex_unlock(&kctx->jit_evict_lock);
1799*4882a593Smuzhiyun 
1800*4882a593Smuzhiyun 	return 0;
1801*4882a593Smuzhiyun }
1802*4882a593Smuzhiyun KBASE_JIT_DEBUGFS_DECLARE(kbase_jit_debugfs_count_fops,
1803*4882a593Smuzhiyun 		kbase_jit_debugfs_count_get);
1804*4882a593Smuzhiyun 
kbase_jit_debugfs_vm_get(struct kbase_jit_debugfs_data * data)1805*4882a593Smuzhiyun static int kbase_jit_debugfs_vm_get(struct kbase_jit_debugfs_data *data)
1806*4882a593Smuzhiyun {
1807*4882a593Smuzhiyun 	struct kbase_context *kctx = data->kctx;
1808*4882a593Smuzhiyun 	struct kbase_va_region *reg;
1809*4882a593Smuzhiyun 
1810*4882a593Smuzhiyun 	mutex_lock(&kctx->jit_evict_lock);
1811*4882a593Smuzhiyun 	list_for_each_entry(reg, &kctx->jit_active_head, jit_node) {
1812*4882a593Smuzhiyun 		data->active_value += reg->nr_pages;
1813*4882a593Smuzhiyun 	}
1814*4882a593Smuzhiyun 
1815*4882a593Smuzhiyun 	list_for_each_entry(reg, &kctx->jit_pool_head, jit_node) {
1816*4882a593Smuzhiyun 		data->pool_value += reg->nr_pages;
1817*4882a593Smuzhiyun 	}
1818*4882a593Smuzhiyun 
1819*4882a593Smuzhiyun 	list_for_each_entry(reg, &kctx->jit_destroy_head, jit_node) {
1820*4882a593Smuzhiyun 		data->destroy_value += reg->nr_pages;
1821*4882a593Smuzhiyun 	}
1822*4882a593Smuzhiyun 	mutex_unlock(&kctx->jit_evict_lock);
1823*4882a593Smuzhiyun 
1824*4882a593Smuzhiyun 	return 0;
1825*4882a593Smuzhiyun }
1826*4882a593Smuzhiyun KBASE_JIT_DEBUGFS_DECLARE(kbase_jit_debugfs_vm_fops,
1827*4882a593Smuzhiyun 		kbase_jit_debugfs_vm_get);
1828*4882a593Smuzhiyun 
kbase_jit_debugfs_phys_get(struct kbase_jit_debugfs_data * data)1829*4882a593Smuzhiyun static int kbase_jit_debugfs_phys_get(struct kbase_jit_debugfs_data *data)
1830*4882a593Smuzhiyun {
1831*4882a593Smuzhiyun 	struct kbase_context *kctx = data->kctx;
1832*4882a593Smuzhiyun 	struct kbase_va_region *reg;
1833*4882a593Smuzhiyun 
1834*4882a593Smuzhiyun 	mutex_lock(&kctx->jit_evict_lock);
1835*4882a593Smuzhiyun 	list_for_each_entry(reg, &kctx->jit_active_head, jit_node) {
1836*4882a593Smuzhiyun 		data->active_value += reg->gpu_alloc->nents;
1837*4882a593Smuzhiyun 	}
1838*4882a593Smuzhiyun 
1839*4882a593Smuzhiyun 	list_for_each_entry(reg, &kctx->jit_pool_head, jit_node) {
1840*4882a593Smuzhiyun 		data->pool_value += reg->gpu_alloc->nents;
1841*4882a593Smuzhiyun 	}
1842*4882a593Smuzhiyun 
1843*4882a593Smuzhiyun 	list_for_each_entry(reg, &kctx->jit_destroy_head, jit_node) {
1844*4882a593Smuzhiyun 		data->destroy_value += reg->gpu_alloc->nents;
1845*4882a593Smuzhiyun 	}
1846*4882a593Smuzhiyun 	mutex_unlock(&kctx->jit_evict_lock);
1847*4882a593Smuzhiyun 
1848*4882a593Smuzhiyun 	return 0;
1849*4882a593Smuzhiyun }
1850*4882a593Smuzhiyun KBASE_JIT_DEBUGFS_DECLARE(kbase_jit_debugfs_phys_fops,
1851*4882a593Smuzhiyun 		kbase_jit_debugfs_phys_get);
1852*4882a593Smuzhiyun 
kbase_jit_debugfs_init(struct kbase_context * kctx)1853*4882a593Smuzhiyun void kbase_jit_debugfs_init(struct kbase_context *kctx)
1854*4882a593Smuzhiyun {
1855*4882a593Smuzhiyun 	/* Debugfs entry for getting the number of JIT allocations. */
1856*4882a593Smuzhiyun 	debugfs_create_file("mem_jit_count", S_IRUGO, kctx->kctx_dentry,
1857*4882a593Smuzhiyun 			kctx, &kbase_jit_debugfs_count_fops);
1858*4882a593Smuzhiyun 
1859*4882a593Smuzhiyun 	/*
1860*4882a593Smuzhiyun 	 * Debugfs entry for getting the total number of virtual pages
1861*4882a593Smuzhiyun 	 * used by JIT allocations.
1862*4882a593Smuzhiyun 	 */
1863*4882a593Smuzhiyun 	debugfs_create_file("mem_jit_vm", S_IRUGO, kctx->kctx_dentry,
1864*4882a593Smuzhiyun 			kctx, &kbase_jit_debugfs_vm_fops);
1865*4882a593Smuzhiyun 
1866*4882a593Smuzhiyun 	/*
1867*4882a593Smuzhiyun 	 * Debugfs entry for getting the number of physical pages used
1868*4882a593Smuzhiyun 	 * by JIT allocations.
1869*4882a593Smuzhiyun 	 */
1870*4882a593Smuzhiyun 	debugfs_create_file("mem_jit_phys", S_IRUGO, kctx->kctx_dentry,
1871*4882a593Smuzhiyun 			kctx, &kbase_jit_debugfs_phys_fops);
1872*4882a593Smuzhiyun }
1873*4882a593Smuzhiyun #endif /* CONFIG_DEBUG_FS */
1874*4882a593Smuzhiyun 
1875*4882a593Smuzhiyun /**
1876*4882a593Smuzhiyun  * kbase_jit_destroy_worker - Deferred worker which frees JIT allocations
1877*4882a593Smuzhiyun  * @work: Work item
1878*4882a593Smuzhiyun  *
1879*4882a593Smuzhiyun  * This function does the work of freeing JIT allocations whose physical
1880*4882a593Smuzhiyun  * backing has been released.
1881*4882a593Smuzhiyun  */
kbase_jit_destroy_worker(struct work_struct * work)1882*4882a593Smuzhiyun static void kbase_jit_destroy_worker(struct work_struct *work)
1883*4882a593Smuzhiyun {
1884*4882a593Smuzhiyun 	struct kbase_context *kctx;
1885*4882a593Smuzhiyun 	struct kbase_va_region *reg;
1886*4882a593Smuzhiyun 
1887*4882a593Smuzhiyun 	kctx = container_of(work, struct kbase_context, jit_work);
1888*4882a593Smuzhiyun 	do {
1889*4882a593Smuzhiyun 		mutex_lock(&kctx->jit_evict_lock);
1890*4882a593Smuzhiyun 		if (list_empty(&kctx->jit_destroy_head)) {
1891*4882a593Smuzhiyun 			mutex_unlock(&kctx->jit_evict_lock);
1892*4882a593Smuzhiyun 			break;
1893*4882a593Smuzhiyun 		}
1894*4882a593Smuzhiyun 
1895*4882a593Smuzhiyun 		reg = list_first_entry(&kctx->jit_destroy_head,
1896*4882a593Smuzhiyun 				struct kbase_va_region, jit_node);
1897*4882a593Smuzhiyun 
1898*4882a593Smuzhiyun 		list_del(&reg->jit_node);
1899*4882a593Smuzhiyun 		mutex_unlock(&kctx->jit_evict_lock);
1900*4882a593Smuzhiyun 
1901*4882a593Smuzhiyun 		kbase_gpu_vm_lock(kctx);
1902*4882a593Smuzhiyun 		kbase_mem_free_region(kctx, reg);
1903*4882a593Smuzhiyun 		kbase_gpu_vm_unlock(kctx);
1904*4882a593Smuzhiyun 	} while (1);
1905*4882a593Smuzhiyun }
1906*4882a593Smuzhiyun 
kbase_jit_init(struct kbase_context * kctx)1907*4882a593Smuzhiyun int kbase_jit_init(struct kbase_context *kctx)
1908*4882a593Smuzhiyun {
1909*4882a593Smuzhiyun 	INIT_LIST_HEAD(&kctx->jit_active_head);
1910*4882a593Smuzhiyun 	INIT_LIST_HEAD(&kctx->jit_pool_head);
1911*4882a593Smuzhiyun 	INIT_LIST_HEAD(&kctx->jit_destroy_head);
1912*4882a593Smuzhiyun 	INIT_WORK(&kctx->jit_work, kbase_jit_destroy_worker);
1913*4882a593Smuzhiyun 
1914*4882a593Smuzhiyun 	INIT_LIST_HEAD(&kctx->jit_pending_alloc);
1915*4882a593Smuzhiyun 	INIT_LIST_HEAD(&kctx->jit_atoms_head);
1916*4882a593Smuzhiyun 
1917*4882a593Smuzhiyun 	return 0;
1918*4882a593Smuzhiyun }
1919*4882a593Smuzhiyun 
kbase_jit_allocate(struct kbase_context * kctx,struct base_jit_alloc_info * info)1920*4882a593Smuzhiyun struct kbase_va_region *kbase_jit_allocate(struct kbase_context *kctx,
1921*4882a593Smuzhiyun 		struct base_jit_alloc_info *info)
1922*4882a593Smuzhiyun {
1923*4882a593Smuzhiyun 	struct kbase_va_region *reg = NULL;
1924*4882a593Smuzhiyun 	struct kbase_va_region *walker;
1925*4882a593Smuzhiyun 	struct kbase_va_region *temp;
1926*4882a593Smuzhiyun 	size_t current_diff = SIZE_MAX;
1927*4882a593Smuzhiyun 
1928*4882a593Smuzhiyun 	int ret;
1929*4882a593Smuzhiyun 
1930*4882a593Smuzhiyun 	mutex_lock(&kctx->jit_evict_lock);
1931*4882a593Smuzhiyun 	/*
1932*4882a593Smuzhiyun 	 * Scan the pool for an existing allocation which meets our
1933*4882a593Smuzhiyun 	 * requirements and remove it.
1934*4882a593Smuzhiyun 	 */
1935*4882a593Smuzhiyun 	list_for_each_entry_safe(walker, temp, &kctx->jit_pool_head, jit_node) {
1936*4882a593Smuzhiyun 
1937*4882a593Smuzhiyun 		if (walker->nr_pages >= info->va_pages) {
1938*4882a593Smuzhiyun 			size_t min_size, max_size, diff;
1939*4882a593Smuzhiyun 
1940*4882a593Smuzhiyun 			/*
1941*4882a593Smuzhiyun 			 * The JIT allocations VA requirements have been
1942*4882a593Smuzhiyun 			 * meet, it's suitable but other allocations
1943*4882a593Smuzhiyun 			 * might be a better fit.
1944*4882a593Smuzhiyun 			 */
1945*4882a593Smuzhiyun 			min_size = min_t(size_t, walker->gpu_alloc->nents,
1946*4882a593Smuzhiyun 					info->commit_pages);
1947*4882a593Smuzhiyun 			max_size = max_t(size_t, walker->gpu_alloc->nents,
1948*4882a593Smuzhiyun 					info->commit_pages);
1949*4882a593Smuzhiyun 			diff = max_size - min_size;
1950*4882a593Smuzhiyun 
1951*4882a593Smuzhiyun 			if (current_diff > diff) {
1952*4882a593Smuzhiyun 				current_diff = diff;
1953*4882a593Smuzhiyun 				reg = walker;
1954*4882a593Smuzhiyun 			}
1955*4882a593Smuzhiyun 
1956*4882a593Smuzhiyun 			/* The allocation is an exact match, stop looking */
1957*4882a593Smuzhiyun 			if (current_diff == 0)
1958*4882a593Smuzhiyun 				break;
1959*4882a593Smuzhiyun 		}
1960*4882a593Smuzhiyun 	}
1961*4882a593Smuzhiyun 
1962*4882a593Smuzhiyun 	if (reg) {
1963*4882a593Smuzhiyun 		/*
1964*4882a593Smuzhiyun 		 * Remove the found region from the pool and add it to the
1965*4882a593Smuzhiyun 		 * active list.
1966*4882a593Smuzhiyun 		 */
1967*4882a593Smuzhiyun 		list_move(&reg->jit_node, &kctx->jit_active_head);
1968*4882a593Smuzhiyun 
1969*4882a593Smuzhiyun 		/*
1970*4882a593Smuzhiyun 		 * Remove the allocation from the eviction list as it's no
1971*4882a593Smuzhiyun 		 * longer eligible for eviction. This must be done before
1972*4882a593Smuzhiyun 		 * dropping the jit_evict_lock
1973*4882a593Smuzhiyun 		 */
1974*4882a593Smuzhiyun 		list_del_init(&reg->gpu_alloc->evict_node);
1975*4882a593Smuzhiyun 		mutex_unlock(&kctx->jit_evict_lock);
1976*4882a593Smuzhiyun 
1977*4882a593Smuzhiyun 		kbase_gpu_vm_lock(kctx);
1978*4882a593Smuzhiyun 
1979*4882a593Smuzhiyun 		/* Make the physical backing no longer reclaimable */
1980*4882a593Smuzhiyun 		if (!kbase_mem_evictable_unmake(reg->gpu_alloc))
1981*4882a593Smuzhiyun 			goto update_failed;
1982*4882a593Smuzhiyun 
1983*4882a593Smuzhiyun 		/* Grow the backing if required */
1984*4882a593Smuzhiyun 		if (reg->gpu_alloc->nents < info->commit_pages) {
1985*4882a593Smuzhiyun 			size_t delta;
1986*4882a593Smuzhiyun 			size_t old_size = reg->gpu_alloc->nents;
1987*4882a593Smuzhiyun 
1988*4882a593Smuzhiyun 			/* Allocate some more pages */
1989*4882a593Smuzhiyun 			delta = info->commit_pages - reg->gpu_alloc->nents;
1990*4882a593Smuzhiyun 			if (kbase_alloc_phy_pages_helper(reg->gpu_alloc, delta)
1991*4882a593Smuzhiyun 					!= 0)
1992*4882a593Smuzhiyun 				goto update_failed;
1993*4882a593Smuzhiyun 
1994*4882a593Smuzhiyun 			if (reg->cpu_alloc != reg->gpu_alloc) {
1995*4882a593Smuzhiyun 				if (kbase_alloc_phy_pages_helper(
1996*4882a593Smuzhiyun 						reg->cpu_alloc, delta) != 0) {
1997*4882a593Smuzhiyun 					kbase_free_phy_pages_helper(
1998*4882a593Smuzhiyun 							reg->gpu_alloc, delta);
1999*4882a593Smuzhiyun 					goto update_failed;
2000*4882a593Smuzhiyun 				}
2001*4882a593Smuzhiyun 			}
2002*4882a593Smuzhiyun 
2003*4882a593Smuzhiyun 			ret = kbase_mem_grow_gpu_mapping(kctx, reg,
2004*4882a593Smuzhiyun 					info->commit_pages, old_size);
2005*4882a593Smuzhiyun 			/*
2006*4882a593Smuzhiyun 			 * The grow failed so put the allocation back in the
2007*4882a593Smuzhiyun 			 * pool and return failure.
2008*4882a593Smuzhiyun 			 */
2009*4882a593Smuzhiyun 			if (ret)
2010*4882a593Smuzhiyun 				goto update_failed;
2011*4882a593Smuzhiyun 		}
2012*4882a593Smuzhiyun 		kbase_gpu_vm_unlock(kctx);
2013*4882a593Smuzhiyun 	} else {
2014*4882a593Smuzhiyun 		/* No suitable JIT allocation was found so create a new one */
2015*4882a593Smuzhiyun 		u64 flags = BASE_MEM_PROT_CPU_RD | BASE_MEM_PROT_GPU_RD |
2016*4882a593Smuzhiyun 				BASE_MEM_PROT_GPU_WR | BASE_MEM_GROW_ON_GPF |
2017*4882a593Smuzhiyun 				BASE_MEM_COHERENT_LOCAL;
2018*4882a593Smuzhiyun 		u64 gpu_addr;
2019*4882a593Smuzhiyun 
2020*4882a593Smuzhiyun 		mutex_unlock(&kctx->jit_evict_lock);
2021*4882a593Smuzhiyun 
2022*4882a593Smuzhiyun 		reg = kbase_mem_alloc(kctx, info->va_pages, info->commit_pages,
2023*4882a593Smuzhiyun 				info->extent, &flags, &gpu_addr);
2024*4882a593Smuzhiyun 		if (!reg)
2025*4882a593Smuzhiyun 			goto out_unlocked;
2026*4882a593Smuzhiyun 
2027*4882a593Smuzhiyun 		mutex_lock(&kctx->jit_evict_lock);
2028*4882a593Smuzhiyun 		list_add(&reg->jit_node, &kctx->jit_active_head);
2029*4882a593Smuzhiyun 		mutex_unlock(&kctx->jit_evict_lock);
2030*4882a593Smuzhiyun 	}
2031*4882a593Smuzhiyun 
2032*4882a593Smuzhiyun 	return reg;
2033*4882a593Smuzhiyun 
2034*4882a593Smuzhiyun update_failed:
2035*4882a593Smuzhiyun 	/*
2036*4882a593Smuzhiyun 	 * An update to an allocation from the pool failed, chances
2037*4882a593Smuzhiyun 	 * are slim a new allocation would fair any better so return
2038*4882a593Smuzhiyun 	 * the allocation to the pool and return the function with failure.
2039*4882a593Smuzhiyun 	 */
2040*4882a593Smuzhiyun 	kbase_gpu_vm_unlock(kctx);
2041*4882a593Smuzhiyun 	mutex_lock(&kctx->jit_evict_lock);
2042*4882a593Smuzhiyun 	list_move(&reg->jit_node, &kctx->jit_pool_head);
2043*4882a593Smuzhiyun 	mutex_unlock(&kctx->jit_evict_lock);
2044*4882a593Smuzhiyun out_unlocked:
2045*4882a593Smuzhiyun 	return NULL;
2046*4882a593Smuzhiyun }
2047*4882a593Smuzhiyun 
kbase_jit_free(struct kbase_context * kctx,struct kbase_va_region * reg)2048*4882a593Smuzhiyun void kbase_jit_free(struct kbase_context *kctx, struct kbase_va_region *reg)
2049*4882a593Smuzhiyun {
2050*4882a593Smuzhiyun 	/* The physical backing of memory in the pool is always reclaimable */
2051*4882a593Smuzhiyun 	kbase_gpu_vm_lock(kctx);
2052*4882a593Smuzhiyun 	kbase_mem_evictable_make(reg->gpu_alloc);
2053*4882a593Smuzhiyun 	kbase_gpu_vm_unlock(kctx);
2054*4882a593Smuzhiyun 
2055*4882a593Smuzhiyun 	mutex_lock(&kctx->jit_evict_lock);
2056*4882a593Smuzhiyun 	list_move(&reg->jit_node, &kctx->jit_pool_head);
2057*4882a593Smuzhiyun 	mutex_unlock(&kctx->jit_evict_lock);
2058*4882a593Smuzhiyun }
2059*4882a593Smuzhiyun 
kbase_jit_backing_lost(struct kbase_va_region * reg)2060*4882a593Smuzhiyun void kbase_jit_backing_lost(struct kbase_va_region *reg)
2061*4882a593Smuzhiyun {
2062*4882a593Smuzhiyun 	struct kbase_context *kctx = reg->kctx;
2063*4882a593Smuzhiyun 
2064*4882a593Smuzhiyun 	lockdep_assert_held(&kctx->jit_evict_lock);
2065*4882a593Smuzhiyun 
2066*4882a593Smuzhiyun 	/*
2067*4882a593Smuzhiyun 	 * JIT allocations will always be on a list, if the region
2068*4882a593Smuzhiyun 	 * is not on a list then it's not a JIT allocation.
2069*4882a593Smuzhiyun 	 */
2070*4882a593Smuzhiyun 	if (list_empty(&reg->jit_node))
2071*4882a593Smuzhiyun 		return;
2072*4882a593Smuzhiyun 
2073*4882a593Smuzhiyun 	/*
2074*4882a593Smuzhiyun 	 * Freeing the allocation requires locks we might not be able
2075*4882a593Smuzhiyun 	 * to take now, so move the allocation to the free list and kick
2076*4882a593Smuzhiyun 	 * the worker which will do the freeing.
2077*4882a593Smuzhiyun 	 */
2078*4882a593Smuzhiyun 	list_move(&reg->jit_node, &kctx->jit_destroy_head);
2079*4882a593Smuzhiyun 
2080*4882a593Smuzhiyun 	schedule_work(&kctx->jit_work);
2081*4882a593Smuzhiyun }
2082*4882a593Smuzhiyun 
kbase_jit_evict(struct kbase_context * kctx)2083*4882a593Smuzhiyun bool kbase_jit_evict(struct kbase_context *kctx)
2084*4882a593Smuzhiyun {
2085*4882a593Smuzhiyun 	struct kbase_va_region *reg = NULL;
2086*4882a593Smuzhiyun 
2087*4882a593Smuzhiyun 	lockdep_assert_held(&kctx->reg_lock);
2088*4882a593Smuzhiyun 
2089*4882a593Smuzhiyun 	/* Free the oldest allocation from the pool */
2090*4882a593Smuzhiyun 	mutex_lock(&kctx->jit_evict_lock);
2091*4882a593Smuzhiyun 	if (!list_empty(&kctx->jit_pool_head)) {
2092*4882a593Smuzhiyun 		reg = list_entry(kctx->jit_pool_head.prev,
2093*4882a593Smuzhiyun 				struct kbase_va_region, jit_node);
2094*4882a593Smuzhiyun 		list_del(&reg->jit_node);
2095*4882a593Smuzhiyun 	}
2096*4882a593Smuzhiyun 	mutex_unlock(&kctx->jit_evict_lock);
2097*4882a593Smuzhiyun 
2098*4882a593Smuzhiyun 	if (reg)
2099*4882a593Smuzhiyun 		kbase_mem_free_region(kctx, reg);
2100*4882a593Smuzhiyun 
2101*4882a593Smuzhiyun 	return (reg != NULL);
2102*4882a593Smuzhiyun }
2103*4882a593Smuzhiyun 
kbase_jit_term(struct kbase_context * kctx)2104*4882a593Smuzhiyun void kbase_jit_term(struct kbase_context *kctx)
2105*4882a593Smuzhiyun {
2106*4882a593Smuzhiyun 	struct kbase_va_region *walker;
2107*4882a593Smuzhiyun 
2108*4882a593Smuzhiyun 	/* Free all allocations for this context */
2109*4882a593Smuzhiyun 
2110*4882a593Smuzhiyun 	/*
2111*4882a593Smuzhiyun 	 * Flush the freeing of allocations whose backing has been freed
2112*4882a593Smuzhiyun 	 * (i.e. everything in jit_destroy_head).
2113*4882a593Smuzhiyun 	 */
2114*4882a593Smuzhiyun 	cancel_work_sync(&kctx->jit_work);
2115*4882a593Smuzhiyun 
2116*4882a593Smuzhiyun 	kbase_gpu_vm_lock(kctx);
2117*4882a593Smuzhiyun 	mutex_lock(&kctx->jit_evict_lock);
2118*4882a593Smuzhiyun 	/* Free all allocations from the pool */
2119*4882a593Smuzhiyun 	while (!list_empty(&kctx->jit_pool_head)) {
2120*4882a593Smuzhiyun 		walker = list_first_entry(&kctx->jit_pool_head,
2121*4882a593Smuzhiyun 				struct kbase_va_region, jit_node);
2122*4882a593Smuzhiyun 		list_del(&walker->jit_node);
2123*4882a593Smuzhiyun 		mutex_unlock(&kctx->jit_evict_lock);
2124*4882a593Smuzhiyun 		kbase_mem_free_region(kctx, walker);
2125*4882a593Smuzhiyun 		mutex_lock(&kctx->jit_evict_lock);
2126*4882a593Smuzhiyun 	}
2127*4882a593Smuzhiyun 
2128*4882a593Smuzhiyun 	/* Free all allocations from active list */
2129*4882a593Smuzhiyun 	while (!list_empty(&kctx->jit_active_head)) {
2130*4882a593Smuzhiyun 		walker = list_first_entry(&kctx->jit_active_head,
2131*4882a593Smuzhiyun 				struct kbase_va_region, jit_node);
2132*4882a593Smuzhiyun 		list_del(&walker->jit_node);
2133*4882a593Smuzhiyun 		mutex_unlock(&kctx->jit_evict_lock);
2134*4882a593Smuzhiyun 		kbase_mem_free_region(kctx, walker);
2135*4882a593Smuzhiyun 		mutex_lock(&kctx->jit_evict_lock);
2136*4882a593Smuzhiyun 	}
2137*4882a593Smuzhiyun 	mutex_unlock(&kctx->jit_evict_lock);
2138*4882a593Smuzhiyun 	kbase_gpu_vm_unlock(kctx);
2139*4882a593Smuzhiyun }
2140*4882a593Smuzhiyun 
kbase_jd_user_buf_map(struct kbase_context * kctx,struct kbase_va_region * reg)2141*4882a593Smuzhiyun static int kbase_jd_user_buf_map(struct kbase_context *kctx,
2142*4882a593Smuzhiyun 		struct kbase_va_region *reg)
2143*4882a593Smuzhiyun {
2144*4882a593Smuzhiyun 	long pinned_pages;
2145*4882a593Smuzhiyun 	struct kbase_mem_phy_alloc *alloc;
2146*4882a593Smuzhiyun 	struct page **pages;
2147*4882a593Smuzhiyun 	phys_addr_t *pa;
2148*4882a593Smuzhiyun 	long i;
2149*4882a593Smuzhiyun 	int err = -ENOMEM;
2150*4882a593Smuzhiyun 	unsigned long address;
2151*4882a593Smuzhiyun 	struct mm_struct *mm;
2152*4882a593Smuzhiyun 	struct device *dev;
2153*4882a593Smuzhiyun 	unsigned long offset;
2154*4882a593Smuzhiyun 	unsigned long local_size;
2155*4882a593Smuzhiyun 
2156*4882a593Smuzhiyun 	alloc = reg->gpu_alloc;
2157*4882a593Smuzhiyun 	pa = kbase_get_gpu_phy_pages(reg);
2158*4882a593Smuzhiyun 	address = alloc->imported.user_buf.address;
2159*4882a593Smuzhiyun 	mm = alloc->imported.user_buf.mm;
2160*4882a593Smuzhiyun 
2161*4882a593Smuzhiyun 	KBASE_DEBUG_ASSERT(alloc->type == KBASE_MEM_TYPE_IMPORTED_USER_BUF);
2162*4882a593Smuzhiyun 
2163*4882a593Smuzhiyun 	pages = alloc->imported.user_buf.pages;
2164*4882a593Smuzhiyun 
2165*4882a593Smuzhiyun #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0)
2166*4882a593Smuzhiyun 	pinned_pages = get_user_pages(NULL, mm,
2167*4882a593Smuzhiyun 			address,
2168*4882a593Smuzhiyun 			alloc->imported.user_buf.nr_pages,
2169*4882a593Smuzhiyun 			reg->flags & KBASE_REG_GPU_WR,
2170*4882a593Smuzhiyun 			0, pages, NULL);
2171*4882a593Smuzhiyun #elif LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 0)
2172*4882a593Smuzhiyun 	pinned_pages = get_user_pages_remote(NULL, mm,
2173*4882a593Smuzhiyun 			address,
2174*4882a593Smuzhiyun 			alloc->imported.user_buf.nr_pages,
2175*4882a593Smuzhiyun 			reg->flags & KBASE_REG_GPU_WR,
2176*4882a593Smuzhiyun 			0, pages, NULL);
2177*4882a593Smuzhiyun #elif LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0)
2178*4882a593Smuzhiyun 	pinned_pages = get_user_pages_remote(NULL, mm,
2179*4882a593Smuzhiyun 			address,
2180*4882a593Smuzhiyun 			alloc->imported.user_buf.nr_pages,
2181*4882a593Smuzhiyun 			reg->flags & KBASE_REG_GPU_WR ? FOLL_WRITE : 0,
2182*4882a593Smuzhiyun 			pages, NULL);
2183*4882a593Smuzhiyun #elif LINUX_VERSION_CODE < KERNEL_VERSION(5, 9, 0)
2184*4882a593Smuzhiyun 	pinned_pages = get_user_pages_remote(NULL, mm,
2185*4882a593Smuzhiyun 			address,
2186*4882a593Smuzhiyun 			alloc->imported.user_buf.nr_pages,
2187*4882a593Smuzhiyun 			reg->flags & KBASE_REG_GPU_WR ? FOLL_WRITE : 0,
2188*4882a593Smuzhiyun 			pages, NULL, NULL);
2189*4882a593Smuzhiyun #else
2190*4882a593Smuzhiyun 	pinned_pages = get_user_pages_remote(mm,
2191*4882a593Smuzhiyun 			address,
2192*4882a593Smuzhiyun 			alloc->imported.user_buf.nr_pages,
2193*4882a593Smuzhiyun 			reg->flags & KBASE_REG_GPU_WR ? FOLL_WRITE : 0,
2194*4882a593Smuzhiyun 			pages, NULL, NULL);
2195*4882a593Smuzhiyun #endif
2196*4882a593Smuzhiyun 
2197*4882a593Smuzhiyun 	if (pinned_pages <= 0)
2198*4882a593Smuzhiyun 		return pinned_pages;
2199*4882a593Smuzhiyun 
2200*4882a593Smuzhiyun 	if (pinned_pages != alloc->imported.user_buf.nr_pages) {
2201*4882a593Smuzhiyun 		for (i = 0; i < pinned_pages; i++)
2202*4882a593Smuzhiyun 			put_page(pages[i]);
2203*4882a593Smuzhiyun 		return -ENOMEM;
2204*4882a593Smuzhiyun 	}
2205*4882a593Smuzhiyun 
2206*4882a593Smuzhiyun 	dev = kctx->kbdev->dev;
2207*4882a593Smuzhiyun 	offset = address & ~PAGE_MASK;
2208*4882a593Smuzhiyun 	local_size = alloc->imported.user_buf.size;
2209*4882a593Smuzhiyun 
2210*4882a593Smuzhiyun 	for (i = 0; i < pinned_pages; i++) {
2211*4882a593Smuzhiyun 		dma_addr_t dma_addr;
2212*4882a593Smuzhiyun 		unsigned long min;
2213*4882a593Smuzhiyun 
2214*4882a593Smuzhiyun 		min = MIN(PAGE_SIZE - offset, local_size);
2215*4882a593Smuzhiyun 		dma_addr = dma_map_page(dev, pages[i],
2216*4882a593Smuzhiyun 				offset, min,
2217*4882a593Smuzhiyun 				DMA_BIDIRECTIONAL);
2218*4882a593Smuzhiyun 		if (dma_mapping_error(dev, dma_addr))
2219*4882a593Smuzhiyun 			goto unwind;
2220*4882a593Smuzhiyun 
2221*4882a593Smuzhiyun 		alloc->imported.user_buf.dma_addrs[i] = dma_addr;
2222*4882a593Smuzhiyun 		pa[i] = page_to_phys(pages[i]);
2223*4882a593Smuzhiyun 
2224*4882a593Smuzhiyun 		local_size -= min;
2225*4882a593Smuzhiyun 		offset = 0;
2226*4882a593Smuzhiyun 	}
2227*4882a593Smuzhiyun 
2228*4882a593Smuzhiyun 	alloc->nents = pinned_pages;
2229*4882a593Smuzhiyun 
2230*4882a593Smuzhiyun 	err = kbase_mmu_insert_pages(kctx, reg->start_pfn, pa,
2231*4882a593Smuzhiyun 			kbase_reg_current_backed_size(reg),
2232*4882a593Smuzhiyun 			reg->flags);
2233*4882a593Smuzhiyun 	if (err == 0)
2234*4882a593Smuzhiyun 		return 0;
2235*4882a593Smuzhiyun 
2236*4882a593Smuzhiyun 	alloc->nents = 0;
2237*4882a593Smuzhiyun 	/* fall down */
2238*4882a593Smuzhiyun unwind:
2239*4882a593Smuzhiyun 	while (i--) {
2240*4882a593Smuzhiyun 		dma_unmap_page(kctx->kbdev->dev,
2241*4882a593Smuzhiyun 				alloc->imported.user_buf.dma_addrs[i],
2242*4882a593Smuzhiyun 				PAGE_SIZE, DMA_BIDIRECTIONAL);
2243*4882a593Smuzhiyun 		put_page(pages[i]);
2244*4882a593Smuzhiyun 		pages[i] = NULL;
2245*4882a593Smuzhiyun 	}
2246*4882a593Smuzhiyun 
2247*4882a593Smuzhiyun 	return err;
2248*4882a593Smuzhiyun }
2249*4882a593Smuzhiyun 
kbase_jd_user_buf_unmap(struct kbase_context * kctx,struct kbase_mem_phy_alloc * alloc,bool writeable)2250*4882a593Smuzhiyun static void kbase_jd_user_buf_unmap(struct kbase_context *kctx,
2251*4882a593Smuzhiyun 		struct kbase_mem_phy_alloc *alloc, bool writeable)
2252*4882a593Smuzhiyun {
2253*4882a593Smuzhiyun 	long i;
2254*4882a593Smuzhiyun 	struct page **pages;
2255*4882a593Smuzhiyun 	unsigned long size = alloc->imported.user_buf.size;
2256*4882a593Smuzhiyun 
2257*4882a593Smuzhiyun 	KBASE_DEBUG_ASSERT(alloc->type == KBASE_MEM_TYPE_IMPORTED_USER_BUF);
2258*4882a593Smuzhiyun 	pages = alloc->imported.user_buf.pages;
2259*4882a593Smuzhiyun 	for (i = 0; i < alloc->imported.user_buf.nr_pages; i++) {
2260*4882a593Smuzhiyun 		unsigned long local_size;
2261*4882a593Smuzhiyun 		dma_addr_t dma_addr = alloc->imported.user_buf.dma_addrs[i];
2262*4882a593Smuzhiyun 
2263*4882a593Smuzhiyun 		local_size = MIN(size, PAGE_SIZE - (dma_addr & ~PAGE_MASK));
2264*4882a593Smuzhiyun 		dma_unmap_page(kctx->kbdev->dev, dma_addr, local_size,
2265*4882a593Smuzhiyun 				DMA_BIDIRECTIONAL);
2266*4882a593Smuzhiyun 		if (writeable)
2267*4882a593Smuzhiyun 			set_page_dirty_lock(pages[i]);
2268*4882a593Smuzhiyun 		put_page(pages[i]);
2269*4882a593Smuzhiyun 		pages[i] = NULL;
2270*4882a593Smuzhiyun 
2271*4882a593Smuzhiyun 		size -= local_size;
2272*4882a593Smuzhiyun 	}
2273*4882a593Smuzhiyun 	alloc->nents = 0;
2274*4882a593Smuzhiyun }
2275*4882a593Smuzhiyun 
2276*4882a593Smuzhiyun 
2277*4882a593Smuzhiyun /* to replace sg_dma_len. */
2278*4882a593Smuzhiyun #define MALI_SG_DMA_LEN(sg)        ((sg)->length)
2279*4882a593Smuzhiyun 
2280*4882a593Smuzhiyun #ifdef CONFIG_DMA_SHARED_BUFFER
kbase_jd_umm_map(struct kbase_context * kctx,struct kbase_va_region * reg)2281*4882a593Smuzhiyun static int kbase_jd_umm_map(struct kbase_context *kctx,
2282*4882a593Smuzhiyun 		struct kbase_va_region *reg)
2283*4882a593Smuzhiyun {
2284*4882a593Smuzhiyun 	struct sg_table *sgt;
2285*4882a593Smuzhiyun 	struct scatterlist *s;
2286*4882a593Smuzhiyun 	int i;
2287*4882a593Smuzhiyun 	phys_addr_t *pa;
2288*4882a593Smuzhiyun 	int err;
2289*4882a593Smuzhiyun 	size_t count = 0;
2290*4882a593Smuzhiyun 	struct kbase_mem_phy_alloc *alloc;
2291*4882a593Smuzhiyun 
2292*4882a593Smuzhiyun 	alloc = reg->gpu_alloc;
2293*4882a593Smuzhiyun 
2294*4882a593Smuzhiyun 	KBASE_DEBUG_ASSERT(alloc->type == KBASE_MEM_TYPE_IMPORTED_UMM);
2295*4882a593Smuzhiyun 	KBASE_DEBUG_ASSERT(NULL == alloc->imported.umm.sgt);
2296*4882a593Smuzhiyun 	sgt = dma_buf_map_attachment(alloc->imported.umm.dma_attachment,
2297*4882a593Smuzhiyun 			DMA_BIDIRECTIONAL);
2298*4882a593Smuzhiyun 
2299*4882a593Smuzhiyun 	if (IS_ERR_OR_NULL(sgt))
2300*4882a593Smuzhiyun 		return -EINVAL;
2301*4882a593Smuzhiyun 
2302*4882a593Smuzhiyun 	/* save for later */
2303*4882a593Smuzhiyun 	alloc->imported.umm.sgt = sgt;
2304*4882a593Smuzhiyun 
2305*4882a593Smuzhiyun 	pa = kbase_get_gpu_phy_pages(reg);
2306*4882a593Smuzhiyun 	KBASE_DEBUG_ASSERT(pa);
2307*4882a593Smuzhiyun 
2308*4882a593Smuzhiyun 	for_each_sg(sgt->sgl, s, sgt->nents, i) {
2309*4882a593Smuzhiyun 		int j;
2310*4882a593Smuzhiyun 		size_t pages = PFN_UP(MALI_SG_DMA_LEN(s));
2311*4882a593Smuzhiyun 
2312*4882a593Smuzhiyun 		WARN_ONCE(MALI_SG_DMA_LEN(s) & (PAGE_SIZE-1),
2313*4882a593Smuzhiyun 		"MALI_SG_DMA_LEN(s)=%u is not a multiple of PAGE_SIZE\n",
2314*4882a593Smuzhiyun 		MALI_SG_DMA_LEN(s));
2315*4882a593Smuzhiyun 
2316*4882a593Smuzhiyun 		WARN_ONCE(sg_dma_address(s) & (PAGE_SIZE-1),
2317*4882a593Smuzhiyun 		"sg_dma_address(s)=%llx is not aligned to PAGE_SIZE\n",
2318*4882a593Smuzhiyun 		(unsigned long long) sg_dma_address(s));
2319*4882a593Smuzhiyun 
2320*4882a593Smuzhiyun 		for (j = 0; (j < pages) && (count < reg->nr_pages); j++,
2321*4882a593Smuzhiyun 				count++)
2322*4882a593Smuzhiyun 			*pa++ = sg_dma_address(s) + (j << PAGE_SHIFT);
2323*4882a593Smuzhiyun 		WARN_ONCE(j < pages,
2324*4882a593Smuzhiyun 		"sg list from dma_buf_map_attachment > dma_buf->size=%zu\n",
2325*4882a593Smuzhiyun 		alloc->imported.umm.dma_buf->size);
2326*4882a593Smuzhiyun 	}
2327*4882a593Smuzhiyun 
2328*4882a593Smuzhiyun 	if (!(reg->flags & KBASE_REG_IMPORT_PAD) &&
2329*4882a593Smuzhiyun 			WARN_ONCE(count < reg->nr_pages,
2330*4882a593Smuzhiyun 			"sg list from dma_buf_map_attachment < dma_buf->size=%zu\n",
2331*4882a593Smuzhiyun 			alloc->imported.umm.dma_buf->size)) {
2332*4882a593Smuzhiyun 		err = -EINVAL;
2333*4882a593Smuzhiyun 		goto err_unmap_attachment;
2334*4882a593Smuzhiyun 	}
2335*4882a593Smuzhiyun 
2336*4882a593Smuzhiyun 	/* Update nents as we now have pages to map */
2337*4882a593Smuzhiyun 	alloc->nents = reg->nr_pages;
2338*4882a593Smuzhiyun 
2339*4882a593Smuzhiyun 	err = kbase_mmu_insert_pages(kctx, reg->start_pfn,
2340*4882a593Smuzhiyun 			kbase_get_gpu_phy_pages(reg),
2341*4882a593Smuzhiyun 			count,
2342*4882a593Smuzhiyun 			reg->flags | KBASE_REG_GPU_WR | KBASE_REG_GPU_RD);
2343*4882a593Smuzhiyun 	if (err)
2344*4882a593Smuzhiyun 		goto err_unmap_attachment;
2345*4882a593Smuzhiyun 
2346*4882a593Smuzhiyun 	if (reg->flags & KBASE_REG_IMPORT_PAD) {
2347*4882a593Smuzhiyun 		err = kbase_mmu_insert_single_page(kctx,
2348*4882a593Smuzhiyun 				reg->start_pfn + count,
2349*4882a593Smuzhiyun 				page_to_phys(kctx->aliasing_sink_page),
2350*4882a593Smuzhiyun 				reg->nr_pages - count,
2351*4882a593Smuzhiyun 				(reg->flags | KBASE_REG_GPU_RD) &
2352*4882a593Smuzhiyun 				~KBASE_REG_GPU_WR);
2353*4882a593Smuzhiyun 		if (err)
2354*4882a593Smuzhiyun 			goto err_teardown_orig_pages;
2355*4882a593Smuzhiyun 	}
2356*4882a593Smuzhiyun 
2357*4882a593Smuzhiyun 	return 0;
2358*4882a593Smuzhiyun 
2359*4882a593Smuzhiyun err_teardown_orig_pages:
2360*4882a593Smuzhiyun 	kbase_mmu_teardown_pages(kctx, reg->start_pfn, count);
2361*4882a593Smuzhiyun err_unmap_attachment:
2362*4882a593Smuzhiyun 	dma_buf_unmap_attachment(alloc->imported.umm.dma_attachment,
2363*4882a593Smuzhiyun 			alloc->imported.umm.sgt, DMA_BIDIRECTIONAL);
2364*4882a593Smuzhiyun 	alloc->imported.umm.sgt = NULL;
2365*4882a593Smuzhiyun 
2366*4882a593Smuzhiyun 	return err;
2367*4882a593Smuzhiyun }
2368*4882a593Smuzhiyun 
kbase_jd_umm_unmap(struct kbase_context * kctx,struct kbase_mem_phy_alloc * alloc)2369*4882a593Smuzhiyun static void kbase_jd_umm_unmap(struct kbase_context *kctx,
2370*4882a593Smuzhiyun 		struct kbase_mem_phy_alloc *alloc)
2371*4882a593Smuzhiyun {
2372*4882a593Smuzhiyun 	KBASE_DEBUG_ASSERT(kctx);
2373*4882a593Smuzhiyun 	KBASE_DEBUG_ASSERT(alloc);
2374*4882a593Smuzhiyun 	KBASE_DEBUG_ASSERT(alloc->imported.umm.dma_attachment);
2375*4882a593Smuzhiyun 	KBASE_DEBUG_ASSERT(alloc->imported.umm.sgt);
2376*4882a593Smuzhiyun 	dma_buf_unmap_attachment(alloc->imported.umm.dma_attachment,
2377*4882a593Smuzhiyun 	    alloc->imported.umm.sgt, DMA_BIDIRECTIONAL);
2378*4882a593Smuzhiyun 	alloc->imported.umm.sgt = NULL;
2379*4882a593Smuzhiyun 	alloc->nents = 0;
2380*4882a593Smuzhiyun }
2381*4882a593Smuzhiyun #endif				/* CONFIG_DMA_SHARED_BUFFER */
2382*4882a593Smuzhiyun 
2383*4882a593Smuzhiyun #if (defined(CONFIG_KDS) && defined(CONFIG_UMP)) \
2384*4882a593Smuzhiyun 		|| defined(CONFIG_DMA_SHARED_BUFFER_USES_KDS)
add_kds_resource(struct kds_resource * kds_res,struct kds_resource ** kds_resources,u32 * kds_res_count,unsigned long * kds_access_bitmap,bool exclusive)2385*4882a593Smuzhiyun static void add_kds_resource(struct kds_resource *kds_res,
2386*4882a593Smuzhiyun 		struct kds_resource **kds_resources, u32 *kds_res_count,
2387*4882a593Smuzhiyun 		unsigned long *kds_access_bitmap, bool exclusive)
2388*4882a593Smuzhiyun {
2389*4882a593Smuzhiyun 	u32 i;
2390*4882a593Smuzhiyun 
2391*4882a593Smuzhiyun 	for (i = 0; i < *kds_res_count; i++) {
2392*4882a593Smuzhiyun 		/* Duplicate resource, ignore */
2393*4882a593Smuzhiyun 		if (kds_resources[i] == kds_res)
2394*4882a593Smuzhiyun 			return;
2395*4882a593Smuzhiyun 	}
2396*4882a593Smuzhiyun 
2397*4882a593Smuzhiyun 	kds_resources[*kds_res_count] = kds_res;
2398*4882a593Smuzhiyun 	if (exclusive)
2399*4882a593Smuzhiyun 		set_bit(*kds_res_count, kds_access_bitmap);
2400*4882a593Smuzhiyun 	(*kds_res_count)++;
2401*4882a593Smuzhiyun }
2402*4882a593Smuzhiyun #endif
2403*4882a593Smuzhiyun 
kbase_map_external_resource(struct kbase_context * kctx,struct kbase_va_region * reg,struct mm_struct * locked_mm,u32 * kds_res_count,struct kds_resource ** kds_resources,unsigned long * kds_access_bitmap,bool exclusive)2404*4882a593Smuzhiyun struct kbase_mem_phy_alloc *kbase_map_external_resource(
2405*4882a593Smuzhiyun 		struct kbase_context *kctx, struct kbase_va_region *reg,
2406*4882a593Smuzhiyun 		struct mm_struct *locked_mm
2407*4882a593Smuzhiyun #ifdef CONFIG_KDS
2408*4882a593Smuzhiyun 		, u32 *kds_res_count, struct kds_resource **kds_resources,
2409*4882a593Smuzhiyun 		unsigned long *kds_access_bitmap, bool exclusive
2410*4882a593Smuzhiyun #endif
2411*4882a593Smuzhiyun 		)
2412*4882a593Smuzhiyun {
2413*4882a593Smuzhiyun 	int err;
2414*4882a593Smuzhiyun 
2415*4882a593Smuzhiyun 	/* decide what needs to happen for this resource */
2416*4882a593Smuzhiyun 	switch (reg->gpu_alloc->type) {
2417*4882a593Smuzhiyun 	case KBASE_MEM_TYPE_IMPORTED_USER_BUF: {
2418*4882a593Smuzhiyun 		if (reg->gpu_alloc->imported.user_buf.mm != locked_mm)
2419*4882a593Smuzhiyun 			goto exit;
2420*4882a593Smuzhiyun 
2421*4882a593Smuzhiyun 		reg->gpu_alloc->imported.user_buf.current_mapping_usage_count++;
2422*4882a593Smuzhiyun 		if (1 == reg->gpu_alloc->imported.user_buf.current_mapping_usage_count) {
2423*4882a593Smuzhiyun 			err = kbase_jd_user_buf_map(kctx, reg);
2424*4882a593Smuzhiyun 			if (err) {
2425*4882a593Smuzhiyun 				reg->gpu_alloc->imported.user_buf.current_mapping_usage_count--;
2426*4882a593Smuzhiyun 				goto exit;
2427*4882a593Smuzhiyun 			}
2428*4882a593Smuzhiyun 		}
2429*4882a593Smuzhiyun 	}
2430*4882a593Smuzhiyun 	break;
2431*4882a593Smuzhiyun 	case KBASE_MEM_TYPE_IMPORTED_UMP: {
2432*4882a593Smuzhiyun #if defined(CONFIG_KDS) && defined(CONFIG_UMP)
2433*4882a593Smuzhiyun 		if (kds_res_count) {
2434*4882a593Smuzhiyun 			struct kds_resource *kds_res;
2435*4882a593Smuzhiyun 
2436*4882a593Smuzhiyun 			kds_res = ump_dd_kds_resource_get(
2437*4882a593Smuzhiyun 					reg->gpu_alloc->imported.ump_handle);
2438*4882a593Smuzhiyun 			if (kds_res)
2439*4882a593Smuzhiyun 				add_kds_resource(kds_res, kds_resources,
2440*4882a593Smuzhiyun 						kds_res_count,
2441*4882a593Smuzhiyun 						kds_access_bitmap, exclusive);
2442*4882a593Smuzhiyun 		}
2443*4882a593Smuzhiyun #endif				/*defined(CONFIG_KDS) && defined(CONFIG_UMP) */
2444*4882a593Smuzhiyun 		break;
2445*4882a593Smuzhiyun 	}
2446*4882a593Smuzhiyun #ifdef CONFIG_DMA_SHARED_BUFFER
2447*4882a593Smuzhiyun 	case KBASE_MEM_TYPE_IMPORTED_UMM: {
2448*4882a593Smuzhiyun #ifdef CONFIG_DMA_SHARED_BUFFER_USES_KDS
2449*4882a593Smuzhiyun 		if (kds_res_count) {
2450*4882a593Smuzhiyun 			struct kds_resource *kds_res;
2451*4882a593Smuzhiyun 
2452*4882a593Smuzhiyun 			kds_res = get_dma_buf_kds_resource(
2453*4882a593Smuzhiyun 					reg->gpu_alloc->imported.umm.dma_buf);
2454*4882a593Smuzhiyun 			if (kds_res)
2455*4882a593Smuzhiyun 				add_kds_resource(kds_res, kds_resources,
2456*4882a593Smuzhiyun 						kds_res_count,
2457*4882a593Smuzhiyun 						kds_access_bitmap, exclusive);
2458*4882a593Smuzhiyun 		}
2459*4882a593Smuzhiyun #endif
2460*4882a593Smuzhiyun 		reg->gpu_alloc->imported.umm.current_mapping_usage_count++;
2461*4882a593Smuzhiyun 		if (1 == reg->gpu_alloc->imported.umm.current_mapping_usage_count) {
2462*4882a593Smuzhiyun 			err = kbase_jd_umm_map(kctx, reg);
2463*4882a593Smuzhiyun 			if (err) {
2464*4882a593Smuzhiyun 				reg->gpu_alloc->imported.umm.current_mapping_usage_count--;
2465*4882a593Smuzhiyun 				goto exit;
2466*4882a593Smuzhiyun 			}
2467*4882a593Smuzhiyun 		}
2468*4882a593Smuzhiyun 		break;
2469*4882a593Smuzhiyun 	}
2470*4882a593Smuzhiyun #endif
2471*4882a593Smuzhiyun 	default:
2472*4882a593Smuzhiyun 		goto exit;
2473*4882a593Smuzhiyun 	}
2474*4882a593Smuzhiyun 
2475*4882a593Smuzhiyun 	return kbase_mem_phy_alloc_get(reg->gpu_alloc);
2476*4882a593Smuzhiyun exit:
2477*4882a593Smuzhiyun 	return NULL;
2478*4882a593Smuzhiyun }
2479*4882a593Smuzhiyun 
kbase_unmap_external_resource(struct kbase_context * kctx,struct kbase_va_region * reg,struct kbase_mem_phy_alloc * alloc)2480*4882a593Smuzhiyun void kbase_unmap_external_resource(struct kbase_context *kctx,
2481*4882a593Smuzhiyun 		struct kbase_va_region *reg, struct kbase_mem_phy_alloc *alloc)
2482*4882a593Smuzhiyun {
2483*4882a593Smuzhiyun 	switch (alloc->type) {
2484*4882a593Smuzhiyun #ifdef CONFIG_DMA_SHARED_BUFFER
2485*4882a593Smuzhiyun 	case KBASE_MEM_TYPE_IMPORTED_UMM: {
2486*4882a593Smuzhiyun 		alloc->imported.umm.current_mapping_usage_count--;
2487*4882a593Smuzhiyun 
2488*4882a593Smuzhiyun 		if (0 == alloc->imported.umm.current_mapping_usage_count) {
2489*4882a593Smuzhiyun 			if (reg && reg->gpu_alloc == alloc) {
2490*4882a593Smuzhiyun 				int err;
2491*4882a593Smuzhiyun 
2492*4882a593Smuzhiyun 				err = kbase_mmu_teardown_pages(
2493*4882a593Smuzhiyun 						kctx,
2494*4882a593Smuzhiyun 						reg->start_pfn,
2495*4882a593Smuzhiyun 						alloc->nents);
2496*4882a593Smuzhiyun 				WARN_ON(err);
2497*4882a593Smuzhiyun 			}
2498*4882a593Smuzhiyun 
2499*4882a593Smuzhiyun 			kbase_jd_umm_unmap(kctx, alloc);
2500*4882a593Smuzhiyun 		}
2501*4882a593Smuzhiyun 	}
2502*4882a593Smuzhiyun 	break;
2503*4882a593Smuzhiyun #endif /* CONFIG_DMA_SHARED_BUFFER */
2504*4882a593Smuzhiyun 	case KBASE_MEM_TYPE_IMPORTED_USER_BUF: {
2505*4882a593Smuzhiyun 		alloc->imported.user_buf.current_mapping_usage_count--;
2506*4882a593Smuzhiyun 
2507*4882a593Smuzhiyun 		if (0 == alloc->imported.user_buf.current_mapping_usage_count) {
2508*4882a593Smuzhiyun 			bool writeable = true;
2509*4882a593Smuzhiyun 
2510*4882a593Smuzhiyun 			if (reg && reg->gpu_alloc == alloc)
2511*4882a593Smuzhiyun 				kbase_mmu_teardown_pages(
2512*4882a593Smuzhiyun 						kctx,
2513*4882a593Smuzhiyun 						reg->start_pfn,
2514*4882a593Smuzhiyun 						kbase_reg_current_backed_size(reg));
2515*4882a593Smuzhiyun 
2516*4882a593Smuzhiyun 			if (reg && ((reg->flags & KBASE_REG_GPU_WR) == 0))
2517*4882a593Smuzhiyun 				writeable = false;
2518*4882a593Smuzhiyun 
2519*4882a593Smuzhiyun 			kbase_jd_user_buf_unmap(kctx, alloc, writeable);
2520*4882a593Smuzhiyun 		}
2521*4882a593Smuzhiyun 	}
2522*4882a593Smuzhiyun 	break;
2523*4882a593Smuzhiyun 	default:
2524*4882a593Smuzhiyun 	break;
2525*4882a593Smuzhiyun 	}
2526*4882a593Smuzhiyun 	kbase_mem_phy_alloc_put(alloc);
2527*4882a593Smuzhiyun }
2528*4882a593Smuzhiyun 
kbase_sticky_resource_acquire(struct kbase_context * kctx,u64 gpu_addr)2529*4882a593Smuzhiyun struct kbase_ctx_ext_res_meta *kbase_sticky_resource_acquire(
2530*4882a593Smuzhiyun 		struct kbase_context *kctx, u64 gpu_addr)
2531*4882a593Smuzhiyun {
2532*4882a593Smuzhiyun 	struct kbase_ctx_ext_res_meta *meta = NULL;
2533*4882a593Smuzhiyun 	struct kbase_ctx_ext_res_meta *walker;
2534*4882a593Smuzhiyun 
2535*4882a593Smuzhiyun 	lockdep_assert_held(&kctx->reg_lock);
2536*4882a593Smuzhiyun 
2537*4882a593Smuzhiyun 	/*
2538*4882a593Smuzhiyun 	 * Walk the per context external resource metadata list for the
2539*4882a593Smuzhiyun 	 * metadata which matches the region which is being acquired.
2540*4882a593Smuzhiyun 	 */
2541*4882a593Smuzhiyun 	list_for_each_entry(walker, &kctx->ext_res_meta_head, ext_res_node) {
2542*4882a593Smuzhiyun 		if (walker->gpu_addr == gpu_addr) {
2543*4882a593Smuzhiyun 			meta = walker;
2544*4882a593Smuzhiyun 			break;
2545*4882a593Smuzhiyun 		}
2546*4882a593Smuzhiyun 	}
2547*4882a593Smuzhiyun 
2548*4882a593Smuzhiyun 	/* No metadata exists so create one. */
2549*4882a593Smuzhiyun 	if (!meta) {
2550*4882a593Smuzhiyun 		struct kbase_va_region *reg;
2551*4882a593Smuzhiyun 
2552*4882a593Smuzhiyun 		/* Find the region */
2553*4882a593Smuzhiyun 		reg = kbase_region_tracker_find_region_enclosing_address(
2554*4882a593Smuzhiyun 				kctx, gpu_addr);
2555*4882a593Smuzhiyun 		if (NULL == reg || (reg->flags & KBASE_REG_FREE))
2556*4882a593Smuzhiyun 			goto failed;
2557*4882a593Smuzhiyun 
2558*4882a593Smuzhiyun 		/* Allocate the metadata object */
2559*4882a593Smuzhiyun 		meta = kzalloc(sizeof(*meta), GFP_KERNEL);
2560*4882a593Smuzhiyun 		if (!meta)
2561*4882a593Smuzhiyun 			goto failed;
2562*4882a593Smuzhiyun 
2563*4882a593Smuzhiyun 		/*
2564*4882a593Smuzhiyun 		 * Fill in the metadata object and acquire a reference
2565*4882a593Smuzhiyun 		 * for the physical resource.
2566*4882a593Smuzhiyun 		 */
2567*4882a593Smuzhiyun 		meta->alloc = kbase_map_external_resource(kctx, reg, NULL
2568*4882a593Smuzhiyun #ifdef CONFIG_KDS
2569*4882a593Smuzhiyun 				, NULL, NULL,
2570*4882a593Smuzhiyun 				NULL, false
2571*4882a593Smuzhiyun #endif
2572*4882a593Smuzhiyun 				);
2573*4882a593Smuzhiyun 
2574*4882a593Smuzhiyun 		if (!meta->alloc)
2575*4882a593Smuzhiyun 			goto fail_map;
2576*4882a593Smuzhiyun 
2577*4882a593Smuzhiyun 		meta->gpu_addr = reg->start_pfn << PAGE_SHIFT;
2578*4882a593Smuzhiyun 
2579*4882a593Smuzhiyun 		list_add(&meta->ext_res_node, &kctx->ext_res_meta_head);
2580*4882a593Smuzhiyun 	}
2581*4882a593Smuzhiyun 
2582*4882a593Smuzhiyun 	return meta;
2583*4882a593Smuzhiyun 
2584*4882a593Smuzhiyun fail_map:
2585*4882a593Smuzhiyun 	kfree(meta);
2586*4882a593Smuzhiyun failed:
2587*4882a593Smuzhiyun 	return NULL;
2588*4882a593Smuzhiyun }
2589*4882a593Smuzhiyun 
kbase_sticky_resource_release(struct kbase_context * kctx,struct kbase_ctx_ext_res_meta * meta,u64 gpu_addr)2590*4882a593Smuzhiyun bool kbase_sticky_resource_release(struct kbase_context *kctx,
2591*4882a593Smuzhiyun 		struct kbase_ctx_ext_res_meta *meta, u64 gpu_addr)
2592*4882a593Smuzhiyun {
2593*4882a593Smuzhiyun 	struct kbase_ctx_ext_res_meta *walker;
2594*4882a593Smuzhiyun 	struct kbase_va_region *reg;
2595*4882a593Smuzhiyun 
2596*4882a593Smuzhiyun 	lockdep_assert_held(&kctx->reg_lock);
2597*4882a593Smuzhiyun 
2598*4882a593Smuzhiyun 	/* Search of the metadata if one isn't provided. */
2599*4882a593Smuzhiyun 	if (!meta) {
2600*4882a593Smuzhiyun 		/*
2601*4882a593Smuzhiyun 		 * Walk the per context external resource metadata list for the
2602*4882a593Smuzhiyun 		 * metadata which matches the region which is being released.
2603*4882a593Smuzhiyun 		 */
2604*4882a593Smuzhiyun 		list_for_each_entry(walker, &kctx->ext_res_meta_head,
2605*4882a593Smuzhiyun 				ext_res_node) {
2606*4882a593Smuzhiyun 			if (walker->gpu_addr == gpu_addr) {
2607*4882a593Smuzhiyun 				meta = walker;
2608*4882a593Smuzhiyun 				break;
2609*4882a593Smuzhiyun 			}
2610*4882a593Smuzhiyun 		}
2611*4882a593Smuzhiyun 	}
2612*4882a593Smuzhiyun 
2613*4882a593Smuzhiyun 	/* No metadata so just return. */
2614*4882a593Smuzhiyun 	if (!meta)
2615*4882a593Smuzhiyun 		return false;
2616*4882a593Smuzhiyun 
2617*4882a593Smuzhiyun 	/* Drop the physical memory reference and free the metadata. */
2618*4882a593Smuzhiyun 	reg = kbase_region_tracker_find_region_enclosing_address(
2619*4882a593Smuzhiyun 			kctx,
2620*4882a593Smuzhiyun 			meta->gpu_addr);
2621*4882a593Smuzhiyun 
2622*4882a593Smuzhiyun 	kbase_unmap_external_resource(kctx, reg, meta->alloc);
2623*4882a593Smuzhiyun 	list_del(&meta->ext_res_node);
2624*4882a593Smuzhiyun 	kfree(meta);
2625*4882a593Smuzhiyun 
2626*4882a593Smuzhiyun 	return true;
2627*4882a593Smuzhiyun }
2628*4882a593Smuzhiyun 
kbase_sticky_resource_init(struct kbase_context * kctx)2629*4882a593Smuzhiyun int kbase_sticky_resource_init(struct kbase_context *kctx)
2630*4882a593Smuzhiyun {
2631*4882a593Smuzhiyun 	INIT_LIST_HEAD(&kctx->ext_res_meta_head);
2632*4882a593Smuzhiyun 
2633*4882a593Smuzhiyun 	return 0;
2634*4882a593Smuzhiyun }
2635*4882a593Smuzhiyun 
kbase_sticky_resource_term(struct kbase_context * kctx)2636*4882a593Smuzhiyun void kbase_sticky_resource_term(struct kbase_context *kctx)
2637*4882a593Smuzhiyun {
2638*4882a593Smuzhiyun 	struct kbase_ctx_ext_res_meta *walker;
2639*4882a593Smuzhiyun 
2640*4882a593Smuzhiyun 	lockdep_assert_held(&kctx->reg_lock);
2641*4882a593Smuzhiyun 
2642*4882a593Smuzhiyun 	/*
2643*4882a593Smuzhiyun 	 * Free any sticky resources which haven't been unmapped.
2644*4882a593Smuzhiyun 	 *
2645*4882a593Smuzhiyun 	 * Note:
2646*4882a593Smuzhiyun 	 * We don't care about refcounts at this point as no future
2647*4882a593Smuzhiyun 	 * references to the meta data will be made.
2648*4882a593Smuzhiyun 	 * Region termination would find these if we didn't free them
2649*4882a593Smuzhiyun 	 * here, but it's more efficient if we do the clean up here.
2650*4882a593Smuzhiyun 	 */
2651*4882a593Smuzhiyun 	while (!list_empty(&kctx->ext_res_meta_head)) {
2652*4882a593Smuzhiyun 		walker = list_first_entry(&kctx->ext_res_meta_head,
2653*4882a593Smuzhiyun 				struct kbase_ctx_ext_res_meta, ext_res_node);
2654*4882a593Smuzhiyun 
2655*4882a593Smuzhiyun 		kbase_sticky_resource_release(kctx, walker, 0);
2656*4882a593Smuzhiyun 	}
2657*4882a593Smuzhiyun }
2658