Module Name: src
Committed By: jym
Date: Sat Sep 24 10:32:53 UTC 2011
Modified Files:
src/sys/arch/amd64/amd64: cpufunc.S
src/sys/arch/i386/i386: cpufunc.S
src/sys/arch/x86/include: cpufunc.h
Log Message:
Import rdmsr_safe(msr, *value) for x86 world. It allows reading MSRs
in a safe way by handling the fault that might trigger for certain
register <> CPU/arch combos.
Requested by Jukka. Patch adapted from one found in DragonflyBSD.
To generate a diff of this commit:
cvs rdiff -u -r1.19 -r1.20 src/sys/arch/amd64/amd64/cpufunc.S
cvs rdiff -u -r1.15 -r1.16 src/sys/arch/i386/i386/cpufunc.S
cvs rdiff -u -r1.12 -r1.13 src/sys/arch/x86/include/cpufunc.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/amd64/amd64/cpufunc.S
diff -u src/sys/arch/amd64/amd64/cpufunc.S:1.19 src/sys/arch/amd64/amd64/cpufunc.S:1.20
--- src/sys/arch/amd64/amd64/cpufunc.S:1.19 Sun Jun 12 03:35:37 2011
+++ src/sys/arch/amd64/amd64/cpufunc.S Sat Sep 24 10:32:52 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: cpufunc.S,v 1.19 2011/06/12 03:35:37 rmind Exp $ */
+/* $NetBSD: cpufunc.S,v 1.20 2011/09/24 10:32:52 jym Exp $ */
/*-
* Copyright (c) 1998, 2007, 2008 The NetBSD Foundation, Inc.
@@ -33,6 +33,8 @@
* Functions to provide access to i386-specific instructions.
*/
+#include <sys/errno.h>
+
#include <machine/asm.h>
#include <machine/frameasm.h>
#include <machine/specialreg.h>
@@ -221,6 +223,37 @@
wrmsr
ret
+/*
+ * Support for reading MSRs in the safe manner (returns EFAULT on fault)
+ */
+/* int rdmsr_safe(u_int msr, uint64_t *data) */
+ENTRY(rdmsr_safe)
+ movq CPUVAR(CURLWP), %r8
+ movq L_PCB(%r8), %r8
+ movq $_C_LABEL(msr_onfault), PCB_ONFAULT(%r8)
+
+ movl %edi, %ecx /* u_int msr */
+ rdmsr /* Read MSR pointed by %ecx. Returns
+ hi byte in edx, lo in %eax */
+ salq $32, %rdx /* sign-shift %rdx left */
+ movl %eax, %eax /* zero-extend %eax -> %rax */
+ orq %rdx, %rax
+ movq %rax, (%rsi) /* *data */
+ xorq %rax, %rax /* "no error" */
+
+ movq %rax, PCB_ONFAULT(%r8)
+ ret
+
+/*
+ * MSR operations fault handler
+ */
+NENTRY(msr_onfault)
+ movq CPUVAR(CURLWP), %r8
+ movq L_PCB(%r8), %r8
+ movq $0, PCB_ONFAULT(%r8)
+ movl $EFAULT, %eax
+ ret
+
#ifndef XEN
ENTRY(wbinvd)
wbinvd
Index: src/sys/arch/i386/i386/cpufunc.S
diff -u src/sys/arch/i386/i386/cpufunc.S:1.15 src/sys/arch/i386/i386/cpufunc.S:1.16
--- src/sys/arch/i386/i386/cpufunc.S:1.15 Fri Mar 18 15:32:02 2011
+++ src/sys/arch/i386/i386/cpufunc.S Sat Sep 24 10:32:52 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: cpufunc.S,v 1.15 2011/03/18 15:32:02 joerg Exp $ */
+/* $NetBSD: cpufunc.S,v 1.16 2011/09/24 10:32:52 jym Exp $ */
/*-
* Copyright (c) 1998, 2007 The NetBSD Foundation, Inc.
@@ -35,8 +35,10 @@
* These are shared with NetBSD/xen.
*/
+#include <sys/errno.h>
+
#include <machine/asm.h>
-__KERNEL_RCSID(0, "$NetBSD: cpufunc.S,v 1.15 2011/03/18 15:32:02 joerg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpufunc.S,v 1.16 2011/09/24 10:32:52 jym Exp $");
#include "opt_xen.h"
@@ -137,6 +139,40 @@
ret
END(wrmsr_locked)
+/*
+ * Support for reading MSRs in the safe manner (returns EFAULT on fault)
+ */
+/* int rdmsr_safe(u_int msr, uint64_t *data) */
+ENTRY(rdmsr_safe)
+ movl CPUVAR(CURLWP), %ecx
+ movl L_PCB(%ecx), %ecx
+ movl $_C_LABEL(msr_onfault), PCB_ONFAULT(%ecx)
+
+ movl 4(%esp), %ecx /* u_int msr */
+ rdmsr
+ movl 8(%esp), %ecx /* *data */
+ movl %eax, (%ecx) /* low-order bits */
+ movl %edx, 4(%ecx) /* high-order bits */
+ xorl %eax, %eax /* "no error" */
+
+ movl CPUVAR(CURLWP), %ecx
+ movl L_PCB(%ecx), %ecx
+ movl %eax, PCB_ONFAULT(%ecx)
+
+ ret
+
+/*
+ * MSR operations fault handler
+ */
+NENTRY(msr_onfault)
+ movl CPUVAR(CURLWP), %ecx
+ movl L_PCB(%ecx), %ecx
+ movl $0, PCB_ONFAULT(%ecx)
+ movl $EFAULT, %eax
+ ret
+
+END(rdmsr_safe)
+
ENTRY(cpu_counter)
rdtsc
addl CPUVAR(CC_SKEW), %eax
Index: src/sys/arch/x86/include/cpufunc.h
diff -u src/sys/arch/x86/include/cpufunc.h:1.12 src/sys/arch/x86/include/cpufunc.h:1.13
--- src/sys/arch/x86/include/cpufunc.h:1.12 Wed Jul 7 01:14:53 2010
+++ src/sys/arch/x86/include/cpufunc.h Sat Sep 24 10:32:52 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: cpufunc.h,v 1.12 2010/07/07 01:14:53 chs Exp $ */
+/* $NetBSD: cpufunc.h,v 1.13 2011/09/24 10:32:52 jym Exp $ */
/*-
* Copyright (c) 1998, 2007 The NetBSD Foundation, Inc.
@@ -118,6 +118,7 @@
uint64_t rdmsr(u_int);
uint64_t rdmsr_locked(u_int, u_int);
+int rdmsr_safe(u_int, uint64_t *);
uint64_t rdtsc(void);
uint64_t rdpmc(u_int);
void wrmsr(u_int, uint64_t);