Skip to contentSkip to conversation

Improve non-"safe" MSR access failure handling

PATCH Superseded Andy Lutomirski 10 participants 97 messages Apr 2, 2016 – Apr 13, 2016

Subsystems (6)
x86 KVM x86 MM Xen hypervisor x86 +2 more subsystems
lore
Share & tools
lore

Andy Lutomirski

author maintainer
#0 lore raw

v5 cover Improve non-"safe" MSR access failure handling

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.

With CONFIG_PARAVIRT=n, unchecked MSR failures OOPS and probably cause boot to fail if they happen before init starts.

Neither behavior is very good, and it's particularly unfortunate that the behavior changes depending on CONFIG_PARAVIRT.

In particular, KVM guests might be unwittingly depending on the PARAVIRT=y behavior because CONFIG_KVM_GUEST currently depends on CONFIG_PARAVIRT, and, because accesses in that case are completely unchecked, we wouldn't even see a warning.

This series changes the native behavior, regardless of CONFIG_PARAVIRT. A non-"safe" MSR failure will give an informative warning once and will be fixed up -- native_read_msr will return zero, and both reads and writes will continue where they left off.

If panic_on_oops is set, they will still OOPS and panic.

By using the shiny new custom exception handler infrastructure, there should be no overhead on the success paths.

I didn't change the behavior on Xen, but, with this series applied, it would be straightforward for the Xen maintainers to make the corresponding change -- knowledge of whether the access is "safe" is now propagated into the pvops.

Doing this is probably a prerequisite to sanely decoupling CONFIG_KVM_GUEST and CONFIG_PARAVIRT, which would probably make Arjan and the rest of the Clear Containers people happy :)

There's also room to reduce the code size of the "safe" variants using custom exception handlers in the future.

Changes from v4:
- Fix a missing \n (Joe Perches)
- No more panic_on_oops
- Works early

Changes from v3:
- WARN_ONCE instead of WARN (Ingo)
- In the warning text, s/unsafe/unchecked/ (Ingo, sort of)

Changes from earlier versions: lots of changes!

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

 arch/x86/include/asm/msr.h            |  20 ++++--
 arch/x86/include/asm/paravirt.h       |  45 +++++++------
 arch/x86/include/asm/paravirt_types.h |  14 ++--
 arch/x86/include/asm/uaccess.h        |   2 +-
 arch/x86/kernel/head_32.S             | 116 ++++++++++++++--------------------
 arch/x86/kernel/head_64.S             |  95 ++++++++--------------------
 arch/x86/kernel/paravirt.c            |   6 +-
 arch/x86/mm/extable.c                 |  64 +++++++++++++++----
 arch/x86/xen/enlighten.c              |  27 +++++++-
 9 files changed, 208 insertions(+), 181 deletions(-)
Signature · 1 line
2.5.5
author maintainer
#1 lore raw

PATCH v5 1/9 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.

---
 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(-)
arch/x86/include/asm/uaccess.h +1 -1
index c0f27d7ea7ff..a3afb7259751 100644
@@ -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
arch/x86/kernel/head_32.S +51 -23

93 lines not on this page · raw message

arch/x86/kernel/head_64.S +37 -31

106 lines not on this page · raw message

arch/x86/mm/extable.c +3 -3
index 9dd7e4b7fcde..176e48de25d4 100644
@@ -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;
 }
 
Signature · 7 lines
2.5.5


_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
#2 lore raw

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

x86/head: Pass a real pt_regs and trapnr to early_fixup_exception()
Commit-ID:  7bbcdb1ca4d2fd69094ee89c18601b396531ca9f
Gitweb:     http://git.kernel.org/tip/7bbcdb1ca4d2fd69094ee89c18601b396531ca9f
Author:     Andy Lutomirski <[email protected]>
AuthorDate: Sat, 2 Apr 2016 07:01:32 -0700
Committer:  Ingo Molnar <[email protected]>
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.

---
 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(-)
arch/x86/include/asm/uaccess.h +1 -1
index a969ae6..b6fb311 100644
@@ -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
arch/x86/kernel/head_32.S +51 -23

93 lines not on this page · raw message

arch/x86/kernel/head_64.S +37 -31

106 lines not on this page · raw message

arch/x86/mm/extable.c +3 -3
index 82447b3..1366e06 100644
@@ -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;
 }
#3 lore raw

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

In reply to Andy Lutomirski
x86/head: Pass a real pt_regs and trapnr to early_fixup_exception()
Commit-ID:  7bbcdb1ca4d2fd69094ee89c18601b396531ca9f
Gitweb:     http://git.kernel.org/tip/7bbcdb1ca4d2fd69094ee89c18601b396531ca9f
Author:     Andy Lutomirski <[email protected]>
AuthorDate: Sat, 2 Apr 2016 07:01:32 -0700
Committer:  Ingo Molnar <[email protected]>
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.

---
 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(-)
arch/x86/include/asm/uaccess.h +1 -1
index a969ae6..b6fb311 100644
@@ -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
arch/x86/kernel/head_32.S +51 -23

93 lines not on this page · raw message

arch/x86/kernel/head_64.S +37 -31

106 lines not on this page · raw message

arch/x86/mm/extable.c +3 -3
index 82447b3..1366e06 100644
@@ -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;
 }

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel

author maintainer
#4 lore raw

PATCH v5 2/9 x86/head: Move the early NMI fixup into C

In reply to Andy Lutomirski

C is nicer than asm.

---
 arch/x86/kernel/head_32.S | 7 -------
 arch/x86/kernel/head_64.S | 6 ------
 arch/x86/mm/extable.c     | 5 +++++
 3 files changed, 5 insertions(+), 13 deletions(-)
arch/x86/kernel/head_32.S +0 -7
index bef3e6c49b56..5e6ce845813a 100644
@@ -555,9 +555,6 @@ early_idt_handler_common:
 	 */
 	cld
 
-	cmpl $2,(%esp)		# X86_TRAP_NMI
-	je .Lis_nmi		# Ignore NMI
-
 	cmpl $2,%ss:early_recursion_flag
 	je hlt_loop
 	incl %ss:early_recursion_flag
@@ -636,10 +633,6 @@ early_idt_handler_common:
 hlt_loop:
 	hlt
 	jmp hlt_loop
-
-.Lis_nmi:
-	addl $8,%esp		/* drop vector number and error code */
-	iret
 ENDPROC(early_idt_handler_common)
 
 /* This is the default interrupt "handler" :-) */
arch/x86/kernel/head_64.S +0 -6
index f8d6dad41e8d..af87896b6a23 100644
@@ -354,9 +354,6 @@ early_idt_handler_common:
 	 */
 	cld
 
-	cmpl $2,(%rsp)		# X86_TRAP_NMI
-	je .Lis_nmi		# Ignore NMI
-
 	cmpl $2,early_recursion_flag(%rip)
 	jz  1f
 	incl early_recursion_flag(%rip)
@@ -425,9 +422,6 @@ early_idt_handler_common:
 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
 ENDPROC(early_idt_handler_common)
 
 	__INITDATA
arch/x86/mm/extable.c +5 -0
index 176e48de25d4..d6e4e6fb4002 100644
@@ -2,6 +2,7 @@
 #include <linux/spinlock.h>
 #include <linux/sort.h>
 #include <asm/uaccess.h>
+#include <asm/traps.h>
 
 typedef bool (*ex_handler_t)(const struct exception_table_entry *,
 			    struct pt_regs *, int);
@@ -96,6 +97,10 @@ int __init early_fixup_exception(struct pt_regs *regs, int trapnr)
 	unsigned long new_ip;
 	ex_handler_t handler;
 
+	/* Ignore early NMIs. */
+	if (trapnr == X86_TRAP_NMI)
+		return 1;
+
 	e = search_exception_tables(regs->ip);
 	if (!e)
 		return 0;
Signature · 1 line
2.5.5
#5 lore raw

[tip:x86/asm] x86/head: Move the early NMI fixup into C

x86/head: Move the early NMI fixup into C
Commit-ID:  0d0efc07f3df677d7622bb760f8e2920b5e33f42
Gitweb:     http://git.kernel.org/tip/0d0efc07f3df677d7622bb760f8e2920b5e33f42
Author:     Andy Lutomirski <[email protected]>
AuthorDate: Sat, 2 Apr 2016 07:01:33 -0700
Committer:  Ingo Molnar <[email protected]>
CommitDate: Wed, 13 Apr 2016 11:37:44 +0200

x86/head: Move the early NMI fixup into C

C is nicer than asm.

---
 arch/x86/kernel/head_32.S | 7 -------
 arch/x86/kernel/head_64.S | 6 ------
 arch/x86/mm/extable.c     | 5 +++++
 3 files changed, 5 insertions(+), 13 deletions(-)
arch/x86/kernel/head_32.S +0 -7
index 0904536..184291c 100644
@@ -561,9 +561,6 @@ early_idt_handler_common:
 	 */
 	cld
 
-	cmpl $2,(%esp)		# X86_TRAP_NMI
-	je .Lis_nmi		# Ignore NMI
-
 	cmpl $2,%ss:early_recursion_flag
 	je hlt_loop
 	incl %ss:early_recursion_flag
@@ -642,10 +639,6 @@ early_idt_handler_common:
 hlt_loop:
 	hlt
 	jmp hlt_loop
-
-.Lis_nmi:
-	addl $8,%esp		/* drop vector number and error code */
-	iret
 ENDPROC(early_idt_handler_common)
 
 /* This is the default interrupt "handler" :-) */
arch/x86/kernel/head_64.S +0 -6
index 9e8636d..2308437 100644
@@ -351,9 +351,6 @@ early_idt_handler_common:
 	 */
 	cld
 
-	cmpl $2,(%rsp)		# X86_TRAP_NMI
-	je .Lis_nmi		# Ignore NMI
-
 	cmpl $2,early_recursion_flag(%rip)
 	jz  1f
 	incl early_recursion_flag(%rip)
@@ -422,9 +419,6 @@ early_idt_handler_common:
 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
 ENDPROC(early_idt_handler_common)
 
 	__INITDATA
arch/x86/mm/extable.c +5 -0
index 1366e06..4be0419 100644
@@ -1,5 +1,6 @@
 #include <linux/module.h>
 #include <asm/uaccess.h>
+#include <asm/traps.h>
 
 typedef bool (*ex_handler_t)(const struct exception_table_entry *,
 			    struct pt_regs *, int);
@@ -89,6 +90,10 @@ int __init early_fixup_exception(struct pt_regs *regs, int trapnr)
 	unsigned long new_ip;
 	ex_handler_t handler;
 
+	/* Ignore early NMIs. */
+	if (trapnr == X86_TRAP_NMI)
+		return 1;
+
 	e = search_exception_tables(regs->ip);
 	if (!e)
 		return 0;
#6 lore raw

[tip:x86/asm] x86/head: Move the early NMI fixup into C

In reply to Andy Lutomirski
x86/head: Move the early NMI fixup into C
Commit-ID:  0d0efc07f3df677d7622bb760f8e2920b5e33f42
Gitweb:     http://git.kernel.org/tip/0d0efc07f3df677d7622bb760f8e2920b5e33f42
Author:     Andy Lutomirski <[email protected]>
AuthorDate: Sat, 2 Apr 2016 07:01:33 -0700
Committer:  Ingo Molnar <[email protected]>
CommitDate: Wed, 13 Apr 2016 11:37:44 +0200

x86/head: Move the early NMI fixup into C

C is nicer than asm.

---
 arch/x86/kernel/head_32.S | 7 -------
 arch/x86/kernel/head_64.S | 6 ------
 arch/x86/mm/extable.c     | 5 +++++
 3 files changed, 5 insertions(+), 13 deletions(-)
arch/x86/kernel/head_32.S +0 -7
index 0904536..184291c 100644
@@ -561,9 +561,6 @@ early_idt_handler_common:
 	 */
 	cld
 
-	cmpl $2,(%esp)		# X86_TRAP_NMI
-	je .Lis_nmi		# Ignore NMI
-
 	cmpl $2,%ss:early_recursion_flag
 	je hlt_loop
 	incl %ss:early_recursion_flag
@@ -642,10 +639,6 @@ early_idt_handler_common:
 hlt_loop:
 	hlt
 	jmp hlt_loop
-
-.Lis_nmi:
-	addl $8,%esp		/* drop vector number and error code */
-	iret
 ENDPROC(early_idt_handler_common)
 
 /* This is the default interrupt "handler" :-) */
arch/x86/kernel/head_64.S +0 -6
index 9e8636d..2308437 100644
@@ -351,9 +351,6 @@ early_idt_handler_common:
 	 */
 	cld
 
-	cmpl $2,(%rsp)		# X86_TRAP_NMI
-	je .Lis_nmi		# Ignore NMI
-
 	cmpl $2,early_recursion_flag(%rip)
 	jz  1f
 	incl early_recursion_flag(%rip)
@@ -422,9 +419,6 @@ early_idt_handler_common:
 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
 ENDPROC(early_idt_handler_common)
 
 	__INITDATA
arch/x86/mm/extable.c +5 -0
index 1366e06..4be0419 100644
@@ -1,5 +1,6 @@
 #include <linux/module.h>
 #include <asm/uaccess.h>
+#include <asm/traps.h>
 
 typedef bool (*ex_handler_t)(const struct exception_table_entry *,
 			    struct pt_regs *, int);
@@ -89,6 +90,10 @@ int __init early_fixup_exception(struct pt_regs *regs, int trapnr)
 	unsigned long new_ip;
 	ex_handler_t handler;
 
+	/* Ignore early NMIs. */
+	if (trapnr == X86_TRAP_NMI)
+		return 1;
+
 	e = search_exception_tables(regs->ip);
 	if (!e)
 		return 0;

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel

author maintainer
#7 lore raw

PATCH v5 2/9 x86/head: Move the early NMI fixup into C

In reply to Andy Lutomirski

C is nicer than asm.

---
 arch/x86/kernel/head_32.S | 7 -------
 arch/x86/kernel/head_64.S | 6 ------
 arch/x86/mm/extable.c     | 5 +++++
 3 files changed, 5 insertions(+), 13 deletions(-)
arch/x86/kernel/head_32.S +0 -7
index bef3e6c49b56..5e6ce845813a 100644
@@ -555,9 +555,6 @@ early_idt_handler_common:
 	 */
 	cld
 
-	cmpl $2,(%esp)		# X86_TRAP_NMI
-	je .Lis_nmi		# Ignore NMI
-
 	cmpl $2,%ss:early_recursion_flag
 	je hlt_loop
 	incl %ss:early_recursion_flag
@@ -636,10 +633,6 @@ early_idt_handler_common:
 hlt_loop:
 	hlt
 	jmp hlt_loop
-
-.Lis_nmi:
-	addl $8,%esp		/* drop vector number and error code */
-	iret
 ENDPROC(early_idt_handler_common)
 
 /* This is the default interrupt "handler" :-) */
arch/x86/kernel/head_64.S +0 -6
index f8d6dad41e8d..af87896b6a23 100644
@@ -354,9 +354,6 @@ early_idt_handler_common:
 	 */
 	cld
 
-	cmpl $2,(%rsp)		# X86_TRAP_NMI
-	je .Lis_nmi		# Ignore NMI
-
 	cmpl $2,early_recursion_flag(%rip)
 	jz  1f
 	incl early_recursion_flag(%rip)
@@ -425,9 +422,6 @@ early_idt_handler_common:
 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
 ENDPROC(early_idt_handler_common)
 
 	__INITDATA
arch/x86/mm/extable.c +5 -0
index 176e48de25d4..d6e4e6fb4002 100644
@@ -2,6 +2,7 @@
 #include <linux/spinlock.h>
 #include <linux/sort.h>
 #include <asm/uaccess.h>
