qemu-devel
[Top][All Lists]
Advanced

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

Re: [PATCH v3 2/4] target/arm: Add support for FEAT_DIT, Data Independen


From: Richard Henderson
Subject: Re: [PATCH v3 2/4] target/arm: Add support for FEAT_DIT, Data Independent Timing
Date: Tue, 2 Feb 2021 14:11:26 -1000
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.10.0

On 2/2/21 12:21 PM, Rebecca Cran wrote:
> On 1/27/21 10:06 PM, Richard Henderson wrote:
>> In particular: CPSR.DIT (bit 21) -> SPSR_EL1.DIT (bit 24), and merging
>> PSTATE.SS into SPSR_EL1.SS (bit 21).
> 
> Thanks. I _think_ I'm understanding it better now. Would the following work? I
> don't see where I need to map PSTATE.SS into SPSR_EL1.SS though, because isn't
> that handled automatically since PSTATE maps onto SPSR?
> 
> 
> diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
> index a6b162049806..c1ff24d42f32 100644
> --- a/target/arm/helper-a64.c
> +++ b/target/arm/helper-a64.c
> @@ -1003,6 +1003,11 @@ void HELPER(exception_return)(CPUARMState *env, 
> uint64_t
> new_pc)
>          if (!arm_singlestep_active(env)) {
>              env->pstate &= ~PSTATE_SS;
>          }
> +
> +        if (spsr & PSTATE_DIT) {
> +            env->uncached_cpsr |= CPSR_DIT;
> +        }

This is missing the restore of PSTATE_SS for when singlestep *is* active.

> @@ -9426,6 +9426,12 @@ static void take_aarch32_exception(CPUARMState *env, 
> int
> new_mode,
>       */
>      env->pstate &= ~PSTATE_SS;
>      env->spsr = cpsr_read(env);
> +
> +    if (env->uncached_cpsr & CPSR_DIT) {
> +        env->spsr |= PSTATE_DIT;
> +        env->spsr &= ~PSTATE_SS;
> +    }

This one is incorrect because we're not storing to SPSR_ELx format, but SPSR
(the aa32 version), which has DIT at bit 21.

> @@ -9905,6 +9911,11 @@ static void arm_cpu_do_interrupt_aarch64(CPUState *cs)
>          old_mode = cpsr_read(env);
>          env->elr_el[new_el] = env->regs[15];
> 
> +        if (old_mode & CPSR_DIT) {
> +            old_mode |= PSTATE_DIT;
> +            old_mode &= ~PSTATE_SS;

This line would be clearer using CPSR_DIT.  I don't see PSTATE_SS being added
to old_mode.  Is that somewhere else, or simply missing context here?

I think it would be clearer to add some new helpers.  Naming is always
difficult, but how about:

static uint32_t cpsr_read_for_spsr_elx(CPUARMState *env)
{
    uint32_t ret = cpsr_read(env);

    /* Move DIT to the correct location for SPSR_ELx */
    if (ret & CPSR_DIT) {
        ret &= ~CPSR_DIT;
        ret |= PSTATE_DIT;
    }
    /* Merge PSTATE.SS into SPSR_ELx */
    ret |= env->pstate & PSTATE_SS;

    return ret;
}

static void cpsr_write_from_spsr_elx(CPUARMState *env,
                                     uint32_t val)
{
    uint32_t mask;

    /* Save SPSR_ELx.SS into PSTATE. */
    env->pstate = (env->pstate & ~PSTATE_SS) | (val & PSTATE_SS);
    val &= ~PSTATE_SS;

    /* Move DIT to the correct location for CPSR */
    if (val & PSTATE_DIT) {
        val &= ~PSTATE_DIT;
        val |= CPSR_DIT;
    }

    mask = aarch32_cpsr_valid_mask(env->features, \
        &env_archcpu(env)->isar);
    cpsr_write(env, val, mask, CPSRWriteRaw);
}


r~



reply via email to

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