From: scott.bauer@intel.com (Scott Bauer)
Subject: [PATCH v4 5/6] nvme: Add Support for Opal: Unlock from S3 & Opal Allocation/Ioctls
Date: Thu, 29 Dec 2016 12:26:54 -0700 [thread overview]
Message-ID: <1483039615-22407-6-git-send-email-scott.bauer@intel.com> (raw)
In-Reply-To: <1483039615-22407-1-git-send-email-scott.bauer@intel.com>
This patch implements the necessary logic to unlock an Opal
enabled device coming back from an S3.
The patch also implements the SED/Opal allocation necessary to support
the opal ioctls.
Signed-off-by: Scott Bauer <scott.bauer at intel.com>
---
drivers/nvme/host/Kconfig | 7 +++++
drivers/nvme/host/core.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++
drivers/nvme/host/nvme.h | 9 +++++-
drivers/nvme/host/pci.c | 4 +++
4 files changed, 97 insertions(+), 1 deletion(-)
diff --git a/drivers/nvme/host/Kconfig b/drivers/nvme/host/Kconfig
index 90745a6..f492b00 100644
--- a/drivers/nvme/host/Kconfig
+++ b/drivers/nvme/host/Kconfig
@@ -25,6 +25,13 @@ config BLK_DEV_NVME_SCSI
emulation to provide stable device names for mount by id, like
some OpenSuSE and SLES versions.
+config BLK_DEV_SED_OPAL
+ bool "Enable support for Opal Enabled NVMe Device"
+ depends on BLK_SED_OPAL
+ default n
+ ---help---
+ This enables support for an Opal enabled NVMe device.
+
config NVME_FABRICS
tristate
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index b40cfb0..3a8ea98 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -28,6 +28,8 @@
#include <linux/t10-pi.h>
#include <scsi/sg.h>
#include <asm/unaligned.h>
+#include <linux/sed.h>
+#include <linux/sed-opal.h>
#include "nvme.h"
#include "fabrics.h"
@@ -762,6 +764,27 @@ static int nvme_user_cmd(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
return status;
}
+#ifdef CONFIG_BLK_DEV_SED_OPAL
+static int nvme_sec_submit(struct sed_context *ctx, u16 spsp, u8 secp,
+ void *buffer, size_t len, bool send)
+{
+ struct nvme_command cmd = { 0 };
+ struct nvme_ns *ns = NULL;
+
+ if (send)
+ cmd.common.opcode = nvme_admin_security_send;
+ else
+ cmd.common.opcode = nvme_admin_security_recv;
+ ns = container_of(ctx, struct nvme_ns, sed_ctx);
+ cmd.common.nsid = cpu_to_le32(ns->ns_id);
+ cmd.common.cdw10[0] = cpu_to_le32(((u32)secp) << 24 | ((u32)spsp) << 8);
+ cmd.common.cdw10[1] = cpu_to_le32(len);
+
+ return __nvme_submit_sync_cmd(ns->ctrl->admin_q, &cmd, NULL, buffer, len,
+ ADMIN_TIMEOUT, NVME_QID_ANY, 1, 0);
+}
+#endif
+
static int nvme_ioctl(struct block_device *bdev, fmode_t mode,
unsigned int cmd, unsigned long arg)
{
@@ -784,6 +807,11 @@ static int nvme_ioctl(struct block_device *bdev, fmode_t mode,
return nvme_sg_io(ns, (void __user *)arg);
#endif
default:
+#ifdef CONFIG_BLK_DEV_SED_OPAL
+ if (is_sed_ioctl(cmd))
+ return sed_ioctl(&ns->sed_ctx, cmd, arg);
+
+#endif
return -ENOTTY;
}
}
@@ -1051,6 +1079,51 @@ static const struct pr_ops nvme_pr_ops = {
.pr_clear = nvme_pr_clear,
};
+static int nvme_opal_initialize(struct nvme_ns *ns)
+{
+
+#ifdef CONFIG_BLK_DEV_SED_OPAL
+ /* Opal dev has already been allocated for this controller */
+ if (ns->sed_ctx.dev)
+ return 0;
+
+ ns->sed_ctx.dev = alloc_opal_dev(ns->ctrl->admin_q);
+ if (!ns->sed_ctx.dev)
+ return -ENOMEM;
+ ns->sed_ctx.send_recv = &nvme_sec_submit;
+
+ /* In the future when we have to determine whether or not we're in
+ * Multi-LR Mult-NS mode or Single-LR Multi-NS mode we'll
+ * pass pointers into is_opal_supported
+ */
+ if (is_opal_supported(&ns->sed_ctx, NULL, NULL) != 1) {
+ dev_warn(ns->ctrl->device, "Opal is not supported\n");
+ kfree(ns->sed_ctx.dev);
+ ns->sed_ctx.dev = NULL;
+ }
+ return 0;
+#else
+ return 0;
+#endif
+}
+
+
+void nvme_unlock_from_suspend(struct nvme_ctrl *ctrl)
+{
+#ifdef CONFIG_BLK_DEV_SED_OPAL
+ struct nvme_ns *ns, *next;
+ mutex_lock(&ctrl->namespaces_mutex);
+ list_for_each_entry_safe(ns, next, &ctrl->namespaces, list) {
+ if (!ns->sed_ctx.supported)
+ continue;
+ if (opal_unlock_from_suspend(&ns->sed_ctx))
+ dev_warn(ctrl->dev, "Failed to unlock one or more locking ranges!\n");
+ }
+ mutex_unlock(&ctrl->namespaces_mutex);
+#endif
+}
+EXPORT_SYMBOL_GPL(nvme_unlock_from_suspend);
+
static const struct block_device_operations nvme_fops = {
.owner = THIS_MODULE,
.ioctl = nvme_ioctl,
@@ -1673,6 +1746,11 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid)
goto out_free_id;
}
+ if (nvme_opal_initialize(ns)) {
+ dev_warn(ctrl->dev, "%s Couldn't allocate an Opal structure!\n",
+ __func__);
+ goto out_free_id;
+ }
disk = alloc_disk_node(0, node);
if (!disk)
goto out_free_id;
diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
index bd53214..1f18c53 100644
--- a/drivers/nvme/host/nvme.h
+++ b/drivers/nvme/host/nvme.h
@@ -19,6 +19,7 @@
#include <linux/kref.h>
#include <linux/blk-mq.h>
#include <linux/lightnvm.h>
+#include <linux/sed.h>
enum {
/*
@@ -188,6 +189,10 @@ struct nvme_ns {
u64 mode_select_num_blocks;
u32 mode_select_block_len;
+
+#ifdef CONFIG_BLK_SED_OPAL
+ struct sed_context sed_ctx;
+#endif
};
struct nvme_ctrl_ops {
@@ -256,7 +261,8 @@ static inline int nvme_error_status(u16 status)
static inline bool nvme_req_needs_retry(struct request *req, u16 status)
{
- return !(status & NVME_SC_DNR || blk_noretry_request(req)) &&
+ return !(status & NVME_SC_DNR || status & NVME_SC_ACCESS_DENIED ||
+ blk_noretry_request(req)) &&
(jiffies - req->start_time) < req->timeout &&
req->retries < nvme_max_retries;
}
@@ -275,6 +281,7 @@ int nvme_init_identify(struct nvme_ctrl *ctrl);
void nvme_queue_scan(struct nvme_ctrl *ctrl);
void nvme_remove_namespaces(struct nvme_ctrl *ctrl);
+void nvme_unlock_from_suspend(struct nvme_ctrl *ctrl);
#define NVME_NR_AERS 1
void nvme_complete_async_event(struct nvme_ctrl *ctrl, __le16 status,
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
index 3d21a15..dbf7818 100644
--- a/drivers/nvme/host/pci.c
+++ b/drivers/nvme/host/pci.c
@@ -1764,6 +1764,7 @@ static void nvme_remove_dead_ctrl(struct nvme_dev *dev, int status)
static void nvme_reset_work(struct work_struct *work)
{
struct nvme_dev *dev = container_of(work, struct nvme_dev, reset_work);
+ bool was_suspend = !!(dev->ctrl.ctrl_config & NVME_CC_SHN_NORMAL);
int result = -ENODEV;
if (WARN_ON(dev->ctrl.state == NVME_CTRL_RESETTING))
@@ -1796,6 +1797,9 @@ static void nvme_reset_work(struct work_struct *work)
if (result)
goto out;
+ if (was_suspend)
+ nvme_unlock_from_suspend(&dev->ctrl);
+
result = nvme_setup_io_queues(dev);
if (result)
goto out;
--
2.7.4
next prev parent reply other threads:[~2016-12-29 19:26 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-12-29 19:26 [PATCH v4 0/6] SED OPAL Library Scott Bauer
2016-12-29 19:26 ` [PATCH v4 1/6] Include: Uapi: Add user ABI for Sed/Opal Scott Bauer
2016-12-29 19:26 ` [PATCH v4 2/6] block: Add Sed-opal library Scott Bauer
2016-12-30 21:02 ` Jon Derrick
2017-01-08 13:32 ` Christoph Hellwig
2017-01-08 14:05 ` Christoph Hellwig
2017-01-11 17:47 ` J Freyensee
2017-01-30 17:08 ` Scott Bauer
2017-01-19 18:28 ` Scott Bauer
2017-01-24 0:20 ` J Freyensee
2017-01-24 7:46 ` Christoph Hellwig
2016-12-29 19:26 ` [PATCH v4 3/6] block: add ioctl interface for interfacing with Opal library Scott Bauer
2017-01-08 14:06 ` Christoph Hellwig
2016-12-29 19:26 ` [PATCH v4 4/6] block: Add Opal Files to Makefile & add config option to Kconfig Scott Bauer
2017-01-08 14:09 ` Christoph Hellwig
2016-12-29 19:26 ` Scott Bauer [this message]
2017-01-08 14:20 ` [PATCH v4 5/6] nvme: Add Support for Opal: Unlock from S3 & Opal Allocation/Ioctls Christoph Hellwig
2017-01-18 18:45 ` Keith Busch
2017-01-24 8:14 ` Christoph Hellwig
2017-01-19 19:32 ` Jon Derrick
2016-12-29 19:26 ` [PATCH v4 6/6] Maintainers: Add maintainer info for SED/Opal library Scott Bauer
2016-12-29 21:00 ` [PATCH v4 0/6] SED OPAL Library Scott Bauer
2016-12-30 8:28 ` Christoph Hellwig
2016-12-30 22:52 ` Scott Bauer
2016-12-31 3:51 ` Christoph Hellwig
2016-12-31 5:41 ` Scott Bauer
2016-12-31 5:47 ` Christoph Hellwig
2017-01-03 22:09 ` Scott Bauer
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1483039615-22407-6-git-send-email-scott.bauer@intel.com \
--to=scott.bauer@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.