All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3] target/arm: Fix ESR_EL2 buglet, implement FEAT_PAN3
@ 2023-03-31 14:50 Peter Maydell
  2023-03-31 14:50 ` [PATCH 1/3] target/arm: Pass ARMMMUFaultInfo to merge_syn_data_abort() Peter Maydell
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Peter Maydell @ 2023-03-31 14:50 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

The main purpose of this patchset is to implement FEAT_PAN3,
which allows the guest to force privileged code to not be able
to access memory that can be executed by user code. (This is
an extension of the existing FEAT_PAN which denies access
if user code could read or write the memory.) That is all
done in patch 3.

Patches 1 and 2 fix a buglet in our ESR_EL2 syndrome reporting
that I happened to notice while testing the FEAT_PAN3 code:
we were reporting the detailed instruction syndrome information
for all data aborts reported to EL2, whereas the architecture
requires this to happen only for stage-2 aborts, not stage-1
aborts.

This is all for-8.1 material -- the syndrome bug is minor
and has been around forever so isn't worth trying to fix
for 8.0 at this point in the release cycle.

thanks
-- PMM

Peter Maydell (3):
  target/arm: Pass ARMMMUFaultInfo to merge_syn_data_abort()
  target/arm: Don't set ISV when reporting stage 1 faults in ESR_EL2
  target/arm: Implement FEAT_PAN3

 docs/system/arm/emulation.rst |  1 +
 target/arm/cpu.h              |  5 +++++
 target/arm/cpu64.c            |  2 +-
 target/arm/ptw.c              | 14 +++++++++++++-
 target/arm/tcg/tlb_helper.c   | 26 ++++++++++++++++----------
 5 files changed, 36 insertions(+), 12 deletions(-)

-- 
2.34.1

 


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 1/3] target/arm: Pass ARMMMUFaultInfo to merge_syn_data_abort()
  2023-03-31 14:50 [PATCH 0/3] target/arm: Fix ESR_EL2 buglet, implement FEAT_PAN3 Peter Maydell
@ 2023-03-31 14:50 ` Peter Maydell
  2023-03-31 15:43   ` Richard Henderson
  2023-04-03  7:52   ` Philippe Mathieu-Daudé
  2023-03-31 14:50 ` [PATCH 2/3] target/arm: Don't set ISV when reporting stage 1 faults in ESR_EL2 Peter Maydell
  2023-03-31 14:50 ` [PATCH 3/3] target/arm: Implement FEAT_PAN3 Peter Maydell
  2 siblings, 2 replies; 8+ messages in thread
From: Peter Maydell @ 2023-03-31 14:50 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

We already pass merge_syn_data_abort() two fields from the
ARMMMUFaultInfo struct, and we're about to want to use a third field.
Refactor to just pass a pointer to the fault info.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target/arm/tcg/tlb_helper.c | 15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/target/arm/tcg/tlb_helper.c b/target/arm/tcg/tlb_helper.c
index 31eb77f7df9..1a61adb8a68 100644
--- a/target/arm/tcg/tlb_helper.c
+++ b/target/arm/tcg/tlb_helper.c
@@ -24,9 +24,9 @@ bool arm_s1_regime_using_lpae_format(CPUARMState *env, ARMMMUIdx mmu_idx)
 }
 
 static inline uint32_t merge_syn_data_abort(uint32_t template_syn,
+                                            ARMMMUFaultInfo *fi,
                                             unsigned int target_el,
-                                            bool same_el, bool ea,
-                                            bool s1ptw, bool is_write,
+                                            bool same_el, bool is_write,
                                             int fsc)
 {
     uint32_t syn;
@@ -43,9 +43,9 @@ static inline uint32_t merge_syn_data_abort(uint32_t template_syn,
      * ISS encoding for an exception from a Data Abort, the
      * ISV field.
      */
-    if (!(template_syn & ARM_EL_ISV) || target_el != 2 || s1ptw) {
+    if (!(template_syn & ARM_EL_ISV) || target_el != 2 || fi->s1ptw) {
         syn = syn_data_abort_no_iss(same_el, 0,
-                                    ea, 0, s1ptw, is_write, fsc);
+                                    fi->ea, 0, fi->s1ptw, is_write, fsc);
     } else {
         /*
          * Fields: IL, ISV, SAS, SSE, SRT, SF and AR come from the template
@@ -54,7 +54,7 @@ static inline uint32_t merge_syn_data_abort(uint32_t template_syn,
          */
         syn = syn_data_abort_with_iss(same_el,
                                       0, 0, 0, 0, 0,
-                                      ea, 0, s1ptw, is_write, fsc,
+                                      fi->ea, 0, fi->s1ptw, is_write, fsc,
                                       true);
         /* Merge the runtime syndrome with the template syndrome.  */
         syn |= template_syn;
@@ -117,9 +117,8 @@ void arm_deliver_fault(ARMCPU *cpu, vaddr addr,
         syn = syn_insn_abort(same_el, fi->ea, fi->s1ptw, fsc);
         exc = EXCP_PREFETCH_ABORT;
     } else {
-        syn = merge_syn_data_abort(env->exception.syndrome, target_el,
-                                   same_el, fi->ea, fi->s1ptw,
-                                   access_type == MMU_DATA_STORE,
+        syn = merge_syn_data_abort(env->exception.syndrome, fi, target_el,
+                                   same_el, access_type == MMU_DATA_STORE,
                                    fsc);
         if (access_type == MMU_DATA_STORE
             && arm_feature(env, ARM_FEATURE_V6)) {
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 2/3] target/arm: Don't set ISV when reporting stage 1 faults in ESR_EL2
  2023-03-31 14:50 [PATCH 0/3] target/arm: Fix ESR_EL2 buglet, implement FEAT_PAN3 Peter Maydell
  2023-03-31 14:50 ` [PATCH 1/3] target/arm: Pass ARMMMUFaultInfo to merge_syn_data_abort() Peter Maydell
@ 2023-03-31 14:50 ` Peter Maydell
  2023-03-31 15:52   ` Richard Henderson
  2023-03-31 14:50 ` [PATCH 3/3] target/arm: Implement FEAT_PAN3 Peter Maydell
  2 siblings, 1 reply; 8+ messages in thread
From: Peter Maydell @ 2023-03-31 14:50 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

The syndrome value reported to ESR_EL2 should only contain the
detailed instruction syndrome information when the fault has been
caused by a stage 2 abort, not when the fault was a stage 1 abort
(i.e.  caused by execution at EL2).  We were getting this wrong and
reporting the detailed ISV information all the time.

Fix the bug by checking fi->stage2.  Add a TODO comment noting the
cases where we'll have to come back and revisit this when we
implement FEAT_LS64 and friends.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target/arm/tcg/tlb_helper.c | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/target/arm/tcg/tlb_helper.c b/target/arm/tcg/tlb_helper.c
index 1a61adb8a68..d5a89bc5141 100644
--- a/target/arm/tcg/tlb_helper.c
+++ b/target/arm/tcg/tlb_helper.c
@@ -32,8 +32,9 @@ static inline uint32_t merge_syn_data_abort(uint32_t template_syn,
     uint32_t syn;
 
     /*
-     * ISV is only set for data aborts routed to EL2 and
-     * never for stage-1 page table walks faulting on stage 2.
+     * ISV is only set for stage-2 data aborts routed to EL2 and
+     * never for stage-1 page table walks faulting on stage 2
+     * or for stage-1 faults.
      *
      * Furthermore, ISV is only set for certain kinds of load/stores.
      * If the template syndrome does not have ISV set, we should leave
@@ -42,8 +43,14 @@ static inline uint32_t merge_syn_data_abort(uint32_t template_syn,
      * See ARMv8 specs, D7-1974:
      * ISS encoding for an exception from a Data Abort, the
      * ISV field.
+     *
+     * TODO: FEAT_LS64/FEAT_LS64_V/FEAT_SL64_ACCDATA: Translation,
+     * Access Flag, and Permission faults caused by LD64B, ST64B,
+     * ST64BV, or ST64BV0 insns report syndrome info even for stage-1
+     * faults and regardless of the target EL.
      */
-    if (!(template_syn & ARM_EL_ISV) || target_el != 2 || fi->s1ptw) {
+    if (!(template_syn & ARM_EL_ISV) || target_el != 2
+        || fi->s1ptw || !fi->stage2) {
         syn = syn_data_abort_no_iss(same_el, 0,
                                     fi->ea, 0, fi->s1ptw, is_write, fsc);
     } else {
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 3/3] target/arm: Implement FEAT_PAN3
  2023-03-31 14:50 [PATCH 0/3] target/arm: Fix ESR_EL2 buglet, implement FEAT_PAN3 Peter Maydell
  2023-03-31 14:50 ` [PATCH 1/3] target/arm: Pass ARMMMUFaultInfo to merge_syn_data_abort() Peter Maydell
  2023-03-31 14:50 ` [PATCH 2/3] target/arm: Don't set ISV when reporting stage 1 faults in ESR_EL2 Peter Maydell
@ 2023-03-31 14:50 ` Peter Maydell
  2023-03-31 17:04   ` Richard Henderson
  2 siblings, 1 reply; 8+ messages in thread
From: Peter Maydell @ 2023-03-31 14:50 UTC (permalink / raw)
  To: qemu-arm, qemu-devel

FEAT_PAN3 adds an EPAN bit to SCTLR_EL1 and SCTLR_EL2, which allows
the PAN bit to make memory non-privileged-read/write if it is
user-executable as well as if it is user-read/write.

Implement this feature and enable it in the AArch64 'max' CPU.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 docs/system/arm/emulation.rst |  1 +
 target/arm/cpu.h              |  5 +++++
 target/arm/cpu64.c            |  2 +-
 target/arm/ptw.c              | 14 +++++++++++++-
 4 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
index 2062d712610..73389878755 100644
--- a/docs/system/arm/emulation.rst
+++ b/docs/system/arm/emulation.rst
@@ -56,6 +56,7 @@ the following architecture extensions:
 - FEAT_MTE3 (MTE Asymmetric Fault Handling)
 - FEAT_PAN (Privileged access never)
 - FEAT_PAN2 (AT S1E1R and AT S1E1W instruction variants affected by PSTATE.PAN)
+- FEAT_PAN3 (Support for SCTLR_ELx.EPAN)
 - FEAT_PAuth (Pointer authentication)
 - FEAT_PMULL (PMULL, PMULL2 instructions)
 - FEAT_PMUv3p1 (PMU Extensions v3.1)
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index c097cae9882..d469a2637b3 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -3823,6 +3823,11 @@ static inline bool isar_feature_aa64_ats1e1(const ARMISARegisters *id)
     return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, PAN) >= 2;
 }
 
+static inline bool isar_feature_aa64_pan3(const ARMISARegisters *id)
+{
+    return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, PAN) >= 3;
+}
+
 static inline bool isar_feature_aa64_hcx(const ARMISARegisters *id)
 {
     return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, HCX) != 0;
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 0fb07cc7b6d..735ca541634 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -1302,7 +1302,7 @@ static void aarch64_max_initfn(Object *obj)
     t = FIELD_DP64(t, ID_AA64MMFR1, VH, 1);       /* FEAT_VHE */
     t = FIELD_DP64(t, ID_AA64MMFR1, HPDS, 1);     /* FEAT_HPDS */
     t = FIELD_DP64(t, ID_AA64MMFR1, LO, 1);       /* FEAT_LOR */
-    t = FIELD_DP64(t, ID_AA64MMFR1, PAN, 2);      /* FEAT_PAN2 */
+    t = FIELD_DP64(t, ID_AA64MMFR1, PAN, 3);      /* FEAT_PAN3 */
     t = FIELD_DP64(t, ID_AA64MMFR1, XNX, 1);      /* FEAT_XNX */
     t = FIELD_DP64(t, ID_AA64MMFR1, ETS, 1);      /* FEAT_ETS */
     t = FIELD_DP64(t, ID_AA64MMFR1, HCX, 1);      /* FEAT_HCX */
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
index ec3f51782aa..499308fcb07 100644
--- a/target/arm/ptw.c
+++ b/target/arm/ptw.c
@@ -947,6 +947,7 @@ static int get_S2prot(CPUARMState *env, int s2ap, int xn, bool s1_is_el0)
 static int get_S1prot(CPUARMState *env, ARMMMUIdx mmu_idx, bool is_aa64,
                       int ap, int ns, int xn, int pxn)
 {
+    ARMCPU *cpu = env_archcpu(env);
     bool is_user = regime_is_user(env, mmu_idx);
     int prot_rw, user_rw;
     bool have_wxn;
@@ -958,8 +959,19 @@ static int get_S1prot(CPUARMState *env, ARMMMUIdx mmu_idx, bool is_aa64,
     if (is_user) {
         prot_rw = user_rw;
     } else {
+        /*
+         * PAN controls can forbid data accesses but don't affect insn fetch.
+         * Plain PAN forbids data accesses if EL0 has data permissions;
+         * PAN3 forbids data accesses if EL0 has either data or exec perms.
+         * Note that for AArch64 the 'user can exec' case is exactly !xn.
+         * We make the IMPDEF choices that SCR_EL3.SIF and Realm EL2&0
+         * do not affect EPAN.
+         */
         if (user_rw && regime_is_pan(env, mmu_idx)) {
-            /* PAN forbids data accesses but doesn't affect insn fetch */
+            prot_rw = 0;
+        } else if (cpu_isar_feature(aa64_pan3, cpu) && is_aa64 &&
+                   regime_is_pan(env, mmu_idx) &&
+                   (regime_sctlr(env, mmu_idx) & SCTLR_EPAN) && !xn) {
             prot_rw = 0;
         } else {
             prot_rw = simple_ap_to_rw_prot_is_user(ap, false);
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH 1/3] target/arm: Pass ARMMMUFaultInfo to merge_syn_data_abort()
  2023-03-31 14:50 ` [PATCH 1/3] target/arm: Pass ARMMMUFaultInfo to merge_syn_data_abort() Peter Maydell
@ 2023-03-31 15:43   ` Richard Henderson
  2023-04-03  7:52   ` Philippe Mathieu-Daudé
  1 sibling, 0 replies; 8+ messages in thread
From: Richard Henderson @ 2023-03-31 15:43 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 3/31/23 07:50, Peter Maydell wrote:
> We already pass merge_syn_data_abort() two fields from the
> ARMMMUFaultInfo struct, and we're about to want to use a third field.
> Refactor to just pass a pointer to the fault info.
> 
> Signed-off-by: Peter Maydell<peter.maydell@linaro.org>
> ---
>   target/arm/tcg/tlb_helper.c | 15 +++++++--------
>   1 file changed, 7 insertions(+), 8 deletions(-)

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

r~


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 2/3] target/arm: Don't set ISV when reporting stage 1 faults in ESR_EL2
  2023-03-31 14:50 ` [PATCH 2/3] target/arm: Don't set ISV when reporting stage 1 faults in ESR_EL2 Peter Maydell
@ 2023-03-31 15:52   ` Richard Henderson
  0 siblings, 0 replies; 8+ messages in thread
From: Richard Henderson @ 2023-03-31 15:52 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 3/31/23 07:50, Peter Maydell wrote:
> The syndrome value reported to ESR_EL2 should only contain the
> detailed instruction syndrome information when the fault has been
> caused by a stage 2 abort, not when the fault was a stage 1 abort
> (i.e.  caused by execution at EL2).  We were getting this wrong and
> reporting the detailed ISV information all the time.
> 
> Fix the bug by checking fi->stage2.  Add a TODO comment noting the
> cases where we'll have to come back and revisit this when we
> implement FEAT_LS64 and friends.
> 
> Signed-off-by: Peter Maydell<peter.maydell@linaro.org>
> ---
>   target/arm/tcg/tlb_helper.c | 13 ++++++++++---
>   1 file changed, 10 insertions(+), 3 deletions(-)

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

r~


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 3/3] target/arm: Implement FEAT_PAN3
  2023-03-31 14:50 ` [PATCH 3/3] target/arm: Implement FEAT_PAN3 Peter Maydell
@ 2023-03-31 17:04   ` Richard Henderson
  0 siblings, 0 replies; 8+ messages in thread
From: Richard Henderson @ 2023-03-31 17:04 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 3/31/23 07:50, Peter Maydell wrote:
> FEAT_PAN3 adds an EPAN bit to SCTLR_EL1 and SCTLR_EL2, which allows
> the PAN bit to make memory non-privileged-read/write if it is
> user-executable as well as if it is user-read/write.
> 
> Implement this feature and enable it in the AArch64 'max' CPU.
> 
> Signed-off-by: Peter Maydell<peter.maydell@linaro.org>
> ---
>   docs/system/arm/emulation.rst |  1 +
>   target/arm/cpu.h              |  5 +++++
>   target/arm/cpu64.c            |  2 +-
>   target/arm/ptw.c              | 14 +++++++++++++-
>   4 files changed, 20 insertions(+), 2 deletions(-)

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

r~


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 1/3] target/arm: Pass ARMMMUFaultInfo to merge_syn_data_abort()
  2023-03-31 14:50 ` [PATCH 1/3] target/arm: Pass ARMMMUFaultInfo to merge_syn_data_abort() Peter Maydell
  2023-03-31 15:43   ` Richard Henderson
@ 2023-04-03  7:52   ` Philippe Mathieu-Daudé
  1 sibling, 0 replies; 8+ messages in thread
From: Philippe Mathieu-Daudé @ 2023-04-03  7:52 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel

On 31/3/23 16:50, Peter Maydell wrote:
> We already pass merge_syn_data_abort() two fields from the
> ARMMMUFaultInfo struct, and we're about to want to use a third field.
> Refactor to just pass a pointer to the fault info.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>   target/arm/tcg/tlb_helper.c | 15 +++++++--------
>   1 file changed, 7 insertions(+), 8 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>



^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2023-04-03  7:53 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-03-31 14:50 [PATCH 0/3] target/arm: Fix ESR_EL2 buglet, implement FEAT_PAN3 Peter Maydell
2023-03-31 14:50 ` [PATCH 1/3] target/arm: Pass ARMMMUFaultInfo to merge_syn_data_abort() Peter Maydell
2023-03-31 15:43   ` Richard Henderson
2023-04-03  7:52   ` Philippe Mathieu-Daudé
2023-03-31 14:50 ` [PATCH 2/3] target/arm: Don't set ISV when reporting stage 1 faults in ESR_EL2 Peter Maydell
2023-03-31 15:52   ` Richard Henderson
2023-03-31 14:50 ` [PATCH 3/3] target/arm: Implement FEAT_PAN3 Peter Maydell
2023-03-31 17:04   ` Richard Henderson

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.