qemu-arm
[Top][All Lists]
Advanced

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

Re: [Qemu-arm] [PATCH v1 2/2] target-arm: Extend PAR format determinatio


From: Edgar E. Iglesias
Subject: Re: [Qemu-arm] [PATCH v1 2/2] target-arm: Extend PAR format determination
Date: Tue, 11 Jul 2017 12:03:34 +0200
User-agent: Mutt/1.5.24 (2015-08-30)

On Mon, Jul 10, 2017 at 04:11:29PM +0100, Peter Maydell wrote:
> On 30 June 2017 at 14:45, Edgar E. Iglesias <address@hidden> wrote:
> > From: "Edgar E. Iglesias" <address@hidden>
> >
> > Extend PAR format determination to handle more cases.
> >
> > Signed-off-by: Edgar E. Iglesias <address@hidden>
> > ---
> >  target/arm/helper.c | 30 +++++++++++++++++++++++++++++-
> >  1 file changed, 29 insertions(+), 1 deletion(-)
> >
> > diff --git a/target/arm/helper.c b/target/arm/helper.c
> > index fd1027e..6a1fffe 100644
> > --- a/target/arm/helper.c
> > +++ b/target/arm/helper.c
> > @@ -2345,12 +2345,40 @@ static uint64_t do_ats_write(CPUARMState *env, 
> > uint64_t value,
> >      uint32_t fsr;
> >      bool ret;
> >      uint64_t par64;
> > +    bool format64 = false;
> >      MemTxAttrs attrs = {};
> >      ARMMMUFaultInfo fi = {};
> >
> >      ret = get_phys_addr(env, value, access_type, mmu_idx,
> >                          &phys_addr, &attrs, &prot, &page_size, &fsr, &fi);
> > -    if (extended_addresses_enabled(env)) {
> > +
> > +    if (is_a64(env)) {
> > +        format64 = true;
> > +    } else if (arm_feature(env, ARM_FEATURE_LPAE)) {
> > +        /*
> > +         * ATS1Cxx:
> > +         * * TTBCR.EAE determines whether the result is returned using the
> > +         *   32-bit or the 64-bit PAR format
> > +         * * Instructions executed in Hyp mode always use the 64bit format
> > +         *
> > +         * ATS1S2NSOxx uses the 64bit format if any of the following is 
> > true:
> > +         * * The Non-secure TTBCR.EAE bit is set to 1
> > +         * * The implementation includes EL2, and the value of HCR.VM is 1
> > +         *
> > +         * ATS1Hx always uses the 64bit format (not supported yet).
> > +         */
> > +        format64 = regime_using_lpae_format(env, mmu_idx);
> > +
> > +        if (arm_feature(env, ARM_FEATURE_EL2)) {
> > +            if (mmu_idx == ARMMMUIdx_S12NSE0 || mmu_idx == 
> > ARMMMUIdx_S12NSE1) {
> > +                format64 |= env->cp15.hcr_el2 & HCR_VM;
> > +            } else {
> > +                format64 |= arm_current_el(env) == 2;
> > +            }
> > +        }
> > +    }
> 
> So this kind of worries me, because what it's coded as is "determine
> whether architecturally we should be returning a 64-bit or 32-bit
> PAR format", but what the code below it uses the format64 flag for is
> "manipulate whatever PAR we got handed back by get_phys_addr()".
> So we have two separate bits of code that are both choosing
> 32 vs 64 bit PAR (the code in this patch, and the logic inside
> get_phys_addr()), and they have to come to the same conclusion
> or we'll silently mangle the PAR. It seems like it would be
> better to either have get_phys_addr() explicitly tell us what kind
> of format it is returning to us, or to have the caller tell it
> what kind of PAR it needs.

Yes, I see your point and that's exactly what's happenning before the patch.
Some of these new checks are generic in the sense that they check for 
LPAE/64bitness
but others are I guess ATS specific for lack of a better term.
It feels a bit weird to put the ATS specific PAR format logic into 
get_phys_addr.

The basic idea here is that we never downgrade to the 32bit format, we only 
uprgade.
The following line was meant to get the initial format I think you are 
requesting:
format64 = regime_using_lpae_format(env, mmu_idx);

After that, we apply possible ATS specfic upgrades to 64bit PAR format if 
needed.

For clarity, perhaps we could make get_phys_addr return this same initial 
format, and then
we can follow up with the ATS specific upgrades. E.g:

    ret = get_phys_addr(env, value, access_type, mmu_idx,
                        &phys_addr, &attrs, &prot, &page_size, &fsr, &fi,
                        &format64);

    /* Apply possible ATS/PAR 64bit upgrades if format64 is false.  */
    if (is_a64(env)) {
        format64 = true;
    } else if (arm_feature(env, ARM_FEATURE_LPAE)) {
        if (arm_feature(env, ARM_FEATURE_EL2)) {
            if (mmu_idx == ARMMMUIdx_S12NSE0 || mmu_idx == ARMMMUIdx_S12NSE1) {
                format64 |= env->cp15.hcr_el2 & HCR_VM;
            } else {
                format64 |= arm_current_el(env) == 2;
            }
        }
    }


Does something like that sound OK?

Cheers,
Edgar


> >      ret = get_phys_addr(env, value, access_type, mmu_idx,
> >                          &phys_addr, &attrs, &prot, &page_size, &fsr, &fi);
> > -    if (extended_addresses_enabled(env)) {
> > +
> > +    if (is_a64(env)) {
> > +        format64 = true;
> > +    } else if (arm_feature(env, ARM_FEATURE_LPAE)) {
> > +        /*
> > +         * ATS1Cxx:
> > +         * * TTBCR.EAE determines whether the result is returned using the
> > +         *   32-bit or the 64-bit PAR format
> > +         * * Instructions executed in Hyp mode always use the 64bit format
> > +         *
> > +         * ATS1S2NSOxx uses the 64bit format if any of the following is 
> > true:
> > +         * * The Non-secure TTBCR.EAE bit is set to 1
> > +         * * The implementation includes EL2, and the value of HCR.VM is 1
> > +         *
> > +         * ATS1Hx always uses the 64bit format (not supported yet).
> > +         */
> > +        format64 = regime_using_lpae_format(env, mmu_idx);
> > +
> > +        if (arm_feature(env, ARM_FEATURE_EL2)) {
> > +            if (mmu_idx == ARMMMUIdx_S12NSE0 || mmu_idx == 
> > ARMMMUIdx_S12NSE1) {
> > +                format64 |= env->cp15.hcr_el2 & HCR_VM;
> > +            } else {
> > +                format64 |= arm_current_el(env) == 2;
> > +            }
>

> 
> PS: on the subject of virtualization, I notice there's a comment
> a bit later on in do_ats_write() that says
>     /* Note that S2WLK and FSTAGE are always zero, because we don't
>      * implement virtualization and therefore there can't be a stage 2
>      * fault.
>      */
> so we'll need to address that too at some point...
> 
> thanks
> -- PMM



reply via email to

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