aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2017-02-17 07:59:39 -0500
committerJens Axboe <axboe@fb.com>2017-02-17 14:41:47 -0500
commit4f1244c8298606b8fae64b4d78b820ae6b896e3c (patch)
tree81fbf9080d730ca328572847be75fa4e05e4268e
parentf5b37b7c23915af93081a8711e0a0f0219063756 (diff)
block/sed-opal: allocate struct opal_dev dynamically
Insted of bloating the containing structure with it all the time this allocates struct opal_dev dynamically. Additionally this allows moving the definition of struct opal_dev into sed-opal.c. For this a new private data field is added to it that is passed to the send/receive callback. After that a lot of internals can be made private as well. Signed-off-by: Christoph Hellwig <hch@lst.de> Tested-by: Scott Bauer <scott.bauer@intel.com> Reviewed-by: Scott Bauer <scott.bauer@intel.com> Signed-off-by: Jens Axboe <axboe@fb.com>
-rw-r--r--block/opal_proto.h23
-rw-r--r--block/sed-opal.c101
-rw-r--r--drivers/nvme/host/core.c9
-rw-r--r--drivers/nvme/host/nvme.h14
-rw-r--r--drivers/nvme/host/pci.c8
-rw-r--r--include/linux/sed-opal.h116
6 files changed, 131 insertions, 140 deletions
diff --git a/block/opal_proto.h b/block/opal_proto.h
index af9abc56c157..f40c9acf8895 100644
--- a/block/opal_proto.h
+++ b/block/opal_proto.h
@@ -19,6 +19,29 @@
19#ifndef _OPAL_PROTO_H 19#ifndef _OPAL_PROTO_H
20#define _OPAL_PROTO_H 20#define _OPAL_PROTO_H
21 21
22/*
23 * These constant values come from:
24 * SPC-4 section
25 * 6.30 SECURITY PROTOCOL IN command / table 265.
26 */
27enum {
28 TCG_SECP_00 = 0,
29 TCG_SECP_01,
30};
31
32/*
33 * Token defs derived from:
34 * TCG_Storage_Architecture_Core_Spec_v2.01_r1.00
35 * 3.2.2 Data Stream Encoding
36 */
37enum opal_response_token {
38 OPAL_DTA_TOKENID_BYTESTRING = 0xe0,
39 OPAL_DTA_TOKENID_SINT = 0xe1,
40 OPAL_DTA_TOKENID_UINT = 0xe2,
41 OPAL_DTA_TOKENID_TOKEN = 0xe3, /* actual token is returned */
42 OPAL_DTA_TOKENID_INVALID = 0X0
43};
44
22#define DTAERROR_NO_METHOD_STATUS 0x89 45#define DTAERROR_NO_METHOD_STATUS 0x89
23#define GENERIC_HOST_SESSION_NUM 0x41 46#define GENERIC_HOST_SESSION_NUM 0x41
24 47
diff --git a/block/sed-opal.c b/block/sed-opal.c
index bcdd5b6d02e8..d1c52ba4d62d 100644
--- a/block/sed-opal.c
+++ b/block/sed-opal.c
@@ -31,6 +31,77 @@
31 31
32#include "opal_proto.h" 32#include "opal_proto.h"
33 33
34#define IO_BUFFER_LENGTH 2048
35#define MAX_TOKS 64
36
37typedef int (*opal_step)(struct opal_dev *dev);
38
39enum opal_atom_width {
40 OPAL_WIDTH_TINY,
41 OPAL_WIDTH_SHORT,
42 OPAL_WIDTH_MEDIUM,
43 OPAL_WIDTH_LONG,
44 OPAL_WIDTH_TOKEN
45};
46
47/*
48 * On the parsed response, we don't store again the toks that are already
49 * stored in the response buffer. Instead, for each token, we just store a
50 * pointer to the position in the buffer where the token starts, and the size
51 * of the token in bytes.
52 */
53struct opal_resp_tok {
54 const u8 *pos;
55 size_t len;
56 enum opal_response_token type;
57 enum opal_atom_width width;
58 union {
59 u64 u;
60 s64 s;
61 } stored;
62};
63
64/*
65 * From the response header it's not possible to know how many tokens there are
66 * on the payload. So we hardcode that the maximum will be MAX_TOKS, and later
67 * if we start dealing with messages that have more than that, we can increase
68 * this number. This is done to avoid having to make two passes through the
69 * response, the first one counting how many tokens we have and the second one
70 * actually storing the positions.
71 */
72struct parsed_resp {
73 int num;
74 struct opal_resp_tok toks[MAX_TOKS];
75};
76
77struct opal_dev {
78 bool supported;
79
80 void *data;
81 sec_send_recv *send_recv;
82
83 const opal_step *funcs;
84 void **func_data;
85 int state;
86 struct mutex dev_lock;
87 u16 comid;
88 u32 hsn;
89 u32 tsn;
90 u64 align;
91 u64 lowest_lba;
92
93 size_t pos;
94 u8 cmd[IO_BUFFER_LENGTH];
95 u8 resp[IO_BUFFER_LENGTH];
96
97 struct parsed_resp parsed;
98 size_t prev_d_len;
99 void *prev_data;
100
101 struct list_head unlk_lst;
102};
103
104
34static const u8 opaluid[][OPAL_UID_LENGTH] = { 105static const u8 opaluid[][OPAL_UID_LENGTH] = {
35 /* users */ 106 /* users */
36 [OPAL_SMUID_UID] = 107 [OPAL_SMUID_UID] =
@@ -243,14 +314,14 @@ static u16 get_comid_v200(const void *data)
243 314
244static int opal_send_cmd(struct opal_dev *dev) 315static int opal_send_cmd(struct opal_dev *dev)
245{ 316{
246 return dev->send_recv(dev, dev->comid, TCG_SECP_01, 317 return dev->send_recv(dev->data, dev->comid, TCG_SECP_01,
247 dev->cmd, IO_BUFFER_LENGTH, 318 dev->cmd, IO_BUFFER_LENGTH,
248 true); 319 true);
249} 320}
250 321
251static int opal_recv_cmd(struct opal_dev *dev) 322static int opal_recv_cmd(struct opal_dev *dev)
252{ 323{
253 return dev->send_recv(dev, dev->comid, TCG_SECP_01, 324 return dev->send_recv(dev->data, dev->comid, TCG_SECP_01,
254 dev->resp, IO_BUFFER_LENGTH, 325 dev->resp, IO_BUFFER_LENGTH,
255 false); 326 false);
256} 327}
@@ -1943,16 +2014,24 @@ static int check_opal_support(struct opal_dev *dev)
1943 return ret; 2014 return ret;
1944} 2015}
1945 2016
1946void init_opal_dev(struct opal_dev *opal_dev, sec_send_recv *send_recv) 2017struct opal_dev *init_opal_dev(void *data, sec_send_recv *send_recv)
1947{ 2018{
1948 if (opal_dev->initialized) 2019 struct opal_dev *dev;
1949 return; 2020
1950 INIT_LIST_HEAD(&opal_dev->unlk_lst); 2021 dev = kmalloc(sizeof(*dev), GFP_KERNEL);
1951 mutex_init(&opal_dev->dev_lock); 2022 if (!dev)
1952 opal_dev->send_recv = send_recv; 2023 return NULL;
1953 if (check_opal_support(opal_dev) < 0) 2024
2025 INIT_LIST_HEAD(&dev->unlk_lst);
2026 mutex_init(&dev->dev_lock);
2027 dev->data = data;
2028 dev->send_recv = send_recv;
2029 if (check_opal_support(dev) != 0) {
1954 pr_debug("Opal is not supported on this device\n"); 2030 pr_debug("Opal is not supported on this device\n");
1955 opal_dev->initialized = true; 2031 kfree(dev);
2032 return NULL;
2033 }
2034 return dev;
1956} 2035}
1957EXPORT_SYMBOL(init_opal_dev); 2036EXPORT_SYMBOL(init_opal_dev);
1958 2037
@@ -2351,6 +2430,8 @@ int sed_ioctl(struct opal_dev *dev, unsigned int cmd, void __user *arg)
2351 2430
2352 if (!capable(CAP_SYS_ADMIN)) 2431 if (!capable(CAP_SYS_ADMIN))
2353 return -EACCES; 2432 return -EACCES;
2433 if (!dev)
2434 return -ENOTSUPP;
2354 if (!dev->supported) { 2435 if (!dev->supported) {
2355 pr_err("Not supported\n"); 2436 pr_err("Not supported\n");
2356 return -ENOTSUPP; 2437 return -ENOTSUPP;
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index b92a79281611..f6b56a12457a 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -789,7 +789,7 @@ static int nvme_ioctl(struct block_device *bdev, fmode_t mode,
789 return nvme_nvm_ioctl(ns, cmd, arg); 789 return nvme_nvm_ioctl(ns, cmd, arg);
790#endif 790#endif
791 if (is_sed_ioctl(cmd)) 791 if (is_sed_ioctl(cmd))
792 return sed_ioctl(&ns->ctrl->opal_dev, cmd, 792 return sed_ioctl(ns->ctrl->opal_dev, cmd,
793 (void __user *) arg); 793 (void __user *) arg);
794 return -ENOTTY; 794 return -ENOTTY;
795 } 795 }
@@ -1059,18 +1059,17 @@ static const struct pr_ops nvme_pr_ops = {
1059}; 1059};
1060 1060
1061#ifdef CONFIG_BLK_SED_OPAL 1061#ifdef CONFIG_BLK_SED_OPAL
1062int nvme_sec_submit(struct opal_dev *dev, u16 spsp, u8 secp, 1062int nvme_sec_submit(void *data, u16 spsp, u8 secp, void *buffer, size_t len,
1063 void *buffer, size_t len, bool send) 1063 bool send)
1064{ 1064{
1065 struct nvme_ctrl *ctrl = data;
1065 struct nvme_command cmd; 1066 struct nvme_command cmd;
1066 struct nvme_ctrl *ctrl = NULL;
1067 1067
1068 memset(&cmd, 0, sizeof(cmd)); 1068 memset(&cmd, 0, sizeof(cmd));
1069 if (send) 1069 if (send)
1070 cmd.common.opcode = nvme_admin_security_send; 1070 cmd.common.opcode = nvme_admin_security_send;
1071 else 1071 else
1072 cmd.common.opcode = nvme_admin_security_recv; 1072 cmd.common.opcode = nvme_admin_security_recv;
1073 ctrl = container_of(dev, struct nvme_ctrl, opal_dev);
1074 cmd.common.nsid = 0; 1073 cmd.common.nsid = 0;
1075 cmd.common.cdw10[0] = cpu_to_le32(((u32)secp) << 24 | ((u32)spsp) << 8); 1074 cmd.common.cdw10[0] = cpu_to_le32(((u32)secp) << 24 | ((u32)spsp) << 8);
1076 cmd.common.cdw10[1] = cpu_to_le32(len); 1075 cmd.common.cdw10[1] = cpu_to_le32(len);
diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
index 1aa353a848e3..fd94c94ccbcb 100644
--- a/drivers/nvme/host/nvme.h
+++ b/drivers/nvme/host/nvme.h
@@ -126,7 +126,7 @@ struct nvme_ctrl {
126 struct list_head node; 126 struct list_head node;
127 struct ida ns_ida; 127 struct ida ns_ida;
128 128
129 struct opal_dev opal_dev; 129 struct opal_dev *opal_dev;
130 130
131 char name[12]; 131 char name[12];
132 char serial[20]; 132 char serial[20];
@@ -278,16 +278,8 @@ int nvme_init_identify(struct nvme_ctrl *ctrl);
278void nvme_queue_scan(struct nvme_ctrl *ctrl); 278void nvme_queue_scan(struct nvme_ctrl *ctrl);
279void nvme_remove_namespaces(struct nvme_ctrl *ctrl); 279void nvme_remove_namespaces(struct nvme_ctrl *ctrl);
280 280
281#ifdef CONFIG_BLK_SED_OPAL 281int nvme_sec_submit(void *data, u16 spsp, u8 secp, void *buffer, size_t len,
282int nvme_sec_submit(struct opal_dev *dev, u16 spsp, u8 secp, 282 bool send);
283 void *buffer, size_t len, bool send);
284#else
285static inline int nvme_sec_submit(struct opal_dev *dev, u16 spsp, u8 secp,
286 void *buffer, size_t len, bool send)
287{
288 return 0;
289}
290#endif /* CONFIG_BLK_DEV_SED_OPAL */
291 283
292#define NVME_NR_AERS 1 284#define NVME_NR_AERS 1
293void nvme_complete_async_event(struct nvme_ctrl *ctrl, __le16 status, 285void 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 f08e86e73dda..50b070528c50 100644
--- a/drivers/nvme/host/pci.c
+++ b/drivers/nvme/host/pci.c
@@ -1742,6 +1742,7 @@ static void nvme_pci_free_ctrl(struct nvme_ctrl *ctrl)
1742 if (dev->ctrl.admin_q) 1742 if (dev->ctrl.admin_q)
1743 blk_put_queue(dev->ctrl.admin_q); 1743 blk_put_queue(dev->ctrl.admin_q);
1744 kfree(dev->queues); 1744 kfree(dev->queues);
1745 kfree(dev->ctrl.opal_dev);
1745 kfree(dev); 1746 kfree(dev);
1746} 1747}
1747 1748
@@ -1791,10 +1792,13 @@ static void nvme_reset_work(struct work_struct *work)
1791 if (result) 1792 if (result)
1792 goto out; 1793 goto out;
1793 1794
1794 init_opal_dev(&dev->ctrl.opal_dev, &nvme_sec_submit); 1795 if (!dev->ctrl.opal_dev) {
1796 dev->ctrl.opal_dev =
1797 init_opal_dev(&dev->ctrl, &nvme_sec_submit);
1798 }
1795 1799
1796 if (was_suspend) 1800 if (was_suspend)
1797 opal_unlock_from_suspend(&dev->ctrl.opal_dev); 1801 opal_unlock_from_suspend(dev->ctrl.opal_dev);
1798 1802
1799 result = nvme_setup_io_queues(dev); 1803 result = nvme_setup_io_queues(dev);
1800 if (result) 1804 if (result)
diff --git a/include/linux/sed-opal.h b/include/linux/sed-opal.h
index 205d520ea688..deee23d012e7 100644
--- a/include/linux/sed-opal.h
+++ b/include/linux/sed-opal.h
@@ -21,117 +21,14 @@
21#include <uapi/linux/sed-opal.h> 21#include <uapi/linux/sed-opal.h>
22#include <linux/kernel.h> 22#include <linux/kernel.h>
23 23
24/*
25 * These constant values come from:
26 * SPC-4 section
27 * 6.30 SECURITY PROTOCOL IN command / table 265.
28 */
29enum {
30 TCG_SECP_00 = 0,
31 TCG_SECP_01,
32};
33struct opal_dev; 24struct opal_dev;
34 25
35#define IO_BUFFER_LENGTH 2048 26typedef int (sec_send_recv)(void *data, u16 spsp, u8 secp, void *buffer,
36#define MAX_TOKS 64 27 size_t len, bool send);
37
38typedef int (*opal_step)(struct opal_dev *dev);
39typedef int (sec_send_recv)(struct opal_dev *ctx, u16 spsp, u8 secp,
40 void *buffer, size_t len, bool send);
41
42
43enum opal_atom_width {
44 OPAL_WIDTH_TINY,
45 OPAL_WIDTH_SHORT,
46 OPAL_WIDTH_MEDIUM,
47 OPAL_WIDTH_LONG,
48 OPAL_WIDTH_TOKEN
49};
50
51/*
52 * Token defs derived from:
53 * TCG_Storage_Architecture_Core_Spec_v2.01_r1.00
54 * 3.2.2 Data Stream Encoding
55 */
56enum opal_response_token {
57 OPAL_DTA_TOKENID_BYTESTRING = 0xe0,
58 OPAL_DTA_TOKENID_SINT = 0xe1,
59 OPAL_DTA_TOKENID_UINT = 0xe2,
60 OPAL_DTA_TOKENID_TOKEN = 0xe3, /* actual token is returned */
61 OPAL_DTA_TOKENID_INVALID = 0X0
62};
63
64/*
65 * On the parsed response, we don't store again the toks that are already
66 * stored in the response buffer. Instead, for each token, we just store a
67 * pointer to the position in the buffer where the token starts, and the size
68 * of the token in bytes.
69 */
70struct opal_resp_tok {
71 const u8 *pos;
72 size_t len;
73 enum opal_response_token type;
74 enum opal_atom_width width;
75 union {
76 u64 u;
77 s64 s;
78 } stored;
79};
80
81/*
82 * From the response header it's not possible to know how many tokens there are
83 * on the payload. So we hardcode that the maximum will be MAX_TOKS, and later
84 * if we start dealing with messages that have more than that, we can increase
85 * this number. This is done to avoid having to make two passes through the
86 * response, the first one counting how many tokens we have and the second one
87 * actually storing the positions.
88 */
89struct parsed_resp {
90 int num;
91 struct opal_resp_tok toks[MAX_TOKS];
92};
93
94/**
95 * struct opal_dev - The structure representing a OPAL enabled SED.
96 * @supported: Whether or not OPAL is supported on this controller.
97 * @send_recv: The combined sec_send/sec_recv function pointer.
98 * @opal_step: A series of opal methods that are necessary to complete a command.
99 * @func_data: An array of parameters for the opal methods above.
100 * @state: Describes the current opal_step we're working on.
101 * @dev_lock: Locks the entire opal_dev structure.
102 * @parsed: Parsed response from controller.
103 * @prev_data: Data returned from a method to the controller.
104 * @unlk_lst: A list of Locking ranges to unlock on this device during a resume.
105 */
106struct opal_dev {
107 bool initialized;
108 bool supported;
109 sec_send_recv *send_recv;
110
111 const opal_step *funcs;
112 void **func_data;
113 int state;
114 struct mutex dev_lock;
115 u16 comid;
116 u32 hsn;
117 u32 tsn;
118 u64 align;
119 u64 lowest_lba;
120
121 size_t pos;
122 u8 cmd[IO_BUFFER_LENGTH];
123 u8 resp[IO_BUFFER_LENGTH];
124
125 struct parsed_resp parsed;
126 size_t prev_d_len;
127 void *prev_data;
128
129 struct list_head unlk_lst;
130};
131 28
132#ifdef CONFIG_BLK_SED_OPAL 29#ifdef CONFIG_BLK_SED_OPAL
133bool opal_unlock_from_suspend(struct opal_dev *dev); 30bool opal_unlock_from_suspend(struct opal_dev *dev);
134void init_opal_dev(struct opal_dev *opal_dev, sec_send_recv *send_recv); 31struct opal_dev *init_opal_dev(void *data, sec_send_recv *send_recv);
135int sed_ioctl(struct opal_dev *dev, unsigned int cmd, void __user *ioctl_ptr); 32int sed_ioctl(struct opal_dev *dev, unsigned int cmd, void __user *ioctl_ptr);
136 33
137static inline bool is_sed_ioctl(unsigned int cmd) 34static inline bool is_sed_ioctl(unsigned int cmd)
@@ -168,11 +65,6 @@ static inline bool opal_unlock_from_suspend(struct opal_dev *dev)
168{ 65{
169 return false; 66 return false;
170} 67}
171static inline void init_opal_dev(struct opal_dev *opal_dev, 68#define init_opal_dev(data, send_recv) NULL
172 sec_send_recv *send_recv)
173{
174 opal_dev->supported = false;
175 opal_dev->initialized = true;
176}
177#endif /* CONFIG_BLK_SED_OPAL */ 69#endif /* CONFIG_BLK_SED_OPAL */
178#endif /* LINUX_OPAL_H */ 70#endif /* LINUX_OPAL_H */