xref: /linux/drivers/gpu/drm/xe/xe_sriov_pf.c (revision 53597deca0e38c30e6cd4ba2114fa42d2bcd85bb)
1 // SPDX-License-Identifier: MIT
2 /*
3  * Copyright © 2023-2024 Intel Corporation
4  */
5 
6 #include <linux/debugfs.h>
7 #include <drm/drm_debugfs.h>
8 #include <drm/drm_managed.h>
9 
10 #include "xe_assert.h"
11 #include "xe_configfs.h"
12 #include "xe_device.h"
13 #include "xe_gt_sriov_pf.h"
14 #include "xe_module.h"
15 #include "xe_sriov.h"
16 #include "xe_sriov_pf.h"
17 #include "xe_sriov_pf_helpers.h"
18 #include "xe_sriov_pf_migration.h"
19 #include "xe_sriov_pf_service.h"
20 #include "xe_sriov_pf_sysfs.h"
21 #include "xe_sriov_printk.h"
22 
23 static bool wanted_admin_only(struct xe_device *xe)
24 {
25 	return xe_configfs_admin_only_pf(to_pci_dev(xe->drm.dev));
26 }
27 
28 static unsigned int wanted_max_vfs(struct xe_device *xe)
29 {
30 	return xe_configfs_get_max_vfs(to_pci_dev(xe->drm.dev));
31 }
32 
33 static int pf_reduce_totalvfs(struct xe_device *xe, int limit)
34 {
35 	struct device *dev = xe->drm.dev;
36 	struct pci_dev *pdev = to_pci_dev(dev);
37 	int err;
38 
39 	err = pci_sriov_set_totalvfs(pdev, limit);
40 	if (err)
41 		xe_sriov_notice(xe, "Failed to set number of VFs to %d (%pe)\n",
42 				limit, ERR_PTR(err));
43 	return err;
44 }
45 
46 static bool pf_continue_as_native(struct xe_device *xe, const char *why)
47 {
48 	xe_sriov_dbg(xe, "%s, continuing as native\n", why);
49 	pf_reduce_totalvfs(xe, 0);
50 	return false;
51 }
52 
53 /**
54  * xe_sriov_pf_readiness - Check if PF functionality can be enabled.
55  * @xe: the &xe_device to check
56  *
57  * This function is called as part of the SR-IOV probe to validate if all
58  * PF prerequisites are satisfied and we can continue with enabling PF mode.
59  *
60  * Return: true if the PF mode can be turned on.
61  */
62 bool xe_sriov_pf_readiness(struct xe_device *xe)
63 {
64 	struct device *dev = xe->drm.dev;
65 	struct pci_dev *pdev = to_pci_dev(dev);
66 	int totalvfs = pci_sriov_get_totalvfs(pdev);
67 	int newlimit = min_t(u16, wanted_max_vfs(xe), totalvfs);
68 
69 	xe_assert(xe, totalvfs <= U16_MAX);
70 
71 	if (!dev_is_pf(dev))
72 		return false;
73 
74 	if (!xe_device_uc_enabled(xe))
75 		return pf_continue_as_native(xe, "Guc submission disabled");
76 
77 	if (!newlimit)
78 		return pf_continue_as_native(xe, "all VFs disabled");
79 
80 	pf_reduce_totalvfs(xe, newlimit);
81 
82 	xe->sriov.pf.admin_only = wanted_admin_only(xe);
83 	xe->sriov.pf.device_total_vfs = totalvfs;
84 	xe->sriov.pf.driver_max_vfs = newlimit;
85 
86 	return true;
87 }
88 
89 /**
90  * xe_sriov_pf_init_early - Initialize SR-IOV PF specific data.
91  * @xe: the &xe_device to initialize
92  *
93  * Return: 0 on success or a negative error code on failure.
94  */
95 int xe_sriov_pf_init_early(struct xe_device *xe)
96 {
97 	int err;
98 
99 	xe_assert(xe, IS_SRIOV_PF(xe));
100 
101 	xe->sriov.pf.vfs = drmm_kcalloc(&xe->drm, 1 + xe_sriov_pf_get_totalvfs(xe),
102 					sizeof(*xe->sriov.pf.vfs), GFP_KERNEL);
103 	if (!xe->sriov.pf.vfs)
104 		return -ENOMEM;
105 
106 	err = drmm_mutex_init(&xe->drm, &xe->sriov.pf.master_lock);
107 	if (err)
108 		return err;
109 
110 	err = xe_sriov_pf_migration_init(xe);
111 	if (err)
112 		return err;
113 
114 	xe_guard_init(&xe->sriov.pf.guard_vfs_enabling, "vfs_enabling");
115 
116 	xe_sriov_pf_service_init(xe);
117 
118 	xe_mert_init_early(xe);
119 
120 	return 0;
121 }
122 
123 /**
124  * xe_sriov_pf_init_late() - Late initialization of the SR-IOV PF.
125  * @xe: the &xe_device to initialize
126  *
127  * This function can only be called on PF.
128  *
129  * Return: 0 on success or a negative error code on failure.
130  */
131 int xe_sriov_pf_init_late(struct xe_device *xe)
132 {
133 	struct xe_gt *gt;
134 	unsigned int id;
135 	int err;
136 
137 	xe_assert(xe, IS_SRIOV_PF(xe));
138 
139 	for_each_gt(gt, xe, id) {
140 		err = xe_gt_sriov_pf_init(gt);
141 		if (err)
142 			return err;
143 	}
144 
145 	err = xe_sriov_pf_sysfs_init(xe);
146 	if (err)
147 		return err;
148 
149 	return 0;
150 }
151 
152 /**
153  * xe_sriov_pf_wait_ready() - Wait until PF is ready to operate.
154  * @xe: the &xe_device to test
155  *
156  * This function can only be called on PF.
157  *
158  * Return: 0 on success or a negative error code on failure.
159  */
160 int xe_sriov_pf_wait_ready(struct xe_device *xe)
161 {
162 	struct xe_gt *gt;
163 	unsigned int id;
164 	int err;
165 
166 	if (xe_device_wedged(xe))
167 		return -ECANCELED;
168 
169 	for_each_gt(gt, xe, id) {
170 		err = xe_gt_sriov_pf_wait_ready(gt);
171 		if (err)
172 			return err;
173 	}
174 
175 	return 0;
176 }
177 
178 /**
179  * xe_sriov_pf_arm_guard() - Arm the guard for exclusive/lockdown mode.
180  * @xe: the PF &xe_device
181  * @guard: the &xe_guard to arm
182  * @lockdown: arm for lockdown(true) or exclusive(false) mode
183  * @who: the address of the new owner, or NULL if it's a caller
184  *
185  * This function can only be called on PF.
186  *
187  * It is a simple wrapper for xe_guard_arm() with additional debug
188  * messages.
189  *
190  * Return: 0 on success or a negative error code on failure.
191  */
192 int xe_sriov_pf_arm_guard(struct xe_device *xe, struct xe_guard *guard,
193 			  bool lockdown, void *who)
194 {
195 	void *new_owner = who ?: __builtin_return_address(0);
196 	int err;
197 
198 	err = xe_guard_arm(guard, lockdown, new_owner);
199 	if (err) {
200 		xe_sriov_dbg(xe, "%s/%s mode denied (%pe) last owner %ps\n",
201 			     guard->name, xe_guard_mode_str(lockdown),
202 			     ERR_PTR(err), guard->owner);
203 		return err;
204 	}
205 
206 	xe_sriov_dbg_verbose(xe, "%s/%s by %ps\n",
207 			     guard->name, xe_guard_mode_str(lockdown),
208 			     new_owner);
209 	return 0;
210 }
211 
212 /**
213  * xe_sriov_pf_disarm_guard() - Disarm the guard.
214  * @xe: the PF &xe_device
215  * @guard: the &xe_guard to disarm
216  * @lockdown: disarm from lockdown(true) or exclusive(false) mode
217  * @who: the address of the indirect owner, or NULL if it's a caller
218  *
219  * This function can only be called on PF.
220  *
221  * It is a simple wrapper for xe_guard_disarm() with additional debug
222  * messages and xe_assert() to easily catch any illegal calls.
223  */
224 void xe_sriov_pf_disarm_guard(struct xe_device *xe, struct xe_guard *guard,
225 			      bool lockdown, void *who)
226 {
227 	bool disarmed;
228 
229 	xe_sriov_dbg_verbose(xe, "%s/%s by %ps\n",
230 			     guard->name, xe_guard_mode_str(lockdown),
231 			     who ?: __builtin_return_address(0));
232 
233 	disarmed = xe_guard_disarm(guard, lockdown);
234 	xe_assert_msg(xe, disarmed, "%s/%s not armed? last owner %ps",
235 		      guard->name, xe_guard_mode_str(lockdown), guard->owner);
236 }
237 
238 /**
239  * xe_sriov_pf_lockdown() - Lockdown the PF to prevent VFs enabling.
240  * @xe: the PF &xe_device
241  *
242  * This function can only be called on PF.
243  *
244  * Once the PF is locked down, it will not enable VFs.
245  * If VFs are already enabled, the -EBUSY will be returned.
246  * To allow the PF enable VFs again call xe_sriov_pf_end_lockdown().
247  *
248  * Return: 0 on success or a negative error code on failure.
249  */
250 int xe_sriov_pf_lockdown(struct xe_device *xe)
251 {
252 	xe_assert(xe, IS_SRIOV_PF(xe));
253 
254 	return xe_sriov_pf_arm_guard(xe, &xe->sriov.pf.guard_vfs_enabling, true,
255 				     __builtin_return_address(0));
256 }
257 
258 /**
259  * xe_sriov_pf_end_lockdown() - Allow the PF to enable VFs again.
260  * @xe: the PF &xe_device
261  *
262  * This function can only be called on PF.
263  * See xe_sriov_pf_lockdown() for details.
264  */
265 void xe_sriov_pf_end_lockdown(struct xe_device *xe)
266 {
267 	xe_assert(xe, IS_SRIOV_PF(xe));
268 
269 	xe_sriov_pf_disarm_guard(xe, &xe->sriov.pf.guard_vfs_enabling, true,
270 				 __builtin_return_address(0));
271 }
272 
273 /**
274  * xe_sriov_pf_print_vfs_summary - Print SR-IOV PF information.
275  * @xe: the &xe_device to print info from
276  * @p: the &drm_printer
277  *
278  * Print SR-IOV PF related information into provided DRM printer.
279  */
280 void xe_sriov_pf_print_vfs_summary(struct xe_device *xe, struct drm_printer *p)
281 {
282 	struct pci_dev *pdev = to_pci_dev(xe->drm.dev);
283 
284 	xe_assert(xe, IS_SRIOV_PF(xe));
285 
286 	drm_printf(p, "total: %u\n", xe->sriov.pf.device_total_vfs);
287 	drm_printf(p, "supported: %u\n", xe->sriov.pf.driver_max_vfs);
288 	drm_printf(p, "enabled: %u\n", pci_num_vf(pdev));
289 }
290