[haiku-commits] haiku: hrev53411 - in src/system/kernel/arch/x86: 64 32

  • From: Adrien Destugues <pulkomandy@xxxxxxxxx>
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Tue, 27 Aug 2019 06:03:41 -0400 (EDT)

hrev53411 adds 1 changeset to branch 'master'
old head: d7818b5aaeb3e2a9da65dd1858f51b7f14d1d279
new head: 26e0b0c8d6541be2940be0ac429d5660147f5619
overview: 
https://git.haiku-os.org/haiku/log/?qt=range&q=26e0b0c8d654+%5Ed7818b5aaeb3

----------------------------------------------------------------------------

26e0b0c8d654: kernel/x86_64: Add errata patching.
  
  The patched errata are only the AMD ones FreeBSD patches
  (it seems there are no Intel errata that can be patched
  this way, they are all in microcode updates ... or can't
  be patched in the CPU at all.)
  
  This also seems to be roughly the point in the boot that
  FreeBSD patches these, too, despite how "critical" some
  of them seem.
  
  Change-Id: I9065f8d025332418a21c2cdf39afd7d29405edcc
  Reviewed-on: https://review.haiku-os.org/c/haiku/+/1740
  Reviewed-by: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx>

                              [ Augustin Cavalier <waddlesplash@xxxxxxxxx> ]

----------------------------------------------------------------------------

Revision:    hrev53411
Commit:      26e0b0c8d6541be2940be0ac429d5660147f5619
URL:         https://git.haiku-os.org/haiku/commit/?id=26e0b0c8d654
Author:      Augustin Cavalier <waddlesplash@xxxxxxxxx>
Date:        Sat Aug 24 19:32:24 2019 UTC
Committer:   Adrien Destugues <pulkomandy@xxxxxxxxx>
Commit-Date: Tue Aug 27 10:03:39 2019 UTC

----------------------------------------------------------------------------

5 files changed, 128 insertions(+), 1 deletion(-)
headers/private/kernel/arch/x86/arch_cpu.h |   2 +
src/system/kernel/arch/x86/32/errata.cpp   |  18 +++++
src/system/kernel/arch/x86/64/errata.cpp   | 105 +++++++++++++++++++++++++
src/system/kernel/arch/x86/Jamfile         |   2 +
src/system/kernel/arch/x86/arch_cpu.cpp    |   2 +-

----------------------------------------------------------------------------

diff --git a/headers/private/kernel/arch/x86/arch_cpu.h 
b/headers/private/kernel/arch/x86/arch_cpu.h
index dc4b3d1e23..e4ea1e21fb 100644
--- a/headers/private/kernel/arch/x86/arch_cpu.h
+++ b/headers/private/kernel/arch/x86/arch_cpu.h
@@ -557,6 +557,8 @@ void __x86_setup_system_time(uint32 conversionFactor,
        uint32 conversionFactorNsecs, bool conversionFactorNsecsShift);
 #endif
 
+status_t __x86_patch_errata_percpu(int cpu);
+
 void x86_userspace_thread_exit(void);
 void x86_end_userspace_thread_exit(void);
 
