Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9b87ed79 authored by Hirokazu Takata's avatar Hirokazu Takata Committed by Linus Torvalds
Browse files

[PATCH] m32r: fix do_page_fault and update_mmu_cache



Fix do_page_fault and update_mmu_cache.

  * Fix do_page_fault (vmalloc_fault:) to pass error_code correctly
    to update_mmu_cache by using a thread-fault code for all m32r chips.

  * Fix update_mmu_cache for OPSP chip
    - #ifdef CONFIG_CHIP_OPSP portion is a workaround of OPSP;
      Add a notfound-case operation to update_mmu_cache for OPSP
      like other m32r chip.
    - Fix pte_data that was not initialized if no entry found.

Signed-off-by: default avatarKazuhiro Inaoka <inaoka@linux-m32r.org>
Signed-off-by: default avatarHirokazu Takata <takata@linux-m32r.org>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 9674dcf7
Loading
Loading
Loading
Loading
+19 −21
Original line number Diff line number Diff line
@@ -362,8 +362,10 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code,
		if (!pte_present(*pte_k))
			goto no_context;

		addr = (address & PAGE_MASK) | (error_code & ACE_INSTRUCTION);
		addr = (address & PAGE_MASK);
		set_thread_fault_code(error_code);
		update_mmu_cache(NULL, addr, *pte_k);
		set_thread_fault_code(0);
		return;
	}
}
@@ -377,7 +379,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code,
void update_mmu_cache(struct vm_area_struct *vma, unsigned long vaddr,
	pte_t pte)
{
	unsigned long *entry1, *entry2;
	volatile unsigned long *entry1, *entry2;
	unsigned long pte_data, flags;
	unsigned int *entry_dat;
	int inst = get_thread_fault_code() & ACE_INSTRUCTION;
@@ -391,11 +393,12 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long vaddr,

	vaddr = (vaddr & PAGE_MASK) | get_asid();

	pte_data = pte_val(pte);

#ifdef CONFIG_CHIP_OPSP
	entry1 = (unsigned long *)ITLB_BASE;
	for (i = 0; i < NR_TLB_ENTRIES; i++) {
		if (*entry1++ == vaddr) {
	                pte_data = pte_val(pte);
			set_tlb_data(entry1, pte_data);
			break;
		}
@@ -404,17 +407,12 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long vaddr,
	entry2 = (unsigned long *)DTLB_BASE;
	for (i = 0; i < NR_TLB_ENTRIES; i++) {
		if (*entry2++ == vaddr) {
	                pte_data = pte_val(pte);
			set_tlb_data(entry2, pte_data);
			break;
		}
		entry2++;
	}
	local_irq_restore(flags);
	return;
#else
	pte_data = pte_val(pte);

	/*
	 * Update TLB entries
	 *  entry1: ITLB entry address
@@ -439,6 +437,7 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long vaddr,
		"i" (MSVA_offset), "i" (MTOP_offset), "i" (MIDXI_offset)
		: "r4", "memory"
	);
#endif

	if ((!inst && entry2 >= DTLB_END) || (inst && entry1 >= ITLB_END))
		goto notfound;
@@ -482,7 +481,6 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long vaddr,
	set_tlb_data(entry1, pte_data);

	goto found;
#endif
}

/*======================================================================*