diff options
Diffstat (limited to 'arch/sparc')
| -rw-r--r-- | arch/sparc/include/asm/dma-mapping.h | 18 | ||||
| -rw-r--r-- | arch/sparc/include/asm/pgtable_64.h | 4 | ||||
| -rw-r--r-- | arch/sparc/kernel/central.c | 2 | ||||
| -rw-r--r-- | arch/sparc/kernel/ds.c | 2 | ||||
| -rw-r--r-- | arch/sparc/kernel/iommu.c | 10 | ||||
| -rw-r--r-- | arch/sparc/kernel/ioport.c | 18 | ||||
| -rw-r--r-- | arch/sparc/kernel/leon_kernel.c | 6 | ||||
| -rw-r--r-- | arch/sparc/kernel/leon_pci.c | 13 | ||||
| -rw-r--r-- | arch/sparc/kernel/leon_smp.c | 3 | ||||
| -rw-r--r-- | arch/sparc/kernel/pci_sun4v.c | 9 | ||||
| -rw-r--r-- | arch/sparc/kernel/rtrap_64.S | 7 | ||||
| -rw-r--r-- | arch/sparc/kernel/sys_sparc_64.c | 7 | ||||
| -rw-r--r-- | arch/sparc/mm/fault_32.c | 37 | ||||
| -rw-r--r-- | arch/sparc/mm/fault_64.c | 37 | ||||
| -rw-r--r-- | arch/sparc/mm/ultra.S | 6 | 
15 files changed, 107 insertions, 72 deletions
diff --git a/arch/sparc/include/asm/dma-mapping.h b/arch/sparc/include/asm/dma-mapping.h index 8c0e4f7bb20..48a7c65731d 100644 --- a/arch/sparc/include/asm/dma-mapping.h +++ b/arch/sparc/include/asm/dma-mapping.h @@ -26,24 +26,30 @@ static inline struct dma_map_ops *get_dma_ops(struct device *dev)  #include <asm-generic/dma-mapping-common.h> -static inline void *dma_alloc_coherent(struct device *dev, size_t size, -				       dma_addr_t *dma_handle, gfp_t flag) +#define dma_alloc_coherent(d,s,h,f)	dma_alloc_attrs(d,s,h,f,NULL) + +static inline void *dma_alloc_attrs(struct device *dev, size_t size, +				    dma_addr_t *dma_handle, gfp_t flag, +				    struct dma_attrs *attrs)  {  	struct dma_map_ops *ops = get_dma_ops(dev);  	void *cpu_addr; -	cpu_addr = ops->alloc_coherent(dev, size, dma_handle, flag); +	cpu_addr = ops->alloc(dev, size, dma_handle, flag, attrs);  	debug_dma_alloc_coherent(dev, size, *dma_handle, cpu_addr);  	return cpu_addr;  } -static inline void dma_free_coherent(struct device *dev, size_t size, -				     void *cpu_addr, dma_addr_t dma_handle) +#define dma_free_coherent(d,s,c,h) dma_free_attrs(d,s,c,h,NULL) + +static inline void dma_free_attrs(struct device *dev, size_t size, +				  void *cpu_addr, dma_addr_t dma_handle, +				  struct dma_attrs *attrs)  {  	struct dma_map_ops *ops = get_dma_ops(dev);  	debug_dma_free_coherent(dev, size, cpu_addr, dma_handle); -	ops->free_coherent(dev, size, cpu_addr, dma_handle); +	ops->free(dev, size, cpu_addr, dma_handle, attrs);  }  static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) diff --git a/arch/sparc/include/asm/pgtable_64.h b/arch/sparc/include/asm/pgtable_64.h index 6fa2f7980e6..76e4a52aa85 100644 --- a/arch/sparc/include/asm/pgtable_64.h +++ b/arch/sparc/include/asm/pgtable_64.h @@ -12,8 +12,6 @@   * the SpitFire page tables.   */ -#include <asm-generic/pgtable-nopud.h> -  #include <linux/compiler.h>  #include <linux/const.h>  #include <asm/types.h> @@ -22,6 +20,8 @@  #include <asm/page.h>  #include <asm/processor.h> +#include <asm-generic/pgtable-nopud.h> +  /* The kernel image occupies 0x4000000 to 0x6000000 (4MB --> 96MB).   * The page copy blockops can use 0x6000000 to 0x8000000.   * The TSB is mapped in the 0x8000000 to 0xa000000 range. diff --git a/arch/sparc/kernel/central.c b/arch/sparc/kernel/central.c index 38d48a59879..9708851a8b9 100644 --- a/arch/sparc/kernel/central.c +++ b/arch/sparc/kernel/central.c @@ -269,4 +269,4 @@ static int __init sunfire_init(void)  	return 0;  } -subsys_initcall(sunfire_init); +fs_initcall(sunfire_init); diff --git a/arch/sparc/kernel/ds.c b/arch/sparc/kernel/ds.c index fea13c7b1ae..b93c2c9ccb1 100644 --- a/arch/sparc/kernel/ds.c +++ b/arch/sparc/kernel/ds.c @@ -1264,4 +1264,4 @@ static int __init ds_init(void)  	return vio_register_driver(&ds_driver);  } -subsys_initcall(ds_init); +fs_initcall(ds_init); diff --git a/arch/sparc/kernel/iommu.c b/arch/sparc/kernel/iommu.c index 4643d68713f..070ed141aac 100644 --- a/arch/sparc/kernel/iommu.c +++ b/arch/sparc/kernel/iommu.c @@ -280,7 +280,8 @@ static inline void iommu_free_ctx(struct iommu *iommu, int ctx)  }  static void *dma_4u_alloc_coherent(struct device *dev, size_t size, -				   dma_addr_t *dma_addrp, gfp_t gfp) +				   dma_addr_t *dma_addrp, gfp_t gfp, +				   struct dma_attrs *attrs)  {  	unsigned long flags, order, first_page;  	struct iommu *iommu; @@ -330,7 +331,8 @@ static void *dma_4u_alloc_coherent(struct device *dev, size_t size,  }  static void dma_4u_free_coherent(struct device *dev, size_t size, -				 void *cpu, dma_addr_t dvma) +				 void *cpu, dma_addr_t dvma, +				 struct dma_attrs *attrs)  {  	struct iommu *iommu;  	unsigned long flags, order, npages; @@ -825,8 +827,8 @@ static void dma_4u_sync_sg_for_cpu(struct device *dev,  }  static struct dma_map_ops sun4u_dma_ops = { -	.alloc_coherent		= dma_4u_alloc_coherent, -	.free_coherent		= dma_4u_free_coherent, +	.alloc			= dma_4u_alloc_coherent, +	.free			= dma_4u_free_coherent,  	.map_page		= dma_4u_map_page,  	.unmap_page		= dma_4u_unmap_page,  	.map_sg			= dma_4u_map_sg, diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c index d0479e2163f..21bd73943f7 100644 --- a/arch/sparc/kernel/ioport.c +++ b/arch/sparc/kernel/ioport.c @@ -261,7 +261,8 @@ EXPORT_SYMBOL(sbus_set_sbus64);   * CPU may access them without any explicit flushing.   */  static void *sbus_alloc_coherent(struct device *dev, size_t len, -				 dma_addr_t *dma_addrp, gfp_t gfp) +				 dma_addr_t *dma_addrp, gfp_t gfp, +				 struct dma_attrs *attrs)  {  	struct platform_device *op = to_platform_device(dev);  	unsigned long len_total = PAGE_ALIGN(len); @@ -315,7 +316,7 @@ err_nopages:  }  static void sbus_free_coherent(struct device *dev, size_t n, void *p, -			       dma_addr_t ba) +			       dma_addr_t ba, struct dma_attrs *attrs)  {  	struct resource *res;  	struct page *pgv; @@ -407,8 +408,8 @@ static void sbus_sync_sg_for_device(struct device *dev, struct scatterlist *sg,  }  struct dma_map_ops sbus_dma_ops = { -	.alloc_coherent		= sbus_alloc_coherent, -	.free_coherent		= sbus_free_coherent, +	.alloc			= sbus_alloc_coherent, +	.free			= sbus_free_coherent,  	.map_page		= sbus_map_page,  	.unmap_page		= sbus_unmap_page,  	.map_sg			= sbus_map_sg, @@ -436,7 +437,8 @@ arch_initcall(sparc_register_ioport);   * hwdev should be valid struct pci_dev pointer for PCI devices.   */  static void *pci32_alloc_coherent(struct device *dev, size_t len, -				  dma_addr_t *pba, gfp_t gfp) +				  dma_addr_t *pba, gfp_t gfp, +				  struct dma_attrs *attrs)  {  	unsigned long len_total = PAGE_ALIGN(len);  	void *va; @@ -489,7 +491,7 @@ err_nopages:   * past this call are illegal.   */  static void pci32_free_coherent(struct device *dev, size_t n, void *p, -				dma_addr_t ba) +				dma_addr_t ba, struct dma_attrs *attrs)  {  	struct resource *res; @@ -645,8 +647,8 @@ static void pci32_sync_sg_for_device(struct device *device, struct scatterlist *  }  struct dma_map_ops pci32_dma_ops = { -	.alloc_coherent		= pci32_alloc_coherent, -	.free_coherent		= pci32_free_coherent, +	.alloc			= pci32_alloc_coherent, +	.free			= pci32_free_coherent,  	.map_page		= pci32_map_page,  	.unmap_page		= pci32_unmap_page,  	.map_sg			= pci32_map_sg, diff --git a/arch/sparc/kernel/leon_kernel.c b/arch/sparc/kernel/leon_kernel.c index a19c8a06368..35e43673c45 100644 --- a/arch/sparc/kernel/leon_kernel.c +++ b/arch/sparc/kernel/leon_kernel.c @@ -104,11 +104,11 @@ static int irq_choose_cpu(const struct cpumask *affinity)  {  	cpumask_t mask; -	cpus_and(mask, cpu_online_map, *affinity); -	if (cpus_equal(mask, cpu_online_map) || cpus_empty(mask)) +	cpumask_and(&mask, cpu_online_mask, affinity); +	if (cpumask_equal(&mask, cpu_online_mask) || cpumask_empty(&mask))  		return boot_cpu_id;  	else -		return first_cpu(mask); +		return cpumask_first(&mask);  }  #else  #define irq_choose_cpu(affinity) boot_cpu_id diff --git a/arch/sparc/kernel/leon_pci.c b/arch/sparc/kernel/leon_pci.c index aba6b958b2a..19f56058742 100644 --- a/arch/sparc/kernel/leon_pci.c +++ b/arch/sparc/kernel/leon_pci.c @@ -45,7 +45,6 @@ void leon_pci_init(struct platform_device *ofdev, struct leon_pci_info *info)  void __devinit pcibios_fixup_bus(struct pci_bus *pbus)  { -	struct leon_pci_info *info = pbus->sysdata;  	struct pci_dev *dev;  	int i, has_io, has_mem;  	u16 cmd; @@ -111,18 +110,6 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)  	return pci_enable_resources(dev, mask);  } -struct device_node *pci_device_to_OF_node(struct pci_dev *pdev) -{ -	/* -	 * Currently the OpenBoot nodes are not connected with the PCI device, -	 * this is because the LEON PROM does not create PCI nodes. Eventually -	 * this will change and the same approach as pcic.c can be used to -	 * match PROM nodes with pci devices. -	 */ -	return NULL; -} -EXPORT_SYMBOL(pci_device_to_OF_node); -  void __devinit pcibios_update_irq(struct pci_dev *dev, int irq)  {  #ifdef CONFIG_PCI_DEBUG diff --git a/arch/sparc/kernel/leon_smp.c b/arch/sparc/kernel/leon_smp.c index 1210fde1874..160cac9c403 100644 --- a/arch/sparc/kernel/leon_smp.c +++ b/arch/sparc/kernel/leon_smp.c @@ -23,6 +23,7 @@  #include <linux/pm.h>  #include <linux/delay.h>  #include <linux/gfp.h> +#include <linux/cpu.h>  #include <asm/cacheflush.h>  #include <asm/tlbflush.h> @@ -78,6 +79,8 @@ void __cpuinit leon_callin(void)  	local_flush_tlb_all();  	leon_configure_cache_smp(); +	notify_cpu_starting(cpuid); +  	/* Get our local ticker going. */  	smp_setup_percpu_timer(); diff --git a/arch/sparc/kernel/pci_sun4v.c b/arch/sparc/kernel/pci_sun4v.c index af5755d20fb..7661e84a05a 100644 --- a/arch/sparc/kernel/pci_sun4v.c +++ b/arch/sparc/kernel/pci_sun4v.c @@ -128,7 +128,8 @@ static inline long iommu_batch_end(void)  }  static void *dma_4v_alloc_coherent(struct device *dev, size_t size, -				   dma_addr_t *dma_addrp, gfp_t gfp) +				   dma_addr_t *dma_addrp, gfp_t gfp, +				   struct dma_attrs *attrs)  {  	unsigned long flags, order, first_page, npages, n;  	struct iommu *iommu; @@ -198,7 +199,7 @@ range_alloc_fail:  }  static void dma_4v_free_coherent(struct device *dev, size_t size, void *cpu, -				 dma_addr_t dvma) +				 dma_addr_t dvma, struct dma_attrs *attrs)  {  	struct pci_pbm_info *pbm;  	struct iommu *iommu; @@ -527,8 +528,8 @@ static void dma_4v_unmap_sg(struct device *dev, struct scatterlist *sglist,  }  static struct dma_map_ops sun4v_dma_ops = { -	.alloc_coherent			= dma_4v_alloc_coherent, -	.free_coherent			= dma_4v_free_coherent, +	.alloc				= dma_4v_alloc_coherent, +	.free				= dma_4v_free_coherent,  	.map_page			= dma_4v_map_page,  	.unmap_page			= dma_4v_unmap_page,  	.map_sg				= dma_4v_map_sg, diff --git a/arch/sparc/kernel/rtrap_64.S b/arch/sparc/kernel/rtrap_64.S index 77f1b95e080..9171fc238de 100644 --- a/arch/sparc/kernel/rtrap_64.S +++ b/arch/sparc/kernel/rtrap_64.S @@ -20,11 +20,6 @@  		.text  		.align			32 -__handle_softirq: -		call			do_softirq -		 nop -		ba,a,pt			%xcc, __handle_softirq_continue -		 nop  __handle_preemption:  		call			schedule  		 wrpr			%g0, RTRAP_PSTATE, %pstate @@ -89,9 +84,7 @@ rtrap:  		cmp			%l1, 0  		/* mm/ultra.S:xcall_report_regs KNOWS about this load. */ -		bne,pn			%icc, __handle_softirq  		 ldx			[%sp + PTREGS_OFF + PT_V9_TSTATE], %l1 -__handle_softirq_continue:  rtrap_xcall:  		sethi			%hi(0xf << 20), %l4  		and			%l1, %l4, %l4 diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c index 232df994953..3ee51f189a5 100644 --- a/arch/sparc/kernel/sys_sparc_64.c +++ b/arch/sparc/kernel/sys_sparc_64.c @@ -566,15 +566,10 @@ out:  SYSCALL_DEFINE2(64_munmap, unsigned long, addr, size_t, len)  { -	long ret; -  	if (invalid_64bit_range(addr, len))  		return -EINVAL; -	down_write(¤t->mm->mmap_sem); -	ret = do_munmap(current->mm, addr, len); -	up_write(¤t->mm->mmap_sem); -	return ret; +	return vm_munmap(addr, len);  }  extern unsigned long do_mremap(unsigned long addr, diff --git a/arch/sparc/mm/fault_32.c b/arch/sparc/mm/fault_32.c index 7705c6731e2..df3155a1799 100644 --- a/arch/sparc/mm/fault_32.c +++ b/arch/sparc/mm/fault_32.c @@ -225,6 +225,8 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,  	unsigned long g2;  	int from_user = !(regs->psr & PSR_PS);  	int fault, code; +	unsigned int flags = (FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE | +			      (write ? FAULT_FLAG_WRITE : 0));  	if(text_fault)  		address = regs->pc; @@ -251,6 +253,7 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,  	perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address); +retry:  	down_read(&mm->mmap_sem);  	/* @@ -289,7 +292,11 @@ good_area:  	 * make sure we exit gracefully rather than endlessly redo  	 * the fault.  	 */ -	fault = handle_mm_fault(mm, vma, address, write ? FAULT_FLAG_WRITE : 0); +	fault = handle_mm_fault(mm, vma, address, flags); + +	if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current)) +		return; +  	if (unlikely(fault & VM_FAULT_ERROR)) {  		if (fault & VM_FAULT_OOM)  			goto out_of_memory; @@ -297,13 +304,29 @@ good_area:  			goto do_sigbus;  		BUG();  	} -	if (fault & VM_FAULT_MAJOR) { -		current->maj_flt++; -		perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, regs, address); -	} else { -		current->min_flt++; -		perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, regs, address); + +	if (flags & FAULT_FLAG_ALLOW_RETRY) { +		if (fault & VM_FAULT_MAJOR) { +			current->maj_flt++; +			perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, +				      1, regs, address); +		} else { +			current->min_flt++; +			perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, +				      1, regs, address); +		} +		if (fault & VM_FAULT_RETRY) { +			flags &= ~FAULT_FLAG_ALLOW_RETRY; + +			/* No need to up_read(&mm->mmap_sem) as we would +			 * have already released it in __lock_page_or_retry +			 * in mm/filemap.c. +			 */ + +			goto retry; +		}  	} +  	up_read(&mm->mmap_sem);  	return; diff --git a/arch/sparc/mm/fault_64.c b/arch/sparc/mm/fault_64.c index 504c0622f72..1fe0429b631 100644 --- a/arch/sparc/mm/fault_64.c +++ b/arch/sparc/mm/fault_64.c @@ -279,6 +279,7 @@ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)  	unsigned int insn = 0;  	int si_code, fault_code, fault;  	unsigned long address, mm_rss; +	unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;  	fault_code = get_thread_fault_code(); @@ -333,6 +334,8 @@ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)  			insn = get_fault_insn(regs, insn);  			goto handle_kernel_fault;  		} + +retry:  		down_read(&mm->mmap_sem);  	} @@ -423,7 +426,12 @@ good_area:  			goto bad_area;  	} -	fault = handle_mm_fault(mm, vma, address, (fault_code & FAULT_CODE_WRITE) ? FAULT_FLAG_WRITE : 0); +	flags |= ((fault_code & FAULT_CODE_WRITE) ? FAULT_FLAG_WRITE : 0); +	fault = handle_mm_fault(mm, vma, address, flags); + +	if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current)) +		return; +  	if (unlikely(fault & VM_FAULT_ERROR)) {  		if (fault & VM_FAULT_OOM)  			goto out_of_memory; @@ -431,12 +439,27 @@ good_area:  			goto do_sigbus;  		BUG();  	} -	if (fault & VM_FAULT_MAJOR) { -		current->maj_flt++; -		perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, regs, address); -	} else { -		current->min_flt++; -		perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, regs, address); + +	if (flags & FAULT_FLAG_ALLOW_RETRY) { +		if (fault & VM_FAULT_MAJOR) { +			current->maj_flt++; +			perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, +				      1, regs, address); +		} else { +			current->min_flt++; +			perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, +				      1, regs, address); +		} +		if (fault & VM_FAULT_RETRY) { +			flags &= ~FAULT_FLAG_ALLOW_RETRY; + +			/* No need to up_read(&mm->mmap_sem) as we would +			 * have already released it in __lock_page_or_retry +			 * in mm/filemap.c. +			 */ + +			goto retry; +		}  	}  	up_read(&mm->mmap_sem); diff --git a/arch/sparc/mm/ultra.S b/arch/sparc/mm/ultra.S index b57a5942ba6..874162a11ce 100644 --- a/arch/sparc/mm/ultra.S +++ b/arch/sparc/mm/ultra.S @@ -495,11 +495,11 @@ xcall_fetch_glob_regs:  	stx		%o7, [%g1 + GR_SNAP_O7]  	stx		%i7, [%g1 + GR_SNAP_I7]  	/* Don't try this at home kids... */ -	rdpr		%cwp, %g2 -	sub		%g2, 1, %g7 +	rdpr		%cwp, %g3 +	sub		%g3, 1, %g7  	wrpr		%g7, %cwp  	mov		%i7, %g7 -	wrpr		%g2, %cwp +	wrpr		%g3, %cwp  	stx		%g7, [%g1 + GR_SNAP_RPC]  	sethi		%hi(trap_block), %g7  	or		%g7, %lo(trap_block), %g7  |