diff options
Diffstat (limited to 'arch/nios2')
-rw-r--r-- | arch/nios2/include/asm/pgtable.h | 22 | ||||
-rw-r--r-- | arch/nios2/include/asm/syscall.h | 16 | ||||
-rw-r--r-- | arch/nios2/kernel/cpuinfo.c | 5 | ||||
-rw-r--r-- | arch/nios2/mm/tlb.c | 18 |
4 files changed, 44 insertions, 17 deletions
diff --git a/arch/nios2/include/asm/pgtable.h b/arch/nios2/include/asm/pgtable.h index eab87c6beacb..e98578e27e26 100644 --- a/arch/nios2/include/asm/pgtable.h +++ b/arch/nios2/include/asm/pgtable.h @@ -221,12 +221,6 @@ static inline void pte_clear(struct mm_struct *mm, * Conversion functions: convert a page and protection to a page entry, * and a page entry and page directory to the page they refer to. */ -#define mk_pte(page, prot) (pfn_pte(page_to_pfn(page), prot)) - -/* - * Conversion functions: convert a page and protection to a page entry, - * and a page entry and page directory to the page they refer to. - */ #define pmd_phys(pmd) virt_to_phys((void *)pmd_val(pmd)) #define pmd_pfn(pmd) (pmd_phys(pmd) >> PAGE_SHIFT) #define pmd_page(pmd) (pfn_to_page(pmd_phys(pmd) >> PAGE_SHIFT)) @@ -291,4 +285,20 @@ void update_mmu_cache_range(struct vm_fault *vmf, struct vm_area_struct *vma, #define update_mmu_cache(vma, addr, ptep) \ update_mmu_cache_range(NULL, vma, addr, ptep, 1) +static inline int pte_same(pte_t pte_a, pte_t pte_b); + +#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS +static inline int ptep_set_access_flags(struct vm_area_struct *vma, + unsigned long address, pte_t *ptep, + pte_t entry, int dirty) +{ + if (!pte_same(*ptep, entry)) + set_ptes(vma->vm_mm, address, ptep, entry, 1); + /* + * update_mmu_cache will unconditionally execute, handling both + * the case that the PTE changed and the spurious fault case. + */ + return true; +} + #endif /* _ASM_NIOS2_PGTABLE_H */ diff --git a/arch/nios2/include/asm/syscall.h b/arch/nios2/include/asm/syscall.h index fff52205fb65..8e3eb1d689bb 100644 --- a/arch/nios2/include/asm/syscall.h +++ b/arch/nios2/include/asm/syscall.h @@ -15,6 +15,11 @@ static inline int syscall_get_nr(struct task_struct *task, struct pt_regs *regs) return regs->r2; } +static inline void syscall_set_nr(struct task_struct *task, struct pt_regs *regs, int nr) +{ + regs->r2 = nr; +} + static inline void syscall_rollback(struct task_struct *task, struct pt_regs *regs) { @@ -58,6 +63,17 @@ static inline void syscall_get_arguments(struct task_struct *task, *args = regs->r9; } +static inline void syscall_set_arguments(struct task_struct *task, + struct pt_regs *regs, const unsigned long *args) +{ + regs->r4 = *args++; + regs->r5 = *args++; + regs->r6 = *args++; + regs->r7 = *args++; + regs->r8 = *args++; + regs->r9 = *args; +} + static inline int syscall_get_arch(struct task_struct *task) { return AUDIT_ARCH_NIOS2; diff --git a/arch/nios2/kernel/cpuinfo.c b/arch/nios2/kernel/cpuinfo.c index 7b1e8f9128e9..55882feb6249 100644 --- a/arch/nios2/kernel/cpuinfo.c +++ b/arch/nios2/kernel/cpuinfo.c @@ -46,10 +46,7 @@ void __init setup_cpuinfo(void) cpuinfo.cpu_clock_freq = fcpu(cpu, "clock-frequency"); str = of_get_property(cpu, "altr,implementation", &len); - if (str) - strscpy(cpuinfo.cpu_impl, str, sizeof(cpuinfo.cpu_impl)); - else - strcpy(cpuinfo.cpu_impl, "<unknown>"); + strscpy(cpuinfo.cpu_impl, str ?: "<unknown>"); cpuinfo.has_div = of_property_read_bool(cpu, "altr,has-div"); cpuinfo.has_mul = of_property_read_bool(cpu, "altr,has-mul"); diff --git a/arch/nios2/mm/tlb.c b/arch/nios2/mm/tlb.c index f90ac35f05f3..a9cbe20f9e79 100644 --- a/arch/nios2/mm/tlb.c +++ b/arch/nios2/mm/tlb.c @@ -144,10 +144,11 @@ static void flush_tlb_one(unsigned long addr) if (((pteaddr >> 2) & 0xfffff) != (addr >> PAGE_SHIFT)) continue; + tlbmisc = RDCTL(CTL_TLBMISC); pr_debug("Flush entry by writing way=%dl pid=%ld\n", - way, (pid_misc >> TLBMISC_PID_SHIFT)); + way, ((tlbmisc >> TLBMISC_PID_SHIFT) & TLBMISC_PID_MASK)); - tlbmisc = TLBMISC_WE | (way << TLBMISC_WAY_SHIFT); + tlbmisc = TLBMISC_WE | (way << TLBMISC_WAY_SHIFT) | (tlbmisc & TLBMISC_PID); WRCTL(CTL_TLBMISC, tlbmisc); WRCTL(CTL_PTEADDR, pteaddr_invalid(addr)); WRCTL(CTL_TLBACC, 0); @@ -237,7 +238,8 @@ void flush_tlb_pid(unsigned long mmu_pid) if (pid != mmu_pid) continue; - tlbmisc = TLBMISC_WE | (way << TLBMISC_WAY_SHIFT); + tlbmisc = TLBMISC_WE | (way << TLBMISC_WAY_SHIFT) | + (pid << TLBMISC_PID_SHIFT); WRCTL(CTL_TLBMISC, tlbmisc); WRCTL(CTL_TLBACC, 0); } @@ -272,15 +274,17 @@ void flush_tlb_all(void) /* remember pid/way until we return */ get_misc_and_pid(&org_misc, &pid_misc); - /* Start at way 0, way is auto-incremented after each TLBACC write */ - WRCTL(CTL_TLBMISC, TLBMISC_WE); - /* Map each TLB entry to physcal address 0 with no-access and a bad ptbase */ for (line = 0; line < cpuinfo.tlb_num_lines; line++) { WRCTL(CTL_PTEADDR, pteaddr_invalid(addr)); - for (way = 0; way < cpuinfo.tlb_num_ways; way++) + for (way = 0; way < cpuinfo.tlb_num_ways; way++) { + // Code such as replace_tlb_one_pid assumes that no duplicate entries exist + // for a single address across ways, so also use way as a dummy PID + WRCTL(CTL_TLBMISC, TLBMISC_WE | (way << TLBMISC_WAY_SHIFT) | + (way << TLBMISC_PID_SHIFT)); WRCTL(CTL_TLBACC, 0); + } addr += PAGE_SIZE; } |