1 // SPDX-License-Identifier: GPL-2.0-only
2 /* Copyright(c) 2020 Intel Corporation. All rights reserved. */
3 #include <linux/security.h>
4 #include <linux/debugfs.h>
5 #include <linux/ktime.h>
6 #include <linux/mutex.h>
7 #include <asm/unaligned.h>
15 static bool cxl_raw_allow_all;
20 * Core implementation of the CXL 2.0 Type-3 Memory Device Mailbox. The
21 * implementation is used by the cxl_pci driver to initialize the device
22 * and implement the cxl_mem.h IOCTL UAPI. It also implements the
23 * backend of the cxl_pmem_ctl() transport for LIBNVDIMM.
26 #define cxl_for_each_cmd(cmd) \
27 for ((cmd) = &cxl_mem_commands[0]; \
28 ((cmd) - cxl_mem_commands) < ARRAY_SIZE(cxl_mem_commands); (cmd)++)
30 #define CXL_CMD(_id, sin, sout, _flags) \
31 [CXL_MEM_COMMAND_ID_##_id] = { \
33 .id = CXL_MEM_COMMAND_ID_##_id, \
37 .opcode = CXL_MBOX_OP_##_id, \
41 #define CXL_VARIABLE_PAYLOAD ~0U
43 * This table defines the supported mailbox commands for the driver. This table
44 * is made up of a UAPI structure. Non-negative values as parameters in the
45 * table will be validated against the user's input. For example, if size_in is
46 * 0, and the user passed in 1, it is an error.
48 static struct cxl_mem_command cxl_mem_commands[CXL_MEM_COMMAND_ID_MAX] = {
49 CXL_CMD(IDENTIFY, 0, 0x43, CXL_CMD_FLAG_FORCE_ENABLE),
50 #ifdef CONFIG_CXL_MEM_RAW_COMMANDS
51 CXL_CMD(RAW, CXL_VARIABLE_PAYLOAD, CXL_VARIABLE_PAYLOAD, 0),
53 CXL_CMD(GET_SUPPORTED_LOGS, 0, CXL_VARIABLE_PAYLOAD, CXL_CMD_FLAG_FORCE_ENABLE),
54 CXL_CMD(GET_FW_INFO, 0, 0x50, 0),
55 CXL_CMD(GET_PARTITION_INFO, 0, 0x20, 0),
56 CXL_CMD(GET_LSA, 0x8, CXL_VARIABLE_PAYLOAD, 0),
57 CXL_CMD(GET_HEALTH_INFO, 0, 0x12, 0),
58 CXL_CMD(GET_LOG, 0x18, CXL_VARIABLE_PAYLOAD, CXL_CMD_FLAG_FORCE_ENABLE),
59 CXL_CMD(SET_PARTITION_INFO, 0x0a, 0, 0),
60 CXL_CMD(SET_LSA, CXL_VARIABLE_PAYLOAD, 0, 0),
61 CXL_CMD(GET_ALERT_CONFIG, 0, 0x10, 0),
62 CXL_CMD(SET_ALERT_CONFIG, 0xc, 0, 0),
63 CXL_CMD(GET_SHUTDOWN_STATE, 0, 0x1, 0),
64 CXL_CMD(SET_SHUTDOWN_STATE, 0x1, 0, 0),
65 CXL_CMD(GET_SCAN_MEDIA_CAPS, 0x10, 0x4, 0),
66 CXL_CMD(GET_TIMESTAMP, 0, 0x8, 0),
70 * Commands that RAW doesn't permit. The rationale for each:
72 * CXL_MBOX_OP_ACTIVATE_FW: Firmware activation requires adjustment /
73 * coordination of transaction timeout values at the root bridge level.
75 * CXL_MBOX_OP_SET_PARTITION_INFO: The device memory map may change live
76 * and needs to be coordinated with HDM updates.
78 * CXL_MBOX_OP_SET_LSA: The label storage area may be cached by the
79 * driver and any writes from userspace invalidates those contents.
81 * CXL_MBOX_OP_SET_SHUTDOWN_STATE: Set shutdown state assumes no writes
82 * to the device after it is marked clean, userspace can not make that
85 * CXL_MBOX_OP_[GET_]SCAN_MEDIA: The kernel provides a native error list that
86 * is kept up to date with patrol notifications and error management.
88 * CXL_MBOX_OP_[GET_,INJECT_,CLEAR_]POISON: These commands require kernel
89 * driver orchestration for safety.
91 static u16 cxl_disabled_raw_commands[] = {
92 CXL_MBOX_OP_ACTIVATE_FW,
93 CXL_MBOX_OP_SET_PARTITION_INFO,
95 CXL_MBOX_OP_SET_SHUTDOWN_STATE,
96 CXL_MBOX_OP_SCAN_MEDIA,
97 CXL_MBOX_OP_GET_SCAN_MEDIA,
98 CXL_MBOX_OP_GET_POISON,
99 CXL_MBOX_OP_INJECT_POISON,
100 CXL_MBOX_OP_CLEAR_POISON,
104 * Command sets that RAW doesn't permit. All opcodes in this set are
105 * disabled because they pass plain text security payloads over the
106 * user/kernel boundary. This functionality is intended to be wrapped
107 * behind the keys ABI which allows for encrypted payloads in the UAPI
109 static u8 security_command_sets[] = {
111 0x45, /* Persistent Memory Data-at-rest Security */
112 0x46, /* Security Passthrough */
115 static bool cxl_is_security_command(u16 opcode)
119 for (i = 0; i < ARRAY_SIZE(security_command_sets); i++)
120 if (security_command_sets[i] == (opcode >> 8))
125 static void cxl_set_security_cmd_enabled(struct cxl_security_state *security,
129 case CXL_MBOX_OP_SANITIZE:
130 set_bit(CXL_SEC_ENABLED_SANITIZE, security->enabled_cmds);
132 case CXL_MBOX_OP_SECURE_ERASE:
133 set_bit(CXL_SEC_ENABLED_SECURE_ERASE,
134 security->enabled_cmds);
136 case CXL_MBOX_OP_GET_SECURITY_STATE:
137 set_bit(CXL_SEC_ENABLED_GET_SECURITY_STATE,
138 security->enabled_cmds);
140 case CXL_MBOX_OP_SET_PASSPHRASE:
141 set_bit(CXL_SEC_ENABLED_SET_PASSPHRASE,
142 security->enabled_cmds);
144 case CXL_MBOX_OP_DISABLE_PASSPHRASE:
145 set_bit(CXL_SEC_ENABLED_DISABLE_PASSPHRASE,
146 security->enabled_cmds);
148 case CXL_MBOX_OP_UNLOCK:
149 set_bit(CXL_SEC_ENABLED_UNLOCK, security->enabled_cmds);
151 case CXL_MBOX_OP_FREEZE_SECURITY:
152 set_bit(CXL_SEC_ENABLED_FREEZE_SECURITY,
153 security->enabled_cmds);
155 case CXL_MBOX_OP_PASSPHRASE_SECURE_ERASE:
156 set_bit(CXL_SEC_ENABLED_PASSPHRASE_SECURE_ERASE,
157 security->enabled_cmds);
164 static bool cxl_is_poison_command(u16 opcode)
166 #define CXL_MBOX_OP_POISON_CMDS 0x43
168 if ((opcode >> 8) == CXL_MBOX_OP_POISON_CMDS)
174 static void cxl_set_poison_cmd_enabled(struct cxl_poison_state *poison,
178 case CXL_MBOX_OP_GET_POISON:
179 set_bit(CXL_POISON_ENABLED_LIST, poison->enabled_cmds);
181 case CXL_MBOX_OP_INJECT_POISON:
182 set_bit(CXL_POISON_ENABLED_INJECT, poison->enabled_cmds);
184 case CXL_MBOX_OP_CLEAR_POISON:
185 set_bit(CXL_POISON_ENABLED_CLEAR, poison->enabled_cmds);
187 case CXL_MBOX_OP_GET_SCAN_MEDIA_CAPS:
188 set_bit(CXL_POISON_ENABLED_SCAN_CAPS, poison->enabled_cmds);
190 case CXL_MBOX_OP_SCAN_MEDIA:
191 set_bit(CXL_POISON_ENABLED_SCAN_MEDIA, poison->enabled_cmds);
193 case CXL_MBOX_OP_GET_SCAN_MEDIA:
194 set_bit(CXL_POISON_ENABLED_SCAN_RESULTS, poison->enabled_cmds);
201 static struct cxl_mem_command *cxl_mem_find_command(u16 opcode)
203 struct cxl_mem_command *c;
206 if (c->opcode == opcode)
212 static const char *cxl_mem_opcode_to_name(u16 opcode)
214 struct cxl_mem_command *c;
216 c = cxl_mem_find_command(opcode);
220 return cxl_command_names[c->info.id].name;
224 * cxl_internal_send_cmd() - Kernel internal interface to send a mailbox command
225 * @mds: The driver data for the operation
226 * @mbox_cmd: initialized command to execute
228 * Context: Any context.
230 * * %>=0 - Number of bytes returned in @out.
231 * * %-E2BIG - Payload is too large for hardware.
232 * * %-EBUSY - Couldn't acquire exclusive mailbox access.
233 * * %-EFAULT - Hardware error occurred.
234 * * %-ENXIO - Command completed, but device reported an error.
235 * * %-EIO - Unexpected output size.
237 * Mailbox commands may execute successfully yet the device itself reported an
238 * error. While this distinction can be useful for commands from userspace, the
239 * kernel will only be able to use results when both are successful.
241 int cxl_internal_send_cmd(struct cxl_memdev_state *mds,
242 struct cxl_mbox_cmd *mbox_cmd)
244 size_t out_size, min_out;
247 if (mbox_cmd->size_in > mds->payload_size ||
248 mbox_cmd->size_out > mds->payload_size)
251 out_size = mbox_cmd->size_out;
252 min_out = mbox_cmd->min_out;
253 rc = mds->mbox_send(mds, mbox_cmd);
255 * EIO is reserved for a payload size mismatch and mbox_send()
256 * may not return this error.
258 if (WARN_ONCE(rc == -EIO, "Bad return code: -EIO"))
263 if (mbox_cmd->return_code != CXL_MBOX_CMD_RC_SUCCESS &&
264 mbox_cmd->return_code != CXL_MBOX_CMD_RC_BACKGROUND)
265 return cxl_mbox_cmd_rc2errno(mbox_cmd);
271 * Variable sized output needs to at least satisfy the caller's
272 * minimum if not the fully requested size.
277 if (mbox_cmd->size_out < min_out)
281 EXPORT_SYMBOL_NS_GPL(cxl_internal_send_cmd, CXL);
283 static bool cxl_mem_raw_command_allowed(u16 opcode)
287 if (!IS_ENABLED(CONFIG_CXL_MEM_RAW_COMMANDS))
290 if (security_locked_down(LOCKDOWN_PCI_ACCESS))
293 if (cxl_raw_allow_all)
296 if (cxl_is_security_command(opcode))
299 for (i = 0; i < ARRAY_SIZE(cxl_disabled_raw_commands); i++)
300 if (cxl_disabled_raw_commands[i] == opcode)
307 * cxl_payload_from_user_allowed() - Check contents of in_payload.
308 * @opcode: The mailbox command opcode.
309 * @payload_in: Pointer to the input payload passed in from user space.
312 * * true - payload_in passes check for @opcode.
313 * * false - payload_in contains invalid or unsupported values.
315 * The driver may inspect payload contents before sending a mailbox
316 * command from user space to the device. The intent is to reject
317 * commands with input payloads that are known to be unsafe. This
318 * check is not intended to replace the users careful selection of
319 * mailbox command parameters and makes no guarantee that the user
320 * command will succeed, nor that it is appropriate.
322 * The specific checks are determined by the opcode.
324 static bool cxl_payload_from_user_allowed(u16 opcode, void *payload_in)
327 case CXL_MBOX_OP_SET_PARTITION_INFO: {
328 struct cxl_mbox_set_partition_info *pi = payload_in;
330 if (pi->flags & CXL_SET_PARTITION_IMMEDIATE_FLAG)
340 static int cxl_mbox_cmd_ctor(struct cxl_mbox_cmd *mbox,
341 struct cxl_memdev_state *mds, u16 opcode,
342 size_t in_size, size_t out_size, u64 in_payload)
344 *mbox = (struct cxl_mbox_cmd) {
350 mbox->payload_in = vmemdup_user(u64_to_user_ptr(in_payload),
352 if (IS_ERR(mbox->payload_in))
353 return PTR_ERR(mbox->payload_in);
355 if (!cxl_payload_from_user_allowed(opcode, mbox->payload_in)) {
356 dev_dbg(mds->cxlds.dev, "%s: input payload not allowed\n",
357 cxl_mem_opcode_to_name(opcode));
358 kvfree(mbox->payload_in);
363 /* Prepare to handle a full payload for variable sized output */
364 if (out_size == CXL_VARIABLE_PAYLOAD)
365 mbox->size_out = mds->payload_size;
367 mbox->size_out = out_size;
369 if (mbox->size_out) {
370 mbox->payload_out = kvzalloc(mbox->size_out, GFP_KERNEL);
371 if (!mbox->payload_out) {
372 kvfree(mbox->payload_in);
379 static void cxl_mbox_cmd_dtor(struct cxl_mbox_cmd *mbox)
381 kvfree(mbox->payload_in);
382 kvfree(mbox->payload_out);
385 static int cxl_to_mem_cmd_raw(struct cxl_mem_command *mem_cmd,
386 const struct cxl_send_command *send_cmd,
387 struct cxl_memdev_state *mds)
389 if (send_cmd->raw.rsvd)
393 * Unlike supported commands, the output size of RAW commands
394 * gets passed along without further checking, so it must be
397 if (send_cmd->out.size > mds->payload_size)
400 if (!cxl_mem_raw_command_allowed(send_cmd->raw.opcode))
403 dev_WARN_ONCE(mds->cxlds.dev, true, "raw command path used\n");
405 *mem_cmd = (struct cxl_mem_command) {
407 .id = CXL_MEM_COMMAND_ID_RAW,
408 .size_in = send_cmd->in.size,
409 .size_out = send_cmd->out.size,
411 .opcode = send_cmd->raw.opcode
417 static int cxl_to_mem_cmd(struct cxl_mem_command *mem_cmd,
418 const struct cxl_send_command *send_cmd,
419 struct cxl_memdev_state *mds)
421 struct cxl_mem_command *c = &cxl_mem_commands[send_cmd->id];
422 const struct cxl_command_info *info = &c->info;
424 if (send_cmd->flags & ~CXL_MEM_COMMAND_FLAG_MASK)
430 if (send_cmd->in.rsvd || send_cmd->out.rsvd)
433 /* Check that the command is enabled for hardware */
434 if (!test_bit(info->id, mds->enabled_cmds))
437 /* Check that the command is not claimed for exclusive kernel use */
438 if (test_bit(info->id, mds->exclusive_cmds))
441 /* Check the input buffer is the expected size */
442 if ((info->size_in != CXL_VARIABLE_PAYLOAD) &&
443 (info->size_in != send_cmd->in.size))
446 /* Check the output buffer is at least large enough */
447 if ((info->size_out != CXL_VARIABLE_PAYLOAD) &&
448 (send_cmd->out.size < info->size_out))
451 *mem_cmd = (struct cxl_mem_command) {
454 .flags = info->flags,
455 .size_in = send_cmd->in.size,
456 .size_out = send_cmd->out.size,
465 * cxl_validate_cmd_from_user() - Check fields for CXL_MEM_SEND_COMMAND.
466 * @mbox_cmd: Sanitized and populated &struct cxl_mbox_cmd.
467 * @mds: The driver data for the operation
468 * @send_cmd: &struct cxl_send_command copied in from userspace.
471 * * %0 - @out_cmd is ready to send.
472 * * %-ENOTTY - Invalid command specified.
473 * * %-EINVAL - Reserved fields or invalid values were used.
474 * * %-ENOMEM - Input or output buffer wasn't sized properly.
475 * * %-EPERM - Attempted to use a protected command.
476 * * %-EBUSY - Kernel has claimed exclusive access to this opcode
478 * The result of this command is a fully validated command in @mbox_cmd that is
479 * safe to send to the hardware.
481 static int cxl_validate_cmd_from_user(struct cxl_mbox_cmd *mbox_cmd,
482 struct cxl_memdev_state *mds,
483 const struct cxl_send_command *send_cmd)
485 struct cxl_mem_command mem_cmd;
488 if (send_cmd->id == 0 || send_cmd->id >= CXL_MEM_COMMAND_ID_MAX)
492 * The user can never specify an input payload larger than what hardware
493 * supports, but output can be arbitrarily large (simply write out as
494 * much data as the hardware provides).
496 if (send_cmd->in.size > mds->payload_size)
499 /* Sanitize and construct a cxl_mem_command */
500 if (send_cmd->id == CXL_MEM_COMMAND_ID_RAW)
501 rc = cxl_to_mem_cmd_raw(&mem_cmd, send_cmd, mds);
503 rc = cxl_to_mem_cmd(&mem_cmd, send_cmd, mds);
508 /* Sanitize and construct a cxl_mbox_cmd */
509 return cxl_mbox_cmd_ctor(mbox_cmd, mds, mem_cmd.opcode,
510 mem_cmd.info.size_in, mem_cmd.info.size_out,
511 send_cmd->in.payload);
514 int cxl_query_cmd(struct cxl_memdev *cxlmd,
515 struct cxl_mem_query_commands __user *q)
517 struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlmd->cxlds);
518 struct device *dev = &cxlmd->dev;
519 struct cxl_mem_command *cmd;
523 dev_dbg(dev, "Query IOCTL\n");
525 if (get_user(n_commands, &q->n_commands))
528 /* returns the total number if 0 elements are requested. */
530 return put_user(ARRAY_SIZE(cxl_mem_commands), &q->n_commands);
533 * otherwise, return max(n_commands, total commands) cxl_command_info
536 cxl_for_each_cmd(cmd) {
537 struct cxl_command_info info = cmd->info;
539 if (test_bit(info.id, mds->enabled_cmds))
540 info.flags |= CXL_MEM_COMMAND_FLAG_ENABLED;
541 if (test_bit(info.id, mds->exclusive_cmds))
542 info.flags |= CXL_MEM_COMMAND_FLAG_EXCLUSIVE;
544 if (copy_to_user(&q->commands[j++], &info, sizeof(info)))
555 * handle_mailbox_cmd_from_user() - Dispatch a mailbox command for userspace.
556 * @mds: The driver data for the operation
557 * @mbox_cmd: The validated mailbox command.
558 * @out_payload: Pointer to userspace's output payload.
559 * @size_out: (Input) Max payload size to copy out.
560 * (Output) Payload size hardware generated.
561 * @retval: Hardware generated return code from the operation.
564 * * %0 - Mailbox transaction succeeded. This implies the mailbox
565 * protocol completed successfully not that the operation itself
567 * * %-ENOMEM - Couldn't allocate a bounce buffer.
568 * * %-EFAULT - Something happened with copy_to/from_user.
569 * * %-EINTR - Mailbox acquisition interrupted.
570 * * %-EXXX - Transaction level failures.
572 * Dispatches a mailbox command on behalf of a userspace request.
573 * The output payload is copied to userspace.
575 * See cxl_send_cmd().
577 static int handle_mailbox_cmd_from_user(struct cxl_memdev_state *mds,
578 struct cxl_mbox_cmd *mbox_cmd,
579 u64 out_payload, s32 *size_out,
582 struct device *dev = mds->cxlds.dev;
586 "Submitting %s command for user\n"
589 cxl_mem_opcode_to_name(mbox_cmd->opcode),
590 mbox_cmd->opcode, mbox_cmd->size_in);
592 rc = mds->mbox_send(mds, mbox_cmd);
597 * @size_out contains the max size that's allowed to be written back out
598 * to userspace. While the payload may have written more output than
599 * this it will have to be ignored.
601 if (mbox_cmd->size_out) {
602 dev_WARN_ONCE(dev, mbox_cmd->size_out > *size_out,
603 "Invalid return size\n");
604 if (copy_to_user(u64_to_user_ptr(out_payload),
605 mbox_cmd->payload_out, mbox_cmd->size_out)) {
611 *size_out = mbox_cmd->size_out;
612 *retval = mbox_cmd->return_code;
615 cxl_mbox_cmd_dtor(mbox_cmd);
619 int cxl_send_cmd(struct cxl_memdev *cxlmd, struct cxl_send_command __user *s)
621 struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlmd->cxlds);
622 struct device *dev = &cxlmd->dev;
623 struct cxl_send_command send;
624 struct cxl_mbox_cmd mbox_cmd;
627 dev_dbg(dev, "Send IOCTL\n");
629 if (copy_from_user(&send, s, sizeof(send)))
632 rc = cxl_validate_cmd_from_user(&mbox_cmd, mds, &send);
636 rc = handle_mailbox_cmd_from_user(mds, &mbox_cmd, send.out.payload,
637 &send.out.size, &send.retval);
641 if (copy_to_user(s, &send, sizeof(send)))
647 static int cxl_xfer_log(struct cxl_memdev_state *mds, uuid_t *uuid,
650 u32 remaining = *size;
654 u32 xfer_size = min_t(u32, remaining, mds->payload_size);
655 struct cxl_mbox_cmd mbox_cmd;
656 struct cxl_mbox_get_log log;
659 log = (struct cxl_mbox_get_log) {
661 .offset = cpu_to_le32(offset),
662 .length = cpu_to_le32(xfer_size),
665 mbox_cmd = (struct cxl_mbox_cmd) {
666 .opcode = CXL_MBOX_OP_GET_LOG,
667 .size_in = sizeof(log),
669 .size_out = xfer_size,
673 rc = cxl_internal_send_cmd(mds, &mbox_cmd);
676 * The output payload length that indicates the number
677 * of valid bytes can be smaller than the Log buffer
680 if (rc == -EIO && mbox_cmd.size_out < xfer_size) {
681 offset += mbox_cmd.size_out;
689 remaining -= xfer_size;
699 * cxl_walk_cel() - Walk through the Command Effects Log.
700 * @mds: The driver data for the operation
701 * @size: Length of the Command Effects Log.
704 * Iterate over each entry in the CEL and determine if the driver supports the
705 * command. If so, the command is enabled for the device and can be used later.
707 static void cxl_walk_cel(struct cxl_memdev_state *mds, size_t size, u8 *cel)
709 struct cxl_cel_entry *cel_entry;
710 const int cel_entries = size / sizeof(*cel_entry);
711 struct device *dev = mds->cxlds.dev;
714 cel_entry = (struct cxl_cel_entry *) cel;
716 for (i = 0; i < cel_entries; i++) {
717 u16 opcode = le16_to_cpu(cel_entry[i].opcode);
718 struct cxl_mem_command *cmd = cxl_mem_find_command(opcode);
722 set_bit(cmd->info.id, mds->enabled_cmds);
726 if (cxl_is_poison_command(opcode)) {
727 cxl_set_poison_cmd_enabled(&mds->poison, opcode);
731 if (cxl_is_security_command(opcode)) {
732 cxl_set_security_cmd_enabled(&mds->security, opcode);
736 dev_dbg(dev, "Opcode 0x%04x %s\n", opcode,
737 enabled ? "enabled" : "unsupported by driver");
741 static struct cxl_mbox_get_supported_logs *cxl_get_gsl(struct cxl_memdev_state *mds)
743 struct cxl_mbox_get_supported_logs *ret;
744 struct cxl_mbox_cmd mbox_cmd;
747 ret = kvmalloc(mds->payload_size, GFP_KERNEL);
749 return ERR_PTR(-ENOMEM);
751 mbox_cmd = (struct cxl_mbox_cmd) {
752 .opcode = CXL_MBOX_OP_GET_SUPPORTED_LOGS,
753 .size_out = mds->payload_size,
755 /* At least the record number field must be valid */
758 rc = cxl_internal_send_cmd(mds, &mbox_cmd);
773 /* See CXL 2.0 Table 170. Get Log Input Payload */
774 static const uuid_t log_uuid[] = {
775 [CEL_UUID] = DEFINE_CXL_CEL_UUID,
776 [VENDOR_DEBUG_UUID] = DEFINE_CXL_VENDOR_DEBUG_UUID,
780 * cxl_enumerate_cmds() - Enumerate commands for a device.
781 * @mds: The driver data for the operation
783 * Returns 0 if enumerate completed successfully.
785 * CXL devices have optional support for certain commands. This function will
786 * determine the set of supported commands for the hardware and update the
787 * enabled_cmds bitmap in the @mds.
789 int cxl_enumerate_cmds(struct cxl_memdev_state *mds)
791 struct cxl_mbox_get_supported_logs *gsl;
792 struct device *dev = mds->cxlds.dev;
793 struct cxl_mem_command *cmd;
796 gsl = cxl_get_gsl(mds);
801 for (i = 0; i < le16_to_cpu(gsl->entries); i++) {
802 u32 size = le32_to_cpu(gsl->entry[i].size);
803 uuid_t uuid = gsl->entry[i].uuid;
806 dev_dbg(dev, "Found LOG type %pU of size %d", &uuid, size);
808 if (!uuid_equal(&uuid, &log_uuid[CEL_UUID]))
811 log = kvmalloc(size, GFP_KERNEL);
817 rc = cxl_xfer_log(mds, &uuid, &size, log);
823 cxl_walk_cel(mds, size, log);
826 /* In case CEL was bogus, enable some default commands. */
827 cxl_for_each_cmd(cmd)
828 if (cmd->flags & CXL_CMD_FLAG_FORCE_ENABLE)
829 set_bit(cmd->info.id, mds->enabled_cmds);
831 /* Found the required CEL */
838 EXPORT_SYMBOL_NS_GPL(cxl_enumerate_cmds, CXL);
840 void cxl_event_trace_record(const struct cxl_memdev *cxlmd,
841 enum cxl_event_log_type type,
842 enum cxl_event_type event_type,
843 const uuid_t *uuid, union cxl_event *evt)
845 if (event_type == CXL_CPER_EVENT_GEN_MEDIA)
846 trace_cxl_general_media(cxlmd, type, &evt->gen_media);
847 else if (event_type == CXL_CPER_EVENT_DRAM)
848 trace_cxl_dram(cxlmd, type, &evt->dram);
849 else if (event_type == CXL_CPER_EVENT_MEM_MODULE)
850 trace_cxl_memory_module(cxlmd, type, &evt->mem_module);
852 trace_cxl_generic_event(cxlmd, type, uuid, &evt->generic);
854 EXPORT_SYMBOL_NS_GPL(cxl_event_trace_record, CXL);
856 static void __cxl_event_trace_record(const struct cxl_memdev *cxlmd,
857 enum cxl_event_log_type type,
858 struct cxl_event_record_raw *record)
860 enum cxl_event_type ev_type = CXL_CPER_EVENT_GENERIC;
861 const uuid_t *uuid = &record->id;
863 if (uuid_equal(uuid, &CXL_EVENT_GEN_MEDIA_UUID))
864 ev_type = CXL_CPER_EVENT_GEN_MEDIA;
865 else if (uuid_equal(uuid, &CXL_EVENT_DRAM_UUID))
866 ev_type = CXL_CPER_EVENT_DRAM;
867 else if (uuid_equal(uuid, &CXL_EVENT_MEM_MODULE_UUID))
868 ev_type = CXL_CPER_EVENT_MEM_MODULE;
870 cxl_event_trace_record(cxlmd, type, ev_type, uuid, &record->event);
873 static int cxl_clear_event_record(struct cxl_memdev_state *mds,
874 enum cxl_event_log_type log,
875 struct cxl_get_event_payload *get_pl)
877 struct cxl_mbox_clear_event_payload *payload;
878 u16 total = le16_to_cpu(get_pl->record_count);
879 u8 max_handles = CXL_CLEAR_EVENT_MAX_HANDLES;
880 size_t pl_size = struct_size(payload, handles, max_handles);
881 struct cxl_mbox_cmd mbox_cmd;
886 /* Payload size may limit the max handles */
887 if (pl_size > mds->payload_size) {
888 max_handles = (mds->payload_size - sizeof(*payload)) /
890 pl_size = struct_size(payload, handles, max_handles);
893 payload = kvzalloc(pl_size, GFP_KERNEL);
897 *payload = (struct cxl_mbox_clear_event_payload) {
901 mbox_cmd = (struct cxl_mbox_cmd) {
902 .opcode = CXL_MBOX_OP_CLEAR_EVENT_RECORD,
903 .payload_in = payload,
908 * Clear Event Records uses u8 for the handle cnt while Get Event
909 * Record can return up to 0xffff records.
912 for (cnt = 0; cnt < total; cnt++) {
913 struct cxl_event_record_raw *raw = &get_pl->records[cnt];
914 struct cxl_event_generic *gen = &raw->event.generic;
916 payload->handles[i++] = gen->hdr.handle;
917 dev_dbg(mds->cxlds.dev, "Event log '%d': Clearing %u\n", log,
918 le16_to_cpu(payload->handles[i]));
920 if (i == max_handles) {
921 payload->nr_recs = i;
922 rc = cxl_internal_send_cmd(mds, &mbox_cmd);
929 /* Clear what is left if any */
931 payload->nr_recs = i;
932 mbox_cmd.size_in = struct_size(payload, handles, i);
933 rc = cxl_internal_send_cmd(mds, &mbox_cmd);
943 static void cxl_mem_get_records_log(struct cxl_memdev_state *mds,
944 enum cxl_event_log_type type)
946 struct cxl_memdev *cxlmd = mds->cxlds.cxlmd;
947 struct device *dev = mds->cxlds.dev;
948 struct cxl_get_event_payload *payload;
949 struct cxl_mbox_cmd mbox_cmd;
953 mutex_lock(&mds->event.log_lock);
954 payload = mds->event.buf;
956 mbox_cmd = (struct cxl_mbox_cmd) {
957 .opcode = CXL_MBOX_OP_GET_EVENT_RECORD,
958 .payload_in = &log_type,
959 .size_in = sizeof(log_type),
960 .payload_out = payload,
961 .size_out = mds->payload_size,
962 .min_out = struct_size(payload, records, 0),
968 rc = cxl_internal_send_cmd(mds, &mbox_cmd);
970 dev_err_ratelimited(dev,
971 "Event log '%d': Failed to query event records : %d",
976 nr_rec = le16_to_cpu(payload->record_count);
980 for (i = 0; i < nr_rec; i++)
981 __cxl_event_trace_record(cxlmd, type,
982 &payload->records[i]);
984 if (payload->flags & CXL_GET_EVENT_FLAG_OVERFLOW)
985 trace_cxl_overflow(cxlmd, type, payload);
987 rc = cxl_clear_event_record(mds, type, payload);
989 dev_err_ratelimited(dev,
990 "Event log '%d': Failed to clear events : %d",
996 mutex_unlock(&mds->event.log_lock);
1000 * cxl_mem_get_event_records - Get Event Records from the device
1001 * @mds: The driver data for the operation
1002 * @status: Event Status register value identifying which events are available.
1004 * Retrieve all event records available on the device, report them as trace
1005 * events, and clear them.
1007 * See CXL rev 3.0 @8.2.9.2.2 Get Event Records
1008 * See CXL rev 3.0 @8.2.9.2.3 Clear Event Records
1010 void cxl_mem_get_event_records(struct cxl_memdev_state *mds, u32 status)
1012 dev_dbg(mds->cxlds.dev, "Reading event logs: %x\n", status);
1014 if (status & CXLDEV_EVENT_STATUS_FATAL)
1015 cxl_mem_get_records_log(mds, CXL_EVENT_TYPE_FATAL);
1016 if (status & CXLDEV_EVENT_STATUS_FAIL)
1017 cxl_mem_get_records_log(mds, CXL_EVENT_TYPE_FAIL);
1018 if (status & CXLDEV_EVENT_STATUS_WARN)
1019 cxl_mem_get_records_log(mds, CXL_EVENT_TYPE_WARN);
1020 if (status & CXLDEV_EVENT_STATUS_INFO)
1021 cxl_mem_get_records_log(mds, CXL_EVENT_TYPE_INFO);
1023 EXPORT_SYMBOL_NS_GPL(cxl_mem_get_event_records, CXL);
1026 * cxl_mem_get_partition_info - Get partition info
1027 * @mds: The driver data for the operation
1029 * Retrieve the current partition info for the device specified. The active
1030 * values are the current capacity in bytes. If not 0, the 'next' values are
1031 * the pending values, in bytes, which take affect on next cold reset.
1033 * Return: 0 if no error: or the result of the mailbox command.
1035 * See CXL @8.2.9.5.2.1 Get Partition Info
1037 static int cxl_mem_get_partition_info(struct cxl_memdev_state *mds)
1039 struct cxl_mbox_get_partition_info pi;
1040 struct cxl_mbox_cmd mbox_cmd;
1043 mbox_cmd = (struct cxl_mbox_cmd) {
1044 .opcode = CXL_MBOX_OP_GET_PARTITION_INFO,
1045 .size_out = sizeof(pi),
1048 rc = cxl_internal_send_cmd(mds, &mbox_cmd);
1052 mds->active_volatile_bytes =
1053 le64_to_cpu(pi.active_volatile_cap) * CXL_CAPACITY_MULTIPLIER;
1054 mds->active_persistent_bytes =
1055 le64_to_cpu(pi.active_persistent_cap) * CXL_CAPACITY_MULTIPLIER;
1056 mds->next_volatile_bytes =
1057 le64_to_cpu(pi.next_volatile_cap) * CXL_CAPACITY_MULTIPLIER;
1058 mds->next_persistent_bytes =
1059 le64_to_cpu(pi.next_volatile_cap) * CXL_CAPACITY_MULTIPLIER;
1065 * cxl_dev_state_identify() - Send the IDENTIFY command to the device.
1066 * @mds: The driver data for the operation
1068 * Return: 0 if identify was executed successfully or media not ready.
1070 * This will dispatch the identify command to the device and on success populate
1071 * structures to be exported to sysfs.
1073 int cxl_dev_state_identify(struct cxl_memdev_state *mds)
1075 /* See CXL 2.0 Table 175 Identify Memory Device Output Payload */
1076 struct cxl_mbox_identify id;
1077 struct cxl_mbox_cmd mbox_cmd;
1081 if (!mds->cxlds.media_ready)
1084 mbox_cmd = (struct cxl_mbox_cmd) {
1085 .opcode = CXL_MBOX_OP_IDENTIFY,
1086 .size_out = sizeof(id),
1089 rc = cxl_internal_send_cmd(mds, &mbox_cmd);
1094 le64_to_cpu(id.total_capacity) * CXL_CAPACITY_MULTIPLIER;
1095 mds->volatile_only_bytes =
1096 le64_to_cpu(id.volatile_capacity) * CXL_CAPACITY_MULTIPLIER;
1097 mds->persistent_only_bytes =
1098 le64_to_cpu(id.persistent_capacity) * CXL_CAPACITY_MULTIPLIER;
1099 mds->partition_align_bytes =
1100 le64_to_cpu(id.partition_align) * CXL_CAPACITY_MULTIPLIER;
1102 mds->lsa_size = le32_to_cpu(id.lsa_size);
1103 memcpy(mds->firmware_version, id.fw_revision,
1104 sizeof(id.fw_revision));
1106 if (test_bit(CXL_POISON_ENABLED_LIST, mds->poison.enabled_cmds)) {
1107 val = get_unaligned_le24(id.poison_list_max_mer);
1108 mds->poison.max_errors = min_t(u32, val, CXL_POISON_LIST_MAX);
1113 EXPORT_SYMBOL_NS_GPL(cxl_dev_state_identify, CXL);
1115 static int __cxl_mem_sanitize(struct cxl_memdev_state *mds, u16 cmd)
1119 struct cxl_get_security_output {
1122 struct cxl_mbox_cmd sec_cmd = {
1123 .opcode = CXL_MBOX_OP_GET_SECURITY_STATE,
1124 .payload_out = &out,
1125 .size_out = sizeof(out),
1127 struct cxl_mbox_cmd mbox_cmd = { .opcode = cmd };
1128 struct cxl_dev_state *cxlds = &mds->cxlds;
1130 if (cmd != CXL_MBOX_OP_SANITIZE && cmd != CXL_MBOX_OP_SECURE_ERASE)
1133 rc = cxl_internal_send_cmd(mds, &sec_cmd);
1135 dev_err(cxlds->dev, "Failed to get security state : %d", rc);
1140 * Prior to using these commands, any security applied to
1141 * the user data areas of the device shall be DISABLED (or
1142 * UNLOCKED for secure erase case).
1144 sec_out = le32_to_cpu(out.flags);
1145 if (sec_out & CXL_PMEM_SEC_STATE_USER_PASS_SET)
1148 if (cmd == CXL_MBOX_OP_SECURE_ERASE &&
1149 sec_out & CXL_PMEM_SEC_STATE_LOCKED)
1152 rc = cxl_internal_send_cmd(mds, &mbox_cmd);
1154 dev_err(cxlds->dev, "Failed to sanitize device : %d", rc);
1163 * cxl_mem_sanitize() - Send a sanitization command to the device.
1164 * @cxlmd: The device for the operation
1165 * @cmd: The specific sanitization command opcode
1167 * Return: 0 if the command was executed successfully, regardless of
1168 * whether or not the actual security operation is done in the background,
1169 * such as for the Sanitize case.
1170 * Error return values can be the result of the mailbox command, -EINVAL
1171 * when security requirements are not met or invalid contexts, or -EBUSY
1172 * if the sanitize operation is already in flight.
1174 * See CXL 3.0 @8.2.9.8.5.1 Sanitize and @8.2.9.8.5.2 Secure Erase.
1176 int cxl_mem_sanitize(struct cxl_memdev *cxlmd, u16 cmd)
1178 struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlmd->cxlds);
1179 struct cxl_port *endpoint;
1182 /* synchronize with cxl_mem_probe() and decoder write operations */
1183 device_lock(&cxlmd->dev);
1184 endpoint = cxlmd->endpoint;
1185 down_read(&cxl_region_rwsem);
1187 * Require an endpoint to be safe otherwise the driver can not
1188 * be sure that the device is unmapped.
1190 if (endpoint && cxl_num_decoders_committed(endpoint) == 0)
1191 rc = __cxl_mem_sanitize(mds, cmd);
1194 up_read(&cxl_region_rwsem);
1195 device_unlock(&cxlmd->dev);
1200 static int add_dpa_res(struct device *dev, struct resource *parent,
1201 struct resource *res, resource_size_t start,
1202 resource_size_t size, const char *type)
1208 res->end = start + size - 1;
1209 res->flags = IORESOURCE_MEM;
1210 if (resource_size(res) == 0) {
1211 dev_dbg(dev, "DPA(%s): no capacity\n", res->name);
1214 rc = request_resource(parent, res);
1216 dev_err(dev, "DPA(%s): failed to track %pr (%d)\n", res->name,
1221 dev_dbg(dev, "DPA(%s): %pr\n", res->name, res);
1226 int cxl_mem_create_range_info(struct cxl_memdev_state *mds)
1228 struct cxl_dev_state *cxlds = &mds->cxlds;
1229 struct device *dev = cxlds->dev;
1232 if (!cxlds->media_ready) {
1233 cxlds->dpa_res = DEFINE_RES_MEM(0, 0);
1234 cxlds->ram_res = DEFINE_RES_MEM(0, 0);
1235 cxlds->pmem_res = DEFINE_RES_MEM(0, 0);
1239 cxlds->dpa_res = DEFINE_RES_MEM(0, mds->total_bytes);
1241 if (mds->partition_align_bytes == 0) {
1242 rc = add_dpa_res(dev, &cxlds->dpa_res, &cxlds->ram_res, 0,
1243 mds->volatile_only_bytes, "ram");
1246 return add_dpa_res(dev, &cxlds->dpa_res, &cxlds->pmem_res,
1247 mds->volatile_only_bytes,
1248 mds->persistent_only_bytes, "pmem");
1251 rc = cxl_mem_get_partition_info(mds);
1253 dev_err(dev, "Failed to query partition information\n");
1257 rc = add_dpa_res(dev, &cxlds->dpa_res, &cxlds->ram_res, 0,
1258 mds->active_volatile_bytes, "ram");
1261 return add_dpa_res(dev, &cxlds->dpa_res, &cxlds->pmem_res,
1262 mds->active_volatile_bytes,
1263 mds->active_persistent_bytes, "pmem");
1265 EXPORT_SYMBOL_NS_GPL(cxl_mem_create_range_info, CXL);
1267 int cxl_set_timestamp(struct cxl_memdev_state *mds)
1269 struct cxl_mbox_cmd mbox_cmd;
1270 struct cxl_mbox_set_timestamp_in pi;
1273 pi.timestamp = cpu_to_le64(ktime_get_real_ns());
1274 mbox_cmd = (struct cxl_mbox_cmd) {
1275 .opcode = CXL_MBOX_OP_SET_TIMESTAMP,
1276 .size_in = sizeof(pi),
1280 rc = cxl_internal_send_cmd(mds, &mbox_cmd);
1282 * Command is optional. Devices may have another way of providing
1283 * a timestamp, or may return all 0s in timestamp fields.
1284 * Don't report an error if this command isn't supported
1286 if (rc && (mbox_cmd.return_code != CXL_MBOX_CMD_RC_UNSUPPORTED))
1291 EXPORT_SYMBOL_NS_GPL(cxl_set_timestamp, CXL);
1293 int cxl_mem_get_poison(struct cxl_memdev *cxlmd, u64 offset, u64 len,
1294 struct cxl_region *cxlr)
1296 struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlmd->cxlds);
1297 struct cxl_mbox_poison_out *po;
1298 struct cxl_mbox_poison_in pi;
1299 struct cxl_mbox_cmd mbox_cmd;
1303 rc = mutex_lock_interruptible(&mds->poison.lock);
1307 po = mds->poison.list_out;
1308 pi.offset = cpu_to_le64(offset);
1309 pi.length = cpu_to_le64(len / CXL_POISON_LEN_MULT);
1311 mbox_cmd = (struct cxl_mbox_cmd) {
1312 .opcode = CXL_MBOX_OP_GET_POISON,
1313 .size_in = sizeof(pi),
1315 .size_out = mds->payload_size,
1317 .min_out = struct_size(po, record, 0),
1321 rc = cxl_internal_send_cmd(mds, &mbox_cmd);
1325 for (int i = 0; i < le16_to_cpu(po->count); i++)
1326 trace_cxl_poison(cxlmd, cxlr, &po->record[i],
1327 po->flags, po->overflow_ts,
1328 CXL_POISON_TRACE_LIST);
1330 /* Protect against an uncleared _FLAG_MORE */
1331 nr_records = nr_records + le16_to_cpu(po->count);
1332 if (nr_records >= mds->poison.max_errors) {
1333 dev_dbg(&cxlmd->dev, "Max Error Records reached: %d\n",
1337 } while (po->flags & CXL_POISON_FLAG_MORE);
1339 mutex_unlock(&mds->poison.lock);
1342 EXPORT_SYMBOL_NS_GPL(cxl_mem_get_poison, CXL);
1344 static void free_poison_buf(void *buf)
1349 /* Get Poison List output buffer is protected by mds->poison.lock */
1350 static int cxl_poison_alloc_buf(struct cxl_memdev_state *mds)
1352 mds->poison.list_out = kvmalloc(mds->payload_size, GFP_KERNEL);
1353 if (!mds->poison.list_out)
1356 return devm_add_action_or_reset(mds->cxlds.dev, free_poison_buf,
1357 mds->poison.list_out);
1360 int cxl_poison_state_init(struct cxl_memdev_state *mds)
1364 if (!test_bit(CXL_POISON_ENABLED_LIST, mds->poison.enabled_cmds))
1367 rc = cxl_poison_alloc_buf(mds);
1369 clear_bit(CXL_POISON_ENABLED_LIST, mds->poison.enabled_cmds);
1373 mutex_init(&mds->poison.lock);
1376 EXPORT_SYMBOL_NS_GPL(cxl_poison_state_init, CXL);
1378 struct cxl_memdev_state *cxl_memdev_state_create(struct device *dev)
1380 struct cxl_memdev_state *mds;
1382 mds = devm_kzalloc(dev, sizeof(*mds), GFP_KERNEL);
1384 dev_err(dev, "No memory available\n");
1385 return ERR_PTR(-ENOMEM);
1388 mutex_init(&mds->mbox_mutex);
1389 mutex_init(&mds->event.log_lock);
1390 mds->cxlds.dev = dev;
1391 mds->cxlds.reg_map.host = dev;
1392 mds->cxlds.reg_map.resource = CXL_RESOURCE_NONE;
1393 mds->cxlds.type = CXL_DEVTYPE_CLASSMEM;
1394 INIT_LIST_HEAD(&mds->ram_perf_list);
1395 INIT_LIST_HEAD(&mds->pmem_perf_list);
1399 EXPORT_SYMBOL_NS_GPL(cxl_memdev_state_create, CXL);
1401 void __init cxl_mbox_init(void)
1403 struct dentry *mbox_debugfs;
1405 mbox_debugfs = cxl_debugfs_create_dir("mbox");
1406 debugfs_create_bool("raw_allow_all", 0600, mbox_debugfs,
1407 &cxl_raw_allow_all);