Skip to content

Commit 5666a7e

Browse files
committed
cxl: Refactor user ioctl command path from mds to mailbox
With 'struct cxl_mailbox' context introduced, the helper functions cxl_query_cmd() and cxl_send_cmd() can take a cxl_mailbox directly rather than a cxl_memdev parameter. Refactor to use cxl_mailbox directly. Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> Reviewed-by: Dan Williams <dan.j.williams@intel.com> Link: https://patch.msgid.link/20250204220430.4146187-2-dave.jiang@intel.com Signed-off-by: Dave Jiang <dave.jiang@intel.com>
1 parent 2014c95 commit 5666a7e

File tree

5 files changed

+101
-96
lines changed

5 files changed

+101
-96
lines changed

drivers/cxl/core/core.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
#ifndef __CXL_CORE_H__
55
#define __CXL_CORE_H__
66

7+
#include <cxl/mailbox.h>
8+
79
extern const struct device_type cxl_nvdimm_bridge_type;
810
extern const struct device_type cxl_nvdimm_type;
911
extern const struct device_type cxl_pmu_type;
@@ -65,9 +67,9 @@ static inline void cxl_region_exit(void)
6567

6668
struct cxl_send_command;
6769
struct cxl_mem_query_commands;
68-
int cxl_query_cmd(struct cxl_memdev *cxlmd,
70+
int cxl_query_cmd(struct cxl_mailbox *cxl_mbox,
6971
struct cxl_mem_query_commands __user *q);
70-
int cxl_send_cmd(struct cxl_memdev *cxlmd, struct cxl_send_command __user *s);
72+
int cxl_send_cmd(struct cxl_mailbox *cxl_mbox, struct cxl_send_command __user *s);
7173
void __iomem *devm_cxl_iomap_block(struct device *dev, resource_size_t addr,
7274
resource_size_t length);
7375

drivers/cxl/core/mbox.c

Lines changed: 42 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -349,40 +349,39 @@ static bool cxl_payload_from_user_allowed(u16 opcode, void *payload_in)
349349
return true;
350350
}
351351

