kernel/arm/exception.c
/*
 * Page fault when accessing data.
 * When the previous mode is USR or SYS acquire the kernel mutex
 * Only other time is in SVC mode with kernel lock already acquired by
 * this process AND the try/catch pc/sp is initialized.
 * Other modes and times it is a kernel panic.
 */
Page fault when accessing data.
When the previous mode is USR or SYS acquire the kernel mutex
Only other time is in SVC mode with kernel lock already acquired by
this process AND the try/catch pc/sp is initialized.
Other modes and times it is a kernel panic.
Page fault when accessing data . When the previous mode is USR or SYS acquire the kernel mutex Only other time is in SVC mode with kernel lock already acquired by this process AND the try / catch pc / sp is initialized . Other modes and times it is a kernel panic .
void DataAbortHandler(struct UserContext *context) {
  bits32_t dfsr;
  bits32_t access;
  vm_addr fault_addr;
  uint32_t mode;
  struct Process *current;
  current = GetCurrentProcess();
  dfsr = GetDFSR();
  fault_addr = GetFAR();
  mode = context->cpsr & CPSR_MODE_MASK;
  if (mode == USR_MODE || mode == SYS_MODE) {
    KernelLock();
  } else if (bkl_owner != current) {
    DisableInterrupts();
    PrintUserContext(context);
    Error("fault addr = %08x", fault_addr);
    KernelPanic();
  }
  if (dfsr & DFSR_RW)
    access = PROT_WRITE;
  else
    access = PROT_READ;
  if (PageFault(fault_addr, access) != 0) {
    if (mode == SVC_MODE && current->catch_state.pc != 0xdeadbeef) {
      Error("Page fault failed during copyin/copyout");
      context->pc = current->catch_state.pc;
      current->catch_state.pc = 0xdeadbeef;
    } else if (mode == USR_MODE || mode == SYS_MODE) {
      PrintUserContext(context);
      Error("? USER Data Abort: fault addr = %08x", fault_addr);
      current->signal.si_code[SIGSEGV-1] = 0;    
      current->signal.sigsegv_ptr = fault_addr;
      Kill(current->pid, SIGSEGV);
    } else {
      PrintUserContext(context);
      Error("fault addr = %08x", fault_addr);
      KernelPanic();
    }
  }
  KASSERT(context->pc != 0);
  if (mode == USR_MODE || mode == SYS_MODE) {
    CheckSignals(context);
    if (bkl_locked == FALSE) {
      DisableInterrupts();
      PrintUserContext(context);
      KernelPanic();
    }
    KernelUnlock();
  }
}
void DataAbortHandler ( struct UserContext * context ) { bits32_t dfsr ; bits32_t access ; vm_addr fault_addr ; uint32_t mode ; struct Process * current ; current = GetCurrentProcess ( ) ; dfsr = GetDFSR ( ) ; fault_addr = GetFAR ( ) ; mode = context -> cpsr & CPSR_MODE_MASK ; if ( mode == USR_MODE || mode == SYS_MODE ) { KernelLock ( ) ; } else if ( bkl_owner != current ) { DisableInterrupts ( ) ; PrintUserContext ( context ) ; Error ( " " , fault_addr ) ; KernelPanic ( ) ; } if ( dfsr & DFSR_RW ) access = PROT_WRITE ; else access = PROT_READ ; if ( PageFault ( fault_addr , access ) != 0 ) { if ( mode == SVC_MODE && current -> catch_state . pc != 0xdeadbeef ) { Error ( " " ) ; context -> pc = current -> catch_state . pc ; current -> catch_state . pc = 0xdeadbeef ; } else if ( mode == USR_MODE || mode == SYS_MODE ) { PrintUserContext ( context ) ; Error ( " " , fault_addr ) ; current -> signal . si_code [ SIGSEGV - 1 ] = 0 ; current -> signal . sigsegv_ptr = fault_addr ; Kill ( current -> pid , SIGSEGV ) ; } else { PrintUserContext ( context ) ; Error ( " " , fault_addr ) ; KernelPanic ( ) ; } } KASSERT ( context -> pc != 0 ) ; if ( mode == USR_MODE || mode == SYS_MODE ) { CheckSignals ( context ) ; if ( bkl_locked == FALSE ) { DisableInterrupts ( ) ; PrintUserContext ( context ) ; KernelPanic ( ) ; } KernelUnlock ( ) ; } }
Page fault when accessing data.
Page fault when accessing data .
// FIXME: Must not enable interrupts before getting above registers?
 // TODO: Could be access bit?
