From 690a973f48b6ba2954465992c08e65059c8374fe Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Sat, 21 Oct 2006 18:37:01 +0200 Subject: [PATCH] x86-64: Speed up dwarf2 unwinder This changes the dwarf2 unwinder to do a binary search for CIEs instead of a linear work. The linker is unfortunately not able to build a proper lookup table at link time, instead it creates one at runtime as soon as the bootmem allocator is usable (so you'll continue using the linear lookup for the first [hopefully] few calls). The code should be ready to utilize a build-time created table once a fixed linker becomes available. Signed-off-by: Jan Beulich Signed-off-by: Andi Kleen --- include/asm-generic/vmlinux.lds.h | 16 ++++++++++++++++ include/linux/unwind.h | 2 ++ 2 files changed, 18 insertions(+) (limited to 'include') diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index 69240b52f8e1..9d0d11c180d9 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -125,6 +125,10 @@ *(__param) \ VMLINUX_SYMBOL(__stop___param) = .; \ } \ + \ + /* Unwind data binary search table */ \ + EH_FRAME_HDR \ + \ __end_rodata = .; \ . = ALIGN(4096); @@ -157,6 +161,18 @@ *(.kprobes.text) \ VMLINUX_SYMBOL(__kprobes_text_end) = .; +#ifdef CONFIG_STACK_UNWIND + /* Unwind data binary search table */ +#define EH_FRAME_HDR \ + .eh_frame_hdr : AT(ADDR(.eh_frame_hdr) - LOAD_OFFSET) { \ + VMLINUX_SYMBOL(__start_unwind_hdr) = .; \ + *(.eh_frame_hdr) \ + VMLINUX_SYMBOL(__end_unwind_hdr) = .; \ + } +#else +#define EH_FRAME_HDR +#endif + /* DWARF debug sections. Symbols in the DWARF debugging sections are relative to the beginning of the section so we begin them at 0. */ diff --git a/include/linux/unwind.h b/include/linux/unwind.h index 73e1751d03dd..749928c161fb 100644 --- a/include/linux/unwind.h +++ b/include/linux/unwind.h @@ -26,6 +26,7 @@ struct module; * Initialize unwind support. */ extern void unwind_init(void); +extern void unwind_setup(void); #ifdef CONFIG_MODULES @@ -73,6 +74,7 @@ extern int unwind_to_user(struct unwind_frame_info *); struct unwind_frame_info {}; static inline void unwind_init(void) {} +static inline void unwind_setup(void) {} #ifdef CONFIG_MODULES -- cgit v1.2.3 From 7a71cef780404e8c90d23b1131142e158d94354b Mon Sep 17 00:00:00 2001 From: "bibo,mao" Date: Sat, 21 Oct 2006 18:37:02 +0200 Subject: [PATCH] x86-64: x86_64 add NX mask for PTE entry If function change_page_attr_addr calls revert_page to revert to original pte value, mk_pte_phys does not mask NX bit. If NX bit is set on no NX hardware supported x86_64 machine, there is will be RSVD type page fault and system will crash. This patch adds NX mask bit for PTE entry. Signed-off-by: bibo,mao Signed-off-by: Andi Kleen --- include/asm-x86_64/pgtable.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/asm-x86_64/pgtable.h b/include/asm-x86_64/pgtable.h index 6899e770b173..0555c1c4d8fa 100644 --- a/include/asm-x86_64/pgtable.h +++ b/include/asm-x86_64/pgtable.h @@ -366,6 +366,7 @@ static inline pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot) { pte_t pte; pte_val(pte) = physpage | pgprot_val(pgprot); + pte_val(pte) &= __supported_pte_mask; return pte; } -- cgit v1.2.3 From a1bae67243512ca30ceda48e3e24e25b543f8ab7 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Sat, 21 Oct 2006 18:37:02 +0200 Subject: [PATCH] i386: Disable nmi watchdog on all ThinkPads Even newer Thinkpads have bugs in SMM code that causes hangs with NMI watchdog. Signed-off-by: Andi Kleen --- arch/i386/kernel/nmi.c | 10 +++++----- drivers/firmware/dmi_scan.c | 20 ++++++++++++++++++++ include/linux/dmi.h | 2 ++ 3 files changed, 27 insertions(+), 5 deletions(-) (limited to 'include') diff --git a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c index 3e8e3adb0489..eaafe233a5da 100644 --- a/arch/i386/kernel/nmi.c +++ b/arch/i386/kernel/nmi.c @@ -219,11 +219,11 @@ static int __init check_nmi_watchdog(void) int cpu; /* Enable NMI watchdog for newer systems. - Actually it should be safe for most systems before 2004 too except - for some IBM systems that corrupt registers when NMI happens - during SMM. Unfortunately we don't have more exact information - on these and use this coarse check. */ - if (nmi_watchdog == NMI_DEFAULT && dmi_get_year(DMI_BIOS_DATE) >= 2004) + Probably safe on most older systems too, but let's be careful. + IBM ThinkPads use INT10 inside SMM and that allows early NMI inside SMM + which hangs the system. Disable watchdog for all thinkpads */ + if (nmi_watchdog == NMI_DEFAULT && dmi_get_year(DMI_BIOS_DATE) >= 2004 && + !dmi_name_in_vendors("ThinkPad")) nmi_watchdog = NMI_LOCAL_APIC; if ((nmi_watchdog == NMI_NONE) || (nmi_watchdog == NMI_DEFAULT)) diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c index b8b596d5778d..37deee6c0c1c 100644 --- a/drivers/firmware/dmi_scan.c +++ b/drivers/firmware/dmi_scan.c @@ -326,6 +326,26 @@ char *dmi_get_system_info(int field) } EXPORT_SYMBOL(dmi_get_system_info); + +/** + * dmi_name_in_vendors - Check if string is anywhere in the DMI vendor information. + * @str: Case sensitive Name + */ +int dmi_name_in_vendors(char *str) +{ + static int fields[] = { DMI_BIOS_VENDOR, DMI_BIOS_VERSION, DMI_SYS_VENDOR, + DMI_PRODUCT_NAME, DMI_PRODUCT_VERSION, DMI_BOARD_VENDOR, + DMI_BOARD_NAME, DMI_BOARD_VERSION, DMI_NONE }; + int i; + for (i = 0; fields[i] != DMI_NONE; i++) { + int f = fields[i]; + if (dmi_ident[f] && strstr(dmi_ident[f], str)) + return 1; + } + return 0; +} +EXPORT_SYMBOL(dmi_name_in_vendors); + /** * dmi_find_device - find onboard device by type/name * @type: device type or %DMI_DEV_TYPE_ANY to match all device types diff --git a/include/linux/dmi.h b/include/linux/dmi.h index 38dc403be70b..904bf3d2d90b 100644 --- a/include/linux/dmi.h +++ b/include/linux/dmi.h @@ -69,6 +69,7 @@ extern struct dmi_device * dmi_find_device(int type, const char *name, struct dmi_device *from); extern void dmi_scan_machine(void); extern int dmi_get_year(int field); +extern int dmi_name_in_vendors(char *str); #else @@ -77,6 +78,7 @@ static inline char * dmi_get_system_info(int field) { return NULL; } static inline struct dmi_device * dmi_find_device(int type, const char *name, struct dmi_device *from) { return NULL; } static inline int dmi_get_year(int year) { return 0; } +static inline int dmi_name_in_vendors(char *s) { return 0; } #endif -- cgit v1.2.3 From e70ea8c09db0e25ab58f84ba7f393e5c9125a8ee Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Sat, 21 Oct 2006 18:37:03 +0200 Subject: [PATCH] x86-64: Revert timer routing behaviour back to 2.6.16 state By default route the 8254 over the 8259 and only disable it on ATI boards where this causes double timer interrupts. This should unbreak some Nvidia boards where the timer doesn't seem to tick of it isn't enabled in the 8259. At least one VIA board also seemed to have a little trouble with the disabled 8259. For 2.6.20 we'll try both dynamically without black listing, but I think for .19 this is the safer approach because it has been already well tested in earlier kernels. This also makes the x86-64 behaviour the same as i386. Command line options can change all this of course. Signed-off-by: Andi Kleen --- arch/x86_64/kernel/early-quirks.c | 9 +++++---- arch/x86_64/kernel/io_apic.c | 2 +- include/asm-x86_64/proto.h | 2 ++ 3 files changed, 8 insertions(+), 5 deletions(-) (limited to 'include') diff --git a/arch/x86_64/kernel/early-quirks.c b/arch/x86_64/kernel/early-quirks.c index 208e38a372c1..2b1245d86258 100644 --- a/arch/x86_64/kernel/early-quirks.c +++ b/arch/x86_64/kernel/early-quirks.c @@ -61,10 +61,11 @@ static void nvidia_bugs(void) static void ati_bugs(void) { -#if 1 /* for testing */ - printk("ATI board detected\n"); -#endif - /* No bugs right now */ + if (timer_over_8254 == 1) { + timer_over_8254 = 0; + printk(KERN_INFO + "ATI board detected. Disabling timer routing over 8254.\n"); + } } struct chipset { diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c index 8a9a357875b7..b000017e4b5d 100644 --- a/arch/x86_64/kernel/io_apic.c +++ b/arch/x86_64/kernel/io_apic.c @@ -57,7 +57,7 @@ static int no_timer_check; static int disable_timer_pin_1 __initdata; -int timer_over_8254 __initdata = 0; +int timer_over_8254 __initdata = 1; /* Where if anywhere is the i8259 connect in external int mode */ static struct { int pin, apic; } ioapic_i8259 = { -1, -1 }; diff --git a/include/asm-x86_64/proto.h b/include/asm-x86_64/proto.h index c181fef786e4..e72cfcdf5344 100644 --- a/include/asm-x86_64/proto.h +++ b/include/asm-x86_64/proto.h @@ -122,6 +122,8 @@ extern int fix_aperture; extern int reboot_force; extern int notsc_setup(char *); +extern int timer_over_8254; + extern int gsi_irq_sharing(int gsi); extern void smp_local_timer_interrupt(void); -- cgit v1.2.3