Source-Changes-HG archive

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

[src/trunk]: src/sys/arch add support Hardware updates to Access flag and Dir...



details:   https://anonhg.NetBSD.org/src/rev/b7f826c98b25
branches:  trunk
changeset: 359916:b7f826c98b25
user:      ryo <ryo%NetBSD.org@localhost>
date:      Mon Jan 31 09:16:09 2022 +0000

description:
add support Hardware updates to Access flag and Dirty state (FEAT_HAFDBS)

- The DBM bit of the PTE is now used to determine if it is writable, and
  the AF bit is treated entirely as a reference bit. A valid PTE is always
  treated as readable. There can be no valid PTE that is not readable.
- LX_BLKPAG_OS_{READ,WRITE} are used only for debugging purposes,
  and has been superseded by LX_BLKPAG_AF and LX_BLKPAG_DBM.
- Improve comment

The need for reference/modify emulation has been eliminated,
and access/permission faults have been reduced, however,
there has been little change in overall performance.

diffstat:

 sys/arch/aarch64/aarch64/aarch64_machdep.c |   12 +-
 sys/arch/aarch64/aarch64/cpufunc.c         |   70 ++++++++-
 sys/arch/aarch64/aarch64/fault.c           |   18 +-
 sys/arch/aarch64/aarch64/locore.S          |   12 +-
 sys/arch/aarch64/aarch64/pmap.c            |  222 ++++++++++++++++++++++------
 sys/arch/aarch64/conf/files.aarch64        |    3 +-
 sys/arch/aarch64/include/cpufunc.h         |    4 +-
 sys/arch/evbarm/conf/GENERIC64             |    5 +-
 8 files changed, 281 insertions(+), 65 deletions(-)

diffs (truncated from 673 to 300 lines):

diff -r ad0098030ad8 -r b7f826c98b25 sys/arch/aarch64/aarch64/aarch64_machdep.c
--- a/sys/arch/aarch64/aarch64/aarch64_machdep.c        Mon Jan 31 08:43:05 2022 +0000
+++ b/sys/arch/aarch64/aarch64/aarch64_machdep.c        Mon Jan 31 09:16:09 2022 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: aarch64_machdep.c,v 1.63 2021/10/31 16:23:47 skrll Exp $ */
+/* $NetBSD: aarch64_machdep.c,v 1.64 2022/01/31 09:16:09 ryo Exp $ */
 
 /*-
  * Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: aarch64_machdep.c,v 1.63 2021/10/31 16:23:47 skrll Exp $");
+__KERNEL_RCSID(1, "$NetBSD: aarch64_machdep.c,v 1.64 2022/01/31 09:16:09 ryo Exp $");
 
 #include "opt_arm_debug.h"
 #include "opt_cpuoptions.h"
@@ -533,6 +533,14 @@
            NULL, 0,
            &aarch64_bti_enabled, 0,
            CTL_MACHDEP, CTL_CREATE, CTL_EOL);
+
+       sysctl_createv(clog, 0, NULL, NULL,
+           CTLFLAG_PERMANENT,
+           CTLTYPE_INT, "hafdbs",
+           SYSCTL_DESCR("Whether Hardware updates to Access flag and Dirty state is enabled"),
+           NULL, 0,
+           &aarch64_hafdbs_enabled, 0,
+           CTL_MACHDEP, CTL_CREATE, CTL_EOL);
 }
 
 void
diff -r ad0098030ad8 -r b7f826c98b25 sys/arch/aarch64/aarch64/cpufunc.c
--- a/sys/arch/aarch64/aarch64/cpufunc.c        Mon Jan 31 08:43:05 2022 +0000
+++ b/sys/arch/aarch64/aarch64/cpufunc.c        Mon Jan 31 09:16:09 2022 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: cpufunc.c,v 1.32 2021/10/31 16:23:47 skrll Exp $       */
+/*     $NetBSD: cpufunc.c,v 1.33 2022/01/31 09:16:09 ryo Exp $ */
 
 /*
  * Copyright (c) 2017 Ryo Shimizu <ryo%nerv.org@localhost>
@@ -30,7 +30,7 @@
 #include "opt_multiprocessor.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cpufunc.c,v 1.32 2021/10/31 16:23:47 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpufunc.c,v 1.33 2022/01/31 09:16:09 ryo Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -50,6 +50,7 @@
 u_int aarch64_cache_vindexsize;
 u_int aarch64_cache_prefer_mask;
 
+int aarch64_hafdbs_enabled __read_mostly;
 int aarch64_pan_enabled __read_mostly;
 int aarch64_pac_enabled __read_mostly;
 
@@ -464,6 +465,71 @@
 }
 
 void
+aarch64_hafdbs_init(int primary)
+{
+#ifdef ARMV81_HAFDBS
+       uint64_t tcr;
+       int hafdbs;
+
+       hafdbs = __SHIFTOUT(reg_id_aa64mmfr1_el1_read(),
+           ID_AA64MMFR1_EL1_HAFDBS);
+
+       /*
+        * hafdbs
+        *   0:HAFDBS_NONE - no support for any hardware flags
+        *   1:HAFDBS_A    - only hardware access flag supported
+        *   2:HAFDBS_AD   - hardware access and modified flags supported.
+        */
+
+       if (primary) {
+               /* CPU0 does the detection. */
+               switch (hafdbs) {
+               case ID_AA64MMFR1_EL1_HAFDBS_NONE:
+               default:
+                       aarch64_hafdbs_enabled = 0;
+                       break;
+               case ID_AA64MMFR1_EL1_HAFDBS_A:
+               case ID_AA64MMFR1_EL1_HAFDBS_AD:
+                       aarch64_hafdbs_enabled = hafdbs;
+                       break;
+               }
+       } else {
+               /*
+                * The support status of HAFDBS on the primary CPU is different
+                * from that of the application processor.
+                *
+                * XXX:
+                *  The correct way to do this is to disable it on all cores,
+                *  or call pmap_fault_fixup() only on the unsupported cores,
+                *  but for now, do panic().
+                */
+               if (aarch64_hafdbs_enabled != hafdbs)
+                       panic("HAFDBS is supported (%d) on primary cpu, "
+                           "but isn't equal (%d) on secondary cpu",
+                           aarch64_hafdbs_enabled, hafdbs);
+       }
+
+       /* enable Hardware updates to Access flag and Dirty state */
+       tcr = reg_tcr_el1_read();
+       switch (hafdbs) {
+       case ID_AA64MMFR1_EL1_HAFDBS_NONE:
+       default:
+               break;
+       case ID_AA64MMFR1_EL1_HAFDBS_A:
+               /* enable only access */
+               reg_tcr_el1_write(tcr | TCR_HA);
+               isb();
+               break;
+       case ID_AA64MMFR1_EL1_HAFDBS_AD:
+               /* enable both access and dirty */
+               reg_tcr_el1_write(tcr | TCR_HD | TCR_HA);
+               isb();
+               break;
+       }
+#endif
+}
+
+void
 aarch64_pan_init(int primary)
 {
 #ifdef ARMV81_PAN
diff -r ad0098030ad8 -r b7f826c98b25 sys/arch/aarch64/aarch64/fault.c
--- a/sys/arch/aarch64/aarch64/fault.c  Mon Jan 31 08:43:05 2022 +0000
+++ b/sys/arch/aarch64/aarch64/fault.c  Mon Jan 31 09:16:09 2022 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: fault.c,v 1.21 2020/12/11 18:03:33 skrll Exp $ */
+/*     $NetBSD: fault.c,v 1.22 2022/01/31 09:16:09 ryo Exp $   */
 
 /*
  * Copyright (c) 2017 Ryo Shimizu <ryo%nerv.org@localhost>
@@ -27,9 +27,10 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fault.c,v 1.21 2020/12/11 18:03:33 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fault.c,v 1.22 2022/01/31 09:16:09 ryo Exp $");
 
 #include "opt_compat_netbsd32.h"
+#include "opt_cpuoptions.h"
 #include "opt_ddb.h"
 #include "opt_uvmhist.h"
 
@@ -199,9 +200,16 @@
        }
 
        /* reference/modified emulation */
-       if (pmap_fault_fixup(map->pmap, va, ftype, user)) {
-               UVMHIST_LOG(pmaphist, "fixed: va=%016llx", tf->tf_far, 0, 0, 0);
-               return;
+#ifdef ARMV81_HAFDBS
+       if (aarch64_hafdbs_enabled == ID_AA64MMFR1_EL1_HAFDBS_NONE ||
+           (aarch64_hafdbs_enabled == ID_AA64MMFR1_EL1_HAFDBS_A &&
+           ftype == VM_PROT_WRITE))
+#endif
+       {
+               if (pmap_fault_fixup(map->pmap, va, ftype, user)) {
+                       UVMHIST_LOG(pmaphist, "fixed: va=%016llx", tf->tf_far, 0, 0, 0);
+                       return;
+               }
        }
 
        fb = cpu_disable_onfault();
diff -r ad0098030ad8 -r b7f826c98b25 sys/arch/aarch64/aarch64/locore.S
--- a/sys/arch/aarch64/aarch64/locore.S Mon Jan 31 08:43:05 2022 +0000
+++ b/sys/arch/aarch64/aarch64/locore.S Mon Jan 31 09:16:09 2022 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: locore.S,v 1.84 2021/12/10 20:36:02 andvar Exp $       */
+/*     $NetBSD: locore.S,v 1.85 2022/01/31 09:16:09 ryo Exp $  */
 
 /*
  * Copyright (c) 2017 Ryo Shimizu <ryo%nerv.org@localhost>
@@ -38,7 +38,7 @@
 #include <aarch64/hypervisor.h>
 #include "assym.h"
 
-RCSID("$NetBSD: locore.S,v 1.84 2021/12/10 20:36:02 andvar Exp $")
+RCSID("$NetBSD: locore.S,v 1.85 2022/01/31 09:16:09 ryo Exp $")
 
 #ifdef AARCH64_DEVICE_MEM_STRONGLY_ORDERED
 #define        MAIR_DEVICE_MEM         MAIR_DEVICE_nGnRnE
@@ -180,6 +180,10 @@
        msr     tpidr_el1, x0
        DPRINTREG("curlwp           = ", x0);
 
+       /* init HAFDBS if supported */
+       mov     x0, #1
+       bl      aarch64_hafdbs_init
+
        /* init PAN if supported */
        mov     x0, #1
        bl      aarch64_pan_init
@@ -545,6 +549,10 @@
        add     x2, x2, #(UPAGES * PAGE_SIZE)
        sub     sp, x2, #TF_SIZE        /* sp = pcb + USPACE - TF_SIZE */
 
+       /* init HAFDBS if supported */
+       mov     x0, #0
+       bl      aarch64_hafdbs_init
+
        /* init PAN if supported */
        mov     x0, #0
        bl      aarch64_pan_init
diff -r ad0098030ad8 -r b7f826c98b25 sys/arch/aarch64/aarch64/pmap.c
--- a/sys/arch/aarch64/aarch64/pmap.c   Mon Jan 31 08:43:05 2022 +0000
+++ b/sys/arch/aarch64/aarch64/pmap.c   Mon Jan 31 09:16:09 2022 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pmap.c,v 1.126 2022/01/31 08:43:05 ryo Exp $   */
+/*     $NetBSD: pmap.c,v 1.127 2022/01/31 09:16:09 ryo Exp $   */
 
 /*
  * Copyright (c) 2017 Ryo Shimizu <ryo%nerv.org@localhost>
@@ -27,9 +27,10 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.126 2022/01/31 08:43:05 ryo Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.127 2022/01/31 09:16:09 ryo Exp $");
 
 #include "opt_arm_debug.h"
+#include "opt_cpuoptions.h"
 #include "opt_ddb.h"
 #include "opt_modular.h"
 #include "opt_multiprocessor.h"
@@ -1018,43 +1019,43 @@
 }
 
 static pt_entry_t
-_pmap_pte_adjust_prot(pt_entry_t pte, vm_prot_t prot, vm_prot_t protmask,
+_pmap_pte_adjust_prot(pt_entry_t pte, vm_prot_t prot, vm_prot_t refmod,
     bool user)
 {
        vm_prot_t masked;
        pt_entry_t xn;
 
-       masked = prot & protmask;
-       pte &= ~(LX_BLKPAG_OS_RWMASK|LX_BLKPAG_AF|LX_BLKPAG_AP);
-
-       /* keep prot for ref/mod emulation */
-       switch (prot & (VM_PROT_READ|VM_PROT_WRITE)) {
-       case 0:
-       default:
-               break;
-       case VM_PROT_READ:
-               pte |= LX_BLKPAG_OS_READ;
-               break;
-       case VM_PROT_WRITE:
-       case VM_PROT_READ|VM_PROT_WRITE:
-               pte |= (LX_BLKPAG_OS_READ|LX_BLKPAG_OS_WRITE);
-               break;
-       }
+       masked = prot & refmod;
+       pte &= ~(LX_BLKPAG_OS_RWMASK|LX_BLKPAG_AF|LX_BLKPAG_DBM|LX_BLKPAG_AP);
+
+       /*
+        * keep actual prot in the pte as OS_{READ|WRITE} for ref/mod emulation,
+        * and set the DBM bit for HAFDBS if it has write permission.
+        */
+       pte |= LX_BLKPAG_OS_READ;       /* a valid pte can always be readable */
+       if (prot & VM_PROT_WRITE)
+               pte |= LX_BLKPAG_OS_WRITE|LX_BLKPAG_DBM;
 
        switch (masked & (VM_PROT_READ|VM_PROT_WRITE)) {
        case 0:
        default:
-               /* cannot access due to No LX_BLKPAG_AF */
+               /*
+                * it cannot be accessed because there is no AF bit,
+                * but the AF bit will be added by fixup() or HAFDBS.
+                */
                pte |= LX_BLKPAG_AP_RO;
                break;
        case VM_PROT_READ:
-               /* actual permission of pte */
+               /*
+                * as it is RO, it cannot be written as is,
+                * but it may be changed to RW by fixup() or HAFDBS.
+                */
                pte |= LX_BLKPAG_AF;
                pte |= LX_BLKPAG_AP_RO;
                break;
        case VM_PROT_WRITE:
        case VM_PROT_READ|VM_PROT_WRITE:
-               /* actual permission of pte */
+               /* fully readable and writable */
                pte |= LX_BLKPAG_AF;
                pte |= LX_BLKPAG_AP_RW;
                break;
@@ -1098,6 +1099,24 @@
        return pte;
 }



Home | Main Index | Thread Index | Old Index