Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1369949 > unrolled thread

[PATCH v5 0/9] Improve non-"safe" MSR access failure handling

Started byAndy Lutomirski <luto@kernel.org>
First post2016-04-02 16:10 +0200
Last post2016-04-05 17:40 +0200
Articles 19 on this page of 39 — 10 participants

Back to article view | Back to linux.kernel


Contents

  [PATCH v5 0/9] Improve non-"safe" MSR access failure handling Andy Lutomirski <luto@kernel.org> - 2016-04-02 16:10 +0200
    [PATCH v5 5/9] x86/paravirt: Add _safe to the read_msr and write_msr PV hooks Andy Lutomirski <luto@kernel.org> - 2016-04-02 16:10 +0200
      Re: [PATCH v5 5/9] x86/paravirt: Add _safe to the read_msr and  write_msr PV hooks Borislav Petkov <bp@alien8.de> - 2016-04-03 10:50 +0200
        Re: [PATCH v5 5/9] x86/paravirt: Add _safe to the read_msr and  write_msr PV hooks Andy Lutomirski <luto@amacapital.net> - 2016-04-03 15:30 +0200
          Re: [PATCH v5 5/9] x86/paravirt: Add _safe to the read_msr and  write_msr PV hooks Borislav Petkov <bp@alien8.de> - 2016-04-03 16:10 +0200
      [tip:x86/asm] x86/paravirt: Add _safe to the read_ms()r and  write_msr() PV callbacks tip-bot for Andy Lutomirski <tipbot@zytor.com> - 2016-04-13 13:50 +0200
    [PATCH v5 8/9] x86/paravirt: Make "unsafe" MSR accesses unsafe even if PARAVIRT=y Andy Lutomirski <luto@kernel.org> - 2016-04-02 16:10 +0200
      [tip:x86/asm] x86/paravirt: Make "unsafe" MSR accesses unsafe even  if PARAVIRT=y tip-bot for Andy Lutomirski <tipbot@zytor.com> - 2016-04-13 13:50 +0200
    [PATCH v5 2/9] x86/head: Move the early NMI fixup into C Andy Lutomirski <luto@kernel.org> - 2016-04-02 16:10 +0200
      [tip:x86/asm] x86/head: Move the early NMI fixup into C tip-bot for Andy Lutomirski <tipbot@zytor.com> - 2016-04-13 13:50 +0200
    [PATCH v5 3/9] x86/head: Move early exception panic code into early_fixup_exception Andy Lutomirski <luto@kernel.org> - 2016-04-02 16:10 +0200
      Re: [PATCH v5 3/9] x86/head: Move early exception panic code into  early_fixup_exception Borislav Petkov <bp@alien8.de> - 2016-04-02 20:40 +0200
        Re: [PATCH v5 3/9] x86/head: Move early exception panic code into early_fixup_exception Andy Lutomirski <luto@amacapital.net> - 2016-04-02 22:20 +0200
          Re: [PATCH v5 3/9] x86/head: Move early exception panic code into  early_fixup_exception Borislav Petkov <bp@alien8.de> - 2016-04-02 22:50 +0200
            Re: [PATCH v5 3/9] x86/head: Move early exception panic code into early_fixup_exception Andy Lutomirski <luto@amacapital.net> - 2016-04-02 23:00 +0200
              Re: [PATCH v5 3/9] x86/head: Move early exception panic code into  early_fixup_exception Jan Kara <jack@suse.cz> - 2016-04-04 14:00 +0200
                Re: [PATCH v5 3/9] x86/head: Move early exception panic code into  early_fixup_exception Peter Zijlstra <peterz@infradead.org> - 2016-04-04 14:50 +0200
                Re: [PATCH v5 3/9] x86/head: Move early exception panic code into  early_fixup_exception Arjan van de Ven <arjan@linux.intel.com> - 2016-04-04 17:40 +0200
                Re: [PATCH v5 3/9] x86/head: Move early exception panic code into early_fixup_exception Andy Lutomirski <luto@amacapital.net> - 2016-04-04 17:40 +0200
                  Re: [PATCH v5 3/9] x86/head: Move early exception panic code into  early_fixup_exception Peter Zijlstra <peterz@infradead.org> - 2016-04-04 18:10 +0200
                    Re: [PATCH v5 3/9] x86/head: Move early exception panic code into  early_fixup_exception Borislav Petkov <bp@alien8.de> - 2016-04-04 21:40 +0200
                      Re: [PATCH v5 3/9] x86/head: Move early exception panic code into early_fixup_exception Andy Lutomirski <luto@amacapital.net> - 2016-04-04 23:40 +0200
                        Re: [PATCH v5 3/9] x86/head: Move early exception panic code into  early_fixup_exception Borislav Petkov <bp@alien8.de> - 2016-04-04 23:50 +0200
      [tip:x86/asm] x86/head: Move early exception panic code into  early_fixup_exception() tip-bot for Andy Lutomirski <tipbot@zytor.com> - 2016-04-13 13:50 +0200
    [PATCH v5 7/9] x86/paravirt: Add paravirt_{read,write}_msr Andy Lutomirski <luto@kernel.org> - 2016-04-02 16:10 +0200
      Re: [Xen-devel] [PATCH v5 7/9] x86/paravirt: Add paravirt_{read,  write}_msr David Vrabel <david.vrabel@citrix.com> - 2016-04-04 18:40 +0200
        Re: [Xen-devel] [PATCH v5 7/9] x86/paravirt: Add paravirt_{read, write}_msr Andy Lutomirski <luto@amacapital.net> - 2016-04-04 18:50 +0200
      [tip:x86/asm] x86/paravirt: Add paravirt_{read,write}_msr() tip-bot for Andy Lutomirski <tipbot@zytor.com> - 2016-04-13 13:50 +0200
    [PATCH v5 1/9] x86/head: Pass a real pt_regs and trapnr to early_fixup_exception Andy Lutomirski <luto@kernel.org> - 2016-04-02 16:10 +0200
      [tip:x86/asm] x86/head: Pass a real pt_regs and trapnr to  early_fixup_exception() tip-bot for Andy Lutomirski <tipbot@zytor.com> - 2016-04-13 13:50 +0200
    [PATCH v5 6/9] x86/msr: Carry on after a non-"safe" MSR access fails Andy Lutomirski <luto@kernel.org> - 2016-04-02 16:10 +0200
      [tip:x86/asm] x86/msr: Carry on after a non-"safe" MSR access fails tip-bot for Andy Lutomirski <tipbot@zytor.com> - 2016-04-13 13:50 +0200
    [PATCH v5 9/9] x86/msr: Set the return value to zero when native_rdmsr_safe fails Andy Lutomirski <luto@kernel.org> - 2016-04-02 16:10 +0200
      [tip:x86/asm] x86/msr: Set the return value to zero when  native_rdmsr_safe() fails tip-bot for Andy Lutomirski <tipbot@zytor.com> - 2016-04-13 13:50 +0200
    Re: [PATCH v5 0/9] Improve non-"safe" MSR access failure handling Linus Torvalds <torvalds@linux-foundation.org> - 2016-04-02 16:30 +0200
      Re: [PATCH v5 0/9] Improve non-"safe" MSR access failure handling Andy Lutomirski <luto@amacapital.net> - 2016-04-02 17:20 +0200
        Re: [PATCH v5 0/9] Improve non-"safe" MSR access failure handling Linus Torvalds <torvalds@linux-foundation.org> - 2016-04-02 17:30 +0200
    Re: [PATCH v5 0/9] Improve non-"safe" MSR access failure handling Borislav Petkov <bp@alien8.de> - 2016-04-04 18:30 +0200
    Re: [Xen-devel] [PATCH v5 0/9] Improve non-"safe" MSR access failure  handling Boris Ostrovsky <boris.ostrovsky@oracle.com> - 2016-04-05 17:40 +0200

Page 2 of 2 — ← Prev page 1 [2]


#1370836 — Re: [PATCH v5 3/9] x86/head: Move early exception panic code into early_fixup_exception

FromBorislav Petkov <bp@alien8.de>
Date2016-04-04 21:40 +0200
SubjectRe: [PATCH v5 3/9] x86/head: Move early exception panic code into early_fixup_exception
Message-ID<rkivU-86a-13@gated-at.bofh.it>
In reply to#1370723
On Mon, Apr 04, 2016 at 06:00:42PM +0200, Peter Zijlstra wrote:
> On Mon, Apr 04, 2016 at 08:32:21AM -0700, Andy Lutomirski wrote:
> 
> > Adding locking would be easy enough, wouldn't it?
> 
> See patch in this thread..
> 
> > But do any platforms really boot a second CPU before switching to real
> > printk? 
> 
> I _only_ use early_printk() as printk() is a quagmire of fail :-)

And since I'm the king of minimalistic changes... this below
works. However, the problem is that we need to pull up all that
early_param parsing in order to enable the early console, i.e.
"earlyprintk=ttyS0,115200" cmdline parsing.

And we can do all that after having setup the IDT. So I'd need to do
some early dancing with cmdline_find_option_bool(boot_command_line, ...
in asm or so. Need to think about it more.

---
diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c
index 1f4422d5c8d0..ad534226653b 100644
--- a/arch/x86/kernel/head64.c
+++ b/arch/x86/kernel/head64.c
@@ -130,6 +130,13 @@ static void __init copy_bootdata(char *real_mode_data)
 	}
 }
 
