File Index
Files and directories
Sign in
FILE

core.c

File preview with syntax highlighting.

linux-6.19.14/drivers/platform/x86/intel/ifs/core.c C
  1// SPDX-License-Identifier: GPL-2.0-only
  2/* Copyright(c) 2022 Intel Corporation. */
  3
  4#include <linux/bitfield.h>
  5#include <linux/module.h>
  6#include <linux/kdev_t.h>
  7#include <linux/semaphore.h>
  8#include <linux/slab.h>
  9
 10#include <asm/cpu_device_id.h>
 11#include <asm/msr.h>
 12
 13#include "ifs.h"
 14
 15#define X86_MATCH(vfm, array_gen)				\
 16	X86_MATCH_VFM_FEATURE(vfm, X86_FEATURE_CORE_CAPABILITIES, array_gen)
 17
 18static const struct x86_cpu_id ifs_cpu_ids[] __initconst = {
 19	X86_MATCH(INTEL_SAPPHIRERAPIDS_X, ARRAY_GEN0),
 20	X86_MATCH(INTEL_EMERALDRAPIDS_X, ARRAY_GEN0),
 21	X86_MATCH(INTEL_GRANITERAPIDS_X, ARRAY_GEN0),
 22	X86_MATCH(INTEL_GRANITERAPIDS_D, ARRAY_GEN0),
 23	X86_MATCH(INTEL_ATOM_CRESTMONT_X, ARRAY_GEN1),
 24	X86_MATCH(INTEL_ATOM_DARKMONT_X, ARRAY_GEN1),
 25	{}
 26};
 27MODULE_DEVICE_TABLE(x86cpu, ifs_cpu_ids);
 28
 29ATTRIBUTE_GROUPS(plat_ifs);
 30ATTRIBUTE_GROUPS(plat_ifs_array);
 31
 32bool *ifs_pkg_auth;
 33
 34static const struct ifs_test_caps scan_test = {
 35	.integrity_cap_bit = MSR_INTEGRITY_CAPS_PERIODIC_BIST_BIT,
 36	.test_num = IFS_TYPE_SAF,
 37	.image_suffix = "scan",
 38};
 39
 40static const struct ifs_test_caps array_test = {
 41	.integrity_cap_bit = MSR_INTEGRITY_CAPS_ARRAY_BIST_BIT,
 42	.test_num = IFS_TYPE_ARRAY_BIST,
 43};
 44
 45static const struct ifs_test_msrs scan_msrs = {
 46	.copy_hashes = MSR_COPY_SCAN_HASHES,
 47	.copy_hashes_status = MSR_SCAN_HASHES_STATUS,
 48	.copy_chunks = MSR_AUTHENTICATE_AND_COPY_CHUNK,
 49	.copy_chunks_status = MSR_CHUNKS_AUTHENTICATION_STATUS,
 50	.test_ctrl = MSR_SAF_CTRL,
 51};
 52
 53static const struct ifs_test_msrs sbaf_msrs = {
 54	.copy_hashes = MSR_COPY_SBAF_HASHES,
 55	.copy_hashes_status = MSR_SBAF_HASHES_STATUS,
 56	.copy_chunks = MSR_AUTHENTICATE_AND_COPY_SBAF_CHUNK,
 57	.copy_chunks_status = MSR_SBAF_CHUNKS_AUTHENTICATION_STATUS,
 58	.test_ctrl = MSR_SBAF_CTRL,
 59};
 60
 61static const struct ifs_test_caps sbaf_test = {
 62	.integrity_cap_bit = MSR_INTEGRITY_CAPS_SBAF_BIT,
 63	.test_num = IFS_TYPE_SBAF,
 64	.image_suffix = "sbft",
 65};
 66
 67static struct ifs_device ifs_devices[] = {
 68	[IFS_TYPE_SAF] = {
 69		.test_caps = &scan_test,
 70		.test_msrs = &scan_msrs,
 71		.misc = {
 72			.name = "intel_ifs_0",
 73			.minor = MISC_DYNAMIC_MINOR,
 74			.groups = plat_ifs_groups,
 75		},
 76	},
 77	[IFS_TYPE_ARRAY_BIST] = {
 78		.test_caps = &array_test,
 79		.misc = {
 80			.name = "intel_ifs_1",
 81			.minor = MISC_DYNAMIC_MINOR,
 82			.groups = plat_ifs_array_groups,
 83		},
 84	},
 85	[IFS_TYPE_SBAF] = {
 86		.test_caps = &sbaf_test,
 87		.test_msrs = &sbaf_msrs,
 88		.misc = {
 89			.name = "intel_ifs_2",
 90			.minor = MISC_DYNAMIC_MINOR,
 91			.groups = plat_ifs_groups,
 92		},
 93	},
 94};
 95
 96#define IFS_NUMTESTS ARRAY_SIZE(ifs_devices)
 97
 98static void ifs_cleanup(void)
 99{
100	int i;
101
102	for (i = 0; i < IFS_NUMTESTS; i++) {
103		if (ifs_devices[i].misc.this_device)
104			misc_deregister(&ifs_devices[i].misc);
105	}
106	kfree(ifs_pkg_auth);
107}
108
109static int __init ifs_init(void)
110{
111	const struct x86_cpu_id *m;
112	u64 msrval;
113	int i, ret;
114
115	m = x86_match_cpu(ifs_cpu_ids);
116	if (!m)
117		return -ENODEV;
118
119	if (rdmsrq_safe(MSR_IA32_CORE_CAPS, &msrval))
120		return -ENODEV;
121
122	if (!(msrval & MSR_IA32_CORE_CAPS_INTEGRITY_CAPS))
123		return -ENODEV;
124
125	if (rdmsrq_safe(MSR_INTEGRITY_CAPS, &msrval))
126		return -ENODEV;
127
128	ifs_pkg_auth = kmalloc_array(topology_max_packages(), sizeof(bool), GFP_KERNEL);
129	if (!ifs_pkg_auth)
130		return -ENOMEM;
131
132	for (i = 0; i < IFS_NUMTESTS; i++) {
133		if (!(msrval & BIT(ifs_devices[i].test_caps->integrity_cap_bit)))
134			continue;
135		ifs_devices[i].rw_data.generation = FIELD_GET(MSR_INTEGRITY_CAPS_SAF_GEN_MASK,
136							      msrval);
137		ifs_devices[i].rw_data.array_gen = (u32)m->driver_data;
138		ret = misc_register(&ifs_devices[i].misc);
139		if (ret)
140			goto err_exit;
141	}
142	return 0;
143
144err_exit:
145	ifs_cleanup();
146	return ret;
147}
148
149static void __exit ifs_exit(void)
150{
151	ifs_cleanup();
152}
153
154module_init(ifs_init);
155module_exit(ifs_exit);
156
157MODULE_LICENSE("GPL");
158MODULE_DESCRIPTION("Intel In Field Scan (IFS) device");
~/ Read-only file preview.