WIP FPC-III support
[linux/fpc-iii.git] / arch / powerpc / platforms / powernv / opal-secvar.c
blob14133e120bdd26896dbc514cf94fbf706733c020
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * PowerNV code for secure variables
5 * Copyright (C) 2019 IBM Corporation
6 * Author: Claudio Carvalho
7 * Nayna Jain
9 * APIs to access secure variables managed by OPAL.
12 #define pr_fmt(fmt) "secvar: "fmt
14 #include <linux/types.h>
15 #include <linux/platform_device.h>
16 #include <linux/of_platform.h>
17 #include <asm/opal.h>
18 #include <asm/secvar.h>
19 #include <asm/secure_boot.h>
21 static int opal_status_to_err(int rc)
23 int err;
25 switch (rc) {
26 case OPAL_SUCCESS:
27 err = 0;
28 break;
29 case OPAL_UNSUPPORTED:
30 err = -ENXIO;
31 break;
32 case OPAL_PARAMETER:
33 err = -EINVAL;
34 break;
35 case OPAL_RESOURCE:
36 err = -ENOSPC;
37 break;
38 case OPAL_HARDWARE:
39 err = -EIO;
40 break;
41 case OPAL_NO_MEM:
42 err = -ENOMEM;
43 break;
44 case OPAL_EMPTY:
45 err = -ENOENT;
46 break;
47 case OPAL_PARTIAL:
48 err = -EFBIG;
49 break;
50 default:
51 err = -EINVAL;
54 return err;
57 static int opal_get_variable(const char *key, uint64_t ksize,
58 u8 *data, uint64_t *dsize)
60 int rc;
62 if (!key || !dsize)
63 return -EINVAL;
65 *dsize = cpu_to_be64(*dsize);
67 rc = opal_secvar_get(key, ksize, data, dsize);
69 *dsize = be64_to_cpu(*dsize);
71 return opal_status_to_err(rc);
74 static int opal_get_next_variable(const char *key, uint64_t *keylen,
75 uint64_t keybufsize)
77 int rc;
79 if (!key || !keylen)
80 return -EINVAL;
82 *keylen = cpu_to_be64(*keylen);
84 rc = opal_secvar_get_next(key, keylen, keybufsize);
86 *keylen = be64_to_cpu(*keylen);
88 return opal_status_to_err(rc);
91 static int opal_set_variable(const char *key, uint64_t ksize, u8 *data,
92 uint64_t dsize)
94 int rc;
96 if (!key || !data)
97 return -EINVAL;
99 rc = opal_secvar_enqueue_update(key, ksize, data, dsize);
101 return opal_status_to_err(rc);
104 static const struct secvar_operations opal_secvar_ops = {
105 .get = opal_get_variable,
106 .get_next = opal_get_next_variable,
107 .set = opal_set_variable,
110 static int opal_secvar_probe(struct platform_device *pdev)
112 if (!opal_check_token(OPAL_SECVAR_GET)
113 || !opal_check_token(OPAL_SECVAR_GET_NEXT)
114 || !opal_check_token(OPAL_SECVAR_ENQUEUE_UPDATE)) {
115 pr_err("OPAL doesn't support secure variables\n");
116 return -ENODEV;
119 set_secvar_ops(&opal_secvar_ops);
121 return 0;
124 static const struct of_device_id opal_secvar_match[] = {
125 { .compatible = "ibm,secvar-backend",},
129 static struct platform_driver opal_secvar_driver = {
130 .driver = {
131 .name = "secvar",
132 .of_match_table = opal_secvar_match,
136 static int __init opal_secvar_init(void)
138 return platform_driver_probe(&opal_secvar_driver, opal_secvar_probe);
140 device_initcall(opal_secvar_init);