+static int _early_printk(const char *fmt, va_list args)
+{
+	early_printk(fmt, args);
+
+	return 0;
+}
+
 asmlinkage __visible void __init x86_64_start_kernel(char * real_mode_data)
 {
 	int i;
@@ -164,6 +171,10 @@ asmlinkage __visible void __init x86_64_start_kernel(char * real_mode_data)
 	load_idt((const struct desc_ptr *)&idt_descr);
 
 	copy_bootdata(__va(real_mode_data));
+	parse_early_param();
+	this_cpu_write(printk_func, _early_printk);
+
+	printk("This is a test!\n");
 
 	/*
 	 * Load microcode early on BSP.
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 2367ae07eb76..998d6c675549 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -882,6 +882,7 @@ void __init setup_arch(char **cmdline_p)
 	 */
 	__flush_tlb_all();
 #else
+	this_cpu_write(printk_func, vprintk_default);
 	printk(KERN_INFO "Command line: %s\n", boot_command_line);
 #endif
 
diff --git a/include/linux/printk.h b/include/linux/printk.h
index 9ccbdf2c1453..97df81c97b2f 100644
--- a/include/linux/printk.h
+++ b/include/linux/printk.h
@@ -169,6 +169,7 @@ void __init setup_log_buf(int early);
 __printf(1, 2) void dump_stack_set_arch_desc(const char *fmt, ...);
 void dump_stack_print_info(const char *log_lvl);
 void show_regs_print_info(const char *log_lvl);
+int vprintk_default(const char *fmt, va_list args);
 #else
 static inline __printf(1, 0)
 int vprintk(const char *s, va_list args)

-- 
Regards/Gruss,
    Boris.

ECO tip #101: Trim your mails when you reply.

[toc] | [prev] | [next] | [standalone]


#1370912 — Re: [PATCH v5 3/9] x86/head: Move early exception panic code into early_fixup_exception

FromAndy Lutomirski <luto@amacapital.net>
Date2016-04-04 23:40 +0200
SubjectRe: [PATCH v5 3/9] x86/head: Move early exception panic code into early_fixup_exception
Message-ID<rkko2-VB-7@gated-at.bofh.it>
In reply to#1370836
On Mon, Apr 4, 2016 at 12:38 PM, Borislav Petkov <bp@alien8.de> wrote:
> On Mon, Apr 04, 2016 at 06:00:42PM +0200, Peter Zijlstra wrote:
>> On Mon, Apr 04, 2016 at 08:32:21AM -0700, Andy Lutomirski wrote:
>>
>> > Adding locking would be easy enough, wouldn't it?
>>
>> See patch in this thread..
>>
>> > But do any platforms really boot a second CPU before switching to real
>> > printk?
>>
>> I _only_ use early_printk() as printk() is a quagmire of fail :-)
>
> And since I'm the king of minimalistic changes... this below
> works. However, the problem is that we need to pull up all that
> early_param parsing in order to enable the early console, i.e.
> "earlyprintk=ttyS0,115200" cmdline parsing.
>
> And we can do all that after having setup the IDT. So I'd need to do
> some early dancing with cmdline_find_option_bool(boot_command_line, ...
> in asm or so. Need to think about it more.
>

I'd be nervous about moving early param parsing, especially as part of
the same patch.

Could you do it by moving just the earlyprintk stuff a la
fpu__init_parse_early_param()?

--Andy

[toc] | [prev] | [next] | [standalone]


#1370927 — Re: [PATCH v5 3/9] x86/head: Move early exception panic code into early_fixup_exception

FromBorislav Petkov <bp@alien8.de>
Date2016-04-04 23:50 +0200
SubjectRe: [PATCH v5 3/9] x86/head: Move early exception panic code into early_fixup_exception
Message-ID<rkkxJ-Zd-31@gated-at.bofh.it>
In reply to#1370912
On Mon, Apr 04, 2016 at 02:31:46PM -0700, Andy Lutomirski wrote:
> Could you do it by moving just the earlyprintk stuff a la
> fpu__init_parse_early_param()?

Yeah, something like that. I'll play with this more tomorrow. Btw, no
need to make any of this part of your patchset - I'd like early changes
like that to cook longer for obvious reasons anyway...

-- 
Regards/Gruss,
    Boris.

ECO tip #101: Trim your mails when you reply.

[toc] | [prev] | [next] | [standalone]


#1377813 — [tip:x86/asm] x86/head: Move early exception panic code into early_fixup_exception()

Fromtip-bot for Andy Lutomirski <tipbot@zytor.com>
Date2016-04-13 13:50 +0200
Subject[tip:x86/asm] x86/head: Move early exception panic code into early_fixup_exception()
Message-ID<rnrsZ-BH-7@gated-at.bofh.it>
In reply to#1369955
Commit-ID:  0e861fbb5bda79b871341ef2a9a8059765cbe8a4
Gitweb:     http://git.kernel.org/tip/0e861fbb5bda79b871341ef2a9a8059765cbe8a4
Author:     Andy Lutomirski <luto@kernel.org>
AuthorDate: Sat, 2 Apr 2016 07:01:34 -0700
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Wed, 13 Apr 2016 11:37:44 +0200

x86/head: Move early exception panic code into early_fixup_exception()

This removes a bunch of assembly and adds some C code instead.  It
changes the actual printouts on both 32-bit and 64-bit kernels, but
they still seem okay.

Tested-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Signed-off-by: Andy Lutomirski <luto@kernel.org>
Acked-by: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Arjan van de Ven <arjan@linux.intel.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: KVM list <kvm@vger.kernel.org>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: xen-devel <Xen-devel@lists.xen.org>
Link: http://lkml.kernel.org/r/4085070316fc3ab29538d3fcfe282648d1d4ee2e.1459605520.git.luto@kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/include/asm/uaccess.h |  2 +-
 arch/x86/kernel/head_32.S      | 49 +++++-------------------------------------
 arch/x86/kernel/head_64.S      | 45 ++------------------------------------
 arch/x86/mm/extable.c          | 29 ++++++++++++++++++++-----
 4 files changed, 32 insertions(+), 93 deletions(-)

diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h
index b6fb311..d794fd1 100644
--- a/arch/x86/include/asm/uaccess.h
+++ b/arch/x86/include/asm/uaccess.h
@@ -110,7 +110,7 @@ struct exception_table_entry {
 
 extern int fixup_exception(struct pt_regs *regs, int trapnr);
 extern bool ex_has_fault_handler(unsigned long ip);
-extern int early_fixup_exception(struct pt_regs *regs, int trapnr);
+extern void early_fixup_exception(struct pt_regs *regs, int trapnr);
 
 /*
  * These are the main single-value transfer routines.  They automatically
diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S
index 184291c..6770865 100644
--- a/arch/x86/kernel/head_32.S
+++ b/arch/x86/kernel/head_32.S
@@ -561,8 +561,6 @@ early_idt_handler_common:
 	 */
 	cld
 
-	cmpl $2,%ss:early_recursion_flag
-	je hlt_loop
 	incl %ss:early_recursion_flag
 
 	/* The vector number is in pt_regs->gs */
@@ -594,13 +592,8 @@ early_idt_handler_common:
 	movw	%gs, PT_GS(%esp)
 	movw	$0, PT_GS+2(%esp)
 
-	cmpl $(__KERNEL_CS),PT_CS(%esp)
-	jne 10f
-
 	movl	%esp, %eax	/* args are pt_regs (EAX), trapnr (EDX) */
 	call	early_fixup_exception
-	andl	%eax,%eax
-	jz	10f		/* Exception wasn't fixed up */
 
 	popl	%ebx		/* pt_regs->bx */
 	popl	%ecx		/* pt_regs->cx */
@@ -616,29 +609,6 @@ early_idt_handler_common:
 	decl	%ss:early_recursion_flag
 	addl	$4, %esp	/* pop pt_regs->orig_ax */
 	iret
-
-10:
-#ifdef CONFIG_PRINTK
-	xorl %eax,%eax
-	movw %ax,PT_FS+2(%esp)	/* clean up the segment values on some cpus */
-	movw %ax,PT_DS+2(%esp)
-	movw %ax,PT_ES+2(%esp)
-	leal  40(%esp),%eax
-	pushl %eax		/* %esp before the exception */
-	pushl %ebx
-	pushl %ebp
-	pushl %esi
-	pushl %edi
-	movl %cr2,%eax
-	pushl %eax
-	pushl (20+6*4)(%esp)	/* trapno */
-	pushl $fault_msg
-	call printk
-#endif
-	call dump_stack
-hlt_loop:
-	hlt
-	jmp hlt_loop
 ENDPROC(early_idt_handler_common)
 
 /* This is the default interrupt "handler" :-) */
@@ -674,10 +644,14 @@ ignore_int:
 	popl %eax
 #endif
 	iret
+
+hlt_loop:
+	hlt
+	jmp hlt_loop
 ENDPROC(ignore_int)
 __INITDATA
 	.align 4
-early_recursion_flag:
+GLOBAL(early_recursion_flag)
 	.long 0
 
 __REFDATA
@@ -742,19 +716,6 @@ __INITRODATA
 int_msg:
 	.asciz "Unknown interrupt or fault at: %p %p %p\n"
 
-fault_msg:
-/* fault info: */
-	.ascii "BUG: Int %d: CR2 %p\n"
-/* regs pushed in early_idt_handler: */
-	.ascii "     EDI %p  ESI %p  EBP %p  EBX %p\n"
-	.ascii "     ESP %p   ES %p   DS %p\n"
-	.ascii "     EDX %p  ECX %p  EAX %p\n"
-/* fault frame: */
-	.ascii "     vec %p  err %p  EIP %p   CS %p  flg %p\n"
-	.ascii "Stack: %p %p %p %p %p %p %p %p\n"
-	.ascii "       %p %p %p %p %p %p %p %p\n"
-	.asciz "       %p %p %p %p %p %p %p %p\n"
-
 #include "../../x86/xen/xen-head.S"
 
 /*
diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S
index 2308437..3de91a7 100644
--- a/arch/x86/kernel/head_64.S
+++ b/arch/x86/kernel/head_64.S
@@ -351,8 +351,6 @@ early_idt_handler_common:
 	 */
 	cld
 
-	cmpl $2,early_recursion_flag(%rip)
-	jz  1f
 	incl early_recursion_flag(%rip)
 
 	/* The vector number is currently in the pt_regs->di slot. */
@@ -373,9 +371,6 @@ early_idt_handler_common:
 	pushq %r14				/* pt_regs->r14 */
 	pushq %r15				/* pt_regs->r15 */
 
-	cmpl $__KERNEL_CS,CS(%rsp)
-	jne 11f
-
 	cmpq $14,%rsi		/* Page fault? */
 	jnz 10f
 	GET_CR2_INTO(%rdi)	/* Can clobber any volatile register if pv */
@@ -386,37 +381,8 @@ early_idt_handler_common:
 10:
 	movq %rsp,%rdi		/* RDI = pt_regs; RSI is already trapnr */
 	call early_fixup_exception
-	andl %eax,%eax
-	jnz 20f			# Found an exception entry
-
-11:
-#ifdef CONFIG_EARLY_PRINTK
-	/*
-	 * On paravirt kernels, GET_CR2_INTO clobbers callee-clobbered regs.
-	 * We only care about RSI, so we need to save it.
-	 */
-	movq %rsi,%rbx		/* Save vector number */
-	GET_CR2_INTO(%r9)
-	movq ORIG_RAX(%rsp),%r8	/* error code */
-	movq %rbx,%rsi		/* vector number */
-	movq CS(%rsp),%rdx
-	movq RIP(%rsp),%rcx
-	xorl %eax,%eax
-	leaq early_idt_msg(%rip),%rdi
-	call early_printk
-	cmpl $2,early_recursion_flag(%rip)
-	jz  1f
-	call dump_stack
-#ifdef CONFIG_KALLSYMS	
-	leaq early_idt_ripmsg(%rip),%rdi
-	movq RIP(%rsp),%rsi	# %rip again
-	call __print_symbol
-#endif
-#endif /* EARLY_PRINTK */
-1:	hlt
-	jmp 1b
 
-20:	/* Exception table entry found or page table generated */
+20:
 	decl early_recursion_flag(%rip)
 	jmp restore_regs_and_iret
 ENDPROC(early_idt_handler_common)
@@ -424,16 +390,9 @@ ENDPROC(early_idt_handler_common)
 	__INITDATA
 
 	.balign 4
-early_recursion_flag:
+GLOBAL(early_recursion_flag)
 	.long 0
 
-#ifdef CONFIG_EARLY_PRINTK
-early_idt_msg:
-	.asciz "PANIC: early exception %02lx rip %lx:%lx error %lx cr2 %lx\n"
-early_idt_ripmsg:
-	.asciz "RIP %s\n"
-#endif /* CONFIG_EARLY_PRINTK */
-
 #define NEXT_PAGE(name) \
 	.balign	PAGE_SIZE; \
 GLOBAL(name)
diff --git a/arch/x86/mm/extable.c b/arch/x86/mm/extable.c
index 4be0419..da442f3 100644
--- a/arch/x86/mm/extable.c
+++ b/arch/x86/mm/extable.c
@@ -83,8 +83,10 @@ int fixup_exception(struct pt_regs *regs, int trapnr)
 	return handler(e, regs, trapnr);
 }
 
+extern unsigned int early_recursion_flag;
+
 /* Restricted version used during very early boot */
-int __init early_fixup_exception(struct pt_regs *regs, int trapnr)
+void __init early_fixup_exception(struct pt_regs *regs, int trapnr)
 {
 	const struct exception_table_entry *e;
 	unsigned long new_ip;
@@ -92,19 +94,36 @@ int __init early_fixup_exception(struct pt_regs *regs, int trapnr)
 
 	/* Ignore early NMIs. */
 	if (trapnr == X86_TRAP_NMI)
-		return 1;
+		return;
+
+	if (early_recursion_flag > 2)
+		goto halt_loop;
+
+	if (regs->cs != __KERNEL_CS)
+		goto fail;
 
 	e = search_exception_tables(regs->ip);
 	if (!e)
-		return 0;
+		goto fail;
 
 	new_ip  = ex_fixup_addr(e);
 	handler = ex_fixup_handler(e);
 
 	/* special handling not supported during early boot */
 	if (handler != ex_handler_default)
-		return 0;
+		goto fail;
 
 	regs->ip = new_ip;
-	return 1;
+	return;
+
+fail:
+	early_printk("PANIC: early exception 0x%02x IP %lx:%lx error %lx cr2 0x%lx\n",
+		     (unsigned)trapnr, (unsigned long)regs->cs, regs->ip,
+		     regs->orig_ax, read_cr2());
+
+	show_regs(regs);
+
+halt_loop:
+	while (true)
+		halt();
 }

[toc] | [prev] | [next] | [standalone]


#1369956 — [PATCH v5 7/9] x86/paravirt: Add paravirt_{read,write}_msr

FromAndy Lutomirski <luto@kernel.org>
Date2016-04-02 16:10 +0200
Subject[PATCH v5 7/9] x86/paravirt: Add paravirt_{read,write}_msr
Message-ID<rjupu-4TG-25@gated-at.bofh.it>
In reply to#1369949
This adds paravirt hooks for unsafe MSR access.  On native, they
call native_{read,write}_msr.  On Xen, they use
xen_{read,write}_msr_safe.

Nothing uses them yet for ease of bisection.  The next patch will
use them in rdmsrl, wrmsrl, etc.

I intentionally didn't make them warn on #GP on Xen.  I think that
should be done separately by the Xen maintainers.

Signed-off-by: Andy Lutomirski <luto@kernel.org>
---
 arch/x86/include/asm/msr.h            |  5 +++--
 arch/x86/include/asm/paravirt.h       | 11 +++++++++++
 arch/x86/include/asm/paravirt_types.h | 10 ++++++++--
 arch/x86/kernel/paravirt.c            |  2 ++
 arch/x86/xen/enlighten.c              | 23 +++++++++++++++++++++++
 5 files changed, 47 insertions(+), 4 deletions(-)

diff --git a/arch/x86/include/asm/msr.h b/arch/x86/include/asm/msr.h
index 1487054a1a70..13da359881d7 100644
--- a/arch/x86/include/asm/msr.h
+++ b/arch/x86/include/asm/msr.h
@@ -119,8 +119,9 @@ static inline unsigned long long native_read_msr_safe(unsigned int msr,
 	return EAX_EDX_VAL(val, low, high);
 }
 
-static inline void native_write_msr(unsigned int msr,
-				    unsigned low, unsigned high)
+/* Can be uninlined because referenced by paravirt */
+notrace static inline void native_write_msr(unsigned int msr,
+					    unsigned low, unsigned high)
 {
 	asm volatile("1: wrmsr\n"
 		     "2:\n"
diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h
index 2e49228ed9a3..68297d87e85c 100644
--- a/arch/x86/include/asm/paravirt.h
+++ b/arch/x86/include/asm/paravirt.h
@@ -129,6 +129,17 @@ static inline void wbinvd(void)
 
 #define get_kernel_rpl()  (pv_info.kernel_rpl)
 
+static inline u64 paravirt_read_msr(unsigned msr)
+{
+	return PVOP_CALL1(u64, pv_cpu_ops.read_msr, msr);
+}
+
+static inline void paravirt_write_msr(unsigned msr,
+				      unsigned low, unsigned high)
+{
+	return PVOP_VCALL3(pv_cpu_ops.write_msr, msr, low, high);
+}
+
 static inline u64 paravirt_read_msr_safe(unsigned msr, int *err)
 {
 	return PVOP_CALL2(u64, pv_cpu_ops.read_msr_safe, msr, err);
diff --git a/arch/x86/include/asm/paravirt_types.h b/arch/x86/include/asm/paravirt_types.h
index 5a06cccd36f0..b85aec45a1b8 100644
--- a/arch/x86/include/asm/paravirt_types.h
+++ b/arch/x86/include/asm/paravirt_types.h
@@ -155,8 +155,14 @@ struct pv_cpu_ops {
 	void (*cpuid)(unsigned int *eax, unsigned int *ebx,
 		      unsigned int *ecx, unsigned int *edx);
 
-	/* MSR operations.
-	   err = 0/-EIO.  wrmsr returns 0/-EIO. */
+	/* Unsafe MSR operations.  These will warn or panic on failure. */
+	u64 (*read_msr)(unsigned int msr);
+	void (*write_msr)(unsigned int msr, unsigned low, unsigned high);
+
+	/*
+	 * Safe MSR operations.
+	 * read sets err to 0 or -EIO.  write returns 0 or -EIO.
+	 */
 	u64 (*read_msr_safe)(unsigned int msr, int *err);
 	int (*write_msr_safe)(unsigned int msr, unsigned low, unsigned high);
 
diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c
index 8aad95478ae5..f9583917c7c4 100644
--- a/arch/x86/kernel/paravirt.c
+++ b/arch/x86/kernel/paravirt.c
@@ -339,6 +339,8 @@ __visible struct pv_cpu_ops pv_cpu_ops = {
 	.write_cr8 = native_write_cr8,
 #endif
 	.wbinvd = native_wbinvd,
+	.read_msr = native_read_msr,
+	.write_msr = native_write_msr,
 	.read_msr_safe = native_read_msr_safe,
 	.write_msr_safe = native_write_msr_safe,
 	.read_pmc = native_read_pmc,
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index ff2df20d0067..548cd3e02b9e 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -1092,6 +1092,26 @@ static int xen_write_msr_safe(unsigned int msr, unsigned low, unsigned high)
 	return ret;
 }
 
+static u64 xen_read_msr(unsigned int msr)
+{
+	/*
+	 * This will silently swallow a #GP from RDMSR.  It may be worth
+	 * changing that.
+	 */
+	int err;
+
+	return xen_read_msr_safe(msr, &err);
+}
+
+static void xen_write_msr(unsigned int msr, unsigned low, unsigned high)
+{
+	/*
+	 * This will silently swallow a #GP from WRMSR.  It may be worth
+	 * changing that.
+	 */
+	xen_write_msr_safe(msr, low, high);
+}
+
 void xen_setup_shared_info(void)
 {
 	if (!xen_feature(XENFEAT_auto_translated_physmap)) {
@@ -1222,6 +1242,9 @@ static const struct pv_cpu_ops xen_cpu_ops __initconst = {
 
 	.wbinvd = native_wbinvd,
 
+	.read_msr = xen_read_msr,
+	.write_msr = xen_write_msr,
+
 	.read_msr_safe = xen_read_msr_safe,
 	.write_msr_safe = xen_write_msr_safe,
 
-- 
2.5.5

[toc] | [prev] | [next] | [standalone]


#1370765 — Re: [Xen-devel] [PATCH v5 7/9] x86/paravirt: Add paravirt_{read, write}_msr

FromDavid Vrabel <david.vrabel@citrix.com>
Date2016-04-04 18:40 +0200
SubjectRe: [Xen-devel] [PATCH v5 7/9] x86/paravirt: Add paravirt_{read, write}_msr
Message-ID<rkfHI-5Tz-21@gated-at.bofh.it>
In reply to#1369956
On 02/04/16 15:01, Andy Lutomirski wrote:
> This adds paravirt hooks for unsafe MSR access.  On native, they
> call native_{read,write}_msr.  On Xen, they use
> xen_{read,write}_msr_safe.
> 
> Nothing uses them yet for ease of bisection.  The next patch will
> use them in rdmsrl, wrmsrl, etc.
> 
> I intentionally didn't make them warn on #GP on Xen.  I think that
> should be done separately by the Xen maintainers.
...
> --- a/arch/x86/xen/enlighten.c
> +++ b/arch/x86/xen/enlighten.c

Reviewed-by: David Vrabel <david.vrabel@citrix.com>

> @@ -1092,6 +1092,26 @@ static int xen_write_msr_safe(unsigned int msr, unsigned low, unsigned high)
>  	return ret;
>  }
>  
> +static u64 xen_read_msr(unsigned int msr)
> +{
> +	/*
> +	 * This will silently swallow a #GP from RDMSR.  It may be worth
> +	 * changing that.

This probably isn't important.

David

[toc] | [prev] | [next] | [standalone]


#1370767 — Re: [Xen-devel] [PATCH v5 7/9] x86/paravirt: Add paravirt_{read, write}_msr

FromAndy Lutomirski <luto@amacapital.net>
Date2016-04-04 18:50 +0200
SubjectRe: [Xen-devel] [PATCH v5 7/9] x86/paravirt: Add paravirt_{read, write}_msr
Message-ID<rkfRn-5XM-5@gated-at.bofh.it>
In reply to#1370765
On Mon, Apr 4, 2016 at 9:33 AM, David Vrabel <david.vrabel@citrix.com> wrote:
> On 02/04/16 15:01, Andy Lutomirski wrote:
>> This adds paravirt hooks for unsafe MSR access.  On native, they
>> call native_{read,write}_msr.  On Xen, they use
>> xen_{read,write}_msr_safe.
>>
>> Nothing uses them yet for ease of bisection.  The next patch will
>> use them in rdmsrl, wrmsrl, etc.
>>
>> I intentionally didn't make them warn on #GP on Xen.  I think that
>> should be done separately by the Xen maintainers.
> ...
>> --- a/arch/x86/xen/enlighten.c
>> +++ b/arch/x86/xen/enlighten.c
>
> Reviewed-by: David Vrabel <david.vrabel@citrix.com>
>
>> @@ -1092,6 +1092,26 @@ static int xen_write_msr_safe(unsigned int msr, unsigned low, unsigned high)
>>       return ret;
>>  }
>>
>> +static u64 xen_read_msr(unsigned int msr)
>> +{
>> +     /*
>> +      * This will silently swallow a #GP from RDMSR.  It may be worth
>> +      * changing that.
>
> This probably isn't important.
>

It might be nice to do a WARN_ON_ONCE like this series does for the
native case to help shake out latent bugs.

--Andy

[toc] | [prev] | [next] | [standalone]


#1377843 — [tip:x86/asm] x86/paravirt: Add paravirt_{read,write}_msr()

Fromtip-bot for Andy Lutomirski <tipbot@zytor.com>
Date2016-04-13 13:50 +0200
Subject[tip:x86/asm] x86/paravirt: Add paravirt_{read,write}_msr()
Message-ID<rnrt2-BH-79@gated-at.bofh.it>
In reply to#1369956
Commit-ID:  dd2f4a004b016bbfb64f1de49cb45e66232e40a6
Gitweb:     http://git.kernel.org/tip/dd2f4a004b016bbfb64f1de49cb45e66232e40a6
Author:     Andy Lutomirski <luto@kernel.org>
AuthorDate: Sat, 2 Apr 2016 07:01:38 -0700
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Wed, 13 Apr 2016 11:37:46 +0200

x86/paravirt: Add paravirt_{read,write}_msr()

This adds paravirt callbacks for unsafe MSR access.  On native, they
call native_{read,write}_msr().  On Xen, they use xen_{read,write}_msr_safe().

Nothing uses them yet for ease of bisection.  The next patch will
use them in rdmsrl(), wrmsrl(), etc.

I intentionally didn't make them warn on #GP on Xen.  I think that
should be done separately by the Xen maintainers.

Tested-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Signed-off-by: Andy Lutomirski <luto@kernel.org>
Acked-by: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Arjan van de Ven <arjan@linux.intel.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: KVM list <kvm@vger.kernel.org>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: xen-devel <Xen-devel@lists.xen.org>
Link: http://lkml.kernel.org/r/880eebc5dcd2ad9f310d41345f82061ea500e9fa.1459605520.git.luto@kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/include/asm/msr.h            |  5 +++--
 arch/x86/include/asm/paravirt.h       | 11 +++++++++++
 arch/x86/include/asm/paravirt_types.h | 10 ++++++++--
 arch/x86/kernel/paravirt.c            |  2 ++
 arch/x86/xen/enlighten.c              | 23 +++++++++++++++++++++++
 5 files changed, 47 insertions(+), 4 deletions(-)

diff --git a/arch/x86/include/asm/msr.h b/arch/x86/include/asm/msr.h
index 25f169c..00050c0 100644
--- a/arch/x86/include/asm/msr.h
+++ b/arch/x86/include/asm/msr.h
@@ -111,8 +111,9 @@ static inline unsigned long long native_read_msr_safe(unsigned int msr,
 	return EAX_EDX_VAL(val, low, high);
 }
 
-static inline void native_write_msr(unsigned int msr,
-				    unsigned low, unsigned high)
+/* Can be uninlined because referenced by paravirt */
+notrace static inline void native_write_msr(unsigned int msr,
+					    unsigned low, unsigned high)
 {
 	asm volatile("1: wrmsr\n"
 		     "2:\n"
diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h
index 81ef2d5..97839fa 100644
--- a/arch/x86/include/asm/paravirt.h
+++ b/arch/x86/include/asm/paravirt.h
@@ -130,6 +130,17 @@ static inline void wbinvd(void)
 
 #define get_kernel_rpl()  (pv_info.kernel_rpl)
 
+static inline u64 paravirt_read_msr(unsigned msr)
+{
+	return PVOP_CALL1(u64, pv_cpu_ops.read_msr, msr);
+}
+
+static inline void paravirt_write_msr(unsigned msr,
+				      unsigned low, unsigned high)
+{
+	return PVOP_VCALL3(pv_cpu_ops.write_msr, msr, low, high);
+}
+
 static inline u64 paravirt_read_msr_safe(unsigned msr, int *err)
 {
 	return PVOP_CALL2(u64, pv_cpu_ops.read_msr_safe, msr, err);
diff --git a/arch/x86/include/asm/paravirt_types.h b/arch/x86/include/asm/paravirt_types.h
index 09c9e1d..b4a23ea 100644
--- a/arch/x86/include/asm/paravirt_types.h
+++ b/arch/x86/include/asm/paravirt_types.h
@@ -155,8 +155,14 @@ struct pv_cpu_ops {
 	void (*cpuid)(unsigned int *eax, unsigned int *ebx,
 		      unsigned int *ecx, unsigned int *edx);
 
-	/* MSR operations.
-	   err = 0/-EIO.  wrmsr returns 0/-EIO. */
+	/* Unsafe MSR operations.  These will warn or panic on failure. */
+	u64 (*read_msr)(unsigned int msr);
+	void (*write_msr)(unsigned int msr, unsigned low, unsigned high);
+
+	/*
+	 * Safe MSR operations.
+	 * read sets err to 0 or -EIO.  write returns 0 or -EIO.
+	 */
 	u64 (*read_msr_safe)(unsigned int msr, int *err);
 	int (*write_msr_safe)(unsigned int msr, unsigned low, unsigned high);
 
diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c
index 8aad954..f958391 100644
--- a/arch/x86/kernel/paravirt.c
+++ b/arch/x86/kernel/paravirt.c
@@ -339,6 +339,8 @@ __visible struct pv_cpu_ops pv_cpu_ops = {
 	.write_cr8 = native_write_cr8,
 #endif
 	.wbinvd = native_wbinvd,
+	.read_msr = native_read_msr,
+	.write_msr = native_write_msr,
 	.read_msr_safe = native_read_msr_safe,
 	.write_msr_safe = native_write_msr_safe,
 	.read_pmc = native_read_pmc,
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index 13f756f..6ab6722 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -1092,6 +1092,26 @@ static int xen_write_msr_safe(unsigned int msr, unsigned low, unsigned high)
 	return ret;
 }
 
+static u64 xen_read_msr(unsigned int msr)
+{
+	/*
+	 * This will silently swallow a #GP from RDMSR.  It may be worth
+	 * changing that.
+	 */
+	int err;
+
+	return xen_read_msr_safe(msr, &err);
+}
+
+static void xen_write_msr(unsigned int msr, unsigned low, unsigned high)
+{
+	/*
+	 * This will silently swallow a #GP from WRMSR.  It may be worth
+	 * changing that.
+	 */
+	xen_write_msr_safe(msr, low, high);
+}
+
 void xen_setup_shared_info(void)
 {
 	if (!xen_feature(XENFEAT_auto_translated_physmap)) {
@@ -1222,6 +1242,9 @@ static const struct pv_cpu_ops xen_cpu_ops __initconst = {
 
 	.wbinvd = native_wbinvd,
 
+	.read_msr = xen_read_msr,
+	.write_msr = xen_write_msr,
+
 	.read_msr_safe = xen_read_msr_safe,
 	.write_msr_safe = xen_write_msr_safe,
 

[toc] | [prev] | [next] | [standalone]


#1369957 — [PATCH v5 1/9] x86/head: Pass a real pt_regs and trapnr to early_fixup_exception

FromAndy Lutomirski <luto@kernel.org>
Date2016-04-02 16:10 +0200
Subject[PATCH v5 1/9] x86/head: Pass a real pt_regs and trapnr to early_fixup_exception
Message-ID<rjupu-4TG-29@gated-at.bofh.it>
In reply to#1369949
early_fixup_exception is limited by the fact that it doesn't have a
real struct pt_regs.  Change both the 32-bit and 64-bit asm and the
C code to pass and accept a real pt_regs.

Signed-off-by: Andy Lutomirski <luto@kernel.org>
---
 arch/x86/include/asm/uaccess.h |  2 +-
 arch/x86/kernel/head_32.S      | 74 +++++++++++++++++++++++++++++-------------
 arch/x86/kernel/head_64.S      | 68 ++++++++++++++++++++------------------
 arch/x86/mm/extable.c          |  6 ++--
 4 files changed, 92 insertions(+), 58 deletions(-)

diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h
index c0f27d7ea7ff..a3afb7259751 100644
--- a/arch/x86/include/asm/uaccess.h
+++ b/arch/x86/include/asm/uaccess.h
@@ -111,7 +111,7 @@ struct exception_table_entry {
 
 extern int fixup_exception(struct pt_regs *regs, int trapnr);
 extern bool ex_has_fault_handler(unsigned long ip);
-extern int early_fixup_exception(unsigned long *ip);
+extern int early_fixup_exception(struct pt_regs *regs, int trapnr);
 
 /*
  * These are the main single-value transfer routines.  They automatically
diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S
index 6bc9ae24b6d2..bef3e6c49b56 100644
--- a/arch/x86/kernel/head_32.S
+++ b/arch/x86/kernel/head_32.S
@@ -562,29 +562,64 @@ early_idt_handler_common:
 	je hlt_loop
 	incl %ss:early_recursion_flag
 
-	push %eax		# 16(%esp)
-	push %ecx		# 12(%esp)
-	push %edx		#  8(%esp)
-	push %ds		#  4(%esp)
-	push %es		#  0(%esp)
-	movl $(__KERNEL_DS),%eax
-	movl %eax,%ds
-	movl %eax,%es
+	/* The vector number is in pt_regs->gs */
 
-	cmpl $(__KERNEL_CS),32(%esp)
+	cld
+	pushl	%fs		/* pt_regs->fs */
+	movw	$0, 2(%esp)	/* clear high bits (some CPUs leave garbage) */
+	pushl	%es		/* pt_regs->es */
+	movw	$0, 2(%esp)	/* clear high bits (some CPUs leave garbage) */
+	pushl	%ds		/* pt_regs->ds */
+	movw	$0, 2(%esp)	/* clear high bits (some CPUs leave garbage) */
+	pushl	%eax		/* pt_regs->ax */
+	pushl	%ebp		/* pt_regs->bp */
+	pushl	%edi		/* pt_regs->di */
+	pushl	%esi		/* pt_regs->si */
+	pushl	%edx		/* pt_regs->dx */
+	pushl	%ecx		/* pt_regs->cx */
+	pushl	%ebx		/* pt_regs->bx */
+
+	/* Fix up DS and ES */
+	movl	$(__KERNEL_DS), %ecx
+	movl	%ecx, %ds
+	movl	%ecx, %es
+
+	/* Load the vector number into EDX */
+	movl	PT_GS(%esp), %edx
+
+	/* Load GS into pt_regs->gs and clear high bits */
+	movw	%gs, PT_GS(%esp)
+	movw	$0, PT_GS+2(%esp)
+
+	cmpl $(__KERNEL_CS),PT_CS(%esp)
 	jne 10f
 
-	leal 28(%esp),%eax	# Pointer to %eip
-	call early_fixup_exception
-	andl %eax,%eax
-	jnz ex_entry		/* found an exception entry */
+	movl	%esp, %eax	/* args are pt_regs (EAX), trapnr (EDX) */
+	call	early_fixup_exception
+	andl	%eax,%eax
+	jz	10f		/* Exception wasn't fixed up */
+
+	popl	%ebx		/* pt_regs->bx */
+	popl	%ecx		/* pt_regs->cx */
+	popl	%edx		/* pt_regs->dx */
+	popl	%esi		/* pt_regs->si */
+	popl	%edi		/* pt_regs->di */
+	popl	%ebp		/* pt_regs->bp */
+	popl	%eax		/* pt_regs->ax */
+	popl	%ds		/* pt_regs->ds */
+	popl	%es		/* pt_regs->es */
+	popl	%fs		/* pt_regs->fs */
+	popl	%gs		/* pt_regs->gs */
+	decl	%ss:early_recursion_flag
+	addl	$4, %esp	/* pop pt_regs->orig_ax */
+	iret
 
 10:
 #ifdef CONFIG_PRINTK
 	xorl %eax,%eax
-	movw %ax,2(%esp)	/* clean up the segment values on some cpus */
-	movw %ax,6(%esp)
-	movw %ax,34(%esp)
+	movw %ax,PT_FS+2(%esp)	/* clean up the segment values on some cpus */
+	movw %ax,PT_DS+2(%esp)
+	movw %ax,PT_ES+2(%esp)
 	leal  40(%esp),%eax
 	pushl %eax		/* %esp before the exception */
 	pushl %ebx
@@ -602,13 +637,6 @@ hlt_loop:
 	hlt
 	jmp hlt_loop
 
-ex_entry:
-	pop %es
-	pop %ds
-	pop %edx
-	pop %ecx
-	pop %eax
-	decl %ss:early_recursion_flag
 .Lis_nmi:
 	addl $8,%esp		/* drop vector number and error code */
 	iret
diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S
index ffdc0e860390..f8d6dad41e8d 100644
--- a/arch/x86/kernel/head_64.S
+++ b/arch/x86/kernel/head_64.S
@@ -20,6 +20,7 @@
 #include <asm/processor-flags.h>
 #include <asm/percpu.h>
 #include <asm/nops.h>
+#include "../entry/calling.h"
 
 #ifdef CONFIG_PARAVIRT
 #include <asm/asm-offsets.h>
@@ -360,39 +361,52 @@ early_idt_handler_common:
 	jz  1f
 	incl early_recursion_flag(%rip)
 
-	pushq %rax		# 64(%rsp)
-	pushq %rcx		# 56(%rsp)
-	pushq %rdx		# 48(%rsp)
-	pushq %rsi		# 40(%rsp)
-	pushq %rdi		# 32(%rsp)
-	pushq %r8		# 24(%rsp)
-	pushq %r9		# 16(%rsp)
-	pushq %r10		#  8(%rsp)
-	pushq %r11		#  0(%rsp)
-
-	cmpl $__KERNEL_CS,96(%rsp)
+	/* The vector number is currently in the pt_regs->di slot. */
+	pushq %rsi				/* pt_regs->si */
+	movq 8(%rsp), %rsi			/* RSI = vector number */
+	movq %rdi, 8(%rsp)			/* pt_regs->di = RDI */
+	pushq %rdx				/* pt_regs->dx */
+	pushq %rcx				/* pt_regs->cx */
+	pushq %rax				/* pt_regs->ax */
+	pushq %r8				/* pt_regs->r8 */
+	pushq %r9				/* pt_regs->r9 */
+	pushq %r10				/* pt_regs->r10 */
+	pushq %r11				/* pt_regs->r11 */
+	pushq %rbx				/* pt_regs->bx */
+	pushq %rbp				/* pt_regs->bp */
+	pushq %r12				/* pt_regs->r12 */
+	pushq %r13				/* pt_regs->r13 */
+	pushq %r14				/* pt_regs->r14 */
+	pushq %r15				/* pt_regs->r15 */
+
+	cmpl $__KERNEL_CS,CS(%rsp)
 	jne 11f
 
-	cmpl $14,72(%rsp)	# Page fault?
+	cmpq $14,%rsi		/* Page fault? */
 	jnz 10f
-	GET_CR2_INTO(%rdi)	# can clobber any volatile register if pv
+	GET_CR2_INTO(%rdi)	/* Can clobber any volatile register if pv */
 	call early_make_pgtable
 	andl %eax,%eax
-	jz 20f			# All good
+	jz 20f			/* All good */
 
 10:
-	leaq 88(%rsp),%rdi	# Pointer to %rip
+	movq %rsp,%rdi		/* RDI = pt_regs; RSI is already trapnr */
 	call early_fixup_exception
 	andl %eax,%eax
 	jnz 20f			# Found an exception entry
 
 11:
 #ifdef CONFIG_EARLY_PRINTK
-	GET_CR2_INTO(%r9)	# can clobber any volatile register if pv
-	movl 80(%rsp),%r8d	# error code
-	movl 72(%rsp),%esi	# vector number
-	movl 96(%rsp),%edx	# %cs
-	movq 88(%rsp),%rcx	# %rip
+	/*
+	 * On paravirt kernels, GET_CR2_INTO clobbers callee-clobbered regs.
+	 * We only care about RSI, so we need to save it.
+	 */
+	movq %rsi,%rbx		/* Save vector number */
+	GET_CR2_INTO(%r9)
+	movq ORIG_RAX(%rsp),%r8	/* error code */
+	movq %rbx,%rsi		/* vector number */
+	movq CS(%rsp),%rdx
+	movq RIP(%rsp),%rcx
 	xorl %eax,%eax
 	leaq early_idt_msg(%rip),%rdi
 	call early_printk
@@ -401,24 +415,16 @@ early_idt_handler_common:
 	call dump_stack
 #ifdef CONFIG_KALLSYMS	
 	leaq early_idt_ripmsg(%rip),%rdi
-	movq 40(%rsp),%rsi	# %rip again
+	movq RIP(%rsp),%rsi	# %rip again
 	call __print_symbol
 #endif
 #endif /* EARLY_PRINTK */
 1:	hlt
 	jmp 1b
 
-20:	# Exception table entry found or page table generated
-	popq %r11
-	popq %r10
-	popq %r9
-	popq %r8
-	popq %rdi
-	popq %rsi
-	popq %rdx
-	popq %rcx
-	popq %rax
+20:	/* Exception table entry found or page table generated */
 	decl early_recursion_flag(%rip)
+	jmp restore_regs_and_iret
 .Lis_nmi:
 	addq $16,%rsp		# drop vector number and error code
 	INTERRUPT_RETURN
diff --git a/arch/x86/mm/extable.c b/arch/x86/mm/extable.c
index 9dd7e4b7fcde..176e48de25d4 100644
--- a/arch/x86/mm/extable.c
+++ b/arch/x86/mm/extable.c
@@ -90,13 +90,13 @@ int fixup_exception(struct pt_regs *regs, int trapnr)
 }
 
 /* Restricted version used during very early boot */
-int __init early_fixup_exception(unsigned long *ip)
+int __init early_fixup_exception(struct pt_regs *regs, int trapnr)
 {
 	const struct exception_table_entry *e;
 	unsigned long new_ip;
 	ex_handler_t handler;
 
-	e = search_exception_tables(*ip);
+	e = search_exception_tables(regs->ip);
 	if (!e)
 		return 0;
 
@@ -107,7 +107,7 @@ int __init early_fixup_exception(unsigned long *ip)
 	if (handler != ex_handler_default)
 		return 0;
 
-	*ip = new_ip;
+	regs->ip = new_ip;
 	return 1;
 }
 
-- 
2.5.5

[toc] | [prev] | [next] | [standalone]


#1377845 — [tip:x86/asm] x86/head: Pass a real pt_regs and trapnr to early_fixup_exception()

Fromtip-bot for Andy Lutomirski <tipbot@zytor.com>
Date2016-04-13 13:50 +0200
Subject[tip:x86/asm] x86/head: Pass a real pt_regs and trapnr to early_fixup_exception()
Message-ID<rnrt2-BH-75@gated-at.bofh.it>
In reply to#1369957
Commit-ID:  7bbcdb1ca4d2fd69094ee89c18601b396531ca9f
Gitweb:     http://git.kernel.org/tip/7bbcdb1ca4d2fd69094ee89c18601b396531ca9f
Author:     Andy Lutomirski <luto@kernel.org>
AuthorDate: Sat, 2 Apr 2016 07:01:32 -0700
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Wed, 13 Apr 2016 11:37:44 +0200

x86/head: Pass a real pt_regs and trapnr to early_fixup_exception()

early_fixup_exception() is limited by the fact that it doesn't have a
real struct pt_regs.  Change both the 32-bit and 64-bit asm and the
C code to pass and accept a real pt_regs.

Tested-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Signed-off-by: Andy Lutomirski <luto@kernel.org>
Acked-by: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Arjan van de Ven <arjan@linux.intel.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: KVM list <kvm@vger.kernel.org>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: xen-devel <Xen-devel@lists.xen.org>
Link: http://lkml.kernel.org/r/e3fb680fcfd5e23e38237e8328b64a25cc121d37.1459605520.git.luto@kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/include/asm/uaccess.h |  2 +-
 arch/x86/kernel/head_32.S      | 74 +++++++++++++++++++++++++++++-------------
 arch/x86/kernel/head_64.S      | 68 ++++++++++++++++++++------------------
 arch/x86/mm/extable.c          |  6 ++--
 4 files changed, 92 insertions(+), 58 deletions(-)

diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h
index a969ae6..b6fb311 100644
--- a/arch/x86/include/asm/uaccess.h
+++ b/arch/x86/include/asm/uaccess.h
@@ -110,7 +110,7 @@ struct exception_table_entry {
 
 extern int fixup_exception(struct pt_regs *regs, int trapnr);
 extern bool ex_has_fault_handler(unsigned long ip);
-extern int early_fixup_exception(unsigned long *ip);
+extern int early_fixup_exception(struct pt_regs *regs, int trapnr);
 
 /*
  * These are the main single-value transfer routines.  They automatically
diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S
index 54cdbd2..0904536 100644
--- a/arch/x86/kernel/head_32.S
+++ b/arch/x86/kernel/head_32.S
@@ -568,29 +568,64 @@ early_idt_handler_common:
 	je hlt_loop
 	incl %ss:early_recursion_flag
 
-	push %eax		# 16(%esp)
-	push %ecx		# 12(%esp)
-	push %edx		#  8(%esp)
-	push %ds		#  4(%esp)
-	push %es		#  0(%esp)
-	movl $(__KERNEL_DS),%eax
-	movl %eax,%ds
-	movl %eax,%es
+	/* The vector number is in pt_regs->gs */
 
-	cmpl $(__KERNEL_CS),32(%esp)
+	cld
+	pushl	%fs		/* pt_regs->fs */
+	movw	$0, 2(%esp)	/* clear high bits (some CPUs leave garbage) */
+	pushl	%es		/* pt_regs->es */
+	movw	$0, 2(%esp)	/* clear high bits (some CPUs leave garbage) */
+	pushl	%ds		/* pt_regs->ds */
+	movw	$0, 2(%esp)	/* clear high bits (some CPUs leave garbage) */
+	pushl	%eax		/* pt_regs->ax */
+	pushl	%ebp		/* pt_regs->bp */
+	pushl	%edi		/* pt_regs->di */
+	pushl	%esi		/* pt_regs->si */
+	pushl	%edx		/* pt_regs->dx */
+	pushl	%ecx		/* pt_regs->cx */
+	pushl	%ebx		/* pt_regs->bx */
+
+	/* Fix up DS and ES */
+	movl	$(__KERNEL_DS), %ecx
+	movl	%ecx, %ds
+	movl	%ecx, %es
+
+	/* Load the vector number into EDX */
+	movl	PT_GS(%esp), %edx
+
+	/* Load GS into pt_regs->gs and clear high bits */
+	movw	%gs, PT_GS(%esp)
+	movw	$0, PT_GS+2(%esp)
+
+	cmpl $(__KERNEL_CS),PT_CS(%esp)
 	jne 10f
 
-	leal 28(%esp),%eax	# Pointer to %eip
-	call early_fixup_exception
-	andl %eax,%eax
-	jnz ex_entry		/* found an exception entry */
+	movl	%esp, %eax	/* args are pt_regs (EAX), trapnr (EDX) */
+	call	early_fixup_exception
+	andl	%eax,%eax
+	jz	10f		/* Exception wasn't fixed up */
+
+	popl	%ebx		/* pt_regs->bx */
+	popl	%ecx		/* pt_regs->cx */
+	popl	%edx		/* pt_regs->dx */
+	popl	%esi		/* pt_regs->si */
+	popl	%edi		/* pt_regs->di */
+	popl	%ebp		/* pt_regs->bp */
+	popl	%eax		/* pt_regs->ax */
+	popl	%ds		/* pt_regs->ds */
+	popl	%es		/* pt_regs->es */
+	popl	%fs		/* pt_regs->fs */
+	popl	%gs		/* pt_regs->gs */
+	decl	%ss:early_recursion_flag
+	addl	$4, %esp	/* pop pt_regs->orig_ax */
+	iret
 
 10:
 #ifdef CONFIG_PRINTK
 	xorl %eax,%eax
-	movw %ax,2(%esp)	/* clean up the segment values on some cpus */
-	movw %ax,6(%esp)
-	movw %ax,34(%esp)
+	movw %ax,PT_FS+2(%esp)	/* clean up the segment values on some cpus */
+	movw %ax,PT_DS+2(%esp)
+	movw %ax,PT_ES+2(%esp)
 	leal  40(%esp),%eax
 	pushl %eax		/* %esp before the exception */
 	pushl %ebx
@@ -608,13 +643,6 @@ hlt_loop:
 	hlt
 	jmp hlt_loop
 
-ex_entry:
-	pop %es
-	pop %ds
-	pop %edx
-	pop %ecx
-	pop %eax
-	decl %ss:early_recursion_flag
 .Lis_nmi:
 	addl $8,%esp		/* drop vector number and error code */
 	iret
diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S
index 22fbf9d..9e8636d 100644
--- a/arch/x86/kernel/head_64.S
+++ b/arch/x86/kernel/head_64.S
@@ -20,6 +20,7 @@
 #include <asm/processor-flags.h>
 #include <asm/percpu.h>
 #include <asm/nops.h>
+#include "../entry/calling.h"
 
 #ifdef CONFIG_PARAVIRT
 #include <asm/asm-offsets.h>
@@ -357,39 +358,52 @@ early_idt_handler_common:
 	jz  1f
 	incl early_recursion_flag(%rip)
 
-	pushq %rax		# 64(%rsp)
-	pushq %rcx		# 56(%rsp)
-	pushq %rdx		# 48(%rsp)
-	pushq %rsi		# 40(%rsp)
-	pushq %rdi		# 32(%rsp)
-	pushq %r8		# 24(%rsp)
-	pushq %r9		# 16(%rsp)
-	pushq %r10		#  8(%rsp)
-	pushq %r11		#  0(%rsp)
-
-	cmpl $__KERNEL_CS,96(%rsp)
+	/* The vector number is currently in the pt_regs->di slot. */
+	pushq %rsi				/* pt_regs->si */
+	movq 8(%rsp), %rsi			/* RSI = vector number */
+	movq %rdi, 8(%rsp)			/* pt_regs->di = RDI */
+	pushq %rdx				/* pt_regs->dx */
+	pushq %rcx				/* pt_regs->cx */
+	pushq %rax				/* pt_regs->ax */
+	pushq %r8				/* pt_regs->r8 */
+	pushq %r9				/* pt_regs->r9 */
+	pushq %r10				/* pt_regs->r10 */
+	pushq %r11				/* pt_regs->r11 */
+	pushq %rbx				/* pt_regs->bx */
+	pushq %rbp				/* pt_regs->bp */
+	pushq %r12				/* pt_regs->r12 */
+	pushq %r13				/* pt_regs->r13 */
+	pushq %r14				/* pt_regs->r14 */
+	pushq %r15				/* pt_regs->r15 */
+
+	cmpl $__KERNEL_CS,CS(%rsp)
 	jne 11f
 
-	cmpl $14,72(%rsp)	# Page fault?
+	cmpq $14,%rsi		/* Page fault? */
 	jnz 10f
-	GET_CR2_INTO(%rdi)	# can clobber any volatile register if pv
+	GET_CR2_INTO(%rdi)	/* Can clobber any volatile register if pv */
 	call early_make_pgtable
 	andl %eax,%eax
-	jz 20f			# All good
+	jz 20f			/* All good */
 
 10:
-	leaq 88(%rsp),%rdi	# Pointer to %rip
+	movq %rsp,%rdi		/* RDI = pt_regs; RSI is already trapnr */
 	call early_fixup_exception
 	andl %eax,%eax
 	jnz 20f			# Found an exception entry
 
 11:
 #ifdef CONFIG_EARLY_PRINTK
-	GET_CR2_INTO(%r9)	# can clobber any volatile register if pv
-	movl 80(%rsp),%r8d	# error code
-	movl 72(%rsp),%esi	# vector number
-	movl 96(%rsp),%edx	# %cs
-	movq 88(%rsp),%rcx	# %rip
+	/*
+	 * On paravirt kernels, GET_CR2_INTO clobbers callee-clobbered regs.
+	 * We only care about RSI, so we need to save it.
+	 */
+	movq %rsi,%rbx		/* Save vector number */
+	GET_CR2_INTO(%r9)
+	movq ORIG_RAX(%rsp),%r8	/* error code */
+	movq %rbx,%rsi		/* vector number */
+	movq CS(%rsp),%rdx
+	movq RIP(%rsp),%rcx
 	xorl %eax,%eax
 	leaq early_idt_msg(%rip),%rdi
 	call early_printk
@@ -398,24 +412,16 @@ early_idt_handler_common:
 	call dump_stack
 #ifdef CONFIG_KALLSYMS	
 	leaq early_idt_ripmsg(%rip),%rdi
-	movq 40(%rsp),%rsi	# %rip again
+	movq RIP(%rsp),%rsi	# %rip again
 	call __print_symbol
 #endif
 #endif /* EARLY_PRINTK */
 1:	hlt
 	jmp 1b
 
-20:	# Exception table entry found or page table generated
-	popq %r11
-	popq %r10
-	popq %r9
-	popq %r8
-	popq %rdi
-	popq %rsi
-	popq %rdx
-	popq %rcx
-	popq %rax
+20:	/* Exception table entry found or page table generated */
 	decl early_recursion_flag(%rip)
+	jmp restore_regs_and_iret
 .Lis_nmi:
 	addq $16,%rsp		# drop vector number and error code
 	INTERRUPT_RETURN
diff --git a/arch/x86/mm/extable.c b/arch/x86/mm/extable.c
index 82447b3..1366e06 100644
--- a/arch/x86/mm/extable.c
+++ b/arch/x86/mm/extable.c
@@ -83,13 +83,13 @@ int fixup_exception(struct pt_regs *regs, int trapnr)
 }
 
 /* Restricted version used during very early boot */
-int __init early_fixup_exception(unsigned long *ip)
+int __init early_fixup_exception(struct pt_regs *regs, int trapnr)
 {
 	const struct exception_table_entry *e;
 	unsigned long new_ip;
 	ex_handler_t handler;
 
-	e = search_exception_tables(*ip);
+	e = search_exception_tables(regs->ip);
 	if (!e)
 		return 0;
 
@@ -100,6 +100,6 @@ int __init early_fixup_exception(unsigned long *ip)
 	if (handler != ex_handler_default)
 		return 0;
 
-	*ip = new_ip;
+	regs->ip = new_ip;
 	return 1;
 }

[toc] | [prev] | [next] | [standalone]


#1369958 — [PATCH v5 6/9] x86/msr: Carry on after a non-"safe" MSR access fails

FromAndy Lutomirski <luto@kernel.org>
Date2016-04-02 16:10 +0200
Subject[PATCH v5 6/9] x86/msr: Carry on after a non-"safe" MSR access fails
Message-ID<rjupv-4TG-33@gated-at.bofh.it>
In reply to#1369949
This demotes an OOPS and likely panic due to a failed non-"safe" MSR
access to a WARN_ONCE and, for RDMSR, a return value of zero.

To be clear, this type of failure should *not* happen.  This patch
exists to minimize the chance of nasty undebuggable failures
happening when a CONFIG_PARAVIRT=y bug in the non-"safe" MSR helpers
gets fixed.

Signed-off-by: Andy Lutomirski <luto@kernel.org>
---
 arch/x86/include/asm/msr.h | 10 ++++++++--
 arch/x86/mm/extable.c      | 27 +++++++++++++++++++++++++++
 2 files changed, 35 insertions(+), 2 deletions(-)

diff --git a/arch/x86/include/asm/msr.h b/arch/x86/include/asm/msr.h
index 93fb7c1cffda..1487054a1a70 100644
--- a/arch/x86/include/asm/msr.h
+++ b/arch/x86/include/asm/msr.h
@@ -92,7 +92,10 @@ static inline unsigned long long native_read_msr(unsigned int msr)
 {
 	DECLARE_ARGS(val, low, high);
 
-	asm volatile("rdmsr" : EAX_EDX_RET(val, low, high) : "c" (msr));
+	asm volatile("1: rdmsr\n"
+		     "2:\n"
+		     _ASM_EXTABLE_HANDLE(1b, 2b, ex_handler_rdmsr_unsafe)
+		     : EAX_EDX_RET(val, low, high) : "c" (msr));
 	if (msr_tracepoint_active(__tracepoint_read_msr))
 		do_trace_read_msr(msr, EAX_EDX_VAL(val, low, high), 0);
 	return EAX_EDX_VAL(val, low, high);
@@ -119,7 +122,10 @@ static inline unsigned long long native_read_msr_safe(unsigned int msr,
 static inline void native_write_msr(unsigned int msr,
 				    unsigned low, unsigned high)
 {
-	asm volatile("wrmsr" : : "c" (msr), "a"(low), "d" (high) : "memory");
+	asm volatile("1: wrmsr\n"
+		     "2:\n"
+		     _ASM_EXTABLE_HANDLE(1b, 2b, ex_handler_wrmsr_unsafe)
+		     : : "c" (msr), "a"(low), "d" (high) : "memory");
 	if (msr_tracepoint_active(__tracepoint_read_msr))
 		do_trace_write_msr(msr, ((u64)high << 32 | low), 0);
 }
diff --git a/arch/x86/mm/extable.c b/arch/x86/mm/extable.c
index 50dfe438bd91..98b5f45d9d79 100644
--- a/arch/x86/mm/extable.c
+++ b/arch/x86/mm/extable.c
@@ -50,6 +50,33 @@ bool ex_handler_ext(const struct exception_table_entry *fixup,
 }
 EXPORT_SYMBOL(ex_handler_ext);
 
+bool ex_handler_rdmsr_unsafe(const struct exception_table_entry *fixup,
+			     struct pt_regs *regs, int trapnr)
+{
+	WARN_ONCE(1, "unchecked MSR access error: RDMSR from 0x%x\n",
+		  (unsigned int)regs->cx);
+
+	/* Pretend that the read succeeded and returned 0. */
+	regs->ip = ex_fixup_addr(fixup);
+	regs->ax = 0;
+	regs->dx = 0;
+	return true;
+}
+EXPORT_SYMBOL(ex_handler_rdmsr_unsafe);
+
+bool ex_handler_wrmsr_unsafe(const struct exception_table_entry *fixup,
+			     struct pt_regs *regs, int trapnr)
+{
+	WARN_ONCE(1, "unchecked MSR access error: WRMSR to 0x%x (tried to write 0x%08x%08x)\n",
+		  (unsigned int)regs->cx,
+		  (unsigned int)regs->dx, (unsigned int)regs->ax);
+
+	/* Pretend that the write succeeded. */
+	regs->ip = ex_fixup_addr(fixup);
+	return true;
+}
+EXPORT_SYMBOL(ex_handler_wrmsr_unsafe);
+
 bool ex_has_fault_handler(unsigned long ip)
 {
 	const struct exception_table_entry *e;
-- 
2.5.5

[toc] | [prev] | [next] | [standalone]


#1377828 — [tip:x86/asm] x86/msr: Carry on after a non-"safe" MSR access fails

Fromtip-bot for Andy Lutomirski <tipbot@zytor.com>
Date2016-04-13 13:50 +0200
Subject[tip:x86/asm] x86/msr: Carry on after a non-"safe" MSR access fails
Message-ID<rnrt1-BH-43@gated-at.bofh.it>
In reply to#1369958
Commit-ID:  fbd704374d111bed16a19261176fa30e2379c87c
Gitweb:     http://git.kernel.org/tip/fbd704374d111bed16a19261176fa30e2379c87c
Author:     Andy Lutomirski <luto@kernel.org>
AuthorDate: Sat, 2 Apr 2016 07:01:37 -0700
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Wed, 13 Apr 2016 11:37:45 +0200

x86/msr: Carry on after a non-"safe" MSR access fails

This demotes an OOPS and likely panic due to a failed non-"safe" MSR
access to a WARN_ONCE() and, for RDMSR, a return value of zero.

To be clear, this type of failure should *not* happen.  This patch
exists to minimize the chance of nasty undebuggable failures
happening when a CONFIG_PARAVIRT=y bug in the non-"safe" MSR helpers
gets fixed.

Tested-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Signed-off-by: Andy Lutomirski <luto@kernel.org>
Acked-by: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Arjan van de Ven <arjan@linux.intel.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: KVM list <kvm@vger.kernel.org>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: xen-devel <Xen-devel@lists.xen.org>
Link: http://lkml.kernel.org/r/26567b216aae70e795938f4b567eace5a0eb90ba.1459605520.git.luto@kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/include/asm/msr.h | 10 ++++++++--
 arch/x86/mm/extable.c      | 27 +++++++++++++++++++++++++++
 2 files changed, 35 insertions(+), 2 deletions(-)

diff --git a/arch/x86/include/asm/msr.h b/arch/x86/include/asm/msr.h
index 7a79ee2..25f169c 100644
--- a/arch/x86/include/asm/msr.h
+++ b/arch/x86/include/asm/msr.h
@@ -84,7 +84,10 @@ static inline unsigned long long native_read_msr(unsigned int msr)
 {
 	DECLARE_ARGS(val, low, high);
 
-	asm volatile("rdmsr" : EAX_EDX_RET(val, low, high) : "c" (msr));
+	asm volatile("1: rdmsr\n"
+		     "2:\n"
+		     _ASM_EXTABLE_HANDLE(1b, 2b, ex_handler_rdmsr_unsafe)
+		     : EAX_EDX_RET(val, low, high) : "c" (msr));
 	if (msr_tracepoint_active(__tracepoint_read_msr))
 		do_trace_read_msr(msr, EAX_EDX_VAL(val, low, high), 0);
 	return EAX_EDX_VAL(val, low, high);
@@ -111,7 +114,10 @@ static inline unsigned long long native_read_msr_safe(unsigned int msr,
 static inline void native_write_msr(unsigned int msr,
 				    unsigned low, unsigned high)
 {
-	asm volatile("wrmsr" : : "c" (msr), "a"(low), "d" (high) : "memory");
+	asm volatile("1: wrmsr\n"
+		     "2:\n"
+		     _ASM_EXTABLE_HANDLE(1b, 2b, ex_handler_wrmsr_unsafe)
+		     : : "c" (msr), "a"(low), "d" (high) : "memory");
 	if (msr_tracepoint_active(__tracepoint_read_msr))
 		do_trace_write_msr(msr, ((u64)high << 32 | low), 0);
 }
diff --git a/arch/x86/mm/extable.c b/arch/x86/mm/extable.c
index 061a237..fd9eb98 100644
--- a/arch/x86/mm/extable.c
+++ b/arch/x86/mm/extable.c
@@ -43,6 +43,33 @@ bool ex_handler_ext(const struct exception_table_entry *fixup,
 }
 EXPORT_SYMBOL(ex_handler_ext);
 
+bool ex_handler_rdmsr_unsafe(const struct exception_table_entry *fixup,
+			     struct pt_regs *regs, int trapnr)
+{
+	WARN_ONCE(1, "unchecked MSR access error: RDMSR from 0x%x\n",
+		  (unsigned int)regs->cx);
+
+	/* Pretend that the read succeeded and returned 0. */
+	regs->ip = ex_fixup_addr(fixup);
+	regs->ax = 0;
+	regs->dx = 0;
+	return true;
+}
+EXPORT_SYMBOL(ex_handler_rdmsr_unsafe);
+
+bool ex_handler_wrmsr_unsafe(const struct exception_table_entry *fixup,
+			     struct pt_regs *regs, int trapnr)
+{
+	WARN_ONCE(1, "unchecked MSR access error: WRMSR to 0x%x (tried to write 0x%08x%08x)\n",
+		  (unsigned int)regs->cx,
+		  (unsigned int)regs->dx, (unsigned int)regs->ax);
+
+	/* Pretend that the write succeeded. */
+	regs->ip = ex_fixup_addr(fixup);
+	return true;
+}
+EXPORT_SYMBOL(ex_handler_wrmsr_unsafe);
+
 bool ex_has_fault_handler(unsigned long ip)
 {
 	const struct exception_table_entry *e;

[toc] | [prev] | [next] | [standalone]


#1369960 — [PATCH v5 9/9] x86/msr: Set the return value to zero when native_rdmsr_safe fails

FromAndy Lutomirski <luto@kernel.org>
Date2016-04-02 16:10 +0200
Subject[PATCH v5 9/9] x86/msr: Set the return value to zero when native_rdmsr_safe fails
Message-ID<rjupv-4TG-31@gated-at.bofh.it>
In reply to#1369949
This will cause unchecked native_rdmsr_safe failures to return
deterministic results.

Signed-off-by: Andy Lutomirski <luto@kernel.org>
---
 arch/x86/include/asm/msr.h | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/x86/include/asm/msr.h b/arch/x86/include/asm/msr.h
index 13da359881d7..e97e79f8a22b 100644
--- a/arch/x86/include/asm/msr.h
+++ b/arch/x86/include/asm/msr.h
@@ -109,7 +109,10 @@ static inline unsigned long long native_read_msr_safe(unsigned int msr,
 	asm volatile("2: rdmsr ; xor %[err],%[err]\n"
 		     "1:\n\t"
 		     ".section .fixup,\"ax\"\n\t"
-		     "3:  mov %[fault],%[err] ; jmp 1b\n\t"
+		     "3: mov %[fault],%[err]\n\t"
+		     "xorl %%eax, %%eax\n\t"
+		     "xorl %%edx, %%edx\n\t"
+		     "jmp 1b\n\t"
 		     ".previous\n\t"
 		     _ASM_EXTABLE(2b, 3b)
 		     : [err] "=r" (*err), EAX_EDX_RET(val, low, high)
-- 
2.5.5

[toc] | [prev] | [next] | [standalone]


#1377825 — [tip:x86/asm] x86/msr: Set the return value to zero when native_rdmsr_safe() fails

Fromtip-bot for Andy Lutomirski <tipbot@zytor.com>
Date2016-04-13 13:50 +0200
Subject[tip:x86/asm] x86/msr: Set the return value to zero when native_rdmsr_safe() fails
Message-ID<rnrt1-BH-37@gated-at.bofh.it>
In reply to#1369960
Commit-ID:  b828b79fcced0e66492590707649dbfaea6435e6
Gitweb:     http://git.kernel.org/tip/b828b79fcced0e66492590707649dbfaea6435e6
Author:     Andy Lutomirski <luto@kernel.org>
AuthorDate: Sat, 2 Apr 2016 07:01:40 -0700
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Wed, 13 Apr 2016 11:37:46 +0200

x86/msr: Set the return value to zero when native_rdmsr_safe() fails

This will cause unchecked native_rdmsr_safe() failures to return
deterministic results.

Tested-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Signed-off-by: Andy Lutomirski <luto@kernel.org>
Acked-by: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Arjan van de Ven <arjan@linux.intel.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: KVM list <kvm@vger.kernel.org>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: xen-devel <Xen-devel@lists.xen.org>
Link: http://lkml.kernel.org/r/515fb611449a755312a476cfe11675906e7ddf6c.1459605520.git.luto@kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/include/asm/msr.h | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/x86/include/asm/msr.h b/arch/x86/include/asm/msr.h
index 00050c0..7dc1d8f 100644
--- a/arch/x86/include/asm/msr.h
+++ b/arch/x86/include/asm/msr.h
@@ -101,7 +101,10 @@ static inline unsigned long long native_read_msr_safe(unsigned int msr,
 	asm volatile("2: rdmsr ; xor %[err],%[err]\n"
 		     "1:\n\t"
 		     ".section .fixup,\"ax\"\n\t"
-		     "3:  mov %[fault],%[err] ; jmp 1b\n\t"
+		     "3: mov %[fault],%[err]\n\t"
+		     "xorl %%eax, %%eax\n\t"
+		     "xorl %%edx, %%edx\n\t"
+		     "jmp 1b\n\t"
 		     ".previous\n\t"
 		     _ASM_EXTABLE(2b, 3b)
 		     : [err] "=r" (*err), EAX_EDX_RET(val, low, high)

[toc] | [prev] | [next] | [standalone]


#1369962

FromLinus Torvalds <torvalds@linux-foundation.org>
Date2016-04-02 16:30 +0200
Message-ID<rjuIN-531-13@gated-at.bofh.it>
In reply to#1369949
This patch series looks much nicer than the last one. I assume you
tested that the early-trap handling actually worked too? I only looked
at the patches..

Ack to it all,

           Linus

[toc] | [prev] | [next] | [standalone]


#1369966

FromAndy Lutomirski <luto@amacapital.net>
Date2016-04-02 17:20 +0200
Message-ID<rjvvc-5Hg-9@gated-at.bofh.it>
In reply to#1369962
On Sat, Apr 2, 2016 at 7:24 AM, Linus Torvalds
<torvalds@linux-foundation.org> wrote:
> This patch series looks much nicer than the last one. I assume you
> tested that the early-trap handling actually worked too? I only looked
> at the patches..
>
> Ack to it all,

I injected some BUGs in various places on 32-bit an 64-bit and it
seemed to do the right thing.  Depending on how early they were, I
either got a clean hang or I got a printout, and whether it displayed
anything didn't seem to change with and without the patches.  I think
that early_printk doesn't work from the very very beginning.

I also tried a bad wrmsrl at a couple early points.  Very very early
it just works with not warning.  A little later and it prints the
warning.

--Andy

[toc] | [prev] | [next] | [standalone]


#1369967

FromLinus Torvalds <torvalds@linux-foundation.org>
Date2016-04-02 17:30 +0200
Message-ID<rjvES-5Mq-7@gated-at.bofh.it>
In reply to#1369966
On Sat, Apr 2, 2016 at 10:13 AM, Andy Lutomirski <luto@amacapital.net> wrote:
>
> I also tried a bad wrmsrl at a couple early points.  Very very early
> it just works with not warning.  A little later and it prints the
> warning.

Ok, that sounds like the correct behavior - I'm sure the very very
early ones "warned" too, it just got dropped on the floor due to being
before the printing/logging was up and running.

And even then, it's obviously much better than having machines
mysteriously just reboot.

Thanks,
         Linus

[toc] | [prev] | [next] | [standalone]


#1370751

FromBorislav Petkov <bp@alien8.de>
Date2016-04-04 18:30 +0200
Message-ID<rkfy4-5Pj-35@gated-at.bofh.it>
In reply to#1369949
On Sat, Apr 02, 2016 at 07:01:31AM -0700, Andy Lutomirski wrote:
> There are two parts here:
> 
> ***** FIRST PART: EARLY EXCEPTIONS *****
> 
> The first few patches move some early panic code into C, add pt_regs
> to early exception handling, and make fancy exception handlers work early.
> 
> ***** SECOND PART: MSRs *****
> 
> Setting CONFIG_PARAVIRT=y has an unintended side effect: it silently
> turns all rdmsr and wrmsr operations into the safe variants without
> any checks that the operations actually succeed.


...

FWIW:

Reviewed-by: Borislav Petkov <bp@suse.de>

Definitely a step in the right direction, regardless of how we're going
to be doing early_printk(), which is a tangential topic. This pile could
be taken for a spin in tip.

-- 
Regards/Gruss,
    Boris.

ECO tip #101: Trim your mails when you reply.

[toc] | [prev] | [next] | [standalone]


#1371724 — Re: [Xen-devel] [PATCH v5 0/9] Improve non-"safe" MSR access failure handling

FromBoris Ostrovsky <boris.ostrovsky@oracle.com>
Date2016-04-05 17:40 +0200
SubjectRe: [Xen-devel] [PATCH v5 0/9] Improve non-"safe" MSR access failure handling
Message-ID<rkBfb-61Y-1@gated-at.bofh.it>
In reply to#1369949
On 04/02/2016 10:01 AM, Andy Lutomirski wrote:
>
> Andy Lutomirski (9):
>    x86/head: Pass a real pt_regs and trapnr to early_fixup_exception
>    x86/head: Move the early NMI fixup into C
>    x86/head: Move early exception panic code into early_fixup_exception
>    x86/traps: Enable all exception handler callbacks early
>    x86/paravirt: Add _safe to the read_msr and write_msr PV hooks
>    x86/msr: Carry on after a non-"safe" MSR access fails
>    x86/paravirt: Add paravirt_{read,write}_msr
>    x86/paravirt: Make "unsafe" MSR accesses unsafe even if PARAVIRT=y
>    x86/msr: Set the return value to zero when native_rdmsr_safe fails

With Xen (on top of eb1af3b):

Tested-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>

-boris

[toc] | [prev] | [standalone]


Page 2 of 2 — ← Prev page 1 [2]

Back to top | Article view | linux.kernel


csiph-web