diff options
Diffstat (limited to 'arch')
63 files changed, 524 insertions, 196 deletions
diff --git a/arch/alpha/kernel/alpha_ksyms.c b/arch/alpha/kernel/alpha_ksyms.c index c645c5e..2b245ad 100644 --- a/arch/alpha/kernel/alpha_ksyms.c +++ b/arch/alpha/kernel/alpha_ksyms.c @@ -182,7 +182,6 @@ EXPORT_SYMBOL(smp_num_cpus); EXPORT_SYMBOL(smp_call_function); EXPORT_SYMBOL(smp_call_function_on_cpu); EXPORT_SYMBOL(_atomic_dec_and_lock); -EXPORT_SYMBOL(cpu_present_mask); #endif /* CONFIG_SMP */ /* diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c index 9924fd0..c760a83 100644 --- a/arch/alpha/kernel/process.c +++ b/arch/alpha/kernel/process.c @@ -94,7 +94,7 @@ common_shutdown_1(void *generic_ptr) if (cpuid != boot_cpuid) { flags |= 0x00040000UL; /* "remain halted" */ *pflags = flags; - clear_bit(cpuid, &cpu_present_mask); + cpu_clear(cpuid, cpu_present_map); halt(); } #endif @@ -120,8 +120,8 @@ common_shutdown_1(void *generic_ptr) #ifdef CONFIG_SMP /* Wait for the secondaries to halt. */ - cpu_clear(boot_cpuid, cpu_possible_map); - while (cpus_weight(cpu_possible_map)) + cpu_clear(boot_cpuid, cpu_present_map); + while (cpus_weight(cpu_present_map)) barrier(); #endif diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c index 1852554..4dc273e 100644 --- a/arch/alpha/kernel/smp.c +++ b/arch/alpha/kernel/smp.c @@ -68,7 +68,6 @@ enum ipi_message_type { static int smp_secondary_alive __initdata = 0; /* Which cpus ids came online. */ -cpumask_t cpu_present_mask; cpumask_t cpu_online_map; EXPORT_SYMBOL(cpu_online_map); @@ -439,7 +438,7 @@ setup_smp(void) if ((cpu->flags & 0x1cc) == 0x1cc) { smp_num_probed++; /* Assume here that "whami" == index */ - cpu_set(i, cpu_present_mask); + cpu_set(i, cpu_present_map); cpu->pal_revision = boot_cpu_palrev; } @@ -450,11 +449,10 @@ setup_smp(void) } } else { smp_num_probed = 1; - cpu_set(boot_cpuid, cpu_present_mask); } - printk(KERN_INFO "SMP: %d CPUs probed -- cpu_present_mask = %lx\n", - smp_num_probed, cpu_possible_map.bits[0]); + printk(KERN_INFO "SMP: %d CPUs probed -- cpu_present_map = %lx\n", + smp_num_probed, cpu_present_map.bits[0]); } /* @@ -473,7 +471,7 @@ smp_prepare_cpus(unsigned int max_cpus) /* Nothing to do on a UP box, or when told not to. */ if (smp_num_probed == 1 || max_cpus == 0) { - cpu_present_mask = cpumask_of_cpu(boot_cpuid); + cpu_present_map = cpumask_of_cpu(boot_cpuid); printk(KERN_INFO "SMP mode deactivated.\n"); return; } @@ -486,10 +484,6 @@ smp_prepare_cpus(unsigned int max_cpus) void __devinit smp_prepare_boot_cpu(void) { - /* - * Mark the boot cpu (current cpu) as online - */ - cpu_set(smp_processor_id(), cpu_online_map); } int __devinit diff --git a/arch/alpha/kernel/sys_titan.c b/arch/alpha/kernel/sys_titan.c index 5f84417..2551fb4 100644 --- a/arch/alpha/kernel/sys_titan.c +++ b/arch/alpha/kernel/sys_titan.c @@ -66,7 +66,7 @@ titan_update_irq_hw(unsigned long mask) register int bcpu = boot_cpuid; #ifdef CONFIG_SMP - cpumask_t cpm = cpu_present_mask; + cpumask_t cpm = cpu_present_map; volatile unsigned long *dim0, *dim1, *dim2, *dim3; unsigned long mask0, mask1, mask2, mask3, dummy; diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index 5d3acff..d22f38b 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug @@ -101,7 +101,7 @@ config DEBUG_S3C2410_UART help Choice for UART for kernel low-level using S3C2410 UARTS, should be between zero and two. The port must have been - initalised by the boot-loader before use. + initialised by the boot-loader before use. The uncompressor code port configuration is now handled by CONFIG_S3C2410_LOWLEVEL_UART_PORT. diff --git a/arch/arm/mach-ep93xx/ts72xx.c b/arch/arm/mach-ep93xx/ts72xx.c index 9be01b0c..e24566b 100644 --- a/arch/arm/mach-ep93xx/ts72xx.c +++ b/arch/arm/mach-ep93xx/ts72xx.c @@ -111,21 +111,21 @@ static void __init ts72xx_map_io(void) } } -static unsigned char ts72xx_rtc_readb(unsigned long addr) +static unsigned char ts72xx_rtc_readbyte(unsigned long addr) { __raw_writeb(addr, TS72XX_RTC_INDEX_VIRT_BASE); return __raw_readb(TS72XX_RTC_DATA_VIRT_BASE); } -static void ts72xx_rtc_writeb(unsigned char value, unsigned long addr) +static void ts72xx_rtc_writebyte(unsigned char value, unsigned long addr) { __raw_writeb(addr, TS72XX_RTC_INDEX_VIRT_BASE); __raw_writeb(value, TS72XX_RTC_DATA_VIRT_BASE); } static struct m48t86_ops ts72xx_rtc_ops = { - .readb = ts72xx_rtc_readb, - .writeb = ts72xx_rtc_writeb, + .readbyte = ts72xx_rtc_readbyte, + .writebyte = ts72xx_rtc_writebyte, }; static struct platform_device ts72xx_rtc_device = { diff --git a/arch/arm/mach-ixp23xx/core.c b/arch/arm/mach-ixp23xx/core.c index 092ee12..affd1d5 100644 --- a/arch/arm/mach-ixp23xx/core.c +++ b/arch/arm/mach-ixp23xx/core.c @@ -178,8 +178,12 @@ static int ixp23xx_irq_set_type(unsigned int irq, unsigned int type) static void ixp23xx_irq_mask(unsigned int irq) { - volatile unsigned long *intr_reg = IXP23XX_INTR_EN1 + (irq / 32); + volatile unsigned long *intr_reg; + if (irq >= 56) + irq += 8; + + intr_reg = IXP23XX_INTR_EN1 + (irq / 32); *intr_reg &= ~(1 << (irq % 32)); } @@ -199,17 +203,25 @@ static void ixp23xx_irq_ack(unsigned int irq) */ static void ixp23xx_irq_level_unmask(unsigned int irq) { - volatile unsigned long *intr_reg = IXP23XX_INTR_EN1 + (irq / 32); + volatile unsigned long *intr_reg; ixp23xx_irq_ack(irq); + if (irq >= 56) + irq += 8; + + intr_reg = IXP23XX_INTR_EN1 + (irq / 32); *intr_reg |= (1 << (irq % 32)); } static void ixp23xx_irq_edge_unmask(unsigned int irq) { - volatile unsigned long *intr_reg = IXP23XX_INTR_EN1 + (irq / 32); + volatile unsigned long *intr_reg; + + if (irq >= 56) + irq += 8; + intr_reg = IXP23XX_INTR_EN1 + (irq / 32); *intr_reg |= (1 << (irq % 32)); } diff --git a/arch/arm/mach-ixp4xx/Kconfig b/arch/arm/mach-ixp4xx/Kconfig index 2a39f9e..3b23f43 100644 --- a/arch/arm/mach-ixp4xx/Kconfig +++ b/arch/arm/mach-ixp4xx/Kconfig @@ -141,7 +141,7 @@ config IXP4XX_INDIRECT_PCI 2) If > 64MB of memory space is required, the IXP4xx can be configured to use indirect registers to access PCI This allows for up to 128MB (0x48000000 to 0x4fffffff) of memory on the bus. - The disadvantadge of this is that every PCI access requires + The disadvantage of this is that every PCI access requires three local register accesses plus a spinlock, but in some cases the performance hit is acceptable. In addition, you cannot mmap() PCI devices in this case due to the indirect nature diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c index 02e188d..b307f11 100644 --- a/arch/arm/mach-pxa/mainstone.c +++ b/arch/arm/mach-pxa/mainstone.c @@ -493,6 +493,7 @@ static void __init mainstone_map_io(void) MACHINE_START(MAINSTONE, "Intel HCDDBBVA0 Development Platform (aka Mainstone)") /* Maintainer: MontaVista Software Inc. */ .phys_io = 0x40000000, + .boot_params = 0xa0000100, /* BLOB boot parameter setting */ .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, .map_io = mainstone_map_io, .init_irq = mainstone_init_irq, diff --git a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig index ce7d810..970f98d 100644 --- a/arch/arm/mach-s3c2410/Kconfig +++ b/arch/arm/mach-s3c2410/Kconfig @@ -170,7 +170,7 @@ config S3C2410_PM_DEBUG depends on ARCH_S3C2410 && PM help Say Y here if you want verbose debugging from the PM Suspend and - Resume code. See `Documentation/arm/Samsing-S3C24XX/Suspend.txt` + Resume code. See <file:Documentation/arm/Samsung-S3C24XX/Suspend.txt> for more information. config S3C2410_PM_CHECK diff --git a/arch/i386/kernel/acpi/earlyquirk.c b/arch/i386/kernel/acpi/earlyquirk.c index 2e3b643..1649a17 100644 --- a/arch/i386/kernel/acpi/earlyquirk.c +++ b/arch/i386/kernel/acpi/earlyquirk.c @@ -5,17 +5,34 @@ #include <linux/init.h> #include <linux/kernel.h> #include <linux/pci.h> +#include <linux/acpi.h> + #include <asm/pci-direct.h> #include <asm/acpi.h> #include <asm/apic.h> +#ifdef CONFIG_ACPI + +static int nvidia_hpet_detected __initdata; + +static int __init nvidia_hpet_check(unsigned long phys, unsigned long size) +{ + nvidia_hpet_detected = 1; + return 0; +} +#endif + static int __init check_bridge(int vendor, int device) { #ifdef CONFIG_ACPI - /* According to Nvidia all timer overrides are bogus. Just ignore - them all. */ + /* According to Nvidia all timer overrides are bogus unless HPET + is enabled. */ if (vendor == PCI_VENDOR_ID_NVIDIA) { - acpi_skip_timer_override = 1; + nvidia_hpet_detected = 0; + acpi_table_parse(ACPI_HPET, nvidia_hpet_check); + if (nvidia_hpet_detected == 0) { + acpi_skip_timer_override = 1; + } } #endif if (vendor == PCI_VENDOR_ID_ATI && timer_over_8254 == 1) { diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index 846e163..dd6b0e3 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c @@ -1547,15 +1547,18 @@ void __init setup_arch(char **cmdline_p) if (efi_enabled) efi_map_memmap(); -#ifdef CONFIG_X86_IO_APIC - check_acpi_pci(); /* Checks more than just ACPI actually */ -#endif - #ifdef CONFIG_ACPI /* * Parse the ACPI tables for possible boot-time SMP configuration. */ acpi_boot_table_init(); +#endif + +#ifdef CONFIG_X86_IO_APIC + check_acpi_pci(); /* Checks more than just ACPI actually */ +#endif + +#ifdef CONFIG_ACPI acpi_boot_init(); #if defined(CONFIG_SMP) && defined(CONFIG_X86_PC) diff --git a/arch/mips/au1000/common/prom.c b/arch/mips/au1000/common/prom.c index 9c171af..ae7d8c5 100644 --- a/arch/mips/au1000/common/prom.c +++ b/arch/mips/au1000/common/prom.c @@ -1,10 +1,9 @@ /* * * BRIEF MODULE DESCRIPTION - * PROM library initialisation code, assuming a version of - * pmon is the boot code. + * PROM library initialisation code, assuming YAMON is the boot loader. * - * Copyright 2000,2001 MontaVista Software Inc. + * Copyright 2000, 2001, 2006 MontaVista Software Inc. * Author: MontaVista Software, Inc. * ppopov@mvista.com or source@mvista.com * @@ -49,9 +48,9 @@ extern char **prom_argv, **prom_envp; typedef struct { - char *name; -/* char *val; */ -}t_env_var; + char *name; + char *val; +} t_env_var; char * prom_getcmdline(void) @@ -85,21 +84,16 @@ char *prom_getenv(char *envname) { /* * Return a pointer to the given environment variable. - * Environment variables are stored in the form of "memsize=64". */ t_env_var *env = (t_env_var *)prom_envp; - int i; - - i = strlen(envname); - while(env->name) { - if(strncmp(envname, env->name, i) == 0) { - return(env->name + strlen(envname) + 1); - } + while (env->name) { + if (strcmp(envname, env->name) == 0) + return env->val; env++; } - return(NULL); + return NULL; } inline unsigned char str2hexnum(unsigned char c) diff --git a/arch/mips/au1000/common/sleeper.S b/arch/mips/au1000/common/sleeper.S index 44dac3b..683d9da 100644 --- a/arch/mips/au1000/common/sleeper.S +++ b/arch/mips/au1000/common/sleeper.S @@ -112,6 +112,11 @@ sdsleep: mtc0 k0, CP0_PAGEMASK lw k0, 0x14(sp) mtc0 k0, CP0_CONFIG + + /* We need to catch the ealry Alchemy SOCs with + * the write-only Config[OD] bit and set it back to one... + */ + jal au1x00_fixup_config_od lw $1, PT_R1(sp) lw $2, PT_R2(sp) lw $3, PT_R3(sp) diff --git a/arch/mips/ddb5xxx/ddb5476/dbg_io.c b/arch/mips/ddb5xxx/ddb5476/dbg_io.c index 85e9e50..f2296a9 100644 --- a/arch/mips/ddb5xxx/ddb5476/dbg_io.c +++ b/arch/mips/ddb5xxx/ddb5476/dbg_io.c @@ -86,7 +86,7 @@ void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop) /* disable interrupts */ UART16550_WRITE(OFS_INTR_ENABLE, 0); - /* set up buad rate */ + /* set up baud rate */ { uint32 divisor; diff --git a/arch/mips/ddb5xxx/ddb5477/kgdb_io.c b/arch/mips/ddb5xxx/ddb5477/kgdb_io.c index 1d18d59..385bbdb 100644 --- a/arch/mips/ddb5xxx/ddb5477/kgdb_io.c +++ b/arch/mips/ddb5xxx/ddb5477/kgdb_io.c @@ -86,7 +86,7 @@ void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop) /* disable interrupts */ UART16550_WRITE(OFS_INTR_ENABLE, 0); - /* set up buad rate */ + /* set up baud rate */ { uint32 divisor; diff --git a/arch/mips/gt64120/ev64120/serialGT.c b/arch/mips/gt64120/ev64120/serialGT.c index 16e34a5..8f0d835 100644 --- a/arch/mips/gt64120/ev64120/serialGT.c +++ b/arch/mips/gt64120/ev64120/serialGT.c @@ -149,7 +149,7 @@ void serial_set(int channel, unsigned long baud) #else /* * Note: Set baud rate, hardcoded here for rate of 115200 - * since became unsure of above "buad rate" algorithm (??). + * since became unsure of above "baud rate" algorithm (??). */ outreg(channel, LCR, 0x83); outreg(channel, DLM, 0x00); // See note above diff --git a/arch/mips/gt64120/momenco_ocelot/dbg_io.c b/arch/mips/gt64120/momenco_ocelot/dbg_io.c index 8720bcc..f0a6a38 100644 --- a/arch/mips/gt64120/momenco_ocelot/dbg_io.c +++ b/arch/mips/gt64120/momenco_ocelot/dbg_io.c @@ -73,7 +73,7 @@ void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop) /* disable interrupts */ UART16550_WRITE(OFS_INTR_ENABLE, 0); - /* set up buad rate */ + /* set up baud rate */ { uint32 divisor; diff --git a/arch/mips/ite-boards/generic/dbg_io.c b/arch/mips/ite-boards/generic/dbg_io.c index c4f8530..6a7ccaf 100644 --- a/arch/mips/ite-boards/generic/dbg_io.c +++ b/arch/mips/ite-boards/generic/dbg_io.c @@ -72,7 +72,7 @@ void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop) /* disable interrupts */ UART16550_WRITE(OFS_INTR_ENABLE, 0); - /* set up buad rate */ + /* set up baud rate */ { uint32 divisor; diff --git a/arch/mips/kernel/cpu-bugs64.c b/arch/mips/kernel/cpu-bugs64.c index 47a087b..d268827 100644 --- a/arch/mips/kernel/cpu-bugs64.c +++ b/arch/mips/kernel/cpu-bugs64.c @@ -206,7 +206,7 @@ static inline void check_daddi(void) "daddi %0, %1, %3\n\t" ".set pop" : "=r" (v), "=&r" (tmp) - : "I" (0xffffffffffffdb9a), "I" (0x1234)); + : "I" (0xffffffffffffdb9aUL), "I" (0x1234)); set_except_vector(12, handler); local_irq_restore(flags); @@ -224,7 +224,7 @@ static inline void check_daddi(void) "dsrl %1, %1, 1\n\t" "daddi %0, %1, %3" : "=r" (v), "=&r" (tmp) - : "I" (0xffffffffffffdb9a), "I" (0x1234)); + : "I" (0xffffffffffffdb9aUL), "I" (0x1234)); set_except_vector(12, handler); local_irq_restore(flags); @@ -280,7 +280,7 @@ static inline void check_daddiu(void) "daddu %1, %2\n\t" ".set pop" : "=&r" (v), "=&r" (w), "=&r" (tmp) - : "I" (0xffffffffffffdb9a), "I" (0x1234)); + : "I" (0xffffffffffffdb9aUL), "I" (0x1234)); if (v == w) { printk("no.\n"); @@ -296,7 +296,7 @@ static inline void check_daddiu(void) "addiu %1, $0, %4\n\t" "daddu %1, %2" : "=&r" (v), "=&r" (w), "=&r" (tmp) - : "I" (0xffffffffffffdb9a), "I" (0x1234)); + : "I" (0xffffffffffffdb9aUL), "I" (0x1234)); if (v == w) { printk("yes.\n"); diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index bef3e2d..8c2c359 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c @@ -655,7 +655,7 @@ static inline void cpu_probe_sibyte(struct cpuinfo_mips *c) case PRID_IMP_SB1: c->cputype = CPU_SB1; /* FPU in pass1 is known to have issues. */ - if ((c->processor_id & 0xff) < 0x20) + if ((c->processor_id & 0xff) < 0x02) c->options &= ~(MIPS_CPU_FPU | MIPS_CPU_32FPR); break; case PRID_IMP_SB1A: diff --git a/arch/mips/kernel/module.c b/arch/mips/kernel/module.c index e54a7f4..d7bf021 100644 --- a/arch/mips/kernel/module.c +++ b/arch/mips/kernel/module.c @@ -288,6 +288,9 @@ int apply_relocate(Elf_Shdr *sechdrs, const char *strtab, sym = (Elf_Sym *)sechdrs[symindex].sh_addr + ELF_MIPS_R_SYM(rel[i]); if (!sym->st_value) { + /* Ignore unresolved weak symbol */ + if (ELF_ST_BIND(sym->st_info) == STB_WEAK) + continue; printk(KERN_WARNING "%s: Unknown symbol %s\n", me->name, strtab + sym->st_name); return -ENOENT; @@ -325,6 +328,9 @@ int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab, sym = (Elf_Sym *)sechdrs[symindex].sh_addr + ELF_MIPS_R_SYM(rel[i]); if (!sym->st_value) { + /* Ignore unresolved weak symbol */ + if (ELF_ST_BIND(sym->st_info) == STB_WEAK) + continue; printk(KERN_WARNING "%s: Unknown symbol %s\n", me->name, strtab + sym->st_name); return -ENOENT; diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S index b53a920..8efb23a 100644 --- a/arch/mips/kernel/scall64-o32.S +++ b/arch/mips/kernel/scall64-o32.S @@ -209,7 +209,7 @@ sys_call_table: PTR sys_fork PTR sys_read PTR sys_write - PTR sys_open /* 4005 */ + PTR compat_sys_open /* 4005 */ PTR sys_close PTR sys_waitpid PTR sys_creat diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index bcf1b10..397a70e 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -246,7 +246,7 @@ static inline int parse_rd_cmdline(unsigned long* rd_start, unsigned long* rd_en #ifdef CONFIG_64BIT /* HACK: Guess if the sign extension was forgotten */ if (start > 0x0000000080000000 && start < 0x00000000ffffffff) - start |= 0xffffffff00000000; + start |= 0xffffffff00000000UL; #endif end = start + size; @@ -355,8 +355,6 @@ static inline void bootmem_init(void) } #endif - memory_present(0, first_usable_pfn, max_low_pfn); - /* Initialize the boot-time allocator with low memory only. */ bootmap_size = init_bootmem(first_usable_pfn, max_low_pfn); @@ -410,6 +408,7 @@ static inline void bootmem_init(void) /* Register lowmem ranges */ free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(size)); + memory_present(0, curr_pfn, curr_pfn + size - 1); } /* Reserve the bootmap memory. */ @@ -419,17 +418,20 @@ static inline void bootmem_init(void) #ifdef CONFIG_BLK_DEV_INITRD initrd_below_start_ok = 1; if (initrd_start) { - unsigned long initrd_size = ((unsigned char *)initrd_end) - ((unsigned char *)initrd_start); + unsigned long initrd_size = ((unsigned char *)initrd_end) - + ((unsigned char *)initrd_start); + const int width = sizeof(long) * 2; + printk("Initial ramdisk at: 0x%p (%lu bytes)\n", (void *)initrd_start, initrd_size); if (CPHYSADDR(initrd_end) > PFN_PHYS(max_low_pfn)) { printk("initrd extends beyond end of memory " "(0x%0*Lx > 0x%0*Lx)\ndisabling initrd\n", - sizeof(long) * 2, - (unsigned long long)CPHYSADDR(initrd_end), - sizeof(long) * 2, - (unsigned long long)PFN_PHYS(max_low_pfn)); + width, + (unsigned long long) CPHYSADDR(initrd_end), + width, + (unsigned long long) PFN_PHYS(max_low_pfn)); initrd_start = initrd_end = 0; initrd_reserve_bootmem = 0; } diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c index d42f358..298f82f 100644 --- a/arch/mips/kernel/smp.c +++ b/arch/mips/kernel/smp.c @@ -247,6 +247,9 @@ void __init smp_prepare_cpus(unsigned int max_cpus) current_thread_info()->cpu = 0; smp_tune_scheduling(); plat_prepare_cpus(max_cpus); +#ifndef CONFIG_HOTPLUG_CPU + cpu_present_map = cpu_possible_map; +#endif } /* preload SMP state for boot cpu */ @@ -442,7 +445,7 @@ static int __init topology_init(void) int cpu; int ret; - for_each_cpu(cpu) { + for_each_present_cpu(cpu) { ret = register_cpu(&per_cpu(cpu_devices, cpu), cpu, NULL); if (ret) printk(KERN_WARNING "topology_init: register_cpu %d " diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c index 8f4fdd9..5e8a18a 100644 --- a/arch/mips/kernel/syscall.c +++ b/arch/mips/kernel/syscall.c @@ -276,8 +276,7 @@ void sys_set_thread_area(unsigned long addr) asmlinkage int _sys_sysmips(int cmd, long arg1, int arg2, int arg3) { - int tmp, len; - char __user *name; + int tmp; switch(cmd) { case MIPS_ATOMIC_SET: diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 35cb08d..a7564b0 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -819,15 +819,30 @@ asmlinkage void do_watch(struct pt_regs *regs) asmlinkage void do_mcheck(struct pt_regs *regs) { + const int field = 2 * sizeof(unsigned long); + int multi_match = regs->cp0_status & ST0_TS; + show_regs(regs); - dump_tlb_all(); + + if (multi_match) { + printk("Index : %0x\n", read_c0_index()); + printk("Pagemask: %0x\n", read_c0_pagemask()); + printk("EntryHi : %0*lx\n", field, read_c0_entryhi()); + printk("EntryLo0: %0*lx\n", field, read_c0_entrylo0()); + printk("EntryLo1: %0*lx\n", field, read_c0_entrylo1()); + printk("\n"); + dump_tlb_all(); + } + + show_code((unsigned int *) regs->cp0_epc); + /* * Some chips may have other causes of machine check (e.g. SB1 * graduation timer) */ panic("Caught Machine Check exception - %scaused by multiple " "matching entries in the TLB.", - (regs->cp0_status & ST0_TS) ? "" : "not "); + (multi_match) ? "" : "not "); } asmlinkage void do_mt(struct pt_regs *regs) diff --git a/arch/mips/math-emu/dp_fint.c b/arch/mips/math-emu/dp_fint.c index a1962eb..39a71de1 100644 --- a/arch/mips/math-emu/dp_fint.c +++ b/arch/mips/math-emu/dp_fint.c @@ -29,7 +29,9 @@ ieee754dp ieee754dp_fint(int x) { - COMPXDP; + u64 xm; + int xe; + int xs; CLEARCX; diff --git a/arch/mips/math-emu/dp_flong.c b/arch/mips/math-emu/dp_flong.c index eae90a8..f08f223 100644 --- a/arch/mips/math-emu/dp_flong.c +++ b/arch/mips/math-emu/dp_flong.c @@ -29,7 +29,9 @@ ieee754dp ieee754dp_flong(s64 x) { - COMPXDP; + u64 xm; + int xe; + int xs; CLEARCX; diff --git a/arch/mips/math-emu/sp_fint.c b/arch/mips/math-emu/sp_fint.c index 7aac13a..e88e125 100644 --- a/arch/mips/math-emu/sp_fint.c +++ b/arch/mips/math-emu/sp_fint.c @@ -29,7 +29,9 @@ ieee754sp ieee754sp_fint(int x) { - COMPXSP; + unsigned xm; + int xe; + int xs; CLEARCX; diff --git a/arch/mips/math-emu/sp_flong.c b/arch/mips/math-emu/sp_flong.c index 3d6c1d1..26d6919 100644 --- a/arch/mips/math-emu/sp_flong.c +++ b/arch/mips/math-emu/sp_flong.c @@ -29,7 +29,9 @@ ieee754sp ieee754sp_flong(s64 x) { - COMPXDP; /* <--- need 64-bit mantissa temp */ + u64 xm; /* <--- need 64-bit mantissa temp */ + int xe; + int xs; CLEARCX; diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index 6b35417..4a43924 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c @@ -1161,6 +1161,31 @@ static void __init setup_scache(void) c->options |= MIPS_CPU_SUBSET_CACHES; } +void au1x00_fixup_config_od(void) +{ + /* + * c0_config.od (bit 19) was write only (and read as 0) + * on the early revisions of Alchemy SOCs. It disables the bus + * transaction overlapping and needs to be set to fix various errata. + */ + switch (read_c0_prid()) { + case 0x00030100: /* Au1000 DA */ + case 0x00030201: /* Au1000 HA */ + case 0x00030202: /* Au1000 HB */ + case 0x01030200: /* Au1500 AB */ + /* + * Au1100 errata actually keeps silence about this bit, so we set it + * just in case for those revisions that require it to be set according + * to arch/mips/au1000/common/cputable.c + */ + case 0x02030200: /* Au1100 AB */ + case 0x02030201: /* Au1100 BA */ + case 0x02030202: /* Au1100 BC */ + set_c0_config(1 << 19); + break; + } +} + static inline void coherency_setup(void) { change_c0_config(CONF_CM_CMASK, CONF_CM_DEFAULT); @@ -1181,6 +1206,15 @@ static inline void coherency_setup(void) case CPU_R4400MC: clear_c0_config(CONF_CU); break; + /* + * We need to catch the ealry Alchemy SOCs with + * the write-only co_config.od bit and set it back to one... + */ + case CPU_AU1000: /* rev. DA, HA, HB */ + case CPU_AU1100: /* rev. AB, BA, BC ?? */ + case CPU_AU1500: /* rev. AB */ + au1x00_fixup_config_od(); + break; } } diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index c22308b..33f6e1c 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c @@ -227,7 +227,7 @@ void __init mem_init(void) for (tmp = 0; tmp < max_low_pfn; tmp++) if (page_is_ram(tmp)) { ram++; - if (PageReserved(mem_map+tmp)) + if (PageReserved(pfn_to_page(tmp))) reservedpages++; } diff --git a/arch/mips/momentum/jaguar_atx/dbg_io.c b/arch/mips/momentum/jaguar_atx/dbg_io.c index 542eac8..d7dea0a 100644 --- a/arch/mips/momentum/jaguar_atx/dbg_io.c +++ b/arch/mips/momentum/jaguar_atx/dbg_io.c @@ -73,7 +73,7 @@ void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop) /* disable interrupts */ UART16550_WRITE(OFS_INTR_ENABLE, 0); - /* set up buad rate */ + /* set up baud rate */ { uint32 divisor; diff --git a/arch/mips/momentum/ocelot_c/dbg_io.c b/arch/mips/momentum/ocelot_c/dbg_io.c index 8720bcc..f0a6a38 100644 --- a/arch/mips/momentum/ocelot_c/dbg_io.c +++ b/arch/mips/momentum/ocelot_c/dbg_io.c @@ -73,7 +73,7 @@ void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop) /* disable interrupts */ UART16550_WRITE(OFS_INTR_ENABLE, 0); - /* set up buad rate */ + /* set up baud rate */ { uint32 divisor; diff --git a/arch/mips/momentum/ocelot_g/dbg_io.c b/arch/mips/momentum/ocelot_g/dbg_io.c index 8720bcc..f0a6a38 100644 --- a/arch/mips/momentum/ocelot_g/dbg_io.c +++ b/arch/mips/momentum/ocelot_g/dbg_io.c @@ -73,7 +73,7 @@ void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop) /* disable interrupts */ UART16550_WRITE(OFS_INTR_ENABLE, 0); - /* set up buad rate */ + /* set up baud rate */ { uint32 divisor; diff --git a/arch/mips/oprofile/common.c b/arch/mips/oprofile/common.c index 91b799d..c31e4cf 100644 --- a/arch/mips/oprofile/common.c +++ b/arch/mips/oprofile/common.c @@ -14,8 +14,8 @@ #include "op_impl.h" -extern struct op_mips_model op_model_mipsxx __attribute__((weak)); -extern struct op_mips_model op_model_rm9000 __attribute__((weak)); +extern struct op_mips_model op_model_mipsxx_ops __attribute__((weak)); +extern struct op_mips_model op_model_rm9000_ops __attribute__((weak)); static struct op_mips_model *model; @@ -83,11 +83,11 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) case CPU_74K: case CPU_SB1: case CPU_SB1A: - lmodel = &op_model_mipsxx; + lmodel = &op_model_mipsxx_ops; break; case CPU_RM9000: - lmodel = &op_model_rm9000; + lmodel = &op_model_rm9000_ops; break; }; diff --git a/arch/mips/oprofile/op_model_mipsxx.c b/arch/mips/oprofile/op_model_mipsxx.c index e7ce923..f26a00e 100644 --- a/arch/mips/oprofile/op_model_mipsxx.c +++ b/arch/mips/oprofile/op_model_mipsxx.c @@ -23,7 +23,7 @@ #define M_COUNTER_OVERFLOW (1UL << 31) -struct op_mips_model op_model_mipsxx; +struct op_mips_model op_model_mipsxx_ops; static struct mipsxx_register_config { unsigned int control[4]; @@ -34,7 +34,7 @@ static struct mipsxx_register_config { static void mipsxx_reg_setup(struct op_counter_config *ctr) { - unsigned int counters = op_model_mipsxx.num_counters; + unsigned int counters = op_model_mipsxx_ops.num_counters; int i; /* Compute the performance counter control word. */ @@ -62,7 +62,7 @@ static void mipsxx_reg_setup(struct op_counter_config *ctr) static void mipsxx_cpu_setup (void *args) { - unsigned int counters = op_model_mipsxx.num_counters; + unsigned int counters = op_model_mipsxx_ops.num_counters; switch (counters) { case 4: @@ -83,7 +83,7 @@ static void mipsxx_cpu_setup (void *args) /* Start all counters on current CPU */ static void mipsxx_cpu_start(void *args) { - unsigned int counters = op_model_mipsxx.num_counters; + unsigned int counters = op_model_mipsxx_ops.num_counters; switch (counters) { case 4: @@ -100,7 +100,7 @@ static void mipsxx_cpu_start(void *args) /* Stop all counters on current CPU */ static void mipsxx_cpu_stop(void *args) { - unsigned int counters = op_model_mipsxx.num_counters; + unsigned int counters = op_model_mipsxx_ops.num_counters; switch (counters) { case 4: @@ -116,7 +116,7 @@ static void mipsxx_cpu_stop(void *args) static int mipsxx_perfcount_handler(struct pt_regs *regs) { - unsigned int counters = op_model_mipsxx.num_counters; + unsigned int counters = op_model_mipsxx_ops.num_counters; unsigned int control; unsigned int counter; int handled = 0; @@ -187,37 +187,37 @@ static int __init mipsxx_init(void) reset_counters(counters); - op_model_mipsxx.num_counters = counters; + op_model_mipsxx_ops.num_counters = counters; switch (current_cpu_data.cputype) { case CPU_20KC: - op_model_mipsxx.cpu_type = "mips/20K"; + op_model_mipsxx_ops.cpu_type = "mips/20K"; break; case CPU_24K: - op_model_mipsxx.cpu_type = "mips/24K"; + op_model_mipsxx_ops.cpu_type = "mips/24K"; break; case CPU_25KF: - op_model_mipsxx.cpu_type = "mips/25K"; + op_model_mipsxx_ops.cpu_type = "mips/25K"; break; #ifndef CONFIG_SMP case CPU_34K: - op_model_mipsxx.cpu_type = "mips/34K"; + op_model_mipsxx_ops.cpu_type = "mips/34K"; break; case CPU_74K: - op_model_mipsxx.cpu_type = "mips/74K"; + op_model_mipsxx_ops.cpu_type = "mips/74K"; break; #endif case CPU_5KC: - op_model_mipsxx.cpu_type = "mips/5K"; + op_model_mipsxx_ops.cpu_type = "mips/5K"; break; case CPU_SB1: case CPU_SB1A: - op_model_mipsxx.cpu_type = "mips/sb1"; + op_model_mipsxx_ops.cpu_type = "mips/sb1"; break; default: @@ -233,12 +233,12 @@ static int __init mipsxx_init(void) static void mipsxx_exit(void) { - reset_counters(op_model_mipsxx.num_counters); + reset_counters(op_model_mipsxx_ops.num_counters); perf_irq = null_perf_irq; } -struct op_mips_model op_model_mipsxx = { +struct op_mips_model op_model_mipsxx_ops = { .reg_setup = mipsxx_reg_setup, .cpu_setup = mipsxx_cpu_setup, .init = mipsxx_init, diff --git a/arch/mips/oprofile/op_model_rm9000.c b/arch/mips/oprofile/op_model_rm9000.c index 9b75e41..b7063fe 100644 --- a/arch/mips/oprofile/op_model_rm9000.c +++ b/arch/mips/oprofile/op_model_rm9000.c @@ -126,7 +126,7 @@ static void rm9000_exit(void) free_irq(rm9000_perfcount_irq, NULL); } -struct op_mips_model op_model_rm9000 = { +struct op_mips_model op_model_rm9000_ops = { .reg_setup = rm9000_reg_setup, .cpu_setup = rm9000_cpu_setup, .init = rm9000_init, diff --git a/arch/mips/sgi-ip32/ip32-irq.c b/arch/mips/sgi-ip32/ip32-irq.c index de01c98..8ba0804 100644 --- a/arch/mips/sgi-ip32/ip32-irq.c +++ b/arch/mips/sgi-ip32/ip32-irq.c @@ -31,12 +31,12 @@ /* issue a PIO read to make sure no PIO writes are pending */ static void inline flush_crime_bus(void) { - volatile unsigned long junk = crime->control; + crime->control; } static void inline flush_mace_bus(void) { - volatile unsigned long junk = mace->perif.ctrl.misc; + mace->perif.ctrl.misc; } #undef DEBUG_IRQ diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index 5908690..57d8a16 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c @@ -776,6 +776,7 @@ static void __init prom_send_capabilities(void) /* try calling the ibm,client-architecture-support method */ if (call_prom_ret("call-method", 3, 2, &ret, ADDR("ibm,client-architecture-support"), + root, ADDR(ibm_architecture_vec)) == 0) { /* the call exists... */ if (ret) @@ -1541,6 +1542,15 @@ static int __init prom_find_machine_type(void) if (strstr(p, RELOC("Power Macintosh")) || strstr(p, RELOC("MacRISC"))) return PLATFORM_POWERMAC; +#ifdef CONFIG_PPC64 + /* We must make sure we don't detect the IBM Cell + * blades as pSeries due to some firmware issues, + * so we do it here. + */ + if (strstr(p, RELOC("IBM,CBEA")) || + strstr(p, RELOC("IBM,CPBW-1.0"))) + return PLATFORM_GENERIC; +#endif /* CONFIG_PPC64 */ i += sl + 1; } } diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index 237faee..d73b25e 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -808,10 +808,13 @@ static int do_setcontext(struct ucontext __user *ucp, struct pt_regs *regs, int if (__get_user(cmcp, &ucp->uc_regs)) return -EFAULT; mcp = (struct mcontext __user *)(u64)cmcp; + /* no need to check access_ok(mcp), since mcp < 4GB */ } #else if (__get_user(mcp, &ucp->uc_regs)) return -EFAULT; + if (!access_ok(VERIFY_READ, mcp, sizeof(*mcp))) + return -EFAULT; #endif restore_sigmask(&set); if (restore_user_regs(regs, mcp, sig)) @@ -913,13 +916,14 @@ int sys_debug_setcontext(struct ucontext __user *ctx, { struct sig_dbg_op op; int i; + unsigned char tmp; unsigned long new_msr = regs->msr; #if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) unsigned long new_dbcr0 = current->thread.dbcr0; #endif for (i=0; i<ndbg; i++) { - if (__copy_from_user(&op, dbg, sizeof(op))) + if (copy_from_user(&op, dbg + i, sizeof(op))) return -EFAULT; switch (op.dbg_type) { case SIG_DBG_SINGLE_STEPPING: @@ -964,6 +968,11 @@ int sys_debug_setcontext(struct ucontext __user *ctx, current->thread.dbcr0 = new_dbcr0; #endif + if (!access_ok(VERIFY_READ, ctx, sizeof(*ctx)) + || __get_user(tmp, (u8 __user *) ctx) + || __get_user(tmp, (u8 __user *) (ctx + 1) - 1)) + return -EFAULT; + /* * If we get a fault copying the context into the kernel's * image of the user's registers, we can't just return -EFAULT diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c index 66a5fbe..6e75d7a 100644 --- a/arch/powerpc/kernel/signal_64.c +++ b/arch/powerpc/kernel/signal_64.c @@ -184,6 +184,8 @@ static long restore_sigcontext(struct pt_regs *regs, sigset_t *set, int sig, err |= __get_user(v_regs, &sc->v_regs); if (err) return err; + if (v_regs && !access_ok(VERIFY_READ, v_regs, 34 * sizeof(vector128))) + return -EFAULT; /* Copy 33 vec registers (vr0..31 and vscr) from the stack */ if (v_regs != 0 && (msr & MSR_VEC) != 0) err |= __copy_from_user(current->thread.vr, v_regs, diff --git a/arch/powerpc/platforms/cell/setup.c b/arch/powerpc/platforms/cell/setup.c index 6574b22..fd3e560 100644 --- a/arch/powerpc/platforms/cell/setup.c +++ b/arch/powerpc/platforms/cell/setup.c @@ -125,14 +125,13 @@ static void __init cell_init_early(void) static int __init cell_probe(void) { - /* XXX This is temporary, the Cell maintainer will come up with - * more appropriate detection logic - */ unsigned long root = of_get_flat_dt_root(); - if (!of_flat_dt_is_compatible(root, "IBM,CPBW-1.0")) - return 0; - return 1; + if (of_flat_dt_is_compatible(root, "IBM,CBEA") || + of_flat_dt_is_compatible(root, "IBM,CPBW-1.0")) + return 1; + + return 0; } /* diff --git a/arch/powerpc/platforms/powermac/pfunc_core.c b/arch/powerpc/platforms/powermac/pfunc_core.c index 4baa75b..f08173b 100644 --- a/arch/powerpc/platforms/powermac/pfunc_core.c +++ b/arch/powerpc/platforms/powermac/pfunc_core.c @@ -11,6 +11,7 @@ #include <linux/kernel.h> #include <linux/spinlock.h> #include <linux/module.h> +#include <linux/mutex.h> #include <asm/semaphore.h> #include <asm/prom.h> @@ -546,6 +547,7 @@ struct pmf_device { static LIST_HEAD(pmf_devices); static spinlock_t pmf_lock = SPIN_LOCK_UNLOCKED; +static DEFINE_MUTEX(pmf_irq_mutex); static void pmf_release_device(struct kref *kref) { @@ -864,15 +866,17 @@ int pmf_register_irq_client(struct device_node *target, spin_lock_irqsave(&pmf_lock, flags); func = __pmf_find_function(target, name, PMF_FLAGS_INT_GEN); - if (func == NULL) { - spin_unlock_irqrestore(&pmf_lock, flags); + if (func) + func = pmf_get_function(func); + spin_unlock_irqrestore(&pmf_lock, flags); + if (func == NULL) return -ENODEV; - } + mutex_lock(&pmf_irq_mutex); if (list_empty(&func->irq_clients)) func->dev->handlers->irq_enable(func); list_add(&client->link, &func->irq_clients); client->func = func; - spin_unlock_irqrestore(&pmf_lock, flags); + mutex_unlock(&pmf_irq_mutex); return 0; } @@ -881,16 +885,16 @@ EXPORT_SYMBOL_GPL(pmf_register_irq_client); void pmf_unregister_irq_client(struct pmf_irq_client *client) { struct pmf_function *func = client->func; - unsigned long flags; BUG_ON(func == NULL); - spin_lock_irqsave(&pmf_lock, flags); + mutex_lock(&pmf_irq_mutex); client->func = NULL; list_del(&client->link); if (list_empty(&func->irq_clients)) func->dev->handlers->irq_disable(func); - spin_unlock_irqrestore(&pmf_lock, flags); + mutex_unlock(&pmf_irq_mutex); + pmf_put_function(func); } EXPORT_SYMBOL_GPL(pmf_unregister_irq_client); diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index ee89d19..1e28518 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c @@ -389,6 +389,7 @@ static int __init pSeries_probe_hypertas(unsigned long node, static int __init pSeries_probe(void) { + unsigned long root = of_get_flat_dt_root(); char *dtype = of_get_flat_dt_prop(of_get_flat_dt_root(), "device_type", NULL); if (dtype == NULL) @@ -396,6 +397,13 @@ static int __init pSeries_probe(void) if (strcmp(dtype, "chrp")) return 0; + /* Cell blades firmware claims to be chrp while it's not. Until this + * is fixed, we need to avoid those here. + */ + if (of_flat_dt_is_compatible(root, "IBM,CPBW-1.0") || + of_flat_dt_is_compatible(root, "IBM,CBEA")) + return 0; + DBG("pSeries detected, looking for LPAR capability...\n"); /* Now try to figure out if we are running on LPAR */ diff --git a/arch/sparc/kernel/smp.c b/arch/sparc/kernel/smp.c index a93f5da..40b42c8 100644 --- a/arch/sparc/kernel/smp.c +++ b/arch/sparc/kernel/smp.c @@ -69,6 +69,17 @@ void __init smp_store_cpu_info(int id) "clock-frequency", 0); cpu_data(id).prom_node = cpu_node; cpu_data(id).mid = cpu_get_hwmid(cpu_node); + + /* this is required to tune the scheduler correctly */ + /* is it possible to have CPUs with different cache sizes? */ + if (id == boot_cpu_id) { + int cache_line,cache_nlines; + cache_line = 0x20; + cache_line = prom_getintdefault(cpu_node, "ecache-line-size", cache_line); + cache_nlines = 0x8000; + cache_nlines = prom_getintdefault(cpu_node, "ecache-nlines", cache_nlines); + max_cache_size = cache_line * cache_nlines; + } if (cpu_data(id).mid < 0) panic("No MID found for CPU%d at node 0x%08d", id, cpu_node); } diff --git a/arch/sparc64/kernel/head.S b/arch/sparc64/kernel/head.S index 3eadac5..31c5892 100644 --- a/arch/sparc64/kernel/head.S +++ b/arch/sparc64/kernel/head.S @@ -10,6 +10,7 @@ #include <linux/config.h> #include <linux/version.h> #include <linux/errno.h> +#include <linux/threads.h> #include <asm/thread_info.h> #include <asm/asi.h> #include <asm/pstate.h> @@ -493,6 +494,35 @@ tlb_fixup_done: call prom_init mov %l7, %o0 ! OpenPROM cif handler + /* Initialize current_thread_info()->cpu as early as possible. + * In order to do that accurately we have to patch up the get_cpuid() + * assembler sequences. And that, in turn, requires that we know + * if we are on a Starfire box or not. While we're here, patch up + * the sun4v sequences as well. + */ + call check_if_starfire + nop + call per_cpu_patch + nop + call sun4v_patch + nop + +#ifdef CONFIG_SMP + call hard_smp_processor_id + nop + cmp %o0, NR_CPUS + blu,pt %xcc, 1f + nop + call boot_cpu_id_too_large + nop + /* Not reached... */ + +1: +#else + mov 0, %o0 +#endif + stb %o0, [%g6 + TI_CPU] + /* Off we go.... */ call start_kernel nop diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c index 2b7a1f3..0c08952 100644 --- a/arch/sparc64/kernel/pci_sun4v.c +++ b/arch/sparc64/kernel/pci_sun4v.c @@ -599,18 +599,128 @@ struct pci_iommu_ops pci_sun4v_iommu_ops = { /* SUN4V PCI configuration space accessors. */ -static inline int pci_sun4v_out_of_range(struct pci_pbm_info *pbm, unsigned int bus, unsigned int device, unsigned int func) +struct pdev_entry { + struct pdev_entry *next; + u32 devhandle; + unsigned int bus; + unsigned int device; + unsigned int func; +}; + +#define PDEV_HTAB_SIZE 16 +#define PDEV_HTAB_MASK (PDEV_HTAB_SIZE - 1) +static struct pdev_entry *pdev_htab[PDEV_HTAB_SIZE]; + +static inline unsigned int pdev_hashfn(u32 devhandle, unsigned int bus, unsigned int device, unsigned int func) { - if (bus == pbm->pci_first_busno) { - if (device == 0 && func == 0) - return 0; - return 1; + unsigned int val; + + val = (devhandle ^ (devhandle >> 4)); + val ^= bus; + val ^= device; + val ^= func; + + return val & PDEV_HTAB_MASK; +} + +static int pdev_htab_add(u32 devhandle, unsigned int bus, unsigned int device, unsigned int func) +{ + struct pdev_entry *p = kmalloc(sizeof(*p), GFP_KERNEL); + struct pdev_entry **slot; + + if (!p) + return -ENOMEM; + + slot = &pdev_htab[pdev_hashfn(devhandle, bus, device, func)]; + p->next = *slot; + *slot = p; + + p->devhandle = devhandle; + p->bus = bus; + p->device = device; + p->func = func; + + return 0; +} + +/* Recursively descend into the OBP device tree, rooted at toplevel_node, + * looking for a PCI device matching bus and devfn. + */ +static int obp_find(struct linux_prom_pci_registers *pregs, int toplevel_node, unsigned int bus, unsigned int devfn) +{ + toplevel_node = prom_getchild(toplevel_node); + + while (toplevel_node != 0) { + int ret = obp_find(pregs, toplevel_node, bus, devfn); + + if (ret != 0) + return ret; + + ret = prom_getproperty(toplevel_node, "reg", (char *) pregs, + sizeof(*pregs) * PROMREG_MAX); + if (ret == 0 || ret == -1) + goto next_sibling; + + if (((pregs[0].phys_hi >> 16) & 0xff) == bus && + ((pregs[0].phys_hi >> 8) & 0xff) == devfn) + break; + + next_sibling: + toplevel_node = prom_getsibling(toplevel_node); + } + + return toplevel_node; +} + +static int pdev_htab_populate(struct pci_pbm_info *pbm) +{ + struct linux_prom_pci_registers pr[PROMREG_MAX]; + u32 devhandle = pbm->devhandle; + unsigned int bus; + + for (bus = pbm->pci_first_busno; bus <= pbm->pci_last_busno; bus++) { + unsigned int devfn; + + for (devfn = 0; devfn < 256; devfn++) { + unsigned int device = PCI_SLOT(devfn); + unsigned int func = PCI_FUNC(devfn); + + if (obp_find(pr, pbm->prom_node, bus, devfn)) { + int err = pdev_htab_add(devhandle, bus, + device, func); + if (err) + return err; + } + } + } + + return 0; +} + +static struct pdev_entry *pdev_find(u32 devhandle, unsigned int bus, unsigned int device, unsigned int func) +{ + struct pdev_entry *p; + + p = pdev_htab[pdev_hashfn(devhandle, bus, device, func)]; + while (p) { + if (p->devhandle == devhandle && + p->bus == bus && + p->device == device && + p->func == func) + break; + + p = p->next; } + return p; +} + +static inline int pci_sun4v_out_of_range(struct pci_pbm_info *pbm, unsigned int bus, unsigned int device, unsigned int func) +{ if (bus < pbm->pci_first_busno || bus > pbm->pci_last_busno) return 1; - return 0; + return pdev_find(pbm->devhandle, bus, device, func) == NULL; } static int pci_sun4v_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, @@ -1063,6 +1173,8 @@ static void pci_sun4v_pbm_init(struct pci_controller_info *p, int prom_node, u32 pci_sun4v_get_bus_range(pbm); pci_sun4v_iommu_init(pbm); + + pdev_htab_populate(pbm); } void sun4v_pci_init(int node, char *model_name) diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c index 005167f..9cf1c88 100644 --- a/arch/sparc64/kernel/setup.c +++ b/arch/sparc64/kernel/setup.c @@ -220,7 +220,7 @@ char reboot_command[COMMAND_LINE_SIZE]; static struct pt_regs fake_swapper_regs = { { 0, }, 0, 0, 0, 0 }; -static void __init per_cpu_patch(void) +void __init per_cpu_patch(void) { struct cpuid_patch_entry *p; unsigned long ver; @@ -280,7 +280,7 @@ static void __init per_cpu_patch(void) } } -static void __init sun4v_patch(void) +void __init sun4v_patch(void) { struct sun4v_1insn_patch_entry *p1; struct sun4v_2insn_patch_entry *p2; @@ -315,6 +315,15 @@ static void __init sun4v_patch(void) } } +#ifdef CONFIG_SMP +void __init boot_cpu_id_too_large(int cpu) +{ + prom_printf("Serious problem, boot cpu id (%d) >= NR_CPUS (%d)\n", + cpu, NR_CPUS); + prom_halt(); +} +#endif + void __init setup_arch(char **cmdline_p) { /* Initialize PROM console and command line. */ @@ -332,16 +341,6 @@ void __init setup_arch(char **cmdline_p) conswitchp = &prom_con; #endif - /* Work out if we are starfire early on */ - check_if_starfire(); - - /* Now we know enough to patch the get_cpuid sequences - * used by trap code. - */ - per_cpu_patch(); - - sun4v_patch(); - boot_flags_init(*cmdline_p); idprom_init(); diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c index 90eaca3..f03d52d 100644 --- a/arch/sparc64/kernel/smp.c +++ b/arch/sparc64/kernel/smp.c @@ -1264,7 +1264,6 @@ void __init smp_tick_init(void) boot_cpu_id = hard_smp_processor_id(); current_tick_offset = timer_tick_offset; - cpu_set(boot_cpu_id, cpu_online_map); prof_counter(boot_cpu_id) = prof_multiplier(boot_cpu_id) = 1; } @@ -1288,6 +1287,40 @@ int setup_profiling_timer(unsigned int multiplier) return 0; } +static void __init smp_tune_scheduling(void) +{ + int instance, node; + unsigned int def, smallest = ~0U; + + def = ((tlb_type == hypervisor) ? + (3 * 1024 * 1024) : + (4 * 1024 * 1024)); + + instance = 0; + while (!cpu_find_by_instance(instance, &node, NULL)) { + unsigned int val; + + val = prom_getintdefault(node, "ecache-size", def); + if (val < smallest) + smallest = val; + + instance++; + } + + /* Any value less than 256K is nonsense. */ + if (smallest < (256U * 1024U)) + smallest = 256 * 1024; + + max_cache_size = smallest; + + if (smallest < 1U * 1024U * 1024U) + printk(KERN_INFO "Using max_cache_size of %uKB\n", + smallest / 1024U); + else + printk(KERN_INFO "Using max_cache_size of %uMB\n", + smallest / 1024U / 1024U); +} + /* Constrain the number of cpus to max_cpus. */ void __init smp_prepare_cpus(unsigned int max_cpus) { @@ -1323,6 +1356,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus) } smp_store_cpu_info(boot_cpu_id); + smp_tune_scheduling(); } /* Set this up early so that things like the scheduler can init @@ -1345,18 +1379,6 @@ void __init smp_setup_cpu_possible_map(void) void __devinit smp_prepare_boot_cpu(void) { - int cpu = hard_smp_processor_id(); - - if (cpu >= NR_CPUS) { - prom_printf("Serious problem, boot cpu id >= NR_CPUS\n"); - prom_halt(); - } - - current_thread_info()->cpu = cpu; - __local_per_cpu_offset = __per_cpu_offset(cpu); - - cpu_set(smp_processor_id(), cpu_online_map); - cpu_set(smp_processor_id(), phys_cpu_present_map); } int __devinit __cpu_up(unsigned int cpu) @@ -1433,4 +1455,7 @@ void __init setup_per_cpu_areas(void) for (i = 0; i < NR_CPUS; i++, ptr += size) memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start); + + /* Setup %g5 for the boot cpu. */ + __local_per_cpu_offset = __per_cpu_offset(smp_processor_id()); } diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c index 2793a5d..563db52 100644 --- a/arch/sparc64/kernel/traps.c +++ b/arch/sparc64/kernel/traps.c @@ -1797,7 +1797,9 @@ static const char *sun4v_err_type_to_str(u32 type) }; } -static void sun4v_log_error(struct sun4v_error_entry *ent, int cpu, const char *pfx, atomic_t *ocnt) +extern void __show_regs(struct pt_regs * regs); + +static void sun4v_log_error(struct pt_regs *regs, struct sun4v_error_entry *ent, int cpu, const char *pfx, atomic_t *ocnt) { int cnt; @@ -1830,6 +1832,8 @@ static void sun4v_log_error(struct sun4v_error_entry *ent, int cpu, const char * pfx, ent->err_raddr, ent->err_size, ent->err_cpu); + __show_regs(regs); + if ((cnt = atomic_read(ocnt)) != 0) { atomic_set(ocnt, 0); wmb(); @@ -1862,7 +1866,7 @@ void sun4v_resum_error(struct pt_regs *regs, unsigned long offset) put_cpu(); - sun4v_log_error(&local_copy, cpu, + sun4v_log_error(regs, &local_copy, cpu, KERN_ERR "RESUMABLE ERROR", &sun4v_resum_oflow_cnt); } @@ -1910,7 +1914,7 @@ void sun4v_nonresum_error(struct pt_regs *regs, unsigned long offset) } #endif - sun4v_log_error(&local_copy, cpu, + sun4v_log_error(regs, &local_copy, cpu, KERN_EMERG "NON-RESUMABLE ERROR", &sun4v_nonresum_oflow_cnt); @@ -2200,7 +2204,6 @@ static inline struct reg_window *kernel_stack_up(struct reg_window *rw) void die_if_kernel(char *str, struct pt_regs *regs) { static int die_counter; - extern void __show_regs(struct pt_regs * regs); extern void smp_report_regs(void); int count = 0; diff --git a/arch/sparc64/lib/checksum.S b/arch/sparc64/lib/checksum.S index ba9cd3c..1d230f6 100644 --- a/arch/sparc64/lib/checksum.S +++ b/arch/sparc64/lib/checksum.S @@ -165,8 +165,9 @@ csum_partial_end_cruft: sll %g1, 8, %g1 or %o5, %g1, %o4 -1: add %o2, %o4, %o2 +1: addcc %o2, %o4, %o2 + addc %g0, %o2, %o2 csum_partial_finish: retl - mov %o2, %o0 + srl %o2, 0, %o0 diff --git a/arch/sparc64/lib/csum_copy.S b/arch/sparc64/lib/csum_copy.S index 71af488..e566c77 100644 --- a/arch/sparc64/lib/csum_copy.S +++ b/arch/sparc64/lib/csum_copy.S @@ -221,11 +221,12 @@ FUNC_NAME: /* %o0=src, %o1=dst, %o2=len, %o3=sum */ sll %g1, 8, %g1 or %o5, %g1, %o4 -1: add %o3, %o4, %o3 +1: addcc %o3, %o4, %o3 + addc %g0, %o3, %o3 70: retl - mov %o3, %o0 + srl %o3, 0, %o0 95: mov 0, GLOBAL_SPARE brlez,pn %o2, 4f diff --git a/arch/um/Makefile-i386 b/arch/um/Makefile-i386 index 7a0e04e..b65ca11 100644 --- a/arch/um/Makefile-i386 +++ b/arch/um/Makefile-i386 @@ -33,5 +33,9 @@ include $(srctree)/arch/i386/Makefile.cpu # prevent gcc from keeping the stack 16 byte aligned. Taken from i386. cflags-y += $(call cc-option,-mpreferred-stack-boundary=2) +# Prevent sprintf in nfsd from being converted to strcpy and resulting in +# an unresolved reference. +cflags-y += -ffreestanding + CFLAGS += $(cflags-y) USER_CFLAGS += $(cflags-y) diff --git a/arch/um/include/kern_util.h b/arch/um/include/kern_util.h index efa3d33..310980b 100644 --- a/arch/um/include/kern_util.h +++ b/arch/um/include/kern_util.h @@ -120,20 +120,11 @@ extern int is_syscall(unsigned long addr); extern void free_irq(unsigned int, void *); extern int cpu(void); +extern void time_init_kern(void); + /* Are we disallowed to sleep? Used to choose between GFP_KERNEL and GFP_ATOMIC. */ extern int __cant_sleep(void); extern void segv_handler(int sig, union uml_pt_regs *regs); extern void sigio_handler(int sig, union uml_pt_regs *regs); #endif - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff --git a/arch/um/kernel/time_kern.c b/arch/um/kernel/time_kern.c index 528cf62..86f51d0 100644 --- a/arch/um/kernel/time_kern.c +++ b/arch/um/kernel/time_kern.c @@ -84,6 +84,16 @@ void timer_irq(union uml_pt_regs *regs) } } + +void time_init_kern(void) +{ + unsigned long long nsecs; + + nsecs = os_nsecs(); + set_normalized_timespec(&wall_to_monotonic, -nsecs / BILLION, + -nsecs % BILLION); +} + void do_boot_timer_handler(struct sigcontext * sc) { struct pt_regs regs; diff --git a/arch/um/os-Linux/main.c b/arch/um/os-Linux/main.c index 3a0ac38..90912aa 100644 --- a/arch/um/os-Linux/main.c +++ b/arch/um/os-Linux/main.c @@ -59,7 +59,7 @@ static __init void do_uml_initcalls(void) initcall_t *call; call = &__uml_initcall_start; - while (call < &__uml_initcall_end){; + while (call < &__uml_initcall_end){ (*call)(); call++; } diff --git a/arch/um/os-Linux/time.c b/arch/um/os-Linux/time.c index 6f76267..280c4fb 100644 --- a/arch/um/os-Linux/time.c +++ b/arch/um/os-Linux/time.c @@ -81,20 +81,12 @@ void uml_idle_timer(void) set_interval(ITIMER_REAL); } -extern void ktime_get_ts(struct timespec *ts); -#define do_posix_clock_monotonic_gettime(ts) ktime_get_ts(ts) - void time_init(void) { - struct timespec now; - if(signal(SIGVTALRM, boot_timer_handler) == SIG_ERR) panic("Couldn't set SIGVTALRM handler"); set_interval(ITIMER_VIRTUAL); - - do_posix_clock_monotonic_gettime(&now); - wall_to_monotonic.tv_sec = -now.tv_sec; - wall_to_monotonic.tv_nsec = -now.tv_nsec; + time_init_kern(); } unsigned long long os_nsecs(void) diff --git a/arch/um/sys-i386/syscalls.c b/arch/um/sys-i386/syscalls.c index 749dd1b..710d5fb 100644 --- a/arch/um/sys-i386/syscalls.c +++ b/arch/um/sys-i386/syscalls.c @@ -99,11 +99,12 @@ long sys_ipc (uint call, int first, int second, switch (call) { case SEMOP: - return sys_semtimedop(first, (struct sembuf *) ptr, second, - NULL); + return sys_semtimedop(first, (struct sembuf __user *) ptr, + second, NULL); case SEMTIMEDOP: - return sys_semtimedop(first, (struct sembuf *) ptr, second, - (const struct timespec *) fifth); + return sys_semtimedop(first, (struct sembuf __user *) ptr, + second, + (const struct timespec __user *) fifth); case SEMGET: return sys_semget (first, second, third); case SEMCTL: { diff --git a/arch/um/sys-x86_64/signal.c b/arch/um/sys-x86_64/signal.c index a4c46a8..9edf114 100644 --- a/arch/um/sys-x86_64/signal.c +++ b/arch/um/sys-x86_64/signal.c @@ -21,7 +21,7 @@ #include "skas.h" static int copy_sc_from_user_skas(struct pt_regs *regs, - struct sigcontext *from) + struct sigcontext __user *from) { int err = 0; @@ -54,7 +54,8 @@ static int copy_sc_from_user_skas(struct pt_regs *regs, return(err); } -int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate *to_fp, +int copy_sc_to_user_skas(struct sigcontext __user *to, + struct _fpstate __user *to_fp, struct pt_regs *regs, unsigned long mask, unsigned long sp) { @@ -106,10 +107,11 @@ int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate *to_fp, #endif #ifdef CONFIG_MODE_TT -int copy_sc_from_user_tt(struct sigcontext *to, struct sigcontext *from, +int copy_sc_from_user_tt(struct sigcontext *to, struct sigcontext __user *from, int fpsize) { - struct _fpstate *to_fp, *from_fp; + struct _fpstate *to_fp; + struct _fpstate __user *from_fp; unsigned long sigs; int err; @@ -124,13 +126,14 @@ int copy_sc_from_user_tt(struct sigcontext *to, struct sigcontext *from, return(err); } -int copy_sc_to_user_tt(struct sigcontext *to, struct _fpstate *fp, +int copy_sc_to_user_tt(struct sigcontext __user *to, struct _fpstate __user *fp, struct sigcontext *from, int fpsize, unsigned long sp) { - struct _fpstate *to_fp, *from_fp; + struct _fpstate __user *to_fp; + struct _fpstate *from_fp; int err; - to_fp = (fp ? fp : (struct _fpstate *) (to + 1)); + to_fp = (fp ? fp : (struct _fpstate __user *) (to + 1)); from_fp = from->fpstate; err = copy_to_user(to, from, sizeof(*to)); /* The SP in the sigcontext is the updated one for the signal @@ -158,7 +161,8 @@ static int copy_sc_from_user(struct pt_regs *to, void __user *from) return(ret); } -static int copy_sc_to_user(struct sigcontext *to, struct _fpstate *fp, +static int copy_sc_to_user(struct sigcontext __user *to, + struct _fpstate __user *fp, struct pt_regs *from, unsigned long mask, unsigned long sp) { @@ -169,7 +173,7 @@ static int copy_sc_to_user(struct sigcontext *to, struct _fpstate *fp, struct rt_sigframe { - char *pretcode; + char __user *pretcode; struct ucontext uc; struct siginfo info; }; @@ -188,7 +192,7 @@ int setup_signal_stack_si(unsigned long stack_top, int sig, frame = (struct rt_sigframe __user *) round_down(stack_top - sizeof(struct rt_sigframe), 16) - 8; - frame = (struct rt_sigframe *) ((unsigned long) frame - 128); + frame = (struct rt_sigframe __user *) ((unsigned long) frame - 128); if (!access_ok(VERIFY_WRITE, fp, sizeof(struct _fpstate))) goto out; diff --git a/arch/um/sys-x86_64/syscalls.c b/arch/um/sys-x86_64/syscalls.c index 6acee5c..6fce9f4 100644 --- a/arch/um/sys-x86_64/syscalls.c +++ b/arch/um/sys-x86_64/syscalls.c @@ -45,7 +45,7 @@ static long arch_prctl_tt(int code, unsigned long addr) case ARCH_GET_GS: ret = arch_prctl(code, (unsigned long) &tmp); if(!ret) - ret = put_user(tmp, &addr); + ret = put_user(tmp, (long __user *)addr); break; default: ret = -EINVAL; diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c index 0de3ea9..9cc7031 100644 --- a/arch/x86_64/kernel/io_apic.c +++ b/arch/x86_64/kernel/io_apic.c @@ -271,6 +271,18 @@ __setup("enable_8254_timer", setup_enable_8254_timer); #include <linux/pci_ids.h> #include <linux/pci.h> + +#ifdef CONFIG_ACPI + +static int nvidia_hpet_detected __initdata; + +static int __init nvidia_hpet_check(unsigned long phys, unsigned long size) +{ + nvidia_hpet_detected = 1; + return 0; +} +#endif + /* Temporary Hack. Nvidia and VIA boards currently only work with IO-APIC off. Check for an Nvidia or VIA PCI bridge and turn it off. Use pci direct infrastructure because this runs before the PCI subsystem. @@ -317,11 +329,19 @@ void __init check_ioapic(void) return; case PCI_VENDOR_ID_NVIDIA: #ifdef CONFIG_ACPI - /* All timer overrides on Nvidia - seem to be wrong. Skip them. */ - acpi_skip_timer_override = 1; - printk(KERN_INFO - "Nvidia board detected. Ignoring ACPI timer override.\n"); + /* + * All timer overrides on Nvidia are + * wrong unless HPET is enabled. + */ + nvidia_hpet_detected = 0; + acpi_table_parse(ACPI_HPET, + nvidia_hpet_check); + if (nvidia_hpet_detected == 0) { + acpi_skip_timer_override = 1; + printk(KERN_INFO "Nvidia board " + "detected. Ignoring ACPI " + "timer override.\n"); + } #endif /* RED-PEN skip them on mptables too? */ return; |