1 // SPDX-License-Identifier: GPL-2.0
2 
3 /*
4  * Copyright 2016-2019 HabanaLabs, Ltd.
5  * All Rights Reserved.
6  */
7 
8 #include "habanalabs.h"
9 
10 #include <linux/slab.h>
11 
hl_asid_init(struct hl_device * hdev)12 int hl_asid_init(struct hl_device *hdev)
13 {
14 	hdev->asid_bitmap = bitmap_zalloc(hdev->asic_prop.max_asid, GFP_KERNEL);
15 	if (!hdev->asid_bitmap)
16 		return -ENOMEM;
17 
18 	mutex_init(&hdev->asid_mutex);
19 
20 	/* ASID 0 is reserved for the kernel driver and device CPU */
21 	set_bit(0, hdev->asid_bitmap);
22 
23 	return 0;
24 }
25 
hl_asid_fini(struct hl_device * hdev)26 void hl_asid_fini(struct hl_device *hdev)
27 {
28 	mutex_destroy(&hdev->asid_mutex);
29 	bitmap_free(hdev->asid_bitmap);
30 }
31 
hl_asid_alloc(struct hl_device * hdev)32 unsigned long hl_asid_alloc(struct hl_device *hdev)
33 {
34 	unsigned long found;
35 
36 	mutex_lock(&hdev->asid_mutex);
37 
38 	found = find_first_zero_bit(hdev->asid_bitmap,
39 					hdev->asic_prop.max_asid);
40 	if (found == hdev->asic_prop.max_asid)
41 		found = 0;
42 	else
43 		set_bit(found, hdev->asid_bitmap);
44 
45 	mutex_unlock(&hdev->asid_mutex);
46 
47 	return found;
48 }
49 
hl_asid_free(struct hl_device * hdev,unsigned long asid)50 void hl_asid_free(struct hl_device *hdev, unsigned long asid)
51 {
52 	if (asid == HL_KERNEL_ASID_ID || asid >= hdev->asic_prop.max_asid) {
53 		dev_crit(hdev->dev, "Invalid ASID %lu", asid);
54 		return;
55 	}
56 
57 	clear_bit(asid, hdev->asid_bitmap);
58 }
59