Skip to content

Commit 64abb58

Browse files
committed
mi: Add ISH bit (admin command cflags)
Add ish bit for mi admin commands that access media spec NVM-Express-Management-Interface-Specification-Revision-2.1-2025.08.01-Ratified Figure 136: NVMe Admin Command Request Description Command Flags (CFLGS): Bit 2 : Ignore Shutdown (ISH) This bit shall have no effect on the value of the CSTS.SHST field (refer to the NVM Express Base Specification). (193 page from spec) If an NVMe Admin Command does not require access to media, then the ISH bit shall have no effect on the processing of that NVMe Admin Command. spec NVM-Express-Base-Specification-Revision-2.3-2025.08.01-Ratified Figure 84: Admin Commands Permitted to Return a Status Code of Admin Command Media Not Ready From Figure 84, we can assume that below Admin commands access media Capacity Management, Device Self-test, Firmware Commit, Firmware Image Download, Get LBA Status, Get Log Page, Namespace Attachment, Namespace Management, Format NVM, Sanitize, Sanitize Namespace, Security Receive, Security Send, Vendor Specific Signed-off-by: Steven Seungcheol Lee <sc108.lee@samsung.com> Reported-by: Hojin Ahn <hojin82.ahn.samsung.com>
1 parent d65b44c commit 64abb58

File tree

3 files changed

+98
-23
lines changed

3 files changed

+98
-23
lines changed

src/nvme/api-types.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ struct nvme_identify_args {
7474
* @ot: Offset Type; if set @lpo specifies the index into the list
7575
* of data structures, otherwise @lpo specifies the byte offset
7676
* into the log page.
77+
* @ish: Ignore Shutdown (for NVMe-MI command)
7778
*/
7879
struct nvme_get_log_args {
7980
__u64 lpo;
@@ -91,6 +92,7 @@ struct nvme_get_log_args {
9192
__u8 uuidx;
9293
bool rae;
9394
bool ot;
95+
bool ish;
9496
};
9597

9698
/**
@@ -171,6 +173,7 @@ struct nvme_get_features_args {
171173
* @lbaf: Logical block address format least significant 4 bits
172174
* @rsvd1: Reserved
173175
* @lbafu: Logical block address format most significant 2 bits
176+
* @ish: Ignore Shutdown (for NVMe-MI command)
174177
*/
175178
struct nvme_format_nvm_args {
176179
__u32 *result;
@@ -185,6 +188,7 @@ struct nvme_format_nvm_args {
185188
__u8 lbaf;
186189
__u8 rsvd1[7];
187190
__u8 lbafu;
191+
bool ish;
188192
};
189193

190194
/**
@@ -200,6 +204,7 @@ struct nvme_format_nvm_args {
200204
* @rsvd1: Reserved
201205
* @rsvd2: Reserved
202206
* @data: Host Software Specified Fields
207+
* @ish: Ignore Shutdown (for NVMe-MI command)
203208
*/
204209
struct nvme_ns_mgmt_args {
205210
__u32 *result;
@@ -213,6 +218,7 @@ struct nvme_ns_mgmt_args {
213218
__u8 rsvd1[3];
214219
void *rsvd2;
215220
struct nvme_ns_mgmt_host_sw_specified *data;
221+
bool ish;
216222
};
217223

218224
/**
@@ -224,6 +230,7 @@ struct nvme_ns_mgmt_args {
224230
* @timeout: Timeout in ms
225231
* @nsid: Namespace ID to execute attach selection
226232
* @sel: Attachment selection, see &enum nvme_ns_attach_sel
233+
* @ish: Ignore Shutdown (for NVMe-MI command)
227234
*/
228235
struct nvme_ns_attach_args {
229236
__u32 *result;
@@ -233,6 +240,7 @@ struct nvme_ns_attach_args {
233240
__u32 timeout;
234241
__u32 nsid;
235242
enum nvme_ns_attach_sel sel;
243+
bool ish;
236244
};
237245

238246
/**
@@ -244,6 +252,7 @@ struct nvme_ns_attach_args {
244252
* @offset: Offset in the firmware data
245253
* @data: Userspace address of the firmware data
246254
* @data_len: Length of data in this command in bytes
255+
* @ish: Ignore Shutdown (for NVMe-MI command)
247256
*/
248257
struct nvme_fw_download_args {
249258
__u32 *result;
@@ -253,6 +262,7 @@ struct nvme_fw_download_args {
253262
__u32 timeout;
254263
__u32 offset;
255264
__u32 data_len;
265+
bool ish;
256266
};
257267

258268
/**
@@ -264,6 +274,7 @@ struct nvme_fw_download_args {
264274
* @result: The command completion result from CQE dword0
265275
* @slot: Firmware slot to commit the downloaded image
266276
* @bpid: Set to true to select the boot partition id
277+
* @ish: Ignore Shutdown (for NVMe-MI command)
267278
*/
268279
struct nvme_fw_commit_args {
269280
__u32 *result;
@@ -273,6 +284,7 @@ struct nvme_fw_commit_args {
273284
enum nvme_fw_commit_ca action;
274285
__u8 slot;
275286
bool bpid;
287+
bool ish;
276288
};
277289

278290
/**
@@ -289,6 +301,7 @@ struct nvme_fw_commit_args {
289301
* @spsp0: Security Protocol Specific field
290302
* @spsp1: Security Protocol Specific field
291303
* @secp: Security Protocol
304+
* @ish: Ignore Shutdown (for NVMe-MI command)
292305
*/
293306
struct nvme_security_send_args {
294307
__u32 *result;
@@ -303,6 +316,7 @@ struct nvme_security_send_args {
303316
__u8 spsp0;
304317
__u8 spsp1;
305318
__u8 secp;
319+
bool ish;
306320
};
307321

308322
/**
@@ -319,6 +333,7 @@ struct nvme_security_send_args {
319333
* @spsp0: Security Protocol Specific field
320334
* @spsp1: Security Protocol Specific field
321335
* @secp: Security Protocol
336+
* @ish: Ignore Shutdown (for NVMe-MI command)
322337
*/
323338
struct nvme_security_receive_args {
324339
__u32 *result;
@@ -333,6 +348,7 @@ struct nvme_security_receive_args {
333348
__u8 spsp0;
334349
__u8 spsp1;
335350
__u8 secp;
351+
bool ish;
336352
};
337353

338354
/**
@@ -513,6 +529,7 @@ struct nvme_get_property_args {
513529
* @oipbp: Set to overwrite invert pattern between passes
514530
* @nodas: Set to not deallocate blocks after sanitizing
515531
* @emvs: Set to enter media verification state
532+
* @ish: Ignore Shutdown (for NVMe-MI command)
516533
*/
517534
struct nvme_sanitize_nvm_args {
518535
__u32 *result;
@@ -526,6 +543,7 @@ struct nvme_sanitize_nvm_args {
526543
bool oipbp;
527544
bool nodas;
528545
bool emvs;
546+
bool ish;
529547
};
530548

531549
/**

src/nvme/ioctl.c

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,8 @@ int nvme_identify(struct nvme_identify_args *args)
285285

286286
int nvme_get_log(struct nvme_get_log_args *args)
287287
{
288+
const size_t size_v1 = sizeof_args(struct nvme_get_log_args, ot, __u64);
289+
const size_t size_v2 = sizeof_args(struct nvme_get_log_args, ish, __u64);
288290
__u32 numd = (args->len >> 2) - 1;
289291
__u16 numdu = numd >> 16, numdl = numd & 0xffff;
290292

@@ -313,7 +315,7 @@ int nvme_get_log(struct nvme_get_log_args *args)
313315
.timeout_ms = args->timeout,
314316
};
315317

316-
if (args->args_size < sizeof(struct nvme_get_log_args)) {
318+
if (args->args_size < size_v1 || args->args_size > size_v2) {
317319
errno = EINVAL;
318320
return -1;
319321
}
@@ -373,6 +375,8 @@ static void nvme_uring_cmd_exit(struct io_uring *ring)
373375

374376
static int nvme_uring_cmd_admin_passthru_async(struct io_uring *ring, struct nvme_get_log_args *args)
375377
{
378+
const size_t size_v1 = sizeof_args(struct nvme_get_log_args, ot, __u64);
379+
const size_t size_v2 = sizeof_args(struct nvme_get_log_args, ish, __u64);
376380
struct io_uring_sqe *sqe;
377381
struct nvme_uring_cmd *cmd;
378382
int ret;
@@ -392,7 +396,7 @@ static int nvme_uring_cmd_admin_passthru_async(struct io_uring *ring, struct nvm
392396
NVME_SET(!!args->ot, LOG_CDW14_OT) |
393397
NVME_SET(args->csi, LOG_CDW14_CSI);
394398

395-
if (args->args_size < sizeof(struct nvme_get_log_args)) {
399+
if (args->args_size < size_v1 || args->args_size > size_v2) {
396400
errno = EINVAL;
397401
return -1;
398402
}
@@ -1501,9 +1505,10 @@ int nvme_format_nvm(struct nvme_format_nvm_args *args)
15011505
{
15021506
const size_t size_v1 = sizeof_args(struct nvme_format_nvm_args, lbaf, __u64);
15031507
const size_t size_v2 = sizeof_args(struct nvme_format_nvm_args, lbafu, __u64);
1508+
const size_t size_v3 = sizeof_args(struct nvme_format_nvm_args, ish, __u64);
15041509
__u32 cdw10;
15051510

1506-
if (args->args_size < size_v1 || args->args_size > size_v2) {
1511+
if (args->args_size < size_v1 || args->args_size > size_v3) {
15071512
errno = EINVAL;
15081513
return -1;
15091514
}
@@ -1533,10 +1538,11 @@ int nvme_ns_mgmt(struct nvme_ns_mgmt_args *args)
15331538
{
15341539
const size_t size_v1 = sizeof_args(struct nvme_ns_mgmt_args, csi, __u64);
15351540
const size_t size_v2 = sizeof_args(struct nvme_ns_mgmt_args, data, __u64);
1541+
const size_t size_v3 = sizeof_args(struct nvme_ns_mgmt_args, ish, __u64);
15361542
__u32 cdw10 = NVME_SET(args->sel, NAMESPACE_MGMT_CDW10_SEL);
15371543
__u32 cdw11 = NVME_SET(args->csi, NAMESPACE_MGMT_CDW11_CSI);
15381544

1539-
if (args->args_size < size_v1 || args->args_size > size_v2) {
1545+
if (args->args_size < size_v1 || args->args_size > size_v3) {
15401546
errno = EINVAL;
15411547
return -1;
15421548
}
@@ -1566,6 +1572,8 @@ int nvme_ns_mgmt(struct nvme_ns_mgmt_args *args)
15661572

15671573
int nvme_ns_attach(struct nvme_ns_attach_args *args)
15681574
{
1575+
const size_t size_v1 = sizeof_args(struct nvme_ns_attach_args, sel, __u64);
1576+
const size_t size_v2 = sizeof_args(struct nvme_ns_attach_args, ish, __u64);
15691577
__u32 cdw10 = NVME_SET(args->sel, NAMESPACE_ATTACH_CDW10_SEL);
15701578

15711579
struct nvme_passthru_cmd cmd = {
@@ -1577,7 +1585,7 @@ int nvme_ns_attach(struct nvme_ns_attach_args *args)
15771585
.timeout_ms = args->timeout,
15781586
};
15791587

1580-
if (args->args_size < sizeof(*args)) {
1588+
if (args->args_size < size_v1 || args->args_size > size_v2) {
15811589
errno = EINVAL;
15821590
return -1;
15831591
}
@@ -1586,6 +1594,8 @@ int nvme_ns_attach(struct nvme_ns_attach_args *args)
15861594

15871595
int nvme_fw_download(struct nvme_fw_download_args *args)
15881596
{
1597+
const size_t size_v1 = sizeof_args(struct nvme_fw_download_args, data_len, __u64);
1598+
const size_t size_v2 = sizeof_args(struct nvme_fw_download_args, ish, __u64);
15891599
__u32 cdw10 = (args->data_len >> 2) - 1;
15901600
__u32 cdw11 = args->offset >> 2;
15911601

@@ -1598,7 +1608,7 @@ int nvme_fw_download(struct nvme_fw_download_args *args)
15981608
.timeout_ms = args->timeout,
15991609
};
16001610

1601-
if (args->args_size < sizeof(*args)) {
1611+
if (args->args_size < size_v1 || args->args_size > size_v2) {
16021612
errno = EINVAL;
16031613
return -1;
16041614
}
@@ -1607,6 +1617,8 @@ int nvme_fw_download(struct nvme_fw_download_args *args)
16071617

16081618
int nvme_fw_commit(struct nvme_fw_commit_args *args)
16091619
{
1620+
const size_t size_v1 = sizeof_args(struct nvme_fw_commit_args, bpid, __u64);
1621+
const size_t size_v2 = sizeof_args(struct nvme_fw_commit_args, ish, __u64);
16101622
__u32 cdw10 = NVME_SET(args->slot, FW_COMMIT_CDW10_FS) |
16111623
NVME_SET(args->action, FW_COMMIT_CDW10_CA) |
16121624
NVME_SET(args->bpid, FW_COMMIT_CDW10_BPID);
@@ -1617,7 +1629,7 @@ int nvme_fw_commit(struct nvme_fw_commit_args *args)
16171629
.timeout_ms = args->timeout,
16181630
};
16191631

1620-
if (args->args_size < sizeof(*args)) {
1632+
if (args->args_size < size_v1 || args->args_size > size_v2) {
16211633
errno = EINVAL;
16221634
return -1;
16231635
}
@@ -1626,6 +1638,8 @@ int nvme_fw_commit(struct nvme_fw_commit_args *args)
16261638

16271639
int nvme_security_send(struct nvme_security_send_args *args)
16281640
{
1641+
const size_t size_v1 = sizeof_args(struct nvme_security_send_args, secp, __u64);
1642+
const size_t size_v2 = sizeof_args(struct nvme_security_send_args, ish, __u64);
16291643
__u32 cdw10 = NVME_SET(args->secp, SECURITY_SECP) |
16301644
NVME_SET(args->spsp0, SECURITY_SPSP0) |
16311645
NVME_SET(args->spsp1, SECURITY_SPSP1) |
@@ -1642,7 +1656,7 @@ int nvme_security_send(struct nvme_security_send_args *args)
16421656
.timeout_ms = args->timeout,
16431657
};
16441658

1645-
if (args->args_size < sizeof(*args)) {
1659+
if (args->args_size < size_v1 || args->args_size > size_v2) {
16461660
errno = EINVAL;
16471661
return -1;
16481662
}
@@ -1651,6 +1665,8 @@ int nvme_security_send(struct nvme_security_send_args *args)
16511665

16521666
int nvme_security_receive(struct nvme_security_receive_args *args)
16531667
{
1668+
const size_t size_v1 = sizeof_args(struct nvme_security_receive_args, secp, __u64);
1669+
const size_t size_v2 = sizeof_args(struct nvme_security_receive_args, ish, __u64);
16541670
__u32 cdw10 = NVME_SET(args->secp, SECURITY_SECP) |
16551671
NVME_SET(args->spsp0, SECURITY_SPSP0) |
16561672
NVME_SET(args->spsp1, SECURITY_SPSP1) |
@@ -1667,7 +1683,7 @@ int nvme_security_receive(struct nvme_security_receive_args *args)
16671683
.timeout_ms = args->timeout,
16681684
};
16691685

1670-
if (args->args_size < sizeof(*args)) {
1686+
if (args->args_size < size_v1 || args->args_size > size_v2) {
16711687
errno = EINVAL;
16721688
return -1;
16731689
}
@@ -1858,9 +1874,10 @@ int nvme_sanitize_nvm(struct nvme_sanitize_nvm_args *args)
18581874
{
18591875
const size_t size_v1 = sizeof_args(struct nvme_sanitize_nvm_args, nodas, __u64);
18601876
const size_t size_v2 = sizeof_args(struct nvme_sanitize_nvm_args, emvs, __u64);
1877+
const size_t size_v3 = sizeof_args(struct nvme_sanitize_nvm_args, ish, __u64);
18611878
__u32 cdw10, cdw11;
18621879

1863-
if (args->args_size < size_v1 || args->args_size > size_v2) {
1880+
if (args->args_size < size_v1 || args->args_size > size_v3) {
18641881
errno = EINVAL;
18651882
return -1;
18661883
}

0 commit comments

Comments
 (0)