qemu-arm
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-arm] [PATCH 10/11] target-arm: Make mode switches from Hyp via


From: Sergey Fedorov
Subject: Re: [Qemu-arm] [PATCH 10/11] target-arm: Make mode switches from Hyp via CPS and MRS illegal
Date: Thu, 18 Feb 2016 20:44:17 +0300
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.5.1

On 15.02.2016 20:22, Peter Maydell wrote:
> Mode switches from Hyp to any other mode via the CPS and MRS
> instructions are illegal mode switches (though obviously switching
> via exception return is valid).  Add this check to bad_mode_switch().
>
> Signed-off-by: Peter Maydell <address@hidden>

Reviewed-by: Sergey Fedorov <address@hidden>

> ---
>  target-arm/helper.c | 12 ++++++++++--
>  1 file changed, 10 insertions(+), 2 deletions(-)
>
> diff --git a/target-arm/helper.c b/target-arm/helper.c
> index 69e93a2..e1af9d5 100644
> --- a/target-arm/helper.c
> +++ b/target-arm/helper.c
> @@ -5166,12 +5166,20 @@ void arm_cp_reset_ignore(CPUARMState *env, const 
> ARMCPRegInfo *opaque)
>      /* Helper coprocessor reset function for do-nothing-on-reset registers */
>  }
>  
> -static int bad_mode_switch(CPUARMState *env, int mode)
> +static int bad_mode_switch(CPUARMState *env, int mode, CPSRWriteType 
> write_type)
>  {
>      /* Return true if it is not valid for us to switch to
>       * this CPU mode (ie all the UNPREDICTABLE cases in
>       * the ARM ARM CPSRWriteByInstr pseudocode).
>       */
> +
> +    /* Changes to or from Hyp via MSR and CPS are illegal. */
> +    if (write_type == CPSRWriteByInstr &&
> +        ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_HYP ||
> +         mode == ARM_CPU_MODE_HYP)) {
> +        return 1;
> +    }
> +
>      switch (mode) {
>      case ARM_CPU_MODE_USR:
>      case ARM_CPU_MODE_SYS:
> @@ -5290,7 +5298,7 @@ void cpsr_write(CPUARMState *env, uint32_t val, 
> uint32_t mask,
>      if (write_type != CPSRWriteRaw &&
>          (env->uncached_cpsr & CPSR_M) != CPSR_USER &&
>          ((env->uncached_cpsr ^ val) & mask & CPSR_M)) {
> -        if (bad_mode_switch(env, val & CPSR_M)) {
> +        if (bad_mode_switch(env, val & CPSR_M, write_type)) {
>              /* Attempt to switch to an invalid mode: this is UNPREDICTABLE in
>               * v7, and has defined behaviour in v8:
>               *  + leave CPSR.M untouched




reply via email to

[Prev in Thread] Current Thread [Next in Thread]