diff options
Diffstat (limited to 'arch/sparc')
| -rw-r--r-- | arch/sparc/kernel/ds.c | 2 | ||||
| -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/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 | 
7 files changed, 65 insertions, 41 deletions
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/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/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);  |