1 /* 2 * Copyright 2019-2023, Haiku, Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Augustin Cavalier <waddlesplash> 7 */ 8 9 #include <cpu.h> 10 #include <arch_cpu.h> 11 12 13 static bool 14 needs_zenbleed_patch(const uint32 family, const uint32 model, const uint64 microcode) 15 { 16 if (family != 0x17) 17 return false; 18 19 // https://github.com/torvalds/linux/blob/522b1d6921/arch/x86/kernel/cpu/amd.c#L986 20 if (model >= 0x30 && model <= 0x3f) 21 return (microcode < 0x0830107a); 22 if (model >= 0x60 && model <= 0x67) 23 return (microcode < 0x0860010b); 24 if (model >= 0x68 && model <= 0x6f) 25 return (microcode < 0x08608105); 26 if (model >= 0x70 && model <= 0x7f) 27 return (microcode < 0x08701032); 28 if (model >= 0xa0 && model <= 0xaf) 29 return (microcode < 0x08a00008); 30 31 return false; 32 } 33 34 35 static status_t 36 patch_errata_percpu_amd(int currentCPU, const cpu_ent* cpu) 37 { 38 // There are no errata to patch on a hypervisor, the host will have 39 // already taken care of everything for us. 40 if (x86_check_feature(IA32_FEATURE_EXT_HYPERVISOR, FEATURE_EXT)) 41 return B_OK; 42 43 const uint32 family = cpu->arch.family + cpu->arch.extended_family, 44 model = (cpu->arch.extended_model << 4) | cpu->arch.model; 45 const uint64 microcode = x86_read_msr(IA32_MSR_UCODE_REV); 46 47 // Family 10h and 12h, Erratum 721: 48 // 49 // "Under a highly specific and detailed set of internal timing conditions, 50 // the processor may incorrectly update the stack pointer after a long 51 // series of push and/or near-call instructions, or a long series of pop 52 // and/or near-return instructions. 53 // 54 // https://www.amd.com/system/files/TechDocs/41322_10h_Rev_Gd.pdf 55 // https://www.amd.com/system/files/TechDocs/44739_12h_Rev_Gd.pdf 56 switch (family) { 57 case 0x10: 58 case 0x12: 59 x86_write_msr(0xc0011029, x86_read_msr(0xc0011029) | 1); 60 break; 61 } 62 63 // Family 16h ("Jaguar"), Erratum 793: 64 // 65 // "Under a highly specific and detailed set of internal timing conditions, 66 // a locked instruction may trigger a timing sequence whereby the write to 67 // a write combined memory type is not flushed, causing the locked instruction 68 // to stall indefinitely." 69 // 70 // https://www.amd.com/system/files/TechDocs/53072_Rev_Guide_16h_Models_30h-3Fh.pdf 71 if (family == 0x16 && model <= 0xf) { 72 x86_write_msr(0xc0011020, x86_read_msr(0xc0011020) | ((uint64)1 << 15)); 73 } 74 75 // Family 17h ("Zen") Model 1h 76 // https://www.amd.com/system/files/TechDocs/55449_Fam_17h_M_00h-0Fh_Rev_Guide.pdf 77 if (family == 0x17 && model == 0x1) { 78 // Erratum 1021: 79 // 80 // "Under a highly specific and detailed set of internal timing 81 // conditions, a load operation may incorrectly receive stale data 82 // from an older store operation." 83 x86_write_msr(0xc0011029, x86_read_msr(0xc0011029) | (1 << 13)); 84 85 // Erratum 1033: 86 // 87 // "Under a highly specific and detailed set of internal timing 88 // conditions, a Lock operation may cause the system to hang." 89 x86_write_msr(0xc0011020, x86_read_msr(0xc0011020) | (1 << 4)); 90 91 // Erratum 1049: 92 // 93 // "Under a highly specific and detailed set of internal timing 94 // conditions, an FCMOV instruction may yield incorrect data if the 95 // following sequence of events occurs: 96 // * An FCOMI instruction 97 // * A non-FP instruction that modifies RFLAGS 98 // * An FCMOV instruction." 99 x86_write_msr(0xc0011028, x86_read_msr(0xc0011028) | (1 << 4)); 100 101 // Erratum 1095: 102 // 103 // Under a highly detailed and specific set of internal timing 104 // conditions, a lock operation may not fence a younger load operation 105 // correctly when the following conditions are met: 106 // * SMT (Simultaneous Multithreading) is enabled, and 107 // * a lock operation on memory location A, followed by a load 108 // operation on memory location B are executing on one thread while 109 // * a lock operation on memory location B, followed by a load operation 110 // on memory location A are executing on the second thread on the 111 // same core. 112 // This may result in the load operations on both threads incorrectly 113 // receiving pre-lock data." 114 x86_write_msr(0xc0011020, x86_read_msr(0xc0011020) | ((uint64)1 << 57)); 115 } 116 117 // Family 17h ("Zen") 118 // Cross-Process Information Leak (aka. "Zenbleed") 119 // https://www.amd.com/en/resources/product-security/bulletin/amd-sb-7008.html 120 if (needs_zenbleed_patch(family, model, microcode)) { 121 x86_write_msr(MSR_F10H_DE_CFG, x86_read_msr(MSR_F10H_DE_CFG) | (1 << 9)); 122 } 123 124 return B_OK; 125 } 126 127 128 status_t 129 __x86_patch_errata_percpu(int currentCPU) 130 { 131 const cpu_ent* cpu = get_cpu_struct(); 132 if (cpu->arch.vendor == VENDOR_AMD 133 || cpu->arch.vendor == VENDOR_HYGON) { 134 return patch_errata_percpu_amd(currentCPU, cpu); 135 } 136 return B_OK; 137 } 138