[PATCH 20/35] target/arm: Handle FEAT_NV page table attribute changes

Peter Maydell posted 35 patches 11 months, 2 weeks ago
Maintainers: Peter Maydell <peter.maydell@linaro.org>
[PATCH 20/35] target/arm: Handle FEAT_NV page table attribute changes
Posted by Peter Maydell 11 months, 2 weeks ago
FEAT_NV requires that when HCR_EL2.{NV,NV1} == {1,1} the handling
of some of the page table attribute bits changes for the EL1&0
translation regime:

 * for block and page descriptors:
  - bit [54] holds PXN, not UXN
  - bit [53] is RES0, and the effective value of UXN is 0
  - bit [6], AP[1], is treated as 0
 * for table descriptors, when hierarchical permissions are enabled:
  - bit [60] holds PXNTable, not UXNTable
  - bit [59] is RES0
  - bit [61], APTable[0] is treated as 0

Implement these changes to the page table attribute handling.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target/arm/ptw.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/target/arm/ptw.c b/target/arm/ptw.c
index 1762b058aec..cab30f0bf46 100644
--- a/target/arm/ptw.c
+++ b/target/arm/ptw.c
@@ -1581,6 +1581,12 @@ static bool lpae_block_desc_valid(ARMCPU *cpu, bool ds,
     }
 }
 
+static bool nv_nv1_enabled(CPUARMState *env, S1Translate *ptw)
+{
+    uint64_t hcr = arm_hcr_el2_eff_secstate(env, ptw->in_space);
+    return (hcr & (HCR_NV | HCR_NV1)) == (HCR_NV | HCR_NV1);
+}
+
 /**
  * get_phys_addr_lpae: perform one stage of page table walk, LPAE format
  *
@@ -1989,6 +1995,21 @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
         xn = extract64(attrs, 54, 1);
         pxn = extract64(attrs, 53, 1);
 
+        if (el == 1 && nv_nv1_enabled(env, ptw)) {
+            /*
+             * With FEAT_NV, when HCR_EL2.{NV,NV1} == {1,1}, the block/page
+             * descriptor bit 54 holds PXN, 53 is RES0, and the effective value
+             * of UXN is 0. Similarly for bits 59 and 60 in table descriptors
+             * (which we have already folded into bits 53 and 54 of attrs).
+             * AP[1] (descriptor bit 6, our ap bit 0) is treated as 0.
+             * Similarly, APTable[0] from the table descriptor is treated as 0;
+             * we already folded this into AP[1] and squashing that to 0 does
+             * the right thing.
+             */
+            pxn = xn;
+            xn = 0;
+            ap &= ~1;
+        }
         /*
          * Note that we modified ptw->in_space earlier for NSTable, but
          * result->f.attrs retains a copy of the original security space.
-- 
2.34.1
Re: [PATCH 20/35] target/arm: Handle FEAT_NV page table attribute changes
Posted by Richard Henderson 11 months ago
On 12/18/23 22:32, Peter Maydell wrote:
> FEAT_NV requires that when HCR_EL2.{NV,NV1} == {1,1} the handling
> of some of the page table attribute bits changes for the EL1&0
> translation regime:
> 
>   * for block and page descriptors:
>    - bit [54] holds PXN, not UXN
>    - bit [53] is RES0, and the effective value of UXN is 0
>    - bit [6], AP[1], is treated as 0
>   * for table descriptors, when hierarchical permissions are enabled:
>    - bit [60] holds PXNTable, not UXNTable
>    - bit [59] is RES0
>    - bit [61], APTable[0] is treated as 0
> 
> Implement these changes to the page table attribute handling.
> 
> Signed-off-by: Peter Maydell<peter.maydell@linaro.org>
> ---
>   target/arm/ptw.c | 21 +++++++++++++++++++++
>   1 file changed, 21 insertions(+)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>

r~