# This is a BitKeeper generated patch for the following project: # Project Name: Linux kernel tree # This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas: # ChangeSet v2.5.65 -> 1.1171 # arch/i386/kernel/process.c 1.47 -> 1.48 # include/linux/file.h 1.7 -> 1.8 # arch/parisc/kernel/pci.c 1.8 -> 1.9 # arch/x86_64/kernel/traps.c 1.16 -> 1.17 # include/asm-mips64/elf.h 1.4 -> 1.5 # arch/parisc/kernel/ioctl32.c 1.4 -> 1.5 # fs/select.c 1.16 -> 1.17 # arch/x86_64/ia32/ia32_binfmt.c 1.9 -> 1.10 # arch/sh/kernel/traps.c 1.6 -> 1.7 # fs/file_table.c 1.18 -> 1.22 # drivers/block/ll_rw_blk.c 1.157 -> 1.158 # fs/dcache.c 1.41 -> 1.42 # fs/proc/proc_misc.c 1.68 -> 1.69 # arch/i386/Kconfig 1.48 -> 1.49 # arch/i386/kernel/traps.c 1.47 -> 1.48 # arch/ppc/kernel/traps.c 1.17 -> 1.18 # arch/parisc/kernel/entry.S 1.9 -> 1.10 # include/asm-m68k/elf.h 1.1 -> 1.2 # include/asm-sh/elf.h 1.2 -> 1.3 # drivers/oprofile/buffer_sync.c 1.9 -> 1.10 # include/linux/backing-dev.h 1.4 -> 1.5 # arch/parisc/kernel/Makefile 1.11 -> 1.12 # arch/i386/kernel/io_apic.c 1.55 -> 1.57 # arch/s390/kernel/traps.c 1.14 -> 1.15 # include/asm-parisc/ide.h 1.9 -> 1.10 # fs/exec.c 1.72 -> 1.73 # fs/nfsd/vfs.c 1.57 -> 1.58 # arch/parisc/kernel/binfmt_elf32.c 1.3 -> 1.4 # include/asm-cris/elf.h 1.3 -> 1.4 # fs/ufs/util.c 1.9 -> 1.10 # arch/arm/kernel/traps.c 1.23 -> 1.24 # arch/parisc/kernel/hardware.c 1.3 -> 1.4 # arch/mips/kernel/traps.c 1.6 -> 1.7 # include/asm-mips/elf.h 1.3 -> 1.4 # arch/parisc/kernel/cache.c 1.3 -> 1.4 # include/asm-parisc/ptrace.h 1.2 -> 1.3 # fs/binfmt_elf.c 1.41 -> 1.42 # mm/memory.c 1.115 -> 1.116 # drivers/block/genhd.c 1.74 -> 1.75 # arch/i386/kernel/smpboot.c 1.53 -> 1.54 # Documentation/sysrq.txt 1.7 -> 1.8 # include/asm-alpha/elf.h 1.3 -> 1.4 # arch/ppc64/kernel/traps.c 1.13 -> 1.14 # kernel/posix-timers.c 1.5 -> 1.6 # include/asm-s390x/elf.h 1.4 -> 1.5 # include/asm-parisc/kmap_types.h 1.1 -> 1.2 # include/asm-parisc/assembly.h 1.4 -> 1.5 # arch/parisc/kernel/init_task.c 1.4 -> 1.5 # drivers/char/tty_io.c 1.65 -> 1.66 # arch/parisc/kernel/sys32.h 1.3 -> 1.4 # mm/highmem.c 1.40 -> 1.41 # arch/mips64/kernel/traps.c 1.5 -> 1.6 # include/asm-i386/elf.h 1.5 -> 1.6 # include/asm-ia64/elf.h 1.7 -> 1.8 # drivers/char/vt_ioctl.c 1.19 -> 1.20 # include/asm-parisc/bug.h 1.2 -> 1.3 # include/asm-ppc64/elf.h 1.8 -> 1.9 # include/asm-parisc/elf.h 1.2 -> 1.4 # arch/s390x/kernel/traps.c 1.12 -> 1.13 # include/asm-i386/pgtable.h 1.30 -> 1.31 # include/asm-v850/elf.h 1.3 -> 1.4 # mm/slab.c 1.69 -> 1.70 # fs/nfs/inode.c 1.72 -> 1.73 # include/asm-m68knommu/elf.h 1.2 -> 1.3 # include/asm-um/archparam-i386.h 1.2 -> 1.3 # include/asm-x86_64/elf.h 1.4 -> 1.5 # kernel/timer.c 1.43 -> 1.45 # include/asm-parisc/posix_types.h 1.3 -> 1.4 # arch/parisc/kernel/sys_parisc.c 1.7 -> 1.8 # mm/nommu.c 1.1 -> 1.2 # arch/parisc/Makefile 1.18 -> 1.19 # include/asm-arm/elf.h 1.3 -> 1.4 # include/asm-s390/elf.h 1.3 -> 1.4 # fs/locks.c 1.39 -> 1.40 # arch/ia64/kernel/traps.c 1.26 -> 1.27 # include/asm-parisc/signal.h 1.2 -> 1.3 # include/asm-parisc/cacheflush.h 1.2 -> 1.3 # arch/parisc/kernel/signal.c 1.8 -> 1.9 # fs/inode.c 1.85 -> 1.86 # include/asm-i386/hw_irq.h 1.20 -> 1.21 # include/asm-ia64/ia32.h 1.17 -> 1.18 # arch/parisc/kernel/process.c 1.8 -> 1.9 # include/linux/thread_info.h 1.4 -> 1.5 # arch/parisc/kernel/syscall.S 1.8 -> 1.9 # arch/s390x/kernel/binfmt_elf32.c 1.7 -> 1.8 # arch/parisc/kernel/traps.c 1.7 -> 1.8 # arch/parisc/kernel/module.c 1.2 -> 1.3 # include/asm-parisc/compat.h 1.3 -> 1.4 # # The following is the BitKeeper ChangeSet Log # -------------------------------------------- # 03/03/17 torvalds@penguin.transmeta.com 1.1143 # Linux 2.5.65 # -------------------------------------------- # 03/03/18 willy@debian.org 1.1144 # [PATCH] PARISC update # # PA-RISC patches for 2.5.65: # # - Only remove palo.conf on a `make mrproper' # - Add a \ continuation to kernel/Makefile # - Reindent cache.c # - Always call schedule_tail # - Fix some typos in the hardware database # - Signal handling changes # - RAID, Device Mapper & BLKSZGET ioctl32 translations # - Clean up pci host bridge handling a bit. # - Make IDE link again # - Fix up compat changes # - Improve stack dumping code # -------------------------------------------- # 03/03/18 akpm@digeo.com 1.1145 # [PATCH] Fix noirqbalance # # Patch from Zwane Mwaikambo # # This patch fixes what seems to have been a longstanding bug. Ever since we # moved cpu bringup later into the boot process, we end up programming the # ioapics before we have any of our possible cpus in the cpu_online_map. # Therefore leading to the following current situation; # # For walmart-smp, bigsmp and summit we set the logical destination for cpu # to TARGET_CPUS which can depend on the cpu_online_map, so what you would # normally see with noirqbalance would be all interrupts handled on cpu0 # since at that stage no other cpu apart from the BSP is online. # # You can check for this by looking at the ioredtbls at boottime for a two # way system; # # .... IRQ redirection table: # NR Log Phy Mask Trig IRR Pol Stat Dest Deli Vect: # 00 000 00 1 0 0 0 0 0 0 00 # 01 001 01 0 0 0 0 0 1 1 39 # 02 001 01 0 0 0 0 0 1 1 31 # 03 001 01 0 0 0 0 0 1 1 41 # 04 001 01 0 0 0 0 0 1 1 49 # 05 001 01 0 0 0 0 0 1 1 51 # 06 001 01 0 0 0 0 0 1 1 59 # # Notice that 'Log' is set to 1 instead of 3. # # This patch will simply reprogram all the ioredtbls to handle the other # online cpus. # # Patch tested on my 2way P2-400 and a 16way NUMAQ both with noirqbalance. # It will not affect the irqbalance case because we are simply setting # TARGET_CPUS which is done anyway. # # before: # CPU0 CPU1 # 0: 1495632 0 IO-APIC-edge timer # 1: 4270 0 IO-APIC-edge i8042 # 2: 0 0 XT-PIC cascade # 8: 1 0 IO-APIC-edge rtc # 12: 83592 0 IO-APIC-edge i8042 # 14: 93791 0 IO-APIC-edge ide0 # 15: 103167 0 IO-APIC-edge ide1 # 17: 1396088 0 IO-APIC-level EMU10K1, eth0 # 18: 56125 0 IO-APIC-level aic7xxx, aic7xxx # 19: 2258 0 IO-APIC-level uhci-hcd, eth1, serial # NMI: 0 0 # LOC: 1495566 1497133 # # after: # CPU0 CPU1 # 0: 1046157 1015670 IO-APIC-edge timer # 1: 4923 4173 IO-APIC-edge i8042 # 2: 0 0 XT-PIC cascade # 8: 1 0 IO-APIC-edge rtc # 12: 48596 48968 IO-APIC-edge i8042 # 14: 4238 3416 IO-APIC-edge ide0 # 15: 25362 31525 IO-APIC-edge ide1 # 17: 3757 4014 IO-APIC-level EMU10K1, eth0 # 18: 335 366 IO-APIC-level aic7xxx, aic7xxx # 19: 1052 908 IO-APIC-level uhci-hcd, eth1 # NMI: 0 0 # LOC: 2061856 2061893 # -------------------------------------------- # 03/03/18 akpm@digeo.com 1.1146 # [PATCH] Pass the load address into ELF_PLAT_INIT() # # Patch from Anton Blanchard # # With ppc64 64bit dynamic executables we have to relocate the contents of the # function descriptor. Passing in the load address to ELF_PLAT_INIT allows us # to do this. # # The patch allows ppc64 to run 64-bit executables and is a no-op for other # architectures. # -------------------------------------------- # 03/03/18 akpm@digeo.com 1.1147 # [PATCH] remove unused block congestion code # # Patch from: Hugh Dickins # # Removes a ton of dead code from ll_rw_blk.c. I don't expect we'll be using # this now. # -------------------------------------------- # 03/03/18 akpm@digeo.com 1.1148 # [PATCH] timer code cleanup # # - Use list_head functions rather than open-coding them # # - Use time comparison macros rather than open-coding them # # - Hide some ifdefs # # - uninline internal_add_timer(). Saves half a kilobyte of text. # -------------------------------------------- # 03/03/18 akpm@digeo.com 1.1149 # [PATCH] timer re-addition lockup fix # # This is a forward-port of Andrea's fix in 2.4. # # If a timer handler re-adds a timer to go off right now, __run_timers() will # never terminate. (I wrote a test. It happens.) # # Fix that up by teaching internal_add_timer() to detect when it is being # called from within the context of __run_timers() and to park newly-added # timers onto a temp list instead. These timers are then added for real by # __run_timers(), after it has finished processing all pending timers. # -------------------------------------------- # 03/03/18 akpm@digeo.com 1.1150 # [PATCH] use set_current_state in fs # # Patch from Robert Love # # This patch is by Inaky Perez-Gonzalez. # # There are a couple uses of 'p->state=foo' in fs/ which are open coded. # This patch converts them to the proper [__]set_current_state() function. # -------------------------------------------- # 03/03/18 akpm@digeo.com 1.1151 # [PATCH] use set_current_state in mm # # Patch from Robert Love # # There are a couple uses of 'p->state=foo' in mm/ which are open coded. # This patch converts them to the proper [__]set_current_state() function. # -------------------------------------------- # 03/03/18 akpm@digeo.com 1.1152 # [PATCH] Fix memory leak in copy_thread # # Patch from Andi Kleen # # copy_thread could leak memory if you had a io bitmap and passed wrong # arguments to the new clone flags. # -------------------------------------------- # 03/03/18 akpm@digeo.com 1.1153 # [PATCH] file_list_lock contention fixes # # Patch from Manfred Spraul # # Fixes the lock contention over file_list_lock by simply removing the unneeded # anon_list. So filp allocation does not need to take a global lock any more. # # The use of a spinlock to protect files_stat.nr_files is a bit awkward, but # the alternative is a custom sysctl handler, and isn't much more efficient # anyway. # -------------------------------------------- # 03/03/18 akpm@digeo.com 1.1154 # [PATCH] file->f_list locking in tty_io.c # # release_mem() is altering the file->f_list lists without taking the # appropriate spinlock. # -------------------------------------------- # 03/03/18 akpm@digeo.com 1.1155 # [PATCH] file_list cleanup # # Replace the odd handling of f_list.next = NULL with list_emptiness. # -------------------------------------------- # 03/03/18 akpm@digeo.com 1.1156 # [PATCH] file_table: remove the private freelist # # - Remove the private freelist. There's no point in special-casing file # structure allocations in this way. # # - Hence the freeing of files can be moved outside file_list_lock() # # - Replace euid test with capable(CAP_SYS_ADMIN). # # - Tidy various other things up. # -------------------------------------------- # 03/03/18 akpm@digeo.com 1.1157 # [PATCH] file_list: less locking # # - optimise file_kill() to not take the global lock if the file is not on a # list. # # - Use optimised file_kill() in a few places rather than open-coding the # list removal. # -------------------------------------------- # 03/03/18 akpm@digeo.com 1.1158 # [PATCH] stack reduction in drivers/char/vt_ioctl.c # # Patch from "Randy.Dunlap" # # This patch (to 2.5.64) reduces the stack usage in vt_ioctl() # from 0x334 bytes to 0xec bytes (P4, UP, gcc 2.96). # -------------------------------------------- # 03/03/18 akpm@digeo.com 1.1159 # [PATCH] a few missing stubs for !CONFIG_MMU # # Patch from Christoph Hellwig # # This is from the uClinux patches - there are a few more stubs needed # in nommu.c to get the mmuless plattforms working. # -------------------------------------------- # 03/03/18 akpm@digeo.com 1.1160 # [PATCH] slab changes for !CONFIG_MMU # # Patch from Christoph Hellwig # # It extends the maximum amount of memory which may be kmalloced on nommu # machines. This is needed because these machines cannot perform vmalloc(). # # We couldn't really find a way of doing this which avoided the ifdef tangle. # -------------------------------------------- # 03/03/18 akpm@digeo.com 1.1161 # [PATCH] memleak in fs/nfs/inode.c::nfs_get_sb() # # Patch from Oleg Drokin # # There is trivial memleak on error exit path in nfs get_sb function. # -------------------------------------------- # 03/03/18 akpm@digeo.com 1.1162 # [PATCH] Memleak in fs/ufs/util.c # # Patch from Oleg Drokin # # There is trivial memleak on error exit path in # fs/ufs/util.c::_ubh_bread_() # -------------------------------------------- # 03/03/18 akpm@digeo.com 1.1163 # [PATCH] posix timers update # # Patch from george anzinger # # Fix the "large sleep returns EINVAL" problem, and clean a few things up. # -------------------------------------------- # 03/03/18 akpm@digeo.com 1.1164 # [PATCH] OOPS instance counters # # Patch from "Randy.Dunlap" # # Adds an oops counter to the oops messages, such as: # # Oops: 0002 [#2] # # So we can tell whether oops reports refer to the first oops, or to some # less-interesting followon oops. # -------------------------------------------- # 03/03/18 akpm@digeo.com 1.1165 # [PATCH] io-apic.c: DO_ACTION cleanup # # Patch from "Martin J. Bligh" # # This removes the DO_ACTION stuff. The downside is that we add some boring # and repetive code. The upside is that it's simple, and mere mortals can read # it without screwing their brains into a small piece of silly putty and # bouncing it off the wall. I think that's more important than pure source # code size. # -------------------------------------------- # 03/03/18 akpm@digeo.com 1.1166 # [PATCH] fix oprofile timer race # # Patch from John Levon # # wli got an oops from this. The callbacks call mod_timer so the timer had # better be setup by then # -------------------------------------------- # 03/03/18 akpm@digeo.com 1.1167 # [PATCH] pgd_index/pmd_index/pte_index commentary # # Patch from Dave Hansen # # Adds some commentary to these newly-introduced macros. # -------------------------------------------- # 03/03/18 akpm@digeo.com 1.1168 # [PATCH] /proc/sysrq-trigger: trigger sysrq functions via # # This makes sysrq facilities available to remote users. # # Writing a 'C' to /proc/sysrq-trigger receives the same treatment as typing # sysrq-C on the local keyboard. # -------------------------------------------- # 03/03/18 akpm@digeo.com 1.1169 # [PATCH] Tighten CONFIG_NUMA preconditions # # Patch from Martin J. Bligh and Dave Hansen # # People with ordinary PCs are accidentally turning on NUMA support, and people # with NUMA machines are finding the NUMA option mysteriously disappearing. # This patch sets the defaults to sane things for everyone, and only allows you # to turn on NUMA with both SMP and 64Gb support on (it's useful for the # distros on non-Summit boxes, but not on their UP kernels ;-)). # # I've also moved it below the highmem options, as it logically depends on # them, so this makes more sense. For those searching for NUMA support on # *real* NUMA machine, Dave has provided some guiding comments to show them # what they messed up (it's totally non-obvious). Hopefully this will stop # people's recent unfortunate foot-wounds (I think UP machines were defaulting # to NUMA on ... oops). # -------------------------------------------- # 03/03/18 akpm@digeo.com 1.1170 # [PATCH] Fix nfsd_symlink() failure path # # Patch from Andreas Gruenbacher # # In both 2.5 and 2.4, the fs/nfsd/vfs.c:nfsd_symlink() function calls down to # notify_change(). If notify_change fails for some reason, the error code is # not converted to an nfs no-the-wire error code as is should. The attached # patches fix that (one for 2.4, the other for 2.5). # -------------------------------------------- # 03/03/18 akpm@digeo.com 1.1171 # [PATCH] Add error checking get_disk() # # Patch from Bob Miller # # The get_disk() function should check the return value from kobject_get() # before passing it to to_disk(). This patch fixes this error. # # (Acked by Pat) # -------------------------------------------- # diff -Nru a/Documentation/sysrq.txt b/Documentation/sysrq.txt --- a/Documentation/sysrq.txt Tue Mar 18 15:05:35 2003 +++ b/Documentation/sysrq.txt Tue Mar 18 15:05:35 2003 @@ -36,6 +36,10 @@ On other - If you know of the key combos for other architectures, please let me know so I can add them to this section. +On all - write a character to /proc/sysrq-trigger. eg: + + echo t > /proc/sysrq-trigger + * What are the 'command' keys? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 'r' - Turns off keyboard raw mode and sets it to XLATE. diff -Nru a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c --- a/arch/arm/kernel/traps.c Tue Mar 18 15:05:35 2003 +++ b/arch/arm/kernel/traps.c Tue Mar 18 15:05:35 2003 @@ -208,12 +208,13 @@ NORET_TYPE void die(const char *str, struct pt_regs *regs, int err) { struct task_struct *tsk = current; + static int die_counter; console_verbose(); spin_lock_irq(&die_lock); bust_spinlocks(1); - printk("Internal error: %s: %x\n", str, err); + printk("Internal error: %s: %x [#%d]\n", str, err, ++die_counter); print_modules(); printk("CPU: %d\n", smp_processor_id()); show_regs(regs); diff -Nru a/arch/i386/Kconfig b/arch/i386/Kconfig --- a/arch/i386/Kconfig Tue Mar 18 15:05:35 2003 +++ b/arch/i386/Kconfig Tue Mar 18 15:05:35 2003 @@ -476,21 +476,6 @@ This is purely to save memory - each supported CPU adds approximately eight kilobytes to the kernel image. -# Common NUMA Features -config NUMA - bool "Numa Memory Allocation Support" - depends on (HIGHMEM64G && (X86_NUMAQ || (X86_SUMMIT && ACPI && !ACPI_HT_ONLY))) || X86_PC - -config DISCONTIGMEM - bool - depends on NUMA - default y - -config HAVE_ARCH_BOOTMEM_NODE - bool - depends on NUMA - default y - config X86_TSC bool depends on (MWINCHIP3D || MWINCHIP2 || MCRUSOE || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2) && !X86_NUMAQ @@ -678,6 +663,30 @@ config X86_PAE bool depends on HIGHMEM64G + default y + +# Common NUMA Features +config NUMA + bool "Numa Memory Allocation Support" + depends on SMP && HIGHMEM64G && (X86_PC || X86_NUMAQ || (X86_SUMMIT && ACPI && !ACPI_HT_ONLY)) + default n if X86_PC + default y if (X86_NUMAQ || X86_SUMMIT) + +# Need comments to help the hapless user trying to turn on NUMA support +comment "NUMA (NUMA-Q) requires SMP, 64GB highmem support" + depends on X86_NUMAQ && (!HIGHMEM64G || !SMP) + +comment "NUMA (Summit) requires SMP, 64GB highmem support, full ACPI" + depends on X86_SUMMIT && (!HIGHMEM64G || !ACPI || ACPI_HT_ONLY) + +config DISCONTIGMEM + bool + depends on NUMA + default y + +config HAVE_ARCH_BOOTMEM_NODE + bool + depends on NUMA default y config HIGHPTE diff -Nru a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c --- a/arch/i386/kernel/io_apic.c Tue Mar 18 15:05:35 2003 +++ b/arch/i386/kernel/io_apic.c Tue Mar 18 15:05:35 2003 @@ -116,40 +116,84 @@ } } -#define __DO_ACTION(R, ACTION, FINAL) \ - \ -{ \ - int pin; \ - struct irq_pin_list *entry = irq_2_pin + irq; \ - \ - for (;;) { \ - unsigned int reg; \ - pin = entry->pin; \ - if (pin == -1) \ - break; \ - reg = io_apic_read(entry->apic, 0x10 + R + pin*2); \ - reg ACTION; \ - io_apic_modify(entry->apic, 0x10 + R + pin*2, reg); \ - if (!entry->next) \ - break; \ - entry = irq_2_pin + entry->next; \ - } \ - FINAL; \ -} - -#define DO_ACTION(name,R,ACTION, FINAL) \ - \ - static void name##_IO_APIC_irq (unsigned int irq) \ - __DO_ACTION(R, ACTION, FINAL) - -DO_ACTION( __mask, 0, |= 0x00010000, io_apic_sync(entry->apic) ) - /* mask = 1 */ -DO_ACTION( __unmask, 0, &= 0xfffeffff, ) - /* mask = 0 */ -DO_ACTION( __mask_and_edge, 0, = (reg & 0xffff7fff) | 0x00010000, ) - /* mask = 1, trigger = 0 */ -DO_ACTION( __unmask_and_level, 0, = (reg & 0xfffeffff) | 0x00008000, ) - /* mask = 0, trigger = 1 */ +/* mask = 1 */ +static void __mask_IO_APIC_irq (unsigned int irq) +{ + int pin; + struct irq_pin_list *entry = irq_2_pin + irq; + + for (;;) { + unsigned int reg; + pin = entry->pin; + if (pin == -1) + break; + reg = io_apic_read(entry->apic, 0x10 + pin*2); + io_apic_modify(entry->apic, 0x10 + pin*2, reg |= 0x00010000); + if (!entry->next) + break; + entry = irq_2_pin + entry->next; + } + io_apic_sync(entry->apic); +} + +/* mask = 0 */ +static void __unmask_IO_APIC_irq (unsigned int irq) +{ + int pin; + struct irq_pin_list *entry = irq_2_pin + irq; + + for (;;) { + unsigned int reg; + pin = entry->pin; + if (pin == -1) + break; + reg = io_apic_read(entry->apic, 0x10 + pin*2); + io_apic_modify(entry->apic, 0x10 + pin*2, reg &= 0xfffeffff); + if (!entry->next) + break; + entry = irq_2_pin + entry->next; + } +} + +/* mask = 1, trigger = 0 */ +static void __mask_and_edge_IO_APIC_irq (unsigned int irq) +{ + int pin; + struct irq_pin_list *entry = irq_2_pin + irq; + + for (;;) { + unsigned int reg; + pin = entry->pin; + if (pin == -1) + break; + reg = io_apic_read(entry->apic, 0x10 + pin*2); + reg = (reg & 0xffff7fff) | 0x00010000; + io_apic_modify(entry->apic, 0x10 + pin*2, reg); + if (!entry->next) + break; + entry = irq_2_pin + entry->next; + } +} + +/* mask = 0, trigger = 1 */ +static void __unmask_and_level_IO_APIC_irq (unsigned int irq) +{ + int pin; + struct irq_pin_list *entry = irq_2_pin + irq; + + for (;;) { + unsigned int reg; + pin = entry->pin; + if (pin == -1) + break; + reg = io_apic_read(entry->apic, 0x10 + pin*2); + reg = (reg & 0xfffeffff) | 0x00008000; + io_apic_modify(entry->apic, 0x10 + pin*2, reg); + if (!entry->next) + break; + entry = irq_2_pin + entry->next; + } +} static void mask_IO_APIC_irq (unsigned int irq) { @@ -197,13 +241,23 @@ static void set_ioapic_affinity (unsigned int irq, unsigned long mask) { unsigned long flags; + int pin; + struct irq_pin_list *entry = irq_2_pin + irq; /* * Only the first 8 bits are valid. */ mask = mask << 24; spin_lock_irqsave(&ioapic_lock, flags); - __DO_ACTION(1, = mask, ) + for (;;) { + pin = entry->pin; + if (pin == -1) + break; + io_apic_write(entry->apic, 0x10 + 1 + pin*2, mask); + if (!entry->next) + break; + entry = irq_2_pin + entry->next; + } spin_unlock_irqrestore(&ioapic_lock, flags); } @@ -740,6 +794,30 @@ } } return best_guess; +} + +/* + * This function currently is only a helper for the i386 smp boot process where + * we need to reprogram the ioredtbls to cater for the cpus which have come online + * so mask in all cases should simply be TARGET_CPUS + */ +void __init setup_ioapic_dest (unsigned long mask) +{ + int pin, ioapic, irq, irq_entry; + + if (skip_ioapic_setup == 1) + return; + + for (ioapic = 0; ioapic < nr_ioapics; ioapic++) { + for (pin = 0; pin < nr_ioapic_registers[ioapic]; pin++) { + irq_entry = find_irq_entry(ioapic, pin, mp_INT); + if (irq_entry == -1) + continue; + irq = pin_2_irq(irq_entry, ioapic, pin); + set_ioapic_affinity(irq, mask); + } + + } } /* diff -Nru a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c --- a/arch/i386/kernel/process.c Tue Mar 18 15:05:35 2003 +++ b/arch/i386/kernel/process.c Tue Mar 18 15:05:35 2003 @@ -290,6 +290,7 @@ { struct pt_regs * childregs; struct task_struct *tsk; + int err; childregs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) p->thread_info)) - 1; struct_cpy(childregs, regs); @@ -322,20 +323,27 @@ struct user_desc info; int idx; + err = -EFAULT; if (copy_from_user(&info, (void *)childregs->esi, sizeof(info))) - return -EFAULT; + goto out; + err = -EINVAL; if (LDT_empty(&info)) - return -EINVAL; + goto out; idx = info.entry_number; if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX) - return -EINVAL; + goto out; desc = p->thread.tls_array + idx - GDT_ENTRY_TLS_MIN; desc->a = LDT_entry_a(&info); desc->b = LDT_entry_b(&info); } - return 0; + + err = 0; + out: + if (err && p->thread.ts_io_bitmap) + kfree(p->thread.ts_io_bitmap); + return err; } /* diff -Nru a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c --- a/arch/i386/kernel/smpboot.c Tue Mar 18 15:05:35 2003 +++ b/arch/i386/kernel/smpboot.c Tue Mar 18 15:05:35 2003 @@ -1155,6 +1155,7 @@ void __init smp_cpus_done(unsigned int max_cpus) { + setup_ioapic_dest(TARGET_CPUS); zap_low_mappings(); } diff -Nru a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c --- a/arch/i386/kernel/traps.c Tue Mar 18 15:05:35 2003 +++ b/arch/i386/kernel/traps.c Tue Mar 18 15:05:35 2003 @@ -247,11 +247,13 @@ void die(const char * str, struct pt_regs * regs, long err) { + static int die_counter; + console_verbose(); spin_lock_irq(&die_lock); bust_spinlocks(1); handle_BUG(regs); - printk("%s: %04lx\n", str, err & 0xffff); + printk("%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter); show_registers(regs); bust_spinlocks(0); spin_unlock_irq(&die_lock); diff -Nru a/arch/ia64/kernel/traps.c b/arch/ia64/kernel/traps.c --- a/arch/ia64/kernel/traps.c Tue Mar 18 15:05:35 2003 +++ b/arch/ia64/kernel/traps.c Tue Mar 18 15:05:35 2003 @@ -101,6 +101,7 @@ .lock_owner = -1, .lock_owner_depth = 0 }; + static int die_counter; if (die.lock_owner != smp_processor_id()) { console_verbose(); @@ -111,7 +112,8 @@ } if (++die.lock_owner_depth < 3) { - printk("%s[%d]: %s %ld\n", current->comm, current->pid, str, err); + printk("%s[%d]: %s %ld [%d]\n", + current->comm, current->pid, str, err, ++die_counter); show_regs(regs); } else printk(KERN_ERR "Recursive die() failure, output suppressed\n"); diff -Nru a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c --- a/arch/mips/kernel/traps.c Tue Mar 18 15:05:35 2003 +++ b/arch/mips/kernel/traps.c Tue Mar 18 15:05:35 2003 @@ -191,12 +191,13 @@ extern void __die(const char * str, struct pt_regs * regs, const char *where, unsigned long line) { + static int die_counter; console_verbose(); spin_lock_irq(&die_lock); printk("%s", str); if (where) printk(" in %s, line %ld", where, line); - printk(":\n"); + printk("[#%d]:\n", ++die_counter); show_regs(regs); printk("Process %s (pid: %d, stackpage=%08lx)\n", current->comm, current->pid, (unsigned long) current); diff -Nru a/arch/mips64/kernel/traps.c b/arch/mips64/kernel/traps.c --- a/arch/mips64/kernel/traps.c Tue Mar 18 15:05:35 2003 +++ b/arch/mips64/kernel/traps.c Tue Mar 18 15:05:35 2003 @@ -161,12 +161,13 @@ void die(const char * str, struct pt_regs * regs, unsigned long err) { + static int die_counter; if (user_mode(regs)) /* Just return if in user mode. */ return; console_verbose(); spin_lock_irq(&die_lock); - printk("%s: %04lx\n", str, err & 0xffff); + printk("%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter); show_regs(regs); printk("Process %s (pid: %d, stackpage=%08lx)\n", current->comm, current->pid, (unsigned long) current); diff -Nru a/arch/parisc/Makefile b/arch/parisc/Makefile --- a/arch/parisc/Makefile Tue Mar 18 15:05:35 2003 +++ b/arch/parisc/Makefile Tue Mar 18 15:05:35 2003 @@ -93,7 +93,8 @@ include/asm-parisc/offsets.h: arch/parisc/kernel/asm-offsets.s $(call filechk,gen-asm-offsets) -CLEAN_FILES += palo.conf lifimage include/asm-parisc/offsets.h +CLEAN_FILES += lifimage include/asm-parisc/offsets.h +MRPROPER_FILES += palo.conf define archhelp @echo '* vmlinux - Uncompressed kernel image (./vmlinux)' diff -Nru a/arch/parisc/kernel/Makefile b/arch/parisc/kernel/Makefile --- a/arch/parisc/kernel/Makefile Tue Mar 18 15:05:35 2003 +++ b/arch/parisc/kernel/Makefile Tue Mar 18 15:05:35 2003 @@ -4,7 +4,7 @@ head-y := head.o head-$(CONFIG_PARISC64) := head64.o -extra-y := init_task.o pdc_cons.o process.o +extra-y := init_task.o pdc_cons.o process.o \ unaligned.o $(head-y) AFLAGS_entry.o := -traditional diff -Nru a/arch/parisc/kernel/binfmt_elf32.c b/arch/parisc/kernel/binfmt_elf32.c --- a/arch/parisc/kernel/binfmt_elf32.c Tue Mar 18 15:05:35 2003 +++ b/arch/parisc/kernel/binfmt_elf32.c Tue Mar 18 15:05:35 2003 @@ -12,6 +12,26 @@ #define ELF_CLASS ELFCLASS32 +#define ELF_CORE_COPY_REGS(dst, pt) \ + memset(dst, 0, sizeof(dst)); /* don't leak any "random" bits */ \ + { int i; \ + for (i = 0; i < 32; i++) dst[i] = (elf_greg_t) pt->gr[i]; \ + for (i = 0; i < 8; i++) dst[32 + i] = (elf_greg_t) pt->sr[i]; \ + } \ + dst[40] = (elf_greg_t) pt->iaoq[0]; dst[41] = (elf_greg_t) pt->iaoq[1]; \ + dst[42] = (elf_greg_t) pt->iasq[0]; dst[43] = (elf_greg_t) pt->iasq[1]; \ + dst[44] = (elf_greg_t) pt->sar; dst[45] = (elf_greg_t) pt->iir; \ + dst[46] = (elf_greg_t) pt->isr; dst[47] = (elf_greg_t) pt->ior; \ + dst[48] = (elf_greg_t) mfctl(22); dst[49] = (elf_greg_t) mfctl(0); \ + dst[50] = (elf_greg_t) mfctl(24); dst[51] = (elf_greg_t) mfctl(25); \ + dst[52] = (elf_greg_t) mfctl(26); dst[53] = (elf_greg_t) mfctl(27); \ + dst[54] = (elf_greg_t) mfctl(28); dst[55] = (elf_greg_t) mfctl(29); \ + dst[56] = (elf_greg_t) mfctl(30); dst[57] = (elf_greg_t) mfctl(31); \ + dst[58] = (elf_greg_t) mfctl( 8); dst[59] = (elf_greg_t) mfctl( 9); \ + dst[60] = (elf_greg_t) mfctl(12); dst[61] = (elf_greg_t) mfctl(13); \ + dst[62] = (elf_greg_t) mfctl(10); dst[63] = (elf_greg_t) mfctl(15); + + typedef unsigned int elf_greg_t; #include @@ -60,25 +80,6 @@ #define init_elf_binfmt init_elf32_binfmt #define ELF_PLATFORM ("PARISC32\0") - -#define ELF_CORE_COPY_REGS(dst, pt) \ - memset(dst, 0, sizeof(dst)); /* don't leak any "random" bits */ \ - { int i; \ - for (i = 0; i < 32; i++) dst[i] = (elf_greg_t) pt->gr[i]; \ - for (i = 0; i < 8; i++) dst[32 + i] = (elf_greg_t) pt->sr[i]; \ - } \ - dst[40] = (elf_greg_t) pt->iaoq[0]; dst[41] = (elf_greg_t) pt->iaoq[1]; \ - dst[42] = (elf_greg_t) pt->iasq[0]; dst[43] = (elf_greg_t) pt->iasq[1]; \ - dst[44] = (elf_greg_t) pt->sar; dst[45] = (elf_greg_t) pt->iir; \ - dst[46] = (elf_greg_t) pt->isr; dst[47] = (elf_greg_t) pt->ior; \ - dst[48] = (elf_greg_t) mfctl(22); dst[49] = (elf_greg_t) mfctl(0); \ - dst[50] = (elf_greg_t) mfctl(24); dst[51] = (elf_greg_t) mfctl(25); \ - dst[52] = (elf_greg_t) mfctl(26); dst[53] = (elf_greg_t) mfctl(27); \ - dst[54] = (elf_greg_t) mfctl(28); dst[55] = (elf_greg_t) mfctl(29); \ - dst[56] = (elf_greg_t) mfctl(30); dst[57] = (elf_greg_t) mfctl(31); \ - dst[58] = (elf_greg_t) mfctl( 8); dst[59] = (elf_greg_t) mfctl( 9); \ - dst[60] = (elf_greg_t) mfctl(12); dst[61] = (elf_greg_t) mfctl(13); \ - dst[62] = (elf_greg_t) mfctl(10); dst[63] = (elf_greg_t) mfctl(15); /* * We should probably use this macro to set a flag somewhere to indicate diff -Nru a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c --- a/arch/parisc/kernel/cache.c Tue Mar 18 15:05:35 2003 +++ b/arch/parisc/kernel/cache.c Tue Mar 18 15:05:35 2003 @@ -114,7 +114,7 @@ void __init parisc_cache_init(void) { - if(pdc_cache_info(&cache_info)<0) + if (pdc_cache_info(&cache_info) < 0) panic("parisc_cache_init: pdc_cache_info failed"); #if 0 @@ -167,25 +167,25 @@ split_tlb = 0; if (cache_info.dt_conf.tc_sh == 0 || cache_info.dt_conf.tc_sh == 2) { - - if (cache_info.dt_conf.tc_sh == 2) - printk(KERN_WARNING "Unexpected TLB configuration. " + if (cache_info.dt_conf.tc_sh == 2) + printk(KERN_WARNING "Unexpected TLB configuration. " "Will flush I/D separately (could be optimized).\n"); - split_tlb = 1; + split_tlb = 1; } - dcache_stride = ( (1<<(cache_info.dc_conf.cc_block+3)) * - cache_info.dc_conf.cc_line ); - icache_stride = ( (1<<(cache_info.ic_conf.cc_block+3)) * - cache_info.ic_conf.cc_line ); + dcache_stride = (1 << (cache_info.dc_conf.cc_block + 3)) * + cache_info.dc_conf.cc_line; + icache_stride = (1 << (cache_info.ic_conf.cc_block + 3)) * + cache_info.ic_conf.cc_line; #ifndef CONFIG_PA20 - if(pdc_btlb_info(&btlb_info)<0) { + if (pdc_btlb_info(&btlb_info) < 0) { memset(&btlb_info, 0, sizeof btlb_info); } #endif - if ((boot_cpu_data.pdc.capabilities & PDC_MODEL_NVA_MASK) == PDC_MODEL_NVA_UNSUPPORTED) { + if ((boot_cpu_data.pdc.capabilities & PDC_MODEL_NVA_MASK) == + PDC_MODEL_NVA_UNSUPPORTED) { printk(KERN_WARNING "Only equivalent aliasing supported\n"); #ifndef CONFIG_SMP panic("SMP kernel required to avoid non-equivalent aliasing"); @@ -195,31 +195,69 @@ void disable_sr_hashing(void) { - int srhash_type; + int srhash_type; + + switch (boot_cpu_data.cpu_type) { + case pcx: /* We shouldn't get this far. setup.c should prevent it. */ + BUG(); + return; + + case pcxs: + case pcxt: + case pcxt_: + srhash_type = SRHASH_PCXST; + break; + + case pcxl: + srhash_type = SRHASH_PCXL; + break; + + case pcxl2: /* pcxl2 doesn't support space register hashing */ + return; + + default: /* Currently all PA2.0 machines use the same ins. sequence */ + srhash_type = SRHASH_PA20; + break; + } - if (boot_cpu_data.cpu_type == pcxl2) - return; /* pcxl2 doesn't support space register hashing */ + disable_sr_hashing_asm(srhash_type); +} + +void __flush_dcache_page(struct page *page) +{ + struct mm_struct *mm = current->active_mm; + struct list_head *l; - switch (boot_cpu_data.cpu_type) { + flush_kernel_dcache_page(page_address(page)); - case pcx: - BUG(); /* We shouldn't get here. code in setup.c should prevent it */ - return; + if (!page->mapping) + return; - case pcxs: - case pcxt: - case pcxt_: - srhash_type = SRHASH_PCXST; - break; + list_for_each(l, &page->mapping->i_mmap_shared) { + struct vm_area_struct *mpnt; + unsigned long off; - case pcxl: - srhash_type = SRHASH_PCXL; - break; + mpnt = list_entry(l, struct vm_area_struct, shared); - default: /* Currently all PA2.0 machines use the same ins. sequence */ - srhash_type = SRHASH_PA20; - break; - } + /* + * If this VMA is not in our MM, we can ignore it. + */ + if (mpnt->vm_mm != mm) + continue; - disable_sr_hashing_asm(srhash_type); + if (page->index < mpnt->vm_pgoff) + continue; + + off = page->index - mpnt->vm_pgoff; + if (off >= (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT) + continue; + + flush_cache_page(mpnt, mpnt->vm_start + (off << PAGE_SHIFT)); + + /* All user shared mappings should be equivalently mapped, + * so once we've flushed one we should be ok + */ + break; + } } + diff -Nru a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S --- a/arch/parisc/kernel/entry.S Tue Mar 18 15:05:35 2003 +++ b/arch/parisc/kernel/entry.S Tue Mar 18 15:05:35 2003 @@ -558,11 +558,9 @@ .export ret_from_kernel_thread ret_from_kernel_thread: -#if CONFIG_PREEMPT || CONFIG_SMP /* Call schedule_tail first though */ bl schedule_tail, %r2 nop -#endif LDREG TI_TASK-THREAD_SZ_ALGN(%r30), %r1 LDREG TASK_PT_GR25(%r1), %r26 @@ -2014,10 +2012,8 @@ /* Set the return value for the child */ child_return: -#if CONFIG_SMP || CONFIG_PREEMPT bl schedule_tail, %r2 nop -#endif LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE-FRAME_SIZE(%r30), %r1 LDREG TASK_PT_GR19(%r1),%r2 diff -Nru a/arch/parisc/kernel/hardware.c b/arch/parisc/kernel/hardware.c --- a/arch/parisc/kernel/hardware.c Tue Mar 18 15:05:35 2003 +++ b/arch/parisc/kernel/hardware.c Tue Mar 18 15:05:35 2003 @@ -99,8 +99,8 @@ {HPHW_NPROC,0x481,0x4,0x81,"Wilbur (E25)"}, {HPHW_NPROC,0x482,0x4,0x81,"WB-80 (E35)"}, {HPHW_NPROC,0x483,0x4,0x81,"WB-96 (E45)"}, - {HPHW_NPROC,0x48,0x4,0x81,"UL Proc L-100 (811/D210,D310)"}, - {HPHW_NPROC,0x48,0x4,0x81,"UL Proc L-75 (801/D200)"}, + {HPHW_NPROC,0x484,0x4,0x81,"UL Proc L-100 (811/D210,D310)"}, + {HPHW_NPROC,0x485,0x4,0x81,"UL Proc L-75 (801/D200)"}, {HPHW_NPROC,0x501,0x4,0x81,"Merlin L2 132 (9000/778/B132L)"}, {HPHW_NPROC,0x502,0x4,0x81,"Merlin L2 160 (9000/778/B160L)"}, {HPHW_NPROC,0x503,0x4,0x81,"Merlin L2+ 132 (9000/778/B132L)"}, diff -Nru a/arch/parisc/kernel/init_task.c b/arch/parisc/kernel/init_task.c --- a/arch/parisc/kernel/init_task.c Tue Mar 18 15:05:35 2003 +++ b/arch/parisc/kernel/init_task.c Tue Mar 18 15:05:35 2003 @@ -10,6 +10,7 @@ static struct fs_struct init_fs = INIT_FS; static struct files_struct init_files = INIT_FILES; static struct signal_struct init_signals = INIT_SIGNALS(init_signals); +static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); struct mm_struct init_mm = INIT_MM(init_mm); /* diff -Nru a/arch/parisc/kernel/ioctl32.c b/arch/parisc/kernel/ioctl32.c --- a/arch/parisc/kernel/ioctl32.c Tue Mar 18 15:05:35 2003 +++ b/arch/parisc/kernel/ioctl32.c Tue Mar 18 15:05:35 2003 @@ -1,4 +1,4 @@ -/* $Id: ioctl32.c,v 1.6 2002/10/21 16:13:22 varenet Exp $ +/* $Id: ioctl32.c,v 1.5 2002/10/18 00:21:43 varenet Exp $ * ioctl32.c: Conversion between 32bit and 64bit native ioctls. * * Copyright (C) 1997-2000 Jakub Jelinek (jakub@redhat.com) @@ -66,6 +66,9 @@ #define __KERNEL__ #include +#include +#include + #include #include #include @@ -2824,6 +2827,27 @@ return err; } +/* Fix sizeof(sizeof()) breakage */ +#define BLKBSZGET_32 _IOR(0x12,112,int) +#define BLKBSZSET_32 _IOW(0x12,113,int) +#define BLKGETSIZE64_32 _IOR(0x12,114,int) + +static int do_blkbszget(unsigned int fd, unsigned int cmd, unsigned long arg) +{ + return sys_ioctl(fd, BLKBSZGET, arg); +} + +static int do_blkbszset(unsigned int fd, unsigned int cmd, unsigned long arg) +{ + return sys_ioctl(fd, BLKBSZSET, arg); +} + +static int do_blkgetsize64(unsigned int fd, unsigned int cmd, + unsigned long arg) +{ + return sys_ioctl(fd, BLKGETSIZE64, arg); +} + static int ioc_settimeout(unsigned int fd, unsigned int cmd, unsigned long arg) { return rw_long(fd, AUTOFS_IOC_SETTIMEOUT, arg); @@ -2997,14 +3021,13 @@ COMPATIBLE_IOCTL(BLKRRPART) COMPATIBLE_IOCTL(BLKFLSBUF) COMPATIBLE_IOCTL(BLKSECTSET) -COMPATIBLE_IOCTL(BLKSSZGET) -COMPATIBLE_IOCTL(BLKBSZGET) /* RAID */ COMPATIBLE_IOCTL(RAID_VERSION) COMPATIBLE_IOCTL(GET_ARRAY_INFO) COMPATIBLE_IOCTL(GET_DISK_INFO) COMPATIBLE_IOCTL(PRINT_RAID_DEBUG) +COMPATIBLE_IOCTL(RAID_AUTORUN) COMPATIBLE_IOCTL(CLEAR_ARRAY) COMPATIBLE_IOCTL(ADD_NEW_DISK) COMPATIBLE_IOCTL(HOT_REMOVE_DISK) @@ -3015,12 +3038,26 @@ COMPATIBLE_IOCTL(PROTECT_ARRAY) COMPATIBLE_IOCTL(HOT_ADD_DISK) COMPATIBLE_IOCTL(SET_DISK_FAULTY) +COMPATIBLE_IOCTL(HOT_GENERATE_ERROR) COMPATIBLE_IOCTL(RUN_ARRAY) COMPATIBLE_IOCTL(START_ARRAY) COMPATIBLE_IOCTL(STOP_ARRAY) COMPATIBLE_IOCTL(STOP_ARRAY_RO) COMPATIBLE_IOCTL(RESTART_ARRAY_RW) +/* DM */ +COMPATIBLE_IOCTL(DM_VERSION) +COMPATIBLE_IOCTL(DM_REMOVE_ALL) +COMPATIBLE_IOCTL(DM_DEV_CREATE) +COMPATIBLE_IOCTL(DM_DEV_REMOVE) +COMPATIBLE_IOCTL(DM_DEV_RELOAD) +COMPATIBLE_IOCTL(DM_DEV_SUSPEND) +COMPATIBLE_IOCTL(DM_DEV_RENAME) +COMPATIBLE_IOCTL(DM_DEV_DEPS) +COMPATIBLE_IOCTL(DM_DEV_STATUS) +COMPATIBLE_IOCTL(DM_TARGET_STATUS) +COMPATIBLE_IOCTL(DM_TARGET_WAIT) + /* Big K */ COMPATIBLE_IOCTL(PIO_FONT) COMPATIBLE_IOCTL(GIO_FONT) @@ -3570,6 +3607,11 @@ HANDLE_IOCTL(0x1260, broken_blkgetsize) HANDLE_IOCTL(BLKSECTGET, w_long) HANDLE_IOCTL(BLKPG, blkpg_ioctl_trans) +/* take care of sizeof(sizeof()) breakage */ +/* block stuff */ +HANDLE_IOCTL(BLKBSZGET_32, do_blkbszget) +HANDLE_IOCTL(BLKBSZSET_32, do_blkbszset) +HANDLE_IOCTL(BLKGETSIZE64_32, do_blkgetsize64) HANDLE_IOCTL(FBIOGET_FSCREENINFO, fb_ioctl_trans) HANDLE_IOCTL(FBIOGETCMAP, fb_ioctl_trans) diff -Nru a/arch/parisc/kernel/module.c b/arch/parisc/kernel/module.c --- a/arch/parisc/kernel/module.c Tue Mar 18 15:05:35 2003 +++ b/arch/parisc/kernel/module.c Tue Mar 18 15:05:35 2003 @@ -562,10 +562,8 @@ #ifdef __LP64__ me->init = (void *)get_fdesc(me, (Elf_Addr)me->init); #ifdef CONFIG_MODULE_UNLOAD - if (me->cleanup) - me->cleanup = (void *)get_fdesc(me, (Elf_Addr)me->cleanup); - if (me->destroy) - me->destroy = (void *)get_fdesc(me, (Elf_Addr)me->destroy); + if (me->exit) + me->exit = (void *)get_fdesc(me, (Elf_Addr)me->exit); #endif #endif return 0; diff -Nru a/arch/parisc/kernel/pci.c b/arch/parisc/kernel/pci.c --- a/arch/parisc/kernel/pci.c Tue Mar 18 15:05:35 2003 +++ b/arch/parisc/kernel/pci.c Tue Mar 18 15:05:35 2003 @@ -83,16 +83,9 @@ u##size in##type (int addr) \ { \ int b = PCI_PORT_HBA(addr); \ - u##size d = (u##size) -1; \ EISA_IN(size); \ - ASSERT(pci_port); /* make sure services are defined */ \ - ASSERT(parisc_pci_hba[b]); /* make sure ioaddr are "fixed up" */ \ - if (parisc_pci_hba[b] == NULL) { \ - printk(KERN_WARNING "\nPCI or EISA Host Bus Adapter %d not registered. in" #size "(0x%x) returning -1\n", b, addr); \ - } else { \ - d = pci_port->in##type(parisc_pci_hba[b], PCI_PORT_ADDR(addr)); \ - } \ - return d; \ + if (!parisc_pci_hba[b]) return (u##size) -1; \ + return pci_port->in##type(parisc_pci_hba[b], PCI_PORT_ADDR(addr)); \ } PCI_PORT_IN(b, 8) @@ -105,7 +98,7 @@ { \ int b = PCI_PORT_HBA(addr); \ EISA_OUT(size); \ - ASSERT(pci_port); \ + if (!parisc_pci_hba[b]) return; \ pci_port->out##type(parisc_pci_hba[b], PCI_PORT_ADDR(addr), d); \ } @@ -318,9 +311,6 @@ EXPORT_SYMBOL(pcibios_resource_to_bus); #endif -#define MAX(val1, val2) ((val1) > (val2) ? (val1) : (val2)) - - /* ** pcibios align resources() is called everytime generic PCI code ** wants to generate a new address. The process of looking for @@ -349,7 +339,7 @@ align = (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM; /* Align to largest of MIN or input size */ - mask = MAX(alignment, align) - 1; + mask = max(alignment, align) - 1; res->start += mask; res->start &= ~mask; diff -Nru a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c --- a/arch/parisc/kernel/process.c Tue Mar 18 15:05:35 2003 +++ b/arch/parisc/kernel/process.c Tue Mar 18 15:05:35 2003 @@ -205,7 +205,16 @@ int dump_fpu (struct pt_regs * regs, elf_fpregset_t *r) { + if (regs == NULL) + return 0; + memcpy(r, regs->fr, sizeof *r); + return 1; +} + +int dump_task_fpu (struct task_struct *tsk, elf_fpregset_t *r) +{ + memcpy(r, tsk->thread.regs.fr, sizeof(*r)); return 1; } diff -Nru a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c --- a/arch/parisc/kernel/signal.c Tue Mar 18 15:05:35 2003 +++ b/arch/parisc/kernel/signal.c Tue Mar 18 15:05:35 2003 @@ -310,7 +310,7 @@ #endif #if CACHE_FLUSHING_IS_NOT_BROKEN - flush_icache_range((unsigned long) &frame->tramp[0], + flush_user_icache_range((unsigned long) &frame->tramp[0], (unsigned long) &frame->tramp[4]); #else /* It should *always* be cache line-aligned, but the compiler @@ -395,7 +395,7 @@ handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset, struct pt_regs *regs, int in_syscall) { - struct k_sigaction *ka = ¤t->sig->action[sig-1]; + struct k_sigaction *ka = ¤t->sighand->action[sig-1]; DBG(("handle_signal(sig=%ld, ka=%p, info=%p, oldset=%p, regs=%p)\n", sig, ka, info, oldset, regs)); @@ -451,7 +451,7 @@ oldset->sig[0], oldset->sig[1])); - signr = get_signal_to_deliver(&info, regs); + signr = get_signal_to_deliver(&info, regs, NULL); if (signr > 0) { /* Restart a system call if necessary. */ if (in_syscall) { @@ -463,7 +463,7 @@ break; case -ERESTARTSYS: - ka = ¤t->sig->action[signr-1]; + ka = ¤t->sighand->action[signr-1]; if (!(ka->sa.sa_flags & SA_RESTART)) { DBG(("ERESTARTSYS: putting -EINTR\n")); regs->gr[28] = -EINTR; diff -Nru a/arch/parisc/kernel/sys32.h b/arch/parisc/kernel/sys32.h --- a/arch/parisc/kernel/sys32.h Tue Mar 18 15:05:35 2003 +++ b/arch/parisc/kernel/sys32.h Tue Mar 18 15:05:35 2003 @@ -1,6 +1,8 @@ #ifndef _PARISC64_KERNEL_SYS32_H #define _PARISC64_KERNEL_SYS32_H +#include + /* Call a kernel syscall which will use kernel space instead of user * space for its copy_to/from_user. */ @@ -12,6 +14,8 @@ set_fs (old_fs); \ } +#ifdef CONFIG_COMPAT + typedef __u32 __sighandler_t32; struct sigaction32 { @@ -19,5 +23,7 @@ unsigned int sa_flags; compat_sigset_t sa_mask; /* mask last for extensibility */ }; + +#endif #endif diff -Nru a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c --- a/arch/parisc/kernel/sys_parisc.c Tue Mar 18 15:05:35 2003 +++ b/arch/parisc/kernel/sys_parisc.c Tue Mar 18 15:05:35 2003 @@ -309,25 +309,6 @@ return -ENOSYS; } -/* - * Set a given TLS descriptor: - */ -asmlinkage int sys_set_thread_area(struct user_desc *u_info) -{ - return -ENOSYS; -} - - -/* - * Get the current Thread-Local Storage area: - */ - -asmlinkage int sys_get_thread_area(struct user_desc *u_info) -{ - return -ENOSYS; -} - - asmlinkage unsigned long sys_alloc_hugepages(int key, unsigned long addr, unsigned long len, int prot, int flag) { return -ENOMEM; diff -Nru a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S --- a/arch/parisc/kernel/syscall.S Tue Mar 18 15:05:35 2003 +++ b/arch/parisc/kernel/syscall.S Tue Mar 18 15:05:35 2003 @@ -567,10 +567,10 @@ ENTRY_SAME(rt_sigsuspend_wrapper) /* not really SAME -- see the code */ ENTRY_SAME(chown) /* 180 */ /* setsockopt() used by iptables: SO_SET_REPLACE/SO_SET_ADD_COUNTERS */ - ENTRY_DIFF(setsockopt) + ENTRY_COMP(setsockopt) ENTRY_SAME(getsockopt) - ENTRY_DIFF(sendmsg) - ENTRY_DIFF(recvmsg) + ENTRY_COMP(sendmsg) + ENTRY_COMP(recvmsg) ENTRY_SAME(semop) /* 185 */ ENTRY_SAME(semget) ENTRY_DIFF(semctl_broken) @@ -600,8 +600,8 @@ ENTRY_COMP(futex) /* 210 */ ENTRY_SAME(sched_setaffinity) ENTRY_SAME(sched_getaffinity) - ENTRY_SAME(set_thread_area) - ENTRY_SAME(get_thread_area) + ENTRY_SAME(ni_syscall) + ENTRY_SAME(ni_syscall) ENTRY_SAME(io_setup) /* 215 */ ENTRY_SAME(io_destroy) ENTRY_SAME(io_getevents) diff -Nru a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c --- a/arch/parisc/kernel/traps.c Tue Mar 18 15:05:35 2003 +++ b/arch/parisc/kernel/traps.c Tue Mar 18 15:05:35 2003 @@ -27,6 +27,7 @@ #include #include +#include #include #include #include @@ -165,9 +166,11 @@ startstack = (unsigned long *)((unsigned long)stack & ~(THREAD_SIZE - 1)); i = 1; + stack = (long *)((long)(stack + 32) &~ (FRAME_SIZE-1)); /* Align */ printk("Kernel addresses on the stack:\n"); - while (stack >= startstack) { - addr = *stack--; + while (stack > startstack) { + stack -= 16; /* Stack frames are a multiple of 16 words */ + addr = stack[16 - RP_OFFSET / sizeof(long)]; /* * If the address is either in the text segment of the * kernel, or in the region which contains vmalloc'ed diff -Nru a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c --- a/arch/ppc/kernel/traps.c Tue Mar 18 15:05:35 2003 +++ b/arch/ppc/kernel/traps.c Tue Mar 18 15:05:35 2003 @@ -86,13 +86,14 @@ void die(const char * str, struct pt_regs * fp, long err) { + static int die_counter; console_verbose(); spin_lock_irq(&die_lock); #ifdef CONFIG_PMAC_BACKLIGHT set_backlight_enable(1); set_backlight_level(BACKLIGHT_MAX); #endif - printk("Oops: %s, sig: %ld\n", str, err); + printk("Oops: %s, sig: %ld [#%d]\n", str, err, ++die_counter); show_regs(fp); spin_unlock_irq(&die_lock); /* do_exit() should take care of panic'ing from an interrupt diff -Nru a/arch/ppc64/kernel/traps.c b/arch/ppc64/kernel/traps.c --- a/arch/ppc64/kernel/traps.c Tue Mar 18 15:05:35 2003 +++ b/arch/ppc64/kernel/traps.c Tue Mar 18 15:05:35 2003 @@ -62,10 +62,11 @@ void die(const char *str, struct pt_regs *regs, long err) { + static int die_counter; console_verbose(); spin_lock_irq(&die_lock); bust_spinlocks(1); - printk("Oops: %s, sig: %ld\n", str, err); + printk("Oops: %s, sig: %ld [#%d]\n", str, err, ++die_counter); show_regs(regs); bust_spinlocks(0); spin_unlock_irq(&die_lock); diff -Nru a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c --- a/arch/s390/kernel/traps.c Tue Mar 18 15:05:35 2003 +++ b/arch/s390/kernel/traps.c Tue Mar 18 15:05:35 2003 @@ -226,10 +226,11 @@ void die(const char * str, struct pt_regs * regs, long err) { + static int die_counter; console_verbose(); spin_lock_irq(&die_lock); bust_spinlocks(1); - printk("%s: %04lx\n", str, err & 0xffff); + printk("%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter); show_regs(regs); bust_spinlocks(0); spin_unlock_irq(&die_lock); diff -Nru a/arch/s390x/kernel/binfmt_elf32.c b/arch/s390x/kernel/binfmt_elf32.c --- a/arch/s390x/kernel/binfmt_elf32.c Tue Mar 18 15:05:35 2003 +++ b/arch/s390x/kernel/binfmt_elf32.c Tue Mar 18 15:05:35 2003 @@ -36,7 +36,7 @@ /* For SVR4/S390 the function pointer to be registered with `atexit` is passed in R14. */ -#define ELF_PLAT_INIT(_r) \ +#define ELF_PLAT_INIT(_r, load_addr) \ do { \ _r->gprs[14] = 0; \ set_thread_flag(TIF_31BIT); \ diff -Nru a/arch/s390x/kernel/traps.c b/arch/s390x/kernel/traps.c --- a/arch/s390x/kernel/traps.c Tue Mar 18 15:05:35 2003 +++ b/arch/s390x/kernel/traps.c Tue Mar 18 15:05:35 2003 @@ -228,10 +228,11 @@ void die(const char * str, struct pt_regs * regs, long err) { + static int die_counter; console_verbose(); spin_lock_irq(&die_lock); bust_spinlocks(1); - printk("%s: %04lx\n", str, err & 0xffff); + printk("%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter); show_regs(regs); bust_spinlocks(0); spin_unlock_irq(&die_lock); diff -Nru a/arch/sh/kernel/traps.c b/arch/sh/kernel/traps.c --- a/arch/sh/kernel/traps.c Tue Mar 18 15:05:35 2003 +++ b/arch/sh/kernel/traps.c Tue Mar 18 15:05:35 2003 @@ -58,9 +58,10 @@ void die(const char * str, struct pt_regs * regs, long err) { + static int die_counter; console_verbose(); spin_lock_irq(&die_lock); - printk("%s: %04lx\n", str, err & 0xffff); + printk("%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter); show_regs(regs); spin_unlock_irq(&die_lock); do_exit(SIGSEGV); diff -Nru a/arch/x86_64/ia32/ia32_binfmt.c b/arch/x86_64/ia32/ia32_binfmt.c --- a/arch/x86_64/ia32/ia32_binfmt.c Tue Mar 18 15:05:35 2003 +++ b/arch/x86_64/ia32/ia32_binfmt.c Tue Mar 18 15:05:35 2003 @@ -217,7 +217,7 @@ # define CONFIG_BINFMT_ELF_MODULE CONFIG_BINFMT_ELF32_MODULE #endif -#define ELF_PLAT_INIT(r) elf32_init(r) +#define ELF_PLAT_INIT(r, load_addr) elf32_init(r) #define setup_arg_pages(bprm) ia32_setup_arg_pages(bprm) int ia32_setup_arg_pages(struct linux_binprm *bprm); diff -Nru a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c --- a/arch/x86_64/kernel/traps.c Tue Mar 18 15:05:35 2003 +++ b/arch/x86_64/kernel/traps.c Tue Mar 18 15:05:35 2003 @@ -325,11 +325,12 @@ { int cpu; struct die_args args = { regs, str, err }; + static int die_counter; console_verbose(); notifier_call_chain(&die_chain, DIE_DIE, &args); bust_spinlocks(1); handle_BUG(regs); - printk("%s: %04lx\n", str, err & 0xffff); + printk("%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter); cpu = safe_smp_processor_id(); /* racy, but better than risking deadlock. */ local_irq_disable(); diff -Nru a/drivers/block/genhd.c b/drivers/block/genhd.c --- a/drivers/block/genhd.c Tue Mar 18 15:05:35 2003 +++ b/drivers/block/genhd.c Tue Mar 18 15:05:35 2003 @@ -538,12 +538,20 @@ struct gendisk *get_disk(struct gendisk *disk) { struct module *owner; + struct kobject *kobj; + if (!disk->fops) return NULL; owner = disk->fops->owner; if (owner && !try_module_get(owner)) return NULL; - return to_disk(kobject_get(&disk->kobj)); + kobj = kobject_get(&disk->kobj); + if (kobj == NULL) { + module_put(owner); + return NULL; + } + return to_disk(kobj); + } void put_disk(struct gendisk *disk) diff -Nru a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c --- a/drivers/block/ll_rw_blk.c Tue Mar 18 15:05:35 2003 +++ b/drivers/block/ll_rw_blk.c Tue Mar 18 15:05:35 2003 @@ -56,11 +56,7 @@ unsigned long blk_max_low_pfn, blk_max_pfn; int blk_nohighio = 0; -static struct congestion_state { - wait_queue_head_t wqh; - atomic_t nr_congested_queues; - atomic_t nr_active_queues; -} congestion_states[2]; +static wait_queue_head_t congestion_wqh[2]; /* * Return the threshold (number of free requests) at which the queue is @@ -98,14 +94,12 @@ static void clear_queue_congested(request_queue_t *q, int rw) { enum bdi_state bit; - struct congestion_state *cs = &congestion_states[rw]; + wait_queue_head_t *wqh = &congestion_wqh[rw]; bit = (rw == WRITE) ? BDI_write_congested : BDI_read_congested; - - if (test_and_clear_bit(bit, &q->backing_dev_info.state)) - atomic_dec(&cs->nr_congested_queues); - if (waitqueue_active(&cs->wqh)) - wake_up(&cs->wqh); + clear_bit(bit, &q->backing_dev_info.state); + if (waitqueue_active(wqh)) + wake_up(wqh); } /* @@ -117,37 +111,7 @@ enum bdi_state bit; bit = (rw == WRITE) ? BDI_write_congested : BDI_read_congested; - - if (!test_and_set_bit(bit, &q->backing_dev_info.state)) - atomic_inc(&congestion_states[rw].nr_congested_queues); -} - -/* - * A queue has just put back its last read or write request and has fallen - * idle. - */ -static void clear_queue_active(request_queue_t *q, int rw) -{ - enum bdi_state bit; - - bit = (rw == WRITE) ? BDI_write_active : BDI_read_active; - - if (test_and_clear_bit(bit, &q->backing_dev_info.state)) - atomic_dec(&congestion_states[rw].nr_active_queues); -} - -/* - * A queue has just taken its first read or write request and has become - * active. - */ -static void set_queue_active(request_queue_t *q, int rw) -{ - enum bdi_state bit; - - bit = (rw == WRITE) ? BDI_write_active : BDI_read_active; - - if (!test_and_set_bit(bit, &q->backing_dev_info.state)) - atomic_inc(&congestion_states[rw].nr_active_queues); + set_bit(bit, &q->backing_dev_info.state); } /** @@ -1325,8 +1289,6 @@ rq = blkdev_free_rq(&rl->free); list_del_init(&rq->queuelist); rq->ref_count = 1; - if (rl->count == queue_nr_requests) - set_queue_active(q, rw); rl->count--; if (rl->count < queue_congestion_on_threshold()) set_queue_congested(q, rw); @@ -1569,8 +1531,6 @@ rl->count++; if (rl->count >= queue_congestion_off_threshold()) clear_queue_congested(q, rw); - if (rl->count == queue_nr_requests) - clear_queue_active(q, rw); if (rl->count >= batch_requests && waitqueue_active(&rl->wait)) wake_up(&rl->wait); } @@ -1605,12 +1565,12 @@ void blk_congestion_wait(int rw, long timeout) { DEFINE_WAIT(wait); - struct congestion_state *cs = &congestion_states[rw]; + wait_queue_head_t *wqh = &congestion_wqh[rw]; blk_run_queues(); - prepare_to_wait(&cs->wqh, &wait, TASK_UNINTERRUPTIBLE); + prepare_to_wait(wqh, &wait, TASK_UNINTERRUPTIBLE); io_schedule_timeout(timeout); - finish_wait(&cs->wqh, &wait); + finish_wait(wqh, &wait); } /* @@ -2249,11 +2209,8 @@ blk_max_low_pfn = max_low_pfn; blk_max_pfn = max_pfn; - for (i = 0; i < ARRAY_SIZE(congestion_states); i++) { - init_waitqueue_head(&congestion_states[i].wqh); - atomic_set(&congestion_states[i].nr_congested_queues, 0); - atomic_set(&congestion_states[i].nr_active_queues, 0); - } + for (i = 0; i < ARRAY_SIZE(congestion_wqh); i++) + init_waitqueue_head(&congestion_wqh[i]); return 0; }; diff -Nru a/drivers/char/tty_io.c b/drivers/char/tty_io.c --- a/drivers/char/tty_io.c Tue Mar 18 15:05:35 2003 +++ b/drivers/char/tty_io.c Tue Mar 18 15:05:35 2003 @@ -1034,7 +1034,9 @@ } o_tty->magic = 0; (*o_tty->driver.refcount)--; + file_list_lock(); list_del(&o_tty->tty_files); + file_list_unlock(); free_tty_struct(o_tty); } @@ -1046,7 +1048,9 @@ } tty->magic = 0; (*tty->driver.refcount)--; + file_list_lock(); list_del(&tty->tty_files); + file_list_unlock(); module_put(tty->driver.owner); free_tty_struct(tty); } diff -Nru a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c --- a/drivers/char/vt_ioctl.c Tue Mar 18 15:05:35 2003 +++ b/drivers/char/vt_ioctl.c Tue Mar 18 15:05:35 2003 @@ -191,38 +191,56 @@ static inline int do_kdgkb_ioctl(int cmd, struct kbsentry *user_kdgkb, int perm) { - struct kbsentry tmp; + struct kbsentry *kbs; char *p; u_char *q; int sz; int delta; char *first_free, *fj, *fnw; int i, j, k; + int ret; + + kbs = kmalloc(sizeof(*kbs), GFP_KERNEL); + if (!kbs) { + ret = -ENOMEM; + goto reterr; + } /* we mostly copy too much here (512bytes), but who cares ;) */ - if (copy_from_user(&tmp, user_kdgkb, sizeof(struct kbsentry))) - return -EFAULT; - tmp.kb_string[sizeof(tmp.kb_string)-1] = '\0'; - if (tmp.kb_func >= MAX_NR_FUNC) - return -EINVAL; - i = tmp.kb_func; + if (copy_from_user(kbs, user_kdgkb, sizeof(struct kbsentry))) { + ret = -EFAULT; + goto reterr; + } + kbs->kb_string[sizeof(kbs->kb_string)-1] = '\0'; + if (kbs->kb_func >= MAX_NR_FUNC) { + ret = -EINVAL; + goto reterr; + } + i = kbs->kb_func; switch (cmd) { case KDGKBSENT: - sz = sizeof(tmp.kb_string) - 1; /* sz should have been + sz = sizeof(kbs->kb_string) - 1; /* sz should have been a struct member */ q = user_kdgkb->kb_string; p = func_table[i]; if(p) for ( ; *p && sz; p++, sz--) - if (put_user(*p, q++)) - return -EFAULT; - if (put_user('\0', q)) - return -EFAULT; + if (put_user(*p, q++)) { + ret = -EFAULT; + goto reterr; + } + if (put_user('\0', q)) { + ret = -EFAULT; + goto reterr; + } + kfree(kbs); return ((p && *p) ? -EOVERFLOW : 0); case KDSKBSENT: - if (!perm) - return -EPERM; + if (!perm) { + ret = -EPERM; + goto reterr; + } q = func_table[i]; first_free = funcbufptr + (funcbufsize - funcbufleft); @@ -233,7 +251,7 @@ else fj = first_free; - delta = (q ? -strlen(q) : 1) + strlen(tmp.kb_string); + delta = (q ? -strlen(q) : 1) + strlen(kbs->kb_string); if (delta <= funcbufleft) { /* it fits in current buf */ if (j < MAX_NR_FUNC) { memmove(fj + delta, fj, first_free - fj); @@ -249,8 +267,10 @@ while (sz < funcbufsize - funcbufleft + delta) sz <<= 1; fnw = (char *) kmalloc(sz, GFP_KERNEL); - if(!fnw) - return -ENOMEM; + if(!fnw) { + ret = -ENOMEM; + goto reterr; + } if (!q) func_table[i] = fj; @@ -272,17 +292,19 @@ funcbufleft = funcbufleft - delta + sz - funcbufsize; funcbufsize = sz; } - strcpy(func_table[i], tmp.kb_string); + strcpy(func_table[i], kbs->kb_string); break; } - return 0; + ret = 0; +reterr: + kfree(kbs); + return ret; } static inline int -do_fontx_ioctl(int cmd, struct consolefontdesc *user_cfd, int perm) +do_fontx_ioctl(int cmd, struct consolefontdesc *user_cfd, int perm, struct console_font_op *op) { struct consolefontdesc cfdarg; - struct console_font_op op; int i; if (copy_from_user(&cfdarg, user_cfd, sizeof(struct consolefontdesc))) @@ -292,25 +314,25 @@ case PIO_FONTX: if (!perm) return -EPERM; - op.op = KD_FONT_OP_SET; - op.flags = KD_FONT_FLAG_OLD; - op.width = 8; - op.height = cfdarg.charheight; - op.charcount = cfdarg.charcount; - op.data = cfdarg.chardata; - return con_font_op(fg_console, &op); + op->op = KD_FONT_OP_SET; + op->flags = KD_FONT_FLAG_OLD; + op->width = 8; + op->height = cfdarg.charheight; + op->charcount = cfdarg.charcount; + op->data = cfdarg.chardata; + return con_font_op(fg_console, op); case GIO_FONTX: { - op.op = KD_FONT_OP_GET; - op.flags = KD_FONT_FLAG_OLD; - op.width = 8; - op.height = cfdarg.charheight; - op.charcount = cfdarg.charcount; - op.data = cfdarg.chardata; - i = con_font_op(fg_console, &op); + op->op = KD_FONT_OP_GET; + op->flags = KD_FONT_FLAG_OLD; + op->width = 8; + op->height = cfdarg.charheight; + op->charcount = cfdarg.charcount; + op->data = cfdarg.chardata; + i = con_font_op(fg_console, op); if (i) return i; - cfdarg.charheight = op.height; - cfdarg.charcount = op.charcount; + cfdarg.charheight = op->height; + cfdarg.charcount = op->charcount; if (copy_to_user(user_cfd, &cfdarg, sizeof(struct consolefontdesc))) return -EFAULT; return 0; @@ -355,6 +377,7 @@ unsigned char ucval; struct kbd_struct * kbd; struct vt_struct *vt = (struct vt_struct *)tty->driver_data; + struct console_font_op op; /* used in multiple places here */ console = vt->vc_num; @@ -860,7 +883,6 @@ } case PIO_FONT: { - struct console_font_op op; if (!perm) return -EPERM; op.op = KD_FONT_OP_SET; @@ -873,7 +895,6 @@ } case GIO_FONT: { - struct console_font_op op; op.op = KD_FONT_OP_GET; op.flags = KD_FONT_FLAG_OLD; op.width = 8; @@ -893,7 +914,7 @@ case PIO_FONTX: case GIO_FONTX: - return do_fontx_ioctl(cmd, (struct consolefontdesc *)arg, perm); + return do_fontx_ioctl(cmd, (struct consolefontdesc *)arg, perm, &op); case PIO_FONTRESET: { @@ -906,7 +927,6 @@ return -ENOSYS; #else { - struct console_font_op op; op.op = KD_FONT_OP_SET_DEFAULT; op.data = NULL; i = con_font_op(fg_console, &op); @@ -918,7 +938,6 @@ } case KDFONTOP: { - struct console_font_op op; if (copy_from_user(&op, (void *) arg, sizeof(op))) return -EFAULT; if (!perm && op.op != KD_FONT_OP_GET) diff -Nru a/drivers/oprofile/buffer_sync.c b/drivers/oprofile/buffer_sync.c --- a/drivers/oprofile/buffer_sync.c Tue Mar 18 15:05:35 2003 +++ b/drivers/oprofile/buffer_sync.c Tue Mar 18 15:05:35 2003 @@ -82,9 +82,16 @@ int sync_start(void) { - int err = profile_event_register(EXIT_TASK, &exit_task_nb); + int err; + + init_timer(&sync_timer); + sync_timer.function = timer_ping; + sync_timer.expires = jiffies + DEFAULT_EXPIRE; + add_timer(&sync_timer); + + err = profile_event_register(EXIT_TASK, &exit_task_nb); if (err) - goto out; + goto out1; err = profile_event_register(EXIT_MMAP, &exit_mmap_nb); if (err) goto out2; @@ -92,16 +99,14 @@ if (err) goto out3; - init_timer(&sync_timer); - sync_timer.function = timer_ping; - sync_timer.expires = jiffies + DEFAULT_EXPIRE; - add_timer(&sync_timer); out: return err; out3: profile_event_unregister(EXIT_MMAP, &exit_mmap_nb); out2: profile_event_unregister(EXIT_TASK, &exit_task_nb); +out1: + del_timer_sync(&sync_timer); goto out; } diff -Nru a/fs/binfmt_elf.c b/fs/binfmt_elf.c --- a/fs/binfmt_elf.c Tue Mar 18 15:05:35 2003 +++ b/fs/binfmt_elf.c Tue Mar 18 15:05:35 2003 @@ -452,6 +452,7 @@ unsigned int size; unsigned long elf_entry, interp_load_addr = 0; unsigned long start_code, end_code, start_data, end_data; + unsigned long reloc_func_desc = 0; struct elfhdr elf_ex; struct elfhdr interp_elf_ex; struct exec interp_ex; @@ -695,6 +696,7 @@ load_bias += error - ELF_PAGESTART(load_bias + vaddr); load_addr += load_bias; + reloc_func_desc = load_addr; } } k = elf_ppnt->p_vaddr; @@ -742,6 +744,7 @@ retval = -ENOEXEC; /* Nobody gets to see this, but.. */ goto out; } + reloc_func_desc = interp_load_addr; } else { elf_entry = elf_ex.e_entry; } @@ -789,10 +792,14 @@ /* * The ABI may specify that certain registers be set up in special * ways (on i386 %edx is the address of a DT_FINI function, for - * example. This macro performs whatever initialization to - * the regs structure is required. + * example. In addition, it may also specify (eg, PowerPC64 ELF) + * that the e_entry field is the address of the function descriptor + * for the startup routine, rather than the address of the startup + * routine itself. This macro performs whatever initialization to + * the regs structure is required as well as any relocations to the + * function descriptor entries when executing dynamically links apps. */ - ELF_PLAT_INIT(regs); + ELF_PLAT_INIT(regs, reloc_func_desc); #endif start_thread(regs, elf_entry, bprm->p); diff -Nru a/fs/dcache.c b/fs/dcache.c --- a/fs/dcache.c Tue Mar 18 15:05:35 2003 +++ b/fs/dcache.c Tue Mar 18 15:05:35 2003 @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -1574,7 +1575,7 @@ filp_cachep = kmem_cache_create("filp", sizeof(struct file), 0, - SLAB_HWCACHE_ALIGN, NULL, NULL); + SLAB_HWCACHE_ALIGN, filp_ctor, filp_dtor); if(!filp_cachep) panic("Cannot create filp SLAB cache"); diff -Nru a/fs/exec.c b/fs/exec.c --- a/fs/exec.c Tue Mar 18 15:05:35 2003 +++ b/fs/exec.c Tue Mar 18 15:05:35 2003 @@ -633,7 +633,7 @@ count = 1; while (atomic_read(&oldsig->count) > count) { oldsig->group_exit_task = current; - current->state = TASK_UNINTERRUPTIBLE; + __set_current_state(TASK_UNINTERRUPTIBLE); spin_unlock_irq(lock); schedule(); spin_lock_irq(lock); diff -Nru a/fs/file_table.c b/fs/file_table.c --- a/fs/file_table.c Tue Mar 18 15:05:35 2003 +++ b/fs/file_table.c Tue Mar 18 15:05:35 2003 @@ -22,72 +22,81 @@ .max_files = NR_FILE }; -/* Here the new files go */ -static LIST_HEAD(anon_list); -/* And here the free ones sit */ -static LIST_HEAD(free_list); /* public *and* exported. Not pretty! */ -spinlock_t files_lock __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED; +spinlock_t __cacheline_aligned_in_smp files_lock = SPIN_LOCK_UNLOCKED; + +static spinlock_t filp_count_lock = SPIN_LOCK_UNLOCKED; + +/* slab constructors and destructors are called from arbitrary + * context and must be fully threaded - use a local spinlock + * to protect files_stat.nr_files + */ +void filp_ctor(void * objp, struct kmem_cache_s *cachep, unsigned long cflags) +{ + if ((cflags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == + SLAB_CTOR_CONSTRUCTOR) { + unsigned long flags; + spin_lock_irqsave(&filp_count_lock, flags); + files_stat.nr_files++; + spin_unlock_irqrestore(&filp_count_lock, flags); + } +} + +void filp_dtor(void * objp, struct kmem_cache_s *cachep, unsigned long dflags) +{ + unsigned long flags; + spin_lock_irqsave(&filp_count_lock, flags); + files_stat.nr_files--; + spin_unlock_irqrestore(&filp_count_lock, flags); +} + +static inline void file_free(struct file *f) +{ + kmem_cache_free(filp_cachep, f); +} /* Find an unused file structure and return a pointer to it. * Returns NULL, if there are no more free file structures or * we run out of memory. - * - * SMP-safe. */ -struct file * get_empty_filp(void) +struct file *get_empty_filp(void) { - static int old_max = 0; +static int old_max = 0; struct file * f; - file_list_lock(); - if (files_stat.nr_free_files > NR_RESERVED_FILES) { - used_one: - f = list_entry(free_list.next, struct file, f_list); - list_del(&f->f_list); - files_stat.nr_free_files--; - new_one: - memset(f, 0, sizeof(*f)); - if (security_file_alloc(f)) { - list_add(&f->f_list, &free_list); - files_stat.nr_free_files++; - file_list_unlock(); - return NULL; - } - eventpoll_init_file(f); - atomic_set(&f->f_count,1); - f->f_version = 0; - f->f_uid = current->fsuid; - f->f_gid = current->fsgid; - f->f_owner.lock = RW_LOCK_UNLOCKED; - list_add(&f->f_list, &anon_list); - file_list_unlock(); - return f; - } - /* - * Use a reserved one if we're the superuser - */ - if (files_stat.nr_free_files && !current->euid) - goto used_one; /* - * Allocate a new one if we're below the limit. + * Privileged users can go above max_files */ - if (files_stat.nr_files < files_stat.max_files) { - file_list_unlock(); - f = kmem_cache_alloc(filp_cachep, SLAB_KERNEL); - file_list_lock(); + if (files_stat.nr_files < files_stat.max_files || + capable(CAP_SYS_ADMIN)) { + f = kmem_cache_alloc(filp_cachep, GFP_KERNEL); if (f) { - files_stat.nr_files++; - goto new_one; + memset(f, 0, sizeof(*f)); + if (security_file_alloc(f)) { + file_free(f); + goto fail; + } + eventpoll_init_file(f); + atomic_set(&f->f_count, 1); + f->f_uid = current->fsuid; + f->f_gid = current->fsgid; + f->f_owner.lock = RW_LOCK_UNLOCKED; + /* f->f_version: 0 */ + INIT_LIST_HEAD(&f->f_list); + return f; } - /* Big problems... */ - printk(KERN_WARNING "VFS: filp allocation failed\n"); + } - } else if (files_stat.max_files > old_max) { - printk(KERN_INFO "VFS: file-max limit %d reached\n", files_stat.max_files); + /* Ran out of filps - report that */ + if (files_stat.max_files >= old_max) { + printk(KERN_INFO "VFS: file-max limit %d reached\n", + files_stat.max_files); old_max = files_stat.max_files; + } else { + /* Big problems... */ + printk(KERN_WARNING "VFS: filp allocation failed\n"); } - file_list_unlock(); +fail: return NULL; } @@ -108,6 +117,7 @@ filp->f_uid = current->fsuid; filp->f_gid = current->fsgid; filp->f_op = dentry->d_inode->i_fop; + INIT_LIST_HEAD(&filp->f_list); error = security_file_alloc(filp); if (!error) if (filp->f_op && filp->f_op->open) { @@ -140,11 +150,11 @@ /* __fput is called from task context when aio completion releases the last * last use of a struct file *. Do not use otherwise. */ -void __fput(struct file * file) +void __fput(struct file *file) { - struct dentry * dentry = file->f_dentry; - struct vfsmount * mnt = file->f_vfsmnt; - struct inode * inode = dentry->d_inode; + struct dentry *dentry = file->f_dentry; + struct vfsmount *mnt = file->f_vfsmnt; + struct inode *inode = dentry->d_inode; /* * The function eventpoll_release() should be the first called @@ -159,20 +169,17 @@ fops_put(file->f_op); if (file->f_mode & FMODE_WRITE) put_write_access(inode); - file_list_lock(); file->f_dentry = NULL; file->f_vfsmnt = NULL; - list_del(&file->f_list); - list_add(&file->f_list, &free_list); - files_stat.nr_free_files++; - file_list_unlock(); + file_kill(file); + file_free(file); dput(dentry); mntput(mnt); } -struct file * fget(unsigned int fd) +struct file *fget(unsigned int fd) { - struct file * file; + struct file *file; struct files_struct *files = current->files; read_lock(&files->file_lock); @@ -183,17 +190,12 @@ return file; } -/* Here. put_filp() is SMP-safe now. */ - void put_filp(struct file *file) { - if(atomic_dec_and_test(&file->f_count)) { + if (atomic_dec_and_test(&file->f_count)) { security_file_free(file); - file_list_lock(); - list_del(&file->f_list); - list_add(&file->f_list, &free_list); - files_stat.nr_free_files++; - file_list_unlock(); + file_kill(file); + file_free(file); } } @@ -202,16 +204,17 @@ if (!list) return; file_list_lock(); - list_del(&file->f_list); - list_add(&file->f_list, list); + list_move(&file->f_list, list); file_list_unlock(); } void file_kill(struct file *file) { - file_list_lock(); - list_del_init(&file->f_list); - file_list_unlock(); + if (!list_empty(&file->f_list)) { + file_list_lock(); + list_del_init(&file->f_list); + file_list_unlock(); + } } int fs_may_remount_ro(struct super_block *sb) @@ -228,7 +231,7 @@ if (inode->i_nlink == 0) goto too_bad; - /* Writable file? */ + /* Writeable file? */ if (S_ISREG(inode->i_mode) && (file->f_mode & FMODE_WRITE)) goto too_bad; } diff -Nru a/fs/inode.c b/fs/inode.c --- a/fs/inode.c Tue Mar 18 15:05:35 2003 +++ b/fs/inode.c Tue Mar 18 15:05:35 2003 @@ -1214,7 +1214,7 @@ goto repeat; } remove_wait_queue(wq, &wait); - current->state = TASK_RUNNING; + __set_current_state(TASK_RUNNING); } void wake_up_inode(struct inode *inode) diff -Nru a/fs/locks.c b/fs/locks.c --- a/fs/locks.c Tue Mar 18 15:05:35 2003 +++ b/fs/locks.c Tue Mar 18 15:05:35 2003 @@ -565,7 +565,7 @@ int result = 0; DECLARE_WAITQUEUE(wait, current); - current->state = TASK_INTERRUPTIBLE; + __set_current_state(TASK_INTERRUPTIBLE); add_wait_queue(fl_wait, &wait); if (timeout == 0) schedule(); @@ -574,7 +574,7 @@ if (signal_pending(current)) result = -ERESTARTSYS; remove_wait_queue(fl_wait, &wait); - current->state = TASK_RUNNING; + __set_current_state(TASK_RUNNING); return result; } diff -Nru a/fs/nfs/inode.c b/fs/nfs/inode.c --- a/fs/nfs/inode.c Tue Mar 18 15:05:35 2003 +++ b/fs/nfs/inode.c Tue Mar 18 15:05:35 2003 @@ -1231,6 +1231,7 @@ if (root->size > sizeof(root->data)) { printk("nfs_get_sb: invalid root filehandle\n"); + kfree(server); return ERR_PTR(-EINVAL); } /* We now require that the mount process passes the remote address */ diff -Nru a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c --- a/fs/nfsd/vfs.c Tue Mar 18 15:05:35 2003 +++ b/fs/nfsd/vfs.c Tue Mar 18 15:05:35 2003 @@ -1203,7 +1203,9 @@ iap->ia_mode = (iap->ia_mode&S_IALLUGO) | S_IFLNK; err = notify_change(dnew, iap); - if (!err && EX_ISSYNC(fhp->fh_export)) + if (err) + err = nfserrno(err); + else if (EX_ISSYNC(fhp->fh_export)) write_inode_now(dentry->d_inode, 1); } } diff -Nru a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c --- a/fs/proc/proc_misc.c Tue Mar 18 15:05:35 2003 +++ b/fs/proc/proc_misc.c Tue Mar 18 15:05:35 2003 @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -521,6 +522,28 @@ .write = write_profile, }; +#ifdef CONFIG_MAGIC_SYSRQ +/* + * writing 'C' to /proc/sysrq-trigger is like sysrq-C + */ +static ssize_t write_sysrq_trigger(struct file *file, const char *buf, + size_t count, loff_t *ppos) +{ + if (count) { + char c; + + if (get_user(c, buf)) + return -EFAULT; + handle_sysrq(c, NULL, NULL); + } + return count; +} + +static struct file_operations proc_sysrq_trigger_operations = { + .write = write_sysrq_trigger, +}; +#endif + struct proc_dir_entry *proc_root_kcore; static void create_seq_entry(char *name, mode_t mode, struct file_operations *f) @@ -592,6 +615,11 @@ entry->size = (1+prof_len) * sizeof(unsigned int); } } +#ifdef CONFIG_MAGIC_SYSRQ + entry = create_proc_entry("sysrq-trigger", S_IWUSR, NULL); + if (entry) + entry->proc_fops = &proc_sysrq_trigger_operations; +#endif #ifdef CONFIG_PPC32 { extern struct file_operations ppc_htab_operations; diff -Nru a/fs/select.c b/fs/select.c --- a/fs/select.c Tue Mar 18 15:05:35 2003 +++ b/fs/select.c Tue Mar 18 15:05:35 2003 @@ -235,7 +235,7 @@ } __timeout = schedule_timeout(__timeout); } - current->state = TASK_RUNNING; + __set_current_state(TASK_RUNNING); poll_freewait(&table); @@ -425,7 +425,7 @@ break; timeout = schedule_timeout(timeout); } - current->state = TASK_RUNNING; + __set_current_state(TASK_RUNNING); return count; } diff -Nru a/fs/ufs/util.c b/fs/ufs/util.c --- a/fs/ufs/util.c Tue Mar 18 15:05:35 2003 +++ b/fs/ufs/util.c Tue Mar 18 15:05:35 2003 @@ -48,6 +48,7 @@ failed: for (j = 0; j < i; j++) brelse (ubh->bh[j]); + kfree(ubh); return NULL; } diff -Nru a/include/asm-alpha/elf.h b/include/asm-alpha/elf.h --- a/include/asm-alpha/elf.h Tue Mar 18 15:05:35 2003 +++ b/include/asm-alpha/elf.h Tue Mar 18 15:05:35 2003 @@ -50,7 +50,7 @@ we start programs with a value of 0 to indicate that there is no such function. */ -#define ELF_PLAT_INIT(_r) _r->r0 = 0 +#define ELF_PLAT_INIT(_r, load_addr) _r->r0 = 0 /* The registers are layed out in pt_regs for PAL and syscall convenience. Re-order them for the linear elf_gregset_t. */ diff -Nru a/include/asm-arm/elf.h b/include/asm-arm/elf.h --- a/include/asm-arm/elf.h Tue Mar 18 15:05:35 2003 +++ b/include/asm-arm/elf.h Tue Mar 18 15:05:35 2003 @@ -48,7 +48,7 @@ /* When the program starts, a1 contains a pointer to a function to be registered with atexit, as per the SVR4 ABI. A value of 0 means we have no such handler. */ -#define ELF_PLAT_INIT(_r) (_r)->ARM_r0 = 0 +#define ELF_PLAT_INIT(_r, load_addr) (_r)->ARM_r0 = 0 /* This yields a mask that user programs can use to figure out what instruction set this cpu supports. */ diff -Nru a/include/asm-cris/elf.h b/include/asm-cris/elf.h --- a/include/asm-cris/elf.h Tue Mar 18 15:05:35 2003 +++ b/include/asm-cris/elf.h Tue Mar 18 15:05:35 2003 @@ -39,7 +39,7 @@ A value of 0 tells we have no such handler. */ /* Explicitly set registers to 0 to increase determinism. */ -#define ELF_PLAT_INIT(_r) do { \ +#define ELF_PLAT_INIT(_r, load_addr) do { \ (_r)->r13 = 0; (_r)->r12 = 0; (_r)->r11 = 0; (_r)->r10 = 0; \ (_r)->r9 = 0; (_r)->r8 = 0; (_r)->r7 = 0; (_r)->r6 = 0; \ (_r)->r5 = 0; (_r)->r4 = 0; (_r)->r3 = 0; (_r)->r2 = 0; \ diff -Nru a/include/asm-i386/elf.h b/include/asm-i386/elf.h --- a/include/asm-i386/elf.h Tue Mar 18 15:05:35 2003 +++ b/include/asm-i386/elf.h Tue Mar 18 15:05:35 2003 @@ -43,7 +43,7 @@ We might as well make sure everything else is cleared too (except for %esp), just to make things more deterministic. */ -#define ELF_PLAT_INIT(_r) do { \ +#define ELF_PLAT_INIT(_r, load_addr) do { \ _r->ebx = 0; _r->ecx = 0; _r->edx = 0; \ _r->esi = 0; _r->edi = 0; _r->ebp = 0; \ _r->eax = 0; \ diff -Nru a/include/asm-i386/hw_irq.h b/include/asm-i386/hw_irq.h --- a/include/asm-i386/hw_irq.h Tue Mar 18 15:05:35 2003 +++ b/include/asm-i386/hw_irq.h Tue Mar 18 15:05:35 2003 @@ -56,6 +56,7 @@ extern void print_IO_APIC(void); extern int IO_APIC_get_PCI_irq_vector(int bus, int slot, int fn); extern void send_IPI(int dest, int vector); +extern void setup_ioapic_dest(unsigned long mask); extern unsigned long io_apic_irqs; diff -Nru a/include/asm-i386/pgtable.h b/include/asm-i386/pgtable.h --- a/include/asm-i386/pgtable.h Tue Mar 18 15:05:35 2003 +++ b/include/asm-i386/pgtable.h Tue Mar 18 15:05:35 2003 @@ -231,18 +231,41 @@ #define pmd_large(pmd) \ ((pmd_val(pmd) & (_PAGE_PSE|_PAGE_PRESENT)) == (_PAGE_PSE|_PAGE_PRESENT)) -/* to find an entry in a page-table-directory. */ +/* + * the pgd page can be thought of an array like this: pgd_t[PTRS_PER_PGD] + * + * this macro returns the index of the entry in the pgd page which would + * control the given virtual address + */ #define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1)) +/* + * pgd_offset() returns a (pgd_t *) + * pgd_index() is used get the offset into the pgd page's array of pgd_t's; + */ #define pgd_offset(mm, address) ((mm)->pgd+pgd_index(address)) -/* to find an entry in a kernel page-table-directory */ +/* + * a shortcut which implies the use of the kernel's pgd, instead + * of a process's + */ #define pgd_offset_k(address) pgd_offset(&init_mm, address) +/* + * the pmd page can be thought of an array like this: pmd_t[PTRS_PER_PMD] + * + * this macro returns the index of the entry in the pmd page which would + * control the given virtual address + */ #define pmd_index(address) \ (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1)) -/* Find an entry in the third-level page table.. */ +/* + * the pte page can be thought of an array like this: pte_t[PTRS_PER_PTE] + * + * this macro returns the index of the entry in the pte page which would + * control the given virtual address + */ #define pte_index(address) \ (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)) #define pte_offset_kernel(dir, address) \ diff -Nru a/include/asm-ia64/elf.h b/include/asm-ia64/elf.h --- a/include/asm-ia64/elf.h Tue Mar 18 15:05:35 2003 +++ b/include/asm-ia64/elf.h Tue Mar 18 15:05:35 2003 @@ -50,7 +50,7 @@ * talk to him... */ extern void ia64_init_addr_space (void); -#define ELF_PLAT_INIT(_r) ia64_init_addr_space() +#define ELF_PLAT_INIT(_r, load_addr) ia64_init_addr_space() /* ELF register definitions. This is needed for core dump support. */ diff -Nru a/include/asm-ia64/ia32.h b/include/asm-ia64/ia32.h --- a/include/asm-ia64/ia32.h Tue Mar 18 15:05:35 2003 +++ b/include/asm-ia64/ia32.h Tue Mar 18 15:05:35 2003 @@ -306,7 +306,7 @@ #define ELF_ET_DYN_BASE (IA32_PAGE_OFFSET/3 + 0x1000000) void ia64_elf32_init(struct pt_regs *regs); -#define ELF_PLAT_INIT(_r) ia64_elf32_init(_r) +#define ELF_PLAT_INIT(_r, load_addr) ia64_elf32_init(_r) #define elf_addr_t u32 diff -Nru a/include/asm-m68k/elf.h b/include/asm-m68k/elf.h --- a/include/asm-m68k/elf.h Tue Mar 18 15:05:35 2003 +++ b/include/asm-m68k/elf.h Tue Mar 18 15:05:35 2003 @@ -31,7 +31,7 @@ /* For SVR4/m68k the function pointer to be registered with `atexit' is passed in %a1. Although my copy of the ABI has no such statement, it is actually used on ASV. */ -#define ELF_PLAT_INIT(_r) _r->a1 = 0 +#define ELF_PLAT_INIT(_r, load_addr) _r->a1 = 0 #define USE_ELF_CORE_DUMP #ifndef CONFIG_SUN3 diff -Nru a/include/asm-m68knommu/elf.h b/include/asm-m68knommu/elf.h --- a/include/asm-m68knommu/elf.h Tue Mar 18 15:05:35 2003 +++ b/include/asm-m68knommu/elf.h Tue Mar 18 15:05:35 2003 @@ -31,7 +31,7 @@ /* For SVR4/m68k the function pointer to be registered with `atexit' is passed in %a1. Although my copy of the ABI has no such statement, it is actually used on ASV. */ -#define ELF_PLAT_INIT(_r) _r->a1 = 0 +#define ELF_PLAT_INIT(_r, load_addr) _r->a1 = 0 #define USE_ELF_CORE_DUMP #ifndef CONFIG_SUN3 diff -Nru a/include/asm-mips/elf.h b/include/asm-mips/elf.h --- a/include/asm-mips/elf.h Tue Mar 18 15:05:35 2003 +++ b/include/asm-mips/elf.h Tue Mar 18 15:05:35 2003 @@ -73,7 +73,7 @@ * See comments in asm-alpha/elf.h, this is the same thing * on the MIPS. */ -#define ELF_PLAT_INIT(_r) do { \ +#define ELF_PLAT_INIT(_r, load_addr) do { \ _r->regs[1] = _r->regs[2] = _r->regs[3] = _r->regs[4] = 0; \ _r->regs[5] = _r->regs[6] = _r->regs[7] = _r->regs[8] = 0; \ _r->regs[9] = _r->regs[10] = _r->regs[11] = _r->regs[12] = 0; \ diff -Nru a/include/asm-mips64/elf.h b/include/asm-mips64/elf.h --- a/include/asm-mips64/elf.h Tue Mar 18 15:05:35 2003 +++ b/include/asm-mips64/elf.h Tue Mar 18 15:05:35 2003 @@ -76,7 +76,7 @@ * See comments in asm-alpha/elf.h, this is the same thing * on the MIPS. */ -#define ELF_PLAT_INIT(_r) do { \ +#define ELF_PLAT_INIT(_r, load_addr) do { \ _r->regs[1] = _r->regs[2] = _r->regs[3] = _r->regs[4] = 0; \ _r->regs[5] = _r->regs[6] = _r->regs[7] = _r->regs[8] = 0; \ _r->regs[9] = _r->regs[10] = _r->regs[11] = _r->regs[12] = 0; \ diff -Nru a/include/asm-parisc/assembly.h b/include/asm-parisc/assembly.h --- a/include/asm-parisc/assembly.h Tue Mar 18 15:05:35 2003 +++ b/include/asm-parisc/assembly.h Tue Mar 18 15:05:35 2003 @@ -21,7 +21,25 @@ #ifndef _PARISC_ASSEMBLY_H #define _PARISC_ASSEMBLY_H -#if defined(__LP64__) && defined(__ASSEMBLY__) +#ifdef __LP64__ +#define LDREG ldd +#define STREG std +#define LDREGM ldd,mb +#define STREGM std,ma +#define RP_OFFSET 16 +#define FRAME_SIZE 128 +#else +#define LDREG ldw +#define STREG stw +#define LDREGM ldwm +#define STREGM stwm +#define RP_OFFSET 20 +#define FRAME_SIZE 64 +#endif + +#ifdef __ASSEMBLY__ + +#ifdef __LP64__ /* the 64-bit pa gnu assembler unfortunately defaults to .level 1.1 or 2.0 so * work around that for now... */ .level 2.0w @@ -101,22 +119,6 @@ ldo R%\value(\reg), \reg .endm -#ifdef __LP64__ -#define LDREG ldd -#define STREG std -#define LDREGM ldd,mb -#define STREGM std,ma -#define RP_OFFSET 16 -#define FRAME_SIZE 128 -#else -#define LDREG ldw -#define STREG stw -#define LDREGM ldwm -#define STREGM stwm -#define RP_OFFSET 20 -#define FRAME_SIZE 64 -#endif - .macro loadgp #ifdef __LP64__ ldil L%__gp, %r27 @@ -420,4 +422,5 @@ REST_CR (%cr22, PT_PSW (\regs)) .endm +#endif /* __ASSEMBLY__ */ #endif diff -Nru a/include/asm-parisc/bug.h b/include/asm-parisc/bug.h --- a/include/asm-parisc/bug.h Tue Mar 18 15:05:35 2003 +++ b/include/asm-parisc/bug.h Tue Mar 18 15:05:35 2003 @@ -5,7 +5,9 @@ * Tell the user there is some problem. */ #define BUG() do { \ + extern void dump_stack(void); \ printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \ + dump_stack(); \ } while (0) #define PAGE_BUG(page) do { \ diff -Nru a/include/asm-parisc/cacheflush.h b/include/asm-parisc/cacheflush.h --- a/include/asm-parisc/cacheflush.h Tue Mar 18 15:05:35 2003 +++ b/include/asm-parisc/cacheflush.h Tue Mar 18 15:05:35 2003 @@ -25,9 +25,14 @@ extern void flush_cache_all_local(void); +static inline void cacheflush_h_tmp_function(void *dummy) +{ + flush_cache_all_local(); +} + static inline void flush_cache_all(void) { - on_each_cpu((void (*)(void *))flush_cache_all_local, NULL, 1, 1); + on_each_cpu(cacheflush_h_tmp_function, NULL, 1, 1); } /* The following value needs to be tuned and probably scaled with the @@ -62,13 +67,15 @@ #endif } +extern void __flush_dcache_page(struct page *page); + static inline void flush_dcache_page(struct page *page) { if (page->mapping && list_empty(&page->mapping->i_mmap) && list_empty(&page->mapping->i_mmap_shared)) { set_bit(PG_dcache_dirty, &page->flags); } else { - flush_kernel_dcache_page(page_address(page)); + __flush_dcache_page(page); } } diff -Nru a/include/asm-parisc/compat.h b/include/asm-parisc/compat.h --- a/include/asm-parisc/compat.h Tue Mar 18 15:05:35 2003 +++ b/include/asm-parisc/compat.h Tue Mar 18 15:05:35 2003 @@ -18,6 +18,7 @@ typedef u32 compat_ino_t; typedef u32 compat_dev_t; typedef s32 compat_off_t; +typedef s64 compat_loff_t; typedef u16 compat_nlink_t; typedef u16 compat_ipc_pid_t; typedef s32 compat_daddr_t; @@ -96,7 +97,7 @@ typedef u32 compat_old_sigset_t; /* at least 32 bits */ #define _COMPAT_NSIG 64 -#define _COMPAT_NSIG_BPW BITS_PER_LONG +#define _COMPAT_NSIG_BPW 32 typedef u32 compat_sigset_word; diff -Nru a/include/asm-parisc/elf.h b/include/asm-parisc/elf.h --- a/include/asm-parisc/elf.h Tue Mar 18 15:05:35 2003 +++ b/include/asm-parisc/elf.h Tue Mar 18 15:05:35 2003 @@ -99,6 +99,9 @@ typedef double elf_fpreg_t; typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; +extern int dump_task_fpu (struct task_struct *, elf_fpregset_t *); +#define ELF_CORE_COPY_FPREGS(tsk, elf_fpregs) dump_task_fpu(tsk, elf_fpregs) + struct pt_regs; /* forward declaration... */ @@ -118,7 +121,7 @@ So that we can use the same startup file with static executables, we start programs with a value of 0 to indicate that there is no such function. */ -#define ELF_PLAT_INIT(_r) _r->gr[23] = 0 +#define ELF_PLAT_INIT(_r, load_addr) _r->gr[23] = 0 #define USE_ELF_CORE_DUMP #define ELF_EXEC_PAGESIZE 4096 diff -Nru a/include/asm-parisc/ide.h b/include/asm-parisc/ide.h --- a/include/asm-parisc/ide.h Tue Mar 18 15:05:35 2003 +++ b/include/asm-parisc/ide.h Tue Mar 18 15:05:35 2003 @@ -83,6 +83,44 @@ #define ide_check_region(from,extent) check_region((from), (extent)) #define ide_request_region(from,extent,name) request_region((from), (extent), (name)) #define ide_release_region(from,extent) release_region((from), (extent)) +/* Generic I/O and MEMIO string operations. */ + +#define __ide_insw insw +#define __ide_insl insl +#define __ide_outsw outsw +#define __ide_outsl outsl + +static __inline__ void __ide_mm_insw(unsigned long port, void *addr, u32 count) +{ + while (count--) { + *(u16 *)addr = readw(port); + addr += 2; + } +} + +static __inline__ void __ide_mm_insl(unsigned long port, void *addr, u32 count) +{ + while (count--) { + *(u32 *)addr = readl(port); + addr += 4; + } +} + +static __inline__ void __ide_mm_outsw(unsigned long port, void *addr, u32 count) +{ + while (count--) { + writew(*(u16 *)addr, port); + addr += 2; + } +} + +static __inline__ void __ide_mm_outsl(unsigned long port, void *addr, u32 count) +{ + while (count--) { + writel(*(u32 *)addr, port); + addr += 4; + } +} #endif /* __KERNEL__ */ diff -Nru a/include/asm-parisc/kmap_types.h b/include/asm-parisc/kmap_types.h --- a/include/asm-parisc/kmap_types.h Tue Mar 18 15:05:35 2003 +++ b/include/asm-parisc/kmap_types.h Tue Mar 18 15:05:35 2003 @@ -21,7 +21,9 @@ D(8) KM_PTE1, D(9) KM_IRQ0, D(10) KM_IRQ1, -D(11) KM_TYPE_NR +D(11) KM_SOFTIRQ0, +D(12) KM_SOFTIRQ1, +D(13) KM_TYPE_NR }; #undef D diff -Nru a/include/asm-parisc/posix_types.h b/include/asm-parisc/posix_types.h --- a/include/asm-parisc/posix_types.h Tue Mar 18 15:05:35 2003 +++ b/include/asm-parisc/posix_types.h Tue Mar 18 15:05:35 2003 @@ -17,6 +17,8 @@ typedef unsigned int __kernel_gid_t; typedef int __kernel_suseconds_t; typedef int __kernel_clock_t; +typedef int __kernel_timer_t; +typedef int __kernel_clockid_t; typedef int __kernel_daddr_t; /* Note these change from narrow to wide kernels */ #ifdef __LP64__ diff -Nru a/include/asm-parisc/ptrace.h b/include/asm-parisc/ptrace.h --- a/include/asm-parisc/ptrace.h Tue Mar 18 15:05:35 2003 +++ b/include/asm-parisc/ptrace.h Tue Mar 18 15:05:35 2003 @@ -43,9 +43,6 @@ * since we have taken branch traps too) */ #define PTRACE_SINGLEBLOCK 12 /* resume execution until next branch */ -#define PTRACE_GETSIGINFO 13 /* get child's siginfo structure */ -#define PTRACE_SETSIGINFO 14 /* set child's siginfo structure */ - #ifdef __KERNEL__ /* XXX should we use iaoq[1] or iaoq[0] ? */ diff -Nru a/include/asm-parisc/signal.h b/include/asm-parisc/signal.h --- a/include/asm-parisc/signal.h Tue Mar 18 15:05:35 2003 +++ b/include/asm-parisc/signal.h Tue Mar 18 15:05:35 2003 @@ -156,6 +156,8 @@ struct sigaction sa; }; +#define ptrace_signal_deliver(regs, cookie) do { } while (0) + #include #endif /* __KERNEL__ */ diff -Nru a/include/asm-ppc64/elf.h b/include/asm-ppc64/elf.h --- a/include/asm-ppc64/elf.h Tue Mar 18 15:05:35 2003 +++ b/include/asm-ppc64/elf.h Tue Mar 18 15:05:35 2003 @@ -84,9 +84,10 @@ #define ELF_PLATFORM (NULL) -#define ELF_PLAT_INIT(_r) do { \ +#define ELF_PLAT_INIT(_r, load_addr) do { \ memset(_r->gpr, 0, sizeof(_r->gpr)); \ _r->ctr = _r->link = _r->xer = _r->ccr = 0; \ + _r->gpr[2] = load_addr; \ } while (0) #ifdef __KERNEL__ diff -Nru a/include/asm-s390/elf.h b/include/asm-s390/elf.h --- a/include/asm-s390/elf.h Tue Mar 18 15:05:35 2003 +++ b/include/asm-s390/elf.h Tue Mar 18 15:05:35 2003 @@ -36,7 +36,7 @@ /* For SVR4/S390 the function pointer to be registered with `atexit` is passed in R14. */ -#define ELF_PLAT_INIT(_r) \ +#define ELF_PLAT_INIT(_r, load_addr) \ _r->gprs[14] = 0 #define USE_ELF_CORE_DUMP diff -Nru a/include/asm-s390x/elf.h b/include/asm-s390x/elf.h --- a/include/asm-s390x/elf.h Tue Mar 18 15:05:35 2003 +++ b/include/asm-s390x/elf.h Tue Mar 18 15:05:35 2003 @@ -36,7 +36,7 @@ /* For SVR4/S390 the function pointer to be registered with `atexit` is passed in R14. */ -#define ELF_PLAT_INIT(_r) \ +#define ELF_PLAT_INIT(_r, load_addr) \ do { \ _r->gprs[14] = 0; \ clear_thread_flag(TIF_31BIT); \ diff -Nru a/include/asm-sh/elf.h b/include/asm-sh/elf.h --- a/include/asm-sh/elf.h Tue Mar 18 15:05:35 2003 +++ b/include/asm-sh/elf.h Tue Mar 18 15:05:35 2003 @@ -61,7 +61,7 @@ #define ELF_PLATFORM (NULL) -#define ELF_PLAT_INIT(_r) \ +#define ELF_PLAT_INIT(_r, load_addr) \ do { _r->regs[0]=0; _r->regs[1]=0; _r->regs[2]=0; _r->regs[3]=0; \ _r->regs[4]=0; _r->regs[5]=0; _r->regs[6]=0; _r->regs[7]=0; \ _r->regs[8]=0; _r->regs[9]=0; _r->regs[10]=0; _r->regs[11]=0; \ diff -Nru a/include/asm-um/archparam-i386.h b/include/asm-um/archparam-i386.h --- a/include/asm-um/archparam-i386.h Tue Mar 18 15:05:35 2003 +++ b/include/asm-um/archparam-i386.h Tue Mar 18 15:05:35 2003 @@ -23,7 +23,7 @@ #define ELF_DATA ELFDATA2LSB #define ELF_ARCH EM_386 -#define ELF_PLAT_INIT(regs) do { \ +#define ELF_PLAT_INIT(regs, load_addr) do { \ PT_REGS_EBX(regs) = 0; \ PT_REGS_ECX(regs) = 0; \ PT_REGS_EDX(regs) = 0; \ diff -Nru a/include/asm-v850/elf.h b/include/asm-v850/elf.h --- a/include/asm-v850/elf.h Tue Mar 18 15:05:35 2003 +++ b/include/asm-v850/elf.h Tue Mar 18 15:05:35 2003 @@ -81,7 +81,7 @@ #define ELF_PLATFORM (NULL) -#define ELF_PLAT_INIT(_r) \ +#define ELF_PLAT_INIT(_r, load_addr) \ do { \ _r->gpr[0] = _r->gpr[1] = _r->gpr[2] = _r->gpr[3] = \ _r->gpr[4] = _r->gpr[5] = _r->gpr[6] = _r->gpr[7] = \ diff -Nru a/include/asm-x86_64/elf.h b/include/asm-x86_64/elf.h --- a/include/asm-x86_64/elf.h Tue Mar 18 15:05:35 2003 +++ b/include/asm-x86_64/elf.h Tue Mar 18 15:05:35 2003 @@ -39,7 +39,7 @@ We might as well make sure everything else is cleared too (except for %esp), just to make things more deterministic. */ -#define ELF_PLAT_INIT(_r) do { \ +#define ELF_PLAT_INIT(_r, load_addr) do { \ struct task_struct *cur = current; \ (_r)->rbx = 0; (_r)->rcx = 0; (_r)->rdx = 0; \ (_r)->rsi = 0; (_r)->rdi = 0; (_r)->rbp = 0; \ diff -Nru a/include/linux/backing-dev.h b/include/linux/backing-dev.h --- a/include/linux/backing-dev.h Tue Mar 18 15:05:35 2003 +++ b/include/linux/backing-dev.h Tue Mar 18 15:05:35 2003 @@ -17,8 +17,6 @@ BDI_pdflush, /* A pdflush thread is working this device */ BDI_write_congested, /* The write queue is getting full */ BDI_read_congested, /* The read queue is getting full */ - BDI_write_active, /* There are one or more queued writes */ - BDI_read_active, /* There are one or more queued reads */ BDI_unused, /* Available bits start here */ }; @@ -42,16 +40,6 @@ static inline int bdi_write_congested(struct backing_dev_info *bdi) { return test_bit(BDI_write_congested, &bdi->state); -} - -static inline int bdi_read_active(struct backing_dev_info *bdi) -{ - return test_bit(BDI_read_active, &bdi->state); -} - -static inline int bdi_write_active(struct backing_dev_info *bdi) -{ - return test_bit(BDI_write_active, &bdi->state); } #endif /* _LINUX_BACKING_DEV_H */ diff -Nru a/include/linux/file.h b/include/linux/file.h --- a/include/linux/file.h Tue Mar 18 15:05:35 2003 +++ b/include/linux/file.h Tue Mar 18 15:05:35 2003 @@ -40,6 +40,9 @@ extern void put_filp(struct file *); extern int get_unused_fd(void); extern void FASTCALL(put_unused_fd(unsigned int fd)); +struct kmem_cache_s; +extern void filp_ctor(void * objp, struct kmem_cache_s *cachep, unsigned long cflags); +extern void filp_dtor(void * objp, struct kmem_cache_s *cachep, unsigned long dflags); extern struct file ** alloc_fd_array(int); extern int expand_fd_array(struct files_struct *, int nr); diff -Nru a/include/linux/thread_info.h b/include/linux/thread_info.h --- a/include/linux/thread_info.h Tue Mar 18 15:05:35 2003 +++ b/include/linux/thread_info.h Tue Mar 18 15:05:35 2003 @@ -12,7 +12,7 @@ */ struct restart_block { long (*fn)(struct restart_block *); - unsigned long arg0, arg1, arg2; + unsigned long arg0, arg1, arg2, arg3; }; extern long do_no_restart_syscall(struct restart_block *parm); diff -Nru a/kernel/posix-timers.c b/kernel/posix-timers.c --- a/kernel/posix-timers.c Tue Mar 18 15:05:35 2003 +++ b/kernel/posix-timers.c Tue Mar 18 15:05:35 2003 @@ -9,7 +9,6 @@ /* These are all the functions necessary to implement * POSIX clocks & timers */ - #include #include #include @@ -23,6 +22,7 @@ #include #include #include +#include #ifndef div_long_long_rem #include @@ -56,8 +56,8 @@ * Lets keep our timers in a slab cache :-) */ static kmem_cache_t *posix_timers_cache; -struct idr posix_timers_id; -spinlock_t idr_lock = SPIN_LOCK_UNLOCKED; +static struct idr posix_timers_id; +static spinlock_t idr_lock = SPIN_LOCK_UNLOCKED; /* * Just because the timer is not in the timer list does NOT mean it is @@ -130,7 +130,7 @@ * which we beg off on and pass to do_sys_settimeofday(). */ -struct k_clock posix_clocks[MAX_CLOCKS]; +static struct k_clock posix_clocks[MAX_CLOCKS]; #define if_clock_do(clock_fun, alt_fun,parms) (! clock_fun)? alt_fun parms :\ clock_fun parms @@ -183,7 +183,7 @@ __initcall(init_posix_timers); static inline int -tstojiffie(struct timespec *tp, int res, unsigned long *jiff) +tstojiffie(struct timespec *tp, int res, u64 *jiff) { unsigned long sec = tp->tv_sec; long nsec = tp->tv_nsec + res - 1; @@ -203,7 +203,7 @@ * below. Here it is enough to just discard the high order * bits. */ - *jiff = HZ * sec; + *jiff = (u64)sec * HZ; /* * Do the res thing. (Don't forget the add in the declaration of nsec) */ @@ -221,9 +221,12 @@ static void tstotimer(struct itimerspec *time, struct k_itimer *timer) { + u64 result; int res = posix_clocks[timer->it_clock].res; - tstojiffie(&time->it_value, res, &timer->it_timer.expires); - tstojiffie(&time->it_interval, res, &timer->it_incr); + tstojiffie(&time->it_value, res, &result); + timer->it_timer.expires = (unsigned long)result; + tstojiffie(&time->it_interval, res, &result); + timer->it_incr = (unsigned long)result; } static void @@ -1020,6 +1023,9 @@ * Note also that the while loop assures that the sub_jiff_offset * will be less than a jiffie, thus no need to normalize the result. * Well, not really, if called with ints off :( + + * HELP, this code should make an attempt at resolution beyond the + * jiffie. Trouble is this is "arch" dependent... */ int @@ -1127,26 +1133,14 @@ * holds (or has held for it) a write_lock_irq( xtime_lock) and is * called from the timer bh code. Thus we need the irq save locks. */ -spinlock_t nanosleep_abs_list_lock = SPIN_LOCK_UNLOCKED; -struct list_head nanosleep_abs_list = LIST_HEAD_INIT(nanosleep_abs_list); +static DECLARE_WAIT_QUEUE_HEAD(nanosleep_abs_wqueue); -struct abs_struct { - struct list_head list; - struct task_struct *t; -}; void clock_was_set(void) { - struct list_head *pos; - unsigned long flags; - - spin_lock_irqsave(&nanosleep_abs_list_lock, flags); - list_for_each(pos, &nanosleep_abs_list) { - wake_up_process(list_entry(pos, struct abs_struct, list)->t); - } - spin_unlock_irqrestore(&nanosleep_abs_list_lock, flags); + wake_up_all(&nanosleep_abs_wqueue); } long clock_nanosleep_restart(struct restart_block *restart_block); @@ -1201,19 +1195,19 @@ return ret; } - long do_clock_nanosleep(clockid_t which_clock, int flags, struct timespec *tsave) { struct timespec t; struct timer_list new_timer; - struct abs_struct abs_struct = { .list = { .next = 0 } }; + DECLARE_WAITQUEUE(abs_wqueue, current); + u64 rq_time = 0; + s64 left; int abs; - int rtn = 0; - int active; struct restart_block *restart_block = ¤t_thread_info()->restart_block; + abs_wqueue.flags = 0; init_timer(&new_timer); new_timer.expires = 0; new_timer.data = (unsigned long) current; @@ -1226,54 +1220,50 @@ * time and continue. */ restart_block->fn = do_no_restart_syscall; - if (!restart_block->arg2) - return -EINTR; - new_timer.expires = restart_block->arg2; - if (time_before(new_timer.expires, jiffies)) + rq_time = restart_block->arg3; + rq_time = (rq_time << 32) + restart_block->arg2; + if (!rq_time) + return -EINTR; + if (rq_time <= get_jiffies_64()) return 0; } if (abs && (posix_clocks[which_clock].clock_get != posix_clocks[CLOCK_MONOTONIC].clock_get)) { - spin_lock_irq(&nanosleep_abs_list_lock); - list_add(&abs_struct.list, &nanosleep_abs_list); - abs_struct.t = current; - spin_unlock_irq(&nanosleep_abs_list_lock); + add_wait_queue(&nanosleep_abs_wqueue, &abs_wqueue); } do { t = *tsave; - if ((abs || !new_timer.expires) && - !(rtn = adjust_abs_time(&posix_clocks[which_clock], - &t, abs))) { - /* - * On error, we don't set up the timer so - * we don't arm the timer so - * del_timer_sync() will return 0, thus - * active is zero... and so it goes. - */ + if (abs || !rq_time){ + adjust_abs_time(&posix_clocks[which_clock], &t, abs); - tstojiffie(&t, - posix_clocks[which_clock].res, - &new_timer.expires); + tstojiffie(&t, posix_clocks[which_clock].res, &rq_time); } - if (new_timer.expires) { - current->state = TASK_INTERRUPTIBLE; - add_timer(&new_timer); - - schedule(); +#if (BITS_PER_LONG < 64) + if ((rq_time - get_jiffies_64()) > MAX_JIFFY_OFFSET){ + new_timer.expires = MAX_JIFFY_OFFSET; + }else +#endif + { + new_timer.expires = (long)rq_time; } - } - while ((active = del_timer_sync(&new_timer)) && - !test_thread_flag(TIF_SIGPENDING)); + current->state = TASK_INTERRUPTIBLE; + add_timer(&new_timer); + + schedule(); - if (abs_struct.list.next) { - spin_lock_irq(&nanosleep_abs_list_lock); - list_del(&abs_struct.list); - spin_unlock_irq(&nanosleep_abs_list_lock); + del_timer_sync(&new_timer); + left = rq_time - get_jiffies_64(); } - if (active) { - long jiffies_left; + while ( (left > 0) && + !test_thread_flag(TIF_SIGPENDING)); + + if( abs_wqueue.task_list.next) + finish_wait(&nanosleep_abs_wqueue, &abs_wqueue); + + if (left > 0) { + unsigned long rmd; /* * Always restart abs calls from scratch to pick up any @@ -1282,29 +1272,19 @@ if (abs) return -ERESTARTNOHAND; - jiffies_left = new_timer.expires - jiffies; - - if (jiffies_left < 0) - return 0; - - jiffies_to_timespec(jiffies_left, tsave); + tsave->tv_sec = div_long_long_rem(left, HZ, &rmd); + tsave->tv_nsec = rmd * (NSEC_PER_SEC / HZ); - while (tsave->tv_nsec < 0) { - tsave->tv_nsec += NSEC_PER_SEC; - tsave->tv_sec--; - } - if (tsave->tv_sec < 0) { - tsave->tv_sec = 0; - tsave->tv_nsec = 1; - } restart_block->fn = clock_nanosleep_restart; restart_block->arg0 = which_clock; restart_block->arg1 = (unsigned long)tsave; - restart_block->arg2 = new_timer.expires; + restart_block->arg2 = rq_time & 0xffffffffLL; + restart_block->arg3 = rq_time >> 32; + return -ERESTART_RESTARTBLOCK; } - return rtn; + return 0; } /* * This will restart either clock_nanosleep or clock_nanosleep diff -Nru a/kernel/timer.c b/kernel/timer.c --- a/kernel/timer.c Tue Mar 18 15:05:35 2003 +++ b/kernel/timer.c Tue Mar 18 15:05:35 2003 @@ -53,11 +53,11 @@ struct list_head vec[TVR_SIZE]; } tvec_root_t; - struct tvec_t_base_s { spinlock_t lock; unsigned long timer_jiffies; struct timer_list *running_timer; + struct list_head *run_timer_list_running; tvec_root_t tv1; tvec_t tv2; tvec_t tv3; @@ -67,6 +67,14 @@ typedef struct tvec_t_base_s tvec_base_t; +static inline void set_running_timer(tvec_base_t *base, + struct timer_list *timer) +{ +#ifdef CONFIG_SMP + base->running_timer = timer; +#endif +} + /* Fake initialization */ static DEFINE_PER_CPU(tvec_base_t, tvec_bases) = { SPIN_LOCK_UNLOCKED }; @@ -94,13 +102,22 @@ check_timer_failed(timer); } -static inline void internal_add_timer(tvec_base_t *base, struct timer_list *timer) +/* + * If a timer handler re-adds the timer with expires == jiffies, the timer + * running code can lock up. So here we detect that situation and park the + * timer onto base->run_timer_list_running. It will be added to the main timer + * structures later, by __run_timers(). + */ + +static void internal_add_timer(tvec_base_t *base, struct timer_list *timer) { unsigned long expires = timer->expires; unsigned long idx = expires - base->timer_jiffies; struct list_head *vec; - if (idx < TVR_SIZE) { + if (base->run_timer_list_running) { + vec = base->run_timer_list_running; + } else if (idx < TVR_SIZE) { int i = expires & TVR_MASK; vec = base->tv1.vec + i; } else if (idx < 1 << (TVR_BITS + TVN_BITS)) { @@ -354,7 +371,7 @@ static int cascade(tvec_base_t *base, tvec_t *tv) { /* cascade all the timers from tv up one level */ - struct list_head *head, *curr, *next; + struct list_head *head, *curr; head = tv->vec + tv->index; curr = head->next; @@ -366,11 +383,9 @@ struct timer_list *tmp; tmp = list_entry(curr, struct timer_list, entry); - if (tmp->base != base) - BUG(); - next = curr->next; + BUG_ON(tmp->base != base); + curr = curr->next; internal_add_timer(base, tmp); - curr = next; } INIT_LIST_HEAD(head); @@ -386,9 +401,12 @@ */ static inline void __run_timers(tvec_base_t *base) { + struct timer_list *timer; + spin_lock_irq(&base->lock); - while ((long)(jiffies - base->timer_jiffies) >= 0) { - struct list_head *head, *curr; + while (time_after_eq(jiffies, base->timer_jiffies)) { + LIST_HEAD(deferred_timers); + struct list_head *head; /* * Cascade timers: @@ -398,37 +416,36 @@ (cascade(base, &base->tv3) == 1) && cascade(base, &base->tv4) == 1) cascade(base, &base->tv5); + base->run_timer_list_running = &deferred_timers; repeat: head = base->tv1.vec + base->tv1.index; - curr = head->next; - if (curr != head) { + if (!list_empty(head)) { void (*fn)(unsigned long); unsigned long data; - struct timer_list *timer; - timer = list_entry(curr, struct timer_list, entry); + timer = list_entry(head->next,struct timer_list,entry); fn = timer->function; data = timer->data; list_del(&timer->entry); timer->base = NULL; -#if CONFIG_SMP - base->running_timer = timer; -#endif + set_running_timer(base, timer); spin_unlock_irq(&base->lock); - if (!fn) - printk("Bad: timer %p has NULL fn. (data: %08lx)\n", timer, data); - else - fn(data); + fn(data); spin_lock_irq(&base->lock); goto repeat; } + base->run_timer_list_running = NULL; ++base->timer_jiffies; base->tv1.index = (base->tv1.index + 1) & TVR_MASK; + while (!list_empty(&deferred_timers)) { + timer = list_entry(deferred_timers.prev, + struct timer_list, entry); + list_del(&timer->entry); + internal_add_timer(base, timer); + } } -#if CONFIG_SMP - base->running_timer = NULL; -#endif + set_running_timer(base, NULL); spin_unlock_irq(&base->lock); } @@ -775,7 +792,7 @@ { tvec_base_t *base = &per_cpu(tvec_bases, smp_processor_id()); - if ((long)(jiffies - base->timer_jiffies) >= 0) + if (time_after_eq(jiffies, base->timer_jiffies)) __run_timers(base); } diff -Nru a/mm/highmem.c b/mm/highmem.c --- a/mm/highmem.c Tue Mar 18 15:05:35 2003 +++ b/mm/highmem.c Tue Mar 18 15:05:35 2003 @@ -120,7 +120,7 @@ { DECLARE_WAITQUEUE(wait, current); - current->state = TASK_UNINTERRUPTIBLE; + __set_current_state(TASK_UNINTERRUPTIBLE); add_wait_queue(&pkmap_map_wait, &wait); spin_unlock(&kmap_lock); schedule(); diff -Nru a/mm/memory.c b/mm/memory.c --- a/mm/memory.c Tue Mar 18 15:05:35 2003 +++ b/mm/memory.c Tue Mar 18 15:05:35 2003 @@ -1453,7 +1453,7 @@ pgd_t *pgd; pmd_t *pmd; - current->state = TASK_RUNNING; + __set_current_state(TASK_RUNNING); pgd = pgd_offset(mm, address); inc_page_state(pgfault); diff -Nru a/mm/nommu.c b/mm/nommu.c --- a/mm/nommu.c Tue Mar 18 15:05:35 2003 +++ b/mm/nommu.c Tue Mar 18 15:05:35 2003 @@ -130,6 +130,11 @@ return kmalloc(size, gfp_mask & ~__GFP_HIGHMEM); } +struct page * vmalloc_to_page(void *addr) +{ + return virt_to_page(addr); +} + long vread(char *buf, char *addr, unsigned long count) { memcpy(buf, addr, count); @@ -544,6 +549,17 @@ struct vm_area_struct * find_vma(struct mm_struct * mm, unsigned long addr) { return NULL; +} + +struct page * follow_page(struct mm_struct *mm, unsigned long addr, int write) +{ + return NULL; +} + +int remap_page_range(struct vm_area_struct *vma, unsigned long from, + unsigned long to, unsigned long size, pgprot_t prot) +{ + return -EPERM; } unsigned long get_unmapped_area(struct file *file, unsigned long addr, diff -Nru a/mm/slab.c b/mm/slab.c --- a/mm/slab.c Tue Mar 18 15:05:35 2003 +++ b/mm/slab.c Tue Mar 18 15:05:35 2003 @@ -344,8 +344,20 @@ #endif -/* maximum size of an obj (in 2^order pages) */ +/* + * Maximum size of an obj (in 2^order pages) + * and absolute limit for the gfp order. + */ +#if defined(CONFIG_LARGE_ALLOCS) +#define MAX_OBJ_ORDER 13 /* up to 32Mb */ +#define MAX_GFP_ORDER 13 /* up to 32Mb */ +#elif defined(CONFIG_MMU) #define MAX_OBJ_ORDER 5 /* 32 pages */ +#define MAX_GFP_ORDER 5 /* 32 pages */ +#else +#define MAX_OBJ_ORDER 8 /* up to 1Mb */ +#define MAX_GFP_ORDER 8 /* up to 1Mb */ +#endif /* * Do not go above this order unless 0 objects fit into the slab. @@ -354,12 +366,6 @@ #define BREAK_GFP_ORDER_LO 1 static int slab_break_gfp_order = BREAK_GFP_ORDER_LO; -/* - * Absolute limit for the gfp order - */ -#define MAX_GFP_ORDER 5 /* 32 pages */ - - /* Macros for storing/retrieving the cachep and or slab from the * global 'mem_map'. These are used to find the slab an obj belongs to. * With kfree(), these are used to find the cache which an obj belongs to. @@ -399,6 +405,18 @@ { 32768, NULL, NULL}, { 65536, NULL, NULL}, {131072, NULL, NULL}, +#ifndef CONFIG_MMU + {262144, NULL, NULL}, + {524288, NULL, NULL}, + {1048576, NULL, NULL}, +#ifdef CONFIG_LARGE_ALLOCS + {2097152, NULL, NULL}, + {4194304, NULL, NULL}, + {8388608, NULL, NULL}, + {16777216, NULL, NULL}, + {33554432, NULL, NULL}, +#endif /* CONFIG_LARGE_ALLOCS */ +#endif /* CONFIG_MMU */ { 0, NULL, NULL} }; /* Must match cache_sizes above. Out of line to keep cache footprint low. */ @@ -427,7 +445,19 @@ CN("size-16384"), CN("size-32768"), CN("size-65536"), - CN("size-131072") + CN("size-131072"), +#ifndef CONFIG_MMU + CN("size-262144"), + CN("size-524288"), + CN("size-1048576"), +#ifdef CONFIG_LARGE_ALLOCS + CN("size-2097152"), + CN("size-4194304"), + CN("size-8388608"), + CN("size-16777216"), + CN("size-33554432"), +#endif /* CONFIG_LARGE_ALLOCS */ +#endif /* CONFIG_MMU */ }; #undef CN