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