PowerVM PLPKS variables are exposed via fwsecurityfs. Initialize fwsecurityfs arch-specific structure with plpks configuration. Eg: [root@ltcfleet35-lp1 config]# pwd /sys/firmware/security/plpks/config [root@ltcfleet35-lp1 config]# ls -ltrh total 0 -r--r--r-- 1 root root 1 Sep 28 15:01 version -r--r--r-- 1 root root 4 Sep 28 15:01 used_space -r--r--r-- 1 root root 4 Sep 28 15:01 total_size -r--r--r-- 1 root root 2 Sep 28 15:01 max_object_size -r--r--r-- 1 root root 2 Sep 28 15:01 max_object_label_size Signed-off-by: Nayna Jain <nayna@xxxxxxxxxxxxx> --- arch/powerpc/platforms/pseries/Kconfig | 10 ++ arch/powerpc/platforms/pseries/Makefile | 1 + .../platforms/pseries/fwsecurityfs_arch.c | 116 ++++++++++++++++++ include/linux/fwsecurityfs.h | 4 + 4 files changed, 131 insertions(+) create mode 100644 arch/powerpc/platforms/pseries/fwsecurityfs_arch.c diff --git a/arch/powerpc/platforms/pseries/Kconfig b/arch/powerpc/platforms/pseries/Kconfig index a3b4d99567cb..5fb45e601982 100644 --- a/arch/powerpc/platforms/pseries/Kconfig +++ b/arch/powerpc/platforms/pseries/Kconfig @@ -162,6 +162,16 @@ config PSERIES_PLPKS If unsure, select N. +config PSERIES_FWSECURITYFS_ARCH + select FWSECURITYFS + bool "Support fwsecurityfs for pseries" + help + Enable fwsecurityfs arch specific code. This would initialize + the firmware security filesystem with initial platform specific + structure. + + If you are unsure how to use it, say N. + config PAPR_SCM depends on PPC_PSERIES && MEMORY_HOTPLUG && LIBNVDIMM tristate "Support for the PAPR Storage Class Memory interface" diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile index 92310202bdd7..2903cff26258 100644 --- a/arch/powerpc/platforms/pseries/Makefile +++ b/arch/powerpc/platforms/pseries/Makefile @@ -28,6 +28,7 @@ obj-$(CONFIG_PPC_SPLPAR) += vphn.o obj-$(CONFIG_PPC_SVM) += svm.o obj-$(CONFIG_FA_DUMP) += rtas-fadump.o obj-$(CONFIG_PSERIES_PLPKS) += plpks.o +obj-$(CONFIG_PSERIES_FWSECURITYFS_ARCH) += fwsecurityfs_arch.o obj-$(CONFIG_SUSPEND) += suspend.o obj-$(CONFIG_PPC_VAS) += vas.o vas-sysfs.o diff --git a/arch/powerpc/platforms/pseries/fwsecurityfs_arch.c b/arch/powerpc/platforms/pseries/fwsecurityfs_arch.c new file mode 100644 index 000000000000..b43bd3cf7889 --- /dev/null +++ b/arch/powerpc/platforms/pseries/fwsecurityfs_arch.c @@ -0,0 +1,116 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Initialize fwsecurityfs with POWER LPAR Platform KeyStore (PLPKS) + * Copyright (C) 2022 IBM Corporation + * Author: Nayna Jain <nayna@xxxxxxxxxxxxx> + * + */ + +#include <linux/fwsecurityfs.h> +#include "plpks.h" + +static struct dentry *plpks_dir; + +static ssize_t plpks_config_file_read(struct file *file, char __user *userbuf, + size_t count, loff_t *ppos) +{ + u8 out[4]; + u32 outlen; + size_t size; + char *name; + u32 data; + + name = file_dentry(file)->d_iname; + + if (strcmp(name, "max_object_size") == 0) { + outlen = sizeof(u16); + data = plpks_get_maxobjectsize(); + } else if (strcmp(name, "max_object_label_size") == 0) { + outlen = sizeof(u16); + data = plpks_get_maxobjectlabelsize(); + } else if (strcmp(name, "total_size") == 0) { + outlen = sizeof(u32); + data = plpks_get_totalsize(); + } else if (strcmp(name, "used_space") == 0) { + outlen = sizeof(u32); + data = plpks_get_usedspace(); + } else if (strcmp(name, "version") == 0) { + outlen = sizeof(u8); + data = plpks_get_version(); + } else { + return -EINVAL; + } + + memcpy(out, &data, outlen); + + size = simple_read_from_buffer(userbuf, count, ppos, out, outlen); + + return size; +} + +static const struct file_operations plpks_config_file_operations = { + .open = simple_open, + .read = plpks_config_file_read, + .llseek = no_llseek, +}; + +static int create_plpks_dir(void) +{ + struct dentry *config_dir; + struct dentry *fdentry; + + if (!IS_ENABLED(CONFIG_PSERIES_PLPKS) || !plpks_is_available()) { + pr_warn("Platform KeyStore is not available on this LPAR\n"); + return 0; + } + + plpks_dir = fwsecurityfs_create_dir("plpks", S_IFDIR | 0755, NULL, + NULL); + if (IS_ERR(plpks_dir)) { + pr_err("Unable to create PLPKS dir: %ld\n", PTR_ERR(plpks_dir)); + return PTR_ERR(plpks_dir); + } + + config_dir = fwsecurityfs_create_dir("config", S_IFDIR | 0755, plpks_dir, NULL); + if (IS_ERR(config_dir)) { + pr_err("Unable to create config dir: %ld\n", PTR_ERR(config_dir)); + return PTR_ERR(config_dir); + } + + fdentry = fwsecurityfs_create_file("max_object_size", S_IFREG | 0444, + sizeof(u16), config_dir, NULL, NULL, + &plpks_config_file_operations); + if (IS_ERR(fdentry)) + pr_err("Could not create max object size %ld\n", PTR_ERR(fdentry)); + + fdentry = fwsecurityfs_create_file("max_object_label_size", S_IFREG | 0444, + sizeof(u16), config_dir, NULL, NULL, + &plpks_config_file_operations); + if (IS_ERR(fdentry)) + pr_err("Could not create max object label size %ld\n", PTR_ERR(fdentry)); + + fdentry = fwsecurityfs_create_file("total_size", S_IFREG | 0444, + sizeof(u32), config_dir, NULL, NULL, + &plpks_config_file_operations); + if (IS_ERR(fdentry)) + pr_err("Could not create total size %ld\n", PTR_ERR(fdentry)); + + fdentry = fwsecurityfs_create_file("used_space", S_IFREG | 0444, + sizeof(u32), config_dir, NULL, NULL, + &plpks_config_file_operations); + if (IS_ERR(fdentry)) + pr_err("Could not create used space %ld\n", PTR_ERR(fdentry)); + + fdentry = fwsecurityfs_create_file("version", S_IFREG | 0444, + sizeof(u8), config_dir, NULL, NULL, + &plpks_config_file_operations); + if (IS_ERR(fdentry)) + pr_err("Could not create version %ld\n", PTR_ERR(fdentry)); + + return 0; +} + +int arch_fwsecurityfs_init(void) +{ + return create_plpks_dir(); +} diff --git a/include/linux/fwsecurityfs.h b/include/linux/fwsecurityfs.h index ed8f328f3133..38fcb3cb374e 100644 --- a/include/linux/fwsecurityfs.h +++ b/include/linux/fwsecurityfs.h @@ -21,9 +21,13 @@ struct dentry *fwsecurityfs_create_dir(const char *name, umode_t mode, const struct inode_operations *iops); int fwsecurityfs_remove_dir(struct dentry *dentry); +#ifdef CONFIG_PSERIES_FWSECURITYFS_ARCH +int arch_fwsecurityfs_init(void); +#else static int arch_fwsecurityfs_init(void) { return 0; } +#endif #endif /* _FWSECURITYFS_H_ */ -- 2.31.1