mbox series

[00/62] target/arm: Implement FEAT_HAFDBS

Message ID 20220703082419.770989-1-richard.henderson@linaro.org
Headers show
Series target/arm: Implement FEAT_HAFDBS | expand

Message

Richard Henderson July 3, 2022, 8:23 a.m. UTC
This is a major reorg to arm page table walking.  While the result
here is "merely" Hardware-assited Access Flag and Dirty Bit Setting
(HAFDBS), the ultimate goal is the Realm Management Extension (RME).
RME "recommends" that HAFDBS be implemented (I_CSLWZ).

For HAFDBS, being able to find a host pointer for the ram that
backs a given page table entry is required in order to perform the
atomic update to that PTE.  The easiest way to find a host pointer
is to use the existing softtlb mechanism.  Thus all of the page
table walkers have been adjusted to take an mmu_idx that corresponds
to the regime in which the page table is stored.  In some cases,
this is a new "physical" mmu_idx that has a permanent 1-1 mapping.

For RME, "physical" addresses also have page permissions, coming
from the Root realm Granule Protection Table, which can be thought
of as a third stage page table lookup.  So eventually the new
Secure and Nonsecure physical mmu indexes will joined by
Realm and Root physical mmu indexes, and all of them will take
the new Granule Page Table into account.

Previously, we had A-profile allocate separate mmu_idx for secure
vs non-secure.  I've done away with that.  Now, I flush all mmu_idx
when SCR_EL3.NS is changed.  I did not see how we could reasonably
add 8 more mmu_idx for Realm.  Moreover, I had a look through ARM
Trusted Firmware, at the code paths used to change between Secure
and Nonsecure.  We wind up flushing all of these mmu_idx anyway while
swapping the EL1+EL2 cpregs, so there is no gain at all in attempting
to keep them live at the same time within qemu.


r~


Richard Henderson (62):
  accel/tcg: Introduce PageEntryExtra
  target/arm: Enable PageEntryExtra
  target/arm: Fix MTE check in sve_ldnfff1_r
  target/arm: Record tagged bit for user-only in sve_probe_page
  target/arm: Use PageEntryExtra for MTE
  target/arm: Use PageEntryExtra for BTI
  include/exec: Remove target_tlb_bitN from MemTxAttrs
  target/arm: Create GetPhysAddrResult
  target/arm: Fix ipa_secure in get_phys_addr
  target/arm: Use GetPhysAddrResult in get_phys_addr_lpae
  target/arm: Use GetPhysAddrResult in get_phys_addr_v6
  target/arm: Use GetPhysAddrResult in get_phys_addr_v5
  target/arm: Use GetPhysAddrResult in get_phys_addr_pmsav5
  target/arm: Use GetPhysAddrResult in get_phys_addr_pmsav7
  target/arm: Use GetPhysAddrResult in get_phys_addr_pmsav8
  target/arm: Use GetPhysAddrResult in pmsav8_mpu_lookup
  target/arm: Remove is_subpage argument to pmsav8_mpu_lookup
  target/arm: Add is_secure parameter to v8m_security_lookup
  target/arm: Add is_secure parameter to pmsav8_mpu_lookup
  target/arm: Add is_secure parameter to get_phys_addr_v5
  target/arm: Add is_secure parameter to get_phys_addr_v6
  target/arm: Add secure parameter to get_phys_addr_pmsav8
  target/arm: Add is_secure parameter to pmsav7_use_background_region
  target/arm: Add is_secure parameter to get_phys_addr_lpae
  target/arm: Add is_secure parameter to get_phys_addr_pmsav7
  target/arm: Add is_secure parameter to regime_translation_disabled
  target/arm: Add is_secure parameter to get_phys_addr_pmsav5
  target/arm: Split out get_phys_addr_with_secure
  target/arm: Add is_secure parameter to v7m_read_half_insn
  target/arm: Add TBFLAG_M32.SECURE
  target/arm: Merge regime_is_secure into get_phys_addr
  target/arm: Add is_secure parameter to do_ats_write
  target/arm: Fold secure and non-secure a-profile mmu indexes
  target/arm: Reorg regime_translation_disabled
  target/arm: Drop secure check for HCR.TGE vs SCTLR_EL1.M
  target/arm: Introduce arm_hcr_el2_eff_secstate
  target/arm: Hoist read of *is_secure in S1_ptw_translate
  target/arm: Fix S2 disabled check in S1_ptw_translate
  target/arm: Remove env argument from combined_attrs_fwb
  target/arm: Pass HCR to attribute subroutines.
  target/arm: Fix ATS12NSO* from S PL1
  target/arm: Split out get_phys_addr_disabled
  target/arm: Reorg get_phys_addr_disabled
  target/arm: Add ARMMMUIdx_Phys_{S,NS}
  target/arm: Move ARMMMUIdx_Stage2 to a real tlb mmu_idx
  target/arm: Use softmmu tlbs for page table walking
  target/arm: Hoist check for disabled stage2 translation.
  target/arm: Split out get_phys_addr_twostage
  target/arm: Use bool consistently for get_phys_addr subroutines
  target/arm: Only use ARMMMUIdx_Stage1* for two-stage translation
  target/arm: Add ptw_idx argument to S1_ptw_translate
  target/arm: Add isar predicates for FEAT_HAFDBS
  target/arm: Extract HA and HD in aa64_va_parameters
  target/arm: Split out S1TranslateResult type
  target/arm: Move be test for regime into S1TranslateResult
  target/arm: Move S1_ptw_translate outside arm_ld[lq]_ptw
  target/arm: Add ARMFault_UnsuppAtomicUpdate
  target/arm: Remove loop from get_phys_addr_lpae
  target/arm: Fix fault reporting in get_phys_addr_lpae
  target/arm: Don't shift attrs in get_phys_addr_lpae
  target/arm: Consider GP an attribute in get_phys_addr_lpae
  target/arm: Implement FEAT_HAFDBS

 docs/system/arm/emulation.rst  |    1 +
 include/exec/cpu-defs.h        |    5 +
 include/exec/exec-all.h        |   26 +-
 include/exec/memattrs.h        |   10 -
 include/qemu/typedefs.h        |    1 +
 target/arm/cpu-param.h         |   10 +-
 target/arm/cpu.h               |  138 ++--
 target/arm/internals.h         |  118 +--
 target/arm/sve_ldst_internal.h |    1 +
 accel/tcg/cputlb.c             |   73 +-
 target/arm/cpu64.c             |    1 +
 target/arm/helper.c            |  213 +++--
 target/arm/m_helper.c          |   83 +-
 target/arm/mte_helper.c        |   52 +-
 target/arm/ptw.c               | 1346 +++++++++++++++++++-------------
 target/arm/sve_helper.c        |   50 +-
 target/arm/tlb_helper.c        |   51 +-
 target/arm/translate-a64.c     |   30 +-
 target/arm/translate.c         |    9 +-
 19 files changed, 1194 insertions(+), 1024 deletions(-)

