aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-12-06 11:42:13 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-12-06 11:42:13 -0500
commit04c5decdc0aecde43bf44860484f26ee0691335f (patch)
tree16e1e9982c090c78a471ab43e62d30824412437b
parentd91fa971285a3ac33b4e8af6cea7c455543e2599 (diff)
parentc90e6fbb220d44988cb65af3707367c57cdb65a8 (diff)
Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-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()
-rw-r--r--arch/mips/include/asm/hugetlb.h12
-rw-r--r--arch/mips/kernel/cpu-probe.c1
-rw-r--r--arch/mips/kernel/entry.S7
-rw-r--r--arch/mips/kernel/scall64-n32.S6
-rw-r--r--arch/mips/mm/tlb-r4k.c18
5 files changed, 24 insertions, 20 deletions
diff --git a/arch/mips/include/asm/hugetlb.h b/arch/mips/include/asm/hugetlb.h
index bd94946a18f3..ef99db994c2f 100644
--- a/arch/mips/include/asm/hugetlb.h
+++ b/arch/mips/include/asm/hugetlb.h
@@ -95,7 +95,17 @@ static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
95 pte_t *ptep, pte_t pte, 95 pte_t *ptep, pte_t pte,
96 int dirty) 96 int dirty)
97{ 97{
98 return ptep_set_access_flags(vma, addr, ptep, pte, dirty); 98 int changed = !pte_same(*ptep, pte);
99
100 if (changed) {
101 set_pte_at(vma->vm_mm, addr, ptep, pte);
102 /*
103 * There could be some standard sized pages in there,
104 * get them all.
105 */
106 flush_tlb_range(vma, addr, addr + HPAGE_SIZE);
107 }
108 return changed;
99} 109}
100 110
101static inline pte_t huge_ptep_get(pte_t *ptep) 111static inline pte_t huge_ptep_get(pte_t *ptep)
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index b1fb7af3c350..cce3782c96c9 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -510,7 +510,6 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
510 c->cputype = CPU_R3000A; 510 c->cputype = CPU_R3000A;
511 __cpu_name[cpu] = "R3000A"; 511 __cpu_name[cpu] = "R3000A";
512 } 512 }
513 break;
514 } else { 513 } else {
515 c->cputype = CPU_R3000; 514 c->cputype = CPU_R3000;
516 __cpu_name[cpu] = "R3000"; 515 __cpu_name[cpu] = "R3000";
diff --git a/arch/mips/kernel/entry.S b/arch/mips/kernel/entry.S
index a6c133212003..9b00362f32f6 100644
--- a/arch/mips/kernel/entry.S
+++ b/arch/mips/kernel/entry.S
@@ -36,6 +36,11 @@ FEXPORT(ret_from_exception)
36FEXPORT(ret_from_irq) 36FEXPORT(ret_from_irq)
37 LONG_S s0, TI_REGS($28) 37 LONG_S s0, TI_REGS($28)
38FEXPORT(__ret_from_irq) 38FEXPORT(__ret_from_irq)
39/*
40 * We can be coming here from a syscall done in the kernel space,
41 * e.g. a failed kernel_execve().
42 */
43resume_userspace_check:
39 LONG_L t0, PT_STATUS(sp) # returning to kernel mode? 44 LONG_L t0, PT_STATUS(sp) # returning to kernel mode?
40 andi t0, t0, KU_USER 45 andi t0, t0, KU_USER
41 beqz t0, resume_kernel 46 beqz t0, resume_kernel
@@ -162,7 +167,7 @@ work_notifysig: # deal with pending signals and
162 move a0, sp 167 move a0, sp
163 li a1, 0 168 li a1, 0
164 jal do_notify_resume # a2 already loaded 169 jal do_notify_resume # a2 already loaded
165 j resume_userspace 170 j resume_userspace_check
166 171
167FEXPORT(syscall_exit_partial) 172FEXPORT(syscall_exit_partial)
168 local_irq_disable # make sure need_resched doesn't 173 local_irq_disable # make sure need_resched doesn't
diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S
index f6ba8381ee01..86ec03f0e00c 100644
--- a/arch/mips/kernel/scall64-n32.S
+++ b/arch/mips/kernel/scall64-n32.S
@@ -397,14 +397,14 @@ EXPORT(sysn32_call_table)
397 PTR sys_timerfd_create 397 PTR sys_timerfd_create
398 PTR compat_sys_timerfd_gettime /* 6285 */ 398 PTR compat_sys_timerfd_gettime /* 6285 */
399 PTR compat_sys_timerfd_settime 399 PTR compat_sys_timerfd_settime
400 PTR sys_signalfd4 400 PTR compat_sys_signalfd4
401 PTR sys_eventfd2 401 PTR sys_eventfd2
402 PTR sys_epoll_create1 402 PTR sys_epoll_create1
403 PTR sys_dup3 /* 6290 */ 403 PTR sys_dup3 /* 6290 */
404 PTR sys_pipe2 404 PTR sys_pipe2
405 PTR sys_inotify_init1 405 PTR sys_inotify_init1
406 PTR sys_preadv 406 PTR compat_sys_preadv
407 PTR sys_pwritev 407 PTR compat_sys_pwritev
408 PTR compat_sys_rt_tgsigqueueinfo /* 6295 */ 408 PTR compat_sys_rt_tgsigqueueinfo /* 6295 */
409 PTR sys_perf_event_open 409 PTR sys_perf_event_open
410 PTR sys_accept4 410 PTR sys_accept4
diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c
index 4b9b935a070e..88e79ad6f811 100644
--- a/arch/mips/mm/tlb-r4k.c
+++ b/arch/mips/mm/tlb-r4k.c
@@ -120,18 +120,11 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
120 120
121 if (cpu_context(cpu, mm) != 0) { 121 if (cpu_context(cpu, mm) != 0) {
122 unsigned long size, flags; 122 unsigned long size, flags;
123 int huge = is_vm_hugetlb_page(vma);
124 123
125 ENTER_CRITICAL(flags); 124 ENTER_CRITICAL(flags);
126 if (huge) { 125 start = round_down(start, PAGE_SIZE << 1);
127 start = round_down(start, HPAGE_SIZE); 126 end = round_up(end, PAGE_SIZE << 1);
128 end = round_up(end, HPAGE_SIZE); 127 size = (end - start) >> (PAGE_SHIFT + 1);
129 size = (end - start) >> HPAGE_SHIFT;
130 } else {
131 start = round_down(start, PAGE_SIZE << 1);
132 end = round_up(end, PAGE_SIZE << 1);
133 size = (end - start) >> (PAGE_SHIFT + 1);
134 }
135 if (size <= current_cpu_data.tlbsize/2) { 128 if (size <= current_cpu_data.tlbsize/2) {
136 int oldpid = read_c0_entryhi(); 129 int oldpid = read_c0_entryhi();
137 int newpid = cpu_asid(cpu, mm); 130 int newpid = cpu_asid(cpu, mm);
@@ -140,10 +133,7 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
140 int idx; 133 int idx;
141 134
142 write_c0_entryhi(start | newpid); 135 write_c0_entryhi(start | newpid);
143 if (huge) 136 start += (PAGE_SIZE << 1);
144 start += HPAGE_SIZE;
145 else
146 start += (PAGE_SIZE << 1);
147 mtc0_tlbw_hazard(); 137 mtc0_tlbw_hazard();
148 tlb_probe(); 138 tlb_probe();
149 tlb_probe_hazard(); 139 tlb_probe_hazard();