Re: [PATCH] x86: optionally show last exception from/to register contents (v2)

2007-09-01 Thread Andi Kleen
On Tuesday 28 August 2007 12:44:31 Jan Beulich wrote:
> .. when dumping register state. This is particularly useful when gcc
> managed to tail-call optimize an indirect call which happens to hit a
> NULL (or otherwise invalid) pointer.

I added it, with a warning in the documentation and changelog

Also all the other patches except for the #DF one. Thanks.

BTW I think there is a reasonable cheap way to avoid the interrupt race: 

If pda->irqcount was split into two 16bit words and irq entry code increases 
the upper 
16bit word (that should be nearly free because because both are in L1 cache; 
with some luck the CPU can even dual-issue). Then the traps code could save
the irq count early and then in the no_context case disable interrupts,
compare and only print LER if there were no interrupts inbetween.

-Andi 


-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] x86: optionally show last exception from/to register contents (v2)

2007-09-01 Thread Andi Kleen
On Tuesday 28 August 2007 12:44:31 Jan Beulich wrote:
 .. when dumping register state. This is particularly useful when gcc
 managed to tail-call optimize an indirect call which happens to hit a
 NULL (or otherwise invalid) pointer.

I added it, with a warning in the documentation and changelog

Also all the other patches except for the #DF one. Thanks.

BTW I think there is a reasonable cheap way to avoid the interrupt race: 

If pda-irqcount was split into two 16bit words and irq entry code increases 
the upper 
16bit word (that should be nearly free because because both are in L1 cache; 
with some luck the CPU can even dual-issue). Then the traps code could save
the irq count early and then in the no_context case disable interrupts,
compare and only print LER if there were no interrupts inbetween.

-Andi 


-
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] x86: optionally show last exception from/to register contents (v2)

2007-08-28 Thread Jan Beulich
.. when dumping register state. This is particularly useful when gcc
managed to tail-call optimize an indirect call which happens to hit a
NULL (or otherwise invalid) pointer.

Signed-off-by: Jan Beulich <[EMAIL PROTECTED]>

 Documentation/kernel-parameters.txt |3 +++
 arch/i386/kernel/cpu/amd.c  |4 
 arch/i386/kernel/cpu/common.c   |2 ++
 arch/i386/kernel/cpu/intel.c|   20 ++--
 arch/i386/kernel/traps.c|   35 +++
 arch/x86_64/kernel/setup.c  |   23 ++-
 arch/x86_64/kernel/traps.c  |   34 ++
 include/asm-i386/msr-index.h|3 +++
 include/asm-i386/processor.h|4 
 include/asm-x86_64/msr.h|6 ++
 include/asm-x86_64/processor.h  |3 +++
 11 files changed, 126 insertions(+), 11 deletions(-)

--- linux-2.6.23-rc4/Documentation/kernel-parameters.txt2007-08-28 
09:41:55.0 +0200
+++ 2.6.23-rc4-x86-ler/Documentation/kernel-parameters.txt  2007-08-17 
09:58:55.0 +0200
@@ -1155,6 +1155,9 @@ and is between 256 and 4096 characters. 
 
nolapic_timer   [X86-32,APIC] Do not use the local APIC timer.
 
+   noler   [X86-32/X86-64] Do not print last exception records
+   with kernel register dumps.
+
noltlbs [PPC] Do not use large page/tlb entries for kernel
lowmem mapping on PPC40x.
 
--- linux-2.6.23-rc4/arch/i386/kernel/cpu/amd.c 2007-08-28 09:41:58.0 
+0200
+++ 2.6.23-rc4-x86-ler/arch/i386/kernel/cpu/amd.c   2007-08-17 
10:02:17.0 +0200
@@ -238,9 +238,13 @@ static void __cpuinit init_amd(struct cp
case 0x10:
case 0x11:
set_bit(X86_FEATURE_K8, c->x86_capability);
+   if (ler_enabled)
+   __get_cpu_var(ler_msr) = MSR_IA32_LASTINTFROMIP;
break;
case 6:
set_bit(X86_FEATURE_K7, c->x86_capability); 
+   if (ler_enabled)
+   __get_cpu_var(ler_msr) = MSR_IA32_LASTINTFROMIP;
break;
}
if (c->x86 >= 6)
--- linux-2.6.23-rc4/arch/i386/kernel/cpu/common.c  2007-08-28 
09:41:58.0 +0200
+++ 2.6.23-rc4-x86-ler/arch/i386/kernel/cpu/common.c2007-08-07 
10:42:55.0 +0200
@@ -503,6 +503,8 @@ static void __cpuinit identify_cpu(struc
 
/* Init Machine Check Exception if available. */
mcheck_init(c);
+
+   ler_enable();
 }
 
 void __init identify_boot_cpu(void)
--- linux-2.6.23-rc4/arch/i386/kernel/cpu/intel.c   2007-07-09 
01:32:17.0 +0200
+++ 2.6.23-rc4-x86-ler/arch/i386/kernel/cpu/intel.c 2007-08-07 
10:42:55.0 +0200
@@ -188,15 +188,23 @@ static void __cpuinit init_intel(struct 
}
 #endif
 
