]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
nvme: fix miss command type check
authormin15.li <min15.li@samsung.com>
Fri, 26 May 2023 17:06:56 +0000 (17:06 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 10 Apr 2024 14:19:43 +0000 (16:19 +0200)
commit 31a5978243d24d77be4bacca56c78a0fbc43b00d upstream.

In the function nvme_passthru_end(), only the value of the command
opcode is checked, without checking the command type (IO command or
Admin command). When we send a Dataset Management command (The opcode
of the Dataset Management command is the same as the Set Feature
command), kernel thinks it is a set feature command, then sets the
controller's keep alive interval, and calls nvme_keep_alive_work().

Signed-off-by: min15.li <min15.li@samsung.com>
Reviewed-by: Kanchan Joshi <joshi.k@samsung.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Keith Busch <kbusch@kernel.org>
Fixes: b58da2d270db ("nvme: update keep alive interval when kato is modified")
Signed-off-by: Tokunori Ikegami <ikegami.t@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/nvme/host/core.c

index 8f06e5c1706ba2e7439cd03f513b35b718fcfcc8..960a31e3307a2abf3809c37374b23cc012d30031 100644 (file)
@@ -1185,7 +1185,7 @@ static u32 nvme_passthru_start(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
        return effects;
 }
 
-static void nvme_passthru_end(struct nvme_ctrl *ctrl, u32 effects,
+static void nvme_passthru_end(struct nvme_ctrl *ctrl, struct nvme_ns *ns, u32 effects,
                              struct nvme_command *cmd, int status)
 {
        if (effects & NVME_CMD_EFFECTS_CSE_MASK) {
@@ -1201,6 +1201,8 @@ static void nvme_passthru_end(struct nvme_ctrl *ctrl, u32 effects,
                nvme_queue_scan(ctrl);
                flush_work(&ctrl->scan_work);
        }
+       if (ns)
+               return;
 
        switch (cmd->common.opcode) {
        case nvme_admin_set_features:
@@ -1235,7 +1237,7 @@ int nvme_execute_passthru_rq(struct request *rq)
        effects = nvme_passthru_start(ctrl, ns, cmd->common.opcode);
        ret = nvme_execute_rq(disk, rq, false);
        if (effects) /* nothing to be done for zero cmd effects */
-               nvme_passthru_end(ctrl, effects, cmd, ret);
+               nvme_passthru_end(ctrl, ns, effects, cmd, ret);
 
        return ret;
 }