Changeset b5851913 in mainline    
  
  
  
    - Timestamp:
- 
      2013-10-18T16:22:03Z
(12 years ago)    
- Author:
- Martin Decky <martin@…>
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- a1314ce9
- Parents:
- 0c96e6cb
- Message:
- 
      
fix kernel assertion (panic) on arm32 (BeagleBone and others) in frame_reference_add()
 
 
The macro PTE_GET_FRAME_ARCH() retrieves a physical frame number from the page table entry. Although the frame_base_addr member of the page table entry structure (pte_t) is declared as an unsigned bit field, due to the integer promotion rules the value is interpreted as a signed integer.
 
 
C99-§6.3.1.1: Boolean, characters, and integers
 
 
2: If an int can represent all values of the original type (as restricted by the width, for a bit-field), the value is converted to an int; otherwise, it is converted to an unsigned int. These are called the integer promotions. All other types are unchanged by the integer promotions.
 
 
 
 
Since the bitwise shift operations in PTE_GET_FRAME_ARCH() and especially in ADDR2PFN() (used by anon_share() in backend_anon.c) are applied on a signed integer, they create a false sign-extended (negative) physical frame number that is then passed to frame_reference_add(). This routine is obviously unable to find a valid physical memory zone for the malformed frame number and hits the assertion. The fix is to explicitly typecast the value in PTE_GET_FRAME_ARCH() as unsigned.
 
 
The original panic and stack trace for reference:
 
 
######> Kernel panic on cpu0 due to a failed assertion: <######
 frame_reference_add() at generic/src/mm/frame.c:976:
 znum != (size_t) -1
 
 
THE=0x802ca000: pe=1 thr=0x802c8000 task=0x802c1000 cpu=0x80292800
 as=0x8000112c magic=0xfacefeed
 0x802cbd2c: generic/src/debug/stacktrace.o:stack_trace()+0x0000001c
 0x802cbd5c: generic/src/debug/panic.o:panic_common()+0x000001b4
 0x802cbd94: generic/src/mm/frame.o:frame_reference_add()+0x000000a8
 0x802cbdf4: generic/src/mm/backend_anon.o:anon_share()+0x00000168
 0x802cbe44: generic/src/mm/as.o:as_area_share()+0x000001bc
 0x802cbe7c: generic/src/ipc/ops/sharein.o:answer_preprocess()+0x0000007c
 0x802cbeb4: generic/src/ipc/sysipc.o:answer_preprocess()+0x000000a4
 0x802cbf04: generic/src/ipc/sysipc.o:sys_ipc_answer_fast()+0x0000007c
 0x802cbf4c: generic/src/syscall/syscall.o:syscall_handler()+0x000000e0
 0x802cbf74: arch/arm32/src/exception.o:swi_exception()+0x00000034
 0x802cbfb4: generic/src/interrupt/interrupt.o:exc_dispatch()+0x00000144
 cpu0: halted
 
 
- Location:
- kernel/arch/arm32/include/arch/mm
- 
      Files:
    
- 
      
      
 
    
      Legend:
      
        - Unmodified
- Added
- Removed
 
  
    - 
      
      
        
          
        
        
          
            | r0c96e6cb | rb5851913 |  |  
            | 48 | 48 | (((pte_t *) (pte))->l0.descriptor_type != 0) |  
            | 49 | 49 | #define PTE_GET_FRAME_ARCH(pte) \ |  
            | 50 |  | ((( pte_t *) (pte))->l1.frame_base_addr<< FRAME_WIDTH) |  
            |  | 50 | (((uintptr_t) ((pte_t *) (pte))->l1.frame_base_addr) << FRAME_WIDTH) |  
            | 51 | 51 | #define PTE_WRITABLE_ARCH(pte) \ |  
            | 52 | 52 | (((pte_t *) (pte))->l1.access_permission_0 == PTE_AP_USER_RW_KERNEL_RW) |  
 
- 
      
      
        
          
        
        
          
            | r0c96e6cb | rb5851913 |  |  
            | 48 | 48 | (((pte_t *) (pte))->l0.descriptor_type != 0) |  
            | 49 | 49 | #define PTE_GET_FRAME_ARCH(pte) \ |  
            | 50 |  | ((( pte_t *) (pte))->l1.frame_base_addr<< FRAME_WIDTH) |  
            |  | 50 | (((uintptr_t) ((pte_t *) (pte))->l1.frame_base_addr) << FRAME_WIDTH) |  
            | 51 | 51 | #define PTE_WRITABLE_ARCH(pte) \ |  
            | 52 | 52 | (((pte_t *) (pte))->l1.access_permission_1 != PTE_AP1_RO) |