From owner-freebsd-arm@FreeBSD.ORG Sat Jan 12 22:16:03 2013 Return-Path: Delivered-To: arm@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by hub.freebsd.org (Postfix) with ESMTP id D95E0800 for ; Sat, 12 Jan 2013 22:16:03 +0000 (UTC) (envelope-from gonzo@id.bluezbox.com) Received: from id.bluezbox.com (id.bluezbox.com [88.198.91.248]) by mx1.freebsd.org (Postfix) with ESMTP id 7F776B01 for ; Sat, 12 Jan 2013 22:16:03 +0000 (UTC) Received: from [88.198.91.248] (helo=[IPv6:::1]) by id.bluezbox.com with esmtpsa (TLSv1:CAMELLIA256-SHA:256) (Exim 4.77 (FreeBSD)) (envelope-from ) id 1Tu9Mj-000HYU-Ur; Sat, 12 Jan 2013 14:15:55 -0800 Message-ID: <50F1E092.1050905@bluezbox.com> Date: Sat, 12 Jan 2013 14:15:46 -0800 From: Oleksandr Tymoshenko User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:17.0) Gecko/20130107 Thunderbird/17.0.2 MIME-Version: 1.0 To: okuno.kohji@jp.panasonic.com, arm@freebsd.org Subject: Fwd: arm: cpu_switch() has bug? References: <20130109.193945.561808600309975779.okuno.kohji@jp.panasonic.com> In-Reply-To: <20130109.193945.561808600309975779.okuno.kohji@jp.panasonic.com> X-Forwarded-Message-Id: <20130109.193945.561808600309975779.okuno.kohji@jp.panasonic.com> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Sender: gonzo@id.bluezbox.com X-Spam-Level: -- X-Spam-Report: Spam detection software, running on the system "id.bluezbox.com", has identified this incoming email as possible spam. The original message has been attached to this so you can view it (if it isn't spam) or label similar future email. If you have any questions, see The administrator of that system for details. Content preview: Forwarding this email to more appropriate mailing list. Someone on arm@ might know the answer -------- Original Message -------- Subject: arm: cpu_switch() has bug? Date: Wed, 09 Jan 2013 19:39:45 +0900 (JST) From: Kohji Okuno Organization: Panasonic Corporation To: freebsd-current@FreeBSD.org [...] Content analysis details: (-2.9 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -1.0 ALL_TRUSTED Passed through trusted hosts only via SMTP -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] X-BeenThere: freebsd-arm@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Porting FreeBSD to the StrongARM Processor List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 12 Jan 2013 22:16:03 -0000 Forwarding this email to more appropriate mailing list. Someone on arm@ might know the answer -------- Original Message -------- Subject: arm: cpu_switch() has bug? Date: Wed, 09 Jan 2013 19:39:45 +0900 (JST) From: Kohji Okuno Organization: Panasonic Corporation To: freebsd-current@FreeBSD.org Hi, I have doubt if cpu_switch() of arm has a bug. In swtch.S:L.334, if newtd->td_pcb (this is in stack pointer for kernel) has an address accessed first for the old(current) thread, data_abort_fault may occur. When data_abort_fault occurs, data_abort_handler() tries to solve this address from kernel_map. In this time, curthread and curpcb are already updated in swtch.S:L.223-231. As this result, data_abort_handler() will occur data_abort_fault in trap.c:L.301, again. When I check, in other CPUs, after updating the root pointer of MMU, curthread and curpcb are updated. Would you please check this? Thanks, Kohji Okuno <> 215 ENTRY(cpu_switch) 216 stmfd sp!, {r4-r7, lr} 217 mov r6, r2 /* Save the mutex */ 218 219 .Lswitch_resume: 220 /* rem: r0 = old lwp */ 221 /* rem: interrupts are disabled */ 222 223 /* Process is now on a processor. */ 224 /* We have a new curthread now so make a note it */ 225 GET_CURTHREAD_PTR(r7) 226 str r1, [r7] 227 228 /* Hook in a new pcb */ 229 GET_PCPU(r7) 230 ldr r2, [r1, #TD_PCB] 231 str r2, [r7, #PC_CURPCB] 232 233 /* rem: r1 = new process */ 234 /* rem: interrupts are enabled */ ==== SNIP ==== 298 /* rem: r2 = old PCB */ 299 /* rem: r9 = new PCB */ 300 /* rem: interrupts are enabled */ 301 302 #ifdef ARM_VFP_SUPPORT 303 /* 304 * vfp_store will clear pcpu->pc_vfpcthread, save 305 * registers and state, and modify the control as needed. 306 * a future exception will bounce the backup settings in the fp unit. 307 * XXX vfp_store can't change r4 308 */ 309 GET_PCPU(r7) 310 ldr r8, [r7, #(PC_VFPCTHREAD)] 311 cmp r4, r8 /* old thread used vfp? */ 312 bne 1f /* no, don't save */ 313 cmp r1, r4 /* same thread ? */ 314 beq 1f /* yes, skip vfp store */ 315 #ifdef SMP 316 ldr r8, [r7, #(PC_CPU)] /* last used on this cpu? */ 317 ldr r3, [r2, #(PCB_VFPCPU)] 318 cmp r8, r3 /* last cpu to use these registers? */ 319 bne 1f /* no. these values are stale */ 320 #endif 321 add r0, r2, #(PCB_VFPSTATE) 322 bl _C_LABEL(vfp_store) 323 1: 324 #endif /* ARM_VFP_SUPPORT */ 325 326 /* r1 now free! */ 327 328 /* Third phase : restore saved context */ 329 330 /* rem: r2 = old PCB */ 331 /* rem: r9 = new PCB */ 332 /* rem: interrupts are enabled */ 333 334 ldr r5, [r9, #(PCB_DACR)] /* r5 = new DACR */ 335 mov r2, #DOMAIN_CLIENT 336 cmp r5, r2, lsl #(PMAP_DOMAIN_KERNEL * 2) /* Sw to kernel thread? */ 337 beq .Lcs_context_switched /* Yup. Don't flush cache */ 338 mrc p15, 0, r0, c3, c0, 0 /* r0 = old DACR */ <> 224 void 225 data_abort_handler(trapframe_t *tf) 226 { 227 struct vm_map *map; 228 struct pcb *pcb; 229 struct thread *td; 230 u_int user, far, fsr; 231 vm_prot_t ftype; 232 void *onfault; 233 vm_offset_t va; 234 int error = 0; 235 struct ksig ksig; 236 struct proc *p; 237 238 239 /* Grab FAR/FSR before enabling interrupts */ 240 far = cpu_faultaddress(); 241 fsr = cpu_faultstatus(); 242 #if 0 243 printf("data abort: %p (from %p %p)\n", (void*)far, (void*)tf->tf_pc, 244 (void*)tf->tf_svc_lr); 245 #endif 246 247 /* Update vmmeter statistics */ 248 #if 0 249 vmexp.traps++; 250 #endif 251 252 td = curthread; 253 p = td->td_proc; 254 255 PCPU_INC(cnt.v_trap); 256 /* Data abort came from user mode? */ 257 user = TRAP_USERMODE(tf); 258 259 if (user) { 260 td->td_pticks = 0; 261 td->td_frame = tf; 262 if (td->td_ucred != td->td_proc->p_ucred) 263 cred_update_thread(td); 264 265 } 266 /* Grab the current pcb */ 267 pcb = td->td_pcb; ==== SNIP ==== 299 300 /* fusubailout is used by [fs]uswintr to avoid page faulting */ 301 if (__predict_false(pcb->pcb_onfault == fusubailout)) { 302 tf->tf_r0 = EFAULT; 303 tf->tf_pc = (register_t)(intptr_t) pcb->pcb_onfault; 304 return; 305 } _______________________________________________ freebsd-current@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-current To unsubscribe, send any mail to "freebsd-current-unsubscribe@freebsd.org"