+#include <asm/traps.h>
 
 typedef bool (*ex_handler_t)(const struct exception_table_entry *,
 			    struct pt_regs *, int);
@@ -96,6 +97,10 @@ int __init early_fixup_exception(struct pt_regs *regs, int trapnr)
 	unsigned long new_ip;
 	ex_handler_t handler;
 
+	/* Ignore early NMIs. */
+	if (trapnr == X86_TRAP_NMI)
+		return 1;
+
 	e = search_exception_tables(regs->ip);
 	if (!e)
 		return 0;
Signature · 7 lines
2.5.5


_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
author maintainer
#8 lore raw

PATCH v5 3/9 x86/head: Move early exception panic code into early_fixup_exception

In reply to Andy Lutomirski

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.

---
 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(-)
arch/x86/include/asm/uaccess.h +1 -1
index a3afb7259751..83fd2cf187d2 100644
@@ -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(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
arch/x86/kernel/head_32.S +5 -44

84 lines not on this page · raw message

arch/x86/kernel/head_64.S +2 -43

72 lines not on this page · raw message

arch/x86/mm/extable.c +24 -5
index d6e4e6fb4002..8997022abebc 100644
@@ -90,8 +90,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;
@@ -99,21 +101,38 @@ 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();
 }
 
 /*
Signature · 7 lines
2.5.5


_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
maintainer
#9 lore raw

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

Quoted 11 lines · Andy Lutomirski

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.

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

...

Quoted 26 lines
arch/x86/mm/extable.c +9 -3
@@ -99,21 +101,38 @@ 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;
 

arch/x86/mm/extable.c int __init early_fixup_exception(struct pt_regs *regs, int trapnr) · line 131

Quoted 10 lines
arch/x86/mm/extable.c +8 -1
 	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);

To make this even better, it could be something called early_show_regs() or so and be a simplified version of __show_regs() on both bitness but which calls early_printk().

This way you'll be able to get out stuff to the console as early as possible.

Btw, you don't need to dump rIP, CR2, etc in the PANIC message above since you're going to early_show_regs() anyway.

Signature · 9 lines
Regards/Gruss,
    Boris.

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

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
maintainer
#10 lore raw

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

In reply to Andy Lutomirski
Quoted 11 lines · Andy Lutomirski

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.

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

...

Quoted 26 lines
arch/x86/mm/extable.c +9 -3
@@ -99,21 +101,38 @@ 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;
 

arch/x86/mm/extable.c int __init early_fixup_exception(struct pt_regs *regs, int trapnr) · line 131

Quoted 10 lines
arch/x86/mm/extable.c +8 -1
 	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);

To make this even better, it could be something called early_show_regs() or so and be a simplified version of __show_regs() on both bitness but which calls early_printk().

This way you'll be able to get out stuff to the console as early as possible.

Btw, you don't need to dump rIP, CR2, etc in the PANIC message above since you're going to early_show_regs() anyway.

Signature · 4 lines
Regards/Gruss,
    Boris.

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

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

Quoted 56 lines · Borislav Petkov
Quoted 11 lines · Andy Lutomirski

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.

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

...

Quoted 26 lines
arch/x86/mm/extable.c +9 -3
@@ -99,21 +101,38 @@ 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;
 

arch/x86/mm/extable.c int __init early_fixup_exception(struct pt_regs *regs, int trapnr) · line 131

Quoted 10 lines
arch/x86/mm/extable.c +8 -1
      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);

To make this even better, it could be something called early_show_regs() or so and be a simplified version of __show_regs() on both bitness but which calls early_printk().

Quoted 5 lines

This way you'll be able to get out stuff to the console as early as possible.

Btw, you don't need to dump rIP, CR2, etc in the PANIC message above since you're going to early_show_regs() anyway.

Given that I this isn't really a regression with my patches (it probably never worked much better on 32-bit and the regs never would have shown at all on 64-bit), I propose a different approach: make printk work earlier. Something like:

if (early) {
    early_printk(args);
}

or early_vprintk or whatever.

If the cost of a branch mattered, this could be alternative-patched out later on, but that seems silly. I also bet that a more sensible fallback could be created in which printk would try to use an early console if there's no real console.

--Andy

maintainer
#12 lore raw

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

Quoted 3 lines · Andy Lutomirski

Given that I this isn't really a regression with my patches (it probably never worked much better on 32-bit and the regs never would have shown at all on 64-bit),

You're right. That thing calls printk *and* early_printk, WTF:

#ifdef CONFIG_EARLY_PRINTK

	call early_printk
	...

	call dump_stack

	...

	call __print_symbol

those last two call printk. Great.

Quoted 7 lines

I propose a different approach: make
printk work earlier. Something like:

if (early) {
    early_printk(args);
}
Quoted 6 lines

or early_vprintk or whatever.

If the cost of a branch mattered, this could be alternative-patched out later on, but that seems silly. I also bet that a more sensible fallback could be created in which printk would try to use an early console if there's no real console.

So how about this:

printk() does

	vprintk_func = this_cpu_read(printk_func);

and that's

DEFINE_PER_CPU(printk_func_t, printk_func) = vprintk_default

I guess we can make that function be early_printk-something and once printk is initialized, we overwrite it with vprintk_default.

Elegant and no need for if branches and alternatives.

Hmmm.

Signature · 9 lines
Regards/Gruss,
    Boris.

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

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
maintainer
#13 lore raw

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

In reply to Andy Lutomirski
Quoted 3 lines · Andy Lutomirski

Given that I this isn't really a regression with my patches (it probably never worked much better on 32-bit and the regs never would have shown at all on 64-bit),

You're right. That thing calls printk *and* early_printk, WTF:

#ifdef CONFIG_EARLY_PRINTK

	call early_printk
	...

	call dump_stack

	...

	call __print_symbol

those last two call printk. Great.

Quoted 7 lines

I propose a different approach: make
printk work earlier. Something like:

if (early) {
    early_printk(args);
}
Quoted 6 lines

or early_vprintk or whatever.

If the cost of a branch mattered, this could be alternative-patched out later on, but that seems silly. I also bet that a more sensible fallback could be created in which printk would try to use an early console if there's no real console.

So how about this:

printk() does

	vprintk_func = this_cpu_read(printk_func);

and that's

DEFINE_PER_CPU(printk_func_t, printk_func) = vprintk_default

I guess we can make that function be early_printk-something and once printk is initialized, we overwrite it with vprintk_default.

Elegant and no need for if branches and alternatives.

Hmmm.

Signature · 4 lines
Regards/Gruss,
    Boris.

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

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

[cc Jan Kara]

Quoted 42 lines · Borislav Petkov
Quoted 3 lines · Andy Lutomirski

Given that I this isn't really a regression with my patches (it probably never worked much better on 32-bit and the regs never would have shown at all on 64-bit),

You're right. That thing calls printk *and* early_printk, WTF:

#ifdef CONFIG_EARLY_PRINTK

        call early_printk
        ...

        call dump_stack

        ...

        call __print_symbol

those last two call printk. Great.

Quoted 7 lines

I propose a different approach: make
printk work earlier. Something like:

if (early) {
    early_printk(args);
}
Quoted 6 lines

or early_vprintk or whatever.

If the cost of a branch mattered, this could be alternative-patched out later on, but that seems silly. I also bet that a more sensible fallback could be created in which printk would try to use an early console if there's no real console.

So how about this:

printk() does

        vprintk_func = this_cpu_read(printk_func);

and that's

Quoted 8 lines

DEFINE_PER_CPU(printk_func_t, printk_func) = vprintk_default

I guess we can make that function be early_printk-something and once printk is initialized, we overwrite it with vprintk_default.

Elegant and no need for if branches and alternatives.

Hmmm.

Jan, IIRC you were looking at printk recently-ish. Any thoughts here?

--Andy

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel

#15 lore raw

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

In reply to Borislav Petkov

[cc Jan Kara]

Quoted 42 lines · Borislav Petkov
Quoted 3 lines · Andy Lutomirski

Given that I this isn't really a regression with my patches (it probably never worked much better on 32-bit and the regs never would have shown at all on 64-bit),

You're right. That thing calls printk *and* early_printk, WTF:

#ifdef CONFIG_EARLY_PRINTK

        call early_printk
        ...

        call dump_stack

        ...

        call __print_symbol

those last two call printk. Great.

Quoted 7 lines

I propose a different approach: make
printk work earlier. Something like:

if (early) {
    early_printk(args);
}
Quoted 6 lines

or early_vprintk or whatever.

If the cost of a branch mattered, this could be alternative-patched out later on, but that seems silly. I also bet that a more sensible fallback could be created in which printk would try to use an early console if there's no real console.

So how about this:

printk() does

        vprintk_func = this_cpu_read(printk_func);

and that's

Quoted 8 lines

DEFINE_PER_CPU(printk_func_t, printk_func) = vprintk_default

I guess we can make that function be early_printk-something and once printk is initialized, we overwrite it with vprintk_default.

Elegant and no need for if branches and alternatives.

Hmmm.

Jan, IIRC you were looking at printk recently-ish. Any thoughts here?

--Andy

#16 lore raw

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

Quoted 47 lines · Andy Lutomirski

[cc Jan Kara]

Quoted 44 lines · Borislav Petkov
Quoted 3 lines · Andy Lutomirski

Given that I this isn't really a regression with my patches (it probably never worked much better on 32-bit and the regs never would have shown at all on 64-bit),

You're right. That thing calls printk *and* early_printk, WTF:

#ifdef CONFIG_EARLY_PRINTK

        call early_printk
        ...

        call dump_stack

        ...

        call __print_symbol

those last two call printk. Great.

Quoted 7 lines

I propose a different approach: make
printk work earlier. Something like:

if (early) {
    early_printk(args);
}
Quoted 6 lines

or early_vprintk or whatever.

If the cost of a branch mattered, this could be alternative-patched out later on, but that seems silly. I also bet that a more sensible fallback could be created in which printk would try to use an early console if there's no real console.

So how about this:

printk() does

        vprintk_func = this_cpu_read(printk_func);

and that's

DEFINE_PER_CPU(printk_func_t, printk_func) = vprintk_default

Quoted 8 lines
Quoted 6 lines

I guess we can make that function be early_printk-something and once printk is initialized, we overwrite it with vprintk_default.

Elegant and no need for if branches and alternatives.

Hmmm.

Jan, IIRC you were looking at printk recently-ish. Any thoughts here?

Sounds like a good idea to me. I've also consulted this with Petr Mladek (added to CC) who is using printk_func per-cpu variable in his printk-from-NMI patches and he also doesn't see a problem with this.

I was just wondering about one thing - this way we add more early printks if I understand your intention right. Are we guaranteed that they happen only from a single CPU? Because currently there is no locking in early_printk() and thus we can end up writing to early console several messages in parallel from different CPUs. Not sure what's going to happen in that case...

Honza

Signature · 2 lines
Jan Kara <[email protected]>
SUSE Labs, CR
maintainer
#17 lore raw

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

Quoted 3 lines · Jan Kara

Sounds like a good idea to me. I've also consulted this with Petr Mladek (added to CC) who is using printk_func per-cpu variable in his printk-from-NMI patches and he also doesn't see a problem with this.

There's a few printk() variants that do not go through this; which means they're broken for a number of cases, including the kdb printk redirection, this NMI stuff etc.

Quoted 6 lines

I was just wondering about one thing - this way we add more early printks if I understand your intention right. Are we guaranteed that they happen only from a single CPU? Because currently there is no locking in early_printk() and thus we can end up writing to early console several messages in parallel from different CPUs. Not sure what's going to happen in that case...

You get lovely per char interleaving on you serial line ;-)

What I've done in the past was something like the below; that way you only get the normal task->softirq->irq->nmi nesting, which is mostly decipherable.

kernel/printk/printk.c +20 -1
index bfbf284e4218..c4c3269ff104 100644
@@ -1907,17 +1907,36 @@ struct console *early_console;
 asmlinkage __visible void early_printk(const char *fmt, ...)
 {
 	va_list ap;
+	static int print_cpu = -1;
 	char buf[512];
-	int n;
+	int n, cpu;
 
 	if (!early_console)
 		return;
 
+	preempt_disable();
+	cpu = raw_smp_processor_id();
+	for (;;) {
+		if (READ_ONCE(print_cpu) == cpu)
+			break;
+
+		if (READ_ONCE(print_cpu) == -1 &&
+		    cmpxchg(&print_cpu, -1, cpu) == -1) {
+			cpu = -1;
+			break;
+		}
+
+		cpu_relax();
+	}
+
 	va_start(ap, fmt);
 	n = vscnprintf(buf, sizeof(buf), fmt, ap);
 	va_end(ap);
 
 	early_console->write(early_console, buf, n);
+
+	smp_store_release(&print_cpu, cpu);
+	preempt_enable();
 }
 #endif
 
maintainer
#18 lore raw

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

In reply to Jan Kara
Quoted 3 lines · Jan Kara

Sounds like a good idea to me. I've also consulted this with Petr Mladek (added to CC) who is using printk_func per-cpu variable in his printk-from-NMI patches and he also doesn't see a problem with this.

There's a few printk() variants that do not go through this; which means they're broken for a number of cases, including the kdb printk redirection, this NMI stuff etc.

Quoted 6 lines

I was just wondering about one thing - this way we add more early printks if I understand your intention right. Are we guaranteed that they happen only from a single CPU? Because currently there is no locking in early_printk() and thus we can end up writing to early console several messages in parallel from different CPUs. Not sure what's going to happen in that case...

You get lovely per char interleaving on you serial line ;-)

What I've done in the past was something like the below; that way you only get the normal task->softirq->irq->nmi nesting, which is mostly decipherable.

kernel/printk/printk.c +20 -1
index bfbf284e4218..c4c3269ff104 100644
@@ -1907,17 +1907,36 @@ struct console *early_console;
 asmlinkage __visible void early_printk(const char *fmt, ...)
 {
 	va_list ap;
+	static int print_cpu = -1;
 	char buf[512];
-	int n;
+	int n, cpu;
 
 	if (!early_console)
 		return;
 
+	preempt_disable();
+	cpu = raw_smp_processor_id();
+	for (;;) {
+		if (READ_ONCE(print_cpu) == cpu)
+			break;
+
+		if (READ_ONCE(print_cpu) == -1 &&
+		    cmpxchg(&print_cpu, -1, cpu) == -1) {
+			cpu = -1;
+			break;
+		}
+
+		cpu_relax();
+	}
+
 	va_start(ap, fmt);
 	n = vscnprintf(buf, sizeof(buf), fmt, ap);
 	va_end(ap);
 
 	early_console->write(early_console, buf, n);
+
+	smp_store_release(&print_cpu, cpu);
+	preempt_enable();
 }
 #endif
 

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel

#19 lore raw

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

In reply to Jan Kara
Quoted 62 lines · Jan Kara
Quoted 47 lines · Andy Lutomirski

[cc Jan Kara]

Quoted 44 lines · Borislav Petkov
Quoted 3 lines · Andy Lutomirski

Given that I this isn't really a regression with my patches (it probably never worked much better on 32-bit and the regs never would have shown at all on 64-bit),

You're right. That thing calls printk *and* early_printk, WTF:

#ifdef CONFIG_EARLY_PRINTK

        call early_printk
        ...

        call dump_stack

        ...

        call __print_symbol

those last two call printk. Great.

Quoted 7 lines

I propose a different approach: make
printk work earlier. Something like:

if (early) {
    early_printk(args);
}
Quoted 6 lines

or early_vprintk or whatever.

If the cost of a branch mattered, this could be alternative-patched out later on, but that seems silly. I also bet that a more sensible fallback could be created in which printk would try to use an early console if there's no real console.

So how about this:

printk() does

        vprintk_func = this_cpu_read(printk_func);

and that's

DEFINE_PER_CPU(printk_func_t, printk_func) = vprintk_default

Quoted 8 lines
Quoted 6 lines

I guess we can make that function be early_printk-something and once printk is initialized, we overwrite it with vprintk_default.

Elegant and no need for if branches and alternatives.

Hmmm.

Jan, IIRC you were looking at printk recently-ish. Any thoughts here?

Sounds like a good idea to me. I've also consulted this with Petr Mladek (added to CC) who is using printk_func per-cpu variable in his printk-from-NMI patches and he also doesn't see a problem with this.

Quoted 6 lines

I was just wondering about one thing - this way we add more early printks if I understand your intention right. Are we guaranteed that they happen only from a single CPU? Because currently there is no locking in early_printk() and thus we can end up writing to early console several messages in parallel from different CPUs. Not sure what's going to happen in that case...

Adding locking would be easy enough, wouldn't it?

But do any platforms really boot a second CPU before switching to real printk? Given that I see all the smpboot stuff in dmesg, I guess real printk happens first. I admit I haven't actually checked.

--Andy

Quoted 5 lines

Honza
--
Jan Kara <[email protected]>
SUSE Labs, CR

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel

#20 lore raw

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

In reply to Jan Kara
Quoted 62 lines · Jan Kara
Quoted 47 lines · Andy Lutomirski

[cc Jan Kara]

Quoted 44 lines · Borislav Petkov
Quoted 3 lines · Andy Lutomirski

Given that I this isn't really a regression with my patches (it probably never worked much better on 32-bit and the regs never would have shown at all on 64-bit),

You're right. That thing calls printk *and* early_printk, WTF:

#ifdef CONFIG_EARLY_PRINTK

        call early_printk
        ...

        call dump_stack

        ...

        call __print_symbol

those last two call printk. Great.

Quoted 7 lines

I propose a different approach: make
printk work earlier. Something like:

if (early) {
    early_printk(args);
}
Quoted 6 lines

or early_vprintk or whatever.

If the cost of a branch mattered, this could be alternative-patched out later on, but that seems silly. I also bet that a more sensible fallback could be created in which printk would try to use an early console if there's no real console.

So how about this:

printk() does

        vprintk_func = this_cpu_read(printk_func);

and that's

DEFINE_PER_CPU(printk_func_t, printk_func) = vprintk_default

Quoted 8 lines
Quoted 6 lines

I guess we can make that function be early_printk-something and once printk is initialized, we overwrite it with vprintk_default.

Elegant and no need for if branches and alternatives.

Hmmm.

Jan, IIRC you were looking at printk recently-ish. Any thoughts here?

Sounds like a good idea to me. I've also consulted this with Petr Mladek (added to CC) who is using printk_func per-cpu variable in his printk-from-NMI patches and he also doesn't see a problem with this.

Quoted 6 lines

I was just wondering about one thing - this way we add more early printks if I understand your intention right. Are we guaranteed that they happen only from a single CPU? Because currently there is no locking in early_printk() and thus we can end up writing to early console several messages in parallel from different CPUs. Not sure what's going to happen in that case...

Adding locking would be easy enough, wouldn't it?

But do any platforms really boot a second CPU before switching to real printk? Given that I see all the smpboot stuff in dmesg, I guess real printk happens first. I admit I haven't actually checked.

--Andy

Quoted 5 lines

Honza
--
Jan Kara <[email protected]>
SUSE Labs, CR

#21 lore raw

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

Quoted 6 lines · Andy Lutomirski

Adding locking would be easy enough, wouldn't it?

But do any platforms really boot a second CPU before switching to real printk? Given that I see all the smpboot stuff in dmesg, I guess real printk happens first. I admit I haven't actually checked.

adding locking also makes things more fragile in terms of getting the last thing out before you go down in flaming death....

until it's a proven problem, this early, get the message out at all is more important than getting it out perfectly, sometimes.

#22 lore raw

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

In reply to Andy Lutomirski
Quoted 6 lines · Andy Lutomirski

Adding locking would be easy enough, wouldn't it?

But do any platforms really boot a second CPU before switching to real printk? Given that I see all the smpboot stuff in dmesg, I guess real printk happens first. I admit I haven't actually checked.

adding locking also makes things more fragile in terms of getting the last thing out before you go down in flaming death....

until it's a proven problem, this early, get the message out at all is more important than getting it out perfectly, sometimes.

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel

maintainer
#23 lore raw

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

In reply to Andy Lutomirski
Quoted 1 line · Andy Lutomirski

Adding locking would be easy enough, wouldn't it?

See patch in this thread..

Quoted 2 lines

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

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel

maintainer
#24 lore raw

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

In reply to Andy Lutomirski
Quoted 1 line · Andy Lutomirski

Adding locking would be easy enough, wouldn't it?

See patch in this thread..

Quoted 2 lines

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

maintainer
#25 lore raw

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

Quoted 10 lines · Peter Zijlstra
Quoted 1 line · Andy Lutomirski

Adding locking would be easy enough, wouldn't it?

See patch in this thread..

Quoted 2 lines

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.

---

arch/x86/kernel/head64.c +11 -0
index 1f4422d5c8d0..ad534226653b 100644
@@ -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.
arch/x86/kernel/setup.c +1 -0
index 2367ae07eb76..998d6c675549 100644
@@ -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
 
include/linux/printk.h +1 -0
index 9ccbdf2c1453..97df81c97b2f 100644
@@ -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)
Signature · 9 lines
Regards/Gruss,
    Boris.

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

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
maintainer
#26 lore raw

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

In reply to Peter Zijlstra
Quoted 10 lines · Peter Zijlstra
Quoted 1 line · Andy Lutomirski

Adding locking would be easy enough, wouldn't it?

See patch in this thread..

Quoted 2 lines

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.

---

arch/x86/kernel/head64.c +11 -0
index 1f4422d5c8d0..ad534226653b 100644
@@ -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.
arch/x86/kernel/setup.c +1 -0
index 2367ae07eb76..998d6c675549 100644
@@ -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
 
include/linux/printk.h +1 -0
index 9ccbdf2c1453..97df81c97b2f 100644
@@ -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)
Signature · 4 lines
Regards/Gruss,
    Boris.

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

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

Quoted 12 lines · Borislav Petkov
Quoted 10 lines · Peter Zijlstra
Quoted 1 line · Andy Lutomirski

Adding locking would be easy enough, wouldn't it?

See patch in this thread..

Quoted 2 lines

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

Quoted 9 lines

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

maintainer
#28 lore raw

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

Quoted 2 lines · Andy Lutomirski

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...

Signature · 4 lines
Regards/Gruss,
    Boris.

ECO tip #101: Trim your mails when you reply.
maintainer
#29 lore raw

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

In reply to Andy Lutomirski
Quoted 2 lines · Andy Lutomirski

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...

Signature · 9 lines
Regards/Gruss,
    Boris.

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

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
#30 lore raw

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

In reply to Borislav Petkov
Quoted 12 lines · Borislav Petkov
Quoted 10 lines · Peter Zijlstra
Quoted 1 line · Andy Lutomirski

Adding locking would be easy enough, wouldn't it?

See patch in this thread..

Quoted 2 lines

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

Quoted 9 lines

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

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel

#31 lore raw

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

In reply to Andy Lutomirski
Quoted 47 lines · Andy Lutomirski

[cc Jan Kara]

Quoted 44 lines · Borislav Petkov
Quoted 3 lines · Andy Lutomirski

Given that I this isn't really a regression with my patches (it probably never worked much better on 32-bit and the regs never would have shown at all on 64-bit),

You're right. That thing calls printk *and* early_printk, WTF:

#ifdef CONFIG_EARLY_PRINTK

        call early_printk
        ...

        call dump_stack

        ...

        call __print_symbol

those last two call printk. Great.

Quoted 7 lines

I propose a different approach: make
printk work earlier. Something like:

if (early) {
    early_printk(args);
}
Quoted 6 lines

or early_vprintk or whatever.

If the cost of a branch mattered, this could be alternative-patched out later on, but that seems silly. I also bet that a more sensible fallback could be created in which printk would try to use an early console if there's no real console.

So how about this:

printk() does

        vprintk_func = this_cpu_read(printk_func);

and that's

DEFINE_PER_CPU(printk_func_t, printk_func) = vprintk_default

Quoted 8 lines
Quoted 6 lines

I guess we can make that function be early_printk-something and once printk is initialized, we overwrite it with vprintk_default.

Elegant and no need for if branches and alternatives.

Hmmm.

Jan, IIRC you were looking at printk recently-ish. Any thoughts here?

Sounds like a good idea to me. I've also consulted this with Petr Mladek (added to CC) who is using printk_func per-cpu variable in his printk-from-NMI patches and he also doesn't see a problem with this.

I was just wondering about one thing - this way we add more early printks if I understand your intention right. Are we guaranteed that they happen only from a single CPU? Because currently there is no locking in early_printk() and thus we can end up writing to early console several messages in parallel from different CPUs. Not sure what's going to happen in that case...

Honza

Signature · 7 lines
Jan Kara <[email protected]>
SUSE Labs, CR

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
#32 lore raw

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

In reply to Borislav Petkov
Quoted 56 lines · Borislav Petkov
Quoted 11 lines · Andy Lutomirski

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.

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

...

Quoted 26 lines
arch/x86/mm/extable.c +9 -3
@@ -99,21 +101,38 @@ 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;
 

arch/x86/mm/extable.c int __init early_fixup_exception(struct pt_regs *regs, int trapnr) · line 131

Quoted 10 lines
arch/x86/mm/extable.c +8 -1
      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);

To make this even better, it could be something called early_show_regs() or so and be a simplified version of __show_regs() on both bitness but which calls early_printk().

Quoted 5 lines

This way you'll be able to get out stuff to the console as early as possible.

Btw, you don't need to dump rIP, CR2, etc in the PANIC message above since you're going to early_show_regs() anyway.

Given that I this isn't really a regression with my patches (it probably never worked much better on 32-bit and the regs never would have shown at all on 64-bit), I propose a different approach: make printk work earlier. Something like:

if (early) {
    early_printk(args);
}

or early_vprintk or whatever.

If the cost of a branch mattered, this could be alternative-patched out later on, but that seems silly. I also bet that a more sensible fallback could be created in which printk would try to use an early console if there's no real console.

--Andy

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel

#33 lore raw

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

In reply to Andy Lutomirski
x86/head: Move early exception panic code into early_fixup_exception()
Commit-ID:  0e861fbb5bda79b871341ef2a9a8059765cbe8a4
Gitweb:     http://git.kernel.org/tip/0e861fbb5bda79b871341ef2a9a8059765cbe8a4
Author:     Andy Lutomirski <[email protected]>
AuthorDate: Sat, 2 Apr 2016 07:01:34 -0700
Committer:  Ingo Molnar <[email protected]>
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.

---
 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(-)
arch/x86/include/asm/uaccess.h +1 -1
index b6fb311..d794fd1 100644
@@ -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
arch/x86/kernel/head_32.S +5 -44

84 lines not on this page · raw message

arch/x86/kernel/head_64.S +2 -43

72 lines not on this page · raw message

arch/x86/mm/extable.c +24 -5
index 4be0419..da442f3 100644
@@ -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();
 }
#34 lore raw

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

In reply to Andy Lutomirski
x86/head: Move early exception panic code into early_fixup_exception()
Commit-ID:  0e861fbb5bda79b871341ef2a9a8059765cbe8a4
Gitweb:     http://git.kernel.org/tip/0e861fbb5bda79b871341ef2a9a8059765cbe8a4
Author:     Andy Lutomirski <[email protected]>
AuthorDate: Sat, 2 Apr 2016 07:01:34 -0700
Committer:  Ingo Molnar <[email protected]>
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.

---
 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(-)
arch/x86/include/asm/uaccess.h +1 -1
index b6fb311..d794fd1 100644
@@ -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
arch/x86/kernel/head_32.S +5 -44

84 lines not on this page · raw message

arch/x86/kernel/head_64.S +2 -43

72 lines not on this page · raw message

arch/x86/mm/extable.c +24 -5
index 4be0419..da442f3 100644
@@ -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();
 }

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel

author maintainer
#35 lore raw

PATCH v5 4/9 x86/traps: Enable all exception handler callbacks early

In reply to Andy Lutomirski

Now that early_fixup_exception has pt_regs, we can just call fixup_exception from it. This will make fancy exception handlers work early.

---
 arch/x86/mm/extable.c | 19 ++-----------------
 1 file changed, 2 insertions(+), 17 deletions(-)
arch/x86/mm/extable.c +2 -17
index 8997022abebc..50dfe438bd91 100644
@@ -95,10 +95,6 @@ extern unsigned int early_recursion_flag;
 /* Restricted version used during very early boot */
 void __init early_fixup_exception(struct pt_regs *regs, int trapnr)
 {
-	const struct exception_table_entry *e;
-	unsigned long new_ip;
-	ex_handler_t handler;
-
 	/* Ignore early NMIs. */
 	if (trapnr == X86_TRAP_NMI)
 		return;
@@ -109,19 +105,8 @@ void __init early_fixup_exception(struct pt_regs *regs, int trapnr)
 	if (regs->cs != __KERNEL_CS)
 		goto fail;
 
-	e = search_exception_tables(regs->ip);
-	if (!e)
-		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)
-		goto fail;
-
-	regs->ip = new_ip;
-	return;
+	if (fixup_exception(regs, trapnr))
+		return;
 
 fail:
 	early_printk("PANIC: early exception 0x%02x IP %lx:%lx error %lx cr2 0x%lx\n",
Signature · 1 line
2.5.5
maintainer
#36 lore raw

Re: [PATCH v5 4/9] x86/traps: Enable all exception handler callbacks early

Quoted 28 lines · Andy Lutomirski

Now that early_fixup_exception has pt_regs, we can just call fixup_exception from it. This will make fancy exception handlers work early.

---
 arch/x86/mm/extable.c | 19 ++-----------------
 1 file changed, 2 insertions(+), 17 deletions(-)
arch/x86/mm/extable.c +0 -4
index 8997022abebc..50dfe438bd91 100644
@@ -95,10 +95,6 @@ extern unsigned int early_recursion_flag;
 /* Restricted version used during very early boot */
 void __init early_fixup_exception(struct pt_regs *regs, int trapnr)
 {
-	const struct exception_table_entry *e;
-	unsigned long new_ip;
-	ex_handler_t handler;
-
 	/* Ignore early NMIs. */
 	if (trapnr == X86_TRAP_NMI)
 		return;
@@ -109,19 +105,8 @@ void __init early_fixup_exception(struct pt_regs *regs, int trapnr)
 	if (regs->cs != __KERNEL_CS)
 		goto fail;
 

arch/x86/mm/extable.c void __init early_fixup_exception(struct pt_regs *regs, int trapnr) · line 121

Quoted 10 lines
arch/x86/mm/extable.c +0 -10
-	e = search_exception_tables(regs->ip);
-	if (!e)
-		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)
-		goto fail;

Hold on, what happened to the uaccess handling not being supported during early boot?

So before Tony changed it, the original code had:

/* Restricted version used during very early boot */ int __init early_fixup_exception(unsigned long *ip) {

...
- if (fixup->fixup - fixup->insn >= 0x7ffffff0 - 4) {
- /* uaccess handling not supported during early boot */
- return 0;
- }

I'm guessing that wasn't supported early, probably because some stuff wasn't initialized yet. Our normal, late fixup is by doing:

        current_thread_info()->uaccess_err = 1;

and I'm assuming we can't do that early. current_thread_info is probably not setup yet...

arch/x86/mm/extable.c void __init early_fixup_exception(struct pt_regs *regs, int trapnr) · line 109

Quoted 5 lines
arch/x86/mm/extable.c +2 -3
-
-	regs->ip = new_ip;
-	return;
+	if (fixup_exception(regs, trapnr))
+		return;

So why can we do it now, all of a sudden?

/me is scratching head.

Signature · 9 lines
Regards/Gruss,
    Boris.

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

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
maintainer
#37 lore raw

Re: [PATCH v5 4/9] x86/traps: Enable all exception handler callbacks early

In reply to Andy Lutomirski
Quoted 28 lines · Andy Lutomirski

Now that early_fixup_exception has pt_regs, we can just call fixup_exception from it. This will make fancy exception handlers work early.

---
 arch/x86/mm/extable.c | 19 ++-----------------
 1 file changed, 2 insertions(+), 17 deletions(-)
arch/x86/mm/extable.c +0 -4
index 8997022abebc..50dfe438bd91 100644
@@ -95,10 +95,6 @@ extern unsigned int early_recursion_flag;
 /* Restricted version used during very early boot */
 void __init early_fixup_exception(struct pt_regs *regs, int trapnr)
 {
-	const struct exception_table_entry *e;
-	unsigned long new_ip;
-	ex_handler_t handler;
-
 	/* Ignore early NMIs. */
 	if (trapnr == X86_TRAP_NMI)
 		return;
@@ -109,19 +105,8 @@ void __init early_fixup_exception(struct pt_regs *regs, int trapnr)
 	if (regs->cs != __KERNEL_CS)
 		goto fail;
 

arch/x86/mm/extable.c void __init early_fixup_exception(struct pt_regs *regs, int trapnr) · line 121

Quoted 10 lines
arch/x86/mm/extable.c +0 -10
-	e = search_exception_tables(regs->ip);
-	if (!e)
-		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)
-		goto fail;

Hold on, what happened to the uaccess handling not being supported during early boot?

So before Tony changed it, the original code had:

/* Restricted version used during very early boot */ int __init early_fixup_exception(unsigned long *ip) {

...
- if (fixup->fixup - fixup->insn >= 0x7ffffff0 - 4) {
- /* uaccess handling not supported during early boot */
- return 0;
- }

I'm guessing that wasn't supported early, probably because some stuff wasn't initialized yet. Our normal, late fixup is by doing:

        current_thread_info()->uaccess_err = 1;

and I'm assuming we can't do that early. current_thread_info is probably not setup yet...

arch/x86/mm/extable.c void __init early_fixup_exception(struct pt_regs *regs, int trapnr) · line 109

Quoted 5 lines
arch/x86/mm/extable.c +2 -3
-
-	regs->ip = new_ip;
-	return;
+	if (fixup_exception(regs, trapnr))
+		return;

So why can we do it now, all of a sudden?

/me is scratching head.

Signature · 4 lines
Regards/Gruss,
    Boris.

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

Re: [PATCH v5 4/9] x86/traps: Enable all exception handler callbacks early

Quoted 64 lines · Borislav Petkov
Quoted 28 lines · Andy Lutomirski

Now that early_fixup_exception has pt_regs, we can just call fixup_exception from it. This will make fancy exception handlers work early.

---
 arch/x86/mm/extable.c | 19 ++-----------------
 1 file changed, 2 insertions(+), 17 deletions(-)
arch/x86/mm/extable.c +0 -4
index 8997022abebc..50dfe438bd91 100644
@@ -95,10 +95,6 @@ extern unsigned int early_recursion_flag;
 /* Restricted version used during very early boot */
 void __init early_fixup_exception(struct pt_regs *regs, int trapnr)
 {
-     const struct exception_table_entry *e;
-     unsigned long new_ip;
-     ex_handler_t handler;
-
      /* Ignore early NMIs. */
      if (trapnr == X86_TRAP_NMI)
              return;
@@ -109,19 +105,8 @@ void __init early_fixup_exception(struct pt_regs *regs, int trapnr)
      if (regs->cs != __KERNEL_CS)
              goto fail;
 

arch/x86/mm/extable.c void __init early_fixup_exception(struct pt_regs *regs, int trapnr) · line 121

Quoted 10 lines
arch/x86/mm/extable.c +0 -10
-     e = search_exception_tables(regs->ip);
-     if (!e)
-             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)
-             goto fail;

Hold on, what happened to the uaccess handling not being supported during early boot?

So before Tony changed it, the original code had:

/* Restricted version used during very early boot */ int __init early_fixup_exception(unsigned long *ip) {

...

(quoted diff) +0 -4
-               if (fixup->fixup - fixup->insn >= 0x7ffffff0 - 4) {
-                       /* uaccess handling not supported during early boot */
-                       return 0;
-               }

I'm guessing that wasn't supported early, probably because some stuff wasn't initialized yet. Our normal, late fixup is by doing:

        current_thread_info()->uaccess_err = 1;

and I'm assuming we can't do that early. current_thread_info is probably not setup yet...

Quoted 7 lines

arch/x86/mm/extable.c void __init early_fixup_exception(struct pt_regs *regs, int trapnr) · line 109

Quoted 5 lines
arch/x86/mm/extable.c +2 -3
-
-     regs->ip = new_ip;
-     return;
+     if (fixup_exception(regs, trapnr))
+             return;

So why can we do it now, all of a sudden?

I have no idea why it was explicitly unsupported, but I'm guessing it was just to avoid duplicating the code. Early "ext" uaccess failures are certainly not going to work, but I don't think this is a problem -- there's no userspace before trap_init runs, so how exactly is an "ext" uaccess going to happen in the first place?

In any event, if it did happen in older kernels, it would have immediately panicked due to that code. At least with my code it just might manage to EFAULT correctly.

--Andy

maintainer
#39 lore raw

Re: [PATCH v5 4/9] x86/traps: Enable all exception handler callbacks early

Quoted 9 lines · Andy Lutomirski

I have no idea why it was explicitly unsupported, but I'm guessing it was just to avoid duplicating the code. Early "ext" uaccess failures are certainly not going to work, but I don't think this is a problem -- there's no userspace before trap_init runs, so how exactly is an "ext" uaccess going to happen in the first place?

In any event, if it did happen in older kernels, it would have immediately panicked due to that code. At least with my code it just might manage to EFAULT correctly.

Yeah, I was wondering what that early thing meant.

Linus or tip guys probably remember what this whole deal with early uaccess was about. I'll try to do some git archeology tomorrow.

In any event, it would be a good idea IMO, to hold that situation down in a comment somewhere. Once we've figured it out...

Signature · 4 lines
Regards/Gruss,
    Boris.

ECO tip #101: Trim your mails when you reply.
maintainer
#40 lore raw

Re: [PATCH v5 4/9] x86/traps: Enable all exception handler callbacks early

Quoted 7 lines · Borislav Petkov
Quoted 6 lines · Andy Lutomirski

I have no idea why it was explicitly unsupported, but I'm guessing it was just to avoid duplicating the code. Early "ext" uaccess failures are certainly not going to work, but I don't think this is a problem -- there's no userspace before trap_init runs, so how exactly is an "ext" uaccess going to happen in the first place?

Quoted 8 lines
Quoted 3 lines

In any event, if it did happen in older kernels, it would have immediately panicked due to that code. At least with my code it just might manage to EFAULT correctly.

Yeah, I was wondering what that early thing meant.

Linus or tip guys probably remember what this whole deal with early uaccess was about. I'll try to do some git archeology tomorrow.

Yep, just as I suspected:

6a1ea279c210 ("x86, extable: Add early_fixup_exception()")

Apparently, thread_info might not have been setup yet. I'm guessing the intention behind this no-uaccess-fixup-early is to not even attempt any fixup due to stuff *probably* not initialized yet and so the safer thing would be to panic instead.

I'm wondering whether making it try to EFAULT correctly is the right thing to do... We're certainly more conservative if we panic and not allow some silently failed attempt at recovery which looks successful, to continue.

hpa, thoughts?

Signature · 9 lines
Regards/Gruss,
    Boris.

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

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
maintainer
#41 lore raw

Re: [PATCH v5 4/9] x86/traps: Enable all exception handler callbacks early

In reply to Borislav Petkov
Quoted 7 lines · Borislav Petkov
Quoted 6 lines · Andy Lutomirski

I have no idea why it was explicitly unsupported, but I'm guessing it was just to avoid duplicating the code. Early "ext" uaccess failures are certainly not going to work, but I don't think this is a problem -- there's no userspace before trap_init runs, so how exactly is an "ext" uaccess going to happen in the first place?

Quoted 8 lines
Quoted 3 lines

In any event, if it did happen in older kernels, it would have immediately panicked due to that code. At least with my code it just might manage to EFAULT correctly.

Yeah, I was wondering what that early thing meant.

Linus or tip guys probably remember what this whole deal with early uaccess was about. I'll try to do some git archeology tomorrow.

Yep, just as I suspected:

6a1ea279c210 ("x86, extable: Add early_fixup_exception()")

Apparently, thread_info might not have been setup yet. I'm guessing the intention behind this no-uaccess-fixup-early is to not even attempt any fixup due to stuff *probably* not initialized yet and so the safer thing would be to panic instead.

I'm wondering whether making it try to EFAULT correctly is the right thing to do... We're certainly more conservative if we panic and not allow some silently failed attempt at recovery which looks successful, to continue.

hpa, thoughts?

Signature · 4 lines
Regards/Gruss,
    Boris.

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

Re: [PATCH v5 4/9] x86/traps: Enable all exception handler callbacks early

Quoted 26 lines · Borislav Petkov
Quoted 7 lines · Borislav Petkov
Quoted 6 lines · Andy Lutomirski

I have no idea why it was explicitly unsupported, but I'm guessing it was just to avoid duplicating the code. Early "ext" uaccess failures are certainly not going to work, but I don't think this is a problem -- there's no userspace before trap_init runs, so how exactly is an "ext" uaccess going to happen in the first place?

Quoted 8 lines
Quoted 3 lines

In any event, if it did happen in older kernels, it would have immediately panicked due to that code. At least with my code it just might manage to EFAULT correctly.

Yeah, I was wondering what that early thing meant.

Linus or tip guys probably remember what this whole deal with early uaccess was about. I'll try to do some git archeology tomorrow.

Yep, just as I suspected:

6a1ea279c210 ("x86, extable: Add early_fixup_exception()")

Apparently, thread_info might not have been setup yet. I'm guessing the intention behind this no-uaccess-fixup-early is to not even attempt any fixup due to stuff *probably* not initialized yet and so the safer thing would be to panic instead.

Quoted 6 lines

I'm wondering whether making it try to EFAULT correctly is the right thing to do... We're certainly more conservative if we panic and not allow some silently failed attempt at recovery which looks successful, to continue.

hpa, thoughts?

I don't think this matters much. There aren't many users of this mechanism in the tree:

./arch/x86/kernel/signal.c:    get_user_try {
./arch/x86/kernel/signal.c:    put_user_try {
./arch/x86/kernel/signal.c:    put_user_try {
./arch/x86/kernel/signal.c:    put_user_try {
./arch/x86/kernel/signal.c:    put_user_try {

./arch/x86/kernel/signal_compat.c: put_user_try {
./arch/x86/kernel/signal_compat.c: get_user_try {
./arch/x86/kernel/vm86_32.c: put_user_try {
./arch/x86/kernel/vm86_32.c: get_user_try {

./arch/x86/ia32/ia32_signal.c:    get_user_try {
./arch/x86/ia32/ia32_signal.c:    put_user_try {
./arch/x86/ia32/ia32_signal.c:    put_user_try {
./arch/x86/ia32/ia32_signal.c:    put_user_try {

./arch/x86/include/asm/uaccess.h: * {get|put}_user_try and catch ./arch/x86/include/asm/uaccess.h: * get_user_try {
./arch/x86/include/asm/uaccess.h:#define get_user_try uaccess_try
./arch/x86/include/asm/uaccess.h:#define put_user_try uaccess_try

I don't see how we could get to that code in the first place without current_thread_info() working.

If we can ever convince gcc to do jump labels properly for uaccess, it would probably be better to just delete all that code.

--Andy

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel

#43 lore raw

Re: [PATCH v5 4/9] x86/traps: Enable all exception handler callbacks early

In reply to Borislav Petkov
Quoted 26 lines · Borislav Petkov
Quoted 7 lines · Borislav Petkov
Quoted 6 lines · Andy Lutomirski

I have no idea why it was explicitly unsupported, but I'm guessing it was just to avoid duplicating the code. Early "ext" uaccess failures are certainly not going to work, but I don't think this is a problem -- there's no userspace before trap_init runs, so how exactly is an "ext" uaccess going to happen in the first place?

Quoted 8 lines
Quoted 3 lines

In any event, if it did happen in older kernels, it would have immediately panicked due to that code. At least with my code it just might manage to EFAULT correctly.

Yeah, I was wondering what that early thing meant.

Linus or tip guys probably remember what this whole deal with early uaccess was about. I'll try to do some git archeology tomorrow.

Yep, just as I suspected:

6a1ea279c210 ("x86, extable: Add early_fixup_exception()")

Apparently, thread_info might not have been setup yet. I'm guessing the intention behind this no-uaccess-fixup-early is to not even attempt any fixup due to stuff *probably* not initialized yet and so the safer thing would be to panic instead.

Quoted 6 lines

I'm wondering whether making it try to EFAULT correctly is the right thing to do... We're certainly more conservative if we panic and not allow some silently failed attempt at recovery which looks successful, to continue.

hpa, thoughts?

I don't think this matters much. There aren't many users of this mechanism in the tree:

./arch/x86/kernel/signal.c:    get_user_try {
./arch/x86/kernel/signal.c:    put_user_try {
./arch/x86/kernel/signal.c:    put_user_try {
./arch/x86/kernel/signal.c:    put_user_try {
./arch/x86/kernel/signal.c:    put_user_try {

./arch/x86/kernel/signal_compat.c: put_user_try {
./arch/x86/kernel/signal_compat.c: get_user_try {
./arch/x86/kernel/vm86_32.c: put_user_try {
./arch/x86/kernel/vm86_32.c: get_user_try {

./arch/x86/ia32/ia32_signal.c:    get_user_try {
./arch/x86/ia32/ia32_signal.c:    put_user_try {
./arch/x86/ia32/ia32_signal.c:    put_user_try {
./arch/x86/ia32/ia32_signal.c:    put_user_try {

./arch/x86/include/asm/uaccess.h: * {get|put}_user_try and catch ./arch/x86/include/asm/uaccess.h: * get_user_try {
./arch/x86/include/asm/uaccess.h:#define get_user_try uaccess_try
./arch/x86/include/asm/uaccess.h:#define put_user_try uaccess_try

I don't see how we could get to that code in the first place without current_thread_info() working.

If we can ever convince gcc to do jump labels properly for uaccess, it would probably be better to just delete all that code.

--Andy

#44 lore raw

Re: [PATCH v5 4/9] x86/traps: Enable all exception handler callbacks early

In reply to Borislav Petkov
Quoted 5 lines · Borislav Petkov

I'm wondering whether making it try to EFAULT correctly is the right thing to do... We're certainly more conservative if we panic and not allow some silently failed attempt at recovery which looks successful, to continue.

No, please don't fail at early boot.

Early boot is just about the *worst* situation to try to debug odd failures, exactly since things like printk may not be reliable, and things won't get logged etc.

So particularly during early boot we should try as hard as possible not to crash - even if it means not being able to log about a problem. At least that way you have a hopefully working machine and can *maybe* debug things.

Linus

#45 lore raw

Re: [PATCH v5 4/9] x86/traps: Enable all exception handler callbacks early

Quoted 9 lines · Linus Torvalds
Quoted 5 lines · Borislav Petkov

I'm wondering whether making it try to EFAULT correctly is the right thing to do... We're certainly more conservative if we panic and not allow some silently failed attempt at recovery which looks successful, to continue.

No, please don't fail at early boot.

Quoted 9 lines

Early boot is just about the *worst* situation to try to debug odd failures, exactly since things like printk may not be reliable, and things won't get logged etc.

So particularly during early boot we should try as hard as possible not to crash - even if it means not being able to log about a problem. At least that way you have a hopefully working machine and can *maybe* debug things.

In this regard, at least, my patch is the right approach. Calling the handler, whatever it is, is less likely to panic than refusing to call it.

--Andy

maintainer
#46 lore raw

Re: [PATCH v5 4/9] x86/traps: Enable all exception handler callbacks early

Quoted 12 lines · Andy Lutomirski
Quoted 11 lines

No, please don't fail at early boot.

Early boot is just about the *worst* situation to try to debug odd failures, exactly since things like printk may not be reliable, and things won't get logged etc.

So particularly during early boot we should try as hard as possible not to crash - even if it means not being able to log about a problem. At least that way you have a hopefully working machine and can *maybe* debug things.

Quoted 3 lines

In this regard, at least, my patch is the right approach. Calling the handler, whatever it is, is less likely to panic than refusing to call it.

Ok, good.

But can we pretty please document this whole situation, i.e., the fact that we're trying really really hard not to fail early boot for debuggability reasons - either in the commit message or better in the code, for future reference. I think this is an important aspect to hold down.

Thanks.

Signature · 4 lines
Regards/Gruss,
    Boris.

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

Re: [PATCH v5 4/9] x86/traps: Enable all exception handler callbacks early

Quoted 17 lines · Borislav Petkov
Quoted 12 lines · Andy Lutomirski
Quoted 11 lines

No, please don't fail at early boot.

Early boot is just about the *worst* situation to try to debug odd failures, exactly since things like printk may not be reliable, and things won't get logged etc.

So particularly during early boot we should try as hard as possible not to crash - even if it means not being able to log about a problem. At least that way you have a hopefully working machine and can *maybe* debug things.

Quoted 3 lines

In this regard, at least, my patch is the right approach. Calling the handler, whatever it is, is less likely to panic than refusing to call it.

Quoted 7 lines

Ok, good.

But can we pretty please document this whole situation, i.e., the fact that we're trying really really hard not to fail early boot for debuggability reasons - either in the commit message or better in the code, for future reference. I think this is an important aspect to hold down.

I emailed out a followup patch to add a comment.

--Andy

Quoted 8 lines

Thanks.

--
Regards/Gruss,
Boris.

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

Signature · 2 lines
Andy Lutomirski
AMA Capital Management, LLC
#48 lore raw

Re: [PATCH v5 4/9] x86/traps: Enable all exception handler callbacks early

In reply to Borislav Petkov
Quoted 17 lines · Borislav Petkov
Quoted 12 lines · Andy Lutomirski
Quoted 11 lines

No, please don't fail at early boot.

Early boot is just about the *worst* situation to try to debug odd failures, exactly since things like printk may not be reliable, and things won't get logged etc.

So particularly during early boot we should try as hard as possible not to crash - even if it means not being able to log about a problem. At least that way you have a hopefully working machine and can *maybe* debug things.

Quoted 3 lines

In this regard, at least, my patch is the right approach. Calling the handler, whatever it is, is less likely to panic than refusing to call it.

Quoted 7 lines

Ok, good.

But can we pretty please document this whole situation, i.e., the fact that we're trying really really hard not to fail early boot for debuggability reasons - either in the commit message or better in the code, for future reference. I think this is an important aspect to hold down.

I emailed out a followup patch to add a comment.

--Andy

Quoted 8 lines

Thanks.

--
Regards/Gruss,
Boris.

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

Signature · 7 lines
Andy Lutomirski
AMA Capital Management, LLC

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
maintainer
#49 lore raw

Re: [PATCH v5 4/9] x86/traps: Enable all exception handler callbacks early

In reply to Andy Lutomirski
Quoted 12 lines · Andy Lutomirski
Quoted 11 lines

No, please don't fail at early boot.

Early boot is just about the *worst* situation to try to debug odd failures, exactly since things like printk may not be reliable, and things won't get logged etc.

So particularly during early boot we should try as hard as possible not to crash - even if it means not being able to log about a problem. At least that way you have a hopefully working machine and can *maybe* debug things.

Quoted 3 lines

In this regard, at least, my patch is the right approach. Calling the handler, whatever it is, is less likely to panic than refusing to call it.

Ok, good.

But can we pretty please document this whole situation, i.e., the fact that we're trying really really hard not to fail early boot for debuggability reasons - either in the commit message or better in the code, for future reference. I think this is an important aspect to hold down.

Thanks.

Signature · 9 lines
Regards/Gruss,
    Boris.

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

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
#50 lore raw

Re: [PATCH v5 4/9] x86/traps: Enable all exception handler callbacks early

In reply to Andy Lutomirski
Quoted 4 lines · Andy Lutomirski

In this regard, at least, my patch is the right approach. Calling the handler, whatever it is, is less likely to panic than refusing to call it.

Agreed, the patch series looks like a good thing in general.

Linus

#51 lore raw

Re: [PATCH v5 4/9] x86/traps: Enable all exception handler callbacks early

In reply to Andy Lutomirski
Quoted 4 lines · Andy Lutomirski

In this regard, at least, my patch is the right approach. Calling the handler, whatever it is, is less likely to panic than refusing to call it.

Agreed, the patch series looks like a good thing in general.

Linus

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel

#52 lore raw

Re: [PATCH v5 4/9] x86/traps: Enable all exception handler callbacks early

In reply to Linus Torvalds
Quoted 9 lines · Linus Torvalds
Quoted 5 lines · Borislav Petkov

I'm wondering whether making it try to EFAULT correctly is the right thing to do... We're certainly more conservative if we panic and not allow some silently failed attempt at recovery which looks successful, to continue.

No, please don't fail at early boot.

Quoted 9 lines

Early boot is just about the *worst* situation to try to debug odd failures, exactly since things like printk may not be reliable, and things won't get logged etc.

So particularly during early boot we should try as hard as possible not to crash - even if it means not being able to log about a problem. At least that way you have a hopefully working machine and can *maybe* debug things.

In this regard, at least, my patch is the right approach. Calling the handler, whatever it is, is less likely to panic than refusing to call it.

--Andy

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel

#53 lore raw

Re: [PATCH v5 4/9] x86/traps: Enable all exception handler callbacks early

In reply to Borislav Petkov
Quoted 5 lines · Borislav Petkov

I'm wondering whether making it try to EFAULT correctly is the right thing to do... We're certainly more conservative if we panic and not allow some silently failed attempt at recovery which looks successful, to continue.

No, please don't fail at early boot.

Early boot is just about the *worst* situation to try to debug odd failures, exactly since things like printk may not be reliable, and things won't get logged etc.

So particularly during early boot we should try as hard as possible not to crash - even if it means not being able to log about a problem. At least that way you have a hopefully working machine and can *maybe* debug things.

Linus

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel

maintainer
#54 lore raw

Re: [PATCH v5 4/9] x86/traps: Enable all exception handler callbacks early

In reply to Andy Lutomirski
Quoted 9 lines · Andy Lutomirski

I have no idea why it was explicitly unsupported, but I'm guessing it was just to avoid duplicating the code. Early "ext" uaccess failures are certainly not going to work, but I don't think this is a problem -- there's no userspace before trap_init runs, so how exactly is an "ext" uaccess going to happen in the first place?

In any event, if it did happen in older kernels, it would have immediately panicked due to that code. At least with my code it just might manage to EFAULT correctly.

Yeah, I was wondering what that early thing meant.

Linus or tip guys probably remember what this whole deal with early uaccess was about. I'll try to do some git archeology tomorrow.

In any event, it would be a good idea IMO, to hold that situation down in a comment somewhere. Once we've figured it out...

Signature · 9 lines
Regards/Gruss,
    Boris.

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

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
#55 lore raw

Re: [PATCH v5 4/9] x86/traps: Enable all exception handler callbacks early

In reply to Borislav Petkov
Quoted 64 lines · Borislav Petkov
Quoted 28 lines · Andy Lutomirski

Now that early_fixup_exception has pt_regs, we can just call fixup_exception from it. This will make fancy exception handlers work early.

---
 arch/x86/mm/extable.c | 19 ++-----------------
 1 file changed, 2 insertions(+), 17 deletions(-)
arch/x86/mm/extable.c +0 -4
index 8997022abebc..50dfe438bd91 100644
@@ -95,10 +95,6 @@ extern unsigned int early_recursion_flag;
 /* Restricted version used during very early boot */
 void __init early_fixup_exception(struct pt_regs *regs, int trapnr)
 {
-     const struct exception_table_entry *e;
-     unsigned long new_ip;
-     ex_handler_t handler;
-
      /* Ignore early NMIs. */
      if (trapnr == X86_TRAP_NMI)
              return;
@@ -109,19 +105,8 @@ void __init early_fixup_exception(struct pt_regs *regs, int trapnr)
      if (regs->cs != __KERNEL_CS)
              goto fail;
 

arch/x86/mm/extable.c void __init early_fixup_exception(struct pt_regs *regs, int trapnr) · line 121

Quoted 10 lines
arch/x86/mm/extable.c +0 -10
-     e = search_exception_tables(regs->ip);
-     if (!e)
-             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)
-             goto fail;

Hold on, what happened to the uaccess handling not being supported during early boot?

So before Tony changed it, the original code had:

/* Restricted version used during very early boot */ int __init early_fixup_exception(unsigned long *ip) {

...

(quoted diff) +0 -4
-               if (fixup->fixup - fixup->insn >= 0x7ffffff0 - 4) {
-                       /* uaccess handling not supported during early boot */
-                       return 0;
-               }

I'm guessing that wasn't supported early, probably because some stuff wasn't initialized yet. Our normal, late fixup is by doing:

        current_thread_info()->uaccess_err = 1;

and I'm assuming we can't do that early. current_thread_info is probably not setup yet...

Quoted 7 lines

arch/x86/mm/extable.c void __init early_fixup_exception(struct pt_regs *regs, int trapnr) · line 109

Quoted 5 lines
arch/x86/mm/extable.c +2 -3
-
-     regs->ip = new_ip;
-     return;
+     if (fixup_exception(regs, trapnr))
+             return;

So why can we do it now, all of a sudden?

I have no idea why it was explicitly unsupported, but I'm guessing it was just to avoid duplicating the code. Early "ext" uaccess failures are certainly not going to work, but I don't think this is a problem -- there's no userspace before trap_init runs, so how exactly is an "ext" uaccess going to happen in the first place?

In any event, if it did happen in older kernels, it would have immediately panicked due to that code. At least with my code it just might manage to EFAULT correctly.

--Andy

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel

#56 lore raw

[tip:x86/asm] x86/traps: Enable all exception handler callbacks early

In reply to Andy Lutomirski
x86/traps: Enable all exception handler callbacks early
Commit-ID:  ae7ef45e12354a1e2f6013b46df0c9f5bbb6ffbe
Gitweb:     http://git.kernel.org/tip/ae7ef45e12354a1e2f6013b46df0c9f5bbb6ffbe
Author:     Andy Lutomirski <[email protected]>
AuthorDate: Sat, 2 Apr 2016 07:01:35 -0700
Committer:  Ingo Molnar <[email protected]>
CommitDate: Wed, 13 Apr 2016 11:37:45 +0200

x86/traps: Enable all exception handler callbacks early

Now that early_fixup_exception() has pt_regs, we can just call fixup_exception() from it. This will make fancy exception handlers work early.

---
 arch/x86/mm/extable.c | 19 ++-----------------
 1 file changed, 2 insertions(+), 17 deletions(-)
arch/x86/mm/extable.c +2 -17
index da442f3..061a237 100644
@@ -88,10 +88,6 @@ extern unsigned int early_recursion_flag;
 /* Restricted version used during very early boot */
 void __init early_fixup_exception(struct pt_regs *regs, int trapnr)
 {
-	const struct exception_table_entry *e;
-	unsigned long new_ip;
-	ex_handler_t handler;
-
 	/* Ignore early NMIs. */
 	if (trapnr == X86_TRAP_NMI)
 		return;
@@ -102,19 +98,8 @@ void __init early_fixup_exception(struct pt_regs *regs, int trapnr)
 	if (regs->cs != __KERNEL_CS)
 		goto fail;
 
-	e = search_exception_tables(regs->ip);
-	if (!e)
-		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)
-		goto fail;
-
-	regs->ip = new_ip;
-	return;
+	if (fixup_exception(regs, trapnr))
+		return;
 
 fail:
 	early_printk("PANIC: early exception 0x%02x IP %lx:%lx error %lx cr2 0x%lx\n",
#57 lore raw

[tip:x86/asm] x86/traps: Enable all exception handler callbacks early

In reply to Andy Lutomirski
x86/traps: Enable all exception handler callbacks early
Commit-ID:  ae7ef45e12354a1e2f6013b46df0c9f5bbb6ffbe
Gitweb:     http://git.kernel.org/tip/ae7ef45e12354a1e2f6013b46df0c9f5bbb6ffbe
Author:     Andy Lutomirski <[email protected]>
AuthorDate: Sat, 2 Apr 2016 07:01:35 -0700
Committer:  Ingo Molnar <[email protected]>
CommitDate: Wed, 13 Apr 2016 11:37:45 +0200

x86/traps: Enable all exception handler callbacks early

Now that early_fixup_exception() has pt_regs, we can just call fixup_exception() from it. This will make fancy exception handlers work early.

---
 arch/x86/mm/extable.c | 19 ++-----------------
 1 file changed, 2 insertions(+), 17 deletions(-)
arch/x86/mm/extable.c +2 -17
index da442f3..061a237 100644
@@ -88,10 +88,6 @@ extern unsigned int early_recursion_flag;
 /* Restricted version used during very early boot */
 void __init early_fixup_exception(struct pt_regs *regs, int trapnr)
 {
-	const struct exception_table_entry *e;
-	unsigned long new_ip;
-	ex_handler_t handler;
-
 	/* Ignore early NMIs. */
 	if (trapnr == X86_TRAP_NMI)
 		return;
@@ -102,19 +98,8 @@ void __init early_fixup_exception(struct pt_regs *regs, int trapnr)
 	if (regs->cs != __KERNEL_CS)
 		goto fail;
 
-	e = search_exception_tables(regs->ip);
-	if (!e)
-		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)
-		goto fail;
-
-	regs->ip = new_ip;
-	return;
+	if (fixup_exception(regs, trapnr))
+		return;
 
 fail:
 	early_printk("PANIC: early exception 0x%02x IP %lx:%lx error %lx cr2 0x%lx\n",

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel

author maintainer
#58 lore raw

PATCH v5 4/9 x86/traps: Enable all exception handler callbacks early

In reply to Andy Lutomirski

Now that early_fixup_exception has pt_regs, we can just call fixup_exception from it. This will make fancy exception handlers work early.

---
 arch/x86/mm/extable.c | 19 ++-----------------
 1 file changed, 2 insertions(+), 17 deletions(-)
arch/x86/mm/extable.c +2 -17
index 8997022abebc..50dfe438bd91 100644
@@ -95,10 +95,6 @@ extern unsigned int early_recursion_flag;
 /* Restricted version used during very early boot */
 void __init early_fixup_exception(struct pt_regs *regs, int trapnr)
 {
-	const struct exception_table_entry *e;
-	unsigned long new_ip;
-	ex_handler_t handler;
-
 	/* Ignore early NMIs. */
 	if (trapnr == X86_TRAP_NMI)
 		return;
@@ -109,19 +105,8 @@ void __init early_fixup_exception(struct pt_regs *regs, int trapnr)
 	if (regs->cs != __KERNEL_CS)
 		goto fail;
 
-	e = search_exception_tables(regs->ip);
-	if (!e)
-		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)
-		goto fail;
-
-	regs->ip = new_ip;
-	return;
+	if (fixup_exception(regs, trapnr))
+		return;
 
 fail:
 	early_printk("PANIC: early exception 0x%02x IP %lx:%lx error %lx cr2 0x%lx\n",
Signature · 7 lines
2.5.5


_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
author maintainer
#59 lore raw

PATCH v5 5/9 x86/paravirt: Add _safe to the read_msr and write_msr PV hooks

In reply to Andy Lutomirski

These hooks match the _safe variants, so name them accordingly. This will make room for unsafe PV hooks.

---
 arch/x86/include/asm/paravirt.h       | 33 +++++++++++++++++----------------
 arch/x86/include/asm/paravirt_types.h |  8 ++++----
 arch/x86/kernel/paravirt.c            |  4 ++--
 arch/x86/xen/enlighten.c              |  4 ++--
 4 files changed, 25 insertions(+), 24 deletions(-)
arch/x86/include/asm/paravirt.h +17 -16
index f6192502149e..2e49228ed9a3 100644
@@ -129,34 +129,35 @@ static inline void wbinvd(void)
 
 #define get_kernel_rpl()  (pv_info.kernel_rpl)
 
-static inline u64 paravirt_read_msr(unsigned msr, int *err)
+static inline u64 paravirt_read_msr_safe(unsigned msr, int *err)
 {
-	return PVOP_CALL2(u64, pv_cpu_ops.read_msr, msr, err);
+	return PVOP_CALL2(u64, pv_cpu_ops.read_msr_safe, msr, err);
 }
 
-static inline int paravirt_write_msr(unsigned msr, unsigned low, unsigned high)
+static inline int paravirt_write_msr_safe(unsigned msr,
+					  unsigned low, unsigned high)
 {
-	return PVOP_CALL3(int, pv_cpu_ops.write_msr, msr, low, high);
+	return PVOP_CALL3(int, pv_cpu_ops.write_msr_safe, msr, low, high);
 }
 
 /* These should all do BUG_ON(_err), but our headers are too tangled. */
 #define rdmsr(msr, val1, val2)			\
 do {						\
 	int _err;				\
-	u64 _l = paravirt_read_msr(msr, &_err);	\
+	u64 _l = paravirt_read_msr_safe(msr, &_err);	\
 	val1 = (u32)_l;				\
 	val2 = _l >> 32;			\
 } while (0)
 
 #define wrmsr(msr, val1, val2)			\
 do {						\
-	paravirt_write_msr(msr, val1, val2);	\
+	paravirt_write_msr_safe(msr, val1, val2);	\
 } while (0)
 
 #define rdmsrl(msr, val)			\
 do {						\
 	int _err;				\
-	val = paravirt_read_msr(msr, &_err);	\
+	val = paravirt_read_msr_safe(msr, &_err);	\
 } while (0)
 
 static inline void wrmsrl(unsigned msr, u64 val)
@@ -164,23 +165,23 @@ static inline void wrmsrl(unsigned msr, u64 val)
 	wrmsr(msr, (u32)val, (u32)(val>>32));
 }
 
-#define wrmsr_safe(msr, a, b)	paravirt_write_msr(msr, a, b)
+#define wrmsr_safe(msr, a, b)	paravirt_write_msr_safe(msr, a, b)
 
 /* rdmsr with exception handling */
-#define rdmsr_safe(msr, a, b)			\
-({						\
-	int _err;				\
-	u64 _l = paravirt_read_msr(msr, &_err);	\
-	(*a) = (u32)_l;				\
-	(*b) = _l >> 32;			\
-	_err;					\
+#define rdmsr_safe(msr, a, b)				\
+({							\
+	int _err;					\
+	u64 _l = paravirt_read_msr_safe(msr, &_err);	\
+	(*a) = (u32)_l;					\
+	(*b) = _l >> 32;				\
+	_err;						\
 })
 
 static inline int rdmsrl_safe(unsigned msr, unsigned long long *p)
 {
 	int err;
 
-	*p = paravirt_read_msr(msr, &err);
+	*p = paravirt_read_msr_safe(msr, &err);
 	return err;
 }
 
arch/x86/include/asm/paravirt_types.h +4 -4
index 77db5616a473..5a06cccd36f0 100644
@@ -155,10 +155,10 @@ struct pv_cpu_ops {
 	void (*cpuid)(unsigned int *eax, unsigned int *ebx,
 		      unsigned int *ecx, unsigned int *edx);
 
-	/* MSR, PMC and TSR operations.
-	   err = 0/-EFAULT.  wrmsr returns 0/-EFAULT. */
-	u64 (*read_msr)(unsigned int msr, int *err);
-	int (*write_msr)(unsigned int msr, unsigned low, unsigned high);
+	/* MSR operations.
+	   err = 0/-EIO.  wrmsr returns 0/-EIO. */
+	u64 (*read_msr_safe)(unsigned int msr, int *err);
+	int (*write_msr_safe)(unsigned int msr, unsigned low, unsigned high);
 
 	u64 (*read_pmc)(int counter);
 
arch/x86/kernel/paravirt.c +2 -2
index f08ac28b8136..8aad95478ae5 100644
@@ -339,8 +339,8 @@ __visible struct pv_cpu_ops pv_cpu_ops = {
 	.write_cr8 = native_write_cr8,
 #endif
 	.wbinvd = native_wbinvd,
-	.read_msr = native_read_msr_safe,
-	.write_msr = native_write_msr_safe,
+	.read_msr_safe = native_read_msr_safe,
+	.write_msr_safe = native_write_msr_safe,
 	.read_pmc = native_read_pmc,
 	.load_tr_desc = native_load_tr_desc,
 	.set_ldt = native_set_ldt,
arch/x86/xen/enlighten.c +2 -2
index d09e4c9d7cc5..ff2df20d0067 100644
@@ -1222,8 +1222,8 @@ static const struct pv_cpu_ops xen_cpu_ops __initconst = {
 
 	.wbinvd = native_wbinvd,
 
-	.read_msr = xen_read_msr_safe,
-	.write_msr = xen_write_msr_safe,
+	.read_msr_safe = xen_read_msr_safe,
+	.write_msr_safe = xen_write_msr_safe,
 
 	.read_pmc = xen_read_pmc,
 
Signature · 7 lines
2.5.5


_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
maintainer
#60 lore raw

Re: [PATCH v5 5/9] x86/paravirt: Add _safe to the read_msr and write_msr PV hooks

Quoted 10 lines · Andy Lutomirski

These hooks match the _safe variants, so name them accordingly. This will make room for unsafe PV hooks.

---
 arch/x86/include/asm/paravirt.h       | 33 +++++++++++++++++----------------
 arch/x86/include/asm/paravirt_types.h |  8 ++++----
 arch/x86/kernel/paravirt.c            |  4 ++--
 arch/x86/xen/enlighten.c              |  4 ++--
 4 files changed, 25 insertions(+), 24 deletions(-)

...

Quoted 5 lines
arch/x86/include/asm/paravirt_types.h +0 -0
index 77db5616a473..5a06cccd36f0 100644

arch/x86/include/asm/paravirt_types.h struct pv_cpu_ops { · line 159

Quoted 9 lines
arch/x86/include/asm/paravirt_types.h +2 -4
@@ -155,10 +155,10 @@ struct pv_cpu_ops {
 	void (*cpuid)(unsigned int *eax, unsigned int *ebx,
 		      unsigned int *ecx, unsigned int *edx);
 
-	/* MSR, PMC and TSR operations.
-	   err = 0/-EFAULT.  wrmsr returns 0/-EFAULT. */
-	u64 (*read_msr)(unsigned int msr, int *err);
-	int (*write_msr)(unsigned int msr, unsigned low, unsigned high);
+	/* MSR operations.
+	   err = 0/-EIO.  wrmsr returns 0/-EIO. */

Please reformat this comment properly, while you're at it:

	/*
	 * A sentence.
	 * Another sentence.
	 */
Quoted 6 lines
arch/x86/include/asm/paravirt_types.h +1 -0
+	u64 (*read_msr_safe)(unsigned int msr, int *err)Please reformat this

comment properly, while you're at it:

arch/x86/include/asm/paravirt_types.h +1 -0
+	int (*write_msr_safe)(unsigned int msr, unsigned low, unsigned high);
 
 	u64 (*read_pmc)(int counter);
Signature · 4 lines
Regards/Gruss,
    Boris.

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

Re: [PATCH v5 5/9] x86/paravirt: Add _safe to the read_msr and write_msr PV hooks

Quoted 31 lines · Borislav Petkov
Quoted 10 lines · Andy Lutomirski

These hooks match the _safe variants, so name them accordingly. This will make room for unsafe PV hooks.

---
 arch/x86/include/asm/paravirt.h       | 33 +++++++++++++++++----------------
 arch/x86/include/asm/paravirt_types.h |  8 ++++----
 arch/x86/kernel/paravirt.c            |  4 ++--
 arch/x86/xen/enlighten.c              |  4 ++--
 4 files changed, 25 insertions(+), 24 deletions(-)

...

Quoted 5 lines
arch/x86/include/asm/paravirt_types.h +0 -0
index 77db5616a473..5a06cccd36f0 100644

arch/x86/include/asm/paravirt_types.h struct pv_cpu_ops { · line 159

Quoted 9 lines
arch/x86/include/asm/paravirt_types.h +2 -4
@@ -155,10 +155,10 @@ struct pv_cpu_ops {
      void (*cpuid)(unsigned int *eax, unsigned int *ebx,
                    unsigned int *ecx, unsigned int *edx);
 
-     /* MSR, PMC and TSR operations.
-        err = 0/-EFAULT.  wrmsr returns 0/-EFAULT. */
-     u64 (*read_msr)(unsigned int msr, int *err);
-     int (*write_msr)(unsigned int msr, unsigned low, unsigned high);
+     /* MSR operations.
+        err = 0/-EIO.  wrmsr returns 0/-EIO. */

Please reformat this comment properly, while you're at it:

Quoted 4 lines

/*
* A sentence.
* Another sentence.
*/

You already caught that one. It's fixed in "x86/paravirt: Add paravirt_{read,write}_msr".

Congrats on being deterministic :)

--Andy

maintainer
#62 lore raw

Re: [PATCH v5 5/9] x86/paravirt: Add _safe to the read_msr and write_msr PV hooks

Quoted 4 lines · Andy Lutomirski

You already caught that one. It's fixed in "x86/paravirt: Add paravirt_{read,write}_msr".

Congrats on being deterministic :)

LOL.

TBH, I had a strange deja-vu while typing... :-)

Signature · 9 lines
Regards/Gruss,
    Boris.

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

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
maintainer
#63 lore raw

Re: [PATCH v5 5/9] x86/paravirt: Add _safe to the read_msr and write_msr PV hooks

In reply to Andy Lutomirski
Quoted 4 lines · Andy Lutomirski

You already caught that one. It's fixed in "x86/paravirt: Add paravirt_{read,write}_msr".

Congrats on being deterministic :)

LOL.

TBH, I had a strange deja-vu while typing... :-)

Signature · 4 lines
Regards/Gruss,
    Boris.

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

Re: [PATCH v5 5/9] x86/paravirt: Add _safe to the read_msr and write_msr PV hooks

In reply to Borislav Petkov
Quoted 31 lines · Borislav Petkov
Quoted 10 lines · Andy Lutomirski

These hooks match the _safe variants, so name them accordingly. This will make room for unsafe PV hooks.

---
 arch/x86/include/asm/paravirt.h       | 33 +++++++++++++++++----------------
 arch/x86/include/asm/paravirt_types.h |  8 ++++----
 arch/x86/kernel/paravirt.c            |  4 ++--
 arch/x86/xen/enlighten.c              |  4 ++--
 4 files changed, 25 insertions(+), 24 deletions(-)

...

Quoted 5 lines
arch/x86/include/asm/paravirt_types.h +0 -0
index 77db5616a473..5a06cccd36f0 100644

arch/x86/include/asm/paravirt_types.h struct pv_cpu_ops { · line 159

Quoted 9 lines
arch/x86/include/asm/paravirt_types.h +2 -4
@@ -155,10 +155,10 @@ struct pv_cpu_ops {
      void (*cpuid)(unsigned int *eax, unsigned int *ebx,
                    unsigned int *ecx, unsigned int *edx);
 
-     /* MSR, PMC and TSR operations.
-        err = 0/-EFAULT.  wrmsr returns 0/-EFAULT. */
-     u64 (*read_msr)(unsigned int msr, int *err);
-     int (*write_msr)(unsigned int msr, unsigned low, unsigned high);
+     /* MSR operations.
+        err = 0/-EIO.  wrmsr returns 0/-EIO. */

Please reformat this comment properly, while you're at it:

Quoted 4 lines

/*
* A sentence.
* Another sentence.
*/

You already caught that one. It's fixed in "x86/paravirt: Add paravirt_{read,write}_msr".

Congrats on being deterministic :)

--Andy

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel

maintainer
#65 lore raw

Re: [PATCH v5 5/9] x86/paravirt: Add _safe to the read_msr and write_msr PV hooks

In reply to Andy Lutomirski
Quoted 10 lines · Andy Lutomirski

These hooks match the _safe variants, so name them accordingly. This will make room for unsafe PV hooks.

---
 arch/x86/include/asm/paravirt.h       | 33 +++++++++++++++++----------------
 arch/x86/include/asm/paravirt_types.h |  8 ++++----
 arch/x86/kernel/paravirt.c            |  4 ++--
 arch/x86/xen/enlighten.c              |  4 ++--
 4 files changed, 25 insertions(+), 24 deletions(-)

...

Quoted 5 lines
arch/x86/include/asm/paravirt_types.h +0 -0
index 77db5616a473..5a06cccd36f0 100644

arch/x86/include/asm/paravirt_types.h struct pv_cpu_ops { · line 159

Quoted 9 lines
arch/x86/include/asm/paravirt_types.h +2 -4
@@ -155,10 +155,10 @@ struct pv_cpu_ops {
 	void (*cpuid)(unsigned int *eax, unsigned int *ebx,
 		      unsigned int *ecx, unsigned int *edx);
 
-	/* MSR, PMC and TSR operations.
-	   err = 0/-EFAULT.  wrmsr returns 0/-EFAULT. */
-	u64 (*read_msr)(unsigned int msr, int *err);
-	int (*write_msr)(unsigned int msr, unsigned low, unsigned high);
+	/* MSR operations.
+	   err = 0/-EIO.  wrmsr returns 0/-EIO. */

Please reformat this comment properly, while you're at it:

	/*
	 * A sentence.
	 * Another sentence.
	 */
Quoted 6 lines
arch/x86/include/asm/paravirt_types.h +1 -0
+	u64 (*read_msr_safe)(unsigned int msr, int *err)Please reformat this

comment properly, while you're at it:

arch/x86/include/asm/paravirt_types.h +1 -0
+	int (*write_msr_safe)(unsigned int msr, unsigned low, unsigned high);
 
 	u64 (*read_pmc)(int counter);
Signature · 9 lines
Regards/Gruss,
    Boris.

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

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
#66 lore raw

[tip:x86/asm] x86/paravirt: Add _safe to the read_ms()r and write_msr() PV callbacks

In reply to Andy Lutomirski
x86/paravirt: Add _safe to the read_ms()r and write_msr() PV callbacks
Commit-ID:  c2ee03b2a94d7ba692cf6206bbe069d5bfcc20ed
Gitweb:     http://git.kernel.org/tip/c2ee03b2a94d7ba692cf6206bbe069d5bfcc20ed
Author:     Andy Lutomirski <[email protected]>
AuthorDate: Sat, 2 Apr 2016 07:01:36 -0700
Committer:  Ingo Molnar <[email protected]>
CommitDate: Wed, 13 Apr 2016 11:37:45 +0200

x86/paravirt: Add _safe to the read_ms()r and write_msr() PV callbacks

These callbacks match the _safe variants, so name them accordingly. This will make room for unsafe PV callbacks.

---
 arch/x86/include/asm/paravirt.h       | 33 +++++++++++++++++----------------
 arch/x86/include/asm/paravirt_types.h |  8 ++++----
 arch/x86/kernel/paravirt.c            |  4 ++--
 arch/x86/xen/enlighten.c              |  4 ++--
 4 files changed, 25 insertions(+), 24 deletions(-)
arch/x86/include/asm/paravirt.h +17 -16
index 601f1b8..81ef2d5 100644
@@ -130,34 +130,35 @@ static inline void wbinvd(void)
 
 #define get_kernel_rpl()  (pv_info.kernel_rpl)
 
-static inline u64 paravirt_read_msr(unsigned msr, int *err)
+static inline u64 paravirt_read_msr_safe(unsigned msr, int *err)
 {
-	return PVOP_CALL2(u64, pv_cpu_ops.read_msr, msr, err);
+	return PVOP_CALL2(u64, pv_cpu_ops.read_msr_safe, msr, err);
 }
 
-static inline int paravirt_write_msr(unsigned msr, unsigned low, unsigned high)
+static inline int paravirt_write_msr_safe(unsigned msr,
+					  unsigned low, unsigned high)
 {
-	return PVOP_CALL3(int, pv_cpu_ops.write_msr, msr, low, high);
+	return PVOP_CALL3(int, pv_cpu_ops.write_msr_safe, msr, low, high);
 }
 
 /* These should all do BUG_ON(_err), but our headers are too tangled. */
 #define rdmsr(msr, val1, val2)			\
 do {						\
 	int _err;				\
-	u64 _l = paravirt_read_msr(msr, &_err);	\
+	u64 _l = paravirt_read_msr_safe(msr, &_err);	\
 	val1 = (u32)_l;				\
 	val2 = _l >> 32;			\
 } while (0)
 
 #define wrmsr(msr, val1, val2)			\
 do {						\
-	paravirt_write_msr(msr, val1, val2);	\
+	paravirt_write_msr_safe(msr, val1, val2);	\
 } while (0)
 
 #define rdmsrl(msr, val)			\
 do {						\
 	int _err;				\
-	val = paravirt_read_msr(msr, &_err);	\
+	val = paravirt_read_msr_safe(msr, &_err);	\
 } while (0)
 
 static inline void wrmsrl(unsigned msr, u64 val)
@@ -165,23 +166,23 @@ static inline void wrmsrl(unsigned msr, u64 val)
 	wrmsr(msr, (u32)val, (u32)(val>>32));
 }
 
-#define wrmsr_safe(msr, a, b)	paravirt_write_msr(msr, a, b)
+#define wrmsr_safe(msr, a, b)	paravirt_write_msr_safe(msr, a, b)
 
 /* rdmsr with exception handling */
-#define rdmsr_safe(msr, a, b)			\
-({						\
-	int _err;				\
-	u64 _l = paravirt_read_msr(msr, &_err);	\
-	(*a) = (u32)_l;				\
-	(*b) = _l >> 32;			\
-	_err;					\
+#define rdmsr_safe(msr, a, b)				\
+({							\
+	int _err;					\
+	u64 _l = paravirt_read_msr_safe(msr, &_err);	\
+	(*a) = (u32)_l;					\
+	(*b) = _l >> 32;				\
+	_err;						\
 })
 
 static inline int rdmsrl_safe(unsigned msr, unsigned long long *p)
 {
 	int err;
 
-	*p = paravirt_read_msr(msr, &err);
+	*p = paravirt_read_msr_safe(msr, &err);
 	return err;
 }
 
arch/x86/include/asm/paravirt_types.h +4 -4
index e8c2326..09c9e1d 100644
@@ -155,10 +155,10 @@ struct pv_cpu_ops {
 	void (*cpuid)(unsigned int *eax, unsigned int *ebx,
 		      unsigned int *ecx, unsigned int *edx);
 
-	/* MSR, PMC and TSR operations.
-	   err = 0/-EFAULT.  wrmsr returns 0/-EFAULT. */
-	u64 (*read_msr)(unsigned int msr, int *err);
-	int (*write_msr)(unsigned int msr, unsigned low, unsigned high);
+	/* MSR operations.
+	   err = 0/-EIO.  wrmsr returns 0/-EIO. */
+	u64 (*read_msr_safe)(unsigned int msr, int *err);
+	int (*write_msr_safe)(unsigned int msr, unsigned low, unsigned high);
 
 	u64 (*read_pmc)(int counter);
 
arch/x86/kernel/paravirt.c +2 -2
index f08ac28..8aad954 100644
@@ -339,8 +339,8 @@ __visible struct pv_cpu_ops pv_cpu_ops = {
 	.write_cr8 = native_write_cr8,
 #endif
 	.wbinvd = native_wbinvd,
-	.read_msr = native_read_msr_safe,
-	.write_msr = native_write_msr_safe,
+	.read_msr_safe = native_read_msr_safe,
+	.write_msr_safe = native_write_msr_safe,
 	.read_pmc = native_read_pmc,
 	.load_tr_desc = native_load_tr_desc,
 	.set_ldt = native_set_ldt,
arch/x86/xen/enlighten.c +2 -2
index 9b8f1ea..13f756f 100644
@@ -1222,8 +1222,8 @@ static const struct pv_cpu_ops xen_cpu_ops __initconst = {
 
 	.wbinvd = native_wbinvd,
 
-	.read_msr = xen_read_msr_safe,
-	.write_msr = xen_write_msr_safe,
+	.read_msr_safe = xen_read_msr_safe,
+	.write_msr_safe = xen_write_msr_safe,
 
 	.read_pmc = xen_read_pmc,
 
#67 lore raw

[tip:x86/asm] x86/paravirt: Add _safe to the read_ms()r and write_msr() PV callbacks

In reply to Andy Lutomirski
x86/paravirt: Add _safe to the read_ms()r and write_msr() PV callbacks
Commit-ID:  c2ee03b2a94d7ba692cf6206bbe069d5bfcc20ed
Gitweb:     http://git.kernel.org/tip/c2ee03b2a94d7ba692cf6206bbe069d5bfcc20ed
Author:     Andy Lutomirski <[email protected]>
AuthorDate: Sat, 2 Apr 2016 07:01:36 -0700
Committer:  Ingo Molnar <[email protected]>
CommitDate: Wed, 13 Apr 2016 11:37:45 +0200

x86/paravirt: Add _safe to the read_ms()r and write_msr() PV callbacks

These callbacks match the _safe variants, so name them accordingly. This will make room for unsafe PV callbacks.

---
 arch/x86/include/asm/paravirt.h       | 33 +++++++++++++++++----------------
 arch/x86/include/asm/paravirt_types.h |  8 ++++----
 arch/x86/kernel/paravirt.c            |  4 ++--
 arch/x86/xen/enlighten.c              |  4 ++--
 4 files changed, 25 insertions(+), 24 deletions(-)
arch/x86/include/asm/paravirt.h +17 -16
index 601f1b8..81ef2d5 100644
@@ -130,34 +130,35 @@ static inline void wbinvd(void)
 
 #define get_kernel_rpl()  (pv_info.kernel_rpl)
 
-static inline u64 paravirt_read_msr(unsigned msr, int *err)
+static inline u64 paravirt_read_msr_safe(unsigned msr, int *err)
 {
-	return PVOP_CALL2(u64, pv_cpu_ops.read_msr, msr, err);
+	return PVOP_CALL2(u64, pv_cpu_ops.read_msr_safe, msr, err);
 }
 
-static inline int paravirt_write_msr(unsigned msr, unsigned low, unsigned high)
+static inline int paravirt_write_msr_safe(unsigned msr,
+					  unsigned low, unsigned high)
 {
-	return PVOP_CALL3(int, pv_cpu_ops.write_msr, msr, low, high);
+	return PVOP_CALL3(int, pv_cpu_ops.write_msr_safe, msr, low, high);
 }
 
 /* These should all do BUG_ON(_err), but our headers are too tangled. */
 #define rdmsr(msr, val1, val2)			\
 do {						\
 	int _err;				\
-	u64 _l = paravirt_read_msr(msr, &_err);	\
+	u64 _l = paravirt_read_msr_safe(msr, &_err);	\
 	val1 = (u32)_l;				\
 	val2 = _l >> 32;			\
 } while (0)
 
 #define wrmsr(msr, val1, val2)			\
 do {						\
-	paravirt_write_msr(msr, val1, val2);	\
+	paravirt_write_msr_safe(msr, val1, val2);	\
 } while (0)
 
 #define rdmsrl(msr, val)			\
 do {						\
 	int _err;				\
-	val = paravirt_read_msr(msr, &_err);	\
+	val = paravirt_read_msr_safe(msr, &_err);	\
 } while (0)
 
 static inline void wrmsrl(unsigned msr, u64 val)
@@ -165,23 +166,23 @@ static inline void wrmsrl(unsigned msr, u64 val)
 	wrmsr(msr, (u32)val, (u32)(val>>32));
 }
 
-#define wrmsr_safe(msr, a, b)	paravirt_write_msr(msr, a, b)
+#define wrmsr_safe(msr, a, b)	paravirt_write_msr_safe(msr, a, b)
 
 /* rdmsr with exception handling */
-#define rdmsr_safe(msr, a, b)			\
-({						\
-	int _err;				\
-	u64 _l = paravirt_read_msr(msr, &_err);	\
-	(*a) = (u32)_l;				\
-	(*b) = _l >> 32;			\
-	_err;					\
+#define rdmsr_safe(msr, a, b)				\
+({							\
+	int _err;					\
+	u64 _l = paravirt_read_msr_safe(msr, &_err);	\
+	(*a) = (u32)_l;					\
+	(*b) = _l >> 32;				\
+	_err;						\
 })
 
 static inline int rdmsrl_safe(unsigned msr, unsigned long long *p)
 {
 	int err;
 
-	*p = paravirt_read_msr(msr, &err);
+	*p = paravirt_read_msr_safe(msr, &err);
 	return err;
 }
 
arch/x86/include/asm/paravirt_types.h +4 -4
index e8c2326..09c9e1d 100644
@@ -155,10 +155,10 @@ struct pv_cpu_ops {
 	void (*cpuid)(unsigned int *eax, unsigned int *ebx,
 		      unsigned int *ecx, unsigned int *edx);
 
-	/* MSR, PMC and TSR operations.
-	   err = 0/-EFAULT.  wrmsr returns 0/-EFAULT. */
-	u64 (*read_msr)(unsigned int msr, int *err);
-	int (*write_msr)(unsigned int msr, unsigned low, unsigned high);
+	/* MSR operations.
+	   err = 0/-EIO.  wrmsr returns 0/-EIO. */
+	u64 (*read_msr_safe)(unsigned int msr, int *err);
+	int (*write_msr_safe)(unsigned int msr, unsigned low, unsigned high);
 
 	u64 (*read_pmc)(int counter);
 
arch/x86/kernel/paravirt.c +2 -2
index f08ac28..8aad954 100644
@@ -339,8 +339,8 @@ __visible struct pv_cpu_ops pv_cpu_ops = {
 	.write_cr8 = native_write_cr8,
 #endif
 	.wbinvd = native_wbinvd,
-	.read_msr = native_read_msr_safe,
-	.write_msr = native_write_msr_safe,
+	.read_msr_safe = native_read_msr_safe,
+	.write_msr_safe = native_write_msr_safe,
 	.read_pmc = native_read_pmc,
 	.load_tr_desc = native_load_tr_desc,
 	.set_ldt = native_set_ldt,
arch/x86/xen/enlighten.c +2 -2
index 9b8f1ea..13f756f 100644
@@ -1222,8 +1222,8 @@ static const struct pv_cpu_ops xen_cpu_ops __initconst = {
 
 	.wbinvd = native_wbinvd,
 
-	.read_msr = xen_read_msr_safe,
-	.write_msr = xen_write_msr_safe,
+	.read_msr_safe = xen_read_msr_safe,
+	.write_msr_safe = xen_write_msr_safe,
 
 	.read_pmc = xen_read_pmc,
 

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel

author maintainer
#68 lore raw

PATCH v5 6/9 x86/msr: Carry on after a non-"safe" MSR access fails

In reply to Andy Lutomirski

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.

---
 arch/x86/include/asm/msr.h | 10 ++++++++--
 arch/x86/mm/extable.c      | 27 +++++++++++++++++++++++++++
 2 files changed, 35 insertions(+), 2 deletions(-)
arch/x86/include/asm/msr.h +8 -2
index 93fb7c1cffda..1487054a1a70 100644
@@ -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);
 }
arch/x86/mm/extable.c +27 -0
index 50dfe438bd91..98b5f45d9d79 100644
@@ -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;
Signature · 1 line
2.5.5
#69 lore raw

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

x86/msr: Carry on after a non-"safe" MSR access fails
Commit-ID:  fbd704374d111bed16a19261176fa30e2379c87c
Gitweb:     http://git.kernel.org/tip/fbd704374d111bed16a19261176fa30e2379c87c
Author:     Andy Lutomirski <[email protected]>
AuthorDate: Sat, 2 Apr 2016 07:01:37 -0700
Committer:  Ingo Molnar <[email protected]>
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.

---
 arch/x86/include/asm/msr.h | 10 ++++++++--
 arch/x86/mm/extable.c      | 27 +++++++++++++++++++++++++++
 2 files changed, 35 insertions(+), 2 deletions(-)
arch/x86/include/asm/msr.h +8 -2
index 7a79ee2..25f169c 100644
@@ -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);
 }
arch/x86/mm/extable.c +27 -0
index 061a237..fd9eb98 100644
@@ -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;
#70 lore raw

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

In reply to Andy Lutomirski
x86/msr: Carry on after a non-"safe" MSR access fails
Commit-ID:  fbd704374d111bed16a19261176fa30e2379c87c
Gitweb:     http://git.kernel.org/tip/fbd704374d111bed16a19261176fa30e2379c87c
Author:     Andy Lutomirski <[email protected]>
AuthorDate: Sat, 2 Apr 2016 07:01:37 -0700
Committer:  Ingo Molnar <[email protected]>
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.

---
 arch/x86/include/asm/msr.h | 10 ++++++++--
 arch/x86/mm/extable.c      | 27 +++++++++++++++++++++++++++
 2 files changed, 35 insertions(+), 2 deletions(-)
arch/x86/include/asm/msr.h +8 -2
index 7a79ee2..25f169c 100644
@@ -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);
 }
arch/x86/mm/extable.c +27 -0
index 061a237..fd9eb98 100644
@@ -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;

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel

author maintainer
#71 lore raw

PATCH v5 6/9 x86/msr: Carry on after a non-"safe" MSR access fails

In reply to Andy Lutomirski

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.

---
 arch/x86/include/asm/msr.h | 10 ++++++++--
 arch/x86/mm/extable.c      | 27 +++++++++++++++++++++++++++
 2 files changed, 35 insertions(+), 2 deletions(-)
arch/x86/include/asm/msr.h +8 -2
index 93fb7c1cffda..1487054a1a70 100644
@@ -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);
 }
arch/x86/mm/extable.c +27 -0
index 50dfe438bd91..98b5f45d9d79 100644
@@ -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;
Signature · 7 lines
2.5.5


_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
author maintainer
#72 lore raw

PATCH v5 7/9 x86/paravirt: Add paravirt_{read,write}_msr

In reply to Andy Lutomirski

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.

---
 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(-)
arch/x86/include/asm/msr.h +3 -2
index 1487054a1a70..13da359881d7 100644
@@ -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"
arch/x86/include/asm/paravirt.h +11 -0
index 2e49228ed9a3..68297d87e85c 100644
@@ -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);
arch/x86/include/asm/paravirt_types.h +8 -2
index 5a06cccd36f0..b85aec45a1b8 100644
@@ -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);
 
arch/x86/kernel/paravirt.c +2 -0
index 8aad95478ae5..f9583917c7c4 100644
@@ -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,
arch/x86/xen/enlighten.c +23 -0
index ff2df20d0067..548cd3e02b9e 100644
@@ -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,
 
Signature · 1 line
2.5.5
Reviewed-by on v5 7/9
#73 lore raw

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

Quoted 9 lines · Andy Lutomirski

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.

...

arch/x86/xen/enlighten.c

Quoted 2 lines
arch/x86/xen/enlighten.c +0 -0

arch/x86/xen/enlighten.c static int xen_write_msr_safe(unsigned int msr, unsigned low, unsigned high) · line 1099

Quoted 9 lines
arch/x86/xen/enlighten.c +5 -0
@@ -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

#74 lore raw

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

Quoted 20 lines · David Vrabel
Quoted 9 lines · Andy Lutomirski

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.

...

arch/x86/xen/enlighten.c

Quoted 2 lines
arch/x86/xen/enlighten.c +0 -0
Quoted 4 lines
arch/x86/xen/enlighten.c +0 -0
@@ -1092,6 +1092,26 @@ static int xen_write_msr_safe(unsigned int msr, unsigned low, unsigned high)
      return ret;
 }
 
Quoted 8 lines

arch/x86/xen/enlighten.c static int xen_write_msr_safe(unsigned int msr, unsigned low, unsigned high) · line 1099

Quoted 5 lines
arch/x86/xen/enlighten.c +5 -0
+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

#75 lore raw

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

In reply to David Vrabel
Quoted 20 lines · David Vrabel
Quoted 9 lines · Andy Lutomirski

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.

...

arch/x86/xen/enlighten.c

Quoted 2 lines
arch/x86/xen/enlighten.c +0 -0
Quoted 4 lines
arch/x86/xen/enlighten.c +0 -0
@@ -1092,6 +1092,26 @@ static int xen_write_msr_safe(unsigned int msr, unsigned low, unsigned high)
      return ret;
 }
 
Quoted 8 lines

arch/x86/xen/enlighten.c static int xen_write_msr_safe(unsigned int msr, unsigned low, unsigned high) · line 1099

Quoted 5 lines
arch/x86/xen/enlighten.c +5 -0
+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

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel

Reviewed-by on v5 7/9
#76 lore raw

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

In reply to Andy Lutomirski
Quoted 9 lines · Andy Lutomirski

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.

...

arch/x86/xen/enlighten.c

Quoted 2 lines
arch/x86/xen/enlighten.c +0 -0

arch/x86/xen/enlighten.c static int xen_write_msr_safe(unsigned int msr, unsigned low, unsigned high) · line 1099

Quoted 9 lines
arch/x86/xen/enlighten.c +5 -0
@@ -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

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel

#77 lore raw

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

In reply to Andy Lutomirski
x86/paravirt: Add paravirt_{read,write}_msr()
Commit-ID:  dd2f4a004b016bbfb64f1de49cb45e66232e40a6
Gitweb:     http://git.kernel.org/tip/dd2f4a004b016bbfb64f1de49cb45e66232e40a6
Author:     Andy Lutomirski <[email protected]>
AuthorDate: Sat, 2 Apr 2016 07:01:38 -0700
Committer:  Ingo Molnar <[email protected]>
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.

---
 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(-)
arch/x86/include/asm/msr.h +3 -2
index 25f169c..00050c0 100644
@@ -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"
arch/x86/include/asm/paravirt.h +11 -0
index 81ef2d5..97839fa 100644
@@ -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);
arch/x86/include/asm/paravirt_types.h +8 -2
index 09c9e1d..b4a23ea 100644
@@ -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);
 
arch/x86/kernel/paravirt.c +2 -0
index 8aad954..f958391 100644
@@ -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,
arch/x86/xen/enlighten.c +23 -0
index 13f756f..6ab6722 100644
@@ -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,
 
#78 lore raw

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

In reply to Andy Lutomirski
x86/paravirt: Add paravirt_{read,write}_msr()
Commit-ID:  dd2f4a004b016bbfb64f1de49cb45e66232e40a6
Gitweb:     http://git.kernel.org/tip/dd2f4a004b016bbfb64f1de49cb45e66232e40a6
Author:     Andy Lutomirski <[email protected]>
AuthorDate: Sat, 2 Apr 2016 07:01:38 -0700
Committer:  Ingo Molnar <[email protected]>
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.

---
 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(-)
arch/x86/include/asm/msr.h +3 -2
index 25f169c..00050c0 100644
@@ -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"
arch/x86/include/asm/paravirt.h +11 -0
index 81ef2d5..97839fa 100644
@@ -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);
arch/x86/include/asm/paravirt_types.h +8 -2
index 09c9e1d..b4a23ea 100644
@@ -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);
 
arch/x86/kernel/paravirt.c +2 -0
index 8aad954..f958391 100644
@@ -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,
arch/x86/xen/enlighten.c +23 -0
index 13f756f..6ab6722 100644
@@ -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,
 

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel

author maintainer
#79 lore raw

PATCH v5 7/9 x86/paravirt: Add paravirt_{read, write}_msr

In reply to Andy Lutomirski

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.

---
 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(-)
arch/x86/include/asm/msr.h +3 -2
index 1487054a1a70..13da359881d7 100644
@@ -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"
arch/x86/include/asm/paravirt.h +11 -0
index 2e49228ed9a3..68297d87e85c 100644
@@ -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);
arch/x86/include/asm/paravirt_types.h +8 -2
index 5a06cccd36f0..b85aec45a1b8 100644
@@ -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);
 
arch/x86/kernel/paravirt.c +2 -0
index 8aad95478ae5..f9583917c7c4 100644
@@ -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,
arch/x86/xen/enlighten.c +23 -0
index ff2df20d0067..548cd3e02b9e 100644
@@ -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,
 
Signature · 7 lines
2.5.5


_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
author maintainer
#80 lore raw

PATCH v5 8/9 x86/paravirt: Make "unsafe" MSR accesses unsafe even if PARAVIRT=y

In reply to Andy Lutomirski

Enabling CONFIG_PARAVIRT had an unintended side effect: rdmsr turned into rdmsr_safe and wrmsr turned into wrmsr_safe, even on bare metal. Undo that by using the new unsafe paravirt MSR hooks.

---
 arch/x86/include/asm/paravirt.h | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)
arch/x86/include/asm/paravirt.h +3 -6
index 68297d87e85c..0c99f10874e4 100644
@@ -151,24 +151,21 @@ static inline int paravirt_write_msr_safe(unsigned msr,
 	return PVOP_CALL3(int, pv_cpu_ops.write_msr_safe, msr, low, high);
 }
 
-/* These should all do BUG_ON(_err), but our headers are too tangled. */
 #define rdmsr(msr, val1, val2)			\
 do {						\
-	int _err;				\
-	u64 _l = paravirt_read_msr_safe(msr, &_err);	\
+	u64 _l = paravirt_read_msr(msr);	\
 	val1 = (u32)_l;				\
 	val2 = _l >> 32;			\
 } while (0)
 
 #define wrmsr(msr, val1, val2)			\
 do {						\
-	paravirt_write_msr_safe(msr, val1, val2);	\
+	paravirt_write_msr(msr, val1, val2);	\
 } while (0)
 
 #define rdmsrl(msr, val)			\
 do {						\
-	int _err;				\
-	val = paravirt_read_msr_safe(msr, &_err);	\
+	val = paravirt_read_msr(msr);		\
 } while (0)
 
 static inline void wrmsrl(unsigned msr, u64 val)
Signature · 7 lines
2.5.5


_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
#81 lore raw

[tip:x86/asm] x86/paravirt: Make "unsafe" MSR accesses unsafe even if PARAVIRT=y

x86/paravirt: Make "unsafe" MSR accesses unsafe even if PARAVIRT=y
Commit-ID:  4985ce15a397e9b6541548efe3b9ffac2dda9127
Gitweb:     http://git.kernel.org/tip/4985ce15a397e9b6541548efe3b9ffac2dda9127
Author:     Andy Lutomirski <[email protected]>
AuthorDate: Sat, 2 Apr 2016 07:01:39 -0700
Committer:  Ingo Molnar <[email protected]>
CommitDate: Wed, 13 Apr 2016 11:37:46 +0200

x86/paravirt: Make "unsafe" MSR accesses unsafe even if PARAVIRT=y

Enabling CONFIG_PARAVIRT had an unintended side effect: rdmsr() turned into rdmsr_safe() and wrmsr() turned into wrmsr_safe(), even on bare metal. Undo that by using the new unsafe paravirt MSR callbacks.

---
 arch/x86/include/asm/paravirt.h | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)
arch/x86/include/asm/paravirt.h +3 -6
index 97839fa..3c73141 100644
@@ -152,24 +152,21 @@ static inline int paravirt_write_msr_safe(unsigned msr,
 	return PVOP_CALL3(int, pv_cpu_ops.write_msr_safe, msr, low, high);
 }
 
-/* These should all do BUG_ON(_err), but our headers are too tangled. */
 #define rdmsr(msr, val1, val2)			\
 do {						\
-	int _err;				\
-	u64 _l = paravirt_read_msr_safe(msr, &_err);	\
+	u64 _l = paravirt_read_msr(msr);	\
 	val1 = (u32)_l;				\
 	val2 = _l >> 32;			\
 } while (0)
 
 #define wrmsr(msr, val1, val2)			\
 do {						\
-	paravirt_write_msr_safe(msr, val1, val2);	\
+	paravirt_write_msr(msr, val1, val2);	\
 } while (0)
 
 #define rdmsrl(msr, val)			\
 do {						\
-	int _err;				\
-	val = paravirt_read_msr_safe(msr, &_err);	\
+	val = paravirt_read_msr(msr);		\
 } while (0)
 
 static inline void wrmsrl(unsigned msr, u64 val)
#82 lore raw

[tip:x86/asm] x86/paravirt: Make "unsafe" MSR accesses unsafe even if PARAVIRT=y

In reply to Andy Lutomirski
x86/paravirt: Make "unsafe" MSR accesses unsafe even if PARAVIRT=y
Commit-ID:  4985ce15a397e9b6541548efe3b9ffac2dda9127
Gitweb:     http://git.kernel.org/tip/4985ce15a397e9b6541548efe3b9ffac2dda9127
Author:     Andy Lutomirski <[email protected]>
AuthorDate: Sat, 2 Apr 2016 07:01:39 -0700
Committer:  Ingo Molnar <[email protected]>
CommitDate: Wed, 13 Apr 2016 11:37:46 +0200

x86/paravirt: Make "unsafe" MSR accesses unsafe even if PARAVIRT=y

Enabling CONFIG_PARAVIRT had an unintended side effect: rdmsr() turned into rdmsr_safe() and wrmsr() turned into wrmsr_safe(), even on bare metal. Undo that by using the new unsafe paravirt MSR callbacks.

---
 arch/x86/include/asm/paravirt.h | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)
arch/x86/include/asm/paravirt.h +3 -6
index 97839fa..3c73141 100644
@@ -152,24 +152,21 @@ static inline int paravirt_write_msr_safe(unsigned msr,
 	return PVOP_CALL3(int, pv_cpu_ops.write_msr_safe, msr, low, high);
 }
 
-/* These should all do BUG_ON(_err), but our headers are too tangled. */
 #define rdmsr(msr, val1, val2)			\
 do {						\
-	int _err;				\
-	u64 _l = paravirt_read_msr_safe(msr, &_err);	\
+	u64 _l = paravirt_read_msr(msr);	\
 	val1 = (u32)_l;				\
 	val2 = _l >> 32;			\
 } while (0)
 
 #define wrmsr(msr, val1, val2)			\
 do {						\
-	paravirt_write_msr_safe(msr, val1, val2);	\
+	paravirt_write_msr(msr, val1, val2);	\
 } while (0)
 
 #define rdmsrl(msr, val)			\
 do {						\
-	int _err;				\
-	val = paravirt_read_msr_safe(msr, &_err);	\
+	val = paravirt_read_msr(msr);		\
 } while (0)
 
 static inline void wrmsrl(unsigned msr, u64 val)

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel

author maintainer
#83 lore raw

PATCH v5 9/9 x86/msr: Set the return value to zero when native_rdmsr_safe fails

In reply to Andy Lutomirski

This will cause unchecked native_rdmsr_safe failures to return deterministic results.

---
 arch/x86/include/asm/msr.h | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
arch/x86/include/asm/msr.h +4 -1
index 13da359881d7..e97e79f8a22b 100644
@@ -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)
Signature · 1 line
2.5.5
#84 lore raw

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

x86/msr: Set the return value to zero when native_rdmsr_safe() fails
Commit-ID:  b828b79fcced0e66492590707649dbfaea6435e6
Gitweb:     http://git.kernel.org/tip/b828b79fcced0e66492590707649dbfaea6435e6
Author:     Andy Lutomirski <[email protected]>
AuthorDate: Sat, 2 Apr 2016 07:01:40 -0700
Committer:  Ingo Molnar <[email protected]>
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.

---
 arch/x86/include/asm/msr.h | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
arch/x86/include/asm/msr.h +4 -1
index 00050c0..7dc1d8f 100644
@@ -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)
#85 lore raw

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

In reply to Andy Lutomirski
x86/msr: Set the return value to zero when native_rdmsr_safe() fails
Commit-ID:  b828b79fcced0e66492590707649dbfaea6435e6
Gitweb:     http://git.kernel.org/tip/b828b79fcced0e66492590707649dbfaea6435e6
Author:     Andy Lutomirski <[email protected]>
AuthorDate: Sat, 2 Apr 2016 07:01:40 -0700
Committer:  Ingo Molnar <[email protected]>
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.

---
 arch/x86/include/asm/msr.h | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
arch/x86/include/asm/msr.h +4 -1
index 00050c0..7dc1d8f 100644
@@ -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)

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel

author maintainer
#86 lore raw

PATCH v5 9/9 x86/msr: Set the return value to zero when native_rdmsr_safe fails

In reply to Andy Lutomirski

This will cause unchecked native_rdmsr_safe failures to return deterministic results.

---
 arch/x86/include/asm/msr.h | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
arch/x86/include/asm/msr.h +4 -1
index 13da359881d7..e97e79f8a22b 100644
@@ -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)
Signature · 7 lines
2.5.5


_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
#88 lore raw
Quoted 5 lines · Linus Torvalds

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

#89 lore raw
Quoted 4 lines · Andy Lutomirski

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

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel

#90 lore raw
In reply to Andy Lutomirski
Quoted 4 lines · Andy Lutomirski

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

#91 lore raw
In reply to Linus Torvalds
Quoted 5 lines · Linus Torvalds

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

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel

maintainer Reviewed-by on the v5 series
#93 lore raw
In reply to Andy Lutomirski
Quoted 4 lines · Andy Lutomirski

There are two parts here:

***** FIRST PART: EARLY EXCEPTIONS *****

Quoted 8 lines

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:

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.

Signature · 9 lines
Regards/Gruss,
    Boris.

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

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
maintainer Reviewed-by on the v5 series
#94 lore raw
In reply to Andy Lutomirski
Quoted 4 lines · Andy Lutomirski

There are two parts here:

***** FIRST PART: EARLY EXCEPTIONS *****

Quoted 8 lines

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:

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.

Signature · 4 lines
Regards/Gruss,
    Boris.

ECO tip #101: Trim your mails when you reply.
reviewer Tested-by on the v5 series
#95 lore raw
In reply to Andy Lutomirski
Quoted 11 lines · Andy Lutomirski

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

-boris

reviewer Tested-by on the v5 series
#96 lore raw
In reply to Andy Lutomirski
Quoted 11 lines · Andy Lutomirski

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

-boris

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel