 fault_done: /* These values are no longer needed, clear them. */ set_thread_fault_code(0); current_thread_info()->fault_address = 0; 
asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs){	struct mm_struct *mm = current->mm;	struct vm_area_struct *vma;	unsigned int insn = 0;	int si_code, fault_code;	unsigned long address;	fault_code = get_thread_fault_code();	if (notify_die(DIE_PAGE_FAULT, "page_fault", regs,		       fault_code, 0, SIGSEGV) == NOTIFY_STOP)		return;	si_code = SEGV_MAPERR;	address = current_thread_info()->fault_address;	if ((fault_code & FAULT_CODE_ITLB) &&	    (fault_code & FAULT_CODE_DTLB))		BUG();	if (regs->tstate & TSTATE_PRIV) {		unsigned long tpc = regs->tpc;		/* Sanity check the PC. */		if ((tpc >= KERNBASE && tpc < (unsigned long) _etext) ||		    (tpc >= MODULES_VADDR && tpc < MODULES_END)) {			/* Valid, no problems... */		} else {			bad_kernel_pc(regs);			return;		}	}	/*	 * If we're in an interrupt or have no user	 * context, we must not take the fault..	 */	if (in_atomic() || !mm)		goto intr_or_no_mm;	if (test_thread_flag(TIF_32BIT)) {		if (!(regs->tstate & TSTATE_PRIV))			regs->tpc &= 0xffffffff;		address &= 0xffffffff;	}	if (!down_read_trylock(&mm->mmap_sem)) {		if ((regs->tstate & TSTATE_PRIV) &&		    !search_exception_tables(regs->tpc)) {			insn = get_fault_insn(regs, insn);			goto handle_kernel_fault;		}		down_read(&mm->mmap_sem);	}	vma = find_vma(mm, address);	if (!vma)		goto bad_area;	/* Pure DTLB misses do not tell us whether the fault causing	 * load/store/atomic was a write or not, it only says that there	 * was no match.  So in such a case we (carefully) read the	 * instruction to try and figure this out.  It's an optimization	 * so it's ok if we can't do this.	 *	 * Special hack, window spill/fill knows the exact fault type.	 */	if (((fault_code &	      (FAULT_CODE_DTLB | FAULT_CODE_WRITE | FAULT_CODE_WINFIXUP)) == FAULT_CODE_DTLB) &&	    (vma->vm_flags & VM_WRITE) != 0) {		insn = get_fault_insn(regs, 0);		if (!insn)			goto continue_fault;		if ((insn & 0xc0200000) == 0xc0200000 &&		    (insn & 0x1780000) != 0x1680000) {			/* Don't bother updating thread struct value,			 * because update_mmu_cache only cares which tlb			 * the access came from.			 */			fault_code |= FAULT_CODE_WRITE;		}	}continue_fault:	if (vma->vm_start <= address)		goto good_area;	if (!(vma->vm_flags & VM_GROWSDOWN))		goto bad_area;	if (!(fault_code & FAULT_CODE_WRITE)) {		/* Non-faulting loads shouldn't expand stack. */		insn = get_fault_insn(regs, insn);		if ((insn & 0xc0800000) == 0xc0800000) {			unsigned char asi;			if (insn & 0x2000)				asi = (regs->tstate >> 24);			else				asi = (insn >> 5);			if ((asi & 0xf2) == 0x82)				goto bad_area;		}	}	if (expand_stack(vma, address))		goto bad_area;	/*	 * Ok, we have a good vm_area for this memory access, so	 * we can handle it..	 */good_area:	si_code = SEGV_ACCERR;	/* If we took a ITLB miss on a non-executable page, catch	 * that here.	 */	if ((fault_code & FAULT_CODE_ITLB) && !(vma->vm_flags & VM_EXEC)) {		BUG_ON(address != regs->tpc);		BUG_ON(regs->tstate & TSTATE_PRIV);		goto bad_area;	}	if (fault_code & FAULT_CODE_WRITE) {		if (!(vma->vm_flags & VM_WRITE))			goto bad_area;		/* Spitfire has an icache which does not snoop		 * processor stores.  Later processors do...		 */		if (tlb_type == spitfire &&		    (vma->vm_flags & VM_EXEC) != 0 &&		    vma->vm_file != NULL)			set_thread_fault_code(fault_code |					      FAULT_CODE_BLKCOMMIT);	} else {		/* Allow reads even for write-only mappings */		if (!(vma->vm_flags & (VM_READ | VM_EXEC)))			goto bad_area;	}	switch (handle_mm_fault(mm, vma, address, (fault_code & FAULT_CODE_WRITE))) {	case VM_FAULT_MINOR:		current->min_flt++;		break;	case VM_FAULT_MAJOR:		current->maj_flt++;		break;	case VM_FAULT_SIGBUS:		goto do_sigbus;	case VM_FAULT_OOM:		goto out_of_memory;	default:		BUG();	}	up_read(&mm->mmap_sem);	goto fault_done;	/*	 * Something tried to access memory that isn't in our memory map..	 * Fix it, but check if it's kernel or user first..	 */bad_area:	insn = get_fault_insn(regs, insn);	up_read(&mm->mmap_sem);handle_kernel_fault:	do_kernel_fault(regs, si_code, fault_code, insn, address);	goto fault_done;/* * We ran out of memory, or some other thing happened to us that made * us unable to handle the page fault gracefully. */out_of_memory:	insn = get_fault_insn(regs, insn);	up_read(&mm->mmap_sem);	printk("VM: killing process %s\n", current->comm);	if (!(regs->tstate & TSTATE_PRIV))		do_exit(SIGKILL);	goto handle_kernel_fault;intr_or_no_mm:	insn = get_fault_insn(regs, 0);	goto handle_kernel_fault;do_sigbus:	insn = get_fault_insn(regs, insn);	up_read(&mm->mmap_sem);	/*	 * Send a sigbus, regardless of whether we were in kernel	 * or user mode.	 */	do_fault_siginfo(BUS_ADRERR, SIGBUS, regs, insn, fault_code);	/* Kernel mode? Handle exceptions or die */	if (regs->tstate & TSTATE_PRIV)		goto handle_kernel_fault;fault_done:	/* These values are no longer needed, clear them. */	set_thread_fault_code(0);	current_thread_info()->fault_address = 0;}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/efdc1e2083e04cc70721d55803889b346c1a3de2/fault.c/buggy/arch/sparc64/mm/fault.c