diff mbox

[U-Boot,v2,1/2] x86: Display correct CS/EIP/EFLAGS when there is an error code

Message ID BLU436-SMTP206842CFD7B06FB9061DD4CBF9F0@phx.gbl
State Accepted
Delegated to: Simon Glass
Headers show

Commit Message

Bin Meng July 10, 2015, 2:38 a.m. UTC
Some exceptions cause an error code to be saved on the current stack
after the EIP value. We should extract CS/EIP/EFLAGS from different
position on the stack based on the exception number.

Signed-off-by: Bin Meng <bmeng.cn@gmail.com>

---

Changes in v2:
- Use enum for x86 exception numbers

 arch/x86/cpu/interrupts.c        | 29 ++++++++++++++++++++++++++++-
 arch/x86/include/asm/interrupt.h | 24 ++++++++++++++++++++++++
 arch/x86/include/asm/ptrace.h    | 16 +++++++++++++---
 3 files changed, 65 insertions(+), 4 deletions(-)

Comments

Simon Glass July 18, 2015, 2:37 p.m. UTC | #1
On 9 July 2015 at 20:38, Bin Meng <bmeng.cn@gmail.com> wrote:
> Some exceptions cause an error code to be saved on the current stack
> after the EIP value. We should extract CS/EIP/EFLAGS from different
> position on the stack based on the exception number.
>
> Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
>
> ---
>
> Changes in v2:
> - Use enum for x86 exception numbers
>
>  arch/x86/cpu/interrupts.c        | 29 ++++++++++++++++++++++++++++-
>  arch/x86/include/asm/interrupt.h | 24 ++++++++++++++++++++++++
>  arch/x86/include/asm/ptrace.h    | 16 +++++++++++++---
>  3 files changed, 65 insertions(+), 4 deletions(-)

Acked-by: Simon Glass <sjg@chromium.org>
Simon Glass July 20, 2015, 2:04 a.m. UTC | #2
On 18 July 2015 at 08:37, Simon Glass <sjg@chromium.org> wrote:
> On 9 July 2015 at 20:38, Bin Meng <bmeng.cn@gmail.com> wrote:
>> Some exceptions cause an error code to be saved on the current stack
>> after the EIP value. We should extract CS/EIP/EFLAGS from different
>> position on the stack based on the exception number.
>>
>> Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
>>
>> ---
>>
>> Changes in v2:
>> - Use enum for x86 exception numbers
>>
>>  arch/x86/cpu/interrupts.c        | 29 ++++++++++++++++++++++++++++-
>>  arch/x86/include/asm/interrupt.h | 24 ++++++++++++++++++++++++
>>  arch/x86/include/asm/ptrace.h    | 16 +++++++++++++---
>>  3 files changed, 65 insertions(+), 4 deletions(-)
>
> Acked-by: Simon Glass <sjg@chromium.org>

Applied to u-boot-x86, thanks!
diff mbox

Patch

diff --git a/arch/x86/cpu/interrupts.c b/arch/x86/cpu/interrupts.c
index c777d36..043a8d4 100644
--- a/arch/x86/cpu/interrupts.c
+++ b/arch/x86/cpu/interrupts.c
@@ -34,12 +34,39 @@  DECLARE_GLOBAL_DATA_PTR;
 
 static void dump_regs(struct irq_regs *regs)
 {
+	unsigned long cs, eip, eflags;
 	unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L;
 	unsigned long d0, d1, d2, d3, d6, d7;
 	unsigned long sp;
 
+	/*
+	 * Some exceptions cause an error code to be saved on the current stack
+	 * after the EIP value. We should extract CS/EIP/EFLAGS from different
+	 * position on the stack based on the exception number.
+	 */
+	switch (regs->irq_id) {
+	case EXC_DF:
+	case EXC_TS:
+	case EXC_NP:
+	case EXC_SS:
+	case EXC_GP:
+	case EXC_PF:
+	case EXC_AC:
+		cs = regs->context.ctx2.xcs;
+		eip = regs->context.ctx2.eip;
+		eflags = regs->context.ctx2.eflags;
+		/* We should fix up the ESP due to error code */
+		regs->esp += 4;
+		break;
+	default:
+		cs = regs->context.ctx1.xcs;
+		eip = regs->context.ctx1.eip;
+		eflags = regs->context.ctx1.eflags;
+		break;
+	}
+
 	printf("EIP: %04x:[<%08lx>] EFLAGS: %08lx\n",
-			(u16)regs->xcs, regs->eip, regs->eflags);
+			(u16)cs, eip, eflags);
 
 	printf("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n",
 		regs->eax, regs->ebx, regs->ecx, regs->edx);
diff --git a/arch/x86/include/asm/interrupt.h b/arch/x86/include/asm/interrupt.h
index 0a75f89..6eef4f9 100644
--- a/arch/x86/include/asm/interrupt.h
+++ b/arch/x86/include/asm/interrupt.h
@@ -13,6 +13,30 @@ 
 
 #include <asm/types.h>
 
+/* Architecture defined exceptions */
+enum x86_exception {
+	EXC_DE = 0,
+	EXC_DB,
+	EXC_NMI,
+	EXC_BP,
+	EXC_OF,
+	EXC_BR,
+	EXC_UD,
+	EXC_NM,
+	EXC_DF,
+	EXC_CSO,
+	EXC_TS,
+	EXC_NP,
+	EXC_SS,
+	EXC_GP,
+	EXC_PF,
+	EXC_MF = 16,
+	EXC_AC,
+	EXC_MC,
+	EXC_XM,
+	EXC_VE
+};
+
 /* arch/x86/cpu/interrupts.c */
 void set_vector(u8 intnum, void *routine);
 
diff --git a/arch/x86/include/asm/ptrace.h b/arch/x86/include/asm/ptrace.h
index a727dbf..3849bc0 100644
--- a/arch/x86/include/asm/ptrace.h
+++ b/arch/x86/include/asm/ptrace.h
@@ -63,9 +63,19 @@  struct irq_regs {
 	/* Pushed by vector handler (irq_<num>) */
 	long irq_id;
 	/* Pushed by cpu in response to interrupt */
-	long eip;
-	long xcs;
-	long eflags;
+	union {
+		struct {
+			long eip;
+			long xcs;
+			long eflags;
+		} ctx1;
+		struct {
+			long err;
+			long eip;
+			long xcs;
+			long eflags;
+		} ctx2;
+	} context;
 }  __attribute__ ((packed));
 
 /* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */