Skip to content
  • Victor Kamensky's avatar
    ARM: 7882/1: mm: fix __phys_to_virt to work with 64 bit phys_addr_t in BE case · 139cc2ba
    Victor Kamensky authored
    
    
    Make sure that inline assembler that expects 'r' operand
    receives 32 bit value.
    
    Before this fix in case of CONFIG_ARCH_PHYS_ADDR_T_64BIT and
    CONFIG_ARM_PATCH_PHYS_VIRT __phys_to_virt function passed 64 bit
    value to __pv_stub inline assembler where 'r' operand is
    expected. Compiler behavior in such case is not well specified.
    It worked in little endian case, but in big endian case
    incorrect code was generated, where compiler confused which
    part of 64 bit value it needed to modify. For example BE
    snippet looked like this:
    
    N:0x80904E08 : MOV      r2,#0
    N:0x80904E0C : SUB      r2,r2,#0x81000000
    
    when LE similar code looked like this
    
    N:0x808FCE2C : MOV      r2,r0
    N:0x808FCE30 : SUB      r2,r2,#0xc0, 8 ; #0xc0000000
    
    Note 'r0' register is va that have to be translated into phys
    
    To avoid this situation use explicit cast to 'unsigned long',
    which explicitly discard upper part of phys address and convert
    value to 32 bit. Also add comment so such cast will not be
    removed in the future.
    
    Signed-off-by: default avatarVictor Kamensky <victor.kamensky@linaro.org>
    Acked-by: default avatarSantosh Shilimkar <santosh.shilimkar@ti.com>
    Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
    139cc2ba