Merge branch 'for-linus' of git://one.firstfloor.org/home/andi/git/linux-2.6
* 'for-linus' of git://one.firstfloor.org/home/andi/git/linux-2.6: [PATCH] x86-64: Revert timer routing behaviour back to 2.6.16 state [PATCH] x86-64: Overlapping program headers in physical addr space fix [PATCH] x86-64: Put more than one cpu in TARGET_CPUS [PATCH] x86: Revert new unwind kernel stack termination [PATCH] x86-64: Use irq_domain in ioapic_retrigger_irq [PATCH] i386: Disable nmi watchdog on all ThinkPads [PATCH] x86-64: Revert interrupt backlink changes [PATCH] x86-64: Fix ENOSYS in system call tracing [PATCH] i386: Fix fake return address [PATCH] x86-64: x86_64 add NX mask for PTE entry [PATCH] x86-64: Speed up dwarf2 unwinder [PATCH] x86: Use -maccumulate-outgoing-args [PATCH] x86-64: fix page align in e820 allocator [PATCH] x86-64: Fix for arch/x86_64/pci/Makefile CFLAGS [PATCH] i386: fix .cfi_signal_frame copy-n-paste error [PATCH] x86-64: typo in __assign_irq_vector when updating pos for vector and offset [PATCH] x86-64: x86_64 hot-add memory srat.c fix [PATCH] i386: Update defconfig [PATCH] x86-64: Update defconfig
This commit is contained in:
commit
5d6aaf3f6d
24 changed files with 399 additions and 111 deletions
1
Makefile
1
Makefile
|
@ -499,6 +499,7 @@ endif
|
||||||
|
|
||||||
ifdef CONFIG_UNWIND_INFO
|
ifdef CONFIG_UNWIND_INFO
|
||||||
CFLAGS += -fasynchronous-unwind-tables
|
CFLAGS += -fasynchronous-unwind-tables
|
||||||
|
LDFLAGS_vmlinux += --eh-frame-hdr
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifdef CONFIG_DEBUG_INFO
|
ifdef CONFIG_DEBUG_INFO
|
||||||
|
|
|
@ -42,6 +42,10 @@ cflags-$(CONFIG_REGPARM) += -mregparm=3
|
||||||
# temporary until string.h is fixed
|
# temporary until string.h is fixed
|
||||||
cflags-y += -ffreestanding
|
cflags-y += -ffreestanding
|
||||||
|
|
||||||
|
# this works around some issues with generating unwind tables in older gccs
|
||||||
|
# newer gccs do it by default
|
||||||
|
cflags-y += -maccumulate-outgoing-args
|
||||||
|
|
||||||
# Disable unit-at-a-time mode on pre-gcc-4.0 compilers, it makes gcc use
|
# Disable unit-at-a-time mode on pre-gcc-4.0 compilers, it makes gcc use
|
||||||
# a lot more stack due to the lack of sharing of stacklots:
|
# a lot more stack due to the lack of sharing of stacklots:
|
||||||
CFLAGS += $(shell if [ $(call cc-version) -lt 0400 ] ; then echo $(call cc-option,-fno-unit-at-a-time); fi ;)
|
CFLAGS += $(shell if [ $(call cc-version) -lt 0400 ] ; then echo $(call cc-option,-fno-unit-at-a-time); fi ;)
|
||||||
|
@ -51,8 +55,8 @@ cflags-y += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
|
||||||
AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
|
AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
|
||||||
|
|
||||||
# is .cfi_signal_frame supported too?
|
# is .cfi_signal_frame supported too?
|
||||||
cflags-y += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
|
cflags-y += $(call as-instr,.cfi_startproc\n.cfi_signal_frame\n.cfi_endproc,-DCONFIG_AS_CFI_SIGNAL_FRAME=1,)
|
||||||
AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
|
AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_signal_frame\n.cfi_endproc,-DCONFIG_AS_CFI_SIGNAL_FRAME=1,)
|
||||||
|
|
||||||
CFLAGS += $(cflags-y)
|
CFLAGS += $(cflags-y)
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#
|
#
|
||||||
# Automatically generated make config: don't edit
|
# Automatically generated make config: don't edit
|
||||||
# Linux kernel version: 2.6.19-rc1
|
# Linux kernel version: 2.6.19-rc2-git4
|
||||||
# Thu Oct 5 13:04:53 2006
|
# Sat Oct 21 03:38:56 2006
|
||||||
#
|
#
|
||||||
CONFIG_X86_32=y
|
CONFIG_X86_32=y
|
||||||
CONFIG_GENERIC_TIME=y
|
CONFIG_GENERIC_TIME=y
|
||||||
|
@ -380,8 +380,8 @@ CONFIG_INET6_XFRM_MODE_TRANSPORT=y
|
||||||
CONFIG_INET6_XFRM_MODE_TUNNEL=y
|
CONFIG_INET6_XFRM_MODE_TUNNEL=y
|
||||||
# CONFIG_INET6_XFRM_MODE_BEET is not set
|
# CONFIG_INET6_XFRM_MODE_BEET is not set
|
||||||
# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
|
# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
|
||||||
|
CONFIG_IPV6_SIT=y
|
||||||
# CONFIG_IPV6_TUNNEL is not set
|
# CONFIG_IPV6_TUNNEL is not set
|
||||||
# CONFIG_IPV6_SUBTREES is not set
|
|
||||||
# CONFIG_IPV6_MULTIPLE_TABLES is not set
|
# CONFIG_IPV6_MULTIPLE_TABLES is not set
|
||||||
# CONFIG_NETWORK_SECMARK is not set
|
# CONFIG_NETWORK_SECMARK is not set
|
||||||
# CONFIG_NETFILTER is not set
|
# CONFIG_NETFILTER is not set
|
||||||
|
@ -482,6 +482,13 @@ CONFIG_BLK_DEV_INITRD=y
|
||||||
# CONFIG_CDROM_PKTCDVD is not set
|
# CONFIG_CDROM_PKTCDVD is not set
|
||||||
# CONFIG_ATA_OVER_ETH is not set
|
# CONFIG_ATA_OVER_ETH is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Misc devices
|
||||||
|
#
|
||||||
|
# CONFIG_IBM_ASM is not set
|
||||||
|
# CONFIG_SGI_IOC4 is not set
|
||||||
|
# CONFIG_TIFM_CORE is not set
|
||||||
|
|
||||||
#
|
#
|
||||||
# ATA/ATAPI/MFM/RLL support
|
# ATA/ATAPI/MFM/RLL support
|
||||||
#
|
#
|
||||||
|
@ -1024,6 +1031,7 @@ CONFIG_HANGCHECK_TIMER=y
|
||||||
#
|
#
|
||||||
# Dallas's 1-wire bus
|
# Dallas's 1-wire bus
|
||||||
#
|
#
|
||||||
|
# CONFIG_W1 is not set
|
||||||
|
|
||||||
#
|
#
|
||||||
# Hardware Monitoring support
|
# Hardware Monitoring support
|
||||||
|
@ -1031,12 +1039,6 @@ CONFIG_HANGCHECK_TIMER=y
|
||||||
# CONFIG_HWMON is not set
|
# CONFIG_HWMON is not set
|
||||||
# CONFIG_HWMON_VID is not set
|
# CONFIG_HWMON_VID is not set
|
||||||
|
|
||||||
#
|
|
||||||
# Misc devices
|
|
||||||
#
|
|
||||||
# CONFIG_IBM_ASM is not set
|
|
||||||
# CONFIG_TIFM_CORE is not set
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Multimedia devices
|
# Multimedia devices
|
||||||
#
|
#
|
||||||
|
@ -1169,7 +1171,6 @@ CONFIG_USB_HIDINPUT=y
|
||||||
# CONFIG_USB_ATI_REMOTE2 is not set
|
# CONFIG_USB_ATI_REMOTE2 is not set
|
||||||
# CONFIG_USB_KEYSPAN_REMOTE is not set
|
# CONFIG_USB_KEYSPAN_REMOTE is not set
|
||||||
# CONFIG_USB_APPLETOUCH is not set
|
# CONFIG_USB_APPLETOUCH is not set
|
||||||
# CONFIG_USB_TRANCEVIBRATOR is not set
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# USB Imaging devices
|
# USB Imaging devices
|
||||||
|
@ -1215,6 +1216,7 @@ CONFIG_USB_MON=y
|
||||||
# CONFIG_USB_APPLEDISPLAY is not set
|
# CONFIG_USB_APPLEDISPLAY is not set
|
||||||
# CONFIG_USB_SISUSBVGA is not set
|
# CONFIG_USB_SISUSBVGA is not set
|
||||||
# CONFIG_USB_LD is not set
|
# CONFIG_USB_LD is not set
|
||||||
|
# CONFIG_USB_TRANCEVIBRATOR is not set
|
||||||
# CONFIG_USB_TEST is not set
|
# CONFIG_USB_TEST is not set
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -1284,6 +1286,7 @@ CONFIG_EXT3_FS=y
|
||||||
CONFIG_EXT3_FS_XATTR=y
|
CONFIG_EXT3_FS_XATTR=y
|
||||||
CONFIG_EXT3_FS_POSIX_ACL=y
|
CONFIG_EXT3_FS_POSIX_ACL=y
|
||||||
# CONFIG_EXT3_FS_SECURITY is not set
|
# CONFIG_EXT3_FS_SECURITY is not set
|
||||||
|
# CONFIG_EXT4DEV_FS is not set
|
||||||
CONFIG_JBD=y
|
CONFIG_JBD=y
|
||||||
# CONFIG_JBD_DEBUG is not set
|
# CONFIG_JBD_DEBUG is not set
|
||||||
CONFIG_FS_MBCACHE=y
|
CONFIG_FS_MBCACHE=y
|
||||||
|
@ -1307,6 +1310,7 @@ CONFIG_DNOTIFY=y
|
||||||
# CONFIG_AUTOFS_FS is not set
|
# CONFIG_AUTOFS_FS is not set
|
||||||
CONFIG_AUTOFS4_FS=y
|
CONFIG_AUTOFS4_FS=y
|
||||||
# CONFIG_FUSE_FS is not set
|
# CONFIG_FUSE_FS is not set
|
||||||
|
CONFIG_GENERIC_ACL=y
|
||||||
|
|
||||||
#
|
#
|
||||||
# CD-ROM/DVD Filesystems
|
# CD-ROM/DVD Filesystems
|
||||||
|
@ -1384,7 +1388,6 @@ CONFIG_SUNRPC=y
|
||||||
# CONFIG_CODA_FS is not set
|
# CONFIG_CODA_FS is not set
|
||||||
# CONFIG_AFS_FS is not set
|
# CONFIG_AFS_FS is not set
|
||||||
# CONFIG_9P_FS is not set
|
# CONFIG_9P_FS is not set
|
||||||
CONFIG_GENERIC_ACL=y
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Partition Types
|
# Partition Types
|
||||||
|
@ -1436,10 +1439,6 @@ CONFIG_NLS_ISO8859_15=y
|
||||||
# CONFIG_NLS_KOI8_U is not set
|
# CONFIG_NLS_KOI8_U is not set
|
||||||
CONFIG_NLS_UTF8=y
|
CONFIG_NLS_UTF8=y
|
||||||
|
|
||||||
#
|
|
||||||
# Distributed Lock Manager
|
|
||||||
#
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Instrumentation Support
|
# Instrumentation Support
|
||||||
#
|
#
|
||||||
|
@ -1480,6 +1479,7 @@ CONFIG_DEBUG_BUGVERBOSE=y
|
||||||
CONFIG_UNWIND_INFO=y
|
CONFIG_UNWIND_INFO=y
|
||||||
CONFIG_STACK_UNWIND=y
|
CONFIG_STACK_UNWIND=y
|
||||||
# CONFIG_FORCED_INLINING is not set
|
# CONFIG_FORCED_INLINING is not set
|
||||||
|
# CONFIG_HEADERS_CHECK is not set
|
||||||
# CONFIG_RCU_TORTURE_TEST is not set
|
# CONFIG_RCU_TORTURE_TEST is not set
|
||||||
# CONFIG_LKDTM is not set
|
# CONFIG_LKDTM is not set
|
||||||
CONFIG_EARLY_PRINTK=y
|
CONFIG_EARLY_PRINTK=y
|
||||||
|
|
|
@ -317,7 +317,7 @@ is386: movl $2,%ecx # set MP
|
||||||
movl %eax,%gs
|
movl %eax,%gs
|
||||||
lldt %ax
|
lldt %ax
|
||||||
cld # gcc2 wants the direction flag cleared at all times
|
cld # gcc2 wants the direction flag cleared at all times
|
||||||
pushl %eax # fake return address
|
pushl $0 # fake return address for unwinder
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
movb ready, %cl
|
movb ready, %cl
|
||||||
movb $1, ready
|
movb $1, ready
|
||||||
|
|
|
@ -219,11 +219,11 @@ static int __init check_nmi_watchdog(void)
|
||||||
int cpu;
|
int cpu;
|
||||||
|
|
||||||
/* Enable NMI watchdog for newer systems.
|
/* Enable NMI watchdog for newer systems.
|
||||||
Actually it should be safe for most systems before 2004 too except
|
Probably safe on most older systems too, but let's be careful.
|
||||||
for some IBM systems that corrupt registers when NMI happens
|
IBM ThinkPads use INT10 inside SMM and that allows early NMI inside SMM
|
||||||
during SMM. Unfortunately we don't have more exact information
|
which hangs the system. Disable watchdog for all thinkpads */
|
||||||
on these and use this coarse check. */
|
if (nmi_watchdog == NMI_DEFAULT && dmi_get_year(DMI_BIOS_DATE) >= 2004 &&
|
||||||
if (nmi_watchdog == NMI_DEFAULT && dmi_get_year(DMI_BIOS_DATE) >= 2004)
|
!dmi_name_in_vendors("ThinkPad"))
|
||||||
nmi_watchdog = NMI_LOCAL_APIC;
|
nmi_watchdog = NMI_LOCAL_APIC;
|
||||||
|
|
||||||
if ((nmi_watchdog == NMI_NONE) || (nmi_watchdog == NMI_DEFAULT))
|
if ((nmi_watchdog == NMI_NONE) || (nmi_watchdog == NMI_DEFAULT))
|
||||||
|
|
|
@ -336,7 +336,6 @@ extern void kernel_thread_helper(void);
|
||||||
int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
|
int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
|
||||||
{
|
{
|
||||||
struct pt_regs regs;
|
struct pt_regs regs;
|
||||||
int err;
|
|
||||||
|
|
||||||
memset(®s, 0, sizeof(regs));
|
memset(®s, 0, sizeof(regs));
|
||||||
|
|
||||||
|
@ -351,10 +350,7 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
|
||||||
regs.eflags = X86_EFLAGS_IF | X86_EFLAGS_SF | X86_EFLAGS_PF | 0x2;
|
regs.eflags = X86_EFLAGS_IF | X86_EFLAGS_SF | X86_EFLAGS_PF | 0x2;
|
||||||
|
|
||||||
/* Ok, create the new process.. */
|
/* Ok, create the new process.. */
|
||||||
err = do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL);
|
return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL);
|
||||||
if (err == 0) /* terminate kernel stack */
|
|
||||||
task_pt_regs(current)->eip = 0;
|
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(kernel_thread);
|
EXPORT_SYMBOL(kernel_thread);
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,10 @@ endif
|
||||||
cflags-y += $(call cc-option,-funit-at-a-time)
|
cflags-y += $(call cc-option,-funit-at-a-time)
|
||||||
# prevent gcc from generating any FP code by mistake
|
# prevent gcc from generating any FP code by mistake
|
||||||
cflags-y += $(call cc-option,-mno-sse -mno-mmx -mno-sse2 -mno-3dnow,)
|
cflags-y += $(call cc-option,-mno-sse -mno-mmx -mno-sse2 -mno-3dnow,)
|
||||||
|
# this works around some issues with generating unwind tables in older gccs
|
||||||
|
# newer gccs do it by default
|
||||||
|
cflags-y += -maccumulate-outgoing-args
|
||||||
|
|
||||||
# do binutils support CFI?
|
# do binutils support CFI?
|
||||||
cflags-y += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
|
cflags-y += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
|
||||||
AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
|
AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#
|
#
|
||||||
# Automatically generated make config: don't edit
|
# Automatically generated make config: don't edit
|
||||||
# Linux kernel version: 2.6.19-rc1
|
# Linux kernel version: 2.6.19-rc2-git4
|
||||||
# Thu Oct 5 13:04:43 2006
|
# Sat Oct 21 03:38:52 2006
|
||||||
#
|
#
|
||||||
CONFIG_X86_64=y
|
CONFIG_X86_64=y
|
||||||
CONFIG_64BIT=y
|
CONFIG_64BIT=y
|
||||||
|
@ -335,8 +335,8 @@ CONFIG_IPV6=y
|
||||||
# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
|
# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
|
||||||
# CONFIG_INET6_XFRM_MODE_BEET is not set
|
# CONFIG_INET6_XFRM_MODE_BEET is not set
|
||||||
# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
|
# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
|
||||||
|
CONFIG_IPV6_SIT=y
|
||||||
# CONFIG_IPV6_TUNNEL is not set
|
# CONFIG_IPV6_TUNNEL is not set
|
||||||
# CONFIG_IPV6_SUBTREES is not set
|
|
||||||
# CONFIG_IPV6_MULTIPLE_TABLES is not set
|
# CONFIG_IPV6_MULTIPLE_TABLES is not set
|
||||||
# CONFIG_NETWORK_SECMARK is not set
|
# CONFIG_NETWORK_SECMARK is not set
|
||||||
# CONFIG_NETFILTER is not set
|
# CONFIG_NETFILTER is not set
|
||||||
|
@ -437,6 +437,13 @@ CONFIG_BLK_DEV_INITRD=y
|
||||||
# CONFIG_CDROM_PKTCDVD is not set
|
# CONFIG_CDROM_PKTCDVD is not set
|
||||||
# CONFIG_ATA_OVER_ETH is not set
|
# CONFIG_ATA_OVER_ETH is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Misc devices
|
||||||
|
#
|
||||||
|
# CONFIG_IBM_ASM is not set
|
||||||
|
# CONFIG_SGI_IOC4 is not set
|
||||||
|
# CONFIG_TIFM_CORE is not set
|
||||||
|
|
||||||
#
|
#
|
||||||
# ATA/ATAPI/MFM/RLL support
|
# ATA/ATAPI/MFM/RLL support
|
||||||
#
|
#
|
||||||
|
@ -1008,6 +1015,7 @@ CONFIG_I2C_ISA=m
|
||||||
#
|
#
|
||||||
# Dallas's 1-wire bus
|
# Dallas's 1-wire bus
|
||||||
#
|
#
|
||||||
|
# CONFIG_W1 is not set
|
||||||
|
|
||||||
#
|
#
|
||||||
# Hardware Monitoring support
|
# Hardware Monitoring support
|
||||||
|
@ -1058,12 +1066,6 @@ CONFIG_SENSORS_SMSC47B397=m
|
||||||
# CONFIG_SENSORS_HDAPS is not set
|
# CONFIG_SENSORS_HDAPS is not set
|
||||||
# CONFIG_HWMON_DEBUG_CHIP is not set
|
# CONFIG_HWMON_DEBUG_CHIP is not set
|
||||||
|
|
||||||
#
|
|
||||||
# Misc devices
|
|
||||||
#
|
|
||||||
# CONFIG_IBM_ASM is not set
|
|
||||||
# CONFIG_TIFM_CORE is not set
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Multimedia devices
|
# Multimedia devices
|
||||||
#
|
#
|
||||||
|
@ -1196,7 +1198,6 @@ CONFIG_USB_HIDINPUT=y
|
||||||
# CONFIG_USB_ATI_REMOTE2 is not set
|
# CONFIG_USB_ATI_REMOTE2 is not set
|
||||||
# CONFIG_USB_KEYSPAN_REMOTE is not set
|
# CONFIG_USB_KEYSPAN_REMOTE is not set
|
||||||
# CONFIG_USB_APPLETOUCH is not set
|
# CONFIG_USB_APPLETOUCH is not set
|
||||||
# CONFIG_USB_TRANCEVIBRATOR is not set
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# USB Imaging devices
|
# USB Imaging devices
|
||||||
|
@ -1242,6 +1243,7 @@ CONFIG_USB_MON=y
|
||||||
# CONFIG_USB_APPLEDISPLAY is not set
|
# CONFIG_USB_APPLEDISPLAY is not set
|
||||||
# CONFIG_USB_SISUSBVGA is not set
|
# CONFIG_USB_SISUSBVGA is not set
|
||||||
# CONFIG_USB_LD is not set
|
# CONFIG_USB_LD is not set
|
||||||
|
# CONFIG_USB_TRANCEVIBRATOR is not set
|
||||||
# CONFIG_USB_TEST is not set
|
# CONFIG_USB_TEST is not set
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -1318,6 +1320,7 @@ CONFIG_EXT3_FS=y
|
||||||
CONFIG_EXT3_FS_XATTR=y
|
CONFIG_EXT3_FS_XATTR=y
|
||||||
CONFIG_EXT3_FS_POSIX_ACL=y
|
CONFIG_EXT3_FS_POSIX_ACL=y
|
||||||
# CONFIG_EXT3_FS_SECURITY is not set
|
# CONFIG_EXT3_FS_SECURITY is not set
|
||||||
|
# CONFIG_EXT4DEV_FS is not set
|
||||||
CONFIG_JBD=y
|
CONFIG_JBD=y
|
||||||
# CONFIG_JBD_DEBUG is not set
|
# CONFIG_JBD_DEBUG is not set
|
||||||
CONFIG_FS_MBCACHE=y
|
CONFIG_FS_MBCACHE=y
|
||||||
|
@ -1341,6 +1344,7 @@ CONFIG_DNOTIFY=y
|
||||||
# CONFIG_AUTOFS_FS is not set
|
# CONFIG_AUTOFS_FS is not set
|
||||||
CONFIG_AUTOFS4_FS=y
|
CONFIG_AUTOFS4_FS=y
|
||||||
# CONFIG_FUSE_FS is not set
|
# CONFIG_FUSE_FS is not set
|
||||||
|
CONFIG_GENERIC_ACL=y
|
||||||
|
|
||||||
#
|
#
|
||||||
# CD-ROM/DVD Filesystems
|
# CD-ROM/DVD Filesystems
|
||||||
|
@ -1418,7 +1422,6 @@ CONFIG_SUNRPC=y
|
||||||
# CONFIG_CODA_FS is not set
|
# CONFIG_CODA_FS is not set
|
||||||
# CONFIG_AFS_FS is not set
|
# CONFIG_AFS_FS is not set
|
||||||
# CONFIG_9P_FS is not set
|
# CONFIG_9P_FS is not set
|
||||||
CONFIG_GENERIC_ACL=y
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Partition Types
|
# Partition Types
|
||||||
|
@ -1470,10 +1473,6 @@ CONFIG_NLS_ISO8859_15=y
|
||||||
# CONFIG_NLS_KOI8_U is not set
|
# CONFIG_NLS_KOI8_U is not set
|
||||||
CONFIG_NLS_UTF8=y
|
CONFIG_NLS_UTF8=y
|
||||||
|
|
||||||
#
|
|
||||||
# Distributed Lock Manager
|
|
||||||
#
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Instrumentation Support
|
# Instrumentation Support
|
||||||
#
|
#
|
||||||
|
@ -1512,6 +1511,7 @@ CONFIG_DEBUG_FS=y
|
||||||
CONFIG_UNWIND_INFO=y
|
CONFIG_UNWIND_INFO=y
|
||||||
CONFIG_STACK_UNWIND=y
|
CONFIG_STACK_UNWIND=y
|
||||||
# CONFIG_FORCED_INLINING is not set
|
# CONFIG_FORCED_INLINING is not set
|
||||||
|
# CONFIG_HEADERS_CHECK is not set
|
||||||
# CONFIG_RCU_TORTURE_TEST is not set
|
# CONFIG_RCU_TORTURE_TEST is not set
|
||||||
# CONFIG_LKDTM is not set
|
# CONFIG_LKDTM is not set
|
||||||
# CONFIG_DEBUG_RODATA is not set
|
# CONFIG_DEBUG_RODATA is not set
|
||||||
|
|
|
@ -54,13 +54,13 @@ static inline int bad_addr(unsigned long *addrp, unsigned long size)
|
||||||
|
|
||||||
/* various gunk below that needed for SMP startup */
|
/* various gunk below that needed for SMP startup */
|
||||||
if (addr < 0x8000) {
|
if (addr < 0x8000) {
|
||||||
*addrp = 0x8000;
|
*addrp = PAGE_ALIGN(0x8000);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* direct mapping tables of the kernel */
|
/* direct mapping tables of the kernel */
|
||||||
if (last >= table_start<<PAGE_SHIFT && addr < table_end<<PAGE_SHIFT) {
|
if (last >= table_start<<PAGE_SHIFT && addr < table_end<<PAGE_SHIFT) {
|
||||||
*addrp = table_end << PAGE_SHIFT;
|
*addrp = PAGE_ALIGN(table_end << PAGE_SHIFT);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,18 +68,18 @@ static inline int bad_addr(unsigned long *addrp, unsigned long size)
|
||||||
#ifdef CONFIG_BLK_DEV_INITRD
|
#ifdef CONFIG_BLK_DEV_INITRD
|
||||||
if (LOADER_TYPE && INITRD_START && last >= INITRD_START &&
|
if (LOADER_TYPE && INITRD_START && last >= INITRD_START &&
|
||||||
addr < INITRD_START+INITRD_SIZE) {
|
addr < INITRD_START+INITRD_SIZE) {
|
||||||
*addrp = INITRD_START + INITRD_SIZE;
|
*addrp = PAGE_ALIGN(INITRD_START + INITRD_SIZE);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
/* kernel code */
|
/* kernel code */
|
||||||
if (last >= __pa_symbol(&_text) && last < __pa_symbol(&_end)) {
|
if (last >= __pa_symbol(&_text) && addr < __pa_symbol(&_end)) {
|
||||||
*addrp = __pa_symbol(&_end);
|
*addrp = PAGE_ALIGN(__pa_symbol(&_end));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (last >= ebda_addr && addr < ebda_addr + ebda_size) {
|
if (last >= ebda_addr && addr < ebda_addr + ebda_size) {
|
||||||
*addrp = ebda_addr + ebda_size;
|
*addrp = PAGE_ALIGN(ebda_addr + ebda_size);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,7 +152,7 @@ unsigned long __init find_e820_area(unsigned long start, unsigned long end, unsi
|
||||||
continue;
|
continue;
|
||||||
while (bad_addr(&addr, size) && addr+size <= ei->addr+ei->size)
|
while (bad_addr(&addr, size) && addr+size <= ei->addr+ei->size)
|
||||||
;
|
;
|
||||||
last = addr + size;
|
last = PAGE_ALIGN(addr) + size;
|
||||||
if (last > ei->addr + ei->size)
|
if (last > ei->addr + ei->size)
|
||||||
continue;
|
continue;
|
||||||
if (last > end)
|
if (last > end)
|
||||||
|
|
|
@ -61,10 +61,11 @@ static void nvidia_bugs(void)
|
||||||
|
|
||||||
static void ati_bugs(void)
|
static void ati_bugs(void)
|
||||||
{
|
{
|
||||||
#if 1 /* for testing */
|
if (timer_over_8254 == 1) {
|
||||||
printk("ATI board detected\n");
|
timer_over_8254 = 0;
|
||||||
#endif
|
printk(KERN_INFO
|
||||||
/* No bugs right now */
|
"ATI board detected. Disabling timer routing over 8254.\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct chipset {
|
struct chipset {
|
||||||
|
|
|
@ -315,6 +315,8 @@ tracesys:
|
||||||
LOAD_ARGS ARGOFFSET /* reload args from stack in case ptrace changed it */
|
LOAD_ARGS ARGOFFSET /* reload args from stack in case ptrace changed it */
|
||||||
RESTORE_REST
|
RESTORE_REST
|
||||||
cmpq $__NR_syscall_max,%rax
|
cmpq $__NR_syscall_max,%rax
|
||||||
|
movq $-ENOSYS,%rcx
|
||||||
|
cmova %rcx,%rax
|
||||||
ja 1f
|
ja 1f
|
||||||
movq %r10,%rcx /* fixup for C */
|
movq %r10,%rcx /* fixup for C */
|
||||||
call *sys_call_table(,%rax,8)
|
call *sys_call_table(,%rax,8)
|
||||||
|
@ -535,8 +537,6 @@ END(stub_rt_sigreturn)
|
||||||
1: incl %gs:pda_irqcount
|
1: incl %gs:pda_irqcount
|
||||||
cmoveq %gs:pda_irqstackptr,%rsp
|
cmoveq %gs:pda_irqstackptr,%rsp
|
||||||
push %rbp # backlink for old unwinder
|
push %rbp # backlink for old unwinder
|
||||||
CFI_ADJUST_CFA_OFFSET 8
|
|
||||||
CFI_REL_OFFSET rbp,0
|
|
||||||
/*
|
/*
|
||||||
* We entered an interrupt context - irqs are off:
|
* We entered an interrupt context - irqs are off:
|
||||||
*/
|
*/
|
||||||
|
@ -980,11 +980,6 @@ ENTRY(kernel_thread)
|
||||||
call do_fork
|
call do_fork
|
||||||
movq %rax,RAX(%rsp)
|
movq %rax,RAX(%rsp)
|
||||||
xorl %edi,%edi
|
xorl %edi,%edi
|
||||||
test %rax,%rax
|
|
||||||
jnz 1f
|
|
||||||
/* terminate stack in child */
|
|
||||||
movq %rdi,RIP(%rsp)
|
|
||||||
1:
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* It isn't worth to check for reschedule here,
|
* It isn't worth to check for reschedule here,
|
||||||
|
@ -1176,7 +1171,6 @@ ENTRY(call_softirq)
|
||||||
incl %gs:pda_irqcount
|
incl %gs:pda_irqcount
|
||||||
cmove %gs:pda_irqstackptr,%rsp
|
cmove %gs:pda_irqstackptr,%rsp
|
||||||
push %rbp # backlink for old unwinder
|
push %rbp # backlink for old unwinder
|
||||||
CFI_ADJUST_CFA_OFFSET 8
|
|
||||||
call __do_softirq
|
call __do_softirq
|
||||||
leaveq
|
leaveq
|
||||||
CFI_DEF_CFA_REGISTER rsp
|
CFI_DEF_CFA_REGISTER rsp
|
||||||
|
|
|
@ -153,7 +153,7 @@ struct genapic apic_flat = {
|
||||||
|
|
||||||
static cpumask_t physflat_target_cpus(void)
|
static cpumask_t physflat_target_cpus(void)
|
||||||
{
|
{
|
||||||
return cpumask_of_cpu(0);
|
return cpu_online_map;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cpumask_t physflat_vector_allocation_domain(int cpu)
|
static cpumask_t physflat_vector_allocation_domain(int cpu)
|
||||||
|
|
|
@ -57,7 +57,7 @@ static int no_timer_check;
|
||||||
|
|
||||||
static int disable_timer_pin_1 __initdata;
|
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 */
|
/* Where if anywhere is the i8259 connect in external int mode */
|
||||||
static struct { int pin, apic; } ioapic_i8259 = { -1, -1 };
|
static struct { int pin, apic; } ioapic_i8259 = { -1, -1 };
|
||||||
|
@ -651,12 +651,12 @@ next:
|
||||||
if (vector == IA32_SYSCALL_VECTOR)
|
if (vector == IA32_SYSCALL_VECTOR)
|
||||||
goto next;
|
goto next;
|
||||||
for_each_cpu_mask(new_cpu, domain)
|
for_each_cpu_mask(new_cpu, domain)
|
||||||
if (per_cpu(vector_irq, cpu)[vector] != -1)
|
if (per_cpu(vector_irq, new_cpu)[vector] != -1)
|
||||||
goto next;
|
goto next;
|
||||||
/* Found one! */
|
/* Found one! */
|
||||||
for_each_cpu_mask(new_cpu, domain) {
|
for_each_cpu_mask(new_cpu, domain) {
|
||||||
pos[cpu].vector = vector;
|
pos[new_cpu].vector = vector;
|
||||||
pos[cpu].offset = offset;
|
pos[new_cpu].offset = offset;
|
||||||
}
|
}
|
||||||
if (old_vector >= 0) {
|
if (old_vector >= 0) {
|
||||||
int old_cpu;
|
int old_cpu;
|
||||||
|
@ -1255,12 +1255,15 @@ static int ioapic_retrigger_irq(unsigned int irq)
|
||||||
{
|
{
|
||||||
cpumask_t mask;
|
cpumask_t mask;
|
||||||
unsigned vector;
|
unsigned vector;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&vector_lock, flags);
|
||||||
vector = irq_vector[irq];
|
vector = irq_vector[irq];
|
||||||
cpus_clear(mask);
|
cpus_clear(mask);
|
||||||
cpu_set(vector >> 8, mask);
|
cpu_set(first_cpu(irq_domain[irq]), mask);
|
||||||
|
|
||||||
send_IPI_mask(mask, vector & 0xff);
|
send_IPI_mask(mask, vector);
|
||||||
|
spin_unlock_irqrestore(&vector_lock, flags);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ PHDRS {
|
||||||
text PT_LOAD FLAGS(5); /* R_E */
|
text PT_LOAD FLAGS(5); /* R_E */
|
||||||
data PT_LOAD FLAGS(7); /* RWE */
|
data PT_LOAD FLAGS(7); /* RWE */
|
||||||
user PT_LOAD FLAGS(7); /* RWE */
|
user PT_LOAD FLAGS(7); /* RWE */
|
||||||
|
data.init PT_LOAD FLAGS(7); /* RWE */
|
||||||
note PT_NOTE FLAGS(4); /* R__ */
|
note PT_NOTE FLAGS(4); /* R__ */
|
||||||
}
|
}
|
||||||
SECTIONS
|
SECTIONS
|
||||||
|
@ -131,7 +132,7 @@ SECTIONS
|
||||||
. = ALIGN(8192); /* init_task */
|
. = ALIGN(8192); /* init_task */
|
||||||
.data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
|
.data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
|
||||||
*(.data.init_task)
|
*(.data.init_task)
|
||||||
} :data
|
}:data.init
|
||||||
|
|
||||||
. = ALIGN(4096);
|
. = ALIGN(4096);
|
||||||
.data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
|
.data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
|
||||||
|
|
|
@ -207,7 +207,7 @@ static inline int save_add_info(void)
|
||||||
return hotadd_percent > 0;
|
return hotadd_percent > 0;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
int update_end_of_memory(unsigned long end) {return 0;}
|
int update_end_of_memory(unsigned long end) {return -1;}
|
||||||
static int hotadd_enough_memory(struct bootnode *nd) {return 1;}
|
static int hotadd_enough_memory(struct bootnode *nd) {return 1;}
|
||||||
#ifdef CONFIG_MEMORY_HOTPLUG_SPARSE
|
#ifdef CONFIG_MEMORY_HOTPLUG_SPARSE
|
||||||
static inline int save_add_info(void) {return 1;}
|
static inline int save_add_info(void) {return 1;}
|
||||||
|
@ -337,7 +337,7 @@ acpi_numa_memory_affinity_init(struct acpi_table_memory_affinity *ma)
|
||||||
push_node_boundaries(node, nd->start >> PAGE_SHIFT,
|
push_node_boundaries(node, nd->start >> PAGE_SHIFT,
|
||||||
nd->end >> PAGE_SHIFT);
|
nd->end >> PAGE_SHIFT);
|
||||||
|
|
||||||
if (ma->flags.hot_pluggable && !reserve_hotadd(node, start, end) < 0) {
|
if (ma->flags.hot_pluggable && (reserve_hotadd(node, start, end) < 0)) {
|
||||||
/* Ignore hotadd region. Undo damage */
|
/* Ignore hotadd region. Undo damage */
|
||||||
printk(KERN_NOTICE "SRAT: Hotplug region ignored\n");
|
printk(KERN_NOTICE "SRAT: Hotplug region ignored\n");
|
||||||
*nd = oldnode;
|
*nd = oldnode;
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
#
|
#
|
||||||
# Reuse the i386 PCI subsystem
|
# Reuse the i386 PCI subsystem
|
||||||
#
|
#
|
||||||
CFLAGS += -Iarch/i386/pci
|
EXTRA_CFLAGS += -Iarch/i386/pci
|
||||||
|
|
||||||
obj-y := i386.o
|
obj-y := i386.o
|
||||||
obj-$(CONFIG_PCI_DIRECT)+= direct.o
|
obj-$(CONFIG_PCI_DIRECT)+= direct.o
|
||||||
|
|
|
@ -326,6 +326,26 @@ char *dmi_get_system_info(int field)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(dmi_get_system_info);
|
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
|
* dmi_find_device - find onboard device by type/name
|
||||||
* @type: device type or %DMI_DEV_TYPE_ANY to match all device types
|
* @type: device type or %DMI_DEV_TYPE_ANY to match all device types
|
||||||
|
|
|
@ -125,6 +125,10 @@
|
||||||
*(__param) \
|
*(__param) \
|
||||||
VMLINUX_SYMBOL(__stop___param) = .; \
|
VMLINUX_SYMBOL(__stop___param) = .; \
|
||||||
} \
|
} \
|
||||||
|
\
|
||||||
|
/* Unwind data binary search table */ \
|
||||||
|
EH_FRAME_HDR \
|
||||||
|
\
|
||||||
__end_rodata = .; \
|
__end_rodata = .; \
|
||||||
. = ALIGN(4096);
|
. = ALIGN(4096);
|
||||||
|
|
||||||
|
@ -157,6 +161,18 @@
|
||||||
*(.kprobes.text) \
|
*(.kprobes.text) \
|
||||||
VMLINUX_SYMBOL(__kprobes_text_end) = .;
|
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.
|
/* DWARF debug sections.
|
||||||
Symbols in the DWARF debugging sections are relative to
|
Symbols in the DWARF debugging sections are relative to
|
||||||
the beginning of the section so we begin them at 0. */
|
the beginning of the section so we begin them at 0. */
|
||||||
|
|
|
@ -366,6 +366,7 @@ static inline pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot)
|
||||||
{
|
{
|
||||||
pte_t pte;
|
pte_t pte;
|
||||||
pte_val(pte) = physpage | pgprot_val(pgprot);
|
pte_val(pte) = physpage | pgprot_val(pgprot);
|
||||||
|
pte_val(pte) &= __supported_pte_mask;
|
||||||
return pte;
|
return pte;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -122,6 +122,8 @@ extern int fix_aperture;
|
||||||
extern int reboot_force;
|
extern int reboot_force;
|
||||||
extern int notsc_setup(char *);
|
extern int notsc_setup(char *);
|
||||||
|
|
||||||
|
extern int timer_over_8254;
|
||||||
|
|
||||||
extern int gsi_irq_sharing(int gsi);
|
extern int gsi_irq_sharing(int gsi);
|
||||||
|
|
||||||
extern void smp_local_timer_interrupt(void);
|
extern void smp_local_timer_interrupt(void);
|
||||||
|
|
|
@ -69,6 +69,7 @@ extern struct dmi_device * dmi_find_device(int type, const char *name,
|
||||||
struct dmi_device *from);
|
struct dmi_device *from);
|
||||||
extern void dmi_scan_machine(void);
|
extern void dmi_scan_machine(void);
|
||||||
extern int dmi_get_year(int field);
|
extern int dmi_get_year(int field);
|
||||||
|
extern int dmi_name_in_vendors(char *str);
|
||||||
|
|
||||||
#else
|
#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,
|
static inline struct dmi_device * dmi_find_device(int type, const char *name,
|
||||||
struct dmi_device *from) { return NULL; }
|
struct dmi_device *from) { return NULL; }
|
||||||
static inline int dmi_get_year(int year) { return 0; }
|
static inline int dmi_get_year(int year) { return 0; }
|
||||||
|
static inline int dmi_name_in_vendors(char *s) { return 0; }
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@ struct module;
|
||||||
* Initialize unwind support.
|
* Initialize unwind support.
|
||||||
*/
|
*/
|
||||||
extern void unwind_init(void);
|
extern void unwind_init(void);
|
||||||
|
extern void unwind_setup(void);
|
||||||
|
|
||||||
#ifdef CONFIG_MODULES
|
#ifdef CONFIG_MODULES
|
||||||
|
|
||||||
|
@ -73,6 +74,7 @@ extern int unwind_to_user(struct unwind_frame_info *);
|
||||||
struct unwind_frame_info {};
|
struct unwind_frame_info {};
|
||||||
|
|
||||||
static inline void unwind_init(void) {}
|
static inline void unwind_init(void) {}
|
||||||
|
static inline void unwind_setup(void) {}
|
||||||
|
|
||||||
#ifdef CONFIG_MODULES
|
#ifdef CONFIG_MODULES
|
||||||
|
|
||||||
|
|
|
@ -503,6 +503,7 @@ asmlinkage void __init start_kernel(void)
|
||||||
printk(KERN_NOTICE);
|
printk(KERN_NOTICE);
|
||||||
printk(linux_banner);
|
printk(linux_banner);
|
||||||
setup_arch(&command_line);
|
setup_arch(&command_line);
|
||||||
|
unwind_setup();
|
||||||
setup_per_cpu_areas();
|
setup_per_cpu_areas();
|
||||||
smp_prepare_boot_cpu(); /* arch-specific boot-cpu hooks */
|
smp_prepare_boot_cpu(); /* arch-specific boot-cpu hooks */
|
||||||
|
|
||||||
|
|
294
kernel/unwind.c
294
kernel/unwind.c
|
@ -11,13 +11,15 @@
|
||||||
|
|
||||||
#include <linux/unwind.h>
|
#include <linux/unwind.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/bootmem.h>
|
||||||
|
#include <linux/sort.h>
|
||||||
#include <linux/stop_machine.h>
|
#include <linux/stop_machine.h>
|
||||||
#include <asm/sections.h>
|
#include <asm/sections.h>
|
||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
#include <asm/unaligned.h>
|
#include <asm/unaligned.h>
|
||||||
|
|
||||||
extern char __start_unwind[], __end_unwind[];
|
extern char __start_unwind[], __end_unwind[];
|
||||||
|
extern const u8 __start_unwind_hdr[], __end_unwind_hdr[];
|
||||||
|
|
||||||
#define MAX_STACK_DEPTH 8
|
#define MAX_STACK_DEPTH 8
|
||||||
|
|
||||||
|
@ -100,6 +102,8 @@ static struct unwind_table {
|
||||||
} core, init;
|
} core, init;
|
||||||
const void *address;
|
const void *address;
|
||||||
unsigned long size;
|
unsigned long size;
|
||||||
|
const unsigned char *header;
|
||||||
|
unsigned long hdrsz;
|
||||||
struct unwind_table *link;
|
struct unwind_table *link;
|
||||||
const char *name;
|
const char *name;
|
||||||
} root_table;
|
} root_table;
|
||||||
|
@ -145,6 +149,10 @@ static struct unwind_table *find_table(unsigned long pc)
|
||||||
return table;
|
return table;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned long read_pointer(const u8 **pLoc,
|
||||||
|
const void *end,
|
||||||
|
signed ptrType);
|
||||||
|
|
||||||
static void init_unwind_table(struct unwind_table *table,
|
static void init_unwind_table(struct unwind_table *table,
|
||||||
const char *name,
|
const char *name,
|
||||||
const void *core_start,
|
const void *core_start,
|
||||||
|
@ -152,14 +160,30 @@ static void init_unwind_table(struct unwind_table *table,
|
||||||
const void *init_start,
|
const void *init_start,
|
||||||
unsigned long init_size,
|
unsigned long init_size,
|
||||||
const void *table_start,
|
const void *table_start,
|
||||||
unsigned long table_size)
|
unsigned long table_size,
|
||||||
|
const u8 *header_start,
|
||||||
|
unsigned long header_size)
|
||||||
{
|
{
|
||||||
|
const u8 *ptr = header_start + 4;
|
||||||
|
const u8 *end = header_start + header_size;
|
||||||
|
|
||||||
table->core.pc = (unsigned long)core_start;
|
table->core.pc = (unsigned long)core_start;
|
||||||
table->core.range = core_size;
|
table->core.range = core_size;
|
||||||
table->init.pc = (unsigned long)init_start;
|
table->init.pc = (unsigned long)init_start;
|
||||||
table->init.range = init_size;
|
table->init.range = init_size;
|
||||||
table->address = table_start;
|
table->address = table_start;
|
||||||
table->size = table_size;
|
table->size = table_size;
|
||||||
|
/* See if the linker provided table looks valid. */
|
||||||
|
if (header_size <= 4
|
||||||
|
|| header_start[0] != 1
|
||||||
|
|| (void *)read_pointer(&ptr, end, header_start[1]) != table_start
|
||||||
|
|| header_start[2] == DW_EH_PE_omit
|
||||||
|
|| read_pointer(&ptr, end, header_start[2]) <= 0
|
||||||
|
|| header_start[3] == DW_EH_PE_omit)
|
||||||
|
header_start = NULL;
|
||||||
|
table->hdrsz = header_size;
|
||||||
|
smp_wmb();
|
||||||
|
table->header = header_start;
|
||||||
table->link = NULL;
|
table->link = NULL;
|
||||||
table->name = name;
|
table->name = name;
|
||||||
}
|
}
|
||||||
|
@ -169,7 +193,143 @@ void __init unwind_init(void)
|
||||||
init_unwind_table(&root_table, "kernel",
|
init_unwind_table(&root_table, "kernel",
|
||||||
_text, _end - _text,
|
_text, _end - _text,
|
||||||
NULL, 0,
|
NULL, 0,
|
||||||
__start_unwind, __end_unwind - __start_unwind);
|
__start_unwind, __end_unwind - __start_unwind,
|
||||||
|
__start_unwind_hdr, __end_unwind_hdr - __start_unwind_hdr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const u32 bad_cie, not_fde;
|
||||||
|
static const u32 *cie_for_fde(const u32 *fde, const struct unwind_table *);
|
||||||
|
static signed fde_pointer_type(const u32 *cie);
|
||||||
|
|
||||||
|
struct eh_frame_hdr_table_entry {
|
||||||
|
unsigned long start, fde;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int cmp_eh_frame_hdr_table_entries(const void *p1, const void *p2)
|
||||||
|
{
|
||||||
|
const struct eh_frame_hdr_table_entry *e1 = p1;
|
||||||
|
const struct eh_frame_hdr_table_entry *e2 = p2;
|
||||||
|
|
||||||
|
return (e1->start > e2->start) - (e1->start < e2->start);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void swap_eh_frame_hdr_table_entries(void *p1, void *p2, int size)
|
||||||
|
{
|
||||||
|
struct eh_frame_hdr_table_entry *e1 = p1;
|
||||||
|
struct eh_frame_hdr_table_entry *e2 = p2;
|
||||||
|
unsigned long v;
|
||||||
|
|
||||||
|
v = e1->start;
|
||||||
|
e1->start = e2->start;
|
||||||
|
e2->start = v;
|
||||||
|
v = e1->fde;
|
||||||
|
e1->fde = e2->fde;
|
||||||
|
e2->fde = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __init setup_unwind_table(struct unwind_table *table,
|
||||||
|
void *(*alloc)(unsigned long))
|
||||||
|
{
|
||||||
|
const u8 *ptr;
|
||||||
|
unsigned long tableSize = table->size, hdrSize;
|
||||||
|
unsigned n;
|
||||||
|
const u32 *fde;
|
||||||
|
struct {
|
||||||
|
u8 version;
|
||||||
|
u8 eh_frame_ptr_enc;
|
||||||
|
u8 fde_count_enc;
|
||||||
|
u8 table_enc;
|
||||||
|
unsigned long eh_frame_ptr;
|
||||||
|
unsigned int fde_count;
|
||||||
|
struct eh_frame_hdr_table_entry table[];
|
||||||
|
} __attribute__((__packed__)) *header;
|
||||||
|
|
||||||
|
if (table->header)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (table->hdrsz)
|
||||||
|
printk(KERN_WARNING ".eh_frame_hdr for '%s' present but unusable\n",
|
||||||
|
table->name);
|
||||||
|
|
||||||
|
if (tableSize & (sizeof(*fde) - 1))
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (fde = table->address, n = 0;
|
||||||
|
tableSize > sizeof(*fde) && tableSize - sizeof(*fde) >= *fde;
|
||||||
|
tableSize -= sizeof(*fde) + *fde, fde += 1 + *fde / sizeof(*fde)) {
|
||||||
|
const u32 *cie = cie_for_fde(fde, table);
|
||||||
|
signed ptrType;
|
||||||
|
|
||||||
|
if (cie == ¬_fde)
|
||||||
|
continue;
|
||||||
|
if (cie == NULL
|
||||||
|
|| cie == &bad_cie
|
||||||
|
|| (ptrType = fde_pointer_type(cie)) < 0)
|
||||||
|
return;
|
||||||
|
ptr = (const u8 *)(fde + 2);
|
||||||
|
if (!read_pointer(&ptr,
|
||||||
|
(const u8 *)(fde + 1) + *fde,
|
||||||
|
ptrType))
|
||||||
|
return;
|
||||||
|
++n;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tableSize || !n)
|
||||||
|
return;
|
||||||
|
|
||||||
|
hdrSize = 4 + sizeof(unsigned long) + sizeof(unsigned int)
|
||||||
|
+ 2 * n * sizeof(unsigned long);
|
||||||
|
header = alloc(hdrSize);
|
||||||
|
if (!header)
|
||||||
|
return;
|
||||||
|
header->version = 1;
|
||||||
|
header->eh_frame_ptr_enc = DW_EH_PE_abs|DW_EH_PE_native;
|
||||||
|
header->fde_count_enc = DW_EH_PE_abs|DW_EH_PE_data4;
|
||||||
|
header->table_enc = DW_EH_PE_abs|DW_EH_PE_native;
|
||||||
|
put_unaligned((unsigned long)table->address, &header->eh_frame_ptr);
|
||||||
|
BUILD_BUG_ON(offsetof(typeof(*header), fde_count)
|
||||||
|
% __alignof(typeof(header->fde_count)));
|
||||||
|
header->fde_count = n;
|
||||||
|
|
||||||
|
BUILD_BUG_ON(offsetof(typeof(*header), table)
|
||||||
|
% __alignof(typeof(*header->table)));
|
||||||
|
for (fde = table->address, tableSize = table->size, n = 0;
|
||||||
|
tableSize;
|
||||||
|
tableSize -= sizeof(*fde) + *fde, fde += 1 + *fde / sizeof(*fde)) {
|
||||||
|
const u32 *cie = fde + 1 - fde[1] / sizeof(*fde);
|
||||||
|
|
||||||
|
if (!fde[1])
|
||||||
|
continue; /* this is a CIE */
|
||||||
|
ptr = (const u8 *)(fde + 2);
|
||||||
|
header->table[n].start = read_pointer(&ptr,
|
||||||
|
(const u8 *)(fde + 1) + *fde,
|
||||||
|
fde_pointer_type(cie));
|
||||||
|
header->table[n].fde = (unsigned long)fde;
|
||||||
|
++n;
|
||||||
|
}
|
||||||
|
WARN_ON(n != header->fde_count);
|
||||||
|
|
||||||
|
sort(header->table,
|
||||||
|
n,
|
||||||
|
sizeof(*header->table),
|
||||||
|
cmp_eh_frame_hdr_table_entries,
|
||||||
|
swap_eh_frame_hdr_table_entries);
|
||||||
|
|
||||||
|
table->hdrsz = hdrSize;
|
||||||
|
smp_wmb();
|
||||||
|
table->header = (const void *)header;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *__init balloc(unsigned long sz)
|
||||||
|
{
|
||||||
|
return __alloc_bootmem_nopanic(sz,
|
||||||
|
sizeof(unsigned int),
|
||||||
|
__pa(MAX_DMA_ADDRESS));
|
||||||
|
}
|
||||||
|
|
||||||
|
void __init unwind_setup(void)
|
||||||
|
{
|
||||||
|
setup_unwind_table(&root_table, balloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_MODULES
|
#ifdef CONFIG_MODULES
|
||||||
|
@ -193,7 +353,8 @@ void *unwind_add_table(struct module *module,
|
||||||
init_unwind_table(table, module->name,
|
init_unwind_table(table, module->name,
|
||||||
module->module_core, module->core_size,
|
module->module_core, module->core_size,
|
||||||
module->module_init, module->init_size,
|
module->module_init, module->init_size,
|
||||||
table_start, table_size);
|
table_start, table_size,
|
||||||
|
NULL, 0);
|
||||||
|
|
||||||
if (last_table)
|
if (last_table)
|
||||||
last_table->link = table;
|
last_table->link = table;
|
||||||
|
@ -303,6 +464,26 @@ static sleb128_t get_sleb128(const u8 **pcur, const u8 *end)
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const u32 *cie_for_fde(const u32 *fde, const struct unwind_table *table)
|
||||||
|
{
|
||||||
|
const u32 *cie;
|
||||||
|
|
||||||
|
if (!*fde || (*fde & (sizeof(*fde) - 1)))
|
||||||
|
return &bad_cie;
|
||||||
|
if (!fde[1])
|
||||||
|
return ¬_fde; /* this is a CIE */
|
||||||
|
if ((fde[1] & (sizeof(*fde) - 1))
|
||||||
|
|| fde[1] > (unsigned long)(fde + 1) - (unsigned long)table->address)
|
||||||
|
return NULL; /* this is not a valid FDE */
|
||||||
|
cie = fde + 1 - fde[1] / sizeof(*fde);
|
||||||
|
if (*cie <= sizeof(*cie) + 4
|
||||||
|
|| *cie >= fde[1] - sizeof(*fde)
|
||||||
|
|| (*cie & (sizeof(*cie) - 1))
|
||||||
|
|| cie[1])
|
||||||
|
return NULL; /* this is not a (valid) CIE */
|
||||||
|
return cie;
|
||||||
|
}
|
||||||
|
|
||||||
static unsigned long read_pointer(const u8 **pLoc,
|
static unsigned long read_pointer(const u8 **pLoc,
|
||||||
const void *end,
|
const void *end,
|
||||||
signed ptrType)
|
signed ptrType)
|
||||||
|
@ -610,49 +791,108 @@ int unwind(struct unwind_frame_info *frame)
|
||||||
unsigned i;
|
unsigned i;
|
||||||
signed ptrType = -1;
|
signed ptrType = -1;
|
||||||
uleb128_t retAddrReg = 0;
|
uleb128_t retAddrReg = 0;
|
||||||
struct unwind_table *table;
|
const struct unwind_table *table;
|
||||||
struct unwind_state state;
|
struct unwind_state state;
|
||||||
|
|
||||||
if (UNW_PC(frame) == 0)
|
if (UNW_PC(frame) == 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if ((table = find_table(pc)) != NULL
|
if ((table = find_table(pc)) != NULL
|
||||||
&& !(table->size & (sizeof(*fde) - 1))) {
|
&& !(table->size & (sizeof(*fde) - 1))) {
|
||||||
unsigned long tableSize = table->size;
|
const u8 *hdr = table->header;
|
||||||
|
unsigned long tableSize;
|
||||||
|
|
||||||
for (fde = table->address;
|
smp_rmb();
|
||||||
tableSize > sizeof(*fde) && tableSize - sizeof(*fde) >= *fde;
|
if (hdr && hdr[0] == 1) {
|
||||||
|
switch(hdr[3] & DW_EH_PE_FORM) {
|
||||||
|
case DW_EH_PE_native: tableSize = sizeof(unsigned long); break;
|
||||||
|
case DW_EH_PE_data2: tableSize = 2; break;
|
||||||
|
case DW_EH_PE_data4: tableSize = 4; break;
|
||||||
|
case DW_EH_PE_data8: tableSize = 8; break;
|
||||||
|
default: tableSize = 0; break;
|
||||||
|
}
|
||||||
|
ptr = hdr + 4;
|
||||||
|
end = hdr + table->hdrsz;
|
||||||
|
if (tableSize
|
||||||
|
&& read_pointer(&ptr, end, hdr[1])
|
||||||
|
== (unsigned long)table->address
|
||||||
|
&& (i = read_pointer(&ptr, end, hdr[2])) > 0
|
||||||
|
&& i == (end - ptr) / (2 * tableSize)
|
||||||
|
&& !((end - ptr) % (2 * tableSize))) {
|
||||||
|
do {
|
||||||
|
const u8 *cur = ptr + (i / 2) * (2 * tableSize);
|
||||||
|
|
||||||
|
startLoc = read_pointer(&cur,
|
||||||
|
cur + tableSize,
|
||||||
|
hdr[3]);
|
||||||
|
if (pc < startLoc)
|
||||||
|
i /= 2;
|
||||||
|
else {
|
||||||
|
ptr = cur - tableSize;
|
||||||
|
i = (i + 1) / 2;
|
||||||
|
}
|
||||||
|
} while (startLoc && i > 1);
|
||||||
|
if (i == 1
|
||||||
|
&& (startLoc = read_pointer(&ptr,
|
||||||
|
ptr + tableSize,
|
||||||
|
hdr[3])) != 0
|
||||||
|
&& pc >= startLoc)
|
||||||
|
fde = (void *)read_pointer(&ptr,
|
||||||
|
ptr + tableSize,
|
||||||
|
hdr[3]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fde != NULL) {
|
||||||
|
cie = cie_for_fde(fde, table);
|
||||||
|
ptr = (const u8 *)(fde + 2);
|
||||||
|
if(cie != NULL
|
||||||
|
&& cie != &bad_cie
|
||||||
|
&& cie != ¬_fde
|
||||||
|
&& (ptrType = fde_pointer_type(cie)) >= 0
|
||||||
|
&& read_pointer(&ptr,
|
||||||
|
(const u8 *)(fde + 1) + *fde,
|
||||||
|
ptrType) == startLoc) {
|
||||||
|
if (!(ptrType & DW_EH_PE_indirect))
|
||||||
|
ptrType &= DW_EH_PE_FORM|DW_EH_PE_signed;
|
||||||
|
endLoc = startLoc
|
||||||
|
+ read_pointer(&ptr,
|
||||||
|
(const u8 *)(fde + 1) + *fde,
|
||||||
|
ptrType);
|
||||||
|
if(pc >= endLoc)
|
||||||
|
fde = NULL;
|
||||||
|
} else
|
||||||
|
fde = NULL;
|
||||||
|
}
|
||||||
|
if (fde == NULL) {
|
||||||
|
for (fde = table->address, tableSize = table->size;
|
||||||
|
cie = NULL, tableSize > sizeof(*fde)
|
||||||
|
&& tableSize - sizeof(*fde) >= *fde;
|
||||||
tableSize -= sizeof(*fde) + *fde,
|
tableSize -= sizeof(*fde) + *fde,
|
||||||
fde += 1 + *fde / sizeof(*fde)) {
|
fde += 1 + *fde / sizeof(*fde)) {
|
||||||
if (!*fde || (*fde & (sizeof(*fde) - 1)))
|
cie = cie_for_fde(fde, table);
|
||||||
|
if (cie == &bad_cie) {
|
||||||
|
cie = NULL;
|
||||||
break;
|
break;
|
||||||
if (!fde[1])
|
|
||||||
continue; /* this is a CIE */
|
|
||||||
if ((fde[1] & (sizeof(*fde) - 1))
|
|
||||||
|| fde[1] > (unsigned long)(fde + 1)
|
|
||||||
- (unsigned long)table->address)
|
|
||||||
continue; /* this is not a valid FDE */
|
|
||||||
cie = fde + 1 - fde[1] / sizeof(*fde);
|
|
||||||
if (*cie <= sizeof(*cie) + 4
|
|
||||||
|| *cie >= fde[1] - sizeof(*fde)
|
|
||||||
|| (*cie & (sizeof(*cie) - 1))
|
|
||||||
|| cie[1]
|
|
||||||
|| (ptrType = fde_pointer_type(cie)) < 0) {
|
|
||||||
cie = NULL; /* this is not a (valid) CIE */
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
if (cie == NULL
|
||||||
|
|| cie == ¬_fde
|
||||||
|
|| (ptrType = fde_pointer_type(cie)) < 0)
|
||||||
|
continue;
|
||||||
ptr = (const u8 *)(fde + 2);
|
ptr = (const u8 *)(fde + 2);
|
||||||
startLoc = read_pointer(&ptr,
|
startLoc = read_pointer(&ptr,
|
||||||
(const u8 *)(fde + 1) + *fde,
|
(const u8 *)(fde + 1) + *fde,
|
||||||
ptrType);
|
ptrType);
|
||||||
|
if (!startLoc)
|
||||||
|
continue;
|
||||||
|
if (!(ptrType & DW_EH_PE_indirect))
|
||||||
|
ptrType &= DW_EH_PE_FORM|DW_EH_PE_signed;
|
||||||
endLoc = startLoc
|
endLoc = startLoc
|
||||||
+ read_pointer(&ptr,
|
+ read_pointer(&ptr,
|
||||||
(const u8 *)(fde + 1) + *fde,
|
(const u8 *)(fde + 1) + *fde,
|
||||||
ptrType & DW_EH_PE_indirect
|
ptrType);
|
||||||
? ptrType
|
|
||||||
: ptrType & (DW_EH_PE_FORM|DW_EH_PE_signed));
|
|
||||||
if (pc >= startLoc && pc < endLoc)
|
if (pc >= startLoc && pc < endLoc)
|
||||||
break;
|
break;
|
||||||
cie = NULL;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (cie != NULL) {
|
if (cie != NULL) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue