// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (C) 2025 IBM Corporation, Srish Srinivasan * * This code exposes PLPKS config to user via sysfs */ #define pr_fmt(fmt) "plpks-sysfs: "fmt #include #include #include #include #include /* config attributes for sysfs */ #define PLPKS_CONFIG_ATTR(name, fmt, func) \ static ssize_t name##_show(struct kobject *kobj, \ struct kobj_attribute *attr, \ char *buf) \ { \ return sysfs_emit(buf, fmt, func()); \ } \ static struct kobj_attribute attr_##name = __ATTR_RO(name) PLPKS_CONFIG_ATTR(version, "%u\n", plpks_get_version); PLPKS_CONFIG_ATTR(max_object_size, "%u\n", plpks_get_maxobjectsize); PLPKS_CONFIG_ATTR(total_size, "%u\n", plpks_get_totalsize); PLPKS_CONFIG_ATTR(used_space, "%u\n", plpks_get_usedspace); PLPKS_CONFIG_ATTR(supported_policies, "%08x\n", plpks_get_supportedpolicies); PLPKS_CONFIG_ATTR(signed_update_algorithms, "%016llx\n", plpks_get_signedupdatealgorithms); PLPKS_CONFIG_ATTR(wrapping_features, "%016llx\n", plpks_get_wrappingfeatures); static const struct attribute *config_attrs[] = { &attr_version.attr, &attr_max_object_size.attr, &attr_total_size.attr, &attr_used_space.attr, &attr_supported_policies.attr, &attr_signed_update_algorithms.attr, &attr_wrapping_features.attr, NULL, }; static struct kobject *plpks_kobj, *plpks_config_kobj; int plpks_config_create_softlink(struct kobject *from) { if (!plpks_config_kobj) return -EINVAL; return sysfs_create_link(from, plpks_config_kobj, "config"); } static __init int plpks_sysfs_config(struct kobject *kobj) { struct attribute_group config_group = { .name = NULL, .attrs = (struct attribute **)config_attrs, }; return sysfs_create_group(kobj, &config_group); } static __init int plpks_sysfs_init(void) { int rc; if (!plpks_is_available()) return -ENODEV; plpks_kobj = kobject_create_and_add("plpks", firmware_kobj); if (!plpks_kobj) { pr_err("Failed to create plpks kobj\n"); return -ENOMEM; } plpks_config_kobj = kobject_create_and_add("config", plpks_kobj); if (!plpks_config_kobj) { pr_err("Failed to create plpks config kobj\n"); kobject_put(plpks_kobj); return -ENOMEM; } rc = plpks_sysfs_config(plpks_config_kobj); if (rc) { pr_err("Failed to create attribute group for plpks config\n"); kobject_put(plpks_config_kobj); kobject_put(plpks_kobj); return rc; } return 0; } machine_subsys_initcall(pseries, plpks_sysfs_init);