xref: /linux/drivers/cxl/core/memdev.c (revision 2ed519c21bb4fbac5d544ef4b1f98d515b18036d)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /* Copyright(c) 2020 Intel Corporation. */
3 
4 #include <linux/io-64-nonatomic-lo-hi.h>
5 #include <linux/firmware.h>
6 #include <linux/device.h>
7 #include <linux/slab.h>
8 #include <linux/idr.h>
9 #include <linux/pci.h>
10 #include <cxlmem.h>
11 #include "trace.h"
12 #include "core.h"
13 
14 static DECLARE_RWSEM(cxl_memdev_rwsem);
15 
16 /*
17  * An entire PCI topology full of devices should be enough for any
18  * config
19  */
20 #define CXL_MEM_MAX_DEVS 65536
21 
22 static int cxl_mem_major;
23 static DEFINE_IDA(cxl_memdev_ida);
24 
25 static void cxl_memdev_release(struct device *dev)
26 {
27 	struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
28 	struct device *parent = dev->parent;
29 
30 	ida_free(&cxl_memdev_ida, cxlmd->id);
31 	kfree(cxlmd);
32 	put_device(parent);
33 }
34 
35 static char *cxl_memdev_devnode(const struct device *dev, umode_t *mode, kuid_t *uid,
36 				kgid_t *gid)
37 {
38 	return kasprintf(GFP_KERNEL, "cxl/%s", dev_name(dev));
39 }
40 
41 static ssize_t firmware_version_show(struct device *dev,
42 				     struct device_attribute *attr, char *buf)
43 {
44 	struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
45 	struct cxl_dev_state *cxlds = cxlmd->cxlds;
46 	struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlds);
47 
48 	if (!mds)
49 		return sysfs_emit(buf, "\n");
50 	return sysfs_emit(buf, "%.16s\n", mds->firmware_version);
51 }
52 static DEVICE_ATTR_RO(firmware_version);
53 
54 static ssize_t payload_max_show(struct device *dev,
55 				struct device_attribute *attr, char *buf)
56 {
57 	struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
58 	struct cxl_dev_state *cxlds = cxlmd->cxlds;
59 	struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlds);
60 
61 	if (!mds)
62 		return sysfs_emit(buf, "\n");
63 	return sysfs_emit(buf, "%zu\n", cxlds->cxl_mbox.payload_size);
64 }
65 static DEVICE_ATTR_RO(payload_max);
66 
67 static ssize_t label_storage_size_show(struct device *dev,
68 				       struct device_attribute *attr, char *buf)
69 {
70 	struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
71 	struct cxl_dev_state *cxlds = cxlmd->cxlds;
72 	struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlds);
73 
74 	if (!mds)
75 		return sysfs_emit(buf, "\n");
76 	return sysfs_emit(buf, "%zu\n", mds->lsa_size);
77 }
78 static DEVICE_ATTR_RO(label_storage_size);
79 
80 static resource_size_t cxl_ram_size(struct cxl_dev_state *cxlds)
81 {
82 	/* Static RAM is only expected at partition 0. */
83 	if (cxlds->part[0].mode != CXL_PARTMODE_RAM)
84 		return 0;
85 	return resource_size(&cxlds->part[0].res);
86 }
87 
88 static ssize_t ram_size_show(struct device *dev, struct device_attribute *attr,
89 			     char *buf)
90 {
91 	struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
92 	struct cxl_dev_state *cxlds = cxlmd->cxlds;
93 	unsigned long long len = cxl_ram_size(cxlds);
94 
95 	return sysfs_emit(buf, "%#llx\n", len);
96 }
97 
98 static struct device_attribute dev_attr_ram_size =
99 	__ATTR(size, 0444, ram_size_show, NULL);
100 
101 static ssize_t pmem_size_show(struct device *dev, struct device_attribute *attr,
102 			      char *buf)
103 {
104 	struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
105 	struct cxl_dev_state *cxlds = cxlmd->cxlds;
106 	unsigned long long len = cxl_pmem_size(cxlds);
107 
108 	return sysfs_emit(buf, "%#llx\n", len);
109 }
110 
111 static struct device_attribute dev_attr_pmem_size =
112 	__ATTR(size, 0444, pmem_size_show, NULL);
113 
114 static ssize_t serial_show(struct device *dev, struct device_attribute *attr,
115 			   char *buf)
116 {
117 	struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
118 	struct cxl_dev_state *cxlds = cxlmd->cxlds;
119 
120 	return sysfs_emit(buf, "%#llx\n", cxlds->serial);
121 }
122 static DEVICE_ATTR_RO(serial);
123 
124 static ssize_t numa_node_show(struct device *dev, struct device_attribute *attr,
125 			      char *buf)
126 {
127 	return sysfs_emit(buf, "%d\n", dev_to_node(dev));
128 }
129 static DEVICE_ATTR_RO(numa_node);
130 
131 static ssize_t security_state_show(struct device *dev,
132 				   struct device_attribute *attr,
133 				   char *buf)
134 {
135 	struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
136 	struct cxl_dev_state *cxlds = cxlmd->cxlds;
137 	struct cxl_mailbox *cxl_mbox = &cxlds->cxl_mbox;
138 	struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlds);
139 	unsigned long state = mds->security.state;
140 	int rc = 0;
141 
142 	/* sync with latest submission state */
143 	mutex_lock(&cxl_mbox->mbox_mutex);
144 	if (mds->security.sanitize_active)
145 		rc = sysfs_emit(buf, "sanitize\n");
146 	mutex_unlock(&cxl_mbox->mbox_mutex);
147 	if (rc)
148 		return rc;
149 
150 	if (!(state & CXL_PMEM_SEC_STATE_USER_PASS_SET))
151 		return sysfs_emit(buf, "disabled\n");
152 	if (state & CXL_PMEM_SEC_STATE_FROZEN ||
153 	    state & CXL_PMEM_SEC_STATE_MASTER_PLIMIT ||
154 	    state & CXL_PMEM_SEC_STATE_USER_PLIMIT)
155 		return sysfs_emit(buf, "frozen\n");
156 	if (state & CXL_PMEM_SEC_STATE_LOCKED)
157 		return sysfs_emit(buf, "locked\n");
158 
159 	return sysfs_emit(buf, "unlocked\n");
160 }
161 static struct device_attribute dev_attr_security_state =
162 	__ATTR(state, 0444, security_state_show, NULL);
163 
164 static ssize_t security_sanitize_store(struct device *dev,
165 				       struct device_attribute *attr,
166 				       const char *buf, size_t len)
167 {
168 	struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
169 	bool sanitize;
170 	ssize_t rc;
171 
172 	if (kstrtobool(buf, &sanitize) || !sanitize)
173 		return -EINVAL;
174 
175 	rc = cxl_mem_sanitize(cxlmd, CXL_MBOX_OP_SANITIZE);
176 	if (rc)
177 		return rc;
178 
179 	return len;
180 }
181 static struct device_attribute dev_attr_security_sanitize =
182 	__ATTR(sanitize, 0200, NULL, security_sanitize_store);
183 
184 static ssize_t security_erase_store(struct device *dev,
185 				    struct device_attribute *attr,
186 				    const char *buf, size_t len)
187 {
188 	struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
189 	ssize_t rc;
190 	bool erase;
191 
192 	if (kstrtobool(buf, &erase) || !erase)
193 		return -EINVAL;
194 
195 	rc = cxl_mem_sanitize(cxlmd, CXL_MBOX_OP_SECURE_ERASE);
196 	if (rc)
197 		return rc;
198 
199 	return len;
200 }
201 static struct device_attribute dev_attr_security_erase =
202 	__ATTR(erase, 0200, NULL, security_erase_store);
203 
204 bool cxl_memdev_has_poison_cmd(struct cxl_memdev *cxlmd,
205 			       enum poison_cmd_enabled_bits cmd)
206 {
207 	struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlmd->cxlds);
208 
209 	if (!mds)
210 		return 0;
211 
212 	return test_bit(cmd, mds->poison.enabled_cmds);
213 }
214 
215 static int cxl_get_poison_by_memdev(struct cxl_memdev *cxlmd)
216 {
217 	struct cxl_dev_state *cxlds = cxlmd->cxlds;
218 	u64 offset, length;
219 	int rc = 0;
220 
221 	/* CXL 3.0 Spec 8.2.9.8.4.1 Separate pmem and ram poison requests */
222 	for (int i = 0; i < cxlds->nr_partitions; i++) {
223 		const struct resource *res = &cxlds->part[i].res;
224 
225 		offset = res->start;
226 		length = resource_size(res);
227 		rc = cxl_mem_get_poison(cxlmd, offset, length, NULL);
228 		/*
229 		 * Invalid Physical Address is not an error for
230 		 * volatile addresses. Device support is optional.
231 		 */
232 		if (rc == -EFAULT && cxlds->part[i].mode == CXL_PARTMODE_RAM)
233 			rc = 0;
234 	}
235 	return rc;
236 }
237 
238 int cxl_trigger_poison_list(struct cxl_memdev *cxlmd)
239 {
240 	struct cxl_port *port;
241 	int rc;
242 
243 	port = cxlmd->endpoint;
244 	if (!port || !is_cxl_endpoint(port))
245 		return -EINVAL;
246 
247 	ACQUIRE(rwsem_read_intr, region_rwsem)(&cxl_rwsem.region);
248 	if ((rc = ACQUIRE_ERR(rwsem_read_intr, &region_rwsem)))
249 		return rc;
250 
251 	ACQUIRE(rwsem_read_intr, dpa_rwsem)(&cxl_rwsem.dpa);
252 	if ((rc = ACQUIRE_ERR(rwsem_read_intr, &dpa_rwsem)))
253 		return rc;
254 
255 	if (cxl_num_decoders_committed(port) == 0) {
256 		/* No regions mapped to this memdev */
257 		rc = cxl_get_poison_by_memdev(cxlmd);
258 	} else {
259 		/* Regions mapped, collect poison by endpoint */
260 		rc =  cxl_get_poison_by_endpoint(port);
261 	}
262 
263 	return rc;
264 }
265 EXPORT_SYMBOL_NS_GPL(cxl_trigger_poison_list, "CXL");
266 
267 static int cxl_validate_poison_dpa(struct cxl_memdev *cxlmd, u64 dpa)
268 {
269 	struct cxl_dev_state *cxlds = cxlmd->cxlds;
270 
271 	if (!IS_ENABLED(CONFIG_DEBUG_FS))
272 		return 0;
273 
274 	if (!resource_size(&cxlds->dpa_res)) {
275 		dev_dbg(cxlds->dev, "device has no dpa resource\n");
276 		return -EINVAL;
277 	}
278 	if (!cxl_resource_contains_addr(&cxlds->dpa_res, dpa)) {
279 		dev_dbg(cxlds->dev, "dpa:0x%llx not in resource:%pR\n",
280 			dpa, &cxlds->dpa_res);
281 		return -EINVAL;
282 	}
283 	if (!IS_ALIGNED(dpa, 64)) {
284 		dev_dbg(cxlds->dev, "dpa:0x%llx is not 64-byte aligned\n", dpa);
285 		return -EINVAL;
286 	}
287 
288 	return 0;
289 }
290 
291 int cxl_inject_poison_locked(struct cxl_memdev *cxlmd, u64 dpa)
292 {
293 	struct cxl_mailbox *cxl_mbox = &cxlmd->cxlds->cxl_mbox;
294 	struct cxl_mbox_inject_poison inject;
295 	struct cxl_poison_record record;
296 	struct cxl_mbox_cmd mbox_cmd;
297 	struct cxl_region *cxlr;
298 	int rc;
299 
300 	if (!IS_ENABLED(CONFIG_DEBUG_FS))
301 		return 0;
302 
303 	lockdep_assert_held(&cxl_rwsem.dpa);
304 	lockdep_assert_held(&cxl_rwsem.region);
305 
306 	rc = cxl_validate_poison_dpa(cxlmd, dpa);
307 	if (rc)
308 		return rc;
309 
310 	inject.address = cpu_to_le64(dpa);
311 	mbox_cmd = (struct cxl_mbox_cmd) {
312 		.opcode = CXL_MBOX_OP_INJECT_POISON,
313 		.size_in = sizeof(inject),
314 		.payload_in = &inject,
315 	};
316 	rc = cxl_internal_send_cmd(cxl_mbox, &mbox_cmd);
317 	if (rc)
318 		return rc;
319 
320 	cxlr = cxl_dpa_to_region(cxlmd, dpa);
321 	if (cxlr)
322 		dev_warn_once(cxl_mbox->host,
323 			      "poison inject dpa:%#llx region: %s\n", dpa,
324 			      dev_name(&cxlr->dev));
325 
326 	record = (struct cxl_poison_record) {
327 		.address = cpu_to_le64(dpa),
328 		.length = cpu_to_le32(1),
329 	};
330 	trace_cxl_poison(cxlmd, cxlr, &record, 0, 0, CXL_POISON_TRACE_INJECT);
331 
332 	return 0;
333 }
334 
335 int cxl_inject_poison(struct cxl_memdev *cxlmd, u64 dpa)
336 {
337 	int rc;
338 
339 	ACQUIRE(rwsem_read_intr, region_rwsem)(&cxl_rwsem.region);
340 	if ((rc = ACQUIRE_ERR(rwsem_read_intr, &region_rwsem)))
341 		return rc;
342 
343 	ACQUIRE(rwsem_read_intr, dpa_rwsem)(&cxl_rwsem.dpa);
344 	if ((rc = ACQUIRE_ERR(rwsem_read_intr, &dpa_rwsem)))
345 		return rc;
346 
347 	return cxl_inject_poison_locked(cxlmd, dpa);
348 }
349 EXPORT_SYMBOL_NS_GPL(cxl_inject_poison, "CXL");
350 
351 int cxl_clear_poison_locked(struct cxl_memdev *cxlmd, u64 dpa)
352 {
353 	struct cxl_mailbox *cxl_mbox = &cxlmd->cxlds->cxl_mbox;
354 	struct cxl_mbox_clear_poison clear;
355 	struct cxl_poison_record record;
356 	struct cxl_mbox_cmd mbox_cmd;
357 	struct cxl_region *cxlr;
358 	int rc;
359 
360 	if (!IS_ENABLED(CONFIG_DEBUG_FS))
361 		return 0;
362 
363 	lockdep_assert_held(&cxl_rwsem.dpa);
364 	lockdep_assert_held(&cxl_rwsem.region);
365 
366 	rc = cxl_validate_poison_dpa(cxlmd, dpa);
367 	if (rc)
368 		return rc;
369 
370 	/*
371 	 * In CXL 3.0 Spec 8.2.9.8.4.3, the Clear Poison mailbox command
372 	 * is defined to accept 64 bytes of write-data, along with the
373 	 * address to clear. This driver uses zeroes as write-data.
374 	 */
375 	clear = (struct cxl_mbox_clear_poison) {
376 		.address = cpu_to_le64(dpa)
377 	};
378 
379 	mbox_cmd = (struct cxl_mbox_cmd) {
380 		.opcode = CXL_MBOX_OP_CLEAR_POISON,
381 		.size_in = sizeof(clear),
382 		.payload_in = &clear,
383 	};
384 
385 	rc = cxl_internal_send_cmd(cxl_mbox, &mbox_cmd);
386 	if (rc)
387 		return rc;
388 
389 	cxlr = cxl_dpa_to_region(cxlmd, dpa);
390 	if (cxlr)
391 		dev_warn_once(cxl_mbox->host,
392 			      "poison clear dpa:%#llx region: %s\n", dpa,
393 			      dev_name(&cxlr->dev));
394 
395 	record = (struct cxl_poison_record) {
396 		.address = cpu_to_le64(dpa),
397 		.length = cpu_to_le32(1),
398 	};
399 	trace_cxl_poison(cxlmd, cxlr, &record, 0, 0, CXL_POISON_TRACE_CLEAR);
400 
401 	return 0;
402 }
403 
404 int cxl_clear_poison(struct cxl_memdev *cxlmd, u64 dpa)
405 {
406 	int rc;
407 
408 	ACQUIRE(rwsem_read_intr, region_rwsem)(&cxl_rwsem.region);
409 	if ((rc = ACQUIRE_ERR(rwsem_read_intr, &region_rwsem)))
410 		return rc;
411 
412 	ACQUIRE(rwsem_read_intr, dpa_rwsem)(&cxl_rwsem.dpa);
413 	if ((rc = ACQUIRE_ERR(rwsem_read_intr, &dpa_rwsem)))
414 		return rc;
415 
416 	return cxl_clear_poison_locked(cxlmd, dpa);
417 }
418 EXPORT_SYMBOL_NS_GPL(cxl_clear_poison, "CXL");
419 
420 static struct attribute *cxl_memdev_attributes[] = {
421 	&dev_attr_serial.attr,
422 	&dev_attr_firmware_version.attr,
423 	&dev_attr_payload_max.attr,
424 	&dev_attr_label_storage_size.attr,
425 	&dev_attr_numa_node.attr,
426 	NULL,
427 };
428 
429 static struct cxl_dpa_perf *to_pmem_perf(struct cxl_dev_state *cxlds)
430 {
431 	for (int i = 0; i < cxlds->nr_partitions; i++)
432 		if (cxlds->part[i].mode == CXL_PARTMODE_PMEM)
433 			return &cxlds->part[i].perf;
434 	return NULL;
435 }
436 
437 static ssize_t pmem_qos_class_show(struct device *dev,
438 				   struct device_attribute *attr, char *buf)
439 {
440 	struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
441 	struct cxl_dev_state *cxlds = cxlmd->cxlds;
442 
443 	return sysfs_emit(buf, "%d\n", to_pmem_perf(cxlds)->qos_class);
444 }
445 
446 static struct device_attribute dev_attr_pmem_qos_class =
447 	__ATTR(qos_class, 0444, pmem_qos_class_show, NULL);
448 
449 static struct attribute *cxl_memdev_pmem_attributes[] = {
450 	&dev_attr_pmem_size.attr,
451 	&dev_attr_pmem_qos_class.attr,
452 	NULL,
453 };
454 
455 static struct cxl_dpa_perf *to_ram_perf(struct cxl_dev_state *cxlds)
456 {
457 	if (cxlds->part[0].mode != CXL_PARTMODE_RAM)
458 		return NULL;
459 	return &cxlds->part[0].perf;
460 }
461 
462 static ssize_t ram_qos_class_show(struct device *dev,
463 				  struct device_attribute *attr, char *buf)
464 {
465 	struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
466 	struct cxl_dev_state *cxlds = cxlmd->cxlds;
467 
468 	return sysfs_emit(buf, "%d\n", to_ram_perf(cxlds)->qos_class);
469 }
470 
471 static struct device_attribute dev_attr_ram_qos_class =
472 	__ATTR(qos_class, 0444, ram_qos_class_show, NULL);
473 
474 static struct attribute *cxl_memdev_ram_attributes[] = {
475 	&dev_attr_ram_size.attr,
476 	&dev_attr_ram_qos_class.attr,
477 	NULL,
478 };
479 
480 static struct attribute *cxl_memdev_security_attributes[] = {
481 	&dev_attr_security_state.attr,
482 	&dev_attr_security_sanitize.attr,
483 	&dev_attr_security_erase.attr,
484 	NULL,
485 };
486 
487 static umode_t cxl_memdev_visible(struct kobject *kobj, struct attribute *a,
488 				  int n)
489 {
490 	if (!IS_ENABLED(CONFIG_NUMA) && a == &dev_attr_numa_node.attr)
491 		return 0;
492 	return a->mode;
493 }
494 
495 static struct attribute_group cxl_memdev_attribute_group = {
496 	.attrs = cxl_memdev_attributes,
497 	.is_visible = cxl_memdev_visible,
498 };
499 
500 static umode_t cxl_ram_visible(struct kobject *kobj, struct attribute *a, int n)
501 {
502 	struct device *dev = kobj_to_dev(kobj);
503 	struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
504 	struct cxl_dpa_perf *perf = to_ram_perf(cxlmd->cxlds);
505 
506 	if (a == &dev_attr_ram_qos_class.attr &&
507 	    (!perf || perf->qos_class == CXL_QOS_CLASS_INVALID))
508 		return 0;
509 
510 	return a->mode;
511 }
512 
513 static struct attribute_group cxl_memdev_ram_attribute_group = {
514 	.name = "ram",
515 	.attrs = cxl_memdev_ram_attributes,
516 	.is_visible = cxl_ram_visible,
517 };
518 
519 static umode_t cxl_pmem_visible(struct kobject *kobj, struct attribute *a, int n)
520 {
521 	struct device *dev = kobj_to_dev(kobj);
522 	struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
523 	struct cxl_dpa_perf *perf = to_pmem_perf(cxlmd->cxlds);
524 
525 	if (a == &dev_attr_pmem_qos_class.attr &&
526 	    (!perf || perf->qos_class == CXL_QOS_CLASS_INVALID))
527 		return 0;
528 
529 	return a->mode;
530 }
531 
532 static struct attribute_group cxl_memdev_pmem_attribute_group = {
533 	.name = "pmem",
534 	.attrs = cxl_memdev_pmem_attributes,
535 	.is_visible = cxl_pmem_visible,
536 };
537 
538 static umode_t cxl_memdev_security_visible(struct kobject *kobj,
539 					   struct attribute *a, int n)
540 {
541 	struct device *dev = kobj_to_dev(kobj);
542 	struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
543 	struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlmd->cxlds);
544 
545 	if (a == &dev_attr_security_sanitize.attr &&
546 	    !test_bit(CXL_SEC_ENABLED_SANITIZE, mds->security.enabled_cmds))
547 		return 0;
548 
549 	if (a == &dev_attr_security_erase.attr &&
550 	    !test_bit(CXL_SEC_ENABLED_SECURE_ERASE, mds->security.enabled_cmds))
551 		return 0;
552 
553 	return a->mode;
554 }
555 
556 static struct attribute_group cxl_memdev_security_attribute_group = {
557 	.name = "security",
558 	.attrs = cxl_memdev_security_attributes,
559 	.is_visible = cxl_memdev_security_visible,
560 };
561 
562 static const struct attribute_group *cxl_memdev_attribute_groups[] = {
563 	&cxl_memdev_attribute_group,
564 	&cxl_memdev_ram_attribute_group,
565 	&cxl_memdev_pmem_attribute_group,
566 	&cxl_memdev_security_attribute_group,
567 	NULL,
568 };
569 
570 void cxl_memdev_update_perf(struct cxl_memdev *cxlmd)
571 {
572 	sysfs_update_group(&cxlmd->dev.kobj, &cxl_memdev_ram_attribute_group);
573 	sysfs_update_group(&cxlmd->dev.kobj, &cxl_memdev_pmem_attribute_group);
574 }
575 EXPORT_SYMBOL_NS_GPL(cxl_memdev_update_perf, "CXL");
576 
577 static const struct device_type cxl_class_memdev_type = {
578 	.name = "cxl_memdev",
579 	.release = cxl_memdev_release,
580 	.devnode = cxl_memdev_devnode,
581 	.groups = cxl_memdev_attribute_groups,
582 };
583 
584 static const struct device_type cxl_memdev_type = {
585 	.name = "cxl_memdev",
586 	.release = cxl_memdev_release,
587 	.devnode = cxl_memdev_devnode,
588 };
589 
590 bool is_cxl_memdev(const struct device *dev)
591 {
592 	return (dev->type == &cxl_class_memdev_type ||
593 		dev->type == &cxl_memdev_type);
594 }
595 EXPORT_SYMBOL_NS_GPL(is_cxl_memdev, "CXL");
596 
597 /**
598  * set_exclusive_cxl_commands() - atomically disable user cxl commands
599  * @mds: The device state to operate on
600  * @cmds: bitmap of commands to mark exclusive
601  *
602  * Grab the cxl_memdev_rwsem in write mode to flush in-flight
603  * invocations of the ioctl path and then disable future execution of
604  * commands with the command ids set in @cmds.
605  */
606 void set_exclusive_cxl_commands(struct cxl_memdev_state *mds,
607 				unsigned long *cmds)
608 {
609 	struct cxl_mailbox *cxl_mbox = &mds->cxlds.cxl_mbox;
610 
611 	guard(rwsem_write)(&cxl_memdev_rwsem);
612 	bitmap_or(cxl_mbox->exclusive_cmds, cxl_mbox->exclusive_cmds,
613 		  cmds, CXL_MEM_COMMAND_ID_MAX);
614 }
615 EXPORT_SYMBOL_NS_GPL(set_exclusive_cxl_commands, "CXL");
616 
617 /**
618  * clear_exclusive_cxl_commands() - atomically enable user cxl commands
619  * @mds: The device state to modify
620  * @cmds: bitmap of commands to mark available for userspace
621  */
622 void clear_exclusive_cxl_commands(struct cxl_memdev_state *mds,
623 				  unsigned long *cmds)
624 {
625 	struct cxl_mailbox *cxl_mbox = &mds->cxlds.cxl_mbox;
626 
627 	guard(rwsem_write)(&cxl_memdev_rwsem);
628 	bitmap_andnot(cxl_mbox->exclusive_cmds, cxl_mbox->exclusive_cmds,
629 		      cmds, CXL_MEM_COMMAND_ID_MAX);
630 }
631 EXPORT_SYMBOL_NS_GPL(clear_exclusive_cxl_commands, "CXL");
632 
633 static void cxl_memdev_shutdown(struct device *dev)
634 {
635 	struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
636 
637 	guard(rwsem_write)(&cxl_memdev_rwsem);
638 	cxlmd->cxlds = NULL;
639 }
640 
641 static void cxl_memdev_unregister(void *_cxlmd)
642 {
643 	struct cxl_memdev *cxlmd = _cxlmd;
644 	struct device *dev = &cxlmd->dev;
645 
646 	cdev_device_del(&cxlmd->cdev, dev);
647 	cxl_memdev_shutdown(dev);
648 	put_device(dev);
649 }
650 
651 static void detach_memdev(struct work_struct *work)
652 {
653 	struct cxl_memdev *cxlmd;
654 
655 	cxlmd = container_of(work, typeof(*cxlmd), detach_work);
656 
657 	/*
658 	 * When the creator of @cxlmd sets ->attach it indicates CXL operation
659 	 * is required. In that case, @cxlmd detach escalates to parent device
660 	 * detach.
661 	 */
662 	if (cxlmd->attach)
663 		device_release_driver(cxlmd->dev.parent);
664 	else
665 		device_release_driver(&cxlmd->dev);
666 	put_device(&cxlmd->dev);
667 }
668 
669 static struct lock_class_key cxl_memdev_key;
670 
671 struct cxl_dev_state *_devm_cxl_dev_state_create(struct device *dev,
672 						 enum cxl_devtype type,
673 						 u64 serial, u16 dvsec,
674 						 size_t size, bool has_mbox)
675 {
676 	struct cxl_dev_state *cxlds = devm_kzalloc(dev, size, GFP_KERNEL);
677 
678 	if (!cxlds)
679 		return NULL;
680 
681 	cxlds->dev = dev;
682 	cxlds->type = type;
683 	cxlds->serial = serial;
684 	cxlds->cxl_dvsec = dvsec;
685 	cxlds->reg_map.host = dev;
686 	cxlds->reg_map.resource = CXL_RESOURCE_NONE;
687 
688 	if (has_mbox)
689 		cxlds->cxl_mbox.host = dev;
690 
691 	return cxlds;
692 }
693 EXPORT_SYMBOL_NS_GPL(_devm_cxl_dev_state_create, "CXL");
694 
695 static struct cxl_memdev *cxl_memdev_alloc(struct cxl_dev_state *cxlds,
696 					   const struct file_operations *fops,
697 					   const struct cxl_memdev_attach *attach)
698 {
699 	struct cxl_memdev *cxlmd;
700 	struct device *dev;
701 	struct cdev *cdev;
702 	int rc;
703 
704 	cxlmd = kzalloc_obj(*cxlmd);
705 	if (!cxlmd)
706 		return ERR_PTR(-ENOMEM);
707 
708 	rc = ida_alloc_max(&cxl_memdev_ida, CXL_MEM_MAX_DEVS - 1, GFP_KERNEL);
709 	if (rc < 0)
710 		goto err;
711 	cxlmd->id = rc;
712 	cxlmd->depth = -1;
713 	cxlmd->attach = attach;
714 	cxlmd->endpoint = ERR_PTR(-ENXIO);
715 
716 	dev = &cxlmd->dev;
717 	device_initialize(dev);
718 	lockdep_set_class(&dev->mutex, &cxl_memdev_key);
719 	dev->parent = get_device(cxlds->dev);
720 	dev->bus = &cxl_bus_type;
721 	dev->devt = MKDEV(cxl_mem_major, cxlmd->id);
722 	if (cxlds->type == CXL_DEVTYPE_DEVMEM)
723 		dev->type = &cxl_memdev_type;
724 	else
725 		dev->type = &cxl_class_memdev_type;
726 	device_set_pm_not_required(dev);
727 	INIT_WORK(&cxlmd->detach_work, detach_memdev);
728 
729 	cdev = &cxlmd->cdev;
730 	cdev_init(cdev, fops);
731 	return cxlmd;
732 
733 err:
734 	kfree(cxlmd);
735 	return ERR_PTR(rc);
736 }
737 
738 static long __cxl_memdev_ioctl(struct cxl_memdev *cxlmd, unsigned int cmd,
739 			       unsigned long arg)
740 {
741 	struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlmd->cxlds);
742 	struct cxl_mailbox *cxl_mbox = &mds->cxlds.cxl_mbox;
743 
744 	switch (cmd) {
745 	case CXL_MEM_QUERY_COMMANDS:
746 		return cxl_query_cmd(cxl_mbox, (void __user *)arg);
747 	case CXL_MEM_SEND_COMMAND:
748 		return cxl_send_cmd(cxl_mbox, (void __user *)arg);
749 	default:
750 		return -ENOTTY;
751 	}
752 }
753 
754 static long cxl_memdev_ioctl(struct file *file, unsigned int cmd,
755 			     unsigned long arg)
756 {
757 	struct cxl_memdev *cxlmd = file->private_data;
758 	struct cxl_dev_state *cxlds;
759 
760 	guard(rwsem_read)(&cxl_memdev_rwsem);
761 	cxlds = cxlmd->cxlds;
762 	if (cxlds && cxlds->type == CXL_DEVTYPE_CLASSMEM)
763 		return __cxl_memdev_ioctl(cxlmd, cmd, arg);
764 
765 	return -ENXIO;
766 }
767 
768 static int cxl_memdev_open(struct inode *inode, struct file *file)
769 {
770 	struct cxl_memdev *cxlmd =
771 		container_of(inode->i_cdev, typeof(*cxlmd), cdev);
772 
773 	get_device(&cxlmd->dev);
774 	file->private_data = cxlmd;
775 
776 	return 0;
777 }
778 
779 static int cxl_memdev_release_file(struct inode *inode, struct file *file)
780 {
781 	struct cxl_memdev *cxlmd =
782 		container_of(inode->i_cdev, typeof(*cxlmd), cdev);
783 
784 	put_device(&cxlmd->dev);
785 
786 	return 0;
787 }
788 
789 /**
790  * cxl_mem_get_fw_info - Get Firmware info
791  * @mds: The device data for the operation
792  *
793  * Retrieve firmware info for the device specified.
794  *
795  * Return: 0 if no error: or the result of the mailbox command.
796  *
797  * See CXL-3.0 8.2.9.3.1 Get FW Info
798  */
799 static int cxl_mem_get_fw_info(struct cxl_memdev_state *mds)
800 {
801 	struct cxl_mailbox *cxl_mbox = &mds->cxlds.cxl_mbox;
802 	struct cxl_mbox_get_fw_info info;
803 	struct cxl_mbox_cmd mbox_cmd;
804 	int rc;
805 
806 	mbox_cmd = (struct cxl_mbox_cmd) {
807 		.opcode = CXL_MBOX_OP_GET_FW_INFO,
808 		.size_out = sizeof(info),
809 		.payload_out = &info,
810 	};
811 
812 	rc = cxl_internal_send_cmd(cxl_mbox, &mbox_cmd);
813 	if (rc < 0)
814 		return rc;
815 
816 	mds->fw.num_slots = info.num_slots;
817 	mds->fw.cur_slot = FIELD_GET(CXL_FW_INFO_SLOT_INFO_CUR_MASK,
818 				       info.slot_info);
819 
820 	return 0;
821 }
822 
823 /**
824  * cxl_mem_activate_fw - Activate Firmware
825  * @mds: The device data for the operation
826  * @slot: slot number to activate
827  *
828  * Activate firmware in a given slot for the device specified.
829  *
830  * Return: 0 if no error: or the result of the mailbox command.
831  *
832  * See CXL-3.0 8.2.9.3.3 Activate FW
833  */
834 static int cxl_mem_activate_fw(struct cxl_memdev_state *mds, int slot)
835 {
836 	struct cxl_mailbox *cxl_mbox = &mds->cxlds.cxl_mbox;
837 	struct cxl_mbox_activate_fw activate;
838 	struct cxl_mbox_cmd mbox_cmd;
839 
840 	if (slot == 0 || slot > mds->fw.num_slots)
841 		return -EINVAL;
842 
843 	mbox_cmd = (struct cxl_mbox_cmd) {
844 		.opcode = CXL_MBOX_OP_ACTIVATE_FW,
845 		.size_in = sizeof(activate),
846 		.payload_in = &activate,
847 	};
848 
849 	/* Only offline activation supported for now */
850 	activate.action = CXL_FW_ACTIVATE_OFFLINE;
851 	activate.slot = slot;
852 
853 	return cxl_internal_send_cmd(cxl_mbox, &mbox_cmd);
854 }
855 
856 /**
857  * cxl_mem_abort_fw_xfer - Abort an in-progress FW transfer
858  * @mds: The device data for the operation
859  *
860  * Abort an in-progress firmware transfer for the device specified.
861  *
862  * Return: 0 if no error: or the result of the mailbox command.
863  *
864  * See CXL-3.0 8.2.9.3.2 Transfer FW
865  */
866 static int cxl_mem_abort_fw_xfer(struct cxl_memdev_state *mds)
867 {
868 	struct cxl_mailbox *cxl_mbox = &mds->cxlds.cxl_mbox;
869 	struct cxl_mbox_transfer_fw *transfer;
870 	struct cxl_mbox_cmd mbox_cmd;
871 	int rc;
872 
873 	transfer = kzalloc_flex(*transfer, data, 0);
874 	if (!transfer)
875 		return -ENOMEM;
876 
877 	/* Set a 1s poll interval and a total wait time of 30s */
878 	mbox_cmd = (struct cxl_mbox_cmd) {
879 		.opcode = CXL_MBOX_OP_TRANSFER_FW,
880 		.size_in = sizeof(*transfer),
881 		.payload_in = transfer,
882 		.poll_interval_ms = 1000,
883 		.poll_count = 30,
884 	};
885 
886 	transfer->action = CXL_FW_TRANSFER_ACTION_ABORT;
887 
888 	rc = cxl_internal_send_cmd(cxl_mbox, &mbox_cmd);
889 	kfree(transfer);
890 	return rc;
891 }
892 
893 static void cxl_fw_cleanup(struct fw_upload *fwl)
894 {
895 	struct cxl_memdev_state *mds = fwl->dd_handle;
896 
897 	mds->fw.next_slot = 0;
898 }
899 
900 static int cxl_fw_do_cancel(struct fw_upload *fwl)
901 {
902 	struct cxl_memdev_state *mds = fwl->dd_handle;
903 	struct cxl_dev_state *cxlds = &mds->cxlds;
904 	struct cxl_memdev *cxlmd = cxlds->cxlmd;
905 	int rc;
906 
907 	rc = cxl_mem_abort_fw_xfer(mds);
908 	if (rc < 0)
909 		dev_err(&cxlmd->dev, "Error aborting FW transfer: %d\n", rc);
910 
911 	return FW_UPLOAD_ERR_CANCELED;
912 }
913 
914 static enum fw_upload_err cxl_fw_prepare(struct fw_upload *fwl, const u8 *data,
915 					 u32 size)
916 {
917 	struct cxl_memdev_state *mds = fwl->dd_handle;
918 	struct cxl_mbox_transfer_fw *transfer;
919 	struct cxl_mailbox *cxl_mbox = &mds->cxlds.cxl_mbox;
920 
921 	if (!size)
922 		return FW_UPLOAD_ERR_INVALID_SIZE;
923 
924 	mds->fw.oneshot = struct_size(transfer, data, size) <
925 			    cxl_mbox->payload_size;
926 
927 	if (cxl_mem_get_fw_info(mds))
928 		return FW_UPLOAD_ERR_HW_ERROR;
929 
930 	/*
931 	 * So far no state has been changed, hence no other cleanup is
932 	 * necessary. Simply return the cancelled status.
933 	 */
934 	if (test_and_clear_bit(CXL_FW_CANCEL, mds->fw.state))
935 		return FW_UPLOAD_ERR_CANCELED;
936 
937 	return FW_UPLOAD_ERR_NONE;
938 }
939 
940 static enum fw_upload_err cxl_fw_write(struct fw_upload *fwl, const u8 *data,
941 				       u32 offset, u32 size, u32 *written)
942 {
943 	struct cxl_memdev_state *mds = fwl->dd_handle;
944 	struct cxl_dev_state *cxlds = &mds->cxlds;
945 	struct cxl_mailbox *cxl_mbox = &cxlds->cxl_mbox;
946 	struct cxl_memdev *cxlmd = cxlds->cxlmd;
947 	struct cxl_mbox_transfer_fw *transfer;
948 	struct cxl_mbox_cmd mbox_cmd;
949 	u32 cur_size, remaining;
950 	size_t size_in;
951 	int rc;
952 
953 	*written = 0;
954 
955 	/* Offset has to be aligned to 128B (CXL-3.0 8.2.9.3.2 Table 8-57) */
956 	if (!IS_ALIGNED(offset, CXL_FW_TRANSFER_ALIGNMENT)) {
957 		dev_err(&cxlmd->dev,
958 			"misaligned offset for FW transfer slice (%u)\n",
959 			offset);
960 		return FW_UPLOAD_ERR_RW_ERROR;
961 	}
962 
963 	/*
964 	 * Pick transfer size based on mds->payload_size @size must bw 128-byte
965 	 * aligned, ->payload_size is a power of 2 starting at 256 bytes, and
966 	 * sizeof(*transfer) is 128.  These constraints imply that @cur_size
967 	 * will always be 128b aligned.
968 	 */
969 	cur_size = min_t(size_t, size, cxl_mbox->payload_size - sizeof(*transfer));
970 
971 	remaining = size - cur_size;
972 	size_in = struct_size(transfer, data, cur_size);
973 
974 	if (test_and_clear_bit(CXL_FW_CANCEL, mds->fw.state))
975 		return cxl_fw_do_cancel(fwl);
976 
977 	/*
978 	 * Slot numbers are 1-indexed
979 	 * cur_slot is the 0-indexed next_slot (i.e. 'cur_slot - 1 + 1')
980 	 * Check for rollover using modulo, and 1-index it by adding 1
981 	 */
982 	mds->fw.next_slot = (mds->fw.cur_slot % mds->fw.num_slots) + 1;
983 
984 	/* Do the transfer via mailbox cmd */
985 	transfer = kzalloc(size_in, GFP_KERNEL);
986 	if (!transfer)
987 		return FW_UPLOAD_ERR_RW_ERROR;
988 
989 	transfer->offset = cpu_to_le32(offset / CXL_FW_TRANSFER_ALIGNMENT);
990 	memcpy(transfer->data, data + offset, cur_size);
991 	if (mds->fw.oneshot) {
992 		transfer->action = CXL_FW_TRANSFER_ACTION_FULL;
993 		transfer->slot = mds->fw.next_slot;
994 	} else {
995 		if (offset == 0) {
996 			transfer->action = CXL_FW_TRANSFER_ACTION_INITIATE;
997 		} else if (remaining == 0) {
998 			transfer->action = CXL_FW_TRANSFER_ACTION_END;
999 			transfer->slot = mds->fw.next_slot;
1000 		} else {
1001 			transfer->action = CXL_FW_TRANSFER_ACTION_CONTINUE;
1002 		}
1003 	}
1004 
1005 	mbox_cmd = (struct cxl_mbox_cmd) {
1006 		.opcode = CXL_MBOX_OP_TRANSFER_FW,
1007 		.size_in = size_in,
1008 		.payload_in = transfer,
1009 		.poll_interval_ms = 1000,
1010 		.poll_count = 30,
1011 	};
1012 
1013 	rc = cxl_internal_send_cmd(cxl_mbox, &mbox_cmd);
1014 	if (rc < 0) {
1015 		rc = FW_UPLOAD_ERR_RW_ERROR;
1016 		goto out_free;
1017 	}
1018 
1019 	*written = cur_size;
1020 
1021 	/* Activate FW if oneshot or if the last slice was written */
1022 	if (mds->fw.oneshot || remaining == 0) {
1023 		dev_dbg(&cxlmd->dev, "Activating firmware slot: %d\n",
1024 			mds->fw.next_slot);
1025 		rc = cxl_mem_activate_fw(mds, mds->fw.next_slot);
1026 		if (rc < 0) {
1027 			dev_err(&cxlmd->dev, "Error activating firmware: %d\n",
1028 				rc);
1029 			rc = FW_UPLOAD_ERR_HW_ERROR;
1030 			goto out_free;
1031 		}
1032 	}
1033 
1034 	rc = FW_UPLOAD_ERR_NONE;
1035 
1036 out_free:
1037 	kfree(transfer);
1038 	return rc;
1039 }
1040 
1041 static enum fw_upload_err cxl_fw_poll_complete(struct fw_upload *fwl)
1042 {
1043 	struct cxl_memdev_state *mds = fwl->dd_handle;
1044 
1045 	/*
1046 	 * cxl_internal_send_cmd() handles background operations synchronously.
1047 	 * No need to wait for completions here - any errors would've been
1048 	 * reported and handled during the ->write() call(s).
1049 	 * Just check if a cancel request was received, and return success.
1050 	 */
1051 	if (test_and_clear_bit(CXL_FW_CANCEL, mds->fw.state))
1052 		return cxl_fw_do_cancel(fwl);
1053 
1054 	return FW_UPLOAD_ERR_NONE;
1055 }
1056 
1057 static void cxl_fw_cancel(struct fw_upload *fwl)
1058 {
1059 	struct cxl_memdev_state *mds = fwl->dd_handle;
1060 
1061 	set_bit(CXL_FW_CANCEL, mds->fw.state);
1062 }
1063 
1064 static const struct fw_upload_ops cxl_memdev_fw_ops = {
1065         .prepare = cxl_fw_prepare,
1066         .write = cxl_fw_write,
1067         .poll_complete = cxl_fw_poll_complete,
1068         .cancel = cxl_fw_cancel,
1069         .cleanup = cxl_fw_cleanup,
1070 };
1071 
1072 static void cxl_remove_fw_upload(void *fwl)
1073 {
1074 	firmware_upload_unregister(fwl);
1075 }
1076 
1077 int devm_cxl_setup_fw_upload(struct device *host, struct cxl_memdev_state *mds)
1078 {
1079 	struct cxl_dev_state *cxlds = &mds->cxlds;
1080 	struct cxl_mailbox *cxl_mbox = &cxlds->cxl_mbox;
1081 	struct device *dev = &cxlds->cxlmd->dev;
1082 	struct fw_upload *fwl;
1083 
1084 	if (!test_bit(CXL_MEM_COMMAND_ID_GET_FW_INFO, cxl_mbox->enabled_cmds))
1085 		return 0;
1086 
1087 	fwl = firmware_upload_register(THIS_MODULE, dev, dev_name(dev),
1088 				       &cxl_memdev_fw_ops, mds);
1089 	if (IS_ERR(fwl))
1090 		return PTR_ERR(fwl);
1091 	return devm_add_action_or_reset(host, cxl_remove_fw_upload, fwl);
1092 }
1093 EXPORT_SYMBOL_NS_GPL(devm_cxl_setup_fw_upload, "CXL");
1094 
1095 static const struct file_operations cxl_memdev_fops = {
1096 	.owner = THIS_MODULE,
1097 	.unlocked_ioctl = cxl_memdev_ioctl,
1098 	.open = cxl_memdev_open,
1099 	.release = cxl_memdev_release_file,
1100 	.compat_ioctl = compat_ptr_ioctl,
1101 	.llseek = noop_llseek,
1102 };
1103 
1104 /*
1105  * Activate ioctl operations, no cxl_memdev_rwsem manipulation needed as this is
1106  * ordered with cdev_add() publishing the device.
1107  */
1108 static int cxlmd_add(struct cxl_memdev *cxlmd, struct cxl_dev_state *cxlds)
1109 {
1110 	int rc;
1111 
1112 	cxlmd->cxlds = cxlds;
1113 	cxlds->cxlmd = cxlmd;
1114 
1115 	rc = cdev_device_add(&cxlmd->cdev, &cxlmd->dev);
1116 	if (rc) {
1117 		/*
1118 		 * The cdev was briefly live, shutdown any ioctl operations that
1119 		 * saw that state.
1120 		 */
1121 		cxl_memdev_shutdown(&cxlmd->dev);
1122 		return rc;
1123 	}
1124 
1125 	return 0;
1126 }
1127 
1128 DEFINE_FREE(put_cxlmd, struct cxl_memdev *,
1129 	    if (!IS_ERR_OR_NULL(_T)) put_device(&_T->dev))
1130 
1131 static bool cxl_memdev_attach_failed(struct cxl_memdev *cxlmd)
1132 {
1133 	/*
1134 	 * If @attach is provided fail if the driver is not attached upon
1135 	 * return. Note that failure here could be the result of a race to
1136 	 * teardown the CXL port topology. I.e. cxl_mem_probe() could have
1137 	 * succeeded and then cxl_mem unbound before the lock is acquired.
1138 	 */
1139 	guard(device)(&cxlmd->dev);
1140 	return (cxlmd->attach && !cxlmd->dev.driver);
1141 }
1142 
1143 static struct cxl_memdev *cxl_memdev_autoremove(struct cxl_memdev *cxlmd)
1144 {
1145 	int rc;
1146 
1147 	if (cxl_memdev_attach_failed(cxlmd)) {
1148 		cxl_memdev_unregister(cxlmd);
1149 		return ERR_PTR(-ENXIO);
1150 	}
1151 
1152 	rc = devm_add_action_or_reset(cxlmd->cxlds->dev, cxl_memdev_unregister,
1153 				      cxlmd);
1154 	if (rc)
1155 		return ERR_PTR(rc);
1156 
1157 	return cxlmd;
1158 }
1159 
1160 /*
1161  * Core helper for devm_cxl_add_memdev() that wants to both create a device and
1162  * assert to the caller that upon return cxl_mem::probe() has been invoked.
1163  */
1164 struct cxl_memdev *__devm_cxl_add_memdev(struct cxl_dev_state *cxlds,
1165 					 const struct cxl_memdev_attach *attach)
1166 {
1167 	struct device *dev;
1168 	int rc;
1169 
1170 	struct cxl_memdev *cxlmd __free(put_cxlmd) =
1171 		cxl_memdev_alloc(cxlds, &cxl_memdev_fops, attach);
1172 	if (IS_ERR(cxlmd))
1173 		return cxlmd;
1174 
1175 	dev = &cxlmd->dev;
1176 	rc = dev_set_name(dev, "mem%d", cxlmd->id);
1177 	if (rc)
1178 		return ERR_PTR(rc);
1179 
1180 	rc = cxlmd_add(cxlmd, cxlds);
1181 	if (rc)
1182 		return ERR_PTR(rc);
1183 
1184 	return cxl_memdev_autoremove(no_free_ptr(cxlmd));
1185 }
1186 EXPORT_SYMBOL_FOR_MODULES(__devm_cxl_add_memdev, "cxl_mem");
1187 
1188 static void sanitize_teardown_notifier(void *data)
1189 {
1190 	struct cxl_memdev_state *mds = data;
1191 	struct cxl_mailbox *cxl_mbox = &mds->cxlds.cxl_mbox;
1192 	struct kernfs_node *state;
1193 
1194 	/*
1195 	 * Prevent new irq triggered invocations of the workqueue and
1196 	 * flush inflight invocations.
1197 	 */
1198 	mutex_lock(&cxl_mbox->mbox_mutex);
1199 	state = mds->security.sanitize_node;
1200 	mds->security.sanitize_node = NULL;
1201 	mutex_unlock(&cxl_mbox->mbox_mutex);
1202 
1203 	cancel_delayed_work_sync(&mds->security.poll_dwork);
1204 	sysfs_put(state);
1205 }
1206 
1207 int devm_cxl_sanitize_setup_notifier(struct device *host,
1208 				     struct cxl_memdev *cxlmd)
1209 {
1210 	struct cxl_dev_state *cxlds = cxlmd->cxlds;
1211 	struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlds);
1212 	struct kernfs_node *sec;
1213 
1214 	if (!test_bit(CXL_SEC_ENABLED_SANITIZE, mds->security.enabled_cmds))
1215 		return 0;
1216 
1217 	/*
1218 	 * Note, the expectation is that @cxlmd would have failed to be
1219 	 * created if these sysfs_get_dirent calls fail.
1220 	 */
1221 	sec = sysfs_get_dirent(cxlmd->dev.kobj.sd, "security");
1222 	if (!sec)
1223 		return -ENOENT;
1224 	mds->security.sanitize_node = sysfs_get_dirent(sec, "state");
1225 	sysfs_put(sec);
1226 	if (!mds->security.sanitize_node)
1227 		return -ENOENT;
1228 
1229 	return devm_add_action_or_reset(host, sanitize_teardown_notifier, mds);
1230 }
1231 EXPORT_SYMBOL_NS_GPL(devm_cxl_sanitize_setup_notifier, "CXL");
1232 
1233 __init int cxl_memdev_init(void)
1234 {
1235 	dev_t devt;
1236 	int rc;
1237 
1238 	rc = alloc_chrdev_region(&devt, 0, CXL_MEM_MAX_DEVS, "cxl");
1239 	if (rc)
1240 		return rc;
1241 
1242 	cxl_mem_major = MAJOR(devt);
1243 
1244 	return 0;
1245 }
1246 
1247 void cxl_memdev_exit(void)
1248 {
1249 	unregister_chrdev_region(MKDEV(cxl_mem_major, 0), CXL_MEM_MAX_DEVS);
1250 }
1251