All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC] arm64: properly define SOFT_DIRTY for arm64
@ 2023-07-03 13:55 ` Nico Pache
  0 siblings, 0 replies; 13+ messages in thread
From: Nico Pache @ 2023-07-03 13:55 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: aquini, Andrew Morton, Anshuman Khandual, Catalin Marinas,
	David Hildenbrand, Gerald Schaefer, Liu Shixin, Will Deacon,
	Yu Zhao

ARM64 has a soft-dirty bit (software dirty) but never properly defines
CONFIG_ARCH_HAS_SOFT_DIRTY or its necessary functions. This patch
introduces the ability to set/clear the soft dirty bit in a similar
manner as the other arches that utilize it.

However, we must be careful... there are cases where the DBM bit is not
available and the software dirty bit plays a essential role in determining
whether or not a page is dirty. In these cases we must not allow the
user to clear the software dirty bit. We can test for these cases by
utilizing the arch_faults_on_old_pte() function which test the availability
of DBM.

Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Anshuman Khandual <anshuman.khandual@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: David Hildenbrand <david@redhat.com>
Cc: Gerald Schaefer <gerald.schaefer@linux.ibm.com>
Cc: Liu Shixin <liushixin2@huawei.com>
Cc: Will Deacon <will@kernel.org>
Cc: Yu Zhao <yuzhao@google.com>
Signed-off-by: Nico Pache <npache@redhat.com>
---
 arch/arm64/Kconfig               |  1 +
 arch/arm64/include/asm/pgtable.h | 77 +++++++++++++++++++++++++++++++-
 2 files changed, 76 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 891ab530a665..4de491627f49 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -173,6 +173,7 @@ config ARM64
 	select HAVE_ARCH_PREL32_RELOCATIONS
 	select HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET
 	select HAVE_ARCH_SECCOMP_FILTER
+	select HAVE_ARCH_SOFT_DIRTY
 	select HAVE_ARCH_STACKLEAK
 	select HAVE_ARCH_THREAD_STRUCT_WHITELIST
 	select HAVE_ARCH_TRACEHOOK
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 0bd18de9fd97..a0a15ffa2417 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -121,8 +121,9 @@ static inline pteval_t __phys_to_pte_val(phys_addr_t phys)
 })
 
 #define pte_hw_dirty(pte)	(pte_write(pte) && !(pte_val(pte) & PTE_RDONLY))
-#define pte_sw_dirty(pte)	(!!(pte_val(pte) & PTE_DIRTY))
-#define pte_dirty(pte)		(pte_sw_dirty(pte) || pte_hw_dirty(pte))
+#define pte_soft_dirty(pte)	(!!(pte_val(pte) & PTE_DIRTY))
+#define pte_dirty(pte)		(pte_soft_dirty(pte) || pte_hw_dirty(pte))
+#define pte_swp_soft_dirty(pte)	pte_soft_dirty(pte)
 
 #define pte_valid(pte)		(!!(pte_val(pte) & PTE_VALID))
 /*
@@ -1096,6 +1097,78 @@ static inline bool pud_sect_supported(void)
 	return PAGE_SIZE == SZ_4K;
 }
 
+#ifdef CONFIG_ARM64_HW_AFDBM
+/*
+ * if we have the DBM bit we can utilize the software dirty bit as
+ * a mechanism to introduce the soft_dirty functionality; however, without
+ * it this bit is crucial to determining if a entry is dirty and we cannot
+ * clear it via software. DBM can also be disabled or broken on some early
+ * armv8 devices, so check its availability before modifying it.
+ */
+static inline pte_t pte_clear_soft_dirty(pte_t pte)
+{
+	if (arch_faults_on_old_pte())
+		return pte;
+
+	return clear_pte_bit(pte, __pgprot(PTE_DIRTY));
+}
+
+static inline pte_t pte_mksoft_dirty(pte_t pte)
+{
+	if (arch_faults_on_old_pte())
+		return pte;
+
+	return set_pte_bit(pte, __pgprot(PTE_DIRTY));
+}
+
+static inline pte_t pte_swp_clear_soft_dirty(pte_t pte)
+{
+	if (arch_faults_on_old_pte())
+		return pte;
+
+	return clear_pte_bit(pte, __pgprot(PTE_DIRTY));
+}
+
+static inline pte_t pte_swp_mksoft_dirty(pte_t pte)
+{
+	if (arch_faults_on_old_pte())
+		return pte;
+
+	return set_pte_bit(pte, __pgprot(PTE_DIRTY));
+}
+
+static inline int pmd_soft_dirty(pmd_t pmd)
+{
+	return pte_soft_dirty(pmd_pte(pmd));
+}
+
+static inline pmd_t pmd_clear_soft_dirty(pmd_t pmd)
+{
+	return pte_pmd(pte_clear_soft_dirty(pmd_pte(pmd)));
+}
+
+static inline pmd_t pmd_mksoft_dirty(pmd_t pmd)
+{
+	return pte_pmd(pte_mksoft_dirty(pmd_pte(pmd)));
+}
+
+#ifdef CONFIG_ARCH_ENABLE_THP_MIGRATION
+static inline int pmd_swp_soft_dirty(pmd_t pmd)
+{
+	return pmd_soft_dirty(pmd);
+}
+
+static inline pmd_t pmd_swp_clear_soft_dirty(pmd_t pmd)
+{
+	return pmd_clear_soft_dirty(pmd);
+}
+
+static inline pmd_t pmd_swp_mksoft_dirty(pmd_t pmd)
+{
+	return pmd_mksoft_dirty(pmd);
+}
+#endif /* CONFIG_ARCH_ENABLE_THP_MIGRATION */
+#endif /* CONFIG_ARM64_HW_AFDBM */
 
 #define __HAVE_ARCH_PTEP_MODIFY_PROT_TRANSACTION
 #define ptep_modify_prot_start ptep_modify_prot_start
-- 
2.41.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [RFC] arm64: properly define SOFT_DIRTY for arm64
@ 2023-07-03 13:55 ` Nico Pache
  0 siblings, 0 replies; 13+ messages in thread
From: Nico Pache @ 2023-07-03 13:55 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: aquini, Andrew Morton, Anshuman Khandual, Catalin Marinas,
	David Hildenbrand, Gerald Schaefer, Liu Shixin, Will Deacon,
	Yu Zhao

ARM64 has a soft-dirty bit (software dirty) but never properly defines
CONFIG_ARCH_HAS_SOFT_DIRTY or its necessary functions. This patch
introduces the ability to set/clear the soft dirty bit in a similar
manner as the other arches that utilize it.

However, we must be careful... there are cases where the DBM bit is not
available and the software dirty bit plays a essential role in determining
whether or not a page is dirty. In these cases we must not allow the
user to clear the software dirty bit. We can test for these cases by
utilizing the arch_faults_on_old_pte() function which test the availability
of DBM.

Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Anshuman Khandual <anshuman.khandual@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: David Hildenbrand <david@redhat.com>
Cc: Gerald Schaefer <gerald.schaefer@linux.ibm.com>
Cc: Liu Shixin <liushixin2@huawei.com>
Cc: Will Deacon <will@kernel.org>
Cc: Yu Zhao <yuzhao@google.com>
Signed-off-by: Nico Pache <npache@redhat.com>
---
 arch/arm64/Kconfig               |  1 +
 arch/arm64/include/asm/pgtable.h | 77 +++++++++++++++++++++++++++++++-
 2 files changed, 76 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 891ab530a665..4de491627f49 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -173,6 +173,7 @@ config ARM64
 	select HAVE_ARCH_PREL32_RELOCATIONS
 	select HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET
 	select HAVE_ARCH_SECCOMP_FILTER
+	select HAVE_ARCH_SOFT_DIRTY
 	select HAVE_ARCH_STACKLEAK
 	select HAVE_ARCH_THREAD_STRUCT_WHITELIST
 	select HAVE_ARCH_TRACEHOOK
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 0bd18de9fd97..a0a15ffa2417 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -121,8 +121,9 @@ static inline pteval_t __phys_to_pte_val(phys_addr_t phys)
 })
 
 #define pte_hw_dirty(pte)	(pte_write(pte) && !(pte_val(pte) & PTE_RDONLY))
