summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormlarkin <mlarkin@openbsd.org>2019-01-20 00:53:08 +0000
committermlarkin <mlarkin@openbsd.org>2019-01-20 00:53:08 +0000
commit6f4c4614c4fc04a76572b96b17282c73ce060c60 (patch)
treebe83d1cf9bf8b80337cf43ff9c5c7bc6edadff80
parentfix SMALL_KERNEL build after changes in rev 1.361 (diff)
downloadwireguard-openbsd-6f4c4614c4fc04a76572b96b17282c73ce060c60.tar.xz
wireguard-openbsd-6f4c4614c4fc04a76572b96b17282c73ce060c60.zip
Implement rdmsr_safe
rdmsr_safe is used when reading potentially missing MSRs, to avoid triggering #GPs in the kernel. ok guenther
-rw-r--r--sys/arch/amd64/amd64/locore.S24
-rw-r--r--sys/arch/amd64/amd64/vector.S15
-rw-r--r--sys/arch/amd64/include/cpufunc.h4
3 files changed, 38 insertions, 5 deletions
diff --git a/sys/arch/amd64/amd64/locore.S b/sys/arch/amd64/amd64/locore.S
index 67147ed2376..788e50eb1a6 100644
--- a/sys/arch/amd64/amd64/locore.S
+++ b/sys/arch/amd64/amd64/locore.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: locore.S,v 1.111 2018/10/07 22:43:06 guenther Exp $ */
+/* $OpenBSD: locore.S,v 1.112 2019/01/20 00:53:08 mlarkin Exp $ */
/* $NetBSD: locore.S,v 1.13 2004/03/25 18:33:17 drochner Exp $ */
/*
@@ -1143,6 +1143,28 @@ ENTRY(pagezero)
RETGUARD_CHECK(pagezero, r11)
ret
+/* int rdmsr_safe(u_int msr, uint64_t *data) */
+ENTRY(rdmsr_safe)
+ RETGUARD_SETUP(rdmsr_safe_return, r10)
+
+ movl %edi, %ecx /* u_int msr */
+ .globl rdmsr_safe_fault
+rdmsr_safe_fault:
+ rdmsr
+ salq $32, %rdx
+ movl %eax, %eax
+ orq %rdx, %rax
+ movq %rax, (%rsi) /* *data */
+ xorq %rax, %rax
+
+ RETGUARD_CHECK(rdmsr_safe_return, r10)
+ ret
+
+NENTRY(rdmsr_resume)
+ movl $0x1, %eax
+ RETGUARD_CHECK(rdmsr_safe_return, r10)
+ ret
+
#if NXEN > 0
/* Hypercall page needs to be page aligned */
.text
diff --git a/sys/arch/amd64/amd64/vector.S b/sys/arch/amd64/amd64/vector.S
index dc51e24ec3e..4cbd92a28b4 100644
--- a/sys/arch/amd64/amd64/vector.S
+++ b/sys/arch/amd64/amd64/vector.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: vector.S,v 1.78 2019/01/01 03:19:37 guenther Exp $ */
+/* $OpenBSD: vector.S,v 1.79 2019/01/20 00:53:08 mlarkin Exp $ */
/* $NetBSD: vector.S,v 1.5 2004/06/28 09:13:11 fvdl Exp $ */
/*
@@ -263,11 +263,12 @@ IDTVEC(trap0c)
TRAP(T_STKFLT)
/*
- * The #GP (general protection fault) handler has a couple weird cases
+ * The #GP (general protection fault) handler has a few weird cases
* to handle:
* - trapping in iretq to userspace and
* - trapping in xrstor in the kernel.
- * We detect both of these by examining the %rip in the iretq_frame.
+ * - trapping when invalid MSRs are read in rdmsr_safe
+ * We detect these by examining the %rip in the iretq_frame.
* Handling them is done by updating %rip in the iretq_frame to point
* to a stub handler of some sort and then iretq'ing to it. For the
* iretq fault we resume in a stub which acts like we got a fresh #GP.
@@ -287,10 +288,18 @@ IDTVEC(trap0d)
leaq xsetbv_fault(%rip),%rcx
cmpq %rcx,%rdx
je .Lhandle_xsetbv
+ leaq rdmsr_safe_fault(%rip),%rcx
+ cmpq %rcx,%rdx
+ je .Lhandle_rdmsr_safe
popq %rcx
popq %rdx
TRAP(T_PROTFLT)
+.Lhandle_rdmsr_safe:
+ /* rdmsr faulted; just resume in rdmsr_resume */
+ leaq rdmsr_resume(%rip),%rcx
+ jmp 1f
+
.Lhandle_xrstor:
/* xrstor faulted; just resume in xrstor_resume */
leaq xrstor_resume(%rip),%rcx
diff --git a/sys/arch/amd64/include/cpufunc.h b/sys/arch/amd64/include/cpufunc.h
index 5e2437e1b95..edca45c5c2d 100644
--- a/sys/arch/amd64/include/cpufunc.h
+++ b/sys/arch/amd64/include/cpufunc.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: cpufunc.h,v 1.31 2018/10/04 05:00:40 guenther Exp $ */
+/* $OpenBSD: cpufunc.h,v 1.32 2019/01/20 00:53:08 mlarkin Exp $ */
/* $NetBSD: cpufunc.h,v 1.3 2003/05/08 10:27:43 fvdl Exp $ */
/*-
@@ -353,6 +353,8 @@ void cpu_ucode_apply(struct cpu_info *);
struct cpu_info_full;
void cpu_enter_pages(struct cpu_info_full *);
+int rdmsr_safe(u_int msr, uint64_t *);
+
#endif /* _KERNEL */
#endif /* !_MACHINE_CPUFUNC_H_ */