diff options
81 files changed, 921 insertions, 293 deletions
diff --git a/Documentation/fb/pvr2fb.txt b/Documentation/fb/pvr2fb.txt index 2bf6c2321c2..36bdeff585e 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 75b3680c41e..6c0817c4568 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 536d5bfbdb8..fe8b0c4892c 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 efdb42fd3fb..a326487a3ab 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 00000000000..5fbcc22c98e --- /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 ba328f25541..ef19142896c 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 e65e96a14be..ab483778a7f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -664,7 +664,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 diff --git a/arch/alpha/kernel/sys_titan.c b/arch/alpha/kernel/sys_titan.c index 1d3c1398c42..52c91ccc164 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 b45188f8512..673c860ffc2 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 5a51dd6ab28..6a7aefe4834 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 f5e1ae3d170..abcd14817d0 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 8766bd612b4..792a8416fe1 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 4b41248b61a..6b4d026a00a 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 275673c192a..1e74f3c5cee 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 c85598acb8f..1b66d5c70ea 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 bfc6cb7df7e..f9fff29e01a 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 c7ba455d5ac..dcf6bbb1c7c 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 265c5597efb..40978af630e 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 7c52b222207..8f0382161c9 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 ea962c0667d..739cfb207dd 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 72042bb7ec9..18673e0f193 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 8927222b3ab..4241a74d16c 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 85503deeda4..ebc6f3c6634 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 e7306dbf6c4..c82cbf4c722 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 f2cb942f828..665db063a40 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 149a9588c25..5565d7016b7 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 bb1afd9e589..0d46b7a88b3 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 adbe17a38f6..f5f165f69e0 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 e58bae2076a..8c66f275756 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 f1b486d4190..8ecb1c72259 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 9a8c1181c00..f0c37511d8d 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/x86_64/boot/compressed/head.S b/arch/x86_64/boot/compressed/head.S index 1312bfaff30..9fd8030cc54 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 900ff38d68d..925758dbca0 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 ba16c968ca3..71da01e73f0 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 7e161c698af..10b9809ce82 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 65d82736987..4095e4d66a1 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 00000000000..f8b69d84238 --- /dev/null +++ b/arch/x86_64/vdso/.gitignore @@ -0,0 +1 @@ +vdso.lds diff --git a/drivers/acpi/resources/rsxface.c b/drivers/acpi/resources/rsxface.c index f63813a358c..4c3fd4cdaf7 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/char/hvc_lguest.c b/drivers/char/hvc_lguest.c index feeccbaec43..3d6bd0baa56 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 fee58e03dbe..4177f6db83e 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 af88181a17f..b24a3e7bbb9 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 de37ebc3a4c..51ea93cab6c 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 524beea7fb1..6e135ac0834 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 55a7940ca73..9e7752cc800 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/mtd/mtdchar.c b/drivers/mtd/mtdchar.c index 8c86b802f21..d091b2430b4 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 0c16a2b39b4..2adf856e44c 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 630f781aeb1..c55459c592b 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 decfdc8eb9c..e58c87b3e3a 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 7c76e079ca7..d42346e7fdd 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 df39c319373..7a98ce8043d 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 d59577c8de8..f3107ad7e54 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 5948e54b9ef..ab7fb50bc1d 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 f9300266044..7d6c29800d1 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 c97709ecbad..e7c8db2eb49 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 52bb2638f7a..6874785bb65 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 0a50942b437..131954b3fb9 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 e557a676692..a98497264fe 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/include/asm-frv/unistd.h b/include/asm-frv/unistd.h index 7306c71a892..cd84f1771e3 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 f605e8d0eed..5f0d797d33f 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 1e8f6f252dd..4091b33dcb1 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 c961c03cf1e..7b3aa28ebc6 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 7df88be2dd9..9fa3fa9e62d 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 d790343e998..4fcacc71138 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-x86_64/pci.h b/include/asm-x86_64/pci.h index 88926eb44f5..5da8cb0c059 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/clockchips.h b/include/linux/clockchips.h index e0bd46eb241..def5a659b8a 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/init.h b/include/linux/init.h index 1a4a283d19a..74b1f43bf98 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 b4f5b81b425..f592df74b3c 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 28e3664fdf1..cd13a78c5db 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 c6b7485eac7..fe17d7d750c 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 691a1748d9d..6570719eafd 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 3e9f513a728..4b8a4493c54 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 a3b7854b8f7..a686590d88c 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 5b20fe977be..cb1e37d2dac 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 b0afd8db139..6247e4a8350 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 3da32156394..87e524762b8 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 e91db32cadf..c5af38948a1 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 79c891e6266..8bdb8c07e04 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 2ad1c37b8df..41dd3105ce7 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 16f2e2935e8..bd5edaeaa80 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 50021a60d01..90b657b50f8 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 diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 73751ab6ec0..dae7d30dca0 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); } |