diff options
583 files changed, 6257 insertions, 3663 deletions
diff --git a/Documentation/00-INDEX b/Documentation/00-INDEX index 5b5aba404aa..73060819ed9 100644 --- a/Documentation/00-INDEX +++ b/Documentation/00-INDEX @@ -251,8 +251,6 @@ mono.txt - how to execute Mono-based .NET binaries with the help of BINFMT_MISC. moxa-smartio - file with info on installing/using Moxa multiport serial driver. -mtrr.txt - - how to use PPro Memory Type Range Registers to increase performance. mutex-design.txt - info on the generic mutex subsystem. namespaces/ diff --git a/Documentation/DMA-mapping.txt b/Documentation/DMA-mapping.txt index b463ecd0c7c..c74fec8c235 100644 --- a/Documentation/DMA-mapping.txt +++ b/Documentation/DMA-mapping.txt @@ -740,7 +740,7 @@ failure can be determined by: dma_addr_t dma_handle; dma_handle = pci_map_single(pdev, addr, size, direction); - if (pci_dma_mapping_error(dma_handle)) { + if (pci_dma_mapping_error(pdev, dma_handle)) { /* * reduce current DMA mapping usage, * delay and try again later or diff --git a/Documentation/HOWTO b/Documentation/HOWTO index c2371c5a98f..48a3955f05f 100644 --- a/Documentation/HOWTO +++ b/Documentation/HOWTO @@ -77,7 +77,8 @@ documentation files are also added which explain how to use the feature. When a kernel change causes the interface that the kernel exposes to userspace to change, it is recommended that you send the information or a patch to the manual pages explaining the change to the manual pages -maintainer at mtk.manpages@gmail.com. +maintainer at mtk.manpages@gmail.com, and CC the list +linux-api@vger.kernel.org. Here is a list of files that are in the kernel source tree that are required reading: diff --git a/Documentation/SubmitChecklist b/Documentation/SubmitChecklist index da10e071424..21f0795af20 100644 --- a/Documentation/SubmitChecklist +++ b/Documentation/SubmitChecklist @@ -67,6 +67,8 @@ kernel patches. 19: All new userspace interfaces are documented in Documentation/ABI/. See Documentation/ABI/README for more information. + Patches that change userspace interfaces should be CCed to + linux-api@vger.kernel.org. 20: Check that it all passes `make headers_check'. diff --git a/Documentation/ioctl/cdrom.txt b/Documentation/ioctl/cdrom.txt index 62d4af44ec4..59df81c8da2 100644 --- a/Documentation/ioctl/cdrom.txt +++ b/Documentation/ioctl/cdrom.txt @@ -271,14 +271,14 @@ CDROMCLOSETRAY pendant of CDROMEJECT usage: - ioctl(fd, CDROMEJECT, 0); + ioctl(fd, CDROMCLOSETRAY, 0); inputs: none outputs: none error returns: - ENOSYS cd drive not capable of ejecting + ENOSYS cd drive not capable of closing the tray EBUSY other processes are accessing drive, or door is locked notes: diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 1150444a21a..329dcabe4c5 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -463,12 +463,6 @@ and is between 256 and 4096 characters. It is defined in the file Range: 0 - 8192 Default: 64 - disable_8254_timer - enable_8254_timer - [IA32/X86_64] Disable/Enable interrupt 0 timer routing - over the 8254 in addition to over the IO-APIC. The - kernel tries to set a sensible default. - hpet= [X86-32,HPET] option to control HPET usage Format: { enable (default) | disable | force } disable: disable HPET and use PIT instead @@ -1882,6 +1876,12 @@ and is between 256 and 4096 characters. It is defined in the file shapers= [NET] Maximal number of shapers. + show_msr= [x86] show boot-time MSR settings + Format: { <integer> } + Show boot-time (BIOS-initialized) MSR settings. + The parameter means the number of CPUs to show, + for example 1 means boot CPU only. + sim710= [SCSI,HW] See header of drivers/scsi/sim710.c. diff --git a/Documentation/sysctl/kernel.txt b/Documentation/sysctl/kernel.txt index 276a7e63782..e1ff0d920a5 100644 --- a/Documentation/sysctl/kernel.txt +++ b/Documentation/sysctl/kernel.txt @@ -351,9 +351,10 @@ kernel. This value defaults to SHMMAX. softlockup_thresh: -This value can be used to lower the softlockup tolerance -threshold. The default threshold is 10s. If a cpu is locked up -for 10s, the kernel complains. Valid values are 1-60s. +This value can be used to lower the softlockup tolerance threshold. The +default threshold is 60 seconds. If a cpu is locked up for 60 seconds, +the kernel complains. Valid values are 1-60 seconds. Setting this +tunable to zero will disable the softlockup detection altogether. ============================================================== diff --git a/Documentation/usb/anchors.txt b/Documentation/usb/anchors.txt index 7304bcf5a30..5e6b64c20d2 100644 --- a/Documentation/usb/anchors.txt +++ b/Documentation/usb/anchors.txt @@ -42,9 +42,21 @@ This function kills all URBs associated with an anchor. The URBs are called in the reverse temporal order they were submitted. This way no data can be reordered. +usb_unlink_anchored_urbs() +-------------------------- + +This function unlinks all URBs associated with an anchor. The URBs +are processed in the reverse temporal order they were submitted. +This is similar to usb_kill_anchored_urbs(), but it will not sleep. +Therefore no guarantee is made that the URBs have been unlinked when +the call returns. They may be unlinked later but will be unlinked in +finite time. + usb_wait_anchor_empty_timeout() ------------------------------- This function waits for all URBs associated with an anchor to finish or a timeout, whichever comes first. Its return value will tell you whether the timeout was reached. + + diff --git a/Documentation/x86/00-INDEX b/Documentation/x86/00-INDEX new file mode 100644 index 00000000000..dbe3377754a --- /dev/null +++ b/Documentation/x86/00-INDEX @@ -0,0 +1,4 @@ +00-INDEX + - this file +mtrr.txt + - how to use x86 Memory Type Range Registers to increase performance diff --git a/Documentation/x86/i386/boot.txt b/Documentation/x86/boot.txt index 147bfe511cd..83c0033ee9e 100644 --- a/Documentation/x86/i386/boot.txt +++ b/Documentation/x86/boot.txt @@ -308,7 +308,7 @@ Protocol: 2.00+ Field name: start_sys Type: read -Offset/size: 0x20c/4 +Offset/size: 0x20c/2 Protocol: 2.00+ The load low segment (0x1000). Obsolete. diff --git a/Documentation/mtrr.txt b/Documentation/x86/mtrr.txt index c39ac395970..cc071dc333c 100644 --- a/Documentation/mtrr.txt +++ b/Documentation/x86/mtrr.txt @@ -18,7 +18,7 @@ Richard Gooch The AMD K6-2 (stepping 8 and above) and K6-3 processors have two MTRRs. These are supported. The AMD Athlon family provide 8 Intel style MTRRs. - + The Centaur C6 (WinChip) has 8 MCRs, allowing write-combining. These are supported. @@ -87,7 +87,7 @@ reg00: base=0x00000000 ( 0MB), size= 64MB: write-back, count=1 reg01: base=0xfb000000 (4016MB), size= 16MB: write-combining, count=1 reg02: base=0xfb000000 (4016MB), size= 4kB: uncachable, count=1 -Some cards (especially Voodoo Graphics boards) need this 4 kB area +Some cards (especially Voodoo Graphics boards) need this 4 kB area excluded from the beginning of the region because it is used for registers. diff --git a/Documentation/x86/pat.txt b/Documentation/x86/pat.txt index 17965f927c1..c93ff5f4c0d 100644 --- a/Documentation/x86/pat.txt +++ b/Documentation/x86/pat.txt @@ -14,6 +14,10 @@ PAT allows for different types of memory attributes. The most commonly used ones that will be supported at this time are Write-back, Uncached, Write-combined and Uncached Minus. + +PAT APIs +-------- + There are many different APIs in the kernel that allows setting of memory attributes at the page level. In order to avoid aliasing, these interfaces should be used thoughtfully. Below is a table of interfaces available, @@ -26,38 +30,38 @@ address range to avoid any aliasing. API | RAM | ACPI,... | Reserved/Holes | -----------------------|----------|------------|------------------| | | | | -ioremap | -- | UC | UC | +ioremap | -- | UC- | UC- | | | | | ioremap_cache | -- | WB | WB | | | | | -ioremap_nocache | -- | UC | UC | +ioremap_nocache | -- | UC- | UC- | | | | | ioremap_wc | -- | -- | WC | | | | | -set_memory_uc | UC | -- | -- | +set_memory_uc | UC- | -- | -- | set_memory_wb | | | | | | | | set_memory_wc | WC | -- | -- | set_memory_wb | | | | | | | | -pci sysfs resource | -- | -- | UC | +pci sysfs resource | -- | -- | UC- | | | | | pci sysfs resource_wc | -- | -- | WC | is IORESOURCE_PREFETCH| | | | | | | | -pci proc | -- | -- | UC | +pci proc | -- | -- | UC- | !PCIIOC_WRITE_COMBINE | | | | | | | | pci proc | -- | -- | WC | PCIIOC_WRITE_COMBINE | | | | | | | | -/dev/mem | -- | UC | UC | +/dev/mem | -- | WB/WC/UC- | WB/WC/UC- | read-write | | | | | | | | -/dev/mem | -- | UC | UC | +/dev/mem | -- | UC- | UC- | mmap SYNC flag | | | | | | | | -/dev/mem | -- | WB/WC/UC | WB/WC/UC | +/dev/mem | -- | WB/WC/UC- | WB/WC/UC- | mmap !SYNC flag | |(from exist-| (from exist- | and | | ing alias)| ing alias) | any alias to this area| | | | @@ -68,7 +72,7 @@ pci proc | -- | -- | WC | and | | | | MTRR says WB | | | | | | | | -/dev/mem | -- | -- | UC_MINUS | +/dev/mem | -- | -- | UC- | mmap !SYNC flag | | | | no alias to this area | | | | and | | | | @@ -98,3 +102,35 @@ types. Drivers should use set_memory_[uc|wc] to set access type for RAM ranges. + +PAT debugging +------------- + +With CONFIG_DEBUG_FS enabled, PAT memtype list can be examined by + +# mount -t debugfs debugfs /sys/kernel/debug +# cat /sys/kernel/debug/x86/pat_memtype_list +PAT memtype list: +uncached-minus @ 0x7fadf000-0x7fae0000 +uncached-minus @ 0x7fb19000-0x7fb1a000 +uncached-minus @ 0x7fb1a000-0x7fb1b000 +uncached-minus @ 0x7fb1b000-0x7fb1c000 +uncached-minus @ 0x7fb1c000-0x7fb1d000 +uncached-minus @ 0x7fb1d000-0x7fb1e000 +uncached-minus @ 0x7fb1e000-0x7fb25000 +uncached-minus @ 0x7fb25000-0x7fb26000 +uncached-minus @ 0x7fb26000-0x7fb27000 +uncached-minus @ 0x7fb27000-0x7fb28000 +uncached-minus @ 0x7fb28000-0x7fb2e000 +uncached-minus @ 0x7fb2e000-0x7fb2f000 +uncached-minus @ 0x7fb2f000-0x7fb30000 +uncached-minus @ 0x7fb31000-0x7fb32000 +uncached-minus @ 0x80000000-0x90000000 + +This list shows physical address ranges and various PAT settings used to +access those physical address ranges. + +Another, more verbose way of getting PAT related debug messages is with +"debugpat" boot parameter. With this parameter, various debug messages are +printed to dmesg log. + diff --git a/Documentation/x86/i386/usb-legacy-support.txt b/Documentation/x86/usb-legacy-support.txt index 1894cdfc69d..1894cdfc69d 100644 --- a/Documentation/x86/i386/usb-legacy-support.txt +++ b/Documentation/x86/usb-legacy-support.txt diff --git a/Documentation/x86/x86_64/boot-options.txt b/Documentation/x86/x86_64/boot-options.txt index b0c7b6c4abd..72ffb5373ec 100644 --- a/Documentation/x86/x86_64/boot-options.txt +++ b/Documentation/x86/x86_64/boot-options.txt @@ -54,10 +54,6 @@ APICs apicmaintimer. Useful when your PIT timer is totally broken. - disable_8254_timer / enable_8254_timer - Enable interrupt 0 timer routing over the 8254 in addition to over - the IO-APIC. The kernel tries to set a sensible default. - Early Console syntax: earlyprintk=vga diff --git a/Documentation/x86/i386/zero-page.txt b/Documentation/x86/zero-page.txt index 169ad423a3d..169ad423a3d 100644 --- a/Documentation/x86/i386/zero-page.txt +++ b/Documentation/x86/zero-page.txt diff --git a/MAINTAINERS b/MAINTAINERS index cad81a24e83..8dae4555f10 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1198,9 +1198,7 @@ M: hpa@zytor.com S: Maintained CPUSETS -P: Paul Jackson P: Paul Menage -M: pj@sgi.com M: menage@google.com L: linux-kernel@vger.kernel.org W: http://www.bullopensource.org/cpuset/ @@ -1984,7 +1982,7 @@ S: Maintained I2C/SMBUS STUB DRIVER P: Mark M. Hoffman M: mhoffman@lightlink.com -L: lm-sensors@lm-sensors.org +L: i2c@lm-sensors.org S: Maintained I2C SUBSYSTEM @@ -2706,6 +2704,7 @@ MAN-PAGES: MANUAL PAGES FOR LINUX -- Sections 2, 3, 4, 5, and 7 P: Michael Kerrisk M: mtk.manpages@gmail.com W: http://www.kernel.org/doc/man-pages +L: linux-man@vger.kernel.org S: Supported MARVELL LIBERTAS WIRELESS DRIVER @@ -3726,7 +3725,7 @@ S: Maintained SIS 96X I2C/SMBUS DRIVER P: Mark M. Hoffman M: mhoffman@lightlink.com -L: lm-sensors@lm-sensors.org +L: i2c@lm-sensors.org S: Maintained SIS FRAMEBUFFER DRIVER @@ -3833,11 +3832,12 @@ S: Maintained SOUND - SOC LAYER / DYNAMIC AUDIO POWER MANAGEMENT P: Liam Girdwood -M: liam.girdwood@wolfsonmicro.com +M: lrg@slimlogic.co.uk P: Mark Brown M: broonie@opensource.wolfsonmicro.com T: git opensource.wolfsonmicro.com/linux-2.6-asoc L: alsa-devel@alsa-project.org (subscribers-only) +W: http://alsa-project.org/main/index.php/ASoC S: Supported SPI SUBSYSTEM @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 27 -EXTRAVERSION = -rc7 +EXTRAVERSION = -rc8 NAME = Rotary Wombat # *DOCUMENTATION* diff --git a/arch/arm/kernel/kgdb.c b/arch/arm/kernel/kgdb.c index aaffaecffcd..ba8ccfede96 100644 --- a/arch/arm/kernel/kgdb.c +++ b/arch/arm/kernel/kgdb.c @@ -111,8 +111,6 @@ int kgdb_arch_handle_exception(int exception_vector, int signo, case 'D': case 'k': case 'c': - kgdb_contthread = NULL; - /* * Try to read optional parameter, pc unchanged if no parm. * If this was a compiled breakpoint, we need to move diff --git a/arch/arm/mach-pxa/time.c b/arch/arm/mach-pxa/time.c index 67e18509d7b..b0d6b32654c 100644 --- a/arch/arm/mach-pxa/time.c +++ b/arch/arm/mach-pxa/time.c @@ -17,9 +17,9 @@ #include <linux/interrupt.h> #include <linux/clockchips.h> #include <linux/sched.h> +#include <linux/cnt32_to_63.h> #include <asm/div64.h> -#include <asm/cnt32_to_63.h> #include <asm/mach/irq.h> #include <asm/mach/time.h> #include <mach/pxa-regs.h> diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c index 1362994c78a..b422526f6d8 100644 --- a/arch/arm/mach-sa1100/generic.c +++ b/arch/arm/mach-sa1100/generic.c @@ -18,9 +18,9 @@ #include <linux/ioport.h> #include <linux/sched.h> /* just for sched_clock() - funny that */ #include <linux/platform_device.h> +#include <linux/cnt32_to_63.h> #include <asm/div64.h> -#include <asm/cnt32_to_63.h> #include <mach/hardware.h> #include <asm/system.h> #include <asm/pgtable.h> diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c index d75e795c893..b638f10411e 100644 --- a/arch/arm/mach-versatile/core.c +++ b/arch/arm/mach-versatile/core.c @@ -28,8 +28,8 @@ #include <linux/amba/clcd.h> #include <linux/clocksource.h> #include <linux/clockchips.h> +#include <linux/cnt32_to_63.h> -#include <asm/cnt32_to_63.h> #include <asm/system.h> #include <mach/hardware.h> #include <asm/io.h> diff --git a/arch/ia64/include/asm/sections.h b/arch/ia64/include/asm/sections.h index f6679989103..1a873b36a4a 100644 --- a/arch/ia64/include/asm/sections.h +++ b/arch/ia64/include/asm/sections.h @@ -11,6 +11,9 @@ #include <asm-generic/sections.h> extern char __per_cpu_start[], __per_cpu_end[], __phys_per_cpu_start[]; +#ifdef CONFIG_SMP +extern char __cpu0_per_cpu[]; +#endif extern char __start___vtop_patchlist[], __end___vtop_patchlist[]; extern char __start___rse_patchlist[], __end___rse_patchlist[]; extern char __start___mckinley_e9_bundles[], __end___mckinley_e9_bundles[]; diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c index d45f215bc8f..51b75cea701 100644 --- a/arch/ia64/kernel/efi.c +++ b/arch/ia64/kernel/efi.c @@ -1232,9 +1232,10 @@ efi_initialize_iomem_resources(struct resource *code_resource, if (md->attribute & EFI_MEMORY_WP) { name = "System ROM"; flags |= IORESOURCE_READONLY; - } else { + } else if (md->attribute == EFI_MEMORY_UC) + name = "Uncached RAM"; + else name = "System RAM"; - } break; case EFI_ACPI_MEMORY_NVS: diff --git a/arch/ia64/kernel/head.S b/arch/ia64/kernel/head.S index 8bdea8eb62e..66e491d8baa 100644 --- a/arch/ia64/kernel/head.S +++ b/arch/ia64/kernel/head.S @@ -367,16 +367,17 @@ start_ap: ;; #else (isAP) br.few 2f - mov r20=r19 - sub r19=r19,r18 + movl r20=__cpu0_per_cpu ;; shr.u r18=r18,3 1: - ld8 r21=[r20],8;; - st8[r19]=r21,8 + ld8 r21=[r19],8;; + st8[r20]=r21,8 adds r18=-1,r18;; cmp4.lt p7,p6=0,r18 (p7) br.cond.dptk.few 1b + mov r19=r20 + ;; 2: #endif tpa r19=r19 diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c index c27d5b2c182..de636b21567 100644 --- a/arch/ia64/kernel/setup.c +++ b/arch/ia64/kernel/setup.c @@ -616,7 +616,9 @@ setup_arch (char **cmdline_p) ia64_mca_init(); platform_setup(cmdline_p); +#ifndef CONFIG_IA64_HP_SIM check_sal_cache_flush(); +#endif paging_init(); } diff --git a/arch/ia64/kernel/vmlinux.lds.S b/arch/ia64/kernel/vmlinux.lds.S index de71da811cd..10a7d47e851 100644 --- a/arch/ia64/kernel/vmlinux.lds.S +++ b/arch/ia64/kernel/vmlinux.lds.S @@ -215,9 +215,6 @@ SECTIONS /* Per-cpu data: */ percpu : { } :percpu . = ALIGN(PERCPU_PAGE_SIZE); -#ifdef CONFIG_SMP - . = . + PERCPU_PAGE_SIZE; /* cpu0 per-cpu space */ -#endif __phys_per_cpu_start = .; .data.percpu PERCPU_ADDR : AT(__phys_per_cpu_start - LOAD_OFFSET) { @@ -233,6 +230,11 @@ SECTIONS data : { } :data .data : AT(ADDR(.data) - LOAD_OFFSET) { +#ifdef CONFIG_SMP + . = ALIGN(PERCPU_PAGE_SIZE); + __cpu0_per_cpu = .; + . = . + PERCPU_PAGE_SIZE; /* cpu0 per-cpu space */ +#endif DATA_DATA *(.data1) *(.gnu.linkonce.d*) diff --git a/arch/ia64/mm/contig.c b/arch/ia64/mm/contig.c index e566ff43884..0ee085efbe2 100644 --- a/arch/ia64/mm/contig.c +++ b/arch/ia64/mm/contig.c @@ -163,7 +163,7 @@ per_cpu_init (void) * get_zeroed_page(). */ if (first_time) { - void *cpu0_data = __phys_per_cpu_start - PERCPU_PAGE_SIZE; + void *cpu0_data = __cpu0_per_cpu; first_time=0; diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c index 78026aabaa7..d8c5fcd89e5 100644 --- a/arch/ia64/mm/discontig.c +++ b/arch/ia64/mm/discontig.c @@ -144,7 +144,7 @@ static void *per_cpu_node_setup(void *cpu_data, int node) for_each_possible_early_cpu(cpu) { if (cpu == 0) { - void *cpu0_data = __phys_per_cpu_start - PERCPU_PAGE_SIZE; + void *cpu0_data = __cpu0_per_cpu; __per_cpu_offset[cpu] = (char*)cpu0_data - __per_cpu_start; } else if (node == node_cpuid[cpu].nid) { diff --git a/arch/m32r/Kconfig b/arch/m32r/Kconfig index a5f864c445b..f57113f1f89 100644 --- a/arch/m32r/Kconfig +++ b/arch/m32r/Kconfig @@ -216,10 +216,6 @@ config MEMORY_SIZE default "01000000" if PLAT_M32104UT default "00800000" if PLAT_OAKS32R -config NOHIGHMEM - bool - default y - config ARCH_DISCONTIGMEM_ENABLE bool "Internal RAM Support" depends on CHIP_M32700 || CHIP_M32102 || CHIP_VDEC2 || CHIP_OPSP || CHIP_M32104 @@ -410,11 +406,7 @@ config PCI_DIRECT source "drivers/pci/Kconfig" config ISA - bool "ISA support" - help - Find out whether you have ISA slots on your motherboard. ISA is the - name of a bus system, i.e. the way the CPU talks to the other stuff - inside your box. If you have ISA, say Y, otherwise N. + bool source "drivers/pcmcia/Kconfig" diff --git a/arch/m32r/kernel/entry.S b/arch/m32r/kernel/entry.S index d4eaa2fd181..612d35b082a 100644 --- a/arch/m32r/kernel/entry.S +++ b/arch/m32r/kernel/entry.S @@ -143,7 +143,7 @@ ret_from_intr: and3 r4, r4, #0x8000 ; check BSM bit #endif beqz r4, resume_kernel -ENTRY(resume_userspace) +resume_userspace: DISABLE_INTERRUPTS(r4) ; make sure we don't miss an interrupt ; setting need_resched or sigpending ; between sampling and the iret diff --git a/arch/m32r/kernel/head.S b/arch/m32r/kernel/head.S index dab7436d7bb..40180778a5c 100644 --- a/arch/m32r/kernel/head.S +++ b/arch/m32r/kernel/head.S @@ -29,7 +29,6 @@ __INITDATA .global _end ENTRY(stext) ENTRY(_stext) -ENTRY(startup_32) /* Setup up the stack pointer */ LDIMM (r0, spi_stack_top) LDIMM (r1, spu_stack_top) diff --git a/arch/m32r/kernel/irq.c b/arch/m32r/kernel/irq.c index d0c5b0b7da2..2aeae467009 100644 --- a/arch/m32r/kernel/irq.c +++ b/arch/m32r/kernel/irq.c @@ -22,9 +22,6 @@ #include <linux/module.h> #include <asm/uaccess.h> -atomic_t irq_err_count; -atomic_t irq_mis_count; - /* * Generic, controller-independent functions: */ @@ -63,9 +60,6 @@ int show_interrupts(struct seq_file *p, void *v) seq_putc(p, '\n'); skip: spin_unlock_irqrestore(&irq_desc[i].lock, flags); - } else if (i == NR_IRQS) { - seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count)); - seq_printf(p, "MIS: %10u\n", atomic_read(&irq_mis_count)); } return 0; } diff --git a/arch/m32r/kernel/m32r_ksyms.c b/arch/m32r/kernel/m32r_ksyms.c index 16bcb189a38..22624b51d4d 100644 --- a/arch/m32r/kernel/m32r_ksyms.c +++ b/arch/m32r/kernel/m32r_ksyms.c @@ -14,6 +14,7 @@ #include <asm/delay.h> #include <asm/irq.h> #include <asm/tlbflush.h> +#include <asm/pgtable.h> /* platform dependent support */ EXPORT_SYMBOL(boot_cpu_data); @@ -65,6 +66,7 @@ EXPORT_SYMBOL(memset); EXPORT_SYMBOL(copy_page); EXPORT_SYMBOL(clear_page); EXPORT_SYMBOL(strlen); +EXPORT_SYMBOL(empty_zero_page); EXPORT_SYMBOL(_inb); EXPORT_SYMBOL(_inw); diff --git a/arch/m32r/kernel/process.c b/arch/m32r/kernel/process.c index a689e2978b6..5be4faaf5b1 100644 --- a/arch/m32r/kernel/process.c +++ b/arch/m32r/kernel/process.c @@ -35,8 +35,6 @@ #include <linux/err.h> -static int hlt_counter=0; - /* * Return saved PC of a blocked thread. */ @@ -48,31 +46,16 @@ unsigned long thread_saved_pc(struct task_struct *tsk) /* * Powermanagement idle function, if any.. */ -void (*pm_idle)(void) = NULL; -EXPORT_SYMBOL(pm_idle); +static void (*pm_idle)(void) = NULL; void (*pm_power_off)(void) = NULL; EXPORT_SYMBOL(pm_power_off); -void disable_hlt(void) -{ - hlt_counter++; -} - -EXPORT_SYMBOL(disable_hlt); - -void enable_hlt(void) -{ - hlt_counter--; -} - -EXPORT_SYMBOL(enable_hlt); - /* * We use this is we don't have any better * idle routine.. */ -void default_idle(void) +static void default_idle(void) { /* M32R_FIXME: Please use "cpu_sleep" mode. */ cpu_relax(); @@ -260,15 +243,6 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long spu, return 0; } -/* - * Capture the user space registers if the task is not running (in user space) - */ -int dump_task_regs(struct task_struct *tsk, elf_gregset_t *regs) -{ - /* M32R_FIXME */ - return 1; -} - asmlinkage int sys_fork(unsigned long r0, unsigned long r1, unsigned long r2, unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, struct pt_regs regs) diff --git a/arch/m32r/kernel/smp.c b/arch/m32r/kernel/smp.c index 7577f971ea4..929e5c9d3ad 100644 --- a/arch/m32r/kernel/smp.c +++ b/arch/m32r/kernel/smp.c @@ -84,7 +84,7 @@ void smp_send_timer(void); void smp_ipi_timer_interrupt(struct pt_regs *); void smp_local_timer_interrupt(void); -void send_IPI_allbutself(int, int); +static void send_IPI_allbutself(int, int); static void send_IPI_mask(cpumask_t, int, int); unsigned long send_IPI_mask_phys(cpumask_t, int, int); @@ -722,7 +722,7 @@ void smp_local_timer_interrupt(void) * ---------- --- -------------------------------------------------------- * *==========================================================================*/ -void send_IPI_allbutself(int ipi_num, int try) +static void send_IPI_allbutself(int ipi_num, int try) { cpumask_t cpumask; diff --git a/arch/m32r/kernel/time.c b/arch/m32r/kernel/time.c index 994cc155635..6ea017727cc 100644 --- a/arch/m32r/kernel/time.c +++ b/arch/m32r/kernel/time.c @@ -34,7 +34,6 @@ #include <asm/hw_irq.h> #ifdef CONFIG_SMP -extern void send_IPI_allbutself(int, int); extern void smp_local_timer_interrupt(void); #endif @@ -188,7 +187,7 @@ static long last_rtc_update = 0; * timer_interrupt() needs to keep up the real-time clock, * as well as call the "do_timer()" routine every clocktick */ -irqreturn_t timer_interrupt(int irq, void *dev_id) +static irqreturn_t timer_interrupt(int irq, void *dev_id) { #ifndef CONFIG_SMP profile_tick(CPU_PROFILING); @@ -228,7 +227,7 @@ irqreturn_t timer_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } -struct irqaction irq0 = { +static struct irqaction irq0 = { .handler = timer_interrupt, .flags = IRQF_DISABLED, .mask = CPU_MASK_NONE, diff --git a/arch/m32r/kernel/traps.c b/arch/m32r/kernel/traps.c index 46159a4e644..03b14e55cd8 100644 --- a/arch/m32r/kernel/traps.c +++ b/arch/m32r/kernel/traps.c @@ -61,7 +61,7 @@ extern unsigned long eit_vector[]; ((unsigned long)func - (unsigned long)eit_vector - entry*4)/4 \ + 0xff000000UL -void set_eit_vector_entries(void) +static void set_eit_vector_entries(void) { extern void default_eit_handler(void); extern void system_call(void); @@ -121,9 +121,9 @@ void __init trap_init(void) cpu_init(); } -int kstack_depth_to_print = 24; +static int kstack_depth_to_print = 24; -void show_trace(struct task_struct *task, unsigned long *stack) +static void show_trace(struct task_struct *task, unsigned long *stack) { unsigned long addr; @@ -224,7 +224,7 @@ bad: printk("\n"); } -DEFINE_SPINLOCK(die_lock); +static DEFINE_SPINLOCK(die_lock); void die(const char * str, struct pt_regs * regs, long err) { diff --git a/arch/m32r/lib/delay.c b/arch/m32r/lib/delay.c index 59bfc34e0d9..ced549be80f 100644 --- a/arch/m32r/lib/delay.c +++ b/arch/m32r/lib/delay.c @@ -6,6 +6,7 @@ */ #include <linux/param.h> +#include <linux/module.h> #ifdef CONFIG_SMP #include <linux/sched.h> #include <asm/current.h> @@ -121,3 +122,4 @@ void __ndelay(unsigned long nsecs) { __const_udelay(nsecs * 0x00005); /* 2**32 / 1000000000 (rounded up) */ } +EXPORT_SYMBOL(__ndelay); diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 49896a2a1d7..c930b8ceb41 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -1403,7 +1403,6 @@ config MIPS_MT_SMTC depends on CPU_MIPS32_R2 #depends on CPU_MIPS64_R2 # once there is hardware ... depends on SYS_SUPPORTS_MULTITHREADING - select GENERIC_CLOCKEVENTS_BROADCAST select CPU_MIPSR2_IRQ_VI select CPU_MIPSR2_IRQ_EI select MIPS_MT @@ -1451,32 +1450,17 @@ config MIPS_VPE_LOADER Includes a loader for loading an elf relocatable object onto another VPE and running it. -config MIPS_MT_SMTC_INSTANT_REPLAY - bool "Low-latency Dispatch of Deferred SMTC IPIs" - depends on MIPS_MT_SMTC && !PREEMPT - default y - help - SMTC pseudo-interrupts between TCs are deferred and queued - if the target TC is interrupt-inhibited (IXMT). In the first - SMTC prototypes, these queued IPIs were serviced on return - to user mode, or on entry into the kernel idle loop. The - INSTANT_REPLAY option dispatches them as part of local_irq_restore() - processing, which adds runtime overhead (hence the option to turn - it off), but ensures that IPIs are handled promptly even under - heavy I/O interrupt load. - config MIPS_MT_SMTC_IM_BACKSTOP bool "Use per-TC register bits as backstop for inhibited IM bits" depends on MIPS_MT_SMTC - default y + default n help To support multiple TC microthreads acting as "CPUs" within a VPE, VPE-wide interrupt mask bits must be specially manipulated during interrupt handling. To support legacy drivers and interrupt controller management code, SMTC has a "backstop" to track and if necessary restore the interrupt mask. This has some performance - impact on interrupt service overhead. Disable it only if you know - what you are doing. + impact on interrupt service overhead. config MIPS_MT_SMTC_IRQAFF bool "Support IRQ affinity API" @@ -1486,10 +1470,8 @@ config MIPS_MT_SMTC_IRQAFF Enables SMP IRQ affinity API (/proc/irq/*/smp_affinity, etc.) for SMTC Linux kernel. Requires platform support, of which an example can be found in the MIPS kernel i8259 and Malta - platform code. It is recommended that MIPS_MT_SMTC_INSTANT_REPLAY - be enabled if MIPS_MT_SMTC_IRQAFF is used. Adds overhead to - interrupt dispatch, and should be used only if you know what - you are doing. + platform code. Adds some overhead to interrupt dispatch, and + should be used only if you know what you are doing. config MIPS_VPE_LOADER_TOM bool "Load VPE program into memory hidden from linux" diff --git a/arch/mips/au1000/common/gpio.c b/arch/mips/au1000/common/gpio.c index b485d94ce8a..e660ddd611c 100644 --- a/arch/mips/au1000/common/gpio.c +++ b/arch/mips/au1000/common/gpio.c @@ -48,7 +48,7 @@ static void au1xxx_gpio2_write(unsigned gpio, int value) { gpio -= AU1XXX_GPIO_BASE; - gpio2->output = (GPIO2_OUTPUT_ENABLE_MASK << gpio) | (value << gpio); + gpio2->output = (GPIO2_OUTPUT_ENABLE_MASK << gpio) | ((!!value) << gpio); } static int au1xxx_gpio2_direction_input(unsigned gpio) @@ -61,7 +61,8 @@ static int au1xxx_gpio2_direction_input(unsigned gpio) static int au1xxx_gpio2_direction_output(unsigned gpio, int value) { gpio -= AU1XXX_GPIO_BASE; - gpio2->dir = (0x01 << gpio) | (value << gpio); + gpio2->dir |= 0x01 << gpio; + gpio2->output = (GPIO2_OUTPUT_ENABLE_MASK << gpio) | ((!!value) << gpio); return 0; } @@ -90,6 +91,7 @@ static int au1xxx_gpio1_direction_input(unsigned gpio) static int au1xxx_gpio1_direction_output(unsigned gpio, int value) { gpio1->trioutclr = (0x01 & gpio); + au1xxx_gpio1_write(gpio, value); return 0; } diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index 706f9397479..25775cb5400 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile @@ -10,6 +10,7 @@ obj-y += cpu-probe.o branch.o entry.o genex.o irq.o process.o \ obj-$(CONFIG_CEVT_BCM1480) += cevt-bcm1480.o obj-$(CONFIG_CEVT_R4K) += cevt-r4k.o +obj-$(CONFIG_MIPS_MT_SMTC) += cevt-smtc.o obj-$(CONFIG_CEVT_DS1287) += cevt-ds1287.o obj-$(CONFIG_CEVT_GT641XX) += cevt-gt641xx.o obj-$(CONFIG_CEVT_SB1250) += cevt-sb1250.o diff --git a/arch/mips/kernel/cevt-r4k.c b/arch/mips/kernel/cevt-r4k.c index 24a2d907aa0..4a4c59f2737 100644 --- a/arch/mips/kernel/cevt-r4k.c +++ b/arch/mips/kernel/cevt-r4k.c @@ -12,6 +12,14 @@ #include <asm/smtc_ipi.h> #include <asm/time.h> +#include <asm/cevt-r4k.h> + +/* + * The SMTC Kernel for the 34K, 1004K, et. al. replaces several + * of these routines with SMTC-specific variants. + */ + +#ifndef CONFIG_MIPS_MT_SMTC static int mips_next_event(unsigned long delta, struct clock_event_device *evt) @@ -19,60 +27,27 @@ static int mips_next_event(unsigned long delta, unsigned int cnt; int res; -#ifdef CONFIG_MIPS_MT_SMTC - { - unsigned long flags, vpflags; - local_irq_save(flags); - vpflags = dvpe(); -#endif cnt = read_c0_count(); cnt += delta; write_c0_compare(cnt); res = ((int)(read_c0_count() - cnt) > 0) ? -ETIME : 0; -#ifdef CONFIG_MIPS_MT_SMTC - evpe(vpflags); - local_irq_restore(flags); - } -#endif return res; } -static void mips_set_mode(enum clock_event_mode mode, - struct clock_event_device *evt) +#endif /* CONFIG_MIPS_MT_SMTC */ + +void mips_set_clock_mode(enum clock_event_mode mode, + struct clock_event_device *evt) { /* Nothing to do ... */ } -static DEFINE_PER_CPU(struct clock_event_device, mips_clockevent_device); -static int cp0_timer_irq_installed; +DEFINE_PER_CPU(struct clock_event_device, mips_clockevent_device); +int cp0_timer_irq_installed; -/* - * Timer ack for an R4k-compatible timer of a known frequency. - */ -static void c0_timer_ack(void) -{ - write_c0_compare(read_c0_compare()); -} +#ifndef CONFIG_MIPS_MT_SMTC -/* - * Possibly handle a performance counter interrupt. - * Return true if the timer interrupt should not be checked - */ -static inline int handle_perf_irq(int r2) -{ - /* - * The performance counter overflow interrupt may be shared with the - * timer interrupt (cp0_perfcount_irq < 0). If it is and a - * performance counter has overflowed (perf_irq() == IRQ_HANDLED) - * and we can't reliably determine if a counter interrupt has also - * happened (!r2) then don't check for a timer interrupt. - */ - return (cp0_perfcount_irq < 0) && - perf_irq() == IRQ_HANDLED && - !r2; -} - -static irqreturn_t c0_compare_interrupt(int irq, void *dev_id) +irqreturn_t c0_compare_interrupt(int irq, void *dev_id) { const int r2 = cpu_has_mips_r2; struct clock_event_device *cd; @@ -93,12 +68,8 @@ static irqreturn_t c0_compare_interrupt(int irq, void *dev_id) * interrupt. Being the paranoiacs we are we check anyway. */ if (!r2 || (read_c0_cause() & (1 << 30))) { - c0_timer_ack(); -#ifdef CONFIG_MIPS_MT_SMTC - if (cpu_data[cpu].vpe_id) - goto out; - cpu = 0; -#endif + /* Clear Count/Compare Interrupt */ + write_c0_compare(read_c0_compare()); cd = &per_cpu(mips_clockevent_device, cpu); cd->event_handler(cd); } @@ -107,65 +78,16 @@ out: return IRQ_HANDLED; } -static struct irqaction c0_compare_irqaction = { +#endif /* Not CONFIG_MIPS_MT_SMTC */ + +struct irqaction c0_compare_irqaction = { .handler = c0_compare_interrupt, -#ifdef CONFIG_MIPS_MT_SMTC - .flags = IRQF_DISABLED, -#else .flags = IRQF_DISABLED | IRQF_PERCPU, -#endif .name = "timer", }; -#ifdef CONFIG_MIPS_MT_SMTC -DEFINE_PER_CPU(struct clock_event_device, smtc_dummy_clockevent_device); - -static void smtc_set_mode(enum clock_event_mode mode, - struct clock_event_device *evt) -{ -} - -static void mips_broadcast(cpumask_t mask) -{ - unsigned int cpu; - - for_each_cpu_mask(cpu, mask) - smtc_send_ipi(cpu, SMTC_CLOCK_TICK, 0); -} - -static void setup_smtc_dummy_clockevent_device(void) -{ - //uint64_t mips_freq = mips_hpt_^frequency; - unsigned int cpu = smp_processor_id(); - struct clock_event_device *cd; - cd = &per_cpu(smtc_dummy_clockevent_device, cpu); - - cd->name = "SMTC"; - cd->features = CLOCK_EVT_FEAT_DUMMY; - - /* Calculate the min / max delta */ - cd->mult = 0; //div_sc((unsigned long) mips_freq, NSEC_PER_SEC, 32); - cd->shift = 0; //32; - cd->max_delta_ns = 0; //clockevent_delta2ns(0x7fffffff, cd); - cd->min_delta_ns = 0; //clockevent_delta2ns(0x30, cd); - - cd->rating = 200; - cd->irq = 17; //-1; -// if (cpu) -// cd->cpumask = CPU_MASK_ALL; // cpumask_of_cpu(cpu); -// else - cd->cpumask = cpumask_of_cpu(cpu); - - cd->set_mode = smtc_set_mode; - - cd->broadcast = mips_broadcast; - - clockevents_register_device(cd); -} -#endif - -static void mips_event_handler(struct clock_event_device *dev) +void mips_event_handler(struct clock_event_device *dev) { } @@ -177,7 +99,23 @@ static int c0_compare_int_pending(void) return (read_c0_cause() >> cp0_compare_irq) & 0x100; } -static int c0_compare_int_usable(void) +/* + * Compare interrupt can be routed and latched outside the core, + * so a single execution hazard barrier may not be enough to give + * it time to clear as seen in the Cause register. 4 time the + * pipeline depth seems reasonably conservative, and empirically + * works better in configurations with high CPU/bus clock ratios. + */ + +#define compare_change_hazard() \ + do { \ + irq_disable_hazard(); \ + irq_disable_hazard(); \ + irq_disable_hazard(); \ + irq_disable_hazard(); \ + } while (0) + +int c0_compare_int_usable(void) { unsigned int delta; unsigned int cnt; @@ -187,7 +125,7 @@ static int c0_compare_int_usable(void) */ if (c0_compare_int_pending()) { write_c0_compare(read_c0_count()); - irq_disable_hazard(); + compare_change_hazard(); if (c0_compare_int_pending()) return 0; } @@ -196,7 +134,7 @@ static int c0_compare_int_usable(void) cnt = read_c0_count(); cnt += delta; write_c0_compare(cnt); - irq_disable_hazard(); + compare_change_hazard(); if ((int)(read_c0_count() - cnt) < 0) break; /* increase delta if the timer was already expired */ @@ -205,11 +143,12 @@ static int c0_compare_int_usable(void) while ((int)(read_c0_count() - cnt) <= 0) ; /* Wait for expiry */ + compare_change_hazard(); if (!c0_compare_int_pending()) return 0; write_c0_compare(read_c0_count()); - irq_disable_hazard(); + compare_change_hazard(); if (c0_compare_int_pending()) return 0; @@ -219,6 +158,8 @@ static int c0_compare_int_usable(void) return 1; } +#ifndef CONFIG_MIPS_MT_SMTC + int __cpuinit mips_clockevent_init(void) { uint64_t mips_freq = mips_hpt_frequency; @@ -229,17 +170,6 @@ int __cpuinit mips_clockevent_init(void) if (!cpu_has_counter || !mips_hpt_frequency) return -ENXIO; -#ifdef CONFIG_MIPS_MT_SMTC - setup_smtc_dummy_clockevent_device(); - - /* - * On SMTC we only register VPE0's compare interrupt as clockevent - * device. - */ - if (cpu) - return 0; -#endif - if (!c0_compare_int_usable()) return -ENXIO; @@ -265,13 +195,9 @@ int __cpuinit mips_clockevent_init(void) cd->rating = 300; cd->irq = irq; -#ifdef CONFIG_MIPS_MT_SMTC - cd->cpumask = CPU_MASK_ALL; -#else cd->cpumask = cpumask_of_cpu(cpu); -#endif cd->set_next_event = mips_next_event; - cd->set_mode = mips_set_mode; + cd->set_mode = mips_set_clock_mode; cd->event_handler = mips_event_handler; clockevents_register_device(cd); @@ -281,12 +207,9 @@ int __cpuinit mips_clockevent_init(void) cp0_timer_irq_installed = 1; -#ifdef CONFIG_MIPS_MT_SMTC -#define CPUCTR_IMASKBIT (0x100 << cp0_compare_irq) - setup_irq_smtc(irq, &c0_compare_irqaction, CPUCTR_IMASKBIT); -#else setup_irq(irq, &c0_compare_irqaction); -#endif return 0; } + +#endif /* Not CONFIG_MIPS_MT_SMTC */ diff --git a/arch/mips/kernel/cevt-smtc.c b/arch/mips/kernel/cevt-smtc.c new file mode 100644 index 00000000000..5162fe4b595 --- /dev/null +++ b/arch/mips/kernel/cevt-smtc.c @@ -0,0 +1,321 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2007 MIPS Technologies, Inc. + * Copyright (C) 2007 Ralf Baechle <ralf@linux-mips.org> + * Copyright (C) 2008 Kevin D. Kissell, Paralogos sarl + */ +#include <linux/clockchips.h> +#include <linux/interrupt.h> +#include <linux/percpu.h> + +#include <asm/smtc_ipi.h> +#include <asm/time.h> +#include <asm/cevt-r4k.h> + +/* + * Variant clock event timer support for SMTC on MIPS 34K, 1004K + * or other MIPS MT cores. + * + * Notes on SMTC Support: + * + * SMTC has multiple microthread TCs pretending to be Linux CPUs. + * But there's only one Count/Compare pair per VPE, and Compare + * interrupts are taken opportunisitically by available TCs + * bound to the VPE with the Count register. The new timer + * framework provides for global broadcasts, but we really + * want VPE-level multicasts for best behavior. So instead + * of invoking the high-level clock-event broadcast code, + * this version of SMTC support uses the historical SMTC + * multicast mechanisms "under the hood", appearing to the + * generic clock layer as if the interrupts are per-CPU. + * + * The approach taken here is to maintain a set of NR_CPUS + * virtual timers, and track which "CPU" needs to be alerted + * at each event. + * + * It's unlikely that we'll see a MIPS MT core with more than + * 2 VPEs, but we *know* that we won't need to handle more + * VPEs than we have "CPUs". So NCPUs arrays of NCPUs elements + * is always going to be overkill, but always going to be enough. + */ + +unsigned long smtc_nexttime[NR_CPUS][NR_CPUS]; +static int smtc_nextinvpe[NR_CPUS]; + +/* + * Timestamps stored are absolute values to be programmed + * into Count register. Valid timestamps will never be zero. + * If a Zero Count value is actually calculated, it is converted + * to be a 1, which will introduce 1 or two CPU cycles of error + * roughly once every four billion events, which at 1000 HZ means + * about once every 50 days. If that's actually a problem, one + * could alternate squashing 0 to 1 and to -1. + */ + +#define MAKEVALID(x) (((x) == 0L) ? 1L : (x)) +#define ISVALID(x) ((x) != 0L) + +/* + * Time comparison is subtle, as it's really truncated + * modular arithmetic. + */ + +#define IS_SOONER(a, b, reference) \ + (((a) - (unsigned long)(reference)) < ((b) - (unsigned long)(reference))) + +/* + * CATCHUP_INCREMENT, used when the function falls behind the counter. + * Could be an increasing function instead of a constant; + */ + +#define CATCHUP_INCREMENT 64 + +static int mips_next_event(unsigned long delta, + struct clock_event_device *evt) +{ + unsigned long flags; + unsigned int mtflags; + unsigned long timestamp, reference, previous; + unsigned long nextcomp = 0L; + int vpe = current_cpu_data.vpe_id; + int cpu = smp_processor_id(); + local_irq_save(flags); + mtflags = dmt(); + + /* + * Maintain the per-TC virtual timer + * and program the per-VPE shared Count register + * as appropriate here... + */ + reference = (unsigned long)read_c0_count(); + timestamp = MAKEVALID(reference + delta); + /* + * To really model the clock, we have to catch the case + * where the current next-in-VPE timestamp is the old + * timestamp for the calling CPE, but the new value is + * in fact later. In that case, we have to do a full + * scan and discover the new next-in-VPE CPU id and + * timestamp. + */ + previous = smtc_nexttime[vpe][cpu]; + if (cpu == smtc_nextinvpe[vpe] && ISVALID(previous) + && IS_SOONER(previous, timestamp, reference)) { + int i; + int soonest = cpu; + + /* + * Update timestamp array here, so that new + * value gets considered along with those of + * other virtual CPUs on the VPE. + */ + smtc_nexttime[vpe][cpu] = timestamp; + for_each_online_cpu(i) { + if (ISVALID(smtc_nexttime[vpe][i]) + && IS_SOONER(smtc_nexttime[vpe][i], + smtc_nexttime[vpe][soonest], reference)) { + soonest = i; + } + } + smtc_nextinvpe[vpe] = soonest; + nextcomp = smtc_nexttime[vpe][soonest]; + /* + * Otherwise, we don't have to process the whole array rank, + * we just have to see if the event horizon has gotten closer. + */ + } else { + if (!ISVALID(smtc_nexttime[vpe][smtc_nextinvpe[vpe]]) || + IS_SOONER(timestamp, + smtc_nexttime[vpe][smtc_nextinvpe[vpe]], reference)) { + smtc_nextinvpe[vpe] = cpu; + nextcomp = timestamp; + } + /* + * Since next-in-VPE may me the same as the executing + * virtual CPU, we update the array *after* checking + * its value. + */ + smtc_nexttime[vpe][cpu] = timestamp; + } + + /* + * It may be that, in fact, we don't need to update Compare, + * but if we do, we want to make sure we didn't fall into + * a crack just behind Count. + */ + if (ISVALID(nextcomp)) { + write_c0_compare(nextcomp); + ehb(); + /* + * We never return an error, we just make sure + * that we trigger the handlers as quickly as + * we can if we fell behind. + */ + while ((nextcomp - (unsigned long)read_c0_count()) + > (unsigned long)LONG_MAX) { + nextcomp += CATCHUP_INCREMENT; + write_c0_compare(nextcomp); + ehb(); + } + } + emt(mtflags); + local_irq_restore(flags); + return 0; +} + + +void smtc_distribute_timer(int vpe) +{ + unsigned long flags; + unsigned int mtflags; + int cpu; + struct clock_event_device *cd; + unsigned long nextstamp = 0L; + unsigned long reference; + + +repeat: + for_each_online_cpu(cpu) { + /* + * Find virtual CPUs within the current VPE who have + * unserviced timer requests whose time is now past. + */ + local_irq_save(flags); + mtflags = dmt(); + if (cpu_data[cpu].vpe_id == vpe && + ISVALID(smtc_nexttime[vpe][cpu])) { + reference = (unsigned long)read_c0_count(); + if ((smtc_nexttime[vpe][cpu] - reference) + > (unsigned long)LONG_MAX) { + smtc_nexttime[vpe][cpu] = 0L; + emt(mtflags); + local_irq_restore(flags); + /* + * We don't send IPIs to ourself. + */ + if (cpu != smp_processor_id()) { + smtc_send_ipi(cpu, SMTC_CLOCK_TICK, 0); + } else { + cd = &per_cpu(mips_clockevent_device, cpu); + cd->event_handler(cd); + } + } else { + /* Local to VPE but Valid Time not yet reached. */ + if (!ISVALID(nextstamp) || + IS_SOONER(smtc_nexttime[vpe][cpu], nextstamp, + reference)) { + smtc_nextinvpe[vpe] = cpu; + nextstamp = smtc_nexttime[vpe][cpu]; + } + emt(mtflags); + local_irq_restore(flags); + } + } else { + emt(mtflags); + local_irq_restore(flags); + + } + } + /* Reprogram for interrupt at next soonest timestamp for VPE */ + if (ISVALID(nextstamp)) { + write_c0_compare(nextstamp); + ehb(); + if ((nextstamp - (unsigned long)read_c0_count()) + > (unsigned long)LONG_MAX) + goto repeat; + } +} + + +irqreturn_t c0_compare_interrupt(int irq, void *dev_id) +{ + int cpu = smp_processor_id(); + + /* If we're running SMTC, we've got MIPS MT and therefore MIPS32R2 */ + handle_perf_irq(1); + + if (read_c0_cause() & (1 << 30)) { + /* Clear Count/Compare Interrupt */ + write_c0_compare(read_c0_compare()); + smtc_distribute_timer(cpu_data[cpu].vpe_id); + } + return IRQ_HANDLED; +} + + +int __cpuinit mips_clockevent_init(void) +{ + uint64_t mips_freq = mips_hpt_frequency; + unsigned int cpu = smp_processor_id(); + struct clock_event_device *cd; + unsigned int irq; + int i; + int j; + + if (!cpu_has_counter || !mips_hpt_frequency) + return -ENXIO; + if (cpu == 0) { + for (i = 0; i < num_possible_cpus(); i++) { + smtc_nextinvpe[i] = 0; + for (j = 0; j < num_possible_cpus(); j++) + smtc_nexttime[i][j] = 0L; + } + /* + * SMTC also can't have the usablility test + * run by secondary TCs once Compare is in use. + */ + if (!c0_compare_int_usable()) + return -ENXIO; + } + + /* + * With vectored interrupts things are getting platform specific. + * get_c0_compare_int is a hook to allow a platform to return the + * interrupt number of it's liking. + */ + irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq; + if (get_c0_compare_int) + irq = get_c0_compare_int(); + + cd = &per_cpu(mips_clockevent_device, cpu); + + cd->name = "MIPS"; + cd->features = CLOCK_EVT_FEAT_ONESHOT; + + /* Calculate the min / max delta */ + cd->mult = div_sc((unsigned long) mips_freq, NSEC_PER_SEC, 32); + cd->shift = 32; + cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd); + cd->min_delta_ns = clockevent_delta2ns(0x300, cd); + + cd->rating = 300; + cd->irq = irq; + cd->cpumask = cpumask_of_cpu(cpu); + cd->set_next_event = mips_next_event; + cd->set_mode = mips_set_clock_mode; + cd->event_handler = mips_event_handler; + + clockevents_register_device(cd); + + /* + * On SMTC we only want to do the data structure + * initialization and IRQ setup once. + */ + if (cpu) + return 0; + /* + * And we need the hwmask associated with the c0_compare + * vector to be initialized. + */ + irq_hwmask[irq] = (0x100 << cp0_compare_irq); + if (cp0_timer_irq_installed) + return 0; + + cp0_timer_irq_installed = 1; + + setup_irq(irq, &c0_compare_irqaction); + + return 0; +} diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index 11c92dc5379..e621fda8ab3 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c @@ -54,14 +54,18 @@ extern void r4k_wait(void); * interrupt is requested" restriction in the MIPS32/MIPS64 architecture makes * using this version a gamble. */ -static void r4k_wait_irqoff(void) +void r4k_wait_irqoff(void) { local_irq_disable(); if (!need_resched()) - __asm__(" .set mips3 \n" + __asm__(" .set push \n" + " .set mips3 \n" " wait \n" - " .set mips0 \n"); + " .set pop \n"); local_irq_enable(); + __asm__(" .globl __pastwait \n" + "__pastwait: \n"); + return; } /* diff --git a/arch/mips/kernel/entry.S b/arch/mips/kernel/entry.S index e29598ae939..ffa331029e0 100644 --- a/arch/mips/kernel/entry.S +++ b/arch/mips/kernel/entry.S @@ -79,11 +79,6 @@ FEXPORT(syscall_exit) FEXPORT(restore_all) # restore full frame #ifdef CONFIG_MIPS_MT_SMTC -/* Detect and execute deferred IPI "interrupts" */ - LONG_L s0, TI_REGS($28) - LONG_S sp, TI_REGS($28) - jal deferred_smtc_ipi - LONG_S s0, TI_REGS($28) #ifdef CONFIG_MIPS_MT_SMTC_IM_BACKSTOP /* Re-arm any temporarily masked interrupts not explicitly "acked" */ mfc0 v0, CP0_TCSTATUS @@ -112,6 +107,11 @@ FEXPORT(restore_all) # restore full frame xor t0, t0, t3 mtc0 t0, CP0_TCCONTEXT #endif /* CONFIG_MIPS_MT_SMTC_IM_BACKSTOP */ +/* Detect and execute deferred IPI "interrupts" */ + LONG_L s0, TI_REGS($28) + LONG_S sp, TI_REGS($28) + jal deferred_smtc_ipi + LONG_S s0, TI_REGS($28) #endif /* CONFIG_MIPS_MT_SMTC */ .set noat RESTORE_TEMP diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S index f886dd7f708..01dcbe38fa0 100644 --- a/arch/mips/kernel/genex.S +++ b/arch/mips/kernel/genex.S @@ -282,8 +282,8 @@ NESTED(except_vec_vi_handler, 0, sp) and t0, a0, t1 #ifdef CONFIG_MIPS_MT_SMTC_IM_BACKSTOP mfc0 t2, CP0_TCCONTEXT - or t0, t0, t2 - mtc0 t0, CP0_TCCONTEXT + or t2, t0, t2 + mtc0 t2, CP0_TCCONTEXT #endif /* CONFIG_MIPS_MT_SMTC_IM_BACKSTOP */ xor t1, t1, t0 mtc0 t1, CP0_STATUS diff --git a/arch/mips/kernel/kgdb.c b/arch/mips/kernel/kgdb.c index 8f6d58ede33..6e152c80cd4 100644 --- a/arch/mips/kernel/kgdb.c +++ b/arch/mips/kernel/kgdb.c @@ -236,8 +236,7 @@ int kgdb_arch_handle_exception(int vector, int signo, int err_code, atomic_set(&kgdb_cpu_doing_single_step, -1); if (remcom_in_buffer[0] == 's') - if (kgdb_contthread) - atomic_set(&kgdb_cpu_doing_single_step, cpu); + atomic_set(&kgdb_cpu_doing_single_step, cpu); return 0; } diff --git a/arch/mips/kernel/mips-mt-fpaff.c b/arch/mips/kernel/mips-mt-fpaff.c index df4d3f2f740..dc9eb72ed9d 100644 --- a/arch/mips/kernel/mips-mt-fpaff.c +++ b/arch/mips/kernel/mips-mt-fpaff.c @@ -159,7 +159,7 @@ __setup("fpaff=", fpaff_thresh); /* * FPU Use Factor empirically derived from experiments on 34K */ -#define FPUSEFACTOR 333 +#define FPUSEFACTOR 2000 static __init int mt_fp_affinity_init(void) { diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index ce7684335a4..22fc19bbe87 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c @@ -55,7 +55,7 @@ void __noreturn cpu_idle(void) while (1) { tick_nohz_stop_sched_tick(1); while (!need_resched()) { -#ifdef CONFIG_SMTC_IDLE_HOOK_DEBUG +#ifdef CONFIG_MIPS_MT_SMTC extern void smtc_idle_loop_hook(void); smtc_idle_loop_hook(); @@ -145,19 +145,18 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, */ p->thread.cp0_status = read_c0_status() & ~(ST0_CU2|ST0_CU1); childregs->cp0_status &= ~(ST0_CU2|ST0_CU1); + +#ifdef CONFIG_MIPS_MT_SMTC + /* + * SMTC restores TCStatus after Status, and the CU bits + * are aliased there. + */ + childregs->cp0_tcstatus &= ~(ST0_CU2|ST0_CU1); +#endif clear_tsk_thread_flag(p, TIF_USEDFPU); #ifdef CONFIG_MIPS_MT_FPAFF clear_tsk_thread_flag(p, TIF_FPUBOUND); - - /* - * FPU affinity support is cleaner if we track the - * user-visible CPU affinity from the very beginning. - * The generic cpus_allowed mask will already have - * been copied from the parent before copy_thread - * is invoked. - */ - p->thread.user_cpus_allowed = p->cpus_allowed; #endif /* CONFIG_MIPS_MT_FPAFF */ if (clone_flags & CLONE_SETTLS) diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c index 35234b92b9a..96ffc9c6d19 100644 --- a/arch/mips/kernel/ptrace.c +++ b/arch/mips/kernel/ptrace.c @@ -238,7 +238,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) case FPC_EIR: { /* implementation / version register */ unsigned int flags; #ifdef CONFIG_MIPS_MT_SMTC - unsigned int irqflags; + unsigned long irqflags; unsigned int mtflags; #endif /* CONFIG_MIPS_MT_SMTC */ diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c index a516286532a..897fb2b4751 100644 --- a/arch/mips/kernel/smtc.c +++ b/arch/mips/kernel/smtc.c @@ -1,4 +1,21 @@ -/* Copyright (C) 2004 Mips Technologies, Inc */ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Copyright (C) 2004 Mips Technologies, Inc + * Copyright (C) 2008 Kevin D. Kissell + */ #include <linux/clockchips.h> #include <linux/kernel.h> @@ -21,7 +38,6 @@ #include <asm/time.h> #include <asm/addrspace.h> #include <asm/smtc.h> -#include <asm/smtc_ipi.h> #include <asm/smtc_proc.h> /* @@ -58,11 +74,6 @@ unsigned long irq_hwmask[NR_IRQS]; asiduse smtc_live_asid[MAX_SMTC_TLBS][MAX_SMTC_ASIDS]; -/* - * Clock interrupt "latch" buffers, per "CPU" - */ - -static atomic_t ipi_timer_latch[NR_CPUS]; /* * Number of InterProcessor Interrupt (IPI) message buffers to allocate @@ -70,7 +81,7 @@ static atomic_t ipi_timer_latch[NR_CPUS]; #define IPIBUF_PER_CPU 4 -static struct smtc_ipi_q IPIQ[NR_CPUS]; +struct smtc_ipi_q IPIQ[NR_CPUS]; static struct smtc_ipi_q freeIPIq; @@ -282,7 +293,7 @@ static void smtc_configure_tlb(void) * phys_cpu_present_map and the logical/physical mappings. */ -int __init mipsmt_build_cpu_map(int start_cpu_slot) +int __init smtc_build_cpu_map(int start_cpu_slot) { int i, ntcs; @@ -325,7 +336,12 @@ static void smtc_tc_setup(int vpe, int tc, int cpu) write_tc_c0_tcstatus((read_tc_c0_tcstatus() & ~(TCSTATUS_TKSU | TCSTATUS_DA | TCSTATUS_IXMT)) | TCSTATUS_A); - write_tc_c0_tccontext(0); + /* + * TCContext gets an offset from the base of the IPIQ array + * to be used in low-level code to detect the presence of + * an active IPI queue + */ + write_tc_c0_tccontext((sizeof(struct smtc_ipi_q) * cpu) << 16); /* Bind tc to vpe */ write_tc_c0_tcbind(vpe); /* In general, all TCs should have the same cpu_data indications */ @@ -336,10 +352,18 @@ static void smtc_tc_setup(int vpe, int tc, int cpu) cpu_data[cpu].options &= ~MIPS_CPU_FPU; cpu_data[cpu].vpe_id = vpe; cpu_data[cpu].tc_id = tc; + /* Multi-core SMTC hasn't been tested, but be prepared */ + cpu_data[cpu].core = (read_vpe_c0_ebase() >> 1) & 0xff; } +/* + * Tweak to get Count registes in as close a sync as possible. + * Value seems good for 34K-class cores. + */ + +#define CP0_SKEW 8 -void mipsmt_prepare_cpus(void) +void smtc_prepare_cpus(int cpus) { int i, vpe, tc, ntc, nvpe, tcpervpe[NR_CPUS], slop, cpu; unsigned long flags; @@ -363,13 +387,13 @@ void mipsmt_prepare_cpus(void) IPIQ[i].head = IPIQ[i].tail = NULL; spin_lock_init(&IPIQ[i].lock); IPIQ[i].depth = 0; - atomic_set(&ipi_timer_latch[i], 0); } /* cpu_data index starts at zero */ cpu = 0; cpu_data[cpu].vpe_id = 0; cpu_data[cpu].tc_id = 0; + cpu_data[cpu].core = (read_c0_ebase() >> 1) & 0xff; cpu++; /* Report on boot-time options */ @@ -484,7 +508,8 @@ void mipsmt_prepare_cpus(void) write_vpe_c0_compare(0); /* Propagate Config7 */ write_vpe_c0_config7(read_c0_config7()); - write_vpe_c0_count(read_c0_count()); + write_vpe_c0_count(read_c0_count() + CP0_SKEW); + ehb(); } /* enable multi-threading within VPE */ write_vpe_c0_vpecontrol(read_vpe_c0_vpecontrol() | VPECONTROL_TE); @@ -556,7 +581,7 @@ void mipsmt_prepare_cpus(void) void __cpuinit smtc_boot_secondary(int cpu, struct task_struct *idle) { extern u32 kernelsp[NR_CPUS]; - long flags; + unsigned long flags; int mtflags; LOCK_MT_PRA(); @@ -585,24 +610,22 @@ void __cpuinit smtc_boot_secondary(int cpu, struct task_struct *idle) void smtc_init_secondary(void) { - /* - * Start timer on secondary VPEs if necessary. - * plat_timer_setup has already have been invoked by init/main - * on "boot" TC. Like per_cpu_trap_init() hack, this assumes that - * SMTC init code assigns TCs consdecutively and in ascending order - * to across available VPEs. - */ - if (((read_c0_tcbind() & TCBIND_CURTC) != 0) && - ((read_c0_tcbind() & TCBIND_CURVPE) - != cpu_data[smp_processor_id() - 1].vpe_id)){ - write_c0_compare(read_c0_count() + mips_hpt_frequency/HZ); - } - local_irq_enable(); } void smtc_smp_finish(void) { + int cpu = smp_processor_id(); + + /* + * Lowest-numbered CPU per VPE starts a clock tick. + * Like per_cpu_trap_init() hack, this assumes that + * SMTC init code assigns TCs consdecutively and + * in ascending order across available VPEs. + */ + if (cpu > 0 && (cpu_data[cpu].vpe_id != cpu_data[cpu - 1].vpe_id)) + write_c0_compare(read_c0_count() + mips_hpt_frequency/HZ); + printk("TC %d going on-line as CPU %d\n", cpu_data[smp_processor_id()].tc_id, smp_processor_id()); } @@ -753,8 +776,10 @@ void smtc_send_ipi(int cpu, int type, unsigned int action) { int tcstatus; struct smtc_ipi *pipi; - long flags; + unsigned long flags; int mtflags; + unsigned long tcrestart; + extern void r4k_wait_irqoff(void), __pastwait(void); if (cpu == smp_processor_id()) { printk("Cannot Send IPI to self!\n"); @@ -771,8 +796,6 @@ void smtc_send_ipi(int cpu, int type, unsigned int action) pipi->arg = (void *)action; pipi->dest = cpu; if (cpu_data[cpu].vpe_id != cpu_data[smp_processor_id()].vpe_id) { - if (type == SMTC_CLOCK_TICK) - atomic_inc(&ipi_timer_latch[cpu]); /* If not on same VPE, enqueue and send cross-VPE interrupt */ smtc_ipi_nq(&IPIQ[cpu], pipi); LOCK_CORE_PRA(); @@ -800,22 +823,29 @@ void smtc_send_ipi(int cpu, int type, unsigned int action) if ((tcstatus & TCSTATUS_IXMT) != 0) { /* - * Spin-waiting here can deadlock, - * so we queue the message for the target TC. + * If we're in the the irq-off version of the wait + * loop, we need to force exit from the wait and + * do a direct post of the IPI. + */ + if (cpu_wait == r4k_wait_irqoff) { + tcrestart = read_tc_c0_tcrestart(); + if (tcrestart >= (unsigned long)r4k_wait_irqoff + && tcrestart < (unsigned long)__pastwait) { + write_tc_c0_tcrestart(__pastwait); + tcstatus &= ~TCSTATUS_IXMT; + write_tc_c0_tcstatus(tcstatus); + goto postdirect; + } + } + /* + * Otherwise we queue the message for the target TC + * to pick up when he does a local_irq_restore() */ write_tc_c0_tchalt(0); UNLOCK_CORE_PRA(); - /* Try to reduce redundant timer interrupt messages */ - if (type == SMTC_CLOCK_TICK) { - if (atomic_postincrement(&ipi_timer_latch[cpu])!=0){ - smtc_ipi_nq(&freeIPIq, pipi); - return; - } - } smtc_ipi_nq(&IPIQ[cpu], pipi); } else { - if (type == SMTC_CLOCK_TICK) - atomic_inc(&ipi_timer_latch[cpu]); +postdirect: post_direct_ipi(cpu, pipi); write_tc_c0_tchalt(0); UNLOCK_CORE_PRA(); @@ -883,7 +913,7 @@ static void ipi_call_interrupt(void) smp_call_function_interrupt(); } -DECLARE_PER_CPU(struct clock_event_device, smtc_dummy_clockevent_device); +DECLARE_PER_CPU(struct clock_event_device, mips_clockevent_device); void ipi_decode(struct smtc_ipi *pipi) { @@ -891,20 +921,13 @@ void ipi_decode(struct smtc_ipi *pipi) struct clock_event_device *cd; void *arg_copy = pipi->arg; int type_copy = pipi->type; - int ticks; - smtc_ipi_nq(&freeIPIq, pipi); switch (type_copy) { case SMTC_CLOCK_TICK: irq_enter(); kstat_this_cpu.irqs[MIPS_CPU_IRQ_BASE + 1]++; - cd = &per_cpu(smtc_dummy_clockevent_device, cpu); - ticks = atomic_read(&ipi_timer_latch[cpu]); - atomic_sub(ticks, &ipi_timer_latch[cpu]); - while (ticks) { - cd->event_handler(cd); - ticks--; - } + cd = &per_cpu(mips_clockevent_device, cpu); + cd->event_handler(cd); irq_exit(); break; @@ -937,24 +960,48 @@ void ipi_decode(struct smtc_ipi *pipi) } } +/* + * Similar to smtc_ipi_replay(), but invoked from context restore, + * so it reuses the current exception frame rather than set up a + * new one with self_ipi. + */ + void deferred_smtc_ipi(void) { - struct smtc_ipi *pipi; - unsigned long flags; -/* DEBUG */ - int q = smp_processor_id(); + int cpu = smp_processor_id(); /* * Test is not atomic, but much faster than a dequeue, * and the vast majority of invocations will have a null queue. + * If irq_disabled when this was called, then any IPIs queued + * after we test last will be taken on the next irq_enable/restore. + * If interrupts were enabled, then any IPIs added after the + * last test will be taken directly. */ - if (IPIQ[q].head != NULL) { - while((pipi = smtc_ipi_dq(&IPIQ[q])) != NULL) { - /* ipi_decode() should be called with interrupts off */ - local_irq_save(flags); + + while (IPIQ[cpu].head != NULL) { + struct smtc_ipi_q *q = &IPIQ[cpu]; + struct smtc_ipi *pipi; + unsigned long flags; + + /* + * It may be possible we'll come in with interrupts + * already enabled. + */ + local_irq_save(flags); + + spin_lock(&q->lock); + pipi = __smtc_ipi_dq(q); + spin_unlock(&q->lock); + if (pipi != NULL) ipi_decode(pipi); - local_irq_restore(flags); - } + /* + * The use of the __raw_local restore isn't + * as obviously necessary here as in smtc_ipi_replay(), + * but it's more efficient, given that we're already + * running down the IPI queue. + */ + __raw_local_irq_restore(flags); } } @@ -975,7 +1022,7 @@ static irqreturn_t ipi_interrupt(int irq, void *dev_idm) struct smtc_ipi *pipi; unsigned long tcstatus; int sent; - long flags; + unsigned long flags; unsigned int mtflags; unsigned int vpflags; @@ -1066,55 +1113,53 @@ static void setup_cross_vpe_interrupts(unsigned int nvpe) /* * SMTC-specific hacks invoked from elsewhere in the kernel. - * - * smtc_ipi_replay is called from raw_local_irq_restore which is only ever - * called with interrupts disabled. We do rely on interrupts being disabled - * here because using spin_lock_irqsave()/spin_unlock_irqrestore() would - * result in a recursive call to raw_local_irq_restore(). */ -static void __smtc_ipi_replay(void) + /* + * smtc_ipi_replay is called from raw_local_irq_restore + */ + +void smtc_ipi_replay(void) { unsigned int cpu = smp_processor_id(); /* * To the extent that we've ever turned interrupts off, * we may have accumulated deferred IPIs. This is subtle. - * If we use the smtc_ipi_qdepth() macro, we'll get an - * exact number - but we'll also disable interrupts - * and create a window of failure where a new IPI gets - * queued after we test the depth but before we re-enable - * interrupts. So long as IXMT never gets set, however, * we should be OK: If we pick up something and dispatch * it here, that's great. If we see nothing, but concurrent * with this operation, another TC sends us an IPI, IXMT * is clear, and we'll handle it as a real pseudo-interrupt - * and not a pseudo-pseudo interrupt. + * and not a pseudo-pseudo interrupt. The important thing + * is to do the last check for queued message *after* the + * re-enabling of interrupts. */ - if (IPIQ[cpu].depth > 0) { - while (1) { - struct smtc_ipi_q *q = &IPIQ[cpu]; - struct smtc_ipi *pipi; - extern void self_ipi(struct smtc_ipi *); - - spin_lock(&q->lock); - pipi = __smtc_ipi_dq(q); - spin_unlock(&q->lock); - if (!pipi) - break; + while (IPIQ[cpu].head != NULL) { + struct smtc_ipi_q *q = &IPIQ[cpu]; + struct smtc_ipi *pipi; + unsigned long flags; + + /* + * It's just possible we'll come in with interrupts + * already enabled. + */ + local_irq_save(flags); + + spin_lock(&q->lock); + pipi = __smtc_ipi_dq(q); + spin_unlock(&q->lock); + /* + ** But use a raw restore here to avoid recursion. + */ + __raw_local_irq_restore(flags); + if (pipi) { self_ipi(pipi); smtc_cpu_stats[cpu].selfipis++; } } } -void smtc_ipi_replay(void) -{ - raw_local_irq_disable(); - __smtc_ipi_replay(); -} - EXPORT_SYMBOL(smtc_ipi_replay); void smtc_idle_loop_hook(void) @@ -1193,40 +1238,13 @@ void smtc_idle_loop_hook(void) } } - /* - * Now that we limit outstanding timer IPIs, check for hung TC - */ - for (tc = 0; tc < NR_CPUS; tc++) { - /* Don't check ourself - we'll dequeue IPIs just below */ - if ((tc != smp_processor_id()) && - atomic_read(&ipi_timer_latch[tc]) > timerq_limit) { - if (clock_hang_reported[tc] == 0) { - pdb_msg += sprintf(pdb_msg, - "TC %d looks hung with timer latch at %d\n", - tc, atomic_read(&ipi_timer_latch[tc])); - clock_hang_reported[tc]++; - } - } - } emt(mtflags); local_irq_restore(flags); if (pdb_msg != &id_ho_db_msg[0]) printk("CPU%d: %s", smp_processor_id(), id_ho_db_msg); #endif /* CONFIG_SMTC_IDLE_HOOK_DEBUG */ - /* - * Replay any accumulated deferred IPIs. If "Instant Replay" - * is in use, there should never be any. - */ -#ifndef CONFIG_MIPS_MT_SMTC_INSTANT_REPLAY - { - unsigned long flags; - - local_irq_save(flags); - __smtc_ipi_replay(); - local_irq_restore(flags); - } -#endif /* CONFIG_MIPS_MT_SMTC_INSTANT_REPLAY */ + smtc_ipi_replay(); } void smtc_soft_dump(void) @@ -1242,10 +1260,6 @@ void smtc_soft_dump(void) printk("%d: %ld\n", i, smtc_cpu_stats[i].selfipis); } smtc_ipi_qdump(); - printk("Timer IPI Backlogs:\n"); - for (i=0; i < NR_CPUS; i++) { - printk("%d: %d\n", i, atomic_read(&ipi_timer_latch[i])); - } printk("%d Recoveries of \"stolen\" FPU\n", atomic_read(&smtc_fpu_recoveries)); } diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 5fd0cd020af..b602ac6eb47 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -825,8 +825,10 @@ static void mt_ase_fp_affinity(void) if (cpus_intersects(current->cpus_allowed, mt_fpu_cpumask)) { cpumask_t tmask; - cpus_and(tmask, current->thread.user_cpus_allowed, - mt_fpu_cpumask); + current->thread.user_cpus_allowed + = current->cpus_allowed; + cpus_and(tmask, current->cpus_allowed, + mt_fpu_cpumask); set_cpus_allowed(current, tmask); set_thread_flag(TIF_FPUBOUND); } diff --git a/arch/mips/mti-malta/Makefile b/arch/mips/mti-malta/Makefile index 3b7dd722c32..cef2db8d222 100644 --- a/arch/mips/mti-malta/Makefile +++ b/arch/mips/mti-malta/Makefile @@ -15,6 +15,6 @@ obj-$(CONFIG_EARLY_PRINTK) += malta-console.o obj-$(CONFIG_PCI) += malta-pci.o # FIXME FIXME FIXME -obj-$(CONFIG_MIPS_MT_SMTC) += malta_smtc.o +obj-$(CONFIG_MIPS_MT_SMTC) += malta-smtc.o EXTRA_CFLAGS += -Werror diff --git a/arch/mips/mti-malta/malta-smtc.c b/arch/mips/mti-malta/malta-smtc.c index 5ea705e4945..f84a46a8ae6 100644 --- a/arch/mips/mti-malta/malta-smtc.c +++ b/arch/mips/mti-malta/malta-smtc.c @@ -84,12 +84,17 @@ static void msmtc_cpus_done(void) static void __init msmtc_smp_setup(void) { - mipsmt_build_cpu_map(0); + /* + * we won't get the definitive value until + * we've run smtc_prepare_cpus later, but + * we would appear to need an upper bound now. + */ + smp_num_siblings = smtc_build_cpu_map(0); } static void __init msmtc_prepare_cpus(unsigned int max_cpus) { - mipsmt_prepare_cpus(); + smtc_prepare_cpus(max_cpus); } struct plat_smp_ops msmtc_smp_ops = { diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile index 15e01aec37f..c8c32f417b6 100644 --- a/arch/mips/pci/Makefile +++ b/arch/mips/pci/Makefile @@ -15,6 +15,7 @@ obj-$(CONFIG_SOC_TX3927) += ops-tx3927.o obj-$(CONFIG_PCI_VR41XX) += ops-vr41xx.o pci-vr41xx.o obj-$(CONFIG_MARKEINS) += ops-emma2rh.o pci-emma2rh.o fixup-emma2rh.o obj-$(CONFIG_PCI_TX4927) += ops-tx4927.o +obj-$(CONFIG_BCM47XX) += pci-bcm47xx.o # # These are still pretty much in the old state, watch, go blind. diff --git a/arch/mips/pci/pci-bcm47xx.c b/arch/mips/pci/pci-bcm47xx.c new file mode 100644 index 00000000000..bea9b6cdfdb --- /dev/null +++ b/arch/mips/pci/pci-bcm47xx.c @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2008 Aurelien Jarno <aurelien@aurel32.net> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <linux/types.h> +#include <linux/pci.h> +#include <linux/ssb/ssb.h> + +int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +{ + return 0; +} + +int pcibios_plat_dev_init(struct pci_dev *dev) +{ + int res; + u8 slot, pin; + + res = ssb_pcibios_plat_dev_init(dev); + if (res < 0) { + printk(KERN_ALERT "PCI: Failed to init device %s\n", + pci_name(dev)); + return res; + } + + pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); + slot = PCI_SLOT(dev->devfn); + res = ssb_pcibios_map_irq(dev, slot, pin); + + /* IRQ-0 and IRQ-1 are software interrupts. */ + if (res < 2) { + printk(KERN_ALERT "PCI: Failed to map IRQ of device %s\n", + pci_name(dev)); + return res; + } + + dev->irq = res; + return 0; +} + diff --git a/arch/mips/pci/pci-ip27.c b/arch/mips/pci/pci-ip27.c index bd78368c82b..f97ab146101 100644 --- a/arch/mips/pci/pci-ip27.c +++ b/arch/mips/pci/pci-ip27.c @@ -143,25 +143,47 @@ int __cpuinit bridge_probe(nasid_t nasid, int widget_id, int masterwid) */ int __devinit pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { + return 0; +} + +/* Most MIPS systems have straight-forward swizzling needs. */ +static inline u8 bridge_swizzle(u8 pin, u8 slot) +{ + return (((pin - 1) + slot) % 4) + 1; +} + +static inline struct pci_dev *bridge_root_dev(struct pci_dev *dev) +{ + while (dev->bus->parent) { + /* Move up the chain of bridges. */ + dev = dev->bus->self; + } + + return dev; +} + +/* Do platform specific device initialization at pci_enable_device() time */ +int pcibios_plat_dev_init(struct pci_dev *dev) +{ struct bridge_controller *bc = BRIDGE_CONTROLLER(dev->bus); - int irq = bc->pci_int[slot]; + struct pci_dev *rdev = bridge_root_dev(dev); + int slot = PCI_SLOT(rdev->devfn); + int irq; + irq = bc->pci_int[slot]; if (irq == -1) { - irq = bc->pci_int[slot] = request_bridge_irq(bc); + irq = request_bridge_irq(bc); if (irq < 0) - panic("Can't allocate interrupt for PCI device %s\n", - pci_name(dev)); + return irq; + + bc->pci_int[slot] = irq; } irq_to_bridge[irq] = bc; irq_to_slot[irq] = slot; - return irq; -} + dev->irq = irq; -/* Do platform specific device initialization at pci_enable_device() time */ -int pcibios_plat_dev_init(struct pci_dev *dev) -{ return 0; } diff --git a/arch/mn10300/kernel/irq.c b/arch/mn10300/kernel/irq.c index 761c434a248..56c64ccc9c2 100644 --- a/arch/mn10300/kernel/irq.c +++ b/arch/mn10300/kernel/irq.c @@ -20,22 +20,8 @@ EXPORT_SYMBOL(__mn10300_irq_enabled_epsw); atomic_t irq_err_count; /* - * MN10300 INTC controller operations + * MN10300 interrupt controller operations */ -static void mn10300_cpupic_disable(unsigned int irq) -{ - u16 tmp = GxICR(irq); - GxICR(irq) = (tmp & GxICR_LEVEL) | GxICR_DETECT; - tmp = GxICR(irq); -} - -static void mn10300_cpupic_enable(unsigned int irq) -{ - u16 tmp = GxICR(irq); - GxICR(irq) = (tmp & GxICR_LEVEL) | GxICR_ENABLE; - tmp = GxICR(irq); -} - static void mn10300_cpupic_ack(unsigned int irq) { u16 tmp; @@ -60,26 +46,54 @@ static void mn10300_cpupic_mask_ack(unsigned int irq) static void mn10300_cpupic_unmask(unsigned int irq) { u16 tmp = GxICR(irq); - GxICR(irq) = (tmp & GxICR_LEVEL) | GxICR_ENABLE | GxICR_DETECT; + GxICR(irq) = (tmp & GxICR_LEVEL) | GxICR_ENABLE; tmp = GxICR(irq); } -static void mn10300_cpupic_end(unsigned int irq) +static void mn10300_cpupic_unmask_clear(unsigned int irq) { + /* the MN10300 PIC latches its interrupt request bit, even after the + * device has ceased to assert its interrupt line and the interrupt + * channel has been disabled in the PIC, so for level-triggered + * interrupts we need to clear the request bit when we re-enable */ u16 tmp = GxICR(irq); - GxICR(irq) = (tmp & GxICR_LEVEL) | GxICR_ENABLE; + GxICR(irq) = (tmp & GxICR_LEVEL) | GxICR_ENABLE | GxICR_DETECT; tmp = GxICR(irq); } -static struct irq_chip mn10300_cpu_pic = { - .name = "cpu", - .disable = mn10300_cpupic_disable, - .enable = mn10300_cpupic_enable, +/* + * MN10300 PIC level-triggered IRQ handling. + * + * The PIC has no 'ACK' function per se. It is possible to clear individual + * channel latches, but each latch relatches whether or not the channel is + * masked, so we need to clear the latch when we unmask the channel. + * + * Also for this reason, we don't supply an ack() op (it's unused anyway if + * mask_ack() is provided), and mask_ack() just masks. + */ +static struct irq_chip mn10300_cpu_pic_level = { + .name = "cpu_l", + .disable = mn10300_cpupic_mask, + .enable = mn10300_cpupic_unmask_clear, + .ack = NULL, + .mask = mn10300_cpupic_mask, + .mask_ack = mn10300_cpupic_mask, + .unmask = mn10300_cpupic_unmask_clear, +}; + +/* + * MN10300 PIC edge-triggered IRQ handling. + * + * We use the latch clearing function of the PIC as the 'ACK' function. + */ +static struct irq_chip mn10300_cpu_pic_edge = { + .name = "cpu_e", + .disable = mn10300_cpupic_mask, + .enable = mn10300_cpupic_unmask, .ack = mn10300_cpupic_ack, .mask = mn10300_cpupic_mask, .mask_ack = mn10300_cpupic_mask_ack, .unmask = mn10300_cpupic_unmask, - .end = mn10300_cpupic_end, }; /* @@ -114,7 +128,8 @@ void set_intr_level(int irq, u16 level) */ void set_intr_postackable(int irq) { - set_irq_handler(irq, handle_level_irq); + set_irq_chip_and_handler(irq, &mn10300_cpu_pic_level, + handle_level_irq); } /* @@ -126,8 +141,12 @@ void __init init_IRQ(void) for (irq = 0; irq < NR_IRQS; irq++) if (irq_desc[irq].chip == &no_irq_type) - set_irq_chip_and_handler(irq, &mn10300_cpu_pic, - handle_edge_irq); + /* due to the PIC latching interrupt requests, even + * when the IRQ is disabled, IRQ_PENDING is superfluous + * and we can use handle_level_irq() for edge-triggered + * interrupts */ + set_irq_chip_and_handler(irq, &mn10300_cpu_pic_edge, + handle_level_irq); unit_init_IRQ(); } diff --git a/arch/mn10300/kernel/time.c b/arch/mn10300/kernel/time.c index babb7c2ac37..e4606586f94 100644 --- a/arch/mn10300/kernel/time.c +++ b/arch/mn10300/kernel/time.c @@ -1,6 +1,6 @@ /* MN10300 Low level time management * - * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Copyright (C) 2007-2008 Red Hat, Inc. All Rights Reserved. * Written by David Howells (dhowells@redhat.com) * - Derived from arch/i386/kernel/time.c * @@ -16,6 +16,7 @@ #include <linux/init.h> #include <linux/smp.h> #include <linux/profile.h> +#include <linux/cnt32_to_63.h> #include <asm/irq.h> #include <asm/div64.h> #include <asm/processor.h> @@ -40,27 +41,54 @@ static struct irqaction timer_irq = { .name = "timer", }; +static unsigned long sched_clock_multiplier; + /* * scheduler clock - returns current time in nanosec units. */ unsigned long long sched_clock(void) { union { - unsigned long long l; - u32 w[2]; - } quot; + unsigned long long ll; + unsigned l[2]; + } tsc64, result; + unsigned long tsc, tmp; + unsigned product[3]; /* 96-bit intermediate value */ + + /* read the TSC value + */ + tsc = 0 - get_cycles(); /* get_cycles() counts down */ - quot.w[0] = mn10300_last_tsc - get_cycles(); - quot.w[1] = 1000000000; + /* expand to 64-bits. + * - sched_clock() must be called once a minute or better or the + * following will go horribly wrong - see cnt32_to_63() + */ + tsc64.ll = cnt32_to_63(tsc) & 0x7fffffffffffffffULL; - asm("mulu %2,%3,%0,%1" - : "=r"(quot.w[1]), "=r"(quot.w[0]) - : "0"(quot.w[1]), "1"(quot.w[0]) + /* scale the 64-bit TSC value to a nanosecond value via a 96-bit + * intermediate + */ + asm("mulu %2,%0,%3,%0 \n" /* LSW * mult -> 0:%3:%0 */ + "mulu %2,%1,%2,%1 \n" /* MSW * mult -> %2:%1:0 */ + "add %3,%1 \n" + "addc 0,%2 \n" /* result in %2:%1:%0 */ + : "=r"(product[0]), "=r"(product[1]), "=r"(product[2]), "=r"(tmp) + : "0"(tsc64.l[0]), "1"(tsc64.l[1]), "2"(sched_clock_multiplier) : "cc"); - do_div(quot.l, MN10300_TSCCLK); + result.l[0] = product[1] << 16 | product[0] >> 16; + result.l[1] = product[2] << 16 | product[1] >> 16; - return quot.l; + return result.ll; +} + +/* + * initialise the scheduler clock + */ +static void __init mn10300_sched_clock_init(void) +{ + sched_clock_multiplier = + __muldiv64u(NSEC_PER_SEC, 1 << 16, MN10300_TSCCLK); } /* @@ -128,4 +156,6 @@ void __init time_init(void) /* start the watchdog timer */ watchdog_go(); #endif + + mn10300_sched_clock_init(); } diff --git a/arch/mn10300/unit-asb2303/unit-init.c b/arch/mn10300/unit-asb2303/unit-init.c index 14b2c817cff..70e8cb4ea26 100644 --- a/arch/mn10300/unit-asb2303/unit-init.c +++ b/arch/mn10300/unit-asb2303/unit-init.c @@ -51,7 +51,7 @@ void __init unit_init_IRQ(void) switch (GET_XIRQ_TRIGGER(extnum)) { case XIRQ_TRIGGER_HILEVEL: case XIRQ_TRIGGER_LOWLEVEL: - set_irq_handler(XIRQ2IRQ(extnum), handle_level_irq); + set_intr_postackable(XIRQ2IRQ(extnum)); break; default: break; diff --git a/arch/mn10300/unit-asb2305/unit-init.c b/arch/mn10300/unit-asb2305/unit-init.c index 6a352414a35..72812a9439a 100644 --- a/arch/mn10300/unit-asb2305/unit-init.c +++ b/arch/mn10300/unit-asb2305/unit-init.c @@ -52,7 +52,7 @@ void __init unit_init_IRQ(void) switch (GET_XIRQ_TRIGGER(extnum)) { case XIRQ_TRIGGER_HILEVEL: case XIRQ_TRIGGER_LOWLEVEL: - set_irq_handler(XIRQ2IRQ(extnum), handle_level_irq); + set_intr_postackable(XIRQ2IRQ(extnum)); break; default: break; diff --git a/arch/powerpc/boot/dts/holly.dts b/arch/powerpc/boot/dts/holly.dts index f87fe7b9ced..c6e11ebeceb 100644 --- a/arch/powerpc/boot/dts/holly.dts +++ b/arch/powerpc/boot/dts/holly.dts @@ -133,61 +133,61 @@ reg = <0x00007400 0x00000400>; big-endian; }; + }; - pci@1000 { - device_type = "pci"; - compatible = "tsi109-pci", "tsi108-pci"; - #interrupt-cells = <1>; - #size-cells = <2>; - #address-cells = <3>; - reg = <0x00001000 0x00001000>; - bus-range = <0x0 0x0>; - /*----------------------------------------------------+ - | PCI memory range. - | 01 denotes I/O space - | 02 denotes 32-bit memory space - +----------------------------------------------------*/ - ranges = <0x02000000 0x00000000 0x40000000 0x40000000 0x00000000 0x10000000 - 0x01000000 0x00000000 0x00000000 0x7e000000 0x00000000 0x00010000>; - clock-frequency = <133333332>; - interrupt-parent = <&MPIC>; + pci@c0001000 { + device_type = "pci"; + compatible = "tsi109-pci", "tsi108-pci"; + #interrupt-cells = <1>; + #size-cells = <2>; + #address-cells = <3>; + reg = <0xc0001000 0x00001000>; + bus-range = <0x0 0x0>; + /*----------------------------------------------------+ + | PCI memory range. + | 01 denotes I/O space + | 02 denotes 32-bit memory space + +----------------------------------------------------*/ + ranges = <0x02000000 0x00000000 0x40000000 0x40000000 0x00000000 0x10000000 + 0x01000000 0x00000000 0x00000000 0x7e000000 0x00000000 0x00010000>; + clock-frequency = <133333332>; + interrupt-parent = <&MPIC>; + interrupts = <0x17 0x2>; + interrupt-map-mask = <0xf800 0x0 0x0 0x7>; + /*----------------------------------------------------+ + | The INTA, INTB, INTC, INTD are shared. + +----------------------------------------------------*/ + interrupt-map = < + 0x800 0x0 0x0 0x1 &RT0 0x24 0x0 + 0x800 0x0 0x0 0x2 &RT0 0x25 0x0 + 0x800 0x0 0x0 0x3 &RT0 0x26 0x0 + 0x800 0x0 0x0 0x4 &RT0 0x27 0x0 + + 0x1000 0x0 0x0 0x1 &RT0 0x25 0x0 + 0x1000 0x0 0x0 0x2 &RT0 0x26 0x0 + 0x1000 0x0 0x0 0x3 &RT0 0x27 0x0 + 0x1000 0x0 0x0 0x4 &RT0 0x24 0x0 + + 0x1800 0x0 0x0 0x1 &RT0 0x26 0x0 + 0x1800 0x0 0x0 0x2 &RT0 0x27 0x0 + 0x1800 0x0 0x0 0x3 &RT0 0x24 0x0 + 0x1800 0x0 0x0 0x4 &RT0 0x25 0x0 + + 0x2000 0x0 0x0 0x1 &RT0 0x27 0x0 + 0x2000 0x0 0x0 0x2 &RT0 0x24 0x0 + 0x2000 0x0 0x0 0x3 &RT0 0x25 0x0 + 0x2000 0x0 0x0 0x4 &RT0 0x26 0x0 + >; + + RT0: router@1180 { + device_type = "pic-router"; + interrupt-controller; + big-endian; + clock-frequency = <0>; + #address-cells = <0>; + #interrupt-cells = <2>; interrupts = <0x17 0x2>; - interrupt-map-mask = <0xf800 0x0 0x0 0x7>; - /*----------------------------------------------------+ - | The INTA, INTB, INTC, INTD are shared. - +----------------------------------------------------*/ - interrupt-map = < - 0x800 0x0 0x0 0x1 &RT0 0x24 0x0 - 0x800 0x0 0x0 0x2 &RT0 0x25 0x0 - 0x800 0x0 0x0 0x3 &RT0 0x26 0x0 - 0x800 0x0 0x0 0x4 &RT0 0x27 0x0 - - 0x1000 0x0 0x0 0x1 &RT0 0x25 0x0 - 0x1000 0x0 0x0 0x2 &RT0 0x26 0x0 - 0x1000 0x0 0x0 0x3 &RT0 0x27 0x0 - 0x1000 0x0 0x0 0x4 &RT0 0x24 0x0 - - 0x1800 0x0 0x0 0x1 &RT0 0x26 0x0 - 0x1800 0x0 0x0 0x2 &RT0 0x27 0x0 - 0x1800 0x0 0x0 0x3 &RT0 0x24 0x0 - 0x1800 0x0 0x0 0x4 &RT0 0x25 0x0 - - 0x2000 0x0 0x0 0x1 &RT0 0x27 0x0 - 0x2000 0x0 0x0 0x2 &RT0 0x24 0x0 - 0x2000 0x0 0x0 0x3 &RT0 0x25 0x0 - 0x2000 0x0 0x0 0x4 &RT0 0x26 0x0 - >; - - RT0: router@1180 { - device_type = "pic-router"; - interrupt-controller; - big-endian; - clock-frequency = <0>; - #address-cells = <0>; - #interrupt-cells = <2>; - interrupts = <0x17 0x2>; - interrupt-parent = <&MPIC>; - }; + interrupt-parent = <&MPIC>; }; }; diff --git a/arch/powerpc/kernel/idle.c b/arch/powerpc/kernel/idle.c index d308a9f70f1..31982d05d81 100644 --- a/arch/powerpc/kernel/idle.c +++ b/arch/powerpc/kernel/idle.c @@ -34,11 +34,7 @@ #include <asm/smp.h> #ifdef CONFIG_HOTPLUG_CPU -/* this is used for software suspend, and that shuts down - * CPUs even while the system is still booting... */ -#define cpu_should_die() (cpu_is_offline(smp_processor_id()) && \ - (system_state == SYSTEM_RUNNING \ - || system_state == SYSTEM_BOOTING)) +#define cpu_should_die() cpu_is_offline(smp_processor_id()) #else #define cpu_should_die() 0 #endif diff --git a/arch/powerpc/kernel/kgdb.c b/arch/powerpc/kernel/kgdb.c index b4fdf2f2743..fe8f71dd0b3 100644 --- a/arch/powerpc/kernel/kgdb.c +++ b/arch/powerpc/kernel/kgdb.c @@ -347,9 +347,8 @@ int kgdb_arch_handle_exception(int vector, int signo, int err_code, linux_regs->msr |= MSR_SE; #endif kgdb_single_step = 1; - if (kgdb_contthread) - atomic_set(&kgdb_cpu_doing_single_step, - raw_smp_processor_id()); + atomic_set(&kgdb_cpu_doing_single_step, + raw_smp_processor_id()); } return 0; } diff --git a/arch/powerpc/platforms/fsl_uli1575.c b/arch/powerpc/platforms/fsl_uli1575.c index ef74a0763ec..8c619963bec 100644 --- a/arch/powerpc/platforms/fsl_uli1575.c +++ b/arch/powerpc/platforms/fsl_uli1575.c @@ -219,11 +219,21 @@ static void __devinit quirk_final_uli5249(struct pci_dev *dev) int i; u8 *dummy; struct pci_bus *bus = dev->bus; + resource_size_t end = 0; + + for (i = PCI_BRIDGE_RESOURCES; i < PCI_BRIDGE_RESOURCES+3; i++) { + unsigned long flags = pci_resource_flags(dev, i); + if ((flags & (IORESOURCE_MEM|IORESOURCE_PREFETCH)) == IORESOURCE_MEM) + end = pci_resource_end(dev, i); + } for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) { if ((bus->resource[i]) && (bus->resource[i]->flags & IORESOURCE_MEM)) { - dummy = ioremap(bus->resource[i]->end - 3, 0x4); + if (bus->resource[i]->end == end) + dummy = ioremap(bus->resource[i]->start, 0x4); + else + dummy = ioremap(bus->resource[i]->end - 3, 0x4); if (dummy) { in_8(dummy); iounmap(dummy); diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c index ca114fe46ff..06acb1a18bb 100644 --- a/arch/s390/kernel/time.c +++ b/arch/s390/kernel/time.c @@ -169,6 +169,8 @@ void init_cpu_timer(void) static void clock_comparator_interrupt(__u16 code) { + if (S390_lowcore.clock_comparator == -1ULL) + set_clock_comparator(S390_lowcore.clock_comparator); } static void etr_timing_alert(struct etr_irq_parm *); diff --git a/arch/s390/lib/delay.c b/arch/s390/lib/delay.c index fc6ab6094df..0953cee05ef 100644 --- a/arch/s390/lib/delay.c +++ b/arch/s390/lib/delay.c @@ -1,14 +1,9 @@ /* - * arch/s390/lib/delay.c * Precise Delay Loops for S390 * - * S390 version - * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation - * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), - * - * Derived from "arch/i386/lib/delay.c" - * Copyright (C) 1993 Linus Torvalds - * Copyright (C) 1997 Martin Mares <mj@atrey.karlin.mff.cuni.cz> + * Copyright IBM Corp. 1999,2008 + * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>, + * Heiko Carstens <heiko.carstens@de.ibm.com>, */ #include <linux/sched.h> @@ -29,30 +24,31 @@ void __delay(unsigned long loops) asm volatile("0: brct %0,0b" : : "d" ((loops/2) + 1)); } -/* - * Waits for 'usecs' microseconds using the TOD clock comparator. - */ -void __udelay(unsigned long usecs) +static void __udelay_disabled(unsigned long usecs) { - u64 end, time, old_cc = 0; - unsigned long flags, cr0, mask, dummy; - int irq_context; + unsigned long mask, cr0, cr0_saved; + u64 clock_saved; - irq_context = in_interrupt(); - if (!irq_context) - local_bh_disable(); - local_irq_save(flags); - if (raw_irqs_disabled_flags(flags)) { - old_cc = local_tick_disable(); - S390_lowcore.clock_comparator = -1ULL; - __ctl_store(cr0, 0, 0); - dummy = (cr0 & 0xffff00e0) | 0x00000800; - __ctl_load(dummy , 0, 0); - mask = psw_kernel_bits | PSW_MASK_WAIT | PSW_MASK_EXT; - } else - mask = psw_kernel_bits | PSW_MASK_WAIT | - PSW_MASK_EXT | PSW_MASK_IO; + clock_saved = local_tick_disable(); + set_clock_comparator(get_clock() + ((u64) usecs << 12)); + __ctl_store(cr0_saved, 0, 0); + cr0 = (cr0_saved & 0xffff00e0) | 0x00000800; + __ctl_load(cr0 , 0, 0); + mask = psw_kernel_bits | PSW_MASK_WAIT | PSW_MASK_EXT; + trace_hardirqs_on(); + __load_psw_mask(mask); + local_irq_disable(); + __ctl_load(cr0_saved, 0, 0); + local_tick_enable(clock_saved); + set_clock_comparator(S390_lowcore.clock_comparator); +} +static void __udelay_enabled(unsigned long usecs) +{ + unsigned long mask; + u64 end, time; + + mask = psw_kernel_bits | PSW_MASK_WAIT | PSW_MASK_EXT | PSW_MASK_IO; end = get_clock() + ((u64) usecs << 12); do { time = end < S390_lowcore.clock_comparator ? @@ -62,13 +58,37 @@ void __udelay(unsigned long usecs) __load_psw_mask(mask); local_irq_disable(); } while (get_clock() < end); + set_clock_comparator(S390_lowcore.clock_comparator); +} - if (raw_irqs_disabled_flags(flags)) { - __ctl_load(cr0, 0, 0); - local_tick_enable(old_cc); +/* + * Waits for 'usecs' microseconds using the TOD clock comparator. + */ +void __udelay(unsigned long usecs) +{ + unsigned long flags; + + preempt_disable(); + local_irq_save(flags); + if (in_irq()) { + __udelay_disabled(usecs); + goto out; + } + if (in_softirq()) { + if (raw_irqs_disabled_flags(flags)) + __udelay_disabled(usecs); + else + __udelay_enabled(usecs); + goto out; } - if (!irq_context) + if (raw_irqs_disabled_flags(flags)) { + local_bh_disable(); + __udelay_disabled(usecs); _local_bh_enable(); - set_clock_comparator(S390_lowcore.clock_comparator); + goto out; + } + __udelay_enabled(usecs); +out: local_irq_restore(flags); + preempt_enable(); } diff --git a/arch/sparc64/kernel/of_device.c b/arch/sparc64/kernel/of_device.c index f845f150f56..100ebd52749 100644 --- a/arch/sparc64/kernel/of_device.c +++ b/arch/sparc64/kernel/of_device.c @@ -169,7 +169,7 @@ static unsigned long of_bus_default_get_flags(const u32 *addr, unsigned long fla static int of_bus_pci_match(struct device_node *np) { - if (!strcmp(np->type, "pci") || !strcmp(np->type, "pciex")) { + if (!strcmp(np->name, "pci")) { const char *model = of_get_property(np, "model", NULL); if (model && !strcmp(model, "SUNW,simba")) @@ -200,7 +200,7 @@ static int of_bus_simba_match(struct device_node *np) /* Treat PCI busses lacking ranges property just like * simba. */ - if (!strcmp(np->type, "pci") || !strcmp(np->type, "pciex")) { + if (!strcmp(np->name, "pci")) { if (!of_find_property(np, "ranges", NULL)) return 1; } @@ -429,7 +429,7 @@ static int __init use_1to1_mapping(struct device_node *pp) * it lacks a ranges property, and this will include * cases like Simba. */ - if (!strcmp(pp->type, "pci") || !strcmp(pp->type, "pciex")) + if (!strcmp(pp->name, "pci")) return 0; return 1; @@ -714,8 +714,7 @@ static unsigned int __init build_one_device_irq(struct of_device *op, break; } } else { - if (!strcmp(pp->type, "pci") || - !strcmp(pp->type, "pciex")) { + if (!strcmp(pp->name, "pci")) { unsigned int this_orig_irq = irq; irq = pci_irq_swizzle(dp, pp, irq); diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index 55096195458..80dad76f8b8 100644 --- a/arch/sparc64/kernel/pci.c +++ b/arch/sparc64/kernel/pci.c @@ -425,7 +425,7 @@ struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, dev->current_state = 4; /* unknown power state */ dev->error_state = pci_channel_io_normal; - if (!strcmp(type, "pci") || !strcmp(type, "pciex")) { + if (!strcmp(node->name, "pci")) { /* a PCI-PCI bridge */ dev->hdr_type = PCI_HEADER_TYPE_BRIDGE; dev->rom_base_reg = PCI_ROM_ADDRESS1; diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index ed92864d132..97f0d2b6dc0 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -29,6 +29,7 @@ config X86 select HAVE_FTRACE select HAVE_KVM if ((X86_32 && !X86_VOYAGER && !X86_VISWS && !X86_NUMAQ) || X86_64) select HAVE_ARCH_KGDB if !X86_VOYAGER + select HAVE_ARCH_TRACEHOOK select HAVE_GENERIC_DMA_COHERENT if X86_32 select HAVE_EFFICIENT_UNALIGNED_ACCESS @@ -1020,7 +1021,7 @@ config HAVE_ARCH_ALLOC_REMAP config ARCH_FLATMEM_ENABLE def_bool y - depends on X86_32 && ARCH_SELECT_MEMORY_MODEL && X86_PC && !NUMA + depends on X86_32 && ARCH_SELECT_MEMORY_MODEL && !NUMA config ARCH_DISCONTIGMEM_ENABLE def_bool y @@ -1036,7 +1037,7 @@ config ARCH_SPARSEMEM_DEFAULT config ARCH_SPARSEMEM_ENABLE def_bool y - depends on X86_64 || NUMA || (EXPERIMENTAL && X86_PC) + depends on X86_64 || NUMA || (EXPERIMENTAL && X86_PC) || X86_GENERICARCH select SPARSEMEM_STATIC if X86_32 select SPARSEMEM_VMEMMAP_ENABLE if X86_64 @@ -1117,10 +1118,10 @@ config MTRR You can safely say Y even if your machine doesn't have MTRRs, you'll just add about 9 KB to your kernel. - See <file:Documentation/mtrr.txt> for more information. + See <file:Documentation/x86/mtrr.txt> for more information. config MTRR_SANITIZER - bool + def_bool y prompt "MTRR cleanup support" depends on MTRR help @@ -1131,7 +1132,7 @@ config MTRR_SANITIZER The largest mtrr entry size for a continous block can be set with mtrr_chunk_size. - If unsure, say N. + If unsure, say Y. config MTRR_SANITIZER_ENABLE_DEFAULT int "MTRR cleanup enable value (0-1)" @@ -1191,7 +1192,6 @@ config IRQBALANCE config SECCOMP def_bool y prompt "Enable seccomp to safely compute untrusted bytecode" - depends on PROC_FS help This kernel feature is useful for number crunching applications that may need to compute untrusted bytecode during their @@ -1199,7 +1199,7 @@ config SECCOMP the process as file descriptors supporting the read/write syscalls, it's possible to isolate those applications in their own address space using seccomp. Once seccomp is - enabled via /proc/<pid>/seccomp, it cannot be disabled + enabled via prctl(PR_SET_SECCOMP), it cannot be disabled and the task is only allowed to execute a few safe syscalls defined by each seccomp mode. @@ -1356,14 +1356,14 @@ config PHYSICAL_ALIGN Don't change this unless you know what you are doing. config HOTPLUG_CPU - bool "Support for suspend on SMP and hot-pluggable CPUs (EXPERIMENTAL)" - depends on SMP && HOTPLUG && EXPERIMENTAL && !X86_VOYAGER + bool "Support for hot-pluggable CPUs" + depends on SMP && HOTPLUG && !X86_VOYAGER ---help--- - Say Y here to experiment with turning CPUs off and on, and to - enable suspend on SMP systems. CPUs can be controlled through - /sys/devices/system/cpu. - Say N if you want to disable CPU hotplug and don't need to - suspend. + Say Y here to allow turning CPUs off and on. CPUs can be + controlled through /sys/devices/system/cpu. + ( Note: power management support will enable this option + automatically on SMP systems. ) + Say N if you want to disable CPU hotplug. config COMPAT_VDSO def_bool y @@ -1378,6 +1378,51 @@ config COMPAT_VDSO If unsure, say Y. +config CMDLINE_BOOL + bool "Built-in kernel command line" + default n + help + Allow for specifying boot arguments to the kernel at + build time. On some systems (e.g. embedded ones), it is + necessary or convenient to provide some or all of the + kernel boot arguments with the kernel itself (that is, + to not rely on the boot loader to provide them.) + + To compile command line arguments into the kernel, + set this option to 'Y', then fill in the + the boot arguments in CONFIG_CMDLINE. + + Systems with fully functional boot loaders (i.e. non-embedded) + should leave this option set to 'N'. + +config CMDLINE + string "Built-in kernel command string" + depends on CMDLINE_BOOL + default "" + help + Enter arguments here that should be compiled into the kernel + image and used at boot time. If the boot loader provides a + command line at boot time, it is appended to this string to + form the full kernel command line, when the system boots. + + However, you can use the CONFIG_CMDLINE_OVERRIDE option to + change this behavior. + + In most cases, the command line (whether built-in or provided + by the boot loader) should specify the device for the root + file system. + +config CMDLINE_OVERRIDE + bool "Built-in command line overrides boot loader arguments" + default n + depends on CMDLINE_BOOL + help + Set this option to 'Y' to have the kernel ignore the boot loader + command line, and use ONLY the built-in command line. + + This is used to work around broken boot loaders. This should + be set to 'N' under normal conditions. + endmenu config ARCH_ENABLE_MEMORY_HOTPLUG @@ -1773,7 +1818,7 @@ config COMPAT_FOR_U64_ALIGNMENT config SYSVIPC_COMPAT def_bool y - depends on X86_64 && COMPAT && SYSVIPC + depends on COMPAT && SYSVIPC endmenu diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu index b225219c448..60a85768cfc 100644 --- a/arch/x86/Kconfig.cpu +++ b/arch/x86/Kconfig.cpu @@ -418,3 +418,21 @@ config X86_MINIMUM_CPU_FAMILY config X86_DEBUGCTLMSR def_bool y depends on !(MK6 || MWINCHIPC6 || MWINCHIP2 || MWINCHIP3D || MCYRIXIII || M586MMX || M586TSC || M586 || M486 || M386) + +config X86_DS + bool "Debug Store support" + default y + help + Add support for Debug Store. + This allows the kernel to provide a memory buffer to the hardware + to store various profiling and tracing events. + +config X86_PTRACE_BTS + bool "ptrace interface to Branch Trace Store" + default y + depends on (X86_DS && X86_DEBUGCTLMSR) + help + Add a ptrace interface to allow collecting an execution trace + of the traced task. + This collects control flow changes in a (cyclic) buffer and allows + debuggers to fill in the gaps and show an execution trace of the debuggee. diff --git a/arch/x86/boot/compressed/head_32.S b/arch/x86/boot/compressed/head_32.S index ba7736cf2ec..29c5fbf0839 100644 --- a/arch/x86/boot/compressed/head_32.S +++ b/arch/x86/boot/compressed/head_32.S @@ -137,14 +137,15 @@ relocated: */ movl output_len(%ebx), %eax pushl %eax + # push arguments for decompress_kernel: pushl %ebp # output address movl input_len(%ebx), %eax pushl %eax # input_len leal input_data(%ebx), %eax pushl %eax # input_data leal boot_heap(%ebx), %eax - pushl %eax # heap area as third argument - pushl %esi # real mode pointer as second arg + pushl %eax # heap area + pushl %esi # real mode pointer call decompress_kernel addl $20, %esp popl %ecx diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c index 9fea7370647..5780d361105 100644 --- a/arch/x86/boot/compressed/misc.c +++ b/arch/x86/boot/compressed/misc.c @@ -16,7 +16,7 @@ */ #undef CONFIG_PARAVIRT #ifdef CONFIG_X86_32 -#define _ASM_DESC_H_ 1 +#define ASM_X86__DESC_H 1 #endif #ifdef CONFIG_X86_64 @@ -27,7 +27,7 @@ #include <linux/linkage.h> #include <linux/screen_info.h> #include <linux/elf.h> -#include <asm/io.h> +#include <linux/io.h> #include <asm/page.h> #include <asm/boot.h> #include <asm/bootparam.h> @@ -251,7 +251,7 @@ static void __putstr(int error, const char *s) y--; } } else { - vidmem [(x + cols * y) * 2] = c; + vidmem[(x + cols * y) * 2] = c; if (++x >= cols) { x = 0; if (++y >= lines) { @@ -277,7 +277,8 @@ static void *memset(void *s, int c, unsigned n) int i; char *ss = s; - for (i = 0; i < n; i++) ss[i] = c; + for (i = 0; i < n; i++) + ss[i] = c; return s; } @@ -287,7 +288,8 @@ static void *memcpy(void *dest, const void *src, unsigned n) const char *s = src; char *d = dest; - for (i = 0; i < n; i++) d[i] = s[i]; + for (i = 0; i < n; i++) + d[i] = s[i]; return dest; } diff --git a/arch/x86/boot/compressed/relocs.c b/arch/x86/boot/compressed/relocs.c index a1310c52fc0..857e492c571 100644 --- a/arch/x86/boot/compressed/relocs.c +++ b/arch/x86/boot/compressed/relocs.c @@ -492,7 +492,7 @@ static void walk_relocs(void (*visit)(Elf32_Rel *rel, Elf32_Sym *sym)) continue; } sh_symtab = sec_symtab->symtab; - sym_strtab = sec->link->strtab; + sym_strtab = sec_symtab->link->strtab; for (j = 0; j < sec->shdr.sh_size/sizeof(Elf32_Rel); j++) { Elf32_Rel *rel; Elf32_Sym *sym; diff --git a/arch/x86/boot/header.S b/arch/x86/boot/header.S index af86e431acf..b993062e9a5 100644 --- a/arch/x86/boot/header.S +++ b/arch/x86/boot/header.S @@ -30,7 +30,6 @@ SYSSEG = DEF_SYSSEG /* system loaded at 0x10000 (65536) */ SYSSIZE = DEF_SYSSIZE /* system size: # of 16-byte clicks */ /* to be loaded */ ROOT_DEV = 0 /* ROOT_DEV is now written by "build" */ -SWAP_DEV = 0 /* SWAP_DEV is now written by "build" */ #ifndef SVGA_MODE #define SVGA_MODE ASK_VGA diff --git a/arch/x86/configs/i386_defconfig b/arch/x86/configs/i386_defconfig index 104275e191a..ef9a52005ec 100644 --- a/arch/x86/configs/i386_defconfig +++ b/arch/x86/configs/i386_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.27-rc4 -# Mon Aug 25 15:04:00 2008 +# Linux kernel version: 2.6.27-rc5 +# Wed Sep 3 17:23:09 2008 # # CONFIG_64BIT is not set CONFIG_X86_32=y @@ -202,7 +202,7 @@ CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y # CONFIG_M586 is not set # CONFIG_M586TSC is not set # CONFIG_M586MMX is not set -# CONFIG_M686 is not set +CONFIG_M686=y # CONFIG_MPENTIUMII is not set # CONFIG_MPENTIUMIII is not set # CONFIG_MPENTIUMM is not set @@ -221,13 +221,14 @@ CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y # CONFIG_MVIAC3_2 is not set # CONFIG_MVIAC7 is not set # CONFIG_MPSC is not set -CONFIG_MCORE2=y +# CONFIG_MCORE2 is not set # CONFIG_GENERIC_CPU is not set CONFIG_X86_GENERIC=y CONFIG_X86_CPU=y CONFIG_X86_CMPXCHG=y CONFIG_X86_L1_CACHE_SHIFT=7 CONFIG_X86_XADD=y +# CONFIG_X86_PPRO_FENCE is not set CONFIG_X86_WP_WORKS_OK=y CONFIG_X86_INVLPG=y CONFIG_X86_BSWAP=y @@ -235,14 +236,15 @@ CONFIG_X86_POPAD_OK=y CONFIG_X86_INTEL_USERCOPY=y CONFIG_X86_USE_PPRO_CHECKSUM=y CONFIG_X86_TSC=y +CONFIG_X86_CMOV=y CONFIG_X86_MINIMUM_CPU_FAMILY=4 CONFIG_X86_DEBUGCTLMSR=y CONFIG_HPET_TIMER=y CONFIG_HPET_EMULATE_RTC=y CONFIG_DMI=y # CONFIG_IOMMU_HELPER is not set -CONFIG_NR_CPUS=4 -# CONFIG_SCHED_SMT is not set +CONFIG_NR_CPUS=64 +CONFIG_SCHED_SMT=y CONFIG_SCHED_MC=y # CONFIG_PREEMPT_NONE is not set CONFIG_PREEMPT_VOLUNTARY=y @@ -254,7 +256,8 @@ CONFIG_VM86=y # CONFIG_TOSHIBA is not set # CONFIG_I8K is not set CONFIG_X86_REBOOTFIXUPS=y -# CONFIG_MICROCODE is not set +CONFIG_MICROCODE=y +CONFIG_MICROCODE_OLD_INTERFACE=y CONFIG_X86_MSR=y CONFIG_X86_CPUID=y # CONFIG_NOHIGHMEM is not set @@ -2115,7 +2118,7 @@ CONFIG_IO_DELAY_0X80=y CONFIG_DEFAULT_IO_DELAY_TYPE=0 CONFIG_DEBUG_BOOT_PARAMS=y # CONFIG_CPA_DEBUG is not set -# CONFIG_OPTIMIZE_INLINING is not set +CONFIG_OPTIMIZE_INLINING=y # # Security options diff --git a/arch/x86/configs/x86_64_defconfig b/arch/x86/configs/x86_64_defconfig index 678c8acefe0..e620ea6e2a7 100644 --- a/arch/x86/configs/x86_64_defconfig +++ b/arch/x86/configs/x86_64_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.27-rc4 -# Mon Aug 25 14:40:46 2008 +# Linux kernel version: 2.6.27-rc5 +# Wed Sep 3 17:13:39 2008 # CONFIG_64BIT=y # CONFIG_X86_32 is not set @@ -218,17 +218,14 @@ CONFIG_X86_PC=y # CONFIG_MVIAC3_2 is not set # CONFIG_MVIAC7 is not set # CONFIG_MPSC is not set -CONFIG_MCORE2=y -# CONFIG_GENERIC_CPU is not set +# CONFIG_MCORE2 is not set +CONFIG_GENERIC_CPU=y CONFIG_X86_CPU=y -CONFIG_X86_L1_CACHE_BYTES=64 -CONFIG_X86_INTERNODE_CACHE_BYTES=64 +CONFIG_X86_L1_CACHE_BYTES=128 +CONFIG_X86_INTERNODE_CACHE_BYTES=128 CONFIG_X86_CMPXCHG=y -CONFIG_X86_L1_CACHE_SHIFT=6 +CONFIG_X86_L1_CACHE_SHIFT=7 CONFIG_X86_WP_WORKS_OK=y -CONFIG_X86_INTEL_USERCOPY=y -CONFIG_X86_USE_PPRO_CHECKSUM=y -CONFIG_X86_P6_NOP=y CONFIG_X86_TSC=y CONFIG_X86_CMPXCHG64=y CONFIG_X86_CMOV=y @@ -243,9 +240,8 @@ CONFIG_CALGARY_IOMMU_ENABLED_BY_DEFAULT=y CONFIG_AMD_IOMMU=y CONFIG_SWIOTLB=y CONFIG_IOMMU_HELPER=y -# CONFIG_MAXSMP is not set -CONFIG_NR_CPUS=4 -# CONFIG_SCHED_SMT is not set +CONFIG_NR_CPUS=64 +CONFIG_SCHED_SMT=y CONFIG_SCHED_MC=y # CONFIG_PREEMPT_NONE is not set CONFIG_PREEMPT_VOLUNTARY=y @@ -254,7 +250,8 @@ CONFIG_X86_LOCAL_APIC=y CONFIG_X86_IO_APIC=y # CONFIG_X86_MCE is not set # CONFIG_I8K is not set -# CONFIG_MICROCODE is not set +CONFIG_MICROCODE=y +CONFIG_MICROCODE_OLD_INTERFACE=y CONFIG_X86_MSR=y CONFIG_X86_CPUID=y CONFIG_NUMA=y @@ -290,7 +287,7 @@ CONFIG_BOUNCE=y CONFIG_VIRT_TO_BUS=y CONFIG_MTRR=y # CONFIG_MTRR_SANITIZER is not set -# CONFIG_X86_PAT is not set +CONFIG_X86_PAT=y CONFIG_EFI=y CONFIG_SECCOMP=y # CONFIG_HZ_100 is not set @@ -2089,7 +2086,7 @@ CONFIG_IO_DELAY_0X80=y CONFIG_DEFAULT_IO_DELAY_TYPE=0 CONFIG_DEBUG_BOOT_PARAMS=y # CONFIG_CPA_DEBUG is not set -# CONFIG_OPTIMIZE_INLINING is not set +CONFIG_OPTIMIZE_INLINING=y # # Security options diff --git a/arch/x86/ia32/ia32_aout.c b/arch/x86/ia32/ia32_aout.c index a0e1dbe67dc..127ec3f0721 100644 --- a/arch/x86/ia32/ia32_aout.c +++ b/arch/x86/ia32/ia32_aout.c @@ -85,8 +85,10 @@ static void dump_thread32(struct pt_regs *regs, struct user32 *dump) dump->regs.ax = regs->ax; dump->regs.ds = current->thread.ds; dump->regs.es = current->thread.es; - asm("movl %%fs,%0" : "=r" (fs)); dump->regs.fs = fs; - asm("movl %%gs,%0" : "=r" (gs)); dump->regs.gs = gs; + savesegment(fs, fs); + dump->regs.fs = fs; + savesegment(gs, gs); + dump->regs.gs = gs; dump->regs.orig_ax = regs->orig_ax; dump->regs.ip = regs->ip; dump->regs.cs = regs->cs; @@ -430,8 +432,9 @@ beyond_if: current->mm->start_stack = (unsigned long)create_aout_tables((char __user *)bprm->p, bprm); /* start thread */ - asm volatile("movl %0,%%fs" :: "r" (0)); \ - asm volatile("movl %0,%%es; movl %0,%%ds": :"r" (__USER32_DS)); + loadsegment(fs, 0); + loadsegment(ds, __USER32_DS); + loadsegment(es, __USER32_DS); load_gs_index(0); (regs)->ip = ex.a_entry; (regs)->sp = current->mm->start_stack; diff --git a/arch/x86/ia32/ia32_signal.c b/arch/x86/ia32/ia32_signal.c index 20af4c79579..f1a2ac777fa 100644 --- a/arch/x86/ia32/ia32_signal.c +++ b/arch/x86/ia32/ia32_signal.c @@ -206,7 +206,7 @@ struct rt_sigframe { unsigned int cur; \ unsigned short pre; \ err |= __get_user(pre, &sc->seg); \ - asm volatile("movl %%" #seg ",%0" : "=r" (cur)); \ + savesegment(seg, cur); \ pre |= mask; \ if (pre != cur) loadsegment(seg, pre); } @@ -235,7 +235,7 @@ static int ia32_restore_sigcontext(struct pt_regs *regs, */ err |= __get_user(gs, &sc->gs); gs |= 3; - asm("movl %%gs,%0" : "=r" (oldgs)); + savesegment(gs, oldgs); if (gs != oldgs) load_gs_index(gs); @@ -355,14 +355,13 @@ static int ia32_setup_sigcontext(struct sigcontext_ia32 __user *sc, { int tmp, err = 0; - tmp = 0; - __asm__("movl %%gs,%0" : "=r"(tmp): "0"(tmp)); + savesegment(gs, tmp); err |= __put_user(tmp, (unsigned int __user *)&sc->gs); - __asm__("movl %%fs,%0" : "=r"(tmp): "0"(tmp)); + savesegment(fs, tmp); err |= __put_user(tmp, (unsigned int __user *)&sc->fs); - __asm__("movl %%ds,%0" : "=r"(tmp): "0"(tmp)); + savesegment(ds, tmp); err |= __put_user(tmp, (unsigned int __user *)&sc->ds); - __asm__("movl %%es,%0" : "=r"(tmp): "0"(tmp)); + savesegment(es, tmp); err |= __put_user(tmp, (unsigned int __user *)&sc->es); err |= __put_user((u32)regs->di, &sc->di); @@ -498,8 +497,8 @@ int ia32_setup_frame(int sig, struct k_sigaction *ka, regs->dx = 0; regs->cx = 0; - asm volatile("movl %0,%%ds" :: "r" (__USER32_DS)); - asm volatile("movl %0,%%es" :: "r" (__USER32_DS)); + loadsegment(ds, __USER32_DS); + loadsegment(es, __USER32_DS); regs->cs = __USER32_CS; regs->ss = __USER32_DS; @@ -591,8 +590,8 @@ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, regs->dx = (unsigned long) &frame->info; regs->cx = (unsigned long) &frame->uc; - asm volatile("movl %0,%%ds" :: "r" (__USER32_DS)); - asm volatile("movl %0,%%es" :: "r" (__USER32_DS)); + loadsegment(ds, __USER32_DS); + loadsegment(es, __USER32_DS); regs->cs = __USER32_CS; regs->ss = __USER32_DS; diff --git a/arch/x86/ia32/sys_ia32.c b/arch/x86/ia32/sys_ia32.c index d3c64088b98..beda4232ce6 100644 --- a/arch/x86/ia32/sys_ia32.c +++ b/arch/x86/ia32/sys_ia32.c @@ -556,15 +556,6 @@ asmlinkage long sys32_rt_sigqueueinfo(int pid, int sig, return ret; } -/* These are here just in case some old ia32 binary calls it. */ -asmlinkage long sys32_pause(void) -{ - current->state = TASK_INTERRUPTIBLE; - schedule(); - return -ERESTARTNOHAND; -} - - #ifdef CONFIG_SYSCTL_SYSCALL struct sysctl_ia32 { unsigned int name; diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index bfd10fd211c..e5032d7b391 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c @@ -58,7 +58,6 @@ EXPORT_SYMBOL(acpi_disabled); #ifdef CONFIG_X86_64 #include <asm/proto.h> -#include <asm/genapic.h> #else /* X86 */ @@ -97,8 +96,6 @@ static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE; #warning ACPI uses CMPXCHG, i486 and later hardware #endif -static int acpi_mcfg_64bit_base_addr __initdata = FALSE; - /* -------------------------------------------------------------------------- Boot-time Configuration -------------------------------------------------------------------------- */ @@ -160,6 +157,8 @@ char *__init __acpi_map_table(unsigned long phys, unsigned long size) struct acpi_mcfg_allocation *pci_mmcfg_config; int pci_mmcfg_config_num; +static int acpi_mcfg_64bit_base_addr __initdata = FALSE; + static int __init acpi_mcfg_oem_check(struct acpi_table_mcfg *mcfg) { if (!strcmp(mcfg->header.oem_id, "SGI")) diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c index 65a0c1b4869..fb04e49776b 100644 --- a/arch/x86/kernel/alternative.c +++ b/arch/x86/kernel/alternative.c @@ -231,25 +231,25 @@ static void alternatives_smp_lock(u8 **start, u8 **end, u8 *text, u8 *text_end) continue; if (*ptr > text_end) continue; - text_poke(*ptr, ((unsigned char []){0xf0}), 1); /* add lock prefix */ + /* turn DS segment override prefix into lock prefix */ + text_poke(*ptr, ((unsigned char []){0xf0}), 1); }; } 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; - text_poke(*ptr, insn, 1); + /* turn lock prefix into DS segment override prefix */ + text_poke(*ptr, ((unsigned char []){0x3E}), 1); }; } diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c index 69b4d060b21..042fdc27bc9 100644 --- a/arch/x86/kernel/amd_iommu.c +++ b/arch/x86/kernel/amd_iommu.c @@ -101,10 +101,10 @@ static int iommu_queue_command(struct amd_iommu *iommu, struct iommu_cmd *cmd) */ static int iommu_completion_wait(struct amd_iommu *iommu) { - int ret, ready = 0; + int ret = 0, ready = 0; unsigned status = 0; struct iommu_cmd cmd; - unsigned long i = 0; + unsigned long flags, i = 0; memset(&cmd, 0, sizeof(cmd)); cmd.data[0] = CMD_COMPL_WAIT_INT_MASK; @@ -112,10 +112,12 @@ static int iommu_completion_wait(struct amd_iommu *iommu) iommu->need_sync = 0; - ret = iommu_queue_command(iommu, &cmd); + spin_lock_irqsave(&iommu->lock, flags); + + ret = __iommu_queue_command(iommu, &cmd); if (ret) - return ret; + goto out; while (!ready && (i < EXIT_LOOP_COUNT)) { ++i; @@ -130,6 +132,8 @@ static int iommu_completion_wait(struct amd_iommu *iommu) if (unlikely((i == EXIT_LOOP_COUNT) && printk_ratelimit())) printk(KERN_WARNING "AMD IOMMU: Completion wait loop failed\n"); +out: + spin_unlock_irqrestore(&iommu->lock, flags); return 0; } @@ -140,6 +144,7 @@ static int iommu_completion_wait(struct amd_iommu *iommu) static int iommu_queue_inv_dev_entry(struct amd_iommu *iommu, u16 devid) { struct iommu_cmd cmd; + int ret; BUG_ON(iommu == NULL); @@ -147,9 +152,11 @@ static int iommu_queue_inv_dev_entry(struct amd_iommu *iommu, u16 devid) CMD_SET_TYPE(&cmd, CMD_INV_DEV_ENTRY); cmd.data[0] = devid; + ret = iommu_queue_command(iommu, &cmd); + iommu->need_sync = 1; - return iommu_queue_command(iommu, &cmd); + return ret; } /* @@ -159,6 +166,7 @@ static int iommu_queue_inv_iommu_pages(struct amd_iommu *iommu, u64 address, u16 domid, int pde, int s) { struct iommu_cmd cmd; + int ret; memset(&cmd, 0, sizeof(cmd)); address &= PAGE_MASK; @@ -171,9 +179,11 @@ static int iommu_queue_inv_iommu_pages(struct amd_iommu *iommu, if (pde) /* PDE bit - we wan't flush everything not only the PTEs */ cmd.data[2] |= CMD_INV_IOMMU_PAGES_PDE_MASK; + ret = iommu_queue_command(iommu, &cmd); + iommu->need_sync = 1; - return iommu_queue_command(iommu, &cmd); + return ret; } /* diff --git a/arch/x86/kernel/aperture_64.c b/arch/x86/kernel/aperture_64.c index 44e21826db1..9a32b37ee2e 100644 --- a/arch/x86/kernel/aperture_64.c +++ b/arch/x86/kernel/aperture_64.c @@ -455,11 +455,11 @@ out: force_iommu || valid_agp || fallback_aper_force) { - printk(KERN_ERR + printk(KERN_INFO "Your BIOS doesn't leave a aperture memory hole\n"); - printk(KERN_ERR + printk(KERN_INFO "Please enable the IOMMU option in the BIOS setup\n"); - printk(KERN_ERR + printk(KERN_INFO "This costs you %d MB of RAM\n", 32 << fallback_aper_order); diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c index 9ee24e6bc4b..5145a6e72bb 100644 --- a/arch/x86/kernel/apm_32.c +++ b/arch/x86/kernel/apm_32.c @@ -228,12 +228,12 @@ #include <linux/suspend.h> #include <linux/kthread.h> #include <linux/jiffies.h> -#include <linux/smp_lock.h> #include <asm/system.h> #include <asm/uaccess.h> #include <asm/desc.h> #include <asm/i8253.h> +#include <asm/olpc.h> #include <asm/paravirt.h> #include <asm/reboot.h> @@ -2217,7 +2217,7 @@ static int __init apm_init(void) dmi_check_system(apm_dmi_table); - if (apm_info.bios.version == 0 || paravirt_enabled()) { + if (apm_info.bios.version == 0 || paravirt_enabled() || machine_is_olpc()) { printk(KERN_INFO "apm: BIOS not found.\n"); return -ENODEV; } diff --git a/arch/x86/kernel/asm-offsets_64.c b/arch/x86/kernel/asm-offsets_64.c index aa89387006f..505543a75a5 100644 --- a/arch/x86/kernel/asm-offsets_64.c +++ b/arch/x86/kernel/asm-offsets_64.c @@ -22,7 +22,7 @@ #define __NO_STUBS 1 #undef __SYSCALL -#undef _ASM_X86_64_UNISTD_H_ +#undef ASM_X86__UNISTD_64_H #define __SYSCALL(nr, sym) [nr] = 1, static char syscalls[] = { #include <asm/unistd.h> diff --git a/arch/x86/kernel/bios_uv.c b/arch/x86/kernel/bios_uv.c index c639bd55391..fdd585f9c53 100644 --- a/arch/x86/kernel/bios_uv.c +++ b/arch/x86/kernel/bios_uv.c @@ -25,11 +25,11 @@ x86_bios_strerror(long status) { const char *str; switch (status) { - case 0: str = "Call completed without error"; break; - case -1: str = "Not implemented"; break; - case -2: str = "Invalid argument"; break; - case -3: str = "Call completed with error"; break; - default: str = "Unknown BIOS status code"; break; + case 0: str = "Call completed without error"; break; + case -1: str = "Not implemented"; break; + case -2: str = "Invalid argument"; break; + case -3: str = "Call completed with error"; break; + default: str = "Unknown BIOS status code"; break; } return str; } diff --git a/arch/x86/kernel/cpu/common_64.c b/arch/x86/kernel/cpu/common_64.c index a11f5d4477c..305b465889b 100644 --- a/arch/x86/kernel/cpu/common_64.c +++ b/arch/x86/kernel/cpu/common_64.c @@ -430,6 +430,49 @@ static __init int setup_noclflush(char *arg) } __setup("noclflush", setup_noclflush); +struct msr_range { + unsigned min; + unsigned max; +}; + +static struct msr_range msr_range_array[] __cpuinitdata = { + { 0x00000000, 0x00000418}, + { 0xc0000000, 0xc000040b}, + { 0xc0010000, 0xc0010142}, + { 0xc0011000, 0xc001103b}, +}; + +static void __cpuinit print_cpu_msr(void) +{ + unsigned index; + u64 val; + int i; + unsigned index_min, index_max; + + for (i = 0; i < ARRAY_SIZE(msr_range_array); i++) { + index_min = msr_range_array[i].min; + index_max = msr_range_array[i].max; + for (index = index_min; index < index_max; index++) { + if (rdmsrl_amd_safe(index, &val)) + continue; + printk(KERN_INFO " MSR%08x: %016llx\n", index, val); + } + } +} + +static int show_msr __cpuinitdata; +static __init int setup_show_msr(char *arg) +{ + int num; + + get_option(&arg, &num); + + if (num > 0) + show_msr = num; + return 1; +} +__setup("show_msr=", setup_show_msr); + void __cpuinit print_cpu_info(struct cpuinfo_x86 *c) { if (c->x86_model_id[0]) @@ -439,6 +482,14 @@ void __cpuinit print_cpu_info(struct cpuinfo_x86 *c) printk(KERN_CONT " stepping %02x\n", c->x86_mask); else printk(KERN_CONT "\n"); + +#ifdef CONFIG_SMP + if (c->cpu_index < show_msr) + print_cpu_msr(); +#else + if (show_msr) + print_cpu_msr(); +#endif } static __init int setup_disablecpuid(char *arg) diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index b75f2569b8f..f113ef4595f 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c @@ -222,10 +222,11 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c) set_cpu_cap(c, X86_FEATURE_BTS); if (!(l1 & (1<<12))) set_cpu_cap(c, X86_FEATURE_PEBS); + ds_init_intel(c); } if (cpu_has_bts) - ds_init_intel(c); + ptrace_bts_init_intel(c); /* * See if we have a good local APIC by checking for buggy Pentia, diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/generic.c index cb7d3b6a80e..4e8d77f01ee 100644 --- a/arch/x86/kernel/cpu/mtrr/generic.c +++ b/arch/x86/kernel/cpu/mtrr/generic.c @@ -401,12 +401,7 @@ static void generic_get_mtrr(unsigned int reg, unsigned long *base, tmp |= ~((1<<(hi - 1)) - 1); if (tmp != mask_lo) { - static int once = 1; - - if (once) { - printk(KERN_INFO "mtrr: your BIOS has set up an incorrect mask, fixing it up.\n"); - once = 0; - } + WARN_ONCE(1, KERN_INFO "mtrr: your BIOS has set up an incorrect mask, fixing it up.\n"); mask_lo = tmp; } } diff --git a/arch/x86/kernel/cpu/mtrr/if.c b/arch/x86/kernel/cpu/mtrr/if.c index 84c480bb371..4c4214690dd 100644 --- a/arch/x86/kernel/cpu/mtrr/if.c +++ b/arch/x86/kernel/cpu/mtrr/if.c @@ -405,9 +405,9 @@ static int mtrr_seq_show(struct seq_file *seq, void *offset) } /* RED-PEN: base can be > 32bit */ len += seq_printf(seq, - "reg%02i: base=0x%05lx000 (%4luMB), size=%4lu%cB: %s, count=%d\n", + "reg%02i: base=0x%06lx000 (%5luMB), size=%5lu%cB, count=%d: %s\n", i, base, base >> (20 - PAGE_SHIFT), size, factor, - mtrr_attrib_to_str(type), mtrr_usage_table[i]); + mtrr_usage_table[i], mtrr_attrib_to_str(type)); } } return 0; diff --git a/arch/x86/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c index b117d7f8a56..c78c04821ea 100644 --- a/arch/x86/kernel/cpu/mtrr/main.c +++ b/arch/x86/kernel/cpu/mtrr/main.c @@ -729,7 +729,7 @@ struct var_mtrr_range_state { mtrr_type type; }; -struct var_mtrr_range_state __initdata range_state[RANGE_NUM]; +static struct var_mtrr_range_state __initdata range_state[RANGE_NUM]; static int __initdata debug_print; static int __init @@ -759,7 +759,8 @@ x86_get_mtrr_mem_range(struct res_range *range, int nr_range, /* take out UC ranges */ for (i = 0; i < num_var_ranges; i++) { type = range_state[i].type; - if (type != MTRR_TYPE_UNCACHABLE) + if (type != MTRR_TYPE_UNCACHABLE && + type != MTRR_TYPE_WRPROT) continue; size = range_state[i].size_pfn; if (!size) @@ -834,7 +835,14 @@ static int __init enable_mtrr_cleanup_setup(char *str) enable_mtrr_cleanup = 1; return 0; } -early_param("enble_mtrr_cleanup", enable_mtrr_cleanup_setup); +early_param("enable_mtrr_cleanup", enable_mtrr_cleanup_setup); + +static int __init mtrr_cleanup_debug_setup(char *str) +{ + debug_print = 1; + return 0; +} +early_param("mtrr_cleanup_debug", mtrr_cleanup_debug_setup); struct var_mtrr_state { unsigned long range_startk; @@ -898,6 +906,27 @@ set_var_mtrr_all(unsigned int address_bits) } } +static unsigned long to_size_factor(unsigned long sizek, char *factorp) +{ + char factor; + unsigned long base = sizek; + + if (base & ((1<<10) - 1)) { + /* not MB alignment */ + factor = 'K'; + } else if (base & ((1<<20) - 1)){ + factor = 'M'; + base >>= 10; + } else { + factor = 'G'; + base >>= 20; + } + + *factorp = factor; + + return base; +} + static unsigned int __init range_to_mtrr(unsigned int reg, unsigned long range_startk, unsigned long range_sizek, unsigned char type) @@ -919,13 +948,21 @@ range_to_mtrr(unsigned int reg, unsigned long range_startk, align = max_align; sizek = 1 << align; - if (debug_print) + if (debug_print) { + char start_factor = 'K', size_factor = 'K'; + unsigned long start_base, size_base; + + start_base = to_size_factor(range_startk, &start_factor), + size_base = to_size_factor(sizek, &size_factor), + printk(KERN_DEBUG "Setting variable MTRR %d, " - "base: %ldMB, range: %ldMB, type %s\n", - reg, range_startk >> 10, sizek >> 10, + "base: %ld%cB, range: %ld%cB, type %s\n", + reg, start_base, start_factor, + size_base, size_factor, (type == MTRR_TYPE_UNCACHABLE)?"UC": ((type == MTRR_TYPE_WRBACK)?"WB":"Other") ); + } save_var_mtrr(reg++, range_startk, sizek, type); range_startk += sizek; range_sizek -= sizek; @@ -970,6 +1007,8 @@ range_to_mtrr_with_hole(struct var_mtrr_state *state, unsigned long basek, /* try to append some small hole */ range0_basek = state->range_startk; range0_sizek = ALIGN(state->range_sizek, chunk_sizek); + + /* no increase */ if (range0_sizek == state->range_sizek) { if (debug_print) printk(KERN_DEBUG "rangeX: %016lx - %016lx\n", @@ -980,13 +1019,40 @@ range_to_mtrr_with_hole(struct var_mtrr_state *state, unsigned long basek, return 0; } - range0_sizek -= chunk_sizek; - if (range0_sizek && sizek) { - while (range0_basek + range0_sizek > (basek + sizek)) { - range0_sizek -= chunk_sizek; - if (!range0_sizek) - break; - } + /* only cut back, when it is not the last */ + if (sizek) { + while (range0_basek + range0_sizek > (basek + sizek)) { + if (range0_sizek >= chunk_sizek) + range0_sizek -= chunk_sizek; + else + range0_sizek = 0; + + if (!range0_sizek) + break; + } + } + +second_try: + range_basek = range0_basek + range0_sizek; + + /* one hole in the middle */ + if (range_basek > basek && range_basek <= (basek + sizek)) + second_sizek = range_basek - basek; + + if (range0_sizek > state->range_sizek) { + + /* one hole in middle or at end */ + hole_sizek = range0_sizek - state->range_sizek - second_sizek; + + /* hole size should be less than half of range0 size */ + if (hole_sizek >= (range0_sizek >> 1) && + range0_sizek >= chunk_sizek) { + range0_sizek -= chunk_sizek; + second_sizek = 0; + hole_sizek = 0; + + goto second_try; + } } if (range0_sizek) { @@ -996,50 +1062,28 @@ range_to_mtrr_with_hole(struct var_mtrr_state *state, unsigned long basek, (range0_basek + range0_sizek)<<10); state->reg = range_to_mtrr(state->reg, range0_basek, range0_sizek, MTRR_TYPE_WRBACK); - - } - - range_basek = range0_basek + range0_sizek; - range_sizek = chunk_sizek; - - if (range_basek + range_sizek > basek && - range_basek + range_sizek <= (basek + sizek)) { - /* one hole */ - second_basek = basek; - second_sizek = range_basek + range_sizek - basek; } - /* if last piece, only could one hole near end */ - if ((second_basek || !basek) && - range_sizek - (state->range_sizek - range0_sizek) - second_sizek < - (chunk_sizek >> 1)) { - /* - * one hole in middle (second_sizek is 0) or at end - * (second_sizek is 0 ) - */ - hole_sizek = range_sizek - (state->range_sizek - range0_sizek) - - second_sizek; - hole_basek = range_basek + range_sizek - hole_sizek - - second_sizek; - } else { - /* fallback for big hole, or several holes */ + if (range0_sizek < state->range_sizek) { + /* need to handle left over */ range_sizek = state->range_sizek - range0_sizek; - second_basek = 0; - second_sizek = 0; + + if (debug_print) + printk(KERN_DEBUG "range: %016lx - %016lx\n", + range_basek<<10, + (range_basek + range_sizek)<<10); + state->reg = range_to_mtrr(state->reg, range_basek, + range_sizek, MTRR_TYPE_WRBACK); } - if (debug_print) - printk(KERN_DEBUG "range: %016lx - %016lx\n", range_basek<<10, - (range_basek + range_sizek)<<10); - state->reg = range_to_mtrr(state->reg, range_basek, range_sizek, - MTRR_TYPE_WRBACK); if (hole_sizek) { + hole_basek = range_basek - hole_sizek - second_sizek; if (debug_print) printk(KERN_DEBUG "hole: %016lx - %016lx\n", - hole_basek<<10, (hole_basek + hole_sizek)<<10); - state->reg = range_to_mtrr(state->reg, hole_basek, hole_sizek, - MTRR_TYPE_UNCACHABLE); - + hole_basek<<10, + (hole_basek + hole_sizek)<<10); + state->reg = range_to_mtrr(state->reg, hole_basek, + hole_sizek, MTRR_TYPE_UNCACHABLE); } return second_sizek; @@ -1154,11 +1198,11 @@ struct mtrr_cleanup_result { }; /* - * gran_size: 1M, 2M, ..., 2G - * chunk size: gran_size, ..., 4G - * so we need (2+13)*6 + * gran_size: 64K, 128K, 256K, 512K, 1M, 2M, ..., 2G + * chunk size: gran_size, ..., 2G + * so we need (1+16)*8 */ -#define NUM_RESULT 90 +#define NUM_RESULT 136 #define PSHIFT (PAGE_SHIFT - 10) static struct mtrr_cleanup_result __initdata result[NUM_RESULT]; @@ -1168,13 +1212,14 @@ static unsigned long __initdata min_loss_pfn[RANGE_NUM]; static int __init mtrr_cleanup(unsigned address_bits) { unsigned long extra_remove_base, extra_remove_size; - unsigned long i, base, size, def, dummy; + unsigned long base, size, def, dummy; mtrr_type type; int nr_range, nr_range_new; u64 chunk_size, gran_size; unsigned long range_sums, range_sums_new; int index_good; int num_reg_good; + int i; /* extra one for all 0 */ int num[MTRR_NUM_TYPES + 1]; @@ -1204,6 +1249,8 @@ static int __init mtrr_cleanup(unsigned address_bits) continue; if (!size) type = MTRR_NUM_TYPES; + if (type == MTRR_TYPE_WRPROT) + type = MTRR_TYPE_UNCACHABLE; num[type]++; } @@ -1216,23 +1263,57 @@ static int __init mtrr_cleanup(unsigned address_bits) num_var_ranges - num[MTRR_NUM_TYPES]) return 0; + /* print original var MTRRs at first, for debugging: */ + printk(KERN_DEBUG "original variable MTRRs\n"); + for (i = 0; i < num_var_ranges; i++) { + char start_factor = 'K', size_factor = 'K'; + unsigned long start_base, size_base; + + size_base = range_state[i].size_pfn << (PAGE_SHIFT - 10); + if (!size_base) + continue; + + size_base = to_size_factor(size_base, &size_factor), + start_base = range_state[i].base_pfn << (PAGE_SHIFT - 10); + start_base = to_size_factor(start_base, &start_factor), + type = range_state[i].type; + + printk(KERN_DEBUG "reg %d, base: %ld%cB, range: %ld%cB, type %s\n", + i, start_base, start_factor, + size_base, size_factor, + (type == MTRR_TYPE_UNCACHABLE) ? "UC" : + ((type == MTRR_TYPE_WRPROT) ? "WP" : + ((type == MTRR_TYPE_WRBACK) ? "WB" : "Other")) + ); + } + memset(range, 0, sizeof(range)); extra_remove_size = 0; - if (mtrr_tom2) { - extra_remove_base = 1 << (32 - PAGE_SHIFT); + extra_remove_base = 1 << (32 - PAGE_SHIFT); + if (mtrr_tom2) extra_remove_size = (mtrr_tom2 >> PAGE_SHIFT) - extra_remove_base; - } nr_range = x86_get_mtrr_mem_range(range, 0, extra_remove_base, extra_remove_size); + /* + * [0, 1M) should always be coverred by var mtrr with WB + * and fixed mtrrs should take effective before var mtrr for it + */ + nr_range = add_range_with_merge(range, nr_range, 0, + (1ULL<<(20 - PAGE_SHIFT)) - 1); + /* sort the ranges */ + sort(range, nr_range, sizeof(struct res_range), cmp_range, NULL); + range_sums = sum_ranges(range, nr_range); printk(KERN_INFO "total RAM coverred: %ldM\n", range_sums >> (20 - PAGE_SHIFT)); if (mtrr_chunk_size && mtrr_gran_size) { int num_reg; + char gran_factor, chunk_factor, lose_factor; + unsigned long gran_base, chunk_base, lose_base; - debug_print = 1; + debug_print++; /* convert ranges to var ranges state */ num_reg = x86_setup_var_mtrrs(range, nr_range, mtrr_chunk_size, mtrr_gran_size); @@ -1256,34 +1337,48 @@ static int __init mtrr_cleanup(unsigned address_bits) result[i].lose_cover_sizek = (range_sums - range_sums_new) << PSHIFT; - printk(KERN_INFO "%sgran_size: %ldM \tchunk_size: %ldM \t", - result[i].bad?"*BAD*":" ", result[i].gran_sizek >> 10, - result[i].chunk_sizek >> 10); - printk(KERN_CONT "num_reg: %d \tlose cover RAM: %s%ldM \n", + gran_base = to_size_factor(result[i].gran_sizek, &gran_factor), + chunk_base = to_size_factor(result[i].chunk_sizek, &chunk_factor), + lose_base = to_size_factor(result[i].lose_cover_sizek, &lose_factor), + printk(KERN_INFO "%sgran_size: %ld%c \tchunk_size: %ld%c \t", + result[i].bad?"*BAD*":" ", + gran_base, gran_factor, chunk_base, chunk_factor); + printk(KERN_CONT "num_reg: %d \tlose cover RAM: %s%ld%c\n", result[i].num_reg, result[i].bad?"-":"", - result[i].lose_cover_sizek >> 10); + lose_base, lose_factor); if (!result[i].bad) { set_var_mtrr_all(address_bits); return 1; } printk(KERN_INFO "invalid mtrr_gran_size or mtrr_chunk_size, " "will find optimal one\n"); - debug_print = 0; + debug_print--; memset(result, 0, sizeof(result[0])); } i = 0; memset(min_loss_pfn, 0xff, sizeof(min_loss_pfn)); memset(result, 0, sizeof(result)); - for (gran_size = (1ULL<<20); gran_size < (1ULL<<32); gran_size <<= 1) { - for (chunk_size = gran_size; chunk_size < (1ULL<<33); + for (gran_size = (1ULL<<16); gran_size < (1ULL<<32); gran_size <<= 1) { + char gran_factor; + unsigned long gran_base; + + if (debug_print) + gran_base = to_size_factor(gran_size >> 10, &gran_factor); + + for (chunk_size = gran_size; chunk_size < (1ULL<<32); chunk_size <<= 1) { int num_reg; - if (debug_print) - printk(KERN_INFO - "\ngran_size: %lldM chunk_size_size: %lldM\n", - gran_size >> 20, chunk_size >> 20); + if (debug_print) { + char chunk_factor; + unsigned long chunk_base; + + chunk_base = to_size_factor(chunk_size>>10, &chunk_factor), + printk(KERN_INFO "\n"); + printk(KERN_INFO "gran_size: %ld%c chunk_size: %ld%c \n", + gran_base, gran_factor, chunk_base, chunk_factor); + } if (i >= NUM_RESULT) continue; @@ -1326,12 +1421,18 @@ static int __init mtrr_cleanup(unsigned address_bits) /* print out all */ for (i = 0; i < NUM_RESULT; i++) { - printk(KERN_INFO "%sgran_size: %ldM \tchunk_size: %ldM \t", - result[i].bad?"*BAD* ":" ", result[i].gran_sizek >> 10, - result[i].chunk_sizek >> 10); - printk(KERN_CONT "num_reg: %d \tlose RAM: %s%ldM\n", - result[i].num_reg, result[i].bad?"-":"", - result[i].lose_cover_sizek >> 10); + char gran_factor, chunk_factor, lose_factor; + unsigned long gran_base, chunk_base, lose_base; + + gran_base = to_size_factor(result[i].gran_sizek, &gran_factor), + chunk_base = to_size_factor(result[i].chunk_sizek, &chunk_factor), + lose_base = to_size_factor(result[i].lose_cover_sizek, &lose_factor), + printk(KERN_INFO "%sgran_size: %ld%c \tchunk_size: %ld%c \t", + result[i].bad?"*BAD*":" ", + gran_base, gran_factor, chunk_base, chunk_factor); + printk(KERN_CONT "num_reg: %d \tlose cover RAM: %s%ld%c\n", + result[i].num_reg, result[i].bad?"-":"", + lose_base, lose_factor); } /* try to find the optimal index */ @@ -1339,10 +1440,8 @@ static int __init mtrr_cleanup(unsigned address_bits) nr_mtrr_spare_reg = num_var_ranges - 1; num_reg_good = -1; for (i = num_var_ranges - nr_mtrr_spare_reg; i > 0; i--) { - if (!min_loss_pfn[i]) { + if (!min_loss_pfn[i]) num_reg_good = i; - break; - } } index_good = -1; @@ -1358,21 +1457,26 @@ static int __init mtrr_cleanup(unsigned address_bits) } if (index_good != -1) { + char gran_factor, chunk_factor, lose_factor; + unsigned long gran_base, chunk_base, lose_base; + printk(KERN_INFO "Found optimal setting for mtrr clean up\n"); i = index_good; - printk(KERN_INFO "gran_size: %ldM \tchunk_size: %ldM \t", - result[i].gran_sizek >> 10, - result[i].chunk_sizek >> 10); - printk(KERN_CONT "num_reg: %d \tlose RAM: %ldM\n", - result[i].num_reg, - result[i].lose_cover_sizek >> 10); + gran_base = to_size_factor(result[i].gran_sizek, &gran_factor), + chunk_base = to_size_factor(result[i].chunk_sizek, &chunk_factor), + lose_base = to_size_factor(result[i].lose_cover_sizek, &lose_factor), + printk(KERN_INFO "gran_size: %ld%c \tchunk_size: %ld%c \t", + gran_base, gran_factor, chunk_base, chunk_factor); + printk(KERN_CONT "num_reg: %d \tlose RAM: %ld%c\n", + result[i].num_reg, lose_base, lose_factor); /* convert ranges to var ranges state */ chunk_size = result[i].chunk_sizek; chunk_size <<= 10; gran_size = result[i].gran_sizek; gran_size <<= 10; - debug_print = 1; + debug_print++; x86_setup_var_mtrrs(range, nr_range, chunk_size, gran_size); + debug_print--; set_var_mtrr_all(address_bits); return 1; } diff --git a/arch/x86/kernel/cpuid.c b/arch/x86/kernel/cpuid.c index 8e9cd6a8ec1..6a44d646599 100644 --- a/arch/x86/kernel/cpuid.c +++ b/arch/x86/kernel/cpuid.c @@ -36,7 +36,6 @@ #include <linux/smp_lock.h> #include <linux/major.h> #include <linux/fs.h> -#include <linux/smp_lock.h> #include <linux/device.h> #include <linux/cpu.h> #include <linux/notifier.h> diff --git a/arch/x86/kernel/crash_dump_64.c b/arch/x86/kernel/crash_dump_64.c index 15e6c6bc4a4..e90a60ef10c 100644 --- a/arch/x86/kernel/crash_dump_64.c +++ b/arch/x86/kernel/crash_dump_64.c @@ -7,9 +7,8 @@ #include <linux/errno.h> #include <linux/crash_dump.h> - -#include <asm/uaccess.h> -#include <asm/io.h> +#include <linux/uaccess.h> +#include <linux/io.h> /** * copy_oldmem_page - copy one page from "oldmem" @@ -25,7 +24,7 @@ * in the current kernel. We stitch up a pte, similar to kmap_atomic. */ ssize_t copy_oldmem_page(unsigned long pfn, char *buf, - size_t csize, unsigned long offset, int userbuf) + size_t csize, unsigned long offset, int userbuf) { void *vaddr; @@ -33,14 +32,16 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf, return 0; vaddr = ioremap(pfn << PAGE_SHIFT, PAGE_SIZE); + if (!vaddr) + return -ENOMEM; if (userbuf) { - if (copy_to_user(buf, (vaddr + offset), csize)) { + if (copy_to_user(buf, vaddr + offset, csize)) { iounmap(vaddr); return -EFAULT; } } else - memcpy(buf, (vaddr + offset), csize); + memcpy(buf, vaddr + offset, csize); iounmap(vaddr); return csize; diff --git a/arch/x86/kernel/ds.c b/arch/x86/kernel/ds.c index 11c11b8ec48..2b69994fd3a 100644 --- a/arch/x86/kernel/ds.c +++ b/arch/x86/kernel/ds.c @@ -2,26 +2,49 @@ * Debug Store support * * This provides a low-level interface to the hardware's Debug Store - * feature that is used for last branch recording (LBR) and + * feature that is used for branch trace store (BTS) and * precise-event based sampling (PEBS). * - * Different architectures use a different DS layout/pointer size. - * The below functions therefore work on a void*. + * It manages: + * - per-thread and per-cpu allocation of BTS and PEBS + * - buffer memory allocation (optional) + * - buffer overflow handling + * - buffer access * + * It assumes: + * - get_task_struct on all parameter tasks + * - current is allowed to trace parameter tasks * - * Since there is no user for PEBS, yet, only LBR (or branch - * trace store, BTS) is supported. * - * - * Copyright (C) 2007 Intel Corporation. - * Markus Metzger <markus.t.metzger@intel.com>, Dec 2007 + * Copyright (C) 2007-2008 Intel Corporation. + * Markus Metzger <markus.t.metzger@intel.com>, 2007-2008 */ + +#ifdef CONFIG_X86_DS + #include <asm/ds.h> #include <linux/errno.h> #include <linux/string.h> #include <linux/slab.h> +#include <linux/sched.h> +#include <linux/mm.h> + + +/* + * The configuration for a particular DS hardware implementation. + */ +struct ds_configuration { + /* the size of the DS structure in bytes */ + unsigned char sizeof_ds; + /* the size of one pointer-typed field in the DS structure in bytes; + this covers the first 8 fields related to buffer management. */ + unsigned char sizeof_field; + /* the size of a BTS/PEBS record in bytes */ + unsigned char sizeof_rec[2]; +}; +static struct ds_configuration ds_cfg; /* @@ -44,378 +67,747 @@ * (interrupt occurs when write pointer passes interrupt pointer) * - value to which counter is reset following counter overflow * - * On later architectures, the last branch recording hardware uses - * 64bit pointers even in 32bit mode. - * - * - * Branch Trace Store (BTS) records store information about control - * flow changes. They at least provide the following information: - * - source linear address - * - destination linear address + * Later architectures use 64bit pointers throughout, whereas earlier + * architectures use 32bit pointers in 32bit mode. * - * Netburst supported a predicated bit that had been dropped in later - * architectures. We do not suppor it. * + * We compute the base address for the first 8 fields based on: + * - the field size stored in the DS configuration + * - the relative field position + * - an offset giving the start of the respective region * - * In order to abstract from the actual DS and BTS layout, we describe - * the access to the relevant fields. - * Thanks to Andi Kleen for proposing this design. + * This offset is further used to index various arrays holding + * information for BTS and PEBS at the respective index. * - * The implementation, however, is not as general as it might seem. In - * order to stay somewhat simple and efficient, we assume an - * underlying unsigned type (mostly a pointer type) and we expect the - * field to be at least as big as that type. + * On later 32bit processors, we only access the lower 32bit of the + * 64bit pointer fields. The upper halves will be zeroed out. */ -/* - * A special from_ip address to indicate that the BTS record is an - * info record that needs to be interpreted or skipped. - */ -#define BTS_ESCAPE_ADDRESS (-1) +enum ds_field { + ds_buffer_base = 0, + ds_index, + ds_absolute_maximum, + ds_interrupt_threshold, +}; -/* - * A field access descriptor - */ -struct access_desc { - unsigned char offset; - unsigned char size; +enum ds_qualifier { + ds_bts = 0, + ds_pebs }; +static inline unsigned long ds_get(const unsigned char *base, + enum ds_qualifier qual, enum ds_field field) +{ + base += (ds_cfg.sizeof_field * (field + (4 * qual))); + return *(unsigned long *)base; +} + +static inline void ds_set(unsigned char *base, enum ds_qualifier qual, + enum ds_field field, unsigned long value) +{ + base += (ds_cfg.sizeof_field * (field + (4 * qual))); + (*(unsigned long *)base) = value; +} + + /* - * The configuration for a particular DS/BTS hardware implementation. + * Locking is done only for allocating BTS or PEBS resources and for + * guarding context and buffer memory allocation. + * + * Most functions require the current task to own the ds context part + * they are going to access. All the locking is done when validating + * access to the context. */ -struct ds_configuration { - /* the DS configuration */ - unsigned char sizeof_ds; - struct access_desc bts_buffer_base; - struct access_desc bts_index; - struct access_desc bts_absolute_maximum; - struct access_desc bts_interrupt_threshold; - /* the BTS configuration */ - unsigned char sizeof_bts; - struct access_desc from_ip; - struct access_desc to_ip; - /* BTS variants used to store additional information like - timestamps */ - struct access_desc info_type; - struct access_desc info_data; - unsigned long debugctl_mask; -}; +static spinlock_t ds_lock = __SPIN_LOCK_UNLOCKED(ds_lock); /* - * The global configuration used by the below accessor functions + * Validate that the current task is allowed to access the BTS/PEBS + * buffer of the parameter task. + * + * Returns 0, if access is granted; -Eerrno, otherwise. */ -static struct ds_configuration ds_cfg; +static inline int ds_validate_access(struct ds_context *context, + enum ds_qualifier qual) +{ + if (!context) + return -EPERM; + + if (context->owner[qual] == current) + return 0; + + return -EPERM; +} + /* - * Accessor functions for some DS and BTS fields using the above - * global ptrace_bts_cfg. + * We either support (system-wide) per-cpu or per-thread allocation. + * We distinguish the two based on the task_struct pointer, where a + * NULL pointer indicates per-cpu allocation for the current cpu. + * + * Allocations are use-counted. As soon as resources are allocated, + * further allocations must be of the same type (per-cpu or + * per-thread). We model this by counting allocations (i.e. the number + * of tracers of a certain type) for one type negatively: + * =0 no tracers + * >0 number of per-thread tracers + * <0 number of per-cpu tracers + * + * The below functions to get and put tracers and to check the + * allocation type require the ds_lock to be held by the caller. + * + * Tracers essentially gives the number of ds contexts for a certain + * type of allocation. */ -static inline unsigned long get_bts_buffer_base(char *base) +static long tracers; + +static inline void get_tracer(struct task_struct *task) { - return *(unsigned long *)(base + ds_cfg.bts_buffer_base.offset); + tracers += (task ? 1 : -1); } -static inline void set_bts_buffer_base(char *base, unsigned long value) + +static inline void put_tracer(struct task_struct *task) { - (*(unsigned long *)(base + ds_cfg.bts_buffer_base.offset)) = value; + tracers -= (task ? 1 : -1); } -static inline unsigned long get_bts_index(char *base) + +static inline int check_tracer(struct task_struct *task) { - return *(unsigned long *)(base + ds_cfg.bts_index.offset); + return (task ? (tracers >= 0) : (tracers <= 0)); } -static inline void set_bts_index(char *base, unsigned long value) + + +/* + * The DS context is either attached to a thread or to a cpu: + * - in the former case, the thread_struct contains a pointer to the + * attached context. + * - in the latter case, we use a static array of per-cpu context + * pointers. + * + * Contexts are use-counted. They are allocated on first access and + * deallocated when the last user puts the context. + * + * We distinguish between an allocating and a non-allocating get of a + * context: + * - the allocating get is used for requesting BTS/PEBS resources. It + * requires the caller to hold the global ds_lock. + * - the non-allocating get is used for all other cases. A + * non-existing context indicates an error. It acquires and releases + * the ds_lock itself for obtaining the context. + * + * A context and its DS configuration are allocated and deallocated + * together. A context always has a DS configuration of the + * appropriate size. + */ +static DEFINE_PER_CPU(struct ds_context *, system_context); + +#define this_system_context per_cpu(system_context, smp_processor_id()) + +/* + * Returns the pointer to the parameter task's context or to the + * system-wide context, if task is NULL. + * + * Increases the use count of the returned context, if not NULL. + */ +static inline struct ds_context *ds_get_context(struct task_struct *task) { - (*(unsigned long *)(base + ds_cfg.bts_index.offset)) = value; + struct ds_context *context; + + spin_lock(&ds_lock); + + context = (task ? task->thread.ds_ctx : this_system_context); + if (context) + context->count++; + + spin_unlock(&ds_lock); + + return context; } -static inline unsigned long get_bts_absolute_maximum(char *base) + +/* + * Same as ds_get_context, but allocates the context and it's DS + * structure, if necessary; returns NULL; if out of memory. + * + * pre: requires ds_lock to be held + */ +static inline struct ds_context *ds_alloc_context(struct task_struct *task) { - return *(unsigned long *)(base + ds_cfg.bts_absolute_maximum.offset); + struct ds_context **p_context = + (task ? &task->thread.ds_ctx : &this_system_context); + struct ds_context *context = *p_context; + + if (!context) { + context = kzalloc(sizeof(*context), GFP_KERNEL); + + if (!context) + return NULL; + + context->ds = kzalloc(ds_cfg.sizeof_ds, GFP_KERNEL); + if (!context->ds) { + kfree(context); + return NULL; + } + + *p_context = context; + + context->this = p_context; + context->task = task; + + if (task) + set_tsk_thread_flag(task, TIF_DS_AREA_MSR); + + if (!task || (task == current)) + wrmsr(MSR_IA32_DS_AREA, (unsigned long)context->ds, 0); + + get_tracer(task); + } + + context->count++; + + return context; } -static inline void set_bts_absolute_maximum(char *base, unsigned long value) + +/* + * Decreases the use count of the parameter context, if not NULL. + * Deallocates the context, if the use count reaches zero. + */ +static inline void ds_put_context(struct ds_context *context) { - (*(unsigned long *)(base + ds_cfg.bts_absolute_maximum.offset)) = value; + if (!context) + return; + + spin_lock(&ds_lock); + + if (--context->count) + goto out; + + *(context->this) = NULL; + + if (context->task) + clear_tsk_thread_flag(context->task, TIF_DS_AREA_MSR); + + if (!context->task || (context->task == current)) + wrmsrl(MSR_IA32_DS_AREA, 0); + + put_tracer(context->task); + + /* free any leftover buffers from tracers that did not + * deallocate them properly. */ + kfree(context->buffer[ds_bts]); + kfree(context->buffer[ds_pebs]); + kfree(context->ds); + kfree(context); + out: + spin_unlock(&ds_lock); } -static inline unsigned long get_bts_interrupt_threshold(char *base) + + +/* + * Handle a buffer overflow + * + * task: the task whose buffers are overflowing; + * NULL for a buffer overflow on the current cpu + * context: the ds context + * qual: the buffer type + */ +static void ds_overflow(struct task_struct *task, struct ds_context *context, + enum ds_qualifier qual) { - return *(unsigned long *)(base + ds_cfg.bts_interrupt_threshold.offset); + if (!context) + return; + + if (context->callback[qual]) + (*context->callback[qual])(task); + + /* todo: do some more overflow handling */ } -static inline void set_bts_interrupt_threshold(char *base, unsigned long value) + + +/* + * Allocate a non-pageable buffer of the parameter size. + * Checks the memory and the locked memory rlimit. + * + * Returns the buffer, if successful; + * NULL, if out of memory or rlimit exceeded. + * + * size: the requested buffer size in bytes + * pages (out): if not NULL, contains the number of pages reserved + */ +static inline void *ds_allocate_buffer(size_t size, unsigned int *pages) { - (*(unsigned long *)(base + ds_cfg.bts_interrupt_threshold.offset)) = value; + unsigned long rlim, vm, pgsz; + void *buffer; + + pgsz = PAGE_ALIGN(size) >> PAGE_SHIFT; + + rlim = current->signal->rlim[RLIMIT_AS].rlim_cur >> PAGE_SHIFT; + vm = current->mm->total_vm + pgsz; + if (rlim < vm) + return NULL; + + rlim = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur >> PAGE_SHIFT; + vm = current->mm->locked_vm + pgsz; + if (rlim < vm) + return NULL; + + buffer = kzalloc(size, GFP_KERNEL); + if (!buffer) + return NULL; + + current->mm->total_vm += pgsz; + current->mm->locked_vm += pgsz; + + if (pages) + *pages = pgsz; + + return buffer; } -static inline unsigned long get_from_ip(char *base) + +static int ds_request(struct task_struct *task, void *base, size_t size, + ds_ovfl_callback_t ovfl, enum ds_qualifier qual) { - return *(unsigned long *)(base + ds_cfg.from_ip.offset); + struct ds_context *context; + unsigned long buffer, adj; + const unsigned long alignment = (1 << 3); + int error = 0; + + if (!ds_cfg.sizeof_ds) + return -EOPNOTSUPP; + + /* we require some space to do alignment adjustments below */ + if (size < (alignment + ds_cfg.sizeof_rec[qual])) + return -EINVAL; + + /* buffer overflow notification is not yet implemented */ + if (ovfl) + return -EOPNOTSUPP; + + + spin_lock(&ds_lock); + + if (!check_tracer(task)) + return -EPERM; + + error = -ENOMEM; + context = ds_alloc_context(task); + if (!context) + goto out_unlock; + + error = -EALREADY; + if (context->owner[qual] == current) + goto out_unlock; + error = -EPERM; + if (context->owner[qual] != NULL) + goto out_unlock; + context->owner[qual] = current; + + spin_unlock(&ds_lock); + + + error = -ENOMEM; + if (!base) { + base = ds_allocate_buffer(size, &context->pages[qual]); + if (!base) + goto out_release; + + context->buffer[qual] = base; + } + error = 0; + + context->callback[qual] = ovfl; + + /* adjust the buffer address and size to meet alignment + * constraints: + * - buffer is double-word aligned + * - size is multiple of record size + * + * We checked the size at the very beginning; we have enough + * space to do the adjustment. + */ + buffer = (unsigned long)base; + + adj = ALIGN(buffer, alignment) - buffer; + buffer += adj; + size -= adj; + + size /= ds_cfg.sizeof_rec[qual]; + size *= ds_cfg.sizeof_rec[qual]; + + ds_set(context->ds, qual, ds_buffer_base, buffer); + ds_set(context->ds, qual, ds_index, buffer); + ds_set(context->ds, qual, ds_absolute_maximum, buffer + size); + + if (ovfl) { + /* todo: select a suitable interrupt threshold */ + } else + ds_set(context->ds, qual, + ds_interrupt_threshold, buffer + size + 1); + + /* we keep the context until ds_release */ + return error; + + out_release: + context->owner[qual] = NULL; + ds_put_context(context); + return error; + + out_unlock: + spin_unlock(&ds_lock); + ds_put_context(context); + return error; } -static inline void set_from_ip(char *base, unsigned long value) + +int ds_request_bts(struct task_struct *task, void *base, size_t size, + ds_ovfl_callback_t ovfl) { - (*(unsigned long *)(base + ds_cfg.from_ip.offset)) = value; + return ds_request(task, base, size, ovfl, ds_bts); } -static inline unsigned long get_to_ip(char *base) + +int ds_request_pebs(struct task_struct *task, void *base, size_t size, + ds_ovfl_callback_t ovfl) { - return *(unsigned long *)(base + ds_cfg.to_ip.offset); + return ds_request(task, base, size, ovfl, ds_pebs); } -static inline void set_to_ip(char *base, unsigned long value) + +static int ds_release(struct task_struct *task, enum ds_qualifier qual) { - (*(unsigned long *)(base + ds_cfg.to_ip.offset)) = value; + struct ds_context *context; + int error; + + context = ds_get_context(task); + error = ds_validate_access(context, qual); + if (error < 0) + goto out; + + kfree(context->buffer[qual]); + context->buffer[qual] = NULL; + + current->mm->total_vm -= context->pages[qual]; + current->mm->locked_vm -= context->pages[qual]; + context->pages[qual] = 0; + context->owner[qual] = NULL; + + /* + * we put the context twice: + * once for the ds_get_context + * once for the corresponding ds_request + */ + ds_put_context(context); + out: + ds_put_context(context); + return error; } -static inline unsigned char get_info_type(char *base) + +int ds_release_bts(struct task_struct *task) { - return *(unsigned char *)(base + ds_cfg.info_type.offset); + return ds_release(task, ds_bts); } -static inline void set_info_type(char *base, unsigned char value) + +int ds_release_pebs(struct task_struct *task) { - (*(unsigned char *)(base + ds_cfg.info_type.offset)) = value; + return ds_release(task, ds_pebs); } -static inline unsigned long get_info_data(char *base) + +static int ds_get_index(struct task_struct *task, size_t *pos, + enum ds_qualifier qual) { - return *(unsigned long *)(base + ds_cfg.info_data.offset); + struct ds_context *context; + unsigned long base, index; + int error; + + context = ds_get_context(task); + error = ds_validate_access(context, qual); + if (error < 0) + goto out; + + base = ds_get(context->ds, qual, ds_buffer_base); + index = ds_get(context->ds, qual, ds_index); + + error = ((index - base) / ds_cfg.sizeof_rec[qual]); + if (pos) + *pos = error; + out: + ds_put_context(context); + return error; } -static inline void set_info_data(char *base, unsigned long value) + +int ds_get_bts_index(struct task_struct *task, size_t *pos) { - (*(unsigned long *)(base + ds_cfg.info_data.offset)) = value; + return ds_get_index(task, pos, ds_bts); } +int ds_get_pebs_index(struct task_struct *task, size_t *pos) +{ + return ds_get_index(task, pos, ds_pebs); +} -int ds_allocate(void **dsp, size_t bts_size_in_bytes) +static int ds_get_end(struct task_struct *task, size_t *pos, + enum ds_qualifier qual) { - size_t bts_size_in_records; - unsigned long bts; - void *ds; + struct ds_context *context; + unsigned long base, end; + int error; + + context = ds_get_context(task); + error = ds_validate_access(context, qual); + if (error < 0) + goto out; + + base = ds_get(context->ds, qual, ds_buffer_base); + end = ds_get(context->ds, qual, ds_absolute_maximum); + + error = ((end - base) / ds_cfg.sizeof_rec[qual]); + if (pos) + *pos = error; + out: + ds_put_context(context); + return error; +} - if (!ds_cfg.sizeof_ds || !ds_cfg.sizeof_bts) - return -EOPNOTSUPP; +int ds_get_bts_end(struct task_struct *task, size_t *pos) +{ + return ds_get_end(task, pos, ds_bts); +} - if (bts_size_in_bytes < 0) - return -EINVAL; +int ds_get_pebs_end(struct task_struct *task, size_t *pos) +{ + return ds_get_end(task, pos, ds_pebs); +} - bts_size_in_records = - bts_size_in_bytes / ds_cfg.sizeof_bts; - bts_size_in_bytes = - bts_size_in_records * ds_cfg.sizeof_bts; +static int ds_access(struct task_struct *task, size_t index, + const void **record, enum ds_qualifier qual) +{ + struct ds_context *context; + unsigned long base, idx; + int error; - if (bts_size_in_bytes <= 0) + if (!record) return -EINVAL; - bts = (unsigned long)kzalloc(bts_size_in_bytes, GFP_KERNEL); - - if (!bts) - return -ENOMEM; + context = ds_get_context(task); + error = ds_validate_access(context, qual); + if (error < 0) + goto out; - ds = kzalloc(ds_cfg.sizeof_ds, GFP_KERNEL); + base = ds_get(context->ds, qual, ds_buffer_base); + idx = base + (index * ds_cfg.sizeof_rec[qual]); - if (!ds) { - kfree((void *)bts); - return -ENOMEM; - } - - set_bts_buffer_base(ds, bts); - set_bts_index(ds, bts); - set_bts_absolute_maximum(ds, bts + bts_size_in_bytes); - set_bts_interrupt_threshold(ds, bts + bts_size_in_bytes + 1); + error = -EINVAL; + if (idx > ds_get(context->ds, qual, ds_absolute_maximum)) + goto out; - *dsp = ds; - return 0; + *record = (const void *)idx; + error = ds_cfg.sizeof_rec[qual]; + out: + ds_put_context(context); + return error; } -int ds_free(void **dsp) +int ds_access_bts(struct task_struct *task, size_t index, const void **record) { - if (*dsp) { - kfree((void *)get_bts_buffer_base(*dsp)); - kfree(*dsp); - *dsp = NULL; - } - return 0; + return ds_access(task, index, record, ds_bts); } -int ds_get_bts_size(void *ds) +int ds_access_pebs(struct task_struct *task, size_t index, const void **record) { - int size_in_bytes; - - if (!ds_cfg.sizeof_ds || !ds_cfg.sizeof_bts) - return -EOPNOTSUPP; - - if (!ds) - return 0; - - size_in_bytes = - get_bts_absolute_maximum(ds) - - get_bts_buffer_base(ds); - return size_in_bytes; + return ds_access(task, index, record, ds_pebs); } -int ds_get_bts_end(void *ds) +static int ds_write(struct task_struct *task, const void *record, size_t size, + enum ds_qualifier qual, int force) { - int size_in_bytes = ds_get_bts_size(ds); - - if (size_in_bytes <= 0) - return size_in_bytes; + struct ds_context *context; + int error; - return size_in_bytes / ds_cfg.sizeof_bts; -} + if (!record) + return -EINVAL; -int ds_get_bts_index(void *ds) -{ - int index_offset_in_bytes; + error = -EPERM; + context = ds_get_context(task); + if (!context) + goto out; - if (!ds_cfg.sizeof_ds || !ds_cfg.sizeof_bts) - return -EOPNOTSUPP; + if (!force) { + error = ds_validate_access(context, qual); + if (error < 0) + goto out; + } - index_offset_in_bytes = - get_bts_index(ds) - - get_bts_buffer_base(ds); + error = 0; + while (size) { + unsigned long base, index, end, write_end, int_th; + unsigned long write_size, adj_write_size; + + /* + * write as much as possible without producing an + * overflow interrupt. + * + * interrupt_threshold must either be + * - bigger than absolute_maximum or + * - point to a record between buffer_base and absolute_maximum + * + * index points to a valid record. + */ + base = ds_get(context->ds, qual, ds_buffer_base); + index = ds_get(context->ds, qual, ds_index); + end = ds_get(context->ds, qual, ds_absolute_maximum); + int_th = ds_get(context->ds, qual, ds_interrupt_threshold); + + write_end = min(end, int_th); + + /* if we are already beyond the interrupt threshold, + * we fill the entire buffer */ + if (write_end <= index) + write_end = end; + + if (write_end <= index) + goto out; + + write_size = min((unsigned long) size, write_end - index); + memcpy((void *)index, record, write_size); + + record = (const char *)record + write_size; + size -= write_size; + error += write_size; + + adj_write_size = write_size / ds_cfg.sizeof_rec[qual]; + adj_write_size *= ds_cfg.sizeof_rec[qual]; + + /* zero out trailing bytes */ + memset((char *)index + write_size, 0, + adj_write_size - write_size); + index += adj_write_size; + + if (index >= end) + index = base; + ds_set(context->ds, qual, ds_index, index); + + if (index >= int_th) + ds_overflow(task, context, qual); + } - return index_offset_in_bytes / ds_cfg.sizeof_bts; + out: + ds_put_context(context); + return error; } -int ds_set_overflow(void *ds, int method) +int ds_write_bts(struct task_struct *task, const void *record, size_t size) { - switch (method) { - case DS_O_SIGNAL: - return -EOPNOTSUPP; - case DS_O_WRAP: - return 0; - default: - return -EINVAL; - } + return ds_write(task, record, size, ds_bts, /* force = */ 0); } -int ds_get_overflow(void *ds) +int ds_write_pebs(struct task_struct *task, const void *record, size_t size) { - return DS_O_WRAP; + return ds_write(task, record, size, ds_pebs, /* force = */ 0); } -int ds_clear(void *ds) +int ds_unchecked_write_bts(struct task_struct *task, + const void *record, size_t size) { - int bts_size = ds_get_bts_size(ds); - unsigned long bts_base; - - if (bts_size <= 0) - return bts_size; - - bts_base = get_bts_buffer_base(ds); - memset((void *)bts_base, 0, bts_size); - - set_bts_index(ds, bts_base); - return 0; + return ds_write(task, record, size, ds_bts, /* force = */ 1); } -int ds_read_bts(void *ds, int index, struct bts_struct *out) +int ds_unchecked_write_pebs(struct task_struct *task, + const void *record, size_t size) { - void *bts; + return ds_write(task, record, size, ds_pebs, /* force = */ 1); +} - if (!ds_cfg.sizeof_ds || !ds_cfg.sizeof_bts) - return -EOPNOTSUPP; +static int ds_reset_or_clear(struct task_struct *task, + enum ds_qualifier qual, int clear) +{ + struct ds_context *context; + unsigned long base, end; + int error; - if (index < 0) - return -EINVAL; + context = ds_get_context(task); + error = ds_validate_access(context, qual); + if (error < 0) + goto out; - if (index >= ds_get_bts_size(ds)) - return -EINVAL; + base = ds_get(context->ds, qual, ds_buffer_base); + end = ds_get(context->ds, qual, ds_absolute_maximum); - bts = (void *)(get_bts_buffer_base(ds) + (index * ds_cfg.sizeof_bts)); + if (clear) + memset((void *)base, 0, end - base); - memset(out, 0, sizeof(*out)); - if (get_from_ip(bts) == BTS_ESCAPE_ADDRESS) { - out->qualifier = get_info_type(bts); - out->variant.jiffies = get_info_data(bts); - } else { - out->qualifier = BTS_BRANCH; - out->variant.lbr.from_ip = get_from_ip(bts); - out->variant.lbr.to_ip = get_to_ip(bts); - } + ds_set(context->ds, qual, ds_index, base); - return sizeof(*out);; + error = 0; + out: + ds_put_context(context); + return error; } -int ds_write_bts(void *ds, const struct bts_struct *in) +int ds_reset_bts(struct task_struct *task) { - unsigned long bts; - - if (!ds_cfg.sizeof_ds || !ds_cfg.sizeof_bts) - return -EOPNOTSUPP; - - if (ds_get_bts_size(ds) <= 0) - return -ENXIO; + return ds_reset_or_clear(task, ds_bts, /* clear = */ 0); +} - bts = get_bts_index(ds); +int ds_reset_pebs(struct task_struct *task) +{ + return ds_reset_or_clear(task, ds_pebs, /* clear = */ 0); +} - memset((void *)bts, 0, ds_cfg.sizeof_bts); - switch (in->qualifier) { - case BTS_INVALID: - break; +int ds_clear_bts(struct task_struct *task) +{ + return ds_reset_or_clear(task, ds_bts, /* clear = */ 1); +} - case BTS_BRANCH: - set_from_ip((void *)bts, in->variant.lbr.from_ip); - set_to_ip((void *)bts, in->variant.lbr.to_ip); - break; +int ds_clear_pebs(struct task_struct *task) +{ + return ds_reset_or_clear(task, ds_pebs, /* clear = */ 1); +} - case BTS_TASK_ARRIVES: - case BTS_TASK_DEPARTS: - set_from_ip((void *)bts, BTS_ESCAPE_ADDRESS); - set_info_type((void *)bts, in->qualifier); - set_info_data((void *)bts, in->variant.jiffies); - break; +int ds_get_pebs_reset(struct task_struct *task, u64 *value) +{ + struct ds_context *context; + int error; - default: + if (!value) return -EINVAL; - } - bts = bts + ds_cfg.sizeof_bts; - if (bts >= get_bts_absolute_maximum(ds)) - bts = get_bts_buffer_base(ds); - set_bts_index(ds, bts); + context = ds_get_context(task); + error = ds_validate_access(context, ds_pebs); + if (error < 0) + goto out; - return ds_cfg.sizeof_bts; + *value = *(u64 *)(context->ds + (ds_cfg.sizeof_field * 8)); + + error = 0; + out: + ds_put_context(context); + return error; } -unsigned long ds_debugctl_mask(void) +int ds_set_pebs_reset(struct task_struct *task, u64 value) { - return ds_cfg.debugctl_mask; -} + struct ds_context *context; + int error; -#ifdef __i386__ -static const struct ds_configuration ds_cfg_netburst = { - .sizeof_ds = 9 * 4, - .bts_buffer_base = { 0, 4 }, - .bts_index = { 4, 4 }, - .bts_absolute_maximum = { 8, 4 }, - .bts_interrupt_threshold = { 12, 4 }, - .sizeof_bts = 3 * 4, - .from_ip = { 0, 4 }, - .to_ip = { 4, 4 }, - .info_type = { 4, 1 }, - .info_data = { 8, 4 }, - .debugctl_mask = (1<<2)|(1<<3) -}; + context = ds_get_context(task); + error = ds_validate_access(context, ds_pebs); + if (error < 0) + goto out; -static const struct ds_configuration ds_cfg_pentium_m = { - .sizeof_ds = 9 * 4, - .bts_buffer_base = { 0, 4 }, - .bts_index = { 4, 4 }, - .bts_absolute_maximum = { 8, 4 }, - .bts_interrupt_threshold = { 12, 4 }, - .sizeof_bts = 3 * 4, - .from_ip = { 0, 4 }, - .to_ip = { 4, 4 }, - .info_type = { 4, 1 }, - .info_data = { 8, 4 }, - .debugctl_mask = (1<<6)|(1<<7) + *(u64 *)(context->ds + (ds_cfg.sizeof_field * 8)) = value; + + error = 0; + out: + ds_put_context(context); + return error; +} + +static const struct ds_configuration ds_cfg_var = { + .sizeof_ds = sizeof(long) * 12, + .sizeof_field = sizeof(long), + .sizeof_rec[ds_bts] = sizeof(long) * 3, + .sizeof_rec[ds_pebs] = sizeof(long) * 10 }; -#endif /* _i386_ */ - -static const struct ds_configuration ds_cfg_core2 = { - .sizeof_ds = 9 * 8, - .bts_buffer_base = { 0, 8 }, - .bts_index = { 8, 8 }, - .bts_absolute_maximum = { 16, 8 }, - .bts_interrupt_threshold = { 24, 8 }, - .sizeof_bts = 3 * 8, - .from_ip = { 0, 8 }, - .to_ip = { 8, 8 }, - .info_type = { 8, 1 }, - .info_data = { 16, 8 }, - .debugctl_mask = (1<<6)|(1<<7)|(1<<9) +static const struct ds_configuration ds_cfg_64 = { + .sizeof_ds = 8 * 12, + .sizeof_field = 8, + .sizeof_rec[ds_bts] = 8 * 3, + .sizeof_rec[ds_pebs] = 8 * 10 }; static inline void @@ -429,14 +821,13 @@ void __cpuinit ds_init_intel(struct cpuinfo_x86 *c) switch (c->x86) { case 0x6: switch (c->x86_model) { -#ifdef __i386__ case 0xD: case 0xE: /* Pentium M */ - ds_configure(&ds_cfg_pentium_m); + ds_configure(&ds_cfg_var); break; -#endif /* _i386_ */ case 0xF: /* Core2 */ - ds_configure(&ds_cfg_core2); + case 0x1C: /* Atom */ + ds_configure(&ds_cfg_64); break; default: /* sorry, don't know about them */ @@ -445,13 +836,11 @@ void __cpuinit ds_init_intel(struct cpuinfo_x86 *c) break; case 0xF: switch (c->x86_model) { -#ifdef __i386__ case 0x0: case 0x1: case 0x2: /* Netburst */ - ds_configure(&ds_cfg_netburst); + ds_configure(&ds_cfg_var); break; -#endif /* _i386_ */ default: /* sorry, don't know about them */ break; @@ -462,3 +851,14 @@ void __cpuinit ds_init_intel(struct cpuinfo_x86 *c) break; } } + +void ds_free(struct ds_context *context) +{ + /* This is called when the task owning the parameter context + * is dying. There should not be any user of that context left + * to disturb us, anymore. */ + unsigned long leftovers = context->count; + while (leftovers--) + ds_put_context(context); +} +#endif /* CONFIG_X86_DS */ diff --git a/arch/x86/kernel/efi.c b/arch/x86/kernel/efi.c index 06cc8d4254b..945a31cdd81 100644 --- a/arch/x86/kernel/efi.c +++ b/arch/x86/kernel/efi.c @@ -414,9 +414,11 @@ void __init efi_init(void) if (memmap.map == NULL) printk(KERN_ERR "Could not map the EFI memory map!\n"); memmap.map_end = memmap.map + (memmap.nr_map * memmap.desc_size); + if (memmap.desc_size != sizeof(efi_memory_desc_t)) - printk(KERN_WARNING "Kernel-defined memdesc" - "doesn't match the one from EFI!\n"); + printk(KERN_WARNING + "Kernel-defined memdesc doesn't match the one from EFI!\n"); + if (add_efi_memmap) do_add_efi_memmap(); diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index 89434d43960..cf3a0b2d005 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S @@ -275,9 +275,9 @@ ENTRY(native_usergs_sysret64) ENTRY(ret_from_fork) CFI_DEFAULT_STACK push kernel_eflags(%rip) - CFI_ADJUST_CFA_OFFSET 4 + CFI_ADJUST_CFA_OFFSET 8 popf # reset kernel eflags - CFI_ADJUST_CFA_OFFSET -4 + CFI_ADJUST_CFA_OFFSET -8 call schedule_tail GET_THREAD_INFO(%rcx) testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT),TI_flags(%rcx) diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c index 9bfc4d72fb2..d16084f9064 100644 --- a/arch/x86/kernel/head64.c +++ b/arch/x86/kernel/head64.c @@ -108,12 +108,11 @@ void __init x86_64_start_kernel(char * real_mode_data) } load_idt((const struct desc_ptr *)&idt_descr); - early_printk("Kernel alive\n"); + if (console_loglevel == 10) + early_printk("Kernel alive\n"); x86_64_init_pda(); - early_printk("Kernel really alive\n"); - x86_64_start_reservations(real_mode_data); } diff --git a/arch/x86/kernel/ioport.c b/arch/x86/kernel/ioport.c index 50e5e4a31c8..19191430274 100644 --- a/arch/x86/kernel/ioport.c +++ b/arch/x86/kernel/ioport.c @@ -14,6 +14,7 @@ #include <linux/slab.h> #include <linux/thread_info.h> #include <linux/syscalls.h> +#include <asm/syscalls.h> /* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */ static void set_bitmap(unsigned long *bitmap, unsigned int base, diff --git a/arch/x86/kernel/ipi.c b/arch/x86/kernel/ipi.c index 3f7537b669d..f1c688e46f3 100644 --- a/arch/x86/kernel/ipi.c +++ b/arch/x86/kernel/ipi.c @@ -20,6 +20,8 @@ #ifdef CONFIG_X86_32 #include <mach_apic.h> +#include <mach_ipi.h> + /* * the following functions deal with sending IPIs between CPUs. * @@ -147,7 +149,6 @@ void send_IPI_mask_sequence(cpumask_t mask, int vector) } /* must come after the send_IPI functions above for inlining */ -#include <mach_ipi.h> static int convert_apicid_to_cpu(int apic_id) { int i; diff --git a/arch/x86/kernel/irq_32.c b/arch/x86/kernel/irq_32.c index 1cf8c1fcc08..b71e02d42f4 100644 --- a/arch/x86/kernel/irq_32.c +++ b/arch/x86/kernel/irq_32.c @@ -325,7 +325,7 @@ skip: for_each_online_cpu(j) seq_printf(p, "%10u ", per_cpu(irq_stat,j).irq_call_count); - seq_printf(p, " function call interrupts\n"); + seq_printf(p, " Function call interrupts\n"); seq_printf(p, "TLB: "); for_each_online_cpu(j) seq_printf(p, "%10u ", diff --git a/arch/x86/kernel/irq_64.c b/arch/x86/kernel/irq_64.c index 1f78b238d8d..f065fe9071b 100644 --- a/arch/x86/kernel/irq_64.c +++ b/arch/x86/kernel/irq_64.c @@ -129,7 +129,7 @@ skip: seq_printf(p, "CAL: "); for_each_online_cpu(j) seq_printf(p, "%10u ", cpu_pda(j)->irq_call_count); - seq_printf(p, " function call interrupts\n"); + seq_printf(p, " Function call interrupts\n"); seq_printf(p, "TLB: "); for_each_online_cpu(j) seq_printf(p, "%10u ", cpu_pda(j)->irq_tlb_count); diff --git a/arch/x86/kernel/kgdb.c b/arch/x86/kernel/kgdb.c index f47f0eb886b..8282a213968 100644 --- a/arch/x86/kernel/kgdb.c +++ b/arch/x86/kernel/kgdb.c @@ -69,6 +69,9 @@ static int gdb_x86vector = -1; */ void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs) { +#ifndef CONFIG_X86_32 + u32 *gdb_regs32 = (u32 *)gdb_regs; +#endif gdb_regs[GDB_AX] = regs->ax; gdb_regs[GDB_BX] = regs->bx; gdb_regs[GDB_CX] = regs->cx; @@ -76,9 +79,9 @@ void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs) gdb_regs[GDB_SI] = regs->si; gdb_regs[GDB_DI] = regs->di; gdb_regs[GDB_BP] = regs->bp; - gdb_regs[GDB_PS] = regs->flags; gdb_regs[GDB_PC] = regs->ip; #ifdef CONFIG_X86_32 + gdb_regs[GDB_PS] = regs->flags; gdb_regs[GDB_DS] = regs->ds; gdb_regs[GDB_ES] = regs->es; gdb_regs[GDB_CS] = regs->cs; @@ -94,6 +97,9 @@ void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs) gdb_regs[GDB_R13] = regs->r13; gdb_regs[GDB_R14] = regs->r14; gdb_regs[GDB_R15] = regs->r15; + gdb_regs32[GDB_PS] = regs->flags; + gdb_regs32[GDB_CS] = regs->cs; + gdb_regs32[GDB_SS] = regs->ss; #endif gdb_regs[GDB_SP] = regs->sp; } @@ -112,6 +118,9 @@ void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs) */ void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p) { +#ifndef CONFIG_X86_32 + u32 *gdb_regs32 = (u32 *)gdb_regs; +#endif gdb_regs[GDB_AX] = 0; gdb_regs[GDB_BX] = 0; gdb_regs[GDB_CX] = 0; @@ -129,8 +138,10 @@ void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p) gdb_regs[GDB_FS] = 0xFFFF; gdb_regs[GDB_GS] = 0xFFFF; #else - gdb_regs[GDB_PS] = *(unsigned long *)(p->thread.sp + 8); - gdb_regs[GDB_PC] = 0; + gdb_regs32[GDB_PS] = *(unsigned long *)(p->thread.sp + 8); + gdb_regs32[GDB_CS] = __KERNEL_CS; + gdb_regs32[GDB_SS] = __KERNEL_DS; + gdb_regs[GDB_PC] = p->thread.ip; gdb_regs[GDB_R8] = 0; gdb_regs[GDB_R9] = 0; gdb_regs[GDB_R10] = 0; @@ -153,6 +164,9 @@ void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p) */ void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs) { +#ifndef CONFIG_X86_32 + u32 *gdb_regs32 = (u32 *)gdb_regs; +#endif regs->ax = gdb_regs[GDB_AX]; regs->bx = gdb_regs[GDB_BX]; regs->cx = gdb_regs[GDB_CX]; @@ -160,9 +174,9 @@ void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs) regs->si = gdb_regs[GDB_SI]; regs->di = gdb_regs[GDB_DI]; regs->bp = gdb_regs[GDB_BP]; - regs->flags = gdb_regs[GDB_PS]; regs->ip = gdb_regs[GDB_PC]; #ifdef CONFIG_X86_32 + regs->flags = gdb_regs[GDB_PS]; regs->ds = gdb_regs[GDB_DS]; regs->es = gdb_regs[GDB_ES]; regs->cs = gdb_regs[GDB_CS]; @@ -175,6 +189,9 @@ void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs) regs->r13 = gdb_regs[GDB_R13]; regs->r14 = gdb_regs[GDB_R14]; regs->r15 = gdb_regs[GDB_R15]; + regs->flags = gdb_regs32[GDB_PS]; + regs->cs = gdb_regs32[GDB_CS]; + regs->ss = gdb_regs32[GDB_SS]; #endif } @@ -378,10 +395,8 @@ int kgdb_arch_handle_exception(int e_vector, int signo, int err_code, if (remcomInBuffer[0] == 's') { linux_regs->flags |= X86_EFLAGS_TF; kgdb_single_step = 1; - if (kgdb_contthread) { - atomic_set(&kgdb_cpu_doing_single_step, - raw_smp_processor_id()); - } + atomic_set(&kgdb_cpu_doing_single_step, + raw_smp_processor_id()); } get_debugreg(dr6, 6); @@ -466,9 +481,15 @@ static int __kgdb_notify(struct die_args *args, unsigned long cmd) case DIE_DEBUG: if (atomic_read(&kgdb_cpu_doing_single_step) == - raw_smp_processor_id() && - user_mode(regs)) - return single_step_cont(regs, args); + raw_smp_processor_id()) { + if (user_mode(regs)) + return single_step_cont(regs, args); + break; + } else if (test_thread_flag(TIF_SINGLESTEP)) + /* This means a user thread is single stepping + * a system call which should be ignored + */ + return NOTIFY_DONE; /* fall through */ default: if (user_mode(regs)) diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c index 8b7a3cf37d2..478bca986ec 100644 --- a/arch/x86/kernel/kvm.c +++ b/arch/x86/kernel/kvm.c @@ -178,7 +178,7 @@ static void kvm_flush_tlb(void) kvm_deferred_mmu_op(&ftlb, sizeof ftlb); } -static void kvm_release_pt(u32 pfn) +static void kvm_release_pt(unsigned long pfn) { struct kvm_mmu_op_release_pt rpt = { .header.op = KVM_MMU_OP_RELEASE_PT, diff --git a/arch/x86/kernel/ldt.c b/arch/x86/kernel/ldt.c index b68e21f06f4..0ed5f939b90 100644 --- a/arch/x86/kernel/ldt.c +++ b/arch/x86/kernel/ldt.c @@ -18,6 +18,7 @@ #include <asm/ldt.h> #include <asm/desc.h> #include <asm/mmu_context.h> +#include <asm/syscalls.h> #ifdef CONFIG_SMP static void flush_ldt(void *current_mm) diff --git a/arch/x86/kernel/olpc.c b/arch/x86/kernel/olpc.c index 3e667227480..7a13fac63a1 100644 --- a/arch/x86/kernel/olpc.c +++ b/arch/x86/kernel/olpc.c @@ -190,12 +190,12 @@ EXPORT_SYMBOL_GPL(olpc_ec_cmd); static void __init platform_detect(void) { size_t propsize; - u32 rev; + __be32 rev; if (ofw("getprop", 4, 1, NULL, "board-revision-int", &rev, 4, &propsize) || propsize != 4) { printk(KERN_ERR "ofw: getprop call failed!\n"); - rev = 0; + rev = cpu_to_be32(0); } olpc_platform_info.boardrev = be32_to_cpu(rev); } @@ -203,7 +203,7 @@ static void __init platform_detect(void) static void __init platform_detect(void) { /* stopgap until OFW support is added to the kernel */ - olpc_platform_info.boardrev = be32_to_cpu(0xc2); + olpc_platform_info.boardrev = 0xc2; } #endif diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c index 300da17e61c..e2f43768723 100644 --- a/arch/x86/kernel/paravirt.c +++ b/arch/x86/kernel/paravirt.c @@ -330,6 +330,7 @@ struct pv_cpu_ops pv_cpu_ops = { #endif .wbinvd = native_wbinvd, .read_msr = native_read_msr_safe, + .read_msr_amd = native_read_msr_amd_safe, .write_msr = native_write_msr_safe, .read_tsc = native_read_tsc, .read_pmc = native_read_pmc, diff --git a/arch/x86/kernel/paravirt_patch_32.c b/arch/x86/kernel/paravirt_patch_32.c index 58262218781..9fe644f4861 100644 --- a/arch/x86/kernel/paravirt_patch_32.c +++ b/arch/x86/kernel/paravirt_patch_32.c @@ -23,7 +23,7 @@ unsigned native_patch(u8 type, u16 clobbers, void *ibuf, start = start_##ops##_##x; \ end = end_##ops##_##x; \ goto patch_site - switch(type) { + switch (type) { PATCH_SITE(pv_irq_ops, irq_disable); PATCH_SITE(pv_irq_ops, irq_enable); PATCH_SITE(pv_irq_ops, restore_fl); diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c index 87d4d6964ec..f704cb51ff8 100644 --- a/arch/x86/kernel/pci-dma.c +++ b/arch/x86/kernel/pci-dma.c @@ -82,7 +82,7 @@ void __init dma32_reserve_bootmem(void) * using 512M as goal */ align = 64ULL<<20; - size = round_up(dma32_bootmem_size, align); + size = roundup(dma32_bootmem_size, align); dma32_bootmem_ptr = __alloc_bootmem_nopanic(size, align, 512ULL<<20); if (dma32_bootmem_ptr) diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c index 49285f8fd4d..1a895a58253 100644 --- a/arch/x86/kernel/pci-gart_64.c +++ b/arch/x86/kernel/pci-gart_64.c @@ -82,7 +82,8 @@ AGPEXTERN __u32 *agp_gatt_table; static unsigned long next_bit; /* protected by iommu_bitmap_lock */ static int need_flush; /* global flush state. set for each gart wrap */ -static unsigned long alloc_iommu(struct device *dev, int size) +static unsigned long alloc_iommu(struct device *dev, int size, + unsigned long align_mask) { unsigned long offset, flags; unsigned long boundary_size; @@ -90,16 +91,17 @@ static unsigned long alloc_iommu(struct device *dev, int size) base_index = ALIGN(iommu_bus_base & dma_get_seg_boundary(dev), PAGE_SIZE) >> PAGE_SHIFT; - boundary_size = ALIGN(dma_get_seg_boundary(dev) + 1, + boundary_size = ALIGN((unsigned long long)dma_get_seg_boundary(dev) + 1, PAGE_SIZE) >> PAGE_SHIFT; spin_lock_irqsave(&iommu_bitmap_lock, flags); offset = iommu_area_alloc(iommu_gart_bitmap, iommu_pages, next_bit, - size, base_index, boundary_size, 0); + size, base_index, boundary_size, align_mask); if (offset == -1) { need_flush = 1; offset = iommu_area_alloc(iommu_gart_bitmap, iommu_pages, 0, - size, base_index, boundary_size, 0); + size, base_index, boundary_size, + align_mask); } if (offset != -1) { next_bit = offset+size; @@ -236,10 +238,10 @@ nonforced_iommu(struct device *dev, unsigned long addr, size_t size) * Caller needs to check if the iommu is needed and flush. */ static dma_addr_t dma_map_area(struct device *dev, dma_addr_t phys_mem, - size_t size, int dir) + size_t size, int dir, unsigned long align_mask) { unsigned long npages = iommu_num_pages(phys_mem, size); - unsigned long iommu_page = alloc_iommu(dev, npages); + unsigned long iommu_page = alloc_iommu(dev, npages, align_mask); int i; if (iommu_page == -1) { @@ -262,7 +264,11 @@ static dma_addr_t dma_map_area(struct device *dev, dma_addr_t phys_mem, static dma_addr_t gart_map_simple(struct device *dev, phys_addr_t paddr, size_t size, int dir) { - dma_addr_t map = dma_map_area(dev, paddr, size, dir); + dma_addr_t map; + unsigned long align_mask; + + align_mask = (1UL << get_order(size)) - 1; + map = dma_map_area(dev, paddr, size, dir, align_mask); flush_gart(); @@ -281,7 +287,8 @@ gart_map_single(struct device *dev, phys_addr_t paddr, size_t size, int dir) if (!need_iommu(dev, paddr, size)) return paddr; - bus = gart_map_simple(dev, paddr, size, dir); + bus = dma_map_area(dev, paddr, size, dir, 0); + flush_gart(); return bus; } @@ -340,7 +347,7 @@ static int dma_map_sg_nonforce(struct device *dev, struct scatterlist *sg, unsigned long addr = sg_phys(s); if (nonforced_iommu(dev, addr, s->length)) { - addr = dma_map_area(dev, addr, s->length, dir); + addr = dma_map_area(dev, addr, s->length, dir, 0); if (addr == bad_dma_address) { if (i > 0) gart_unmap_sg(dev, sg, i, dir); @@ -362,7 +369,7 @@ static int __dma_map_cont(struct device *dev, struct scatterlist *start, int nelems, struct scatterlist *sout, unsigned long pages) { - unsigned long iommu_start = alloc_iommu(dev, pages); + unsigned long iommu_start = alloc_iommu(dev, pages, 0); unsigned long iommu_page = iommu_start; struct scatterlist *s; int i; @@ -626,7 +633,6 @@ static __init int init_k8_gatt(struct agp_kern_info *info) struct pci_dev *dev; void *gatt; int i, error; - unsigned long start_pfn, end_pfn; printk(KERN_INFO "PCI-DMA: Disabling AGP.\n"); aper_size = aper_base = info->aper_size = 0; @@ -672,12 +678,6 @@ static __init int init_k8_gatt(struct agp_kern_info *info) printk(KERN_INFO "PCI-DMA: aperture base @ %x size %u KB\n", aper_base, aper_size>>10); - /* need to map that range */ - end_pfn = (aper_base>>PAGE_SHIFT) + (aper_size>>PAGE_SHIFT); - if (end_pfn > max_low_pfn_mapped) { - start_pfn = (aper_base>>PAGE_SHIFT); - init_memory_mapping(start_pfn<<PAGE_SHIFT, end_pfn<<PAGE_SHIFT); - } return 0; nommu: @@ -727,7 +727,8 @@ void __init gart_iommu_init(void) { struct agp_kern_info info; unsigned long iommu_start; - unsigned long aper_size; + unsigned long aper_base, aper_size; + unsigned long start_pfn, end_pfn; unsigned long scratch; long i; @@ -765,8 +766,16 @@ void __init gart_iommu_init(void) return; } + /* need to map that range */ + aper_size = info.aper_size << 20; + aper_base = info.aper_base; + end_pfn = (aper_base>>PAGE_SHIFT) + (aper_size>>PAGE_SHIFT); + if (end_pfn > max_low_pfn_mapped) { + start_pfn = (aper_base>>PAGE_SHIFT); + init_memory_mapping(start_pfn<<PAGE_SHIFT, end_pfn<<PAGE_SHIFT); + } + printk(KERN_INFO "PCI-DMA: using GART IOMMU.\n"); - aper_size = info.aper_size * 1024 * 1024; iommu_size = check_iommu_size(info.aper_base, aper_size); iommu_pages = iommu_size >> PAGE_SHIFT; diff --git a/arch/x86/kernel/pcspeaker.c b/arch/x86/kernel/pcspeaker.c index bc1f2d3ea27..a311ffcaad1 100644 --- a/arch/x86/kernel/pcspeaker.c +++ b/arch/x86/kernel/pcspeaker.c @@ -1,20 +1,13 @@ #include <linux/platform_device.h> -#include <linux/errno.h> +#include <linux/err.h> #include <linux/init.h> static __init int add_pcspkr(void) { struct platform_device *pd; - int ret; - pd = platform_device_alloc("pcspkr", -1); - if (!pd) - return -ENOMEM; + pd = platform_device_register_simple("pcspkr", -1, NULL, 0); - ret = platform_device_add(pd); - if (ret) - platform_device_put(pd); - - return ret; + return IS_ERR(pd) ? PTR_ERR(pd) : 0; } device_initcall(add_pcspkr); diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index 7fc4d5b0a6a..ec7a2ba9bce 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -185,7 +185,8 @@ static void mwait_idle(void) static void poll_idle(void) { local_irq_enable(); - cpu_relax(); + while (!need_resched()) + cpu_relax(); } /* @@ -246,6 +247,14 @@ static int __cpuinit check_c1e_idle(const struct cpuinfo_x86 *c) return 1; } +static cpumask_t c1e_mask = CPU_MASK_NONE; +static int c1e_detected; + +void c1e_remove_cpu(int cpu) +{ + cpu_clear(cpu, c1e_mask); +} + /* * C1E aware idle routine. We check for C1E active in the interrupt * pending message MSR. If we detect C1E, then we handle it the same @@ -253,9 +262,6 @@ static int __cpuinit check_c1e_idle(const struct cpuinfo_x86 *c) */ static void c1e_idle(void) { - static cpumask_t c1e_mask = CPU_MASK_NONE; - static int c1e_detected; - if (need_resched()) return; @@ -265,8 +271,10 @@ static void c1e_idle(void) rdmsr(MSR_K8_INT_PENDING_MSG, lo, hi); if (lo & K8_INTP_C1E_ACTIVE_MASK) { c1e_detected = 1; - mark_tsc_unstable("TSC halt in C1E"); - printk(KERN_INFO "System has C1E enabled\n"); + if (!boot_cpu_has(X86_FEATURE_CONSTANT_TSC)) + mark_tsc_unstable("TSC halt in AMD C1E"); + printk(KERN_INFO "System has AMD C1E enabled\n"); + set_cpu_cap(&boot_cpu_data, X86_FEATURE_AMDC1E); } } diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c index 3b7a1ddcc0b..205188db962 100644 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c @@ -37,6 +37,7 @@ #include <linux/tick.h> #include <linux/percpu.h> #include <linux/prctl.h> +#include <linux/dmi.h> #include <asm/uaccess.h> #include <asm/pgtable.h> @@ -55,6 +56,9 @@ #include <asm/tlbflush.h> #include <asm/cpu.h> #include <asm/kdebug.h> +#include <asm/idle.h> +#include <asm/syscalls.h> +#include <asm/smp.h> asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); @@ -88,6 +92,7 @@ static void cpu_exit_clear(void) cpu_clear(cpu, cpu_callin_map); numa_remove_cpu(cpu); + c1e_remove_cpu(cpu); } /* We don't actually take CPU down, just spin without interrupts. */ @@ -159,6 +164,7 @@ void __show_registers(struct pt_regs *regs, int all) unsigned long d0, d1, d2, d3, d6, d7; unsigned long sp; unsigned short ss, gs; + const char *board; if (user_mode_vm(regs)) { sp = regs->sp; @@ -171,11 +177,15 @@ void __show_registers(struct pt_regs *regs, int all) } printk("\n"); - printk("Pid: %d, comm: %s %s (%s %.*s)\n", + + board = dmi_get_system_info(DMI_PRODUCT_NAME); + if (!board) + board = ""; + printk("Pid: %d, comm: %s %s (%s %.*s) %s\n", task_pid_nr(current), current->comm, print_tainted(), init_utsname()->release, (int)strcspn(init_utsname()->version, " "), - init_utsname()->version); + init_utsname()->version, board); printk("EIP: %04x:[<%08lx>] EFLAGS: %08lx CPU: %d\n", (u16)regs->cs, regs->ip, regs->flags, @@ -275,6 +285,14 @@ void exit_thread(void) tss->x86_tss.io_bitmap_base = INVALID_IO_BITMAP_OFFSET; put_cpu(); } +#ifdef CONFIG_X86_DS + /* Free any DS contexts that have not been properly released. */ + if (unlikely(current->thread.ds_ctx)) { + /* we clear debugctl to make sure DS is not used. */ + update_debugctlmsr(0); + ds_free(current->thread.ds_ctx); + } +#endif /* CONFIG_X86_DS */ } void flush_thread(void) @@ -436,6 +454,35 @@ int set_tsc_mode(unsigned int val) return 0; } +#ifdef CONFIG_X86_DS +static int update_debugctl(struct thread_struct *prev, + struct thread_struct *next, unsigned long debugctl) +{ + unsigned long ds_prev = 0; + unsigned long ds_next = 0; + + if (prev->ds_ctx) + ds_prev = (unsigned long)prev->ds_ctx->ds; + if (next->ds_ctx) + ds_next = (unsigned long)next->ds_ctx->ds; + + if (ds_next != ds_prev) { + /* we clear debugctl to make sure DS + * is not in use when we change it */ + debugctl = 0; + update_debugctlmsr(0); + wrmsr(MSR_IA32_DS_AREA, ds_next, 0); + } + return debugctl; +} +#else +static int update_debugctl(struct thread_struct *prev, + struct thread_struct *next, unsigned long debugctl) +{ + return debugctl; +} +#endif /* CONFIG_X86_DS */ + static noinline void __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p, struct tss_struct *tss) @@ -446,14 +493,7 @@ __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p, prev = &prev_p->thread; next = &next_p->thread; - debugctl = prev->debugctlmsr; - if (next->ds_area_msr != prev->ds_area_msr) { - /* we clear debugctl to make sure DS - * is not in use when we change it */ - debugctl = 0; - update_debugctlmsr(0); - wrmsr(MSR_IA32_DS_AREA, next->ds_area_msr, 0); - } + debugctl = update_debugctl(prev, next, prev->debugctlmsr); if (next->debugctlmsr != debugctl) update_debugctlmsr(next->debugctlmsr); @@ -477,13 +517,13 @@ __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p, hard_enable_TSC(); } -#ifdef X86_BTS +#ifdef CONFIG_X86_PTRACE_BTS if (test_tsk_thread_flag(prev_p, TIF_BTS_TRACE_TS)) ptrace_bts_take_timestamp(prev_p, BTS_TASK_DEPARTS); if (test_tsk_thread_flag(next_p, TIF_BTS_TRACE_TS)) ptrace_bts_take_timestamp(next_p, BTS_TASK_ARRIVES); -#endif +#endif /* CONFIG_X86_PTRACE_BTS */ if (!test_tsk_thread_flag(next_p, TIF_IO_BITMAP)) { diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index 71553b664e2..2a8ccb9238b 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -37,11 +37,11 @@ #include <linux/kdebug.h> #include <linux/tick.h> #include <linux/prctl.h> +#include <linux/uaccess.h> +#include <linux/io.h> -#include <asm/uaccess.h> #include <asm/pgtable.h> #include <asm/system.h> -#include <asm/io.h> #include <asm/processor.h> #include <asm/i387.h> #include <asm/mmu_context.h> @@ -51,6 +51,7 @@ #include <asm/proto.h> #include <asm/ia32.h> #include <asm/idle.h> +#include <asm/syscalls.h> asmlinkage extern void ret_from_fork(void); @@ -88,11 +89,13 @@ void exit_idle(void) #ifdef CONFIG_HOTPLUG_CPU DECLARE_PER_CPU(int, cpu_state); -#include <asm/nmi.h> +#include <linux/nmi.h> /* We halt the CPU with physical CPU hotplug */ static inline void play_dead(void) { idle_task_exit(); + c1e_remove_cpu(raw_smp_processor_id()); + mb(); /* Ack it */ __get_cpu_var(cpu_state) = CPU_DEAD; @@ -151,7 +154,7 @@ void cpu_idle(void) } /* Prints also some state that isn't saved in the pt_regs */ -void __show_regs(struct pt_regs * regs) +void __show_regs(struct pt_regs *regs) { unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L, fs, gs, shadowgs; unsigned long d0, d1, d2, d3, d6, d7; @@ -160,59 +163,61 @@ void __show_regs(struct pt_regs * regs) printk("\n"); print_modules(); - printk("Pid: %d, comm: %.20s %s %s %.*s\n", + printk(KERN_INFO "Pid: %d, comm: %.20s %s %s %.*s\n", current->pid, current->comm, print_tainted(), init_utsname()->release, (int)strcspn(init_utsname()->version, " "), init_utsname()->version); - printk("RIP: %04lx:[<%016lx>] ", regs->cs & 0xffff, regs->ip); + printk(KERN_INFO "RIP: %04lx:[<%016lx>] ", regs->cs & 0xffff, regs->ip); printk_address(regs->ip, 1); - printk("RSP: %04lx:%016lx EFLAGS: %08lx\n", regs->ss, regs->sp, - regs->flags); - printk("RAX: %016lx RBX: %016lx RCX: %016lx\n", + printk(KERN_INFO "RSP: %04lx:%016lx EFLAGS: %08lx\n", regs->ss, + regs->sp, regs->flags); + printk(KERN_INFO "RAX: %016lx RBX: %016lx RCX: %016lx\n", regs->ax, regs->bx, regs->cx); - printk("RDX: %016lx RSI: %016lx RDI: %016lx\n", + printk(KERN_INFO "RDX: %016lx RSI: %016lx RDI: %016lx\n", regs->dx, regs->si, regs->di); - printk("RBP: %016lx R08: %016lx R09: %016lx\n", + printk(KERN_INFO "RBP: %016lx R08: %016lx R09: %016lx\n", regs->bp, regs->r8, regs->r9); - printk("R10: %016lx R11: %016lx R12: %016lx\n", - regs->r10, regs->r11, regs->r12); - printk("R13: %016lx R14: %016lx R15: %016lx\n", - regs->r13, regs->r14, regs->r15); - - asm("movl %%ds,%0" : "=r" (ds)); - asm("movl %%cs,%0" : "=r" (cs)); - asm("movl %%es,%0" : "=r" (es)); + printk(KERN_INFO "R10: %016lx R11: %016lx R12: %016lx\n", + regs->r10, regs->r11, regs->r12); + printk(KERN_INFO "R13: %016lx R14: %016lx R15: %016lx\n", + regs->r13, regs->r14, regs->r15); + + asm("movl %%ds,%0" : "=r" (ds)); + asm("movl %%cs,%0" : "=r" (cs)); + asm("movl %%es,%0" : "=r" (es)); asm("movl %%fs,%0" : "=r" (fsindex)); asm("movl %%gs,%0" : "=r" (gsindex)); rdmsrl(MSR_FS_BASE, fs); - rdmsrl(MSR_GS_BASE, gs); - rdmsrl(MSR_KERNEL_GS_BASE, shadowgs); + rdmsrl(MSR_GS_BASE, gs); + rdmsrl(MSR_KERNEL_GS_BASE, shadowgs); cr0 = read_cr0(); cr2 = read_cr2(); cr3 = read_cr3(); cr4 = read_cr4(); - printk("FS: %016lx(%04x) GS:%016lx(%04x) knlGS:%016lx\n", - fs,fsindex,gs,gsindex,shadowgs); - printk("CS: %04x DS: %04x ES: %04x CR0: %016lx\n", cs, ds, es, cr0); - printk("CR2: %016lx CR3: %016lx CR4: %016lx\n", cr2, cr3, cr4); + printk(KERN_INFO "FS: %016lx(%04x) GS:%016lx(%04x) knlGS:%016lx\n", + fs, fsindex, gs, gsindex, shadowgs); + printk(KERN_INFO "CS: %04x DS: %04x ES: %04x CR0: %016lx\n", cs, ds, + es, cr0); + printk(KERN_INFO "CR2: %016lx CR3: %016lx CR4: %016lx\n", cr2, cr3, + cr4); get_debugreg(d0, 0); get_debugreg(d1, 1); get_debugreg(d2, 2); - printk("DR0: %016lx DR1: %016lx DR2: %016lx\n", d0, d1, d2); + printk(KERN_INFO "DR0: %016lx DR1: %016lx DR2: %016lx\n", d0, d1, d2); get_debugreg(d3, 3); get_debugreg(d6, 6); get_debugreg(d7, 7); - printk("DR3: %016lx DR6: %016lx DR7: %016lx\n", d3, d6, d7); + printk(KERN_INFO "DR3: %016lx DR6: %016lx DR7: %016lx\n", d3, d6, d7); } void show_regs(struct pt_regs *regs) { - printk("CPU %d:", smp_processor_id()); + printk(KERN_INFO "CPU %d:", smp_processor_id()); __show_regs(regs); show_trace(NULL, regs, (void *)(regs + 1), regs->bp); } @@ -238,6 +243,14 @@ void exit_thread(void) t->io_bitmap_max = 0; put_cpu(); } +#ifdef CONFIG_X86_DS + /* Free any DS contexts that have not been properly released. */ + if (unlikely(t->ds_ctx)) { + /* we clear debugctl to make sure DS is not used. */ + update_debugctlmsr(0); + ds_free(t->ds_ctx); + } +#endif /* CONFIG_X86_DS */ } void flush_thread(void) @@ -313,10 +326,10 @@ void prepare_to_copy(struct task_struct *tsk) int copy_thread(int nr, unsigned long clone_flags, unsigned long sp, unsigned long unused, - struct task_struct * p, struct pt_regs * regs) + struct task_struct *p, struct pt_regs *regs) { int err; - struct pt_regs * childregs; + struct pt_regs *childregs; struct task_struct *me = current; childregs = ((struct pt_regs *) @@ -361,10 +374,10 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp, if (test_thread_flag(TIF_IA32)) err = do_set_thread_area(p, -1, (struct user_desc __user *)childregs->si, 0); - else -#endif - err = do_arch_prctl(p, ARCH_SET_FS, childregs->r8); - if (err) + else +#endif + err = do_arch_prctl(p, ARCH_SET_FS, childregs->r8); + if (err) goto out; } err = 0; @@ -471,13 +484,27 @@ static inline void __switch_to_xtra(struct task_struct *prev_p, next = &next_p->thread; debugctl = prev->debugctlmsr; - if (next->ds_area_msr != prev->ds_area_msr) { - /* we clear debugctl to make sure DS - * is not in use when we change it */ - debugctl = 0; - update_debugctlmsr(0); - wrmsrl(MSR_IA32_DS_AREA, next->ds_area_msr); + +#ifdef CONFIG_X86_DS + { + unsigned long ds_prev = 0, ds_next = 0; + + if (prev->ds_ctx) + ds_prev = (unsigned long)prev->ds_ctx->ds; + if (next->ds_ctx) + ds_next = (unsigned long)next->ds_ctx->ds; + + if (ds_next != ds_prev) { + /* + * We clear debugctl to make sure DS + * is not in use when we change it: + */ + debugctl = 0; + update_debugctlmsr(0); + wrmsrl(MSR_IA32_DS_AREA, ds_next); + } } +#endif /* CONFIG_X86_DS */ if (next->debugctlmsr != debugctl) update_debugctlmsr(next->debugctlmsr); @@ -515,13 +542,13 @@ static inline void __switch_to_xtra(struct task_struct *prev_p, memset(tss->io_bitmap, 0xff, prev->io_bitmap_max); } -#ifdef X86_BTS +#ifdef CONFIG_X86_PTRACE_BTS if (test_tsk_thread_flag(prev_p, TIF_BTS_TRACE_TS)) ptrace_bts_take_timestamp(prev_p, BTS_TASK_DEPARTS); if (test_tsk_thread_flag(next_p, TIF_BTS_TRACE_TS)) ptrace_bts_take_timestamp(next_p, BTS_TASK_ARRIVES); -#endif +#endif /* CONFIG_X86_PTRACE_BTS */ } /* @@ -543,7 +570,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) unsigned fsindex, gsindex; /* we're going to use this soon, after a few expensive things */ - if (next_p->fpu_counter>5) + if (next_p->fpu_counter > 5) prefetch(next->xstate); /* @@ -551,13 +578,13 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) */ load_sp0(tss, next); - /* + /* * Switch DS and ES. * This won't pick up thread selector changes, but I guess that is ok. */ savesegment(es, prev->es); if (unlikely(next->es | prev->es)) - loadsegment(es, next->es); + loadsegment(es, next->es); savesegment(ds, prev->ds); if (unlikely(next->ds | prev->ds)) @@ -583,7 +610,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) */ arch_leave_lazy_cpu_mode(); - /* + /* * Switch FS and GS. * * Segment register != 0 always requires a reload. Also @@ -592,13 +619,13 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) */ if (unlikely(fsindex | next->fsindex | prev->fs)) { loadsegment(fs, next->fsindex); - /* + /* * Check if the user used a selector != 0; if yes * clear 64bit base, since overloaded base is always * mapped to the Null selector */ if (fsindex) - prev->fs = 0; + prev->fs = 0; } /* when next process has a 64bit base use it */ if (next->fs) @@ -608,7 +635,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) if (unlikely(gsindex | next->gsindex | prev->gs)) { load_gs_index(next->gsindex); if (gsindex) - prev->gs = 0; + prev->gs = 0; } if (next->gs) wrmsrl(MSR_KERNEL_GS_BASE, next->gs); @@ -617,12 +644,12 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) /* Must be after DS reload */ unlazy_fpu(prev_p); - /* + /* * Switch the PDA and FPU contexts. */ prev->usersp = read_pda(oldrsp); write_pda(oldrsp, next->usersp); - write_pda(pcurrent, next_p); + write_pda(pcurrent, next_p); write_pda(kernelstack, (unsigned long)task_stack_page(next_p) + @@ -663,7 +690,7 @@ long sys_execve(char __user *name, char __user * __user *argv, char __user * __user *envp, struct pt_regs *regs) { long error; - char * filename; + char *filename; filename = getname(name); error = PTR_ERR(filename); @@ -721,55 +748,55 @@ asmlinkage long sys_vfork(struct pt_regs *regs) unsigned long get_wchan(struct task_struct *p) { unsigned long stack; - u64 fp,ip; + u64 fp, ip; int count = 0; - if (!p || p == current || p->state==TASK_RUNNING) - return 0; + if (!p || p == current || p->state == TASK_RUNNING) + return 0; stack = (unsigned long)task_stack_page(p); if (p->thread.sp < stack || p->thread.sp > stack+THREAD_SIZE) return 0; fp = *(u64 *)(p->thread.sp); - do { + do { if (fp < (unsigned long)stack || fp > (unsigned long)stack+THREAD_SIZE) - return 0; + return 0; ip = *(u64 *)(fp+8); if (!in_sched_functions(ip)) return ip; - fp = *(u64 *)fp; - } while (count++ < 16); + fp = *(u64 *)fp; + } while (count++ < 16); return 0; } long do_arch_prctl(struct task_struct *task, int code, unsigned long addr) -{ - int ret = 0; +{ + int ret = 0; int doit = task == current; int cpu; - switch (code) { + switch (code) { case ARCH_SET_GS: if (addr >= TASK_SIZE_OF(task)) - return -EPERM; + return -EPERM; cpu = get_cpu(); - /* handle small bases via the GDT because that's faster to + /* handle small bases via the GDT because that's faster to switch. */ - if (addr <= 0xffffffff) { - set_32bit_tls(task, GS_TLS, addr); - if (doit) { + if (addr <= 0xffffffff) { + set_32bit_tls(task, GS_TLS, addr); + if (doit) { load_TLS(&task->thread, cpu); - load_gs_index(GS_TLS_SEL); + load_gs_index(GS_TLS_SEL); } - task->thread.gsindex = GS_TLS_SEL; + task->thread.gsindex = GS_TLS_SEL; task->thread.gs = 0; - } else { + } else { task->thread.gsindex = 0; task->thread.gs = addr; if (doit) { load_gs_index(0); ret = checking_wrmsrl(MSR_KERNEL_GS_BASE, addr); - } + } } put_cpu(); break; @@ -823,8 +850,7 @@ long do_arch_prctl(struct task_struct *task, int code, unsigned long addr) rdmsrl(MSR_KERNEL_GS_BASE, base); else base = task->thread.gs; - } - else + } else base = task->thread.gs; ret = put_user(base, (unsigned long __user *)addr); break; diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c index e37dccce85d..e375b658efc 100644 --- a/arch/x86/kernel/ptrace.c +++ b/arch/x86/kernel/ptrace.c @@ -14,6 +14,7 @@ #include <linux/errno.h> #include <linux/ptrace.h> #include <linux/regset.h> +#include <linux/tracehook.h> #include <linux/user.h> #include <linux/elf.h> #include <linux/security.h> @@ -69,7 +70,7 @@ static inline bool invalid_selector(u16 value) #define FLAG_MASK FLAG_MASK_32 -static long *pt_regs_access(struct pt_regs *regs, unsigned long regno) +static unsigned long *pt_regs_access(struct pt_regs *regs, unsigned long regno) { BUILD_BUG_ON(offsetof(struct pt_regs, bx) != 0); regno >>= 2; @@ -554,45 +555,115 @@ static int ptrace_set_debugreg(struct task_struct *child, return 0; } -#ifdef X86_BTS +#ifdef CONFIG_X86_PTRACE_BTS +/* + * The configuration for a particular BTS hardware implementation. + */ +struct bts_configuration { + /* the size of a BTS record in bytes; at most BTS_MAX_RECORD_SIZE */ + unsigned char sizeof_bts; + /* the size of a field in the BTS record in bytes */ + unsigned char sizeof_field; + /* a bitmask to enable/disable BTS in DEBUGCTL MSR */ + unsigned long debugctl_mask; +}; +static struct bts_configuration bts_cfg; + +#define BTS_MAX_RECORD_SIZE (8 * 3) + + +/* + * Branch Trace Store (BTS) uses the following format. Different + * architectures vary in the size of those fields. + * - source linear address + * - destination linear address + * - flags + * + * Later architectures use 64bit pointers throughout, whereas earlier + * architectures use 32bit pointers in 32bit mode. + * + * We compute the base address for the first 8 fields based on: + * - the field size stored in the DS configuration + * - the relative field position + * + * In order to store additional information in the BTS buffer, we use + * a special source address to indicate that the record requires + * special interpretation. + * + * Netburst indicated via a bit in the flags field whether the branch + * was predicted; this is ignored. + */ + +enum bts_field { + bts_from = 0, + bts_to, + bts_flags, + + bts_escape = (unsigned long)-1, + bts_qual = bts_to, + bts_jiffies = bts_flags +}; + +static inline unsigned long bts_get(const char *base, enum bts_field field) +{ + base += (bts_cfg.sizeof_field * field); + return *(unsigned long *)base; +} -static int ptrace_bts_get_size(struct task_struct *child) +static inline void bts_set(char *base, enum bts_field field, unsigned long val) { - if (!child->thread.ds_area_msr) - return -ENXIO; + base += (bts_cfg.sizeof_field * field);; + (*(unsigned long *)base) = val; +} - return ds_get_bts_index((void *)child->thread.ds_area_msr); +/* + * Translate a BTS record from the raw format into the bts_struct format + * + * out (out): bts_struct interpretation + * raw: raw BTS record + */ +static void ptrace_bts_translate_record(struct bts_struct *out, const void *raw) +{ + memset(out, 0, sizeof(*out)); + if (bts_get(raw, bts_from) == bts_escape) { + out->qualifier = bts_get(raw, bts_qual); + out->variant.jiffies = bts_get(raw, bts_jiffies); + } else { + out->qualifier = BTS_BRANCH; + out->variant.lbr.from_ip = bts_get(raw, bts_from); + out->variant.lbr.to_ip = bts_get(raw, bts_to); + } } -static int ptrace_bts_read_record(struct task_struct *child, - long index, +static int ptrace_bts_read_record(struct task_struct *child, size_t index, struct bts_struct __user *out) { struct bts_struct ret; - int retval; - int bts_end; - int bts_index; - - if (!child->thread.ds_area_msr) - return -ENXIO; + const void *bts_record; + size_t bts_index, bts_end; + int error; - if (index < 0) - return -EINVAL; + error = ds_get_bts_end(child, &bts_end); + if (error < 0) + return error; - bts_end = ds_get_bts_end((void *)child->thread.ds_area_msr); if (bts_end <= index) return -EINVAL; + error = ds_get_bts_index(child, &bts_index); + if (error < 0) + return error; + /* translate the ptrace bts index into the ds bts index */ - bts_index = ds_get_bts_index((void *)child->thread.ds_area_msr); - bts_index -= (index + 1); - if (bts_index < 0) - bts_index += bts_end; + bts_index += bts_end - (index + 1); + if (bts_end <= bts_index) + bts_index -= bts_end; - retval = ds_read_bts((void *)child->thread.ds_area_msr, - bts_index, &ret); - if (retval < 0) - return retval; + error = ds_access_bts(child, bts_index, &bts_record); + if (error < 0) + return error; + + ptrace_bts_translate_record(&ret, bts_record); if (copy_to_user(out, &ret, sizeof(ret))) return -EFAULT; @@ -600,101 +671,106 @@ static int ptrace_bts_read_record(struct task_struct *child, return sizeof(ret); } -static int ptrace_bts_clear(struct task_struct *child) -{ - if (!child->thread.ds_area_msr) - return -ENXIO; - - return ds_clear((void *)child->thread.ds_area_msr); -} - static int ptrace_bts_drain(struct task_struct *child, long size, struct bts_struct __user *out) { - int end, i; - void *ds = (void *)child->thread.ds_area_msr; - - if (!ds) - return -ENXIO; + struct bts_struct ret; + const unsigned char *raw; + size_t end, i; + int error; - end = ds_get_bts_index(ds); - if (end <= 0) - return end; + error = ds_get_bts_index(child, &end); + if (error < 0) + return error; if (size < (end * sizeof(struct bts_struct))) return -EIO; - for (i = 0; i < end; i++, out++) { - struct bts_struct ret; - int retval; + error = ds_access_bts(child, 0, (const void **)&raw); + if (error < 0) + return error; - retval = ds_read_bts(ds, i, &ret); - if (retval < 0) - return retval; + for (i = 0; i < end; i++, out++, raw += bts_cfg.sizeof_bts) { + ptrace_bts_translate_record(&ret, raw); if (copy_to_user(out, &ret, sizeof(ret))) return -EFAULT; } - ds_clear(ds); + error = ds_clear_bts(child); + if (error < 0) + return error; return end; } +static void ptrace_bts_ovfl(struct task_struct *child) +{ + send_sig(child->thread.bts_ovfl_signal, child, 0); +} + static int ptrace_bts_config(struct task_struct *child, long cfg_size, const struct ptrace_bts_config __user *ucfg) { struct ptrace_bts_config cfg; - int bts_size, ret = 0; - void *ds; + int error = 0; + + error = -EOPNOTSUPP; + if (!bts_cfg.sizeof_bts) + goto errout; + error = -EIO; if (cfg_size < sizeof(cfg)) - return -EIO; + goto errout; + error = -EFAULT; if (copy_from_user(&cfg, ucfg, sizeof(cfg))) - return -EFAULT; + goto errout; - if ((int)cfg.size < 0) - return -EINVAL; + error = -EINVAL; + if ((cfg.flags & PTRACE_BTS_O_SIGNAL) && + !(cfg.flags & PTRACE_BTS_O_ALLOC)) + goto errout; - bts_size = 0; - ds = (void *)child->thread.ds_area_msr; - if (ds) { - bts_size = ds_get_bts_size(ds); - if (bts_size < 0) - return bts_size; - } - cfg.size = PAGE_ALIGN(cfg.size); + if (cfg.flags & PTRACE_BTS_O_ALLOC) { + ds_ovfl_callback_t ovfl = NULL; + unsigned int sig = 0; + + /* we ignore the error in case we were not tracing child */ + (void)ds_release_bts(child); - if (bts_size != cfg.size) { - ret = ptrace_bts_realloc(child, cfg.size, - cfg.flags & PTRACE_BTS_O_CUT_SIZE); - if (ret < 0) + if (cfg.flags & PTRACE_BTS_O_SIGNAL) { + if (!cfg.signal) + goto errout; + + sig = cfg.signal; + ovfl = ptrace_bts_ovfl; + } + + error = ds_request_bts(child, /* base = */ NULL, cfg.size, ovfl); + if (error < 0) goto errout; - ds = (void *)child->thread.ds_area_msr; + child->thread.bts_ovfl_signal = sig; } - if (cfg.flags & PTRACE_BTS_O_SIGNAL) - ret = ds_set_overflow(ds, DS_O_SIGNAL); - else - ret = ds_set_overflow(ds, DS_O_WRAP); - if (ret < 0) + error = -EINVAL; + if (!child->thread.ds_ctx && cfg.flags) goto errout; if (cfg.flags & PTRACE_BTS_O_TRACE) - child->thread.debugctlmsr |= ds_debugctl_mask(); + child->thread.debugctlmsr |= bts_cfg.debugctl_mask; else - child->thread.debugctlmsr &= ~ds_debugctl_mask(); + child->thread.debugctlmsr &= ~bts_cfg.debugctl_mask; if (cfg.flags & PTRACE_BTS_O_SCHED) set_tsk_thread_flag(child, TIF_BTS_TRACE_TS); else clear_tsk_thread_flag(child, TIF_BTS_TRACE_TS); - ret = sizeof(cfg); + error = sizeof(cfg); out: if (child->thread.debugctlmsr) @@ -702,10 +778,10 @@ out: else clear_tsk_thread_flag(child, TIF_DEBUGCTLMSR); - return ret; + return error; errout: - child->thread.debugctlmsr &= ~ds_debugctl_mask(); + child->thread.debugctlmsr &= ~bts_cfg.debugctl_mask; clear_tsk_thread_flag(child, TIF_BTS_TRACE_TS); goto out; } @@ -714,29 +790,40 @@ static int ptrace_bts_status(struct task_struct *child, long cfg_size, struct ptrace_bts_config __user *ucfg) { - void *ds = (void *)child->thread.ds_area_msr; struct ptrace_bts_config cfg; + size_t end; + const void *base, *max; + int error; if (cfg_size < sizeof(cfg)) return -EIO; - memset(&cfg, 0, sizeof(cfg)); + error = ds_get_bts_end(child, &end); + if (error < 0) + return error; - if (ds) { - cfg.size = ds_get_bts_size(ds); + error = ds_access_bts(child, /* index = */ 0, &base); + if (error < 0) + return error; - if (ds_get_overflow(ds) == DS_O_SIGNAL) - cfg.flags |= PTRACE_BTS_O_SIGNAL; + error = ds_access_bts(child, /* index = */ end, &max); + if (error < 0) + return error; - if (test_tsk_thread_flag(child, TIF_DEBUGCTLMSR) && - child->thread.debugctlmsr & ds_debugctl_mask()) - cfg.flags |= PTRACE_BTS_O_TRACE; + memset(&cfg, 0, sizeof(cfg)); + cfg.size = (max - base); + cfg.signal = child->thread.bts_ovfl_signal; + cfg.bts_size = sizeof(struct bts_struct); - if (test_tsk_thread_flag(child, TIF_BTS_TRACE_TS)) - cfg.flags |= PTRACE_BTS_O_SCHED; - } + if (cfg.signal) + cfg.flags |= PTRACE_BTS_O_SIGNAL; - cfg.bts_size = sizeof(struct bts_struct); + if (test_tsk_thread_flag(child, TIF_DEBUGCTLMSR) && + child->thread.debugctlmsr & bts_cfg.debugctl_mask) + cfg.flags |= PTRACE_BTS_O_TRACE; + + if (test_tsk_thread_flag(child, TIF_BTS_TRACE_TS)) + cfg.flags |= PTRACE_BTS_O_SCHED; if (copy_to_user(ucfg, &cfg, sizeof(cfg))) return -EFAULT; @@ -744,89 +831,38 @@ static int ptrace_bts_status(struct task_struct *child, return sizeof(cfg); } - static int ptrace_bts_write_record(struct task_struct *child, const struct bts_struct *in) { - int retval; + unsigned char bts_record[BTS_MAX_RECORD_SIZE]; - if (!child->thread.ds_area_msr) - return -ENXIO; + BUG_ON(BTS_MAX_RECORD_SIZE < bts_cfg.sizeof_bts); - retval = ds_write_bts((void *)child->thread.ds_area_msr, in); - if (retval) - return retval; + memset(bts_record, 0, bts_cfg.sizeof_bts); + switch (in->qualifier) { + case BTS_INVALID: + break; - return sizeof(*in); -} + case BTS_BRANCH: + bts_set(bts_record, bts_from, in->variant.lbr.from_ip); + bts_set(bts_record, bts_to, in->variant.lbr.to_ip); + break; -static int ptrace_bts_realloc(struct task_struct *child, - int size, int reduce_size) -{ - unsigned long rlim, vm; - int ret, old_size; + case BTS_TASK_ARRIVES: + case BTS_TASK_DEPARTS: + bts_set(bts_record, bts_from, bts_escape); + bts_set(bts_record, bts_qual, in->qualifier); + bts_set(bts_record, bts_jiffies, in->variant.jiffies); + break; - if (size < 0) + default: return -EINVAL; - - old_size = ds_get_bts_size((void *)child->thread.ds_area_msr); - if (old_size < 0) - return old_size; - - ret = ds_free((void **)&child->thread.ds_area_msr); - if (ret < 0) - goto out; - - size >>= PAGE_SHIFT; - old_size >>= PAGE_SHIFT; - - current->mm->total_vm -= old_size; - current->mm->locked_vm -= old_size; - - if (size == 0) - goto out; - - rlim = current->signal->rlim[RLIMIT_AS].rlim_cur >> PAGE_SHIFT; - vm = current->mm->total_vm + size; - if (rlim < vm) { - ret = -ENOMEM; - - if (!reduce_size) - goto out; - - size = rlim - current->mm->total_vm; - if (size <= 0) - goto out; - } - - rlim = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur >> PAGE_SHIFT; - vm = current->mm->locked_vm + size; - if (rlim < vm) { - ret = -ENOMEM; - - if (!reduce_size) - goto out; - - size = rlim - current->mm->locked_vm; - if (size <= 0) - goto out; } - ret = ds_allocate((void **)&child->thread.ds_area_msr, - size << PAGE_SHIFT); - if (ret < 0) - goto out; - - current->mm->total_vm += size; - current->mm->locked_vm += size; - -out: - if (child->thread.ds_area_msr) - set_tsk_thread_flag(child, TIF_DS_AREA_MSR); - else - clear_tsk_thread_flag(child, TIF_DS_AREA_MSR); - - return ret; + /* The writing task will be the switched-to task on a context + * switch. It needs to write into the switched-from task's BTS + * buffer. */ + return ds_unchecked_write_bts(child, bts_record, bts_cfg.sizeof_bts); } void ptrace_bts_take_timestamp(struct task_struct *tsk, @@ -839,7 +875,66 @@ void ptrace_bts_take_timestamp(struct task_struct *tsk, ptrace_bts_write_record(tsk, &rec); } -#endif /* X86_BTS */ + +static const struct bts_configuration bts_cfg_netburst = { + .sizeof_bts = sizeof(long) * 3, + .sizeof_field = sizeof(long), + .debugctl_mask = (1<<2)|(1<<3)|(1<<5) +}; + +static const struct bts_configuration bts_cfg_pentium_m = { + .sizeof_bts = sizeof(long) * 3, + .sizeof_field = sizeof(long), + .debugctl_mask = (1<<6)|(1<<7) +}; + +static const struct bts_configuration bts_cfg_core2 = { + .sizeof_bts = 8 * 3, + .sizeof_field = 8, + .debugctl_mask = (1<<6)|(1<<7)|(1<<9) +}; + +static inline void bts_configure(const struct bts_configuration *cfg) +{ + bts_cfg = *cfg; +} + +void __cpuinit ptrace_bts_init_intel(struct cpuinfo_x86 *c) +{ + switch (c->x86) { + case 0x6: + switch (c->x86_model) { + case 0xD: + case 0xE: /* Pentium M */ + bts_configure(&bts_cfg_pentium_m); + break; + case 0xF: /* Core2 */ + case 0x1C: /* Atom */ + bts_configure(&bts_cfg_core2); + break; + default: + /* sorry, don't know about them */ + break; + } + break; + case 0xF: + switch (c->x86_model) { + case 0x0: + case 0x1: + case 0x2: /* Netburst */ + bts_configure(&bts_cfg_netburst); + break; + default: + /* sorry, don't know about them */ + break; + } + break; + default: + /* sorry, don't know about them */ + break; + } +} +#endif /* CONFIG_X86_PTRACE_BTS */ /* * Called by kernel/ptrace.c when detaching.. @@ -852,15 +947,15 @@ void ptrace_disable(struct task_struct *child) #ifdef TIF_SYSCALL_EMU clear_tsk_thread_flag(child, TIF_SYSCALL_EMU); #endif - if (child->thread.ds_area_msr) { -#ifdef X86_BTS - ptrace_bts_realloc(child, 0, 0); -#endif - child->thread.debugctlmsr &= ~ds_debugctl_mask(); - if (!child->thread.debugctlmsr) - clear_tsk_thread_flag(child, TIF_DEBUGCTLMSR); - clear_tsk_thread_flag(child, TIF_BTS_TRACE_TS); - } +#ifdef CONFIG_X86_PTRACE_BTS + (void)ds_release_bts(child); + + child->thread.debugctlmsr &= ~bts_cfg.debugctl_mask; + if (!child->thread.debugctlmsr) + clear_tsk_thread_flag(child, TIF_DEBUGCTLMSR); + + clear_tsk_thread_flag(child, TIF_BTS_TRACE_TS); +#endif /* CONFIG_X86_PTRACE_BTS */ } #if defined CONFIG_X86_32 || defined CONFIG_IA32_EMULATION @@ -980,7 +1075,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) /* * These bits need more cooking - not enabled yet: */ -#ifdef X86_BTS +#ifdef CONFIG_X86_PTRACE_BTS case PTRACE_BTS_CONFIG: ret = ptrace_bts_config (child, data, (struct ptrace_bts_config __user *)addr); @@ -992,7 +1087,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) break; case PTRACE_BTS_SIZE: - ret = ptrace_bts_get_size(child); + ret = ds_get_bts_index(child, /* pos = */ NULL); break; case PTRACE_BTS_GET: @@ -1001,14 +1096,14 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) break; case PTRACE_BTS_CLEAR: - ret = ptrace_bts_clear(child); + ret = ds_clear_bts(child); break; case PTRACE_BTS_DRAIN: ret = ptrace_bts_drain (child, data, (struct bts_struct __user *) addr); break; -#endif +#endif /* CONFIG_X86_PTRACE_BTS */ default: ret = ptrace_request(child, request, addr, data); @@ -1375,30 +1470,6 @@ void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code) force_sig_info(SIGTRAP, &info, tsk); } -static void syscall_trace(struct pt_regs *regs) -{ - if (!(current->ptrace & PT_PTRACED)) - return; - -#if 0 - printk("trace %s ip %lx sp %lx ax %d origrax %d caller %lx tiflags %x ptrace %x\n", - current->comm, - regs->ip, regs->sp, regs->ax, regs->orig_ax, __builtin_return_address(0), - current_thread_info()->flags, current->ptrace); -#endif - - ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) - ? 0x80 : 0)); - /* - * this isn't the same as continuing with a signal, but it will do - * for normal use. strace only continues with a signal if the - * stopping signal is not SIGTRAP. -brl - */ - if (current->exit_code) { - send_sig(current->exit_code, current, 1); - current->exit_code = 0; - } -} #ifdef CONFIG_X86_32 # define IS_IA32 1 @@ -1432,8 +1503,9 @@ asmregparm long syscall_trace_enter(struct pt_regs *regs) if (unlikely(test_thread_flag(TIF_SYSCALL_EMU))) ret = -1L; - if (ret || test_thread_flag(TIF_SYSCALL_TRACE)) - syscall_trace(regs); + if ((ret || test_thread_flag(TIF_SYSCALL_TRACE)) && + tracehook_report_syscall_entry(regs)) + ret = -1L; if (unlikely(current->audit_context)) { if (IS_IA32) @@ -1459,7 +1531,7 @@ asmregparm void syscall_trace_leave(struct pt_regs *regs) audit_syscall_exit(AUDITSC_RESULT(regs->ax), regs->ax); if (test_thread_flag(TIF_SYSCALL_TRACE)) - syscall_trace(regs); + tracehook_report_syscall_exit(regs, 0); /* * If TIF_SYSCALL_EMU is set, we only get here because of @@ -1475,6 +1547,6 @@ asmregparm void syscall_trace_leave(struct pt_regs *regs) * system call instruction. */ if (test_thread_flag(TIF_SINGLESTEP) && - (current->ptrace & PT_PTRACED)) + tracehook_consider_fatal_signal(current, SIGTRAP, SIG_DFL)) send_sigtrap(current, regs, 0); } diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c index 724adfc63cb..f4c93f1cfc1 100644 --- a/arch/x86/kernel/reboot.c +++ b/arch/x86/kernel/reboot.c @@ -29,7 +29,11 @@ EXPORT_SYMBOL(pm_power_off); static const struct desc_ptr no_idt = {}; static int reboot_mode; -enum reboot_type reboot_type = BOOT_KBD; +/* + * Keyboard reset and triple fault may result in INIT, not RESET, which + * doesn't work when we're in vmx root mode. Try ACPI first. + */ +enum reboot_type reboot_type = BOOT_ACPI; int reboot_force; #if defined(CONFIG_X86_32) && defined(CONFIG_SMP) diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 9838f2539df..141efab5240 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -223,6 +223,9 @@ unsigned long saved_video_mode; #define RAMDISK_LOAD_FLAG 0x4000 static char __initdata command_line[COMMAND_LINE_SIZE]; +#ifdef CONFIG_CMDLINE_BOOL +static char __initdata builtin_cmdline[COMMAND_LINE_SIZE] = CONFIG_CMDLINE; +#endif #if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE) struct edd edd; @@ -665,6 +668,19 @@ void __init setup_arch(char **cmdline_p) bss_resource.start = virt_to_phys(&__bss_start); bss_resource.end = virt_to_phys(&__bss_stop)-1; +#ifdef CONFIG_CMDLINE_BOOL +#ifdef CONFIG_CMDLINE_OVERRIDE + strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE); +#else + if (builtin_cmdline[0]) { + /* append boot loader cmdline to builtin */ + strlcat(builtin_cmdline, " ", COMMAND_LINE_SIZE); + strlcat(builtin_cmdline, boot_command_line, COMMAND_LINE_SIZE); + strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE); + } +#endif +#endif + strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE); *cmdline_p = command_line; diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c index 76e305e064f..0e67f72d931 100644 --- a/arch/x86/kernel/setup_percpu.c +++ b/arch/x86/kernel/setup_percpu.c @@ -162,9 +162,16 @@ void __init setup_per_cpu_areas(void) printk(KERN_INFO "cpu %d has no node %d or node-local memory\n", cpu, node); + if (ptr) + printk(KERN_DEBUG "per cpu data for cpu%d at %016lx\n", + cpu, __pa(ptr)); } - else + else { ptr = alloc_bootmem_pages_node(NODE_DATA(node), size); + if (ptr) + printk(KERN_DEBUG "per cpu data for cpu%d on node%d at %016lx\n", + cpu, node, __pa(ptr)); + } #endif per_cpu_offset(cpu) = ptr - __per_cpu_start; memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start); diff --git a/arch/x86/kernel/sigframe.h b/arch/x86/kernel/sigframe.h index 72bbb519d2d..8b4956e800a 100644 --- a/arch/x86/kernel/sigframe.h +++ b/arch/x86/kernel/sigframe.h @@ -24,4 +24,9 @@ struct rt_sigframe { struct ucontext uc; struct siginfo info; }; + +int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, + sigset_t *set, struct pt_regs *regs); +int ia32_setup_frame(int sig, struct k_sigaction *ka, + sigset_t *set, struct pt_regs *regs); #endif diff --git a/arch/x86/kernel/signal_32.c b/arch/x86/kernel/signal_32.c index 6fb5bcdd893..2a2435d3037 100644 --- a/arch/x86/kernel/signal_32.c +++ b/arch/x86/kernel/signal_32.c @@ -17,6 +17,7 @@ #include <linux/errno.h> #include <linux/sched.h> #include <linux/wait.h> +#include <linux/tracehook.h> #include <linux/elf.h> #include <linux/smp.h> #include <linux/mm.h> @@ -26,6 +27,7 @@ #include <asm/uaccess.h> #include <asm/i387.h> #include <asm/vdso.h> +#include <asm/syscalls.h> #include "sigframe.h" @@ -558,8 +560,6 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, * handler too. */ regs->flags &= ~X86_EFLAGS_TF; - if (test_thread_flag(TIF_SINGLESTEP)) - ptrace_notify(SIGTRAP); spin_lock_irq(¤t->sighand->siglock); sigorsets(¤t->blocked, ¤t->blocked, &ka->sa.sa_mask); @@ -568,6 +568,9 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); + tracehook_signal_handler(sig, info, ka, regs, + test_thread_flag(TIF_SINGLESTEP)); + return 0; } @@ -661,5 +664,10 @@ do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags) if (thread_info_flags & _TIF_SIGPENDING) do_signal(regs); + if (thread_info_flags & _TIF_NOTIFY_RESUME) { + clear_thread_flag(TIF_NOTIFY_RESUME); + tracehook_notify_resume(regs); + } + clear_thread_flag(TIF_IRET); } diff --git a/arch/x86/kernel/signal_64.c b/arch/x86/kernel/signal_64.c index ca316b5b742..694aa888bb1 100644 --- a/arch/x86/kernel/signal_64.c +++ b/arch/x86/kernel/signal_64.c @@ -15,17 +15,21 @@ #include <linux/errno.h> #include <linux/wait.h> #include <linux/ptrace.h> +#include <linux/tracehook.h> #include <linux/unistd.h> #include <linux/stddef.h> #include <linux/personality.h> #include <linux/compiler.h> +#include <linux/uaccess.h> + #include <asm/processor.h> #include <asm/ucontext.h> -#include <asm/uaccess.h> #include <asm/i387.h> #include <asm/proto.h> #include <asm/ia32_unistd.h> #include <asm/mce.h> +#include <asm/syscall.h> +#include <asm/syscalls.h> #include "sigframe.h" #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) @@ -41,11 +45,6 @@ # define FIX_EFLAGS __FIX_EFLAGS #endif -int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, - sigset_t *set, struct pt_regs * regs); -int ia32_setup_frame(int sig, struct k_sigaction *ka, - sigset_t *set, struct pt_regs * regs); - asmlinkage long sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, struct pt_regs *regs) @@ -128,7 +127,7 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, /* Always make any pending restarted system calls return -EINTR */ current_thread_info()->restart_block.fn = do_no_restart_syscall; -#define COPY(x) err |= __get_user(regs->x, &sc->x) +#define COPY(x) (err |= __get_user(regs->x, &sc->x)) COPY(di); COPY(si); COPY(bp); COPY(sp); COPY(bx); COPY(dx); COPY(cx); COPY(ip); @@ -158,7 +157,7 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, } { - struct _fpstate __user * buf; + struct _fpstate __user *buf; err |= __get_user(buf, &sc->fpstate); if (buf) { @@ -198,7 +197,7 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs *regs) current->blocked = set; recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); - + if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &ax)) goto badframe; @@ -208,16 +207,17 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs *regs) return ax; badframe: - signal_fault(regs,frame,"sigreturn"); + signal_fault(regs, frame, "sigreturn"); return 0; -} +} /* * Set up a signal frame. */ static inline int -setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, unsigned long mask, struct task_struct *me) +setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, + unsigned long mask, struct task_struct *me) { int err = 0; @@ -273,35 +273,35 @@ get_stack(struct k_sigaction *ka, struct pt_regs *regs, unsigned long size) } static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, - sigset_t *set, struct pt_regs * regs) + sigset_t *set, struct pt_regs *regs) { struct rt_sigframe __user *frame; - struct _fpstate __user *fp = NULL; + struct _fpstate __user *fp = NULL; int err = 0; struct task_struct *me = current; if (used_math()) { - fp = get_stack(ka, regs, sizeof(struct _fpstate)); + fp = get_stack(ka, regs, sizeof(struct _fpstate)); frame = (void __user *)round_down( (unsigned long)fp - sizeof(struct rt_sigframe), 16) - 8; if (!access_ok(VERIFY_WRITE, fp, sizeof(struct _fpstate))) goto give_sigsegv; - if (save_i387(fp) < 0) - err |= -1; + if (save_i387(fp) < 0) + err |= -1; } else frame = get_stack(ka, regs, sizeof(struct rt_sigframe)) - 8; if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) goto give_sigsegv; - if (ka->sa.sa_flags & SA_SIGINFO) { + if (ka->sa.sa_flags & SA_SIGINFO) { err |= copy_siginfo_to_user(&frame->info, info); if (err) goto give_sigsegv; } - + /* Create the ucontext. */ err |= __put_user(0, &frame->uc.uc_flags); err |= __put_user(0, &frame->uc.uc_link); @@ -311,9 +311,9 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, err |= __put_user(me->sas_ss_size, &frame->uc.uc_stack.ss_size); err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0], me); err |= __put_user(fp, &frame->uc.uc_mcontext.fpstate); - if (sizeof(*set) == 16) { + if (sizeof(*set) == 16) { __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]); - __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]); + __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]); } else err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); @@ -324,7 +324,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, err |= __put_user(ka->sa.sa_restorer, &frame->pretcode); } else { /* could use a vstub here */ - goto give_sigsegv; + goto give_sigsegv; } if (err) @@ -332,7 +332,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, /* Set up registers for signal handler */ regs->di = sig; - /* In case the signal handler was declared without prototypes */ + /* In case the signal handler was declared without prototypes */ regs->ax = 0; /* This also works for non SA_SIGINFO handlers because they expect the @@ -355,37 +355,8 @@ give_sigsegv: } /* - * Return -1L or the syscall number that @regs is executing. - */ -static long current_syscall(struct pt_regs *regs) -{ - /* - * We always sign-extend a -1 value being set here, - * so this is always either -1L or a syscall number. - */ - return regs->orig_ax; -} - -/* - * Return a value that is -EFOO if the system call in @regs->orig_ax - * returned an error. This only works for @regs from @current. - */ -static long current_syscall_ret(struct pt_regs *regs) -{ -#ifdef CONFIG_IA32_EMULATION - if (test_thread_flag(TIF_IA32)) - /* - * Sign-extend the value so (int)-EFOO becomes (long)-EFOO - * and will match correctly in comparisons. - */ - return (int) regs->ax; -#endif - return regs->ax; -} - -/* * OK, we're invoking a handler - */ + */ static int handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, @@ -394,9 +365,9 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, int ret; /* Are we from a system call? */ - if (current_syscall(regs) >= 0) { + if (syscall_get_nr(current, regs) >= 0) { /* If so, check system call restarting.. */ - switch (current_syscall_ret(regs)) { + switch (syscall_get_error(current, regs)) { case -ERESTART_RESTARTBLOCK: case -ERESTARTNOHAND: regs->ax = -EINTR; @@ -429,7 +400,7 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, ret = ia32_setup_rt_frame(sig, ka, info, oldset, regs); else ret = ia32_setup_frame(sig, ka, oldset, regs); - } else + } else #endif ret = setup_rt_frame(sig, ka, info, oldset, regs); @@ -453,15 +424,16 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, * handler too. */ regs->flags &= ~X86_EFLAGS_TF; - if (test_thread_flag(TIF_SINGLESTEP)) - ptrace_notify(SIGTRAP); spin_lock_irq(¤t->sighand->siglock); - sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); + sigorsets(¤t->blocked, ¤t->blocked, &ka->sa.sa_mask); if (!(ka->sa.sa_flags & SA_NODEFER)) - sigaddset(¤t->blocked,sig); + sigaddset(¤t->blocked, sig); recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); + + tracehook_signal_handler(sig, info, ka, regs, + test_thread_flag(TIF_SINGLESTEP)); } return ret; @@ -518,9 +490,9 @@ static void do_signal(struct pt_regs *regs) } /* Did we come from a system call? */ - if (current_syscall(regs) >= 0) { + if (syscall_get_nr(current, regs) >= 0) { /* Restart the system call - no handlers present */ - switch (current_syscall_ret(regs)) { + switch (syscall_get_error(current, regs)) { case -ERESTARTNOHAND: case -ERESTARTSYS: case -ERESTARTNOINTR: @@ -558,17 +530,23 @@ void do_notify_resume(struct pt_regs *regs, void *unused, /* deal with pending signal delivery */ if (thread_info_flags & _TIF_SIGPENDING) do_signal(regs); + + if (thread_info_flags & _TIF_NOTIFY_RESUME) { + clear_thread_flag(TIF_NOTIFY_RESUME); + tracehook_notify_resume(regs); + } } void signal_fault(struct pt_regs *regs, void __user *frame, char *where) -{ - struct task_struct *me = current; +{ + struct task_struct *me = current; if (show_unhandled_signals && printk_ratelimit()) { printk("%s[%d] bad frame in %s frame:%p ip:%lx sp:%lx orax:%lx", - me->comm,me->pid,where,frame,regs->ip,regs->sp,regs->orig_ax); + me->comm, me->pid, where, frame, regs->ip, + regs->sp, regs->orig_ax); print_vma_addr(" in ", regs->ip); printk("\n"); } - force_sig(SIGSEGV, me); -} + force_sig(SIGSEGV, me); +} diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index 7985c5b3f91..45531e3ba19 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -88,7 +88,7 @@ static DEFINE_PER_CPU(struct task_struct *, idle_thread_array); #define get_idle_for_cpu(x) (per_cpu(idle_thread_array, x)) #define set_idle_for_cpu(x, p) (per_cpu(idle_thread_array, x) = (p)) #else -struct task_struct *idle_thread_array[NR_CPUS] __cpuinitdata ; +static struct task_struct *idle_thread_array[NR_CPUS] __cpuinitdata ; #define get_idle_for_cpu(x) (idle_thread_array[(x)]) #define set_idle_for_cpu(x, p) (idle_thread_array[(x)] = (p)) #endif @@ -129,7 +129,7 @@ static int boot_cpu_logical_apicid; static cpumask_t cpu_sibling_setup_map; /* Set if we find a B stepping CPU */ -int __cpuinitdata smp_b_stepping; +static int __cpuinitdata smp_b_stepping; #if defined(CONFIG_NUMA) && defined(CONFIG_X86_32) @@ -1313,16 +1313,13 @@ __init void prefill_possible_map(void) if (!num_processors) num_processors = 1; -#ifdef CONFIG_HOTPLUG_CPU if (additional_cpus == -1) { if (disabled_cpus > 0) additional_cpus = disabled_cpus; else additional_cpus = 0; } -#else - additional_cpus = 0; -#endif + possible = num_processors + additional_cpus; if (possible > NR_CPUS) possible = NR_CPUS; diff --git a/arch/x86/kernel/sys_i386_32.c b/arch/x86/kernel/sys_i386_32.c index 7066cb855a6..1884a8d12bf 100644 --- a/arch/x86/kernel/sys_i386_32.c +++ b/arch/x86/kernel/sys_i386_32.c @@ -22,6 +22,8 @@ #include <linux/uaccess.h> #include <linux/unistd.h> +#include <asm/syscalls.h> + asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, unsigned long fd, unsigned long pgoff) diff --git a/arch/x86/kernel/sys_x86_64.c b/arch/x86/kernel/sys_x86_64.c index 3b360ef3381..6bc211accf0 100644 --- a/arch/x86/kernel/sys_x86_64.c +++ b/arch/x86/kernel/sys_x86_64.c @@ -13,15 +13,17 @@ #include <linux/utsname.h> #include <linux/personality.h> #include <linux/random.h> +#include <linux/uaccess.h> -#include <asm/uaccess.h> #include <asm/ia32.h> +#include <asm/syscalls.h> -asmlinkage long sys_mmap(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, - unsigned long fd, unsigned long off) +asmlinkage long sys_mmap(unsigned long addr, unsigned long len, + unsigned long prot, unsigned long flags, + unsigned long fd, unsigned long off) { long error; - struct file * file; + struct file *file; error = -EINVAL; if (off & ~PAGE_MASK) @@ -56,9 +58,9 @@ static void find_start_end(unsigned long flags, unsigned long *begin, unmapped base down for this case. This can give conflicts with the heap, but we assume that glibc malloc knows how to fall back to mmap. Give it 1GB - of playground for now. -AK */ - *begin = 0x40000000; - *end = 0x80000000; + of playground for now. -AK */ + *begin = 0x40000000; + *end = 0x80000000; if (current->flags & PF_RANDOMIZE) { new_begin = randomize_range(*begin, *begin + 0x02000000, 0); if (new_begin) @@ -66,9 +68,9 @@ static void find_start_end(unsigned long flags, unsigned long *begin, } } else { *begin = TASK_UNMAPPED_BASE; - *end = TASK_SIZE; + *end = TASK_SIZE; } -} +} unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, @@ -78,11 +80,11 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, struct vm_area_struct *vma; unsigned long start_addr; unsigned long begin, end; - + if (flags & MAP_FIXED) return addr; - find_start_end(flags, &begin, &end); + find_start_end(flags, &begin, &end); if (len > end) return -ENOMEM; @@ -96,12 +98,12 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, } if (((flags & MAP_32BIT) || test_thread_flag(TIF_IA32)) && len <= mm->cached_hole_size) { - mm->cached_hole_size = 0; + mm->cached_hole_size = 0; mm->free_area_cache = begin; } addr = mm->free_area_cache; - if (addr < begin) - addr = begin; + if (addr < begin) + addr = begin; start_addr = addr; full_search: @@ -127,7 +129,7 @@ full_search: return addr; } if (addr + mm->cached_hole_size < vma->vm_start) - mm->cached_hole_size = vma->vm_start - addr; + mm->cached_hole_size = vma->vm_start - addr; addr = vma->vm_end; } @@ -177,7 +179,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, vma = find_vma(mm, addr-len); if (!vma || addr <= vma->vm_start) /* remember the address as a hint for next time */ - return (mm->free_area_cache = addr-len); + return mm->free_area_cache = addr-len; } if (mm->mmap_base < len) @@ -194,7 +196,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, vma = find_vma(mm, addr); if (!vma || addr+len <= vma->vm_start) /* remember the address as a hint for next time */ - return (mm->free_area_cache = addr); + return mm->free_area_cache = addr; /* remember the largest hole we saw so far */ if (addr + mm->cached_hole_size < vma->vm_start) @@ -224,13 +226,13 @@ bottomup: } -asmlinkage long sys_uname(struct new_utsname __user * name) +asmlinkage long sys_uname(struct new_utsname __user *name) { int err; down_read(&uts_sem); - err = copy_to_user(name, utsname(), sizeof (*name)); + err = copy_to_user(name, utsname(), sizeof(*name)); up_read(&uts_sem); - if (personality(current->personality) == PER_LINUX32) - err |= copy_to_user(&name->machine, "i686", 5); + if (personality(current->personality) == PER_LINUX32) + err |= copy_to_user(&name->machine, "i686", 5); return err ? -EFAULT : 0; } diff --git a/arch/x86/kernel/syscall_64.c b/arch/x86/kernel/syscall_64.c index 170d43c1748..3d1be4f0fac 100644 --- a/arch/x86/kernel/syscall_64.c +++ b/arch/x86/kernel/syscall_64.c @@ -8,12 +8,12 @@ #define __NO_STUBS #define __SYSCALL(nr, sym) extern asmlinkage void sym(void) ; -#undef _ASM_X86_64_UNISTD_H_ +#undef ASM_X86__UNISTD_64_H #include <asm/unistd_64.h> #undef __SYSCALL #define __SYSCALL(nr, sym) [nr] = sym, -#undef _ASM_X86_64_UNISTD_H_ +#undef ASM_X86__UNISTD_64_H typedef void (*sys_call_ptr_t)(void); diff --git a/arch/x86/kernel/time_32.c b/arch/x86/kernel/time_32.c index ffe3c664afc..bbecf8b6bf9 100644 --- a/arch/x86/kernel/time_32.c +++ b/arch/x86/kernel/time_32.c @@ -36,6 +36,7 @@ #include <asm/arch_hooks.h> #include <asm/hpet.h> #include <asm/time.h> +#include <asm/timer.h> #include "do_timer.h" diff --git a/arch/x86/kernel/tls.c b/arch/x86/kernel/tls.c index ab6bf375a30..6bb7b8579e7 100644 --- a/arch/x86/kernel/tls.c +++ b/arch/x86/kernel/tls.c @@ -10,6 +10,7 @@ #include <asm/ldt.h> #include <asm/processor.h> #include <asm/proto.h> +#include <asm/syscalls.h> #include "tls.h" diff --git a/arch/x86/kernel/traps_64.c b/arch/x86/kernel/traps_64.c index 513caaca711..7a31f104bef 100644 --- a/arch/x86/kernel/traps_64.c +++ b/arch/x86/kernel/traps_64.c @@ -32,6 +32,8 @@ #include <linux/bug.h> #include <linux/nmi.h> #include <linux/mm.h> +#include <linux/smp.h> +#include <linux/io.h> #if defined(CONFIG_EDAC) #include <linux/edac.h> @@ -45,9 +47,6 @@ #include <asm/unwind.h> #include <asm/desc.h> #include <asm/i387.h> -#include <asm/nmi.h> -#include <asm/smp.h> -#include <asm/io.h> #include <asm/pgalloc.h> #include <asm/proto.h> #include <asm/pda.h> @@ -85,7 +84,8 @@ static inline void preempt_conditional_cli(struct pt_regs *regs) void printk_address(unsigned long address, int reliable) { - printk(" [<%016lx>] %s%pS\n", address, reliable ? "": "? ", (void *) address); + printk(" [<%016lx>] %s%pS\n", + address, reliable ? "" : "? ", (void *) address); } static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack, @@ -98,7 +98,8 @@ static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack, [STACKFAULT_STACK - 1] = "#SS", [MCE_STACK - 1] = "#MC", #if DEBUG_STKSZ > EXCEPTION_STKSZ - [N_EXCEPTION_STACKS ... N_EXCEPTION_STACKS + DEBUG_STKSZ / EXCEPTION_STKSZ - 2] = "#DB[?]" + [N_EXCEPTION_STACKS ... + N_EXCEPTION_STACKS + DEBUG_STKSZ / EXCEPTION_STKSZ - 2] = "#DB[?]" #endif }; unsigned k; @@ -163,7 +164,7 @@ static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack, } /* - * x86-64 can have up to three kernel stacks: + * x86-64 can have up to three kernel stacks: * process stack * interrupt stack * severe exception (double fault, nmi, stack fault, debug, mce) hardware stack @@ -219,7 +220,7 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs, const struct stacktrace_ops *ops, void *data) { const unsigned cpu = get_cpu(); - unsigned long *irqstack_end = (unsigned long*)cpu_pda(cpu)->irqstackptr; + unsigned long *irqstack_end = (unsigned long *)cpu_pda(cpu)->irqstackptr; unsigned used = 0; struct thread_info *tinfo; @@ -237,7 +238,7 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs, if (!bp) { if (task == current) { /* Grab bp right from our regs */ - asm("movq %%rbp, %0" : "=r" (bp) :); + asm("movq %%rbp, %0" : "=r" (bp) : ); } else { /* bp is the last reg pushed by switch_to */ bp = *(unsigned long *) task->thread.sp; @@ -339,9 +340,8 @@ static void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, unsigned long *stack, unsigned long bp, char *log_lvl) { - printk("\nCall Trace:\n"); + printk("Call Trace:\n"); dump_trace(task, regs, stack, bp, &print_trace_ops, log_lvl); - printk("\n"); } void show_trace(struct task_struct *task, struct pt_regs *regs, @@ -357,11 +357,15 @@ show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs, unsigned long *stack; int i; const int cpu = smp_processor_id(); - unsigned long *irqstack_end = (unsigned long *) (cpu_pda(cpu)->irqstackptr); - unsigned long *irqstack = (unsigned long *) (cpu_pda(cpu)->irqstackptr - IRQSTACKSIZE); + unsigned long *irqstack_end = + (unsigned long *) (cpu_pda(cpu)->irqstackptr); + unsigned long *irqstack = + (unsigned long *) (cpu_pda(cpu)->irqstackptr - IRQSTACKSIZE); - // debugging aid: "show_stack(NULL, NULL);" prints the - // back trace for this cpu. + /* + * debugging aid: "show_stack(NULL, NULL);" prints the + * back trace for this cpu. + */ if (sp == NULL) { if (task) @@ -386,6 +390,7 @@ show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs, printk(" %016lx", *stack++); touch_nmi_watchdog(); } + printk("\n"); show_trace_log_lvl(task, regs, sp, bp, log_lvl); } @@ -404,7 +409,7 @@ void dump_stack(void) #ifdef CONFIG_FRAME_POINTER if (!bp) - asm("movq %%rbp, %0" : "=r" (bp):); + asm("movq %%rbp, %0" : "=r" (bp) : ); #endif printk("Pid: %d, comm: %.20s %s %s %.*s\n", @@ -414,7 +419,6 @@ void dump_stack(void) init_utsname()->version); show_trace(NULL, NULL, &stack, bp); } - EXPORT_SYMBOL(dump_stack); void show_registers(struct pt_regs *regs) @@ -443,7 +447,6 @@ void show_registers(struct pt_regs *regs) printk("Stack: "); show_stack_log_lvl(NULL, regs, (unsigned long *)sp, regs->bp, ""); - printk("\n"); printk(KERN_EMERG "Code: "); @@ -493,7 +496,7 @@ unsigned __kprobes long oops_begin(void) raw_local_irq_save(flags); cpu = smp_processor_id(); if (!__raw_spin_trylock(&die_lock)) { - if (cpu == die_owner) + if (cpu == die_owner) /* nested oops. should stop eventually */; else __raw_spin_lock(&die_lock); @@ -638,7 +641,7 @@ kernel_trap: } #define DO_ERROR(trapnr, signr, str, name) \ -asmlinkage void do_##name(struct pt_regs * regs, long error_code) \ +asmlinkage void do_##name(struct pt_regs *regs, long error_code) \ { \ if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \ == NOTIFY_STOP) \ @@ -648,7 +651,7 @@ asmlinkage void do_##name(struct pt_regs * regs, long error_code) \ } #define DO_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) \ -asmlinkage void do_##name(struct pt_regs * regs, long error_code) \ +asmlinkage void do_##name(struct pt_regs *regs, long error_code) \ { \ siginfo_t info; \ info.si_signo = signr; \ @@ -683,7 +686,7 @@ asmlinkage void do_stack_segment(struct pt_regs *regs, long error_code) preempt_conditional_cli(regs); } -asmlinkage void do_double_fault(struct pt_regs * regs, long error_code) +asmlinkage void do_double_fault(struct pt_regs *regs, long error_code) { static const char str[] = "double fault"; struct task_struct *tsk = current; @@ -778,9 +781,10 @@ io_check_error(unsigned char reason, struct pt_regs *regs) } static notrace __kprobes void -unknown_nmi_error(unsigned char reason, struct pt_regs * regs) +unknown_nmi_error(unsigned char reason, struct pt_regs *regs) { - if (notify_die(DIE_NMIUNKNOWN, "nmi", regs, reason, 2, SIGINT) == NOTIFY_STOP) + if (notify_die(DIE_NMIUNKNOWN, "nmi", regs, reason, 2, SIGINT) == + NOTIFY_STOP) return; printk(KERN_EMERG "Uhhuh. NMI received for unknown reason %02x.\n", reason); @@ -882,7 +886,7 @@ asmlinkage __kprobes struct pt_regs *sync_regs(struct pt_regs *eregs) else if (user_mode(eregs)) regs = task_pt_regs(current); /* Exception from kernel and interrupts are enabled. Move to - kernel process stack. */ + kernel process stack. */ else if (eregs->flags & X86_EFLAGS_IF) regs = (struct pt_regs *)(eregs->sp -= sizeof(struct pt_regs)); if (eregs != regs) @@ -891,7 +895,7 @@ asmlinkage __kprobes struct pt_regs *sync_regs(struct pt_regs *eregs) } /* runs on IST stack. */ -asmlinkage void __kprobes do_debug(struct pt_regs * regs, +asmlinkage void __kprobes do_debug(struct pt_regs *regs, unsigned long error_code) { struct task_struct *tsk = current; @@ -1035,7 +1039,7 @@ asmlinkage void do_coprocessor_error(struct pt_regs *regs) asmlinkage void bad_intr(void) { - printk("bad interrupt"); + printk("bad interrupt"); } asmlinkage void do_simd_coprocessor_error(struct pt_regs *regs) @@ -1047,7 +1051,7 @@ asmlinkage void do_simd_coprocessor_error(struct pt_regs *regs) conditional_sti(regs); if (!user_mode(regs) && - kernel_math_error(regs, "kernel simd math error", 19)) + kernel_math_error(regs, "kernel simd math error", 19)) return; /* @@ -1092,7 +1096,7 @@ asmlinkage void do_simd_coprocessor_error(struct pt_regs *regs) force_sig_info(SIGFPE, &info, task); } -asmlinkage void do_spurious_interrupt_bug(struct pt_regs * regs) +asmlinkage void do_spurious_interrupt_bug(struct pt_regs *regs) { } @@ -1149,8 +1153,10 @@ void __init trap_init(void) set_intr_gate(0, ÷_error); set_intr_gate_ist(1, &debug, DEBUG_STACK); set_intr_gate_ist(2, &nmi, NMI_STACK); - set_system_gate_ist(3, &int3, DEBUG_STACK); /* int3 can be called from all */ - set_system_gate(4, &overflow); /* int4 can be called from all */ + /* int3 can be called from all */ + set_system_gate_ist(3, &int3, DEBUG_STACK); + /* int4 can be called from all */ + set_system_gate(4, &overflow); set_intr_gate(5, &bounds); set_intr_gate(6, &invalid_op); set_intr_gate(7, &device_not_available); diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c index 8f98e9de1b8..161bb850fc4 100644 --- a/arch/x86/kernel/tsc.c +++ b/arch/x86/kernel/tsc.c @@ -104,7 +104,7 @@ __setup("notsc", notsc_setup); /* * Read TSC and the reference counters. Take care of SMI disturbance */ -static u64 tsc_read_refs(u64 *pm, u64 *hpet) +static u64 tsc_read_refs(u64 *p, int hpet) { u64 t1, t2; int i; @@ -112,9 +112,9 @@ static u64 tsc_read_refs(u64 *pm, u64 *hpet) for (i = 0; i < MAX_RETRIES; i++) { t1 = get_cycles(); if (hpet) - *hpet = hpet_readl(HPET_COUNTER) & 0xFFFFFFFF; + *p = hpet_readl(HPET_COUNTER) & 0xFFFFFFFF; else - *pm = acpi_pm_read_early(); + *p = acpi_pm_read_early(); t2 = get_cycles(); if ((t2 - t1) < SMI_TRESHOLD) return t2; @@ -123,13 +123,59 @@ static u64 tsc_read_refs(u64 *pm, u64 *hpet) } /* + * Calculate the TSC frequency from HPET reference + */ +static unsigned long calc_hpet_ref(u64 deltatsc, u64 hpet1, u64 hpet2) +{ + u64 tmp; + + if (hpet2 < hpet1) + hpet2 += 0x100000000ULL; + hpet2 -= hpet1; + tmp = ((u64)hpet2 * hpet_readl(HPET_PERIOD)); + do_div(tmp, 1000000); + do_div(deltatsc, tmp); + + return (unsigned long) deltatsc; +} + +/* + * Calculate the TSC frequency from PMTimer reference + */ +static unsigned long calc_pmtimer_ref(u64 deltatsc, u64 pm1, u64 pm2) +{ + u64 tmp; + + if (!pm1 && !pm2) + return ULONG_MAX; + + if (pm2 < pm1) + pm2 += (u64)ACPI_PM_OVRRUN; + pm2 -= pm1; + tmp = pm2 * 1000000000LL; + do_div(tmp, PMTMR_TICKS_PER_SEC); + do_div(deltatsc, tmp); + + return (unsigned long) deltatsc; +} + +#define CAL_MS 10 +#define CAL_LATCH (CLOCK_TICK_RATE / (1000 / CAL_MS)) +#define CAL_PIT_LOOPS 1000 + +#define CAL2_MS 50 +#define CAL2_LATCH (CLOCK_TICK_RATE / (1000 / CAL2_MS)) +#define CAL2_PIT_LOOPS 5000 + + +/* * Try to calibrate the TSC against the Programmable * Interrupt Timer and return the frequency of the TSC * in kHz. * * Return ULONG_MAX on failure to calibrate. */ -static unsigned long pit_calibrate_tsc(void) +static unsigned long pit_calibrate_tsc(u32 latch, unsigned long ms, int loopmin) { u64 tsc, t1, t2, delta; unsigned long tscmin, tscmax; @@ -144,8 +190,8 @@ static unsigned long pit_calibrate_tsc(void) * (LSB then MSB) to begin countdown. */ outb(0xb0, 0x43); - outb((CLOCK_TICK_RATE / (1000 / 50)) & 0xff, 0x42); - outb((CLOCK_TICK_RATE / (1000 / 50)) >> 8, 0x42); + outb(latch & 0xff, 0x42); + outb(latch >> 8, 0x42); tsc = t1 = t2 = get_cycles(); @@ -166,31 +212,154 @@ static unsigned long pit_calibrate_tsc(void) /* * Sanity checks: * - * If we were not able to read the PIT more than 5000 + * If we were not able to read the PIT more than loopmin * times, then we have been hit by a massive SMI * * If the maximum is 10 times larger than the minimum, * then we got hit by an SMI as well. */ - if (pitcnt < 5000 || tscmax > 10 * tscmin) + if (pitcnt < loopmin || tscmax > 10 * tscmin) return ULONG_MAX; /* Calculate the PIT value */ delta = t2 - t1; - do_div(delta, 50); + do_div(delta, ms); return delta; } +/* + * This reads the current MSB of the PIT counter, and + * checks if we are running on sufficiently fast and + * non-virtualized hardware. + * + * Our expectations are: + * + * - the PIT is running at roughly 1.19MHz + * + * - each IO is going to take about 1us on real hardware, + * but we allow it to be much faster (by a factor of 10) or + * _slightly_ slower (ie we allow up to a 2us read+counter + * update - anything else implies a unacceptably slow CPU + * or PIT for the fast calibration to work. + * + * - with 256 PIT ticks to read the value, we have 214us to + * see the same MSB (and overhead like doing a single TSC + * read per MSB value etc). + * + * - We're doing 2 reads per loop (LSB, MSB), and we expect + * them each to take about a microsecond on real hardware. + * So we expect a count value of around 100. But we'll be + * generous, and accept anything over 50. + * + * - if the PIT is stuck, and we see *many* more reads, we + * return early (and the next caller of pit_expect_msb() + * then consider it a failure when they don't see the + * next expected value). + * + * These expectations mean that we know that we have seen the + * transition from one expected value to another with a fairly + * high accuracy, and we didn't miss any events. We can thus + * use the TSC value at the transitions to calculate a pretty + * good value for the TSC frequencty. + */ +static inline int pit_expect_msb(unsigned char val) +{ + int count = 0; + + for (count = 0; count < 50000; count++) { + /* Ignore LSB */ + inb(0x42); + if (inb(0x42) != val) + break; + } + return count > 50; +} + +/* + * How many MSB values do we want to see? We aim for a + * 15ms calibration, which assuming a 2us counter read + * error should give us roughly 150 ppm precision for + * the calibration. + */ +#define QUICK_PIT_MS 15 +#define QUICK_PIT_ITERATIONS (QUICK_PIT_MS * PIT_TICK_RATE / 1000 / 256) + +static unsigned long quick_pit_calibrate(void) +{ + /* Set the Gate high, disable speaker */ + outb((inb(0x61) & ~0x02) | 0x01, 0x61); + + /* + * Counter 2, mode 0 (one-shot), binary count + * + * NOTE! Mode 2 decrements by two (and then the + * output is flipped each time, giving the same + * final output frequency as a decrement-by-one), + * so mode 0 is much better when looking at the + * individual counts. + */ + outb(0xb0, 0x43); + + /* Start at 0xffff */ + outb(0xff, 0x42); + outb(0xff, 0x42); + + if (pit_expect_msb(0xff)) { + int i; + u64 t1, t2, delta; + unsigned char expect = 0xfe; + + t1 = get_cycles(); + for (i = 0; i < QUICK_PIT_ITERATIONS; i++, expect--) { + if (!pit_expect_msb(expect)) + goto failed; + } + t2 = get_cycles(); + + /* + * Make sure we can rely on the second TSC timestamp: + */ + if (!pit_expect_msb(expect)) + goto failed; + + /* + * Ok, if we get here, then we've seen the + * MSB of the PIT decrement QUICK_PIT_ITERATIONS + * times, and each MSB had many hits, so we never + * had any sudden jumps. + * + * As a result, we can depend on there not being + * any odd delays anywhere, and the TSC reads are + * reliable. + * + * kHz = ticks / time-in-seconds / 1000; + * kHz = (t2 - t1) / (QPI * 256 / PIT_TICK_RATE) / 1000 + * kHz = ((t2 - t1) * PIT_TICK_RATE) / (QPI * 256 * 1000) + */ + delta = (t2 - t1)*PIT_TICK_RATE; + do_div(delta, QUICK_PIT_ITERATIONS*256*1000); + printk("Fast TSC calibration using PIT\n"); + return delta; + } +failed: + return 0; +} /** * native_calibrate_tsc - calibrate the tsc on boot */ unsigned long native_calibrate_tsc(void) { - u64 tsc1, tsc2, delta, pm1, pm2, hpet1, hpet2; + u64 tsc1, tsc2, delta, ref1, ref2; unsigned long tsc_pit_min = ULONG_MAX, tsc_ref_min = ULONG_MAX; - unsigned long flags; - int hpet = is_hpet_enabled(), i; + unsigned long flags, latch, ms, fast_calibrate; + int hpet = is_hpet_enabled(), i, loopmin; + + local_irq_save(flags); + fast_calibrate = quick_pit_calibrate(); + local_irq_restore(flags); + if (fast_calibrate) + return fast_calibrate; /* * Run 5 calibration loops to get the lowest frequency value @@ -216,7 +385,13 @@ unsigned long native_calibrate_tsc(void) * calibration delay loop as we have to wait for a certain * amount of time anyway. */ - for (i = 0; i < 5; i++) { + + /* Preset PIT loop values */ + latch = CAL_LATCH; + ms = CAL_MS; + loopmin = CAL_PIT_LOOPS; + + for (i = 0; i < 3; i++) { unsigned long tsc_pit_khz; /* @@ -226,16 +401,16 @@ unsigned long native_calibrate_tsc(void) * read the end value. */ local_irq_save(flags); - tsc1 = tsc_read_refs(&pm1, hpet ? &hpet1 : NULL); - tsc_pit_khz = pit_calibrate_tsc(); - tsc2 = tsc_read_refs(&pm2, hpet ? &hpet2 : NULL); + tsc1 = tsc_read_refs(&ref1, hpet); + tsc_pit_khz = pit_calibrate_tsc(latch, ms, loopmin); + tsc2 = tsc_read_refs(&ref2, hpet); local_irq_restore(flags); /* Pick the lowest PIT TSC calibration so far */ tsc_pit_min = min(tsc_pit_min, tsc_pit_khz); /* hpet or pmtimer available ? */ - if (!hpet && !pm1 && !pm2) + if (!hpet && !ref1 && !ref2) continue; /* Check, whether the sampling was disturbed by an SMI */ @@ -243,23 +418,41 @@ unsigned long native_calibrate_tsc(void) continue; tsc2 = (tsc2 - tsc1) * 1000000LL; + if (hpet) + tsc2 = calc_hpet_ref(tsc2, ref1, ref2); + else + tsc2 = calc_pmtimer_ref(tsc2, ref1, ref2); - if (hpet) { - if (hpet2 < hpet1) - hpet2 += 0x100000000ULL; - hpet2 -= hpet1; - tsc1 = ((u64)hpet2 * hpet_readl(HPET_PERIOD)); - do_div(tsc1, 1000000); - } else { - if (pm2 < pm1) - pm2 += (u64)ACPI_PM_OVRRUN; - pm2 -= pm1; - tsc1 = pm2 * 1000000000LL; - do_div(tsc1, PMTMR_TICKS_PER_SEC); + tsc_ref_min = min(tsc_ref_min, (unsigned long) tsc2); + + /* Check the reference deviation */ + delta = ((u64) tsc_pit_min) * 100; + do_div(delta, tsc_ref_min); + + /* + * If both calibration results are inside a 10% window + * then we can be sure, that the calibration + * succeeded. We break out of the loop right away. We + * use the reference value, as it is more precise. + */ + if (delta >= 90 && delta <= 110) { + printk(KERN_INFO + "TSC: PIT calibration matches %s. %d loops\n", + hpet ? "HPET" : "PMTIMER", i + 1); + return tsc_ref_min; } - do_div(tsc2, tsc1); - tsc_ref_min = min(tsc_ref_min, (unsigned long) tsc2); + /* + * Check whether PIT failed more than once. This + * happens in virtualized environments. We need to + * give the virtual PC a slightly longer timeframe for + * the HPET/PMTIMER to make the result precise. + */ + if (i == 1 && tsc_pit_min == ULONG_MAX) { + latch = CAL2_LATCH; + ms = CAL2_MS; + loopmin = CAL2_PIT_LOOPS; + } } /* @@ -270,7 +463,7 @@ unsigned long native_calibrate_tsc(void) printk(KERN_WARNING "TSC: Unable to calibrate against PIT\n"); /* We don't have an alternative source, disable TSC */ - if (!hpet && !pm1 && !pm2) { + if (!hpet && !ref1 && !ref2) { printk("TSC: No reference (HPET/PMTIMER) available\n"); return 0; } @@ -278,7 +471,7 @@ unsigned long native_calibrate_tsc(void) /* The alternative source failed as well, disable TSC */ if (tsc_ref_min == ULONG_MAX) { printk(KERN_WARNING "TSC: HPET/PMTIMER calibration " - "failed due to SMI disturbance.\n"); + "failed.\n"); return 0; } @@ -290,44 +483,25 @@ unsigned long native_calibrate_tsc(void) } /* We don't have an alternative source, use the PIT calibration value */ - if (!hpet && !pm1 && !pm2) { + if (!hpet && !ref1 && !ref2) { printk(KERN_INFO "TSC: Using PIT calibration value\n"); return tsc_pit_min; } /* The alternative source failed, use the PIT calibration value */ if (tsc_ref_min == ULONG_MAX) { - printk(KERN_WARNING "TSC: HPET/PMTIMER calibration failed due " - "to SMI disturbance. Using PIT calibration\n"); + printk(KERN_WARNING "TSC: HPET/PMTIMER calibration failed. " + "Using PIT calibration\n"); return tsc_pit_min; } - /* Check the reference deviation */ - delta = ((u64) tsc_pit_min) * 100; - do_div(delta, tsc_ref_min); - - /* - * If both calibration results are inside a 5% window, the we - * use the lower frequency of those as it is probably the - * closest estimate. - */ - if (delta >= 95 && delta <= 105) { - printk(KERN_INFO "TSC: PIT calibration confirmed by %s.\n", - hpet ? "HPET" : "PMTIMER"); - printk(KERN_INFO "TSC: using %s calibration value\n", - tsc_pit_min <= tsc_ref_min ? "PIT" : - hpet ? "HPET" : "PMTIMER"); - return tsc_pit_min <= tsc_ref_min ? tsc_pit_min : tsc_ref_min; - } - - printk(KERN_WARNING "TSC: PIT calibration deviates from %s: %lu %lu.\n", - hpet ? "HPET" : "PMTIMER", tsc_pit_min, tsc_ref_min); - /* * The calibration values differ too much. In doubt, we use * the PIT value as we know that there are PMTIMERs around - * running at double speed. + * running at double speed. At least we let the user know: */ + printk(KERN_WARNING "TSC: PIT calibration deviates from %s: %lu %lu.\n", + hpet ? "HPET" : "PMTIMER", tsc_pit_min, tsc_ref_min); printk(KERN_INFO "TSC: Using PIT calibration value\n"); return tsc_pit_min; } diff --git a/arch/x86/kernel/visws_quirks.c b/arch/x86/kernel/visws_quirks.c index 594ef47f0a6..61a97e616f7 100644 --- a/arch/x86/kernel/visws_quirks.c +++ b/arch/x86/kernel/visws_quirks.c @@ -25,45 +25,31 @@ #include <asm/visws/cobalt.h> #include <asm/visws/piix4.h> #include <asm/arch_hooks.h> +#include <asm/io_apic.h> #include <asm/fixmap.h> #include <asm/reboot.h> #include <asm/setup.h> #include <asm/e820.h> -#include <asm/smp.h> #include <asm/io.h> #include <mach_ipi.h> #include "mach_apic.h" -#include <linux/init.h> -#include <linux/smp.h> - #include <linux/kernel_stat.h> -#include <linux/interrupt.h> -#include <linux/init.h> -#include <asm/io.h> -#include <asm/apic.h> #include <asm/i8259.h> #include <asm/irq_vectors.h> -#include <asm/visws/cobalt.h> #include <asm/visws/lithium.h> -#include <asm/visws/piix4.h> #include <linux/sched.h> #include <linux/kernel.h> -#include <linux/init.h> #include <linux/pci.h> #include <linux/pci_ids.h> extern int no_broadcast; -#include <asm/io.h> #include <asm/apic.h> -#include <asm/arch_hooks.h> -#include <asm/visws/cobalt.h> -#include <asm/visws/lithium.h> char visws_board_type = -1; char visws_board_rev = -1; diff --git a/arch/x86/kernel/vm86_32.c b/arch/x86/kernel/vm86_32.c index 38f566fa27d..4eeb5cf9720 100644 --- a/arch/x86/kernel/vm86_32.c +++ b/arch/x86/kernel/vm86_32.c @@ -46,6 +46,7 @@ #include <asm/io.h> #include <asm/tlbflush.h> #include <asm/irq.h> +#include <asm/syscalls.h> /* * Known problems: diff --git a/arch/x86/kernel/vmi_32.c b/arch/x86/kernel/vmi_32.c index 6ca515d6db5..8c9ad02af5a 100644 --- a/arch/x86/kernel/vmi_32.c +++ b/arch/x86/kernel/vmi_32.c @@ -235,7 +235,7 @@ static void vmi_write_ldt_entry(struct desc_struct *dt, int entry, const void *desc) { u32 *ldt_entry = (u32 *)desc; - vmi_ops.write_idt_entry(dt, entry, ldt_entry[0], ldt_entry[1]); + vmi_ops.write_ldt_entry(dt, entry, ldt_entry[0], ldt_entry[1]); } static void vmi_load_sp0(struct tss_struct *tss, @@ -393,13 +393,13 @@ static void *vmi_kmap_atomic_pte(struct page *page, enum km_type type) } #endif -static void vmi_allocate_pte(struct mm_struct *mm, u32 pfn) +static void vmi_allocate_pte(struct mm_struct *mm, unsigned long pfn) { vmi_set_page_type(pfn, VMI_PAGE_L1); vmi_ops.allocate_page(pfn, VMI_PAGE_L1, 0, 0, 0); } -static void vmi_allocate_pmd(struct mm_struct *mm, u32 pfn) +static void vmi_allocate_pmd(struct mm_struct *mm, unsigned long pfn) { /* * This call comes in very early, before mem_map is setup. @@ -410,20 +410,20 @@ static void vmi_allocate_pmd(struct mm_struct *mm, u32 pfn) vmi_ops.allocate_page(pfn, VMI_PAGE_L2, 0, 0, 0); } -static void vmi_allocate_pmd_clone(u32 pfn, u32 clonepfn, u32 start, u32 count) +static void vmi_allocate_pmd_clone(unsigned long pfn, unsigned long clonepfn, unsigned long start, unsigned long count) { vmi_set_page_type(pfn, VMI_PAGE_L2 | VMI_PAGE_CLONE); vmi_check_page_type(clonepfn, VMI_PAGE_L2); vmi_ops.allocate_page(pfn, VMI_PAGE_L2 | VMI_PAGE_CLONE, clonepfn, start, count); } -static void vmi_release_pte(u32 pfn) +static void vmi_release_pte(unsigned long pfn) { vmi_ops.release_page(pfn, VMI_PAGE_L1); vmi_set_page_type(pfn, VMI_PAGE_NORMAL); } -static void vmi_release_pmd(u32 pfn) +static void vmi_release_pmd(unsigned long pfn) { vmi_ops.release_page(pfn, VMI_PAGE_L2); vmi_set_page_type(pfn, VMI_PAGE_NORMAL); diff --git a/arch/x86/kernel/vsmp_64.c b/arch/x86/kernel/vsmp_64.c index 0c029e8959c..7766d36983f 100644 --- a/arch/x86/kernel/vsmp_64.c +++ b/arch/x86/kernel/vsmp_64.c @@ -61,7 +61,7 @@ static void vsmp_irq_enable(void) native_restore_fl((flags | X86_EFLAGS_IF) & (~X86_EFLAGS_AC)); } -static unsigned __init vsmp_patch(u8 type, u16 clobbers, void *ibuf, +static unsigned __init_or_module vsmp_patch(u8 type, u16 clobbers, void *ibuf, unsigned long addr, unsigned len) { switch (type) { diff --git a/arch/x86/lib/msr-on-cpu.c b/arch/x86/lib/msr-on-cpu.c index 01b868ba82f..321cf720dbb 100644 --- a/arch/x86/lib/msr-on-cpu.c +++ b/arch/x86/lib/msr-on-cpu.c @@ -16,37 +16,46 @@ static void __rdmsr_on_cpu(void *info) rdmsr(rv->msr_no, rv->l, rv->h); } -static void __rdmsr_safe_on_cpu(void *info) +static void __wrmsr_on_cpu(void *info) { struct msr_info *rv = info; - rv->err = rdmsr_safe(rv->msr_no, &rv->l, &rv->h); + wrmsr(rv->msr_no, rv->l, rv->h); } -static int _rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h, int safe) +int rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h) { - int err = 0; + int err; struct msr_info rv; rv.msr_no = msr_no; - if (safe) { - err = smp_call_function_single(cpu, __rdmsr_safe_on_cpu, - &rv, 1); - err = err ? err : rv.err; - } else { - err = smp_call_function_single(cpu, __rdmsr_on_cpu, &rv, 1); - } + err = smp_call_function_single(cpu, __rdmsr_on_cpu, &rv, 1); *l = rv.l; *h = rv.h; return err; } -static void __wrmsr_on_cpu(void *info) +int wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h) +{ + int err; + struct msr_info rv; + + rv.msr_no = msr_no; + rv.l = l; + rv.h = h; + err = smp_call_function_single(cpu, __wrmsr_on_cpu, &rv, 1); + + return err; +} + +/* These "safe" variants are slower and should be used when the target MSR + may not actually exist. */ +static void __rdmsr_safe_on_cpu(void *info) { struct msr_info *rv = info; - wrmsr(rv->msr_no, rv->l, rv->h); + rv->err = rdmsr_safe(rv->msr_no, &rv->l, &rv->h); } static void __wrmsr_safe_on_cpu(void *info) @@ -56,45 +65,30 @@ static void __wrmsr_safe_on_cpu(void *info) rv->err = wrmsr_safe(rv->msr_no, rv->l, rv->h); } -static int _wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h, int safe) +int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h) { - int err = 0; + int err; struct msr_info rv; rv.msr_no = msr_no; - rv.l = l; - rv.h = h; - if (safe) { - err = smp_call_function_single(cpu, __wrmsr_safe_on_cpu, - &rv, 1); - err = err ? err : rv.err; - } else { - err = smp_call_function_single(cpu, __wrmsr_on_cpu, &rv, 1); - } - - return err; -} + err = smp_call_function_single(cpu, __rdmsr_safe_on_cpu, &rv, 1); + *l = rv.l; + *h = rv.h; -int wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h) -{ - return _wrmsr_on_cpu(cpu, msr_no, l, h, 0); + return err ? err : rv.err; } -int rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h) -{ - return _rdmsr_on_cpu(cpu, msr_no, l, h, 0); -} - -/* These "safe" variants are slower and should be used when the target MSR - may not actually exist. */ int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h) { - return _wrmsr_on_cpu(cpu, msr_no, l, h, 1); -} + int err; + struct msr_info rv; -int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h) -{ - return _rdmsr_on_cpu(cpu, msr_no, l, h, 1); + rv.msr_no = msr_no; + rv.l = l; + rv.h = h; + err = smp_call_function_single(cpu, __wrmsr_safe_on_cpu, &rv, 1); + + return err ? err : rv.err; } EXPORT_SYMBOL(rdmsr_on_cpu); diff --git a/arch/x86/lib/string_32.c b/arch/x86/lib/string_32.c index 94972e7c094..82004d2bf05 100644 --- a/arch/x86/lib/string_32.c +++ b/arch/x86/lib/string_32.c @@ -22,7 +22,7 @@ char *strcpy(char *dest, const char *src) "testb %%al,%%al\n\t" "jne 1b" : "=&S" (d0), "=&D" (d1), "=&a" (d2) - :"0" (src), "1" (dest) : "memory"); + : "0" (src), "1" (dest) : "memory"); return dest; } EXPORT_SYMBOL(strcpy); @@ -42,7 +42,7 @@ char *strncpy(char *dest, const char *src, size_t count) "stosb\n" "2:" : "=&S" (d0), "=&D" (d1), "=&c" (d2), "=&a" (d3) - :"0" (src), "1" (dest), "2" (count) : "memory"); + : "0" (src), "1" (dest), "2" (count) : "memory"); return dest; } EXPORT_SYMBOL(strncpy); @@ -60,7 +60,7 @@ char *strcat(char *dest, const char *src) "testb %%al,%%al\n\t" "jne 1b" : "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3) - : "0" (src), "1" (dest), "2" (0), "3" (0xffffffffu): "memory"); + : "0" (src), "1" (dest), "2" (0), "3" (0xffffffffu) : "memory"); return dest; } EXPORT_SYMBOL(strcat); @@ -105,9 +105,9 @@ int strcmp(const char *cs, const char *ct) "2:\tsbbl %%eax,%%eax\n\t" "orb $1,%%al\n" "3:" - :"=a" (res), "=&S" (d0), "=&D" (d1) - :"1" (cs), "2" (ct) - :"memory"); + : "=a" (res), "=&S" (d0), "=&D" (d1) + : "1" (cs), "2" (ct) + : "memory"); return res; } EXPORT_SYMBOL(strcmp); @@ -130,9 +130,9 @@ int strncmp(const char *cs, const char *ct, size_t count) "3:\tsbbl %%eax,%%eax\n\t" "orb $1,%%al\n" "4:" - :"=a" (res), "=&S" (d0), "=&D" (d1), "=&c" (d2) - :"1" (cs), "2" (ct), "3" (count) - :"memory"); + : "=a" (res), "=&S" (d0), "=&D" (d1), "=&c" (d2) + : "1" (cs), "2" (ct), "3" (count) + : "memory"); return res; } EXPORT_SYMBOL(strncmp); @@ -152,9 +152,9 @@ char *strchr(const char *s, int c) "movl $1,%1\n" "2:\tmovl %1,%0\n\t" "decl %0" - :"=a" (res), "=&S" (d0) - :"1" (s), "0" (c) - :"memory"); + : "=a" (res), "=&S" (d0) + : "1" (s), "0" (c) + : "memory"); return res; } EXPORT_SYMBOL(strchr); @@ -169,9 +169,9 @@ size_t strlen(const char *s) "scasb\n\t" "notl %0\n\t" "decl %0" - :"=c" (res), "=&D" (d0) - :"1" (s), "a" (0), "0" (0xffffffffu) - :"memory"); + : "=c" (res), "=&D" (d0) + : "1" (s), "a" (0), "0" (0xffffffffu) + : "memory"); return res; } EXPORT_SYMBOL(strlen); @@ -189,9 +189,9 @@ void *memchr(const void *cs, int c, size_t count) "je 1f\n\t" "movl $1,%0\n" "1:\tdecl %0" - :"=D" (res), "=&c" (d0) - :"a" (c), "0" (cs), "1" (count) - :"memory"); + : "=D" (res), "=&c" (d0) + : "a" (c), "0" (cs), "1" (count) + : "memory"); return res; } EXPORT_SYMBOL(memchr); @@ -228,9 +228,9 @@ size_t strnlen(const char *s, size_t count) "cmpl $-1,%1\n\t" "jne 1b\n" "3:\tsubl %2,%0" - :"=a" (res), "=&d" (d0) - :"c" (s), "1" (count) - :"memory"); + : "=a" (res), "=&d" (d0) + : "c" (s), "1" (count) + : "memory"); return res; } EXPORT_SYMBOL(strnlen); diff --git a/arch/x86/lib/strstr_32.c b/arch/x86/lib/strstr_32.c index 42e8a50303f..8e2d55f754b 100644 --- a/arch/x86/lib/strstr_32.c +++ b/arch/x86/lib/strstr_32.c @@ -23,9 +23,9 @@ __asm__ __volatile__( "jne 1b\n\t" "xorl %%eax,%%eax\n\t" "2:" - :"=a" (__res), "=&c" (d0), "=&S" (d1) - :"0" (0), "1" (0xffffffff), "2" (cs), "g" (ct) - :"dx", "di"); + : "=a" (__res), "=&c" (d0), "=&S" (d1) + : "0" (0), "1" (0xffffffff), "2" (cs), "g" (ct) + : "dx", "di"); return __res; } diff --git a/arch/x86/mach-default/setup.c b/arch/x86/mach-default/setup.c index 3d317836be9..3f2cf11f201 100644 --- a/arch/x86/mach-default/setup.c +++ b/arch/x86/mach-default/setup.c @@ -10,13 +10,15 @@ #include <asm/e820.h> #include <asm/setup.h> +#include <mach_ipi.h> + #ifdef CONFIG_HOTPLUG_CPU #define DEFAULT_SEND_IPI (1) #else #define DEFAULT_SEND_IPI (0) #endif -int no_broadcast=DEFAULT_SEND_IPI; +int no_broadcast = DEFAULT_SEND_IPI; /** * pre_intr_init_hook - initialisation prior to setting up interrupt vectors diff --git a/arch/x86/mm/discontig_32.c b/arch/x86/mm/discontig_32.c index 62fa440678d..847c164725f 100644 --- a/arch/x86/mm/discontig_32.c +++ b/arch/x86/mm/discontig_32.c @@ -328,7 +328,7 @@ void __init initmem_init(unsigned long start_pfn, get_memcfg_numa(); - kva_pages = round_up(calculate_numa_remap_pages(), PTRS_PER_PTE); + kva_pages = roundup(calculate_numa_remap_pages(), PTRS_PER_PTE); kva_target_pfn = round_down(max_low_pfn - kva_pages, PTRS_PER_PTE); do { diff --git a/arch/x86/mm/dump_pagetables.c b/arch/x86/mm/dump_pagetables.c index a20d1fa64b4..e7277cbcfb4 100644 --- a/arch/x86/mm/dump_pagetables.c +++ b/arch/x86/mm/dump_pagetables.c @@ -148,8 +148,8 @@ static void note_page(struct seq_file *m, struct pg_state *st, * we have now. "break" is either changing perms, levels or * address space marker. */ - prot = pgprot_val(new_prot) & ~(PTE_PFN_MASK); - cur = pgprot_val(st->current_prot) & ~(PTE_PFN_MASK); + prot = pgprot_val(new_prot) & PTE_FLAGS_MASK; + cur = pgprot_val(st->current_prot) & PTE_FLAGS_MASK; if (!st->level) { /* First entry */ diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index 455f3fe67b4..8f92cac4e6d 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c @@ -35,6 +35,7 @@ #include <asm/tlbflush.h> #include <asm/proto.h> #include <asm-generic/sections.h> +#include <asm/traps.h> /* * Page fault error code bits @@ -357,8 +358,6 @@ static int is_errata100(struct pt_regs *regs, unsigned long address) return 0; } -void do_invalid_op(struct pt_regs *, unsigned long); - static int is_f00f_bug(struct pt_regs *regs, unsigned long address) { #ifdef CONFIG_X86_F00F_BUG diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c index 60ec1d08ff2..6b9a9358b33 100644 --- a/arch/x86/mm/init_32.c +++ b/arch/x86/mm/init_32.c @@ -47,6 +47,7 @@ #include <asm/paravirt.h> #include <asm/setup.h> #include <asm/cacheflush.h> +#include <asm/smp.h> unsigned int __VMALLOC_RESERVE = 128 << 20; diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index d3746efb060..770536ebf7e 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c @@ -225,7 +225,7 @@ void __init init_extra_mapping_uc(unsigned long phys, unsigned long size) void __init cleanup_highmap(void) { unsigned long vaddr = __START_KERNEL_map; - unsigned long end = round_up((unsigned long)_end, PMD_SIZE) - 1; + unsigned long end = roundup((unsigned long)_end, PMD_SIZE) - 1; pmd_t *pmd = level2_kernel_pgt; pmd_t *last_pmd = pmd + PTRS_PER_PMD; @@ -451,14 +451,14 @@ static void __init find_early_table_space(unsigned long end) unsigned long puds, pmds, ptes, tables, start; puds = (end + PUD_SIZE - 1) >> PUD_SHIFT; - tables = round_up(puds * sizeof(pud_t), PAGE_SIZE); + tables = roundup(puds * sizeof(pud_t), PAGE_SIZE); if (direct_gbpages) { unsigned long extra; extra = end - ((end>>PUD_SHIFT) << PUD_SHIFT); pmds = (extra + PMD_SIZE - 1) >> PMD_SHIFT; } else pmds = (end + PMD_SIZE - 1) >> PMD_SHIFT; - tables += round_up(pmds * sizeof(pmd_t), PAGE_SIZE); + tables += roundup(pmds * sizeof(pmd_t), PAGE_SIZE); if (cpu_has_pse) { unsigned long extra; @@ -466,7 +466,7 @@ static void __init find_early_table_space(unsigned long end) ptes = (extra + PAGE_SIZE - 1) >> PAGE_SHIFT; } else ptes = (end + PAGE_SIZE - 1) >> PAGE_SHIFT; - tables += round_up(ptes * sizeof(pte_t), PAGE_SIZE); + tables += roundup(ptes * sizeof(pte_t), PAGE_SIZE); /* * RED-PEN putting page tables only on node 0 could diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c index d4b6e6a29ae..cac6da54203 100644 --- a/arch/x86/mm/ioremap.c +++ b/arch/x86/mm/ioremap.c @@ -421,7 +421,7 @@ void unxlate_dev_mem_ptr(unsigned long phys, void *addr) return; } -int __initdata early_ioremap_debug; +static int __initdata early_ioremap_debug; static int __init early_ioremap_debug_setup(char *str) { @@ -547,7 +547,7 @@ static inline void __init early_clear_fixmap(enum fixed_addresses idx) } -int __initdata early_ioremap_nested; +static int __initdata early_ioremap_nested; static int __init check_early_ioremap_leak(void) { diff --git a/arch/x86/mm/numa_64.c b/arch/x86/mm/numa_64.c index a4dd793d600..cebcbf152d4 100644 --- a/arch/x86/mm/numa_64.c +++ b/arch/x86/mm/numa_64.c @@ -79,7 +79,7 @@ static int __init allocate_cachealigned_memnodemap(void) return 0; addr = 0x8000; - nodemap_size = round_up(sizeof(s16) * memnodemapsize, L1_CACHE_BYTES); + nodemap_size = roundup(sizeof(s16) * memnodemapsize, L1_CACHE_BYTES); nodemap_addr = find_e820_area(addr, max_pfn<<PAGE_SHIFT, nodemap_size, L1_CACHE_BYTES); if (nodemap_addr == -1UL) { @@ -176,10 +176,10 @@ void __init setup_node_bootmem(int nodeid, unsigned long start, unsigned long start_pfn, last_pfn, bootmap_pages, bootmap_size; unsigned long bootmap_start, nodedata_phys; void *bootmap; - const int pgdat_size = round_up(sizeof(pg_data_t), PAGE_SIZE); + const int pgdat_size = roundup(sizeof(pg_data_t), PAGE_SIZE); int nid; - start = round_up(start, ZONE_ALIGN); + start = roundup(start, ZONE_ALIGN); printk(KERN_INFO "Bootmem setup node %d %016lx-%016lx\n", nodeid, start, end); @@ -210,9 +210,9 @@ void __init setup_node_bootmem(int nodeid, unsigned long start, bootmap_pages = bootmem_bootmap_pages(last_pfn - start_pfn); nid = phys_to_nid(nodedata_phys); if (nid == nodeid) - bootmap_start = round_up(nodedata_phys + pgdat_size, PAGE_SIZE); + bootmap_start = roundup(nodedata_phys + pgdat_size, PAGE_SIZE); else - bootmap_start = round_up(start, PAGE_SIZE); + bootmap_start = roundup(start, PAGE_SIZE); /* * SMP_CACHE_BYTES could be enough, but init_bootmem_node like * to use that to align to PAGE_SIZE diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index 43e2f8483e4..898fad617ab 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c @@ -84,7 +84,7 @@ static inline unsigned long highmap_start_pfn(void) static inline unsigned long highmap_end_pfn(void) { - return __pa(round_up((unsigned long)_end, PMD_SIZE)) >> PAGE_SHIFT; + return __pa(roundup((unsigned long)_end, PMD_SIZE)) >> PAGE_SHIFT; } #endif @@ -906,11 +906,13 @@ int set_memory_ro(unsigned long addr, int numpages) { return change_page_attr_clear(addr, numpages, __pgprot(_PAGE_RW)); } +EXPORT_SYMBOL_GPL(set_memory_ro); int set_memory_rw(unsigned long addr, int numpages) { return change_page_attr_set(addr, numpages, __pgprot(_PAGE_RW)); } +EXPORT_SYMBOL_GPL(set_memory_rw); int set_memory_np(unsigned long addr, int numpages) { diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c index d50302774fe..86f2ffc43c3 100644 --- a/arch/x86/mm/pgtable.c +++ b/arch/x86/mm/pgtable.c @@ -63,10 +63,8 @@ static inline void pgd_list_del(pgd_t *pgd) #define UNSHARED_PTRS_PER_PGD \ (SHARED_KERNEL_PMD ? KERNEL_PGD_BOUNDARY : PTRS_PER_PGD) -static void pgd_ctor(void *p) +static void pgd_ctor(pgd_t *pgd) { - pgd_t *pgd = p; - /* If the pgd points to a shared pagetable level (either the ptes in non-PAE, or shared PMD in PAE), then just copy the references from swapper_pg_dir. */ @@ -87,7 +85,7 @@ static void pgd_ctor(void *p) pgd_list_add(pgd); } -static void pgd_dtor(void *pgd) +static void pgd_dtor(pgd_t *pgd) { unsigned long flags; /* can be called from interrupt context */ diff --git a/arch/x86/mm/pgtable_32.c b/arch/x86/mm/pgtable_32.c index cab0abbd1eb..0951db9ee51 100644 --- a/arch/x86/mm/pgtable_32.c +++ b/arch/x86/mm/pgtable_32.c @@ -123,7 +123,8 @@ static int __init parse_vmalloc(char *arg) if (!arg) return -EINVAL; - __VMALLOC_RESERVE = memparse(arg, &arg); + /* Add VMALLOC_OFFSET to the parsed value due to vm area guard hole*/ + __VMALLOC_RESERVE = memparse(arg, &arg) + VMALLOC_OFFSET; return 0; } early_param("vmalloc", parse_vmalloc); diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c index 0227694f7da..8a5f1614a3d 100644 --- a/arch/x86/oprofile/nmi_int.c +++ b/arch/x86/oprofile/nmi_int.c @@ -295,10 +295,12 @@ static void nmi_cpu_shutdown(void *dummy) static void nmi_shutdown(void) { - struct op_msrs *msrs = &get_cpu_var(cpu_msrs); + struct op_msrs *msrs; + nmi_enabled = 0; on_each_cpu(nmi_cpu_shutdown, NULL, 1); unregister_die_notifier(&profile_exceptions_nb); + msrs = &get_cpu_var(cpu_msrs); model->shutdown(msrs); free_msrs(); put_cpu_var(cpu_msrs); diff --git a/arch/x86/oprofile/op_model_p4.c b/arch/x86/oprofile/op_model_p4.c index 56b4757a1f4..43ac5af338d 100644 --- a/arch/x86/oprofile/op_model_p4.c +++ b/arch/x86/oprofile/op_model_p4.c @@ -10,11 +10,12 @@ #include <linux/oprofile.h> #include <linux/smp.h> +#include <linux/ptrace.h> +#include <linux/nmi.h> #include <asm/msr.h> -#include <asm/ptrace.h> #include <asm/fixmap.h> #include <asm/apic.h> -#include <asm/nmi.h> + #include "op_x86_model.h" #include "op_counter.h" @@ -40,7 +41,7 @@ static unsigned int num_controls = NUM_CONTROLS_NON_HT; static inline void setup_num_counters(void) { #ifdef CONFIG_SMP - if (smp_num_siblings == 2){ + if (smp_num_siblings == 2) { num_counters = NUM_COUNTERS_HT2; num_controls = NUM_CONTROLS_HT2; } @@ -86,7 +87,7 @@ struct p4_event_binding { #define CTR_FLAME_2 (1 << 6) #define CTR_IQ_5 (1 << 7) -static struct p4_counter_binding p4_counters [NUM_COUNTERS_NON_HT] = { +static struct p4_counter_binding p4_counters[NUM_COUNTERS_NON_HT] = { { CTR_BPU_0, MSR_P4_BPU_PERFCTR0, MSR_P4_BPU_CCCR0 }, { CTR_MS_0, MSR_P4_MS_PERFCTR0, MSR_P4_MS_CCCR0 }, { CTR_FLAME_0, MSR_P4_FLAME_PERFCTR0, MSR_P4_FLAME_CCCR0 }, @@ -97,32 +98,32 @@ static struct p4_counter_binding p4_counters [NUM_COUNTERS_NON_HT] = { { CTR_IQ_5, MSR_P4_IQ_PERFCTR5, MSR_P4_IQ_CCCR5 } }; -#define NUM_UNUSED_CCCRS NUM_CCCRS_NON_HT - NUM_COUNTERS_NON_HT +#define NUM_UNUSED_CCCRS (NUM_CCCRS_NON_HT - NUM_COUNTERS_NON_HT) /* p4 event codes in libop/op_event.h are indices into this table. */ static struct p4_event_binding p4_events[NUM_EVENTS] = { - + { /* BRANCH_RETIRED */ - 0x05, 0x06, + 0x05, 0x06, { {CTR_IQ_4, MSR_P4_CRU_ESCR2}, {CTR_IQ_5, MSR_P4_CRU_ESCR3} } }, - + { /* MISPRED_BRANCH_RETIRED */ - 0x04, 0x03, + 0x04, 0x03, { { CTR_IQ_4, MSR_P4_CRU_ESCR0}, { CTR_IQ_5, MSR_P4_CRU_ESCR1} } }, - + { /* TC_DELIVER_MODE */ 0x01, 0x01, - { { CTR_MS_0, MSR_P4_TC_ESCR0}, + { { CTR_MS_0, MSR_P4_TC_ESCR0}, { CTR_MS_2, MSR_P4_TC_ESCR1} } }, - + { /* BPU_FETCH_REQUEST */ - 0x00, 0x03, + 0x00, 0x03, { { CTR_BPU_0, MSR_P4_BPU_ESCR0}, { CTR_BPU_2, MSR_P4_BPU_ESCR1} } }, @@ -146,7 +147,7 @@ static struct p4_event_binding p4_events[NUM_EVENTS] = { }, { /* LOAD_PORT_REPLAY */ - 0x02, 0x04, + 0x02, 0x04, { { CTR_FLAME_0, MSR_P4_SAAT_ESCR0}, { CTR_FLAME_2, MSR_P4_SAAT_ESCR1} } }, @@ -170,43 +171,43 @@ static struct p4_event_binding p4_events[NUM_EVENTS] = { }, { /* BSQ_CACHE_REFERENCE */ - 0x07, 0x0c, + 0x07, 0x0c, { { CTR_BPU_0, MSR_P4_BSU_ESCR0}, { CTR_BPU_2, MSR_P4_BSU_ESCR1} } }, { /* IOQ_ALLOCATION */ - 0x06, 0x03, + 0x06, 0x03, { { CTR_BPU_0, MSR_P4_FSB_ESCR0}, { 0, 0 } } }, { /* IOQ_ACTIVE_ENTRIES */ - 0x06, 0x1a, + 0x06, 0x1a, { { CTR_BPU_2, MSR_P4_FSB_ESCR1}, { 0, 0 } } }, { /* FSB_DATA_ACTIVITY */ - 0x06, 0x17, + 0x06, 0x17, { { CTR_BPU_0, MSR_P4_FSB_ESCR0}, { CTR_BPU_2, MSR_P4_FSB_ESCR1} } }, { /* BSQ_ALLOCATION */ - 0x07, 0x05, + 0x07, 0x05, { { CTR_BPU_0, MSR_P4_BSU_ESCR0}, { 0, 0 } } }, { /* BSQ_ACTIVE_ENTRIES */ 0x07, 0x06, - { { CTR_BPU_2, MSR_P4_BSU_ESCR1 /* guess */}, + { { CTR_BPU_2, MSR_P4_BSU_ESCR1 /* guess */}, { 0, 0 } } }, { /* X87_ASSIST */ - 0x05, 0x03, + 0x05, 0x03, { { CTR_IQ_4, MSR_P4_CRU_ESCR2}, { CTR_IQ_5, MSR_P4_CRU_ESCR3} } }, @@ -216,21 +217,21 @@ static struct p4_event_binding p4_events[NUM_EVENTS] = { { { CTR_FLAME_0, MSR_P4_FIRM_ESCR0}, { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} } }, - + { /* PACKED_SP_UOP */ - 0x01, 0x08, + 0x01, 0x08, { { CTR_FLAME_0, MSR_P4_FIRM_ESCR0}, { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} } }, - + { /* PACKED_DP_UOP */ - 0x01, 0x0c, + 0x01, 0x0c, { { CTR_FLAME_0, MSR_P4_FIRM_ESCR0}, { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} } }, { /* SCALAR_SP_UOP */ - 0x01, 0x0a, + 0x01, 0x0a, { { CTR_FLAME_0, MSR_P4_FIRM_ESCR0}, { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} } }, @@ -242,31 +243,31 @@ static struct p4_event_binding p4_events[NUM_EVENTS] = { }, { /* 64BIT_MMX_UOP */ - 0x01, 0x02, + 0x01, 0x02, { { CTR_FLAME_0, MSR_P4_FIRM_ESCR0}, { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} } }, - + { /* 128BIT_MMX_UOP */ - 0x01, 0x1a, + 0x01, 0x1a, { { CTR_FLAME_0, MSR_P4_FIRM_ESCR0}, { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} } }, { /* X87_FP_UOP */ - 0x01, 0x04, + 0x01, 0x04, { { CTR_FLAME_0, MSR_P4_FIRM_ESCR0}, { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} } }, - + { /* X87_SIMD_MOVES_UOP */ - 0x01, 0x2e, + 0x01, 0x2e, { { CTR_FLAME_0, MSR_P4_FIRM_ESCR0}, { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} } }, - + { /* MACHINE_CLEAR */ - 0x05, 0x02, + 0x05, 0x02, { { CTR_IQ_4, MSR_P4_CRU_ESCR2}, { CTR_IQ_5, MSR_P4_CRU_ESCR3} } }, @@ -276,9 +277,9 @@ static struct p4_event_binding p4_events[NUM_EVENTS] = { { { CTR_BPU_0, MSR_P4_FSB_ESCR0}, { CTR_BPU_2, MSR_P4_FSB_ESCR1} } }, - + { /* TC_MS_XFER */ - 0x00, 0x05, + 0x00, 0x05, { { CTR_MS_0, MSR_P4_MS_ESCR0}, { CTR_MS_2, MSR_P4_MS_ESCR1} } }, @@ -308,7 +309,7 @@ static struct p4_event_binding p4_events[NUM_EVENTS] = { }, { /* INSTR_RETIRED */ - 0x04, 0x02, + 0x04, 0x02, { { CTR_IQ_4, MSR_P4_CRU_ESCR0}, { CTR_IQ_5, MSR_P4_CRU_ESCR1} } }, @@ -319,14 +320,14 @@ static struct p4_event_binding p4_events[NUM_EVENTS] = { { CTR_IQ_5, MSR_P4_CRU_ESCR1} } }, - { /* UOP_TYPE */ - 0x02, 0x02, + { /* UOP_TYPE */ + 0x02, 0x02, { { CTR_IQ_4, MSR_P4_RAT_ESCR0}, { CTR_IQ_5, MSR_P4_RAT_ESCR1} } }, { /* RETIRED_MISPRED_BRANCH_TYPE */ - 0x02, 0x05, + 0x02, 0x05, { { CTR_MS_0, MSR_P4_TBPU_ESCR0}, { CTR_MS_2, MSR_P4_TBPU_ESCR1} } }, @@ -349,8 +350,8 @@ static struct p4_event_binding p4_events[NUM_EVENTS] = { #define ESCR_SET_OS_1(escr, os) ((escr) |= (((os) & 1) << 1)) #define ESCR_SET_EVENT_SELECT(escr, sel) ((escr) |= (((sel) & 0x3f) << 25)) #define ESCR_SET_EVENT_MASK(escr, mask) ((escr) |= (((mask) & 0xffff) << 9)) -#define ESCR_READ(escr,high,ev,i) do {rdmsr(ev->bindings[(i)].escr_address, (escr), (high));} while (0) -#define ESCR_WRITE(escr,high,ev,i) do {wrmsr(ev->bindings[(i)].escr_address, (escr), (high));} while (0) +#define ESCR_READ(escr, high, ev, i) do {rdmsr(ev->bindings[(i)].escr_address, (escr), (high)); } while (0) +#define ESCR_WRITE(escr, high, ev, i) do {wrmsr(ev->bindings[(i)].escr_address, (escr), (high)); } while (0) #define CCCR_RESERVED_BITS 0x38030FFF #define CCCR_CLEAR(cccr) ((cccr) &= CCCR_RESERVED_BITS) @@ -360,15 +361,15 @@ static struct p4_event_binding p4_events[NUM_EVENTS] = { #define CCCR_SET_PMI_OVF_1(cccr) ((cccr) |= (1<<27)) #define CCCR_SET_ENABLE(cccr) ((cccr) |= (1<<12)) #define CCCR_SET_DISABLE(cccr) ((cccr) &= ~(1<<12)) -#define CCCR_READ(low, high, i) do {rdmsr(p4_counters[(i)].cccr_address, (low), (high));} while (0) -#define CCCR_WRITE(low, high, i) do {wrmsr(p4_counters[(i)].cccr_address, (low), (high));} while (0) +#define CCCR_READ(low, high, i) do {rdmsr(p4_counters[(i)].cccr_address, (low), (high)); } while (0) +#define CCCR_WRITE(low, high, i) do {wrmsr(p4_counters[(i)].cccr_address, (low), (high)); } while (0) #define CCCR_OVF_P(cccr) ((cccr) & (1U<<31)) #define CCCR_CLEAR_OVF(cccr) ((cccr) &= (~(1U<<31))) -#define CTRL_IS_RESERVED(msrs,c) (msrs->controls[(c)].addr ? 1 : 0) -#define CTR_IS_RESERVED(msrs,c) (msrs->counters[(c)].addr ? 1 : 0) -#define CTR_READ(l,h,i) do {rdmsr(p4_counters[(i)].counter_address, (l), (h));} while (0) -#define CTR_WRITE(l,i) do {wrmsr(p4_counters[(i)].counter_address, -(u32)(l), -1);} while (0) +#define CTRL_IS_RESERVED(msrs, c) (msrs->controls[(c)].addr ? 1 : 0) +#define CTR_IS_RESERVED(msrs, c) (msrs->counters[(c)].addr ? 1 : 0) +#define CTR_READ(l, h, i) do {rdmsr(p4_counters[(i)].counter_address, (l), (h)); } while (0) +#define CTR_WRITE(l, i) do {wrmsr(p4_counters[(i)].counter_address, -(u32)(l), -1); } while (0) #define CTR_OVERFLOW_P(ctr) (!((ctr) & 0x80000000)) @@ -380,7 +381,7 @@ static unsigned int get_stagger(void) #ifdef CONFIG_SMP int cpu = smp_processor_id(); return (cpu != first_cpu(per_cpu(cpu_sibling_map, cpu))); -#endif +#endif return 0; } @@ -395,25 +396,23 @@ static unsigned long reset_value[NUM_COUNTERS_NON_HT]; static void p4_fill_in_addresses(struct op_msrs * const msrs) { - unsigned int i; + unsigned int i; unsigned int addr, cccraddr, stag; setup_num_counters(); stag = get_stagger(); /* initialize some registers */ - for (i = 0; i < num_counters; ++i) { + for (i = 0; i < num_counters; ++i) msrs->counters[i].addr = 0; - } - for (i = 0; i < num_controls; ++i) { + for (i = 0; i < num_controls; ++i) msrs->controls[i].addr = 0; - } - + /* the counter & cccr registers we pay attention to */ for (i = 0; i < num_counters; ++i) { addr = p4_counters[VIRT_CTR(stag, i)].counter_address; cccraddr = p4_counters[VIRT_CTR(stag, i)].cccr_address; - if (reserve_perfctr_nmi(addr)){ + if (reserve_perfctr_nmi(addr)) { msrs->counters[i].addr = addr; msrs->controls[i].addr = cccraddr; } @@ -447,22 +446,22 @@ static void p4_fill_in_addresses(struct op_msrs * const msrs) if (reserve_evntsel_nmi(addr)) msrs->controls[i].addr = addr; } - + for (addr = MSR_P4_MS_ESCR0 + stag; - addr <= MSR_P4_TC_ESCR1; ++i, addr += addr_increment()) { + addr <= MSR_P4_TC_ESCR1; ++i, addr += addr_increment()) { if (reserve_evntsel_nmi(addr)) msrs->controls[i].addr = addr; } - + for (addr = MSR_P4_IX_ESCR0 + stag; - addr <= MSR_P4_CRU_ESCR3; ++i, addr += addr_increment()) { + addr <= MSR_P4_CRU_ESCR3; ++i, addr += addr_increment()) { if (reserve_evntsel_nmi(addr)) msrs->controls[i].addr = addr; } /* there are 2 remaining non-contiguously located ESCRs */ - if (num_counters == NUM_COUNTERS_NON_HT) { + if (num_counters == NUM_COUNTERS_NON_HT) { /* standard non-HT CPUs handle both remaining ESCRs*/ if (reserve_evntsel_nmi(MSR_P4_CRU_ESCR5)) msrs->controls[i++].addr = MSR_P4_CRU_ESCR5; @@ -498,20 +497,20 @@ static void pmc_setup_one_p4_counter(unsigned int ctr) unsigned int stag; stag = get_stagger(); - + /* convert from counter *number* to counter *bit* */ counter_bit = 1 << VIRT_CTR(stag, ctr); - + /* find our event binding structure. */ if (counter_config[ctr].event <= 0 || counter_config[ctr].event > NUM_EVENTS) { - printk(KERN_ERR - "oprofile: P4 event code 0x%lx out of range\n", + printk(KERN_ERR + "oprofile: P4 event code 0x%lx out of range\n", counter_config[ctr].event); return; } - + ev = &(p4_events[counter_config[ctr].event - 1]); - + for (i = 0; i < maxbind; i++) { if (ev->bindings[i].virt_counter & counter_bit) { @@ -526,25 +525,24 @@ static void pmc_setup_one_p4_counter(unsigned int ctr) ESCR_SET_OS_1(escr, counter_config[ctr].kernel); } ESCR_SET_EVENT_SELECT(escr, ev->event_select); - ESCR_SET_EVENT_MASK(escr, counter_config[ctr].unit_mask); + ESCR_SET_EVENT_MASK(escr, counter_config[ctr].unit_mask); ESCR_WRITE(escr, high, ev, i); - + /* modify CCCR */ CCCR_READ(cccr, high, VIRT_CTR(stag, ctr)); CCCR_CLEAR(cccr); CCCR_SET_REQUIRED_BITS(cccr); CCCR_SET_ESCR_SELECT(cccr, ev->escr_select); - if (stag == 0) { + if (stag == 0) CCCR_SET_PMI_OVF_0(cccr); - } else { + else CCCR_SET_PMI_OVF_1(cccr); - } CCCR_WRITE(cccr, high, VIRT_CTR(stag, ctr)); return; } } - printk(KERN_ERR + printk(KERN_ERR "oprofile: P4 event code 0x%lx no binding, stag %d ctr %d\n", counter_config[ctr].event, stag, ctr); } @@ -559,14 +557,14 @@ static void p4_setup_ctrs(struct op_msrs const * const msrs) stag = get_stagger(); rdmsr(MSR_IA32_MISC_ENABLE, low, high); - if (! MISC_PMC_ENABLED_P(low)) { + if (!MISC_PMC_ENABLED_P(low)) { printk(KERN_ERR "oprofile: P4 PMC not available\n"); return; } /* clear the cccrs we will use */ for (i = 0 ; i < num_counters ; i++) { - if (unlikely(!CTRL_IS_RESERVED(msrs,i))) + if (unlikely(!CTRL_IS_RESERVED(msrs, i))) continue; rdmsr(p4_counters[VIRT_CTR(stag, i)].cccr_address, low, high); CCCR_CLEAR(low); @@ -576,14 +574,14 @@ static void p4_setup_ctrs(struct op_msrs const * const msrs) /* clear all escrs (including those outside our concern) */ for (i = num_counters; i < num_controls; i++) { - if (unlikely(!CTRL_IS_RESERVED(msrs,i))) + if (unlikely(!CTRL_IS_RESERVED(msrs, i))) continue; wrmsr(msrs->controls[i].addr, 0, 0); } /* setup all counters */ for (i = 0 ; i < num_counters ; ++i) { - if ((counter_config[i].enabled) && (CTRL_IS_RESERVED(msrs,i))) { + if ((counter_config[i].enabled) && (CTRL_IS_RESERVED(msrs, i))) { reset_value[i] = counter_config[i].count; pmc_setup_one_p4_counter(i); CTR_WRITE(counter_config[i].count, VIRT_CTR(stag, i)); @@ -603,11 +601,11 @@ static int p4_check_ctrs(struct pt_regs * const regs, stag = get_stagger(); for (i = 0; i < num_counters; ++i) { - - if (!reset_value[i]) + + if (!reset_value[i]) continue; - /* + /* * there is some eccentricity in the hardware which * requires that we perform 2 extra corrections: * @@ -616,24 +614,24 @@ static int p4_check_ctrs(struct pt_regs * const regs, * * - write the counter back twice to ensure it gets * updated properly. - * + * * the former seems to be related to extra NMIs happening * during the current NMI; the latter is reported as errata * N15 in intel doc 249199-029, pentium 4 specification * update, though their suggested work-around does not * appear to solve the problem. */ - + real = VIRT_CTR(stag, i); CCCR_READ(low, high, real); - CTR_READ(ctr, high, real); + CTR_READ(ctr, high, real); if (CCCR_OVF_P(low) || CTR_OVERFLOW_P(ctr)) { oprofile_add_sample(regs, i); - CTR_WRITE(reset_value[i], real); + CTR_WRITE(reset_value[i], real); CCCR_CLEAR_OVF(low); CCCR_WRITE(low, high, real); - CTR_WRITE(reset_value[i], real); + CTR_WRITE(reset_value[i], real); } } @@ -683,15 +681,16 @@ static void p4_shutdown(struct op_msrs const * const msrs) int i; for (i = 0 ; i < num_counters ; ++i) { - if (CTR_IS_RESERVED(msrs,i)) + if (CTR_IS_RESERVED(msrs, i)) release_perfctr_nmi(msrs->counters[i].addr); } - /* some of the control registers are specially reserved in + /* + * some of the control registers are specially reserved in * conjunction with the counter registers (hence the starting offset). * This saves a few bits. */ for (i = num_counters ; i < num_controls ; ++i) { - if (CTRL_IS_RESERVED(msrs,i)) + if (CTRL_IS_RESERVED(msrs, i)) release_evntsel_nmi(msrs->controls[i].addr); } } diff --git a/arch/x86/pci/amd_bus.c b/arch/x86/pci/amd_bus.c index 6a0fca78c36..22e057665e5 100644 --- a/arch/x86/pci/amd_bus.c +++ b/arch/x86/pci/amd_bus.c @@ -580,7 +580,7 @@ static int __cpuinit amd_cpu_notify(struct notifier_block *self, unsigned long action, void *hcpu) { int cpu = (long)hcpu; - switch(action) { + switch (action) { case CPU_ONLINE: case CPU_ONLINE_FROZEN: smp_call_function_single(cpu, enable_pci_io_ecs, NULL, 0); diff --git a/arch/x86/pci/irq.c b/arch/x86/pci/irq.c index 8e077185e18..006599db0dc 100644 --- a/arch/x86/pci/irq.c +++ b/arch/x86/pci/irq.c @@ -1043,35 +1043,44 @@ static void __init pcibios_fixup_irqs(void) if (io_apic_assign_pci_irqs) { int irq; - if (pin) { - /* - * interrupt pins are numbered starting - * from 1 - */ - pin--; - irq = IO_APIC_get_PCI_irq_vector(dev->bus->number, - PCI_SLOT(dev->devfn), pin); - /* - * Busses behind bridges are typically not listed in the MP-table. - * In this case we have to look up the IRQ based on the parent bus, - * parent slot, and pin number. The SMP code detects such bridged - * busses itself so we should get into this branch reliably. - */ - if (irq < 0 && dev->bus->parent) { /* go back to the bridge */ - struct pci_dev *bridge = dev->bus->self; - - pin = (pin + PCI_SLOT(dev->devfn)) % 4; - irq = IO_APIC_get_PCI_irq_vector(bridge->bus->number, - PCI_SLOT(bridge->devfn), pin); - if (irq >= 0) - dev_warn(&dev->dev, "using bridge %s INT %c to get IRQ %d\n", - pci_name(bridge), - 'A' + pin, irq); - } - if (irq >= 0) { - dev_info(&dev->dev, "PCI->APIC IRQ transform: INT %c -> IRQ %d\n", 'A' + pin, irq); - dev->irq = irq; - } + if (!pin) + continue; + + /* + * interrupt pins are numbered starting from 1 + */ + pin--; + irq = IO_APIC_get_PCI_irq_vector(dev->bus->number, + PCI_SLOT(dev->devfn), pin); + /* + * Busses behind bridges are typically not listed in the + * MP-table. In this case we have to look up the IRQ + * based on the parent bus, parent slot, and pin number. + * The SMP code detects such bridged busses itself so we + * should get into this branch reliably. + */ + if (irq < 0 && dev->bus->parent) { + /* go back to the bridge */ + struct pci_dev *bridge = dev->bus->self; + int bus; + + pin = (pin + PCI_SLOT(dev->devfn)) % 4; + bus = bridge->bus->number; + irq = IO_APIC_get_PCI_irq_vector(bus, + PCI_SLOT(bridge->devfn), pin); + if (irq >= 0) + dev_warn(&dev->dev, + "using bridge %s INT %c to " + "get IRQ %d\n", + pci_name(bridge), + 'A' + pin, irq); + } + if (irq >= 0) { + dev_info(&dev->dev, + "PCI->APIC IRQ transform: INT %c " + "-> IRQ %d\n", + 'A' + pin, irq); + dev->irq = irq; } } #endif diff --git a/arch/x86/power/hibernate_asm_32.S b/arch/x86/power/hibernate_asm_32.S index 4fc7e872c85..d1e9b53f9d3 100644 --- a/arch/x86/power/hibernate_asm_32.S +++ b/arch/x86/power/hibernate_asm_32.S @@ -1,5 +1,3 @@ -.text - /* * This may not use any stack, nor any variable that is not "NoSave": * @@ -12,17 +10,18 @@ #include <asm/segment.h> #include <asm/page.h> #include <asm/asm-offsets.h> +#include <asm/processor-flags.h> - .text +.text ENTRY(swsusp_arch_suspend) - movl %esp, saved_context_esp movl %ebx, saved_context_ebx movl %ebp, saved_context_ebp movl %esi, saved_context_esi movl %edi, saved_context_edi - pushfl ; popl saved_context_eflags + pushfl + popl saved_context_eflags call swsusp_save ret @@ -59,7 +58,7 @@ done: movl mmu_cr4_features, %ecx jecxz 1f # cr4 Pentium and higher, skip if zero movl %ecx, %edx - andl $~(1<<7), %edx; # PGE + andl $~(X86_CR4_PGE), %edx movl %edx, %cr4; # turn off PGE 1: movl %cr3, %eax; # flush TLB @@ -74,7 +73,8 @@ done: movl saved_context_esi, %esi movl saved_context_edi, %edi - pushl saved_context_eflags ; popfl + pushl saved_context_eflags + popfl xorl %eax, %eax diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index a4e201b47f6..7dcd321a050 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c @@ -812,7 +812,7 @@ static int xen_write_msr_safe(unsigned int msr, unsigned low, unsigned high) /* Early in boot, while setting up the initial pagetable, assume everything is pinned. */ -static __init void xen_alloc_pte_init(struct mm_struct *mm, u32 pfn) +static __init void xen_alloc_pte_init(struct mm_struct *mm, unsigned long pfn) { #ifdef CONFIG_FLATMEM BUG_ON(mem_map); /* should only be used early */ @@ -822,7 +822,7 @@ static __init void xen_alloc_pte_init(struct mm_struct *mm, u32 pfn) /* Early release_pte assumes that all pts are pinned, since there's only init_mm and anything attached to that is pinned. */ -static void xen_release_pte_init(u32 pfn) +static void xen_release_pte_init(unsigned long pfn) { make_lowmem_page_readwrite(__va(PFN_PHYS(pfn))); } @@ -838,7 +838,7 @@ static void pin_pagetable_pfn(unsigned cmd, unsigned long pfn) /* This needs to make sure the new pte page is pinned iff its being attached to a pinned pagetable. */ -static void xen_alloc_ptpage(struct mm_struct *mm, u32 pfn, unsigned level) +static void xen_alloc_ptpage(struct mm_struct *mm, unsigned long pfn, unsigned level) { struct page *page = pfn_to_page(pfn); @@ -856,12 +856,12 @@ static void xen_alloc_ptpage(struct mm_struct *mm, u32 pfn, unsigned level) } } -static void xen_alloc_pte(struct mm_struct *mm, u32 pfn) +static void xen_alloc_pte(struct mm_struct *mm, unsigned long pfn) { xen_alloc_ptpage(mm, pfn, PT_PTE); } -static void xen_alloc_pmd(struct mm_struct *mm, u32 pfn) +static void xen_alloc_pmd(struct mm_struct *mm, unsigned long pfn) { xen_alloc_ptpage(mm, pfn, PT_PMD); } @@ -909,7 +909,7 @@ static void xen_pgd_free(struct mm_struct *mm, pgd_t *pgd) } /* This should never happen until we're OK to use struct page */ -static void xen_release_ptpage(u32 pfn, unsigned level) +static void xen_release_ptpage(unsigned long pfn, unsigned level) { struct page *page = pfn_to_page(pfn); @@ -923,23 +923,23 @@ static void xen_release_ptpage(u32 pfn, unsigned level) } } -static void xen_release_pte(u32 pfn) +static void xen_release_pte(unsigned long pfn) { xen_release_ptpage(pfn, PT_PTE); } -static void xen_release_pmd(u32 pfn) +static void xen_release_pmd(unsigned long pfn) { xen_release_ptpage(pfn, PT_PMD); } #if PAGETABLE_LEVELS == 4 -static void xen_alloc_pud(struct mm_struct *mm, u32 pfn) +static void xen_alloc_pud(struct mm_struct *mm, unsigned long pfn) { xen_alloc_ptpage(mm, pfn, PT_PUD); } -static void xen_release_pud(u32 pfn) +static void xen_release_pud(unsigned long pfn) { xen_release_ptpage(pfn, PT_PUD); } diff --git a/drivers/accessibility/braille/braille_console.c b/drivers/accessibility/braille/braille_console.c index 0a5f6b2114c..d672cfe7ca5 100644 --- a/drivers/accessibility/braille/braille_console.c +++ b/drivers/accessibility/braille/braille_console.c @@ -376,6 +376,8 @@ int braille_register_console(struct console *console, int index, console->flags |= CON_ENABLED; console->index = index; braille_co = console; + register_keyboard_notifier(&keyboard_notifier_block); + register_vt_notifier(&vt_notifier_block); return 0; } @@ -383,15 +385,8 @@ int braille_unregister_console(struct console *console) { if (braille_co != console) return -EINVAL; + unregister_keyboard_notifier(&keyboard_notifier_block); + unregister_vt_notifier(&vt_notifier_block); braille_co = NULL; return 0; } - -static int __init braille_init(void) -{ - register_keyboard_notifier(&keyboard_notifier_block); - register_vt_notifier(&vt_notifier_block); - return 0; -} - -console_initcall(braille_init); diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index 084109507c9..8dd3336efd7 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c @@ -165,8 +165,11 @@ static int acpi_bind_one(struct device *dev, acpi_handle handle) "firmware_node"); ret = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj, "physical_node"); - if (acpi_dev->wakeup.flags.valid) + if (acpi_dev->wakeup.flags.valid) { device_set_wakeup_capable(dev, true); + device_set_wakeup_enable(dev, + acpi_dev->wakeup.state.enabled); + } } return 0; diff --git a/drivers/acpi/sleep/proc.c b/drivers/acpi/sleep/proc.c index 4ebbba2b6b1..bf5b04de02d 100644 --- a/drivers/acpi/sleep/proc.c +++ b/drivers/acpi/sleep/proc.c @@ -377,6 +377,14 @@ acpi_system_wakeup_device_seq_show(struct seq_file *seq, void *offset) return 0; } +static void physical_device_enable_wakeup(struct acpi_device *adev) +{ + struct device *dev = acpi_get_physical_device(adev->handle); + + if (dev && device_can_wakeup(dev)) + device_set_wakeup_enable(dev, adev->wakeup.state.enabled); +} + static ssize_t acpi_system_write_wakeup_device(struct file *file, const char __user * buffer, @@ -411,6 +419,7 @@ acpi_system_write_wakeup_device(struct file *file, } } if (found_dev) { + physical_device_enable_wakeup(found_dev); list_for_each_safe(node, next, &acpi_wakeup_device_list) { struct acpi_device *dev = container_of(node, struct @@ -428,6 +437,7 @@ acpi_system_write_wakeup_device(struct file *file, dev->pnp.bus_id, found_dev->pnp.bus_id); dev->wakeup.state.enabled = found_dev->wakeup.state.enabled; + physical_device_enable_wakeup(dev); } } } diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c index 1e1f3f3757a..14601dc05e4 100644 --- a/drivers/ata/sata_nv.c +++ b/drivers/ata/sata_nv.c @@ -309,6 +309,8 @@ static void nv_nf2_freeze(struct ata_port *ap); static void nv_nf2_thaw(struct ata_port *ap); static void nv_ck804_freeze(struct ata_port *ap); static void nv_ck804_thaw(struct ata_port *ap); +static int nv_hardreset(struct ata_link *link, unsigned int *class, + unsigned long deadline); static int nv_adma_slave_config(struct scsi_device *sdev); static int nv_adma_check_atapi_dma(struct ata_queued_cmd *qc); static void nv_adma_qc_prep(struct ata_queued_cmd *qc); @@ -403,28 +405,45 @@ static struct scsi_host_template nv_swncq_sht = { .slave_configure = nv_swncq_slave_config, }; -static struct ata_port_operations nv_generic_ops = { +/* OSDL bz3352 reports that some nv controllers can't determine device + * signature reliably and nv_hardreset is implemented to work around + * the problem. This was reported on nf3 and it's unclear whether any + * other controllers are affected. However, the workaround has been + * applied to all variants and there isn't much to gain by trying to + * find out exactly which ones are affected at this point especially + * because NV has moved over to ahci for newer controllers. + */ +static struct ata_port_operations nv_common_ops = { .inherits = &ata_bmdma_port_ops, - .hardreset = ATA_OP_NULL, + .hardreset = nv_hardreset, .scr_read = nv_scr_read, .scr_write = nv_scr_write, }; +/* OSDL bz11195 reports that link doesn't come online after hardreset + * on generic nv's and there have been several other similar reports + * on linux-ide. Disable hardreset for generic nv's. + */ +static struct ata_port_operations nv_generic_ops = { + .inherits = &nv_common_ops, + .hardreset = ATA_OP_NULL, +}; + static struct ata_port_operations nv_nf2_ops = { - .inherits = &nv_generic_ops, + .inherits = &nv_common_ops, .freeze = nv_nf2_freeze, .thaw = nv_nf2_thaw, }; static struct ata_port_operations nv_ck804_ops = { - .inherits = &nv_generic_ops, + .inherits = &nv_common_ops, .freeze = nv_ck804_freeze, .thaw = nv_ck804_thaw, .host_stop = nv_ck804_host_stop, }; static struct ata_port_operations nv_adma_ops = { - .inherits = &nv_generic_ops, + .inherits = &nv_common_ops, .check_atapi_dma = nv_adma_check_atapi_dma, .sff_tf_read = nv_adma_tf_read, @@ -448,7 +467,7 @@ static struct ata_port_operations nv_adma_ops = { }; static struct ata_port_operations nv_swncq_ops = { - .inherits = &nv_generic_ops, + .inherits = &nv_common_ops, .qc_defer = ata_std_qc_defer, .qc_prep = nv_swncq_qc_prep, @@ -1586,6 +1605,21 @@ static void nv_mcp55_thaw(struct ata_port *ap) ata_sff_thaw(ap); } +static int nv_hardreset(struct ata_link *link, unsigned int *class, + unsigned long deadline) +{ + int rc; + + /* SATA hardreset fails to retrieve proper device signature on + * some controllers. Request follow up SRST. For more info, + * see http://bugzilla.kernel.org/show_bug.cgi?id=3352 + */ + rc = sata_sff_hardreset(link, class, deadline); + if (rc) + return rc; + return -EAGAIN; +} + static void nv_adma_error_handler(struct ata_port *ap) { struct nv_adma_port_priv *pp = ap->private_data; diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 6a010681ecf..29ae99817c6 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -104,6 +104,9 @@ static struct usb_device_id blacklist_table[] = { /* Broadcom BCM2046 */ { USB_DEVICE(0x0a5c, 0x2151), .driver_info = BTUSB_RESET }, + /* Apple MacBook Pro with Broadcom chip */ + { USB_DEVICE(0x05ac, 0x820f), .driver_info = BTUSB_RESET }, + /* IBM/Lenovo ThinkPad with Broadcom chip */ { USB_DEVICE(0x0a5c, 0x201e), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU }, { USB_DEVICE(0x0a5c, 0x2110), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU }, @@ -169,6 +172,7 @@ static struct usb_device_id blacklist_table[] = { struct btusb_data { struct hci_dev *hdev; struct usb_device *udev; + struct usb_interface *intf; struct usb_interface *isoc; spinlock_t lock; @@ -516,7 +520,7 @@ static int btusb_open(struct hci_dev *hdev) err = btusb_submit_intr_urb(hdev); if (err < 0) { - clear_bit(BTUSB_INTR_RUNNING, &hdev->flags); + clear_bit(BTUSB_INTR_RUNNING, &data->flags); clear_bit(HCI_RUNNING, &hdev->flags); } @@ -532,8 +536,10 @@ static int btusb_close(struct hci_dev *hdev) if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags)) return 0; + cancel_work_sync(&data->work); + clear_bit(BTUSB_ISOC_RUNNING, &data->flags); - usb_kill_anchored_urbs(&data->intr_anchor); + usb_kill_anchored_urbs(&data->isoc_anchor); clear_bit(BTUSB_BULK_RUNNING, &data->flags); usb_kill_anchored_urbs(&data->bulk_anchor); @@ -821,6 +827,7 @@ static int btusb_probe(struct usb_interface *intf, } data->udev = interface_to_usbdev(intf); + data->intf = intf; spin_lock_init(&data->lock); @@ -889,7 +896,7 @@ static int btusb_probe(struct usb_interface *intf, if (data->isoc) { err = usb_driver_claim_interface(&btusb_driver, - data->isoc, NULL); + data->isoc, data); if (err < 0) { hci_free_dev(hdev); kfree(data); @@ -921,13 +928,22 @@ static void btusb_disconnect(struct usb_interface *intf) hdev = data->hdev; - if (data->isoc) - usb_driver_release_interface(&btusb_driver, data->isoc); + __hci_dev_hold(hdev); - usb_set_intfdata(intf, NULL); + usb_set_intfdata(data->intf, NULL); + + if (data->isoc) + usb_set_intfdata(data->isoc, NULL); hci_unregister_dev(hdev); + if (intf == data->isoc) + usb_driver_release_interface(&btusb_driver, data->intf); + else if (data->isoc) + usb_driver_release_interface(&btusb_driver, data->isoc); + + __hci_dev_put(hdev); + hci_free_dev(hdev); } diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index daeb8f76697..e4dce870954 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c @@ -695,13 +695,23 @@ struct tty_driver *tty_find_polling_driver(char *name, int *line) { struct tty_driver *p, *res = NULL; int tty_line = 0; + int len; char *str; + for (str = name; *str; str++) + if ((*str >= '0' && *str <= '9') || *str == ',') + break; + if (!*str) + return NULL; + + len = str - name; + tty_line = simple_strtoul(str, &str, 10); + mutex_lock(&tty_mutex); /* Search through the tty devices to look for a match */ list_for_each_entry(p, &tty_drivers, tty_drivers) { - str = name + strlen(p->name); - tty_line = simple_strtoul(str, &str, 10); + if (strncmp(name, p->name, len) != 0) + continue; if (*str == ',') str++; if (*str == '\0') diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c index 94df9177124..0778d99aea7 100644 --- a/drivers/dma/dw_dmac.c +++ b/drivers/dma/dw_dmac.c @@ -364,7 +364,7 @@ static void dw_dma_tasklet(unsigned long data) int i; status_block = dma_readl(dw, RAW.BLOCK); - status_xfer = dma_readl(dw, RAW.BLOCK); + status_xfer = dma_readl(dw, RAW.XFER); status_err = dma_readl(dw, RAW.ERROR); dev_vdbg(dw->dma.dev, "tasklet: status_block=%x status_err=%x\n", diff --git a/drivers/i2c/busses/i2c-powermac.c b/drivers/i2c/busses/i2c-powermac.c index 22f6d5c00d8..0e7b1c6724a 100644 --- a/drivers/i2c/busses/i2c-powermac.c +++ b/drivers/i2c/busses/i2c-powermac.c @@ -180,7 +180,7 @@ static const struct i2c_algorithm i2c_powermac_algorithm = { }; -static int i2c_powermac_remove(struct platform_device *dev) +static int __devexit i2c_powermac_remove(struct platform_device *dev) { struct i2c_adapter *adapter = platform_get_drvdata(dev); struct pmac_i2c_bus *bus = i2c_get_adapdata(adapter); @@ -200,7 +200,7 @@ static int i2c_powermac_remove(struct platform_device *dev) } -static int __devexit i2c_powermac_probe(struct platform_device *dev) +static int __devinit i2c_powermac_probe(struct platform_device *dev) { struct pmac_i2c_bus *bus = dev->dev.platform_data; struct device_node *parent = NULL; diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c index af4491fa7e3..307d976c9b6 100644 --- a/drivers/i2c/i2c-dev.c +++ b/drivers/i2c/i2c-dev.c @@ -583,8 +583,10 @@ static int __init i2c_dev_init(void) goto out; i2c_dev_class = class_create(THIS_MODULE, "i2c-dev"); - if (IS_ERR(i2c_dev_class)) + if (IS_ERR(i2c_dev_class)) { + res = PTR_ERR(i2c_dev_class); goto out_unreg_chrdev; + } res = i2c_add_driver(&i2cdev_driver); if (res) diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index fc735ab08ff..8e93a797c93 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig @@ -292,6 +292,20 @@ config IDE_GENERIC tristate "generic/default IDE chipset support" depends on ALPHA || X86 || IA64 || M32R || MIPS help + This is the generic IDE driver. This driver attaches to the + fixed legacy ports (e.g. on PCs 0x1f0/0x170, 0x1e8/0x168 and + so on). Please note that if this driver is built into the + kernel or loaded before other ATA (IDE or libata) drivers + and the controller is located at legacy ports, this driver + may grab those ports and thus can prevent the controller + specific driver from attaching. + + Also, currently, IDE generic doesn't allow IRQ sharing + meaning that the IRQs it grabs won't be available to other + controllers sharing those IRQs which usually makes drivers + for those controllers fail. Generally, it's not a good idea + to load IDE generic driver on modern systems. + If unsure, say N. config BLK_DEV_PLATFORM diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 1bce84b5663..3833189144e 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -2338,7 +2338,7 @@ static void idetape_get_inquiry_results(ide_drive_t *drive) { idetape_tape_t *tape = drive->driver_data; struct ide_atapi_pc pc; - char fw_rev[6], vendor_id[10], product_id[18]; + char fw_rev[4], vendor_id[8], product_id[16]; idetape_create_inquiry_cmd(&pc); if (idetape_queue_pc_tail(drive, &pc)) { @@ -2350,11 +2350,11 @@ static void idetape_get_inquiry_results(ide_drive_t *drive) memcpy(product_id, &pc.buf[16], 16); memcpy(fw_rev, &pc.buf[32], 4); - ide_fixstring(vendor_id, 10, 0); - ide_fixstring(product_id, 18, 0); - ide_fixstring(fw_rev, 6, 0); + ide_fixstring(vendor_id, 8, 0); + ide_fixstring(product_id, 16, 0); + ide_fixstring(fw_rev, 4, 0); - printk(KERN_INFO "ide-tape: %s <-> %s: %s %s rev %s\n", + printk(KERN_INFO "ide-tape: %s <-> %s: %.8s %.16s rev %.4s\n", drive->name, tape->name, vendor_id, product_id, fw_rev); } diff --git a/drivers/ide/mips/swarm.c b/drivers/ide/mips/swarm.c index badf79fc9e3..39c9ee99585 100644 --- a/drivers/ide/mips/swarm.c +++ b/drivers/ide/mips/swarm.c @@ -107,6 +107,7 @@ static int __devinit swarm_ide_probe(struct device *dev) base = ioremap(offset, size); + memset(&hw, 0, sizeof(hw)); for (i = 0; i <= 7; i++) hw.io_ports_array[i] = (unsigned long)(base + ((0x1f0 + i) << 5)); diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index 1b1df5cc411..e9ca3cb57d5 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c @@ -404,7 +404,7 @@ static void path_rec_completion(int status, struct net_device *dev = path->dev; struct ipoib_dev_priv *priv = netdev_priv(dev); struct ipoib_ah *ah = NULL; - struct ipoib_ah *old_ah; + struct ipoib_ah *old_ah = NULL; struct ipoib_neigh *neigh, *tn; struct sk_buff_head skqueue; struct sk_buff *skb; @@ -428,12 +428,12 @@ static void path_rec_completion(int status, spin_lock_irqsave(&priv->lock, flags); - old_ah = path->ah; - path->ah = ah; - if (ah) { path->pathrec = *pathrec; + old_ah = path->ah; + path->ah = ah; + ipoib_dbg(priv, "created address handle %p for LID 0x%04x, SL %d\n", ah, be16_to_cpu(pathrec->dlid), pathrec->sl); diff --git a/drivers/input/mouse/bcm5974.c b/drivers/input/mouse/bcm5974.c index 18f4d7f6ce6..2998a6ac9ae 100644 --- a/drivers/input/mouse/bcm5974.c +++ b/drivers/input/mouse/bcm5974.c @@ -351,8 +351,9 @@ static int report_tp_state(struct bcm5974 *dev, int size) #define BCM5974_WELLSPRING_MODE_REQUEST_VALUE 0x300 #define BCM5974_WELLSPRING_MODE_REQUEST_INDEX 0 #define BCM5974_WELLSPRING_MODE_VENDOR_VALUE 0x01 +#define BCM5974_WELLSPRING_MODE_NORMAL_VALUE 0x08 -static int bcm5974_wellspring_mode(struct bcm5974 *dev) +static int bcm5974_wellspring_mode(struct bcm5974 *dev, bool on) { char *data = kmalloc(8, GFP_KERNEL); int retval = 0, size; @@ -377,7 +378,9 @@ static int bcm5974_wellspring_mode(struct bcm5974 *dev) } /* apply the mode switch */ - data[0] = BCM5974_WELLSPRING_MODE_VENDOR_VALUE; + data[0] = on ? + BCM5974_WELLSPRING_MODE_VENDOR_VALUE : + BCM5974_WELLSPRING_MODE_NORMAL_VALUE; /* write configuration */ size = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), @@ -392,7 +395,8 @@ static int bcm5974_wellspring_mode(struct bcm5974 *dev) goto out; } - dprintk(2, "bcm5974: switched to wellspring mode.\n"); + dprintk(2, "bcm5974: switched to %s mode.\n", + on ? "wellspring" : "normal"); out: kfree(data); @@ -481,7 +485,7 @@ exit: */ static int bcm5974_start_traffic(struct bcm5974 *dev) { - if (bcm5974_wellspring_mode(dev)) { + if (bcm5974_wellspring_mode(dev, true)) { dprintk(1, "bcm5974: mode switch failed\n"); goto error; } @@ -504,6 +508,7 @@ static void bcm5974_pause_traffic(struct bcm5974 *dev) { usb_kill_urb(dev->tp_urb); usb_kill_urb(dev->bt_urb); + bcm5974_wellspring_mode(dev, false); } /* diff --git a/drivers/input/touchscreen/jornada720_ts.c b/drivers/input/touchscreen/jornada720_ts.c index bf44f9d6834..c8b7e8a45c4 100644 --- a/drivers/input/touchscreen/jornada720_ts.c +++ b/drivers/input/touchscreen/jornada720_ts.c @@ -119,8 +119,8 @@ static int __devinit jornada720_ts_probe(struct platform_device *pdev) input_dev->id.bustype = BUS_HOST; input_dev->dev.parent = &pdev->dev; - input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); - input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); + input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); + input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); input_set_abs_params(input_dev, ABS_X, 270, 3900, 0, 0); input_set_abs_params(input_dev, ABS_Y, 180, 3700, 0, 0); diff --git a/drivers/leds/leds-fsg.c b/drivers/leds/leds-fsg.c index be0e12144b8..34935155c1c 100644 --- a/drivers/leds/leds-fsg.c +++ b/drivers/leds/leds-fsg.c @@ -161,6 +161,16 @@ static int fsg_led_probe(struct platform_device *pdev) { int ret; + /* Map the LED chip select address space */ + latch_address = (unsigned short *) ioremap(IXP4XX_EXP_BUS_BASE(2), 512); + if (!latch_address) { + ret = -ENOMEM; + goto failremap; + } + + latch_value = 0xffff; + *latch_address = latch_value; + ret = led_classdev_register(&pdev->dev, &fsg_wlan_led); if (ret < 0) goto failwlan; @@ -185,20 +195,8 @@ static int fsg_led_probe(struct platform_device *pdev) if (ret < 0) goto failring; - /* Map the LED chip select address space */ - latch_address = (unsigned short *) ioremap(IXP4XX_EXP_BUS_BASE(2), 512); - if (!latch_address) { - ret = -ENOMEM; - goto failremap; - } - - latch_value = 0xffff; - *latch_address = latch_value; - return ret; - failremap: - led_classdev_unregister(&fsg_ring_led); failring: led_classdev_unregister(&fsg_sync_led); failsync: @@ -210,14 +208,14 @@ static int fsg_led_probe(struct platform_device *pdev) failwan: led_classdev_unregister(&fsg_wlan_led); failwlan: + iounmap(latch_address); + failremap: return ret; } static int fsg_led_remove(struct platform_device *pdev) { - iounmap(latch_address); - led_classdev_unregister(&fsg_wlan_led); led_classdev_unregister(&fsg_wan_led); led_classdev_unregister(&fsg_sata_led); @@ -225,6 +223,8 @@ static int fsg_led_remove(struct platform_device *pdev) led_classdev_unregister(&fsg_sync_led); led_classdev_unregister(&fsg_ring_led); + iounmap(latch_address); + return 0; } diff --git a/drivers/leds/leds-pca955x.c b/drivers/leds/leds-pca955x.c index 146c0697286..f508729123b 100644 --- a/drivers/leds/leds-pca955x.c +++ b/drivers/leds/leds-pca955x.c @@ -248,11 +248,10 @@ static int __devinit pca955x_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct pca955x_led *pca955x; - int i; - int err = -ENODEV; struct pca955x_chipdef *chip; struct i2c_adapter *adapter; struct led_platform_data *pdata; + int i, err; chip = &pca955x_chipdefs[id->driver_data]; adapter = to_i2c_adapter(client->dev.parent); @@ -282,43 +281,41 @@ static int __devinit pca955x_probe(struct i2c_client *client, } } + pca955x = kzalloc(sizeof(*pca955x) * chip->bits, GFP_KERNEL); + if (!pca955x) + return -ENOMEM; + + i2c_set_clientdata(client, pca955x); + for (i = 0; i < chip->bits; i++) { - pca955x = kzalloc(sizeof(struct pca955x_led), GFP_KERNEL); - if (!pca955x) { - err = -ENOMEM; - goto exit; - } + pca955x[i].chipdef = chip; + pca955x[i].client = client; + pca955x[i].led_num = i; - pca955x->chipdef = chip; - pca955x->client = client; - pca955x->led_num = i; /* Platform data can specify LED names and default triggers */ if (pdata) { if (pdata->leds[i].name) - snprintf(pca955x->name, 32, "pca955x:%s", - pdata->leds[i].name); + snprintf(pca955x[i].name, + sizeof(pca955x[i].name), "pca955x:%s", + pdata->leds[i].name); if (pdata->leds[i].default_trigger) - pca955x->led_cdev.default_trigger = + pca955x[i].led_cdev.default_trigger = pdata->leds[i].default_trigger; } else { - snprintf(pca955x->name, 32, "pca955x:%d", i); + snprintf(pca955x[i].name, sizeof(pca955x[i].name), + "pca955x:%d", i); } - spin_lock_init(&pca955x->lock); - pca955x->led_cdev.name = pca955x->name; - pca955x->led_cdev.brightness_set = - pca955x_led_set; + spin_lock_init(&pca955x[i].lock); - /* - * Client data is a pointer to the _first_ pca955x_led - * struct - */ - if (i == 0) - i2c_set_clientdata(client, pca955x); + pca955x[i].led_cdev.name = pca955x[i].name; + pca955x[i].led_cdev.brightness_set = pca955x_led_set; - INIT_WORK(&(pca955x->work), pca955x_led_work); + INIT_WORK(&pca955x[i].work, pca955x_led_work); - led_classdev_register(&client->dev, &(pca955x->led_cdev)); + err = led_classdev_register(&client->dev, &pca955x[i].led_cdev); + if (err < 0) + goto exit; } /* Turn off LEDs */ @@ -336,23 +333,32 @@ static int __devinit pca955x_probe(struct i2c_client *client, pca955x_write_psc(client, 1, 0); return 0; + exit: + while (i--) { + led_classdev_unregister(&pca955x[i].led_cdev); + cancel_work_sync(&pca955x[i].work); + } + + kfree(pca955x); + i2c_set_clientdata(client, NULL); + return err; } static int __devexit pca955x_remove(struct i2c_client *client) { struct pca955x_led *pca955x = i2c_get_clientdata(client); - int leds = pca955x->chipdef->bits; int i; - for (i = 0; i < leds; i++) { - led_classdev_unregister(&(pca955x->led_cdev)); - cancel_work_sync(&(pca955x->work)); - kfree(pca955x); - pca955x = pca955x + 1; + for (i = 0; i < pca955x->chipdef->bits; i++) { + led_classdev_unregister(&pca955x[i].led_cdev); + cancel_work_sync(&pca955x[i].work); } + kfree(pca955x); + i2c_set_clientdata(client, NULL); + return 0; } diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c index 71dd65aa31b..c2fcf28b4c7 100644 --- a/drivers/md/dm-mpath.c +++ b/drivers/md/dm-mpath.c @@ -63,6 +63,7 @@ struct multipath { const char *hw_handler_name; struct work_struct activate_path; + struct pgpath *pgpath_to_activate; unsigned nr_priority_groups; struct list_head priority_groups; unsigned pg_init_required; /* pg_init needs calling? */ @@ -146,6 +147,7 @@ static struct priority_group *alloc_priority_group(void) static void free_pgpaths(struct list_head *pgpaths, struct dm_target *ti) { + unsigned long flags; struct pgpath *pgpath, *tmp; struct multipath *m = ti->private; @@ -154,6 +156,10 @@ static void free_pgpaths(struct list_head *pgpaths, struct dm_target *ti) if (m->hw_handler_name) scsi_dh_detach(bdev_get_queue(pgpath->path.dev->bdev)); dm_put_device(ti, pgpath->path.dev); + spin_lock_irqsave(&m->lock, flags); + if (m->pgpath_to_activate == pgpath) + m->pgpath_to_activate = NULL; + spin_unlock_irqrestore(&m->lock, flags); free_pgpath(pgpath); } } @@ -421,6 +427,7 @@ static void process_queued_ios(struct work_struct *work) __choose_pgpath(m); pgpath = m->current_pgpath; + m->pgpath_to_activate = m->current_pgpath; if ((pgpath && !m->queue_io) || (!pgpath && !m->queue_if_no_path)) @@ -1093,8 +1100,15 @@ static void activate_path(struct work_struct *work) int ret; struct multipath *m = container_of(work, struct multipath, activate_path); - struct dm_path *path = &m->current_pgpath->path; + struct dm_path *path; + unsigned long flags; + spin_lock_irqsave(&m->lock, flags); + path = &m->pgpath_to_activate->path; + m->pgpath_to_activate = NULL; + spin_unlock_irqrestore(&m->lock, flags); + if (!path) + return; ret = scsi_dh_activate(bdev_get_queue(path->dev->bdev)); pg_init_done(path, ret); } diff --git a/drivers/md/dm.c b/drivers/md/dm.c index bca448e1187..ace998ce59f 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -837,12 +837,14 @@ static int dm_merge_bvec(struct request_queue *q, struct dm_table *map = dm_get_table(md); struct dm_target *ti; sector_t max_sectors; - int max_size; + int max_size = 0; if (unlikely(!map)) - return 0; + goto out; ti = dm_table_find_target(map, bvm->bi_sector); + if (!dm_target_is_valid(ti)) + goto out_table; /* * Find maximum amount of I/O that won't need splitting @@ -861,14 +863,16 @@ static int dm_merge_bvec(struct request_queue *q, if (max_size && ti->type->merge) max_size = ti->type->merge(ti, bvm, biovec, max_size); +out_table: + dm_table_put(map); + +out: /* * Always allow an entire first page */ if (max_size <= biovec->bv_len && !(bvm->bi_size >> SECTOR_SHIFT)) max_size = biovec->bv_len; - dm_table_put(map); - return max_size; } diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 10c44d3fe01..68dc8d9eb24 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -21,7 +21,7 @@ config MFD_SM501 config MFD_SM501_GPIO bool "Export GPIO via GPIO layer" - depends on MFD_SM501 && HAVE_GPIO_LIB + depends on MFD_SM501 && GPIOLIB ---help--- This option uses the gpio library layer to export the 64 GPIO lines on the SM501. The platform data is used to supply the @@ -29,7 +29,7 @@ config MFD_SM501_GPIO config MFD_ASIC3 bool "Support for Compaq ASIC3" - depends on GENERIC_HARDIRQS && HAVE_GPIO_LIB && ARM + depends on GENERIC_HARDIRQS && GPIOLIB && ARM ---help--- This driver supports the ASIC3 multifunction chip found on many PDAs (mainly iPAQ and HTC based ones) diff --git a/drivers/mfd/asic3.c b/drivers/mfd/asic3.c index bc2a807f210..ba5aa200827 100644 --- a/drivers/mfd/asic3.c +++ b/drivers/mfd/asic3.c @@ -312,7 +312,6 @@ static int __init asic3_irq_probe(struct platform_device *pdev) struct asic3 *asic = platform_get_drvdata(pdev); unsigned long clksel = 0; unsigned int irq, irq_base; - int map_size; int ret; ret = platform_get_irq(pdev, 0); @@ -534,6 +533,7 @@ static int __init asic3_probe(struct platform_device *pdev) struct asic3 *asic; struct resource *mem; unsigned long clksel; + int map_size; int ret = 0; asic = kzalloc(sizeof(struct asic3), GFP_KERNEL); diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h index ac4e506b4f8..5ea6b60fa37 100644 --- a/drivers/net/e1000e/e1000.h +++ b/drivers/net/e1000e/e1000.h @@ -257,7 +257,6 @@ struct e1000_adapter { struct net_device *netdev; struct pci_dev *pdev; struct net_device_stats net_stats; - spinlock_t stats_lock; /* prevent concurrent stats updates */ /* structs defined in e1000_hw.h */ struct e1000_hw hw; @@ -284,6 +283,8 @@ struct e1000_adapter { unsigned long led_status; unsigned int flags; + struct work_struct downshift_task; + struct work_struct update_phy_task; }; struct e1000_info { @@ -305,6 +306,7 @@ struct e1000_info { #define FLAG_HAS_CTRLEXT_ON_LOAD (1 << 5) #define FLAG_HAS_SWSM_ON_LOAD (1 << 6) #define FLAG_HAS_JUMBO_FRAMES (1 << 7) +#define FLAG_READ_ONLY_NVM (1 << 8) #define FLAG_IS_ICH (1 << 9) #define FLAG_HAS_SMART_POWER_DOWN (1 << 11) #define FLAG_IS_QUAD_PORT_A (1 << 12) @@ -385,6 +387,7 @@ extern bool e1000e_enable_mng_pass_thru(struct e1000_hw *hw); extern bool e1000e_get_laa_state_82571(struct e1000_hw *hw); extern void e1000e_set_laa_state_82571(struct e1000_hw *hw, bool state); +extern void e1000e_write_protect_nvm_ich8lan(struct e1000_hw *hw); extern void e1000e_set_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw, bool state); extern void e1000e_igp3_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw); diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c index e21c9e0f373..33a3ff17b5d 100644 --- a/drivers/net/e1000e/ethtool.c +++ b/drivers/net/e1000e/ethtool.c @@ -432,6 +432,10 @@ static void e1000_get_regs(struct net_device *netdev, regs_buff[11] = er32(TIDV); regs_buff[12] = adapter->hw.phy.type; /* PHY type (IGP=1, M88=0) */ + + /* ethtool doesn't use anything past this point, so all this + * code is likely legacy junk for apps that may or may not + * exist */ if (hw->phy.type == e1000_phy_m88) { e1e_rphy(hw, M88E1000_PHY_SPEC_STATUS, &phy_data); regs_buff[13] = (u32)phy_data; /* cable length */ @@ -447,7 +451,7 @@ static void e1000_get_regs(struct net_device *netdev, regs_buff[22] = adapter->phy_stats.receive_errors; regs_buff[23] = regs_buff[13]; /* mdix mode */ } - regs_buff[21] = adapter->phy_stats.idle_errors; /* phy idle errors */ + regs_buff[21] = 0; /* was idle_errors */ e1e_rphy(hw, PHY_1000T_STATUS, &phy_data); regs_buff[24] = (u32)phy_data; /* phy local receiver status */ regs_buff[25] = regs_buff[24]; /* phy remote receiver status */ @@ -529,6 +533,9 @@ static int e1000_set_eeprom(struct net_device *netdev, if (eeprom->magic != (adapter->pdev->vendor | (adapter->pdev->device << 16))) return -EFAULT; + if (adapter->flags & FLAG_READ_ONLY_NVM) + return -EINVAL; + max_len = hw->nvm.word_size * 2; first_word = eeprom->offset >> 1; diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c index 9e38452a738..bcd2bc477af 100644 --- a/drivers/net/e1000e/ich8lan.c +++ b/drivers/net/e1000e/ich8lan.c @@ -58,6 +58,7 @@ #define ICH_FLASH_HSFCTL 0x0006 #define ICH_FLASH_FADDR 0x0008 #define ICH_FLASH_FDATA0 0x0010 +#define ICH_FLASH_PR0 0x0074 #define ICH_FLASH_READ_COMMAND_TIMEOUT 500 #define ICH_FLASH_WRITE_COMMAND_TIMEOUT 500 @@ -150,6 +151,19 @@ union ich8_hws_flash_regacc { u16 regval; }; +/* ICH Flash Protected Region */ +union ich8_flash_protected_range { + struct ich8_pr { + u32 base:13; /* 0:12 Protected Range Base */ + u32 reserved1:2; /* 13:14 Reserved */ + u32 rpe:1; /* 15 Read Protection Enable */ + u32 limit:13; /* 16:28 Protected Range Limit */ + u32 reserved2:2; /* 29:30 Reserved */ + u32 wpe:1; /* 31 Write Protection Enable */ + } range; + u32 regval; +}; + static s32 e1000_setup_link_ich8lan(struct e1000_hw *hw); static void e1000_clear_hw_cntrs_ich8lan(struct e1000_hw *hw); static void e1000_initialize_hw_bits_ich8lan(struct e1000_hw *hw); @@ -366,6 +380,9 @@ static s32 e1000_get_variants_ich8lan(struct e1000_adapter *adapter) return 0; } +static DEFINE_MUTEX(nvm_mutex); +static pid_t nvm_owner = -1; + /** * e1000_acquire_swflag_ich8lan - Acquire software control flag * @hw: pointer to the HW structure @@ -379,6 +396,15 @@ static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw) u32 extcnf_ctrl; u32 timeout = PHY_CFG_TIMEOUT; + might_sleep(); + + if (!mutex_trylock(&nvm_mutex)) { + WARN(1, KERN_ERR "e1000e mutex contention. Owned by pid %d\n", + nvm_owner); + mutex_lock(&nvm_mutex); + } + nvm_owner = current->pid; + while (timeout) { extcnf_ctrl = er32(EXTCNF_CTRL); extcnf_ctrl |= E1000_EXTCNF_CTRL_SWFLAG; @@ -393,6 +419,8 @@ static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw) if (!timeout) { hw_dbg(hw, "FW or HW has locked the resource for too long.\n"); + nvm_owner = -1; + mutex_unlock(&nvm_mutex); return -E1000_ERR_CONFIG; } @@ -414,6 +442,9 @@ static void e1000_release_swflag_ich8lan(struct e1000_hw *hw) extcnf_ctrl = er32(EXTCNF_CTRL); extcnf_ctrl &= ~E1000_EXTCNF_CTRL_SWFLAG; ew32(EXTCNF_CTRL, extcnf_ctrl); + + nvm_owner = -1; + mutex_unlock(&nvm_mutex); } /** @@ -1284,6 +1315,7 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw) * programming failed. */ if (ret_val) { + /* Possibly read-only, see e1000e_write_protect_nvm_ich8lan() */ hw_dbg(hw, "Flash commit failed.\n"); e1000_release_swflag_ich8lan(hw); return ret_val; @@ -1374,6 +1406,49 @@ static s32 e1000_validate_nvm_checksum_ich8lan(struct e1000_hw *hw) } /** + * e1000e_write_protect_nvm_ich8lan - Make the NVM read-only + * @hw: pointer to the HW structure + * + * To prevent malicious write/erase of the NVM, set it to be read-only + * so that the hardware ignores all write/erase cycles of the NVM via + * the flash control registers. The shadow-ram copy of the NVM will + * still be updated, however any updates to this copy will not stick + * across driver reloads. + **/ +void e1000e_write_protect_nvm_ich8lan(struct e1000_hw *hw) +{ + union ich8_flash_protected_range pr0; + union ich8_hws_flash_status hsfsts; + u32 gfpreg; + s32 ret_val; + + ret_val = e1000_acquire_swflag_ich8lan(hw); + if (ret_val) + return; + + gfpreg = er32flash(ICH_FLASH_GFPREG); + + /* Write-protect GbE Sector of NVM */ + pr0.regval = er32flash(ICH_FLASH_PR0); + pr0.range.base = gfpreg & FLASH_GFPREG_BASE_MASK; + pr0.range.limit = ((gfpreg >> 16) & FLASH_GFPREG_BASE_MASK); + pr0.range.wpe = true; + ew32flash(ICH_FLASH_PR0, pr0.regval); + + /* + * Lock down a subset of GbE Flash Control Registers, e.g. + * PR0 to prevent the write-protection from being lifted. + * Once FLOCKDN is set, the registers protected by it cannot + * be written until FLOCKDN is cleared by a hardware reset. + */ + hsfsts.regval = er16flash(ICH_FLASH_HSFSTS); + hsfsts.hsf_status.flockdn = true; + ew32flash(ICH_FLASH_HSFSTS, hsfsts.regval); + + e1000_release_swflag_ich8lan(hw); +} + +/** * e1000_write_flash_data_ich8lan - Writes bytes to the NVM * @hw: pointer to the HW structure * @offset: The offset (in bytes) of the byte/word to read. @@ -1720,6 +1795,9 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw) ew32(CTRL, (ctrl | E1000_CTRL_RST)); msleep(20); + /* release the swflag because it is not reset by hardware reset */ + e1000_release_swflag_ich8lan(hw); + ret_val = e1000e_get_auto_rd_done(hw); if (ret_val) { /* diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index d266510c8a9..b81c4237b5d 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -47,7 +47,7 @@ #include "e1000.h" -#define DRV_VERSION "0.3.3.3-k2" +#define DRV_VERSION "0.3.3.3-k6" char e1000e_driver_name[] = "e1000e"; const char e1000e_driver_version[] = DRV_VERSION; @@ -1115,6 +1115,14 @@ static void e1000_clean_rx_ring(struct e1000_adapter *adapter) writel(0, adapter->hw.hw_addr + rx_ring->tail); } +static void e1000e_downshift_workaround(struct work_struct *work) +{ + struct e1000_adapter *adapter = container_of(work, + struct e1000_adapter, downshift_task); + + e1000e_gig_downshift_workaround_ich8lan(&adapter->hw); +} + /** * e1000_intr_msi - Interrupt Handler * @irq: interrupt number @@ -1139,7 +1147,7 @@ static irqreturn_t e1000_intr_msi(int irq, void *data) */ if ((adapter->flags & FLAG_LSC_GIG_SPEED_DROP) && (!(er32(STATUS) & E1000_STATUS_LU))) - e1000e_gig_downshift_workaround_ich8lan(hw); + schedule_work(&adapter->downshift_task); /* * 80003ES2LAN workaround-- For packet buffer work-around on @@ -1205,7 +1213,7 @@ static irqreturn_t e1000_intr(int irq, void *data) */ if ((adapter->flags & FLAG_LSC_GIG_SPEED_DROP) && (!(er32(STATUS) & E1000_STATUS_LU))) - e1000e_gig_downshift_workaround_ich8lan(hw); + schedule_work(&adapter->downshift_task); /* * 80003ES2LAN workaround-- @@ -2592,8 +2600,6 @@ static int __devinit e1000_sw_init(struct e1000_adapter *adapter) /* Explicitly disable IRQ since the NIC can be in any state. */ e1000_irq_disable(adapter); - spin_lock_init(&adapter->stats_lock); - set_bit(__E1000_DOWN, &adapter->state); return 0; @@ -2912,6 +2918,21 @@ static int e1000_set_mac(struct net_device *netdev, void *p) return 0; } +/** + * e1000e_update_phy_task - work thread to update phy + * @work: pointer to our work struct + * + * this worker thread exists because we must acquire a + * semaphore to read the phy, which we could msleep while + * waiting for it, and we can't msleep in a timer. + **/ +static void e1000e_update_phy_task(struct work_struct *work) +{ + struct e1000_adapter *adapter = container_of(work, + struct e1000_adapter, update_phy_task); + e1000_get_phy_info(&adapter->hw); +} + /* * Need to wait a few seconds after link up to get diagnostic information from * the phy @@ -2919,7 +2940,7 @@ static int e1000_set_mac(struct net_device *netdev, void *p) static void e1000_update_phy_info(unsigned long data) { struct e1000_adapter *adapter = (struct e1000_adapter *) data; - e1000_get_phy_info(&adapter->hw); + schedule_work(&adapter->update_phy_task); } /** @@ -2930,10 +2951,6 @@ void e1000e_update_stats(struct e1000_adapter *adapter) { struct e1000_hw *hw = &adapter->hw; struct pci_dev *pdev = adapter->pdev; - unsigned long irq_flags; - u16 phy_tmp; - -#define PHY_IDLE_ERROR_COUNT_MASK 0x00FF /* * Prevent stats update while adapter is being reset, or if the pci @@ -2944,14 +2961,6 @@ void e1000e_update_stats(struct e1000_adapter *adapter) if (pci_channel_offline(pdev)) return; - spin_lock_irqsave(&adapter->stats_lock, irq_flags); - - /* - * these counters are modified from e1000_adjust_tbi_stats, - * called from the interrupt context, so they must only - * be written while holding adapter->stats_lock - */ - adapter->stats.crcerrs += er32(CRCERRS); adapter->stats.gprc += er32(GPRC); adapter->stats.gorc += er32(GORCL); @@ -3022,21 +3031,10 @@ void e1000e_update_stats(struct e1000_adapter *adapter) /* Tx Dropped needs to be maintained elsewhere */ - /* Phy Stats */ - if (hw->phy.media_type == e1000_media_type_copper) { - if ((adapter->link_speed == SPEED_1000) && - (!e1e_rphy(hw, PHY_1000T_STATUS, &phy_tmp))) { - phy_tmp &= PHY_IDLE_ERROR_COUNT_MASK; - adapter->phy_stats.idle_errors += phy_tmp; - } - } - /* Management Stats */ adapter->stats.mgptc += er32(MGTPTC); adapter->stats.mgprc += er32(MGTPRC); adapter->stats.mgpdc += er32(MGTPDC); - - spin_unlock_irqrestore(&adapter->stats_lock, irq_flags); } /** @@ -3048,10 +3046,6 @@ static void e1000_phy_read_status(struct e1000_adapter *adapter) struct e1000_hw *hw = &adapter->hw; struct e1000_phy_regs *phy = &adapter->phy_regs; int ret_val; - unsigned long irq_flags; - - - spin_lock_irqsave(&adapter->stats_lock, irq_flags); if ((er32(STATUS) & E1000_STATUS_LU) && (adapter->hw.phy.media_type == e1000_media_type_copper)) { @@ -3082,8 +3076,6 @@ static void e1000_phy_read_status(struct e1000_adapter *adapter) phy->stat1000 = 0; phy->estatus = (ESTATUS_1000_TFULL | ESTATUS_1000_THALF); } - - spin_unlock_irqrestore(&adapter->stats_lock, irq_flags); } static void e1000_print_link_info(struct e1000_adapter *adapter) @@ -4467,6 +4459,8 @@ static int __devinit e1000_probe(struct pci_dev *pdev, adapter->bd_number = cards_found++; + e1000e_check_options(adapter); + /* setup adapter struct */ err = e1000_sw_init(adapter); if (err) @@ -4482,6 +4476,10 @@ static int __devinit e1000_probe(struct pci_dev *pdev, if (err) goto err_hw_init; + if ((adapter->flags & FLAG_IS_ICH) && + (adapter->flags & FLAG_READ_ONLY_NVM)) + e1000e_write_protect_nvm_ich8lan(&adapter->hw); + hw->mac.ops.get_bus_info(&adapter->hw); adapter->hw.phy.autoneg_wait_to_complete = 0; @@ -4572,8 +4570,8 @@ static int __devinit e1000_probe(struct pci_dev *pdev, INIT_WORK(&adapter->reset_task, e1000_reset_task); INIT_WORK(&adapter->watchdog_task, e1000_watchdog_task); - - e1000e_check_options(adapter); + INIT_WORK(&adapter->downshift_task, e1000e_downshift_workaround); + INIT_WORK(&adapter->update_phy_task, e1000e_update_phy_task); /* Initialize link parameters. User can change them with ethtool */ adapter->hw.mac.autoneg = 1; diff --git a/drivers/net/e1000e/param.c b/drivers/net/e1000e/param.c index ed912e023a7..d91dbf7ba43 100644 --- a/drivers/net/e1000e/param.c +++ b/drivers/net/e1000e/param.c @@ -133,6 +133,15 @@ E1000_PARAM(SmartPowerDownEnable, "Enable PHY smart power down"); */ E1000_PARAM(KumeranLockLoss, "Enable Kumeran lock loss workaround"); +/* + * Write Protect NVM + * + * Valid Range: 0, 1 + * + * Default Value: 1 (enabled) + */ +E1000_PARAM(WriteProtectNVM, "Write-protect NVM [WARNING: disabling this can lead to corrupted NVM]"); + struct e1000_option { enum { enable_option, range_option, list_option } type; const char *name; @@ -388,4 +397,25 @@ void __devinit e1000e_check_options(struct e1000_adapter *adapter) opt.def); } } + { /* Write-protect NVM */ + const struct e1000_option opt = { + .type = enable_option, + .name = "Write-protect NVM", + .err = "defaulting to Enabled", + .def = OPTION_ENABLED + }; + + if (adapter->flags & FLAG_IS_ICH) { + if (num_WriteProtectNVM > bd) { + unsigned int write_protect_nvm = WriteProtectNVM[bd]; + e1000_validate_option(&write_protect_nvm, &opt, + adapter); + if (write_protect_nvm) + adapter->flags |= FLAG_READ_ONLY_NVM; + } else { + if (opt.def) + adapter->flags |= FLAG_READ_ONLY_NVM; + } + } + } } diff --git a/drivers/net/wireless/ath9k/core.c b/drivers/net/wireless/ath9k/core.c index f6c45288d0e..87e37bc3914 100644 --- a/drivers/net/wireless/ath9k/core.c +++ b/drivers/net/wireless/ath9k/core.c @@ -294,8 +294,6 @@ static int ath_stop(struct ath_softc *sc) * hardware is gone (invalid). */ - if (!sc->sc_invalid) - ath9k_hw_set_interrupts(ah, 0); ath_draintxq(sc, false); if (!sc->sc_invalid) { ath_stoprecv(sc); @@ -797,6 +795,12 @@ int ath_open(struct ath_softc *sc, struct ath9k_channel *initial_chan) if (ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT) sc->sc_imask |= ATH9K_INT_CST; + /* Note: We disable MIB interrupts for now as we don't yet + * handle processing ANI, otherwise you will get an interrupt + * storm after about 7 hours of usage making the system unusable + * with huge latency. Once we do have ANI processing included + * we can re-enable this interrupt. */ +#if 0 /* * Enable MIB interrupts when there are hardware phy counters. * Note we only do this (at the moment) for station mode. @@ -804,6 +808,7 @@ int ath_open(struct ath_softc *sc, struct ath9k_channel *initial_chan) if (ath9k_hw_phycounters(ah) && ((sc->sc_opmode == ATH9K_M_STA) || (sc->sc_opmode == ATH9K_M_IBSS))) sc->sc_imask |= ATH9K_INT_MIB; +#endif /* * Some hardware processes the TIM IE and fires an * interrupt when the TIM bit is set. For hardware @@ -1336,6 +1341,8 @@ void ath_deinit(struct ath_softc *sc) DPRINTF(sc, ATH_DBG_CONFIG, "%s\n", __func__); + tasklet_kill(&sc->intr_tq); + tasklet_kill(&sc->bcon_tasklet); ath_stop(sc); if (!sc->sc_invalid) ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE); diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h index 4ee695b76b8..2f84093331e 100644 --- a/drivers/net/wireless/ath9k/core.h +++ b/drivers/net/wireless/ath9k/core.h @@ -974,7 +974,6 @@ struct ath_softc { u32 sc_keymax; /* size of key cache */ DECLARE_BITMAP(sc_keymap, ATH_KEYMAX); /* key use bit map */ u8 sc_splitmic; /* split TKIP MIC keys */ - int sc_keytype; /* RX */ struct list_head sc_rxbuf; diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index 99badf1404c..acebdf1d20a 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c @@ -206,8 +206,6 @@ static int ath_key_config(struct ath_softc *sc, if (!ret) return -EIO; - if (mac) - sc->sc_keytype = hk.kv_type; return 0; } @@ -778,7 +776,6 @@ static int ath9k_set_key(struct ieee80211_hw *hw, case DISABLE_KEY: ath_key_delete(sc, key); clear_bit(key->keyidx, sc->sc_keymap); - sc->sc_keytype = ATH9K_CIPHER_CLR; break; default: ret = -EINVAL; @@ -1414,10 +1411,17 @@ static void ath_pci_remove(struct pci_dev *pdev) { struct ieee80211_hw *hw = pci_get_drvdata(pdev); struct ath_softc *sc = hw->priv; + enum ath9k_int status; - if (pdev->irq) + if (pdev->irq) { + ath9k_hw_set_interrupts(sc->sc_ah, 0); + /* clear the ISR */ + ath9k_hw_getisr(sc->sc_ah, &status); + sc->sc_invalid = 1; free_irq(pdev->irq, sc); + } ath_detach(sc); + pci_iounmap(pdev, sc->mem); pci_release_region(pdev, 0); pci_disable_device(pdev); diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k/xmit.c index 550129f717e..8b332e11a65 100644 --- a/drivers/net/wireless/ath9k/xmit.c +++ b/drivers/net/wireless/ath9k/xmit.c @@ -315,11 +315,11 @@ static int ath_tx_prepare(struct ath_softc *sc, txctl->keyix = tx_info->control.hw_key->hw_key_idx; txctl->frmlen += tx_info->control.icv_len; - if (sc->sc_keytype == ATH9K_CIPHER_WEP) + if (tx_info->control.hw_key->alg == ALG_WEP) txctl->keytype = ATH9K_KEY_TYPE_WEP; - else if (sc->sc_keytype == ATH9K_CIPHER_TKIP) + else if (tx_info->control.hw_key->alg == ALG_TKIP) txctl->keytype = ATH9K_KEY_TYPE_TKIP; - else if (sc->sc_keytype == ATH9K_CIPHER_AES_CCM) + else if (tx_info->control.hw_key->alg == ALG_CCMP) txctl->keytype = ATH9K_KEY_TYPE_AES; } diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c index da8b7433e3a..a60ae86bd5c 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.c +++ b/drivers/net/wireless/zd1211rw/zd_usb.c @@ -58,6 +58,7 @@ static struct usb_device_id usb_ids[] = { { USB_DEVICE(0x0586, 0x3407), .driver_info = DEVICE_ZD1211 }, { USB_DEVICE(0x129b, 0x1666), .driver_info = DEVICE_ZD1211 }, { USB_DEVICE(0x157e, 0x300a), .driver_info = DEVICE_ZD1211 }, + { USB_DEVICE(0x0105, 0x145f), .driver_info = DEVICE_ZD1211 }, /* ZD1211B */ { USB_DEVICE(0x0ace, 0x1215), .driver_info = DEVICE_ZD1211B }, { USB_DEVICE(0x157e, 0x300d), .driver_info = DEVICE_ZD1211B }, diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 9c718583a23..77baff022f7 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -16,6 +16,7 @@ #include <linux/kernel.h> +#include <linux/sched.h> #include <linux/pci.h> #include <linux/stat.h> #include <linux/topology.h> @@ -484,6 +485,21 @@ pci_mmap_legacy_mem(struct kobject *kobj, struct bin_attribute *attr, #endif /* HAVE_PCI_LEGACY */ #ifdef HAVE_PCI_MMAP + +static int pci_mmap_fits(struct pci_dev *pdev, int resno, struct vm_area_struct *vma) +{ + unsigned long nr, start, size; + + nr = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; + start = vma->vm_pgoff; + size = pci_resource_len(pdev, resno) >> PAGE_SHIFT; + if (start < size && size - start >= nr) + return 1; + WARN(1, "process \"%s\" tried to map 0x%08lx-0x%08lx on %s BAR %d (size 0x%08lx)\n", + current->comm, start, start+nr, pci_name(pdev), resno, size); + return 0; +} + /** * pci_mmap_resource - map a PCI resource into user memory space * @kobj: kobject for mapping @@ -510,6 +526,9 @@ pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr, if (i >= PCI_ROM_RESOURCE) return -ENODEV; + if (!pci_mmap_fits(pdev, i, vma)) + return -EINVAL; + /* pci_mmap_page_range() expects the same kind of entry as coming * from /proc/bus/pci/ which is a "user visible" value. If this is * different from the resource itself, arch will do necessary fixup. diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index 9a7c9e1408a..851f5b83cdb 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c @@ -527,7 +527,7 @@ static int pcie_aspm_sanity_check(struct pci_dev *pdev) */ pci_read_config_dword(child_dev, child_pos + PCI_EXP_DEVCAP, ®32); - if (!(reg32 & PCI_EXP_DEVCAP_RBER && !aspm_force)) { + if (!(reg32 & PCI_EXP_DEVCAP_RBER) && !aspm_force) { printk("Pre-1.1 PCIe device detected, " "disable ASPM for %s. It can be enabled forcedly" " with 'pcie_aspm=force'\n", pci_name(pdev)); diff --git a/drivers/pci/search.c b/drivers/pci/search.c index 3b3b5f17879..4edfc4731bd 100644 --- a/drivers/pci/search.c +++ b/drivers/pci/search.c @@ -162,7 +162,7 @@ EXPORT_SYMBOL(pci_find_slot); * time. */ struct pci_dev *pci_find_device(unsigned int vendor, unsigned int device, - const struct pci_dev *from) + struct pci_dev *from) { struct pci_dev *pdev; @@ -263,7 +263,7 @@ static int match_pci_dev_by_id(struct device *dev, void *data) * this file. */ static struct pci_dev *pci_get_dev_by_id(const struct pci_device_id *id, - const struct pci_dev *from) + struct pci_dev *from) { struct device *dev; struct device *dev_start = NULL; @@ -303,7 +303,7 @@ static struct pci_dev *pci_get_dev_by_id(const struct pci_device_id *id, */ struct pci_dev *pci_get_subsys(unsigned int vendor, unsigned int device, unsigned int ss_vendor, unsigned int ss_device, - const struct pci_dev *from) + struct pci_dev *from) { struct pci_dev *pdev; struct pci_device_id *id; diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index 4174d9656e3..34c83d3ca0f 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c @@ -427,6 +427,18 @@ static int pcmcia_device_probe(struct device * dev) p_drv = to_pcmcia_drv(dev->driver); s = p_dev->socket; + /* The PCMCIA code passes the match data in via dev->driver_data + * which is an ugly hack. Once the driver probe is called it may + * and often will overwrite the match data so we must save it first + * + * handle pseudo multifunction devices: + * there are at most two pseudo multifunction devices. + * if we're matching against the first, schedule a + * call which will then check whether there are two + * pseudo devices, and if not, add the second one. + */ + did = p_dev->dev.driver_data; + ds_dbg(1, "trying to bind %s to %s\n", p_dev->dev.bus_id, p_drv->drv.name); @@ -455,21 +467,14 @@ static int pcmcia_device_probe(struct device * dev) goto put_module; } - /* handle pseudo multifunction devices: - * there are at most two pseudo multifunction devices. - * if we're matching against the first, schedule a - * call which will then check whether there are two - * pseudo devices, and if not, add the second one. - */ - did = p_dev->dev.driver_data; if (did && (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) && (p_dev->socket->device_count == 1) && (p_dev->device_no == 0)) pcmcia_add_device_later(p_dev->socket, 0); - put_module: +put_module: if (ret) module_put(p_drv->owner); - put_dev: +put_dev: if (ret) put_device(dev); return (ret); diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c index f118252f3a9..52e2743b04e 100644 --- a/drivers/rtc/rtc-dev.c +++ b/drivers/rtc/rtc-dev.c @@ -422,6 +422,12 @@ done: return err; } +static int rtc_dev_fasync(int fd, struct file *file, int on) +{ + struct rtc_device *rtc = file->private_data; + return fasync_helper(fd, file, on, &rtc->async_queue); +} + static int rtc_dev_release(struct inode *inode, struct file *file) { struct rtc_device *rtc = file->private_data; @@ -434,16 +440,13 @@ static int rtc_dev_release(struct inode *inode, struct file *file) if (rtc->ops->release) rtc->ops->release(rtc->dev.parent); + if (file->f_flags & FASYNC) + rtc_dev_fasync(-1, file, 0); + clear_bit_unlock(RTC_DEV_BUSY, &rtc->flags); return 0; } -static int rtc_dev_fasync(int fd, struct file *file, int on) -{ - struct rtc_device *rtc = file->private_data; - return fasync_helper(fd, file, on, &rtc->async_queue); -} - static const struct file_operations rtc_dev_fops = { .owner = THIS_MODULE, .llseek = no_llseek, diff --git a/drivers/s390/cio/qdio_setup.c b/drivers/s390/cio/qdio_setup.c index 1679e2f91c9..a0b6b46e746 100644 --- a/drivers/s390/cio/qdio_setup.c +++ b/drivers/s390/cio/qdio_setup.c @@ -447,51 +447,36 @@ void qdio_print_subchannel_info(struct qdio_irq *irq_ptr, { char s[80]; - sprintf(s, "%s sc:%x ", cdev->dev.bus_id, irq_ptr->schid.sch_no); - + sprintf(s, "qdio: %s ", dev_name(&cdev->dev)); switch (irq_ptr->qib.qfmt) { case QDIO_QETH_QFMT: - sprintf(s + strlen(s), "OSADE "); + sprintf(s + strlen(s), "OSA "); break; case QDIO_ZFCP_QFMT: sprintf(s + strlen(s), "ZFCP "); break; case QDIO_IQDIO_QFMT: - sprintf(s + strlen(s), "HiperSockets "); + sprintf(s + strlen(s), "HS "); break; } - sprintf(s + strlen(s), "using: "); - - if (!is_thinint_irq(irq_ptr)) - sprintf(s + strlen(s), "no"); - sprintf(s + strlen(s), "AdapterInterrupts "); - if (!(irq_ptr->sch_token != 0)) - sprintf(s + strlen(s), "no"); - sprintf(s + strlen(s), "QEBSM "); - if (!(irq_ptr->qib.ac & QIB_AC_OUTBOUND_PCI_SUPPORTED)) - sprintf(s + strlen(s), "no"); - sprintf(s + strlen(s), "OutboundPCI "); - if (!css_general_characteristics.aif_tdd) - sprintf(s + strlen(s), "no"); - sprintf(s + strlen(s), "TDD\n"); - printk(KERN_INFO "qdio: %s", s); - - memset(s, 0, sizeof(s)); - sprintf(s, "%s SIGA required: ", cdev->dev.bus_id); - if (irq_ptr->siga_flag.input) - sprintf(s + strlen(s), "Read "); - if (irq_ptr->siga_flag.output) - sprintf(s + strlen(s), "Write "); - if (irq_ptr->siga_flag.sync) - sprintf(s + strlen(s), "Sync "); - if (!irq_ptr->siga_flag.no_sync_ti) - sprintf(s + strlen(s), "SyncAI "); - if (!irq_ptr->siga_flag.no_sync_out_ti) - sprintf(s + strlen(s), "SyncOutAI "); - if (!irq_ptr->siga_flag.no_sync_out_pci) - sprintf(s + strlen(s), "SyncOutPCI"); + sprintf(s + strlen(s), "on SC %x using ", irq_ptr->schid.sch_no); + sprintf(s + strlen(s), "AI:%d ", is_thinint_irq(irq_ptr)); + sprintf(s + strlen(s), "QEBSM:%d ", (irq_ptr->sch_token) ? 1 : 0); + sprintf(s + strlen(s), "PCI:%d ", + (irq_ptr->qib.ac & QIB_AC_OUTBOUND_PCI_SUPPORTED) ? 1 : 0); + sprintf(s + strlen(s), "TDD:%d ", css_general_characteristics.aif_tdd); + sprintf(s + strlen(s), "SIGA:"); + sprintf(s + strlen(s), "%s", (irq_ptr->siga_flag.input) ? "R" : " "); + sprintf(s + strlen(s), "%s", (irq_ptr->siga_flag.output) ? "W" : " "); + sprintf(s + strlen(s), "%s", (irq_ptr->siga_flag.sync) ? "S" : " "); + sprintf(s + strlen(s), "%s", + (!irq_ptr->siga_flag.no_sync_ti) ? "A" : " "); + sprintf(s + strlen(s), "%s", + (!irq_ptr->siga_flag.no_sync_out_ti) ? "O" : " "); + sprintf(s + strlen(s), "%s", + (!irq_ptr->siga_flag.no_sync_out_pci) ? "P" : " "); sprintf(s + strlen(s), "\n"); - printk(KERN_INFO "qdio: %s", s); + printk(KERN_INFO "%s", s); } int __init qdio_setup_init(void) diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 45a3b93eed5..bf41887cdd6 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -1834,7 +1834,6 @@ clear_risc_ints: WRT_REG_WORD(®->isp.hccr, HCCR_CLR_HOST_INT); } spin_unlock_irq(&ha->hardware_lock); - ha->isp_ops->enable_intrs(ha); fail: return ret; diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 26afe44265c..6d0f0e5f282 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -1740,6 +1740,8 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) if (ret) goto probe_failed; + ha->isp_ops->enable_intrs(ha); + scsi_scan_host(host); qla2x00_alloc_sysfs_attr(ha); diff --git a/drivers/scsi/qlogicpti.c b/drivers/scsi/qlogicpti.c index 4a1cf6377f6..90535089672 100644 --- a/drivers/scsi/qlogicpti.c +++ b/drivers/scsi/qlogicpti.c @@ -914,6 +914,7 @@ static inline int load_cmd(struct scsi_cmnd *Cmnd, struct Command_Entry *cmd, ds[i].d_count = sg_dma_len(s); } sg_count -= n; + sg = s; } } else { cmd->dataseg[0].d_base = 0; diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index ff5d56b3ee4..62307bd794a 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -852,7 +852,7 @@ static void scsi_end_bidi_request(struct scsi_cmnd *cmd) void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) { int result = cmd->result; - int this_count = scsi_bufflen(cmd); + int this_count; struct request_queue *q = cmd->device->request_queue; struct request *req = cmd->request; int error = 0; @@ -908,6 +908,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) */ if (scsi_end_request(cmd, error, good_bytes, result == 0) == NULL) return; + this_count = blk_rq_bytes(req); /* good_bytes = 0, or (inclusive) there were leftovers and * result = 0, so scsi_end_request couldn't retry. diff --git a/drivers/serial/atmel_serial.c b/drivers/serial/atmel_serial.c index 3a6da80b081..61fb8b6d19a 100644 --- a/drivers/serial/atmel_serial.c +++ b/drivers/serial/atmel_serial.c @@ -131,7 +131,8 @@ struct atmel_uart_char { struct atmel_uart_port { struct uart_port uart; /* uart */ struct clk *clk; /* uart clock */ - unsigned short suspended; /* is port suspended? */ + int may_wakeup; /* cached value of device_may_wakeup for times we need to disable it */ + u32 backup_imr; /* IMR saved during suspend */ int break_active; /* break being received */ short use_dma_rx; /* enable PDC receiver */ @@ -984,8 +985,15 @@ static void atmel_serial_pm(struct uart_port *port, unsigned int state, * This is called on uart_open() or a resume event. */ clk_enable(atmel_port->clk); + + /* re-enable interrupts if we disabled some on suspend */ + UART_PUT_IER(port, atmel_port->backup_imr); break; case 3: + /* Back up the interrupt mask and disable all interrupts */ + atmel_port->backup_imr = UART_GET_IMR(port); + UART_PUT_IDR(port, -1); + /* * Disable the peripheral clock for this serial port. * This is called on uart_close() or a suspend event. @@ -1475,13 +1483,12 @@ static int atmel_serial_suspend(struct platform_device *pdev, cpu_relax(); } - if (device_may_wakeup(&pdev->dev) - && !atmel_serial_clk_will_stop()) - enable_irq_wake(port->irq); - else { - uart_suspend_port(&atmel_uart, port); - atmel_port->suspended = 1; - } + /* we can not wake up if we're running on slow clock */ + atmel_port->may_wakeup = device_may_wakeup(&pdev->dev); + if (atmel_serial_clk_will_stop()) + device_set_wakeup_enable(&pdev->dev, 0); + + uart_suspend_port(&atmel_uart, port); return 0; } @@ -1491,11 +1498,8 @@ static int atmel_serial_resume(struct platform_device *pdev) struct uart_port *port = platform_get_drvdata(pdev); struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); - if (atmel_port->suspended) { - uart_resume_port(&atmel_uart, port); - atmel_port->suspended = 0; - } else - disable_irq_wake(port->irq); + uart_resume_port(&atmel_uart, port); + device_set_wakeup_enable(&pdev->dev, atmel_port->may_wakeup); return 0; } @@ -1513,6 +1517,8 @@ static int __devinit atmel_serial_probe(struct platform_device *pdev) BUILD_BUG_ON(!is_power_of_2(ATMEL_SERIAL_RINGSIZE)); port = &atmel_ports[pdev->id]; + port->backup_imr = 0; + atmel_init_port(port, pdev); if (!atmel_use_dma_rx(&port->uart)) { diff --git a/drivers/spi/orion_spi.c b/drivers/spi/orion_spi.c index c4eaacd6e55..b872bfaf4bd 100644 --- a/drivers/spi/orion_spi.c +++ b/drivers/spi/orion_spi.c @@ -427,7 +427,7 @@ static int orion_spi_transfer(struct spi_device *spi, struct spi_message *m) goto msg_rejected; } - if (t->speed_hz < orion_spi->min_speed) { + if (t->speed_hz && t->speed_hz < orion_spi->min_speed) { dev_err(&spi->dev, "message rejected : " "device min speed (%d Hz) exceeds " diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c index 0e53354c1cf..d47d3636227 100644 --- a/drivers/spi/pxa2xx_spi.c +++ b/drivers/spi/pxa2xx_spi.c @@ -49,7 +49,7 @@ MODULE_ALIAS("platform:pxa2xx-spi"); #define DMA_INT_MASK (DCSR_ENDINTR | DCSR_STARTINTR | DCSR_BUSERR) #define RESET_DMA_CHANNEL (DCSR_NODESC | DMA_INT_MASK) -#define IS_DMA_ALIGNED(x) (((x) & 0x07) == 0) +#define IS_DMA_ALIGNED(x) ((((u32)(x)) & 0x07) == 0) #define MAX_DMA_LEN 8191 /* @@ -896,7 +896,7 @@ static void pump_transfers(unsigned long data) || transfer->rx_dma || transfer->tx_dma) { dev_err(&drv_data->pdev->dev, "pump_transfers: mapped transfer length " - "of %lu is greater than %d\n", + "of %u is greater than %d\n", transfer->len, MAX_DMA_LEN); message->status = -EINVAL; giveback(drv_data); diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c index 87ab2443e66..0ffabf5c0b6 100644 --- a/drivers/ssb/main.c +++ b/drivers/ssb/main.c @@ -471,6 +471,7 @@ static int ssb_devices_register(struct ssb_bus *bus) #endif break; case SSB_BUSTYPE_SSB: + dev->dma_mask = &dev->coherent_dma_mask; break; } diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 8abd4e59bf4..8ab389dca2b 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -1876,7 +1876,8 @@ int usb_add_hcd(struct usb_hcd *hcd, * with IRQF_SHARED. As usb_hcd_irq() will always disable * interrupts we can remove it here. */ - irqflags &= ~IRQF_DISABLED; + if (irqflags & IRQF_SHARED) + irqflags &= ~IRQF_DISABLED; snprintf(hcd->irq_descr, sizeof(hcd->irq_descr), "%s:usb%d", hcd->driver->description, hcd->self.busnum); diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 6a5cb018383..d99963873e3 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -2683,35 +2683,17 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, USB_PORT_STAT_C_ENABLE); #endif - /* Try to use the debounce delay for protection against - * port-enable changes caused, for example, by EMI. - */ - if (portchange & (USB_PORT_STAT_C_CONNECTION | - USB_PORT_STAT_C_ENABLE)) { - status = hub_port_debounce(hub, port1); - if (status < 0) { - if (printk_ratelimit()) - dev_err (hub_dev, "connect-debounce failed, " - "port %d disabled\n", port1); - portstatus &= ~USB_PORT_STAT_CONNECTION; - } else { - portstatus = status; - } - } - /* Try to resuscitate an existing device */ udev = hdev->children[port1-1]; if ((portstatus & USB_PORT_STAT_CONNECTION) && udev && udev->state != USB_STATE_NOTATTACHED) { - usb_lock_device(udev); if (portstatus & USB_PORT_STAT_ENABLE) { status = 0; /* Nothing to do */ - } else if (!udev->persist_enabled) { - status = -ENODEV; /* Mustn't resuscitate */ #ifdef CONFIG_USB_SUSPEND - } else if (udev->state == USB_STATE_SUSPENDED) { + } else if (udev->state == USB_STATE_SUSPENDED && + udev->persist_enabled) { /* For a suspended device, treat this as a * remote wakeup event. */ @@ -2726,7 +2708,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, #endif } else { - status = usb_reset_device(udev); + status = -ENODEV; /* Don't resuscitate */ } usb_unlock_device(udev); @@ -2741,6 +2723,19 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, usb_disconnect(&hdev->children[port1-1]); clear_bit(port1, hub->change_bits); + if (portchange & (USB_PORT_STAT_C_CONNECTION | + USB_PORT_STAT_C_ENABLE)) { + status = hub_port_debounce(hub, port1); + if (status < 0) { + if (printk_ratelimit()) + dev_err(hub_dev, "connect-debounce failed, " + "port %d disabled\n", port1); + portstatus &= ~USB_PORT_STAT_CONNECTION; + } else { + portstatus = status; + } + } + /* Return now if debouncing failed or nothing is connected */ if (!(portstatus & USB_PORT_STAT_CONNECTION)) { @@ -2748,7 +2743,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, if ((wHubCharacteristics & HUB_CHAR_LPSM) < 2 && !(portstatus & (1 << USB_PORT_FEAT_POWER))) set_port_feature(hdev, port1, USB_PORT_FEAT_POWER); - + if (portstatus & USB_PORT_STAT_ENABLE) goto done; return; diff --git a/drivers/usb/gadget/fsl_usb2_udc.c b/drivers/usb/gadget/fsl_usb2_udc.c index 1cfccf102a2..45ad556169f 100644 --- a/drivers/usb/gadget/fsl_usb2_udc.c +++ b/drivers/usb/gadget/fsl_usb2_udc.c @@ -223,7 +223,7 @@ static int dr_controller_setup(struct fsl_udc *udc) fsl_writel(tmp, &dr_regs->endpointlistaddr); VDBG("vir[qh_base] is %p phy[qh_base] is 0x%8x reg is 0x%8x", - (int)udc->ep_qh, (int)tmp, + udc->ep_qh, (int)tmp, fsl_readl(&dr_regs->endpointlistaddr)); /* Config PHY interface */ diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c index 574c53831a0..bb54cca4c54 100644 --- a/drivers/usb/gadget/omap_udc.c +++ b/drivers/usb/gadget/omap_udc.c @@ -787,7 +787,7 @@ static void dma_channel_claim(struct omap_ep *ep, unsigned channel) omap_set_dma_dest_params(ep->lch, OMAP_DMA_PORT_TIPB, OMAP_DMA_AMODE_CONSTANT, - (unsigned long) io_v2p(UDC_DATA_DMA), + UDC_DATA_DMA, 0, 0); } } else { @@ -804,7 +804,7 @@ static void dma_channel_claim(struct omap_ep *ep, unsigned channel) omap_set_dma_src_params(ep->lch, OMAP_DMA_PORT_TIPB, OMAP_DMA_AMODE_CONSTANT, - (unsigned long) io_v2p(UDC_DATA_DMA), + UDC_DATA_DMA, 0, 0); /* EMIFF or SDRC */ omap_set_dma_dest_burst_mode(ep->lch, diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index d9d53f289ca..8409e0705d6 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -145,16 +145,6 @@ static int handshake (struct ehci_hcd *ehci, void __iomem *ptr, return -ETIMEDOUT; } -static int handshake_on_error_set_halt(struct ehci_hcd *ehci, void __iomem *ptr, - u32 mask, u32 done, int usec) -{ - int error = handshake(ehci, ptr, mask, done, usec); - if (error) - ehci_to_hcd(ehci)->state = HC_STATE_HALT; - - return error; -} - /* force HC to halt state from unknown (EHCI spec section 2.3) */ static int ehci_halt (struct ehci_hcd *ehci) { @@ -173,6 +163,22 @@ static int ehci_halt (struct ehci_hcd *ehci) STS_HALT, STS_HALT, 16 * 125); } +static int handshake_on_error_set_halt(struct ehci_hcd *ehci, void __iomem *ptr, + u32 mask, u32 done, int usec) +{ + int error; + + error = handshake(ehci, ptr, mask, done, usec); + if (error) { + ehci_halt(ehci); + ehci_to_hcd(ehci)->state = HC_STATE_HALT; + ehci_err(ehci, "force halt; handhake %p %08x %08x -> %d\n", + ptr, mask, done, error); + } + + return error; +} + /* put TDI/ARC silicon into EHCI mode */ static void tdi_reset (struct ehci_hcd *ehci) { diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index b7853c8bac0..4a0c5a78b2e 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c @@ -437,6 +437,9 @@ static int enable_periodic (struct ehci_hcd *ehci) u32 cmd; int status; + if (ehci->periodic_sched++) + return 0; + /* did clearing PSE did take effect yet? * takes effect only at frame boundaries... */ @@ -461,6 +464,9 @@ static int disable_periodic (struct ehci_hcd *ehci) u32 cmd; int status; + if (--ehci->periodic_sched) + return 0; + /* did setting PSE not take effect yet? * takes effect only at frame boundaries... */ @@ -544,13 +550,10 @@ static int qh_link_periodic (struct ehci_hcd *ehci, struct ehci_qh *qh) : (qh->usecs * 8); /* maybe enable periodic schedule processing */ - if (!ehci->periodic_sched++) - return enable_periodic (ehci); - - return 0; + return enable_periodic(ehci); } -static void qh_unlink_periodic (struct ehci_hcd *ehci, struct ehci_qh *qh) +static int qh_unlink_periodic(struct ehci_hcd *ehci, struct ehci_qh *qh) { unsigned i; unsigned period; @@ -586,9 +589,7 @@ static void qh_unlink_periodic (struct ehci_hcd *ehci, struct ehci_qh *qh) qh_put (qh); /* maybe turn off periodic schedule */ - ehci->periodic_sched--; - if (!ehci->periodic_sched) - (void) disable_periodic (ehci); + return disable_periodic(ehci); } static void intr_deschedule (struct ehci_hcd *ehci, struct ehci_qh *qh) @@ -1562,9 +1563,7 @@ itd_link_urb ( urb->hcpriv = NULL; timer_action (ehci, TIMER_IO_WATCHDOG); - if (unlikely (!ehci->periodic_sched++)) - return enable_periodic (ehci); - return 0; + return enable_periodic(ehci); } #define ISO_ERRS (EHCI_ISOC_BUF_ERR | EHCI_ISOC_BABBLE | EHCI_ISOC_XACTERR) @@ -1642,7 +1641,7 @@ itd_complete ( ehci_urb_done(ehci, urb, 0); retval = true; urb = NULL; - ehci->periodic_sched--; + (void) disable_periodic(ehci); ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--; if (unlikely (list_empty (&stream->td_list))) { @@ -1951,9 +1950,7 @@ sitd_link_urb ( urb->hcpriv = NULL; timer_action (ehci, TIMER_IO_WATCHDOG); - if (!ehci->periodic_sched++) - return enable_periodic (ehci); - return 0; + return enable_periodic(ehci); } /*-------------------------------------------------------------------------*/ @@ -2019,7 +2016,7 @@ sitd_complete ( ehci_urb_done(ehci, urb, 0); retval = true; urb = NULL; - ehci->periodic_sched--; + (void) disable_periodic(ehci); ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--; if (list_empty (&stream->td_list)) { @@ -2243,8 +2240,7 @@ restart: if (unlikely (modified)) { if (likely(ehci->periodic_sched > 0)) goto restart; - /* maybe we can short-circuit this scan! */ - disable_periodic(ehci); + /* short-circuit this scan */ now_uframe = clock; break; } diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig index a0017486ad4..58b2b8fc943 100644 --- a/drivers/usb/musb/Kconfig +++ b/drivers/usb/musb/Kconfig @@ -9,6 +9,7 @@ comment "Enable Host or Gadget support to see Inventra options" # (M)HDRC = (Multipoint) Highspeed Dual-Role Controller config USB_MUSB_HDRC depends on (USB || USB_GADGET) && HAVE_CLK + depends on !SUPERH select TWL4030_USB if MACH_OMAP_3430SDP tristate 'Inventra Highspeed Dual Role Controller (TI, ...)' help diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index c5b8f0296fc..128e949db47 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -100,8 +100,8 @@ #include <linux/io.h> #ifdef CONFIG_ARM -#include <asm/arch/hardware.h> -#include <asm/arch/memory.h> +#include <mach/hardware.h> +#include <mach/memory.h> #include <asm/mach-types.h> #endif diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index 298b22e6ad0..9d2dcb121c5 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -35,8 +35,8 @@ #include <linux/io.h> #include <asm/mach-types.h> -#include <asm/arch/hardware.h> -#include <asm/arch/mux.h> +#include <mach/hardware.h> +#include <mach/mux.h> #include "musb_core.h" #include "omap2430.h" diff --git a/drivers/usb/musb/omap2430.h b/drivers/usb/musb/omap2430.h index 786a62071f7..dc7670718cd 100644 --- a/drivers/usb/musb/omap2430.h +++ b/drivers/usb/musb/omap2430.h @@ -11,8 +11,8 @@ #define __MUSB_OMAP243X_H__ #if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3430) -#include <asm/arch/hardware.h> -#include <asm/arch/usb.h> +#include <mach/hardware.h> +#include <mach/usb.h> /* * OMAP2430-specific definitions diff --git a/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp2101.c index 442cba69cce..1279553381e 100644 --- a/drivers/usb/serial/cp2101.c +++ b/drivers/usb/serial/cp2101.c @@ -72,6 +72,7 @@ static struct usb_device_id id_table [] = { { USB_DEVICE(0x10C4, 0x80CA) }, /* Degree Controls Inc */ { USB_DEVICE(0x10C4, 0x80DD) }, /* Tracient RFID */ { USB_DEVICE(0x10C4, 0x80F6) }, /* Suunto sports instrument */ + { USB_DEVICE(0x10C4, 0x8115) }, /* Arygon NFC/Mifare Reader */ { USB_DEVICE(0x10C4, 0x813D) }, /* Burnside Telecom Deskmobile */ { USB_DEVICE(0x10C4, 0x814A) }, /* West Mountain Radio RIGblaster P&P */ { USB_DEVICE(0x10C4, 0x814B) }, /* West Mountain Radio RIGtalk */ @@ -83,6 +84,7 @@ static struct usb_device_id id_table [] = { { USB_DEVICE(0x10C4, 0x81E7) }, /* Aerocomm Radio */ { USB_DEVICE(0x10C4, 0x8218) }, /* Lipowsky Industrie Elektronik GmbH, HARP-1 */ { USB_DEVICE(0x10c4, 0x8293) }, /* Telegesys ETRX2USB */ + { USB_DEVICE(0x10C4, 0x8341) }, /* Siemens MC35PU GPRS Modem */ { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */ { USB_DEVICE(0x10C4, 0xF001) }, /* Elan Digital Systems USBscope50 */ @@ -93,6 +95,7 @@ static struct usb_device_id id_table [] = { { USB_DEVICE(0x13AD, 0x9999) }, /* Baltech card reader */ { USB_DEVICE(0x166A, 0x0303) }, /* Clipsal 5500PCU C-Bus USB interface */ { USB_DEVICE(0x16D6, 0x0001) }, /* Jablotron serial interface */ + { USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */ { } /* Terminating Entry */ }; diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 984f6eff4c4..3dc93b542b3 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -654,6 +654,9 @@ static struct usb_device_id id_table_combined [] = { .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_USB60F) }, { USB_DEVICE(FTDI_VID, FTDI_REU_TINY_PID) }, + { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO4x4_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_DOMINTELL_DGQG_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_DOMINTELL_DUSB_PID) }, { }, /* Optional parameter entry */ { } /* Terminating entry */ }; diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index 382265bba96..8a5b6df3a97 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h @@ -750,6 +750,7 @@ #define PAPOUCH_VID 0x5050 /* Vendor ID */ #define PAPOUCH_TMU_PID 0x0400 /* TMU USB Thermometer */ +#define PAPOUCH_QUIDO4x4_PID 0x0900 /* Quido 4/4 Module */ /* * ACG Identification Technologies GmbH products (http://www.acg.de/). @@ -838,6 +839,10 @@ /* Rig Expert Ukraine devices */ #define FTDI_REU_TINY_PID 0xED22 /* RigExpert Tiny */ +/* Domintell products http://www.domintell.com */ +#define FTDI_DOMINTELL_DGQG_PID 0xEF50 /* Master */ +#define FTDI_DOMINTELL_DUSB_PID 0xEF51 /* DUSB01 module */ + /* Commands */ #define FTDI_SIO_RESET 0 /* Reset the port */ #define FTDI_SIO_MODEM_CTRL 1 /* Set the modem control register */ diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 9f9cd36455f..73f8277f88f 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -218,6 +218,7 @@ static int option_send_setup(struct tty_struct *tty, struct usb_serial_port *po /* ZTE PRODUCTS */ #define ZTE_VENDOR_ID 0x19d2 #define ZTE_PRODUCT_MF628 0x0015 +#define ZTE_PRODUCT_CDMA_TECH 0xfffe static struct usb_device_id option_ids[] = { { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, @@ -347,6 +348,7 @@ static struct usb_device_id option_ids[] = { { USB_DEVICE(MAXON_VENDOR_ID, 0x6280) }, /* BP3-USB & BP3-EXT HSDPA */ { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) }, { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_MF628) }, + { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH) }, { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, option_ids); diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index 706033753ad..ea1a103c99b 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c @@ -14,7 +14,7 @@ Whom based his on the Keyspan driver by Hugh Blemings <hugh@blemings.org> */ -#define DRIVER_VERSION "v.1.2.13a" +#define DRIVER_VERSION "v.1.3.2" #define DRIVER_AUTHOR "Kevin Lloyd <klloyd@sierrawireless.com>" #define DRIVER_DESC "USB Driver for Sierra Wireless USB modems" @@ -30,9 +30,6 @@ #define SWIMS_USB_REQUEST_SetPower 0x00 #define SWIMS_USB_REQUEST_SetNmea 0x07 -#define SWIMS_USB_REQUEST_SetMode 0x0B -#define SWIMS_USB_REQUEST_GetSwocInfo 0x0A -#define SWIMS_SET_MODE_Modem 0x0001 /* per port private data */ #define N_IN_URB 4 @@ -163,7 +160,7 @@ static struct usb_device_id id_table [] = { { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */ { USB_DEVICE(0x1199, 0x0018) }, /* Sierra Wireless MC5720 */ { USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */ - { USB_DEVICE(0x0f30, 0x1b1d) }, /* Sierra Wireless MC5720 */ + { USB_DEVICE(0x03f0, 0x1b1d) }, /* HP ev2200 a.k.a MC5720 */ { USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */ { USB_DEVICE(0x1199, 0x0024) }, /* Sierra Wireless MC5727 */ { USB_DEVICE(0x1199, 0x0220) }, /* Sierra Wireless MC5725 */ @@ -175,6 +172,8 @@ static struct usb_device_id id_table [] = { /* Sierra Wireless Device */ { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x0025, 0xFF, 0xFF, 0xFF) }, { USB_DEVICE(0x1199, 0x0026) }, /* Sierra Wireless Device */ + { USB_DEVICE(0x1199, 0x0027) }, /* Sierra Wireless Device */ + { USB_DEVICE(0x1199, 0x0028) }, /* Sierra Wireless Device */ { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */ { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */ @@ -187,6 +186,7 @@ static struct usb_device_id id_table [] = { { USB_DEVICE(0x1199, 0x6821) }, /* Sierra Wireless AirCard 875U */ { USB_DEVICE(0x1199, 0x6832) }, /* Sierra Wireless MC8780 */ { USB_DEVICE(0x1199, 0x6833) }, /* Sierra Wireless MC8781 */ + { USB_DEVICE(0x1199, 0x683A) }, /* Sierra Wireless MC8785 */ { USB_DEVICE(0x1199, 0x683B) }, /* Sierra Wireless MC8785 Composite */ { USB_DEVICE(0x1199, 0x683C) }, /* Sierra Wireless MC8790 */ { USB_DEVICE(0x1199, 0x683D) }, /* Sierra Wireless MC8790 */ @@ -204,6 +204,8 @@ static struct usb_device_id id_table [] = { /* Sierra Wireless Device */ { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6890, 0xFF, 0xFF, 0xFF)}, /* Sierra Wireless Device */ + { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6891, 0xFF, 0xFF, 0xFF)}, + /* Sierra Wireless Device */ { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6892, 0xFF, 0xFF, 0xFF)}, { USB_DEVICE(0x1199, 0x0112) }, /* Sierra Wireless AirCard 580 */ diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index e39c779e416..9a3e495c769 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c @@ -1744,7 +1744,7 @@ static int ti_download_firmware(struct ti_device *tdev, int type) if (buffer) { memcpy(buffer, fw_p->data, fw_p->size); memset(buffer + fw_p->size, 0xff, buffer_size - fw_p->size); - ti_do_download(dev, pipe, buffer, fw_p->size); + status = ti_do_download(dev, pipe, buffer, fw_p->size); kfree(buffer); } release_firmware(fw_p); diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index b157c48e8b7..4f7f9e3ae0a 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -733,7 +733,9 @@ int usb_serial_probe(struct usb_interface *interface, ((le16_to_cpu(dev->descriptor.idVendor) == ATEN_VENDOR_ID) && (le16_to_cpu(dev->descriptor.idProduct) == ATEN_PRODUCT_ID)) || ((le16_to_cpu(dev->descriptor.idVendor) == ALCOR_VENDOR_ID) && - (le16_to_cpu(dev->descriptor.idProduct) == ALCOR_PRODUCT_ID))) { + (le16_to_cpu(dev->descriptor.idProduct) == ALCOR_PRODUCT_ID)) || + ((le16_to_cpu(dev->descriptor.idVendor) == SIEMENS_VENDOR_ID) && + (le16_to_cpu(dev->descriptor.idProduct) == SIEMENS_PRODUCT_ID_EF81))) { if (interface != dev->actconfig->interface[0]) { /* check out the endpoints of the other interface*/ iface_desc = dev->actconfig->interface[0]->cur_altsetting; diff --git a/drivers/usb/storage/Kconfig b/drivers/usb/storage/Kconfig index c76034672c1..3d9249632ae 100644 --- a/drivers/usb/storage/Kconfig +++ b/drivers/usb/storage/Kconfig @@ -146,18 +146,6 @@ config USB_STORAGE_KARMA on the resulting scsi device node returns the Karma to normal operation. -config USB_STORAGE_SIERRA - bool "Sierra Wireless TRU-Install Feature Support" - depends on USB_STORAGE - help - Say Y here to include additional code to support Sierra Wireless - products with the TRU-Install feature (e.g., AC597E, AC881U). - - This code switches the Sierra Wireless device from being in - Mass Storage mode to Modem mode. It also has the ability to - support host software upgrades should full Linux support be added - to TRU-Install. - config USB_STORAGE_CYPRESS_ATACB bool "SAT emulation on Cypress USB/ATA Bridge with ATACB" depends on USB_STORAGE diff --git a/drivers/usb/storage/Makefile b/drivers/usb/storage/Makefile index bc3415b475c..7f8beb5366a 100644 --- a/drivers/usb/storage/Makefile +++ b/drivers/usb/storage/Makefile @@ -21,11 +21,10 @@ usb-storage-obj-$(CONFIG_USB_STORAGE_JUMPSHOT) += jumpshot.o usb-storage-obj-$(CONFIG_USB_STORAGE_ALAUDA) += alauda.o usb-storage-obj-$(CONFIG_USB_STORAGE_ONETOUCH) += onetouch.o usb-storage-obj-$(CONFIG_USB_STORAGE_KARMA) += karma.o -usb-storage-obj-$(CONFIG_USB_STORAGE_SIERRA) += sierra_ms.o usb-storage-obj-$(CONFIG_USB_STORAGE_CYPRESS_ATACB) += cypress_atacb.o usb-storage-objs := scsiglue.o protocol.o transport.o usb.o \ - initializers.o $(usb-storage-obj-y) + initializers.o sierra_ms.o $(usb-storage-obj-y) ifneq ($(CONFIG_USB_LIBUSUAL),) obj-$(CONFIG_USB) += libusual.o diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index ba412e68d47..cd155475cb6 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -160,6 +160,13 @@ UNUSUAL_DEV( 0x0421, 0x0019, 0x0592, 0x0592, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_MAX_SECTORS_64 ), +/* Reported by Filip Joelsson <filip@blueturtle.nu> */ +UNUSUAL_DEV( 0x0421, 0x005d, 0x0001, 0x0600, + "Nokia", + "Nokia 3110c", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_FIX_CAPACITY ), + /* Reported by Mario Rettig <mariorettig@web.de> */ UNUSUAL_DEV( 0x0421, 0x042e, 0x0100, 0x0100, "Nokia", @@ -232,6 +239,20 @@ UNUSUAL_DEV( 0x0421, 0x04b9, 0x0551, 0x0551, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_CAPACITY ), +/* Reported by Richard Nauber <RichardNauber@web.de> */ +UNUSUAL_DEV( 0x0421, 0x04fa, 0x0601, 0x0601, + "Nokia", + "6300", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_FIX_CAPACITY ), + +/* Patch for Nokia 5310 capacity */ +UNUSUAL_DEV( 0x0421, 0x006a, 0x0000, 0x0591, + "Nokia", + "5310", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_FIX_CAPACITY ), + /* Reported by Olaf Hering <olh@suse.de> from novell bug #105878 */ UNUSUAL_DEV( 0x0424, 0x0fdc, 0x0210, 0x0210, "SMSC", @@ -987,6 +1008,13 @@ UNUSUAL_DEV( 0x069b, 0x3004, 0x0001, 0x0001, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_CAPACITY ), +/* Reported by Adrian Pilchowiec <adi1981@epf.pl> */ +UNUSUAL_DEV( 0x071b, 0x3203, 0x0000, 0x0000, + "RockChip", + "MP3", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_NO_WP_DETECT | US_FL_MAX_SECTORS_64), + /* Reported by Massimiliano Ghilardi <massimiliano.ghilardi@gmail.com> * This USB MP3/AVI player device fails and disconnects if more than 128 * sectors (64kB) are read/written in a single command, and may be present @@ -1576,7 +1604,6 @@ UNUSUAL_DEV( 0x10d6, 0x2200, 0x0100, 0x0100, US_SC_DEVICE, US_PR_DEVICE, NULL, 0), -#ifdef CONFIG_USB_STORAGE_SIERRA /* Reported by Kevin Lloyd <linux@sierrawireless.com> * Entry is needed for the initializer function override, * which instructs the device to load as a modem @@ -1587,7 +1614,6 @@ UNUSUAL_DEV( 0x1199, 0x0fff, 0x0000, 0x9999, "USB MMC Storage", US_SC_DEVICE, US_PR_DEVICE, sierra_ms_init, 0), -#endif /* Reported by Jaco Kroon <jaco@kroon.co.za> * The usb-storage module found on the Digitech GNX4 (and supposedly other diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index 73679aa506d..27016fd2cad 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c @@ -102,9 +102,7 @@ #ifdef CONFIG_USB_STORAGE_CYPRESS_ATACB #include "cypress_atacb.h" #endif -#ifdef CONFIG_USB_STORAGE_SIERRA #include "sierra_ms.h" -#endif /* Some informational data */ MODULE_AUTHOR("Matthew Dharm <mdharm-usb@one-eyed-alien.net>"); diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index c6299e8a041..9cbff84b787 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c @@ -2400,11 +2400,15 @@ static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch) if (!fbcon_is_inactive(vc, info)) { if (ops->blank_state != blank) { + int ret = 1; + ops->blank_state = blank; fbcon_cursor(vc, blank ? CM_ERASE : CM_DRAW); ops->cursor_flash = (!blank); - if (fb_blank(info, blank)) + if (info->fbops->fb_blank) + ret = info->fbops->fb_blank(blank, info); + if (ret) fbcon_generic_blank(vc, info, blank); } diff --git a/drivers/video/console/fbcon.h b/drivers/video/console/fbcon.h index a6e38e9ea73..89a346880ec 100644 --- a/drivers/video/console/fbcon.h +++ b/drivers/video/console/fbcon.h @@ -110,7 +110,7 @@ static inline int mono_col(const struct fb_info *info) __u32 max_len; max_len = max(info->var.green.length, info->var.red.length); max_len = max(info->var.blue.length, max_len); - return ~(0xfff << (max_len & 0xff)); + return (~(0xfff << max_len)) & 0xff; } static inline int attr_col_ec(int shift, struct vc_data *vc, diff --git a/drivers/watchdog/geodewdt.c b/drivers/watchdog/geodewdt.c index 614a5c7017b..6799a6de66f 100644 --- a/drivers/watchdog/geodewdt.c +++ b/drivers/watchdog/geodewdt.c @@ -130,8 +130,8 @@ static ssize_t geodewdt_write(struct file *file, const char __user *data, return len; } -static int geodewdt_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) +static long geodewdt_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) { void __user *argp = (void __user *)arg; int __user *p = argp; @@ -198,7 +198,7 @@ static const struct file_operations geodewdt_fops = { .owner = THIS_MODULE, .llseek = no_llseek, .write = geodewdt_write, - .ioctl = geodewdt_ioctl, + .unlocked_ioctl = geodewdt_ioctl, .open = geodewdt_open, .release = geodewdt_release, }; diff --git a/drivers/watchdog/ibmasr.c b/drivers/watchdog/ibmasr.c index b82405cfb4c..89fcefcc851 100644 --- a/drivers/watchdog/ibmasr.c +++ b/drivers/watchdog/ibmasr.c @@ -85,7 +85,6 @@ static void __asr_toggle(void) outb(reg & ~asr_toggle_mask, asr_write_addr); reg = inb(asr_read_addr); - spin_unlock(&asr_lock); } static void asr_toggle(void) diff --git a/drivers/watchdog/pnx4008_wdt.c b/drivers/watchdog/pnx4008_wdt.c index 0ed84162437..6d9f3d4a998 100644 --- a/drivers/watchdog/pnx4008_wdt.c +++ b/drivers/watchdog/pnx4008_wdt.c @@ -173,8 +173,8 @@ static const struct watchdog_info ident = { .identity = "PNX4008 Watchdog", }; -static long pnx4008_wdt_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) +static long pnx4008_wdt_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) { int ret = -ENOTTY; int time; diff --git a/drivers/watchdog/rc32434_wdt.c b/drivers/watchdog/rc32434_wdt.c index 6756bcb009e..c9c73b69c5e 100644 --- a/drivers/watchdog/rc32434_wdt.c +++ b/drivers/watchdog/rc32434_wdt.c @@ -182,8 +182,8 @@ static ssize_t rc32434_wdt_write(struct file *file, const char *data, return 0; } -static int rc32434_wdt_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) +static long rc32434_wdt_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) { void __user *argp = (void __user *)arg; int new_timeout; @@ -242,7 +242,7 @@ static struct file_operations rc32434_wdt_fops = { .owner = THIS_MODULE, .llseek = no_llseek, .write = rc32434_wdt_write, - .ioctl = rc32434_wdt_ioctl, + .unlocked_ioctl = rc32434_wdt_ioctl, .open = rc32434_wdt_open, .release = rc32434_wdt_release, }; diff --git a/drivers/watchdog/rdc321x_wdt.c b/drivers/watchdog/rdc321x_wdt.c index 9108efa73e7..bf92802f2bb 100644 --- a/drivers/watchdog/rdc321x_wdt.c +++ b/drivers/watchdog/rdc321x_wdt.c @@ -144,8 +144,8 @@ static int rdc321x_wdt_release(struct inode *inode, struct file *file) return 0; } -static int rdc321x_wdt_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) +static long rdc321x_wdt_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) { void __user *argp = (void __user *)arg; unsigned int value; @@ -204,7 +204,7 @@ static ssize_t rdc321x_wdt_write(struct file *file, const char __user *buf, static const struct file_operations rdc321x_wdt_fops = { .owner = THIS_MODULE, .llseek = no_llseek, - .ioctl = rdc321x_wdt_ioctl, + .unlocked_ioctl = rdc321x_wdt_ioctl, .open = rdc321x_wdt_open, .write = rdc321x_wdt_write, .release = rdc321x_wdt_release, diff --git a/drivers/watchdog/wdt285.c b/drivers/watchdog/wdt285.c index db362c34958..191ea630210 100644 --- a/drivers/watchdog/wdt285.c +++ b/drivers/watchdog/wdt285.c @@ -115,8 +115,8 @@ static int watchdog_release(struct inode *inode, struct file *file) return 0; } -static ssize_t watchdog_write(struct file *file, const char *data, - size_t len, loff_t *ppos) +static ssize_t watchdog_write(struct file *file, const char __user *data, + size_t len, loff_t *ppos) { /* * Refresh the timer. @@ -133,21 +133,22 @@ static const struct watchdog_info ident = { }; static long watchdog_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) + unsigned long arg) { unsigned int new_margin; + int __user *int_arg = (int __user *)arg; int ret = -ENOTTY; switch (cmd) { case WDIOC_GETSUPPORT: ret = 0; - if (copy_to_user((void *)arg, &ident, sizeof(ident))) + if (copy_to_user((void __user *)arg, &ident, sizeof(ident))) ret = -EFAULT; break; case WDIOC_GETSTATUS: case WDIOC_GETBOOTSTATUS: - ret = put_user(0, (int *)arg); + ret = put_user(0, int_arg); break; case WDIOC_KEEPALIVE: @@ -156,7 +157,7 @@ static long watchdog_ioctl(struct file *file, unsigned int cmd, break; case WDIOC_SETTIMEOUT: - ret = get_user(new_margin, (int *)arg); + ret = get_user(new_margin, int_arg); if (ret) break; @@ -171,7 +172,7 @@ static long watchdog_ioctl(struct file *file, unsigned int cmd, watchdog_ping(); /* Fall */ case WDIOC_GETTIMEOUT: - ret = put_user(soft_margin, (int *)arg); + ret = put_user(soft_margin, int_arg); break; } return ret; diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index c95295c6504..e83aa5ebe86 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c @@ -626,8 +626,7 @@ static struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry, return NULL; error: - if (fid) - p9_client_clunk(fid); + p9_client_clunk(fid); return ERR_PTR(result); } diff --git a/fs/dcache.c b/fs/dcache.c index 80e93956ace..e7a1a99b746 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -1395,6 +1395,10 @@ struct dentry * __d_lookup(struct dentry * parent, struct qstr * name) if (dentry->d_parent != parent) goto next; + /* non-existing due to RCU? */ + if (d_unhashed(dentry)) + goto next; + /* * It is safe to compare names since d_move() cannot * change the qstr (protected by d_lock). @@ -1410,10 +1414,8 @@ struct dentry * __d_lookup(struct dentry * parent, struct qstr * name) goto next; } - if (!d_unhashed(dentry)) { - atomic_inc(&dentry->d_count); - found = dentry; - } + atomic_inc(&dentry->d_count); + found = dentry; spin_unlock(&dentry->d_lock); break; next: diff --git a/fs/exec.c b/fs/exec.c index 32993beecbe..cecee501ce7 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -752,11 +752,11 @@ static int exec_mmap(struct mm_struct *mm) tsk->active_mm = mm; activate_mm(active_mm, mm); task_unlock(tsk); - mm_update_next_owner(old_mm); arch_pick_mmap_layout(mm); if (old_mm) { up_read(&old_mm->mmap_sem); BUG_ON(active_mm != old_mm); + mm_update_next_owner(old_mm); mmput(old_mm); return 0; } diff --git a/fs/inotify_user.c b/fs/inotify_user.c index 60249429a25..d85c7d931cd 100644 --- a/fs/inotify_user.c +++ b/fs/inotify_user.c @@ -323,7 +323,7 @@ out: } /* - * remove_kevent - cleans up and ultimately frees the given kevent + * remove_kevent - cleans up the given kevent * * Caller must hold dev->ev_mutex. */ @@ -334,7 +334,13 @@ static void remove_kevent(struct inotify_device *dev, dev->event_count--; dev->queue_size -= sizeof(struct inotify_event) + kevent->event.len; +} +/* + * free_kevent - frees the given kevent. + */ +static void free_kevent(struct inotify_kernel_event *kevent) +{ kfree(kevent->name); kmem_cache_free(event_cachep, kevent); } @@ -350,6 +356,7 @@ static void inotify_dev_event_dequeue(struct inotify_device *dev) struct inotify_kernel_event *kevent; kevent = inotify_dev_get_event(dev); remove_kevent(dev, kevent); + free_kevent(kevent); } } @@ -433,17 +440,15 @@ static ssize_t inotify_read(struct file *file, char __user *buf, dev = file->private_data; while (1) { - int events; prepare_to_wait(&dev->wq, &wait, TASK_INTERRUPTIBLE); mutex_lock(&dev->ev_mutex); - events = !list_empty(&dev->events); - mutex_unlock(&dev->ev_mutex); - if (events) { + if (!list_empty(&dev->events)) { ret = 0; break; } + mutex_unlock(&dev->ev_mutex); if (file->f_flags & O_NONBLOCK) { ret = -EAGAIN; @@ -462,7 +467,6 @@ static ssize_t inotify_read(struct file *file, char __user *buf, if (ret) return ret; - mutex_lock(&dev->ev_mutex); while (1) { struct inotify_kernel_event *kevent; @@ -481,6 +485,13 @@ static ssize_t inotify_read(struct file *file, char __user *buf, } break; } + remove_kevent(dev, kevent); + + /* + * Must perform the copy_to_user outside the mutex in order + * to avoid a lock order reversal with mmap_sem. + */ + mutex_unlock(&dev->ev_mutex); if (copy_to_user(buf, &kevent->event, event_size)) { ret = -EFAULT; @@ -498,7 +509,9 @@ static ssize_t inotify_read(struct file *file, char __user *buf, count -= kevent->event.len; } - remove_kevent(dev, kevent); + free_kevent(kevent); + + mutex_lock(&dev->ev_mutex); } mutex_unlock(&dev->ev_mutex); diff --git a/fs/ramfs/file-nommu.c b/fs/ramfs/file-nommu.c index 52312ec93ff..5145cb9125a 100644 --- a/fs/ramfs/file-nommu.c +++ b/fs/ramfs/file-nommu.c @@ -58,7 +58,7 @@ const struct inode_operations ramfs_file_inode_operations = { * size 0 on the assumption that it's going to be used for an mmap of shared * memory */ -static int ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize) +int ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize) { struct pagevec lru_pvec; unsigned long npages, xpages, loop, limit; diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c index b9cb7747375..d7f7645779f 100644 --- a/fs/ubifs/debug.c +++ b/fs/ubifs/debug.c @@ -538,7 +538,7 @@ void dbg_dump_node(const struct ubifs_info *c, const void *node) printk(KERN_DEBUG "\t%d orphan inode numbers:\n", n); for (i = 0; i < n; i++) printk(KERN_DEBUG "\t ino %llu\n", - le64_to_cpu(orph->inos[i])); + (unsigned long long)le64_to_cpu(orph->inos[i])); break; } default: diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c index 2b267c9a180..526c01ec800 100644 --- a/fs/ubifs/dir.c +++ b/fs/ubifs/dir.c @@ -426,7 +426,7 @@ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir) while (1) { dbg_gen("feed '%s', ino %llu, new f_pos %#x", - dent->name, le64_to_cpu(dent->inum), + dent->name, (unsigned long long)le64_to_cpu(dent->inum), key_hash_flash(c, &dent->key)); ubifs_assert(dent->ch.sqnum > ubifs_inode(dir)->creat_sqnum); diff --git a/fs/ubifs/find.c b/fs/ubifs/find.c index e045c8b5542..47814cde240 100644 --- a/fs/ubifs/find.c +++ b/fs/ubifs/find.c @@ -507,7 +507,6 @@ int ubifs_find_free_space(struct ubifs_info *c, int min_space, int *free, rsvd_idx_lebs = 0; lebs = c->lst.empty_lebs + c->freeable_cnt + c->idx_gc_cnt - c->lst.taken_empty_lebs; - ubifs_assert(lebs + c->lst.idx_lebs >= c->min_idx_lebs); if (rsvd_idx_lebs < lebs) /* * OK to allocate an empty LEB, but we still don't want to go diff --git a/fs/ubifs/gc.c b/fs/ubifs/gc.c index 13f1019c859..02aba36fe3d 100644 --- a/fs/ubifs/gc.c +++ b/fs/ubifs/gc.c @@ -334,15 +334,15 @@ int ubifs_garbage_collect_leb(struct ubifs_info *c, struct ubifs_lprops *lp) err = move_nodes(c, sleb); if (err) - goto out; + goto out_inc_seq; err = gc_sync_wbufs(c); if (err) - goto out; + goto out_inc_seq; err = ubifs_change_one_lp(c, lnum, c->leb_size, 0, 0, 0, 0); if (err) - goto out; + goto out_inc_seq; /* Allow for races with TNC */ c->gced_lnum = lnum; @@ -369,6 +369,14 @@ int ubifs_garbage_collect_leb(struct ubifs_info *c, struct ubifs_lprops *lp) out: ubifs_scan_destroy(sleb); return err; + +out_inc_seq: + /* We may have moved at least some nodes so allow for races with TNC */ + c->gced_lnum = lnum; + smp_wmb(); + c->gc_seq += 1; + smp_wmb(); + goto out; } /** diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c index 7562464ac83..3f4902060c7 100644 --- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c @@ -1024,14 +1024,13 @@ static int mount_ubifs(struct ubifs_info *c) goto out_dereg; } + sprintf(c->bgt_name, BGT_NAME_PATTERN, c->vi.ubi_num, c->vi.vol_id); if (!mounted_read_only) { err = alloc_wbufs(c); if (err) goto out_cbuf; /* Create background thread */ - sprintf(c->bgt_name, BGT_NAME_PATTERN, c->vi.ubi_num, - c->vi.vol_id); c->bgt = kthread_create(ubifs_bg_thread, c, c->bgt_name); if (!c->bgt) c->bgt = ERR_PTR(-EINVAL); diff --git a/fs/ubifs/tnc.c b/fs/ubifs/tnc.c index 7da209ab937..7634c597088 100644 --- a/fs/ubifs/tnc.c +++ b/fs/ubifs/tnc.c @@ -1476,7 +1476,7 @@ again: } err = fallible_read_node(c, key, &zbr, node); - if (maybe_leb_gced(c, zbr.lnum, gc_seq1)) { + if (err <= 0 || maybe_leb_gced(c, zbr.lnum, gc_seq1)) { /* * The node may have been GC'ed out from under us so try again * while keeping the TNC mutex locked. diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 00e80df9dd9..dbd9cef852e 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -4118,7 +4118,7 @@ xfs_iext_indirect_to_direct( ASSERT(nextents <= XFS_LINEAR_EXTS); size = nextents * sizeof(xfs_bmbt_rec_t); - xfs_iext_irec_compact_full(ifp); + xfs_iext_irec_compact_pages(ifp); ASSERT(ifp->if_real_bytes == XFS_IEXT_BUFSZ); ep = ifp->if_u1.if_ext_irec->er_extbuf; @@ -4449,8 +4449,7 @@ xfs_iext_irec_remove( * compaction policy is as follows: * * Full Compaction: Extents fit into a single page (or inline buffer) - * Full Compaction: Extents occupy less than 10% of allocated space - * Partial Compaction: Extents occupy > 10% and < 50% of allocated space + * Partial Compaction: Extents occupy less than 50% of allocated space * No Compaction: Extents occupy at least 50% of allocated space */ void @@ -4471,8 +4470,6 @@ xfs_iext_irec_compact( xfs_iext_direct_to_inline(ifp, nextents); } else if (nextents <= XFS_LINEAR_EXTS) { xfs_iext_indirect_to_direct(ifp); - } else if (nextents < (nlists * XFS_LINEAR_EXTS) >> 3) { - xfs_iext_irec_compact_full(ifp); } else if (nextents < (nlists * XFS_LINEAR_EXTS) >> 1) { xfs_iext_irec_compact_pages(ifp); } @@ -4496,7 +4493,7 @@ xfs_iext_irec_compact_pages( erp_next = erp + 1; if (erp_next->er_extcount <= (XFS_LINEAR_EXTS - erp->er_extcount)) { - memmove(&erp->er_extbuf[erp->er_extcount], + memcpy(&erp->er_extbuf[erp->er_extcount], erp_next->er_extbuf, erp_next->er_extcount * sizeof(xfs_bmbt_rec_t)); erp->er_extcount += erp_next->er_extcount; @@ -4516,91 +4513,6 @@ xfs_iext_irec_compact_pages( } /* - * Fully compact the extent records managed by the indirection array. - */ -void -xfs_iext_irec_compact_full( - xfs_ifork_t *ifp) /* inode fork pointer */ -{ - xfs_bmbt_rec_host_t *ep, *ep_next; /* extent record pointers */ - xfs_ext_irec_t *erp, *erp_next; /* extent irec pointers */ - int erp_idx = 0; /* extent irec index */ - int ext_avail; /* empty entries in ex list */ - int ext_diff; /* number of exts to add */ - int nlists; /* number of irec's (ex lists) */ - - ASSERT(ifp->if_flags & XFS_IFEXTIREC); - - nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; - erp = ifp->if_u1.if_ext_irec; - ep = &erp->er_extbuf[erp->er_extcount]; - erp_next = erp + 1; - ep_next = erp_next->er_extbuf; - - while (erp_idx < nlists - 1) { - /* - * Check how many extent records are available in this irec. - * If there is none skip the whole exercise. - */ - ext_avail = XFS_LINEAR_EXTS - erp->er_extcount; - if (ext_avail) { - - /* - * Copy over as many as possible extent records into - * the previous page. - */ - ext_diff = MIN(ext_avail, erp_next->er_extcount); - memcpy(ep, ep_next, ext_diff * sizeof(xfs_bmbt_rec_t)); - erp->er_extcount += ext_diff; - erp_next->er_extcount -= ext_diff; - - /* - * If the next irec is empty now we can simply - * remove it. - */ - if (erp_next->er_extcount == 0) { - /* - * Free page before removing extent record - * so er_extoffs don't get modified in - * xfs_iext_irec_remove. - */ - kmem_free(erp_next->er_extbuf); - erp_next->er_extbuf = NULL; - xfs_iext_irec_remove(ifp, erp_idx + 1); - erp = &ifp->if_u1.if_ext_irec[erp_idx]; - nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; - - /* - * If the next irec is not empty move up the content - * that has not been copied to the previous page to - * the beggining of this one. - */ - } else { - memmove(erp_next->er_extbuf, &ep_next[ext_diff], - erp_next->er_extcount * - sizeof(xfs_bmbt_rec_t)); - ep_next = erp_next->er_extbuf; - memset(&ep_next[erp_next->er_extcount], 0, - (XFS_LINEAR_EXTS - - erp_next->er_extcount) * - sizeof(xfs_bmbt_rec_t)); - } - } - - if (erp->er_extcount == XFS_LINEAR_EXTS) { - erp_idx++; - if (erp_idx < nlists) - erp = &ifp->if_u1.if_ext_irec[erp_idx]; - else - break; - } - ep = &erp->er_extbuf[erp->er_extcount]; - erp_next = erp + 1; - ep_next = erp_next->er_extbuf; - } -} - -/* * This is called to update the er_extoff field in the indirection * array when extents have been added or removed from one of the * extent lists. erp_idx contains the irec index to begin updating diff --git a/include/asm-mips/cevt-r4k.h b/include/asm-mips/cevt-r4k.h new file mode 100644 index 00000000000..fa4328f9124 --- /dev/null +++ b/include/asm-mips/cevt-r4k.h @@ -0,0 +1,46 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2008 Kevin D. Kissell + */ + +/* + * Definitions used for common event timer implementation + * for MIPS 4K-type processors and their MIPS MT variants. + * Avoids unsightly extern declarations in C files. + */ +#ifndef __ASM_CEVT_R4K_H +#define __ASM_CEVT_R4K_H + +DECLARE_PER_CPU(struct clock_event_device, mips_clockevent_device); + +void mips_event_handler(struct clock_event_device *dev); +int c0_compare_int_usable(void); +void mips_set_clock_mode(enum clock_event_mode, struct clock_event_device *); +irqreturn_t c0_compare_interrupt(int, void *); + +extern struct irqaction c0_compare_irqaction; +extern int cp0_timer_irq_installed; + +/* + * Possibly handle a performance counter interrupt. + * Return true if the timer interrupt should not be checked + */ + +static inline int handle_perf_irq(int r2) +{ + /* + * The performance counter overflow interrupt may be shared with the + * timer interrupt (cp0_perfcount_irq < 0). If it is and a + * performance counter has overflowed (perf_irq() == IRQ_HANDLED) + * and we can't reliably determine if a counter interrupt has also + * happened (!r2) then don't check for a timer interrupt. + */ + return (cp0_perfcount_irq < 0) && + perf_irq() == IRQ_HANDLED && + !r2; +} + +#endif /* __ASM_CEVT_R4K_H */ diff --git a/include/asm-mips/irqflags.h b/include/asm-mips/irqflags.h index 881e8866501..701ec0ba8fa 100644 --- a/include/asm-mips/irqflags.h +++ b/include/asm-mips/irqflags.h @@ -38,8 +38,17 @@ __asm__( " .set pop \n" " .endm"); +extern void smtc_ipi_replay(void); + static inline void raw_local_irq_enable(void) { +#ifdef CONFIG_MIPS_MT_SMTC + /* + * SMTC kernel needs to do a software replay of queued + * IPIs, at the cost of call overhead on each local_irq_enable() + */ + smtc_ipi_replay(); +#endif __asm__ __volatile__( "raw_local_irq_enable" : /* no outputs */ @@ -47,6 +56,7 @@ static inline void raw_local_irq_enable(void) : "memory"); } + /* * For cli() we have to insert nops to make sure that the new value * has actually arrived in the status register before the end of this @@ -185,15 +195,14 @@ __asm__( " .set pop \n" " .endm \n"); -extern void smtc_ipi_replay(void); static inline void raw_local_irq_restore(unsigned long flags) { unsigned long __tmp1; -#ifdef CONFIG_MIPS_MT_SMTC_INSTANT_REPLAY +#ifdef CONFIG_MIPS_MT_SMTC /* - * CONFIG_MIPS_MT_SMTC_INSTANT_REPLAY does prompt replay of deferred + * SMTC kernel needs to do a software replay of queued * IPIs, at the cost of branch and call overhead on each * local_irq_restore() */ @@ -208,6 +217,17 @@ static inline void raw_local_irq_restore(unsigned long flags) : "memory"); } +static inline void __raw_local_irq_restore(unsigned long flags) +{ + unsigned long __tmp1; + + __asm__ __volatile__( + "raw_local_irq_restore\t%0" + : "=r" (__tmp1) + : "0" (flags) + : "memory"); +} + static inline int raw_irqs_disabled_flags(unsigned long flags) { #ifdef CONFIG_MIPS_MT_SMTC diff --git a/include/asm-mips/mipsregs.h b/include/asm-mips/mipsregs.h index a46f8e258e6..979866000da 100644 --- a/include/asm-mips/mipsregs.h +++ b/include/asm-mips/mipsregs.h @@ -1462,7 +1462,7 @@ set_c0_##name(unsigned int set) \ { \ unsigned int res; \ unsigned int omt; \ - unsigned int flags; \ + unsigned long flags; \ \ local_irq_save(flags); \ omt = __dmt(); \ @@ -1480,7 +1480,7 @@ clear_c0_##name(unsigned int clear) \ { \ unsigned int res; \ unsigned int omt; \ - unsigned int flags; \ + unsigned long flags; \ \ local_irq_save(flags); \ omt = __dmt(); \ @@ -1498,7 +1498,7 @@ change_c0_##name(unsigned int change, unsigned int new) \ { \ unsigned int res; \ unsigned int omt; \ - unsigned int flags; \ + unsigned long flags; \ \ local_irq_save(flags); \ \ diff --git a/include/asm-mips/pgtable-32.h b/include/asm-mips/pgtable-32.h index 4396e9ffd41..55813d6150c 100644 --- a/include/asm-mips/pgtable-32.h +++ b/include/asm-mips/pgtable-32.h @@ -57,7 +57,7 @@ extern int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1, #define PMD_ORDER 1 #define PTE_ORDER 0 -#define PTRS_PER_PGD ((PAGE_SIZE << PGD_ORDER) / sizeof(pgd_t)) +#define PTRS_PER_PGD (USER_PTRS_PER_PGD * 2) #define PTRS_PER_PTE ((PAGE_SIZE << PTE_ORDER) / sizeof(pte_t)) #define USER_PTRS_PER_PGD (0x80000000UL/PGDIR_SIZE) diff --git a/include/asm-mips/smtc.h b/include/asm-mips/smtc.h index 3639b28f80d..ea60bf08dcb 100644 --- a/include/asm-mips/smtc.h +++ b/include/asm-mips/smtc.h @@ -6,6 +6,7 @@ */ #include <asm/mips_mt.h> +#include <asm/smtc_ipi.h> /* * System-wide SMTC status information @@ -38,14 +39,15 @@ struct mm_struct; struct task_struct; void smtc_get_new_mmu_context(struct mm_struct *mm, unsigned long cpu); - +void self_ipi(struct smtc_ipi *); void smtc_flush_tlb_asid(unsigned long asid); -extern int mipsmt_build_cpu_map(int startslot); -extern void mipsmt_prepare_cpus(void); +extern int smtc_build_cpu_map(int startslot); +extern void smtc_prepare_cpus(int cpus); extern void smtc_smp_finish(void); extern void smtc_boot_secondary(int cpu, struct task_struct *t); extern void smtc_cpus_done(void); + /* * Sharing the TLB between multiple VPEs means that the * "random" index selection function is not allowed to diff --git a/include/asm-mips/stackframe.h b/include/asm-mips/stackframe.h index 051e1af0bb9..4c37c4e5f72 100644 --- a/include/asm-mips/stackframe.h +++ b/include/asm-mips/stackframe.h @@ -297,14 +297,31 @@ #ifdef CONFIG_MIPS_MT_SMTC .set mips32r2 /* - * This may not really be necessary if ints are already - * inhibited here. + * We need to make sure the read-modify-write + * of Status below isn't perturbed by an interrupt + * or cross-TC access, so we need to do at least a DMT, + * protected by an interrupt-inhibit. But setting IXMT + * also creates a few-cycle window where an IPI could + * be queued and not be detected before potentially + * returning to a WAIT or user-mode loop. It must be + * replayed. + * + * We're in the middle of a context switch, and + * we can't dispatch it directly without trashing + * some registers, so we'll try to detect this unlikely + * case and program a software interrupt in the VPE, + * as would be done for a cross-VPE IPI. To accomodate + * the handling of that case, we're doing a DVPE instead + * of just a DMT here to protect against other threads. + * This is a lot of cruft to cover a tiny window. + * If you can find a better design, implement it! + * */ mfc0 v0, CP0_TCSTATUS ori v0, TCSTATUS_IXMT mtc0 v0, CP0_TCSTATUS _ehb - DMT 5 # dmt a1 + DVPE 5 # dvpe a1 jal mips_ihb #endif /* CONFIG_MIPS_MT_SMTC */ mfc0 a0, CP0_STATUS @@ -325,17 +342,50 @@ */ LONG_L v1, PT_TCSTATUS(sp) _ehb - mfc0 v0, CP0_TCSTATUS + mfc0 a0, CP0_TCSTATUS andi v1, TCSTATUS_IXMT - /* We know that TCStatua.IXMT should be set from above */ - xori v0, v0, TCSTATUS_IXMT - or v0, v0, v1 - mtc0 v0, CP0_TCSTATUS - _ehb - andi a1, a1, VPECONTROL_TE + bnez v1, 0f + +/* + * We'd like to detect any IPIs queued in the tiny window + * above and request an software interrupt to service them + * when we ERET. + * + * Computing the offset into the IPIQ array of the executing + * TC's IPI queue in-line would be tedious. We use part of + * the TCContext register to hold 16 bits of offset that we + * can add in-line to find the queue head. + */ + mfc0 v0, CP0_TCCONTEXT + la a2, IPIQ + srl v0, v0, 16 + addu a2, a2, v0 + LONG_L v0, 0(a2) + beqz v0, 0f +/* + * If we have a queue, provoke dispatch within the VPE by setting C_SW1 + */ + mfc0 v0, CP0_CAUSE + ori v0, v0, C_SW1 + mtc0 v0, CP0_CAUSE +0: + /* + * This test should really never branch but + * let's be prudent here. Having atomized + * the shared register modifications, we can + * now EVPE, and must do so before interrupts + * are potentially re-enabled. + */ + andi a1, a1, MVPCONTROL_EVP beqz a1, 1f - emt + evpe 1: + /* We know that TCStatua.IXMT should be set from above */ + xori a0, a0, TCSTATUS_IXMT + or a0, a0, v1 + mtc0 a0, CP0_TCSTATUS + _ehb + .set mips0 #endif /* CONFIG_MIPS_MT_SMTC */ LONG_L v1, PT_EPC(sp) diff --git a/include/asm-x86/a.out-core.h b/include/asm-x86/a.out-core.h index 714207a1c38..f5705761a37 100644 --- a/include/asm-x86/a.out-core.h +++ b/include/asm-x86/a.out-core.h @@ -9,8 +9,8 @@ * 2 of the Licence, or (at your option) any later version. */ -#ifndef _ASM_A_OUT_CORE_H -#define _ASM_A_OUT_CORE_H +#ifndef ASM_X86__A_OUT_CORE_H +#define ASM_X86__A_OUT_CORE_H #ifdef __KERNEL__ #ifdef CONFIG_X86_32 @@ -70,4 +70,4 @@ static inline void aout_dump_thread(struct pt_regs *regs, struct user *dump) #endif /* CONFIG_X86_32 */ #endif /* __KERNEL__ */ -#endif /* _ASM_A_OUT_CORE_H */ +#endif /* ASM_X86__A_OUT_CORE_H */ diff --git a/include/asm-x86/a.out.h b/include/asm-x86/a.out.h index 4684f97a5bb..0948748bc69 100644 --- a/include/asm-x86/a.out.h +++ b/include/asm-x86/a.out.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_A_OUT_H -#define _ASM_X86_A_OUT_H +#ifndef ASM_X86__A_OUT_H +#define ASM_X86__A_OUT_H struct exec { @@ -17,4 +17,4 @@ struct exec #define N_DRSIZE(a) ((a).a_drsize) #define N_SYMSIZE(a) ((a).a_syms) -#endif /* _ASM_X86_A_OUT_H */ +#endif /* ASM_X86__A_OUT_H */ diff --git a/include/asm-x86/acpi.h b/include/asm-x86/acpi.h index 635d764dc13..392e17336be 100644 --- a/include/asm-x86/acpi.h +++ b/include/asm-x86/acpi.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_ACPI_H -#define _ASM_X86_ACPI_H +#ifndef ASM_X86__ACPI_H +#define ASM_X86__ACPI_H /* * Copyright (C) 2001 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> @@ -140,6 +140,8 @@ static inline unsigned int acpi_processor_cstate_check(unsigned int max_cstate) boot_cpu_data.x86_model <= 0x05 && boot_cpu_data.x86_mask < 0x0A) return 1; + else if (boot_cpu_has(X86_FEATURE_AMDC1E)) + return 1; else return max_cstate; } @@ -173,4 +175,4 @@ static inline void acpi_fake_nodes(const struct bootnode *fake_nodes, #define acpi_unlazy_tlb(x) leave_mm(x) -#endif /*__X86_ASM_ACPI_H*/ +#endif /* ASM_X86__ACPI_H */ diff --git a/include/asm-x86/agp.h b/include/asm-x86/agp.h index e4004a9f6a9..3617fd4fcdf 100644 --- a/include/asm-x86/agp.h +++ b/include/asm-x86/agp.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_AGP_H -#define _ASM_X86_AGP_H +#ifndef ASM_X86__AGP_H +#define ASM_X86__AGP_H #include <asm/pgtable.h> #include <asm/cacheflush.h> @@ -32,4 +32,4 @@ #define free_gatt_pages(table, order) \ free_pages((unsigned long)(table), (order)) -#endif +#endif /* ASM_X86__AGP_H */ diff --git a/include/asm-x86/alternative.h b/include/asm-x86/alternative.h index f6aa18eadf7..22d3c9862bf 100644 --- a/include/asm-x86/alternative.h +++ b/include/asm-x86/alternative.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_ALTERNATIVE_H -#define _ASM_X86_ALTERNATIVE_H +#ifndef ASM_X86__ALTERNATIVE_H +#define ASM_X86__ALTERNATIVE_H #include <linux/types.h> #include <linux/stddef.h> @@ -180,4 +180,4 @@ extern void add_nops(void *insns, unsigned int len); extern void *text_poke(void *addr, const void *opcode, size_t len); extern void *text_poke_early(void *addr, const void *opcode, size_t len); -#endif /* _ASM_X86_ALTERNATIVE_H */ +#endif /* ASM_X86__ALTERNATIVE_H */ diff --git a/include/asm-x86/amd_iommu.h b/include/asm-x86/amd_iommu.h index 30a12049353..783f43e5805 100644 --- a/include/asm-x86/amd_iommu.h +++ b/include/asm-x86/amd_iommu.h @@ -17,8 +17,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _ASM_X86_AMD_IOMMU_H -#define _ASM_X86_AMD_IOMMU_H +#ifndef ASM_X86__AMD_IOMMU_H +#define ASM_X86__AMD_IOMMU_H #ifdef CONFIG_AMD_IOMMU extern int amd_iommu_init(void); @@ -29,4 +29,4 @@ static inline int amd_iommu_init(void) { return -ENODEV; } static inline void amd_iommu_detect(void) { } #endif -#endif +#endif /* ASM_X86__AMD_IOMMU_H */ diff --git a/include/asm-x86/amd_iommu_types.h b/include/asm-x86/amd_iommu_types.h index dcc81206739..1ffa4e53c98 100644 --- a/include/asm-x86/amd_iommu_types.h +++ b/include/asm-x86/amd_iommu_types.h @@ -17,8 +17,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef __AMD_IOMMU_TYPES_H__ -#define __AMD_IOMMU_TYPES_H__ +#ifndef ASM_X86__AMD_IOMMU_TYPES_H +#define ASM_X86__AMD_IOMMU_TYPES_H #include <linux/types.h> #include <linux/list.h> @@ -341,4 +341,4 @@ static inline u16 calc_devid(u8 bus, u8 devfn) return (((u16)bus) << 8) | devfn; } -#endif +#endif /* ASM_X86__AMD_IOMMU_TYPES_H */ diff --git a/include/asm-x86/apic.h b/include/asm-x86/apic.h index 133c998161c..65590c9aecd 100644 --- a/include/asm-x86/apic.h +++ b/include/asm-x86/apic.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_APIC_H -#define _ASM_X86_APIC_H +#ifndef ASM_X86__APIC_H +#define ASM_X86__APIC_H #include <linux/pm.h> #include <linux/delay.h> @@ -54,6 +54,11 @@ extern int disable_apic; #endif extern int is_vsmp_box(void); +extern void xapic_wait_icr_idle(void); +extern u32 safe_xapic_wait_icr_idle(void); +extern u64 xapic_icr_read(void); +extern void xapic_icr_write(u32, u32); +extern int setup_profiling_timer(unsigned int); static inline void native_apic_write(unsigned long reg, u32 v) { @@ -76,9 +81,7 @@ extern int get_physical_broadcast(void); static inline void ack_APIC_irq(void) { /* - * ack_APIC_irq() actually gets compiled as a single instruction: - * - a single rmw on Pentium/82489DX - * - a single write on P6+ cores (CONFIG_X86_GOOD_APIC) + * ack_APIC_irq() actually gets compiled as a single instruction * ... yummie. */ @@ -128,4 +131,4 @@ static inline void init_apic_mappings(void) { } #endif /* !CONFIG_X86_LOCAL_APIC */ -#endif /* __ASM_APIC_H */ +#endif /* ASM_X86__APIC_H */ diff --git a/include/asm-x86/apicdef.h b/include/asm-x86/apicdef.h index 6b9008c7873..c40687da20f 100644 --- a/include/asm-x86/apicdef.h +++ b/include/asm-x86/apicdef.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_APICDEF_H -#define _ASM_X86_APICDEF_H +#ifndef ASM_X86__APICDEF_H +#define ASM_X86__APICDEF_H /* * Constants for various Intel APICs. (local APIC, IOAPIC, etc.) @@ -411,4 +411,4 @@ struct local_apic { #else #define BAD_APICID 0xFFFFu #endif -#endif +#endif /* ASM_X86__APICDEF_H */ diff --git a/include/asm-x86/arch_hooks.h b/include/asm-x86/arch_hooks.h index 8411750ceb6..72adc3a109c 100644 --- a/include/asm-x86/arch_hooks.h +++ b/include/asm-x86/arch_hooks.h @@ -1,5 +1,5 @@ -#ifndef _ASM_ARCH_HOOKS_H -#define _ASM_ARCH_HOOKS_H +#ifndef ASM_X86__ARCH_HOOKS_H +#define ASM_X86__ARCH_HOOKS_H #include <linux/interrupt.h> @@ -25,4 +25,4 @@ extern void pre_time_init_hook(void); extern void time_init_hook(void); extern void mca_nmi_hook(void); -#endif +#endif /* ASM_X86__ARCH_HOOKS_H */ diff --git a/include/asm-x86/asm.h b/include/asm-x86/asm.h index 97220321f39..e1355f44d7c 100644 --- a/include/asm-x86/asm.h +++ b/include/asm-x86/asm.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_ASM_H -#define _ASM_X86_ASM_H +#ifndef ASM_X86__ASM_H +#define ASM_X86__ASM_H #ifdef __ASSEMBLY__ # define __ASM_FORM(x) x @@ -20,17 +20,22 @@ #define _ASM_PTR __ASM_SEL(.long, .quad) #define _ASM_ALIGN __ASM_SEL(.balign 4, .balign 8) -#define _ASM_MOV_UL __ASM_SIZE(mov) +#define _ASM_MOV __ASM_SIZE(mov) #define _ASM_INC __ASM_SIZE(inc) #define _ASM_DEC __ASM_SIZE(dec) #define _ASM_ADD __ASM_SIZE(add) #define _ASM_SUB __ASM_SIZE(sub) #define _ASM_XADD __ASM_SIZE(xadd) + #define _ASM_AX __ASM_REG(ax) #define _ASM_BX __ASM_REG(bx) #define _ASM_CX __ASM_REG(cx) #define _ASM_DX __ASM_REG(dx) +#define _ASM_SP __ASM_REG(sp) +#define _ASM_BP __ASM_REG(bp) +#define _ASM_SI __ASM_REG(si) +#define _ASM_DI __ASM_REG(di) /* Exception table entry */ # define _ASM_EXTABLE(from,to) \ @@ -39,4 +44,4 @@ _ASM_PTR #from "," #to "\n" \ " .previous\n" -#endif /* _ASM_X86_ASM_H */ +#endif /* ASM_X86__ASM_H */ diff --git a/include/asm-x86/atomic_32.h b/include/asm-x86/atomic_32.h index 21a4825148c..14d3f0beb88 100644 --- a/include/asm-x86/atomic_32.h +++ b/include/asm-x86/atomic_32.h @@ -1,5 +1,5 @@ -#ifndef __ARCH_I386_ATOMIC__ -#define __ARCH_I386_ATOMIC__ +#ifndef ASM_X86__ATOMIC_32_H +#define ASM_X86__ATOMIC_32_H #include <linux/compiler.h> #include <asm/processor.h> @@ -256,4 +256,4 @@ static inline int atomic_add_unless(atomic_t *v, int a, int u) #define smp_mb__after_atomic_inc() barrier() #include <asm-generic/atomic.h> -#endif +#endif /* ASM_X86__ATOMIC_32_H */ diff --git a/include/asm-x86/atomic_64.h b/include/asm-x86/atomic_64.h index 91c7d03e65b..2cb218c4a35 100644 --- a/include/asm-x86/atomic_64.h +++ b/include/asm-x86/atomic_64.h @@ -1,5 +1,5 @@ -#ifndef __ARCH_X86_64_ATOMIC__ -#define __ARCH_X86_64_ATOMIC__ +#ifndef ASM_X86__ATOMIC_64_H +#define ASM_X86__ATOMIC_64_H #include <asm/alternative.h> #include <asm/cmpxchg.h> @@ -470,4 +470,4 @@ static inline void atomic_or_long(unsigned long *v1, unsigned long v2) #define smp_mb__after_atomic_inc() barrier() #include <asm-generic/atomic.h> -#endif +#endif /* ASM_X86__ATOMIC_64_H */ diff --git a/include/asm-x86/auxvec.h b/include/asm-x86/auxvec.h index 87f5e6d5a02..12c7cac7420 100644 --- a/include/asm-x86/auxvec.h +++ b/include/asm-x86/auxvec.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_AUXVEC_H -#define _ASM_X86_AUXVEC_H +#ifndef ASM_X86__AUXVEC_H +#define ASM_X86__AUXVEC_H /* * Architecture-neutral AT_ values in 0-17, leave some room * for more of them, start the x86-specific ones at 32. @@ -9,4 +9,4 @@ #endif #define AT_SYSINFO_EHDR 33 -#endif +#endif /* ASM_X86__AUXVEC_H */ diff --git a/include/asm-x86/bios_ebda.h b/include/asm-x86/bios_ebda.h index 0033e50c13b..ec42ed87459 100644 --- a/include/asm-x86/bios_ebda.h +++ b/include/asm-x86/bios_ebda.h @@ -1,5 +1,5 @@ -#ifndef _MACH_BIOS_EBDA_H -#define _MACH_BIOS_EBDA_H +#ifndef ASM_X86__BIOS_EBDA_H +#define ASM_X86__BIOS_EBDA_H #include <asm/io.h> @@ -16,4 +16,4 @@ static inline unsigned int get_bios_ebda(void) void reserve_ebda_region(void); -#endif /* _MACH_BIOS_EBDA_H */ +#endif /* ASM_X86__BIOS_EBDA_H */ diff --git a/include/asm-x86/bitops.h b/include/asm-x86/bitops.h index cfb2b64f76e..61989b93b47 100644 --- a/include/asm-x86/bitops.h +++ b/include/asm-x86/bitops.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_BITOPS_H -#define _ASM_X86_BITOPS_H +#ifndef ASM_X86__BITOPS_H +#define ASM_X86__BITOPS_H /* * Copyright 1992, Linus Torvalds. @@ -458,4 +458,4 @@ static inline void set_bit_string(unsigned long *bitmap, #include <asm-generic/bitops/minix.h> #endif /* __KERNEL__ */ -#endif /* _ASM_X86_BITOPS_H */ +#endif /* ASM_X86__BITOPS_H */ diff --git a/include/asm-x86/boot.h b/include/asm-x86/boot.h index 2faed7ecb09..825de5dc867 100644 --- a/include/asm-x86/boot.h +++ b/include/asm-x86/boot.h @@ -1,5 +1,5 @@ -#ifndef _ASM_BOOT_H -#define _ASM_BOOT_H +#ifndef ASM_X86__BOOT_H +#define ASM_X86__BOOT_H /* Don't touch these, unless you really know what you're doing. */ #define DEF_INITSEG 0x9000 @@ -25,4 +25,4 @@ #define BOOT_STACK_SIZE 0x1000 #endif -#endif /* _ASM_BOOT_H */ +#endif /* ASM_X86__BOOT_H */ diff --git a/include/asm-x86/bootparam.h b/include/asm-x86/bootparam.h index ae22bdf0ab1..ccf027e2d97 100644 --- a/include/asm-x86/bootparam.h +++ b/include/asm-x86/bootparam.h @@ -1,5 +1,5 @@ -#ifndef _ASM_BOOTPARAM_H -#define _ASM_BOOTPARAM_H +#ifndef ASM_X86__BOOTPARAM_H +#define ASM_X86__BOOTPARAM_H #include <linux/types.h> #include <linux/screen_info.h> @@ -108,4 +108,4 @@ struct boot_params { __u8 _pad9[276]; /* 0xeec */ } __attribute__((packed)); -#endif /* _ASM_BOOTPARAM_H */ +#endif /* ASM_X86__BOOTPARAM_H */ diff --git a/include/asm-x86/bug.h b/include/asm-x86/bug.h index b69aa64b82a..91ad43a54c4 100644 --- a/include/asm-x86/bug.h +++ b/include/asm-x86/bug.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_BUG_H -#define _ASM_X86_BUG_H +#ifndef ASM_X86__BUG_H +#define ASM_X86__BUG_H #ifdef CONFIG_BUG #define HAVE_ARCH_BUG @@ -36,4 +36,4 @@ do { \ #endif /* !CONFIG_BUG */ #include <asm-generic/bug.h> -#endif +#endif /* ASM_X86__BUG_H */ diff --git a/include/asm-x86/bugs.h b/include/asm-x86/bugs.h index 021cbdd5f25..4761c461d23 100644 --- a/include/asm-x86/bugs.h +++ b/include/asm-x86/bugs.h @@ -1,7 +1,7 @@ -#ifndef _ASM_X86_BUGS_H -#define _ASM_X86_BUGS_H +#ifndef ASM_X86__BUGS_H +#define ASM_X86__BUGS_H extern void check_bugs(void); int ppro_with_ram_bug(void); -#endif /* _ASM_X86_BUGS_H */ +#endif /* ASM_X86__BUGS_H */ diff --git a/include/asm-x86/byteorder.h b/include/asm-x86/byteorder.h index e02ae2d89ac..722f27d6810 100644 --- a/include/asm-x86/byteorder.h +++ b/include/asm-x86/byteorder.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_BYTEORDER_H -#define _ASM_X86_BYTEORDER_H +#ifndef ASM_X86__BYTEORDER_H +#define ASM_X86__BYTEORDER_H #include <asm/types.h> #include <linux/compiler.h> @@ -78,4 +78,4 @@ static inline __attribute_const__ __u32 ___arch__swab32(__u32 x) #include <linux/byteorder/little_endian.h> -#endif /* _ASM_X86_BYTEORDER_H */ +#endif /* ASM_X86__BYTEORDER_H */ diff --git a/include/asm-x86/cache.h b/include/asm-x86/cache.h index 1e0bac86f38..ea3f1cc06a9 100644 --- a/include/asm-x86/cache.h +++ b/include/asm-x86/cache.h @@ -1,5 +1,5 @@ -#ifndef _ARCH_X86_CACHE_H -#define _ARCH_X86_CACHE_H +#ifndef ASM_X86__CACHE_H +#define ASM_X86__CACHE_H /* L1 cache line size */ #define L1_CACHE_SHIFT (CONFIG_X86_L1_CACHE_SHIFT) @@ -17,4 +17,4 @@ #endif #endif -#endif +#endif /* ASM_X86__CACHE_H */ diff --git a/include/asm-x86/cacheflush.h b/include/asm-x86/cacheflush.h index f4c0ab50d2c..59859cb28a3 100644 --- a/include/asm-x86/cacheflush.h +++ b/include/asm-x86/cacheflush.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_CACHEFLUSH_H -#define _ASM_X86_CACHEFLUSH_H +#ifndef ASM_X86__CACHEFLUSH_H +#define ASM_X86__CACHEFLUSH_H /* Keep includes the same across arches. */ #include <linux/mm.h> @@ -112,4 +112,4 @@ static inline int rodata_test(void) } #endif -#endif +#endif /* ASM_X86__CACHEFLUSH_H */ diff --git a/include/asm-x86/calgary.h b/include/asm-x86/calgary.h index 67f60406e2d..933fd272f82 100644 --- a/include/asm-x86/calgary.h +++ b/include/asm-x86/calgary.h @@ -21,8 +21,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _ASM_X86_64_CALGARY_H -#define _ASM_X86_64_CALGARY_H +#ifndef ASM_X86__CALGARY_H +#define ASM_X86__CALGARY_H #include <linux/spinlock.h> #include <linux/device.h> @@ -69,4 +69,4 @@ static inline int calgary_iommu_init(void) { return 1; } static inline void detect_calgary(void) { return; } #endif -#endif /* _ASM_X86_64_CALGARY_H */ +#endif /* ASM_X86__CALGARY_H */ diff --git a/include/asm-x86/checksum_32.h b/include/asm-x86/checksum_32.h index 52bbb0d8c4c..d041e8cda22 100644 --- a/include/asm-x86/checksum_32.h +++ b/include/asm-x86/checksum_32.h @@ -1,5 +1,5 @@ -#ifndef _I386_CHECKSUM_H -#define _I386_CHECKSUM_H +#ifndef ASM_X86__CHECKSUM_32_H +#define ASM_X86__CHECKSUM_32_H #include <linux/in6.h> @@ -186,4 +186,4 @@ static inline __wsum csum_and_copy_to_user(const void *src, return (__force __wsum)-1; /* invalid checksum */ } -#endif +#endif /* ASM_X86__CHECKSUM_32_H */ diff --git a/include/asm-x86/checksum_64.h b/include/asm-x86/checksum_64.h index 8bd861cc526..110f403beb8 100644 --- a/include/asm-x86/checksum_64.h +++ b/include/asm-x86/checksum_64.h @@ -1,5 +1,5 @@ -#ifndef _X86_64_CHECKSUM_H -#define _X86_64_CHECKSUM_H +#ifndef ASM_X86__CHECKSUM_64_H +#define ASM_X86__CHECKSUM_64_H /* * Checksums for x86-64 @@ -188,4 +188,4 @@ static inline unsigned add32_with_carry(unsigned a, unsigned b) return a; } -#endif +#endif /* ASM_X86__CHECKSUM_64_H */ diff --git a/include/asm-x86/cmpxchg_32.h b/include/asm-x86/cmpxchg_32.h index bf5a69d1329..0622e45cdf7 100644 --- a/include/asm-x86/cmpxchg_32.h +++ b/include/asm-x86/cmpxchg_32.h @@ -1,5 +1,5 @@ -#ifndef __ASM_CMPXCHG_H -#define __ASM_CMPXCHG_H +#ifndef ASM_X86__CMPXCHG_32_H +#define ASM_X86__CMPXCHG_32_H #include <linux/bitops.h> /* for LOCK_PREFIX */ @@ -341,4 +341,4 @@ extern unsigned long long cmpxchg_486_u64(volatile void *, u64, u64); #endif -#endif +#endif /* ASM_X86__CMPXCHG_32_H */ diff --git a/include/asm-x86/cmpxchg_64.h b/include/asm-x86/cmpxchg_64.h index 17463ccf816..63c1a5e61b9 100644 --- a/include/asm-x86/cmpxchg_64.h +++ b/include/asm-x86/cmpxchg_64.h @@ -1,5 +1,5 @@ -#ifndef __ASM_CMPXCHG_H -#define __ASM_CMPXCHG_H +#ifndef ASM_X86__CMPXCHG_64_H +#define ASM_X86__CMPXCHG_64_H #include <asm/alternative.h> /* Provides LOCK_PREFIX */ @@ -182,4 +182,4 @@ static inline unsigned long __cmpxchg_local(volatile void *ptr, cmpxchg_local((ptr), (o), (n)); \ }) -#endif +#endif /* ASM_X86__CMPXCHG_64_H */ diff --git a/include/asm-x86/compat.h b/include/asm-x86/compat.h index 1793ac317a3..6732b150949 100644 --- a/include/asm-x86/compat.h +++ b/include/asm-x86/compat.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_64_COMPAT_H -#define _ASM_X86_64_COMPAT_H +#ifndef ASM_X86__COMPAT_H +#define ASM_X86__COMPAT_H /* * Architecture specific compatibility types @@ -215,4 +215,4 @@ static inline int is_compat_task(void) return current_thread_info()->status & TS_COMPAT; } -#endif /* _ASM_X86_64_COMPAT_H */ +#endif /* ASM_X86__COMPAT_H */ diff --git a/include/asm-x86/cpu.h b/include/asm-x86/cpu.h index 73f2ea84fd7..83a115083f0 100644 --- a/include/asm-x86/cpu.h +++ b/include/asm-x86/cpu.h @@ -1,5 +1,5 @@ -#ifndef _ASM_I386_CPU_H_ -#define _ASM_I386_CPU_H_ +#ifndef ASM_X86__CPU_H +#define ASM_X86__CPU_H #include <linux/device.h> #include <linux/cpu.h> @@ -17,4 +17,4 @@ extern void arch_unregister_cpu(int); #endif DECLARE_PER_CPU(int, cpu_state); -#endif /* _ASM_I386_CPU_H_ */ +#endif /* ASM_X86__CPU_H */ diff --git a/include/asm-x86/cpufeature.h b/include/asm-x86/cpufeature.h index 9489283a4bc..250fa0cb144 100644 --- a/include/asm-x86/cpufeature.h +++ b/include/asm-x86/cpufeature.h @@ -1,8 +1,8 @@ /* * Defines x86 CPU feature bits */ -#ifndef _ASM_X86_CPUFEATURE_H -#define _ASM_X86_CPUFEATURE_H +#ifndef ASM_X86__CPUFEATURE_H +#define ASM_X86__CPUFEATURE_H #include <asm/required-features.h> @@ -81,6 +81,7 @@ #define X86_FEATURE_LFENCE_RDTSC (3*32+18) /* Lfence synchronizes RDTSC */ #define X86_FEATURE_11AP (3*32+19) /* Bad local APIC aka 11AP */ #define X86_FEATURE_NOPL (3*32+20) /* The NOPL (0F 1F) instructions */ +#define X86_FEATURE_AMDC1E (3*32+21) /* AMD C1E detected */ /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */ #define X86_FEATURE_XMM3 (4*32+ 0) /* Streaming SIMD Extensions-3 */ @@ -223,4 +224,4 @@ extern const char * const x86_power_flags[32]; #endif /* defined(__KERNEL__) && !defined(__ASSEMBLY__) */ -#endif /* _ASM_X86_CPUFEATURE_H */ +#endif /* ASM_X86__CPUFEATURE_H */ diff --git a/include/asm-x86/current.h b/include/asm-x86/current.h index 7515c19d498..a863ead856f 100644 --- a/include/asm-x86/current.h +++ b/include/asm-x86/current.h @@ -1,5 +1,5 @@ -#ifndef _X86_CURRENT_H -#define _X86_CURRENT_H +#ifndef ASM_X86__CURRENT_H +#define ASM_X86__CURRENT_H #ifdef CONFIG_X86_32 #include <linux/compiler.h> @@ -36,4 +36,4 @@ static __always_inline struct task_struct *get_current(void) #define current get_current() -#endif /* X86_CURRENT_H */ +#endif /* ASM_X86__CURRENT_H */ diff --git a/include/asm-x86/debugreg.h b/include/asm-x86/debugreg.h index c6344d572b0..ecb6907c3ea 100644 --- a/include/asm-x86/debugreg.h +++ b/include/asm-x86/debugreg.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_DEBUGREG_H -#define _ASM_X86_DEBUGREG_H +#ifndef ASM_X86__DEBUGREG_H +#define ASM_X86__DEBUGREG_H /* Indicate the register numbers for a number of the specific @@ -67,4 +67,4 @@ #define DR_LOCAL_SLOWDOWN (0x100) /* Local slow the pipeline */ #define DR_GLOBAL_SLOWDOWN (0x200) /* Global slow the pipeline */ -#endif +#endif /* ASM_X86__DEBUGREG_H */ diff --git a/include/asm-x86/delay.h b/include/asm-x86/delay.h index 409a649204a..8a0da95b4fc 100644 --- a/include/asm-x86/delay.h +++ b/include/asm-x86/delay.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_DELAY_H -#define _ASM_X86_DELAY_H +#ifndef ASM_X86__DELAY_H +#define ASM_X86__DELAY_H /* * Copyright (C) 1993 Linus Torvalds @@ -28,4 +28,4 @@ extern void __delay(unsigned long loops); void use_tsc_delay(void); -#endif /* _ASM_X86_DELAY_H */ +#endif /* ASM_X86__DELAY_H */ diff --git a/include/asm-x86/desc.h b/include/asm-x86/desc.h index a44c4dc7059..b73fea54def 100644 --- a/include/asm-x86/desc.h +++ b/include/asm-x86/desc.h @@ -1,5 +1,5 @@ -#ifndef _ASM_DESC_H_ -#define _ASM_DESC_H_ +#ifndef ASM_X86__DESC_H +#define ASM_X86__DESC_H #ifndef __ASSEMBLY__ #include <asm/desc_defs.h> @@ -397,4 +397,4 @@ static inline void set_system_gate_ist(int n, void *addr, unsigned ist) #endif /* __ASSEMBLY__ */ -#endif +#endif /* ASM_X86__DESC_H */ diff --git a/include/asm-x86/desc_defs.h b/include/asm-x86/desc_defs.h index f7bacf357da..b881db664b4 100644 --- a/include/asm-x86/desc_defs.h +++ b/include/asm-x86/desc_defs.h @@ -1,6 +1,6 @@ /* Written 2000 by Andi Kleen */ -#ifndef __ARCH_DESC_DEFS_H -#define __ARCH_DESC_DEFS_H +#ifndef ASM_X86__DESC_DEFS_H +#define ASM_X86__DESC_DEFS_H /* * Segment descriptor structure definitions, usable from both x86_64 and i386 @@ -92,4 +92,4 @@ struct desc_ptr { #endif /* !__ASSEMBLY__ */ -#endif +#endif /* ASM_X86__DESC_DEFS_H */ diff --git a/include/asm-x86/device.h b/include/asm-x86/device.h index 3c034f48fdb..1bece04c7d9 100644 --- a/include/asm-x86/device.h +++ b/include/asm-x86/device.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_DEVICE_H -#define _ASM_X86_DEVICE_H +#ifndef ASM_X86__DEVICE_H +#define ASM_X86__DEVICE_H struct dev_archdata { #ifdef CONFIG_ACPI @@ -13,4 +13,4 @@ struct dma_mapping_ops *dma_ops; #endif }; -#endif /* _ASM_X86_DEVICE_H */ +#endif /* ASM_X86__DEVICE_H */ diff --git a/include/asm-x86/div64.h b/include/asm-x86/div64.h index 9a2d644c08e..f9530f23f1d 100644 --- a/include/asm-x86/div64.h +++ b/include/asm-x86/div64.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_DIV64_H -#define _ASM_X86_DIV64_H +#ifndef ASM_X86__DIV64_H +#define ASM_X86__DIV64_H #ifdef CONFIG_X86_32 @@ -57,4 +57,4 @@ static inline u64 div_u64_rem(u64 dividend, u32 divisor, u32 *remainder) # include <asm-generic/div64.h> #endif /* CONFIG_X86_32 */ -#endif /* _ASM_X86_DIV64_H */ +#endif /* ASM_X86__DIV64_H */ diff --git a/include/asm-x86/dma-mapping.h b/include/asm-x86/dma-mapping.h index ad9cd6d49bf..5d200e78bd8 100644 --- a/include/asm-x86/dma-mapping.h +++ b/include/asm-x86/dma-mapping.h @@ -1,5 +1,5 @@ -#ifndef _ASM_DMA_MAPPING_H_ -#define _ASM_DMA_MAPPING_H_ +#ifndef ASM_X86__DMA_MAPPING_H +#define ASM_X86__DMA_MAPPING_H /* * IOMMU interface. See Documentation/DMA-mapping.txt and DMA-API.txt for @@ -250,4 +250,4 @@ static inline int dma_get_cache_alignment(void) #define dma_is_consistent(d, h) (1) #include <asm-generic/dma-coherent.h> -#endif +#endif /* ASM_X86__DMA_MAPPING_H */ diff --git a/include/asm-x86/dma.h b/include/asm-x86/dma.h index ca1098a7e58..c9f7a4eec55 100644 --- a/include/asm-x86/dma.h +++ b/include/asm-x86/dma.h @@ -5,8 +5,8 @@ * and John Boyd, Nov. 1992. */ -#ifndef _ASM_X86_DMA_H -#define _ASM_X86_DMA_H +#ifndef ASM_X86__DMA_H +#define ASM_X86__DMA_H #include <linux/spinlock.h> /* And spinlocks */ #include <asm/io.h> /* need byte IO */ @@ -315,4 +315,4 @@ extern int isa_dma_bridge_buggy; #define isa_dma_bridge_buggy (0) #endif -#endif /* _ASM_X86_DMA_H */ +#endif /* ASM_X86__DMA_H */ diff --git a/include/asm-x86/dmi.h b/include/asm-x86/dmi.h index 58a86571fe0..1cff6fe81fa 100644 --- a/include/asm-x86/dmi.h +++ b/include/asm-x86/dmi.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_DMI_H -#define _ASM_X86_DMI_H +#ifndef ASM_X86__DMI_H +#define ASM_X86__DMI_H #include <asm/io.h> @@ -23,4 +23,4 @@ static inline void *dmi_alloc(unsigned len) #define dmi_ioremap early_ioremap #define dmi_iounmap early_iounmap -#endif +#endif /* ASM_X86__DMI_H */ diff --git a/include/asm-x86/ds.h b/include/asm-x86/ds.h index 7881368142f..c3c953a45b2 100644 --- a/include/asm-x86/ds.h +++ b/include/asm-x86/ds.h @@ -2,71 +2,237 @@ * Debug Store (DS) support * * This provides a low-level interface to the hardware's Debug Store - * feature that is used for last branch recording (LBR) and + * feature that is used for branch trace store (BTS) and * precise-event based sampling (PEBS). * - * Different architectures use a different DS layout/pointer size. - * The below functions therefore work on a void*. + * It manages: + * - per-thread and per-cpu allocation of BTS and PEBS + * - buffer memory allocation (optional) + * - buffer overflow handling + * - buffer access * + * It assumes: + * - get_task_struct on all parameter tasks + * - current is allowed to trace parameter tasks * - * Since there is no user for PEBS, yet, only LBR (or branch - * trace store, BTS) is supported. * - * - * Copyright (C) 2007 Intel Corporation. - * Markus Metzger <markus.t.metzger@intel.com>, Dec 2007 + * Copyright (C) 2007-2008 Intel Corporation. + * Markus Metzger <markus.t.metzger@intel.com>, 2007-2008 */ -#ifndef _ASM_X86_DS_H -#define _ASM_X86_DS_H +#ifndef ASM_X86__DS_H +#define ASM_X86__DS_H + +#ifdef CONFIG_X86_DS #include <linux/types.h> #include <linux/init.h> -struct cpuinfo_x86; +struct task_struct; -/* a branch trace record entry +/* + * Request BTS or PEBS + * + * Due to alignement constraints, the actual buffer may be slightly + * smaller than the requested or provided buffer. * - * In order to unify the interface between various processor versions, - * we use the below data structure for all processors. + * Returns 0 on success; -Eerrno otherwise + * + * task: the task to request recording for; + * NULL for per-cpu recording on the current cpu + * base: the base pointer for the (non-pageable) buffer; + * NULL if buffer allocation requested + * size: the size of the requested or provided buffer + * ovfl: pointer to a function to be called on buffer overflow; + * NULL if cyclic buffer requested */ -enum bts_qualifier { - BTS_INVALID = 0, - BTS_BRANCH, - BTS_TASK_ARRIVES, - BTS_TASK_DEPARTS -}; +typedef void (*ds_ovfl_callback_t)(struct task_struct *); +extern int ds_request_bts(struct task_struct *task, void *base, size_t size, + ds_ovfl_callback_t ovfl); +extern int ds_request_pebs(struct task_struct *task, void *base, size_t size, + ds_ovfl_callback_t ovfl); -struct bts_struct { - u64 qualifier; - union { - /* BTS_BRANCH */ - struct { - u64 from_ip; - u64 to_ip; - } lbr; - /* BTS_TASK_ARRIVES or - BTS_TASK_DEPARTS */ - u64 jiffies; - } variant; +/* + * Release BTS or PEBS resources + * + * Frees buffers allocated on ds_request. + * + * Returns 0 on success; -Eerrno otherwise + * + * task: the task to release resources for; + * NULL to release resources for the current cpu + */ +extern int ds_release_bts(struct task_struct *task); +extern int ds_release_pebs(struct task_struct *task); + +/* + * Return the (array) index of the write pointer. + * (assuming an array of BTS/PEBS records) + * + * Returns -Eerrno on error + * + * task: the task to access; + * NULL to access the current cpu + * pos (out): if not NULL, will hold the result + */ +extern int ds_get_bts_index(struct task_struct *task, size_t *pos); +extern int ds_get_pebs_index(struct task_struct *task, size_t *pos); + +/* + * Return the (array) index one record beyond the end of the array. + * (assuming an array of BTS/PEBS records) + * + * Returns -Eerrno on error + * + * task: the task to access; + * NULL to access the current cpu + * pos (out): if not NULL, will hold the result + */ +extern int ds_get_bts_end(struct task_struct *task, size_t *pos); +extern int ds_get_pebs_end(struct task_struct *task, size_t *pos); + +/* + * Provide a pointer to the BTS/PEBS record at parameter index. + * (assuming an array of BTS/PEBS records) + * + * The pointer points directly into the buffer. The user is + * responsible for copying the record. + * + * Returns the size of a single record on success; -Eerrno on error + * + * task: the task to access; + * NULL to access the current cpu + * index: the index of the requested record + * record (out): pointer to the requested record + */ +extern int ds_access_bts(struct task_struct *task, + size_t index, const void **record); +extern int ds_access_pebs(struct task_struct *task, + size_t index, const void **record); + +/* + * Write one or more BTS/PEBS records at the write pointer index and + * advance the write pointer. + * + * If size is not a multiple of the record size, trailing bytes are + * zeroed out. + * + * May result in one or more overflow notifications. + * + * If called during overflow handling, that is, with index >= + * interrupt threshold, the write will wrap around. + * + * An overflow notification is given if and when the interrupt + * threshold is reached during or after the write. + * + * Returns the number of bytes written or -Eerrno. + * + * task: the task to access; + * NULL to access the current cpu + * buffer: the buffer to write + * size: the size of the buffer + */ +extern int ds_write_bts(struct task_struct *task, + const void *buffer, size_t size); +extern int ds_write_pebs(struct task_struct *task, + const void *buffer, size_t size); + +/* + * Same as ds_write_bts/pebs, but omit ownership checks. + * + * This is needed to have some other task than the owner of the + * BTS/PEBS buffer or the parameter task itself write into the + * respective buffer. + */ +extern int ds_unchecked_write_bts(struct task_struct *task, + const void *buffer, size_t size); +extern int ds_unchecked_write_pebs(struct task_struct *task, + const void *buffer, size_t size); + +/* + * Reset the write pointer of the BTS/PEBS buffer. + * + * Returns 0 on success; -Eerrno on error + * + * task: the task to access; + * NULL to access the current cpu + */ +extern int ds_reset_bts(struct task_struct *task); +extern int ds_reset_pebs(struct task_struct *task); + +/* + * Clear the BTS/PEBS buffer and reset the write pointer. + * The entire buffer will be zeroed out. + * + * Returns 0 on success; -Eerrno on error + * + * task: the task to access; + * NULL to access the current cpu + */ +extern int ds_clear_bts(struct task_struct *task); +extern int ds_clear_pebs(struct task_struct *task); + +/* + * Provide the PEBS counter reset value. + * + * Returns 0 on success; -Eerrno on error + * + * task: the task to access; + * NULL to access the current cpu + * value (out): the counter reset value + */ +extern int ds_get_pebs_reset(struct task_struct *task, u64 *value); + +/* + * Set the PEBS counter reset value. + * + * Returns 0 on success; -Eerrno on error + * + * task: the task to access; + * NULL to access the current cpu + * value: the new counter reset value + */ +extern int ds_set_pebs_reset(struct task_struct *task, u64 value); + +/* + * Initialization + */ +struct cpuinfo_x86; +extern void __cpuinit ds_init_intel(struct cpuinfo_x86 *); + + + +/* + * The DS context - part of struct thread_struct. + */ +struct ds_context { + /* pointer to the DS configuration; goes into MSR_IA32_DS_AREA */ + unsigned char *ds; + /* the owner of the BTS and PEBS configuration, respectively */ + struct task_struct *owner[2]; + /* buffer overflow notification function for BTS and PEBS */ + ds_ovfl_callback_t callback[2]; + /* the original buffer address */ + void *buffer[2]; + /* the number of allocated pages for on-request allocated buffers */ + unsigned int pages[2]; + /* use count */ + unsigned long count; + /* a pointer to the context location inside the thread_struct + * or the per_cpu context array */ + struct ds_context **this; + /* a pointer to the task owning this context, or NULL, if the + * context is owned by a cpu */ + struct task_struct *task; }; -/* Overflow handling mechanisms */ -#define DS_O_SIGNAL 1 /* send overflow signal */ -#define DS_O_WRAP 2 /* wrap around */ - -extern int ds_allocate(void **, size_t); -extern int ds_free(void **); -extern int ds_get_bts_size(void *); -extern int ds_get_bts_end(void *); -extern int ds_get_bts_index(void *); -extern int ds_set_overflow(void *, int); -extern int ds_get_overflow(void *); -extern int ds_clear(void *); -extern int ds_read_bts(void *, int, struct bts_struct *); -extern int ds_write_bts(void *, const struct bts_struct *); -extern unsigned long ds_debugctl_mask(void); -extern void __cpuinit ds_init_intel(struct cpuinfo_x86 *c); - -#endif /* _ASM_X86_DS_H */ +/* called by exit_thread() to free leftover contexts */ +extern void ds_free(struct ds_context *context); + +#else /* CONFIG_X86_DS */ + +#define ds_init_intel(config) do {} while (0) + +#endif /* CONFIG_X86_DS */ +#endif /* ASM_X86__DS_H */ diff --git a/include/asm-x86/dwarf2.h b/include/asm-x86/dwarf2.h index 738bb9fb3e5..21d1bc32ad7 100644 --- a/include/asm-x86/dwarf2.h +++ b/include/asm-x86/dwarf2.h @@ -1,5 +1,5 @@ -#ifndef _DWARF2_H -#define _DWARF2_H +#ifndef ASM_X86__DWARF2_H +#define ASM_X86__DWARF2_H #ifndef __ASSEMBLY__ #warning "asm/dwarf2.h should be only included in pure assembly files" @@ -58,4 +58,4 @@ #endif -#endif +#endif /* ASM_X86__DWARF2_H */ diff --git a/include/asm-x86/e820.h b/include/asm-x86/e820.h index 16a31e2c7c5..f52daf176bc 100644 --- a/include/asm-x86/e820.h +++ b/include/asm-x86/e820.h @@ -1,5 +1,5 @@ -#ifndef __ASM_E820_H -#define __ASM_E820_H +#ifndef ASM_X86__E820_H +#define ASM_X86__E820_H #define E820MAP 0x2d0 /* our map */ #define E820MAX 128 /* number of entries in E820MAP */ @@ -64,6 +64,7 @@ struct e820map { extern struct e820map e820; extern struct e820map e820_saved; +extern unsigned long pci_mem_start; extern int e820_any_mapped(u64 start, u64 end, unsigned type); extern int e820_all_mapped(u64 start, u64 end, unsigned type); extern void e820_add_region(u64 start, u64 size, int type); @@ -140,4 +141,4 @@ extern char *memory_setup(void); #define HIGH_MEMORY (1024*1024) #endif /* __KERNEL__ */ -#endif /* __ASM_E820_H */ +#endif /* ASM_X86__E820_H */ diff --git a/include/asm-x86/edac.h b/include/asm-x86/edac.h index a8088f63a30..9493c5b27bb 100644 --- a/include/asm-x86/edac.h +++ b/include/asm-x86/edac.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_EDAC_H -#define _ASM_X86_EDAC_H +#ifndef ASM_X86__EDAC_H +#define ASM_X86__EDAC_H /* ECC atomic, DMA, SMP and interrupt safe scrub function */ @@ -15,4 +15,4 @@ static inline void atomic_scrub(void *va, u32 size) asm volatile("lock; addl $0, %0"::"m" (*virt_addr)); } -#endif +#endif /* ASM_X86__EDAC_H */ diff --git a/include/asm-x86/efi.h b/include/asm-x86/efi.h index d4f2b0abe92..ed2de22e870 100644 --- a/include/asm-x86/efi.h +++ b/include/asm-x86/efi.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_EFI_H -#define _ASM_X86_EFI_H +#ifndef ASM_X86__EFI_H +#define ASM_X86__EFI_H #ifdef CONFIG_X86_32 @@ -94,4 +94,4 @@ extern void efi_reserve_early(void); extern void efi_call_phys_prelog(void); extern void efi_call_phys_epilog(void); -#endif +#endif /* ASM_X86__EFI_H */ diff --git a/include/asm-x86/elf.h b/include/asm-x86/elf.h index 7be4733c793..5c4745bec90 100644 --- a/include/asm-x86/elf.h +++ b/include/asm-x86/elf.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_ELF_H -#define _ASM_X86_ELF_H +#ifndef ASM_X86__ELF_H +#define ASM_X86__ELF_H /* * ELF register definitions.. @@ -148,8 +148,9 @@ do { \ static inline void start_ia32_thread(struct pt_regs *regs, u32 ip, u32 sp) { - asm volatile("movl %0,%%fs" :: "r" (0)); - asm volatile("movl %0,%%es; movl %0,%%ds" : : "r" (__USER32_DS)); + loadsegment(fs, 0); + loadsegment(ds, __USER32_DS); + loadsegment(es, __USER32_DS); load_gs_index(0); regs->ip = ip; regs->sp = sp; @@ -332,4 +333,4 @@ extern int syscall32_setup_pages(struct linux_binprm *, int exstack); extern unsigned long arch_randomize_brk(struct mm_struct *mm); #define arch_randomize_brk arch_randomize_brk -#endif +#endif /* ASM_X86__ELF_H */ diff --git a/include/asm-x86/emergency-restart.h b/include/asm-x86/emergency-restart.h index 8e6aef19f8f..190d0d8b71e 100644 --- a/include/asm-x86/emergency-restart.h +++ b/include/asm-x86/emergency-restart.h @@ -1,5 +1,5 @@ -#ifndef _ASM_EMERGENCY_RESTART_H -#define _ASM_EMERGENCY_RESTART_H +#ifndef ASM_X86__EMERGENCY_RESTART_H +#define ASM_X86__EMERGENCY_RESTART_H enum reboot_type { BOOT_TRIPLE = 't', @@ -15,4 +15,4 @@ extern enum reboot_type reboot_type; extern void machine_emergency_restart(void); -#endif /* _ASM_EMERGENCY_RESTART_H */ +#endif /* ASM_X86__EMERGENCY_RESTART_H */ diff --git a/include/asm-x86/fb.h b/include/asm-x86/fb.h index 53018464aea..aca38dbd9a6 100644 --- a/include/asm-x86/fb.h +++ b/include/asm-x86/fb.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_FB_H -#define _ASM_X86_FB_H +#ifndef ASM_X86__FB_H +#define ASM_X86__FB_H #include <linux/fb.h> #include <linux/fs.h> @@ -18,4 +18,4 @@ extern int fb_is_primary_device(struct fb_info *info); static inline int fb_is_primary_device(struct fb_info *info) { return 0; } #endif -#endif /* _ASM_X86_FB_H */ +#endif /* ASM_X86__FB_H */ diff --git a/include/asm-x86/fixmap.h b/include/asm-x86/fixmap.h index 44d4f821734..78e33a1bc59 100644 --- a/include/asm-x86/fixmap.h +++ b/include/asm-x86/fixmap.h @@ -1,5 +1,5 @@ -#ifndef _ASM_FIXMAP_H -#define _ASM_FIXMAP_H +#ifndef ASM_X86__FIXMAP_H +#define ASM_X86__FIXMAP_H #ifdef CONFIG_X86_32 # include "fixmap_32.h" @@ -65,4 +65,4 @@ static inline unsigned long virt_to_fix(const unsigned long vaddr) BUG_ON(vaddr >= FIXADDR_TOP || vaddr < FIXADDR_START); return __virt_to_fix(vaddr); } -#endif +#endif /* ASM_X86__FIXMAP_H */ diff --git a/include/asm-x86/fixmap_32.h b/include/asm-x86/fixmap_32.h index f1ac2b2167d..784e3e75986 100644 --- a/include/asm-x86/fixmap_32.h +++ b/include/asm-x86/fixmap_32.h @@ -10,8 +10,8 @@ * Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999 */ -#ifndef _ASM_FIXMAP_32_H -#define _ASM_FIXMAP_32_H +#ifndef ASM_X86__FIXMAP_32_H +#define ASM_X86__FIXMAP_32_H /* used by vmalloc.c, vsyscall.lds.S. @@ -120,4 +120,4 @@ extern void reserve_top_address(unsigned long reserve); #define FIXADDR_BOOT_START (FIXADDR_TOP - __FIXADDR_BOOT_SIZE) #endif /* !__ASSEMBLY__ */ -#endif +#endif /* ASM_X86__FIXMAP_32_H */ diff --git a/include/asm-x86/fixmap_64.h b/include/asm-x86/fixmap_64.h index 00f3d74a052..dafb24bc042 100644 --- a/include/asm-x86/fixmap_64.h +++ b/include/asm-x86/fixmap_64.h @@ -8,8 +8,8 @@ * Copyright (C) 1998 Ingo Molnar */ -#ifndef _ASM_FIXMAP_64_H -#define _ASM_FIXMAP_64_H +#ifndef ASM_X86__FIXMAP_64_H +#define ASM_X86__FIXMAP_64_H #include <linux/kernel.h> #include <asm/acpi.h> @@ -80,4 +80,4 @@ enum fixed_addresses { #define FIXADDR_USER_START ((unsigned long)VSYSCALL32_VSYSCALL) #define FIXADDR_USER_END (FIXADDR_USER_START + PAGE_SIZE) -#endif +#endif /* ASM_X86__FIXMAP_64_H */ diff --git a/include/asm-x86/floppy.h b/include/asm-x86/floppy.h index dbe82a5c5ea..7d83a3a83e3 100644 --- a/include/asm-x86/floppy.h +++ b/include/asm-x86/floppy.h @@ -7,8 +7,8 @@ * * Copyright (C) 1995 */ -#ifndef _ASM_X86_FLOPPY_H -#define _ASM_X86_FLOPPY_H +#ifndef ASM_X86__FLOPPY_H +#define ASM_X86__FLOPPY_H #include <linux/vmalloc.h> @@ -278,4 +278,4 @@ static int FDC2 = -1; #define EXTRA_FLOPPY_PARAMS -#endif /* _ASM_X86_FLOPPY_H */ +#endif /* ASM_X86__FLOPPY_H */ diff --git a/include/asm-x86/ftrace.h b/include/asm-x86/ftrace.h index 5c68b32ee1c..be0e004ad14 100644 --- a/include/asm-x86/ftrace.h +++ b/include/asm-x86/ftrace.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_FTRACE -#define _ASM_X86_FTRACE +#ifndef ASM_X86__FTRACE_H +#define ASM_X86__FTRACE_H #ifdef CONFIG_FTRACE #define MCOUNT_ADDR ((long)(mcount)) @@ -11,4 +11,4 @@ extern void mcount(void); #endif /* CONFIG_FTRACE */ -#endif /* _ASM_X86_FTRACE */ +#endif /* ASM_X86__FTRACE_H */ diff --git a/include/asm-x86/futex.h b/include/asm-x86/futex.h index e7a76b37b33..06b924ef6fa 100644 --- a/include/asm-x86/futex.h +++ b/include/asm-x86/futex.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_FUTEX_H -#define _ASM_X86_FUTEX_H +#ifndef ASM_X86__FUTEX_H +#define ASM_X86__FUTEX_H #ifdef __KERNEL__ @@ -25,7 +25,7 @@ asm volatile("1:\tmovl %2, %0\n" \ "\tmovl\t%0, %3\n" \ "\t" insn "\n" \ - "2:\tlock; cmpxchgl %3, %2\n" \ + "2:\t" LOCK_PREFIX "cmpxchgl %3, %2\n" \ "\tjnz\t1b\n" \ "3:\t.section .fixup,\"ax\"\n" \ "4:\tmov\t%5, %1\n" \ @@ -64,7 +64,7 @@ static inline int futex_atomic_op_inuser(int encoded_op, int __user *uaddr) __futex_atomic_op1("xchgl %0, %2", ret, oldval, uaddr, oparg); break; case FUTEX_OP_ADD: - __futex_atomic_op1("lock; xaddl %0, %2", ret, oldval, + __futex_atomic_op1(LOCK_PREFIX "xaddl %0, %2", ret, oldval, uaddr, oparg); break; case FUTEX_OP_OR: @@ -122,7 +122,7 @@ static inline int futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int))) return -EFAULT; - asm volatile("1:\tlock; cmpxchgl %3, %1\n" + asm volatile("1:\t" LOCK_PREFIX "cmpxchgl %3, %1\n" "2:\t.section .fixup, \"ax\"\n" "3:\tmov %2, %0\n" "\tjmp 2b\n" @@ -137,4 +137,4 @@ static inline int futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, } #endif -#endif +#endif /* ASM_X86__FUTEX_H */ diff --git a/include/asm-x86/gart.h b/include/asm-x86/gart.h index 3f62a83887f..baa54faba89 100644 --- a/include/asm-x86/gart.h +++ b/include/asm-x86/gart.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X8664_GART_H -#define _ASM_X8664_GART_H 1 +#ifndef ASM_X86__GART_H +#define ASM_X86__GART_H #include <asm/e820.h> @@ -52,15 +52,15 @@ static inline int aperture_valid(u64 aper_base, u32 aper_size, u32 min_size) return 0; if (aper_base + aper_size > 0x100000000ULL) { - printk(KERN_ERR "Aperture beyond 4GB. Ignoring.\n"); + printk(KERN_INFO "Aperture beyond 4GB. Ignoring.\n"); return 0; } if (e820_any_mapped(aper_base, aper_base + aper_size, E820_RAM)) { - printk(KERN_ERR "Aperture pointing to e820 RAM. Ignoring.\n"); + printk(KERN_INFO "Aperture pointing to e820 RAM. Ignoring.\n"); return 0; } if (aper_size < min_size) { - printk(KERN_ERR "Aperture too small (%d MB) than (%d MB)\n", + printk(KERN_INFO "Aperture too small (%d MB) than (%d MB)\n", aper_size>>20, min_size>>20); return 0; } @@ -68,4 +68,4 @@ static inline int aperture_valid(u64 aper_base, u32 aper_size, u32 min_size) return 1; } -#endif +#endif /* ASM_X86__GART_H */ diff --git a/include/asm-x86/genapic_32.h b/include/asm-x86/genapic_32.h index 754d635f90f..34280f02766 100644 --- a/include/asm-x86/genapic_32.h +++ b/include/asm-x86/genapic_32.h @@ -1,5 +1,5 @@ -#ifndef _ASM_GENAPIC_H -#define _ASM_GENAPIC_H 1 +#ifndef ASM_X86__GENAPIC_32_H +#define ASM_X86__GENAPIC_32_H #include <asm/mpspec.h> @@ -121,4 +121,4 @@ enum uv_system_type {UV_NONE, UV_LEGACY_APIC, UV_X2APIC, UV_NON_UNIQUE_APIC}; #define uv_system_init() do {} while (0) -#endif +#endif /* ASM_X86__GENAPIC_32_H */ diff --git a/include/asm-x86/genapic_64.h b/include/asm-x86/genapic_64.h index a47d6312913..25097a8cc5e 100644 --- a/include/asm-x86/genapic_64.h +++ b/include/asm-x86/genapic_64.h @@ -1,5 +1,5 @@ -#ifndef _ASM_GENAPIC_H -#define _ASM_GENAPIC_H 1 +#ifndef ASM_X86__GENAPIC_64_H +#define ASM_X86__GENAPIC_64_H /* * Copyright 2004 James Cleverdon, IBM. @@ -47,4 +47,4 @@ extern int uv_wakeup_secondary(int phys_apicid, unsigned int start_rip); extern void setup_apic_routing(void); -#endif +#endif /* ASM_X86__GENAPIC_64_H */ diff --git a/include/asm-x86/geode.h b/include/asm-x86/geode.h index 2c1cda0b8a8..3f3444be263 100644 --- a/include/asm-x86/geode.h +++ b/include/asm-x86/geode.h @@ -7,8 +7,8 @@ * as published by the Free Software Foundation. */ -#ifndef _ASM_GEODE_H_ -#define _ASM_GEODE_H_ +#ifndef ASM_X86__GEODE_H +#define ASM_X86__GEODE_H #include <asm/processor.h> #include <linux/io.h> @@ -250,4 +250,4 @@ extern int __init mfgpt_timer_setup(void); static inline int mfgpt_timer_setup(void) { return 0; } #endif -#endif +#endif /* ASM_X86__GEODE_H */ diff --git a/include/asm-x86/gpio.h b/include/asm-x86/gpio.h index c4c91b37c10..497fb980d96 100644 --- a/include/asm-x86/gpio.h +++ b/include/asm-x86/gpio.h @@ -53,4 +53,4 @@ static inline int irq_to_gpio(unsigned int irq) #endif /* CONFIG_GPIOLIB */ -#endif /* _ASM_I386_GPIO_H */ +#endif /* ASM_X86__GPIO_H */ diff --git a/include/asm-x86/hardirq_32.h b/include/asm-x86/hardirq_32.h index 4f85f0f4b56..700fe230d91 100644 --- a/include/asm-x86/hardirq_32.h +++ b/include/asm-x86/hardirq_32.h @@ -1,5 +1,5 @@ -#ifndef __ASM_HARDIRQ_H -#define __ASM_HARDIRQ_H +#ifndef ASM_X86__HARDIRQ_32_H +#define ASM_X86__HARDIRQ_32_H #include <linux/threads.h> #include <linux/irq.h> @@ -25,4 +25,4 @@ DECLARE_PER_CPU(irq_cpustat_t, irq_stat); void ack_bad_irq(unsigned int irq); #include <linux/irq_cpustat.h> -#endif /* __ASM_HARDIRQ_H */ +#endif /* ASM_X86__HARDIRQ_32_H */ diff --git a/include/asm-x86/hardirq_64.h b/include/asm-x86/hardirq_64.h index 95d5e090ed8..f8bd2919a8c 100644 --- a/include/asm-x86/hardirq_64.h +++ b/include/asm-x86/hardirq_64.h @@ -1,5 +1,5 @@ -#ifndef __ASM_HARDIRQ_H -#define __ASM_HARDIRQ_H +#ifndef ASM_X86__HARDIRQ_64_H +#define ASM_X86__HARDIRQ_64_H #include <linux/threads.h> #include <linux/irq.h> @@ -20,4 +20,4 @@ extern void ack_bad_irq(unsigned int irq); -#endif /* __ASM_HARDIRQ_H */ +#endif /* ASM_X86__HARDIRQ_64_H */ diff --git a/include/asm-x86/highmem.h b/include/asm-x86/highmem.h index 4514b16cc72..bc3f6a28031 100644 --- a/include/asm-x86/highmem.h +++ b/include/asm-x86/highmem.h @@ -15,8 +15,8 @@ * Copyright (C) 1999 Ingo Molnar <mingo@redhat.com> */ -#ifndef _ASM_HIGHMEM_H -#define _ASM_HIGHMEM_H +#ifndef ASM_X86__HIGHMEM_H +#define ASM_X86__HIGHMEM_H #ifdef __KERNEL__ @@ -79,4 +79,4 @@ extern void add_highpages_with_active_regions(int nid, unsigned long start_pfn, #endif /* __KERNEL__ */ -#endif /* _ASM_HIGHMEM_H */ +#endif /* ASM_X86__HIGHMEM_H */ diff --git a/include/asm-x86/hpet.h b/include/asm-x86/hpet.h index 82f1ac641bd..cbbbb6d4dd3 100644 --- a/include/asm-x86/hpet.h +++ b/include/asm-x86/hpet.h @@ -1,5 +1,5 @@ -#ifndef ASM_X86_HPET_H -#define ASM_X86_HPET_H +#ifndef ASM_X86__HPET_H +#define ASM_X86__HPET_H #ifdef CONFIG_HPET_TIMER @@ -90,4 +90,4 @@ static inline int is_hpet_enabled(void) { return 0; } #define hpet_readl(a) 0 #endif -#endif /* ASM_X86_HPET_H */ +#endif /* ASM_X86__HPET_H */ diff --git a/include/asm-x86/hugetlb.h b/include/asm-x86/hugetlb.h index 439a9acc132..0b7ec5dc088 100644 --- a/include/asm-x86/hugetlb.h +++ b/include/asm-x86/hugetlb.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_HUGETLB_H -#define _ASM_X86_HUGETLB_H +#ifndef ASM_X86__HUGETLB_H +#define ASM_X86__HUGETLB_H #include <asm/page.h> @@ -90,4 +90,4 @@ static inline void arch_release_hugepage(struct page *page) { } -#endif /* _ASM_X86_HUGETLB_H */ +#endif /* ASM_X86__HUGETLB_H */ diff --git a/include/asm-x86/hw_irq.h b/include/asm-x86/hw_irq.h index edd0b95f14d..65997b15d56 100644 --- a/include/asm-x86/hw_irq.h +++ b/include/asm-x86/hw_irq.h @@ -1,5 +1,5 @@ -#ifndef _ASM_HW_IRQ_H -#define _ASM_HW_IRQ_H +#ifndef ASM_X86__HW_IRQ_H +#define ASM_X86__HW_IRQ_H /* * (C) 1992, 1993 Linus Torvalds, (C) 1997 Ingo Molnar @@ -93,6 +93,26 @@ extern asmlinkage void qic_reschedule_interrupt(void); extern asmlinkage void qic_enable_irq_interrupt(void); extern asmlinkage void qic_call_function_interrupt(void); +/* SMP */ +extern void smp_apic_timer_interrupt(struct pt_regs *); +#ifdef CONFIG_X86_32 +extern void smp_spurious_interrupt(struct pt_regs *); +extern void smp_error_interrupt(struct pt_regs *); +#else +extern asmlinkage void smp_spurious_interrupt(void); +extern asmlinkage void smp_error_interrupt(void); +#endif +#ifdef CONFIG_X86_SMP +extern void smp_reschedule_interrupt(struct pt_regs *); +extern void smp_call_function_interrupt(struct pt_regs *); +extern void smp_call_function_single_interrupt(struct pt_regs *); +#ifdef CONFIG_X86_32 +extern void smp_invalidate_interrupt(struct pt_regs *); +#else +extern asmlinkage void smp_invalidate_interrupt(struct pt_regs *); +#endif +#endif + #ifdef CONFIG_X86_32 extern void (*const interrupt[NR_IRQS])(void); #else @@ -112,4 +132,4 @@ static inline void __setup_vector_irq(int cpu) {} #endif /* !ASSEMBLY_ */ -#endif +#endif /* ASM_X86__HW_IRQ_H */ diff --git a/include/asm-x86/hypertransport.h b/include/asm-x86/hypertransport.h index d2bbd238b3e..cc011a3bc1c 100644 --- a/include/asm-x86/hypertransport.h +++ b/include/asm-x86/hypertransport.h @@ -1,5 +1,5 @@ -#ifndef ASM_HYPERTRANSPORT_H -#define ASM_HYPERTRANSPORT_H +#ifndef ASM_X86__HYPERTRANSPORT_H +#define ASM_X86__HYPERTRANSPORT_H /* * Constants for x86 Hypertransport Interrupts. @@ -42,4 +42,4 @@ #define HT_IRQ_HIGH_DEST_ID(v) \ ((((v) >> 8) << HT_IRQ_HIGH_DEST_ID_SHIFT) & HT_IRQ_HIGH_DEST_ID_MASK) -#endif /* ASM_HYPERTRANSPORT_H */ +#endif /* ASM_X86__HYPERTRANSPORT_H */ diff --git a/include/asm-x86/i387.h b/include/asm-x86/i387.h index 56d00e31aec..1ecdc3ed96e 100644 --- a/include/asm-x86/i387.h +++ b/include/asm-x86/i387.h @@ -7,8 +7,8 @@ * x86-64 work by Andi Kleen 2002 */ -#ifndef _ASM_X86_I387_H -#define _ASM_X86_I387_H +#ifndef ASM_X86__I387_H +#define ASM_X86__I387_H #include <linux/sched.h> #include <linux/kernel_stat.h> @@ -25,6 +25,7 @@ extern void mxcsr_feature_mask_init(void); extern int init_fpu(struct task_struct *child); extern asmlinkage void math_state_restore(void); extern void init_thread_xstate(void); +extern int dump_fpu(struct pt_regs *, struct user_i387_struct *); extern user_regset_active_fn fpregs_active, xfpregs_active; extern user_regset_get_fn fpregs_get, xfpregs_get, fpregs_soft_get; @@ -336,4 +337,4 @@ static inline unsigned short get_fpu_mxcsr(struct task_struct *tsk) } } -#endif /* _ASM_X86_I387_H */ +#endif /* ASM_X86__I387_H */ diff --git a/include/asm-x86/i8253.h b/include/asm-x86/i8253.h index b51c0487fc4..15a5b530044 100644 --- a/include/asm-x86/i8253.h +++ b/include/asm-x86/i8253.h @@ -1,5 +1,5 @@ -#ifndef __ASM_I8253_H__ -#define __ASM_I8253_H__ +#ifndef ASM_X86__I8253_H +#define ASM_X86__I8253_H /* i8253A PIT registers */ #define PIT_MODE 0x43 @@ -15,4 +15,4 @@ extern void setup_pit_timer(void); #define inb_pit inb_p #define outb_pit outb_p -#endif /* __ASM_I8253_H__ */ +#endif /* ASM_X86__I8253_H */ diff --git a/include/asm-x86/i8259.h b/include/asm-x86/i8259.h index 2f98df91f1f..c586559a695 100644 --- a/include/asm-x86/i8259.h +++ b/include/asm-x86/i8259.h @@ -1,5 +1,5 @@ -#ifndef __ASM_I8259_H__ -#define __ASM_I8259_H__ +#ifndef ASM_X86__I8259_H +#define ASM_X86__I8259_H #include <linux/delay.h> @@ -57,4 +57,4 @@ static inline void outb_pic(unsigned char value, unsigned int port) extern struct irq_chip i8259A_chip; -#endif /* __ASM_I8259_H__ */ +#endif /* ASM_X86__I8259_H */ diff --git a/include/asm-x86/ia32.h b/include/asm-x86/ia32.h index 55d3abe5276..f932f7ad51d 100644 --- a/include/asm-x86/ia32.h +++ b/include/asm-x86/ia32.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_64_IA32_H -#define _ASM_X86_64_IA32_H +#ifndef ASM_X86__IA32_H +#define ASM_X86__IA32_H #ifdef CONFIG_IA32_EMULATION @@ -167,4 +167,4 @@ extern void ia32_pick_mmap_layout(struct mm_struct *mm); #endif /* !CONFIG_IA32_SUPPORT */ -#endif +#endif /* ASM_X86__IA32_H */ diff --git a/include/asm-x86/ia32_unistd.h b/include/asm-x86/ia32_unistd.h index 61cea9e7c5c..dbd887d8a5a 100644 --- a/include/asm-x86/ia32_unistd.h +++ b/include/asm-x86/ia32_unistd.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_64_IA32_UNISTD_H_ -#define _ASM_X86_64_IA32_UNISTD_H_ +#ifndef ASM_X86__IA32_UNISTD_H +#define ASM_X86__IA32_UNISTD_H /* * This file contains the system call numbers of the ia32 port, @@ -15,4 +15,4 @@ #define __NR_ia32_sigreturn 119 #define __NR_ia32_rt_sigreturn 173 -#endif /* _ASM_X86_64_IA32_UNISTD_H_ */ +#endif /* ASM_X86__IA32_UNISTD_H */ diff --git a/include/asm-x86/idle.h b/include/asm-x86/idle.h index d240e5b30a4..baa3f783d27 100644 --- a/include/asm-x86/idle.h +++ b/include/asm-x86/idle.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_64_IDLE_H -#define _ASM_X86_64_IDLE_H 1 +#ifndef ASM_X86__IDLE_H +#define ASM_X86__IDLE_H #define IDLE_START 1 #define IDLE_END 2 @@ -10,4 +10,6 @@ void idle_notifier_register(struct notifier_block *n); void enter_idle(void); void exit_idle(void); -#endif +void c1e_remove_cpu(int cpu); + +#endif /* ASM_X86__IDLE_H */ diff --git a/include/asm-x86/intel_arch_perfmon.h b/include/asm-x86/intel_arch_perfmon.h index fa0fd068bc2..07c03c6c9a1 100644 --- a/include/asm-x86/intel_arch_perfmon.h +++ b/include/asm-x86/intel_arch_perfmon.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_INTEL_ARCH_PERFMON_H -#define _ASM_X86_INTEL_ARCH_PERFMON_H +#ifndef ASM_X86__INTEL_ARCH_PERFMON_H +#define ASM_X86__INTEL_ARCH_PERFMON_H #define MSR_ARCH_PERFMON_PERFCTR0 0xc1 #define MSR_ARCH_PERFMON_PERFCTR1 0xc2 @@ -28,4 +28,4 @@ union cpuid10_eax { unsigned int full; }; -#endif /* _ASM_X86_INTEL_ARCH_PERFMON_H */ +#endif /* ASM_X86__INTEL_ARCH_PERFMON_H */ diff --git a/include/asm-x86/io.h b/include/asm-x86/io.h index 0f954dc89cb..72b7719523b 100644 --- a/include/asm-x86/io.h +++ b/include/asm-x86/io.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_IO_H -#define _ASM_X86_IO_H +#ifndef ASM_X86__IO_H +#define ASM_X86__IO_H #define ARCH_HAS_IOREMAP_WC @@ -73,6 +73,8 @@ build_mmio_write(__writeq, "q", unsigned long, "r", ) #define writeq writeq #endif +extern int iommu_bio_merge; + #ifdef CONFIG_X86_32 # include "io_32.h" #else @@ -99,4 +101,4 @@ extern void early_iounmap(void *addr, unsigned long size); extern void __iomem *fix_ioremap(unsigned idx, unsigned long phys); -#endif /* _ASM_X86_IO_H */ +#endif /* ASM_X86__IO_H */ diff --git a/include/asm-x86/io_32.h b/include/asm-x86/io_32.h index e876d89ac15..4f7d878bda1 100644 --- a/include/asm-x86/io_32.h +++ b/include/asm-x86/io_32.h @@ -1,5 +1,5 @@ -#ifndef _ASM_IO_H -#define _ASM_IO_H +#ifndef ASM_X86__IO_32_H +#define ASM_X86__IO_32_H #include <linux/string.h> #include <linux/compiler.h> @@ -281,4 +281,4 @@ BUILDIO(b, b, char) BUILDIO(w, w, short) BUILDIO(l, , int) -#endif +#endif /* ASM_X86__IO_32_H */ diff --git a/include/asm-x86/io_64.h b/include/asm-x86/io_64.h index 22995c5c5ad..64429e9431a 100644 --- a/include/asm-x86/io_64.h +++ b/include/asm-x86/io_64.h @@ -1,5 +1,5 @@ -#ifndef _ASM_IO_H -#define _ASM_IO_H +#ifndef ASM_X86__IO_64_H +#define ASM_X86__IO_64_H /* @@ -235,7 +235,6 @@ void memset_io(volatile void __iomem *a, int b, size_t c); #define flush_write_buffers() -extern int iommu_bio_merge; #define BIO_VMERGE_BOUNDARY iommu_bio_merge /* @@ -245,4 +244,4 @@ extern int iommu_bio_merge; #endif /* __KERNEL__ */ -#endif +#endif /* ASM_X86__IO_64_H */ diff --git a/include/asm-x86/io_apic.h b/include/asm-x86/io_apic.h index 14f82bbcb5f..be62847ab07 100644 --- a/include/asm-x86/io_apic.h +++ b/include/asm-x86/io_apic.h @@ -1,5 +1,5 @@ -#ifndef __ASM_IO_APIC_H -#define __ASM_IO_APIC_H +#ifndef ASM_X86__IO_APIC_H +#define ASM_X86__IO_APIC_H #include <linux/types.h> #include <asm/mpspec.h> @@ -189,4 +189,4 @@ static const int timer_through_8259 = 0; static inline void ioapic_init_mappings(void) { } #endif -#endif +#endif /* ASM_X86__IO_APIC_H */ diff --git a/include/asm-x86/ioctls.h b/include/asm-x86/ioctls.h index c0c338bd406..33660351239 100644 --- a/include/asm-x86/ioctls.h +++ b/include/asm-x86/ioctls.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_IOCTLS_H -#define _ASM_X86_IOCTLS_H +#ifndef ASM_X86__IOCTLS_H +#define ASM_X86__IOCTLS_H #include <asm/ioctl.h> @@ -85,4 +85,4 @@ #define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ -#endif +#endif /* ASM_X86__IOCTLS_H */ diff --git a/include/asm-x86/iommu.h b/include/asm-x86/iommu.h index 5f888cc5be4..e86f44148c6 100644 --- a/include/asm-x86/iommu.h +++ b/include/asm-x86/iommu.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X8664_IOMMU_H -#define _ASM_X8664_IOMMU_H 1 +#ifndef ASM_X86__IOMMU_H +#define ASM_X86__IOMMU_H extern void pci_iommu_shutdown(void); extern void no_iommu_init(void); @@ -42,4 +42,4 @@ static inline void gart_iommu_hole_init(void) } #endif -#endif +#endif /* ASM_X86__IOMMU_H */ diff --git a/include/asm-x86/ipcbuf.h b/include/asm-x86/ipcbuf.h index ee678fd5159..910304fbdc8 100644 --- a/include/asm-x86/ipcbuf.h +++ b/include/asm-x86/ipcbuf.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_IPCBUF_H -#define _ASM_X86_IPCBUF_H +#ifndef ASM_X86__IPCBUF_H +#define ASM_X86__IPCBUF_H /* * The ipc64_perm structure for x86 architecture. @@ -25,4 +25,4 @@ struct ipc64_perm { unsigned long __unused2; }; -#endif /* _ASM_X86_IPCBUF_H */ +#endif /* ASM_X86__IPCBUF_H */ diff --git a/include/asm-x86/ipi.h b/include/asm-x86/ipi.h index bb1c09f7a76..c1b22679751 100644 --- a/include/asm-x86/ipi.h +++ b/include/asm-x86/ipi.h @@ -1,5 +1,5 @@ -#ifndef __ASM_IPI_H -#define __ASM_IPI_H +#ifndef ASM_X86__IPI_H +#define ASM_X86__IPI_H /* * Copyright 2004 James Cleverdon, IBM. @@ -129,4 +129,4 @@ static inline void send_IPI_mask_sequence(cpumask_t mask, int vector) local_irq_restore(flags); } -#endif /* __ASM_IPI_H */ +#endif /* ASM_X86__IPI_H */ diff --git a/include/asm-x86/irq.h b/include/asm-x86/irq.h index 1a292575731..1e5f2909c1d 100644 --- a/include/asm-x86/irq.h +++ b/include/asm-x86/irq.h @@ -1,5 +1,5 @@ -#ifndef _ASM_IRQ_H -#define _ASM_IRQ_H +#ifndef ASM_X86__IRQ_H +#define ASM_X86__IRQ_H /* * (C) 1992, 1993 Linus Torvalds, (C) 1997 Ingo Molnar * @@ -47,4 +47,4 @@ extern void native_init_IRQ(void); /* Interrupt vector management */ extern DECLARE_BITMAP(used_vectors, NR_VECTORS); -#endif /* _ASM_IRQ_H */ +#endif /* ASM_X86__IRQ_H */ diff --git a/include/asm-x86/irq_regs_32.h b/include/asm-x86/irq_regs_32.h index 3368b20c0b4..316a3b25887 100644 --- a/include/asm-x86/irq_regs_32.h +++ b/include/asm-x86/irq_regs_32.h @@ -4,8 +4,8 @@ * * Jeremy Fitzhardinge <jeremy@goop.org> */ -#ifndef _ASM_I386_IRQ_REGS_H -#define _ASM_I386_IRQ_REGS_H +#ifndef ASM_X86__IRQ_REGS_32_H +#define ASM_X86__IRQ_REGS_32_H #include <asm/percpu.h> @@ -26,4 +26,4 @@ static inline struct pt_regs *set_irq_regs(struct pt_regs *new_regs) return old_regs; } -#endif /* _ASM_I386_IRQ_REGS_H */ +#endif /* ASM_X86__IRQ_REGS_32_H */ diff --git a/include/asm-x86/irq_vectors.h b/include/asm-x86/irq_vectors.h index a48c7f2dbdc..c5d2d767a1f 100644 --- a/include/asm-x86/irq_vectors.h +++ b/include/asm-x86/irq_vectors.h @@ -1,5 +1,5 @@ -#ifndef _ASM_IRQ_VECTORS_H -#define _ASM_IRQ_VECTORS_H +#ifndef ASM_X86__IRQ_VECTORS_H +#define ASM_X86__IRQ_VECTORS_H #include <linux/threads.h> @@ -179,4 +179,4 @@ #define VIC_CPU_BOOT_ERRATA_CPI (VIC_CPI_LEVEL0 + 8) -#endif /* _ASM_IRQ_VECTORS_H */ +#endif /* ASM_X86__IRQ_VECTORS_H */ diff --git a/include/asm-x86/ist.h b/include/asm-x86/ist.h index 6ec6ceed95a..35a2fe9bc92 100644 --- a/include/asm-x86/ist.h +++ b/include/asm-x86/ist.h @@ -1,5 +1,5 @@ -#ifndef _ASM_IST_H -#define _ASM_IST_H +#ifndef ASM_X86__IST_H +#define ASM_X86__IST_H /* * Include file for the interface to IST BIOS @@ -31,4 +31,4 @@ struct ist_info { extern struct ist_info ist_info; #endif /* __KERNEL__ */ -#endif /* _ASM_IST_H */ +#endif /* ASM_X86__IST_H */ diff --git a/include/asm-x86/k8.h b/include/asm-x86/k8.h index 452e2b696ff..2bbaf4370a5 100644 --- a/include/asm-x86/k8.h +++ b/include/asm-x86/k8.h @@ -1,5 +1,5 @@ -#ifndef _ASM_K8_H -#define _ASM_K8_H 1 +#ifndef ASM_X86__K8_H +#define ASM_X86__K8_H #include <linux/pci.h> @@ -12,4 +12,4 @@ extern int cache_k8_northbridges(void); extern void k8_flush_garts(void); extern int k8_scan_nodes(unsigned long start, unsigned long end); -#endif +#endif /* ASM_X86__K8_H */ diff --git a/include/asm-x86/kdebug.h b/include/asm-x86/kdebug.h index 96651bb59ba..5ec3ad3e825 100644 --- a/include/asm-x86/kdebug.h +++ b/include/asm-x86/kdebug.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_KDEBUG_H -#define _ASM_X86_KDEBUG_H +#ifndef ASM_X86__KDEBUG_H +#define ASM_X86__KDEBUG_H #include <linux/notifier.h> @@ -35,4 +35,4 @@ extern void show_regs(struct pt_regs *regs); extern unsigned long oops_begin(void); extern void oops_end(unsigned long, struct pt_regs *, int signr); -#endif +#endif /* ASM_X86__KDEBUG_H */ diff --git a/include/asm-x86/kexec.h b/include/asm-x86/kexec.h index 4246ab7dc98..ea09600d612 100644 --- a/include/asm-x86/kexec.h +++ b/include/asm-x86/kexec.h @@ -1,5 +1,5 @@ -#ifndef _KEXEC_H -#define _KEXEC_H +#ifndef ASM_X86__KEXEC_H +#define ASM_X86__KEXEC_H #ifdef CONFIG_X86_32 # define PA_CONTROL_PAGE 0 @@ -172,4 +172,4 @@ relocate_kernel(unsigned long indirection_page, #endif /* __ASSEMBLY__ */ -#endif /* _KEXEC_H */ +#endif /* ASM_X86__KEXEC_H */ diff --git a/include/asm-x86/kgdb.h b/include/asm-x86/kgdb.h index 484c47554f3..d283863354d 100644 --- a/include/asm-x86/kgdb.h +++ b/include/asm-x86/kgdb.h @@ -1,5 +1,5 @@ -#ifndef _ASM_KGDB_H_ -#define _ASM_KGDB_H_ +#ifndef ASM_X86__KGDB_H +#define ASM_X86__KGDB_H /* * Copyright (C) 2001-2004 Amit S. Kale @@ -39,12 +39,13 @@ enum regnames { GDB_FS, /* 14 */ GDB_GS, /* 15 */ }; +#define NUMREGBYTES ((GDB_GS+1)*4) #else /* ! CONFIG_X86_32 */ -enum regnames { +enum regnames64 { GDB_AX, /* 0 */ - GDB_DX, /* 1 */ + GDB_BX, /* 1 */ GDB_CX, /* 2 */ - GDB_BX, /* 3 */ + GDB_DX, /* 3 */ GDB_SI, /* 4 */ GDB_DI, /* 5 */ GDB_BP, /* 6 */ @@ -58,18 +59,15 @@ enum regnames { GDB_R14, /* 14 */ GDB_R15, /* 15 */ GDB_PC, /* 16 */ - GDB_PS, /* 17 */ }; -#endif /* CONFIG_X86_32 */ -/* - * Number of bytes of registers: - */ -#ifdef CONFIG_X86_32 -# define NUMREGBYTES 64 -#else -# define NUMREGBYTES ((GDB_PS+1)*8) -#endif +enum regnames32 { + GDB_PS = 34, + GDB_CS, + GDB_SS, +}; +#define NUMREGBYTES ((GDB_SS+1)*4) +#endif /* CONFIG_X86_32 */ static inline void arch_kgdb_breakpoint(void) { @@ -78,4 +76,4 @@ static inline void arch_kgdb_breakpoint(void) #define BREAK_INSTR_SIZE 1 #define CACHE_FLUSH_IS_SAFE 1 -#endif /* _ASM_KGDB_H_ */ +#endif /* ASM_X86__KGDB_H */ diff --git a/include/asm-x86/kmap_types.h b/include/asm-x86/kmap_types.h index 5f4174132a2..89f44493e64 100644 --- a/include/asm-x86/kmap_types.h +++ b/include/asm-x86/kmap_types.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_KMAP_TYPES_H -#define _ASM_X86_KMAP_TYPES_H +#ifndef ASM_X86__KMAP_TYPES_H +#define ASM_X86__KMAP_TYPES_H #if defined(CONFIG_X86_32) && defined(CONFIG_DEBUG_HIGHMEM) # define D(n) __KM_FENCE_##n , @@ -26,4 +26,4 @@ D(13) KM_TYPE_NR #undef D -#endif +#endif /* ASM_X86__KMAP_TYPES_H */ diff --git a/include/asm-x86/kprobes.h b/include/asm-x86/kprobes.h index 54980b0b389..bd8407863c1 100644 --- a/include/asm-x86/kprobes.h +++ b/include/asm-x86/kprobes.h @@ -1,5 +1,5 @@ -#ifndef _ASM_KPROBES_H -#define _ASM_KPROBES_H +#ifndef ASM_X86__KPROBES_H +#define ASM_X86__KPROBES_H /* * Kernel Probes (KProbes) * @@ -94,4 +94,4 @@ static inline void restore_interrupts(struct pt_regs *regs) extern int kprobe_fault_handler(struct pt_regs *regs, int trapnr); extern int kprobe_exceptions_notify(struct notifier_block *self, unsigned long val, void *data); -#endif /* _ASM_KPROBES_H */ +#endif /* ASM_X86__KPROBES_H */ diff --git a/include/asm-x86/kvm.h b/include/asm-x86/kvm.h index 6f1840812e5..78e954db1e7 100644 --- a/include/asm-x86/kvm.h +++ b/include/asm-x86/kvm.h @@ -1,5 +1,5 @@ -#ifndef __LINUX_KVM_X86_H -#define __LINUX_KVM_X86_H +#ifndef ASM_X86__KVM_H +#define ASM_X86__KVM_H /* * KVM x86 specific structures and definitions @@ -230,4 +230,4 @@ struct kvm_pit_state { #define KVM_TRC_APIC_ACCESS (KVM_TRC_HANDLER + 0x14) #define KVM_TRC_TDP_FAULT (KVM_TRC_HANDLER + 0x15) -#endif +#endif /* ASM_X86__KVM_H */ diff --git a/include/asm-x86/kvm_host.h b/include/asm-x86/kvm_host.h index c2e34c27590..69794547f51 100644 --- a/include/asm-x86/kvm_host.h +++ b/include/asm-x86/kvm_host.h @@ -1,4 +1,4 @@ -#/* +/* * Kernel-based Virtual Machine driver for Linux * * This header defines architecture specific interfaces, x86 version @@ -8,8 +8,8 @@ * */ -#ifndef ASM_KVM_HOST_H -#define ASM_KVM_HOST_H +#ifndef ASM_X86__KVM_HOST_H +#define ASM_X86__KVM_HOST_H #include <linux/types.h> #include <linux/mm.h> @@ -735,4 +735,4 @@ asmlinkage void kvm_handle_fault_on_reboot(void); int kvm_unmap_hva(struct kvm *kvm, unsigned long hva); int kvm_age_hva(struct kvm *kvm, unsigned long hva); -#endif +#endif /* ASM_X86__KVM_HOST_H */ diff --git a/include/asm-x86/kvm_para.h b/include/asm-x86/kvm_para.h index 76f392146da..30054fded4f 100644 --- a/include/asm-x86/kvm_para.h +++ b/include/asm-x86/kvm_para.h @@ -1,5 +1,5 @@ -#ifndef __X86_KVM_PARA_H -#define __X86_KVM_PARA_H +#ifndef ASM_X86__KVM_PARA_H +#define ASM_X86__KVM_PARA_H /* This CPUID returns the signature 'KVMKVMKVM' in ebx, ecx, and edx. It * should be used to determine that a VM is running under KVM. @@ -144,4 +144,4 @@ static inline unsigned int kvm_arch_para_features(void) #endif -#endif +#endif /* ASM_X86__KVM_PARA_H */ diff --git a/include/asm-x86/kvm_x86_emulate.h b/include/asm-x86/kvm_x86_emulate.h index 4e8c1e48d91..e2d9b030c1a 100644 --- a/include/asm-x86/kvm_x86_emulate.h +++ b/include/asm-x86/kvm_x86_emulate.h @@ -8,8 +8,8 @@ * From: xen-unstable 10676:af9809f51f81a3c43f276f00c81a52ef558afda4 */ -#ifndef __X86_EMULATE_H__ -#define __X86_EMULATE_H__ +#ifndef ASM_X86__KVM_X86_EMULATE_H +#define ASM_X86__KVM_X86_EMULATE_H struct x86_emulate_ctxt; @@ -181,4 +181,4 @@ int x86_decode_insn(struct x86_emulate_ctxt *ctxt, int x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops); -#endif /* __X86_EMULATE_H__ */ +#endif /* ASM_X86__KVM_X86_EMULATE_H */ diff --git a/include/asm-x86/ldt.h b/include/asm-x86/ldt.h index 20c597242b5..a5228504d86 100644 --- a/include/asm-x86/ldt.h +++ b/include/asm-x86/ldt.h @@ -3,8 +3,8 @@ * * Definitions of structures used with the modify_ldt system call. */ -#ifndef _ASM_X86_LDT_H -#define _ASM_X86_LDT_H +#ifndef ASM_X86__LDT_H +#define ASM_X86__LDT_H /* Maximum number of LDT entries supported. */ #define LDT_ENTRIES 8192 @@ -37,4 +37,4 @@ struct user_desc { #define MODIFY_LDT_CONTENTS_CODE 2 #endif /* !__ASSEMBLY__ */ -#endif +#endif /* ASM_X86__LDT_H */ diff --git a/include/asm-x86/lguest.h b/include/asm-x86/lguest.h index be4a7247fa2..7505e947ed2 100644 --- a/include/asm-x86/lguest.h +++ b/include/asm-x86/lguest.h @@ -1,5 +1,5 @@ -#ifndef _X86_LGUEST_H -#define _X86_LGUEST_H +#ifndef ASM_X86__LGUEST_H +#define ASM_X86__LGUEST_H #define GDT_ENTRY_LGUEST_CS 10 #define GDT_ENTRY_LGUEST_DS 11 @@ -91,4 +91,4 @@ static inline void lguest_set_ts(void) #endif /* __ASSEMBLY__ */ -#endif +#endif /* ASM_X86__LGUEST_H */ diff --git a/include/asm-x86/lguest_hcall.h b/include/asm-x86/lguest_hcall.h index a3241f28e34..8f034ba4b53 100644 --- a/include/asm-x86/lguest_hcall.h +++ b/include/asm-x86/lguest_hcall.h @@ -1,6 +1,6 @@ /* Architecture specific portion of the lguest hypercalls */ -#ifndef _X86_LGUEST_HCALL_H -#define _X86_LGUEST_HCALL_H +#ifndef ASM_X86__LGUEST_HCALL_H +#define ASM_X86__LGUEST_HCALL_H #define LHCALL_FLUSH_ASYNC 0 #define LHCALL_LGUEST_INIT 1 @@ -68,4 +68,4 @@ struct hcall_args { }; #endif /* !__ASSEMBLY__ */ -#endif /* _I386_LGUEST_HCALL_H */ +#endif /* ASM_X86__LGUEST_HCALL_H */ diff --git a/include/asm-x86/linkage.h b/include/asm-x86/linkage.h index 64e444f8e85..42d8b62ee8a 100644 --- a/include/asm-x86/linkage.h +++ b/include/asm-x86/linkage.h @@ -1,5 +1,5 @@ -#ifndef __ASM_LINKAGE_H -#define __ASM_LINKAGE_H +#ifndef ASM_X86__LINKAGE_H +#define ASM_X86__LINKAGE_H #undef notrace #define notrace __attribute__((no_instrument_function)) @@ -57,5 +57,5 @@ #define __ALIGN_STR ".align 16,0x90" #endif -#endif +#endif /* ASM_X86__LINKAGE_H */ diff --git a/include/asm-x86/local.h b/include/asm-x86/local.h index 330a72496ab..ae91994fd6c 100644 --- a/include/asm-x86/local.h +++ b/include/asm-x86/local.h @@ -1,5 +1,5 @@ -#ifndef _ARCH_LOCAL_H -#define _ARCH_LOCAL_H +#ifndef ASM_X86__LOCAL_H +#define ASM_X86__LOCAL_H #include <linux/percpu.h> @@ -232,4 +232,4 @@ static inline long local_sub_return(long i, local_t *l) #define __cpu_local_add(i, l) cpu_local_add((i), (l)) #define __cpu_local_sub(i, l) cpu_local_sub((i), (l)) -#endif /* _ARCH_LOCAL_H */ +#endif /* ASM_X86__LOCAL_H */ diff --git a/include/asm-x86/mach-bigsmp/mach_apic.h b/include/asm-x86/mach-bigsmp/mach_apic.h index c3b9dc6970c..05362d44a3e 100644 --- a/include/asm-x86/mach-bigsmp/mach_apic.h +++ b/include/asm-x86/mach-bigsmp/mach_apic.h @@ -1,5 +1,5 @@ -#ifndef __ASM_MACH_APIC_H -#define __ASM_MACH_APIC_H +#ifndef ASM_X86__MACH_BIGSMP__MACH_APIC_H +#define ASM_X86__MACH_BIGSMP__MACH_APIC_H #define xapic_phys_to_log_apicid(cpu) (per_cpu(x86_bios_cpu_apicid, cpu)) #define esr_disable (1) @@ -141,4 +141,4 @@ static inline u32 phys_pkg_id(u32 cpuid_apic, int index_msb) return cpuid_apic >> index_msb; } -#endif /* __ASM_MACH_APIC_H */ +#endif /* ASM_X86__MACH_BIGSMP__MACH_APIC_H */ diff --git a/include/asm-x86/mach-bigsmp/mach_apicdef.h b/include/asm-x86/mach-bigsmp/mach_apicdef.h index a58ab5a75c8..811935d9d49 100644 --- a/include/asm-x86/mach-bigsmp/mach_apicdef.h +++ b/include/asm-x86/mach-bigsmp/mach_apicdef.h @@ -1,5 +1,5 @@ -#ifndef __ASM_MACH_APICDEF_H -#define __ASM_MACH_APICDEF_H +#ifndef ASM_X86__MACH_BIGSMP__MACH_APICDEF_H +#define ASM_X86__MACH_BIGSMP__MACH_APICDEF_H #define APIC_ID_MASK (0xFF<<24) @@ -10,4 +10,4 @@ static inline unsigned get_apic_id(unsigned long x) #define GET_APIC_ID(x) get_apic_id(x) -#endif +#endif /* ASM_X86__MACH_BIGSMP__MACH_APICDEF_H */ diff --git a/include/asm-x86/mach-bigsmp/mach_ipi.h b/include/asm-x86/mach-bigsmp/mach_ipi.h index 9404c535b7e..b1b0f966a00 100644 --- a/include/asm-x86/mach-bigsmp/mach_ipi.h +++ b/include/asm-x86/mach-bigsmp/mach_ipi.h @@ -1,5 +1,5 @@ -#ifndef __ASM_MACH_IPI_H -#define __ASM_MACH_IPI_H +#ifndef ASM_X86__MACH_BIGSMP__MACH_IPI_H +#define ASM_X86__MACH_BIGSMP__MACH_IPI_H void send_IPI_mask_sequence(cpumask_t mask, int vector); @@ -22,4 +22,4 @@ static inline void send_IPI_all(int vector) send_IPI_mask(cpu_online_map, vector); } -#endif /* __ASM_MACH_IPI_H */ +#endif /* ASM_X86__MACH_BIGSMP__MACH_IPI_H */ diff --git a/include/asm-x86/mach-default/apm.h b/include/asm-x86/mach-default/apm.h index 989f34c37d3..2aa61b54fbd 100644 --- a/include/asm-x86/mach-default/apm.h +++ b/include/asm-x86/mach-default/apm.h @@ -3,8 +3,8 @@ * Split out from apm.c by Osamu Tomita <tomita@cinet.co.jp> */ -#ifndef _ASM_APM_H -#define _ASM_APM_H +#ifndef ASM_X86__MACH_DEFAULT__APM_H +#define ASM_X86__MACH_DEFAULT__APM_H #ifdef APM_ZERO_SEGS # define APM_DO_ZERO_SEGS \ @@ -70,4 +70,4 @@ static inline u8 apm_bios_call_simple_asm(u32 func, u32 ebx_in, return error; } -#endif /* _ASM_APM_H */ +#endif /* ASM_X86__MACH_DEFAULT__APM_H */ diff --git a/include/asm-x86/mach-default/mach_apic.h b/include/asm-x86/mach-default/mach_apic.h index f3226b9a6b8..b615f40736b 100644 --- a/include/asm-x86/mach-default/mach_apic.h +++ b/include/asm-x86/mach-default/mach_apic.h @@ -1,5 +1,5 @@ -#ifndef __ASM_MACH_APIC_H -#define __ASM_MACH_APIC_H +#ifndef ASM_X86__MACH_DEFAULT__MACH_APIC_H +#define ASM_X86__MACH_DEFAULT__MACH_APIC_H #ifdef CONFIG_X86_LOCAL_APIC @@ -138,4 +138,4 @@ static inline void enable_apic_mode(void) } #endif /* CONFIG_X86_LOCAL_APIC */ -#endif /* __ASM_MACH_APIC_H */ +#endif /* ASM_X86__MACH_DEFAULT__MACH_APIC_H */ diff --git a/include/asm-x86/mach-default/mach_apicdef.h b/include/asm-x86/mach-default/mach_apicdef.h index e4b29ba37de..936704f816d 100644 --- a/include/asm-x86/mach-default/mach_apicdef.h +++ b/include/asm-x86/mach-default/mach_apicdef.h @@ -1,5 +1,5 @@ -#ifndef __ASM_MACH_APICDEF_H -#define __ASM_MACH_APICDEF_H +#ifndef ASM_X86__MACH_DEFAULT__MACH_APICDEF_H +#define ASM_X86__MACH_DEFAULT__MACH_APICDEF_H #include <asm/apic.h> @@ -21,4 +21,4 @@ static inline unsigned get_apic_id(unsigned long x) #define GET_APIC_ID(x) get_apic_id(x) #endif -#endif +#endif /* ASM_X86__MACH_DEFAULT__MACH_APICDEF_H */ diff --git a/include/asm-x86/mach-default/mach_ipi.h b/include/asm-x86/mach-default/mach_ipi.h index be323364e68..674bc7e50c3 100644 --- a/include/asm-x86/mach-default/mach_ipi.h +++ b/include/asm-x86/mach-default/mach_ipi.h @@ -1,5 +1,5 @@ -#ifndef __ASM_MACH_IPI_H -#define __ASM_MACH_IPI_H +#ifndef ASM_X86__MACH_DEFAULT__MACH_IPI_H +#define ASM_X86__MACH_DEFAULT__MACH_IPI_H /* Avoid include hell */ #define NMI_VECTOR 0x02 @@ -61,4 +61,4 @@ static inline void send_IPI_all(int vector) } #endif -#endif /* __ASM_MACH_IPI_H */ +#endif /* ASM_X86__MACH_DEFAULT__MACH_IPI_H */ diff --git a/include/asm-x86/mach-default/mach_mpparse.h b/include/asm-x86/mach-default/mach_mpparse.h index d14108505bb..9c381f2815a 100644 --- a/include/asm-x86/mach-default/mach_mpparse.h +++ b/include/asm-x86/mach-default/mach_mpparse.h @@ -1,5 +1,5 @@ -#ifndef __ASM_MACH_MPPARSE_H -#define __ASM_MACH_MPPARSE_H +#ifndef ASM_X86__MACH_DEFAULT__MACH_MPPARSE_H +#define ASM_X86__MACH_DEFAULT__MACH_MPPARSE_H static inline int mps_oem_check(struct mp_config_table *mpc, char *oem, char *productid) @@ -14,4 +14,4 @@ static inline int acpi_madt_oem_check(char *oem_id, char *oem_table_id) } -#endif /* __ASM_MACH_MPPARSE_H */ +#endif /* ASM_X86__MACH_DEFAULT__MACH_MPPARSE_H */ diff --git a/include/asm-x86/mach-default/mach_mpspec.h b/include/asm-x86/mach-default/mach_mpspec.h index 51c9a977593..d77646f011f 100644 --- a/include/asm-x86/mach-default/mach_mpspec.h +++ b/include/asm-x86/mach-default/mach_mpspec.h @@ -1,5 +1,5 @@ -#ifndef __ASM_MACH_MPSPEC_H -#define __ASM_MACH_MPSPEC_H +#ifndef ASM_X86__MACH_DEFAULT__MACH_MPSPEC_H +#define ASM_X86__MACH_DEFAULT__MACH_MPSPEC_H #define MAX_IRQ_SOURCES 256 @@ -9,4 +9,4 @@ #define MAX_MP_BUSSES 32 #endif -#endif /* __ASM_MACH_MPSPEC_H */ +#endif /* ASM_X86__MACH_DEFAULT__MACH_MPSPEC_H */ diff --git a/include/asm-x86/mach-default/mach_timer.h b/include/asm-x86/mach-default/mach_timer.h index 4b76e536cd9..990b1583383 100644 --- a/include/asm-x86/mach-default/mach_timer.h +++ b/include/asm-x86/mach-default/mach_timer.h @@ -10,8 +10,8 @@ * directly because of the awkward 8-bit access mechanism of the 82C54 * device. */ -#ifndef _MACH_TIMER_H -#define _MACH_TIMER_H +#ifndef ASM_X86__MACH_DEFAULT__MACH_TIMER_H +#define ASM_X86__MACH_DEFAULT__MACH_TIMER_H #define CALIBRATE_TIME_MSEC 30 /* 30 msecs */ #define CALIBRATE_LATCH \ @@ -45,4 +45,4 @@ static inline void mach_countup(unsigned long *count_p) *count_p = count; } -#endif /* !_MACH_TIMER_H */ +#endif /* ASM_X86__MACH_DEFAULT__MACH_TIMER_H */ diff --git a/include/asm-x86/mach-default/mach_traps.h b/include/asm-x86/mach-default/mach_traps.h index 2fe7705c048..de9ac3f5c4c 100644 --- a/include/asm-x86/mach-default/mach_traps.h +++ b/include/asm-x86/mach-default/mach_traps.h @@ -2,8 +2,8 @@ * Machine specific NMI handling for generic. * Split out from traps.c by Osamu Tomita <tomita@cinet.co.jp> */ -#ifndef _MACH_TRAPS_H -#define _MACH_TRAPS_H +#ifndef ASM_X86__MACH_DEFAULT__MACH_TRAPS_H +#define ASM_X86__MACH_DEFAULT__MACH_TRAPS_H #include <asm/mc146818rtc.h> @@ -36,4 +36,4 @@ static inline void reassert_nmi(void) unlock_cmos(); } -#endif /* !_MACH_TRAPS_H */ +#endif /* ASM_X86__MACH_DEFAULT__MACH_TRAPS_H */ diff --git a/include/asm-x86/mach-default/mach_wakecpu.h b/include/asm-x86/mach-default/mach_wakecpu.h index 3ebb17893aa..361b810f516 100644 --- a/include/asm-x86/mach-default/mach_wakecpu.h +++ b/include/asm-x86/mach-default/mach_wakecpu.h @@ -1,5 +1,5 @@ -#ifndef __ASM_MACH_WAKECPU_H -#define __ASM_MACH_WAKECPU_H +#ifndef ASM_X86__MACH_DEFAULT__MACH_WAKECPU_H +#define ASM_X86__MACH_DEFAULT__MACH_WAKECPU_H /* * This file copes with machines that wakeup secondary CPUs by the @@ -39,4 +39,4 @@ static inline void restore_NMI_vector(unsigned short *high, unsigned short *low) #define inquire_remote_apic(apicid) {} #endif -#endif /* __ASM_MACH_WAKECPU_H */ +#endif /* ASM_X86__MACH_DEFAULT__MACH_WAKECPU_H */ diff --git a/include/asm-x86/mach-es7000/mach_apic.h b/include/asm-x86/mach-es7000/mach_apic.h index 0a3fdf93067..c1f6f682d61 100644 --- a/include/asm-x86/mach-es7000/mach_apic.h +++ b/include/asm-x86/mach-es7000/mach_apic.h @@ -1,5 +1,5 @@ -#ifndef __ASM_MACH_APIC_H -#define __ASM_MACH_APIC_H +#ifndef ASM_X86__MACH_ES7000__MACH_APIC_H +#define ASM_X86__MACH_ES7000__MACH_APIC_H #define xapic_phys_to_log_apicid(cpu) per_cpu(x86_bios_cpu_apicid, cpu) #define esr_disable (1) @@ -191,4 +191,4 @@ static inline u32 phys_pkg_id(u32 cpuid_apic, int index_msb) return cpuid_apic >> index_msb; } -#endif /* __ASM_MACH_APIC_H */ +#endif /* ASM_X86__MACH_ES7000__MACH_APIC_H */ diff --git a/include/asm-x86/mach-es7000/mach_apicdef.h b/include/asm-x86/mach-es7000/mach_apicdef.h index a58ab5a75c8..a07e5674402 100644 --- a/include/asm-x86/mach-es7000/mach_apicdef.h +++ b/include/asm-x86/mach-es7000/mach_apicdef.h @@ -1,5 +1,5 @@ -#ifndef __ASM_MACH_APICDEF_H -#define __ASM_MACH_APICDEF_H +#ifndef ASM_X86__MACH_ES7000__MACH_APICDEF_H +#define ASM_X86__MACH_ES7000__MACH_APICDEF_H #define APIC_ID_MASK (0xFF<<24) @@ -10,4 +10,4 @@ static inline unsigned get_apic_id(unsigned long x) #define GET_APIC_ID(x) get_apic_id(x) -#endif +#endif /* ASM_X86__MACH_ES7000__MACH_APICDEF_H */ diff --git a/include/asm-x86/mach-es7000/mach_ipi.h b/include/asm-x86/mach-es7000/mach_ipi.h index 5e61bd220b0..3a21240e03d 100644 --- a/include/asm-x86/mach-es7000/mach_ipi.h +++ b/include/asm-x86/mach-es7000/mach_ipi.h @@ -1,5 +1,5 @@ -#ifndef __ASM_MACH_IPI_H -#define __ASM_MACH_IPI_H +#ifndef ASM_X86__MACH_ES7000__MACH_IPI_H +#define ASM_X86__MACH_ES7000__MACH_IPI_H void send_IPI_mask_sequence(cpumask_t mask, int vector); @@ -21,4 +21,4 @@ static inline void send_IPI_all(int vector) send_IPI_mask(cpu_online_map, vector); } -#endif /* __ASM_MACH_IPI_H */ +#endif /* ASM_X86__MACH_ES7000__MACH_IPI_H */ diff --git a/include/asm-x86/mach-es7000/mach_mpparse.h b/include/asm-x86/mach-es7000/mach_mpparse.h index ef26d352362..befde24705b 100644 --- a/include/asm-x86/mach-es7000/mach_mpparse.h +++ b/include/asm-x86/mach-es7000/mach_mpparse.h @@ -1,5 +1,5 @@ -#ifndef __ASM_MACH_MPPARSE_H -#define __ASM_MACH_MPPARSE_H +#ifndef ASM_X86__MACH_ES7000__MACH_MPPARSE_H +#define ASM_X86__MACH_ES7000__MACH_MPPARSE_H #include <linux/acpi.h> @@ -26,4 +26,4 @@ static inline int es7000_check_dsdt(void) } #endif -#endif /* __ASM_MACH_MPPARSE_H */ +#endif /* ASM_X86__MACH_ES7000__MACH_MPPARSE_H */ diff --git a/include/asm-x86/mach-es7000/mach_wakecpu.h b/include/asm-x86/mach-es7000/mach_wakecpu.h index 84ff5831450..97c776ce13f 100644 --- a/include/asm-x86/mach-es7000/mach_wakecpu.h +++ b/include/asm-x86/mach-es7000/mach_wakecpu.h @@ -1,5 +1,5 @@ -#ifndef __ASM_MACH_WAKECPU_H -#define __ASM_MACH_WAKECPU_H +#ifndef ASM_X86__MACH_ES7000__MACH_WAKECPU_H +#define ASM_X86__MACH_ES7000__MACH_WAKECPU_H /* * This file copes with machines that wakeup secondary CPUs by the @@ -56,4 +56,4 @@ static inline void restore_NMI_vector(unsigned short *high, unsigned short *low) #define inquire_remote_apic(apicid) {} #endif -#endif /* __ASM_MACH_WAKECPU_H */ +#endif /* ASM_X86__MACH_ES7000__MACH_WAKECPU_H */ diff --git a/include/asm-x86/mach-generic/gpio.h b/include/asm-x86/mach-generic/gpio.h index 5305dcb96df..6ce0f7786ef 100644 --- a/include/asm-x86/mach-generic/gpio.h +++ b/include/asm-x86/mach-generic/gpio.h @@ -1,5 +1,5 @@ -#ifndef __ASM_MACH_GENERIC_GPIO_H -#define __ASM_MACH_GENERIC_GPIO_H +#ifndef ASM_X86__MACH_GENERIC__GPIO_H +#define ASM_X86__MACH_GENERIC__GPIO_H int gpio_request(unsigned gpio, const char *label); void gpio_free(unsigned gpio); @@ -12,4 +12,4 @@ int irq_to_gpio(unsigned irq); #include <asm-generic/gpio.h> /* cansleep wrappers */ -#endif /* __ASM_MACH_GENERIC_GPIO_H */ +#endif /* ASM_X86__MACH_GENERIC__GPIO_H */ diff --git a/include/asm-x86/mach-generic/irq_vectors_limits.h b/include/asm-x86/mach-generic/irq_vectors_limits.h index 890ce3f5e09..f7870e1a220 100644 --- a/include/asm-x86/mach-generic/irq_vectors_limits.h +++ b/include/asm-x86/mach-generic/irq_vectors_limits.h @@ -1,5 +1,5 @@ -#ifndef _ASM_IRQ_VECTORS_LIMITS_H -#define _ASM_IRQ_VECTORS_LIMITS_H +#ifndef ASM_X86__MACH_GENERIC__IRQ_VECTORS_LIMITS_H +#define ASM_X86__MACH_GENERIC__IRQ_VECTORS_LIMITS_H /* * For Summit or generic (i.e. installer) kernels, we have lots of I/O APICs, @@ -11,4 +11,4 @@ #define NR_IRQS 224 #define NR_IRQ_VECTORS 1024 -#endif /* _ASM_IRQ_VECTORS_LIMITS_H */ +#endif /* ASM_X86__MACH_GENERIC__IRQ_VECTORS_LIMITS_H */ diff --git a/include/asm-x86/mach-generic/mach_apic.h b/include/asm-x86/mach-generic/mach_apic.h index 6eff343e123..5d010c6881d 100644 --- a/include/asm-x86/mach-generic/mach_apic.h +++ b/include/asm-x86/mach-generic/mach_apic.h @@ -1,5 +1,5 @@ -#ifndef __ASM_MACH_APIC_H -#define __ASM_MACH_APIC_H +#ifndef ASM_X86__MACH_GENERIC__MACH_APIC_H +#define ASM_X86__MACH_GENERIC__MACH_APIC_H #include <asm/genapic.h> @@ -29,4 +29,4 @@ extern void generic_bigsmp_probe(void); -#endif /* __ASM_MACH_APIC_H */ +#endif /* ASM_X86__MACH_GENERIC__MACH_APIC_H */ diff --git a/include/asm-x86/mach-generic/mach_apicdef.h b/include/asm-x86/mach-generic/mach_apicdef.h index 28ed98972ca..1657f38b8f2 100644 --- a/include/asm-x86/mach-generic/mach_apicdef.h +++ b/include/asm-x86/mach-generic/mach_apicdef.h @@ -1,5 +1,5 @@ -#ifndef _GENAPIC_MACH_APICDEF_H -#define _GENAPIC_MACH_APICDEF_H 1 +#ifndef ASM_X86__MACH_GENERIC__MACH_APICDEF_H +#define ASM_X86__MACH_GENERIC__MACH_APICDEF_H #ifndef APIC_DEFINITION #include <asm/genapic.h> @@ -8,4 +8,4 @@ #define APIC_ID_MASK (genapic->apic_id_mask) #endif -#endif +#endif /* ASM_X86__MACH_GENERIC__MACH_APICDEF_H */ diff --git a/include/asm-x86/mach-generic/mach_ipi.h b/include/asm-x86/mach-generic/mach_ipi.h index 441b0fe3ed1..f67433dbd65 100644 --- a/include/asm-x86/mach-generic/mach_ipi.h +++ b/include/asm-x86/mach-generic/mach_ipi.h @@ -1,5 +1,5 @@ -#ifndef _MACH_IPI_H -#define _MACH_IPI_H 1 +#ifndef ASM_X86__MACH_GENERIC__MACH_IPI_H +#define ASM_X86__MACH_GENERIC__MACH_IPI_H #include <asm/genapic.h> @@ -7,4 +7,4 @@ #define send_IPI_allbutself (genapic->send_IPI_allbutself) #define send_IPI_all (genapic->send_IPI_all) -#endif +#endif /* ASM_X86__MACH_GENERIC__MACH_IPI_H */ diff --git a/include/asm-x86/mach-generic/mach_mpparse.h b/include/asm-x86/mach-generic/mach_mpparse.h index 586cadbf378..3115564e557 100644 --- a/include/asm-x86/mach-generic/mach_mpparse.h +++ b/include/asm-x86/mach-generic/mach_mpparse.h @@ -1,5 +1,5 @@ -#ifndef _MACH_MPPARSE_H -#define _MACH_MPPARSE_H 1 +#ifndef ASM_X86__MACH_GENERIC__MACH_MPPARSE_H +#define ASM_X86__MACH_GENERIC__MACH_MPPARSE_H extern int mps_oem_check(struct mp_config_table *mpc, char *oem, @@ -7,4 +7,4 @@ extern int mps_oem_check(struct mp_config_table *mpc, char *oem, extern int acpi_madt_oem_check(char *oem_id, char *oem_table_id); -#endif +#endif /* ASM_X86__MACH_GENERIC__MACH_MPPARSE_H */ diff --git a/include/asm-x86/mach-generic/mach_mpspec.h b/include/asm-x86/mach-generic/mach_mpspec.h index c83c120be53..6061b153613 100644 --- a/include/asm-x86/mach-generic/mach_mpspec.h +++ b/include/asm-x86/mach-generic/mach_mpspec.h @@ -1,5 +1,5 @@ -#ifndef __ASM_MACH_MPSPEC_H -#define __ASM_MACH_MPSPEC_H +#ifndef ASM_X86__MACH_GENERIC__MACH_MPSPEC_H +#define ASM_X86__MACH_GENERIC__MACH_MPSPEC_H #define MAX_IRQ_SOURCES 256 @@ -9,4 +9,4 @@ extern void numaq_mps_oem_check(struct mp_config_table *mpc, char *oem, char *productid); -#endif /* __ASM_MACH_MPSPEC_H */ +#endif /* ASM_X86__MACH_GENERIC__MACH_MPSPEC_H */ diff --git a/include/asm-x86/mach-numaq/mach_apic.h b/include/asm-x86/mach-numaq/mach_apic.h index d802465e026..7a0d39edfcf 100644 --- a/include/asm-x86/mach-numaq/mach_apic.h +++ b/include/asm-x86/mach-numaq/mach_apic.h @@ -1,5 +1,5 @@ -#ifndef __ASM_MACH_APIC_H -#define __ASM_MACH_APIC_H +#ifndef ASM_X86__MACH_NUMAQ__MACH_APIC_H +#define ASM_X86__MACH_NUMAQ__MACH_APIC_H #include <asm/io.h> #include <linux/mmzone.h> @@ -135,4 +135,4 @@ static inline u32 phys_pkg_id(u32 cpuid_apic, int index_msb) return cpuid_apic >> index_msb; } -#endif /* __ASM_MACH_APIC_H */ +#endif /* ASM_X86__MACH_NUMAQ__MACH_APIC_H */ diff --git a/include/asm-x86/mach-numaq/mach_apicdef.h b/include/asm-x86/mach-numaq/mach_apicdef.h index bf439d0690f..f870ec5f778 100644 --- a/include/asm-x86/mach-numaq/mach_apicdef.h +++ b/include/asm-x86/mach-numaq/mach_apicdef.h @@ -1,5 +1,5 @@ -#ifndef __ASM_MACH_APICDEF_H -#define __ASM_MACH_APICDEF_H +#ifndef ASM_X86__MACH_NUMAQ__MACH_APICDEF_H +#define ASM_X86__MACH_NUMAQ__MACH_APICDEF_H #define APIC_ID_MASK (0xF<<24) @@ -11,4 +11,4 @@ static inline unsigned get_apic_id(unsigned long x) #define GET_APIC_ID(x) get_apic_id(x) -#endif +#endif /* ASM_X86__MACH_NUMAQ__MACH_APICDEF_H */ diff --git a/include/asm-x86/mach-numaq/mach_ipi.h b/include/asm-x86/mach-numaq/mach_ipi.h index c6044488e9e..1e835823f4b 100644 --- a/include/asm-x86/mach-numaq/mach_ipi.h +++ b/include/asm-x86/mach-numaq/mach_ipi.h @@ -1,5 +1,5 @@ -#ifndef __ASM_MACH_IPI_H -#define __ASM_MACH_IPI_H +#ifndef ASM_X86__MACH_NUMAQ__MACH_IPI_H +#define ASM_X86__MACH_NUMAQ__MACH_IPI_H void send_IPI_mask_sequence(cpumask_t, int vector); @@ -22,4 +22,4 @@ static inline void send_IPI_all(int vector) send_IPI_mask(cpu_online_map, vector); } -#endif /* __ASM_MACH_IPI_H */ +#endif /* ASM_X86__MACH_NUMAQ__MACH_IPI_H */ diff --git a/include/asm-x86/mach-numaq/mach_mpparse.h b/include/asm-x86/mach-numaq/mach_mpparse.h index 626aef6b155..74ade184920 100644 --- a/include/asm-x86/mach-numaq/mach_mpparse.h +++ b/include/asm-x86/mach-numaq/mach_mpparse.h @@ -1,7 +1,7 @@ -#ifndef __ASM_MACH_MPPARSE_H -#define __ASM_MACH_MPPARSE_H +#ifndef ASM_X86__MACH_NUMAQ__MACH_MPPARSE_H +#define ASM_X86__MACH_NUMAQ__MACH_MPPARSE_H extern void numaq_mps_oem_check(struct mp_config_table *mpc, char *oem, char *productid); -#endif /* __ASM_MACH_MPPARSE_H */ +#endif /* ASM_X86__MACH_NUMAQ__MACH_MPPARSE_H */ diff --git a/include/asm-x86/mach-numaq/mach_wakecpu.h b/include/asm-x86/mach-numaq/mach_wakecpu.h index 00530041a99..0db8cea643c 100644 --- a/include/asm-x86/mach-numaq/mach_wakecpu.h +++ b/include/asm-x86/mach-numaq/mach_wakecpu.h @@ -1,5 +1,5 @@ -#ifndef __ASM_MACH_WAKECPU_H -#define __ASM_MACH_WAKECPU_H +#ifndef ASM_X86__MACH_NUMAQ__MACH_WAKECPU_H +#define ASM_X86__MACH_NUMAQ__MACH_WAKECPU_H /* This file copes with machines that wakeup secondary CPUs by NMIs */ @@ -40,4 +40,4 @@ static inline void restore_NMI_vector(unsigned short *high, unsigned short *low) #define inquire_remote_apic(apicid) {} -#endif /* __ASM_MACH_WAKECPU_H */ +#endif /* ASM_X86__MACH_NUMAQ__MACH_WAKECPU_H */ diff --git a/include/asm-x86/mach-rdc321x/gpio.h b/include/asm-x86/mach-rdc321x/gpio.h index acce0b7d397..94b6cdf532e 100644 --- a/include/asm-x86/mach-rdc321x/gpio.h +++ b/include/asm-x86/mach-rdc321x/gpio.h @@ -1,5 +1,7 @@ -#ifndef _RDC321X_GPIO_H -#define _RDC321X_GPIO_H +#ifndef ASM_X86__MACH_RDC321X__GPIO_H +#define ASM_X86__MACH_RDC321X__GPIO_H + +#include <linux/kernel.h> extern int rdc_gpio_get_value(unsigned gpio); extern void rdc_gpio_set_value(unsigned gpio, int value); @@ -18,6 +20,7 @@ static inline int gpio_request(unsigned gpio, const char *label) static inline void gpio_free(unsigned gpio) { + might_sleep(); rdc_gpio_free(gpio); } @@ -54,4 +57,4 @@ static inline int irq_to_gpio(unsigned irq) /* For cansleep */ #include <asm-generic/gpio.h> -#endif /* _RDC321X_GPIO_H_ */ +#endif /* ASM_X86__MACH_RDC321X__GPIO_H */ diff --git a/include/asm-x86/mach-summit/irq_vectors_limits.h b/include/asm-x86/mach-summit/irq_vectors_limits.h index 890ce3f5e09..22f376ad68e 100644 --- a/include/asm-x86/mach-summit/irq_vectors_limits.h +++ b/include/asm-x86/mach-summit/irq_vectors_limits.h @@ -1,5 +1,5 @@ -#ifndef _ASM_IRQ_VECTORS_LIMITS_H -#define _ASM_IRQ_VECTORS_LIMITS_H +#ifndef ASM_X86__MACH_SUMMIT__IRQ_VECTORS_LIMITS_H +#define ASM_X86__MACH_SUMMIT__IRQ_VECTORS_LIMITS_H /* * For Summit or generic (i.e. installer) kernels, we have lots of I/O APICs, @@ -11,4 +11,4 @@ #define NR_IRQS 224 #define NR_IRQ_VECTORS 1024 -#endif /* _ASM_IRQ_VECTORS_LIMITS_H */ +#endif /* ASM_X86__MACH_SUMMIT__IRQ_VECTORS_LIMITS_H */ diff --git a/include/asm-x86/mach-summit/mach_apic.h b/include/asm-x86/mach-summit/mach_apic.h index c47e2ab5c5c..7a66758d701 100644 --- a/include/asm-x86/mach-summit/mach_apic.h +++ b/include/asm-x86/mach-summit/mach_apic.h @@ -1,5 +1,5 @@ -#ifndef __ASM_MACH_APIC_H -#define __ASM_MACH_APIC_H +#ifndef ASM_X86__MACH_SUMMIT__MACH_APIC_H +#define ASM_X86__MACH_SUMMIT__MACH_APIC_H #include <asm/smp.h> @@ -182,4 +182,4 @@ static inline u32 phys_pkg_id(u32 cpuid_apic, int index_msb) return hard_smp_processor_id() >> index_msb; } -#endif /* __ASM_MACH_APIC_H */ +#endif /* ASM_X86__MACH_SUMMIT__MACH_APIC_H */ diff --git a/include/asm-x86/mach-summit/mach_apicdef.h b/include/asm-x86/mach-summit/mach_apicdef.h index a58ab5a75c8..d4bc8590c4f 100644 --- a/include/asm-x86/mach-summit/mach_apicdef.h +++ b/include/asm-x86/mach-summit/mach_apicdef.h @@ -1,5 +1,5 @@ -#ifndef __ASM_MACH_APICDEF_H -#define __ASM_MACH_APICDEF_H +#ifndef ASM_X86__MACH_SUMMIT__MACH_APICDEF_H +#define ASM_X86__MACH_SUMMIT__MACH_APICDEF_H #define APIC_ID_MASK (0xFF<<24) @@ -10,4 +10,4 @@ static inline unsigned get_apic_id(unsigned long x) #define GET_APIC_ID(x) get_apic_id(x) -#endif +#endif /* ASM_X86__MACH_SUMMIT__MACH_APICDEF_H */ diff --git a/include/asm-x86/mach-summit/mach_ipi.h b/include/asm-x86/mach-summit/mach_ipi.h index 9404c535b7e..a3b31c528d9 100644 --- a/include/asm-x86/mach-summit/mach_ipi.h +++ b/include/asm-x86/mach-summit/mach_ipi.h @@ -1,5 +1,5 @@ -#ifndef __ASM_MACH_IPI_H -#define __ASM_MACH_IPI_H +#ifndef ASM_X86__MACH_SUMMIT__MACH_IPI_H +#define ASM_X86__MACH_SUMMIT__MACH_IPI_H void send_IPI_mask_sequence(cpumask_t mask, int vector); @@ -22,4 +22,4 @@ static inline void send_IPI_all(int vector) send_IPI_mask(cpu_online_map, vector); } -#endif /* __ASM_MACH_IPI_H */ +#endif /* ASM_X86__MACH_SUMMIT__MACH_IPI_H */ diff --git a/include/asm-x86/mach-summit/mach_mpparse.h b/include/asm-x86/mach-summit/mach_mpparse.h index fdf59170133..92396f28772 100644 --- a/include/asm-x86/mach-summit/mach_mpparse.h +++ b/include/asm-x86/mach-summit/mach_mpparse.h @@ -1,5 +1,5 @@ -#ifndef __ASM_MACH_MPPARSE_H -#define __ASM_MACH_MPPARSE_H +#ifndef ASM_X86__MACH_SUMMIT__MACH_MPPARSE_H +#define ASM_X86__MACH_SUMMIT__MACH_MPPARSE_H #include <mach_apic.h> #include <asm/tsc.h> @@ -107,4 +107,4 @@ static inline int is_WPEG(struct rio_detail *rio){ rio->type == LookOutAWPEG || rio->type == LookOutBWPEG); } -#endif /* __ASM_MACH_MPPARSE_H */ +#endif /* ASM_X86__MACH_SUMMIT__MACH_MPPARSE_H */ diff --git a/include/asm-x86/math_emu.h b/include/asm-x86/math_emu.h index 9bf4ae93ab1..5768d8e95c8 100644 --- a/include/asm-x86/math_emu.h +++ b/include/asm-x86/math_emu.h @@ -1,5 +1,5 @@ -#ifndef _I386_MATH_EMU_H -#define _I386_MATH_EMU_H +#ifndef ASM_X86__MATH_EMU_H +#define ASM_X86__MATH_EMU_H /* This structure matches the layout of the data saved to the stack following a device-not-present interrupt, part of it saved @@ -28,4 +28,4 @@ struct info { long ___vm86_fs; long ___vm86_gs; }; -#endif +#endif /* ASM_X86__MATH_EMU_H */ diff --git a/include/asm-x86/mc146818rtc.h b/include/asm-x86/mc146818rtc.h index daf1ccde77a..a995f33176c 100644 --- a/include/asm-x86/mc146818rtc.h +++ b/include/asm-x86/mc146818rtc.h @@ -1,8 +1,8 @@ /* * Machine dependent access functions for RTC registers. */ -#ifndef _ASM_MC146818RTC_H -#define _ASM_MC146818RTC_H +#ifndef ASM_X86__MC146818RTC_H +#define ASM_X86__MC146818RTC_H #include <asm/io.h> #include <asm/system.h> @@ -101,4 +101,4 @@ extern unsigned long mach_get_cmos_time(void); #define RTC_IRQ 8 -#endif /* _ASM_MC146818RTC_H */ +#endif /* ASM_X86__MC146818RTC_H */ diff --git a/include/asm-x86/mca.h b/include/asm-x86/mca.h index 09adf2eac4d..60d1ed287b1 100644 --- a/include/asm-x86/mca.h +++ b/include/asm-x86/mca.h @@ -1,8 +1,8 @@ /* -*- mode: c; c-basic-offset: 8 -*- */ /* Platform specific MCA defines */ -#ifndef _ASM_MCA_H -#define _ASM_MCA_H +#ifndef ASM_X86__MCA_H +#define ASM_X86__MCA_H /* Maximal number of MCA slots - actually, some machines have less, but * they all have sufficient number of POS registers to cover 8. @@ -40,4 +40,4 @@ */ #define MCA_NUMADAPTERS (MCA_MAX_SLOT_NR+3) -#endif +#endif /* ASM_X86__MCA_H */ diff --git a/include/asm-x86/mca_dma.h b/include/asm-x86/mca_dma.h index c3dca6edc6b..49f22be237d 100644 --- a/include/asm-x86/mca_dma.h +++ b/include/asm-x86/mca_dma.h @@ -1,5 +1,5 @@ -#ifndef MCA_DMA_H -#define MCA_DMA_H +#ifndef ASM_X86__MCA_DMA_H +#define ASM_X86__MCA_DMA_H #include <asm/io.h> #include <linux/ioport.h> @@ -198,4 +198,4 @@ static inline void mca_set_dma_mode(unsigned int dmanr, unsigned int mode) outb(mode, MCA_DMA_REG_EXE); } -#endif /* MCA_DMA_H */ +#endif /* ASM_X86__MCA_DMA_H */ diff --git a/include/asm-x86/mce.h b/include/asm-x86/mce.h index 531eaa58745..036133eaf74 100644 --- a/include/asm-x86/mce.h +++ b/include/asm-x86/mce.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_MCE_H -#define _ASM_X86_MCE_H +#ifndef ASM_X86__MCE_H +#define ASM_X86__MCE_H #ifdef __x86_64__ @@ -127,4 +127,4 @@ extern void restart_mce(void); #endif /* __KERNEL__ */ -#endif +#endif /* ASM_X86__MCE_H */ diff --git a/include/asm-x86/mman.h b/include/asm-x86/mman.h index 90bc4108a4f..4ef28e6de38 100644 --- a/include/asm-x86/mman.h +++ b/include/asm-x86/mman.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_MMAN_H -#define _ASM_X86_MMAN_H +#ifndef ASM_X86__MMAN_H +#define ASM_X86__MMAN_H #include <asm-generic/mman.h> @@ -17,4 +17,4 @@ #define MCL_CURRENT 1 /* lock all current mappings */ #define MCL_FUTURE 2 /* lock all future mappings */ -#endif /* _ASM_X86_MMAN_H */ +#endif /* ASM_X86__MMAN_H */ diff --git a/include/asm-x86/mmconfig.h b/include/asm-x86/mmconfig.h index e293ab81e85..fb79b1cf5d0 100644 --- a/include/asm-x86/mmconfig.h +++ b/include/asm-x86/mmconfig.h @@ -1,5 +1,5 @@ -#ifndef _ASM_MMCONFIG_H -#define _ASM_MMCONFIG_H +#ifndef ASM_X86__MMCONFIG_H +#define ASM_X86__MMCONFIG_H #ifdef CONFIG_PCI_MMCONFIG extern void __cpuinit fam10h_check_enable_mmcfg(void); @@ -9,4 +9,4 @@ static inline void fam10h_check_enable_mmcfg(void) { } static inline void check_enable_amd_mmconf_dmi(void) { } #endif -#endif +#endif /* ASM_X86__MMCONFIG_H */ diff --git a/include/asm-x86/mmu.h b/include/asm-x86/mmu.h index 00e88679e11..9d5aff14334 100644 --- a/include/asm-x86/mmu.h +++ b/include/asm-x86/mmu.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_MMU_H -#define _ASM_X86_MMU_H +#ifndef ASM_X86__MMU_H +#define ASM_X86__MMU_H #include <linux/spinlock.h> #include <linux/mutex.h> @@ -7,14 +7,9 @@ /* * The x86 doesn't have a mmu context, but * we put the segment information here. - * - * cpu_vm_mask is used to optimize ldt flushing. */ typedef struct { void *ldt; -#ifdef CONFIG_X86_64 - rwlock_t ldtlock; -#endif int size; struct mutex lock; void *vdso; @@ -28,4 +23,4 @@ static inline void leave_mm(int cpu) } #endif -#endif /* _ASM_X86_MMU_H */ +#endif /* ASM_X86__MMU_H */ diff --git a/include/asm-x86/mmu_context.h b/include/asm-x86/mmu_context.h index fac57014e7c..8ec940bfd07 100644 --- a/include/asm-x86/mmu_context.h +++ b/include/asm-x86/mmu_context.h @@ -1,5 +1,5 @@ -#ifndef __ASM_X86_MMU_CONTEXT_H -#define __ASM_X86_MMU_CONTEXT_H +#ifndef ASM_X86__MMU_CONTEXT_H +#define ASM_X86__MMU_CONTEXT_H #include <asm/desc.h> #include <asm/atomic.h> @@ -34,4 +34,4 @@ do { \ } while (0); -#endif /* __ASM_X86_MMU_CONTEXT_H */ +#endif /* ASM_X86__MMU_CONTEXT_H */ diff --git a/include/asm-x86/mmu_context_32.h b/include/asm-x86/mmu_context_32.h index 824fc575c6d..cce6f6e4afd 100644 --- a/include/asm-x86/mmu_context_32.h +++ b/include/asm-x86/mmu_context_32.h @@ -1,5 +1,5 @@ -#ifndef __I386_SCHED_H -#define __I386_SCHED_H +#ifndef ASM_X86__MMU_CONTEXT_32_H +#define ASM_X86__MMU_CONTEXT_32_H static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) { @@ -53,4 +53,4 @@ static inline void switch_mm(struct mm_struct *prev, #define deactivate_mm(tsk, mm) \ asm("movl %0,%%gs": :"r" (0)); -#endif +#endif /* ASM_X86__MMU_CONTEXT_32_H */ diff --git a/include/asm-x86/mmu_context_64.h b/include/asm-x86/mmu_context_64.h index c7000634cca..26758673c82 100644 --- a/include/asm-x86/mmu_context_64.h +++ b/include/asm-x86/mmu_context_64.h @@ -1,5 +1,5 @@ -#ifndef __X86_64_MMU_CONTEXT_H -#define __X86_64_MMU_CONTEXT_H +#ifndef ASM_X86__MMU_CONTEXT_64_H +#define ASM_X86__MMU_CONTEXT_64_H #include <asm/pda.h> @@ -51,4 +51,4 @@ do { \ asm volatile("movl %0,%%fs"::"r"(0)); \ } while (0) -#endif +#endif /* ASM_X86__MMU_CONTEXT_64_H */ diff --git a/include/asm-x86/mmx.h b/include/asm-x86/mmx.h index 940881218ff..2e7299bb365 100644 --- a/include/asm-x86/mmx.h +++ b/include/asm-x86/mmx.h @@ -1,5 +1,5 @@ -#ifndef _ASM_MMX_H -#define _ASM_MMX_H +#ifndef ASM_X86__MMX_H +#define ASM_X86__MMX_H /* * MMX 3Dnow! helper operations @@ -11,4 +11,4 @@ extern void *_mmx_memcpy(void *to, const void *from, size_t size); extern void mmx_clear_page(void *page); extern void mmx_copy_page(void *to, void *from); -#endif +#endif /* ASM_X86__MMX_H */ diff --git a/include/asm-x86/mmzone_32.h b/include/asm-x86/mmzone_32.h index 5862e646065..121b65d61d8 100644 --- a/include/asm-x86/mmzone_32.h +++ b/include/asm-x86/mmzone_32.h @@ -3,8 +3,8 @@ * */ -#ifndef _ASM_MMZONE_H_ -#define _ASM_MMZONE_H_ +#ifndef ASM_X86__MMZONE_32_H +#define ASM_X86__MMZONE_32_H #include <asm/smp.h> @@ -131,4 +131,4 @@ static inline int pfn_valid(int pfn) }) #endif /* CONFIG_NEED_MULTIPLE_NODES */ -#endif /* _ASM_MMZONE_H_ */ +#endif /* ASM_X86__MMZONE_32_H */ diff --git a/include/asm-x86/mmzone_64.h b/include/asm-x86/mmzone_64.h index 594bd0dc1d0..626b03a1487 100644 --- a/include/asm-x86/mmzone_64.h +++ b/include/asm-x86/mmzone_64.h @@ -1,8 +1,8 @@ /* K8 NUMA support */ /* Copyright 2002,2003 by Andi Kleen, SuSE Labs */ /* 2.5 Version loosely based on the NUMAQ Code by Pat Gaughen. */ -#ifndef _ASM_X86_64_MMZONE_H -#define _ASM_X86_64_MMZONE_H 1 +#ifndef ASM_X86__MMZONE_64_H +#define ASM_X86__MMZONE_64_H #ifdef CONFIG_NUMA @@ -49,4 +49,4 @@ extern int early_pfn_to_nid(unsigned long pfn); #endif #endif -#endif +#endif /* ASM_X86__MMZONE_64_H */ diff --git a/include/asm-x86/module.h b/include/asm-x86/module.h index bfedb247871..48dc3e0c07d 100644 --- a/include/asm-x86/module.h +++ b/include/asm-x86/module.h @@ -1,5 +1,5 @@ -#ifndef _ASM_MODULE_H -#define _ASM_MODULE_H +#ifndef ASM_X86__MODULE_H +#define ASM_X86__MODULE_H /* x86_32/64 are simple */ struct mod_arch_specific {}; @@ -79,4 +79,4 @@ struct mod_arch_specific {}; # define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_STACKSIZE #endif -#endif /* _ASM_MODULE_H */ +#endif /* ASM_X86__MODULE_H */ diff --git a/include/asm-x86/mpspec.h b/include/asm-x86/mpspec.h index b6995e567fc..118da365e37 100644 --- a/include/asm-x86/mpspec.h +++ b/include/asm-x86/mpspec.h @@ -1,5 +1,5 @@ -#ifndef _AM_X86_MPSPEC_H -#define _AM_X86_MPSPEC_H +#ifndef ASM_X86__MPSPEC_H +#define ASM_X86__MPSPEC_H #include <linux/init.h> @@ -141,4 +141,4 @@ static inline void physid_set_mask_of_physid(int physid, physid_mask_t *map) extern physid_mask_t phys_cpu_present_map; -#endif +#endif /* ASM_X86__MPSPEC_H */ diff --git a/include/asm-x86/mpspec_def.h b/include/asm-x86/mpspec_def.h index 38d1e73b49e..79166b04801 100644 --- a/include/asm-x86/mpspec_def.h +++ b/include/asm-x86/mpspec_def.h @@ -1,5 +1,5 @@ -#ifndef __ASM_MPSPEC_DEF_H -#define __ASM_MPSPEC_DEF_H +#ifndef ASM_X86__MPSPEC_DEF_H +#define ASM_X86__MPSPEC_DEF_H /* * Structure definitions for SMP machines following the @@ -177,4 +177,4 @@ enum mp_bustype { MP_BUS_PCI, MP_BUS_MCA, }; -#endif +#endif /* ASM_X86__MPSPEC_DEF_H */ diff --git a/include/asm-x86/msgbuf.h b/include/asm-x86/msgbuf.h index 7e4e9481f51..1b538c907a3 100644 --- a/include/asm-x86/msgbuf.h +++ b/include/asm-x86/msgbuf.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_MSGBUF_H -#define _ASM_X86_MSGBUF_H +#ifndef ASM_X86__MSGBUF_H +#define ASM_X86__MSGBUF_H /* * The msqid64_ds structure for i386 architecture. @@ -36,4 +36,4 @@ struct msqid64_ds { unsigned long __unused5; }; -#endif /* _ASM_X86_MSGBUF_H */ +#endif /* ASM_X86__MSGBUF_H */ diff --git a/include/asm-x86/msidef.h b/include/asm-x86/msidef.h index 296f29ce426..3139666a94f 100644 --- a/include/asm-x86/msidef.h +++ b/include/asm-x86/msidef.h @@ -1,5 +1,5 @@ -#ifndef ASM_MSIDEF_H -#define ASM_MSIDEF_H +#ifndef ASM_X86__MSIDEF_H +#define ASM_X86__MSIDEF_H /* * Constants for Intel APIC based MSI messages. @@ -48,4 +48,4 @@ #define MSI_ADDR_DEST_ID(dest) (((dest) << MSI_ADDR_DEST_ID_SHIFT) & \ MSI_ADDR_DEST_ID_MASK) -#endif /* ASM_MSIDEF_H */ +#endif /* ASM_X86__MSIDEF_H */ diff --git a/include/asm-x86/msr-index.h b/include/asm-x86/msr-index.h index 44bce773012..3052f058ab0 100644 --- a/include/asm-x86/msr-index.h +++ b/include/asm-x86/msr-index.h @@ -1,5 +1,5 @@ -#ifndef __ASM_MSR_INDEX_H -#define __ASM_MSR_INDEX_H +#ifndef ASM_X86__MSR_INDEX_H +#define ASM_X86__MSR_INDEX_H /* CPU model specific register (MSR) numbers */ @@ -310,4 +310,4 @@ /* Geode defined MSRs */ #define MSR_GEODE_BUSCONT_CONF0 0x00001900 -#endif /* __ASM_MSR_INDEX_H */ +#endif /* ASM_X86__MSR_INDEX_H */ diff --git a/include/asm-x86/msr.h b/include/asm-x86/msr.h index 2362cfda1fb..530af1f6389 100644 --- a/include/asm-x86/msr.h +++ b/include/asm-x86/msr.h @@ -1,5 +1,5 @@ -#ifndef __ASM_X86_MSR_H_ -#define __ASM_X86_MSR_H_ +#ifndef ASM_X86__MSR_H +#define ASM_X86__MSR_H #include <asm/msr-index.h> @@ -63,6 +63,22 @@ static inline unsigned long long native_read_msr_safe(unsigned int msr, return EAX_EDX_VAL(val, low, high); } +static inline unsigned long long native_read_msr_amd_safe(unsigned int msr, + int *err) +{ + DECLARE_ARGS(val, low, high); + + asm volatile("2: rdmsr ; xor %0,%0\n" + "1:\n\t" + ".section .fixup,\"ax\"\n\t" + "3: mov %3,%0 ; jmp 1b\n\t" + ".previous\n\t" + _ASM_EXTABLE(2b, 3b) + : "=r" (*err), EAX_EDX_RET(val, low, high) + : "c" (msr), "D" (0x9c5a203a), "i" (-EFAULT)); + return EAX_EDX_VAL(val, low, high); +} + static inline void native_write_msr(unsigned int msr, unsigned low, unsigned high) { @@ -158,6 +174,13 @@ static inline int rdmsrl_safe(unsigned msr, unsigned long long *p) *p = native_read_msr_safe(msr, &err); return err; } +static inline int rdmsrl_amd_safe(unsigned msr, unsigned long long *p) +{ + int err; + + *p = native_read_msr_amd_safe(msr, &err); + return err; +} #define rdtscl(low) \ ((low) = (u32)native_read_tsc()) @@ -221,4 +244,4 @@ static inline int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h) #endif /* __KERNEL__ */ -#endif +#endif /* ASM_X86__MSR_H */ diff --git a/include/asm-x86/mtrr.h b/include/asm-x86/mtrr.h index a69a01a5172..23a7f83da95 100644 --- a/include/asm-x86/mtrr.h +++ b/include/asm-x86/mtrr.h @@ -20,8 +20,8 @@ The postal address is: Richard Gooch, c/o ATNF, P. O. Box 76, Epping, N.S.W., 2121, Australia. */ -#ifndef _ASM_X86_MTRR_H -#define _ASM_X86_MTRR_H +#ifndef ASM_X86__MTRR_H +#define ASM_X86__MTRR_H #include <linux/ioctl.h> #include <linux/errno.h> @@ -170,4 +170,4 @@ struct mtrr_gentry32 { #endif /* __KERNEL__ */ -#endif /* _ASM_X86_MTRR_H */ +#endif /* ASM_X86__MTRR_H */ diff --git a/include/asm-x86/mutex_32.h b/include/asm-x86/mutex_32.h index 73e928ef5f0..25c16d8ba3c 100644 --- a/include/asm-x86/mutex_32.h +++ b/include/asm-x86/mutex_32.h @@ -6,8 +6,8 @@ * * Copyright (C) 2004, 2005, 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com> */ -#ifndef _ASM_MUTEX_H -#define _ASM_MUTEX_H +#ifndef ASM_X86__MUTEX_32_H +#define ASM_X86__MUTEX_32_H #include <asm/alternative.h> @@ -122,4 +122,4 @@ static inline int __mutex_fastpath_trylock(atomic_t *count, #endif } -#endif +#endif /* ASM_X86__MUTEX_32_H */ diff --git a/include/asm-x86/mutex_64.h b/include/asm-x86/mutex_64.h index f3fae9becb3..918ba21ab9d 100644 --- a/include/asm-x86/mutex_64.h +++ b/include/asm-x86/mutex_64.h @@ -6,8 +6,8 @@ * * Copyright (C) 2004, 2005, 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com> */ -#ifndef _ASM_MUTEX_H -#define _ASM_MUTEX_H +#ifndef ASM_X86__MUTEX_64_H +#define ASM_X86__MUTEX_64_H /** * __mutex_fastpath_lock - decrement and call function if negative @@ -97,4 +97,4 @@ static inline int __mutex_fastpath_trylock(atomic_t *count, return 0; } -#endif +#endif /* ASM_X86__MUTEX_64_H */ diff --git a/include/asm-x86/nmi.h b/include/asm-x86/nmi.h index 02bfc81cbd6..d5e715f024d 100644 --- a/include/asm-x86/nmi.h +++ b/include/asm-x86/nmi.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_NMI_H_ -#define _ASM_X86_NMI_H_ +#ifndef ASM_X86__NMI_H +#define ASM_X86__NMI_H #include <linux/pm.h> #include <asm/irq.h> @@ -82,4 +82,4 @@ void enable_lapic_nmi_watchdog(void); void stop_nmi(void); void restart_nmi(void); -#endif +#endif /* ASM_X86__NMI_H */ diff --git a/include/asm-x86/nops.h b/include/asm-x86/nops.h index ad0bedd10b8..ae742721ae7 100644 --- a/include/asm-x86/nops.h +++ b/include/asm-x86/nops.h @@ -1,5 +1,5 @@ -#ifndef _ASM_NOPS_H -#define _ASM_NOPS_H 1 +#ifndef ASM_X86__NOPS_H +#define ASM_X86__NOPS_H /* Define nops for use with alternative() */ @@ -115,4 +115,4 @@ #define ASM_NOP_MAX 8 -#endif +#endif /* ASM_X86__NOPS_H */ diff --git a/include/asm-x86/numa_32.h b/include/asm-x86/numa_32.h index 220d7b7707a..44cb07855c5 100644 --- a/include/asm-x86/numa_32.h +++ b/include/asm-x86/numa_32.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_32_NUMA_H -#define _ASM_X86_32_NUMA_H 1 +#ifndef ASM_X86__NUMA_32_H +#define ASM_X86__NUMA_32_H extern int pxm_to_nid(int pxm); extern void numa_remove_cpu(int cpu); @@ -8,4 +8,4 @@ extern void numa_remove_cpu(int cpu); extern void set_highmem_pages_init(void); #endif -#endif /* _ASM_X86_32_NUMA_H */ +#endif /* ASM_X86__NUMA_32_H */ diff --git a/include/asm-x86/numa_64.h b/include/asm-x86/numa_64.h index 3830094434a..15c990395b0 100644 --- a/include/asm-x86/numa_64.h +++ b/include/asm-x86/numa_64.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X8664_NUMA_H -#define _ASM_X8664_NUMA_H 1 +#ifndef ASM_X86__NUMA_64_H +#define ASM_X86__NUMA_64_H #include <linux/nodemask.h> #include <asm/apicdef.h> @@ -40,4 +40,4 @@ static inline void numa_add_cpu(int cpu, int node) { } static inline void numa_remove_cpu(int cpu) { } #endif -#endif +#endif /* ASM_X86__NUMA_64_H */ diff --git a/include/asm-x86/numaq.h b/include/asm-x86/numaq.h index 34b92d581fa..124bf7d4b70 100644 --- a/include/asm-x86/numaq.h +++ b/include/asm-x86/numaq.h @@ -23,8 +23,8 @@ * Send feedback to <gone@us.ibm.com> */ -#ifndef NUMAQ_H -#define NUMAQ_H +#ifndef ASM_X86__NUMAQ_H +#define ASM_X86__NUMAQ_H #ifdef CONFIG_X86_NUMAQ @@ -165,5 +165,5 @@ static inline int get_memcfg_numaq(void) return 0; } #endif /* CONFIG_X86_NUMAQ */ -#endif /* NUMAQ_H */ +#endif /* ASM_X86__NUMAQ_H */ diff --git a/include/asm-x86/olpc.h b/include/asm-x86/olpc.h index 97d47133486..d7328b1a05c 100644 --- a/include/asm-x86/olpc.h +++ b/include/asm-x86/olpc.h @@ -1,7 +1,7 @@ /* OLPC machine specific definitions */ -#ifndef ASM_OLPC_H_ -#define ASM_OLPC_H_ +#ifndef ASM_X86__OLPC_H +#define ASM_X86__OLPC_H #include <asm/geode.h> @@ -129,4 +129,4 @@ extern int olpc_ec_mask_unset(uint8_t bits); #define OLPC_GPIO_LID geode_gpio(26) #define OLPC_GPIO_ECSCI geode_gpio(27) -#endif +#endif /* ASM_X86__OLPC_H */ diff --git a/include/asm-x86/page.h b/include/asm-x86/page.h index 49982110e4d..79544e6ffb8 100644 --- a/include/asm-x86/page.h +++ b/include/asm-x86/page.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_PAGE_H -#define _ASM_X86_PAGE_H +#ifndef ASM_X86__PAGE_H +#define ASM_X86__PAGE_H #include <linux/const.h> @@ -199,4 +199,4 @@ static inline pteval_t native_pte_flags(pte_t pte) #define __HAVE_ARCH_GATE_AREA 1 #endif /* __KERNEL__ */ -#endif /* _ASM_X86_PAGE_H */ +#endif /* ASM_X86__PAGE_H */ diff --git a/include/asm-x86/page_32.h b/include/asm-x86/page_32.h index ab8528793f0..72f7305682c 100644 --- a/include/asm-x86/page_32.h +++ b/include/asm-x86/page_32.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_PAGE_32_H -#define _ASM_X86_PAGE_32_H +#ifndef ASM_X86__PAGE_32_H +#define ASM_X86__PAGE_32_H /* * This handles the memory map. @@ -89,13 +89,11 @@ extern int nx_enabled; extern unsigned int __VMALLOC_RESERVE; extern int sysctl_legacy_va_layout; -#define VMALLOC_RESERVE ((unsigned long)__VMALLOC_RESERVE) -#define MAXMEM (-__PAGE_OFFSET - __VMALLOC_RESERVE) - extern void find_low_pfn_range(void); extern unsigned long init_memory_mapping(unsigned long start, unsigned long end); extern void initmem_init(unsigned long, unsigned long); +extern void free_initmem(void); extern void setup_bootmem_allocator(void); @@ -126,4 +124,4 @@ static inline void copy_page(void *to, void *from) #endif /* CONFIG_X86_3DNOW */ #endif /* !__ASSEMBLY__ */ -#endif /* _ASM_X86_PAGE_32_H */ +#endif /* ASM_X86__PAGE_32_H */ diff --git a/include/asm-x86/page_64.h b/include/asm-x86/page_64.h index c6916c83e6b..5e64acfed0a 100644 --- a/include/asm-x86/page_64.h +++ b/include/asm-x86/page_64.h @@ -1,5 +1,5 @@ -#ifndef _X86_64_PAGE_H -#define _X86_64_PAGE_H +#ifndef ASM_X86__PAGE_64_H +#define ASM_X86__PAGE_64_H #define PAGETABLE_LEVELS 4 @@ -91,6 +91,7 @@ extern unsigned long init_memory_mapping(unsigned long start, unsigned long end); extern void initmem_init(unsigned long start_pfn, unsigned long end_pfn); +extern void free_initmem(void); extern void init_extra_mapping_uc(unsigned long phys, unsigned long size); extern void init_extra_mapping_wb(unsigned long phys, unsigned long size); @@ -102,4 +103,4 @@ extern void init_extra_mapping_wb(unsigned long phys, unsigned long size); #endif -#endif /* _X86_64_PAGE_H */ +#endif /* ASM_X86__PAGE_64_H */ diff --git a/include/asm-x86/param.h b/include/asm-x86/param.h index 6f0d0422f4c..0009cfb11a5 100644 --- a/include/asm-x86/param.h +++ b/include/asm-x86/param.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_PARAM_H -#define _ASM_X86_PARAM_H +#ifndef ASM_X86__PARAM_H +#define ASM_X86__PARAM_H #ifdef __KERNEL__ # define HZ CONFIG_HZ /* Internal kernel timer frequency */ @@ -19,4 +19,4 @@ #define MAXHOSTNAMELEN 64 /* max length of hostname */ -#endif /* _ASM_X86_PARAM_H */ +#endif /* ASM_X86__PARAM_H */ diff --git a/include/asm-x86/paravirt.h b/include/asm-x86/paravirt.h index fbbde93f12d..891971f57d3 100644 --- a/include/asm-x86/paravirt.h +++ b/include/asm-x86/paravirt.h @@ -1,5 +1,5 @@ -#ifndef __ASM_PARAVIRT_H -#define __ASM_PARAVIRT_H +#ifndef ASM_X86__PARAVIRT_H +#define ASM_X86__PARAVIRT_H /* Various instructions on x86 need to be replaced for * para-virtualization: those hooks are defined here. */ @@ -137,6 +137,7 @@ struct pv_cpu_ops { /* MSR, PMC and TSR operations. err = 0/-EFAULT. wrmsr returns 0/-EFAULT. */ + u64 (*read_msr_amd)(unsigned int msr, int *err); u64 (*read_msr)(unsigned int msr, int *err); int (*write_msr)(unsigned int msr, unsigned low, unsigned high); @@ -257,13 +258,13 @@ struct pv_mmu_ops { * Hooks for allocating/releasing pagetable pages when they're * attached to a pagetable */ - void (*alloc_pte)(struct mm_struct *mm, u32 pfn); - void (*alloc_pmd)(struct mm_struct *mm, u32 pfn); - void (*alloc_pmd_clone)(u32 pfn, u32 clonepfn, u32 start, u32 count); - void (*alloc_pud)(struct mm_struct *mm, u32 pfn); - void (*release_pte)(u32 pfn); - void (*release_pmd)(u32 pfn); - void (*release_pud)(u32 pfn); + void (*alloc_pte)(struct mm_struct *mm, unsigned long pfn); + void (*alloc_pmd)(struct mm_struct *mm, unsigned long pfn); + void (*alloc_pmd_clone)(unsigned long pfn, unsigned long clonepfn, unsigned long start, unsigned long count); + void (*alloc_pud)(struct mm_struct *mm, unsigned long pfn); + void (*release_pte)(unsigned long pfn); + void (*release_pmd)(unsigned long pfn); + void (*release_pud)(unsigned long pfn); /* Pagetable manipulation functions */ void (*set_pte)(pte_t *ptep, pte_t pteval); @@ -726,6 +727,10 @@ static inline u64 paravirt_read_msr(unsigned msr, int *err) { return PVOP_CALL2(u64, pv_cpu_ops.read_msr, msr, err); } +static inline u64 paravirt_read_msr_amd(unsigned msr, int *err) +{ + return PVOP_CALL2(u64, pv_cpu_ops.read_msr_amd, msr, err); +} static inline int paravirt_write_msr(unsigned msr, unsigned low, unsigned high) { return PVOP_CALL3(int, pv_cpu_ops.write_msr, msr, low, high); @@ -771,6 +776,13 @@ static inline int rdmsrl_safe(unsigned msr, unsigned long long *p) *p = paravirt_read_msr(msr, &err); return err; } +static inline int rdmsrl_amd_safe(unsigned msr, unsigned long long *p) +{ + int err; + + *p = paravirt_read_msr_amd(msr, &err); + return err; +} static inline u64 paravirt_read_tsc(void) { @@ -993,35 +1005,35 @@ static inline void paravirt_pgd_free(struct mm_struct *mm, pgd_t *pgd) PVOP_VCALL2(pv_mmu_ops.pgd_free, mm, pgd); } -static inline void paravirt_alloc_pte(struct mm_struct *mm, unsigned pfn) +static inline void paravirt_alloc_pte(struct mm_struct *mm, unsigned long pfn) { PVOP_VCALL2(pv_mmu_ops.alloc_pte, mm, pfn); } -static inline void paravirt_release_pte(unsigned pfn) +static inline void paravirt_release_pte(unsigned long pfn) { PVOP_VCALL1(pv_mmu_ops.release_pte, pfn); } -static inline void paravirt_alloc_pmd(struct mm_struct *mm, unsigned pfn) +static inline void paravirt_alloc_pmd(struct mm_struct *mm, unsigned long pfn) { PVOP_VCALL2(pv_mmu_ops.alloc_pmd, mm, pfn); } -static inline void paravirt_alloc_pmd_clone(unsigned pfn, unsigned clonepfn, - unsigned start, unsigned count) +static inline void paravirt_alloc_pmd_clone(unsigned long pfn, unsigned long clonepfn, + unsigned long start, unsigned long count) { PVOP_VCALL4(pv_mmu_ops.alloc_pmd_clone, pfn, clonepfn, start, count); } -static inline void paravirt_release_pmd(unsigned pfn) +static inline void paravirt_release_pmd(unsigned long pfn) { PVOP_VCALL1(pv_mmu_ops.release_pmd, pfn); } -static inline void paravirt_alloc_pud(struct mm_struct *mm, unsigned pfn) +static inline void paravirt_alloc_pud(struct mm_struct *mm, unsigned long pfn) { PVOP_VCALL2(pv_mmu_ops.alloc_pud, mm, pfn); } -static inline void paravirt_release_pud(unsigned pfn) +static inline void paravirt_release_pud(unsigned long pfn) { PVOP_VCALL1(pv_mmu_ops.release_pud, pfn); } @@ -1634,4 +1646,4 @@ static inline unsigned long __raw_local_irq_save(void) #endif /* __ASSEMBLY__ */ #endif /* CONFIG_PARAVIRT */ -#endif /* __ASM_PARAVIRT_H */ +#endif /* ASM_X86__PARAVIRT_H */ diff --git a/include/asm-x86/parport.h b/include/asm-x86/parport.h index 3c4ffeb467e..2e3dda4dc3d 100644 --- a/include/asm-x86/parport.h +++ b/include/asm-x86/parport.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_PARPORT_H -#define _ASM_X86_PARPORT_H +#ifndef ASM_X86__PARPORT_H +#define ASM_X86__PARPORT_H static int __devinit parport_pc_find_isa_ports(int autoirq, int autodma); static int __devinit parport_pc_find_nonpci_ports(int autoirq, int autodma) @@ -7,4 +7,4 @@ static int __devinit parport_pc_find_nonpci_ports(int autoirq, int autodma) return parport_pc_find_isa_ports(autoirq, autodma); } -#endif /* _ASM_X86_PARPORT_H */ +#endif /* ASM_X86__PARPORT_H */ diff --git a/include/asm-x86/pat.h b/include/asm-x86/pat.h index 7edc4730721..482c3e3f987 100644 --- a/include/asm-x86/pat.h +++ b/include/asm-x86/pat.h @@ -1,5 +1,5 @@ -#ifndef _ASM_PAT_H -#define _ASM_PAT_H +#ifndef ASM_X86__PAT_H +#define ASM_X86__PAT_H #include <linux/types.h> @@ -19,4 +19,4 @@ extern int free_memtype(u64 start, u64 end); extern void pat_disable(char *reason); -#endif +#endif /* ASM_X86__PAT_H */ diff --git a/include/asm-x86/pci-direct.h b/include/asm-x86/pci-direct.h index 80c775d9fe2..da42be07b69 100644 --- a/include/asm-x86/pci-direct.h +++ b/include/asm-x86/pci-direct.h @@ -1,5 +1,5 @@ -#ifndef ASM_PCI_DIRECT_H -#define ASM_PCI_DIRECT_H 1 +#ifndef ASM_X86__PCI_DIRECT_H +#define ASM_X86__PCI_DIRECT_H #include <linux/types.h> @@ -18,4 +18,4 @@ extern int early_pci_allowed(void); extern unsigned int pci_early_dump_regs; extern void early_dump_pci_device(u8 bus, u8 slot, u8 func); extern void early_dump_pci_devices(void); -#endif +#endif /* ASM_X86__PCI_DIRECT_H */ diff --git a/include/asm-x86/pci.h b/include/asm-x86/pci.h index 2db14cf17db..60258319299 100644 --- a/include/asm-x86/pci.h +++ b/include/asm-x86/pci.h @@ -1,5 +1,5 @@ -#ifndef __x86_PCI_H -#define __x86_PCI_H +#ifndef ASM_X86__PCI_H +#define ASM_X86__PCI_H #include <linux/mm.h> /* for struct page */ #include <linux/types.h> @@ -111,4 +111,4 @@ static inline cpumask_t __pcibus_to_cpumask(struct pci_bus *bus) } #endif -#endif +#endif /* ASM_X86__PCI_H */ diff --git a/include/asm-x86/pci_32.h b/include/asm-x86/pci_32.h index a50d4685128..3f2288207c0 100644 --- a/include/asm-x86/pci_32.h +++ b/include/asm-x86/pci_32.h @@ -1,5 +1,5 @@ -#ifndef __i386_PCI_H -#define __i386_PCI_H +#ifndef ASM_X86__PCI_32_H +#define ASM_X86__PCI_32_H #ifdef __KERNEL__ @@ -31,4 +31,4 @@ struct pci_dev; #endif /* __KERNEL__ */ -#endif /* __i386_PCI_H */ +#endif /* ASM_X86__PCI_32_H */ diff --git a/include/asm-x86/pci_64.h b/include/asm-x86/pci_64.h index f330234ffa5..f72e12d5770 100644 --- a/include/asm-x86/pci_64.h +++ b/include/asm-x86/pci_64.h @@ -1,5 +1,5 @@ -#ifndef __x8664_PCI_H -#define __x8664_PCI_H +#ifndef ASM_X86__PCI_64_H +#define ASM_X86__PCI_64_H #ifdef __KERNEL__ @@ -63,4 +63,4 @@ extern void pci_iommu_alloc(void); #endif /* __KERNEL__ */ -#endif /* __x8664_PCI_H */ +#endif /* ASM_X86__PCI_64_H */ diff --git a/include/asm-x86/pda.h b/include/asm-x86/pda.h index b34e9a7cc80..80860afffbd 100644 --- a/include/asm-x86/pda.h +++ b/include/asm-x86/pda.h @@ -1,5 +1,5 @@ -#ifndef X86_64_PDA_H -#define X86_64_PDA_H +#ifndef ASM_X86__PDA_H +#define ASM_X86__PDA_H #ifndef __ASSEMBLY__ #include <linux/stddef.h> @@ -134,4 +134,4 @@ do { \ #define PDA_STACKOFFSET (5*8) -#endif +#endif /* ASM_X86__PDA_H */ diff --git a/include/asm-x86/percpu.h b/include/asm-x86/percpu.h index f643a3a92da..e10a1d0678c 100644 --- a/include/asm-x86/percpu.h +++ b/include/asm-x86/percpu.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_PERCPU_H_ -#define _ASM_X86_PERCPU_H_ +#ifndef ASM_X86__PERCPU_H +#define ASM_X86__PERCPU_H #ifdef CONFIG_X86_64 #include <linux/compiler.h> @@ -215,4 +215,4 @@ do { \ #endif /* !CONFIG_SMP */ -#endif /* _ASM_X86_PERCPU_H_ */ +#endif /* ASM_X86__PERCPU_H */ diff --git a/include/asm-x86/pgalloc.h b/include/asm-x86/pgalloc.h index d63ea431cb3..3cd23adedae 100644 --- a/include/asm-x86/pgalloc.h +++ b/include/asm-x86/pgalloc.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_PGALLOC_H -#define _ASM_X86_PGALLOC_H +#ifndef ASM_X86__PGALLOC_H +#define ASM_X86__PGALLOC_H #include <linux/threads.h> #include <linux/mm.h> /* for struct page */ @@ -111,4 +111,4 @@ extern void __pud_free_tlb(struct mmu_gather *tlb, pud_t *pud); #endif /* PAGETABLE_LEVELS > 3 */ #endif /* PAGETABLE_LEVELS > 2 */ -#endif /* _ASM_X86_PGALLOC_H */ +#endif /* ASM_X86__PGALLOC_H */ diff --git a/include/asm-x86/pgtable-2level-defs.h b/include/asm-x86/pgtable-2level-defs.h index 0f71c9f13da..7ec48f4e534 100644 --- a/include/asm-x86/pgtable-2level-defs.h +++ b/include/asm-x86/pgtable-2level-defs.h @@ -1,5 +1,5 @@ -#ifndef _I386_PGTABLE_2LEVEL_DEFS_H -#define _I386_PGTABLE_2LEVEL_DEFS_H +#ifndef ASM_X86__PGTABLE_2LEVEL_DEFS_H +#define ASM_X86__PGTABLE_2LEVEL_DEFS_H #define SHARED_KERNEL_PMD 0 @@ -17,4 +17,4 @@ #define PTRS_PER_PTE 1024 -#endif /* _I386_PGTABLE_2LEVEL_DEFS_H */ +#endif /* ASM_X86__PGTABLE_2LEVEL_DEFS_H */ diff --git a/include/asm-x86/pgtable-2level.h b/include/asm-x86/pgtable-2level.h index 46bc52c0eae..81762081dcd 100644 --- a/include/asm-x86/pgtable-2level.h +++ b/include/asm-x86/pgtable-2level.h @@ -1,5 +1,5 @@ -#ifndef _I386_PGTABLE_2LEVEL_H -#define _I386_PGTABLE_2LEVEL_H +#ifndef ASM_X86__PGTABLE_2LEVEL_H +#define ASM_X86__PGTABLE_2LEVEL_H #define pte_ERROR(e) \ printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, (e).pte_low) @@ -53,9 +53,7 @@ static inline pte_t native_ptep_get_and_clear(pte_t *xp) #define native_ptep_get_and_clear(xp) native_local_ptep_get_and_clear(xp) #endif -#define pte_page(x) pfn_to_page(pte_pfn(x)) #define pte_none(x) (!(x).pte_low) -#define pte_pfn(x) (pte_val(x) >> PAGE_SHIFT) /* * Bits 0, 6 and 7 are taken, split up the 29 bits of offset @@ -78,4 +76,4 @@ static inline pte_t native_ptep_get_and_clear(pte_t *xp) #define __pte_to_swp_entry(pte) ((swp_entry_t) { (pte).pte_low }) #define __swp_entry_to_pte(x) ((pte_t) { .pte = (x).val }) -#endif /* _I386_PGTABLE_2LEVEL_H */ +#endif /* ASM_X86__PGTABLE_2LEVEL_H */ diff --git a/include/asm-x86/pgtable-3level-defs.h b/include/asm-x86/pgtable-3level-defs.h index 448ac951631..c05fe6ff372 100644 --- a/include/asm-x86/pgtable-3level-defs.h +++ b/include/asm-x86/pgtable-3level-defs.h @@ -1,5 +1,5 @@ -#ifndef _I386_PGTABLE_3LEVEL_DEFS_H -#define _I386_PGTABLE_3LEVEL_DEFS_H +#ifndef ASM_X86__PGTABLE_3LEVEL_DEFS_H +#define ASM_X86__PGTABLE_3LEVEL_DEFS_H #ifdef CONFIG_PARAVIRT #define SHARED_KERNEL_PMD (pv_info.shared_kernel_pmd) @@ -25,4 +25,4 @@ */ #define PTRS_PER_PTE 512 -#endif /* _I386_PGTABLE_3LEVEL_DEFS_H */ +#endif /* ASM_X86__PGTABLE_3LEVEL_DEFS_H */ diff --git a/include/asm-x86/pgtable-3level.h b/include/asm-x86/pgtable-3level.h index 105057f3403..75f4276b5dd 100644 --- a/include/asm-x86/pgtable-3level.h +++ b/include/asm-x86/pgtable-3level.h @@ -1,5 +1,5 @@ -#ifndef _I386_PGTABLE_3LEVEL_H -#define _I386_PGTABLE_3LEVEL_H +#ifndef ASM_X86__PGTABLE_3LEVEL_H +#define ASM_X86__PGTABLE_3LEVEL_H /* * Intel Physical Address Extension (PAE) Mode - three-level page @@ -151,18 +151,11 @@ static inline int pte_same(pte_t a, pte_t b) return a.pte_low == b.pte_low && a.pte_high == b.pte_high; } -#define pte_page(x) pfn_to_page(pte_pfn(x)) - static inline int pte_none(pte_t pte) { return !pte.pte_low && !pte.pte_high; } -static inline unsigned long pte_pfn(pte_t pte) -{ - return (pte_val(pte) & PTE_PFN_MASK) >> PAGE_SHIFT; -} - /* * Bits 0, 6 and 7 are taken in the low part of the pte, * put the 32 bits of offset into the high part. @@ -179,4 +172,4 @@ static inline unsigned long pte_pfn(pte_t pte) #define __pte_to_swp_entry(pte) ((swp_entry_t){ (pte).pte_high }) #define __swp_entry_to_pte(x) ((pte_t){ { .pte_high = (x).val } }) -#endif /* _I386_PGTABLE_3LEVEL_H */ +#endif /* ASM_X86__PGTABLE_3LEVEL_H */ diff --git a/include/asm-x86/pgtable.h b/include/asm-x86/pgtable.h index 04caa2f544d..888add7b088 100644 --- a/include/asm-x86/pgtable.h +++ b/include/asm-x86/pgtable.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_PGTABLE_H -#define _ASM_X86_PGTABLE_H +#ifndef ASM_X86__PGTABLE_H +#define ASM_X86__PGTABLE_H #define FIRST_USER_ADDRESS 0 @@ -186,6 +186,13 @@ static inline int pte_special(pte_t pte) return pte_val(pte) & _PAGE_SPECIAL; } +static inline unsigned long pte_pfn(pte_t pte) +{ + return (pte_val(pte) & PTE_PFN_MASK) >> PAGE_SHIFT; +} + +#define pte_page(pte) pfn_to_page(pte_pfn(pte)) + static inline int pmd_large(pmd_t pte) { return (pmd_val(pte) & (_PAGE_PSE | _PAGE_PRESENT)) == @@ -313,6 +320,8 @@ static inline void native_pagetable_setup_start(pgd_t *base) {} static inline void native_pagetable_setup_done(pgd_t *base) {} #endif +extern int arch_report_meminfo(char *page); + #ifdef CONFIG_PARAVIRT #include <asm/paravirt.h> #else /* !CONFIG_PARAVIRT */ @@ -521,4 +530,4 @@ static inline void clone_pgd_range(pgd_t *dst, pgd_t *src, int count) #include <asm-generic/pgtable.h> #endif /* __ASSEMBLY__ */ -#endif /* _ASM_X86_PGTABLE_H */ +#endif /* ASM_X86__PGTABLE_H */ diff --git a/include/asm-x86/pgtable_32.h b/include/asm-x86/pgtable_32.h index 5c3b26567a9..8de702dc7d6 100644 --- a/include/asm-x86/pgtable_32.h +++ b/include/asm-x86/pgtable_32.h @@ -1,5 +1,5 @@ -#ifndef _I386_PGTABLE_H -#define _I386_PGTABLE_H +#ifndef ASM_X86__PGTABLE_32_H +#define ASM_X86__PGTABLE_32_H /* @@ -31,6 +31,7 @@ static inline void pgtable_cache_init(void) { } static inline void check_pgt_cache(void) { } void paging_init(void); +extern void set_pmd_pfn(unsigned long, unsigned long, pgprot_t); /* * The Linux x86 paging architecture is 'compile-time dual-mode', it @@ -56,8 +57,7 @@ void paging_init(void); * area for the same reason. ;) */ #define VMALLOC_OFFSET (8 * 1024 * 1024) -#define VMALLOC_START (((unsigned long)high_memory + 2 * VMALLOC_OFFSET - 1) \ - & ~(VMALLOC_OFFSET - 1)) +#define VMALLOC_START ((unsigned long)high_memory + VMALLOC_OFFSET) #ifdef CONFIG_X86_PAE #define LAST_PKMAP 512 #else @@ -73,6 +73,8 @@ void paging_init(void); # define VMALLOC_END (FIXADDR_START - 2 * PAGE_SIZE) #endif +#define MAXMEM (VMALLOC_END - PAGE_OFFSET - __VMALLOC_RESERVE) + /* * Define this if things work differently on an i386 and an i486: * it will (on an i486) warn about kernel memory accesses that are @@ -186,4 +188,4 @@ do { \ #define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \ remap_pfn_range(vma, vaddr, pfn, size, prot) -#endif /* _I386_PGTABLE_H */ +#endif /* ASM_X86__PGTABLE_32_H */ diff --git a/include/asm-x86/pgtable_64.h b/include/asm-x86/pgtable_64.h index 549144d03d9..fde9770e53d 100644 --- a/include/asm-x86/pgtable_64.h +++ b/include/asm-x86/pgtable_64.h @@ -1,5 +1,5 @@ -#ifndef _X86_64_PGTABLE_H -#define _X86_64_PGTABLE_H +#ifndef ASM_X86__PGTABLE_64_H +#define ASM_X86__PGTABLE_64_H #include <linux/const.h> #ifndef __ASSEMBLY__ @@ -175,8 +175,6 @@ static inline int pmd_bad(pmd_t pmd) #define pte_present(x) (pte_val((x)) & (_PAGE_PRESENT | _PAGE_PROTNONE)) #define pages_to_mb(x) ((x) >> (20 - PAGE_SHIFT)) /* FIXME: is this right? */ -#define pte_page(x) pfn_to_page(pte_pfn((x))) -#define pte_pfn(x) ((pte_val((x)) & __PHYSICAL_MASK) >> PAGE_SHIFT) /* * Macro to mark a page protection value as "uncacheable". @@ -284,4 +282,4 @@ extern void cleanup_highmap(void); #define __HAVE_ARCH_PTE_SAME #endif /* !__ASSEMBLY__ */ -#endif /* _X86_64_PGTABLE_H */ +#endif /* ASM_X86__PGTABLE_64_H */ diff --git a/include/asm-x86/posix_types_32.h b/include/asm-x86/posix_types_32.h index b031efda37e..70cf2bb0593 100644 --- a/include/asm-x86/posix_types_32.h +++ b/include/asm-x86/posix_types_32.h @@ -1,5 +1,5 @@ -#ifndef __ARCH_I386_POSIX_TYPES_H -#define __ARCH_I386_POSIX_TYPES_H +#ifndef ASM_X86__POSIX_TYPES_32_H +#define ASM_X86__POSIX_TYPES_32_H /* * This file is generally used by user-level software, so you need to @@ -82,4 +82,4 @@ do { \ #endif /* defined(__KERNEL__) */ -#endif +#endif /* ASM_X86__POSIX_TYPES_32_H */ diff --git a/include/asm-x86/posix_types_64.h b/include/asm-x86/posix_types_64.h index d6624c95854..388b4e7f4a4 100644 --- a/include/asm-x86/posix_types_64.h +++ b/include/asm-x86/posix_types_64.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_64_POSIX_TYPES_H -#define _ASM_X86_64_POSIX_TYPES_H +#ifndef ASM_X86__POSIX_TYPES_64_H +#define ASM_X86__POSIX_TYPES_64_H /* * This file is generally used by user-level software, so you need to @@ -116,4 +116,4 @@ static inline void __FD_ZERO(__kernel_fd_set *p) #endif /* defined(__KERNEL__) */ -#endif +#endif /* ASM_X86__POSIX_TYPES_64_H */ diff --git a/include/asm-x86/prctl.h b/include/asm-x86/prctl.h index 52952adef1c..e7ae34eb410 100644 --- a/include/asm-x86/prctl.h +++ b/include/asm-x86/prctl.h @@ -1,5 +1,5 @@ -#ifndef X86_64_PRCTL_H -#define X86_64_PRCTL_H 1 +#ifndef ASM_X86__PRCTL_H +#define ASM_X86__PRCTL_H #define ARCH_SET_GS 0x1001 #define ARCH_SET_FS 0x1002 @@ -7,4 +7,4 @@ #define ARCH_GET_GS 0x1004 -#endif +#endif /* ASM_X86__PRCTL_H */ diff --git a/include/asm-x86/processor-flags.h b/include/asm-x86/processor-flags.h index eff2ecd7fff..5dd79774f69 100644 --- a/include/asm-x86/processor-flags.h +++ b/include/asm-x86/processor-flags.h @@ -1,5 +1,5 @@ -#ifndef __ASM_I386_PROCESSOR_FLAGS_H -#define __ASM_I386_PROCESSOR_FLAGS_H +#ifndef ASM_X86__PROCESSOR_FLAGS_H +#define ASM_X86__PROCESSOR_FLAGS_H /* Various flags defined: can be included from assembler. */ /* @@ -96,4 +96,4 @@ #endif #endif -#endif /* __ASM_I386_PROCESSOR_FLAGS_H */ +#endif /* ASM_X86__PROCESSOR_FLAGS_H */ diff --git a/include/asm-x86/processor.h b/include/asm-x86/processor.h index 4df3e2f6fb5..5eaf9bf0a62 100644 --- a/include/asm-x86/processor.h +++ b/include/asm-x86/processor.h @@ -1,5 +1,5 @@ -#ifndef __ASM_X86_PROCESSOR_H -#define __ASM_X86_PROCESSOR_H +#ifndef ASM_X86__PROCESSOR_H +#define ASM_X86__PROCESSOR_H #include <asm/processor-flags.h> @@ -20,6 +20,7 @@ struct mm_struct; #include <asm/msr.h> #include <asm/desc_defs.h> #include <asm/nops.h> +#include <asm/ds.h> #include <linux/personality.h> #include <linux/cpumask.h> @@ -140,6 +141,8 @@ DECLARE_PER_CPU(struct cpuinfo_x86, cpu_info); #define current_cpu_data boot_cpu_data #endif +extern const struct seq_operations cpuinfo_op; + static inline int hlt_works(int cpu) { #ifdef CONFIG_X86_32 @@ -153,6 +156,8 @@ static inline int hlt_works(int cpu) extern void cpu_detect(struct cpuinfo_x86 *c); +extern struct pt_regs *idle_regs(struct pt_regs *); + extern void early_cpu_init(void); extern void identify_boot_cpu(void); extern void identify_secondary_cpu(struct cpuinfo_x86 *); @@ -411,9 +416,14 @@ struct thread_struct { unsigned io_bitmap_max; /* MSR_IA32_DEBUGCTLMSR value to switch in if TIF_DEBUGCTLMSR is set. */ unsigned long debugctlmsr; -/* Debug Store - if not 0 points to a DS Save Area configuration; - * goes into MSR_IA32_DS_AREA */ - unsigned long ds_area_msr; +#ifdef CONFIG_X86_DS +/* Debug Store context; see include/asm-x86/ds.h; goes into MSR_IA32_DS_AREA */ + struct ds_context *ds_ctx; +#endif /* CONFIG_X86_DS */ +#ifdef CONFIG_X86_PTRACE_BTS +/* the signal to send on a bts buffer overflow */ + unsigned int bts_ovfl_signal; +#endif /* CONFIG_X86_PTRACE_BTS */ }; static inline unsigned long native_get_debugreg(int regno) @@ -943,4 +953,4 @@ extern void start_thread(struct pt_regs *regs, unsigned long new_ip, extern int get_tsc_mode(unsigned long adr); extern int set_tsc_mode(unsigned int val); -#endif +#endif /* ASM_X86__PROCESSOR_H */ diff --git a/include/asm-x86/proto.h b/include/asm-x86/proto.h index 3dd458c385c..6e89e8b4de0 100644 --- a/include/asm-x86/proto.h +++ b/include/asm-x86/proto.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X8664_PROTO_H -#define _ASM_X8664_PROTO_H 1 +#ifndef ASM_X86__PROTO_H +#define ASM_X86__PROTO_H #include <asm/ldt.h> @@ -29,4 +29,4 @@ long do_arch_prctl(struct task_struct *task, int code, unsigned long addr); #define round_up(x, y) (((x) + (y) - 1) & ~((y) - 1)) #define round_down(x, y) ((x) & ~((y) - 1)) -#endif +#endif /* ASM_X86__PROTO_H */ diff --git a/include/asm-x86/ptrace-abi.h b/include/asm-x86/ptrace-abi.h index 72e7b9db29b..4298b8882a7 100644 --- a/include/asm-x86/ptrace-abi.h +++ b/include/asm-x86/ptrace-abi.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_PTRACE_ABI_H -#define _ASM_X86_PTRACE_ABI_H +#ifndef ASM_X86__PTRACE_ABI_H +#define ASM_X86__PTRACE_ABI_H #ifdef __i386__ @@ -80,8 +80,9 @@ #define PTRACE_SINGLEBLOCK 33 /* resume execution until next branch */ -#ifndef __ASSEMBLY__ +#ifdef CONFIG_X86_PTRACE_BTS +#ifndef __ASSEMBLY__ #include <asm/types.h> /* configuration/status structure used in PTRACE_BTS_CONFIG and @@ -97,20 +98,20 @@ struct ptrace_bts_config { /* actual size of bts_struct in bytes */ __u32 bts_size; }; -#endif +#endif /* __ASSEMBLY__ */ #define PTRACE_BTS_O_TRACE 0x1 /* branch trace */ #define PTRACE_BTS_O_SCHED 0x2 /* scheduling events w/ jiffies */ #define PTRACE_BTS_O_SIGNAL 0x4 /* send SIG<signal> on buffer overflow instead of wrapping around */ -#define PTRACE_BTS_O_CUT_SIZE 0x8 /* cut requested size to max available - instead of failing */ +#define PTRACE_BTS_O_ALLOC 0x8 /* (re)allocate buffer */ #define PTRACE_BTS_CONFIG 40 /* Configure branch trace recording. ADDR points to a struct ptrace_bts_config. DATA gives the size of that buffer. - A new buffer is allocated, iff the size changes. + A new buffer is allocated, if requested in the flags. + An overflow signal may only be requested for new buffers. Returns the number of bytes read. */ #define PTRACE_BTS_STATUS 41 @@ -119,7 +120,7 @@ struct ptrace_bts_config { Returns the number of bytes written. */ #define PTRACE_BTS_SIZE 42 -/* Return the number of available BTS records. +/* Return the number of available BTS records for draining. DATA and ADDR are ignored. */ #define PTRACE_BTS_GET 43 @@ -139,5 +140,6 @@ struct ptrace_bts_config { BTS records are read from oldest to newest. Returns number of BTS records drained. */ +#endif /* CONFIG_X86_PTRACE_BTS */ -#endif +#endif /* ASM_X86__PTRACE_ABI_H */ diff --git a/include/asm-x86/ptrace.h b/include/asm-x86/ptrace.h index 8a71db803da..d64a6109716 100644 --- a/include/asm-x86/ptrace.h +++ b/include/asm-x86/ptrace.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_PTRACE_H -#define _ASM_X86_PTRACE_H +#ifndef ASM_X86__PTRACE_H +#define ASM_X86__PTRACE_H #include <linux/compiler.h> /* For __user */ #include <asm/ptrace-abi.h> @@ -127,14 +127,48 @@ struct pt_regs { #endif /* __KERNEL__ */ #endif /* !__i386__ */ + +#ifdef CONFIG_X86_PTRACE_BTS +/* a branch trace record entry + * + * In order to unify the interface between various processor versions, + * we use the below data structure for all processors. + */ +enum bts_qualifier { + BTS_INVALID = 0, + BTS_BRANCH, + BTS_TASK_ARRIVES, + BTS_TASK_DEPARTS +}; + +struct bts_struct { + __u64 qualifier; + union { + /* BTS_BRANCH */ + struct { + __u64 from_ip; + __u64 to_ip; + } lbr; + /* BTS_TASK_ARRIVES or + BTS_TASK_DEPARTS */ + __u64 jiffies; + } variant; +}; +#endif /* CONFIG_X86_PTRACE_BTS */ + #ifdef __KERNEL__ -/* the DS BTS struct is used for ptrace as well */ -#include <asm/ds.h> +#include <linux/init.h> +struct cpuinfo_x86; struct task_struct; +#ifdef CONFIG_X86_PTRACE_BTS +extern void __cpuinit ptrace_bts_init_intel(struct cpuinfo_x86 *); extern void ptrace_bts_take_timestamp(struct task_struct *, enum bts_qualifier); +#else +#define ptrace_bts_init_intel(config) do {} while (0) +#endif /* CONFIG_X86_PTRACE_BTS */ extern unsigned long profile_pc(struct pt_regs *regs); @@ -148,6 +182,9 @@ extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, void signal_fault(struct pt_regs *regs, void __user *frame, char *where); #endif +extern long syscall_trace_enter(struct pt_regs *); +extern void syscall_trace_leave(struct pt_regs *); + static inline unsigned long regs_return_value(struct pt_regs *regs) { return regs->ax; @@ -213,6 +250,11 @@ static inline unsigned long frame_pointer(struct pt_regs *regs) return regs->bp; } +static inline unsigned long user_stack_pointer(struct pt_regs *regs) +{ + return regs->sp; +} + /* * These are defined as per linux/ptrace.h, which see. */ @@ -239,4 +281,4 @@ extern int do_set_thread_area(struct task_struct *p, int idx, #endif /* !__ASSEMBLY__ */ -#endif +#endif /* ASM_X86__PTRACE_H */ diff --git a/include/asm-x86/pvclock-abi.h b/include/asm-x86/pvclock-abi.h index 6857f840b24..edb3b4ecfc8 100644 --- a/include/asm-x86/pvclock-abi.h +++ b/include/asm-x86/pvclock-abi.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_PVCLOCK_ABI_H_ -#define _ASM_X86_PVCLOCK_ABI_H_ +#ifndef ASM_X86__PVCLOCK_ABI_H +#define ASM_X86__PVCLOCK_ABI_H #ifndef __ASSEMBLY__ /* @@ -39,4 +39,4 @@ struct pvclock_wall_clock { } __attribute__((__packed__)); #endif /* __ASSEMBLY__ */ -#endif /* _ASM_X86_PVCLOCK_ABI_H_ */ +#endif /* ASM_X86__PVCLOCK_ABI_H */ diff --git a/include/asm-x86/pvclock.h b/include/asm-x86/pvclock.h index 85b1bba8e0a..1a38f683480 100644 --- a/include/asm-x86/pvclock.h +++ b/include/asm-x86/pvclock.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_PVCLOCK_H_ -#define _ASM_X86_PVCLOCK_H_ +#ifndef ASM_X86__PVCLOCK_H +#define ASM_X86__PVCLOCK_H #include <linux/clocksource.h> #include <asm/pvclock-abi.h> @@ -10,4 +10,4 @@ void pvclock_read_wallclock(struct pvclock_wall_clock *wall, struct pvclock_vcpu_time_info *vcpu, struct timespec *ts); -#endif /* _ASM_X86_PVCLOCK_H_ */ +#endif /* ASM_X86__PVCLOCK_H */ diff --git a/include/asm-x86/reboot.h b/include/asm-x86/reboot.h index 206f355786d..1c2f0ce9e31 100644 --- a/include/asm-x86/reboot.h +++ b/include/asm-x86/reboot.h @@ -1,5 +1,5 @@ -#ifndef _ASM_REBOOT_H -#define _ASM_REBOOT_H +#ifndef ASM_X86__REBOOT_H +#define ASM_X86__REBOOT_H struct pt_regs; @@ -18,4 +18,4 @@ void native_machine_crash_shutdown(struct pt_regs *regs); void native_machine_shutdown(void); void machine_real_restart(const unsigned char *code, int length); -#endif /* _ASM_REBOOT_H */ +#endif /* ASM_X86__REBOOT_H */ diff --git a/include/asm-x86/reboot_fixups.h b/include/asm-x86/reboot_fixups.h index 0cb7d87c2b6..2c2987d9757 100644 --- a/include/asm-x86/reboot_fixups.h +++ b/include/asm-x86/reboot_fixups.h @@ -1,6 +1,6 @@ -#ifndef _LINUX_REBOOT_FIXUPS_H -#define _LINUX_REBOOT_FIXUPS_H +#ifndef ASM_X86__REBOOT_FIXUPS_H +#define ASM_X86__REBOOT_FIXUPS_H extern void mach_reboot_fixups(void); -#endif /* _LINUX_REBOOT_FIXUPS_H */ +#endif /* ASM_X86__REBOOT_FIXUPS_H */ diff --git a/include/asm-x86/required-features.h b/include/asm-x86/required-features.h index 5c2ff4bc298..a01c4e37633 100644 --- a/include/asm-x86/required-features.h +++ b/include/asm-x86/required-features.h @@ -1,5 +1,5 @@ -#ifndef _ASM_REQUIRED_FEATURES_H -#define _ASM_REQUIRED_FEATURES_H 1 +#ifndef ASM_X86__REQUIRED_FEATURES_H +#define ASM_X86__REQUIRED_FEATURES_H /* Define minimum CPUID feature set for kernel These bits are checked really early to actually display a visible error message before the @@ -79,4 +79,4 @@ #define REQUIRED_MASK6 0 #define REQUIRED_MASK7 0 -#endif +#endif /* ASM_X86__REQUIRED_FEATURES_H */ diff --git a/include/asm-x86/resume-trace.h b/include/asm-x86/resume-trace.h index 8d9f0b41ee8..e39376d7de5 100644 --- a/include/asm-x86/resume-trace.h +++ b/include/asm-x86/resume-trace.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_RESUME_TRACE_H -#define _ASM_X86_RESUME_TRACE_H +#ifndef ASM_X86__RESUME_TRACE_H +#define ASM_X86__RESUME_TRACE_H #include <asm/asm.h> @@ -7,7 +7,7 @@ do { \ if (pm_trace_enabled) { \ const void *tracedata; \ - asm volatile(_ASM_MOV_UL " $1f,%0\n" \ + asm volatile(_ASM_MOV " $1f,%0\n" \ ".section .tracedata,\"a\"\n" \ "1:\t.word %c1\n\t" \ _ASM_PTR " %c2\n" \ @@ -18,4 +18,4 @@ do { \ } \ } while (0) -#endif +#endif /* ASM_X86__RESUME_TRACE_H */ diff --git a/include/asm-x86/rio.h b/include/asm-x86/rio.h index c9448bd8968..5e1256bdee8 100644 --- a/include/asm-x86/rio.h +++ b/include/asm-x86/rio.h @@ -5,8 +5,8 @@ * Author: Laurent Vivier <Laurent.Vivier@bull.net> */ -#ifndef __ASM_RIO_H -#define __ASM_RIO_H +#ifndef ASM_X86__RIO_H +#define ASM_X86__RIO_H #define RIO_TABLE_VERSION 3 @@ -60,4 +60,4 @@ enum { ALT_CALGARY = 5, /* Second Planar Calgary */ }; -#endif /* __ASM_RIO_H */ +#endif /* ASM_X86__RIO_H */ diff --git a/include/asm-x86/rwlock.h b/include/asm-x86/rwlock.h index 6a8c0d64510..48a3109e1a7 100644 --- a/include/asm-x86/rwlock.h +++ b/include/asm-x86/rwlock.h @@ -1,8 +1,8 @@ -#ifndef _ASM_X86_RWLOCK_H -#define _ASM_X86_RWLOCK_H +#ifndef ASM_X86__RWLOCK_H +#define ASM_X86__RWLOCK_H #define RW_LOCK_BIAS 0x01000000 /* Actual code is in asm/spinlock.h or in arch/x86/lib/rwlock.S */ -#endif /* _ASM_X86_RWLOCK_H */ +#endif /* ASM_X86__RWLOCK_H */ diff --git a/include/asm-x86/rwsem.h b/include/asm-x86/rwsem.h index 750f2a3542b..3ff3015b71a 100644 --- a/include/asm-x86/rwsem.h +++ b/include/asm-x86/rwsem.h @@ -29,8 +29,8 @@ * front, then they'll all be woken up, but no other readers will be. */ -#ifndef _I386_RWSEM_H -#define _I386_RWSEM_H +#ifndef ASM_X86__RWSEM_H +#define ASM_X86__RWSEM_H #ifndef _LINUX_RWSEM_H #error "please don't include asm/rwsem.h directly, use linux/rwsem.h instead" @@ -262,4 +262,4 @@ static inline int rwsem_is_locked(struct rw_semaphore *sem) } #endif /* __KERNEL__ */ -#endif /* _I386_RWSEM_H */ +#endif /* ASM_X86__RWSEM_H */ diff --git a/include/asm-x86/scatterlist.h b/include/asm-x86/scatterlist.h index c0432061f81..ee48f880005 100644 --- a/include/asm-x86/scatterlist.h +++ b/include/asm-x86/scatterlist.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_SCATTERLIST_H -#define _ASM_X86_SCATTERLIST_H +#ifndef ASM_X86__SCATTERLIST_H +#define ASM_X86__SCATTERLIST_H #include <asm/types.h> @@ -30,4 +30,4 @@ struct scatterlist { # define sg_dma_len(sg) ((sg)->dma_length) #endif -#endif +#endif /* ASM_X86__SCATTERLIST_H */ diff --git a/include/asm-x86/seccomp_32.h b/include/asm-x86/seccomp_32.h index 36e71c5f306..cf9ab2dbcef 100644 --- a/include/asm-x86/seccomp_32.h +++ b/include/asm-x86/seccomp_32.h @@ -1,5 +1,5 @@ -#ifndef _ASM_SECCOMP_H -#define _ASM_SECCOMP_H +#ifndef ASM_X86__SECCOMP_32_H +#define ASM_X86__SECCOMP_32_H #include <linux/thread_info.h> @@ -14,4 +14,4 @@ #define __NR_seccomp_exit __NR_exit #define __NR_seccomp_sigreturn __NR_sigreturn -#endif /* _ASM_SECCOMP_H */ +#endif /* ASM_X86__SECCOMP_32_H */ diff --git a/include/asm-x86/seccomp_64.h b/include/asm-x86/seccomp_64.h index 76cfe69aa63..03274cea751 100644 --- a/include/asm-x86/seccomp_64.h +++ b/include/asm-x86/seccomp_64.h @@ -1,5 +1,5 @@ -#ifndef _ASM_SECCOMP_H -#define _ASM_SECCOMP_H +#ifndef ASM_X86__SECCOMP_64_H +#define ASM_X86__SECCOMP_64_H #include <linux/thread_info.h> @@ -22,4 +22,4 @@ #define __NR_seccomp_exit_32 __NR_ia32_exit #define __NR_seccomp_sigreturn_32 __NR_ia32_sigreturn -#endif /* _ASM_SECCOMP_H */ +#endif /* ASM_X86__SECCOMP_64_H */ diff --git a/include/asm-x86/segment.h b/include/asm-x86/segment.h index 646452ea9ea..ea5f0a8686f 100644 --- a/include/asm-x86/segment.h +++ b/include/asm-x86/segment.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_SEGMENT_H_ -#define _ASM_X86_SEGMENT_H_ +#ifndef ASM_X86__SEGMENT_H +#define ASM_X86__SEGMENT_H /* Constructor for a conventional segment GDT (or LDT) entry */ /* This is a macro so it can be used in initializers */ @@ -212,4 +212,4 @@ extern const char early_idt_handlers[NUM_EXCEPTION_VECTORS][10]; #endif #endif -#endif +#endif /* ASM_X86__SEGMENT_H */ diff --git a/include/asm-x86/sembuf.h b/include/asm-x86/sembuf.h index ee50c801f7b..81f06b7e5a3 100644 --- a/include/asm-x86/sembuf.h +++ b/include/asm-x86/sembuf.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_SEMBUF_H -#define _ASM_X86_SEMBUF_H +#ifndef ASM_X86__SEMBUF_H +#define ASM_X86__SEMBUF_H /* * The semid64_ds structure for x86 architecture. @@ -21,4 +21,4 @@ struct semid64_ds { unsigned long __unused4; }; -#endif /* _ASM_X86_SEMBUF_H */ +#endif /* ASM_X86__SEMBUF_H */ diff --git a/include/asm-x86/serial.h b/include/asm-x86/serial.h index 628c801535e..303660b671e 100644 --- a/include/asm-x86/serial.h +++ b/include/asm-x86/serial.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_SERIAL_H -#define _ASM_X86_SERIAL_H +#ifndef ASM_X86__SERIAL_H +#define ASM_X86__SERIAL_H /* * This assumes you have a 1.8432 MHz clock for your UART. @@ -26,4 +26,4 @@ { 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS }, /* ttyS2 */ \ { 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS }, /* ttyS3 */ -#endif /* _ASM_X86_SERIAL_H */ +#endif /* ASM_X86__SERIAL_H */ diff --git a/include/asm-x86/setup.h b/include/asm-x86/setup.h index a07c6f1c01e..9030cb73c4d 100644 --- a/include/asm-x86/setup.h +++ b/include/asm-x86/setup.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_SETUP_H -#define _ASM_X86_SETUP_H +#ifndef ASM_X86__SETUP_H +#define ASM_X86__SETUP_H #define COMMAND_LINE_SIZE 2048 @@ -41,6 +41,7 @@ struct x86_quirks { }; extern struct x86_quirks *x86_quirks; +extern unsigned long saved_video_mode; #ifndef CONFIG_PARAVIRT #define paravirt_post_allocator_init() do {} while (0) @@ -100,4 +101,4 @@ void __init x86_64_start_reservations(char *real_mode_data); #endif /* __ASSEMBLY__ */ #endif /* __KERNEL__ */ -#endif /* _ASM_X86_SETUP_H */ +#endif /* ASM_X86__SETUP_H */ diff --git a/include/asm-x86/shmbuf.h b/include/asm-x86/shmbuf.h index b51413b7497..f51aec2298e 100644 --- a/include/asm-x86/shmbuf.h +++ b/include/asm-x86/shmbuf.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_SHMBUF_H -#define _ASM_X86_SHMBUF_H +#ifndef ASM_X86__SHMBUF_H +#define ASM_X86__SHMBUF_H /* * The shmid64_ds structure for x86 architecture. @@ -48,4 +48,4 @@ struct shminfo64 { unsigned long __unused4; }; -#endif /* _ASM_X86_SHMBUF_H */ +#endif /* ASM_X86__SHMBUF_H */ diff --git a/include/asm-x86/shmparam.h b/include/asm-x86/shmparam.h index 0880cf0917b..a83a1fd96a0 100644 --- a/include/asm-x86/shmparam.h +++ b/include/asm-x86/shmparam.h @@ -1,6 +1,6 @@ -#ifndef _ASM_X86_SHMPARAM_H -#define _ASM_X86_SHMPARAM_H +#ifndef ASM_X86__SHMPARAM_H +#define ASM_X86__SHMPARAM_H #define SHMLBA PAGE_SIZE /* attach addr a multiple of this */ -#endif /* _ASM_X86_SHMPARAM_H */ +#endif /* ASM_X86__SHMPARAM_H */ diff --git a/include/asm-x86/sigcontext.h b/include/asm-x86/sigcontext.h index 2f9c884d2c0..24879c85b29 100644 --- a/include/asm-x86/sigcontext.h +++ b/include/asm-x86/sigcontext.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_SIGCONTEXT_H -#define _ASM_X86_SIGCONTEXT_H +#ifndef ASM_X86__SIGCONTEXT_H +#define ASM_X86__SIGCONTEXT_H #include <linux/compiler.h> #include <asm/types.h> @@ -202,4 +202,4 @@ struct sigcontext { #endif /* !__i386__ */ -#endif +#endif /* ASM_X86__SIGCONTEXT_H */ diff --git a/include/asm-x86/sigcontext32.h b/include/asm-x86/sigcontext32.h index 57a9686fb49..4e2ec732dd0 100644 --- a/include/asm-x86/sigcontext32.h +++ b/include/asm-x86/sigcontext32.h @@ -1,5 +1,5 @@ -#ifndef _SIGCONTEXT32_H -#define _SIGCONTEXT32_H 1 +#ifndef ASM_X86__SIGCONTEXT32_H +#define ASM_X86__SIGCONTEXT32_H /* signal context for 32bit programs. */ @@ -68,4 +68,4 @@ struct sigcontext_ia32 { unsigned int cr2; }; -#endif +#endif /* ASM_X86__SIGCONTEXT32_H */ diff --git a/include/asm-x86/siginfo.h b/include/asm-x86/siginfo.h index a477bea0c2a..808bdfb2958 100644 --- a/include/asm-x86/siginfo.h +++ b/include/asm-x86/siginfo.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_SIGINFO_H -#define _ASM_X86_SIGINFO_H +#ifndef ASM_X86__SIGINFO_H +#define ASM_X86__SIGINFO_H #ifdef __x86_64__ # define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int)) @@ -7,4 +7,4 @@ #include <asm-generic/siginfo.h> -#endif +#endif /* ASM_X86__SIGINFO_H */ diff --git a/include/asm-x86/signal.h b/include/asm-x86/signal.h index 6dac49364e9..65acc82d267 100644 --- a/include/asm-x86/signal.h +++ b/include/asm-x86/signal.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_SIGNAL_H -#define _ASM_X86_SIGNAL_H +#ifndef ASM_X86__SIGNAL_H +#define ASM_X86__SIGNAL_H #ifndef __ASSEMBLY__ #include <linux/types.h> @@ -140,6 +140,9 @@ struct sigaction { struct k_sigaction { struct sigaction sa; }; + +extern void do_notify_resume(struct pt_regs *, void *, __u32); + # else /* __KERNEL__ */ /* Here we must cater to libcs that poke about in kernel headers. */ @@ -256,4 +259,4 @@ struct pt_regs; #endif /* __KERNEL__ */ #endif /* __ASSEMBLY__ */ -#endif +#endif /* ASM_X86__SIGNAL_H */ diff --git a/include/asm-x86/smp.h b/include/asm-x86/smp.h index 3c877f74f27..04f84f4e2c8 100644 --- a/include/asm-x86/smp.h +++ b/include/asm-x86/smp.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_SMP_H_ -#define _ASM_X86_SMP_H_ +#ifndef ASM_X86__SMP_H +#define ASM_X86__SMP_H #ifndef __ASSEMBLY__ #include <linux/cpumask.h> #include <linux/init.h> @@ -34,6 +34,9 @@ extern cpumask_t cpu_initialized; DECLARE_PER_CPU(cpumask_t, cpu_sibling_map); DECLARE_PER_CPU(cpumask_t, cpu_core_map); DECLARE_PER_CPU(u16, cpu_llc_id); +#ifdef CONFIG_X86_32 +DECLARE_PER_CPU(int, cpu_number); +#endif DECLARE_EARLY_PER_CPU(u16, x86_cpu_to_apicid); DECLARE_EARLY_PER_CPU(u16, x86_bios_cpu_apicid); @@ -142,7 +145,6 @@ extern unsigned disabled_cpus __cpuinitdata; * from the initial startup. We map APIC_BASE very early in page_setup(), * so this is correct in the x86 case. */ -DECLARE_PER_CPU(int, cpu_number); #define raw_smp_processor_id() (x86_read_percpu(cpu_number)) extern int safe_smp_processor_id(void); @@ -205,4 +207,4 @@ extern void cpu_uninit(void); #endif #endif /* __ASSEMBLY__ */ -#endif +#endif /* ASM_X86__SMP_H */ diff --git a/include/asm-x86/socket.h b/include/asm-x86/socket.h index 80af9c4ccad..db73274c83c 100644 --- a/include/asm-x86/socket.h +++ b/include/asm-x86/socket.h @@ -1,5 +1,5 @@ -#ifndef _ASM_SOCKET_H -#define _ASM_SOCKET_H +#ifndef ASM_X86__SOCKET_H +#define ASM_X86__SOCKET_H #include <asm/sockios.h> @@ -54,4 +54,4 @@ #define SO_MARK 36 -#endif /* _ASM_SOCKET_H */ +#endif /* ASM_X86__SOCKET_H */ diff --git a/include/asm-x86/sockios.h b/include/asm-x86/sockios.h index 49cc72b5d3c..a006704fdc8 100644 --- a/include/asm-x86/sockios.h +++ b/include/asm-x86/sockios.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_SOCKIOS_H -#define _ASM_X86_SOCKIOS_H +#ifndef ASM_X86__SOCKIOS_H +#define ASM_X86__SOCKIOS_H /* Socket-level I/O control calls. */ #define FIOSETOWN 0x8901 @@ -10,4 +10,4 @@ #define SIOCGSTAMP 0x8906 /* Get stamp (timeval) */ #define SIOCGSTAMPNS 0x8907 /* Get stamp (timespec) */ -#endif /* _ASM_X86_SOCKIOS_H */ +#endif /* ASM_X86__SOCKIOS_H */ diff --git a/include/asm-x86/sparsemem.h b/include/asm-x86/sparsemem.h index 9bd48b0a534..38f8e6bc318 100644 --- a/include/asm-x86/sparsemem.h +++ b/include/asm-x86/sparsemem.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_SPARSEMEM_H -#define _ASM_X86_SPARSEMEM_H +#ifndef ASM_X86__SPARSEMEM_H +#define ASM_X86__SPARSEMEM_H #ifdef CONFIG_SPARSEMEM /* @@ -31,4 +31,4 @@ #endif #endif /* CONFIG_SPARSEMEM */ -#endif +#endif /* ASM_X86__SPARSEMEM_H */ diff --git a/include/asm-x86/spinlock.h b/include/asm-x86/spinlock.h index e39c790dbfd..93adae338ac 100644 --- a/include/asm-x86/spinlock.h +++ b/include/asm-x86/spinlock.h @@ -1,5 +1,5 @@ -#ifndef _X86_SPINLOCK_H_ -#define _X86_SPINLOCK_H_ +#ifndef ASM_X86__SPINLOCK_H +#define ASM_X86__SPINLOCK_H #include <asm/atomic.h> #include <asm/rwlock.h> @@ -97,7 +97,7 @@ static __always_inline int __ticket_spin_trylock(raw_spinlock_t *lock) "jne 1f\n\t" "movw %w0,%w1\n\t" "incb %h1\n\t" - "lock ; cmpxchgw %w1,%2\n\t" + LOCK_PREFIX "cmpxchgw %w1,%2\n\t" "1:" "sete %b1\n\t" "movzbl %b1,%0\n\t" @@ -135,7 +135,7 @@ static __always_inline void __ticket_spin_lock(raw_spinlock_t *lock) int inc = 0x00010000; int tmp; - asm volatile("lock ; xaddl %0, %1\n" + asm volatile(LOCK_PREFIX "xaddl %0, %1\n" "movzwl %w0, %2\n\t" "shrl $16, %0\n\t" "1:\t" @@ -162,7 +162,7 @@ static __always_inline int __ticket_spin_trylock(raw_spinlock_t *lock) "cmpl %0,%1\n\t" "jne 1f\n\t" "addl $0x00010000, %1\n\t" - "lock ; cmpxchgl %1,%2\n\t" + LOCK_PREFIX "cmpxchgl %1,%2\n\t" "1:" "sete %b1\n\t" "movzbl %b1,%0\n\t" @@ -366,4 +366,4 @@ static inline void __raw_write_unlock(raw_rwlock_t *rw) #define _raw_read_relax(lock) cpu_relax() #define _raw_write_relax(lock) cpu_relax() -#endif +#endif /* ASM_X86__SPINLOCK_H */ diff --git a/include/asm-x86/spinlock_types.h b/include/asm-x86/spinlock_types.h index 06c071c9eee..6aa9b562c50 100644 --- a/include/asm-x86/spinlock_types.h +++ b/include/asm-x86/spinlock_types.h @@ -1,5 +1,5 @@ -#ifndef __ASM_SPINLOCK_TYPES_H -#define __ASM_SPINLOCK_TYPES_H +#ifndef ASM_X86__SPINLOCK_TYPES_H +#define ASM_X86__SPINLOCK_TYPES_H #ifndef __LINUX_SPINLOCK_TYPES_H # error "please don't include this file directly" @@ -17,4 +17,4 @@ typedef struct { #define __RAW_RW_LOCK_UNLOCKED { RW_LOCK_BIAS } -#endif +#endif /* ASM_X86__SPINLOCK_TYPES_H */ diff --git a/include/asm-x86/srat.h b/include/asm-x86/srat.h index 774c919dc23..5363e4f7e1c 100644 --- a/include/asm-x86/srat.h +++ b/include/asm-x86/srat.h @@ -24,8 +24,8 @@ * Send feedback to Pat Gaughen <gone@us.ibm.com> */ -#ifndef _ASM_SRAT_H_ -#define _ASM_SRAT_H_ +#ifndef ASM_X86__SRAT_H +#define ASM_X86__SRAT_H #ifdef CONFIG_ACPI_NUMA extern int get_memcfg_from_srat(void); @@ -36,4 +36,4 @@ static inline int get_memcfg_from_srat(void) } #endif -#endif /* _ASM_SRAT_H_ */ +#endif /* ASM_X86__SRAT_H */ diff --git a/include/asm-x86/stacktrace.h b/include/asm-x86/stacktrace.h index 30f82526a8e..f43517e2853 100644 --- a/include/asm-x86/stacktrace.h +++ b/include/asm-x86/stacktrace.h @@ -1,5 +1,5 @@ -#ifndef _ASM_STACKTRACE_H -#define _ASM_STACKTRACE_H 1 +#ifndef ASM_X86__STACKTRACE_H +#define ASM_X86__STACKTRACE_H extern int kstack_depth_to_print; @@ -18,4 +18,4 @@ void dump_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long *stack, unsigned long bp, const struct stacktrace_ops *ops, void *data); -#endif +#endif /* ASM_X86__STACKTRACE_H */ diff --git a/include/asm-x86/stat.h b/include/asm-x86/stat.h index 5c22dcb5d17..1e120f62890 100644 --- a/include/asm-x86/stat.h +++ b/include/asm-x86/stat.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_STAT_H -#define _ASM_X86_STAT_H +#ifndef ASM_X86__STAT_H +#define ASM_X86__STAT_H #define STAT_HAVE_NSEC 1 @@ -111,4 +111,4 @@ struct __old_kernel_stat { #endif }; -#endif +#endif /* ASM_X86__STAT_H */ diff --git a/include/asm-x86/statfs.h b/include/asm-x86/statfs.h index 7c651aa9725..3f005bc3aa5 100644 --- a/include/asm-x86/statfs.h +++ b/include/asm-x86/statfs.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_STATFS_H -#define _ASM_X86_STATFS_H +#ifndef ASM_X86__STATFS_H +#define ASM_X86__STATFS_H #ifdef __i386__ #include <asm-generic/statfs.h> @@ -60,4 +60,4 @@ struct compat_statfs64 { } __attribute__((packed)); #endif /* !__i386__ */ -#endif +#endif /* ASM_X86__STATFS_H */ diff --git a/include/asm-x86/string_32.h b/include/asm-x86/string_32.h index 193578cd1fd..487843ed245 100644 --- a/include/asm-x86/string_32.h +++ b/include/asm-x86/string_32.h @@ -1,5 +1,5 @@ -#ifndef _I386_STRING_H_ -#define _I386_STRING_H_ +#ifndef ASM_X86__STRING_32_H +#define ASM_X86__STRING_32_H #ifdef __KERNEL__ @@ -323,4 +323,4 @@ extern void *memscan(void *addr, int c, size_t size); #endif /* __KERNEL__ */ -#endif +#endif /* ASM_X86__STRING_32_H */ diff --git a/include/asm-x86/string_64.h b/include/asm-x86/string_64.h index 52b5ab38339..a2add11d3b6 100644 --- a/include/asm-x86/string_64.h +++ b/include/asm-x86/string_64.h @@ -1,5 +1,5 @@ -#ifndef _X86_64_STRING_H_ -#define _X86_64_STRING_H_ +#ifndef ASM_X86__STRING_64_H +#define ASM_X86__STRING_64_H #ifdef __KERNEL__ @@ -57,4 +57,4 @@ int strcmp(const char *cs, const char *ct); #endif /* __KERNEL__ */ -#endif +#endif /* ASM_X86__STRING_64_H */ diff --git a/include/asm-x86/suspend_32.h b/include/asm-x86/suspend_32.h index 8675c6782a7..acb6d4d491f 100644 --- a/include/asm-x86/suspend_32.h +++ b/include/asm-x86/suspend_32.h @@ -3,8 +3,8 @@ * Based on code * Copyright 2001 Patrick Mochel <mochel@osdl.org> */ -#ifndef __ASM_X86_32_SUSPEND_H -#define __ASM_X86_32_SUSPEND_H +#ifndef ASM_X86__SUSPEND_32_H +#define ASM_X86__SUSPEND_32_H #include <asm/desc.h> #include <asm/i387.h> @@ -48,4 +48,4 @@ static inline void acpi_save_register_state(unsigned long return_point) extern int acpi_save_state_mem(void); #endif -#endif /* __ASM_X86_32_SUSPEND_H */ +#endif /* ASM_X86__SUSPEND_32_H */ diff --git a/include/asm-x86/suspend_64.h b/include/asm-x86/suspend_64.h index dc3262b4307..cf821dd310e 100644 --- a/include/asm-x86/suspend_64.h +++ b/include/asm-x86/suspend_64.h @@ -3,8 +3,8 @@ * Based on code * Copyright 2001 Patrick Mochel <mochel@osdl.org> */ -#ifndef __ASM_X86_64_SUSPEND_H -#define __ASM_X86_64_SUSPEND_H +#ifndef ASM_X86__SUSPEND_64_H +#define ASM_X86__SUSPEND_64_H #include <asm/desc.h> #include <asm/i387.h> @@ -49,4 +49,4 @@ extern int acpi_save_state_mem(void); extern char core_restore_code; extern char restore_registers; -#endif /* __ASM_X86_64_SUSPEND_H */ +#endif /* ASM_X86__SUSPEND_64_H */ diff --git a/include/asm-x86/swiotlb.h b/include/asm-x86/swiotlb.h index 2730b351afc..1e20adbcad4 100644 --- a/include/asm-x86/swiotlb.h +++ b/include/asm-x86/swiotlb.h @@ -1,5 +1,5 @@ -#ifndef _ASM_SWIOTLB_H -#define _ASM_SWIOTLB_H 1 +#ifndef ASM_X86__SWIOTLB_H +#define ASM_X86__SWIOTLB_H #include <asm/dma-mapping.h> @@ -55,4 +55,4 @@ static inline void pci_swiotlb_init(void) static inline void dma_mark_clean(void *addr, size_t size) {} -#endif /* _ASM_SWIOTLB_H */ +#endif /* ASM_X86__SWIOTLB_H */ diff --git a/include/asm-x86/sync_bitops.h b/include/asm-x86/sync_bitops.h index b47a1d0b8a8..b689bee7110 100644 --- a/include/asm-x86/sync_bitops.h +++ b/include/asm-x86/sync_bitops.h @@ -1,5 +1,5 @@ -#ifndef _I386_SYNC_BITOPS_H -#define _I386_SYNC_BITOPS_H +#ifndef ASM_X86__SYNC_BITOPS_H +#define ASM_X86__SYNC_BITOPS_H /* * Copyright 1992, Linus Torvalds. @@ -127,4 +127,4 @@ static inline int sync_test_and_change_bit(int nr, volatile unsigned long *addr) #undef ADDR -#endif /* _I386_SYNC_BITOPS_H */ +#endif /* ASM_X86__SYNC_BITOPS_H */ diff --git a/include/asm-x86/syscall.h b/include/asm-x86/syscall.h new file mode 100644 index 00000000000..04c47dc5597 --- /dev/null +++ b/include/asm-x86/syscall.h @@ -0,0 +1,211 @@ +/* + * Access to user system call parameters and results + * + * Copyright (C) 2008 Red Hat, Inc. All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU General Public License v.2. + * + * See asm-generic/syscall.h for descriptions of what we must do here. + */ + +#ifndef _ASM_SYSCALL_H +#define _ASM_SYSCALL_H 1 + +#include <linux/sched.h> +#include <linux/err.h> + +static inline long syscall_get_nr(struct task_struct *task, + struct pt_regs *regs) +{ + /* + * We always sign-extend a -1 value being set here, + * so this is always either -1L or a syscall number. + */ + return regs->orig_ax; +} + +static inline void syscall_rollback(struct task_struct *task, + struct pt_regs *regs) +{ + regs->ax = regs->orig_ax; +} + +static inline long syscall_get_error(struct task_struct *task, + struct pt_regs *regs) +{ + unsigned long error = regs->ax; +#ifdef CONFIG_IA32_EMULATION + /* + * TS_COMPAT is set for 32-bit syscall entries and then + * remains set until we return to user mode. + */ + if (task_thread_info(task)->status & TS_COMPAT) + /* + * Sign-extend the value so (int)-EFOO becomes (long)-EFOO + * and will match correctly in comparisons. + */ + error = (long) (int) error; +#endif + return IS_ERR_VALUE(error) ? error : 0; +} + +static inline long syscall_get_return_value(struct task_struct *task, + struct pt_regs *regs) +{ + return regs->ax; +} + +static inline void syscall_set_return_value(struct task_struct *task, + struct pt_regs *regs, + int error, long val) +{ + regs->ax = (long) error ?: val; +} + +#ifdef CONFIG_X86_32 + +static inline void syscall_get_arguments(struct task_struct *task, + struct pt_regs *regs, + unsigned int i, unsigned int n, + unsigned long *args) +{ + BUG_ON(i + n > 6); + memcpy(args, ®s->bx + i, n * sizeof(args[0])); +} + +static inline void syscall_set_arguments(struct task_struct *task, + struct pt_regs *regs, + unsigned int i, unsigned int n, + const unsigned long *args) +{ + BUG_ON(i + n > 6); + memcpy(®s->bx + i, args, n * sizeof(args[0])); +} + +#else /* CONFIG_X86_64 */ + +static inline void syscall_get_arguments(struct task_struct *task, + struct pt_regs *regs, + unsigned int i, unsigned int n, + unsigned long *args) +{ +# ifdef CONFIG_IA32_EMULATION + if (task_thread_info(task)->status & TS_COMPAT) + switch (i + n) { + case 6: + if (!n--) break; + *args++ = regs->bp; + case 5: + if (!n--) break; + *args++ = regs->di; + case 4: + if (!n--) break; + *args++ = regs->si; + case 3: + if (!n--) break; + *args++ = regs->dx; + case 2: + if (!n--) break; + *args++ = regs->cx; + case 1: + if (!n--) break; + *args++ = regs->bx; + case 0: + if (!n--) break; + default: + BUG(); + break; + } + else +# endif + switch (i + n) { + case 6: + if (!n--) break; + *args++ = regs->r9; + case 5: + if (!n--) break; + *args++ = regs->r8; + case 4: + if (!n--) break; + *args++ = regs->r10; + case 3: + if (!n--) break; + *args++ = regs->dx; + case 2: + if (!n--) break; + *args++ = regs->si; + case 1: + if (!n--) break; + *args++ = regs->di; + case 0: + if (!n--) break; + default: + BUG(); + break; + } +} + +static inline void syscall_set_arguments(struct task_struct *task, + struct pt_regs *regs, + unsigned int i, unsigned int n, + const unsigned long *args) +{ +# ifdef CONFIG_IA32_EMULATION + if (task_thread_info(task)->status & TS_COMPAT) + switch (i + n) { + case 6: + if (!n--) break; + regs->bp = *args++; + case 5: + if (!n--) break; + regs->di = *args++; + case 4: + if (!n--) break; + regs->si = *args++; + case 3: + if (!n--) break; + regs->dx = *args++; + case 2: + if (!n--) break; + regs->cx = *args++; + case 1: + if (!n--) break; + regs->bx = *args++; + case 0: + if (!n--) break; + default: + BUG(); + } + else +# endif + switch (i + n) { + case 6: + if (!n--) break; + regs->r9 = *args++; + case 5: + if (!n--) break; + regs->r8 = *args++; + case 4: + if (!n--) break; + regs->r10 = *args++; + case 3: + if (!n--) break; + regs->dx = *args++; + case 2: + if (!n--) break; + regs->si = *args++; + case 1: + if (!n--) break; + regs->di = *args++; + case 0: + if (!n--) break; + default: + BUG(); + } +} + +#endif /* CONFIG_X86_32 */ + +#endif /* _ASM_SYSCALL_H */ diff --git a/include/asm-x86/syscalls.h b/include/asm-x86/syscalls.h new file mode 100644 index 00000000000..87803da4401 --- /dev/null +++ b/include/asm-x86/syscalls.h @@ -0,0 +1,93 @@ +/* + * syscalls.h - Linux syscall interfaces (arch-specific) + * + * Copyright (c) 2008 Jaswinder Singh + * + * This file is released under the GPLv2. + * See the file COPYING for more details. + */ + +#ifndef _ASM_X86_SYSCALLS_H +#define _ASM_X86_SYSCALLS_H + +#include <linux/compiler.h> +#include <linux/linkage.h> +#include <linux/types.h> +#include <linux/signal.h> + +/* Common in X86_32 and X86_64 */ +/* kernel/ioport.c */ +asmlinkage long sys_ioperm(unsigned long, unsigned long, int); + +/* X86_32 only */ +#ifdef CONFIG_X86_32 +/* kernel/process_32.c */ +asmlinkage int sys_fork(struct pt_regs); +asmlinkage int sys_clone(struct pt_regs); +asmlinkage int sys_vfork(struct pt_regs); +asmlinkage int sys_execve(struct pt_regs); + +/* kernel/signal_32.c */ +asmlinkage int sys_sigsuspend(int, int, old_sigset_t); +asmlinkage int sys_sigaction(int, const struct old_sigaction __user *, + struct old_sigaction __user *); +asmlinkage int sys_sigaltstack(unsigned long); +asmlinkage unsigned long sys_sigreturn(unsigned long); +asmlinkage int sys_rt_sigreturn(unsigned long); + +/* kernel/ioport.c */ +asmlinkage long sys_iopl(unsigned long); + +/* kernel/ldt.c */ +asmlinkage int sys_modify_ldt(int, void __user *, unsigned long); + +/* kernel/sys_i386_32.c */ +asmlinkage long sys_mmap2(unsigned long, unsigned long, unsigned long, + unsigned long, unsigned long, unsigned long); +struct mmap_arg_struct; +asmlinkage int old_mmap(struct mmap_arg_struct __user *); +struct sel_arg_struct; +asmlinkage int old_select(struct sel_arg_struct __user *); +asmlinkage int sys_ipc(uint, int, int, int, void __user *, long); +struct old_utsname; +asmlinkage int sys_uname(struct old_utsname __user *); +struct oldold_utsname; +asmlinkage int sys_olduname(struct oldold_utsname __user *); + +/* kernel/tls.c */ +asmlinkage int sys_set_thread_area(struct user_desc __user *); +asmlinkage int sys_get_thread_area(struct user_desc __user *); + +/* kernel/vm86_32.c */ +asmlinkage int sys_vm86old(struct pt_regs); +asmlinkage int sys_vm86(struct pt_regs); + +#else /* CONFIG_X86_32 */ + +/* X86_64 only */ +/* kernel/process_64.c */ +asmlinkage long sys_fork(struct pt_regs *); +asmlinkage long sys_clone(unsigned long, unsigned long, + void __user *, void __user *, + struct pt_regs *); +asmlinkage long sys_vfork(struct pt_regs *); +asmlinkage long sys_execve(char __user *, char __user * __user *, + char __user * __user *, + struct pt_regs *); + +/* kernel/ioport.c */ +asmlinkage long sys_iopl(unsigned int, struct pt_regs *); + +/* kernel/signal_64.c */ +asmlinkage long sys_sigaltstack(const stack_t __user *, stack_t __user *, + struct pt_regs *); +asmlinkage long sys_rt_sigreturn(struct pt_regs *); + +/* kernel/sys_x86_64.c */ +asmlinkage long sys_mmap(unsigned long, unsigned long, unsigned long, + unsigned long, unsigned long, unsigned long); +struct new_utsname; +asmlinkage long sys_uname(struct new_utsname __user *); + +#endif /* CONFIG_X86_32 */ +#endif /* _ASM_X86_SYSCALLS_H */ diff --git a/include/asm-x86/system.h b/include/asm-x86/system.h index 983ce37c491..34505dd7b24 100644 --- a/include/asm-x86/system.h +++ b/include/asm-x86/system.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_SYSTEM_H_ -#define _ASM_X86_SYSTEM_H_ +#ifndef ASM_X86__SYSTEM_H +#define ASM_X86__SYSTEM_H #include <asm/asm.h> #include <asm/segment.h> @@ -419,4 +419,4 @@ static inline void rdtsc_barrier(void) alternative(ASM_NOP3, "lfence", X86_FEATURE_LFENCE_RDTSC); } -#endif +#endif /* ASM_X86__SYSTEM_H */ diff --git a/include/asm-x86/system_64.h b/include/asm-x86/system_64.h index 97fa251ccb2..5aedb8bffc5 100644 --- a/include/asm-x86/system_64.h +++ b/include/asm-x86/system_64.h @@ -1,5 +1,5 @@ -#ifndef __ASM_SYSTEM_H -#define __ASM_SYSTEM_H +#ifndef ASM_X86__SYSTEM_64_H +#define ASM_X86__SYSTEM_64_H #include <asm/segment.h> #include <asm/cmpxchg.h> @@ -19,4 +19,4 @@ static inline void write_cr8(unsigned long val) #include <linux/irqflags.h> -#endif +#endif /* ASM_X86__SYSTEM_64_H */ diff --git a/include/asm-x86/tce.h b/include/asm-x86/tce.h index b1a4ea00df7..e7932d7fbba 100644 --- a/include/asm-x86/tce.h +++ b/include/asm-x86/tce.h @@ -21,8 +21,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _ASM_X86_64_TCE_H -#define _ASM_X86_64_TCE_H +#ifndef ASM_X86__TCE_H +#define ASM_X86__TCE_H extern unsigned int specified_table_size; struct iommu_table; @@ -45,4 +45,4 @@ extern void * __init alloc_tce_table(void); extern void __init free_tce_table(void *tbl); extern int __init build_tce_table(struct pci_dev *dev, void __iomem *bbar); -#endif /* _ASM_X86_64_TCE_H */ +#endif /* ASM_X86__TCE_H */ diff --git a/include/asm-x86/termbits.h b/include/asm-x86/termbits.h index af1b70ea440..3d00dc5e0c7 100644 --- a/include/asm-x86/termbits.h +++ b/include/asm-x86/termbits.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_TERMBITS_H -#define _ASM_X86_TERMBITS_H +#ifndef ASM_X86__TERMBITS_H +#define ASM_X86__TERMBITS_H #include <linux/posix_types.h> @@ -195,4 +195,4 @@ struct ktermios { #define TCSADRAIN 1 #define TCSAFLUSH 2 -#endif /* _ASM_X86_TERMBITS_H */ +#endif /* ASM_X86__TERMBITS_H */ diff --git a/include/asm-x86/termios.h b/include/asm-x86/termios.h index f72956331c4..e235db24807 100644 --- a/include/asm-x86/termios.h +++ b/include/asm-x86/termios.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_TERMIOS_H -#define _ASM_X86_TERMIOS_H +#ifndef ASM_X86__TERMIOS_H +#define ASM_X86__TERMIOS_H #include <asm/termbits.h> #include <asm/ioctls.h> @@ -110,4 +110,4 @@ static inline int kernel_termios_to_user_termios_1(struct termios __user *u, #endif /* __KERNEL__ */ -#endif /* _ASM_X86_TERMIOS_H */ +#endif /* ASM_X86__TERMIOS_H */ diff --git a/include/asm-x86/therm_throt.h b/include/asm-x86/therm_throt.h index 399bf6026b1..1c7f57b6b66 100644 --- a/include/asm-x86/therm_throt.h +++ b/include/asm-x86/therm_throt.h @@ -1,9 +1,9 @@ -#ifndef __ASM_I386_THERM_THROT_H__ -#define __ASM_I386_THERM_THROT_H__ 1 +#ifndef ASM_X86__THERM_THROT_H +#define ASM_X86__THERM_THROT_H #include <asm/atomic.h> extern atomic_t therm_throt_en; int therm_throt_process(int curr); -#endif /* __ASM_I386_THERM_THROT_H__ */ +#endif /* ASM_X86__THERM_THROT_H */ diff --git a/include/asm-x86/thread_info.h b/include/asm-x86/thread_info.h index da0a675adf9..4db0066a3a3 100644 --- a/include/asm-x86/thread_info.h +++ b/include/asm-x86/thread_info.h @@ -4,8 +4,8 @@ * - Incorporating suggestions made by Linus Torvalds and Dave Miller */ -#ifndef _ASM_X86_THREAD_INFO_H -#define _ASM_X86_THREAD_INFO_H +#ifndef ASM_X86__THREAD_INFO_H +#define ASM_X86__THREAD_INFO_H #include <linux/compiler.h> #include <asm/page.h> @@ -71,6 +71,7 @@ struct thread_info { * Warning: layout of LSW is hardcoded in entry.S */ #define TIF_SYSCALL_TRACE 0 /* syscall trace active */ +#define TIF_NOTIFY_RESUME 1 /* callback before returning to user */ #define TIF_SIGPENDING 2 /* signal pending */ #define TIF_NEED_RESCHED 3 /* rescheduling necessary */ #define TIF_SINGLESTEP 4 /* reenable singlestep on user return*/ @@ -93,6 +94,7 @@ struct thread_info { #define TIF_BTS_TRACE_TS 27 /* record scheduling event timestamps */ #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) +#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) #define _TIF_SIGPENDING (1 << TIF_SIGPENDING) #define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP) #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) @@ -133,7 +135,7 @@ struct thread_info { /* Only used for 64 bit */ #define _TIF_DO_NOTIFY_MASK \ - (_TIF_SIGPENDING|_TIF_MCE_NOTIFY) + (_TIF_SIGPENDING|_TIF_MCE_NOTIFY|_TIF_NOTIFY_RESUME) /* flags to check in __switch_to() */ #define _TIF_WORK_CTXSW \ @@ -258,4 +260,4 @@ extern void free_thread_info(struct thread_info *ti); extern int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src); #define arch_task_cache_init arch_task_cache_init #endif -#endif /* _ASM_X86_THREAD_INFO_H */ +#endif /* ASM_X86__THREAD_INFO_H */ diff --git a/include/asm-x86/time.h b/include/asm-x86/time.h index a17fa473e91..3e724eef7ac 100644 --- a/include/asm-x86/time.h +++ b/include/asm-x86/time.h @@ -1,5 +1,5 @@ -#ifndef _ASMX86_TIME_H -#define _ASMX86_TIME_H +#ifndef ASM_X86__TIME_H +#define ASM_X86__TIME_H extern void hpet_time_init(void); @@ -46,6 +46,8 @@ static inline int native_set_wallclock(unsigned long nowtime) #endif +extern void time_init(void); + #ifdef CONFIG_PARAVIRT #include <asm/paravirt.h> #else /* !CONFIG_PARAVIRT */ @@ -58,4 +60,4 @@ static inline int native_set_wallclock(unsigned long nowtime) extern unsigned long __init calibrate_cpu(void); -#endif +#endif /* ASM_X86__TIME_H */ diff --git a/include/asm-x86/timer.h b/include/asm-x86/timer.h index fb2a4ddddf3..d0babce4b47 100644 --- a/include/asm-x86/timer.h +++ b/include/asm-x86/timer.h @@ -1,5 +1,5 @@ -#ifndef _ASMi386_TIMER_H -#define _ASMi386_TIMER_H +#ifndef ASM_X86__TIMER_H +#define ASM_X86__TIMER_H #include <linux/init.h> #include <linux/pm.h> #include <linux/percpu.h> @@ -9,9 +9,12 @@ unsigned long long native_sched_clock(void); unsigned long native_calibrate_tsc(void); +#ifdef CONFIG_X86_32 extern int timer_ack; -extern int no_timer_check; extern int recalibrate_cpu_khz(void); +#endif /* CONFIG_X86_32 */ + +extern int no_timer_check; #ifndef CONFIG_PARAVIRT #define calibrate_tsc() native_calibrate_tsc() @@ -60,4 +63,4 @@ static inline unsigned long long cycles_2_ns(unsigned long long cyc) return ns; } -#endif +#endif /* ASM_X86__TIMER_H */ diff --git a/include/asm-x86/timex.h b/include/asm-x86/timex.h index 43e5a78500c..d1ce2416a5d 100644 --- a/include/asm-x86/timex.h +++ b/include/asm-x86/timex.h @@ -1,6 +1,6 @@ /* x86 architecture timex specifications */ -#ifndef _ASM_X86_TIMEX_H -#define _ASM_X86_TIMEX_H +#ifndef ASM_X86__TIMEX_H +#define ASM_X86__TIMEX_H #include <asm/processor.h> #include <asm/tsc.h> @@ -16,4 +16,4 @@ #define ARCH_HAS_READ_CURRENT_TIMER -#endif +#endif /* ASM_X86__TIMEX_H */ diff --git a/include/asm-x86/tlb.h b/include/asm-x86/tlb.h index e4e9e2d07a9..db36e9e89e8 100644 --- a/include/asm-x86/tlb.h +++ b/include/asm-x86/tlb.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_TLB_H -#define _ASM_X86_TLB_H +#ifndef ASM_X86__TLB_H +#define ASM_X86__TLB_H #define tlb_start_vma(tlb, vma) do { } while (0) #define tlb_end_vma(tlb, vma) do { } while (0) @@ -8,4 +8,4 @@ #include <asm-generic/tlb.h> -#endif +#endif /* ASM_X86__TLB_H */ diff --git a/include/asm-x86/tlbflush.h b/include/asm-x86/tlbflush.h index 35c76ceb9f4..ef68b76dc3c 100644 --- a/include/asm-x86/tlbflush.h +++ b/include/asm-x86/tlbflush.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_TLBFLUSH_H -#define _ASM_X86_TLBFLUSH_H +#ifndef ASM_X86__TLBFLUSH_H +#define ASM_X86__TLBFLUSH_H #include <linux/mm.h> #include <linux/sched.h> @@ -165,4 +165,4 @@ static inline void flush_tlb_kernel_range(unsigned long start, flush_tlb_all(); } -#endif /* _ASM_X86_TLBFLUSH_H */ +#endif /* ASM_X86__TLBFLUSH_H */ diff --git a/include/asm-x86/topology.h b/include/asm-x86/topology.h index 90ac7718469..7eca9bc022b 100644 --- a/include/asm-x86/topology.h +++ b/include/asm-x86/topology.h @@ -22,8 +22,8 @@ * * Send feedback to <colpatch@us.ibm.com> */ -#ifndef _ASM_X86_TOPOLOGY_H -#define _ASM_X86_TOPOLOGY_H +#ifndef ASM_X86__TOPOLOGY_H +#define ASM_X86__TOPOLOGY_H #ifdef CONFIG_X86_32 # ifdef CONFIG_X86_HT @@ -255,4 +255,4 @@ static inline void set_mp_bus_to_node(int busnum, int node) } #endif -#endif /* _ASM_X86_TOPOLOGY_H */ +#endif /* ASM_X86__TOPOLOGY_H */ diff --git a/include/asm-x86/trampoline.h b/include/asm-x86/trampoline.h index b156b08d013..0406bbd898a 100644 --- a/include/asm-x86/trampoline.h +++ b/include/asm-x86/trampoline.h @@ -1,5 +1,5 @@ -#ifndef __TRAMPOLINE_HEADER -#define __TRAMPOLINE_HEADER +#ifndef ASM_X86__TRAMPOLINE_H +#define ASM_X86__TRAMPOLINE_H #ifndef __ASSEMBLY__ @@ -18,4 +18,4 @@ extern unsigned long setup_trampoline(void); #endif /* __ASSEMBLY__ */ -#endif /* __TRAMPOLINE_HEADER */ +#endif /* ASM_X86__TRAMPOLINE_H */ diff --git a/include/asm-x86/traps.h b/include/asm-x86/traps.h index a4b65a71bd6..2ccebc6fb0b 100644 --- a/include/asm-x86/traps.h +++ b/include/asm-x86/traps.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_TRAPS_H -#define _ASM_X86_TRAPS_H +#ifndef ASM_X86__TRAPS_H +#define ASM_X86__TRAPS_H /* Common in X86_32 and X86_64 */ asmlinkage void divide_error(void); @@ -51,6 +51,8 @@ void do_spurious_interrupt_bug(struct pt_regs *, long); unsigned long patch_espfix_desc(unsigned long, unsigned long); asmlinkage void math_emulate(long); +void do_page_fault(struct pt_regs *regs, unsigned long error_code); + #else /* CONFIG_X86_32 */ asmlinkage void double_fault(void); @@ -62,5 +64,7 @@ asmlinkage void do_coprocessor_error(struct pt_regs *); asmlinkage void do_simd_coprocessor_error(struct pt_regs *); asmlinkage void do_spurious_interrupt_bug(struct pt_regs *); +asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code); + #endif /* CONFIG_X86_32 */ -#endif /* _ASM_X86_TRAPS_H */ +#endif /* ASM_X86__TRAPS_H */ diff --git a/include/asm-x86/tsc.h b/include/asm-x86/tsc.h index cb6f6ee45b8..ad0f5c41e78 100644 --- a/include/asm-x86/tsc.h +++ b/include/asm-x86/tsc.h @@ -1,8 +1,8 @@ /* * x86 TSC related functions */ -#ifndef _ASM_X86_TSC_H -#define _ASM_X86_TSC_H +#ifndef ASM_X86__TSC_H +#define ASM_X86__TSC_H #include <asm/processor.h> @@ -59,4 +59,4 @@ extern void check_tsc_sync_target(void); extern int notsc_setup(char *); -#endif +#endif /* ASM_X86__TSC_H */ diff --git a/include/asm-x86/types.h b/include/asm-x86/types.h index 1ac80cd9acf..e78b52e1744 100644 --- a/include/asm-x86/types.h +++ b/include/asm-x86/types.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_TYPES_H -#define _ASM_X86_TYPES_H +#ifndef ASM_X86__TYPES_H +#define ASM_X86__TYPES_H #include <asm-generic/int-ll64.h> @@ -33,4 +33,4 @@ typedef u32 dma_addr_t; #endif /* __ASSEMBLY__ */ #endif /* __KERNEL__ */ -#endif +#endif /* ASM_X86__TYPES_H */ diff --git a/include/asm-x86/uaccess.h b/include/asm-x86/uaccess.h index 5f702d1d521..48ebc0ad40e 100644 --- a/include/asm-x86/uaccess.h +++ b/include/asm-x86/uaccess.h @@ -1,5 +1,5 @@ -#ifndef _ASM_UACCES_H_ -#define _ASM_UACCES_H_ +#ifndef ASM_X86__UACCESS_H +#define ASM_X86__UACCESS_H /* * User space memory access functions */ @@ -450,5 +450,5 @@ extern struct movsl_mask { # include "uaccess_64.h" #endif -#endif +#endif /* ASM_X86__UACCESS_H */ diff --git a/include/asm-x86/uaccess_32.h b/include/asm-x86/uaccess_32.h index 6fdef39a0bc..6b5b57d9c6d 100644 --- a/include/asm-x86/uaccess_32.h +++ b/include/asm-x86/uaccess_32.h @@ -1,5 +1,5 @@ -#ifndef __i386_UACCESS_H -#define __i386_UACCESS_H +#ifndef ASM_X86__UACCESS_32_H +#define ASM_X86__UACCESS_32_H /* * User space memory access functions @@ -215,4 +215,4 @@ long strnlen_user(const char __user *str, long n); unsigned long __must_check clear_user(void __user *mem, unsigned long len); unsigned long __must_check __clear_user(void __user *mem, unsigned long len); -#endif /* __i386_UACCESS_H */ +#endif /* ASM_X86__UACCESS_32_H */ diff --git a/include/asm-x86/uaccess_64.h b/include/asm-x86/uaccess_64.h index 515d4dce96b..c96c1f5d07a 100644 --- a/include/asm-x86/uaccess_64.h +++ b/include/asm-x86/uaccess_64.h @@ -1,5 +1,5 @@ -#ifndef __X86_64_UACCESS_H -#define __X86_64_UACCESS_H +#ifndef ASM_X86__UACCESS_64_H +#define ASM_X86__UACCESS_64_H /* * User space memory access functions @@ -7,6 +7,7 @@ #include <linux/compiler.h> #include <linux/errno.h> #include <linux/prefetch.h> +#include <linux/lockdep.h> #include <asm/page.h> /* @@ -198,4 +199,4 @@ static inline int __copy_from_user_inatomic_nocache(void *dst, unsigned long copy_user_handle_tail(char *to, char *from, unsigned len, unsigned zerorest); -#endif /* __X86_64_UACCESS_H */ +#endif /* ASM_X86__UACCESS_64_H */ diff --git a/include/asm-x86/ucontext.h b/include/asm-x86/ucontext.h index 50a79f7fcde..9948dd32808 100644 --- a/include/asm-x86/ucontext.h +++ b/include/asm-x86/ucontext.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_UCONTEXT_H -#define _ASM_X86_UCONTEXT_H +#ifndef ASM_X86__UCONTEXT_H +#define ASM_X86__UCONTEXT_H struct ucontext { unsigned long uc_flags; @@ -9,4 +9,4 @@ struct ucontext { sigset_t uc_sigmask; /* mask last for extensibility */ }; -#endif /* _ASM_X86_UCONTEXT_H */ +#endif /* ASM_X86__UCONTEXT_H */ diff --git a/include/asm-x86/unaligned.h b/include/asm-x86/unaligned.h index a7bd416b476..59dcdec3716 100644 --- a/include/asm-x86/unaligned.h +++ b/include/asm-x86/unaligned.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_UNALIGNED_H -#define _ASM_X86_UNALIGNED_H +#ifndef ASM_X86__UNALIGNED_H +#define ASM_X86__UNALIGNED_H /* * The x86 can do unaligned accesses itself. @@ -11,4 +11,4 @@ #define get_unaligned __get_unaligned_le #define put_unaligned __put_unaligned_le -#endif /* _ASM_X86_UNALIGNED_H */ +#endif /* ASM_X86__UNALIGNED_H */ diff --git a/include/asm-x86/unistd_32.h b/include/asm-x86/unistd_32.h index d7394673b77..017f4a87c91 100644 --- a/include/asm-x86/unistd_32.h +++ b/include/asm-x86/unistd_32.h @@ -1,5 +1,5 @@ -#ifndef _ASM_I386_UNISTD_H_ -#define _ASM_I386_UNISTD_H_ +#ifndef ASM_X86__UNISTD_32_H +#define ASM_X86__UNISTD_32_H /* * This file contains the system call numbers. @@ -376,4 +376,4 @@ #endif #endif /* __KERNEL__ */ -#endif /* _ASM_I386_UNISTD_H_ */ +#endif /* ASM_X86__UNISTD_32_H */ diff --git a/include/asm-x86/unistd_64.h b/include/asm-x86/unistd_64.h index 3a341d79179..ace83f1f678 100644 --- a/include/asm-x86/unistd_64.h +++ b/include/asm-x86/unistd_64.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_64_UNISTD_H_ -#define _ASM_X86_64_UNISTD_H_ +#ifndef ASM_X86__UNISTD_64_H +#define ASM_X86__UNISTD_64_H #ifndef __SYSCALL #define __SYSCALL(a, b) @@ -690,4 +690,4 @@ __SYSCALL(__NR_inotify_init1, sys_inotify_init1) #define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall") #endif /* __KERNEL__ */ -#endif /* _ASM_X86_64_UNISTD_H_ */ +#endif /* ASM_X86__UNISTD_64_H */ diff --git a/include/asm-x86/unwind.h b/include/asm-x86/unwind.h index 8b064bd9c55..a2151567db4 100644 --- a/include/asm-x86/unwind.h +++ b/include/asm-x86/unwind.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_UNWIND_H -#define _ASM_X86_UNWIND_H +#ifndef ASM_X86__UNWIND_H +#define ASM_X86__UNWIND_H #define UNW_PC(frame) ((void)(frame), 0UL) #define UNW_SP(frame) ((void)(frame), 0UL) @@ -10,4 +10,4 @@ static inline int arch_unw_user_mode(const void *info) return 0; } -#endif /* _ASM_X86_UNWIND_H */ +#endif /* ASM_X86__UNWIND_H */ diff --git a/include/asm-x86/user32.h b/include/asm-x86/user32.h index a3d91004787..aa66c1857f0 100644 --- a/include/asm-x86/user32.h +++ b/include/asm-x86/user32.h @@ -1,5 +1,5 @@ -#ifndef USER32_H -#define USER32_H 1 +#ifndef ASM_X86__USER32_H +#define ASM_X86__USER32_H /* IA32 compatible user structures for ptrace. * These should be used for 32bit coredumps too. */ @@ -67,4 +67,4 @@ struct user32 { }; -#endif +#endif /* ASM_X86__USER32_H */ diff --git a/include/asm-x86/user_32.h b/include/asm-x86/user_32.h index d6e51edc259..e0fe2f55f1a 100644 --- a/include/asm-x86/user_32.h +++ b/include/asm-x86/user_32.h @@ -1,5 +1,5 @@ -#ifndef _I386_USER_H -#define _I386_USER_H +#ifndef ASM_X86__USER_32_H +#define ASM_X86__USER_32_H #include <asm/page.h> /* Core file format: The core file is written in such a way that gdb @@ -128,4 +128,4 @@ struct user{ #define HOST_TEXT_START_ADDR (u.start_code) #define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG) -#endif /* _I386_USER_H */ +#endif /* ASM_X86__USER_32_H */ diff --git a/include/asm-x86/user_64.h b/include/asm-x86/user_64.h index 6037b634c77..38b5799863b 100644 --- a/include/asm-x86/user_64.h +++ b/include/asm-x86/user_64.h @@ -1,5 +1,5 @@ -#ifndef _X86_64_USER_H -#define _X86_64_USER_H +#ifndef ASM_X86__USER_64_H +#define ASM_X86__USER_64_H #include <asm/types.h> #include <asm/page.h> @@ -134,4 +134,4 @@ struct user { #define HOST_TEXT_START_ADDR (u.start_code) #define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG) -#endif /* _X86_64_USER_H */ +#endif /* ASM_X86__USER_64_H */ diff --git a/include/asm-x86/uv/bios.h b/include/asm-x86/uv/bios.h index aa73362ff5d..7cd6d7ec130 100644 --- a/include/asm-x86/uv/bios.h +++ b/include/asm-x86/uv/bios.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_BIOS_H -#define _ASM_X86_BIOS_H +#ifndef ASM_X86__UV__BIOS_H +#define ASM_X86__UV__BIOS_H /* * BIOS layer definitions. @@ -65,4 +65,4 @@ x86_bios_freq_base(unsigned long which, unsigned long *ticks_per_second, unsigned long *drift_info); extern const char *x86_bios_strerror(long status); -#endif /* _ASM_X86_BIOS_H */ +#endif /* ASM_X86__UV__BIOS_H */ diff --git a/include/asm-x86/uv/uv_bau.h b/include/asm-x86/uv/uv_bau.h index 610b6b308e9..77153fb18f5 100644 --- a/include/asm-x86/uv/uv_bau.h +++ b/include/asm-x86/uv/uv_bau.h @@ -8,8 +8,8 @@ * Copyright (C) 2008 Silicon Graphics, Inc. All rights reserved. */ -#ifndef __ASM_X86_UV_BAU__ -#define __ASM_X86_UV_BAU__ +#ifndef ASM_X86__UV__UV_BAU_H +#define ASM_X86__UV__UV_BAU_H #include <linux/bitmap.h> #define BITSPERBYTE 8 @@ -329,4 +329,4 @@ extern int uv_flush_tlb_others(cpumask_t *, struct mm_struct *, unsigned long); extern void uv_bau_message_intr1(void); extern void uv_bau_timeout_intr1(void); -#endif /* __ASM_X86_UV_BAU__ */ +#endif /* ASM_X86__UV__UV_BAU_H */ diff --git a/include/asm-x86/uv/uv_hub.h b/include/asm-x86/uv/uv_hub.h index a4ef26e5850..bdb5b01afbf 100644 --- a/include/asm-x86/uv/uv_hub.h +++ b/include/asm-x86/uv/uv_hub.h @@ -8,8 +8,8 @@ * Copyright (C) 2007-2008 Silicon Graphics, Inc. All rights reserved. */ -#ifndef __ASM_X86_UV_HUB_H__ -#define __ASM_X86_UV_HUB_H__ +#ifndef ASM_X86__UV__UV_HUB_H +#define ASM_X86__UV__UV_HUB_H #include <linux/numa.h> #include <linux/percpu.h> @@ -350,5 +350,5 @@ static inline int uv_num_possible_blades(void) return uv_possible_blades; } -#endif /* __ASM_X86_UV_HUB__ */ +#endif /* ASM_X86__UV__UV_HUB_H */ diff --git a/include/asm-x86/uv/uv_mmrs.h b/include/asm-x86/uv/uv_mmrs.h index 151fd7fcb80..8b03d89d245 100644 --- a/include/asm-x86/uv/uv_mmrs.h +++ b/include/asm-x86/uv/uv_mmrs.h @@ -8,8 +8,8 @@ * Copyright (C) 2007-2008 Silicon Graphics, Inc. All rights reserved. */ -#ifndef __ASM_X86_UV_MMRS__ -#define __ASM_X86_UV_MMRS__ +#ifndef ASM_X86__UV__UV_MMRS_H +#define ASM_X86__UV__UV_MMRS_H #define UV_MMR_ENABLE (1UL << 63) @@ -1292,4 +1292,4 @@ union uvh_si_alias2_overlay_config_u { }; -#endif /* __ASM_X86_UV_MMRS__ */ +#endif /* ASM_X86__UV__UV_MMRS_H */ diff --git a/include/asm-x86/vdso.h b/include/asm-x86/vdso.h index 8e18fb80f5e..4ab320913ea 100644 --- a/include/asm-x86/vdso.h +++ b/include/asm-x86/vdso.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_VDSO_H -#define _ASM_X86_VDSO_H 1 +#ifndef ASM_X86__VDSO_H +#define ASM_X86__VDSO_H #ifdef CONFIG_X86_64 extern const char VDSO64_PRELINK[]; @@ -44,4 +44,4 @@ extern const char vdso32_int80_start, vdso32_int80_end; extern const char vdso32_syscall_start, vdso32_syscall_end; extern const char vdso32_sysenter_start, vdso32_sysenter_end; -#endif /* asm-x86/vdso.h */ +#endif /* ASM_X86__VDSO_H */ diff --git a/include/asm-x86/vga.h b/include/asm-x86/vga.h index 0ccf804377e..b9e493d07d0 100644 --- a/include/asm-x86/vga.h +++ b/include/asm-x86/vga.h @@ -4,8 +4,8 @@ * (c) 1998 Martin Mares <mj@ucw.cz> */ -#ifndef _LINUX_ASM_VGA_H_ -#define _LINUX_ASM_VGA_H_ +#ifndef ASM_X86__VGA_H +#define ASM_X86__VGA_H /* * On the PC, we can just recalculate addresses and then @@ -17,4 +17,4 @@ #define vga_readb(x) (*(x)) #define vga_writeb(x, y) (*(y) = (x)) -#endif +#endif /* ASM_X86__VGA_H */ diff --git a/include/asm-x86/vgtod.h b/include/asm-x86/vgtod.h index 3301f092934..38fd1336402 100644 --- a/include/asm-x86/vgtod.h +++ b/include/asm-x86/vgtod.h @@ -1,5 +1,5 @@ -#ifndef _ASM_VGTOD_H -#define _ASM_VGTOD_H 1 +#ifndef ASM_X86__VGTOD_H +#define ASM_X86__VGTOD_H #include <asm/vsyscall.h> #include <linux/clocksource.h> @@ -26,4 +26,4 @@ extern struct vsyscall_gtod_data __vsyscall_gtod_data __section_vsyscall_gtod_data; extern struct vsyscall_gtod_data vsyscall_gtod_data; -#endif +#endif /* ASM_X86__VGTOD_H */ diff --git a/include/asm-x86/visws/cobalt.h b/include/asm-x86/visws/cobalt.h index 995258831b7..9627a8fe84e 100644 --- a/include/asm-x86/visws/cobalt.h +++ b/include/asm-x86/visws/cobalt.h @@ -1,5 +1,5 @@ -#ifndef __I386_SGI_COBALT_H -#define __I386_SGI_COBALT_H +#ifndef ASM_X86__VISWS__COBALT_H +#define ASM_X86__VISWS__COBALT_H #include <asm/fixmap.h> @@ -122,4 +122,4 @@ extern char visws_board_type; extern char visws_board_rev; -#endif /* __I386_SGI_COBALT_H */ +#endif /* ASM_X86__VISWS__COBALT_H */ diff --git a/include/asm-x86/visws/lithium.h b/include/asm-x86/visws/lithium.h index dfcd4f07ab8..b36d3b378c6 100644 --- a/include/asm-x86/visws/lithium.h +++ b/include/asm-x86/visws/lithium.h @@ -1,5 +1,5 @@ -#ifndef __I386_SGI_LITHIUM_H -#define __I386_SGI_LITHIUM_H +#ifndef ASM_X86__VISWS__LITHIUM_H +#define ASM_X86__VISWS__LITHIUM_H #include <asm/fixmap.h> @@ -49,5 +49,5 @@ static inline unsigned short li_pcib_read16(unsigned long reg) return *((volatile unsigned short *)(LI_PCIB_VADDR+reg)); } -#endif +#endif /* ASM_X86__VISWS__LITHIUM_H */ diff --git a/include/asm-x86/visws/piix4.h b/include/asm-x86/visws/piix4.h index 83ea4f46e41..61c938045ec 100644 --- a/include/asm-x86/visws/piix4.h +++ b/include/asm-x86/visws/piix4.h @@ -1,5 +1,5 @@ -#ifndef __I386_SGI_PIIX_H -#define __I386_SGI_PIIX_H +#ifndef ASM_X86__VISWS__PIIX4_H +#define ASM_X86__VISWS__PIIX4_H /* * PIIX4 as used on SGI Visual Workstations @@ -104,4 +104,4 @@ */ #define PIIX_GPI_STPCLK 0x4 // STPCLK signal routed back in -#endif +#endif /* ASM_X86__VISWS__PIIX4_H */ diff --git a/include/asm-x86/vm86.h b/include/asm-x86/vm86.h index 5ce351325e0..998bd18eb73 100644 --- a/include/asm-x86/vm86.h +++ b/include/asm-x86/vm86.h @@ -1,5 +1,5 @@ -#ifndef _LINUX_VM86_H -#define _LINUX_VM86_H +#ifndef ASM_X86__VM86_H +#define ASM_X86__VM86_H /* * I'm guessing at the VIF/VIP flag usage, but hope that this is how @@ -205,4 +205,4 @@ static inline int handle_vm86_trap(struct kernel_vm86_regs *a, long b, int c) #endif /* __KERNEL__ */ -#endif +#endif /* ASM_X86__VM86_H */ diff --git a/include/asm-x86/vmi_time.h b/include/asm-x86/vmi_time.h index c3118c38515..b2d39e6a08b 100644 --- a/include/asm-x86/vmi_time.h +++ b/include/asm-x86/vmi_time.h @@ -22,8 +22,8 @@ * */ -#ifndef __VMI_TIME_H -#define __VMI_TIME_H +#ifndef ASM_X86__VMI_TIME_H +#define ASM_X86__VMI_TIME_H /* * Raw VMI call indices for timer functions @@ -95,4 +95,4 @@ extern void __devinit vmi_time_ap_init(void); #define CONFIG_VMI_ALARM_HZ 100 -#endif +#endif /* ASM_X86__VMI_TIME_H */ diff --git a/include/asm-x86/vsyscall.h b/include/asm-x86/vsyscall.h index 6b66ff905af..dcd4682413d 100644 --- a/include/asm-x86/vsyscall.h +++ b/include/asm-x86/vsyscall.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_64_VSYSCALL_H_ -#define _ASM_X86_64_VSYSCALL_H_ +#ifndef ASM_X86__VSYSCALL_H +#define ASM_X86__VSYSCALL_H enum vsyscall_num { __NR_vgettimeofday, @@ -41,4 +41,4 @@ extern void map_vsyscall(void); #endif /* __KERNEL__ */ -#endif /* _ASM_X86_64_VSYSCALL_H_ */ +#endif /* ASM_X86__VSYSCALL_H */ diff --git a/include/asm-x86/xen/events.h b/include/asm-x86/xen/events.h index 8ded7472002..8151f5b8b6c 100644 --- a/include/asm-x86/xen/events.h +++ b/include/asm-x86/xen/events.h @@ -1,5 +1,5 @@ -#ifndef __XEN_EVENTS_H -#define __XEN_EVENTS_H +#ifndef ASM_X86__XEN__EVENTS_H +#define ASM_X86__XEN__EVENTS_H enum ipi_vector { XEN_RESCHEDULE_VECTOR, @@ -21,4 +21,4 @@ static inline void xen_do_IRQ(int irq, struct pt_regs *regs) do_IRQ(regs); } -#endif /* __XEN_EVENTS_H */ +#endif /* ASM_X86__XEN__EVENTS_H */ diff --git a/include/asm-x86/xen/grant_table.h b/include/asm-x86/xen/grant_table.h index 2444d4593a3..c4baab4d2b6 100644 --- a/include/asm-x86/xen/grant_table.h +++ b/include/asm-x86/xen/grant_table.h @@ -1,7 +1,7 @@ -#ifndef __XEN_GRANT_TABLE_H -#define __XEN_GRANT_TABLE_H +#ifndef ASM_X86__XEN__GRANT_TABLE_H +#define ASM_X86__XEN__GRANT_TABLE_H #define xen_alloc_vm_area(size) alloc_vm_area(size) #define xen_free_vm_area(area) free_vm_area(area) -#endif /* __XEN_GRANT_TABLE_H */ +#endif /* ASM_X86__XEN__GRANT_TABLE_H */ diff --git a/include/asm-x86/xen/hypercall.h b/include/asm-x86/xen/hypercall.h index 91cb7fd5c12..44f4259bee3 100644 --- a/include/asm-x86/xen/hypercall.h +++ b/include/asm-x86/xen/hypercall.h @@ -30,8 +30,8 @@ * IN THE SOFTWARE. */ -#ifndef __HYPERCALL_H__ -#define __HYPERCALL_H__ +#ifndef ASM_X86__XEN__HYPERCALL_H +#define ASM_X86__XEN__HYPERCALL_H #include <linux/errno.h> #include <linux/string.h> @@ -524,4 +524,4 @@ MULTI_stack_switch(struct multicall_entry *mcl, mcl->args[1] = esp; } -#endif /* __HYPERCALL_H__ */ +#endif /* ASM_X86__XEN__HYPERCALL_H */ diff --git a/include/asm-x86/xen/hypervisor.h b/include/asm-x86/xen/hypervisor.h index 04ee0610014..0ef3a88b869 100644 --- a/include/asm-x86/xen/hypervisor.h +++ b/include/asm-x86/xen/hypervisor.h @@ -30,8 +30,8 @@ * IN THE SOFTWARE. */ -#ifndef __HYPERVISOR_H__ -#define __HYPERVISOR_H__ +#ifndef ASM_X86__XEN__HYPERVISOR_H +#define ASM_X86__XEN__HYPERVISOR_H #include <linux/types.h> #include <linux/kernel.h> @@ -69,4 +69,4 @@ u64 jiffies_to_st(unsigned long jiffies); #define is_running_on_xen() (xen_start_info ? 1 : 0) -#endif /* __HYPERVISOR_H__ */ +#endif /* ASM_X86__XEN__HYPERVISOR_H */ diff --git a/include/asm-x86/xen/interface.h b/include/asm-x86/xen/interface.h index 9d810f2538a..d077bba96da 100644 --- a/include/asm-x86/xen/interface.h +++ b/include/asm-x86/xen/interface.h @@ -6,8 +6,8 @@ * Copyright (c) 2004, K A Fraser */ -#ifndef __ASM_X86_XEN_INTERFACE_H -#define __ASM_X86_XEN_INTERFACE_H +#ifndef ASM_X86__XEN__INTERFACE_H +#define ASM_X86__XEN__INTERFACE_H #ifdef __XEN__ #define __DEFINE_GUEST_HANDLE(name, type) \ @@ -172,4 +172,4 @@ DEFINE_GUEST_HANDLE_STRUCT(vcpu_guest_context); #define XEN_CPUID XEN_EMULATE_PREFIX "cpuid" #endif -#endif /* __ASM_X86_XEN_INTERFACE_H */ +#endif /* ASM_X86__XEN__INTERFACE_H */ diff --git a/include/asm-x86/xen/interface_32.h b/include/asm-x86/xen/interface_32.h index d8ac41d5db8..08167e19fc6 100644 --- a/include/asm-x86/xen/interface_32.h +++ b/include/asm-x86/xen/interface_32.h @@ -6,8 +6,8 @@ * Copyright (c) 2004, K A Fraser */ -#ifndef __ASM_X86_XEN_INTERFACE_32_H -#define __ASM_X86_XEN_INTERFACE_32_H +#ifndef ASM_X86__XEN__INTERFACE_32_H +#define ASM_X86__XEN__INTERFACE_32_H /* @@ -94,4 +94,4 @@ typedef struct xen_callback xen_callback_t; #define xen_pfn_to_cr3(pfn) (((unsigned)(pfn) << 12) | ((unsigned)(pfn) >> 20)) #define xen_cr3_to_pfn(cr3) (((unsigned)(cr3) >> 12) | ((unsigned)(cr3) << 20)) -#endif /* __ASM_X86_XEN_INTERFACE_32_H */ +#endif /* ASM_X86__XEN__INTERFACE_32_H */ diff --git a/include/asm-x86/xen/interface_64.h b/include/asm-x86/xen/interface_64.h index 842266ce96e..046c0f1e01d 100644 --- a/include/asm-x86/xen/interface_64.h +++ b/include/asm-x86/xen/interface_64.h @@ -1,5 +1,5 @@ -#ifndef __ASM_X86_XEN_INTERFACE_64_H -#define __ASM_X86_XEN_INTERFACE_64_H +#ifndef ASM_X86__XEN__INTERFACE_64_H +#define ASM_X86__XEN__INTERFACE_64_H /* * 64-bit segment selectors @@ -156,4 +156,4 @@ typedef unsigned long xen_callback_t; #endif /* !__ASSEMBLY__ */ -#endif /* __ASM_X86_XEN_INTERFACE_64_H */ +#endif /* ASM_X86__XEN__INTERFACE_64_H */ diff --git a/include/asm-x86/xen/page.h b/include/asm-x86/xen/page.h index 7b3835d3b77..c50185dccec 100644 --- a/include/asm-x86/xen/page.h +++ b/include/asm-x86/xen/page.h @@ -1,5 +1,5 @@ -#ifndef __XEN_PAGE_H -#define __XEN_PAGE_H +#ifndef ASM_X86__XEN__PAGE_H +#define ASM_X86__XEN__PAGE_H #include <linux/pfn.h> @@ -162,4 +162,4 @@ xmaddr_t arbitrary_virt_to_machine(void *address); void make_lowmem_page_readonly(void *vaddr); void make_lowmem_page_readwrite(void *vaddr); -#endif /* __XEN_PAGE_H */ +#endif /* ASM_X86__XEN__PAGE_H */ diff --git a/arch/arm/include/asm/cnt32_to_63.h b/include/linux/cnt32_to_63.h index 480c873fa74..8c0f9505b48 100644 --- a/arch/arm/include/asm/cnt32_to_63.h +++ b/include/linux/cnt32_to_63.h @@ -1,5 +1,5 @@ /* - * include/asm/cnt32_to_63.h -- extend a 32-bit counter to 63 bits + * Extend a 32-bit counter to 63 bits * * Author: Nicolas Pitre * Created: December 3, 2006 @@ -10,15 +10,30 @@ * as published by the Free Software Foundation. */ -#ifndef __INCLUDE_CNT32_TO_63_H__ -#define __INCLUDE_CNT32_TO_63_H__ +#ifndef __LINUX_CNT32_TO_63_H__ +#define __LINUX_CNT32_TO_63_H__ #include <linux/compiler.h> -#include <asm/types.h> +#include <linux/types.h> #include <asm/byteorder.h> -/* - * Prototype: u64 cnt32_to_63(u32 cnt) +/* this is used only to give gcc a clue about good code generation */ +union cnt32_to_63 { + struct { +#if defined(__LITTLE_ENDIAN) + u32 lo, hi; +#elif defined(__BIG_ENDIAN) + u32 hi, lo; +#endif + }; + u64 val; +}; + + +/** + * cnt32_to_63 - Expand a 32-bit counter to a 63-bit counter + * @cnt_lo: The low part of the counter + * * Many hardware clock counters are only 32 bits wide and therefore have * a relatively short period making wrap-arounds rather frequent. This * is a problem when implementing sched_clock() for example, where a 64-bit @@ -51,26 +66,13 @@ * clear-bit instruction. Otherwise caller must remember to clear the top * bit explicitly. */ - -/* this is used only to give gcc a clue about good code generation */ -typedef union { - struct { -#if defined(__LITTLE_ENDIAN) - u32 lo, hi; -#elif defined(__BIG_ENDIAN) - u32 hi, lo; -#endif - }; - u64 val; -} cnt32_to_63_t; - #define cnt32_to_63(cnt_lo) \ ({ \ - static volatile u32 __m_cnt_hi = 0; \ - cnt32_to_63_t __x; \ + static volatile u32 __m_cnt_hi; \ + union cnt32_to_63 __x; \ __x.hi = __m_cnt_hi; \ __x.lo = (cnt_lo); \ - if (unlikely((s32)(__x.hi ^ __x.lo) < 0)) \ + if (unlikely((s32)(__x.hi ^ __x.lo) < 0)) \ __m_cnt_hi = __x.hi = (__x.hi ^ 0x80000000) + (__x.hi >> 31); \ __x.val; \ }) diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index 6d93dce61cb..2f245fe63bd 100644 --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h @@ -47,14 +47,22 @@ enum hrtimer_restart { * HRTIMER_CB_IRQSAFE: Callback may run in hardirq context * HRTIMER_CB_IRQSAFE_NO_RESTART: Callback may run in hardirq context and * does not restart the timer - * HRTIMER_CB_IRQSAFE_NO_SOFTIRQ: Callback must run in hardirq context - * Special mode for tick emultation + * HRTIMER_CB_IRQSAFE_PERCPU: Callback must run in hardirq context + * Special mode for tick emulation and + * scheduler timer. Such timers are per + * cpu and not allowed to be migrated on + * cpu unplug. + * HRTIMER_CB_IRQSAFE_UNLOCKED: Callback should run in hardirq context + * with timer->base lock unlocked + * used for timers which call wakeup to + * avoid lock order problems with rq->lock */ enum hrtimer_cb_mode { HRTIMER_CB_SOFTIRQ, HRTIMER_CB_IRQSAFE, HRTIMER_CB_IRQSAFE_NO_RESTART, - HRTIMER_CB_IRQSAFE_NO_SOFTIRQ, + HRTIMER_CB_IRQSAFE_PERCPU, + HRTIMER_CB_IRQSAFE_UNLOCKED, }; /* @@ -67,9 +75,10 @@ enum hrtimer_cb_mode { * 0x02 callback function running * 0x04 callback pending (high resolution mode) * - * Special case: + * Special cases: * 0x03 callback function running and enqueued * (was requeued on another CPU) + * 0x09 timer was migrated on CPU hotunplug * The "callback function running and enqueued" status is only possible on * SMP. It happens for example when a posix timer expired and the callback * queued a signal. Between dropping the lock which protects the posix timer @@ -87,6 +96,7 @@ enum hrtimer_cb_mode { #define HRTIMER_STATE_ENQUEUED 0x01 #define HRTIMER_STATE_CALLBACK 0x02 #define HRTIMER_STATE_PENDING 0x04 +#define HRTIMER_STATE_MIGRATE 0x08 /** * struct hrtimer - the basic hrtimer structure diff --git a/include/linux/pci.h b/include/linux/pci.h index c0e14008a3c..98dc6243a70 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -534,7 +534,7 @@ extern void pci_sort_breadthfirst(void); #ifdef CONFIG_PCI_LEGACY struct pci_dev __deprecated *pci_find_device(unsigned int vendor, unsigned int device, - const struct pci_dev *from); + struct pci_dev *from); struct pci_dev __deprecated *pci_find_slot(unsigned int bus, unsigned int devfn); #endif /* CONFIG_PCI_LEGACY */ @@ -550,7 +550,7 @@ struct pci_dev *pci_get_device(unsigned int vendor, unsigned int device, struct pci_dev *from); struct pci_dev *pci_get_subsys(unsigned int vendor, unsigned int device, unsigned int ss_vendor, unsigned int ss_device, - const struct pci_dev *from); + struct pci_dev *from); struct pci_dev *pci_get_slot(struct pci_bus *bus, unsigned int devfn); struct pci_dev *pci_get_bus_and_slot(unsigned int bus, unsigned int devfn); struct pci_dev *pci_get_class(unsigned int class, struct pci_dev *from); @@ -816,7 +816,7 @@ _PCI_NOP_ALL(write,) static inline struct pci_dev *pci_find_device(unsigned int vendor, unsigned int device, - const struct pci_dev *from) + struct pci_dev *from) { return NULL; } @@ -838,7 +838,7 @@ static inline struct pci_dev *pci_get_subsys(unsigned int vendor, unsigned int device, unsigned int ss_vendor, unsigned int ss_device, - const struct pci_dev *from) + struct pci_dev *from) { return NULL; } diff --git a/include/linux/ramfs.h b/include/linux/ramfs.h index b160fb18e8d..37aaf2b3986 100644 --- a/include/linux/ramfs.h +++ b/include/linux/ramfs.h @@ -6,6 +6,7 @@ extern int ramfs_get_sb(struct file_system_type *fs_type, int flags, const char *dev_name, void *data, struct vfsmount *mnt); #ifndef CONFIG_MMU +extern int ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize); extern unsigned long ramfs_nommu_get_unmapped_area(struct file *file, unsigned long addr, unsigned long len, diff --git a/include/linux/smb.h b/include/linux/smb.h index caa43b2370c..82fefddc598 100644 --- a/include/linux/smb.h +++ b/include/linux/smb.h @@ -11,7 +11,9 @@ #include <linux/types.h> #include <linux/magic.h> +#ifdef __KERNEL__ #include <linux/time.h> +#endif enum smb_protocol { SMB_PROTOCOL_NONE, diff --git a/include/linux/stacktrace.h b/include/linux/stacktrace.h index 5da9794b2d7..b106fd8e0d5 100644 --- a/include/linux/stacktrace.h +++ b/include/linux/stacktrace.h @@ -1,6 +1,8 @@ #ifndef __LINUX_STACKTRACE_H #define __LINUX_STACKTRACE_H +struct task_struct; + #ifdef CONFIG_STACKTRACE struct stack_trace { unsigned int nr_entries, max_entries; diff --git a/include/net/9p/9p.h b/include/net/9p/9p.h index b3d3e27c629..c3626c0ba9d 100644 --- a/include/net/9p/9p.h +++ b/include/net/9p/9p.h @@ -596,4 +596,5 @@ int p9_idpool_check(int id, struct p9_idpool *p); int p9_error_init(void); int p9_errstr2errno(char *, int); int p9_trans_fd_init(void); +void p9_trans_fd_exit(void); #endif /* NET_9P_H */ diff --git a/include/net/9p/transport.h b/include/net/9p/transport.h index 0db3a4038dc..3ca737120a9 100644 --- a/include/net/9p/transport.h +++ b/include/net/9p/transport.h @@ -26,6 +26,8 @@ #ifndef NET_9P_TRANSPORT_H #define NET_9P_TRANSPORT_H +#include <linux/module.h> + /** * enum p9_trans_status - different states of underlying transports * @Connected: transport is connected and healthy @@ -91,9 +93,12 @@ struct p9_trans_module { int maxsize; /* max message size of transport */ int def; /* this transport should be default */ struct p9_trans * (*create)(const char *, char *, int, unsigned char); + struct module *owner; }; void v9fs_register_trans(struct p9_trans_module *m); -struct p9_trans_module *v9fs_match_trans(const substring_t *name); -struct p9_trans_module *v9fs_default_trans(void); +void v9fs_unregister_trans(struct p9_trans_module *m); +struct p9_trans_module *v9fs_get_trans_by_name(const substring_t *name); +struct p9_trans_module *v9fs_get_default_trans(void); +void v9fs_put_trans(struct p9_trans_module *m); #endif /* NET_9P_TRANSPORT_H */ diff --git a/include/net/sctp/sm.h b/include/net/sctp/sm.h index 24811732bdb..029a54a0239 100644 --- a/include/net/sctp/sm.h +++ b/include/net/sctp/sm.h @@ -227,6 +227,9 @@ struct sctp_chunk *sctp_make_abort_violation(const struct sctp_association *, const struct sctp_chunk *, const __u8 *, const size_t ); +struct sctp_chunk *sctp_make_violation_paramlen(const struct sctp_association *, + const struct sctp_chunk *, + struct sctp_paramhdr *); struct sctp_chunk *sctp_make_heartbeat(const struct sctp_association *, const struct sctp_transport *, const void *payload, diff --git a/init/main.c b/init/main.c index f6f7042331d..3820323c4c8 100644 --- a/init/main.c +++ b/init/main.c @@ -708,7 +708,7 @@ int do_one_initcall(initcall_t fn) int result; if (initcall_debug) { - print_fn_descriptor_symbol("calling %s\n", fn); + printk("calling %pF\n", fn); t0 = ktime_get(); } @@ -718,8 +718,8 @@ int do_one_initcall(initcall_t fn) t1 = ktime_get(); delta = ktime_sub(t1, t0); - print_fn_descriptor_symbol("initcall %s", fn); - printk(" returned %d after %Ld msecs\n", result, + printk("initcall %pF returned %d after %Ld msecs\n", + fn, result, (unsigned long long) delta.tv64 >> 20); } @@ -737,8 +737,7 @@ int do_one_initcall(initcall_t fn) local_irq_enable(); } if (msgbuf[0]) { - print_fn_descriptor_symbol(KERN_WARNING "initcall %s", fn); - printk(" returned with %s\n", msgbuf); + printk("initcall %pF returned with %s\n", fn, msgbuf); } return result; diff --git a/kernel/cgroup.c b/kernel/cgroup.c index 13932abde15..a0123d75ec9 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c @@ -2738,14 +2738,15 @@ void cgroup_fork_callbacks(struct task_struct *child) */ void cgroup_mm_owner_callbacks(struct task_struct *old, struct task_struct *new) { - struct cgroup *oldcgrp, *newcgrp; + struct cgroup *oldcgrp, *newcgrp = NULL; if (need_mm_owner_callback) { int i; for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) { struct cgroup_subsys *ss = subsys[i]; oldcgrp = task_cgroup(old, ss->subsys_id); - newcgrp = task_cgroup(new, ss->subsys_id); + if (new) + newcgrp = task_cgroup(new, ss->subsys_id); if (oldcgrp == newcgrp) continue; if (ss->mm_owner_changed) diff --git a/kernel/exit.c b/kernel/exit.c index 16395644a98..85a83c83185 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -583,8 +583,6 @@ mm_need_new_owner(struct mm_struct *mm, struct task_struct *p) * If there are other users of the mm and the owner (us) is exiting * we need to find a new owner to take on the responsibility. */ - if (!mm) - return 0; if (atomic_read(&mm->mm_users) <= 1) return 0; if (mm->owner != p) @@ -627,6 +625,16 @@ retry: } while_each_thread(g, c); read_unlock(&tasklist_lock); + /* + * We found no owner yet mm_users > 1: this implies that we are + * most likely racing with swapoff (try_to_unuse()) or /proc or + * ptrace or page migration (get_task_mm()). Mark owner as NULL, + * so that subsystems can understand the callback and take action. + */ + down_write(&mm->mmap_sem); + cgroup_mm_owner_callbacks(mm->owner, NULL); + mm->owner = NULL; + up_write(&mm->mmap_sem); return; assign_new_owner: diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index b8e4dce80a7..cdec83e722f 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c @@ -672,13 +672,14 @@ static inline int hrtimer_enqueue_reprogram(struct hrtimer *timer, */ BUG_ON(timer->function(timer) != HRTIMER_NORESTART); return 1; - case HRTIMER_CB_IRQSAFE_NO_SOFTIRQ: + case HRTIMER_CB_IRQSAFE_PERCPU: + case HRTIMER_CB_IRQSAFE_UNLOCKED: /* * This is solely for the sched tick emulation with * dynamic tick support to ensure that we do not * restart the tick right on the edge and end up with * the tick timer in the softirq ! The calling site - * takes care of this. + * takes care of this. Also used for hrtimer sleeper ! */ debug_hrtimer_deactivate(timer); return 1; @@ -1245,7 +1246,8 @@ static void __run_hrtimer(struct hrtimer *timer) timer_stats_account_hrtimer(timer); fn = timer->function; - if (timer->cb_mode == HRTIMER_CB_IRQSAFE_NO_SOFTIRQ) { + if (timer->cb_mode == HRTIMER_CB_IRQSAFE_PERCPU || + timer->cb_mode == HRTIMER_CB_IRQSAFE_UNLOCKED) { /* * Used for scheduler timers, avoid lock inversion with * rq->lock and tasklist_lock. @@ -1452,7 +1454,7 @@ void hrtimer_init_sleeper(struct hrtimer_sleeper *sl, struct task_struct *task) sl->timer.function = hrtimer_wakeup; sl->task = task; #ifdef CONFIG_HIGH_RES_TIMERS - sl->timer.cb_mode = HRTIMER_CB_IRQSAFE_NO_SOFTIRQ; + sl->timer.cb_mode = HRTIMER_CB_IRQSAFE_UNLOCKED; #endif } @@ -1591,29 +1593,95 @@ static void __cpuinit init_hrtimers_cpu(int cpu) #ifdef CONFIG_HOTPLUG_CPU -static void migrate_hrtimer_list(struct hrtimer_clock_base *old_base, - struct hrtimer_clock_base *new_base) +static int migrate_hrtimer_list(struct hrtimer_clock_base *old_base, + struct hrtimer_clock_base *new_base, int dcpu) { struct hrtimer *timer; struct rb_node *node; + int raise = 0; while ((node = rb_first(&old_base->active))) { timer = rb_entry(node, struct hrtimer, node); BUG_ON(hrtimer_callback_running(timer)); debug_hrtimer_deactivate(timer); - __remove_hrtimer(timer, old_base, HRTIMER_STATE_INACTIVE, 0); + + /* + * Should not happen. Per CPU timers should be + * canceled _before_ the migration code is called + */ + if (timer->cb_mode == HRTIMER_CB_IRQSAFE_PERCPU) { + __remove_hrtimer(timer, old_base, + HRTIMER_STATE_INACTIVE, 0); + WARN(1, "hrtimer (%p %p)active but cpu %d dead\n", + timer, timer->function, dcpu); + continue; + } + + /* + * Mark it as STATE_MIGRATE not INACTIVE otherwise the + * timer could be seen as !active and just vanish away + * under us on another CPU + */ + __remove_hrtimer(timer, old_base, HRTIMER_STATE_MIGRATE, 0); timer->base = new_base; /* * Enqueue the timer. Allow reprogramming of the event device */ enqueue_hrtimer(timer, new_base, 1); + +#ifdef CONFIG_HIGH_RES_TIMERS + /* + * Happens with high res enabled when the timer was + * already expired and the callback mode is + * HRTIMER_CB_IRQSAFE_UNLOCKED (hrtimer_sleeper). The + * enqueue code does not move them to the soft irq + * pending list for performance/latency reasons, but + * in the migration state, we need to do that + * otherwise we end up with a stale timer. + */ + if (timer->state == HRTIMER_STATE_MIGRATE) { + timer->state = HRTIMER_STATE_PENDING; + list_add_tail(&timer->cb_entry, + &new_base->cpu_base->cb_pending); + raise = 1; + } +#endif + /* Clear the migration state bit */ + timer->state &= ~HRTIMER_STATE_MIGRATE; + } + return raise; +} + +#ifdef CONFIG_HIGH_RES_TIMERS +static int migrate_hrtimer_pending(struct hrtimer_cpu_base *old_base, + struct hrtimer_cpu_base *new_base) +{ + struct hrtimer *timer; + int raise = 0; + + while (!list_empty(&old_base->cb_pending)) { + timer = list_entry(old_base->cb_pending.next, + struct hrtimer, cb_entry); + + __remove_hrtimer(timer, timer->base, HRTIMER_STATE_PENDING, 0); + timer->base = &new_base->clock_base[timer->base->index]; + list_add_tail(&timer->cb_entry, &new_base->cb_pending); + raise = 1; } + return raise; +} +#else +static int migrate_hrtimer_pending(struct hrtimer_cpu_base *old_base, + struct hrtimer_cpu_base *new_base) +{ + return 0; } +#endif static void migrate_hrtimers(int cpu) { struct hrtimer_cpu_base *old_base, *new_base; - int i; + int i, raise = 0; BUG_ON(cpu_online(cpu)); old_base = &per_cpu(hrtimer_bases, cpu); @@ -1626,14 +1694,21 @@ static void migrate_hrtimers(int cpu) spin_lock_nested(&old_base->lock, SINGLE_DEPTH_NESTING); for (i = 0; i < HRTIMER_MAX_CLOCK_BASES; i++) { - migrate_hrtimer_list(&old_base->clock_base[i], - &new_base->clock_base[i]); + if (migrate_hrtimer_list(&old_base->clock_base[i], + &new_base->clock_base[i], cpu)) + raise = 1; } + if (migrate_hrtimer_pending(old_base, new_base)) + raise = 1; + spin_unlock(&old_base->lock); spin_unlock(&new_base->lock); local_irq_enable(); put_cpu_var(hrtimer_bases); + + if (raise) + hrtimer_raise_softirq(); } #endif /* CONFIG_HOTPLUG_CPU */ diff --git a/kernel/kexec.c b/kernel/kexec.c index 59f3f0df35d..aef265325cd 100644 --- a/kernel/kexec.c +++ b/kernel/kexec.c @@ -753,8 +753,14 @@ static struct page *kimage_alloc_page(struct kimage *image, *old = addr | (*old & ~PAGE_MASK); /* The old page I have found cannot be a - * destination page, so return it. + * destination page, so return it if it's + * gfp_flags honor the ones passed in. */ + if (!(gfp_mask & __GFP_HIGHMEM) && + PageHighMem(old_page)) { + kimage_free_pages(old_page); + continue; + } addr = old_addr; page = old_page; break; diff --git a/kernel/kgdb.c b/kernel/kgdb.c index eaa21fc9ad1..25d955dbb98 100644 --- a/kernel/kgdb.c +++ b/kernel/kgdb.c @@ -488,7 +488,7 @@ static int write_mem_msg(int binary) if (err) return err; if (CACHE_FLUSH_IS_SAFE) - flush_icache_range(addr, addr + length + 1); + flush_icache_range(addr, addr + length); return 0; } @@ -1462,7 +1462,7 @@ acquirelock: * Get the passive CPU lock which will hold all the non-primary * CPU in a spin state while the debugger is active */ - if (!kgdb_single_step || !kgdb_contthread) { + if (!kgdb_single_step) { for (i = 0; i < NR_CPUS; i++) atomic_set(&passive_cpu_wait[i], 1); } @@ -1475,7 +1475,7 @@ acquirelock: #ifdef CONFIG_SMP /* Signal the other CPUs to enter kgdb_wait() */ - if ((!kgdb_single_step || !kgdb_contthread) && kgdb_do_roundup) + if ((!kgdb_single_step) && kgdb_do_roundup) kgdb_roundup_cpus(flags); #endif @@ -1494,7 +1494,7 @@ acquirelock: kgdb_post_primary_code(ks->linux_regs, ks->ex_vector, ks->err_code); kgdb_deactivate_sw_breakpoints(); kgdb_single_step = 0; - kgdb_contthread = NULL; + kgdb_contthread = current; exception_level = 0; /* Talk to debugger with gdbserial protocol */ @@ -1508,7 +1508,7 @@ acquirelock: kgdb_info[ks->cpu].task = NULL; atomic_set(&cpu_in_kgdb[ks->cpu], 0); - if (!kgdb_single_step || !kgdb_contthread) { + if (!kgdb_single_step) { for (i = NR_CPUS-1; i >= 0; i--) atomic_set(&passive_cpu_wait[i], 0); /* diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c index e36d5798cbf..5131e547116 100644 --- a/kernel/posix-timers.c +++ b/kernel/posix-timers.c @@ -441,7 +441,7 @@ static struct k_itimer * alloc_posix_timer(void) return tmr; if (unlikely(!(tmr->sigq = sigqueue_alloc()))) { kmem_cache_free(posix_timers_cache, tmr); - tmr = NULL; + return NULL; } memset(&tmr->sigq->info, 0, sizeof(siginfo_t)); return tmr; diff --git a/kernel/sched.c b/kernel/sched.c index 98890807375..ad1962dc0aa 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -201,7 +201,7 @@ void init_rt_bandwidth(struct rt_bandwidth *rt_b, u64 period, u64 runtime) hrtimer_init(&rt_b->rt_period_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); rt_b->rt_period_timer.function = sched_rt_period_timer; - rt_b->rt_period_timer.cb_mode = HRTIMER_CB_IRQSAFE_NO_SOFTIRQ; + rt_b->rt_period_timer.cb_mode = HRTIMER_CB_IRQSAFE_UNLOCKED; } static void start_rt_bandwidth(struct rt_bandwidth *rt_b) @@ -1087,7 +1087,7 @@ hotplug_hrtick(struct notifier_block *nfb, unsigned long action, void *hcpu) return NOTIFY_DONE; } -static void init_hrtick(void) +static __init void init_hrtick(void) { hotcpu_notifier(hotplug_hrtick, 0); } @@ -1119,7 +1119,7 @@ static void init_rq_hrtick(struct rq *rq) hrtimer_init(&rq->hrtick_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); rq->hrtick_timer.function = hrtick; - rq->hrtick_timer.cb_mode = HRTIMER_CB_IRQSAFE_NO_SOFTIRQ; + rq->hrtick_timer.cb_mode = HRTIMER_CB_IRQSAFE_PERCPU; } #else static inline void hrtick_clear(struct rq *rq) diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c index f1f3eee2811..cb01cd8f919 100644 --- a/kernel/time/tick-broadcast.c +++ b/kernel/time/tick-broadcast.c @@ -235,7 +235,8 @@ static void tick_do_broadcast_on_off(void *why) case CLOCK_EVT_NOTIFY_BROADCAST_FORCE: if (!cpu_isset(cpu, tick_broadcast_mask)) { cpu_set(cpu, tick_broadcast_mask); - if (td->mode == TICKDEV_MODE_PERIODIC) + if (tick_broadcast_device.mode == + TICKDEV_MODE_PERIODIC) clockevents_shutdown(dev); } if (*reason == CLOCK_EVT_NOTIFY_BROADCAST_FORCE) @@ -245,7 +246,8 @@ static void tick_do_broadcast_on_off(void *why) if (!tick_broadcast_force && cpu_isset(cpu, tick_broadcast_mask)) { cpu_clear(cpu, tick_broadcast_mask); - if (td->mode == TICKDEV_MODE_PERIODIC) + if (tick_broadcast_device.mode == + TICKDEV_MODE_PERIODIC) tick_setup_periodic(dev, 0); } break; @@ -575,4 +577,12 @@ void tick_shutdown_broadcast_oneshot(unsigned int *cpup) spin_unlock_irqrestore(&tick_broadcast_lock, flags); } +/* + * Check, whether the broadcast device is in one shot mode + */ +int tick_broadcast_oneshot_active(void) +{ + return tick_broadcast_device.mode == TICKDEV_MODE_ONESHOT; +} + #endif diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c index 019315ebf9d..df12434b43c 100644 --- a/kernel/time/tick-common.c +++ b/kernel/time/tick-common.c @@ -33,7 +33,7 @@ DEFINE_PER_CPU(struct tick_device, tick_cpu_device); */ ktime_t tick_next_period; ktime_t tick_period; -int tick_do_timer_cpu __read_mostly = -1; +int tick_do_timer_cpu __read_mostly = TICK_DO_TIMER_BOOT; DEFINE_SPINLOCK(tick_device_lock); /* @@ -109,7 +109,8 @@ void tick_setup_periodic(struct clock_event_device *dev, int broadcast) if (!tick_device_is_functional(dev)) return; - if (dev->features & CLOCK_EVT_FEAT_PERIODIC) { + if ((dev->features & CLOCK_EVT_FEAT_PERIODIC) && + !tick_broadcast_oneshot_active()) { clockevents_set_mode(dev, CLOCK_EVT_MODE_PERIODIC); } else { unsigned long seq; @@ -148,7 +149,7 @@ static void tick_setup_device(struct tick_device *td, * If no cpu took the do_timer update, assign it to * this cpu: */ - if (tick_do_timer_cpu == -1) { + if (tick_do_timer_cpu == TICK_DO_TIMER_BOOT) { tick_do_timer_cpu = cpu; tick_next_period = ktime_get(); tick_period = ktime_set(0, NSEC_PER_SEC / HZ); @@ -300,7 +301,8 @@ static void tick_shutdown(unsigned int *cpup) if (*cpup == tick_do_timer_cpu) { int cpu = first_cpu(cpu_online_map); - tick_do_timer_cpu = (cpu != NR_CPUS) ? cpu : -1; + tick_do_timer_cpu = (cpu != NR_CPUS) ? cpu : + TICK_DO_TIMER_NONE; } spin_unlock_irqrestore(&tick_device_lock, flags); } diff --git a/kernel/time/tick-internal.h b/kernel/time/tick-internal.h index 6e9db9734aa..469248782c2 100644 --- a/kernel/time/tick-internal.h +++ b/kernel/time/tick-internal.h @@ -1,6 +1,10 @@ /* * tick internal variable and functions used by low/high res code */ + +#define TICK_DO_TIMER_NONE -1 +#define TICK_DO_TIMER_BOOT -2 + DECLARE_PER_CPU(struct tick_device, tick_cpu_device); extern spinlock_t tick_device_lock; extern ktime_t tick_next_period; @@ -31,6 +35,7 @@ extern void tick_broadcast_oneshot_control(unsigned long reason); extern void tick_broadcast_switch_to_oneshot(void); extern void tick_shutdown_broadcast_oneshot(unsigned int *cpup); extern int tick_resume_broadcast_oneshot(struct clock_event_device *bc); +extern int tick_broadcast_oneshot_active(void); # else /* BROADCAST */ static inline void tick_broadcast_setup_oneshot(struct clock_event_device *bc) { @@ -39,6 +44,7 @@ static inline void tick_broadcast_setup_oneshot(struct clock_event_device *bc) static inline void tick_broadcast_oneshot_control(unsigned long reason) { } static inline void tick_broadcast_switch_to_oneshot(void) { } static inline void tick_shutdown_broadcast_oneshot(unsigned int *cpup) { } +static inline int tick_broadcast_oneshot_active(void) { return 0; } # endif /* !BROADCAST */ #else /* !ONESHOT */ @@ -68,6 +74,7 @@ static inline int tick_resume_broadcast_oneshot(struct clock_event_device *bc) { return 0; } +static inline int tick_broadcast_oneshot_active(void) { return 0; } #endif /* !TICK_ONESHOT */ /* diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index a87b0468568..cb02324bdb8 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c @@ -75,6 +75,9 @@ static void tick_do_update_jiffies64(ktime_t now) incr * ticks); } do_timer(++ticks); + + /* Keep the tick_next_period variable up to date */ + tick_next_period = ktime_add(last_jiffies_update, tick_period); } write_sequnlock(&xtime_lock); } @@ -221,7 +224,7 @@ void tick_nohz_stop_sched_tick(int inidle) */ if (unlikely(!cpu_online(cpu))) { if (cpu == tick_do_timer_cpu) - tick_do_timer_cpu = -1; + tick_do_timer_cpu = TICK_DO_TIMER_NONE; } if (unlikely(ts->nohz_mode == NOHZ_MODE_INACTIVE)) @@ -303,7 +306,7 @@ void tick_nohz_stop_sched_tick(int inidle) * invoked. */ if (cpu == tick_do_timer_cpu) - tick_do_timer_cpu = -1; + tick_do_timer_cpu = TICK_DO_TIMER_NONE; ts->idle_sleeps++; @@ -468,7 +471,7 @@ static void tick_nohz_handler(struct clock_event_device *dev) * this duty, then the jiffies update is still serialized by * xtime_lock. */ - if (unlikely(tick_do_timer_cpu == -1)) + if (unlikely(tick_do_timer_cpu == TICK_DO_TIMER_NONE)) tick_do_timer_cpu = cpu; /* Check, if the jiffies need an update */ @@ -570,7 +573,7 @@ static enum hrtimer_restart tick_sched_timer(struct hrtimer *timer) * this duty, then the jiffies update is still serialized by * xtime_lock. */ - if (unlikely(tick_do_timer_cpu == -1)) + if (unlikely(tick_do_timer_cpu == TICK_DO_TIMER_NONE)) tick_do_timer_cpu = cpu; #endif @@ -622,7 +625,7 @@ void tick_setup_sched_timer(void) */ hrtimer_init(&ts->sched_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS); ts->sched_timer.function = tick_sched_timer; - ts->sched_timer.cb_mode = HRTIMER_CB_IRQSAFE_NO_SOFTIRQ; + ts->sched_timer.cb_mode = HRTIMER_CB_IRQSAFE_PERCPU; /* Get the next period (per cpu) */ ts->sched_timer.expires = tick_init_jiffy_update(); diff --git a/kernel/trace/trace_sysprof.c b/kernel/trace/trace_sysprof.c index bb948e52ce2..db58fb66a13 100644 --- a/kernel/trace/trace_sysprof.c +++ b/kernel/trace/trace_sysprof.c @@ -202,7 +202,7 @@ static void start_stack_timer(int cpu) hrtimer_init(hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); hrtimer->function = stack_trace_timer_fn; - hrtimer->cb_mode = HRTIMER_CB_IRQSAFE_NO_SOFTIRQ; + hrtimer->cb_mode = HRTIMER_CB_IRQSAFE_PERCPU; hrtimer_start(hrtimer, ns_to_ktime(sample_period), HRTIMER_MODE_REL); } diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 0f1f7a7374b..36896f3eb7f 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -250,6 +250,14 @@ static struct mem_cgroup *mem_cgroup_from_cont(struct cgroup *cont) struct mem_cgroup *mem_cgroup_from_task(struct task_struct *p) { + /* + * mm_update_next_owner() may clear mm->owner to NULL + * if it races with swapoff, page migration, etc. + * So this can be called with p == NULL. + */ + if (unlikely(!p)) + return NULL; + return container_of(task_subsys_state(p, mem_cgroup_subsys_id), struct mem_cgroup, css); } @@ -549,6 +557,11 @@ static int mem_cgroup_charge_common(struct page *page, struct mm_struct *mm, if (likely(!memcg)) { rcu_read_lock(); mem = mem_cgroup_from_task(rcu_dereference(mm->owner)); + if (unlikely(!mem)) { + rcu_read_unlock(); + kmem_cache_free(page_cgroup_cache, pc); + return 0; + } /* * For every charge from the cgroup, increment reference count */ @@ -801,11 +814,16 @@ int mem_cgroup_shrink_usage(struct mm_struct *mm, gfp_t gfp_mask) rcu_read_lock(); mem = mem_cgroup_from_task(rcu_dereference(mm->owner)); + if (unlikely(!mem)) { + rcu_read_unlock(); + return 0; + } css_get(&mem->css); rcu_read_unlock(); do { progress = try_to_free_mem_cgroup_pages(mem, gfp_mask); + progress += res_counter_check_under_limit(&mem->res); } while (!progress && --retry); css_put(&mem->css); diff --git a/mm/page_alloc.c b/mm/page_alloc.c index e293c58bea5..27b8681139f 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -268,13 +268,14 @@ void prep_compound_page(struct page *page, unsigned long order) { int i; int nr_pages = 1 << order; + struct page *p = page + 1; set_compound_page_dtor(page, free_compound_page); set_compound_order(page, order); __SetPageHead(page); - for (i = 1; i < nr_pages; i++) { - struct page *p = page + i; - + for (i = 1; i < nr_pages; i++, p++) { + if (unlikely((i & (MAX_ORDER_NR_PAGES - 1)) == 0)) + p = pfn_to_page(page_to_pfn(page) + i); __SetPageTail(p); p->first_page = page; } @@ -284,6 +285,7 @@ static void destroy_compound_page(struct page *page, unsigned long order) { int i; int nr_pages = 1 << order; + struct page *p = page + 1; if (unlikely(compound_order(page) != order)) bad_page(page); @@ -291,8 +293,9 @@ static void destroy_compound_page(struct page *page, unsigned long order) if (unlikely(!PageHead(page))) bad_page(page); __ClearPageHead(page); - for (i = 1; i < nr_pages; i++) { - struct page *p = page + i; + for (i = 1; i < nr_pages; i++, p++) { + if (unlikely((i & (MAX_ORDER_NR_PAGES - 1)) == 0)) + p = pfn_to_page(page_to_pfn(page) + i); if (unlikely(!PageTail(p) | (p->first_page != page))) diff --git a/mm/page_isolation.c b/mm/page_isolation.c index c69f84fe038..b70a7fec1ff 100644 --- a/mm/page_isolation.c +++ b/mm/page_isolation.c @@ -114,8 +114,10 @@ __test_page_isolated_in_pageblock(unsigned long pfn, unsigned long end_pfn) int test_pages_isolated(unsigned long start_pfn, unsigned long end_pfn) { - unsigned long pfn; + unsigned long pfn, flags; struct page *page; + struct zone *zone; + int ret; pfn = start_pfn; /* @@ -131,7 +133,9 @@ int test_pages_isolated(unsigned long start_pfn, unsigned long end_pfn) if (pfn < end_pfn) return -EBUSY; /* Check all pages are free or Marked as ISOLATED */ - if (__test_page_isolated_in_pageblock(start_pfn, end_pfn)) - return 0; - return -EBUSY; + zone = page_zone(pfn_to_page(pfn)); + spin_lock_irqsave(&zone->lock, flags); + ret = __test_page_isolated_in_pageblock(start_pfn, end_pfn); + spin_unlock_irqrestore(&zone->lock, flags); + return ret ? 0 : -EBUSY; } diff --git a/mm/tiny-shmem.c b/mm/tiny-shmem.c index ae532f50194..8d7a27a6335 100644 --- a/mm/tiny-shmem.c +++ b/mm/tiny-shmem.c @@ -65,31 +65,31 @@ struct file *shmem_file_setup(char *name, loff_t size, unsigned long flags) if (!dentry) goto put_memory; + error = -ENFILE; + file = get_empty_filp(); + if (!file) + goto put_dentry; + error = -ENOSPC; inode = ramfs_get_inode(root->d_sb, S_IFREG | S_IRWXUGO, 0); if (!inode) - goto put_dentry; + goto close_file; d_instantiate(dentry, inode); - error = -ENFILE; - file = alloc_file(shm_mnt, dentry, FMODE_WRITE | FMODE_READ, - &ramfs_file_operations); - if (!file) - goto put_dentry; - + inode->i_size = size; inode->i_nlink = 0; /* It is unlinked */ + init_file(file, shm_mnt, dentry, FMODE_WRITE | FMODE_READ, + &ramfs_file_operations); - /* notify everyone as to the change of file size */ - error = do_truncate(dentry, size, 0, file); - if (error < 0) +#ifndef CONFIG_MMU + error = ramfs_nommu_expand_for_mapping(inode, size); + if (error) goto close_file; - +#endif return file; close_file: put_filp(file); - return ERR_PTR(error); - put_dentry: dput(dentry); put_memory: diff --git a/net/9p/client.c b/net/9p/client.c index 2ffe40cf2f0..10e320307ec 100644 --- a/net/9p/client.c +++ b/net/9p/client.c @@ -75,7 +75,6 @@ static int parse_opts(char *opts, struct p9_client *clnt) int option; int ret = 0; - clnt->trans_mod = v9fs_default_trans(); clnt->dotu = 1; clnt->msize = 8192; @@ -108,7 +107,7 @@ static int parse_opts(char *opts, struct p9_client *clnt) clnt->msize = option; break; case Opt_trans: - clnt->trans_mod = v9fs_match_trans(&args[0]); + clnt->trans_mod = v9fs_get_trans_by_name(&args[0]); break; case Opt_legacy: clnt->dotu = 0; @@ -117,6 +116,10 @@ static int parse_opts(char *opts, struct p9_client *clnt) continue; } } + + if (!clnt->trans_mod) + clnt->trans_mod = v9fs_get_default_trans(); + kfree(options); return ret; } @@ -150,6 +153,7 @@ struct p9_client *p9_client_create(const char *dev_name, char *options) if (!clnt) return ERR_PTR(-ENOMEM); + clnt->trans_mod = NULL; clnt->trans = NULL; spin_lock_init(&clnt->lock); INIT_LIST_HEAD(&clnt->fidlist); @@ -235,6 +239,8 @@ void p9_client_destroy(struct p9_client *clnt) clnt->trans = NULL; } + v9fs_put_trans(clnt->trans_mod); + list_for_each_entry_safe(fid, fidptr, &clnt->fidlist, flist) p9_fid_destroy(fid); diff --git a/net/9p/conv.c b/net/9p/conv.c index 44547201f5b..5ad3a3bd73b 100644 --- a/net/9p/conv.c +++ b/net/9p/conv.c @@ -451,8 +451,10 @@ p9_put_data(struct cbuf *bufp, const char *data, int count, unsigned char **pdata) { *pdata = buf_alloc(bufp, count); + if (*pdata == NULL) + return -ENOMEM; memmove(*pdata, data, count); - return count; + return 0; } static int @@ -460,6 +462,8 @@ p9_put_user_data(struct cbuf *bufp, const char __user *data, int count, unsigned char **pdata) { *pdata = buf_alloc(bufp, count); + if (*pdata == NULL) + return -ENOMEM; return copy_from_user(*pdata, data, count); } diff --git a/net/9p/mod.c b/net/9p/mod.c index bdee1fb7cc6..1084feb24cb 100644 --- a/net/9p/mod.c +++ b/net/9p/mod.c @@ -31,6 +31,7 @@ #include <linux/parser.h> #include <net/9p/transport.h> #include <linux/list.h> +#include <linux/spinlock.h> #ifdef CONFIG_NET_9P_DEBUG unsigned int p9_debug_level = 0; /* feature-rific global debug level */ @@ -44,8 +45,8 @@ MODULE_PARM_DESC(debug, "9P debugging level"); * */ +static DEFINE_SPINLOCK(v9fs_trans_lock); static LIST_HEAD(v9fs_trans_list); -static struct p9_trans_module *v9fs_default_transport; /** * v9fs_register_trans - register a new transport with 9p @@ -54,48 +55,87 @@ static struct p9_trans_module *v9fs_default_transport; */ void v9fs_register_trans(struct p9_trans_module *m) { + spin_lock(&v9fs_trans_lock); list_add_tail(&m->list, &v9fs_trans_list); - if (m->def) - v9fs_default_transport = m; + spin_unlock(&v9fs_trans_lock); } EXPORT_SYMBOL(v9fs_register_trans); /** - * v9fs_match_trans - match transport versus registered transports + * v9fs_unregister_trans - unregister a 9p transport + * @m: the transport to remove + * + */ +void v9fs_unregister_trans(struct p9_trans_module *m) +{ + spin_lock(&v9fs_trans_lock); + list_del_init(&m->list); + spin_unlock(&v9fs_trans_lock); +} +EXPORT_SYMBOL(v9fs_unregister_trans); + +/** + * v9fs_get_trans_by_name - get transport with the matching name * @name: string identifying transport * */ -struct p9_trans_module *v9fs_match_trans(const substring_t *name) +struct p9_trans_module *v9fs_get_trans_by_name(const substring_t *name) { - struct list_head *p; - struct p9_trans_module *t = NULL; - - list_for_each(p, &v9fs_trans_list) { - t = list_entry(p, struct p9_trans_module, list); - if (strncmp(t->name, name->from, name->to-name->from) == 0) - return t; - } - return NULL; + struct p9_trans_module *t, *found = NULL; + + spin_lock(&v9fs_trans_lock); + + list_for_each_entry(t, &v9fs_trans_list, list) + if (strncmp(t->name, name->from, name->to-name->from) == 0 && + try_module_get(t->owner)) { + found = t; + break; + } + + spin_unlock(&v9fs_trans_lock); + return found; } -EXPORT_SYMBOL(v9fs_match_trans); +EXPORT_SYMBOL(v9fs_get_trans_by_name); /** - * v9fs_default_trans - returns pointer to default transport + * v9fs_get_default_trans - get the default transport * */ -struct p9_trans_module *v9fs_default_trans(void) +struct p9_trans_module *v9fs_get_default_trans(void) { - if (v9fs_default_transport) - return v9fs_default_transport; - else if (!list_empty(&v9fs_trans_list)) - return list_first_entry(&v9fs_trans_list, - struct p9_trans_module, list); - else - return NULL; + struct p9_trans_module *t, *found = NULL; + + spin_lock(&v9fs_trans_lock); + + list_for_each_entry(t, &v9fs_trans_list, list) + if (t->def && try_module_get(t->owner)) { + found = t; + break; + } + + if (!found) + list_for_each_entry(t, &v9fs_trans_list, list) + if (try_module_get(t->owner)) { + found = t; + break; + } + + spin_unlock(&v9fs_trans_lock); + return found; } -EXPORT_SYMBOL(v9fs_default_trans); +EXPORT_SYMBOL(v9fs_get_default_trans); +/** + * v9fs_put_trans - put trans + * @m: transport to put + * + */ +void v9fs_put_trans(struct p9_trans_module *m) +{ + if (m) + module_put(m->owner); +} /** * v9fs_init - Initialize module @@ -120,6 +160,8 @@ static int __init init_p9(void) static void __exit exit_p9(void) { printk(KERN_INFO "Unloading 9P2000 support\n"); + + p9_trans_fd_exit(); } module_init(init_p9) diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c index cdf137af7ad..d652baf5ff9 100644 --- a/net/9p/trans_fd.c +++ b/net/9p/trans_fd.c @@ -151,7 +151,6 @@ struct p9_mux_poll_task { * @trans: reference to transport instance for this connection * @tagpool: id accounting for transactions * @err: error state - * @equeue: event wait_q (?) * @req_list: accounting for requests which have been sent * @unsent_req_list: accounting for requests that haven't been sent * @rcall: current response &p9_fcall structure @@ -178,7 +177,6 @@ struct p9_conn { struct p9_trans *trans; struct p9_idpool *tagpool; int err; - wait_queue_head_t equeue; struct list_head req_list; struct list_head unsent_req_list; struct p9_fcall *rcall; @@ -240,22 +238,6 @@ static int p9_conn_rpcnb(struct p9_conn *m, struct p9_fcall *tc, static void p9_conn_cancel(struct p9_conn *m, int err); -static int p9_mux_global_init(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(p9_mux_poll_tasks); i++) - p9_mux_poll_tasks[i].task = NULL; - - p9_mux_wq = create_workqueue("v9fs"); - if (!p9_mux_wq) { - printk(KERN_WARNING "v9fs: mux: creating workqueue failed\n"); - return -ENOMEM; - } - - return 0; -} - static u16 p9_mux_get_tag(struct p9_conn *m) { int tag; @@ -409,11 +391,11 @@ static void p9_mux_poll_stop(struct p9_conn *m) static struct p9_conn *p9_conn_create(struct p9_trans *trans) { int i, n; - struct p9_conn *m, *mtmp; + struct p9_conn *m; P9_DPRINTK(P9_DEBUG_MUX, "transport %p msize %d\n", trans, trans->msize); - m = kmalloc(sizeof(struct p9_conn), GFP_KERNEL); + m = kzalloc(sizeof(struct p9_conn), GFP_KERNEL); if (!m) return ERR_PTR(-ENOMEM); @@ -424,25 +406,14 @@ static struct p9_conn *p9_conn_create(struct p9_trans *trans) m->trans = trans; m->tagpool = p9_idpool_create(); if (IS_ERR(m->tagpool)) { - mtmp = ERR_PTR(-ENOMEM); kfree(m); - return mtmp; + return ERR_PTR(-ENOMEM); } - m->err = 0; - init_waitqueue_head(&m->equeue); INIT_LIST_HEAD(&m->req_list); INIT_LIST_HEAD(&m->unsent_req_list); - m->rcall = NULL; - m->rpos = 0; - m->rbuf = NULL; - m->wpos = m->wsize = 0; - m->wbuf = NULL; INIT_WORK(&m->rq, p9_read_work); INIT_WORK(&m->wq, p9_write_work); - m->wsched = 0; - memset(&m->poll_waddr, 0, sizeof(m->poll_waddr)); - m->poll_task = NULL; n = p9_mux_poll_start(m); if (n) { kfree(m); @@ -463,10 +434,8 @@ static struct p9_conn *p9_conn_create(struct p9_trans *trans) for (i = 0; i < ARRAY_SIZE(m->poll_waddr); i++) { if (IS_ERR(m->poll_waddr[i])) { p9_mux_poll_stop(m); - mtmp = (void *)m->poll_waddr; /* the error code */ kfree(m); - m = mtmp; - break; + return (void *)m->poll_waddr; /* the error code */ } } @@ -483,18 +452,13 @@ static void p9_conn_destroy(struct p9_conn *m) { P9_DPRINTK(P9_DEBUG_MUX, "mux %p prev %p next %p\n", m, m->mux_list.prev, m->mux_list.next); - p9_conn_cancel(m, -ECONNRESET); - - if (!list_empty(&m->req_list)) { - /* wait until all processes waiting on this session exit */ - P9_DPRINTK(P9_DEBUG_MUX, - "mux %p waiting for empty request queue\n", m); - wait_event_timeout(m->equeue, (list_empty(&m->req_list)), 5000); - P9_DPRINTK(P9_DEBUG_MUX, "mux %p request queue empty: %d\n", m, - list_empty(&m->req_list)); - } p9_mux_poll_stop(m); + cancel_work_sync(&m->rq); + cancel_work_sync(&m->wq); + + p9_conn_cancel(m, -ECONNRESET); + m->trans = NULL; p9_idpool_destroy(m->tagpool); kfree(m); @@ -840,8 +804,6 @@ static void p9_read_work(struct work_struct *work) (*req->cb) (req, req->cba); else kfree(req->rcall); - - wake_up(&m->equeue); } } else { if (err >= 0 && rcall->id != P9_RFLUSH) @@ -908,8 +870,10 @@ static struct p9_req *p9_send_request(struct p9_conn *m, else n = p9_mux_get_tag(m); - if (n < 0) + if (n < 0) { + kfree(req); return ERR_PTR(-ENOMEM); + } p9_set_tag(tc, n); @@ -984,8 +948,6 @@ static void p9_mux_flush_cb(struct p9_req *freq, void *a) (*req->cb) (req, req->cba); else kfree(req->rcall); - - wake_up(&m->equeue); } kfree(freq->tcall); @@ -1191,8 +1153,6 @@ void p9_conn_cancel(struct p9_conn *m, int err) else kfree(req->rcall); } - - wake_up(&m->equeue); } /** @@ -1370,7 +1330,6 @@ p9_fd_poll(struct p9_trans *trans, struct poll_table_struct *pt) { int ret, n; struct p9_trans_fd *ts = NULL; - mm_segment_t oldfs; if (trans && trans->status == Connected) ts = trans->priv; @@ -1384,24 +1343,17 @@ p9_fd_poll(struct p9_trans *trans, struct poll_table_struct *pt) if (!ts->wr->f_op || !ts->wr->f_op->poll) return -EIO; - oldfs = get_fs(); - set_fs(get_ds()); - ret = ts->rd->f_op->poll(ts->rd, pt); if (ret < 0) - goto end; + return ret; if (ts->rd != ts->wr) { n = ts->wr->f_op->poll(ts->wr, pt); - if (n < 0) { - ret = n; - goto end; - } + if (n < 0) + return n; ret = (ret & ~POLLOUT) | (n & ~POLLIN); } -end: - set_fs(oldfs); return ret; } @@ -1629,6 +1581,7 @@ static struct p9_trans_module p9_tcp_trans = { .maxsize = MAX_SOCK_BUF, .def = 1, .create = p9_trans_create_tcp, + .owner = THIS_MODULE, }; static struct p9_trans_module p9_unix_trans = { @@ -1636,6 +1589,7 @@ static struct p9_trans_module p9_unix_trans = { .maxsize = MAX_SOCK_BUF, .def = 0, .create = p9_trans_create_unix, + .owner = THIS_MODULE, }; static struct p9_trans_module p9_fd_trans = { @@ -1643,14 +1597,20 @@ static struct p9_trans_module p9_fd_trans = { .maxsize = MAX_SOCK_BUF, .def = 0, .create = p9_trans_create_fd, + .owner = THIS_MODULE, }; int p9_trans_fd_init(void) { - int ret = p9_mux_global_init(); - if (ret) { - printk(KERN_WARNING "9p: starting mux failed\n"); - return ret; + int i; + + for (i = 0; i < ARRAY_SIZE(p9_mux_poll_tasks); i++) + p9_mux_poll_tasks[i].task = NULL; + + p9_mux_wq = create_workqueue("v9fs"); + if (!p9_mux_wq) { + printk(KERN_WARNING "v9fs: mux: creating workqueue failed\n"); + return -ENOMEM; } v9fs_register_trans(&p9_tcp_trans); @@ -1659,4 +1619,12 @@ int p9_trans_fd_init(void) return 0; } -EXPORT_SYMBOL(p9_trans_fd_init); + +void p9_trans_fd_exit(void) +{ + v9fs_unregister_trans(&p9_tcp_trans); + v9fs_unregister_trans(&p9_unix_trans); + v9fs_unregister_trans(&p9_fd_trans); + + destroy_workqueue(p9_mux_wq); +} diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c index 42adc052b14..94912e077a5 100644 --- a/net/9p/trans_virtio.c +++ b/net/9p/trans_virtio.c @@ -528,6 +528,7 @@ static struct p9_trans_module p9_virtio_trans = { .create = p9_virtio_create, .maxsize = PAGE_SIZE*16, .def = 0, + .owner = THIS_MODULE, }; /* The standard init function */ @@ -545,6 +546,7 @@ static int __init p9_virtio_init(void) static void __exit p9_virtio_cleanup(void) { unregister_virtio_driver(&p9_virtio_drv); + v9fs_unregister_trans(&p9_virtio_trans); } module_init(p9_virtio_init); diff --git a/net/core/dev.c b/net/core/dev.c index e719ed29310..e8eb2b47834 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -122,6 +122,7 @@ #include <linux/if_arp.h> #include <linux/if_vlan.h> #include <linux/ip.h> +#include <net/ip.h> #include <linux/ipv6.h> #include <linux/in.h> #include <linux/jhash.h> @@ -1667,7 +1668,7 @@ static u16 simple_tx_hash(struct net_device *dev, struct sk_buff *skb) { u32 addr1, addr2, ports; u32 hash, ihl; - u8 ip_proto; + u8 ip_proto = 0; if (unlikely(!simple_tx_hashrnd_initialized)) { get_random_bytes(&simple_tx_hashrnd, 4); @@ -1676,7 +1677,8 @@ static u16 simple_tx_hash(struct net_device *dev, struct sk_buff *skb) switch (skb->protocol) { case __constant_htons(ETH_P_IP): - ip_proto = ip_hdr(skb)->protocol; + if (!(ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET))) + ip_proto = ip_hdr(skb)->protocol; addr1 = ip_hdr(skb)->saddr; addr2 = ip_hdr(skb)->daddr; ihl = ip_hdr(skb)->ihl; diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 1b4fee20fc9..011478e46c4 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -618,7 +618,7 @@ static void tcp_v4_send_ack(struct sk_buff *skb, u32 seq, u32 ack, ]; } rep; struct ip_reply_arg arg; - struct net *net = dev_net(skb->dev); + struct net *net = dev_net(skb->dst->dev); memset(&rep.th, 0, sizeof(struct tcphdr)); memset(&arg, 0, sizeof(arg)); diff --git a/net/ipv6/netfilter/ip6t_hbh.c b/net/ipv6/netfilter/ip6t_hbh.c index 62e39ace058..26654b26d7f 100644 --- a/net/ipv6/netfilter/ip6t_hbh.c +++ b/net/ipv6/netfilter/ip6t_hbh.c @@ -97,8 +97,6 @@ hbh_mt6(const struct sk_buff *skb, const struct net_device *in, hdrlen -= 2; if (!(optinfo->flags & IP6T_OPTS_OPTS)) { return ret; - } else if (optinfo->flags & IP6T_OPTS_NSTRICT) { - pr_debug("Not strict - not implemented"); } else { pr_debug("Strict "); pr_debug("#%d ", optinfo->optsnr); @@ -177,6 +175,12 @@ hbh_mt6_check(const char *tablename, const void *entry, pr_debug("ip6t_opts: unknown flags %X\n", optsinfo->invflags); return false; } + + if (optsinfo->flags & IP6T_OPTS_NSTRICT) { + pr_debug("ip6t_opts: Not strict - not implemented"); + return false; + } + return true; } diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 9af6115f0f5..63442a1e741 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -2688,6 +2688,8 @@ int __init ip6_route_init(void) if (ret) goto out_kmem_cache; + ip6_dst_blackhole_ops.kmem_cachep = ip6_dst_ops_template.kmem_cachep; + /* Registering of the loopback is done before this portion of code, * the loopback reference in rt6_info will not be taken, do it * manually for init_net */ diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index b585c850a89..10e22fd4822 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -1050,7 +1050,7 @@ static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32 struct tcphdr *th = tcp_hdr(skb), *t1; struct sk_buff *buff; struct flowi fl; - struct net *net = dev_net(skb->dev); + struct net *net = dev_net(skb->dst->dev); struct sock *ctl_sk = net->ipv6.tcp_sk; unsigned int tot_len = sizeof(struct tcphdr); __be32 *topt; diff --git a/net/iucv/iucv.c b/net/iucv/iucv.c index 705959b31e2..d7b54b5bfa6 100644 --- a/net/iucv/iucv.c +++ b/net/iucv/iucv.c @@ -524,7 +524,6 @@ static int iucv_enable(void) get_online_cpus(); for_each_online_cpu(cpu) smp_call_function_single(cpu, iucv_declare_cpu, NULL, 1); - preempt_enable(); if (cpus_empty(iucv_buffer_cpumask)) /* No cpu could declare an iucv buffer. */ goto out_path; @@ -547,7 +546,9 @@ out: */ static void iucv_disable(void) { + get_online_cpus(); on_each_cpu(iucv_retrieve_cpu, NULL, 1); + put_online_cpus(); kfree(iucv_path_table); } diff --git a/net/key/af_key.c b/net/key/af_key.c index d628df97e02..b7f5a1c353e 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c @@ -73,22 +73,18 @@ static int pfkey_can_dump(struct sock *sk) return 0; } -static int pfkey_do_dump(struct pfkey_sock *pfk) +static void pfkey_terminate_dump(struct pfkey_sock *pfk) { - int rc; - - rc = pfk->dump.dump(pfk); - if (rc == -ENOBUFS) - return 0; - - pfk->dump.done(pfk); - pfk->dump.dump = NULL; - pfk->dump.done = NULL; - return rc; + if (pfk->dump.dump) { + pfk->dump.done(pfk); + pfk->dump.dump = NULL; + pfk->dump.done = NULL; + } } static void pfkey_sock_destruct(struct sock *sk) { + pfkey_terminate_dump(pfkey_sk(sk)); skb_queue_purge(&sk->sk_receive_queue); if (!sock_flag(sk, SOCK_DEAD)) { @@ -310,6 +306,18 @@ static int pfkey_broadcast(struct sk_buff *skb, gfp_t allocation, return err; } +static int pfkey_do_dump(struct pfkey_sock *pfk) +{ + int rc; + + rc = pfk->dump.dump(pfk); + if (rc == -ENOBUFS) + return 0; + + pfkey_terminate_dump(pfk); + return rc; +} + static inline void pfkey_hdr_dup(struct sadb_msg *new, struct sadb_msg *orig) { *new = *orig; diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index b599cbba4fb..d68869f966c 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c @@ -1012,6 +1012,29 @@ end: return retval; } +struct sctp_chunk *sctp_make_violation_paramlen( + const struct sctp_association *asoc, + const struct sctp_chunk *chunk, + struct sctp_paramhdr *param) +{ + struct sctp_chunk *retval; + static const char error[] = "The following parameter had invalid length:"; + size_t payload_len = sizeof(error) + sizeof(sctp_errhdr_t) + + sizeof(sctp_paramhdr_t); + + retval = sctp_make_abort(asoc, chunk, payload_len); + if (!retval) + goto nodata; + + sctp_init_cause(retval, SCTP_ERROR_PROTO_VIOLATION, + sizeof(error) + sizeof(sctp_paramhdr_t)); + sctp_addto_chunk(retval, sizeof(error), error); + sctp_addto_param(retval, sizeof(sctp_paramhdr_t), param); + +nodata: + return retval; +} + /* Make a HEARTBEAT chunk. */ struct sctp_chunk *sctp_make_heartbeat(const struct sctp_association *asoc, const struct sctp_transport *transport, @@ -1782,11 +1805,6 @@ static int sctp_process_inv_paramlength(const struct sctp_association *asoc, const struct sctp_chunk *chunk, struct sctp_chunk **errp) { - static const char error[] = "The following parameter had invalid length:"; - size_t payload_len = WORD_ROUND(sizeof(error)) + - sizeof(sctp_paramhdr_t); - - /* This is a fatal error. Any accumulated non-fatal errors are * not reported. */ @@ -1794,14 +1812,7 @@ static int sctp_process_inv_paramlength(const struct sctp_association *asoc, sctp_chunk_free(*errp); /* Create an error chunk and fill it in with our payload. */ - *errp = sctp_make_op_error_space(asoc, chunk, payload_len); - - if (*errp) { - sctp_init_cause(*errp, SCTP_ERROR_PROTO_VIOLATION, - sizeof(error) + sizeof(sctp_paramhdr_t)); - sctp_addto_chunk(*errp, sizeof(error), error); - sctp_addto_param(*errp, sizeof(sctp_paramhdr_t), param); - } + *errp = sctp_make_violation_paramlen(asoc, chunk, param); return 0; } diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index 8848d329aa2..7c622af2ce5 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c @@ -119,7 +119,7 @@ static sctp_disposition_t sctp_sf_violation_paramlen( const struct sctp_endpoint *ep, const struct sctp_association *asoc, const sctp_subtype_t type, - void *arg, + void *arg, void *ext, sctp_cmd_seq_t *commands); static sctp_disposition_t sctp_sf_violation_ctsn( @@ -3425,7 +3425,7 @@ sctp_disposition_t sctp_sf_do_asconf(const struct sctp_endpoint *ep, addr_param = (union sctp_addr_param *)hdr->params; length = ntohs(addr_param->p.length); if (length < sizeof(sctp_paramhdr_t)) - return sctp_sf_violation_paramlen(ep, asoc, type, + return sctp_sf_violation_paramlen(ep, asoc, type, arg, (void *)addr_param, commands); /* Verify the ASCONF chunk before processing it. */ @@ -3433,8 +3433,8 @@ sctp_disposition_t sctp_sf_do_asconf(const struct sctp_endpoint *ep, (sctp_paramhdr_t *)((void *)addr_param + length), (void *)chunk->chunk_end, &err_param)) - return sctp_sf_violation_paramlen(ep, asoc, type, - (void *)&err_param, commands); + return sctp_sf_violation_paramlen(ep, asoc, type, arg, + (void *)err_param, commands); /* ADDIP 5.2 E1) Compare the value of the serial number to the value * the endpoint stored in a new association variable @@ -3542,8 +3542,8 @@ sctp_disposition_t sctp_sf_do_asconf_ack(const struct sctp_endpoint *ep, (sctp_paramhdr_t *)addip_hdr->params, (void *)asconf_ack->chunk_end, &err_param)) - return sctp_sf_violation_paramlen(ep, asoc, type, - (void *)&err_param, commands); + return sctp_sf_violation_paramlen(ep, asoc, type, arg, + (void *)err_param, commands); if (last_asconf) { addip_hdr = (sctp_addiphdr_t *)last_asconf->subh.addip_hdr; @@ -4240,12 +4240,38 @@ static sctp_disposition_t sctp_sf_violation_paramlen( const struct sctp_endpoint *ep, const struct sctp_association *asoc, const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) { - static const char err_str[] = "The following parameter had invalid length:"; + void *arg, void *ext, + sctp_cmd_seq_t *commands) +{ + struct sctp_chunk *chunk = arg; + struct sctp_paramhdr *param = ext; + struct sctp_chunk *abort = NULL; - return sctp_sf_abort_violation(ep, asoc, arg, commands, err_str, - sizeof(err_str)); + if (sctp_auth_recv_cid(SCTP_CID_ABORT, asoc)) + goto discard; + + /* Make the abort chunk. */ + abort = sctp_make_violation_paramlen(asoc, chunk, param); + if (!abort) + goto nomem; + + sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort)); + SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS); + + sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, + SCTP_ERROR(ECONNABORTED)); + sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, + SCTP_PERR(SCTP_ERROR_PROTO_VIOLATION)); + SCTP_DEC_STATS(SCTP_MIB_CURRESTAB); + +discard: + sctp_sf_pdiscard(ep, asoc, SCTP_ST_CHUNK(0), arg, commands); + + SCTP_INC_STATS(SCTP_MIB_ABORTEDS); + + return SCTP_DISPOSITION_ABORT; +nomem: + return SCTP_DISPOSITION_NOMEM; } /* Handle a protocol violation when the peer trying to advance the diff --git a/net/socket.c b/net/socket.c index 8ef8ba81b9e..3e8d4e35c08 100644 --- a/net/socket.c +++ b/net/socket.c @@ -1511,6 +1511,7 @@ out_fd: goto out_put; } +#if 0 #ifdef HAVE_SET_RESTORE_SIGMASK asmlinkage long sys_paccept(int fd, struct sockaddr __user *upeer_sockaddr, int __user *upeer_addrlen, @@ -1564,6 +1565,7 @@ asmlinkage long sys_paccept(int fd, struct sockaddr __user *upeer_sockaddr, return do_accept(fd, upeer_sockaddr, upeer_addrlen, flags); } #endif +#endif asmlinkage long sys_accept(int fd, struct sockaddr __user *upeer_sockaddr, int __user *upeer_addrlen) diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c index ac25b4c0e98..dc50f1e71f7 100644 --- a/net/xfrm/xfrm_output.c +++ b/net/xfrm/xfrm_output.c @@ -27,10 +27,14 @@ static int xfrm_state_check_space(struct xfrm_state *x, struct sk_buff *skb) - skb_headroom(skb); int ntail = dst->dev->needed_tailroom - skb_tailroom(skb); - if (nhead > 0 || ntail > 0) - return pskb_expand_head(skb, nhead, ntail, GFP_ATOMIC); - - return 0; + if (nhead <= 0) { + if (ntail <= 0) + return 0; + nhead = 0; + } else if (ntail < 0) + ntail = 0; + + return pskb_expand_head(skb, nhead, ntail, GFP_ATOMIC); } static int xfrm_output_one(struct sk_buff *skb, int err) diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c index 36b5eedcdc7..3e1057f885c 100644 --- a/scripts/kconfig/conf.c +++ b/scripts/kconfig/conf.c @@ -32,6 +32,7 @@ char *defconfig_file; static int indent = 1; static int valid_stdin = 1; +static int sync_kconfig; static int conf_cnt; static char line[128]; static struct menu *rootEntry; @@ -65,7 +66,7 @@ static void strip(char *str) static void check_stdin(void) { - if (!valid_stdin && input_mode == ask_silent) { + if (!valid_stdin) { printf(_("aborted!\n\n")); printf(_("Console input/output is redirected. ")); printf(_("Run 'make oldconfig' to update configuration.\n\n")); @@ -427,43 +428,6 @@ static void check_conf(struct menu *menu) check_conf(child); } -static void conf_do_update(void) -{ - /* Update until a loop caused no more changes */ - do { - conf_cnt = 0; - check_conf(&rootmenu); - } while (conf_cnt); -} - -static int conf_silent_update(void) -{ - const char *name; - - if (conf_get_changed()) { - name = getenv("KCONFIG_NOSILENTUPDATE"); - if (name && *name) { - fprintf(stderr, - _("\n*** Kernel configuration requires explicit update.\n\n")); - return 1; - } - conf_do_update(); - } - return 0; -} - -static int conf_update(void) -{ - rootEntry = &rootmenu; - conf(&rootmenu); - if (input_mode == ask_all) { - input_mode = ask_silent; - valid_stdin = 1; - } - conf_do_update(); - return 0; -} - int main(int ac, char **av) { int opt; @@ -477,11 +441,11 @@ int main(int ac, char **av) while ((opt = getopt(ac, av, "osdD:nmyrh")) != -1) { switch (opt) { case 'o': - input_mode = ask_new; + input_mode = ask_silent; break; case 's': input_mode = ask_silent; - valid_stdin = isatty(0) && isatty(1) && isatty(2); + sync_kconfig = 1; break; case 'd': input_mode = set_default; @@ -519,6 +483,19 @@ int main(int ac, char **av) name = av[optind]; conf_parse(name); //zconfdump(stdout); + if (sync_kconfig) { + if (stat(".config", &tmpstat)) { + fprintf(stderr, _("***\n" + "*** You have not yet configured your kernel!\n" + "*** (missing kernel .config file)\n" + "***\n" + "*** Please run some configurator (e.g. \"make oldconfig\" or\n" + "*** \"make menuconfig\" or \"make xconfig\").\n" + "***\n")); + exit(1); + } + } + switch (input_mode) { case set_default: if (!defconfig_file) @@ -531,16 +508,6 @@ int main(int ac, char **av) } break; case ask_silent: - if (stat(".config", &tmpstat)) { - printf(_("***\n" - "*** You have not yet configured your kernel!\n" - "*** (missing kernel .config file)\n" - "***\n" - "*** Please run some configurator (e.g. \"make oldconfig\" or\n" - "*** \"make menuconfig\" or \"make xconfig\").\n" - "***\n")); - exit(1); - } case ask_all: case ask_new: conf_read(NULL); @@ -569,6 +536,19 @@ int main(int ac, char **av) default: break; } + + if (sync_kconfig) { + if (conf_get_changed()) { + name = getenv("KCONFIG_NOSILENTUPDATE"); + if (name && *name) { + fprintf(stderr, + _("\n*** Kernel configuration requires explicit update.\n\n")); + return 1; + } + } + valid_stdin = isatty(0) && isatty(1) && isatty(2); + } + switch (input_mode) { case set_no: conf_set_all_new_symbols(def_no); @@ -585,27 +565,38 @@ int main(int ac, char **av) case set_default: conf_set_all_new_symbols(def_default); break; - case ask_silent: case ask_new: - if (conf_silent_update()) - exit(1); - break; case ask_all: - if (conf_update()) - exit(1); + rootEntry = &rootmenu; + conf(&rootmenu); + input_mode = ask_silent; + /* fall through */ + case ask_silent: + /* Update until a loop caused no more changes */ + do { + conf_cnt = 0; + check_conf(&rootmenu); + } while (conf_cnt); break; } - if (conf_write(NULL)) { - fprintf(stderr, _("\n*** Error during writing of the kernel configuration.\n\n")); - exit(1); - } - /* ask_silent is used during the build so we shall update autoconf. - * All other commands are only used to generate a config. - */ - if (input_mode == ask_silent && conf_write_autoconf()) { - fprintf(stderr, _("\n*** Error during writing of the kernel configuration.\n\n")); - return 1; + if (sync_kconfig) { + /* silentoldconfig is used during the build so we shall update autoconf. + * All other commands are only used to generate a config. + */ + if (conf_get_changed() && conf_write(NULL)) { + fprintf(stderr, _("\n*** Error during writing of the kernel configuration.\n\n")); + exit(1); + } + if (conf_write_autoconf()) { + fprintf(stderr, _("\n*** Error during update of the kernel configuration.\n\n")); + return 1; + } + } else { + if (conf_write(NULL)) { + fprintf(stderr, _("\n*** Error during writing of the kernel configuration.\n\n")); + exit(1); + } } return 0; } diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index df6a188b993..b91cf241a53 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -222,8 +222,10 @@ load: continue; if (def == S_DEF_USER) { sym = sym_find(line + 9); - if (!sym) + if (!sym) { + sym_add_change_count(1); break; + } } else { sym = sym_lookup(line + 9, 0); if (sym->type == S_UNKNOWN) @@ -259,8 +261,10 @@ load: } if (def == S_DEF_USER) { sym = sym_find(line + 7); - if (!sym) + if (!sym) { + sym_add_change_count(1); break; + } } else { sym = sym_lookup(line + 7, 0); if (sym->type == S_UNKNOWN) diff --git a/scripts/kernel-doc b/scripts/kernel-doc index ff787e6ff8e..44ee94d2ab7 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -781,6 +781,7 @@ sub output_struct_xml(%) { print " <refsect1>\n"; print " <title>Members</title>\n"; + if ($#{$args{'parameterlist'}} >= 0) { print " <variablelist>\n"; foreach $parameter (@{$args{'parameterlist'}}) { ($parameter =~ /^#/) && next; @@ -798,6 +799,9 @@ sub output_struct_xml(%) { print " </varlistentry>\n"; } print " </variablelist>\n"; + } else { + print " <para>\n None\n </para>\n"; + } print " </refsect1>\n"; output_section_xml(@_); diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index d11a8154500..8551952ef32 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -2737,6 +2737,7 @@ int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr, if (ctx == NULL) goto netlbl_secattr_to_sid_return; + context_init(&ctx_new); ctx_new.user = ctx->user; ctx_new.role = ctx->role; ctx_new.type = ctx->type; @@ -2745,13 +2746,9 @@ int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr, if (ebitmap_netlbl_import(&ctx_new.range.level[0].cat, secattr->attr.mls.cat) != 0) goto netlbl_secattr_to_sid_return; - ctx_new.range.level[1].cat.highbit = - ctx_new.range.level[0].cat.highbit; - ctx_new.range.level[1].cat.node = - ctx_new.range.level[0].cat.node; - } else { - ebitmap_init(&ctx_new.range.level[0].cat); - ebitmap_init(&ctx_new.range.level[1].cat); + memcpy(&ctx_new.range.level[1].cat, + &ctx_new.range.level[0].cat, + sizeof(ctx_new.range.level[0].cat)); } if (mls_context_isvalid(&policydb, &ctx_new) != 1) goto netlbl_secattr_to_sid_return_cleanup; diff --git a/sound/core/pcm.c b/sound/core/pcm.c index 9dd9bc73fe1..ece25c718e9 100644 --- a/sound/core/pcm.c +++ b/sound/core/pcm.c @@ -781,7 +781,7 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream, return -ENODEV; card = pcm->card; - down_read(&card->controls_rwsem); + read_lock(&card->ctl_files_rwlock); list_for_each_entry(kctl, &card->ctl_files, list) { if (kctl->pid == current->pid) { prefer_subdevice = kctl->prefer_pcm_subdevice; @@ -789,7 +789,7 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream, break; } } - up_read(&card->controls_rwsem); + read_unlock(&card->ctl_files_rwlock); switch (stream) { case SNDRV_PCM_STREAM_PLAYBACK: diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index c49b9d9e303..c487025d345 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -1546,16 +1546,10 @@ static int snd_pcm_drop(struct snd_pcm_substream *substream) card = substream->pcm->card; if (runtime->status->state == SNDRV_PCM_STATE_OPEN || - runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED) + runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED || + runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) return -EBADFD; - snd_power_lock(card); - if (runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) { - result = snd_power_wait(card, SNDRV_CTL_POWER_D0); - if (result < 0) - goto _unlock; - } - snd_pcm_stream_lock_irq(substream); /* resume pause */ if (runtime->status->state == SNDRV_PCM_STATE_PAUSED) @@ -1564,8 +1558,7 @@ static int snd_pcm_drop(struct snd_pcm_substream *substream) snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP); /* runtime->control->appl_ptr = runtime->status->hw_ptr; */ snd_pcm_stream_unlock_irq(substream); - _unlock: - snd_power_unlock(card); + return result; } diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c index f7ea7287c59..b917a9f981c 100644 --- a/sound/core/rawmidi.c +++ b/sound/core/rawmidi.c @@ -418,7 +418,7 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file) mutex_lock(&rmidi->open_mutex); while (1) { subdevice = -1; - down_read(&card->controls_rwsem); + read_lock(&card->ctl_files_rwlock); list_for_each_entry(kctl, &card->ctl_files, list) { if (kctl->pid == current->pid) { subdevice = kctl->prefer_rawmidi_subdevice; @@ -426,7 +426,7 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file) break; } } - up_read(&card->controls_rwsem); + read_unlock(&card->ctl_files_rwlock); err = snd_rawmidi_kernel_open(rmidi->card, rmidi->device, subdevice, fflags, rawmidi_file); if (err >= 0) diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index ad994fcab72..f3da621f25c 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -1683,8 +1683,8 @@ static struct snd_pci_quirk stac927x_cfg_tbl[] = { /* Dell 3 stack systems with verb table in BIOS */ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f3, "Dell Inspiron 1420", STAC_DELL_BIOS), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0227, "Dell Vostro 1400 ", STAC_DELL_BIOS), - SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022f, "Dell ", STAC_DELL_BIOS), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022e, "Dell ", STAC_DELL_BIOS), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022f, "Dell Inspiron 1525", STAC_DELL_3ST), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0242, "Dell ", STAC_DELL_BIOS), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0243, "Dell ", STAC_DELL_BIOS), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ff, "Dell ", STAC_DELL_BIOS), diff --git a/sound/ppc/awacs.c b/sound/ppc/awacs.c index 566a6d0daf4..106c48225bb 100644 --- a/sound/ppc/awacs.c +++ b/sound/ppc/awacs.c @@ -621,6 +621,13 @@ static struct snd_kcontrol_new snd_pmac_screamer_mixers_imac[] __initdata = { AWACS_SWITCH("CD Capture Switch", 0, SHIFT_MUX_CD, 0), }; +static struct snd_kcontrol_new snd_pmac_screamer_mixers_g4agp[] __initdata = { + AWACS_VOLUME("Line out Playback Volume", 2, 6, 1), + AWACS_VOLUME("Master Playback Volume", 5, 6, 1), + AWACS_SWITCH("CD Capture Switch", 0, SHIFT_MUX_CD, 0), + AWACS_SWITCH("Line Capture Switch", 0, SHIFT_MUX_MIC, 0), +}; + static struct snd_kcontrol_new snd_pmac_awacs_mixers_pmac7500[] __initdata = { AWACS_VOLUME("Line out Playback Volume", 2, 6, 1), AWACS_SWITCH("CD Capture Switch", 0, SHIFT_MUX_CD, 0), @@ -688,7 +695,10 @@ static struct snd_kcontrol_new snd_pmac_awacs_speaker_vol[] __initdata = { static struct snd_kcontrol_new snd_pmac_awacs_speaker_sw __initdata = AWACS_SWITCH("PC Speaker Playback Switch", 1, SHIFT_SPKMUTE, 1); -static struct snd_kcontrol_new snd_pmac_awacs_speaker_sw_imac __initdata = +static struct snd_kcontrol_new snd_pmac_awacs_speaker_sw_imac1 __initdata = +AWACS_SWITCH("PC Speaker Playback Switch", 1, SHIFT_PAROUT1, 1); + +static struct snd_kcontrol_new snd_pmac_awacs_speaker_sw_imac2 __initdata = AWACS_SWITCH("PC Speaker Playback Switch", 1, SHIFT_PAROUT1, 0); @@ -765,11 +775,12 @@ static void snd_pmac_awacs_resume(struct snd_pmac *chip) #define IS_PM7500 (machine_is_compatible("AAPL,7500")) #define IS_BEIGE (machine_is_compatible("AAPL,Gossamer")) -#define IS_IMAC (machine_is_compatible("PowerMac2,1") \ - || machine_is_compatible("PowerMac2,2") \ +#define IS_IMAC1 (machine_is_compatible("PowerMac2,1")) +#define IS_IMAC2 (machine_is_compatible("PowerMac2,2") \ || machine_is_compatible("PowerMac4,1")) +#define IS_G4AGP (machine_is_compatible("PowerMac3,1")) -static int imac; +static int imac1, imac2; #ifdef PMAC_SUPPORT_AUTOMUTE /* @@ -815,13 +826,18 @@ static void snd_pmac_awacs_update_automute(struct snd_pmac *chip, int do_notify) { int reg = chip->awacs_reg[1] | (MASK_HDMUTE | MASK_SPKMUTE); - if (imac) { + if (imac1) { + reg &= ~MASK_SPKMUTE; + reg |= MASK_PAROUT1; + } else if (imac2) { reg &= ~MASK_SPKMUTE; reg &= ~MASK_PAROUT1; } if (snd_pmac_awacs_detect_headphone(chip)) reg &= ~MASK_HDMUTE; - else if (imac) + else if (imac1) + reg &= ~MASK_PAROUT1; + else if (imac2) reg |= MASK_PAROUT1; else reg &= ~MASK_SPKMUTE; @@ -850,9 +866,13 @@ snd_pmac_awacs_init(struct snd_pmac *chip) { int pm7500 = IS_PM7500; int beige = IS_BEIGE; + int g4agp = IS_G4AGP; + int imac; int err, vol; - imac = IS_IMAC; + imac1 = IS_IMAC1; + imac2 = IS_IMAC2; + imac = imac1 || imac2; /* looks like MASK_GAINLINE triggers something, so we set here * as start-up */ @@ -939,7 +959,7 @@ snd_pmac_awacs_init(struct snd_pmac *chip) snd_pmac_awacs_mixers); if (err < 0) return err; - if (beige) + if (beige || g4agp) ; else if (chip->model == PMAC_SCREAMER) err = build_mixers(chip, ARRAY_SIZE(snd_pmac_screamer_mixers2), @@ -961,13 +981,17 @@ snd_pmac_awacs_init(struct snd_pmac *chip) err = build_mixers(chip, ARRAY_SIZE(snd_pmac_screamer_mixers_imac), snd_pmac_screamer_mixers_imac); + else if (g4agp) + err = build_mixers(chip, + ARRAY_SIZE(snd_pmac_screamer_mixers_g4agp), + snd_pmac_screamer_mixers_g4agp); else err = build_mixers(chip, ARRAY_SIZE(snd_pmac_awacs_mixers_pmac), snd_pmac_awacs_mixers_pmac); if (err < 0) return err; - chip->master_sw_ctl = snd_ctl_new1((pm7500 || imac) + chip->master_sw_ctl = snd_ctl_new1((pm7500 || imac || g4agp) ? &snd_pmac_awacs_master_sw_imac : &snd_pmac_awacs_master_sw, chip); err = snd_ctl_add(chip->card, chip->master_sw_ctl); @@ -1004,15 +1028,17 @@ snd_pmac_awacs_init(struct snd_pmac *chip) snd_pmac_awacs_speaker_vol); if (err < 0) return err; - chip->speaker_sw_ctl = snd_ctl_new1(imac - ? &snd_pmac_awacs_speaker_sw_imac + chip->speaker_sw_ctl = snd_ctl_new1(imac1 + ? &snd_pmac_awacs_speaker_sw_imac1 + : imac2 + ? &snd_pmac_awacs_speaker_sw_imac2 : &snd_pmac_awacs_speaker_sw, chip); err = snd_ctl_add(chip->card, chip->speaker_sw_ctl); if (err < 0) return err; } - if (beige) + if (beige || g4agp) err = build_mixers(chip, ARRAY_SIZE(snd_pmac_screamer_mic_boost_beige), snd_pmac_screamer_mic_boost_beige); diff --git a/sound/soc/at32/at32-pcm.c b/sound/soc/at32/at32-pcm.c index 435f1daf177..c83584f989a 100644 --- a/sound/soc/at32/at32-pcm.c +++ b/sound/soc/at32/at32-pcm.c @@ -434,7 +434,8 @@ static int at32_pcm_suspend(struct platform_device *pdev, params = prtd->params; /* Disable the PDC and save the PDC registers */ - ssc_writex(params->ssc->regs, PDC_PTCR, params->mask->pdc_disable); + ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR, + params->mask->pdc_disable); prtd->pdc_xpr_save = ssc_readx(params->ssc->regs, params->pdc->xpr); prtd->pdc_xcr_save = ssc_readx(params->ssc->regs, params->pdc->xcr); @@ -464,7 +465,7 @@ static int at32_pcm_resume(struct platform_device *pdev, ssc_writex(params->ssc->regs, params->pdc->xnpr, prtd->pdc_xnpr_save); ssc_writex(params->ssc->regs, params->pdc->xncr, prtd->pdc_xncr_save); - ssc_writex(params->ssc->regs, PDC_PTCR, params->mask->pdc_enable); + ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR, params->mask->pdc_enable); return 0; } #else /* CONFIG_PM */ diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c index 9deb8c74fdf..0bbd94501d7 100644 --- a/sound/soc/codecs/cs4270.c +++ b/sound/soc/codecs/cs4270.c @@ -490,34 +490,7 @@ static int cs4270_mute(struct snd_soc_dai *dai, int mute) #endif -static int cs4270_i2c_probe(struct i2c_adapter *adap, int addr, int kind); - -/* - * Notify the driver that a new I2C bus has been found. - * - * This function is called for each I2C bus in the system. The function - * then asks the I2C subsystem to probe that bus at the addresses on which - * our device (the CS4270) could exist. If a device is found at one of - * those addresses, then our probe function (cs4270_i2c_probe) is called. - */ -static int cs4270_i2c_attach(struct i2c_adapter *adapter) -{ - return i2c_probe(adapter, &addr_data, cs4270_i2c_probe); -} - -static int cs4270_i2c_detach(struct i2c_client *client) -{ - struct snd_soc_codec *codec = i2c_get_clientdata(client); - - i2c_detach_client(client); - codec->control_data = NULL; - - kfree(codec->reg_cache); - codec->reg_cache = NULL; - - kfree(client); - return 0; -} +static int cs4270_i2c_probe(struct i2c_client *, const struct i2c_device_id *); /* A list of non-DAPM controls that the CS4270 supports */ static const struct snd_kcontrol_new cs4270_snd_controls[] = { @@ -525,14 +498,19 @@ static const struct snd_kcontrol_new cs4270_snd_controls[] = { CS4270_VOLA, CS4270_VOLB, 0, 0xFF, 1) }; +static const struct i2c_device_id cs4270_id[] = { + {"cs4270", 0}, + {} +}; +MODULE_DEVICE_TABLE(i2c, cs4270_id); + static struct i2c_driver cs4270_i2c_driver = { .driver = { .name = "CS4270 I2C", .owner = THIS_MODULE, }, - .id = I2C_DRIVERID_CS4270, - .attach_adapter = cs4270_i2c_attach, - .detach_client = cs4270_i2c_detach, + .id_table = cs4270_id, + .probe = cs4270_i2c_probe, }; /* @@ -561,11 +539,11 @@ static struct snd_soc_device *cs4270_socdev; * Note: snd_soc_new_pcms() must be called before this function can be called, * because of snd_ctl_add(). */ -static int cs4270_i2c_probe(struct i2c_adapter *adapter, int addr, int kind) +static int cs4270_i2c_probe(struct i2c_client *i2c_client, + const struct i2c_device_id *id) { struct snd_soc_device *socdev = cs4270_socdev; struct snd_soc_codec *codec = socdev->codec; - struct i2c_client *i2c_client = NULL; int i; int ret = 0; @@ -578,12 +556,6 @@ static int cs4270_i2c_probe(struct i2c_adapter *adapter, int addr, int kind) /* Note: codec_dai->codec is NULL here */ - i2c_client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); - if (!i2c_client) { - printk(KERN_ERR "cs4270: could not allocate I2C client\n"); - return -ENOMEM; - } - codec->reg_cache = kzalloc(CS4270_NUMREGS, GFP_KERNEL); if (!codec->reg_cache) { printk(KERN_ERR "cs4270: could not allocate register cache\n"); @@ -591,13 +563,6 @@ static int cs4270_i2c_probe(struct i2c_adapter *adapter, int addr, int kind) goto error; } - i2c_set_clientdata(i2c_client, codec); - strcpy(i2c_client->name, "CS4270"); - - i2c_client->driver = &cs4270_i2c_driver; - i2c_client->adapter = adapter; - i2c_client->addr = addr; - /* Verify that we have a CS4270 */ ret = i2c_smbus_read_byte_data(i2c_client, CS4270_CHIPID); @@ -612,18 +577,10 @@ static int cs4270_i2c_probe(struct i2c_adapter *adapter, int addr, int kind) goto error; } - printk(KERN_INFO "cs4270: found device at I2C address %X\n", addr); + printk(KERN_INFO "cs4270: found device at I2C address %X\n", + i2c_client->addr); printk(KERN_INFO "cs4270: hardware revision %X\n", ret & 0xF); - /* Tell the I2C layer a new client has arrived */ - - ret = i2c_attach_client(i2c_client); - if (ret) { - printk(KERN_ERR "cs4270: could not attach codec, " - "I2C address %x, error code %i\n", addr, ret); - goto error; - } - codec->control_data = i2c_client; codec->read = cs4270_read_reg_cache; codec->write = cs4270_i2c_write; @@ -648,20 +605,17 @@ static int cs4270_i2c_probe(struct i2c_adapter *adapter, int addr, int kind) goto error; } + i2c_set_clientdata(i2c_client, codec); + return 0; error: - if (codec->control_data) { - i2c_detach_client(i2c_client); - codec->control_data = NULL; - } + codec->control_data = NULL; kfree(codec->reg_cache); codec->reg_cache = NULL; codec->reg_cache_size = 0; - kfree(i2c_client); - return ret; } @@ -727,7 +681,7 @@ static int cs4270_probe(struct platform_device *pdev) ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); if (ret < 0) { printk(KERN_ERR "cs4270: failed to create PCMs\n"); - return ret; + goto error_free_codec; } #ifdef USE_I2C @@ -736,8 +690,7 @@ static int cs4270_probe(struct platform_device *pdev) ret = i2c_add_driver(&cs4270_i2c_driver); if (ret) { printk(KERN_ERR "cs4270: failed to attach driver"); - snd_soc_free_pcms(socdev); - return ret; + goto error_free_pcms; } /* Did we find a CS4270 on the I2C bus? */ @@ -759,10 +712,23 @@ static int cs4270_probe(struct platform_device *pdev) ret = snd_soc_register_card(socdev); if (ret < 0) { printk(KERN_ERR "cs4270: failed to register card\n"); - snd_soc_free_pcms(socdev); - return ret; + goto error_del_driver; } + return 0; + +error_del_driver: +#ifdef USE_I2C + i2c_del_driver(&cs4270_i2c_driver); + +error_free_pcms: +#endif + snd_soc_free_pcms(socdev); + +error_free_codec: + kfree(socdev->codec); + socdev->codec = NULL; + return ret; } @@ -773,8 +739,7 @@ static int cs4270_remove(struct platform_device *pdev) snd_soc_free_pcms(socdev); #ifdef USE_I2C - if (socdev->codec->control_data) - i2c_del_driver(&cs4270_i2c_driver); + i2c_del_driver(&cs4270_i2c_driver); #endif kfree(socdev->codec); diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c index 5761164fe16..e873414840c 100644 --- a/sound/soc/codecs/wm8753.c +++ b/sound/soc/codecs/wm8753.c @@ -583,7 +583,7 @@ static const struct snd_soc_dapm_route audio_map[] = { /* out 4 */ {"Out4 Mux", "VREF", "VREF"}, - {"Out4 Mux", "Capture ST", "Capture ST Mixer"}, + {"Out4 Mux", "Capture ST", "Playback Mixer"}, {"Out4 Mux", "LOUT2", "LOUT2"}, {"Out 4", NULL, "Out4 Mux"}, {"OUT4", NULL, "Out 4"}, @@ -607,7 +607,7 @@ static const struct snd_soc_dapm_route audio_map[] = { /* Capture Right Mux */ {"Capture Right Mux", "PGA", "Right Capture Volume"}, {"Capture Right Mux", "Line or RXP-RXN", "Line Right Mux"}, - {"Capture Right Mux", "Sidetone", "Capture ST Mixer"}, + {"Capture Right Mux", "Sidetone", "Playback Mixer"}, /* Mono Capture mixer-mux */ {"Capture Right Mixer", "Stereo", "Capture Right Mux"}, |