Commit 22b9a896 authored by Jens Axboe's avatar Jens Axboe

Merge tag 'nvme-6.7-2023-12-7' of git://git.infradead.org/nvme into block-6.7

Pull NVMe fixes from Keith:

"nvme fixes for Linux 6.7

 - Proper nvme ctrl state setting (Keith)
 - Passthrough command optimization (Keith)
 - Spectre fix (Nitesh)
 - Kconfig clarifications (Shin'ichiro)
 - Frozen state deadlock fix (Bitao)
 - Power setting quirk (Georg)"

* tag 'nvme-6.7-2023-12-7' of git://git.infradead.org/nvme:
  nvme-pci: Add sleep quirk for Kingston drives
  nvme: fix deadlock between reset and scan
  nvme: prevent potential spectre v1 gadget
  nvme: improve NVME_HOST_AUTH and NVME_TARGET_AUTH config descriptions
  nvme-ioctl: move capable() admin check to the end
  nvme: ensure reset state check ordering
  nvme: introduce helper function to get ctrl state
parents 7d2affce 107b4e06
...@@ -107,11 +107,12 @@ config NVME_TCP_TLS ...@@ -107,11 +107,12 @@ config NVME_TCP_TLS
If unsure, say N. If unsure, say N.
config NVME_HOST_AUTH config NVME_HOST_AUTH
bool "NVM Express over Fabrics In-Band Authentication" bool "NVMe over Fabrics In-Band Authentication in host side"
depends on NVME_CORE depends on NVME_CORE
select NVME_AUTH select NVME_AUTH
help help
This provides support for NVMe over Fabrics In-Band Authentication. This provides support for NVMe over Fabrics In-Band Authentication in
host side.
If unsure, say N. If unsure, say N.
......
...@@ -131,7 +131,7 @@ void nvme_queue_scan(struct nvme_ctrl *ctrl) ...@@ -131,7 +131,7 @@ void nvme_queue_scan(struct nvme_ctrl *ctrl)
/* /*
* Only new queue scan work when admin and IO queues are both alive * Only new queue scan work when admin and IO queues are both alive
*/ */
if (ctrl->state == NVME_CTRL_LIVE && ctrl->tagset) if (nvme_ctrl_state(ctrl) == NVME_CTRL_LIVE && ctrl->tagset)
queue_work(nvme_wq, &ctrl->scan_work); queue_work(nvme_wq, &ctrl->scan_work);
} }
...@@ -143,7 +143,7 @@ void nvme_queue_scan(struct nvme_ctrl *ctrl) ...@@ -143,7 +143,7 @@ void nvme_queue_scan(struct nvme_ctrl *ctrl)
*/ */
int nvme_try_sched_reset(struct nvme_ctrl *ctrl) int nvme_try_sched_reset(struct nvme_ctrl *ctrl)
{ {
if (ctrl->state != NVME_CTRL_RESETTING) if (nvme_ctrl_state(ctrl) != NVME_CTRL_RESETTING)
return -EBUSY; return -EBUSY;
if (!queue_work(nvme_reset_wq, &ctrl->reset_work)) if (!queue_work(nvme_reset_wq, &ctrl->reset_work))
return -EBUSY; return -EBUSY;
...@@ -156,7 +156,7 @@ static void nvme_failfast_work(struct work_struct *work) ...@@ -156,7 +156,7 @@ static void nvme_failfast_work(struct work_struct *work)
struct nvme_ctrl *ctrl = container_of(to_delayed_work(work), struct nvme_ctrl *ctrl = container_of(to_delayed_work(work),
struct nvme_ctrl, failfast_work); struct nvme_ctrl, failfast_work);
if (ctrl->state != NVME_CTRL_CONNECTING) if (nvme_ctrl_state(ctrl) != NVME_CTRL_CONNECTING)
return; return;
set_bit(NVME_CTRL_FAILFAST_EXPIRED, &ctrl->flags); set_bit(NVME_CTRL_FAILFAST_EXPIRED, &ctrl->flags);
...@@ -200,7 +200,7 @@ int nvme_reset_ctrl_sync(struct nvme_ctrl *ctrl) ...@@ -200,7 +200,7 @@ int nvme_reset_ctrl_sync(struct nvme_ctrl *ctrl)
ret = nvme_reset_ctrl(ctrl); ret = nvme_reset_ctrl(ctrl);
if (!ret) { if (!ret) {
flush_work(&ctrl->reset_work); flush_work(&ctrl->reset_work);
if (ctrl->state != NVME_CTRL_LIVE) if (nvme_ctrl_state(ctrl) != NVME_CTRL_LIVE)
ret = -ENETRESET; ret = -ENETRESET;
} }
...@@ -499,7 +499,7 @@ bool nvme_change_ctrl_state(struct nvme_ctrl *ctrl, ...@@ -499,7 +499,7 @@ bool nvme_change_ctrl_state(struct nvme_ctrl *ctrl,
spin_lock_irqsave(&ctrl->lock, flags); spin_lock_irqsave(&ctrl->lock, flags);
old_state = ctrl->state; old_state = nvme_ctrl_state(ctrl);
switch (new_state) { switch (new_state) {
case NVME_CTRL_LIVE: case NVME_CTRL_LIVE:
switch (old_state) { switch (old_state) {
...@@ -567,7 +567,7 @@ bool nvme_change_ctrl_state(struct nvme_ctrl *ctrl, ...@@ -567,7 +567,7 @@ bool nvme_change_ctrl_state(struct nvme_ctrl *ctrl,
} }
if (changed) { if (changed) {
ctrl->state = new_state; WRITE_ONCE(ctrl->state, new_state);
wake_up_all(&ctrl->state_wq); wake_up_all(&ctrl->state_wq);
} }
...@@ -575,11 +575,11 @@ bool nvme_change_ctrl_state(struct nvme_ctrl *ctrl, ...@@ -575,11 +575,11 @@ bool nvme_change_ctrl_state(struct nvme_ctrl *ctrl,
if (!changed) if (!changed)
return false; return false;
if (ctrl->state == NVME_CTRL_LIVE) { if (new_state == NVME_CTRL_LIVE) {
if (old_state == NVME_CTRL_CONNECTING) if (old_state == NVME_CTRL_CONNECTING)
nvme_stop_failfast_work(ctrl); nvme_stop_failfast_work(ctrl);
nvme_kick_requeue_lists(ctrl); nvme_kick_requeue_lists(ctrl);
} else if (ctrl->state == NVME_CTRL_CONNECTING && } else if (new_state == NVME_CTRL_CONNECTING &&
old_state == NVME_CTRL_RESETTING) { old_state == NVME_CTRL_RESETTING) {
nvme_start_failfast_work(ctrl); nvme_start_failfast_work(ctrl);
} }
...@@ -592,7 +592,7 @@ EXPORT_SYMBOL_GPL(nvme_change_ctrl_state); ...@@ -592,7 +592,7 @@ EXPORT_SYMBOL_GPL(nvme_change_ctrl_state);
*/ */
static bool nvme_state_terminal(struct nvme_ctrl *ctrl) static bool nvme_state_terminal(struct nvme_ctrl *ctrl)
{ {
switch (ctrl->state) { switch (nvme_ctrl_state(ctrl)) {
case NVME_CTRL_NEW: case NVME_CTRL_NEW:
case NVME_CTRL_LIVE: case NVME_CTRL_LIVE:
case NVME_CTRL_RESETTING: case NVME_CTRL_RESETTING:
...@@ -617,7 +617,7 @@ bool nvme_wait_reset(struct nvme_ctrl *ctrl) ...@@ -617,7 +617,7 @@ bool nvme_wait_reset(struct nvme_ctrl *ctrl)
wait_event(ctrl->state_wq, wait_event(ctrl->state_wq,
nvme_change_ctrl_state(ctrl, NVME_CTRL_RESETTING) || nvme_change_ctrl_state(ctrl, NVME_CTRL_RESETTING) ||
nvme_state_terminal(ctrl)); nvme_state_terminal(ctrl));
return ctrl->state == NVME_CTRL_RESETTING; return nvme_ctrl_state(ctrl) == NVME_CTRL_RESETTING;
} }
EXPORT_SYMBOL_GPL(nvme_wait_reset); EXPORT_SYMBOL_GPL(nvme_wait_reset);
...@@ -704,9 +704,11 @@ EXPORT_SYMBOL_GPL(nvme_init_request); ...@@ -704,9 +704,11 @@ EXPORT_SYMBOL_GPL(nvme_init_request);
blk_status_t nvme_fail_nonready_command(struct nvme_ctrl *ctrl, blk_status_t nvme_fail_nonready_command(struct nvme_ctrl *ctrl,
struct request *rq) struct request *rq)
{ {
if (ctrl->state != NVME_CTRL_DELETING_NOIO && enum nvme_ctrl_state state = nvme_ctrl_state(ctrl);
ctrl->state != NVME_CTRL_DELETING &&
ctrl->state != NVME_CTRL_DEAD && if (state != NVME_CTRL_DELETING_NOIO &&
state != NVME_CTRL_DELETING &&
state != NVME_CTRL_DEAD &&
!test_bit(NVME_CTRL_FAILFAST_EXPIRED, &ctrl->flags) && !test_bit(NVME_CTRL_FAILFAST_EXPIRED, &ctrl->flags) &&
!blk_noretry_request(rq) && !(rq->cmd_flags & REQ_NVME_MPATH)) !blk_noretry_request(rq) && !(rq->cmd_flags & REQ_NVME_MPATH))
return BLK_STS_RESOURCE; return BLK_STS_RESOURCE;
...@@ -736,7 +738,7 @@ bool __nvme_check_ready(struct nvme_ctrl *ctrl, struct request *rq, ...@@ -736,7 +738,7 @@ bool __nvme_check_ready(struct nvme_ctrl *ctrl, struct request *rq,
* command, which is require to set the queue live in the * command, which is require to set the queue live in the
* appropinquate states. * appropinquate states.
*/ */
switch (ctrl->state) { switch (nvme_ctrl_state(ctrl)) {
case NVME_CTRL_CONNECTING: case NVME_CTRL_CONNECTING:
if (blk_rq_is_passthrough(rq) && nvme_is_fabrics(req->cmd) && if (blk_rq_is_passthrough(rq) && nvme_is_fabrics(req->cmd) &&
(req->cmd->fabrics.fctype == nvme_fabrics_type_connect || (req->cmd->fabrics.fctype == nvme_fabrics_type_connect ||
...@@ -2550,7 +2552,7 @@ static void nvme_set_latency_tolerance(struct device *dev, s32 val) ...@@ -2550,7 +2552,7 @@ static void nvme_set_latency_tolerance(struct device *dev, s32 val)
if (ctrl->ps_max_latency_us != latency) { if (ctrl->ps_max_latency_us != latency) {
ctrl->ps_max_latency_us = latency; ctrl->ps_max_latency_us = latency;
if (ctrl->state == NVME_CTRL_LIVE) if (nvme_ctrl_state(ctrl) == NVME_CTRL_LIVE)
nvme_configure_apst(ctrl); nvme_configure_apst(ctrl);
} }
} }
...@@ -3238,7 +3240,7 @@ static int nvme_dev_open(struct inode *inode, struct file *file) ...@@ -3238,7 +3240,7 @@ static int nvme_dev_open(struct inode *inode, struct file *file)
struct nvme_ctrl *ctrl = struct nvme_ctrl *ctrl =
container_of(inode->i_cdev, struct nvme_ctrl, cdev); container_of(inode->i_cdev, struct nvme_ctrl, cdev);
switch (ctrl->state) { switch (nvme_ctrl_state(ctrl)) {
case NVME_CTRL_LIVE: case NVME_CTRL_LIVE:
break; break;
default: default:
...@@ -3660,6 +3662,14 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, struct nvme_ns_info *info) ...@@ -3660,6 +3662,14 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, struct nvme_ns_info *info)
goto out_unlink_ns; goto out_unlink_ns;
down_write(&ctrl->namespaces_rwsem); down_write(&ctrl->namespaces_rwsem);
/*
* Ensure that no namespaces are added to the ctrl list after the queues
* are frozen, thereby avoiding a deadlock between scan and reset.
*/
if (test_bit(NVME_CTRL_FROZEN, &ctrl->flags)) {
up_write(&ctrl->namespaces_rwsem);
goto out_unlink_ns;
}
nvme_ns_add_to_ctrl_list(ns); nvme_ns_add_to_ctrl_list(ns);
up_write(&ctrl->namespaces_rwsem); up_write(&ctrl->namespaces_rwsem);
nvme_get_ctrl(ctrl); nvme_get_ctrl(ctrl);
...@@ -3924,7 +3934,7 @@ static void nvme_scan_work(struct work_struct *work) ...@@ -3924,7 +3934,7 @@ static void nvme_scan_work(struct work_struct *work)
int ret; int ret;
/* No tagset on a live ctrl means IO queues could not created */ /* No tagset on a live ctrl means IO queues could not created */
if (ctrl->state != NVME_CTRL_LIVE || !ctrl->tagset) if (nvme_ctrl_state(ctrl) != NVME_CTRL_LIVE || !ctrl->tagset)
return; return;
/* /*
...@@ -3994,7 +4004,7 @@ void nvme_remove_namespaces(struct nvme_ctrl *ctrl) ...@@ -3994,7 +4004,7 @@ void nvme_remove_namespaces(struct nvme_ctrl *ctrl)
* removing the namespaces' disks; fail all the queues now to avoid * removing the namespaces' disks; fail all the queues now to avoid
* potentially having to clean up the failed sync later. * potentially having to clean up the failed sync later.
*/ */
if (ctrl->state == NVME_CTRL_DEAD) if (nvme_ctrl_state(ctrl) == NVME_CTRL_DEAD)
nvme_mark_namespaces_dead(ctrl); nvme_mark_namespaces_dead(ctrl);
/* this is a no-op when called from the controller reset handler */ /* this is a no-op when called from the controller reset handler */
...@@ -4076,7 +4086,7 @@ static void nvme_async_event_work(struct work_struct *work) ...@@ -4076,7 +4086,7 @@ static void nvme_async_event_work(struct work_struct *work)
* flushing ctrl async_event_work after changing the controller state * flushing ctrl async_event_work after changing the controller state
* from LIVE and before freeing the admin queue. * from LIVE and before freeing the admin queue.
*/ */
if (ctrl->state == NVME_CTRL_LIVE) if (nvme_ctrl_state(ctrl) == NVME_CTRL_LIVE)
ctrl->ops->submit_async_event(ctrl); ctrl->ops->submit_async_event(ctrl);
} }
...@@ -4471,7 +4481,7 @@ int nvme_init_ctrl(struct nvme_ctrl *ctrl, struct device *dev, ...@@ -4471,7 +4481,7 @@ int nvme_init_ctrl(struct nvme_ctrl *ctrl, struct device *dev,
{ {
int ret; int ret;
ctrl->state = NVME_CTRL_NEW; WRITE_ONCE(ctrl->state, NVME_CTRL_NEW);
clear_bit(NVME_CTRL_FAILFAST_EXPIRED, &ctrl->flags); clear_bit(NVME_CTRL_FAILFAST_EXPIRED, &ctrl->flags);
spin_lock_init(&ctrl->lock); spin_lock_init(&ctrl->lock);
mutex_init(&ctrl->scan_lock); mutex_init(&ctrl->scan_lock);
...@@ -4581,6 +4591,7 @@ void nvme_unfreeze(struct nvme_ctrl *ctrl) ...@@ -4581,6 +4591,7 @@ void nvme_unfreeze(struct nvme_ctrl *ctrl)
list_for_each_entry(ns, &ctrl->namespaces, list) list_for_each_entry(ns, &ctrl->namespaces, list)
blk_mq_unfreeze_queue(ns->queue); blk_mq_unfreeze_queue(ns->queue);
up_read(&ctrl->namespaces_rwsem); up_read(&ctrl->namespaces_rwsem);
clear_bit(NVME_CTRL_FROZEN, &ctrl->flags);
} }
EXPORT_SYMBOL_GPL(nvme_unfreeze); EXPORT_SYMBOL_GPL(nvme_unfreeze);
...@@ -4614,6 +4625,7 @@ void nvme_start_freeze(struct nvme_ctrl *ctrl) ...@@ -4614,6 +4625,7 @@ void nvme_start_freeze(struct nvme_ctrl *ctrl)
{ {
struct nvme_ns *ns; struct nvme_ns *ns;
set_bit(NVME_CTRL_FROZEN, &ctrl->flags);
down_read(&ctrl->namespaces_rwsem); down_read(&ctrl->namespaces_rwsem);
list_for_each_entry(ns, &ctrl->namespaces, list) list_for_each_entry(ns, &ctrl->namespaces, list)
blk_freeze_queue_start(ns->queue); blk_freeze_queue_start(ns->queue);
......
...@@ -557,7 +557,7 @@ nvme_fc_rport_get(struct nvme_fc_rport *rport) ...@@ -557,7 +557,7 @@ nvme_fc_rport_get(struct nvme_fc_rport *rport)
static void static void
nvme_fc_resume_controller(struct nvme_fc_ctrl *ctrl) nvme_fc_resume_controller(struct nvme_fc_ctrl *ctrl)
{ {
switch (ctrl->ctrl.state) { switch (nvme_ctrl_state(&ctrl->ctrl)) {
case NVME_CTRL_NEW: case NVME_CTRL_NEW:
case NVME_CTRL_CONNECTING: case NVME_CTRL_CONNECTING:
/* /*
...@@ -793,7 +793,7 @@ nvme_fc_ctrl_connectivity_loss(struct nvme_fc_ctrl *ctrl) ...@@ -793,7 +793,7 @@ nvme_fc_ctrl_connectivity_loss(struct nvme_fc_ctrl *ctrl)
"NVME-FC{%d}: controller connectivity lost. Awaiting " "NVME-FC{%d}: controller connectivity lost. Awaiting "
"Reconnect", ctrl->cnum); "Reconnect", ctrl->cnum);
switch (ctrl->ctrl.state) { switch (nvme_ctrl_state(&ctrl->ctrl)) {
case NVME_CTRL_NEW: case NVME_CTRL_NEW:
case NVME_CTRL_LIVE: case NVME_CTRL_LIVE:
/* /*
...@@ -3319,7 +3319,7 @@ nvme_fc_reconnect_or_delete(struct nvme_fc_ctrl *ctrl, int status) ...@@ -3319,7 +3319,7 @@ nvme_fc_reconnect_or_delete(struct nvme_fc_ctrl *ctrl, int status)
unsigned long recon_delay = ctrl->ctrl.opts->reconnect_delay * HZ; unsigned long recon_delay = ctrl->ctrl.opts->reconnect_delay * HZ;
bool recon = true; bool recon = true;
if (ctrl->ctrl.state != NVME_CTRL_CONNECTING) if (nvme_ctrl_state(&ctrl->ctrl) != NVME_CTRL_CONNECTING)
return; return;
if (portptr->port_state == FC_OBJSTATE_ONLINE) { if (portptr->port_state == FC_OBJSTATE_ONLINE) {
......
...@@ -18,15 +18,12 @@ static bool nvme_cmd_allowed(struct nvme_ns *ns, struct nvme_command *c, ...@@ -18,15 +18,12 @@ static bool nvme_cmd_allowed(struct nvme_ns *ns, struct nvme_command *c,
{ {
u32 effects; u32 effects;
if (capable(CAP_SYS_ADMIN))
return true;
/* /*
* Do not allow unprivileged passthrough on partitions, as that allows an * Do not allow unprivileged passthrough on partitions, as that allows an
* escape from the containment of the partition. * escape from the containment of the partition.
*/ */
if (flags & NVME_IOCTL_PARTITION) if (flags & NVME_IOCTL_PARTITION)
return false; goto admin;
/* /*
* Do not allow unprivileged processes to send vendor specific or fabrics * Do not allow unprivileged processes to send vendor specific or fabrics
...@@ -34,7 +31,7 @@ static bool nvme_cmd_allowed(struct nvme_ns *ns, struct nvme_command *c, ...@@ -34,7 +31,7 @@ static bool nvme_cmd_allowed(struct nvme_ns *ns, struct nvme_command *c,
*/ */
if (c->common.opcode >= nvme_cmd_vendor_start || if (c->common.opcode >= nvme_cmd_vendor_start ||
c->common.opcode == nvme_fabrics_command) c->common.opcode == nvme_fabrics_command)
return false; goto admin;
/* /*
* Do not allow unprivileged passthrough of admin commands except * Do not allow unprivileged passthrough of admin commands except
...@@ -53,7 +50,7 @@ static bool nvme_cmd_allowed(struct nvme_ns *ns, struct nvme_command *c, ...@@ -53,7 +50,7 @@ static bool nvme_cmd_allowed(struct nvme_ns *ns, struct nvme_command *c,
return true; return true;
} }
} }
return false; goto admin;
} }
/* /*
...@@ -63,7 +60,7 @@ static bool nvme_cmd_allowed(struct nvme_ns *ns, struct nvme_command *c, ...@@ -63,7 +60,7 @@ static bool nvme_cmd_allowed(struct nvme_ns *ns, struct nvme_command *c,
*/ */
effects = nvme_command_effects(ns->ctrl, ns, c->common.opcode); effects = nvme_command_effects(ns->ctrl, ns, c->common.opcode);
if (!(effects & NVME_CMD_EFFECTS_CSUPP)) if (!(effects & NVME_CMD_EFFECTS_CSUPP))
return false; goto admin;
/* /*
* Don't allow passthrough for command that have intrusive (or unknown) * Don't allow passthrough for command that have intrusive (or unknown)
...@@ -72,16 +69,20 @@ static bool nvme_cmd_allowed(struct nvme_ns *ns, struct nvme_command *c, ...@@ -72,16 +69,20 @@ static bool nvme_cmd_allowed(struct nvme_ns *ns, struct nvme_command *c,
if (effects & ~(NVME_CMD_EFFECTS_CSUPP | NVME_CMD_EFFECTS_LBCC | if (effects & ~(NVME_CMD_EFFECTS_CSUPP | NVME_CMD_EFFECTS_LBCC |
NVME_CMD_EFFECTS_UUID_SEL | NVME_CMD_EFFECTS_UUID_SEL |
NVME_CMD_EFFECTS_SCOPE_MASK)) NVME_CMD_EFFECTS_SCOPE_MASK))
return false; goto admin;
/* /*
* Only allow I/O commands that transfer data to the controller or that * Only allow I/O commands that transfer data to the controller or that
* change the logical block contents if the file descriptor is open for * change the logical block contents if the file descriptor is open for
* writing. * writing.
*/ */
if (nvme_is_write(c) || (effects & NVME_CMD_EFFECTS_LBCC)) if ((nvme_is_write(c) || (effects & NVME_CMD_EFFECTS_LBCC)) &&
return open_for_write; !open_for_write)
goto admin;
return true; return true;
admin:
return capable(CAP_SYS_ADMIN);
} }
/* /*
......
...@@ -156,6 +156,11 @@ enum nvme_quirks { ...@@ -156,6 +156,11 @@ enum nvme_quirks {
* No temperature thresholds for channels other than 0 (Composite). * No temperature thresholds for channels other than 0 (Composite).
*/ */
NVME_QUIRK_NO_SECONDARY_TEMP_THRESH = (1 << 19), NVME_QUIRK_NO_SECONDARY_TEMP_THRESH = (1 << 19),
/*
* Disables simple suspend/resume path.
*/
NVME_QUIRK_FORCE_NO_SIMPLE_SUSPEND = (1 << 20),
}; };
/* /*
...@@ -251,6 +256,7 @@ enum nvme_ctrl_flags { ...@@ -251,6 +256,7 @@ enum nvme_ctrl_flags {
NVME_CTRL_STOPPED = 3, NVME_CTRL_STOPPED = 3,
NVME_CTRL_SKIP_ID_CNS_CS = 4, NVME_CTRL_SKIP_ID_CNS_CS = 4,
NVME_CTRL_DIRTY_CAPABILITY = 5, NVME_CTRL_DIRTY_CAPABILITY = 5,
NVME_CTRL_FROZEN = 6,
}; };
struct nvme_ctrl { struct nvme_ctrl {
...@@ -387,6 +393,11 @@ struct nvme_ctrl { ...@@ -387,6 +393,11 @@ struct nvme_ctrl {
enum nvme_dctype dctype; enum nvme_dctype dctype;
}; };
static inline enum nvme_ctrl_state nvme_ctrl_state(struct nvme_ctrl *ctrl)
{
return READ_ONCE(ctrl->state);
}
enum nvme_iopolicy { enum nvme_iopolicy {
NVME_IOPOLICY_NUMA, NVME_IOPOLICY_NUMA,
NVME_IOPOLICY_RR, NVME_IOPOLICY_RR,
......
...@@ -1233,7 +1233,7 @@ static bool nvme_should_reset(struct nvme_dev *dev, u32 csts) ...@@ -1233,7 +1233,7 @@ static bool nvme_should_reset(struct nvme_dev *dev, u32 csts)
bool nssro = dev->subsystem && (csts & NVME_CSTS_NSSRO); bool nssro = dev->subsystem && (csts & NVME_CSTS_NSSRO);
/* If there is a reset/reinit ongoing, we shouldn't reset again. */ /* If there is a reset/reinit ongoing, we shouldn't reset again. */
switch (dev->ctrl.state) { switch (nvme_ctrl_state(&dev->ctrl)) {
case NVME_CTRL_RESETTING: case NVME_CTRL_RESETTING:
case NVME_CTRL_CONNECTING: case NVME_CTRL_CONNECTING:
return false; return false;
...@@ -1321,7 +1321,7 @@ static enum blk_eh_timer_return nvme_timeout(struct request *req) ...@@ -1321,7 +1321,7 @@ static enum blk_eh_timer_return nvme_timeout(struct request *req)
* cancellation error. All outstanding requests are completed on * cancellation error. All outstanding requests are completed on
* shutdown, so we return BLK_EH_DONE. * shutdown, so we return BLK_EH_DONE.
*/ */
switch (dev->ctrl.state) { switch (nvme_ctrl_state(&dev->ctrl)) {
case NVME_CTRL_CONNECTING: case NVME_CTRL_CONNECTING:
nvme_change_ctrl_state(&dev->ctrl, NVME_CTRL_DELETING); nvme_change_ctrl_state(&dev->ctrl, NVME_CTRL_DELETING);
fallthrough; fallthrough;
...@@ -1593,7 +1593,7 @@ static int nvme_setup_io_queues_trylock(struct nvme_dev *dev) ...@@ -1593,7 +1593,7 @@ static int nvme_setup_io_queues_trylock(struct nvme_dev *dev)
/* /*
* Controller is in wrong state, fail early. * Controller is in wrong state, fail early.
*/ */
if (dev->ctrl.state != NVME_CTRL_CONNECTING) { if (nvme_ctrl_state(&dev->ctrl) != NVME_CTRL_CONNECTING) {
mutex_unlock(&dev->shutdown_lock); mutex_unlock(&dev->shutdown_lock);
return -ENODEV; return -ENODEV;
} }
...@@ -2573,13 +2573,13 @@ static bool nvme_pci_ctrl_is_dead(struct nvme_dev *dev) ...@@ -2573,13 +2573,13 @@ static bool nvme_pci_ctrl_is_dead(struct nvme_dev *dev)
static void nvme_dev_disable(struct nvme_dev *dev, bool shutdown) static void nvme_dev_disable(struct nvme_dev *dev, bool shutdown)
{ {
enum nvme_ctrl_state state = nvme_ctrl_state(&dev->ctrl);
struct pci_dev *pdev = to_pci_dev(dev->dev); struct pci_dev *pdev = to_pci_dev(dev->dev);
bool dead; bool dead;
mutex_lock(&dev->shutdown_lock); mutex_lock(&dev->shutdown_lock);
dead = nvme_pci_ctrl_is_dead(dev); dead = nvme_pci_ctrl_is_dead(dev);
if (dev->ctrl.state == NVME_CTRL_LIVE || if (state == NVME_CTRL_LIVE || state == NVME_CTRL_RESETTING) {
dev->ctrl.state == NVME_CTRL_RESETTING) {
if (pci_is_enabled(pdev)) if (pci_is_enabled(pdev))
nvme_start_freeze(&dev->ctrl); nvme_start_freeze(&dev->ctrl);
/* /*
...@@ -2690,7 +2690,7 @@ static void nvme_reset_work(struct work_struct *work) ...@@ -2690,7 +2690,7 @@ static void nvme_reset_work(struct work_struct *work)
bool was_suspend = !!(dev->ctrl.ctrl_config & NVME_CC_SHN_NORMAL); bool was_suspend = !!(dev->ctrl.ctrl_config & NVME_CC_SHN_NORMAL);
int result; int result;
if (dev->ctrl.state != NVME_CTRL_RESETTING) { if (nvme_ctrl_state(&dev->ctrl) != NVME_CTRL_RESETTING) {
dev_warn(dev->ctrl.device, "ctrl state %d is not RESETTING\n", dev_warn(dev->ctrl.device, "ctrl state %d is not RESETTING\n",
dev->ctrl.state); dev->ctrl.state);
result = -ENODEV; result = -ENODEV;
...@@ -2902,6 +2902,18 @@ static unsigned long check_vendor_combination_bug(struct pci_dev *pdev) ...@@ -2902,6 +2902,18 @@ static unsigned long check_vendor_combination_bug(struct pci_dev *pdev)
if ((dmi_match(DMI_BOARD_VENDOR, "LENOVO")) && if ((dmi_match(DMI_BOARD_VENDOR, "LENOVO")) &&
dmi_match(DMI_BOARD_NAME, "LNVNB161216")) dmi_match(DMI_BOARD_NAME, "LNVNB161216"))
return NVME_QUIRK_SIMPLE_SUSPEND; return NVME_QUIRK_SIMPLE_SUSPEND;
} else if (pdev->vendor == 0x2646 && (pdev->device == 0x2263 ||
pdev->device == 0x500f)) {
/*
* Exclude some Kingston NV1 and A2000 devices from
* NVME_QUIRK_SIMPLE_SUSPEND. Do a full suspend to save a
* lot fo energy with s2idle sleep on some TUXEDO platforms.
*/
if (dmi_match(DMI_BOARD_NAME, "NS5X_NS7XAU") ||
dmi_match(DMI_BOARD_NAME, "NS5x_7xAU") ||
dmi_match(DMI_BOARD_NAME, "NS5x_7xPU") ||
dmi_match(DMI_BOARD_NAME, "PH4PRX1_PH6PRX1"))
return NVME_QUIRK_FORCE_NO_SIMPLE_SUSPEND;
} }
return 0; return 0;
...@@ -2932,7 +2944,9 @@ static struct nvme_dev *nvme_pci_alloc_dev(struct pci_dev *pdev, ...@@ -2932,7 +2944,9 @@ static struct nvme_dev *nvme_pci_alloc_dev(struct pci_dev *pdev,
dev->dev = get_device(&pdev->dev); dev->dev = get_device(&pdev->dev);
quirks |= check_vendor_combination_bug(pdev); quirks |= check_vendor_combination_bug(pdev);
if (!noacpi && acpi_storage_d3(&pdev->dev)) { if (!noacpi &&
!(quirks & NVME_QUIRK_FORCE_NO_SIMPLE_SUSPEND) &&
acpi_storage_d3(&pdev->dev)) {
/* /*
* Some systems use a bios work around to ask for D3 on * Some systems use a bios work around to ask for D3 on
* platforms that support kernel managed suspend. * platforms that support kernel managed suspend.
...@@ -3192,7 +3206,7 @@ static int nvme_suspend(struct device *dev) ...@@ -3192,7 +3206,7 @@ static int nvme_suspend(struct device *dev)
nvme_wait_freeze(ctrl); nvme_wait_freeze(ctrl);
nvme_sync_queues(ctrl); nvme_sync_queues(ctrl);
if (ctrl->state != NVME_CTRL_LIVE) if (nvme_ctrl_state(ctrl) != NVME_CTRL_LIVE)
goto unfreeze; goto unfreeze;
/* /*
......
...@@ -984,10 +984,11 @@ static void nvme_rdma_free_ctrl(struct nvme_ctrl *nctrl) ...@@ -984,10 +984,11 @@ static void nvme_rdma_free_ctrl(struct nvme_ctrl *nctrl)
static void nvme_rdma_reconnect_or_remove(struct nvme_rdma_ctrl *ctrl) static void nvme_rdma_reconnect_or_remove(struct nvme_rdma_ctrl *ctrl)
{ {
enum nvme_ctrl_state state = nvme_ctrl_state(&ctrl->ctrl);
/* If we are resetting/deleting then do nothing */ /* If we are resetting/deleting then do nothing */
if (ctrl->ctrl.state != NVME_CTRL_CONNECTING) { if (state != NVME_CTRL_CONNECTING) {
WARN_ON_ONCE(ctrl->ctrl.state == NVME_CTRL_NEW || WARN_ON_ONCE(state == NVME_CTRL_NEW || state == NVME_CTRL_LIVE);
ctrl->ctrl.state == NVME_CTRL_LIVE);
return; return;
} }
...@@ -1059,8 +1060,10 @@ static int nvme_rdma_setup_ctrl(struct nvme_rdma_ctrl *ctrl, bool new) ...@@ -1059,8 +1060,10 @@ static int nvme_rdma_setup_ctrl(struct nvme_rdma_ctrl *ctrl, bool new)
* unless we're during creation of a new controller to * unless we're during creation of a new controller to
* avoid races with teardown flow. * avoid races with teardown flow.
*/ */
WARN_ON_ONCE(ctrl->ctrl.state != NVME_CTRL_DELETING && enum nvme_ctrl_state state = nvme_ctrl_state(&ctrl->ctrl);
ctrl->ctrl.state != NVME_CTRL_DELETING_NOIO);
WARN_ON_ONCE(state != NVME_CTRL_DELETING &&
state != NVME_CTRL_DELETING_NOIO);
WARN_ON_ONCE(new); WARN_ON_ONCE(new);
ret = -EINVAL; ret = -EINVAL;
goto destroy_io; goto destroy_io;
...@@ -1129,8 +1132,10 @@ static void nvme_rdma_error_recovery_work(struct work_struct *work) ...@@ -1129,8 +1132,10 @@ static void nvme_rdma_error_recovery_work(struct work_struct *work)
if (!nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_CONNECTING)) { if (!nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_CONNECTING)) {
/* state change failure is ok if we started ctrl delete */ /* state change failure is ok if we started ctrl delete */
WARN_ON_ONCE(ctrl->ctrl.state != NVME_CTRL_DELETING && enum nvme_ctrl_state state = nvme_ctrl_state(&ctrl->ctrl);
ctrl->ctrl.state != NVME_CTRL_DELETING_NOIO);
WARN_ON_ONCE(state != NVME_CTRL_DELETING &&
state != NVME_CTRL_DELETING_NOIO);
return; return;
} }
...@@ -1162,7 +1167,7 @@ static void nvme_rdma_wr_error(struct ib_cq *cq, struct ib_wc *wc, ...@@ -1162,7 +1167,7 @@ static void nvme_rdma_wr_error(struct ib_cq *cq, struct ib_wc *wc,
struct nvme_rdma_queue *queue = wc->qp->qp_context; struct nvme_rdma_queue *queue = wc->qp->qp_context;
struct nvme_rdma_ctrl *ctrl = queue->ctrl; struct nvme_rdma_ctrl *ctrl = queue->ctrl;
if (ctrl->ctrl.state == NVME_CTRL_LIVE) if (nvme_ctrl_state(&ctrl->ctrl) == NVME_CTRL_LIVE)
dev_info(ctrl->ctrl.device, dev_info(ctrl->ctrl.device,
"%s for CQE 0x%p failed with status %s (%d)\n", "%s for CQE 0x%p failed with status %s (%d)\n",
op, wc->wr_cqe, op, wc->wr_cqe,
...@@ -1945,7 +1950,7 @@ static enum blk_eh_timer_return nvme_rdma_timeout(struct request *rq) ...@@ -1945,7 +1950,7 @@ static enum blk_eh_timer_return nvme_rdma_timeout(struct request *rq)
dev_warn(ctrl->ctrl.device, "I/O %d QID %d timeout\n", dev_warn(ctrl->ctrl.device, "I/O %d QID %d timeout\n",
rq->tag, nvme_rdma_queue_idx(queue)); rq->tag, nvme_rdma_queue_idx(queue));
if (ctrl->ctrl.state != NVME_CTRL_LIVE) { if (nvme_ctrl_state(&ctrl->ctrl) != NVME_CTRL_LIVE) {
/* /*
* If we are resetting, connecting or deleting we should * If we are resetting, connecting or deleting we should
* complete immediately because we may block controller * complete immediately because we may block controller
......
...@@ -2152,10 +2152,11 @@ static void nvme_tcp_teardown_io_queues(struct nvme_ctrl *ctrl, ...@@ -2152,10 +2152,11 @@ static void nvme_tcp_teardown_io_queues(struct nvme_ctrl *ctrl,
static void nvme_tcp_reconnect_or_remove(struct nvme_ctrl *ctrl) static void nvme_tcp_reconnect_or_remove(struct nvme_ctrl *ctrl)
{ {
enum nvme_ctrl_state state = nvme_ctrl_state(ctrl);
/* If we are resetting/deleting then do nothing */ /* If we are resetting/deleting then do nothing */
if (ctrl->state != NVME_CTRL_CONNECTING) { if (state != NVME_CTRL_CONNECTING) {
WARN_ON_ONCE(ctrl->state == NVME_CTRL_NEW || WARN_ON_ONCE(state == NVME_CTRL_NEW || state == NVME_CTRL_LIVE);
ctrl->state == NVME_CTRL_LIVE);
return; return;
} }
...@@ -2215,8 +2216,10 @@ static int nvme_tcp_setup_ctrl(struct nvme_ctrl *ctrl, bool new) ...@@ -2215,8 +2216,10 @@ static int nvme_tcp_setup_ctrl(struct nvme_ctrl *ctrl, bool new)
* unless we're during creation of a new controller to * unless we're during creation of a new controller to
* avoid races with teardown flow. * avoid races with teardown flow.
*/ */
WARN_ON_ONCE(ctrl->state != NVME_CTRL_DELETING && enum nvme_ctrl_state state = nvme_ctrl_state(ctrl);
ctrl->state != NVME_CTRL_DELETING_NOIO);
WARN_ON_ONCE(state != NVME_CTRL_DELETING &&
state != NVME_CTRL_DELETING_NOIO);
WARN_ON_ONCE(new); WARN_ON_ONCE(new);
ret = -EINVAL; ret = -EINVAL;
goto destroy_io; goto destroy_io;
...@@ -2280,8 +2283,10 @@ static void nvme_tcp_error_recovery_work(struct work_struct *work) ...@@ -2280,8 +2283,10 @@ static void nvme_tcp_error_recovery_work(struct work_struct *work)
if (!nvme_change_ctrl_state(ctrl, NVME_CTRL_CONNECTING)) { if (!nvme_change_ctrl_state(ctrl, NVME_CTRL_CONNECTING)) {
/* state change failure is ok if we started ctrl delete */ /* state change failure is ok if we started ctrl delete */
WARN_ON_ONCE(ctrl->state != NVME_CTRL_DELETING && enum nvme_ctrl_state state = nvme_ctrl_state(ctrl);
ctrl->state != NVME_CTRL_DELETING_NOIO);
WARN_ON_ONCE(state != NVME_CTRL_DELETING &&
state != NVME_CTRL_DELETING_NOIO);
return; return;
} }
...@@ -2311,8 +2316,10 @@ static void nvme_reset_ctrl_work(struct work_struct *work) ...@@ -2311,8 +2316,10 @@ static void nvme_reset_ctrl_work(struct work_struct *work)
if (!nvme_change_ctrl_state(ctrl, NVME_CTRL_CONNECTING)) { if (!nvme_change_ctrl_state(ctrl, NVME_CTRL_CONNECTING)) {
/* state change failure is ok if we started ctrl delete */ /* state change failure is ok if we started ctrl delete */
WARN_ON_ONCE(ctrl->state != NVME_CTRL_DELETING && enum nvme_ctrl_state state = nvme_ctrl_state(ctrl);
ctrl->state != NVME_CTRL_DELETING_NOIO);
WARN_ON_ONCE(state != NVME_CTRL_DELETING &&
state != NVME_CTRL_DELETING_NOIO);
return; return;
} }
...@@ -2430,7 +2437,7 @@ static enum blk_eh_timer_return nvme_tcp_timeout(struct request *rq) ...@@ -2430,7 +2437,7 @@ static enum blk_eh_timer_return nvme_tcp_timeout(struct request *rq)
nvme_tcp_queue_id(req->queue), nvme_cid(rq), pdu->hdr.type, nvme_tcp_queue_id(req->queue), nvme_cid(rq), pdu->hdr.type,
opc, nvme_opcode_str(qid, opc, fctype)); opc, nvme_opcode_str(qid, opc, fctype));
if (ctrl->state != NVME_CTRL_LIVE) { if (nvme_ctrl_state(ctrl) != NVME_CTRL_LIVE) {
/* /*
* If we are resetting, connecting or deleting we should * If we are resetting, connecting or deleting we should
* complete immediately because we may block controller * complete immediately because we may block controller
......
...@@ -99,10 +99,11 @@ config NVME_TARGET_TCP_TLS ...@@ -99,10 +99,11 @@ config NVME_TARGET_TCP_TLS
If unsure, say N. If unsure, say N.
config NVME_TARGET_AUTH config NVME_TARGET_AUTH
bool "NVMe over Fabrics In-band Authentication support" bool "NVMe over Fabrics In-band Authentication in target side"
depends on NVME_TARGET depends on NVME_TARGET
select NVME_AUTH select NVME_AUTH
help help
This enables support for NVMe over Fabrics In-band Authentication This enables support for NVMe over Fabrics In-band Authentication in
target side.
If unsure, say N. If unsure, say N.
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include <linux/nvme-keyring.h> #include <linux/nvme-keyring.h>
#include <crypto/hash.h> #include <crypto/hash.h>
#include <crypto/kpp.h> #include <crypto/kpp.h>
#include <linux/nospec.h>
#include "nvmet.h" #include "nvmet.h"
...@@ -621,6 +622,7 @@ static ssize_t nvmet_ns_ana_grpid_store(struct config_item *item, ...@@ -621,6 +622,7 @@ static ssize_t nvmet_ns_ana_grpid_store(struct config_item *item,
down_write(&nvmet_ana_sem); down_write(&nvmet_ana_sem);
oldgrpid = ns->anagrpid; oldgrpid = ns->anagrpid;
newgrpid = array_index_nospec(newgrpid, NVMET_MAX_ANAGRPS);
nvmet_ana_group_enabled[newgrpid]++; nvmet_ana_group_enabled[newgrpid]++;
ns->anagrpid = newgrpid; ns->anagrpid = newgrpid;
nvmet_ana_group_enabled[oldgrpid]--; nvmet_ana_group_enabled[oldgrpid]--;
...@@ -1812,6 +1814,7 @@ static struct config_group *nvmet_ana_groups_make_group( ...@@ -1812,6 +1814,7 @@ static struct config_group *nvmet_ana_groups_make_group(
grp->grpid = grpid; grp->grpid = grpid;
down_write(&nvmet_ana_sem); down_write(&nvmet_ana_sem);
grpid = array_index_nospec(grpid, NVMET_MAX_ANAGRPS);
nvmet_ana_group_enabled[grpid]++; nvmet_ana_group_enabled[grpid]++;
up_write(&nvmet_ana_sem); up_write(&nvmet_ana_sem);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment