1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 2024 Rivos Inc. 4 */ 5 6 #include <linux/cpu.h> 7 #include <linux/device.h> 8 #include <linux/sprintf.h> 9 10 #include <asm/bugs.h> 11 #include <asm/vendor_extensions/thead.h> 12 13 static enum mitigation_state ghostwrite_state; 14 15 void ghostwrite_set_vulnerable(void) 16 { 17 ghostwrite_state = VULNERABLE; 18 } 19 20 /* 21 * Vendor extension alternatives will use the value set at the time of boot 22 * alternative patching, thus this must be called before boot alternatives are 23 * patched (and after extension probing) to be effective. 24 * 25 * Returns true if mitgated, false otherwise. 26 */ 27 bool ghostwrite_enable_mitigation(void) 28 { 29 if (IS_ENABLED(CONFIG_RISCV_ISA_XTHEADVECTOR) && 30 ghostwrite_state == VULNERABLE && !cpu_mitigations_off()) { 31 disable_xtheadvector(); 32 ghostwrite_state = MITIGATED; 33 return true; 34 } 35 36 return false; 37 } 38 39 enum mitigation_state ghostwrite_get_state(void) 40 { 41 return ghostwrite_state; 42 } 43 44 ssize_t cpu_show_ghostwrite(struct device *dev, struct device_attribute *attr, char *buf) 45 { 46 if (IS_ENABLED(CONFIG_RISCV_ISA_XTHEADVECTOR)) { 47 switch (ghostwrite_state) { 48 case UNAFFECTED: 49 return sprintf(buf, "Not affected\n"); 50 case MITIGATED: 51 return sprintf(buf, "Mitigation: xtheadvector disabled\n"); 52 case VULNERABLE: 53 fallthrough; 54 default: 55 return sprintf(buf, "Vulnerable\n"); 56 } 57 } else { 58 return sprintf(buf, "Not affected\n"); 59 } 60 } 61