lsm: cleanup the size counters in security_getselfattr()
[linux-2.6-block.git] / block / sed-opal.c
CommitLineData
8c16567d 1// SPDX-License-Identifier: GPL-2.0
455a7b23
SB
2/*
3 * Copyright © 2016 Intel Corporation
4 *
5 * Authors:
6 * Scott Bauer <scott.bauer@intel.com>
7 * Rafael Antognolli <rafael.antognolli@intel.com>
455a7b23
SB
8 */
9
10#define pr_fmt(fmt) KBUILD_MODNAME ":OPAL: " fmt
11
12#include <linux/delay.h>
13#include <linux/device.h>
14#include <linux/kernel.h>
15#include <linux/list.h>
322cbb50 16#include <linux/blkdev.h>
455a7b23
SB
17#include <linux/slab.h>
18#include <linux/uaccess.h>
19#include <uapi/linux/sed-opal.h>
20#include <linux/sed-opal.h>
5dd33972 21#include <linux/sed-opal-key.h>
455a7b23
SB
22#include <linux/string.h>
23#include <linux/kdev_t.h>
3bfeb612
GJ
24#include <linux/key.h>
25#include <linux/key-type.h>
26#include <keys/user-type.h>
455a7b23
SB
27
28#include "opal_proto.h"
29
4f1244c8
CH
30#define IO_BUFFER_LENGTH 2048
31#define MAX_TOKS 64
32
a9b25b4c
JR
33/* Number of bytes needed by cmd_finalize. */
34#define CMD_FINALIZE_BYTES_NEEDED 7
35
3bfeb612
GJ
36static struct key *sed_opal_keyring;
37
eed64951
JD
38struct opal_step {
39 int (*fn)(struct opal_dev *dev, void *data);
40 void *data;
41};
42typedef int (cont_fn)(struct opal_dev *dev);
4f1244c8
CH
43
44enum opal_atom_width {
45 OPAL_WIDTH_TINY,
46 OPAL_WIDTH_SHORT,
47 OPAL_WIDTH_MEDIUM,
48 OPAL_WIDTH_LONG,
49 OPAL_WIDTH_TOKEN
50};
51
52/*
53 * On the parsed response, we don't store again the toks that are already
54 * stored in the response buffer. Instead, for each token, we just store a
55 * pointer to the position in the buffer where the token starts, and the size
56 * of the token in bytes.
57 */
58struct opal_resp_tok {
59 const u8 *pos;
60 size_t len;
61 enum opal_response_token type;
62 enum opal_atom_width width;
63 union {
64 u64 u;
65 s64 s;
66 } stored;
67};
68
69/*
70 * From the response header it's not possible to know how many tokens there are
71 * on the payload. So we hardcode that the maximum will be MAX_TOKS, and later
72 * if we start dealing with messages that have more than that, we can increase
73 * this number. This is done to avoid having to make two passes through the
74 * response, the first one counting how many tokens we have and the second one
75 * actually storing the positions.
76 */
77struct parsed_resp {
78 int num;
79 struct opal_resp_tok toks[MAX_TOKS];
80};
81
82struct opal_dev {
c6ea7060 83 u32 flags;
4f1244c8
CH
84
85 void *data;
86 sec_send_recv *send_recv;
87
4f1244c8
CH
88 struct mutex dev_lock;
89 u16 comid;
90 u32 hsn;
91 u32 tsn;
9e05a259 92 u64 align; /* alignment granularity */
4f1244c8 93 u64 lowest_lba;
9e05a259
OK
94 u32 logical_block_size;
95 u8 align_required; /* ALIGN: 0 or 1 */
4f1244c8
CH
96
97 size_t pos;
f829230d
SS
98 u8 *cmd;
99 u8 *resp;
4f1244c8
CH
100
101 struct parsed_resp parsed;
102 size_t prev_d_len;
103 void *prev_data;
104
105 struct list_head unlk_lst;
106};
107
108
455a7b23
SB
109static const u8 opaluid[][OPAL_UID_LENGTH] = {
110 /* users */
111 [OPAL_SMUID_UID] =
112 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff },
113 [OPAL_THISSP_UID] =
114 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
115 [OPAL_ADMINSP_UID] =
116 { 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x00, 0x01 },
117 [OPAL_LOCKINGSP_UID] =
118 { 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x00, 0x02 },
119 [OPAL_ENTERPRISE_LOCKINGSP_UID] =
120 { 0x00, 0x00, 0x02, 0x05, 0x00, 0x01, 0x00, 0x01 },
121 [OPAL_ANYBODY_UID] =
122 { 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x01 },
123 [OPAL_SID_UID] =
124 { 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x06 },
125 [OPAL_ADMIN1_UID] =
126 { 0x00, 0x00, 0x00, 0x09, 0x00, 0x01, 0x00, 0x01 },
127 [OPAL_USER1_UID] =
128 { 0x00, 0x00, 0x00, 0x09, 0x00, 0x03, 0x00, 0x01 },
129 [OPAL_USER2_UID] =
130 { 0x00, 0x00, 0x00, 0x09, 0x00, 0x03, 0x00, 0x02 },
131 [OPAL_PSID_UID] =
132 { 0x00, 0x00, 0x00, 0x09, 0x00, 0x01, 0xff, 0x01 },
133 [OPAL_ENTERPRISE_BANDMASTER0_UID] =
134 { 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x80, 0x01 },
135 [OPAL_ENTERPRISE_ERASEMASTER_UID] =
136 { 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x84, 0x01 },
137
138 /* tables */
dc301025 139 [OPAL_TABLE_TABLE] =
ff91064e 140 { 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01 },
455a7b23
SB
141 [OPAL_LOCKINGRANGE_GLOBAL] =
142 { 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x00, 0x01 },
8be19a02
OK
143 [OPAL_LOCKINGRANGE_ACE_START_TO_KEY] =
144 { 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0xD0, 0x01 },
455a7b23
SB
145 [OPAL_LOCKINGRANGE_ACE_RDLOCKED] =
146 { 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0xE0, 0x01 },
147 [OPAL_LOCKINGRANGE_ACE_WRLOCKED] =
148 { 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0xE8, 0x01 },
149 [OPAL_MBRCONTROL] =
150 { 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x00, 0x01 },
151 [OPAL_MBR] =
152 { 0x00, 0x00, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00 },
153 [OPAL_AUTHORITY_TABLE] =
154 { 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00},
155 [OPAL_C_PIN_TABLE] =
156 { 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00},
157 [OPAL_LOCKING_INFO_TABLE] =
158 { 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x01 },
159 [OPAL_ENTERPRISE_LOCKING_INFO_TABLE] =
160 { 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00 },
62c441c6
RR
161 [OPAL_DATASTORE] =
162 { 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x00, 0x00 },
455a7b23
SB
163
164 /* C_PIN_TABLE object ID's */
1e815b33 165 [OPAL_C_PIN_MSID] =
455a7b23
SB
166 { 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x84, 0x02},
167 [OPAL_C_PIN_SID] =
168 { 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x01},
169 [OPAL_C_PIN_ADMIN1] =
170 { 0x00, 0x00, 0x00, 0x0B, 0x00, 0x01, 0x00, 0x01},
171
172 /* half UID's (only first 4 bytes used) */
455a7b23
SB
173 [OPAL_HALF_UID_AUTHORITY_OBJ_REF] =
174 { 0x00, 0x00, 0x0C, 0x05, 0xff, 0xff, 0xff, 0xff },
175 [OPAL_HALF_UID_BOOLEAN_ACE] =
176 { 0x00, 0x00, 0x04, 0x0E, 0xff, 0xff, 0xff, 0xff },
177
178 /* special value for omitted optional parameter */
179 [OPAL_UID_HEXFF] =
180 { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
181};
182
183/*
184 * TCG Storage SSC Methods.
185 * Derived from: TCG_Storage_Architecture_Core_Spec_v2.01_r1.00
186 * Section: 6.3 Assigned UIDs
187 */
1b6b75b0 188static const u8 opalmethod[][OPAL_METHOD_LENGTH] = {
455a7b23
SB
189 [OPAL_PROPERTIES] =
190 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x01 },
191 [OPAL_STARTSESSION] =
192 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x02 },
193 [OPAL_REVERT] =
194 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x02, 0x02 },
195 [OPAL_ACTIVATE] =
196 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x02, 0x03 },
197 [OPAL_EGET] =
198 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06 },
199 [OPAL_ESET] =
200 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07 },
201 [OPAL_NEXT] =
202 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08 },
203 [OPAL_EAUTHENTICATE] =
204 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0c },
205 [OPAL_GETACL] =
206 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0d },
207 [OPAL_GENKEY] =
208 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x10 },
209 [OPAL_REVERTSP] =
210 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x11 },
211 [OPAL_GET] =
212 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x16 },
213 [OPAL_SET] =
214 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x17 },
215 [OPAL_AUTHENTICATE] =
216 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x1c },
217 [OPAL_RANDOM] =
218 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x01 },
219 [OPAL_ERASE] =
220 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x08, 0x03 },
221};
222
455a7b23 223static int end_opal_session_error(struct opal_dev *dev);
0af2648e 224static int opal_discovery0_step(struct opal_dev *dev);
455a7b23
SB
225
226struct opal_suspend_data {
227 struct opal_lock_unlock unlk;
228 u8 lr;
229 struct list_head node;
230};
231
232/*
233 * Derived from:
234 * TCG_Storage_Architecture_Core_Spec_v2.01_r1.00
235 * Section: 5.1.5 Method Status Codes
236 */
237static const char * const opal_errors[] = {
238 "Success",
239 "Not Authorized",
240 "Unknown Error",
241 "SP Busy",
242 "SP Failed",
243 "SP Disabled",
244 "SP Frozen",
245 "No Sessions Available",
246 "Uniqueness Conflict",
247 "Insufficient Space",
248 "Insufficient Rows",
249 "Invalid Function",
250 "Invalid Parameter",
251 "Invalid Reference",
252 "Unknown Error",
253 "TPER Malfunction",
254 "Transaction Failure",
255 "Response Overflow",
256 "Authority Locked Out",
257};
258
259static const char *opal_error_to_human(int error)
260{
261 if (error == 0x3f)
262 return "Failed";
263
264 if (error >= ARRAY_SIZE(opal_errors) || error < 0)
265 return "Unknown Error";
266
267 return opal_errors[error];
268}
269
270static void print_buffer(const u8 *ptr, u32 length)
271{
272#ifdef DEBUG
273 print_hex_dump_bytes("OPAL: ", DUMP_PREFIX_OFFSET, ptr, length);
274 pr_debug("\n");
275#endif
276}
277
3bfeb612
GJ
278/*
279 * Allocate/update a SED Opal key and add it to the SED Opal keyring.
280 */
281static int update_sed_opal_key(const char *desc, u_char *key_data, int keylen)
282{
283 key_ref_t kr;
284
285 if (!sed_opal_keyring)
286 return -ENOKEY;
287
288 kr = key_create_or_update(make_key_ref(sed_opal_keyring, true), "user",
289 desc, (const void *)key_data, keylen,
290 KEY_USR_VIEW | KEY_USR_SEARCH | KEY_USR_WRITE,
291 KEY_ALLOC_NOT_IN_QUOTA | KEY_ALLOC_BUILT_IN |
292 KEY_ALLOC_BYPASS_RESTRICTION);
293 if (IS_ERR(kr)) {
294 pr_err("Error adding SED key (%ld)\n", PTR_ERR(kr));
295 return PTR_ERR(kr);
296 }
297
298 return 0;
299}
300
301/*
302 * Read a SED Opal key from the SED Opal keyring.
303 */
304static int read_sed_opal_key(const char *key_name, u_char *buffer, int buflen)
305{
306 int ret;
307 key_ref_t kref;
308 struct key *key;
309
310 if (!sed_opal_keyring)
311 return -ENOKEY;
312
313 kref = keyring_search(make_key_ref(sed_opal_keyring, true),
314 &key_type_user, key_name, true);
315
316 if (IS_ERR(kref))
317 ret = PTR_ERR(kref);
318
319 key = key_ref_to_ptr(kref);
320 down_read(&key->sem);
321 ret = key_validate(key);
322 if (ret == 0) {
323 if (buflen > key->datalen)
324 buflen = key->datalen;
325
326 ret = key->type->read(key, (char *)buffer, buflen);
327 }
328 up_read(&key->sem);
329
330 key_ref_put(kref);
331
332 return ret;
333}
334
335static int opal_get_key(struct opal_dev *dev, struct opal_key *key)
336{
337 int ret = 0;
338
339 switch (key->key_type) {
340 case OPAL_INCLUDED:
341 /* the key is ready to use */
342 break;
343 case OPAL_KEYRING:
344 /* the key is in the keyring */
345 ret = read_sed_opal_key(OPAL_AUTH_KEY, key->key, OPAL_KEY_MAX);
346 if (ret > 0) {
347 if (ret > U8_MAX) {
348 ret = -ENOSPC;
349 goto error;
350 }
351 key->key_len = ret;
352 key->key_type = OPAL_INCLUDED;
353 }
354 break;
355 default:
356 ret = -EINVAL;
357 break;
358 }
359 if (ret < 0)
360 goto error;
361
362 /* must have a PEK by now or it's an error */
363 if (key->key_type != OPAL_INCLUDED || key->key_len == 0) {
364 ret = -EINVAL;
365 goto error;
366 }
367 return 0;
368error:
369 pr_debug("Error getting password: %d\n", ret);
370 return ret;
371}
372
455a7b23
SB
373static bool check_tper(const void *data)
374{
375 const struct d0_tper_features *tper = data;
376 u8 flags = tper->supported_features;
377
378 if (!(flags & TPER_SYNC_SUPPORTED)) {
591c59d1
SB
379 pr_debug("TPer sync not supported. flags = %d\n",
380 tper->supported_features);
455a7b23
SB
381 return false;
382 }
383
384 return true;
385}
386
c6ea7060 387static bool check_lcksuppt(const void *data)
388{
389 const struct d0_locking_features *lfeat = data;
390 u8 sup_feat = lfeat->supported_features;
391
392 return !!(sup_feat & LOCKING_SUPPORTED_MASK);
393}
394
395static bool check_lckenabled(const void *data)
396{
397 const struct d0_locking_features *lfeat = data;
398 u8 sup_feat = lfeat->supported_features;
399
400 return !!(sup_feat & LOCKING_ENABLED_MASK);
401}
402
403static bool check_locked(const void *data)
404{
405 const struct d0_locking_features *lfeat = data;
406 u8 sup_feat = lfeat->supported_features;
407
408 return !!(sup_feat & LOCKED_MASK);
409}
410
dbec491b
SB
411static bool check_mbrenabled(const void *data)
412{
413 const struct d0_locking_features *lfeat = data;
414 u8 sup_feat = lfeat->supported_features;
415
416 return !!(sup_feat & MBR_ENABLED_MASK);
417}
418
c6ea7060 419static bool check_mbrdone(const void *data)
420{
421 const struct d0_locking_features *lfeat = data;
422 u8 sup_feat = lfeat->supported_features;
423
424 return !!(sup_feat & MBR_DONE_MASK);
425}
426
455a7b23
SB
427static bool check_sum(const void *data)
428{
429 const struct d0_single_user_mode *sum = data;
430 u32 nlo = be32_to_cpu(sum->num_locking_objects);
431
432 if (nlo == 0) {
591c59d1 433 pr_debug("Need at least one locking object.\n");
455a7b23
SB
434 return false;
435 }
436
437 pr_debug("Number of locking objects: %d\n", nlo);
438
439 return true;
440}
441
442static u16 get_comid_v100(const void *data)
443{
444 const struct d0_opal_v100 *v100 = data;
445
446 return be16_to_cpu(v100->baseComID);
447}
448
449static u16 get_comid_v200(const void *data)
450{
451 const struct d0_opal_v200 *v200 = data;
452
453 return be16_to_cpu(v200->baseComID);
454}
455
456static int opal_send_cmd(struct opal_dev *dev)
457{
4f1244c8 458 return dev->send_recv(dev->data, dev->comid, TCG_SECP_01,
455a7b23
SB
459 dev->cmd, IO_BUFFER_LENGTH,
460 true);
461}
462
463static int opal_recv_cmd(struct opal_dev *dev)
464{
4f1244c8 465 return dev->send_recv(dev->data, dev->comid, TCG_SECP_01,
455a7b23
SB
466 dev->resp, IO_BUFFER_LENGTH,
467 false);
468}
469
470static int opal_recv_check(struct opal_dev *dev)
471{
472 size_t buflen = IO_BUFFER_LENGTH;
473 void *buffer = dev->resp;
474 struct opal_header *hdr = buffer;
475 int ret;
476
477 do {
478 pr_debug("Sent OPAL command: outstanding=%d, minTransfer=%d\n",
479 hdr->cp.outstandingData,
480 hdr->cp.minTransfer);
481
482 if (hdr->cp.outstandingData == 0 ||
483 hdr->cp.minTransfer != 0)
484 return 0;
485
486 memset(buffer, 0, buflen);
487 ret = opal_recv_cmd(dev);
488 } while (!ret);
489
490 return ret;
491}
492
493static int opal_send_recv(struct opal_dev *dev, cont_fn *cont)
494{
495 int ret;
496
497 ret = opal_send_cmd(dev);
498 if (ret)
499 return ret;
500 ret = opal_recv_cmd(dev);
501 if (ret)
502 return ret;
503 ret = opal_recv_check(dev);
504 if (ret)
505 return ret;
506 return cont(dev);
507}
508
509static void check_geometry(struct opal_dev *dev, const void *data)
510{
511 const struct d0_geometry_features *geo = data;
512
a9eb49c9
RD
513 dev->align = be64_to_cpu(geo->alignment_granularity);
514 dev->lowest_lba = be64_to_cpu(geo->lowest_aligned_lba);
9e05a259
OK
515 dev->logical_block_size = be32_to_cpu(geo->logical_block_size);
516 dev->align_required = geo->reserved01 & 1;
455a7b23
SB
517}
518
0af2648e
DK
519static int execute_step(struct opal_dev *dev,
520 const struct opal_step *step, size_t stepIndex)
521{
522 int error = step->fn(dev, step->data);
523
524 if (error) {
525 pr_debug("Step %zu (%pS) failed with error %d: %s\n",
526 stepIndex, step->fn, error,
527 opal_error_to_human(error));
528 }
529
530 return error;
531}
532
a80f36cc
DK
533static int execute_steps(struct opal_dev *dev,
534 const struct opal_step *steps, size_t n_steps)
455a7b23 535{
0af2648e
DK
536 size_t state = 0;
537 int error;
455a7b23 538
0af2648e
DK
539 /* first do a discovery0 */
540 error = opal_discovery0_step(dev);
541 if (error)
542 return error;
455a7b23 543
0af2648e
DK
544 for (state = 0; state < n_steps; state++) {
545 error = execute_step(dev, &steps[state], state);
3db87236
DK
546 if (error)
547 goto out_error;
548 }
2d19020b 549
3db87236
DK
550 return 0;
551
552out_error:
553 /*
0af2648e
DK
554 * For each OPAL command the first step in steps starts some sort of
555 * session. If an error occurred in the initial discovery0 or if an
556 * error occurred in the first step (and thus stopping the loop with
557 * state == 0) then there was an error before or during the attempt to
558 * start a session. Therefore we shouldn't attempt to terminate a
559 * session, as one has not yet been created.
3db87236 560 */
0af2648e 561 if (state > 0)
3db87236 562 end_opal_session_error(dev);
455a7b23
SB
563
564 return error;
565}
566
9fb10726 567static int opal_discovery0_end(struct opal_dev *dev, void *data)
455a7b23 568{
9fb10726
GJ
569 struct opal_discovery *discv_out = data; /* may be NULL */
570 u8 __user *buf_out;
571 u64 len_out;
455a7b23
SB
572 bool found_com_id = false, supported = true, single_user = false;
573 const struct d0_header *hdr = (struct d0_header *)dev->resp;
574 const u8 *epos = dev->resp, *cpos = dev->resp;
575 u16 comid = 0;
77039b96 576 u32 hlen = be32_to_cpu(hdr->length);
455a7b23 577
77039b96 578 print_buffer(dev->resp, hlen);
c6ea7060 579 dev->flags &= OPAL_FL_SUPPORTED;
455a7b23 580
77039b96 581 if (hlen > IO_BUFFER_LENGTH - sizeof(*hdr)) {
591c59d1
SB
582 pr_debug("Discovery length overflows buffer (%zu+%u)/%u\n",
583 sizeof(*hdr), hlen, IO_BUFFER_LENGTH);
77039b96
JD
584 return -EFAULT;
585 }
586
9fb10726
GJ
587 if (discv_out) {
588 buf_out = (u8 __user *)(uintptr_t)discv_out->data;
589 len_out = min_t(u64, discv_out->size, hlen);
590 if (buf_out && copy_to_user(buf_out, dev->resp, len_out))
591 return -EFAULT;
592
593 discv_out->size = hlen; /* actual size of data */
594 }
595
77039b96 596 epos += hlen; /* end of buffer */
455a7b23
SB
597 cpos += sizeof(*hdr); /* current position on buffer */
598
599 while (cpos < epos && supported) {
600 const struct d0_features *body =
601 (const struct d0_features *)cpos;
602
603 switch (be16_to_cpu(body->code)) {
604 case FC_TPER:
605 supported = check_tper(body->features);
606 break;
607 case FC_SINGLEUSER:
608 single_user = check_sum(body->features);
9ec041ea
LB
609 if (single_user)
610 dev->flags |= OPAL_FL_SUM_SUPPORTED;
455a7b23
SB
611 break;
612 case FC_GEOMETRY:
613 check_geometry(dev, body);
614 break;
615 case FC_LOCKING:
c6ea7060 616 if (check_lcksuppt(body->features))
617 dev->flags |= OPAL_FL_LOCKING_SUPPORTED;
618 if (check_lckenabled(body->features))
619 dev->flags |= OPAL_FL_LOCKING_ENABLED;
620 if (check_locked(body->features))
621 dev->flags |= OPAL_FL_LOCKED;
622 if (check_mbrenabled(body->features))
623 dev->flags |= OPAL_FL_MBR_ENABLED;
624 if (check_mbrdone(body->features))
625 dev->flags |= OPAL_FL_MBR_DONE;
dbec491b 626 break;
455a7b23
SB
627 case FC_ENTERPRISE:
628 case FC_DATASTORE:
629 /* some ignored properties */
630 pr_debug("Found OPAL feature description: %d\n",
631 be16_to_cpu(body->code));
632 break;
633 case FC_OPALV100:
634 comid = get_comid_v100(body->features);
635 found_com_id = true;
636 break;
637 case FC_OPALV200:
638 comid = get_comid_v200(body->features);
639 found_com_id = true;
640 break;
641 case 0xbfff ... 0xffff:
642 /* vendor specific, just ignore */
643 break;
644 default:
645 pr_debug("OPAL Unknown feature: %d\n",
646 be16_to_cpu(body->code));
647
648 }
649 cpos += body->length + 4;
650 }
651
652 if (!supported) {
f5b37b7c 653 pr_debug("This device is not Opal enabled. Not Supported!\n");
455a7b23
SB
654 return -EOPNOTSUPP;
655 }
656
657 if (!single_user)
f5b37b7c 658 pr_debug("Device doesn't support single user mode\n");
455a7b23
SB
659
660
661 if (!found_com_id) {
f5b37b7c 662 pr_debug("Could not find OPAL comid for device. Returning early\n");
ed7158ba 663 return -EOPNOTSUPP;
455a7b23
SB
664 }
665
666 dev->comid = comid;
667
668 return 0;
669}
670
eed64951 671static int opal_discovery0(struct opal_dev *dev, void *data)
455a7b23
SB
672{
673 int ret;
674
675 memset(dev->resp, 0, IO_BUFFER_LENGTH);
676 dev->comid = OPAL_DISCOVERY_COMID;
677 ret = opal_recv_cmd(dev);
678 if (ret)
679 return ret;
5cc23ed7 680
9fb10726 681 return opal_discovery0_end(dev, data);
455a7b23
SB
682}
683
0af2648e
DK
684static int opal_discovery0_step(struct opal_dev *dev)
685{
686 const struct opal_step discovery0_step = {
9fb10726 687 opal_discovery0, NULL
0af2648e 688 };
5cc23ed7 689
0af2648e
DK
690 return execute_step(dev, &discovery0_step, 0);
691}
692
a9b25b4c
JR
693static size_t remaining_size(struct opal_dev *cmd)
694{
695 return IO_BUFFER_LENGTH - cmd->pos;
696}
697
e2821a50 698static bool can_add(int *err, struct opal_dev *cmd, size_t len)
455a7b23
SB
699{
700 if (*err)
e2821a50
JR
701 return false;
702
a9b25b4c 703 if (remaining_size(cmd) < len) {
e2821a50 704 pr_debug("Error adding %zu bytes: end of buffer.\n", len);
455a7b23 705 *err = -ERANGE;
e2821a50 706 return false;
455a7b23 707 }
e2821a50
JR
708
709 return true;
710}
711
712static void add_token_u8(int *err, struct opal_dev *cmd, u8 tok)
713{
714 if (!can_add(err, cmd, 1))
715 return;
5cc23ed7 716
455a7b23
SB
717 cmd->cmd[cmd->pos++] = tok;
718}
719
720static void add_short_atom_header(struct opal_dev *cmd, bool bytestring,
721 bool has_sign, int len)
722{
723 u8 atom;
724 int err = 0;
725
726 atom = SHORT_ATOM_ID;
727 atom |= bytestring ? SHORT_ATOM_BYTESTRING : 0;
728 atom |= has_sign ? SHORT_ATOM_SIGNED : 0;
729 atom |= len & SHORT_ATOM_LEN_MASK;
730
731 add_token_u8(&err, cmd, atom);
732}
733
734static void add_medium_atom_header(struct opal_dev *cmd, bool bytestring,
735 bool has_sign, int len)
736{
737 u8 header0;
738
739 header0 = MEDIUM_ATOM_ID;
740 header0 |= bytestring ? MEDIUM_ATOM_BYTESTRING : 0;
741 header0 |= has_sign ? MEDIUM_ATOM_SIGNED : 0;
742 header0 |= (len >> 8) & MEDIUM_ATOM_LEN_MASK;
5cc23ed7 743
455a7b23
SB
744 cmd->cmd[cmd->pos++] = header0;
745 cmd->cmd[cmd->pos++] = len;
746}
747
748static void add_token_u64(int *err, struct opal_dev *cmd, u64 number)
749{
455a7b23
SB
750 size_t len;
751 int msb;
455a7b23
SB
752
753 if (!(number & ~TINY_ATOM_DATA_MASK)) {
754 add_token_u8(err, cmd, number);
755 return;
756 }
757
5f990d31
JR
758 msb = fls64(number);
759 len = DIV_ROUND_UP(msb, 8);
455a7b23 760
e2821a50 761 if (!can_add(err, cmd, len + 1)) {
591c59d1 762 pr_debug("Error adding u64: end of buffer.\n");
455a7b23
SB
763 return;
764 }
765 add_short_atom_header(cmd, false, false, len);
5f990d31
JR
766 while (len--)
767 add_token_u8(err, cmd, number >> (len * 8));
455a7b23
SB
768}
769
28559959 770static u8 *add_bytestring_header(int *err, struct opal_dev *cmd, size_t len)
455a7b23
SB
771{
772 size_t header_len = 1;
773 bool is_short_atom = true;
774
455a7b23
SB
775 if (len & ~SHORT_ATOM_LEN_MASK) {
776 header_len = 2;
777 is_short_atom = false;
778 }
779
e2821a50 780 if (!can_add(err, cmd, header_len + len)) {
591c59d1 781 pr_debug("Error adding bytestring: end of buffer.\n");
28559959 782 return NULL;
455a7b23
SB
783 }
784
785 if (is_short_atom)
786 add_short_atom_header(cmd, true, false, len);
787 else
788 add_medium_atom_header(cmd, true, false, len);
789
28559959
JR
790 return &cmd->cmd[cmd->pos];
791}
455a7b23 792
28559959
JR
793static void add_token_bytestring(int *err, struct opal_dev *cmd,
794 const u8 *bytestring, size_t len)
795{
796 u8 *start;
797
798 start = add_bytestring_header(err, cmd, len);
799 if (!start)
800 return;
801 memcpy(start, bytestring, len);
802 cmd->pos += len;
455a7b23
SB
803}
804
805static int build_locking_range(u8 *buffer, size_t length, u8 lr)
806{
807 if (length > OPAL_UID_LENGTH) {
591c59d1 808 pr_debug("Can't build locking range. Length OOB\n");
455a7b23
SB
809 return -ERANGE;
810 }
811
812 memcpy(buffer, opaluid[OPAL_LOCKINGRANGE_GLOBAL], OPAL_UID_LENGTH);
813
814 if (lr == 0)
815 return 0;
5cc23ed7 816
455a7b23
SB
817 buffer[5] = LOCKING_RANGE_NON_GLOBAL;
818 buffer[7] = lr;
819
820 return 0;
821}
822
823static int build_locking_user(u8 *buffer, size_t length, u8 lr)
824{
825 if (length > OPAL_UID_LENGTH) {
1e815b33 826 pr_debug("Can't build locking range user. Length OOB\n");
455a7b23
SB
827 return -ERANGE;
828 }
829
830 memcpy(buffer, opaluid[OPAL_USER1_UID], OPAL_UID_LENGTH);
831
832 buffer[7] = lr + 1;
833
834 return 0;
835}
836
837static void set_comid(struct opal_dev *cmd, u16 comid)
838{
839 struct opal_header *hdr = (struct opal_header *)cmd->cmd;
840
841 hdr->cp.extendedComID[0] = comid >> 8;
842 hdr->cp.extendedComID[1] = comid;
843 hdr->cp.extendedComID[2] = 0;
844 hdr->cp.extendedComID[3] = 0;
845}
846
847static int cmd_finalize(struct opal_dev *cmd, u32 hsn, u32 tsn)
848{
849 struct opal_header *hdr;
850 int err = 0;
851
a9b25b4c
JR
852 /*
853 * Close the parameter list opened from cmd_start.
854 * The number of bytes added must be equal to
855 * CMD_FINALIZE_BYTES_NEEDED.
856 */
78d584ca
DK
857 add_token_u8(&err, cmd, OPAL_ENDLIST);
858
455a7b23
SB
859 add_token_u8(&err, cmd, OPAL_ENDOFDATA);
860 add_token_u8(&err, cmd, OPAL_STARTLIST);
861 add_token_u8(&err, cmd, 0);
862 add_token_u8(&err, cmd, 0);
863 add_token_u8(&err, cmd, 0);
864 add_token_u8(&err, cmd, OPAL_ENDLIST);
865
866 if (err) {
591c59d1 867 pr_debug("Error finalizing command.\n");
455a7b23
SB
868 return -EFAULT;
869 }
870
871 hdr = (struct opal_header *) cmd->cmd;
872
873 hdr->pkt.tsn = cpu_to_be32(tsn);
874 hdr->pkt.hsn = cpu_to_be32(hsn);
875
876 hdr->subpkt.length = cpu_to_be32(cmd->pos - sizeof(*hdr));
877 while (cmd->pos % 4) {
878 if (cmd->pos >= IO_BUFFER_LENGTH) {
591c59d1 879 pr_debug("Error: Buffer overrun\n");
455a7b23
SB
880 return -ERANGE;
881 }
882 cmd->cmd[cmd->pos++] = 0;
883 }
884 hdr->pkt.length = cpu_to_be32(cmd->pos - sizeof(hdr->cp) -
885 sizeof(hdr->pkt));
886 hdr->cp.length = cpu_to_be32(cmd->pos - sizeof(hdr->cp));
887
888 return 0;
889}
890
cccb9241
JD
891static const struct opal_resp_tok *response_get_token(
892 const struct parsed_resp *resp,
893 int n)
455a7b23
SB
894{
895 const struct opal_resp_tok *tok;
896
7d9b62ae
DK
897 if (!resp) {
898 pr_debug("Response is NULL\n");
899 return ERR_PTR(-EINVAL);
900 }
901
455a7b23 902 if (n >= resp->num) {
591c59d1
SB
903 pr_debug("Token number doesn't exist: %d, resp: %d\n",
904 n, resp->num);
cccb9241 905 return ERR_PTR(-EINVAL);
455a7b23
SB
906 }
907
908 tok = &resp->toks[n];
909 if (tok->len == 0) {
591c59d1 910 pr_debug("Token length must be non-zero\n");
cccb9241 911 return ERR_PTR(-EINVAL);
455a7b23
SB
912 }
913
cccb9241 914 return tok;
455a7b23
SB
915}
916
aedb6e24
JD
917static ssize_t response_parse_tiny(struct opal_resp_tok *tok,
918 const u8 *pos)
455a7b23
SB
919{
920 tok->pos = pos;
921 tok->len = 1;
922 tok->width = OPAL_WIDTH_TINY;
923
924 if (pos[0] & TINY_ATOM_SIGNED) {
925 tok->type = OPAL_DTA_TOKENID_SINT;
926 } else {
927 tok->type = OPAL_DTA_TOKENID_UINT;
928 tok->stored.u = pos[0] & 0x3f;
929 }
930
931 return tok->len;
932}
933
aedb6e24
JD
934static ssize_t response_parse_short(struct opal_resp_tok *tok,
935 const u8 *pos)
455a7b23
SB
936{
937 tok->pos = pos;
938 tok->len = (pos[0] & SHORT_ATOM_LEN_MASK) + 1;
939 tok->width = OPAL_WIDTH_SHORT;
940
941 if (pos[0] & SHORT_ATOM_BYTESTRING) {
942 tok->type = OPAL_DTA_TOKENID_BYTESTRING;
943 } else if (pos[0] & SHORT_ATOM_SIGNED) {
944 tok->type = OPAL_DTA_TOKENID_SINT;
945 } else {
946 u64 u_integer = 0;
aedb6e24 947 ssize_t i, b = 0;
455a7b23
SB
948
949 tok->type = OPAL_DTA_TOKENID_UINT;
950 if (tok->len > 9) {
591c59d1 951 pr_debug("uint64 with more than 8 bytes\n");
455a7b23
SB
952 return -EINVAL;
953 }
954 for (i = tok->len - 1; i > 0; i--) {
955 u_integer |= ((u64)pos[i] << (8 * b));
956 b++;
957 }
958 tok->stored.u = u_integer;
959 }
960
961 return tok->len;
962}
963
aedb6e24
JD
964static ssize_t response_parse_medium(struct opal_resp_tok *tok,
965 const u8 *pos)
455a7b23
SB
966{
967 tok->pos = pos;
968 tok->len = (((pos[0] & MEDIUM_ATOM_LEN_MASK) << 8) | pos[1]) + 2;
969 tok->width = OPAL_WIDTH_MEDIUM;
970
971 if (pos[0] & MEDIUM_ATOM_BYTESTRING)
972 tok->type = OPAL_DTA_TOKENID_BYTESTRING;
973 else if (pos[0] & MEDIUM_ATOM_SIGNED)
974 tok->type = OPAL_DTA_TOKENID_SINT;
975 else
976 tok->type = OPAL_DTA_TOKENID_UINT;
977
978 return tok->len;
979}
980
aedb6e24
JD
981static ssize_t response_parse_long(struct opal_resp_tok *tok,
982 const u8 *pos)
455a7b23
SB
983{
984 tok->pos = pos;
985 tok->len = ((pos[1] << 16) | (pos[2] << 8) | pos[3]) + 4;
986 tok->width = OPAL_WIDTH_LONG;
987
988 if (pos[0] & LONG_ATOM_BYTESTRING)
989 tok->type = OPAL_DTA_TOKENID_BYTESTRING;
990 else if (pos[0] & LONG_ATOM_SIGNED)
991 tok->type = OPAL_DTA_TOKENID_SINT;
992 else
993 tok->type = OPAL_DTA_TOKENID_UINT;
994
995 return tok->len;
996}
997
aedb6e24
JD
998static ssize_t response_parse_token(struct opal_resp_tok *tok,
999 const u8 *pos)
455a7b23
SB
1000{
1001 tok->pos = pos;
1002 tok->len = 1;
1003 tok->type = OPAL_DTA_TOKENID_TOKEN;
1004 tok->width = OPAL_WIDTH_TOKEN;
1005
1006 return tok->len;
1007}
1008
1009static int response_parse(const u8 *buf, size_t length,
1010 struct parsed_resp *resp)
1011{
1012 const struct opal_header *hdr;
1013 struct opal_resp_tok *iter;
1014 int num_entries = 0;
1015 int total;
aedb6e24 1016 ssize_t token_length;
455a7b23 1017 const u8 *pos;
77039b96 1018 u32 clen, plen, slen;
455a7b23
SB
1019
1020 if (!buf)
1021 return -EFAULT;
1022
1023 if (!resp)
1024 return -EFAULT;
1025
1026 hdr = (struct opal_header *)buf;
1027 pos = buf;
1028 pos += sizeof(*hdr);
1029
77039b96
JD
1030 clen = be32_to_cpu(hdr->cp.length);
1031 plen = be32_to_cpu(hdr->pkt.length);
1032 slen = be32_to_cpu(hdr->subpkt.length);
1033 pr_debug("Response size: cp: %u, pkt: %u, subpkt: %u\n",
1034 clen, plen, slen);
1035
1036 if (clen == 0 || plen == 0 || slen == 0 ||
1037 slen > IO_BUFFER_LENGTH - sizeof(*hdr)) {
591c59d1
SB
1038 pr_debug("Bad header length. cp: %u, pkt: %u, subpkt: %u\n",
1039 clen, plen, slen);
455a7b23
SB
1040 print_buffer(pos, sizeof(*hdr));
1041 return -EINVAL;
1042 }
1043
1044 if (pos > buf + length)
1045 return -EFAULT;
1046
1047 iter = resp->toks;
77039b96 1048 total = slen;
455a7b23
SB
1049 print_buffer(pos, total);
1050 while (total > 0) {
1051 if (pos[0] <= TINY_ATOM_BYTE) /* tiny atom */
1052 token_length = response_parse_tiny(iter, pos);
1053 else if (pos[0] <= SHORT_ATOM_BYTE) /* short atom */
1054 token_length = response_parse_short(iter, pos);
1055 else if (pos[0] <= MEDIUM_ATOM_BYTE) /* medium atom */
1056 token_length = response_parse_medium(iter, pos);
1057 else if (pos[0] <= LONG_ATOM_BYTE) /* long atom */
1058 token_length = response_parse_long(iter, pos);
1059 else /* TOKEN */
1060 token_length = response_parse_token(iter, pos);
1061
aedb6e24
JD
1062 if (token_length < 0)
1063 return token_length;
455a7b23
SB
1064
1065 pos += token_length;
1066 total -= token_length;
1067 iter++;
1068 num_entries++;
1069 }
1070
455a7b23
SB
1071 resp->num = num_entries;
1072
1073 return 0;
1074}
1075
1076static size_t response_get_string(const struct parsed_resp *resp, int n,
1077 const char **store)
1078{
d15e1175 1079 u8 skip;
b68f09ec 1080 const struct opal_resp_tok *tok;
d15e1175 1081
455a7b23 1082 *store = NULL;
b68f09ec
DK
1083 tok = response_get_token(resp, n);
1084 if (IS_ERR(tok))
455a7b23 1085 return 0;
455a7b23 1086
b68f09ec 1087 if (tok->type != OPAL_DTA_TOKENID_BYTESTRING) {
591c59d1 1088 pr_debug("Token is not a byte string!\n");
455a7b23
SB
1089 return 0;
1090 }
1091
b68f09ec 1092 switch (tok->width) {
d15e1175
JR
1093 case OPAL_WIDTH_TINY:
1094 case OPAL_WIDTH_SHORT:
1095 skip = 1;
1096 break;
1097 case OPAL_WIDTH_MEDIUM:
1098 skip = 2;
1099 break;
1100 case OPAL_WIDTH_LONG:
1101 skip = 4;
1102 break;
1103 default:
1104 pr_debug("Token has invalid width!\n");
1105 return 0;
1106 }
1107
b68f09ec 1108 *store = tok->pos + skip;
5cc23ed7 1109
b68f09ec 1110 return tok->len - skip;
455a7b23
SB
1111}
1112
1113static u64 response_get_u64(const struct parsed_resp *resp, int n)
1114{
b68f09ec 1115 const struct opal_resp_tok *tok;
455a7b23 1116
b68f09ec
DK
1117 tok = response_get_token(resp, n);
1118 if (IS_ERR(tok))
455a7b23 1119 return 0;
455a7b23 1120
b68f09ec
DK
1121 if (tok->type != OPAL_DTA_TOKENID_UINT) {
1122 pr_debug("Token is not unsigned int: %d\n", tok->type);
455a7b23
SB
1123 return 0;
1124 }
1125
b68f09ec
DK
1126 if (tok->width != OPAL_WIDTH_TINY && tok->width != OPAL_WIDTH_SHORT) {
1127 pr_debug("Atom is not short or tiny: %d\n", tok->width);
455a7b23
SB
1128 return 0;
1129 }
1130
b68f09ec 1131 return tok->stored.u;
455a7b23
SB
1132}
1133
cccb9241
JD
1134static bool response_token_matches(const struct opal_resp_tok *token, u8 match)
1135{
1136 if (IS_ERR(token) ||
1137 token->type != OPAL_DTA_TOKENID_TOKEN ||
1138 token->pos[0] != match)
1139 return false;
1140 return true;
1141}
1142
455a7b23
SB
1143static u8 response_status(const struct parsed_resp *resp)
1144{
cccb9241
JD
1145 const struct opal_resp_tok *tok;
1146
1147 tok = response_get_token(resp, 0);
1148 if (response_token_matches(tok, OPAL_ENDOFSESSION))
455a7b23 1149 return 0;
455a7b23
SB
1150
1151 if (resp->num < 5)
1152 return DTAERROR_NO_METHOD_STATUS;
1153
cccb9241
JD
1154 tok = response_get_token(resp, resp->num - 5);
1155 if (!response_token_matches(tok, OPAL_STARTLIST))
1156 return DTAERROR_NO_METHOD_STATUS;
1157
1158 tok = response_get_token(resp, resp->num - 1);
1159 if (!response_token_matches(tok, OPAL_ENDLIST))
455a7b23
SB
1160 return DTAERROR_NO_METHOD_STATUS;
1161
1162 return response_get_u64(resp, resp->num - 4);
1163}
1164
1165/* Parses and checks for errors */
1166static int parse_and_check_status(struct opal_dev *dev)
1167{
1168 int error;
1169
1170 print_buffer(dev->cmd, dev->pos);
1171
1172 error = response_parse(dev->resp, IO_BUFFER_LENGTH, &dev->parsed);
1173 if (error) {
591c59d1 1174 pr_debug("Couldn't parse response.\n");
455a7b23
SB
1175 return error;
1176 }
1177
1178 return response_status(&dev->parsed);
1179}
1180
1181static void clear_opal_cmd(struct opal_dev *dev)
1182{
1183 dev->pos = sizeof(struct opal_header);
1184 memset(dev->cmd, 0, IO_BUFFER_LENGTH);
1185}
1186
e8b29224
DK
1187static int cmd_start(struct opal_dev *dev, const u8 *uid, const u8 *method)
1188{
1189 int err = 0;
1190
1191 clear_opal_cmd(dev);
1192 set_comid(dev, dev->comid);
1193
1194 add_token_u8(&err, dev, OPAL_CALL);
1195 add_token_bytestring(&err, dev, uid, OPAL_UID_LENGTH);
1196 add_token_bytestring(&err, dev, method, OPAL_METHOD_LENGTH);
1197
1198 /*
1199 * Every method call is followed by its parameters enclosed within
1200 * OPAL_STARTLIST and OPAL_ENDLIST tokens. We automatically open the
1201 * parameter list here and close it later in cmd_finalize.
1202 */
1203 add_token_u8(&err, dev, OPAL_STARTLIST);
1204
1205 return err;
1206}
1207
455a7b23
SB
1208static int start_opal_session_cont(struct opal_dev *dev)
1209{
1210 u32 hsn, tsn;
1211 int error = 0;
1212
1213 error = parse_and_check_status(dev);
1214 if (error)
1215 return error;
1216
1217 hsn = response_get_u64(&dev->parsed, 4);
1218 tsn = response_get_u64(&dev->parsed, 5);
1219
88d6041d 1220 if (hsn != GENERIC_HOST_SESSION_NUM || tsn < FIRST_TPER_SESSION_NUM) {
591c59d1 1221 pr_debug("Couldn't authenticate session\n");
455a7b23
SB
1222 return -EPERM;
1223 }
1224
1225 dev->hsn = hsn;
1226 dev->tsn = tsn;
5cc23ed7 1227
455a7b23
SB
1228 return 0;
1229}
1230
1231static void add_suspend_info(struct opal_dev *dev,
1232 struct opal_suspend_data *sus)
1233{
1234 struct opal_suspend_data *iter;
1235
1236 list_for_each_entry(iter, &dev->unlk_lst, node) {
1237 if (iter->lr == sus->lr) {
1238 list_del(&iter->node);
1239 kfree(iter);
1240 break;
1241 }
1242 }
1243 list_add_tail(&sus->node, &dev->unlk_lst);
1244}
1245
1246static int end_session_cont(struct opal_dev *dev)
1247{
1248 dev->hsn = 0;
1249 dev->tsn = 0;
5cc23ed7 1250
455a7b23
SB
1251 return parse_and_check_status(dev);
1252}
1253
1254static int finalize_and_send(struct opal_dev *dev, cont_fn cont)
1255{
1256 int ret;
1257
1258 ret = cmd_finalize(dev, dev->hsn, dev->tsn);
1259 if (ret) {
591c59d1 1260 pr_debug("Error finalizing command buffer: %d\n", ret);
455a7b23
SB
1261 return ret;
1262 }
1263
1264 print_buffer(dev->cmd, dev->pos);
1265
1266 return opal_send_recv(dev, cont);
1267}
1268
baf82b67
OK
1269static int generic_get_columns(struct opal_dev *dev, const u8 *table,
1270 u64 start_column, u64 end_column)
3fff234b
DK
1271{
1272 int err;
1273
1274 err = cmd_start(dev, table, opalmethod[OPAL_GET]);
1275
1276 add_token_u8(&err, dev, OPAL_STARTLIST);
1277
1278 add_token_u8(&err, dev, OPAL_STARTNAME);
1279 add_token_u8(&err, dev, OPAL_STARTCOLUMN);
baf82b67 1280 add_token_u64(&err, dev, start_column);
3fff234b
DK
1281 add_token_u8(&err, dev, OPAL_ENDNAME);
1282
1283 add_token_u8(&err, dev, OPAL_STARTNAME);
1284 add_token_u8(&err, dev, OPAL_ENDCOLUMN);
baf82b67 1285 add_token_u64(&err, dev, end_column);
3fff234b
DK
1286 add_token_u8(&err, dev, OPAL_ENDNAME);
1287
1288 add_token_u8(&err, dev, OPAL_ENDLIST);
1289
1290 if (err)
1291 return err;
1292
1293 return finalize_and_send(dev, parse_and_check_status);
1294}
1295
baf82b67
OK
1296/*
1297 * request @column from table @table on device @dev. On success, the column
1298 * data will be available in dev->resp->tok[4]
1299 */
1300static int generic_get_column(struct opal_dev *dev, const u8 *table,
1301 u64 column)
1302{
1303 return generic_get_columns(dev, table, column, column);
1304}
1305
ff91064e
JR
1306/*
1307 * see TCG SAS 5.3.2.3 for a description of the available columns
1308 *
1309 * the result is provided in dev->resp->tok[4]
1310 */
3495ea1b 1311static int generic_get_table_info(struct opal_dev *dev, const u8 *table_uid,
ff91064e
JR
1312 u64 column)
1313{
1314 u8 uid[OPAL_UID_LENGTH];
3495ea1b 1315 const unsigned int half = OPAL_UID_LENGTH_HALF;
ff91064e
JR
1316
1317 /* sed-opal UIDs can be split in two halves:
1318 * first: actual table index
1319 * second: relative index in the table
1320 * so we have to get the first half of the OPAL_TABLE_TABLE and use the
1321 * first part of the target table as relative index into that table
1322 */
1323 memcpy(uid, opaluid[OPAL_TABLE_TABLE], half);
3495ea1b 1324 memcpy(uid + half, table_uid, half);
ff91064e
JR
1325
1326 return generic_get_column(dev, uid, column);
1327}
1328
eed64951 1329static int gen_key(struct opal_dev *dev, void *data)
455a7b23 1330{
455a7b23 1331 u8 uid[OPAL_UID_LENGTH];
e8b29224 1332 int err;
455a7b23
SB
1333
1334 memcpy(uid, dev->prev_data, min(sizeof(uid), dev->prev_d_len));
455a7b23
SB
1335 kfree(dev->prev_data);
1336 dev->prev_data = NULL;
1337
e8b29224 1338 err = cmd_start(dev, uid, opalmethod[OPAL_GENKEY]);
455a7b23
SB
1339
1340 if (err) {
591c59d1 1341 pr_debug("Error building gen key command\n");
455a7b23
SB
1342 return err;
1343
1344 }
5cc23ed7 1345
455a7b23
SB
1346 return finalize_and_send(dev, parse_and_check_status);
1347}
1348
1349static int get_active_key_cont(struct opal_dev *dev)
1350{
1351 const char *activekey;
1352 size_t keylen;
1353 int error = 0;
1354
1355 error = parse_and_check_status(dev);
1356 if (error)
1357 return error;
5cc23ed7 1358
455a7b23
SB
1359 keylen = response_get_string(&dev->parsed, 4, &activekey);
1360 if (!activekey) {
591c59d1
SB
1361 pr_debug("%s: Couldn't extract the Activekey from the response\n",
1362 __func__);
455a7b23
SB
1363 return OPAL_INVAL_PARAM;
1364 }
5cc23ed7 1365
455a7b23
SB
1366 dev->prev_data = kmemdup(activekey, keylen, GFP_KERNEL);
1367
1368 if (!dev->prev_data)
1369 return -ENOMEM;
1370
1371 dev->prev_d_len = keylen;
1372
1373 return 0;
1374}
1375
eed64951 1376static int get_active_key(struct opal_dev *dev, void *data)
455a7b23
SB
1377{
1378 u8 uid[OPAL_UID_LENGTH];
e8b29224 1379 int err;
eed64951 1380 u8 *lr = data;
455a7b23 1381
455a7b23
SB
1382 err = build_locking_range(uid, sizeof(uid), *lr);
1383 if (err)
1384 return err;
1385
3fff234b
DK
1386 err = generic_get_column(dev, uid, OPAL_ACTIVEKEY);
1387 if (err)
455a7b23 1388 return err;
455a7b23 1389
3fff234b 1390 return get_active_key_cont(dev);
455a7b23
SB
1391}
1392
3495ea1b
RR
1393static int generic_table_write_data(struct opal_dev *dev, const u64 data,
1394 u64 offset, u64 size, const u8 *uid)
1395{
1396 const u8 __user *src = (u8 __user *)(uintptr_t)data;
1397 u8 *dst;
1398 u64 len;
1399 size_t off = 0;
1400 int err;
1401
1402 /* do we fit in the available space? */
1403 err = generic_get_table_info(dev, uid, OPAL_TABLE_ROWS);
1404 if (err) {
1405 pr_debug("Couldn't get the table size\n");
1406 return err;
1407 }
1408
1409 len = response_get_u64(&dev->parsed, 4);
1410 if (size > len || offset > len - size) {
1411 pr_debug("Does not fit in the table (%llu vs. %llu)\n",
1412 offset + size, len);
1413 return -ENOSPC;
1414 }
1415
1416 /* do the actual transmission(s) */
1417 while (off < size) {
1418 err = cmd_start(dev, uid, opalmethod[OPAL_SET]);
1419 add_token_u8(&err, dev, OPAL_STARTNAME);
1420 add_token_u8(&err, dev, OPAL_WHERE);
1421 add_token_u64(&err, dev, offset + off);
1422 add_token_u8(&err, dev, OPAL_ENDNAME);
1423
1424 add_token_u8(&err, dev, OPAL_STARTNAME);
1425 add_token_u8(&err, dev, OPAL_VALUES);
1426
1427 /*
1428 * The bytestring header is either 1 or 2 bytes, so assume 2.
1429 * There also needs to be enough space to accommodate the
1430 * trailing OPAL_ENDNAME (1 byte) and tokens added by
1431 * cmd_finalize.
1432 */
1433 len = min(remaining_size(dev) - (2+1+CMD_FINALIZE_BYTES_NEEDED),
1434 (size_t)(size - off));
1435 pr_debug("Write bytes %zu+%llu/%llu\n", off, len, size);
1436
1437 dst = add_bytestring_header(&err, dev, len);
1438 if (!dst)
1439 break;
1440
1441 if (copy_from_user(dst, src + off, len)) {
1442 err = -EFAULT;
1443 break;
1444 }
1445
1446 dev->pos += len;
1447
1448 add_token_u8(&err, dev, OPAL_ENDNAME);
1449 if (err)
1450 break;
1451
1452 err = finalize_and_send(dev, parse_and_check_status);
1453 if (err)
1454 break;
1455
1456 off += len;
1457 }
1458
1459 return err;
1460}
1461
455a7b23
SB
1462static int generic_lr_enable_disable(struct opal_dev *dev,
1463 u8 *uid, bool rle, bool wle,
1464 bool rl, bool wl)
1465{
e8b29224 1466 int err;
455a7b23 1467
e8b29224 1468 err = cmd_start(dev, uid, opalmethod[OPAL_SET]);
455a7b23 1469
455a7b23
SB
1470 add_token_u8(&err, dev, OPAL_STARTNAME);
1471 add_token_u8(&err, dev, OPAL_VALUES);
1472 add_token_u8(&err, dev, OPAL_STARTLIST);
1473
1474 add_token_u8(&err, dev, OPAL_STARTNAME);
372be408 1475 add_token_u8(&err, dev, OPAL_READLOCKENABLED);
455a7b23
SB
1476 add_token_u8(&err, dev, rle);
1477 add_token_u8(&err, dev, OPAL_ENDNAME);
1478
1479 add_token_u8(&err, dev, OPAL_STARTNAME);
372be408 1480 add_token_u8(&err, dev, OPAL_WRITELOCKENABLED);
455a7b23
SB
1481 add_token_u8(&err, dev, wle);
1482 add_token_u8(&err, dev, OPAL_ENDNAME);
1483
1484 add_token_u8(&err, dev, OPAL_STARTNAME);
1485 add_token_u8(&err, dev, OPAL_READLOCKED);
1486 add_token_u8(&err, dev, rl);
1487 add_token_u8(&err, dev, OPAL_ENDNAME);
1488
1489 add_token_u8(&err, dev, OPAL_STARTNAME);
1490 add_token_u8(&err, dev, OPAL_WRITELOCKED);
1491 add_token_u8(&err, dev, wl);
1492 add_token_u8(&err, dev, OPAL_ENDNAME);
1493
1494 add_token_u8(&err, dev, OPAL_ENDLIST);
1495 add_token_u8(&err, dev, OPAL_ENDNAME);
5cc23ed7 1496
455a7b23
SB
1497 return err;
1498}
1499
1500static inline int enable_global_lr(struct opal_dev *dev, u8 *uid,
1501 struct opal_user_lr_setup *setup)
1502{
1503 int err;
1504
1505 err = generic_lr_enable_disable(dev, uid, !!setup->RLE, !!setup->WLE,
1506 0, 0);
1507 if (err)
591c59d1 1508 pr_debug("Failed to create enable global lr command\n");
5cc23ed7 1509
455a7b23
SB
1510 return err;
1511}
1512
eed64951 1513static int setup_locking_range(struct opal_dev *dev, void *data)
455a7b23
SB
1514{
1515 u8 uid[OPAL_UID_LENGTH];
eed64951 1516 struct opal_user_lr_setup *setup = data;
455a7b23 1517 u8 lr;
e8b29224 1518 int err;
455a7b23 1519
455a7b23
SB
1520 lr = setup->session.opal_key.lr;
1521 err = build_locking_range(uid, sizeof(uid), lr);
1522 if (err)
1523 return err;
1524
1525 if (lr == 0)
1526 err = enable_global_lr(dev, uid, setup);
1527 else {
e8b29224 1528 err = cmd_start(dev, uid, opalmethod[OPAL_SET]);
455a7b23 1529
455a7b23
SB
1530 add_token_u8(&err, dev, OPAL_STARTNAME);
1531 add_token_u8(&err, dev, OPAL_VALUES);
1532 add_token_u8(&err, dev, OPAL_STARTLIST);
1533
1534 add_token_u8(&err, dev, OPAL_STARTNAME);
372be408 1535 add_token_u8(&err, dev, OPAL_RANGESTART);
455a7b23
SB
1536 add_token_u64(&err, dev, setup->range_start);
1537 add_token_u8(&err, dev, OPAL_ENDNAME);
1538
1539 add_token_u8(&err, dev, OPAL_STARTNAME);
372be408 1540 add_token_u8(&err, dev, OPAL_RANGELENGTH);
455a7b23
SB
1541 add_token_u64(&err, dev, setup->range_length);
1542 add_token_u8(&err, dev, OPAL_ENDNAME);
1543
1544 add_token_u8(&err, dev, OPAL_STARTNAME);
372be408 1545 add_token_u8(&err, dev, OPAL_READLOCKENABLED);
455a7b23
SB
1546 add_token_u64(&err, dev, !!setup->RLE);
1547 add_token_u8(&err, dev, OPAL_ENDNAME);
1548
1549 add_token_u8(&err, dev, OPAL_STARTNAME);
372be408 1550 add_token_u8(&err, dev, OPAL_WRITELOCKENABLED);
455a7b23
SB
1551 add_token_u64(&err, dev, !!setup->WLE);
1552 add_token_u8(&err, dev, OPAL_ENDNAME);
1553
1554 add_token_u8(&err, dev, OPAL_ENDLIST);
1555 add_token_u8(&err, dev, OPAL_ENDNAME);
455a7b23
SB
1556 }
1557 if (err) {
591c59d1 1558 pr_debug("Error building Setup Locking range command.\n");
455a7b23 1559 return err;
455a7b23
SB
1560 }
1561
1562 return finalize_and_send(dev, parse_and_check_status);
1563}
1564
4c4dd04e
OK
1565static int response_get_column(const struct parsed_resp *resp,
1566 int *iter,
1567 u8 column,
1568 u64 *value)
1569{
1570 const struct opal_resp_tok *tok;
1571 int n = *iter;
1572 u64 val;
1573
1574 tok = response_get_token(resp, n);
1575 if (IS_ERR(tok))
1576 return PTR_ERR(tok);
1577
1578 if (!response_token_matches(tok, OPAL_STARTNAME)) {
1579 pr_debug("Unexpected response token type %d.\n", n);
1580 return OPAL_INVAL_PARAM;
1581 }
1582 n++;
1583
1584 if (response_get_u64(resp, n) != column) {
1585 pr_debug("Token %d does not match expected column %u.\n",
1586 n, column);
1587 return OPAL_INVAL_PARAM;
1588 }
1589 n++;
1590
1591 val = response_get_u64(resp, n);
1592 n++;
1593
1594 tok = response_get_token(resp, n);
1595 if (IS_ERR(tok))
1596 return PTR_ERR(tok);
1597
1598 if (!response_token_matches(tok, OPAL_ENDNAME)) {
1599 pr_debug("Unexpected response token type %d.\n", n);
1600 return OPAL_INVAL_PARAM;
1601 }
1602 n++;
1603
1604 *value = val;
1605 *iter = n;
1606
1607 return 0;
1608}
1609
1610static int locking_range_status(struct opal_dev *dev, void *data)
1611{
1612 u8 lr_buffer[OPAL_UID_LENGTH];
1613 u64 resp;
1614 bool rlocked, wlocked;
1615 int err, tok_n = 2;
1616 struct opal_lr_status *lrst = data;
1617
1618 err = build_locking_range(lr_buffer, sizeof(lr_buffer),
1619 lrst->session.opal_key.lr);
1620 if (err)
1621 return err;
1622
1623 err = generic_get_columns(dev, lr_buffer, OPAL_RANGESTART,
1624 OPAL_WRITELOCKED);
1625 if (err) {
1626 pr_debug("Couldn't get lr %u table columns %d to %d.\n",
1627 lrst->session.opal_key.lr, OPAL_RANGESTART,
1628 OPAL_WRITELOCKED);
1629 return err;
1630 }
1631
1632 /* range start */
1633 err = response_get_column(&dev->parsed, &tok_n, OPAL_RANGESTART,
1634 &lrst->range_start);
1635 if (err)
1636 return err;
1637
1638 /* range length */
1639 err = response_get_column(&dev->parsed, &tok_n, OPAL_RANGELENGTH,
1640 &lrst->range_length);
1641 if (err)
1642 return err;
1643
1644 /* RLE */
1645 err = response_get_column(&dev->parsed, &tok_n, OPAL_READLOCKENABLED,
1646 &resp);
1647 if (err)
1648 return err;
1649
1650 lrst->RLE = !!resp;
1651
1652 /* WLE */
1653 err = response_get_column(&dev->parsed, &tok_n, OPAL_WRITELOCKENABLED,
1654 &resp);
1655 if (err)
1656 return err;
1657
1658 lrst->WLE = !!resp;
1659
1660 /* read locked */
1661 err = response_get_column(&dev->parsed, &tok_n, OPAL_READLOCKED, &resp);
1662 if (err)
1663 return err;
1664
1665 rlocked = !!resp;
1666
1667 /* write locked */
1668 err = response_get_column(&dev->parsed, &tok_n, OPAL_WRITELOCKED, &resp);
1669 if (err)
1670 return err;
1671
1672 wlocked = !!resp;
1673
1674 /* opal_lock_state can not map 'read locked' only state. */
1675 lrst->l_state = OPAL_RW;
1676 if (rlocked && wlocked)
1677 lrst->l_state = OPAL_LK;
1678 else if (wlocked)
1679 lrst->l_state = OPAL_RO;
1680 else if (rlocked) {
1681 pr_debug("Can not report read locked only state.\n");
1682 return -EINVAL;
1683 }
1684
1685 return 0;
1686}
1687
455a7b23
SB
1688static int start_generic_opal_session(struct opal_dev *dev,
1689 enum opal_uid auth,
1690 enum opal_uid sp_type,
1691 const char *key,
1692 u8 key_len)
1693{
1694 u32 hsn;
e8b29224 1695 int err;
455a7b23 1696
591c59d1 1697 if (key == NULL && auth != OPAL_ANYBODY_UID)
455a7b23 1698 return OPAL_INVAL_PARAM;
455a7b23 1699
455a7b23 1700 hsn = GENERIC_HOST_SESSION_NUM;
e8b29224
DK
1701 err = cmd_start(dev, opaluid[OPAL_SMUID_UID],
1702 opalmethod[OPAL_STARTSESSION]);
455a7b23 1703
455a7b23
SB
1704 add_token_u64(&err, dev, hsn);
1705 add_token_bytestring(&err, dev, opaluid[sp_type], OPAL_UID_LENGTH);
1706 add_token_u8(&err, dev, 1);
1707
1708 switch (auth) {
1709 case OPAL_ANYBODY_UID:
455a7b23
SB
1710 break;
1711 case OPAL_ADMIN1_UID:
1712 case OPAL_SID_UID:
5e4c7cf6 1713 case OPAL_PSID_UID:
455a7b23
SB
1714 add_token_u8(&err, dev, OPAL_STARTNAME);
1715 add_token_u8(&err, dev, 0); /* HostChallenge */
1716 add_token_bytestring(&err, dev, key, key_len);
1717 add_token_u8(&err, dev, OPAL_ENDNAME);
1718 add_token_u8(&err, dev, OPAL_STARTNAME);
1719 add_token_u8(&err, dev, 3); /* HostSignAuth */
1720 add_token_bytestring(&err, dev, opaluid[auth],
1721 OPAL_UID_LENGTH);
1722 add_token_u8(&err, dev, OPAL_ENDNAME);
455a7b23
SB
1723 break;
1724 default:
591c59d1 1725 pr_debug("Cannot start Admin SP session with auth %d\n", auth);
455a7b23
SB
1726 return OPAL_INVAL_PARAM;
1727 }
1728
1729 if (err) {
591c59d1 1730 pr_debug("Error building start adminsp session command.\n");
455a7b23
SB
1731 return err;
1732 }
1733
1734 return finalize_and_send(dev, start_opal_session_cont);
1735}
1736
eed64951 1737static int start_anybodyASP_opal_session(struct opal_dev *dev, void *data)
455a7b23
SB
1738{
1739 return start_generic_opal_session(dev, OPAL_ANYBODY_UID,
1740 OPAL_ADMINSP_UID, NULL, 0);
1741}
1742
eed64951 1743static int start_SIDASP_opal_session(struct opal_dev *dev, void *data)
455a7b23
SB
1744{
1745 int ret;
1746 const u8 *key = dev->prev_data;
455a7b23
SB
1747
1748 if (!key) {
eed64951 1749 const struct opal_key *okey = data;
1e815b33 1750
455a7b23
SB
1751 ret = start_generic_opal_session(dev, OPAL_SID_UID,
1752 OPAL_ADMINSP_UID,
1753 okey->key,
1754 okey->key_len);
1755 } else {
1756 ret = start_generic_opal_session(dev, OPAL_SID_UID,
1757 OPAL_ADMINSP_UID,
1758 key, dev->prev_d_len);
1759 kfree(key);
1760 dev->prev_data = NULL;
1761 }
5cc23ed7 1762
455a7b23
SB
1763 return ret;
1764}
1765
eed64951 1766static int start_admin1LSP_opal_session(struct opal_dev *dev, void *data)
455a7b23 1767{
eed64951 1768 struct opal_key *key = data;
1e815b33 1769
455a7b23
SB
1770 return start_generic_opal_session(dev, OPAL_ADMIN1_UID,
1771 OPAL_LOCKINGSP_UID,
1772 key->key, key->key_len);
1773}
1774
5e4c7cf6
RR
1775static int start_PSID_opal_session(struct opal_dev *dev, void *data)
1776{
1777 const struct opal_key *okey = data;
1778
1779 return start_generic_opal_session(dev, OPAL_PSID_UID,
1780 OPAL_ADMINSP_UID,
1781 okey->key,
1782 okey->key_len);
1783}
1784
eed64951 1785static int start_auth_opal_session(struct opal_dev *dev, void *data)
455a7b23 1786{
eed64951 1787 struct opal_session_info *session = data;
455a7b23 1788 u8 lk_ul_user[OPAL_UID_LENGTH];
eed64951 1789 size_t keylen = session->opal_key.key_len;
455a7b23
SB
1790 int err = 0;
1791
455a7b23
SB
1792 u8 *key = session->opal_key.key;
1793 u32 hsn = GENERIC_HOST_SESSION_NUM;
1794
e8b29224 1795 if (session->sum)
455a7b23
SB
1796 err = build_locking_user(lk_ul_user, sizeof(lk_ul_user),
1797 session->opal_key.lr);
e8b29224 1798 else if (session->who != OPAL_ADMIN1 && !session->sum)
455a7b23
SB
1799 err = build_locking_user(lk_ul_user, sizeof(lk_ul_user),
1800 session->who - 1);
e8b29224 1801 else
455a7b23
SB
1802 memcpy(lk_ul_user, opaluid[OPAL_ADMIN1_UID], OPAL_UID_LENGTH);
1803
e8b29224
DK
1804 if (err)
1805 return err;
1806
1807 err = cmd_start(dev, opaluid[OPAL_SMUID_UID],
1808 opalmethod[OPAL_STARTSESSION]);
455a7b23 1809
455a7b23
SB
1810 add_token_u64(&err, dev, hsn);
1811 add_token_bytestring(&err, dev, opaluid[OPAL_LOCKINGSP_UID],
1812 OPAL_UID_LENGTH);
1813 add_token_u8(&err, dev, 1);
1814 add_token_u8(&err, dev, OPAL_STARTNAME);
1815 add_token_u8(&err, dev, 0);
1816 add_token_bytestring(&err, dev, key, keylen);
1817 add_token_u8(&err, dev, OPAL_ENDNAME);
1818 add_token_u8(&err, dev, OPAL_STARTNAME);
1819 add_token_u8(&err, dev, 3);
1820 add_token_bytestring(&err, dev, lk_ul_user, OPAL_UID_LENGTH);
1821 add_token_u8(&err, dev, OPAL_ENDNAME);
455a7b23
SB
1822
1823 if (err) {
591c59d1 1824 pr_debug("Error building STARTSESSION command.\n");
455a7b23
SB
1825 return err;
1826 }
1827
1828 return finalize_and_send(dev, start_opal_session_cont);
1829}
1830
eed64951 1831static int revert_tper(struct opal_dev *dev, void *data)
455a7b23 1832{
e8b29224 1833 int err;
455a7b23 1834
e8b29224
DK
1835 err = cmd_start(dev, opaluid[OPAL_ADMINSP_UID],
1836 opalmethod[OPAL_REVERT]);
455a7b23 1837 if (err) {
591c59d1 1838 pr_debug("Error building REVERT TPER command.\n");
455a7b23
SB
1839 return err;
1840 }
1841
1842 return finalize_and_send(dev, parse_and_check_status);
1843}
1844
eed64951 1845static int internal_activate_user(struct opal_dev *dev, void *data)
455a7b23 1846{
eed64951 1847 struct opal_session_info *session = data;
455a7b23 1848 u8 uid[OPAL_UID_LENGTH];
e8b29224 1849 int err;
455a7b23
SB
1850
1851 memcpy(uid, opaluid[OPAL_USER1_UID], OPAL_UID_LENGTH);
1852 uid[7] = session->who;
1853
e8b29224 1854 err = cmd_start(dev, uid, opalmethod[OPAL_SET]);
455a7b23
SB
1855 add_token_u8(&err, dev, OPAL_STARTNAME);
1856 add_token_u8(&err, dev, OPAL_VALUES);
1857 add_token_u8(&err, dev, OPAL_STARTLIST);
1858 add_token_u8(&err, dev, OPAL_STARTNAME);
1859 add_token_u8(&err, dev, 5); /* Enabled */
1860 add_token_u8(&err, dev, OPAL_TRUE);
1861 add_token_u8(&err, dev, OPAL_ENDNAME);
1862 add_token_u8(&err, dev, OPAL_ENDLIST);
1863 add_token_u8(&err, dev, OPAL_ENDNAME);
455a7b23
SB
1864
1865 if (err) {
591c59d1 1866 pr_debug("Error building Activate UserN command.\n");
455a7b23
SB
1867 return err;
1868 }
1869
1870 return finalize_and_send(dev, parse_and_check_status);
1871}
1872
5c82efc1
GJ
1873static int revert_lsp(struct opal_dev *dev, void *data)
1874{
1875 struct opal_revert_lsp *rev = data;
1876 int err;
1877
1878 err = cmd_start(dev, opaluid[OPAL_THISSP_UID],
1879 opalmethod[OPAL_REVERTSP]);
1880 add_token_u8(&err, dev, OPAL_STARTNAME);
1881 add_token_u64(&err, dev, OPAL_KEEP_GLOBAL_RANGE_KEY);
1882 add_token_u8(&err, dev, (rev->options & OPAL_PRESERVE) ?
1883 OPAL_TRUE : OPAL_FALSE);
1884 add_token_u8(&err, dev, OPAL_ENDNAME);
1885 if (err) {
1886 pr_debug("Error building REVERT SP command.\n");
1887 return err;
1888 }
1889
1890 return finalize_and_send(dev, parse_and_check_status);
1891}
1892
eed64951 1893static int erase_locking_range(struct opal_dev *dev, void *data)
455a7b23 1894{
eed64951 1895 struct opal_session_info *session = data;
455a7b23 1896 u8 uid[OPAL_UID_LENGTH];
e8b29224 1897 int err;
455a7b23
SB
1898
1899 if (build_locking_range(uid, sizeof(uid), session->opal_key.lr) < 0)
1900 return -ERANGE;
1901
e8b29224 1902 err = cmd_start(dev, uid, opalmethod[OPAL_ERASE]);
455a7b23
SB
1903
1904 if (err) {
591c59d1 1905 pr_debug("Error building Erase Locking Range Command.\n");
455a7b23
SB
1906 return err;
1907 }
5cc23ed7 1908
455a7b23
SB
1909 return finalize_and_send(dev, parse_and_check_status);
1910}
1911
eed64951 1912static int set_mbr_done(struct opal_dev *dev, void *data)
455a7b23 1913{
eed64951 1914 u8 *mbr_done_tf = data;
e8b29224 1915 int err;
455a7b23 1916
e8b29224
DK
1917 err = cmd_start(dev, opaluid[OPAL_MBRCONTROL],
1918 opalmethod[OPAL_SET]);
455a7b23 1919
455a7b23
SB
1920 add_token_u8(&err, dev, OPAL_STARTNAME);
1921 add_token_u8(&err, dev, OPAL_VALUES);
1922 add_token_u8(&err, dev, OPAL_STARTLIST);
1923 add_token_u8(&err, dev, OPAL_STARTNAME);
372be408 1924 add_token_u8(&err, dev, OPAL_MBRDONE);
eed64951 1925 add_token_u8(&err, dev, *mbr_done_tf); /* Done T or F */
455a7b23
SB
1926 add_token_u8(&err, dev, OPAL_ENDNAME);
1927 add_token_u8(&err, dev, OPAL_ENDLIST);
1928 add_token_u8(&err, dev, OPAL_ENDNAME);
455a7b23
SB
1929
1930 if (err) {
591c59d1 1931 pr_debug("Error Building set MBR Done command\n");
455a7b23
SB
1932 return err;
1933 }
1934
1935 return finalize_and_send(dev, parse_and_check_status);
1936}
1937
eed64951 1938static int set_mbr_enable_disable(struct opal_dev *dev, void *data)
455a7b23 1939{
eed64951 1940 u8 *mbr_en_dis = data;
e8b29224 1941 int err;
455a7b23 1942
e8b29224
DK
1943 err = cmd_start(dev, opaluid[OPAL_MBRCONTROL],
1944 opalmethod[OPAL_SET]);
455a7b23 1945
455a7b23
SB
1946 add_token_u8(&err, dev, OPAL_STARTNAME);
1947 add_token_u8(&err, dev, OPAL_VALUES);
1948 add_token_u8(&err, dev, OPAL_STARTLIST);
1949 add_token_u8(&err, dev, OPAL_STARTNAME);
372be408 1950 add_token_u8(&err, dev, OPAL_MBRENABLE);
eed64951 1951 add_token_u8(&err, dev, *mbr_en_dis);
455a7b23
SB
1952 add_token_u8(&err, dev, OPAL_ENDNAME);
1953 add_token_u8(&err, dev, OPAL_ENDLIST);
1954 add_token_u8(&err, dev, OPAL_ENDNAME);
455a7b23
SB
1955
1956 if (err) {
591c59d1 1957 pr_debug("Error Building set MBR done command\n");
455a7b23
SB
1958 return err;
1959 }
1960
1961 return finalize_and_send(dev, parse_and_check_status);
1962}
1963
a9b25b4c
JR
1964static int write_shadow_mbr(struct opal_dev *dev, void *data)
1965{
1966 struct opal_shadow_mbr *shadow = data;
a9b25b4c 1967
3495ea1b
RR
1968 return generic_table_write_data(dev, shadow->data, shadow->offset,
1969 shadow->size, opaluid[OPAL_MBR]);
a9b25b4c
JR
1970}
1971
455a7b23
SB
1972static int generic_pw_cmd(u8 *key, size_t key_len, u8 *cpin_uid,
1973 struct opal_dev *dev)
1974{
e8b29224 1975 int err;
455a7b23 1976
e8b29224 1977 err = cmd_start(dev, cpin_uid, opalmethod[OPAL_SET]);
455a7b23 1978
455a7b23
SB
1979 add_token_u8(&err, dev, OPAL_STARTNAME);
1980 add_token_u8(&err, dev, OPAL_VALUES);
1981 add_token_u8(&err, dev, OPAL_STARTLIST);
1982 add_token_u8(&err, dev, OPAL_STARTNAME);
372be408 1983 add_token_u8(&err, dev, OPAL_PIN);
455a7b23
SB
1984 add_token_bytestring(&err, dev, key, key_len);
1985 add_token_u8(&err, dev, OPAL_ENDNAME);
1986 add_token_u8(&err, dev, OPAL_ENDLIST);
1987 add_token_u8(&err, dev, OPAL_ENDNAME);
455a7b23
SB
1988
1989 return err;
1990}
1991
eed64951 1992static int set_new_pw(struct opal_dev *dev, void *data)
455a7b23
SB
1993{
1994 u8 cpin_uid[OPAL_UID_LENGTH];
eed64951 1995 struct opal_session_info *usr = data;
455a7b23
SB
1996
1997 memcpy(cpin_uid, opaluid[OPAL_C_PIN_ADMIN1], OPAL_UID_LENGTH);
1998
1999 if (usr->who != OPAL_ADMIN1) {
2000 cpin_uid[5] = 0x03;
2001 if (usr->sum)
2002 cpin_uid[7] = usr->opal_key.lr + 1;
2003 else
2004 cpin_uid[7] = usr->who;
2005 }
2006
2007 if (generic_pw_cmd(usr->opal_key.key, usr->opal_key.key_len,
2008 cpin_uid, dev)) {
591c59d1 2009 pr_debug("Error building set password command.\n");
455a7b23
SB
2010 return -ERANGE;
2011 }
2012
2013 return finalize_and_send(dev, parse_and_check_status);
2014}
2015
eed64951 2016static int set_sid_cpin_pin(struct opal_dev *dev, void *data)
455a7b23
SB
2017{
2018 u8 cpin_uid[OPAL_UID_LENGTH];
eed64951 2019 struct opal_key *key = data;
455a7b23
SB
2020
2021 memcpy(cpin_uid, opaluid[OPAL_C_PIN_SID], OPAL_UID_LENGTH);
2022
2023 if (generic_pw_cmd(key->key, key->key_len, cpin_uid, dev)) {
591c59d1 2024 pr_debug("Error building Set SID cpin\n");
455a7b23
SB
2025 return -ERANGE;
2026 }
2027 return finalize_and_send(dev, parse_and_check_status);
2028}
2029
175b6544
OK
2030static void add_authority_object_ref(int *err,
2031 struct opal_dev *dev,
2032 const u8 *uid,
2033 size_t uid_len)
2034{
2035 add_token_u8(err, dev, OPAL_STARTNAME);
2036 add_token_bytestring(err, dev,
2037 opaluid[OPAL_HALF_UID_AUTHORITY_OBJ_REF],
2038 OPAL_UID_LENGTH/2);
2039 add_token_bytestring(err, dev, uid, uid_len);
2040 add_token_u8(err, dev, OPAL_ENDNAME);
2041}
2042
2043static void add_boolean_object_ref(int *err,
2044 struct opal_dev *dev,
2045 u8 boolean_op)
2046{
2047 add_token_u8(err, dev, OPAL_STARTNAME);
2048 add_token_bytestring(err, dev, opaluid[OPAL_HALF_UID_BOOLEAN_ACE],
2049 OPAL_UID_LENGTH/2);
2050 add_token_u8(err, dev, boolean_op);
2051 add_token_u8(err, dev, OPAL_ENDNAME);
2052}
2053
2054static int set_lr_boolean_ace(struct opal_dev *dev,
2055 unsigned int opal_uid,
2056 u8 lr,
2057 const u8 *users,
2058 size_t users_len)
455a7b23
SB
2059{
2060 u8 lr_buffer[OPAL_UID_LENGTH];
2061 u8 user_uid[OPAL_UID_LENGTH];
175b6544 2062 u8 u;
e8b29224 2063 int err;
455a7b23 2064
175b6544
OK
2065 memcpy(lr_buffer, opaluid[opal_uid], OPAL_UID_LENGTH);
2066 lr_buffer[7] = lr;
455a7b23 2067
e8b29224 2068 err = cmd_start(dev, lr_buffer, opalmethod[OPAL_SET]);
455a7b23 2069
455a7b23
SB
2070 add_token_u8(&err, dev, OPAL_STARTNAME);
2071 add_token_u8(&err, dev, OPAL_VALUES);
2072
2073 add_token_u8(&err, dev, OPAL_STARTLIST);
2074 add_token_u8(&err, dev, OPAL_STARTNAME);
2075 add_token_u8(&err, dev, 3);
2076
2077 add_token_u8(&err, dev, OPAL_STARTLIST);
2078
175b6544
OK
2079 for (u = 0; u < users_len; u++) {
2080 if (users[u] == OPAL_ADMIN1)
2081 memcpy(user_uid, opaluid[OPAL_ADMIN1_UID],
2082 OPAL_UID_LENGTH);
2083 else {
2084 memcpy(user_uid, opaluid[OPAL_USER1_UID],
2085 OPAL_UID_LENGTH);
2086 user_uid[7] = users[u];
2087 }
2088
2089 add_authority_object_ref(&err, dev, user_uid, sizeof(user_uid));
455a7b23 2090
175b6544
OK
2091 /*
2092 * Add boolean operator in postfix only with
2093 * two or more authorities being added in ACE
2094 * expresion.
2095 * */
2096 if (u > 0)
2097 add_boolean_object_ref(&err, dev, OPAL_BOOLEAN_OR);
2098 }
455a7b23 2099
455a7b23
SB
2100 add_token_u8(&err, dev, OPAL_ENDLIST);
2101 add_token_u8(&err, dev, OPAL_ENDNAME);
2102 add_token_u8(&err, dev, OPAL_ENDLIST);
2103 add_token_u8(&err, dev, OPAL_ENDNAME);
455a7b23 2104
175b6544
OK
2105 return err;
2106}
2107
2108static int add_user_to_lr(struct opal_dev *dev, void *data)
2109{
2110 int err;
2111 struct opal_lock_unlock *lkul = data;
2112 const u8 users[] = {
2113 lkul->session.who
2114 };
2115
2116 err = set_lr_boolean_ace(dev,
2117 lkul->l_state == OPAL_RW ?
2118 OPAL_LOCKINGRANGE_ACE_WRLOCKED :
2119 OPAL_LOCKINGRANGE_ACE_RDLOCKED,
2120 lkul->session.opal_key.lr, users,
2121 ARRAY_SIZE(users));
455a7b23 2122 if (err) {
591c59d1 2123 pr_debug("Error building add user to locking range command.\n");
455a7b23
SB
2124 return err;
2125 }
2126
2127 return finalize_and_send(dev, parse_and_check_status);
2128}
2129
8be19a02
OK
2130static int add_user_to_lr_ace(struct opal_dev *dev, void *data)
2131{
2132 int err;
2133 struct opal_lock_unlock *lkul = data;
2134 const u8 users[] = {
2135 OPAL_ADMIN1,
2136 lkul->session.who
2137 };
2138
2139 err = set_lr_boolean_ace(dev, OPAL_LOCKINGRANGE_ACE_START_TO_KEY,
2140 lkul->session.opal_key.lr, users,
2141 ARRAY_SIZE(users));
2142
2143 if (err) {
2144 pr_debug("Error building add user to locking ranges ACEs.\n");
2145 return err;
2146 }
2147
2148 return finalize_and_send(dev, parse_and_check_status);
2149}
2150
eed64951 2151static int lock_unlock_locking_range(struct opal_dev *dev, void *data)
455a7b23
SB
2152{
2153 u8 lr_buffer[OPAL_UID_LENGTH];
eed64951 2154 struct opal_lock_unlock *lkul = data;
455a7b23
SB
2155 u8 read_locked = 1, write_locked = 1;
2156 int err = 0;
2157
455a7b23
SB
2158 if (build_locking_range(lr_buffer, sizeof(lr_buffer),
2159 lkul->session.opal_key.lr) < 0)
2160 return -ERANGE;
2161
2162 switch (lkul->l_state) {
2163 case OPAL_RO:
2164 read_locked = 0;
2165 write_locked = 1;
2166 break;
2167 case OPAL_RW:
2168 read_locked = 0;
2169 write_locked = 0;
2170 break;
2171 case OPAL_LK:
1e815b33 2172 /* vars are initialized to locked */
455a7b23
SB
2173 break;
2174 default:
591c59d1 2175 pr_debug("Tried to set an invalid locking state... returning to uland\n");
455a7b23
SB
2176 return OPAL_INVAL_PARAM;
2177 }
2178
e8b29224
DK
2179 err = cmd_start(dev, lr_buffer, opalmethod[OPAL_SET]);
2180
455a7b23
SB
2181 add_token_u8(&err, dev, OPAL_STARTNAME);
2182 add_token_u8(&err, dev, OPAL_VALUES);
2183 add_token_u8(&err, dev, OPAL_STARTLIST);
2184
2185 add_token_u8(&err, dev, OPAL_STARTNAME);
2186 add_token_u8(&err, dev, OPAL_READLOCKED);
2187 add_token_u8(&err, dev, read_locked);
2188 add_token_u8(&err, dev, OPAL_ENDNAME);
2189
2190 add_token_u8(&err, dev, OPAL_STARTNAME);
2191 add_token_u8(&err, dev, OPAL_WRITELOCKED);
2192 add_token_u8(&err, dev, write_locked);
2193 add_token_u8(&err, dev, OPAL_ENDNAME);
2194
2195 add_token_u8(&err, dev, OPAL_ENDLIST);
2196 add_token_u8(&err, dev, OPAL_ENDNAME);
455a7b23
SB
2197
2198 if (err) {
591c59d1 2199 pr_debug("Error building SET command.\n");
455a7b23
SB
2200 return err;
2201 }
5cc23ed7 2202
455a7b23
SB
2203 return finalize_and_send(dev, parse_and_check_status);
2204}
2205
2206
eed64951 2207static int lock_unlock_locking_range_sum(struct opal_dev *dev, void *data)
455a7b23
SB
2208{
2209 u8 lr_buffer[OPAL_UID_LENGTH];
2210 u8 read_locked = 1, write_locked = 1;
eed64951 2211 struct opal_lock_unlock *lkul = data;
455a7b23
SB
2212 int ret;
2213
2214 clear_opal_cmd(dev);
2215 set_comid(dev, dev->comid);
2216
455a7b23
SB
2217 if (build_locking_range(lr_buffer, sizeof(lr_buffer),
2218 lkul->session.opal_key.lr) < 0)
2219 return -ERANGE;
2220
2221 switch (lkul->l_state) {
2222 case OPAL_RO:
2223 read_locked = 0;
2224 write_locked = 1;
2225 break;
2226 case OPAL_RW:
2227 read_locked = 0;
2228 write_locked = 0;
2229 break;
2230 case OPAL_LK:
1e815b33 2231 /* vars are initialized to locked */
455a7b23
SB
2232 break;
2233 default:
591c59d1 2234 pr_debug("Tried to set an invalid locking state.\n");
455a7b23
SB
2235 return OPAL_INVAL_PARAM;
2236 }
2237 ret = generic_lr_enable_disable(dev, lr_buffer, 1, 1,
2238 read_locked, write_locked);
2239
2240 if (ret < 0) {
591c59d1 2241 pr_debug("Error building SET command.\n");
455a7b23
SB
2242 return ret;
2243 }
5cc23ed7 2244
455a7b23
SB
2245 return finalize_and_send(dev, parse_and_check_status);
2246}
2247
eed64951 2248static int activate_lsp(struct opal_dev *dev, void *data)
455a7b23 2249{
eed64951 2250 struct opal_lr_act *opal_act = data;
455a7b23 2251 u8 user_lr[OPAL_UID_LENGTH];
e8b29224 2252 int err, i;
455a7b23 2253
e8b29224
DK
2254 err = cmd_start(dev, opaluid[OPAL_LOCKINGSP_UID],
2255 opalmethod[OPAL_ACTIVATE]);
455a7b23
SB
2256
2257 if (opal_act->sum) {
2258 err = build_locking_range(user_lr, sizeof(user_lr),
2259 opal_act->lr[0]);
2260 if (err)
2261 return err;
2262
455a7b23 2263 add_token_u8(&err, dev, OPAL_STARTNAME);
c6da429e 2264 add_token_u64(&err, dev, OPAL_SUM_SET_LIST);
455a7b23
SB
2265
2266 add_token_u8(&err, dev, OPAL_STARTLIST);
2267 add_token_bytestring(&err, dev, user_lr, OPAL_UID_LENGTH);
2268 for (i = 1; i < opal_act->num_lrs; i++) {
2269 user_lr[7] = opal_act->lr[i];
2270 add_token_bytestring(&err, dev, user_lr, OPAL_UID_LENGTH);
2271 }
2272 add_token_u8(&err, dev, OPAL_ENDLIST);
2273 add_token_u8(&err, dev, OPAL_ENDNAME);
455a7b23
SB
2274 }
2275
2276 if (err) {
591c59d1 2277 pr_debug("Error building Activate LockingSP command.\n");
455a7b23
SB
2278 return err;
2279 }
2280
2281 return finalize_and_send(dev, parse_and_check_status);
2282}
2283
3fff234b
DK
2284/* Determine if we're in the Manufactured Inactive or Active state */
2285static int get_lsp_lifecycle(struct opal_dev *dev, void *data)
455a7b23
SB
2286{
2287 u8 lc_status;
3fff234b 2288 int err;
455a7b23 2289
3fff234b
DK
2290 err = generic_get_column(dev, opaluid[OPAL_LOCKINGSP_UID],
2291 OPAL_LIFECYCLE);
2292 if (err)
2293 return err;
455a7b23
SB
2294
2295 lc_status = response_get_u64(&dev->parsed, 4);
1e815b33 2296 /* 0x08 is Manufactured Inactive */
455a7b23
SB
2297 /* 0x09 is Manufactured */
2298 if (lc_status != OPAL_MANUFACTURED_INACTIVE) {
591c59d1 2299 pr_debug("Couldn't determine the status of the Lifecycle state\n");
455a7b23
SB
2300 return -ENODEV;
2301 }
2302
2303 return 0;
2304}
2305
3fff234b 2306static int get_msid_cpin_pin(struct opal_dev *dev, void *data)
455a7b23
SB
2307{
2308 const char *msid_pin;
2309 size_t strlen;
3fff234b 2310 int err;
455a7b23 2311
3fff234b
DK
2312 err = generic_get_column(dev, opaluid[OPAL_C_PIN_MSID], OPAL_PIN);
2313 if (err)
2314 return err;
455a7b23
SB
2315
2316 strlen = response_get_string(&dev->parsed, 4, &msid_pin);
2317 if (!msid_pin) {
3fff234b 2318 pr_debug("Couldn't extract MSID_CPIN from response\n");
455a7b23
SB
2319 return OPAL_INVAL_PARAM;
2320 }
2321
2322 dev->prev_data = kmemdup(msid_pin, strlen, GFP_KERNEL);
2323 if (!dev->prev_data)
2324 return -ENOMEM;
2325
2326 dev->prev_d_len = strlen;
2327
2328 return 0;
2329}
2330
51f421c8
RR
2331static int write_table_data(struct opal_dev *dev, void *data)
2332{
2333 struct opal_read_write_table *write_tbl = data;
2334
2335 return generic_table_write_data(dev, write_tbl->data, write_tbl->offset,
2336 write_tbl->size, write_tbl->table_uid);
2337}
2338
2339static int read_table_data_cont(struct opal_dev *dev)
2340{
2341 int err;
2342 const char *data_read;
2343
2344 err = parse_and_check_status(dev);
2345 if (err)
2346 return err;
2347
2348 dev->prev_d_len = response_get_string(&dev->parsed, 1, &data_read);
2349 dev->prev_data = (void *)data_read;
2350 if (!dev->prev_data) {
2351 pr_debug("%s: Couldn't read data from the table.\n", __func__);
2352 return OPAL_INVAL_PARAM;
2353 }
2354
2355 return 0;
2356}
2357
2358/*
2359 * IO_BUFFER_LENGTH = 2048
2360 * sizeof(header) = 56
2361 * No. of Token Bytes in the Response = 11
2362 * MAX size of data that can be carried in response buffer
2363 * at a time is : 2048 - (56 + 11) = 1981 = 0x7BD.
2364 */
2365#define OPAL_MAX_READ_TABLE (0x7BD)
2366
2367static int read_table_data(struct opal_dev *dev, void *data)
2368{
2369 struct opal_read_write_table *read_tbl = data;
2370 int err;
2371 size_t off = 0, max_read_size = OPAL_MAX_READ_TABLE;
2372 u64 table_len, len;
2373 u64 offset = read_tbl->offset, read_size = read_tbl->size - 1;
2374 u8 __user *dst;
2375
2376 err = generic_get_table_info(dev, read_tbl->table_uid, OPAL_TABLE_ROWS);
2377 if (err) {
2378 pr_debug("Couldn't get the table size\n");
2379 return err;
2380 }
2381
2382 table_len = response_get_u64(&dev->parsed, 4);
2383
2384 /* Check if the user is trying to read from the table limits */
2385 if (read_size > table_len || offset > table_len - read_size) {
2386 pr_debug("Read size exceeds the Table size limits (%llu vs. %llu)\n",
2387 offset + read_size, table_len);
2388 return -EINVAL;
2389 }
2390
2391 while (off < read_size) {
2392 err = cmd_start(dev, read_tbl->table_uid, opalmethod[OPAL_GET]);
2393
2394 add_token_u8(&err, dev, OPAL_STARTLIST);
2395 add_token_u8(&err, dev, OPAL_STARTNAME);
2396 add_token_u8(&err, dev, OPAL_STARTROW);
2397 add_token_u64(&err, dev, offset + off); /* start row value */
2398 add_token_u8(&err, dev, OPAL_ENDNAME);
2399
2400 add_token_u8(&err, dev, OPAL_STARTNAME);
2401 add_token_u8(&err, dev, OPAL_ENDROW);
2402
2403 len = min(max_read_size, (size_t)(read_size - off));
2404 add_token_u64(&err, dev, offset + off + len); /* end row value
2405 */
2406 add_token_u8(&err, dev, OPAL_ENDNAME);
2407 add_token_u8(&err, dev, OPAL_ENDLIST);
2408
2409 if (err) {
2410 pr_debug("Error building read table data command.\n");
2411 break;
2412 }
2413
2414 err = finalize_and_send(dev, read_table_data_cont);
2415 if (err)
2416 break;
2417
2418 /* len+1: This includes the NULL terminator at the end*/
2419 if (dev->prev_d_len > len + 1) {
2420 err = -EOVERFLOW;
2421 break;
2422 }
2423
2424 dst = (u8 __user *)(uintptr_t)read_tbl->data;
2425 if (copy_to_user(dst + off, dev->prev_data, dev->prev_d_len)) {
2426 pr_debug("Error copying data to userspace\n");
2427 err = -EFAULT;
2428 break;
2429 }
2430 dev->prev_data = NULL;
2431
2432 off += len;
2433 }
2434
2435 return err;
2436}
2437
eed64951 2438static int end_opal_session(struct opal_dev *dev, void *data)
455a7b23
SB
2439{
2440 int err = 0;
2441
2442 clear_opal_cmd(dev);
455a7b23
SB
2443 set_comid(dev, dev->comid);
2444 add_token_u8(&err, dev, OPAL_ENDOFSESSION);
455a7b23 2445
eed64951
JD
2446 if (err < 0)
2447 return err;
5cc23ed7 2448
455a7b23
SB
2449 return finalize_and_send(dev, end_session_cont);
2450}
2451
2452static int end_opal_session_error(struct opal_dev *dev)
2453{
0af2648e
DK
2454 const struct opal_step error_end_session = {
2455 end_opal_session,
455a7b23 2456 };
5cc23ed7 2457
0af2648e 2458 return execute_step(dev, &error_end_session, 0);
455a7b23
SB
2459}
2460
3db87236 2461static inline void setup_opal_dev(struct opal_dev *dev)
455a7b23 2462{
455a7b23
SB
2463 dev->tsn = 0;
2464 dev->hsn = 0;
455a7b23
SB
2465 dev->prev_data = NULL;
2466}
2467
2468static int check_opal_support(struct opal_dev *dev)
2469{
455a7b23
SB
2470 int ret;
2471
2472 mutex_lock(&dev->dev_lock);
3db87236 2473 setup_opal_dev(dev);
0af2648e 2474 ret = opal_discovery0_step(dev);
c6ea7060 2475 if (!ret)
2476 dev->flags |= OPAL_FL_SUPPORTED;
455a7b23 2477 mutex_unlock(&dev->dev_lock);
5cc23ed7 2478
455a7b23
SB
2479 return ret;
2480}
2481
7d6d1578
SB
2482static void clean_opal_dev(struct opal_dev *dev)
2483{
2484
2485 struct opal_suspend_data *suspend, *next;
2486
2487 mutex_lock(&dev->dev_lock);
2488 list_for_each_entry_safe(suspend, next, &dev->unlk_lst, node) {
2489 list_del(&suspend->node);
2490 kfree(suspend);
2491 }
2492 mutex_unlock(&dev->dev_lock);
2493}
2494
2495void free_opal_dev(struct opal_dev *dev)
2496{
2497 if (!dev)
2498 return;
5cc23ed7 2499
7d6d1578 2500 clean_opal_dev(dev);
f829230d
SS
2501 kfree(dev->resp);
2502 kfree(dev->cmd);
7d6d1578
SB
2503 kfree(dev);
2504}
2505EXPORT_SYMBOL(free_opal_dev);
2506
4f1244c8 2507struct opal_dev *init_opal_dev(void *data, sec_send_recv *send_recv)
455a7b23 2508{
4f1244c8
CH
2509 struct opal_dev *dev;
2510
2511 dev = kmalloc(sizeof(*dev), GFP_KERNEL);
2512 if (!dev)
2513 return NULL;
2514
f829230d
SS
2515 /*
2516 * Presumably DMA-able buffers must be cache-aligned. Kmalloc makes
2517 * sure the allocated buffer is DMA-safe in that regard.
2518 */
2519 dev->cmd = kmalloc(IO_BUFFER_LENGTH, GFP_KERNEL);
2520 if (!dev->cmd)
2521 goto err_free_dev;
2522
2523 dev->resp = kmalloc(IO_BUFFER_LENGTH, GFP_KERNEL);
2524 if (!dev->resp)
2525 goto err_free_cmd;
2526
4f1244c8
CH
2527 INIT_LIST_HEAD(&dev->unlk_lst);
2528 mutex_init(&dev->dev_lock);
c6ea7060 2529 dev->flags = 0;
4f1244c8
CH
2530 dev->data = data;
2531 dev->send_recv = send_recv;
2532 if (check_opal_support(dev) != 0) {
f5b37b7c 2533 pr_debug("Opal is not supported on this device\n");
f829230d 2534 goto err_free_resp;
4f1244c8 2535 }
5cc23ed7 2536
4f1244c8 2537 return dev;
f829230d
SS
2538
2539err_free_resp:
2540 kfree(dev->resp);
2541
2542err_free_cmd:
2543 kfree(dev->cmd);
2544
2545err_free_dev:
2546 kfree(dev);
2547
2548 return NULL;
455a7b23
SB
2549}
2550EXPORT_SYMBOL(init_opal_dev);
2551
2552static int opal_secure_erase_locking_range(struct opal_dev *dev,
2553 struct opal_session_info *opal_session)
2554{
eed64951 2555 const struct opal_step erase_steps[] = {
eed64951
JD
2556 { start_auth_opal_session, opal_session },
2557 { get_active_key, &opal_session->opal_key.lr },
2558 { gen_key, },
3db87236 2559 { end_opal_session, }
455a7b23
SB
2560 };
2561 int ret;
2562
3bfeb612
GJ
2563 ret = opal_get_key(dev, &opal_session->opal_key);
2564 if (ret)
2565 return ret;
455a7b23 2566 mutex_lock(&dev->dev_lock);
3db87236 2567 setup_opal_dev(dev);
a80f36cc 2568 ret = execute_steps(dev, erase_steps, ARRAY_SIZE(erase_steps));
455a7b23 2569 mutex_unlock(&dev->dev_lock);
5cc23ed7 2570
455a7b23
SB
2571 return ret;
2572}
2573
9fb10726
GJ
2574static int opal_get_discv(struct opal_dev *dev, struct opal_discovery *discv)
2575{
2576 const struct opal_step discovery0_step = {
2577 opal_discovery0, discv
2578 };
2579 int ret = 0;
2580
2581 mutex_lock(&dev->dev_lock);
2582 setup_opal_dev(dev);
2583 ret = execute_step(dev, &discovery0_step, 0);
2584 mutex_unlock(&dev->dev_lock);
2585 if (ret)
2586 return ret;
2587 return discv->size; /* modified to actual length of data */
2588}
2589
5c82efc1
GJ
2590static int opal_revertlsp(struct opal_dev *dev, struct opal_revert_lsp *rev)
2591{
2592 /* controller will terminate session */
2593 const struct opal_step steps[] = {
2594 { start_admin1LSP_opal_session, &rev->key },
2595 { revert_lsp, rev }
2596 };
2597 int ret;
2598
3bfeb612
GJ
2599 ret = opal_get_key(dev, &rev->key);
2600 if (ret)
2601 return ret;
5c82efc1
GJ
2602 mutex_lock(&dev->dev_lock);
2603 setup_opal_dev(dev);
2604 ret = execute_steps(dev, steps, ARRAY_SIZE(steps));
2605 mutex_unlock(&dev->dev_lock);
2606
2607 return ret;
2608}
2609
455a7b23
SB
2610static int opal_erase_locking_range(struct opal_dev *dev,
2611 struct opal_session_info *opal_session)
2612{
eed64951 2613 const struct opal_step erase_steps[] = {
eed64951
JD
2614 { start_auth_opal_session, opal_session },
2615 { erase_locking_range, opal_session },
3db87236 2616 { end_opal_session, }
455a7b23
SB
2617 };
2618 int ret;
2619
3bfeb612
GJ
2620 ret = opal_get_key(dev, &opal_session->opal_key);
2621 if (ret)
2622 return ret;
455a7b23 2623 mutex_lock(&dev->dev_lock);
3db87236 2624 setup_opal_dev(dev);
a80f36cc 2625 ret = execute_steps(dev, erase_steps, ARRAY_SIZE(erase_steps));
455a7b23 2626 mutex_unlock(&dev->dev_lock);
5cc23ed7 2627
455a7b23
SB
2628 return ret;
2629}
2630
2631static int opal_enable_disable_shadow_mbr(struct opal_dev *dev,
2632 struct opal_mbr_data *opal_mbr)
2633{
78bf4735
DK
2634 u8 enable_disable = opal_mbr->enable_disable == OPAL_MBR_ENABLE ?
2635 OPAL_TRUE : OPAL_FALSE;
2636
eed64951 2637 const struct opal_step mbr_steps[] = {
eed64951 2638 { start_admin1LSP_opal_session, &opal_mbr->key },
78bf4735 2639 { set_mbr_done, &enable_disable },
eed64951
JD
2640 { end_opal_session, },
2641 { start_admin1LSP_opal_session, &opal_mbr->key },
78bf4735 2642 { set_mbr_enable_disable, &enable_disable },
3db87236 2643 { end_opal_session, }
455a7b23
SB
2644 };
2645 int ret;
2646
2647 if (opal_mbr->enable_disable != OPAL_MBR_ENABLE &&
2648 opal_mbr->enable_disable != OPAL_MBR_DISABLE)
2649 return -EINVAL;
2650
3bfeb612
GJ
2651 ret = opal_get_key(dev, &opal_mbr->key);
2652 if (ret)
2653 return ret;
455a7b23 2654 mutex_lock(&dev->dev_lock);
3db87236 2655 setup_opal_dev(dev);
a80f36cc 2656 ret = execute_steps(dev, mbr_steps, ARRAY_SIZE(mbr_steps));
455a7b23 2657 mutex_unlock(&dev->dev_lock);
5cc23ed7 2658
455a7b23
SB
2659 return ret;
2660}
2661
c9888443
JR
2662static int opal_set_mbr_done(struct opal_dev *dev,
2663 struct opal_mbr_done *mbr_done)
2664{
2665 u8 mbr_done_tf = mbr_done->done_flag == OPAL_MBR_DONE ?
2666 OPAL_TRUE : OPAL_FALSE;
2667
2668 const struct opal_step mbr_steps[] = {
2669 { start_admin1LSP_opal_session, &mbr_done->key },
2670 { set_mbr_done, &mbr_done_tf },
2671 { end_opal_session, }
2672 };
2673 int ret;
2674
2675 if (mbr_done->done_flag != OPAL_MBR_DONE &&
2676 mbr_done->done_flag != OPAL_MBR_NOT_DONE)
2677 return -EINVAL;
2678
3bfeb612
GJ
2679 ret = opal_get_key(dev, &mbr_done->key);
2680 if (ret)
2681 return ret;
c9888443
JR
2682 mutex_lock(&dev->dev_lock);
2683 setup_opal_dev(dev);
2684 ret = execute_steps(dev, mbr_steps, ARRAY_SIZE(mbr_steps));
2685 mutex_unlock(&dev->dev_lock);
5cc23ed7 2686
c9888443
JR
2687 return ret;
2688}
2689
a9b25b4c
JR
2690static int opal_write_shadow_mbr(struct opal_dev *dev,
2691 struct opal_shadow_mbr *info)
2692{
2693 const struct opal_step mbr_steps[] = {
2694 { start_admin1LSP_opal_session, &info->key },
2695 { write_shadow_mbr, info },
2696 { end_opal_session, }
2697 };
2698 int ret;
2699
2700 if (info->size == 0)
2701 return 0;
2702
3bfeb612
GJ
2703 ret = opal_get_key(dev, &info->key);
2704 if (ret)
2705 return ret;
a9b25b4c
JR
2706 mutex_lock(&dev->dev_lock);
2707 setup_opal_dev(dev);
2708 ret = execute_steps(dev, mbr_steps, ARRAY_SIZE(mbr_steps));
2709 mutex_unlock(&dev->dev_lock);
5cc23ed7 2710
a9b25b4c
JR
2711 return ret;
2712}
2713
455a7b23
SB
2714static int opal_save(struct opal_dev *dev, struct opal_lock_unlock *lk_unlk)
2715{
2716 struct opal_suspend_data *suspend;
2717
2718 suspend = kzalloc(sizeof(*suspend), GFP_KERNEL);
2719 if (!suspend)
2720 return -ENOMEM;
2721
2722 suspend->unlk = *lk_unlk;
2723 suspend->lr = lk_unlk->session.opal_key.lr;
2724
2725 mutex_lock(&dev->dev_lock);
3db87236 2726 setup_opal_dev(dev);
455a7b23
SB
2727 add_suspend_info(dev, suspend);
2728 mutex_unlock(&dev->dev_lock);
5cc23ed7 2729
455a7b23
SB
2730 return 0;
2731}
2732
2733static int opal_add_user_to_lr(struct opal_dev *dev,
2734 struct opal_lock_unlock *lk_unlk)
2735{
eed64951 2736 const struct opal_step steps[] = {
eed64951
JD
2737 { start_admin1LSP_opal_session, &lk_unlk->session.opal_key },
2738 { add_user_to_lr, lk_unlk },
8be19a02 2739 { add_user_to_lr_ace, lk_unlk },
3db87236 2740 { end_opal_session, }
455a7b23
SB
2741 };
2742 int ret;
2743
2744 if (lk_unlk->l_state != OPAL_RO &&
2745 lk_unlk->l_state != OPAL_RW) {
591c59d1 2746 pr_debug("Locking state was not RO or RW\n");
455a7b23
SB
2747 return -EINVAL;
2748 }
5cc23ed7 2749
b0bfdfc2 2750 if (lk_unlk->session.who < OPAL_USER1 ||
455a7b23 2751 lk_unlk->session.who > OPAL_USER9) {
591c59d1
SB
2752 pr_debug("Authority was not within the range of users: %d\n",
2753 lk_unlk->session.who);
455a7b23
SB
2754 return -EINVAL;
2755 }
5cc23ed7 2756
455a7b23 2757 if (lk_unlk->session.sum) {
591c59d1
SB
2758 pr_debug("%s not supported in sum. Use setup locking range\n",
2759 __func__);
455a7b23
SB
2760 return -EINVAL;
2761 }
2762
3bfeb612
GJ
2763 ret = opal_get_key(dev, &lk_unlk->session.opal_key);
2764 if (ret)
2765 return ret;
455a7b23 2766 mutex_lock(&dev->dev_lock);
3db87236 2767 setup_opal_dev(dev);
a80f36cc 2768 ret = execute_steps(dev, steps, ARRAY_SIZE(steps));
455a7b23 2769 mutex_unlock(&dev->dev_lock);
5cc23ed7 2770
455a7b23
SB
2771 return ret;
2772}
2773
5e4c7cf6 2774static int opal_reverttper(struct opal_dev *dev, struct opal_key *opal, bool psid)
455a7b23 2775{
5e4c7cf6 2776 /* controller will terminate session */
eed64951 2777 const struct opal_step revert_steps[] = {
eed64951 2778 { start_SIDASP_opal_session, opal },
5e4c7cf6 2779 { revert_tper, }
455a7b23 2780 };
5e4c7cf6
RR
2781 const struct opal_step psid_revert_steps[] = {
2782 { start_PSID_opal_session, opal },
2783 { revert_tper, }
2784 };
2785
455a7b23
SB
2786 int ret;
2787
3bfeb612
GJ
2788 ret = opal_get_key(dev, opal);
2789
2790 if (ret)
2791 return ret;
455a7b23 2792 mutex_lock(&dev->dev_lock);
3db87236 2793 setup_opal_dev(dev);
5e4c7cf6
RR
2794 if (psid)
2795 ret = execute_steps(dev, psid_revert_steps,
2796 ARRAY_SIZE(psid_revert_steps));
2797 else
2798 ret = execute_steps(dev, revert_steps,
2799 ARRAY_SIZE(revert_steps));
455a7b23 2800 mutex_unlock(&dev->dev_lock);
7d6d1578
SB
2801
2802 /*
2803 * If we successfully reverted lets clean
2804 * any saved locking ranges.
2805 */
2806 if (!ret)
2807 clean_opal_dev(dev);
2808
455a7b23
SB
2809 return ret;
2810}
2811
eed64951
JD
2812static int __opal_lock_unlock(struct opal_dev *dev,
2813 struct opal_lock_unlock *lk_unlk)
455a7b23 2814{
eed64951 2815 const struct opal_step unlock_steps[] = {
eed64951
JD
2816 { start_auth_opal_session, &lk_unlk->session },
2817 { lock_unlock_locking_range, lk_unlk },
3db87236 2818 { end_opal_session, }
455a7b23 2819 };
eed64951 2820 const struct opal_step unlock_sum_steps[] = {
eed64951
JD
2821 { start_auth_opal_session, &lk_unlk->session },
2822 { lock_unlock_locking_range_sum, lk_unlk },
3db87236 2823 { end_opal_session, }
455a7b23
SB
2824 };
2825
3db87236 2826 if (lk_unlk->session.sum)
a80f36cc
DK
2827 return execute_steps(dev, unlock_sum_steps,
2828 ARRAY_SIZE(unlock_sum_steps));
3db87236 2829 else
a80f36cc
DK
2830 return execute_steps(dev, unlock_steps,
2831 ARRAY_SIZE(unlock_steps));
455a7b23
SB
2832}
2833
dbec491b
SB
2834static int __opal_set_mbr_done(struct opal_dev *dev, struct opal_key *key)
2835{
78bf4735 2836 u8 mbr_done_tf = OPAL_TRUE;
1e815b33 2837 const struct opal_step mbrdone_step[] = {
dbec491b
SB
2838 { start_admin1LSP_opal_session, key },
2839 { set_mbr_done, &mbr_done_tf },
3db87236 2840 { end_opal_session, }
dbec491b
SB
2841 };
2842
a80f36cc 2843 return execute_steps(dev, mbrdone_step, ARRAY_SIZE(mbrdone_step));
dbec491b
SB
2844}
2845
c1f480b2
LB
2846static void opal_lock_check_for_saved_key(struct opal_dev *dev,
2847 struct opal_lock_unlock *lk_unlk)
2848{
2849 struct opal_suspend_data *iter;
2850
2851 if (lk_unlk->l_state != OPAL_LK ||
2852 lk_unlk->session.opal_key.key_len > 0)
2853 return;
2854
2855 /*
2856 * Usually when closing a crypto device (eg: dm-crypt with LUKS) the
2857 * volume key is not required, as it requires root privileges anyway,
2858 * and root can deny access to a disk in many ways regardless.
2859 * Requiring the volume key to lock the device is a peculiarity of the
2860 * OPAL specification. Given we might already have saved the key if
2861 * the user requested it via the 'IOC_OPAL_SAVE' ioctl, we can use
2862 * that key to lock the device if no key was provided here, the
2863 * locking range matches and the appropriate flag was passed with
2864 * 'IOC_OPAL_SAVE'.
2865 * This allows integrating OPAL with tools and libraries that are used
2866 * to the common behaviour and do not ask for the volume key when
2867 * closing a device.
2868 */
2869 setup_opal_dev(dev);
2870 list_for_each_entry(iter, &dev->unlk_lst, node) {
2871 if ((iter->unlk.flags & OPAL_SAVE_FOR_LOCK) &&
2872 iter->lr == lk_unlk->session.opal_key.lr &&
2873 iter->unlk.session.opal_key.key_len > 0) {
2874 lk_unlk->session.opal_key.key_len =
2875 iter->unlk.session.opal_key.key_len;
2876 memcpy(lk_unlk->session.opal_key.key,
2877 iter->unlk.session.opal_key.key,
2878 iter->unlk.session.opal_key.key_len);
2879 break;
2880 }
2881 }
2882}
2883
eed64951
JD
2884static int opal_lock_unlock(struct opal_dev *dev,
2885 struct opal_lock_unlock *lk_unlk)
455a7b23 2886{
455a7b23
SB
2887 int ret;
2888
15ddffcb 2889 if (lk_unlk->session.who > OPAL_USER9)
455a7b23
SB
2890 return -EINVAL;
2891
2892 mutex_lock(&dev->dev_lock);
c1f480b2 2893 opal_lock_check_for_saved_key(dev, lk_unlk);
4eaf0932
MB
2894 ret = opal_get_key(dev, &lk_unlk->session.opal_key);
2895 if (!ret)
2896 ret = __opal_lock_unlock(dev, lk_unlk);
455a7b23 2897 mutex_unlock(&dev->dev_lock);
5cc23ed7 2898
455a7b23
SB
2899 return ret;
2900}
2901
2902static int opal_take_ownership(struct opal_dev *dev, struct opal_key *opal)
2903{
eed64951 2904 const struct opal_step owner_steps[] = {
eed64951
JD
2905 { start_anybodyASP_opal_session, },
2906 { get_msid_cpin_pin, },
2907 { end_opal_session, },
2908 { start_SIDASP_opal_session, opal },
2909 { set_sid_cpin_pin, opal },
3db87236 2910 { end_opal_session, }
455a7b23 2911 };
455a7b23
SB
2912 int ret;
2913
2914 if (!dev)
2915 return -ENODEV;
2916
3bfeb612
GJ
2917 ret = opal_get_key(dev, opal);
2918 if (ret)
2919 return ret;
455a7b23 2920 mutex_lock(&dev->dev_lock);
3db87236 2921 setup_opal_dev(dev);
a80f36cc 2922 ret = execute_steps(dev, owner_steps, ARRAY_SIZE(owner_steps));
455a7b23 2923 mutex_unlock(&dev->dev_lock);
5cc23ed7 2924
455a7b23
SB
2925 return ret;
2926}
2927
1e815b33
DK
2928static int opal_activate_lsp(struct opal_dev *dev,
2929 struct opal_lr_act *opal_lr_act)
455a7b23 2930{
eed64951 2931 const struct opal_step active_steps[] = {
eed64951
JD
2932 { start_SIDASP_opal_session, &opal_lr_act->key },
2933 { get_lsp_lifecycle, },
2934 { activate_lsp, opal_lr_act },
3db87236 2935 { end_opal_session, }
455a7b23
SB
2936 };
2937 int ret;
2938
2939 if (!opal_lr_act->num_lrs || opal_lr_act->num_lrs > OPAL_MAX_LRS)
2940 return -EINVAL;
2941
3bfeb612
GJ
2942 ret = opal_get_key(dev, &opal_lr_act->key);
2943 if (ret)
2944 return ret;
455a7b23 2945 mutex_lock(&dev->dev_lock);
3db87236 2946 setup_opal_dev(dev);
a80f36cc 2947 ret = execute_steps(dev, active_steps, ARRAY_SIZE(active_steps));
455a7b23 2948 mutex_unlock(&dev->dev_lock);
5cc23ed7 2949
455a7b23
SB
2950 return ret;
2951}
2952
2953static int opal_setup_locking_range(struct opal_dev *dev,
2954 struct opal_user_lr_setup *opal_lrs)
2955{
eed64951 2956 const struct opal_step lr_steps[] = {
eed64951
JD
2957 { start_auth_opal_session, &opal_lrs->session },
2958 { setup_locking_range, opal_lrs },
3db87236 2959 { end_opal_session, }
455a7b23
SB
2960 };
2961 int ret;
2962
3bfeb612
GJ
2963 ret = opal_get_key(dev, &opal_lrs->session.opal_key);
2964 if (ret)
2965 return ret;
455a7b23 2966 mutex_lock(&dev->dev_lock);
3db87236 2967 setup_opal_dev(dev);
a80f36cc 2968 ret = execute_steps(dev, lr_steps, ARRAY_SIZE(lr_steps));
455a7b23 2969 mutex_unlock(&dev->dev_lock);
5cc23ed7 2970
455a7b23
SB
2971 return ret;
2972}
2973
4c4dd04e
OK
2974static int opal_locking_range_status(struct opal_dev *dev,
2975 struct opal_lr_status *opal_lrst,
2976 void __user *data)
2977{
2978 const struct opal_step lr_steps[] = {
2979 { start_auth_opal_session, &opal_lrst->session },
2980 { locking_range_status, opal_lrst },
2981 { end_opal_session, }
2982 };
2983 int ret;
2984
2985 mutex_lock(&dev->dev_lock);
2986 setup_opal_dev(dev);
2987 ret = execute_steps(dev, lr_steps, ARRAY_SIZE(lr_steps));
2988 mutex_unlock(&dev->dev_lock);
2989
2990 /* skip session info when copying back to uspace */
2991 if (!ret && copy_to_user(data + offsetof(struct opal_lr_status, range_start),
2992 (void *)opal_lrst + offsetof(struct opal_lr_status, range_start),
2993 sizeof(*opal_lrst) - offsetof(struct opal_lr_status, range_start))) {
2994 pr_debug("Error copying status to userspace\n");
2995 return -EFAULT;
2996 }
2997
2998 return ret;
2999}
3000
455a7b23
SB
3001static int opal_set_new_pw(struct opal_dev *dev, struct opal_new_pw *opal_pw)
3002{
eed64951 3003 const struct opal_step pw_steps[] = {
eed64951
JD
3004 { start_auth_opal_session, &opal_pw->session },
3005 { set_new_pw, &opal_pw->new_user_pw },
3db87236 3006 { end_opal_session, }
455a7b23 3007 };
455a7b23
SB
3008 int ret;
3009
15ddffcb 3010 if (opal_pw->session.who > OPAL_USER9 ||
455a7b23
SB
3011 opal_pw->new_user_pw.who > OPAL_USER9)
3012 return -EINVAL;
3013
3014 mutex_lock(&dev->dev_lock);
3db87236 3015 setup_opal_dev(dev);
a80f36cc 3016 ret = execute_steps(dev, pw_steps, ARRAY_SIZE(pw_steps));
455a7b23 3017 mutex_unlock(&dev->dev_lock);
5cc23ed7 3018
3bfeb612
GJ
3019 if (ret)
3020 return ret;
3021
5dd33972
GJ
3022 /* update keyring and key store with new password */
3023 ret = sed_write_key(OPAL_AUTH_KEY,
3024 opal_pw->new_user_pw.opal_key.key,
3025 opal_pw->new_user_pw.opal_key.key_len);
3026 if (ret != -EOPNOTSUPP)
3027 pr_warn("error updating SED key: %d\n", ret);
3028
3bfeb612
GJ
3029 ret = update_sed_opal_key(OPAL_AUTH_KEY,
3030 opal_pw->new_user_pw.opal_key.key,
3031 opal_pw->new_user_pw.opal_key.key_len);
3032
455a7b23
SB
3033 return ret;
3034}
3035
3036static int opal_activate_user(struct opal_dev *dev,
3037 struct opal_session_info *opal_session)
3038{
eed64951 3039 const struct opal_step act_steps[] = {
eed64951
JD
3040 { start_admin1LSP_opal_session, &opal_session->opal_key },
3041 { internal_activate_user, opal_session },
3db87236 3042 { end_opal_session, }
455a7b23 3043 };
455a7b23
SB
3044 int ret;
3045
3046 /* We can't activate Admin1 it's active as manufactured */
b0bfdfc2 3047 if (opal_session->who < OPAL_USER1 ||
455a7b23 3048 opal_session->who > OPAL_USER9) {
591c59d1 3049 pr_debug("Who was not a valid user: %d\n", opal_session->who);
455a7b23
SB
3050 return -EINVAL;
3051 }
3052
3bfeb612
GJ
3053 ret = opal_get_key(dev, &opal_session->opal_key);
3054 if (ret)
3055 return ret;
455a7b23 3056 mutex_lock(&dev->dev_lock);
3db87236 3057 setup_opal_dev(dev);
a80f36cc 3058 ret = execute_steps(dev, act_steps, ARRAY_SIZE(act_steps));
455a7b23 3059 mutex_unlock(&dev->dev_lock);
5cc23ed7 3060
455a7b23
SB
3061 return ret;
3062}
3063
3064bool opal_unlock_from_suspend(struct opal_dev *dev)
3065{
3066 struct opal_suspend_data *suspend;
455a7b23
SB
3067 bool was_failure = false;
3068 int ret = 0;
3069
3070 if (!dev)
3071 return false;
5cc23ed7 3072
c6ea7060 3073 if (!(dev->flags & OPAL_FL_SUPPORTED))
455a7b23
SB
3074 return false;
3075
3076 mutex_lock(&dev->dev_lock);
3db87236 3077 setup_opal_dev(dev);
455a7b23
SB
3078
3079 list_for_each_entry(suspend, &dev->unlk_lst, node) {
455a7b23
SB
3080 dev->tsn = 0;
3081 dev->hsn = 0;
3082
eed64951 3083 ret = __opal_lock_unlock(dev, &suspend->unlk);
455a7b23 3084 if (ret) {
591c59d1
SB
3085 pr_debug("Failed to unlock LR %hhu with sum %d\n",
3086 suspend->unlk.session.opal_key.lr,
3087 suspend->unlk.session.sum);
455a7b23
SB
3088 was_failure = true;
3089 }
5cc23ed7 3090
c6ea7060 3091 if (dev->flags & OPAL_FL_MBR_ENABLED) {
dbec491b
SB
3092 ret = __opal_set_mbr_done(dev, &suspend->unlk.session.opal_key);
3093 if (ret)
3094 pr_debug("Failed to set MBR Done in S3 resume\n");
3095 }
455a7b23
SB
3096 }
3097 mutex_unlock(&dev->dev_lock);
5cc23ed7 3098
455a7b23
SB
3099 return was_failure;
3100}
3101EXPORT_SYMBOL(opal_unlock_from_suspend);
3102
51f421c8
RR
3103static int opal_read_table(struct opal_dev *dev,
3104 struct opal_read_write_table *rw_tbl)
3105{
3106 const struct opal_step read_table_steps[] = {
3107 { start_admin1LSP_opal_session, &rw_tbl->key },
3108 { read_table_data, rw_tbl },
3109 { end_opal_session, }
3110 };
3111 int ret = 0;
3112
3113 if (!rw_tbl->size)
3114 return ret;
3115
3116 return execute_steps(dev, read_table_steps,
3117 ARRAY_SIZE(read_table_steps));
3118}
3119
3120static int opal_write_table(struct opal_dev *dev,
3121 struct opal_read_write_table *rw_tbl)
3122{
3123 const struct opal_step write_table_steps[] = {
3124 { start_admin1LSP_opal_session, &rw_tbl->key },
3125 { write_table_data, rw_tbl },
3126 { end_opal_session, }
3127 };
3128 int ret = 0;
3129
3130 if (!rw_tbl->size)
3131 return ret;
3132
3133 return execute_steps(dev, write_table_steps,
3134 ARRAY_SIZE(write_table_steps));
3135}
3136
3137static int opal_generic_read_write_table(struct opal_dev *dev,
3138 struct opal_read_write_table *rw_tbl)
3139{
3140 int ret, bit_set;
3141
3bfeb612
GJ
3142 ret = opal_get_key(dev, &rw_tbl->key);
3143 if (ret)
3144 return ret;
51f421c8
RR
3145 mutex_lock(&dev->dev_lock);
3146 setup_opal_dev(dev);
3147
3148 bit_set = fls64(rw_tbl->flags) - 1;
3149 switch (bit_set) {
3150 case OPAL_READ_TABLE:
3151 ret = opal_read_table(dev, rw_tbl);
3152 break;
3153 case OPAL_WRITE_TABLE:
3154 ret = opal_write_table(dev, rw_tbl);
3155 break;
3156 default:
3157 pr_debug("Invalid bit set in the flag (%016llx).\n",
3158 rw_tbl->flags);
3159 ret = -EINVAL;
3160 break;
3161 }
3162
3163 mutex_unlock(&dev->dev_lock);
3164
3165 return ret;
3166}
3167
c6ea7060 3168static int opal_get_status(struct opal_dev *dev, void __user *data)
3169{
3170 struct opal_status sts = {0};
3171
3172 /*
3173 * check_opal_support() error is not fatal,
3174 * !dev->supported is a valid condition
3175 */
3176 if (!check_opal_support(dev))
3177 sts.flags = dev->flags;
3178 if (copy_to_user(data, &sts, sizeof(sts))) {
3179 pr_debug("Error copying status to userspace\n");
3180 return -EFAULT;
3181 }
3182 return 0;
3183}
3184
9e05a259
OK
3185static int opal_get_geometry(struct opal_dev *dev, void __user *data)
3186{
3187 struct opal_geometry geo = {0};
3188
3189 if (check_opal_support(dev))
3190 return -EINVAL;
3191
3192 geo.align = dev->align_required;
3193 geo.logical_block_size = dev->logical_block_size;
3194 geo.alignment_granularity = dev->align;
3195 geo.lowest_aligned_lba = dev->lowest_lba;
3196
3197 if (copy_to_user(data, &geo, sizeof(geo))) {
3198 pr_debug("Error copying geometry data to userspace\n");
3199 return -EFAULT;
3200 }
3201
3202 return 0;
3203}
3204
e225c20e 3205int sed_ioctl(struct opal_dev *dev, unsigned int cmd, void __user *arg)
455a7b23 3206{
e225c20e
SB
3207 void *p;
3208 int ret = -ENOTTY;
455a7b23
SB
3209
3210 if (!capable(CAP_SYS_ADMIN))
3211 return -EACCES;
4f1244c8 3212 if (!dev)
3bfeb612 3213 return -EOPNOTSUPP;
c6ea7060 3214 if (!(dev->flags & OPAL_FL_SUPPORTED))
3bfeb612 3215 return -EOPNOTSUPP;
455a7b23 3216
c6ea7060 3217 if (cmd & IOC_IN) {
3218 p = memdup_user(arg, _IOC_SIZE(cmd));
3219 if (IS_ERR(p))
3220 return PTR_ERR(p);
3221 }
455a7b23 3222
e225c20e
SB
3223 switch (cmd) {
3224 case IOC_OPAL_SAVE:
3225 ret = opal_save(dev, p);
3226 break;
3227 case IOC_OPAL_LOCK_UNLOCK:
3228 ret = opal_lock_unlock(dev, p);
3229 break;
3230 case IOC_OPAL_TAKE_OWNERSHIP:
3231 ret = opal_take_ownership(dev, p);
3232 break;
3233 case IOC_OPAL_ACTIVATE_LSP:
3234 ret = opal_activate_lsp(dev, p);
3235 break;
3236 case IOC_OPAL_SET_PW:
3237 ret = opal_set_new_pw(dev, p);
3238 break;
3239 case IOC_OPAL_ACTIVATE_USR:
3240 ret = opal_activate_user(dev, p);
3241 break;
3242 case IOC_OPAL_REVERT_TPR:
5e4c7cf6 3243 ret = opal_reverttper(dev, p, false);
e225c20e
SB
3244 break;
3245 case IOC_OPAL_LR_SETUP:
3246 ret = opal_setup_locking_range(dev, p);
3247 break;
3248 case IOC_OPAL_ADD_USR_TO_LR:
3249 ret = opal_add_user_to_lr(dev, p);
3250 break;
3251 case IOC_OPAL_ENABLE_DISABLE_MBR:
3252 ret = opal_enable_disable_shadow_mbr(dev, p);
3253 break;
c9888443
JR
3254 case IOC_OPAL_MBR_DONE:
3255 ret = opal_set_mbr_done(dev, p);
3256 break;
a9b25b4c
JR
3257 case IOC_OPAL_WRITE_SHADOW_MBR:
3258 ret = opal_write_shadow_mbr(dev, p);
3259 break;
e225c20e
SB
3260 case IOC_OPAL_ERASE_LR:
3261 ret = opal_erase_locking_range(dev, p);
3262 break;
3263 case IOC_OPAL_SECURE_ERASE_LR:
3264 ret = opal_secure_erase_locking_range(dev, p);
3265 break;
5e4c7cf6
RR
3266 case IOC_OPAL_PSID_REVERT_TPR:
3267 ret = opal_reverttper(dev, p, true);
3268 break;
51f421c8
RR
3269 case IOC_OPAL_GENERIC_TABLE_RW:
3270 ret = opal_generic_read_write_table(dev, p);
3271 break;
c6ea7060 3272 case IOC_OPAL_GET_STATUS:
3273 ret = opal_get_status(dev, arg);
3274 break;
4c4dd04e
OK
3275 case IOC_OPAL_GET_LR_STATUS:
3276 ret = opal_locking_range_status(dev, p, arg);
3277 break;
9e05a259
OK
3278 case IOC_OPAL_GET_GEOMETRY:
3279 ret = opal_get_geometry(dev, arg);
3280 break;
5c82efc1
GJ
3281 case IOC_OPAL_REVERT_LSP:
3282 ret = opal_revertlsp(dev, p);
3283 break;
9fb10726
GJ
3284 case IOC_OPAL_DISCOVERY:
3285 ret = opal_get_discv(dev, p);
3286 break;
3287
455a7b23 3288 default:
591c59d1 3289 break;
455a7b23 3290 }
e225c20e 3291
c6ea7060 3292 if (cmd & IOC_IN)
3293 kfree(p);
e225c20e 3294 return ret;
455a7b23
SB
3295}
3296EXPORT_SYMBOL_GPL(sed_ioctl);
3bfeb612
GJ
3297
3298static int __init sed_opal_init(void)
3299{
3300 struct key *kr;
5dd33972
GJ
3301 char init_sed_key[OPAL_KEY_MAX];
3302 int keylen = OPAL_KEY_MAX - 1;
3bfeb612
GJ
3303
3304 kr = keyring_alloc(".sed_opal",
3305 GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, current_cred(),
3306 (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW |
3307 KEY_USR_READ | KEY_USR_SEARCH | KEY_USR_WRITE,
3308 KEY_ALLOC_NOT_IN_QUOTA,
3309 NULL, NULL);
3310 if (IS_ERR(kr))
3311 return PTR_ERR(kr);
3312
3313 sed_opal_keyring = kr;
3314
5dd33972
GJ
3315 if (sed_read_key(OPAL_AUTH_KEY, init_sed_key, &keylen) < 0) {
3316 memset(init_sed_key, '\0', sizeof(init_sed_key));
3317 keylen = OPAL_KEY_MAX - 1;
3318 }
3319
3320 return update_sed_opal_key(OPAL_AUTH_KEY, init_sed_key, keylen);
3bfeb612
GJ
3321}
3322late_initcall(sed_opal_init);