-   if (c->x86 == 15) {
+   switch (c->x86) {
+   case 15:
set_bit(X86_FEATURE_P4, c->x86_capability);
set_bit(X86_FEATURE_SYNC_RDTSC, c->x86_capability);
-   }
-   if (c->x86 == 6) 
+   if (c->x86_model >= 0x03)
+   set_bit(X86_FEATURE_CONSTANT_TSC, c->x86_capability);
+   if (ler_enabled)
+   __get_cpu_var(ler_msr) = MSR_P4_LER_FROM_LIP;
+   break;
+   case 6:
set_bit(X86_FEATURE_P3, c->x86_capability);
-   if ((c->x86 == 0xf && c->x86_model >= 0x03) ||
-   (c->x86 == 0x6 && c->x86_model >= 0x0e))
-   set_bit(X86_FEATURE_CONSTANT_TSC, c->x86_capability);
+   if (c->x86_model >= 0x0e)
+   set_bit(X86_FEATURE_CONSTANT_TSC, c->x86_capability);
+   if (ler_enabled)
+   __get_cpu_var(ler_msr) = MSR_IA32_LASTINTFROMIP;
+   break;
+   }
 
if (cpu_has_ds) {
unsigned int l1;
--- linux-2.6.23-rc4/arch/i386/kernel/traps.c   2007-08-28 09:41:58.0 
+0200
+++ 2.6.23-rc4-x86-ler/arch/i386/kernel/traps.c 2007-08-17 14:26:08.0 
+0200
@@ -321,6 +321,20 @@ void show_registers(struct pt_regs *regs
unsigned int code_len = code_bytes;
unsigned char c;
 
+   if (oops_in_progress && __get_cpu_var(ler_msr)) {
+   u32 from, to, hi;
+
+   if (rdmsr_safe(__get_cpu_var(ler_msr), , ) == 0
+   && rdmsr_safe(__get_cpu_var(ler_msr) + 1, , ) 
== 0) {
+   printk("\n" KERN_EMERG
+  "last branch before last 
exception/interrupt\n");
+   printk(KERN_EMERG " from %08x", from);
+   print_symbol(" (%s)\n", from);
+   printk(KERN_EMERG " to %08x", to);
+   print_symbol(" (%s)", to);
+   } else
+   

[PATCH] x86: optionally show last exception from/to register contents (v2)

2007-08-28 Thread Jan Beulich
.. when dumping register state. This is particularly useful when gcc
managed to tail-call optimize an indirect call which happens to hit a
NULL (or otherwise invalid) pointer.

Signed-off-by: Jan Beulich [EMAIL PROTECTED]

 Documentation/kernel-parameters.txt |3 +++
 arch/i386/kernel/cpu/amd.c  |4 
 arch/i386/kernel/cpu/common.c   |2 ++
 arch/i386/kernel/cpu/intel.c|   20 ++--
 arch/i386/kernel/traps.c|   35 +++
 arch/x86_64/kernel/setup.c  |   23 ++-
 arch/x86_64/kernel/traps.c  |   34 ++
 include/asm-i386/msr-index.h|3 +++
 include/asm-i386/processor.h|4 
 include/asm-x86_64/msr.h|6 ++
 include/asm-x86_64/processor.h  |3 +++
 11 files changed, 126 insertions(+), 11 deletions(-)

--- linux-2.6.23-rc4/Documentation/kernel-parameters.txt2007-08-28 
09:41:55.0 +0200
+++ 2.6.23-rc4-x86-ler/Documentation/kernel-parameters.txt  2007-08-17 
09:58:55.0 +0200
@@ -1155,6 +1155,9 @@ and is between 256 and 4096 characters. 
 
nolapic_timer   [X86-32,APIC] Do not use the local APIC timer.
 
+   noler   [X86-32/X86-64] Do not print last exception records
+   with kernel register dumps.
+
noltlbs [PPC] Do not use large page/tlb entries for kernel
lowmem mapping on PPC40x.
 
--- linux-2.6.23-rc4/arch/i386/kernel/cpu/amd.c 2007-08-28 09:41:58.0 
+0200
+++ 2.6.23-rc4-x86-ler/arch/i386/kernel/cpu/amd.c   2007-08-17 
10:02:17.0 +0200
@@ -238,9 +238,13 @@ static void __cpuinit init_amd(struct cp
case 0x10:
case 0x11:
set_bit(X86_FEATURE_K8, c-x86_capability);
+   if (ler_enabled)
+   __get_cpu_var(ler_msr) = MSR_IA32_LASTINTFROMIP;
break;
case 6:
set_bit(X86_FEATURE_K7, c-x86_capability); 
+   if (ler_enabled)
+   __get_cpu_var(ler_msr) = MSR_IA32_LASTINTFROMIP;
break;
}
if (c-x86 = 6)
--- linux-2.6.23-rc4/arch/i386/kernel/cpu/common.c  2007-08-28 
09:41:58.0 +0200
+++ 2.6.23-rc4-x86-ler/arch/i386/kernel/cpu/common.c2007-08-07 
10:42:55.0 +0200
@@ -503,6 +503,8 @@ static void __cpuinit identify_cpu(struc
 
/* Init Machine Check Exception if available. */
mcheck_init(c);
+
+   ler_enable();
 }
 
 void __init identify_boot_cpu(void)
--- linux-2.6.23-rc4/arch/i386/kernel/cpu/intel.c   2007-07-09 
01:32:17.0 +0200
+++ 2.6.23-rc4-x86-ler/arch/i386/kernel/cpu/intel.c 2007-08-07 
10:42:55.0 +0200
@@ -188,15 +188,23 @@ static void __cpuinit init_intel(struct 
}
 #endif
 
-   if (c-x86 == 15) {
+   switch (c-x86) {
+   case 15:
set_bit(X86_FEATURE_P4, c-x86_capability);
set_bit(X86_FEATURE_SYNC_RDTSC, c-x86_capability);
-   }
-   if (c-x86 == 6) 
+   if (c-x86_model = 0x03)
+   set_bit(X86_FEATURE_CONSTANT_TSC, c-x86_capability);
+   if (ler_enabled)
+   __get_cpu_var(ler_msr) = MSR_P4_LER_FROM_LIP;
+   break;
+   case 6:
set_bit(X86_FEATURE_P3, c-x86_capability);
-   if ((c-x86 == 0xf  c-x86_model = 0x03) ||
-   (c-x86 == 0x6  c-x86_model = 0x0e))
-   set_bit(X86_FEATURE_CONSTANT_TSC, c-x86_capability);
+   if (c-x86_model = 0x0e)
+   set_bit(X86_FEATURE_CONSTANT_TSC, c-x86_capability);
+   if (ler_enabled)
+   __get_cpu_var(ler_msr) = MSR_IA32_LASTINTFROMIP;
+   break;
+   }
 
if (cpu_has_ds) {
unsigned int l1;
--- linux-2.6.23-rc4/arch/i386/kernel/traps.c   2007-08-28 09:41:58.0 
+0200
+++ 2.6.23-rc4-x86-ler/arch/i386/kernel/traps.c 2007-08-17 14:26:08.0 
+0200
@@ -321,6 +321,20 @@ void show_registers(struct pt_regs *regs
unsigned int code_len = code_bytes;
unsigned char c;
 
+   if (oops_in_progress  __get_cpu_var(ler_msr)) {
+   u32 from, to, hi;
+
+   if (rdmsr_safe(__get_cpu_var(ler_msr), from, hi) == 0
+rdmsr_safe(__get_cpu_var(ler_msr) + 1, to, hi) 
== 0) {
+   printk(\n KERN_EMERG
+  last branch before last 
exception/interrupt\n);
+   printk(KERN_EMERG  from %08x, from);
+   print_symbol( (%s)\n, from);
+   printk(KERN_EMERG  to %08x, to);
+   print_symbol( (%s), to);
+   } else
+   __get_cpu_var(ler_msr) = 0;
+

Re: [PATCH] x86: optionally show last exception from/to register contents

2007-08-13 Thread Randy Dunlap
On Mon, 13 Aug 2007 16:21:10 +0200 Andi Kleen wrote:

> > I though you did, but since I never saw it appear in any release, I posted
> > this one...
> 
> It's a little different (and somewhat hackish I admit) 
> ftp://firstfloor.org/pub/ak/x86_64/debug/last-branch
> It has far more overhead than yours of course.
> 
> The only way to merge something like that would be dynamic
> patching and I was never quite motivated for that.
> 
> > So especially with the first concern of yours - is it worth at all rev-ing 
> > this
> > patch to address the other change requests you voiced?
> 
> The patch is useful even with the race, just document somewhere
> that it is unreliable (perhaps in the printk itself) and do the
> other changes.

and add "ler" entry to Documentation/kernel-parameters.txt, please,
with what it means.

> I would also suggest to enable it by default.


---
~Randy
*** Remember to use Documentation/SubmitChecklist when testing your code ***
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] x86: optionally show last exception from/to register contents

2007-08-13 Thread Keith Owens
Andi Kleen (on Mon, 13 Aug 2007 15:08:45 +0200) wrote:
>On Mon, Aug 13, 2007 at 12:33:05PM +0100, Jan Beulich wrote:
>
>
>>  
>>  if (cpu_has_ds) {
>>  unsigned int l1;
>> --- linux-2.6.23-rc3/arch/i386/kernel/traps.c2007-08-13 
>> 08:59:45.0 +0200
>> +++ 2.6.23-rc3-x86-ler/arch/i386/kernel/traps.c  2007-08-07 
>> 10:42:55.0 +0200
>> @@ -321,6 +321,13 @@ void show_registers(struct pt_regs *regs
>>  unsigned int code_len = code_bytes;
>>  unsigned char c;
>>  
>> +if (__get_cpu_var(ler_msr)) {
>> +u32 from, to, hi;
>> +
>> +rdmsr(__get_cpu_var(ler_msr), from, hi);
>> +rdmsr(__get_cpu_var(ler_msr) + 1, to, hi);
>> +printk("LER: %08x -> %08x\n", from, to);
>> +}
>
>This seems racy -- AFAIK the MSR will record the last branch
>before an interrupt too, and the trap handlers enable interrupts
>before coming here. 
>
>Can't think of a good way to avoid that for page fault at least
>without impacting interrupt latency or reading the MSR always.

KDB used to have a "last branch recording" (lbr) feature.  The page
fault handler was modified to disable lbr before entering
do_page_fault().  Nobody seemed to care about the slight slowdown but
also nobody seemed to be using that feature for debugging, we rarely
get wild branches into the middle of nowhere.  lbr was messy to
maintain for very little gain, so I removed it from KDB at
2.6.17-i386-2.

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] x86: optionally show last exception from/to register contents

2007-08-13 Thread Andi Kleen
> I though you did, but since I never saw it appear in any release, I posted
> this one...

It's a little different (and somewhat hackish I admit) 
ftp://firstfloor.org/pub/ak/x86_64/debug/last-branch
It has far more overhead than yours of course.

The only way to merge something like that would be dynamic
patching and I was never quite motivated for that.

> So especially with the first concern of yours - is it worth at all rev-ing 
> this
> patch to address the other change requests you voiced?

The patch is useful even with the race, just document somewhere
that it is unreliable (perhaps in the printk itself) and do the
other changes.

I would also suggest to enable it by default.

-Andi
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] x86: optionally show last exception from/to register contents

2007-08-13 Thread Jan Beulich
>>> Andi Kleen <[EMAIL PROTECTED]> 13.08.07 15:08 >>>
>On Mon, Aug 13, 2007 at 12:33:05PM +0100, Jan Beulich wrote:
>> +if (__get_cpu_var(ler_msr)) {
>> +u32 from, to, hi;
>> +
>> +rdmsr(__get_cpu_var(ler_msr), from, hi);
>> +rdmsr(__get_cpu_var(ler_msr) + 1, to, hi);
>> +printk("LER: %08x -> %08x\n", from, to);
>> +}
>
>This seems racy -- AFAIK the MSR will record the last branch
>before an interrupt too, and the trap handlers enable interrupts
>before coming here. 
>
>Can't think of a good way to avoid that for page fault at least
>without impacting interrupt latency or reading the MSR always.

That's the problem. Other than either going through interrupt gates *and* 
keeping
interrupts disabled long enough, there's nothing you can do, except turning of
tracing before re-enabling interrupts, which in turn you would likely reject 
because
of the performance overhead of the necessary rdmsr/wrmsr pair.

>The other thing is that this should use print_symbol()

I considered this, but decided against it due to the address pair being 
displayed.
But I could certainly change that.

>> @@ -360,6 +367,18 @@ int is_valid_bugaddr(unsigned long eip)
>>  return ud2 == 0x0b0f;
>>  }
>>  
>> +DEFINE_PER_CPU(u32, ler_msr);
>> +int ler_enabled = 0;
>> +
>> +void ler_enable(void) {
>> +if (__get_cpu_var(ler_msr)) {
>> +u64 debugctl;
>> +
>> +rdmsrl(MSR_IA32_DEBUGCTLMSR, debugctl);
>> +wrmsrl(MSR_IA32_DEBUGCTLMSR, debugctl | 1);
>
>Better use checking_rd/wrmsrl and disable on fail -- often emulators 
>fake specific CPUs, but don't implement all debugging features.

Okay, if you consider emulators important here (this is one of the reasons for
having to turn on the feature via command line option).

>> +static int __init ler_setup(char *s)
>> +{
>> +ler_enabled = 1;
>> +return 1;
>> +}
>> +__setup("ler", ler_setup);
>
>I don't think the option is very useful.

Apart from the above, I assume it's also useful initially to avoid boot problems
in case the model->msr mapping isn't fully cooked, yet (obviously I don't have
machines with all the different CPU families/models around to test, so the 
coding
of what I wasn't able to test is purely based on the manuals).

>BTW I have a patch somewhere to save/report last branch on exception
>too, but it never seemed suitable for mainline because of its

I though you did, but since I never saw it appear in any release, I posted
this one...

So especially with the first concern of yours - is it worth at all rev-ing this
patch to address the other change requests you voiced?

>high overhead. If someone submitted a full BTS driver I would
>be tempted though :)

That shouldn't be too difficult.

Jan

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] x86: optionally show last exception from/to register contents

2007-08-13 Thread Andi Kleen
On Mon, Aug 13, 2007 at 12:33:05PM +0100, Jan Beulich wrote:


>  
>   if (cpu_has_ds) {
>   unsigned int l1;
> --- linux-2.6.23-rc3/arch/i386/kernel/traps.c 2007-08-13 08:59:45.0 
> +0200
> +++ 2.6.23-rc3-x86-ler/arch/i386/kernel/traps.c   2007-08-07 
> 10:42:55.0 +0200
> @@ -321,6 +321,13 @@ void show_registers(struct pt_regs *regs
>   unsigned int code_len = code_bytes;
>   unsigned char c;
>  
> + if (__get_cpu_var(ler_msr)) {
> + u32 from, to, hi;
> +
> + rdmsr(__get_cpu_var(ler_msr), from, hi);
> + rdmsr(__get_cpu_var(ler_msr) + 1, to, hi);
> + printk("LER: %08x -> %08x\n", from, to);
> + }

This seems racy -- AFAIK the MSR will record the last branch
before an interrupt too, and the trap handlers enable interrupts
before coming here. 

Can't think of a good way to avoid that for page fault at least
without impacting interrupt latency or reading the MSR always.

The other thing is that this should use print_symbol()

>   printk("\n" KERN_EMERG "Stack: ");
>   show_stack_log_lvl(NULL, regs, (unsigned long *)esp, 
> KERN_EMERG);
>  
> @@ -360,6 +367,18 @@ int is_valid_bugaddr(unsigned long eip)
>   return ud2 == 0x0b0f;
>  }
>  
> +DEFINE_PER_CPU(u32, ler_msr);
> +int ler_enabled = 0;
> +
> +void ler_enable(void) {
> + if (__get_cpu_var(ler_msr)) {
> + u64 debugctl;
> +
> + rdmsrl(MSR_IA32_DEBUGCTLMSR, debugctl);
> + wrmsrl(MSR_IA32_DEBUGCTLMSR, debugctl | 1);

Better use checking_rd/wrmsrl and disable on fail -- often emulators 
fake specific CPUs, but don't implement all debugging features.

> +static int __init ler_setup(char *s)
> +{
> + ler_enabled = 1;
> + return 1;
> +}
> +__setup("ler", ler_setup);

I don't think the option is very useful.

BTW I have a patch somewhere to save/report last branch on exception
too, but it never seemed suitable for mainline because of its
high overhead. If someone submitted a full BTS driver I would
be tempted though :)

-Andi

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] x86: optionally show last exception from/to register contents

2007-08-13 Thread Jan Beulich
.. when dumping register state. This is particularly useful when gcc
managed to tail-call optimize an indirect call which happens to hit a
NULL (or otherwise invalid) pointer.

Signed-off-by: Jan Beulich <[EMAIL PROTECTED]>

 arch/i386/kernel/cpu/amd.c |4 
 arch/i386/kernel/cpu/common.c  |2 ++
 arch/i386/kernel/cpu/intel.c   |   20 ++--
 arch/i386/kernel/traps.c   |   27 +++
 arch/x86_64/kernel/setup.c |   23 ++-
 arch/x86_64/kernel/traps.c |   27 +++
 include/asm-i386/msr-index.h   |3 +++
 include/asm-i386/processor.h   |4 
 include/asm-x86_64/processor.h |3 +++
 9 files changed, 102 insertions(+), 11 deletions(-)

--- linux-2.6.23-rc3/arch/i386/kernel/cpu/amd.c 2007-08-13 08:59:44.0 
+0200
+++ 2.6.23-rc3-x86-ler/arch/i386/kernel/cpu/amd.c   2007-08-07 
10:42:55.0 +0200
@@ -238,9 +238,13 @@ static void __cpuinit init_amd(struct cp
case 0x10:
case 0x11:
set_bit(X86_FEATURE_K8, c->x86_capability);
+   if (ler_enabled)
+   __get_cpu_var(ler_msr) = MSR_IA32_LASTINTFROMIP;
break;
case 6:
set_bit(X86_FEATURE_K7, c->x86_capability); 
+   if (ler_enabled)
+   __get_cpu_var(ler_msr) = MSR_IA32_LASTINTFROMIP;
break;
}
if (c->x86 >= 6)
--- linux-2.6.23-rc3/arch/i386/kernel/cpu/common.c  2007-08-13 
08:59:44.0 +0200
+++ 2.6.23-rc3-x86-ler/arch/i386/kernel/cpu/common.c2007-08-07 
10:42:55.0 +0200
@@ -503,6 +503,8 @@ static void __cpuinit identify_cpu(struc
 
/* Init Machine Check Exception if available. */
mcheck_init(c);
+
+   ler_enable();
 }
 
 void __init identify_boot_cpu(void)
--- linux-2.6.23-rc3/arch/i386/kernel/cpu/intel.c   2007-07-09 
01:32:17.0 +0200
+++ 2.6.23-rc3-x86-ler/arch/i386/kernel/cpu/intel.c 2007-08-07 
10:42:55.0 +0200
@@ -188,15 +188,23 @@ static void __cpuinit init_intel(struct 
}
 #endif
 
-   if (c->x86 == 15) {
+   switch (c->x86) {
+   case 15:
set_bit(X86_FEATURE_P4, c->x86_capability);
set_bit(X86_FEATURE_SYNC_RDTSC, c->x86_capability);
-   }
-   if (c->x86 == 6) 
+   if (c->x86_model >= 0x03)
+   set_bit(X86_FEATURE_CONSTANT_TSC, c->x86_capability);
+   if (ler_enabled)
+   __get_cpu_var(ler_msr) = MSR_P4_LER_FROM_LIP;
+   break;
+   case 6:
set_bit(X86_FEATURE_P3, c->x86_capability);
-   if ((c->x86 == 0xf && c->x86_model >= 0x03) ||
-   (c->x86 == 0x6 && c->x86_model >= 0x0e))
-   set_bit(X86_FEATURE_CONSTANT_TSC, c->x86_capability);
+   if (c->x86_model >= 0x0e)
+   set_bit(X86_FEATURE_CONSTANT_TSC, c->x86_capability);
+   if (ler_enabled)
+   __get_cpu_var(ler_msr) = MSR_IA32_LASTINTFROMIP;
+   break;
+   }
 
if (cpu_has_ds) {
unsigned int l1;
--- linux-2.6.23-rc3/arch/i386/kernel/traps.c   2007-08-13 08:59:45.0 
+0200
+++ 2.6.23-rc3-x86-ler/arch/i386/kernel/traps.c 2007-08-07 10:42:55.0 
+0200
@@ -321,6 +321,13 @@ void show_registers(struct pt_regs *regs
unsigned int code_len = code_bytes;
unsigned char c;
 
+   if (__get_cpu_var(ler_msr)) {
+   u32 from, to, hi;
+
+   rdmsr(__get_cpu_var(ler_msr), from, hi);
+   rdmsr(__get_cpu_var(ler_msr) + 1, to, hi);
+   printk("LER: %08x -> %08x\n", from, to);
+   }
printk("\n" KERN_EMERG "Stack: ");
show_stack_log_lvl(NULL, regs, (unsigned long *)esp, 
KERN_EMERG);
 
@@ -360,6 +367,18 @@ int is_valid_bugaddr(unsigned long eip)
return ud2 == 0x0b0f;
 }
 
+DEFINE_PER_CPU(u32, ler_msr);
+int ler_enabled = 0;
+
+void ler_enable(void) {
+   if (__get_cpu_var(ler_msr)) {
+   u64 debugctl;
+
+   rdmsrl(MSR_IA32_DEBUGCTLMSR, debugctl);
+   wrmsrl(MSR_IA32_DEBUGCTLMSR, debugctl | 1);
+   }
+}
+
 /*
  * This is gone through when something in the kernel has done something bad and
  * is about to be terminated.
@@ -846,6 +865,7 @@ fastcall void __kprobes do_debug(struct 
struct task_struct *tsk = current;
 
get_debugreg(condition, 6);
+   ler_enable();
 
if (notify_die(DIE_DEBUG, "debug", regs, condition, error_code,
SIGTRAP) == NOTIFY_STOP)
@@ -1239,3 +1259,10 @@ static int __init code_bytes_setup(char 
return 1;
 }
 __setup("code_bytes=", code_bytes_setup);
+
+static int __init ler_setup(char *s)
+{
+   ler_enabled = 1;
+   return 1;
+}
+__setup("ler", ler_setup);
--- 

[PATCH] x86: optionally show last exception from/to register contents

2007-08-13 Thread Jan Beulich
.. when dumping register state. This is particularly useful when gcc
managed to tail-call optimize an indirect call which happens to hit a
NULL (or otherwise invalid) pointer.

Signed-off-by: Jan Beulich [EMAIL PROTECTED]

 arch/i386/kernel/cpu/amd.c |4 
 arch/i386/kernel/cpu/common.c  |2 ++
 arch/i386/kernel/cpu/intel.c   |   20 ++--
 arch/i386/kernel/traps.c   |   27 +++
 arch/x86_64/kernel/setup.c |   23 ++-
 arch/x86_64/kernel/traps.c |   27 +++
 include/asm-i386/msr-index.h   |3 +++
 include/asm-i386/processor.h   |4 
 include/asm-x86_64/processor.h |3 +++
 9 files changed, 102 insertions(+), 11 deletions(-)

--- linux-2.6.23-rc3/arch/i386/kernel/cpu/amd.c 2007-08-13 08:59:44.0 
+0200
+++ 2.6.23-rc3-x86-ler/arch/i386/kernel/cpu/amd.c   2007-08-07 
10:42:55.0 +0200
@@ -238,9 +238,13 @@ static void __cpuinit init_amd(struct cp
case 0x10:
case 0x11:
set_bit(X86_FEATURE_K8, c-x86_capability);
+   if (ler_enabled)
+   __get_cpu_var(ler_msr) = MSR_IA32_LASTINTFROMIP;
break;
case 6:
set_bit(X86_FEATURE_K7, c-x86_capability); 
+   if (ler_enabled)
+   __get_cpu_var(ler_msr) = MSR_IA32_LASTINTFROMIP;
break;
}
if (c-x86 = 6)
--- linux-2.6.23-rc3/arch/i386/kernel/cpu/common.c  2007-08-13 
08:59:44.0 +0200
+++ 2.6.23-rc3-x86-ler/arch/i386/kernel/cpu/common.c2007-08-07 
10:42:55.0 +0200
@@ -503,6 +503,8 @@ static void __cpuinit identify_cpu(struc
 
/* Init Machine Check Exception if available. */
mcheck_init(c);
+
+   ler_enable();
 }
 
 void __init identify_boot_cpu(void)
--- linux-2.6.23-rc3/arch/i386/kernel/cpu/intel.c   2007-07-09 
01:32:17.0 +0200
+++ 2.6.23-rc3-x86-ler/arch/i386/kernel/cpu/intel.c 2007-08-07 
10:42:55.0 +0200
@@ -188,15 +188,23 @@ static void __cpuinit init_intel(struct 
}
 #endif
 
-   if (c-x86 == 15) {
+   switch (c-x86) {
+   case 15:
set_bit(X86_FEATURE_P4, c-x86_capability);
set_bit(X86_FEATURE_SYNC_RDTSC, c-x86_capability);
-   }
-   if (c-x86 == 6) 
+   if (c-x86_model = 0x03)
+   set_bit(X86_FEATURE_CONSTANT_TSC, c-x86_capability);
+   if (ler_enabled)
+   __get_cpu_var(ler_msr) = MSR_P4_LER_FROM_LIP;
+   break;
+   case 6:
set_bit(X86_FEATURE_P3, c-x86_capability);
-   if ((c-x86 == 0xf  c-x86_model = 0x03) ||
-   (c-x86 == 0x6  c-x86_model = 0x0e))
-   set_bit(X86_FEATURE_CONSTANT_TSC, c-x86_capability);
+   if (c-x86_model = 0x0e)
+   set_bit(X86_FEATURE_CONSTANT_TSC, c-x86_capability);
+   if (ler_enabled)
+   __get_cpu_var(ler_msr) = MSR_IA32_LASTINTFROMIP;
+   break;
+   }
 
if (cpu_has_ds) {
unsigned int l1;
--- linux-2.6.23-rc3/arch/i386/kernel/traps.c   2007-08-13 08:59:45.0 
+0200
+++ 2.6.23-rc3-x86-ler/arch/i386/kernel/traps.c 2007-08-07 10:42:55.0 
+0200
@@ -321,6 +321,13 @@ void show_registers(struct pt_regs *regs
unsigned int code_len = code_bytes;
unsigned char c;
 
+   if (__get_cpu_var(ler_msr)) {
+   u32 from, to, hi;
+
+   rdmsr(__get_cpu_var(ler_msr), from, hi);
+   rdmsr(__get_cpu_var(ler_msr) + 1, to, hi);
+   printk(LER: %08x - %08x\n, from, to);
+   }
printk(\n KERN_EMERG Stack: );
show_stack_log_lvl(NULL, regs, (unsigned long *)esp, 
KERN_EMERG);
 
@@ -360,6 +367,18 @@ int is_valid_bugaddr(unsigned long eip)
return ud2 == 0x0b0f;
 }
 
+DEFINE_PER_CPU(u32, ler_msr);
+int ler_enabled = 0;
+
+void ler_enable(void) {
+   if (__get_cpu_var(ler_msr)) {
+   u64 debugctl;
+
+   rdmsrl(MSR_IA32_DEBUGCTLMSR, debugctl);
+   wrmsrl(MSR_IA32_DEBUGCTLMSR, debugctl | 1);
+   }
+}
+
 /*
  * This is gone through when something in the kernel has done something bad and
  * is about to be terminated.
@@ -846,6 +865,7 @@ fastcall void __kprobes do_debug(struct 
struct task_struct *tsk = current;
 
get_debugreg(condition, 6);
+   ler_enable();
 
if (notify_die(DIE_DEBUG, debug, regs, condition, error_code,
SIGTRAP) == NOTIFY_STOP)
@@ -1239,3 +1259,10 @@ static int __init code_bytes_setup(char 
return 1;
 }
 __setup(code_bytes=, code_bytes_setup);
+
+static int __init ler_setup(char *s)
+{
+   ler_enabled = 1;
+   return 1;
+}
+__setup(ler, ler_setup);
--- linux-2.6.23-rc3/arch/x86_64/kernel/setup.c 

Re: [PATCH] x86: optionally show last exception from/to register contents

2007-08-13 Thread Andi Kleen
On Mon, Aug 13, 2007 at 12:33:05PM +0100, Jan Beulich wrote:


  
   if (cpu_has_ds) {
   unsigned int l1;
 --- linux-2.6.23-rc3/arch/i386/kernel/traps.c 2007-08-13 08:59:45.0 
 +0200
 +++ 2.6.23-rc3-x86-ler/arch/i386/kernel/traps.c   2007-08-07 
 10:42:55.0 +0200
 @@ -321,6 +321,13 @@ void show_registers(struct pt_regs *regs
   unsigned int code_len = code_bytes;
   unsigned char c;
  
 + if (__get_cpu_var(ler_msr)) {
 + u32 from, to, hi;
 +
 + rdmsr(__get_cpu_var(ler_msr), from, hi);
 + rdmsr(__get_cpu_var(ler_msr) + 1, to, hi);
 + printk(LER: %08x - %08x\n, from, to);
 + }

This seems racy -- AFAIK the MSR will record the last branch
before an interrupt too, and the trap handlers enable interrupts
before coming here. 

Can't think of a good way to avoid that for page fault at least
without impacting interrupt latency or reading the MSR always.

The other thing is that this should use print_symbol()

   printk(\n KERN_EMERG Stack: );
   show_stack_log_lvl(NULL, regs, (unsigned long *)esp, 
 KERN_EMERG);
  
 @@ -360,6 +367,18 @@ int is_valid_bugaddr(unsigned long eip)
   return ud2 == 0x0b0f;
  }
  
 +DEFINE_PER_CPU(u32, ler_msr);
 +int ler_enabled = 0;
 +
 +void ler_enable(void) {
 + if (__get_cpu_var(ler_msr)) {
 + u64 debugctl;
 +
 + rdmsrl(MSR_IA32_DEBUGCTLMSR, debugctl);
 + wrmsrl(MSR_IA32_DEBUGCTLMSR, debugctl | 1);

Better use checking_rd/wrmsrl and disable on fail -- often emulators 
fake specific CPUs, but don't implement all debugging features.

 +static int __init ler_setup(char *s)
 +{
 + ler_enabled = 1;
 + return 1;
 +}
 +__setup(ler, ler_setup);

I don't think the option is very useful.

BTW I have a patch somewhere to save/report last branch on exception
too, but it never seemed suitable for mainline because of its
high overhead. If someone submitted a full BTS driver I would
be tempted though :)

-Andi

-
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] x86: optionally show last exception from/to register contents

2007-08-13 Thread Andi Kleen
 I though you did, but since I never saw it appear in any release, I posted
 this one...

It's a little different (and somewhat hackish I admit) 
ftp://firstfloor.org/pub/ak/x86_64/debug/last-branch
It has far more overhead than yours of course.

The only way to merge something like that would be dynamic
patching and I was never quite motivated for that.

 So especially with the first concern of yours - is it worth at all rev-ing 
 this
 patch to address the other change requests you voiced?

The patch is useful even with the race, just document somewhere
that it is unreliable (perhaps in the printk itself) and do the
other changes.

I would also suggest to enable it by default.

-Andi
-
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] x86: optionally show last exception from/to register contents

2007-08-13 Thread Jan Beulich
 Andi Kleen [EMAIL PROTECTED] 13.08.07 15:08 
On Mon, Aug 13, 2007 at 12:33:05PM +0100, Jan Beulich wrote:
 +if (__get_cpu_var(ler_msr)) {
 +u32 from, to, hi;
 +
 +rdmsr(__get_cpu_var(ler_msr), from, hi);
 +rdmsr(__get_cpu_var(ler_msr) + 1, to, hi);
 +printk(LER: %08x - %08x\n, from, to);
 +}

This seems racy -- AFAIK the MSR will record the last branch
before an interrupt too, and the trap handlers enable interrupts
before coming here. 

Can't think of a good way to avoid that for page fault at least
without impacting interrupt latency or reading the MSR always.

That's the problem. Other than either going through interrupt gates *and* 
keeping
interrupts disabled long enough, there's nothing you can do, except turning of
tracing before re-enabling interrupts, which in turn you would likely reject 
because
of the performance overhead of the necessary rdmsr/wrmsr pair.

The other thing is that this should use print_symbol()

I considered this, but decided against it due to the address pair being 
displayed.
But I could certainly change that.

 @@ -360,6 +367,18 @@ int is_valid_bugaddr(unsigned long eip)
  return ud2 == 0x0b0f;
  }
  
 +DEFINE_PER_CPU(u32, ler_msr);
 +int ler_enabled = 0;
 +
 +void ler_enable(void) {
 +if (__get_cpu_var(ler_msr)) {
 +u64 debugctl;
 +
 +rdmsrl(MSR_IA32_DEBUGCTLMSR, debugctl);
 +wrmsrl(MSR_IA32_DEBUGCTLMSR, debugctl | 1);

Better use checking_rd/wrmsrl and disable on fail -- often emulators 
fake specific CPUs, but don't implement all debugging features.

Okay, if you consider emulators important here (this is one of the reasons for
having to turn on the feature via command line option).

 +static int __init ler_setup(char *s)
 +{
 +ler_enabled = 1;
 +return 1;
 +}
 +__setup(ler, ler_setup);

I don't think the option is very useful.

Apart from the above, I assume it's also useful initially to avoid boot problems
in case the model-msr mapping isn't fully cooked, yet (obviously I don't have
machines with all the different CPU families/models around to test, so the 
coding
of what I wasn't able to test is purely based on the manuals).

BTW I have a patch somewhere to save/report last branch on exception
too, but it never seemed suitable for mainline because of its

I though you did, but since I never saw it appear in any release, I posted
this one...

So especially with the first concern of yours - is it worth at all rev-ing this
patch to address the other change requests you voiced?

high overhead. If someone submitted a full BTS driver I would
be tempted though :)

That shouldn't be too difficult.

Jan

-
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] x86: optionally show last exception from/to register contents

2007-08-13 Thread Keith Owens
Andi Kleen (on Mon, 13 Aug 2007 15:08:45 +0200) wrote:
On Mon, Aug 13, 2007 at 12:33:05PM +0100, Jan Beulich wrote:


  
  if (cpu_has_ds) {
  unsigned int l1;
 --- linux-2.6.23-rc3/arch/i386/kernel/traps.c2007-08-13 
 08:59:45.0 +0200
 +++ 2.6.23-rc3-x86-ler/arch/i386/kernel/traps.c  2007-08-07 
 10:42:55.0 +0200
 @@ -321,6 +321,13 @@ void show_registers(struct pt_regs *regs
  unsigned int code_len = code_bytes;
  unsigned char c;
  
 +if (__get_cpu_var(ler_msr)) {
 +u32 from, to, hi;
 +
 +rdmsr(__get_cpu_var(ler_msr), from, hi);
 +rdmsr(__get_cpu_var(ler_msr) + 1, to, hi);
 +printk(LER: %08x - %08x\n, from, to);
 +}

This seems racy -- AFAIK the MSR will record the last branch
before an interrupt too, and the trap handlers enable interrupts
before coming here. 

Can't think of a good way to avoid that for page fault at least
without impacting interrupt latency or reading the MSR always.

KDB used to have a last branch recording (lbr) feature.  The page
fault handler was modified to disable lbr before entering
do_page_fault().  Nobody seemed to care about the slight slowdown but
also nobody seemed to be using that feature for debugging, we rarely
get wild branches into the middle of nowhere.  lbr was messy to
maintain for very little gain, so I removed it from KDB at
2.6.17-i386-2.

-
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] x86: optionally show last exception from/to register contents

2007-08-13 Thread Randy Dunlap
On Mon, 13 Aug 2007 16:21:10 +0200 Andi Kleen wrote:

  I though you did, but since I never saw it appear in any release, I posted
  this one...
 
 It's a little different (and somewhat hackish I admit) 
 ftp://firstfloor.org/pub/ak/x86_64/debug/last-branch
 It has far more overhead than yours of course.
 
 The only way to merge something like that would be dynamic
 patching and I was never quite motivated for that.
 
  So especially with the first concern of yours - is it worth at all rev-ing 
  this
  patch to address the other change requests you voiced?
 
 The patch is useful even with the race, just document somewhere
 that it is unreliable (perhaps in the printk itself) and do the
 other changes.

and add ler entry to Documentation/kernel-parameters.txt, please,
with what it means.

 I would also suggest to enable it by default.


---
~Randy
*** Remember to use Documentation/SubmitChecklist when testing your code ***
-
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/