On Wed, Apr 20, 2022 at 09:48:58AM +0200, Greg KH wrote: > Don't write code today for stuff you do not have right now, you all know > that. We can always revisit it in the future. Direction check on the virtual device option. Is this what you are asking for in "core.c"? The second test type is happening internally right away ... so I put in some example code of how it can be added. Upstream submission will just have the one test that exists today. Static definition of: static struct ifs_data ifs_data[IFS_NUMTESTS]; keeps the code simpler (no need to have code to cleanup if dynamic allocation of this small structure fails). But if you feel strongly that all static allocation is bad, then I can kzallloc() per enumerated test type. With this change it is no longer a platform driver. So maybe doesn't belong in drivers/platform/x86/intel/ifs/* Any thoughts on where I should move it to? -Tony ---- core.c --- // SPDX-License-Identifier: GPL-2.0-only /* Copyright(c) 2022 Intel Corporation. */ #include <linux/module.h> #include <linux/device.h> #include <linux/kdev_t.h> #include <linux/semaphore.h> #include <asm/cpu_device_id.h> #include "ifs.h" enum test_types { IFS_SAF, IFS_ANOTHER, IFS_NUMTESTS }; static struct class *ifs_class; static struct ifs_data ifs_data[IFS_NUMTESTS]; #define MSR_IA32_CORE_CAPS_INTEGRITY_BIT 2 #define MSR_IA32_CORE_CAPS_INTEGRITY BIT(MSR_IA32_CORE_CAPS_INTEGRITY_BIT) #define X86_MATCH(model) \ X86_MATCH_VENDOR_FAM_MODEL_FEATURE(INTEL, 6, \ INTEL_FAM6_##model, X86_FEATURE_CORE_CAPABILITIES, NULL) static const struct x86_cpu_id ifs_cpu_ids[] __initconst = { X86_MATCH(SAPPHIRERAPIDS_X), {} }; MODULE_DEVICE_TABLE(x86cpu, ifs_cpu_ids); static int ifs_device_unregister(struct device *dev, void *data) { device_unregister(dev); return 0; } static int __init ifs_init(void) { const struct x86_cpu_id *m; u64 ia32_core_caps; struct device *dev; int ndevices = 0; int ret = 0; m = x86_match_cpu(ifs_cpu_ids); if (!m) return -ENODEV; if (rdmsrl_safe(MSR_IA32_CORE_CAPS, &ia32_core_caps)) return -ENODEV; ifs_class = class_create(THIS_MODULE, "intel_ifs"); if (IS_ERR(ifs_class)) return PTR_ERR(ifs_class); ret = ifs_setup_wq(); if (ret) goto class_cleanup; if (ia32_core_caps & MSR_IA32_CORE_CAPS_INTEGRITY) { dev = device_create_with_groups(ifs_class, NULL, MKDEV(0, 0), &ifs_data[IFS_SAF], plat_ifs_groups, "ifs%d", IFS_SAF); if (dev) { ndevices++; down(&ifs_sem); ifs_data[IFS_SAF].loaded = !ifs_load_firmware(dev); up(&ifs_sem); } } if (1) { // placeholder to test 2nd test dev = device_create_with_groups(ifs_class, NULL, MKDEV(0, 0), &ifs_data[IFS_ANOTHER], plat_ifs_groups, "ifs%d", IFS_ANOTHER); if (dev) ndevices++; } if (ndevices) goto done; ret = -ENODEV; class_for_each_device(ifs_class, NULL, NULL, ifs_device_unregister); class_cleanup: class_destroy(ifs_class); done: return ret; } static void __exit ifs_exit(void) { class_for_each_device(ifs_class, NULL, NULL, ifs_device_unregister); class_destroy(ifs_class); ifs_destroy_wq(); } module_init(ifs_init); module_exit(ifs_exit); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Intel In Field Scan (IFS) driver");