xref: /linux-6.15/arch/powerpc/kernel/security.c (revision 815069ca)
19a868f63SMichael Ellerman // SPDX-License-Identifier: GPL-2.0+
29a868f63SMichael Ellerman //
39a868f63SMichael Ellerman // Security related flags and so on.
49a868f63SMichael Ellerman //
59a868f63SMichael Ellerman // Copyright 2018, Michael Ellerman, IBM Corporation.
69a868f63SMichael Ellerman 
79a868f63SMichael Ellerman #include <linux/kernel.h>
88ad33041SMichael Ellerman #include <linux/device.h>
9ff348355SMichael Ellerman #include <linux/seq_buf.h>
108ad33041SMichael Ellerman 
119a868f63SMichael Ellerman #include <asm/security_features.h>
122eea7f06SMichal Suchanek #include <asm/setup.h>
139a868f63SMichael Ellerman 
149a868f63SMichael Ellerman 
15e7347a86SMauricio Faria de Oliveira unsigned long powerpc_security_features __read_mostly = SEC_FTR_DEFAULT;
168ad33041SMichael Ellerman 
17*815069caSMichal Suchanek bool barrier_nospec_enabled;
182eea7f06SMichal Suchanek 
192eea7f06SMichal Suchanek static void enable_barrier_nospec(bool enable)
202eea7f06SMichal Suchanek {
212eea7f06SMichal Suchanek 	barrier_nospec_enabled = enable;
222eea7f06SMichal Suchanek 	do_barrier_nospec_fixups(enable);
232eea7f06SMichal Suchanek }
242eea7f06SMichal Suchanek 
258ad33041SMichael Ellerman ssize_t cpu_show_meltdown(struct device *dev, struct device_attribute *attr, char *buf)
268ad33041SMichael Ellerman {
27ff348355SMichael Ellerman 	bool thread_priv;
28ff348355SMichael Ellerman 
29ff348355SMichael Ellerman 	thread_priv = security_ftr_enabled(SEC_FTR_L1D_THREAD_PRIV);
30ff348355SMichael Ellerman 
31ff348355SMichael Ellerman 	if (rfi_flush || thread_priv) {
32ff348355SMichael Ellerman 		struct seq_buf s;
33ff348355SMichael Ellerman 		seq_buf_init(&s, buf, PAGE_SIZE - 1);
34ff348355SMichael Ellerman 
35ff348355SMichael Ellerman 		seq_buf_printf(&s, "Mitigation: ");
36ff348355SMichael Ellerman 
378ad33041SMichael Ellerman 		if (rfi_flush)
38ff348355SMichael Ellerman 			seq_buf_printf(&s, "RFI Flush");
39ff348355SMichael Ellerman 
40ff348355SMichael Ellerman 		if (rfi_flush && thread_priv)
41ff348355SMichael Ellerman 			seq_buf_printf(&s, ", ");
42ff348355SMichael Ellerman 
43ff348355SMichael Ellerman 		if (thread_priv)
44ff348355SMichael Ellerman 			seq_buf_printf(&s, "L1D private per thread");
45ff348355SMichael Ellerman 
46ff348355SMichael Ellerman 		seq_buf_printf(&s, "\n");
47ff348355SMichael Ellerman 
48ff348355SMichael Ellerman 		return s.len;
49ff348355SMichael Ellerman 	}
50ff348355SMichael Ellerman 
51ff348355SMichael Ellerman 	if (!security_ftr_enabled(SEC_FTR_L1D_FLUSH_HV) &&
52ff348355SMichael Ellerman 	    !security_ftr_enabled(SEC_FTR_L1D_FLUSH_PR))
53ff348355SMichael Ellerman 		return sprintf(buf, "Not affected\n");
548ad33041SMichael Ellerman 
558ad33041SMichael Ellerman 	return sprintf(buf, "Vulnerable\n");
568ad33041SMichael Ellerman }
5756986016SMichael Ellerman 
5856986016SMichael Ellerman ssize_t cpu_show_spectre_v1(struct device *dev, struct device_attribute *attr, char *buf)
5956986016SMichael Ellerman {
6056986016SMichael Ellerman 	if (!security_ftr_enabled(SEC_FTR_BNDS_CHK_SPEC_BAR))
6156986016SMichael Ellerman 		return sprintf(buf, "Not affected\n");
6256986016SMichael Ellerman 
6356986016SMichael Ellerman 	return sprintf(buf, "Vulnerable\n");
6456986016SMichael Ellerman }
65d6fbe1c5SMichael Ellerman 
66d6fbe1c5SMichael Ellerman ssize_t cpu_show_spectre_v2(struct device *dev, struct device_attribute *attr, char *buf)
67d6fbe1c5SMichael Ellerman {
68d6fbe1c5SMichael Ellerman 	bool bcs, ccd, ori;
69d6fbe1c5SMichael Ellerman 	struct seq_buf s;
70d6fbe1c5SMichael Ellerman 
71d6fbe1c5SMichael Ellerman 	seq_buf_init(&s, buf, PAGE_SIZE - 1);
72d6fbe1c5SMichael Ellerman 
73d6fbe1c5SMichael Ellerman 	bcs = security_ftr_enabled(SEC_FTR_BCCTRL_SERIALISED);
74d6fbe1c5SMichael Ellerman 	ccd = security_ftr_enabled(SEC_FTR_COUNT_CACHE_DISABLED);
75d6fbe1c5SMichael Ellerman 	ori = security_ftr_enabled(SEC_FTR_SPEC_BAR_ORI31);
76d6fbe1c5SMichael Ellerman 
77d6fbe1c5SMichael Ellerman 	if (bcs || ccd) {
78d6fbe1c5SMichael Ellerman 		seq_buf_printf(&s, "Mitigation: ");
79d6fbe1c5SMichael Ellerman 
80d6fbe1c5SMichael Ellerman 		if (bcs)
81d6fbe1c5SMichael Ellerman 			seq_buf_printf(&s, "Indirect branch serialisation (kernel only)");
82d6fbe1c5SMichael Ellerman 
83d6fbe1c5SMichael Ellerman 		if (bcs && ccd)
84d6fbe1c5SMichael Ellerman 			seq_buf_printf(&s, ", ");
85d6fbe1c5SMichael Ellerman 
86d6fbe1c5SMichael Ellerman 		if (ccd)
87d6fbe1c5SMichael Ellerman 			seq_buf_printf(&s, "Indirect branch cache disabled");
88d6fbe1c5SMichael Ellerman 	} else
89d6fbe1c5SMichael Ellerman 		seq_buf_printf(&s, "Vulnerable");
90d6fbe1c5SMichael Ellerman 
91d6fbe1c5SMichael Ellerman 	if (ori)
92d6fbe1c5SMichael Ellerman 		seq_buf_printf(&s, ", ori31 speculation barrier enabled");
93d6fbe1c5SMichael Ellerman 
94d6fbe1c5SMichael Ellerman 	seq_buf_printf(&s, "\n");
95d6fbe1c5SMichael Ellerman 
96d6fbe1c5SMichael Ellerman 	return s.len;
97d6fbe1c5SMichael Ellerman }
98