xref: /linux/drivers/cxl/core/mbox.c (revision f5c31bcf604db54470868f3118a60dc4a9ba8813)
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>
8 #include <cxlpci.h>
9 #include <cxlmem.h>
10 #include <cxl.h>
11 
12 #include "core.h"
13 #include "trace.h"
14 
15 static bool cxl_raw_allow_all;
16 
17 /**
18  * DOC: cxl mbox
19  *
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.
24  */
25 
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)++)
29 
30 #define CXL_CMD(_id, sin, sout, _flags)                                        \
31 	[CXL_MEM_COMMAND_ID_##_id] = {                                         \
32 	.info =	{                                                              \
33 			.id = CXL_MEM_COMMAND_ID_##_id,                        \
34 			.size_in = sin,                                        \
35 			.size_out = sout,                                      \
36 		},                                                             \
37 	.opcode = CXL_MBOX_OP_##_id,                                           \
38 	.flags = _flags,                                                       \
39 	}
40 
41 #define CXL_VARIABLE_PAYLOAD	~0U
42 /*
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.
47  */
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),
52 #endif
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),
67 };
68 
69 /*
70  * Commands that RAW doesn't permit. The rationale for each:
71  *
72  * CXL_MBOX_OP_ACTIVATE_FW: Firmware activation requires adjustment /
73  * coordination of transaction timeout values at the root bridge level.
74  *
75  * CXL_MBOX_OP_SET_PARTITION_INFO: The device memory map may change live
76  * and needs to be coordinated with HDM updates.
77  *
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.
80  *
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
83  * assertion.
84  *
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.
87  *
88  * CXL_MBOX_OP_[GET_,INJECT_,CLEAR_]POISON: These commands require kernel
89  * driver orchestration for safety.
90  */
91 static u16 cxl_disabled_raw_commands[] = {
92 	CXL_MBOX_OP_ACTIVATE_FW,
93 	CXL_MBOX_OP_SET_PARTITION_INFO,
94 	CXL_MBOX_OP_SET_LSA,
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,
101 };
102 
103 /*
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
108  */
109 static u8 security_command_sets[] = {
110 	0x44, /* Sanitize */
111 	0x45, /* Persistent Memory Data-at-rest Security */
112 	0x46, /* Security Passthrough */
113 };
114 
115 static bool cxl_is_security_command(u16 opcode)
116 {
117 	int i;
118 
119 	for (i = 0; i < ARRAY_SIZE(security_command_sets); i++)
120 		if (security_command_sets[i] == (opcode >> 8))
121 			return true;
122 	return false;
123 }
124 
125 static void cxl_set_security_cmd_enabled(struct cxl_security_state *security,
126 					 u16 opcode)
127 {
128 	switch (opcode) {
129 	case CXL_MBOX_OP_SANITIZE:
130 		set_bit(CXL_SEC_ENABLED_SANITIZE, security->enabled_cmds);
131 		break;
132 	case CXL_MBOX_OP_SECURE_ERASE:
133 		set_bit(CXL_SEC_ENABLED_SECURE_ERASE,
134 			security->enabled_cmds);
135 		break;
136 	case CXL_MBOX_OP_GET_SECURITY_STATE:
137 		set_bit(CXL_SEC_ENABLED_GET_SECURITY_STATE,
138 			security->enabled_cmds);
139 		break;
140 	case CXL_MBOX_OP_SET_PASSPHRASE:
141 		set_bit(CXL_SEC_ENABLED_SET_PASSPHRASE,
142 			security->enabled_cmds);
143 		break;
144 	case CXL_MBOX_OP_DISABLE_PASSPHRASE:
145 		set_bit(CXL_SEC_ENABLED_DISABLE_PASSPHRASE,
146 			security->enabled_cmds);
147 		break;
148 	case CXL_MBOX_OP_UNLOCK:
149 		set_bit(CXL_SEC_ENABLED_UNLOCK, security->enabled_cmds);
150 		break;
151 	case CXL_MBOX_OP_FREEZE_SECURITY:
152 		set_bit(CXL_SEC_ENABLED_FREEZE_SECURITY,
153 			security->enabled_cmds);
154 		break;
155 	case CXL_MBOX_OP_PASSPHRASE_SECURE_ERASE:
156 		set_bit(CXL_SEC_ENABLED_PASSPHRASE_SECURE_ERASE,
157 			security->enabled_cmds);
158 		break;
159 	default:
160 		break;
161 	}
162 }
163 
164 static bool cxl_is_poison_command(u16 opcode)
165 {
166 #define CXL_MBOX_OP_POISON_CMDS 0x43
167 
168 	if ((opcode >> 8) == CXL_MBOX_OP_POISON_CMDS)
169 		return true;
170 
171 	return false;
172 }
173 
174 static void cxl_set_poison_cmd_enabled(struct cxl_poison_state *poison,
175 				       u16 opcode)
176 {
177 	switch (opcode) {
178 	case CXL_MBOX_OP_GET_POISON:
179 		set_bit(CXL_POISON_ENABLED_LIST, poison->enabled_cmds);
180 		break;
181 	case CXL_MBOX_OP_INJECT_POISON:
182 		set_bit(CXL_POISON_ENABLED_INJECT, poison->enabled_cmds);
183 		break;
184 	case CXL_MBOX_OP_CLEAR_POISON:
185 		set_bit(CXL_POISON_ENABLED_CLEAR, poison->enabled_cmds);
186 		break;
187 	case CXL_MBOX_OP_GET_SCAN_MEDIA_CAPS:
188 		set_bit(CXL_POISON_ENABLED_SCAN_CAPS, poison->enabled_cmds);
189 		break;
190 	case CXL_MBOX_OP_SCAN_MEDIA:
191 		set_bit(CXL_POISON_ENABLED_SCAN_MEDIA, poison->enabled_cmds);
192 		break;
193 	case CXL_MBOX_OP_GET_SCAN_MEDIA:
194 		set_bit(CXL_POISON_ENABLED_SCAN_RESULTS, poison->enabled_cmds);
195 		break;
196 	default:
197 		break;
198 	}
199 }
200 
201 static struct cxl_mem_command *cxl_mem_find_command(u16 opcode)
202 {
203 	struct cxl_mem_command *c;
204 
205 	cxl_for_each_cmd(c)
206 		if (c->opcode == opcode)
207 			return c;
208 
209 	return NULL;
210 }
211 
212 static const char *cxl_mem_opcode_to_name(u16 opcode)
213 {
214 	struct cxl_mem_command *c;
215 
216 	c = cxl_mem_find_command(opcode);
217 	if (!c)
218 		return NULL;
219 
220 	return cxl_command_names[c->info.id].name;
221 }
222 
223 /**
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
227  *
228  * Context: Any context.
229  * Return:
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.
236  *
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.
240  */
241 int cxl_internal_send_cmd(struct cxl_memdev_state *mds,
242 			  struct cxl_mbox_cmd *mbox_cmd)
243 {
244 	size_t out_size, min_out;
245 	int rc;
246 
247 	if (mbox_cmd->size_in > mds->payload_size ||
248 	    mbox_cmd->size_out > mds->payload_size)
249 		return -E2BIG;
250 
251 	out_size = mbox_cmd->size_out;
252 	min_out = mbox_cmd->min_out;
253 	rc = mds->mbox_send(mds, mbox_cmd);
254 	/*
255 	 * EIO is reserved for a payload size mismatch and mbox_send()
256 	 * may not return this error.
257 	 */
258 	if (WARN_ONCE(rc == -EIO, "Bad return code: -EIO"))
259 		return -ENXIO;
260 	if (rc)
261 		return rc;
262 
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);
266 
267 	if (!out_size)
268 		return 0;
269 
270 	/*
271 	 * Variable sized output needs to at least satisfy the caller's
272 	 * minimum if not the fully requested size.
273 	 */
274 	if (min_out == 0)
275 		min_out = out_size;
276 
277 	if (mbox_cmd->size_out < min_out)
278 		return -EIO;
279 	return 0;
280 }
281 EXPORT_SYMBOL_NS_GPL(cxl_internal_send_cmd, CXL);
282 
283 static bool cxl_mem_raw_command_allowed(u16 opcode)
284 {
285 	int i;
286 
287 	if (!IS_ENABLED(CONFIG_CXL_MEM_RAW_COMMANDS))
288 		return false;
289 
290 	if (security_locked_down(LOCKDOWN_PCI_ACCESS))
291 		return false;
292 
293 	if (cxl_raw_allow_all)
294 		return true;
295 
296 	if (cxl_is_security_command(opcode))
297 		return false;
298 
299 	for (i = 0; i < ARRAY_SIZE(cxl_disabled_raw_commands); i++)
300 		if (cxl_disabled_raw_commands[i] == opcode)
301 			return false;
302 
303 	return true;
304 }
305 
306 /**
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.
310  *
311  * Return:
312  *  * true	- payload_in passes check for @opcode.
313  *  * false	- payload_in contains invalid or unsupported values.
314  *
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.
321  *
322  * The specific checks are determined by the opcode.
323  */
324 static bool cxl_payload_from_user_allowed(u16 opcode, void *payload_in)
325 {
326 	switch (opcode) {
327 	case CXL_MBOX_OP_SET_PARTITION_INFO: {
328 		struct cxl_mbox_set_partition_info *pi = payload_in;
329 
330 		if (pi->flags & CXL_SET_PARTITION_IMMEDIATE_FLAG)
331 			return false;
332 		break;
333 	}
334 	default:
335 		break;
336 	}
337 	return true;
338 }
339 
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)
343 {
344 	*mbox = (struct cxl_mbox_cmd) {
345 		.opcode = opcode,
346 		.size_in = in_size,
347 	};
348 
349 	if (in_size) {
350 		mbox->payload_in = vmemdup_user(u64_to_user_ptr(in_payload),
351 						in_size);
352 		if (IS_ERR(mbox->payload_in))
353 			return PTR_ERR(mbox->payload_in);
354 
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);
359 			return -EBUSY;
360 		}
361 	}
362 
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;
366 	else
367 		mbox->size_out = out_size;
368 
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);
373 			return -ENOMEM;
374 		}
375 	}
376 	return 0;
377 }
378 
379 static void cxl_mbox_cmd_dtor(struct cxl_mbox_cmd *mbox)
380 {
381 	kvfree(mbox->payload_in);
382 	kvfree(mbox->payload_out);
383 }
384 
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)
388 {
389 	if (send_cmd->raw.rsvd)
390 		return -EINVAL;
391 
392 	/*
393 	 * Unlike supported commands, the output size of RAW commands
394 	 * gets passed along without further checking, so it must be
395 	 * validated here.
396 	 */
397 	if (send_cmd->out.size > mds->payload_size)
398 		return -EINVAL;
399 
400 	if (!cxl_mem_raw_command_allowed(send_cmd->raw.opcode))
401 		return -EPERM;
402 
403 	dev_WARN_ONCE(mds->cxlds.dev, true, "raw command path used\n");
404 
405 	*mem_cmd = (struct cxl_mem_command) {
406 		.info = {
407 			.id = CXL_MEM_COMMAND_ID_RAW,
408 			.size_in = send_cmd->in.size,
409 			.size_out = send_cmd->out.size,
410 		},
411 		.opcode = send_cmd->raw.opcode
412 	};
413 
414 	return 0;
415 }
416 
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)
420 {
421 	struct cxl_mem_command *c = &cxl_mem_commands[send_cmd->id];
422 	const struct cxl_command_info *info = &c->info;
423 
424 	if (send_cmd->flags & ~CXL_MEM_COMMAND_FLAG_MASK)
425 		return -EINVAL;
426 
427 	if (send_cmd->rsvd)
428 		return -EINVAL;
429 
430 	if (send_cmd->in.rsvd || send_cmd->out.rsvd)
431 		return -EINVAL;
432 
433 	/* Check that the command is enabled for hardware */
434 	if (!test_bit(info->id, mds->enabled_cmds))
435 		return -ENOTTY;
436 
437 	/* Check that the command is not claimed for exclusive kernel use */
438 	if (test_bit(info->id, mds->exclusive_cmds))
439 		return -EBUSY;
440 
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))
444 		return -ENOMEM;
445 
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))
449 		return -ENOMEM;
450 
451 	*mem_cmd = (struct cxl_mem_command) {
452 		.info = {
453 			.id = info->id,
454 			.flags = info->flags,
455 			.size_in = send_cmd->in.size,
456 			.size_out = send_cmd->out.size,
457 		},
458 		.opcode = c->opcode
459 	};
460 
461 	return 0;
462 }
463 
464 /**
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.
469  *
470  * Return:
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
477  *
478  * The result of this command is a fully validated command in @mbox_cmd that is
479  * safe to send to the hardware.
480  */
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)
484 {
485 	struct cxl_mem_command mem_cmd;
486 	int rc;
487 
488 	if (send_cmd->id == 0 || send_cmd->id >= CXL_MEM_COMMAND_ID_MAX)
489 		return -ENOTTY;
490 
491 	/*
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).
495 	 */
496 	if (send_cmd->in.size > mds->payload_size)
497 		return -EINVAL;
498 
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);
502 	else
503 		rc = cxl_to_mem_cmd(&mem_cmd, send_cmd, mds);
504 
505 	if (rc)
506 		return rc;
507 
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);
512 }
513 
514 int cxl_query_cmd(struct cxl_memdev *cxlmd,
515 		  struct cxl_mem_query_commands __user *q)
516 {
517 	struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlmd->cxlds);
518 	struct device *dev = &cxlmd->dev;
519 	struct cxl_mem_command *cmd;
520 	u32 n_commands;
521 	int j = 0;
522 
523 	dev_dbg(dev, "Query IOCTL\n");
524 
525 	if (get_user(n_commands, &q->n_commands))
526 		return -EFAULT;
527 
528 	/* returns the total number if 0 elements are requested. */
529 	if (n_commands == 0)
530 		return put_user(ARRAY_SIZE(cxl_mem_commands), &q->n_commands);
531 
532 	/*
533 	 * otherwise, return max(n_commands, total commands) cxl_command_info
534 	 * structures.
535 	 */
536 	cxl_for_each_cmd(cmd) {
537 		struct cxl_command_info info = cmd->info;
538 
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;
543 
544 		if (copy_to_user(&q->commands[j++], &info, sizeof(info)))
545 			return -EFAULT;
546 
547 		if (j == n_commands)
548 			break;
549 	}
550 
551 	return 0;
552 }
553 
554 /**
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.
562  *
563  * Return:
564  *  * %0	- Mailbox transaction succeeded. This implies the mailbox
565  *		  protocol completed successfully not that the operation itself
566  *		  was successful.
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.
571  *
572  * Dispatches a mailbox command on behalf of a userspace request.
573  * The output payload is copied to userspace.
574  *
575  * See cxl_send_cmd().
576  */
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,
580 					u32 *retval)
581 {
582 	struct device *dev = mds->cxlds.dev;
583 	int rc;
584 
585 	dev_dbg(dev,
586 		"Submitting %s command for user\n"
587 		"\topcode: %x\n"
588 		"\tsize: %zx\n",
589 		cxl_mem_opcode_to_name(mbox_cmd->opcode),
590 		mbox_cmd->opcode, mbox_cmd->size_in);
591 
592 	rc = mds->mbox_send(mds, mbox_cmd);
593 	if (rc)
594 		goto out;
595 
596 	/*
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.
600 	 */
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)) {
606 			rc = -EFAULT;
607 			goto out;
608 		}
609 	}
610 
611 	*size_out = mbox_cmd->size_out;
612 	*retval = mbox_cmd->return_code;
613 
614 out:
615 	cxl_mbox_cmd_dtor(mbox_cmd);
616 	return rc;
617 }
618 
619 int cxl_send_cmd(struct cxl_memdev *cxlmd, struct cxl_send_command __user *s)
620 {
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;
625 	int rc;
626 
627 	dev_dbg(dev, "Send IOCTL\n");
628 
629 	if (copy_from_user(&send, s, sizeof(send)))
630 		return -EFAULT;
631 
632 	rc = cxl_validate_cmd_from_user(&mbox_cmd, mds, &send);
633 	if (rc)
634 		return rc;
635 
636 	rc = handle_mailbox_cmd_from_user(mds, &mbox_cmd, send.out.payload,
637 					  &send.out.size, &send.retval);
638 	if (rc)
639 		return rc;
640 
641 	if (copy_to_user(s, &send, sizeof(send)))
642 		return -EFAULT;
643 
644 	return 0;
645 }
646 
647 static int cxl_xfer_log(struct cxl_memdev_state *mds, uuid_t *uuid,
648 			u32 *size, u8 *out)
649 {
650 	u32 remaining = *size;
651 	u32 offset = 0;
652 
653 	while (remaining) {
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;
657 		int rc;
658 
659 		log = (struct cxl_mbox_get_log) {
660 			.uuid = *uuid,
661 			.offset = cpu_to_le32(offset),
662 			.length = cpu_to_le32(xfer_size),
663 		};
664 
665 		mbox_cmd = (struct cxl_mbox_cmd) {
666 			.opcode = CXL_MBOX_OP_GET_LOG,
667 			.size_in = sizeof(log),
668 			.payload_in = &log,
669 			.size_out = xfer_size,
670 			.payload_out = out,
671 		};
672 
673 		rc = cxl_internal_send_cmd(mds, &mbox_cmd);
674 
675 		/*
676 		 * The output payload length that indicates the number
677 		 * of valid bytes can be smaller than the Log buffer
678 		 * size.
679 		 */
680 		if (rc == -EIO && mbox_cmd.size_out < xfer_size) {
681 			offset += mbox_cmd.size_out;
682 			break;
683 		}
684 
685 		if (rc < 0)
686 			return rc;
687 
688 		out += xfer_size;
689 		remaining -= xfer_size;
690 		offset += xfer_size;
691 	}
692 
693 	*size = offset;
694 
695 	return 0;
696 }
697 
698 /**
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.
702  * @cel: CEL
703  *
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.
706  */
707 static void cxl_walk_cel(struct cxl_memdev_state *mds, size_t size, u8 *cel)
708 {
709 	struct cxl_cel_entry *cel_entry;
710 	const int cel_entries = size / sizeof(*cel_entry);
711 	struct device *dev = mds->cxlds.dev;
712 	int i;
713 
714 	cel_entry = (struct cxl_cel_entry *) cel;
715 
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);
719 		int enabled = 0;
720 
721 		if (cmd) {
722 			set_bit(cmd->info.id, mds->enabled_cmds);
723 			enabled++;
724 		}
725 
726 		if (cxl_is_poison_command(opcode)) {
727 			cxl_set_poison_cmd_enabled(&mds->poison, opcode);
728 			enabled++;
729 		}
730 
731 		if (cxl_is_security_command(opcode)) {
732 			cxl_set_security_cmd_enabled(&mds->security, opcode);
733 			enabled++;
734 		}
735 
736 		dev_dbg(dev, "Opcode 0x%04x %s\n", opcode,
737 			enabled ? "enabled" : "unsupported by driver");
738 	}
739 }
740 
741 static struct cxl_mbox_get_supported_logs *cxl_get_gsl(struct cxl_memdev_state *mds)
742 {
743 	struct cxl_mbox_get_supported_logs *ret;
744 	struct cxl_mbox_cmd mbox_cmd;
745 	int rc;
746 
747 	ret = kvmalloc(mds->payload_size, GFP_KERNEL);
748 	if (!ret)
749 		return ERR_PTR(-ENOMEM);
750 
751 	mbox_cmd = (struct cxl_mbox_cmd) {
752 		.opcode = CXL_MBOX_OP_GET_SUPPORTED_LOGS,
753 		.size_out = mds->payload_size,
754 		.payload_out = ret,
755 		/* At least the record number field must be valid */
756 		.min_out = 2,
757 	};
758 	rc = cxl_internal_send_cmd(mds, &mbox_cmd);
759 	if (rc < 0) {
760 		kvfree(ret);
761 		return ERR_PTR(rc);
762 	}
763 
764 
765 	return ret;
766 }
767 
768 enum {
769 	CEL_UUID,
770 	VENDOR_DEBUG_UUID,
771 };
772 
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,
777 };
778 
779 /**
780  * cxl_enumerate_cmds() - Enumerate commands for a device.
781  * @mds: The driver data for the operation
782  *
783  * Returns 0 if enumerate completed successfully.
784  *
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.
788  */
789 int cxl_enumerate_cmds(struct cxl_memdev_state *mds)
790 {
791 	struct cxl_mbox_get_supported_logs *gsl;
792 	struct device *dev = mds->cxlds.dev;
793 	struct cxl_mem_command *cmd;
794 	int i, rc;
795 
796 	gsl = cxl_get_gsl(mds);
797 	if (IS_ERR(gsl))
798 		return PTR_ERR(gsl);
799 
800 	rc = -ENOENT;
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;
804 		u8 *log;
805 
806 		dev_dbg(dev, "Found LOG type %pU of size %d", &uuid, size);
807 
808 		if (!uuid_equal(&uuid, &log_uuid[CEL_UUID]))
809 			continue;
810 
811 		log = kvmalloc(size, GFP_KERNEL);
812 		if (!log) {
813 			rc = -ENOMEM;
814 			goto out;
815 		}
816 
817 		rc = cxl_xfer_log(mds, &uuid, &size, log);
818 		if (rc) {
819 			kvfree(log);
820 			goto out;
821 		}
822 
823 		cxl_walk_cel(mds, size, log);
824 		kvfree(log);
825 
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);
830 
831 		/* Found the required CEL */
832 		rc = 0;
833 	}
834 out:
835 	kvfree(gsl);
836 	return rc;
837 }
838 EXPORT_SYMBOL_NS_GPL(cxl_enumerate_cmds, CXL);
839 
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)
844 {
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);
851 	else
852 		trace_cxl_generic_event(cxlmd, type, uuid, &evt->generic);
853 }
854 EXPORT_SYMBOL_NS_GPL(cxl_event_trace_record, CXL);
855 
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)
859 {
860 	enum cxl_event_type ev_type = CXL_CPER_EVENT_GENERIC;
861 	const uuid_t *uuid = &record->id;
862 
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;
869 
870 	cxl_event_trace_record(cxlmd, type, ev_type, uuid, &record->event);
871 }
872 
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)
876 {
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;
882 	u16 cnt;
883 	int rc = 0;
884 	int i;
885 
886 	/* Payload size may limit the max handles */
887 	if (pl_size > mds->payload_size) {
888 		max_handles = (mds->payload_size - sizeof(*payload)) /
889 			      sizeof(__le16);
890 		pl_size = struct_size(payload, handles, max_handles);
891 	}
892 
893 	payload = kvzalloc(pl_size, GFP_KERNEL);
894 	if (!payload)
895 		return -ENOMEM;
896 
897 	*payload = (struct cxl_mbox_clear_event_payload) {
898 		.event_log = log,
899 	};
900 
901 	mbox_cmd = (struct cxl_mbox_cmd) {
902 		.opcode = CXL_MBOX_OP_CLEAR_EVENT_RECORD,
903 		.payload_in = payload,
904 		.size_in = pl_size,
905 	};
906 
907 	/*
908 	 * Clear Event Records uses u8 for the handle cnt while Get Event
909 	 * Record can return up to 0xffff records.
910 	 */
911 	i = 0;
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;
915 
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]));
919 
920 		if (i == max_handles) {
921 			payload->nr_recs = i;
922 			rc = cxl_internal_send_cmd(mds, &mbox_cmd);
923 			if (rc)
924 				goto free_pl;
925 			i = 0;
926 		}
927 	}
928 
929 	/* Clear what is left if any */
930 	if (i) {
931 		payload->nr_recs = i;
932 		mbox_cmd.size_in = struct_size(payload, handles, i);
933 		rc = cxl_internal_send_cmd(mds, &mbox_cmd);
934 		if (rc)
935 			goto free_pl;
936 	}
937 
938 free_pl:
939 	kvfree(payload);
940 	return rc;
941 }
942 
943 static void cxl_mem_get_records_log(struct cxl_memdev_state *mds,
944 				    enum cxl_event_log_type type)
945 {
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;
950 	u8 log_type = type;
951 	u16 nr_rec;
952 
953 	mutex_lock(&mds->event.log_lock);
954 	payload = mds->event.buf;
955 
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),
963 	};
964 
965 	do {
966 		int rc, i;
967 
968 		rc = cxl_internal_send_cmd(mds, &mbox_cmd);
969 		if (rc) {
970 			dev_err_ratelimited(dev,
971 				"Event log '%d': Failed to query event records : %d",
972 				type, rc);
973 			break;
974 		}
975 
976 		nr_rec = le16_to_cpu(payload->record_count);
977 		if (!nr_rec)
978 			break;
979 
980 		for (i = 0; i < nr_rec; i++)
981 			__cxl_event_trace_record(cxlmd, type,
982 						 &payload->records[i]);
983 
984 		if (payload->flags & CXL_GET_EVENT_FLAG_OVERFLOW)
985 			trace_cxl_overflow(cxlmd, type, payload);
986 
987 		rc = cxl_clear_event_record(mds, type, payload);
988 		if (rc) {
989 			dev_err_ratelimited(dev,
990 				"Event log '%d': Failed to clear events : %d",
991 				type, rc);
992 			break;
993 		}
994 	} while (nr_rec);
995 
996 	mutex_unlock(&mds->event.log_lock);
997 }
998 
999 /**
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.
1003  *
1004  * Retrieve all event records available on the device, report them as trace
1005  * events, and clear them.
1006  *
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
1009  */
1010 void cxl_mem_get_event_records(struct cxl_memdev_state *mds, u32 status)
1011 {
1012 	dev_dbg(mds->cxlds.dev, "Reading event logs: %x\n", status);
1013 
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);
1022 }
1023 EXPORT_SYMBOL_NS_GPL(cxl_mem_get_event_records, CXL);
1024 
1025 /**
1026  * cxl_mem_get_partition_info - Get partition info
1027  * @mds: The driver data for the operation
1028  *
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.
1032  *
1033  * Return: 0 if no error: or the result of the mailbox command.
1034  *
1035  * See CXL @8.2.9.5.2.1 Get Partition Info
1036  */
1037 static int cxl_mem_get_partition_info(struct cxl_memdev_state *mds)
1038 {
1039 	struct cxl_mbox_get_partition_info pi;
1040 	struct cxl_mbox_cmd mbox_cmd;
1041 	int rc;
1042 
1043 	mbox_cmd = (struct cxl_mbox_cmd) {
1044 		.opcode = CXL_MBOX_OP_GET_PARTITION_INFO,
1045 		.size_out = sizeof(pi),
1046 		.payload_out = &pi,
1047 	};
1048 	rc = cxl_internal_send_cmd(mds, &mbox_cmd);
1049 	if (rc)
1050 		return rc;
1051 
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;
1060 
1061 	return 0;
1062 }
1063 
1064 /**
1065  * cxl_dev_state_identify() - Send the IDENTIFY command to the device.
1066  * @mds: The driver data for the operation
1067  *
1068  * Return: 0 if identify was executed successfully or media not ready.
1069  *
1070  * This will dispatch the identify command to the device and on success populate
1071  * structures to be exported to sysfs.
1072  */
1073 int cxl_dev_state_identify(struct cxl_memdev_state *mds)
1074 {
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;
1078 	u32 val;
1079 	int rc;
1080 
1081 	if (!mds->cxlds.media_ready)
1082 		return 0;
1083 
1084 	mbox_cmd = (struct cxl_mbox_cmd) {
1085 		.opcode = CXL_MBOX_OP_IDENTIFY,
1086 		.size_out = sizeof(id),
1087 		.payload_out = &id,
1088 	};
1089 	rc = cxl_internal_send_cmd(mds, &mbox_cmd);
1090 	if (rc < 0)
1091 		return rc;
1092 
1093 	mds->total_bytes =
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;
1101 
1102 	mds->lsa_size = le32_to_cpu(id.lsa_size);
1103 	memcpy(mds->firmware_version, id.fw_revision,
1104 	       sizeof(id.fw_revision));
1105 
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);
1109 	}
1110 
1111 	return 0;
1112 }
1113 EXPORT_SYMBOL_NS_GPL(cxl_dev_state_identify, CXL);
1114 
1115 static int __cxl_mem_sanitize(struct cxl_memdev_state *mds, u16 cmd)
1116 {
1117 	int rc;
1118 	u32 sec_out = 0;
1119 	struct cxl_get_security_output {
1120 		__le32 flags;
1121 	} out;
1122 	struct cxl_mbox_cmd sec_cmd = {
1123 		.opcode = CXL_MBOX_OP_GET_SECURITY_STATE,
1124 		.payload_out = &out,
1125 		.size_out = sizeof(out),
1126 	};
1127 	struct cxl_mbox_cmd mbox_cmd = { .opcode = cmd };
1128 	struct cxl_dev_state *cxlds = &mds->cxlds;
1129 
1130 	if (cmd != CXL_MBOX_OP_SANITIZE && cmd != CXL_MBOX_OP_SECURE_ERASE)
1131 		return -EINVAL;
1132 
1133 	rc = cxl_internal_send_cmd(mds, &sec_cmd);
1134 	if (rc < 0) {
1135 		dev_err(cxlds->dev, "Failed to get security state : %d", rc);
1136 		return rc;
1137 	}
1138 
1139 	/*
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).
1143 	 */
1144 	sec_out = le32_to_cpu(out.flags);
1145 	if (sec_out & CXL_PMEM_SEC_STATE_USER_PASS_SET)
1146 		return -EINVAL;
1147 
1148 	if (cmd == CXL_MBOX_OP_SECURE_ERASE &&
1149 	    sec_out & CXL_PMEM_SEC_STATE_LOCKED)
1150 		return -EINVAL;
1151 
1152 	rc = cxl_internal_send_cmd(mds, &mbox_cmd);
1153 	if (rc < 0) {
1154 		dev_err(cxlds->dev, "Failed to sanitize device : %d", rc);
1155 		return rc;
1156 	}
1157 
1158 	return 0;
1159 }
1160 
1161 
1162 /**
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
1166  *
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.
1173  *
1174  * See CXL 3.0 @8.2.9.8.5.1 Sanitize and @8.2.9.8.5.2 Secure Erase.
1175  */
1176 int cxl_mem_sanitize(struct cxl_memdev *cxlmd, u16 cmd)
1177 {
1178 	struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlmd->cxlds);
1179 	struct cxl_port  *endpoint;
1180 	int rc;
1181 
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);
1186 	/*
1187 	 * Require an endpoint to be safe otherwise the driver can not
1188 	 * be sure that the device is unmapped.
1189 	 */
1190 	if (endpoint && cxl_num_decoders_committed(endpoint) == 0)
1191 		rc = __cxl_mem_sanitize(mds, cmd);
1192 	else
1193 		rc = -EBUSY;
1194 	up_read(&cxl_region_rwsem);
1195 	device_unlock(&cxlmd->dev);
1196 
1197 	return rc;
1198 }
1199 
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)
1203 {
1204 	int rc;
1205 
1206 	res->name = type;
1207 	res->start = start;
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);
1212 		return 0;
1213 	}
1214 	rc = request_resource(parent, res);
1215 	if (rc) {
1216 		dev_err(dev, "DPA(%s): failed to track %pr (%d)\n", res->name,
1217 			res, rc);
1218 		return rc;
1219 	}
1220 
1221 	dev_dbg(dev, "DPA(%s): %pr\n", res->name, res);
1222 
1223 	return 0;
1224 }
1225 
1226 int cxl_mem_create_range_info(struct cxl_memdev_state *mds)
1227 {
1228 	struct cxl_dev_state *cxlds = &mds->cxlds;
1229 	struct device *dev = cxlds->dev;
1230 	int rc;
1231 
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);
1236 		return 0;
1237 	}
1238 
1239 	cxlds->dpa_res = DEFINE_RES_MEM(0, mds->total_bytes);
1240 
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");
1244 		if (rc)
1245 			return rc;
1246 		return add_dpa_res(dev, &cxlds->dpa_res, &cxlds->pmem_res,
1247 				   mds->volatile_only_bytes,
1248 				   mds->persistent_only_bytes, "pmem");
1249 	}
1250 
1251 	rc = cxl_mem_get_partition_info(mds);
1252 	if (rc) {
1253 		dev_err(dev, "Failed to query partition information\n");
1254 		return rc;
1255 	}
1256 
1257 	rc = add_dpa_res(dev, &cxlds->dpa_res, &cxlds->ram_res, 0,
1258 			 mds->active_volatile_bytes, "ram");
1259 	if (rc)
1260 		return rc;
1261 	return add_dpa_res(dev, &cxlds->dpa_res, &cxlds->pmem_res,
1262 			   mds->active_volatile_bytes,
1263 			   mds->active_persistent_bytes, "pmem");
1264 }
1265 EXPORT_SYMBOL_NS_GPL(cxl_mem_create_range_info, CXL);
1266 
1267 int cxl_set_timestamp(struct cxl_memdev_state *mds)
1268 {
1269 	struct cxl_mbox_cmd mbox_cmd;
1270 	struct cxl_mbox_set_timestamp_in pi;
1271 	int rc;
1272 
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),
1277 		.payload_in = &pi,
1278 	};
1279 
1280 	rc = cxl_internal_send_cmd(mds, &mbox_cmd);
1281 	/*
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
1285 	 */
1286 	if (rc && (mbox_cmd.return_code != CXL_MBOX_CMD_RC_UNSUPPORTED))
1287 		return rc;
1288 
1289 	return 0;
1290 }
1291 EXPORT_SYMBOL_NS_GPL(cxl_set_timestamp, CXL);
1292 
1293 int cxl_mem_get_poison(struct cxl_memdev *cxlmd, u64 offset, u64 len,
1294 		       struct cxl_region *cxlr)
1295 {
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;
1300 	int nr_records = 0;
1301 	int rc;
1302 
1303 	rc = mutex_lock_interruptible(&mds->poison.lock);
1304 	if (rc)
1305 		return rc;
1306 
1307 	po = mds->poison.list_out;
1308 	pi.offset = cpu_to_le64(offset);
1309 	pi.length = cpu_to_le64(len / CXL_POISON_LEN_MULT);
1310 
1311 	mbox_cmd = (struct cxl_mbox_cmd) {
1312 		.opcode = CXL_MBOX_OP_GET_POISON,
1313 		.size_in = sizeof(pi),
1314 		.payload_in = &pi,
1315 		.size_out = mds->payload_size,
1316 		.payload_out = po,
1317 		.min_out = struct_size(po, record, 0),
1318 	};
1319 
1320 	do {
1321 		rc = cxl_internal_send_cmd(mds, &mbox_cmd);
1322 		if (rc)
1323 			break;
1324 
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);
1329 
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",
1334 				nr_records);
1335 			break;
1336 		}
1337 	} while (po->flags & CXL_POISON_FLAG_MORE);
1338 
1339 	mutex_unlock(&mds->poison.lock);
1340 	return rc;
1341 }
1342 EXPORT_SYMBOL_NS_GPL(cxl_mem_get_poison, CXL);
1343 
1344 static void free_poison_buf(void *buf)
1345 {
1346 	kvfree(buf);
1347 }
1348 
1349 /* Get Poison List output buffer is protected by mds->poison.lock */
1350 static int cxl_poison_alloc_buf(struct cxl_memdev_state *mds)
1351 {
1352 	mds->poison.list_out = kvmalloc(mds->payload_size, GFP_KERNEL);
1353 	if (!mds->poison.list_out)
1354 		return -ENOMEM;
1355 
1356 	return devm_add_action_or_reset(mds->cxlds.dev, free_poison_buf,
1357 					mds->poison.list_out);
1358 }
1359 
1360 int cxl_poison_state_init(struct cxl_memdev_state *mds)
1361 {
1362 	int rc;
1363 
1364 	if (!test_bit(CXL_POISON_ENABLED_LIST, mds->poison.enabled_cmds))
1365 		return 0;
1366 
1367 	rc = cxl_poison_alloc_buf(mds);
1368 	if (rc) {
1369 		clear_bit(CXL_POISON_ENABLED_LIST, mds->poison.enabled_cmds);
1370 		return rc;
1371 	}
1372 
1373 	mutex_init(&mds->poison.lock);
1374 	return 0;
1375 }
1376 EXPORT_SYMBOL_NS_GPL(cxl_poison_state_init, CXL);
1377 
1378 struct cxl_memdev_state *cxl_memdev_state_create(struct device *dev)
1379 {
1380 	struct cxl_memdev_state *mds;
1381 
1382 	mds = devm_kzalloc(dev, sizeof(*mds), GFP_KERNEL);
1383 	if (!mds) {
1384 		dev_err(dev, "No memory available\n");
1385 		return ERR_PTR(-ENOMEM);
1386 	}
1387 
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 	mds->ram_perf.qos_class = CXL_QOS_CLASS_INVALID;
1395 	mds->pmem_perf.qos_class = CXL_QOS_CLASS_INVALID;
1396 
1397 	return mds;
1398 }
1399 EXPORT_SYMBOL_NS_GPL(cxl_memdev_state_create, CXL);
1400 
1401 void __init cxl_mbox_init(void)
1402 {
1403 	struct dentry *mbox_debugfs;
1404 
1405 	mbox_debugfs = cxl_debugfs_create_dir("mbox");
1406 	debugfs_create_bool("raw_allow_all", 0600, mbox_debugfs,
1407 			    &cxl_raw_allow_all);
1408 }
1409