Skip to content

Commit

Permalink
Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upst…
Browse files Browse the repository at this point in the history
…ream-linus

Pull MIPS fixes from Ralf Baechle:
 "These are the fixes for the N32 syscall bugs found by Al, an
  extraneous break that broke detection for R3000 and R3081 processors,
  an endless loop processing signals for kernel task (x86 received the
  same fix a while ago) and a fix for transparent huge page which took
  ages to track down because it was so hard to come up with a workable
  test case."

* 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus:
  MIPS: Fix endless loop when processing signals for kernel tasks
  MIPS: R3000/R3081: Fix CPU detection.
  MIPS: N32: Fix signalfd4 syscall entry point
  MIPS: N32: Fix preadv(2) and pwritev(2) entry points.
  MIPS: Avoid mcheck by flushing page range in huge_ptep_set_access_flags()
  • Loading branch information
torvalds committed Dec 6, 2012
2 parents d91fa97 + c90e6fb commit 04c5dec
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 20 deletions.
12 changes: 11 additions & 1 deletion arch/mips/include/asm/hugetlb.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,17 @@ static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
pte_t *ptep, pte_t pte,
int dirty)
{
return ptep_set_access_flags(vma, addr, ptep, pte, dirty);
int changed = !pte_same(*ptep, pte);

if (changed) {
set_pte_at(vma->vm_mm, addr, ptep, pte);
/*
* There could be some standard sized pages in there,
* get them all.
*/
flush_tlb_range(vma, addr, addr + HPAGE_SIZE);
}
return changed;
}

static inline pte_t huge_ptep_get(pte_t *ptep)
Expand Down
1 change: 0 additions & 1 deletion arch/mips/kernel/cpu-probe.c
Original file line number Diff line number Diff line change
Expand Up @@ -510,7 +510,6 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
c->cputype = CPU_R3000A;
__cpu_name[cpu] = "R3000A";
}
break;
} else {
c->cputype = CPU_R3000;
__cpu_name[cpu] = "R3000";
Expand Down
7 changes: 6 additions & 1 deletion arch/mips/kernel/entry.S
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ FEXPORT(ret_from_exception)
FEXPORT(ret_from_irq)
LONG_S s0, TI_REGS($28)
FEXPORT(__ret_from_irq)
/*
* We can be coming here from a syscall done in the kernel space,
* e.g. a failed kernel_execve().
*/
resume_userspace_check:
LONG_L t0, PT_STATUS(sp) # returning to kernel mode?
andi t0, t0, KU_USER
beqz t0, resume_kernel
Expand Down Expand Up @@ -162,7 +167,7 @@ work_notifysig: # deal with pending signals and
move a0, sp
li a1, 0
jal do_notify_resume # a2 already loaded
j resume_userspace
j resume_userspace_check

FEXPORT(syscall_exit_partial)
local_irq_disable # make sure need_resched doesn't
Expand Down
6 changes: 3 additions & 3 deletions arch/mips/kernel/scall64-n32.S
Original file line number Diff line number Diff line change
Expand Up @@ -397,14 +397,14 @@ EXPORT(sysn32_call_table)
PTR sys_timerfd_create
PTR compat_sys_timerfd_gettime /* 6285 */
PTR compat_sys_timerfd_settime
PTR sys_signalfd4
PTR compat_sys_signalfd4
PTR sys_eventfd2
PTR sys_epoll_create1
PTR sys_dup3 /* 6290 */
PTR sys_pipe2
PTR sys_inotify_init1
PTR sys_preadv
PTR sys_pwritev
PTR compat_sys_preadv
PTR compat_sys_pwritev
PTR compat_sys_rt_tgsigqueueinfo /* 6295 */
PTR sys_perf_event_open
PTR sys_accept4
Expand Down
18 changes: 4 additions & 14 deletions arch/mips/mm/tlb-r4k.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,18 +120,11 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,

if (cpu_context(cpu, mm) != 0) {
unsigned long size, flags;
int huge = is_vm_hugetlb_page(vma);

ENTER_CRITICAL(flags);
if (huge) {
start = round_down(start, HPAGE_SIZE);
end = round_up(end, HPAGE_SIZE);
size = (end - start) >> HPAGE_SHIFT;
} else {
start = round_down(start, PAGE_SIZE << 1);
end = round_up(end, PAGE_SIZE << 1);
size = (end - start) >> (PAGE_SHIFT + 1);
}
start = round_down(start, PAGE_SIZE << 1);
end = round_up(end, PAGE_SIZE << 1);
size = (end - start) >> (PAGE_SHIFT + 1);
if (size <= current_cpu_data.tlbsize/2) {
int oldpid = read_c0_entryhi();
int newpid = cpu_asid(cpu, mm);
Expand All @@ -140,10 +133,7 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
int idx;

write_c0_entryhi(start | newpid);
if (huge)
start += HPAGE_SIZE;
else
start += (PAGE_SIZE << 1);
start += (PAGE_SIZE << 1);
mtc0_tlbw_hazard();
tlb_probe();
tlb_probe_hazard();
Expand Down

0 comments on commit 04c5dec

Please sign in to comment.