[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: Kazuhiro Inaoka <inaoka@linux-m32r.org>
Signed-off-by: Hirokazu Takata <takata@linux-m32r.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
			
			
This commit is contained in:
		
							parent
							
								
									9674dcf795
								
							
						
					
					
						commit
						9b87ed7907
					
				| @ -362,8 +362,10 @@ vmalloc_fault: | ||||
| 		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 @@ vmalloc_fault: | ||||
| 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,30 +393,26 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long vaddr, | ||||
| 
 | ||||
| 	vaddr = (vaddr & PAGE_MASK) | get_asid(); | ||||
| 
 | ||||
| #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; | ||||
| 	        } | ||||
| 	        entry1++; | ||||
| 	} | ||||
| 	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); | ||||
| 
 | ||||
| #ifdef CONFIG_CHIP_OPSP | ||||
| 	entry1 = (unsigned long *)ITLB_BASE; | ||||
| 	for (i = 0; i < NR_TLB_ENTRIES; i++) { | ||||
| 		if (*entry1++ == vaddr) { | ||||
| 			set_tlb_data(entry1, pte_data); | ||||
| 			break; | ||||
| 		} | ||||
| 		entry1++; | ||||
| 	} | ||||
| 	entry2 = (unsigned long *)DTLB_BASE; | ||||
| 	for (i = 0; i < NR_TLB_ENTRIES; i++) { | ||||
| 		if (*entry2++ == vaddr) { | ||||
| 			set_tlb_data(entry2, pte_data); | ||||
| 			break; | ||||
| 		} | ||||
| 		entry2++; | ||||
| 	} | ||||
| #else | ||||
| 	/*
 | ||||
| 	 * 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 @@ notfound: | ||||
| 	set_tlb_data(entry1, pte_data); | ||||
| 
 | ||||
| 	goto found; | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| /*======================================================================*
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user