diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/include/asm/hardware/cache-l2x0.h | 9 | ||||
-rw-r--r-- | arch/arm/mach-integrator/integrator_ap.c | 6 | ||||
-rw-r--r-- | arch/arm/mm/abort-macro.S | 2 | ||||
-rw-r--r-- | arch/arm/mm/cache-l2x0.c | 21 | ||||
-rw-r--r-- | arch/arm/mm/init.c | 2 | ||||
-rw-r--r-- | arch/openrisc/include/asm/dma-mapping.h | 59 | ||||
-rw-r--r-- | arch/openrisc/include/asm/sigcontext.h | 7 | ||||
-rw-r--r-- | arch/openrisc/kernel/dma.c | 28 | ||||
-rw-r--r-- | arch/openrisc/kernel/signal.c | 29 | ||||
-rw-r--r-- | arch/x86/include/asm/pvclock.h | 2 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/perf_event.c | 3 | ||||
-rw-r--r-- | arch/x86/pci/acpi.c | 9 | ||||
-rw-r--r-- | arch/x86/xen/setup.c | 19 | ||||
-rw-r--r-- | arch/x86/xen/smp.c | 10 | ||||
-rw-r--r-- | arch/x86/xen/xen-asm_32.S | 8 |
15 files changed, 174 insertions, 40 deletions
diff --git a/arch/arm/include/asm/hardware/cache-l2x0.h b/arch/arm/include/asm/hardware/cache-l2x0.h index bfa706ffd968..99a6ed7e1bfd 100644 --- a/arch/arm/include/asm/hardware/cache-l2x0.h +++ b/arch/arm/include/asm/hardware/cache-l2x0.h @@ -45,8 +45,13 @@ #define L2X0_CLEAN_INV_LINE_PA 0x7F0 #define L2X0_CLEAN_INV_LINE_IDX 0x7F8 #define L2X0_CLEAN_INV_WAY 0x7FC -#define L2X0_LOCKDOWN_WAY_D 0x900 -#define L2X0_LOCKDOWN_WAY_I 0x904 +/* + * The lockdown registers repeat 8 times for L310, the L210 has only one + * D and one I lockdown register at 0x0900 and 0x0904. + */ +#define L2X0_LOCKDOWN_WAY_D_BASE 0x900 +#define L2X0_LOCKDOWN_WAY_I_BASE 0x904 +#define L2X0_LOCKDOWN_STRIDE 0x08 #define L2X0_TEST_OPERATION 0xF00 #define L2X0_LINE_DATA 0xF10 #define L2X0_LINE_TAG 0xF30 diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c index 2fbbdd5eac35..fcf0ae95651f 100644 --- a/arch/arm/mach-integrator/integrator_ap.c +++ b/arch/arm/mach-integrator/integrator_ap.c @@ -337,15 +337,15 @@ static unsigned long timer_reload; static void integrator_clocksource_init(u32 khz) { void __iomem *base = (void __iomem *)TIMER2_VA_BASE; - u32 ctrl = TIMER_CTRL_ENABLE; + u32 ctrl = TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC; if (khz >= 1500) { khz /= 16; - ctrl = TIMER_CTRL_DIV16; + ctrl |= TIMER_CTRL_DIV16; } - writel(ctrl, base + TIMER_CTRL); writel(0xffff, base + TIMER_LOAD); + writel(ctrl, base + TIMER_CTRL); clocksource_mmio_init(base + TIMER_VALUE, "timer2", khz * 1000, 200, 16, clocksource_mmio_readl_down); diff --git a/arch/arm/mm/abort-macro.S b/arch/arm/mm/abort-macro.S index 52162d59407a..2cbf68ef0e83 100644 --- a/arch/arm/mm/abort-macro.S +++ b/arch/arm/mm/abort-macro.S @@ -17,7 +17,7 @@ cmp \tmp, # 0x5600 @ Is it ldrsb? orreq \tmp, \tmp, #1 << 11 @ Set L-bit if yes tst \tmp, #1 << 11 @ L = 0 -> write - orreq \psr, \psr, #1 << 11 @ yes. + orreq \fsr, \fsr, #1 << 11 @ yes. b do_DataAbort not_thumb: .endm diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c index 44c086710d2b..9ecfdb511951 100644 --- a/arch/arm/mm/cache-l2x0.c +++ b/arch/arm/mm/cache-l2x0.c @@ -277,6 +277,25 @@ static void l2x0_disable(void) spin_unlock_irqrestore(&l2x0_lock, flags); } +static void __init l2x0_unlock(__u32 cache_id) +{ + int lockregs; + int i; + + if (cache_id == L2X0_CACHE_ID_PART_L310) + lockregs = 8; + else + /* L210 and unknown types */ + lockregs = 1; + + for (i = 0; i < lockregs; i++) { + writel_relaxed(0x0, l2x0_base + L2X0_LOCKDOWN_WAY_D_BASE + + i * L2X0_LOCKDOWN_STRIDE); + writel_relaxed(0x0, l2x0_base + L2X0_LOCKDOWN_WAY_I_BASE + + i * L2X0_LOCKDOWN_STRIDE); + } +} + void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask) { __u32 aux; @@ -328,6 +347,8 @@ void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask) * accessing the below registers will fault. */ if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & 1)) { + /* Make sure that I&D is not locked down when starting */ + l2x0_unlock(cache_id); /* l2x0 controller is disabled */ writel_relaxed(aux, l2x0_base + L2X0_AUX_CTRL); diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 91bca355cd31..cc7e2d8be9aa 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -298,7 +298,7 @@ static void __init arm_bootmem_free(unsigned long min, unsigned long max_low, #ifdef CONFIG_HAVE_ARCH_PFN_VALID int pfn_valid(unsigned long pfn) { - return memblock_is_memory(pfn << PAGE_SHIFT); + return memblock_is_memory(__pfn_to_phys(pfn)); } EXPORT_SYMBOL(pfn_valid); #endif diff --git a/arch/openrisc/include/asm/dma-mapping.h b/arch/openrisc/include/asm/dma-mapping.h index 052f877b52a5..60b472233900 100644 --- a/arch/openrisc/include/asm/dma-mapping.h +++ b/arch/openrisc/include/asm/dma-mapping.h @@ -31,7 +31,6 @@ #define DMA_ERROR_CODE (~(dma_addr_t)0x0) -int dma_mapping_error(struct device *dev, dma_addr_t dma_addr); #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) @@ -47,6 +46,12 @@ dma_addr_t or1k_map_page(struct device *dev, struct page *page, void or1k_unmap_page(struct device *dev, dma_addr_t dma_handle, size_t size, enum dma_data_direction dir, struct dma_attrs *attrs); +int or1k_map_sg(struct device *dev, struct scatterlist *sg, + int nents, enum dma_data_direction dir, + struct dma_attrs *attrs); +void or1k_unmap_sg(struct device *dev, struct scatterlist *sg, + int nents, enum dma_data_direction dir, + struct dma_attrs *attrs); void or1k_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size, enum dma_data_direction dir); @@ -98,6 +103,51 @@ static inline void dma_unmap_single(struct device *dev, dma_addr_t addr, debug_dma_unmap_page(dev, addr, size, dir, true); } +static inline int dma_map_sg(struct device *dev, struct scatterlist *sg, + int nents, enum dma_data_direction dir) +{ + int i, ents; + struct scatterlist *s; + + for_each_sg(sg, s, nents, i) + kmemcheck_mark_initialized(sg_virt(s), s->length); + BUG_ON(!valid_dma_direction(dir)); + ents = or1k_map_sg(dev, sg, nents, dir, NULL); + debug_dma_map_sg(dev, sg, nents, ents, dir); + + return ents; +} + +static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sg, + int nents, enum dma_data_direction dir) +{ + BUG_ON(!valid_dma_direction(dir)); + debug_dma_unmap_sg(dev, sg, nents, dir); + or1k_unmap_sg(dev, sg, nents, dir, NULL); +} + +static inline dma_addr_t dma_map_page(struct device *dev, struct page *page, + size_t offset, size_t size, + enum dma_data_direction dir) +{ + dma_addr_t addr; + + kmemcheck_mark_initialized(page_address(page) + offset, size); + BUG_ON(!valid_dma_direction(dir)); + addr = or1k_map_page(dev, page, offset, size, dir, NULL); + debug_dma_map_page(dev, page, offset, size, dir, addr, false); + + return addr; +} + +static inline void dma_unmap_page(struct device *dev, dma_addr_t addr, + size_t size, enum dma_data_direction dir) +{ + BUG_ON(!valid_dma_direction(dir)); + or1k_unmap_page(dev, addr, size, dir, NULL); + debug_dma_unmap_page(dev, addr, size, dir, true); +} + static inline void dma_sync_single_for_cpu(struct device *dev, dma_addr_t addr, size_t size, enum dma_data_direction dir) @@ -119,7 +169,12 @@ static inline void dma_sync_single_for_device(struct device *dev, static inline int dma_supported(struct device *dev, u64 dma_mask) { /* Support 32 bit DMA mask exclusively */ - return dma_mask == 0xffffffffULL; + return dma_mask == DMA_BIT_MASK(32); +} + +static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) +{ + return 0; } static inline int dma_set_mask(struct device *dev, u64 dma_mask) diff --git a/arch/openrisc/include/asm/sigcontext.h b/arch/openrisc/include/asm/sigcontext.h index 54a5c50132e3..b79c2b19afbe 100644 --- a/arch/openrisc/include/asm/sigcontext.h +++ b/arch/openrisc/include/asm/sigcontext.h @@ -23,16 +23,11 @@ /* This struct is saved by setup_frame in signal.c, to keep the current context while a signal handler is executed. It's restored by sys_sigreturn. - - To keep things simple, we use pt_regs here even though normally you just - specify the list of regs to save. Then we can use copy_from_user on the - entire regs instead of a bunch of get_user's as well... */ struct sigcontext { - struct pt_regs regs; /* needs to be first */ + struct user_regs_struct regs; /* needs to be first */ unsigned long oldmask; - unsigned long usp; /* usp before stacking this gunk on it */ }; #endif /* __ASM_OPENRISC_SIGCONTEXT_H */ diff --git a/arch/openrisc/kernel/dma.c b/arch/openrisc/kernel/dma.c index 968d3ee477e3..f1c8ee2895d0 100644 --- a/arch/openrisc/kernel/dma.c +++ b/arch/openrisc/kernel/dma.c @@ -154,6 +154,33 @@ void or1k_unmap_page(struct device *dev, dma_addr_t dma_handle, /* Nothing special to do here... */ } +int or1k_map_sg(struct device *dev, struct scatterlist *sg, + int nents, enum dma_data_direction dir, + struct dma_attrs *attrs) +{ + struct scatterlist *s; + int i; + + for_each_sg(sg, s, nents, i) { + s->dma_address = or1k_map_page(dev, sg_page(s), s->offset, + s->length, dir, NULL); + } + + return nents; +} + +void or1k_unmap_sg(struct device *dev, struct scatterlist *sg, + int nents, enum dma_data_direction dir, + struct dma_attrs *attrs) +{ + struct scatterlist *s; + int i; + + for_each_sg(sg, s, nents, i) { + or1k_unmap_page(dev, sg_dma_address(s), sg_dma_len(s), dir, NULL); + } +} + void or1k_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size, enum dma_data_direction dir) @@ -187,5 +214,4 @@ static int __init dma_init(void) return 0; } - fs_initcall(dma_init); diff --git a/arch/openrisc/kernel/signal.c b/arch/openrisc/kernel/signal.c index 5f759c76834e..95207ab0c99e 100644 --- a/arch/openrisc/kernel/signal.c +++ b/arch/openrisc/kernel/signal.c @@ -52,31 +52,25 @@ struct rt_sigframe { static int restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc) { unsigned int err = 0; - unsigned long old_usp; /* Alwys make any pending restarted system call return -EINTR */ current_thread_info()->restart_block.fn = do_no_restart_syscall; - /* restore the regs from &sc->regs (same as sc, since regs is first) + /* + * Restore the regs from &sc->regs. * (sc is already checked for VERIFY_READ since the sigframe was * checked in sys_sigreturn previously) */ - - if (__copy_from_user(regs, sc, sizeof(struct pt_regs))) + if (__copy_from_user(regs, sc->regs.gpr, 32 * sizeof(unsigned long))) + goto badframe; + if (__copy_from_user(®s->pc, &sc->regs.pc, sizeof(unsigned long))) + goto badframe; + if (__copy_from_user(®s->sr, &sc->regs.sr, sizeof(unsigned long))) goto badframe; /* make sure the SM-bit is cleared so user-mode cannot fool us */ regs->sr &= ~SPR_SR_SM; - /* restore the old USP as it was before we stacked the sc etc. - * (we cannot just pop the sigcontext since we aligned the sp and - * stuff after pushing it) - */ - - err |= __get_user(old_usp, &sc->usp); - - regs->sp = old_usp; - /* TODO: the other ports use regs->orig_XX to disable syscall checks * after this completes, but we don't use that mechanism. maybe we can * use it now ? @@ -137,18 +131,17 @@ static int setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs, unsigned long mask) { int err = 0; - unsigned long usp = regs->sp; - /* copy the regs. they are first in sc so we can use sc directly */ + /* copy the regs */ - err |= __copy_to_user(sc, regs, sizeof(struct pt_regs)); + err |= __copy_to_user(sc->regs.gpr, regs, 32 * sizeof(unsigned long)); + err |= __copy_to_user(&sc->regs.pc, ®s->pc, sizeof(unsigned long)); + err |= __copy_to_user(&sc->regs.sr, ®s->sr, sizeof(unsigned long)); /* then some other stuff */ err |= __put_user(mask, &sc->oldmask); - err |= __put_user(usp, &sc->usp); - return err; } diff --git a/arch/x86/include/asm/pvclock.h b/arch/x86/include/asm/pvclock.h index a518c0a45044..c59cc97fe6c1 100644 --- a/arch/x86/include/asm/pvclock.h +++ b/arch/x86/include/asm/pvclock.h @@ -44,7 +44,7 @@ static inline u64 pvclock_scale_delta(u64 delta, u32 mul_frac, int shift) : "a" ((u32)delta), "1" ((u32)(delta >> 32)), "2" (mul_frac) ); #elif defined(__x86_64__) __asm__ ( - "mul %[mul_frac] ; shrd $32, %[hi], %[lo]" + "mulq %[mul_frac] ; shrd $32, %[hi], %[lo]" : [lo]"=a"(product), [hi]"=d"(tmp) : "0"(delta), diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 4ee3abf20ed6..cfa62ec090ec 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -1900,6 +1900,9 @@ perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs) perf_callchain_store(entry, regs->ip); + if (!current->mm) + return; + if (perf_callchain_user32(regs, entry)) return; diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c index c95330267f08..039d91315bc5 100644 --- a/arch/x86/pci/acpi.c +++ b/arch/x86/pci/acpi.c @@ -365,8 +365,13 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root) */ if (bus) { struct pci_bus *child; - list_for_each_entry(child, &bus->children, node) - pcie_bus_configure_settings(child, child->self->pcie_mpss); + list_for_each_entry(child, &bus->children, node) { + struct pci_dev *self = child->self; + if (!self) + continue; + + pcie_bus_configure_settings(child, self->pcie_mpss); + } } if (!bus) diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c index df118a825f39..c3b8d440873c 100644 --- a/arch/x86/xen/setup.c +++ b/arch/x86/xen/setup.c @@ -184,6 +184,19 @@ static unsigned long __init xen_set_identity(const struct e820entry *list, PFN_UP(start_pci), PFN_DOWN(last)); return identity; } + +static unsigned long __init xen_get_max_pages(void) +{ + unsigned long max_pages = MAX_DOMAIN_PAGES; + domid_t domid = DOMID_SELF; + int ret; + + ret = HYPERVISOR_memory_op(XENMEM_maximum_reservation, &domid); + if (ret > 0) + max_pages = ret; + return min(max_pages, MAX_DOMAIN_PAGES); +} + /** * machine_specific_memory_setup - Hook for machine specific memory setup. **/ @@ -292,6 +305,12 @@ char * __init xen_memory_setup(void) sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map); + extra_limit = xen_get_max_pages(); + if (extra_limit >= max_pfn) + extra_pages = extra_limit - max_pfn; + else + extra_pages = 0; + extra_pages += xen_return_unused_memory(xen_start_info->nr_pages, &e820); /* diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c index e79dbb95482b..d4fc6d454f8d 100644 --- a/arch/x86/xen/smp.c +++ b/arch/x86/xen/smp.c @@ -32,6 +32,7 @@ #include <xen/page.h> #include <xen/events.h> +#include <xen/hvc-console.h> #include "xen-ops.h" #include "mmu.h" @@ -207,6 +208,15 @@ static void __init xen_smp_prepare_cpus(unsigned int max_cpus) unsigned cpu; unsigned int i; + if (skip_ioapic_setup) { + char *m = (max_cpus == 0) ? + "The nosmp parameter is incompatible with Xen; " \ + "use Xen dom0_max_vcpus=1 parameter" : + "The noapic parameter is incompatible with Xen"; + + xen_raw_printk(m); + panic(m); + } xen_init_lock_cpu(0); smp_store_cpu_info(0); diff --git a/arch/x86/xen/xen-asm_32.S b/arch/x86/xen/xen-asm_32.S index 22a2093b5862..b040b0e518ca 100644 --- a/arch/x86/xen/xen-asm_32.S +++ b/arch/x86/xen/xen-asm_32.S @@ -113,11 +113,13 @@ xen_iret_start_crit: /* * If there's something pending, mask events again so we can - * jump back into xen_hypervisor_callback + * jump back into xen_hypervisor_callback. Otherwise do not + * touch XEN_vcpu_info_mask. */ - sete XEN_vcpu_info_mask(%eax) + jne 1f + movb $1, XEN_vcpu_info_mask(%eax) - popl %eax +1: popl %eax /* * From this point on the registers are restored and the stack |