Merge commit 'linus/master' into tracing/kprobes
Conflicts: kernel/trace/Makefile kernel/trace/trace.h kernel/trace/trace_event_types.h kernel/trace/trace_export.c Merge reason: Sync with latest significant tracing core changes.
This commit is contained in:
@@ -22,6 +22,8 @@ lib-y += usercopy_$(BITS).o getuser.o putuser.o
|
||||
lib-y += memcpy_$(BITS).o
|
||||
lib-y += insn.o inat.o
|
||||
|
||||
obj-y += msr-reg.o msr-reg-export.o
|
||||
|
||||
ifeq ($(CONFIG_X86_32),y)
|
||||
obj-y += atomic64_32.o
|
||||
lib-y += checksum_32.o
|
||||
|
5
arch/x86/lib/msr-reg-export.c
Normal file
5
arch/x86/lib/msr-reg-export.c
Normal file
@@ -0,0 +1,5 @@
|
||||
#include <linux/module.h>
|
||||
#include <asm/msr.h>
|
||||
|
||||
EXPORT_SYMBOL(native_rdmsr_safe_regs);
|
||||
EXPORT_SYMBOL(native_wrmsr_safe_regs);
|
102
arch/x86/lib/msr-reg.S
Normal file
102
arch/x86/lib/msr-reg.S
Normal file
@@ -0,0 +1,102 @@
|
||||
#include <linux/linkage.h>
|
||||
#include <linux/errno.h>
|
||||
#include <asm/dwarf2.h>
|
||||
#include <asm/asm.h>
|
||||
#include <asm/msr.h>
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
/*
|
||||
* int native_{rdmsr,wrmsr}_safe_regs(u32 gprs[8]);
|
||||
*
|
||||
* reg layout: u32 gprs[eax, ecx, edx, ebx, esp, ebp, esi, edi]
|
||||
*
|
||||
*/
|
||||
.macro op_safe_regs op
|
||||
ENTRY(native_\op\()_safe_regs)
|
||||
CFI_STARTPROC
|
||||
pushq_cfi %rbx
|
||||
pushq_cfi %rbp
|
||||
movq %rdi, %r10 /* Save pointer */
|
||||
xorl %r11d, %r11d /* Return value */
|
||||
movl (%rdi), %eax
|
||||
movl 4(%rdi), %ecx
|
||||
movl 8(%rdi), %edx
|
||||
movl 12(%rdi), %ebx
|
||||
movl 20(%rdi), %ebp
|
||||
movl 24(%rdi), %esi
|
||||
movl 28(%rdi), %edi
|
||||
CFI_REMEMBER_STATE
|
||||
1: \op
|
||||
2: movl %eax, (%r10)
|
||||
movl %r11d, %eax /* Return value */
|
||||
movl %ecx, 4(%r10)
|
||||
movl %edx, 8(%r10)
|
||||
movl %ebx, 12(%r10)
|
||||
movl %ebp, 20(%r10)
|
||||
movl %esi, 24(%r10)
|
||||
movl %edi, 28(%r10)
|
||||
popq_cfi %rbp
|
||||
popq_cfi %rbx
|
||||
ret
|
||||
3:
|
||||
CFI_RESTORE_STATE
|
||||
movl $-EIO, %r11d
|
||||
jmp 2b
|
||||
|
||||
_ASM_EXTABLE(1b, 3b)
|
||||
CFI_ENDPROC
|
||||
ENDPROC(native_\op\()_safe_regs)
|
||||
.endm
|
||||
|
||||
#else /* X86_32 */
|
||||
|
||||
.macro op_safe_regs op
|
||||
ENTRY(native_\op\()_safe_regs)
|
||||
CFI_STARTPROC
|
||||
pushl_cfi %ebx
|
||||
pushl_cfi %ebp
|
||||
pushl_cfi %esi
|
||||
pushl_cfi %edi
|
||||
pushl_cfi $0 /* Return value */
|
||||
pushl_cfi %eax
|
||||
movl 4(%eax), %ecx
|
||||
movl 8(%eax), %edx
|
||||
movl 12(%eax), %ebx
|
||||
movl 20(%eax), %ebp
|
||||
movl 24(%eax), %esi
|
||||
movl 28(%eax), %edi
|
||||
movl (%eax), %eax
|
||||
CFI_REMEMBER_STATE
|
||||
1: \op
|
||||
2: pushl_cfi %eax
|
||||
movl 4(%esp), %eax
|
||||
popl_cfi (%eax)
|
||||
addl $4, %esp
|
||||
CFI_ADJUST_CFA_OFFSET -4
|
||||
movl %ecx, 4(%eax)
|
||||
movl %edx, 8(%eax)
|
||||
movl %ebx, 12(%eax)
|
||||
movl %ebp, 20(%eax)
|
||||
movl %esi, 24(%eax)
|
||||
movl %edi, 28(%eax)
|
||||
popl_cfi %eax
|
||||
popl_cfi %edi
|
||||
popl_cfi %esi
|
||||
popl_cfi %ebp
|
||||
popl_cfi %ebx
|
||||
ret
|
||||
3:
|
||||
CFI_RESTORE_STATE
|
||||
movl $-EIO, 4(%esp)
|
||||
jmp 2b
|
||||
|
||||
_ASM_EXTABLE(1b, 3b)
|
||||
CFI_ENDPROC
|
||||
ENDPROC(native_\op\()_safe_regs)
|
||||
.endm
|
||||
|
||||
#endif
|
||||
|
||||
op_safe_regs rdmsr
|
||||
op_safe_regs wrmsr
|
||||
|
@@ -175,3 +175,52 @@ int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
|
||||
return err ? err : rv.err;
|
||||
}
|
||||
EXPORT_SYMBOL(wrmsr_safe_on_cpu);
|
||||
|
||||
/*
|
||||
* These variants are significantly slower, but allows control over
|
||||
* the entire 32-bit GPR set.
|
||||
*/
|
||||
struct msr_regs_info {
|
||||
u32 *regs;
|
||||
int err;
|
||||
};
|
||||
|
||||
static void __rdmsr_safe_regs_on_cpu(void *info)
|
||||
{
|
||||
struct msr_regs_info *rv = info;
|
||||
|
||||
rv->err = rdmsr_safe_regs(rv->regs);
|
||||
}
|
||||
|
||||
static void __wrmsr_safe_regs_on_cpu(void *info)
|
||||
{
|
||||
struct msr_regs_info *rv = info;
|
||||
|
||||
rv->err = wrmsr_safe_regs(rv->regs);
|
||||
}
|
||||
|
||||
int rdmsr_safe_regs_on_cpu(unsigned int cpu, u32 *regs)
|
||||
{
|
||||
int err;
|
||||
struct msr_regs_info rv;
|
||||
|
||||
rv.regs = regs;
|
||||
rv.err = -EIO;
|
||||
err = smp_call_function_single(cpu, __rdmsr_safe_regs_on_cpu, &rv, 1);
|
||||
|
||||
return err ? err : rv.err;
|
||||
}
|
||||
EXPORT_SYMBOL(rdmsr_safe_regs_on_cpu);
|
||||
|
||||
int wrmsr_safe_regs_on_cpu(unsigned int cpu, u32 *regs)
|
||||
{
|
||||
int err;
|
||||
struct msr_regs_info rv;
|
||||
|
||||
rv.regs = regs;
|
||||
rv.err = -EIO;
|
||||
err = smp_call_function_single(cpu, __wrmsr_safe_regs_on_cpu, &rv, 1);
|
||||
|
||||
return err ? err : rv.err;
|
||||
}
|
||||
EXPORT_SYMBOL(wrmsr_safe_regs_on_cpu);
|
||||
|
Reference in New Issue
Block a user