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

source code of linux/block/sed-opal.c