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