set_fiq_handler: Bad mode in data abort handler detected (mmu translation fault)
Nicolas Pitre
nicolas.pitre at linaro.org
Mon May 12 12:06:04 PDT 2014
On Mon, 12 May 2014, Tim Sander wrote:
> I did an prefaulting for each available processes:
> for_each_process(process)
> {
> printk("process: %s [%d]\n",process->comm,process->pid);
> if(process->mm) {
> switch_mm(old_process->mm,process->mm,process);
> ioread32(priv->my_hardware); // access the memory, prefault mmu
> old_process = process;
> }
> }
> but still i get the the "Bad mode in data abort":
> Bad mode in data abort handler detected
> Internal error: Oops - bad mode: 0 [#1] PREEMPT SMP ARM
> Modules linked in: firq(O+) ipv6
> CPU: 0 PID: 0 Comm: swapper/0 Tainted: G O 3.12.0-xilinx-00005-gc9455c0-dirty #97
> task: c05cb420 ti: c05c0000 task.ti: c05c0000
> PC is at 0xe3fc0000
> LR is at arch_cpu_idle+0x20/0x2c
> pc : [<e3fc0000>] lr : [<c000f344>] psr: 600701d1
> sp : c05c1f70 ip : 00000000 fp : 00000000
> r10: 00000000 r9 : 413fc090 r8 : c0a7b4c0
> r7 : c05b6088 r6 : c0412348 r5 : c06008c0 r4 : c05c0000
> r3 : 00000000 r2 : 00000000 r1 : 00000000 r0 : c0a7e9f8
> Flags: nZCv IRQs off FIQs off Mode FIQ_32 ISA ARM Segment kernel
> Control: 18c5387d Table: 1ec2c04a DAC: 00000015
> Process swapper/0 (pid: 0, stack limit = 0xc05c0240)
> Stack: (0xc05c1f70 to 0xc05c2000)
> 1f60: c0a7e9f8 00000000 00000000 00000000
> 1f80: c05c0000 c06008c0 c0412348 c05b6088 c0a7b4c0 413fc090 00000000 00000000
> 1fa0: 00000000 c05c1f70 c000f344 e3fc0000 600701d1 ffffffff 00000000 c0056748
> 1fc0: c0414a30 c0592a60 ffffffff ffffffff c0592574 00000000 00000000 c05b6088
> 1fe0: 18c5387d c05c83cc c05b6084 c05cc440 0000406a 00008074 00000000 00000000
> [<c000f344>] (arch_cpu_idle+0x20/0x2c) from [<00000000>] ( (null))
> Code: bad PC value
> ---[ end trace 38f263d4b2076bcb ]---
>
> But then i realized that its always swapper/0 which is faulting. But i don't see a pid 0 process
> in my for_each_process loop. So i tried some special handling for pid 0 to also prefault it:
>
> process = pid_task(&init_struct_pid, PIDTYPE_PID);
> if(process) {
> printk("process: %s [%d]\n",process->comm,process->pid);
> switch_mm(current_task->mm,process->mm,process);
> ioread32(priv->my_hardware); // access the memory, prefault mmu
> switch_mm(process->mm,current_task->mm,current_task);
> } else printk("process pid prefault failed\n"); //<this path is taken
>
> But it seems that the scheduler pid struct has no process associated. So its
> not possible to get the mmu_struct for the pid 0. The structure can't be
> implicit or otherwise there should be an mmu entry due to the prefaulting done
> or due to the static mapping. So it seems there is an MMU table which is not
> associated with any process and is used during scheduler/swapper work...
> but where is it hiding?
The mmu_struct for PID 0 is at &init_mm.
Try: switch_mm(current_task->mm, &init_mm, NULL);
Nicolas
More information about the linux-arm-kernel
mailing list