352-
static int cxl_mbox_cmd_ctor(struct cxl_mbox_cmd *mbox,
353-
struct cxl_memdev_state *mds, u16 opcode,
352+
static int cxl_mbox_cmd_ctor(struct cxl_mbox_cmd *mbox_cmd,
353+
struct cxl_mailbox *cxl_mbox, u16 opcode,
354354
size_t in_size, size_t out_size, u64 in_payload)
355355
{
356-
struct cxl_mailbox *cxl_mbox = &mds->cxlds.cxl_mbox;
357-
*mbox = (struct cxl_mbox_cmd) {
356+
*mbox_cmd = (struct cxl_mbox_cmd) {
358357
.opcode = opcode,
359358
.size_in = in_size,
360359
};
361360

362361
if (in_size) {
363-
mbox->payload_in = vmemdup_user(u64_to_user_ptr(in_payload),
364-
in_size);
365-
if (IS_ERR(mbox->payload_in))
366-
return PTR_ERR(mbox->payload_in);
362+
mbox_cmd->payload_in = vmemdup_user(u64_to_user_ptr(in_payload),
363+
in_size);
364+
if (IS_ERR(mbox_cmd->payload_in))
365+
return PTR_ERR(mbox_cmd->payload_in);
367366

368-
if (!cxl_payload_from_user_allowed(opcode, mbox->payload_in)) {
369-
dev_dbg(mds->cxlds.dev, "%s: input payload not allowed\n",
367+
if (!cxl_payload_from_user_allowed(opcode, mbox_cmd->payload_in)) {
368+
dev_dbg(cxl_mbox->host, "%s: input payload not allowed\n",
370369
cxl_mem_opcode_to_name(opcode));
371-
kvfree(mbox->payload_in);
370+
kvfree(mbox_cmd->payload_in);
372371
return -EBUSY;
373372
}
374373
}
375374

376375
/* Prepare to handle a full payload for variable sized output */
377376
if (out_size == CXL_VARIABLE_PAYLOAD)
378-
mbox->size_out = cxl_mbox->payload_size;
377+
mbox_cmd->size_out = cxl_mbox->payload_size;
379378
else
380-
mbox->size_out = out_size;
379+
mbox_cmd->size_out = out_size;
381380

382-
if (mbox->size_out) {
383-
mbox->payload_out = kvzalloc(mbox->size_out, GFP_KERNEL);
384-
if (!mbox->payload_out) {
385-
kvfree(mbox->payload_in);
381+
if (mbox_cmd->size_out) {
382+
mbox_cmd->payload_out = kvzalloc(mbox_cmd->size_out, GFP_KERNEL);
383+
if (!mbox_cmd->payload_out) {
384+
kvfree(mbox_cmd->payload_in);
386385
return -ENOMEM;
387386
}
388387
}
@@ -397,10 +396,8 @@ static void cxl_mbox_cmd_dtor(struct cxl_mbox_cmd *mbox)
397396

398397
static int cxl_to_mem_cmd_raw(struct cxl_mem_command *mem_cmd,
399398
const struct cxl_send_command *send_cmd,
400-
struct cxl_memdev_state *mds)
399+
struct cxl_mailbox *cxl_mbox)
401400
{
402-
struct cxl_mailbox *cxl_mbox = &mds->cxlds.cxl_mbox;
403-
404401
if (send_cmd->raw.rsvd)
405402
return -EINVAL;
406403

@@ -415,7 +412,7 @@ static int cxl_to_mem_cmd_raw(struct cxl_mem_command *mem_cmd,
415412
if (!cxl_mem_raw_command_allowed(send_cmd->raw.opcode))
416413
return -EPERM;
417414

418-
dev_WARN_ONCE(mds->cxlds.dev, true, "raw command path used\n");
415+
dev_WARN_ONCE(cxl_mbox->host, true, "raw command path used\n");
419416

420417
*mem_cmd = (struct cxl_mem_command) {
421418
.info = {
@@ -431,7 +428,7 @@ static int cxl_to_mem_cmd_raw(struct cxl_mem_command *mem_cmd,
431428

432429
static int cxl_to_mem_cmd(struct cxl_mem_command *mem_cmd,
433430
const struct cxl_send_command *send_cmd,
434-
struct cxl_memdev_state *mds)
431+
struct cxl_mailbox *cxl_mbox)
435432
{
436433
struct cxl_mem_command *c = &cxl_mem_commands[send_cmd->id];
437434
const struct cxl_command_info *info = &c->info;
@@ -446,11 +443,11 @@ static int cxl_to_mem_cmd(struct cxl_mem_command *mem_cmd,
446443
return -EINVAL;
447444

448445
/* Check that the command is enabled for hardware */
449-
if (!test_bit(info->id, mds->enabled_cmds))
446+
if (!test_bit(info->id, cxl_mbox->enabled_cmds))
450447
return -ENOTTY;
451448

452449
/* Check that the command is not claimed for exclusive kernel use */
453-
if (test_bit(info->id, mds->exclusive_cmds))
450+
if (test_bit(info->id, cxl_mbox->exclusive_cmds))
454451
return -EBUSY;
455452

456453
/* Check the input buffer is the expected size */
@@ -479,7 +476,7 @@ static int cxl_to_mem_cmd(struct cxl_mem_command *mem_cmd,
479476
/**
480477
* cxl_validate_cmd_from_user() - Check fields for CXL_MEM_SEND_COMMAND.
481478
* @mbox_cmd: Sanitized and populated &struct cxl_mbox_cmd.
482-
* @mds: The driver data for the operation
479+
* @cxl_mbox: CXL mailbox context
483480
* @send_cmd: &struct cxl_send_command copied in from userspace.
484481
*
485482
* Return:
@@ -494,10 +491,9 @@ static int cxl_to_mem_cmd(struct cxl_mem_command *mem_cmd,
494491
* safe to send to the hardware.
495492
*/
496493
static int cxl_validate_cmd_from_user(struct cxl_mbox_cmd *mbox_cmd,
497-
struct cxl_memdev_state *mds,
494+
struct cxl_mailbox *cxl_mbox,
498495
const struct cxl_send_command *send_cmd)
499496
{
500-
struct cxl_mailbox *cxl_mbox = &mds->cxlds.cxl_mbox;
501497
struct cxl_mem_command mem_cmd;
502498
int rc;
503499

@@ -514,24 +510,23 @@ static int cxl_validate_cmd_from_user(struct cxl_mbox_cmd *mbox_cmd,
514510

515511
/* Sanitize and construct a cxl_mem_command */
516512
if (send_cmd->id == CXL_MEM_COMMAND_ID_RAW)
517-
rc = cxl_to_mem_cmd_raw(&mem_cmd, send_cmd, mds);
513+
rc = cxl_to_mem_cmd_raw(&mem_cmd, send_cmd, cxl_mbox);
518514
else
519-
rc = cxl_to_mem_cmd(&mem_cmd, send_cmd, mds);
515+
rc = cxl_to_mem_cmd(&mem_cmd, send_cmd, cxl_mbox);
520516

521517
if (rc)
522518
return rc;
523519

524520
/* Sanitize and construct a cxl_mbox_cmd */
525-
return cxl_mbox_cmd_ctor(mbox_cmd, mds, mem_cmd.opcode,
521+
return cxl_mbox_cmd_ctor(mbox_cmd, cxl_mbox, mem_cmd.opcode,
526522
mem_cmd.info.size_in, mem_cmd.info.size_out,
527523
send_cmd->in.payload);
528524
}
529525

530-
int cxl_query_cmd(struct cxl_memdev *cxlmd,
526+
int cxl_query_cmd(struct cxl_mailbox *cxl_mbox,
531527
struct cxl_mem_query_commands __user *q)
532528
{
533-
struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlmd->cxlds);
534-
struct device *dev = &cxlmd->dev;
529+
struct device *dev = cxl_mbox->host;
535530
struct cxl_mem_command *cmd;
536531
u32 n_commands;
537532
int j = 0;
@@ -552,9 +547,9 @@ int cxl_query_cmd(struct cxl_memdev *cxlmd,
552547
cxl_for_each_cmd(cmd) {
553548
struct cxl_command_info info = cmd->info;
554549

555-
if (test_bit(info.id, mds->enabled_cmds))
550+
if (test_bit(info.id, cxl_mbox->enabled_cmds))
556551
info.flags |= CXL_MEM_COMMAND_FLAG_ENABLED;
557-
if (test_bit(info.id, mds->exclusive_cmds))
552+
if (test_bit(info.id, cxl_mbox->exclusive_cmds))
558553
info.flags |= CXL_MEM_COMMAND_FLAG_EXCLUSIVE;
559554

560555
if (copy_to_user(&q->commands[j++], &info, sizeof(info)))
@@ -569,7 +564,7 @@ int cxl_query_cmd(struct cxl_memdev *cxlmd,
569564

570565
/**
571566
* handle_mailbox_cmd_from_user() - Dispatch a mailbox command for userspace.
572-
* @mds: The driver data for the operation
567+
* @cxl_mbox: The mailbox context for the operation.
573568
* @mbox_cmd: The validated mailbox command.
574569
* @out_payload: Pointer to userspace's output payload.
575570
* @size_out: (Input) Max payload size to copy out.
@@ -590,13 +585,12 @@ int cxl_query_cmd(struct cxl_memdev *cxlmd,
590585
*
591586
* See cxl_send_cmd().
592587
*/
593-
static int handle_mailbox_cmd_from_user(struct cxl_memdev_state *mds,
588+
static int handle_mailbox_cmd_from_user(struct cxl_mailbox *cxl_mbox,
594589
struct cxl_mbox_cmd *mbox_cmd,
595590
u64 out_payload, s32 *size_out,
596591
u32 *retval)
597592
{
598-
struct cxl_mailbox *cxl_mbox = &mds->cxlds.cxl_mbox;
599-
struct device *dev = mds->cxlds.dev;
593+
struct device *dev = cxl_mbox->host;
600594
int rc;
601595

602596
dev_dbg(dev,
@@ -633,10 +627,9 @@ static int handle_mailbox_cmd_from_user(struct cxl_memdev_state *mds,
633627
return rc;
634628
}
635629

636-
int cxl_send_cmd(struct cxl_memdev *cxlmd, struct cxl_send_command __user *s)
630+
int cxl_send_cmd(struct cxl_mailbox *cxl_mbox, struct cxl_send_command __user *s)
637631
{
638-
struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlmd->cxlds);
639-
struct device *dev = &cxlmd->dev;
632+
struct device *dev = cxl_mbox->host;
640633
struct cxl_send_command send;
641634
struct cxl_mbox_cmd mbox_cmd;
642635
int rc;
@@ -646,11 +639,11 @@ int cxl_send_cmd(struct cxl_memdev *cxlmd, struct cxl_send_command __user *s)
646639
if (copy_from_user(&send, s, sizeof(send)))
647640
return -EFAULT;
648641

649-
rc = cxl_validate_cmd_from_user(&mbox_cmd, mds, &send);
642+
rc = cxl_validate_cmd_from_user(&mbox_cmd, cxl_mbox, &send);
650643
if (rc)
651644
return rc;
652645

653-
rc = handle_mailbox_cmd_from_user(mds, &mbox_cmd, send.out.payload,
646+
rc = handle_mailbox_cmd_from_user(cxl_mbox, &mbox_cmd, send.out.payload,
654647
&send.out.size, &send.retval);
655648
if (rc)
656649
return rc;
@@ -724,6 +717,7 @@ static int cxl_xfer_log(struct cxl_memdev_state *mds, uuid_t *uuid,
724717
*/
725718
static void cxl_walk_cel(struct cxl_memdev_state *mds, size_t size, u8 *cel)
726719
{
720+
struct cxl_mailbox *cxl_mbox = &mds->cxlds.cxl_mbox;
727721
struct cxl_cel_entry *cel_entry;
728722
const int cel_entries = size / sizeof(*cel_entry);
729723
struct device *dev = mds->cxlds.dev;
@@ -737,7 +731,7 @@ static void cxl_walk_cel(struct cxl_memdev_state *mds, size_t size, u8 *cel)
737731
int enabled = 0;
738732

739733
if (cmd) {
740-
set_bit(cmd->info.id, mds->enabled_cmds);
734+
set_bit(cmd->info.id, cxl_mbox->enabled_cmds);
741735
enabled++;
742736
}
743737

@@ -807,6 +801,7 @@ static const uuid_t log_uuid[] = {
807801
*/
808802
int cxl_enumerate_cmds(struct cxl_memdev_state *mds)
809803
{
804+
struct cxl_mailbox *cxl_mbox = &mds->cxlds.cxl_mbox;
810805
struct cxl_mbox_get_supported_logs *gsl;
811806
struct device *dev = mds->cxlds.dev;
812807
struct cxl_mem_command *cmd;
@@ -845,7 +840,7 @@ int cxl_enumerate_cmds(struct cxl_memdev_state *mds)
845840
/* In case CEL was bogus, enable some default commands. */
846841
cxl_for_each_cmd(cmd)
847842
if (cmd->flags & CXL_CMD_FLAG_FORCE_ENABLE)
848-
set_bit(cmd->info.id, mds->enabled_cmds);
843+
set_bit(cmd->info.id, cxl_mbox->enabled_cmds);
849844

850845
/* Found the required CEL */
851846
rc = 0;
@@ -1448,6 +1443,7 @@ struct cxl_memdev_state *cxl_memdev_state_create(struct device *dev)
14481443
mutex_init(&mds->event.log_lock);
14491444
mds->cxlds.dev = dev;
14501445
mds->cxlds.reg_map.host = dev;
1446+
mds->cxlds.cxl_mbox.host = dev;
14511447
mds->cxlds.reg_map.resource = CXL_RESOURCE_NONE;
14521448
mds->cxlds.type = CXL_DEVTYPE_CLASSMEM;
14531449
mds->ram_perf.qos_class = CXL_QOS_CLASS_INVALID;

drivers/cxl/core/memdev.c

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -564,9 +564,11 @@ EXPORT_SYMBOL_NS_GPL(is_cxl_memdev, "CXL");
564564
void set_exclusive_cxl_commands(struct cxl_memdev_state *mds,
565565
unsigned long *cmds)
566566
{
567+
struct cxl_mailbox *cxl_mbox = &mds->cxlds.cxl_mbox;
568+
567569
down_write(&cxl_memdev_rwsem);
568-
bitmap_or(mds->exclusive_cmds, mds->exclusive_cmds, cmds,
569-
CXL_MEM_COMMAND_ID_MAX);
570+
bitmap_or(cxl_mbox->exclusive_cmds, cxl_mbox->exclusive_cmds,
571+
cmds, CXL_MEM_COMMAND_ID_MAX);
570572
up_write(&cxl_memdev_rwsem);
571573
}
572574
EXPORT_SYMBOL_NS_GPL(set_exclusive_cxl_commands, "CXL");
@@ -579,9 +581,11 @@ EXPORT_SYMBOL_NS_GPL(set_exclusive_cxl_commands, "CXL");
579581
void clear_exclusive_cxl_commands(struct cxl_memdev_state *mds,
580582
unsigned long *cmds)
581583
{
584+
struct cxl_mailbox *cxl_mbox = &mds->cxlds.cxl_mbox;
585+
582586
down_write(&cxl_memdev_rwsem);
583-
bitmap_andnot(mds->exclusive_cmds, mds->exclusive_cmds, cmds,
584-
CXL_MEM_COMMAND_ID_MAX);
587+
bitmap_andnot(cxl_mbox->exclusive_cmds, cxl_mbox->exclusive_cmds,
588+
cmds, CXL_MEM_COMMAND_ID_MAX);
585589
up_write(&cxl_memdev_rwsem);
586590
}
587591
EXPORT_SYMBOL_NS_GPL(clear_exclusive_cxl_commands, "CXL");
@@ -656,11 +660,14 @@ static struct cxl_memdev *cxl_memdev_alloc(struct cxl_dev_state *cxlds,
656660
static long __cxl_memdev_ioctl(struct cxl_memdev *cxlmd, unsigned int cmd,
657661
unsigned long arg)
658662
{
663+
struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlmd->cxlds);
664+
struct cxl_mailbox *cxl_mbox = &mds->cxlds.cxl_mbox;
665+
659666
switch (cmd) {
660667
case CXL_MEM_QUERY_COMMANDS:
661-
return cxl_query_cmd(cxlmd, (void __user *)arg);
668+
return cxl_query_cmd(cxl_mbox, (void __user *)arg);
662669
case CXL_MEM_SEND_COMMAND:
663-
return cxl_send_cmd(cxlmd, (void __user *)arg);
670+
return cxl_send_cmd(cxl_mbox, (void __user *)arg);
664671
default:
665672
return -ENOTTY;
666673
}
@@ -994,10 +1001,11 @@ static void cxl_remove_fw_upload(void *fwl)
9941001
int devm_cxl_setup_fw_upload(struct device *host, struct cxl_memdev_state *mds)
9951002
{
9961003
struct cxl_dev_state *cxlds = &mds->cxlds;
1004+
struct cxl_mailbox *cxl_mbox = &cxlds->cxl_mbox;
9971005
struct device *dev = &cxlds->cxlmd->dev;
9981006
struct fw_upload *fwl;
9991007

1000-
if (!test_bit(CXL_MEM_COMMAND_ID_GET_FW_INFO, mds->enabled_cmds))
1008+
if (!test_bit(CXL_MEM_COMMAND_ID_GET_FW_INFO, cxl_mbox->enabled_cmds))
10011009
return 0;
10021010

10031011
fwl = firmware_upload_register(THIS_MODULE, dev, dev_name(dev),

drivers/cxl/cxlmem.h

Lines changed: 0 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -106,42 +106,6 @@ static inline struct cxl_ep *cxl_ep_load(struct cxl_port *port,
106106
return xa_load(&port->endpoints, (unsigned long)&cxlmd->dev);
107107
}
108108

109-
/**
110-
* struct cxl_mbox_cmd - A command to be submitted to hardware.
111-
* @opcode: (input) The command set and command submitted to hardware.
112-
* @payload_in: (input) Pointer to the input payload.
113-
* @payload_out: (output) Pointer to the output payload. Must be allocated by
114-
* the caller.
115-
* @size_in: (input) Number of bytes to load from @payload_in.
116-
* @size_out: (input) Max number of bytes loaded into @payload_out.
117-
* (output) Number of bytes generated by the device. For fixed size
118-
* outputs commands this is always expected to be deterministic. For
119-
* variable sized output commands, it tells the exact number of bytes
120-
* written.
121-
* @min_out: (input) internal command output payload size validation
122-
* @poll_count: (input) Number of timeouts to attempt.
123-
* @poll_interval_ms: (input) Time between mailbox background command polling
124-
* interval timeouts.
125-
* @return_code: (output) Error code returned from hardware.
126-
*
127-
* This is the primary mechanism used to send commands to the hardware.
128-
* All the fields except @payload_* correspond exactly to the fields described in
129-
* Command Register section of the CXL 2.0 8.2.8.4.5. @payload_in and
130-
* @payload_out are written to, and read from the Command Payload Registers
131-
* defined in CXL 2.0 8.2.8.4.8.
132-
*/
133-
struct cxl_mbox_cmd {
134-
u16 opcode;
135-
void *payload_in;
136-
void *payload_out;
137-
size_t size_in;
138-
size_t size_out;
139-
size_t min_out;
140-
int poll_count;
141-
int poll_interval_ms;
142-
u16 return_code;
143-
};
144-
145109
/*
146110
* Per CXL 3.0 Section 8.2.8.4.5.1
147111
*/
@@ -461,8 +425,6 @@ static inline struct cxl_dev_state *mbox_to_cxlds(struct cxl_mailbox *cxl_mbox)
461425
* @lsa_size: Size of Label Storage Area
462426
* (CXL 2.0 8.2.9.5.1.1 Identify Memory Device)
463427
* @firmware_version: Firmware version for the memory device.
464-
* @enabled_cmds: Hardware commands found enabled in CEL.
465-
* @exclusive_cmds: Commands that are kernel-internal only
466428
* @total_bytes: sum of all possible capacities
467429
* @volatile_only_bytes: hard volatile capacity
468430
* @persistent_only_bytes: hard persistent capacity
@@ -485,8 +447,6 @@ struct cxl_memdev_state {
485447
struct cxl_dev_state cxlds;
486448
size_t lsa_size;
487449
char firmware_version[0x10];
488-
DECLARE_BITMAP(enabled_cmds, CXL_MEM_COMMAND_ID_MAX);
489-
DECLARE_BITMAP(exclusive_cmds, CXL_MEM_COMMAND_ID_MAX);
490450
u64 total_bytes;
491451
u64 volatile_only_bytes;
492452
u64 persistent_only_bytes;

0 commit comments

Comments
 (0)