From: Andi Kleen x86-64 update for 2.6.4. Only changes x86-64 specific files. The biggest new feature is fixed 32bit vsyscall (SYSCALL+SYSENTER) support, mostly from Jakub Jelinek. This increases 32bit syscall performance greatly (latency halved and better). The SYSENTER for Intel support required some infrastructure changes, but seems to work now too. The 64bit vsyscall vtime() just references xtime.tv_sec now. This should make it a lot faster too. A fix for some Intel IA32e systems. Also a few long standing bugs in NMI like exception handlers were fixed. And a lot of other bug fixes. Full changeLog: - Clean up 32bit address room limit handling, fix 3gb personality - Move memcpy_{from,to}io export to ksyms.c file. This seems to work around a toolchain bug (Andreas Gruenbacher) - Update defconfig - ACPI merges from i386 (SBF should work now, acpi=strict) - Implement mmconfig support based on i386 code (untested) - Fix i386/x86-64 pci source file sharing - Implement ptrace access for 32bit vsyscall page - Always initialize all 32bit SYSENTER/SYSCALL MSRs. - Export run time cache line size to generic kernel - Remove explicit CPUID in ia32 syscall code - Fill in most of boot_cpu_data early - Remove unused PER_LINUX32 setup - Fix syscall trace in fast 32bit calls (Suresh B. Siddha) - Tighten first line of the oops again. - Set up ptrace registers correctly for debug,ss,double fault exceptions - Fix 64bit bug in sys_time64 - Optimize time syscall/vsyscall to only read xtime - Fix csum_partial_copy_nocheck - Remove last traces of FPU emulation - Check properly for rescheduling in exceptions with own stack - Harden exception stack entries (#SS,#NMI,#MC,#DF,#DB) against bogus GS - Use an exception stack for machine checks - Handle TIF_SINGLESTEP properly in kernel exit - Add exception stack for debug handler - Disable X86_HT for Opteron optimized builds because it pulls in ACPI_BOOT - Fix CONFIG_ACPI_BOOT compilation without CONFIG_ACPI - Fix eflags handling in SYSENTER path (Jakub Jelinek) - Use atomic counter for enable/disable_hlt - Support 32bit SYSENTER vsyscall too (Jakub Jelinek) - Don't redefine Dprintk - Change some cpu/apic id arrays to char - Support arbitary cpu<->apicid in hard_smp_processor_id (Surresh B Sidda) - Move K8 erratum #100 workaround into slow path of page fault handler. - Fix 32bit cdrom direct access ioctls (Jens Axboe) - Enable 32bit vsyscalls by default - Fix 32bit vsyscalls (Jakub Jelinek) --- /dev/null | 172 ------------ arch/x86_64/Kconfig | 8 arch/x86_64/Makefile | 2 arch/x86_64/defconfig | 473 ++++++++++++++++++++++++++++------ arch/x86_64/ia32/Makefile | 18 - arch/x86_64/ia32/ia32_binfmt.c | 5 arch/x86_64/ia32/ia32_signal.c | 4 arch/x86_64/ia32/ia32entry.S | 129 ++++++++- arch/x86_64/ia32/sys_ia32.c | 9 arch/x86_64/ia32/syscall32.c | 38 ++ arch/x86_64/ia32/vsyscall-sigreturn.S | 120 ++++++++ arch/x86_64/ia32/vsyscall-syscall.S | 68 ++++ arch/x86_64/ia32/vsyscall-sysenter.S | 94 ++++++ arch/x86_64/kernel/Makefile | 3 arch/x86_64/kernel/acpi/boot.c | 51 +++ arch/x86_64/kernel/entry.S | 118 +++++--- arch/x86_64/kernel/ioport.c | 2 arch/x86_64/kernel/mpparse.c | 2 arch/x86_64/kernel/pci-gart.c | 6 arch/x86_64/kernel/process.c | 8 arch/x86_64/kernel/setup.c | 30 +- arch/x86_64/kernel/setup64.c | 8 arch/x86_64/kernel/smpboot.c | 14 - arch/x86_64/kernel/traps.c | 60 ++-- arch/x86_64/kernel/vsyscall.c | 30 +- arch/x86_64/kernel/x8664_ksyms.c | 3 arch/x86_64/lib/csum-copy.S | 4 arch/x86_64/lib/io.c | 4 arch/x86_64/mm/fault.c | 19 - arch/x86_64/mm/init.c | 31 ++ arch/x86_64/mm/numa.c | 2 arch/x86_64/pci/Makefile | 31 -- arch/x86_64/pci/mmconfig.c | 98 +++++++ include/asm-x86_64/calling.h | 13 include/asm-x86_64/msr.h | 4 include/asm-x86_64/page.h | 7 include/asm-x86_64/processor.h | 8 include/asm-x86_64/proto.h | 4 include/asm-x86_64/smp.h | 12 include/asm-x86_64/thread_info.h | 7 include/asm-x86_64/vsyscall32.h | 7 41 files changed, 1294 insertions(+), 432 deletions(-) diff -puN arch/x86_64/defconfig~x86_64-update arch/x86_64/defconfig --- 25/arch/x86_64/defconfig~x86_64-update 2004-03-10 21:50:35.000000000 -0800 +++ 25-akpm/arch/x86_64/defconfig 2004-03-10 21:50:35.000000000 -0800 @@ -26,7 +26,7 @@ CONFIG_SWAP=y CONFIG_SYSVIPC=y # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y -CONFIG_LOG_BUF_SHIFT=18 +CONFIG_LOG_BUF_SHIFT=17 # CONFIG_HOTPLUG is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y @@ -47,7 +47,8 @@ CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_FORCE_UNLOAD=y CONFIG_OBSOLETE_MODPARM=y # CONFIG_MODVERSIONS is not set -# CONFIG_KMOD is not set +CONFIG_KMOD=y +CONFIG_STOP_MACHINE=y # # Processor type and features @@ -93,20 +94,19 @@ CONFIG_ACPI_INTERPRETER=y CONFIG_ACPI_SLEEP=y CONFIG_ACPI_SLEEP_PROC_FS=y CONFIG_ACPI_AC=y -CONFIG_ACPI_BATTERY=y +# CONFIG_ACPI_BATTERY is not set CONFIG_ACPI_BUTTON=y CONFIG_ACPI_FAN=y CONFIG_ACPI_PROCESSOR=y CONFIG_ACPI_THERMAL=y # CONFIG_ACPI_ASUS is not set -CONFIG_ACPI_TOSHIBA=y -CONFIG_ACPI_DEBUG=y +# CONFIG_ACPI_TOSHIBA is not set +# CONFIG_ACPI_DEBUG is not set CONFIG_ACPI_BUS=y CONFIG_ACPI_EC=y CONFIG_ACPI_POWER=y CONFIG_ACPI_PCI=y CONFIG_ACPI_SYSTEM=y -# CONFIG_ACPI_RELAXED_AML is not set # CONFIG_X86_PM_TIMER is not set # @@ -119,16 +119,17 @@ CONFIG_ACPI_SYSTEM=y # CONFIG_PCI=y CONFIG_PCI_DIRECT=y -# CONFIG_PCI_LEGACY_PROC is not set +CONFIG_PCI_MMCONFIG=y +CONFIG_PCI_LEGACY_PROC=y # CONFIG_PCI_NAMES is not set # # Executable file formats / Emulations # CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_MISC is not set +CONFIG_BINFMT_MISC=y CONFIG_IA32_EMULATION=y -# CONFIG_IA32_AOUT is not set +CONFIG_IA32_AOUT=y CONFIG_COMPAT=y CONFIG_UID16=y @@ -139,6 +140,7 @@ CONFIG_UID16=y # # Generic Driver Options # +# CONFIG_DEBUG_DRIVER is not set # # Memory Technology Devices (MTD) @@ -148,7 +150,14 @@ CONFIG_UID16=y # # Parallel port support # -# CONFIG_PARPORT is not set +CONFIG_PARPORT=y +CONFIG_PARPORT_PC=y +CONFIG_PARPORT_PC_CML1=y +# CONFIG_PARPORT_SERIAL is not set +# CONFIG_PARPORT_PC_FIFO is not set +# CONFIG_PARPORT_PC_SUPERIO is not set +# CONFIG_PARPORT_OTHER is not set +CONFIG_PARPORT_1284=y # # Plug and Play support @@ -158,6 +167,7 @@ CONFIG_UID16=y # Block devices # CONFIG_BLK_DEV_FD=y +# CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set @@ -165,11 +175,8 @@ CONFIG_BLK_DEV_FD=y CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_CRYPTOLOOP is not set # CONFIG_BLK_DEV_NBD is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_SIZE=4096 -CONFIG_BLK_DEV_INITRD=y -CONFIG_LBD=y -# CONFIG_DCSSBLK is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_LBD is not set # # ATA/ATAPI/MFM/RLL support @@ -187,7 +194,7 @@ CONFIG_IDEDISK_MULTI_MODE=y CONFIG_BLK_DEV_IDECD=y # CONFIG_BLK_DEV_IDETAPE is not set # CONFIG_BLK_DEV_IDEFLOPPY is not set -# CONFIG_BLK_DEV_IDESCSI is not set +CONFIG_BLK_DEV_IDESCSI=m # CONFIG_IDE_TASK_IOCTL is not set # CONFIG_IDE_TASKFILE_IO is not set @@ -195,11 +202,12 @@ CONFIG_BLK_DEV_IDECD=y # IDE chipset support/bugfixes # CONFIG_IDE_GENERIC=y -# CONFIG_BLK_DEV_CMD640 is not set +CONFIG_BLK_DEV_CMD640=y +# CONFIG_BLK_DEV_CMD640_ENHANCED is not set CONFIG_BLK_DEV_IDEPCI=y -# CONFIG_IDEPCI_SHARE_IRQ is not set +CONFIG_IDEPCI_SHARE_IRQ=y # CONFIG_BLK_DEV_OFFBOARD is not set -# CONFIG_BLK_DEV_GENERIC is not set +CONFIG_BLK_DEV_GENERIC=y # CONFIG_BLK_DEV_OPTI621 is not set # CONFIG_BLK_DEV_RZ1000 is not set CONFIG_BLK_DEV_IDEDMA_PCI=y @@ -218,16 +226,16 @@ CONFIG_BLK_DEV_AMD74XX=y # CONFIG_BLK_DEV_HPT34X is not set # CONFIG_BLK_DEV_HPT366 is not set # CONFIG_BLK_DEV_SC1200 is not set -CONFIG_BLK_DEV_PIIX=y +# CONFIG_BLK_DEV_PIIX is not set # CONFIG_BLK_DEV_NS87415 is not set # CONFIG_BLK_DEV_PDC202XX_OLD is not set # CONFIG_BLK_DEV_PDC202XX_NEW is not set # CONFIG_BLK_DEV_SVWKS is not set # CONFIG_BLK_DEV_SIIMAGE is not set -# CONFIG_BLK_DEV_SIS5513 is not set +CONFIG_BLK_DEV_SIS5513=y # CONFIG_BLK_DEV_SLC90E66 is not set # CONFIG_BLK_DEV_TRM290 is not set -# CONFIG_BLK_DEV_VIA82CXXX is not set +CONFIG_BLK_DEV_VIA82CXXX=y CONFIG_BLK_DEV_IDEDMA=y # CONFIG_IDEDMA_IVB is not set CONFIG_IDEDMA_AUTO=y @@ -246,8 +254,9 @@ CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y # CONFIG_CHR_DEV_ST is not set # CONFIG_CHR_DEV_OSST is not set -# CONFIG_BLK_DEV_SR is not set -# CONFIG_CHR_DEV_SG is not set +CONFIG_BLK_DEV_SR=m +# CONFIG_BLK_DEV_SR_VENDOR is not set +CONFIG_CHR_DEV_SG=m # # Some SCSI devices (e.g. CD jukebox) support multiple LUNs @@ -260,7 +269,7 @@ CONFIG_BLK_DEV_SD=y # # SCSI low-level drivers # -# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +CONFIG_BLK_DEV_3W_XXXX_RAID=y # CONFIG_SCSI_ACARD is not set # CONFIG_SCSI_AACRAID is not set # CONFIG_SCSI_AIC7XXX is not set @@ -268,7 +277,11 @@ CONFIG_BLK_DEV_SD=y # CONFIG_SCSI_AIC79XX is not set # CONFIG_SCSI_ADVANSYS is not set # CONFIG_SCSI_MEGARAID is not set -# CONFIG_SCSI_SATA is not set +CONFIG_SCSI_SATA=y +# CONFIG_SCSI_SATA_SVW is not set +CONFIG_SCSI_ATA_PIIX=y +# CONFIG_SCSI_SATA_PROMISE is not set +CONFIG_SCSI_SATA_VIA=y # CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_CPQFCTS is not set # CONFIG_SCSI_DMX3191D is not set @@ -278,6 +291,8 @@ CONFIG_BLK_DEV_SD=y # CONFIG_SCSI_GDTH is not set # CONFIG_SCSI_IPS is not set # CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_PPA is not set +# CONFIG_SCSI_IMM is not set # CONFIG_SCSI_SYM53C8XX_2 is not set # CONFIG_SCSI_QLOGIC_ISP is not set # CONFIG_SCSI_QLOGIC_FC is not set @@ -330,37 +345,111 @@ CONFIG_NET=y # CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set -# CONFIG_NETLINK_DEV is not set +CONFIG_NETLINK_DEV=y CONFIG_UNIX=y -# CONFIG_NET_KEY is not set +CONFIG_NET_KEY=m CONFIG_INET=y CONFIG_IP_MULTICAST=y # CONFIG_IP_ADVANCED_ROUTER is not set # CONFIG_IP_PNP is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set -# CONFIG_IP_MROUTE is not set +CONFIG_IP_MROUTE=y +# CONFIG_IP_PIMSM_V1 is not set +# CONFIG_IP_PIMSM_V2 is not set # CONFIG_ARPD is not set # CONFIG_INET_ECN is not set # CONFIG_SYN_COOKIES is not set -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set +CONFIG_INET_AH=m +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m + +# +# IP: Virtual Server Configuration +# +# CONFIG_IP_VS is not set CONFIG_IPV6=y -# CONFIG_IPV6_PRIVACY is not set +CONFIG_IPV6_PRIVACY=y # CONFIG_INET6_AH is not set -# CONFIG_INET6_ESP is not set -# CONFIG_INET6_IPCOMP is not set +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m # CONFIG_IPV6_TUNNEL is not set # CONFIG_DECNET is not set # CONFIG_BRIDGE is not set -# CONFIG_NETFILTER is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_CONNTRACK=m +CONFIG_IP_NF_FTP=m +CONFIG_IP_NF_IRC=m +# CONFIG_IP_NF_TFTP is not set +# CONFIG_IP_NF_AMANDA is not set +# CONFIG_IP_NF_QUEUE is not set +CONFIG_IP_NF_IPTABLES=m +# CONFIG_IP_NF_MATCH_LIMIT is not set +# CONFIG_IP_NF_MATCH_IPRANGE is not set +# CONFIG_IP_NF_MATCH_MAC is not set +# CONFIG_IP_NF_MATCH_PKTTYPE is not set +# CONFIG_IP_NF_MATCH_MARK is not set +# CONFIG_IP_NF_MATCH_MULTIPORT is not set +# CONFIG_IP_NF_MATCH_TOS is not set +# CONFIG_IP_NF_MATCH_RECENT is not set +# CONFIG_IP_NF_MATCH_ECN is not set +# CONFIG_IP_NF_MATCH_DSCP is not set +# CONFIG_IP_NF_MATCH_AH_ESP is not set +# CONFIG_IP_NF_MATCH_LENGTH is not set +# CONFIG_IP_NF_MATCH_TTL is not set +# CONFIG_IP_NF_MATCH_TCPMSS is not set +# CONFIG_IP_NF_MATCH_HELPER is not set +CONFIG_IP_NF_MATCH_STATE=m +CONFIG_IP_NF_MATCH_CONNTRACK=m +# CONFIG_IP_NF_MATCH_OWNER is not set +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +# CONFIG_IP_NF_TARGET_REDIRECT is not set +# CONFIG_IP_NF_TARGET_NETMAP is not set +# CONFIG_IP_NF_TARGET_SAME is not set +# CONFIG_IP_NF_NAT_LOCAL is not set +# CONFIG_IP_NF_NAT_SNMP_BASIC is not set +CONFIG_IP_NF_NAT_IRC=m +CONFIG_IP_NF_NAT_FTP=m +CONFIG_IP_NF_MANGLE=m +# CONFIG_IP_NF_TARGET_TOS is not set +# CONFIG_IP_NF_TARGET_ECN is not set +# CONFIG_IP_NF_TARGET_DSCP is not set +CONFIG_IP_NF_TARGET_MARK=m +# CONFIG_IP_NF_TARGET_CLASSIFY is not set +CONFIG_IP_NF_TARGET_LOG=m +# CONFIG_IP_NF_TARGET_ULOG is not set +CONFIG_IP_NF_TARGET_TCPMSS=m +# CONFIG_IP_NF_ARPTABLES is not set +# CONFIG_IP_NF_COMPAT_IPCHAINS is not set +# CONFIG_IP_NF_COMPAT_IPFWADM is not set + +# +# IPv6: Netfilter Configuration +# +# CONFIG_IP6_NF_QUEUE is not set +# CONFIG_IP6_NF_IPTABLES is not set +CONFIG_XFRM=y +CONFIG_XFRM_USER=m # # SCTP Configuration (EXPERIMENTAL) # CONFIG_IPV6_SCTP__=y -# CONFIG_IP_SCTP is not set +CONFIG_IP_SCTP=m +# CONFIG_SCTP_DBG_MSG is not set +# CONFIG_SCTP_DBG_OBJCNT is not set +CONFIG_SCTP_HMAC_NONE=y +# CONFIG_SCTP_HMAC_SHA1 is not set +# CONFIG_SCTP_HMAC_MD5 is not set # CONFIG_ATM is not set # CONFIG_VLAN_8021Q is not set # CONFIG_LLC2 is not set @@ -389,10 +478,11 @@ CONFIG_NETDEVICES=y # ARCnet devices # # CONFIG_ARCNET is not set -# CONFIG_DUMMY is not set +CONFIG_DUMMY=m # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set +CONFIG_TUN=m +CONFIG_ETHERTAP=m # # Ethernet (10 or 100Mbit) @@ -401,7 +491,9 @@ CONFIG_NET_ETHERNET=y CONFIG_MII=y # CONFIG_HAPPYMEAL is not set # CONFIG_SUNGEM is not set -# CONFIG_NET_VENDOR_3COM is not set +CONFIG_NET_VENDOR_3COM=y +CONFIG_VORTEX=m +# CONFIG_TYPHOON is not set # # Tulip family network device support @@ -409,25 +501,25 @@ CONFIG_MII=y # CONFIG_NET_TULIP is not set # CONFIG_HP100 is not set CONFIG_NET_PCI=y -# CONFIG_PCNET32 is not set -CONFIG_AMD8111_ETH=y +CONFIG_PCNET32=y +CONFIG_AMD8111_ETH=m # CONFIG_ADAPTEC_STARFIRE is not set # CONFIG_B44 is not set -CONFIG_FORCEDETH=y +# CONFIG_FORCEDETH is not set # CONFIG_DGRS is not set # CONFIG_EEPRO100 is not set # CONFIG_E100 is not set # CONFIG_FEALNX is not set # CONFIG_NATSEMI is not set # CONFIG_NE2K_PCI is not set -CONFIG_8139CP=m -CONFIG_8139TOO=m +# CONFIG_8139CP is not set +CONFIG_8139TOO=y # CONFIG_8139TOO_PIO is not set # CONFIG_8139TOO_TUNE_TWISTER is not set # CONFIG_8139TOO_8129 is not set # CONFIG_8139_OLD_RX_RESET is not set CONFIG_8139_RXBUF_IDX=2 -# CONFIG_SIS900 is not set +CONFIG_SIS900=m # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set # CONFIG_VIA_RHINE is not set @@ -437,7 +529,7 @@ CONFIG_8139_RXBUF_IDX=2 # # CONFIG_ACENIC is not set # CONFIG_DL2K is not set -CONFIG_E1000=y +CONFIG_E1000=m # CONFIG_E1000_NAPI is not set # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set @@ -453,7 +545,15 @@ CONFIG_TIGON3=y # CONFIG_IXGB is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set -# CONFIG_PPP is not set +# CONFIG_PLIP is not set +CONFIG_PPP=m +# CONFIG_PPP_MULTILINK is not set +# CONFIG_PPP_FILTER is not set +# CONFIG_PPP_ASYNC is not set +# CONFIG_PPP_SYNC_TTY is not set +# CONFIG_PPP_DEFLATE is not set +# CONFIG_PPP_BSDCOMP is not set +CONFIG_PPPOE=m # CONFIG_SLIP is not set # @@ -512,7 +612,7 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_TSDEV is not set -CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVDEV is not set # CONFIG_INPUT_EVBUG is not set # @@ -524,6 +624,7 @@ CONFIG_SERIO=y CONFIG_SERIO_I8042=y # CONFIG_SERIO_SERPORT is not set # CONFIG_SERIO_CT82C710 is not set +# CONFIG_SERIO_PARKBD is not set # CONFIG_SERIO_PCIPS2 is not set # @@ -547,7 +648,12 @@ CONFIG_MOUSE_PS2=y CONFIG_VT=y CONFIG_VT_CONSOLE=y CONFIG_HW_CONSOLE=y -# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_SERIAL_NONSTANDARD=y +CONFIG_ROCKETPORT=m +# CONFIG_SYNCLINK is not set +# CONFIG_SYNCLINKMP is not set +# CONFIG_N_HDLC is not set +# CONFIG_STALDRV is not set # # Serial drivers @@ -564,13 +670,16 @@ CONFIG_SERIAL_8250_NR_UARTS=4 CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_UNIX98_PTYS=y -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=256 +# CONFIG_LEGACY_PTYS is not set +CONFIG_PRINTER=y +# CONFIG_LP_CONSOLE is not set +# CONFIG_PPDEV is not set +# CONFIG_TIPAR is not set # # Mice # -# CONFIG_BUSMOUSE is not set +CONFIG_BUSMOUSE=y # CONFIG_QIC02_TAPE is not set # @@ -594,12 +703,17 @@ CONFIG_RTC=y # CONFIG_AGP=y CONFIG_AGP_AMD64=y -CONFIG_AGP_INTEL=y -# CONFIG_DRM is not set +# CONFIG_AGP_INTEL is not set +CONFIG_DRM=y +# CONFIG_DRM_TDFX is not set +# CONFIG_DRM_GAMMA is not set +# CONFIG_DRM_R128 is not set +CONFIG_DRM_RADEON=m +# CONFIG_DRM_SIS is not set # CONFIG_MWAVE is not set -CONFIG_RAW_DRIVER=y +CONFIG_RAW_DRIVER=m CONFIG_MAX_RAW_DEVS=256 -CONFIG_HANGCHECK_TIMER=y +# CONFIG_HANGCHECK_TIMER is not set # # I2C support @@ -607,6 +721,11 @@ CONFIG_HANGCHECK_TIMER=y # CONFIG_I2C is not set # +# Misc devices +# +# CONFIG_IBM_ASM is not set + +# # Multimedia devices # # CONFIG_VIDEO_DEV is not set @@ -642,10 +761,11 @@ CONFIG_SOUND=y # # Open Sound System # -CONFIG_SOUND_PRIME=y +CONFIG_SOUND_PRIME=m # CONFIG_SOUND_BT878 is not set # CONFIG_SOUND_CMPCI is not set -# CONFIG_SOUND_EMU10K1 is not set +CONFIG_SOUND_EMU10K1=m +# CONFIG_MIDI_EMU10K1 is not set # CONFIG_SOUND_FUSION is not set # CONFIG_SOUND_CS4281 is not set # CONFIG_SOUND_ES1370 is not set @@ -653,12 +773,13 @@ CONFIG_SOUND_PRIME=y # CONFIG_SOUND_ESSSOLO1 is not set # CONFIG_SOUND_MAESTRO is not set # CONFIG_SOUND_MAESTRO3 is not set -CONFIG_SOUND_ICH=y +CONFIG_SOUND_ICH=m # CONFIG_SOUND_SONICVIBES is not set # CONFIG_SOUND_TRIDENT is not set # CONFIG_SOUND_MSNDCLAS is not set # CONFIG_SOUND_MSNDPIN is not set -# CONFIG_SOUND_VIA82CXXX is not set +CONFIG_SOUND_VIA82CXXX=m +# CONFIG_MIDI_VIA82CXXX is not set # CONFIG_SOUND_OSS is not set # CONFIG_SOUND_ALI5455 is not set # CONFIG_SOUND_FORTE is not set @@ -668,7 +789,151 @@ CONFIG_SOUND_ICH=y # # USB support # -# CONFIG_USB is not set +CONFIG_USB=m +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +CONFIG_USB_BANDWIDTH=y +# CONFIG_USB_DYNAMIC_MINORS is not set + +# +# USB Host Controller Drivers +# +CONFIG_USB_EHCI_HCD=m +CONFIG_USB_OHCI_HCD=m +CONFIG_USB_UHCI_HCD=m + +# +# USB Device Class drivers +# +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_BLUETOOTH_TTY is not set +# CONFIG_USB_MIDI is not set +# CONFIG_USB_ACM is not set +CONFIG_USB_PRINTER=m +CONFIG_USB_STORAGE=m +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_HP8200e is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set + +# +# USB Human Interface Devices (HID) +# +CONFIG_USB_HID=m +CONFIG_USB_HIDINPUT=y +# CONFIG_HID_FF is not set +# CONFIG_USB_HIDDEV is not set + +# +# USB HID Boot Protocol drivers +# +# CONFIG_USB_KBD is not set +# CONFIG_USB_MOUSE is not set +# CONFIG_USB_AIPTEK is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set +# CONFIG_USB_XPAD is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_HPUSBSCSI is not set + +# +# USB Multimedia devices +# +# CONFIG_USB_DABUSB is not set + +# +# Video4Linux support is needed for USB Multimedia device support +# + +# +# USB Network adaptors +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +CONFIG_USB_USBNET=m + +# +# USB Host-to-Host Cables +# +CONFIG_USB_AN2720=y +CONFIG_USB_BELKIN=y +CONFIG_USB_GENESYS=y +CONFIG_USB_NET1080=y +CONFIG_USB_PL2301=y + +# +# Intelligent USB Devices/Gadgets +# +CONFIG_USB_ARMLINUX=y +CONFIG_USB_EPSON2888=y +# CONFIG_USB_ZAURUS is not set +# CONFIG_USB_CDCETHER is not set + +# +# USB Network Adapters +# +CONFIG_USB_AX8817X=y + +# +# USB port drivers +# +# CONFIG_USB_USS720 is not set + +# +# USB Serial Converter support +# +CONFIG_USB_SERIAL=m +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_BELKIN=m +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +# CONFIG_USB_SERIAL_EMPEG is not set +# CONFIG_USB_SERIAL_FTDI_SIO is not set +# CONFIG_USB_SERIAL_VISOR is not set +# CONFIG_USB_SERIAL_IPAQ is not set +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_EDGEPORT is not set +# CONFIG_USB_SERIAL_EDGEPORT_TI is not set +# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set +# CONFIG_USB_SERIAL_KEYSPAN is not set +# CONFIG_USB_SERIAL_KLSI is not set +# CONFIG_USB_SERIAL_KOBIL_SCT is not set +# CONFIG_USB_SERIAL_MCT_U232 is not set +# CONFIG_USB_SERIAL_PL2303 is not set +# CONFIG_USB_SERIAL_SAFE is not set +# CONFIG_USB_SERIAL_CYBERJACK is not set +# CONFIG_USB_SERIAL_XIRCOM is not set +# CONFIG_USB_SERIAL_OMNINET is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_TIGL is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_BRLVGER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_TEST is not set # # USB Gadget Support @@ -680,20 +945,17 @@ CONFIG_SOUND_ICH=y # CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y -CONFIG_EXT2_FS_POSIX_ACL=y +# CONFIG_EXT2_FS_POSIX_ACL is not set # CONFIG_EXT2_FS_SECURITY is not set CONFIG_EXT3_FS=y -CONFIG_EXT3_FS_XATTR=y -CONFIG_EXT3_FS_POSIX_ACL=y -# CONFIG_EXT3_FS_SECURITY is not set +# CONFIG_EXT3_FS_XATTR is not set CONFIG_JBD=y # CONFIG_JBD_DEBUG is not set CONFIG_FS_MBCACHE=y CONFIG_REISERFS_FS=y # CONFIG_REISERFS_CHECK is not set -# CONFIG_REISERFS_PROC_INFO is not set +CONFIG_REISERFS_PROC_INFO=y # CONFIG_JFS_FS is not set -CONFIG_FS_POSIX_ACL=y # CONFIG_XFS_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set @@ -705,14 +967,16 @@ CONFIG_AUTOFS_FS=y # CD-ROM/DVD Filesystems # CONFIG_ISO9660_FS=y -# CONFIG_JOLIET is not set +CONFIG_JOLIET=y # CONFIG_ZISOFS is not set -# CONFIG_UDF_FS is not set +CONFIG_UDF_FS=m # # DOS/FAT/NT Filesystems # -# CONFIG_FAT_FS is not set +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=m # CONFIG_NTFS_FS is not set # @@ -723,8 +987,8 @@ CONFIG_PROC_KCORE=y # CONFIG_DEVFS_FS is not set # CONFIG_DEVPTS_FS_XATTR is not set CONFIG_TMPFS=y -CONFIG_HUGETLBFS=y -CONFIG_HUGETLB_PAGE=y +# CONFIG_HUGETLBFS is not set +# CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y # @@ -750,7 +1014,7 @@ CONFIG_RAMFS=y CONFIG_NFS_FS=y CONFIG_NFS_V3=y # CONFIG_NFS_V4 is not set -# CONFIG_NFS_DIRECTIO is not set +CONFIG_NFS_DIRECTIO=y CONFIG_NFSD=y CONFIG_NFSD_V3=y # CONFIG_NFSD_V4 is not set @@ -775,7 +1039,45 @@ CONFIG_MSDOS_PARTITION=y # # Native Language Support # -# CONFIG_NLS is not set +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set # # Profiling support @@ -803,9 +1105,28 @@ CONFIG_MAGIC_SYSRQ=y # # Cryptographic options # -# CONFIG_CRYPTO is not set +CONFIG_CRYPTO=y +CONFIG_CRYPTO_HMAC=y +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_SHA1=m +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +CONFIG_CRYPTO_DES=m +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_TWOFISH is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_ARC4 is not set +CONFIG_CRYPTO_DEFLATE=m +# CONFIG_CRYPTO_TEST is not set # # Library routines # CONFIG_CRC32=y +CONFIG_ZLIB_INFLATE=m +CONFIG_ZLIB_DEFLATE=m diff -puN arch/x86_64/ia32/ia32_binfmt.c~x86_64-update arch/x86_64/ia32/ia32_binfmt.c --- 25/arch/x86_64/ia32/ia32_binfmt.c~x86_64-update 2004-03-10 21:50:35.000000000 -0800 +++ 25-akpm/arch/x86_64/ia32/ia32_binfmt.c 2004-03-10 21:50:35.000000000 -0800 @@ -32,7 +32,7 @@ #define AT_SYSINFO 32 #define AT_SYSINFO_EHDR 33 -int sysctl_vsyscall32; +int sysctl_vsyscall32 = 1; #define ARCH_DLINFO do { \ if (sysctl_vsyscall32) { \ @@ -46,7 +46,7 @@ struct elf_phdr; #define IA32_EMULATOR 1 -#define ELF_ET_DYN_BASE (IA32_PAGE_OFFSET/3 + 0x1000000) +#define ELF_ET_DYN_BASE (TASK_UNMAPPED_32 + 0x1000000) #undef ELF_ARCH #define ELF_ARCH EM_386 @@ -261,7 +261,6 @@ do { \ set_thread_flag(TIF_ABI_PENDING); \ else \ clear_thread_flag(TIF_ABI_PENDING); \ - set_personality((ibcs2)?PER_SVR4:current->personality); \ } while (0) /* Override some function names */ diff -puN arch/x86_64/ia32/ia32entry.S~x86_64-update arch/x86_64/ia32/ia32entry.S --- 25/arch/x86_64/ia32/ia32entry.S~x86_64-update 2004-03-10 21:50:35.000000000 -0800 +++ 25-akpm/arch/x86_64/ia32/ia32entry.S 2004-03-10 21:50:35.000000000 -0800 @@ -12,6 +12,7 @@ #include #include #include +#include #include .macro IA32_ARG_FIXUP noebp=0 @@ -25,6 +26,99 @@ movl %edx,%edx /* zero extension */ .endm + /* clobbers %eax */ + .macro CLEAR_RREGS + xorl %eax,%eax + movq %rax,R11(%rsp) + movq %rax,R10(%rsp) + movq %rax,R9(%rsp) + movq %rax,R8(%rsp) + .endm + +/* + * 32bit SYSENTER instruction entry. + * + * Arguments: + * %eax System call number. + * %ebx Arg1 + * %ecx Arg2 + * %edx Arg3 + * %esi Arg4 + * %edi Arg5 + * %ebp user stack + * 0(%ebp) Arg6 + * + * Interrupts off. + * + * This is purely a fast path. For anything complicated we use the int 0x80 + * path below. Set up a complete hardware stack frame to share code + * with the int 0x80 path. + */ +ENTRY(ia32_sysenter_target) + CFI_STARTPROC + swapgs + movq %gs:pda_kernelstack, %rsp + addq $(PDA_STACKOFFSET),%rsp + sti + movl %ebp,%ebp /* zero extension */ + pushq $__USER32_DS + pushq %rbp + pushfq + movl $VSYSCALL32_SYSEXIT, %r10d + pushq $__USER32_CS + movl %eax, %eax + pushq %r10 + pushq %rax + cld + SAVE_ARGS 0,0,1 + /* no need to do an access_ok check here because rbp has been + 32bit zero extended */ +1: movl (%rbp),%r9d + .section __ex_table,"a" + .quad 1b,ia32_badarg + .previous + GET_THREAD_INFO(%r10) + bt $TIF_SYSCALL_TRACE,threadinfo_flags(%r10) + jc sysenter_tracesys +sysenter_do_call: + cmpl $(IA32_NR_syscalls),%eax + jae ia32_badsys + IA32_ARG_FIXUP 1 + call *ia32_sys_call_table(,%rax,8) + movq %rax,RAX-ARGOFFSET(%rsp) + GET_THREAD_INFO(%r10) + cli + testl $_TIF_ALLWORK_MASK,threadinfo_flags(%r10) + jnz int_ret_from_sys_call + /* clear IF, that popfq doesn't enable interrupts early */ + andl $~0x200,EFLAGS-R11(%rsp) + RESTORE_ARGS 1,24,1,1,1,1 + popfq + popq %rcx /* User %esp */ + movl $VSYSCALL32_SYSEXIT,%edx /* User %eip */ + swapgs + sti /* sti only takes effect after the next instruction */ + /* sysexit */ + .byte 0xf, 0x35 + +sysenter_tracesys: + SAVE_REST + CLEAR_RREGS + movq $-ENOSYS,RAX(%rsp) /* really needed? */ + movq %rsp,%rdi /* &pt_regs -> arg1 */ + call syscall_trace + LOAD_ARGS ARGOFFSET /* reload args from stack in case ptrace changed it */ + RESTORE_REST + movl %ebp, %ebp + /* no need to do an access_ok check here because rbp has been + 32bit zero extended */ +1: movl (%rbp),%r9d + .section __ex_table,"a" + .quad 1b,ia32_badarg + .previous + jmp sysenter_do_call + CFI_ENDPROC + /* * 32bit SYSCALL instruction entry. * @@ -51,7 +145,7 @@ ENTRY(ia32_cstar_target) movl %esp,%r8d movq %gs:pda_kernelstack,%rsp sti - SAVE_ARGS 8,1 + SAVE_ARGS 8,1,1 movl %eax,%eax /* zero extension */ movq %rax,ORIG_RAX-ARGOFFSET(%rsp) movq %rcx,RIP-ARGOFFSET(%rsp) @@ -66,47 +160,48 @@ ENTRY(ia32_cstar_target) /* hardware stack frame is complete now */ 1: movl (%r8),%r9d .section __ex_table,"a" - .quad 1b,cstar_badarg + .quad 1b,ia32_badarg .previous GET_THREAD_INFO(%r10) bt $TIF_SYSCALL_TRACE,threadinfo_flags(%r10) - jc ia32_tracesys + jc cstar_tracesys cstar_do_call: cmpl $IA32_NR_syscalls,%eax jae ia32_badsys IA32_ARG_FIXUP 1 call *ia32_sys_call_table(,%rax,8) - .globl cstar_sysret - /* label must directly follow call */ -cstar_sysret: movq %rax,RAX-ARGOFFSET(%rsp) GET_THREAD_INFO(%r10) cli testl $_TIF_ALLWORK_MASK,threadinfo_flags(%r10) - jnz 1f - RESTORE_ARGS 1,-ARG_SKIP,1,1 + jnz int_ret_from_sys_call + RESTORE_ARGS 1,-ARG_SKIP,1,1,1 movl RIP-ARGOFFSET(%rsp),%ecx movl EFLAGS-ARGOFFSET(%rsp),%r11d movl RSP-ARGOFFSET(%rsp),%esp swapgs sysretl -1: - btc $TIF_IRET,threadinfo_flags(%r10) - jmp int_ret_from_sys_call - cstar_tracesys: SAVE_REST + CLEAR_RREGS movq $-ENOSYS,RAX(%rsp) /* really needed? */ movq %rsp,%rdi /* &pt_regs -> arg1 */ call syscall_trace LOAD_ARGS ARGOFFSET /* reload args from stack in case ptrace changed it */ RESTORE_REST + movl RSP-ARGOFFSET(%rsp), %r8d + /* no need to do an access_ok check here because r8 has been + 32bit zero extended */ +1: movl (%r8),%r9d + .section __ex_table,"a" + .quad 1b,ia32_badarg + .previous jmp cstar_do_call -cstar_badarg: +ia32_badarg: movq $-EFAULT,%rax - jmp cstar_sysret + jmp ia32_sysret CFI_ENDPROC /* @@ -139,7 +234,7 @@ ENTRY(ia32_syscall) cld /* note the registers are not zero extended to the sf. this could be a problem. */ - SAVE_ARGS + SAVE_ARGS 0,0,1 GET_THREAD_INFO(%r10) bt $TIF_SYSCALL_TRACE,threadinfo_flags(%r10) jc ia32_tracesys @@ -148,6 +243,7 @@ ia32_do_syscall: jae ia32_badsys IA32_ARG_FIXUP call *ia32_sys_call_table(,%rax,8) # xxx: rip relative +ia32_sysret: movq %rax,RAX-ARGOFFSET(%rsp) jmp int_ret_from_sys_call @@ -200,8 +296,7 @@ ENTRY(ia32_ptregs_common) call *%rax movq %r15, %r11 RESTORE_REST - cmpq $cstar_sysret,%r11 - je int_ret_from_sys_call /* misbalances the call/ret stack. sorry */ + leaq ia32_sysret(%rip),%r11 pushq %r11 ret CFI_ENDPROC diff -puN arch/x86_64/ia32/ia32_signal.c~x86_64-update arch/x86_64/ia32/ia32_signal.c --- 25/arch/x86_64/ia32/ia32_signal.c~x86_64-update 2004-03-10 21:50:35.000000000 -0800 +++ 25-akpm/arch/x86_64/ia32/ia32_signal.c 2004-03-10 21:50:35.000000000 -0800 @@ -273,8 +273,6 @@ asmlinkage long sys32_sigreturn(struct p sigset_t set; unsigned int eax; - set_thread_flag(TIF_IRET); - if (verify_area(VERIFY_READ, frame, sizeof(*frame))) goto badframe; if (__get_user(set.sig[0], &frame->sc.oldmask) @@ -305,8 +303,6 @@ asmlinkage long sys32_rt_sigreturn(struc stack_t st; unsigned int eax; - set_thread_flag(TIF_IRET); - if (verify_area(VERIFY_READ, frame, sizeof(*frame))) goto badframe; if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) diff -puN arch/x86_64/ia32/Makefile~x86_64-update arch/x86_64/ia32/Makefile --- 25/arch/x86_64/ia32/Makefile~x86_64-update 2004-03-10 21:50:35.000000000 -0800 +++ 25-akpm/arch/x86_64/ia32/Makefile 2004-03-10 21:50:35.000000000 -0800 @@ -11,18 +11,22 @@ obj-$(CONFIG_IA32_EMULATION) += $(sysv-y obj-$(CONFIG_IA32_AOUT) += ia32_aout.o -$(obj)/syscall32.o: $(src)/syscall32.c $(obj)/vsyscall.so +$(obj)/syscall32.o: $(src)/syscall32.c \ + $(foreach F,sysenter syscall,$(obj)/vsyscall-$F.so) # Teach kbuild about targets -targets := vsyscall.o vsyscall.so +targets := $(foreach F,sysenter syscall,vsyscall-$F.o vsyscall-$F.so) # The DSO images are built using a special linker script -quiet_cmd_vsyscall = SYSCALL $@ - cmd_vsyscall = $(CC) -m32 -nostdlib -shared -s \ +quiet_cmd_syscall = SYSCALL $@ + cmd_syscall = $(CC) -m32 -nostdlib -shared -s \ -Wl,-soname=linux-gate.so.1 -o $@ \ -Wl,-T,$(filter-out FORCE,$^) -$(obj)/vsyscall.so: $(src)/vsyscall.lds $(obj)/vsyscall.o FORCE - $(call if_changed,vsyscall) -AFLAGS_vsyscall.o = -m32 +$(obj)/vsyscall-sysenter.so $(obj)/vsyscall-syscall.so: \ +$(obj)/vsyscall-%.so: $(src)/vsyscall.lds $(obj)/vsyscall-%.o FORCE + $(call if_changed,syscall) + +AFLAGS_vsyscall-sysenter.o = -m32 +AFLAGS_vsyscall-syscall.o = -m32 CFLAGS_ia32_ioctl.o += -Ifs/ diff -puN arch/x86_64/ia32/syscall32.c~x86_64-update arch/x86_64/ia32/syscall32.c --- 25/arch/x86_64/ia32/syscall32.c~x86_64-update 2004-03-10 21:50:35.000000000 -0800 +++ 25-akpm/arch/x86_64/ia32/syscall32.c 2004-03-10 21:50:35.000000000 -0800 @@ -13,16 +13,22 @@ #include #include -/* 32bit VDSO mapped into user space. */ +/* 32bit VDSOs mapped into user space. */ asm(".section \".init.data\",\"aw\"\n" - "syscall32:\n" - ".incbin \"arch/x86_64/ia32/vsyscall.so\"\n" - "syscall32_end:\n" + "syscall32_syscall:\n" + ".incbin \"arch/x86_64/ia32/vsyscall-syscall.so\"\n" + "syscall32_syscall_end:\n" + "syscall32_sysenter:\n" + ".incbin \"arch/x86_64/ia32/vsyscall-sysenter.so\"\n" + "syscall32_sysenter_end:\n" ".previous"); -extern unsigned char syscall32[], syscall32_end[]; +extern unsigned char syscall32_syscall[], syscall32_syscall_end[]; +extern unsigned char syscall32_sysenter[], syscall32_sysenter_end[]; +extern int sysctl_vsyscall32; char *syscall32_page; +static int use_sysenter __initdata = -1; /* RED-PEN: This knows too much about high level VM */ /* Alternative would be to generate a vma with appropriate backing options @@ -58,8 +64,28 @@ static int __init init_syscall32(void) if (!syscall32_page) panic("Cannot allocate syscall32 page"); SetPageReserved(virt_to_page(syscall32_page)); - memcpy(syscall32_page, syscall32, syscall32_end - syscall32); + if (use_sysenter > 0) { + memcpy(syscall32_page, syscall32_sysenter, + syscall32_sysenter_end - syscall32_sysenter); + } else { + memcpy(syscall32_page, syscall32_syscall, + syscall32_syscall_end - syscall32_syscall); + } return 0; } __initcall(init_syscall32); + +void __init syscall32_cpu_init(void) +{ + if (use_sysenter < 0) + use_sysenter = (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL); + + /* Load these always in case some future AMD CPU supports + SYSENTER from compat mode too. */ + wrmsr(MSR_IA32_SYSENTER_CS, __KERNEL_CS, 0); + wrmsr(MSR_IA32_SYSENTER_ESP, 0, 0); + wrmsrl(MSR_IA32_SYSENTER_EIP, ia32_sysenter_target); + + wrmsrl(MSR_CSTAR, ia32_cstar_target); +} diff -puN arch/x86_64/ia32/sys_ia32.c~x86_64-update arch/x86_64/ia32/sys_ia32.c --- 25/arch/x86_64/ia32/sys_ia32.c~x86_64-update 2004-03-10 21:50:35.000000000 -0800 +++ 25-akpm/arch/x86_64/ia32/sys_ia32.c 2004-03-10 21:50:35.000000000 -0800 @@ -1876,18 +1876,9 @@ long sys32_quotactl(void) cond_syscall(sys32_ipc) -struct exec_domain ia32_exec_domain = { - .name = "linux/x86", - .pers_low = PER_LINUX32, - .pers_high = PER_LINUX32, -}; - static int __init ia32_init (void) { printk("IA32 emulation $Id: sys_ia32.c,v 1.32 2002/03/24 13:02:28 ak Exp $\n"); - ia32_exec_domain.signal_map = default_exec_domain.signal_map; - ia32_exec_domain.signal_invmap = default_exec_domain.signal_invmap; - register_exec_domain(&ia32_exec_domain); return 0; } diff -puN -L arch/x86_64/ia32/vsyscall.S arch/x86_64/ia32/vsyscall.S~x86_64-update /dev/null --- 25/arch/x86_64/ia32/vsyscall.S +++ /dev/null 2002-08-30 16:31:37.000000000 -0700 @@ -1,172 +0,0 @@ -/* - * Code for the vsyscall page. This version uses the syscall instruction. - */ - -#include -#include - - .text - .section .text.vsyscall,"ax" - .globl __kernel_vsyscall - .type __kernel_vsyscall,@function -__kernel_vsyscall: -.LSTART_vsyscall: - push %ebp -.Lpush_ebp: - movl %ecx, %ebp - syscall - popl %ebp -.Lpop_ebp: - ret -.LEND_vsyscall: - .size __kernel_vsyscall,.-.LSTART_vsyscall - - .section .text.sigreturn,"ax" - .balign 32 - .globl __kernel_sigreturn - .type __kernel_sigreturn,@function -__kernel_sigreturn: -.LSTART_sigreturn: - popl %eax - movl $__NR_ia32_sigreturn, %eax - syscall -.LEND_sigreturn: - .size __kernel_sigreturn,.-.LSTART_sigreturn - - .section .text.rtsigreturn,"ax" - .balign 32 - .globl __kernel_rt_sigreturn - .type __kernel_rt_sigreturn,@function -__kernel_rt_sigreturn: -.LSTART_rt_sigreturn: - movl $__NR_ia32_rt_sigreturn, %eax - syscall -.LEND_rt_sigreturn: - .size __kernel_rt_sigreturn,.-.LSTART_rt_sigreturn - - .section .eh_frame,"a",@progbits -.LSTARTFRAME: - .long .LENDCIE-.LSTARTCIE -.LSTARTCIE: - .long 0 /* CIE ID */ - .byte 1 /* Version number */ - .string "zR" /* NUL-terminated augmentation string */ - .uleb128 1 /* Code alignment factor */ - .sleb128 -4 /* Data alignment factor */ - .byte 8 /* Return address register column */ - .uleb128 1 /* Augmentation value length */ - .byte 0x1b /* DW_EH_PE_pcrel|DW_EH_PE_sdata4. */ - .byte 0x0c /* DW_CFA_def_cfa */ - .uleb128 4 - .uleb128 4 - .byte 0x88 /* DW_CFA_offset, column 0x8 */ - .uleb128 1 - .align 4 -.LENDCIE: - - .long .LENDFDE1-.LSTARTFDE1 /* Length FDE */ -.LSTARTFDE1: - .long .LSTARTFDE1-.LSTARTFRAME /* CIE pointer */ - .long .LSTART_vsyscall-. /* PC-relative start address */ - .long .LEND_vsyscall-.LSTART_vsyscall - .uleb128 0 /* Augmentation length */ - /* What follows are the instructions for the table generation. - We have to record all changes of the stack pointer. */ - .byte 0x40 + .Lpush_ebp-.LSTART_vsyscall /* DW_CFA_advance_loc */ - .byte 0x0e /* DW_CFA_def_cfa_offset */ - .uleb128 8 - .byte 0x85, 0x02 /* DW_CFA_offset %ebp -8 */ - .byte 0x40 + .Lpop_ebp-.Lpush_ebp /* DW_CFA_advance_loc */ - .byte 0xc5 /* DW_CFA_restore %ebp */ - .byte 0x0e /* DW_CFA_def_cfa_offset */ - .uleb128 4 - .align 4 -.LENDFDE1: - - .long .LENDFDE2-.LSTARTFDE2 /* Length FDE */ -.LSTARTFDE2: - .long .LSTARTFDE2-.LSTARTFRAME /* CIE pointer */ - /* HACK: The dwarf2 unwind routines will subtract 1 from the - return address to get an address in the middle of the - presumed call instruction. Since we didn't get here via - a call, we need to include the nop before the real start - to make up for it. */ - .long .LSTART_sigreturn-1-. /* PC-relative start address */ - .long .LEND_sigreturn-.LSTART_sigreturn+1 - .uleb128 0 /* Augmentation length */ - /* What follows are the instructions for the table generation. - We record the locations of each register saved. This is - complicated by the fact that the "CFA" is always assumed to - be the value of the stack pointer in the caller. This means - that we must define the CFA of this body of code to be the - saved value of the stack pointer in the sigcontext. Which - also means that there is no fixed relation to the other - saved registers, which means that we must use DW_CFA_expression - to compute their addresses. It also means that when we - adjust the stack with the popl, we have to do it all over again. */ - -#define do_cfa_expr(offset) \ - .byte 0x0f; /* DW_CFA_def_cfa_expression */ \ - .uleb128 1f-0f; /* length */ \ -0: .byte 0x74; /* DW_OP_breg4 */ \ - .sleb128 offset; /* offset */ \ - .byte 0x06; /* DW_OP_deref */ \ -1: - -#define do_expr(regno, offset) \ - .byte 0x10; /* DW_CFA_expression */ \ - .uleb128 regno; /* regno */ \ - .uleb128 1f-0f; /* length */ \ -0: .byte 0x74; /* DW_OP_breg4 */ \ - .sleb128 offset; /* offset */ \ -1: - - do_cfa_expr(IA32_SIGCONTEXT_esp+4) - do_expr(0, IA32_SIGCONTEXT_eax+4) - do_expr(1, IA32_SIGCONTEXT_ecx+4) - do_expr(2, IA32_SIGCONTEXT_edx+4) - do_expr(3, IA32_SIGCONTEXT_ebx+4) - do_expr(5, IA32_SIGCONTEXT_ebp+4) - do_expr(6, IA32_SIGCONTEXT_esi+4) - do_expr(7, IA32_SIGCONTEXT_edi+4) - do_expr(8, IA32_SIGCONTEXT_eip+4) - - .byte 0x42 /* DW_CFA_advance_loc 2 -- nop; popl eax. */ - - do_cfa_expr(IA32_SIGCONTEXT_esp) - do_expr(0, IA32_SIGCONTEXT_eax) - do_expr(1, IA32_SIGCONTEXT_ecx) - do_expr(2, IA32_SIGCONTEXT_edx) - do_expr(3, IA32_SIGCONTEXT_ebx) - do_expr(5, IA32_SIGCONTEXT_ebp) - do_expr(6, IA32_SIGCONTEXT_esi) - do_expr(7, IA32_SIGCONTEXT_edi) - do_expr(8, IA32_SIGCONTEXT_eip) - - .align 4 -.LENDFDE2: - - .long .LENDFDE3-.LSTARTFDE3 /* Length FDE */ -.LSTARTFDE3: - .long .LSTARTFDE3-.LSTARTFRAME /* CIE pointer */ - /* HACK: See above wrt unwind library assumptions. */ - .long .LSTART_rt_sigreturn-1-. /* PC-relative start address */ - .long .LEND_rt_sigreturn-.LSTART_rt_sigreturn+1 - .uleb128 0 /* Augmentation */ - /* What follows are the instructions for the table generation. - We record the locations of each register saved. This is - slightly less complicated than the above, since we don't - modify the stack pointer in the process. */ - - do_cfa_expr(IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_esp) - do_expr(0, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_eax) - do_expr(1, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_ecx) - do_expr(2, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_edx) - do_expr(3, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_ebx) - do_expr(5, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_ebp) - do_expr(6, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_esi) - do_expr(7, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_edi) - do_expr(8, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_eip) - - .align 4 -.LENDFDE3: diff -puN /dev/null arch/x86_64/ia32/vsyscall-sigreturn.S --- /dev/null 2002-08-30 16:31:37.000000000 -0700 +++ 25-akpm/arch/x86_64/ia32/vsyscall-sigreturn.S 2004-03-10 21:50:35.000000000 -0800 @@ -0,0 +1,120 @@ +/* + * Common code for the sigreturn entry points on the vsyscall page. + * This code uses SYSCALL_ENTER_KERNEL (either syscall or int $0x80) + * to enter the kernel. + * This file is #include'd by vsyscall-*.S to define them after the + * vsyscall entry point. The addresses we get for these entry points + * by doing ".balign 32" must match in both versions of the page. + */ + + .section .text.sigreturn,"ax" + .balign 32 + .globl __kernel_sigreturn + .type __kernel_sigreturn,@function +__kernel_sigreturn: +.LSTART_sigreturn: + popl %eax + movl $__NR_ia32_sigreturn, %eax + SYSCALL_ENTER_KERNEL +.LEND_sigreturn: + .size __kernel_sigreturn,.-.LSTART_sigreturn + + .section .text.rtsigreturn,"ax" + .balign 32 + .globl __kernel_rt_sigreturn + .type __kernel_rt_sigreturn,@function +__kernel_rt_sigreturn: +.LSTART_rt_sigreturn: + movl $__NR_ia32_rt_sigreturn, %eax + SYSCALL_ENTER_KERNEL +.LEND_rt_sigreturn: + .size __kernel_rt_sigreturn,.-.LSTART_rt_sigreturn + + .section .eh_frame,"a",@progbits + .long .LENDFDE2-.LSTARTFDE2 /* Length FDE */ +.LSTARTFDE2: + .long .LSTARTFDE2-.LSTARTFRAME /* CIE pointer */ + /* HACK: The dwarf2 unwind routines will subtract 1 from the + return address to get an address in the middle of the + presumed call instruction. Since we didn't get here via + a call, we need to include the nop before the real start + to make up for it. */ + .long .LSTART_sigreturn-1-. /* PC-relative start address */ + .long .LEND_sigreturn-.LSTART_sigreturn+1 + .uleb128 0 /* Augmentation length */ + /* What follows are the instructions for the table generation. + We record the locations of each register saved. This is + complicated by the fact that the "CFA" is always assumed to + be the value of the stack pointer in the caller. This means + that we must define the CFA of this body of code to be the + saved value of the stack pointer in the sigcontext. Which + also means that there is no fixed relation to the other + saved registers, which means that we must use DW_CFA_expression + to compute their addresses. It also means that when we + adjust the stack with the popl, we have to do it all over again. */ + +#define do_cfa_expr(offset) \ + .byte 0x0f; /* DW_CFA_def_cfa_expression */ \ + .uleb128 1f-0f; /* length */ \ +0: .byte 0x74; /* DW_OP_breg4 */ \ + .sleb128 offset; /* offset */ \ + .byte 0x06; /* DW_OP_deref */ \ +1: + +#define do_expr(regno, offset) \ + .byte 0x10; /* DW_CFA_expression */ \ + .uleb128 regno; /* regno */ \ + .uleb128 1f-0f; /* length */ \ +0: .byte 0x74; /* DW_OP_breg4 */ \ + .sleb128 offset; /* offset */ \ +1: + + do_cfa_expr(IA32_SIGCONTEXT_esp+4) + do_expr(0, IA32_SIGCONTEXT_eax+4) + do_expr(1, IA32_SIGCONTEXT_ecx+4) + do_expr(2, IA32_SIGCONTEXT_edx+4) + do_expr(3, IA32_SIGCONTEXT_ebx+4) + do_expr(5, IA32_SIGCONTEXT_ebp+4) + do_expr(6, IA32_SIGCONTEXT_esi+4) + do_expr(7, IA32_SIGCONTEXT_edi+4) + do_expr(8, IA32_SIGCONTEXT_eip+4) + + .byte 0x42 /* DW_CFA_advance_loc 2 -- nop; popl eax. */ + + do_cfa_expr(IA32_SIGCONTEXT_esp) + do_expr(0, IA32_SIGCONTEXT_eax) + do_expr(1, IA32_SIGCONTEXT_ecx) + do_expr(2, IA32_SIGCONTEXT_edx) + do_expr(3, IA32_SIGCONTEXT_ebx) + do_expr(5, IA32_SIGCONTEXT_ebp) + do_expr(6, IA32_SIGCONTEXT_esi) + do_expr(7, IA32_SIGCONTEXT_edi) + do_expr(8, IA32_SIGCONTEXT_eip) + + .align 4 +.LENDFDE2: + + .long .LENDFDE3-.LSTARTFDE3 /* Length FDE */ +.LSTARTFDE3: + .long .LSTARTFDE3-.LSTARTFRAME /* CIE pointer */ + /* HACK: See above wrt unwind library assumptions. */ + .long .LSTART_rt_sigreturn-1-. /* PC-relative start address */ + .long .LEND_rt_sigreturn-.LSTART_rt_sigreturn+1 + .uleb128 0 /* Augmentation */ + /* What follows are the instructions for the table generation. + We record the locations of each register saved. This is + slightly less complicated than the above, since we don't + modify the stack pointer in the process. */ + + do_cfa_expr(IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_esp) + do_expr(0, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_eax) + do_expr(1, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_ecx) + do_expr(2, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_edx) + do_expr(3, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_ebx) + do_expr(5, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_ebp) + do_expr(6, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_esi) + do_expr(7, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_edi) + do_expr(8, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_eip) + + .align 4 +.LENDFDE3: diff -puN /dev/null arch/x86_64/ia32/vsyscall-syscall.S --- /dev/null 2002-08-30 16:31:37.000000000 -0700 +++ 25-akpm/arch/x86_64/ia32/vsyscall-syscall.S 2004-03-10 21:50:35.000000000 -0800 @@ -0,0 +1,68 @@ +/* + * Code for the vsyscall page. This version uses the syscall instruction. + */ + +#include +#include +#include + + .text + .section .text.vsyscall,"ax" + .globl __kernel_vsyscall + .type __kernel_vsyscall,@function +__kernel_vsyscall: +.LSTART_vsyscall: + push %ebp +.Lpush_ebp: + movl %ecx, %ebp + syscall + movl $__USER32_DS, %ecx + movl %ecx, %ss + movl %ebp, %ecx + popl %ebp +.Lpop_ebp: + ret +.LEND_vsyscall: + .size __kernel_vsyscall,.-.LSTART_vsyscall + + .section .eh_frame,"a",@progbits +.LSTARTFRAME: + .long .LENDCIE-.LSTARTCIE +.LSTARTCIE: + .long 0 /* CIE ID */ + .byte 1 /* Version number */ + .string "zR" /* NUL-terminated augmentation string */ + .uleb128 1 /* Code alignment factor */ + .sleb128 -4 /* Data alignment factor */ + .byte 8 /* Return address register column */ + .uleb128 1 /* Augmentation value length */ + .byte 0x1b /* DW_EH_PE_pcrel|DW_EH_PE_sdata4. */ + .byte 0x0c /* DW_CFA_def_cfa */ + .uleb128 4 + .uleb128 4 + .byte 0x88 /* DW_CFA_offset, column 0x8 */ + .uleb128 1 + .align 4 +.LENDCIE: + + .long .LENDFDE1-.LSTARTFDE1 /* Length FDE */ +.LSTARTFDE1: + .long .LSTARTFDE1-.LSTARTFRAME /* CIE pointer */ + .long .LSTART_vsyscall-. /* PC-relative start address */ + .long .LEND_vsyscall-.LSTART_vsyscall + .uleb128 0 /* Augmentation length */ + /* What follows are the instructions for the table generation. + We have to record all changes of the stack pointer. */ + .byte 0x40 + .Lpush_ebp-.LSTART_vsyscall /* DW_CFA_advance_loc */ + .byte 0x0e /* DW_CFA_def_cfa_offset */ + .uleb128 8 + .byte 0x85, 0x02 /* DW_CFA_offset %ebp -8 */ + .byte 0x40 + .Lpop_ebp-.Lpush_ebp /* DW_CFA_advance_loc */ + .byte 0xc5 /* DW_CFA_restore %ebp */ + .byte 0x0e /* DW_CFA_def_cfa_offset */ + .uleb128 4 + .align 4 +.LENDFDE1: + +#define SYSCALL_ENTER_KERNEL syscall +#include "vsyscall-sigreturn.S" diff -puN /dev/null arch/x86_64/ia32/vsyscall-sysenter.S --- /dev/null 2002-08-30 16:31:37.000000000 -0700 +++ 25-akpm/arch/x86_64/ia32/vsyscall-sysenter.S 2004-03-10 21:50:35.000000000 -0800 @@ -0,0 +1,94 @@ +/* + * Code for the vsyscall page. This version uses the sysenter instruction. + */ + +#include +#include + + .text + .section .text.vsyscall,"ax" + .globl __kernel_vsyscall + .type __kernel_vsyscall,@function +__kernel_vsyscall: +.LSTART_vsyscall: + push %ecx +.Lpush_ecx: + push %edx +.Lpush_edx: + push %ebp +.Lenter_kernel: + movl %esp,%ebp + sysenter + .space 7,0x90 + jmp .Lenter_kernel + /* 16: System call normal return point is here! */ + pop %ebp +.Lpop_ebp: + pop %edx +.Lpop_edx: + pop %ecx +.Lpop_ecx: + ret +.LEND_vsyscall: + .size __kernel_vsyscall,.-.LSTART_vsyscall + + .section .eh_frame,"a",@progbits +.LSTARTFRAME: + .long .LENDCIE-.LSTARTCIE +.LSTARTCIE: + .long 0 /* CIE ID */ + .byte 1 /* Version number */ + .string "zR" /* NUL-terminated augmentation string */ + .uleb128 1 /* Code alignment factor */ + .sleb128 -4 /* Data alignment factor */ + .byte 8 /* Return address register column */ + .uleb128 1 /* Augmentation value length */ + .byte 0x1b /* DW_EH_PE_pcrel|DW_EH_PE_sdata4. */ + .byte 0x0c /* DW_CFA_def_cfa */ + .uleb128 4 + .uleb128 4 + .byte 0x88 /* DW_CFA_offset, column 0x8 */ + .uleb128 1 + .align 4 +.LENDCIE: + + .long .LENDFDE1-.LSTARTFDE1 /* Length FDE */ +.LSTARTFDE1: + .long .LSTARTFDE1-.LSTARTFRAME /* CIE pointer */ + .long .LSTART_vsyscall-. /* PC-relative start address */ + .long .LEND_vsyscall-.LSTART_vsyscall + .uleb128 0 /* Augmentation length */ + /* What follows are the instructions for the table generation. + We have to record all changes of the stack pointer. */ + .byte 0x04 /* DW_CFA_advance_loc4 */ + .long .Lpush_ecx-.LSTART_vsyscall + .byte 0x0e /* DW_CFA_def_cfa_offset */ + .byte 0x08 /* RA at offset 8 now */ + .byte 0x04 /* DW_CFA_advance_loc4 */ + .long .Lpush_edx-.Lpush_ecx + .byte 0x0e /* DW_CFA_def_cfa_offset */ + .byte 0x0c /* RA at offset 12 now */ + .byte 0x04 /* DW_CFA_advance_loc4 */ + .long .Lenter_kernel-.Lpush_edx + .byte 0x0e /* DW_CFA_def_cfa_offset */ + .byte 0x10 /* RA at offset 16 now */ + .byte 0x85, 0x04 /* DW_CFA_offset %ebp -16 */ + /* Finally the epilogue. */ + .byte 0x04 /* DW_CFA_advance_loc4 */ + .long .Lpop_ebp-.Lenter_kernel + .byte 0x0e /* DW_CFA_def_cfa_offset */ + .byte 0x12 /* RA at offset 12 now */ + .byte 0xc5 /* DW_CFA_restore %ebp */ + .byte 0x04 /* DW_CFA_advance_loc4 */ + .long .Lpop_edx-.Lpop_ebp + .byte 0x0e /* DW_CFA_def_cfa_offset */ + .byte 0x08 /* RA at offset 8 now */ + .byte 0x04 /* DW_CFA_advance_loc4 */ + .long .Lpop_ecx-.Lpop_edx + .byte 0x0e /* DW_CFA_def_cfa_offset */ + .byte 0x04 /* RA at offset 4 now */ + .align 4 +.LENDFDE1: + +#define SYSCALL_ENTER_KERNEL int $0x80 +#include "vsyscall-sigreturn.S" diff -puN arch/x86_64/Kconfig~x86_64-update arch/x86_64/Kconfig --- 25/arch/x86_64/Kconfig~x86_64-update 2004-03-10 21:50:35.000000000 -0800 +++ 25-akpm/arch/x86_64/Kconfig 2004-03-10 21:50:35.000000000 -0800 @@ -160,9 +160,10 @@ config X86_CPUID with major 203 and minors 0 to 31 for /dev/cpu/0/cpuid to /dev/cpu/31/cpuid. +# disable it for opteron optimized builds because it pulls in ACPI_BOOT config X86_HT bool - depends on SMP + depends on SMP && !MK8 default y config MATH_EMULATION @@ -330,6 +331,11 @@ config PCI_DIRECT depends on PCI default y +config PCI_MMCONFIG + bool "Support mmconfig PCI config space access" + depends on PCI + select ACPI_BOOT + # the drivers/pci/msi.c code needs to be fixed first before enabling config PCI_USE_VECTOR bool "Vector-based interrupt indexing" diff -puN arch/x86_64/kernel/acpi/boot.c~x86_64-update arch/x86_64/kernel/acpi/boot.c --- 25/arch/x86_64/kernel/acpi/boot.c~x86_64-update 2004-03-10 21:50:35.000000000 -0800 +++ 25-akpm/arch/x86_64/kernel/acpi/boot.c 2004-03-10 21:50:35.000000000 -0800 @@ -78,6 +78,31 @@ __acpi_map_table ( return NULL; } +#ifdef CONFIG_PCI_MMCONFIG +static int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size) +{ + struct acpi_table_mcfg *mcfg; + + if (!phys_addr || !size) + return -EINVAL; + + mcfg = (struct acpi_table_mcfg *) __acpi_map_table(phys_addr, size); + if (!mcfg) { + printk(KERN_WARNING PREFIX "Unable to map MCFG\n"); + return -ENODEV; + } + + if (mcfg->base_reserved) { + printk(KERN_ERR PREFIX "MMCONFIG not in low 4GB of memory\n"); + return -ENODEV; + } + + pci_mmcfg_base_addr = mcfg->base_address; + + return 0; +} +#endif /* CONFIG_PCI_MMCONFIG */ + #ifdef CONFIG_X86_LOCAL_APIC static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE; @@ -234,6 +259,24 @@ acpi_parse_nmi_src ( #endif /*CONFIG_X86_IO_APIC*/ +static int __init acpi_parse_sbf(unsigned long phys_addr, unsigned long size) +{ + struct acpi_table_sbf *sb; + + if (!phys_addr || !size) + return -EINVAL; + + sb = (struct acpi_table_sbf *) __acpi_map_table(phys_addr, size); + if (!sb) { + printk(KERN_WARNING PREFIX "Unable to map SBF\n"); + return -ENODEV; + } + + sbf_port = sb->sbf_cmos; /* Save CMOS port */ + + return 0; +} + #ifdef CONFIG_HPET_TIMER static int __init acpi_parse_hpet ( @@ -404,6 +447,8 @@ acpi_boot_init (void) return result; } + (void) acpi_table_parse(ACPI_BOOT, acpi_parse_sbf); + result = acpi_blacklisted(); if (result) { printk(KERN_WARNING PREFIX "BIOS listed in blacklist, disabling ACPI support\n"); @@ -550,6 +595,12 @@ acpi_boot_init (void) printk("ACPI: no HPET table found (%d).\n", result); #endif +#ifdef CONFIG_PCI_MMCONFIG + result = acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg); + if (result) + printk(KERN_ERR PREFIX "Error %d parsing MCFG\n", result); +#endif + return 0; } diff -puN arch/x86_64/kernel/entry.S~x86_64-update arch/x86_64/kernel/entry.S --- 25/arch/x86_64/kernel/entry.S~x86_64-update 2004-03-10 21:50:35.000000000 -0800 +++ 25-akpm/arch/x86_64/kernel/entry.S 2004-03-10 21:50:35.000000000 -0800 @@ -226,7 +226,7 @@ sysret_careful: /* Handle a signal */ sysret_signal: sti - testl $(_TIF_SIGPENDING|_TIF_NOTIFY_RESUME),%edx + testl $(_TIF_SIGPENDING|_TIF_NOTIFY_RESUME|_TIF_SINGLESTEP),%edx jz 1f /* Really a signal */ @@ -307,7 +307,7 @@ int_very_careful: jmp int_restore_rest int_signal: - testl $(_TIF_NOTIFY_RESUME|_TIF_SIGPENDING),%edx + testl $(_TIF_NOTIFY_RESUME|_TIF_SIGPENDING|_TIF_SINGLESTEP),%edx jz 1f movq %rsp,%rdi # &ptregs -> arg1 xorl %esi,%esi # oldset -> arg2 @@ -489,7 +489,7 @@ retint_careful: jmp retint_check retint_signal: - testl $(_TIF_SIGPENDING|_TIF_NOTIFY_RESUME),%edx + testl $(_TIF_SIGPENDING|_TIF_NOTIFY_RESUME|_TIF_SINGLESTEP),%edx jz retint_swapgs sti SAVE_REST @@ -572,6 +572,24 @@ ENTRY(spurious_interrupt) jmp error_entry .endm + /* error code is on the stack already */ + /* handle NMI like exceptions that can happen everywhere */ + .macro paranoidentry sym + SAVE_ALL + cld + movl $1,%ebx + movl $MSR_GS_BASE,%ecx + rdmsr + testl %edx,%edx + js 1f + swapgs + xorl %ebx,%ebx +1: movq %rsp,%rdi + movq ORIG_RAX(%rsp),%rsi + movq $-1,ORIG_RAX(%rsp) + call \sym + .endm + /* * Exception entry point. This expects an error code/orig_rax on the stack * and the exception handler in %rax. @@ -625,6 +643,7 @@ error_sti: movq ORIG_RAX(%rsp),%rsi /* get error code */ movq $-1,ORIG_RAX(%rsp) call *%rax + /* ebx: no swapgs flag (1: don't need swapgs, 0: need it) */ error_exit: movl %ebx,%eax RESTORE_REST @@ -776,48 +795,59 @@ ENTRY(simd_coprocessor_error) zeroentry do_simd_coprocessor_error ENTRY(device_not_available) - CFI_STARTPROC - pushq $-1 #error code - SAVE_ALL - movl $1,%ebx - testl $3,CS(%rsp) - je 1f - xorl %ebx,%ebx - swapgs -1: movq %cr0,%rax - leaq math_state_restore(%rip),%rcx - leaq math_emulate(%rip),%rdx - testl $0x4,%eax - cmoveq %rcx,%rdx - call *%rdx - jmp error_exit - CFI_ENDPROC + zeroentry math_state_restore + /* runs on exception stack */ ENTRY(debug) - zeroentry do_debug + CFI_STARTPROC + pushq $0 + CFI_ADJUST_CFA_OFFSET 8 + paranoidentry do_debug +paranoid_stack_switch: + testq %rax,%rax + jz paranoid_exit + /* switch back to process stack to restore the state ptrace touched */ + movq %rax,%rsp + jmp paranoid_exit + CFI_ENDPROC + /* runs on exception stack */ ENTRY(nmi) CFI_STARTPROC pushq $-1 - SAVE_ALL - /* NMI could happen inside the critical section of a swapgs, - so it is needed to use this expensive way to check. */ - movl $MSR_GS_BASE,%ecx - rdmsr - xorl %ebx,%ebx - testl %edx,%edx - js 1f - swapgs - movl $1,%ebx -1: movq %rsp,%rdi # regs -> arg1 - call do_nmi - /* XXX: should do preemption checks here */ + CFI_ADJUST_CFA_OFFSET 8 + paranoidentry do_nmi + /* ebx: no swapgs flag */ +paranoid_exit: + testl $3,CS(%rsp) + jnz paranoid_userspace + testl %ebx,%ebx /* swapgs needed? */ + jnz paranoid_restore +paranoid_swapgs: cli - testl %ebx,%ebx - jz 2f swapgs -2: RESTORE_ALL 8 +paranoid_restore: + RESTORE_ALL 8 iretq +paranoid_userspace: + cli + GET_THREAD_INFO(%rcx) + movl threadinfo_flags(%rcx),%edx + testl $_TIF_NEED_RESCHED,%edx + jnz paranoid_resched + testl $(_TIF_SIGPENDING|_TIF_NOTIFY_RESUME|_TIF_SINGLESTEP),%edx + jnz paranoid_signal + jmp paranoid_swapgs +paranoid_resched: + sti + call schedule + jmp paranoid_exit +paranoid_signal: + sti + xorl %esi,%esi /* oldset */ + movq %rsp,%rdi /* &pt_regs */ + call do_notify_resume + jmp paranoid_exit CFI_ENDPROC ENTRY(int3) @@ -838,8 +868,10 @@ ENTRY(coprocessor_segment_overrun) ENTRY(reserved) zeroentry do_reserved + /* runs on exception stack */ ENTRY(double_fault) - errorentry do_double_fault + paranoidentry do_double_fault + jmp paranoid_stack_switch ENTRY(invalid_TSS) errorentry do_invalid_TSS @@ -847,8 +879,10 @@ ENTRY(invalid_TSS) ENTRY(segment_not_present) errorentry do_segment_not_present + /* runs on exception stack */ ENTRY(stack_segment) - errorentry do_stack_segment + paranoidentry do_stack_segment + jmp paranoid_stack_switch ENTRY(general_protection) errorentry do_general_protection @@ -862,8 +896,14 @@ ENTRY(divide_error) ENTRY(spurious_interrupt_bug) zeroentry do_spurious_interrupt_bug + /* runs on exception stack */ ENTRY(machine_check) - zeroentry do_machine_check + CFI_STARTPROC + pushq $0 + CFI_ADJUST_CFA_OFFSET 8 + paranoidentry do_machine_check + jmp paranoid_exit + CFI_ENDPROC ENTRY(call_debug) zeroentry do_call_debug diff -puN arch/x86_64/kernel/ioport.c~x86_64-update arch/x86_64/kernel/ioport.c --- 25/arch/x86_64/kernel/ioport.c~x86_64-update 2004-03-10 21:50:35.000000000 -0800 +++ 25-akpm/arch/x86_64/kernel/ioport.c 2004-03-10 21:50:35.000000000 -0800 @@ -95,7 +95,5 @@ asmlinkage long sys_iopl(unsigned int le return -EPERM; } regs.eflags = (regs.eflags &~ 0x3000UL) | (level << 12); - /* Make sure we return the long way (not sysenter) */ - set_thread_flag(TIF_IRET); return 0; } diff -puN arch/x86_64/kernel/Makefile~x86_64-update arch/x86_64/kernel/Makefile --- 25/arch/x86_64/kernel/Makefile~x86_64-update 2004-03-10 21:50:35.000000000 -0800 +++ 25-akpm/arch/x86_64/kernel/Makefile 2004-03-10 21:50:35.000000000 -0800 @@ -8,10 +8,9 @@ obj-y := process.o semaphore.o signal.o ptrace.o i8259.o ioport.o ldt.o setup.o time.o sys_x86_64.o \ x8664_ksyms.o i387.o syscall.o vsyscall.o \ setup64.o bootflag.o e820.o reboot.o warmreboot.o -obj-y += mce.o +obj-y += mce.o acpi/ obj-$(CONFIG_MTRR) += ../../i386/kernel/cpu/mtrr/ -obj-$(CONFIG_ACPI) += acpi/ obj-$(CONFIG_X86_MSR) += msr.o obj-$(CONFIG_MICROCODE) += microcode.o obj-$(CONFIG_X86_CPUID) += cpuid.o diff -puN arch/x86_64/kernel/mpparse.c~x86_64-update arch/x86_64/kernel/mpparse.c --- 25/arch/x86_64/kernel/mpparse.c~x86_64-update 2004-03-10 21:50:35.000000000 -0800 +++ 25-akpm/arch/x86_64/kernel/mpparse.c 2004-03-10 21:50:35.000000000 -0800 @@ -880,6 +880,7 @@ extern FADT_DESCRIPTOR acpi_fadt; void __init mp_config_ioapic_for_sci(int irq) { +#ifdef CONFIG_ACPI_INTERPRETER int ioapic; int ioapic_pin; struct acpi_table_madt *madt; @@ -939,6 +940,7 @@ found: */ io_apic_set_pci_routing(ioapic, ioapic_pin, irq, (flags.trigger == 1 ? 0 : 1), (flags.polarity == 1 ? 0 : 1)); +#endif } #ifdef CONFIG_ACPI_PCI diff -puN arch/x86_64/kernel/pci-gart.c~x86_64-update arch/x86_64/kernel/pci-gart.c --- 25/arch/x86_64/kernel/pci-gart.c~x86_64-update 2004-03-10 21:50:35.000000000 -0800 +++ 25-akpm/arch/x86_64/kernel/pci-gart.c 2004-03-10 21:50:35.000000000 -0800 @@ -50,6 +50,12 @@ int force_iommu = 0; #endif int iommu_merge = 0; int iommu_sac_force = 0; + +/* If this is disabled the IOMMU will use an optimized flushing strategy + of only flushing when an mapping is reused. With it true the GART is flushed + for every mapping. Problem is that doing the lazy flush seems to trigger + bugs with some popular PCI cards, in particular 3ware (but has been also + also seen with Qlogic at least). */ int iommu_fullflush = 1; #define MAX_NB 8 diff -puN arch/x86_64/kernel/process.c~x86_64-update arch/x86_64/kernel/process.c --- 25/arch/x86_64/kernel/process.c~x86_64-update 2004-03-10 21:50:35.000000000 -0800 +++ 25-akpm/arch/x86_64/kernel/process.c 2004-03-10 21:50:35.000000000 -0800 @@ -53,7 +53,7 @@ asmlinkage extern void ret_from_fork(voi unsigned long kernel_thread_flags = CLONE_VM | CLONE_UNTRACED; -int hlt_counter; +atomic_t hlt_counter = ATOMIC_INIT(0); /* * Powermanagement idle function, if any.. @@ -62,14 +62,14 @@ void (*pm_idle)(void); void disable_hlt(void) { - hlt_counter++; + atomic_inc(&hlt_counter); } EXPORT_SYMBOL(disable_hlt); void enable_hlt(void) { - hlt_counter--; + atomic_dec(&hlt_counter); } EXPORT_SYMBOL(enable_hlt); @@ -80,7 +80,7 @@ EXPORT_SYMBOL(enable_hlt); */ void default_idle(void) { - if (!hlt_counter) { + if (!atomic_read(&hlt_counter)) { local_irq_disable(); if (!need_resched()) safe_halt(); diff -puN arch/x86_64/kernel/setup64.c~x86_64-update arch/x86_64/kernel/setup64.c --- 25/arch/x86_64/kernel/setup64.c~x86_64-update 2004-03-10 21:50:35.000000000 -0800 +++ 25-akpm/arch/x86_64/kernel/setup64.c 2004-03-10 21:50:35.000000000 -0800 @@ -202,7 +202,7 @@ void __init syscall_init(void) wrmsrl(MSR_LSTAR, system_call); #ifdef CONFIG_IA32_EMULATION - wrmsrl(MSR_CSTAR, ia32_cstar_target); + syscall32_cpu_init (); #endif /* Flags to clear on syscall */ @@ -274,6 +274,9 @@ void __init cpu_init (void) asm volatile("pushfq ; popq %%rax ; btr $14,%%rax ; pushq %%rax ; popfq" ::: "eax"); + if (cpu == 0) + early_identify_cpu(&boot_cpu_data); + syscall_init(); wrmsrl(MSR_FS_BASE, 0); @@ -287,7 +290,8 @@ void __init cpu_init (void) */ for (v = 0; v < N_EXCEPTION_STACKS; v++) { if (cpu) { - estacks = (char *)__get_free_pages(GFP_ATOMIC, 0); + estacks = (char *)__get_free_pages(GFP_ATOMIC, + EXCEPTION_STACK_ORDER); if (!estacks) panic("Cannot allocate exception stack %ld %d\n", v, cpu); diff -puN arch/x86_64/kernel/setup.c~x86_64-update arch/x86_64/kernel/setup.c --- 25/arch/x86_64/kernel/setup.c~x86_64-update 2004-03-10 21:50:35.000000000 -0800 +++ 25-akpm/arch/x86_64/kernel/setup.c 2004-03-10 21:50:35.000000000 -0800 @@ -218,6 +218,11 @@ static __init void parse_cmdline_early ( if (!memcmp(from, "acpi=ht", 7)) { acpi_ht = 1; } + + /* acpi=strict disables out-of-spec workarounds */ + else if (!memcmp(from, "acpi=strict", 11)) { + acpi_strict = 1; + } #endif if (!memcmp(from, "nolapic", 7) || @@ -793,13 +798,12 @@ struct cpu_model_info { char *model_names[16]; }; -/* - * This does the hard work of actually picking apart the CPU stuff... - */ -void __init identify_cpu(struct cpuinfo_x86 *c) +/* Do some early cpuid on the boot CPU to get some parameter that are + needed before check_bugs. Everything advanced is in identify_cpu + below. */ +void __init early_identify_cpu(struct cpuinfo_x86 *c) { - int i; - u32 xlvl, tfms; + u32 tfms; c->loops_per_jiffy = loops_per_jiffy; c->x86_cache_size = -1; @@ -807,6 +811,7 @@ void __init identify_cpu(struct cpuinfo_ c->x86_model = c->x86_mask = 0; /* So far unknown... */ c->x86_vendor_id[0] = '\0'; /* Unset */ c->x86_model_id[0] = '\0'; /* Unset */ + c->x86_clflush_size = 64; memset(&c->x86_capability, 0, sizeof c->x86_capability); /* Get vendor name */ @@ -816,6 +821,7 @@ void __init identify_cpu(struct cpuinfo_ (int *)&c->x86_vendor_id[4]); get_cpu_vendor(c); + /* Initialize the standard set of capabilities */ /* Note that the vendor-specific code below might override */ @@ -837,6 +843,17 @@ void __init identify_cpu(struct cpuinfo_ /* Have CPUID level 0 only - unheard of */ c->x86 = 4; } +} + +/* + * This does the hard work of actually picking apart the CPU stuff... + */ +void __init identify_cpu(struct cpuinfo_x86 *c) +{ + int i; + u32 xlvl; + + early_identify_cpu(c); /* AMD-defined flags: level 0x80000001 */ xlvl = cpuid_eax(0x80000000); @@ -854,7 +871,6 @@ void __init identify_cpu(struct cpuinfo_ c->x86_capability[2] = cpuid_edx(0x80860001); } - /* * Vendor-specific initialization. In this section we * canonicalize the feature flags, meaning if there are diff -puN arch/x86_64/kernel/smpboot.c~x86_64-update arch/x86_64/kernel/smpboot.c --- 25/arch/x86_64/kernel/smpboot.c~x86_64-update 2004-03-10 21:50:35.000000000 -0800 +++ 25-akpm/arch/x86_64/kernel/smpboot.c 2004-03-10 21:50:35.000000000 -0800 @@ -55,11 +55,16 @@ /* Number of siblings per CPU package */ int smp_num_siblings = 1; -int phys_proc_id[NR_CPUS]; /* Package ID of each logical CPU */ +char phys_proc_id[NR_CPUS]; /* Package ID of each logical CPU */ /* Bitmask of currently online CPUs */ cpumask_t cpu_online_map; +/* which CPU (physical APIC ID) maps to which logical CPU number */ +volatile char x86_apicid_to_cpu[NR_CPUS]; +/* which logical CPU number maps to which CPU (physical APIC ID) */ +volatile char x86_cpu_to_apicid[NR_CPUS]; + static cpumask_t cpu_callin_map; cpumask_t cpu_callout_map; static cpumask_t smp_commenced_mask; @@ -70,7 +75,7 @@ struct cpuinfo_x86 cpu_data[NR_CPUS] __c /* Set when the idlers are all forked */ int smp_threads_ready; -int cpu_sibling_map[NR_CPUS] __cacheline_aligned; +char cpu_sibling_map[NR_CPUS] __cacheline_aligned; /* * Trampoline 80x86 program as an array. @@ -574,6 +579,9 @@ static void __init do_boot_cpu (int apic if (IS_ERR(idle)) panic("failed fork for CPU %d", cpu); wake_up_forked_process(idle); + x86_cpu_to_apicid[cpu] = apicid; + x86_apicid_to_cpu[apicid] = cpu; + /* * We remove it from the pidhash and the runqueue @@ -885,7 +893,7 @@ static void __init smp_boot_cpus(unsigne break; } } - if (cpu_sibling_map[cpu] == NO_PROC_ID) { + if (cpu_sibling_map[cpu] == (char)NO_PROC_ID) { smp_num_siblings = 1; printk(KERN_WARNING "WARNING: No sibling found for CPU %d.\n", cpu); } diff -puN arch/x86_64/kernel/traps.c~x86_64-update arch/x86_64/kernel/traps.c --- 25/arch/x86_64/kernel/traps.c~x86_64-update 2004-03-10 21:50:35.000000000 -0800 +++ 25-akpm/arch/x86_64/kernel/traps.c 2004-03-10 21:50:35.000000000 -0800 @@ -351,24 +351,19 @@ void oops_end(void) void __die(const char * str, struct pt_regs * regs, long err) { - int nl = 0; static int die_counter; - printk(KERN_EMERG "%s: %04lx [%u]\n", str, err & 0xffff,++die_counter); - notify_die(DIE_OOPS, (char *)str, regs, err, 255, SIGSEGV); + printk(KERN_EMERG "%s: %04lx [%u] ", str, err & 0xffff,++die_counter); #ifdef CONFIG_PREEMPT printk("PREEMPT "); - nl = 1; #endif #ifdef CONFIG_SMP printk("SMP "); - nl = 1; #endif #ifdef CONFIG_DEBUG_PAGEALLOC printk("DEBUG_PAGEALLOC"); - nl = 1; #endif - if (nl) printk("\n"); + notify_die(DIE_OOPS, (char *)str, regs, err, 255, SIGSEGV); show_registers(regs); /* Executive summary in case the oops scrolled away */ printk("RIP "); @@ -475,14 +470,27 @@ DO_ERROR( 4, SIGSEGV, "overflow", overfl DO_ERROR( 5, SIGSEGV, "bounds", bounds) DO_ERROR_INFO( 6, SIGILL, "invalid operand", invalid_op, ILL_ILLOPN, regs->rip) DO_ERROR( 7, SIGSEGV, "device not available", device_not_available) -DO_ERROR( 8, SIGSEGV, "double fault", double_fault) DO_ERROR( 9, SIGFPE, "coprocessor segment overrun", coprocessor_segment_overrun) DO_ERROR(10, SIGSEGV, "invalid TSS", invalid_TSS) DO_ERROR(11, SIGBUS, "segment not present", segment_not_present) -DO_ERROR(12, SIGBUS, "stack segment", stack_segment) DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, get_cr2()) DO_ERROR(18, SIGSEGV, "reserved", reserved) +#define DO_ERROR_STACK(trapnr, signr, str, name) \ +asmlinkage unsigned long do_##name(struct pt_regs * regs, long error_code) \ +{ \ + struct pt_regs *pr = ((struct pt_regs *)(current->thread.rsp0))-1; \ + if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) == NOTIFY_BAD) \ + return 0; \ + if (regs->cs & 3) \ + memcpy(pr, regs, sizeof(struct pt_regs)); \ + do_trap(trapnr, signr, str, regs, error_code, NULL); \ + return (regs->cs & 3) ? (unsigned long)pr : 0; \ +} + +DO_ERROR_STACK(12, SIGBUS, "stack segment", stack_segment) +DO_ERROR_STACK( 8, SIGSEGV, "double fault", double_fault) + asmlinkage void do_general_protection(struct pt_regs * regs, long error_code) { conditional_sti(regs); @@ -596,12 +604,18 @@ asmlinkage void default_do_nmi(struct pt inb(0x71); /* dummy */ } -asmlinkage void do_debug(struct pt_regs * regs, long error_code) +/* runs on IST stack. */ +asmlinkage unsigned long do_debug(struct pt_regs * regs, unsigned long error_code) { + struct pt_regs *processregs; unsigned long condition; struct task_struct *tsk = current; siginfo_t info; + processregs = (struct pt_regs *)(current->thread.rsp0)-1; + if (regs->cs & 3) + memcpy(processregs, regs, sizeof(struct pt_regs)); + #ifdef CONFIG_CHECKING { /* RED-PEN interaction with debugger - could destroy gs */ @@ -658,17 +672,21 @@ asmlinkage void do_debug(struct pt_regs force_sig_info(SIGTRAP, &info, tsk); clear_dr7: asm volatile("movq %0,%%db7"::"r"(0UL)); - notify_die(DIE_DEBUG, "debug", regs, error_code, 1, SIGTRAP); - return; + notify_die(DIE_DEBUG, "debug", regs, condition, 1, SIGTRAP); +out: + return (regs->cs & 3) ? (unsigned long)processregs : 0; clear_TF_reenable: + printk("clear_tf_reenable\n"); set_tsk_thread_flag(tsk, TIF_SINGLESTEP); clear_TF: /* RED-PEN could cause spurious errors */ - if (notify_die(DIE_DEBUG, "debug2", regs, error_code, 1, SIGTRAP) != NOTIFY_BAD) + if (notify_die(DIE_DEBUG, "debug2", regs, condition, 1, SIGTRAP) + != NOTIFY_BAD) regs->eflags &= ~TF_MASK; - return; + + goto out; } /* @@ -730,7 +748,7 @@ void math_error(void *rip) force_sig_info(SIGFPE, &info, task); } -asmlinkage void do_coprocessor_error(struct pt_regs * regs, long error_code) +asmlinkage void do_coprocessor_error(struct pt_regs * regs) { conditional_sti(regs); math_error((void *)regs->rip); @@ -789,8 +807,7 @@ static inline void simd_math_error(void force_sig_info(SIGFPE, &info, task); } -asmlinkage void do_simd_coprocessor_error(struct pt_regs * regs, - long error_code) +asmlinkage void do_simd_coprocessor_error(struct pt_regs * regs) { conditional_sti(regs); simd_math_error((void *)regs->rip); @@ -818,11 +835,6 @@ asmlinkage void math_state_restore(void) me->thread_info->status |= TS_USEDFPU; } -asmlinkage void math_emulate(void) -{ - BUG(); -} - void do_call_debug(struct pt_regs *regs) { notify_die(DIE_CALL, "debug call", regs, 0, 255, SIGINT); @@ -831,7 +843,7 @@ void do_call_debug(struct pt_regs *regs) void __init trap_init(void) { set_intr_gate(0,÷_error); - set_intr_gate(1,&debug); + set_intr_gate_ist(1,&debug,DEBUG_STACK); set_intr_gate_ist(2,&nmi,NMI_STACK); set_system_gate(3,&int3); /* int3-5 can be called from all */ set_system_gate(4,&overflow); @@ -848,7 +860,7 @@ void __init trap_init(void) set_intr_gate(15,&spurious_interrupt_bug); set_intr_gate(16,&coprocessor_error); set_intr_gate(17,&alignment_check); - set_intr_gate(18,&machine_check); + set_intr_gate_ist(18,&machine_check, MCE_STACK); set_intr_gate(19,&simd_coprocessor_error); #ifdef CONFIG_IA32_EMULATION diff -puN arch/x86_64/kernel/vsyscall.c~x86_64-update arch/x86_64/kernel/vsyscall.c --- 25/arch/x86_64/kernel/vsyscall.c~x86_64-update 2004-03-10 21:50:35.000000000 -0800 +++ 25-akpm/arch/x86_64/kernel/vsyscall.c 2004-03-10 21:50:35.000000000 -0800 @@ -31,9 +31,6 @@ * broken programs will segfault and there's no security risk until we choose to * fix it. * - * Add HPET support (port from 2.4). Still needed? - * Nop out vsyscall syscall to avoid anchor for buffer overflows when sysctl off. - * * These are not urgent things that we need to address only before shipping the first * production binary kernels. */ @@ -89,7 +86,7 @@ static force_inline void do_vgettimeofda if (t < __vxtime.last_tsc) t = __vxtime.last_tsc; usec += ((t - __vxtime.last_tsc) * __vxtime.tsc_quot) >> 32; - /* See comment in x86_64 do_gettimeopfday. */ + /* See comment in x86_64 do_gettimeofday. */ } else { usec += ((readl(fix_to_virt(VSYSCALL_HPET) + 0xf0) - __vxtime.last) * __vxtime.quot) >> 32; @@ -106,6 +103,7 @@ static force_inline void do_get_tz(struc *tz = __sys_tz; } + static force_inline int gettimeofday(struct timeval *tv, struct timezone *tz) { int ret; @@ -115,6 +113,15 @@ static force_inline int gettimeofday(str return ret; } +static force_inline long time_syscall(long *t) +{ + long secs; + asm volatile("syscall" + : "=a" (secs) + : "0" (__NR_time),"D" (t) : __syscall_clobber); + return secs; +} + static int __vsyscall(0) vgettimeofday(struct timeval * tv, struct timezone * tz) { if (unlikely(!__sysctl_vsyscall)) @@ -126,16 +133,15 @@ static int __vsyscall(0) vgettimeofday(s return 0; } -static time_t __vsyscall(1) vtime(time_t * t) +/* This will break when the xtime seconds get inaccurate, but that is + * unlikely */ +static time_t __vsyscall(1) vtime(time_t *t) { - struct timeval tv; if (unlikely(!__sysctl_vsyscall)) - gettimeofday(&tv, NULL); - else - do_vgettimeofday(&tv); - if (t) - *t = tv.tv_sec; - return tv.tv_sec; + return time_syscall(t); + else if (t) + *t = __xtime.tv_sec; + return __xtime.tv_sec; } static long __vsyscall(2) venosys_0(void) diff -puN arch/x86_64/kernel/x8664_ksyms.c~x86_64-update arch/x86_64/kernel/x8664_ksyms.c --- 25/arch/x86_64/kernel/x8664_ksyms.c~x86_64-update 2004-03-10 21:50:35.000000000 -0800 +++ 25-akpm/arch/x86_64/kernel/x8664_ksyms.c 2004-03-10 21:50:35.000000000 -0800 @@ -225,3 +225,6 @@ EXPORT_SYMBOL_GPL(flush_tlb_all); #endif EXPORT_SYMBOL(sys_ioctl); + +EXPORT_SYMBOL(memcpy_toio); +EXPORT_SYMBOL(memcpy_fromio); diff -puN arch/x86_64/lib/csum-copy.S~x86_64-update arch/x86_64/lib/csum-copy.S --- 25/arch/x86_64/lib/csum-copy.S~x86_64-update 2004-03-10 21:50:35.000000000 -0800 +++ 25-akpm/arch/x86_64/lib/csum-copy.S 2004-03-10 21:50:35.000000000 -0800 @@ -220,10 +220,14 @@ csum_partial_copy_generic: /* Exception handlers. Very simple, zeroing is done in the wrappers */ .Lbad_source: movq (%rsp),%rax + testq %rax,%rax + jz .Lende movl $-EFAULT,(%rax) jmp .Lende .Lbad_dest: movq 8(%rsp),%rax + testq %rax,%rax + jz .Lende movl $-EFAULT,(%rax) jmp .Lende diff -puN arch/x86_64/lib/io.c~x86_64-update arch/x86_64/lib/io.c --- 25/arch/x86_64/lib/io.c~x86_64-update 2004-03-10 21:50:35.000000000 -0800 +++ 25-akpm/arch/x86_64/lib/io.c 2004-03-10 21:50:35.000000000 -0800 @@ -11,7 +11,3 @@ void *memcpy_fromio(void *dst,const void { return __inline_memcpy(dst,__io_virt(src),len); } - -EXPORT_SYMBOL(memcpy_toio); -EXPORT_SYMBOL(memcpy_fromio); - diff -puN arch/x86_64/Makefile~x86_64-update arch/x86_64/Makefile --- 25/arch/x86_64/Makefile~x86_64-update 2004-03-10 21:50:35.000000000 -0800 +++ 25-akpm/arch/x86_64/Makefile 2004-03-10 21:50:35.000000000 -0800 @@ -63,7 +63,7 @@ head-y := arch/x86_64/kernel/head.o arch libs-y += arch/x86_64/lib/ core-y += arch/x86_64/kernel/ arch/x86_64/mm/ core-$(CONFIG_IA32_EMULATION) += arch/x86_64/ia32/ -drivers-$(CONFIG_PCI) += arch/i386/pci/ +drivers-$(CONFIG_PCI) += arch/x86_64/pci/ drivers-$(CONFIG_OPROFILE) += arch/x86_64/oprofile/ boot := arch/x86_64/boot diff -puN arch/x86_64/mm/fault.c~x86_64-update arch/x86_64/mm/fault.c --- 25/arch/x86_64/mm/fault.c~x86_64-update 2004-03-10 21:50:35.000000000 -0800 +++ 25-akpm/arch/x86_64/mm/fault.c 2004-03-10 21:50:35.000000000 -0800 @@ -280,15 +280,6 @@ asmlinkage void do_page_fault(struct pt_ if (unlikely(in_atomic() || !mm)) goto bad_area_nosemaphore; - /* Work around K8 erratum #100 - K8 in compat mode occasionally jumps to illegal addresses >4GB. - We catch this here in the page fault handler because these - addresses are not reachable. Just detect this case and return. - Any code segment in LDT is compatibility mode. */ - if ((regs->cs == __USER32_CS || (regs->cs & (1<<2))) && - (address >> 32)) - return; - again: down_read(&mm->mmap_sem); @@ -373,6 +364,16 @@ bad_area_nosemaphore: if (is_prefetch(regs, address)) return; + /* Work around K8 erratum #100 K8 in compat mode + occasionally jumps to illegal addresses >4GB. We + catch this here in the page fault handler because + these addresses are not reachable. Just detect this + case and return. Any code segment in LDT is + compatibility mode. */ + if ((regs->cs == __USER32_CS || (regs->cs & (1<<2))) && + (address >> 32)) + return; + if (exception_trace && !unhandled_signal(tsk, SIGSEGV)) { printk(KERN_INFO "%s[%d]: segfault at %016lx rip %016lx rsp %016lx error %lx\n", diff -puN arch/x86_64/mm/init.c~x86_64-update arch/x86_64/mm/init.c --- 25/arch/x86_64/mm/init.c~x86_64-update 2004-03-10 21:50:35.000000000 -0800 +++ 25-akpm/arch/x86_64/mm/init.c 2004-03-10 21:50:35.000000000 -0800 @@ -37,7 +37,9 @@ #include #include +#ifndef Dprintk #define Dprintk(x...) +#endif extern char _stext[]; @@ -577,3 +579,32 @@ static __init int x8664_sysctl_init(void } __initcall(x8664_sysctl_init); #endif + +/* Pseudo VMAs to allow ptrace access for the vsyscall pages. x86-64 has two + different ones: one for 32bit and one for 64bit. Use the appropiate + for the target task. */ + +static struct vm_area_struct gate_vma = { + .vm_start = VSYSCALL_START, + .vm_end = VSYSCALL_END, + .vm_page_prot = PAGE_READONLY +}; + +static struct vm_area_struct gate32_vma = { + .vm_start = VSYSCALL32_BASE, + .vm_end = VSYSCALL32_END, + .vm_page_prot = PAGE_READONLY +}; + +struct vm_area_struct *get_gate_vma(struct task_struct *tsk) +{ + return test_tsk_thread_flag(tsk, TIF_IA32) ? &gate32_vma : &gate_vma; +} + +int in_gate_area(struct task_struct *task, unsigned long addr) +{ + struct vm_area_struct *vma = &gate_vma; + if (test_tsk_thread_flag(task, TIF_IA32)) + vma = &gate32_vma; + return (addr >= vma->vm_start) && (addr < vma->vm_end); +} diff -puN arch/x86_64/mm/numa.c~x86_64-update arch/x86_64/mm/numa.c --- 25/arch/x86_64/mm/numa.c~x86_64-update 2004-03-10 21:50:35.000000000 -0800 +++ 25-akpm/arch/x86_64/mm/numa.c 2004-03-10 21:50:35.000000000 -0800 @@ -14,7 +14,9 @@ #include #include +#ifndef Dprintk #define Dprintk(x...) +#endif struct pglist_data *node_data[MAXNODE]; bootmem_data_t plat_node_bdata[MAX_NUMNODES]; diff -puN arch/x86_64/pci/Makefile~x86_64-update arch/x86_64/pci/Makefile --- 25/arch/x86_64/pci/Makefile~x86_64-update 2004-03-10 21:50:35.000000000 -0800 +++ 25-akpm/arch/x86_64/pci/Makefile 2004-03-10 21:50:35.000000000 -0800 @@ -1,29 +1,22 @@ # # Makefile for X86_64 specific PCI routines # -# Reuse the i386 PCI subsystem using symlinks +# Reuse the i386 PCI subsystem # +CFLAGS += -I arch/i386/pci + obj-y := i386.o obj-$(CONFIG_PCI_DIRECT)+= direct.o obj-y += fixup.o obj-$(CONFIG_ACPI_PCI) += acpi.o obj-y += legacy.o irq.o common.o +# mmconfig has a 64bit special +obj-$(CONFIG_PCI_MMCONFIG) += mmconfig.o -$(obj)/direct.c: $(obj)/pci.h - @ln -sf ../../i386/pci/direct.c $(obj)/direct.c -$(obj)/legacy.c: $(obj)/pci.h - @ln -sf ../../i386/pci/legacy.c $(obj)/legacy.c -$(obj)/common.c: $(obj)/pci.h - @ln -sf ../../i386/pci/common.c $(obj)/common.c -$(obj)/acpi.c: $(obj)/pci.h - @ln -sf ../../i386/pci/acpi.c $(obj)/acpi.c -$(obj)/pci.h: - @ln -sf ../../i386/pci/pci.h $(obj)/pci.h -$(obj)/irq.c: $(obj)/pci.h - @ln -sf ../../i386/pci/irq.c $(obj)/irq.c -$(obj)/fixup.c: $(obj)/pci.h - @ln -sf ../../i386/pci/fixup.c $(obj)/fixup.c -$(obj)/i386.c: $(obj)/pci.h - @ln -sf ../../i386/pci/i386.c $(obj)/i386.c - -clean-files += i386.c legacy.c fixup.c acpi.c irq.c pci.h common.c direct.c +direct-y += ../../i386/pci/direct.o +acpi-y += ../../i386/pci/acpi.o +legacy-y += ../../i386/pci/legacy.o +irq-y += ../../i386/pci/irq.o +common-y += ../../i386/pci/common.o +fixup-y += ../../i386/pci/fixup.o +i386-y += ../../i386/pci/i386.o diff -puN /dev/null arch/x86_64/pci/mmconfig.c --- /dev/null 2002-08-30 16:31:37.000000000 -0700 +++ 25-akpm/arch/x86_64/pci/mmconfig.c 2004-03-10 21:50:35.000000000 -0800 @@ -0,0 +1,98 @@ +/* + * mmconfig.c - Low-level direct PCI config space access via MMCONFIG + * + * This is an 64bit optimized version that always keeps the full mmconfig + * space mapped. This allows lockless config space operation. + */ + +#include +#include +#include "pci.h" + +#define MMCONFIG_APER_SIZE (256*1024*1024) + +/* The physical address of the MMCONFIG aperture. Set from ACPI tables. */ +u32 pci_mmcfg_base_addr; + +/* Static virtual mapping of the MMCONFIG aperture */ +char *pci_mmcfg_virt; + +static inline char *pci_dev_base(int bus, int devfn) +{ + return pci_mmcfg_virt + ((bus << 20) | (devfn << 12)); +} + +static int pci_mmcfg_read(int seg, int bus, int devfn, int reg, int len, u32 *value) +{ + char *addr = pci_dev_base(bus, devfn); + + if (unlikely(!value || (bus > 255) || (devfn > 255) || (reg > 4095))) + return -EINVAL; + + switch (len) { + case 1: + *value = readb(addr + reg); + break; + case 2: + *value = readw(addr + reg); + break; + case 4: + *value = readl(addr + reg); + break; + } + + return 0; +} + +static int pci_mmcfg_write(int seg, int bus, int devfn, int reg, int len, u32 value) +{ + char *addr = pci_dev_base(bus,devfn); + + if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095))) + return -EINVAL; + + switch (len) { + case 1: + writeb(value, addr + reg); + break; + case 2: + writew(value, addr + reg); + break; + case 4: + writel(value, addr + reg); + break; + } + + /* Dummy read to flush PCI write */ + readl(addr); + + return 0; +} + +static struct pci_raw_ops pci_mmcfg = { + .read = pci_mmcfg_read, + .write = pci_mmcfg_write, +}; + +static int __init pci_mmcfg_init(void) +{ + if ((pci_probe & PCI_PROBE_MMCONF) == 0) + return 0; + if (!pci_mmcfg_base_addr) + return 0; + + /* RED-PEN i386 doesn't do _nocache right now */ + pci_mmcfg_virt = ioremap_nocache(pci_mmcfg_base_addr, MMCONFIG_APER_SIZE); + if (!pci_mmcfg_virt) { + printk("PCI: Cannot map mmconfig aperture\n"); + return 0; + } + + printk(KERN_INFO "PCI: Using MMCONFIG at %lx\n", pci_mmcfg_base_addr); + raw_pci_ops = &pci_mmcfg; + pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF; + + return 0; +} + +arch_initcall(pci_mmcfg_init); diff -puN include/asm-x86_64/calling.h~x86_64-update include/asm-x86_64/calling.h --- 25/include/asm-x86_64/calling.h~x86_64-update 2004-03-10 21:50:35.000000000 -0800 +++ 25-akpm/include/asm-x86_64/calling.h 2004-03-10 21:50:35.000000000 -0800 @@ -31,7 +31,7 @@ #define ARGOFFSET R11 #define SWFRAME ORIG_RAX - .macro SAVE_ARGS addskip=0,norcx=0 + .macro SAVE_ARGS addskip=0,norcx=0,nor891011=0 subq $9*8+\addskip,%rsp CFI_ADJUST_CFA_OFFSET 9*8+\addskip movq %rdi,8*8(%rsp) @@ -47,6 +47,8 @@ .endif movq %rax,4*8(%rsp) CFI_OFFSET rax,4*8-(9*8+\addskip) + .if \nor891011 + .else movq %r8,3*8(%rsp) CFI_OFFSET r8,3*8-(9*8+\addskip) movq %r9,2*8(%rsp) @@ -55,17 +57,21 @@ CFI_OFFSET r10,1*8-(9*8+\addskip) movq %r11,(%rsp) CFI_OFFSET r11,-(9*8+\addskip) + .endif .endm #define ARG_SKIP 9*8 - .macro RESTORE_ARGS skiprax=0,addskip=0,skiprcx=0,skipr11=0 + .macro RESTORE_ARGS skiprax=0,addskip=0,skiprcx=0,skipr11=0,skipr8910=0,skiprdx=0 .if \skipr11 .else movq (%rsp),%r11 .endif + .if \skipr8910 + .else movq 1*8(%rsp),%r10 movq 2*8(%rsp),%r9 movq 3*8(%rsp),%r8 + .endif .if \skiprax .else movq 4*8(%rsp),%rax @@ -74,7 +80,10 @@ .else movq 5*8(%rsp),%rcx .endif + .if \skiprdx + .else movq 6*8(%rsp),%rdx + .endif movq 7*8(%rsp),%rsi movq 8*8(%rsp),%rdi .if ARG_SKIP+\addskip > 0 diff -puN include/asm-x86_64/msr.h~x86_64-update include/asm-x86_64/msr.h --- 25/include/asm-x86_64/msr.h~x86_64-update 2004-03-10 21:50:35.000000000 -0800 +++ 25-akpm/include/asm-x86_64/msr.h 2004-03-10 21:50:35.000000000 -0800 @@ -156,6 +156,10 @@ extern inline unsigned int cpuid_edx(uns #define MSR_MTRRcap 0x0fe #define MSR_IA32_BBL_CR_CTL 0x119 +#define MSR_IA32_SYSENTER_CS 0x174 +#define MSR_IA32_SYSENTER_ESP 0x175 +#define MSR_IA32_SYSENTER_EIP 0x176 + #define MSR_IA32_MCG_CAP 0x179 #define MSR_IA32_MCG_STATUS 0x17a #define MSR_IA32_MCG_CTL 0x17b diff -puN include/asm-x86_64/page.h~x86_64-update include/asm-x86_64/page.h --- 25/include/asm-x86_64/page.h~x86_64-update 2004-03-10 21:50:35.000000000 -0800 +++ 25-akpm/include/asm-x86_64/page.h 2004-03-10 21:50:35.000000000 -0800 @@ -137,6 +137,13 @@ extern __inline__ int get_order(unsigned #define VM_STACK_DEFAULT_FLAGS \ (test_thread_flag(TIF_IA32) ? vm_stack_flags32 : vm_stack_flags) +#define CONFIG_ARCH_GATE_AREA 1 + +#ifndef __ASSEMBLY__ +struct task_struct; +struct vm_area_struct *get_gate_vma(struct task_struct *tsk); +int in_gate_area(struct task_struct *task, unsigned long addr); +#endif #endif /* __KERNEL__ */ diff -puN include/asm-x86_64/processor.h~x86_64-update include/asm-x86_64/processor.h --- 25/include/asm-x86_64/processor.h~x86_64-update 2004-03-10 21:50:35.000000000 -0800 +++ 25-akpm/include/asm-x86_64/processor.h 2004-03-10 21:50:35.000000000 -0800 @@ -173,7 +173,7 @@ static inline void clear_in_cr4 (unsigne * space during mmap's. */ #define IA32_PAGE_OFFSET ((current->personality & ADDR_LIMIT_3GB) ? 0xc0000000 : 0xFFFFe000) -#define TASK_UNMAPPED_32 (PAGE_ALIGN(0xc5000000)) +#define TASK_UNMAPPED_32 PAGE_ALIGN(IA32_PAGE_OFFSET/3) #define TASK_UNMAPPED_64 PAGE_ALIGN(TASK_SIZE/3) #define TASK_UNMAPPED_BASE \ (test_thread_flag(TIF_IA32) ? TASK_UNMAPPED_32 : TASK_UNMAPPED_64) @@ -262,7 +262,9 @@ struct thread_struct { #define STACKFAULT_STACK 1 #define DOUBLEFAULT_STACK 2 #define NMI_STACK 3 -#define N_EXCEPTION_STACKS 3 /* hw limit: 7 */ +#define DEBUG_STACK 4 +#define MCE_STACK 5 +#define N_EXCEPTION_STACKS 5 /* hw limit: 7 */ #define EXCEPTION_STKSZ (PAGE_SIZE << EXCEPTION_STACK_ORDER) #define EXCEPTION_STACK_ORDER 0 @@ -451,4 +453,6 @@ static inline void __mwait(unsigned long ti->task; \ }) +#define cache_line_size() (boot_cpu_data.x86_clflush_size) + #endif /* __ASM_X86_64_PROCESSOR_H */ diff -puN include/asm-x86_64/proto.h~x86_64-update include/asm-x86_64/proto.h --- 25/include/asm-x86_64/proto.h~x86_64-update 2004-03-10 21:50:35.000000000 -0800 +++ 25-akpm/include/asm-x86_64/proto.h 2004-03-10 21:50:35.000000000 -0800 @@ -21,6 +21,7 @@ extern void syscall_init(void); extern void ia32_syscall(void); extern void ia32_cstar_target(void); +extern void ia32_sysenter_target(void); extern void calibrate_delay(void); extern void cpu_idle(void); @@ -37,6 +38,8 @@ extern int numa_setup(char *opt); extern int setup_early_printk(char *); extern void early_printk(const char *fmt, ...) __attribute__((format(printf,1,2))); +extern void early_identify_cpu(struct cpuinfo_x86 *c); + extern int k8_scan_nodes(unsigned long start, unsigned long end); extern int numa_initmem_init(unsigned long start_pfn, unsigned long end_pfn); @@ -68,6 +71,7 @@ extern void show_regs(struct pt_regs * r extern int map_syscall32(struct mm_struct *mm, unsigned long address); extern char *syscall32_page; +extern void syscall32_cpu_init(void); extern void setup_node_bootmem(int nodeid, unsigned long start, unsigned long end); diff -puN include/asm-x86_64/smp.h~x86_64-update include/asm-x86_64/smp.h --- 25/include/asm-x86_64/smp.h~x86_64-update 2004-03-10 21:50:35.000000000 -0800 +++ 25-akpm/include/asm-x86_64/smp.h 2004-03-10 21:50:35.000000000 -0800 @@ -47,7 +47,7 @@ extern void smp_invalidate_rcv(void); / extern void (*mtrr_hook) (void); extern void zap_low_mappings(void); void smp_stop_cpu(void); -extern int cpu_sibling_map[]; +extern char cpu_sibling_map[]; #define SMP_TRAMPOLINE_BASE 0x6000 @@ -74,7 +74,15 @@ extern __inline int hard_smp_processor_i return GET_APIC_ID(*(unsigned int *)(APIC_BASE+APIC_ID)); } -#define safe_smp_processor_id() (disable_apic ? 0 : hard_smp_processor_id()) +/* + * Some lowlevel functions might want to know about + * the real APIC ID <-> CPU # mapping. + * AK: why is this volatile? + */ +extern volatile char x86_apicid_to_cpu[NR_CPUS]; +extern volatile char x86_cpu_to_apicid[NR_CPUS]; + +#define safe_smp_processor_id() (disable_apic ? 0 : x86_apicid_to_cpu[hard_smp_processor_id()]) #define cpu_online(cpu) cpu_isset(cpu, cpu_online_map) #endif /* !ASSEMBLY */ diff -puN include/asm-x86_64/thread_info.h~x86_64-update include/asm-x86_64/thread_info.h --- 25/include/asm-x86_64/thread_info.h~x86_64-update 2004-03-10 21:50:35.000000000 -0800 +++ 25-akpm/include/asm-x86_64/thread_info.h 2004-03-10 21:50:35.000000000 -0800 @@ -82,7 +82,6 @@ static inline struct thread_info *stack_ #else /* !__ASSEMBLY__ */ /* how to get the thread information struct from ASM */ -/* only works on the process stack. otherwise get it via the PDA. */ #define GET_THREAD_INFO(reg) \ movq %gs:pda_kernelstack,reg ; \ subq $(THREAD_SIZE-PDA_STACKOFFSET),reg @@ -118,8 +117,10 @@ static inline struct thread_info *stack_ #define _TIF_FORK (1<