diff options
113 files changed, 1391 insertions, 788 deletions
diff --git a/Documentation/fb/pvr2fb.txt b/Documentation/fb/pvr2fb.txt index 2bf6c2321c2d..36bdeff585e2 100644 --- a/Documentation/fb/pvr2fb.txt +++ b/Documentation/fb/pvr2fb.txt @@ -9,14 +9,13 @@ one found in the Dreamcast. Advantages: * It provides a nice large console (128 cols + 48 lines with 1024x768) - without using tiny, unreadable fonts. + without using tiny, unreadable fonts (NOT on the Dreamcast) * You can run XF86_FBDev on top of /dev/fb0 * Most important: boot logo :-) Disadvantages: - * Driver is currently limited to the Dreamcast PowerVR 2 implementation - at the time of this writing. + * Driver is largely untested on non-Dreamcast systems. Configuration ============= @@ -29,11 +28,16 @@ Accepted options: font:X - default font to use. All fonts are supported, including the SUN12x22 font which is very nice at high resolutions. -mode:X - default video mode. The following video modes are supported: - 640x240-60, 640x480-60. +mode:X - default video mode with format [xres]x[yres]-<bpp>@<refresh rate> + The following video modes are supported: + 640x640-16@60, 640x480-24@60, 640x480-32@60. The Dreamcast + defaults to 640x480-16@60. At the time of writing the + 24bpp and 32bpp modes function poorly. Work to fix that is + ongoing + Note: the 640x240 mode is currently broken, and should not be - used for any reason. It is only mentioned as a reference. + used for any reason. It is only mentioned here as a reference. inverse - invert colors on screen (for LCD displays) @@ -52,10 +56,10 @@ output:X - output type. This can be any of the following: pal, ntsc, and X11 === -XF86_FBDev should work, in theory. At the time of this writing it is -totally untested and may or may not even portray the beginnings of -working. If you end up testing this, please let me know! +XF86_FBDev has been shown to work on the Dreamcast in the past - though not yet +on any 2.6 series kernel. -- Paul Mundt <lethal@linuxdc.org> +Updated by Adrian McMenamin <adrian@mcmen.demon.co.uk> diff --git a/Documentation/i386/zero-page.txt b/Documentation/i386/zero-page.txt index 75b3680c41eb..6c0817c45683 100644 --- a/Documentation/i386/zero-page.txt +++ b/Documentation/i386/zero-page.txt @@ -1,3 +1,13 @@ +--------------------------------------------------------------------------- +!!!!!!!!!!!!!!!WARNING!!!!!!!! +The zero page is a kernel internal data structure, not a stable ABI. It might change +without warning and the kernel has no way to detect old version of it. +If you're writing some external code like a boot loader you should only use +the stable versioned real mode boot protocol described in boot.txt. Otherwise the kernel +might break you at any time. +!!!!!!!!!!!!!WARNING!!!!!!!!!!! +---------------------------------------------------------------------------- + Summary of boot_params layout (kernel point of view) ( collected by Hans Lermen and Martin Mares ) diff --git a/Documentation/kbuild/kconfig-language.txt b/Documentation/kbuild/kconfig-language.txt index 536d5bfbdb8d..fe8b0c4892cf 100644 --- a/Documentation/kbuild/kconfig-language.txt +++ b/Documentation/kbuild/kconfig-language.txt @@ -98,6 +98,15 @@ applicable everywhere (see syntax). times, the limit is set to the largest selection. Reverse dependencies can only be used with boolean or tristate symbols. + Note: + select is evil.... select will by brute force set a symbol + equal to 'y' without visiting the dependencies. So abusing + select you are able to select a symbol FOO even if FOO depends + on BAR that is not set. In general use select only for + non-visible symbols (no promts anywhere) and for symbols with + no dependencies. That will limit the usefulness but on the + other hand avoid the illegal configurations all over. kconfig + should one day warn about such things. - numerical ranges: "range" <symbol> <symbol> ["if" <expr>] This allows to limit the range of possible input values for int diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index efdb42fd3fb8..a326487a3ab5 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -1922,7 +1922,7 @@ and is between 256 and 4096 characters. It is defined in the file See header of drivers/scsi/wd7000.c. wdt= [WDT] Watchdog - See Documentation/watchdog/watchdog.txt. + See Documentation/watchdog/wdt.txt. xd= [HW,XT] Original XT pre-IDE (RLL encoded) disks. xd_geo= See header of drivers/block/xd.c. diff --git a/Documentation/memory-hotplug.txt b/Documentation/memory-hotplug.txt new file mode 100644 index 000000000000..5fbcc22c98e9 --- /dev/null +++ b/Documentation/memory-hotplug.txt @@ -0,0 +1,322 @@ +============== +Memory Hotplug +============== + +Last Updated: Jul 28 2007 + +This document is about memory hotplug including how-to-use and current status. +Because Memory Hotplug is still under development, contents of this text will +be changed often. + +1. Introduction + 1.1 purpose of memory hotplug + 1.2. Phases of memory hotplug + 1.3. Unit of Memory online/offline operation +2. Kernel Configuration +3. sysfs files for memory hotplug +4. Physical memory hot-add phase + 4.1 Hardware(Firmware) Support + 4.2 Notify memory hot-add event by hand +5. Logical Memory hot-add phase + 5.1. State of memory + 5.2. How to online memory +6. Logical memory remove + 6.1 Memory offline and ZONE_MOVABLE + 6.2. How to offline memory +7. Physical memory remove +8. Future Work List + +Note(1): x86_64's has special implementation for memory hotplug. + This text does not describe it. +Note(2): This text assumes that sysfs is mounted at /sys. + + +--------------- +1. Introduction +--------------- + +1.1 purpose of memory hotplug +------------ +Memory Hotplug allows users to increase/decrease the amount of memory. +Generally, there are two purposes. + +(A) For changing the amount of memory. + This is to allow a feature like capacity on demand. +(B) For installing/removing DIMMs or NUMA-nodes physically. + This is to exchange DIMMs/NUMA-nodes, reduce power consumption, etc. + +(A) is required by highly virtualized environments and (B) is required by +hardware which supports memory power management. + +Linux memory hotplug is designed for both purpose. + + +1.2. Phases of memory hotplug +--------------- +There are 2 phases in Memory Hotplug. + 1) Physical Memory Hotplug phase + 2) Logical Memory Hotplug phase. + +The First phase is to communicate hardware/firmware and make/erase +environment for hotplugged memory. Basically, this phase is necessary +for the purpose (B), but this is good phase for communication between +highly virtualized environments too. + +When memory is hotplugged, the kernel recognizes new memory, makes new memory +management tables, and makes sysfs files for new memory's operation. + +If firmware supports notification of connection of new memory to OS, +this phase is triggered automatically. ACPI can notify this event. If not, +"probe" operation by system administration is used instead. +(see Section 4.). + +Logical Memory Hotplug phase is to change memory state into +avaiable/unavailable for users. Amount of memory from user's view is +changed by this phase. The kernel makes all memory in it as free pages +when a memory range is available. + +In this document, this phase is described as online/offline. + +Logical Memory Hotplug phase is triggred by write of sysfs file by system +administrator. For the hot-add case, it must be executed after Physical Hotplug +phase by hand. +(However, if you writes udev's hotplug scripts for memory hotplug, these + phases can be execute in seamless way.) + + +1.3. Unit of Memory online/offline operation +------------ +Memory hotplug uses SPARSEMEM memory model. SPARSEMEM divides the whole memory +into chunks of the same size. The chunk is called a "section". The size of +a section is architecture dependent. For example, power uses 16MiB, ia64 uses +1GiB. The unit of online/offline operation is "one section". (see Section 3.) + +To determine the size of sections, please read this file: + +/sys/devices/system/memory/block_size_bytes + +This file shows the size of sections in byte. + +----------------------- +2. Kernel Configuration +----------------------- +To use memory hotplug feature, kernel must be compiled with following +config options. + +- For all memory hotplug + Memory model -> Sparse Memory (CONFIG_SPARSEMEM) + Allow for memory hot-add (CONFIG_MEMORY_HOTPLUG) + +- To enable memory removal, the followings are also necessary + Allow for memory hot remove (CONFIG_MEMORY_HOTREMOVE) + Page Migration (CONFIG_MIGRATION) + +- For ACPI memory hotplug, the followings are also necessary + Memory hotplug (under ACPI Support menu) (CONFIG_ACPI_HOTPLUG_MEMORY) + This option can be kernel module. + +- As a related configuration, if your box has a feature of NUMA-node hotplug + via ACPI, then this option is necessary too. + ACPI0004,PNP0A05 and PNP0A06 Container Driver (under ACPI Support menu) + (CONFIG_ACPI_CONTAINER). + This option can be kernel module too. + +-------------------------------- +3 sysfs files for memory hotplug +-------------------------------- +All sections have their device information under /sys/devices/system/memory as + +/sys/devices/system/memory/memoryXXX +(XXX is section id.) + +Now, XXX is defined as start_address_of_section / section_size. + +For example, assume 1GiB section size. A device for a memory starting at +0x100000000 is /sys/device/system/memory/memory4 +(0x100000000 / 1Gib = 4) +This device covers address range [0x100000000 ... 0x140000000) + +Under each section, you can see 3 files. + +/sys/devices/system/memory/memoryXXX/phys_index +/sys/devices/system/memory/memoryXXX/phys_device +/sys/devices/system/memory/memoryXXX/state + +'phys_index' : read-only and contains section id, same as XXX. +'state' : read-write + at read: contains online/offline state of memory. + at write: user can specify "online", "offline" command +'phys_device': read-only: designed to show the name of physical memory device. + This is not well implemented now. + +NOTE: + These directories/files appear after physical memory hotplug phase. + + +-------------------------------- +4. Physical memory hot-add phase +-------------------------------- + +4.1 Hardware(Firmware) Support +------------ +On x86_64/ia64 platform, memory hotplug by ACPI is supported. + +In general, the firmware (ACPI) which supports memory hotplug defines +memory class object of _HID "PNP0C80". When a notify is asserted to PNP0C80, +Linux's ACPI handler does hot-add memory to the system and calls a hotplug udev +script. This will be done automatically. + +But scripts for memory hotplug are not contained in generic udev package(now). +You may have to write it by yourself or online/offline memory by hand. +Please see "How to online memory", "How to offline memory" in this text. + +If firmware supports NUMA-node hotplug, and defines an object _HID "ACPI0004", +"PNP0A05", or "PNP0A06", notification is asserted to it, and ACPI handler +calls hotplug code for all of objects which are defined in it. +If memory device is found, memory hotplug code will be called. + + +4.2 Notify memory hot-add event by hand +------------ +In some environments, especially virtualized environment, firmware will not +notify memory hotplug event to the kernel. For such environment, "probe" +interface is supported. This interface depends on CONFIG_ARCH_MEMORY_PROBE. + +Now, CONFIG_ARCH_MEMORY_PROBE is supported only by powerpc but it does not +contain highly architecture codes. Please add config if you need "probe" +interface. + +Probe interface is located at +/sys/devices/system/memory/probe + +You can tell the physical address of new memory to the kernel by + +% echo start_address_of_new_memory > /sys/devices/system/memory/probe + +Then, [start_address_of_new_memory, start_address_of_new_memory + section_size) +memory range is hot-added. In this case, hotplug script is not called (in +current implementation). You'll have to online memory by yourself. +Please see "How to online memory" in this text. + + + +------------------------------ +5. Logical Memory hot-add phase +------------------------------ + +5.1. State of memory +------------ +To see (online/offline) state of memory section, read 'state' file. + +% cat /sys/device/system/memory/memoryXXX/state + + +If the memory section is online, you'll read "online". +If the memory section is offline, you'll read "offline". + + +5.2. How to online memory +------------ +Even if the memory is hot-added, it is not at ready-to-use state. +For using newly added memory, you have to "online" the memory section. + +For onlining, you have to write "online" to the section's state file as: + +% echo online > /sys/devices/system/memory/memoryXXX/state + +After this, section memoryXXX's state will be 'online' and the amount of +available memory will be increased. + +Currently, newly added memory is added as ZONE_NORMAL (for powerpc, ZONE_DMA). +This may be changed in future. + + + +------------------------ +6. Logical memory remove +------------------------ + +6.1 Memory offline and ZONE_MOVABLE +------------ +Memory offlining is more complicated than memory online. Because memory offline +has to make the whole memory section be unused, memory offline can fail if +the section includes memory which cannot be freed. + +In general, memory offline can use 2 techniques. + +(1) reclaim and free all memory in the section. +(2) migrate all pages in the section. + +In the current implementation, Linux's memory offline uses method (2), freeing +all pages in the section by page migration. But not all pages are +migratable. Under current Linux, migratable pages are anonymous pages and +page caches. For offlining a section by migration, the kernel has to guarantee +that the section contains only migratable pages. + +Now, a boot option for making a section which consists of migratable pages is +supported. By specifying "kernelcore=" or "movablecore=" boot option, you can +create ZONE_MOVABLE...a zone which is just used for movable pages. +(See also Documentation/kernel-parameters.txt) + +Assume the system has "TOTAL" amount of memory at boot time, this boot option +creates ZONE_MOVABLE as following. + +1) When kernelcore=YYYY boot option is used, + Size of memory not for movable pages (not for offline) is YYYY. + Size of memory for movable pages (for offline) is TOTAL-YYYY. + +2) When movablecore=ZZZZ boot option is used, + Size of memory not for movable pages (not for offline) is TOTAL - ZZZZ. + Size of memory for movable pages (for offline) is ZZZZ. + + +Note) Unfortunately, there is no information to show which section belongs +to ZONE_MOVABLE. This is TBD. + + +6.2. How to offline memory +------------ +You can offline a section by using the same sysfs interface that was used in +memory onlining. + +% echo offline > /sys/devices/system/memory/memoryXXX/state + +If offline succeeds, the state of the memory section is changed to be "offline". +If it fails, some error core (like -EBUSY) will be returned by the kernel. +Even if a section does not belong to ZONE_MOVABLE, you can try to offline it. +If it doesn't contain 'unmovable' memory, you'll get success. + +A section under ZONE_MOVABLE is considered to be able to be offlined easily. +But under some busy state, it may return -EBUSY. Even if a memory section +cannot be offlined due to -EBUSY, you can retry offlining it and may be able to +offline it (or not). +(For example, a page is referred to by some kernel internal call and released + soon.) + +Consideration: +Memory hotplug's design direction is to make the possibility of memory offlining +higher and to guarantee unplugging memory under any situation. But it needs +more work. Returning -EBUSY under some situation may be good because the user +can decide to retry more or not by himself. Currently, memory offlining code +does some amount of retry with 120 seconds timeout. + +------------------------- +7. Physical memory remove +------------------------- +Need more implementation yet.... + - Notification completion of remove works by OS to firmware. + - Guard from remove if not yet. + +-------------- +8. Future Work +-------------- + - allowing memory hot-add to ZONE_MOVABLE. maybe we need some switch like + sysctl or new control file. + - showing memory section and physical device relationship. + - showing memory section and node relationship (maybe good for NUMA) + - showing memory section is under ZONE_MOVABLE or not + - test and make it better memory offlining. + - support HugeTLB page migration and offlining. + - memmap removing at memory offline. + - physical remove memory. + diff --git a/Documentation/sysrq.txt b/Documentation/sysrq.txt index ba328f255417..ef19142896ca 100644 --- a/Documentation/sysrq.txt +++ b/Documentation/sysrq.txt @@ -1,6 +1,6 @@ Linux Magic System Request Key Hacks Documentation for sysrq.c -Last update: 2007-MAR-14 +Last update: 2007-AUG-04 * What is the magic SysRq key? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -78,7 +78,7 @@ On all - write a character to /proc/sysrq-trigger. e.g.: 'g' - Used by kgdb on ppc and sh platforms. 'h' - Will display help (actually any other key than those listed - above will display help. but 'h' is easy to remember :-) + here will display help. but 'h' is easy to remember :-) 'i' - Send a SIGKILL to all processes, except for init. diff --git a/MAINTAINERS b/MAINTAINERS index e65e96a14bec..d3a0684945b4 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -612,6 +612,15 @@ W: http://sourceforge.net/projects/acpi4asus W: http://xf.iksaif.net/acpi4asus S: Maintained +ASYNCHRONOUS TRANSFERS/TRANSFORMS API +P: Dan Williams +M: dan.j.williams@intel.com +P: Shannon Nelson +M: shannon.nelson@intel.com +L: linux-kernel@vger.kernel.org +W: http://sourceforge.net/projects/xscaleiop +S: Supported + ATA OVER ETHERNET DRIVER P: Ed L. Cashin M: ecashin@coraid.com @@ -664,7 +673,7 @@ S: Maintained AUDIT SUBSYSTEM P: David Woodhouse M: dwmw2@infradead.org -L: linux-audit@redhat.com +L: linux-audit@redhat.com (subscribers-only) W: http://people.redhat.com/sgrubb/audit/ T: git kernel.org:/pub/scm/linux/kernel/git/dwmw2/audit-2.6.git S: Maintained @@ -1277,11 +1286,13 @@ M: tori@unhappy.mine.nu L: netdev@vger.kernel.org S: Maintained -DMA GENERIC MEMCPY SUBSYSTEM +DMA GENERIC OFFLOAD ENGINE SUBSYSTEM P: Shannon Nelson M: shannon.nelson@intel.com +P: Dan Williams +M: dan.j.williams@intel.com L: linux-kernel@vger.kernel.org -S: Maintained +S: Supported DME1737 HARDWARE MONITOR DRIVER P: Juerg Haefliger @@ -1958,6 +1969,12 @@ M: shannon.nelson@intel.com L: linux-kernel@vger.kernel.org S: Supported +INTEL IOP-ADMA DMA DRIVER +P: Dan Williams +M: dan.j.williams@intel.com +L: linux-kernel@vger.kernel.org +S: Supported + INTEL IXP4XX RANDOM NUMBER GENERATOR SUPPORT P: Deepak Saxena M: dsaxena@plexity.net diff --git a/arch/alpha/kernel/sys_titan.c b/arch/alpha/kernel/sys_titan.c index 1d3c1398c428..52c91ccc1648 100644 --- a/arch/alpha/kernel/sys_titan.c +++ b/arch/alpha/kernel/sys_titan.c @@ -271,6 +271,19 @@ titan_dispatch_irqs(u64 mask) * Titan Family */ static void __init +titan_request_irq(unsigned int irq, irq_handler_t handler, + unsigned long irqflags, const char *devname, + void *dev_id) +{ + int err; + err = request_irq(irq, handler, irqflags, devname, dev_id); + if (err) { + printk("titan_request_irq for IRQ %d returned %d; ignoring\n", + irq, err); + } +} + +static void __init titan_late_init(void) { /* @@ -278,15 +291,15 @@ titan_late_init(void) * all reported to the kernel as machine checks, so the handler * is a nop so it can be called to count the individual events. */ - request_irq(63+16, titan_intr_nop, IRQF_DISABLED, + titan_request_irq(63+16, titan_intr_nop, IRQF_DISABLED, "CChip Error", NULL); - request_irq(62+16, titan_intr_nop, IRQF_DISABLED, + titan_request_irq(62+16, titan_intr_nop, IRQF_DISABLED, "PChip 0 H_Error", NULL); - request_irq(61+16, titan_intr_nop, IRQF_DISABLED, + titan_request_irq(61+16, titan_intr_nop, IRQF_DISABLED, "PChip 1 H_Error", NULL); - request_irq(60+16, titan_intr_nop, IRQF_DISABLED, + titan_request_irq(60+16, titan_intr_nop, IRQF_DISABLED, "PChip 0 C_Error", NULL); - request_irq(59+16, titan_intr_nop, IRQF_DISABLED, + titan_request_irq(59+16, titan_intr_nop, IRQF_DISABLED, "PChip 1 C_Error", NULL); /* @@ -345,9 +358,9 @@ privateer_init_pci(void) * Hook a couple of extra err interrupts that the * common titan code won't. */ - request_irq(53+16, titan_intr_nop, IRQF_DISABLED, + titan_request_irq(53+16, titan_intr_nop, IRQF_DISABLED, "NMI", NULL); - request_irq(50+16, titan_intr_nop, IRQF_DISABLED, + titan_request_irq(50+16, titan_intr_nop, IRQF_DISABLED, "Temperature Warning", NULL); /* diff --git a/arch/blackfin/kernel/init_task.c b/arch/blackfin/kernel/init_task.c index b45188f8512e..673c860ffc23 100644 --- a/arch/blackfin/kernel/init_task.c +++ b/arch/blackfin/kernel/init_task.c @@ -31,6 +31,7 @@ #include <linux/module.h> #include <linux/init_task.h> #include <linux/mqueue.h> +#include <linux/fs.h> static struct fs_struct init_fs = INIT_FS; static struct files_struct init_files = INIT_FILES; diff --git a/arch/blackfin/kernel/process.c b/arch/blackfin/kernel/process.c index 5a51dd6ab280..6a7aefe48346 100644 --- a/arch/blackfin/kernel/process.c +++ b/arch/blackfin/kernel/process.c @@ -33,6 +33,8 @@ #include <linux/user.h> #include <linux/a.out.h> #include <linux/uaccess.h> +#include <linux/fs.h> +#include <linux/err.h> #include <asm/blackfin.h> #include <asm/fixed_code.h> diff --git a/arch/blackfin/kernel/sys_bfin.c b/arch/blackfin/kernel/sys_bfin.c index f5e1ae3d1705..abcd14817d0e 100644 --- a/arch/blackfin/kernel/sys_bfin.c +++ b/arch/blackfin/kernel/sys_bfin.c @@ -37,6 +37,7 @@ #include <linux/syscalls.h> #include <linux/mman.h> #include <linux/file.h> +#include <linux/fs.h> #include <linux/uaccess.h> #include <linux/ipc.h> #include <linux/unistd.h> diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c index 8766bd612b47..792a8416fe10 100644 --- a/arch/blackfin/kernel/traps.c +++ b/arch/blackfin/kernel/traps.c @@ -31,6 +31,7 @@ #include <linux/interrupt.h> #include <linux/module.h> #include <linux/kallsyms.h> +#include <linux/fs.h> #include <asm/traps.h> #include <asm/cacheflush.h> #include <asm/blackfin.h> diff --git a/arch/cris/Kconfig b/arch/cris/Kconfig index 4b41248b61ad..6b4d026a00a1 100644 --- a/arch/cris/Kconfig +++ b/arch/cris/Kconfig @@ -180,8 +180,6 @@ source "drivers/isdn/Kconfig" source "drivers/telephony/Kconfig" -source "drivers/cdrom/Kconfig" - # # input before char - char/joystick depends on it. As does USB. # diff --git a/arch/frv/kernel/entry.S b/arch/frv/kernel/entry.S index 275673c192aa..1e74f3c5cee2 100644 --- a/arch/frv/kernel/entry.S +++ b/arch/frv/kernel/entry.S @@ -1496,6 +1496,7 @@ sys_call_table: .long sys_signalfd .long sys_timerfd .long sys_eventfd + .long sys_fallocate syscall_table_size = (. - sys_call_table) diff --git a/arch/i386/kernel/alternative.c b/arch/i386/kernel/alternative.c index c85598acb8fd..1b66d5c70eaf 100644 --- a/arch/i386/kernel/alternative.c +++ b/arch/i386/kernel/alternative.c @@ -11,6 +11,8 @@ #include <asm/mce.h> #include <asm/nmi.h> +#define MAX_PATCH_LEN (255-1) + #ifdef CONFIG_HOTPLUG_CPU static int smp_alt_once; @@ -148,7 +150,8 @@ static unsigned char** find_nop_table(void) #endif /* CONFIG_X86_64 */ -static void nop_out(void *insns, unsigned int len) +/* Use this to add nops to a buffer, then text_poke the whole buffer. */ +static void add_nops(void *insns, unsigned int len) { unsigned char **noptable = find_nop_table(); @@ -156,7 +159,7 @@ static void nop_out(void *insns, unsigned int len) unsigned int noplen = len; if (noplen > ASM_NOP_MAX) noplen = ASM_NOP_MAX; - text_poke(insns, noptable[noplen], noplen); + memcpy(insns, noptable[noplen], noplen); insns += noplen; len -= noplen; } @@ -174,15 +177,15 @@ extern u8 *__smp_locks[], *__smp_locks_end[]; void apply_alternatives(struct alt_instr *start, struct alt_instr *end) { struct alt_instr *a; - u8 *instr; - int diff; + char insnbuf[MAX_PATCH_LEN]; DPRINTK("%s: alt table %p -> %p\n", __FUNCTION__, start, end); for (a = start; a < end; a++) { + u8 *instr = a->instr; BUG_ON(a->replacementlen > a->instrlen); + BUG_ON(a->instrlen > sizeof(insnbuf)); if (!boot_cpu_has(a->cpuid)) continue; - instr = a->instr; #ifdef CONFIG_X86_64 /* vsyscall code is not mapped yet. resolve it manually. */ if (instr >= (u8 *)VSYSCALL_START && instr < (u8*)VSYSCALL_END) { @@ -191,9 +194,10 @@ void apply_alternatives(struct alt_instr *start, struct alt_instr *end) __FUNCTION__, a->instr, instr); } #endif - memcpy(instr, a->replacement, a->replacementlen); - diff = a->instrlen - a->replacementlen; - nop_out(instr + a->replacementlen, diff); + memcpy(insnbuf, a->replacement, a->replacementlen); + add_nops(insnbuf + a->replacementlen, + a->instrlen - a->replacementlen); + text_poke(instr, insnbuf, a->instrlen); } } @@ -215,16 +219,18 @@ static void alternatives_smp_lock(u8 **start, u8 **end, u8 *text, u8 *text_end) static void alternatives_smp_unlock(u8 **start, u8 **end, u8 *text, u8 *text_end) { u8 **ptr; + char insn[1]; if (noreplace_smp) return; + add_nops(insn, 1); for (ptr = start; ptr < end; ptr++) { if (*ptr < text) continue; if (*ptr > text_end) continue; - nop_out(*ptr, 1); + text_poke(*ptr, insn, 1); }; } @@ -351,6 +357,7 @@ void apply_paravirt(struct paravirt_patch_site *start, struct paravirt_patch_site *end) { struct paravirt_patch_site *p; + char insnbuf[MAX_PATCH_LEN]; if (noreplace_paravirt) return; @@ -358,13 +365,15 @@ void apply_paravirt(struct paravirt_patch_site *start, for (p = start; p < end; p++) { unsigned int used; - used = paravirt_ops.patch(p->instrtype, p->clobbers, p->instr, - p->len); + BUG_ON(p->len > MAX_PATCH_LEN); + used = paravirt_ops.patch(p->instrtype, p->clobbers, insnbuf, + (unsigned long)p->instr, p->len); BUG_ON(used > p->len); /* Pad the rest with nops */ - nop_out(p->instr + used, p->len - used); + add_nops(insnbuf + used, p->len - used); + text_poke(p->instr, insnbuf, p->len); } } extern struct paravirt_patch_site __start_parainstructions[], @@ -379,7 +388,7 @@ void __init alternative_instructions(void) that might execute the to be patched code. Other CPUs are not running. */ stop_nmi(); -#ifdef CONFIG_MCE +#ifdef CONFIG_X86_MCE stop_mce(); #endif @@ -417,7 +426,7 @@ void __init alternative_instructions(void) local_irq_restore(flags); restart_nmi(); -#ifdef CONFIG_MCE +#ifdef CONFIG_X86_MCE restart_mce(); #endif } diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c index bfc6cb7df7e7..f9fff29e01a9 100644 --- a/arch/i386/kernel/apic.c +++ b/arch/i386/kernel/apic.c @@ -61,8 +61,9 @@ static int enable_local_apic __initdata = 0; /* Local APIC timer verification ok */ static int local_apic_timer_verify_ok; -/* Disable local APIC timer from the kernel commandline or via dmi quirk */ -static int local_apic_timer_disabled; +/* Disable local APIC timer from the kernel commandline or via dmi quirk + or using CPU MSR check */ +int local_apic_timer_disabled; /* Local APIC timer works in C2 */ int local_apic_timer_c2_ok; EXPORT_SYMBOL_GPL(local_apic_timer_c2_ok); @@ -370,12 +371,9 @@ void __init setup_boot_APIC_clock(void) long delta, deltapm; int pm_referenced = 0; - if (boot_cpu_has(X86_FEATURE_LAPIC_TIMER_BROKEN)) - local_apic_timer_disabled = 1; - /* * The local apic timer can be disabled via the kernel - * commandline or from the test above. Register the lapic + * commandline or from the CPU detection code. Register the lapic * timer as a dummy clock event source on SMP systems, so the * broadcast mechanism is used. On UP systems simply ignore it. */ diff --git a/arch/i386/kernel/cpu/amd.c b/arch/i386/kernel/cpu/amd.c index c7ba455d5ac7..dcf6bbb1c7c0 100644 --- a/arch/i386/kernel/cpu/amd.c +++ b/arch/i386/kernel/cpu/amd.c @@ -3,6 +3,7 @@ #include <linux/mm.h> #include <asm/io.h> #include <asm/processor.h> +#include <asm/apic.h> #include "cpu.h" @@ -22,6 +23,7 @@ extern void vide(void); __asm__(".align 4\nvide: ret"); +#ifdef CONFIG_X86_LOCAL_APIC #define ENABLE_C1E_MASK 0x18000000 #define CPUID_PROCESSOR_SIGNATURE 1 #define CPUID_XFAM 0x0ff00000 @@ -52,6 +54,7 @@ static __cpuinit int amd_apic_timer_broken(void) } return 0; } +#endif int force_mwait __cpuinitdata; @@ -282,8 +285,10 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c) num_cache_leaves = 3; } +#ifdef CONFIG_X86_LOCAL_APIC if (amd_apic_timer_broken()) - set_bit(X86_FEATURE_LAPIC_TIMER_BROKEN, c->x86_capability); + local_apic_timer_disabled = 1; +#endif if (c->x86 == 0x10 && !force_mwait) clear_bit(X86_FEATURE_MWAIT, c->x86_capability); diff --git a/arch/i386/kernel/doublefault.c b/arch/i386/kernel/doublefault.c index 265c5597efb0..40978af630e7 100644 --- a/arch/i386/kernel/doublefault.c +++ b/arch/i386/kernel/doublefault.c @@ -13,7 +13,7 @@ static unsigned long doublefault_stack[DOUBLEFAULT_STACKSIZE]; #define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE) -#define ptr_ok(x) ((x) > PAGE_OFFSET && (x) < PAGE_OFFSET + 0x1000000) +#define ptr_ok(x) ((x) > PAGE_OFFSET && (x) < PAGE_OFFSET + MAXMEM) static void doublefault_fn(void) { @@ -23,23 +23,23 @@ static void doublefault_fn(void) store_gdt(&gdt_desc); gdt = gdt_desc.address; - printk("double fault, gdt at %08lx [%d bytes]\n", gdt, gdt_desc.size); + printk(KERN_EMERG "PANIC: double fault, gdt at %08lx [%d bytes]\n", gdt, gdt_desc.size); if (ptr_ok(gdt)) { gdt += GDT_ENTRY_TSS << 3; tss = *(u16 *)(gdt+2); tss += *(u8 *)(gdt+4) << 16; tss += *(u8 *)(gdt+7) << 24; - printk("double fault, tss at %08lx\n", tss); + printk(KERN_EMERG "double fault, tss at %08lx\n", tss); if (ptr_ok(tss)) { struct i386_hw_tss *t = (struct i386_hw_tss *)tss; - printk("eip = %08lx, esp = %08lx\n", t->eip, t->esp); + printk(KERN_EMERG "eip = %08lx, esp = %08lx\n", t->eip, t->esp); - printk("eax = %08lx, ebx = %08lx, ecx = %08lx, edx = %08lx\n", + printk(KERN_EMERG "eax = %08lx, ebx = %08lx, ecx = %08lx, edx = %08lx\n", t->eax, t->ebx, t->ecx, t->edx); - printk("esi = %08lx, edi = %08lx\n", + printk(KERN_EMERG "esi = %08lx, edi = %08lx\n", t->esi, t->edi); } } @@ -63,6 +63,7 @@ struct tss_struct doublefault_tss __cacheline_aligned = { .cs = __KERNEL_CS, .ss = __KERNEL_DS, .ds = __USER_DS, + .fs = __KERNEL_PERCPU, .__cr3 = __pa(swapper_pg_dir) } diff --git a/arch/i386/kernel/head.S b/arch/i386/kernel/head.S index 7c52b222207e..8f0382161c91 100644 --- a/arch/i386/kernel/head.S +++ b/arch/i386/kernel/head.S @@ -162,9 +162,7 @@ page_pde_offset = (__PAGE_OFFSET >> 20); * which will be freed later */ -#ifdef CONFIG_HOTPLUG_CPU -.section .text,"ax",@progbits -#else +#ifndef CONFIG_HOTPLUG_CPU .section .init.text,"ax",@progbits #endif diff --git a/arch/i386/kernel/paravirt.c b/arch/i386/kernel/paravirt.c index ea962c0667d5..739cfb207dd7 100644 --- a/arch/i386/kernel/paravirt.c +++ b/arch/i386/kernel/paravirt.c @@ -69,7 +69,8 @@ DEF_NATIVE(read_tsc, "rdtsc"); DEF_NATIVE(ud2a, "ud2a"); -static unsigned native_patch(u8 type, u16 clobbers, void *insns, unsigned len) +static unsigned native_patch(u8 type, u16 clobbers, void *ibuf, + unsigned long addr, unsigned len) { const unsigned char *start, *end; unsigned ret; @@ -90,7 +91,7 @@ static unsigned native_patch(u8 type, u16 clobbers, void *insns, unsigned len) #undef SITE patch_site: - ret = paravirt_patch_insns(insns, len, start, end); + ret = paravirt_patch_insns(ibuf, len, start, end); break; case PARAVIRT_PATCH(make_pgd): @@ -107,7 +108,7 @@ static unsigned native_patch(u8 type, u16 clobbers, void *insns, unsigned len) break; default: - ret = paravirt_patch_default(type, clobbers, insns, len); + ret = paravirt_patch_default(type, clobbers, ibuf, addr, len); break; } @@ -129,68 +130,67 @@ struct branch { u32 delta; } __attribute__((packed)); -unsigned paravirt_patch_call(void *target, u16 tgt_clobbers, - void *site, u16 site_clobbers, +unsigned paravirt_patch_call(void *insnbuf, + const void *target, u16 tgt_clobbers, + unsigned long addr, u16 site_clobbers, unsigned len) { - unsigned char *call = site; - unsigned long delta = (unsigned long)target - (unsigned long)(call+5); - struct branch b; + struct branch *b = insnbuf; + unsigned long delta = (unsigned long)target - (addr+5); if (tgt_clobbers & ~site_clobbers) return len; /* target would clobber too much for this site */ if (len < 5) return len; /* call too long for patch site */ - b.opcode = 0xe8; /* call */ - b.delta = delta; - BUILD_BUG_ON(sizeof(b) != 5); - text_poke(call, (unsigned char *)&b, 5); + b->opcode = 0xe8; /* call */ + b->delta = delta; + BUILD_BUG_ON(sizeof(*b) != 5); return 5; } -unsigned paravirt_patch_jmp(void *target, void *site, unsigned len) +unsigned paravirt_patch_jmp(const void *target, void *insnbuf, + unsigned long addr, unsigned len) { - unsigned char *jmp = site; - unsigned long delta = (unsigned long)target - (unsigned long)(jmp+5); - struct branch b; + struct branch *b = insnbuf; + unsigned long delta = (unsigned long)target - (addr+5); if (len < 5) return len; /* call too long for patch site */ - b.opcode = 0xe9; /* jmp */ - b.delta = delta; - text_poke(jmp, (unsigned char *)&b, 5); + b->opcode = 0xe9; /* jmp */ + b->delta = delta; return 5; } -unsigned paravirt_patch_default(u8 type, u16 clobbers, void *site, unsigned len) +unsigned paravirt_patch_default(u8 type, u16 clobbers, void *insnbuf, + unsigned long addr, unsigned len) { void *opfunc = *((void **)¶virt_ops + type); unsigned ret; if (opfunc == NULL) /* If there's no function, patch it with a ud2a (BUG) */ - ret = paravirt_patch_insns(site, len, start_ud2a, end_ud2a); + ret = paravirt_patch_insns(insnbuf, len, start_ud2a, end_ud2a); else if (opfunc == paravirt_nop) /* If the operation is a nop, then nop the callsite */ ret = paravirt_patch_nop(); else if (type == PARAVIRT_PATCH(iret) || type == PARAVIRT_PATCH(irq_enable_sysexit)) /* If operation requires a jmp, then jmp */ - ret = paravirt_patch_jmp(opfunc, site, len); + ret = paravirt_patch_jmp(opfunc, insnbuf, addr, len); else /* Otherwise call the function; assume target could clobber any caller-save reg */ - ret = paravirt_patch_call(opfunc, CLBR_ANY, - site, clobbers, len); + ret = paravirt_patch_call(insnbuf, opfunc, CLBR_ANY, + addr, clobbers, len); return ret; } -unsigned paravirt_patch_insns(void *site, unsigned len, +unsigned paravirt_patch_insns(void *insnbuf, unsigned len, const char *start, const char *end) { unsigned insn_len = end - start; @@ -198,7 +198,7 @@ unsigned paravirt_patch_insns(void *site, unsigned len, if (insn_len > len || start == NULL) insn_len = len; else - memcpy(site, start, insn_len); + memcpy(insnbuf, start, insn_len); return insn_len; } diff --git a/arch/i386/kernel/vmi.c b/arch/i386/kernel/vmi.c index 72042bb7ec94..18673e0f193b 100644 --- a/arch/i386/kernel/vmi.c +++ b/arch/i386/kernel/vmi.c @@ -87,12 +87,14 @@ struct vmi_timer_ops vmi_timer_ops; #define IRQ_PATCH_INT_MASK 0 #define IRQ_PATCH_DISABLE 5 -static inline void patch_offset(unsigned char *eip, unsigned char *dest) +static inline void patch_offset(void *insnbuf, + unsigned long eip, unsigned long dest) { - *(unsigned long *)(eip+1) = dest-eip-5; + *(unsigned long *)(insnbuf+1) = dest-eip-5; } -static unsigned patch_internal(int call, unsigned len, void *insns) +static unsigned patch_internal(int call, unsigned len, void *insnbuf, + unsigned long eip) { u64 reloc; struct vmi_relocation_info *const rel = (struct vmi_relocation_info *)&reloc; @@ -100,14 +102,14 @@ static unsigned patch_internal(int call, unsigned len, void *insns) switch(rel->type) { case VMI_RELOCATION_CALL_REL: BUG_ON(len < 5); - *(char *)insns = MNEM_CALL; - patch_offset(insns, rel->eip); + *(char *)insnbuf = MNEM_CALL; + patch_offset(insnbuf, eip, (unsigned long)rel->eip); return 5; case VMI_RELOCATION_JUMP_REL: BUG_ON(len < 5); - *(char *)insns = MNEM_JMP; - patch_offset(insns, rel->eip); + *(char *)insnbuf = MNEM_JMP; + patch_offset(insnbuf, eip, (unsigned long)rel->eip); return 5; case VMI_RELOCATION_NOP: @@ -128,21 +130,26 @@ static unsigned patch_internal(int call, unsigned len, void *insns) * Apply patch if appropriate, return length of new instruction * sequence. The callee does nop padding for us. */ -static unsigned vmi_patch(u8 type, u16 clobbers, void *insns, unsigned len) +static unsigned vmi_patch(u8 type, u16 clobbers, void *insns, + unsigned long eip, unsigned len) { switch (type) { case PARAVIRT_PATCH(irq_disable): - return patch_internal(VMI_CALL_DisableInterrupts, len, insns); + return patch_internal(VMI_CALL_DisableInterrupts, len, + insns, eip); case PARAVIRT_PATCH(irq_enable): - return patch_internal(VMI_CALL_EnableInterrupts, len, insns); + return patch_internal(VMI_CALL_EnableInterrupts, len, + insns, eip); case PARAVIRT_PATCH(restore_fl): - return patch_internal(VMI_CALL_SetInterruptMask, len, insns); + return patch_internal(VMI_CALL_SetInterruptMask, len, + insns, eip); case PARAVIRT_PATCH(save_fl): - return patch_internal(VMI_CALL_GetInterruptMask, len, insns); + return patch_internal(VMI_CALL_GetInterruptMask, len, + insns, eip); case PARAVIRT_PATCH(iret): - return patch_internal(VMI_CALL_IRET, len, insns); + return patch_internal(VMI_CALL_IRET, len, insns, eip); case PARAVIRT_PATCH(irq_enable_sysexit): - return patch_internal(VMI_CALL_SYSEXIT, len, insns); + return patch_internal(VMI_CALL_SYSEXIT, len, insns, eip); default: break; } diff --git a/arch/i386/mm/pageattr.c b/arch/i386/mm/pageattr.c index 8927222b3ab2..4241a74d16c8 100644 --- a/arch/i386/mm/pageattr.c +++ b/arch/i386/mm/pageattr.c @@ -82,7 +82,7 @@ static void flush_kernel_map(void *arg) struct page *p; /* High level code is not ready for clflush yet */ - if (cpu_has_clflush) { + if (0 && cpu_has_clflush) { list_for_each_entry (p, lh, lru) cache_flush_page(p); } else if (boot_cpu_data.x86_model >= 4) diff --git a/arch/i386/pci/common.c b/arch/i386/pci/common.c index 85503deeda46..ebc6f3c66340 100644 --- a/arch/i386/pci/common.c +++ b/arch/i386/pci/common.c @@ -455,3 +455,26 @@ void pcibios_disable_device (struct pci_dev *dev) if (!dev->msi_enabled && pcibios_disable_irq) pcibios_disable_irq(dev); } + +struct pci_bus *pci_scan_bus_with_sysdata(int busno) +{ + struct pci_bus *bus = NULL; + struct pci_sysdata *sd; + + /* + * Allocate per-root-bus (not per bus) arch-specific data. + * TODO: leak; this memory is never freed. + * It's arguable whether it's worth the trouble to care. + */ + sd = kzalloc(sizeof(*sd), GFP_KERNEL); + if (!sd) { + printk(KERN_ERR "PCI: OOM, skipping PCI bus %02x\n", busno); + return NULL; + } + sd->node = -1; + bus = pci_scan_bus(busno, &pci_root_ops, sd); + if (!bus) + kfree(sd); + + return bus; +} diff --git a/arch/i386/pci/fixup.c b/arch/i386/pci/fixup.c index e7306dbf6c42..c82cbf4c7226 100644 --- a/arch/i386/pci/fixup.c +++ b/arch/i386/pci/fixup.c @@ -25,9 +25,9 @@ static void __devinit pci_fixup_i450nx(struct pci_dev *d) pci_read_config_byte(d, reg++, &subb); DBG("i450NX PXB %d: %02x/%02x/%02x\n", pxb, busno, suba, subb); if (busno) - pci_scan_bus(busno, &pci_root_ops, NULL); /* Bus A */ + pci_scan_bus_with_sysdata(busno); /* Bus A */ if (suba < subb) - pci_scan_bus(suba+1, &pci_root_ops, NULL); /* Bus B */ + pci_scan_bus_with_sysdata(suba+1); /* Bus B */ } pcibios_last_bus = -1; } @@ -42,7 +42,7 @@ static void __devinit pci_fixup_i450gx(struct pci_dev *d) u8 busno; pci_read_config_byte(d, 0x4a, &busno); printk(KERN_INFO "PCI: i440KX/GX host bridge %s: secondary bus %02x\n", pci_name(d), busno); - pci_scan_bus(busno, &pci_root_ops, NULL); + pci_scan_bus_with_sysdata(busno); pcibios_last_bus = -1; } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454GX, pci_fixup_i450gx); diff --git a/arch/i386/pci/irq.c b/arch/i386/pci/irq.c index f2cb942f8281..665db063a40a 100644 --- a/arch/i386/pci/irq.c +++ b/arch/i386/pci/irq.c @@ -138,8 +138,9 @@ static void __init pirq_peer_trick(void) for(i = 1; i < 256; i++) { if (!busmap[i] || pci_find_bus(0, i)) continue; - if (pci_scan_bus(i, &pci_root_ops, NULL)) - printk(KERN_INFO "PCI: Discovered primary peer bus %02x [IRQ]\n", i); + if (pci_scan_bus_with_sysdata(i)) + printk(KERN_INFO "PCI: Discovered primary peer " + "bus %02x [IRQ]\n", i); } pcibios_last_bus = -1; } diff --git a/arch/i386/pci/legacy.c b/arch/i386/pci/legacy.c index 149a9588c256..5565d7016b75 100644 --- a/arch/i386/pci/legacy.c +++ b/arch/i386/pci/legacy.c @@ -26,7 +26,7 @@ static void __devinit pcibios_fixup_peer_bridges(void) l != 0x0000 && l != 0xffff) { DBG("Found device at %02x:%02x [%04x]\n", n, devfn, l); printk(KERN_INFO "PCI: Discovered peer bus %02x\n", n); - pci_scan_bus(n, &pci_root_ops, NULL); + pci_scan_bus_with_sysdata(n); break; } } diff --git a/arch/i386/pci/mmconfig.c b/arch/i386/pci/mmconfig.c index bb1afd9e589d..0d46b7a88b3b 100644 --- a/arch/i386/pci/mmconfig.c +++ b/arch/i386/pci/mmconfig.c @@ -82,16 +82,15 @@ static int pci_mmcfg_read(unsigned int seg, unsigned int bus, switch (len) { case 1: - *value = readb(mmcfg_virt_addr + reg); + *value = mmio_config_readb(mmcfg_virt_addr + reg); break; case 2: - *value = readw(mmcfg_virt_addr + reg); + *value = mmio_config_readw(mmcfg_virt_addr + reg); break; case 4: - *value = readl(mmcfg_virt_addr + reg); + *value = mmio_config_readl(mmcfg_virt_addr + reg); break; } - spin_unlock_irqrestore(&pci_config_lock, flags); return 0; @@ -116,16 +115,15 @@ static int pci_mmcfg_write(unsigned int seg, unsigned int bus, switch (len) { case 1: - writeb(value, mmcfg_virt_addr + reg); + mmio_config_writeb(mmcfg_virt_addr, value); break; case 2: - writew(value, mmcfg_virt_addr + reg); + mmio_config_writew(mmcfg_virt_addr, value); break; case 4: - writel(value, mmcfg_virt_addr + reg); + mmio_config_writel(mmcfg_virt_addr, value); break; } - spin_unlock_irqrestore(&pci_config_lock, flags); return 0; diff --git a/arch/i386/pci/numa.c b/arch/i386/pci/numa.c index adbe17a38f6f..f5f165f69e0c 100644 --- a/arch/i386/pci/numa.c +++ b/arch/i386/pci/numa.c @@ -96,10 +96,14 @@ static void __devinit pci_fixup_i450nx(struct pci_dev *d) pci_read_config_byte(d, reg++, &suba); pci_read_config_byte(d, reg++, &subb); DBG("i450NX PXB %d: %02x/%02x/%02x\n", pxb, busno, suba, subb); - if (busno) - pci_scan_bus(QUADLOCAL2BUS(quad,busno), &pci_root_ops, NULL); /* Bus A */ - if (suba < subb) - pci_scan_bus(QUADLOCAL2BUS(quad,suba+1), &pci_root_ops, NULL); /* Bus B */ + if (busno) { + /* Bus A */ + pci_scan_bus_with_sysdata(QUADLOCAL2BUS(quad, busno)); + } + if (suba < subb) { + /* Bus B */ + pci_scan_bus_with_sysdata(QUADLOCAL2BUS(quad, suba+1)); + } } pcibios_last_bus = -1; } @@ -123,8 +127,7 @@ static int __init pci_numa_init(void) continue; printk("Scanning PCI bus %d for quad %d\n", QUADLOCAL2BUS(quad,0), quad); - pci_scan_bus(QUADLOCAL2BUS(quad,0), - &pci_root_ops, NULL); + pci_scan_bus_with_sysdata(QUADLOCAL2BUS(quad, 0)); } return 0; } diff --git a/arch/i386/pci/pci.h b/arch/i386/pci/pci.h index e58bae2076ad..8c66f275756f 100644 --- a/arch/i386/pci/pci.h +++ b/arch/i386/pci/pci.h @@ -104,3 +104,46 @@ extern DECLARE_BITMAP(pci_mmcfg_fallback_slots, 32*PCI_MMCFG_MAX_CHECK_BUS); extern int __init pci_mmcfg_arch_reachable(unsigned int seg, unsigned int bus, unsigned int devfn); extern int __init pci_mmcfg_arch_init(void); + +/* + * AMD Fam10h CPUs are buggy, and cannot access MMIO config space + * on their northbrige except through the * %eax register. As such, you MUST + * NOT use normal IOMEM accesses, you need to only use the magic mmio-config + * accessor functions. + * In fact just use pci_config_*, nothing else please. + */ +static inline unsigned char mmio_config_readb(void __iomem *pos) +{ + u8 val; + asm volatile("movb (%1),%%al" : "=a" (val) : "r" (pos)); + return val; +} + +static inline unsigned short mmio_config_readw(void __iomem *pos) +{ + u16 val; + asm volatile("movw (%1),%%ax" : "=a" (val) : "r" (pos)); + return val; +} + +static inline unsigned int mmio_config_readl(void __iomem *pos) +{ + u32 val; + asm volatile("movl (%1),%%eax" : "=a" (val) : "r" (pos)); + return val; +} + +static inline void mmio_config_writeb(void __iomem *pos, u8 val) +{ + asm volatile("movb %%al,(%1)" :: "a" (val), "r" (pos) : "memory"); +} + +static inline void mmio_config_writew(void __iomem *pos, u16 val) +{ + asm volatile("movw %%ax,(%1)" :: "a" (val), "r" (pos) : "memory"); +} + +static inline void mmio_config_writel(void __iomem *pos, u32 val) +{ + asm volatile("movl %%eax,(%1)" :: "a" (val), "r" (pos) : "memory"); +} diff --git a/arch/i386/pci/visws.c b/arch/i386/pci/visws.c index f1b486d4190b..8ecb1c722594 100644 --- a/arch/i386/pci/visws.c +++ b/arch/i386/pci/visws.c @@ -101,8 +101,8 @@ static int __init pcibios_init(void) "bridge B (PIIX4) bus: %u\n", pci_bus1, pci_bus0); raw_pci_ops = &pci_direct_conf1; - pci_scan_bus(pci_bus0, &pci_root_ops, NULL); - pci_scan_bus(pci_bus1, &pci_root_ops, NULL); + pci_scan_bus_with_sysdata(pci_bus0); + pci_scan_bus_with_sysdata(pci_bus1); pci_fixup_irqs(visws_swizzle, visws_map_irq); pcibios_resource_survey(); return 0; diff --git a/arch/i386/xen/enlighten.c b/arch/i386/xen/enlighten.c index 9a8c1181c001..f0c37511d8da 100644 --- a/arch/i386/xen/enlighten.c +++ b/arch/i386/xen/enlighten.c @@ -842,7 +842,8 @@ void __init xen_setup_vcpu_info_placement(void) } } -static unsigned xen_patch(u8 type, u16 clobbers, void *insns, unsigned len) +static unsigned xen_patch(u8 type, u16 clobbers, void *insnbuf, + unsigned long addr, unsigned len) { char *start, *end, *reloc; unsigned ret; @@ -869,7 +870,7 @@ static unsigned xen_patch(u8 type, u16 clobbers, void *insns, unsigned len) if (start == NULL || (end-start) > len) goto default_patch; - ret = paravirt_patch_insns(insns, len, start, end); + ret = paravirt_patch_insns(insnbuf, len, start, end); /* Note: because reloc is assigned from something that appears to be an array, gcc assumes it's non-null, @@ -877,8 +878,8 @@ static unsigned xen_patch(u8 type, u16 clobbers, void *insns, unsigned len) end. */ if (reloc > start && reloc < end) { int reloc_off = reloc - start; - long *relocp = (long *)(insns + reloc_off); - long delta = start - (char *)insns; + long *relocp = (long *)(insnbuf + reloc_off); + long delta = start - (char *)addr; *relocp += delta; } @@ -886,7 +887,8 @@ static unsigned xen_patch(u8 type, u16 clobbers, void *insns, unsigned len) default_patch: default: - ret = paravirt_patch_default(type, clobbers, insns, len); + ret = paravirt_patch_default(type, clobbers, insnbuf, + addr, len); break; } diff --git a/arch/powerpc/configs/ps3_defconfig b/arch/powerpc/configs/ps3_defconfig index d0b43df44426..ca7a197998ee 100644 --- a/arch/powerpc/configs/ps3_defconfig +++ b/arch/powerpc/configs/ps3_defconfig @@ -1,9 +1,23 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.22-rc6 -# Tue Jun 26 14:15:19 2007 +# Linux kernel version: 2.6.23-rc2 +# Tue Aug 7 19:17:26 2007 # CONFIG_PPC64=y + +# +# Processor support +# +# CONFIG_POWER4_ONLY is not set +CONFIG_POWER3=y +CONFIG_POWER4=y +CONFIG_PPC_FPU=y +CONFIG_ALTIVEC=y +CONFIG_PPC_STD_MMU=y +# CONFIG_PPC_MM_SLICES is not set +CONFIG_VIRT_CPU_ACCOUNTING=y +CONFIG_SMP=y +CONFIG_NR_CPUS=2 CONFIG_64BIT=y CONFIG_PPC_MERGE=y CONFIG_MMU=y @@ -15,6 +29,7 @@ CONFIG_ARCH_HAS_ILOG2_U64=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_PPC=y CONFIG_EARLY_PRINTK=y CONFIG_COMPAT=y @@ -22,50 +37,32 @@ CONFIG_SYSVIPC_COMPAT=y CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y CONFIG_ARCH_MAY_HAVE_PC_FDC=y CONFIG_PPC_OF=y +CONFIG_OF=y # CONFIG_PPC_UDBG_16550 is not set # CONFIG_GENERIC_TBSYNC is not set CONFIG_AUDIT_ARCH=y CONFIG_GENERIC_BUG=y # CONFIG_DEFAULT_UIMAGE is not set - -# -# Processor support -# -# CONFIG_POWER4_ONLY is not set -CONFIG_POWER3=y -CONFIG_POWER4=y -CONFIG_PPC_FPU=y # CONFIG_PPC_DCR_NATIVE is not set # CONFIG_PPC_DCR_MMIO is not set # CONFIG_PPC_OF_PLATFORM_PCI is not set -CONFIG_ALTIVEC=y -CONFIG_PPC_STD_MMU=y -# CONFIG_PPC_MM_SLICES is not set -CONFIG_VIRT_CPU_ACCOUNTING=y -CONFIG_SMP=y -CONFIG_NR_CPUS=2 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # -# Code maturity level options +# General setup # CONFIG_EXPERIMENTAL=y CONFIG_LOCK_KERNEL=y CONFIG_INIT_ENV_ARG_LIMIT=32 - -# -# General setup -# CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION_AUTO=y CONFIG_SWAP=y CONFIG_SYSVIPC=y -# CONFIG_IPC_NS is not set CONFIG_SYSVIPC_SYSCTL=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set -# CONFIG_UTS_NS is not set +# CONFIG_USER_NS is not set # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=17 @@ -100,10 +97,6 @@ CONFIG_SLAB=y CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 - -# -# Loadable module support -# CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set @@ -111,12 +104,9 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_KMOD=y CONFIG_STOP_MACHINE=y - -# -# Block layer -# CONFIG_BLOCK=y # CONFIG_BLK_DEV_IO_TRACE is not set +CONFIG_BLK_DEV_BSG=y # # IO Schedulers @@ -136,7 +126,9 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" # CONFIG_PPC_MULTIPLATFORM=y # CONFIG_EMBEDDED6xx is not set -# CONFIG_APUS is not set +# CONFIG_PPC_82xx is not set +# CONFIG_PPC_83xx is not set +# CONFIG_PPC_86xx is not set # CONFIG_PPC_PSERIES is not set # CONFIG_PPC_ISERIES is not set # CONFIG_PPC_MPC52xx is not set @@ -223,6 +215,7 @@ CONFIG_MEMORY_HOTPLUG_SPARSE=y CONFIG_SPLIT_PTLOCK_CPUS=4 CONFIG_RESOURCES_64BIT=y CONFIG_ZONE_DMA_FLAG=1 +CONFIG_BOUNCE=y CONFIG_ARCH_MEMORY_PROBE=y # CONFIG_PPC_HAS_HASH_64K is not set # CONFIG_PPC_64K_PAGES is not set @@ -241,6 +234,7 @@ CONFIG_ZONE_DMA=y CONFIG_GENERIC_ISA_DMA=y # CONFIG_PCI is not set # CONFIG_PCI_DOMAINS is not set +# CONFIG_PCI_SYSCALL is not set # CONFIG_ARCH_SUPPORTS_MSI is not set # @@ -365,6 +359,7 @@ CONFIG_WIRELESS_EXT=y # CONFIG_MAC80211 is not set # CONFIG_IEEE80211 is not set # CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set # # Device Drivers @@ -379,26 +374,11 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_DEBUG_DRIVER is not set # CONFIG_DEBUG_DEVRES is not set # CONFIG_SYS_HYPERVISOR is not set - -# -# Connector - unified userspace <-> kernelspace linker -# # CONFIG_CONNECTOR is not set # CONFIG_MTD is not set - -# -# Parallel port support -# +CONFIG_OF_DEVICE=y # CONFIG_PARPORT is not set - -# -# Plug and Play support -# -# CONFIG_PNPACPI is not set - -# -# Block devices -# +CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_FD is not set # CONFIG_BLK_DEV_COW_COMMON is not set CONFIG_BLK_DEV_LOOP=y @@ -411,11 +391,8 @@ CONFIG_BLK_DEV_RAM_SIZE=65535 CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set - -# -# Misc devices -# -# CONFIG_BLINK is not set +CONFIG_MISC_DEVICES=y +# CONFIG_EEPROM_93CX6 is not set # CONFIG_IDE is not set # @@ -423,6 +400,7 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y +CONFIG_SCSI_DMA=y # CONFIG_SCSI_TGT is not set # CONFIG_SCSI_NETLINK is not set CONFIG_SCSI_PROC_FS=y @@ -455,37 +433,22 @@ CONFIG_SCSI_WAIT_SCAN=m # CONFIG_SCSI_ISCSI_ATTRS is not set # CONFIG_SCSI_SAS_ATTRS is not set # CONFIG_SCSI_SAS_LIBSAS is not set - -# -# SCSI low-level drivers -# -# CONFIG_ISCSI_TCP is not set -# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_LOWLEVEL is not set # CONFIG_ATA is not set - -# -# Multi-device support (RAID and LVM) -# # CONFIG_MD is not set # CONFIG_MACINTOSH_DRIVERS is not set - -# -# Network device support -# CONFIG_NETDEVICES=y +# CONFIG_NETDEVICES_MULTIQUEUE is not set # CONFIG_DUMMY is not set # CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set - -# -# Ethernet (10 or 100Mbit) -# # CONFIG_NET_ETHERNET is not set CONFIG_MII=m CONFIG_NETDEV_1000=y -CONFIG_NETDEV_10000=y CONFIG_GELIC_NET=y +# CONFIG_NETDEV_10000 is not set # # Wireless LAN @@ -518,15 +481,7 @@ CONFIG_USB_NET_MCS7830=m # CONFIG_NETCONSOLE is not set # CONFIG_NETPOLL is not set # CONFIG_NET_POLL_CONTROLLER is not set - -# -# ISDN subsystem -# # CONFIG_ISDN is not set - -# -# Telephony Support -# # CONFIG_PHONE is not set # @@ -604,10 +559,6 @@ CONFIG_VT_HW_CONSOLE_BINDING=y CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=16 - -# -# IPMI -# # CONFIG_IPMI_HANDLER is not set # CONFIG_WATCHDOG is not set # CONFIG_HW_RANDOM is not set @@ -616,10 +567,6 @@ CONFIG_GEN_RTC=y # CONFIG_R3964 is not set # CONFIG_RAW_DRIVER is not set # CONFIG_HANGCHECK_TIMER is not set - -# -# TPM devices -# # CONFIG_TCG_TPM is not set # CONFIG_I2C is not set @@ -628,11 +575,8 @@ CONFIG_GEN_RTC=y # # CONFIG_SPI is not set # CONFIG_SPI_MASTER is not set - -# -# Dallas's 1-wire bus -# # CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set # CONFIG_HWMON is not set # @@ -657,6 +601,7 @@ CONFIG_GEN_RTC=y # # CONFIG_DISPLAY_SUPPORT is not set # CONFIG_VGASTATE is not set +CONFIG_VIDEO_OUTPUT_CONTROL=m CONFIG_FB=y # CONFIG_FIRMWARE_EDID is not set # CONFIG_FB_DDC is not set @@ -691,11 +636,13 @@ CONFIG_FB_PS3_DEFAULT_SIZE_M=18 # CONFIG_VGA_CONSOLE is not set CONFIG_DUMMY_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y # CONFIG_FONTS is not set CONFIG_FONT_8x8=y CONFIG_FONT_8x16=y CONFIG_LOGO=y +CONFIG_FB_LOGO_EXTRA=y # CONFIG_LOGO_LINUX_MONO is not set # CONFIG_LOGO_LINUX_VGA16 is not set CONFIG_LOGO_LINUX_CLUT224=y @@ -709,6 +656,8 @@ CONFIG_SOUND=y # Advanced Linux Sound Architecture # CONFIG_SND=y +CONFIG_SND_TIMER=y +CONFIG_SND_PCM=y # CONFIG_SND_SEQUENCER is not set # CONFIG_SND_MIXER_OSS is not set # CONFIG_SND_PCM_OSS is not set @@ -735,6 +684,12 @@ CONFIG_SND_VERBOSE_PROCFS=y # # +# ALSA PowerPC devices +# +CONFIG_SND_PS3=y +CONFIG_SND_PS3_DEFAULT_START_DELAY=2000 + +# # USB devices # # CONFIG_SND_USB_AUDIO is not set @@ -747,13 +702,14 @@ CONFIG_SND_VERBOSE_PROCFS=y # CONFIG_SND_SOC is not set # -# Open Sound System +# SoC Audio support for SuperH # -# CONFIG_SOUND_PRIME is not set # -# HID Devices +# Open Sound System # +# CONFIG_SOUND_PRIME is not set +CONFIG_HID_SUPPORT=y CONFIG_HID=y # CONFIG_HID_DEBUG is not set @@ -770,10 +726,7 @@ CONFIG_USB_HID=m # # CONFIG_USB_KBD is not set # CONFIG_USB_MOUSE is not set - -# -# USB support -# +CONFIG_USB_SUPPORT=y CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB_ARCH_HAS_OHCI=y CONFIG_USB_ARCH_HAS_EHCI=y @@ -803,6 +756,7 @@ CONFIG_USB_OHCI_HCD=y CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y CONFIG_USB_OHCI_LITTLE_ENDIAN=y # CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set # # USB Device Class drivers @@ -879,31 +833,8 @@ CONFIG_USB_MON=y # # CONFIG_USB_GADGET is not set # CONFIG_MMC is not set - -# -# LED devices -# # CONFIG_NEW_LEDS is not set - -# -# LED drivers -# - -# -# LED Triggers -# - -# -# InfiniBand support -# - -# -# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) -# - -# -# Real Time Clock -# +# CONFIG_EDAC is not set # CONFIG_RTC_CLASS is not set # @@ -920,6 +851,11 @@ CONFIG_USB_MON=y # # +# Userspace I/O +# +# CONFIG_UIO is not set + +# # File systems # CONFIG_EXT2_FS=m @@ -948,8 +884,8 @@ CONFIG_QUOTA=y CONFIG_QFMT_V2=y CONFIG_QUOTACTL=y CONFIG_DNOTIFY=y -# CONFIG_AUTOFS_FS is not set -CONFIG_AUTOFS4_FS=y +CONFIG_AUTOFS_FS=m +CONFIG_AUTOFS4_FS=m # CONFIG_FUSE_FS is not set # @@ -1030,7 +966,6 @@ CONFIG_CIFS=m # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set -# CONFIG_9P_FS is not set # # Partition Types @@ -1096,6 +1031,7 @@ CONFIG_BITREVERSE=y # CONFIG_CRC16 is not set # CONFIG_CRC_ITU_T is not set CONFIG_CRC32=y +# CONFIG_CRC7 is not set # CONFIG_LIBCRC32C is not set CONFIG_PLIST=y CONFIG_HAS_IOMEM=y @@ -1120,6 +1056,7 @@ CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_KERNEL=y # CONFIG_DEBUG_SHIRQ is not set CONFIG_DETECT_SOFTLOCKUP=y +CONFIG_SCHED_DEBUG=y # CONFIG_SCHEDSTATS is not set # CONFIG_TIMER_STATS is not set # CONFIG_DEBUG_SLAB is not set @@ -1150,10 +1087,6 @@ CONFIG_IRQSTACKS=y # # CONFIG_KEYS is not set # CONFIG_SECURITY is not set - -# -# Cryptographic options -# CONFIG_CRYPTO=y CONFIG_CRYPTO_ALGAPI=y CONFIG_CRYPTO_BLKCIPHER=y @@ -1191,7 +1124,4 @@ CONFIG_CRYPTO_DES=y # CONFIG_CRYPTO_CRC32C is not set # CONFIG_CRYPTO_CAMELLIA is not set # CONFIG_CRYPTO_TEST is not set - -# -# Hardware crypto devices -# +CONFIG_CRYPTO_HW=y diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index 1448af92c6a9..171800002ede 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S @@ -1672,8 +1672,9 @@ _GLOBAL(__start_initialization_multiplatform) * Are we booted from a PROM Of-type client-interface ? */ cmpldi cr0,r5,0 - bne .__boot_from_prom /* yes -> prom */ - + beq 1f + b .__boot_from_prom /* yes -> prom */ +1: /* Save parameters */ mr r31,r3 mr r30,r4 @@ -1701,7 +1702,7 @@ _GLOBAL(__start_initialization_multiplatform) bl .__mmu_off b .__after_prom_start -_STATIC(__boot_from_prom) +_INIT_STATIC(__boot_from_prom) /* Save parameters */ mr r31,r3 mr r30,r4 @@ -1768,9 +1769,10 @@ _STATIC(__after_prom_start) /* the source addr */ cmpdi r4,0 /* In some cases the loader may */ - beq .start_here_multiplatform /* have already put us at zero */ + bne 1f + b .start_here_multiplatform /* have already put us at zero */ /* so we can skip the copy. */ - LOAD_REG_IMMEDIATE(r5,copy_to_here) /* # bytes of memory to copy */ +1: LOAD_REG_IMMEDIATE(r5,copy_to_here) /* # bytes of memory to copy */ sub r5,r5,r27 li r6,0x100 /* Start offset, the first 0x100 */ @@ -1957,7 +1959,7 @@ _GLOBAL(enable_64b_mode) /* * This is where the main kernel code starts. */ -_STATIC(start_here_multiplatform) +_INIT_STATIC(start_here_multiplatform) /* get a new offset, now that the kernel has moved. */ bl .reloc_offset mr r26,r3 @@ -2019,7 +2021,7 @@ _STATIC(start_here_multiplatform) b . /* prevent speculative execution */ /* This is where all platforms converge execution */ -_STATIC(start_here_common) +_INIT_STATIC(start_here_common) /* relocation is on at this point */ /* The following code sets up the SP and TOC now that we are */ diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c index a97e23ac1976..291ffbc360c9 100644 --- a/arch/powerpc/kernel/pci_64.c +++ b/arch/powerpc/kernel/pci_64.c @@ -313,6 +313,7 @@ struct pci_dev *of_create_pci_dev(struct device_node *node, dev->current_state = 4; /* unknown power state */ dev->error_state = pci_channel_io_normal; + dev->dma_mask = 0xffffffff; if (!strcmp(type, "pci") || !strcmp(type, "pciex")) { /* a PCI-PCI bridge */ diff --git a/arch/powerpc/mm/slb.c b/arch/powerpc/mm/slb.c index b0697017d0e8..a73d2d700973 100644 --- a/arch/powerpc/mm/slb.c +++ b/arch/powerpc/mm/slb.c @@ -69,20 +69,9 @@ static inline void slb_shadow_update(unsigned long ea, smp_wmb(); } -static inline void create_shadowed_slbe(unsigned long ea, unsigned long flags, - unsigned long entry) +static inline void slb_shadow_clear(unsigned long entry) { - /* - * Updating the shadow buffer before writing the SLB ensures - * we don't get a stale entry here if we get preempted by PHYP - * between these two statements. - */ - slb_shadow_update(ea, flags, entry); - - asm volatile("slbmte %0,%1" : - : "r" (mk_vsid_data(ea, flags)), - "r" (mk_esid_data(ea, entry)) - : "memory" ); + get_slb_shadow()->save_area[entry].esid = 0; } void slb_flush_and_rebolt(void) @@ -100,11 +89,13 @@ void slb_flush_and_rebolt(void) vflags = SLB_VSID_KERNEL | vmalloc_llp; ksp_esid_data = mk_esid_data(get_paca()->kstack, 2); - if ((ksp_esid_data & ESID_MASK) == PAGE_OFFSET) + if ((ksp_esid_data & ESID_MASK) == PAGE_OFFSET) { ksp_esid_data &= ~SLB_ESID_V; - - /* Only third entry (stack) may change here so only resave that */ - slb_shadow_update(get_paca()->kstack, lflags, 2); + slb_shadow_clear(2); + } else { + /* Update stack entry; others don't change */ + slb_shadow_update(get_paca()->kstack, lflags, 2); + } /* We need to do this all in asm, so we're sure we don't touch * the stack between the slbia and rebolting it. */ @@ -235,16 +226,12 @@ void slb_initialize(void) vflags = SLB_VSID_KERNEL | vmalloc_llp; /* Invalidate the entire SLB (even slot 0) & all the ERATS */ - asm volatile("isync":::"memory"); - asm volatile("slbmte %0,%0"::"r" (0) : "memory"); - asm volatile("isync; slbia; isync":::"memory"); - create_shadowed_slbe(PAGE_OFFSET, lflags, 0); - - create_shadowed_slbe(VMALLOC_START, vflags, 1); - - /* We don't bolt the stack for the time being - we're in boot, - * so the stack is in the bolted segment. By the time it goes - * elsewhere, we'll call _switch() which will bolt in the new - * one. */ - asm volatile("isync":::"memory"); + slb_shadow_update(PAGE_OFFSET, lflags, 0); + asm volatile("isync; slbia; sync; slbmte %0,%1; isync" :: + "r" (get_slb_shadow()->save_area[0].vsid), + "r" (get_slb_shadow()->save_area[0].esid) : "memory"); + + slb_shadow_update(VMALLOC_START, vflags, 1); + + slb_flush_and_rebolt(); } diff --git a/arch/powerpc/mm/slice.c b/arch/powerpc/mm/slice.c index f833dba2a028..d5fd3909d13a 100644 --- a/arch/powerpc/mm/slice.c +++ b/arch/powerpc/mm/slice.c @@ -405,6 +405,8 @@ unsigned long slice_get_unmapped_area(unsigned long addr, unsigned long len, if (len > mm->task_size) return -ENOMEM; + if (len & ((1ul << pshift) - 1)) + return -EINVAL; if (fixed && (addr & ((1ul << pshift) - 1))) return -EINVAL; if (fixed && addr > (mm->task_size - len)) diff --git a/arch/powerpc/platforms/83xx/mpc832x_mds.c b/arch/powerpc/platforms/83xx/mpc832x_mds.c index b39cb52c6fb9..2c8e641a739b 100644 --- a/arch/powerpc/platforms/83xx/mpc832x_mds.c +++ b/arch/powerpc/platforms/83xx/mpc832x_mds.c @@ -106,7 +106,6 @@ static struct of_device_id mpc832x_ids[] = { { .type = "soc", }, { .compatible = "soc", }, { .type = "qe", }, - { .type = "mdio", }, {}, }; diff --git a/arch/powerpc/platforms/83xx/mpc832x_rdb.c b/arch/powerpc/platforms/83xx/mpc832x_rdb.c index b2b28a44738c..090906170a41 100644 --- a/arch/powerpc/platforms/83xx/mpc832x_rdb.c +++ b/arch/powerpc/platforms/83xx/mpc832x_rdb.c @@ -70,7 +70,6 @@ static struct of_device_id mpc832x_ids[] = { { .type = "soc", }, { .compatible = "soc", }, { .type = "qe", }, - { .type = "mdio", }, {}, }; diff --git a/arch/powerpc/platforms/83xx/mpc836x_mds.c b/arch/powerpc/platforms/83xx/mpc836x_mds.c index 0e615fd65c1f..84b58934aafd 100644 --- a/arch/powerpc/platforms/83xx/mpc836x_mds.c +++ b/arch/powerpc/platforms/83xx/mpc836x_mds.c @@ -113,7 +113,6 @@ static struct of_device_id mpc836x_ids[] = { { .type = "soc", }, { .compatible = "soc", }, { .type = "qe", }, - { .type = "mdio", }, {}, }; diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/powerpc/platforms/85xx/mpc85xx_mds.c index e8003bf00c9a..be25ecd911ba 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c @@ -142,7 +142,6 @@ static struct of_device_id mpc85xx_ids[] = { { .type = "soc", }, { .compatible = "soc", }, { .type = "qe", }, - { .type = "mdio", }, {}, }; diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c index 90124228b8f4..095a30304c56 100644 --- a/arch/powerpc/platforms/cell/spu_base.c +++ b/arch/powerpc/platforms/cell/spu_base.c @@ -36,7 +36,6 @@ #include <asm/spu_priv1.h> #include <asm/xmon.h> #include <asm/prom.h> -#include "spu_priv1_mmio.h" const struct spu_management_ops *spu_management_ops; EXPORT_SYMBOL_GPL(spu_management_ops); @@ -636,138 +635,6 @@ static ssize_t spu_stat_show(struct sys_device *sysdev, char *buf) static SYSDEV_ATTR(stat, 0644, spu_stat_show, NULL); -/* Hardcoded affinity idxs for QS20 */ -#define SPES_PER_BE 8 -static int QS20_reg_idxs[SPES_PER_BE] = { 0, 2, 4, 6, 7, 5, 3, 1 }; -static int QS20_reg_memory[SPES_PER_BE] = { 1, 1, 0, 0, 0, 0, 0, 0 }; - -static struct spu *spu_lookup_reg(int node, u32 reg) -{ - struct spu *spu; - - list_for_each_entry(spu, &cbe_spu_info[node].spus, cbe_list) { - if (*(u32 *)get_property(spu_devnode(spu), "reg", NULL) == reg) - return spu; - } - return NULL; -} - -static void init_aff_QS20_harcoded(void) -{ - int node, i; - struct spu *last_spu, *spu; - u32 reg; - - for (node = 0; node < MAX_NUMNODES; node++) { - last_spu = NULL; - for (i = 0; i < SPES_PER_BE; i++) { - reg = QS20_reg_idxs[i]; - spu = spu_lookup_reg(node, reg); - if (!spu) - continue; - spu->has_mem_affinity = QS20_reg_memory[reg]; - if (last_spu) - list_add_tail(&spu->aff_list, - &last_spu->aff_list); - last_spu = spu; - } - } -} - -static int of_has_vicinity(void) -{ - struct spu* spu; - - spu = list_entry(cbe_spu_info[0].spus.next, struct spu, cbe_list); - return of_find_property(spu_devnode(spu), "vicinity", NULL) != NULL; -} - -static struct spu *aff_devnode_spu(int cbe, struct device_node *dn) -{ - struct spu *spu; - - list_for_each_entry(spu, &cbe_spu_info[cbe].spus, cbe_list) - if (spu_devnode(spu) == dn) - return spu; - return NULL; -} - -static struct spu * -aff_node_next_to(int cbe, struct device_node *target, struct device_node *avoid) -{ - struct spu *spu; - const phandle *vic_handles; - int lenp, i; - - list_for_each_entry(spu, &cbe_spu_info[cbe].spus, cbe_list) { - if (spu_devnode(spu) == avoid) - continue; - vic_handles = get_property(spu_devnode(spu), "vicinity", &lenp); - for (i=0; i < (lenp / sizeof(phandle)); i++) { - if (vic_handles[i] == target->linux_phandle) - return spu; - } - } - return NULL; -} - -static void init_aff_fw_vicinity_node(int cbe) -{ - struct spu *spu, *last_spu; - struct device_node *vic_dn, *last_spu_dn; - phandle avoid_ph; - const phandle *vic_handles; - const char *name; - int lenp, i, added, mem_aff; - - last_spu = list_entry(cbe_spu_info[cbe].spus.next, struct spu, cbe_list); - avoid_ph = 0; - for (added = 1; added < cbe_spu_info[cbe].n_spus; added++) { - last_spu_dn = spu_devnode(last_spu); - vic_handles = get_property(last_spu_dn, "vicinity", &lenp); - - for (i = 0; i < (lenp / sizeof(phandle)); i++) { - if (vic_handles[i] == avoid_ph) - continue; - - vic_dn = of_find_node_by_phandle(vic_handles[i]); - if (!vic_dn) - continue; - - name = get_property(vic_dn, "name", NULL); - if (strcmp(name, "spe") == 0) { - spu = aff_devnode_spu(cbe, vic_dn); - avoid_ph = last_spu_dn->linux_phandle; - } - else { - mem_aff = strcmp(name, "mic-tm") == 0; - spu = aff_node_next_to(cbe, vic_dn, last_spu_dn); - if (!spu) - continue; - if (mem_aff) { - last_spu->has_mem_affinity = 1; - spu->has_mem_affinity = 1; - } - avoid_ph = vic_dn->linux_phandle; - } - list_add_tail(&spu->aff_list, &last_spu->aff_list); - last_spu = spu; - break; - } - } -} - -static void init_aff_fw_vicinity(void) -{ - int cbe; - - /* sets has_mem_affinity for each spu, as long as the - * spu->aff_list list, linking each spu to its neighbors - */ - for (cbe = 0; cbe < MAX_NUMNODES; cbe++) - init_aff_fw_vicinity_node(cbe); -} - static int __init init_spu_base(void) { int i, ret = 0; @@ -811,13 +678,7 @@ static int __init init_spu_base(void) mutex_unlock(&spu_full_list_mutex); spu_add_sysdev_attr(&attr_stat); - if (of_has_vicinity()) { - init_aff_fw_vicinity(); - } else { - long root = of_get_flat_dt_root(); - if (of_flat_dt_is_compatible(root, "IBM,CPBW-1.0")) - init_aff_QS20_harcoded(); - } + spu_init_affinity(); return 0; diff --git a/arch/powerpc/platforms/cell/spu_manage.c b/arch/powerpc/platforms/cell/spu_manage.c index 75ed50fcc3db..5eb88346181a 100644 --- a/arch/powerpc/platforms/cell/spu_manage.c +++ b/arch/powerpc/platforms/cell/spu_manage.c @@ -361,8 +361,171 @@ static int of_destroy_spu(struct spu *spu) return 0; } +/* Hardcoded affinity idxs for qs20 */ +#define QS20_SPES_PER_BE 8 +static int qs20_reg_idxs[QS20_SPES_PER_BE] = { 0, 2, 4, 6, 7, 5, 3, 1 }; +static int qs20_reg_memory[QS20_SPES_PER_BE] = { 1, 1, 0, 0, 0, 0, 0, 0 }; + +static struct spu *spu_lookup_reg(int node, u32 reg) +{ + struct spu *spu; + u32 *spu_reg; + + list_for_each_entry(spu, &cbe_spu_info[node].spus, cbe_list) { + spu_reg = (u32*)of_get_property(spu_devnode(spu), "reg", NULL); + if (*spu_reg == reg) + return spu; + } + return NULL; +} + +static void init_affinity_qs20_harcoded(void) +{ + int node, i; + struct spu *last_spu, *spu; + u32 reg; + + for (node = 0; node < MAX_NUMNODES; node++) { + last_spu = NULL; + for (i = 0; i < QS20_SPES_PER_BE; i++) { + reg = qs20_reg_idxs[i]; + spu = spu_lookup_reg(node, reg); + if (!spu) + continue; + spu->has_mem_affinity = qs20_reg_memory[reg]; + if (last_spu) + list_add_tail(&spu->aff_list, + &last_spu->aff_list); + last_spu = spu; + } + } +} + +static int of_has_vicinity(void) +{ + struct spu* spu; + + spu = list_first_entry(&cbe_spu_info[0].spus, struct spu, cbe_list); + return of_find_property(spu_devnode(spu), "vicinity", NULL) != NULL; +} + +static struct spu *devnode_spu(int cbe, struct device_node *dn) +{ + struct spu *spu; + + list_for_each_entry(spu, &cbe_spu_info[cbe].spus, cbe_list) + if (spu_devnode(spu) == dn) + return spu; + return NULL; +} + +static struct spu * +neighbour_spu(int cbe, struct device_node *target, struct device_node *avoid) +{ + struct spu *spu; + struct device_node *spu_dn; + const phandle *vic_handles; + int lenp, i; + + list_for_each_entry(spu, &cbe_spu_info[cbe].spus, cbe_list) { + spu_dn = spu_devnode(spu); + if (spu_dn == avoid) + continue; + vic_handles = of_get_property(spu_dn, "vicinity", &lenp); + for (i=0; i < (lenp / sizeof(phandle)); i++) { + if (vic_handles[i] == target->linux_phandle) + return spu; + } + } + return NULL; +} + +static void init_affinity_node(int cbe) +{ + struct spu *spu, *last_spu; + struct device_node *vic_dn, *last_spu_dn; + phandle avoid_ph; + const phandle *vic_handles; + const char *name; + int lenp, i, added; + + last_spu = list_first_entry(&cbe_spu_info[cbe].spus, struct spu, + cbe_list); + avoid_ph = 0; + for (added = 1; added < cbe_spu_info[cbe].n_spus; added++) { + last_spu_dn = spu_devnode(last_spu); + vic_handles = of_get_property(last_spu_dn, "vicinity", &lenp); + + /* + * Walk through each phandle in vicinity property of the spu + * (tipically two vicinity phandles per spe node) + */ + for (i = 0; i < (lenp / sizeof(phandle)); i++) { + if (vic_handles[i] == avoid_ph) + continue; + + vic_dn = of_find_node_by_phandle(vic_handles[i]); + if (!vic_dn) + continue; + + /* a neighbour might be spe, mic-tm, or bif0 */ + name = of_get_property(vic_dn, "name", NULL); + if (!name) + continue; + + if (strcmp(name, "spe") == 0) { + spu = devnode_spu(cbe, vic_dn); + avoid_ph = last_spu_dn->linux_phandle; + } else { + /* + * "mic-tm" and "bif0" nodes do not have + * vicinity property. So we need to find the + * spe which has vic_dn as neighbour, but + * skipping the one we came from (last_spu_dn) + */ + spu = neighbour_spu(cbe, vic_dn, last_spu_dn); + if (!spu) + continue; + if (!strcmp(name, "mic-tm")) { + last_spu->has_mem_affinity = 1; + spu->has_mem_affinity = 1; + } + avoid_ph = vic_dn->linux_phandle; + } + + list_add_tail(&spu->aff_list, &last_spu->aff_list); + last_spu = spu; + break; + } + } +} + +static void init_affinity_fw(void) +{ + int cbe; + + for (cbe = 0; cbe < MAX_NUMNODES; cbe++) + init_affinity_node(cbe); +} + +static int __init init_affinity(void) +{ + if (of_has_vicinity()) { + init_affinity_fw(); + } else { + long root = of_get_flat_dt_root(); + if (of_flat_dt_is_compatible(root, "IBM,CPBW-1.0")) + init_affinity_qs20_harcoded(); + else + printk("No affinity configuration found"); + } + + return 0; +} + const struct spu_management_ops spu_management_of_ops = { .enumerate_spus = of_enumerate_spus, .create_spu = of_create_spu, .destroy_spu = of_destroy_spu, + .init_affinity = init_affinity, }; diff --git a/arch/powerpc/platforms/ps3/Kconfig b/arch/powerpc/platforms/ps3/Kconfig index d4fc74f7bb15..67144d1d1405 100644 --- a/arch/powerpc/platforms/ps3/Kconfig +++ b/arch/powerpc/platforms/ps3/Kconfig @@ -1,5 +1,5 @@ config PPC_PS3 - bool "Sony PS3 (incomplete)" + bool "Sony PS3" depends on PPC_MULTIPLATFORM && PPC64 select PPC_CELL select USB_ARCH_HAS_OHCI @@ -10,10 +10,10 @@ config PPC_PS3 select MEMORY_HOTPLUG help This option enables support for the Sony PS3 game console - and other platforms using the PS3 hypervisor. - Support for this platform is not yet complete, so - enabling this will not result in a bootable kernel on a - PS3 system. + and other platforms using the PS3 hypervisor. Enabling this + option will allow building otheros.bld, a kernel image suitable + for programming into flash memory, and vmlinux, a kernel image + suitable for loading via kexec. menu "PS3 Platform Options" depends on PPC_PS3 diff --git a/arch/powerpc/platforms/ps3/device-init.c b/arch/powerpc/platforms/ps3/device-init.c index 825ebb2cbc2a..e23a5a874ad3 100644 --- a/arch/powerpc/platforms/ps3/device-init.c +++ b/arch/powerpc/platforms/ps3/device-init.c @@ -273,55 +273,58 @@ static int ps3stor_wait_for_completion(u64 dev_id, u64 tag, static int ps3_storage_wait_for_device(const struct ps3_repository_device *repo) { + int error = -ENODEV; int result; const u64 notification_dev_id = (u64)-1LL; const unsigned int timeout = HZ; u64 lpar; u64 tag; + void *buf; + enum ps3_notify_type { + notify_device_ready = 0, + notify_region_probe = 1, + notify_region_update = 2, + }; struct { u64 operation_code; /* must be zero */ - u64 event_mask; /* 1 = device ready */ + u64 event_mask; /* OR of 1UL << enum ps3_notify_type */ } *notify_cmd; struct { - u64 event_type; /* notify_device_ready */ + u64 event_type; /* enum ps3_notify_type */ u64 bus_id; u64 dev_id; u64 dev_type; u64 dev_port; } *notify_event; - enum { - notify_device_ready = 1 - }; pr_debug(" -> %s:%u: bus_id %u, dev_id %u, dev_type %u\n", __func__, __LINE__, repo->bus_id, repo->dev_id, repo->dev_type); - notify_cmd = kzalloc(512, GFP_KERNEL); - notify_event = (void *)notify_cmd; - if (!notify_cmd) + buf = kzalloc(512, GFP_KERNEL); + if (!buf) return -ENOMEM; - lpar = ps3_mm_phys_to_lpar(__pa(notify_cmd)); + lpar = ps3_mm_phys_to_lpar(__pa(buf)); + notify_cmd = buf; + notify_event = buf; result = lv1_open_device(repo->bus_id, notification_dev_id, 0); if (result) { printk(KERN_ERR "%s:%u: lv1_open_device %s\n", __func__, __LINE__, ps3_result(result)); - result = -ENODEV; goto fail_free; } /* Setup and write the request for device notification. */ - notify_cmd->operation_code = 0; /* must be zero */ - notify_cmd->event_mask = 0x01; /* device ready */ + notify_cmd->operation_code = 0; /* must be zero */ + notify_cmd->event_mask = 1UL << notify_region_probe; result = lv1_storage_write(notification_dev_id, 0, 0, 1, 0, lpar, &tag); if (result) { printk(KERN_ERR "%s:%u: write failed %s\n", __func__, __LINE__, ps3_result(result)); - result = -ENODEV; goto fail_close; } @@ -332,13 +335,11 @@ static int ps3_storage_wait_for_device(const struct ps3_repository_device *repo) if (result) { printk(KERN_ERR "%s:%u: write not completed %s\n", __func__, __LINE__, ps3_result(result)); - result = -ENODEV; goto fail_close; } /* Loop here processing the requested notification events. */ - result = -ENODEV; while (1) { memset(notify_event, 0, sizeof(*notify_event)); @@ -358,7 +359,7 @@ static int ps3_storage_wait_for_device(const struct ps3_repository_device *repo) break; } - if (notify_event->event_type != notify_device_ready || + if (notify_event->event_type != notify_region_probe || notify_event->bus_id != repo->bus_id) { pr_debug("%s:%u: bad notify_event: event %lu, " "dev_id %lu, dev_type %lu\n", @@ -386,9 +387,9 @@ static int ps3_storage_wait_for_device(const struct ps3_repository_device *repo) fail_close: lv1_close_device(repo->bus_id, notification_dev_id); fail_free: - kfree(notify_cmd); + kfree(buf); pr_debug(" <- %s:%u\n", __func__, __LINE__); - return result; + return error; } static int ps3_setup_storage_dev(const struct ps3_repository_device *repo, diff --git a/arch/powerpc/platforms/ps3/spu.c b/arch/powerpc/platforms/ps3/spu.c index 502d80ed982b..ac2a4b8a4c14 100644 --- a/arch/powerpc/platforms/ps3/spu.c +++ b/arch/powerpc/platforms/ps3/spu.c @@ -414,10 +414,16 @@ static int __init ps3_enumerate_spus(int (*fn)(void *data)) return num_resource_id; } +static int ps3_init_affinity(void) +{ + return 0; +} + const struct spu_management_ops spu_management_ps3_ops = { .enumerate_spus = ps3_enumerate_spus, .create_spu = ps3_create_spu, .destroy_spu = ps3_destroy_spu, + .init_affinity = ps3_init_affinity, }; /* spu_priv1_ops */ diff --git a/arch/x86_64/boot/compressed/head.S b/arch/x86_64/boot/compressed/head.S index 1312bfaff306..9fd8030cc54f 100644 --- a/arch/x86_64/boot/compressed/head.S +++ b/arch/x86_64/boot/compressed/head.S @@ -195,6 +195,11 @@ ENTRY(startup_64) movl %eax, %ds movl %eax, %es movl %eax, %ss + movl %eax, %fs + movl %eax, %gs + lldt %ax + movl $0x20, %eax + ltr %ax /* Compute the decompressed kernel start address. It is where * we were loaded at aligned to a 2M boundary. %rbp contains the @@ -295,6 +300,8 @@ gdt: .quad 0x0000000000000000 /* NULL descriptor */ .quad 0x00af9a000000ffff /* __KERNEL_CS */ .quad 0x00cf92000000ffff /* __KERNEL_DS */ + .quad 0x0080890000000000 /* TS descriptor */ + .quad 0x0000000000000000 /* TS continued */ gdt_end: .bss /* Stack for uncompression */ diff --git a/arch/x86_64/kernel/apic.c b/arch/x86_64/kernel/apic.c index 900ff38d68de..925758dbca0c 100644 --- a/arch/x86_64/kernel/apic.c +++ b/arch/x86_64/kernel/apic.c @@ -791,10 +791,8 @@ static void setup_APIC_timer(unsigned int clocks) /* wait for irq slice */ if (hpet_address && hpet_use_timer) { - int trigger = hpet_readl(HPET_T0_CMP); - while (hpet_readl(HPET_COUNTER) >= trigger) - /* do nothing */ ; - while (hpet_readl(HPET_COUNTER) < trigger) + u32 trigger = hpet_readl(HPET_T0_CMP); + while (hpet_readl(HPET_T0_CMP) == trigger) /* do nothing */ ; } else { int c1, c2; diff --git a/arch/x86_64/kernel/pci-calgary.c b/arch/x86_64/kernel/pci-calgary.c index ba16c968ca3f..71da01e73f03 100644 --- a/arch/x86_64/kernel/pci-calgary.c +++ b/arch/x86_64/kernel/pci-calgary.c @@ -367,16 +367,15 @@ static inline struct iommu_table *find_iommu_table(struct device *dev) pdev = to_pci_dev(dev); - /* is the device behind a bridge? */ - if (unlikely(pdev->bus->parent)) - pbus = pdev->bus->parent; - else - pbus = pdev->bus; + pbus = pdev->bus; + + /* is the device behind a bridge? Look for the root bus */ + while (pbus->parent) + pbus = pbus->parent; tbl = pci_iommu(pbus); - BUG_ON(pdev->bus->parent && - (tbl->it_busno != pdev->bus->parent->number)); + BUG_ON(tbl && (tbl->it_busno != pbus->number)); return tbl; } diff --git a/arch/x86_64/mm/pageattr.c b/arch/x86_64/mm/pageattr.c index 7e161c698af4..10b9809ce821 100644 --- a/arch/x86_64/mm/pageattr.c +++ b/arch/x86_64/mm/pageattr.c @@ -75,7 +75,8 @@ static void flush_kernel_map(void *arg) /* When clflush is available always use it because it is much cheaper than WBINVD. */ - if (!cpu_has_clflush) + /* clflush is still broken. Disable for now. */ + if (1 || !cpu_has_clflush) asm volatile("wbinvd" ::: "memory"); else list_for_each_entry(pg, l, lru) { void *adr = page_address(pg); diff --git a/arch/x86_64/pci/mmconfig.c b/arch/x86_64/pci/mmconfig.c index 65d82736987e..4095e4d66a1d 100644 --- a/arch/x86_64/pci/mmconfig.c +++ b/arch/x86_64/pci/mmconfig.c @@ -66,13 +66,13 @@ static int pci_mmcfg_read(unsigned int seg, unsigned int bus, switch (len) { case 1: - *value = readb(addr + reg); + *value = mmio_config_readb(addr + reg); break; case 2: - *value = readw(addr + reg); + *value = mmio_config_readw(addr + reg); break; case 4: - *value = readl(addr + reg); + *value = mmio_config_readl(addr + reg); break; } @@ -94,13 +94,13 @@ static int pci_mmcfg_write(unsigned int seg, unsigned int bus, switch (len) { case 1: - writeb(value, addr + reg); + mmio_config_writeb(addr + reg, value); break; case 2: - writew(value, addr + reg); + mmio_config_writew(addr + reg, value); break; case 4: - writel(value, addr + reg); + mmio_config_writel(addr + reg, value); break; } diff --git a/arch/x86_64/vdso/.gitignore b/arch/x86_64/vdso/.gitignore new file mode 100644 index 000000000000..f8b69d84238e --- /dev/null +++ b/arch/x86_64/vdso/.gitignore @@ -0,0 +1 @@ +vdso.lds diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c index 8c2caff87cc3..a15845c164f2 100644 --- a/block/ll_rw_blk.c +++ b/block/ll_rw_blk.c @@ -3047,6 +3047,10 @@ static inline void blk_partition_remap(struct bio *bio) bio->bi_sector += p->start_sect; bio->bi_bdev = bdev->bd_contains; + + blk_add_trace_remap(bdev_get_queue(bio->bi_bdev), bio, + bdev->bd_dev, bio->bi_sector, + bio->bi_sector - p->start_sect); } } diff --git a/drivers/acpi/resources/rsxface.c b/drivers/acpi/resources/rsxface.c index f63813a358c5..4c3fd4cdaf73 100644 --- a/drivers/acpi/resources/rsxface.c +++ b/drivers/acpi/resources/rsxface.c @@ -474,8 +474,6 @@ acpi_rs_match_vendor_resource(struct acpi_resource *resource, void *context) return (AE_CTRL_TERMINATE); } -ACPI_EXPORT_SYMBOL(acpi_rs_match_vendor_resource) - /******************************************************************************* * * FUNCTION: acpi_walk_resources diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index a11b2bd54bbe..084358a828e9 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -1977,12 +1977,13 @@ cciss_read_capacity(int ctlr, int logvol, int withirq, sector_t *total_size, { ReadCapdata_struct *buf; int return_code; - buf = kmalloc(sizeof(ReadCapdata_struct), GFP_KERNEL); - if (buf == NULL) { + + buf = kzalloc(sizeof(ReadCapdata_struct), GFP_KERNEL); + if (!buf) { printk(KERN_WARNING "cciss: out of memory\n"); return; } - memset(buf, 0, sizeof(ReadCapdata_struct)); + if (withirq) return_code = sendcmd_withirq(CCISS_READ_CAPACITY, ctlr, buf, sizeof(ReadCapdata_struct), @@ -2003,7 +2004,6 @@ cciss_read_capacity(int ctlr, int logvol, int withirq, sector_t *total_size, printk(KERN_INFO " blocks= %llu block_size= %d\n", (unsigned long long)*total_size+1, *block_size); kfree(buf); - return; } static void @@ -2011,12 +2011,13 @@ cciss_read_capacity_16(int ctlr, int logvol, int withirq, sector_t *total_size, { ReadCapdata_struct_16 *buf; int return_code; - buf = kmalloc(sizeof(ReadCapdata_struct_16), GFP_KERNEL); - if (buf == NULL) { + + buf = kzalloc(sizeof(ReadCapdata_struct_16), GFP_KERNEL); + if (!buf) { printk(KERN_WARNING "cciss: out of memory\n"); return; } - memset(buf, 0, sizeof(ReadCapdata_struct_16)); + if (withirq) { return_code = sendcmd_withirq(CCISS_READ_CAPACITY_16, ctlr, buf, sizeof(ReadCapdata_struct_16), @@ -2038,7 +2039,6 @@ cciss_read_capacity_16(int ctlr, int logvol, int withirq, sector_t *total_size, printk(KERN_INFO " blocks= %llu block_size= %d\n", (unsigned long long)*total_size+1, *block_size); kfree(buf); - return; } static int cciss_revalidate(struct gendisk *disk) diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c index be4e3477d83b..eb9799acf65b 100644 --- a/drivers/block/cpqarray.c +++ b/drivers/block/cpqarray.c @@ -420,18 +420,17 @@ static int __init cpqarray_register_ctlr( int i, struct pci_dev *pdev) goto Enomem2; } - hba[i]->cmd_pool = (cmdlist_t *)pci_alloc_consistent( + hba[i]->cmd_pool = pci_alloc_consistent( hba[i]->pci_dev, NR_CMDS * sizeof(cmdlist_t), &(hba[i]->cmd_pool_dhandle)); - hba[i]->cmd_pool_bits = kmalloc( - ((NR_CMDS+BITS_PER_LONG-1)/BITS_PER_LONG)*sizeof(unsigned long), + hba[i]->cmd_pool_bits = kcalloc( + (NR_CMDS+BITS_PER_LONG-1)/BITS_PER_LONG, sizeof(unsigned long), GFP_KERNEL); if (!hba[i]->cmd_pool_bits || !hba[i]->cmd_pool) goto Enomem1; memset(hba[i]->cmd_pool, 0, NR_CMDS * sizeof(cmdlist_t)); - memset(hba[i]->cmd_pool_bits, 0, ((NR_CMDS+BITS_PER_LONG-1)/BITS_PER_LONG)*sizeof(unsigned long)); printk(KERN_INFO "cpqarray: Finding drives on %s", hba[i]->devname); @@ -1660,45 +1659,30 @@ static void getgeometry(int ctlr) info_p->log_drv_map = 0; - id_ldrive = kmalloc(sizeof(id_log_drv_t), GFP_KERNEL); - if(id_ldrive == NULL) - { + id_ldrive = kzalloc(sizeof(id_log_drv_t), GFP_KERNEL); + if (!id_ldrive) { printk( KERN_ERR "cpqarray: out of memory.\n"); - return; + goto err_0; } - id_ctlr_buf = kmalloc(sizeof(id_ctlr_t), GFP_KERNEL); - if(id_ctlr_buf == NULL) - { - kfree(id_ldrive); + id_ctlr_buf = kzalloc(sizeof(id_ctlr_t), GFP_KERNEL); + if (!id_ctlr_buf) { printk( KERN_ERR "cpqarray: out of memory.\n"); - return; + goto err_1; } - id_lstatus_buf = kmalloc(sizeof(sense_log_drv_stat_t), GFP_KERNEL); - if(id_lstatus_buf == NULL) - { - kfree(id_ctlr_buf); - kfree(id_ldrive); + id_lstatus_buf = kzalloc(sizeof(sense_log_drv_stat_t), GFP_KERNEL); + if (!id_lstatus_buf) { printk( KERN_ERR "cpqarray: out of memory.\n"); - return; + goto err_2; } - sense_config_buf = kmalloc(sizeof(config_t), GFP_KERNEL); - if(sense_config_buf == NULL) - { - kfree(id_lstatus_buf); - kfree(id_ctlr_buf); - kfree(id_ldrive); + sense_config_buf = kzalloc(sizeof(config_t), GFP_KERNEL); + if (!sense_config_buf) { printk( KERN_ERR "cpqarray: out of memory.\n"); - return; + goto err_3; } - memset(id_ldrive, 0, sizeof(id_log_drv_t)); - memset(id_ctlr_buf, 0, sizeof(id_ctlr_t)); - memset(id_lstatus_buf, 0, sizeof(sense_log_drv_stat_t)); - memset(sense_config_buf, 0, sizeof(config_t)); - info_p->phys_drives = 0; info_p->log_drv_map = 0; info_p->drv_assign_map = 0; @@ -1712,13 +1696,8 @@ static void getgeometry(int ctlr) * so the idastubopen will fail on all logical drives * on the controller. */ - /* Free all the buffers and return */ printk(KERN_ERR "cpqarray: error sending ID controller\n"); - kfree(sense_config_buf); - kfree(id_lstatus_buf); - kfree(id_ctlr_buf); - kfree(id_ldrive); - return; + goto err_4; } info_p->log_drives = id_ctlr_buf->nr_drvs; @@ -1764,12 +1743,7 @@ static void getgeometry(int ctlr) " failed to report status of logical drive %d\n" "Access to this controller has been disabled\n", ctlr, log_unit); - /* Free all the buffers and return */ - kfree(sense_config_buf); - kfree(id_lstatus_buf); - kfree(id_ctlr_buf); - kfree(id_ldrive); - return; + goto err_4; } /* Make sure the logical drive is configured @@ -1798,14 +1772,8 @@ static void getgeometry(int ctlr) sizeof(config_t), 0, 0, log_unit); if (ret_code == IO_ERROR) { info_p->log_drv_map = 0; - /* Free all the buffers and return */ printk(KERN_ERR "cpqarray: error sending sense config\n"); - kfree(sense_config_buf); - kfree(id_lstatus_buf); - kfree(id_ctlr_buf); - kfree(id_ldrive); - return; - + goto err_4; } info_p->phys_drives = @@ -1820,12 +1788,18 @@ static void getgeometry(int ctlr) log_index = log_index + 1; } /* end of if logical drive configured */ } /* end of for log_unit */ + + /* Free all the buffers and return */ +err_4: kfree(sense_config_buf); - kfree(id_ldrive); +err_3: kfree(id_lstatus_buf); +err_2: kfree(id_ctlr_buf); +err_1: + kfree(id_ldrive); +err_0: return; - } static void __exit cpqarray_exit(void) diff --git a/drivers/block/viodasd.c b/drivers/block/viodasd.c index 85916e2665d4..af3969a9c963 100644 --- a/drivers/block/viodasd.c +++ b/drivers/block/viodasd.c @@ -41,7 +41,6 @@ #include <linux/dma-mapping.h> #include <linux/completion.h> #include <linux/device.h> -#include <linux/kernel.h> #include <asm/uaccess.h> #include <asm/vio.h> diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c index cb27e8863d7c..3ede0b63da13 100644 --- a/drivers/block/xsysace.c +++ b/drivers/block/xsysace.c @@ -902,26 +902,17 @@ static int ace_release(struct inode *inode, struct file *filp) return 0; } -static int ace_ioctl(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) +static int ace_getgeo(struct block_device *bdev, struct hd_geometry *geo) { - struct ace_device *ace = inode->i_bdev->bd_disk->private_data; - struct hd_geometry __user *geo = (struct hd_geometry __user *)arg; - struct hd_geometry g; - dev_dbg(ace->dev, "ace_ioctl()\n"); - - switch (cmd) { - case HDIO_GETGEO: - g.heads = ace->cf_id.heads; - g.sectors = ace->cf_id.sectors; - g.cylinders = ace->cf_id.cyls; - g.start = 0; - return copy_to_user(geo, &g, sizeof(g)) ? -EFAULT : 0; + struct ace_device *ace = bdev->bd_disk->private_data; - default: - return -ENOTTY; - } - return -ENOTTY; + dev_dbg(ace->dev, "ace_getgeo()\n"); + + geo->heads = ace->cf_id.heads; + geo->sectors = ace->cf_id.sectors; + geo->cylinders = ace->cf_id.cyls; + + return 0; } static struct block_device_operations ace_fops = { @@ -930,7 +921,7 @@ static struct block_device_operations ace_fops = { .release = ace_release, .media_changed = ace_media_changed, .revalidate_disk = ace_revalidate_disk, - .ioctl = ace_ioctl, + .getgeo = ace_getgeo, }; /* -------------------------------------------------------------------- diff --git a/drivers/char/hvc_lguest.c b/drivers/char/hvc_lguest.c index feeccbaec438..3d6bd0baa56d 100644 --- a/drivers/char/hvc_lguest.c +++ b/drivers/char/hvc_lguest.c @@ -35,6 +35,7 @@ #include <linux/err.h> #include <linux/init.h> #include <linux/lguest_bus.h> +#include <asm/paravirt.h> #include "hvc_console.h" /*D:340 This is our single console input buffer, with associated "struct diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c index fee58e03dbe2..4177f6db83e9 100644 --- a/drivers/char/pcmcia/cm4000_cs.c +++ b/drivers/char/pcmcia/cm4000_cs.c @@ -1629,7 +1629,7 @@ static int cmm_open(struct inode *inode, struct file *filp) { struct cm4000_dev *dev; struct pcmcia_device *link; - int rc, minor = iminor(inode); + int minor = iminor(inode); if (minor >= CM4000_MAX_DEV) return -ENODEV; @@ -1668,7 +1668,6 @@ static int cmm_open(struct inode *inode, struct file *filp) start_monitor(dev); link->open = 1; /* only one open per device */ - rc = 0; DEBUGP(2, dev, "<- cmm_open\n"); return nonseekable_open(inode, filp); @@ -1824,7 +1823,7 @@ static int cm4000_resume(struct pcmcia_device *link) static void cm4000_release(struct pcmcia_device *link) { - cmm_cm4000_release(link->priv); /* delay release until device closed */ + cmm_cm4000_release(link); /* delay release until device closed */ pcmcia_disable_device(link); } diff --git a/drivers/char/pcmcia/cm4040_cs.c b/drivers/char/pcmcia/cm4040_cs.c index af88181a17f4..b24a3e7bbb9f 100644 --- a/drivers/char/pcmcia/cm4040_cs.c +++ b/drivers/char/pcmcia/cm4040_cs.c @@ -599,7 +599,7 @@ cs_release: static void reader_release(struct pcmcia_device *link) { - cm4040_reader_release(link->priv); + cm4040_reader_release(link); pcmcia_disable_device(link); } diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index de37ebc3a4cf..51ea93cab6c4 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c @@ -369,25 +369,54 @@ static void tty_buffer_free(struct tty_struct *tty, struct tty_buffer *b) } /** - * tty_buffer_flush - flush full tty buffers + * __tty_buffer_flush - flush full tty buffers * @tty: tty to flush * - * flush all the buffers containing receive data + * flush all the buffers containing receive data. Caller must + * hold the buffer lock and must have ensured no parallel flush to + * ldisc is running. * - * Locking: none + * Locking: Caller must hold tty->buf.lock */ -static void tty_buffer_flush(struct tty_struct *tty) +static void __tty_buffer_flush(struct tty_struct *tty) { struct tty_buffer *thead; - unsigned long flags; - spin_lock_irqsave(&tty->buf.lock, flags); while((thead = tty->buf.head) != NULL) { tty->buf.head = thead->next; tty_buffer_free(tty, thead); } tty->buf.tail = NULL; +} + +/** + * tty_buffer_flush - flush full tty buffers + * @tty: tty to flush + * + * flush all the buffers containing receive data. If the buffer is + * being processed by flush_to_ldisc then we defer the processing + * to that function + * + * Locking: none + */ + +static void tty_buffer_flush(struct tty_struct *tty) +{ + unsigned long flags; + spin_lock_irqsave(&tty->buf.lock, flags); + + /* If the data is being pushed to the tty layer then we can't + process it here. Instead set a flag and the flush_to_ldisc + path will process the flush request before it exits */ + if (test_bit(TTY_FLUSHING, &tty->flags)) { + set_bit(TTY_FLUSHPENDING, &tty->flags); + spin_unlock_irqrestore(&tty->buf.lock, flags); + wait_event(tty->read_wait, + test_bit(TTY_FLUSHPENDING, &tty->flags) == 0); + return; + } else + __tty_buffer_flush(tty); spin_unlock_irqrestore(&tty->buf.lock, flags); } @@ -3594,6 +3623,7 @@ static void flush_to_ldisc(struct work_struct *work) return; spin_lock_irqsave(&tty->buf.lock, flags); + set_bit(TTY_FLUSHING, &tty->flags); /* So we know a flush is running */ head = tty->buf.head; if (head != NULL) { tty->buf.head = NULL; @@ -3607,6 +3637,11 @@ static void flush_to_ldisc(struct work_struct *work) tty_buffer_free(tty, tbuf); continue; } + /* Ldisc or user is trying to flush the buffers + we are feeding to the ldisc, stop feeding the + line discipline as we want to empty the queue */ + if (test_bit(TTY_FLUSHPENDING, &tty->flags)) + break; if (!tty->receive_room) { schedule_delayed_work(&tty->buf.work, 1); break; @@ -3620,8 +3655,17 @@ static void flush_to_ldisc(struct work_struct *work) disc->receive_buf(tty, char_buf, flag_buf, count); spin_lock_irqsave(&tty->buf.lock, flags); } + /* Restore the queue head */ tty->buf.head = head; } + /* We may have a deferred request to flush the input buffer, + if so pull the chain under the lock and empty the queue */ + if (test_bit(TTY_FLUSHPENDING, &tty->flags)) { + __tty_buffer_flush(tty); + clear_bit(TTY_FLUSHPENDING, &tty->flags); + wake_up(&tty->read_wait); + } + clear_bit(TTY_FLUSHING, &tty->flags); spin_unlock_irqrestore(&tty->buf.lock, flags); tty_ldisc_deref(disc); diff --git a/drivers/lguest/lguest.c b/drivers/lguest/lguest.c index 524beea7fb19..6e135ac0834f 100644 --- a/drivers/lguest/lguest.c +++ b/drivers/lguest/lguest.c @@ -936,23 +936,24 @@ static const struct lguest_insns /* Now our patch routine is fairly simple (based on the native one in * paravirt.c). If we have a replacement, we copy it in and return how much of * the available space we used. */ -static unsigned lguest_patch(u8 type, u16 clobber, void *insns, unsigned len) +static unsigned lguest_patch(u8 type, u16 clobber, void *ibuf, + unsigned long addr, unsigned len) { unsigned int insn_len; /* Don't do anything special if we don't have a replacement */ if (type >= ARRAY_SIZE(lguest_insns) || !lguest_insns[type].start) - return paravirt_patch_default(type, clobber, insns, len); + return paravirt_patch_default(type, clobber, ibuf, addr, len); insn_len = lguest_insns[type].end - lguest_insns[type].start; /* Similarly if we can't fit replacement (shouldn't happen, but let's * be thorough). */ if (len < insn_len) - return paravirt_patch_default(type, clobber, insns, len); + return paravirt_patch_default(type, clobber, ibuf, addr, len); /* Copy in our instructions. */ - memcpy(insns, lguest_insns[type].start, insn_len); + memcpy(ibuf, lguest_insns[type].start, insn_len); return insn_len; } diff --git a/drivers/lguest/lguest_bus.c b/drivers/lguest/lguest_bus.c index 55a7940ca732..9e7752cc8002 100644 --- a/drivers/lguest/lguest_bus.c +++ b/drivers/lguest/lguest_bus.c @@ -5,6 +5,7 @@ #include <linux/bootmem.h> #include <linux/lguest_bus.h> #include <asm/io.h> +#include <asm/paravirt.h> static ssize_t type_show(struct device *_dev, struct device_attribute *attr, char *buf) diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 141ff9fa296e..2120155929a6 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -580,8 +580,8 @@ static void __map_bio(struct dm_target *ti, struct bio *clone, /* the bio has been remapped so dispatch it */ blk_add_trace_remap(bdev_get_queue(clone->bi_bdev), clone, - tio->io->bio->bi_bdev->bd_dev, sector, - clone->bi_sector); + tio->io->bio->bi_bdev->bd_dev, + clone->bi_sector, sector); generic_make_request(clone); } else if (r < 0 || r == DM_MAPIO_REQUEUE) { diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c index 8c86b802f212..d091b2430b48 100644 --- a/drivers/mtd/mtdchar.c +++ b/drivers/mtd/mtdchar.c @@ -7,6 +7,7 @@ #include <linux/device.h> #include <linux/fs.h> +#include <linux/mm.h> #include <linux/err.h> #include <linux/init.h> #include <linux/kernel.h> diff --git a/drivers/spi/spi_mpc83xx.c b/drivers/spi/spi_mpc83xx.c index 0c16a2b39b41..2adf856e44c2 100644 --- a/drivers/spi/spi_mpc83xx.c +++ b/drivers/spi/spi_mpc83xx.c @@ -86,7 +86,7 @@ struct mpc83xx_spi { unsigned nsecs; /* (clock cycle time)/2 */ - u32 sysclk; + u32 spibrg; /* SPIBRG input clock */ u32 rx_shift; /* RX data reg shift when in qe mode */ u32 tx_shift; /* TX data reg shift when in qe mode */ @@ -148,6 +148,8 @@ static void mpc83xx_spi_chipselect(struct spi_device *spi, int value) if (value == BITBANG_CS_ACTIVE) { u32 regval = mpc83xx_spi_read_reg(&mpc83xx_spi->base->mode); u32 len = spi->bits_per_word; + u8 pm; + if (len == 32) len = 0; else @@ -169,17 +171,20 @@ static void mpc83xx_spi_chipselect(struct spi_device *spi, int value) regval |= SPMODE_LEN(len); - if ((mpc83xx_spi->sysclk / spi->max_speed_hz) >= 64) { - u8 pm = mpc83xx_spi->sysclk / (spi->max_speed_hz * 64); + if ((mpc83xx_spi->spibrg / spi->max_speed_hz) >= 64) { + pm = mpc83xx_spi->spibrg / (spi->max_speed_hz * 64) - 1; if (pm > 0x0f) { - printk(KERN_WARNING "MPC83xx SPI: SPICLK can't be less then a SYSCLK/1024!\n" - "Requested SPICLK is %d Hz. Will use %d Hz instead.\n", - spi->max_speed_hz, mpc83xx_spi->sysclk / 1024); + dev_err(&spi->dev, "Requested speed is too " + "low: %d Hz. Will use %d Hz instead.\n", + spi->max_speed_hz, + mpc83xx_spi->spibrg / 1024); pm = 0x0f; } regval |= SPMODE_PM(pm) | SPMODE_DIV16; } else { - u8 pm = mpc83xx_spi->sysclk / (spi->max_speed_hz * 4); + pm = mpc83xx_spi->spibrg / (spi->max_speed_hz * 4); + if (pm) + pm--; regval |= SPMODE_PM(pm); } @@ -429,13 +434,17 @@ static int __init mpc83xx_spi_probe(struct platform_device *dev) mpc83xx_spi->bitbang.chipselect = mpc83xx_spi_chipselect; mpc83xx_spi->bitbang.setup_transfer = mpc83xx_spi_setup_transfer; mpc83xx_spi->bitbang.txrx_bufs = mpc83xx_spi_bufs; - mpc83xx_spi->sysclk = pdata->sysclk; mpc83xx_spi->activate_cs = pdata->activate_cs; mpc83xx_spi->deactivate_cs = pdata->deactivate_cs; mpc83xx_spi->qe_mode = pdata->qe_mode; mpc83xx_spi->get_rx = mpc83xx_spi_rx_buf_u8; mpc83xx_spi->get_tx = mpc83xx_spi_tx_buf_u8; + if (mpc83xx_spi->qe_mode) + mpc83xx_spi->spibrg = pdata->sysclk / 2; + else + mpc83xx_spi->spibrg = pdata->sysclk; + mpc83xx_spi->rx_shift = 0; mpc83xx_spi->tx_shift = 0; if (mpc83xx_spi->qe_mode) { diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c index 630f781aeb19..c55459c592b8 100644 --- a/drivers/spi/spidev.c +++ b/drivers/spi/spidev.c @@ -183,7 +183,9 @@ static int spidev_message(struct spidev_data *spidev, if (u_tmp->rx_buf) { k_tmp->rx_buf = buf; - if (!access_ok(VERIFY_WRITE, u_tmp->rx_buf, u_tmp->len)) + if (!access_ok(VERIFY_WRITE, (u8 __user *) + (ptrdiff_t) u_tmp->rx_buf, + u_tmp->len)) goto done; } if (u_tmp->tx_buf) { diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index decfdc8eb9cc..e58c87b3e3a0 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c @@ -127,8 +127,20 @@ static int last_fb_vc = MAX_NR_CONSOLES - 1; static int fbcon_is_default = 1; static int fbcon_has_exited; static int primary_device = -1; + +#ifdef CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY static int map_override; +static inline void fbcon_map_override(void) +{ + map_override = 1; +} +#else +static inline void fbcon_map_override(void) +{ +} +#endif /* CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY */ + /* font data */ static char fontname[40]; @@ -506,7 +518,7 @@ static int __init fb_console_setup(char *this_opt) (options[j++]-'0') % FB_MAX; } - map_override = 1; + fbcon_map_override(); } return 1; diff --git a/drivers/video/matrox/g450_pll.c b/drivers/video/matrox/g450_pll.c index 7c76e079ca7d..d42346e7fdda 100644 --- a/drivers/video/matrox/g450_pll.c +++ b/drivers/video/matrox/g450_pll.c @@ -331,16 +331,19 @@ static int __g450_setclk(WPMINFO unsigned int fout, unsigned int pll, tmp |= M1064_XPIXCLKCTRL_PLL_UP; } matroxfb_DAC_out(PMINFO M1064_XPIXCLKCTRL, tmp); -#ifdef __powerpc__ - /* This is necessary to avoid jitter on PowerPC - * (OpenFirmware) systems, but apparently - * introduces jitter, at least on a x86-64 - * using DVI. - * A simple workaround is disable for non-PPC. - */ - matroxfb_DAC_out(PMINFO M1064_XDVICLKCTRL, 0); -#endif /* __powerpc__ */ - matroxfb_DAC_out(PMINFO M1064_XPWRCTRL, xpwrctrl); + /* DVI PLL preferred for frequencies up to + panel link max, standard PLL otherwise */ + if (fout >= MINFO->max_pixel_clock_panellink) + tmp = 0; + else tmp = + M1064_XDVICLKCTRL_DVIDATAPATHSEL | + M1064_XDVICLKCTRL_C1DVICLKSEL | + M1064_XDVICLKCTRL_C1DVICLKEN | + M1064_XDVICLKCTRL_DVILOOPCTL | + M1064_XDVICLKCTRL_P1LOOPBWDTCTL; + matroxfb_DAC_out(PMINFO M1064_XDVICLKCTRL,tmp); + matroxfb_DAC_out(PMINFO M1064_XPWRCTRL, + xpwrctrl); matroxfb_DAC_unlock_irqrestore(flags); } diff --git a/drivers/video/matrox/matroxfb_DAC1064.h b/drivers/video/matrox/matroxfb_DAC1064.h index df39c3193735..7a98ce8043d7 100644 --- a/drivers/video/matrox/matroxfb_DAC1064.h +++ b/drivers/video/matrox/matroxfb_DAC1064.h @@ -33,6 +33,21 @@ void DAC1064_global_restore(WPMINFO2); #define M1064_XCURCTRL_3COLOR 0x01 /* transparent, 0, 1, 2 */ #define M1064_XCURCTRL_XGA 0x02 /* 0, 1, transparent, complement */ #define M1064_XCURCTRL_XWIN 0x03 /* transparent, transparent, 0, 1 */ + /* drive DVI by standard(0)/DVI(1) PLL */ + /* if set(1), C?DVICLKEN and C?DVICLKSEL must be set(1) */ +#define M1064_XDVICLKCTRL_DVIDATAPATHSEL 0x01 + /* drive CRTC1 by standard(0)/DVI(1) PLL */ +#define M1064_XDVICLKCTRL_C1DVICLKSEL 0x02 + /* drive CRTC2 by standard(0)/DVI(1) PLL */ +#define M1064_XDVICLKCTRL_C2DVICLKSEL 0x04 + /* pixel clock allowed to(0)/blocked from(1) driving CRTC1 */ +#define M1064_XDVICLKCTRL_C1DVICLKEN 0x08 + /* DVI PLL loop filter bandwidth selection bits */ +#define M1064_XDVICLKCTRL_DVILOOPCTL 0x30 + /* CRTC2 pixel clock allowed to(0)/blocked from(1) driving CRTC2 */ +#define M1064_XDVICLKCTRL_C2DVICLKEN 0x40 + /* P1PLL loop filter bandwith selection */ +#define M1064_XDVICLKCTRL_P1LOOPBWDTCTL 0x80 #define M1064_XCURCOL0RED 0x08 #define M1064_XCURCOL0GREEN 0x09 #define M1064_XCURCOL0BLUE 0x0A diff --git a/drivers/video/matrox/matroxfb_base.h b/drivers/video/matrox/matroxfb_base.h index d59577c8de86..f3107ad7e545 100644 --- a/drivers/video/matrox/matroxfb_base.h +++ b/drivers/video/matrox/matroxfb_base.h @@ -424,6 +424,7 @@ struct matrox_fb_info { } mmio; unsigned int max_pixel_clock; + unsigned int max_pixel_clock_panellink; struct matrox_switch* hw_switch; diff --git a/drivers/video/matrox/matroxfb_misc.c b/drivers/video/matrox/matroxfb_misc.c index 5948e54b9ef9..ab7fb50bc1de 100644 --- a/drivers/video/matrox/matroxfb_misc.c +++ b/drivers/video/matrox/matroxfb_misc.c @@ -658,6 +658,7 @@ static int parse_pins5(WPMINFO const struct matrox_bios* bd) { MINFO->values.reg.mctlwtst_core = (MINFO->values.reg.mctlwtst & ~7) | wtst_xlat[MINFO->values.reg.mctlwtst & 7]; } + MINFO->max_pixel_clock_panellink = bd->pins[47] * 4000; return 0; } diff --git a/drivers/video/pvr2fb.c b/drivers/video/pvr2fb.c index f9300266044d..7d6c29800d14 100644 --- a/drivers/video/pvr2fb.c +++ b/drivers/video/pvr2fb.c @@ -94,6 +94,7 @@ #define DISP_DIWCONF (DISP_BASE + 0xe8) #define DISP_DIWHSTRT (DISP_BASE + 0xec) #define DISP_DIWVSTRT (DISP_BASE + 0xf0) +#define DISP_PIXDEPTH (DISP_BASE + 0x108) /* Pixel clocks, one for TV output, doubled for VGA output */ #define TV_CLK 74239 @@ -143,6 +144,7 @@ static struct pvr2fb_par { unsigned char is_lowres; /* Is horizontal pixel-doubling enabled? */ unsigned long mmio_base; /* MMIO base */ + u32 palette[16]; } *currentpar; static struct fb_info *fb_info; @@ -599,6 +601,7 @@ static void pvr2_init_display(struct fb_info *info) /* bits per pixel */ fb_writel(fb_readl(DISP_DIWMODE) | (--bytesperpixel << 2), DISP_DIWMODE); + fb_writel(bytesperpixel << 2, DISP_PIXDEPTH); /* video enable, color sync, interlace, * hsync and vsync polarity (currently unused) */ @@ -790,7 +793,7 @@ static int __devinit pvr2fb_common_init(void) fb_info->fbops = &pvr2fb_ops; fb_info->fix = pvr2_fix; fb_info->par = currentpar; - fb_info->pseudo_palette = (void *)(fb_info->par + 1); + fb_info->pseudo_palette = currentpar->palette; fb_info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; if (video_output == VO_VGA) @@ -807,6 +810,8 @@ static int __devinit pvr2fb_common_init(void) if (register_framebuffer(fb_info) < 0) goto out_err; + /*Must write PIXDEPTH to register before anything is displayed - so force init */ + pvr2_init_display(fb_info); modememused = get_line_length(fb_info->var.xres_virtual, fb_info->var.bits_per_pixel); @@ -1082,14 +1087,15 @@ static int __init pvr2fb_init(void) #endif size = sizeof(struct fb_info) + sizeof(struct pvr2fb_par) + 16 * sizeof(u32); - fb_info = kzalloc(size, GFP_KERNEL); + fb_info = framebuffer_alloc(sizeof(struct pvr2fb_par), NULL); + if (!fb_info) { printk(KERN_ERR "Failed to allocate memory for fb_info\n"); return -ENOMEM; } - currentpar = (struct pvr2fb_par *)(fb_info + 1); + currentpar = fb_info->par; for (i = 0; i < ARRAY_SIZE(board_driver); i++) { struct pvr2_board *pvr_board = board_driver + i; @@ -1102,7 +1108,7 @@ static int __init pvr2fb_init(void) if (ret != 0) { printk(KERN_ERR "pvr2fb: Failed init of %s device\n", pvr_board->name); - kfree(fb_info); + framebuffer_release(fb_info); break; } } @@ -1126,7 +1132,7 @@ static void __exit pvr2fb_exit(void) #endif unregister_framebuffer(fb_info); - kfree(fb_info); + framebuffer_release(fb_info); } module_init(pvr2fb_init); diff --git a/drivers/video/stifb.c b/drivers/video/stifb.c index c97709ecbad0..e7c8db2eb49b 100644 --- a/drivers/video/stifb.c +++ b/drivers/video/stifb.c @@ -1100,13 +1100,18 @@ stifb_init_fb(struct sti_struct *sti, int bpp_pref) /* only supported cards are allowed */ switch (fb->id) { case CRT_ID_VISUALIZE_EG: - /* look for a double buffering device like e.g. the - "INTERNAL_EG_DX1024" in the RDI precisionbook laptop - which won't work. The same device in non-double - buffering mode returns "INTERNAL_EG_X1024". */ - if (strstr(sti->outptr.dev_name, "EG_DX")) { - printk(KERN_WARNING - "stifb: ignoring '%s'. Disable double buffering in IPL menu.\n", + /* Visualize cards can run either in "double buffer" or + "standard" mode. Depending on the mode, the card reports + a different device name, e.g. "INTERNAL_EG_DX1024" in double + buffer mode and "INTERNAL_EG_X1024" in standard mode. + Since this driver only supports standard mode, we check + if the device name contains the string "DX" and tell the + user how to reconfigure the card. */ + if (strstr(sti->outptr.dev_name, "DX")) { + printk(KERN_WARNING "WARNING: stifb framebuffer driver does not " + "support '%s' in double-buffer mode.\n" + KERN_WARNING "WARNING: Please disable the double-buffer mode " + "in IPL menu (the PARISC-BIOS).\n", sti->outptr.dev_name); goto out_err0; } diff --git a/fs/direct-io.c b/fs/direct-io.c index 52bb2638f7ab..6874785bb65a 100644 --- a/fs/direct-io.c +++ b/fs/direct-io.c @@ -974,6 +974,7 @@ direct_io_worker(int rw, struct kiocb *iocb, struct inode *inode, dio->get_block = get_block; dio->end_io = end_io; dio->map_bh.b_private = NULL; + dio->map_bh.b_state = 0; dio->final_block_in_bio = -1; dio->next_block_for_io = -1; diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index 0a50942b4378..131954b3fb98 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c @@ -353,6 +353,10 @@ static struct dentry *ecryptfs_lookup(struct inode *dir, struct dentry *dentry, ecryptfs_printk(KERN_DEBUG, "Is a symlink; returning\n"); goto out; } + if (special_file(lower_inode->i_mode)) { + ecryptfs_printk(KERN_DEBUG, "Is a special file; returning\n"); + goto out; + } if (!nd) { ecryptfs_printk(KERN_DEBUG, "We have a NULL nd, just leave" "as we *think* we are about to unlink\n"); diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c index e557a6766927..a98497264fe8 100644 --- a/fs/ecryptfs/main.c +++ b/fs/ecryptfs/main.c @@ -813,6 +813,15 @@ out: return rc; } +static void do_sysfs_unregistration(void) +{ + sysfs_remove_file(&ecryptfs_subsys.kobj, + &sysfs_attr_version.attr); + sysfs_remove_file(&ecryptfs_subsys.kobj, + &sysfs_attr_version_str.attr); + subsystem_unregister(&ecryptfs_subsys); +} + static int __init ecryptfs_init(void) { int rc; @@ -851,6 +860,9 @@ static int __init ecryptfs_init(void) if (rc) { ecryptfs_printk(KERN_ERR, "Failure occured while attempting to " "initialize the eCryptfs netlink socket\n"); + do_sysfs_unregistration(); + unregister_filesystem(&ecryptfs_fs_type); + ecryptfs_free_kmem_caches(); } out: return rc; @@ -858,11 +870,7 @@ out: static void __exit ecryptfs_exit(void) { - sysfs_remove_file(&ecryptfs_subsys.kobj, - &sysfs_attr_version.attr); - sysfs_remove_file(&ecryptfs_subsys.kobj, - &sysfs_attr_version_str.attr); - subsystem_unregister(&ecryptfs_subsys); + do_sysfs_unregistration(); ecryptfs_release_messaging(ecryptfs_transport); unregister_filesystem(&ecryptfs_fs_type); ecryptfs_free_kmem_caches(); diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c index f5e11f4fa952..4f517665c9a0 100644 --- a/fs/ocfs2/alloc.c +++ b/fs/ocfs2/alloc.c @@ -3731,7 +3731,6 @@ int ocfs2_insert_extent(struct ocfs2_super *osb, { int status; struct buffer_head *last_eb_bh = NULL; - struct buffer_head *bh = NULL; struct ocfs2_insert_type insert = {0, }; struct ocfs2_extent_rec rec; @@ -3783,9 +3782,6 @@ int ocfs2_insert_extent(struct ocfs2_super *osb, ocfs2_extent_map_insert_rec(inode, &rec); bail: - if (bh) - brelse(bh); - if (last_eb_bh) brelse(last_eb_bh); diff --git a/fs/ocfs2/cluster/tcp.c b/fs/ocfs2/cluster/tcp.c index f0bdfd944c44..685c18065c82 100644 --- a/fs/ocfs2/cluster/tcp.c +++ b/fs/ocfs2/cluster/tcp.c @@ -854,17 +854,25 @@ static void o2net_sendpage(struct o2net_sock_container *sc, struct o2net_node *nn = o2net_nn_from_num(sc->sc_node->nd_num); ssize_t ret; - - mutex_lock(&sc->sc_send_lock); - ret = sc->sc_sock->ops->sendpage(sc->sc_sock, - virt_to_page(kmalloced_virt), - (long)kmalloced_virt & ~PAGE_MASK, - size, MSG_DONTWAIT); - mutex_unlock(&sc->sc_send_lock); - if (ret != size) { + while (1) { + mutex_lock(&sc->sc_send_lock); + ret = sc->sc_sock->ops->sendpage(sc->sc_sock, + virt_to_page(kmalloced_virt), + (long)kmalloced_virt & ~PAGE_MASK, + size, MSG_DONTWAIT); + mutex_unlock(&sc->sc_send_lock); + if (ret == size) + break; + if (ret == (ssize_t)-EAGAIN) { + mlog(0, "sendpage of size %zu to " SC_NODEF_FMT + " returned EAGAIN\n", size, SC_NODEF_ARGS(sc)); + cond_resched(); + continue; + } mlog(ML_ERROR, "sendpage of size %zu to " SC_NODEF_FMT " failed with %zd\n", size, SC_NODEF_ARGS(sc), ret); o2net_ensure_shutdown(nn, sc, 0); + break; } } diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index c4034f693e7b..4ffa715be09c 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c @@ -187,6 +187,7 @@ int ocfs2_update_inode_atime(struct inode *inode, int ret; struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); handle_t *handle; + struct ocfs2_dinode *di = (struct ocfs2_dinode *) bh->b_data; mlog_entry_void(); @@ -197,11 +198,27 @@ int ocfs2_update_inode_atime(struct inode *inode, goto out; } + ret = ocfs2_journal_access(handle, inode, bh, + OCFS2_JOURNAL_ACCESS_WRITE); + if (ret) { + mlog_errno(ret); + goto out_commit; + } + + /* + * Don't use ocfs2_mark_inode_dirty() here as we don't always + * have i_mutex to guard against concurrent changes to other + * inode fields. + */ inode->i_atime = CURRENT_TIME; - ret = ocfs2_mark_inode_dirty(handle, inode, bh); + di->i_atime = cpu_to_le64(inode->i_atime.tv_sec); + di->i_atime_nsec = cpu_to_le32(inode->i_atime.tv_nsec); + + ret = ocfs2_journal_dirty(handle, bh); if (ret < 0) mlog_errno(ret); +out_commit: ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle); out: mlog_exit(ret); @@ -1011,6 +1028,11 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr) } if (size_change && attr->ia_size != i_size_read(inode)) { + if (attr->ia_size > sb->s_maxbytes) { + status = -EFBIG; + goto bail_unlock; + } + if (i_size_read(inode) > attr->ia_size) status = ocfs2_truncate_file(inode, bh, attr->ia_size); else @@ -1516,7 +1538,7 @@ static int __ocfs2_change_file_space(struct file *file, struct inode *inode, struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); struct buffer_head *di_bh = NULL; handle_t *handle; - unsigned long long max_off = ocfs2_max_file_offset(inode->i_sb->s_blocksize_bits); + unsigned long long max_off = inode->i_sb->s_maxbytes; if (ocfs2_is_hard_readonly(osb) || ocfs2_is_soft_readonly(osb)) return -EROFS; @@ -1942,7 +1964,7 @@ static ssize_t ocfs2_file_buffered_write(struct file *file, loff_t *ppos, } dst = kmap_atomic(page, KM_USER0); - memcpy(dst + (pos & (PAGE_CACHE_SIZE - 1)), buf, bytes); + memcpy(dst + (pos & (loff_t)(PAGE_CACHE_SIZE - 1)), buf, bytes); kunmap_atomic(dst, KM_USER0); flush_dcache_page(page); ocfs2_put_write_source(user_page); diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index d430fdab16e9..701e6d04ed5d 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c @@ -1080,6 +1080,7 @@ static int ocfs2_rename(struct inode *old_dir, struct buffer_head *old_inode_de_bh = NULL; // if old_dentry is a dir, // this is the 1st dirent bh nlink_t old_dir_nlink = old_dir->i_nlink; + struct ocfs2_dinode *old_di; /* At some point it might be nice to break this function up a * bit. */ @@ -1354,7 +1355,20 @@ static int ocfs2_rename(struct inode *old_dir, old_inode->i_ctime = CURRENT_TIME; mark_inode_dirty(old_inode); - ocfs2_mark_inode_dirty(handle, old_inode, old_inode_bh); + + status = ocfs2_journal_access(handle, old_inode, old_inode_bh, + OCFS2_JOURNAL_ACCESS_WRITE); + if (status >= 0) { + old_di = (struct ocfs2_dinode *) old_inode_bh->b_data; + + old_di->i_ctime = cpu_to_le64(old_inode->i_ctime.tv_sec); + old_di->i_ctime_nsec = cpu_to_le32(old_inode->i_ctime.tv_nsec); + + status = ocfs2_journal_dirty(handle, old_inode_bh); + if (status < 0) + mlog_errno(status); + } else + mlog_errno(status); /* now that the name has been added to new_dir, remove the old name */ status = ocfs2_delete_entry(handle, old_dir, old_de, old_de_bh); diff --git a/fs/ocfs2/ocfs2.h b/fs/ocfs2/ocfs2.h index 5cc90a40b3c5..58307853fb4a 100644 --- a/fs/ocfs2/ocfs2.h +++ b/fs/ocfs2/ocfs2.h @@ -494,16 +494,16 @@ static inline unsigned int ocfs2_page_index_to_clusters(struct super_block *sb, /* * Find the 1st page index which covers the given clusters. */ -static inline unsigned long ocfs2_align_clusters_to_page_index(struct super_block *sb, +static inline pgoff_t ocfs2_align_clusters_to_page_index(struct super_block *sb, u32 clusters) { unsigned int cbits = OCFS2_SB(sb)->s_clustersize_bits; - unsigned long index = clusters; + pgoff_t index = clusters; if (PAGE_CACHE_SHIFT > cbits) { - index = clusters >> (PAGE_CACHE_SHIFT - cbits); + index = (pgoff_t)clusters >> (PAGE_CACHE_SHIFT - cbits); } else if (PAGE_CACHE_SHIFT < cbits) { - index = clusters << (cbits - PAGE_CACHE_SHIFT); + index = (pgoff_t)clusters << (cbits - PAGE_CACHE_SHIFT); } return index; diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index 200c7d4790dc..f2fc9a795deb 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c @@ -316,39 +316,51 @@ static void ocfs2_destroy_inode(struct inode *inode) kmem_cache_free(ocfs2_inode_cachep, OCFS2_I(inode)); } -/* From xfs_super.c:xfs_max_file_offset - * Copyright (c) 2000-2004 Silicon Graphics, Inc. - */ -unsigned long long ocfs2_max_file_offset(unsigned int blockshift) +static unsigned long long ocfs2_max_file_offset(unsigned int bbits, + unsigned int cbits) { - unsigned int pagefactor = 1; - unsigned int bitshift = BITS_PER_LONG - 1; - - /* Figure out maximum filesize, on Linux this can depend on - * the filesystem blocksize (on 32 bit platforms). - * __block_prepare_write does this in an [unsigned] long... - * page->index << (PAGE_CACHE_SHIFT - bbits) - * So, for page sized blocks (4K on 32 bit platforms), - * this wraps at around 8Tb (hence MAX_LFS_FILESIZE which is - * (((u64)PAGE_CACHE_SIZE << (BITS_PER_LONG-1))-1) - * but for smaller blocksizes it is less (bbits = log2 bsize). - * Note1: get_block_t takes a long (implicit cast from above) - * Note2: The Large Block Device (LBD and HAVE_SECTOR_T) patch - * can optionally convert the [unsigned] long from above into - * an [unsigned] long long. + unsigned int bytes = 1 << cbits; + unsigned int trim = bytes; + unsigned int bitshift = 32; + + /* + * i_size and all block offsets in ocfs2 are always 64 bits + * wide. i_clusters is 32 bits, in cluster-sized units. So on + * 64 bit platforms, cluster size will be the limiting factor. */ #if BITS_PER_LONG == 32 # if defined(CONFIG_LBD) BUILD_BUG_ON(sizeof(sector_t) != 8); - pagefactor = PAGE_CACHE_SIZE; - bitshift = BITS_PER_LONG; + /* + * We might be limited by page cache size. + */ + if (bytes > PAGE_CACHE_SIZE) { + bytes = PAGE_CACHE_SIZE; + trim = 1; + /* + * Shift by 31 here so that we don't get larger than + * MAX_LFS_FILESIZE + */ + bitshift = 31; + } # else - pagefactor = PAGE_CACHE_SIZE >> (PAGE_CACHE_SHIFT - blockshift); + /* + * We are limited by the size of sector_t. Use block size, as + * that's what we expose to the VFS. + */ + bytes = 1 << bbits; + trim = 1; + bitshift = 31; # endif #endif - return (((unsigned long long)pagefactor) << bitshift) - 1; + /* + * Trim by a whole cluster when we can actually approach the + * on-disk limits. Otherwise we can overflow i_clusters when + * an extent start is at the max offset. + */ + return (((unsigned long long)bytes) << bitshift) - trim; } static int ocfs2_remount(struct super_block *sb, int *flags, char *data) @@ -1259,8 +1271,8 @@ static int ocfs2_initialize_super(struct super_block *sb, int sector_size) { int status = 0; - int i; - struct ocfs2_dinode *di = NULL; + int i, cbits, bbits; + struct ocfs2_dinode *di = (struct ocfs2_dinode *)bh->b_data; struct inode *inode = NULL; struct buffer_head *bitmap_bh = NULL; struct ocfs2_journal *journal; @@ -1279,9 +1291,12 @@ static int ocfs2_initialize_super(struct super_block *sb, sb->s_fs_info = osb; sb->s_op = &ocfs2_sops; sb->s_export_op = &ocfs2_export_ops; + sb->s_time_gran = 1; sb->s_flags |= MS_NOATIME; /* this is needed to support O_LARGEFILE */ - sb->s_maxbytes = ocfs2_max_file_offset(sb->s_blocksize_bits); + cbits = le32_to_cpu(di->id2.i_super.s_clustersize_bits); + bbits = le32_to_cpu(di->id2.i_super.s_blocksize_bits); + sb->s_maxbytes = ocfs2_max_file_offset(bbits, cbits); osb->sb = sb; /* Save off for ocfs2_rw_direct */ @@ -1341,8 +1356,6 @@ static int ocfs2_initialize_super(struct super_block *sb, goto bail; } - di = (struct ocfs2_dinode *)bh->b_data; - osb->max_slots = le16_to_cpu(di->id2.i_super.s_max_slots); if (osb->max_slots > OCFS2_MAX_SLOTS || osb->max_slots == 0) { mlog(ML_ERROR, "Invalid number of node slots (%u)\n", diff --git a/fs/ocfs2/super.h b/fs/ocfs2/super.h index 3b9cb3d0b008..783f5270f2a1 100644 --- a/fs/ocfs2/super.h +++ b/fs/ocfs2/super.h @@ -45,6 +45,4 @@ void __ocfs2_abort(struct super_block *sb, #define ocfs2_abort(sb, fmt, args...) __ocfs2_abort(sb, __PRETTY_FUNCTION__, fmt, ##args) -unsigned long long ocfs2_max_file_offset(unsigned int blockshift); - #endif /* OCFS2_SUPER_H */ diff --git a/include/asm-frv/unistd.h b/include/asm-frv/unistd.h index 7306c71a8926..cd84f1771e34 100644 --- a/include/asm-frv/unistd.h +++ b/include/asm-frv/unistd.h @@ -330,10 +330,11 @@ #define __NR_signalfd 321 #define __NR_timerfd 322 #define __NR_eventfd 323 +#define __NR_fallocate 324 #ifdef __KERNEL__ -#define NR_syscalls 324 +#define NR_syscalls 325 #define __ARCH_WANT_IPC_PARSE_VERSION /* #define __ARCH_WANT_OLD_READDIR */ diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h index f605e8d0eed3..5f0d797d33fd 100644 --- a/include/asm-generic/pgtable.h +++ b/include/asm-generic/pgtable.h @@ -2,6 +2,7 @@ #define _ASM_GENERIC_PGTABLE_H #ifndef __ASSEMBLY__ +#ifdef CONFIG_MMU #ifndef __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS /* @@ -133,41 +134,6 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addres #endif /* - * A facility to provide lazy MMU batching. This allows PTE updates and - * page invalidations to be delayed until a call to leave lazy MMU mode - * is issued. Some architectures may benefit from doing this, and it is - * beneficial for both shadow and direct mode hypervisors, which may batch - * the PTE updates which happen during this window. Note that using this - * interface requires that read hazards be removed from the code. A read - * hazard could result in the direct mode hypervisor case, since the actual - * write to the page tables may not yet have taken place, so reads though - * a raw PTE pointer after it has been modified are not guaranteed to be - * up to date. This mode can only be entered and left under the protection of - * the page table locks for all page tables which may be modified. In the UP - * case, this is required so that preemption is disabled, and in the SMP case, - * it must synchronize the delayed page table writes properly on other CPUs. - */ -#ifndef __HAVE_ARCH_ENTER_LAZY_MMU_MODE -#define arch_enter_lazy_mmu_mode() do {} while (0) -#define arch_leave_lazy_mmu_mode() do {} while (0) -#define arch_flush_lazy_mmu_mode() do {} while (0) -#endif - -/* - * A facility to provide batching of the reload of page tables with the - * actual context switch code for paravirtualized guests. By convention, - * only one of the lazy modes (CPU, MMU) should be active at any given - * time, entry should never be nested, and entry and exits should always - * be paired. This is for sanity of maintaining and reasoning about the - * kernel code. - */ -#ifndef __HAVE_ARCH_ENTER_LAZY_CPU_MODE -#define arch_enter_lazy_cpu_mode() do {} while (0) -#define arch_leave_lazy_cpu_mode() do {} while (0) -#define arch_flush_lazy_cpu_mode() do {} while (0) -#endif - -/* * When walking page tables, get the address of the next boundary, * or the end address of the range if that comes earlier. Although no * vma end wraps to 0, rounded up __boundary may wrap to 0 throughout. @@ -233,6 +199,43 @@ static inline int pmd_none_or_clear_bad(pmd_t *pmd) } return 0; } +#endif /* CONFIG_MMU */ + +/* + * A facility to provide lazy MMU batching. This allows PTE updates and + * page invalidations to be delayed until a call to leave lazy MMU mode + * is issued. Some architectures may benefit from doing this, and it is + * beneficial for both shadow and direct mode hypervisors, which may batch + * the PTE updates which happen during this window. Note that using this + * interface requires that read hazards be removed from the code. A read + * hazard could result in the direct mode hypervisor case, since the actual + * write to the page tables may not yet have taken place, so reads though + * a raw PTE pointer after it has been modified are not guaranteed to be + * up to date. This mode can only be entered and left under the protection of + * the page table locks for all page tables which may be modified. In the UP + * case, this is required so that preemption is disabled, and in the SMP case, + * it must synchronize the delayed page table writes properly on other CPUs. + */ +#ifndef __HAVE_ARCH_ENTER_LAZY_MMU_MODE +#define arch_enter_lazy_mmu_mode() do {} while (0) +#define arch_leave_lazy_mmu_mode() do {} while (0) +#define arch_flush_lazy_mmu_mode() do {} while (0) +#endif + +/* + * A facility to provide batching of the reload of page tables with the + * actual context switch code for paravirtualized guests. By convention, + * only one of the lazy modes (CPU, MMU) should be active at any given + * time, entry should never be nested, and entry and exits should always + * be paired. This is for sanity of maintaining and reasoning about the + * kernel code. + */ +#ifndef __HAVE_ARCH_ENTER_LAZY_CPU_MODE +#define arch_enter_lazy_cpu_mode() do {} while (0) +#define arch_leave_lazy_cpu_mode() do {} while (0) +#define arch_flush_lazy_cpu_mode() do {} while (0) +#endif + #endif /* !__ASSEMBLY__ */ #endif /* _ASM_GENERIC_PGTABLE_H */ diff --git a/include/asm-i386/apic.h b/include/asm-i386/apic.h index 1e8f6f252dd3..4091b33dcb10 100644 --- a/include/asm-i386/apic.h +++ b/include/asm-i386/apic.h @@ -116,6 +116,8 @@ extern void enable_NMI_through_LVT0 (void * dummy); extern int timer_over_8254; extern int local_apic_timer_c2_ok; +extern int local_apic_timer_disabled; + #else /* !CONFIG_X86_LOCAL_APIC */ static inline void lapic_shutdown(void) { } diff --git a/include/asm-i386/cpufeature.h b/include/asm-i386/cpufeature.h index c961c03cf1e2..7b3aa28ebc6e 100644 --- a/include/asm-i386/cpufeature.h +++ b/include/asm-i386/cpufeature.h @@ -79,7 +79,7 @@ #define X86_FEATURE_ARCH_PERFMON (3*32+11) /* Intel Architectural PerfMon */ #define X86_FEATURE_PEBS (3*32+12) /* Precise-Event Based Sampling */ #define X86_FEATURE_BTS (3*32+13) /* Branch Trace Store */ -#define X86_FEATURE_LAPIC_TIMER_BROKEN (3*32+ 14) /* lapic timer broken in C1 */ +/* 14 free */ #define X86_FEATURE_SYNC_RDTSC (3*32+15) /* RDTSC synchronizes the CPU */ #define X86_FEATURE_REP_GOOD (3*32+16) /* rep microcode works well on this CPU */ diff --git a/include/asm-i386/paravirt.h b/include/asm-i386/paravirt.h index 7df88be2dd9e..9fa3fa9e62d1 100644 --- a/include/asm-i386/paravirt.h +++ b/include/asm-i386/paravirt.h @@ -47,7 +47,8 @@ struct paravirt_ops * The patch function should return the number of bytes of code * generated, as we nop pad the rest in generic code. */ - unsigned (*patch)(u8 type, u16 clobber, void *firstinsn, unsigned len); + unsigned (*patch)(u8 type, u16 clobber, void *insnbuf, + unsigned long addr, unsigned len); /* Basic arch-specific setup */ void (*arch_setup)(void); @@ -253,13 +254,16 @@ extern struct paravirt_ops paravirt_ops; unsigned paravirt_patch_nop(void); unsigned paravirt_patch_ignore(unsigned len); -unsigned paravirt_patch_call(void *target, u16 tgt_clobbers, - void *site, u16 site_clobbers, +unsigned paravirt_patch_call(void *insnbuf, + const void *target, u16 tgt_clobbers, + unsigned long addr, u16 site_clobbers, unsigned len); -unsigned paravirt_patch_jmp(void *target, void *site, unsigned len); -unsigned paravirt_patch_default(u8 type, u16 clobbers, void *site, unsigned len); +unsigned paravirt_patch_jmp(const void *target, void *insnbuf, + unsigned long addr, unsigned len); +unsigned paravirt_patch_default(u8 type, u16 clobbers, void *insnbuf, + unsigned long addr, unsigned len); -unsigned paravirt_patch_insns(void *site, unsigned len, +unsigned paravirt_patch_insns(void *insnbuf, unsigned len, const char *start, const char *end); int paravirt_disable_iospace(void); diff --git a/include/asm-i386/pci.h b/include/asm-i386/pci.h index d790343e9982..4fcacc711385 100644 --- a/include/asm-i386/pci.h +++ b/include/asm-i386/pci.h @@ -8,6 +8,9 @@ struct pci_sysdata { int node; /* NUMA node */ }; +/* scan a bus after allocating a pci_sysdata for it */ +extern struct pci_bus *pci_scan_bus_with_sysdata(int busno); + #include <linux/mm.h> /* for struct page */ /* Can be used to override the logic in pci_scan_bus for skipping diff --git a/include/asm-powerpc/dma-mapping.h b/include/asm-powerpc/dma-mapping.h index f6bd804d9090..744d6bb24116 100644 --- a/include/asm-powerpc/dma-mapping.h +++ b/include/asm-powerpc/dma-mapping.h @@ -95,7 +95,7 @@ static inline int dma_set_mask(struct device *dev, u64 dma_mask) return -EIO; if (dma_ops->set_dma_mask != NULL) return dma_ops->set_dma_mask(dev, dma_mask); - if (!dev->dma_mask || !dma_supported(dev, *dev->dma_mask)) + if (!dev->dma_mask || !dma_supported(dev, dma_mask)) return -EIO; *dev->dma_mask = dma_mask; return 0; diff --git a/include/asm-powerpc/spu_priv1.h b/include/asm-powerpc/spu_priv1.h index 7e78f6a1ab8b..0f37c7c90820 100644 --- a/include/asm-powerpc/spu_priv1.h +++ b/include/asm-powerpc/spu_priv1.h @@ -178,6 +178,7 @@ struct spu_management_ops { int (*enumerate_spus)(int (*fn)(void *data)); int (*create_spu)(struct spu *spu, void *data); int (*destroy_spu)(struct spu *spu); + int (*init_affinity)(void); }; extern const struct spu_management_ops* spu_management_ops; @@ -200,6 +201,12 @@ spu_destroy_spu (struct spu *spu) return spu_management_ops->destroy_spu(spu); } +static inline int +spu_init_affinity (void) +{ + return spu_management_ops->init_affinity(); +} + /* * The declarations folowing are put here for convenience * and only intended to be used by the platform setup code. diff --git a/include/asm-x86_64/pci.h b/include/asm-x86_64/pci.h index 88926eb44f5c..5da8cb0c0599 100644 --- a/include/asm-x86_64/pci.h +++ b/include/asm-x86_64/pci.h @@ -10,6 +10,8 @@ struct pci_sysdata { void* iommu; /* IOMMU private data */ }; +extern struct pci_bus *pci_scan_bus_with_sysdata(int busno); + #ifdef CONFIG_CALGARY_IOMMU static inline void* pci_iommu(struct pci_bus *bus) { diff --git a/include/linux/bio.h b/include/linux/bio.h index 4d85262b4fa4..1ddef34f43c3 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h @@ -24,6 +24,8 @@ #include <linux/mempool.h> #include <linux/ioprio.h> +#ifdef CONFIG_BLOCK + /* Platforms may set this to teach the BIO layer about IOMMU hardware. */ #include <asm/io.h> @@ -361,4 +363,5 @@ static inline char *__bio_kmap_irq(struct bio *bio, unsigned short idx, __bio_kmap_irq((bio), (bio)->bi_idx, (flags)) #define bio_kunmap_irq(buf,flags) __bio_kunmap_irq(buf, flags) +#endif /* CONFIG_BLOCK */ #endif /* __LINUX_BIO_H */ diff --git a/include/linux/blktrace_api.h b/include/linux/blktrace_api.h index 90874a5d7d78..7b5d56b82b59 100644 --- a/include/linux/blktrace_api.h +++ b/include/linux/blktrace_api.h @@ -105,7 +105,7 @@ struct blk_io_trace { */ struct blk_io_trace_remap { __be32 device; - u32 __pad; + __be32 device_from; __be64 sector; }; @@ -272,6 +272,7 @@ static inline void blk_add_trace_remap(struct request_queue *q, struct bio *bio, return; r.device = cpu_to_be32(dev); + r.device_from = cpu_to_be32(bio->bi_bdev->bd_dev); r.sector = cpu_to_be64(to); __blk_add_trace(bt, from, bio->bi_size, bio->bi_rw, BLK_TA_REMAP, !bio_flagged(bio, BIO_UPTODATE), sizeof(r), &r); diff --git a/include/linux/clockchips.h b/include/linux/clockchips.h index e0bd46eb2414..def5a659b8a5 100644 --- a/include/linux/clockchips.h +++ b/include/linux/clockchips.h @@ -123,7 +123,6 @@ extern void clockevents_exchange_device(struct clock_event_device *old, extern void clockevents_set_mode(struct clock_event_device *dev, enum clock_event_mode mode); extern int clockevents_register_notifier(struct notifier_block *nb); -extern void clockevents_unregister_notifier(struct notifier_block *nb); extern int clockevents_program_event(struct clock_event_device *dev, ktime_t expires, ktime_t now); diff --git a/include/linux/fs.h b/include/linux/fs.h index 6bf139562947..16421f662a7a 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1659,7 +1659,6 @@ extern int sb_min_blocksize(struct super_block *, int); extern int generic_file_mmap(struct file *, struct vm_area_struct *); extern int generic_file_readonly_mmap(struct file *, struct vm_area_struct *); extern int file_read_actor(read_descriptor_t * desc, struct page *page, unsigned long offset, unsigned long size); -extern int file_send_actor(read_descriptor_t * desc, struct page *page, unsigned long offset, unsigned long size); int generic_write_checks(struct file *file, loff_t *pos, size_t *count, int isblk); extern ssize_t generic_file_aio_read(struct kiocb *, const struct iovec *, unsigned long, loff_t); extern ssize_t generic_file_aio_write(struct kiocb *, const struct iovec *, unsigned long, loff_t); diff --git a/include/linux/init.h b/include/linux/init.h index 1a4a283d19a9..74b1f43bf982 100644 --- a/include/linux/init.h +++ b/include/linux/init.h @@ -43,7 +43,7 @@ #define __init __attribute__ ((__section__ (".init.text"))) __cold #define __initdata __attribute__ ((__section__ (".init.data"))) #define __exitdata __attribute__ ((__section__(".exit.data"))) -#define __exit_call __attribute_used__ __attribute__ ((__section__ (".exitcall.exit"))) __cold +#define __exit_call __attribute_used__ __attribute__ ((__section__ (".exitcall.exit"))) /* modpost check for section mismatches during the kernel build. * A section mismatch happens when there are references from a diff --git a/include/linux/kernel.h b/include/linux/kernel.h index b4f5b81b4257..f592df74b3cf 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -226,7 +226,7 @@ extern void print_hex_dump(const char *level, const char *prefix_str, int prefix_type, int rowsize, int groupsize, const void *buf, size_t len, bool ascii); extern void print_hex_dump_bytes(const char *prefix_str, int prefix_type, - void *buf, size_t len); + const void *buf, size_t len); #define hex_asc(x) "0123456789abcdef"[x] #ifdef DEBUG diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h index 28e3664fdf1b..cd13a78c5db8 100644 --- a/include/linux/proc_fs.h +++ b/include/linux/proc_fs.h @@ -75,7 +75,6 @@ struct proc_dir_entry { write_proc_t *write_proc; atomic_t count; /* use count */ int deleted; /* delete flag */ - void *set; int pde_users; /* number of callers into module in progress */ spinlock_t pde_unload_lock; /* proc_fops checks and pde_users bumps */ struct completion *pde_unload_completion; diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index c6b7485eac7c..fe17d7d750c2 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h @@ -281,7 +281,6 @@ extern void FASTCALL(call_rcu(struct rcu_head *head, extern void FASTCALL(call_rcu_bh(struct rcu_head *head, void (*func)(struct rcu_head *head))); extern void synchronize_rcu(void); -void synchronize_idle(void); extern void rcu_barrier(void); #endif /* __KERNEL__ */ diff --git a/include/linux/tty.h b/include/linux/tty.h index 691a1748d9d2..6570719eafdf 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -274,6 +274,8 @@ struct tty_struct { #define TTY_PTY_LOCK 16 /* pty private */ #define TTY_NO_WRITE_SPLIT 17 /* Preserve write boundaries to driver */ #define TTY_HUPPED 18 /* Post driver->hangup() */ +#define TTY_FLUSHING 19 /* Flushing to ldisc in progress */ +#define TTY_FLUSHPENDING 20 /* Queued buffer flush pending */ #define TTY_WRITE_FLUSH(tty) tty_write_flush((tty)) diff --git a/kernel/kprobes.c b/kernel/kprobes.c index 3e9f513a728d..4b8a4493c541 100644 --- a/kernel/kprobes.c +++ b/kernel/kprobes.c @@ -1063,6 +1063,11 @@ EXPORT_SYMBOL_GPL(register_kprobe); EXPORT_SYMBOL_GPL(unregister_kprobe); EXPORT_SYMBOL_GPL(register_jprobe); EXPORT_SYMBOL_GPL(unregister_jprobe); +#ifdef CONFIG_KPROBES EXPORT_SYMBOL_GPL(jprobe_return); +#endif + +#ifdef CONFIG_KPROBES EXPORT_SYMBOL_GPL(register_kretprobe); EXPORT_SYMBOL_GPL(unregister_kretprobe); +#endif diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c index a3b7854b8f7c..a686590d88c1 100644 --- a/kernel/power/snapshot.c +++ b/kernel/power/snapshot.c @@ -709,7 +709,8 @@ static void mark_nosave_pages(struct memory_bitmap *bm) region->end_pfn << PAGE_SHIFT); for (pfn = region->start_pfn; pfn < region->end_pfn; pfn++) - memory_bm_set_bit(bm, pfn); + if (pfn_valid(pfn)) + memory_bm_set_bit(bm, pfn); } } diff --git a/kernel/profile.c b/kernel/profile.c index 5b20fe977bed..cb1e37d2dac3 100644 --- a/kernel/profile.c +++ b/kernel/profile.c @@ -199,11 +199,11 @@ EXPORT_SYMBOL_GPL(register_timer_hook); EXPORT_SYMBOL_GPL(unregister_timer_hook); EXPORT_SYMBOL_GPL(task_handoff_register); EXPORT_SYMBOL_GPL(task_handoff_unregister); +EXPORT_SYMBOL_GPL(profile_event_register); +EXPORT_SYMBOL_GPL(profile_event_unregister); #endif /* CONFIG_PROFILING */ -EXPORT_SYMBOL_GPL(profile_event_register); -EXPORT_SYMBOL_GPL(profile_event_unregister); #ifdef CONFIG_SMP /* diff --git a/kernel/sched.c b/kernel/sched.c index b0afd8db1396..6247e4a8350f 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -263,6 +263,7 @@ struct rq { unsigned int clock_warps, clock_overflows; unsigned int clock_unstable_events; + u64 tick_timestamp; atomic_t nr_iowait; @@ -341,8 +342,11 @@ static void __update_rq_clock(struct rq *rq) /* * Catch too large forward jumps too: */ - if (unlikely(delta > 2*TICK_NSEC)) { - clock++; + if (unlikely(clock + delta > rq->tick_timestamp + TICK_NSEC)) { + if (clock < rq->tick_timestamp + TICK_NSEC) + clock = rq->tick_timestamp + TICK_NSEC; + else + clock++; rq->clock_overflows++; } else { if (unlikely(delta > rq->clock_max_delta)) @@ -3308,9 +3312,16 @@ void scheduler_tick(void) int cpu = smp_processor_id(); struct rq *rq = cpu_rq(cpu); struct task_struct *curr = rq->curr; + u64 next_tick = rq->tick_timestamp + TICK_NSEC; spin_lock(&rq->lock); __update_rq_clock(rq); + /* + * Let rq->clock advance by at least TICK_NSEC: + */ + if (unlikely(rq->clock < next_tick)) + rq->clock = next_tick; + rq->tick_timestamp = rq->clock; update_cpu_load(rq); if (curr != rq->idle) /* FIXME: needed? */ curr->sched_class->task_tick(rq, curr); diff --git a/kernel/sched_debug.c b/kernel/sched_debug.c index 3da32156394e..87e524762b85 100644 --- a/kernel/sched_debug.c +++ b/kernel/sched_debug.c @@ -108,7 +108,7 @@ print_cfs_rq_runtime_sum(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq) void print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq) { - SEQ_printf(m, "\ncfs_rq %p\n", cfs_rq); + SEQ_printf(m, "\ncfs_rq\n"); #define P(x) \ SEQ_printf(m, " .%-30s: %Ld\n", #x, (long long)(cfs_rq->x)) diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c index e91db32cadfd..c5af38948a1e 100644 --- a/kernel/sched_fair.c +++ b/kernel/sched_fair.c @@ -959,13 +959,12 @@ load_balance_fair(struct rq *this_rq, int this_cpu, struct rq *busiest, for_each_leaf_cfs_rq(busiest, busy_cfs_rq) { #ifdef CONFIG_FAIR_GROUP_SCHED struct cfs_rq *this_cfs_rq; - long imbalances; + long imbalance; unsigned long maxload; this_cfs_rq = cpu_cfs_rq(busy_cfs_rq, this_cpu); - imbalance = busy_cfs_rq->load.weight - - this_cfs_rq->load.weight; + imbalance = busy_cfs_rq->load.weight - this_cfs_rq->load.weight; /* Don't pull if this_cfs_rq has more load than busy_cfs_rq */ if (imbalance <= 0) continue; @@ -976,7 +975,7 @@ load_balance_fair(struct rq *this_rq, int this_cpu, struct rq *busiest, *this_best_prio = cfs_rq_best_prio(this_cfs_rq); #else -#define maxload rem_load_move +# define maxload rem_load_move #endif /* pass busy_cfs_rq argument into * load_balance_[start|next]_fair iterators diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 79c891e6266c..8bdb8c07e04f 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -1023,6 +1023,7 @@ static ctl_table vm_table[] = { .mode = 0644, .proc_handler = &proc_doulongvec_minmax, }, +#endif #ifdef CONFIG_NUMA { .ctl_name = CTL_UNNUMBERED, @@ -1034,7 +1035,6 @@ static ctl_table vm_table[] = { .strategy = &sysctl_string, }, #endif -#endif #if defined(CONFIG_X86_32) || \ (defined(CONFIG_SUPERH) && defined(CONFIG_VSYSCALL)) { diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c index 2ad1c37b8dfe..41dd3105ce7f 100644 --- a/kernel/time/clockevents.c +++ b/kernel/time/clockevents.c @@ -113,16 +113,6 @@ int clockevents_register_notifier(struct notifier_block *nb) return ret; } -/** - * clockevents_unregister_notifier - unregister a clock events change listener - */ -void clockevents_unregister_notifier(struct notifier_block *nb) -{ - spin_lock(&clockevents_lock); - raw_notifier_chain_unregister(&clockevents_chain, nb); - spin_unlock(&clockevents_lock); -} - /* * Notify about a clock event change. Called with clockevents_lock * held. diff --git a/lib/hexdump.c b/lib/hexdump.c index 16f2e2935e87..bd5edaeaa80b 100644 --- a/lib/hexdump.c +++ b/lib/hexdump.c @@ -189,7 +189,7 @@ EXPORT_SYMBOL(print_hex_dump); * rowsize of 16, groupsize of 1, and ASCII output included. */ void print_hex_dump_bytes(const char *prefix_str, int prefix_type, - void *buf, size_t len) + const void *buf, size_t len) { print_hex_dump(KERN_DEBUG, prefix_str, prefix_type, 16, 1, buf, len, 1); diff --git a/mm/filemap.c b/mm/filemap.c index 6cf700d41844..90b657b50f81 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -843,7 +843,7 @@ static void shrink_readahead_size_eio(struct file *filp, /** * do_generic_mapping_read - generic file read routine * @mapping: address_space to be read - * @ra: file's readahead state + * @_ra: file's readahead state * @filp: the file to read * @ppos: current file position * @desc: read_descriptor @@ -1218,26 +1218,6 @@ out: } EXPORT_SYMBOL(generic_file_aio_read); -int file_send_actor(read_descriptor_t * desc, struct page *page, unsigned long offset, unsigned long size) -{ - ssize_t written; - unsigned long count = desc->count; - struct file *file = desc->arg.data; - - if (size > count) - size = count; - - written = file->f_op->sendpage(file, page, offset, - size, &file->f_pos, size<count); - if (written < 0) { - desc->error = written; - written = 0; - } - desc->count = count - written; - desc->written += written; - return written; -} - static ssize_t do_readahead(struct address_space *mapping, struct file *filp, unsigned long index, unsigned long nr) diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 73751ab6ec0c..dae7d30dca0f 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -9,7 +9,7 @@ use strict; my $P = $0; $P =~ s@.*/@@g; -my $V = '0.08'; +my $V = '0.09'; use Getopt::Long qw(:config no_auto_abbrev); @@ -311,7 +311,7 @@ sub process { my $Ident = qr{[A-Za-z\d_]+}; my $Storage = qr{extern|static}; - my $Sparse = qr{__user|__kernel|__force|__iomem}; + my $Sparse = qr{__user|__kernel|__force|__iomem|__must_check|__init_refok}; my $NonptrType = qr{ \b (?:const\s+)? @@ -325,6 +325,7 @@ sub process { unsigned| float| double| + bool| long\s+int| long\s+long| long\s+long\s+int| @@ -340,7 +341,8 @@ sub process { }x; my $Type = qr{ \b$NonptrType\b - (?:\s*\*+\s*const|\s*\*+)? + (?:\s*\*+\s*const|\s*\*+|(?:\s*\[\s*\])+)? + (?:\s+$Sparse)* }x; my $Declare = qr{(?:$Storage\s+)?$Type}; my $Attribute = qr{const|__read_mostly|__init|__initdata|__meminit}; @@ -494,16 +496,15 @@ sub process { ERROR("use tabs not spaces\n" . $herevet); } - # - # The rest of our checks refer specifically to C style - # only apply those _outside_ comments. - # - next if ($in_comment); - # Remove comments from the line before processing. - $line =~ s@/\*.*\*/@@g; - $line =~ s@/\*.*@@; - $line =~ s@.*\*/@@; + my $comment_edge = ($line =~ s@/\*.*\*/@@g) + + ($line =~ s@/\*.*@@) + + ($line =~ s@^(.).*\*/@$1@); + +# The rest of our checks refer specifically to C style +# only apply those _outside_ comments. Only skip +# lines in the middle of comments. + next if (!$comment_edge && $in_comment); # Standardise the strings and chars within the input to simplify matching. $line = sanitise_line($line); @@ -599,7 +600,7 @@ sub process { if (($prevline !~ /^}/) && ($prevline !~ /^\+}/) && ($prevline !~ /^ }/) && - ($prevline !~ /\s$name(?:\s+$Attribute)?\s*(?:;|=)/)) { + ($prevline !~ /\b\Q$name\E(?:\s+$Attribute)?\s*(?:;|=)/)) { WARN("EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr); } } @@ -680,9 +681,9 @@ sub process { # check for spaces between functions and their parentheses. if ($line =~ /($Ident)\s+\(/ && - $1 !~ /^(?:if|for|while|switch|return|volatile)$/ && + $1 !~ /^(?:if|for|while|switch|return|volatile|__volatile__|__attribute__|format|__extension__|Copyright)$/ && $line !~ /$Type\s+\(/ && $line !~ /^.\#\s*define\b/) { - ERROR("no space between function name and open parenthesis '('\n" . $herecurr); + WARN("no space between function name and open parenthesis '('\n" . $herecurr); } # Check operator spacing. # Note we expand the line with the leading + as the real @@ -712,6 +713,7 @@ sub process { $c = 'W' if ($elements[$n + 2] =~ /^\s/); $c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/); $c = 'O' if ($elements[$n + 2] eq ''); + $c = 'E' if ($elements[$n + 2] =~ /\s*\\$/); } else { $c = 'E'; } @@ -812,7 +814,11 @@ sub process { # All the others need spaces both sides. } elsif ($ctx !~ /[EW]x[WE]/) { - ERROR("need spaces around that '$op' $at\n" . $hereptr); + # Ignore email addresses <foo@bar> + if (!($op eq '<' && $cb =~ /$;\S+\@\S+>/) && + !($op eq '>' && $cb =~ /<\S+\@\S+$;/)) { + ERROR("need spaces around that '$op' $at\n" . $hereptr); + } } $off += length($elements[$n + 1]); } @@ -823,15 +829,24 @@ sub process { WARN("multiple assignments should be avoided\n" . $herecurr); } -# check for multiple declarations, allowing for a function declaration -# continuation. - if ($line =~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Ident.*/ && - $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) { - WARN("declaring multiple variables together should be avoided\n" . $herecurr); - } +## # check for multiple declarations, allowing for a function declaration +## # continuation. +## if ($line =~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Ident.*/ && +## $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) { +## +## # Remove any bracketed sections to ensure we do not +## # falsly report the parameters of functions. +## my $ln = $line; +## while ($ln =~ s/\([^\(\)]*\)//g) { +## } +## if ($ln =~ /,/) { +## WARN("declaring multiple variables together should be avoided\n" . $herecurr); +## } +## } #need space before brace following if, while, etc - if ($line =~ /\(.*\){/ || $line =~ /do{/) { + if (($line =~ /\(.*\){/ && $line !~ /\($Type\){/) || + $line =~ /do{/) { ERROR("need a space before the open brace '{'\n" . $herecurr); } @@ -841,6 +856,22 @@ sub process { ERROR("need a space after that close brace '}'\n" . $herecurr); } +# check spacing on square brackets + if ($line =~ /\[\s/ && $line !~ /\[\s*$/) { + ERROR("no space after that open square bracket '['\n" . $herecurr); + } + if ($line =~ /\s\]/) { + ERROR("no space before that close square bracket ']'\n" . $herecurr); + } + +# check spacing on paretheses + if ($line =~ /\(\s/ && $line !~ /\(\s*$/) { + ERROR("no space after that open parenthesis '('\n" . $herecurr); + } + if ($line =~ /\s\)/) { + ERROR("no space before that close parenthesis ')'\n" . $herecurr); + } + #goto labels aren't indented, allow a single space however if ($line=~/^.\s+[A-Za-z\d_]+:(?![0-9]+)/ and !($line=~/^. [A-Za-z\d_]+:/) and !($line=~/^.\s+default:/)) { @@ -910,7 +941,7 @@ sub process { # grabbing the statement after the identifier $prevline =~ m{^(.#\s*define\s*$Ident(?:\([^\)]*\))?\s*)(.*)\\\s*$}; ##print "1<$1> 2<$2>\n"; - if ($2 ne '') { + if (defined $2 && $2 ne '') { $off = length($1); $ln--; $cnt++; @@ -950,8 +981,10 @@ sub process { my ($lvl, @block) = ctx_block_level($nr, $cnt); my $stmt = join(' ', @block); - $stmt =~ s/^[^{]*{//; - $stmt =~ s/}[^}]*$//; + $stmt =~ s/(^[^{]*){//; + my $before = $1; + $stmt =~ s/}([^}]*$)//; + my $after = $1; #print "block<" . join(' ', @block) . "><" . scalar(@block) . ">\n"; #print "stmt<$stmt>\n\n"; @@ -963,12 +996,14 @@ sub process { # Also nested if's often require braces to # disambiguate the else binding so shhh there. my @semi = ($stmt =~ /;/g); + push(@semi, "/**/") if ($stmt =~ m@/\*@); ##print "semi<" . scalar(@semi) . ">\n"; if ($lvl == 0 && scalar(@semi) < 2 && - $stmt !~ /{/ && $stmt !~ /\bif\b/) { + $stmt !~ /{/ && $stmt !~ /\bif\b/ && + $before !~ /}/ && $after !~ /{/) { my $herectx = "$here\n" . join("\n", @control, @block[1 .. $#block]) . "\n"; shift(@block); - ERROR("braces {} are not necessary for single statement blocks\n" . $herectx); + WARN("braces {} are not necessary for single statement blocks\n" . $herectx); } } } @@ -1013,6 +1048,11 @@ sub process { # $clean = 0; # } +# warn about spacing in #ifdefs + if ($line =~ /^.#\s*(ifdef|ifndef|elif)\s\s+/) { + ERROR("exactly one space required after that #$1\n" . $herecurr); + } + # check for spinlock_t definitions without a comment. if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/) { my $which = $1; @@ -1027,14 +1067,14 @@ sub process { } } # check of hardware specific defines - if ($line =~ m@^.#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@) { + if ($line =~ m@^.#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) { CHK("architecture specific defines should be avoided\n" . $herecurr); } # check the location of the inline attribute, that it is between # storage class and type. - if ($line =~ /$Type\s+(?:inline|__always_inline)\b/ || - $line =~ /\b(?:inline|always_inline)\s+$Storage/) { + if ($line =~ /$Type\s+(?:inline|__always_inline|noinline)\b/ || + $line =~ /\b(?:inline|__always_inline|noinline)\s+$Storage/) { ERROR("inline keyword should sit between storage class and type\n" . $herecurr); } |