]> git.hungrycats.org Git - linux/commitdiff
[PATCH] x86-64 merge
authorAndi Kleen <ak@muc.de>
Fri, 20 Dec 2002 13:37:00 +0000 (05:37 -0800)
committerLinus Torvalds <torvalds@home.transmeta.com>
Fri, 20 Dec 2002 13:37:00 +0000 (05:37 -0800)
This patch depends on the i386 MTRR driver cleanup I sent earlier.

 - Support non executable mappings for x86-64. data/heap are non executable
   by default now.
 - Beginnings of software suspend from Pavel (not working yet)
 - Support generic compat functions and remove some shared code
   in the 32bit emulation (Stephen Rothwell)
 - Support hugetlbfs
 - Some makefile updates
 - Make sure all 32bit emulation functions return long, not int.
   This fixes some problems with ERESTARTNOSYS.et.al. leaking to userspace.
 - Add new system calls.
 - Fix long standing fs/gs context switch bugs (thanks to Karsten Keil
   for helping to fix that mess). Also make sure the gs selector is
   set to 0 after an exec.
 - Simplify TLS switching
 - Paranoid CPUID check at bootup
 - Reorder scatterlist to be more space efficient (Jes Soerensen)
 - Enlarge 32bit address space to full 4GB.
 - Beginnings of 32bit SYSCALL support (not completely working yet
   and vsyscall page miss yet)
 - Various merges from i386
 - New module loader
 - Support threaded core dump (XMM saving for 32bit programs doesn't
   work, but it appears to be broken on i386 too)
 - Fix bug in signal stack rounding
 - Remove DRM 32bit emulation.
 - Use MTRR driver from i386
 - Use bootflag.c from i386
 - Various other fixes and cleanups.

73 files changed:
arch/x86_64/Kconfig
arch/x86_64/Makefile
arch/x86_64/boot/Makefile
arch/x86_64/boot/compressed/Makefile
arch/x86_64/boot/compressed/misc.c
arch/x86_64/defconfig
arch/x86_64/ia32/fpu32.c
arch/x86_64/ia32/ia32_binfmt.c
arch/x86_64/ia32/ia32_ioctl.c
arch/x86_64/ia32/ia32_signal.c
arch/x86_64/ia32/ia32entry.S
arch/x86_64/ia32/ipc32.c
arch/x86_64/ia32/socket32.c
arch/x86_64/ia32/sys_ia32.c
arch/x86_64/kernel/Makefile
arch/x86_64/kernel/acpi.c
arch/x86_64/kernel/bootflag.c [deleted file]
arch/x86_64/kernel/entry.S
arch/x86_64/kernel/head.S
arch/x86_64/kernel/i387.c
arch/x86_64/kernel/i8259.c
arch/x86_64/kernel/io_apic.c
arch/x86_64/kernel/ldt.c
arch/x86_64/kernel/module.c [new file with mode: 0644]
arch/x86_64/kernel/mtrr.c [deleted file]
arch/x86_64/kernel/mtrr/Makefile [new file with mode: 0644]
arch/x86_64/kernel/nmi.c
arch/x86_64/kernel/pci-gart.c
arch/x86_64/kernel/process.c
arch/x86_64/kernel/profile.c
arch/x86_64/kernel/setup64.c
arch/x86_64/kernel/signal.c
arch/x86_64/kernel/smp.c
arch/x86_64/kernel/smpboot.c
arch/x86_64/kernel/suspend.c [new file with mode: 0644]
arch/x86_64/kernel/suspend_asm.S [new file with mode: 0644]
arch/x86_64/kernel/traps.c
arch/x86_64/kernel/x8664_ksyms.c
arch/x86_64/lib/io.c
arch/x86_64/lib/usercopy.c
arch/x86_64/mm/Makefile
arch/x86_64/mm/extable.c
arch/x86_64/mm/fault.c
arch/x86_64/mm/hugetlbpage.c [new file with mode: 0644]
arch/x86_64/mm/init.c
arch/x86_64/mm/modutil.c
arch/x86_64/pci/common.c
arch/x86_64/pci/irq.c
arch/x86_64/vmlinux.lds.S
include/asm-x86_64/bitops.h
include/asm-x86_64/calling.h
include/asm-x86_64/compat.h [new file with mode: 0644]
include/asm-x86_64/desc.h
include/asm-x86_64/elf.h
include/asm-x86_64/hardirq.h
include/asm-x86_64/i387.h
include/asm-x86_64/ia32.h
include/asm-x86_64/ia32_unistd.h
include/asm-x86_64/ide.h
include/asm-x86_64/io.h
include/asm-x86_64/io_apic.h
include/asm-x86_64/mmu_context.h
include/asm-x86_64/module.h
include/asm-x86_64/mtrr.h
include/asm-x86_64/page.h
include/asm-x86_64/pgtable.h
include/asm-x86_64/processor.h
include/asm-x86_64/scatterlist.h
include/asm-x86_64/socket32.h
include/asm-x86_64/suspend.h
include/asm-x86_64/system.h
include/asm-x86_64/thread_info.h
include/asm-x86_64/unistd.h

index 3d5d90fddec62c0d77d7346969157269b274b631..91472e7f99f7d76d40f4ab1ef28a120649a889d5 100644 (file)
@@ -175,6 +175,14 @@ config MTRR
 
          See <file:Documentation/mtrr.txt> for more information.
 
+config HUGETLB_PAGE
+       bool "Huge TLB Page Support"
+       help
+         This enables support for huge pages.  User space applications
+         can make use of this support with the hugetlbfs file system
+         To actually use it you need to pass an hugepages= argument
+         to the kernel at boot time.
+
 config SMP
        bool "Symmetric multi-processing support"
        ---help---
@@ -285,6 +293,35 @@ config PM
          will issue the hlt instruction if nothing is to be done, thereby
          sending the processor to sleep and saving power.
 
+config SOFTWARE_SUSPEND
+       bool "Software Suspend (EXPERIMENTAL)"
+       depends on EXPERIMENTAL && PM
+       ---help---
+         Enable the possibilty of suspendig machine. It doesn't need APM.
+         You may suspend your machine by 'swsusp' or 'shutdown -z <time>' 
+         (patch for sysvinit needed). 
+
+         It creates an image which is saved in your active swaps. By the next
+         booting the, pass 'resume=/path/to/your/swap/file' and kernel will 
+         detect the saved image, restore the memory from
+         it and then it continues to run as before you've suspended.
+         If you don't want the previous state to continue use the 'noresume'
+         kernel option. However note that your partitions will be fsck'd and
+         you must re-mkswap your swap partitions/files.
+
+         Right now you may boot without resuming and then later resume but
+         in meantime you cannot use those swap partitions/files which were
+         involved in suspending. Also in this case there is a risk that buffers
+         on disk won't match with saved ones.
+
+         SMP is supported ``as-is''. There's a code for it but doesn't work.
+         There have been problems reported relating SCSI.
+
+         This option is about getting stable. However there is still some
+         absence of features.
+
+         For more information take a look at Documentation/swsusp.txt.
+
 source "drivers/acpi/Kconfig"
 
 endmenu
@@ -425,6 +462,11 @@ config IA32_EMULATION
          turn this on, unless you're 100% sure that you don't have any 32bit programs
          left.
 
+config COMPAT
+       bool
+       depends on IA32_EMULATION
+       default y
+
 endmenu
 
 source "drivers/mtd/Kconfig"
@@ -692,6 +734,16 @@ config KALLSYMS
          symbolic stack backtraces. This increases the size of the kernel
          somewhat, as all symbols have to be loaded into the kernel image.
 
+config FRAME_POINTER
+       bool "Compile the kernel with frame pointers"
+       depends on DEBUG_KERNEL 
+       help
+         If you say Y here the resulting kernel image will be slightly larger
+         and slower, but it will give very useful debugging information.
+         If you don't debug the kernel, you can say N, but we may not be able
+         to solve problems without frame pointers.
+        Note this is normally not needed on x86-64.
+
 endmenu
 
 source "security/Kconfig"
index bc5c182138398e80e66d5aa73e6dadddeaa19019..ac9649fd9b876501874f9a1a02238820ef0893dc 100644 (file)
@@ -36,6 +36,7 @@ export IA32_CC IA32_LD IA32_AS IA32_OBJCOPY IA32_CPP
 LDFLAGS                := -m elf_x86_64
 OBJCOPYFLAGS   := -O binary -R .note -R .comment -S
 LDFLAGS_vmlinux := -e stext
+LDFLAGS_BLOB   := --format binary --oformat elf64-x86-64
 
 CFLAGS += -mno-red-zone
 CFLAGS += -mcmodel=kernel
@@ -54,8 +55,7 @@ core-y                                        += arch/x86_64/kernel/ arch/x86_64/mm/
 core-$(CONFIG_IA32_EMULATION)          += arch/x86_64/ia32/
 drivers-$(CONFIG_PCI)                  += arch/x86_64/pci/
 
-MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
-makeboot = $(call descend,arch/x86_64/boot,$(1))
+makeboot =$(Q)$(MAKE) -f scripts/Makefile.build obj=arch/x86_64/boot $(1)
 
 .PHONY: zImage bzImage compressed zlilo bzlilo zdisk bzdisk install \
                clean archclean archmrproper
@@ -64,21 +64,21 @@ BOOTIMAGE=arch/x86_64/boot/bzImage
 zImage zlilo zdisk: BOOTIMAGE=arch/x86_64/boot/zImage
 
 zImage bzImage: vmlinux
-       +@$(call makeboot,$(BOOTIMAGE))
+       $(call makeboot,$(BOOTIMAGE))
 
 compressed: zImage
 
 zlilo bzlilo: vmlinux
-       +@$(call makeboot,BOOTIMAGE=$(BOOTIMAGE) zlilo)
+       $(call makeboot,BOOTIMAGE=$(BOOTIMAGE) zlilo)
 
 zdisk bzdisk: vmlinux
-       +@$(call makeboot,BOOTIMAGE=$(BOOTIMAGE) zdisk)
+       $(call makeboot,BOOTIMAGE=$(BOOTIMAGE) zdisk)
 
 install: vmlinux
-       +@$(call makeboot,BOOTIMAGE=$(BOOTIMAGE) install)
+       $(call makeboot,BOOTIMAGE=$(BOOTIMAGE) install)
 
 archclean:
-       +@$(call makeboot,clean)
+       $(call makeboot,clean)
 
 archmrproper:
 
index 7440c56cc5a55e016498e561c2eadfee6f58b30c..b81e05baff846d65a76f6475caf37d84712f1423 100644 (file)
@@ -32,10 +32,6 @@ CFLAGS += -m32
 
 host-progs     := tools/build
 
-#      Default
-
-boot: bzImage
-
 # ---------------------------------------------------------------------------
 
 $(obj)/zImage:  IMAGE_OFFSET := 0x1000
@@ -62,9 +58,8 @@ $(obj)/setup $(obj)/bootsect: %: %.o FORCE
        $(call if_changed,ld)
 
 $(obj)/compressed/vmlinux: FORCE
-       +@$(call descend,$(obj)/compressed,IMAGE_OFFSET=$(IMAGE_OFFSET) \
-               $(obj)/compressed/vmlinux)
-
+       $(Q)$(MAKE) -f scripts/Makefile.build obj=$(obj)/compressed \
+                                       IMAGE_OFFSET=$(IMAGE_OFFSET) $@
 
 zdisk: $(BOOTIMAGE)
        dd bs=8192 if=$(BOOTIMAGE) of=/dev/fd0
index 52fec17d86aed58db119bf74031a46e10bc4ea70..8fd54bab42a6503f9cf5c262ca37133e2cc512af 100644 (file)
@@ -18,9 +18,9 @@ LDFLAGS_vmlinux := -Ttext $(IMAGE_OFFSET) -e startup_32 -m elf_i386
 
 $(obj)/vmlinux: $(obj)/head.o $(obj)/misc.o $(obj)/piggy.o FORCE
        $(call if_changed,ld)
+       @:
 
 $(obj)/vmlinux.bin: vmlinux FORCE
-       strip vmlinux
        $(call if_changed,objcopy)
 
 $(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE
index cc5d85df42fe70cb2f66cf02ffc2117291e660d8..3b56460d43d22cb7d5b745687c2cd8d8329ff482 100644 (file)
@@ -330,6 +330,8 @@ void close_output_buffer_if_we_run_high(struct moveparams *mv)
 void check_cpu(void)
 {
        int res = 0;
+        int tmp, flags;
+
        asm volatile( " \n\
        movl $3,%%edx           # at least 386 \n\
        pushfl                  # push EFLAGS \n\
@@ -395,6 +397,43 @@ void check_cpu(void)
        }
        if (res !=7)
                error( "Sorry, your CPU is not capable of running 64-bit kernel." );
+        /* check required feature flags */ 
+        /* see http://www.x86-64.org/lists/discuss/msg02971.html */
+#define REQUIRED_MASK1 ((1<<0)|(1<<3)|(1<<4)|(1<<5)|(1<<6)|(1<<8)|(1<<11)| \
+                                           (1<<13)|(1<<15)|(1<<24))
+        
+        asm("cpuid" : "=d" (flags), "=a" (tmp) : "1" (0x80000001) : "ebx", "ecx"); 
+        flags &= REQUIRED_MASK1;
+        flags ^= REQUIRED_MASK1; 
+        if (flags & (1<<0))
+                error("CPU misses x87"); 
+        if (flags & (1<<3)) 
+                error("CPU doesn't support page size extension (PSE)");
+        if (flags & (1<<4))
+                error("CPU misses an time stamp counter"); 
+        if (flags & (1<<5))
+                error("CPU misses AMD style MSRs"); 
+        if (flags & (1<<6))
+                error("CPU misses physical address extension (PAE)"); 
+        if (flags & (1<<8))
+                error("CPU misses cmpxchg8"); 
+        if (flags & (1<<11))
+                error("CPU doesn't support SYSCALL/SYSRET");
+        if (flags & (1<<13))
+                error("CPU doesn't support PGE"); 
+        if (flags & (1<<15))
+                error("CPU doesn't support CMOV"); 
+        if (flags & (1<<24))
+                error("CPU doesn't support FXSAVE/FXRSTOR"); 
+
+#define REQUIRED_MASK2 ((1<<25)|(1<<26))        
+        asm("cpuid" : "=d" (flags), "=a" (tmp) : "1" (1) : "ebx", "ecx"); 
+        flags &= REQUIRED_MASK2; 
+        flags ^= REQUIRED_MASK2; 
+        if (flags & (1<<25))
+                error("CPU doesn't support SSE1");
+        if (flags & (1<<26))
+                error("CPU doesn't support SSE2");
 }
 
 int decompress_kernel(struct moveparams *mv, void *rmode)
index 57a53ec3cc0f905faea3f401e54afa15f9cea365..864d6aa2ba60ea83c69e752fa32c362639e68f19 100644 (file)
@@ -3,11 +3,10 @@
 #
 CONFIG_X86_64=y
 CONFIG_X86=y
-# CONFIG_ISA is not set
-# CONFIG_SBUS is not set
+CONFIG_MMU=y
+CONFIG_SWAP=y
 CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_X86_CMPXCHG=y
 CONFIG_EARLY_PRINTK=y
 CONFIG_GENERIC_ISA_DMA=y
@@ -29,7 +28,9 @@ CONFIG_SYSCTL=y
 # Loadable module support
 #
 CONFIG_MODULES=y
-# CONFIG_MODVERSIONS is not set
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_OBSOLETE_MODPARM=y
 # CONFIG_KMOD is not set
 
 #
@@ -43,12 +44,10 @@ CONFIG_X86_TSC=y
 CONFIG_X86_GOOD_APIC=y
 CONFIG_X86_MSR=y
 CONFIG_X86_CPUID=y
-# CONFIG_MATH_EMULATION is not set
-# CONFIG_MCA is not set
-# CONFIG_EISA is not set
 CONFIG_X86_IO_APIC=y
 CONFIG_X86_LOCAL_APIC=y
 CONFIG_MTRR=y
+CONFIG_HUGETLB_PAGE=y
 CONFIG_SMP=y
 CONFIG_HAVE_DEC_LOCK=y
 CONFIG_NR_CPUS=8
@@ -66,7 +65,6 @@ CONFIG_X86_MCE=y
 CONFIG_ACPI=y
 # CONFIG_ACPI_HT_ONLY is not set
 CONFIG_ACPI_BOOT=y
-# CONFIG_ACPI_SLEEP is not set
 CONFIG_ACPI_AC=y
 CONFIG_ACPI_BATTERY=y
 CONFIG_ACPI_BUTTON=y
@@ -75,7 +73,6 @@ CONFIG_ACPI_PROCESSOR=y
 CONFIG_ACPI_THERMAL=y
 CONFIG_ACPI_TOSHIBA=y
 CONFIG_ACPI_DEBUG=y
-CONFIG_ACPI_BOOT=y
 CONFIG_ACPI_BUS=y
 CONFIG_ACPI_INTERPRETER=y
 CONFIG_ACPI_EC=y
@@ -90,7 +87,6 @@ CONFIG_PCI=y
 CONFIG_PCI_DIRECT=y
 # CONFIG_PCI_NAMES is not set
 # CONFIG_HOTPLUG is not set
-# CONFIG_PCMCIA is not set
 
 #
 # Executable file formats / Emulations
@@ -99,6 +95,7 @@ CONFIG_KCORE_ELF=y
 CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 CONFIG_IA32_EMULATION=y
+CONFIG_COMPAT=y
 
 #
 # Memory Technology Devices (MTD)
@@ -114,11 +111,8 @@ CONFIG_IA32_EMULATION=y
 # Block devices
 #
 CONFIG_BLK_DEV_FD=y
-# CONFIG_BLK_DEV_XD is not set
-# CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
-# CONFIG_CISS_SCSI_TAPE is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
 CONFIG_BLK_DEV_LOOP=y
@@ -146,51 +140,42 @@ CONFIG_BLK_DEV_IDE=y
 CONFIG_BLK_DEV_IDEDISK=y
 CONFIG_IDEDISK_MULTI_MODE=y
 # CONFIG_IDEDISK_STROKE is not set
-# CONFIG_BLK_DEV_IDECS is not set
 CONFIG_BLK_DEV_IDECD=y
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
-# CONFIG_BLK_DEV_IDESCSI is not set
 # CONFIG_IDE_TASK_IOCTL is not set
 
 #
 # IDE chipset support/bugfixes
 #
 # CONFIG_BLK_DEV_CMD640 is not set
-# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
-# CONFIG_BLK_DEV_ISAPNP is not set
 CONFIG_BLK_DEV_IDEPCI=y
 # CONFIG_BLK_DEV_GENERIC is not set
 # CONFIG_IDEPCI_SHARE_IRQ is not set
 CONFIG_BLK_DEV_IDEDMA_PCI=y
 # CONFIG_BLK_DEV_IDE_TCQ is not set
-# CONFIG_BLK_DEV_IDE_TCQ_DEFAULT is not set
 # CONFIG_BLK_DEV_OFFBOARD is not set
 # CONFIG_BLK_DEV_IDEDMA_FORCED is not set
 CONFIG_IDEDMA_PCI_AUTO=y
 # CONFIG_IDEDMA_ONLYDISK is not set
 CONFIG_BLK_DEV_IDEDMA=y
 # CONFIG_IDEDMA_PCI_WIP is not set
-# CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set
 CONFIG_BLK_DEV_ADMA=y
 # CONFIG_BLK_DEV_AEC62XX is not set
 # CONFIG_BLK_DEV_ALI15X3 is not set
-# CONFIG_WDC_ALI15X3 is not set
 CONFIG_BLK_DEV_AMD74XX=y
 # CONFIG_AMD74XX_OVERRIDE is not set
 # CONFIG_BLK_DEV_CMD64X is not set
 # CONFIG_BLK_DEV_CY82C693 is not set
-# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_CS5520 is not set
 # CONFIG_BLK_DEV_HPT34X is not set
-# CONFIG_HPT34X_AUTODMA is not set
 # CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_SC1200 is not set
 # CONFIG_BLK_DEV_PIIX is not set
 # CONFIG_BLK_DEV_NFORCE is not set
 # CONFIG_BLK_DEV_NS87415 is not set
 # CONFIG_BLK_DEV_OPTI621 is not set
 # CONFIG_BLK_DEV_PDC202XX_OLD is not set
-# CONFIG_PDC202XX_BURST is not set
 # CONFIG_BLK_DEV_PDC202XX_NEW is not set
-# CONFIG_PDC202XX_FORCE is not set
 # CONFIG_BLK_DEV_RZ1000 is not set
 # CONFIG_BLK_DEV_SVWKS is not set
 # CONFIG_BLK_DEV_SIIMAGE is not set
@@ -198,10 +183,8 @@ CONFIG_BLK_DEV_AMD74XX=y
 # CONFIG_BLK_DEV_SLC90E66 is not set
 # CONFIG_BLK_DEV_TRM290 is not set
 # CONFIG_BLK_DEV_VIA82CXXX is not set
-# CONFIG_IDE_CHIPSETS is not set
 CONFIG_IDEDMA_AUTO=y
 # CONFIG_IDEDMA_IVB is not set
-# CONFIG_DMA_NONPCI is not set
 CONFIG_BLK_DEV_IDE_MODES=y
 
 #
@@ -213,29 +196,15 @@ CONFIG_BLK_DEV_IDE_MODES=y
 # Multi-device support (RAID and LVM)
 #
 # CONFIG_MD is not set
-# CONFIG_BLK_DEV_MD is not set
-# CONFIG_MD_LINEAR is not set
-# CONFIG_MD_RAID0 is not set
-# CONFIG_MD_RAID1 is not set
-# CONFIG_MD_RAID5 is not set
-# CONFIG_MD_MULTIPATH is not set
-# CONFIG_BLK_DEV_LVM is not set
 
 #
 # Telephony Support
 #
 # CONFIG_PHONE is not set
-# CONFIG_PHONE_IXJ is not set
-# CONFIG_PHONE_IXJ_PCMCIA is not set
 
 #
 # Fusion MPT device support
 #
-# CONFIG_FUSION is not set
-# CONFIG_FUSION_BOOT is not set
-# CONFIG_FUSION_ISENSE is not set
-# CONFIG_FUSION_CTL is not set
-# CONFIG_FUSION_LAN is not set
 
 #
 # IEEE 1394 (FireWire) support (EXPERIMENTAL)
@@ -251,6 +220,7 @@ CONFIG_NETLINK_DEV=y
 # CONFIG_NETFILTER is not set
 CONFIG_FILTER=y
 CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
 # CONFIG_IP_ADVANCED_ROUTER is not set
@@ -261,6 +231,9 @@ CONFIG_IP_MULTICAST=y
 # 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_XFRM_USER is not set
 # CONFIG_IPV6 is not set
 
 #
@@ -271,9 +244,6 @@ CONFIG_IPV6_SCTP__=y
 # CONFIG_ATM is not set
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_LLC is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_DEV_APPLETALK is not set
 # CONFIG_DECNET is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_X25 is not set
@@ -289,6 +259,11 @@ CONFIG_IPV6_SCTP__=y
 #
 # CONFIG_NET_SCHED is not set
 
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
 #
 # Network device support
 #
@@ -308,20 +283,9 @@ CONFIG_NETDEVICES=y
 # Ethernet (10 or 100Mbit)
 #
 CONFIG_NET_ETHERNET=y
-# CONFIG_SUNLANCE is not set
 # CONFIG_HAPPYMEAL is not set
-# CONFIG_SUNBMAC is not set
-# CONFIG_SUNQE is not set
 # CONFIG_SUNGEM is not set
-CONFIG_NET_VENDOR_3COM=y
-# CONFIG_EL1 is not set
-# CONFIG_EL2 is not set
-# CONFIG_ELPLUS is not set
-# CONFIG_EL16 is not set
-# CONFIG_ELMC is not set
-# CONFIG_ELMC_II is not set
-CONFIG_VORTEX=y
-# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_NET_VENDOR_SMC is not set
 # CONFIG_NET_VENDOR_RACAL is not set
 
@@ -330,8 +294,27 @@ CONFIG_VORTEX=y
 #
 # CONFIG_NET_TULIP is not set
 # CONFIG_HP100 is not set
-# CONFIG_NET_ISA is not set
-# CONFIG_NET_PCI is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_B44 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_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_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
 # CONFIG_NET_POCKET is not set
 
 #
@@ -339,17 +322,16 @@ CONFIG_VORTEX=y
 #
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
-# CONFIG_E1000 is not set
+CONFIG_E1000=m
 # CONFIG_E1000_NAPI is not set
-# CONFIG_MYRI_SBUS is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
 # CONFIG_SK98LIN is not set
 CONFIG_TIGON3=y
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
-# CONFIG_PLIP is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
 
@@ -359,9 +341,8 @@ CONFIG_TIGON3=y
 # CONFIG_NET_RADIO is not set
 
 #
-# Token Ring devices
+# Token Ring devices (depends on LLC=y)
 #
-# CONFIG_TR is not set
 # CONFIG_NET_FC is not set
 # CONFIG_RCPCI is not set
 # CONFIG_SHAPER is not set
@@ -408,17 +389,10 @@ CONFIG_INPUT_EVDEV=y
 #
 # CONFIG_GAMEPORT is not set
 CONFIG_SOUND_GAMEPORT=y
-# CONFIG_GAMEPORT_NS558 is not set
-# CONFIG_GAMEPORT_L4 is not set
-# CONFIG_GAMEPORT_EMU10K1 is not set
-# CONFIG_GAMEPORT_VORTEX is not set
-# CONFIG_GAMEPORT_FM801 is not set
-# CONFIG_GAMEPORT_CS461x is not set
 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
 
 #
 # Input Device Drivers
@@ -431,21 +405,7 @@ CONFIG_KEYBOARD_ATKBD=y
 CONFIG_INPUT_MOUSE=y
 CONFIG_MOUSE_PS2=y
 # CONFIG_MOUSE_SERIAL is not set
-# CONFIG_MOUSE_INPORT is not set
-# CONFIG_MOUSE_LOGIBM is not set
-# CONFIG_MOUSE_PC110PAD is not set
 CONFIG_INPUT_JOYSTICK=y
-# CONFIG_JOYSTICK_ANALOG is not set
-# CONFIG_JOYSTICK_A3D is not set
-# CONFIG_JOYSTICK_ADI is not set
-# CONFIG_JOYSTICK_COBRA is not set
-# CONFIG_JOYSTICK_GF2K is not set
-# CONFIG_JOYSTICK_GRIP is not set
-# CONFIG_JOYSTICK_GRIP_MP is not set
-# CONFIG_JOYSTICK_GUILLEMOT is not set
-# CONFIG_JOYSTICK_INTERACT is not set
-# CONFIG_JOYSTICK_SIDEWINDER is not set
-# CONFIG_JOYSTICK_TMDC is not set
 # CONFIG_JOYSTICK_IFORCE is not set
 # CONFIG_JOYSTICK_WARRIOR is not set
 # CONFIG_JOYSTICK_MAGELLAN is not set
@@ -453,15 +413,9 @@ CONFIG_INPUT_JOYSTICK=y
 # CONFIG_JOYSTICK_SPACEBALL is not set
 # CONFIG_JOYSTICK_STINGER is not set
 # CONFIG_JOYSTICK_TWIDDLER is not set
-# CONFIG_JOYSTICK_DB9 is not set
-# CONFIG_JOYSTICK_GAMECON is not set
-# CONFIG_JOYSTICK_TURBOGRAFX is not set
 # CONFIG_INPUT_JOYDUMP is not set
 # CONFIG_INPUT_TOUCHSCREEN is not set
-# CONFIG_TOUCHSCREEN_GUNZE is not set
 # CONFIG_INPUT_MISC is not set
-# CONFIG_INPUT_PCSPKR is not set
-# CONFIG_INPUT_UINPUT is not set
 
 #
 # Character devices
@@ -476,13 +430,7 @@ CONFIG_HW_CONSOLE=y
 #
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
-# CONFIG_SERIAL_8250_CS is not set
 # CONFIG_SERIAL_8250_EXTENDED is not set
-# CONFIG_SERIAL_8250_MANY_PORTS is not set
-# CONFIG_SERIAL_8250_SHARE_IRQ is not set
-# CONFIG_SERIAL_8250_DETECT_IRQ is not set
-# CONFIG_SERIAL_8250_MULTIPORT is not set
-# CONFIG_SERIAL_8250_RSA is not set
 
 #
 # Non-8250 serial port support
@@ -520,17 +468,10 @@ CONFIG_RTC=y
 # Ftape, the floppy tape device driver
 #
 # CONFIG_FTAPE is not set
-CONFIG_AGP=y
-# CONFIG_AGP_INTEL is not set
-# CONFIG_AGP_I810 is not set
-# CONFIG_AGP_VIA is not set
-# CONFIG_AGP_AMD is not set
-# CONFIG_AGP_SIS is not set
-# CONFIG_AGP_ALI is not set
-# CONFIG_AGP_SWORKS is not set
+# CONFIG_AGP is not set
+# CONFIG_AGP_GART is not set
 # CONFIG_DRM is not set
 # CONFIG_MWAVE is not set
-# CONFIG_SCx200_GPIO is not set
 CONFIG_RAW_DRIVER=y
 
 #
@@ -546,60 +487,48 @@ CONFIG_RAW_DRIVER=y
 # File systems
 #
 # CONFIG_QUOTA is not set
-# CONFIG_QFMT_V1 is not set
-# CONFIG_QFMT_V2 is not set
 CONFIG_AUTOFS_FS=y
 # CONFIG_AUTOFS4_FS is not set
 CONFIG_REISERFS_FS=y
 # CONFIG_REISERFS_CHECK is not set
 # CONFIG_REISERFS_PROC_INFO is not set
 # CONFIG_ADFS_FS is not set
-# CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 CONFIG_EXT3_FS=y
+# CONFIG_EXT3_FS_XATTR is not set
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
 # CONFIG_FAT_FS is not set
-# CONFIG_MSDOS_FS is not set
-# CONFIG_UMSDOS_FS is not set
-# CONFIG_VFAT_FS is not set
 # CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
-# CONFIG_JFFS2_FS is not set
 # CONFIG_CRAMFS is not set
 CONFIG_TMPFS=y
 CONFIG_RAMFS=y
+CONFIG_HUGETLBFS=y
 CONFIG_ISO9660_FS=y
 # CONFIG_JOLIET is not set
 # CONFIG_ZISOFS is not set
 # CONFIG_JFS_FS is not set
-# CONFIG_JFS_DEBUG is not set
-# CONFIG_JFS_STATISTICS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
-# CONFIG_NTFS_DEBUG is not set
-# CONFIG_NTFS_RW is not set
 # CONFIG_HPFS_FS is not set
 CONFIG_PROC_FS=y
 # CONFIG_DEVFS_FS is not set
-# CONFIG_DEVFS_MOUNT is not set
-# CONFIG_DEVFS_DEBUG is not set
 CONFIG_DEVPTS_FS=y
 # CONFIG_QNX4FS_FS is not set
-# CONFIG_QNX4FS_RW is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UDF_FS is not set
-# CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
-# CONFIG_UFS_FS_WRITE is not set
-# CONFIG_XFS_FS is not set
+CONFIG_XFS_FS=m
 # CONFIG_XFS_RT is not set
 # CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_POSIX_ACL is not set
 
 #
 # Network File Systems
@@ -609,7 +538,6 @@ CONFIG_EXT2_FS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V4 is not set
-# CONFIG_ROOT_NFS is not set
 CONFIG_NFSD=y
 CONFIG_NFSD_V3=y
 # CONFIG_NFSD_V4 is not set
@@ -621,36 +549,26 @@ CONFIG_EXPORTFS=y
 # CONFIG_CIFS is not set
 # CONFIG_SMB_FS is not set
 # CONFIG_NCP_FS is not set
-# CONFIG_NCPFS_PACKET_SIGNING is not set
-# CONFIG_NCPFS_IOCTL_LOCKING is not set
-# CONFIG_NCPFS_STRONG is not set
-# CONFIG_NCPFS_NFS_NS is not set
-# CONFIG_NCPFS_OS2_NS is not set
-# CONFIG_NCPFS_SMALLDOS is not set
-# CONFIG_NCPFS_NLS is not set
-# CONFIG_NCPFS_EXTRAS is not set
 # CONFIG_AFS_FS is not set
-# CONFIG_ZISOFS_FS is not set
 
 #
 # Partition Types
 #
 # CONFIG_PARTITION_ADVANCED is not set
 CONFIG_MSDOS_PARTITION=y
-# CONFIG_SMB_NLS is not set
-# CONFIG_NLS is not set
 
 #
-# Console drivers
+# Graphics support
 #
-CONFIG_VGA_CONSOLE=y
+# CONFIG_FB is not set
 # CONFIG_VIDEO_SELECT is not set
-# CONFIG_MDA_CONSOLE is not set
 
 #
-# Frame-buffer support
+# Console display driver support
 #
-# CONFIG_FB is not set
+CONFIG_VGA_CONSOLE=y
+# CONFIG_MDA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
 
 #
 # Sound
@@ -676,17 +594,20 @@ CONFIG_MAGIC_SYSRQ=y
 # CONFIG_DEBUG_SPINLOCK is not set
 CONFIG_CHECKING=y
 # CONFIG_INIT_DEBUG is not set
-# CONFIG_DEBUG_SPINLOCK is not set
-# CONFIG_KALLSYMS is not set
+CONFIG_KALLSYMS=y
+# CONFIG_FRAME_POINTER is not set
 
 #
 # Security options
 #
-CONFIG_SECURITY_CAPABILITIES=y
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
 
 #
 # Library routines
 #
 # CONFIG_CRC32 is not set
-# CONFIG_ZLIB_INFLATE is not set
-# CONFIG_ZLIB_DEFLATE is not set
index 0528b55b42d51029a2d5165bcc6e437e7ad6317b..ab476cbb12c92ad680af93ea8a62f6694fa7e472 100644 (file)
@@ -70,6 +70,10 @@ static inline unsigned long twd_fxsr_to_i387(struct i387_fxsave_struct *fxsave)
        return ret;
 }
 
+struct s10 { 
+       u64 a;
+       u16 b;
+} __attribute__((packed)); 
 
 static inline int convert_fxsr_from_user(struct i387_fxsave_struct *fxsave,
                                         struct _fpstate_ia32 *buf)
@@ -94,7 +98,9 @@ static inline int convert_fxsr_from_user(struct i387_fxsave_struct *fxsave,
        to = (struct _fpxreg *)&fxsave->st_space[0];
        from = &buf->_st[0];
        for (i = 0 ; i < 8 ; i++, to++, from++) {
-               if (__copy_from_user(to, from, sizeof(*from)))
+               struct s10 *top = (void *)to, *fromp = (void *)from; 
+               if (__put_user(fromp->a, &top->a) ||
+                   __put_user(fromp->b, &top->b))
                        return -1;
        }
        return 0;
@@ -130,7 +136,9 @@ static inline int convert_fxsr_to_user(struct _fpstate_ia32 *buf,
        to = &buf->_st[0];
        from = (struct _fpxreg *) &fxsave->st_space[0];
        for ( i = 0 ; i < 8 ; i++, to++, from++ ) {
-               if (__copy_to_user(to, from, sizeof(*to)))
+               struct s10 *top = (void *)top, *fromp = (void *)from;
+               if (__get_user(fromp->a, &top->a) || 
+                   __get_user(fromp->b, &top->b))
                        return -1;
        }
        return 0;
index 557d4f5e757535f9c43937251bdce003bcec0806..3fd8ae63faaf4d9ea6db73fba797c6bbfb4b5e84 100644 (file)
@@ -6,12 +6,13 @@
  * of ugly preprocessor tricks. Talk about very very poor man's inheritance.
  */ 
 #include <linux/types.h>
+#include <linux/compat.h>
 #include <linux/config.h> 
 #include <linux/stddef.h>
-#include <linux/module.h>
 #include <linux/rwsem.h>
 #include <linux/sched.h>
 #include <linux/string.h>
+#include <linux/binfmts.h>
 #include <asm/segment.h> 
 #include <asm/ptrace.h>
 #include <asm/processor.h>
 #include <asm/sigcontext32.h>
 #include <asm/fpu32.h>
 #include <asm/i387.h>
+#include <asm/uaccess.h>
+#include <asm/ia32.h>
 
 struct file;
 struct elf_phdr; 
 
 #define IA32_EMULATOR 1
 
-#define IA32_PAGE_OFFSET 0xffff0000
-#define IA32_STACK_TOP IA32_PAGE_OFFSET
 #define ELF_ET_DYN_BASE                (IA32_PAGE_OFFSET/3 + 0x1000000)
 
 #undef ELF_ARCH
@@ -53,11 +54,6 @@ struct elf_siginfo
        int     si_errno;                       /* errno */
 };
 
-struct timeval32
-{
-    int tv_sec, tv_usec;
-};
-
 #define jiffies_to_timeval(a,b) do { (b)->tv_usec = 0; (b)->tv_sec = (a)/HZ; }while(0)
 
 struct elf_prstatus
@@ -70,10 +66,10 @@ struct elf_prstatus
        pid_t   pr_ppid;
        pid_t   pr_pgrp;
        pid_t   pr_sid;
-       struct timeval32 pr_utime;      /* User time */
-       struct timeval32 pr_stime;      /* System time */
-       struct timeval32 pr_cutime;     /* Cumulative user time */
-       struct timeval32 pr_cstime;     /* Cumulative system time */
+       struct compat_timeval pr_utime; /* User time */
+       struct compat_timeval pr_stime; /* System time */
+       struct compat_timeval pr_cutime;        /* Cumulative user time */
+       struct compat_timeval pr_cstime;        /* Cumulative system time */
        elf_gregset_t pr_reg;   /* GP registers */
        int pr_fpvalid;         /* True if math co-processor being used.  */
 };
@@ -123,15 +119,68 @@ struct elf_prpsinfo
 
 #define user user32
 
-#define dump_fpu dump_fpu_ia32
-
 #define __ASM_X86_64_ELF_H 1
-#include <asm/ia32.h>
+//#include <asm/ia32.h>
 #include <linux/elf.h>
 
 typedef struct user_i387_ia32_struct elf_fpregset_t;
 typedef struct user32_fxsr_struct elf_fpxregset_t;
 
+
+static inline void elf_core_copy_regs(elf_gregset_t *elfregs, struct pt_regs *regs)
+{
+       ELF_CORE_COPY_REGS((*elfregs), regs)
+}
+
+static inline int elf_core_copy_task_regs(struct task_struct *t, elf_gregset_t* elfregs)
+{      
+       struct pt_regs *pp = (struct pt_regs *)(t->thread.rsp0);
+       ELF_CORE_COPY_REGS((*elfregs), pp);
+       /* fix wrong segments */ 
+       (*elfregs)[7] = t->thread.ds; 
+       (*elfregs)[9] = t->thread.fsindex; 
+       (*elfregs)[10] = t->thread.gsindex; 
+       (*elfregs)[8] = t->thread.es;   
+       return 1; 
+}
+
+static inline int 
+elf_core_copy_task_fpregs(struct task_struct *tsk, elf_fpregset_t *fpu)
+{
+       struct _fpstate_ia32 *fpstate = (void*)fpu; 
+       struct pt_regs *regs = (struct pt_regs *)(tsk->thread.rsp0); 
+       mm_segment_t oldfs = get_fs();
+       int ret;
+
+       if (!tsk->used_math) 
+               return 0;
+       --regs;
+       if (tsk == current)
+               unlazy_fpu(tsk);
+       set_fs(KERNEL_DS); 
+       ret = save_i387_ia32(tsk, fpstate, regs, 1);
+       /* Correct for i386 bug. It puts the fop into the upper 16bits of 
+          the tag word (like FXSAVE), not into the fcs*/ 
+       fpstate->cssel |= fpstate->tag & 0xffff0000; 
+       set_fs(oldfs); 
+       return ret; 
+}
+
+#define ELF_CORE_COPY_XFPREGS 1
+static inline int 
+elf_core_copy_task_xfpregs(struct task_struct *t, elf_fpxregset_t *xfpu)
+{
+       struct pt_regs *regs = ((struct pt_regs *)(t->thread.rsp0))-1; 
+       if (!t->used_math) 
+               return 0;
+       if (t == current)
+               unlazy_fpu(t); 
+       memcpy(xfpu, &t->thread.i387.fxsave, sizeof(elf_fpxregset_t));
+       xfpu->fcs = regs->cs; 
+       xfpu->fos = t->thread.ds; /* right? */ 
+       return 1;
+}
+
 #undef elf_check_arch
 #define elf_check_arch(x) \
        ((x)->e_machine == EM_386)
@@ -168,9 +217,9 @@ int ia32_setup_arg_pages(struct linux_binprm *bprm);
 
 #undef start_thread
 #define start_thread(regs,new_rip,new_rsp) do { \
-       __asm__("movl %0,%%fs": :"r" (0)); \
-       __asm__("movl %0,%%es; movl %0,%%ds": :"r" (__USER32_DS)); \
-       wrmsrl(MSR_KERNEL_GS_BASE, 0); \
+       asm volatile("movl %0,%%fs" :: "r" (0)); \
+       asm volatile("movl %0,%%es; movl %0,%%ds": :"r" (__USER32_DS)); \
+       load_gs_index(0); \
        (regs)->rip = (new_rip); \
        (regs)->rsp = (new_rsp); \
        (regs)->eflags = 0x200; \
@@ -182,6 +231,8 @@ int ia32_setup_arg_pages(struct linux_binprm *bprm);
 
 #define elf_map elf32_map
 
+#include <linux/module.h>
+
 MODULE_DESCRIPTION("Binary format loader for compatibility with IA32 ELF binaries."); 
 MODULE_AUTHOR("Eric Youngdale, Andi Kleen");
 
@@ -245,7 +296,7 @@ int setup_arg_pages(struct linux_binprm *bprm)
                mpnt->vm_mm = mm;
                mpnt->vm_start = PAGE_MASK & (unsigned long) bprm->p;
                mpnt->vm_end = IA32_STACK_TOP;
-               mpnt->vm_page_prot = PAGE_COPY;
+               mpnt->vm_page_prot = PAGE_COPY_EXEC;
                mpnt->vm_flags = VM_STACK_FLAGS;
                mpnt->vm_ops = NULL;
                mpnt->vm_pgoff = 0;
@@ -287,23 +338,3 @@ elf32_map (struct file *filep, unsigned long addr, struct elf_phdr *eppnt, int p
        return(map_addr);
 }
 
-int dump_fpu_ia32(struct pt_regs *regs, elf_fpregset_t *fp)
-{
-       struct _fpstate_ia32 *fpu = (void*)fp; 
-       struct task_struct *tsk = current;
-       mm_segment_t oldfs = get_fs();
-       int ret;
-
-       if (!tsk->used_math) 
-               return 0;
-       if (!(test_thread_flag(TIF_IA32)))
-               BUG(); 
-       unlazy_fpu(tsk);
-       set_fs(KERNEL_DS); 
-       ret = save_i387_ia32(current, fpu, regs, 1);
-       /* Correct for i386 bug. It puts the fop into the upper 16bits of 
-          the tag word (like FXSAVE), not into the fcs*/ 
-       fpu->cssel |= fpu->tag & 0xffff0000; 
-       set_fs(oldfs); 
-       return ret; 
-}
index 8a84ef80c15b5bc3397440fece25c2b87cff1103..0e1e7a2d2f7e3e20cf384d88ff316ec7a4135341 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <linux/config.h>
 #include <linux/types.h>
+#include <linux/compat.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/smp.h>
@@ -405,14 +406,9 @@ out:
        return err;
 }
 
-struct timeval32 {
-       int tv_sec;
-       int tv_usec;
-};
-
 static int do_siocgstamp(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
-       struct timeval32 *up = (struct timeval32 *)arg;
+       struct compat_timeval *up = (struct compat_timeval *)arg;
        struct timeval ktv;
        mm_segment_t old_fs = get_fs();
        int err;
@@ -1611,8 +1607,8 @@ struct ppp_option_data32 {
 #define PPPIOCSCOMPRESS32      _IOW('t', 77, struct ppp_option_data32)
 
 struct ppp_idle32 {
-       __kernel_time_t32 xmit_idle;
-       __kernel_time_t32 recv_idle;
+       compat_time_t xmit_idle;
+       compat_time_t recv_idle;
 };
 #define PPPIOCGIDLE32          _IOR('t', 63, struct ppp_idle32)
 
@@ -1913,9 +1909,9 @@ out:      if (data)
 
 struct loop_info32 {
        int                     lo_number;      /* ioctl r/o */
-       __kernel_dev_t32        lo_device;      /* ioctl r/o */
+       compat_dev_t    lo_device;      /* ioctl r/o */
        unsigned int            lo_inode;       /* ioctl r/o */
-       __kernel_dev_t32        lo_rdevice;     /* ioctl r/o */
+       compat_dev_t    lo_rdevice;     /* ioctl r/o */
        int                     lo_offset;
        int                     lo_encrypt_type;
        int                     lo_encrypt_key_size;    /* ioctl w/o */
@@ -2120,7 +2116,7 @@ static int do_smb_getmountuid(unsigned int fd, unsigned int cmd, unsigned long a
        set_fs(old_fs);
 
        if (err >= 0)
-               err = put_user(kuid, (__kernel_uid_t32 *)arg);
+               err = put_user(kuid, (compat_pid_t *)arg);
 
        return err;
 }
@@ -2779,543 +2775,6 @@ static int do_lvm_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
 }
 #endif
 
-#if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE)
-/* This really belongs in include/linux/drm.h -DaveM */
-#include "../../../drivers/char/drm/drm.h"
-
-typedef struct drm32_version {
-       int    version_major;     /* Major version                          */
-       int    version_minor;     /* Minor version                          */
-       int    version_patchlevel;/* Patch level                            */
-       int    name_len;          /* Length of name buffer                  */
-       u32    name;              /* Name of driver                         */
-       int    date_len;          /* Length of date buffer                  */
-       u32    date;              /* User-space buffer to hold date         */
-       int    desc_len;          /* Length of desc buffer                  */
-       u32    desc;              /* User-space buffer to hold desc         */
-} drm32_version_t;
-#define DRM32_IOCTL_VERSION    DRM_IOWR(0x00, drm32_version_t)
-
-static int drm32_version(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
-       drm32_version_t *uversion = (drm32_version_t *)arg;
-       char *name_ptr, *date_ptr, *desc_ptr;
-       u32 tmp1, tmp2, tmp3;
-       drm_version_t kversion;
-       mm_segment_t old_fs;
-       int ret;
-
-       memset(&kversion, 0, sizeof(kversion));
-       if (get_user(kversion.name_len, &uversion->name_len) ||
-           get_user(kversion.date_len, &uversion->date_len) ||
-           get_user(kversion.desc_len, &uversion->desc_len) ||
-           get_user(tmp1, &uversion->name) ||
-           get_user(tmp2, &uversion->date) ||
-           get_user(tmp3, &uversion->desc))
-               return -EFAULT;
-
-       name_ptr = (char *) A(tmp1);
-       date_ptr = (char *) A(tmp2);
-       desc_ptr = (char *) A(tmp3);
-
-       ret = -ENOMEM;
-       if (kversion.name_len && name_ptr) {
-               kversion.name = kmalloc(kversion.name_len, GFP_KERNEL);
-               if (!kversion.name)
-                       goto out;
-       }
-       if (kversion.date_len && date_ptr) {
-               kversion.date = kmalloc(kversion.date_len, GFP_KERNEL);
-               if (!kversion.date)
-                       goto out;
-       }
-       if (kversion.desc_len && desc_ptr) {
-               kversion.desc = kmalloc(kversion.desc_len, GFP_KERNEL);
-               if (!kversion.desc)
-                       goto out;
-       }
-
-        old_fs = get_fs();
-       set_fs(KERNEL_DS);
-        ret = sys_ioctl (fd, DRM_IOCTL_VERSION, (unsigned long)&kversion);
-        set_fs(old_fs);
-
-       if (!ret) {
-               if ((kversion.name &&
-                    copy_to_user(name_ptr, kversion.name, kversion.name_len)) ||
-                   (kversion.date &&
-                    copy_to_user(date_ptr, kversion.date, kversion.date_len)) ||
-                   (kversion.desc &&
-                    copy_to_user(desc_ptr, kversion.desc, kversion.desc_len)))
-                       ret = -EFAULT;
-               if (put_user(kversion.version_major, &uversion->version_major) ||
-                   put_user(kversion.version_minor, &uversion->version_minor) ||
-                   put_user(kversion.version_patchlevel, &uversion->version_patchlevel) ||
-                   put_user(kversion.name_len, &uversion->name_len) ||
-                   put_user(kversion.date_len, &uversion->date_len) ||
-                   put_user(kversion.desc_len, &uversion->desc_len))
-                       ret = -EFAULT;
-       }
-
-out:
-       if (kversion.name)
-               kfree(kversion.name);
-       if (kversion.date)
-               kfree(kversion.date);
-       if (kversion.desc)
-               kfree(kversion.desc);
-       return ret;
-}
-
-typedef struct drm32_unique {
-       int     unique_len;       /* Length of unique                       */
-       u32     unique;           /* Unique name for driver instantiation   */
-} drm32_unique_t;
-#define DRM32_IOCTL_GET_UNIQUE DRM_IOWR(0x01, drm32_unique_t)
-#define DRM32_IOCTL_SET_UNIQUE DRM_IOW( 0x10, drm32_unique_t)
-
-static int drm32_getsetunique(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
-       drm32_unique_t *uarg = (drm32_unique_t *)arg;
-       drm_unique_t karg;
-       mm_segment_t old_fs;
-       char *uptr;
-       u32 tmp;
-       int ret;
-
-       if (get_user(karg.unique_len, &uarg->unique_len))
-               return -EFAULT;
-       karg.unique = NULL;
-
-       if (get_user(tmp, &uarg->unique))
-               return -EFAULT;
-
-       uptr = (char *) A(tmp);
-
-       if (uptr) {
-               karg.unique = kmalloc(karg.unique_len, GFP_KERNEL);
-               if (!karg.unique)
-                       return -ENOMEM;
-               if (cmd == DRM32_IOCTL_SET_UNIQUE &&
-                   copy_from_user(karg.unique, uptr, karg.unique_len)) {
-                       kfree(karg.unique);
-                       return -EFAULT;
-               }
-       }
-
-       old_fs = get_fs();
-       set_fs(KERNEL_DS);
-       if (cmd == DRM32_IOCTL_GET_UNIQUE)
-               ret = sys_ioctl (fd, DRM_IOCTL_GET_UNIQUE, (unsigned long)&karg);
-       else
-               ret = sys_ioctl (fd, DRM_IOCTL_SET_UNIQUE, (unsigned long)&karg);
-        set_fs(old_fs);
-
-       if (!ret) {
-               if (cmd == DRM32_IOCTL_GET_UNIQUE &&
-                   uptr != NULL &&
-                   copy_to_user(uptr, karg.unique, karg.unique_len))
-                       ret = -EFAULT;
-               if (put_user(karg.unique_len, &uarg->unique_len))
-                       ret = -EFAULT;
-       }
-
-       if (karg.unique != NULL)
-               kfree(karg.unique);
-
-       return ret;
-}
-
-typedef struct drm32_map {
-       u32             offset;  /* Requested physical address (0 for SAREA)*/
-       u32             size;    /* Requested physical size (bytes)         */
-       drm_map_type_t  type;    /* Type of memory to map                   */
-       drm_map_flags_t flags;   /* Flags                                   */
-       u32             handle;  /* User-space: "Handle" to pass to mmap    */
-                                /* Kernel-space: kernel-virtual address    */
-       int             mtrr;    /* MTRR slot used                          */
-                                /* Private data                            */
-} drm32_map_t;
-#define DRM32_IOCTL_ADD_MAP    DRM_IOWR(0x15, drm32_map_t)
-
-static int drm32_addmap(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
-       drm32_map_t *uarg = (drm32_map_t *) arg;
-       drm_map_t karg;
-       mm_segment_t old_fs;
-       u32 tmp;
-       int ret;
-
-       ret  = get_user(karg.offset, &uarg->offset);
-       ret |= get_user(karg.size, &uarg->size);
-       ret |= get_user(karg.type, &uarg->type);
-       ret |= get_user(karg.flags, &uarg->flags);
-       ret |= get_user(tmp, &uarg->handle);
-       ret |= get_user(karg.mtrr, &uarg->mtrr);
-       if (ret)
-               return -EFAULT;
-
-       karg.handle = (void *) A(tmp);
-
-       old_fs = get_fs();
-       set_fs(KERNEL_DS);
-       ret = sys_ioctl(fd, DRM_IOCTL_ADD_MAP, (unsigned long) &karg);
-       set_fs(old_fs);
-
-       if (!ret) {
-               ret  = put_user(karg.offset, &uarg->offset);
-               ret |= put_user(karg.size, &uarg->size);
-               ret |= put_user(karg.type, &uarg->type);
-               ret |= put_user(karg.flags, &uarg->flags);
-               tmp = (u32) (long)karg.handle;
-               ret |= put_user(tmp, &uarg->handle);
-               ret |= put_user(karg.mtrr, &uarg->mtrr);
-               if (ret)
-                       ret = -EFAULT;
-       }
-
-       return ret;
-}
-
-typedef struct drm32_buf_info {
-       int            count;   /* Entries in list                           */
-       u32            list;    /* (drm_buf_desc_t *) */ 
-} drm32_buf_info_t;
-#define DRM32_IOCTL_INFO_BUFS  DRM_IOWR(0x18, drm32_buf_info_t)
-
-static int drm32_info_bufs(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
-       drm32_buf_info_t *uarg = (drm32_buf_info_t *)arg;
-       drm_buf_desc_t *ulist;
-       drm_buf_info_t karg;
-       mm_segment_t old_fs;
-       int orig_count, ret;
-       u32 tmp;
-
-       if (get_user(karg.count, &uarg->count) ||
-           get_user(tmp, &uarg->list))
-               return -EFAULT;
-
-       ulist = (drm_buf_desc_t *) A(tmp);
-
-       orig_count = karg.count;
-
-       karg.list = kmalloc(karg.count * sizeof(drm_buf_desc_t), GFP_KERNEL);
-       if (!karg.list)
-               return -EFAULT;
-
-       old_fs = get_fs();
-       set_fs(KERNEL_DS);
-       ret = sys_ioctl(fd, DRM_IOCTL_INFO_BUFS, (unsigned long) &karg);
-       set_fs(old_fs);
-
-       if (!ret) {
-               if (karg.count <= orig_count &&
-                   (copy_to_user(ulist, karg.list,
-                                 karg.count * sizeof(drm_buf_desc_t))))
-                       ret = -EFAULT;
-               if (put_user(karg.count, &uarg->count))
-                       ret = -EFAULT;
-       }
-
-       kfree(karg.list);
-
-       return ret;
-}
-
-typedef struct drm32_buf_free {
-       int            count;
-       u32            list;    /* (int *) */
-} drm32_buf_free_t;
-#define DRM32_IOCTL_FREE_BUFS  DRM_IOW( 0x1a, drm32_buf_free_t)
-
-static int drm32_free_bufs(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
-       drm32_buf_free_t *uarg = (drm32_buf_free_t *)arg;
-       drm_buf_free_t karg;
-       mm_segment_t old_fs;
-       int *ulist;
-       int ret;
-       u32 tmp;
-
-       if (get_user(karg.count, &uarg->count) ||
-           get_user(tmp, &uarg->list))
-               return -EFAULT;
-
-       ulist = (int *) A(tmp);
-
-       karg.list = kmalloc(karg.count * sizeof(int), GFP_KERNEL);
-       if (!karg.list)
-               return -ENOMEM;
-
-       ret = -EFAULT;
-       if (copy_from_user(karg.list, ulist, (karg.count * sizeof(int))))
-               goto out;
-
-       old_fs = get_fs();
-       set_fs(KERNEL_DS);
-       ret = sys_ioctl(fd, DRM_IOCTL_FREE_BUFS, (unsigned long) &karg);
-       set_fs(old_fs);
-
-out:
-       kfree(karg.list);
-
-       return ret;
-}
-
-typedef struct drm32_buf_pub {
-       int               idx;         /* Index into master buflist          */
-       int               total;       /* Buffer size                        */
-       int               used;        /* Amount of buffer in use (for DMA)  */
-       u32               address;     /* Address of buffer (void *)         */
-} drm32_buf_pub_t;
-
-typedef struct drm32_buf_map {
-       int           count;    /* Length of buflist                        */
-       u32           virtual;  /* Mmaped area in user-virtual (void *)     */
-       u32           list;     /* Buffer information (drm_buf_pub_t *)     */
-} drm32_buf_map_t;
-#define DRM32_IOCTL_MAP_BUFS   DRM_IOWR(0x19, drm32_buf_map_t)
-
-static int drm32_map_bufs(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
-       drm32_buf_map_t *uarg = (drm32_buf_map_t *)arg;
-       drm32_buf_pub_t *ulist;
-       drm_buf_map_t karg;
-       mm_segment_t old_fs;
-       int orig_count, ret, i;
-       u32 tmp1, tmp2;
-
-       if (get_user(karg.count, &uarg->count) ||
-           get_user(tmp1, &uarg->virtual) ||
-           get_user(tmp2, &uarg->list))
-               return -EFAULT;
-
-       karg.virtual = (void *) A(tmp1);
-       ulist = (drm32_buf_pub_t *) A(tmp2);
-
-       orig_count = karg.count;
-
-       karg.list = kmalloc(karg.count * sizeof(drm_buf_pub_t), GFP_KERNEL);
-       if (!karg.list)
-               return -ENOMEM;
-
-       ret = -EFAULT;
-       for (i = 0; i < karg.count; i++) {
-               if (get_user(karg.list[i].idx, &ulist[i].idx) ||
-                   get_user(karg.list[i].total, &ulist[i].total) ||
-                   get_user(karg.list[i].used, &ulist[i].used) ||
-                   get_user(tmp1, &ulist[i].address))
-                       goto out;
-
-               karg.list[i].address = (void *) A(tmp1);
-       }
-
-       old_fs = get_fs();
-       set_fs(KERNEL_DS);
-       ret = sys_ioctl(fd, DRM_IOCTL_MAP_BUFS, (unsigned long) &karg);
-       set_fs(old_fs);
-
-       if (!ret) {
-               for (i = 0; i < orig_count; i++) {
-                       tmp1 = (u32) (long) karg.list[i].address;
-                       if (put_user(karg.list[i].idx, &ulist[i].idx) ||
-                           put_user(karg.list[i].total, &ulist[i].total) ||
-                           put_user(karg.list[i].used, &ulist[i].used) ||
-                           put_user(tmp1, &ulist[i].address)) {
-                               ret = -EFAULT;
-                               goto out;
-                       }
-               }
-               if (put_user(karg.count, &uarg->count))
-                       ret = -EFAULT;
-       }
-
-out:
-       kfree(karg.list);
-       return ret;
-}
-
-typedef struct drm32_dma {
-                               /* Indices here refer to the offset into
-                                  buflist in drm_buf_get_t.  */
-       int             context;          /* Context handle                 */
-       int             send_count;       /* Number of buffers to send      */
-       u32             send_indices;     /* List of handles to buffers (int *) */
-       u32             send_sizes;       /* Lengths of data to send (int *) */
-       drm_dma_flags_t flags;            /* Flags                          */
-       int             request_count;    /* Number of buffers requested    */
-       int             request_size;     /* Desired size for buffers       */
-       u32             request_indices;  /* Buffer information (int *)     */
-       u32             request_sizes;    /* (int *) */
-       int             granted_count;    /* Number of buffers granted      */
-} drm32_dma_t;
-#define DRM32_IOCTL_DMA             DRM_IOWR(0x29, drm32_dma_t)
-
-/* RED PEN     The DRM layer blindly dereferences the send/request
- *             indice/size arrays even though they are userland
- *             pointers.  -DaveM
- */
-static int drm32_dma(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
-       drm32_dma_t *uarg = (drm32_dma_t *) arg;
-       int *u_si, *u_ss, *u_ri, *u_rs;
-       drm_dma_t karg;
-       mm_segment_t old_fs;
-       int ret;
-       u32 tmp1, tmp2, tmp3, tmp4;
-
-       karg.send_indices = karg.send_sizes = NULL;
-       karg.request_indices = karg.request_sizes = NULL;
-
-       if (get_user(karg.context, &uarg->context) ||
-           get_user(karg.send_count, &uarg->send_count) ||
-           get_user(tmp1, &uarg->send_indices) ||
-           get_user(tmp2, &uarg->send_sizes) ||
-           get_user(karg.flags, &uarg->flags) ||
-           get_user(karg.request_count, &uarg->request_count) ||
-           get_user(karg.request_size, &uarg->request_size) ||
-           get_user(tmp3, &uarg->request_indices) ||
-           get_user(tmp4, &uarg->request_sizes) ||
-           get_user(karg.granted_count, &uarg->granted_count))
-               return -EFAULT;
-
-       u_si = (int *) A(tmp1);
-       u_ss = (int *) A(tmp2);
-       u_ri = (int *) A(tmp3);
-       u_rs = (int *) A(tmp4);
-
-       if (karg.send_count) {
-               karg.send_indices = kmalloc(karg.send_count * sizeof(int), GFP_KERNEL);
-               karg.send_sizes = kmalloc(karg.send_count * sizeof(int), GFP_KERNEL);
-
-               ret = -ENOMEM;
-               if (!karg.send_indices || !karg.send_sizes)
-                       goto out;
-
-               ret = -EFAULT;
-               if (copy_from_user(karg.send_indices, u_si,
-                                  (karg.send_count * sizeof(int))) ||
-                   copy_from_user(karg.send_sizes, u_ss,
-                                  (karg.send_count * sizeof(int))))
-                       goto out;
-       }
-
-       if (karg.request_count) {
-               karg.request_indices = kmalloc(karg.request_count * sizeof(int), GFP_KERNEL);
-               karg.request_sizes = kmalloc(karg.request_count * sizeof(int), GFP_KERNEL);
-
-               ret = -ENOMEM;
-               if (!karg.request_indices || !karg.request_sizes)
-                       goto out;
-
-               ret = -EFAULT;
-               if (copy_from_user(karg.request_indices, u_ri,
-                                  (karg.request_count * sizeof(int))) ||
-                   copy_from_user(karg.request_sizes, u_rs,
-                                  (karg.request_count * sizeof(int))))
-                       goto out;
-       }
-
-       old_fs = get_fs();
-       set_fs(KERNEL_DS);
-       ret = sys_ioctl(fd, DRM_IOCTL_DMA, (unsigned long) &karg);
-       set_fs(old_fs);
-
-       if (!ret) {
-               if (put_user(karg.context, &uarg->context) ||
-                   put_user(karg.send_count, &uarg->send_count) ||
-                   put_user(karg.flags, &uarg->flags) ||
-                   put_user(karg.request_count, &uarg->request_count) ||
-                   put_user(karg.request_size, &uarg->request_size) ||
-                   put_user(karg.granted_count, &uarg->granted_count))
-                       ret = -EFAULT;
-
-               if (karg.send_count) {
-                       if (copy_to_user(u_si, karg.send_indices,
-                                        (karg.send_count * sizeof(int))) ||
-                           copy_to_user(u_ss, karg.send_sizes,
-                                        (karg.send_count * sizeof(int))))
-                               ret = -EFAULT;
-               }
-               if (karg.request_count) {
-                       if (copy_to_user(u_ri, karg.request_indices,
-                                        (karg.request_count * sizeof(int))) ||
-                           copy_to_user(u_rs, karg.request_sizes,
-                                        (karg.request_count * sizeof(int))))
-                               ret = -EFAULT;
-               }
-       }
-
-out:
-       if (karg.send_indices)
-               kfree(karg.send_indices);
-       if (karg.send_sizes)
-               kfree(karg.send_sizes);
-       if (karg.request_indices)
-               kfree(karg.request_indices);
-       if (karg.request_sizes)
-               kfree(karg.request_sizes);
-
-       return ret;
-}
-
-typedef struct drm32_ctx_res {
-       int             count;
-       u32             contexts; /* (drm_ctx_t *) */
-} drm32_ctx_res_t;
-#define DRM32_IOCTL_RES_CTX    DRM_IOWR(0x26, drm32_ctx_res_t)
-
-static int drm32_res_ctx(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
-       drm32_ctx_res_t *uarg = (drm32_ctx_res_t *) arg;
-       drm_ctx_t *ulist;
-       drm_ctx_res_t karg;
-       mm_segment_t old_fs;
-       int orig_count, ret;
-       u32 tmp;
-
-       karg.contexts = NULL;
-       if (get_user(karg.count, &uarg->count) ||
-           get_user(tmp, &uarg->contexts))
-               return -EFAULT;
-
-       ulist = (drm_ctx_t *) A(tmp);
-
-       orig_count = karg.count;
-       if (karg.count && ulist) {
-               karg.contexts = kmalloc((karg.count * sizeof(drm_ctx_t)), GFP_KERNEL);
-               if (!karg.contexts)
-                       return -ENOMEM;
-               if (copy_from_user(karg.contexts, ulist,
-                                  (karg.count * sizeof(drm_ctx_t)))) {
-                       kfree(karg.contexts);
-                       return -EFAULT;
-               }
-       }
-
-       old_fs = get_fs();
-       set_fs(KERNEL_DS);
-       ret = sys_ioctl(fd, DRM_IOCTL_RES_CTX, (unsigned long) &karg);
-       set_fs(old_fs);
-
-       if (!ret) {
-               if (orig_count) {
-                       if (copy_to_user(ulist, karg.contexts,
-                                        (orig_count * sizeof(drm_ctx_t))))
-                               ret = -EFAULT;
-               }
-               if (put_user(karg.count, &uarg->count))
-                       ret = -EFAULT;
-       }
-
-       if (karg.contexts)
-               kfree(karg.contexts);
-
-       return ret;
-}
-
-#endif
 
 static int ret_einval(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
@@ -3491,7 +2950,7 @@ static int reiserfs_ioctl32(unsigned fd, unsigned cmd, unsigned long ptr)
 
 struct dirent32 {
        unsigned int            d_ino;
-       __kernel_off_t32        d_off;
+       compat_off_t    d_off;
        unsigned short  d_reclen;
        char            d_name[256]; /* We must not include limits.h! */
 };
@@ -4189,11 +3648,6 @@ COMPATIBLE_IOCTL(TIOCSERGETLSR)
 COMPATIBLE_IOCTL(FBIOGET_VSCREENINFO)
 COMPATIBLE_IOCTL(FBIOPUT_VSCREENINFO)
 COMPATIBLE_IOCTL(FBIOPAN_DISPLAY)
-COMPATIBLE_IOCTL(FBIOGET_FCURSORINFO)
-COMPATIBLE_IOCTL(FBIOGET_VCURSORINFO)
-COMPATIBLE_IOCTL(FBIOPUT_VCURSORINFO)
-COMPATIBLE_IOCTL(FBIOGET_CURSORSTATE)
-COMPATIBLE_IOCTL(FBIOPUT_CURSORSTATE)
 COMPATIBLE_IOCTL(FBIOGET_CON2FBMAP)
 COMPATIBLE_IOCTL(FBIOPUT_CON2FBMAP)
 /* Little f */
@@ -4696,27 +4150,6 @@ COMPATIBLE_IOCTL(LE_REMAP)
 COMPATIBLE_IOCTL(LV_BMAP)
 COMPATIBLE_IOCTL(LV_SNAPSHOT_USE_RATE)
 #endif /* LVM */
-#if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE)
-COMPATIBLE_IOCTL(DRM_IOCTL_GET_MAGIC)
-COMPATIBLE_IOCTL(DRM_IOCTL_IRQ_BUSID)
-COMPATIBLE_IOCTL(DRM_IOCTL_AUTH_MAGIC)
-COMPATIBLE_IOCTL(DRM_IOCTL_BLOCK)
-COMPATIBLE_IOCTL(DRM_IOCTL_UNBLOCK)
-COMPATIBLE_IOCTL(DRM_IOCTL_CONTROL)
-COMPATIBLE_IOCTL(DRM_IOCTL_ADD_BUFS)
-COMPATIBLE_IOCTL(DRM_IOCTL_MARK_BUFS)
-COMPATIBLE_IOCTL(DRM_IOCTL_ADD_CTX)
-COMPATIBLE_IOCTL(DRM_IOCTL_RM_CTX)
-COMPATIBLE_IOCTL(DRM_IOCTL_MOD_CTX)
-COMPATIBLE_IOCTL(DRM_IOCTL_GET_CTX)
-COMPATIBLE_IOCTL(DRM_IOCTL_SWITCH_CTX)
-COMPATIBLE_IOCTL(DRM_IOCTL_NEW_CTX)
-COMPATIBLE_IOCTL(DRM_IOCTL_ADD_DRAW)
-COMPATIBLE_IOCTL(DRM_IOCTL_RM_DRAW)
-COMPATIBLE_IOCTL(DRM_IOCTL_LOCK)
-COMPATIBLE_IOCTL(DRM_IOCTL_UNLOCK)
-COMPATIBLE_IOCTL(DRM_IOCTL_FINISH)
-#endif /* DRM */
 #ifdef CONFIG_AUTOFS_FS
 COMPATIBLE_IOCTL(AUTOFS_IOC_READY)
 COMPATIBLE_IOCTL(AUTOFS_IOC_FAIL)
@@ -4941,7 +4374,7 @@ HANDLE_IOCTL(VIDIOCSFBUF32, do_video_ioctl)
 HANDLE_IOCTL(VIDIOCGFREQ32, do_video_ioctl)
 HANDLE_IOCTL(VIDIOCSFREQ32, do_video_ioctl)
 /* One SMB ioctl needs translations. */
-#define SMB_IOC_GETMOUNTUID_32 _IOR('u', 1, __kernel_uid_t32)
+#define SMB_IOC_GETMOUNTUID_32 _IOR('u', 1, compat_pid_t)
 HANDLE_IOCTL(SMB_IOC_GETMOUNTUID_32, do_smb_getmountuid)
 HANDLE_IOCTL(ATM_GETLINKRATE32, do_atm_ioctl)
 HANDLE_IOCTL(ATM_GETNAMES32, do_atm_ioctl)
@@ -4984,17 +4417,6 @@ HANDLE_IOCTL(PV_STATUS, do_lvm_ioctl)
 HANDLE_IOCTL(VG_CREATE_OLD, do_lvm_ioctl)
 HANDLE_IOCTL(LV_STATUS_BYDEV, do_lvm_ioctl)
 #endif /* LVM */
-#if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE)
-HANDLE_IOCTL(DRM32_IOCTL_VERSION, drm32_version)
-HANDLE_IOCTL(DRM32_IOCTL_GET_UNIQUE, drm32_getsetunique)
-HANDLE_IOCTL(DRM32_IOCTL_SET_UNIQUE, drm32_getsetunique)
-HANDLE_IOCTL(DRM32_IOCTL_ADD_MAP, drm32_addmap)
-HANDLE_IOCTL(DRM32_IOCTL_INFO_BUFS, drm32_info_bufs)
-HANDLE_IOCTL(DRM32_IOCTL_FREE_BUFS, drm32_free_bufs)
-HANDLE_IOCTL(DRM32_IOCTL_MAP_BUFS, drm32_map_bufs)
-HANDLE_IOCTL(DRM32_IOCTL_DMA, drm32_dma)
-HANDLE_IOCTL(DRM32_IOCTL_RES_CTX, drm32_res_ctx)
-#endif /* DRM */
 /* VFAT */
 HANDLE_IOCTL(VFAT_IOCTL_READDIR_BOTH32, vfat_ioctl32)
 HANDLE_IOCTL(VFAT_IOCTL_READDIR_SHORT32, vfat_ioctl32)
@@ -5179,7 +4601,7 @@ int unregister_ioctl32_conversion(unsigned int cmd)
 EXPORT_SYMBOL(register_ioctl32_conversion); 
 EXPORT_SYMBOL(unregister_ioctl32_conversion); 
 
-asmlinkage int sys32_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
+asmlinkage long sys32_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
        struct file * filp;
        int error = -EBADF;
index 782e6144eedf3d43fb31a13a1c8732f66dc35875..3524132d1f0850208ee619f0d2ea04d4ebbe5205 100644 (file)
@@ -76,7 +76,7 @@ static int ia32_copy_siginfo_to_user(siginfo_t32 *to, siginfo_t *from)
        }
 }
 
-asmlinkage int
+asmlinkage long
 sys32_sigsuspend(int history0, int history1, old_sigset_t mask, struct pt_regs regs)
 {
        sigset_t saveset;
@@ -97,7 +97,7 @@ sys32_sigsuspend(int history0, int history1, old_sigset_t mask, struct pt_regs r
        }
 }
 
-asmlinkage int
+asmlinkage long
 sys32_sigaltstack(const stack_ia32_t *uss_ptr, stack_ia32_t *uoss_ptr, 
                                  struct pt_regs regs)
 {
@@ -227,7 +227,7 @@ badframe:
        return 1;
 }
 
-asmlinkage int sys32_sigreturn(struct pt_regs regs)
+asmlinkage long sys32_sigreturn(struct pt_regs regs)
 {
        struct sigframe *frame = (struct sigframe *)(regs.rsp - 8);
        sigset_t set;
@@ -256,7 +256,7 @@ badframe:
        return 0;
 }      
 
-asmlinkage int sys32_rt_sigreturn(struct pt_regs regs)
+asmlinkage long sys32_rt_sigreturn(struct pt_regs regs)
 {
        struct rt_sigframe *frame = (struct rt_sigframe *)(regs.rsp - 4);
        sigset_t set;
index df4e6d13ec3d31e5f9a024c890c3dbbc9fc4f04a..002940247a7fe038514dfce8d9b9eb156eeb6e47 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Compatibility mode system call entry point for x86-64. 
  *             
- * Copyright 2000,2001 Andi Kleen, SuSE Labs.
+ * Copyright 2000-2002 Andi Kleen, SuSE Labs.
  * 
  * $Id: ia32entry.S,v 1.31 2002/03/24 13:01:45 ak Exp $                
  */             
@@ -9,10 +9,11 @@
 #include <asm/calling.h>
 #include <asm/offset.h>
 #include <asm/current.h>
-#include <linux/linkage.h>
 #include <asm/errno.h>
 #include <asm/ia32_unistd.h>   
 #include <asm/thread_info.h>   
+#include <asm/segment.h>
+#include <linux/linkage.h>
 
        .macro IA32_ARG_FIXUP
        movl    %edi,%r8d
        .endm 
 
 /*
- * 32bit SYSCALL instruction entry.    
+ * 32bit SYSCALL instruction entry. This is called from the 32bit vsyscall page.
+ *     
+ * Register setup:
+ *
+ * %eax        System call number.
+ * %ebx Arg1
+ * %ecx return EIP 
+ * %edx Arg3
+ * %esi Arg4
+ * %edi Arg5
+ * %ebp Arg2    [note: not saved in the stack frame, should not be touched]
+ * %esp user stack 
+ * 0(%esp) 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_cstar_target)
-       movq $-ENOSYS,%rax
+       swapgs
+       movl    %esp,%r8d
+       movq    %gs:pda_kernelstack,%rsp
+       sti
+       SAVE_ARGS 8,1
+       movl    %eax,%eax       /* zero extension */
+       movq    %rax,ORIG_RAX-ARGOFFSET(%rsp)
+       movq    %rcx,RIP-ARGOFFSET(%rsp)
+       movl    %ebp,%ecx
+       movq    $__USER32_CS,CS-ARGOFFSET(%rsp)
+       movq    $__USER32_DS,SS-ARGOFFSET(%rsp)
+       movq    %r11,EFLAGS-ARGOFFSET(%rsp)
+       movq    %r8,RSP-ARGOFFSET(%rsp) 
+       /* no need to do an access_ok check here because the 32bit
+          user space cannot set r8 to a value > 4GB and the kernel has no
+          memory mapping in the first 4GB. */
+       /* hardware stack frame is complete now */      
+1:     movl    (%r8),%ebp
+       .section __ex_table,"a"
+       .quad 1b,cstar_badarg
+       .previous       
+       GET_THREAD_INFO(%r10)
+       bt  $TIF_SYSCALL_TRACE,threadinfo_flags(%r10)
+       jc  ia32_tracesys
+       cmpl $IA32_NR_syscalls,%eax
+       jae  ia32_badsys
+       IA32_ARG_FIXUP
+       call *ia32_sys_call_table(,%rax,8)
+       .globl ia32_sysret
+cstar_sysret:  
+       movq %rax,RAX-ARGOFFSET(%rsp)
+       GET_THREAD_INFO(%r10)
+       cli
+       testl $_TIF_WORK_MASK,threadinfo_flags(%r10)
+       jnz int_ret_from_sys_call
+       RESTORE_ARGS 1,0,1,1    /* could avoid the stack restore here */
+       movl RIP-SWFRAME(%rsp),%ecx
+       movl RSP-SWFRAME(%rsp),%esp
+       movl EFLAGS-SWFRAME(%rsp),%r11d
+       swapgs
        sysretl
        
+cstar_badarg:
+       movq $-EFAULT,%rax
+       jmp cstar_sysret
+
 /* 
  * Emulated IA32 system calls via int 0x80. 
  *
@@ -121,7 +183,7 @@ ENTRY(ia32_ptregs_common)
        .align 8
        .globl ia32_sys_call_table
 ia32_sys_call_table:
-       .quad ni_syscall        /* 0  -  old "setup" system call*/
+       .quad sys_restart_syscall
        .quad sys_exit
        .quad stub32_fork
        .quad sys_read
@@ -151,7 +213,7 @@ ia32_sys_call_table:
        .quad sys_alarm         /* XXX sign extension??? */ 
        .quad ni_syscall        /* (old)fstat */
        .quad sys_pause
-       .quad sys32_utime       /* 30 */
+       .quad compat_sys_utime  /* 30 */
        .quad ni_syscall        /* old stty syscall holder */
        .quad ni_syscall        /* old gtty syscall holder */
        .quad sys_access
@@ -164,7 +226,7 @@ ia32_sys_call_table:
        .quad sys_rmdir         /* 40 */
        .quad sys_dup
        .quad sys32_pipe
-       .quad sys32_times
+       .quad compat_sys_times
        .quad ni_syscall                        /* old prof syscall holder */
        .quad sys_brk           /* 45 */
        .quad sys_setgid16
@@ -225,11 +287,11 @@ ia32_sys_call_table:
        .quad sys_ioperm
        .quad sys32_socketcall
        .quad sys_syslog
-       .quad sys32_setitimer
-       .quad sys32_getitimer   /* 105 */
-       .quad sys32_newstat
-       .quad sys32_newlstat
-       .quad sys32_newfstat
+       .quad compat_sys_setitimer
+       .quad compat_sys_getitimer      /* 105 */
+       .quad compat_sys_newstat
+       .quad compat_sys_newlstat
+       .quad compat_sys_newfstat
        .quad sys32_uname
        .quad stub32_iopl               /* 110 */
        .quad sys_vhangup
@@ -283,7 +345,7 @@ ia32_sys_call_table:
        .quad sys_sched_get_priority_max
        .quad sys_sched_get_priority_min  /* 160 */
        .quad sys_sched_rr_get_interval
-       .quad sys32_nanosleep
+       .quad compat_sys_nanosleep
        .quad sys_mremap
        .quad sys_setresuid16
        .quad sys_getresuid16   /* 165 */
@@ -361,7 +423,7 @@ ia32_sys_call_table:
        .quad sys_fremovexattr
        .quad sys_tkill         /* 238 */ 
        .quad sys_sendfile64 
-       .quad sys_futex         /* 240 */
+       .quad sys32_futex               /* 240 */
         .quad sys32_sched_setaffinity
         .quad sys32_sched_getaffinity
        .quad sys_set_thread_area
@@ -374,6 +436,14 @@ ia32_sys_call_table:
        .quad sys_ni_syscall /* 250 alloc_huge_pages */
        .quad sys_ni_syscall /* free_huge_pages */
        .quad sys_exit_group /* exit_group */
+       .quad sys_lookup_dcookie
+       .quad sys_epoll_create
+       .quad sys_epoll_ctl
+       .quad sys_epoll_wait
+       .quad sys_remap_file_pages
+       .quad sys_set_tid_address
+       
+       /* don't forget to change IA32_NR_syscalls */
 ia32_syscall_end:              
        .rept IA32_NR_syscalls-(ia32_syscall_end-ia32_sys_call_table)/8
                .quad ni_syscall
index d8e7eebcfc2248934e012fd9b58a43cbd9f88f6d..380349f596db5f33a4793129e5f59f7009358b9a 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/shm.h>
 #include <linux/slab.h>
 #include <linux/ipc.h>
+#include <linux/compat.h>
 #include <asm/mman.h>
 #include <asm/types.h>
 #include <asm/uaccess.h>
@@ -29,10 +30,10 @@ struct msgbuf32 {
 
 struct ipc_perm32 {
        int key;
-       __kernel_uid_t32 uid;
-       __kernel_gid_t32 gid;
-       __kernel_uid_t32 cuid;
-       __kernel_gid_t32 cgid;
+       compat_uid_t uid;
+       compat_gid_t gid;
+       compat_uid_t cuid;
+       compat_gid_t cgid;
        unsigned short mode;
        unsigned short seq;
 };
@@ -53,8 +54,8 @@ struct ipc64_perm32 {
 
 struct semid_ds32 {
        struct ipc_perm32 sem_perm;               /* permissions .. see ipc.h */
-       __kernel_time_t32 sem_otime;              /* last semop time */
-       __kernel_time_t32 sem_ctime;              /* last change time */
+       compat_time_t sem_otime;              /* last semop time */
+       compat_time_t sem_ctime;              /* last change time */
        u32 sem_base;              /* ptr to first semaphore in array */
        u32 sem_pending;          /* pending operations to be processed */
        u32 sem_pending_last;    /* last pending operation */
@@ -64,9 +65,9 @@ struct semid_ds32 {
 
 struct semid64_ds32 {
        struct ipc64_perm32 sem_perm;
-       __kernel_time_t32 sem_otime;
+       compat_time_t sem_otime;
        unsigned int __unused1;
-       __kernel_time_t32 sem_ctime;
+       compat_time_t sem_ctime;
        unsigned int __unused2;
        unsigned int sem_nsems;
        unsigned int __unused3;
@@ -77,9 +78,9 @@ struct msqid_ds32 {
        struct ipc_perm32 msg_perm;
        u32 msg_first;
        u32 msg_last;
-       __kernel_time_t32 msg_stime;
-       __kernel_time_t32 msg_rtime;
-       __kernel_time_t32 msg_ctime;
+       compat_time_t msg_stime;
+       compat_time_t msg_rtime;
+       compat_time_t msg_ctime;
        u32 wwait;
        u32 rwait;
        unsigned short msg_cbytes;
@@ -91,17 +92,17 @@ struct msqid_ds32 {
 
 struct msqid64_ds32 {
        struct ipc64_perm32 msg_perm;
-       __kernel_time_t32 msg_stime;
+       compat_time_t msg_stime;
        unsigned int __unused1;
-       __kernel_time_t32 msg_rtime;
+       compat_time_t msg_rtime;
        unsigned int __unused2;
-       __kernel_time_t32 msg_ctime;
+       compat_time_t msg_ctime;
        unsigned int __unused3;
        unsigned int msg_cbytes;
        unsigned int msg_qnum;
        unsigned int msg_qbytes;
-       __kernel_pid_t32 msg_lspid;
-       __kernel_pid_t32 msg_lrpid;
+       compat_pid_t msg_lspid;
+       compat_pid_t msg_lrpid;
        unsigned int __unused4;
        unsigned int __unused5;
 };
@@ -109,9 +110,9 @@ struct msqid64_ds32 {
 struct shmid_ds32 {
        struct ipc_perm32 shm_perm;
        int shm_segsz;
-       __kernel_time_t32 shm_atime;
-       __kernel_time_t32 shm_dtime;
-       __kernel_time_t32 shm_ctime;
+       compat_time_t shm_atime;
+       compat_time_t shm_dtime;
+       compat_time_t shm_ctime;
        __kernel_ipc_pid_t32 shm_cpid;
        __kernel_ipc_pid_t32 shm_lpid;
        unsigned short shm_nattch;
@@ -119,15 +120,15 @@ struct shmid_ds32 {
 
 struct shmid64_ds32 {
        struct ipc64_perm32 shm_perm;
-       __kernel_size_t32 shm_segsz;
-       __kernel_time_t32 shm_atime;
+       compat_size_t shm_segsz;
+       compat_time_t shm_atime;
        unsigned int __unused1;
-       __kernel_time_t32 shm_dtime;
+       compat_time_t shm_dtime;
        unsigned int __unused2;
-       __kernel_time_t32 shm_ctime;
+       compat_time_t shm_ctime;
        unsigned int __unused3;
-       __kernel_pid_t32 shm_cpid;
-       __kernel_pid_t32 shm_lpid;
+       compat_pid_t shm_cpid;
+       compat_pid_t shm_lpid;
        unsigned int shm_nattch;
        unsigned int __unused4;
        unsigned int __unused5;
@@ -163,6 +164,7 @@ struct ipc_kludge {
 #define SEMOP           1
 #define SEMGET          2
 #define SEMCTL          3
+#define TIMEDSEMOP      4
 #define MSGSND         11
 #define MSGRCV         12
 #define MSGGET         13
@@ -622,7 +624,12 @@ sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth)
        switch (call) {
              case SEMOP:
                /* struct sembuf is the same on 32 and 64bit :)) */
-               return sys_semop(first, (struct sembuf *)AA(ptr), second);
+               return sys_semtimedop(first, (struct sembuf *)AA(ptr), second,
+                                     NULL);
+             case TIMEDSEMOP:
+               /* struct sembuf is the same on 32 and 64bit :)) */
+               return sys_semtimedop(first, (struct sembuf *)AA(ptr), second,
+                                     (const struct timespec *)AA(fifth));
              case SEMGET:
                return sys_semget(first, second, third);
              case SEMCTL:
@@ -646,7 +653,6 @@ sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth)
                return sys_shmget(first, second, third);
              case SHMCTL:
                return shmctl32(first, second, (void *)AA(ptr));
-
              default:
                return -EINVAL;
        }
index 332122ba4cd962edee55f4b9d0e5c168f514b56e..2b655007024c501817e1bc78651e1af9dc527b45 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/icmpv6.h>
 #include <linux/socket.h>
 #include <linux/filter.h>
+#include <linux/compat.h>
 
 #include <net/scm.h>
 #include <net/sock.h>
@@ -29,6 +30,9 @@
 #define A(__x)         ((unsigned long)(__x))
 #define AA(__x)                ((unsigned long)(__x))
 
+extern asmlinkage long sys_getsockopt(int fd, int level, int optname,
+                                      void * optval, int *optlen);
+
 
 static inline int iov_from_user32_to_kern(struct iovec *kiov,
                                          struct iovec32 *uiov32,
@@ -123,7 +127,7 @@ static int cmsghdr_from_user32_to_kern(struct msghdr *kmsg,
 {
        struct cmsghdr32 *ucmsg;
        struct cmsghdr *kcmsg, *kcmsg_base;
-       __kernel_size_t32 ucmlen;
+       compat_size_t ucmlen;
        __kernel_size_t kcmlen, tmp;
 
        kcmlen = 0;
@@ -362,7 +366,7 @@ fail:
        kmsg->msg_control = (void *) orig_cmsg_uptr;
 }
 
-asmlinkage int sys32_sendmsg(int fd, struct msghdr32 *user_msg, unsigned user_flags)
+asmlinkage long sys32_sendmsg(int fd, struct msghdr32 *user_msg, unsigned user_flags)
 {
        struct socket *sock;
        char address[MAX_SOCK_ADDR];
@@ -407,7 +411,7 @@ out:
        return err;
 }
 
-asmlinkage int sys32_recvmsg(int fd, struct msghdr32 *user_msg, unsigned int user_flags)
+asmlinkage long sys32_recvmsg(int fd, struct msghdr32 *user_msg, unsigned int user_flags)
 {
        struct iovec iovstack[UIO_FASTIOV];
        struct msghdr kern_msg;
@@ -489,7 +493,7 @@ asmlinkage int sys32_recvmsg(int fd, struct msghdr32 *user_msg, unsigned int use
                err = move_addr_to_user(addr, kern_msg.msg_namelen, uaddr, uaddr_len);
        if(cmsg_ptr != 0 && err >= 0) {
                unsigned long ucmsg_ptr = ((unsigned long)kern_msg.msg_control);
-               __kernel_size_t32 uclen = (__kernel_size_t32) (ucmsg_ptr - cmsg_ptr);
+               compat_size_t uclen = (compat_size_t) (ucmsg_ptr - cmsg_ptr);
                err |= __put_user(uclen, &user_msg->msg_controllen);
        }
        if(err >= 0)
@@ -575,12 +579,34 @@ static int do_set_icmpv6_filter(int fd, int level, int optname,
        return ret;
 }
 
-asmlinkage int sys32_setsockopt(int fd, int level, int optname,
+static int do_set_sock_timeout(int fd, int level, int optname, char *optval, int optlen)
+{
+       struct compat_timeval *up = (struct compat_timeval *) optval;
+       struct timeval ktime;
+       mm_segment_t old_fs;
+       int err;
+
+       if (optlen < sizeof(*up))
+               return -EINVAL;
+       if (get_user(ktime.tv_sec, &up->tv_sec) ||
+           __get_user(ktime.tv_usec, &up->tv_usec))
+               return -EFAULT;
+       old_fs = get_fs();
+       set_fs(KERNEL_DS);
+       err = sys_setsockopt(fd, level, optname, (char *) &ktime, sizeof(ktime));
+       set_fs(old_fs);
+
+       return err;
+}
+
+asmlinkage long sys32_setsockopt(int fd, int level, int optname,
                                char *optval, int optlen)
 {
        if (optname == SO_ATTACH_FILTER)
                return do_set_attach_filter(fd, level, optname,
                                            optval, optlen);
+       if (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO)
+               return do_set_sock_timeout(fd, level, optname, optval, optlen);
        if (level == SOL_ICMPV6 && optname == ICMPV6_FILTER)
                return do_set_icmpv6_filter(fd, level, optname,
                                            optval, optlen);
@@ -588,6 +614,39 @@ asmlinkage int sys32_setsockopt(int fd, int level, int optname,
        return sys_setsockopt(fd, level, optname, optval, optlen);
 }
 
+static int do_get_sock_timeout(int fd, int level, int optname, char *optval, int *optlen)
+{
+       struct compat_timeval *up = (struct compat_timeval *) optval;
+       struct timeval ktime;
+       mm_segment_t old_fs;
+       int len, err;
+
+       if (get_user(len, optlen))
+               return -EFAULT;
+       if (len < sizeof(*up))
+               return -EINVAL;
+       len = sizeof(ktime);
+       old_fs = get_fs();
+       set_fs(KERNEL_DS);
+       err = sys_getsockopt(fd, level, optname, (char *) &ktime, &len);
+       set_fs(old_fs);
+
+       if (!err) {
+               if (put_user(sizeof(*up), optlen) ||
+                   put_user(ktime.tv_sec, &up->tv_sec) ||
+                   __put_user(ktime.tv_usec, &up->tv_usec))
+                       err = -EFAULT;
+       }
+       return err;
+}
+
+asmlinkage long sys32_getsockopt(int fd, int level, int optname,
+                               char *optval, int *optlen)
+{
+       if (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO)
+               return do_get_sock_timeout(fd, level, optname, optval, optlen);
+       return sys_getsockopt(fd, level, optname, optval, optlen);
+}
 
 /* Argument list sizes for sys_socketcall */
 #define AL(x) ((x) * sizeof(u32))
@@ -606,14 +665,11 @@ extern asmlinkage long sys_getsockname(int fd, struct sockaddr *usockaddr,
 extern asmlinkage long sys_getpeername(int fd, struct sockaddr *usockaddr,
                                      int *usockaddr_len);
 extern asmlinkage long sys_send(int fd, void *buff, size_t len, unsigned flags);
-extern asmlinkage long sys_sendto(int fd, u32 buff, __kernel_size_t32 len,
+extern asmlinkage long sys_sendto(int fd, u32 buff, compat_size_t len,
                                   unsigned flags, u32 addr, int addr_len);
 extern asmlinkage long sys_recv(int fd, void *ubuf, size_t size, unsigned flags);
-extern asmlinkage long sys_recvfrom(int fd, u32 ubuf, __kernel_size_t32 size,
+extern asmlinkage long sys_recvfrom(int fd, u32 ubuf, compat_size_t size,
                                     unsigned flags, u32 addr, u32 addr_len);
-extern asmlinkage long sys_getsockopt(int fd, int level, int optname,
-                                      u32 optval, u32 optlen);
-
 extern asmlinkage long sys_socket(int family, int type, int protocol);
 extern asmlinkage long sys_socketpair(int family, int type, int protocol,
                                     int usockvec[2]);
@@ -678,11 +734,11 @@ asmlinkage long sys32_socketcall(int call, u32 *args)
                        ret = sys_shutdown(a0,a1);
                        break;
                case SYS_SETSOCKOPT:
-                       ret = sys_setsockopt(a0, a1, a[2], (char *)A(a[3]),
+                       ret = sys32_setsockopt(a0, a1, a[2], (char *)A(a[3]),
                                              a[4]);
                        break;
                case SYS_GETSOCKOPT:
-                       ret = sys_getsockopt(a0, a1, a[2], a[3], a[4]);
+                       ret = sys32_getsockopt(a0, a1, a[2], (char *)(u64)a[3], (int *)(u64)a[4]);
                        break;
                case SYS_SENDMSG:
                        ret = sys32_sendmsg(a0, (struct msghdr32 *)A(a1),
index 8566fb21b7fdac8102210fc1b57d43ecbbcfc6c7..24b33f75bfb5eaad13b82a32710b3f707230479b 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/fs.h> 
 #include <linux/file.h> 
 #include <linux/signal.h>
-#include <linux/utime.h>
 #include <linux/resource.h>
 #include <linux/times.h>
 #include <linux/utsname.h>
@@ -58,6 +57,7 @@
 #include <linux/binfmts.h>
 #include <linux/init.h>
 #include <linux/aio_abi.h>
+#include <linux/compat.h>
 #include <asm/mman.h>
 #include <asm/types.h>
 #include <asm/uaccess.h>
 extern int overflowuid,overflowgid; 
 
 
-static int
-putstat(struct stat32 *ubuf, struct stat *kbuf)
-{
-       if (verify_area(VERIFY_WRITE, ubuf, sizeof(struct stat32)) ||
-           __put_user (kbuf->st_dev, &ubuf->st_dev) ||
-           __put_user (kbuf->st_ino, &ubuf->st_ino) ||
-           __put_user (kbuf->st_mode, &ubuf->st_mode) ||
-           __put_user (kbuf->st_nlink, &ubuf->st_nlink) ||
-           __put_user (kbuf->st_uid, &ubuf->st_uid) ||
-           __put_user (kbuf->st_gid, &ubuf->st_gid) ||
-           __put_user (kbuf->st_rdev, &ubuf->st_rdev) ||
-           __put_user (kbuf->st_size, &ubuf->st_size) ||
-           __put_user (kbuf->st_atime, &ubuf->st_atime) ||
-           __put_user (kbuf->st_mtime, &ubuf->st_mtime) ||
-           __put_user (kbuf->st_ctime, &ubuf->st_ctime) ||
-           __put_user (kbuf->st_blksize, &ubuf->st_blksize) ||
-           __put_user (kbuf->st_blocks, &ubuf->st_blocks))
+int cp_compat_stat(struct kstat *kbuf, struct compat_stat *ubuf)
+{
+       if (verify_area(VERIFY_WRITE, ubuf, sizeof(struct compat_stat)) ||
+           __put_user (kbuf->dev, &ubuf->st_dev) ||
+           __put_user (kbuf->ino, &ubuf->st_ino) ||
+           __put_user (kbuf->mode, &ubuf->st_mode) ||
+           __put_user (kbuf->nlink, &ubuf->st_nlink) ||
+           __put_user (kbuf->uid, &ubuf->st_uid) ||
+           __put_user (kbuf->gid, &ubuf->st_gid) ||
+           __put_user (kbuf->rdev, &ubuf->st_rdev) ||
+           __put_user (kbuf->size, &ubuf->st_size) ||
+           __put_user (kbuf->atime.tv_sec, &ubuf->st_atime) ||
+           __put_user (kbuf->atime.tv_nsec, &ubuf->st_atime_nsec) ||
+           __put_user (kbuf->mtime.tv_sec, &ubuf->st_mtime) ||
+           __put_user (kbuf->mtime.tv_nsec, &ubuf->st_mtime_nsec) ||
+           __put_user (kbuf->ctime.tv_sec, &ubuf->st_ctime) ||
+           __put_user (kbuf->ctime.tv_nsec, &ubuf->st_ctime_nsec) ||
+           __put_user (kbuf->blksize, &ubuf->st_blksize) ||
+           __put_user (kbuf->blocks, &ubuf->st_blocks))
                return -EFAULT;
        return 0;
 }
 
-extern asmlinkage long sys_newstat(char * filename, struct stat * statbuf);
-
-asmlinkage long
-sys32_newstat(char * filename, struct stat32 *statbuf)
-{
-       int ret;
-       struct stat s;
-       mm_segment_t old_fs = get_fs();
-       
-       set_fs (KERNEL_DS);
-       ret = sys_newstat(filename, &s);
-       set_fs (old_fs);
-       if (putstat (statbuf, &s))
-               return -EFAULT;
-       return ret;
-}
-
-extern asmlinkage long sys_newlstat(char * filename, struct stat * statbuf);
-
-asmlinkage long
-sys32_newlstat(char * filename, struct stat32 *statbuf)
-{
-       int ret;
-       struct stat s;
-       mm_segment_t old_fs = get_fs();
-       
-       set_fs (KERNEL_DS);
-       ret = sys_newlstat(filename, &s);
-       set_fs (old_fs);
-       if (putstat (statbuf, &s))
-               return -EFAULT;
-       return ret;
-}
-
-extern asmlinkage long sys_newfstat(unsigned int fd, struct stat * statbuf);
-
-asmlinkage long
-sys32_newfstat(unsigned int fd, struct stat32 *statbuf)
-{
-       int ret;
-       struct stat s;
-       mm_segment_t old_fs = get_fs();
-       
-       set_fs (KERNEL_DS);
-       ret = sys_newfstat(fd, &s);
-       set_fs (old_fs);
-       if (putstat (statbuf, &s))
-               return -EFAULT;
-       return ret;
-}
-
 /* Another set for IA32/LFS -- x86_64 struct stat is different due to 
    support for 64bit inode numbers. */
 
@@ -175,8 +126,11 @@ putstat64(struct stat64 *ubuf, struct stat *kbuf)
            __put_user (kbuf->st_rdev, &ubuf->st_rdev) ||
            __put_user (kbuf->st_size, &ubuf->st_size) ||
            __put_user (kbuf->st_atime, &ubuf->st_atime) ||
+           __put_user (kbuf->st_atime_nsec, &ubuf->st_atime_nsec) ||
            __put_user (kbuf->st_mtime, &ubuf->st_mtime) ||
+           __put_user (kbuf->st_mtime_nsec, &ubuf->st_mtime_nsec) ||
            __put_user (kbuf->st_ctime, &ubuf->st_ctime) ||
+           __put_user (kbuf->st_ctime_nsec, &ubuf->st_ctime_nsec) ||
            __put_user (kbuf->st_blksize, &ubuf->st_blksize) ||
            __put_user (kbuf->st_blocks, &ubuf->st_blocks))
                return -EFAULT;
@@ -245,7 +199,7 @@ struct mmap_arg_struct {
        unsigned int offset;
 };
 
-asmlinkage __u32
+asmlinkage long
 sys32_mmap(struct mmap_arg_struct *arg)
 {
        struct mmap_arg_struct a;
@@ -265,10 +219,8 @@ sys32_mmap(struct mmap_arg_struct *arg)
                        return -EBADF;
        }
        
-#if 0 /* reenable when noexec works */
        if (a.prot & PROT_READ) 
                a.prot |= PROT_EXEC; 
-#endif
 
        a.flags |= MAP_32BIT;
 
@@ -279,7 +231,7 @@ sys32_mmap(struct mmap_arg_struct *arg)
                fput(file);
 
        /* Cannot wrap */
-       if (retval+a.len >= 0xFFFFFFFF && (long)retval > 0) { 
+       if (retval+a.len >= IA32_PAGE_OFFSET && (long)retval > 0) { 
                do_munmap(mm, retval, a.len); 
                retval = -ENOMEM; 
        } 
@@ -290,7 +242,8 @@ sys32_mmap(struct mmap_arg_struct *arg)
 
 extern asmlinkage long sys_mprotect(unsigned long start,size_t len,unsigned long prot);
 
-asmlinkage int sys32_mprotect(unsigned long start, size_t len, unsigned long prot)
+asmlinkage long 
+sys32_mprotect(unsigned long start, size_t len, unsigned long prot)
 {
        if (prot & PROT_READ) 
                prot |= PROT_EXEC; 
@@ -498,19 +451,8 @@ sys32_fstatfs(unsigned int fd, struct statfs32 *buf)
        return ret;
 }
 
-struct timeval32
-{
-    int tv_sec, tv_usec;
-};
-
-struct itimerval32
-{
-    struct timeval32 it_interval;
-    struct timeval32 it_value;
-};
-
 static inline long
-get_tv32(struct timeval *o, struct timeval32 *i)
+get_tv32(struct timeval *o, struct compat_timeval *i)
 {
        int err = -EFAULT; 
        if (access_ok(VERIFY_READ, i, sizeof(*i))) { 
@@ -521,7 +463,7 @@ get_tv32(struct timeval *o, struct timeval32 *i)
 }
 
 static inline long
-put_tv32(struct timeval32 *o, struct timeval *i)
+put_tv32(struct compat_timeval *o, struct timeval *i)
 {
        int err = -EFAULT;
        if (access_ok(VERIFY_WRITE, o, sizeof(*o))) { 
@@ -531,71 +473,7 @@ put_tv32(struct timeval32 *o, struct timeval *i)
        return err; 
 }
 
-static inline long
-get_it32(struct itimerval *o, struct itimerval32 *i)
-{
-       int err = -EFAULT; 
-       if (access_ok(VERIFY_READ, i, sizeof(*i))) { 
-               err = __get_user(o->it_interval.tv_sec, &i->it_interval.tv_sec);
-               err |= __get_user(o->it_interval.tv_usec, &i->it_interval.tv_usec);
-               err |= __get_user(o->it_value.tv_sec, &i->it_value.tv_sec);
-               err |= __get_user(o->it_value.tv_usec, &i->it_value.tv_usec);
-       }
-       return err;
-}
-
-static inline long
-put_it32(struct itimerval32 *o, struct itimerval *i)
-{
-       int err = -EFAULT;
-       if (access_ok(VERIFY_WRITE, o, sizeof(*o))) {
-               err = __put_user(i->it_interval.tv_sec, &o->it_interval.tv_sec);
-               err |= __put_user(i->it_interval.tv_usec, &o->it_interval.tv_usec);
-               err |= __put_user(i->it_value.tv_sec, &o->it_value.tv_sec);
-               err |= __put_user(i->it_value.tv_usec, &o->it_value.tv_usec); 
-       } 
-       return err;
-}
-
-extern int do_getitimer(int which, struct itimerval *value);
-
-asmlinkage long
-sys32_getitimer(int which, struct itimerval32 *it)
-{
-       struct itimerval kit;
-       int error;
-
-       error = do_getitimer(which, &kit);
-       if (!error && put_it32(it, &kit))
-               error = -EFAULT;
-
-       return error;
-}
-
-extern int do_setitimer(int which, struct itimerval *, struct itimerval *);
-
 asmlinkage long
-sys32_setitimer(int which, struct itimerval32 *in, struct itimerval32 *out)
-{
-       struct itimerval kin, kout;
-       int error;
-
-       if (in) {
-               if (get_it32(&kin, in))
-                       return -EFAULT;
-       } else
-               memset(&kin, 0, sizeof(kin));
-
-       error = do_setitimer(which, &kin, out ? &kout : NULL);
-       if (error || !out)
-               return error;
-       if (put_it32(out, &kout))
-               return -EFAULT;
-
-       return 0;
-
-}
-asmlinkage unsigned long 
 sys32_alarm(unsigned int seconds)
 {
        struct itimerval it_new, it_old;
@@ -616,45 +494,11 @@ sys32_alarm(unsigned int seconds)
 /* Translations due to time_t size differences.  Which affects all
    sorts of things, like timeval and itimerval.  */
 
-struct utimbuf_32 {
-       int     atime;
-       int     mtime;
-};
-
-extern asmlinkage long sys_utimes(char * filename, struct timeval * utimes);
-extern asmlinkage long sys_gettimeofday (struct timeval *tv, struct timezone *tz);
-
-asmlinkage long
-ia32_utime(char * filename, struct utimbuf_32 *times32)
-{
-       mm_segment_t old_fs = get_fs();
-       struct timeval tv[2];
-       long ret;
-
-       if (times32) {
-               get_user(tv[0].tv_sec, &times32->atime);
-               tv[0].tv_usec = 0;
-               get_user(tv[1].tv_sec, &times32->mtime);
-               tv[1].tv_usec = 0;
-               set_fs (KERNEL_DS);
-       } else {
-               set_fs (KERNEL_DS);
-               ret = sys_gettimeofday(&tv[0], 0);
-               if (ret < 0)
-                       goto out;
-               tv[1] = tv[0];
-       }
-       ret = sys_utimes(filename, tv);
-  out:
-       set_fs (old_fs);
-       return ret;
-}
-
 extern struct timezone sys_tz;
 extern int do_sys_settimeofday(struct timeval *tv, struct timezone *tz);
 
 asmlinkage long
-sys32_gettimeofday(struct timeval32 *tv, struct timezone *tz)
+sys32_gettimeofday(struct compat_timeval *tv, struct timezone *tz)
 {
        if (tv) {
                struct timeval ktv;
@@ -670,7 +514,7 @@ sys32_gettimeofday(struct timeval32 *tv, struct timezone *tz)
 }
 
 asmlinkage long
-sys32_settimeofday(struct timeval32 *tv, struct timezone *tz)
+sys32_settimeofday(struct compat_timeval *tv, struct timezone *tz)
 {
        struct timeval ktv;
        struct timezone ktz;
@@ -827,7 +671,7 @@ out:
 #define ROUND_UP_TIME(x,y) (((x)+(y)-1)/(y))
 
 asmlinkage long
-sys32_select(int n, fd_set *inp, fd_set *outp, fd_set *exp, struct timeval32 *tvp32)
+sys32_select(int n, fd_set *inp, fd_set *outp, fd_set *exp, struct compat_timeval *tvp32)
 {
        fd_set_bits fds;
        char *bits;
@@ -931,37 +775,7 @@ sys32_old_select(struct sel_arg_struct *arg)
        if (copy_from_user(&a, arg, sizeof(a)))
                return -EFAULT;
        return sys32_select(a.n, (fd_set *)A(a.inp), (fd_set *)A(a.outp), (fd_set *)A(a.exp),
-                           (struct timeval32 *)A(a.tvp));
-}
-
-struct timespec32 {
-       int     tv_sec;
-       int     tv_nsec;
-};
-
-extern asmlinkage long sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp); 
-
-asmlinkage long
-sys32_nanosleep(struct timespec32 *rqtp, struct timespec32 *rmtp)
-{
-       struct timespec t;
-       int ret;
-       mm_segment_t old_fs = get_fs ();
-       
-       if (verify_area(VERIFY_READ, rqtp, sizeof(struct timespec32)) ||
-           __get_user (t.tv_sec, &rqtp->tv_sec) ||
-           __get_user (t.tv_nsec, &rqtp->tv_nsec))
-               return -EFAULT;
-       set_fs (KERNEL_DS);
-       ret = sys_nanosleep(&t, rmtp ? &t : NULL);
-       set_fs (old_fs);
-       if (rmtp && ret == -EINTR) {
-               if (verify_area(VERIFY_WRITE, rmtp, sizeof(struct timespec32)) ||
-                   __put_user (t.tv_sec, &rmtp->tv_sec) ||
-                   __put_user (t.tv_nsec, &rmtp->tv_nsec))
-                       return -EFAULT;
-       }
-       return ret;
+                           (struct compat_timeval *)A(a.tvp));
 }
 
 asmlinkage ssize_t sys_readv(unsigned long,const struct iovec *,unsigned long);
@@ -1153,8 +967,8 @@ asmlinkage long sys32_time(int * tloc)
 }
 
 struct rusage32 {
-        struct timeval32 ru_utime;
-        struct timeval32 ru_stime;
+        struct compat_timeval ru_utime;
+        struct compat_timeval ru_stime;
         int    ru_maxrss;
         int    ru_ixrss;
         int    ru_idrss;
@@ -1201,7 +1015,7 @@ extern asmlinkage long sys_wait4(pid_t pid,unsigned int * stat_addr,
                                int options, struct rusage * ru);
 
 asmlinkage long
-sys32_wait4(__kernel_pid_t32 pid, unsigned int *stat_addr, int options,
+sys32_wait4(compat_pid_t pid, unsigned int *stat_addr, int options,
            struct rusage32 *ru)
 {
        if (!ru)
@@ -1223,7 +1037,7 @@ sys32_wait4(__kernel_pid_t32 pid, unsigned int *stat_addr, int options,
 }
 
 asmlinkage long
-sys32_waitpid(__kernel_pid_t32 pid, unsigned int *stat_addr, int options)
+sys32_waitpid(compat_pid_t pid, unsigned int *stat_addr, int options)
 {
        return sys32_wait4(pid, stat_addr, options, NULL);
 }
@@ -1246,37 +1060,6 @@ sys32_getrusage(int who, struct rusage32 *ru)
        return ret;
 }
 
-struct tms32 {
-       __kernel_clock_t32 tms_utime;
-       __kernel_clock_t32 tms_stime;
-       __kernel_clock_t32 tms_cutime;
-       __kernel_clock_t32 tms_cstime;
-};
-                                
-extern int sys_times(struct tms *);
-
-asmlinkage long
-sys32_times(struct tms32 *tbuf)
-{
-       struct tms t;
-       long ret;
-       mm_segment_t old_fs = get_fs ();
-       
-       set_fs (KERNEL_DS);
-       ret = sys_times(tbuf ? &t : NULL);
-       set_fs (old_fs);
-       if (tbuf) {
-               if (verify_area(VERIFY_WRITE, tbuf, sizeof(struct tms32)) ||
-                   __put_user (t.tms_utime, &tbuf->tms_utime) ||
-                   __put_user (t.tms_stime, &tbuf->tms_stime) ||
-                   __put_user (t.tms_cutime, &tbuf->tms_cutime) ||
-                   __put_user (t.tms_cstime, &tbuf->tms_cstime))
-                       return -EFAULT;
-       }
-       return ret;
-}
-
-
 static inline int get_flock(struct flock *kfl, struct flock32 *ufl)
 {
        int err;
@@ -1406,38 +1189,6 @@ int sys32_ni_syscall(int call)
 
 /* 32-bit timeval and related flotsam.  */
 
-extern asmlinkage long sys_utime(char * filename, struct utimbuf * times);
-
-struct utimbuf32 {
-       __kernel_time_t32 actime, modtime;
-};
-
-asmlinkage long
-sys32_utime(char * filename, struct utimbuf32 *times)
-{
-       struct utimbuf t;
-       mm_segment_t old_fs;
-       int ret;
-       char *filenam;
-       
-       if (!times)
-               return sys_utime(filename, NULL);
-       if (verify_area(VERIFY_READ, times, sizeof(struct utimbuf32)) ||
-           __get_user (t.actime, &times->actime) ||
-           __get_user (t.modtime, &times->modtime))
-               return -EFAULT;
-       filenam = getname (filename);
-       ret = PTR_ERR(filenam);
-       if (!IS_ERR(filenam)) {
-               old_fs = get_fs();
-               set_fs (KERNEL_DS); 
-               ret = sys_utime(filenam, &t);
-               set_fs (old_fs);
-               putname(filenam);
-       }
-       return ret;
-}
-
 extern asmlinkage long sys_sysfs(int option, unsigned long arg1,
                                unsigned long arg2);
 
@@ -1528,7 +1279,7 @@ extern asmlinkage long sys_sched_rr_get_interval(pid_t pid,
                                                struct timespec *interval);
 
 asmlinkage long
-sys32_sched_rr_get_interval(__kernel_pid_t32 pid, struct timespec32 *interval)
+sys32_sched_rr_get_interval(compat_pid_t pid, struct compat_timespec *interval)
 {
        struct timespec t;
        int ret;
@@ -1537,7 +1288,7 @@ sys32_sched_rr_get_interval(__kernel_pid_t32 pid, struct timespec32 *interval)
        set_fs (KERNEL_DS);
        ret = sys_sched_rr_get_interval(pid, &t);
        set_fs (old_fs);
-       if (verify_area(VERIFY_WRITE, interval, sizeof(struct timespec32)) ||
+       if (verify_area(VERIFY_WRITE, interval, sizeof(struct compat_timespec)) ||
            __put_user (t.tv_sec, &interval->tv_sec) ||
            __put_user (t.tv_nsec, &interval->tv_nsec))
                return -EFAULT;
@@ -1582,7 +1333,7 @@ sys32_sigpending(old_sigset32_t *set)
 extern asmlinkage long sys_rt_sigpending(sigset_t *set, size_t sigsetsize);
 
 asmlinkage long
-sys32_rt_sigpending(sigset32_t *set, __kernel_size_t32 sigsetsize)
+sys32_rt_sigpending(sigset32_t *set, compat_size_t sigsetsize)
 {
        sigset_t s;
        sigset32_t s32;
@@ -1688,7 +1439,7 @@ sys_rt_sigtimedwait(const sigset_t *uthese, siginfo_t *uinfo,
 
 asmlinkage long
 sys32_rt_sigtimedwait(sigset32_t *uthese, siginfo_t32 *uinfo,
-                     struct timespec32 *uts, __kernel_size_t32 sigsetsize)
+                     struct compat_timespec *uts, compat_size_t sigsetsize)
 {
        sigset_t s;
        sigset32_t s32;
@@ -1707,7 +1458,7 @@ sys32_rt_sigtimedwait(sigset32_t *uthese, siginfo_t32 *uinfo,
        case 1: s.sig[0] = s32.sig[0] | (((long)s32.sig[1]) << 32);
        }
        if (uts) {
-               if (verify_area(VERIFY_READ, uts, sizeof(struct timespec32)) ||
+               if (verify_area(VERIFY_READ, uts, sizeof(struct compat_timespec)) ||
                    __get_user (t.tv_sec, &uts->tv_sec) ||
                    __get_user (t.tv_nsec, &uts->tv_nsec))
                        return -EFAULT;
@@ -1749,7 +1500,7 @@ extern void check_pending(int signum);
 asmlinkage long sys_utimes(char *, struct timeval *);
 
 asmlinkage long
-sys32_utimes(char *filename, struct timeval32 *tvs)
+sys32_utimes(char *filename, struct compat_timeval *tvs)
 {
        char *kfilename;
        struct timeval ktvs[2];
@@ -1851,21 +1602,16 @@ extern asmlinkage ssize_t sys_pread64(unsigned int fd, char * buf,
 extern asmlinkage ssize_t sys_pwrite64(unsigned int fd, const char * buf,
                                     size_t count, loff_t pos);
 
-typedef __kernel_ssize_t32 ssize_t32;
-
-
 /* warning: next two assume little endian */ 
-asmlinkage ssize_t32
-sys32_pread(unsigned int fd, char *ubuf, __kernel_size_t32 count,
-           u32 poslo, u32 poshi)
+asmlinkage long
+sys32_pread(unsigned int fd, char *ubuf, u32 count, u32 poslo, u32 poshi)
 {
        return sys_pread64(fd, ubuf, count,
                         ((loff_t)AA(poshi) << 32) | AA(poslo));
 }
 
-asmlinkage ssize_t32
-sys32_pwrite(unsigned int fd, char *ubuf, __kernel_size_t32 count,
-            u32 poslo, u32 poshi)
+asmlinkage long
+sys32_pwrite(unsigned int fd, char *ubuf, u32 count, u32 poslo, u32 poshi)
 {
        return sys_pwrite64(fd, ubuf, count,
                          ((loff_t)AA(poshi) << 32) | AA(poslo));
@@ -1891,7 +1637,7 @@ extern asmlinkage ssize_t sys_sendfile(int out_fd, int in_fd, off_t *offset,
                                       size_t count); 
 
 asmlinkage long
-sys32_sendfile(int out_fd, int in_fd, __kernel_off_t32 *offset, s32 count)
+sys32_sendfile(int out_fd, int in_fd, compat_off_t *offset, s32 count)
 {
        mm_segment_t old_fs = get_fs();
        int ret;
@@ -1916,7 +1662,7 @@ struct timex32 {
        u32 modes;
        s32 offset, freq, maxerror, esterror;
        s32 status, constant, precision, tolerance;
-       struct timeval32 time;
+       struct compat_timeval time;
        s32 tick;
        s32 ppsfreq, jitter, shift, stabil;
        s32 jitcnt, calcnt, errcnt, stbcnt;
@@ -2001,14 +1747,15 @@ asmlinkage long sys32_mmap2(unsigned long addr, unsigned long len,
                        return -EBADF;
        }
 
-       /* later add PROT_EXEC for PROT_READ here */
+       if (prot & PROT_READ)
+               prot |= PROT_EXEC;
 
        down_write(&mm->mmap_sem);
        error = do_mmap_pgoff(file, addr, len, prot, flags|MAP_32BIT, pgoff);
        up_write(&mm->mmap_sem);
 
        /* cannot wrap */
-       if (error+len >= 0xFFFFFFFF && (long)error >= 0) { 
+       if (error+len >= IA32_PAGE_OFFSET && (long)error >= 0) { 
                do_munmap(mm, error, len); 
                error = -ENOMEM; 
        } 
@@ -2051,7 +1798,7 @@ asmlinkage long sys32_olduname(struct oldold_utsname * name)
         return error;
 }
 
-int sys32_uname(struct old_utsname * name)
+long sys32_uname(struct old_utsname * name)
 {
        int err;
        if (!name)
@@ -2066,7 +1813,7 @@ int sys32_uname(struct old_utsname * name)
 
 extern int sys_ustat(dev_t, struct ustat *);
 
-int sys32_ustat(dev_t dev, struct ustat32 *u32p)
+long sys32_ustat(dev_t dev, struct ustat32 *u32p)
 {
        struct ustat u;
        mm_segment_t seg;
@@ -2109,7 +1856,7 @@ static int nargs(u32 src, char **dst)
        return cnt; 
 } 
 
-int sys32_execve(char *name, u32 argv, u32 envp, struct pt_regs regs)
+long sys32_execve(char *name, u32 argv, u32 envp, struct pt_regs regs)
 { 
        mm_segment_t oldseg; 
        char **buf; 
@@ -2163,20 +1910,22 @@ free:
        return ret; 
 } 
 
-asmlinkage int sys32_fork(struct pt_regs regs)
+asmlinkage long sys32_fork(struct pt_regs regs)
 {
        struct task_struct *p;
-       p = do_fork(SIGCHLD, regs.rsp, &regs, 0, NULL);
+       p = do_fork(SIGCHLD, regs.rsp, &regs, 0, NULL, NULL);
        return IS_ERR(p) ? PTR_ERR(p) : p->pid;
 }
 
-asmlinkage int sys32_clone(unsigned int clone_flags, unsigned int newsp, struct pt_regs regs)
+asmlinkage long sys32_clone(unsigned int clone_flags, unsigned int newsp, struct pt_regs regs)
 {
        struct task_struct *p;
-       int *user_tid = (int *)regs.rdx;
+       void *parent_tid = (void *)regs.rdx;
+       void *child_tid = (void *)regs.rdi; 
        if (!newsp)
                newsp = regs.rsp;
-       p = do_fork(clone_flags & ~CLONE_IDLETASK, newsp, &regs, 0, user_tid);
+       p = do_fork(clone_flags & ~CLONE_IDLETASK, newsp, &regs, 0, 
+                   parent_tid, child_tid);
        return IS_ERR(p) ? PTR_ERR(p) : p->pid;
 }
 
@@ -2190,10 +1939,10 @@ asmlinkage int sys32_clone(unsigned int clone_flags, unsigned int newsp, struct
  * do not have enough call-clobbered registers to hold all
  * the information you need.
  */
-asmlinkage int sys32_vfork(struct pt_regs regs)
+asmlinkage long sys32_vfork(struct pt_regs regs)
 {
        struct task_struct *p;
-       p = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.rsp, &regs, 0, NULL);
+       p = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.rsp, &regs, 0, NULL, NULL);
        return IS_ERR(p) ? PTR_ERR(p) : p->pid;
 }
 
@@ -2203,14 +1952,14 @@ asmlinkage int sys32_vfork(struct pt_regs regs)
 
 extern off_t sys_lseek (unsigned int fd, off_t offset, unsigned int origin);
 
-int sys32_lseek (unsigned int fd, int offset, unsigned int whence)
+long sys32_lseek (unsigned int fd, int offset, unsigned int whence)
 {
        return sys_lseek(fd, offset, whence);
 }
 
 extern int sys_kill(pid_t pid, int sig); 
 
-int sys32_kill(int pid, int sig)
+long sys32_kill(int pid, int sig)
 {
        return sys_kill(pid, sig);
 }
@@ -2235,27 +1984,27 @@ struct nfsctl_client32 {
 struct nfsctl_export32 {
        s8                      ex32_client[NFSCLNT_IDMAX+1];
        s8                      ex32_path[NFS_MAXPATHLEN+1];
-       __kernel_dev_t32        ex32_dev;
-       __kernel_ino_t32        ex32_ino;
+       compat_dev_t    ex32_dev;
+       compat_ino_t    ex32_ino;
        s32                     ex32_flags;
-       __kernel_uid_t32        ex32_anon_uid;
-       __kernel_gid_t32        ex32_anon_gid;
+       compat_pid_t    ex32_anon_uid;
+       compat_gid_t    ex32_anon_gid;
 };
 
 struct nfsctl_uidmap32 {
        u32                     ug32_ident;   /* char * */
-       __kernel_uid_t32        ug32_uidbase;
+       compat_pid_t    ug32_uidbase;
        s32                     ug32_uidlen;
        u32                     ug32_udimap;  /* uid_t * */
-       __kernel_uid_t32        ug32_gidbase;
+       compat_pid_t    ug32_gidbase;
        s32                     ug32_gidlen;
        u32                     ug32_gdimap;  /* gid_t * */
 };
 
 struct nfsctl_fhparm32 {
        struct sockaddr         gf32_addr;
-       __kernel_dev_t32        gf32_dev;
-       __kernel_ino_t32        gf32_ino;
+       compat_dev_t    gf32_dev;
+       compat_ino_t    gf32_ino;
        s32                     gf32_version;
 };
 
@@ -2384,7 +2133,7 @@ static int nfs_uud32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
                return -ENOMEM;
        for(i = 0; i < karg->ca_umap.ug_uidlen; i++)
                err |= __get_user(karg->ca_umap.ug_udimap[i],
-                             &(((__kernel_uid_t32 *)A(uaddr))[i]));
+                             &(((compat_pid_t *)A(uaddr))[i]));
        err |= __get_user(karg->ca_umap.ug_gidbase,
                      &arg32->ca32_umap.ug32_gidbase);
        err |= __get_user(karg->ca_umap.ug_uidlen,
@@ -2398,7 +2147,7 @@ static int nfs_uud32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
                return -ENOMEM;
        for(i = 0; i < karg->ca_umap.ug_gidlen; i++)
                err |= __get_user(karg->ca_umap.ug_gdimap[i],
-                             &(((__kernel_gid_t32 *)A(uaddr))[i]));
+                             &(((compat_gid_t *)A(uaddr))[i]));
 
        return err;
 }
@@ -2460,7 +2209,7 @@ static int nfs_getfh32_res_trans(union nfsctl_res *kres, union nfsctl_res32 *res
        return copy_to_user(res32, kres, sizeof(*res32));
 }
 
-int asmlinkage sys32_nfsservctl(int cmd, struct nfsctl_arg32 *arg32, union nfsctl_res32 *res32)
+long asmlinkage sys32_nfsservctl(int cmd, struct nfsctl_arg32 *arg32, union nfsctl_res32 *res32)
 {
        struct nfsctl_arg *karg = NULL;
        union nfsctl_res *kres = NULL;
@@ -2541,13 +2290,13 @@ done:
 }
 #else /* !NFSD */
 extern asmlinkage long sys_ni_syscall(void);
-int asmlinkage sys32_nfsservctl(int cmd, void *notused, void *notused2)
+long asmlinkage sys32_nfsservctl(int cmd, void *notused, void *notused2)
 {
        return sys_ni_syscall();
 }
 #endif
 
-int sys32_module_warning(void)
+long sys32_module_warning(void)
 { 
        static long warn_time = -(60*HZ); 
        if (time_before(warn_time + 60*HZ,jiffies) && strcmp(current->comm,"klogd")) { 
@@ -2562,7 +2311,7 @@ int sys_sched_getaffinity(pid_t pid, unsigned int len, unsigned long *new_mask_p
 int sys_sched_setaffinity(pid_t pid, unsigned int len, unsigned long *new_mask_ptr); 
 
 /* only works on LE */
-int sys32_sched_setaffinity(pid_t pid, unsigned int len,
+long sys32_sched_setaffinity(pid_t pid, unsigned int len,
                            unsigned int *new_mask_ptr)
 {
        mm_segment_t oldfs = get_fs(); 
@@ -2577,7 +2326,7 @@ int sys32_sched_setaffinity(pid_t pid, unsigned int len,
 }
 
 /* only works on LE */ 
-int sys32_sched_getaffinity(pid_t pid, unsigned int len,
+long sys32_sched_getaffinity(pid_t pid, unsigned int len,
                            unsigned int *new_mask_ptr)
 {
        mm_segment_t oldfs = get_fs(); 
@@ -2587,11 +2336,38 @@ int sys32_sched_getaffinity(pid_t pid, unsigned int len,
        set_fs(KERNEL_DS); 
        err = sys_sched_getaffinity(pid,sizeof(mask),&mask);    
        set_fs(oldfs); 
-       if (!err
+       if (err > 0
                err = put_user((u32)mask, new_mask_ptr); 
        return err;
 }
 
+extern int sys_futex(unsigned long uaddr, int op, int val, struct timespec *t); 
+
+asmlinkage long
+sys32_futex(unsigned long uaddr, int op, int val, struct compat_timespec *utime32)
+{
+       struct timespec t;
+       mm_segment_t oldfs = get_fs(); 
+       int err;
+
+       if (utime32) {
+               if (verify_area(VERIFY_READ, utime32, sizeof(*utime32)))
+                       return -EFAULT;
+
+               if (__get_user(t.tv_sec, &utime32->tv_sec) ||
+                   __get_user(t.tv_nsec, &utime32->tv_nsec))
+                       return -EFAULT;
+               
+       }
+
+       /* the set_fs is safe because futex doesn't use the seg limit 
+          for valid page checking of uaddr. */ 
+       set_fs(KERNEL_DS); 
+       err = sys_futex(uaddr, op, val, &t);
+       set_fs(oldfs); 
+       return err; 
+}
+
 extern long sys_io_setup(unsigned nr_reqs, aio_context_t *ctx);
 
 long sys32_io_setup(unsigned nr_reqs, u32 *ctx32p)
@@ -2608,8 +2384,53 @@ long sys32_io_setup(unsigned nr_reqs, u32 *ctx32p)
        return ret;
 } 
 
+extern asmlinkage long sys_io_submit(aio_context_t ctx_id, long nr,
+                                    struct iocb **iocbpp);
+
+long sys32_io_submit(aio_context_t ctx_id, unsigned long nr,
+                  u32 *iocbpp)
+{
+       mm_segment_t oldfs = get_fs(); 
+       int k, err = 0;
+       struct iocb **iocb64; 
+       if (nr > 128) 
+               return -EINVAL; 
+       iocb64 = kmalloc(sizeof(struct iocb *) * nr, GFP_KERNEL);
+       if (!iocb64)
+               return -ENOMEM;
+       for (k = 0; k < nr && !err; k++) { 
+               u64 val1, val2;
+               u32 iocb32;
+               struct iocb *iocb;      
+               err = get_user(iocb32, (u32 *)(u64)iocbpp[k]); 
+               iocb64[k] = iocb = (void *)(u64)iocb32; 
+               
+               if (get_user(val1, &iocb->aio_buf) ||
+                   get_user(val2, &iocb->aio_nbytes)) 
+                       err = -EFAULT; 
+               else if (!val1) /* should check cmd */ 
+                       ;
+               else if (verify_area(VERIFY_WRITE, (void*)val1, val2))
+                       err = -EFAULT; 
+
+               /* paranoia check - remove it when you are sure they
+                  are not pointers */
+               if (get_user(val1, &iocb->aio_reserved2) || val1 ||
+                   get_user(val2, &iocb->aio_reserved2) || val2)
+                       err = -EFAULT;                             
+       } 
+       if (!err) {
+               set_fs(KERNEL_DS);
+               err = sys_io_submit(ctx_id, nr, iocb64);
+               set_fs(oldfs); 
+       } 
+       kfree(iocb64);
+       return err;             
+}
+
+/* XXX aio getevents */
 
-int sys32_vm86_warning(void)
+long sys32_vm86_warning(void)
 { 
        static long warn_time = -(60*HZ); 
        if (time_before(warn_time + 60*HZ,jiffies)) { 
index 6fa8f5a32780f9879017a54ecf087d8d035036e0..e5b573273dd843f6fe3fa482154c57e9cf239796 100644 (file)
@@ -4,23 +4,30 @@
 
 EXTRA_TARGETS  := head.o head64.o init_task.o
 
-export-objs     := mtrr.o x8664_ksyms.o pci-gart.o pci-dma.o
+export-objs     := x8664_ksyms.o pci-gart.o pci-dma.o
 
 obj-y  := process.o semaphore.o signal.o entry.o traps.o irq.o \
                ptrace.o i8259.o ioport.o ldt.o setup.o time.o sys_x86_64.o \
                pci-dma.o x8664_ksyms.o i387.o syscall.o vsyscall.o \
                setup64.o bluesmoke.o bootflag.o e820.o reboot.o profile.o
 
-obj-$(CONFIG_MTRR)     += mtrr.o
+obj-$(CONFIG_MTRR)     += mtrr/
 obj-$(CONFIG_X86_MSR)  += msr.o
 obj-$(CONFIG_X86_CPUID)        += cpuid.o
 obj-$(CONFIG_SMP)      += smp.o smpboot.o trampoline.o
 obj-$(CONFIG_X86_LOCAL_APIC)   += apic.o  nmi.o
 obj-$(CONFIG_X86_IO_APIC)      += io_apic.o mpparse.o
+obj-$(CONFIG_SOFTWARE_SUSPEND) += suspend.o suspend_asm.o
 obj-$(CONFIG_ACPI)             += acpi.o
 #obj-$(CONFIG_ACPI_SLEEP)       += acpi_wakeup.o
 obj-$(CONFIG_EARLY_PRINTK)    += early_printk.o
 obj-$(CONFIG_GART_IOMMU) += pci-gart.o aperture.o
 obj-$(CONFIG_DUMMY_IOMMU) += pci-nommu.o
+obj-$(CONFIG_MODULES) += module.o
+
+$(obj)/bootflag.c: 
+       @ln -sf ../../i386/kernel/bootflag.c $(obj)/bootflag.c
+
+clean-files += bootflag.c
 
 EXTRA_AFLAGS := -traditional
index 4c4f93dc4c0a5808bdca26afcc78785c5ce27d85..fd366de53ff2fd32879cfa7b54d52905890517b7 100644 (file)
@@ -443,8 +443,6 @@ acpi_boot_init (
 
 #error not ported to x86-64 yet
 
-#define DEBUG
-
 #ifdef DEBUG
 #include <linux/serial.h>
 #endif
diff --git a/arch/x86_64/kernel/bootflag.c b/arch/x86_64/kernel/bootflag.c
deleted file mode 100644 (file)
index 23c0e1e..0000000
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- *     Implement 'Simple Boot Flag Specification 1.0'
- *
- */
-
-
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <asm/io.h>
-
-#include <linux/mc146818rtc.h>
-
-
-#define SBF_RESERVED (0x78)
-#define SBF_PNPOS    (1<<0)
-#define SBF_BOOTING  (1<<1)
-#define SBF_DIAG     (1<<2)
-#define SBF_PARITY   (1<<7)
-
-
-struct sbf_boot
-{
-       u8 sbf_signature[4];
-       u32 sbf_len;
-       u8 sbf_revision __attribute((packed));
-       u8 sbf_csum __attribute((packed));
-       u8 sbf_oemid[6] __attribute((packed));
-       u8 sbf_oemtable[8] __attribute((packed));
-       u8 sbf_revdata[4] __attribute((packed));
-       u8 sbf_creator[4] __attribute((packed));
-       u8 sbf_crearev[4] __attribute((packed));
-       u8 sbf_cmos __attribute((packed));
-       u8 sbf_spare[3] __attribute((packed));
-};
-
-
-static int sbf_port __initdata = -1;
-
-static int __init sbf_struct_valid(unsigned long tptr)
-{
-       u8 *ap;
-       u8 v;
-       unsigned int i;
-       struct sbf_boot sb;
-       
-       memcpy_fromio(&sb, (void *)tptr, sizeof(sb));
-
-       if(sb.sbf_len != 40 && sb.sbf_len != 39)
-               // 39 on IBM ThinkPad A21m, BIOS version 1.02b (KXET24WW; 2000-12-19).
-               return 0;
-
-       ap = (u8 *)&sb;
-       v= 0;
-       
-       for(i=0;i<sb.sbf_len;i++)
-               v+=*ap++;
-               
-       if(v)
-               return 0;
-
-       if(memcmp(sb.sbf_signature, "BOOT", 4))
-               return 0;
-
-       if (sb.sbf_len == 39)
-               printk (KERN_WARNING "SBF: ACPI BOOT descriptor is wrong length (%d)\n",
-                       sb.sbf_len);
-
-       sbf_port = sb.sbf_cmos; /* Save CMOS port */
-       return 1;
-}
-
-static int __init parity(u8 v)
-{
-       int x = 0;
-       int i;
-       
-       for(i=0;i<8;i++)
-       {
-               x^=(v&1);
-               v>>=1;
-       }
-       return x;
-}
-
-static void __init sbf_write(u8 v)
-{
-       unsigned long flags;
-       if(sbf_port != -1)
-       {
-               v &= ~SBF_PARITY;
-               if(!parity(v))
-                       v|=SBF_PARITY;
-
-               printk(KERN_INFO "SBF: Setting boot flags 0x%x\n",v);
-
-               spin_lock_irqsave(&rtc_lock, flags);
-               CMOS_WRITE(v, sbf_port);
-               spin_unlock_irqrestore(&rtc_lock, flags);
-       }
-}
-
-static u8 __init sbf_read(void)
-{
-       u8 v;
-       unsigned long flags;
-       if(sbf_port == -1)
-               return 0;
-       spin_lock_irqsave(&rtc_lock, flags);
-       v = CMOS_READ(sbf_port);
-       spin_unlock_irqrestore(&rtc_lock, flags);
-       return v;
-}
-
-static int __init sbf_value_valid(u8 v)
-{
-       if(v&SBF_RESERVED)              /* Reserved bits */
-               return 0;
-       if(!parity(v))
-               return 0;
-       return 1;
-}
-
-
-static void __init sbf_bootup(void)
-{
-       u8 v;
-       if(sbf_port == -1)
-               return;
-       v = sbf_read();
-       if(!sbf_value_valid(v))
-               printk(KERN_WARNING "SBF: Simple boot flag value 0x%x read from CMOS RAM was invalid\n",v);
-       v &= ~SBF_RESERVED;
-       v &= ~SBF_BOOTING;
-       v &= ~SBF_DIAG;
-#if defined(CONFIG_ISAPNP)
-       v |= SBF_PNPOS;
-#endif
-       sbf_write(v);
-}
-
-static int __init sbf_init(void)
-{
-       unsigned int i;
-       void *rsdt;
-       u32 rsdtlen = 0;
-       u32 rsdtbase = 0;
-       u8 sum = 0;
-       int n;
-       
-       u8 *p;
-       
-       for(i=0xE0000; i <= 0xFFFE0; i+=16)
-       {
-               p = phys_to_virt(i);
-               
-               if(memcmp(p, "RSD PTR ", 8))
-                       continue;
-               
-               sum = 0;
-               for(n=0; n<20; n++)
-                       sum+=p[n];
-                       
-               if(sum != 0)
-                       continue;
-                       
-               /* So it says RSD PTR and it checksums... */
-
-               /*
-                *      Process the RDSP pointer
-                */
-        
-               rsdtbase = *(u32 *)(p+16);
-               
-               /*
-                *      RSDT length is ACPI 2 only, for ACPI 1 we must map
-                *      and remap.
-                */
-                
-               if(p[15]>1)
-                       rsdtlen = *(u32 *)(p+20);
-               else
-                       rsdtlen = 36;
-
-               if(rsdtlen < 36 || rsdtlen > 1024)
-                       continue;
-               break;
-       }
-       if(i>0xFFFE0)
-               return 0;
-               
-               
-       rsdt = ioremap(rsdtbase, rsdtlen);
-       if(rsdt == 0)
-               return 0;
-               
-       i = readl(rsdt + 4);
-       
-       /*
-        *      Remap if needed
-        */
-        
-       if(i > rsdtlen)
-       {
-               rsdtlen = i;
-               iounmap(rsdt);
-               rsdt = ioremap(rsdtbase, rsdtlen);
-               if(rsdt == 0)
-                       return 0;
-       }
-       
-       for(n = 0; n < i; n++)
-               sum += readb(rsdt + n);
-               
-       if(sum)
-       {
-               iounmap(rsdt);
-               return 0;
-       }
-       
-       /* Ok the RSDT checksums too */
-       
-       for(n = 36; n+3 < i; n += 4)
-       {
-               unsigned long rp = readl(rsdt+n);
-               int len = 4096;
-
-               if(rp > 0xFFFFFFFFUL - len)
-                       len = 0xFFFFFFFFUL - rp;
-                       
-               /* Too close to the end!! */
-               if(len < 20)
-                       continue;
-               rp = (unsigned long)ioremap(rp, 4096);
-               if(rp == 0)
-                       continue;
-               
-               if(sbf_struct_valid(rp))
-               {
-                       /* Found the BOOT table and processed it */
-                       printk(KERN_INFO "SBF: Simple Boot Flag extension found and enabled.\n");
-               }
-               iounmap((void *)rp);
-       }
-       iounmap(rsdt);
-       sbf_bootup();
-       return 0;
-}
-
-module_init(sbf_init);
index d25526072ee230b0c2d61d2587f66d596ffce442..0d7939f3f8c69b3f43be4619391868d7aea07349 100644 (file)
@@ -605,6 +605,9 @@ ENTRY(kernel_thread)
        movq $-1, %rsi
        movq %rsp, %rdx
 
+       xorl %r8d,%r8d
+       xorl %r9d,%r9d
+       
        # clone now
        call do_fork
 
index 0e36834e42c7e9be4af3c9354f7d03956140f481..201daae8c1109715b8acc67e93d1fe57d857e86a 100644 (file)
@@ -79,13 +79,11 @@ startup_32:
        /* Enable System Call */
        btsl    $_EFER_SCE, %eax
 
-#if 0
        /* No Execute supported? */     
        btl     $20,%edi
        jnc     1f
        btsl    $_EFER_NX, %eax
 1:     
-#endif
                                
        /* Make changes effective */
        wrmsr
index 6a50f4dc55c715132fdd50e1630268cfc73b5d1b..f0eac767249f37909760682442070d0396210922 100644 (file)
@@ -127,3 +127,24 @@ int dump_fpu( struct pt_regs *regs, struct user_i387_struct *fpu )
        memcpy(fpu, &tsk->thread.i387.fxsave, sizeof(struct user_i387_struct)); 
        return 1; 
 }
+
+int dump_task_fpu(struct task_struct *tsk, struct user_i387_struct *fpu)
+{
+       int fpvalid = tsk->used_math;
+
+       if (fpvalid) {
+               if (tsk == current)
+                       unlazy_fpu(tsk);
+               memcpy(fpu, &tsk->thread.i387.fxsave, sizeof(struct user_i387_struct));         
+}
+       return fpvalid;
+}
+
+#ifdef CONFIG_SMP
+void dump_smp_unlazy_fpu(void)
+{
+       unlazy_fpu(current);
+       return;
+}
+#endif
+
index 4e321dae12cc2023fd26f6a9f8023a5715885e08..61eb01ca871655204d5f866bb10bc75b9778a867 100644 (file)
@@ -404,6 +404,45 @@ void reschedule_interrupt(void);
 void call_function_interrupt(void);
 void invalidate_interrupt(void);
 
+static void setup_timer(void)
+{
+       outb_p(0x34,0x43);              /* binary, mode 2, LSB/MSB, ch 0 */
+       udelay(10);
+       outb_p(LATCH & 0xff , 0x40);    /* LSB */
+       udelay(10);
+       outb(LATCH >> 8 , 0x40);        /* MSB */
+}
+
+static int timer_resume(struct device *dev, u32 level)
+{
+       if (level == RESUME_POWER_ON)
+               setup_timer();
+       return 0;
+}
+
+static struct device_driver timer_driver = {
+       .name           = "timer",
+       .bus            = &system_bus_type,
+       .resume         = timer_resume,
+};
+
+static struct sys_device device_timer = {
+       .name           = "timer",
+       .id             = 0,
+       .dev            = {
+               .name   = "timer",
+               .driver = &timer_driver,
+       },
+};
+
+static int __init init_timer_devicefs(void)
+{
+       driver_register(&timer_driver);
+       return sys_device_register(&device_timer);
+}
+
+device_initcall(init_timer_devicefs);
+
 void __init init_IRQ(void)
 {
        int i;
@@ -454,9 +493,7 @@ void __init init_IRQ(void)
         * Set the clock to HZ Hz, we already have a valid
         * vector now:
         */
-       outb_p(0x34,0x43);              /* binary, mode 2, LSB/MSB, ch 0 */
-       outb_p(LATCH & 0xff , 0x40);    /* LSB */
-       outb(LATCH >> 8 , 0x40);        /* MSB */
+       setup_timer();
 
        setup_irq(2, &irq2);
 }
index e03674c8fceb8a159b0407d08ddb0129e7a4c5ac..65763b86726f737def4d5c7ae880e9ed46ef5160 100644 (file)
@@ -35,6 +35,8 @@
 #include <asm/smp.h>
 #include <asm/desc.h>
 
+int sis_apic_bug; /* not actually supported, dummy for compile */
+
 #undef APIC_LOCKUP_DEBUG
 
 #define APIC_LOCKUP_DEBUG
index cb1193c82dccab9bab04a6d6c598dd5ef9a0f347..e4d13043c168603a3b01e3ec6227aeeab3b075c6 100644 (file)
@@ -108,13 +108,12 @@ int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
 }
 
 /*
- * No need to lock the MM as we are the last user
+ * 
+ * Don't touch the LDT register - we're already in the next thread.
  */
-void release_segments(struct mm_struct *mm)
+void destroy_context(struct mm_struct *mm)
 {
        if (mm->context.size) {
-               if (mm == current->active_mm)
-                       clear_LDT();
                if (mm->context.size*LDT_ENTRY_SIZE > PAGE_SIZE)
                        vfree(mm->context.ldt);
                else
@@ -188,11 +187,6 @@ static int write_ldt(void * ptr, unsigned long bytecount, int oldmode)
                        goto out;
        }
 
-       me->thread.fsindex = 0; 
-       me->thread.gsindex = 0; 
-       me->thread.gs = 0; 
-       me->thread.fs = 0; 
-
        down(&mm->context.sem);
        if (ldt_info.entry_number >= mm->context.size) {
                error = alloc_ldt(&current->mm->context, ldt_info.entry_number+1, 1);
diff --git a/arch/x86_64/kernel/module.c b/arch/x86_64/kernel/module.c
new file mode 100644 (file)
index 0000000..bd2595b
--- /dev/null
@@ -0,0 +1,134 @@
+/*  Kernel module help for x86-64
+    Copyright (C) 2001 Rusty Russell.
+    Copyright (C) 2002 Andi Kleen, SuSE Labs.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+#include <linux/moduleloader.h>
+#include <linux/elf.h>
+#include <linux/vmalloc.h>
+#include <linux/fs.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+
+#define DEBUGP(fmt...) 
+/* We don't need anything special. */
+long module_core_size(const Elf64_Ehdr *hdr,
+                     const Elf64_Shdr *sechdrs,
+                     const char *secstrings,
+                     struct module *module)
+{
+       return module->core_size;
+}
+
+long module_init_size(const Elf64_Ehdr *hdr,
+                     const Elf64_Shdr *sechdrs,
+                     const char *secstrings,
+                     struct module *module)
+{
+       return module->init_size;
+}
+
+int apply_relocate_add(Elf64_Shdr *sechdrs,
+                  const char *strtab,
+                  unsigned int symindex,
+                  unsigned int relsec,
+                  struct module *me)
+{
+       unsigned int i;
+       Elf64_Rela *rel = (void *)sechdrs[relsec].sh_offset;
+       Elf64_Sym *sym;
+       void *loc;
+       u64 val; 
+
+       DEBUGP("Applying relocate section %u to %u\n", relsec,
+              sechdrs[relsec].sh_info);
+       for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
+               /* This is where to make the change */
+               loc = (void *)sechdrs[sechdrs[relsec].sh_info].sh_offset
+                       + rel[i].r_offset;
+
+               /* This is the symbol it is referring to */
+               sym = (Elf64_Sym *)sechdrs[symindex].sh_offset
+                       + ELF64_R_SYM(rel[i].r_info);
+               if (!sym->st_value) {
+                       printk(KERN_WARNING "%s: Unknown symbol %s\n",
+                              me->name, strtab + sym->st_name);
+                       return -ENOENT;
+               }
+
+               DEBUGP("type %d st_value %Lx r_addend %Lx loc %Lx\n",
+                      (int)ELF64_R_TYPE(rel[i].r_info), 
+                      sym->st_value, rel[i].r_addend, (u64)loc);
+
+               val = sym->st_value + rel[i].r_addend; 
+
+               switch (ELF64_R_TYPE(rel[i].r_info)) {
+               case R_X86_64_NONE:
+                       break;
+               case R_X86_64_64:
+                       *(u64 *)loc = val;
+                       break;
+               case R_X86_64_32:
+                       *(u32 *)loc = val;
+                       if (val != *(u32 *)loc)
+                               goto overflow;
+                       break;
+               case R_X86_64_32S:
+                       *(s32 *)loc = val;
+                       if ((s64)val != *(s32 *)loc)
+                               goto overflow;
+                       break;
+               case R_X86_64_PC32: 
+                       val -= (u64)loc;
+                       *(u32 *)loc = val;
+#if 0
+                       if ((s64)val != *(s32 *)loc)
+                               goto overflow; 
+#endif
+                       break;
+               default:
+                       printk(KERN_ERR "module %s: Unknown rela relocation: %Lu\n",
+                              me->name, ELF64_R_TYPE(rel[i].r_info));
+                       return -ENOEXEC;
+               }
+       }
+       return 0;
+
+overflow:
+       printk(KERN_ERR "overflow in relocation type %d val %Lx\n", 
+              (int)ELF64_R_TYPE(rel[i].r_info), val);
+       printk(KERN_ERR "`%s' likely not compiled with -mcmodel=kernel\n",
+              me->name);
+       return -ENOEXEC;
+}
+
+int apply_relocate(Elf_Shdr *sechdrs,
+                  const char *strtab,
+                  unsigned int symindex,
+                  unsigned int relsec,
+                  struct module *me)
+{
+       printk("non add relocation not supported\n");
+       return -ENOSYS;
+} 
+
+int module_finalize(const Elf_Ehdr *hdr,
+                   const Elf_Shdr *sechdrs,
+                   struct module *me)
+{
+       return 0;
+}
diff --git a/arch/x86_64/kernel/mtrr.c b/arch/x86_64/kernel/mtrr.c
deleted file mode 100644 (file)
index 850c9fb..0000000
+++ /dev/null
@@ -1,1303 +0,0 @@
-/*  x86-64 MTRR (Memory Type Range Register) driver.
-       Based largely upon arch/i386/kernel/mtrr.c
-
-       Copyright (C) 1997-2000  Richard Gooch
-       Copyright (C) 2002 Dave Jones.
-
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Library General Public
-    License as published by the Free Software Foundation; either
-    version 2 of the License, or (at your option) any later version.
-
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Library General Public License for more details.
-
-    You should have received a copy of the GNU Library General Public
-    License along with this library; if not, write to the Free
-    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-       (For earlier history, see arch/i386/kernel/mtrr.c)
-       v2.00   September 2001  Dave Jones <davej@suse.de>
-         Initial rewrite for x86-64.
-         Removal of non-Intel style MTRR code.
-       v2.01  June 2002  Dave Jones <davej@suse.de>
-         Removal of redundant abstraction layer.
-         64-bit fixes.
-       v2.02  July 2002  Dave Jones <davej@suse.de>
-         Fix gentry inconsistencies between kernel/userspace.
-         More casts to clean up warnings.
-       Andi Kleen - rework initialization.
-*/
-
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/tty.h>
-#include <linux/timer.h>
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/wait.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/ioport.h>
-#include <linux/delay.h>
-#include <linux/fs.h>
-#include <linux/ctype.h>
-#include <linux/proc_fs.h>
-#include <linux/devfs_fs_kernel.h>
-#include <linux/mm.h>
-#include <linux/module.h>
-#define MTRR_NEED_STRINGS
-#include <asm/mtrr.h>
-#include <linux/init.h>
-#include <linux/smp.h>
-#include <linux/smp_lock.h>
-#include <linux/agp_backend.h>
-
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/processor.h>
-#include <asm/system.h>
-#include <asm/pgtable.h>
-#include <asm/segment.h>
-#include <asm/bitops.h>
-#include <asm/atomic.h>
-#include <asm/msr.h>
-
-#include <asm/hardirq.h>
-#include <linux/irq.h>
-
-#define MTRR_VERSION "2.02 (20020716)"
-
-#define TRUE  1
-#define FALSE 0
-
-#define MSR_MTRRphysBase(reg) (0x200 + 2 * (reg))
-#define MSR_MTRRphysMask(reg) (0x200 + 2 * (reg) + 1)
-
-#define NUM_FIXED_RANGES 88
-
-#define MTRR_CHANGE_MASK_FIXED     0x01
-#define MTRR_CHANGE_MASK_VARIABLE  0x02
-#define MTRR_CHANGE_MASK_DEFTYPE   0x04
-
-typedef u8 mtrr_type;
-
-#define LINE_SIZE 80
-
-#ifdef CONFIG_SMP
-#define set_mtrr(reg,base,size,type) set_mtrr_smp (reg, base, size, type)
-#else
-#define set_mtrr(reg,base,size,type) set_mtrr_up (reg, base, size, type, TRUE)
-#endif
-
-#if defined(CONFIG_PROC_FS) || defined(CONFIG_DEVFS_FS)
-#define USERSPACE_INTERFACE
-#endif
-
-#ifdef USERSPACE_INTERFACE
-static char *ascii_buffer;
-static unsigned int ascii_buf_bytes;
-static void compute_ascii (void);
-#else
-#define compute_ascii() while (0)
-#endif
-
-static unsigned int *usage_table;
-static DECLARE_MUTEX (mtrr_lock);
-
-struct set_mtrr_context {
-       u32 deftype_lo;
-       u32 deftype_hi;
-       unsigned long flags;
-       u64 cr4val;
-};
-
-
-/*  Put the processor into a state where MTRRs can be safely set  */
-static void set_mtrr_prepare (struct set_mtrr_context *ctxt)
-{
-       u64 cr0;
-
-       /* Disable interrupts locally */
-       local_irq_save(ctxt->flags);
-       local_irq_disable();
-
-       /* Save value of CR4 and clear Page Global Enable (bit 7)  */
-       if (cpu_has_pge) { 
-        ctxt->cr4val = read_cr4();
-               write_cr4(ctxt->cr4val & ~(1UL << 7));
-       }
-
-       /* Disable and flush caches. Note that wbinvd flushes the TLBs as
-          a side-effect */
-       cr0 = read_cr0() | 0x40000000;
-       wbinvd();
-       write_cr0(cr0);
-       wbinvd();
-
-       /* Disable MTRRs, and set the default type to uncached */
-       rdmsr(MSR_MTRRdefType, ctxt->deftype_lo, ctxt->deftype_hi);
-       wrmsr(MSR_MTRRdefType, ctxt->deftype_lo & 0xf300UL, ctxt->deftype_hi);
-}
-
-
-/* Restore the processor after a set_mtrr_prepare */
-static void set_mtrr_done (struct set_mtrr_context *ctxt)
-{
-       /* Flush caches and TLBs */
-       wbinvd();
-
-       /* Restore MTRRdefType */
-       wrmsr(MSR_MTRRdefType, ctxt->deftype_lo, ctxt->deftype_hi);
-
-       /* Enable caches */
-       write_cr0(read_cr0() & 0xbfffffff);
-
-       /* Restore value of CR4 */
-       if (cpu_has_pge)
-               write_cr4 (ctxt->cr4val);
-
-       /* Re-enable interrupts locally (if enabled previously) */
-       local_irq_restore(ctxt->flags);
-}
-
-
-/*  This function returns the number of variable MTRRs  */
-static unsigned int get_num_var_ranges (void)
-{
-       u32 config, dummy;
-
-       rdmsr (MSR_MTRRcap, config, dummy);
-       return (config & 0xff);
-}
-
-
-/*  Returns non-zero if we have the write-combining memory type  */
-static int have_wrcomb (void)
-{
-       u32 config, dummy;
-
-       rdmsr (MSR_MTRRcap, config, dummy);
-       return (config & (1 << 10));
-}
-
-
-static u64 size_or_mask, size_and_mask;
-
-static void get_mtrr (unsigned int reg, u64 *base, u32 *size, mtrr_type * type)
-{
-       u32 mask_lo, mask_hi, base_lo, base_hi;
-       u64 newsize;
-
-       rdmsr (MSR_MTRRphysMask(reg), mask_lo, mask_hi);
-       if ((mask_lo & 0x800) == 0) {
-               /*  Invalid (i.e. free) range  */
-               *base = 0;
-               *size = 0;
-               *type = 0;
-               return;
-       }
-
-       rdmsr (MSR_MTRRphysBase(reg), base_lo, base_hi);
-
-       /* Work out the shifted address mask. */
-       newsize = (u64) mask_hi << 32 | (mask_lo & ~0x800);
-       newsize = ~newsize+1;
-       *size = (u32) newsize >> PAGE_SHIFT;
-       *base = base_hi << (32 - PAGE_SHIFT) | base_lo >> PAGE_SHIFT;
-       *type = base_lo & 0xff;
-}
-
-
-
-/*
- * Set variable MTRR register on the local CPU.
- *  <reg> The register to set.
- *  <base> The base address of the region.
- *  <size> The size of the region. If this is 0 the region is disabled.
- *  <type> The type of the region.
- *  <do_safe> If TRUE, do the change safely. If FALSE, safety measures should
- *  be done externally.
- */
-static void set_mtrr_up (unsigned int reg, u64 base,
-                  u32 size, mtrr_type type, int do_safe)
-{
-       struct set_mtrr_context ctxt;
-       u64 base64;
-       u64 size64;
-
-       if (do_safe)
-               set_mtrr_prepare (&ctxt);
-
-       if (size == 0) {
-               /* The invalid bit is kept in the mask, so we simply clear the
-                  relevant mask register to disable a range. */
-               wrmsr (MSR_MTRRphysMask(reg), 0, 0);
-       } else {
-               base64 = (base << PAGE_SHIFT) & size_and_mask;
-               wrmsr (MSR_MTRRphysBase(reg), base64 | type, base64 >> 32);
-
-               size64 = ~((size << PAGE_SHIFT) - 1);
-               size64 = size64 & size_and_mask;
-               wrmsr (MSR_MTRRphysMask(reg), (u32) (size64 | 0x800), (u32) (size64 >> 32));
-       }
-       if (do_safe)
-               set_mtrr_done (&ctxt);
-}
-
-
-#ifdef CONFIG_SMP
-
-struct mtrr_var_range {
-       u32 base_lo;
-       u32 base_hi;
-       u32 mask_lo;
-       u32 mask_hi;
-};
-
-/*  Get the MSR pair relating to a var range  */
-static void __init get_mtrr_var_range (unsigned int index,
-               struct mtrr_var_range *vr)
-{
-       rdmsr (MSR_MTRRphysBase(index), vr->base_lo, vr->base_hi);
-       rdmsr (MSR_MTRRphysMask(index), vr->mask_lo, vr->mask_hi);
-}
-
-
-/*  Set the MSR pair relating to a var range. Returns TRUE if
-    changes are made  */
-static int __init set_mtrr_var_range_testing (unsigned int index,
-               struct mtrr_var_range *vr)
-{
-       u32 lo, hi;
-       int changed = FALSE;
-
-       rdmsr (MSR_MTRRphysBase(index), lo, hi);
-       if ((vr->base_lo & 0xfffff0ff) != (lo & 0xfffff0ff) ||
-               (vr->base_hi & 0x000fffff) != (hi & 0x000fffff)) {
-               wrmsr (MSR_MTRRphysBase(index), vr->base_lo, vr->base_hi);
-               changed = TRUE;
-       }
-
-       rdmsr (MSR_MTRRphysMask(index), lo, hi);
-       if ((vr->mask_lo & 0xfffff800) != (lo & 0xfffff800) ||
-               (vr->mask_hi & 0x000fffff) != (hi & 0x000fffff)) {
-               wrmsr (MSR_MTRRphysMask(index), vr->mask_lo, vr->mask_hi);
-               changed = TRUE;
-       }
-       return changed;
-}
-
-
-static void __init get_fixed_ranges (mtrr_type * frs)
-{
-       u32 *p = (u32 *) frs;
-       int i;
-
-       rdmsr (MSR_MTRRfix64K_00000, p[0], p[1]);
-
-       for (i = 0; i < 2; i++)
-               rdmsr (MSR_MTRRfix16K_80000 + i, p[2 + i * 2], p[3 + i * 2]);
-       for (i = 0; i < 8; i++)
-               rdmsr (MSR_MTRRfix4K_C0000 + i, p[6 + i * 2], p[7 + i * 2]);
-}
-
-
-static int __init set_fixed_ranges_testing (mtrr_type * frs)
-{
-       u32 *p = (u32 *) frs;
-       int changed = FALSE;
-       int i;
-       u32 lo, hi;
-
-       printk (KERN_INFO "mtrr: rdmsr 64K_00000\n");
-       rdmsr (MSR_MTRRfix64K_00000, lo, hi);
-       if (p[0] != lo || p[1] != hi) {
-               printk (KERN_INFO "mtrr: Writing %x:%x to 64K MSR. lohi were %x:%x\n", p[0], p[1], lo, hi);
-               wrmsr (MSR_MTRRfix64K_00000, p[0], p[1]);
-               changed = TRUE;
-       }
-
-       printk (KERN_INFO "mtrr: rdmsr 16K_80000\n");
-       for (i = 0; i < 2; i++) {
-               rdmsr (MSR_MTRRfix16K_80000 + i, lo, hi);
-               if (p[2 + i * 2] != lo || p[3 + i * 2] != hi) {
-                       printk (KERN_INFO "mtrr: Writing %x:%x to 16K MSR%d. lohi were %x:%x\n", p[2 + i * 2], p[3 + i * 2], i, lo, hi );
-                       wrmsr (MSR_MTRRfix16K_80000 + i, p[2 + i * 2], p[3 + i * 2]);
-                       changed = TRUE;
-               }
-       }
-
-       printk (KERN_INFO "mtrr: rdmsr 4K_C0000\n");
-       for (i = 0; i < 8; i++) {
-               rdmsr (MSR_MTRRfix4K_C0000 + i, lo, hi);
-               printk (KERN_INFO "mtrr: MTRRfix4K_C0000+%d = %x:%x\n", i, lo, hi);
-               if (p[6 + i * 2] != lo || p[7 + i * 2] != hi) {
-                       printk (KERN_INFO "mtrr: Writing %x:%x to 4K MSR%d. lohi were %x:%x\n", p[6 + i * 2], p[7 + i * 2], i, lo, hi);
-                       wrmsr (MSR_MTRRfix4K_C0000 + i, p[6 + i * 2], p[7 + i * 2]);
-                       changed = TRUE;
-               }
-       }
-       return changed;
-}
-
-
-struct mtrr_state {
-       unsigned int num_var_ranges;
-       struct mtrr_var_range *var_ranges;
-       mtrr_type fixed_ranges[NUM_FIXED_RANGES];
-       mtrr_type def_type;
-       unsigned char enabled;
-};
-
-
-/*  Grab all of the MTRR state for this CPU into *state  */
-static void __init get_mtrr_state (struct mtrr_state *state)
-{
-       unsigned int nvrs, i;
-       struct mtrr_var_range *vrs;
-       u32 lo, dummy;
-
-       nvrs = state->num_var_ranges = get_num_var_ranges();
-       vrs = state->var_ranges
-           = kmalloc (nvrs * sizeof (struct mtrr_var_range), GFP_KERNEL);
-       if (vrs == NULL)
-               nvrs = state->num_var_ranges = 0;
-
-       for (i = 0; i < nvrs; i++)
-               get_mtrr_var_range (i, &vrs[i]);
-       get_fixed_ranges (state->fixed_ranges);
-
-       rdmsr (MSR_MTRRdefType, lo, dummy);
-       state->def_type = (lo & 0xff);
-       state->enabled = (lo & 0xc00) >> 10;
-}
-
-
-/*  Free resources associated with a struct mtrr_state  */
-static void __init finalize_mtrr_state (struct mtrr_state *state)
-{
-       if (state->var_ranges)
-               kfree (state->var_ranges);
-}
-
-
-/*
- * Set the MTRR state for this CPU.
- *  <state> The MTRR state information to read.
- *  <ctxt> Some relevant CPU context.
- *  [NOTE] The CPU must already be in a safe state for MTRR changes.
- *  [RETURNS] 0 if no changes made, else a mask indication what was changed.
- */
-static u64 __init set_mtrr_state (struct mtrr_state *state,
-               struct set_mtrr_context *ctxt)
-{
-       unsigned int i;
-       u64 change_mask = 0;
-
-       for (i = 0; i < state->num_var_ranges; i++)
-               if (set_mtrr_var_range_testing (i, &state->var_ranges[i]))
-                       change_mask |= MTRR_CHANGE_MASK_VARIABLE;
-
-       if (set_fixed_ranges_testing (state->fixed_ranges))
-               change_mask |= MTRR_CHANGE_MASK_FIXED;
-       /* Set_mtrr_restore restores the old value of MTRRdefType,
-          so to set it we fiddle with the saved value  */
-       if ((ctxt->deftype_lo & 0xff) != state->def_type
-           || ((ctxt->deftype_lo & 0xc00) >> 10) != state->enabled) {
-               ctxt->deftype_lo |= (state->def_type | state->enabled << 10);
-               change_mask |= MTRR_CHANGE_MASK_DEFTYPE;
-       }
-
-       return change_mask;
-}
-
-
-static atomic_t undone_count;
-static volatile int wait_barrier_execute = FALSE;
-static volatile int wait_barrier_cache_enable = FALSE;
-
-struct set_mtrr_data {
-       u64 smp_base;
-       u32 smp_size;
-       unsigned int smp_reg;
-       mtrr_type smp_type;
-};
-
-/*
- * Synchronisation handler. Executed by "other" CPUs.
- */
-static void ipi_handler (void *info)
-{
-       struct set_mtrr_data *data = info;
-       struct set_mtrr_context ctxt;
-
-       set_mtrr_prepare (&ctxt);
-       /* Notify master that I've flushed and disabled my cache  */
-       atomic_dec (&undone_count);
-       while (wait_barrier_execute)
-               barrier ();
-
-       /* The master has cleared me to execute  */
-       set_mtrr_up (data->smp_reg, data->smp_base, data->smp_size,
-                       data->smp_type, FALSE);
-
-       /* Notify master CPU that I've executed the function  */
-       atomic_dec (&undone_count);
-
-       /* Wait for master to clear me to enable cache and return  */
-       while (wait_barrier_cache_enable)
-               barrier ();
-       set_mtrr_done (&ctxt);
-}
-
-
-static void set_mtrr_smp (unsigned int reg, u64 base, u32 size, mtrr_type type)
-{
-       struct set_mtrr_data data;
-       struct set_mtrr_context ctxt;
-
-       data.smp_reg = reg;
-       data.smp_base = base;
-       data.smp_size = size;
-       data.smp_type = type;
-       wait_barrier_execute = TRUE;
-       wait_barrier_cache_enable = TRUE;
-       atomic_set (&undone_count, num_online_cpus() - 1);
-
-       /*  Start the ball rolling on other CPUs  */
-       if (smp_call_function (ipi_handler, &data, 1, 0) != 0)
-               panic ("mtrr: timed out waiting for other CPUs\n");
-
-       /* Flush and disable the local CPU's cache */
-       set_mtrr_prepare (&ctxt);
-
-       /*  Wait for all other CPUs to flush and disable their caches  */
-       while (atomic_read (&undone_count) > 0)
-               barrier ();
-
-       /* Set up for completion wait and then release other CPUs to change MTRRs */
-       atomic_set (&undone_count, num_online_cpus() - 1);
-       wait_barrier_execute = FALSE;
-       set_mtrr_up (reg, base, size, type, FALSE);
-
-       /*  Now wait for other CPUs to complete the function  */
-       while (atomic_read (&undone_count) > 0)
-               barrier ();
-
-       /*  Now all CPUs should have finished the function. Release the barrier to
-          allow them to re-enable their caches and return from their interrupt,
-          then enable the local cache and return  */
-       wait_barrier_cache_enable = FALSE;
-       set_mtrr_done (&ctxt);
-}
-
-
-/*  Some BIOS's are fucked and don't set all MTRRs the same!  */
-static void __init mtrr_state_warn (u32 mask)
-{
-       if (!mask)
-               return;
-       if (mask & MTRR_CHANGE_MASK_FIXED)
-               printk ("mtrr: your CPUs had inconsistent fixed MTRR settings\n");
-       if (mask & MTRR_CHANGE_MASK_VARIABLE)
-               printk ("mtrr: your CPUs had inconsistent variable MTRR settings\n");
-       if (mask & MTRR_CHANGE_MASK_DEFTYPE)
-               printk ("mtrr: your CPUs had inconsistent MTRRdefType settings\n");
-       printk ("mtrr: probably your BIOS does not setup all CPUs\n");
-}
-
-#endif /*  CONFIG_SMP  */
-
-
-static inline char * attrib_to_str (int x)
-{
-       return (x <= 6) ? mtrr_strings[x] : "?";
-}
-
-
-static void __init init_table (void)
-{
-       int i, max;
-
-       max = get_num_var_ranges ();
-       if ((usage_table = kmalloc (max * sizeof *usage_table, GFP_KERNEL))==NULL) {
-               printk ("mtrr: could not allocate\n");
-               return;
-       }
-
-       for (i = 0; i < max; i++)
-               usage_table[i] = 1;
-
-#ifdef USERSPACE_INTERFACE
-       if ((ascii_buffer = kmalloc (max * LINE_SIZE, GFP_KERNEL)) == NULL) {
-               printk ("mtrr: could not allocate\n");
-               return;
-       }
-       ascii_buf_bytes = 0;
-       compute_ascii ();
-#endif
-}
-
-
-/*
- * Get a free MTRR.
- * returns the index of the region on success, else -1 on error.
-*/
-static int get_free_region(void)
-{
-       int i, max;
-       mtrr_type ltype;
-       u64 lbase;
-       u32 lsize;
-
-       max = get_num_var_ranges ();
-       for (i = 0; i < max; ++i) {
-               get_mtrr (i, &lbase, &lsize, &ltype);
-               if (lsize == 0)
-                       return i;
-       }
-       return -ENOSPC;
-}
-
-
-/**
- *     mtrr_add_page - Add a memory type region
- *     @base: Physical base address of region in pages (4 KB)
- *     @size: Physical size of region in pages (4 KB)
- *     @type: Type of MTRR desired
- *     @increment: If this is true do usage counting on the region
- *     Returns The MTRR register on success, else a negative number
- *     indicating the error code.
- *
- *     Memory type region registers control the caching on newer
- *     processors. This function allows drivers to request an MTRR is added.
- *     The caller should expect to need to provide a power of two size on
- *     an equivalent power of two boundary.
- *
- *     If the region cannot be added either because all regions are in use
- *     or the CPU cannot support it a negative value is returned. On success
- *     the register number for this entry is returned, but should be treated
- *     as a cookie only.
- *
- *     On a multiprocessor machine the changes are made to all processors.
- *
- *     The available types are
- *
- *     %MTRR_TYPE_UNCACHABLE   -       No caching
- *     %MTRR_TYPE_WRBACK       -       Write data back in bursts whenever
- *     %MTRR_TYPE_WRCOMB       -       Write data back soon but allow bursts
- *     %MTRR_TYPE_WRTHROUGH    -       Cache reads but not writes
- *
- *     BUGS: Needs a quiet flag for the cases where drivers do not mind
- *     failures and do not wish system log messages to be sent.
- */
-
-int mtrr_add_page (u64 base, u32 size, unsigned int type, char increment)
-{
-       int i, max;
-       mtrr_type ltype;
-       u64 lbase, last;
-       u32 lsize;
-
-       if (base + size < 0x100) {
-               printk (KERN_WARNING
-                       "mtrr: cannot set region below 1 MiB (0x%Lx000,0x%x000)\n",
-                       base, size);
-               return -EINVAL;
-       }
-
-       /*  Check upper bits of base and last are equal and lower bits are 0
-          for base and 1 for last  */
-       last = base + size - 1;
-       for (lbase = base; !(lbase & 1) && (last & 1);
-            lbase = lbase >> 1, last = last >> 1) ;
-
-       if (lbase != last) {
-               printk (KERN_WARNING
-                       "mtrr: base(0x%Lx000) is not aligned on a size(0x%x000) boundary\n",
-                       base, size);
-               return -EINVAL;
-       }
-
-       if (type >= MTRR_NUM_TYPES) {
-               printk ("mtrr: type: %u illegal\n", type);
-               return -EINVAL;
-       }
-
-       /*  If the type is WC, check that this processor supports it  */
-       if ((type == MTRR_TYPE_WRCOMB) && !have_wrcomb()) {
-               printk (KERN_WARNING
-                       "mtrr: your processor doesn't support write-combining\n");
-               return -ENOSYS;
-       }
-
-       if (base & (size_or_mask>>PAGE_SHIFT)) {
-               printk (KERN_WARNING "mtrr: base(%lx) exceeds the MTRR width(%lx)\n",
-                               (unsigned long) base,
-                               (unsigned long) (size_or_mask>>PAGE_SHIFT));
-               return -EINVAL;
-       }
-
-       if (size & (size_or_mask>>PAGE_SHIFT)) {
-               printk (KERN_WARNING "mtrr: size exceeds the MTRR width\n");
-               return -EINVAL;
-       }
-
-       increment = increment ? 1 : 0;
-       max = get_num_var_ranges ();
-       /*  Search for existing MTRR  */
-       down (&mtrr_lock);
-       for (i = 0; i < max; ++i) {
-               get_mtrr (i, &lbase, &lsize, &ltype);
-               if (base >= lbase + lsize)
-                       continue;
-               if ((base < lbase) && (base + size <= lbase))
-                       continue;
-
-               /*  At this point we know there is some kind of overlap/enclosure  */
-               if ((base < lbase) || (base + size > lbase + lsize)) {
-                       up (&mtrr_lock);
-                       printk (KERN_WARNING
-                               "mtrr: 0x%Lx000,0x%x000 overlaps existing"
-                               " 0x%Lx000,0x%x000\n", base, size, lbase, lsize);
-                       return -EINVAL;
-               }
-               /*  New region is enclosed by an existing region  */
-               if (ltype != type) {
-                       if (type == MTRR_TYPE_UNCACHABLE)
-                               continue;
-                       up (&mtrr_lock);
-                       printk
-                           ("mtrr: type mismatch for %Lx000,%x000 old: %s new: %s\n",
-                            base, size,
-                                attrib_to_str (ltype),
-                            attrib_to_str (type));
-                       return -EINVAL;
-               }
-               if (increment)
-                       ++usage_table[i];
-               compute_ascii ();
-               up (&mtrr_lock);
-               return i;
-       }
-       /*  Search for an empty MTRR  */
-       i = get_free_region();
-       if (i < 0) {
-               up (&mtrr_lock);
-               printk ("mtrr: no more MTRRs available\n");
-               return i;
-       }
-       set_mtrr (i, base, size, type);
-       usage_table[i] = 1;
-       compute_ascii ();
-       up (&mtrr_lock);
-       return i;
-}
-
-
-/**
- *     mtrr_add - Add a memory type region
- *     @base: Physical base address of region
- *     @size: Physical size of region
- *     @type: Type of MTRR desired
- *     @increment: If this is true do usage counting on the region
- *     Return the MTRR register on success, else a negative numbe
- *     indicating the error code.
- *
- *     Memory type region registers control the caching on newer processors.
- *     This function allows drivers to request an MTRR is added.
- *     The caller should expect to need to provide a power of two size on
- *     an equivalent power of two boundary.
- *
- *     If the region cannot be added either because all regions are in use
- *     or the CPU cannot support it a negative value is returned. On success
- *     the register number for this entry is returned, but should be treated
- *     as a cookie only.
- *
- *     On a multiprocessor machine the changes are made to all processors.
- *     This is required on x86 by the Intel processors.
- *
- *     The available types are
- *
- *     %MTRR_TYPE_UNCACHABLE   -       No caching
- *     %MTRR_TYPE_WRBACK       -       Write data back in bursts whenever
- *     %MTRR_TYPE_WRCOMB       -       Write data back soon but allow bursts
- *     %MTRR_TYPE_WRTHROUGH    -       Cache reads but not writes
- *
- *     BUGS: Needs a quiet flag for the cases where drivers do not mind
- *     failures and do not wish system log messages to be sent.
- */
-
-int mtrr_add (u64 base, u32 size, unsigned int type, char increment)
-{
-       if ((base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1))) {
-               printk ("mtrr: size and base must be multiples of 4 kiB\n");
-               printk ("mtrr: size: 0x%x  base: 0x%Lx\n", size, base);
-               return -EINVAL;
-       }
-       return mtrr_add_page (base >> PAGE_SHIFT, size >> PAGE_SHIFT, type,
-                             increment);
-}
-
-
-/**
- *     mtrr_del_page - delete a memory type region
- *     @reg: Register returned by mtrr_add
- *     @base: Physical base address
- *     @size: Size of region
- *
- *     If register is supplied then base and size are ignored. This is
- *     how drivers should call it.
- *
- *     Releases an MTRR region. If the usage count drops to zero the 
- *     register is freed and the region returns to default state.
- *     On success the register is returned, on failure a negative error
- *     code.
- */
-
-int mtrr_del_page (int reg, u64 base, u32 size)
-{
-       int i, max;
-       mtrr_type ltype;
-       u64 lbase;
-       u32 lsize;
-
-       max = get_num_var_ranges ();
-       down (&mtrr_lock);
-       if (reg < 0) {
-               /*  Search for existing MTRR  */
-               for (i = 0; i < max; ++i) {
-                       get_mtrr (i, &lbase, &lsize, &ltype);
-                       if (lbase == base && lsize == size) {
-                               reg = i;
-                               break;
-                       }
-               }
-               if (reg < 0) {
-                       up (&mtrr_lock);
-                       printk ("mtrr: no MTRR for %Lx000,%x000 found\n", base, size);
-                       return -EINVAL;
-               }
-       }
-
-       if (reg >= max) {
-               up (&mtrr_lock);
-               printk ("mtrr: register: %d too big\n", reg);
-               return -EINVAL;
-       }
-       get_mtrr (reg, &lbase, &lsize, &ltype);
-
-       if (lsize < 1) {
-               up (&mtrr_lock);
-               printk ("mtrr: MTRR %d not used\n", reg);
-               return -EINVAL;
-       }
-
-       if (usage_table[reg] < 1) {
-               up (&mtrr_lock);
-               printk ("mtrr: reg: %d has count=0\n", reg);
-               return -EINVAL;
-       }
-
-       if (--usage_table[reg] < 1)
-               set_mtrr (reg, 0, 0, 0);
-       compute_ascii ();
-       up (&mtrr_lock);
-       return reg;
-}
-
-
-/**
- *     mtrr_del - delete a memory type region
- *     @reg: Register returned by mtrr_add
- *     @base: Physical base address
- *     @size: Size of region
- *
- *     If register is supplied then base and size are ignored. This is
- *     how drivers should call it.
- *
- *     Releases an MTRR region. If the usage count drops to zero the 
- *     register is freed and the region returns to default state.
- *     On success the register is returned, on failure a negative error
- *     code.
- */
-
-int mtrr_del (int reg, u64 base, u32 size)
-{
-       if ((base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1))) {
-               printk ("mtrr: size and base must be multiples of 4 kiB\n");
-               printk ("mtrr: size: 0x%x  base: 0x%Lx\n", size, base);
-               return -EINVAL;
-       }
-       return mtrr_del_page (reg, base >> PAGE_SHIFT, size >> PAGE_SHIFT);
-}
-
-
-#ifdef USERSPACE_INTERFACE
-
-static int mtrr_file_add (u64 base, u32 size, unsigned int type,
-               struct file *file, int page)
-{
-       int reg, max;
-       unsigned int *fcount = file->private_data;
-
-       max = get_num_var_ranges ();
-       if (fcount == NULL) {
-               if ((fcount =
-                    kmalloc (max * sizeof *fcount, GFP_KERNEL)) == NULL) {
-                       printk ("mtrr: could not allocate\n");
-                       return -ENOMEM;
-               }
-               memset (fcount, 0, max * sizeof *fcount);
-               file->private_data = fcount;
-       }
-
-       if (!page) {
-               if ((base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1))) {
-                       printk
-                           ("mtrr: size and base must be multiples of 4 kiB\n");
-                       printk ("mtrr: size: 0x%x  base: 0x%Lx\n", size, base);
-                       return -EINVAL;
-               }
-               base >>= PAGE_SHIFT;
-               size >>= PAGE_SHIFT;
-       }
-
-       reg = mtrr_add_page (base, size, type, 1);
-
-       if (reg >= 0)
-               ++fcount[reg];
-       return reg;
-}
-
-
-static int mtrr_file_del (u64 base, u32 size,
-               struct file *file, int page)
-{
-       int reg;
-       unsigned int *fcount = file->private_data;
-
-       if (!page) {
-               if ((base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1))) {
-                       printk
-                           ("mtrr: size and base must be multiples of 4 kiB\n");
-                       printk ("mtrr: size: 0x%x  base: 0x%Lx\n", size, base);
-                       return -EINVAL;
-               }
-               base >>= PAGE_SHIFT;
-               size >>= PAGE_SHIFT;
-       }
-       reg = mtrr_del_page (-1, base, size);
-       if (reg < 0)
-               return reg;
-       if (fcount == NULL)
-               return reg;
-       if (fcount[reg] < 1)
-               return -EINVAL;
-       --fcount[reg];
-       return reg;
-}
-
-
-static ssize_t mtrr_read (struct file *file, char *buf, size_t len,
-               loff_t * ppos)
-{
-       if (*ppos >= ascii_buf_bytes)
-               return 0;
-
-       if (*ppos + len > ascii_buf_bytes)
-               len = ascii_buf_bytes - *ppos;
-
-       if (copy_to_user (buf, ascii_buffer + *ppos, len))
-               return -EFAULT;
-
-       *ppos += len;
-       return len;
-}
-
-
-static ssize_t mtrr_write (struct file *file, const char *buf,
-               size_t len, loff_t * ppos)
-/*  Format of control line:
-    "base=%Lx size=%Lx type=%s"     OR:
-    "disable=%d"
-*/
-{
-       int i, err, reg;
-       u64 base;
-       u32 size;
-       char *ptr;
-       char line[LINE_SIZE];
-
-       if (!capable(CAP_SYS_ADMIN))
-               return -EPERM;
-
-       /*  Can't seek (pwrite) on this device  */
-       if (ppos != &file->f_pos)
-               return -ESPIPE;
-       memset (line, 0, LINE_SIZE);
-
-       if (len > LINE_SIZE)
-               len = LINE_SIZE;
-
-       if (copy_from_user (line, buf, len - 1))
-               return -EFAULT;
-       ptr = line + strlen (line) - 1;
-
-       if (*ptr == '\n')
-               *ptr = '\0';
-
-       if (!strncmp (line, "disable=", 8)) {
-               reg = simple_strtoul (line + 8, &ptr, 0);
-               err = mtrr_del_page (reg, 0, 0);
-               if (err < 0)
-                       return err;
-               return len;
-       }
-
-       if (strncmp (line, "base=", 5)) {
-               printk ("mtrr: no \"base=\" in line: \"%s\"\n", line);
-               return -EINVAL;
-       }
-
-       base = simple_strtoull (line + 5, &ptr, 0);
-
-       for (; isspace (*ptr); ++ptr) ;
-
-       if (strncmp (ptr, "size=", 5)) {
-               printk ("mtrr: no \"size=\" in line: \"%s\"\n", line);
-               return -EINVAL;
-       }
-
-       size = simple_strtoull (ptr + 5, &ptr, 0);
-
-       if ((base & 0xfff) || (size & 0xfff)) {
-               printk ("mtrr: size and base must be multiples of 4 kiB\n");
-               printk ("mtrr: size: 0x%x  base: 0x%Lx\n", size, base);
-               return -EINVAL;
-       }
-
-       for (; isspace (*ptr); ++ptr) ;
-
-       if (strncmp (ptr, "type=", 5)) {
-               printk ("mtrr: no \"type=\" in line: \"%s\"\n", line);
-               return -EINVAL;
-       }
-       ptr += 5;
-
-       for (; isspace (*ptr); ++ptr) ;
-
-       for (i = 0; i < MTRR_NUM_TYPES; ++i) {
-               if (strcmp (ptr, mtrr_strings[i]))
-                       continue;
-               base >>= PAGE_SHIFT;
-               size >>= PAGE_SHIFT;
-               err = mtrr_add_page ((u64) base, size, i, 1);
-               if (err < 0)
-                       return err;
-               return len;
-       }
-       printk ("mtrr: illegal type: \"%s\"\n", ptr);
-       return -EINVAL;
-}
-
-
-static int mtrr_ioctl (struct inode *inode, struct file *file,
-               unsigned int cmd, unsigned long arg)
-{
-       int err;
-       mtrr_type type;
-       struct mtrr_sentry sentry;
-       struct mtrr_gentry gentry;
-
-       switch (cmd) {
-       default:
-               return -ENOIOCTLCMD;
-
-       case MTRRIOC_ADD_ENTRY:
-               if (!capable(CAP_SYS_ADMIN))
-                       return -EPERM;
-               if (copy_from_user (&sentry, (void *) arg, sizeof sentry))
-                       return -EFAULT;
-               err = mtrr_file_add (sentry.base, sentry.size, sentry.type,
-                                  file, 0);
-               if (err < 0)
-                       return err;
-               break;
-
-       case MTRRIOC_SET_ENTRY:
-               if (!capable(CAP_SYS_ADMIN))
-                       return -EPERM;
-               if (copy_from_user (&sentry, (void *) arg, sizeof sentry))
-                       return -EFAULT;
-               err = mtrr_add (sentry.base, sentry.size, sentry.type, 0);
-               if (err < 0)
-                       return err;
-               break;
-
-       case MTRRIOC_DEL_ENTRY:
-               if (!capable(CAP_SYS_ADMIN))
-                       return -EPERM;
-               if (copy_from_user (&sentry, (void *) arg, sizeof sentry))
-                       return -EFAULT;
-               err = mtrr_file_del (sentry.base, sentry.size, file, 0);
-               if (err < 0)
-                       return err;
-               break;
-
-       case MTRRIOC_KILL_ENTRY:
-               if (!capable(CAP_SYS_ADMIN))
-                       return -EPERM;
-               if (copy_from_user (&sentry, (void *) arg, sizeof sentry))
-                       return -EFAULT;
-               err = mtrr_del (-1, sentry.base, sentry.size);
-               if (err < 0)
-                       return err;
-               break;
-
-       case MTRRIOC_GET_ENTRY:
-               if (copy_from_user (&gentry, (void *) arg, sizeof gentry))
-                       return -EFAULT;
-               if (gentry.regnum >= get_num_var_ranges ())
-                       return -EINVAL;
-               get_mtrr (gentry.regnum, (u64*) &gentry.base, &gentry.size, &type);
-
-               /* Hide entries that go above 4GB */
-               if (gentry.base + gentry.size > 0x100000
-                   || gentry.size == 0x100000)
-                       gentry.base = gentry.size = gentry.type = 0;
-               else {
-                       gentry.base <<= PAGE_SHIFT;
-                       gentry.size <<= PAGE_SHIFT;
-                       gentry.type = type;
-               }
-
-               if (copy_to_user ((void *) arg, &gentry, sizeof gentry))
-                       return -EFAULT;
-               break;
-
-       case MTRRIOC_ADD_PAGE_ENTRY:
-               if (!capable(CAP_SYS_ADMIN))
-                       return -EPERM;
-               if (copy_from_user (&sentry, (void *) arg, sizeof sentry))
-                       return -EFAULT;
-               err = mtrr_file_add (sentry.base, sentry.size, sentry.type, file, 1);
-               if (err < 0)
-                       return err;
-               break;
-
-       case MTRRIOC_SET_PAGE_ENTRY:
-               if (!capable(CAP_SYS_ADMIN))
-                       return -EPERM;
-               if (copy_from_user (&sentry, (void *) arg, sizeof sentry))
-                       return -EFAULT;
-               err = mtrr_add_page (sentry.base, sentry.size, sentry.type, 0);
-               if (err < 0)
-                       return err;
-               break;
-
-       case MTRRIOC_DEL_PAGE_ENTRY:
-               if (!capable(CAP_SYS_ADMIN))
-                       return -EPERM;
-               if (copy_from_user (&sentry, (void *) arg, sizeof sentry))
-                       return -EFAULT;
-               err = mtrr_file_del (sentry.base, sentry.size, file, 1);
-               if (err < 0)
-                       return err;
-               break;
-
-       case MTRRIOC_KILL_PAGE_ENTRY:
-               if (!capable(CAP_SYS_ADMIN))
-                       return -EPERM;
-               if (copy_from_user (&sentry, (void *) arg, sizeof sentry))
-                       return -EFAULT;
-               err = mtrr_del_page (-1, sentry.base, sentry.size);
-               if (err < 0)
-                       return err;
-               break;
-
-       case MTRRIOC_GET_PAGE_ENTRY:
-               if (copy_from_user (&gentry, (void *) arg, sizeof gentry))
-                       return -EFAULT;
-               if (gentry.regnum >= get_num_var_ranges ())
-                       return -EINVAL;
-               get_mtrr (gentry.regnum, (u64*) &gentry.base, &gentry.size, &type);
-               gentry.type = type;
-
-               if (copy_to_user ((void *) arg, &gentry, sizeof gentry))
-                       return -EFAULT;
-               break;
-       }
-       return 0;
-}
-
-
-static int mtrr_close (struct inode *ino, struct file *file)
-{
-       int i, max;
-       unsigned int *fcount = file->private_data;
-
-       if (fcount == NULL)
-               return 0;
-
-       lock_kernel ();
-       max = get_num_var_ranges ();
-       for (i = 0; i < max; ++i) {
-               while (fcount[i] > 0) {
-                       if (mtrr_del (i, 0, 0) < 0)
-                               printk ("mtrr: reg %d not used\n", i);
-                       --fcount[i];
-               }
-       }
-       unlock_kernel ();
-       kfree (fcount);
-       file->private_data = NULL;
-       return 0;
-}
-
-
-static struct file_operations mtrr_fops = {
-       .owner   = THIS_MODULE,
-       .read    = mtrr_read,
-       .write   = mtrr_write,
-       .ioctl   = mtrr_ioctl,
-       .release = mtrr_close,
-};
-
-#ifdef CONFIG_PROC_FS
-static struct proc_dir_entry *proc_root_mtrr;
-#endif
-
-static devfs_handle_t devfs_handle;
-
-static void compute_ascii (void)
-{
-       char factor;
-       int i, max;
-       mtrr_type type;
-       u64 base;
-       u32 size;
-
-       ascii_buf_bytes = 0;
-       max = get_num_var_ranges ();
-       for (i = 0; i < max; i++) {
-               get_mtrr (i, &base, &size, &type);
-               if (size == 0)
-                       usage_table[i] = 0;
-               else {
-                       if (size < (0x100000 >> PAGE_SHIFT)) {
-                               /* less than 1MB */
-                               factor = 'K';
-                               size <<= PAGE_SHIFT - 10;
-                       } else {
-                               factor = 'M';
-                               size >>= 20 - PAGE_SHIFT;
-                       }
-                       sprintf (ascii_buffer + ascii_buf_bytes,
-                               "reg%02i: base=0x%05Lx000 (%4iMB), size=%4i%cB: %s, count=%d\n",
-                               i, base, (u32) base >> (20 - PAGE_SHIFT), size, factor,
-                               attrib_to_str (type), usage_table[i]);
-                       ascii_buf_bytes += strlen (ascii_buffer + ascii_buf_bytes);
-               }
-       }
-       devfs_set_file_size (devfs_handle, ascii_buf_bytes);
-#ifdef CONFIG_PROC_FS
-       if (proc_root_mtrr)
-               proc_root_mtrr->size = ascii_buf_bytes;
-#endif
-}
-
-#endif /*  USERSPACE_INTERFACE  */
-
-EXPORT_SYMBOL (mtrr_add);
-EXPORT_SYMBOL (mtrr_del);
-
-static void __init mtrr_setup (void)
-{
-       /* If you want to use other vendors please port over the modular
-          framework from i386 first. */
-       if (!cpu_has_mtrr || boot_cpu_data.x86_vendor != X86_VENDOR_AMD) 
-               return; 
-
-                /* Query the width (in bits) of the physical
-                  addressable memory on the Hammer family. */
-               if ((cpuid_eax (0x80000000) >= 0x80000008)) {
-                       u32 phys_addr;
-                       phys_addr = cpuid_eax (0x80000008) & 0xff;
-                       size_or_mask = ~((1L << phys_addr) - 1);
-                       /*
-                        * top bits MBZ as its beyond the addressable range.
-                        * bottom bits MBZ as we don't care about lower 12 bits of addr.
-                        */
-                       size_and_mask = (~size_or_mask) & 0x000ffffffffff000L;
-       }
-}
-
-#ifdef CONFIG_SMP
-
-static volatile u32 smp_changes_mask __initdata = 0;
-static struct mtrr_state smp_mtrr_state __initdata = { 0, 0 };
-
-#endif /*  CONFIG_SMP  */
-
-void mtrr_init_cpu(int cpu)
-{
-#ifndef CONFIG_SMP
-       if (cpu == 0) 
-               mtrr_setup();
-#else
-       if (cpu == 0) { 
-       mtrr_setup();
-       get_mtrr_state (&smp_mtrr_state);
-       } else { 
-       u64 mask;
-       int count;
-       struct set_mtrr_context ctxt;
-
-               /* Note that this is not ideal, since the cache is
-                  only flushed/disabled for this CPU while the MTRRs
-                  are changed, but changing this requires more
-                  invasive changes to the way the kernel boots  */
-       set_mtrr_prepare (&ctxt);
-       mask = set_mtrr_state (&smp_mtrr_state, &ctxt);
-       set_mtrr_done (&ctxt);
-
-       /*  Use the atomic bitops to update the global mask  */
-               for (count = 0; count < (sizeof mask) * 8; ++count) {
-                       if (mask & 1)
-                       set_bit (count, &smp_changes_mask);
-               mask >>= 1;
-       }
-       } 
-#endif
-}
-
-static int __init mtrr_init (void)
-{
-#ifdef CONFIG_PROC_FS
-       proc_root_mtrr = create_proc_entry ("mtrr", S_IWUSR | S_IRUGO, &proc_root);
-       if (proc_root_mtrr) {
-               proc_root_mtrr->owner = THIS_MODULE;
-               proc_root_mtrr->proc_fops = &mtrr_fops;
-       }
-#endif
-#ifdef CONFIG_DEVFS_FS
-       devfs_handle = devfs_register (NULL, "cpu/mtrr", DEVFS_FL_DEFAULT, 0, 0,
-                               S_IFREG | S_IRUGO | S_IWUSR,
-                               &mtrr_fops, NULL);
-#endif
-       init_table ();
-
-#ifdef CONFIG_SMP
-       finalize_mtrr_state (&smp_mtrr_state);
-       mtrr_state_warn (smp_changes_mask);
-#endif
-
-       return 0;
-}
-
-__initcall(mtrr_init);
diff --git a/arch/x86_64/kernel/mtrr/Makefile b/arch/x86_64/kernel/mtrr/Makefile
new file mode 100644 (file)
index 0000000..8b1e935
--- /dev/null
@@ -0,0 +1,30 @@
+#
+# Reuse the i386 MTRR driver.
+#
+
+obj-y          := main.o if.o generic.o state.o
+obj-y          += amd.o
+obj-y          += cyrix.o
+obj-y          += centaur.o
+
+export-objs    := main.o
+
+$(obj)/main.c: $(obj)/mtrr.h
+       @ln -sf ../../../i386/kernel/cpu/mtrr/main.c $(obj)/main.c
+$(obj)/if.c: $(obj)/mtrr.h
+       @ln -sf ../../../i386/kernel/cpu/mtrr/if.c $(obj)/if.c
+$(obj)/generic.c: $(obj)/mtrr.h
+       @ln -sf ../../../i386/kernel/cpu/mtrr/generic.c $(obj)/generic.c
+$(obj)/state.c: $(obj)/mtrr.h
+       @ln -sf ../../../i386/kernel/cpu/mtrr/state.c $(obj)/state.c
+$(obj)/amd.c: $(obj)/mtrr.h
+       @ln -sf ../../../i386/kernel/cpu/mtrr/amd.c $(obj)/amd.c
+$(obj)/cyrix.c: $(obj)/mtrr.h
+       @ln -sf ../../../i386/kernel/cpu/mtrr/cyrix.c $(obj)/cyrix.c
+$(obj)/centaur.c: $(obj)/mtrr.h
+       @ln -sf ../../../i386/kernel/cpu/mtrr/centaur.c $(obj)/centaur.c
+$(obj)/mtrr.h:
+       @ln -sf ../../../i386/kernel/cpu/mtrr/mtrr.h $(obj)/mtrr.h
+
+clean-files += main.c if.c generic.c state.c amd.c cyrix.c centaur.c mtrr.h
+
index f2a41467cc010d3270cbae4bf75edd9d328c909a..73e3adacefc1fb1c6088b049eb8d9f453bd00450 100644 (file)
@@ -300,12 +300,18 @@ static nmi_callback_t nmi_callback = dummy_nmi_callback;
  
 asmlinkage void do_nmi(struct pt_regs * regs, long error_code)
 {
-       int cpu = smp_processor_id();
+       int cpu;
+
+       nmi_enter();
+
+       cpu = smp_processor_id(); 
 
        add_pda(__nmi_count,1);
 
        if (!nmi_callback(regs, cpu))
                default_do_nmi(regs);
+       
+       nmi_exit();
 }
 
 void set_nmi_callback(nmi_callback_t callback)
index f9629ad3bc75b7ec67a348a1c40bbbefc3f615f6..25cb68ee049fcddb9eafa1f852cee793cb35eaf5 100644 (file)
@@ -245,7 +245,7 @@ static void iommu_full(struct pci_dev *dev, void *addr, size_t size, int dir)
        
        printk(KERN_ERR 
   "PCI-DMA: Error: ran out out IOMMU space for %p size %lu at device %s[%s]\n",
-              addr,size, dev ? dev->name : "?", dev ? dev->slot_name : "?");
+              addr,size, dev ? dev->dev.name : "?", dev ? dev->slot_name : "?");
 
        if (size > PAGE_SIZE*EMERGENCY_PAGES) {
                if (dir == PCI_DMA_FROMDEVICE || dir == PCI_DMA_BIDIRECTIONAL)
@@ -286,7 +286,7 @@ dma_addr_t pci_map_single(struct pci_dev *dev, void *addr, size_t size,int dir)
        if (!need_iommu(dev, phys_mem, size))
                return phys_mem; 
 
-       npages = round_up(size, PAGE_SIZE) >> PAGE_SHIFT;
+       npages = round_up(size + ((u64)addr & ~PAGE_MASK), PAGE_SIZE) >> PAGE_SHIFT;
 
        iommu_page = alloc_iommu(npages); 
        if (iommu_page == -1) {
@@ -328,7 +328,7 @@ void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr,
            dma_addr > iommu_bus_base + iommu_size)
                return;
        iommu_page = (dma_addr - iommu_bus_base)>>PAGE_SHIFT;   
-       npages = round_up(size, PAGE_SIZE) >> PAGE_SHIFT;
+       npages = round_up(size + (dma_addr & ~PAGE_MASK), PAGE_SIZE) >> PAGE_SHIFT;
        for (i = 0; i < npages; i++) { 
                iommu_gatt_base[iommu_page + i] = 0; 
 #ifdef CONFIG_IOMMU_LEAK
index cc3999660819e3e67a2fb6c7350c4bacb6a082ca..010e53985ac112478f4043899d82f8b926895299 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/sched.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
+#include <linux/elfcore.h>
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
 #include <linux/stddef.h>
@@ -223,6 +224,7 @@ void flush_thread(void)
        struct task_struct *tsk = current;
 
        memset(tsk->thread.debugreg, 0, sizeof(unsigned long)*8);
+       memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array));        
        /*
         * Forget coprocessor state..
         */
@@ -259,7 +261,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long rsp,
        if (rsp == ~0) {
                childregs->rsp = (unsigned long)childregs;
        }
-       p->user_tid = NULL;
+       p->set_child_tid = p->clear_child_tid = NULL;
 
        p->thread.rsp = (unsigned long) childregs;
        p->thread.rsp0 = (unsigned long) (childregs+1);
@@ -322,10 +324,6 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long rsp,
 /*
  *     switch_to(x,y) should switch tasks from x to y.
  *
- * We fsave/fwait so that an exception goes off at the right time
- * (as a call from the fsave or fwait in effect) rather than to
- * the wrong process. 
- * 
  * This could still be optimized: 
  * - fold all the options into a flag word and test it with a single test.
  * - could test fs/gs bitsliced
@@ -356,44 +354,37 @@ void __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
        if (unlikely(next->ds | prev->ds))
                loadsegment(ds, next->ds);
 
+       load_TLS(next, cpu);
+
        /* 
         * Switch FS and GS.
-        * XXX Check if this is safe on SMP (!= -> |)
-        * Need to simplify this.
         */
        { 
-               unsigned int fsindex;
-               unsigned int gsindex;
-
+               unsigned fsindex;
                asm volatile("movl %%fs,%0" : "=g" (fsindex)); 
-               asm volatile("movl %%gs,%0" : "=g" (gsindex)); 
-
-               /*
-                * Load the per-thread Thread-Local Storage descriptor.
-                */
-               if (load_TLS(next, cpu)) {
-                       loadsegment(fs,next->fsindex);
-                       /* should find a way to optimize this away - it is
-                          slow */
-                       goto loadgs;    
-               } else { 
-                       if (fsindex  != next->fsindex)
-                               loadsegment(fs,next->fsindex); 
-                       if (gsindex != next->gsindex) {
-                       loadgs:
-                               load_gs_index(next->gsindex); 
-                       }       
-               }
-                               
+               /* segment register != 0 always requires a reload. 
+                  also reload when it has changed. 
+                  when prev process used 64bit base always reload
+                  to avoid an information leak. */
+               if (unlikely((fsindex | next->fsindex) || prev->fs))
+                       loadsegment(fs, next->fsindex);
+               /* check if the user changed the selector
+                  if yes clear 64bit base. */
                if (unlikely(fsindex != prev->fsindex))
                        prev->fs = 0;                           
-               if ((fsindex != prev->fsindex) || (prev->fs != next->fs))
+               /* when next process has a 64bit base use it */
+               if (next->fs) 
                        wrmsrl(MSR_FS_BASE, next->fs); 
                prev->fsindex = fsindex;
-
+       }
+       { 
+               unsigned gsindex;
+               asm volatile("movl %%gs,%0" : "=g" (gsindex)); 
+               if (unlikely((gsindex | next->gsindex) || prev->gs))
+                       load_gs_index(next->gsindex);
                if (unlikely(gsindex != prev->gsindex)) 
                        prev->gs = 0;                           
-               if (gsindex != prev->gsindex || prev->gs != next->gs)
+               if (next->gs)
                        wrmsrl(MSR_KERNEL_GS_BASE, next->gs); 
                prev->gsindex = gsindex;
        }
@@ -477,16 +468,17 @@ void set_personality_64bit(void)
 asmlinkage long sys_fork(struct pt_regs regs)
 {
        struct task_struct *p;
-       p = do_fork(SIGCHLD, regs.rsp, &regs, 0, NULL);
+       p = do_fork(SIGCHLD, regs.rsp, &regs, 0, NULL, NULL);
        return IS_ERR(p) ? PTR_ERR(p) : p->pid;
 }
 
-asmlinkage long sys_clone(unsigned long clone_flags, unsigned long newsp, void *user_tid, struct pt_regs regs)
+asmlinkage long sys_clone(unsigned long clone_flags, unsigned long newsp, void *parent_tid, void *child_tid, struct pt_regs regs)
 {
        struct task_struct *p;
        if (!newsp)
                newsp = regs.rsp;
-       p = do_fork(clone_flags & ~CLONE_IDLETASK, newsp, &regs, 0, user_tid);
+       p = do_fork(clone_flags & ~CLONE_IDLETASK, newsp, &regs, 0, 
+                   parent_tid, child_tid);
        return IS_ERR(p) ? PTR_ERR(p) : p->pid;
 }
 
@@ -503,7 +495,8 @@ asmlinkage long sys_clone(unsigned long clone_flags, unsigned long newsp, void *
 asmlinkage long sys_vfork(struct pt_regs regs)
 {
        struct task_struct *p;
-       p = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.rsp, &regs, 0, NULL);
+       p = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.rsp, &regs, 0, 
+                   NULL, NULL);
        return IS_ERR(p) ? PTR_ERR(p) : p->pid;
 }
 
@@ -547,7 +540,8 @@ int sys_arch_prctl(int code, unsigned long addr)
        case ARCH_SET_GS:
                if (addr >= TASK_SIZE) 
                        return -EPERM; 
-               asm volatile("movw %%gs,%0" : "=g" (current->thread.gsindex)); 
+               load_gs_index(0);
+               current->thread.gsindex = 0;
                current->thread.gs = addr;
                ret = checking_wrmsrl(MSR_KERNEL_GS_BASE, addr); 
                break;
@@ -556,7 +550,8 @@ int sys_arch_prctl(int code, unsigned long addr)
                   with gs */
                if (addr >= TASK_SIZE)
                        return -EPERM; 
-               asm volatile("movw %%fs,%0" : "=g" (current->thread.fsindex)); 
+               asm volatile("movl %0,%%fs" :: "r" (0));
+               current->thread.fsindex = 0;
                current->thread.fs = addr;
                ret = checking_wrmsrl(MSR_FS_BASE, addr); 
                break;
@@ -691,3 +686,22 @@ asmlinkage int sys_get_thread_area(struct user_desc *u_info)
                return -EFAULT;
        return 0;
 }
+
+/* 
+ * Capture the user space registers if the task is not running (in user space)
+ */
+int dump_task_regs(struct task_struct *tsk, elf_gregset_t *regs)
+{
+       struct pt_regs *pp, ptregs;
+
+       pp = (struct pt_regs *)(tsk->thread.rsp0);
+       --pp; 
+
+       ptregs = *pp; 
+       ptregs.cs &= 0xffff;
+       ptregs.ss &= 0xffff;
+
+       elf_core_copy_regs(regs, &ptregs);
+       return 1;
+}
index 334af20585cb43ae2d051f2b346bca1baa0b12a1..781c2d8274791868d33c083456fe948dd8b9a502 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *     linux/arch/i386/kernel/profile.c
+ *     linux/arch/x86_64/kernel/profile.c
  *
  *     (C) 2002 John Levon <levon@movementarian.org>
  *
index ffc18ae4b781f18b8fadad779353b2c9edad6b67..bd27e6363b067f0aecdec37caeaa4f9c0af4a8aa 100644 (file)
@@ -41,6 +41,23 @@ struct desc_ptr idt_descr = { 256 * 16, (unsigned long) idt_table };
 
 char boot_cpu_stack[IRQSTACKSIZE] __cacheline_aligned;
 
+unsigned long __supported_pte_mask = ~0UL;
+static int do_not_nx = 0;
+
+static int __init nonx_setup(char *str)
+{
+        if (!strncmp(str,"off",3)) { 
+                __supported_pte_mask &= ~_PAGE_NX; 
+                do_not_nx = 1; 
+        } else if (!strncmp(str, "on",3)) { 
+                do_not_nx = 0; 
+                __supported_pte_mask |= _PAGE_NX; 
+        } 
+        return 1;
+} 
+
+__setup("noexec=", nonx_setup); 
+
 #ifndef  __GENERIC_PER_CPU
 
 unsigned long __per_cpu_offset[NR_CPUS];
@@ -127,7 +144,7 @@ void __init cpu_init (void)
        int cpu = smp_processor_id();
 #endif
        struct tss_struct * t = &init_tss[cpu];
-       unsigned long v; 
+       unsigned long v, efer
        char *estacks; 
        struct task_struct *me;
 
@@ -189,6 +206,11 @@ void __init cpu_init (void)
        wrmsrl(MSR_KERNEL_GS_BASE, 0);
        barrier(); 
 
+       rdmsrl(MSR_EFER, efer); 
+        if (!(efer & EFER_NX) || do_not_nx) { 
+                __supported_pte_mask &= ~_PAGE_NX; 
+        }       
+
        /*
         * set up and load the per-CPU TSS
         */
index d9f943a3c445e8dadf9f69293d42d9938814e8e0..d7e21aa7eb0a12f2806b5e06389f81cb589ecd17 100644 (file)
 #include <linux/stddef.h>
 #include <linux/personality.h>
 #include <linux/compiler.h>
+#include <linux/suspend.h>
 #include <asm/ucontext.h>
 #include <asm/uaccess.h>
 #include <asm/i387.h>
+#include <asm/proto.h>
 
 /* #define DEBUG_SIG 1 */
 
@@ -184,11 +186,10 @@ badframe:
  * Set up a signal frame.
  */
 
-static int
-setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs, unsigned long mask)
+static inline int
+setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs, unsigned long mask, struct task_struct *me)
 {
        int tmp, err = 0;
-       struct task_struct *me = current;
 
        tmp = 0;
        __asm__("movl %%gs,%0" : "=r"(tmp): "0"(tmp));
@@ -226,8 +227,6 @@ setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs, unsigned long mask
  * Determine which stack to use..
  */
 
-#define round_down(p, r) ((void *)  ((unsigned long)((p) - (r) + 1) & ~((r)-1)))
-
 static void *
 get_stack(struct k_sigaction *ka, struct pt_regs *regs, unsigned long size)
 {
@@ -242,19 +241,20 @@ get_stack(struct k_sigaction *ka, struct pt_regs *regs, unsigned long size)
                        rsp = current->sas_ss_sp + current->sas_ss_size;
        }
 
-       return round_down(rsp - size, 16); 
+       return (void *)round_down(rsp - size, 16); 
 }
 
 static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
                           sigset_t *set, struct pt_regs * regs)
 {
-       struct rt_sigframe *frame = NULL;
+       struct rt_sigframe *frame;
        struct _fpstate *fp = NULL; 
        int err = 0;
+       struct task_struct *me = current;
 
-       if (current->used_math) {
+       if (me->used_math) {
                fp = get_stack(ka, regs, sizeof(struct _fpstate)); 
-               frame = round_down((char *)fp - sizeof(struct rt_sigframe), 16) - 8;
+               frame = (void *)round_down((u64)fp - sizeof(struct rt_sigframe), 16) - 8;
 
                if (!access_ok(VERIFY_WRITE, fp, sizeof(struct _fpstate))) { 
                goto give_sigsegv;
@@ -262,10 +262,9 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
 
                if (save_i387(fp) < 0) 
                        err |= -1; 
-       }
-
-       if (!frame)
+       } else {
                frame = get_stack(ka, regs, sizeof(struct rt_sigframe)) - 8;
+       }
 
        if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) {
                goto give_sigsegv;
@@ -281,13 +280,18 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
        /* Create the ucontext.  */
        err |= __put_user(0, &frame->uc.uc_flags);
        err |= __put_user(0, &frame->uc.uc_link);
-       err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
+       err |= __put_user(me->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
        err |= __put_user(sas_ss_flags(regs->rsp),
                          &frame->uc.uc_stack.ss_flags);
-       err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
-       err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0]);
+       err |= __put_user(me->sas_ss_size, &frame->uc.uc_stack.ss_size);
+       err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0], me);
        err |= __put_user(fp, &frame->uc.uc_mcontext.fpstate);
+       if (sizeof(*set) == 16) { 
+               __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]);
+               __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]); 
+       } else {                
        err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
+       }
 
        /* Set up to return from userspace.  If provided, use a stub
           already in userspace.  */
@@ -295,7 +299,7 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
        if (ka->sa.sa_flags & SA_RESTORER) {
                err |= __put_user(ka->sa.sa_restorer, &frame->pretcode);
        } else {
-               printk("%s forgot to set SA_RESTORER for signal %d.\n", current->comm, sig); 
+               printk("%s forgot to set SA_RESTORER for signal %d.\n", me->comm, sig); 
                goto give_sigsegv; 
        }
 
@@ -338,7 +342,7 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
 give_sigsegv:
        if (sig == SIGSEGV)
                ka->sa.sa_handler = SIG_DFL;
-       signal_fault(regs,frame,"signal setup");
+       signal_fault(regs,frame,"signal deliver");
 }
 
 /*
@@ -360,6 +364,9 @@ handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset,
        if (regs->orig_rax >= 0) {
                /* If so, check system call restarting.. */
                switch (regs->rax) {
+                       case -ERESTART_RESTARTBLOCK:
+                               current_thread_info()->restart_block.fn = do_no_restart_syscall;
+                               /* FALL THROUGH */
                        case -ERESTARTNOHAND:
                                regs->rax = -EINTR;
                                break;
@@ -374,6 +381,10 @@ handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset,
                                regs->rax = regs->orig_rax;
                                regs->rip -= 2;
                }
+               if (regs->rax == -ERESTART_RESTARTBLOCK){
+                       regs->rax = __NR_restart_syscall;
+                       regs->rip -= 2;
+               }               
        }
 
 #ifdef CONFIG_IA32_EMULATION
@@ -418,6 +429,11 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
                return 1;
        }       
 
+       if (current->flags & PF_FREEZE) {
+               refrigerator(0);
+               goto no_signal;
+       }
+
        if (!oldset)
                oldset = &current->blocked;
 
@@ -435,6 +451,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
                return 1;
        }
 
+ no_signal:
        /* Did we come from a system call? */
        if (regs->orig_rax >= 0) {
                /* Restart the system call - no handlers present */
index 9753437eff9dddd732bf263afee2a803626e1df9..6266c936c135104ac7d1f57b802671d87cda4af5 100644 (file)
 #include <linux/smp.h>
 #include <linux/kernel_stat.h>
 #include <linux/mc146818rtc.h>
+#include <linux/interrupt.h>
 
 #include <asm/mtrr.h>
 #include <asm/pgalloc.h>
 #include <asm/tlbflush.h>
-#include <asm/hardirq.h>
 
 /*
  * the following functions deal with sending IPIs between CPUs.
index cd2c0e50ea4473c91f3d3332ef03ddcfc3a01354..e7acfed4bf2afe643a9129313c4eccc6487b5ee2 100644 (file)
@@ -323,12 +323,6 @@ void __init smp_callin(void)
 
        local_irq_enable();
 
-#ifdef CONFIG_MTRR
-       /*
-        * Must be done before calibration delay is computed
-        */
-       mtrr_init_cpu (cpuid);
-#endif
        /*
         * Get our bogomips.
         */
@@ -344,6 +338,8 @@ void __init smp_callin(void)
 
        notify_die(DIE_CPUINIT, "cpuinit", NULL, 0);
 
+       local_irq_disable();
+
        /*
         * Allow the master to continue.
         */
@@ -436,7 +432,7 @@ static struct task_struct * __init fork_by_hand(void)
         * don't care about the rip and regs settings since
         * we'll never reschedule the forked task.
         */
-       return do_fork(CLONE_VM|CLONE_IDLETASK, 0, &regs, 0, NULL);
+       return do_fork(CLONE_VM|CLONE_IDLETASK, 0, &regs, 0, NULL, NULL);
 }
 
 #if APIC_DEBUG
@@ -969,12 +965,17 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
 int __devinit __cpu_up(unsigned int cpu)
 {
        /* This only works at boot for x86.  See "rewrite" above. */
-       if (test_bit(cpu, &smp_commenced_mask))
+       if (test_bit(cpu, &smp_commenced_mask)) { 
+               local_irq_enable();
                return -ENOSYS;
+       }
 
        /* In case one didn't come up */
-       if (!test_bit(cpu, &cpu_callin_map))
+       if (!test_bit(cpu, &cpu_callin_map)) { 
+               local_irq_enable();
                return -EIO;
+       }
+       local_irq_enable();
 
        /* Unleash the CPU! */
        Dprintk("waiting for cpu %d\n", cpu);
diff --git a/arch/x86_64/kernel/suspend.c b/arch/x86_64/kernel/suspend.c
new file mode 100644 (file)
index 0000000..a209202
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ * Suspend support specific for i386.
+ *
+ * Distribute under GPLv2
+ *
+ * Copyright (c) 2002 Pavel Machek <pavel@suse.cz>
+ * Copyright (c) 2001 Patrick Mochel <mochel@osdl.org>
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/spinlock.h>
+#include <linux/poll.h>
+#include <linux/delay.h>
+#include <linux/sysrq.h>
+#include <linux/compatmac.h>
+#include <linux/proc_fs.h>
+#include <linux/irq.h>
+#include <linux/pm.h>
+#include <linux/device.h>
+#include <linux/suspend.h>
+#include <asm/uaccess.h>
+#include <asm/acpi.h>
+#include <asm/tlbflush.h>
+#include <asm/io.h>
+
+static struct saved_context saved_context;
+
+unsigned long saved_context_eax, saved_context_ebx, saved_context_ecx, saved_context_edx;
+unsigned long saved_context_esp, saved_context_ebp, saved_context_esi, saved_context_edi;
+unsigned long saved_context_r08, saved_context_r09, saved_context_r10, saved_context_r11;
+unsigned long saved_context_r12, saved_context_r13, saved_context_r14, saved_context_r15;
+unsigned long saved_context_eflags;
+
+void save_processor_state (void)
+{
+       kernel_fpu_begin();
+
+       /*
+        * descriptor tables
+        */
+       asm volatile ("sgdt %0" : "=m" (saved_context.gdt_limit));
+       asm volatile ("sidt %0" : "=m" (saved_context.idt_limit));
+       asm volatile ("sldt %0" : "=m" (saved_context.ldt));
+       asm volatile ("str %0"  : "=m" (saved_context.tr));
+
+       /* XMM0..XMM15 should be handled by kernel_fpu_begin(). */
+       /* EFER should be constant for kernel version, no need to handle it. */
+       /*
+        * segment registers
+        */
+       asm volatile ("movw %%ds, %0" : "=m" (saved_context.ds));
+       asm volatile ("movw %%es, %0" : "=m" (saved_context.es));
+       asm volatile ("movw %%fs, %0" : "=m" (saved_context.fs));
+       asm volatile ("movw %%gs, %0" : "=m" (saved_context.gs));
+       asm volatile ("movw %%ss, %0" : "=m" (saved_context.ss));
+
+       asm volatile ("swapgs");
+       rdmsrl(0xc0000100, saved_context.fs_base);
+       rdmsrl(0xc0000101, saved_context.gs_base);
+       asm volatile ("swapgs");
+
+       /*
+        * control registers 
+        */
+       asm volatile ("movq %%cr0, %0" : "=r" (saved_context.cr0));
+       asm volatile ("movq %%cr2, %0" : "=r" (saved_context.cr2));
+       asm volatile ("movq %%cr3, %0" : "=r" (saved_context.cr3));
+       asm volatile ("movq %%cr4, %0" : "=r" (saved_context.cr4));
+}
+
+static void
+do_fpu_end(void)
+{
+        /* restore FPU regs if necessary */
+       /* Do it out of line so that gcc does not move cr0 load to some stupid place */
+        kernel_fpu_end();
+}
+
+void restore_processor_state(void)
+{
+       /*
+        * control registers
+        */
+       asm volatile ("movq %0, %%cr4" :: "r" (saved_context.cr4));
+       asm volatile ("movq %0, %%cr3" :: "r" (saved_context.cr3));
+       asm volatile ("movq %0, %%cr2" :: "r" (saved_context.cr2));
+       asm volatile ("movq %0, %%cr0" :: "r" (saved_context.cr0));
+
+       /*
+        * segment registers
+        */
+       asm volatile ("movw %0, %%ds" :: "r" (saved_context.ds));
+       asm volatile ("movw %0, %%es" :: "r" (saved_context.es));
+       asm volatile ("movw %0, %%fs" :: "r" (saved_context.fs));
+       load_gs_index(saved_context.gs);
+       asm volatile ("movw %0, %%ss" :: "r" (saved_context.ss));
+
+       asm volatile ("swapgs");
+       wrmsrl(0xc0000100, saved_context.fs_base);
+       wrmsrl(0xc0000101, saved_context.gs_base);
+       asm volatile ("swapgs");
+
+       /*
+        * now restore the descriptor tables to their proper values
+        * ltr is done i fix_processor_context().
+        */
+       asm volatile ("lgdt %0" :: "m" (saved_context.gdt_limit));
+       asm volatile ("lidt %0" :: "m" (saved_context.idt_limit));
+       asm volatile ("lldt %0" :: "m" (saved_context.ldt));
+
+       fix_processor_context();
+
+       do_fpu_end();
+}
+
+void fix_processor_context(void)
+{
+       int cpu = smp_processor_id();
+       struct tss_struct * t = init_tss + cpu;
+
+       printk("Should fix processor context!\n");
+       load_LDT(&current->mm->context);        /* This does lldt */
+
+       /*
+        * Now maybe reload the debug registers
+        */
+       if (current->thread.debugreg[7]){
+                loaddebug(&current->thread, 0);
+                loaddebug(&current->thread, 1);
+                loaddebug(&current->thread, 2);
+                loaddebug(&current->thread, 3);
+                /* no 4 and 5 */
+                loaddebug(&current->thread, 6);
+                loaddebug(&current->thread, 7);
+       }
+
+}
+
+
diff --git a/arch/x86_64/kernel/suspend_asm.S b/arch/x86_64/kernel/suspend_asm.S
new file mode 100644 (file)
index 0000000..0a97d4e
--- /dev/null
@@ -0,0 +1,125 @@
+/* originally gcc generated, but now changed. don't overwrite. */
+       
+       .text
+#include <linux/linkage.h>
+#include <asm/segment.h>
+#include <asm/page.h>
+
+/* Input:
+ * rdi resume flag 
+ */    
+                       
+ENTRY(do_magic)
+.LFB5:
+       subq    $8, %rsp
+.LCFI2:
+       testl   %edi, %edi
+       jne     .L90
+       call    do_magic_suspend_1
+       call    save_processor_state
+
+       movq %rsp, saved_context_esp(%rip)
+       movq %rax, saved_context_eax(%rip)
+       movq %rbx, saved_context_ebx(%rip)
+       movq %rcx, saved_context_ecx(%rip)
+       movq %rdx, saved_context_edx(%rip)
+       movq %rbp, saved_context_ebp(%rip)
+       movq %rsi, saved_context_esi(%rip)
+       movq %rdi, saved_context_edi(%rip)
+       movq %r8,  saved_context_r08(%rip)
+       movq %r9,  saved_context_r09(%rip)
+       movq %r10, saved_context_r10(%rip)
+       movq %r11, saved_context_r11(%rip)
+       movq %r12, saved_context_r12(%rip)
+       movq %r13, saved_context_r13(%rip)
+       movq %r14, saved_context_r14(%rip)
+       movq %r15, saved_context_r15(%rip)
+       pushfq ; popq saved_context_eflags(%rip)
+
+       addq    $8, %rsp
+       jmp     do_magic_suspend_2
+.L90:
+       /* set up cr3 */        
+       leaq    init_level4_pgt(%rip),%rax
+       subq    $__START_KERNEL_map,%rax
+       movq %rax,%cr3
+
+       movq    mmu_cr4_features(%rip), %rax
+       movq    %rax, %rdx
+       
+       andq    $~(1<<7), %rdx  # PGE
+       movq %rdx, %cr4;  # turn off PGE     
+       movq %cr3, %rcx;  # flush TLB        
+       movq %rcx, %cr3;                     
+       movq %rax, %cr4;  # turn PGE back on 
+
+       call    do_magic_resume_1
+       movl    nr_copy_pages(%rip), %eax
+       xorl    %ecx, %ecx
+       movq    $0, loop(%rip)
+       testl   %eax, %eax
+       je      .L108
+.L105:
+       xorl    %esi, %esi
+       movq    $0, loop2(%rip)
+       jmp     .L104
+       .p2align 4,,7
+.L111:
+       movq    loop(%rip), %rcx
+.L104:
+       movq    pagedir_nosave(%rip), %rdx
+       movq    %rcx, %rax
+       salq    $5, %rax
+       movq    8(%rdx,%rax), %rcx
+       movq    (%rdx,%rax), %rax
+       movzbl  (%rsi,%rax), %eax
+       movb    %al, (%rsi,%rcx)
+
+       movq %cr3, %rax;  # flush TLB 
+       movq %rax, %cr3;              
+
+       movq    loop2(%rip), %rax
+       incq    %rax
+       cmpq    $4095, %rax
+       movq    %rax, %rsi
+       movq    %rax, loop2(%rip)
+       jbe     .L111
+       movq    loop(%rip), %rax
+       incq    %rax
+       movq    %rax, %rcx
+       movq    %rax, loop(%rip)
+       mov     nr_copy_pages(%rip), %eax
+       cmpq    %rax, %rcx
+       jb      .L105
+.L108:
+       .align 4
+       movl    $24, %eax
+
+       movl %eax, %ds
+       movq saved_context_esp(%rip), %rsp
+       movq saved_context_ebp(%rip), %rbp
+       movq saved_context_eax(%rip), %rax
+       movq saved_context_ebx(%rip), %rbx
+       movq saved_context_ecx(%rip), %rcx
+       movq saved_context_edx(%rip), %rdx
+       movq saved_context_esi(%rip), %rsi
+       movq saved_context_edi(%rip), %rdi
+       movq saved_context_r08(%rip), %r8
+       movq saved_context_r09(%rip), %r9
+       movq saved_context_r10(%rip), %r10
+       movq saved_context_r11(%rip), %r11
+       movq saved_context_r12(%rip), %r12
+       movq saved_context_r13(%rip), %r13
+       movq saved_context_r14(%rip), %r14
+       movq saved_context_r15(%rip), %r15
+       pushq saved_context_eflags(%rip) ; popfq
+       call    restore_processor_state
+       addq    $8, %rsp
+       jmp     do_magic_resume_2
+
+       .section .data.nosave
+loop:
+       .quad 0
+loop2: 
+       .quad 0         
+       .previous
\ No newline at end of file
index d90596e4364c54fd6b33e3f82dab433f60c42dfa..21b3fbd5330e7c0c18b1a3c3d9e4028e8938f373 100644 (file)
@@ -83,22 +83,18 @@ static int kstack_depth_to_print = 10;
 #include <linux/kallsyms.h> 
 int printk_address(unsigned long address)
 { 
-       unsigned long dummy; 
-       const char *modname, *secname, *symname;
-       unsigned long symstart; 
+       unsigned long offset = 0, symsize;
+       const char *symname;
+       char *modname;
        char *delim = ":"; 
 
-       /* What a function call! */
-       if (!kallsyms_address_to_symbol(address, 
-                                       &modname, &dummy, &dummy, 
-                                       &secname, &dummy, &dummy,
-                                       &symname, &symstart, &dummy)) {
+       symname = kallsyms_lookup(address, &symsize, &offset, &modname); 
+       if (!symname) 
                return printk("[<%016lx>]", address);
-       } 
-       if (!strcmp(modname, "kernel"))
+       if (!modname) 
                modname = delim = "";           
         return printk("<%016lx>{%s%s%s%s%+ld}",
-                     address,delim,modname,delim,symname,address-symstart); 
+                     address,delim,modname,delim,symname,offset); 
 } 
 #else
 int printk_address(unsigned long address)
@@ -110,7 +106,8 @@ int printk_address(unsigned long address)
 
 #ifdef CONFIG_MODULES
 
-extern struct module kernel_module;
+/* FIXME: Accessed without a lock --RR */
+extern struct list_head modules;
 
 static inline int kernel_text_address(unsigned long addr)
 {
@@ -121,11 +118,11 @@ static inline int kernel_text_address(unsigned long addr)
        addr <= (unsigned long) &_etext)
        return 1;
 
-   for (mod = module_list; mod != &kernel_module; mod = mod->next) {
+   list_for_each_entry(mod, &modules, list) {  
        /* mod_bound tests for addr being inside the vmalloc'ed
         * module area. Of course it'd be better to test only
         * for the .text subset... */
-       if (mod_bound(addr, 0, mod)) {
+       if (mod_bound((void *)addr, 0, mod)) {
            retval = 1;
            break;
        }
@@ -173,7 +170,7 @@ void show_trace(unsigned long *stack)
        int i;
 
        printk("\nCall Trace:");
-       i = 12
+       i = 0
        
        estack_end = in_exception_stack(cpu, (unsigned long)stack); 
        if (estack_end) { 
index 6efa7c582cf227933eae970b4b68416cdde76241..7d2700fbbedd06b78a6b205efb5be044407c9a6c 100644 (file)
@@ -2,7 +2,6 @@
 #include <linux/module.h>
 #include <linux/smp.h>
 #include <linux/user.h>
-#include <linux/mca.h>
 #include <linux/sched.h>
 #include <linux/in6.h>
 #include <linux/interrupt.h>
@@ -46,7 +45,7 @@ extern unsigned long get_cmos_time(void);
 
 /* platform dependent support */
 EXPORT_SYMBOL(boot_cpu_data);
-EXPORT_SYMBOL(dump_fpu);
+//EXPORT_SYMBOL(dump_fpu);
 EXPORT_SYMBOL(__ioremap);
 EXPORT_SYMBOL(ioremap_nocache);
 EXPORT_SYMBOL(iounmap);
@@ -120,10 +119,6 @@ EXPORT_SYMBOL(smp_call_function);
 
 #endif
 
-#ifdef CONFIG_MCA
-EXPORT_SYMBOL(machine_id);
-#endif
-
 #ifdef CONFIG_VT
 EXPORT_SYMBOL(screen_info);
 #endif
@@ -199,3 +194,6 @@ void out_of_line_bug(void);
 EXPORT_SYMBOL(out_of_line_bug);
 
 EXPORT_SYMBOL(init_level4_pgt);
+
+extern unsigned long __supported_pte_mask;
+EXPORT_SYMBOL(__supported_pte_mask);
index fe428878e108a4355600826b28c5f799ebd9ab3c..59f00b21755de694191ce4155ef378fb693e598a 100644 (file)
@@ -2,12 +2,12 @@
 #include <asm/io.h>
 #include <linux/module.h>
 
-void *memcpy_toio(void *dst,void*src,unsigned len)
+void *memcpy_toio(void *dst,const void*src,unsigned len)
 {
        return __inline_memcpy(__io_virt(dst),src,len);
 }
 
-void *memcpy_fromio(void *dst,void*src,unsigned len)
+void *memcpy_fromio(void *dst,const void*src,unsigned len)
 {
        return __inline_memcpy(dst,__io_virt(src),len);
 }
index 453941a07a1232f6c8c873df7952c80f23741f45..4bafd50454616fe54b0e4da566ebee5891e484d4 100644 (file)
@@ -30,7 +30,7 @@ do {                                                                     \
                "       jmp 2b\n"                                          \
                ".previous\n"                                              \
                ".section __ex_table,\"a\"\n"                              \
-               "       .align 4\n"                                        \
+               "       .align 8\n"                                        \
                "       .quad 0b,3b\n"                                     \
                ".previous"                                                \
                : "=r"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1),      \
index 0e9a4291375ed918b6a0ef76bdae55df70ae30cc..2faebe3fad25e40fe9ae804dfb37031da6a85991 100644 (file)
@@ -5,3 +5,4 @@
 export-objs := pageattr.o
 
 obj-y   := init.o fault.o ioremap.o extable.o modutil.o pageattr.o
+obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
index de7a59fca645fc498e4199ba7da4cd1b0bb807c6..710426864f3bb36d95ccd491e43dfebdb9a42947 100644 (file)
@@ -62,14 +62,16 @@ search_exception_table(unsigned long addr)
        return search_one_table(__start___ex_table, __stop___ex_table-1, addr);
 #else
        /* The kernel is the last "module" -- no need to treat it special.  */
-       struct module *mp;
+       struct list_head *i;
 
        spin_lock_irqsave(&modlist_lock, flags);
-       for (mp = module_list; mp != NULL; mp = mp->next) {
-               if (mp->ex_table_start == NULL || !(mp->flags&(MOD_RUNNING|MOD_INITIALIZING)))
+       list_for_each(i, &extables) { 
+               struct exception_table *ex = 
+                       list_entry(i,struct exception_table, list); 
+               if (ex->num_entries == 0) 
                        continue;
-               ret = search_one_table(mp->ex_table_start,
-                                      mp->ex_table_end - 1, addr);
+               ret = search_one_table(ex->entry,
+                                      ex->entry + ex->num_entries - 1, addr);
                if (ret)
                        break;
        }
index 8faa403b596aa3bfaa785134ffd607c07d2eb20d..5f93c2d6ba2fbd6468cf31dc3595b33cd302e2df 100644 (file)
@@ -300,6 +300,9 @@ vmalloc_fault:
                pmd_t *pmd;
                pte_t *pte; 
 
+               printk("vmalloc_fault err %lx addr %lx rip %lx\n", 
+                      error_code, address, regs->rip);
+
                /*
                 * x86-64 has the same kernel 3rd level pages for all CPUs.
                 * But for vmalloc/modules the TLB synchronization works lazily,
diff --git a/arch/x86_64/mm/hugetlbpage.c b/arch/x86_64/mm/hugetlbpage.c
new file mode 100644 (file)
index 0000000..bf5ea47
--- /dev/null
@@ -0,0 +1,360 @@
+/*
+ * x86-64 Huge TLB Page Support for Kernel.
+ *
+ * Copyright (C) 2002, Rohit Seth <rohit.seth@intel.com>
+ * Minor hacks by Andi Kleen for x86-64
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/hugetlb.h>
+#include <linux/pagemap.h>
+#include <linux/smp_lock.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/sysctl.h>
+#include <asm/mman.h>
+#include <asm/pgalloc.h>
+#include <asm/tlb.h>
+#include <asm/tlbflush.h>
+
+static long    htlbpagemem;
+int     htlbpage_max;
+static long    htlbzone_pages;
+
+struct vm_operations_struct hugetlb_vm_ops;
+static LIST_HEAD(htlbpage_freelist);
+static spinlock_t htlbpage_lock = SPIN_LOCK_UNLOCKED;
+
+static struct page *alloc_hugetlb_page(void)
+{
+       int i;
+       struct page *page;
+
+       spin_lock(&htlbpage_lock);
+       if (list_empty(&htlbpage_freelist)) {
+               spin_unlock(&htlbpage_lock);
+               return NULL;
+       }
+
+       page = list_entry(htlbpage_freelist.next, struct page, list);
+       list_del(&page->list);
+       htlbpagemem--;
+       spin_unlock(&htlbpage_lock);
+       set_page_count(page, 1);
+       for (i = 0; i < (HPAGE_SIZE/PAGE_SIZE); ++i)
+               clear_highpage(&page[i]);
+       return page;
+}
+
+static pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr)
+{
+       pgd_t *pgd;
+       pmd_t *pmd = NULL;
+
+       pgd = pgd_offset(mm, addr);
+       pmd = pmd_alloc(mm, pgd, addr);
+       return (pte_t *) pmd;
+}
+
+static pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr)
+{
+       pgd_t *pgd;
+       pmd_t *pmd = NULL;
+
+       pgd = pgd_offset(mm, addr);
+       pmd = pmd_offset(pgd, addr);
+       return (pte_t *) pmd;
+}
+
+#define mk_pte_huge(entry) {pte_val(entry) |= (_PAGE_PRESENT | _PAGE_PSE);}
+
+static void set_huge_pte(struct mm_struct *mm, struct vm_area_struct *vma, struct page *page, pte_t * page_table, int write_access)
+{
+       pte_t entry;
+
+       mm->rss += (HPAGE_SIZE / PAGE_SIZE);
+       if (write_access) {
+               entry =
+                   pte_mkwrite(pte_mkdirty(mk_pte(page, vma->vm_page_prot)));
+       } else
+               entry = pte_wrprotect(mk_pte(page, vma->vm_page_prot));
+       entry = pte_mkyoung(entry);
+       mk_pte_huge(entry);
+       set_pte(page_table, entry);
+}
+
+int
+copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src,
+                       struct vm_area_struct *vma)
+{
+       pte_t *src_pte, *dst_pte, entry;
+       struct page *ptepage;
+       unsigned long addr = vma->vm_start;
+       unsigned long end = vma->vm_end;
+
+       while (addr < end) {
+               dst_pte = huge_pte_alloc(dst, addr);
+               if (!dst_pte)
+                       goto nomem;
+               src_pte = huge_pte_offset(src, addr);
+               entry = *src_pte;
+               ptepage = pte_page(entry);
+               get_page(ptepage);
+               set_pte(dst_pte, entry);
+               dst->rss += (HPAGE_SIZE / PAGE_SIZE);
+               addr += HPAGE_SIZE;
+       }
+       return 0;
+
+nomem:
+       return -ENOMEM;
+}
+
+int
+follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma,
+                   struct page **pages, struct vm_area_struct **vmas,
+                   unsigned long *st, int *length, int i)
+{
+       pte_t *ptep, pte;
+       unsigned long start = *st;
+       unsigned long pstart;
+       int len = *length;
+       struct page *page;
+
+       do {
+               pstart = start;
+               ptep = huge_pte_offset(mm, start);
+               pte = *ptep;
+
+back1:
+               page = pte_page(pte);
+               if (pages) {
+                       page += ((start & ~HPAGE_MASK) >> PAGE_SHIFT);
+                       pages[i] = page;
+               }
+               if (vmas)
+                       vmas[i] = vma;
+               i++;
+               len--;
+               start += PAGE_SIZE;
+               if (((start & HPAGE_MASK) == pstart) && len &&
+                               (start < vma->vm_end))
+                       goto back1;
+       } while (len && start < vma->vm_end);
+       *length = len;
+       *st = start;
+       return i;
+}
+
+void free_huge_page(struct page *page)
+{
+       BUG_ON(page_count(page));
+       BUG_ON(page->mapping);
+
+       INIT_LIST_HEAD(&page->list);
+
+       spin_lock(&htlbpage_lock);
+       list_add(&page->list, &htlbpage_freelist);
+       htlbpagemem++;
+       spin_unlock(&htlbpage_lock);
+}
+
+void huge_page_release(struct page *page)
+{
+       if (!put_page_testzero(page))
+               return;
+
+       free_huge_page(page);
+}
+
+void unmap_hugepage_range(struct vm_area_struct *vma, unsigned long start, unsigned long end)
+{
+       struct mm_struct *mm = vma->vm_mm;
+       unsigned long address;
+       pte_t *pte;
+       struct page *page;
+
+       BUG_ON(start & (HPAGE_SIZE - 1));
+       BUG_ON(end & (HPAGE_SIZE - 1));
+
+       spin_lock(&htlbpage_lock);
+       spin_unlock(&htlbpage_lock);
+       for (address = start; address < end; address += HPAGE_SIZE) {
+               pte = huge_pte_offset(mm, address);
+               page = pte_page(*pte);
+               huge_page_release(page);
+               pte_clear(pte);
+       }
+       mm->rss -= (end - start) >> PAGE_SHIFT;
+       flush_tlb_range(vma, start, end);
+}
+
+void zap_hugepage_range(struct vm_area_struct *vma, unsigned long start, unsigned long length)
+{
+       struct mm_struct *mm = vma->vm_mm;
+       spin_lock(&mm->page_table_lock);
+       unmap_hugepage_range(vma, start, start + length);
+       spin_unlock(&mm->page_table_lock);
+}
+
+int hugetlb_prefault(struct address_space *mapping, struct vm_area_struct *vma)
+{
+       struct mm_struct *mm = current->mm;
+       unsigned long addr;
+       int ret = 0;
+
+       BUG_ON(vma->vm_start & ~HPAGE_MASK);
+       BUG_ON(vma->vm_end & ~HPAGE_MASK);
+
+       spin_lock(&mm->page_table_lock);
+       for (addr = vma->vm_start; addr < vma->vm_end; addr += HPAGE_SIZE) {
+               unsigned long idx;
+               pte_t *pte = huge_pte_alloc(mm, addr);
+               struct page *page;
+
+               if (!pte) {
+                       ret = -ENOMEM;
+                       goto out;
+               }
+               if (!pte_none(*pte))
+                       continue;
+
+               idx = ((addr - vma->vm_start) >> HPAGE_SHIFT)
+                       + (vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT));
+               page = find_get_page(mapping, idx);
+               if (!page) {
+                       page = alloc_hugetlb_page();
+                       if (!page) {
+                               ret = -ENOMEM;
+                               goto out;
+                       }
+                       add_to_page_cache(page, mapping, idx);
+                       unlock_page(page);
+               }
+               set_huge_pte(mm, vma, page, pte, vma->vm_flags & VM_WRITE);
+       }
+out:
+       spin_unlock(&mm->page_table_lock);
+       return ret;
+}
+
+int set_hugetlb_mem_size(int count)
+{
+       int j, lcount;
+       struct page *page, *map;
+       extern long htlbzone_pages;
+       extern struct list_head htlbpage_freelist;
+
+       if (count < 0)
+               lcount = count;
+       else
+               lcount = count - htlbzone_pages;
+
+       if (lcount > 0) {       /* Increase the mem size. */
+               while (lcount--) {
+                       page = alloc_pages(__GFP_HIGHMEM, HUGETLB_PAGE_ORDER);
+                       if (page == NULL)
+                               break;
+                       map = page;
+                       for (j = 0; j < (HPAGE_SIZE / PAGE_SIZE); j++) {
+                               SetPageReserved(map);
+                               map++;
+                       }
+                       spin_lock(&htlbpage_lock);
+                       list_add(&page->list, &htlbpage_freelist);
+                       htlbpagemem++;
+                       htlbzone_pages++;
+                       spin_unlock(&htlbpage_lock);
+               }
+               return (int) htlbzone_pages;
+       }
+       /* Shrink the memory size. */
+       while (lcount++) {
+               page = alloc_hugetlb_page();
+               if (page == NULL)
+                       break;
+               spin_lock(&htlbpage_lock);
+               htlbzone_pages--;
+               spin_unlock(&htlbpage_lock);
+               map = page;
+               for (j = 0; j < (HPAGE_SIZE / PAGE_SIZE); j++) {
+                       map->flags &= ~(1 << PG_locked | 1 << PG_error | 1 << PG_referenced |
+                                       1 << PG_dirty | 1 << PG_active | 1 << PG_reserved |
+                                       1 << PG_private | 1<< PG_writeback);
+                       set_page_count(map, 0);
+                       map++;
+               }
+               set_page_count(page, 1);
+               __free_pages(page, HUGETLB_PAGE_ORDER);
+       }
+       return (int) htlbzone_pages;
+}
+
+/* This will likely not work because of fragmentation. */ 
+int hugetlb_sysctl_handler(ctl_table *table, int write, struct file *file, void *buffer, size_t *length)
+{
+       proc_dointvec(table, write, file, buffer, length);
+       htlbpage_max = set_hugetlb_mem_size(htlbpage_max);
+       return 0;
+}
+
+static int __init hugetlb_setup(char *s)
+{
+       if (sscanf(s, "%d", &htlbpage_max) <= 0)
+               htlbpage_max = 0;
+       return 1;
+}
+__setup("hugepages=", hugetlb_setup);
+
+static int __init hugetlb_init(void)
+{
+       int i, j;
+       struct page *page;
+
+       for (i = 0; i < htlbpage_max; ++i) {
+               page = alloc_pages(__GFP_HIGHMEM, HUGETLB_PAGE_ORDER);
+               if (!page)
+                       break;
+               for (j = 0; j < HPAGE_SIZE/PAGE_SIZE; ++j)
+                       SetPageReserved(&page[j]);
+               spin_lock(&htlbpage_lock);
+               list_add(&page->list, &htlbpage_freelist);
+               spin_unlock(&htlbpage_lock);
+       }
+       htlbpage_max = htlbpagemem = htlbzone_pages = i;
+       printk("Total HugeTLB memory allocated, %ld\n", htlbpagemem);
+       return 0;
+}
+module_init(hugetlb_init);
+
+int hugetlb_report_meminfo(char *buf)
+{
+       return sprintf(buf,
+                       "HugePages_Total: %5lu\n"
+                       "HugePages_Free:  %5lu\n"
+                       "Hugepagesize:    %5lu kB\n",
+                       htlbzone_pages,
+                       htlbpagemem,
+                       HPAGE_SIZE/1024);
+}
+
+static struct page * hugetlb_nopage(struct vm_area_struct * area, unsigned long address, int unused)
+{
+       BUG();
+       return NULL;
+}
+
+struct vm_operations_struct hugetlb_vm_ops = {
+       .nopage = hugetlb_nopage,
+};
+
+int is_hugepage_mem_enough(size_t size)
+{
+       if (size > (htlbpagemem << HPAGE_SHIFT))
+               return 0;
+       return 1;
+}
index e48c5b92707050aa17d56a17313ac0f25b8be4ff..914738b3355e702178659f22abf4ca0477c6f1b1 100644 (file)
@@ -223,7 +223,8 @@ static void __init phys_pgd_init(pgd_t *pgd, unsigned long address, unsigned lon
                                        set_pmd(pmd,  __pmd(0)); 
                                break;
                }
-                       pe = _PAGE_PSE | _KERNPG_TABLE | _PAGE_GLOBAL | paddr;
+                       pe = _PAGE_NX|_PAGE_PSE | _KERNPG_TABLE | _PAGE_GLOBAL | paddr;
+                       pe &= __supported_pte_mask;
                        set_pmd(pmd, __pmd(pe));
                }
                unmap_low_page(map);
index 5a5827166a04df9bef0c68c87c93c4559977ee2e..83584e6621b0ed585188977ac14d41bebc287dcf 100644 (file)
  
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
+#include <linux/module.h>
+#include <linux/err.h>
 
 #include <asm/uaccess.h>
 #include <asm/system.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
 
-static struct vm_struct * modvmlist = NULL;
-
-void module_unmap (void * addr)
+/* FIXME: If module_region == mod->init_region, trim exception
+   table entries. */
+void module_free(struct module *mod, void *module_region)
 {
        struct vm_struct **p, *tmp;
        int i;
+       unsigned long addr = (unsigned long)module_region;
 
        if (!addr)
                return;
-       if ((PAGE_SIZE-1) & (unsigned long) addr) {
-               printk("Trying to unmap module with bad address (%p)\n", addr);
+       if ((PAGE_SIZE-1) & addr) {
+               printk("Trying to unmap module with bad address (%lx)\n", addr);
                return;
        }
-       for (p = &modvmlist ; (tmp = *p) ; p = &tmp->next) {
-               if (tmp->addr == addr) {
+       write_lock(&vmlist_lock); 
+       for (p = &vmlist ; (tmp = *p) ; p = &tmp->next) {
+               if ((unsigned long)tmp->addr == addr) {
                        *p = tmp->next;
+                       write_unlock(&vmlist_lock); 
                        goto found;
                }
        }
-       printk("Trying to unmap nonexistent module vm area (%p)\n", addr);
+       write_unlock(&vmlist_lock); 
+       printk("Trying to unmap nonexistent module vm area (%lx)\n", addr);
        return;
  found:
        unmap_vm_area(tmp);
@@ -49,29 +55,31 @@ void module_unmap (void * addr)
        kfree(tmp);                                     
 }
 
-void * module_map (unsigned long size)
+void * module_alloc (unsigned long size)
 {
        struct vm_struct **p, *tmp, *area;
        struct page **pages;
        void * addr;
        unsigned int nr_pages, array_size, i;
 
-       size = PAGE_ALIGN(size);
-       if (!size || size > MODULES_LEN)
+       if (!size)
                return NULL;
+       size = PAGE_ALIGN(size);
+       if (size > MODULES_LEN)
+               return ERR_PTR(-ENOMEM);
                
        addr = (void *) MODULES_VADDR;
-       for (p = &modvmlist; (tmp = *p) ; p = &tmp->next) {
+       for (p = &vmlist; (tmp = *p) ; p = &tmp->next) {
                if (size + (unsigned long) addr < (unsigned long) tmp->addr)
                        break;
                addr = (void *) (tmp->size + (unsigned long) tmp->addr);
        }
        if ((unsigned long) addr + size >= MODULES_END)
-               return NULL;
+               return ERR_PTR(-ENOMEM);
        
        area = (struct vm_struct *) kmalloc(sizeof(*area), GFP_KERNEL);
        if (!area)
-               return NULL;
+               return ERR_PTR(-ENOMEM);
        area->size = size + PAGE_SIZE;
        area->addr = addr;
        area->next = *p;
@@ -96,11 +104,12 @@ void * module_map (unsigned long size)
                        goto fail;
        }
        
-       if (map_vm_area(area, PAGE_KERNEL, &pages)) {
+       if (map_vm_area(area, PAGE_KERNEL_EXECUTABLE, &pages)) {
                unmap_vm_area(area);
                goto fail;
        }
 
+       memset(area->addr, 0, size);
        return area->addr;
 
 fail:
@@ -113,6 +122,6 @@ fail:
        }
        kfree(area);
 
-       return NULL;
+       return ERR_PTR(-ENOMEM);
 }
 
index ff25ac6ba134c0bec6e9a4609169945ad90a7595..f77e1494c3194bae542bc125ae4ceec3e565f48f 100644 (file)
@@ -94,6 +94,11 @@ static void __devinit pcibios_fixup_ghosts(struct pci_bus *b)
        }
 }
 
+void __devinit
+pcibios_fixup_pbus_ranges (struct pci_bus *bus, struct pbus_set_ranges_data *ranges)
+{
+}
+
 /*
  *  Called after each bus is probed, but before its children
  *  are examined.
index 83939631d676a7e3326f049e322cc3fbc2e24003..50cae3df23328ebc3b3ffd5b59b8e0cad6f4f569 100644 (file)
@@ -151,30 +151,7 @@ static void write_config_nybble(struct pci_dev *router, unsigned offset, unsigne
        pci_write_config_byte(router, reg, x);
 }
 
-/*
- * ALI pirq entries are damn ugly, and completely undocumented.
- * This has been figured out from pirq tables, and it's not a pretty
- * picture.
- */
-static int pirq_ali_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
-{
-       static unsigned char irqmap[16] = { 0, 9, 3, 10, 4, 5, 7, 6, 1, 11, 0, 12, 0, 14, 0, 15 };
-
-       return irqmap[read_config_nybble(router, 0x48, pirq-1)];
-}
-
-static int pirq_ali_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
-{
-       static unsigned char irqmap[16] = { 0, 8, 0, 2, 4, 5, 7, 6, 0, 1, 3, 9, 11, 0, 13, 15 };
-       unsigned int val = irqmap[irq];
-               
-       if (val) {
-               write_config_nybble(router, 0x48, pirq-1, val);
-               return 1;
-       }
-       return 0;
-}
-
+#if 0 /* enable when pci ids ae known */
 /*
  * The VIA pirq rules are nibble-based, like ALI,
  * but without the ugly irq number munging.
@@ -296,6 +273,8 @@ static int pirq_sis_set(struct pci_dev *router, struct pci_dev *dev, int pirq, i
        return 1;
 }
 
+#endif
+
 /* Support for AMD756 PCI IRQ Routing
  * Jhon H. Caicedo <jhcaiced@osso.org.co>
  * Jun/21/2001 0.2.0 Release, fixed to use "nybble" functions... (jhcaiced)
@@ -529,7 +508,7 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign)
        return 1;
 }
 
-static void __init pcibios_fixup_irqs(void)
+void __init pcibios_fixup_irqs(void)
 {
        struct pci_dev *dev;
        u8 pin;
@@ -641,7 +620,6 @@ int pirq_enable_irq(struct pci_dev *dev)
        u8 pin;
        pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
        if (pin && !pcibios_lookup_irq(dev, 1) && !dev->irq) {
-               char *msg;
                printk(KERN_WARNING "PCI: No IRQ known for interrupt pin %c of device %s.\n",
                       'A' + pin - 1, dev->slot_name);
        }
index 20ececfb3985513f76b2362227fb020bb0f1e589..08d1a8696e2d0977d9984f0c7eeadd74d245fb3f 100644 (file)
@@ -26,6 +26,7 @@ SECTIONS
   __ex_table : { *(__ex_table) }
   __stop___ex_table = .;
 
+  . = ALIGN(64); 
   __start___ksymtab = .;       /* Kernel symbol table */
   __ksymtab : { *(__ksymtab) }
   __stop___ksymtab = .;
@@ -79,6 +80,11 @@ SECTIONS
   . = ALIGN(4096); 
   .data.boot_pgt : { *(.data.boot_pgt) }
 
+  . = ALIGN(4096);
+  __initramfs_start = .;
+  .init.ramfs : { *(.init.ramfs) }
+  __initramfs_end = .;
+       
   . = ALIGN(4096);             /* Init code and data */
   __init_begin = .;
   .init.text : { *(.init.text) }
@@ -87,6 +93,9 @@ SECTIONS
   __setup_start = .;
   .init.setup : { *(.init.setup) }
   __setup_end = .;
+  __start___param = .;
+  __param : { *(__param) }
+  __stop___param = .;
   __initcall_start = .;
   .initcall.init : {
        *(.initcall1.init) 
@@ -105,6 +114,12 @@ SECTIONS
   . = ALIGN(4096);
   __init_end = .;
 
+  . = ALIGN(4096);
+  __nosave_begin = .;
+  .data_nosave : { *(.data.nosave) }
+  . = ALIGN(4096);
+  __nosave_end = .;
+
   _end = . ;
 
   /* Sections to be discarded */
index 4ea5626d2e8475d3907b91ba1920c00facbf99fe..72e575a68a331f1f406a1bb2a0b9cfff21f4fb7c 100644 (file)
@@ -89,7 +89,7 @@ static __inline__ void __clear_bit(int nr, volatile void * addr)
 
 /**
  * __change_bit - Toggle a bit in memory
- * @nr: the bit to set
+ * @nr: the bit to change
  * @addr: the address to start counting from
  *
  * Unlike change_bit(), this function is non-atomic and may be reordered.
@@ -106,7 +106,7 @@ static __inline__ void __change_bit(int nr, volatile void * addr)
 
 /**
  * change_bit - Toggle a bit in memory
- * @nr: Bit to clear
+ * @nr: Bit to change
  * @addr: Address to start counting from
  *
  * change_bit() is atomic and may not be reordered.
@@ -162,7 +162,7 @@ static __inline__ int __test_and_set_bit(int nr, volatile void * addr)
 
 /**
  * test_and_clear_bit - Clear a bit and return its old value
- * @nr: Bit to set
+ * @nr: Bit to clear
  * @addr: Address to count from
  *
  * This operation is atomic and cannot be reordered.  
@@ -181,7 +181,7 @@ static __inline__ int test_and_clear_bit(int nr, volatile void * addr)
 
 /**
  * __test_and_clear_bit - Clear a bit and return its old value
- * @nr: Bit to set
+ * @nr: Bit to clear
  * @addr: Address to count from
  *
  * This operation is non-atomic and can be reordered.  
@@ -213,7 +213,7 @@ static __inline__ int __test_and_change_bit(int nr, volatile void * addr)
 
 /**
  * test_and_change_bit - Change a bit and return its new value
- * @nr: Bit to set
+ * @nr: Bit to change
  * @addr: Address to count from
  *
  * This operation is atomic and cannot be reordered.  
@@ -260,6 +260,8 @@ static __inline__ int variable_test_bit(int nr, volatile void * addr)
  constant_test_bit((nr),(addr)) : \
  variable_test_bit((nr),(addr)))
 
+#undef ADDR
+
 /**
  * find_first_zero_bit - find the first zero bit in a memory region
  * @addr: The address to start the search at
index 9afea8132051af9fe666c6358322f99e0d6186ef..8bbf1971fd7bf3f9d73c8a90844acccd9b9419d8 100644 (file)
@@ -29,6 +29,7 @@
 #define RSP 152
 #define SS 160
 #define ARGOFFSET R11
+#define SWFRAME ORIG_RAX
 
        .macro SAVE_ARGS addskip=0,norcx=0      
        subq  $9*8+\addskip,%rsp
        .endm
 
 #define ARG_SKIP 9*8
-       .macro RESTORE_ARGS skiprax=0,addskip=0,skiprcx=0
+       .macro RESTORE_ARGS skiprax=0,addskip=0,skiprcx=0,skipr11=0
+       .if \skipr11
+       .else
        movq (%rsp),%r11
+       .endif
        movq 1*8(%rsp),%r10
        movq 2*8(%rsp),%r9
        movq 3*8(%rsp),%r8
diff --git a/include/asm-x86_64/compat.h b/include/asm-x86_64/compat.h
new file mode 100644 (file)
index 0000000..47e4aa4
--- /dev/null
@@ -0,0 +1,57 @@
+#ifndef _ASM_X86_64_COMPAT_H
+#define _ASM_X86_64_COMPAT_H
+/*
+ * Architecture specific compatibility types
+ */
+#include <linux/types.h>
+
+#define COMPAT_USER_HZ 100
+
+typedef u32            compat_size_t;
+typedef s32            compat_ssize_t;
+typedef s32            compat_time_t;
+typedef s32            compat_suseconds_t;
+typedef s32            compat_clock_t;
+typedef s32            compat_pid_t;
+typedef u16            compat_uid_t;
+typedef u16            compat_gid_t;
+typedef u16            compat_mode_t;
+typedef u32            compat_ino_t;
+typedef u16            compat_dev_t;
+typedef s32            compat_off_t;
+typedef u16            compat_nlink_t;
+
+struct compat_timespec {
+       compat_time_t   tv_sec;
+       s32             tv_nsec;
+};
+
+struct compat_timeval {
+       compat_time_t   tv_sec;
+       s32             tv_usec;
+};
+
+struct compat_stat {
+       compat_dev_t    st_dev;
+       u16             __pad1;
+       compat_ino_t    st_ino;
+       compat_mode_t   st_mode;
+       compat_nlink_t  st_nlink;
+       compat_uid_t    st_uid;
+       compat_gid_t    st_gid;
+       compat_dev_t    st_rdev;
+       u16             __pad2;
+       u32             st_size;
+       u32             st_blksize;
+       u32             st_blocks;
+       u32             st_atime;
+       u32             st_atime_nsec;
+       u32             st_mtime;
+       u32             st_mtime_nsec;
+       u32             st_ctime;
+       u32             st_ctime_nsec;
+       u32             __unused4;
+       u32             __unused5;
+};
+
+#endif /* _ASM_X86_64_COMPAT_H */
index e5353cd3555bd6ac11ed5ddfbd7a658ccc34cbaf..f5775b7ddde535ff0dbf009a815bf28a7cd6da5a 100644 (file)
@@ -165,31 +165,14 @@ static inline void set_ldt_desc(unsigned cpu, void *addr, int size)
 # error update this code.
 #endif
 
-
-static inline u64 load_TLS(struct thread_struct *t, int cpu) 
+static inline void load_TLS(struct thread_struct *t, unsigned int cpu)
 {
-       u64 *p, old, new, change; 
-       union u { 
-               struct desc_struct d;
-               u64 i; 
-       }; 
-       change = 0; 
-
-       /* check assembly! */
-#define C(i) \
-       p = ((u64 *)cpu_gdt_table[cpu]) + GDT_ENTRY_TLS_MIN + i; \
-       old = *p; \
-       new = t->tls_array[i]; \
-       change |= old - new;  \
-       *p = new;
-
-       C(0); C(1); C(2); 
-       return change; 
+       u64 *gdt = (u64 *)(cpu_gdt_table[cpu] + GDT_ENTRY_TLS_MIN);
+       gdt[0] = t->tls_array[0];
+       gdt[1] = t->tls_array[1];
+       gdt[2] = t->tls_array[2];
 } 
 
-#undef C
-
-
 /*
  * load one particular LDT into the current CPU
  */
index 52edff4b2756f0c2d766e6189faa9719f9b99fd2..7d9d5df88456a58f52d97fe7987b50072de5e8bb 100644 (file)
@@ -7,6 +7,7 @@
 
 #include <asm/ptrace.h>
 #include <asm/user.h>
+#include <asm/processor.h>
 
 typedef unsigned long elf_greg_t;
 
@@ -14,7 +15,6 @@ typedef unsigned long elf_greg_t;
 typedef elf_greg_t elf_gregset_t[ELF_NGREG];
 
 typedef struct user_i387_struct elf_fpregset_t;
-typedef struct user_fxsr_struct elf_fpxregset_t;
 
 /*
  * This is used to ensure we don't load something for the wrong architecture.
@@ -123,6 +123,17 @@ typedef struct user_fxsr_struct elf_fpxregset_t;
 extern void set_personality_64bit(void);
 #define SET_PERSONALITY(ex, ibcs2) set_personality_64bit()
        
+extern int dump_task_regs (struct task_struct *, elf_gregset_t *);
+extern int dump_task_fpu (struct task_struct *, elf_fpregset_t *);
+
+#define ELF_CORE_COPY_TASK_REGS(tsk, elf_regs) dump_task_regs(tsk, elf_regs)
+#define ELF_CORE_COPY_FPREGS(tsk, elf_fpregs) dump_task_fpu(tsk, elf_fpregs)
+
+#ifdef CONFIG_SMP
+extern void dump_smp_unlazy_fpu(void);
+#define ELF_CORE_SYNC dump_smp_unlazy_fpu
+#endif
+
 #endif
 
 #endif
index 8c34d3adf97afdf47ae7bcbdd5d0f935fcfe3edd..a9c415b00b896a0a31edd8fa1a43ba6573a1146b 100644 (file)
@@ -77,6 +77,9 @@ typedef struct {
 #define hardirq_endlock()      do { } while (0)
 
 #define irq_enter()            (preempt_count() += HARDIRQ_OFFSET)
+#define nmi_enter()            (irq_enter())
+#define nmi_exit()             (preempt_count() -= HARDIRQ_OFFSET)
+
 
 #if CONFIG_PREEMPT
 # define in_atomic()   ((preempt_count() & ~PREEMPT_ACTIVE) != kernel_locked())
index 2a0292c00b547f715225b2c60f7e00eff3e6d47b..f3d20c00741f75cbcff6ffb3666618a692aa0200 100644 (file)
@@ -43,6 +43,12 @@ static inline int need_signal_i387(struct task_struct *me)
                save_init_fpu(tsk); \
 } while (0)
 
+#define unlazy_current_fpu() do { \
+       if (test_thread_flag(TIF_USEDFPU)) \
+               save_init_fpu(tsk); \
+} while (0)
+
+
 #define clear_fpu(tsk) do { \
        if (test_tsk_thread_flag(tsk, TIF_USEDFPU)) {           \
                asm volatile("fwait");                          \
@@ -64,12 +70,6 @@ extern int get_fpregs(struct user_i387_struct *buf,
 extern int set_fpregs(struct task_struct *tsk,
                      struct user_i387_struct *buf);
 
-/*
- * FPU state for core dumps...
- */
-extern int dump_fpu(struct pt_regs *regs,
-                   struct user_i387_struct *fpu);
-
 /*
  * i387 state interaction
  */
index 23be4a85e41527ae8e9acc5a5b99b9ee77fb8bee..f257195d17406a4991bc0a3dddce2bdefdcacd66 100644 (file)
@@ -5,29 +5,18 @@
 
 #ifdef CONFIG_IA32_EMULATION
 
+#include <linux/compat.h>
+
 /*
  * 32 bit structures for IA32 support.
  */
 
 /* 32bit compatibility types */
-typedef unsigned int          __kernel_size_t32;
-typedef int                   __kernel_ssize_t32;
-typedef int                   __kernel_ptrdiff_t32;
-typedef int                   __kernel_time_t32;
-typedef int                   __kernel_clock_t32;
-typedef int                   __kernel_pid_t32;
 typedef unsigned short        __kernel_ipc_pid_t32;
-typedef unsigned short        __kernel_uid_t32;
 typedef unsigned                               __kernel_uid32_t32;
-typedef unsigned short        __kernel_gid_t32;
 typedef unsigned                               __kernel_gid32_t32;
-typedef unsigned short        __kernel_dev_t32;
-typedef unsigned int          __kernel_ino_t32;
-typedef unsigned short        __kernel_mode_t32;
 typedef unsigned short        __kernel_umode_t32;
-typedef short                 __kernel_nlink_t32;
 typedef int                   __kernel_daddr_t32;
-typedef int                   __kernel_off_t32;
 typedef unsigned int          __kernel_caddr_t32;
 typedef long                  __kernel_loff_t32;
 typedef __kernel_fsid_t               __kernel_fsid_t32;
@@ -37,9 +26,9 @@ typedef __kernel_fsid_t              __kernel_fsid_t32;
 struct flock32 {
        short l_type;
        short l_whence;
-       __kernel_off_t32 l_start;
-       __kernel_off_t32 l_len;
-       __kernel_pid_t32 l_pid;
+       compat_off_t l_start;
+       compat_off_t l_len;
+       compat_pid_t l_pid;
 };
 
 
@@ -98,30 +87,6 @@ struct ucontext_ia32 {
        sigset32_t        uc_sigmask;   /* mask last for extensibility */
 };
 
-struct stat32 {
-       unsigned short st_dev;
-       unsigned short __pad1;
-       unsigned int st_ino;
-       unsigned short st_mode;
-       unsigned short st_nlink;
-       unsigned short st_uid;
-       unsigned short st_gid;
-       unsigned short st_rdev;
-       unsigned short __pad2;
-       unsigned int  st_size;
-       unsigned int  st_blksize;
-       unsigned int  st_blocks;
-       unsigned int  st_atime;
-       unsigned int  __unused1;
-       unsigned int  st_mtime;
-       unsigned int  __unused2;
-       unsigned int  st_ctime;
-       unsigned int  __unused3;
-       unsigned int  __unused4;
-       unsigned int  __unused5;
-};
-
-
 /* This matches struct stat64 in glibc2.2, hence the absolutely
  * insane amounts of padding around dev_t's.
  */
@@ -146,9 +111,12 @@ struct stat64 {
 
        long long               st_blocks;/* Number 512-byte blocks allocated. */
 
-       unsigned long long      st_atime;
-       unsigned long long      st_mtime;
-       unsigned long long      st_ctime;
+       unsigned                st_atime;
+       unsigned                st_atime_nsec;
+       unsigned                st_mtime;
+       unsigned                st_mtime_nsec;
+       unsigned                st_ctime;
+       unsigned                st_ctime_nsec;
 
        unsigned long long      st_ino;
 } __attribute__((packed));
@@ -204,8 +172,8 @@ typedef struct siginfo32 {
                        unsigned int _pid;      /* which child */
                        unsigned int _uid;      /* sender's uid */
                        int _status;            /* exit code */
-                       __kernel_clock_t32 _utime;
-                       __kernel_clock_t32 _stime;
+                       compat_clock_t _utime;
+                       compat_clock_t _stime;
                } _sigchld;
 
                /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
@@ -224,7 +192,7 @@ typedef struct siginfo32 {
 
 struct ustat32 {
        __u32   f_tfree;
-       __kernel_ino_t32                f_tinode;
+       compat_ino_t            f_tinode;
        char                    f_fname[6];
        char                    f_fpack[6];
 };
@@ -234,6 +202,8 @@ struct iovec32 {
        int iov_len; 
 };
 
+#define IA32_PAGE_OFFSET 0xffff0000
+#define IA32_STACK_TOP IA32_PAGE_OFFSET
 
 #endif /* !CONFIG_IA32_SUPPORT */
  
index 21ed35ed964a019d1a1ebb3cceaf8c5fd64111af..110e55509c9b6c146d7fd33af003776c6f3a1a52 100644 (file)
@@ -6,6 +6,7 @@
  * this is for the kernel only.
  */
 
+#define __NR_ia32_restart_syscall 0
 #define __NR_ia32_exit           1
 #define __NR_ia32_fork           2
 #define __NR_ia32_read           3
 #define __NR_ia32_alloc_hugepages              250
 #define __NR_ia32_free_hugepages               251
 #define __NR_ia32_exit_group           252
+#define __NR_ia32_lookup_dcookie       253
+#define __NR_ia32_sys_epoll_create     254
+#define __NR_ia32_sys_epoll_ctl        255
+#define __NR_ia32_sys_epoll_wait       256
+#define __NR_ia32_remap_file_pages     257
+#define __NR_ia32_set_tid_address      258
 
-#define IA32_NR_syscalls 260   /* must be > than biggest syscall! */   
+#define IA32_NR_syscalls 265   /* must be > than biggest syscall! */   
 
 #endif /* _ASM_X86_64_IA32_UNISTD_H_ */
index ac0d00e0d53528f25463a7b3cd8cc2ad0b5f4dcb..b2234e42ef5b0501e319b09abaa7a42e6e9f1cd2 100644 (file)
@@ -70,6 +70,7 @@ static __inline__ void ide_init_default_hwifs(void)
        int index;
 
        for(index = 0; index < MAX_HWIFS; index++) {
+               memset(&hw, 0, sizeof hw);
                ide_init_hwif_ports(&hw, ide_default_io_base(index), 0, NULL);
                hw.irq = ide_default_irq(ide_default_io_base(index));
                ide_register_hw(&hw, NULL);
index 8171bdd9f0d5f235b967209dd8c1e4e5534afc96..aabef395f93534ef45877a1f90d6f048ec67e10d 100644 (file)
@@ -178,19 +178,23 @@ extern void iounmap(void *addr);
 #define readb(addr) (*(volatile unsigned char *) __io_virt(addr))
 #define readw(addr) (*(volatile unsigned short *) __io_virt(addr))
 #define readl(addr) (*(volatile unsigned int *) __io_virt(addr))
+#define readq(addr) (*(volatile unsigned long *) __io_virt(addr))
 #define __raw_readb readb
 #define __raw_readw readw
 #define __raw_readl readl
+#define __raw_readq readq
 
 #define writeb(b,addr) (*(volatile unsigned char *) __io_virt(addr) = (b))
 #define writew(b,addr) (*(volatile unsigned short *) __io_virt(addr) = (b))
 #define writel(b,addr) (*(volatile unsigned int *) __io_virt(addr) = (b))
+#define writeq(b,addr) (*(volatile unsigned long *) __io_virt(addr) = (b))
 #define __raw_writeb writeb
 #define __raw_writew writew
 #define __raw_writel writel
+#define __raw_writeq writeq
 
-void *memcpy_fromio(void*,void*,unsigned); 
-void *memcpy_toio(void*,void*,unsigned); 
+void *memcpy_fromio(void*,const void*,unsigned); 
+void *memcpy_toio(void*,const void*,unsigned); 
 #define memset_io(a,b,c)       memset(__io_virt(a),(b),(c))
 
 /*
@@ -215,7 +219,7 @@ void *memcpy_toio(void*,void*,unsigned);
 
 
 /*
- * Again, i386 does not require mem IO specific function.
+ * Again, x86-64 does not require mem IO specific function.
  */
 
 #define eth_io_copy_and_sum(a,b,c,d)           eth_copy_and_sum((a),__io_virt(b),(c),(d))
index 8cee542f40f4424a0396cf41e0184fbe8ab9dccd..2975afd3f3e572c26e841c5305ad9627d3992af1 100644 (file)
@@ -155,6 +155,8 @@ extern int io_apic_get_redir_entries (int ioapic);
 extern int io_apic_set_pci_routing (int ioapic, int pin, int irq);
 #endif
 
+extern int sis_apic_bug; /* dummy */ 
+
 
 #else  /* !CONFIG_X86_IO_APIC */
 #define io_apic_assign_pci_irqs 0
index 118366346669624bd6924c6e9c0e075261aa2ec0..3a0c29d2e02b91f123afea6f0720ee9162c15dcd 100644 (file)
@@ -12,8 +12,8 @@
 /*
  * possibly do the LDT unload here?
  */
-#define destroy_context(mm)            do { } while(0)
 int init_new_context(struct task_struct *tsk, struct mm_struct *mm);
+void destroy_context(struct mm_struct *mm);
 
 #ifdef CONFIG_SMP
 
index 874d34fcef688f8d748f020a08865a097f3793a6..67f8f69fa7b15f97af64b11b8e3f059d99e12ae6 100644 (file)
@@ -1,15 +1,10 @@
 #ifndef _ASM_X8664_MODULE_H
 #define _ASM_X8664_MODULE_H
 
-/*
- * This file contains the x8664 architecture specific module code.
- * Modules need to be mapped near the kernel code to allow 32bit relocations.
- */
+struct mod_arch_specific {}; 
 
-extern void *module_map(unsigned long);
-extern void module_unmap(void *);
-
-#define module_arch_init(x)    (0)
-#define arch_init_modules(x)   do { } while (0)
+#define Elf_Shdr Elf64_Shdr
+#define Elf_Sym Elf64_Sym
+#define Elf_Ehdr Elf64_Ehdr
 
 #endif 
index b165cefe799766db0f20ea4fd59213ddd7cdfe1b..96a97091c0f7a88a1154a93c4a86a9773ce87096 100644 (file)
 
 struct mtrr_sentry
 {
-    __u64 base;    /*  Base address     */
-    __u32 size;    /*  Size of region   */
+    unsigned long base;    /*  Base address     */
+    unsigned int size;    /*  Size of region   */
     unsigned int type;     /*  Type of region   */
 };
 
 struct mtrr_gentry
 {
-    __u64 base;    /*  Base address     */
-    __u32 size;    /*  Size of region   */
+    unsigned long base;    /*  Base address     */
     unsigned int regnum;   /*  Register number  */
+    unsigned int size;    /*  Size of region   */
     unsigned int type;     /*  Type of region   */
 };
 
@@ -65,49 +65,44 @@ struct mtrr_gentry
 #define MTRR_TYPE_WRBACK     6
 #define MTRR_NUM_TYPES       7
 
-#ifdef MTRR_NEED_STRINGS
-static char *mtrr_strings[MTRR_NUM_TYPES] =
-{
-    "uncachable",               /* 0 */
-    "write-combining",          /* 1 */
-    "?",                        /* 2 */
-    "?",                        /* 3 */
-    "write-through",            /* 4 */
-    "write-protect",            /* 5 */
-    "write-back",               /* 6 */
-};
-#endif
-
 #ifdef __KERNEL__
 
+extern char *mtrr_strings[MTRR_NUM_TYPES];
+
 /*  The following functions are for use by other drivers  */
-#ifdef CONFIG_MTRR
-extern int mtrr_add (__u64 base, __u32 size, unsigned int type, char increment);
-extern int mtrr_add_page (__u64 base, __u32 size, unsigned int type, char increment);
-extern int mtrr_del (int reg, __u64 base, __u32 size);
-extern int mtrr_del_page (int reg, __u64 base, __u32 size);
-#else
-static __inline__ int mtrr_add (__u64 base, __u32 size,
+# ifdef CONFIG_MTRR
+extern int mtrr_add (unsigned long base, unsigned long size,
+                    unsigned int type, char increment);
+extern int mtrr_add_page (unsigned long base, unsigned long size,
+                    unsigned int type, char increment);
+extern int mtrr_del (int reg, unsigned long base, unsigned long size);
+extern int mtrr_del_page (int reg, unsigned long base, unsigned long size);
+extern void mtrr_centaur_report_mcr(int mcr, u32 lo, u32 hi);
+#  else
+static __inline__ int mtrr_add (unsigned long base, unsigned long size,
                                unsigned int type, char increment)
 {
     return -ENODEV;
 }
-static __inline__ int mtrr_add_page (__u64 base, __u32 size,
+static __inline__ int mtrr_add_page (unsigned long base, unsigned long size,
                                unsigned int type, char increment)
 {
     return -ENODEV;
 }
-static __inline__ int mtrr_del (int reg, __u64 base, __u32 size)
+static __inline__ int mtrr_del (int reg, unsigned long base,
+                               unsigned long size)
 {
     return -ENODEV;
 }
-static __inline__ int mtrr_del_page (int reg, __u64 base, __u32 size)
+static __inline__ int mtrr_del_page (int reg, unsigned long base,
+                               unsigned long size)
 {
     return -ENODEV;
 }
-#endif
 
-extern void mtrr_init_cpu(int cpu);
+static __inline__ void mtrr_centaur_report_mcr(int mcr, u32 lo, u32 hi) {;}
+
+#  endif
 
 #endif
 
index 368bf5cc4bf45de86b5c74795ec815562001a83e..41a2b59d9d7d928de6300d3aac2b14ccbb300a72 100644 (file)
 #define LARGE_PAGE_MASK (~(LARGE_PAGE_SIZE-1))
 #define LARGE_PAGE_SIZE (1UL << PMD_SHIFT)
 
+#define HPAGE_SHIFT PMD_SHIFT
+#define HPAGE_SIZE     ((1UL) << HPAGE_SHIFT)
+#define HPAGE_MASK     (~(HPAGE_SIZE - 1))
+#define HUGETLB_PAGE_ORDER     (HPAGE_SHIFT - PAGE_SHIFT)
+
 #ifdef __KERNEL__
 #ifndef __ASSEMBLY__
 
index 9147e8ca66f0aadf8e5815868be0dceeaedffd88..fd60629f338646d81fbb9fdb5a2fcacb7440f7b0 100644 (file)
@@ -23,6 +23,7 @@ extern pgd_t level3_ident_pgt[512];
 extern pmd_t level2_kernel_pgt[512];
 extern pml4_t init_level4_pgt[];
 extern pgd_t boot_vmalloc_pgt[];
+extern unsigned long __supported_pte_mask;
 
 #define swapper_pg_dir NULL
 
@@ -97,7 +98,7 @@ static inline void set_pml4(pml4_t *dst, pml4_t val)
 }
 
 #define pgd_page(pgd) \
-((unsigned long) __va(pgd_val(pgd) & PAGE_MASK))
+((unsigned long) __va(pgd_val(pgd) & PHYSICAL_PAGE_MASK))
 
 #define ptep_get_and_clear(xp) __pte(xchg(&(xp)->pte, 0))
 #define pte_same(a, b)         ((a).pte == (b).pte)
@@ -159,46 +160,53 @@ static inline void set_pml4(pml4_t *dst, pml4_t val)
 #define _PAGE_CHG_MASK (PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
 
 #define PAGE_NONE      __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED)
-#define PAGE_SHARED    __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
-#define PAGE_COPY      __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
-#define PAGE_READONLY  __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
+#define PAGE_SHARED    __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
+#define PAGE_SHARED_EXEC __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
+#define PAGE_COPY    __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
+#define PAGE_COPY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
+#define PAGE_READONLY  __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
+#define PAGE_READONLY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
 
 #define __PAGE_KERNEL \
+       (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX)
+#define __PAGE_KERNEL_EXECUTABLE \
        (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED)
 #define __PAGE_KERNEL_NOCACHE \
-       (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_PCD | _PAGE_ACCESSED)
+       (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_PCD | _PAGE_ACCESSED | _PAGE_NX)
 #define __PAGE_KERNEL_RO \
-       (_PAGE_PRESENT | _PAGE_DIRTY | _PAGE_ACCESSED)
+       (_PAGE_PRESENT | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX)
 #define __PAGE_KERNEL_VSYSCALL \
        (_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
 #define __PAGE_KERNEL_LARGE \
-       (_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_PSE)
+       (_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_PSE | _PAGE_NX)
 
 #define MAKE_GLOBAL(x) __pgprot((x) | _PAGE_GLOBAL)
 
 #define PAGE_KERNEL MAKE_GLOBAL(__PAGE_KERNEL)
+#define PAGE_KERNEL_EXECUTABLE MAKE_GLOBAL(__PAGE_KERNEL_EXECUTABLE)
 #define PAGE_KERNEL_RO MAKE_GLOBAL(__PAGE_KERNEL_RO)
 #define PAGE_KERNEL_NOCACHE MAKE_GLOBAL(__PAGE_KERNEL_NOCACHE)
 #define PAGE_KERNEL_VSYSCALL MAKE_GLOBAL(__PAGE_KERNEL_VSYSCALL)
 #define PAGE_KERNEL_LARGE MAKE_GLOBAL(__PAGE_KERNEL_LARGE)
 
+/*         xwr */
 #define __P000 PAGE_NONE
 #define __P001 PAGE_READONLY
 #define __P010 PAGE_COPY
 #define __P011 PAGE_COPY
-#define __P100 PAGE_READONLY
-#define __P101 PAGE_READONLY
-#define __P110 PAGE_COPY
-#define __P111 PAGE_COPY
+#define __P100 PAGE_READONLY_EXEC
+#define __P101 PAGE_READONLY_EXEC
+#define __P110 PAGE_COPY_EXEC
+#define __P111 PAGE_COPY_EXEC
 
 #define __S000 PAGE_NONE
 #define __S001 PAGE_READONLY
 #define __S010 PAGE_SHARED
 #define __S011 PAGE_SHARED
-#define __S100 PAGE_READONLY
-#define __S101 PAGE_READONLY
-#define __S110 PAGE_SHARED
-#define __S111 PAGE_SHARED
+#define __S100 PAGE_READONLY_EXEC
+#define __S101 PAGE_READONLY_EXEC
+#define __S110 PAGE_SHARED_EXEC
+#define __S111 PAGE_SHARED_EXEC
 
 static inline unsigned long pgd_bad(pgd_t pgd) 
 { 
@@ -220,11 +228,12 @@ static inline unsigned long pgd_bad(pgd_t pgd)
 static inline pte_t pfn_pte(unsigned long page_nr, pgprot_t pgprot)
 {
        pte_t pte;
-       pte_val(pte) = (page_nr << PAGE_SHIFT) | pgprot_val(pgprot); 
+       pte_val(pte) = (page_nr << PAGE_SHIFT);
+       pte_val(pte) |= pgprot_val(pgprot);
+       pte_val(pte) &= __supported_pte_mask;
        return pte;
 }
 
-
 /*
  * The following only work if pte_present() is true.
  * Undefined behaviour if not..
@@ -304,10 +313,6 @@ static inline pgd_t *current_pgd_offset_k(unsigned long address)
        return __pgd_offset_k((pgd_t *)__va(addr), address);
 }
 
-#if 0 /* disabled because of confusing/wrong naming. */
-#define __pgd_offset(address) pgd_index(address)
-#endif
-
 #define pgd_offset(mm, address) ((mm)->pgd+pgd_index(address))
 
 /* PMD  - Level 2 access */
index c918c56459a65ccd2411c2358a80b39903e31bd0..075a49ff9ba421a9f3bc15e0394d78b853529700 100644 (file)
@@ -68,6 +68,7 @@ struct cpuinfo_x86 {
 #define X86_VENDOR_CENTAUR 5
 #define X86_VENDOR_RISE 6
 #define X86_VENDOR_TRANSMETA 7
+#define X86_VENDOR_NUM 8
 #define X86_VENDOR_UNKNOWN 0xff
 
 extern struct cpuinfo_x86 boot_cpu_data;
@@ -256,7 +257,7 @@ static inline void clear_in_cr4 (unsigned long mask)
  * space during mmap's.
  */
 #define TASK_UNMAPPED_32 0x40000000
-#define TASK_UNMAPPED_64 (TASK_SIZE/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)  
 
@@ -337,8 +338,8 @@ struct thread_struct {
 #define EXCEPTION_STKSZ 1024
 
 #define start_thread(regs,new_rip,new_rsp) do { \
-       __asm__("movl %0,%%fs; movl %0,%%es; movl %0,%%ds": :"r" (0));           \
-       wrmsrl(MSR_KERNEL_GS_BASE, 0);                                           \
+       asm volatile("movl %0,%%fs; movl %0,%%es; movl %0,%%ds": :"r" (0));      \
+       load_gs_index(0);                                                       \
        (regs)->rip = (new_rip);                                                 \
        (regs)->rsp = (new_rsp);                                                 \
        write_pda(oldrsp, (new_rsp));                                            \
@@ -358,7 +359,7 @@ extern void release_thread(struct task_struct *);
  */
 extern long kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
 
-extern void release_segments(struct mm_struct * mm);
+static inline void release_segments(struct mm_struct *mm) { }
 
 /*
  * Return saved PC of a blocked thread.
@@ -389,4 +390,31 @@ extern inline void rep_nop(void)
 #define cpu_relax()   rep_nop()
 
 
+/*
+ *      NSC/Cyrix CPU configuration register indexes
+ */
+#define CX86_CCR0 0xc0
+#define CX86_CCR1 0xc1
+#define CX86_CCR2 0xc2
+#define CX86_CCR3 0xc3
+#define CX86_CCR4 0xe8
+#define CX86_CCR5 0xe9
+#define CX86_CCR6 0xea
+#define CX86_CCR7 0xeb
+#define CX86_DIR0 0xfe
+#define CX86_DIR1 0xff
+#define CX86_ARR_BASE 0xc4
+#define CX86_RCR_BASE 0xdc
+
+/*
+ *      NSC/Cyrix CPU indexed register access macros
+ */
+
+#define getCx86(reg) ({ outb((reg), 0x22); inb(0x23); })
+
+#define setCx86(reg, data) do { \
+       outb((reg), 0x22); \
+       outb((data), 0x23); \
+} while (0)
+
 #endif /* __ASM_X86_64_PROCESSOR_H */
index b8d12898a7fcd6fb3d28b7ea1f88ec0d506a1382..01d85d962c547b4cdbf767367c06f563234c6582 100644 (file)
@@ -4,8 +4,8 @@
 struct scatterlist {
     struct page                *page;
     unsigned int       offset;
-    dma_addr_t         dma_address;
     unsigned int       length;
+    dma_addr_t         dma_address;
 };
 
 #define ISA_DMA_THRESHOLD (0x00ffffff)
index 58a5ed609398d41e80ea9b0e811c799f1f8ec3c4..c22075144ca7994252720ee1c77fbe96d624c8ec 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef SOCKET32_H
 #define SOCKET32_H 1
 
+#include <linux/compat.h>
+
 /* XXX This really belongs in some header file... -DaveM */
 #define MAX_SOCK_ADDR  128             /* 108 for Unix domain - 
                                           16 for IP, 16 for IPX,
@@ -11,14 +13,14 @@ struct msghdr32 {
         u32               msg_name;
         int               msg_namelen;
         u32               msg_iov;
-        __kernel_size_t32 msg_iovlen;
+        compat_size_t msg_iovlen;
         u32               msg_control;
-        __kernel_size_t32 msg_controllen;
+        compat_size_t msg_controllen;
         unsigned          msg_flags;
 };
 
 struct cmsghdr32 {
-        __kernel_size_t32 cmsg_len;
+        compat_size_t cmsg_len;
         int               cmsg_level;
         int               cmsg_type;
 };
index 9f065f8fe33debfea7cf1aea4ddb085dbc988eb8..e5e4fb75374619cb268f5f2225254d99c746591c 100644 (file)
@@ -1,6 +1,67 @@
-#ifndef SUSPEND_H
-#define SUSPEND_H 1
+/*
+ * Copyright 2001-2002 Pavel Machek <pavel@suse.cz>
+ * Based on code
+ * Copyright 2001 Patrick Mochel <mochel@osdl.org>
+ */
+#include <asm/desc.h>
+#include <asm/i387.h>
 
-/* dummy for now */
+static inline void
+arch_prepare_suspend(void)
+{
+}
 
+/* image of the saved processor state */
+struct saved_context {
+       u16 ds, es, fs, gs, ss;
+       unsigned long gs_base, fs_base;
+       unsigned long cr0, cr2, cr3, cr4;
+       u16 gdt_pad;
+       u16 gdt_limit;
+       unsigned long gdt_base;
+       u16 idt_pad;
+       u16 idt_limit;
+       unsigned long idt_base;
+       u16 ldt;
+       u16 tss;
+       unsigned long tr;
+       unsigned long safety;
+       unsigned long return_address;
+       unsigned long eflags;
+} __attribute__((packed));
+
+/* We'll access these from assembly, so we'd better have them outside struct */
+extern unsigned long saved_context_eax, saved_context_ebx, saved_context_ecx, saved_context_edx;
+extern unsigned long saved_context_esp, saved_context_ebp, saved_context_esi, saved_context_edi;
+extern unsigned long saved_context_r08, saved_context_r09, saved_context_r10, saved_context_r11;
+extern unsigned long saved_context_r12, saved_context_r13, saved_context_r14, saved_context_r15;
+extern unsigned long saved_context_eflags;
+
+
+#define loaddebug(thread,register) \
+               __asm__("movq %0,%%db" #register  \
+                       : /* no output */ \
+                       :"r" ((thread)->debugreg[register]))
+
+extern void fix_processor_context(void);
+extern void do_magic(int resume);
+
+#ifdef CONFIG_ACPI_SLEEP
+extern unsigned long saved_eip;
+extern unsigned long saved_esp;
+extern unsigned long saved_ebp;
+extern unsigned long saved_ebx;
+extern unsigned long saved_esi;
+extern unsigned long saved_edi;
+
+static inline void acpi_save_register_state(unsigned long return_point)
+{
+       /* FIXME: This is probably no longer correct: we need to save all caller-saved registers */
+}
+
+#define acpi_restore_register_state()  do {} while (0)
+
+/* routines for saving/restoring kernel state */
+extern int acpi_save_state_mem(void);
+extern int acpi_save_state_disk(void);
 #endif
index da9563a84cda28fa79a3ad175c4aabbbb171527d..f1281d48dc93cec2617a6108c4ef691823845030 100644 (file)
 #define __PUSH(x) "pushq %%" __STR(x) "\n\t"
 #define __POP(x)  "popq  %%" __STR(x) "\n\t"
 
-/* frame pointer must be last for get_wchan */
+struct save_context_frame { 
+       unsigned long rbp; 
+       unsigned long rbx;
+       unsigned long rcx;
+       unsigned long rdx;      
+       unsigned long rsi;
+       unsigned long rdi; 
+       unsigned long rax;
+       unsigned long r15;
+       unsigned long r14;
+       unsigned long r13;
+       unsigned long r12;
+       unsigned long r11;
+       unsigned long r10;
+       unsigned long r9;
+       unsigned long r8; 
+}; 
 
+/* frame pointer must be last for get_wchan */
 /* It would be more efficient to let the compiler clobber most of these registers.
    Clobbering all is not possible because that lets reload freak out. Even just 
    clobbering six generates wrong code with gcc 3.1 for me so do it this way for now.
        asm volatile(SAVE_CONTEXT                                                   \
                     "movq %%rsp,%[prevrsp]\n\t"                                    \
                     "movq %[nextrsp],%%rsp\n\t"                                    \
-                    "movq $1f,%[prevrip]\n\t"                                      \
+                    "movq $thread_return,%[prevrip]\n\t"                          \
                     "pushq %[nextrip]\n\t"                                         \
                     "jmp __switch_to\n\t"              \
-                    "1:\n\t"                                                       \
+                    ".globl thread_return\n"                                   \
+                    "thread_return:\n\t"                                           \
                     RESTORE_CONTEXT                                                \
                     :[prevrsp] "=m" (prev->thread.rsp),                            \
                      [prevrip] "=m" (prev->thread.rip)                             \
@@ -88,25 +106,31 @@ extern void load_gs_index(unsigned);
  * Clear and set 'TS' bit respectively
  */
 #define clts() __asm__ __volatile__ ("clts")
-#define read_cr0() ({ \
-       unsigned long __dummy; \
-       __asm__( \
-               "movq %%cr0,%0\n\t" \
-               :"=r" (__dummy)); \
-       __dummy; \
-})
-#define write_cr0(x) \
-       __asm__("movq %0,%%cr0": :"r" (x));
-
-#define read_cr4() ({ \
-       unsigned long __dummy; \
-       __asm__( \
-               "movq %%cr4,%0\n\t" \
-               :"=r" (__dummy)); \
-       __dummy; \
-})
-#define write_cr4(x) \
-       __asm__("movq %0,%%cr4": :"r" (x));
+
+static inline unsigned long read_cr0(void)
+{ 
+       unsigned long cr0;
+       asm volatile("movq %%cr0,%0" : "=r" (cr0));
+       return cr0;
+} 
+
+static inline void write_cr0(unsigned long val) 
+{ 
+       asm volatile("movq %0,%%cr0" :: "r" (val));
+} 
+
+static inline unsigned long read_cr4(void)
+{ 
+       unsigned long cr4;
+       asm("movq %%cr4,%0" : "=r" (cr4));
+       return cr4;
+} 
+
+static inline void write_cr4(unsigned long val)
+{ 
+       asm volatile("movq %0,%%cr4" :: "r" (val));
+} 
+
 #define stts() write_cr0(8 | read_cr0())
 
 #define wbinvd() \
@@ -210,7 +234,6 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
        ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\
                                        (unsigned long)(n),sizeof(*(ptr))))
 
-
 #ifdef CONFIG_SMP
 #define smp_mb()       mb()
 #define smp_rmb()      rmb()
index 7d8f6d855119722fff30e649d223b4658c0d2089..69cac4da715d87ec56b449131da0cdb9d98ce5b2 100644 (file)
@@ -29,6 +29,7 @@ struct thread_info {
        int                     preempt_count;
 
        mm_segment_t            addr_limit;     
+       struct restart_block    restart_block;
 };
 
 #endif
@@ -46,6 +47,9 @@ struct thread_info {
        .cpu           = 0,                     \
        .preempt_count = 1,                     \
        .addr_limit     = KERNEL_DS,            \
+       .restart_block = {                      \
+               .fn = do_no_restart_syscall,    \
+       },                                      \
 }
 
 #define init_thread_info       (init_thread_union.thread_info)
index e0fc3815d8c1b9798bc912d9db8ab712219ee136..2377301d8453f64ab13e985e7e0d95749da956a8 100644 (file)
@@ -399,15 +399,15 @@ __SYSCALL(__NR_iopl, stub_iopl)
 __SYSCALL(__NR_ioperm, sys_ioperm)
 
 #define __NR_create_module                     174
-__SYSCALL(__NR_create_module, sys_create_module)
+__SYSCALL(__NR_create_module, sys_ni_syscall)
 #define __NR_init_module                       175
 __SYSCALL(__NR_init_module, sys_init_module)
 #define __NR_delete_module                     176
 __SYSCALL(__NR_delete_module, sys_delete_module)
 #define __NR_get_kernel_syms                   177
-__SYSCALL(__NR_get_kernel_syms, sys_get_kernel_syms)
+__SYSCALL(__NR_get_kernel_syms, sys_ni_syscall)
 #define __NR_query_module                      178
-__SYSCALL(__NR_query_module, sys_query_module)
+__SYSCALL(__NR_query_module, sys_ni_syscall)
 
 #define __NR_quotactl                          179
 __SYSCALL(__NR_quotactl, sys_quotactl)
@@ -426,7 +426,8 @@ __SYSCALL(__NR_afs_syscall, sys_ni_syscall)
 #define __NR_tuxcall                   184 /* reserved for tux */
 __SYSCALL(__NR_tuxcall, sys_ni_syscall)
 
-/* 165 currently unused */
+#define __NR_security                  185
+__SYSCALL(__NR_security, sys_ni_syscall)
 
 #define __NR_gettid            186
 __SYSCALL(__NR_gettid, sys_gettid)
@@ -483,8 +484,24 @@ __SYSCALL(__NR_io_cancel, sys_io_cancel)
 __SYSCALL(__NR_get_thread_area, sys_get_thread_area)
 #define __NR_lookup_dcookie    212
 __SYSCALL(__NR_lookup_dcookie, sys_lookup_dcookie)
-
-#define __NR_syscall_max __NR_lookup_dcookie
+#define __NR_epoll_create      213
+__SYSCALL(__NR_epoll_create, sys_epoll_create)
+#define __NR_epoll_ctl 214
+__SYSCALL(__NR_epoll_ctl, sys_epoll_ctl)
+#define __NR_epoll_wait        215
+__SYSCALL(__NR_epoll_wait, sys_epoll_wait)
+#define __NR_remap_file_pages  216
+__SYSCALL(__NR_remap_file_pages, sys_remap_file_pages)
+#define __NR_getdents64        217
+__SYSCALL(__NR_getdents64, sys_getdents64)
+#define __NR_set_tid_address   218
+__SYSCALL(__NR_set_tid_address, sys_set_tid_address)
+#define __NR_restart_syscall   219
+__SYSCALL(__NR_restart_syscall, sys_restart_syscall)
+#define __NR_semtimedop                220
+__SYSCALL(__NR_semtimedop, sys_semtimedop)
+
+#define __NR_syscall_max __NR_semtimedop
 #ifndef __NO_STUBS
 
 /* user-visible error numbers are in the range -1 - -4095 */
@@ -605,7 +622,7 @@ static inline pid_t setsid(void)
        return sys_setsid();
 }
 
-extern ssize_t sys_write(unsigned int, char *, size_t);
+long sys_write(int fd, const char *buf, size_t size);
 static inline ssize_t write(unsigned int fd, char * buf, size_t count)
 {
        return sys_write(fd, buf, count);
@@ -651,7 +668,7 @@ extern inline long exit(int error_code)
 }
 
 struct rusage; 
-asmlinkage long sys_wait4(pid_t pid,unsigned int * stat_addr, 
+long sys_wait4(pid_t pid,unsigned int * stat_addr, 
                        int options, struct rusage * ru);
 static inline pid_t waitpid(int pid, int * wait_stat, int flags)
 {