1 // SPDX-License-Identifier: GPL-2.0-only
2 /* Copyright(c) 2020 Intel Corporation. */
4 #include <linux/io-64-nonatomic-lo-hi.h>
5 #include <linux/device.h>
6 #include <linux/slab.h>
13 static DECLARE_RWSEM(cxl_memdev_rwsem);
16 * An entire PCI topology full of devices should be enough for any
19 #define CXL_MEM_MAX_DEVS 65536
21 static int cxl_mem_major;
22 static DEFINE_IDA(cxl_memdev_ida);
24 static void cxl_memdev_release(struct device *dev)
26 struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
28 ida_free(&cxl_memdev_ida, cxlmd->id);
32 static char *cxl_memdev_devnode(const struct device *dev, umode_t *mode, kuid_t *uid,
35 return kasprintf(GFP_KERNEL, "cxl/%s", dev_name(dev));
38 static ssize_t firmware_version_show(struct device *dev,
39 struct device_attribute *attr, char *buf)
41 struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
42 struct cxl_dev_state *cxlds = cxlmd->cxlds;
44 return sysfs_emit(buf, "%.16s\n", cxlds->firmware_version);
46 static DEVICE_ATTR_RO(firmware_version);
48 static ssize_t payload_max_show(struct device *dev,
49 struct device_attribute *attr, char *buf)
51 struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
52 struct cxl_dev_state *cxlds = cxlmd->cxlds;
54 return sysfs_emit(buf, "%zu\n", cxlds->payload_size);
56 static DEVICE_ATTR_RO(payload_max);
58 static ssize_t label_storage_size_show(struct device *dev,
59 struct device_attribute *attr, char *buf)
61 struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
62 struct cxl_dev_state *cxlds = cxlmd->cxlds;
64 return sysfs_emit(buf, "%zu\n", cxlds->lsa_size);
66 static DEVICE_ATTR_RO(label_storage_size);
68 static ssize_t ram_size_show(struct device *dev, struct device_attribute *attr,
71 struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
72 struct cxl_dev_state *cxlds = cxlmd->cxlds;
73 unsigned long long len = resource_size(&cxlds->ram_res);
75 return sysfs_emit(buf, "%#llx\n", len);
78 static struct device_attribute dev_attr_ram_size =
79 __ATTR(size, 0444, ram_size_show, NULL);
81 static ssize_t pmem_size_show(struct device *dev, struct device_attribute *attr,
84 struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
85 struct cxl_dev_state *cxlds = cxlmd->cxlds;
86 unsigned long long len = resource_size(&cxlds->pmem_res);
88 return sysfs_emit(buf, "%#llx\n", len);
91 static struct device_attribute dev_attr_pmem_size =
92 __ATTR(size, 0444, pmem_size_show, NULL);
94 static ssize_t serial_show(struct device *dev, struct device_attribute *attr,
97 struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
98 struct cxl_dev_state *cxlds = cxlmd->cxlds;
100 return sysfs_emit(buf, "%#llx\n", cxlds->serial);
102 static DEVICE_ATTR_RO(serial);
104 static ssize_t numa_node_show(struct device *dev, struct device_attribute *attr,
107 return sprintf(buf, "%d\n", dev_to_node(dev));
109 static DEVICE_ATTR_RO(numa_node);
111 static ssize_t security_state_show(struct device *dev,
112 struct device_attribute *attr,
115 struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
116 struct cxl_dev_state *cxlds = cxlmd->cxlds;
117 unsigned long state = cxlds->security.state;
118 u64 reg = readq(cxlds->regs.mbox + CXLDEV_MBOX_BG_CMD_STATUS_OFFSET);
119 u32 pct = FIELD_GET(CXLDEV_MBOX_BG_CMD_COMMAND_PCT_MASK, reg);
120 u16 cmd = FIELD_GET(CXLDEV_MBOX_BG_CMD_COMMAND_OPCODE_MASK, reg);
122 if (cmd == CXL_MBOX_OP_SANITIZE && pct != 100)
123 return sysfs_emit(buf, "sanitize\n");
125 if (!(state & CXL_PMEM_SEC_STATE_USER_PASS_SET))
126 return sysfs_emit(buf, "disabled\n");
127 if (state & CXL_PMEM_SEC_STATE_FROZEN ||
128 state & CXL_PMEM_SEC_STATE_MASTER_PLIMIT ||
129 state & CXL_PMEM_SEC_STATE_USER_PLIMIT)
130 return sysfs_emit(buf, "frozen\n");
131 if (state & CXL_PMEM_SEC_STATE_LOCKED)
132 return sysfs_emit(buf, "locked\n");
134 return sysfs_emit(buf, "unlocked\n");
136 static struct device_attribute dev_attr_security_state =
137 __ATTR(state, 0444, security_state_show, NULL);
139 static ssize_t security_sanitize_store(struct device *dev,
140 struct device_attribute *attr,
141 const char *buf, size_t len)
143 struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
144 struct cxl_dev_state *cxlds = cxlmd->cxlds;
145 struct cxl_port *port = dev_get_drvdata(&cxlmd->dev);
149 if (kstrtobool(buf, &sanitize) || !sanitize)
152 if (!port || !is_cxl_endpoint(port))
155 /* ensure no regions are mapped to this memdev */
156 if (port->commit_end != -1)
159 rc = cxl_mem_sanitize(cxlds, CXL_MBOX_OP_SANITIZE);
161 return rc ? rc : len;
163 static struct device_attribute dev_attr_security_sanitize =
164 __ATTR(sanitize, 0200, NULL, security_sanitize_store);
166 static ssize_t security_erase_store(struct device *dev,
167 struct device_attribute *attr,
168 const char *buf, size_t len)
170 struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
171 struct cxl_dev_state *cxlds = cxlmd->cxlds;
172 struct cxl_port *port = dev_get_drvdata(&cxlmd->dev);
176 if (kstrtobool(buf, &erase) || !erase)
179 if (!port || !is_cxl_endpoint(port))
182 /* ensure no regions are mapped to this memdev */
183 if (port->commit_end != -1)
186 rc = cxl_mem_sanitize(cxlds, CXL_MBOX_OP_SECURE_ERASE);
188 return rc ? rc : len;
190 static struct device_attribute dev_attr_security_erase =
191 __ATTR(erase, 0200, NULL, security_erase_store);
193 static int cxl_get_poison_by_memdev(struct cxl_memdev *cxlmd)
195 struct cxl_dev_state *cxlds = cxlmd->cxlds;
199 /* CXL 3.0 Spec 8.2.9.8.4.1 Separate pmem and ram poison requests */
200 if (resource_size(&cxlds->pmem_res)) {
201 offset = cxlds->pmem_res.start;
202 length = resource_size(&cxlds->pmem_res);
203 rc = cxl_mem_get_poison(cxlmd, offset, length, NULL);
207 if (resource_size(&cxlds->ram_res)) {
208 offset = cxlds->ram_res.start;
209 length = resource_size(&cxlds->ram_res);
210 rc = cxl_mem_get_poison(cxlmd, offset, length, NULL);
212 * Invalid Physical Address is not an error for
213 * volatile addresses. Device support is optional.
221 int cxl_trigger_poison_list(struct cxl_memdev *cxlmd)
223 struct cxl_port *port;
226 port = dev_get_drvdata(&cxlmd->dev);
227 if (!port || !is_cxl_endpoint(port))
230 rc = down_read_interruptible(&cxl_dpa_rwsem);
234 if (port->commit_end == -1) {
235 /* No regions mapped to this memdev */
236 rc = cxl_get_poison_by_memdev(cxlmd);
238 /* Regions mapped, collect poison by endpoint */
239 rc = cxl_get_poison_by_endpoint(port);
241 up_read(&cxl_dpa_rwsem);
245 EXPORT_SYMBOL_NS_GPL(cxl_trigger_poison_list, CXL);
247 struct cxl_dpa_to_region_context {
248 struct cxl_region *cxlr;
252 static int __cxl_dpa_to_region(struct device *dev, void *arg)
254 struct cxl_dpa_to_region_context *ctx = arg;
255 struct cxl_endpoint_decoder *cxled;
258 if (!is_endpoint_decoder(dev))
261 cxled = to_cxl_endpoint_decoder(dev);
262 if (!cxled->dpa_res || !resource_size(cxled->dpa_res))
265 if (dpa > cxled->dpa_res->end || dpa < cxled->dpa_res->start)
268 dev_dbg(dev, "dpa:0x%llx mapped in region:%s\n", dpa,
269 dev_name(&cxled->cxld.region->dev));
271 ctx->cxlr = cxled->cxld.region;
276 static struct cxl_region *cxl_dpa_to_region(struct cxl_memdev *cxlmd, u64 dpa)
278 struct cxl_dpa_to_region_context ctx;
279 struct cxl_port *port;
281 ctx = (struct cxl_dpa_to_region_context) {
284 port = dev_get_drvdata(&cxlmd->dev);
285 if (port && is_cxl_endpoint(port) && port->commit_end != -1)
286 device_for_each_child(&port->dev, &ctx, __cxl_dpa_to_region);
291 static int cxl_validate_poison_dpa(struct cxl_memdev *cxlmd, u64 dpa)
293 struct cxl_dev_state *cxlds = cxlmd->cxlds;
295 if (!IS_ENABLED(CONFIG_DEBUG_FS))
298 if (!resource_size(&cxlds->dpa_res)) {
299 dev_dbg(cxlds->dev, "device has no dpa resource\n");
302 if (dpa < cxlds->dpa_res.start || dpa > cxlds->dpa_res.end) {
303 dev_dbg(cxlds->dev, "dpa:0x%llx not in resource:%pR\n",
304 dpa, &cxlds->dpa_res);
307 if (!IS_ALIGNED(dpa, 64)) {
308 dev_dbg(cxlds->dev, "dpa:0x%llx is not 64-byte aligned\n", dpa);
315 int cxl_inject_poison(struct cxl_memdev *cxlmd, u64 dpa)
317 struct cxl_dev_state *cxlds = cxlmd->cxlds;
318 struct cxl_mbox_inject_poison inject;
319 struct cxl_poison_record record;
320 struct cxl_mbox_cmd mbox_cmd;
321 struct cxl_region *cxlr;
324 if (!IS_ENABLED(CONFIG_DEBUG_FS))
327 rc = down_read_interruptible(&cxl_dpa_rwsem);
331 rc = cxl_validate_poison_dpa(cxlmd, dpa);
335 inject.address = cpu_to_le64(dpa);
336 mbox_cmd = (struct cxl_mbox_cmd) {
337 .opcode = CXL_MBOX_OP_INJECT_POISON,
338 .size_in = sizeof(inject),
339 .payload_in = &inject,
341 rc = cxl_internal_send_cmd(cxlds, &mbox_cmd);
345 cxlr = cxl_dpa_to_region(cxlmd, dpa);
347 dev_warn_once(cxlds->dev,
348 "poison inject dpa:%#llx region: %s\n", dpa,
349 dev_name(&cxlr->dev));
351 record = (struct cxl_poison_record) {
352 .address = cpu_to_le64(dpa),
353 .length = cpu_to_le32(1),
355 trace_cxl_poison(cxlmd, cxlr, &record, 0, 0, CXL_POISON_TRACE_INJECT);
357 up_read(&cxl_dpa_rwsem);
361 EXPORT_SYMBOL_NS_GPL(cxl_inject_poison, CXL);
363 int cxl_clear_poison(struct cxl_memdev *cxlmd, u64 dpa)
365 struct cxl_dev_state *cxlds = cxlmd->cxlds;
366 struct cxl_mbox_clear_poison clear;
367 struct cxl_poison_record record;
368 struct cxl_mbox_cmd mbox_cmd;
369 struct cxl_region *cxlr;
372 if (!IS_ENABLED(CONFIG_DEBUG_FS))
375 rc = down_read_interruptible(&cxl_dpa_rwsem);
379 rc = cxl_validate_poison_dpa(cxlmd, dpa);
384 * In CXL 3.0 Spec 8.2.9.8.4.3, the Clear Poison mailbox command
385 * is defined to accept 64 bytes of write-data, along with the
386 * address to clear. This driver uses zeroes as write-data.
388 clear = (struct cxl_mbox_clear_poison) {
389 .address = cpu_to_le64(dpa)
392 mbox_cmd = (struct cxl_mbox_cmd) {
393 .opcode = CXL_MBOX_OP_CLEAR_POISON,
394 .size_in = sizeof(clear),
395 .payload_in = &clear,
398 rc = cxl_internal_send_cmd(cxlds, &mbox_cmd);
402 cxlr = cxl_dpa_to_region(cxlmd, dpa);
404 dev_warn_once(cxlds->dev, "poison clear dpa:%#llx region: %s\n",
405 dpa, dev_name(&cxlr->dev));
407 record = (struct cxl_poison_record) {
408 .address = cpu_to_le64(dpa),
409 .length = cpu_to_le32(1),
411 trace_cxl_poison(cxlmd, cxlr, &record, 0, 0, CXL_POISON_TRACE_CLEAR);
413 up_read(&cxl_dpa_rwsem);
417 EXPORT_SYMBOL_NS_GPL(cxl_clear_poison, CXL);
419 static struct attribute *cxl_memdev_attributes[] = {
420 &dev_attr_serial.attr,
421 &dev_attr_firmware_version.attr,
422 &dev_attr_payload_max.attr,
423 &dev_attr_label_storage_size.attr,
424 &dev_attr_numa_node.attr,
428 static struct attribute *cxl_memdev_pmem_attributes[] = {
429 &dev_attr_pmem_size.attr,
433 static struct attribute *cxl_memdev_ram_attributes[] = {
434 &dev_attr_ram_size.attr,
438 static struct attribute *cxl_memdev_security_attributes[] = {
439 &dev_attr_security_state.attr,
440 &dev_attr_security_sanitize.attr,
441 &dev_attr_security_erase.attr,
445 static umode_t cxl_memdev_visible(struct kobject *kobj, struct attribute *a,
448 if (!IS_ENABLED(CONFIG_NUMA) && a == &dev_attr_numa_node.attr)
453 static struct attribute_group cxl_memdev_attribute_group = {
454 .attrs = cxl_memdev_attributes,
455 .is_visible = cxl_memdev_visible,
458 static struct attribute_group cxl_memdev_ram_attribute_group = {
460 .attrs = cxl_memdev_ram_attributes,
463 static struct attribute_group cxl_memdev_pmem_attribute_group = {
465 .attrs = cxl_memdev_pmem_attributes,
468 static struct attribute_group cxl_memdev_security_attribute_group = {
470 .attrs = cxl_memdev_security_attributes,
473 static const struct attribute_group *cxl_memdev_attribute_groups[] = {
474 &cxl_memdev_attribute_group,
475 &cxl_memdev_ram_attribute_group,
476 &cxl_memdev_pmem_attribute_group,
477 &cxl_memdev_security_attribute_group,
481 static const struct device_type cxl_memdev_type = {
482 .name = "cxl_memdev",
483 .release = cxl_memdev_release,
484 .devnode = cxl_memdev_devnode,
485 .groups = cxl_memdev_attribute_groups,
488 bool is_cxl_memdev(const struct device *dev)
490 return dev->type == &cxl_memdev_type;
492 EXPORT_SYMBOL_NS_GPL(is_cxl_memdev, CXL);
495 * set_exclusive_cxl_commands() - atomically disable user cxl commands
496 * @cxlds: The device state to operate on
497 * @cmds: bitmap of commands to mark exclusive
499 * Grab the cxl_memdev_rwsem in write mode to flush in-flight
500 * invocations of the ioctl path and then disable future execution of
501 * commands with the command ids set in @cmds.
503 void set_exclusive_cxl_commands(struct cxl_dev_state *cxlds, unsigned long *cmds)
505 down_write(&cxl_memdev_rwsem);
506 bitmap_or(cxlds->exclusive_cmds, cxlds->exclusive_cmds, cmds,
507 CXL_MEM_COMMAND_ID_MAX);
508 up_write(&cxl_memdev_rwsem);
510 EXPORT_SYMBOL_NS_GPL(set_exclusive_cxl_commands, CXL);
513 * clear_exclusive_cxl_commands() - atomically enable user cxl commands
514 * @cxlds: The device state to modify
515 * @cmds: bitmap of commands to mark available for userspace
517 void clear_exclusive_cxl_commands(struct cxl_dev_state *cxlds, unsigned long *cmds)
519 down_write(&cxl_memdev_rwsem);
520 bitmap_andnot(cxlds->exclusive_cmds, cxlds->exclusive_cmds, cmds,
521 CXL_MEM_COMMAND_ID_MAX);
522 up_write(&cxl_memdev_rwsem);
524 EXPORT_SYMBOL_NS_GPL(clear_exclusive_cxl_commands, CXL);
526 static void cxl_memdev_security_shutdown(struct device *dev)
528 struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
529 struct cxl_dev_state *cxlds = cxlmd->cxlds;
531 if (cxlds->security.poll)
532 cancel_delayed_work_sync(&cxlds->security.poll_dwork);
535 static void cxl_memdev_shutdown(struct device *dev)
537 struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
539 down_write(&cxl_memdev_rwsem);
540 cxl_memdev_security_shutdown(dev);
542 up_write(&cxl_memdev_rwsem);
545 static void cxl_memdev_unregister(void *_cxlmd)
547 struct cxl_memdev *cxlmd = _cxlmd;
548 struct device *dev = &cxlmd->dev;
550 cxl_memdev_shutdown(dev);
551 cdev_device_del(&cxlmd->cdev, dev);
555 static void detach_memdev(struct work_struct *work)
557 struct cxl_memdev *cxlmd;
559 cxlmd = container_of(work, typeof(*cxlmd), detach_work);
560 device_release_driver(&cxlmd->dev);
561 put_device(&cxlmd->dev);
564 static struct lock_class_key cxl_memdev_key;
566 static struct cxl_memdev *cxl_memdev_alloc(struct cxl_dev_state *cxlds,
567 const struct file_operations *fops)
569 struct cxl_memdev *cxlmd;
574 cxlmd = kzalloc(sizeof(*cxlmd), GFP_KERNEL);
576 return ERR_PTR(-ENOMEM);
578 rc = ida_alloc_max(&cxl_memdev_ida, CXL_MEM_MAX_DEVS - 1, GFP_KERNEL);
585 device_initialize(dev);
586 lockdep_set_class(&dev->mutex, &cxl_memdev_key);
587 dev->parent = cxlds->dev;
588 dev->bus = &cxl_bus_type;
589 dev->devt = MKDEV(cxl_mem_major, cxlmd->id);
590 dev->type = &cxl_memdev_type;
591 device_set_pm_not_required(dev);
592 INIT_WORK(&cxlmd->detach_work, detach_memdev);
595 cdev_init(cdev, fops);
603 static long __cxl_memdev_ioctl(struct cxl_memdev *cxlmd, unsigned int cmd,
607 case CXL_MEM_QUERY_COMMANDS:
608 return cxl_query_cmd(cxlmd, (void __user *)arg);
609 case CXL_MEM_SEND_COMMAND:
610 return cxl_send_cmd(cxlmd, (void __user *)arg);
616 static long cxl_memdev_ioctl(struct file *file, unsigned int cmd,
619 struct cxl_memdev *cxlmd = file->private_data;
622 down_read(&cxl_memdev_rwsem);
624 rc = __cxl_memdev_ioctl(cxlmd, cmd, arg);
625 up_read(&cxl_memdev_rwsem);
630 static int cxl_memdev_open(struct inode *inode, struct file *file)
632 struct cxl_memdev *cxlmd =
633 container_of(inode->i_cdev, typeof(*cxlmd), cdev);
635 get_device(&cxlmd->dev);
636 file->private_data = cxlmd;
641 static int cxl_memdev_release_file(struct inode *inode, struct file *file)
643 struct cxl_memdev *cxlmd =
644 container_of(inode->i_cdev, typeof(*cxlmd), cdev);
646 put_device(&cxlmd->dev);
651 static const struct file_operations cxl_memdev_fops = {
652 .owner = THIS_MODULE,
653 .unlocked_ioctl = cxl_memdev_ioctl,
654 .open = cxl_memdev_open,
655 .release = cxl_memdev_release_file,
656 .compat_ioctl = compat_ptr_ioctl,
657 .llseek = noop_llseek,
660 static void put_sanitize(void *data)
662 struct cxl_dev_state *cxlds = data;
664 sysfs_put(cxlds->security.sanitize_node);
667 static int cxl_memdev_security_init(struct cxl_memdev *cxlmd)
669 struct cxl_dev_state *cxlds = cxlmd->cxlds;
670 struct device *dev = &cxlmd->dev;
671 struct kernfs_node *sec;
673 sec = sysfs_get_dirent(dev->kobj.sd, "security");
675 dev_err(dev, "sysfs_get_dirent 'security' failed\n");
678 cxlds->security.sanitize_node = sysfs_get_dirent(sec, "state");
680 if (!cxlds->security.sanitize_node) {
681 dev_err(dev, "sysfs_get_dirent 'state' failed\n");
685 return devm_add_action_or_reset(cxlds->dev, put_sanitize, cxlds);
688 struct cxl_memdev *devm_cxl_add_memdev(struct cxl_dev_state *cxlds)
690 struct cxl_memdev *cxlmd;
695 cxlmd = cxl_memdev_alloc(cxlds, &cxl_memdev_fops);
700 rc = dev_set_name(dev, "mem%d", cxlmd->id);
705 * Activate ioctl operations, no cxl_memdev_rwsem manipulation
706 * needed as this is ordered with cdev_add() publishing the device.
708 cxlmd->cxlds = cxlds;
709 cxlds->cxlmd = cxlmd;
712 rc = cdev_device_add(cdev, dev);
716 rc = cxl_memdev_security_init(cxlmd);
720 rc = devm_add_action_or_reset(cxlds->dev, cxl_memdev_unregister, cxlmd);
727 * The cdev was briefly live, shutdown any ioctl operations that
730 cxl_memdev_shutdown(dev);
734 EXPORT_SYMBOL_NS_GPL(devm_cxl_add_memdev, CXL);
736 __init int cxl_memdev_init(void)
741 rc = alloc_chrdev_region(&devt, 0, CXL_MEM_MAX_DEVS, "cxl");
745 cxl_mem_major = MAJOR(devt);
750 void cxl_memdev_exit(void)
752 unregister_chrdev_region(MKDEV(cxl_mem_major, 0), CXL_MEM_MAX_DEVS);