diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/configs/prpmc2800_defconfig | 2 | ||||
-rw-r--r-- | arch/powerpc/kernel/pci-common.c | 2 | ||||
-rw-r--r-- | arch/powerpc/kernel/prom.c | 2 | ||||
-rw-r--r-- | arch/powerpc/kernel/smp.c | 7 | ||||
-rw-r--r-- | arch/powerpc/mm/fault.c | 8 | ||||
-rw-r--r-- | arch/powerpc/mm/hash_utils_64.c | 4 | ||||
-rw-r--r-- | arch/powerpc/platforms/Kconfig.cputype | 2 | ||||
-rw-r--r-- | arch/powerpc/platforms/embedded6xx/Kconfig | 2 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/firmware.c | 19 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/pseries.h | 2 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/setup.c | 17 | ||||
-rw-r--r-- | arch/powerpc/sysdev/mpic.c | 32 | ||||
-rw-r--r-- | arch/powerpc/xmon/nonstdio.c | 5 | ||||
-rw-r--r-- | arch/powerpc/xmon/nonstdio.h | 3 | ||||
-rw-r--r-- | arch/powerpc/xmon/start.c | 2 | ||||
-rw-r--r-- | arch/powerpc/xmon/xmon.c | 2 | ||||
-rw-r--r-- | arch/ppc/syslib/mv64x60.c | 15 |
17 files changed, 84 insertions, 42 deletions
diff --git a/arch/powerpc/configs/prpmc2800_defconfig b/arch/powerpc/configs/prpmc2800_defconfig index fb504a714625..858f865f2d59 100644 --- a/arch/powerpc/configs/prpmc2800_defconfig +++ b/arch/powerpc/configs/prpmc2800_defconfig @@ -48,7 +48,7 @@ CONFIG_PPC_STD_MMU_32=y # CONFIG_PPC_MM_SLICES is not set # CONFIG_SMP is not set CONFIG_NOT_COHERENT_CACHE=y -CONFIG_CONFIG_CHECK_CACHE_COHERENCY=y +CONFIG_CHECK_CACHE_COHERENCY=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index 94b4a028232a..fe7d1255e11e 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c @@ -166,7 +166,7 @@ int pcibios_add_platform_entries(struct pci_dev *pdev) } -char __init *pcibios_setup(char *str) +char __devinit *pcibios_setup(char *str) { return str; } diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index bdcd23d8d8b9..a38197b12d3e 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -1218,7 +1218,7 @@ void of_attach_node(struct device_node *np) * a reference to the node. The memory associated with the node * is not freed until its refcount goes to zero. */ -void of_detach_node(const struct device_node *np) +void of_detach_node(struct device_node *np) { struct device_node *parent; diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index d577b71db375..087c92f2a3eb 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -284,7 +284,7 @@ int smp_call_function_single(int cpu, void (*func) (void *info), void *info, int int wait) { cpumask_t map = CPU_MASK_NONE; - int ret = -EBUSY; + int ret = 0; if (!cpu_online(cpu)) return -EINVAL; @@ -292,6 +292,11 @@ int smp_call_function_single(int cpu, void (*func) (void *info), void *info, int cpu_set(cpu, map); if (cpu != get_cpu()) ret = smp_call_function_map(func,info,nonatomic,wait,map); + else { + local_irq_disable(); + func(info); + local_irq_enable(); + } put_cpu(); return ret; } diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c index 3767211b3d0f..ab3546c5ac3a 100644 --- a/arch/powerpc/mm/fault.c +++ b/arch/powerpc/mm/fault.c @@ -283,7 +283,13 @@ good_area: /* protection fault */ if (error_code & DSISR_PROTFAULT) goto bad_area; - if (!(vma->vm_flags & VM_EXEC)) + /* + * Allow execution from readable areas if the MMU does not + * provide separate controls over reading and executing. + */ + if (!(vma->vm_flags & VM_EXEC) && + (cpu_has_feature(CPU_FTR_NOEXECUTE) || + !(vma->vm_flags & (VM_READ | VM_WRITE)))) goto bad_area; #else pte_t *ptep; diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c index 2ce9491b48d4..bc7b0cedae5e 100644 --- a/arch/powerpc/mm/hash_utils_64.c +++ b/arch/powerpc/mm/hash_utils_64.c @@ -609,7 +609,7 @@ static void demote_segment_4k(struct mm_struct *mm, unsigned long addr) mm->context.sllp = SLB_VSID_USER | mmu_psize_defs[MMU_PAGE_4K].sllp; #endif /* CONFIG_PPC_MM_SLICES */ -#ifdef CONFIG_SPE_BASE +#ifdef CONFIG_SPU_BASE spu_flush_all_slbs(mm); #endif } @@ -744,7 +744,7 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap) "to 4kB pages because of " "non-cacheable mapping\n"); psize = mmu_vmalloc_psize = MMU_PAGE_4K; -#ifdef CONFIG_SPE_BASE +#ifdef CONFIG_SPU_BASE spu_flush_all_slbs(mm); #endif } diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype index b8b5fde94668..e4b2aee53a73 100644 --- a/arch/powerpc/platforms/Kconfig.cputype +++ b/arch/powerpc/platforms/Kconfig.cputype @@ -215,7 +215,7 @@ config NOT_COHERENT_CACHE depends on 4xx || 8xx || E200 default y -config CONFIG_CHECK_CACHE_COHERENCY +config CHECK_CACHE_COHERENCY bool endmenu diff --git a/arch/powerpc/platforms/embedded6xx/Kconfig b/arch/powerpc/platforms/embedded6xx/Kconfig index bec772674e40..2d12f77e46bc 100644 --- a/arch/powerpc/platforms/embedded6xx/Kconfig +++ b/arch/powerpc/platforms/embedded6xx/Kconfig @@ -59,7 +59,7 @@ config MPC10X_BRIDGE config MV64X60 bool select PPC_INDIRECT_PCI - select CONFIG_CHECK_CACHE_COHERENCY + select CHECK_CACHE_COHERENCY config MPC10X_OPENPIC bool diff --git a/arch/powerpc/platforms/pseries/firmware.c b/arch/powerpc/platforms/pseries/firmware.c index 29bf83bfb1f0..8b18a1c40092 100644 --- a/arch/powerpc/platforms/pseries/firmware.c +++ b/arch/powerpc/platforms/pseries/firmware.c @@ -66,24 +66,13 @@ firmware_features_table[FIRMWARE_MAX_FEATURES] = { * device-tree/ibm,hypertas-functions. Ultimately this functionality may * be moved into prom.c prom_init(). */ -void __init fw_feature_init(void) +void __init fw_feature_init(const char *hypertas, unsigned long len) { - struct device_node *dn; - const char *hypertas, *s; - int len, i; + const char *s; + int i; DBG(" -> fw_feature_init()\n"); - dn = of_find_node_by_path("/rtas"); - if (dn == NULL) { - printk(KERN_ERR "WARNING! Cannot find RTAS in device-tree!\n"); - goto out; - } - - hypertas = of_get_property(dn, "ibm,hypertas-functions", &len); - if (hypertas == NULL) - goto out; - for (s = hypertas; s < hypertas + len; s += strlen(s) + 1) { for (i = 0; i < FIRMWARE_MAX_FEATURES; i++) { /* check value against table of strings */ @@ -98,7 +87,5 @@ void __init fw_feature_init(void) } } -out: - of_node_put(dn); DBG(" <- fw_feature_init()\n"); } diff --git a/arch/powerpc/platforms/pseries/pseries.h b/arch/powerpc/platforms/pseries/pseries.h index 61e19f78b923..61136d019554 100644 --- a/arch/powerpc/platforms/pseries/pseries.h +++ b/arch/powerpc/platforms/pseries/pseries.h @@ -10,7 +10,7 @@ #ifndef _PSERIES_PSERIES_H #define _PSERIES_PSERIES_H -extern void __init fw_feature_init(void); +extern void __init fw_feature_init(const char *hypertas, unsigned long len); struct pt_regs; diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index 59e69f085cb4..f0b7146a110f 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c @@ -320,8 +320,6 @@ static void __init pSeries_init_early(void) { DBG(" -> pSeries_init_early()\n"); - fw_feature_init(); - if (firmware_has_feature(FW_FEATURE_LPAR)) find_udbg_vterm(); @@ -343,14 +341,21 @@ static int __init pSeries_probe_hypertas(unsigned long node, const char *uname, int depth, void *data) { + const char *hypertas; + unsigned long len; + if (depth != 1 || (strcmp(uname, "rtas") != 0 && strcmp(uname, "rtas@0") != 0)) - return 0; + return 0; + + hypertas = of_get_flat_dt_prop(node, "ibm,hypertas-functions", &len); + if (!hypertas) + return 1; - if (of_get_flat_dt_prop(node, "ibm,hypertas-functions", NULL) != NULL) - powerpc_firmware_features |= FW_FEATURE_LPAR; + powerpc_firmware_features |= FW_FEATURE_LPAR; + fw_feature_init(hypertas, len); - return 1; + return 1; } static int __init pSeries_probe(void) diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index 75aad38179f0..74c64c0d3b71 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c @@ -877,6 +877,8 @@ static int mpic_host_map(struct irq_host *h, unsigned int virq, if (hw == mpic->spurious_vec) return -EINVAL; + if (mpic->protected && test_bit(hw, mpic->protected)) + return -EINVAL; #ifdef CONFIG_SMP else if (hw >= mpic->ipi_vecs[0]) { @@ -1034,6 +1036,25 @@ struct mpic * __init mpic_alloc(struct device_node *node, if (node && of_get_property(node, "big-endian", NULL) != NULL) mpic->flags |= MPIC_BIG_ENDIAN; + /* Look for protected sources */ + if (node) { + unsigned int psize, bits, mapsize; + const u32 *psrc = + of_get_property(node, "protected-sources", &psize); + if (psrc) { + psize /= 4; + bits = intvec_top + 1; + mapsize = BITS_TO_LONGS(bits) * sizeof(unsigned long); + mpic->protected = alloc_bootmem(mapsize); + BUG_ON(mpic->protected == NULL); + memset(mpic->protected, 0, mapsize); + for (i = 0; i < psize; i++) { + if (psrc[i] > intvec_top) + continue; + __set_bit(psrc[i], mpic->protected); + } + } + } #ifdef CONFIG_MPIC_WEIRD mpic->hw_set = mpic_infos[MPIC_GET_REGSET(flags)]; @@ -1213,6 +1234,9 @@ void __init mpic_init(struct mpic *mpic) u32 vecpri = MPIC_VECPRI_MASK | i | (8 << MPIC_VECPRI_PRIORITY_SHIFT); + /* check if protected */ + if (mpic->protected && test_bit(i, mpic->protected)) + continue; /* init hw */ mpic_irq_write(i, MPIC_INFO(IRQ_VECTOR_PRI), vecpri); mpic_irq_write(i, MPIC_INFO(IRQ_DESTINATION), @@ -1407,6 +1431,14 @@ unsigned int mpic_get_one_irq(struct mpic *mpic) mpic_eoi(mpic); return NO_IRQ; } + if (unlikely(mpic->protected && test_bit(src, mpic->protected))) { + if (printk_ratelimit()) + printk(KERN_WARNING "%s: Got protected source %d !\n", + mpic->name, (int)src); + mpic_eoi(mpic); + return NO_IRQ; + } + return irq_linear_revmap(mpic->irqhost, src); } diff --git a/arch/powerpc/xmon/nonstdio.c b/arch/powerpc/xmon/nonstdio.c index 78765833f4c0..bfac84fbe780 100644 --- a/arch/powerpc/xmon/nonstdio.c +++ b/arch/powerpc/xmon/nonstdio.c @@ -132,3 +132,8 @@ void xmon_printf(const char *format, ...) va_end(args); xmon_write(xmon_outbuf, n); } + +void xmon_puts(const char *str) +{ + xmon_write(str, strlen(str)); +} diff --git a/arch/powerpc/xmon/nonstdio.h b/arch/powerpc/xmon/nonstdio.h index 47cebbd2b1b1..23dd95f4599c 100644 --- a/arch/powerpc/xmon/nonstdio.h +++ b/arch/powerpc/xmon/nonstdio.h @@ -5,10 +5,11 @@ extern int xmon_putchar(int c); extern int xmon_getchar(void); +extern void xmon_puts(const char *); extern char *xmon_gets(char *, int); extern void xmon_printf(const char *, ...); extern void xmon_map_scc(void); extern int xmon_expect(const char *str, unsigned long timeout); -extern int xmon_write(void *ptr, int nb); +extern int xmon_write(const void *ptr, int nb); extern int xmon_readchar(void); extern int xmon_read_poll(void); diff --git a/arch/powerpc/xmon/start.c b/arch/powerpc/xmon/start.c index 712552c4f242..8864de2af382 100644 --- a/arch/powerpc/xmon/start.c +++ b/arch/powerpc/xmon/start.c @@ -14,7 +14,7 @@ void xmon_map_scc(void) { } -int xmon_write(void *ptr, int nb) +int xmon_write(const void *ptr, int nb) { return udbg_write(ptr, nb); } diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index 669e6566ad70..121b04d165d1 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -833,7 +833,7 @@ cmds(struct pt_regs *excp) mdelay(2000); return cmd; case '?': - printf(help_string); + xmon_puts(help_string); break; case 'b': bpt_cmds(); diff --git a/arch/ppc/syslib/mv64x60.c b/arch/ppc/syslib/mv64x60.c index 032f4b7f4225..d212b1c418a9 100644 --- a/arch/ppc/syslib/mv64x60.c +++ b/arch/ppc/syslib/mv64x60.c @@ -14,6 +14,7 @@ #include <linux/pci.h> #include <linux/slab.h> #include <linux/module.h> +#include <linux/mutex.h> #include <linux/string.h> #include <linux/spinlock.h> #include <linux/mv643xx.h> @@ -2359,7 +2360,7 @@ mv64460_chip_specific_init(struct mv64x60_handle *bh, /* Export the hotswap register via sysfs for enum event monitoring */ #define VAL_LEN_MAX 11 /* 32-bit hex or dec stringified number + '\n' */ -DECLARE_MUTEX(mv64xxx_hs_lock); +static DEFINE_MUTEX(mv64xxx_hs_lock); static ssize_t mv64xxx_hs_reg_read(struct kobject *kobj, char *buf, loff_t off, size_t count) @@ -2372,14 +2373,14 @@ mv64xxx_hs_reg_read(struct kobject *kobj, char *buf, loff_t off, size_t count) if (count < VAL_LEN_MAX) return -EINVAL; - if (down_interruptible(&mv64xxx_hs_lock)) + if (mutex_lock_interruptible(&mv64xxx_hs_lock)) return -ERESTARTSYS; save_exclude = mv64x60_pci_exclude_bridge; mv64x60_pci_exclude_bridge = 0; early_read_config_dword(&sysfs_hose_a, 0, PCI_DEVFN(0, 0), MV64360_PCICFG_CPCI_HOTSWAP, &v); mv64x60_pci_exclude_bridge = save_exclude; - up(&mv64xxx_hs_lock); + mutex_unlock(&mv64xxx_hs_lock); return sprintf(buf, "0x%08x\n", v); } @@ -2396,14 +2397,14 @@ mv64xxx_hs_reg_write(struct kobject *kobj, char *buf, loff_t off, size_t count) return -EINVAL; if (sscanf(buf, "%i", &v) == 1) { - if (down_interruptible(&mv64xxx_hs_lock)) + if (mutex_lock_interruptible(&mv64xxx_hs_lock)) return -ERESTARTSYS; save_exclude = mv64x60_pci_exclude_bridge; mv64x60_pci_exclude_bridge = 0; early_write_config_dword(&sysfs_hose_a, 0, PCI_DEVFN(0, 0), MV64360_PCICFG_CPCI_HOTSWAP, v); mv64x60_pci_exclude_bridge = save_exclude; - up(&mv64xxx_hs_lock); + mutex_unlock(&mv64xxx_hs_lock); } else count = -EINVAL; @@ -2433,10 +2434,10 @@ mv64xxx_hs_reg_valid_show(struct device *dev, struct device_attribute *attr, pdev = container_of(dev, struct platform_device, dev); pdp = (struct mv64xxx_pdata *)pdev->dev.platform_data; - if (down_interruptible(&mv64xxx_hs_lock)) + if (mutex_lock_interruptible(&mv64xxx_hs_lock)) return -ERESTARTSYS; v = pdp->hs_reg_valid; - up(&mv64xxx_hs_lock); + mutex_unlock(&mv64xxx_hs_lock); return sprintf(buf, "%i\n", v); } |