aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Moffett <ian@osmora.org>2024-06-04 22:13:30 -0400
committerIan Moffett <ian@osmora.org>2024-06-04 22:15:54 -0400
commit955d6a381f53c234ce1f4d52aa57f183ed9a6e65 (patch)
treea2525bfe5898683b983b82c2bbda693e609e5152
parent31e9919ced2c577e601d17ec02a3d7886f793469 (diff)
kernel/amd64: Support IBRS
Signed-off-by: Ian Moffett <ian@osmora.org>
-rw-r--r--sys/arch/amd64/amd64/machdep.c19
-rw-r--r--sys/arch/amd64/amd64/spectre.S53
-rw-r--r--sys/arch/amd64/conf/GENERIC3
-rw-r--r--sys/include/arch/amd64/msr.h2
4 files changed, 76 insertions, 1 deletions
diff --git a/sys/arch/amd64/amd64/machdep.c b/sys/arch/amd64/amd64/machdep.c
index 19ba28a..275c23e 100644
--- a/sys/arch/amd64/amd64/machdep.c
+++ b/sys/arch/amd64/amd64/machdep.c
@@ -35,6 +35,14 @@
#include <machine/asm.h>
#include <machine/cpuid.h>
+#if defined(__SPECTRE_IBRS)
+#define SPECTRE_IBRS __SPECTRE_IBRS
+#else
+#define SPECTRE_IBRS 0
+#endif
+
+int ibrs_enable(void);
+
static struct cpu_info g_bsp_ci = {0};
static struct gdtr bsp_gdtr = {
.limit = sizeof(struct gdt_entry) * 256 - 1,
@@ -58,6 +66,16 @@ setup_vectors(void)
idt_set_desc(0xE, IDT_TRAP_GATE, ISR(page_fault), 0);
}
+static void
+try_mitigate_spectre(void)
+{
+ if (!SPECTRE_IBRS) {
+ return;
+ }
+
+ ibrs_enable();
+}
+
void
cpu_startup(void)
{
@@ -66,4 +84,5 @@ cpu_startup(void)
setup_vectors();
amd64_write_gs_base((uintptr_t)&g_bsp_ci);
+ try_mitigate_spectre();
}
diff --git a/sys/arch/amd64/amd64/spectre.S b/sys/arch/amd64/amd64/spectre.S
new file mode 100644
index 0000000..6781cbd
--- /dev/null
+++ b/sys/arch/amd64/amd64/spectre.S
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+ #include <machine/msr.h>
+
+ .text
+ .globl ibrs_enable
+ .type ibrs_enable, @function
+ibrs_enable:
+ /* See if it is supported */
+ mov $7, %eax
+ xor %ecx, %ecx
+ cpuid
+ bt $26, %edx
+ jnc fail
+
+ /* Now we enable it */
+ mov $IA32_SPEC_CTL, %ecx
+ rdmsr
+ or $1, %eax
+ wrmsr
+ xor %rax, %rax
+ jmp 1f
+fail:
+ mov $1, %rax
+1:
+ retq
diff --git a/sys/arch/amd64/conf/GENERIC b/sys/arch/amd64/conf/GENERIC
index 70b786d..1a48a94 100644
--- a/sys/arch/amd64/conf/GENERIC
+++ b/sys/arch/amd64/conf/GENERIC
@@ -1 +1,2 @@
-// TODO
+// Kernel options
+option SPECTRE_IBRS yes
diff --git a/sys/include/arch/amd64/msr.h b/sys/include/arch/amd64/msr.h
index bc0dbcb..6ad95f1 100644
--- a/sys/include/arch/amd64/msr.h
+++ b/sys/include/arch/amd64/msr.h
@@ -33,6 +33,7 @@
#define IA32_SPEC_CTL 0x00000048
#define IA32_KERNEL_GS_BASE 0xC0000102
+#if !defined(__ASSEMBLER__)
static inline uint64_t
rdmsr(uint32_t msr_addr)
{
@@ -60,4 +61,5 @@ wrmsr(uint32_t msr_addr, uint64_t value)
);
}
+#endif /* !__ASSEMBLER__ */
#endif /* !_MACHINE_MSR_H_ */