• P
    Fix masking of PC lower bits when doing exception returns · fb0e8e79
    Peter Maydell 提交于
    In commit 9b6a3ea7 store_reg() was changed to mask
    both bits 0 and 1 of the new PC value when in ARM mode.
    Unfortunately this broke the exception return code paths
    when doing a return from ARM mode to Thumb mode: in some
    of these we write a new CPSR including new Thumb mode
    bit via gen_helper_cpsr_write_eret(), and then use store_reg()
    to write the new PC. In this case if the new CPSR specified
    Thumb mode then masking bit 1 of the PC is incorrect
    (these code paths correspond to the v8 ARM ARM pseudocode
    function AArch32.ExceptionReturn(), which always aligns the
    new PC appropriately for the new instruction set state).
    
    Instead of using store_reg() in exception-return code paths,
    call a new store_pc_exc_ret() which stores the raw new PC
    value to env->regs[15], and then mask it appropriately in
    the subsequent helper_cpsr_write_eret() where the new
    env->thumb state is available.
    
    This fixes a bug introduced by 9b6a3ea7 which caused
    crashes/hangs or otherwise bad behaviour for Linux when
    userspace was using Thumb.
    Reported-by: NJerome Forissier <jerome.forissier@linaro.org>
    Signed-off-by: NPeter Maydell <peter.maydell@linaro.org>
    Message-id: 1476113163-24578-1-git-send-email-peter.maydell@linaro.org
    fb0e8e79
op_helper.c 38.2 KB