-#define pte_sw_dirty(pte)	(!!(pte_val(pte) & PTE_DIRTY))
-#define pte_dirty(pte)		(pte_sw_dirty(pte) || pte_hw_dirty(pte))
+#define pte_soft_dirty(pte)	(!!(pte_val(pte) & PTE_DIRTY))
+#define pte_dirty(pte)		(pte_soft_dirty(pte) || pte_hw_dirty(pte))
+#define pte_swp_soft_dirty(pte)	pte_soft_dirty(pte)
 
 #define pte_valid(pte)		(!!(pte_val(pte) & PTE_VALID))
 /*
@@ -1096,6 +1097,78 @@ static inline bool pud_sect_supported(void)
 	return PAGE_SIZE == SZ_4K;
 }
 
+#ifdef CONFIG_ARM64_HW_AFDBM
+/*
+ * if we have the DBM bit we can utilize the software dirty bit as
+ * a mechanism to introduce the soft_dirty functionality; however, without
+ * it this bit is crucial to determining if a entry is dirty and we cannot
+ * clear it via software. DBM can also be disabled or broken on some early
+ * armv8 devices, so check its availability before modifying it.
+ */
+static inline pte_t pte_clear_soft_dirty(pte_t pte)
+{
+	if (arch_faults_on_old_pte())
+		return pte;
+
+	return clear_pte_bit(pte, __pgprot(PTE_DIRTY));
+}
+
+static inline pte_t pte_mksoft_dirty(pte_t pte)
+{
+	if (arch_faults_on_old_pte())
+		return pte;
+
+	return set_pte_bit(pte, __pgprot(PTE_DIRTY));
+}
+
+static inline pte_t pte_swp_clear_soft_dirty(pte_t pte)
+{
+	if (arch_faults_on_old_pte())
+		return pte;
+
+	return clear_pte_bit(pte, __pgprot(PTE_DIRTY));
+}
+
+static inline pte_t pte_swp_mksoft_dirty(pte_t pte)
+{
+	if (arch_faults_on_old_pte())
+		return pte;
+
+	return set_pte_bit(pte, __pgprot(PTE_DIRTY));
+}
+
+static inline int pmd_soft_dirty(pmd_t pmd)
+{
+	return pte_soft_dirty(pmd_pte(pmd));
+}
+
+static inline pmd_t pmd_clear_soft_dirty(pmd_t pmd)
+{
+	return pte_pmd(pte_clear_soft_dirty(pmd_pte(pmd)));
+}
+
+static inline pmd_t pmd_mksoft_dirty(pmd_t pmd)
+{
+	return pte_pmd(pte_mksoft_dirty(pmd_pte(pmd)));
+}
+
+#ifdef CONFIG_ARCH_ENABLE_THP_MIGRATION
+static inline int pmd_swp_soft_dirty(pmd_t pmd)
+{
+	return pmd_soft_dirty(pmd);
+}
+
+static inline pmd_t pmd_swp_clear_soft_dirty(pmd_t pmd)
+{
+	return pmd_clear_soft_dirty(pmd);
+}
+
+static inline pmd_t pmd_swp_mksoft_dirty(pmd_t pmd)
+{
+	return pmd_mksoft_dirty(pmd);
+}
+#endif /* CONFIG_ARCH_ENABLE_THP_MIGRATION */
+#endif /* CONFIG_ARM64_HW_AFDBM */
 
 #define __HAVE_ARCH_PTEP_MODIFY_PROT_TRANSACTION
 #define ptep_modify_prot_start ptep_modify_prot_start
-- 
2.41.0


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

* Re: [RFC] arm64: properly define SOFT_DIRTY for arm64
  2023-07-03 13:55 ` Nico Pache
  (?)
@ 2023-07-04  2:00 ` kernel test robot
  -1 siblings, 0 replies; 13+ messages in thread
From: kernel test robot @ 2023-07-04  2:00 UTC (permalink / raw)
  To: Nico Pache; +Cc: llvm, oe-kbuild-all

Hi Nico,

[This is a private test report for your RFC patch.]
kernel test robot noticed the following build errors:

[auto build test ERROR on arm64/for-next/core]
[also build test ERROR on arm/for-next arm/fixes kvmarm/next soc/for-next linus/master v6.4 next-20230703]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Nico-Pache/arm64-properly-define-SOFT_DIRTY-for-arm64/20230703-220825
base:   https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git for-next/core
patch link:    https://lore.kernel.org/r/20230703135526.930004-1-npache%40redhat.com
patch subject: [RFC] arm64: properly define SOFT_DIRTY for arm64
config: arm64-randconfig-r022-20230703 (https://download.01.org/0day-ci/archive/20230704/202307040950.rfBxS8hh-lkp@intel.com/config)
compiler: clang version 17.0.0 (https://github.com/llvm/llvm-project.git 4a5ac14ee968ff0ad5d2cc1ffa0299048db4c88a)
reproduce: (https://download.01.org/0day-ci/archive/20230704/202307040950.rfBxS8hh-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202307040950.rfBxS8hh-lkp@intel.com/

All errors (new ones prefixed by >>):

   In file included from arch/arm64/kernel/asm-offsets.c:10:
   In file included from include/linux/arm_sdei.h:8:
   In file included from include/acpi/ghes.h:5:
   In file included from include/acpi/apei.h:9:
   In file included from include/linux/acpi.h:13:
   In file included from include/linux/resource_ext.h:11:
   In file included from include/linux/slab.h:163:
   In file included from include/linux/kasan.h:33:
   In file included from include/linux/pgtable.h:6:
>> arch/arm64/include/asm/pgtable.h:1110:6: error: call to undeclared function 'arch_faults_on_old_pte'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
    1110 |         if (arch_faults_on_old_pte())
         |             ^
   arch/arm64/include/asm/pgtable.h:1118:6: error: call to undeclared function 'arch_faults_on_old_pte'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
    1118 |         if (arch_faults_on_old_pte())
         |             ^
   arch/arm64/include/asm/pgtable.h:1126:6: error: call to undeclared function 'arch_faults_on_old_pte'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
    1126 |         if (arch_faults_on_old_pte())
         |             ^
   arch/arm64/include/asm/pgtable.h:1134:6: error: call to undeclared function 'arch_faults_on_old_pte'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
    1134 |         if (arch_faults_on_old_pte())
         |             ^
   In file included from arch/arm64/kernel/asm-offsets.c:10:
   In file included from include/linux/arm_sdei.h:8:
   In file included from include/acpi/ghes.h:5:
   In file included from include/acpi/apei.h:9:
   In file included from include/linux/acpi.h:14:
   In file included from include/linux/device.h:32:
   In file included from include/linux/device/driver.h:21:
   In file included from include/linux/module.h:19:
   In file included from include/linux/elf.h:6:
   In file included from arch/arm64/include/asm/elf.h:141:
   In file included from include/linux/fs.h:33:
   In file included from include/linux/percpu-rwsem.h:7:
   In file included from include/linux/rcuwait.h:6:
   In file included from include/linux/sched/signal.h:6:
   include/linux/signal.h:97:11: warning: array index 3 is past the end of the array (that has type 'unsigned long[1]') [-Warray-bounds]
      97 |                 return (set->sig[3] | set->sig[2] |
         |                         ^        ~
   include/uapi/asm-generic/signal.h:62:2: note: array 'sig' declared here
      62 |         unsigned long sig[_NSIG_WORDS];
         |         ^
   In file included from arch/arm64/kernel/asm-offsets.c:10:
   In file included from include/linux/arm_sdei.h:8:
   In file included from include/acpi/ghes.h:5:
   In file included from include/acpi/apei.h:9:
   In file included from include/linux/acpi.h:14:
   In file included from include/linux/device.h:32:
   In file included from include/linux/device/driver.h:21:
   In file included from include/linux/module.h:19:
   In file included from include/linux/elf.h:6:
   In file included from arch/arm64/include/asm/elf.h:141:
   In file included from include/linux/fs.h:33:
   In file included from include/linux/percpu-rwsem.h:7:
   In file included from include/linux/rcuwait.h:6:
   In file included from include/linux/sched/signal.h:6:
   include/linux/signal.h:97:25: warning: array index 2 is past the end of the array (that has type 'unsigned long[1]') [-Warray-bounds]
      97 |                 return (set->sig[3] | set->sig[2] |
         |                                       ^        ~
   include/uapi/asm-generic/signal.h:62:2: note: array 'sig' declared here
      62 |         unsigned long sig[_NSIG_WORDS];
         |         ^
   In file included from arch/arm64/kernel/asm-offsets.c:10:
   In file included from include/linux/arm_sdei.h:8:
   In file included from include/acpi/ghes.h:5:
   In file included from include/acpi/apei.h:9:
   In file included from include/linux/acpi.h:14:
   In file included from include/linux/device.h:32:
   In file included from include/linux/device/driver.h:21:
   In file included from include/linux/module.h:19:
   In file included from include/linux/elf.h:6:
   In file included from arch/arm64/include/asm/elf.h:141:
   In file included from include/linux/fs.h:33:
   In file included from include/linux/percpu-rwsem.h:7:
   In file included from include/linux/rcuwait.h:6:
   In file included from include/linux/sched/signal.h:6:
   include/linux/signal.h:98:4: warning: array index 1 is past the end of the array (that has type 'unsigned long[1]') [-Warray-bounds]
      98 |                         set->sig[1] | set->sig[0]) == 0;
         |                         ^        ~
   include/uapi/asm-generic/signal.h:62:2: note: array 'sig' declared here
      62 |         unsigned long sig[_NSIG_WORDS];
         |         ^
   In file included from arch/arm64/kernel/asm-offsets.c:10:
   In file included from include/linux/arm_sdei.h:8:
   In file included from include/acpi/ghes.h:5:
   In file included from include/acpi/apei.h:9:
   In file included from include/linux/acpi.h:14:
   In file included from include/linux/device.h:32:
   In file included from include/linux/device/driver.h:21:
   In file included from include/linux/module.h:19:
   In file included from include/linux/elf.h:6:
   In file included from arch/arm64/include/asm/elf.h:141:
   In file included from include/linux/fs.h:33:
   In file included from include/linux/percpu-rwsem.h:7:
   In file included from include/linux/rcuwait.h:6:
   In file included from include/linux/sched/signal.h:6:
   include/linux/signal.h:100:11: warning: array index 1 is past the end of the array (that has type 'unsigned long[1]') [-Warray-bounds]
     100 |                 return (set->sig[1] | set->sig[0]) == 0;
         |                         ^        ~
   include/uapi/asm-generic/signal.h:62:2: note: array 'sig' declared here
      62 |         unsigned long sig[_NSIG_WORDS];
         |         ^
   In file included from arch/arm64/kernel/asm-offsets.c:10:
   In file included from include/linux/arm_sdei.h:8:
   In file included from include/acpi/ghes.h:5:
   In file included from include/acpi/apei.h:9:
   In file included from include/linux/acpi.h:14:
   In file included from include/linux/device.h:32:
   In file included from include/linux/device/driver.h:21:
   In file included from include/linux/module.h:19:
   In file included from include/linux/elf.h:6:


vim +/arch_faults_on_old_pte +1110 arch/arm64/include/asm/pgtable.h

  1099	
  1100	#ifdef CONFIG_ARM64_HW_AFDBM
  1101	/*
  1102	 * if we have the DBM bit we can utilize the software dirty bit as
  1103	 * a mechanism to introduce the soft_dirty functionality; however, without
  1104	 * it this bit is crucial to determining if a entry is dirty and we cannot
  1105	 * clear it via software. DBM can also be disabled or broken on some early
  1106	 * armv8 devices, so check its availability before modifying it.
  1107	 */
  1108	static inline pte_t pte_clear_soft_dirty(pte_t pte)
  1109	{
> 1110		if (arch_faults_on_old_pte())
  1111			return pte;
  1112	
  1113		return clear_pte_bit(pte, __pgprot(PTE_DIRTY));
  1114	}
  1115	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

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

* Re: [RFC] arm64: properly define SOFT_DIRTY for arm64
  2023-07-03 13:55 ` Nico Pache
  (?)
  (?)
@ 2023-07-04  2:31 ` kernel test robot
  -1 siblings, 0 replies; 13+ messages in thread
From: kernel test robot @ 2023-07-04  2:31 UTC (permalink / raw)
  To: Nico Pache; +Cc: oe-kbuild-all

Hi Nico,

[This is a private test report for your RFC patch.]
kernel test robot noticed the following build errors:

[auto build test ERROR on arm64/for-next/core]
[also build test ERROR on arm/for-next arm/fixes kvmarm/next soc/for-next linus/master v6.4 next-20230703]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Nico-Pache/arm64-properly-define-SOFT_DIRTY-for-arm64/20230703-220825
base:   https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git for-next/core
patch link:    https://lore.kernel.org/r/20230703135526.930004-1-npache%40redhat.com
patch subject: [RFC] arm64: properly define SOFT_DIRTY for arm64
config: arm64-allyesconfig (https://download.01.org/0day-ci/archive/20230704/202307041014.1YFuFmew-lkp@intel.com/config)
compiler: aarch64-linux-gcc (GCC) 12.3.0
reproduce: (https://download.01.org/0day-ci/archive/20230704/202307041014.1YFuFmew-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202307041014.1YFuFmew-lkp@intel.com/

All errors (new ones prefixed by >>):

   scripts/genksyms/parse.y: warning: 9 shift/reduce conflicts [-Wconflicts-sr]
   scripts/genksyms/parse.y: warning: 5 reduce/reduce conflicts [-Wconflicts-rr]
   scripts/genksyms/parse.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
   In file included from include/linux/pgtable.h:6,
                    from arch/arm64/include/asm/io.h:12,
                    from include/linux/io.h:13,
                    from include/acpi/acpi_io.h:5,
                    from include/linux/acpi.h:37,
                    from include/acpi/apei.h:9,
                    from include/acpi/ghes.h:5,
                    from include/linux/arm_sdei.h:8,
                    from arch/arm64/kernel/asm-offsets.c:10:
   arch/arm64/include/asm/pgtable.h: In function 'pte_clear_soft_dirty':
>> arch/arm64/include/asm/pgtable.h:1110:13: error: implicit declaration of function 'arch_faults_on_old_pte' [-Werror=implicit-function-declaration]
    1110 |         if (arch_faults_on_old_pte())
         |             ^~~~~~~~~~~~~~~~~~~~~~
   cc1: some warnings being treated as errors
   make[2]: *** [scripts/Makefile.build:114: arch/arm64/kernel/asm-offsets.s] Error 1
   make[2]: Target 'prepare' not remade because of errors.
   make[1]: *** [Makefile:1287: prepare0] Error 2
   make[1]: Target 'prepare' not remade because of errors.
   make: *** [Makefile:226: __sub-make] Error 2
   make: Target 'prepare' not remade because of errors.


vim +/arch_faults_on_old_pte +1110 arch/arm64/include/asm/pgtable.h

  1099	
  1100	#ifdef CONFIG_ARM64_HW_AFDBM
  1101	/*
  1102	 * if we have the DBM bit we can utilize the software dirty bit as
  1103	 * a mechanism to introduce the soft_dirty functionality; however, without
  1104	 * it this bit is crucial to determining if a entry is dirty and we cannot
  1105	 * clear it via software. DBM can also be disabled or broken on some early
  1106	 * armv8 devices, so check its availability before modifying it.
  1107	 */
  1108	static inline pte_t pte_clear_soft_dirty(pte_t pte)
  1109	{
> 1110		if (arch_faults_on_old_pte())
  1111			return pte;
  1112	
  1113		return clear_pte_bit(pte, __pgprot(PTE_DIRTY));
  1114	}
  1115	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

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

* Re: [RFC] arm64: properly define SOFT_DIRTY for arm64
  2023-07-03 13:55 ` Nico Pache
@ 2023-07-04  9:58   ` Nico Pache
  -1 siblings, 0 replies; 13+ messages in thread
From: Nico Pache @ 2023-07-04  9:58 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: aquini, Andrew Morton, Anshuman Khandual, Catalin Marinas,
	David Hildenbrand, Gerald Schaefer, Liu Shixin, Will Deacon,
	Yu Zhao

Whoops I pulled but never actually rebased... commit e1fd09e3d1dd
("mm: x86, arm64: add arch_has_hw_pte_young()") changed
arch_faults_on_old_pte() into !arch_has_hw_pte_young(). Following up
with a V2 shortly.

-- Nico

On Mon, Jul 3, 2023 at 10:06 AM Nico Pache <npache@redhat.com> wrote:
>
> ARM64 has a soft-dirty bit (software dirty) but never properly defines
> CONFIG_ARCH_HAS_SOFT_DIRTY or its necessary functions. This patch
> introduces the ability to set/clear the soft dirty bit in a similar
> manner as the other arches that utilize it.
>
> However, we must be careful... there are cases where the DBM bit is not
> available and the software dirty bit plays a essential role in determining
> whether or not a page is dirty. In these cases we must not allow the
> user to clear the software dirty bit. We can test for these cases by
> utilizing the arch_faults_on_old_pte() function which test the availability
> of DBM.
>
> Cc: Andrew Morton <akpm@linux-foundation.org>
> Cc: Anshuman Khandual <anshuman.khandual@arm.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: David Hildenbrand <david@redhat.com>
> Cc: Gerald Schaefer <gerald.schaefer@linux.ibm.com>
> Cc: Liu Shixin <liushixin2@huawei.com>
> Cc: Will Deacon <will@kernel.org>
> Cc: Yu Zhao <yuzhao@google.com>
> Signed-off-by: Nico Pache <npache@redhat.com>
> ---
>  arch/arm64/Kconfig               |  1 +
>  arch/arm64/include/asm/pgtable.h | 77 +++++++++++++++++++++++++++++++-
>  2 files changed, 76 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index 891ab530a665..4de491627f49 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -173,6 +173,7 @@ config ARM64
>         select HAVE_ARCH_PREL32_RELOCATIONS
>         select HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET
>         select HAVE_ARCH_SECCOMP_FILTER
> +       select HAVE_ARCH_SOFT_DIRTY
>         select HAVE_ARCH_STACKLEAK
>         select HAVE_ARCH_THREAD_STRUCT_WHITELIST
>         select HAVE_ARCH_TRACEHOOK
> diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
> index 0bd18de9fd97..a0a15ffa2417 100644
> --- a/arch/arm64/include/asm/pgtable.h
> +++ b/arch/arm64/include/asm/pgtable.h
> @@ -121,8 +121,9 @@ static inline pteval_t __phys_to_pte_val(phys_addr_t phys)
>  })
>
>  #define pte_hw_dirty(pte)      (pte_write(pte) && !(pte_val(pte) & PTE_RDONLY))
> -#define pte_sw_dirty(pte)      (!!(pte_val(pte) & PTE_DIRTY))
> -#define pte_dirty(pte)         (pte_sw_dirty(pte) || pte_hw_dirty(pte))
> +#define pte_soft_dirty(pte)    (!!(pte_val(pte) & PTE_DIRTY))
> +#define pte_dirty(pte)         (pte_soft_dirty(pte) || pte_hw_dirty(pte))
> +#define pte_swp_soft_dirty(pte)        pte_soft_dirty(pte)
>
>  #define pte_valid(pte)         (!!(pte_val(pte) & PTE_VALID))
>  /*
> @@ -1096,6 +1097,78 @@ static inline bool pud_sect_supported(void)
>         return PAGE_SIZE == SZ_4K;
>  }
>
> +#ifdef CONFIG_ARM64_HW_AFDBM
> +/*
> + * if we have the DBM bit we can utilize the software dirty bit as
> + * a mechanism to introduce the soft_dirty functionality; however, without
> + * it this bit is crucial to determining if a entry is dirty and we cannot
> + * clear it via software. DBM can also be disabled or broken on some early
> + * armv8 devices, so check its availability before modifying it.
> + */
> +static inline pte_t pte_clear_soft_dirty(pte_t pte)
> +{
> +       if (arch_faults_on_old_pte())
> +               return pte;
> +
> +       return clear_pte_bit(pte, __pgprot(PTE_DIRTY));
> +}
> +
> +static inline pte_t pte_mksoft_dirty(pte_t pte)
> +{
> +       if (arch_faults_on_old_pte())
> +               return pte;
> +
> +       return set_pte_bit(pte, __pgprot(PTE_DIRTY));
> +}
> +
> +static inline pte_t pte_swp_clear_soft_dirty(pte_t pte)
> +{
> +       if (arch_faults_on_old_pte())
> +               return pte;
> +
> +       return clear_pte_bit(pte, __pgprot(PTE_DIRTY));
> +}
> +
> +static inline pte_t pte_swp_mksoft_dirty(pte_t pte)
> +{
> +       if (arch_faults_on_old_pte())
> +               return pte;
> +
> +       return set_pte_bit(pte, __pgprot(PTE_DIRTY));
> +}
> +
> +static inline int pmd_soft_dirty(pmd_t pmd)
> +{
> +       return pte_soft_dirty(pmd_pte(pmd));
> +}
> +
> +static inline pmd_t pmd_clear_soft_dirty(pmd_t pmd)
> +{
> +       return pte_pmd(pte_clear_soft_dirty(pmd_pte(pmd)));
> +}
> +
> +static inline pmd_t pmd_mksoft_dirty(pmd_t pmd)
> +{
> +       return pte_pmd(pte_mksoft_dirty(pmd_pte(pmd)));
> +}
> +
> +#ifdef CONFIG_ARCH_ENABLE_THP_MIGRATION
> +static inline int pmd_swp_soft_dirty(pmd_t pmd)
> +{
> +       return pmd_soft_dirty(pmd);
> +}
> +
> +static inline pmd_t pmd_swp_clear_soft_dirty(pmd_t pmd)
> +{
> +       return pmd_clear_soft_dirty(pmd);
> +}
> +
> +static inline pmd_t pmd_swp_mksoft_dirty(pmd_t pmd)
> +{
> +       return pmd_mksoft_dirty(pmd);
> +}
> +#endif /* CONFIG_ARCH_ENABLE_THP_MIGRATION */
> +#endif /* CONFIG_ARM64_HW_AFDBM */
>
>  #define __HAVE_ARCH_PTEP_MODIFY_PROT_TRANSACTION
>  #define ptep_modify_prot_start ptep_modify_prot_start
> --
> 2.41.0
>


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [RFC] arm64: properly define SOFT_DIRTY for arm64
@ 2023-07-04  9:58   ` Nico Pache
  0 siblings, 0 replies; 13+ messages in thread
From: Nico Pache @ 2023-07-04  9:58 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: aquini, Andrew Morton, Anshuman Khandual, Catalin Marinas,
	David Hildenbrand, Gerald Schaefer, Liu Shixin, Will Deacon,
	Yu Zhao

Whoops I pulled but never actually rebased... commit e1fd09e3d1dd
("mm: x86, arm64: add arch_has_hw_pte_young()") changed
arch_faults_on_old_pte() into !arch_has_hw_pte_young(). Following up
with a V2 shortly.

-- Nico

On Mon, Jul 3, 2023 at 10:06 AM Nico Pache <npache@redhat.com> wrote:
>
> ARM64 has a soft-dirty bit (software dirty) but never properly defines
> CONFIG_ARCH_HAS_SOFT_DIRTY or its necessary functions. This patch
> introduces the ability to set/clear the soft dirty bit in a similar
> manner as the other arches that utilize it.
>
> However, we must be careful... there are cases where the DBM bit is not
> available and the software dirty bit plays a essential role in determining
> whether or not a page is dirty. In these cases we must not allow the
> user to clear the software dirty bit. We can test for these cases by
> utilizing the arch_faults_on_old_pte() function which test the availability
> of DBM.
>
> Cc: Andrew Morton <akpm@linux-foundation.org>
> Cc: Anshuman Khandual <anshuman.khandual@arm.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: David Hildenbrand <david@redhat.com>
> Cc: Gerald Schaefer <gerald.schaefer@linux.ibm.com>
> Cc: Liu Shixin <liushixin2@huawei.com>
> Cc: Will Deacon <will@kernel.org>
> Cc: Yu Zhao <yuzhao@google.com>
> Signed-off-by: Nico Pache <npache@redhat.com>
> ---
>  arch/arm64/Kconfig               |  1 +
>  arch/arm64/include/asm/pgtable.h | 77 +++++++++++++++++++++++++++++++-
>  2 files changed, 76 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index 891ab530a665..4de491627f49 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -173,6 +173,7 @@ config ARM64
>         select HAVE_ARCH_PREL32_RELOCATIONS
>         select HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET
>         select HAVE_ARCH_SECCOMP_FILTER
> +       select HAVE_ARCH_SOFT_DIRTY
>         select HAVE_ARCH_STACKLEAK
>         select HAVE_ARCH_THREAD_STRUCT_WHITELIST
>         select HAVE_ARCH_TRACEHOOK
> diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
> index 0bd18de9fd97..a0a15ffa2417 100644
> --- a/arch/arm64/include/asm/pgtable.h
> +++ b/arch/arm64/include/asm/pgtable.h
> @@ -121,8 +121,9 @@ static inline pteval_t __phys_to_pte_val(phys_addr_t phys)
>  })
>
>  #define pte_hw_dirty(pte)      (pte_write(pte) && !(pte_val(pte) & PTE_RDONLY))
> -#define pte_sw_dirty(pte)      (!!(pte_val(pte) & PTE_DIRTY))
> -#define pte_dirty(pte)         (pte_sw_dirty(pte) || pte_hw_dirty(pte))
> +#define pte_soft_dirty(pte)    (!!(pte_val(pte) & PTE_DIRTY))
> +#define pte_dirty(pte)         (pte_soft_dirty(pte) || pte_hw_dirty(pte))
> +#define pte_swp_soft_dirty(pte)        pte_soft_dirty(pte)
>
>  #define pte_valid(pte)         (!!(pte_val(pte) & PTE_VALID))
>  /*
> @@ -1096,6 +1097,78 @@ static inline bool pud_sect_supported(void)
>         return PAGE_SIZE == SZ_4K;
>  }
>
> +#ifdef CONFIG_ARM64_HW_AFDBM
> +/*
> + * if we have the DBM bit we can utilize the software dirty bit as
> + * a mechanism to introduce the soft_dirty functionality; however, without
> + * it this bit is crucial to determining if a entry is dirty and we cannot
> + * clear it via software. DBM can also be disabled or broken on some early
> + * armv8 devices, so check its availability before modifying it.
> + */
> +static inline pte_t pte_clear_soft_dirty(pte_t pte)
> +{
> +       if (arch_faults_on_old_pte())
> +               return pte;
> +
> +       return clear_pte_bit(pte, __pgprot(PTE_DIRTY));
> +}
> +
> +static inline pte_t pte_mksoft_dirty(pte_t pte)
> +{
> +       if (arch_faults_on_old_pte())
> +               return pte;
> +
> +       return set_pte_bit(pte, __pgprot(PTE_DIRTY));
> +}
> +
> +static inline pte_t pte_swp_clear_soft_dirty(pte_t pte)
> +{
> +       if (arch_faults_on_old_pte())
> +               return pte;
> +
> +       return clear_pte_bit(pte, __pgprot(PTE_DIRTY));
> +}
> +
> +static inline pte_t pte_swp_mksoft_dirty(pte_t pte)
> +{
> +       if (arch_faults_on_old_pte())
> +               return pte;
> +
> +       return set_pte_bit(pte, __pgprot(PTE_DIRTY));
> +}
> +
> +static inline int pmd_soft_dirty(pmd_t pmd)
> +{
> +       return pte_soft_dirty(pmd_pte(pmd));
> +}
> +
> +static inline pmd_t pmd_clear_soft_dirty(pmd_t pmd)
> +{
> +       return pte_pmd(pte_clear_soft_dirty(pmd_pte(pmd)));
> +}
> +
> +static inline pmd_t pmd_mksoft_dirty(pmd_t pmd)
> +{
> +       return pte_pmd(pte_mksoft_dirty(pmd_pte(pmd)));
> +}
> +
> +#ifdef CONFIG_ARCH_ENABLE_THP_MIGRATION
> +static inline int pmd_swp_soft_dirty(pmd_t pmd)
> +{
> +       return pmd_soft_dirty(pmd);
> +}
> +
> +static inline pmd_t pmd_swp_clear_soft_dirty(pmd_t pmd)
> +{
> +       return pmd_clear_soft_dirty(pmd);
> +}
> +
> +static inline pmd_t pmd_swp_mksoft_dirty(pmd_t pmd)
> +{
> +       return pmd_mksoft_dirty(pmd);
> +}
> +#endif /* CONFIG_ARCH_ENABLE_THP_MIGRATION */
> +#endif /* CONFIG_ARM64_HW_AFDBM */
>
>  #define __HAVE_ARCH_PTEP_MODIFY_PROT_TRANSACTION
>  #define ptep_modify_prot_start ptep_modify_prot_start
> --
> 2.41.0
>


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

* Re: [RFC] arm64: properly define SOFT_DIRTY for arm64
  2023-07-03 13:55 ` Nico Pache
@ 2023-07-04 10:01   ` Anshuman Khandual
  -1 siblings, 0 replies; 13+ messages in thread
From: Anshuman Khandual @ 2023-07-04 10:01 UTC (permalink / raw)
  To: Nico Pache, linux-arm-kernel, linux-kernel
  Cc: aquini, Andrew Morton, Catalin Marinas, David Hildenbrand,
	Gerald Schaefer, Liu Shixin, Will Deacon, Yu Zhao

Hi Nico,

On 7/3/23 19:25, Nico Pache wrote:
> ARM64 has a soft-dirty bit (software dirty) but never properly defines
> CONFIG_ARCH_HAS_SOFT_DIRTY or its necessary functions. This patch
> introduces the ability to set/clear the soft dirty bit in a similar
> manner as the other arches that utilize it.
> 
> However, we must be careful... there are cases where the DBM bit is not
> available and the software dirty bit plays a essential role in determining
> whether or not a page is dirty. In these cases we must not allow the
> user to clear the software dirty bit. We can test for these cases by
> utilizing the arch_faults_on_old_pte() function which test the availability
> of DBM.

The current soft-dirty bit is a SW PTE bit i.e PTE_DIRTY, tracking PTE
dirtiness in absence of HW DBM support, although both these tracking
methods are very much intertwined. Current pte helpers like pte_dirty(),
pte_mkdirty(), pte_mkclean(), and pte_wrrotect() etc operate both on
HW and SW dirty tracking bits irrespective of whether DBM is supported
or not.

For soft dirty to work, we need a software PTE bit which sticks around
on the PTE entry until user space (only) clears it and above PTE_DIRTY
bit cannot be used for that purpose as it could be cleared in the kernel.

static inline pte_t pte_mkclean(pte_t pte)
{
        pte = clear_pte_bit(pte, __pgprot(PTE_DIRTY));
        pte = set_pte_bit(pte, __pgprot(PTE_RDONLY));

        return pte;
}

BTW arch_faults_on_old_pte() is no longer available mainline.

- Anshuman

> 
> Cc: Andrew Morton <akpm@linux-foundation.org>
> Cc: Anshuman Khandual <anshuman.khandual@arm.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: David Hildenbrand <david@redhat.com>
> Cc: Gerald Schaefer <gerald.schaefer@linux.ibm.com>
> Cc: Liu Shixin <liushixin2@huawei.com>
> Cc: Will Deacon <will@kernel.org>
> Cc: Yu Zhao <yuzhao@google.com>
> Signed-off-by: Nico Pache <npache@redhat.com>
> ---
>  arch/arm64/Kconfig               |  1 +
>  arch/arm64/include/asm/pgtable.h | 77 +++++++++++++++++++++++++++++++-
>  2 files changed, 76 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index 891ab530a665..4de491627f49 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -173,6 +173,7 @@ config ARM64
>  	select HAVE_ARCH_PREL32_RELOCATIONS
>  	select HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET
>  	select HAVE_ARCH_SECCOMP_FILTER
> +	select HAVE_ARCH_SOFT_DIRTY
>  	select HAVE_ARCH_STACKLEAK
>  	select HAVE_ARCH_THREAD_STRUCT_WHITELIST
>  	select HAVE_ARCH_TRACEHOOK
> diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
> index 0bd18de9fd97..a0a15ffa2417 100644
> --- a/arch/arm64/include/asm/pgtable.h
> +++ b/arch/arm64/include/asm/pgtable.h
> @@ -121,8 +121,9 @@ static inline pteval_t __phys_to_pte_val(phys_addr_t phys)
>  })
>  
>  #define pte_hw_dirty(pte)	(pte_write(pte) && !(pte_val(pte) & PTE_RDONLY))
> -#define pte_sw_dirty(pte)	(!!(pte_val(pte) & PTE_DIRTY))
> -#define pte_dirty(pte)		(pte_sw_dirty(pte) || pte_hw_dirty(pte))
> +#define pte_soft_dirty(pte)	(!!(pte_val(pte) & PTE_DIRTY))
> +#define pte_dirty(pte)		(pte_soft_dirty(pte) || pte_hw_dirty(pte))
> +#define pte_swp_soft_dirty(pte)	pte_soft_dirty(pte)
>  
>  #define pte_valid(pte)		(!!(pte_val(pte) & PTE_VALID))
>  /*
> @@ -1096,6 +1097,78 @@ static inline bool pud_sect_supported(void)
>  	return PAGE_SIZE == SZ_4K;
>  }
>  
> +#ifdef CONFIG_ARM64_HW_AFDBM
> +/*
> + * if we have the DBM bit we can utilize the software dirty bit as
> + * a mechanism to introduce the soft_dirty functionality; however, without
> + * it this bit is crucial to determining if a entry is dirty and we cannot
> + * clear it via software. DBM can also be disabled or broken on some early
> + * armv8 devices, so check its availability before modifying it.
> + */
> +static inline pte_t pte_clear_soft_dirty(pte_t pte)
> +{
> +	if (arch_faults_on_old_pte())
> +		return pte;
> +
> +	return clear_pte_bit(pte, __pgprot(PTE_DIRTY));
> +}
> +
> +static inline pte_t pte_mksoft_dirty(pte_t pte)
> +{
> +	if (arch_faults_on_old_pte())
> +		return pte;
> +
> +	return set_pte_bit(pte, __pgprot(PTE_DIRTY));
> +}
> +
> +static inline pte_t pte_swp_clear_soft_dirty(pte_t pte)
> +{
> +	if (arch_faults_on_old_pte())
> +		return pte;
> +
> +	return clear_pte_bit(pte, __pgprot(PTE_DIRTY));
> +}
> +
> +static inline pte_t pte_swp_mksoft_dirty(pte_t pte)
> +{
> +	if (arch_faults_on_old_pte())
> +		return pte;
> +
> +	return set_pte_bit(pte, __pgprot(PTE_DIRTY));
> +}
> +
> +static inline int pmd_soft_dirty(pmd_t pmd)
> +{
> +	return pte_soft_dirty(pmd_pte(pmd));
> +}
> +
> +static inline pmd_t pmd_clear_soft_dirty(pmd_t pmd)
> +{
> +	return pte_pmd(pte_clear_soft_dirty(pmd_pte(pmd)));
> +}
> +
> +static inline pmd_t pmd_mksoft_dirty(pmd_t pmd)
> +{
> +	return pte_pmd(pte_mksoft_dirty(pmd_pte(pmd)));
> +}
> +
> +#ifdef CONFIG_ARCH_ENABLE_THP_MIGRATION
> +static inline int pmd_swp_soft_dirty(pmd_t pmd)
> +{
> +	return pmd_soft_dirty(pmd);
> +}
> +
> +static inline pmd_t pmd_swp_clear_soft_dirty(pmd_t pmd)
> +{
> +	return pmd_clear_soft_dirty(pmd);
> +}
> +
> +static inline pmd_t pmd_swp_mksoft_dirty(pmd_t pmd)
> +{
> +	return pmd_mksoft_dirty(pmd);
> +}
> +#endif /* CONFIG_ARCH_ENABLE_THP_MIGRATION */
> +#endif /* CONFIG_ARM64_HW_AFDBM */
>  
>  #define __HAVE_ARCH_PTEP_MODIFY_PROT_TRANSACTION
>  #define ptep_modify_prot_start ptep_modify_prot_start

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [RFC] arm64: properly define SOFT_DIRTY for arm64
@ 2023-07-04 10:01   ` Anshuman Khandual
  0 siblings, 0 replies; 13+ messages in thread
From: Anshuman Khandual @ 2023-07-04 10:01 UTC (permalink / raw)
  To: Nico Pache, linux-arm-kernel, linux-kernel
  Cc: aquini, Andrew Morton, Catalin Marinas, David Hildenbrand,
	Gerald Schaefer, Liu Shixin, Will Deacon, Yu Zhao

Hi Nico,

On 7/3/23 19:25, Nico Pache wrote:
> ARM64 has a soft-dirty bit (software dirty) but never properly defines
> CONFIG_ARCH_HAS_SOFT_DIRTY or its necessary functions. This patch
> introduces the ability to set/clear the soft dirty bit in a similar
> manner as the other arches that utilize it.
> 
> However, we must be careful... there are cases where the DBM bit is not
> available and the software dirty bit plays a essential role in determining
> whether or not a page is dirty. In these cases we must not allow the
> user to clear the software dirty bit. We can test for these cases by
> utilizing the arch_faults_on_old_pte() function which test the availability
> of DBM.

The current soft-dirty bit is a SW PTE bit i.e PTE_DIRTY, tracking PTE
dirtiness in absence of HW DBM support, although both these tracking
methods are very much intertwined. Current pte helpers like pte_dirty(),
pte_mkdirty(), pte_mkclean(), and pte_wrrotect() etc operate both on
HW and SW dirty tracking bits irrespective of whether DBM is supported
or not.

For soft dirty to work, we need a software PTE bit which sticks around
on the PTE entry until user space (only) clears it and above PTE_DIRTY
bit cannot be used for that purpose as it could be cleared in the kernel.

static inline pte_t pte_mkclean(pte_t pte)
{
        pte = clear_pte_bit(pte, __pgprot(PTE_DIRTY));
        pte = set_pte_bit(pte, __pgprot(PTE_RDONLY));

        return pte;
}

BTW arch_faults_on_old_pte() is no longer available mainline.

- Anshuman

> 
> Cc: Andrew Morton <akpm@linux-foundation.org>
> Cc: Anshuman Khandual <anshuman.khandual@arm.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: David Hildenbrand <david@redhat.com>
> Cc: Gerald Schaefer <gerald.schaefer@linux.ibm.com>
> Cc: Liu Shixin <liushixin2@huawei.com>
> Cc: Will Deacon <will@kernel.org>
> Cc: Yu Zhao <yuzhao@google.com>
> Signed-off-by: Nico Pache <npache@redhat.com>
> ---
>  arch/arm64/Kconfig               |  1 +
>  arch/arm64/include/asm/pgtable.h | 77 +++++++++++++++++++++++++++++++-
>  2 files changed, 76 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index 891ab530a665..4de491627f49 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -173,6 +173,7 @@ config ARM64
>  	select HAVE_ARCH_PREL32_RELOCATIONS
>  	select HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET
>  	select HAVE_ARCH_SECCOMP_FILTER
> +	select HAVE_ARCH_SOFT_DIRTY
>  	select HAVE_ARCH_STACKLEAK
>  	select HAVE_ARCH_THREAD_STRUCT_WHITELIST
>  	select HAVE_ARCH_TRACEHOOK
> diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
> index 0bd18de9fd97..a0a15ffa2417 100644
> --- a/arch/arm64/include/asm/pgtable.h
> +++ b/arch/arm64/include/asm/pgtable.h
> @@ -121,8 +121,9 @@ static inline pteval_t __phys_to_pte_val(phys_addr_t phys)
>  })
>  
>  #define pte_hw_dirty(pte)	(pte_write(pte) && !(pte_val(pte) & PTE_RDONLY))
> -#define pte_sw_dirty(pte)	(!!(pte_val(pte) & PTE_DIRTY))
> -#define pte_dirty(pte)		(pte_sw_dirty(pte) || pte_hw_dirty(pte))
> +#define pte_soft_dirty(pte)	(!!(pte_val(pte) & PTE_DIRTY))
> +#define pte_dirty(pte)		(pte_soft_dirty(pte) || pte_hw_dirty(pte))
> +#define pte_swp_soft_dirty(pte)	pte_soft_dirty(pte)
>  
>  #define pte_valid(pte)		(!!(pte_val(pte) & PTE_VALID))
>  /*
> @@ -1096,6 +1097,78 @@ static inline bool pud_sect_supported(void)
>  	return PAGE_SIZE == SZ_4K;
>  }
>  
> +#ifdef CONFIG_ARM64_HW_AFDBM
> +/*
> + * if we have the DBM bit we can utilize the software dirty bit as
> + * a mechanism to introduce the soft_dirty functionality; however, without
> + * it this bit is crucial to determining if a entry is dirty and we cannot
> + * clear it via software. DBM can also be disabled or broken on some early
> + * armv8 devices, so check its availability before modifying it.
> + */
> +static inline pte_t pte_clear_soft_dirty(pte_t pte)
> +{
> +	if (arch_faults_on_old_pte())
> +		return pte;
> +
> +	return clear_pte_bit(pte, __pgprot(PTE_DIRTY));
> +}
> +
> +static inline pte_t pte_mksoft_dirty(pte_t pte)
> +{
> +	if (arch_faults_on_old_pte())
> +		return pte;
> +
> +	return set_pte_bit(pte, __pgprot(PTE_DIRTY));
> +}
> +
> +static inline pte_t pte_swp_clear_soft_dirty(pte_t pte)
> +{
> +	if (arch_faults_on_old_pte())
> +		return pte;
> +
> +	return clear_pte_bit(pte, __pgprot(PTE_DIRTY));
> +}
> +
> +static inline pte_t pte_swp_mksoft_dirty(pte_t pte)
> +{
> +	if (arch_faults_on_old_pte())
> +		return pte;
> +
> +	return set_pte_bit(pte, __pgprot(PTE_DIRTY));
> +}
> +
> +static inline int pmd_soft_dirty(pmd_t pmd)
> +{
> +	return pte_soft_dirty(pmd_pte(pmd));
> +}
> +
> +static inline pmd_t pmd_clear_soft_dirty(pmd_t pmd)
> +{
> +	return pte_pmd(pte_clear_soft_dirty(pmd_pte(pmd)));
> +}
> +
> +static inline pmd_t pmd_mksoft_dirty(pmd_t pmd)
> +{
> +	return pte_pmd(pte_mksoft_dirty(pmd_pte(pmd)));
> +}
> +
> +#ifdef CONFIG_ARCH_ENABLE_THP_MIGRATION
> +static inline int pmd_swp_soft_dirty(pmd_t pmd)
> +{
> +	return pmd_soft_dirty(pmd);
> +}
> +
> +static inline pmd_t pmd_swp_clear_soft_dirty(pmd_t pmd)
> +{
> +	return pmd_clear_soft_dirty(pmd);
> +}
> +
> +static inline pmd_t pmd_swp_mksoft_dirty(pmd_t pmd)
> +{
> +	return pmd_mksoft_dirty(pmd);
> +}
> +#endif /* CONFIG_ARCH_ENABLE_THP_MIGRATION */
> +#endif /* CONFIG_ARM64_HW_AFDBM */
>  
>  #define __HAVE_ARCH_PTEP_MODIFY_PROT_TRANSACTION
>  #define ptep_modify_prot_start ptep_modify_prot_start

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

* Re: [RFC] arm64: properly define SOFT_DIRTY for arm64
  2023-07-04 10:01   ` Anshuman Khandual
@ 2023-07-04 10:08     ` Nico Pache
  -1 siblings, 0 replies; 13+ messages in thread
From: Nico Pache @ 2023-07-04 10:08 UTC (permalink / raw)
  To: Anshuman Khandual
  Cc: linux-arm-kernel, linux-kernel, aquini, Andrew Morton,
	Catalin Marinas, David Hildenbrand, Gerald Schaefer, Liu Shixin,
	Will Deacon, Yu Zhao

Hi Anshuman,

Thanks for the explanation!

Is it possible to add the same DBM check I'm using
(!arch_has_hw_pte_young) in these pte helper functions to only clear
it when DBM is not present?

Cheers,
-- Nico

On Tue, Jul 4, 2023 at 6:01 AM Anshuman Khandual
<anshuman.khandual@arm.com> wrote:
>
> Hi Nico,
>
> On 7/3/23 19:25, Nico Pache wrote:
> > ARM64 has a soft-dirty bit (software dirty) but never properly defines
> > CONFIG_ARCH_HAS_SOFT_DIRTY or its necessary functions. This patch
> > introduces the ability to set/clear the soft dirty bit in a similar
> > manner as the other arches that utilize it.
> >
> > However, we must be careful... there are cases where the DBM bit is not
> > available and the software dirty bit plays a essential role in determining
> > whether or not a page is dirty. In these cases we must not allow the
> > user to clear the software dirty bit. We can test for these cases by
> > utilizing the arch_faults_on_old_pte() function which test the availability
> > of DBM.
>
> The current soft-dirty bit is a SW PTE bit i.e PTE_DIRTY, tracking PTE
> dirtiness in absence of HW DBM support, although both these tracking
> methods are very much intertwined. Current pte helpers like pte_dirty(),
> pte_mkdirty(), pte_mkclean(), and pte_wrrotect() etc operate both on
> HW and SW dirty tracking bits irrespective of whether DBM is supported
> or not.
>
> For soft dirty to work, we need a software PTE bit which sticks around
> on the PTE entry until user space (only) clears it and above PTE_DIRTY
> bit cannot be used for that purpose as it could be cleared in the kernel.
>
> static inline pte_t pte_mkclean(pte_t pte)
> {
>         pte = clear_pte_bit(pte, __pgprot(PTE_DIRTY));
>         pte = set_pte_bit(pte, __pgprot(PTE_RDONLY));
>
>         return pte;
> }
>
> BTW arch_faults_on_old_pte() is no longer available mainline.
>
> - Anshuman
>
> >
> > Cc: Andrew Morton <akpm@linux-foundation.org>
> > Cc: Anshuman Khandual <anshuman.khandual@arm.com>
> > Cc: Catalin Marinas <catalin.marinas@arm.com>
> > Cc: David Hildenbrand <david@redhat.com>
> > Cc: Gerald Schaefer <gerald.schaefer@linux.ibm.com>
> > Cc: Liu Shixin <liushixin2@huawei.com>
> > Cc: Will Deacon <will@kernel.org>
> > Cc: Yu Zhao <yuzhao@google.com>
> > Signed-off-by: Nico Pache <npache@redhat.com>
> > ---
> >  arch/arm64/Kconfig               |  1 +
> >  arch/arm64/include/asm/pgtable.h | 77 +++++++++++++++++++++++++++++++-
> >  2 files changed, 76 insertions(+), 2 deletions(-)
> >
> > diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> > index 891ab530a665..4de491627f49 100644
> > --- a/arch/arm64/Kconfig
> > +++ b/arch/arm64/Kconfig
> > @@ -173,6 +173,7 @@ config ARM64
> >       select HAVE_ARCH_PREL32_RELOCATIONS
> >       select HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET
> >       select HAVE_ARCH_SECCOMP_FILTER
> > +     select HAVE_ARCH_SOFT_DIRTY
> >       select HAVE_ARCH_STACKLEAK
> >       select HAVE_ARCH_THREAD_STRUCT_WHITELIST
> >       select HAVE_ARCH_TRACEHOOK
> > diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
> > index 0bd18de9fd97..a0a15ffa2417 100644
> > --- a/arch/arm64/include/asm/pgtable.h
> > +++ b/arch/arm64/include/asm/pgtable.h
> > @@ -121,8 +121,9 @@ static inline pteval_t __phys_to_pte_val(phys_addr_t phys)
> >  })
> >
> >  #define pte_hw_dirty(pte)    (pte_write(pte) && !(pte_val(pte) & PTE_RDONLY))
> > -#define pte_sw_dirty(pte)    (!!(pte_val(pte) & PTE_DIRTY))
> > -#define pte_dirty(pte)               (pte_sw_dirty(pte) || pte_hw_dirty(pte))
> > +#define pte_soft_dirty(pte)  (!!(pte_val(pte) & PTE_DIRTY))
> > +#define pte_dirty(pte)               (pte_soft_dirty(pte) || pte_hw_dirty(pte))
> > +#define pte_swp_soft_dirty(pte)      pte_soft_dirty(pte)
> >
> >  #define pte_valid(pte)               (!!(pte_val(pte) & PTE_VALID))
> >  /*
> > @@ -1096,6 +1097,78 @@ static inline bool pud_sect_supported(void)
> >       return PAGE_SIZE == SZ_4K;
> >  }
> >
> > +#ifdef CONFIG_ARM64_HW_AFDBM
> > +/*
> > + * if we have the DBM bit we can utilize the software dirty bit as
> > + * a mechanism to introduce the soft_dirty functionality; however, without
> > + * it this bit is crucial to determining if a entry is dirty and we cannot
> > + * clear it via software. DBM can also be disabled or broken on some early
> > + * armv8 devices, so check its availability before modifying it.
> > + */
> > +static inline pte_t pte_clear_soft_dirty(pte_t pte)
> > +{
> > +     if (arch_faults_on_old_pte())
> > +             return pte;
> > +
> > +     return clear_pte_bit(pte, __pgprot(PTE_DIRTY));
> > +}
> > +
> > +static inline pte_t pte_mksoft_dirty(pte_t pte)
> > +{
> > +     if (arch_faults_on_old_pte())
> > +             return pte;
> > +
> > +     return set_pte_bit(pte, __pgprot(PTE_DIRTY));
> > +}
> > +
> > +static inline pte_t pte_swp_clear_soft_dirty(pte_t pte)
> > +{
> > +     if (arch_faults_on_old_pte())
> > +             return pte;
> > +
> > +     return clear_pte_bit(pte, __pgprot(PTE_DIRTY));
> > +}
> > +
> > +static inline pte_t pte_swp_mksoft_dirty(pte_t pte)
> > +{
> > +     if (arch_faults_on_old_pte())
> > +             return pte;
> > +
> > +     return set_pte_bit(pte, __pgprot(PTE_DIRTY));
> > +}
> > +
> > +static inline int pmd_soft_dirty(pmd_t pmd)
> > +{
> > +     return pte_soft_dirty(pmd_pte(pmd));
> > +}
> > +
> > +static inline pmd_t pmd_clear_soft_dirty(pmd_t pmd)
> > +{
> > +     return pte_pmd(pte_clear_soft_dirty(pmd_pte(pmd)));
> > +}
> > +
> > +static inline pmd_t pmd_mksoft_dirty(pmd_t pmd)
> > +{
> > +     return pte_pmd(pte_mksoft_dirty(pmd_pte(pmd)));
> > +}
> > +
> > +#ifdef CONFIG_ARCH_ENABLE_THP_MIGRATION
> > +static inline int pmd_swp_soft_dirty(pmd_t pmd)
> > +{
> > +     return pmd_soft_dirty(pmd);
> > +}
> > +
> > +static inline pmd_t pmd_swp_clear_soft_dirty(pmd_t pmd)
> > +{
> > +     return pmd_clear_soft_dirty(pmd);
> > +}
> > +
> > +static inline pmd_t pmd_swp_mksoft_dirty(pmd_t pmd)
> > +{
> > +     return pmd_mksoft_dirty(pmd);
> > +}
> > +#endif /* CONFIG_ARCH_ENABLE_THP_MIGRATION */
> > +#endif /* CONFIG_ARM64_HW_AFDBM */
> >
> >  #define __HAVE_ARCH_PTEP_MODIFY_PROT_TRANSACTION
> >  #define ptep_modify_prot_start ptep_modify_prot_start
>


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [RFC] arm64: properly define SOFT_DIRTY for arm64
@ 2023-07-04 10:08     ` Nico Pache
  0 siblings, 0 replies; 13+ messages in thread
From: Nico Pache @ 2023-07-04 10:08 UTC (permalink / raw)
  To: Anshuman Khandual
  Cc: linux-arm-kernel, linux-kernel, aquini, Andrew Morton,
	Catalin Marinas, David Hildenbrand, Gerald Schaefer, Liu Shixin,
	Will Deacon, Yu Zhao

Hi Anshuman,

Thanks for the explanation!

Is it possible to add the same DBM check I'm using
(!arch_has_hw_pte_young) in these pte helper functions to only clear
it when DBM is not present?

Cheers,
-- Nico

On Tue, Jul 4, 2023 at 6:01 AM Anshuman Khandual
<anshuman.khandual@arm.com> wrote:
>
> Hi Nico,
>
> On 7/3/23 19:25, Nico Pache wrote:
> > ARM64 has a soft-dirty bit (software dirty) but never properly defines
> > CONFIG_ARCH_HAS_SOFT_DIRTY or its necessary functions. This patch
> > introduces the ability to set/clear the soft dirty bit in a similar
> > manner as the other arches that utilize it.
> >
> > However, we must be careful... there are cases where the DBM bit is not
> > available and the software dirty bit plays a essential role in determining
> > whether or not a page is dirty. In these cases we must not allow the
> > user to clear the software dirty bit. We can test for these cases by
> > utilizing the arch_faults_on_old_pte() function which test the availability
> > of DBM.
>
> The current soft-dirty bit is a SW PTE bit i.e PTE_DIRTY, tracking PTE
> dirtiness in absence of HW DBM support, although both these tracking
> methods are very much intertwined. Current pte helpers like pte_dirty(),
> pte_mkdirty(), pte_mkclean(), and pte_wrrotect() etc operate both on
> HW and SW dirty tracking bits irrespective of whether DBM is supported
> or not.
>
> For soft dirty to work, we need a software PTE bit which sticks around
> on the PTE entry until user space (only) clears it and above PTE_DIRTY
> bit cannot be used for that purpose as it could be cleared in the kernel.
>
> static inline pte_t pte_mkclean(pte_t pte)
> {
>         pte = clear_pte_bit(pte, __pgprot(PTE_DIRTY));
>         pte = set_pte_bit(pte, __pgprot(PTE_RDONLY));
>
>         return pte;
> }
>
> BTW arch_faults_on_old_pte() is no longer available mainline.
>
> - Anshuman
>
> >
> > Cc: Andrew Morton <akpm@linux-foundation.org>
> > Cc: Anshuman Khandual <anshuman.khandual@arm.com>
> > Cc: Catalin Marinas <catalin.marinas@arm.com>
> > Cc: David Hildenbrand <david@redhat.com>
> > Cc: Gerald Schaefer <gerald.schaefer@linux.ibm.com>
> > Cc: Liu Shixin <liushixin2@huawei.com>
> > Cc: Will Deacon <will@kernel.org>
> > Cc: Yu Zhao <yuzhao@google.com>
> > Signed-off-by: Nico Pache <npache@redhat.com>
> > ---
> >  arch/arm64/Kconfig               |  1 +
> >  arch/arm64/include/asm/pgtable.h | 77 +++++++++++++++++++++++++++++++-
> >  2 files changed, 76 insertions(+), 2 deletions(-)
> >
> > diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> > index 891ab530a665..4de491627f49 100644
> > --- a/arch/arm64/Kconfig
> > +++ b/arch/arm64/Kconfig
> > @@ -173,6 +173,7 @@ config ARM64
> >       select HAVE_ARCH_PREL32_RELOCATIONS
> >       select HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET
> >       select HAVE_ARCH_SECCOMP_FILTER
> > +     select HAVE_ARCH_SOFT_DIRTY
> >       select HAVE_ARCH_STACKLEAK
> >       select HAVE_ARCH_THREAD_STRUCT_WHITELIST
> >       select HAVE_ARCH_TRACEHOOK
> > diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
> > index 0bd18de9fd97..a0a15ffa2417 100644
> > --- a/arch/arm64/include/asm/pgtable.h
> > +++ b/arch/arm64/include/asm/pgtable.h
> > @@ -121,8 +121,9 @@ static inline pteval_t __phys_to_pte_val(phys_addr_t phys)
> >  })
> >
> >  #define pte_hw_dirty(pte)    (pte_write(pte) && !(pte_val(pte) & PTE_RDONLY))
> > -#define pte_sw_dirty(pte)    (!!(pte_val(pte) & PTE_DIRTY))
> > -#define pte_dirty(pte)               (pte_sw_dirty(pte) || pte_hw_dirty(pte))
> > +#define pte_soft_dirty(pte)  (!!(pte_val(pte) & PTE_DIRTY))
> > +#define pte_dirty(pte)               (pte_soft_dirty(pte) || pte_hw_dirty(pte))
> > +#define pte_swp_soft_dirty(pte)      pte_soft_dirty(pte)
> >
> >  #define pte_valid(pte)               (!!(pte_val(pte) & PTE_VALID))
> >  /*
> > @@ -1096,6 +1097,78 @@ static inline bool pud_sect_supported(void)
> >       return PAGE_SIZE == SZ_4K;
> >  }
> >
> > +#ifdef CONFIG_ARM64_HW_AFDBM
> > +/*
> > + * if we have the DBM bit we can utilize the software dirty bit as
> > + * a mechanism to introduce the soft_dirty functionality; however, without
> > + * it this bit is crucial to determining if a entry is dirty and we cannot
> > + * clear it via software. DBM can also be disabled or broken on some early
> > + * armv8 devices, so check its availability before modifying it.
> > + */
> > +static inline pte_t pte_clear_soft_dirty(pte_t pte)
> > +{
> > +     if (arch_faults_on_old_pte())
> > +             return pte;
> > +
> > +     return clear_pte_bit(pte, __pgprot(PTE_DIRTY));
> > +}
> > +
> > +static inline pte_t pte_mksoft_dirty(pte_t pte)
> > +{
> > +     if (arch_faults_on_old_pte())
> > +             return pte;
> > +
> > +     return set_pte_bit(pte, __pgprot(PTE_DIRTY));
> > +}
> > +
> > +static inline pte_t pte_swp_clear_soft_dirty(pte_t pte)
> > +{
> > +     if (arch_faults_on_old_pte())
> > +             return pte;
> > +
> > +     return clear_pte_bit(pte, __pgprot(PTE_DIRTY));
> > +}
> > +
> > +static inline pte_t pte_swp_mksoft_dirty(pte_t pte)
> > +{
> > +     if (arch_faults_on_old_pte())
> > +             return pte;
> > +
> > +     return set_pte_bit(pte, __pgprot(PTE_DIRTY));
> > +}
> > +
> > +static inline int pmd_soft_dirty(pmd_t pmd)
> > +{
> > +     return pte_soft_dirty(pmd_pte(pmd));
> > +}
> > +
> > +static inline pmd_t pmd_clear_soft_dirty(pmd_t pmd)
> > +{
> > +     return pte_pmd(pte_clear_soft_dirty(pmd_pte(pmd)));
> > +}
> > +
> > +static inline pmd_t pmd_mksoft_dirty(pmd_t pmd)
> > +{
> > +     return pte_pmd(pte_mksoft_dirty(pmd_pte(pmd)));
> > +}
> > +
> > +#ifdef CONFIG_ARCH_ENABLE_THP_MIGRATION
> > +static inline int pmd_swp_soft_dirty(pmd_t pmd)
> > +{
> > +     return pmd_soft_dirty(pmd);
> > +}
> > +
> > +static inline pmd_t pmd_swp_clear_soft_dirty(pmd_t pmd)
> > +{
> > +     return pmd_clear_soft_dirty(pmd);
> > +}
> > +
> > +static inline pmd_t pmd_swp_mksoft_dirty(pmd_t pmd)
> > +{
> > +     return pmd_mksoft_dirty(pmd);
> > +}
> > +#endif /* CONFIG_ARCH_ENABLE_THP_MIGRATION */
> > +#endif /* CONFIG_ARM64_HW_AFDBM */
> >
> >  #define __HAVE_ARCH_PTEP_MODIFY_PROT_TRANSACTION
> >  #define ptep_modify_prot_start ptep_modify_prot_start
>


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

* Re: [RFC] arm64: properly define SOFT_DIRTY for arm64
  2023-07-04 10:08     ` Nico Pache
@ 2023-07-16 15:10       ` Catalin Marinas
  -1 siblings, 0 replies; 13+ messages in thread
From: Catalin Marinas @ 2023-07-16 15:10 UTC (permalink / raw)
  To: Nico Pache
  Cc: Anshuman Khandual, linux-arm-kernel, linux-kernel, aquini,
	Andrew Morton, David Hildenbrand, Gerald Schaefer, Liu Shixin,
	Will Deacon, Yu Zhao

(I noticed Mark already replied in another thread along the same lines)

On Tue, Jul 04, 2023 at 06:08:59AM -0400, Nico Pache wrote:
> Is it possible to add the same DBM check I'm using
> (!arch_has_hw_pte_young) in these pte helper functions to only clear
> it when DBM is not present?

It's not possible since we don't have a way to encode a read-only +
dirty PTE (e.g. after ptep_set_wrprotect()). The PTE_WRITE/PTE_DBM bit
in the architecture only tells that the hardware is allowed to clear the
PTE_RDONLY bit on a write access and that's what we consider hw-dirty.
When a dirty/writeable PTE is made read-only, we clear PTE_WRITE, set
PTE_RDONLY _and_ the software PTE_DIRTY bit.

With the permission indirection extensions (PIE, see patches from Joey),
PTE_RDONLY can be treated as a true !PTE_DIRTY bit but there's no
hardware around yet.

So if you need software dirty, it can only be done with another software
PTE bit. The problem is that we are short of such bits (only one left if
we move PTE_PROT_NONE to a different location). The userfaultfd people
also want such bit.

Personally I'd reuse the four PBHA bits but I keep hearing that they may
be used with some out of tree patches.

-- 
Catalin

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [RFC] arm64: properly define SOFT_DIRTY for arm64
@ 2023-07-16 15:10       ` Catalin Marinas
  0 siblings, 0 replies; 13+ messages in thread
From: Catalin Marinas @ 2023-07-16 15:10 UTC (permalink / raw)
  To: Nico Pache
  Cc: Anshuman Khandual, linux-arm-kernel, linux-kernel, aquini,
	Andrew Morton, David Hildenbrand, Gerald Schaefer, Liu Shixin,
	Will Deacon, Yu Zhao

(I noticed Mark already replied in another thread along the same lines)

On Tue, Jul 04, 2023 at 06:08:59AM -0400, Nico Pache wrote:
> Is it possible to add the same DBM check I'm using
> (!arch_has_hw_pte_young) in these pte helper functions to only clear
> it when DBM is not present?

It's not possible since we don't have a way to encode a read-only +
dirty PTE (e.g. after ptep_set_wrprotect()). The PTE_WRITE/PTE_DBM bit
in the architecture only tells that the hardware is allowed to clear the
PTE_RDONLY bit on a write access and that's what we consider hw-dirty.
When a dirty/writeable PTE is made read-only, we clear PTE_WRITE, set
PTE_RDONLY _and_ the software PTE_DIRTY bit.

With the permission indirection extensions (PIE, see patches from Joey),
PTE_RDONLY can be treated as a true !PTE_DIRTY bit but there's no
hardware around yet.

So if you need software dirty, it can only be done with another software
PTE bit. The problem is that we are short of such bits (only one left if
we move PTE_PROT_NONE to a different location). The userfaultfd people
also want such bit.

Personally I'd reuse the four PBHA bits but I keep hearing that they may
be used with some out of tree patches.

-- 
Catalin

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

* Re: [RFC] arm64: properly define SOFT_DIRTY for arm64
  2023-07-16 15:10       ` Catalin Marinas
  (?)
@ 2023-07-25 21:16       ` Nico Pache
  -1 siblings, 0 replies; 13+ messages in thread
From: Nico Pache @ 2023-07-25 21:16 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: Anshuman Khandual, linux-arm-kernel, linux-kernel, aquini,
	Andrew Morton, David Hildenbrand, Gerald Schaefer, Liu Shixin,
	Will Deacon, Yu Zhao

Hi Catalin,

Thanks for your reply.

From my understanding only two of the PBHA bits [60:59] are being used
for *_TABLE_<UXN|PXN>.

If that's the case is it safe to assume bits [63:61] are usable
(without considering OOT patches) and are treated similarly to the
software bits [58:55]? or do more considerations need to be made with
regards to using these bits?

There isnt much info in the codebase about PBHA, but from some
external research it seems the PBHA bits are intended to be used by
future SoC hardware but are currently not exposed to allow users to
use them for their intended purpose.

If you think this is a viable solution, I will go ahead and use bit 61
to implement a SOFTWARE_DIRTY bit. But if the goal is to inevitably
expose these bits to the hardware and allow them to use it, then
perhaps introducing this feature would be short lived.

Thanks,
-- Nico

On Sun, Jul 16, 2023 at 9:19 AM Catalin Marinas <catalin.marinas@arm.com> wrote:
>
> (I noticed Mark already replied in another thread along the same lines)
>
> On Tue, Jul 04, 2023 at 06:08:59AM -0400, Nico Pache wrote:
> > Is it possible to add the same DBM check I'm using
> > (!arch_has_hw_pte_young) in these pte helper functions to only clear
> > it when DBM is not present?
>
> It's not possible since we don't have a way to encode a read-only +
> dirty PTE (e.g. after ptep_set_wrprotect()). The PTE_WRITE/PTE_DBM bit
> in the architecture only tells that the hardware is allowed to clear the
> PTE_RDONLY bit on a write access and that's what we consider hw-dirty.
> When a dirty/writeable PTE is made read-only, we clear PTE_WRITE, set
> PTE_RDONLY _and_ the software PTE_DIRTY bit.
>
> With the permission indirection extensions (PIE, see patches from Joey),
> PTE_RDONLY can be treated as a true !PTE_DIRTY bit but there's no
> hardware around yet.
>
> So if you need software dirty, it can only be done with another software
> PTE bit. The problem is that we are short of such bits (only one left if
> we move PTE_PROT_NONE to a different location). The userfaultfd people
> also want such bit.
>
> Personally I'd reuse the four PBHA bits but I keep hearing that they may
> be used with some out of tree patches.
>
> --
> Catalin
>


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

end of thread, other threads:[~2023-07-25 21:17 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-07-03 13:55 [RFC] arm64: properly define SOFT_DIRTY for arm64 Nico Pache
2023-07-03 13:55 ` Nico Pache
2023-07-04  2:00 ` kernel test robot
2023-07-04  2:31 ` kernel test robot
2023-07-04  9:58 ` Nico Pache
2023-07-04  9:58   ` Nico Pache
2023-07-04 10:01 ` Anshuman Khandual
2023-07-04 10:01   ` Anshuman Khandual
2023-07-04 10:08   ` Nico Pache
2023-07-04 10:08     ` Nico Pache
2023-07-16 15:10     ` Catalin Marinas
2023-07-16 15:10       ` Catalin Marinas
2023-07-25 21:16       ` Nico Pache

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.