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