Comments

Peter Maydell July 4, 2022, 2:54 p.m. UTC | #1
On Sun, 3 Jul 2022 at 09:25, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> This is a major reorg to arm page table walking.  While the result
> here is "merely" Hardware-assited Access Flag and Dirty Bit Setting
> (HAFDBS), the ultimate goal is the Realm Management Extension (RME).
> RME "recommends" that HAFDBS be implemented (I_CSLWZ).
>
> For HAFDBS, being able to find a host pointer for the ram that
> backs a given page table entry is required in order to perform the
> atomic update to that PTE.  The easiest way to find a host pointer
> is to use the existing softtlb mechanism.  Thus all of the page
> table walkers have been adjusted to take an mmu_idx that corresponds
> to the regime in which the page table is stored.  In some cases,
> this is a new "physical" mmu_idx that has a permanent 1-1 mapping.
>
> For RME, "physical" addresses also have page permissions, coming
> from the Root realm Granule Protection Table, which can be thought
> of as a third stage page table lookup.  So eventually the new
> Secure and Nonsecure physical mmu indexes will joined by
> Realm and Root physical mmu indexes, and all of them will take
> the new Granule Page Table into account.
>
> Previously, we had A-profile allocate separate mmu_idx for secure
> vs non-secure.  I've done away with that.  Now, I flush all mmu_idx
> when SCR_EL3.NS is changed.  I did not see how we could reasonably
> add 8 more mmu_idx for Realm.  Moreover, I had a look through ARM
> Trusted Firmware, at the code paths used to change between Secure
> and Nonsecure.  We wind up flushing all of these mmu_idx anyway while
> swapping the EL1+EL2 cpregs, so there is no gain at all in attempting
> to keep them live at the same time within qemu.

Is there no SMC/interrupt/etc at all which is handled as a "just do the
thing at EL3" without dropping down to secure EL2/EL1 ?

thanks
-- PMM
Richard Henderson July 4, 2022, 2:58 p.m. UTC | #2
On 7/4/22 20:24, Peter Maydell wrote:
>> Previously, we had A-profile allocate separate mmu_idx for secure
>> vs non-secure.  I've done away with that.  Now, I flush all mmu_idx
>> when SCR_EL3.NS is changed.  I did not see how we could reasonably
>> add 8 more mmu_idx for Realm.  Moreover, I had a look through ARM
>> Trusted Firmware, at the code paths used to change between Secure
>> and Nonsecure.  We wind up flushing all of these mmu_idx anyway while
>> swapping the EL1+EL2 cpregs, so there is no gain at all in attempting
>> to keep them live at the same time within qemu.
> 
> Is there no SMC/interrupt/etc at all which is handled as a "just do the
> thing at EL3" without dropping down to secure EL2/EL1 ?

