block/sed: Use ssize_t on atom parsers to return errors
[GitHub/LineageOS/android_kernel_motorola_exynos9610.git] / block / sed-opal.c
CommitLineData
455a7b23
SB
1/*
2 * Copyright © 2016 Intel Corporation
3 *
4 * Authors:
5 * Scott Bauer <scott.bauer@intel.com>
6 * Rafael Antognolli <rafael.antognolli@intel.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms and conditions of the GNU General Public License,
10 * version 2, as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
16 */
17
18#define pr_fmt(fmt) KBUILD_MODNAME ":OPAL: " fmt
19
20#include <linux/delay.h>
21#include <linux/device.h>
22#include <linux/kernel.h>
23#include <linux/list.h>
24#include <linux/genhd.h>
25#include <linux/slab.h>
26#include <linux/uaccess.h>
27#include <uapi/linux/sed-opal.h>
28#include <linux/sed-opal.h>
29#include <linux/string.h>
30#include <linux/kdev_t.h>
31
32#include "opal_proto.h"
33
4f1244c8
CH
34#define IO_BUFFER_LENGTH 2048
35#define MAX_TOKS 64
36
37typedef int (*opal_step)(struct opal_dev *dev);
38
39enum opal_atom_width {
40 OPAL_WIDTH_TINY,
41 OPAL_WIDTH_SHORT,
42 OPAL_WIDTH_MEDIUM,
43 OPAL_WIDTH_LONG,
44 OPAL_WIDTH_TOKEN
45};
46
47/*
48 * On the parsed response, we don't store again the toks that are already
49 * stored in the response buffer. Instead, for each token, we just store a
50 * pointer to the position in the buffer where the token starts, and the size
51 * of the token in bytes.
52 */
53struct opal_resp_tok {
54 const u8 *pos;
55 size_t len;
56 enum opal_response_token type;
57 enum opal_atom_width width;
58 union {
59 u64 u;
60 s64 s;
61 } stored;
62};
63
64/*
65 * From the response header it's not possible to know how many tokens there are
66 * on the payload. So we hardcode that the maximum will be MAX_TOKS, and later
67 * if we start dealing with messages that have more than that, we can increase
68 * this number. This is done to avoid having to make two passes through the
69 * response, the first one counting how many tokens we have and the second one
70 * actually storing the positions.
71 */
72struct parsed_resp {
73 int num;
74 struct opal_resp_tok toks[MAX_TOKS];
75};
76
77struct opal_dev {
78 bool supported;
79
80 void *data;
81 sec_send_recv *send_recv;
82
83 const opal_step *funcs;
84 void **func_data;
85 int state;
86 struct mutex dev_lock;
87 u16 comid;
88 u32 hsn;
89 u32 tsn;
90 u64 align;
91 u64 lowest_lba;
92
93 size_t pos;
94 u8 cmd[IO_BUFFER_LENGTH];
95 u8 resp[IO_BUFFER_LENGTH];
96
97 struct parsed_resp parsed;
98 size_t prev_d_len;
99 void *prev_data;
100
101 struct list_head unlk_lst;
102};
103
104
455a7b23
SB
105static const u8 opaluid[][OPAL_UID_LENGTH] = {
106 /* users */
107 [OPAL_SMUID_UID] =
108 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff },
109 [OPAL_THISSP_UID] =
110 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
111 [OPAL_ADMINSP_UID] =
112 { 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x00, 0x01 },
113 [OPAL_LOCKINGSP_UID] =
114 { 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x00, 0x02 },
115 [OPAL_ENTERPRISE_LOCKINGSP_UID] =
116 { 0x00, 0x00, 0x02, 0x05, 0x00, 0x01, 0x00, 0x01 },
117 [OPAL_ANYBODY_UID] =
118 { 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x01 },
119 [OPAL_SID_UID] =
120 { 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x06 },
121 [OPAL_ADMIN1_UID] =
122 { 0x00, 0x00, 0x00, 0x09, 0x00, 0x01, 0x00, 0x01 },
123 [OPAL_USER1_UID] =
124 { 0x00, 0x00, 0x00, 0x09, 0x00, 0x03, 0x00, 0x01 },
125 [OPAL_USER2_UID] =
126 { 0x00, 0x00, 0x00, 0x09, 0x00, 0x03, 0x00, 0x02 },
127 [OPAL_PSID_UID] =
128 { 0x00, 0x00, 0x00, 0x09, 0x00, 0x01, 0xff, 0x01 },
129 [OPAL_ENTERPRISE_BANDMASTER0_UID] =
130 { 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x80, 0x01 },
131 [OPAL_ENTERPRISE_ERASEMASTER_UID] =
132 { 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x84, 0x01 },
133
134 /* tables */
135
136 [OPAL_LOCKINGRANGE_GLOBAL] =
137 { 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x00, 0x01 },
138 [OPAL_LOCKINGRANGE_ACE_RDLOCKED] =
139 { 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0xE0, 0x01 },
140 [OPAL_LOCKINGRANGE_ACE_WRLOCKED] =
141 { 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0xE8, 0x01 },
142 [OPAL_MBRCONTROL] =
143 { 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x00, 0x01 },
144 [OPAL_MBR] =
145 { 0x00, 0x00, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00 },
146 [OPAL_AUTHORITY_TABLE] =
147 { 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00},
148 [OPAL_C_PIN_TABLE] =
149 { 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00},
150 [OPAL_LOCKING_INFO_TABLE] =
151 { 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x01 },
152 [OPAL_ENTERPRISE_LOCKING_INFO_TABLE] =
153 { 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00 },
154
155 /* C_PIN_TABLE object ID's */
156
157 [OPAL_C_PIN_MSID] =
158 { 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x84, 0x02},
159 [OPAL_C_PIN_SID] =
160 { 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x01},
161 [OPAL_C_PIN_ADMIN1] =
162 { 0x00, 0x00, 0x00, 0x0B, 0x00, 0x01, 0x00, 0x01},
163
164 /* half UID's (only first 4 bytes used) */
165
166 [OPAL_HALF_UID_AUTHORITY_OBJ_REF] =
167 { 0x00, 0x00, 0x0C, 0x05, 0xff, 0xff, 0xff, 0xff },
168 [OPAL_HALF_UID_BOOLEAN_ACE] =
169 { 0x00, 0x00, 0x04, 0x0E, 0xff, 0xff, 0xff, 0xff },
170
171 /* special value for omitted optional parameter */
172 [OPAL_UID_HEXFF] =
173 { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
174};
175
176/*
177 * TCG Storage SSC Methods.
178 * Derived from: TCG_Storage_Architecture_Core_Spec_v2.01_r1.00
179 * Section: 6.3 Assigned UIDs
180 */
181static const u8 opalmethod[][OPAL_UID_LENGTH] = {
182 [OPAL_PROPERTIES] =
183 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x01 },
184 [OPAL_STARTSESSION] =
185 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x02 },
186 [OPAL_REVERT] =
187 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x02, 0x02 },
188 [OPAL_ACTIVATE] =
189 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x02, 0x03 },
190 [OPAL_EGET] =
191 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06 },
192 [OPAL_ESET] =
193 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07 },
194 [OPAL_NEXT] =
195 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08 },
196 [OPAL_EAUTHENTICATE] =
197 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0c },
198 [OPAL_GETACL] =
199 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0d },
200 [OPAL_GENKEY] =
201 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x10 },
202 [OPAL_REVERTSP] =
203 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x11 },
204 [OPAL_GET] =
205 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x16 },
206 [OPAL_SET] =
207 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x17 },
208 [OPAL_AUTHENTICATE] =
209 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x1c },
210 [OPAL_RANDOM] =
211 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x01 },
212 [OPAL_ERASE] =
213 { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x08, 0x03 },
214};
215
216typedef int (cont_fn)(struct opal_dev *dev);
217
218static int end_opal_session_error(struct opal_dev *dev);
219
220struct opal_suspend_data {
221 struct opal_lock_unlock unlk;
222 u8 lr;
223 struct list_head node;
224};
225
226/*
227 * Derived from:
228 * TCG_Storage_Architecture_Core_Spec_v2.01_r1.00
229 * Section: 5.1.5 Method Status Codes
230 */
231static const char * const opal_errors[] = {
232 "Success",
233 "Not Authorized",
234 "Unknown Error",
235 "SP Busy",
236 "SP Failed",
237 "SP Disabled",
238 "SP Frozen",
239 "No Sessions Available",
240 "Uniqueness Conflict",
241 "Insufficient Space",
242 "Insufficient Rows",
243 "Invalid Function",
244 "Invalid Parameter",
245 "Invalid Reference",
246 "Unknown Error",
247 "TPER Malfunction",
248 "Transaction Failure",
249 "Response Overflow",
250 "Authority Locked Out",
251};
252
253static const char *opal_error_to_human(int error)
254{
255 if (error == 0x3f)
256 return "Failed";
257
258 if (error >= ARRAY_SIZE(opal_errors) || error < 0)
259 return "Unknown Error";
260
261 return opal_errors[error];
262}
263
264static void print_buffer(const u8 *ptr, u32 length)
265{
266#ifdef DEBUG
267 print_hex_dump_bytes("OPAL: ", DUMP_PREFIX_OFFSET, ptr, length);
268 pr_debug("\n");
269#endif
270}
271
272static bool check_tper(const void *data)
273{
274 const struct d0_tper_features *tper = data;
275 u8 flags = tper->supported_features;
276
277 if (!(flags & TPER_SYNC_SUPPORTED)) {
278 pr_err("TPer sync not supported. flags = %d\n",
279 tper->supported_features);
280 return false;
281 }
282
283 return true;
284}
285
286static bool check_sum(const void *data)
287{
288 const struct d0_single_user_mode *sum = data;
289 u32 nlo = be32_to_cpu(sum->num_locking_objects);
290
291 if (nlo == 0) {
292 pr_err("Need at least one locking object.\n");
293 return false;
294 }
295
296 pr_debug("Number of locking objects: %d\n", nlo);
297
298 return true;
299}
300
301static u16 get_comid_v100(const void *data)
302{
303 const struct d0_opal_v100 *v100 = data;
304
305 return be16_to_cpu(v100->baseComID);
306}
307
308static u16 get_comid_v200(const void *data)
309{
310 const struct d0_opal_v200 *v200 = data;
311
312 return be16_to_cpu(v200->baseComID);
313}
314
315static int opal_send_cmd(struct opal_dev *dev)
316{
4f1244c8 317 return dev->send_recv(dev->data, dev->comid, TCG_SECP_01,
455a7b23
SB
318 dev->cmd, IO_BUFFER_LENGTH,
319 true);
320}
321
322static int opal_recv_cmd(struct opal_dev *dev)
323{
4f1244c8 324 return dev->send_recv(dev->data, dev->comid, TCG_SECP_01,
455a7b23
SB
325 dev->resp, IO_BUFFER_LENGTH,
326 false);
327}
328
329static int opal_recv_check(struct opal_dev *dev)
330{
331 size_t buflen = IO_BUFFER_LENGTH;
332 void *buffer = dev->resp;
333 struct opal_header *hdr = buffer;
334 int ret;
335
336 do {
337 pr_debug("Sent OPAL command: outstanding=%d, minTransfer=%d\n",
338 hdr->cp.outstandingData,
339 hdr->cp.minTransfer);
340
341 if (hdr->cp.outstandingData == 0 ||
342 hdr->cp.minTransfer != 0)
343 return 0;
344
345 memset(buffer, 0, buflen);
346 ret = opal_recv_cmd(dev);
347 } while (!ret);
348
349 return ret;
350}
351
352static int opal_send_recv(struct opal_dev *dev, cont_fn *cont)
353{
354 int ret;
355
356 ret = opal_send_cmd(dev);
357 if (ret)
358 return ret;
359 ret = opal_recv_cmd(dev);
360 if (ret)
361 return ret;
362 ret = opal_recv_check(dev);
363 if (ret)
364 return ret;
365 return cont(dev);
366}
367
368static void check_geometry(struct opal_dev *dev, const void *data)
369{
370 const struct d0_geometry_features *geo = data;
371
372 dev->align = geo->alignment_granularity;
373 dev->lowest_lba = geo->lowest_aligned_lba;
374}
375
376static int next(struct opal_dev *dev)
377{
378 opal_step func;
379 int error = 0;
380
381 do {
382 func = dev->funcs[dev->state];
383 if (!func)
384 break;
385
386 error = func(dev);
387 if (error) {
388 pr_err("Error on step function: %d with error %d: %s\n",
389 dev->state, error,
390 opal_error_to_human(error));
391
392 /* For each OPAL command we do a discovery0 then we
393 * start some sort of session.
394 * If we haven't passed state 1 then there was an error
395 * on discovery0 or during the attempt to start a
396 * session. Therefore we shouldn't attempt to terminate
397 * a session, as one has not yet been created.
398 */
399 if (dev->state > 1)
400 return end_opal_session_error(dev);
401 }
402 dev->state++;
403 } while (!error);
404
405 return error;
406}
407
408static int opal_discovery0_end(struct opal_dev *dev)
409{
410 bool found_com_id = false, supported = true, single_user = false;
411 const struct d0_header *hdr = (struct d0_header *)dev->resp;
412 const u8 *epos = dev->resp, *cpos = dev->resp;
413 u16 comid = 0;
414
415 print_buffer(dev->resp, be32_to_cpu(hdr->length));
416
417 epos += be32_to_cpu(hdr->length); /* end of buffer */
418 cpos += sizeof(*hdr); /* current position on buffer */
419
420 while (cpos < epos && supported) {
421 const struct d0_features *body =
422 (const struct d0_features *)cpos;
423
424 switch (be16_to_cpu(body->code)) {
425 case FC_TPER:
426 supported = check_tper(body->features);
427 break;
428 case FC_SINGLEUSER:
429 single_user = check_sum(body->features);
430 break;
431 case FC_GEOMETRY:
432 check_geometry(dev, body);
433 break;
434 case FC_LOCKING:
435 case FC_ENTERPRISE:
436 case FC_DATASTORE:
437 /* some ignored properties */
438 pr_debug("Found OPAL feature description: %d\n",
439 be16_to_cpu(body->code));
440 break;
441 case FC_OPALV100:
442 comid = get_comid_v100(body->features);
443 found_com_id = true;
444 break;
445 case FC_OPALV200:
446 comid = get_comid_v200(body->features);
447 found_com_id = true;
448 break;
449 case 0xbfff ... 0xffff:
450 /* vendor specific, just ignore */
451 break;
452 default:
453 pr_debug("OPAL Unknown feature: %d\n",
454 be16_to_cpu(body->code));
455
456 }
457 cpos += body->length + 4;
458 }
459
460 if (!supported) {
f5b37b7c 461 pr_debug("This device is not Opal enabled. Not Supported!\n");
455a7b23
SB
462 return -EOPNOTSUPP;
463 }
464
465 if (!single_user)
f5b37b7c 466 pr_debug("Device doesn't support single user mode\n");
455a7b23
SB
467
468
469 if (!found_com_id) {
f5b37b7c 470 pr_debug("Could not find OPAL comid for device. Returning early\n");
455a7b23
SB
471 return -EOPNOTSUPP;;
472 }
473
474 dev->comid = comid;
475
476 return 0;
477}
478
479static int opal_discovery0(struct opal_dev *dev)
480{
481 int ret;
482
483 memset(dev->resp, 0, IO_BUFFER_LENGTH);
484 dev->comid = OPAL_DISCOVERY_COMID;
485 ret = opal_recv_cmd(dev);
486 if (ret)
487 return ret;
488 return opal_discovery0_end(dev);
489}
490
491static void add_token_u8(int *err, struct opal_dev *cmd, u8 tok)
492{
493 if (*err)
494 return;
495 if (cmd->pos >= IO_BUFFER_LENGTH - 1) {
496 pr_err("Error adding u8: end of buffer.\n");
497 *err = -ERANGE;
498 return;
499 }
500 cmd->cmd[cmd->pos++] = tok;
501}
502
503static void add_short_atom_header(struct opal_dev *cmd, bool bytestring,
504 bool has_sign, int len)
505{
506 u8 atom;
507 int err = 0;
508
509 atom = SHORT_ATOM_ID;
510 atom |= bytestring ? SHORT_ATOM_BYTESTRING : 0;
511 atom |= has_sign ? SHORT_ATOM_SIGNED : 0;
512 atom |= len & SHORT_ATOM_LEN_MASK;
513
514 add_token_u8(&err, cmd, atom);
515}
516
517static void add_medium_atom_header(struct opal_dev *cmd, bool bytestring,
518 bool has_sign, int len)
519{
520 u8 header0;
521
522 header0 = MEDIUM_ATOM_ID;
523 header0 |= bytestring ? MEDIUM_ATOM_BYTESTRING : 0;
524 header0 |= has_sign ? MEDIUM_ATOM_SIGNED : 0;
525 header0 |= (len >> 8) & MEDIUM_ATOM_LEN_MASK;
526 cmd->cmd[cmd->pos++] = header0;
527 cmd->cmd[cmd->pos++] = len;
528}
529
530static void add_token_u64(int *err, struct opal_dev *cmd, u64 number)
531{
532
533 size_t len;
534 int msb;
535 u8 n;
536
537 if (!(number & ~TINY_ATOM_DATA_MASK)) {
538 add_token_u8(err, cmd, number);
539 return;
540 }
541
542 msb = fls(number);
543 len = DIV_ROUND_UP(msb, 4);
544
545 if (cmd->pos >= IO_BUFFER_LENGTH - len - 1) {
546 pr_err("Error adding u64: end of buffer.\n");
547 *err = -ERANGE;
548 return;
549 }
550 add_short_atom_header(cmd, false, false, len);
551 while (len--) {
552 n = number >> (len * 8);
553 add_token_u8(err, cmd, n);
554 }
555}
556
557static void add_token_bytestring(int *err, struct opal_dev *cmd,
558 const u8 *bytestring, size_t len)
559{
560 size_t header_len = 1;
561 bool is_short_atom = true;
562
563 if (*err)
564 return;
565
566 if (len & ~SHORT_ATOM_LEN_MASK) {
567 header_len = 2;
568 is_short_atom = false;
569 }
570
571 if (len >= IO_BUFFER_LENGTH - cmd->pos - header_len) {
572 pr_err("Error adding bytestring: end of buffer.\n");
573 *err = -ERANGE;
574 return;
575 }
576
577 if (is_short_atom)
578 add_short_atom_header(cmd, true, false, len);
579 else
580 add_medium_atom_header(cmd, true, false, len);
581
582 memcpy(&cmd->cmd[cmd->pos], bytestring, len);
583 cmd->pos += len;
584
585}
586
587static int build_locking_range(u8 *buffer, size_t length, u8 lr)
588{
589 if (length > OPAL_UID_LENGTH) {
590 pr_err("Can't build locking range. Length OOB\n");
591 return -ERANGE;
592 }
593
594 memcpy(buffer, opaluid[OPAL_LOCKINGRANGE_GLOBAL], OPAL_UID_LENGTH);
595
596 if (lr == 0)
597 return 0;
598 buffer[5] = LOCKING_RANGE_NON_GLOBAL;
599 buffer[7] = lr;
600
601 return 0;
602}
603
604static int build_locking_user(u8 *buffer, size_t length, u8 lr)
605{
606 if (length > OPAL_UID_LENGTH) {
607 pr_err("Can't build locking range user, Length OOB\n");
608 return -ERANGE;
609 }
610
611 memcpy(buffer, opaluid[OPAL_USER1_UID], OPAL_UID_LENGTH);
612
613 buffer[7] = lr + 1;
614
615 return 0;
616}
617
618static void set_comid(struct opal_dev *cmd, u16 comid)
619{
620 struct opal_header *hdr = (struct opal_header *)cmd->cmd;
621
622 hdr->cp.extendedComID[0] = comid >> 8;
623 hdr->cp.extendedComID[1] = comid;
624 hdr->cp.extendedComID[2] = 0;
625 hdr->cp.extendedComID[3] = 0;
626}
627
628static int cmd_finalize(struct opal_dev *cmd, u32 hsn, u32 tsn)
629{
630 struct opal_header *hdr;
631 int err = 0;
632
633 add_token_u8(&err, cmd, OPAL_ENDOFDATA);
634 add_token_u8(&err, cmd, OPAL_STARTLIST);
635 add_token_u8(&err, cmd, 0);
636 add_token_u8(&err, cmd, 0);
637 add_token_u8(&err, cmd, 0);
638 add_token_u8(&err, cmd, OPAL_ENDLIST);
639
640 if (err) {
641 pr_err("Error finalizing command.\n");
642 return -EFAULT;
643 }
644
645 hdr = (struct opal_header *) cmd->cmd;
646
647 hdr->pkt.tsn = cpu_to_be32(tsn);
648 hdr->pkt.hsn = cpu_to_be32(hsn);
649
650 hdr->subpkt.length = cpu_to_be32(cmd->pos - sizeof(*hdr));
651 while (cmd->pos % 4) {
652 if (cmd->pos >= IO_BUFFER_LENGTH) {
653 pr_err("Error: Buffer overrun\n");
654 return -ERANGE;
655 }
656 cmd->cmd[cmd->pos++] = 0;
657 }
658 hdr->pkt.length = cpu_to_be32(cmd->pos - sizeof(hdr->cp) -
659 sizeof(hdr->pkt));
660 hdr->cp.length = cpu_to_be32(cmd->pos - sizeof(hdr->cp));
661
662 return 0;
663}
664
665static enum opal_response_token token_type(const struct parsed_resp *resp,
666 int n)
667{
668 const struct opal_resp_tok *tok;
669
670 if (n >= resp->num) {
671 pr_err("Token number doesn't exist: %d, resp: %d\n",
672 n, resp->num);
673 return OPAL_DTA_TOKENID_INVALID;
674 }
675
676 tok = &resp->toks[n];
677 if (tok->len == 0) {
678 pr_err("Token length must be non-zero\n");
679 return OPAL_DTA_TOKENID_INVALID;
680 }
681
682 return tok->type;
683}
684
685/*
686 * This function returns 0 in case of invalid token. One should call
687 * token_type() first to find out if the token is valid or not.
688 */
689static enum opal_token response_get_token(const struct parsed_resp *resp,
690 int n)
691{
692 const struct opal_resp_tok *tok;
693
694 if (n >= resp->num) {
695 pr_err("Token number doesn't exist: %d, resp: %d\n",
696 n, resp->num);
697 return 0;
698 }
699
700 tok = &resp->toks[n];
701 if (tok->len == 0) {
702 pr_err("Token length must be non-zero\n");
703 return 0;
704 }
705
706 return tok->pos[0];
707}
708
aedb6e24
JD
709static ssize_t response_parse_tiny(struct opal_resp_tok *tok,
710 const u8 *pos)
455a7b23
SB
711{
712 tok->pos = pos;
713 tok->len = 1;
714 tok->width = OPAL_WIDTH_TINY;
715
716 if (pos[0] & TINY_ATOM_SIGNED) {
717 tok->type = OPAL_DTA_TOKENID_SINT;
718 } else {
719 tok->type = OPAL_DTA_TOKENID_UINT;
720 tok->stored.u = pos[0] & 0x3f;
721 }
722
723 return tok->len;
724}
725
aedb6e24
JD
726static ssize_t response_parse_short(struct opal_resp_tok *tok,
727 const u8 *pos)
455a7b23
SB
728{
729 tok->pos = pos;
730 tok->len = (pos[0] & SHORT_ATOM_LEN_MASK) + 1;
731 tok->width = OPAL_WIDTH_SHORT;
732
733 if (pos[0] & SHORT_ATOM_BYTESTRING) {
734 tok->type = OPAL_DTA_TOKENID_BYTESTRING;
735 } else if (pos[0] & SHORT_ATOM_SIGNED) {
736 tok->type = OPAL_DTA_TOKENID_SINT;
737 } else {
738 u64 u_integer = 0;
aedb6e24 739 ssize_t i, b = 0;
455a7b23
SB
740
741 tok->type = OPAL_DTA_TOKENID_UINT;
742 if (tok->len > 9) {
743 pr_warn("uint64 with more than 8 bytes\n");
744 return -EINVAL;
745 }
746 for (i = tok->len - 1; i > 0; i--) {
747 u_integer |= ((u64)pos[i] << (8 * b));
748 b++;
749 }
750 tok->stored.u = u_integer;
751 }
752
753 return tok->len;
754}
755
aedb6e24
JD
756static ssize_t response_parse_medium(struct opal_resp_tok *tok,
757 const u8 *pos)
455a7b23
SB
758{
759 tok->pos = pos;
760 tok->len = (((pos[0] & MEDIUM_ATOM_LEN_MASK) << 8) | pos[1]) + 2;
761 tok->width = OPAL_WIDTH_MEDIUM;
762
763 if (pos[0] & MEDIUM_ATOM_BYTESTRING)
764 tok->type = OPAL_DTA_TOKENID_BYTESTRING;
765 else if (pos[0] & MEDIUM_ATOM_SIGNED)
766 tok->type = OPAL_DTA_TOKENID_SINT;
767 else
768 tok->type = OPAL_DTA_TOKENID_UINT;
769
770 return tok->len;
771}
772
aedb6e24
JD
773static ssize_t response_parse_long(struct opal_resp_tok *tok,
774 const u8 *pos)
455a7b23
SB
775{
776 tok->pos = pos;
777 tok->len = ((pos[1] << 16) | (pos[2] << 8) | pos[3]) + 4;
778 tok->width = OPAL_WIDTH_LONG;
779
780 if (pos[0] & LONG_ATOM_BYTESTRING)
781 tok->type = OPAL_DTA_TOKENID_BYTESTRING;
782 else if (pos[0] & LONG_ATOM_SIGNED)
783 tok->type = OPAL_DTA_TOKENID_SINT;
784 else
785 tok->type = OPAL_DTA_TOKENID_UINT;
786
787 return tok->len;
788}
789
aedb6e24
JD
790static ssize_t response_parse_token(struct opal_resp_tok *tok,
791 const u8 *pos)
455a7b23
SB
792{
793 tok->pos = pos;
794 tok->len = 1;
795 tok->type = OPAL_DTA_TOKENID_TOKEN;
796 tok->width = OPAL_WIDTH_TOKEN;
797
798 return tok->len;
799}
800
801static int response_parse(const u8 *buf, size_t length,
802 struct parsed_resp *resp)
803{
804 const struct opal_header *hdr;
805 struct opal_resp_tok *iter;
806 int num_entries = 0;
807 int total;
aedb6e24 808 ssize_t token_length;
455a7b23
SB
809 const u8 *pos;
810
811 if (!buf)
812 return -EFAULT;
813
814 if (!resp)
815 return -EFAULT;
816
817 hdr = (struct opal_header *)buf;
818 pos = buf;
819 pos += sizeof(*hdr);
820
821 pr_debug("Response size: cp: %d, pkt: %d, subpkt: %d\n",
822 be32_to_cpu(hdr->cp.length),
823 be32_to_cpu(hdr->pkt.length),
824 be32_to_cpu(hdr->subpkt.length));
825
826 if (hdr->cp.length == 0 || hdr->pkt.length == 0 ||
827 hdr->subpkt.length == 0) {
828 pr_err("Bad header length. cp: %d, pkt: %d, subpkt: %d\n",
829 be32_to_cpu(hdr->cp.length),
830 be32_to_cpu(hdr->pkt.length),
831 be32_to_cpu(hdr->subpkt.length));
832 print_buffer(pos, sizeof(*hdr));
833 return -EINVAL;
834 }
835
836 if (pos > buf + length)
837 return -EFAULT;
838
839 iter = resp->toks;
840 total = be32_to_cpu(hdr->subpkt.length);
841 print_buffer(pos, total);
842 while (total > 0) {
843 if (pos[0] <= TINY_ATOM_BYTE) /* tiny atom */
844 token_length = response_parse_tiny(iter, pos);
845 else if (pos[0] <= SHORT_ATOM_BYTE) /* short atom */
846 token_length = response_parse_short(iter, pos);
847 else if (pos[0] <= MEDIUM_ATOM_BYTE) /* medium atom */
848 token_length = response_parse_medium(iter, pos);
849 else if (pos[0] <= LONG_ATOM_BYTE) /* long atom */
850 token_length = response_parse_long(iter, pos);
851 else /* TOKEN */
852 token_length = response_parse_token(iter, pos);
853
aedb6e24
JD
854 if (token_length < 0)
855 return token_length;
455a7b23
SB
856
857 pos += token_length;
858 total -= token_length;
859 iter++;
860 num_entries++;
861 }
862
863 if (num_entries == 0) {
864 pr_err("Couldn't parse response.\n");
865 return -EINVAL;
866 }
867 resp->num = num_entries;
868
869 return 0;
870}
871
872static size_t response_get_string(const struct parsed_resp *resp, int n,
873 const char **store)
874{
875 *store = NULL;
876 if (!resp) {
877 pr_err("Response is NULL\n");
878 return 0;
879 }
880
881 if (n > resp->num) {
882 pr_err("Response has %d tokens. Can't access %d\n",
883 resp->num, n);
884 return 0;
885 }
886
887 if (resp->toks[n].type != OPAL_DTA_TOKENID_BYTESTRING) {
888 pr_err("Token is not a byte string!\n");
889 return 0;
890 }
891
892 *store = resp->toks[n].pos + 1;
893 return resp->toks[n].len - 1;
894}
895
896static u64 response_get_u64(const struct parsed_resp *resp, int n)
897{
898 if (!resp) {
899 pr_err("Response is NULL\n");
900 return 0;
901 }
902
903 if (n > resp->num) {
904 pr_err("Response has %d tokens. Can't access %d\n",
905 resp->num, n);
906 return 0;
907 }
908
909 if (resp->toks[n].type != OPAL_DTA_TOKENID_UINT) {
910 pr_err("Token is not unsigned it: %d\n",
911 resp->toks[n].type);
912 return 0;
913 }
914
915 if (!(resp->toks[n].width == OPAL_WIDTH_TINY ||
916 resp->toks[n].width == OPAL_WIDTH_SHORT)) {
917 pr_err("Atom is not short or tiny: %d\n",
918 resp->toks[n].width);
919 return 0;
920 }
921
922 return resp->toks[n].stored.u;
923}
924
925static u8 response_status(const struct parsed_resp *resp)
926{
927 if (token_type(resp, 0) == OPAL_DTA_TOKENID_TOKEN &&
928 response_get_token(resp, 0) == OPAL_ENDOFSESSION) {
929 return 0;
930 }
931
932 if (resp->num < 5)
933 return DTAERROR_NO_METHOD_STATUS;
934
935 if (token_type(resp, resp->num - 1) != OPAL_DTA_TOKENID_TOKEN ||
936 token_type(resp, resp->num - 5) != OPAL_DTA_TOKENID_TOKEN ||
937 response_get_token(resp, resp->num - 1) != OPAL_ENDLIST ||
938 response_get_token(resp, resp->num - 5) != OPAL_STARTLIST)
939 return DTAERROR_NO_METHOD_STATUS;
940
941 return response_get_u64(resp, resp->num - 4);
942}
943
944/* Parses and checks for errors */
945static int parse_and_check_status(struct opal_dev *dev)
946{
947 int error;
948
949 print_buffer(dev->cmd, dev->pos);
950
951 error = response_parse(dev->resp, IO_BUFFER_LENGTH, &dev->parsed);
952 if (error) {
953 pr_err("Couldn't parse response.\n");
954 return error;
955 }
956
957 return response_status(&dev->parsed);
958}
959
960static void clear_opal_cmd(struct opal_dev *dev)
961{
962 dev->pos = sizeof(struct opal_header);
963 memset(dev->cmd, 0, IO_BUFFER_LENGTH);
964}
965
966static int start_opal_session_cont(struct opal_dev *dev)
967{
968 u32 hsn, tsn;
969 int error = 0;
970
971 error = parse_and_check_status(dev);
972 if (error)
973 return error;
974
975 hsn = response_get_u64(&dev->parsed, 4);
976 tsn = response_get_u64(&dev->parsed, 5);
977
978 if (hsn == 0 && tsn == 0) {
979 pr_err("Couldn't authenticate session\n");
980 return -EPERM;
981 }
982
983 dev->hsn = hsn;
984 dev->tsn = tsn;
985 return 0;
986}
987
988static void add_suspend_info(struct opal_dev *dev,
989 struct opal_suspend_data *sus)
990{
991 struct opal_suspend_data *iter;
992
993 list_for_each_entry(iter, &dev->unlk_lst, node) {
994 if (iter->lr == sus->lr) {
995 list_del(&iter->node);
996 kfree(iter);
997 break;
998 }
999 }
1000 list_add_tail(&sus->node, &dev->unlk_lst);
1001}
1002
1003static int end_session_cont(struct opal_dev *dev)
1004{
1005 dev->hsn = 0;
1006 dev->tsn = 0;
1007 return parse_and_check_status(dev);
1008}
1009
1010static int finalize_and_send(struct opal_dev *dev, cont_fn cont)
1011{
1012 int ret;
1013
1014 ret = cmd_finalize(dev, dev->hsn, dev->tsn);
1015 if (ret) {
1016 pr_err("Error finalizing command buffer: %d\n", ret);
1017 return ret;
1018 }
1019
1020 print_buffer(dev->cmd, dev->pos);
1021
1022 return opal_send_recv(dev, cont);
1023}
1024
1025static int gen_key(struct opal_dev *dev)
1026{
1027 const u8 *method;
1028 u8 uid[OPAL_UID_LENGTH];
1029 int err = 0;
1030
1031 clear_opal_cmd(dev);
1032 set_comid(dev, dev->comid);
1033
1034 memcpy(uid, dev->prev_data, min(sizeof(uid), dev->prev_d_len));
1035 method = opalmethod[OPAL_GENKEY];
1036 kfree(dev->prev_data);
1037 dev->prev_data = NULL;
1038
1039 add_token_u8(&err, dev, OPAL_CALL);
1040 add_token_bytestring(&err, dev, uid, OPAL_UID_LENGTH);
1041 add_token_bytestring(&err, dev, opalmethod[OPAL_GENKEY],
1042 OPAL_UID_LENGTH);
1043 add_token_u8(&err, dev, OPAL_STARTLIST);
1044 add_token_u8(&err, dev, OPAL_ENDLIST);
1045
1046 if (err) {
1047 pr_err("Error building gen key command\n");
1048 return err;
1049
1050 }
1051 return finalize_and_send(dev, parse_and_check_status);
1052}
1053
1054static int get_active_key_cont(struct opal_dev *dev)
1055{
1056 const char *activekey;
1057 size_t keylen;
1058 int error = 0;
1059
1060 error = parse_and_check_status(dev);
1061 if (error)
1062 return error;
1063 keylen = response_get_string(&dev->parsed, 4, &activekey);
1064 if (!activekey) {
1065 pr_err("%s: Couldn't extract the Activekey from the response\n",
1066 __func__);
1067 return OPAL_INVAL_PARAM;
1068 }
1069 dev->prev_data = kmemdup(activekey, keylen, GFP_KERNEL);
1070
1071 if (!dev->prev_data)
1072 return -ENOMEM;
1073
1074 dev->prev_d_len = keylen;
1075
1076 return 0;
1077}
1078
1079static int get_active_key(struct opal_dev *dev)
1080{
1081 u8 uid[OPAL_UID_LENGTH];
1082 int err = 0;
1083 u8 *lr;
1084
1085 clear_opal_cmd(dev);
1086 set_comid(dev, dev->comid);
1087 lr = dev->func_data[dev->state];
1088
1089 err = build_locking_range(uid, sizeof(uid), *lr);
1090 if (err)
1091 return err;
1092
1093 err = 0;
1094 add_token_u8(&err, dev, OPAL_CALL);
1095 add_token_bytestring(&err, dev, uid, OPAL_UID_LENGTH);
1096 add_token_bytestring(&err, dev, opalmethod[OPAL_GET], OPAL_UID_LENGTH);
1097 add_token_u8(&err, dev, OPAL_STARTLIST);
1098 add_token_u8(&err, dev, OPAL_STARTLIST);
1099 add_token_u8(&err, dev, OPAL_STARTNAME);
1100 add_token_u8(&err, dev, 3); /* startCloumn */
1101 add_token_u8(&err, dev, 10); /* ActiveKey */
1102 add_token_u8(&err, dev, OPAL_ENDNAME);
1103 add_token_u8(&err, dev, OPAL_STARTNAME);
1104 add_token_u8(&err, dev, 4); /* endColumn */
1105 add_token_u8(&err, dev, 10); /* ActiveKey */
1106 add_token_u8(&err, dev, OPAL_ENDNAME);
1107 add_token_u8(&err, dev, OPAL_ENDLIST);
1108 add_token_u8(&err, dev, OPAL_ENDLIST);
1109 if (err) {
1110 pr_err("Error building get active key command\n");
1111 return err;
1112 }
1113
1114 return finalize_and_send(dev, get_active_key_cont);
1115}
1116
1117static int generic_lr_enable_disable(struct opal_dev *dev,
1118 u8 *uid, bool rle, bool wle,
1119 bool rl, bool wl)
1120{
1121 int err = 0;
1122
1123 add_token_u8(&err, dev, OPAL_CALL);
1124 add_token_bytestring(&err, dev, uid, OPAL_UID_LENGTH);
1125 add_token_bytestring(&err, dev, opalmethod[OPAL_SET], OPAL_UID_LENGTH);
1126
1127 add_token_u8(&err, dev, OPAL_STARTLIST);
1128 add_token_u8(&err, dev, OPAL_STARTNAME);
1129 add_token_u8(&err, dev, OPAL_VALUES);
1130 add_token_u8(&err, dev, OPAL_STARTLIST);
1131
1132 add_token_u8(&err, dev, OPAL_STARTNAME);
1133 add_token_u8(&err, dev, 5); /* ReadLockEnabled */
1134 add_token_u8(&err, dev, rle);
1135 add_token_u8(&err, dev, OPAL_ENDNAME);
1136
1137 add_token_u8(&err, dev, OPAL_STARTNAME);
1138 add_token_u8(&err, dev, 6); /* WriteLockEnabled */
1139 add_token_u8(&err, dev, wle);
1140 add_token_u8(&err, dev, OPAL_ENDNAME);
1141
1142 add_token_u8(&err, dev, OPAL_STARTNAME);
1143 add_token_u8(&err, dev, OPAL_READLOCKED);
1144 add_token_u8(&err, dev, rl);
1145 add_token_u8(&err, dev, OPAL_ENDNAME);
1146
1147 add_token_u8(&err, dev, OPAL_STARTNAME);
1148 add_token_u8(&err, dev, OPAL_WRITELOCKED);
1149 add_token_u8(&err, dev, wl);
1150 add_token_u8(&err, dev, OPAL_ENDNAME);
1151
1152 add_token_u8(&err, dev, OPAL_ENDLIST);
1153 add_token_u8(&err, dev, OPAL_ENDNAME);
1154 add_token_u8(&err, dev, OPAL_ENDLIST);
1155 return err;
1156}
1157
1158static inline int enable_global_lr(struct opal_dev *dev, u8 *uid,
1159 struct opal_user_lr_setup *setup)
1160{
1161 int err;
1162
1163 err = generic_lr_enable_disable(dev, uid, !!setup->RLE, !!setup->WLE,
1164 0, 0);
1165 if (err)
1166 pr_err("Failed to create enable global lr command\n");
1167 return err;
1168}
1169
1170static int setup_locking_range(struct opal_dev *dev)
1171{
1172 u8 uid[OPAL_UID_LENGTH];
1173 struct opal_user_lr_setup *setup;
1174 u8 lr;
1175 int err = 0;
1176
1177 clear_opal_cmd(dev);
1178 set_comid(dev, dev->comid);
1179
1180 setup = dev->func_data[dev->state];
1181 lr = setup->session.opal_key.lr;
1182 err = build_locking_range(uid, sizeof(uid), lr);
1183 if (err)
1184 return err;
1185
1186 if (lr == 0)
1187 err = enable_global_lr(dev, uid, setup);
1188 else {
1189 add_token_u8(&err, dev, OPAL_CALL);
1190 add_token_bytestring(&err, dev, uid, OPAL_UID_LENGTH);
1191 add_token_bytestring(&err, dev, opalmethod[OPAL_SET],
1192 OPAL_UID_LENGTH);
1193
1194 add_token_u8(&err, dev, OPAL_STARTLIST);
1195 add_token_u8(&err, dev, OPAL_STARTNAME);
1196 add_token_u8(&err, dev, OPAL_VALUES);
1197 add_token_u8(&err, dev, OPAL_STARTLIST);
1198
1199 add_token_u8(&err, dev, OPAL_STARTNAME);
1200 add_token_u8(&err, dev, 3); /* Ranges Start */
1201 add_token_u64(&err, dev, setup->range_start);
1202 add_token_u8(&err, dev, OPAL_ENDNAME);
1203
1204 add_token_u8(&err, dev, OPAL_STARTNAME);
1205 add_token_u8(&err, dev, 4); /* Ranges length */
1206 add_token_u64(&err, dev, setup->range_length);
1207 add_token_u8(&err, dev, OPAL_ENDNAME);
1208
1209 add_token_u8(&err, dev, OPAL_STARTNAME);
1210 add_token_u8(&err, dev, 5); /*ReadLockEnabled */
1211 add_token_u64(&err, dev, !!setup->RLE);
1212 add_token_u8(&err, dev, OPAL_ENDNAME);
1213
1214 add_token_u8(&err, dev, OPAL_STARTNAME);
1215 add_token_u8(&err, dev, 6); /*WriteLockEnabled*/
1216 add_token_u64(&err, dev, !!setup->WLE);
1217 add_token_u8(&err, dev, OPAL_ENDNAME);
1218
1219 add_token_u8(&err, dev, OPAL_ENDLIST);
1220 add_token_u8(&err, dev, OPAL_ENDNAME);
1221 add_token_u8(&err, dev, OPAL_ENDLIST);
1222
1223 }
1224 if (err) {
1225 pr_err("Error building Setup Locking range command.\n");
1226 return err;
1227
1228 }
1229
1230 return finalize_and_send(dev, parse_and_check_status);
1231}
1232
1233static int start_generic_opal_session(struct opal_dev *dev,
1234 enum opal_uid auth,
1235 enum opal_uid sp_type,
1236 const char *key,
1237 u8 key_len)
1238{
1239 u32 hsn;
1240 int err = 0;
1241
1242 if (key == NULL && auth != OPAL_ANYBODY_UID) {
1243 pr_err("%s: Attempted to open ADMIN_SP Session without a Host" \
1244 "Challenge, and not as the Anybody UID\n", __func__);
1245 return OPAL_INVAL_PARAM;
1246 }
1247
1248 clear_opal_cmd(dev);
1249
1250 set_comid(dev, dev->comid);
1251 hsn = GENERIC_HOST_SESSION_NUM;
1252
1253 add_token_u8(&err, dev, OPAL_CALL);
1254 add_token_bytestring(&err, dev, opaluid[OPAL_SMUID_UID],
1255 OPAL_UID_LENGTH);
1256 add_token_bytestring(&err, dev, opalmethod[OPAL_STARTSESSION],
1257 OPAL_UID_LENGTH);
1258 add_token_u8(&err, dev, OPAL_STARTLIST);
1259 add_token_u64(&err, dev, hsn);
1260 add_token_bytestring(&err, dev, opaluid[sp_type], OPAL_UID_LENGTH);
1261 add_token_u8(&err, dev, 1);
1262
1263 switch (auth) {
1264 case OPAL_ANYBODY_UID:
1265 add_token_u8(&err, dev, OPAL_ENDLIST);
1266 break;
1267 case OPAL_ADMIN1_UID:
1268 case OPAL_SID_UID:
1269 add_token_u8(&err, dev, OPAL_STARTNAME);
1270 add_token_u8(&err, dev, 0); /* HostChallenge */
1271 add_token_bytestring(&err, dev, key, key_len);
1272 add_token_u8(&err, dev, OPAL_ENDNAME);
1273 add_token_u8(&err, dev, OPAL_STARTNAME);
1274 add_token_u8(&err, dev, 3); /* HostSignAuth */
1275 add_token_bytestring(&err, dev, opaluid[auth],
1276 OPAL_UID_LENGTH);
1277 add_token_u8(&err, dev, OPAL_ENDNAME);
1278 add_token_u8(&err, dev, OPAL_ENDLIST);
1279 break;
1280 default:
1281 pr_err("Cannot start Admin SP session with auth %d\n", auth);
1282 return OPAL_INVAL_PARAM;
1283 }
1284
1285 if (err) {
1286 pr_err("Error building start adminsp session command.\n");
1287 return err;
1288 }
1289
1290 return finalize_and_send(dev, start_opal_session_cont);
1291}
1292
1293static int start_anybodyASP_opal_session(struct opal_dev *dev)
1294{
1295 return start_generic_opal_session(dev, OPAL_ANYBODY_UID,
1296 OPAL_ADMINSP_UID, NULL, 0);
1297}
1298
1299static int start_SIDASP_opal_session(struct opal_dev *dev)
1300{
1301 int ret;
1302 const u8 *key = dev->prev_data;
1303 struct opal_key *okey;
1304
1305 if (!key) {
1306 okey = dev->func_data[dev->state];
1307 ret = start_generic_opal_session(dev, OPAL_SID_UID,
1308 OPAL_ADMINSP_UID,
1309 okey->key,
1310 okey->key_len);
1311 } else {
1312 ret = start_generic_opal_session(dev, OPAL_SID_UID,
1313 OPAL_ADMINSP_UID,
1314 key, dev->prev_d_len);
1315 kfree(key);
1316 dev->prev_data = NULL;
1317 }
1318 return ret;
1319}
1320
1321static inline int start_admin1LSP_opal_session(struct opal_dev *dev)
1322{
1323 struct opal_key *key = dev->func_data[dev->state];
1324
1325 return start_generic_opal_session(dev, OPAL_ADMIN1_UID,
1326 OPAL_LOCKINGSP_UID,
1327 key->key, key->key_len);
1328}
1329
1330static int start_auth_opal_session(struct opal_dev *dev)
1331{
1332 u8 lk_ul_user[OPAL_UID_LENGTH];
1333 int err = 0;
1334
1335 struct opal_session_info *session = dev->func_data[dev->state];
1336 size_t keylen = session->opal_key.key_len;
1337 u8 *key = session->opal_key.key;
1338 u32 hsn = GENERIC_HOST_SESSION_NUM;
1339
1340 clear_opal_cmd(dev);
1341 set_comid(dev, dev->comid);
1342
1343 if (session->sum) {
1344 err = build_locking_user(lk_ul_user, sizeof(lk_ul_user),
1345 session->opal_key.lr);
1346 if (err)
1347 return err;
1348
1349 } else if (session->who != OPAL_ADMIN1 && !session->sum) {
1350 err = build_locking_user(lk_ul_user, sizeof(lk_ul_user),
1351 session->who - 1);
1352 if (err)
1353 return err;
1354 } else
1355 memcpy(lk_ul_user, opaluid[OPAL_ADMIN1_UID], OPAL_UID_LENGTH);
1356
1357 add_token_u8(&err, dev, OPAL_CALL);
1358 add_token_bytestring(&err, dev, opaluid[OPAL_SMUID_UID],
1359 OPAL_UID_LENGTH);
1360 add_token_bytestring(&err, dev, opalmethod[OPAL_STARTSESSION],
1361 OPAL_UID_LENGTH);
1362
1363 add_token_u8(&err, dev, OPAL_STARTLIST);
1364 add_token_u64(&err, dev, hsn);
1365 add_token_bytestring(&err, dev, opaluid[OPAL_LOCKINGSP_UID],
1366 OPAL_UID_LENGTH);
1367 add_token_u8(&err, dev, 1);
1368 add_token_u8(&err, dev, OPAL_STARTNAME);
1369 add_token_u8(&err, dev, 0);
1370 add_token_bytestring(&err, dev, key, keylen);
1371 add_token_u8(&err, dev, OPAL_ENDNAME);
1372 add_token_u8(&err, dev, OPAL_STARTNAME);
1373 add_token_u8(&err, dev, 3);
1374 add_token_bytestring(&err, dev, lk_ul_user, OPAL_UID_LENGTH);
1375 add_token_u8(&err, dev, OPAL_ENDNAME);
1376 add_token_u8(&err, dev, OPAL_ENDLIST);
1377
1378 if (err) {
1379 pr_err("Error building STARTSESSION command.\n");
1380 return err;
1381 }
1382
1383 return finalize_and_send(dev, start_opal_session_cont);
1384}
1385
1386static int revert_tper(struct opal_dev *dev)
1387{
1388 int err = 0;
1389
1390 clear_opal_cmd(dev);
1391 set_comid(dev, dev->comid);
1392
1393 add_token_u8(&err, dev, OPAL_CALL);
1394 add_token_bytestring(&err, dev, opaluid[OPAL_ADMINSP_UID],
1395 OPAL_UID_LENGTH);
1396 add_token_bytestring(&err, dev, opalmethod[OPAL_REVERT],
1397 OPAL_UID_LENGTH);
1398 add_token_u8(&err, dev, OPAL_STARTLIST);
1399 add_token_u8(&err, dev, OPAL_ENDLIST);
1400 if (err) {
1401 pr_err("Error building REVERT TPER command.\n");
1402 return err;
1403 }
1404
1405 return finalize_and_send(dev, parse_and_check_status);
1406}
1407
1408static int internal_activate_user(struct opal_dev *dev)
1409{
1410 struct opal_session_info *session = dev->func_data[dev->state];
1411 u8 uid[OPAL_UID_LENGTH];
1412 int err = 0;
1413
1414 clear_opal_cmd(dev);
1415 set_comid(dev, dev->comid);
1416
1417 memcpy(uid, opaluid[OPAL_USER1_UID], OPAL_UID_LENGTH);
1418 uid[7] = session->who;
1419
1420 add_token_u8(&err, dev, OPAL_CALL);
1421 add_token_bytestring(&err, dev, uid, OPAL_UID_LENGTH);
1422 add_token_bytestring(&err, dev, opalmethod[OPAL_SET], OPAL_UID_LENGTH);
1423 add_token_u8(&err, dev, OPAL_STARTLIST);
1424 add_token_u8(&err, dev, OPAL_STARTNAME);
1425 add_token_u8(&err, dev, OPAL_VALUES);
1426 add_token_u8(&err, dev, OPAL_STARTLIST);
1427 add_token_u8(&err, dev, OPAL_STARTNAME);
1428 add_token_u8(&err, dev, 5); /* Enabled */
1429 add_token_u8(&err, dev, OPAL_TRUE);
1430 add_token_u8(&err, dev, OPAL_ENDNAME);
1431 add_token_u8(&err, dev, OPAL_ENDLIST);
1432 add_token_u8(&err, dev, OPAL_ENDNAME);
1433 add_token_u8(&err, dev, OPAL_ENDLIST);
1434
1435 if (err) {
1436 pr_err("Error building Activate UserN command.\n");
1437 return err;
1438 }
1439
1440 return finalize_and_send(dev, parse_and_check_status);
1441}
1442
1443static int erase_locking_range(struct opal_dev *dev)
1444{
1445 struct opal_session_info *session;
1446 u8 uid[OPAL_UID_LENGTH];
1447 int err = 0;
1448
1449 clear_opal_cmd(dev);
1450 set_comid(dev, dev->comid);
1451 session = dev->func_data[dev->state];
1452
1453 if (build_locking_range(uid, sizeof(uid), session->opal_key.lr) < 0)
1454 return -ERANGE;
1455
1456 add_token_u8(&err, dev, OPAL_CALL);
1457 add_token_bytestring(&err, dev, uid, OPAL_UID_LENGTH);
1458 add_token_bytestring(&err, dev, opalmethod[OPAL_ERASE],
1459 OPAL_UID_LENGTH);
1460 add_token_u8(&err, dev, OPAL_STARTLIST);
1461 add_token_u8(&err, dev, OPAL_ENDLIST);
1462
1463 if (err) {
1464 pr_err("Error building Erase Locking Range Command.\n");
1465 return err;
1466 }
1467 return finalize_and_send(dev, parse_and_check_status);
1468}
1469
1470static int set_mbr_done(struct opal_dev *dev)
1471{
1472 u8 mbr_done_tf = *(u8 *)dev->func_data[dev->state];
1473 int err = 0;
1474
1475 clear_opal_cmd(dev);
1476 set_comid(dev, dev->comid);
1477
1478 add_token_u8(&err, dev, OPAL_CALL);
1479 add_token_bytestring(&err, dev, opaluid[OPAL_MBRCONTROL],
1480 OPAL_UID_LENGTH);
1481 add_token_bytestring(&err, dev, opalmethod[OPAL_SET], OPAL_UID_LENGTH);
1482 add_token_u8(&err, dev, OPAL_STARTLIST);
1483 add_token_u8(&err, dev, OPAL_STARTNAME);
1484 add_token_u8(&err, dev, OPAL_VALUES);
1485 add_token_u8(&err, dev, OPAL_STARTLIST);
1486 add_token_u8(&err, dev, OPAL_STARTNAME);
1487 add_token_u8(&err, dev, 2); /* Done */
1488 add_token_u8(&err, dev, mbr_done_tf); /* Done T or F */
1489 add_token_u8(&err, dev, OPAL_ENDNAME);
1490 add_token_u8(&err, dev, OPAL_ENDLIST);
1491 add_token_u8(&err, dev, OPAL_ENDNAME);
1492 add_token_u8(&err, dev, OPAL_ENDLIST);
1493
1494 if (err) {
1495 pr_err("Error Building set MBR Done command\n");
1496 return err;
1497 }
1498
1499 return finalize_and_send(dev, parse_and_check_status);
1500}
1501
1502static int set_mbr_enable_disable(struct opal_dev *dev)
1503{
1504 u8 mbr_en_dis = *(u8 *)dev->func_data[dev->state];
1505 int err = 0;
1506
1507 clear_opal_cmd(dev);
1508 set_comid(dev, dev->comid);
1509
1510 add_token_u8(&err, dev, OPAL_CALL);
1511 add_token_bytestring(&err, dev, opaluid[OPAL_MBRCONTROL],
1512 OPAL_UID_LENGTH);
1513 add_token_bytestring(&err, dev, opalmethod[OPAL_SET], OPAL_UID_LENGTH);
1514 add_token_u8(&err, dev, OPAL_STARTLIST);
1515 add_token_u8(&err, dev, OPAL_STARTNAME);
1516 add_token_u8(&err, dev, OPAL_VALUES);
1517 add_token_u8(&err, dev, OPAL_STARTLIST);
1518 add_token_u8(&err, dev, OPAL_STARTNAME);
1519 add_token_u8(&err, dev, 1);
1520 add_token_u8(&err, dev, mbr_en_dis);
1521 add_token_u8(&err, dev, OPAL_ENDNAME);
1522 add_token_u8(&err, dev, OPAL_ENDLIST);
1523 add_token_u8(&err, dev, OPAL_ENDNAME);
1524 add_token_u8(&err, dev, OPAL_ENDLIST);
1525
1526 if (err) {
1527 pr_err("Error Building set MBR done command\n");
1528 return err;
1529 }
1530
1531 return finalize_and_send(dev, parse_and_check_status);
1532}
1533
1534static int generic_pw_cmd(u8 *key, size_t key_len, u8 *cpin_uid,
1535 struct opal_dev *dev)
1536{
1537 int err = 0;
1538
1539 clear_opal_cmd(dev);
1540 set_comid(dev, dev->comid);
1541
1542 add_token_u8(&err, dev, OPAL_CALL);
1543 add_token_bytestring(&err, dev, cpin_uid, OPAL_UID_LENGTH);
1544 add_token_bytestring(&err, dev, opalmethod[OPAL_SET],
1545 OPAL_UID_LENGTH);
1546 add_token_u8(&err, dev, OPAL_STARTLIST);
1547 add_token_u8(&err, dev, OPAL_STARTNAME);
1548 add_token_u8(&err, dev, OPAL_VALUES);
1549 add_token_u8(&err, dev, OPAL_STARTLIST);
1550 add_token_u8(&err, dev, OPAL_STARTNAME);
1551 add_token_u8(&err, dev, 3); /* PIN */
1552 add_token_bytestring(&err, dev, key, key_len);
1553 add_token_u8(&err, dev, OPAL_ENDNAME);
1554 add_token_u8(&err, dev, OPAL_ENDLIST);
1555 add_token_u8(&err, dev, OPAL_ENDNAME);
1556 add_token_u8(&err, dev, OPAL_ENDLIST);
1557
1558 return err;
1559}
1560
1561static int set_new_pw(struct opal_dev *dev)
1562{
1563 u8 cpin_uid[OPAL_UID_LENGTH];
1564 struct opal_session_info *usr = dev->func_data[dev->state];
1565
1566
1567 memcpy(cpin_uid, opaluid[OPAL_C_PIN_ADMIN1], OPAL_UID_LENGTH);
1568
1569 if (usr->who != OPAL_ADMIN1) {
1570 cpin_uid[5] = 0x03;
1571 if (usr->sum)
1572 cpin_uid[7] = usr->opal_key.lr + 1;
1573 else
1574 cpin_uid[7] = usr->who;
1575 }
1576
1577 if (generic_pw_cmd(usr->opal_key.key, usr->opal_key.key_len,
1578 cpin_uid, dev)) {
1579 pr_err("Error building set password command.\n");
1580 return -ERANGE;
1581 }
1582
1583 return finalize_and_send(dev, parse_and_check_status);
1584}
1585
1586static int set_sid_cpin_pin(struct opal_dev *dev)
1587{
1588 u8 cpin_uid[OPAL_UID_LENGTH];
1589 struct opal_key *key = dev->func_data[dev->state];
1590
1591 memcpy(cpin_uid, opaluid[OPAL_C_PIN_SID], OPAL_UID_LENGTH);
1592
1593 if (generic_pw_cmd(key->key, key->key_len, cpin_uid, dev)) {
1594 pr_err("Error building Set SID cpin\n");
1595 return -ERANGE;
1596 }
1597 return finalize_and_send(dev, parse_and_check_status);
1598}
1599
1600static int add_user_to_lr(struct opal_dev *dev)
1601{
1602 u8 lr_buffer[OPAL_UID_LENGTH];
1603 u8 user_uid[OPAL_UID_LENGTH];
1604 struct opal_lock_unlock *lkul;
1605 int err = 0;
1606
1607 clear_opal_cmd(dev);
1608 set_comid(dev, dev->comid);
1609
1610 lkul = dev->func_data[dev->state];
1611
1612 memcpy(lr_buffer, opaluid[OPAL_LOCKINGRANGE_ACE_RDLOCKED],
1613 OPAL_UID_LENGTH);
1614
1615 if (lkul->l_state == OPAL_RW)
1616 memcpy(lr_buffer, opaluid[OPAL_LOCKINGRANGE_ACE_WRLOCKED],
1617 OPAL_UID_LENGTH);
1618
1619 lr_buffer[7] = lkul->session.opal_key.lr;
1620
1621 memcpy(user_uid, opaluid[OPAL_USER1_UID], OPAL_UID_LENGTH);
1622
1623 user_uid[7] = lkul->session.who;
1624
1625 add_token_u8(&err, dev, OPAL_CALL);
1626 add_token_bytestring(&err, dev, lr_buffer, OPAL_UID_LENGTH);
1627 add_token_bytestring(&err, dev, opalmethod[OPAL_SET],
1628 OPAL_UID_LENGTH);
1629
1630 add_token_u8(&err, dev, OPAL_STARTLIST);
1631 add_token_u8(&err, dev, OPAL_STARTNAME);
1632 add_token_u8(&err, dev, OPAL_VALUES);
1633
1634 add_token_u8(&err, dev, OPAL_STARTLIST);
1635 add_token_u8(&err, dev, OPAL_STARTNAME);
1636 add_token_u8(&err, dev, 3);
1637
1638 add_token_u8(&err, dev, OPAL_STARTLIST);
1639
1640
1641 add_token_u8(&err, dev, OPAL_STARTNAME);
1642 add_token_bytestring(&err, dev,
1643 opaluid[OPAL_HALF_UID_AUTHORITY_OBJ_REF],
1644 OPAL_UID_LENGTH/2);
1645 add_token_bytestring(&err, dev, user_uid, OPAL_UID_LENGTH);
1646 add_token_u8(&err, dev, OPAL_ENDNAME);
1647
1648
1649 add_token_u8(&err, dev, OPAL_STARTNAME);
1650 add_token_bytestring(&err, dev,
1651 opaluid[OPAL_HALF_UID_AUTHORITY_OBJ_REF],
1652 OPAL_UID_LENGTH/2);
1653 add_token_bytestring(&err, dev, user_uid, OPAL_UID_LENGTH);
1654 add_token_u8(&err, dev, OPAL_ENDNAME);
1655
1656
1657 add_token_u8(&err, dev, OPAL_STARTNAME);
1658 add_token_bytestring(&err, dev, opaluid[OPAL_HALF_UID_BOOLEAN_ACE],
1659 OPAL_UID_LENGTH/2);
1660 add_token_u8(&err, dev, 1);
1661 add_token_u8(&err, dev, OPAL_ENDNAME);
1662
1663
1664 add_token_u8(&err, dev, OPAL_ENDLIST);
1665 add_token_u8(&err, dev, OPAL_ENDNAME);
1666 add_token_u8(&err, dev, OPAL_ENDLIST);
1667 add_token_u8(&err, dev, OPAL_ENDNAME);
1668 add_token_u8(&err, dev, OPAL_ENDLIST);
1669
1670 if (err) {
1671 pr_err("Error building add user to locking range command.\n");
1672 return err;
1673 }
1674
1675 return finalize_and_send(dev, parse_and_check_status);
1676}
1677
1678static int lock_unlock_locking_range(struct opal_dev *dev)
1679{
1680 u8 lr_buffer[OPAL_UID_LENGTH];
1681 const u8 *method;
1682 struct opal_lock_unlock *lkul;
1683 u8 read_locked = 1, write_locked = 1;
1684 int err = 0;
1685
1686 clear_opal_cmd(dev);
1687 set_comid(dev, dev->comid);
1688
1689 method = opalmethod[OPAL_SET];
1690 lkul = dev->func_data[dev->state];
1691 if (build_locking_range(lr_buffer, sizeof(lr_buffer),
1692 lkul->session.opal_key.lr) < 0)
1693 return -ERANGE;
1694
1695 switch (lkul->l_state) {
1696 case OPAL_RO:
1697 read_locked = 0;
1698 write_locked = 1;
1699 break;
1700 case OPAL_RW:
1701 read_locked = 0;
1702 write_locked = 0;
1703 break;
1704 case OPAL_LK:
1705 /* vars are initalized to locked */
1706 break;
1707 default:
1708 pr_err("Tried to set an invalid locking state... returning to uland\n");
1709 return OPAL_INVAL_PARAM;
1710 }
1711
1712 add_token_u8(&err, dev, OPAL_CALL);
1713 add_token_bytestring(&err, dev, lr_buffer, OPAL_UID_LENGTH);
1714 add_token_bytestring(&err, dev, opalmethod[OPAL_SET], OPAL_UID_LENGTH);
1715 add_token_u8(&err, dev, OPAL_STARTLIST);
1716 add_token_u8(&err, dev, OPAL_STARTNAME);
1717 add_token_u8(&err, dev, OPAL_VALUES);
1718 add_token_u8(&err, dev, OPAL_STARTLIST);
1719
1720 add_token_u8(&err, dev, OPAL_STARTNAME);
1721 add_token_u8(&err, dev, OPAL_READLOCKED);
1722 add_token_u8(&err, dev, read_locked);
1723 add_token_u8(&err, dev, OPAL_ENDNAME);
1724
1725 add_token_u8(&err, dev, OPAL_STARTNAME);
1726 add_token_u8(&err, dev, OPAL_WRITELOCKED);
1727 add_token_u8(&err, dev, write_locked);
1728 add_token_u8(&err, dev, OPAL_ENDNAME);
1729
1730 add_token_u8(&err, dev, OPAL_ENDLIST);
1731 add_token_u8(&err, dev, OPAL_ENDNAME);
1732 add_token_u8(&err, dev, OPAL_ENDLIST);
1733
1734 if (err) {
1735 pr_err("Error building SET command.\n");
1736 return err;
1737 }
1738 return finalize_and_send(dev, parse_and_check_status);
1739}
1740
1741
1742static int lock_unlock_locking_range_sum(struct opal_dev *dev)
1743{
1744 u8 lr_buffer[OPAL_UID_LENGTH];
1745 u8 read_locked = 1, write_locked = 1;
1746 const u8 *method;
1747 struct opal_lock_unlock *lkul;
1748 int ret;
1749
1750 clear_opal_cmd(dev);
1751 set_comid(dev, dev->comid);
1752
1753 method = opalmethod[OPAL_SET];
1754 lkul = dev->func_data[dev->state];
1755 if (build_locking_range(lr_buffer, sizeof(lr_buffer),
1756 lkul->session.opal_key.lr) < 0)
1757 return -ERANGE;
1758
1759 switch (lkul->l_state) {
1760 case OPAL_RO:
1761 read_locked = 0;
1762 write_locked = 1;
1763 break;
1764 case OPAL_RW:
1765 read_locked = 0;
1766 write_locked = 0;
1767 break;
1768 case OPAL_LK:
1769 /* vars are initalized to locked */
1770 break;
1771 default:
1772 pr_err("Tried to set an invalid locking state.\n");
1773 return OPAL_INVAL_PARAM;
1774 }
1775 ret = generic_lr_enable_disable(dev, lr_buffer, 1, 1,
1776 read_locked, write_locked);
1777
1778 if (ret < 0) {
1779 pr_err("Error building SET command.\n");
1780 return ret;
1781 }
1782 return finalize_and_send(dev, parse_and_check_status);
1783}
1784
1785static int activate_lsp(struct opal_dev *dev)
1786{
1787 struct opal_lr_act *opal_act;
1788 u8 user_lr[OPAL_UID_LENGTH];
1789 u8 uint_3 = 0x83;
1790 int err = 0, i;
1791
1792 clear_opal_cmd(dev);
1793 set_comid(dev, dev->comid);
1794
1795 opal_act = dev->func_data[dev->state];
1796
1797 add_token_u8(&err, dev, OPAL_CALL);
1798 add_token_bytestring(&err, dev, opaluid[OPAL_LOCKINGSP_UID],
1799 OPAL_UID_LENGTH);
1800 add_token_bytestring(&err, dev, opalmethod[OPAL_ACTIVATE],
1801 OPAL_UID_LENGTH);
1802
1803
1804 if (opal_act->sum) {
1805 err = build_locking_range(user_lr, sizeof(user_lr),
1806 opal_act->lr[0]);
1807 if (err)
1808 return err;
1809
1810 add_token_u8(&err, dev, OPAL_STARTLIST);
1811 add_token_u8(&err, dev, OPAL_STARTNAME);
1812 add_token_u8(&err, dev, uint_3);
1813 add_token_u8(&err, dev, 6);
1814 add_token_u8(&err, dev, 0);
1815 add_token_u8(&err, dev, 0);
1816
1817 add_token_u8(&err, dev, OPAL_STARTLIST);
1818 add_token_bytestring(&err, dev, user_lr, OPAL_UID_LENGTH);
1819 for (i = 1; i < opal_act->num_lrs; i++) {
1820 user_lr[7] = opal_act->lr[i];
1821 add_token_bytestring(&err, dev, user_lr, OPAL_UID_LENGTH);
1822 }
1823 add_token_u8(&err, dev, OPAL_ENDLIST);
1824 add_token_u8(&err, dev, OPAL_ENDNAME);
1825 add_token_u8(&err, dev, OPAL_ENDLIST);
1826
1827 } else {
1828 add_token_u8(&err, dev, OPAL_STARTLIST);
1829 add_token_u8(&err, dev, OPAL_ENDLIST);
1830 }
1831
1832 if (err) {
1833 pr_err("Error building Activate LockingSP command.\n");
1834 return err;
1835 }
1836
1837 return finalize_and_send(dev, parse_and_check_status);
1838}
1839
1840static int get_lsp_lifecycle_cont(struct opal_dev *dev)
1841{
1842 u8 lc_status;
1843 int error = 0;
1844
1845 error = parse_and_check_status(dev);
1846 if (error)
1847 return error;
1848
1849 lc_status = response_get_u64(&dev->parsed, 4);
1850 /* 0x08 is Manufacured Inactive */
1851 /* 0x09 is Manufactured */
1852 if (lc_status != OPAL_MANUFACTURED_INACTIVE) {
1853 pr_err("Couldn't determine the status of the Lifcycle state\n");
1854 return -ENODEV;
1855 }
1856
1857 return 0;
1858}
1859
1860/* Determine if we're in the Manufactured Inactive or Active state */
1861static int get_lsp_lifecycle(struct opal_dev *dev)
1862{
1863 int err = 0;
1864
1865 clear_opal_cmd(dev);
1866 set_comid(dev, dev->comid);
1867
1868 add_token_u8(&err, dev, OPAL_CALL);
1869 add_token_bytestring(&err, dev, opaluid[OPAL_LOCKINGSP_UID],
1870 OPAL_UID_LENGTH);
1871 add_token_bytestring(&err, dev, opalmethod[OPAL_GET], OPAL_UID_LENGTH);
1872
1873 add_token_u8(&err, dev, OPAL_STARTLIST);
1874 add_token_u8(&err, dev, OPAL_STARTLIST);
1875
1876 add_token_u8(&err, dev, OPAL_STARTNAME);
1877 add_token_u8(&err, dev, 3); /* Start Column */
1878 add_token_u8(&err, dev, 6); /* Lifecycle Column */
1879 add_token_u8(&err, dev, OPAL_ENDNAME);
1880
1881 add_token_u8(&err, dev, OPAL_STARTNAME);
1882 add_token_u8(&err, dev, 4); /* End Column */
1883 add_token_u8(&err, dev, 6); /* Lifecycle Column */
1884 add_token_u8(&err, dev, OPAL_ENDNAME);
1885
1886 add_token_u8(&err, dev, OPAL_ENDLIST);
1887 add_token_u8(&err, dev, OPAL_ENDLIST);
1888
1889 if (err) {
1890 pr_err("Error Building GET Lifecycle Status command\n");
1891 return err;
1892 }
1893
1894 return finalize_and_send(dev, get_lsp_lifecycle_cont);
1895}
1896
1897static int get_msid_cpin_pin_cont(struct opal_dev *dev)
1898{
1899 const char *msid_pin;
1900 size_t strlen;
1901 int error = 0;
1902
1903 error = parse_and_check_status(dev);
1904 if (error)
1905 return error;
1906
1907 strlen = response_get_string(&dev->parsed, 4, &msid_pin);
1908 if (!msid_pin) {
1909 pr_err("%s: Couldn't extract PIN from response\n", __func__);
1910 return OPAL_INVAL_PARAM;
1911 }
1912
1913 dev->prev_data = kmemdup(msid_pin, strlen, GFP_KERNEL);
1914 if (!dev->prev_data)
1915 return -ENOMEM;
1916
1917 dev->prev_d_len = strlen;
1918
1919 return 0;
1920}
1921
1922static int get_msid_cpin_pin(struct opal_dev *dev)
1923{
1924 int err = 0;
1925
1926 clear_opal_cmd(dev);
1927 set_comid(dev, dev->comid);
1928
1929
1930 add_token_u8(&err, dev, OPAL_CALL);
1931 add_token_bytestring(&err, dev, opaluid[OPAL_C_PIN_MSID],
1932 OPAL_UID_LENGTH);
1933 add_token_bytestring(&err, dev, opalmethod[OPAL_GET], OPAL_UID_LENGTH);
1934
1935 add_token_u8(&err, dev, OPAL_STARTLIST);
1936 add_token_u8(&err, dev, OPAL_STARTLIST);
1937
1938 add_token_u8(&err, dev, OPAL_STARTNAME);
1939 add_token_u8(&err, dev, 3); /* Start Column */
1940 add_token_u8(&err, dev, 3); /* PIN */
1941 add_token_u8(&err, dev, OPAL_ENDNAME);
1942
1943 add_token_u8(&err, dev, OPAL_STARTNAME);
1944 add_token_u8(&err, dev, 4); /* End Column */
1945 add_token_u8(&err, dev, 3); /* Lifecycle Column */
1946 add_token_u8(&err, dev, OPAL_ENDNAME);
1947
1948 add_token_u8(&err, dev, OPAL_ENDLIST);
1949 add_token_u8(&err, dev, OPAL_ENDLIST);
1950
1951 if (err) {
1952 pr_err("Error building Get MSID CPIN PIN command.\n");
1953 return err;
1954 }
1955
1956 return finalize_and_send(dev, get_msid_cpin_pin_cont);
1957}
1958
1959static int build_end_opal_session(struct opal_dev *dev)
1960{
1961 int err = 0;
1962
1963 clear_opal_cmd(dev);
1964
1965 set_comid(dev, dev->comid);
1966 add_token_u8(&err, dev, OPAL_ENDOFSESSION);
1967 return err;
1968}
1969
1970static int end_opal_session(struct opal_dev *dev)
1971{
1972 int ret = build_end_opal_session(dev);
1973
1974 if (ret < 0)
1975 return ret;
1976 return finalize_and_send(dev, end_session_cont);
1977}
1978
1979static int end_opal_session_error(struct opal_dev *dev)
1980{
1981 const opal_step error_end_session[] = {
1982 end_opal_session,
1983 NULL,
1984 };
1985 dev->funcs = error_end_session;
1986 dev->state = 0;
1987 return next(dev);
1988}
1989
1990static inline void setup_opal_dev(struct opal_dev *dev,
1991 const opal_step *funcs)
1992{
1993 dev->state = 0;
1994 dev->funcs = funcs;
1995 dev->tsn = 0;
1996 dev->hsn = 0;
1997 dev->func_data = NULL;
1998 dev->prev_data = NULL;
1999}
2000
2001static int check_opal_support(struct opal_dev *dev)
2002{
2003 static const opal_step funcs[] = {
2004 opal_discovery0,
2005 NULL
2006 };
2007 int ret;
2008
2009 mutex_lock(&dev->dev_lock);
2010 setup_opal_dev(dev, funcs);
2011 ret = next(dev);
2012 dev->supported = !ret;
2013 mutex_unlock(&dev->dev_lock);
2014 return ret;
2015}
2016
4f1244c8 2017struct opal_dev *init_opal_dev(void *data, sec_send_recv *send_recv)
455a7b23 2018{
4f1244c8
CH
2019 struct opal_dev *dev;
2020
2021 dev = kmalloc(sizeof(*dev), GFP_KERNEL);
2022 if (!dev)
2023 return NULL;
2024
2025 INIT_LIST_HEAD(&dev->unlk_lst);
2026 mutex_init(&dev->dev_lock);
2027 dev->data = data;
2028 dev->send_recv = send_recv;
2029 if (check_opal_support(dev) != 0) {
f5b37b7c 2030 pr_debug("Opal is not supported on this device\n");
4f1244c8
CH
2031 kfree(dev);
2032 return NULL;
2033 }
2034 return dev;
455a7b23
SB
2035}
2036EXPORT_SYMBOL(init_opal_dev);
2037
2038static int opal_secure_erase_locking_range(struct opal_dev *dev,
2039 struct opal_session_info *opal_session)
2040{
2041 void *data[3] = { NULL };
2042 static const opal_step erase_funcs[] = {
2043 opal_discovery0,
2044 start_auth_opal_session,
2045 get_active_key,
2046 gen_key,
2047 end_opal_session,
2048 NULL,
2049 };
2050 int ret;
2051
2052 mutex_lock(&dev->dev_lock);
2053 setup_opal_dev(dev, erase_funcs);
2054
2055 dev->func_data = data;
2056 dev->func_data[1] = opal_session;
2057 dev->func_data[2] = &opal_session->opal_key.lr;
2058
2059 ret = next(dev);
2060 mutex_unlock(&dev->dev_lock);
2061 return ret;
2062}
2063
2064static int opal_erase_locking_range(struct opal_dev *dev,
2065 struct opal_session_info *opal_session)
2066{
2067 void *data[3] = { NULL };
2068 static const opal_step erase_funcs[] = {
2069 opal_discovery0,
2070 start_auth_opal_session,
2071 erase_locking_range,
2072 end_opal_session,
2073 NULL,
2074 };
2075 int ret;
2076
2077 mutex_lock(&dev->dev_lock);
2078 setup_opal_dev(dev, erase_funcs);
2079
2080 dev->func_data = data;
2081 dev->func_data[1] = opal_session;
2082 dev->func_data[2] = opal_session;
2083
2084 ret = next(dev);
2085 mutex_unlock(&dev->dev_lock);
2086 return ret;
2087}
2088
2089static int opal_enable_disable_shadow_mbr(struct opal_dev *dev,
2090 struct opal_mbr_data *opal_mbr)
2091{
2092 void *func_data[6] = { NULL };
2093 static const opal_step mbr_funcs[] = {
2094 opal_discovery0,
2095 start_admin1LSP_opal_session,
2096 set_mbr_done,
2097 end_opal_session,
2098 start_admin1LSP_opal_session,
2099 set_mbr_enable_disable,
2100 end_opal_session,
2101 NULL,
2102 };
2103 int ret;
2104
2105 if (opal_mbr->enable_disable != OPAL_MBR_ENABLE &&
2106 opal_mbr->enable_disable != OPAL_MBR_DISABLE)
2107 return -EINVAL;
2108
2109 mutex_lock(&dev->dev_lock);
2110 setup_opal_dev(dev, mbr_funcs);
2111 dev->func_data = func_data;
2112 dev->func_data[1] = &opal_mbr->key;
2113 dev->func_data[2] = &opal_mbr->enable_disable;
2114 dev->func_data[4] = &opal_mbr->key;
2115 dev->func_data[5] = &opal_mbr->enable_disable;
2116 ret = next(dev);
2117 mutex_unlock(&dev->dev_lock);
2118 return ret;
2119}
2120
2121static int opal_save(struct opal_dev *dev, struct opal_lock_unlock *lk_unlk)
2122{
2123 struct opal_suspend_data *suspend;
2124
2125 suspend = kzalloc(sizeof(*suspend), GFP_KERNEL);
2126 if (!suspend)
2127 return -ENOMEM;
2128
2129 suspend->unlk = *lk_unlk;
2130 suspend->lr = lk_unlk->session.opal_key.lr;
2131
2132 mutex_lock(&dev->dev_lock);
2133 setup_opal_dev(dev, NULL);
2134 add_suspend_info(dev, suspend);
2135 mutex_unlock(&dev->dev_lock);
2136 return 0;
2137}
2138
2139static int opal_add_user_to_lr(struct opal_dev *dev,
2140 struct opal_lock_unlock *lk_unlk)
2141{
2142 void *func_data[3] = { NULL };
2143 static const opal_step funcs[] = {
2144 opal_discovery0,
2145 start_admin1LSP_opal_session,
2146 add_user_to_lr,
2147 end_opal_session,
2148 NULL
2149 };
2150 int ret;
2151
2152 if (lk_unlk->l_state != OPAL_RO &&
2153 lk_unlk->l_state != OPAL_RW) {
2154 pr_err("Locking state was not RO or RW\n");
2155 return -EINVAL;
2156 }
2157 if (lk_unlk->session.who < OPAL_USER1 &&
2158 lk_unlk->session.who > OPAL_USER9) {
2159 pr_err("Authority was not within the range of users: %d\n",
2160 lk_unlk->session.who);
2161 return -EINVAL;
2162 }
2163 if (lk_unlk->session.sum) {
2164 pr_err("%s not supported in sum. Use setup locking range\n",
2165 __func__);
2166 return -EINVAL;
2167 }
2168
2169 mutex_lock(&dev->dev_lock);
2170 setup_opal_dev(dev, funcs);
2171 dev->func_data = func_data;
2172 dev->func_data[1] = &lk_unlk->session.opal_key;
2173 dev->func_data[2] = lk_unlk;
2174 ret = next(dev);
2175 mutex_unlock(&dev->dev_lock);
2176 return ret;
2177}
2178
2179static int opal_reverttper(struct opal_dev *dev, struct opal_key *opal)
2180{
2181 void *data[2] = { NULL };
2182 static const opal_step revert_funcs[] = {
2183 opal_discovery0,
2184 start_SIDASP_opal_session,
2185 revert_tper, /* controller will terminate session */
2186 NULL,
2187 };
2188 int ret;
2189
2190 mutex_lock(&dev->dev_lock);
2191 setup_opal_dev(dev, revert_funcs);
2192 dev->func_data = data;
2193 dev->func_data[1] = opal;
2194 ret = next(dev);
2195 mutex_unlock(&dev->dev_lock);
2196 return ret;
2197}
2198
2199static int __opal_lock_unlock_sum(struct opal_dev *dev)
2200{
2201 static const opal_step ulk_funcs_sum[] = {
2202 opal_discovery0,
2203 start_auth_opal_session,
2204 lock_unlock_locking_range_sum,
2205 end_opal_session,
2206 NULL
2207 };
2208
2209 dev->funcs = ulk_funcs_sum;
2210 return next(dev);
2211}
2212
2213static int __opal_lock_unlock(struct opal_dev *dev)
2214{
2215 static const opal_step _unlock_funcs[] = {
2216 opal_discovery0,
2217 start_auth_opal_session,
2218 lock_unlock_locking_range,
2219 end_opal_session,
2220 NULL
2221 };
2222
2223 dev->funcs = _unlock_funcs;
2224 return next(dev);
2225}
2226
2227static int opal_lock_unlock(struct opal_dev *dev, struct opal_lock_unlock *lk_unlk)
2228{
2229 void *func_data[3] = { NULL };
2230 int ret;
2231
2232 if (lk_unlk->session.who < OPAL_ADMIN1 ||
2233 lk_unlk->session.who > OPAL_USER9)
2234 return -EINVAL;
2235
2236 mutex_lock(&dev->dev_lock);
2237 setup_opal_dev(dev, NULL);
2238 dev->func_data = func_data;
2239 dev->func_data[1] = &lk_unlk->session;
2240 dev->func_data[2] = lk_unlk;
2241
2242 if (lk_unlk->session.sum)
2243 ret = __opal_lock_unlock_sum(dev);
2244 else
2245 ret = __opal_lock_unlock(dev);
2246
2247 mutex_unlock(&dev->dev_lock);
2248 return ret;
2249}
2250
2251static int opal_take_ownership(struct opal_dev *dev, struct opal_key *opal)
2252{
2253 static const opal_step owner_funcs[] = {
2254 opal_discovery0,
2255 start_anybodyASP_opal_session,
2256 get_msid_cpin_pin,
2257 end_opal_session,
2258 start_SIDASP_opal_session,
2259 set_sid_cpin_pin,
2260 end_opal_session,
2261 NULL
2262 };
2263 void *data[6] = { NULL };
2264 int ret;
2265
2266 if (!dev)
2267 return -ENODEV;
2268
2269 mutex_lock(&dev->dev_lock);
2270 setup_opal_dev(dev, owner_funcs);
2271 dev->func_data = data;
2272 dev->func_data[4] = opal;
2273 dev->func_data[5] = opal;
2274 ret = next(dev);
2275 mutex_unlock(&dev->dev_lock);
2276 return ret;
2277}
2278
2279static int opal_activate_lsp(struct opal_dev *dev, struct opal_lr_act *opal_lr_act)
2280{
2281 void *data[4] = { NULL };
2282 static const opal_step active_funcs[] = {
2283 opal_discovery0,
2284 start_SIDASP_opal_session, /* Open session as SID auth */
2285 get_lsp_lifecycle,
2286 activate_lsp,
2287 end_opal_session,
2288 NULL
2289 };
2290 int ret;
2291
2292 if (!opal_lr_act->num_lrs || opal_lr_act->num_lrs > OPAL_MAX_LRS)
2293 return -EINVAL;
2294
2295 mutex_lock(&dev->dev_lock);
2296 setup_opal_dev(dev, active_funcs);
2297 dev->func_data = data;
2298 dev->func_data[1] = &opal_lr_act->key;
2299 dev->func_data[3] = opal_lr_act;
2300 ret = next(dev);
2301 mutex_unlock(&dev->dev_lock);
2302 return ret;
2303}
2304
2305static int opal_setup_locking_range(struct opal_dev *dev,
2306 struct opal_user_lr_setup *opal_lrs)
2307{
2308 void *data[3] = { NULL };
2309 static const opal_step lr_funcs[] = {
2310 opal_discovery0,
2311 start_auth_opal_session,
2312 setup_locking_range,
2313 end_opal_session,
2314 NULL,
2315 };
2316 int ret;
2317
2318 mutex_lock(&dev->dev_lock);
2319 setup_opal_dev(dev, lr_funcs);
2320 dev->func_data = data;
2321 dev->func_data[1] = &opal_lrs->session;
2322 dev->func_data[2] = opal_lrs;
2323 ret = next(dev);
2324 mutex_unlock(&dev->dev_lock);
2325 return ret;
2326}
2327
2328static int opal_set_new_pw(struct opal_dev *dev, struct opal_new_pw *opal_pw)
2329{
2330 static const opal_step pw_funcs[] = {
2331 opal_discovery0,
2332 start_auth_opal_session,
2333 set_new_pw,
2334 end_opal_session,
2335 NULL
2336 };
2337 void *data[3] = { NULL };
2338 int ret;
2339
2340 if (opal_pw->session.who < OPAL_ADMIN1 ||
2341 opal_pw->session.who > OPAL_USER9 ||
2342 opal_pw->new_user_pw.who < OPAL_ADMIN1 ||
2343 opal_pw->new_user_pw.who > OPAL_USER9)
2344 return -EINVAL;
2345
2346 mutex_lock(&dev->dev_lock);
2347 setup_opal_dev(dev, pw_funcs);
2348 dev->func_data = data;
2349 dev->func_data[1] = (void *) &opal_pw->session;
2350 dev->func_data[2] = (void *) &opal_pw->new_user_pw;
2351
2352 ret = next(dev);
2353 mutex_unlock(&dev->dev_lock);
2354 return ret;
2355}
2356
2357static int opal_activate_user(struct opal_dev *dev,
2358 struct opal_session_info *opal_session)
2359{
2360 static const opal_step act_funcs[] = {
2361 opal_discovery0,
2362 start_admin1LSP_opal_session,
2363 internal_activate_user,
2364 end_opal_session,
2365 NULL
2366 };
2367 void *data[3] = { NULL };
2368 int ret;
2369
2370 /* We can't activate Admin1 it's active as manufactured */
2371 if (opal_session->who < OPAL_USER1 &&
2372 opal_session->who > OPAL_USER9) {
2373 pr_err("Who was not a valid user: %d\n", opal_session->who);
2374 return -EINVAL;
2375 }
2376
2377 mutex_lock(&dev->dev_lock);
2378 setup_opal_dev(dev, act_funcs);
2379 dev->func_data = data;
2380 dev->func_data[1] = &opal_session->opal_key;
2381 dev->func_data[2] = opal_session;
2382 ret = next(dev);
2383 mutex_unlock(&dev->dev_lock);
2384 return ret;
2385}
2386
2387bool opal_unlock_from_suspend(struct opal_dev *dev)
2388{
2389 struct opal_suspend_data *suspend;
2390 void *func_data[3] = { NULL };
2391 bool was_failure = false;
2392 int ret = 0;
2393
2394 if (!dev)
2395 return false;
2396 if (!dev->supported)
2397 return false;
2398
2399 mutex_lock(&dev->dev_lock);
2400 setup_opal_dev(dev, NULL);
2401 dev->func_data = func_data;
2402
2403 list_for_each_entry(suspend, &dev->unlk_lst, node) {
2404 dev->state = 0;
2405 dev->func_data[1] = &suspend->unlk.session;
2406 dev->func_data[2] = &suspend->unlk;
2407 dev->tsn = 0;
2408 dev->hsn = 0;
2409
2410 if (suspend->unlk.session.sum)
2411 ret = __opal_lock_unlock_sum(dev);
2412 else
2413 ret = __opal_lock_unlock(dev);
2414 if (ret) {
2415 pr_warn("Failed to unlock LR %hhu with sum %d\n",
2416 suspend->unlk.session.opal_key.lr,
2417 suspend->unlk.session.sum);
2418 was_failure = true;
2419 }
2420 }
2421 mutex_unlock(&dev->dev_lock);
2422 return was_failure;
2423}
2424EXPORT_SYMBOL(opal_unlock_from_suspend);
2425
e225c20e 2426int sed_ioctl(struct opal_dev *dev, unsigned int cmd, void __user *arg)
455a7b23 2427{
e225c20e
SB
2428 void *p;
2429 int ret = -ENOTTY;
455a7b23
SB
2430
2431 if (!capable(CAP_SYS_ADMIN))
2432 return -EACCES;
4f1244c8
CH
2433 if (!dev)
2434 return -ENOTSUPP;
455a7b23
SB
2435 if (!dev->supported) {
2436 pr_err("Not supported\n");
2437 return -ENOTSUPP;
2438 }
2439
e225c20e
SB
2440 p = memdup_user(arg, _IOC_SIZE(cmd));
2441 if (IS_ERR(p))
2442 return PTR_ERR(p);
455a7b23 2443
e225c20e
SB
2444 switch (cmd) {
2445 case IOC_OPAL_SAVE:
2446 ret = opal_save(dev, p);
2447 break;
2448 case IOC_OPAL_LOCK_UNLOCK:
2449 ret = opal_lock_unlock(dev, p);
2450 break;
2451 case IOC_OPAL_TAKE_OWNERSHIP:
2452 ret = opal_take_ownership(dev, p);
2453 break;
2454 case IOC_OPAL_ACTIVATE_LSP:
2455 ret = opal_activate_lsp(dev, p);
2456 break;
2457 case IOC_OPAL_SET_PW:
2458 ret = opal_set_new_pw(dev, p);
2459 break;
2460 case IOC_OPAL_ACTIVATE_USR:
2461 ret = opal_activate_user(dev, p);
2462 break;
2463 case IOC_OPAL_REVERT_TPR:
2464 ret = opal_reverttper(dev, p);
2465 break;
2466 case IOC_OPAL_LR_SETUP:
2467 ret = opal_setup_locking_range(dev, p);
2468 break;
2469 case IOC_OPAL_ADD_USR_TO_LR:
2470 ret = opal_add_user_to_lr(dev, p);
2471 break;
2472 case IOC_OPAL_ENABLE_DISABLE_MBR:
2473 ret = opal_enable_disable_shadow_mbr(dev, p);
2474 break;
2475 case IOC_OPAL_ERASE_LR:
2476 ret = opal_erase_locking_range(dev, p);
2477 break;
2478 case IOC_OPAL_SECURE_ERASE_LR:
2479 ret = opal_secure_erase_locking_range(dev, p);
2480 break;
455a7b23
SB
2481 default:
2482 pr_warn("No such Opal Ioctl %u\n", cmd);
2483 }
e225c20e
SB
2484
2485 kfree(p);
2486 return ret;
455a7b23
SB
2487}
2488EXPORT_SYMBOL_GPL(sed_ioctl);