16bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin/*
26bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin * arch/score/mm/fault.c
36bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin *
46bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin * Score Processor version.
56bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin *
66bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin * Copyright (C) 2009 Sunplus Core Technology Co., Ltd.
76bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin *  Lennox Wu <lennox.wu@sunplusct.com>
86bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin *  Chen Liqin <liqin.chen@sunplusct.com>
96bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin *
106bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin * This program is free software; you can redistribute it and/or modify
116bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin * it under the terms of the GNU General Public License as published by
126bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin * the Free Software Foundation; either version 2 of the License, or
136bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin * (at your option) any later version.
146bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin *
156bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin * This program is distributed in the hope that it will be useful,
166bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin * but WITHOUT ANY WARRANTY; without even the implied warranty of
176bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
186bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin * GNU General Public License for more details.
196bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin *
206bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin * You should have received a copy of the GNU General Public License
216bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin * along with this program; if not, see the file COPYING, or write
226bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin * to the Free Software Foundation, Inc.,
236bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
246bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin */
256bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin
266bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin#include <linux/errno.h>
276bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin#include <linux/interrupt.h>
286bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin#include <linux/kernel.h>
296bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin#include <linux/mm.h>
306bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin#include <linux/mman.h>
316bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin#include <linux/module.h>
326bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin#include <linux/signal.h>
336bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin#include <linux/sched.h>
346bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin#include <linux/string.h>
356bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin#include <linux/types.h>
366bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin#include <linux/ptrace.h>
376bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin
386bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin/*
396bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin * This routine handles page faults.  It determines the address,
406bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin * and the problem, and then passes it off to one of the appropriate
416bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin * routines.
426bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin */
436bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqinasmlinkage void do_page_fault(struct pt_regs *regs, unsigned long write,
446bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin				unsigned long address)
456bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin{
466bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	struct vm_area_struct *vma = NULL;
476bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	struct task_struct *tsk = current;
486bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	struct mm_struct *mm = tsk->mm;
496bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	const int field = sizeof(unsigned long) * 2;
50759496ba6407c6994d6a5ce3a5e74937d7816208Johannes Weiner	unsigned long flags = 0;
516bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	siginfo_t info;
526bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	int fault;
536bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin
546bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	info.si_code = SEGV_MAPERR;
556bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin
566bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	/*
576bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	* We fault-in kernel-space virtual memory on-demand. The
586bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	* 'reference' page table is init_mm.pgd.
596bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	*
606bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	* NOTE! We MUST NOT take any locks for this case. We may
616bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	* be in an interrupt or a critical region, and should
626bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	* only copy the information from the master page table,
636bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	* nothing more.
646bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	*/
656bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	if (unlikely(address >= VMALLOC_START && address <= VMALLOC_END))
666bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin		goto vmalloc_fault;
676bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin#ifdef MODULE_START
686bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	if (unlikely(address >= MODULE_START && address < MODULE_END))
696bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin		goto vmalloc_fault;
706bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin#endif
716bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin
726bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	/*
736bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	* If we're in an interrupt or have no user
746bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	* context, we must not take the fault..
756bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	*/
766bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	if (in_atomic() || !mm)
776bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin		goto bad_area_nosemaphore;
786bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin
79759496ba6407c6994d6a5ce3a5e74937d7816208Johannes Weiner	if (user_mode(regs))
80759496ba6407c6994d6a5ce3a5e74937d7816208Johannes Weiner		flags |= FAULT_FLAG_USER;
81759496ba6407c6994d6a5ce3a5e74937d7816208Johannes Weiner
826bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	down_read(&mm->mmap_sem);
836bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	vma = find_vma(mm, address);
846bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	if (!vma)
856bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin		goto bad_area;
866bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	if (vma->vm_start <= address)
876bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin		goto good_area;
886bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	if (!(vma->vm_flags & VM_GROWSDOWN))
896bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin		goto bad_area;
906bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	if (expand_stack(vma, address))
916bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin		goto bad_area;
926bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	/*
936bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	* Ok, we have a good vm_area for this memory access, so
946bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	* we can handle it..
956bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	 */
966bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqingood_area:
976bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	info.si_code = SEGV_ACCERR;
986bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin
996bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	if (write) {
1006bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin		if (!(vma->vm_flags & VM_WRITE))
1016bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin			goto bad_area;
102759496ba6407c6994d6a5ce3a5e74937d7816208Johannes Weiner		flags |= FAULT_FLAG_WRITE;
1036bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	} else {
1046bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin		if (!(vma->vm_flags & (VM_READ | VM_WRITE | VM_EXEC)))
1056bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin			goto bad_area;
1066bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	}
1076bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin
1086bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	/*
1096bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	* If for any reason at all we couldn't handle the fault,
1106bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	* make sure we exit gracefully rather than endlessly redo
1116bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	* the fault.
1126bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	*/
113759496ba6407c6994d6a5ce3a5e74937d7816208Johannes Weiner	fault = handle_mm_fault(mm, vma, address, flags);
1146bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	if (unlikely(fault & VM_FAULT_ERROR)) {
1156bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin		if (fault & VM_FAULT_OOM)
1166bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin			goto out_of_memory;
1176bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin		else if (fault & VM_FAULT_SIGBUS)
1186bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin			goto do_sigbus;
1196bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin		BUG();
1206bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	}
1216bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	if (fault & VM_FAULT_MAJOR)
1226bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin		tsk->maj_flt++;
1236bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	else
1246bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin		tsk->min_flt++;
1256bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin
1266bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	up_read(&mm->mmap_sem);
1276bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	return;
1286bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin
1296bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	/*
1306bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	* Something tried to access memory that isn't in our memory map..
1316bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	* Fix it, but check if it's kernel or user first..
1326bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	 */
1336bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqinbad_area:
1346bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	up_read(&mm->mmap_sem);
1356bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin
1366bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqinbad_area_nosemaphore:
1376bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	/* User mode accesses just cause a SIGSEGV */
1386bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	if (user_mode(regs)) {
1396bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin		tsk->thread.cp0_badvaddr = address;
1406bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin		tsk->thread.error_code = write;
1416bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin		info.si_signo = SIGSEGV;
1426bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin		info.si_errno = 0;
1436bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin		/* info.si_code has been set above */
1446bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin		info.si_addr = (void __user *) address;
1456bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin		force_sig_info(SIGSEGV, &info, tsk);
1466bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin		return;
1476bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	}
1486bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin
1496bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqinno_context:
1506bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	/* Are we prepared to handle this kernel fault? */
1516bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	if (fixup_exception(regs)) {
1526bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin		current->thread.cp0_baduaddr = address;
1536bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin		return;
1546bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	}
1556bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin
1566bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	/*
1576bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	* Oops. The kernel tried to access some bad page. We'll have to
1586bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	* terminate things with extreme prejudice.
1596bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	*/
1606bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	bust_spinlocks(1);
1616bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin
1626bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	printk(KERN_ALERT "CPU %d Unable to handle kernel paging request at "
1636bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin			"virtual address %0*lx, epc == %0*lx, ra == %0*lx\n",
1646bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin			0, field, address, field, regs->cp0_epc,
1656bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin			field, regs->regs[3]);
1666bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	die("Oops", regs);
1676bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin
1686bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	/*
1696bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	* We ran out of memory, or some other thing happened to us that made
1706bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	* us unable to handle the page fault gracefully.
1716bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	*/
1726bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqinout_of_memory:
1736bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	up_read(&mm->mmap_sem);
174609838cfed972d49a65aac7923a9ff5cbe482e30Johannes Weiner	if (!user_mode(regs))
175609838cfed972d49a65aac7923a9ff5cbe482e30Johannes Weiner		goto no_context;
176609838cfed972d49a65aac7923a9ff5cbe482e30Johannes Weiner	pagefault_out_of_memory();
177609838cfed972d49a65aac7923a9ff5cbe482e30Johannes Weiner	return;
1786bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin
1796bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqindo_sigbus:
1806bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	up_read(&mm->mmap_sem);
1816bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	/* Kernel mode? Handle exceptions or die */
1826bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	if (!user_mode(regs))
1836bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin		goto no_context;
1846bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	else
1856bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	/*
1866bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	* Send a sigbus, regardless of whether we were in kernel
1876bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	* or user mode.
1886bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	*/
1896bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	tsk->thread.cp0_badvaddr = address;
1906bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	info.si_signo = SIGBUS;
1916bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	info.si_errno = 0;
1926bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	info.si_code = BUS_ADRERR;
1936bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	info.si_addr = (void __user *) address;
1946bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	force_sig_info(SIGBUS, &info, tsk);
1956bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	return;
1966bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqinvmalloc_fault:
1976bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	{
1986bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin		/*
1996bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin		* Synchronize this task's top level page-table
2006bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin		* with the 'reference' page table.
2016bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin		*
2026bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin		* Do _not_ use "tsk" here. We might be inside
2036bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin		* an interrupt in the middle of a task switch..
2046bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin		*/
2056bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin		int offset = __pgd_offset(address);
2066bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin		pgd_t *pgd, *pgd_k;
2076bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin		pud_t *pud, *pud_k;
2086bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin		pmd_t *pmd, *pmd_k;
2096bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin		pte_t *pte_k;
2106bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin
2116bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin		pgd = (pgd_t *) pgd_current + offset;
2126bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin		pgd_k = init_mm.pgd + offset;
2136bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin
2146bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin		if (!pgd_present(*pgd_k))
2156bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin			goto no_context;
2166bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin		set_pgd(pgd, *pgd_k);
2176bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin
2186bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin		pud = pud_offset(pgd, address);
2196bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin		pud_k = pud_offset(pgd_k, address);
2206bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin		if (!pud_present(*pud_k))
2216bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin			goto no_context;
2226bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin
2236bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin		pmd = pmd_offset(pud, address);
2246bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin		pmd_k = pmd_offset(pud_k, address);
2256bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin		if (!pmd_present(*pmd_k))
2266bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin			goto no_context;
2276bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin		set_pmd(pmd, *pmd_k);
2286bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin
2296bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin		pte_k = pte_offset_kernel(pmd_k, address);
2306bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin		if (!pte_present(*pte_k))
2316bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin			goto no_context;
2326bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin		return;
2336bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin	}
2346bc9a3966f0395419b09b2ec90f89f7f00341b37Chen Liqin}
235