I'm sure there is, but it's only swapping between S EL[012] and NS EL[012] that concerned 
me.  Is there something that I'm missing?


r~
Peter Maydell July 4, 2022, 3:57 p.m. UTC | #3
On Mon, 4 Jul 2022 at 15:58, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> On 7/4/22 20:24, Peter Maydell wrote:
> >> Previously, we had A-profile allocate separate mmu_idx for secure
> >> vs non-secure.  I've done away with that.  Now, I flush all mmu_idx
> >> when SCR_EL3.NS is changed.  I did not see how we could reasonably
> >> add 8 more mmu_idx for Realm.  Moreover, I had a look through ARM
> >> Trusted Firmware, at the code paths used to change between Secure
> >> and Nonsecure.  We wind up flushing all of these mmu_idx anyway while
> >> swapping the EL1+EL2 cpregs, so there is no gain at all in attempting
> >> to keep them live at the same time within qemu.
> >
> > Is there no SMC/interrupt/etc at all which is handled as a "just do the
> > thing at EL3" without dropping down to secure EL2/EL1 ?
>
> I'm sure there is, but it's only swapping between S EL[012] and NS EL[012] that concerned
> me.  Is there something that I'm missing?

Oh, right, EL3 remains its own mmu_idx, of course. (And I guess
also Monitor mode for AArch32 EL3, though the degree to which we
care about performance of emulation there is decreasing I suspect.)

thanks
-- PMM
Peter Maydell Aug. 12, 2022, 4:31 p.m. UTC | #4
On Sun, 3 Jul 2022 at 09:25, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> This is a major reorg to arm page table walking.  While the result
> here is "merely" Hardware-assited Access Flag and Dirty Bit Setting
> (HAFDBS), the ultimate goal is the Realm Management Extension (RME).
> RME "recommends" that HAFDBS be implemented (I_CSLWZ).

> Richard Henderson (62):
>   accel/tcg: Introduce PageEntryExtra
>   target/arm: Enable PageEntryExtra
>   target/arm: Fix MTE check in sve_ldnfff1_r
>   target/arm: Record tagged bit for user-only in sve_probe_page
>   target/arm: Use PageEntryExtra for MTE
>   target/arm: Use PageEntryExtra for BTI
>   include/exec: Remove target_tlb_bitN from MemTxAttrs
>   target/arm: Create GetPhysAddrResult
>   target/arm: Fix ipa_secure in get_phys_addr
>   target/arm: Use GetPhysAddrResult in get_phys_addr_lpae
>   target/arm: Use GetPhysAddrResult in get_phys_addr_v6
>   target/arm: Use GetPhysAddrResult in get_phys_addr_v5
>   target/arm: Use GetPhysAddrResult in get_phys_addr_pmsav5
>   target/arm: Use GetPhysAddrResult in get_phys_addr_pmsav7
>   target/arm: Use GetPhysAddrResult in get_phys_addr_pmsav8
>   target/arm: Use GetPhysAddrResult in pmsav8_mpu_lookup
>   target/arm: Remove is_subpage argument to pmsav8_mpu_lookup
>   target/arm: Add is_secure parameter to v8m_security_lookup
>   target/arm: Add is_secure parameter to pmsav8_mpu_lookup
>   target/arm: Add is_secure parameter to get_phys_addr_v5
>   target/arm: Add is_secure parameter to get_phys_addr_v6
>   target/arm: Add secure parameter to get_phys_addr_pmsav8
>   target/arm: Add is_secure parameter to pmsav7_use_background_region
>   target/arm: Add is_secure parameter to get_phys_addr_lpae
>   target/arm: Add is_secure parameter to get_phys_addr_pmsav7
>   target/arm: Add is_secure parameter to regime_translation_disabled
>   target/arm: Add is_secure parameter to get_phys_addr_pmsav5

Is it possible to rearrange this patchset so the easy
refactoring patches that do "use a struct to return
values from get_phys_addr and friends" are at the front
(ie before the stuff that touches core code) ?
That way they're easy to take into the tree early while
the rest of the series is still under review...

thanks
-- PMM
Richard Henderson Aug. 12, 2022, 5:54 p.m. UTC | #5
On 8/12/22 09:31, Peter Maydell wrote:
> Is it possible to rearrange this patchset so the easy
> refactoring patches that do "use a struct to return
> values from get_phys_addr and friends" are at the front
> (ie before the stuff that touches core code) ?
> That way they're easy to take into the tree early while
> the rest of the series is still under review...

Yes, I think so.


r~