diff options
Diffstat (limited to 'arch/sparc/kernel')
82 files changed, 925 insertions, 952 deletions
diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile index d432fb20358..7cf9c6ea3f1 100644 --- a/arch/sparc/kernel/Makefile +++ b/arch/sparc/kernel/Makefile @@ -1,3 +1,4 @@ + # # Makefile for the linux kernel. # @@ -41,7 +42,6 @@ obj-y += time_$(BITS).o obj-$(CONFIG_SPARC32) += windows.o obj-y += cpu.o obj-$(CONFIG_SPARC32) += devices.o -obj-$(CONFIG_SPARC32) += tadpole.o obj-y += ptrace_$(BITS).o obj-y += unaligned_$(BITS).o obj-y += una_asm_$(BITS).o @@ -99,7 +99,7 @@ obj-$(CONFIG_STACKTRACE) += stacktrace.o obj-$(CONFIG_SPARC64_PCI) += pci.o pci_common.o psycho_common.o obj-$(CONFIG_SPARC64_PCI) += pci_psycho.o pci_sabre.o pci_schizo.o obj-$(CONFIG_SPARC64_PCI) += pci_sun4v.o pci_sun4v_asm.o pci_fire.o -obj-$(CONFIG_PCI_MSI) += pci_msi.o +obj-$(CONFIG_SPARC64_PCI_MSI) += pci_msi.o obj-$(CONFIG_COMPAT) += sys32.o sys_sparc32.o signal32.o diff --git a/arch/sparc/kernel/audit.c b/arch/sparc/kernel/audit.c index 8fff0ac63d5..24361b494a9 100644 --- a/arch/sparc/kernel/audit.c +++ b/arch/sparc/kernel/audit.c @@ -3,6 +3,8 @@ #include <linux/audit.h> #include <asm/unistd.h> +#include "kernel.h" + static unsigned dir_class[] = { #include <asm-generic/audit_dir_write.h> ~0U @@ -40,7 +42,6 @@ int audit_classify_arch(int arch) int audit_classify_syscall(int abi, unsigned syscall) { #ifdef CONFIG_COMPAT - extern int sparc32_classify_syscall(unsigned); if (abi == AUDIT_ARCH_SPARC) return sparc32_classify_syscall(syscall); #endif @@ -61,11 +62,6 @@ int audit_classify_syscall(int abi, unsigned syscall) static int __init audit_classes_init(void) { #ifdef CONFIG_COMPAT - extern __u32 sparc32_dir_class[]; - extern __u32 sparc32_write_class[]; - extern __u32 sparc32_read_class[]; - extern __u32 sparc32_chattr_class[]; - extern __u32 sparc32_signal_class[]; audit_register_class(AUDIT_CLASS_WRITE_32, sparc32_write_class); audit_register_class(AUDIT_CLASS_READ_32, sparc32_read_class); audit_register_class(AUDIT_CLASS_DIR_WRITE_32, sparc32_dir_class); diff --git a/arch/sparc/kernel/auxio_32.c b/arch/sparc/kernel/auxio_32.c index e20cc55fb76..ae88c223e4d 100644 --- a/arch/sparc/kernel/auxio_32.c +++ b/arch/sparc/kernel/auxio_32.c @@ -9,12 +9,15 @@ #include <linux/of.h> #include <linux/of_device.h> #include <linux/export.h> + #include <asm/oplib.h> #include <asm/io.h> #include <asm/auxio.h> #include <asm/string.h> /* memset(), Linux has no bzero() */ #include <asm/cpu_type.h> +#include "kernel.h" + /* Probe and map in the Auxiliary I/O register */ /* auxio_register is not static because it is referenced @@ -103,7 +106,7 @@ EXPORT_SYMBOL(set_auxio); /* sun4m power control register (AUXIO2) */ -volatile unsigned char * auxio_power_register = NULL; +volatile u8 __iomem *auxio_power_register = NULL; void __init auxio_power_probe(void) { @@ -127,8 +130,8 @@ void __init auxio_power_probe(void) r.flags = regs.which_io & 0xF; r.start = regs.phys_addr; r.end = regs.phys_addr + regs.reg_size - 1; - auxio_power_register = (unsigned char *) of_ioremap(&r, 0, - regs.reg_size, "auxpower"); + auxio_power_register = + (u8 __iomem *)of_ioremap(&r, 0, regs.reg_size, "auxpower"); /* Display a quick message on the console. */ if (auxio_power_register) diff --git a/arch/sparc/kernel/btext.c b/arch/sparc/kernel/btext.c index 57073e56ba9..987f7ec497c 100644 --- a/arch/sparc/kernel/btext.c +++ b/arch/sparc/kernel/btext.c @@ -137,7 +137,7 @@ static void scrollscreen(void) } #endif /* ndef NO_SCROLL */ -void btext_drawchar(char c) +static void btext_drawchar(char c) { int cline = 0; #ifdef NO_SCROLL diff --git a/arch/sparc/kernel/compat_audit.c b/arch/sparc/kernel/compat_audit.c index d865575b25b..7062263d09c 100644 --- a/arch/sparc/kernel/compat_audit.c +++ b/arch/sparc/kernel/compat_audit.c @@ -1,5 +1,6 @@ #define __32bit_syscall_numbers__ #include <asm/unistd.h> +#include "kernel.h" unsigned sparc32_dir_class[] = { #include <asm-generic/audit_dir_write.h> diff --git a/arch/sparc/kernel/cpu.c b/arch/sparc/kernel/cpu.c index 5c5125895db..82a3a71c451 100644 --- a/arch/sparc/kernel/cpu.c +++ b/arch/sparc/kernel/cpu.c @@ -22,6 +22,7 @@ #include <asm/cpudata.h> #include "kernel.h" +#include "entry.h" DEFINE_PER_CPU(cpuinfo_sparc, __cpu_data) = { 0 }; EXPORT_PER_CPU_SYMBOL(__cpu_data); diff --git a/arch/sparc/kernel/cpumap.c b/arch/sparc/kernel/cpumap.c index cb5d272d658..de1c844dfab 100644 --- a/arch/sparc/kernel/cpumap.c +++ b/arch/sparc/kernel/cpumap.c @@ -6,7 +6,6 @@ #include <linux/export.h> #include <linux/slab.h> #include <linux/kernel.h> -#include <linux/init.h> #include <linux/cpumask.h> #include <linux/spinlock.h> #include <asm/cpudata.h> diff --git a/arch/sparc/kernel/cpumap.h b/arch/sparc/kernel/cpumap.h index e639880ab86..9dac398c434 100644 --- a/arch/sparc/kernel/cpumap.h +++ b/arch/sparc/kernel/cpumap.h @@ -2,8 +2,8 @@ #define _CPUMAP_H #ifdef CONFIG_SMP -extern void cpu_map_rebuild(void); -extern int map_to_cpu(unsigned int index); +void cpu_map_rebuild(void); +int map_to_cpu(unsigned int index); #define cpu_map_init() cpu_map_rebuild() #else #define cpu_map_init() do {} while (0) diff --git a/arch/sparc/kernel/devices.c b/arch/sparc/kernel/devices.c index 3d465e87f7e..8d5d09f09ca 100644 --- a/arch/sparc/kernel/devices.c +++ b/arch/sparc/kernel/devices.c @@ -19,8 +19,9 @@ #include <asm/smp.h> #include <asm/cpudata.h> #include <asm/cpu_type.h> +#include <asm/setup.h> -extern void clock_stop_probe(void); /* tadpole.c */ +#include "kernel.h" static char *cpu_mid_prop(void) { @@ -131,11 +132,6 @@ void __init device_scan(void) } #endif /* !CONFIG_SMP */ - { - extern void auxio_probe(void); - extern void auxio_power_probe(void); - auxio_probe(); - auxio_power_probe(); - } - clock_stop_probe(); + auxio_probe(); + auxio_power_probe(); } diff --git a/arch/sparc/kernel/ds.c b/arch/sparc/kernel/ds.c index 62d6b153ffa..dff60abbea0 100644 --- a/arch/sparc/kernel/ds.c +++ b/arch/sparc/kernel/ds.c @@ -849,9 +849,8 @@ void ldom_reboot(const char *boot_command) if (boot_command && strlen(boot_command)) { unsigned long len; - strcpy(full_boot_str, "boot "); - strlcpy(full_boot_str + strlen("boot "), boot_command, - sizeof(full_boot_str + strlen("boot "))); + snprintf(full_boot_str, sizeof(full_boot_str), "boot %s", + boot_command); len = strlen(full_boot_str); if (reboot_data_supported) { diff --git a/arch/sparc/kernel/ebus.c b/arch/sparc/kernel/ebus.c index e306fb08ee5..acf8314cec4 100644 --- a/arch/sparc/kernel/ebus.c +++ b/arch/sparc/kernel/ebus.c @@ -7,7 +7,6 @@ #include <linux/export.h> #include <linux/kernel.h> #include <linux/types.h> -#include <linux/init.h> #include <linux/interrupt.h> #include <linux/delay.h> diff --git a/arch/sparc/kernel/entry.h b/arch/sparc/kernel/entry.h index 9c179fbfb21..ebaba6167dd 100644 --- a/arch/sparc/kernel/entry.h +++ b/arch/sparc/kernel/entry.h @@ -6,40 +6,39 @@ #include <linux/init.h> /* irq */ -extern void handler_irq(int irq, struct pt_regs *regs); +void handler_irq(int irq, struct pt_regs *regs); #ifdef CONFIG_SPARC32 /* traps */ -extern void do_hw_interrupt(struct pt_regs *regs, unsigned long type); -extern void do_illegal_instruction(struct pt_regs *regs, unsigned long pc, - unsigned long npc, unsigned long psr); - -extern void do_priv_instruction(struct pt_regs *regs, unsigned long pc, - unsigned long npc, unsigned long psr); -extern void do_memaccess_unaligned(struct pt_regs *regs, unsigned long pc, - unsigned long npc, - unsigned long psr); -extern void do_fpd_trap(struct pt_regs *regs, unsigned long pc, +void do_hw_interrupt(struct pt_regs *regs, unsigned long type); +void do_illegal_instruction(struct pt_regs *regs, unsigned long pc, + unsigned long npc, unsigned long psr); + +void do_priv_instruction(struct pt_regs *regs, unsigned long pc, + unsigned long npc, unsigned long psr); +void do_memaccess_unaligned(struct pt_regs *regs, unsigned long pc, + unsigned long npc, unsigned long psr); +void do_fpd_trap(struct pt_regs *regs, unsigned long pc, + unsigned long npc, unsigned long psr); +void do_fpe_trap(struct pt_regs *regs, unsigned long pc, + unsigned long npc, unsigned long psr); +void handle_tag_overflow(struct pt_regs *regs, unsigned long pc, + unsigned long npc, unsigned long psr); +void handle_watchpoint(struct pt_regs *regs, unsigned long pc, + unsigned long npc, unsigned long psr); +void handle_reg_access(struct pt_regs *regs, unsigned long pc, + unsigned long npc, unsigned long psr); +void handle_cp_disabled(struct pt_regs *regs, unsigned long pc, unsigned long npc, unsigned long psr); -extern void do_fpe_trap(struct pt_regs *regs, unsigned long pc, - unsigned long npc, unsigned long psr); -extern void handle_tag_overflow(struct pt_regs *regs, unsigned long pc, - unsigned long npc, unsigned long psr); -extern void handle_watchpoint(struct pt_regs *regs, unsigned long pc, - unsigned long npc, unsigned long psr); -extern void handle_reg_access(struct pt_regs *regs, unsigned long pc, - unsigned long npc, unsigned long psr); -extern void handle_cp_disabled(struct pt_regs *regs, unsigned long pc, - unsigned long npc, unsigned long psr); -extern void handle_cp_exception(struct pt_regs *regs, unsigned long pc, - unsigned long npc, unsigned long psr); +void handle_cp_exception(struct pt_regs *regs, unsigned long pc, + unsigned long npc, unsigned long psr); /* entry.S */ -extern void fpsave(unsigned long *fpregs, unsigned long *fsr, - void *fpqueue, unsigned long *fpqdepth); -extern void fpload(unsigned long *fpregs, unsigned long *fsr); +void fpsave(unsigned long *fpregs, unsigned long *fsr, + void *fpqueue, unsigned long *fpqdepth); +void fpload(unsigned long *fpregs, unsigned long *fsr); #else /* CONFIG_SPARC32 */ @@ -66,124 +65,123 @@ struct pause_patch_entry { extern struct pause_patch_entry __pause_3insn_patch, __pause_3insn_patch_end; -extern void __init per_cpu_patch(void); -extern void sun4v_patch_1insn_range(struct sun4v_1insn_patch_entry *, - struct sun4v_1insn_patch_entry *); -extern void sun4v_patch_2insn_range(struct sun4v_2insn_patch_entry *, - struct sun4v_2insn_patch_entry *); -extern void __init sun4v_patch(void); -extern void __init boot_cpu_id_too_large(int cpu); +void __init per_cpu_patch(void); +void sun4v_patch_1insn_range(struct sun4v_1insn_patch_entry *, + struct sun4v_1insn_patch_entry *); +void sun4v_patch_2insn_range(struct sun4v_2insn_patch_entry *, + struct sun4v_2insn_patch_entry *); +void __init sun4v_patch(void); +void __init boot_cpu_id_too_large(int cpu); extern unsigned int dcache_parity_tl1_occurred; extern unsigned int icache_parity_tl1_occurred; -extern asmlinkage void sparc_breakpoint(struct pt_regs *regs); -extern void timer_interrupt(int irq, struct pt_regs *regs); - -extern void do_notify_resume(struct pt_regs *regs, - unsigned long orig_i0, - unsigned long thread_info_flags); - -extern asmlinkage int syscall_trace_enter(struct pt_regs *regs); -extern asmlinkage void syscall_trace_leave(struct pt_regs *regs); - -extern void bad_trap_tl1(struct pt_regs *regs, long lvl); - -extern void do_fpe_common(struct pt_regs *regs); -extern void do_fpieee(struct pt_regs *regs); -extern void do_fpother(struct pt_regs *regs); -extern void do_tof(struct pt_regs *regs); -extern void do_div0(struct pt_regs *regs); -extern void do_illegal_instruction(struct pt_regs *regs); -extern void mem_address_unaligned(struct pt_regs *regs, - unsigned long sfar, - unsigned long sfsr); -extern void sun4v_do_mna(struct pt_regs *regs, - unsigned long addr, - unsigned long type_ctx); -extern void do_privop(struct pt_regs *regs); -extern void do_privact(struct pt_regs *regs); -extern void do_cee(struct pt_regs *regs); -extern void do_cee_tl1(struct pt_regs *regs); -extern void do_dae_tl1(struct pt_regs *regs); -extern void do_iae_tl1(struct pt_regs *regs); -extern void do_div0_tl1(struct pt_regs *regs); -extern void do_fpdis_tl1(struct pt_regs *regs); -extern void do_fpieee_tl1(struct pt_regs *regs); -extern void do_fpother_tl1(struct pt_regs *regs); -extern void do_ill_tl1(struct pt_regs *regs); -extern void do_irq_tl1(struct pt_regs *regs); -extern void do_lddfmna_tl1(struct pt_regs *regs); -extern void do_stdfmna_tl1(struct pt_regs *regs); -extern void do_paw(struct pt_regs *regs); -extern void do_paw_tl1(struct pt_regs *regs); -extern void do_vaw(struct pt_regs *regs); -extern void do_vaw_tl1(struct pt_regs *regs); -extern void do_tof_tl1(struct pt_regs *regs); -extern void do_getpsr(struct pt_regs *regs); - -extern void spitfire_insn_access_exception(struct pt_regs *regs, - unsigned long sfsr, - unsigned long sfar); -extern void spitfire_insn_access_exception_tl1(struct pt_regs *regs, - unsigned long sfsr, - unsigned long sfar); -extern void spitfire_data_access_exception(struct pt_regs *regs, - unsigned long sfsr, - unsigned long sfar); -extern void spitfire_data_access_exception_tl1(struct pt_regs *regs, - unsigned long sfsr, - unsigned long sfar); -extern void spitfire_access_error(struct pt_regs *regs, - unsigned long status_encoded, - unsigned long afar); - -extern void cheetah_fecc_handler(struct pt_regs *regs, - unsigned long afsr, - unsigned long afar); -extern void cheetah_cee_handler(struct pt_regs *regs, - unsigned long afsr, - unsigned long afar); -extern void cheetah_deferred_handler(struct pt_regs *regs, - unsigned long afsr, - unsigned long afar); -extern void cheetah_plus_parity_error(int type, struct pt_regs *regs); - -extern void sun4v_insn_access_exception(struct pt_regs *regs, - unsigned long addr, - unsigned long type_ctx); -extern void sun4v_insn_access_exception_tl1(struct pt_regs *regs, - unsigned long addr, - unsigned long type_ctx); -extern void sun4v_data_access_exception(struct pt_regs *regs, - unsigned long addr, - unsigned long type_ctx); -extern void sun4v_data_access_exception_tl1(struct pt_regs *regs, - unsigned long addr, - unsigned long type_ctx); -extern void sun4v_resum_error(struct pt_regs *regs, - unsigned long offset); -extern void sun4v_resum_overflow(struct pt_regs *regs); -extern void sun4v_nonresum_error(struct pt_regs *regs, - unsigned long offset); -extern void sun4v_nonresum_overflow(struct pt_regs *regs); +asmlinkage void sparc_breakpoint(struct pt_regs *regs); +void timer_interrupt(int irq, struct pt_regs *regs); + +void do_notify_resume(struct pt_regs *regs, + unsigned long orig_i0, + unsigned long thread_info_flags); + +asmlinkage int syscall_trace_enter(struct pt_regs *regs); +asmlinkage void syscall_trace_leave(struct pt_regs *regs); + +void bad_trap_tl1(struct pt_regs *regs, long lvl); + +void do_fpieee(struct pt_regs *regs); +void do_fpother(struct pt_regs *regs); +void do_tof(struct pt_regs *regs); +void do_div0(struct pt_regs *regs); +void do_illegal_instruction(struct pt_regs *regs); +void mem_address_unaligned(struct pt_regs *regs, + unsigned long sfar, + unsigned long sfsr); +void sun4v_do_mna(struct pt_regs *regs, + unsigned long addr, + unsigned long type_ctx); +void do_privop(struct pt_regs *regs); +void do_privact(struct pt_regs *regs); +void do_cee(struct pt_regs *regs); +void do_cee_tl1(struct pt_regs *regs); +void do_dae_tl1(struct pt_regs *regs); +void do_iae_tl1(struct pt_regs *regs); +void do_div0_tl1(struct pt_regs *regs); +void do_fpdis_tl1(struct pt_regs *regs); +void do_fpieee_tl1(struct pt_regs *regs); +void do_fpother_tl1(struct pt_regs *regs); +void do_ill_tl1(struct pt_regs *regs); +void do_irq_tl1(struct pt_regs *regs); +void do_lddfmna_tl1(struct pt_regs *regs); +void do_stdfmna_tl1(struct pt_regs *regs); +void do_paw(struct pt_regs *regs); +void do_paw_tl1(struct pt_regs *regs); +void do_vaw(struct pt_regs *regs); +void do_vaw_tl1(struct pt_regs *regs); +void do_tof_tl1(struct pt_regs *regs); +void do_getpsr(struct pt_regs *regs); + +void spitfire_insn_access_exception(struct pt_regs *regs, + unsigned long sfsr, + unsigned long sfar); +void spitfire_insn_access_exception_tl1(struct pt_regs *regs, + unsigned long sfsr, + unsigned long sfar); +void spitfire_data_access_exception(struct pt_regs *regs, + unsigned long sfsr, + unsigned long sfar); +void spitfire_data_access_exception_tl1(struct pt_regs *regs, + unsigned long sfsr, + unsigned long sfar); +void spitfire_access_error(struct pt_regs *regs, + unsigned long status_encoded, + unsigned long afar); + +void cheetah_fecc_handler(struct pt_regs *regs, + unsigned long afsr, + unsigned long afar); +void cheetah_cee_handler(struct pt_regs *regs, + unsigned long afsr, + unsigned long afar); +void cheetah_deferred_handler(struct pt_regs *regs, + unsigned long afsr, + unsigned long afar); +void cheetah_plus_parity_error(int type, struct pt_regs *regs); + +void sun4v_insn_access_exception(struct pt_regs *regs, + unsigned long addr, + unsigned long type_ctx); +void sun4v_insn_access_exception_tl1(struct pt_regs *regs, + unsigned long addr, + unsigned long type_ctx); +void sun4v_data_access_exception(struct pt_regs *regs, + unsigned long addr, + unsigned long type_ctx); +void sun4v_data_access_exception_tl1(struct pt_regs *regs, + unsigned long addr, + unsigned long type_ctx); +void sun4v_resum_error(struct pt_regs *regs, + unsigned long offset); +void sun4v_resum_overflow(struct pt_regs *regs); +void sun4v_nonresum_error(struct pt_regs *regs, + unsigned long offset); +void sun4v_nonresum_overflow(struct pt_regs *regs); extern unsigned long sun4v_err_itlb_vaddr; extern unsigned long sun4v_err_itlb_ctx; extern unsigned long sun4v_err_itlb_pte; extern unsigned long sun4v_err_itlb_error; -extern void sun4v_itlb_error_report(struct pt_regs *regs, int tl); +void sun4v_itlb_error_report(struct pt_regs *regs, int tl); extern unsigned long sun4v_err_dtlb_vaddr; extern unsigned long sun4v_err_dtlb_ctx; extern unsigned long sun4v_err_dtlb_pte; extern unsigned long sun4v_err_dtlb_error; -extern void sun4v_dtlb_error_report(struct pt_regs *regs, int tl); -extern void hypervisor_tlbop_error(unsigned long err, - unsigned long op); -extern void hypervisor_tlbop_error_xcall(unsigned long err, - unsigned long op); +void sun4v_dtlb_error_report(struct pt_regs *regs, int tl); +void hypervisor_tlbop_error(unsigned long err, + unsigned long op); +void hypervisor_tlbop_error_xcall(unsigned long err, + unsigned long op); /* WARNING: The error trap handlers in assembly know the precise * layout of the following structure. @@ -249,8 +247,8 @@ struct ino_bucket { extern struct ino_bucket *ivector_table; extern unsigned long ivector_table_pa; -extern void init_irqwork_curcpu(void); -extern void sun4v_register_mondo_queues(int this_cpu); +void init_irqwork_curcpu(void); +void sun4v_register_mondo_queues(int this_cpu); #endif /* CONFIG_SPARC32 */ #endif /* _ENTRY_H */ diff --git a/arch/sparc/kernel/ftrace.c b/arch/sparc/kernel/ftrace.c index 03ab022e51c..0a2d2ddff54 100644 --- a/arch/sparc/kernel/ftrace.c +++ b/arch/sparc/kernel/ftrace.c @@ -82,12 +82,8 @@ int ftrace_update_ftrace_func(ftrace_func_t func) return ftrace_modify_code(ip, old, new); } -int __init ftrace_dyn_arch_init(void *data) +int __init ftrace_dyn_arch_init(void) { - unsigned long *p = data; - - *p = 0; - return 0; } #endif diff --git a/arch/sparc/kernel/head_64.S b/arch/sparc/kernel/head_64.S index 26b706a1867..452f04fe8da 100644 --- a/arch/sparc/kernel/head_64.S +++ b/arch/sparc/kernel/head_64.S @@ -282,8 +282,8 @@ sun4v_chip_type: stx %l2, [%l4 + 0x0] ldx [%sp + 2047 + 128 + 0x50], %l3 ! physaddr low /* 4MB align */ - srlx %l3, 22, %l3 - sllx %l3, 22, %l3 + srlx %l3, ILOG2_4MB, %l3 + sllx %l3, ILOG2_4MB, %l3 stx %l3, [%l4 + 0x8] /* Leave service as-is, "call-method" */ diff --git a/arch/sparc/kernel/hvtramp.S b/arch/sparc/kernel/hvtramp.S index 4eb1a5a1d54..b7ddcdd1dea 100644 --- a/arch/sparc/kernel/hvtramp.S +++ b/arch/sparc/kernel/hvtramp.S @@ -3,7 +3,6 @@ * Copyright (C) 2007, 2008 David S. Miller <davem@davemloft.net> */ -#include <linux/init.h> #include <asm/thread_info.h> #include <asm/hypervisor.h> diff --git a/arch/sparc/kernel/iommu.c b/arch/sparc/kernel/iommu.c index 070ed141aac..bfa4d0c2df4 100644 --- a/arch/sparc/kernel/iommu.c +++ b/arch/sparc/kernel/iommu.c @@ -21,6 +21,7 @@ #include <asm/iommu.h> #include "iommu_common.h" +#include "kernel.h" #define STC_CTXMATCH_ADDR(STC, CTX) \ ((STC)->strbuf_ctxmatch_base + ((CTX) << 3)) @@ -840,8 +841,6 @@ static struct dma_map_ops sun4u_dma_ops = { struct dma_map_ops *dma_ops = &sun4u_dma_ops; EXPORT_SYMBOL(dma_ops); -extern int pci64_dma_supported(struct pci_dev *pdev, u64 device_mask); - int dma_supported(struct device *dev, u64 device_mask) { struct iommu *iommu = dev->archdata.iommu; @@ -854,7 +853,7 @@ int dma_supported(struct device *dev, u64 device_mask) return 1; #ifdef CONFIG_PCI - if (dev->bus == &pci_bus_type) + if (dev_is_pci(dev)) return pci64_dma_supported(to_pci_dev(dev), device_mask); #endif diff --git a/arch/sparc/kernel/iommu_common.h b/arch/sparc/kernel/iommu_common.h index 591f5879039..1ec0de4156e 100644 --- a/arch/sparc/kernel/iommu_common.h +++ b/arch/sparc/kernel/iommu_common.h @@ -48,12 +48,12 @@ static inline int is_span_boundary(unsigned long entry, return iommu_is_span_boundary(entry, nr, shift, boundary_size); } -extern unsigned long iommu_range_alloc(struct device *dev, - struct iommu *iommu, - unsigned long npages, - unsigned long *handle); -extern void iommu_range_free(struct iommu *iommu, - dma_addr_t dma_addr, - unsigned long npages); +unsigned long iommu_range_alloc(struct device *dev, + struct iommu *iommu, + unsigned long npages, + unsigned long *handle); +void iommu_range_free(struct iommu *iommu, + dma_addr_t dma_addr, + unsigned long npages); #endif /* _IOMMU_COMMON_H */ diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c index 2096468de9b..7f08ec8a7c6 100644 --- a/arch/sparc/kernel/ioport.c +++ b/arch/sparc/kernel/ioport.c @@ -186,7 +186,7 @@ static void __iomem *_sparc_alloc_io(unsigned int busno, unsigned long phys, if (name == NULL) name = "???"; - if ((xres = xres_alloc()) != 0) { + if ((xres = xres_alloc()) != NULL) { tack = xres->xname; res = &xres->xres; } else { @@ -400,7 +400,7 @@ static void sbus_sync_sg_for_device(struct device *dev, struct scatterlist *sg, BUG(); } -struct dma_map_ops sbus_dma_ops = { +static struct dma_map_ops sbus_dma_ops = { .alloc = sbus_alloc_coherent, .free = sbus_free_coherent, .map_page = sbus_map_page, @@ -666,10 +666,9 @@ EXPORT_SYMBOL(dma_ops); */ int dma_supported(struct device *dev, u64 mask) { -#ifdef CONFIG_PCI - if (dev->bus == &pci_bus_type) + if (dev_is_pci(dev)) return 1; -#endif + return 0; } EXPORT_SYMBOL(dma_supported); @@ -682,7 +681,7 @@ static int sparc_io_proc_show(struct seq_file *m, void *v) const char *nm; for (r = root->child; r != NULL; r = r->sibling) { - if ((nm = r->name) == 0) nm = "???"; + if ((nm = r->name) == NULL) nm = "???"; seq_printf(m, "%016llx-%016llx: %s\n", (unsigned long long)r->start, (unsigned long long)r->end, nm); diff --git a/arch/sparc/kernel/irq.h b/arch/sparc/kernel/irq.h index b66b6aad1d6..70a0b8ddd0b 100644 --- a/arch/sparc/kernel/irq.h +++ b/arch/sparc/kernel/irq.h @@ -82,11 +82,20 @@ void handler_irq(unsigned int pil, struct pt_regs *regs); unsigned long leon_get_irqmask(unsigned int irq); +/* irq_32.c */ +void sparc_floppy_irq(int irq, void *dev_id, struct pt_regs *regs); + +/* sun4m_irq.c */ +void sun4m_nmi(struct pt_regs *regs); + +/* sun4d_irq.c */ +void sun4d_handler_irq(unsigned int pil, struct pt_regs *regs); + #ifdef CONFIG_SMP /* All SUN4D IPIs are sent on this IRQ, may be shared with hard IRQs */ #define SUN4D_IPI_IRQ 13 -extern void sun4d_ipi_interrupt(void); +void sun4d_ipi_interrupt(void); #endif diff --git a/arch/sparc/kernel/irq_32.c b/arch/sparc/kernel/irq_32.c index c145f6fd123..a979e99f875 100644 --- a/arch/sparc/kernel/irq_32.c +++ b/arch/sparc/kernel/irq_32.c @@ -17,6 +17,7 @@ #include <asm/cacheflush.h> #include <asm/cpudata.h> +#include <asm/setup.h> #include <asm/pcic.h> #include <asm/leon.h> diff --git a/arch/sparc/kernel/irq_64.c b/arch/sparc/kernel/irq_64.c index d4840cec2c5..666193f4e8b 100644 --- a/arch/sparc/kernel/irq_64.c +++ b/arch/sparc/kernel/irq_64.c @@ -698,30 +698,19 @@ void __irq_entry handler_irq(int pil, struct pt_regs *regs) set_irq_regs(old_regs); } -void do_softirq(void) +void do_softirq_own_stack(void) { - unsigned long flags; - - if (in_interrupt()) - return; - - local_irq_save(flags); + void *orig_sp, *sp = softirq_stack[smp_processor_id()]; - if (local_softirq_pending()) { - void *orig_sp, *sp = softirq_stack[smp_processor_id()]; - - sp += THREAD_SIZE - 192 - STACK_BIAS; - - __asm__ __volatile__("mov %%sp, %0\n\t" - "mov %1, %%sp" - : "=&r" (orig_sp) - : "r" (sp)); - __do_softirq(); - __asm__ __volatile__("mov %0, %%sp" - : : "r" (orig_sp)); - } + sp += THREAD_SIZE - 192 - STACK_BIAS; - local_irq_restore(flags); + __asm__ __volatile__("mov %%sp, %0\n\t" + "mov %1, %%sp" + : "=&r" (orig_sp) + : "r" (sp)); + __do_softirq(); + __asm__ __volatile__("mov %0, %%sp" + : : "r" (orig_sp)); } #ifdef CONFIG_HOTPLUG_CPU diff --git a/arch/sparc/kernel/kernel.h b/arch/sparc/kernel/kernel.h index a702d9ab019..e7f652be9e6 100644 --- a/arch/sparc/kernel/kernel.h +++ b/arch/sparc/kernel/kernel.h @@ -2,6 +2,7 @@ #define __SPARC_KERNEL_H #include <linux/interrupt.h> +#include <linux/ftrace.h> #include <asm/traps.h> #include <asm/head.h> @@ -15,62 +16,111 @@ extern int ncpus_probed; #ifdef CONFIG_SPARC64 /* setup_64.c */ struct seq_file; -extern void cpucap_info(struct seq_file *); +void cpucap_info(struct seq_file *); -static inline unsigned long kimage_addr_to_ra(const char *p) +static inline unsigned long kimage_addr_to_ra(const void *p) { unsigned long val = (unsigned long) p; return kern_base + (val - KERNBASE); } + +/* sys_sparc_64.c */ +asmlinkage long sys_kern_features(void); + +/* unaligned_64.c */ +asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn); +int handle_popc(u32 insn, struct pt_regs *regs); +void handle_lddfmna(struct pt_regs *regs, unsigned long sfar, unsigned long sfsr); +void handle_stdfmna(struct pt_regs *regs, unsigned long sfar, unsigned long sfsr); + +/* smp_64.c */ +void __irq_entry smp_call_function_client(int irq, struct pt_regs *regs); +void __irq_entry smp_call_function_single_client(int irq, struct pt_regs *regs); +void __irq_entry smp_new_mmu_context_version_client(int irq, struct pt_regs *regs); +void __irq_entry smp_penguin_jailcell(int irq, struct pt_regs *regs); +void __irq_entry smp_receive_signal_client(int irq, struct pt_regs *regs); + +/* kgdb_64.c */ +void __irq_entry smp_kgdb_capture_client(int irq, struct pt_regs *regs); + +/* pci.c */ +int pci64_dma_supported(struct pci_dev *pdev, u64 device_mask); + +/* signal32.c */ +void do_sigreturn32(struct pt_regs *regs); +asmlinkage void do_rt_sigreturn32(struct pt_regs *regs); +void do_signal32(struct pt_regs * regs); +asmlinkage int do_sys32_sigstack(u32 u_ssptr, u32 u_ossptr, unsigned long sp); + +/* compat_audit.c */ +extern unsigned sparc32_dir_class[]; +extern unsigned sparc32_chattr_class[]; +extern unsigned sparc32_write_class[]; +extern unsigned sparc32_read_class[]; +extern unsigned sparc32_signal_class[]; +int sparc32_classify_syscall(unsigned syscall); #endif #ifdef CONFIG_SPARC32 /* setup_32.c */ +struct linux_romvec; void sparc32_start_kernel(struct linux_romvec *rp); /* cpu.c */ -extern void cpu_probe(void); +void cpu_probe(void); /* traps_32.c */ -extern void handle_hw_divzero(struct pt_regs *regs, unsigned long pc, - unsigned long npc, unsigned long psr); +void handle_hw_divzero(struct pt_regs *regs, unsigned long pc, + unsigned long npc, unsigned long psr); /* irq_32.c */ extern struct irqaction static_irqaction[]; extern int static_irq_count; extern spinlock_t irq_action_lock; -extern void unexpected_irq(int irq, void *dev_id, struct pt_regs * regs); -extern void init_IRQ(void); +void unexpected_irq(int irq, void *dev_id, struct pt_regs * regs); +void init_IRQ(void); /* sun4m_irq.c */ -extern void sun4m_init_IRQ(void); -extern void sun4m_unmask_profile_irq(void); -extern void sun4m_clear_profile_irq(int cpu); +void sun4m_init_IRQ(void); +void sun4m_unmask_profile_irq(void); +void sun4m_clear_profile_irq(int cpu); /* sun4m_smp.c */ void sun4m_cpu_pre_starting(void *arg); void sun4m_cpu_pre_online(void *arg); +void __init smp4m_boot_cpus(void); +int smp4m_boot_one_cpu(int i, struct task_struct *idle); +void __init smp4m_smp_done(void); +void smp4m_cross_call_irq(void); +void smp4m_percpu_timer_interrupt(struct pt_regs *regs); /* sun4d_irq.c */ extern spinlock_t sun4d_imsk_lock; -extern void sun4d_init_IRQ(void); -extern int sun4d_request_irq(unsigned int irq, - irq_handler_t handler, - unsigned long irqflags, - const char *devname, void *dev_id); -extern int show_sun4d_interrupts(struct seq_file *, void *); -extern void sun4d_distribute_irqs(void); -extern void sun4d_free_irq(unsigned int irq, void *dev_id); +void sun4d_init_IRQ(void); +int sun4d_request_irq(unsigned int irq, + irq_handler_t handler, + unsigned long irqflags, + const char *devname, void *dev_id); +int show_sun4d_interrupts(struct seq_file *, void *); +void sun4d_distribute_irqs(void); +void sun4d_free_irq(unsigned int irq, void *dev_id); /* sun4d_smp.c */ void sun4d_cpu_pre_starting(void *arg); void sun4d_cpu_pre_online(void *arg); +void __init smp4d_boot_cpus(void); +int smp4d_boot_one_cpu(int i, struct task_struct *idle); +void __init smp4d_smp_done(void); +void smp4d_cross_call_irq(void); +void smp4d_percpu_timer_interrupt(struct pt_regs *regs); /* leon_smp.c */ void leon_cpu_pre_starting(void *arg); void leon_cpu_pre_online(void *arg); +void leonsmp_ipi_interrupt(void); +void leon_cross_call_irq(void); /* head_32.S */ extern unsigned int t_nmi[]; @@ -89,12 +139,48 @@ extern unsigned int real_irq_entry[]; extern unsigned int smp4d_ticker[]; extern unsigned int patchme_maybe_smp_msg[]; -extern void floppy_hardint(void); +void floppy_hardint(void); /* trampoline_32.S */ extern unsigned long sun4m_cpu_startup; extern unsigned long sun4d_cpu_startup; +/* process_32.c */ +asmlinkage int sparc_do_fork(unsigned long clone_flags, + unsigned long stack_start, + struct pt_regs *regs, + unsigned long stack_size); + +/* signal_32.c */ +asmlinkage void do_sigreturn(struct pt_regs *regs); +asmlinkage void do_rt_sigreturn(struct pt_regs *regs); +void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, + unsigned long thread_info_flags); +asmlinkage int do_sys_sigstack(struct sigstack __user *ssptr, + struct sigstack __user *ossptr, + unsigned long sp); + +/* ptrace_32.c */ +asmlinkage int syscall_trace(struct pt_regs *regs, int syscall_exit_p); + +/* unaligned_32.c */ +asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn); +asmlinkage void user_unaligned_trap(struct pt_regs *regs, unsigned int insn); + +/* windows.c */ +void try_to_clear_window_buffer(struct pt_regs *regs, int who); + +/* auxio_32.c */ +void __init auxio_probe(void); +void __init auxio_power_probe(void); + +/* pcic.c */ +extern void __iomem *pcic_regs; +void pcic_nmi(unsigned int pend, struct pt_regs *regs); + +/* time_32.c */ +void __init time_init(void); + #else /* CONFIG_SPARC32 */ #endif /* CONFIG_SPARC32 */ #endif /* !(__SPARC_KERNEL_H) */ diff --git a/arch/sparc/kernel/kgdb_64.c b/arch/sparc/kernel/kgdb_64.c index 53c0a82e603..cbf21d0870e 100644 --- a/arch/sparc/kernel/kgdb_64.c +++ b/arch/sparc/kernel/kgdb_64.c @@ -6,12 +6,15 @@ #include <linux/kgdb.h> #include <linux/kdebug.h> #include <linux/ftrace.h> +#include <linux/context_tracking.h> #include <asm/cacheflush.h> #include <asm/kdebug.h> #include <asm/ptrace.h> #include <asm/irq.h> +#include "kernel.h" + void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs) { struct reg_window *win; @@ -159,11 +162,12 @@ int kgdb_arch_handle_exception(int e_vector, int signo, int err_code, asmlinkage void kgdb_trap(unsigned long trap_level, struct pt_regs *regs) { + enum ctx_state prev_state = exception_enter(); unsigned long flags; if (user_mode(regs)) { bad_trap(regs, trap_level); - return; + goto out; } flushw_all(); @@ -171,6 +175,8 @@ asmlinkage void kgdb_trap(unsigned long trap_level, struct pt_regs *regs) local_irq_save(flags); kgdb_handle_exception(0x172, SIGTRAP, 0, regs); local_irq_restore(flags); +out: + exception_exit(prev_state); } int kgdb_arch_init(void) diff --git a/arch/sparc/kernel/kprobes.c b/arch/sparc/kernel/kprobes.c index e72212148d2..98d71284341 100644 --- a/arch/sparc/kernel/kprobes.c +++ b/arch/sparc/kernel/kprobes.c @@ -8,6 +8,7 @@ #include <linux/module.h> #include <linux/kdebug.h> #include <linux/slab.h> +#include <linux/context_tracking.h> #include <asm/signal.h> #include <asm/cacheflush.h> #include <asm/uaccess.h> @@ -349,7 +350,7 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) case KPROBE_HIT_SSDONE: /* * We increment the nmissed count for accounting, - * we can also use npre/npostfault count for accouting + * we can also use npre/npostfault count for accounting * these specific fault cases. */ kprobes_inc_nmissed_count(cur); @@ -418,12 +419,14 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self, asmlinkage void __kprobes kprobe_trap(unsigned long trap_level, struct pt_regs *regs) { + enum ctx_state prev_state = exception_enter(); + BUG_ON(trap_level != 0x170 && trap_level != 0x171); if (user_mode(regs)) { local_irq_enable(); bad_trap(regs, trap_level); - return; + goto out; } /* trap_level == 0x170 --> ta 0x70 @@ -433,6 +436,8 @@ asmlinkage void __kprobes kprobe_trap(unsigned long trap_level, (trap_level == 0x170) ? "debug" : "debug_2", regs, 0, trap_level, SIGTRAP) != NOTIFY_STOP) bad_trap(regs, trap_level); +out: + exception_exit(prev_state); } /* Jprobes support. */ @@ -507,7 +512,8 @@ void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri, /* * Called when the probe at kretprobe trampoline is hit */ -int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) +static int __kprobes trampoline_probe_handler(struct kprobe *p, + struct pt_regs *regs) { struct kretprobe_instance *ri = NULL; struct hlist_head *head, empty_rp; @@ -571,7 +577,7 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) return 1; } -void kretprobe_trampoline_holder(void) +static void __used kretprobe_trampoline_holder(void) { asm volatile(".global kretprobe_trampoline\n" "kretprobe_trampoline:\n" diff --git a/arch/sparc/kernel/ktlb.S b/arch/sparc/kernel/ktlb.S index fde5a419cf2..605d4920458 100644 --- a/arch/sparc/kernel/ktlb.S +++ b/arch/sparc/kernel/ktlb.S @@ -153,12 +153,19 @@ kvmap_dtlb_tsb4m_miss: /* Clear the PAGE_OFFSET top virtual bits, shift * down to get PFN, and make sure PFN is in range. */ - sllx %g4, 21, %g5 +661: sllx %g4, 0, %g5 + .section .page_offset_shift_patch, "ax" + .word 661b + .previous /* Check to see if we know about valid memory at the 4MB * chunk this physical address will reside within. */ - srlx %g5, 21 + 41, %g2 +661: srlx %g5, MAX_PHYS_ADDRESS_BITS, %g2 + .section .page_offset_shift_patch, "ax" + .word 661b + .previous + brnz,pn %g2, kvmap_dtlb_longpath nop @@ -176,7 +183,11 @@ valid_addr_bitmap_patch: or %g7, %lo(sparc64_valid_addr_bitmap), %g7 .previous - srlx %g5, 21 + 22, %g2 +661: srlx %g5, ILOG2_4MB, %g2 + .section .page_offset_shift_patch, "ax" + .word 661b + .previous + srlx %g2, 6, %g5 and %g2, 63, %g2 sllx %g5, 3, %g5 @@ -189,9 +200,18 @@ valid_addr_bitmap_patch: 2: sethi %hi(kpte_linear_bitmap), %g2 /* Get the 256MB physical address index. */ - sllx %g4, 21, %g5 +661: sllx %g4, 0, %g5 + .section .page_offset_shift_patch, "ax" + .word 661b + .previous + or %g2, %lo(kpte_linear_bitmap), %g2 - srlx %g5, 21 + 28, %g5 + +661: srlx %g5, ILOG2_256MB, %g5 + .section .page_offset_shift_patch, "ax" + .word 661b + .previous + and %g5, (32 - 1), %g7 /* Divide by 32 to get the offset into the bitmask. */ @@ -257,7 +277,7 @@ kvmap_dtlb_load: #ifdef CONFIG_SPARSEMEM_VMEMMAP kvmap_vmemmap: sub %g4, %g5, %g5 - srlx %g5, 22, %g5 + srlx %g5, ILOG2_4MB, %g5 sethi %hi(vmemmap_table), %g1 sllx %g5, 3, %g5 or %g1, %lo(vmemmap_table), %g1 diff --git a/arch/sparc/kernel/ldc.c b/arch/sparc/kernel/ldc.c index 54df554b82d..e01d75d4032 100644 --- a/arch/sparc/kernel/ldc.c +++ b/arch/sparc/kernel/ldc.c @@ -1249,12 +1249,12 @@ int ldc_bind(struct ldc_channel *lp, const char *name) snprintf(lp->rx_irq_name, LDC_IRQ_NAME_MAX, "%s RX", name); snprintf(lp->tx_irq_name, LDC_IRQ_NAME_MAX, "%s TX", name); - err = request_irq(lp->cfg.rx_irq, ldc_rx, IRQF_DISABLED, + err = request_irq(lp->cfg.rx_irq, ldc_rx, 0, lp->rx_irq_name, lp); if (err) return err; - err = request_irq(lp->cfg.tx_irq, ldc_tx, IRQF_DISABLED, + err = request_irq(lp->cfg.tx_irq, ldc_tx, 0, lp->tx_irq_name, lp); if (err) { free_irq(lp->cfg.rx_irq, lp); diff --git a/arch/sparc/kernel/leon_kernel.c b/arch/sparc/kernel/leon_kernel.c index b7c68976cbc..683c4af999d 100644 --- a/arch/sparc/kernel/leon_kernel.c +++ b/arch/sparc/kernel/leon_kernel.c @@ -32,12 +32,12 @@ struct leon3_gptimer_regs_map *leon3_gptimer_regs; /* timer controller base addr int leondebug_irq_disable; int leon_debug_irqout; -static int dummy_master_l10_counter; +static volatile u32 dummy_master_l10_counter; unsigned long amba_system_id; static DEFINE_SPINLOCK(leon_irq_lock); +static unsigned long leon3_gptimer_idx; /* Timer Index (0..6) within Timer Core */ unsigned long leon3_gptimer_irq; /* interrupt controller irq number */ -unsigned long leon3_gptimer_idx; /* Timer Index (0..6) within Timer Core */ unsigned int sparc_leon_eirq; #define LEON_IMASK(cpu) (&leon3_irqctrl_regs->mask[cpu]) #define LEON_IACK (&leon3_irqctrl_regs->iclear) @@ -65,7 +65,7 @@ static void leon_handle_ext_irq(unsigned int irq, struct irq_desc *desc) } /* The extended IRQ controller has been found, this function registers it */ -void leon_eirq_setup(unsigned int eirq) +static void leon_eirq_setup(unsigned int eirq) { unsigned long mask, oldmask; unsigned int veirq; @@ -270,7 +270,7 @@ static u32 leon_cycles_offset(void) #ifdef CONFIG_SMP /* smp clockevent irq */ -irqreturn_t leon_percpu_timer_ce_interrupt(int irq, void *unused) +static irqreturn_t leon_percpu_timer_ce_interrupt(int irq, void *unused) { struct clock_event_device *ce; int cpu = smp_processor_id(); @@ -313,7 +313,7 @@ void __init leon_init_timers(void) leondebug_irq_disable = 0; leon_debug_irqout = 0; - master_l10_counter = (unsigned int *)&dummy_master_l10_counter; + master_l10_counter = (u32 __iomem *)&dummy_master_l10_counter; dummy_master_l10_counter = 0; rootnp = of_find_node_by_path("/ambapp0"); diff --git a/arch/sparc/kernel/leon_pci.c b/arch/sparc/kernel/leon_pci.c index 88aaaa57bb6..899b7203a4e 100644 --- a/arch/sparc/kernel/leon_pci.c +++ b/arch/sparc/kernel/leon_pci.c @@ -98,87 +98,3 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res, { return res->start; } - -int pcibios_enable_device(struct pci_dev *dev, int mask) -{ - return pci_enable_resources(dev, mask); -} - -/* in/out routines taken from pcic.c - * - * This probably belongs here rather than ioport.c because - * we do not want this crud linked into SBus kernels. - * Also, think for a moment about likes of floppy.c that - * include architecture specific parts. They may want to redefine ins/outs. - * - * We do not use horrible macros here because we want to - * advance pointer by sizeof(size). - */ -void outsb(unsigned long addr, const void *src, unsigned long count) -{ - while (count) { - count -= 1; - outb(*(const char *)src, addr); - src += 1; - /* addr += 1; */ - } -} -EXPORT_SYMBOL(outsb); - -void outsw(unsigned long addr, const void *src, unsigned long count) -{ - while (count) { - count -= 2; - outw(*(const short *)src, addr); - src += 2; - /* addr += 2; */ - } -} -EXPORT_SYMBOL(outsw); - -void outsl(unsigned long addr, const void *src, unsigned long count) -{ - while (count) { - count -= 4; - outl(*(const long *)src, addr); - src += 4; - /* addr += 4; */ - } -} -EXPORT_SYMBOL(outsl); - -void insb(unsigned long addr, void *dst, unsigned long count) -{ - while (count) { - count -= 1; - *(unsigned char *)dst = inb(addr); - dst += 1; - /* addr += 1; */ - } -} -EXPORT_SYMBOL(insb); - -void insw(unsigned long addr, void *dst, unsigned long count) -{ - while (count) { - count -= 2; - *(unsigned short *)dst = inw(addr); - dst += 2; - /* addr += 2; */ - } -} -EXPORT_SYMBOL(insw); - -void insl(unsigned long addr, void *dst, unsigned long count) -{ - while (count) { - count -= 4; - /* - * XXX I am sure we are in for an unaligned trap here. - */ - *(unsigned long *)dst = inl(addr); - dst += 4; - /* addr += 4; */ - } -} -EXPORT_SYMBOL(insl); diff --git a/arch/sparc/kernel/leon_pci_grpci1.c b/arch/sparc/kernel/leon_pci_grpci1.c index 6df26e37f87..c8bf26edfa7 100644 --- a/arch/sparc/kernel/leon_pci_grpci1.c +++ b/arch/sparc/kernel/leon_pci_grpci1.c @@ -80,7 +80,7 @@ struct grpci1_regs { struct grpci1_priv { struct leon_pci_info info; /* must be on top of this structure */ - struct grpci1_regs *regs; /* GRPCI register map */ + struct grpci1_regs __iomem *regs; /* GRPCI register map */ struct device *dev; int pci_err_mask; /* STATUS register error mask */ int irq; /* LEON irqctrl GRPCI IRQ */ @@ -101,7 +101,7 @@ static struct grpci1_priv *grpci1priv; static int grpci1_cfg_w32(struct grpci1_priv *priv, unsigned int bus, unsigned int devfn, int where, u32 val); -int grpci1_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +static int grpci1_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { struct grpci1_priv *priv = dev->bus->sysdata; int irq_group; @@ -144,7 +144,7 @@ static int grpci1_cfg_r32(struct grpci1_priv *priv, unsigned int bus, grpci1_cfg_w32(priv, TGT, 0, PCI_COMMAND, tmp); } else { /* Bus always little endian (unaffected by byte-swapping) */ - *val = flip_dword(tmp); + *val = swab32(tmp); } return 0; @@ -197,7 +197,7 @@ static int grpci1_cfg_w32(struct grpci1_priv *priv, unsigned int bus, pci_conf = (unsigned int *) (priv->pci_conf | (devfn << 8) | (where & 0xfc)); - LEON3_BYPASS_STORE_PA(pci_conf, flip_dword(val)); + LEON3_BYPASS_STORE_PA(pci_conf, swab32(val)); return 0; } @@ -417,10 +417,10 @@ out: * BAR1: peripheral DMA to host's memory (size at least 256MByte) * BAR2..BAR5: not implemented in hardware */ -void grpci1_hw_init(struct grpci1_priv *priv) +static void grpci1_hw_init(struct grpci1_priv *priv) { u32 ahbadr, bar_sz, data, pciadr; - struct grpci1_regs *regs = priv->regs; + struct grpci1_regs __iomem *regs = priv->regs; /* set 1:1 mapping between AHB -> PCI memory space */ REGSTORE(regs->cfg_stat, priv->pci_area & 0xf0000000); @@ -509,7 +509,7 @@ static irqreturn_t grpci1_err_interrupt(int irq, void *arg) static int grpci1_of_probe(struct platform_device *ofdev) { - struct grpci1_regs *regs; + struct grpci1_regs __iomem *regs; struct grpci1_priv *priv; int err, len; const int *tmp; @@ -690,7 +690,7 @@ err3: err2: release_resource(&priv->info.mem_space); err1: - iounmap((void *)priv->pci_io_va); + iounmap((void __iomem *)priv->pci_io_va); grpci1priv = NULL; return err; } diff --git a/arch/sparc/kernel/leon_pci_grpci2.c b/arch/sparc/kernel/leon_pci_grpci2.c index 5f0402aab7f..e433a4d69fe 100644 --- a/arch/sparc/kernel/leon_pci_grpci2.c +++ b/arch/sparc/kernel/leon_pci_grpci2.c @@ -8,6 +8,7 @@ #include <linux/of_device.h> #include <linux/kernel.h> #include <linux/pci.h> +#include <linux/slab.h> #include <linux/delay.h> #include <linux/export.h> #include <asm/io.h> @@ -190,7 +191,7 @@ struct grpci2_cap_first { struct grpci2_priv { struct leon_pci_info info; /* must be on top of this structure */ - struct grpci2_regs *regs; + struct grpci2_regs __iomem *regs; char irq; char irq_mode; /* IRQ Mode from CAPSTS REG */ char bt_enabled; @@ -214,10 +215,10 @@ struct grpci2_priv { struct grpci2_barcfg tgtbars[6]; }; -DEFINE_SPINLOCK(grpci2_dev_lock); -struct grpci2_priv *grpci2priv; +static DEFINE_SPINLOCK(grpci2_dev_lock); +static struct grpci2_priv *grpci2priv; -int grpci2_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +static int grpci2_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { struct grpci2_priv *priv = dev->bus->sysdata; int irq_group; @@ -269,7 +270,7 @@ static int grpci2_cfg_r32(struct grpci2_priv *priv, unsigned int bus, *val = 0xffffffff; } else { /* Bus always little endian (unaffected by byte-swapping) */ - *val = flip_dword(tmp); + *val = swab32(tmp); } return 0; @@ -327,7 +328,7 @@ static int grpci2_cfg_w32(struct grpci2_priv *priv, unsigned int bus, pci_conf = (unsigned int *) (priv->pci_conf | (devfn << 8) | (where & 0xfc)); - LEON3_BYPASS_STORE_PA(pci_conf, flip_dword(val)); + LEON3_BYPASS_STORE_PA(pci_conf, swab32(val)); /* Wait until GRPCI2 signals that CFG access is done, it should be * done instantaneously unless a DMA operation is ongoing... @@ -560,10 +561,10 @@ out: return virq; } -void grpci2_hw_init(struct grpci2_priv *priv) +static void grpci2_hw_init(struct grpci2_priv *priv) { u32 ahbadr, pciadr, bar_sz, capptr, io_map, data; - struct grpci2_regs *regs = priv->regs; + struct grpci2_regs __iomem *regs = priv->regs; int i; struct grpci2_barcfg *barcfg = priv->tgtbars; @@ -654,7 +655,7 @@ static irqreturn_t grpci2_jump_interrupt(int irq, void *arg) static irqreturn_t grpci2_err_interrupt(int irq, void *arg) { struct grpci2_priv *priv = arg; - struct grpci2_regs *regs = priv->regs; + struct grpci2_regs __iomem *regs = priv->regs; unsigned int status; status = REGLOAD(regs->sts_cap); @@ -681,7 +682,7 @@ static irqreturn_t grpci2_err_interrupt(int irq, void *arg) static int grpci2_of_probe(struct platform_device *ofdev) { - struct grpci2_regs *regs; + struct grpci2_regs __iomem *regs; struct grpci2_priv *priv; int err, i, len; const int *tmp; @@ -877,7 +878,7 @@ err4: release_resource(&priv->info.mem_space); err3: err = -ENOMEM; - iounmap((void *)priv->pci_io_va); + iounmap((void __iomem *)priv->pci_io_va); err2: kfree(priv); err1: diff --git a/arch/sparc/kernel/leon_pmc.c b/arch/sparc/kernel/leon_pmc.c index b0b3967a2dd..ddcf950282e 100644 --- a/arch/sparc/kernel/leon_pmc.c +++ b/arch/sparc/kernel/leon_pmc.c @@ -12,14 +12,14 @@ #include <asm/processor.h> /* List of Systems that need fixup instructions around power-down instruction */ -unsigned int pmc_leon_fixup_ids[] = { +static unsigned int pmc_leon_fixup_ids[] = { AEROFLEX_UT699, GAISLER_GR712RC, LEON4_NEXTREME1, 0 }; -int pmc_leon_need_fixup(void) +static int pmc_leon_need_fixup(void) { unsigned int systemid = amba_system_id >> 16; unsigned int *id; @@ -38,7 +38,7 @@ int pmc_leon_need_fixup(void) * CPU idle callback function for systems that need some extra handling * See .../arch/sparc/kernel/process.c */ -void pmc_leon_idle_fixup(void) +static void pmc_leon_idle_fixup(void) { /* Prepare an address to a non-cachable region. APB is always * none-cachable. One instruction is executed after the Sleep @@ -62,7 +62,7 @@ void pmc_leon_idle_fixup(void) * CPU idle callback function * See .../arch/sparc/kernel/process.c */ -void pmc_leon_idle(void) +static void pmc_leon_idle(void) { /* Interrupts need to be enabled to not hang the CPU */ local_irq_enable(); diff --git a/arch/sparc/kernel/leon_smp.c b/arch/sparc/kernel/leon_smp.c index 6edf955f987..018ef11f57d 100644 --- a/arch/sparc/kernel/leon_smp.c +++ b/arch/sparc/kernel/leon_smp.c @@ -130,7 +130,7 @@ void leon_configure_cache_smp(void) local_ops->tlb_all(); } -void leon_smp_setbroadcast(unsigned int mask) +static void leon_smp_setbroadcast(unsigned int mask) { int broadcast = ((LEON3_BYPASS_LOAD_PA(&(leon3_irqctrl_regs->mpstatus)) >> @@ -148,13 +148,6 @@ void leon_smp_setbroadcast(unsigned int mask) LEON_BYPASS_STORE_PA(&(leon3_irqctrl_regs->mpbroadcast), mask); } -unsigned int leon_smp_getbroadcast(void) -{ - unsigned int mask; - mask = LEON_BYPASS_LOAD_PA(&(leon3_irqctrl_regs->mpbroadcast)); - return mask; -} - int leon_smp_nrcpus(void) { int nrcpu = @@ -266,10 +259,6 @@ void __init leon_smp_done(void) } -void leon_irq_rotate(int cpu) -{ -} - struct leon_ipi_work { int single; int msk; diff --git a/arch/sparc/kernel/mdesc.c b/arch/sparc/kernel/mdesc.c index b90bf23e3aa..a1a4400d402 100644 --- a/arch/sparc/kernel/mdesc.c +++ b/arch/sparc/kernel/mdesc.c @@ -896,10 +896,6 @@ void mdesc_fill_in_cpu_data(cpumask_t *mask) mdesc_iterate_over_cpus(fill_in_one_cpu, NULL, mask); -#ifdef CONFIG_SMP - sparc64_multi_core = 1; -#endif - hp = mdesc_grab(); set_core_ids(hp); diff --git a/arch/sparc/kernel/module.c b/arch/sparc/kernel/module.c index 4435488ebe2..97655e0fd24 100644 --- a/arch/sparc/kernel/module.c +++ b/arch/sparc/kernel/module.c @@ -29,7 +29,7 @@ static void *module_map(unsigned long size) if (PAGE_ALIGN(size) > MODULES_LEN) return NULL; return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END, - GFP_KERNEL, PAGE_KERNEL, -1, + GFP_KERNEL, PAGE_KERNEL, NUMA_NO_NODE, __builtin_return_address(0)); } #else diff --git a/arch/sparc/kernel/nmi.c b/arch/sparc/kernel/nmi.c index 6479256fd5a..33709455691 100644 --- a/arch/sparc/kernel/nmi.c +++ b/arch/sparc/kernel/nmi.c @@ -68,27 +68,16 @@ EXPORT_SYMBOL(touch_nmi_watchdog); static void die_nmi(const char *str, struct pt_regs *regs, int do_panic) { + int this_cpu = smp_processor_id(); + if (notify_die(DIE_NMIWATCHDOG, str, regs, 0, pt_regs_trap_type(regs), SIGINT) == NOTIFY_STOP) return; - console_verbose(); - bust_spinlocks(1); - - printk(KERN_EMERG "%s", str); - printk(" on CPU%d, ip %08lx, registers:\n", - smp_processor_id(), regs->tpc); - show_regs(regs); - dump_stack(); - - bust_spinlocks(0); - if (do_panic || panic_on_oops) - panic("Non maskable interrupt"); - - nmi_exit(); - local_irq_enable(); - do_exit(SIGBUS); + panic("Watchdog detected hard LOCKUP on cpu %d", this_cpu); + else + WARN(1, "Watchdog detected hard LOCKUP on cpu %d", this_cpu); } notrace __kprobes void perfctr_irq(int irq, struct pt_regs *regs) diff --git a/arch/sparc/kernel/of_device_common.c b/arch/sparc/kernel/of_device_common.c index de199bf0cb0..de0ee3971f0 100644 --- a/arch/sparc/kernel/of_device_common.c +++ b/arch/sparc/kernel/of_device_common.c @@ -1,13 +1,14 @@ #include <linux/string.h> #include <linux/kernel.h> #include <linux/of.h> -#include <linux/init.h> #include <linux/export.h> #include <linux/mod_devicetable.h> #include <linux/errno.h> #include <linux/irq.h> -#include <linux/of_device.h> #include <linux/of_platform.h> +#include <linux/of_address.h> +#include <linux/of_device.h> +#include <linux/of_irq.h> #include "of_device_common.h" diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c index bc4d3f5d2e5..539babf00bb 100644 --- a/arch/sparc/kernel/pci.c +++ b/arch/sparc/kernel/pci.c @@ -28,6 +28,7 @@ #include <asm/apb.h> #include "pci_impl.h" +#include "kernel.h" /* List of all PCI controllers found in the system. */ struct pci_pbm_info *pci_pbm_root = NULL; @@ -392,15 +393,15 @@ static void apb_fake_ranges(struct pci_dev *dev, res->flags = IORESOURCE_IO; region.start = (first << 21); region.end = (last << 21) + ((1 << 21) - 1); - pcibios_bus_to_resource(dev, res, ®ion); + pcibios_bus_to_resource(dev->bus, res, ®ion); pci_read_config_byte(dev, APB_MEM_ADDRESS_MAP, &map); apb_calc_first_last(map, &first, &last); res = bus->resource[1]; res->flags = IORESOURCE_MEM; - region.start = (first << 21); - region.end = (last << 21) + ((1 << 21) - 1); - pcibios_bus_to_resource(dev, res, ®ion); + region.start = (first << 29); + region.end = (last << 29) + ((1 << 29) - 1); + pcibios_bus_to_resource(dev->bus, res, ®ion); } static void pci_of_scan_bus(struct pci_pbm_info *pbm, @@ -491,7 +492,7 @@ static void of_scan_pci_bridge(struct pci_pbm_info *pbm, res->flags = flags; region.start = GET_64BIT(ranges, 1); region.end = region.start + size - 1; - pcibios_bus_to_resource(dev, res, ®ion); + pcibios_bus_to_resource(dev->bus, res, ®ion); } after_ranges: sprintf(bus->name, "PCI Bus %04x:%02x", pci_domain_nr(bus), @@ -543,8 +544,7 @@ static void pci_of_scan_bus(struct pci_pbm_info *pbm, printk("PCI: dev header type: %x\n", dev->hdr_type); - if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || - dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) + if (pci_is_bridge(dev)) of_scan_pci_bridge(pbm, child, dev); } } @@ -1005,6 +1005,5 @@ static int __init of_pci_slot_init(void) return 0; } - -module_init(of_pci_slot_init); +device_initcall(of_pci_slot_init); #endif diff --git a/arch/sparc/kernel/pci_common.c b/arch/sparc/kernel/pci_common.c index a6895987fb7..944a06536ec 100644 --- a/arch/sparc/kernel/pci_common.c +++ b/arch/sparc/kernel/pci_common.c @@ -5,7 +5,6 @@ #include <linux/string.h> #include <linux/slab.h> -#include <linux/init.h> #include <linux/pci.h> #include <linux/device.h> #include <linux/of_device.h> diff --git a/arch/sparc/kernel/pci_impl.h b/arch/sparc/kernel/pci_impl.h index 5f688531f48..75803c780af 100644 --- a/arch/sparc/kernel/pci_impl.h +++ b/arch/sparc/kernel/pci_impl.h @@ -48,8 +48,8 @@ struct sparc64_msiq_ops { unsigned long devino); }; -extern void sparc64_pbm_msi_init(struct pci_pbm_info *pbm, - const struct sparc64_msiq_ops *ops); +void sparc64_pbm_msi_init(struct pci_pbm_info *pbm, + const struct sparc64_msiq_ops *ops); struct sparc64_msiq_cookie { struct pci_pbm_info *pbm; @@ -158,23 +158,23 @@ extern struct pci_pbm_info *pci_pbm_root; extern int pci_num_pbms; /* PCI bus scanning and fixup support. */ -extern void pci_get_pbm_props(struct pci_pbm_info *pbm); -extern struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm, - struct device *parent); -extern void pci_determine_mem_io_space(struct pci_pbm_info *pbm); +void pci_get_pbm_props(struct pci_pbm_info *pbm); +struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm, + struct device *parent); +void pci_determine_mem_io_space(struct pci_pbm_info *pbm); /* Error reporting support. */ -extern void pci_scan_for_target_abort(struct pci_pbm_info *, struct pci_bus *); -extern void pci_scan_for_master_abort(struct pci_pbm_info *, struct pci_bus *); -extern void pci_scan_for_parity_error(struct pci_pbm_info *, struct pci_bus *); +void pci_scan_for_target_abort(struct pci_pbm_info *, struct pci_bus *); +void pci_scan_for_master_abort(struct pci_pbm_info *, struct pci_bus *); +void pci_scan_for_parity_error(struct pci_pbm_info *, struct pci_bus *); /* Configuration space access. */ -extern void pci_config_read8(u8 *addr, u8 *ret); -extern void pci_config_read16(u16 *addr, u16 *ret); -extern void pci_config_read32(u32 *addr, u32 *ret); -extern void pci_config_write8(u8 *addr, u8 val); -extern void pci_config_write16(u16 *addr, u16 val); -extern void pci_config_write32(u32 *addr, u32 val); +void pci_config_read8(u8 *addr, u8 *ret); +void pci_config_read16(u16 *addr, u16 *ret); +void pci_config_read32(u32 *addr, u32 *ret); +void pci_config_write8(u8 *addr, u8 val); +void pci_config_write16(u16 *addr, u16 val); +void pci_config_write32(u32 *addr, u32 val); extern struct pci_ops sun4u_pci_ops; extern struct pci_ops sun4v_pci_ops; diff --git a/arch/sparc/kernel/pci_sun4v.h b/arch/sparc/kernel/pci_sun4v.h index 8e9fc3a5b4f..5642212390b 100644 --- a/arch/sparc/kernel/pci_sun4v.h +++ b/arch/sparc/kernel/pci_sun4v.h @@ -6,87 +6,87 @@ #ifndef _PCI_SUN4V_H #define _PCI_SUN4V_H -extern long pci_sun4v_iommu_map(unsigned long devhandle, - unsigned long tsbid, - unsigned long num_ttes, - unsigned long io_attributes, - unsigned long io_page_list_pa); -extern unsigned long pci_sun4v_iommu_demap(unsigned long devhandle, - unsigned long tsbid, - unsigned long num_ttes); -extern unsigned long pci_sun4v_iommu_getmap(unsigned long devhandle, - unsigned long tsbid, - unsigned long *io_attributes, - unsigned long *real_address); -extern unsigned long pci_sun4v_config_get(unsigned long devhandle, - unsigned long pci_device, - unsigned long config_offset, - unsigned long size); -extern int pci_sun4v_config_put(unsigned long devhandle, - unsigned long pci_device, - unsigned long config_offset, - unsigned long size, - unsigned long data); +long pci_sun4v_iommu_map(unsigned long devhandle, + unsigned long tsbid, + unsigned long num_ttes, + unsigned long io_attributes, + unsigned long io_page_list_pa); +unsigned long pci_sun4v_iommu_demap(unsigned long devhandle, + unsigned long tsbid, + unsigned long num_ttes); +unsigned long pci_sun4v_iommu_getmap(unsigned long devhandle, + unsigned long tsbid, + unsigned long *io_attributes, + unsigned long *real_address); +unsigned long pci_sun4v_config_get(unsigned long devhandle, + unsigned long pci_device, + unsigned long config_offset, + unsigned long size); +int pci_sun4v_config_put(unsigned long devhandle, + unsigned long pci_device, + unsigned long config_offset, + unsigned long size, + unsigned long data); -extern unsigned long pci_sun4v_msiq_conf(unsigned long devhandle, +unsigned long pci_sun4v_msiq_conf(unsigned long devhandle, unsigned long msiqid, unsigned long msiq_paddr, unsigned long num_entries); -extern unsigned long pci_sun4v_msiq_info(unsigned long devhandle, - unsigned long msiqid, - unsigned long *msiq_paddr, - unsigned long *num_entries); -extern unsigned long pci_sun4v_msiq_getvalid(unsigned long devhandle, - unsigned long msiqid, - unsigned long *valid); -extern unsigned long pci_sun4v_msiq_setvalid(unsigned long devhandle, - unsigned long msiqid, - unsigned long valid); -extern unsigned long pci_sun4v_msiq_getstate(unsigned long devhandle, - unsigned long msiqid, - unsigned long *state); -extern unsigned long pci_sun4v_msiq_setstate(unsigned long devhandle, - unsigned long msiqid, - unsigned long state); -extern unsigned long pci_sun4v_msiq_gethead(unsigned long devhandle, - unsigned long msiqid, - unsigned long *head); -extern unsigned long pci_sun4v_msiq_sethead(unsigned long devhandle, - unsigned long msiqid, - unsigned long head); -extern unsigned long pci_sun4v_msiq_gettail(unsigned long devhandle, - unsigned long msiqid, - unsigned long *head); -extern unsigned long pci_sun4v_msi_getvalid(unsigned long devhandle, - unsigned long msinum, - unsigned long *valid); -extern unsigned long pci_sun4v_msi_setvalid(unsigned long devhandle, - unsigned long msinum, - unsigned long valid); -extern unsigned long pci_sun4v_msi_getmsiq(unsigned long devhandle, - unsigned long msinum, - unsigned long *msiq); -extern unsigned long pci_sun4v_msi_setmsiq(unsigned long devhandle, - unsigned long msinum, - unsigned long msiq, - unsigned long msitype); -extern unsigned long pci_sun4v_msi_getstate(unsigned long devhandle, - unsigned long msinum, - unsigned long *state); -extern unsigned long pci_sun4v_msi_setstate(unsigned long devhandle, - unsigned long msinum, - unsigned long state); -extern unsigned long pci_sun4v_msg_getmsiq(unsigned long devhandle, - unsigned long msinum, - unsigned long *msiq); -extern unsigned long pci_sun4v_msg_setmsiq(unsigned long devhandle, - unsigned long msinum, - unsigned long msiq); -extern unsigned long pci_sun4v_msg_getvalid(unsigned long devhandle, - unsigned long msinum, - unsigned long *valid); -extern unsigned long pci_sun4v_msg_setvalid(unsigned long devhandle, - unsigned long msinum, - unsigned long valid); +unsigned long pci_sun4v_msiq_info(unsigned long devhandle, + unsigned long msiqid, + unsigned long *msiq_paddr, + unsigned long *num_entries); +unsigned long pci_sun4v_msiq_getvalid(unsigned long devhandle, + unsigned long msiqid, + unsigned long *valid); +unsigned long pci_sun4v_msiq_setvalid(unsigned long devhandle, + unsigned long msiqid, + unsigned long valid); +unsigned long pci_sun4v_msiq_getstate(unsigned long devhandle, + unsigned long msiqid, + unsigned long *state); +unsigned long pci_sun4v_msiq_setstate(unsigned long devhandle, + unsigned long msiqid, + unsigned long state); +unsigned long pci_sun4v_msiq_gethead(unsigned long devhandle, + unsigned long msiqid, + unsigned long *head); +unsigned long pci_sun4v_msiq_sethead(unsigned long devhandle, + unsigned long msiqid, + unsigned long head); +unsigned long pci_sun4v_msiq_gettail(unsigned long devhandle, + unsigned long msiqid, + unsigned long *head); +unsigned long pci_sun4v_msi_getvalid(unsigned long devhandle, + unsigned long msinum, + unsigned long *valid); +unsigned long pci_sun4v_msi_setvalid(unsigned long devhandle, + unsigned long msinum, + unsigned long valid); +unsigned long pci_sun4v_msi_getmsiq(unsigned long devhandle, + unsigned long msinum, + unsigned long *msiq); +unsigned long pci_sun4v_msi_setmsiq(unsigned long devhandle, + unsigned long msinum, + unsigned long msiq, + unsigned long msitype); +unsigned long pci_sun4v_msi_getstate(unsigned long devhandle, + unsigned long msinum, + unsigned long *state); +unsigned long pci_sun4v_msi_setstate(unsigned long devhandle, + unsigned long msinum, + unsigned long state); +unsigned long pci_sun4v_msg_getmsiq(unsigned long devhandle, + unsigned long msinum, + unsigned long *msiq); +unsigned long pci_sun4v_msg_setmsiq(unsigned long devhandle, + unsigned long msinum, + unsigned long msiq); +unsigned long pci_sun4v_msg_getvalid(unsigned long devhandle, + unsigned long msinum, + unsigned long *valid); +unsigned long pci_sun4v_msg_setvalid(unsigned long devhandle, + unsigned long msinum, + unsigned long valid); #endif /* !(_PCI_SUN4V_H) */ diff --git a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c index 09f4fdd8d80..6cc78c213c0 100644 --- a/arch/sparc/kernel/pcic.c +++ b/arch/sparc/kernel/pcic.c @@ -36,6 +36,7 @@ #include <asm/uaccess.h> #include <asm/irq_regs.h> +#include "kernel.h" #include "irq.h" /* @@ -162,8 +163,8 @@ static int pcic0_up; static struct linux_pcic pcic0; void __iomem *pcic_regs; -volatile int pcic_speculative; -volatile int pcic_trapped; +static volatile int pcic_speculative; +static volatile int pcic_trapped; /* forward */ unsigned int pcic_build_device_irq(struct platform_device *op, @@ -329,7 +330,7 @@ int __init pcic_probe(void) pcic->pcic_res_cfg_addr.name = "pcic_cfg_addr"; if ((pcic->pcic_config_space_addr = - ioremap(regs[2].phys_addr, regs[2].reg_size * 2)) == 0) { + ioremap(regs[2].phys_addr, regs[2].reg_size * 2)) == NULL) { prom_printf("PCIC: Error, cannot map " "PCI Configuration Space Address.\n"); prom_halt(); @@ -341,7 +342,7 @@ int __init pcic_probe(void) */ pcic->pcic_res_cfg_data.name = "pcic_cfg_data"; if ((pcic->pcic_config_space_data = - ioremap(regs[3].phys_addr, regs[3].reg_size * 2)) == 0) { + ioremap(regs[3].phys_addr, regs[3].reg_size * 2)) == NULL) { prom_printf("PCIC: Error, cannot map " "PCI Configuration Space Data.\n"); prom_halt(); @@ -353,7 +354,6 @@ int __init pcic_probe(void) strcpy(pbm->prom_name, namebuf); { - extern volatile int t_nmi[4]; extern int pcic_nmi_trap_patch[4]; t_nmi[0] = pcic_nmi_trap_patch[0]; @@ -536,7 +536,7 @@ pcic_fill_irq(struct linux_pcic *pcic, struct pci_dev *dev, int node) prom_getstring(node, "name", namebuf, sizeof(namebuf)); } - if ((p = pcic->pcic_imap) == 0) { + if ((p = pcic->pcic_imap) == NULL) { dev->irq = 0; return; } @@ -670,30 +670,6 @@ void pcibios_fixup_bus(struct pci_bus *bus) } } -/* - * pcic_pin_to_irq() is exported to bus probing code - */ -unsigned int -pcic_pin_to_irq(unsigned int pin, const char *name) -{ - struct linux_pcic *pcic = &pcic0; - unsigned int irq; - unsigned int ivec; - - if (pin < 4) { - ivec = readw(pcic->pcic_regs+PCI_INT_SELECT_LO); - irq = ivec >> (pin << 2) & 0xF; - } else if (pin < 8) { - ivec = readw(pcic->pcic_regs+PCI_INT_SELECT_HI); - irq = ivec >> ((pin-4) << 2) & 0xF; - } else { /* Corrupted map */ - printk("PCIC: BAD PIN %d FOR %s\n", pin, name); - for (;;) {} /* XXX Cannot panic properly in case of PROLL */ - } -/* P3 */ /* printk("PCIC: dev %s pin %d ivec 0x%x irq %x\n", name, pin, ivec, irq); */ - return irq; -} - /* Makes compiler happy */ static volatile int pcic_timer_dummy; @@ -783,7 +759,7 @@ int pcibios_enable_device(struct pci_dev *pdev, int mask) void pcic_nmi(unsigned int pend, struct pt_regs *regs) { - pend = flip_dword(pend); + pend = swab32(pend); if (!pcic_speculative || (pend & PCI_SYS_INT_PENDING_PIO) == 0) { /* @@ -875,82 +851,4 @@ void __init sun4m_pci_init_IRQ(void) sparc_config.load_profile_irq = pcic_load_profile_irq; } -/* - * This probably belongs here rather than ioport.c because - * we do not want this crud linked into SBus kernels. - * Also, think for a moment about likes of floppy.c that - * include architecture specific parts. They may want to redefine ins/outs. - * - * We do not use horrible macros here because we want to - * advance pointer by sizeof(size). - */ -void outsb(unsigned long addr, const void *src, unsigned long count) -{ - while (count) { - count -= 1; - outb(*(const char *)src, addr); - src += 1; - /* addr += 1; */ - } -} -EXPORT_SYMBOL(outsb); - -void outsw(unsigned long addr, const void *src, unsigned long count) -{ - while (count) { - count -= 2; - outw(*(const short *)src, addr); - src += 2; - /* addr += 2; */ - } -} -EXPORT_SYMBOL(outsw); - -void outsl(unsigned long addr, const void *src, unsigned long count) -{ - while (count) { - count -= 4; - outl(*(const long *)src, addr); - src += 4; - /* addr += 4; */ - } -} -EXPORT_SYMBOL(outsl); - -void insb(unsigned long addr, void *dst, unsigned long count) -{ - while (count) { - count -= 1; - *(unsigned char *)dst = inb(addr); - dst += 1; - /* addr += 1; */ - } -} -EXPORT_SYMBOL(insb); - -void insw(unsigned long addr, void *dst, unsigned long count) -{ - while (count) { - count -= 2; - *(unsigned short *)dst = inw(addr); - dst += 2; - /* addr += 2; */ - } -} -EXPORT_SYMBOL(insw); - -void insl(unsigned long addr, void *dst, unsigned long count) -{ - while (count) { - count -= 4; - /* - * XXX I am sure we are in for an unaligned trap here. - */ - *(unsigned long *)dst = inl(addr); - dst += 4; - /* addr += 4; */ - } -} -EXPORT_SYMBOL(insl); - subsys_initcall(pcic_init); diff --git a/arch/sparc/kernel/perf_event.c b/arch/sparc/kernel/perf_event.c index b5c38faa4ea..8efd33753ad 100644 --- a/arch/sparc/kernel/perf_event.c +++ b/arch/sparc/kernel/perf_event.c @@ -110,7 +110,7 @@ struct cpu_hw_events { unsigned int group_flag; }; -DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = { .enabled = 1, }; +static DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = { .enabled = 1, }; /* An event map describes the characteristics of a performance * counter event. In particular it gives the encoding as well as @@ -1153,7 +1153,7 @@ static void perf_stop_nmi_watchdog(void *unused) cpuc->pcr[i] = pcr_ops->read_pcr(i); } -void perf_event_grab_pmc(void) +static void perf_event_grab_pmc(void) { if (atomic_inc_not_zero(&active_events)) return; @@ -1169,7 +1169,7 @@ void perf_event_grab_pmc(void) mutex_unlock(&pmc_grab_mutex); } -void perf_event_release_pmc(void) +static void perf_event_release_pmc(void) { if (atomic_dec_and_mutex_lock(&active_events, &pmc_grab_mutex)) { if (atomic_read(&nmi_active) == 0) @@ -1669,7 +1669,7 @@ static bool __init supported_pmu(void) return false; } -int __init init_hw_perf_events(void) +static int __init init_hw_perf_events(void) { pr_info("Performance events: "); @@ -1742,10 +1742,11 @@ static void perf_callchain_user_64(struct perf_callchain_entry *entry, ufp = regs->u_regs[UREG_I6] + STACK_BIAS; do { - struct sparc_stackf *usf, sf; + struct sparc_stackf __user *usf; + struct sparc_stackf sf; unsigned long pc; - usf = (struct sparc_stackf *) ufp; + usf = (struct sparc_stackf __user *)ufp; if (__copy_from_user_inatomic(&sf, usf, sizeof(sf))) break; @@ -1765,17 +1766,19 @@ static void perf_callchain_user_32(struct perf_callchain_entry *entry, unsigned long pc; if (thread32_stack_is_64bit(ufp)) { - struct sparc_stackf *usf, sf; + struct sparc_stackf __user *usf; + struct sparc_stackf sf; ufp += STACK_BIAS; - usf = (struct sparc_stackf *) ufp; + usf = (struct sparc_stackf __user *)ufp; if (__copy_from_user_inatomic(&sf, usf, sizeof(sf))) break; pc = sf.callers_pc & 0xffffffff; ufp = ((unsigned long) sf.fp) & 0xffffffff; } else { - struct sparc_stackf32 *usf, sf; - usf = (struct sparc_stackf32 *) ufp; + struct sparc_stackf32 __user *usf; + struct sparc_stackf32 sf; + usf = (struct sparc_stackf32 __user *)ufp; if (__copy_from_user_inatomic(&sf, usf, sizeof(sf))) break; pc = sf.callers_pc; diff --git a/arch/sparc/kernel/process_32.c b/arch/sparc/kernel/process_32.c index fdd819dfdac..50e7b626afe 100644 --- a/arch/sparc/kernel/process_32.c +++ b/arch/sparc/kernel/process_32.c @@ -10,6 +10,7 @@ #include <stdarg.h> +#include <linux/elfcore.h> #include <linux/errno.h> #include <linux/module.h> #include <linux/sched.h> @@ -22,8 +23,8 @@ #include <linux/reboot.h> #include <linux/delay.h> #include <linux/pm.h> -#include <linux/init.h> #include <linux/slab.h> +#include <linux/cpu.h> #include <asm/auxio.h> #include <asm/oplib.h> @@ -39,6 +40,8 @@ #include <asm/unistd.h> #include <asm/setup.h> +#include "kernel.h" + /* * Power management idle function * Set in pm platform drivers (apc.c and pmc.c) @@ -103,8 +106,12 @@ void machine_restart(char * cmd) void machine_power_off(void) { if (auxio_power_register && - (strcmp(of_console_device->type, "serial") || scons_pwroff)) - *auxio_power_register |= AUXIO_POWER_OFF; + (strcmp(of_console_device->type, "serial") || scons_pwroff)) { + u8 power_register = sbus_readb(auxio_power_register); + power_register |= AUXIO_POWER_OFF; + sbus_writeb(power_register, auxio_power_register); + } + machine_halt(); } diff --git a/arch/sparc/kernel/process_64.c b/arch/sparc/kernel/process_64.c index baebab21549..027e0998619 100644 --- a/arch/sparc/kernel/process_64.c +++ b/arch/sparc/kernel/process_64.c @@ -31,6 +31,7 @@ #include <linux/elfcore.h> #include <linux/sysrq.h> #include <linux/nmi.h> +#include <linux/context_tracking.h> #include <asm/uaccess.h> #include <asm/page.h> @@ -57,9 +58,12 @@ void arch_cpu_idle(void) { if (tlb_type != hypervisor) { touch_nmi_watchdog(); + local_irq_enable(); } else { unsigned long pstate; + local_irq_enable(); + /* The sun4v sleeping code requires that we have PSTATE.IE cleared over * the cpu sleep hypervisor call. */ @@ -81,11 +85,10 @@ void arch_cpu_idle(void) : "=&r" (pstate) : "i" (PSTATE_IE)); } - local_irq_enable(); } #ifdef CONFIG_HOTPLUG_CPU -void arch_cpu_idle_dead() +void arch_cpu_idle_dead(void) { sched_preempt_enable_no_resched(); cpu_play_dead(); @@ -236,7 +239,7 @@ static void __global_reg_poll(struct global_reg_snapshot *gp) } } -void arch_trigger_all_cpu_backtrace(void) +void arch_trigger_all_cpu_backtrace(bool include_self) { struct thread_info *tp = current_thread_info(); struct pt_regs *regs = get_irq_regs(); @@ -248,16 +251,22 @@ void arch_trigger_all_cpu_backtrace(void) spin_lock_irqsave(&global_cpu_snapshot_lock, flags); - memset(global_cpu_snapshot, 0, sizeof(global_cpu_snapshot)); - this_cpu = raw_smp_processor_id(); - __global_reg_self(tp, regs, this_cpu); + memset(global_cpu_snapshot, 0, sizeof(global_cpu_snapshot)); + + if (include_self) + __global_reg_self(tp, regs, this_cpu); smp_fetch_global_regs(); for_each_online_cpu(cpu) { - struct global_reg_snapshot *gp = &global_cpu_snapshot[cpu].reg; + struct global_reg_snapshot *gp; + + if (!include_self && cpu == this_cpu) + continue; + + gp = &global_cpu_snapshot[cpu].reg; __global_reg_poll(gp); @@ -289,7 +298,7 @@ void arch_trigger_all_cpu_backtrace(void) static void sysrq_handle_globreg(int key) { - arch_trigger_all_cpu_backtrace(); + arch_trigger_all_cpu_backtrace(true); } static struct sysrq_key_op sparc_globalreg_op = { @@ -557,6 +566,7 @@ void fault_in_user_windows(void) barf: set_thread_wsaved(window + 1); + user_exit(); do_exit(SIGILL); } diff --git a/arch/sparc/kernel/prom.h b/arch/sparc/kernel/prom.h index cf5fe1c0b02..890281b12b2 100644 --- a/arch/sparc/kernel/prom.h +++ b/arch/sparc/kernel/prom.h @@ -4,7 +4,7 @@ #include <linux/spinlock.h> #include <asm/prom.h> -extern void of_console_init(void); +void of_console_init(void); extern unsigned int prom_early_allocated; diff --git a/arch/sparc/kernel/prom_64.c b/arch/sparc/kernel/prom_64.c index d397d7fc5c2..20cc5d80a47 100644 --- a/arch/sparc/kernel/prom_64.c +++ b/arch/sparc/kernel/prom_64.c @@ -15,11 +15,12 @@ * 2 of the License, or (at your option) any later version. */ +#include <linux/memblock.h> #include <linux/kernel.h> -#include <linux/types.h> #include <linux/string.h> +#include <linux/types.h> +#include <linux/cpu.h> #include <linux/mm.h> -#include <linux/memblock.h> #include <linux/of.h> #include <asm/prom.h> @@ -373,6 +374,59 @@ static const char *get_mid_prop(void) return (tlb_type == spitfire ? "upa-portid" : "portid"); } +bool arch_find_n_match_cpu_physical_id(struct device_node *cpun, + int cpu, unsigned int *thread) +{ + const char *mid_prop = get_mid_prop(); + int this_cpu_id; + + /* On hypervisor based platforms we interrogate the 'reg' + * property. On everything else we look for a 'upa-portis', + * 'portid', or 'cpuid' property. + */ + + if (tlb_type == hypervisor) { + struct property *prop = of_find_property(cpun, "reg", NULL); + u32 *regs; + + if (!prop) { + pr_warn("CPU node missing reg property\n"); + return false; + } + regs = prop->value; + this_cpu_id = regs[0] & 0x0fffffff; + } else { + this_cpu_id = of_getintprop_default(cpun, mid_prop, -1); + + if (this_cpu_id < 0) { + mid_prop = "cpuid"; + this_cpu_id = of_getintprop_default(cpun, mid_prop, -1); + } + if (this_cpu_id < 0) { + pr_warn("CPU node missing cpu ID property\n"); + return false; + } + } + if (this_cpu_id == cpu) { + if (thread) { + int proc_id = cpu_data(cpu).proc_id; + + /* On sparc64, the cpu thread information is obtained + * either from OBP or the machine description. We've + * actually probed this information already long before + * this interface gets called so instead of interrogating + * both the OF node and the MDESC again, just use what + * we discovered already. + */ + if (proc_id < 0) + proc_id = 0; + *thread = proc_id; + } + return true; + } + return false; +} + static void *of_iterate_over_cpus(void *(*func)(struct device_node *, int, int), int arg) { struct device_node *dp; @@ -502,9 +556,6 @@ static void *fill_in_one_cpu(struct device_node *dp, int cpuid, int arg) cpu_data(cpuid).core_id = portid + 1; cpu_data(cpuid).proc_id = portid; -#ifdef CONFIG_SMP - sparc64_multi_core = 1; -#endif } else { cpu_data(cpuid).dcache_size = of_getintprop_default(dp, "dcache-size", 16 * 1024); diff --git a/arch/sparc/kernel/psycho_common.h b/arch/sparc/kernel/psycho_common.h index 590b4ed8ab5..05a6e30a928 100644 --- a/arch/sparc/kernel/psycho_common.h +++ b/arch/sparc/kernel/psycho_common.h @@ -30,19 +30,19 @@ enum psycho_error_type { UE_ERR, CE_ERR, PCI_ERR }; -extern void psycho_check_iommu_error(struct pci_pbm_info *pbm, - unsigned long afsr, - unsigned long afar, - enum psycho_error_type type); +void psycho_check_iommu_error(struct pci_pbm_info *pbm, + unsigned long afsr, + unsigned long afar, + enum psycho_error_type type); -extern irqreturn_t psycho_pcierr_intr(int irq, void *dev_id); +irqreturn_t psycho_pcierr_intr(int irq, void *dev_id); -extern int psycho_iommu_init(struct pci_pbm_info *pbm, int tsbsize, - u32 dvma_offset, u32 dma_mask, - unsigned long write_complete_offset); +int psycho_iommu_init(struct pci_pbm_info *pbm, int tsbsize, + u32 dvma_offset, u32 dma_mask, + unsigned long write_complete_offset); -extern void psycho_pbm_init_common(struct pci_pbm_info *pbm, - struct platform_device *op, - const char *chip_name, int chip_type); +void psycho_pbm_init_common(struct pci_pbm_info *pbm, + struct platform_device *op, + const char *chip_name, int chip_type); #endif /* _PSYCHO_COMMON_H */ diff --git a/arch/sparc/kernel/ptrace_32.c b/arch/sparc/kernel/ptrace_32.c index 896ba7c5cd8..a331fdc11a2 100644 --- a/arch/sparc/kernel/ptrace_32.c +++ b/arch/sparc/kernel/ptrace_32.c @@ -26,6 +26,8 @@ #include <asm/uaccess.h> #include <asm/cacheflush.h> +#include "kernel.h" + /* #define ALLOW_INIT_TRACING */ /* diff --git a/arch/sparc/kernel/ptrace_64.c b/arch/sparc/kernel/ptrace_64.c index 773c1f2983c..c13c9f25d83 100644 --- a/arch/sparc/kernel/ptrace_64.c +++ b/arch/sparc/kernel/ptrace_64.c @@ -27,6 +27,7 @@ #include <trace/syscall.h> #include <linux/compat.h> #include <linux/elf.h> +#include <linux/context_tracking.h> #include <asm/asi.h> #include <asm/pgtable.h> @@ -1066,6 +1067,9 @@ asmlinkage int syscall_trace_enter(struct pt_regs *regs) /* do the secure computing check first */ secure_computing_strict(regs->u_regs[UREG_G1]); + if (test_thread_flag(TIF_NOHZ)) + user_exit(); + if (test_thread_flag(TIF_SYSCALL_TRACE)) ret = tracehook_report_syscall_entry(regs); @@ -1086,6 +1090,9 @@ asmlinkage int syscall_trace_enter(struct pt_regs *regs) asmlinkage void syscall_trace_leave(struct pt_regs *regs) { + if (test_thread_flag(TIF_NOHZ)) + user_exit(); + audit_syscall_exit(regs); if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) @@ -1093,4 +1100,7 @@ asmlinkage void syscall_trace_leave(struct pt_regs *regs) if (test_thread_flag(TIF_SYSCALL_TRACE)) tracehook_report_syscall_exit(regs, 0); + + if (test_thread_flag(TIF_NOHZ)) + user_enter(); } diff --git a/arch/sparc/kernel/rtrap_64.S b/arch/sparc/kernel/rtrap_64.S index afa2a9e3d0a..39f0c662f4c 100644 --- a/arch/sparc/kernel/rtrap_64.S +++ b/arch/sparc/kernel/rtrap_64.S @@ -18,10 +18,16 @@ #define RTRAP_PSTATE_IRQOFF (PSTATE_TSO|PSTATE_PEF|PSTATE_PRIV) #define RTRAP_PSTATE_AG_IRQOFF (PSTATE_TSO|PSTATE_PEF|PSTATE_PRIV|PSTATE_AG) +#ifdef CONFIG_CONTEXT_TRACKING +# define SCHEDULE_USER schedule_user +#else +# define SCHEDULE_USER schedule +#endif + .text .align 32 __handle_preemption: - call schedule + call SCHEDULE_USER wrpr %g0, RTRAP_PSTATE, %pstate ba,pt %xcc, __handle_preemption_continue wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate @@ -306,12 +312,10 @@ to_kernel: nop cmp %l4, 0 bne,pn %xcc, kern_fpucheck - sethi %hi(PREEMPT_ACTIVE), %l6 - stw %l6, [%g6 + TI_PRE_COUNT] - call schedule + nop + call preempt_schedule_irq nop ba,pt %xcc, rtrap - stw %g0, [%g6 + TI_PRE_COUNT] #endif kern_fpucheck: ldub [%g6 + TI_FPDEPTH], %l5 brz,pt %l5, rt_continue diff --git a/arch/sparc/kernel/setup_32.c b/arch/sparc/kernel/setup_32.c index 1434526970a..baef495c06b 100644 --- a/arch/sparc/kernel/setup_32.c +++ b/arch/sparc/kernel/setup_32.c @@ -267,7 +267,7 @@ static __init void leon_patch(void) } struct tt_entry *sparc_ttable; -struct pt_regs fake_swapper_regs; +static struct pt_regs fake_swapper_regs; /* Called from head_32.S - before we have setup anything * in the kernel. Be very careful with what you do here. @@ -365,7 +365,7 @@ void __init setup_arch(char **cmdline_p) prom_setsync(prom_sync_me); - if((boot_flags&BOOTME_DEBUG) && (linux_dbvec!=0) && + if((boot_flags & BOOTME_DEBUG) && (linux_dbvec != NULL) && ((*(short *)linux_dbvec) != -1)) { printk("Booted under KADB. Syncing trap table.\n"); (*(linux_dbvec->teach_debugger))(); diff --git a/arch/sparc/kernel/signal32.c b/arch/sparc/kernel/signal32.c index b524f91dd0e..62deba7be1a 100644 --- a/arch/sparc/kernel/signal32.c +++ b/arch/sparc/kernel/signal32.c @@ -31,6 +31,7 @@ #include <asm/switch_to.h> #include "sigutil.h" +#include "kernel.h" /* This magic should be in g_upper[0] for all upper parts * to be valid. @@ -68,7 +69,7 @@ struct rt_signal_frame32 { /* __siginfo_rwin_t * */u32 rwin_save; } __attribute__((aligned(8))); -int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from) +int copy_siginfo_to_user32(compat_siginfo_t __user *to, const siginfo_t *from) { int err; @@ -145,7 +146,7 @@ void do_sigreturn32(struct pt_regs *regs) unsigned int psr; unsigned pc, npc; sigset_t set; - unsigned seta[_COMPAT_NSIG_WORDS]; + compat_sigset_t seta; int err, i; /* Always make any pending restarted system calls return -EINTR */ @@ -209,17 +210,13 @@ void do_sigreturn32(struct pt_regs *regs) if (restore_rwin_state(compat_ptr(rwin_save))) goto segv; } - err |= __get_user(seta[0], &sf->info.si_mask); - err |= copy_from_user(seta+1, &sf->extramask, + err |= __get_user(seta.sig[0], &sf->info.si_mask); + err |= copy_from_user(&seta.sig[1], &sf->extramask, (_COMPAT_NSIG_WORDS - 1) * sizeof(unsigned int)); if (err) goto segv; - switch (_NSIG_WORDS) { - case 4: set.sig[3] = seta[6] + (((long)seta[7]) << 32); - case 3: set.sig[2] = seta[4] + (((long)seta[5]) << 32); - case 2: set.sig[1] = seta[2] + (((long)seta[3]) << 32); - case 1: set.sig[0] = seta[0] + (((long)seta[1]) << 32); - } + + set.sig[0] = seta.sig[0] + (((long)seta.sig[1]) << 32); set_current_blocked(&set); return; @@ -303,12 +300,7 @@ asmlinkage void do_rt_sigreturn32(struct pt_regs *regs) goto segv; } - switch (_NSIG_WORDS) { - case 4: set.sig[3] = seta.sig[6] + (((long)seta.sig[7]) << 32); - case 3: set.sig[2] = seta.sig[4] + (((long)seta.sig[5]) << 32); - case 2: set.sig[1] = seta.sig[2] + (((long)seta.sig[3]) << 32); - case 1: set.sig[0] = seta.sig[0] + (((long)seta.sig[1]) << 32); - } + set.sig[0] = seta.sig[0] + (((long)seta.sig[1]) << 32); set_current_blocked(&set); return; segv: @@ -417,7 +409,7 @@ static int setup_frame32(struct ksignal *ksig, struct pt_regs *regs, void __user *tail; int sigframe_size; u32 psr; - unsigned int seta[_COMPAT_NSIG_WORDS]; + compat_sigset_t seta; /* 1. Make sure everything is clean */ synchronize_user_stack(); @@ -481,18 +473,14 @@ static int setup_frame32(struct ksignal *ksig, struct pt_regs *regs, err |= __put_user(0, &sf->rwin_save); } - switch (_NSIG_WORDS) { - case 4: seta[7] = (oldset->sig[3] >> 32); - seta[6] = oldset->sig[3]; - case 3: seta[5] = (oldset->sig[2] >> 32); - seta[4] = oldset->sig[2]; - case 2: seta[3] = (oldset->sig[1] >> 32); - seta[2] = oldset->sig[1]; - case 1: seta[1] = (oldset->sig[0] >> 32); - seta[0] = oldset->sig[0]; - } - err |= __put_user(seta[0], &sf->info.si_mask); - err |= __copy_to_user(sf->extramask, seta + 1, + /* If these change we need to know - assignments to seta relies on these sizes */ + BUILD_BUG_ON(_NSIG_WORDS != 1); + BUILD_BUG_ON(_COMPAT_NSIG_WORDS != 2); + seta.sig[1] = (oldset->sig[0] >> 32); + seta.sig[0] = oldset->sig[0]; + + err |= __put_user(seta.sig[0], &sf->info.si_mask); + err |= __copy_to_user(sf->extramask, &seta.sig[1], (_COMPAT_NSIG_WORDS - 1) * sizeof(unsigned int)); if (!wsaved) { @@ -622,16 +610,8 @@ static int setup_rt_frame32(struct ksignal *ksig, struct pt_regs *regs, /* Setup sigaltstack */ err |= __compat_save_altstack(&sf->stack, regs->u_regs[UREG_FP]); - switch (_NSIG_WORDS) { - case 4: seta.sig[7] = (oldset->sig[3] >> 32); - seta.sig[6] = oldset->sig[3]; - case 3: seta.sig[5] = (oldset->sig[2] >> 32); - seta.sig[4] = oldset->sig[2]; - case 2: seta.sig[3] = (oldset->sig[1] >> 32); - seta.sig[2] = oldset->sig[1]; - case 1: seta.sig[1] = (oldset->sig[0] >> 32); - seta.sig[0] = oldset->sig[0]; - } + seta.sig[1] = (oldset->sig[0] >> 32); + seta.sig[0] = oldset->sig[0]; err |= __copy_to_user(&sf->mask, &seta, sizeof(compat_sigset_t)); if (!wsaved) { diff --git a/arch/sparc/kernel/signal_32.c b/arch/sparc/kernel/signal_32.c index 7d5d8e1f841..9ee72fc8e0e 100644 --- a/arch/sparc/kernel/signal_32.c +++ b/arch/sparc/kernel/signal_32.c @@ -28,6 +28,7 @@ #include <asm/switch_to.h> #include "sigutil.h" +#include "kernel.h" extern void fpsave(unsigned long *fpregs, unsigned long *fsr, void *fpqueue, unsigned long *fpqdepth); @@ -341,7 +342,7 @@ static int setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs, err |= __put_user(0, &sf->extra_size); if (psr & PSR_EF) { - __siginfo_fpu_t *fp = tail; + __siginfo_fpu_t __user *fp = tail; tail += sizeof(*fp); err |= save_fpu_state(regs, fp); err |= __put_user(fp, &sf->fpu_save); @@ -349,7 +350,7 @@ static int setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs, err |= __put_user(0, &sf->fpu_save); } if (wsaved) { - __siginfo_rwin_t *rwp = tail; + __siginfo_rwin_t __user *rwp = tail; tail += sizeof(*rwp); err |= save_rwin_state(wsaved, rwp); err |= __put_user(rwp, &sf->rwin_save); @@ -517,9 +518,9 @@ void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, } } -asmlinkage int -do_sys_sigstack(struct sigstack __user *ssptr, struct sigstack __user *ossptr, - unsigned long sp) +asmlinkage int do_sys_sigstack(struct sigstack __user *ssptr, + struct sigstack __user *ossptr, + unsigned long sp) { int ret = -EFAULT; diff --git a/arch/sparc/kernel/signal_64.c b/arch/sparc/kernel/signal_64.c index 35923e8abd8..1a699986803 100644 --- a/arch/sparc/kernel/signal_64.c +++ b/arch/sparc/kernel/signal_64.c @@ -23,6 +23,7 @@ #include <linux/tty.h> #include <linux/binfmts.h> #include <linux/bitops.h> +#include <linux/context_tracking.h> #include <asm/uaccess.h> #include <asm/ptrace.h> @@ -34,15 +35,17 @@ #include <asm/switch_to.h> #include <asm/cacheflush.h> -#include "entry.h" -#include "systbls.h" #include "sigutil.h" +#include "systbls.h" +#include "kernel.h" +#include "entry.h" /* {set, get}context() needed for 64-bit SparcLinux userland. */ asmlinkage void sparc64_set_context(struct pt_regs *regs) { struct ucontext __user *ucp = (struct ucontext __user *) regs->u_regs[UREG_I0]; + enum ctx_state prev_state = exception_enter(); mc_gregset_t __user *grp; unsigned long pc, npc, tstate; unsigned long fp, i7; @@ -129,16 +132,19 @@ asmlinkage void sparc64_set_context(struct pt_regs *regs) } if (err) goto do_sigsegv; - +out: + exception_exit(prev_state); return; do_sigsegv: force_sig(SIGSEGV, current); + goto out; } asmlinkage void sparc64_get_context(struct pt_regs *regs) { struct ucontext __user *ucp = (struct ucontext __user *) regs->u_regs[UREG_I0]; + enum ctx_state prev_state = exception_enter(); mc_gregset_t __user *grp; mcontext_t __user *mcp; unsigned long fp, i7; @@ -220,10 +226,12 @@ asmlinkage void sparc64_get_context(struct pt_regs *regs) } if (err) goto do_sigsegv; - +out: + exception_exit(prev_state); return; do_sigsegv: force_sig(SIGSEGV, current); + goto out; } struct rt_signal_frame { @@ -485,7 +493,6 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) #ifdef CONFIG_COMPAT if (test_thread_flag(TIF_32BIT)) { - extern void do_signal32(struct pt_regs *); do_signal32(regs); return; } @@ -528,11 +535,13 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, unsigned long thread_info_flags) { + user_exit(); if (thread_info_flags & _TIF_SIGPENDING) do_signal(regs, orig_i0); if (thread_info_flags & _TIF_NOTIFY_RESUME) { clear_thread_flag(TIF_NOTIFY_RESUME); tracehook_notify_resume(regs); } + user_enter(); } diff --git a/arch/sparc/kernel/smp_32.c b/arch/sparc/kernel/smp_32.c index a102bfba6ea..7958242d63c 100644 --- a/arch/sparc/kernel/smp_32.c +++ b/arch/sparc/kernel/smp_32.c @@ -20,6 +20,7 @@ #include <linux/seq_file.h> #include <linux/cache.h> #include <linux/delay.h> +#include <linux/profile.h> #include <linux/cpu.h> #include <asm/ptrace.h> @@ -75,8 +76,6 @@ void smp_store_cpu_info(int id) void __init smp_cpus_done(unsigned int max_cpus) { - extern void smp4m_smp_done(void); - extern void smp4d_smp_done(void); unsigned long bogosum = 0; int cpu, num = 0; @@ -183,8 +182,6 @@ int setup_profiling_timer(unsigned int multiplier) void __init smp_prepare_cpus(unsigned int max_cpus) { - extern void __init smp4m_boot_cpus(void); - extern void __init smp4d_boot_cpus(void); int i, cpuid, extra; printk("Entering SMP Mode...\n"); @@ -261,8 +258,6 @@ void __init smp_prepare_boot_cpu(void) int __cpu_up(unsigned int cpu, struct task_struct *tidle) { - extern int smp4m_boot_one_cpu(int, struct task_struct *); - extern int smp4d_boot_one_cpu(int, struct task_struct *); int ret=0; switch(sparc_cpu_model) { @@ -297,7 +292,7 @@ int __cpu_up(unsigned int cpu, struct task_struct *tidle) return ret; } -void arch_cpu_pre_starting(void *arg) +static void arch_cpu_pre_starting(void *arg) { local_ops->cache_all(); local_ops->tlb_all(); @@ -317,7 +312,7 @@ void arch_cpu_pre_starting(void *arg) } } -void arch_cpu_pre_online(void *arg) +static void arch_cpu_pre_online(void *arg) { unsigned int cpuid = hard_smp_processor_id(); @@ -344,7 +339,7 @@ void arch_cpu_pre_online(void *arg) } } -void sparc_start_secondary(void *arg) +static void sparc_start_secondary(void *arg) { unsigned int cpu; diff --git a/arch/sparc/kernel/smp_64.c b/arch/sparc/kernel/smp_64.c index e142545244f..41aa2478f3c 100644 --- a/arch/sparc/kernel/smp_64.c +++ b/arch/sparc/kernel/smp_64.c @@ -25,6 +25,7 @@ #include <linux/ftrace.h> #include <linux/cpu.h> #include <linux/slab.h> +#include <linux/kgdb.h> #include <asm/head.h> #include <asm/ptrace.h> @@ -35,6 +36,7 @@ #include <asm/hvtramp.h> #include <asm/io.h> #include <asm/timer.h> +#include <asm/setup.h> #include <asm/irq.h> #include <asm/irq_regs.h> @@ -52,8 +54,7 @@ #include <asm/pcr.h> #include "cpumap.h" - -int sparc64_multi_core __read_mostly; +#include "kernel.h" DEFINE_PER_CPU(cpumask_t, cpu_sibling_map) = CPU_MASK_NONE; cpumask_t cpu_core_map[NR_CPUS] __read_mostly = @@ -123,11 +124,12 @@ void smp_callin(void) rmb(); set_cpu_online(cpuid, true); - local_irq_enable(); /* idle thread is expected to have preempt disabled */ preempt_disable(); + local_irq_enable(); + cpu_startup_entry(CPUHP_ONLINE); } @@ -150,7 +152,7 @@ void cpu_panic(void) #define NUM_ROUNDS 64 /* magic value */ #define NUM_ITERS 5 /* likewise */ -static DEFINE_SPINLOCK(itc_sync_lock); +static DEFINE_RAW_SPINLOCK(itc_sync_lock); static unsigned long go[SLAVE + 1]; #define DEBUG_TICK_SYNC 0 @@ -258,7 +260,7 @@ static void smp_synchronize_one_tick(int cpu) go[MASTER] = 0; membar_safe("#StoreLoad"); - spin_lock_irqsave(&itc_sync_lock, flags); + raw_spin_lock_irqsave(&itc_sync_lock, flags); { for (i = 0; i < NUM_ROUNDS*NUM_ITERS; i++) { while (!go[MASTER]) @@ -269,18 +271,10 @@ static void smp_synchronize_one_tick(int cpu) membar_safe("#StoreLoad"); } } - spin_unlock_irqrestore(&itc_sync_lock, flags); + raw_spin_unlock_irqrestore(&itc_sync_lock, flags); } #if defined(CONFIG_SUN_LDOMS) && defined(CONFIG_HOTPLUG_CPU) -/* XXX Put this in some common place. XXX */ -static unsigned long kimage_addr_to_ra(void *p) -{ - unsigned long val = (unsigned long) p; - - return kern_base + (val - KERNBASE); -} - static void ldom_startcpu_cpuid(unsigned int cpu, unsigned long thread_reg, void **descrp) { @@ -868,11 +862,6 @@ extern unsigned long xcall_flush_dcache_page_cheetah; #endif extern unsigned long xcall_flush_dcache_page_spitfire; -#ifdef CONFIG_DEBUG_DCFLUSH -extern atomic_t dcpage_flushes; -extern atomic_t dcpage_flushes_xcall; -#endif - static inline void __local_flush_dcache_page(struct page *page) { #ifdef DCACHE_ALIASING_POSSIBLE @@ -1399,8 +1388,13 @@ void __init smp_cpus_done(unsigned int max_cpus) void smp_send_reschedule(int cpu) { - xcall_deliver((u64) &xcall_receive_signal, 0, 0, - cpumask_of(cpu)); + if (cpu == smp_processor_id()) { + WARN_ON_ONCE(preemptible()); + set_softint(1 << PIL_SMP_RECEIVE_SIGNAL); + } else { + xcall_deliver((u64) &xcall_receive_signal, + 0, 0, cpumask_of(cpu)); + } } void __irq_entry smp_receive_signal_client(int irq, struct pt_regs *regs) diff --git a/arch/sparc/kernel/sparc_ksyms_32.c b/arch/sparc/kernel/sparc_ksyms_32.c index e521c54560f..bf4ccb10a78 100644 --- a/arch/sparc/kernel/sparc_ksyms_32.c +++ b/arch/sparc/kernel/sparc_ksyms_32.c @@ -6,7 +6,6 @@ */ #include <linux/module.h> -#include <linux/init.h> #include <asm/pgtable.h> #include <asm/uaccess.h> diff --git a/arch/sparc/kernel/sparc_ksyms_64.c b/arch/sparc/kernel/sparc_ksyms_64.c index 9f5e24ddcc7..a92d5d2c46a 100644 --- a/arch/sparc/kernel/sparc_ksyms_64.c +++ b/arch/sparc/kernel/sparc_ksyms_64.c @@ -7,7 +7,6 @@ #include <linux/export.h> #include <linux/pci.h> -#include <linux/init.h> #include <linux/bitops.h> #include <asm/cpudata.h> diff --git a/arch/sparc/kernel/sun4d_irq.c b/arch/sparc/kernel/sun4d_irq.c index f8933be3ca8..a1bb2675b28 100644 --- a/arch/sparc/kernel/sun4d_irq.c +++ b/arch/sparc/kernel/sun4d_irq.c @@ -143,7 +143,7 @@ static void sun4d_sbus_handler_irq(int sbusl) } } -void sun4d_handler_irq(int pil, struct pt_regs *regs) +void sun4d_handler_irq(unsigned int pil, struct pt_regs *regs) { struct pt_regs *old_regs; /* SBUS IRQ level (1 - 7) */ @@ -236,7 +236,7 @@ static void sun4d_shutdown_irq(struct irq_data *data) irq_unlink(data->irq); } -struct irq_chip sun4d_irq = { +static struct irq_chip sun4d_irq = { .name = "sun4d", .irq_startup = sun4d_startup_irq, .irq_shutdown = sun4d_shutdown_irq, @@ -285,9 +285,9 @@ static void __init sun4d_load_profile_irqs(void) } } -unsigned int _sun4d_build_device_irq(unsigned int real_irq, - unsigned int pil, - unsigned int board) +static unsigned int _sun4d_build_device_irq(unsigned int real_irq, + unsigned int pil, + unsigned int board) { struct sun4d_handler_data *handler_data; unsigned int irq; @@ -320,8 +320,8 @@ err_out: -unsigned int sun4d_build_device_irq(struct platform_device *op, - unsigned int real_irq) +static unsigned int sun4d_build_device_irq(struct platform_device *op, + unsigned int real_irq) { struct device_node *dp = op->dev.of_node; struct device_node *board_parent, *bus = dp->parent; @@ -383,7 +383,8 @@ err_out: return irq; } -unsigned int sun4d_build_timer_irq(unsigned int board, unsigned int real_irq) +static unsigned int sun4d_build_timer_irq(unsigned int board, + unsigned int real_irq) { return _sun4d_build_device_irq(real_irq, real_irq, board); } diff --git a/arch/sparc/kernel/sun4m_irq.c b/arch/sparc/kernel/sun4m_irq.c index c5ade9d27a1..8bb3b3fddea 100644 --- a/arch/sparc/kernel/sun4m_irq.c +++ b/arch/sparc/kernel/sun4m_irq.c @@ -9,6 +9,8 @@ * Copyright (C) 1996 Dave Redman (djhr@tadpole.co.uk) */ +#include <linux/slab.h> + #include <asm/timer.h> #include <asm/traps.h> #include <asm/pgalloc.h> diff --git a/arch/sparc/kernel/sun4v_tlb_miss.S b/arch/sparc/kernel/sun4v_tlb_miss.S index bde867fd71e..e0c09bf8561 100644 --- a/arch/sparc/kernel/sun4v_tlb_miss.S +++ b/arch/sparc/kernel/sun4v_tlb_miss.S @@ -182,7 +182,7 @@ sun4v_tsb_miss_common: cmp %g5, -1 be,pt %xcc, 80f nop - COMPUTE_TSB_PTR(%g5, %g4, HPAGE_SHIFT, %g2, %g7) + COMPUTE_TSB_PTR(%g5, %g4, REAL_HPAGE_SHIFT, %g2, %g7) /* That clobbered %g2, reload it. */ ldxa [%g0] ASI_SCRATCHPAD, %g2 diff --git a/arch/sparc/kernel/sys32.S b/arch/sparc/kernel/sys32.S index f7c72b6efc2..f834224208e 100644 --- a/arch/sparc/kernel/sys32.S +++ b/arch/sparc/kernel/sys32.S @@ -44,10 +44,11 @@ SIGN1(sys32_timer_settime, compat_sys_timer_settime, %o1) SIGN1(sys32_io_submit, compat_sys_io_submit, %o1) SIGN1(sys32_mq_open, compat_sys_mq_open, %o1) SIGN1(sys32_select, compat_sys_select, %o0) -SIGN3(sys32_futex, compat_sys_futex, %o1, %o2, %o5) +SIGN1(sys32_futex, compat_sys_futex, %o1) SIGN1(sys32_recvfrom, compat_sys_recvfrom, %o0) SIGN1(sys32_recvmsg, compat_sys_recvmsg, %o0) SIGN1(sys32_sendmsg, compat_sys_sendmsg, %o0) +SIGN2(sys32_renameat2, sys_renameat2, %o0, %o2) .globl sys32_mmap2 sys32_mmap2: diff --git a/arch/sparc/kernel/sys_sparc32.c b/arch/sparc/kernel/sys_sparc32.c index 71368850dfc..022c30c72eb 100644 --- a/arch/sparc/kernel/sys_sparc32.c +++ b/arch/sparc/kernel/sys_sparc32.c @@ -49,6 +49,8 @@ #include <asm/mmu_context.h> #include <asm/compat_signal.h> +#include "systbls.h" + asmlinkage long sys32_truncate64(const char __user * path, unsigned long high, unsigned long low) { if ((int)high < 0) diff --git a/arch/sparc/kernel/sys_sparc_32.c b/arch/sparc/kernel/sys_sparc_32.c index 3a8d1844402..646988d4c1a 100644 --- a/arch/sparc/kernel/sys_sparc_32.c +++ b/arch/sparc/kernel/sys_sparc_32.c @@ -24,6 +24,8 @@ #include <asm/uaccess.h> #include <asm/unistd.h> +#include "systbls.h" + /* #define DEBUG_UNIMP_SYSCALL */ /* XXX Make this per-binary type, this way we can detect the type of @@ -68,7 +70,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi * sys_pipe() is the normal C calling standard for creating * a pipe. It's not the way unix traditionally does this, though. */ -asmlinkage int sparc_pipe(struct pt_regs *regs) +asmlinkage long sparc_pipe(struct pt_regs *regs) { int fd[2]; int error; @@ -93,7 +95,7 @@ int sparc_mmap_check(unsigned long addr, unsigned long len) /* Linux version of mmap */ -asmlinkage unsigned long sys_mmap2(unsigned long addr, unsigned long len, +asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, unsigned long fd, unsigned long pgoff) { @@ -103,7 +105,7 @@ asmlinkage unsigned long sys_mmap2(unsigned long addr, unsigned long len, pgoff >> (PAGE_SHIFT - 12)); } -asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len, +asmlinkage long sys_mmap(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, unsigned long fd, unsigned long off) { @@ -197,7 +199,7 @@ SYSCALL_DEFINE5(rt_sigaction, int, sig, return ret; } -asmlinkage int sys_getdomainname(char __user *name, int len) +asmlinkage long sys_getdomainname(char __user *name, int len) { int nlen, err; diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c index 51561b8b15b..c85403d0496 100644 --- a/arch/sparc/kernel/sys_sparc_64.c +++ b/arch/sparc/kernel/sys_sparc_64.c @@ -24,12 +24,14 @@ #include <linux/personality.h> #include <linux/random.h> #include <linux/export.h> +#include <linux/context_tracking.h> #include <asm/uaccess.h> #include <asm/utrap.h> #include <asm/unistd.h> #include "entry.h" +#include "kernel.h" #include "systbls.h" /* #define DEBUG_UNIMP_SYSCALL */ @@ -39,9 +41,6 @@ asmlinkage unsigned long sys_getpagesize(void) return PAGE_SIZE; } -#define VA_EXCLUDE_START (0x0000080000000000UL - (1UL << 32UL)) -#define VA_EXCLUDE_END (0xfffff80000000000UL + (1UL << 32UL)) - /* Does addr --> addr+len fall within 4GB of the VA-space hole or * overflow past the end of the 64-bit address space? */ @@ -499,6 +498,7 @@ asmlinkage unsigned long c_sys_nis_syscall(struct pt_regs *regs) asmlinkage void sparc_breakpoint(struct pt_regs *regs) { + enum ctx_state prev_state = exception_enter(); siginfo_t info; if (test_thread_flag(TIF_32BIT)) { @@ -517,6 +517,7 @@ asmlinkage void sparc_breakpoint(struct pt_regs *regs) #ifdef DEBUG_SPARC_BREAKPOINT printk ("TRAP: Returning to space: PC=%lx nPC=%lx\n", regs->tpc, regs->tnpc); #endif + exception_exit(prev_state); } extern void check_pending(int signum); diff --git a/arch/sparc/kernel/syscalls.S b/arch/sparc/kernel/syscalls.S index d950197a17e..33a17e7b3cc 100644 --- a/arch/sparc/kernel/syscalls.S +++ b/arch/sparc/kernel/syscalls.S @@ -52,7 +52,7 @@ sys32_rt_sigreturn: #endif .align 32 1: ldx [%g6 + TI_FLAGS], %l5 - andcc %l5, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), %g0 + andcc %l5, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT|_TIF_NOHZ), %g0 be,pt %icc, rtrap nop call syscall_trace_leave @@ -184,12 +184,13 @@ linux_sparc_syscall32: srl %i3, 0, %o3 ! IEU0 srl %i2, 0, %o2 ! IEU0 Group - andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), %g0 + andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT|_TIF_NOHZ), %g0 bne,pn %icc, linux_syscall_trace32 ! CTI mov %i0, %l5 ! IEU1 5: call %l7 ! CTI Group brk forced srl %i5, 0, %o5 ! IEU1 - ba,a,pt %xcc, 3f + ba,pt %xcc, 3f + sra %o0, 0, %o0 /* Linux native system calls enter here... */ .align 32 @@ -207,7 +208,7 @@ linux_sparc_syscall: mov %i3, %o3 ! IEU1 mov %i4, %o4 ! IEU0 Group - andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), %g0 + andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT|_TIF_NOHZ), %g0 bne,pn %icc, linux_syscall_trace ! CTI Group mov %i0, %l5 ! IEU0 2: call %l7 ! CTI Group brk forced @@ -217,13 +218,12 @@ linux_sparc_syscall: 3: stx %o0, [%sp + PTREGS_OFF + PT_V9_I0] ret_sys_call: ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %g3 - sra %o0, 0, %o0 mov %ulo(TSTATE_XCARRY | TSTATE_ICARRY), %g2 sllx %g2, 32, %g2 cmp %o0, -ERESTART_RESTARTBLOCK bgeu,pn %xcc, 1f - andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), %g0 + andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT|_TIF_NOHZ), %g0 ldx [%sp + PTREGS_OFF + PT_V9_TNPC], %l1 ! pc = npc 2: diff --git a/arch/sparc/kernel/sysfs.c b/arch/sparc/kernel/sysfs.c index c21c673e5f7..7f41d40b7e6 100644 --- a/arch/sparc/kernel/sysfs.c +++ b/arch/sparc/kernel/sysfs.c @@ -151,7 +151,7 @@ static ssize_t store_mmustat_enable(struct device *s, size_t count) { unsigned long val, err; - int ret = sscanf(buf, "%ld", &val); + int ret = sscanf(buf, "%lu", &val); if (ret != 1) return -EINVAL; @@ -300,7 +300,7 @@ static int __init topology_init(void) check_mmu_stats(); - register_cpu_notifier(&sysfs_cpu_nb); + cpu_notifier_register_begin(); for_each_possible_cpu(cpu) { struct cpu *c = &per_cpu(cpu_devices, cpu); @@ -310,6 +310,10 @@ static int __init topology_init(void) register_cpu_online(cpu); } + __register_cpu_notifier(&sysfs_cpu_nb); + + cpu_notifier_register_done(); + return 0; } diff --git a/arch/sparc/kernel/systbls.h b/arch/sparc/kernel/systbls.h index 26e6dd72e92..2dab8236d49 100644 --- a/arch/sparc/kernel/systbls.h +++ b/arch/sparc/kernel/systbls.h @@ -1,41 +1,103 @@ #ifndef _SYSTBLS_H #define _SYSTBLS_H +#include <linux/signal.h> #include <linux/kernel.h> +#include <linux/compat.h> #include <linux/types.h> -#include <linux/signal.h> + #include <asm/utrap.h> -extern asmlinkage unsigned long sys_getpagesize(void); -extern asmlinkage long sparc_pipe(struct pt_regs *regs); -extern asmlinkage long sys_sparc_ipc(unsigned int call, int first, - unsigned long second, - unsigned long third, - void __user *ptr, long fifth); -extern asmlinkage long sparc64_personality(unsigned long personality); -extern asmlinkage long sys64_munmap(unsigned long addr, size_t len); -extern asmlinkage unsigned long sys64_mremap(unsigned long addr, - unsigned long old_len, - unsigned long new_len, - unsigned long flags, - unsigned long new_addr); -extern asmlinkage unsigned long c_sys_nis_syscall(struct pt_regs *regs); -extern asmlinkage long sys_getdomainname(char __user *name, int len); -extern asmlinkage long sys_utrap_install(utrap_entry_t type, - utrap_handler_t new_p, - utrap_handler_t new_d, - utrap_handler_t __user *old_p, - utrap_handler_t __user *old_d); -extern asmlinkage long sparc_memory_ordering(unsigned long model, - struct pt_regs *regs); -extern asmlinkage long sys_rt_sigaction(int sig, - const struct sigaction __user *act, - struct sigaction __user *oact, - void __user *restorer, - size_t sigsetsize); +asmlinkage unsigned long sys_getpagesize(void); +asmlinkage long sparc_pipe(struct pt_regs *regs); +asmlinkage unsigned long c_sys_nis_syscall(struct pt_regs *regs); +asmlinkage long sys_getdomainname(char __user *name, int len); +void do_rt_sigreturn(struct pt_regs *regs); +asmlinkage long sys_mmap(unsigned long addr, unsigned long len, + unsigned long prot, unsigned long flags, + unsigned long fd, unsigned long off); +asmlinkage void sparc_breakpoint(struct pt_regs *regs); + +#ifdef CONFIG_SPARC32 +asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, + unsigned long prot, unsigned long flags, + unsigned long fd, unsigned long pgoff); +long sparc_remap_file_pages(unsigned long start, unsigned long size, + unsigned long prot, unsigned long pgoff, + unsigned long flags); -extern asmlinkage void sparc64_set_context(struct pt_regs *regs); -extern asmlinkage void sparc64_get_context(struct pt_regs *regs); -extern void do_rt_sigreturn(struct pt_regs *regs); +#endif /* CONFIG_SPARC32 */ +#ifdef CONFIG_SPARC64 +asmlinkage long sys_sparc_ipc(unsigned int call, int first, + unsigned long second, + unsigned long third, + void __user *ptr, long fifth); +asmlinkage long sparc64_personality(unsigned long personality); +asmlinkage long sys64_munmap(unsigned long addr, size_t len); +asmlinkage unsigned long sys64_mremap(unsigned long addr, + unsigned long old_len, + unsigned long new_len, + unsigned long flags, + unsigned long new_addr); +asmlinkage long sys_utrap_install(utrap_entry_t type, + utrap_handler_t new_p, + utrap_handler_t new_d, + utrap_handler_t __user *old_p, + utrap_handler_t __user *old_d); +asmlinkage long sparc_memory_ordering(unsigned long model, + struct pt_regs *regs); +asmlinkage void sparc64_set_context(struct pt_regs *regs); +asmlinkage void sparc64_get_context(struct pt_regs *regs); +asmlinkage long sys32_truncate64(const char __user * path, + unsigned long high, + unsigned long low); +asmlinkage long sys32_ftruncate64(unsigned int fd, + unsigned long high, + unsigned long low); +struct compat_stat64; +asmlinkage long compat_sys_stat64(const char __user * filename, + struct compat_stat64 __user *statbuf); +asmlinkage long compat_sys_lstat64(const char __user * filename, + struct compat_stat64 __user *statbuf); +asmlinkage long compat_sys_fstat64(unsigned int fd, + struct compat_stat64 __user * statbuf); +asmlinkage long compat_sys_fstatat64(unsigned int dfd, + const char __user *filename, + struct compat_stat64 __user * statbuf, int flag); +asmlinkage compat_ssize_t sys32_pread64(unsigned int fd, + char __user *ubuf, + compat_size_t count, + unsigned long poshi, + unsigned long poslo); +asmlinkage compat_ssize_t sys32_pwrite64(unsigned int fd, + char __user *ubuf, + compat_size_t count, + unsigned long poshi, + unsigned long poslo); +asmlinkage long compat_sys_readahead(int fd, + unsigned long offhi, + unsigned long offlo, + compat_size_t count); +long compat_sys_fadvise64(int fd, + unsigned long offhi, + unsigned long offlo, + compat_size_t len, int advice); +long compat_sys_fadvise64_64(int fd, + unsigned long offhi, unsigned long offlo, + unsigned long lenhi, unsigned long lenlo, + int advice); +long sys32_sync_file_range(unsigned int fd, + unsigned long off_high, unsigned long off_low, + unsigned long nb_high, unsigned long nb_low, + unsigned int flags); +asmlinkage long compat_sys_fallocate(int fd, int mode, u32 offhi, u32 offlo, + u32 lenhi, u32 lenlo); +asmlinkage long compat_sys_fstat64(unsigned int fd, + struct compat_stat64 __user * statbuf); +asmlinkage long compat_sys_fstatat64(unsigned int dfd, + const char __user *filename, + struct compat_stat64 __user * statbuf, + int flag); +#endif /* CONFIG_SPARC64 */ #endif /* _SYSTBLS_H */ diff --git a/arch/sparc/kernel/systbls_32.S b/arch/sparc/kernel/systbls_32.S index 7b87171ecf1..85fe9b1087c 100644 --- a/arch/sparc/kernel/systbls_32.S +++ b/arch/sparc/kernel/systbls_32.S @@ -85,4 +85,5 @@ sys_call_table: /*325*/ .long sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init /*330*/ .long sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime /*335*/ .long sys_syncfs, sys_sendmmsg, sys_setns, sys_process_vm_readv, sys_process_vm_writev -/*340*/ .long sys_ni_syscall, sys_kcmp, sys_finit_module +/*340*/ .long sys_ni_syscall, sys_kcmp, sys_finit_module, sys_sched_setattr, sys_sched_getattr +/*345*/ .long sys_renameat2 diff --git a/arch/sparc/kernel/systbls_64.S b/arch/sparc/kernel/systbls_64.S index 6d81597064b..33ecba2826e 100644 --- a/arch/sparc/kernel/systbls_64.S +++ b/arch/sparc/kernel/systbls_64.S @@ -86,7 +86,8 @@ sys_call_table32: .word compat_sys_pwritev, compat_sys_rt_tgsigqueueinfo, sys_perf_event_open, compat_sys_recvmmsg, sys_fanotify_init /*330*/ .word compat_sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, compat_sys_open_by_handle_at, compat_sys_clock_adjtime .word sys_syncfs, compat_sys_sendmmsg, sys_setns, compat_sys_process_vm_readv, compat_sys_process_vm_writev -/*340*/ .word sys_kern_features, sys_kcmp, sys_finit_module +/*340*/ .word sys_kern_features, sys_kcmp, sys_finit_module, sys_sched_setattr, sys_sched_getattr + .word sys32_renameat2 #endif /* CONFIG_COMPAT */ @@ -164,4 +165,5 @@ sys_call_table: .word sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init /*330*/ .word sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime .word sys_syncfs, sys_sendmmsg, sys_setns, sys_process_vm_readv, sys_process_vm_writev -/*340*/ .word sys_kern_features, sys_kcmp, sys_finit_module +/*340*/ .word sys_kern_features, sys_kcmp, sys_finit_module, sys_sched_setattr, sys_sched_getattr + .word sys_renameat2 diff --git a/arch/sparc/kernel/tadpole.c b/arch/sparc/kernel/tadpole.c deleted file mode 100644 index 9aba8bd5a78..00000000000 --- a/arch/sparc/kernel/tadpole.c +++ /dev/null @@ -1,126 +0,0 @@ -/* tadpole.c: Probing for the tadpole clock stopping h/w at boot time. - * - * Copyright (C) 1996 David Redman (djhr@tadpole.co.uk) - */ - -#include <linux/string.h> -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/init.h> - -#include <asm/asi.h> -#include <asm/oplib.h> -#include <asm/io.h> - -#define MACIO_SCSI_CSR_ADDR 0x78400000 -#define MACIO_EN_DMA 0x00000200 -#define CLOCK_INIT_DONE 1 - -static int clk_state; -static volatile unsigned char *clk_ctrl; -void (*cpu_pwr_save)(void); - -static inline unsigned int ldphys(unsigned int addr) -{ - unsigned long data; - - __asm__ __volatile__("\n\tlda [%1] %2, %0\n\t" : - "=r" (data) : - "r" (addr), "i" (ASI_M_BYPASS)); - return data; -} - -static void clk_init(void) -{ - __asm__ __volatile__("mov 0x6c, %%g1\n\t" - "mov 0x4c, %%g2\n\t" - "mov 0xdf, %%g3\n\t" - "stb %%g1, [%0+3]\n\t" - "stb %%g2, [%0+3]\n\t" - "stb %%g3, [%0+3]\n\t" : : - "r" (clk_ctrl) : - "g1", "g2", "g3"); -} - -static void clk_slow(void) -{ - __asm__ __volatile__("mov 0xcc, %%g2\n\t" - "mov 0x4c, %%g3\n\t" - "mov 0xcf, %%g4\n\t" - "mov 0xdf, %%g5\n\t" - "stb %%g2, [%0+3]\n\t" - "stb %%g3, [%0+3]\n\t" - "stb %%g4, [%0+3]\n\t" - "stb %%g5, [%0+3]\n\t" : : - "r" (clk_ctrl) : - "g2", "g3", "g4", "g5"); -} - -/* - * Tadpole is guaranteed to be UP, using local_irq_save. - */ -static void tsu_clockstop(void) -{ - unsigned int mcsr; - unsigned long flags; - - if (!clk_ctrl) - return; - if (!(clk_state & CLOCK_INIT_DONE)) { - local_irq_save(flags); - clk_init(); - clk_state |= CLOCK_INIT_DONE; /* all done */ - local_irq_restore(flags); - return; - } - if (!(clk_ctrl[2] & 1)) - return; /* no speed up yet */ - - local_irq_save(flags); - - /* if SCSI DMA in progress, don't slow clock */ - mcsr = ldphys(MACIO_SCSI_CSR_ADDR); - if ((mcsr&MACIO_EN_DMA) != 0) { - local_irq_restore(flags); - return; - } - /* TODO... the minimum clock setting ought to increase the - * memory refresh interval.. - */ - clk_slow(); - local_irq_restore(flags); -} - -static void swift_clockstop(void) -{ - if (!clk_ctrl) - return; - clk_ctrl[0] = 0; -} - -void __init clock_stop_probe(void) -{ - phandle node, clk_nd; - char name[20]; - - prom_getstring(prom_root_node, "name", name, sizeof(name)); - if (strncmp(name, "Tadpole", 7)) - return; - node = prom_getchild(prom_root_node); - node = prom_searchsiblings(node, "obio"); - node = prom_getchild(node); - clk_nd = prom_searchsiblings(node, "clk-ctrl"); - if (!clk_nd) - return; - printk("Clock Stopping h/w detected... "); - clk_ctrl = (char *) prom_getint(clk_nd, "address"); - clk_state = 0; - if (name[10] == '\0') { - cpu_pwr_save = tsu_clockstop; - printk("enabled (S3)\n"); - } else if ((name[10] == 'X') || (name[10] == 'G')) { - cpu_pwr_save = swift_clockstop; - printk("enabled (%s)\n",name+7); - } else - printk("disabled %s\n",name+7); -} diff --git a/arch/sparc/kernel/time_32.c b/arch/sparc/kernel/time_32.c index c4c27b0f906..5923d1e4e7c 100644 --- a/arch/sparc/kernel/time_32.c +++ b/arch/sparc/kernel/time_32.c @@ -36,6 +36,7 @@ #include <linux/of_device.h> #include <linux/platform_device.h> +#include <asm/mc146818rtc.h> #include <asm/oplib.h> #include <asm/timex.h> #include <asm/timer.h> @@ -47,6 +48,7 @@ #include <asm/irq_regs.h> #include <asm/setup.h> +#include "kernel.h" #include "irq.h" static __cacheline_aligned_in_smp DEFINE_SEQLOCK(timer_cs_lock); @@ -83,7 +85,7 @@ unsigned long profile_pc(struct pt_regs *regs) EXPORT_SYMBOL(profile_pc); -__volatile__ unsigned int *master_l10_counter; +volatile u32 __iomem *master_l10_counter; int update_persistent_clock(struct timespec now) { @@ -143,9 +145,9 @@ static __init void setup_timer_ce(void) static unsigned int sbus_cycles_offset(void) { - unsigned int val, offset; + u32 val, offset; - val = *master_l10_counter; + val = sbus_readl(master_l10_counter); offset = (val >> TIMER_VALUE_SHIFT) & TIMER_VALUE_MASK; /* Limit hit? */ diff --git a/arch/sparc/kernel/time_64.c b/arch/sparc/kernel/time_64.c index c3d82b5f54c..3fddf64c7fc 100644 --- a/arch/sparc/kernel/time_64.c +++ b/arch/sparc/kernel/time_64.c @@ -659,8 +659,7 @@ static int sparc64_cpufreq_notifier(struct notifier_block *nb, unsigned long val ft->clock_tick_ref = cpu_data(cpu).clock_tick; } if ((val == CPUFREQ_PRECHANGE && freq->old < freq->new) || - (val == CPUFREQ_POSTCHANGE && freq->old > freq->new) || - (val == CPUFREQ_RESUMECHANGE)) { + (val == CPUFREQ_POSTCHANGE && freq->old > freq->new)) { cpu_data(cpu).clock_tick = cpufreq_scale(ft->clock_tick_ref, ft->ref_freq, @@ -733,7 +732,7 @@ void __irq_entry timer_interrupt(int irq, struct pt_regs *regs) irq_enter(); local_cpu_data().irq0_irqs++; - kstat_incr_irqs_this_cpu(0, irq_to_desc(0)); + kstat_incr_irq_this_cpu(0); if (unlikely(!evt->event_handler)) { printk(KERN_WARNING diff --git a/arch/sparc/kernel/trampoline_32.S b/arch/sparc/kernel/trampoline_32.S index 76dcbd3c988..3eed99fc698 100644 --- a/arch/sparc/kernel/trampoline_32.S +++ b/arch/sparc/kernel/trampoline_32.S @@ -5,7 +5,6 @@ * Copyright (C) 1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) */ -#include <linux/init.h> #include <asm/head.h> #include <asm/psr.h> #include <asm/page.h> diff --git a/arch/sparc/kernel/trampoline_64.S b/arch/sparc/kernel/trampoline_64.S index ad4bde3bb61..737f8cbc7d5 100644 --- a/arch/sparc/kernel/trampoline_64.S +++ b/arch/sparc/kernel/trampoline_64.S @@ -4,7 +4,6 @@ * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) */ -#include <linux/init.h> #include <asm/head.h> #include <asm/asi.h> diff --git a/arch/sparc/kernel/traps_32.c b/arch/sparc/kernel/traps_32.c index 662982946a8..6fd386c5232 100644 --- a/arch/sparc/kernel/traps_32.c +++ b/arch/sparc/kernel/traps_32.c @@ -44,7 +44,7 @@ static void instruction_dump(unsigned long *pc) #define __SAVE __asm__ __volatile__("save %sp, -0x40, %sp\n\t") #define __RESTORE __asm__ __volatile__("restore %g0, %g0, %g0\n\t") -void die_if_kernel(char *str, struct pt_regs *regs) +void __noreturn die_if_kernel(char *str, struct pt_regs *regs) { static int die_counter; int count = 0; @@ -219,8 +219,6 @@ static unsigned long fake_fsr; static unsigned long fake_queue[32] __attribute__ ((aligned (8))); static unsigned long fake_depth; -extern int do_mathemu(struct pt_regs *, struct task_struct *); - void do_fpe_trap(struct pt_regs *regs, unsigned long pc, unsigned long npc, unsigned long psr) { diff --git a/arch/sparc/kernel/traps_64.c b/arch/sparc/kernel/traps_64.c index b3f833ab90e..fb6640ec855 100644 --- a/arch/sparc/kernel/traps_64.c +++ b/arch/sparc/kernel/traps_64.c @@ -20,6 +20,7 @@ #include <linux/ftrace.h> #include <linux/reboot.h> #include <linux/gfp.h> +#include <linux/context_tracking.h> #include <asm/smp.h> #include <asm/delay.h> @@ -42,8 +43,10 @@ #include <asm/prom.h> #include <asm/memctrl.h> #include <asm/cacheflush.h> +#include <asm/setup.h> #include "entry.h" +#include "kernel.h" #include "kstack.h" /* When an irrecoverable trap occurs at tl > 0, the trap entry @@ -186,11 +189,12 @@ EXPORT_SYMBOL_GPL(unregister_dimm_printer); void spitfire_insn_access_exception(struct pt_regs *regs, unsigned long sfsr, unsigned long sfar) { + enum ctx_state prev_state = exception_enter(); siginfo_t info; if (notify_die(DIE_TRAP, "instruction access exception", regs, 0, 0x8, SIGTRAP) == NOTIFY_STOP) - return; + goto out; if (regs->tstate & TSTATE_PRIV) { printk("spitfire_insn_access_exception: SFSR[%016lx] " @@ -207,6 +211,8 @@ void spitfire_insn_access_exception(struct pt_regs *regs, unsigned long sfsr, un info.si_addr = (void __user *)regs->tpc; info.si_trapno = 0; force_sig_info(SIGSEGV, &info, current); +out: + exception_exit(prev_state); } void spitfire_insn_access_exception_tl1(struct pt_regs *regs, unsigned long sfsr, unsigned long sfar) @@ -260,11 +266,12 @@ void sun4v_insn_access_exception_tl1(struct pt_regs *regs, unsigned long addr, u void spitfire_data_access_exception(struct pt_regs *regs, unsigned long sfsr, unsigned long sfar) { + enum ctx_state prev_state = exception_enter(); siginfo_t info; if (notify_die(DIE_TRAP, "data access exception", regs, 0, 0x30, SIGTRAP) == NOTIFY_STOP) - return; + goto out; if (regs->tstate & TSTATE_PRIV) { /* Test if this comes from uaccess places. */ @@ -280,7 +287,7 @@ void spitfire_data_access_exception(struct pt_regs *regs, unsigned long sfsr, un #endif regs->tpc = entry->fixup; regs->tnpc = regs->tpc + 4; - return; + goto out; } /* Shit... */ printk("spitfire_data_access_exception: SFSR[%016lx] " @@ -294,6 +301,8 @@ void spitfire_data_access_exception(struct pt_regs *regs, unsigned long sfsr, un info.si_addr = (void __user *)sfar; info.si_trapno = 0; force_sig_info(SIGSEGV, &info, current); +out: + exception_exit(prev_state); } void spitfire_data_access_exception_tl1(struct pt_regs *regs, unsigned long sfsr, unsigned long sfar) @@ -1994,6 +2003,7 @@ static void sun4v_log_error(struct pt_regs *regs, struct sun4v_error_entry *ent, */ void sun4v_resum_error(struct pt_regs *regs, unsigned long offset) { + enum ctx_state prev_state = exception_enter(); struct sun4v_error_entry *ent, local_copy; struct trap_per_cpu *tb; unsigned long paddr; @@ -2022,12 +2032,14 @@ void sun4v_resum_error(struct pt_regs *regs, unsigned long offset) pr_info("Shutdown request, %u seconds...\n", local_copy.err_secs); orderly_poweroff(true); - return; + goto out; } sun4v_log_error(regs, &local_copy, cpu, KERN_ERR "RESUMABLE ERROR", &sun4v_resum_oflow_cnt); +out: + exception_exit(prev_state); } /* If we try to printk() we'll probably make matters worse, by trying @@ -2152,7 +2164,7 @@ void hypervisor_tlbop_error_xcall(unsigned long err, unsigned long op) err, op); } -void do_fpe_common(struct pt_regs *regs) +static void do_fpe_common(struct pt_regs *regs) { if (regs->tstate & TSTATE_PRIV) { regs->tpc = regs->tnpc; @@ -2188,23 +2200,26 @@ void do_fpe_common(struct pt_regs *regs) void do_fpieee(struct pt_regs *regs) { + enum ctx_state prev_state = exception_enter(); + if (notify_die(DIE_TRAP, "fpu exception ieee", regs, 0, 0x24, SIGFPE) == NOTIFY_STOP) - return; + goto out; do_fpe_common(regs); +out: + exception_exit(prev_state); } -extern int do_mathemu(struct pt_regs *, struct fpustate *, bool); - void do_fpother(struct pt_regs *regs) { + enum ctx_state prev_state = exception_enter(); struct fpustate *f = FPUSTATE; int ret = 0; if (notify_die(DIE_TRAP, "fpu exception other", regs, 0, 0x25, SIGFPE) == NOTIFY_STOP) - return; + goto out; switch ((current_thread_info()->xfsr[0] & 0x1c000)) { case (2 << 14): /* unfinished_FPop */ @@ -2213,17 +2228,20 @@ void do_fpother(struct pt_regs *regs) break; } if (ret) - return; + goto out; do_fpe_common(regs); +out: + exception_exit(prev_state); } void do_tof(struct pt_regs *regs) { + enum ctx_state prev_state = exception_enter(); siginfo_t info; if (notify_die(DIE_TRAP, "tagged arithmetic overflow", regs, 0, 0x26, SIGEMT) == NOTIFY_STOP) - return; + goto out; if (regs->tstate & TSTATE_PRIV) die_if_kernel("Penguin overflow trap from kernel mode", regs); @@ -2237,15 +2255,18 @@ void do_tof(struct pt_regs *regs) info.si_addr = (void __user *)regs->tpc; info.si_trapno = 0; force_sig_info(SIGEMT, &info, current); +out: + exception_exit(prev_state); } void do_div0(struct pt_regs *regs) { + enum ctx_state prev_state = exception_enter(); siginfo_t info; if (notify_die(DIE_TRAP, "integer division by zero", regs, 0, 0x28, SIGFPE) == NOTIFY_STOP) - return; + goto out; if (regs->tstate & TSTATE_PRIV) die_if_kernel("TL0: Kernel divide by zero.", regs); @@ -2259,6 +2280,8 @@ void do_div0(struct pt_regs *regs) info.si_addr = (void __user *)regs->tpc; info.si_trapno = 0; force_sig_info(SIGFPE, &info, current); +out: + exception_exit(prev_state); } static void instruction_dump(unsigned int *pc) @@ -2360,7 +2383,7 @@ static inline struct reg_window *kernel_stack_up(struct reg_window *rw) return (struct reg_window *) (fp + STACK_BIAS); } -void die_if_kernel(char *str, struct pt_regs *regs) +void __noreturn die_if_kernel(char *str, struct pt_regs *regs) { static int die_counter; int count = 0; @@ -2410,11 +2433,9 @@ EXPORT_SYMBOL(die_if_kernel); #define VIS_OPCODE_MASK ((0x3 << 30) | (0x3f << 19)) #define VIS_OPCODE_VAL ((0x2 << 30) | (0x36 << 19)) -extern int handle_popc(u32 insn, struct pt_regs *regs); -extern int handle_ldf_stq(u32 insn, struct pt_regs *regs); - void do_illegal_instruction(struct pt_regs *regs) { + enum ctx_state prev_state = exception_enter(); unsigned long pc = regs->tpc; unsigned long tstate = regs->tstate; u32 insn; @@ -2422,7 +2443,7 @@ void do_illegal_instruction(struct pt_regs *regs) if (notify_die(DIE_TRAP, "illegal instruction", regs, 0, 0x10, SIGILL) == NOTIFY_STOP) - return; + goto out; if (tstate & TSTATE_PRIV) die_if_kernel("Kernel illegal instruction", regs); @@ -2431,14 +2452,14 @@ void do_illegal_instruction(struct pt_regs *regs) if (get_user(insn, (u32 __user *) pc) != -EFAULT) { if ((insn & 0xc1ffc000) == 0x81700000) /* POPC */ { if (handle_popc(insn, regs)) - return; + goto out; } else if ((insn & 0xc1580000) == 0xc1100000) /* LDQ/STQ */ { if (handle_ldf_stq(insn, regs)) - return; + goto out; } else if (tlb_type == hypervisor) { if ((insn & VIS_OPCODE_MASK) == VIS_OPCODE_VAL) { if (!vis_emul(regs, insn)) - return; + goto out; } else { struct fpustate *f = FPUSTATE; @@ -2448,7 +2469,7 @@ void do_illegal_instruction(struct pt_regs *regs) * Trap in the %fsr to unimplemented_FPop. */ if (do_mathemu(regs, f, true)) - return; + goto out; } } } @@ -2458,21 +2479,22 @@ void do_illegal_instruction(struct pt_regs *regs) info.si_addr = (void __user *)pc; info.si_trapno = 0; force_sig_info(SIGILL, &info, current); +out: + exception_exit(prev_state); } -extern void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn); - void mem_address_unaligned(struct pt_regs *regs, unsigned long sfar, unsigned long sfsr) { + enum ctx_state prev_state = exception_enter(); siginfo_t info; if (notify_die(DIE_TRAP, "memory address unaligned", regs, 0, 0x34, SIGSEGV) == NOTIFY_STOP) - return; + goto out; if (regs->tstate & TSTATE_PRIV) { kernel_unaligned_trap(regs, *((unsigned int *)regs->tpc)); - return; + goto out; } info.si_signo = SIGBUS; info.si_errno = 0; @@ -2480,6 +2502,8 @@ void mem_address_unaligned(struct pt_regs *regs, unsigned long sfar, unsigned lo info.si_addr = (void __user *)sfar; info.si_trapno = 0; force_sig_info(SIGBUS, &info, current); +out: + exception_exit(prev_state); } void sun4v_do_mna(struct pt_regs *regs, unsigned long addr, unsigned long type_ctx) @@ -2504,11 +2528,12 @@ void sun4v_do_mna(struct pt_regs *regs, unsigned long addr, unsigned long type_c void do_privop(struct pt_regs *regs) { + enum ctx_state prev_state = exception_enter(); siginfo_t info; if (notify_die(DIE_TRAP, "privileged operation", regs, 0, 0x11, SIGILL) == NOTIFY_STOP) - return; + goto out; if (test_thread_flag(TIF_32BIT)) { regs->tpc &= 0xffffffff; @@ -2520,6 +2545,8 @@ void do_privop(struct pt_regs *regs) info.si_addr = (void __user *)regs->tpc; info.si_trapno = 0; force_sig_info(SIGILL, &info, current); +out: + exception_exit(prev_state); } void do_privact(struct pt_regs *regs) @@ -2530,99 +2557,116 @@ void do_privact(struct pt_regs *regs) /* Trap level 1 stuff or other traps we should never see... */ void do_cee(struct pt_regs *regs) { + exception_enter(); die_if_kernel("TL0: Cache Error Exception", regs); } void do_cee_tl1(struct pt_regs *regs) { + exception_enter(); dump_tl1_traplog((struct tl1_traplog *)(regs + 1)); die_if_kernel("TL1: Cache Error Exception", regs); } void do_dae_tl1(struct pt_regs *regs) { + exception_enter(); dump_tl1_traplog((struct tl1_traplog *)(regs + 1)); die_if_kernel("TL1: Data Access Exception", regs); } void do_iae_tl1(struct pt_regs *regs) { + exception_enter(); dump_tl1_traplog((struct tl1_traplog *)(regs + 1)); die_if_kernel("TL1: Instruction Access Exception", regs); } void do_div0_tl1(struct pt_regs *regs) { + exception_enter(); dump_tl1_traplog((struct tl1_traplog *)(regs + 1)); die_if_kernel("TL1: DIV0 Exception", regs); } void do_fpdis_tl1(struct pt_regs *regs) { + exception_enter(); dump_tl1_traplog((struct tl1_traplog *)(regs + 1)); die_if_kernel("TL1: FPU Disabled", regs); } void do_fpieee_tl1(struct pt_regs *regs) { + exception_enter(); dump_tl1_traplog((struct tl1_traplog *)(regs + 1)); die_if_kernel("TL1: FPU IEEE Exception", regs); } void do_fpother_tl1(struct pt_regs *regs) { + exception_enter(); dump_tl1_traplog((struct tl1_traplog *)(regs + 1)); die_if_kernel("TL1: FPU Other Exception", regs); } void do_ill_tl1(struct pt_regs *regs) { + exception_enter(); dump_tl1_traplog((struct tl1_traplog *)(regs + 1)); die_if_kernel("TL1: Illegal Instruction Exception", regs); } void do_irq_tl1(struct pt_regs *regs) { + exception_enter(); dump_tl1_traplog((struct tl1_traplog *)(regs + 1)); die_if_kernel("TL1: IRQ Exception", regs); } void do_lddfmna_tl1(struct pt_regs *regs) { + exception_enter(); dump_tl1_traplog((struct tl1_traplog *)(regs + 1)); die_if_kernel("TL1: LDDF Exception", regs); } void do_stdfmna_tl1(struct pt_regs *regs) { + exception_enter(); dump_tl1_traplog((struct tl1_traplog *)(regs + 1)); die_if_kernel("TL1: STDF Exception", regs); } void do_paw(struct pt_regs *regs) { + exception_enter(); die_if_kernel("TL0: Phys Watchpoint Exception", regs); } void do_paw_tl1(struct pt_regs *regs) { + exception_enter(); dump_tl1_traplog((struct tl1_traplog *)(regs + 1)); die_if_kernel("TL1: Phys Watchpoint Exception", regs); } void do_vaw(struct pt_regs *regs) { + exception_enter(); die_if_kernel("TL0: Virt Watchpoint Exception", regs); } void do_vaw_tl1(struct pt_regs *regs) { + exception_enter(); dump_tl1_traplog((struct tl1_traplog *)(regs + 1)); die_if_kernel("TL1: Virt Watchpoint Exception", regs); } void do_tof_tl1(struct pt_regs *regs) { + exception_enter(); dump_tl1_traplog((struct tl1_traplog *)(regs + 1)); die_if_kernel("TL1: Tag Overflow Exception", regs); } diff --git a/arch/sparc/kernel/tsb.S b/arch/sparc/kernel/tsb.S index a313e4a9399..14158d40ba7 100644 --- a/arch/sparc/kernel/tsb.S +++ b/arch/sparc/kernel/tsb.S @@ -75,7 +75,7 @@ tsb_miss_page_table_walk: mov 512, %g7 andn %g5, 0x7, %g5 sllx %g7, %g6, %g7 - srlx %g4, HPAGE_SHIFT, %g6 + srlx %g4, REAL_HPAGE_SHIFT, %g6 sub %g7, 1, %g7 and %g6, %g7, %g6 sllx %g6, 4, %g6 diff --git a/arch/sparc/kernel/unaligned_32.c b/arch/sparc/kernel/unaligned_32.c index c0ec8978619..c5c61b3c6b5 100644 --- a/arch/sparc/kernel/unaligned_32.c +++ b/arch/sparc/kernel/unaligned_32.c @@ -16,6 +16,10 @@ #include <linux/smp.h> #include <linux/perf_event.h> +#include <asm/setup.h> + +#include "kernel.h" + enum direction { load, /* ld, ldd, ldh, ldsh */ store, /* st, std, sth, stsh */ diff --git a/arch/sparc/kernel/unaligned_64.c b/arch/sparc/kernel/unaligned_64.c index 8201c25e766..62098a89bbb 100644 --- a/arch/sparc/kernel/unaligned_64.c +++ b/arch/sparc/kernel/unaligned_64.c @@ -21,8 +21,13 @@ #include <linux/bitops.h> #include <linux/perf_event.h> #include <linux/ratelimit.h> +#include <linux/context_tracking.h> #include <asm/fpumacro.h> #include <asm/cacheflush.h> +#include <asm/setup.h> + +#include "entry.h" +#include "kernel.h" enum direction { load, /* ld, ldd, ldh, ldsh */ @@ -163,17 +168,23 @@ static unsigned long *fetch_reg_addr(unsigned int reg, struct pt_regs *regs) unsigned long compute_effective_address(struct pt_regs *regs, unsigned int insn, unsigned int rd) { + int from_kernel = (regs->tstate & TSTATE_PRIV) != 0; unsigned int rs1 = (insn >> 14) & 0x1f; unsigned int rs2 = insn & 0x1f; - int from_kernel = (regs->tstate & TSTATE_PRIV) != 0; + unsigned long addr; if (insn & 0x2000) { maybe_flush_windows(rs1, 0, rd, from_kernel); - return (fetch_reg(rs1, regs) + sign_extend_imm13(insn)); + addr = (fetch_reg(rs1, regs) + sign_extend_imm13(insn)); } else { maybe_flush_windows(rs1, rs2, rd, from_kernel); - return (fetch_reg(rs1, regs) + fetch_reg(rs2, regs)); + addr = (fetch_reg(rs1, regs) + fetch_reg(rs2, regs)); } + + if (!from_kernel && test_thread_flag(TIF_32BIT)) + addr &= 0xffffffff; + + return addr; } /* This is just to make gcc think die_if_kernel does return... */ @@ -418,9 +429,6 @@ int handle_popc(u32 insn, struct pt_regs *regs) extern void do_fpother(struct pt_regs *regs); extern void do_privact(struct pt_regs *regs); -extern void spitfire_data_access_exception(struct pt_regs *regs, - unsigned long sfsr, - unsigned long sfar); extern void sun4v_data_access_exception(struct pt_regs *regs, unsigned long addr, unsigned long type_ctx); @@ -578,6 +586,7 @@ void handle_ld_nf(u32 insn, struct pt_regs *regs) void handle_lddfmna(struct pt_regs *regs, unsigned long sfar, unsigned long sfsr) { + enum ctx_state prev_state = exception_enter(); unsigned long pc = regs->tpc; unsigned long tstate = regs->tstate; u32 insn; @@ -632,13 +641,16 @@ daex: sun4v_data_access_exception(regs, sfar, sfsr); else spitfire_data_access_exception(regs, sfsr, sfar); - return; + goto out; } advance(regs); +out: + exception_exit(prev_state); } void handle_stdfmna(struct pt_regs *regs, unsigned long sfar, unsigned long sfsr) { + enum ctx_state prev_state = exception_enter(); unsigned long pc = regs->tpc; unsigned long tstate = regs->tstate; u32 insn; @@ -680,7 +692,9 @@ daex: sun4v_data_access_exception(regs, sfar, sfsr); else spitfire_data_access_exception(regs, sfsr, sfar); - return; + goto out; } advance(regs); +out: + exception_exit(prev_state); } diff --git a/arch/sparc/kernel/vmlinux.lds.S b/arch/sparc/kernel/vmlinux.lds.S index 0bacceb1915..932ff90fd76 100644 --- a/arch/sparc/kernel/vmlinux.lds.S +++ b/arch/sparc/kernel/vmlinux.lds.S @@ -122,6 +122,11 @@ SECTIONS *(.swapper_4m_tsb_phys_patch) __swapper_4m_tsb_phys_patch_end = .; } + .page_offset_shift_patch : { + __page_offset_shift_patch = .; + *(.page_offset_shift_patch) + __page_offset_shift_patch_end = .; + } .popc_3insn_patch : { __popc_3insn_patch = .; *(.popc_3insn_patch) diff --git a/arch/sparc/kernel/windows.c b/arch/sparc/kernel/windows.c index 3107381e576..87bab0a3857 100644 --- a/arch/sparc/kernel/windows.c +++ b/arch/sparc/kernel/windows.c @@ -10,8 +10,11 @@ #include <linux/mm.h> #include <linux/smp.h> +#include <asm/cacheflush.h> #include <asm/uaccess.h> +#include "kernel.h" + /* Do save's until all user register windows are out of the cpu. */ void flush_user_windows(void) { |
