1 // SPDX-License-Identifier: GPL-2.0
3 * PowerNV code for secure variables
5 * Copyright (C) 2019 IBM Corporation
6 * Author: Claudio Carvalho
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>
18 #include <asm/secvar.h>
19 #include <asm/secure_boot.h>
21 static int opal_status_to_err(int rc)
29 case OPAL_UNSUPPORTED:
57 static int opal_get_variable(const char *key, u64 ksize, u8 *data, u64 *dsize)
64 *dsize = cpu_to_be64(*dsize);
66 rc = opal_secvar_get(key, ksize, data, dsize);
68 *dsize = be64_to_cpu(*dsize);
70 return opal_status_to_err(rc);
73 static int opal_get_next_variable(const char *key, u64 *keylen, u64 keybufsize)
80 *keylen = cpu_to_be64(*keylen);
82 rc = opal_secvar_get_next(key, keylen, keybufsize);
84 *keylen = be64_to_cpu(*keylen);
86 return opal_status_to_err(rc);
89 static int opal_set_variable(const char *key, u64 ksize, u8 *data, u64 dsize)
96 rc = opal_secvar_enqueue_update(key, ksize, data, dsize);
98 return opal_status_to_err(rc);
101 static ssize_t opal_secvar_format(char *buf, size_t bufsize)
104 struct device_node *node;
107 node = of_find_compatible_node(NULL, NULL, "ibm,secvar-backend");
108 if (!of_device_is_available(node)) {
113 rc = of_property_read_string(node, "format", &format);
117 rc = snprintf(buf, bufsize, "%s", format);
125 static int opal_secvar_max_size(u64 *max_size)
128 struct device_node *node;
130 node = of_find_compatible_node(NULL, NULL, "ibm,secvar-backend");
134 if (!of_device_is_available(node)) {
139 rc = of_property_read_u64(node, "max-var-size", max_size);
146 static const struct secvar_operations opal_secvar_ops = {
147 .get = opal_get_variable,
148 .get_next = opal_get_next_variable,
149 .set = opal_set_variable,
150 .format = opal_secvar_format,
151 .max_size = opal_secvar_max_size,
154 static int opal_secvar_probe(struct platform_device *pdev)
156 if (!opal_check_token(OPAL_SECVAR_GET)
157 || !opal_check_token(OPAL_SECVAR_GET_NEXT)
158 || !opal_check_token(OPAL_SECVAR_ENQUEUE_UPDATE)) {
159 pr_err("OPAL doesn't support secure variables\n");
163 return set_secvar_ops(&opal_secvar_ops);
166 static const struct of_device_id opal_secvar_match[] = {
167 { .compatible = "ibm,secvar-backend",},
171 static struct platform_driver opal_secvar_driver = {
174 .of_match_table = opal_secvar_match,
178 static int __init opal_secvar_init(void)
180 return platform_driver_probe(&opal_secvar_driver, opal_secvar_probe);
182 device_initcall(opal_secvar_init);