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);