diff --git a/src/system/kernel/arch/x86/32/errata.cpp 
b/src/system/kernel/arch/x86/32/errata.cpp
new file mode 100644
index 0000000000..8b4a80f890
--- /dev/null
+++ b/src/system/kernel/arch/x86/32/errata.cpp
@@ -0,0 +1,18 @@
+/*
+ * Copyright 2019, Haiku, Inc. All rights reserved.
+ * Distributed under the terms of the MIT License.
+ *
+ * Authors:
+ *             Augustin Cavalier <waddlesplash>
+ */
+
+#include <cpu.h>
+#include <arch_cpu.h>
+
+
+status_t
+__x86_patch_errata_percpu(int currentCPU)
+{
+       // TODO.
+       return B_OK;
+}
diff --git a/src/system/kernel/arch/x86/64/errata.cpp 
b/src/system/kernel/arch/x86/64/errata.cpp
new file mode 100644
index 0000000000..0ecf7da3fb
--- /dev/null
+++ b/src/system/kernel/arch/x86/64/errata.cpp
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2019, Haiku, Inc. All rights reserved.
+ * Distributed under the terms of the MIT License.
+ *
+ * Authors:
+ *             Augustin Cavalier <waddlesplash>
+ */
+
+#include <cpu.h>
+#include <arch_cpu.h>
+
+
+static status_t
+patch_errata_percpu_amd(int currentCPU, const cpu_ent* cpu)
+{
+       // There are no errata to patch on a hypervisor, the host will have
+       // already taken care of everything for us.
+       if (x86_check_feature(IA32_FEATURE_EXT_HYPERVISOR, FEATURE_EXT))
+               return B_OK;
+
+       const uint32 family = cpu->arch.family + cpu->arch.extended_family,
+               model = (cpu->arch.extended_model << 4) | cpu->arch.model;
+
+       // Family 10h and 12h, Erratum 721:
+       //
+       // "Under a highly specific and detailed set of internal timing 
conditions,
+       // the processor may incorrectly update the stack pointer after a long
+       // series of push and/or near-call instructions, or a long series of pop
+       // and/or near-return instructions.
+       //
+       // https://www.amd.com/system/files/TechDocs/41322_10h_Rev_Gd.pdf
+       // https://www.amd.com/system/files/TechDocs/44739_12h_Rev_Gd.pdf
+       switch (family) {
+       case 0x10:
+       case 0x12:
+               x86_write_msr(0xc0011029, x86_read_msr(0xc0011029) | 1);
+               break;
+       }
+
+       // Family 16h ("Jaguar"), Erratum 793:
+       //
+       // "Under a highly specific and detailed set of internal timing 
conditions,
+       // a locked instruction may trigger a timing sequence whereby the write 
to
+       // a write combined memory type is not flushed, causing the locked 
instruction
+       // to stall indefinitely."
+       //
+       // 
https://www.amd.com/system/files/TechDocs/53072_Rev_Guide_16h_Models_30h-3Fh.pdf
+       if (family == 0x16 && model <= 0xf) {
+               x86_write_msr(0xc0011020, x86_read_msr(0xc0011020) | ((uint64)1 
<< 15));
+       }
+
+       // Family 17h ("Zen") Model 1h
+       // 
https://www.amd.com/system/files/TechDocs/55449_Fam_17h_M_00h-0Fh_Rev_Guide.pdf
+       if (family == 0x17 && model == 0x1) {
+               // Erratum 1021:
+               //
+               // "Under a highly specific and detailed set of internal timing
+               // conditions, a load operation may incorrectly receive stale 
data
+               // from an older store operation."
+               x86_write_msr(0xc0011029, x86_read_msr(0xc0011029) | (1 << 13));
+
+               // Erratum 1033:
+               //
+               // "Under a highly specific and detailed set of internal timing
+               // conditions, a Lock operation may cause the system to hang."
+               x86_write_msr(0xc0011020, x86_read_msr(0xc0011020) | (1 << 4));
+
+               // Erratum 1049:
+               //
+               // "Under a highly specific and detailed set of internal timing
+               // conditions, an FCMOV instruction may yield incorrect data if 
the
+               // following sequence of events occurs:
+               //  * An FCOMI instruction
+               //  * A non-FP instruction that modifies RFLAGS
+               //  * An FCMOV instruction."
+               x86_write_msr(0xc0011028, x86_read_msr(0xc0011028) | (1 << 4));
+
+               // Erratum 1095:
+               //
+               // Under a highly detailed and specific set of internal timing
+               // conditions, a lock operation may not fence a younger load 
operation
+               // correctly when the following conditions are met:
+               //  * SMT (Simultaneous Multithreading) is enabled, and
+               //  * a lock operation on memory location A, followed by a load
+               //    operation on memory location B are executing on one 
thread while
+               //  * a lock operation on memory location B, followed by a load 
operation
+               //    on memory location A are executing on the second thread 
on the
+               //    same core.
+               // This may result in the load operations on both threads 
incorrectly
+               // receiving pre-lock data."
+               x86_write_msr(0xc0011020, x86_read_msr(0xc0011020) | ((uint64)1 
<< 57));
+       }
+
+       return B_OK;
+}
+
+
+status_t
+__x86_patch_errata_percpu(int currentCPU)
+{
+       const cpu_ent* cpu = get_cpu_struct();
+       if (cpu->arch.vendor == VENDOR_AMD)
+               return patch_errata_percpu_amd(currentCPU, cpu);
+       return B_OK;
+}
diff --git a/src/system/kernel/arch/x86/Jamfile 
b/src/system/kernel/arch/x86/Jamfile
index dd068ac875..fee9cbdd4a 100644
--- a/src/system/kernel/arch/x86/Jamfile
+++ b/src/system/kernel/arch/x86/Jamfile
@@ -24,6 +24,7 @@ if $(TARGET_ARCH) = x86_64 {
                arch.S
                cpuid.cpp
                descriptors.cpp
+               errata.cpp
                interrupts.S
                signals.cpp
                signals_asm.S
@@ -49,6 +50,7 @@ if $(TARGET_ARCH) = x86_64 {
                bios.cpp
                cpuid.S
                descriptors.cpp
+               errata.cpp
                interrupts.S
                signals.cpp
                signals_asm.S
diff --git a/src/system/kernel/arch/x86/arch_cpu.cpp 
b/src/system/kernel/arch/x86/arch_cpu.cpp
index 11b6ede26f..653e43dd71 100644
--- a/src/system/kernel/arch/x86/arch_cpu.cpp
+++ b/src/system/kernel/arch/x86/arch_cpu.cpp
@@ -1135,7 +1135,7 @@ arch_cpu_init_percpu(kernel_args* args, int cpu)
                        gCpuIdleFunc = halt_idle;
        }
 
-       return B_OK;
+       return __x86_patch_errata_percpu(cpu);
 }
 
 


Other related posts:

  • » [haiku-commits] haiku: hrev53411 - in src/system/kernel/arch/x86: 64 32 - Adrien Destugues