Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1369949 > unrolled thread
| Started by | Andy Lutomirski <luto@kernel.org> |
|---|---|
| First post | 2016-04-02 16:10 +0200 |
| Last post | 2016-04-05 17:40 +0200 |
| Articles | 19 on this page of 39 — 10 participants |
Back to article view | Back to linux.kernel
[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]
| From | Borislav Petkov <bp@alien8.de> |
|---|---|
| Date | 2016-04-04 21:40 +0200 |
| Subject | Re: [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]
| From | Andy Lutomirski <luto@amacapital.net> |
|---|---|
| Date | 2016-04-04 23:40 +0200 |
| Subject | Re: [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]
| From | Borislav Petkov <bp@alien8.de> |
|---|---|
| Date | 2016-04-04 23:50 +0200 |
| Subject | Re: [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]
| From | tip-bot for Andy Lutomirski <tipbot@zytor.com> |
|---|---|
| Date | 2016-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]
| From | Andy Lutomirski <luto@kernel.org> |
|---|---|
| Date | 2016-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]
| From | David Vrabel <david.vrabel@citrix.com> |
|---|---|
| Date | 2016-04-04 18:40 +0200 |
| Subject | Re: [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]
| From | Andy Lutomirski <luto@amacapital.net> |
|---|---|
| Date | 2016-04-04 18:50 +0200 |
| Subject | Re: [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]
| From | tip-bot for Andy Lutomirski <tipbot@zytor.com> |
|---|---|
| Date | 2016-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]
| From | Andy Lutomirski <luto@kernel.org> |
|---|---|
| Date | 2016-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]
| From | tip-bot for Andy Lutomirski <tipbot@zytor.com> |
|---|---|
| Date | 2016-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]
| From | Andy Lutomirski <luto@kernel.org> |
|---|---|
| Date | 2016-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]
| From | tip-bot for Andy Lutomirski <tipbot@zytor.com> |
|---|---|
| Date | 2016-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]
| From | Andy Lutomirski <luto@kernel.org> |
|---|---|
| Date | 2016-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]
| From | tip-bot for Andy Lutomirski <tipbot@zytor.com> |
|---|---|
| Date | 2016-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]
| From | Linus Torvalds <torvalds@linux-foundation.org> |
|---|---|
| Date | 2016-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]
| From | Andy Lutomirski <luto@amacapital.net> |
|---|---|
| Date | 2016-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]
| From | Linus Torvalds <torvalds@linux-foundation.org> |
|---|---|
| Date | 2016-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]
| From | Borislav Petkov <bp@alien8.de> |
|---|---|
| Date | 2016-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]
| From | Boris Ostrovsky <boris.ostrovsky@oracle.com> |
|---|---|
| Date | 2016-04-05 17:40 +0200 |
| Subject | Re: [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