* [PATCH 0/3] PTE formats changes
@ 2014-09-05 1:03 Leonid Yegoshin
2014-09-05 1:03 ` Leonid Yegoshin
` (4 more replies)
0 siblings, 5 replies; 9+ messages in thread
From: Leonid Yegoshin @ 2014-09-05 1:03 UTC (permalink / raw)
To: linux-mips, hauke, yanh, zajec5, ralf, alex.smith, taohl, chenhc
The following series implements bugfix of PTE formats for swap and file entries
and changes PTE bit position to fixed, which is more better for analysing of
tracer and HW debugger logs.
Hardcoded bits positions and offsets in PTE effectively causes a miss of
relationship between PTE format for TLB and PTE formats for swap and file
entries. This patch series introduces a symbolic relation between both and
also fixes a current mismatch of formats. It can crash kernel or application
in heavy paging environment.
Fixed bit positions helps much in analysing of tracer and HW debugger logs and
improves performance and code size a little due to absence of variable masks
in kernel.
---
Leonid Yegoshin (3):
MIPS: rearrange PTE bits into fixed positions
MIPS: PTE bit positions slightly changed to prepare a more simple swap/file presentation
MIPS: bugfix of PTE formats for swap and file entries
arch/mips/include/asm/pgtable-32.h | 107 ++++++++-----------
arch/mips/include/asm/pgtable-64.h | 25 +++-
arch/mips/include/asm/pgtable-bits.h | 189 ++++++++++++++++++++++++++++++----
3 files changed, 232 insertions(+), 89 deletions(-)
--
Signature
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 0/3] PTE formats changes
2014-09-05 1:03 [PATCH 0/3] PTE formats changes Leonid Yegoshin
@ 2014-09-05 1:03 ` Leonid Yegoshin
2014-09-05 1:03 ` [PATCH 1/3] MIPS: rearrange PTE bits into fixed positions Leonid Yegoshin
` (3 subsequent siblings)
4 siblings, 0 replies; 9+ messages in thread
From: Leonid Yegoshin @ 2014-09-05 1:03 UTC (permalink / raw)
To: linux-mips, hauke, yanh, zajec5, ralf, alex.smith, taohl, chenhc
The following series implements bugfix of PTE formats for swap and file entries
and changes PTE bit position to fixed, which is more better for analysing of
tracer and HW debugger logs.
Hardcoded bits positions and offsets in PTE effectively causes a miss of
relationship between PTE format for TLB and PTE formats for swap and file
entries. This patch series introduces a symbolic relation between both and
also fixes a current mismatch of formats. It can crash kernel or application
in heavy paging environment.
Fixed bit positions helps much in analysing of tracer and HW debugger logs and
improves performance and code size a little due to absence of variable masks
in kernel.
---
Leonid Yegoshin (3):
MIPS: rearrange PTE bits into fixed positions
MIPS: PTE bit positions slightly changed to prepare a more simple swap/file presentation
MIPS: bugfix of PTE formats for swap and file entries
arch/mips/include/asm/pgtable-32.h | 107 ++++++++-----------
arch/mips/include/asm/pgtable-64.h | 25 +++-
arch/mips/include/asm/pgtable-bits.h | 189 ++++++++++++++++++++++++++++++----
3 files changed, 232 insertions(+), 89 deletions(-)
--
Signature
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 1/3] MIPS: rearrange PTE bits into fixed positions
2014-09-05 1:03 [PATCH 0/3] PTE formats changes Leonid Yegoshin
2014-09-05 1:03 ` Leonid Yegoshin
@ 2014-09-05 1:03 ` Leonid Yegoshin
2014-09-05 1:03 ` Leonid Yegoshin
2014-09-05 1:03 ` [PATCH 2/3] MIPS: PTE bit positions slightly changed to prepare a more simple swap/file presentation Leonid Yegoshin
` (2 subsequent siblings)
4 siblings, 1 reply; 9+ messages in thread
From: Leonid Yegoshin @ 2014-09-05 1:03 UTC (permalink / raw)
To: linux-mips, hauke, yanh, zajec5, ralf, alex.smith, taohl, chenhc
Previously, code did a runtime check of RIXI and made runtime
shifts/etc to fit into PTE as much as possible PFN bits.
However, because there is no HUGE page support for MIPS32 R2
there is a way to fit all required bits in fixed positions:
PTE low bits are: CCC D V G RI(=R) XI M A W P
TLB refill will do a ROTR 6 (in case of cpu_has_rixi),
or SRL 6 to strip low bits.
All 20 bits PFN are preserved in high bits (4GB with 4KB pages)
Also rearrange PTE bits for MIPS64 R2 in fixed positions:
PTE low bits are: CCC D V G RI XI [S H] M A W R P
TLB refill will do a ROTR 7/9 (in case of cpu_has_rixi),
or SRL/DSRL 7/9 to strip low bits in absense of RIXI.
PFN size in high bits is 49 or 51 bits --> 512TB or 4*512TB for 4KB pages
Signed-off-by: Leonid Yegoshin <Leonid.Yegoshin@imgtec.com>
---
arch/mips/include/asm/pgtable-bits.h | 102 ++++++++++++++++++++++++++++++++++
1 files changed, 102 insertions(+), 0 deletions(-)
diff --git a/arch/mips/include/asm/pgtable-bits.h b/arch/mips/include/asm/pgtable-bits.h
index e592f36..4183771 100644
--- a/arch/mips/include/asm/pgtable-bits.h
+++ b/arch/mips/include/asm/pgtable-bits.h
@@ -102,6 +102,8 @@
#define _CACHE_MASK (1 << _CACHE_UNCACHED_SHIFT)
#else /* 'Normal' r4K case */
+
+#ifndef CONFIG_CPU_MIPSR2
/*
* When using the RI/XI bit support, we have 13 bits of flags below
* the physical address. The RI/XI bits are placed such that a SRL 5
@@ -154,6 +156,106 @@
#define _PAGE_NO_READ_SHIFT (cpu_has_rixi ? _PAGE_NO_EXEC_SHIFT + 1 : _PAGE_NO_EXEC_SHIFT)
#define _PAGE_NO_READ ({BUG_ON(!cpu_has_rixi); 1 << _PAGE_NO_READ_SHIFT; })
+#else /* CONFIG_CPU_MIPSR2 */
+
+/* static bits allocation in MIPS R2, two variants -
+ HUGE TLB in 64BIT kernel support or not.
+ RIXI support in both */
+
+#ifdef CONFIG_64BIT
+
+/*
+ * Low bits are: CCC D V G RI XI [S H] M A W R P
+ * TLB refill will do a ROTR 7/9 (in case of cpu_has_rixi),
+ * or SRL/DSRL 7/9 to strip low bits.
+ * PFN size in high bits is 49 or 51 bit --> 512TB or 4*512TB for 4KB pages
+ */
+
+#define _PAGE_PRESENT_SHIFT (0)
+#define _PAGE_PRESENT (1 << _PAGE_PRESENT_SHIFT)
+/* implemented in software, should be unused if cpu_has_rixi. */
+#define _PAGE_READ_SHIFT (_PAGE_PRESENT_SHIFT + 1)
+#define _PAGE_READ (1 << _PAGE_READ_SHIFT)
+/* implemented in software */
+#define _PAGE_WRITE_SHIFT (_PAGE_READ_SHIFT + 1)
+#define _PAGE_WRITE (1 << _PAGE_WRITE_SHIFT)
+/* implemented in software */
+#define _PAGE_ACCESSED_SHIFT (_PAGE_WRITE_SHIFT + 1)
+#define _PAGE_ACCESSED (1 << _PAGE_ACCESSED_SHIFT)
+/* implemented in software */
+#define _PAGE_MODIFIED_SHIFT (_PAGE_ACCESSED_SHIFT + 1)
+#define _PAGE_MODIFIED (1 << _PAGE_MODIFIED_SHIFT)
+/* set:pagecache unset:swap */
+#define _PAGE_FILE (_PAGE_MODIFIED)
+
+#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
+/* huge tlb page */
+#define _PAGE_HUGE_SHIFT (_PAGE_MODIFIED_SHIFT + 1)
+#define _PAGE_HUGE (1 << _PAGE_HUGE_SHIFT)
+#define _PAGE_SPLITTING_SHIFT (_PAGE_HUGE_SHIFT + 1)
+#define _PAGE_SPLITTING (1 << _PAGE_SPLITTING_SHIFT)
+#else
+#define _PAGE_HUGE_SHIFT (_PAGE_MODIFIED_SHIFT)
+#define _PAGE_HUGE ({BUG(); 1; }) /* Dummy value */
+#define _PAGE_SPLITTING_SHIFT (_PAGE_HUGE_SHIFT)
+#define _PAGE_SPLITTING ({BUG(); 1; }) /* Dummy value */
+#endif /* CONFIG_MIPS_HUGE_TLB_SUPPORT */
+
+/* Page cannot be executed */
+#define _PAGE_NO_EXEC_SHIFT (_PAGE_SPLITTING_SHIFT + 1)
+#define _PAGE_NO_EXEC (1 << _PAGE_NO_EXEC_SHIFT)
+
+/* Page cannot be read */
+#define _PAGE_NO_READ_SHIFT (_PAGE_NO_EXEC_SHIFT + 1)
+#define _PAGE_NO_READ (1 << _PAGE_NO_READ_SHIFT)
+
+#else /* !CONFIG_64BIT */
+
+/*
+ * No HUGE page support
+ * Low bits are: CCC D V G RI(=R) XI M A W P
+ * TLB refill will do a ROTR 6 (in case of cpu_has_rixi),
+ * or SRL 6 to strip low bits.
+ * All 20 bits PFN are preserved in high bits (4GB in 4KB pages)
+ */
+
+#define _PAGE_PRESENT_SHIFT (0)
+#define _PAGE_PRESENT (1 << _PAGE_PRESENT_SHIFT)
+/* implemented in software */
+#define _PAGE_WRITE_SHIFT (_PAGE_PRESENT_SHIFT + 1)
+#define _PAGE_WRITE (1 << _PAGE_WRITE_SHIFT)
+/* implemented in software */
+#define _PAGE_ACCESSED_SHIFT (_PAGE_WRITE_SHIFT + 1)
+#define _PAGE_ACCESSED (1 << _PAGE_ACCESSED_SHIFT)
+/* implemented in software */
+#define _PAGE_MODIFIED_SHIFT (_PAGE_ACCESSED_SHIFT + 1)
+#define _PAGE_MODIFIED (1 << _PAGE_MODIFIED_SHIFT)
+/* set:pagecache unset:swap */
+#define _PAGE_FILE (_PAGE_MODIFIED)
+
+/* huge tlb page dummies */
+#define _PAGE_HUGE_SHIFT (_PAGE_MODIFIED_SHIFT)
+#define _PAGE_HUGE ({BUG(); 1; }) /* Dummy value */
+#define _PAGE_SPLITTING_SHIFT (_PAGE_HUGE_SHIFT)
+#define _PAGE_SPLITTING ({BUG(); 1; }) /* Dummy value */
+
+/* Page cannot be executed */
+#define _PAGE_NO_EXEC_SHIFT (_PAGE_SPLITTING_SHIFT + 1)
+#define _PAGE_NO_EXEC (1 << _PAGE_NO_EXEC_SHIFT)
+
+/* Page cannot be read */
+#define _PAGE_NO_READ_SHIFT (_PAGE_NO_EXEC_SHIFT + 1)
+#define _PAGE_NO_READ (1 << _PAGE_NO_READ_SHIFT)
+
+/* implemented in software, should be unused if cpu_has_rixi. */
+#define _PAGE_READ_SHIFT (_PAGE_NO_READ_SHIFT)
+#define _PAGE_READ (1 << _PAGE_READ_SHIFT)
+
+#endif /* CONFIG_64BIT */
+
+#endif /* !CONFIG_CPU_MIPSR2 */
+
+
#define _PAGE_GLOBAL_SHIFT (_PAGE_NO_READ_SHIFT + 1)
#define _PAGE_GLOBAL (1 << _PAGE_GLOBAL_SHIFT)
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 1/3] MIPS: rearrange PTE bits into fixed positions
2014-09-05 1:03 ` [PATCH 1/3] MIPS: rearrange PTE bits into fixed positions Leonid Yegoshin
@ 2014-09-05 1:03 ` Leonid Yegoshin
0 siblings, 0 replies; 9+ messages in thread
From: Leonid Yegoshin @ 2014-09-05 1:03 UTC (permalink / raw)
To: linux-mips, hauke, yanh, zajec5, ralf, alex.smith, taohl, chenhc
Previously, code did a runtime check of RIXI and made runtime
shifts/etc to fit into PTE as much as possible PFN bits.
However, because there is no HUGE page support for MIPS32 R2
there is a way to fit all required bits in fixed positions:
PTE low bits are: CCC D V G RI(=R) XI M A W P
TLB refill will do a ROTR 6 (in case of cpu_has_rixi),
or SRL 6 to strip low bits.
All 20 bits PFN are preserved in high bits (4GB with 4KB pages)
Also rearrange PTE bits for MIPS64 R2 in fixed positions:
PTE low bits are: CCC D V G RI XI [S H] M A W R P
TLB refill will do a ROTR 7/9 (in case of cpu_has_rixi),
or SRL/DSRL 7/9 to strip low bits in absense of RIXI.
PFN size in high bits is 49 or 51 bits --> 512TB or 4*512TB for 4KB pages
Signed-off-by: Leonid Yegoshin <Leonid.Yegoshin@imgtec.com>
---
arch/mips/include/asm/pgtable-bits.h | 102 ++++++++++++++++++++++++++++++++++
1 files changed, 102 insertions(+), 0 deletions(-)
diff --git a/arch/mips/include/asm/pgtable-bits.h b/arch/mips/include/asm/pgtable-bits.h
index e592f36..4183771 100644
--- a/arch/mips/include/asm/pgtable-bits.h
+++ b/arch/mips/include/asm/pgtable-bits.h
@@ -102,6 +102,8 @@
#define _CACHE_MASK (1 << _CACHE_UNCACHED_SHIFT)
#else /* 'Normal' r4K case */
+
+#ifndef CONFIG_CPU_MIPSR2
/*
* When using the RI/XI bit support, we have 13 bits of flags below
* the physical address. The RI/XI bits are placed such that a SRL 5
@@ -154,6 +156,106 @@
#define _PAGE_NO_READ_SHIFT (cpu_has_rixi ? _PAGE_NO_EXEC_SHIFT + 1 : _PAGE_NO_EXEC_SHIFT)
#define _PAGE_NO_READ ({BUG_ON(!cpu_has_rixi); 1 << _PAGE_NO_READ_SHIFT; })
+#else /* CONFIG_CPU_MIPSR2 */
+
+/* static bits allocation in MIPS R2, two variants -
+ HUGE TLB in 64BIT kernel support or not.
+ RIXI support in both */
+
+#ifdef CONFIG_64BIT
+
+/*
+ * Low bits are: CCC D V G RI XI [S H] M A W R P
+ * TLB refill will do a ROTR 7/9 (in case of cpu_has_rixi),
+ * or SRL/DSRL 7/9 to strip low bits.
+ * PFN size in high bits is 49 or 51 bit --> 512TB or 4*512TB for 4KB pages
+ */
+
+#define _PAGE_PRESENT_SHIFT (0)
+#define _PAGE_PRESENT (1 << _PAGE_PRESENT_SHIFT)
+/* implemented in software, should be unused if cpu_has_rixi. */
+#define _PAGE_READ_SHIFT (_PAGE_PRESENT_SHIFT + 1)
+#define _PAGE_READ (1 << _PAGE_READ_SHIFT)
+/* implemented in software */
+#define _PAGE_WRITE_SHIFT (_PAGE_READ_SHIFT + 1)
+#define _PAGE_WRITE (1 << _PAGE_WRITE_SHIFT)
+/* implemented in software */
+#define _PAGE_ACCESSED_SHIFT (_PAGE_WRITE_SHIFT + 1)
+#define _PAGE_ACCESSED (1 << _PAGE_ACCESSED_SHIFT)
+/* implemented in software */
+#define _PAGE_MODIFIED_SHIFT (_PAGE_ACCESSED_SHIFT + 1)
+#define _PAGE_MODIFIED (1 << _PAGE_MODIFIED_SHIFT)
+/* set:pagecache unset:swap */
+#define _PAGE_FILE (_PAGE_MODIFIED)
+
+#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
+/* huge tlb page */
+#define _PAGE_HUGE_SHIFT (_PAGE_MODIFIED_SHIFT + 1)
+#define _PAGE_HUGE (1 << _PAGE_HUGE_SHIFT)
+#define _PAGE_SPLITTING_SHIFT (_PAGE_HUGE_SHIFT + 1)
+#define _PAGE_SPLITTING (1 << _PAGE_SPLITTING_SHIFT)
+#else
+#define _PAGE_HUGE_SHIFT (_PAGE_MODIFIED_SHIFT)
+#define _PAGE_HUGE ({BUG(); 1; }) /* Dummy value */
+#define _PAGE_SPLITTING_SHIFT (_PAGE_HUGE_SHIFT)
+#define _PAGE_SPLITTING ({BUG(); 1; }) /* Dummy value */
+#endif /* CONFIG_MIPS_HUGE_TLB_SUPPORT */
+
+/* Page cannot be executed */
+#define _PAGE_NO_EXEC_SHIFT (_PAGE_SPLITTING_SHIFT + 1)
+#define _PAGE_NO_EXEC (1 << _PAGE_NO_EXEC_SHIFT)
+
+/* Page cannot be read */
+#define _PAGE_NO_READ_SHIFT (_PAGE_NO_EXEC_SHIFT + 1)
+#define _PAGE_NO_READ (1 << _PAGE_NO_READ_SHIFT)
+
+#else /* !CONFIG_64BIT */
+
+/*
+ * No HUGE page support
+ * Low bits are: CCC D V G RI(=R) XI M A W P
+ * TLB refill will do a ROTR 6 (in case of cpu_has_rixi),
+ * or SRL 6 to strip low bits.
+ * All 20 bits PFN are preserved in high bits (4GB in 4KB pages)
+ */
+
+#define _PAGE_PRESENT_SHIFT (0)
+#define _PAGE_PRESENT (1 << _PAGE_PRESENT_SHIFT)
+/* implemented in software */
+#define _PAGE_WRITE_SHIFT (_PAGE_PRESENT_SHIFT + 1)
+#define _PAGE_WRITE (1 << _PAGE_WRITE_SHIFT)
+/* implemented in software */
+#define _PAGE_ACCESSED_SHIFT (_PAGE_WRITE_SHIFT + 1)
+#define _PAGE_ACCESSED (1 << _PAGE_ACCESSED_SHIFT)
+/* implemented in software */
+#define _PAGE_MODIFIED_SHIFT (_PAGE_ACCESSED_SHIFT + 1)
+#define _PAGE_MODIFIED (1 << _PAGE_MODIFIED_SHIFT)
+/* set:pagecache unset:swap */
+#define _PAGE_FILE (_PAGE_MODIFIED)
+
+/* huge tlb page dummies */
+#define _PAGE_HUGE_SHIFT (_PAGE_MODIFIED_SHIFT)
+#define _PAGE_HUGE ({BUG(); 1; }) /* Dummy value */
+#define _PAGE_SPLITTING_SHIFT (_PAGE_HUGE_SHIFT)
+#define _PAGE_SPLITTING ({BUG(); 1; }) /* Dummy value */
+
+/* Page cannot be executed */
+#define _PAGE_NO_EXEC_SHIFT (_PAGE_SPLITTING_SHIFT + 1)
+#define _PAGE_NO_EXEC (1 << _PAGE_NO_EXEC_SHIFT)
+
+/* Page cannot be read */
+#define _PAGE_NO_READ_SHIFT (_PAGE_NO_EXEC_SHIFT + 1)
+#define _PAGE_NO_READ (1 << _PAGE_NO_READ_SHIFT)
+
+/* implemented in software, should be unused if cpu_has_rixi. */
+#define _PAGE_READ_SHIFT (_PAGE_NO_READ_SHIFT)
+#define _PAGE_READ (1 << _PAGE_READ_SHIFT)
+
+#endif /* CONFIG_64BIT */
+
+#endif /* !CONFIG_CPU_MIPSR2 */
+
+
#define _PAGE_GLOBAL_SHIFT (_PAGE_NO_READ_SHIFT + 1)
#define _PAGE_GLOBAL (1 << _PAGE_GLOBAL_SHIFT)
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 2/3] MIPS: PTE bit positions slightly changed to prepare a more simple swap/file presentation
2014-09-05 1:03 [PATCH 0/3] PTE formats changes Leonid Yegoshin
2014-09-05 1:03 ` Leonid Yegoshin
2014-09-05 1:03 ` [PATCH 1/3] MIPS: rearrange PTE bits into fixed positions Leonid Yegoshin
@ 2014-09-05 1:03 ` Leonid Yegoshin
2014-09-05 1:03 ` Leonid Yegoshin
2014-09-05 1:04 ` [PATCH 3/3] MIPS: bugfix of PTE formats for swap and file entries Leonid Yegoshin
2014-09-05 7:20 ` [PATCH 0/3] PTE formats changes Rafał Miłecki
4 siblings, 1 reply; 9+ messages in thread
From: Leonid Yegoshin @ 2014-09-05 1:03 UTC (permalink / raw)
To: linux-mips, hauke, yanh, zajec5, ralf, alex.smith, taohl, chenhc
Bit _PAGE_MODIFIED (= _PAGE_FILE) in PTE is moved close to _PAGE_PRESENT.
It allows a more compact bit grouping of V,G and F,P - PTE File entry uses
all available bits besides V/G/F and P to keep page offset in file.
This grouping is needed for subsequent bugfix patch of invalid overlapping
_PAGE_FILE, _PAGE_VALID etc bits with other bits used for file offset.
Signed-off-by: Leonid Yegoshin <Leonid.Yegoshin@imgtec.com>
---
arch/mips/include/asm/pgtable-bits.h | 74 +++++++++++++++++-----------------
1 files changed, 37 insertions(+), 37 deletions(-)
diff --git a/arch/mips/include/asm/pgtable-bits.h b/arch/mips/include/asm/pgtable-bits.h
index 4183771..d47be80 100644
--- a/arch/mips/include/asm/pgtable-bits.h
+++ b/arch/mips/include/asm/pgtable-bits.h
@@ -55,16 +55,15 @@
*/
#define _PAGE_PRESENT_SHIFT 6
#define _PAGE_PRESENT (1 << _PAGE_PRESENT_SHIFT)
-#define _PAGE_READ_SHIFT 7
+#define _PAGE_MODIFIED_SHIFT 7
+#define _PAGE_MODIFIED (1 << _PAGE_MODIFIED_SHIFT)
+#define _PAGE_FILE (1 << _PAGE_MODIFIED_SHIFT)
+#define _PAGE_READ_SHIFT 8
#define _PAGE_READ (1 << _PAGE_READ_SHIFT)
-#define _PAGE_WRITE_SHIFT 8
+#define _PAGE_WRITE_SHIFT 9
#define _PAGE_WRITE (1 << _PAGE_WRITE_SHIFT)
-#define _PAGE_ACCESSED_SHIFT 9
+#define _PAGE_ACCESSED_SHIFT 10
#define _PAGE_ACCESSED (1 << _PAGE_ACCESSED_SHIFT)
-#define _PAGE_MODIFIED_SHIFT 10
-#define _PAGE_MODIFIED (1 << _PAGE_MODIFIED_SHIFT)
-
-#define _PAGE_FILE (1 << 10)
#elif defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
@@ -75,16 +74,16 @@
*/
#define _PAGE_PRESENT_SHIFT 0
#define _PAGE_PRESENT (1 << _PAGE_PRESENT_SHIFT)
-#define _PAGE_READ_SHIFT 1
+#define _PAGE_MODIFIED_SHIFT 1
+#define _PAGE_MODIFIED (1 << _PAGE_MODIFIED_SHIFT)
+#define _PAGE_FILE_SHIFT 1
+#define _PAGE_FILE (1 << _PAGE_FILE_SHIFT)
+#define _PAGE_READ_SHIFT 2
#define _PAGE_READ (1 << _PAGE_READ_SHIFT)
-#define _PAGE_WRITE_SHIFT 2
+#define _PAGE_WRITE_SHIFT 3
#define _PAGE_WRITE (1 << _PAGE_WRITE_SHIFT)
-#define _PAGE_ACCESSED_SHIFT 3
+#define _PAGE_ACCESSED_SHIFT 4
#define _PAGE_ACCESSED (1 << _PAGE_ACCESSED_SHIFT)
-#define _PAGE_MODIFIED_SHIFT 4
-#define _PAGE_MODIFIED (1 << _PAGE_MODIFIED_SHIFT)
-#define _PAGE_FILE_SHIFT 4
-#define _PAGE_FILE (1 << _PAGE_FILE_SHIFT)
/*
* And these are the hardware TLB bits
@@ -120,22 +119,23 @@
*/
#define _PAGE_PRESENT_SHIFT (0)
#define _PAGE_PRESENT (1 << _PAGE_PRESENT_SHIFT)
-#define _PAGE_READ_SHIFT (cpu_has_rixi ? _PAGE_PRESENT_SHIFT : _PAGE_PRESENT_SHIFT + 1)
+#define _PAGE_MODIFIED_SHIFT (_PAGE_PRESENT_SHIFT + 1)
+#define _PAGE_MODIFIED (1 << _PAGE_MODIFIED_SHIFT)
+#define _PAGE_FILE (_PAGE_MODIFIED)
+#define _PAGE_READ_SHIFT \
+ (cpu_has_rixi ? _PAGE_MODIFIED_SHIFT : _PAGE_MODIFIED_SHIFT + 1)
#define _PAGE_READ ({BUG_ON(cpu_has_rixi); 1 << _PAGE_READ_SHIFT; })
#define _PAGE_WRITE_SHIFT (_PAGE_READ_SHIFT + 1)
#define _PAGE_WRITE (1 << _PAGE_WRITE_SHIFT)
#define _PAGE_ACCESSED_SHIFT (_PAGE_WRITE_SHIFT + 1)
#define _PAGE_ACCESSED (1 << _PAGE_ACCESSED_SHIFT)
-#define _PAGE_MODIFIED_SHIFT (_PAGE_ACCESSED_SHIFT + 1)
-#define _PAGE_MODIFIED (1 << _PAGE_MODIFIED_SHIFT)
-#define _PAGE_FILE (_PAGE_MODIFIED)
#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
/* huge tlb page */
-#define _PAGE_HUGE_SHIFT (_PAGE_MODIFIED_SHIFT + 1)
+#define _PAGE_HUGE_SHIFT (_PAGE_ACCESSED_SHIFT + 1)
#define _PAGE_HUGE (1 << _PAGE_HUGE_SHIFT)
#else
-#define _PAGE_HUGE_SHIFT (_PAGE_MODIFIED_SHIFT)
+#define _PAGE_HUGE_SHIFT (_PAGE_ACCESSED_SHIFT)
#define _PAGE_HUGE ({BUG(); 1; }) /* Dummy value */
#endif
@@ -165,7 +165,7 @@
#ifdef CONFIG_64BIT
/*
- * Low bits are: CCC D V G RI XI [S H] M A W R P
+ * Low bits are: CCC D V G RI XI [S H] A W R M(=F) P
* TLB refill will do a ROTR 7/9 (in case of cpu_has_rixi),
* or SRL/DSRL 7/9 to strip low bits.
* PFN size in high bits is 49 or 51 bit --> 512TB or 4*512TB for 4KB pages
@@ -173,6 +173,11 @@
#define _PAGE_PRESENT_SHIFT (0)
#define _PAGE_PRESENT (1 << _PAGE_PRESENT_SHIFT)
+/* implemented in software */
+#define _PAGE_MODIFIED_SHIFT (_PAGE_PRESENT_SHIFT + 1)
+#define _PAGE_MODIFIED (1 << _PAGE_MODIFIED_SHIFT)
+/* set:pagecache unset:swap */
+#define _PAGE_FILE (_PAGE_MODIFIED)
/* implemented in software, should be unused if cpu_has_rixi. */
#define _PAGE_READ_SHIFT (_PAGE_PRESENT_SHIFT + 1)
#define _PAGE_READ (1 << _PAGE_READ_SHIFT)
@@ -182,20 +187,15 @@
/* implemented in software */
#define _PAGE_ACCESSED_SHIFT (_PAGE_WRITE_SHIFT + 1)
#define _PAGE_ACCESSED (1 << _PAGE_ACCESSED_SHIFT)
-/* implemented in software */
-#define _PAGE_MODIFIED_SHIFT (_PAGE_ACCESSED_SHIFT + 1)
-#define _PAGE_MODIFIED (1 << _PAGE_MODIFIED_SHIFT)
-/* set:pagecache unset:swap */
-#define _PAGE_FILE (_PAGE_MODIFIED)
#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
/* huge tlb page */
-#define _PAGE_HUGE_SHIFT (_PAGE_MODIFIED_SHIFT + 1)
+#define _PAGE_HUGE_SHIFT (_PAGE_ACCESSED_SHIFT + 1)
#define _PAGE_HUGE (1 << _PAGE_HUGE_SHIFT)
#define _PAGE_SPLITTING_SHIFT (_PAGE_HUGE_SHIFT + 1)
#define _PAGE_SPLITTING (1 << _PAGE_SPLITTING_SHIFT)
#else
-#define _PAGE_HUGE_SHIFT (_PAGE_MODIFIED_SHIFT)
+#define _PAGE_HUGE_SHIFT (_PAGE_ACCESSED_SHIFT)
#define _PAGE_HUGE ({BUG(); 1; }) /* Dummy value */
#define _PAGE_SPLITTING_SHIFT (_PAGE_HUGE_SHIFT)
#define _PAGE_SPLITTING ({BUG(); 1; }) /* Dummy value */
@@ -213,28 +213,28 @@
/*
* No HUGE page support
- * Low bits are: CCC D V G RI(=R) XI M A W P
+ * Low bits are: CCC D V G RI(=R) XI A W M(=F) P
* TLB refill will do a ROTR 6 (in case of cpu_has_rixi),
* or SRL 6 to strip low bits.
- * All 20 bits PFN are preserved in high bits (4GB in 4KB pages)
+ * All 20 bits PFN are preserved in high bits (4GB with 4KB pages)
*/
#define _PAGE_PRESENT_SHIFT (0)
#define _PAGE_PRESENT (1 << _PAGE_PRESENT_SHIFT)
/* implemented in software */
-#define _PAGE_WRITE_SHIFT (_PAGE_PRESENT_SHIFT + 1)
+#define _PAGE_MODIFIED_SHIFT (_PAGE_PRESENT_SHIFT + 1)
+#define _PAGE_MODIFIED (1 << _PAGE_MODIFIED_SHIFT)
+/* set:pagecache unset:swap */
+#define _PAGE_FILE (_PAGE_MODIFIED)
+/* implemented in software */
+#define _PAGE_WRITE_SHIFT (_PAGE_MODIFIED_SHIFT + 1)
#define _PAGE_WRITE (1 << _PAGE_WRITE_SHIFT)
/* implemented in software */
#define _PAGE_ACCESSED_SHIFT (_PAGE_WRITE_SHIFT + 1)
#define _PAGE_ACCESSED (1 << _PAGE_ACCESSED_SHIFT)
-/* implemented in software */
-#define _PAGE_MODIFIED_SHIFT (_PAGE_ACCESSED_SHIFT + 1)
-#define _PAGE_MODIFIED (1 << _PAGE_MODIFIED_SHIFT)
-/* set:pagecache unset:swap */
-#define _PAGE_FILE (_PAGE_MODIFIED)
/* huge tlb page dummies */
-#define _PAGE_HUGE_SHIFT (_PAGE_MODIFIED_SHIFT)
+#define _PAGE_HUGE_SHIFT (_PAGE_ACCESSED_SHIFT)
#define _PAGE_HUGE ({BUG(); 1; }) /* Dummy value */
#define _PAGE_SPLITTING_SHIFT (_PAGE_HUGE_SHIFT)
#define _PAGE_SPLITTING ({BUG(); 1; }) /* Dummy value */
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 2/3] MIPS: PTE bit positions slightly changed to prepare a more simple swap/file presentation
2014-09-05 1:03 ` [PATCH 2/3] MIPS: PTE bit positions slightly changed to prepare a more simple swap/file presentation Leonid Yegoshin
@ 2014-09-05 1:03 ` Leonid Yegoshin
0 siblings, 0 replies; 9+ messages in thread
From: Leonid Yegoshin @ 2014-09-05 1:03 UTC (permalink / raw)
To: linux-mips, hauke, yanh, zajec5, ralf, alex.smith, taohl, chenhc
Bit _PAGE_MODIFIED (= _PAGE_FILE) in PTE is moved close to _PAGE_PRESENT.
It allows a more compact bit grouping of V,G and F,P - PTE File entry uses
all available bits besides V/G/F and P to keep page offset in file.
This grouping is needed for subsequent bugfix patch of invalid overlapping
_PAGE_FILE, _PAGE_VALID etc bits with other bits used for file offset.
Signed-off-by: Leonid Yegoshin <Leonid.Yegoshin@imgtec.com>
---
arch/mips/include/asm/pgtable-bits.h | 74 +++++++++++++++++-----------------
1 files changed, 37 insertions(+), 37 deletions(-)
diff --git a/arch/mips/include/asm/pgtable-bits.h b/arch/mips/include/asm/pgtable-bits.h
index 4183771..d47be80 100644
--- a/arch/mips/include/asm/pgtable-bits.h
+++ b/arch/mips/include/asm/pgtable-bits.h
@@ -55,16 +55,15 @@
*/
#define _PAGE_PRESENT_SHIFT 6
#define _PAGE_PRESENT (1 << _PAGE_PRESENT_SHIFT)
-#define _PAGE_READ_SHIFT 7
+#define _PAGE_MODIFIED_SHIFT 7
+#define _PAGE_MODIFIED (1 << _PAGE_MODIFIED_SHIFT)
+#define _PAGE_FILE (1 << _PAGE_MODIFIED_SHIFT)
+#define _PAGE_READ_SHIFT 8
#define _PAGE_READ (1 << _PAGE_READ_SHIFT)
-#define _PAGE_WRITE_SHIFT 8
+#define _PAGE_WRITE_SHIFT 9
#define _PAGE_WRITE (1 << _PAGE_WRITE_SHIFT)
-#define _PAGE_ACCESSED_SHIFT 9
+#define _PAGE_ACCESSED_SHIFT 10
#define _PAGE_ACCESSED (1 << _PAGE_ACCESSED_SHIFT)
-#define _PAGE_MODIFIED_SHIFT 10
-#define _PAGE_MODIFIED (1 << _PAGE_MODIFIED_SHIFT)
-
-#define _PAGE_FILE (1 << 10)
#elif defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
@@ -75,16 +74,16 @@
*/
#define _PAGE_PRESENT_SHIFT 0
#define _PAGE_PRESENT (1 << _PAGE_PRESENT_SHIFT)
-#define _PAGE_READ_SHIFT 1
+#define _PAGE_MODIFIED_SHIFT 1
+#define _PAGE_MODIFIED (1 << _PAGE_MODIFIED_SHIFT)
+#define _PAGE_FILE_SHIFT 1
+#define _PAGE_FILE (1 << _PAGE_FILE_SHIFT)
+#define _PAGE_READ_SHIFT 2
#define _PAGE_READ (1 << _PAGE_READ_SHIFT)
-#define _PAGE_WRITE_SHIFT 2
+#define _PAGE_WRITE_SHIFT 3
#define _PAGE_WRITE (1 << _PAGE_WRITE_SHIFT)
-#define _PAGE_ACCESSED_SHIFT 3
+#define _PAGE_ACCESSED_SHIFT 4
#define _PAGE_ACCESSED (1 << _PAGE_ACCESSED_SHIFT)
-#define _PAGE_MODIFIED_SHIFT 4
-#define _PAGE_MODIFIED (1 << _PAGE_MODIFIED_SHIFT)
-#define _PAGE_FILE_SHIFT 4
-#define _PAGE_FILE (1 << _PAGE_FILE_SHIFT)
/*
* And these are the hardware TLB bits
@@ -120,22 +119,23 @@
*/
#define _PAGE_PRESENT_SHIFT (0)
#define _PAGE_PRESENT (1 << _PAGE_PRESENT_SHIFT)
-#define _PAGE_READ_SHIFT (cpu_has_rixi ? _PAGE_PRESENT_SHIFT : _PAGE_PRESENT_SHIFT + 1)
+#define _PAGE_MODIFIED_SHIFT (_PAGE_PRESENT_SHIFT + 1)
+#define _PAGE_MODIFIED (1 << _PAGE_MODIFIED_SHIFT)
+#define _PAGE_FILE (_PAGE_MODIFIED)
+#define _PAGE_READ_SHIFT \
+ (cpu_has_rixi ? _PAGE_MODIFIED_SHIFT : _PAGE_MODIFIED_SHIFT + 1)
#define _PAGE_READ ({BUG_ON(cpu_has_rixi); 1 << _PAGE_READ_SHIFT; })
#define _PAGE_WRITE_SHIFT (_PAGE_READ_SHIFT + 1)
#define _PAGE_WRITE (1 << _PAGE_WRITE_SHIFT)
#define _PAGE_ACCESSED_SHIFT (_PAGE_WRITE_SHIFT + 1)
#define _PAGE_ACCESSED (1 << _PAGE_ACCESSED_SHIFT)
-#define _PAGE_MODIFIED_SHIFT (_PAGE_ACCESSED_SHIFT + 1)
-#define _PAGE_MODIFIED (1 << _PAGE_MODIFIED_SHIFT)
-#define _PAGE_FILE (_PAGE_MODIFIED)
#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
/* huge tlb page */
-#define _PAGE_HUGE_SHIFT (_PAGE_MODIFIED_SHIFT + 1)
+#define _PAGE_HUGE_SHIFT (_PAGE_ACCESSED_SHIFT + 1)
#define _PAGE_HUGE (1 << _PAGE_HUGE_SHIFT)
#else
-#define _PAGE_HUGE_SHIFT (_PAGE_MODIFIED_SHIFT)
+#define _PAGE_HUGE_SHIFT (_PAGE_ACCESSED_SHIFT)
#define _PAGE_HUGE ({BUG(); 1; }) /* Dummy value */
#endif
@@ -165,7 +165,7 @@
#ifdef CONFIG_64BIT
/*
- * Low bits are: CCC D V G RI XI [S H] M A W R P
+ * Low bits are: CCC D V G RI XI [S H] A W R M(=F) P
* TLB refill will do a ROTR 7/9 (in case of cpu_has_rixi),
* or SRL/DSRL 7/9 to strip low bits.
* PFN size in high bits is 49 or 51 bit --> 512TB or 4*512TB for 4KB pages
@@ -173,6 +173,11 @@
#define _PAGE_PRESENT_SHIFT (0)
#define _PAGE_PRESENT (1 << _PAGE_PRESENT_SHIFT)
+/* implemented in software */
+#define _PAGE_MODIFIED_SHIFT (_PAGE_PRESENT_SHIFT + 1)
+#define _PAGE_MODIFIED (1 << _PAGE_MODIFIED_SHIFT)
+/* set:pagecache unset:swap */
+#define _PAGE_FILE (_PAGE_MODIFIED)
/* implemented in software, should be unused if cpu_has_rixi. */
#define _PAGE_READ_SHIFT (_PAGE_PRESENT_SHIFT + 1)
#define _PAGE_READ (1 << _PAGE_READ_SHIFT)
@@ -182,20 +187,15 @@
/* implemented in software */
#define _PAGE_ACCESSED_SHIFT (_PAGE_WRITE_SHIFT + 1)
#define _PAGE_ACCESSED (1 << _PAGE_ACCESSED_SHIFT)
-/* implemented in software */
-#define _PAGE_MODIFIED_SHIFT (_PAGE_ACCESSED_SHIFT + 1)
-#define _PAGE_MODIFIED (1 << _PAGE_MODIFIED_SHIFT)
-/* set:pagecache unset:swap */
-#define _PAGE_FILE (_PAGE_MODIFIED)
#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
/* huge tlb page */
-#define _PAGE_HUGE_SHIFT (_PAGE_MODIFIED_SHIFT + 1)
+#define _PAGE_HUGE_SHIFT (_PAGE_ACCESSED_SHIFT + 1)
#define _PAGE_HUGE (1 << _PAGE_HUGE_SHIFT)
#define _PAGE_SPLITTING_SHIFT (_PAGE_HUGE_SHIFT + 1)
#define _PAGE_SPLITTING (1 << _PAGE_SPLITTING_SHIFT)
#else
-#define _PAGE_HUGE_SHIFT (_PAGE_MODIFIED_SHIFT)
+#define _PAGE_HUGE_SHIFT (_PAGE_ACCESSED_SHIFT)
#define _PAGE_HUGE ({BUG(); 1; }) /* Dummy value */
#define _PAGE_SPLITTING_SHIFT (_PAGE_HUGE_SHIFT)
#define _PAGE_SPLITTING ({BUG(); 1; }) /* Dummy value */
@@ -213,28 +213,28 @@
/*
* No HUGE page support
- * Low bits are: CCC D V G RI(=R) XI M A W P
+ * Low bits are: CCC D V G RI(=R) XI A W M(=F) P
* TLB refill will do a ROTR 6 (in case of cpu_has_rixi),
* or SRL 6 to strip low bits.
- * All 20 bits PFN are preserved in high bits (4GB in 4KB pages)
+ * All 20 bits PFN are preserved in high bits (4GB with 4KB pages)
*/
#define _PAGE_PRESENT_SHIFT (0)
#define _PAGE_PRESENT (1 << _PAGE_PRESENT_SHIFT)
/* implemented in software */
-#define _PAGE_WRITE_SHIFT (_PAGE_PRESENT_SHIFT + 1)
+#define _PAGE_MODIFIED_SHIFT (_PAGE_PRESENT_SHIFT + 1)
+#define _PAGE_MODIFIED (1 << _PAGE_MODIFIED_SHIFT)
+/* set:pagecache unset:swap */
+#define _PAGE_FILE (_PAGE_MODIFIED)
+/* implemented in software */
+#define _PAGE_WRITE_SHIFT (_PAGE_MODIFIED_SHIFT + 1)
#define _PAGE_WRITE (1 << _PAGE_WRITE_SHIFT)
/* implemented in software */
#define _PAGE_ACCESSED_SHIFT (_PAGE_WRITE_SHIFT + 1)
#define _PAGE_ACCESSED (1 << _PAGE_ACCESSED_SHIFT)
-/* implemented in software */
-#define _PAGE_MODIFIED_SHIFT (_PAGE_ACCESSED_SHIFT + 1)
-#define _PAGE_MODIFIED (1 << _PAGE_MODIFIED_SHIFT)
-/* set:pagecache unset:swap */
-#define _PAGE_FILE (_PAGE_MODIFIED)
/* huge tlb page dummies */
-#define _PAGE_HUGE_SHIFT (_PAGE_MODIFIED_SHIFT)
+#define _PAGE_HUGE_SHIFT (_PAGE_ACCESSED_SHIFT)
#define _PAGE_HUGE ({BUG(); 1; }) /* Dummy value */
#define _PAGE_SPLITTING_SHIFT (_PAGE_HUGE_SHIFT)
#define _PAGE_SPLITTING ({BUG(); 1; }) /* Dummy value */
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 3/3] MIPS: bugfix of PTE formats for swap and file entries
2014-09-05 1:03 [PATCH 0/3] PTE formats changes Leonid Yegoshin
` (2 preceding siblings ...)
2014-09-05 1:03 ` [PATCH 2/3] MIPS: PTE bit positions slightly changed to prepare a more simple swap/file presentation Leonid Yegoshin
@ 2014-09-05 1:04 ` Leonid Yegoshin
2014-09-05 1:04 ` Leonid Yegoshin
2014-09-05 7:20 ` [PATCH 0/3] PTE formats changes Rafał Miłecki
4 siblings, 1 reply; 9+ messages in thread
From: Leonid Yegoshin @ 2014-09-05 1:04 UTC (permalink / raw)
To: linux-mips, hauke, yanh, zajec5, ralf, alex.smith, taohl, chenhc
Some patch before last era set up hardcoded bits and offsets values of
PTE file and swap entries formats (traced up to last history era beginning)
in pgtable-32.h/pgtable-64.h
Patches
commit 6ebba0e2f56ee77270a9ef8e92c1b4ec38e5f419
Author: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Date: Sat May 27 20:43:04 2006 +0400
[MIPS] Fix swap entry for MIPS32 36-bit physical address
and
commit 7cb710c9a617384cd0ed30638f3acc00125690fc
Author: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Date: Sat May 27 22:39:39 2006 +0400
[MIPS] Fix non-linear memory mapping on MIPS
fixes some issues but doesn't change a hardcoded bits/offsets encoding,
so, the subsequent patches:
commit 6dd9344cfc41bcc60a01cdc828cb278be7a10e01
Author: David Daney <ddaney@caviumnetworks.com>
Date: Wed Feb 10 15:12:47 2010 -0800
MIPS: Implement Read Inhibit/eXecute Inhibit
commit 970d032fec3f9687446595ee2569fb70b858a69f
Author: Ralf Baechle <ralf@linux-mips.org>
Date: Thu Oct 18 13:54:15 2012 +0200
MIPS: Transparent Huge Pages support
changed PTE bit format yet another time but missed the appropriate bit/offset
changes in pgtable-32.h/pgtable-64.h for file/swap formats.
Besides that, bit formats now are many and even may be run-time dependent
(RI/XI availability or/and HUGE page support availability).
This bugfix patch:
I. Introduces a symbolic named definitions for pgtable-32.h/pgtable-64.h
in proper place - pgtable.h to underline a hard relationship between
PTE bit positions in pgtable.h and file/swap entries format in
pgtable-32.h/pgtable-64.h files.
II. Setup macros to fix multivariable formats (moving bits V/G depending on
kernel config and run-time options) and put this issue finally to rest
Bug can pops-up in heavy paging environment in form of random application/kernel
crashes. It is unusual in embedded and that may be a reason why it is not
catched yet.
This change is based in assumption that excluded bits in file PTE format
(V/G/F/P) are located in two groups with P is rightmost (but 64BIT & MIPS32
configuration is a some special case). Previous patch in series "MIPS: PTE bit
positions slightly changed" does it.
Signed-off-by: Leonid Yegoshin <Leonid.Yegoshin@imgtec.com>
---
arch/mips/include/asm/pgtable-32.h | 107 +++++++++++++++-------------------
arch/mips/include/asm/pgtable-64.h | 25 +++++---
arch/mips/include/asm/pgtable-bits.h | 47 +++++++++++++++
3 files changed, 110 insertions(+), 69 deletions(-)
diff --git a/arch/mips/include/asm/pgtable-32.h b/arch/mips/include/asm/pgtable-32.h
index cd7d606..adba9db 100644
--- a/arch/mips/include/asm/pgtable-32.h
+++ b/arch/mips/include/asm/pgtable-32.h
@@ -152,76 +152,61 @@ pfn_pte(unsigned long pfn, pgprot_t prot)
((pte_t *)page_address(pmd_page(*(dir))) + __pte_offset(address))
#define pte_unmap(pte) ((void)(pte))
-#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
-
-/* Swap entries must have VALID bit cleared. */
-#define __swp_type(x) (((x).val >> 10) & 0x1f)
-#define __swp_offset(x) ((x).val >> 15)
-#define __swp_entry(type,offset) \
- ((swp_entry_t) { ((type) << 10) | ((offset) << 15) })
-
-/*
- * Bits 0, 4, 8, and 9 are taken, split up 28 bits of offset into this range:
- */
-#define PTE_FILE_MAX_BITS 28
-
-#define pte_to_pgoff(_pte) ((((_pte).pte >> 1 ) & 0x07) | \
- (((_pte).pte >> 2 ) & 0x38) | \
- (((_pte).pte >> 10) << 6 ))
-
-#define pgoff_to_pte(off) ((pte_t) { (((off) & 0x07) << 1 ) | \
- (((off) & 0x38) << 2 ) | \
- (((off) >> 6 ) << 10) | \
- _PAGE_FILE })
-
-#else
-
-/* Swap entries must have VALID and GLOBAL bits cleared. */
#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)
-#define __swp_type(x) (((x).val >> 2) & 0x1f)
-#define __swp_offset(x) ((x).val >> 7)
-#define __swp_entry(type,offset) \
- ((swp_entry_t) { ((type) << 2) | ((offset) << 7) })
-#else
-#define __swp_type(x) (((x).val >> 8) & 0x1f)
-#define __swp_offset(x) ((x).val >> 13)
-#define __swp_entry(type,offset) \
- ((swp_entry_t) { ((type) << 8) | ((offset) << 13) })
-#endif /* defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) */
-#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)
/*
- * Bits 0 and 1 of pte_high are taken, use the rest for the page offset...
- */
-#define PTE_FILE_MAX_BITS 30
-
-#define pte_to_pgoff(_pte) ((_pte).pte_high >> 2)
-#define pgoff_to_pte(off) ((pte_t) { _PAGE_FILE, (off) << 2 })
-
-#else
-/*
- * Bits 0, 4, 6, and 7 are taken, split up 28 bits of offset into this range:
+ * Two words PTE case:
+ * Bits 0 and 1 (V+G) of pte_high are taken, use the rest for the swaps and
+ * page offset...
+ * Bits F and P are in pte_low.
+ *
+ * Note: swp_entry_t is one word today.
*/
-#define PTE_FILE_MAX_BITS 28
+#define __swp_type(x) \
+ (((x).val >> __SWP_PTE_SKIP_BITS_NUM) & __SWP_TYPE_MASK)
+#define __swp_offset(x) \
+ ((x).val >> (__SWP_PTE_SKIP_BITS_NUM + __SWP_TYPE_BITS_NUM))
+#define __swp_entry(type, offset) \
+ ((swp_entry_t) { ((type) << __SWP_PTE_SKIP_BITS_NUM) | \
+ ((offset) << (__SWP_TYPE_BITS_NUM + __SWP_PTE_SKIP_BITS_NUM)) })
+#define __pte_to_swp_entry(pte) ((swp_entry_t) { (pte).pte_high })
+#define __swp_entry_to_pte(x) ((pte_t) { 0, (x).val })
-#define pte_to_pgoff(_pte) ((((_pte).pte >> 1) & 0x7) | \
- (((_pte).pte >> 2) & 0x8) | \
- (((_pte).pte >> 8) << 4))
+#define PTE_FILE_MAX_BITS (32 - __SWP_PTE_SKIP_BITS_NUM)
-#define pgoff_to_pte(off) ((pte_t) { (((off) & 0x7) << 1) | \
- (((off) & 0x8) << 2) | \
- (((off) >> 4) << 8) | \
- _PAGE_FILE })
-#endif
+#define pte_to_pgoff(_pte) ((_pte).pte_high >> __SWP_PTE_SKIP_BITS_NUM)
+#define pgoff_to_pte(off) \
+ ((pte_t) { _PAGE_FILE, (off) << __SWP_PTE_SKIP_BITS_NUM })
-#endif
+#else /* CONFIG_CPU_MIPS32 && !CONFIG_64BIT_PHYS_ADDR */
-#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)
-#define __pte_to_swp_entry(pte) ((swp_entry_t) { (pte).pte_high })
-#define __swp_entry_to_pte(x) ((pte_t) { 0, (x).val })
-#else
+/* Swap entries must have V,G,P and F bits cleared. */
+#define __swp_type(x) (((x).val >> _PAGE_DIRTY_SHIFT) & __SWP_TYPE_MASK)
+#define __swp_offset(x) \
+ ((x).val >> (_PAGE_DIRTY_SHIFT + __SWP_TYPE_BITS_NUM))
+#define __swp_entry(type, offset) \
+ ((swp_entry_t) { ((type) << _PAGE_DIRTY_SHIFT) | \
+ ((offset) << (_PAGE_DIRTY_SHIFT + __SWP_TYPE_BITS_NUM)) })
#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
#define __swp_entry_to_pte(x) ((pte_t) { (x).val })
-#endif
+/*
+ * Bits V+G, and F+P are taken, split up 28 bits of offset into two bitfields:
+ */
+#define PTE_FILE_MAX_BITS (32 - __FILE_PTE_TOTAL_BITS_NUM)
+
+#define pte_to_pgoff(_pte) \
+ ((((_pte).pte >> __FILE_PTE_TOTAL_BITS_NUM) & \
+ ~(__FILE_PTE_LOW_MASK)) | \
+ (((_pte).pte >> __FILE_PTE_LOW_BITS_NUM) & \
+ (__FILE_PTE_LOW_MASK)))
+
+#define pgoff_to_pte(off) \
+ ((pte_t) { (((off) & __FILE_PTE_LOW_MASK) << \
+ (__FILE_PTE_LOW_BITS_NUM)) | \
+ (((off) & ~(__FILE_PTE_LOW_MASK)) << \
+ (__FILE_PTE_TOTAL_BITS_NUM)) | \
+ _PAGE_FILE })
+
+#endif /* CONFIG_64BIT_PHYS_ADDR && CONFIG_MIPS32 */
#endif /* _ASM_PGTABLE_32_H */
diff --git a/arch/mips/include/asm/pgtable-64.h b/arch/mips/include/asm/pgtable-64.h
index e1c49a9..3484910 100644
--- a/arch/mips/include/asm/pgtable-64.h
+++ b/arch/mips/include/asm/pgtable-64.h
@@ -283,21 +283,30 @@ extern void pmd_init(unsigned long page, unsigned long pagetable);
* low 32 bits zero.
*/
static inline pte_t mk_swap_pte(unsigned long type, unsigned long offset)
-{ pte_t pte; pte_val(pte) = (type << 32) | (offset << 40); return pte; }
+{
+ pte_t pte;
+
+ pte_val(pte) = (type << __SWP_PTE_SKIP_BITS_NUM) |
+ (offset << (__SWP_PTE_SKIP_BITS_NUM + __SWP_TYPE_BITS_NUM));
+ return pte;
+}
-#define __swp_type(x) (((x).val >> 32) & 0xff)
-#define __swp_offset(x) ((x).val >> 40)
+#define __swp_type(x) \
+ (((x).val >> __SWP_PTE_SKIP_BITS_NUM) & __SWP_TYPE_MASK)
+#define __swp_offset(x) \
+ ((x).val >> (__SWP_PTE_SKIP_BITS_NUM + __SWP_TYPE_BITS_NUM))
#define __swp_entry(type, offset) ((swp_entry_t) { pte_val(mk_swap_pte((type), (offset))) })
#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
#define __swp_entry_to_pte(x) ((pte_t) { (x).val })
/*
- * Bits 0, 4, 6, and 7 are taken. Let's leave bits 1, 2, 3, and 5 alone to
- * make things easier, and only use the upper 56 bits for the page offset...
+ * Take out all bits from V to bit 0. We should actually take out only VGFP but
+ * today PTE is too complicated by HUGE page support etc
*/
-#define PTE_FILE_MAX_BITS 56
+#define PTE_FILE_MAX_BITS (64 - _PAGE_DIRTY_SHIFT)
-#define pte_to_pgoff(_pte) ((_pte).pte >> 8)
-#define pgoff_to_pte(off) ((pte_t) { ((off) << 8) | _PAGE_FILE })
+#define pte_to_pgoff(_pte) ((_pte).pte >> _PAGE_DIRTY_SHIFT)
+#define pgoff_to_pte(off) \
+ ((pte_t) { ((off) << _PAGE_DIRTY_SHIFT) | _PAGE_FILE })
#endif /* _ASM_PGTABLE_64_H */
diff --git a/arch/mips/include/asm/pgtable-bits.h b/arch/mips/include/asm/pgtable-bits.h
index d47be80..708f681 100644
--- a/arch/mips/include/asm/pgtable-bits.h
+++ b/arch/mips/include/asm/pgtable-bits.h
@@ -121,6 +121,7 @@
#define _PAGE_PRESENT (1 << _PAGE_PRESENT_SHIFT)
#define _PAGE_MODIFIED_SHIFT (_PAGE_PRESENT_SHIFT + 1)
#define _PAGE_MODIFIED (1 << _PAGE_MODIFIED_SHIFT)
+#define _PAGE_FILE_SHIFT (_PAGE_MODIFIED_SHIFT)
#define _PAGE_FILE (_PAGE_MODIFIED)
#define _PAGE_READ_SHIFT \
(cpu_has_rixi ? _PAGE_MODIFIED_SHIFT : _PAGE_MODIFIED_SHIFT + 1)
@@ -225,6 +226,7 @@
#define _PAGE_MODIFIED_SHIFT (_PAGE_PRESENT_SHIFT + 1)
#define _PAGE_MODIFIED (1 << _PAGE_MODIFIED_SHIFT)
/* set:pagecache unset:swap */
+#define _PAGE_FILE_SHIFT (_PAGE_MODIFIED_SHIFT)
#define _PAGE_FILE (_PAGE_MODIFIED)
/* implemented in software */
#define _PAGE_WRITE_SHIFT (_PAGE_MODIFIED_SHIFT + 1)
@@ -292,6 +294,51 @@
#define _PAGE_GLOBAL_SHIFT ilog2(_PAGE_GLOBAL)
#endif
+/*
+ * Swap and File entries format definitions in PTE
+ * This constant definitions are here because it is linked with bit positions
+ * The real macros are still in pgtable-32/64.h
+ *
+ * There are 3 kind of format - 64BIT, generic 32BIT and 32BIT & 64BIT PA
+ */
+#define __SWP_TYPE_BITS_NUM 5
+#define __SWP_TYPE_MASK ((1 << __SWP_TYPE_BITS_NUM) - 1)
+
+#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)
+
+/*
+ * Two words PTE case:
+ * Bits 0 and 1 (V+G) of pte_high are taken, use the rest for the swaps and
+ * page offset...
+ * Bits F and P are in pte_low.
+ *
+ * Note: swp_entry_t or file entry are one word today (pte_high)
+ */
+#define __SWP_PTE_SKIP_BITS_NUM 2
+
+#elif defined(CONFIG_64BIT)
+/*
+ * Swap entry is located in high 32 bits of PTE
+ *
+ * File entry starts right from D bit
+ */
+#define __SWP_PTE_SKIP_BITS_NUM 32
+
+#else /* CONFIG_CPU_MIPS32 && !CONFIG_64BIT_PHYS_ADDR */
+/*
+ * Swap entry is encoded starting right from D bit
+ *
+ * File entry is encoded in all bits besides V,G,F and P which are grouped in
+ * two fields with variable gap, so - additonal location info is defined here
+ */
+/* rightmost taken out field - F and P */
+#define __FILE_PTE_LOW_BITS_NUM 2
+/* total number of taken out bits - V,G,F,P */
+#define __FILE_PTE_TOTAL_BITS_NUM 4
+/* mask for intermediate field which is used for encoding */
+#define __FILE_PTE_LOW_MASK ((_PAGE_GLOBAL - 1) >> (_PAGE_FILE_SHIFT + 1))
+
+#endif /* defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) */
#ifndef __ASSEMBLY__
/*
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 3/3] MIPS: bugfix of PTE formats for swap and file entries
2014-09-05 1:04 ` [PATCH 3/3] MIPS: bugfix of PTE formats for swap and file entries Leonid Yegoshin
@ 2014-09-05 1:04 ` Leonid Yegoshin
0 siblings, 0 replies; 9+ messages in thread
From: Leonid Yegoshin @ 2014-09-05 1:04 UTC (permalink / raw)
To: linux-mips, hauke, yanh, zajec5, ralf, alex.smith, taohl, chenhc
Some patch before last era set up hardcoded bits and offsets values of
PTE file and swap entries formats (traced up to last history era beginning)
in pgtable-32.h/pgtable-64.h
Patches
commit 6ebba0e2f56ee77270a9ef8e92c1b4ec38e5f419
Author: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Date: Sat May 27 20:43:04 2006 +0400
[MIPS] Fix swap entry for MIPS32 36-bit physical address
and
commit 7cb710c9a617384cd0ed30638f3acc00125690fc
Author: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Date: Sat May 27 22:39:39 2006 +0400
[MIPS] Fix non-linear memory mapping on MIPS
fixes some issues but doesn't change a hardcoded bits/offsets encoding,
so, the subsequent patches:
commit 6dd9344cfc41bcc60a01cdc828cb278be7a10e01
Author: David Daney <ddaney@caviumnetworks.com>
Date: Wed Feb 10 15:12:47 2010 -0800
MIPS: Implement Read Inhibit/eXecute Inhibit
commit 970d032fec3f9687446595ee2569fb70b858a69f
Author: Ralf Baechle <ralf@linux-mips.org>
Date: Thu Oct 18 13:54:15 2012 +0200
MIPS: Transparent Huge Pages support
changed PTE bit format yet another time but missed the appropriate bit/offset
changes in pgtable-32.h/pgtable-64.h for file/swap formats.
Besides that, bit formats now are many and even may be run-time dependent
(RI/XI availability or/and HUGE page support availability).
This bugfix patch:
I. Introduces a symbolic named definitions for pgtable-32.h/pgtable-64.h
in proper place - pgtable.h to underline a hard relationship between
PTE bit positions in pgtable.h and file/swap entries format in
pgtable-32.h/pgtable-64.h files.
II. Setup macros to fix multivariable formats (moving bits V/G depending on
kernel config and run-time options) and put this issue finally to rest
Bug can pops-up in heavy paging environment in form of random application/kernel
crashes. It is unusual in embedded and that may be a reason why it is not
catched yet.
This change is based in assumption that excluded bits in file PTE format
(V/G/F/P) are located in two groups with P is rightmost (but 64BIT & MIPS32
configuration is a some special case). Previous patch in series "MIPS: PTE bit
positions slightly changed" does it.
Signed-off-by: Leonid Yegoshin <Leonid.Yegoshin@imgtec.com>
---
arch/mips/include/asm/pgtable-32.h | 107 +++++++++++++++-------------------
arch/mips/include/asm/pgtable-64.h | 25 +++++---
arch/mips/include/asm/pgtable-bits.h | 47 +++++++++++++++
3 files changed, 110 insertions(+), 69 deletions(-)
diff --git a/arch/mips/include/asm/pgtable-32.h b/arch/mips/include/asm/pgtable-32.h
index cd7d606..adba9db 100644
--- a/arch/mips/include/asm/pgtable-32.h
+++ b/arch/mips/include/asm/pgtable-32.h
@@ -152,76 +152,61 @@ pfn_pte(unsigned long pfn, pgprot_t prot)
((pte_t *)page_address(pmd_page(*(dir))) + __pte_offset(address))
#define pte_unmap(pte) ((void)(pte))
-#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
-
-/* Swap entries must have VALID bit cleared. */
-#define __swp_type(x) (((x).val >> 10) & 0x1f)
-#define __swp_offset(x) ((x).val >> 15)
-#define __swp_entry(type,offset) \
- ((swp_entry_t) { ((type) << 10) | ((offset) << 15) })
-
-/*
- * Bits 0, 4, 8, and 9 are taken, split up 28 bits of offset into this range:
- */
-#define PTE_FILE_MAX_BITS 28
-
-#define pte_to_pgoff(_pte) ((((_pte).pte >> 1 ) & 0x07) | \
- (((_pte).pte >> 2 ) & 0x38) | \
- (((_pte).pte >> 10) << 6 ))
-
-#define pgoff_to_pte(off) ((pte_t) { (((off) & 0x07) << 1 ) | \
- (((off) & 0x38) << 2 ) | \
- (((off) >> 6 ) << 10) | \
- _PAGE_FILE })
-
-#else
-
-/* Swap entries must have VALID and GLOBAL bits cleared. */
#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)
-#define __swp_type(x) (((x).val >> 2) & 0x1f)
-#define __swp_offset(x) ((x).val >> 7)
-#define __swp_entry(type,offset) \
- ((swp_entry_t) { ((type) << 2) | ((offset) << 7) })
-#else
-#define __swp_type(x) (((x).val >> 8) & 0x1f)
-#define __swp_offset(x) ((x).val >> 13)
-#define __swp_entry(type,offset) \
- ((swp_entry_t) { ((type) << 8) | ((offset) << 13) })
-#endif /* defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) */
-#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)
/*
- * Bits 0 and 1 of pte_high are taken, use the rest for the page offset...
- */
-#define PTE_FILE_MAX_BITS 30
-
-#define pte_to_pgoff(_pte) ((_pte).pte_high >> 2)
-#define pgoff_to_pte(off) ((pte_t) { _PAGE_FILE, (off) << 2 })
-
-#else
-/*
- * Bits 0, 4, 6, and 7 are taken, split up 28 bits of offset into this range:
+ * Two words PTE case:
+ * Bits 0 and 1 (V+G) of pte_high are taken, use the rest for the swaps and
+ * page offset...
+ * Bits F and P are in pte_low.
+ *
+ * Note: swp_entry_t is one word today.
*/
-#define PTE_FILE_MAX_BITS 28
+#define __swp_type(x) \
+ (((x).val >> __SWP_PTE_SKIP_BITS_NUM) & __SWP_TYPE_MASK)
+#define __swp_offset(x) \
+ ((x).val >> (__SWP_PTE_SKIP_BITS_NUM + __SWP_TYPE_BITS_NUM))
+#define __swp_entry(type, offset) \
+ ((swp_entry_t) { ((type) << __SWP_PTE_SKIP_BITS_NUM) | \
+ ((offset) << (__SWP_TYPE_BITS_NUM + __SWP_PTE_SKIP_BITS_NUM)) })
+#define __pte_to_swp_entry(pte) ((swp_entry_t) { (pte).pte_high })
+#define __swp_entry_to_pte(x) ((pte_t) { 0, (x).val })
-#define pte_to_pgoff(_pte) ((((_pte).pte >> 1) & 0x7) | \
- (((_pte).pte >> 2) & 0x8) | \
- (((_pte).pte >> 8) << 4))
+#define PTE_FILE_MAX_BITS (32 - __SWP_PTE_SKIP_BITS_NUM)
-#define pgoff_to_pte(off) ((pte_t) { (((off) & 0x7) << 1) | \
- (((off) & 0x8) << 2) | \
- (((off) >> 4) << 8) | \
- _PAGE_FILE })
-#endif
+#define pte_to_pgoff(_pte) ((_pte).pte_high >> __SWP_PTE_SKIP_BITS_NUM)
+#define pgoff_to_pte(off) \
+ ((pte_t) { _PAGE_FILE, (off) << __SWP_PTE_SKIP_BITS_NUM })
-#endif
+#else /* CONFIG_CPU_MIPS32 && !CONFIG_64BIT_PHYS_ADDR */
-#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)
-#define __pte_to_swp_entry(pte) ((swp_entry_t) { (pte).pte_high })
-#define __swp_entry_to_pte(x) ((pte_t) { 0, (x).val })
-#else
+/* Swap entries must have V,G,P and F bits cleared. */
+#define __swp_type(x) (((x).val >> _PAGE_DIRTY_SHIFT) & __SWP_TYPE_MASK)
+#define __swp_offset(x) \
+ ((x).val >> (_PAGE_DIRTY_SHIFT + __SWP_TYPE_BITS_NUM))
+#define __swp_entry(type, offset) \
+ ((swp_entry_t) { ((type) << _PAGE_DIRTY_SHIFT) | \
+ ((offset) << (_PAGE_DIRTY_SHIFT + __SWP_TYPE_BITS_NUM)) })
#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
#define __swp_entry_to_pte(x) ((pte_t) { (x).val })
-#endif
+/*
+ * Bits V+G, and F+P are taken, split up 28 bits of offset into two bitfields:
+ */
+#define PTE_FILE_MAX_BITS (32 - __FILE_PTE_TOTAL_BITS_NUM)
+
+#define pte_to_pgoff(_pte) \
+ ((((_pte).pte >> __FILE_PTE_TOTAL_BITS_NUM) & \
+ ~(__FILE_PTE_LOW_MASK)) | \
+ (((_pte).pte >> __FILE_PTE_LOW_BITS_NUM) & \
+ (__FILE_PTE_LOW_MASK)))
+
+#define pgoff_to_pte(off) \
+ ((pte_t) { (((off) & __FILE_PTE_LOW_MASK) << \
+ (__FILE_PTE_LOW_BITS_NUM)) | \
+ (((off) & ~(__FILE_PTE_LOW_MASK)) << \
+ (__FILE_PTE_TOTAL_BITS_NUM)) | \
+ _PAGE_FILE })
+
+#endif /* CONFIG_64BIT_PHYS_ADDR && CONFIG_MIPS32 */
#endif /* _ASM_PGTABLE_32_H */
diff --git a/arch/mips/include/asm/pgtable-64.h b/arch/mips/include/asm/pgtable-64.h
index e1c49a9..3484910 100644
--- a/arch/mips/include/asm/pgtable-64.h
+++ b/arch/mips/include/asm/pgtable-64.h
@@ -283,21 +283,30 @@ extern void pmd_init(unsigned long page, unsigned long pagetable);
* low 32 bits zero.
*/
static inline pte_t mk_swap_pte(unsigned long type, unsigned long offset)
-{ pte_t pte; pte_val(pte) = (type << 32) | (offset << 40); return pte; }
+{
+ pte_t pte;
+
+ pte_val(pte) = (type << __SWP_PTE_SKIP_BITS_NUM) |
+ (offset << (__SWP_PTE_SKIP_BITS_NUM + __SWP_TYPE_BITS_NUM));
+ return pte;
+}
-#define __swp_type(x) (((x).val >> 32) & 0xff)
-#define __swp_offset(x) ((x).val >> 40)
+#define __swp_type(x) \
+ (((x).val >> __SWP_PTE_SKIP_BITS_NUM) & __SWP_TYPE_MASK)
+#define __swp_offset(x) \
+ ((x).val >> (__SWP_PTE_SKIP_BITS_NUM + __SWP_TYPE_BITS_NUM))
#define __swp_entry(type, offset) ((swp_entry_t) { pte_val(mk_swap_pte((type), (offset))) })
#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
#define __swp_entry_to_pte(x) ((pte_t) { (x).val })
/*
- * Bits 0, 4, 6, and 7 are taken. Let's leave bits 1, 2, 3, and 5 alone to
- * make things easier, and only use the upper 56 bits for the page offset...
+ * Take out all bits from V to bit 0. We should actually take out only VGFP but
+ * today PTE is too complicated by HUGE page support etc
*/
-#define PTE_FILE_MAX_BITS 56
+#define PTE_FILE_MAX_BITS (64 - _PAGE_DIRTY_SHIFT)
-#define pte_to_pgoff(_pte) ((_pte).pte >> 8)
-#define pgoff_to_pte(off) ((pte_t) { ((off) << 8) | _PAGE_FILE })
+#define pte_to_pgoff(_pte) ((_pte).pte >> _PAGE_DIRTY_SHIFT)
+#define pgoff_to_pte(off) \
+ ((pte_t) { ((off) << _PAGE_DIRTY_SHIFT) | _PAGE_FILE })
#endif /* _ASM_PGTABLE_64_H */
diff --git a/arch/mips/include/asm/pgtable-bits.h b/arch/mips/include/asm/pgtable-bits.h
index d47be80..708f681 100644
--- a/arch/mips/include/asm/pgtable-bits.h
+++ b/arch/mips/include/asm/pgtable-bits.h
@@ -121,6 +121,7 @@
#define _PAGE_PRESENT (1 << _PAGE_PRESENT_SHIFT)
#define _PAGE_MODIFIED_SHIFT (_PAGE_PRESENT_SHIFT + 1)
#define _PAGE_MODIFIED (1 << _PAGE_MODIFIED_SHIFT)
+#define _PAGE_FILE_SHIFT (_PAGE_MODIFIED_SHIFT)
#define _PAGE_FILE (_PAGE_MODIFIED)
#define _PAGE_READ_SHIFT \
(cpu_has_rixi ? _PAGE_MODIFIED_SHIFT : _PAGE_MODIFIED_SHIFT + 1)
@@ -225,6 +226,7 @@
#define _PAGE_MODIFIED_SHIFT (_PAGE_PRESENT_SHIFT + 1)
#define _PAGE_MODIFIED (1 << _PAGE_MODIFIED_SHIFT)
/* set:pagecache unset:swap */
+#define _PAGE_FILE_SHIFT (_PAGE_MODIFIED_SHIFT)
#define _PAGE_FILE (_PAGE_MODIFIED)
/* implemented in software */
#define _PAGE_WRITE_SHIFT (_PAGE_MODIFIED_SHIFT + 1)
@@ -292,6 +294,51 @@
#define _PAGE_GLOBAL_SHIFT ilog2(_PAGE_GLOBAL)
#endif
+/*
+ * Swap and File entries format definitions in PTE
+ * This constant definitions are here because it is linked with bit positions
+ * The real macros are still in pgtable-32/64.h
+ *
+ * There are 3 kind of format - 64BIT, generic 32BIT and 32BIT & 64BIT PA
+ */
+#define __SWP_TYPE_BITS_NUM 5
+#define __SWP_TYPE_MASK ((1 << __SWP_TYPE_BITS_NUM) - 1)
+
+#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)
+
+/*
+ * Two words PTE case:
+ * Bits 0 and 1 (V+G) of pte_high are taken, use the rest for the swaps and
+ * page offset...
+ * Bits F and P are in pte_low.
+ *
+ * Note: swp_entry_t or file entry are one word today (pte_high)
+ */
+#define __SWP_PTE_SKIP_BITS_NUM 2
+
+#elif defined(CONFIG_64BIT)
+/*
+ * Swap entry is located in high 32 bits of PTE
+ *
+ * File entry starts right from D bit
+ */
+#define __SWP_PTE_SKIP_BITS_NUM 32
+
+#else /* CONFIG_CPU_MIPS32 && !CONFIG_64BIT_PHYS_ADDR */
+/*
+ * Swap entry is encoded starting right from D bit
+ *
+ * File entry is encoded in all bits besides V,G,F and P which are grouped in
+ * two fields with variable gap, so - additonal location info is defined here
+ */
+/* rightmost taken out field - F and P */
+#define __FILE_PTE_LOW_BITS_NUM 2
+/* total number of taken out bits - V,G,F,P */
+#define __FILE_PTE_TOTAL_BITS_NUM 4
+/* mask for intermediate field which is used for encoding */
+#define __FILE_PTE_LOW_MASK ((_PAGE_GLOBAL - 1) >> (_PAGE_FILE_SHIFT + 1))
+
+#endif /* defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) */
#ifndef __ASSEMBLY__
/*
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH 0/3] PTE formats changes
2014-09-05 1:03 [PATCH 0/3] PTE formats changes Leonid Yegoshin
` (3 preceding siblings ...)
2014-09-05 1:04 ` [PATCH 3/3] MIPS: bugfix of PTE formats for swap and file entries Leonid Yegoshin
@ 2014-09-05 7:20 ` Rafał Miłecki
4 siblings, 0 replies; 9+ messages in thread
From: Rafał Miłecki @ 2014-09-05 7:20 UTC (permalink / raw)
To: Leonid Yegoshin
Cc: linux-mips@linux-mips.org, Hauke Mehrtens, yanh, Ralf Baechle,
alex.smith, taohl, chenhc
On 5 September 2014 03:03, Leonid Yegoshin <Leonid.Yegoshin@imgtec.com> wrote:
> The following series implements bugfix of PTE formats for swap and file entries
> and changes PTE bit position to fixed, which is more better for analysing of
> tracer and HW debugger logs.
>
> Hardcoded bits positions and offsets in PTE effectively causes a miss of
> relationship between PTE format for TLB and PTE formats for swap and file
> entries. This patch series introduces a symbolic relation between both and
> also fixes a current mismatch of formats. It can crash kernel or application
> in heavy paging environment.
>
> Fixed bit positions helps much in analysing of tracer and HW debugger logs and
> improves performance and code size a little due to absence of variable masks
> in kernel.
Well, this is definitely above my low-level-arch skills to review
this. FWIW kernel with these patches still boots on my BCM5357B0
(router with 32 MiB of RAM).
This pgtable* reminds me of highmem support for bcm47xx, unfortunately
I don't have any device with 256 MiB of RAM to test it.
--
Rafał
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2014-09-05 7:20 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-09-05 1:03 [PATCH 0/3] PTE formats changes Leonid Yegoshin
2014-09-05 1:03 ` Leonid Yegoshin
2014-09-05 1:03 ` [PATCH 1/3] MIPS: rearrange PTE bits into fixed positions Leonid Yegoshin
2014-09-05 1:03 ` Leonid Yegoshin
2014-09-05 1:03 ` [PATCH 2/3] MIPS: PTE bit positions slightly changed to prepare a more simple swap/file presentation Leonid Yegoshin
2014-09-05 1:03 ` Leonid Yegoshin
2014-09-05 1:04 ` [PATCH 3/3] MIPS: bugfix of PTE formats for swap and file entries Leonid Yegoshin
2014-09-05 1:04 ` Leonid Yegoshin
2014-09-05 7:20 ` [PATCH 0/3] PTE formats changes Rafał Miłecki
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox