All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCHv3 00/11] arm64: 16K translation granule support
@ 2015-10-14 11:20 ` Suzuki K. Poulose
  0 siblings, 0 replies; 110+ messages in thread
From: Suzuki K. Poulose @ 2015-10-14 11:20 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-kernel, catalin.marinas, will.deacon, mark.rutland,
	steve.capper, marc.zyngier, ard.biesheuvel, christoffer.dall,
	Suzuki K. Poulose

This series enables the 16K page size support on Linux for arm64.
Adds support for 48bit VA(4 level), 47bit VA(3 level) and
36bit VA(2 level) with 16K. 16K was a late addition to the architecture
and is not implemented by all CPUs. Added a check to ensure the
selected granule size is supported by the CPU, failing which the CPU
won't proceed with booting. Also the kernel page size is added to the
kernel image header (patch from Ard).

KVM support has been dropped from this series, as we need to rewrite the
KVM stage-2 pagetable handling code to get rid of the fake page table
levels (as recommended by Christoffer and Marc). So, with 16K, we cannot
run KVM.

Patches 1-7	cleans up the kernel page size handling code.
Patch 8		Adds a check to ensure the CPU supports the selected granule size.
Patch 9		Adds the page size information to image header.
Patches 10-11	Adds the support for 16K page size

This series applies on top for aarch64:for-next/core with Contiguous bit
support for kernel pagetables.

The tree is also available here:

        git://linux-arm.org/linux-skp.git  16k/v3-aarch64-4.3-next

There is also another branch rebased on top of my 'CPU feature' series here:
	git://linux-arm.org/linux-skp.git  16k/v3-aarch64-4.3-next+ftr

Changes since V2:
  - Dropped KVM support patches
  - Added proper comments for the page-table helper macros
  - Change ARM64_HW_PGTABLE_LEVEL_SHIFT() to accept page table level as described
    by ARM ARM.
  - Added reviews/acks
  - Added CONT_SHIFT for 16K

Changes since V1:
  - Rebase to 4.3-rc1
  - Fix vmemmap_populate for 16K (use !ARM64_SWAPPER_USES_SECTION_MAPS)
  - Better description for patch2 (suggested-by: Ard)
  - Add page size information to the image header flags.
  - Added reviewed-by/tested-by Ard.

Ard Biesheuvel (1):
  arm64: Add page size to the kernel image header

Suzuki K. Poulose (10):
  arm64: Move swapper pagetable definitions
  arm64: Handle section maps for swapper/idmap
  arm64: Introduce helpers for page table levels
  arm64: Calculate size for idmap_pg_dir at compile time
  arm64: Handle 4 level page table for swapper
  arm64: Clean config usages for page size
  arm64: Kconfig: Fix help text about AArch32 support with 64K pages
  arm64: Check for selected granule support
  arm64: Add 16K page size support
  arm64: 36 bit VA

 Documentation/arm64/booting.txt         |    7 ++-
 arch/arm64/Kconfig                      |   37 +++++++++++----
 arch/arm64/Kconfig.debug                |    2 +-
 arch/arm64/include/asm/fixmap.h         |    4 +-
 arch/arm64/include/asm/kernel-pgtable.h |   77 +++++++++++++++++++++++++++++++
 arch/arm64/include/asm/page.h           |   21 ++-------
 arch/arm64/include/asm/pgtable-hwdef.h  |   25 ++++++++--
 arch/arm64/include/asm/sysreg.h         |   12 +++++
 arch/arm64/include/asm/thread_info.h    |    4 +-
 arch/arm64/kernel/head.S                |   75 +++++++++++++++++-------------
 arch/arm64/kernel/image.h               |    5 +-
 arch/arm64/kernel/vmlinux.lds.S         |    1 +
 arch/arm64/kvm/Kconfig                  |    3 ++
 arch/arm64/mm/mmu.c                     |   72 +++++++++++++----------------
 arch/arm64/mm/proc.S                    |    4 +-
 15 files changed, 242 insertions(+), 107 deletions(-)
 create mode 100644 arch/arm64/include/asm/kernel-pgtable.h

-- 
1.7.9.5


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

* [PATCHv3 00/11] arm64: 16K translation granule support
@ 2015-10-14 11:20 ` Suzuki K. Poulose
  0 siblings, 0 replies; 110+ messages in thread
From: Suzuki K. Poulose @ 2015-10-14 11:20 UTC (permalink / raw)
  To: linux-arm-kernel

This series enables the 16K page size support on Linux for arm64.
Adds support for 48bit VA(4 level), 47bit VA(3 level) and
36bit VA(2 level) with 16K. 16K was a late addition to the architecture
and is not implemented by all CPUs. Added a check to ensure the
selected granule size is supported by the CPU, failing which the CPU
won't proceed with booting. Also the kernel page size is added to the
kernel image header (patch from Ard).

KVM support has been dropped from this series, as we need to rewrite the
KVM stage-2 pagetable handling code to get rid of the fake page table
levels (as recommended by Christoffer and Marc). So, with 16K, we cannot
run KVM.

Patches 1-7	cleans up the kernel page size handling code.
Patch 8		Adds a check to ensure the CPU supports the selected granule size.
Patch 9		Adds the page size information to image header.
Patches 10-11	Adds the support for 16K page size

This series applies on top for aarch64:for-next/core with Contiguous bit
support for kernel pagetables.

The tree is also available here:

        git://linux-arm.org/linux-skp.git  16k/v3-aarch64-4.3-next

There is also another branch rebased on top of my 'CPU feature' series here:
	git://linux-arm.org/linux-skp.git  16k/v3-aarch64-4.3-next+ftr

Changes since V2:
  - Dropped KVM support patches
  - Added proper comments for the page-table helper macros
  - Change ARM64_HW_PGTABLE_LEVEL_SHIFT() to accept page table level as described
    by ARM ARM.
  - Added reviews/acks
  - Added CONT_SHIFT for 16K

Changes since V1:
  - Rebase to 4.3-rc1
  - Fix vmemmap_populate for 16K (use !ARM64_SWAPPER_USES_SECTION_MAPS)
  - Better description for patch2 (suggested-by: Ard)
  - Add page size information to the image header flags.
  - Added reviewed-by/tested-by Ard.

Ard Biesheuvel (1):
  arm64: Add page size to the kernel image header

Suzuki K. Poulose (10):
  arm64: Move swapper pagetable definitions
  arm64: Handle section maps for swapper/idmap
  arm64: Introduce helpers for page table levels
  arm64: Calculate size for idmap_pg_dir at compile time
  arm64: Handle 4 level page table for swapper
  arm64: Clean config usages for page size
  arm64: Kconfig: Fix help text about AArch32 support with 64K pages
  arm64: Check for selected granule support
  arm64: Add 16K page size support
  arm64: 36 bit VA

 Documentation/arm64/booting.txt         |    7 ++-
 arch/arm64/Kconfig                      |   37 +++++++++++----
 arch/arm64/Kconfig.debug                |    2 +-
 arch/arm64/include/asm/fixmap.h         |    4 +-
 arch/arm64/include/asm/kernel-pgtable.h |   77 +++++++++++++++++++++++++++++++
 arch/arm64/include/asm/page.h           |   21 ++-------
 arch/arm64/include/asm/pgtable-hwdef.h  |   25 ++++++++--
 arch/arm64/include/asm/sysreg.h         |   12 +++++
 arch/arm64/include/asm/thread_info.h    |    4 +-
 arch/arm64/kernel/head.S                |   75 +++++++++++++++++-------------
 arch/arm64/kernel/image.h               |    5 +-
 arch/arm64/kernel/vmlinux.lds.S         |    1 +
 arch/arm64/kvm/Kconfig                  |    3 ++
 arch/arm64/mm/mmu.c                     |   72 +++++++++++++----------------
 arch/arm64/mm/proc.S                    |    4 +-
 15 files changed, 242 insertions(+), 107 deletions(-)
 create mode 100644 arch/arm64/include/asm/kernel-pgtable.h

-- 
1.7.9.5

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

* [PATCHv3 01/11] arm64: Move swapper pagetable definitions
  2015-10-14 11:20 ` Suzuki K. Poulose
@ 2015-10-14 11:20   ` Suzuki K. Poulose
  -1 siblings, 0 replies; 110+ messages in thread
From: Suzuki K. Poulose @ 2015-10-14 11:20 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-kernel, catalin.marinas, will.deacon, mark.rutland,
	steve.capper, marc.zyngier, ard.biesheuvel, christoffer.dall,
	Suzuki K. Poulose

Move the kernel pagetable (both swapper and idmap) definitions
from the generic asm/page.h to a new file, asm/kernel-pgtable.h.

This is mostly a cosmetic change, to clean up the asm/page.h to
get rid of the arch specific details which are not needed by the
generic code.

Also renames the symbols to prevent conflicts. e.g,
 	BLOCK_SHIFT => SWAPPER_BLOCK_SHIFT

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Tested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 arch/arm64/include/asm/kernel-pgtable.h |   65 +++++++++++++++++++++++++++++++
 arch/arm64/include/asm/page.h           |   18 ---------
 arch/arm64/kernel/head.S                |   37 ++++--------------
 arch/arm64/kernel/vmlinux.lds.S         |    1 +
 4 files changed, 74 insertions(+), 47 deletions(-)
 create mode 100644 arch/arm64/include/asm/kernel-pgtable.h

diff --git a/arch/arm64/include/asm/kernel-pgtable.h b/arch/arm64/include/asm/kernel-pgtable.h
new file mode 100644
index 0000000..622929d
--- /dev/null
+++ b/arch/arm64/include/asm/kernel-pgtable.h
@@ -0,0 +1,65 @@
+/*
+ * asm/kernel-pgtable.h : Kernel page table mapping
+ *
+ * Copyright (C) 2015 ARM Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __ASM_KERNEL_PGTABLE_H
+#define __ASM_KERNEL_PGTABLE_H
+
+/*
+ * The idmap and swapper page tables need some space reserved in the kernel
+ * image. Both require pgd, pud (4 levels only) and pmd tables to (section)
+ * map the kernel. With the 64K page configuration, swapper and idmap need to
+ * map to pte level. The swapper also maps the FDT (see __create_page_tables
+ * for more information). Note that the number of ID map translation levels
+ * could be increased on the fly if system RAM is out of reach for the default
+ * VA range, so 3 pages are reserved in all cases.
+ */
+#ifdef CONFIG_ARM64_64K_PAGES
+#define SWAPPER_PGTABLE_LEVELS	(CONFIG_PGTABLE_LEVELS)
+#else
+#define SWAPPER_PGTABLE_LEVELS	(CONFIG_PGTABLE_LEVELS - 1)
+#endif
+
+#define SWAPPER_DIR_SIZE	(SWAPPER_PGTABLE_LEVELS * PAGE_SIZE)
+#define IDMAP_DIR_SIZE		(3 * PAGE_SIZE)
+
+/* Initial memory map size */
+#ifdef CONFIG_ARM64_64K_PAGES
+#define SWAPPER_BLOCK_SHIFT	PAGE_SHIFT
+#define SWAPPER_BLOCK_SIZE	PAGE_SIZE
+#define SWAPPER_TABLE_SHIFT	PMD_SHIFT
+#else
+#define SWAPPER_BLOCK_SHIFT	SECTION_SHIFT
+#define SWAPPER_BLOCK_SIZE	SECTION_SIZE
+#define SWAPPER_TABLE_SHIFT	PUD_SHIFT
+#endif
+
+
+/*
+ * Initial memory map attributes.
+ */
+#define SWAPPER_PTE_FLAGS	PTE_TYPE_PAGE | PTE_AF | PTE_SHARED
+#define SWAPPER_PMD_FLAGS	PMD_TYPE_SECT | PMD_SECT_AF | PMD_SECT_S
+
+#ifdef CONFIG_ARM64_64K_PAGES
+#define SWAPPER_MM_MMUFLAGS	PTE_ATTRINDX(MT_NORMAL) | SWAPPER_PTE_FLAGS
+#else
+#define SWAPPER_MM_MMUFLAGS	PMD_ATTRINDX(MT_NORMAL) | SWAPPER_PMD_FLAGS
+#endif
+
+
+#endif
diff --git a/arch/arm64/include/asm/page.h b/arch/arm64/include/asm/page.h
index 33892ef..da32354 100644
--- a/arch/arm64/include/asm/page.h
+++ b/arch/arm64/include/asm/page.h
@@ -34,24 +34,6 @@
 #define CONT_SIZE		(_AC(1, UL) << (CONT_SHIFT + PAGE_SHIFT))
 #define CONT_MASK		(~(CONT_SIZE-1))
 
-/*
- * The idmap and swapper page tables need some space reserved in the kernel
- * image. Both require pgd, pud (4 levels only) and pmd tables to (section)
- * map the kernel. With the 64K page configuration, swapper and idmap need to
- * map to pte level. The swapper also maps the FDT (see __create_page_tables
- * for more information). Note that the number of ID map translation levels
- * could be increased on the fly if system RAM is out of reach for the default
- * VA range, so 3 pages are reserved in all cases.
- */
-#ifdef CONFIG_ARM64_64K_PAGES
-#define SWAPPER_PGTABLE_LEVELS	(CONFIG_PGTABLE_LEVELS)
-#else
-#define SWAPPER_PGTABLE_LEVELS	(CONFIG_PGTABLE_LEVELS - 1)
-#endif
-
-#define SWAPPER_DIR_SIZE	(SWAPPER_PGTABLE_LEVELS * PAGE_SIZE)
-#define IDMAP_DIR_SIZE		(3 * PAGE_SIZE)
-
 #ifndef __ASSEMBLY__
 
 #include <asm/pgtable-types.h>
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index 2a8c1d5..149fce3 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -29,6 +29,7 @@
 #include <asm/asm-offsets.h>
 #include <asm/cache.h>
 #include <asm/cputype.h>
+#include <asm/kernel-pgtable.h>
 #include <asm/memory.h>
 #include <asm/thread_info.h>
 #include <asm/pgtable-hwdef.h>
@@ -46,32 +47,10 @@
 #error TEXT_OFFSET must be less than 2MB
 #endif
 
-#ifdef CONFIG_ARM64_64K_PAGES
-#define BLOCK_SHIFT	PAGE_SHIFT
-#define BLOCK_SIZE	PAGE_SIZE
-#define TABLE_SHIFT	PMD_SHIFT
-#else
-#define BLOCK_SHIFT	SECTION_SHIFT
-#define BLOCK_SIZE	SECTION_SIZE
-#define TABLE_SHIFT	PUD_SHIFT
-#endif
-
 #define KERNEL_START	_text
 #define KERNEL_END	_end
 
 /*
- * Initial memory map attributes.
- */
-#define PTE_FLAGS	PTE_TYPE_PAGE | PTE_AF | PTE_SHARED
-#define PMD_FLAGS	PMD_TYPE_SECT | PMD_SECT_AF | PMD_SECT_S
-
-#ifdef CONFIG_ARM64_64K_PAGES
-#define MM_MMUFLAGS	PTE_ATTRINDX(MT_NORMAL) | PTE_FLAGS
-#else
-#define MM_MMUFLAGS	PMD_ATTRINDX(MT_NORMAL) | PMD_FLAGS
-#endif
-
-/*
  * Kernel startup entry point.
  * ---------------------------
  *
@@ -293,7 +272,7 @@ ENDPROC(preserve_boot_args)
 	.macro	create_pgd_entry, tbl, virt, tmp1, tmp2
 	create_table_entry \tbl, \virt, PGDIR_SHIFT, PTRS_PER_PGD, \tmp1, \tmp2
 #if SWAPPER_PGTABLE_LEVELS == 3
-	create_table_entry \tbl, \virt, TABLE_SHIFT, PTRS_PER_PTE, \tmp1, \tmp2
+	create_table_entry \tbl, \virt, SWAPPER_TABLE_SHIFT, PTRS_PER_PTE, \tmp1, \tmp2
 #endif
 	.endm
 
@@ -305,15 +284,15 @@ ENDPROC(preserve_boot_args)
  * Corrupts:	phys, start, end, pstate
  */
 	.macro	create_block_map, tbl, flags, phys, start, end
-	lsr	\phys, \phys, #BLOCK_SHIFT
-	lsr	\start, \start, #BLOCK_SHIFT
+	lsr	\phys, \phys, #SWAPPER_BLOCK_SHIFT
+	lsr	\start, \start, #SWAPPER_BLOCK_SHIFT
 	and	\start, \start, #PTRS_PER_PTE - 1	// table index
-	orr	\phys, \flags, \phys, lsl #BLOCK_SHIFT	// table entry
-	lsr	\end, \end, #BLOCK_SHIFT
+	orr	\phys, \flags, \phys, lsl #SWAPPER_BLOCK_SHIFT	// table entry
+	lsr	\end, \end, #SWAPPER_BLOCK_SHIFT
 	and	\end, \end, #PTRS_PER_PTE - 1		// table end index
 9999:	str	\phys, [\tbl, \start, lsl #3]		// store the entry
 	add	\start, \start, #1			// next entry
-	add	\phys, \phys, #BLOCK_SIZE		// next block
+	add	\phys, \phys, #SWAPPER_BLOCK_SIZE		// next block
 	cmp	\start, \end
 	b.ls	9999b
 	.endm
@@ -350,7 +329,7 @@ __create_page_tables:
 	cmp	x0, x6
 	b.lo	1b
 
-	ldr	x7, =MM_MMUFLAGS
+	ldr	x7, =SWAPPER_MM_MMUFLAGS
 
 	/*
 	 * Create the identity mapping.
diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S
index 9807333..8a5d97b 100644
--- a/arch/arm64/kernel/vmlinux.lds.S
+++ b/arch/arm64/kernel/vmlinux.lds.S
@@ -5,6 +5,7 @@
  */
 
 #include <asm-generic/vmlinux.lds.h>
+#include <asm/kernel-pgtable.h>
 #include <asm/thread_info.h>
 #include <asm/memory.h>
 #include <asm/page.h>
-- 
1.7.9.5


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

* [PATCHv3 01/11] arm64: Move swapper pagetable definitions
@ 2015-10-14 11:20   ` Suzuki K. Poulose
  0 siblings, 0 replies; 110+ messages in thread
From: Suzuki K. Poulose @ 2015-10-14 11:20 UTC (permalink / raw)
  To: linux-arm-kernel

Move the kernel pagetable (both swapper and idmap) definitions
from the generic asm/page.h to a new file, asm/kernel-pgtable.h.

This is mostly a cosmetic change, to clean up the asm/page.h to
get rid of the arch specific details which are not needed by the
generic code.

Also renames the symbols to prevent conflicts. e.g,
 	BLOCK_SHIFT => SWAPPER_BLOCK_SHIFT

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Tested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 arch/arm64/include/asm/kernel-pgtable.h |   65 +++++++++++++++++++++++++++++++
 arch/arm64/include/asm/page.h           |   18 ---------
 arch/arm64/kernel/head.S                |   37 ++++--------------
 arch/arm64/kernel/vmlinux.lds.S         |    1 +
 4 files changed, 74 insertions(+), 47 deletions(-)
 create mode 100644 arch/arm64/include/asm/kernel-pgtable.h

diff --git a/arch/arm64/include/asm/kernel-pgtable.h b/arch/arm64/include/asm/kernel-pgtable.h
new file mode 100644
index 0000000..622929d
--- /dev/null
+++ b/arch/arm64/include/asm/kernel-pgtable.h
@@ -0,0 +1,65 @@
+/*
+ * asm/kernel-pgtable.h : Kernel page table mapping
+ *
+ * Copyright (C) 2015 ARM Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __ASM_KERNEL_PGTABLE_H
+#define __ASM_KERNEL_PGTABLE_H
+
+/*
+ * The idmap and swapper page tables need some space reserved in the kernel
+ * image. Both require pgd, pud (4 levels only) and pmd tables to (section)
+ * map the kernel. With the 64K page configuration, swapper and idmap need to
+ * map to pte level. The swapper also maps the FDT (see __create_page_tables
+ * for more information). Note that the number of ID map translation levels
+ * could be increased on the fly if system RAM is out of reach for the default
+ * VA range, so 3 pages are reserved in all cases.
+ */
+#ifdef CONFIG_ARM64_64K_PAGES
+#define SWAPPER_PGTABLE_LEVELS	(CONFIG_PGTABLE_LEVELS)
+#else
+#define SWAPPER_PGTABLE_LEVELS	(CONFIG_PGTABLE_LEVELS - 1)
+#endif
+
+#define SWAPPER_DIR_SIZE	(SWAPPER_PGTABLE_LEVELS * PAGE_SIZE)
+#define IDMAP_DIR_SIZE		(3 * PAGE_SIZE)
+
+/* Initial memory map size */
+#ifdef CONFIG_ARM64_64K_PAGES
+#define SWAPPER_BLOCK_SHIFT	PAGE_SHIFT
+#define SWAPPER_BLOCK_SIZE	PAGE_SIZE
+#define SWAPPER_TABLE_SHIFT	PMD_SHIFT
+#else
+#define SWAPPER_BLOCK_SHIFT	SECTION_SHIFT
+#define SWAPPER_BLOCK_SIZE	SECTION_SIZE
+#define SWAPPER_TABLE_SHIFT	PUD_SHIFT
+#endif
+
+
+/*
+ * Initial memory map attributes.
+ */
+#define SWAPPER_PTE_FLAGS	PTE_TYPE_PAGE | PTE_AF | PTE_SHARED
+#define SWAPPER_PMD_FLAGS	PMD_TYPE_SECT | PMD_SECT_AF | PMD_SECT_S
+
+#ifdef CONFIG_ARM64_64K_PAGES
+#define SWAPPER_MM_MMUFLAGS	PTE_ATTRINDX(MT_NORMAL) | SWAPPER_PTE_FLAGS
+#else
+#define SWAPPER_MM_MMUFLAGS	PMD_ATTRINDX(MT_NORMAL) | SWAPPER_PMD_FLAGS
+#endif
+
+
+#endif
diff --git a/arch/arm64/include/asm/page.h b/arch/arm64/include/asm/page.h
index 33892ef..da32354 100644
--- a/arch/arm64/include/asm/page.h
+++ b/arch/arm64/include/asm/page.h
@@ -34,24 +34,6 @@
 #define CONT_SIZE		(_AC(1, UL) << (CONT_SHIFT + PAGE_SHIFT))
 #define CONT_MASK		(~(CONT_SIZE-1))
 
-/*
- * The idmap and swapper page tables need some space reserved in the kernel
- * image. Both require pgd, pud (4 levels only) and pmd tables to (section)
- * map the kernel. With the 64K page configuration, swapper and idmap need to
- * map to pte level. The swapper also maps the FDT (see __create_page_tables
- * for more information). Note that the number of ID map translation levels
- * could be increased on the fly if system RAM is out of reach for the default
- * VA range, so 3 pages are reserved in all cases.
- */
-#ifdef CONFIG_ARM64_64K_PAGES
-#define SWAPPER_PGTABLE_LEVELS	(CONFIG_PGTABLE_LEVELS)
-#else
-#define SWAPPER_PGTABLE_LEVELS	(CONFIG_PGTABLE_LEVELS - 1)
-#endif
-
-#define SWAPPER_DIR_SIZE	(SWAPPER_PGTABLE_LEVELS * PAGE_SIZE)
-#define IDMAP_DIR_SIZE		(3 * PAGE_SIZE)
-
 #ifndef __ASSEMBLY__
 
 #include <asm/pgtable-types.h>
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index 2a8c1d5..149fce3 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -29,6 +29,7 @@
 #include <asm/asm-offsets.h>
 #include <asm/cache.h>
 #include <asm/cputype.h>
+#include <asm/kernel-pgtable.h>
 #include <asm/memory.h>
 #include <asm/thread_info.h>
 #include <asm/pgtable-hwdef.h>
@@ -46,32 +47,10 @@
 #error TEXT_OFFSET must be less than 2MB
 #endif
 
-#ifdef CONFIG_ARM64_64K_PAGES
-#define BLOCK_SHIFT	PAGE_SHIFT
-#define BLOCK_SIZE	PAGE_SIZE
-#define TABLE_SHIFT	PMD_SHIFT
-#else
-#define BLOCK_SHIFT	SECTION_SHIFT
-#define BLOCK_SIZE	SECTION_SIZE
-#define TABLE_SHIFT	PUD_SHIFT
-#endif
-
 #define KERNEL_START	_text
 #define KERNEL_END	_end
 
 /*
- * Initial memory map attributes.
- */
-#define PTE_FLAGS	PTE_TYPE_PAGE | PTE_AF | PTE_SHARED
-#define PMD_FLAGS	PMD_TYPE_SECT | PMD_SECT_AF | PMD_SECT_S
-
-#ifdef CONFIG_ARM64_64K_PAGES
-#define MM_MMUFLAGS	PTE_ATTRINDX(MT_NORMAL) | PTE_FLAGS
-#else
-#define MM_MMUFLAGS	PMD_ATTRINDX(MT_NORMAL) | PMD_FLAGS
-#endif
-
-/*
  * Kernel startup entry point.
  * ---------------------------
  *
@@ -293,7 +272,7 @@ ENDPROC(preserve_boot_args)
 	.macro	create_pgd_entry, tbl, virt, tmp1, tmp2
 	create_table_entry \tbl, \virt, PGDIR_SHIFT, PTRS_PER_PGD, \tmp1, \tmp2
 #if SWAPPER_PGTABLE_LEVELS == 3
-	create_table_entry \tbl, \virt, TABLE_SHIFT, PTRS_PER_PTE, \tmp1, \tmp2
+	create_table_entry \tbl, \virt, SWAPPER_TABLE_SHIFT, PTRS_PER_PTE, \tmp1, \tmp2
 #endif
 	.endm
 
@@ -305,15 +284,15 @@ ENDPROC(preserve_boot_args)
  * Corrupts:	phys, start, end, pstate
  */
 	.macro	create_block_map, tbl, flags, phys, start, end
-	lsr	\phys, \phys, #BLOCK_SHIFT
-	lsr	\start, \start, #BLOCK_SHIFT
+	lsr	\phys, \phys, #SWAPPER_BLOCK_SHIFT
+	lsr	\start, \start, #SWAPPER_BLOCK_SHIFT
 	and	\start, \start, #PTRS_PER_PTE - 1	// table index
-	orr	\phys, \flags, \phys, lsl #BLOCK_SHIFT	// table entry
-	lsr	\end, \end, #BLOCK_SHIFT
+	orr	\phys, \flags, \phys, lsl #SWAPPER_BLOCK_SHIFT	// table entry
+	lsr	\end, \end, #SWAPPER_BLOCK_SHIFT
 	and	\end, \end, #PTRS_PER_PTE - 1		// table end index
 9999:	str	\phys, [\tbl, \start, lsl #3]		// store the entry
 	add	\start, \start, #1			// next entry
-	add	\phys, \phys, #BLOCK_SIZE		// next block
+	add	\phys, \phys, #SWAPPER_BLOCK_SIZE		// next block
 	cmp	\start, \end
 	b.ls	9999b
 	.endm
@@ -350,7 +329,7 @@ __create_page_tables:
 	cmp	x0, x6
 	b.lo	1b
 
-	ldr	x7, =MM_MMUFLAGS
+	ldr	x7, =SWAPPER_MM_MMUFLAGS
 
 	/*
 	 * Create the identity mapping.
diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S
index 9807333..8a5d97b 100644
--- a/arch/arm64/kernel/vmlinux.lds.S
+++ b/arch/arm64/kernel/vmlinux.lds.S
@@ -5,6 +5,7 @@
  */
 
 #include <asm-generic/vmlinux.lds.h>
+#include <asm/kernel-pgtable.h>
 #include <asm/thread_info.h>
 #include <asm/memory.h>
 #include <asm/page.h>
-- 
1.7.9.5

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

* [PATCHv3 02/11] arm64: Handle section maps for swapper/idmap
  2015-10-14 11:20 ` Suzuki K. Poulose
@ 2015-10-14 11:20   ` Suzuki K. Poulose
  -1 siblings, 0 replies; 110+ messages in thread
From: Suzuki K. Poulose @ 2015-10-14 11:20 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-kernel, catalin.marinas, will.deacon, mark.rutland,
	steve.capper, marc.zyngier, ard.biesheuvel, christoffer.dall,
	Suzuki K. Poulose

We use section maps with 4K page size to create the swapper/idmaps.
So far we have used !64K or 4K checks to handle the case where we
use the section maps.
This patch adds a new symbol, ARM64_SWAPPER_USES_SECTION_MAPS, to
handle cases where we use section maps, instead of using the page size
symbols.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com>
---
 arch/arm64/include/asm/kernel-pgtable.h |   31 ++++++++-----
 arch/arm64/mm/mmu.c                     |   72 ++++++++++++++-----------------
 2 files changed, 52 insertions(+), 51 deletions(-)

diff --git a/arch/arm64/include/asm/kernel-pgtable.h b/arch/arm64/include/asm/kernel-pgtable.h
index 622929d..5876a36 100644
--- a/arch/arm64/include/asm/kernel-pgtable.h
+++ b/arch/arm64/include/asm/kernel-pgtable.h
@@ -19,6 +19,13 @@
 #ifndef __ASM_KERNEL_PGTABLE_H
 #define __ASM_KERNEL_PGTABLE_H
 
+/* With 4K pages, we use section maps. */
+#ifdef CONFIG_ARM64_4K_PAGES
+#define ARM64_SWAPPER_USES_SECTION_MAPS 1
+#else
+#define ARM64_SWAPPER_USES_SECTION_MAPS 0
+#endif
+
 /*
  * The idmap and swapper page tables need some space reserved in the kernel
  * image. Both require pgd, pud (4 levels only) and pmd tables to (section)
@@ -28,26 +35,28 @@
  * could be increased on the fly if system RAM is out of reach for the default
  * VA range, so 3 pages are reserved in all cases.
  */
-#ifdef CONFIG_ARM64_64K_PAGES
-#define SWAPPER_PGTABLE_LEVELS	(CONFIG_PGTABLE_LEVELS)
-#else
+#if ARM64_SWAPPER_USES_SECTION_MAPS
 #define SWAPPER_PGTABLE_LEVELS	(CONFIG_PGTABLE_LEVELS - 1)
+#else
+#define SWAPPER_PGTABLE_LEVELS	(CONFIG_PGTABLE_LEVELS)
 #endif
 
 #define SWAPPER_DIR_SIZE	(SWAPPER_PGTABLE_LEVELS * PAGE_SIZE)
 #define IDMAP_DIR_SIZE		(3 * PAGE_SIZE)
 
 /* Initial memory map size */
-#ifdef CONFIG_ARM64_64K_PAGES
-#define SWAPPER_BLOCK_SHIFT	PAGE_SHIFT
-#define SWAPPER_BLOCK_SIZE	PAGE_SIZE
-#define SWAPPER_TABLE_SHIFT	PMD_SHIFT
-#else
+#if ARM64_SWAPPER_USES_SECTION_MAPS
 #define SWAPPER_BLOCK_SHIFT	SECTION_SHIFT
 #define SWAPPER_BLOCK_SIZE	SECTION_SIZE
 #define SWAPPER_TABLE_SHIFT	PUD_SHIFT
+#else
+#define SWAPPER_BLOCK_SHIFT	PAGE_SHIFT
+#define SWAPPER_BLOCK_SIZE	PAGE_SIZE
+#define SWAPPER_TABLE_SHIFT	PMD_SHIFT
 #endif
 
+/* The size of the initial kernel direct mapping */
+#define SWAPPER_INIT_MAP_SIZE	(_AC(1, UL) << SWAPPER_TABLE_SHIFT)
 
 /*
  * Initial memory map attributes.
@@ -55,10 +64,10 @@
 #define SWAPPER_PTE_FLAGS	PTE_TYPE_PAGE | PTE_AF | PTE_SHARED
 #define SWAPPER_PMD_FLAGS	PMD_TYPE_SECT | PMD_SECT_AF | PMD_SECT_S
 
-#ifdef CONFIG_ARM64_64K_PAGES
-#define SWAPPER_MM_MMUFLAGS	PTE_ATTRINDX(MT_NORMAL) | SWAPPER_PTE_FLAGS
-#else
+#if ARM64_SWAPPER_USES_SECTION_MAPS
 #define SWAPPER_MM_MMUFLAGS	PMD_ATTRINDX(MT_NORMAL) | SWAPPER_PMD_FLAGS
+#else
+#define SWAPPER_MM_MMUFLAGS	PTE_ATTRINDX(MT_NORMAL) | SWAPPER_PTE_FLAGS
 #endif
 
 
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index eed6d52..bc4373a 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -32,6 +32,7 @@
 
 #include <asm/cputype.h>
 #include <asm/fixmap.h>
+#include <asm/kernel-pgtable.h>
 #include <asm/sections.h>
 #include <asm/setup.h>
 #include <asm/sizes.h>
@@ -406,14 +407,11 @@ static void __init map_mem(void)
 	 * memory addressable from the initial direct kernel mapping.
 	 *
 	 * The initial direct kernel mapping, located at swapper_pg_dir, gives
-	 * us PUD_SIZE (4K pages) or PMD_SIZE (64K pages) memory starting from
-	 * PHYS_OFFSET (which must be aligned to 2MB as per
-	 * Documentation/arm64/booting.txt).
+	 * us PUD_SIZE (with SECTION maps, i.e, 4K) or PMD_SIZE (without
+	 * SECTION maps, i.e, 64K pages) memory starting from PHYS_OFFSET
+	 * (which must be aligned to 2MB as per Documentation/arm64/booting.txt).
 	 */
-	if (IS_ENABLED(CONFIG_ARM64_64K_PAGES))
-		limit = PHYS_OFFSET + PMD_SIZE;
-	else
-		limit = PHYS_OFFSET + PUD_SIZE;
+	limit = PHYS_OFFSET + SWAPPER_INIT_MAP_SIZE;
 	memblock_set_current_limit(limit);
 
 	/* map all the memory banks */
@@ -424,21 +422,24 @@ static void __init map_mem(void)
 		if (start >= end)
 			break;
 
-#ifndef CONFIG_ARM64_64K_PAGES
-		/*
-		 * For the first memory bank align the start address and
-		 * current memblock limit to prevent create_mapping() from
-		 * allocating pte page tables from unmapped memory.
-		 * When 64K pages are enabled, the pte page table for the
-		 * first PGDIR_SIZE is already present in swapper_pg_dir.
-		 */
-		if (start < limit)
-			start = ALIGN(start, PMD_SIZE);
-		if (end < limit) {
-			limit = end & PMD_MASK;
-			memblock_set_current_limit(limit);
+		if (ARM64_SWAPPER_USES_SECTION_MAPS) {
+			/*
+			 * For the first memory bank align the start address and
+			 * current memblock limit to prevent create_mapping() from
+			 * allocating pte page tables from unmapped memory. With
+			 * the section maps, if the first block doesn't end on section
+			 * size boundary, create_mapping() will try to allocate a pte
+			 * page, which may be returned from an unmapped area.
+			 * When section maps are not used, the pte page table for the
+			 * current limit is already present in swapper_pg_dir.
+			 */
+			if (start < limit)
+				start = ALIGN(start, SECTION_SIZE);
+			if (end < limit) {
+				limit = end & SECTION_MASK;
+				memblock_set_current_limit(limit);
+			}
 		}
-#endif
 		__map_memblock(start, end);
 	}
 
@@ -551,7 +552,7 @@ int kern_addr_valid(unsigned long addr)
 	return pfn_valid(pte_pfn(*pte));
 }
 #ifdef CONFIG_SPARSEMEM_VMEMMAP
-#ifdef CONFIG_ARM64_64K_PAGES
+#if !ARM64_SWAPPER_USES_SECTION_MAPS
 int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node)
 {
 	return vmemmap_populate_basepages(start, end, node);
@@ -691,7 +692,7 @@ void *__init fixmap_remap_fdt(phys_addr_t dt_phys)
 {
 	const u64 dt_virt_base = __fix_to_virt(FIX_FDT);
 	pgprot_t prot = PAGE_KERNEL | PTE_RDONLY;
-	int granularity, size, offset;
+	int size, offset;
 	void *dt_virt;
 
 	/*
@@ -717,24 +718,15 @@ void *__init fixmap_remap_fdt(phys_addr_t dt_phys)
 	 */
 	BUILD_BUG_ON(dt_virt_base % SZ_2M);
 
-	if (IS_ENABLED(CONFIG_ARM64_64K_PAGES)) {
-		BUILD_BUG_ON(__fix_to_virt(FIX_FDT_END) >> PMD_SHIFT !=
-			     __fix_to_virt(FIX_BTMAP_BEGIN) >> PMD_SHIFT);
-
-		granularity = PAGE_SIZE;
-	} else {
-		BUILD_BUG_ON(__fix_to_virt(FIX_FDT_END) >> PUD_SHIFT !=
-			     __fix_to_virt(FIX_BTMAP_BEGIN) >> PUD_SHIFT);
-
-		granularity = PMD_SIZE;
-	}
+	BUILD_BUG_ON(__fix_to_virt(FIX_FDT_END) >> SWAPPER_TABLE_SHIFT !=
+		     __fix_to_virt(FIX_BTMAP_BEGIN) >> SWAPPER_TABLE_SHIFT);
 
-	offset = dt_phys % granularity;
+	offset = dt_phys % SWAPPER_BLOCK_SIZE;
 	dt_virt = (void *)dt_virt_base + offset;
 
 	/* map the first chunk so we can read the size from the header */
-	create_mapping(round_down(dt_phys, granularity), dt_virt_base,
-		       granularity, prot);
+	create_mapping(round_down(dt_phys, SWAPPER_BLOCK_SIZE), dt_virt_base,
+		       SWAPPER_BLOCK_SIZE, prot);
 
 	if (fdt_check_header(dt_virt) != 0)
 		return NULL;
@@ -743,9 +735,9 @@ void *__init fixmap_remap_fdt(phys_addr_t dt_phys)
 	if (size > MAX_FDT_SIZE)
 		return NULL;
 
-	if (offset + size > granularity)
-		create_mapping(round_down(dt_phys, granularity), dt_virt_base,
-			       round_up(offset + size, granularity), prot);
+	if (offset + size > SWAPPER_BLOCK_SIZE)
+		create_mapping(round_down(dt_phys, SWAPPER_BLOCK_SIZE), dt_virt_base,
+			       round_up(offset + size, SWAPPER_BLOCK_SIZE), prot);
 
 	memblock_reserve(dt_phys, size);
 
-- 
1.7.9.5


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

* [PATCHv3 02/11] arm64: Handle section maps for swapper/idmap
@ 2015-10-14 11:20   ` Suzuki K. Poulose
  0 siblings, 0 replies; 110+ messages in thread
From: Suzuki K. Poulose @ 2015-10-14 11:20 UTC (permalink / raw)
  To: linux-arm-kernel

We use section maps with 4K page size to create the swapper/idmaps.
So far we have used !64K or 4K checks to handle the case where we
use the section maps.
This patch adds a new symbol, ARM64_SWAPPER_USES_SECTION_MAPS, to
handle cases where we use section maps, instead of using the page size
symbols.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com>
---
 arch/arm64/include/asm/kernel-pgtable.h |   31 ++++++++-----
 arch/arm64/mm/mmu.c                     |   72 ++++++++++++++-----------------
 2 files changed, 52 insertions(+), 51 deletions(-)

diff --git a/arch/arm64/include/asm/kernel-pgtable.h b/arch/arm64/include/asm/kernel-pgtable.h
index 622929d..5876a36 100644
--- a/arch/arm64/include/asm/kernel-pgtable.h
+++ b/arch/arm64/include/asm/kernel-pgtable.h
@@ -19,6 +19,13 @@
 #ifndef __ASM_KERNEL_PGTABLE_H
 #define __ASM_KERNEL_PGTABLE_H
 
+/* With 4K pages, we use section maps. */
+#ifdef CONFIG_ARM64_4K_PAGES
+#define ARM64_SWAPPER_USES_SECTION_MAPS 1
+#else
+#define ARM64_SWAPPER_USES_SECTION_MAPS 0
+#endif
+
 /*
  * The idmap and swapper page tables need some space reserved in the kernel
  * image. Both require pgd, pud (4 levels only) and pmd tables to (section)
@@ -28,26 +35,28 @@
  * could be increased on the fly if system RAM is out of reach for the default
  * VA range, so 3 pages are reserved in all cases.
  */
-#ifdef CONFIG_ARM64_64K_PAGES
-#define SWAPPER_PGTABLE_LEVELS	(CONFIG_PGTABLE_LEVELS)
-#else
+#if ARM64_SWAPPER_USES_SECTION_MAPS
 #define SWAPPER_PGTABLE_LEVELS	(CONFIG_PGTABLE_LEVELS - 1)
+#else
+#define SWAPPER_PGTABLE_LEVELS	(CONFIG_PGTABLE_LEVELS)
 #endif
 
 #define SWAPPER_DIR_SIZE	(SWAPPER_PGTABLE_LEVELS * PAGE_SIZE)
 #define IDMAP_DIR_SIZE		(3 * PAGE_SIZE)
 
 /* Initial memory map size */
-#ifdef CONFIG_ARM64_64K_PAGES
-#define SWAPPER_BLOCK_SHIFT	PAGE_SHIFT
-#define SWAPPER_BLOCK_SIZE	PAGE_SIZE
-#define SWAPPER_TABLE_SHIFT	PMD_SHIFT
-#else
+#if ARM64_SWAPPER_USES_SECTION_MAPS
 #define SWAPPER_BLOCK_SHIFT	SECTION_SHIFT
 #define SWAPPER_BLOCK_SIZE	SECTION_SIZE
 #define SWAPPER_TABLE_SHIFT	PUD_SHIFT
+#else
+#define SWAPPER_BLOCK_SHIFT	PAGE_SHIFT
+#define SWAPPER_BLOCK_SIZE	PAGE_SIZE
+#define SWAPPER_TABLE_SHIFT	PMD_SHIFT
 #endif
 
+/* The size of the initial kernel direct mapping */
+#define SWAPPER_INIT_MAP_SIZE	(_AC(1, UL) << SWAPPER_TABLE_SHIFT)
 
 /*
  * Initial memory map attributes.
@@ -55,10 +64,10 @@
 #define SWAPPER_PTE_FLAGS	PTE_TYPE_PAGE | PTE_AF | PTE_SHARED
 #define SWAPPER_PMD_FLAGS	PMD_TYPE_SECT | PMD_SECT_AF | PMD_SECT_S
 
-#ifdef CONFIG_ARM64_64K_PAGES
-#define SWAPPER_MM_MMUFLAGS	PTE_ATTRINDX(MT_NORMAL) | SWAPPER_PTE_FLAGS
-#else
+#if ARM64_SWAPPER_USES_SECTION_MAPS
 #define SWAPPER_MM_MMUFLAGS	PMD_ATTRINDX(MT_NORMAL) | SWAPPER_PMD_FLAGS
+#else
+#define SWAPPER_MM_MMUFLAGS	PTE_ATTRINDX(MT_NORMAL) | SWAPPER_PTE_FLAGS
 #endif
 
 
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index eed6d52..bc4373a 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -32,6 +32,7 @@
 
 #include <asm/cputype.h>
 #include <asm/fixmap.h>
+#include <asm/kernel-pgtable.h>
 #include <asm/sections.h>
 #include <asm/setup.h>
 #include <asm/sizes.h>
@@ -406,14 +407,11 @@ static void __init map_mem(void)
 	 * memory addressable from the initial direct kernel mapping.
 	 *
 	 * The initial direct kernel mapping, located at swapper_pg_dir, gives
-	 * us PUD_SIZE (4K pages) or PMD_SIZE (64K pages) memory starting from
-	 * PHYS_OFFSET (which must be aligned to 2MB as per
-	 * Documentation/arm64/booting.txt).
+	 * us PUD_SIZE (with SECTION maps, i.e, 4K) or PMD_SIZE (without
+	 * SECTION maps, i.e, 64K pages) memory starting from PHYS_OFFSET
+	 * (which must be aligned to 2MB as per Documentation/arm64/booting.txt).
 	 */
-	if (IS_ENABLED(CONFIG_ARM64_64K_PAGES))
-		limit = PHYS_OFFSET + PMD_SIZE;
-	else
-		limit = PHYS_OFFSET + PUD_SIZE;
+	limit = PHYS_OFFSET + SWAPPER_INIT_MAP_SIZE;
 	memblock_set_current_limit(limit);
 
 	/* map all the memory banks */
@@ -424,21 +422,24 @@ static void __init map_mem(void)
 		if (start >= end)
 			break;
 
-#ifndef CONFIG_ARM64_64K_PAGES
-		/*
-		 * For the first memory bank align the start address and
-		 * current memblock limit to prevent create_mapping() from
-		 * allocating pte page tables from unmapped memory.
-		 * When 64K pages are enabled, the pte page table for the
-		 * first PGDIR_SIZE is already present in swapper_pg_dir.
-		 */
-		if (start < limit)
-			start = ALIGN(start, PMD_SIZE);
-		if (end < limit) {
-			limit = end & PMD_MASK;
-			memblock_set_current_limit(limit);
+		if (ARM64_SWAPPER_USES_SECTION_MAPS) {
+			/*
+			 * For the first memory bank align the start address and
+			 * current memblock limit to prevent create_mapping() from
+			 * allocating pte page tables from unmapped memory. With
+			 * the section maps, if the first block doesn't end on section
+			 * size boundary, create_mapping() will try to allocate a pte
+			 * page, which may be returned from an unmapped area.
+			 * When section maps are not used, the pte page table for the
+			 * current limit is already present in swapper_pg_dir.
+			 */
+			if (start < limit)
+				start = ALIGN(start, SECTION_SIZE);
+			if (end < limit) {
+				limit = end & SECTION_MASK;
+				memblock_set_current_limit(limit);
+			}
 		}
-#endif
 		__map_memblock(start, end);
 	}
 
@@ -551,7 +552,7 @@ int kern_addr_valid(unsigned long addr)
 	return pfn_valid(pte_pfn(*pte));
 }
 #ifdef CONFIG_SPARSEMEM_VMEMMAP
-#ifdef CONFIG_ARM64_64K_PAGES
+#if !ARM64_SWAPPER_USES_SECTION_MAPS
 int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node)
 {
 	return vmemmap_populate_basepages(start, end, node);
@@ -691,7 +692,7 @@ void *__init fixmap_remap_fdt(phys_addr_t dt_phys)
 {
 	const u64 dt_virt_base = __fix_to_virt(FIX_FDT);
 	pgprot_t prot = PAGE_KERNEL | PTE_RDONLY;
-	int granularity, size, offset;
+	int size, offset;
 	void *dt_virt;
 
 	/*
@@ -717,24 +718,15 @@ void *__init fixmap_remap_fdt(phys_addr_t dt_phys)
 	 */
 	BUILD_BUG_ON(dt_virt_base % SZ_2M);
 
-	if (IS_ENABLED(CONFIG_ARM64_64K_PAGES)) {
-		BUILD_BUG_ON(__fix_to_virt(FIX_FDT_END) >> PMD_SHIFT !=
-			     __fix_to_virt(FIX_BTMAP_BEGIN) >> PMD_SHIFT);
-
-		granularity = PAGE_SIZE;
-	} else {
-		BUILD_BUG_ON(__fix_to_virt(FIX_FDT_END) >> PUD_SHIFT !=
-			     __fix_to_virt(FIX_BTMAP_BEGIN) >> PUD_SHIFT);
-
-		granularity = PMD_SIZE;
-	}
+	BUILD_BUG_ON(__fix_to_virt(FIX_FDT_END) >> SWAPPER_TABLE_SHIFT !=
+		     __fix_to_virt(FIX_BTMAP_BEGIN) >> SWAPPER_TABLE_SHIFT);
 
-	offset = dt_phys % granularity;
+	offset = dt_phys % SWAPPER_BLOCK_SIZE;
 	dt_virt = (void *)dt_virt_base + offset;
 
 	/* map the first chunk so we can read the size from the header */
-	create_mapping(round_down(dt_phys, granularity), dt_virt_base,
-		       granularity, prot);
+	create_mapping(round_down(dt_phys, SWAPPER_BLOCK_SIZE), dt_virt_base,
+		       SWAPPER_BLOCK_SIZE, prot);
 
 	if (fdt_check_header(dt_virt) != 0)
 		return NULL;
@@ -743,9 +735,9 @@ void *__init fixmap_remap_fdt(phys_addr_t dt_phys)
 	if (size > MAX_FDT_SIZE)
 		return NULL;
 
-	if (offset + size > granularity)
-		create_mapping(round_down(dt_phys, granularity), dt_virt_base,
-			       round_up(offset + size, granularity), prot);
+	if (offset + size > SWAPPER_BLOCK_SIZE)
+		create_mapping(round_down(dt_phys, SWAPPER_BLOCK_SIZE), dt_virt_base,
+			       round_up(offset + size, SWAPPER_BLOCK_SIZE), prot);
 
 	memblock_reserve(dt_phys, size);
 
-- 
1.7.9.5

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

* [PATCHv3 03/11] arm64: Introduce helpers for page table levels
  2015-10-14 11:20 ` Suzuki K. Poulose
@ 2015-10-14 11:20   ` Suzuki K. Poulose
  -1 siblings, 0 replies; 110+ messages in thread
From: Suzuki K. Poulose @ 2015-10-14 11:20 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-kernel, catalin.marinas, will.deacon, mark.rutland,
	steve.capper, marc.zyngier, ard.biesheuvel, christoffer.dall,
	Suzuki K. Poulose

Introduce helpers for finding the number of page table
levels required for a given VA width, shift for a particular
page table level.

Convert the existing users to the new helpers. More users
to follow.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com>

---
Changes since V2:
  - Add comments around the macros
  - Change ARM64_HW_PGTABLE_LEVEL_SHIFT to accept pagetable level as
    described by ARM ARM
---
 arch/arm64/include/asm/pgtable-hwdef.h |   25 ++++++++++++++++++++++---
 1 file changed, 22 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/include/asm/pgtable-hwdef.h b/arch/arm64/include/asm/pgtable-hwdef.h
index 95c1ec0..c6194ab 100644
--- a/arch/arm64/include/asm/pgtable-hwdef.h
+++ b/arch/arm64/include/asm/pgtable-hwdef.h
@@ -16,13 +16,31 @@
 #ifndef __ASM_PGTABLE_HWDEF_H
 #define __ASM_PGTABLE_HWDEF_H
 
+/*
+ * Number of page-table levels required to address 'va_bits' wide
+ * address, without section mapping. We resolve the top (va_bits - PAGE_SHIFT)
+ * bits with (PAGE_SHIFT - 3) bits at each page table level. Hence:
+ *
+ *  levels = DIV_ROUND_UP((va_bits - PAGE_SHIFT), (PAGE_SHIFT - 3))
+ *
+ * We cannot include linux/kernel.h which defines DIV_ROUND_UP here
+ * due to build issues. So we use the following magic formula.
+ */
+#define ARM64_HW_PGTABLE_LEVELS(va_bits) (((va_bits) - 4) / (PAGE_SHIFT - 3))
+
+/*
+ * Size mapped by an entry at level n
+ * We map PAGE_SHIFT - 3 at all levels, except the PAGE_SHIFT bits at the last level
+ */
+#define ARM64_HW_PGTABLE_LEVEL_SHIFT(n)	((PAGE_SHIFT - 3) * (4 - (n)) + 3)
+
 #define PTRS_PER_PTE		(1 << (PAGE_SHIFT - 3))
 
 /*
  * PMD_SHIFT determines the size a level 2 page table entry can map.
  */
 #if CONFIG_PGTABLE_LEVELS > 2
-#define PMD_SHIFT		((PAGE_SHIFT - 3) * 2 + 3)
+#define PMD_SHIFT		ARM64_HW_PGTABLE_LEVEL_SHIFT(2)
 #define PMD_SIZE		(_AC(1, UL) << PMD_SHIFT)
 #define PMD_MASK		(~(PMD_SIZE-1))
 #define PTRS_PER_PMD		PTRS_PER_PTE
@@ -32,7 +50,7 @@
  * PUD_SHIFT determines the size a level 1 page table entry can map.
  */
 #if CONFIG_PGTABLE_LEVELS > 3
-#define PUD_SHIFT		((PAGE_SHIFT - 3) * 3 + 3)
+#define PUD_SHIFT		ARM64_HW_PGTABLE_LEVEL_SHIFT(1)
 #define PUD_SIZE		(_AC(1, UL) << PUD_SHIFT)
 #define PUD_MASK		(~(PUD_SIZE-1))
 #define PTRS_PER_PUD		PTRS_PER_PTE
@@ -42,7 +60,8 @@
  * PGDIR_SHIFT determines the size a top-level page table entry can map
  * (depending on the configuration, this level can be 0, 1 or 2).
  */
-#define PGDIR_SHIFT		((PAGE_SHIFT - 3) * CONFIG_PGTABLE_LEVELS + 3)
+#define PGDIR_SHIFT	\
+		ARM64_HW_PGTABLE_LEVEL_SHIFT(4 - CONFIG_PGTABLE_LEVELS)
 #define PGDIR_SIZE		(_AC(1, UL) << PGDIR_SHIFT)
 #define PGDIR_MASK		(~(PGDIR_SIZE-1))
 #define PTRS_PER_PGD		(1 << (VA_BITS - PGDIR_SHIFT))
-- 
1.7.9.5


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

* [PATCHv3 03/11] arm64: Introduce helpers for page table levels
@ 2015-10-14 11:20   ` Suzuki K. Poulose
  0 siblings, 0 replies; 110+ messages in thread
From: Suzuki K. Poulose @ 2015-10-14 11:20 UTC (permalink / raw)
  To: linux-arm-kernel

Introduce helpers for finding the number of page table
levels required for a given VA width, shift for a particular
page table level.

Convert the existing users to the new helpers. More users
to follow.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com>

---
Changes since V2:
  - Add comments around the macros
  - Change ARM64_HW_PGTABLE_LEVEL_SHIFT to accept pagetable level as
    described by ARM ARM
---
 arch/arm64/include/asm/pgtable-hwdef.h |   25 ++++++++++++++++++++++---
 1 file changed, 22 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/include/asm/pgtable-hwdef.h b/arch/arm64/include/asm/pgtable-hwdef.h
index 95c1ec0..c6194ab 100644
--- a/arch/arm64/include/asm/pgtable-hwdef.h
+++ b/arch/arm64/include/asm/pgtable-hwdef.h
@@ -16,13 +16,31 @@
 #ifndef __ASM_PGTABLE_HWDEF_H
 #define __ASM_PGTABLE_HWDEF_H
 
+/*
+ * Number of page-table levels required to address 'va_bits' wide
+ * address, without section mapping. We resolve the top (va_bits - PAGE_SHIFT)
+ * bits with (PAGE_SHIFT - 3) bits at each page table level. Hence:
+ *
+ *  levels = DIV_ROUND_UP((va_bits - PAGE_SHIFT), (PAGE_SHIFT - 3))
+ *
+ * We cannot include linux/kernel.h which defines DIV_ROUND_UP here
+ * due to build issues. So we use the following magic formula.
+ */
+#define ARM64_HW_PGTABLE_LEVELS(va_bits) (((va_bits) - 4) / (PAGE_SHIFT - 3))
+
+/*
+ * Size mapped by an entry at level n
+ * We map PAGE_SHIFT - 3 at all levels, except the PAGE_SHIFT bits at the last level
+ */
+#define ARM64_HW_PGTABLE_LEVEL_SHIFT(n)	((PAGE_SHIFT - 3) * (4 - (n)) + 3)
+
 #define PTRS_PER_PTE		(1 << (PAGE_SHIFT - 3))
 
 /*
  * PMD_SHIFT determines the size a level 2 page table entry can map.
  */
 #if CONFIG_PGTABLE_LEVELS > 2
-#define PMD_SHIFT		((PAGE_SHIFT - 3) * 2 + 3)
+#define PMD_SHIFT		ARM64_HW_PGTABLE_LEVEL_SHIFT(2)
 #define PMD_SIZE		(_AC(1, UL) << PMD_SHIFT)
 #define PMD_MASK		(~(PMD_SIZE-1))
 #define PTRS_PER_PMD		PTRS_PER_PTE
@@ -32,7 +50,7 @@
  * PUD_SHIFT determines the size a level 1 page table entry can map.
  */
 #if CONFIG_PGTABLE_LEVELS > 3
-#define PUD_SHIFT		((PAGE_SHIFT - 3) * 3 + 3)
+#define PUD_SHIFT		ARM64_HW_PGTABLE_LEVEL_SHIFT(1)
 #define PUD_SIZE		(_AC(1, UL) << PUD_SHIFT)
 #define PUD_MASK		(~(PUD_SIZE-1))
 #define PTRS_PER_PUD		PTRS_PER_PTE
@@ -42,7 +60,8 @@
  * PGDIR_SHIFT determines the size a top-level page table entry can map
  * (depending on the configuration, this level can be 0, 1 or 2).
  */
-#define PGDIR_SHIFT		((PAGE_SHIFT - 3) * CONFIG_PGTABLE_LEVELS + 3)
+#define PGDIR_SHIFT	\
+		ARM64_HW_PGTABLE_LEVEL_SHIFT(4 - CONFIG_PGTABLE_LEVELS)
 #define PGDIR_SIZE		(_AC(1, UL) << PGDIR_SHIFT)
 #define PGDIR_MASK		(~(PGDIR_SIZE-1))
 #define PTRS_PER_PGD		(1 << (VA_BITS - PGDIR_SHIFT))
-- 
1.7.9.5

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

* [PATCHv3 04/11] arm64: Calculate size for idmap_pg_dir at compile time
  2015-10-14 11:20 ` Suzuki K. Poulose
@ 2015-10-14 11:20   ` Suzuki K. Poulose
  -1 siblings, 0 replies; 110+ messages in thread
From: Suzuki K. Poulose @ 2015-10-14 11:20 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-kernel, catalin.marinas, will.deacon, mark.rutland,
	steve.capper, marc.zyngier, ard.biesheuvel, christoffer.dall,
	Suzuki K. Poulose

Now that we can calculate the number of levels required for
mapping a va width, reserve exact number of pages that would
be required to cover the idmap. The idmap should be able to handle
the maximum physical address size supported.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Tested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 arch/arm64/include/asm/kernel-pgtable.h |    7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/kernel-pgtable.h b/arch/arm64/include/asm/kernel-pgtable.h
index 5876a36..def7168 100644
--- a/arch/arm64/include/asm/kernel-pgtable.h
+++ b/arch/arm64/include/asm/kernel-pgtable.h
@@ -33,16 +33,19 @@
  * map to pte level. The swapper also maps the FDT (see __create_page_tables
  * for more information). Note that the number of ID map translation levels
  * could be increased on the fly if system RAM is out of reach for the default
- * VA range, so 3 pages are reserved in all cases.
+ * VA range, so pages required to map highest possible PA are reserved in all
+ * cases.
  */
 #if ARM64_SWAPPER_USES_SECTION_MAPS
 #define SWAPPER_PGTABLE_LEVELS	(CONFIG_PGTABLE_LEVELS - 1)
+#define IDMAP_PGTABLE_LEVELS	(ARM64_HW_PGTABLE_LEVELS(PHYS_MASK_SHIFT) - 1)
 #else
 #define SWAPPER_PGTABLE_LEVELS	(CONFIG_PGTABLE_LEVELS)
+#define IDMAP_PGTABLE_LEVELS	(ARM64_HW_PGTABLE_LEVELS(PHYS_MASK_SHIFT))
 #endif
 
 #define SWAPPER_DIR_SIZE	(SWAPPER_PGTABLE_LEVELS * PAGE_SIZE)
-#define IDMAP_DIR_SIZE		(3 * PAGE_SIZE)
+#define IDMAP_DIR_SIZE		(IDMAP_PGTABLE_LEVELS * PAGE_SIZE)
 
 /* Initial memory map size */
 #if ARM64_SWAPPER_USES_SECTION_MAPS
-- 
1.7.9.5


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

* [PATCHv3 04/11] arm64: Calculate size for idmap_pg_dir at compile time
@ 2015-10-14 11:20   ` Suzuki K. Poulose
  0 siblings, 0 replies; 110+ messages in thread
From: Suzuki K. Poulose @ 2015-10-14 11:20 UTC (permalink / raw)
  To: linux-arm-kernel

Now that we can calculate the number of levels required for
mapping a va width, reserve exact number of pages that would
be required to cover the idmap. The idmap should be able to handle
the maximum physical address size supported.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Tested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 arch/arm64/include/asm/kernel-pgtable.h |    7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/kernel-pgtable.h b/arch/arm64/include/asm/kernel-pgtable.h
index 5876a36..def7168 100644
--- a/arch/arm64/include/asm/kernel-pgtable.h
+++ b/arch/arm64/include/asm/kernel-pgtable.h
@@ -33,16 +33,19 @@
  * map to pte level. The swapper also maps the FDT (see __create_page_tables
  * for more information). Note that the number of ID map translation levels
  * could be increased on the fly if system RAM is out of reach for the default
- * VA range, so 3 pages are reserved in all cases.
+ * VA range, so pages required to map highest possible PA are reserved in all
+ * cases.
  */
 #if ARM64_SWAPPER_USES_SECTION_MAPS
 #define SWAPPER_PGTABLE_LEVELS	(CONFIG_PGTABLE_LEVELS - 1)
+#define IDMAP_PGTABLE_LEVELS	(ARM64_HW_PGTABLE_LEVELS(PHYS_MASK_SHIFT) - 1)
 #else
 #define SWAPPER_PGTABLE_LEVELS	(CONFIG_PGTABLE_LEVELS)
+#define IDMAP_PGTABLE_LEVELS	(ARM64_HW_PGTABLE_LEVELS(PHYS_MASK_SHIFT))
 #endif
 
 #define SWAPPER_DIR_SIZE	(SWAPPER_PGTABLE_LEVELS * PAGE_SIZE)
-#define IDMAP_DIR_SIZE		(3 * PAGE_SIZE)
+#define IDMAP_DIR_SIZE		(IDMAP_PGTABLE_LEVELS * PAGE_SIZE)
 
 /* Initial memory map size */
 #if ARM64_SWAPPER_USES_SECTION_MAPS
-- 
1.7.9.5

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

* [PATCHv3 05/11] arm64: Handle 4 level page table for swapper
  2015-10-14 11:20 ` Suzuki K. Poulose
@ 2015-10-14 11:20   ` Suzuki K. Poulose
  -1 siblings, 0 replies; 110+ messages in thread
From: Suzuki K. Poulose @ 2015-10-14 11:20 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-kernel, catalin.marinas, will.deacon, mark.rutland,
	steve.capper, marc.zyngier, ard.biesheuvel, christoffer.dall,
	Suzuki K. Poulose

At the moment, we only support maximum of 3-level page table for
swapper. With 48bit VA, 64K has only 3 levels and 4K uses section
mapping. Add support for 4-level page table for swapper, needed
by 16K pages.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Tested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 arch/arm64/kernel/head.S |    5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index 149fce3..7ace955 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -271,7 +271,10 @@ ENDPROC(preserve_boot_args)
  */
 	.macro	create_pgd_entry, tbl, virt, tmp1, tmp2
 	create_table_entry \tbl, \virt, PGDIR_SHIFT, PTRS_PER_PGD, \tmp1, \tmp2
-#if SWAPPER_PGTABLE_LEVELS == 3
+#if SWAPPER_PGTABLE_LEVELS > 3
+	create_table_entry \tbl, \virt, PUD_SHIFT, PTRS_PER_PUD, \tmp1, \tmp2
+#endif
+#if SWAPPER_PGTABLE_LEVELS > 2
 	create_table_entry \tbl, \virt, SWAPPER_TABLE_SHIFT, PTRS_PER_PTE, \tmp1, \tmp2
 #endif
 	.endm
-- 
1.7.9.5


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

* [PATCHv3 05/11] arm64: Handle 4 level page table for swapper
@ 2015-10-14 11:20   ` Suzuki K. Poulose
  0 siblings, 0 replies; 110+ messages in thread
From: Suzuki K. Poulose @ 2015-10-14 11:20 UTC (permalink / raw)
  To: linux-arm-kernel

At the moment, we only support maximum of 3-level page table for
swapper. With 48bit VA, 64K has only 3 levels and 4K uses section
mapping. Add support for 4-level page table for swapper, needed
by 16K pages.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Tested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 arch/arm64/kernel/head.S |    5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index 149fce3..7ace955 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -271,7 +271,10 @@ ENDPROC(preserve_boot_args)
  */
 	.macro	create_pgd_entry, tbl, virt, tmp1, tmp2
 	create_table_entry \tbl, \virt, PGDIR_SHIFT, PTRS_PER_PGD, \tmp1, \tmp2
-#if SWAPPER_PGTABLE_LEVELS == 3
+#if SWAPPER_PGTABLE_LEVELS > 3
+	create_table_entry \tbl, \virt, PUD_SHIFT, PTRS_PER_PUD, \tmp1, \tmp2
+#endif
+#if SWAPPER_PGTABLE_LEVELS > 2
 	create_table_entry \tbl, \virt, SWAPPER_TABLE_SHIFT, PTRS_PER_PTE, \tmp1, \tmp2
 #endif
 	.endm
-- 
1.7.9.5

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

* [PATCHv3 06/11] arm64: Clean config usages for page size
  2015-10-14 11:20 ` Suzuki K. Poulose
@ 2015-10-14 11:20   ` Suzuki K. Poulose
  -1 siblings, 0 replies; 110+ messages in thread
From: Suzuki K. Poulose @ 2015-10-14 11:20 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-kernel, catalin.marinas, will.deacon, mark.rutland,
	steve.capper, marc.zyngier, ard.biesheuvel, christoffer.dall,
	Suzuki K. Poulose

We use !CONFIG_ARM64_64K_PAGES for CONFIG_ARM64_4K_PAGES
(and vice versa) in code. It all worked well, so far since
we only had two options. Now, with the introduction of 16K,
these cases will break. This patch cleans up the code to
use the required CONFIG symbol expression without the assumption
that !64K => 4K (and vice versa)

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Acked-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Tested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 arch/arm64/Kconfig                   |    4 ++--
 arch/arm64/Kconfig.debug             |    2 +-
 arch/arm64/include/asm/thread_info.h |    2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 2782c11..4654c27 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -466,7 +466,7 @@ config ARCH_WANT_GENERAL_HUGETLB
 	def_bool y
 
 config ARCH_WANT_HUGE_PMD_SHARE
-	def_bool y if !ARM64_64K_PAGES
+	def_bool y if ARM64_4K_PAGES
 
 config HAVE_ARCH_TRANSPARENT_HUGEPAGE
 	def_bool y
@@ -678,7 +678,7 @@ source "fs/Kconfig.binfmt"
 
 config COMPAT
 	bool "Kernel support for 32-bit EL0"
-	depends on !ARM64_64K_PAGES || EXPERT
+	depends on ARM64_4K_PAGES || EXPERT
 	select COMPAT_BINFMT_ELF
 	select HAVE_UID16
 	select OLD_SIGSUSPEND3
diff --git a/arch/arm64/Kconfig.debug b/arch/arm64/Kconfig.debug
index d6285ef..c24d6ad 100644
--- a/arch/arm64/Kconfig.debug
+++ b/arch/arm64/Kconfig.debug
@@ -77,7 +77,7 @@ config DEBUG_RODATA
           If in doubt, say Y
 
 config DEBUG_ALIGN_RODATA
-	depends on DEBUG_RODATA && !ARM64_64K_PAGES
+	depends on DEBUG_RODATA && ARM64_4K_PAGES
 	bool "Align linker sections up to SECTION_SIZE"
 	help
 	  If this option is enabled, sections that may potentially be marked as
diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h
index 555c6de..5eac6a2 100644
--- a/arch/arm64/include/asm/thread_info.h
+++ b/arch/arm64/include/asm/thread_info.h
@@ -23,7 +23,7 @@
 
 #include <linux/compiler.h>
 
-#ifndef CONFIG_ARM64_64K_PAGES
+#ifdef CONFIG_ARM64_4K_PAGES
 #define THREAD_SIZE_ORDER	2
 #endif
 
-- 
1.7.9.5


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

* [PATCHv3 06/11] arm64: Clean config usages for page size
@ 2015-10-14 11:20   ` Suzuki K. Poulose
  0 siblings, 0 replies; 110+ messages in thread
From: Suzuki K. Poulose @ 2015-10-14 11:20 UTC (permalink / raw)
  To: linux-arm-kernel

We use !CONFIG_ARM64_64K_PAGES for CONFIG_ARM64_4K_PAGES
(and vice versa) in code. It all worked well, so far since
we only had two options. Now, with the introduction of 16K,
these cases will break. This patch cleans up the code to
use the required CONFIG symbol expression without the assumption
that !64K => 4K (and vice versa)

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Acked-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Tested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 arch/arm64/Kconfig                   |    4 ++--
 arch/arm64/Kconfig.debug             |    2 +-
 arch/arm64/include/asm/thread_info.h |    2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 2782c11..4654c27 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -466,7 +466,7 @@ config ARCH_WANT_GENERAL_HUGETLB
 	def_bool y
 
 config ARCH_WANT_HUGE_PMD_SHARE
-	def_bool y if !ARM64_64K_PAGES
+	def_bool y if ARM64_4K_PAGES
 
 config HAVE_ARCH_TRANSPARENT_HUGEPAGE
 	def_bool y
@@ -678,7 +678,7 @@ source "fs/Kconfig.binfmt"
 
 config COMPAT
 	bool "Kernel support for 32-bit EL0"
-	depends on !ARM64_64K_PAGES || EXPERT
+	depends on ARM64_4K_PAGES || EXPERT
 	select COMPAT_BINFMT_ELF
 	select HAVE_UID16
 	select OLD_SIGSUSPEND3
diff --git a/arch/arm64/Kconfig.debug b/arch/arm64/Kconfig.debug
index d6285ef..c24d6ad 100644
--- a/arch/arm64/Kconfig.debug
+++ b/arch/arm64/Kconfig.debug
@@ -77,7 +77,7 @@ config DEBUG_RODATA
           If in doubt, say Y
 
 config DEBUG_ALIGN_RODATA
-	depends on DEBUG_RODATA && !ARM64_64K_PAGES
+	depends on DEBUG_RODATA && ARM64_4K_PAGES
 	bool "Align linker sections up to SECTION_SIZE"
 	help
 	  If this option is enabled, sections that may potentially be marked as
diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h
index 555c6de..5eac6a2 100644
--- a/arch/arm64/include/asm/thread_info.h
+++ b/arch/arm64/include/asm/thread_info.h
@@ -23,7 +23,7 @@
 
 #include <linux/compiler.h>
 
-#ifndef CONFIG_ARM64_64K_PAGES
+#ifdef CONFIG_ARM64_4K_PAGES
 #define THREAD_SIZE_ORDER	2
 #endif
 
-- 
1.7.9.5

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

* [PATCHv3 07/11] arm64: Kconfig: Fix help text about AArch32 support with 64K pages
  2015-10-14 11:20 ` Suzuki K. Poulose
@ 2015-10-14 11:20   ` Suzuki K. Poulose
  -1 siblings, 0 replies; 110+ messages in thread
From: Suzuki K. Poulose @ 2015-10-14 11:20 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-kernel, catalin.marinas, will.deacon, mark.rutland,
	steve.capper, marc.zyngier, ard.biesheuvel, christoffer.dall,
	Suzuki K. Poulose

Update the help text for ARM64_64K_PAGES to reflect the reality
about AArch32 support.

Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Tested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 arch/arm64/Kconfig |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 4654c27..13b51a0 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -368,8 +368,8 @@ config ARM64_64K_PAGES
 	help
 	  This feature enables 64KB pages support (4KB by default)
 	  allowing only two levels of page tables and faster TLB
-	  look-up. AArch32 emulation is not available when this feature
-	  is enabled.
+	  look-up. AArch32 emulation requires applications compiled
+	  with 64K aligned segments.
 
 endchoice
 
-- 
1.7.9.5


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

* [PATCHv3 07/11] arm64: Kconfig: Fix help text about AArch32 support with 64K pages
@ 2015-10-14 11:20   ` Suzuki K. Poulose
  0 siblings, 0 replies; 110+ messages in thread
From: Suzuki K. Poulose @ 2015-10-14 11:20 UTC (permalink / raw)
  To: linux-arm-kernel

Update the help text for ARM64_64K_PAGES to reflect the reality
about AArch32 support.

Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Tested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 arch/arm64/Kconfig |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 4654c27..13b51a0 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -368,8 +368,8 @@ config ARM64_64K_PAGES
 	help
 	  This feature enables 64KB pages support (4KB by default)
 	  allowing only two levels of page tables and faster TLB
-	  look-up. AArch32 emulation is not available when this feature
-	  is enabled.
+	  look-up. AArch32 emulation requires applications compiled
+	  with 64K aligned segments.
 
 endchoice
 
-- 
1.7.9.5

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

* [PATCHv3 08/11] arm64: Check for selected granule support
  2015-10-14 11:20 ` Suzuki K. Poulose
@ 2015-10-14 11:20   ` Suzuki K. Poulose
  -1 siblings, 0 replies; 110+ messages in thread
From: Suzuki K. Poulose @ 2015-10-14 11:20 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-kernel, catalin.marinas, will.deacon, mark.rutland,
	steve.capper, marc.zyngier, ard.biesheuvel, christoffer.dall,
	Suzuki K. Poulose

Ensure that the selected page size is supported by the
CPU(s).

Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Tested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 arch/arm64/include/asm/sysreg.h |   12 ++++++++++++
 arch/arm64/kernel/head.S        |   28 ++++++++++++++++++++++++++--
 2 files changed, 38 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index a7f3d4b..1f07cc5 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -44,6 +44,18 @@
 #define SET_PSTATE_PAN(x) __inst_arm(0xd5000000 | REG_PSTATE_PAN_IMM |\
 				     (!!x)<<8 | 0x1f)
 
+
+#define ID_AA64MMFR0_TGRAN4_SHIFT	28
+#define ID_AA64MMFR0_TGRAN64_SHIFT	24
+#define ID_AA64MMFR0_TGRAN16_SHIFT	20
+
+#define ID_AA64MMFR0_TGRAN4_NI		0xf
+#define ID_AA64MMFR0_TGRAN4_ON		0x0
+#define ID_AA64MMFR0_TGRAN64_NI		0xf
+#define ID_AA64MMFR0_TGRAN64_ON		0x0
+#define ID_AA64MMFR0_TGRAN16_NI		0x0
+#define ID_AA64MMFR0_TGRAN16_ON		0x1
+
 #ifdef __ASSEMBLY__
 
 	.irp	num,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index 7ace955..b6aa9e0 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -31,10 +31,11 @@
 #include <asm/cputype.h>
 #include <asm/kernel-pgtable.h>
 #include <asm/memory.h>
-#include <asm/thread_info.h>
 #include <asm/pgtable-hwdef.h>
 #include <asm/pgtable.h>
 #include <asm/page.h>
+#include <asm/sysreg.h>
+#include <asm/thread_info.h>
 #include <asm/virt.h>
 
 #define __PHYS_OFFSET	(KERNEL_START - TEXT_OFFSET)
@@ -613,10 +614,28 @@ ENDPROC(__secondary_switched)
  *  x0  = SCTLR_EL1 value for turning on the MMU.
  *  x27 = *virtual* address to jump to upon completion
  *
- * other registers depend on the function called upon completion
+ * Other registers depend on the function called upon completion.
+ *
+ * Checks if the selected granule size is supported by the CPU.
+ * If it doesn't park the CPU
  */
+#if	defined(CONFIG_ARM64_64K_PAGES)
+
+#define id_aa64mmfr0_tgran_shift	ID_AA64MMFR0_TGRAN64_SHIFT
+#define id_aa64mmfr0_tgran_on		ID_AA64MMFR0_TGRAN64_ON
+
+#else
+
+#define id_aa64mmfr0_tgran_shift	ID_AA64MMFR0_TGRAN4_SHIFT
+#define id_aa64mmfr0_tgran_on		ID_AA64MMFR0_TGRAN4_ON
+
+#endif
 	.section	".idmap.text", "ax"
 __enable_mmu:
+	mrs	x1, ID_AA64MMFR0_EL1
+	ubfx	x2, x1, #id_aa64mmfr0_tgran_shift, 4
+	cmp	x2, #id_aa64mmfr0_tgran_on
+	b.ne	__no_granule_support
 	ldr	x5, =vectors
 	msr	vbar_el1, x5
 	msr	ttbr0_el1, x25			// load TTBR0
@@ -634,3 +653,8 @@ __enable_mmu:
 	isb
 	br	x27
 ENDPROC(__enable_mmu)
+
+__no_granule_support:
+	wfe
+	b __no_granule_support
+ENDPROC(__no_granule_support)
-- 
1.7.9.5


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

* [PATCHv3 08/11] arm64: Check for selected granule support
@ 2015-10-14 11:20   ` Suzuki K. Poulose
  0 siblings, 0 replies; 110+ messages in thread
From: Suzuki K. Poulose @ 2015-10-14 11:20 UTC (permalink / raw)
  To: linux-arm-kernel

Ensure that the selected page size is supported by the
CPU(s).

Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Tested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 arch/arm64/include/asm/sysreg.h |   12 ++++++++++++
 arch/arm64/kernel/head.S        |   28 ++++++++++++++++++++++++++--
 2 files changed, 38 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index a7f3d4b..1f07cc5 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -44,6 +44,18 @@
 #define SET_PSTATE_PAN(x) __inst_arm(0xd5000000 | REG_PSTATE_PAN_IMM |\
 				     (!!x)<<8 | 0x1f)
 
+
+#define ID_AA64MMFR0_TGRAN4_SHIFT	28
+#define ID_AA64MMFR0_TGRAN64_SHIFT	24
+#define ID_AA64MMFR0_TGRAN16_SHIFT	20
+
+#define ID_AA64MMFR0_TGRAN4_NI		0xf
+#define ID_AA64MMFR0_TGRAN4_ON		0x0
+#define ID_AA64MMFR0_TGRAN64_NI		0xf
+#define ID_AA64MMFR0_TGRAN64_ON		0x0
+#define ID_AA64MMFR0_TGRAN16_NI		0x0
+#define ID_AA64MMFR0_TGRAN16_ON		0x1
+
 #ifdef __ASSEMBLY__
 
 	.irp	num,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index 7ace955..b6aa9e0 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -31,10 +31,11 @@
 #include <asm/cputype.h>
 #include <asm/kernel-pgtable.h>
 #include <asm/memory.h>
-#include <asm/thread_info.h>
 #include <asm/pgtable-hwdef.h>
 #include <asm/pgtable.h>
 #include <asm/page.h>
+#include <asm/sysreg.h>
+#include <asm/thread_info.h>
 #include <asm/virt.h>
 
 #define __PHYS_OFFSET	(KERNEL_START - TEXT_OFFSET)
@@ -613,10 +614,28 @@ ENDPROC(__secondary_switched)
  *  x0  = SCTLR_EL1 value for turning on the MMU.
  *  x27 = *virtual* address to jump to upon completion
  *
- * other registers depend on the function called upon completion
+ * Other registers depend on the function called upon completion.
+ *
+ * Checks if the selected granule size is supported by the CPU.
+ * If it doesn't park the CPU
  */
+#if	defined(CONFIG_ARM64_64K_PAGES)
+
+#define id_aa64mmfr0_tgran_shift	ID_AA64MMFR0_TGRAN64_SHIFT
+#define id_aa64mmfr0_tgran_on		ID_AA64MMFR0_TGRAN64_ON
+
+#else
+
+#define id_aa64mmfr0_tgran_shift	ID_AA64MMFR0_TGRAN4_SHIFT
+#define id_aa64mmfr0_tgran_on		ID_AA64MMFR0_TGRAN4_ON
+
+#endif
 	.section	".idmap.text", "ax"
 __enable_mmu:
+	mrs	x1, ID_AA64MMFR0_EL1
+	ubfx	x2, x1, #id_aa64mmfr0_tgran_shift, 4
+	cmp	x2, #id_aa64mmfr0_tgran_on
+	b.ne	__no_granule_support
 	ldr	x5, =vectors
 	msr	vbar_el1, x5
 	msr	ttbr0_el1, x25			// load TTBR0
@@ -634,3 +653,8 @@ __enable_mmu:
 	isb
 	br	x27
 ENDPROC(__enable_mmu)
+
+__no_granule_support:
+	wfe
+	b __no_granule_support
+ENDPROC(__no_granule_support)
-- 
1.7.9.5

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

* [PATCHv3 09/11] arm64: Add page size to the kernel image header
  2015-10-14 11:20 ` Suzuki K. Poulose
@ 2015-10-14 11:20   ` Suzuki K. Poulose
  -1 siblings, 0 replies; 110+ messages in thread
From: Suzuki K. Poulose @ 2015-10-14 11:20 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-kernel, catalin.marinas, will.deacon, mark.rutland,
	steve.capper, marc.zyngier, ard.biesheuvel, christoffer.dall,
	Suzuki K. Poulose

From: Ard Biesheuvel <ard.biesheuvel@linaro.org>

This patch adds the page size to the arm64 kernel image header
so that one can infer the PAGESIZE used by the kernel. This will
be helpful to diagnose failures to boot the kernel with page size
not supported by the CPU.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
---
 Documentation/arm64/booting.txt |    7 ++++++-
 arch/arm64/kernel/image.h       |    5 ++++-
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/Documentation/arm64/booting.txt b/Documentation/arm64/booting.txt
index 7d9d3c2..aaf6d77 100644
--- a/Documentation/arm64/booting.txt
+++ b/Documentation/arm64/booting.txt
@@ -104,7 +104,12 @@ Header notes:
 - The flags field (introduced in v3.17) is a little-endian 64-bit field
   composed as follows:
   Bit 0:	Kernel endianness.  1 if BE, 0 if LE.
-  Bits 1-63:	Reserved.
+  Bit 1-2:	Kernel Page size.
+			0 - Unspecified.
+			1 - 4K
+			2 - 16K
+			3 - 64K
+  Bits 3-63:	Reserved.
 
 - When image_size is zero, a bootloader should attempt to keep as much
   memory as possible free for use by the kernel immediately after the
diff --git a/arch/arm64/kernel/image.h b/arch/arm64/kernel/image.h
index 6eb8fee..e45759e 100644
--- a/arch/arm64/kernel/image.h
+++ b/arch/arm64/kernel/image.h
@@ -47,7 +47,10 @@
 #define __HEAD_FLAG_BE	0
 #endif
 
-#define __HEAD_FLAGS	(__HEAD_FLAG_BE << 0)
+#define __HEAD_FLAG_PAGE_SIZE ((PAGE_SHIFT - 10) / 2)
+
+#define __HEAD_FLAGS	(__HEAD_FLAG_BE << 0) |		\
+			(__HEAD_FLAG_PAGE_SIZE << 1)
 
 /*
  * These will output as part of the Image header, which should be little-endian
-- 
1.7.9.5


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

* [PATCHv3 09/11] arm64: Add page size to the kernel image header
@ 2015-10-14 11:20   ` Suzuki K. Poulose
  0 siblings, 0 replies; 110+ messages in thread
From: Suzuki K. Poulose @ 2015-10-14 11:20 UTC (permalink / raw)
  To: linux-arm-kernel

From: Ard Biesheuvel <ard.biesheuvel@linaro.org>

This patch adds the page size to the arm64 kernel image header
so that one can infer the PAGESIZE used by the kernel. This will
be helpful to diagnose failures to boot the kernel with page size
not supported by the CPU.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
---
 Documentation/arm64/booting.txt |    7 ++++++-
 arch/arm64/kernel/image.h       |    5 ++++-
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/Documentation/arm64/booting.txt b/Documentation/arm64/booting.txt
index 7d9d3c2..aaf6d77 100644
--- a/Documentation/arm64/booting.txt
+++ b/Documentation/arm64/booting.txt
@@ -104,7 +104,12 @@ Header notes:
 - The flags field (introduced in v3.17) is a little-endian 64-bit field
   composed as follows:
   Bit 0:	Kernel endianness.  1 if BE, 0 if LE.
-  Bits 1-63:	Reserved.
+  Bit 1-2:	Kernel Page size.
+			0 - Unspecified.
+			1 - 4K
+			2 - 16K
+			3 - 64K
+  Bits 3-63:	Reserved.
 
 - When image_size is zero, a bootloader should attempt to keep as much
   memory as possible free for use by the kernel immediately after the
diff --git a/arch/arm64/kernel/image.h b/arch/arm64/kernel/image.h
index 6eb8fee..e45759e 100644
--- a/arch/arm64/kernel/image.h
+++ b/arch/arm64/kernel/image.h
@@ -47,7 +47,10 @@
 #define __HEAD_FLAG_BE	0
 #endif
 
-#define __HEAD_FLAGS	(__HEAD_FLAG_BE << 0)
+#define __HEAD_FLAG_PAGE_SIZE ((PAGE_SHIFT - 10) / 2)
+
+#define __HEAD_FLAGS	(__HEAD_FLAG_BE << 0) |		\
+			(__HEAD_FLAG_PAGE_SIZE << 1)
 
 /*
  * These will output as part of the Image header, which should be little-endian
-- 
1.7.9.5

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

* [PATCHv3 10/11] arm64: Add 16K page size support
  2015-10-14 11:20 ` Suzuki K. Poulose
@ 2015-10-14 11:20   ` Suzuki K. Poulose
  -1 siblings, 0 replies; 110+ messages in thread
From: Suzuki K. Poulose @ 2015-10-14 11:20 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-kernel, catalin.marinas, will.deacon, mark.rutland,
	steve.capper, marc.zyngier, ard.biesheuvel, christoffer.dall,
	Suzuki K. Poulose, Jeremy Linton

This patch turns on the 16K page support in the kernel. We
support 48bit VA (4 level page tables) and 47bit VA (3 level
page tables).

With 16K we can map 128 entries using contiguous bit hint
at level 3 to map 2M using single TLB entry.

TODO: 16K supports 32 contiguous entries at level 2 to get us
1G(which is not yet supported by the infrastructure). That should
be a separate patch altogether.

Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Jeremy Linton <jeremy.linton@arm.com>
Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Tested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
Changes since V2:
  - Add CONT_SHIFT definitions for 16K
---
 arch/arm64/Kconfig                   |   25 ++++++++++++++++++++-----
 arch/arm64/include/asm/fixmap.h      |    4 +++-
 arch/arm64/include/asm/page.h        |    3 +++
 arch/arm64/include/asm/thread_info.h |    2 ++
 arch/arm64/kernel/head.S             |    7 ++++++-
 arch/arm64/kvm/Kconfig               |    3 +++
 arch/arm64/mm/proc.S                 |    4 +++-
 7 files changed, 40 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 13b51a0..e78045c 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -173,7 +173,8 @@ config PGTABLE_LEVELS
 	default 2 if ARM64_64K_PAGES && ARM64_VA_BITS_42
 	default 3 if ARM64_64K_PAGES && ARM64_VA_BITS_48
 	default 3 if ARM64_4K_PAGES && ARM64_VA_BITS_39
-	default 4 if ARM64_4K_PAGES && ARM64_VA_BITS_48
+	default 3 if ARM64_16K_PAGES && ARM64_VA_BITS_47
+	default 4 if !ARM64_64K_PAGES && ARM64_VA_BITS_48
 
 source "init/Kconfig"
 
@@ -363,6 +364,13 @@ config ARM64_4K_PAGES
 	help
 	  This feature enables 4KB pages support.
 
+config ARM64_16K_PAGES
+	bool "16KB"
+	help
+	  The system will use 16KB pages support. AArch32 emulation
+	  requires applications compiled with 16K(or multiple of 16K)
+	  aligned segments.
+
 config ARM64_64K_PAGES
 	bool "64KB"
 	help
@@ -376,6 +384,7 @@ endchoice
 choice
 	prompt "Virtual address space size"
 	default ARM64_VA_BITS_39 if ARM64_4K_PAGES
+	default ARM64_VA_BITS_47 if ARM64_16K_PAGES
 	default ARM64_VA_BITS_42 if ARM64_64K_PAGES
 	help
 	  Allows choosing one of multiple possible virtual address
@@ -390,6 +399,10 @@ config ARM64_VA_BITS_42
 	bool "42-bit"
 	depends on ARM64_64K_PAGES
 
+config ARM64_VA_BITS_47
+	bool "47-bit"
+	depends on ARM64_16K_PAGES
+
 config ARM64_VA_BITS_48
 	bool "48-bit"
 
@@ -399,6 +412,7 @@ config ARM64_VA_BITS
 	int
 	default 39 if ARM64_VA_BITS_39
 	default 42 if ARM64_VA_BITS_42
+	default 47 if ARM64_VA_BITS_47
 	default 48 if ARM64_VA_BITS_48
 
 config CPU_BIG_ENDIAN
@@ -466,7 +480,7 @@ config ARCH_WANT_GENERAL_HUGETLB
 	def_bool y
 
 config ARCH_WANT_HUGE_PMD_SHARE
-	def_bool y if ARM64_4K_PAGES
+	def_bool y if ARM64_4K_PAGES || ARM64_16K_PAGES
 
 config HAVE_ARCH_TRANSPARENT_HUGEPAGE
 	def_bool y
@@ -503,6 +517,7 @@ config XEN
 config FORCE_MAX_ZONEORDER
 	int
 	default "14" if (ARM64_64K_PAGES && TRANSPARENT_HUGEPAGE)
+	default "12" if (ARM64_16K_PAGES && TRANSPARENT_HUGEPAGE)
 	default "11"
 
 menuconfig ARMV8_DEPRECATED
@@ -689,9 +704,9 @@ config COMPAT
 	  the user helper functions, VFP support and the ptrace interface are
 	  handled appropriately by the kernel.
 
-	  If you also enabled CONFIG_ARM64_64K_PAGES, please be aware that you
-	  will only be able to execute AArch32 binaries that were compiled with
-	  64k aligned segments.
+	  If you use a page size other than 4KB(i.e, 16KB or 64KB), please be aware
+	  that you will only be able to execute AArch32 binaries that were compiled
+	  with page size aligned segments.
 
 	  If you want to execute 32-bit userspace applications, say Y.
 
diff --git a/arch/arm64/include/asm/fixmap.h b/arch/arm64/include/asm/fixmap.h
index 8b9884c..a294c70 100644
--- a/arch/arm64/include/asm/fixmap.h
+++ b/arch/arm64/include/asm/fixmap.h
@@ -55,8 +55,10 @@ enum fixed_addresses {
 	 * Temporary boot-time mappings, used by early_ioremap(),
 	 * before ioremap() is functional.
 	 */
-#ifdef CONFIG_ARM64_64K_PAGES
+#if	defined(CONFIG_ARM64_64K_PAGES)
 #define NR_FIX_BTMAPS		4
+#elif	defined (CONFIG_ARM64_16K_PAGES)
+#define NR_FIX_BTMAPS		16
 #else
 #define NR_FIX_BTMAPS		64
 #endif
diff --git a/arch/arm64/include/asm/page.h b/arch/arm64/include/asm/page.h
index da32354..736ed4c 100644
--- a/arch/arm64/include/asm/page.h
+++ b/arch/arm64/include/asm/page.h
@@ -24,6 +24,9 @@
 #ifdef CONFIG_ARM64_64K_PAGES
 #define PAGE_SHIFT		16
 #define CONT_SHIFT		5
+#elif defined(CONFIG_ARM64_16K_PAGES)
+#define PAGE_SHIFT		14
+#define CONT_SHIFT		9
 #else
 #define PAGE_SHIFT		12
 #define CONT_SHIFT		4
diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h
index 5eac6a2..90c7ff2 100644
--- a/arch/arm64/include/asm/thread_info.h
+++ b/arch/arm64/include/asm/thread_info.h
@@ -25,6 +25,8 @@
 
 #ifdef CONFIG_ARM64_4K_PAGES
 #define THREAD_SIZE_ORDER	2
+#elif defined(CONFIG_ARM64_16K_PAGES)
+#define THREAD_SIZE_ORDER	0
 #endif
 
 #define THREAD_SIZE		16384
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index b6aa9e0..2ed57a8 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -624,7 +624,12 @@ ENDPROC(__secondary_switched)
 #define id_aa64mmfr0_tgran_shift	ID_AA64MMFR0_TGRAN64_SHIFT
 #define id_aa64mmfr0_tgran_on		ID_AA64MMFR0_TGRAN64_ON
 
-#else
+#elif	defined(CONFIG_ARM64_16K_PAGES)
+
+#define id_aa64mmfr0_tgran_shift	ID_AA64MMFR0_TGRAN16_SHIFT
+#define id_aa64mmfr0_tgran_on		ID_AA64MMFR0_TGRAN16_ON
+
+#elif	defined(CONFIG_ARM64_4K_PAGES)
 
 #define id_aa64mmfr0_tgran_shift	ID_AA64MMFR0_TGRAN4_SHIFT
 #define id_aa64mmfr0_tgran_on		ID_AA64MMFR0_TGRAN4_ON
diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
index 5c7e920..6a7d5cd 100644
--- a/arch/arm64/kvm/Kconfig
+++ b/arch/arm64/kvm/Kconfig
@@ -19,6 +19,7 @@ if VIRTUALIZATION
 config KVM
 	bool "Kernel-based Virtual Machine (KVM) support"
 	depends on OF
+	depends on !ARM64_16K_PAGES
 	select MMU_NOTIFIER
 	select PREEMPT_NOTIFIERS
 	select ANON_INODES
@@ -33,6 +34,8 @@ config KVM
 	select HAVE_KVM_IRQFD
 	---help---
 	  Support hosting virtualized guest machines.
+	  We don't support KVM with 16K page tables yet, due to the multiple
+	  levels of fake page tables.
 
 	  If unsure, say N.
 
diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
index 91cb2ea..3a4b8b1 100644
--- a/arch/arm64/mm/proc.S
+++ b/arch/arm64/mm/proc.S
@@ -30,7 +30,9 @@
 
 #ifdef CONFIG_ARM64_64K_PAGES
 #define TCR_TG_FLAGS	TCR_TG0_64K | TCR_TG1_64K
-#else
+#elif defined(CONFIG_ARM64_16K_PAGES)
+#define TCR_TG_FLAGS	TCR_TG0_16K | TCR_TG1_16K
+#else /* CONFIG_ARM64_4K_PAGES */
 #define TCR_TG_FLAGS	TCR_TG0_4K | TCR_TG1_4K
 #endif
 
-- 
1.7.9.5


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

* [PATCHv3 10/11] arm64: Add 16K page size support
@ 2015-10-14 11:20   ` Suzuki K. Poulose
  0 siblings, 0 replies; 110+ messages in thread
From: Suzuki K. Poulose @ 2015-10-14 11:20 UTC (permalink / raw)
  To: linux-arm-kernel

This patch turns on the 16K page support in the kernel. We
support 48bit VA (4 level page tables) and 47bit VA (3 level
page tables).

With 16K we can map 128 entries using contiguous bit hint
at level 3 to map 2M using single TLB entry.

TODO: 16K supports 32 contiguous entries at level 2 to get us
1G(which is not yet supported by the infrastructure). That should
be a separate patch altogether.

Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Jeremy Linton <jeremy.linton@arm.com>
Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Tested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
Changes since V2:
  - Add CONT_SHIFT definitions for 16K
---
 arch/arm64/Kconfig                   |   25 ++++++++++++++++++++-----
 arch/arm64/include/asm/fixmap.h      |    4 +++-
 arch/arm64/include/asm/page.h        |    3 +++
 arch/arm64/include/asm/thread_info.h |    2 ++
 arch/arm64/kernel/head.S             |    7 ++++++-
 arch/arm64/kvm/Kconfig               |    3 +++
 arch/arm64/mm/proc.S                 |    4 +++-
 7 files changed, 40 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 13b51a0..e78045c 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -173,7 +173,8 @@ config PGTABLE_LEVELS
 	default 2 if ARM64_64K_PAGES && ARM64_VA_BITS_42
 	default 3 if ARM64_64K_PAGES && ARM64_VA_BITS_48
 	default 3 if ARM64_4K_PAGES && ARM64_VA_BITS_39
-	default 4 if ARM64_4K_PAGES && ARM64_VA_BITS_48
+	default 3 if ARM64_16K_PAGES && ARM64_VA_BITS_47
+	default 4 if !ARM64_64K_PAGES && ARM64_VA_BITS_48
 
 source "init/Kconfig"
 
@@ -363,6 +364,13 @@ config ARM64_4K_PAGES
 	help
 	  This feature enables 4KB pages support.
 
+config ARM64_16K_PAGES
+	bool "16KB"
+	help
+	  The system will use 16KB pages support. AArch32 emulation
+	  requires applications compiled with 16K(or multiple of 16K)
+	  aligned segments.
+
 config ARM64_64K_PAGES
 	bool "64KB"
 	help
@@ -376,6 +384,7 @@ endchoice
 choice
 	prompt "Virtual address space size"
 	default ARM64_VA_BITS_39 if ARM64_4K_PAGES
+	default ARM64_VA_BITS_47 if ARM64_16K_PAGES
 	default ARM64_VA_BITS_42 if ARM64_64K_PAGES
 	help
 	  Allows choosing one of multiple possible virtual address
@@ -390,6 +399,10 @@ config ARM64_VA_BITS_42
 	bool "42-bit"
 	depends on ARM64_64K_PAGES
 
+config ARM64_VA_BITS_47
+	bool "47-bit"
+	depends on ARM64_16K_PAGES
+
 config ARM64_VA_BITS_48
 	bool "48-bit"
 
@@ -399,6 +412,7 @@ config ARM64_VA_BITS
 	int
 	default 39 if ARM64_VA_BITS_39
 	default 42 if ARM64_VA_BITS_42
+	default 47 if ARM64_VA_BITS_47
 	default 48 if ARM64_VA_BITS_48
 
 config CPU_BIG_ENDIAN
@@ -466,7 +480,7 @@ config ARCH_WANT_GENERAL_HUGETLB
 	def_bool y
 
 config ARCH_WANT_HUGE_PMD_SHARE
-	def_bool y if ARM64_4K_PAGES
+	def_bool y if ARM64_4K_PAGES || ARM64_16K_PAGES
 
 config HAVE_ARCH_TRANSPARENT_HUGEPAGE
 	def_bool y
@@ -503,6 +517,7 @@ config XEN
 config FORCE_MAX_ZONEORDER
 	int
 	default "14" if (ARM64_64K_PAGES && TRANSPARENT_HUGEPAGE)
+	default "12" if (ARM64_16K_PAGES && TRANSPARENT_HUGEPAGE)
 	default "11"
 
 menuconfig ARMV8_DEPRECATED
@@ -689,9 +704,9 @@ config COMPAT
 	  the user helper functions, VFP support and the ptrace interface are
 	  handled appropriately by the kernel.
 
-	  If you also enabled CONFIG_ARM64_64K_PAGES, please be aware that you
-	  will only be able to execute AArch32 binaries that were compiled with
-	  64k aligned segments.
+	  If you use a page size other than 4KB(i.e, 16KB or 64KB), please be aware
+	  that you will only be able to execute AArch32 binaries that were compiled
+	  with page size aligned segments.
 
 	  If you want to execute 32-bit userspace applications, say Y.
 
diff --git a/arch/arm64/include/asm/fixmap.h b/arch/arm64/include/asm/fixmap.h
index 8b9884c..a294c70 100644
--- a/arch/arm64/include/asm/fixmap.h
+++ b/arch/arm64/include/asm/fixmap.h
@@ -55,8 +55,10 @@ enum fixed_addresses {
 	 * Temporary boot-time mappings, used by early_ioremap(),
 	 * before ioremap() is functional.
 	 */
-#ifdef CONFIG_ARM64_64K_PAGES
+#if	defined(CONFIG_ARM64_64K_PAGES)
 #define NR_FIX_BTMAPS		4
+#elif	defined (CONFIG_ARM64_16K_PAGES)
+#define NR_FIX_BTMAPS		16
 #else
 #define NR_FIX_BTMAPS		64
 #endif
diff --git a/arch/arm64/include/asm/page.h b/arch/arm64/include/asm/page.h
index da32354..736ed4c 100644
--- a/arch/arm64/include/asm/page.h
+++ b/arch/arm64/include/asm/page.h
@@ -24,6 +24,9 @@
 #ifdef CONFIG_ARM64_64K_PAGES
 #define PAGE_SHIFT		16
 #define CONT_SHIFT		5
+#elif defined(CONFIG_ARM64_16K_PAGES)
+#define PAGE_SHIFT		14
+#define CONT_SHIFT		9
 #else
 #define PAGE_SHIFT		12
 #define CONT_SHIFT		4
diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h
index 5eac6a2..90c7ff2 100644
--- a/arch/arm64/include/asm/thread_info.h
+++ b/arch/arm64/include/asm/thread_info.h
@@ -25,6 +25,8 @@
 
 #ifdef CONFIG_ARM64_4K_PAGES
 #define THREAD_SIZE_ORDER	2
+#elif defined(CONFIG_ARM64_16K_PAGES)
+#define THREAD_SIZE_ORDER	0
 #endif
 
 #define THREAD_SIZE		16384
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index b6aa9e0..2ed57a8 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -624,7 +624,12 @@ ENDPROC(__secondary_switched)
 #define id_aa64mmfr0_tgran_shift	ID_AA64MMFR0_TGRAN64_SHIFT
 #define id_aa64mmfr0_tgran_on		ID_AA64MMFR0_TGRAN64_ON
 
-#else
+#elif	defined(CONFIG_ARM64_16K_PAGES)
+
+#define id_aa64mmfr0_tgran_shift	ID_AA64MMFR0_TGRAN16_SHIFT
+#define id_aa64mmfr0_tgran_on		ID_AA64MMFR0_TGRAN16_ON
+
+#elif	defined(CONFIG_ARM64_4K_PAGES)
 
 #define id_aa64mmfr0_tgran_shift	ID_AA64MMFR0_TGRAN4_SHIFT
 #define id_aa64mmfr0_tgran_on		ID_AA64MMFR0_TGRAN4_ON
diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
index 5c7e920..6a7d5cd 100644
--- a/arch/arm64/kvm/Kconfig
+++ b/arch/arm64/kvm/Kconfig
@@ -19,6 +19,7 @@ if VIRTUALIZATION
 config KVM
 	bool "Kernel-based Virtual Machine (KVM) support"
 	depends on OF
+	depends on !ARM64_16K_PAGES
 	select MMU_NOTIFIER
 	select PREEMPT_NOTIFIERS
 	select ANON_INODES
@@ -33,6 +34,8 @@ config KVM
 	select HAVE_KVM_IRQFD
 	---help---
 	  Support hosting virtualized guest machines.
+	  We don't support KVM with 16K page tables yet, due to the multiple
+	  levels of fake page tables.
 
 	  If unsure, say N.
 
diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
index 91cb2ea..3a4b8b1 100644
--- a/arch/arm64/mm/proc.S
+++ b/arch/arm64/mm/proc.S
@@ -30,7 +30,9 @@
 
 #ifdef CONFIG_ARM64_64K_PAGES
 #define TCR_TG_FLAGS	TCR_TG0_64K | TCR_TG1_64K
-#else
+#elif defined(CONFIG_ARM64_16K_PAGES)
+#define TCR_TG_FLAGS	TCR_TG0_16K | TCR_TG1_16K
+#else /* CONFIG_ARM64_4K_PAGES */
 #define TCR_TG_FLAGS	TCR_TG0_4K | TCR_TG1_4K
 #endif
 
-- 
1.7.9.5

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

* [PATCHv3 11/11] arm64: 36 bit VA
  2015-10-14 11:20 ` Suzuki K. Poulose
@ 2015-10-14 11:20   ` Suzuki K. Poulose
  -1 siblings, 0 replies; 110+ messages in thread
From: Suzuki K. Poulose @ 2015-10-14 11:20 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-kernel, catalin.marinas, will.deacon, mark.rutland,
	steve.capper, marc.zyngier, ard.biesheuvel, christoffer.dall,
	Suzuki K. Poulose

36bit VA lets us use 2 level page tables while limiting the
available address space to 64GB.

Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Tested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 arch/arm64/Kconfig |    8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index e78045c..3b99aa9 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -170,6 +170,7 @@ config FIX_EARLYCON_MEM
 
 config PGTABLE_LEVELS
 	int
+	default 2 if ARM64_16K_PAGES && ARM64_VA_BITS_36
 	default 2 if ARM64_64K_PAGES && ARM64_VA_BITS_42
 	default 3 if ARM64_64K_PAGES && ARM64_VA_BITS_48
 	default 3 if ARM64_4K_PAGES && ARM64_VA_BITS_39
@@ -391,6 +392,10 @@ choice
 	  space sizes. The level of translation table is determined by
 	  a combination of page size and virtual address space size.
 
+config ARM64_VA_BITS_36
+	bool "36-bit"
+	depends on ARM64_16K_PAGES
+
 config ARM64_VA_BITS_39
 	bool "39-bit"
 	depends on ARM64_4K_PAGES
@@ -410,6 +415,7 @@ endchoice
 
 config ARM64_VA_BITS
 	int
+	default 36 if ARM64_VA_BITS_36
 	default 39 if ARM64_VA_BITS_39
 	default 42 if ARM64_VA_BITS_42
 	default 47 if ARM64_VA_BITS_47
@@ -480,7 +486,7 @@ config ARCH_WANT_GENERAL_HUGETLB
 	def_bool y
 
 config ARCH_WANT_HUGE_PMD_SHARE
-	def_bool y if ARM64_4K_PAGES || ARM64_16K_PAGES
+	def_bool y if ARM64_4K_PAGES || (ARM64_16K_PAGES && !ARM64_VA_BITS_36)
 
 config HAVE_ARCH_TRANSPARENT_HUGEPAGE
 	def_bool y
-- 
1.7.9.5


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

* [PATCHv3 11/11] arm64: 36 bit VA
@ 2015-10-14 11:20   ` Suzuki K. Poulose
  0 siblings, 0 replies; 110+ messages in thread
From: Suzuki K. Poulose @ 2015-10-14 11:20 UTC (permalink / raw)
  To: linux-arm-kernel

36bit VA lets us use 2 level page tables while limiting the
available address space to 64GB.

Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Tested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 arch/arm64/Kconfig |    8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index e78045c..3b99aa9 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -170,6 +170,7 @@ config FIX_EARLYCON_MEM
 
 config PGTABLE_LEVELS
 	int
+	default 2 if ARM64_16K_PAGES && ARM64_VA_BITS_36
 	default 2 if ARM64_64K_PAGES && ARM64_VA_BITS_42
 	default 3 if ARM64_64K_PAGES && ARM64_VA_BITS_48
 	default 3 if ARM64_4K_PAGES && ARM64_VA_BITS_39
@@ -391,6 +392,10 @@ choice
 	  space sizes. The level of translation table is determined by
 	  a combination of page size and virtual address space size.
 
+config ARM64_VA_BITS_36
+	bool "36-bit"
+	depends on ARM64_16K_PAGES
+
 config ARM64_VA_BITS_39
 	bool "39-bit"
 	depends on ARM64_4K_PAGES
@@ -410,6 +415,7 @@ endchoice
 
 config ARM64_VA_BITS
 	int
+	default 36 if ARM64_VA_BITS_36
 	default 39 if ARM64_VA_BITS_39
 	default 42 if ARM64_VA_BITS_42
 	default 47 if ARM64_VA_BITS_47
@@ -480,7 +486,7 @@ config ARCH_WANT_GENERAL_HUGETLB
 	def_bool y
 
 config ARCH_WANT_HUGE_PMD_SHARE
-	def_bool y if ARM64_4K_PAGES || ARM64_16K_PAGES
+	def_bool y if ARM64_4K_PAGES || (ARM64_16K_PAGES && !ARM64_VA_BITS_36)
 
 config HAVE_ARCH_TRANSPARENT_HUGEPAGE
 	def_bool y
-- 
1.7.9.5

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

* Re: [PATCHv3 01/11] arm64: Move swapper pagetable definitions
  2015-10-14 11:20   ` Suzuki K. Poulose
@ 2015-10-14 11:42     ` Mark Rutland
  -1 siblings, 0 replies; 110+ messages in thread
From: Mark Rutland @ 2015-10-14 11:42 UTC (permalink / raw)
  To: Suzuki K. Poulose
  Cc: linux-arm-kernel, linux-kernel, catalin.marinas, will.deacon,
	steve.capper, marc.zyngier, ard.biesheuvel, christoffer.dall

On Wed, Oct 14, 2015 at 12:20:24PM +0100, Suzuki K. Poulose wrote:
> Move the kernel pagetable (both swapper and idmap) definitions
> from the generic asm/page.h to a new file, asm/kernel-pgtable.h.
> 
> This is mostly a cosmetic change, to clean up the asm/page.h to
> get rid of the arch specific details which are not needed by the
> generic code.
> 
> Also renames the symbols to prevent conflicts. e.g,
>  	BLOCK_SHIFT => SWAPPER_BLOCK_SHIFT

This sounds sensible to be, so FWIW:

Acked-by: Mark Rutland <mark.rutland@arm.com>

I have a couple of minor nits below, though.

> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>
> Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com>
> Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Tested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
>  arch/arm64/include/asm/kernel-pgtable.h |   65 +++++++++++++++++++++++++++++++
>  arch/arm64/include/asm/page.h           |   18 ---------
>  arch/arm64/kernel/head.S                |   37 ++++--------------
>  arch/arm64/kernel/vmlinux.lds.S         |    1 +
>  4 files changed, 74 insertions(+), 47 deletions(-)
>  create mode 100644 arch/arm64/include/asm/kernel-pgtable.h
> 
> diff --git a/arch/arm64/include/asm/kernel-pgtable.h b/arch/arm64/include/asm/kernel-pgtable.h
> new file mode 100644
> index 0000000..622929d
> --- /dev/null
> +++ b/arch/arm64/include/asm/kernel-pgtable.h
> @@ -0,0 +1,65 @@
> +/*
> + * asm/kernel-pgtable.h : Kernel page table mapping

Drop the filename from the comment. It's redundant and ends up being
painful when refactoring and moving things around.

> + * Copyright (C) 2015 ARM Ltd.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#ifndef __ASM_KERNEL_PGTABLE_H
> +#define __ASM_KERNEL_PGTABLE_H
> +
> +/*
> + * The idmap and swapper page tables need some space reserved in the kernel
> + * image. Both require pgd, pud (4 levels only) and pmd tables to (section)
> + * map the kernel. With the 64K page configuration, swapper and idmap need to
> + * map to pte level. The swapper also maps the FDT (see __create_page_tables
> + * for more information). Note that the number of ID map translation levels
> + * could be increased on the fly if system RAM is out of reach for the default
> + * VA range, so 3 pages are reserved in all cases.
> + */
> +#ifdef CONFIG_ARM64_64K_PAGES
> +#define SWAPPER_PGTABLE_LEVELS	(CONFIG_PGTABLE_LEVELS)
> +#else
> +#define SWAPPER_PGTABLE_LEVELS	(CONFIG_PGTABLE_LEVELS - 1)
> +#endif
> +
> +#define SWAPPER_DIR_SIZE	(SWAPPER_PGTABLE_LEVELS * PAGE_SIZE)
> +#define IDMAP_DIR_SIZE		(3 * PAGE_SIZE)
> +
> +/* Initial memory map size */
> +#ifdef CONFIG_ARM64_64K_PAGES
> +#define SWAPPER_BLOCK_SHIFT	PAGE_SHIFT
> +#define SWAPPER_BLOCK_SIZE	PAGE_SIZE
> +#define SWAPPER_TABLE_SHIFT	PMD_SHIFT
> +#else
> +#define SWAPPER_BLOCK_SHIFT	SECTION_SHIFT
> +#define SWAPPER_BLOCK_SIZE	SECTION_SIZE
> +#define SWAPPER_TABLE_SHIFT	PUD_SHIFT
> +#endif
> +
> +
> +/*
> + * Initial memory map attributes.
> + */
> +#define SWAPPER_PTE_FLAGS	PTE_TYPE_PAGE | PTE_AF | PTE_SHARED
> +#define SWAPPER_PMD_FLAGS	PMD_TYPE_SECT | PMD_SECT_AF | PMD_SECT_S
> +
> +#ifdef CONFIG_ARM64_64K_PAGES
> +#define SWAPPER_MM_MMUFLAGS	PTE_ATTRINDX(MT_NORMAL) | SWAPPER_PTE_FLAGS
> +#else
> +#define SWAPPER_MM_MMUFLAGS	PMD_ATTRINDX(MT_NORMAL) | SWAPPER_PMD_FLAGS
> +#endif
> +
> +
> +#endif

It would be nice to have the usual comment here for what this is ending,
i.e.

#endif /* __ASM_KERNEL_PGTABLE_H */

Thanks,
Mark.

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

* [PATCHv3 01/11] arm64: Move swapper pagetable definitions
@ 2015-10-14 11:42     ` Mark Rutland
  0 siblings, 0 replies; 110+ messages in thread
From: Mark Rutland @ 2015-10-14 11:42 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Oct 14, 2015 at 12:20:24PM +0100, Suzuki K. Poulose wrote:
> Move the kernel pagetable (both swapper and idmap) definitions
> from the generic asm/page.h to a new file, asm/kernel-pgtable.h.
> 
> This is mostly a cosmetic change, to clean up the asm/page.h to
> get rid of the arch specific details which are not needed by the
> generic code.
> 
> Also renames the symbols to prevent conflicts. e.g,
>  	BLOCK_SHIFT => SWAPPER_BLOCK_SHIFT

This sounds sensible to be, so FWIW:

Acked-by: Mark Rutland <mark.rutland@arm.com>

I have a couple of minor nits below, though.

> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>
> Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com>
> Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Tested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
>  arch/arm64/include/asm/kernel-pgtable.h |   65 +++++++++++++++++++++++++++++++
>  arch/arm64/include/asm/page.h           |   18 ---------
>  arch/arm64/kernel/head.S                |   37 ++++--------------
>  arch/arm64/kernel/vmlinux.lds.S         |    1 +
>  4 files changed, 74 insertions(+), 47 deletions(-)
>  create mode 100644 arch/arm64/include/asm/kernel-pgtable.h
> 
> diff --git a/arch/arm64/include/asm/kernel-pgtable.h b/arch/arm64/include/asm/kernel-pgtable.h
> new file mode 100644
> index 0000000..622929d
> --- /dev/null
> +++ b/arch/arm64/include/asm/kernel-pgtable.h
> @@ -0,0 +1,65 @@
> +/*
> + * asm/kernel-pgtable.h : Kernel page table mapping

Drop the filename from the comment. It's redundant and ends up being
painful when refactoring and moving things around.

> + * Copyright (C) 2015 ARM Ltd.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#ifndef __ASM_KERNEL_PGTABLE_H
> +#define __ASM_KERNEL_PGTABLE_H
> +
> +/*
> + * The idmap and swapper page tables need some space reserved in the kernel
> + * image. Both require pgd, pud (4 levels only) and pmd tables to (section)
> + * map the kernel. With the 64K page configuration, swapper and idmap need to
> + * map to pte level. The swapper also maps the FDT (see __create_page_tables
> + * for more information). Note that the number of ID map translation levels
> + * could be increased on the fly if system RAM is out of reach for the default
> + * VA range, so 3 pages are reserved in all cases.
> + */
> +#ifdef CONFIG_ARM64_64K_PAGES
> +#define SWAPPER_PGTABLE_LEVELS	(CONFIG_PGTABLE_LEVELS)
> +#else
> +#define SWAPPER_PGTABLE_LEVELS	(CONFIG_PGTABLE_LEVELS - 1)
> +#endif
> +
> +#define SWAPPER_DIR_SIZE	(SWAPPER_PGTABLE_LEVELS * PAGE_SIZE)
> +#define IDMAP_DIR_SIZE		(3 * PAGE_SIZE)
> +
> +/* Initial memory map size */
> +#ifdef CONFIG_ARM64_64K_PAGES
> +#define SWAPPER_BLOCK_SHIFT	PAGE_SHIFT
> +#define SWAPPER_BLOCK_SIZE	PAGE_SIZE
> +#define SWAPPER_TABLE_SHIFT	PMD_SHIFT
> +#else
> +#define SWAPPER_BLOCK_SHIFT	SECTION_SHIFT
> +#define SWAPPER_BLOCK_SIZE	SECTION_SIZE
> +#define SWAPPER_TABLE_SHIFT	PUD_SHIFT
> +#endif
> +
> +
> +/*
> + * Initial memory map attributes.
> + */
> +#define SWAPPER_PTE_FLAGS	PTE_TYPE_PAGE | PTE_AF | PTE_SHARED
> +#define SWAPPER_PMD_FLAGS	PMD_TYPE_SECT | PMD_SECT_AF | PMD_SECT_S
> +
> +#ifdef CONFIG_ARM64_64K_PAGES
> +#define SWAPPER_MM_MMUFLAGS	PTE_ATTRINDX(MT_NORMAL) | SWAPPER_PTE_FLAGS
> +#else
> +#define SWAPPER_MM_MMUFLAGS	PMD_ATTRINDX(MT_NORMAL) | SWAPPER_PMD_FLAGS
> +#endif
> +
> +
> +#endif

It would be nice to have the usual comment here for what this is ending,
i.e.

#endif /* __ASM_KERNEL_PGTABLE_H */

Thanks,
Mark.

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

* Re: [PATCHv3 02/11] arm64: Handle section maps for swapper/idmap
  2015-10-14 11:20   ` Suzuki K. Poulose
@ 2015-10-14 12:06     ` Mark Rutland
  -1 siblings, 0 replies; 110+ messages in thread
From: Mark Rutland @ 2015-10-14 12:06 UTC (permalink / raw)
  To: Suzuki K. Poulose
  Cc: linux-arm-kernel, linux-kernel, catalin.marinas, will.deacon,
	steve.capper, marc.zyngier, ard.biesheuvel, christoffer.dall

On Wed, Oct 14, 2015 at 12:20:25PM +0100, Suzuki K. Poulose wrote:
> We use section maps with 4K page size to create the swapper/idmaps.
> So far we have used !64K or 4K checks to handle the case where we
> use the section maps.
> This patch adds a new symbol, ARM64_SWAPPER_USES_SECTION_MAPS, to
> handle cases where we use section maps, instead of using the page size
> symbols.
> 
> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>
> Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com>
> ---
>  arch/arm64/include/asm/kernel-pgtable.h |   31 ++++++++-----
>  arch/arm64/mm/mmu.c                     |   72 ++++++++++++++-----------------
>  2 files changed, 52 insertions(+), 51 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/kernel-pgtable.h b/arch/arm64/include/asm/kernel-pgtable.h
> index 622929d..5876a36 100644
> --- a/arch/arm64/include/asm/kernel-pgtable.h
> +++ b/arch/arm64/include/asm/kernel-pgtable.h
> @@ -19,6 +19,13 @@
>  #ifndef __ASM_KERNEL_PGTABLE_H
>  #define __ASM_KERNEL_PGTABLE_H
>  
> +/* With 4K pages, we use section maps. */
> +#ifdef CONFIG_ARM64_4K_PAGES
> +#define ARM64_SWAPPER_USES_SECTION_MAPS 1
> +#else
> +#define ARM64_SWAPPER_USES_SECTION_MAPS 0
> +#endif

The comment is somewhat redunant. It would be better to state why we do
this for 4K and not 64K (or 16K).

> @@ -406,14 +407,11 @@ static void __init map_mem(void)
>  	 * memory addressable from the initial direct kernel mapping.
>  	 *
>  	 * The initial direct kernel mapping, located at swapper_pg_dir, gives
> -	 * us PUD_SIZE (4K pages) or PMD_SIZE (64K pages) memory starting from
> -	 * PHYS_OFFSET (which must be aligned to 2MB as per
> -	 * Documentation/arm64/booting.txt).
> +	 * us PUD_SIZE (with SECTION maps, i.e, 4K) or PMD_SIZE (without
> +	 * SECTION maps, i.e, 64K pages) memory starting from PHYS_OFFSET
> +	 * (which must be aligned to 2MB as per Documentation/arm64/booting.txt).

This didn't seem to get updated for 16K later in the series, unless I
missed something.

Perhaps drop the mention of 4K / 64K entirely here?

> @@ -551,7 +552,7 @@ int kern_addr_valid(unsigned long addr)
>  	return pfn_valid(pte_pfn(*pte));
>  }
>  #ifdef CONFIG_SPARSEMEM_VMEMMAP
> -#ifdef CONFIG_ARM64_64K_PAGES
> +#if !ARM64_SWAPPER_USES_SECTION_MAPS

This leaves the comments on the #else and #endif stale. Please update
those too.

Otherwise this looks good!

Thanks,
Mark.

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

* [PATCHv3 02/11] arm64: Handle section maps for swapper/idmap
@ 2015-10-14 12:06     ` Mark Rutland
  0 siblings, 0 replies; 110+ messages in thread
From: Mark Rutland @ 2015-10-14 12:06 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Oct 14, 2015 at 12:20:25PM +0100, Suzuki K. Poulose wrote:
> We use section maps with 4K page size to create the swapper/idmaps.
> So far we have used !64K or 4K checks to handle the case where we
> use the section maps.
> This patch adds a new symbol, ARM64_SWAPPER_USES_SECTION_MAPS, to
> handle cases where we use section maps, instead of using the page size
> symbols.
> 
> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>
> Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com>
> ---
>  arch/arm64/include/asm/kernel-pgtable.h |   31 ++++++++-----
>  arch/arm64/mm/mmu.c                     |   72 ++++++++++++++-----------------
>  2 files changed, 52 insertions(+), 51 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/kernel-pgtable.h b/arch/arm64/include/asm/kernel-pgtable.h
> index 622929d..5876a36 100644
> --- a/arch/arm64/include/asm/kernel-pgtable.h
> +++ b/arch/arm64/include/asm/kernel-pgtable.h
> @@ -19,6 +19,13 @@
>  #ifndef __ASM_KERNEL_PGTABLE_H
>  #define __ASM_KERNEL_PGTABLE_H
>  
> +/* With 4K pages, we use section maps. */
> +#ifdef CONFIG_ARM64_4K_PAGES
> +#define ARM64_SWAPPER_USES_SECTION_MAPS 1
> +#else
> +#define ARM64_SWAPPER_USES_SECTION_MAPS 0
> +#endif

The comment is somewhat redunant. It would be better to state why we do
this for 4K and not 64K (or 16K).

> @@ -406,14 +407,11 @@ static void __init map_mem(void)
>  	 * memory addressable from the initial direct kernel mapping.
>  	 *
>  	 * The initial direct kernel mapping, located at swapper_pg_dir, gives
> -	 * us PUD_SIZE (4K pages) or PMD_SIZE (64K pages) memory starting from
> -	 * PHYS_OFFSET (which must be aligned to 2MB as per
> -	 * Documentation/arm64/booting.txt).
> +	 * us PUD_SIZE (with SECTION maps, i.e, 4K) or PMD_SIZE (without
> +	 * SECTION maps, i.e, 64K pages) memory starting from PHYS_OFFSET
> +	 * (which must be aligned to 2MB as per Documentation/arm64/booting.txt).

This didn't seem to get updated for 16K later in the series, unless I
missed something.

Perhaps drop the mention of 4K / 64K entirely here?

> @@ -551,7 +552,7 @@ int kern_addr_valid(unsigned long addr)
>  	return pfn_valid(pte_pfn(*pte));
>  }
>  #ifdef CONFIG_SPARSEMEM_VMEMMAP
> -#ifdef CONFIG_ARM64_64K_PAGES
> +#if !ARM64_SWAPPER_USES_SECTION_MAPS

This leaves the comments on the #else and #endif stale. Please update
those too.

Otherwise this looks good!

Thanks,
Mark.

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

* Re: [PATCHv3 01/11] arm64: Move swapper pagetable definitions
  2015-10-14 11:42     ` Mark Rutland
@ 2015-10-14 12:41       ` Suzuki K. Poulose
  -1 siblings, 0 replies; 110+ messages in thread
From: Suzuki K. Poulose @ 2015-10-14 12:41 UTC (permalink / raw)
  To: Mark Rutland
  Cc: linux-arm-kernel, linux-kernel, catalin.marinas, will.deacon,
	steve.capper, marc.zyngier, ard.biesheuvel, christoffer.dall

On 14/10/15 12:42, Mark Rutland wrote:
> On Wed, Oct 14, 2015 at 12:20:24PM +0100, Suzuki K. Poulose wrote:

>>
>> Also renames the symbols to prevent conflicts. e.g,
>>   	BLOCK_SHIFT => SWAPPER_BLOCK_SHIFT
>
> This sounds sensible to be, so FWIW:
>
> Acked-by: Mark Rutland <mark.rutland@arm.com>
>
> I have a couple of minor nits below, though.

>> diff --git a/arch/arm64/include/asm/kernel-pgtable.h b/arch/arm64/include/asm/kernel-pgtable.h
>> new file mode 100644
>> index 0000000..622929d
>> --- /dev/null
>> +++ b/arch/arm64/include/asm/kernel-pgtable.h
>> @@ -0,0 +1,65 @@
>> +/*
>> + * asm/kernel-pgtable.h : Kernel page table mapping
>
> Drop the filename from the comment. It's redundant and ends up being
> painful when refactoring and moving things around.
>

OK

>> +
>> +
>> +#endif
>
> It would be nice to have the usual comment here for what this is ending,
> i.e.
>
> #endif /* __ASM_KERNEL_PGTABLE_H */

Oh yes, will add it.

Thanks
Suzuki


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

* [PATCHv3 01/11] arm64: Move swapper pagetable definitions
@ 2015-10-14 12:41       ` Suzuki K. Poulose
  0 siblings, 0 replies; 110+ messages in thread
From: Suzuki K. Poulose @ 2015-10-14 12:41 UTC (permalink / raw)
  To: linux-arm-kernel

On 14/10/15 12:42, Mark Rutland wrote:
> On Wed, Oct 14, 2015 at 12:20:24PM +0100, Suzuki K. Poulose wrote:

>>
>> Also renames the symbols to prevent conflicts. e.g,
>>   	BLOCK_SHIFT => SWAPPER_BLOCK_SHIFT
>
> This sounds sensible to be, so FWIW:
>
> Acked-by: Mark Rutland <mark.rutland@arm.com>
>
> I have a couple of minor nits below, though.

>> diff --git a/arch/arm64/include/asm/kernel-pgtable.h b/arch/arm64/include/asm/kernel-pgtable.h
>> new file mode 100644
>> index 0000000..622929d
>> --- /dev/null
>> +++ b/arch/arm64/include/asm/kernel-pgtable.h
>> @@ -0,0 +1,65 @@
>> +/*
>> + * asm/kernel-pgtable.h : Kernel page table mapping
>
> Drop the filename from the comment. It's redundant and ends up being
> painful when refactoring and moving things around.
>

OK

>> +
>> +
>> +#endif
>
> It would be nice to have the usual comment here for what this is ending,
> i.e.
>
> #endif /* __ASM_KERNEL_PGTABLE_H */

Oh yes, will add it.

Thanks
Suzuki

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

* Re: [PATCHv3 02/11] arm64: Handle section maps for swapper/idmap
  2015-10-14 12:06     ` Mark Rutland
@ 2015-10-14 13:21       ` Suzuki K. Poulose
  -1 siblings, 0 replies; 110+ messages in thread
From: Suzuki K. Poulose @ 2015-10-14 13:21 UTC (permalink / raw)
  To: Mark Rutland
  Cc: linux-arm-kernel, linux-kernel, catalin.marinas, will.deacon,
	steve.capper, marc.zyngier, ard.biesheuvel, christoffer.dall

On 14/10/15 13:06, Mark Rutland wrote:
> On Wed, Oct 14, 2015 at 12:20:25PM +0100, Suzuki K. Poulose wrote:
>> We use section maps with 4K page size to create the swapper/idmaps.
>> So far we have used !64K or 4K checks to handle the case where we
>> use the section maps.
>> This patch adds a new symbol, ARM64_SWAPPER_USES_SECTION_MAPS, to
>> handle cases where we use section maps, instead of using the page size
>> symbols.
>>
>> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>> Cc: Mark Rutland <mark.rutland@arm.com>
>> Cc: Catalin Marinas <catalin.marinas@arm.com>
>> Cc: Will Deacon <will.deacon@arm.com>
>> Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com>
>> ---
>>   arch/arm64/include/asm/kernel-pgtable.h |   31 ++++++++-----
>>   arch/arm64/mm/mmu.c                     |   72 ++++++++++++++-----------------
>>   2 files changed, 52 insertions(+), 51 deletions(-)
>>
>> diff --git a/arch/arm64/include/asm/kernel-pgtable.h b/arch/arm64/include/asm/kernel-pgtable.h
>> index 622929d..5876a36 100644
>> --- a/arch/arm64/include/asm/kernel-pgtable.h
>> +++ b/arch/arm64/include/asm/kernel-pgtable.h
>> @@ -19,6 +19,13 @@
>>   #ifndef __ASM_KERNEL_PGTABLE_H
>>   #define __ASM_KERNEL_PGTABLE_H
>>
>> +/* With 4K pages, we use section maps. */
>> +#ifdef CONFIG_ARM64_4K_PAGES
>> +#define ARM64_SWAPPER_USES_SECTION_MAPS 1
>> +#else
>> +#define ARM64_SWAPPER_USES_SECTION_MAPS 0
>> +#endif
>
> The comment is somewhat redunant. It would be better to state why we do
> this for 4K and not 64K (or 16K).

Something like :

/*
  * ARM64 kernel is guaranteed to be loaded at 2M aligned
  * address (as per booting requirements). Hence we can use
  * section mapping with 4K (section size = 2M) and not with
  * 16K(section size = 32M) or 64K (section size = 512M).
  */

>> +	 * us PUD_SIZE (with SECTION maps, i.e, 4K) or PMD_SIZE (without
>> +	 * SECTION maps, i.e, 64K pages) memory starting from PHYS_OFFSET
>> +	 * (which must be aligned to 2MB as per Documentation/arm64/booting.txt).
>
> This didn't seem to get updated for 16K later in the series, unless I
> missed something.
>
> Perhaps drop the mention of 4K / 64K entirely here?

You are right, I missed it. We can drop the pagesize info entirely.

>
>> @@ -551,7 +552,7 @@ int kern_addr_valid(unsigned long addr)
>>   	return pfn_valid(pte_pfn(*pte));
>>   }
>>   #ifdef CONFIG_SPARSEMEM_VMEMMAP
>> -#ifdef CONFIG_ARM64_64K_PAGES
>> +#if !ARM64_SWAPPER_USES_SECTION_MAPS
>
> This leaves the comments on the #else and #endif stale. Please update
> those too.

Done.

Thanks
Suzuki


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

* [PATCHv3 02/11] arm64: Handle section maps for swapper/idmap
@ 2015-10-14 13:21       ` Suzuki K. Poulose
  0 siblings, 0 replies; 110+ messages in thread
From: Suzuki K. Poulose @ 2015-10-14 13:21 UTC (permalink / raw)
  To: linux-arm-kernel

On 14/10/15 13:06, Mark Rutland wrote:
> On Wed, Oct 14, 2015 at 12:20:25PM +0100, Suzuki K. Poulose wrote:
>> We use section maps with 4K page size to create the swapper/idmaps.
>> So far we have used !64K or 4K checks to handle the case where we
>> use the section maps.
>> This patch adds a new symbol, ARM64_SWAPPER_USES_SECTION_MAPS, to
>> handle cases where we use section maps, instead of using the page size
>> symbols.
>>
>> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>> Cc: Mark Rutland <mark.rutland@arm.com>
>> Cc: Catalin Marinas <catalin.marinas@arm.com>
>> Cc: Will Deacon <will.deacon@arm.com>
>> Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com>
>> ---
>>   arch/arm64/include/asm/kernel-pgtable.h |   31 ++++++++-----
>>   arch/arm64/mm/mmu.c                     |   72 ++++++++++++++-----------------
>>   2 files changed, 52 insertions(+), 51 deletions(-)
>>
>> diff --git a/arch/arm64/include/asm/kernel-pgtable.h b/arch/arm64/include/asm/kernel-pgtable.h
>> index 622929d..5876a36 100644
>> --- a/arch/arm64/include/asm/kernel-pgtable.h
>> +++ b/arch/arm64/include/asm/kernel-pgtable.h
>> @@ -19,6 +19,13 @@
>>   #ifndef __ASM_KERNEL_PGTABLE_H
>>   #define __ASM_KERNEL_PGTABLE_H
>>
>> +/* With 4K pages, we use section maps. */
>> +#ifdef CONFIG_ARM64_4K_PAGES
>> +#define ARM64_SWAPPER_USES_SECTION_MAPS 1
>> +#else
>> +#define ARM64_SWAPPER_USES_SECTION_MAPS 0
>> +#endif
>
> The comment is somewhat redunant. It would be better to state why we do
> this for 4K and not 64K (or 16K).

Something like :

/*
  * ARM64 kernel is guaranteed to be loaded at 2M aligned
  * address (as per booting requirements). Hence we can use
  * section mapping with 4K (section size = 2M) and not with
  * 16K(section size = 32M) or 64K (section size = 512M).
  */

>> +	 * us PUD_SIZE (with SECTION maps, i.e, 4K) or PMD_SIZE (without
>> +	 * SECTION maps, i.e, 64K pages) memory starting from PHYS_OFFSET
>> +	 * (which must be aligned to 2MB as per Documentation/arm64/booting.txt).
>
> This didn't seem to get updated for 16K later in the series, unless I
> missed something.
>
> Perhaps drop the mention of 4K / 64K entirely here?

You are right, I missed it. We can drop the pagesize info entirely.

>
>> @@ -551,7 +552,7 @@ int kern_addr_valid(unsigned long addr)
>>   	return pfn_valid(pte_pfn(*pte));
>>   }
>>   #ifdef CONFIG_SPARSEMEM_VMEMMAP
>> -#ifdef CONFIG_ARM64_64K_PAGES
>> +#if !ARM64_SWAPPER_USES_SECTION_MAPS
>
> This leaves the comments on the #else and #endif stale. Please update
> those too.

Done.

Thanks
Suzuki

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

* Re: [PATCHv3 02/11] arm64: Handle section maps for swapper/idmap
  2015-10-14 13:21       ` Suzuki K. Poulose
@ 2015-10-14 14:51         ` Mark Rutland
  -1 siblings, 0 replies; 110+ messages in thread
From: Mark Rutland @ 2015-10-14 14:51 UTC (permalink / raw)
  To: Suzuki K. Poulose
  Cc: linux-arm-kernel, linux-kernel, catalin.marinas, will.deacon,
	steve.capper, marc.zyngier, ard.biesheuvel, christoffer.dall

> >>+/* With 4K pages, we use section maps. */
> >>+#ifdef CONFIG_ARM64_4K_PAGES
> >>+#define ARM64_SWAPPER_USES_SECTION_MAPS 1
> >>+#else
> >>+#define ARM64_SWAPPER_USES_SECTION_MAPS 0
> >>+#endif
> >
> >The comment is somewhat redunant. It would be better to state why we do
> >this for 4K and not 64K (or 16K).
> 
> Something like :
> 
> /*
>  * ARM64 kernel is guaranteed to be loaded at 2M aligned
>  * address (as per booting requirements). Hence we can use
>  * section mapping with 4K (section size = 2M) and not with
>  * 16K(section size = 32M) or 64K (section size = 512M).
>  */

That sounds much better. I hadn't figured out why myself, so thanks for
the explanation :)

However, there's one minor nit: the start of memory below the kernel is
2M aligned, but the offset means that the kernel itself is not loaded at
a 2M aligned address.

So how about:

/*
 * The linear mapping and the start of memory are both 2M aligned (per
 * the arm64 booting.txt requirements). Hence we can use section mapping
 * with 4K (section size = 2M) but not with 16K (section size = 32M) or
 * 64K (section size = 512M).
 */

> >>+	 * us PUD_SIZE (with SECTION maps, i.e, 4K) or PMD_SIZE (without
> >>+	 * SECTION maps, i.e, 64K pages) memory starting from PHYS_OFFSET
> >>+	 * (which must be aligned to 2MB as per Documentation/arm64/booting.txt).
> >
> >This didn't seem to get updated for 16K later in the series, unless I
> >missed something.
> >
> >Perhaps drop the mention of 4K / 64K entirely here?
> 
> You are right, I missed it. We can drop the pagesize info entirely.

Ok. Sounds good.

> >>@@ -551,7 +552,7 @@ int kern_addr_valid(unsigned long addr)
> >>  	return pfn_valid(pte_pfn(*pte));
> >>  }
> >>  #ifdef CONFIG_SPARSEMEM_VMEMMAP
> >>-#ifdef CONFIG_ARM64_64K_PAGES
> >>+#if !ARM64_SWAPPER_USES_SECTION_MAPS
> >
> >This leaves the comments on the #else and #endif stale. Please update
> >those too.
> 
> Done.

Great.

Thanks,
Mark.

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

* [PATCHv3 02/11] arm64: Handle section maps for swapper/idmap
@ 2015-10-14 14:51         ` Mark Rutland
  0 siblings, 0 replies; 110+ messages in thread
From: Mark Rutland @ 2015-10-14 14:51 UTC (permalink / raw)
  To: linux-arm-kernel

> >>+/* With 4K pages, we use section maps. */
> >>+#ifdef CONFIG_ARM64_4K_PAGES
> >>+#define ARM64_SWAPPER_USES_SECTION_MAPS 1
> >>+#else
> >>+#define ARM64_SWAPPER_USES_SECTION_MAPS 0
> >>+#endif
> >
> >The comment is somewhat redunant. It would be better to state why we do
> >this for 4K and not 64K (or 16K).
> 
> Something like :
> 
> /*
>  * ARM64 kernel is guaranteed to be loaded at 2M aligned
>  * address (as per booting requirements). Hence we can use
>  * section mapping with 4K (section size = 2M) and not with
>  * 16K(section size = 32M) or 64K (section size = 512M).
>  */

That sounds much better. I hadn't figured out why myself, so thanks for
the explanation :)

However, there's one minor nit: the start of memory below the kernel is
2M aligned, but the offset means that the kernel itself is not loaded at
a 2M aligned address.

So how about:

/*
 * The linear mapping and the start of memory are both 2M aligned (per
 * the arm64 booting.txt requirements). Hence we can use section mapping
 * with 4K (section size = 2M) but not with 16K (section size = 32M) or
 * 64K (section size = 512M).
 */

> >>+	 * us PUD_SIZE (with SECTION maps, i.e, 4K) or PMD_SIZE (without
> >>+	 * SECTION maps, i.e, 64K pages) memory starting from PHYS_OFFSET
> >>+	 * (which must be aligned to 2MB as per Documentation/arm64/booting.txt).
> >
> >This didn't seem to get updated for 16K later in the series, unless I
> >missed something.
> >
> >Perhaps drop the mention of 4K / 64K entirely here?
> 
> You are right, I missed it. We can drop the pagesize info entirely.

Ok. Sounds good.

> >>@@ -551,7 +552,7 @@ int kern_addr_valid(unsigned long addr)
> >>  	return pfn_valid(pte_pfn(*pte));
> >>  }
> >>  #ifdef CONFIG_SPARSEMEM_VMEMMAP
> >>-#ifdef CONFIG_ARM64_64K_PAGES
> >>+#if !ARM64_SWAPPER_USES_SECTION_MAPS
> >
> >This leaves the comments on the #else and #endif stale. Please update
> >those too.
> 
> Done.

Great.

Thanks,
Mark.

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

* Re: [PATCHv3 02/11] arm64: Handle section maps for swapper/idmap
  2015-10-14 14:51         ` Mark Rutland
@ 2015-10-14 15:08           ` Suzuki K. Poulose
  -1 siblings, 0 replies; 110+ messages in thread
From: Suzuki K. Poulose @ 2015-10-14 15:08 UTC (permalink / raw)
  To: Mark Rutland
  Cc: linux-arm-kernel, linux-kernel, catalin.marinas, will.deacon,
	steve.capper, marc.zyngier, ard.biesheuvel, christoffer.dall

On 14/10/15 15:51, Mark Rutland wrote:
>>>> +/* With 4K pages, we use section maps. */

>> /*
>>   * ARM64 kernel is guaranteed to be loaded at 2M aligned
>>   * address (as per booting requirements). Hence we can use
>>   * section mapping with 4K (section size = 2M) and not with
>>   * 16K(section size = 32M) or 64K (section size = 512M).
>>   */
>
> That sounds much better. I hadn't figured out why myself, so thanks for
> the explanation :)
>
> However, there's one minor nit: the start of memory below the kernel is
> 2M aligned, but the offset means that the kernel itself is not loaded at
> a 2M aligned address.

Oh yes

>
> So how about:
>
> /*
>   * The linear mapping and the start of memory are both 2M aligned (per
>   * the arm64 booting.txt requirements). Hence we can use section mapping
>   * with 4K (section size = 2M) but not with 16K (section size = 32M) or
>   * 64K (section size = 512M).
>   */

Will add this

Thanks
Suzuki


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

* [PATCHv3 02/11] arm64: Handle section maps for swapper/idmap
@ 2015-10-14 15:08           ` Suzuki K. Poulose
  0 siblings, 0 replies; 110+ messages in thread
From: Suzuki K. Poulose @ 2015-10-14 15:08 UTC (permalink / raw)
  To: linux-arm-kernel

On 14/10/15 15:51, Mark Rutland wrote:
>>>> +/* With 4K pages, we use section maps. */

>> /*
>>   * ARM64 kernel is guaranteed to be loaded at 2M aligned
>>   * address (as per booting requirements). Hence we can use
>>   * section mapping with 4K (section size = 2M) and not with
>>   * 16K(section size = 32M) or 64K (section size = 512M).
>>   */
>
> That sounds much better. I hadn't figured out why myself, so thanks for
> the explanation :)
>
> However, there's one minor nit: the start of memory below the kernel is
> 2M aligned, but the offset means that the kernel itself is not loaded at
> a 2M aligned address.

Oh yes

>
> So how about:
>
> /*
>   * The linear mapping and the start of memory are both 2M aligned (per
>   * the arm64 booting.txt requirements). Hence we can use section mapping
>   * with 4K (section size = 2M) but not with 16K (section size = 32M) or
>   * 64K (section size = 512M).
>   */

Will add this

Thanks
Suzuki

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

* Re: [PATCHv3 02/11] arm64: Handle section maps for swapper/idmap
  2015-10-14 15:08           ` Suzuki K. Poulose
@ 2015-10-14 15:14             ` Mark Rutland
  -1 siblings, 0 replies; 110+ messages in thread
From: Mark Rutland @ 2015-10-14 15:14 UTC (permalink / raw)
  To: Suzuki K. Poulose
  Cc: linux-arm-kernel, linux-kernel, catalin.marinas, will.deacon,
	steve.capper, marc.zyngier, ard.biesheuvel, christoffer.dall

On Wed, Oct 14, 2015 at 04:08:43PM +0100, Suzuki K. Poulose wrote:
> On 14/10/15 15:51, Mark Rutland wrote:
> >>>>+/* With 4K pages, we use section maps. */
> 
> >>/*
> >>  * ARM64 kernel is guaranteed to be loaded at 2M aligned
> >>  * address (as per booting requirements). Hence we can use
> >>  * section mapping with 4K (section size = 2M) and not with
> >>  * 16K(section size = 32M) or 64K (section size = 512M).
> >>  */
> >
> >That sounds much better. I hadn't figured out why myself, so thanks for
> >the explanation :)
> >
> >However, there's one minor nit: the start of memory below the kernel is
> >2M aligned, but the offset means that the kernel itself is not loaded at
> >a 2M aligned address.
> 
> Oh yes
> 
> >
> >So how about:
> >
> >/*
> >  * The linear mapping and the start of memory are both 2M aligned (per
> >  * the arm64 booting.txt requirements). Hence we can use section mapping
> >  * with 4K (section size = 2M) but not with 16K (section size = 32M) or
> >  * 64K (section size = 512M).
> >  */
> 
> Will add this

Great.

FWIW, with the changes from this thread applied:

Acked-by: Mark Rutland <mark.rutland@arm.com>

Thanks,
Mark.

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

* [PATCHv3 02/11] arm64: Handle section maps for swapper/idmap
@ 2015-10-14 15:14             ` Mark Rutland
  0 siblings, 0 replies; 110+ messages in thread
From: Mark Rutland @ 2015-10-14 15:14 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Oct 14, 2015 at 04:08:43PM +0100, Suzuki K. Poulose wrote:
> On 14/10/15 15:51, Mark Rutland wrote:
> >>>>+/* With 4K pages, we use section maps. */
> 
> >>/*
> >>  * ARM64 kernel is guaranteed to be loaded at 2M aligned
> >>  * address (as per booting requirements). Hence we can use
> >>  * section mapping with 4K (section size = 2M) and not with
> >>  * 16K(section size = 32M) or 64K (section size = 512M).
> >>  */
> >
> >That sounds much better. I hadn't figured out why myself, so thanks for
> >the explanation :)
> >
> >However, there's one minor nit: the start of memory below the kernel is
> >2M aligned, but the offset means that the kernel itself is not loaded at
> >a 2M aligned address.
> 
> Oh yes
> 
> >
> >So how about:
> >
> >/*
> >  * The linear mapping and the start of memory are both 2M aligned (per
> >  * the arm64 booting.txt requirements). Hence we can use section mapping
> >  * with 4K (section size = 2M) but not with 16K (section size = 32M) or
> >  * 64K (section size = 512M).
> >  */
> 
> Will add this

Great.

FWIW, with the changes from this thread applied:

Acked-by: Mark Rutland <mark.rutland@arm.com>

Thanks,
Mark.

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

* Re: [PATCHv3 10/11] arm64: Add 16K page size support
  2015-10-14 11:20   ` Suzuki K. Poulose
@ 2015-10-14 15:40     ` Jeremy Linton
  -1 siblings, 0 replies; 110+ messages in thread
From: Jeremy Linton @ 2015-10-14 15:40 UTC (permalink / raw)
  To: Suzuki K. Poulose, linux-arm-kernel
  Cc: linux-kernel, catalin.marinas, will.deacon, mark.rutland,
	steve.capper, marc.zyngier, ard.biesheuvel, christoffer.dall

On 10/14/2015 06:20 AM, Suzuki K. Poulose wrote:
> diff --git a/arch/arm64/include/asm/page.h b/arch/arm64/include/asm/page.h
> index da32354..736ed4c 100644
> --- a/arch/arm64/include/asm/page.h
> +++ b/arch/arm64/include/asm/page.h
> @@ -24,6 +24,9 @@
>   #ifdef CONFIG_ARM64_64K_PAGES
>   #define PAGE_SHIFT		16
>   #define CONT_SHIFT		5
> +#elif defined(CONFIG_ARM64_16K_PAGES)
> +#define PAGE_SHIFT		14
> +#define CONT_SHIFT		9
>   #else
>   #define PAGE_SHIFT		12
>   #define CONT_SHIFT		4

Suzuki,

Is CONT_SHIFT correct? I thought it should be 7? The ARM-ARM says that a 
contiguous 3rd level lookup is 128 entries.

Thanks,
	Jeremy


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

* [PATCHv3 10/11] arm64: Add 16K page size support
@ 2015-10-14 15:40     ` Jeremy Linton
  0 siblings, 0 replies; 110+ messages in thread
From: Jeremy Linton @ 2015-10-14 15:40 UTC (permalink / raw)
  To: linux-arm-kernel

On 10/14/2015 06:20 AM, Suzuki K. Poulose wrote:
> diff --git a/arch/arm64/include/asm/page.h b/arch/arm64/include/asm/page.h
> index da32354..736ed4c 100644
> --- a/arch/arm64/include/asm/page.h
> +++ b/arch/arm64/include/asm/page.h
> @@ -24,6 +24,9 @@
>   #ifdef CONFIG_ARM64_64K_PAGES
>   #define PAGE_SHIFT		16
>   #define CONT_SHIFT		5
> +#elif defined(CONFIG_ARM64_16K_PAGES)
> +#define PAGE_SHIFT		14
> +#define CONT_SHIFT		9
>   #else
>   #define PAGE_SHIFT		12
>   #define CONT_SHIFT		4

Suzuki,

Is CONT_SHIFT correct? I thought it should be 7? The ARM-ARM says that a 
contiguous 3rd level lookup is 128 entries.

Thanks,
	Jeremy

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

* Re: [PATCHv3 10/11] arm64: Add 16K page size support
  2015-10-14 15:40     ` Jeremy Linton
@ 2015-10-14 15:53       ` Suzuki K. Poulose
  -1 siblings, 0 replies; 110+ messages in thread
From: Suzuki K. Poulose @ 2015-10-14 15:53 UTC (permalink / raw)
  To: Jeremy Linton, linux-arm-kernel
  Cc: linux-kernel, catalin.marinas, will.deacon, mark.rutland,
	steve.capper, marc.zyngier, ard.biesheuvel, christoffer.dall

On 14/10/15 16:40, Jeremy Linton wrote:
> On 10/14/2015 06:20 AM, Suzuki K. Poulose wrote:
>> diff --git a/arch/arm64/include/asm/page.h b/arch/arm64/include/asm/page.h
>> index da32354..736ed4c 100644
>> --- a/arch/arm64/include/asm/page.h
>> +++ b/arch/arm64/include/asm/page.h
>> @@ -24,6 +24,9 @@
>>   #ifdef CONFIG_ARM64_64K_PAGES
>>   #define PAGE_SHIFT        16
>>   #define CONT_SHIFT        5
>> +#elif defined(CONFIG_ARM64_16K_PAGES)
>> +#define PAGE_SHIFT        14
>> +#define CONT_SHIFT        9
>>   #else
>>   #define PAGE_SHIFT        12
>>   #define CONT_SHIFT        4
>
> Suzuki,
>
> Is CONT_SHIFT correct? I thought it should be 7? The ARM-ARM says that a contiguous 3rd level lookup is 128 entries.
>

Err, you are right. I tested it with 9 and I still got contiguous
mappings. May be because we anyway have 7 contiguous bits and the
kernel text is read-only. I will fix that, thanks for spotting.

Suzuki


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

* [PATCHv3 10/11] arm64: Add 16K page size support
@ 2015-10-14 15:53       ` Suzuki K. Poulose
  0 siblings, 0 replies; 110+ messages in thread
From: Suzuki K. Poulose @ 2015-10-14 15:53 UTC (permalink / raw)
  To: linux-arm-kernel

On 14/10/15 16:40, Jeremy Linton wrote:
> On 10/14/2015 06:20 AM, Suzuki K. Poulose wrote:
>> diff --git a/arch/arm64/include/asm/page.h b/arch/arm64/include/asm/page.h
>> index da32354..736ed4c 100644
>> --- a/arch/arm64/include/asm/page.h
>> +++ b/arch/arm64/include/asm/page.h
>> @@ -24,6 +24,9 @@
>>   #ifdef CONFIG_ARM64_64K_PAGES
>>   #define PAGE_SHIFT        16
>>   #define CONT_SHIFT        5
>> +#elif defined(CONFIG_ARM64_16K_PAGES)
>> +#define PAGE_SHIFT        14
>> +#define CONT_SHIFT        9
>>   #else
>>   #define PAGE_SHIFT        12
>>   #define CONT_SHIFT        4
>
> Suzuki,
>
> Is CONT_SHIFT correct? I thought it should be 7? The ARM-ARM says that a contiguous 3rd level lookup is 128 entries.
>

Err, you are right. I tested it with 9 and I still got contiguous
mappings. May be because we anyway have 7 contiguous bits and the
kernel text is read-only. I will fix that, thanks for spotting.

Suzuki

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

* Re: [PATCHv3 03/11] arm64: Introduce helpers for page table levels
  2015-10-14 11:20   ` Suzuki K. Poulose
@ 2015-10-14 17:07     ` Mark Rutland
  -1 siblings, 0 replies; 110+ messages in thread
From: Mark Rutland @ 2015-10-14 17:07 UTC (permalink / raw)
  To: Suzuki K. Poulose
  Cc: linux-arm-kernel, linux-kernel, catalin.marinas, will.deacon,
	steve.capper, marc.zyngier, ard.biesheuvel, christoffer.dall

On Wed, Oct 14, 2015 at 12:20:26PM +0100, Suzuki K. Poulose wrote:
> Introduce helpers for finding the number of page table
> levels required for a given VA width, shift for a particular
> page table level.
> 
> Convert the existing users to the new helpers. More users
> to follow.
> 
> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>
> Cc: Marc Zyngier <marc.zyngier@arm.com>
> Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com>
> 
> ---
> Changes since V2:
>   - Add comments around the macros
>   - Change ARM64_HW_PGTABLE_LEVEL_SHIFT to accept pagetable level as
>     described by ARM ARM
> ---
>  arch/arm64/include/asm/pgtable-hwdef.h |   25 ++++++++++++++++++++++---
>  1 file changed, 22 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/pgtable-hwdef.h b/arch/arm64/include/asm/pgtable-hwdef.h
> index 95c1ec0..c6194ab 100644
> --- a/arch/arm64/include/asm/pgtable-hwdef.h
> +++ b/arch/arm64/include/asm/pgtable-hwdef.h
> @@ -16,13 +16,31 @@
>  #ifndef __ASM_PGTABLE_HWDEF_H
>  #define __ASM_PGTABLE_HWDEF_H
>  
> +/*
> + * Number of page-table levels required to address 'va_bits' wide
> + * address, without section mapping. We resolve the top (va_bits - PAGE_SHIFT)
> + * bits with (PAGE_SHIFT - 3) bits at each page table level. Hence:
> + *
> + *  levels = DIV_ROUND_UP((va_bits - PAGE_SHIFT), (PAGE_SHIFT - 3))
> + *
> + * We cannot include linux/kernel.h which defines DIV_ROUND_UP here
> + * due to build issues. So we use the following magic formula.
> + */
> +#define ARM64_HW_PGTABLE_LEVELS(va_bits) (((va_bits) - 4) / (PAGE_SHIFT - 3))

I think I failed the interview question [1]. :(

I read the comment to mean this was a brand-new piece of magic, as
opposed to a constant-folded copy of DIV_ROUND_UP. So it seems there's
still some scope for confusion, even if that only includes me.

I think we should bite the bullet and have a full copy of DIV_ROUND_UP,
e.g.

/*
 * We cannot include linux/kernel.h for DIV_ROUND_UP due to build
 * issues. Instead, copy & paste its magic formula here for now.
 */
#define __DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))

/*
 * Number of page-table levels required to address 'va_bits' wide
 * address, without section mapping. We resolve the top (va_bits - PAGE_SHIFT)
 * bits with (PAGE_SHIFT - 3) bits at each page table level.
 */
#define ARM64_HW_PGTABLE_LEVELS(va_bits) \
	__DIV_ROUND_UP((va_bits - PAGE_SHIFT), (PAGE_SHIFT - 3))


It's a little verbose, but it keeps this legible and ensures I get the
job. We can leave the constant-folding to the compiler.

Other than that, this looks good to me. With the above applied:

Acked-by: Mark Rutland <mark.rutland@arm.com>

Thanks,
Mark.

[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2015-October/375609.html

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

* [PATCHv3 03/11] arm64: Introduce helpers for page table levels
@ 2015-10-14 17:07     ` Mark Rutland
  0 siblings, 0 replies; 110+ messages in thread
From: Mark Rutland @ 2015-10-14 17:07 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Oct 14, 2015 at 12:20:26PM +0100, Suzuki K. Poulose wrote:
> Introduce helpers for finding the number of page table
> levels required for a given VA width, shift for a particular
> page table level.
> 
> Convert the existing users to the new helpers. More users
> to follow.
> 
> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>
> Cc: Marc Zyngier <marc.zyngier@arm.com>
> Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com>
> 
> ---
> Changes since V2:
>   - Add comments around the macros
>   - Change ARM64_HW_PGTABLE_LEVEL_SHIFT to accept pagetable level as
>     described by ARM ARM
> ---
>  arch/arm64/include/asm/pgtable-hwdef.h |   25 ++++++++++++++++++++++---
>  1 file changed, 22 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/pgtable-hwdef.h b/arch/arm64/include/asm/pgtable-hwdef.h
> index 95c1ec0..c6194ab 100644
> --- a/arch/arm64/include/asm/pgtable-hwdef.h
> +++ b/arch/arm64/include/asm/pgtable-hwdef.h
> @@ -16,13 +16,31 @@
>  #ifndef __ASM_PGTABLE_HWDEF_H
>  #define __ASM_PGTABLE_HWDEF_H
>  
> +/*
> + * Number of page-table levels required to address 'va_bits' wide
> + * address, without section mapping. We resolve the top (va_bits - PAGE_SHIFT)
> + * bits with (PAGE_SHIFT - 3) bits at each page table level. Hence:
> + *
> + *  levels = DIV_ROUND_UP((va_bits - PAGE_SHIFT), (PAGE_SHIFT - 3))
> + *
> + * We cannot include linux/kernel.h which defines DIV_ROUND_UP here
> + * due to build issues. So we use the following magic formula.
> + */
> +#define ARM64_HW_PGTABLE_LEVELS(va_bits) (((va_bits) - 4) / (PAGE_SHIFT - 3))

I think I failed the interview question [1]. :(

I read the comment to mean this was a brand-new piece of magic, as
opposed to a constant-folded copy of DIV_ROUND_UP. So it seems there's
still some scope for confusion, even if that only includes me.

I think we should bite the bullet and have a full copy of DIV_ROUND_UP,
e.g.

/*
 * We cannot include linux/kernel.h for DIV_ROUND_UP due to build
 * issues. Instead, copy & paste its magic formula here for now.
 */
#define __DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))

/*
 * Number of page-table levels required to address 'va_bits' wide
 * address, without section mapping. We resolve the top (va_bits - PAGE_SHIFT)
 * bits with (PAGE_SHIFT - 3) bits at each page table level.
 */
#define ARM64_HW_PGTABLE_LEVELS(va_bits) \
	__DIV_ROUND_UP((va_bits - PAGE_SHIFT), (PAGE_SHIFT - 3))


It's a little verbose, but it keeps this legible and ensures I get the
job. We can leave the constant-folding to the compiler.

Other than that, this looks good to me. With the above applied:

Acked-by: Mark Rutland <mark.rutland@arm.com>

Thanks,
Mark.

[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2015-October/375609.html

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

* Re: [PATCHv3 04/11] arm64: Calculate size for idmap_pg_dir at compile time
  2015-10-14 11:20   ` Suzuki K. Poulose
@ 2015-10-14 17:12     ` Mark Rutland
  -1 siblings, 0 replies; 110+ messages in thread
From: Mark Rutland @ 2015-10-14 17:12 UTC (permalink / raw)
  To: Suzuki K. Poulose
  Cc: linux-arm-kernel, linux-kernel, catalin.marinas, will.deacon,
	steve.capper, marc.zyngier, ard.biesheuvel, christoffer.dall

On Wed, Oct 14, 2015 at 12:20:27PM +0100, Suzuki K. Poulose wrote:
> Now that we can calculate the number of levels required for
> mapping a va width, reserve exact number of pages that would
> be required to cover the idmap. The idmap should be able to handle
> the maximum physical address size supported.
> 
> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>
> Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com>
> Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Tested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
>  arch/arm64/include/asm/kernel-pgtable.h |    7 +++++--
>  1 file changed, 5 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/kernel-pgtable.h b/arch/arm64/include/asm/kernel-pgtable.h
> index 5876a36..def7168 100644
> --- a/arch/arm64/include/asm/kernel-pgtable.h
> +++ b/arch/arm64/include/asm/kernel-pgtable.h
> @@ -33,16 +33,19 @@
>   * map to pte level. The swapper also maps the FDT (see __create_page_tables
>   * for more information). Note that the number of ID map translation levels
>   * could be increased on the fly if system RAM is out of reach for the default
> - * VA range, so 3 pages are reserved in all cases.
> + * VA range, so pages required to map highest possible PA are reserved in all
> + * cases.
>   */
>  #if ARM64_SWAPPER_USES_SECTION_MAPS
>  #define SWAPPER_PGTABLE_LEVELS	(CONFIG_PGTABLE_LEVELS - 1)
> +#define IDMAP_PGTABLE_LEVELS	(ARM64_HW_PGTABLE_LEVELS(PHYS_MASK_SHIFT) - 1)
>  #else
>  #define SWAPPER_PGTABLE_LEVELS	(CONFIG_PGTABLE_LEVELS)
> +#define IDMAP_PGTABLE_LEVELS	(ARM64_HW_PGTABLE_LEVELS(PHYS_MASK_SHIFT))
>  #endif
>  
>  #define SWAPPER_DIR_SIZE	(SWAPPER_PGTABLE_LEVELS * PAGE_SIZE)
> -#define IDMAP_DIR_SIZE		(3 * PAGE_SIZE)
> +#define IDMAP_DIR_SIZE		(IDMAP_PGTABLE_LEVELS * PAGE_SIZE)

Acked-by: Mark Rutland <mark.rutland@arm.com>

Thanks,
Mark.

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

* [PATCHv3 04/11] arm64: Calculate size for idmap_pg_dir at compile time
@ 2015-10-14 17:12     ` Mark Rutland
  0 siblings, 0 replies; 110+ messages in thread
From: Mark Rutland @ 2015-10-14 17:12 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Oct 14, 2015 at 12:20:27PM +0100, Suzuki K. Poulose wrote:
> Now that we can calculate the number of levels required for
> mapping a va width, reserve exact number of pages that would
> be required to cover the idmap. The idmap should be able to handle
> the maximum physical address size supported.
> 
> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>
> Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com>
> Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Tested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
>  arch/arm64/include/asm/kernel-pgtable.h |    7 +++++--
>  1 file changed, 5 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/kernel-pgtable.h b/arch/arm64/include/asm/kernel-pgtable.h
> index 5876a36..def7168 100644
> --- a/arch/arm64/include/asm/kernel-pgtable.h
> +++ b/arch/arm64/include/asm/kernel-pgtable.h
> @@ -33,16 +33,19 @@
>   * map to pte level. The swapper also maps the FDT (see __create_page_tables
>   * for more information). Note that the number of ID map translation levels
>   * could be increased on the fly if system RAM is out of reach for the default
> - * VA range, so 3 pages are reserved in all cases.
> + * VA range, so pages required to map highest possible PA are reserved in all
> + * cases.
>   */
>  #if ARM64_SWAPPER_USES_SECTION_MAPS
>  #define SWAPPER_PGTABLE_LEVELS	(CONFIG_PGTABLE_LEVELS - 1)
> +#define IDMAP_PGTABLE_LEVELS	(ARM64_HW_PGTABLE_LEVELS(PHYS_MASK_SHIFT) - 1)
>  #else
>  #define SWAPPER_PGTABLE_LEVELS	(CONFIG_PGTABLE_LEVELS)
> +#define IDMAP_PGTABLE_LEVELS	(ARM64_HW_PGTABLE_LEVELS(PHYS_MASK_SHIFT))
>  #endif
>  
>  #define SWAPPER_DIR_SIZE	(SWAPPER_PGTABLE_LEVELS * PAGE_SIZE)
> -#define IDMAP_DIR_SIZE		(3 * PAGE_SIZE)
> +#define IDMAP_DIR_SIZE		(IDMAP_PGTABLE_LEVELS * PAGE_SIZE)

Acked-by: Mark Rutland <mark.rutland@arm.com>

Thanks,
Mark.

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

* Re: [PATCHv3 05/11] arm64: Handle 4 level page table for swapper
  2015-10-14 11:20   ` Suzuki K. Poulose
@ 2015-10-14 17:15     ` Mark Rutland
  -1 siblings, 0 replies; 110+ messages in thread
From: Mark Rutland @ 2015-10-14 17:15 UTC (permalink / raw)
  To: Suzuki K. Poulose
  Cc: linux-arm-kernel, linux-kernel, catalin.marinas, will.deacon,
	steve.capper, marc.zyngier, ard.biesheuvel, christoffer.dall

On Wed, Oct 14, 2015 at 12:20:28PM +0100, Suzuki K. Poulose wrote:
> At the moment, we only support maximum of 3-level page table for
> swapper. With 48bit VA, 64K has only 3 levels and 4K uses section
> mapping. Add support for 4-level page table for swapper, needed
> by 16K pages.
> 
> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>
> Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com>
> Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Tested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
>  arch/arm64/kernel/head.S |    5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
> index 149fce3..7ace955 100644
> --- a/arch/arm64/kernel/head.S
> +++ b/arch/arm64/kernel/head.S
> @@ -271,7 +271,10 @@ ENDPROC(preserve_boot_args)
>   */
>  	.macro	create_pgd_entry, tbl, virt, tmp1, tmp2
>  	create_table_entry \tbl, \virt, PGDIR_SHIFT, PTRS_PER_PGD, \tmp1, \tmp2
> -#if SWAPPER_PGTABLE_LEVELS == 3
> +#if SWAPPER_PGTABLE_LEVELS > 3
> +	create_table_entry \tbl, \virt, PUD_SHIFT, PTRS_PER_PUD, \tmp1, \tmp2
> +#endif
> +#if SWAPPER_PGTABLE_LEVELS > 2
>  	create_table_entry \tbl, \virt, SWAPPER_TABLE_SHIFT, PTRS_PER_PTE, \tmp1, \tmp2
>  #endif
>  	.endm

Acked-by: Mark Rutland <mark.rutland@arm.com>

Thanks,
Mark.

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

* [PATCHv3 05/11] arm64: Handle 4 level page table for swapper
@ 2015-10-14 17:15     ` Mark Rutland
  0 siblings, 0 replies; 110+ messages in thread
From: Mark Rutland @ 2015-10-14 17:15 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Oct 14, 2015 at 12:20:28PM +0100, Suzuki K. Poulose wrote:
> At the moment, we only support maximum of 3-level page table for
> swapper. With 48bit VA, 64K has only 3 levels and 4K uses section
> mapping. Add support for 4-level page table for swapper, needed
> by 16K pages.
> 
> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>
> Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com>
> Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Tested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
>  arch/arm64/kernel/head.S |    5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
> index 149fce3..7ace955 100644
> --- a/arch/arm64/kernel/head.S
> +++ b/arch/arm64/kernel/head.S
> @@ -271,7 +271,10 @@ ENDPROC(preserve_boot_args)
>   */
>  	.macro	create_pgd_entry, tbl, virt, tmp1, tmp2
>  	create_table_entry \tbl, \virt, PGDIR_SHIFT, PTRS_PER_PGD, \tmp1, \tmp2
> -#if SWAPPER_PGTABLE_LEVELS == 3
> +#if SWAPPER_PGTABLE_LEVELS > 3
> +	create_table_entry \tbl, \virt, PUD_SHIFT, PTRS_PER_PUD, \tmp1, \tmp2
> +#endif
> +#if SWAPPER_PGTABLE_LEVELS > 2
>  	create_table_entry \tbl, \virt, SWAPPER_TABLE_SHIFT, PTRS_PER_PTE, \tmp1, \tmp2
>  #endif
>  	.endm

Acked-by: Mark Rutland <mark.rutland@arm.com>

Thanks,
Mark.

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

* Re: [PATCHv3 07/11] arm64: Kconfig: Fix help text about AArch32 support with 64K pages
  2015-10-14 11:20   ` Suzuki K. Poulose
@ 2015-10-14 17:16     ` Mark Rutland
  -1 siblings, 0 replies; 110+ messages in thread
From: Mark Rutland @ 2015-10-14 17:16 UTC (permalink / raw)
  To: Suzuki K. Poulose
  Cc: linux-arm-kernel, linux-kernel, catalin.marinas, will.deacon,
	steve.capper, marc.zyngier, ard.biesheuvel, christoffer.dall

On Wed, Oct 14, 2015 at 12:20:30PM +0100, Suzuki K. Poulose wrote:
> Update the help text for ARM64_64K_PAGES to reflect the reality
> about AArch32 support.
> 
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>
> Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com>
> Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Tested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
>  arch/arm64/Kconfig |    4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index 4654c27..13b51a0 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -368,8 +368,8 @@ config ARM64_64K_PAGES
>  	help
>  	  This feature enables 64KB pages support (4KB by default)
>  	  allowing only two levels of page tables and faster TLB
> -	  look-up. AArch32 emulation is not available when this feature
> -	  is enabled.
> +	  look-up. AArch32 emulation requires applications compiled
> +	  with 64K aligned segments.
>  
>  endchoice

Acked-by: Mark Rutland <mark.rutland@arm.com>

Thanks,
Mark.

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

* [PATCHv3 07/11] arm64: Kconfig: Fix help text about AArch32 support with 64K pages
@ 2015-10-14 17:16     ` Mark Rutland
  0 siblings, 0 replies; 110+ messages in thread
From: Mark Rutland @ 2015-10-14 17:16 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Oct 14, 2015 at 12:20:30PM +0100, Suzuki K. Poulose wrote:
> Update the help text for ARM64_64K_PAGES to reflect the reality
> about AArch32 support.
> 
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>
> Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com>
> Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Tested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
>  arch/arm64/Kconfig |    4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index 4654c27..13b51a0 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -368,8 +368,8 @@ config ARM64_64K_PAGES
>  	help
>  	  This feature enables 64KB pages support (4KB by default)
>  	  allowing only two levels of page tables and faster TLB
> -	  look-up. AArch32 emulation is not available when this feature
> -	  is enabled.
> +	  look-up. AArch32 emulation requires applications compiled
> +	  with 64K aligned segments.
>  
>  endchoice

Acked-by: Mark Rutland <mark.rutland@arm.com>

Thanks,
Mark.

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

* Re: [PATCHv3 08/11] arm64: Check for selected granule support
  2015-10-14 11:20   ` Suzuki K. Poulose
@ 2015-10-14 17:24     ` Mark Rutland
  -1 siblings, 0 replies; 110+ messages in thread
From: Mark Rutland @ 2015-10-14 17:24 UTC (permalink / raw)
  To: Suzuki K. Poulose
  Cc: linux-arm-kernel, linux-kernel, catalin.marinas, will.deacon,
	steve.capper, marc.zyngier, ard.biesheuvel, christoffer.dall

> @@ -613,10 +614,28 @@ ENDPROC(__secondary_switched)
>   *  x0  = SCTLR_EL1 value for turning on the MMU.
>   *  x27 = *virtual* address to jump to upon completion
>   *
> - * other registers depend on the function called upon completion
> + * Other registers depend on the function called upon completion.
> + *
> + * Checks if the selected granule size is supported by the CPU.
> + * If it doesn't park the CPU

Nit: "If it isn't, park the CPU."

>   */
> +#if	defined(CONFIG_ARM64_64K_PAGES)
> +
> +#define id_aa64mmfr0_tgran_shift	ID_AA64MMFR0_TGRAN64_SHIFT
> +#define id_aa64mmfr0_tgran_on		ID_AA64MMFR0_TGRAN64_ON
> +
> +#else
> +
> +#define id_aa64mmfr0_tgran_shift	ID_AA64MMFR0_TGRAN4_SHIFT
> +#define id_aa64mmfr0_tgran_on		ID_AA64MMFR0_TGRAN4_ON

Any reason for not using upper-case names for the macros?

Given they're local you could just call them TGRAN_SHIFT and TRGRAN_ON
to make the asm slightly nicer.

> +
> +#endif
>  	.section	".idmap.text", "ax"
>  __enable_mmu:
> +	mrs	x1, ID_AA64MMFR0_EL1
> +	ubfx	x2, x1, #id_aa64mmfr0_tgran_shift, 4
> +	cmp	x2, #id_aa64mmfr0_tgran_on
> +	b.ne	__no_granule_support
>  	ldr	x5, =vectors
>  	msr	vbar_el1, x5
>  	msr	ttbr0_el1, x25			// load TTBR0
> @@ -634,3 +653,8 @@ __enable_mmu:
>  	isb
>  	br	x27
>  ENDPROC(__enable_mmu)
> +
> +__no_granule_support:
> +	wfe
> +	b __no_granule_support
> +ENDPROC(__no_granule_support)

Other than the above, this loogs fine to me.

In future it would be nice if we could somehow signal that these dead
CPUs are trapped in the kernel -- we should have some kind of canary
mechanism for that. That needn't block this patch, though.

Thanks,
Mark.

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

* [PATCHv3 08/11] arm64: Check for selected granule support
@ 2015-10-14 17:24     ` Mark Rutland
  0 siblings, 0 replies; 110+ messages in thread
From: Mark Rutland @ 2015-10-14 17:24 UTC (permalink / raw)
  To: linux-arm-kernel

> @@ -613,10 +614,28 @@ ENDPROC(__secondary_switched)
>   *  x0  = SCTLR_EL1 value for turning on the MMU.
>   *  x27 = *virtual* address to jump to upon completion
>   *
> - * other registers depend on the function called upon completion
> + * Other registers depend on the function called upon completion.
> + *
> + * Checks if the selected granule size is supported by the CPU.
> + * If it doesn't park the CPU

Nit: "If it isn't, park the CPU."

>   */
> +#if	defined(CONFIG_ARM64_64K_PAGES)
> +
> +#define id_aa64mmfr0_tgran_shift	ID_AA64MMFR0_TGRAN64_SHIFT
> +#define id_aa64mmfr0_tgran_on		ID_AA64MMFR0_TGRAN64_ON
> +
> +#else
> +
> +#define id_aa64mmfr0_tgran_shift	ID_AA64MMFR0_TGRAN4_SHIFT
> +#define id_aa64mmfr0_tgran_on		ID_AA64MMFR0_TGRAN4_ON

Any reason for not using upper-case names for the macros?

Given they're local you could just call them TGRAN_SHIFT and TRGRAN_ON
to make the asm slightly nicer.

> +
> +#endif
>  	.section	".idmap.text", "ax"
>  __enable_mmu:
> +	mrs	x1, ID_AA64MMFR0_EL1
> +	ubfx	x2, x1, #id_aa64mmfr0_tgran_shift, 4
> +	cmp	x2, #id_aa64mmfr0_tgran_on
> +	b.ne	__no_granule_support
>  	ldr	x5, =vectors
>  	msr	vbar_el1, x5
>  	msr	ttbr0_el1, x25			// load TTBR0
> @@ -634,3 +653,8 @@ __enable_mmu:
>  	isb
>  	br	x27
>  ENDPROC(__enable_mmu)
> +
> +__no_granule_support:
> +	wfe
> +	b __no_granule_support
> +ENDPROC(__no_granule_support)

Other than the above, this loogs fine to me.

In future it would be nice if we could somehow signal that these dead
CPUs are trapped in the kernel -- we should have some kind of canary
mechanism for that. That needn't block this patch, though.

Thanks,
Mark.

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

* Re: [PATCHv3 09/11] arm64: Add page size to the kernel image header
  2015-10-14 11:20   ` Suzuki K. Poulose
@ 2015-10-14 17:27     ` Mark Rutland
  -1 siblings, 0 replies; 110+ messages in thread
From: Mark Rutland @ 2015-10-14 17:27 UTC (permalink / raw)
  To: Suzuki K. Poulose
  Cc: linux-arm-kernel, linux-kernel, catalin.marinas, will.deacon,
	steve.capper, marc.zyngier, ard.biesheuvel, christoffer.dall

On Wed, Oct 14, 2015 at 12:20:32PM +0100, Suzuki K. Poulose wrote:
> From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> 
> This patch adds the page size to the arm64 kernel image header
> so that one can infer the PAGESIZE used by the kernel. This will
> be helpful to diagnose failures to boot the kernel with page size
> not supported by the CPU.
> 
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com>
> Acked-by: Catalin Marinas <catalin.marinas@arm.com>
> Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
> ---
>  Documentation/arm64/booting.txt |    7 ++++++-
>  arch/arm64/kernel/image.h       |    5 ++++-
>  2 files changed, 10 insertions(+), 2 deletions(-)
> 
> diff --git a/Documentation/arm64/booting.txt b/Documentation/arm64/booting.txt
> index 7d9d3c2..aaf6d77 100644
> --- a/Documentation/arm64/booting.txt
> +++ b/Documentation/arm64/booting.txt
> @@ -104,7 +104,12 @@ Header notes:
>  - The flags field (introduced in v3.17) is a little-endian 64-bit field
>    composed as follows:
>    Bit 0:	Kernel endianness.  1 if BE, 0 if LE.
> -  Bits 1-63:	Reserved.
> +  Bit 1-2:	Kernel Page size.
> +			0 - Unspecified.
> +			1 - 4K
> +			2 - 16K
> +			3 - 64K
> +  Bits 3-63:	Reserved.
>  
>  - When image_size is zero, a bootloader should attempt to keep as much
>    memory as possible free for use by the kernel immediately after the
> diff --git a/arch/arm64/kernel/image.h b/arch/arm64/kernel/image.h
> index 6eb8fee..e45759e 100644
> --- a/arch/arm64/kernel/image.h
> +++ b/arch/arm64/kernel/image.h
> @@ -47,7 +47,10 @@
>  #define __HEAD_FLAG_BE	0
>  #endif
>  
> -#define __HEAD_FLAGS	(__HEAD_FLAG_BE << 0)
> +#define __HEAD_FLAG_PAGE_SIZE ((PAGE_SHIFT - 10) / 2)
> +
> +#define __HEAD_FLAGS	(__HEAD_FLAG_BE << 0) |		\
> +			(__HEAD_FLAG_PAGE_SIZE << 1)

I'd prefer that we also had brackets around the whole of the
__HEAD_FLAGS value, so we don't get caught out later on by some
unexpected expansion (though we are safe currently).

With that:

Acked-by: Mark Rutland <mark.rutland@arm.com>

Thanks,
Mark.

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

* [PATCHv3 09/11] arm64: Add page size to the kernel image header
@ 2015-10-14 17:27     ` Mark Rutland
  0 siblings, 0 replies; 110+ messages in thread
From: Mark Rutland @ 2015-10-14 17:27 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Oct 14, 2015 at 12:20:32PM +0100, Suzuki K. Poulose wrote:
> From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> 
> This patch adds the page size to the arm64 kernel image header
> so that one can infer the PAGESIZE used by the kernel. This will
> be helpful to diagnose failures to boot the kernel with page size
> not supported by the CPU.
> 
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com>
> Acked-by: Catalin Marinas <catalin.marinas@arm.com>
> Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
> ---
>  Documentation/arm64/booting.txt |    7 ++++++-
>  arch/arm64/kernel/image.h       |    5 ++++-
>  2 files changed, 10 insertions(+), 2 deletions(-)
> 
> diff --git a/Documentation/arm64/booting.txt b/Documentation/arm64/booting.txt
> index 7d9d3c2..aaf6d77 100644
> --- a/Documentation/arm64/booting.txt
> +++ b/Documentation/arm64/booting.txt
> @@ -104,7 +104,12 @@ Header notes:
>  - The flags field (introduced in v3.17) is a little-endian 64-bit field
>    composed as follows:
>    Bit 0:	Kernel endianness.  1 if BE, 0 if LE.
> -  Bits 1-63:	Reserved.
> +  Bit 1-2:	Kernel Page size.
> +			0 - Unspecified.
> +			1 - 4K
> +			2 - 16K
> +			3 - 64K
> +  Bits 3-63:	Reserved.
>  
>  - When image_size is zero, a bootloader should attempt to keep as much
>    memory as possible free for use by the kernel immediately after the
> diff --git a/arch/arm64/kernel/image.h b/arch/arm64/kernel/image.h
> index 6eb8fee..e45759e 100644
> --- a/arch/arm64/kernel/image.h
> +++ b/arch/arm64/kernel/image.h
> @@ -47,7 +47,10 @@
>  #define __HEAD_FLAG_BE	0
>  #endif
>  
> -#define __HEAD_FLAGS	(__HEAD_FLAG_BE << 0)
> +#define __HEAD_FLAG_PAGE_SIZE ((PAGE_SHIFT - 10) / 2)
> +
> +#define __HEAD_FLAGS	(__HEAD_FLAG_BE << 0) |		\
> +			(__HEAD_FLAG_PAGE_SIZE << 1)

I'd prefer that we also had brackets around the whole of the
__HEAD_FLAGS value, so we don't get caught out later on by some
unexpected expansion (though we are safe currently).

With that:

Acked-by: Mark Rutland <mark.rutland@arm.com>

Thanks,
Mark.

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

* Re: [PATCHv3 08/11] arm64: Check for selected granule support
  2015-10-14 17:24     ` Mark Rutland
@ 2015-10-14 17:32       ` Mark Rutland
  -1 siblings, 0 replies; 110+ messages in thread
From: Mark Rutland @ 2015-10-14 17:32 UTC (permalink / raw)
  To: Suzuki K. Poulose
  Cc: steve.capper, ard.biesheuvel, marc.zyngier, catalin.marinas,
	will.deacon, linux-kernel, christoffer.dall, linux-arm-kernel

On Wed, Oct 14, 2015 at 06:24:18PM +0100, Mark Rutland wrote:
> > @@ -613,10 +614,28 @@ ENDPROC(__secondary_switched)
> >   *  x0  = SCTLR_EL1 value for turning on the MMU.
> >   *  x27 = *virtual* address to jump to upon completion
> >   *
> > - * other registers depend on the function called upon completion
> > + * Other registers depend on the function called upon completion.
> > + *
> > + * Checks if the selected granule size is supported by the CPU.
> > + * If it doesn't park the CPU
> 
> Nit: "If it isn't, park the CPU."
> 
> >   */
> > +#if	defined(CONFIG_ARM64_64K_PAGES)
> > +
> > +#define id_aa64mmfr0_tgran_shift	ID_AA64MMFR0_TGRAN64_SHIFT
> > +#define id_aa64mmfr0_tgran_on		ID_AA64MMFR0_TGRAN64_ON
> > +
> > +#else
> > +
> > +#define id_aa64mmfr0_tgran_shift	ID_AA64MMFR0_TGRAN4_SHIFT
> > +#define id_aa64mmfr0_tgran_on		ID_AA64MMFR0_TGRAN4_ON
> 
> Any reason for not using upper-case names for the macros?
> 
> Given they're local you could just call them TGRAN_SHIFT and TRGRAN_ON
> to make the asm slightly nicer.

Actually, even better, s/TGRAN_ON/TGRAN_SUPPORTED/

Mark.

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

* [PATCHv3 08/11] arm64: Check for selected granule support
@ 2015-10-14 17:32       ` Mark Rutland
  0 siblings, 0 replies; 110+ messages in thread
From: Mark Rutland @ 2015-10-14 17:32 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Oct 14, 2015 at 06:24:18PM +0100, Mark Rutland wrote:
> > @@ -613,10 +614,28 @@ ENDPROC(__secondary_switched)
> >   *  x0  = SCTLR_EL1 value for turning on the MMU.
> >   *  x27 = *virtual* address to jump to upon completion
> >   *
> > - * other registers depend on the function called upon completion
> > + * Other registers depend on the function called upon completion.
> > + *
> > + * Checks if the selected granule size is supported by the CPU.
> > + * If it doesn't park the CPU
> 
> Nit: "If it isn't, park the CPU."
> 
> >   */
> > +#if	defined(CONFIG_ARM64_64K_PAGES)
> > +
> > +#define id_aa64mmfr0_tgran_shift	ID_AA64MMFR0_TGRAN64_SHIFT
> > +#define id_aa64mmfr0_tgran_on		ID_AA64MMFR0_TGRAN64_ON
> > +
> > +#else
> > +
> > +#define id_aa64mmfr0_tgran_shift	ID_AA64MMFR0_TGRAN4_SHIFT
> > +#define id_aa64mmfr0_tgran_on		ID_AA64MMFR0_TGRAN4_ON
> 
> Any reason for not using upper-case names for the macros?
> 
> Given they're local you could just call them TGRAN_SHIFT and TRGRAN_ON
> to make the asm slightly nicer.

Actually, even better, s/TGRAN_ON/TGRAN_SUPPORTED/

Mark.

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

* Re: [PATCHv3 08/11] arm64: Check for selected granule support
  2015-10-14 11:20   ` Suzuki K. Poulose
@ 2015-10-14 21:13     ` Jeremy Linton
  -1 siblings, 0 replies; 110+ messages in thread
From: Jeremy Linton @ 2015-10-14 21:13 UTC (permalink / raw)
  To: Suzuki K. Poulose, linux-arm-kernel
  Cc: mark.rutland, steve.capper, ard.biesheuvel, marc.zyngier,
	catalin.marinas, will.deacon, linux-kernel, christoffer.dall

On 10/14/2015 06:20 AM, Suzuki K. Poulose wrote:

> + * Checks if the selected granule size is supported by the CPU.
> + * If it doesn't park the CPU

The problem is when you park the boot CPU.

I think for EFI there is a slightly better error mechanism. This tweak 
will print an error and return to the EFI boot manager rather than 
hanging the machine without any notification. Now it prints:

EFI stub: Booting Linux Kernel...
EFI stub: ERROR: 16K granule not supported by this machine
EFI stub: ERROR: Failed to relocate kernel
FS4:\>


Signed-off-by: Jeremy Linton <jeremy.linton@arm.com>
---
  arch/arm64/kernel/efi-stub.c | 14 ++++++++++++++
  1 file changed, 14 insertions(+)

diff --git a/arch/arm64/kernel/efi-stub.c b/arch/arm64/kernel/efi-stub.c
index 816120e..90fb868 100644
--- a/arch/arm64/kernel/efi-stub.c
+++ b/arch/arm64/kernel/efi-stub.c
@@ -25,6 +25,20 @@ efi_status_t __init 
handle_kernel_image(efi_system_table_t *sys_table_arg,
         unsigned long kernel_size, kernel_memsize = 0;
         unsigned long nr_pages;
         void *old_image_addr = (void *)*image_addr;
+       u32 aa64mmfr0_el1;
+
+#ifdef CONFIG_ARM64_16K_PAGES
+       /*
+        * check to see if this kernel image is
+        * compatible with the current system
+        */
+       asm volatile("mrs %0, ID_AA64MMFR0_EL1" : "=r" (aa64mmfr0_el1));
+       aa64mmfr0_el1 >>= ID_AA64MMFR0_TGRAN16_SHIFT;
+       if ((aa64mmfr0_el1 & ID_AA64MMFR0_TGRAN4_ON) == 0) {
+               pr_efi_err(sys_table_arg, "16K granule not supported by 
this machine\n");
+               return EFI_UNSUPPORTED;
+       }
+#endif

         /* Relocate the image, if required. */
         kernel_size = _edata - _text;
-- 
2.4.3








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

* [PATCHv3 08/11] arm64: Check for selected granule support
@ 2015-10-14 21:13     ` Jeremy Linton
  0 siblings, 0 replies; 110+ messages in thread
From: Jeremy Linton @ 2015-10-14 21:13 UTC (permalink / raw)
  To: linux-arm-kernel

On 10/14/2015 06:20 AM, Suzuki K. Poulose wrote:

> + * Checks if the selected granule size is supported by the CPU.
> + * If it doesn't park the CPU

The problem is when you park the boot CPU.

I think for EFI there is a slightly better error mechanism. This tweak 
will print an error and return to the EFI boot manager rather than 
hanging the machine without any notification. Now it prints:

EFI stub: Booting Linux Kernel...
EFI stub: ERROR: 16K granule not supported by this machine
EFI stub: ERROR: Failed to relocate kernel
FS4:\>


Signed-off-by: Jeremy Linton <jeremy.linton@arm.com>
---
  arch/arm64/kernel/efi-stub.c | 14 ++++++++++++++
  1 file changed, 14 insertions(+)

diff --git a/arch/arm64/kernel/efi-stub.c b/arch/arm64/kernel/efi-stub.c
index 816120e..90fb868 100644
--- a/arch/arm64/kernel/efi-stub.c
+++ b/arch/arm64/kernel/efi-stub.c
@@ -25,6 +25,20 @@ efi_status_t __init 
handle_kernel_image(efi_system_table_t *sys_table_arg,
         unsigned long kernel_size, kernel_memsize = 0;
         unsigned long nr_pages;
         void *old_image_addr = (void *)*image_addr;
+       u32 aa64mmfr0_el1;
+
+#ifdef CONFIG_ARM64_16K_PAGES
+       /*
+        * check to see if this kernel image is
+        * compatible with the current system
+        */
+       asm volatile("mrs %0, ID_AA64MMFR0_EL1" : "=r" (aa64mmfr0_el1));
+       aa64mmfr0_el1 >>= ID_AA64MMFR0_TGRAN16_SHIFT;
+       if ((aa64mmfr0_el1 & ID_AA64MMFR0_TGRAN4_ON) == 0) {
+               pr_efi_err(sys_table_arg, "16K granule not supported by 
this machine\n");
+               return EFI_UNSUPPORTED;
+       }
+#endif

         /* Relocate the image, if required. */
         kernel_size = _edata - _text;
-- 
2.4.3

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

* Re: [PATCHv3 09/11] arm64: Add page size to the kernel image header
  2015-10-14 17:27     ` Mark Rutland
@ 2015-10-15  9:19       ` Suzuki K. Poulose
  -1 siblings, 0 replies; 110+ messages in thread
From: Suzuki K. Poulose @ 2015-10-15  9:19 UTC (permalink / raw)
  To: Mark Rutland
  Cc: linux-arm-kernel, linux-kernel, catalin.marinas, will.deacon,
	steve.capper, marc.zyngier, ard.biesheuvel, christoffer.dall

On 14/10/15 18:27, Mark Rutland wrote:
> On Wed, Oct 14, 2015 at 12:20:32PM +0100, Suzuki K. Poulose wrote:
>> From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>>
>> This patch adds the page size to the arm64 kernel image header
>> so that one can infer the PAGESIZE used by the kernel. This will
>> be helpful to diagnose failures to boot the kernel with page size
>> not supported by the CPU.
>>
>> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>> Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com>
>> Acked-by: Catalin Marinas <catalin.marinas@arm.com>
>> Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
>> ---
>>   Documentation/arm64/booting.txt |    7 ++++++-
>>   arch/arm64/kernel/image.h       |    5 ++++-
>>   2 files changed, 10 insertions(+), 2 deletions(-)
>>
>> diff --git a/Documentation/arm64/booting.txt b/Documentation/arm64/booting.txt
>> index 7d9d3c2..aaf6d77 100644
>> --- a/Documentation/arm64/booting.txt
>> +++ b/Documentation/arm64/booting.txt
>> @@ -104,7 +104,12 @@ Header notes:
>>   - The flags field (introduced in v3.17) is a little-endian 64-bit field
>>     composed as follows:
>>     Bit 0:	Kernel endianness.  1 if BE, 0 if LE.
>> -  Bits 1-63:	Reserved.
>> +  Bit 1-2:	Kernel Page size.
>> +			0 - Unspecified.
>> +			1 - 4K
>> +			2 - 16K
>> +			3 - 64K
>> +  Bits 3-63:	Reserved.
>>
>>   - When image_size is zero, a bootloader should attempt to keep as much
>>     memory as possible free for use by the kernel immediately after the
>> diff --git a/arch/arm64/kernel/image.h b/arch/arm64/kernel/image.h
>> index 6eb8fee..e45759e 100644
>> --- a/arch/arm64/kernel/image.h
>> +++ b/arch/arm64/kernel/image.h
>> @@ -47,7 +47,10 @@
>>   #define __HEAD_FLAG_BE	0
>>   #endif
>>
>> -#define __HEAD_FLAGS	(__HEAD_FLAG_BE << 0)
>> +#define __HEAD_FLAG_PAGE_SIZE ((PAGE_SHIFT - 10) / 2)
>> +
>> +#define __HEAD_FLAGS	(__HEAD_FLAG_BE << 0) |		\
>> +			(__HEAD_FLAG_PAGE_SIZE << 1)
>
> I'd prefer that we also had brackets around the whole of the
> __HEAD_FLAGS value, so we don't get caught out later on by some
> unexpected expansion (though we are safe currently).
>

Sure, will add that.

> With that:
>
> Acked-by: Mark Rutland <mark.rutland@arm.com>

Thanks
Suzuki


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

* [PATCHv3 09/11] arm64: Add page size to the kernel image header
@ 2015-10-15  9:19       ` Suzuki K. Poulose
  0 siblings, 0 replies; 110+ messages in thread
From: Suzuki K. Poulose @ 2015-10-15  9:19 UTC (permalink / raw)
  To: linux-arm-kernel

On 14/10/15 18:27, Mark Rutland wrote:
> On Wed, Oct 14, 2015 at 12:20:32PM +0100, Suzuki K. Poulose wrote:
>> From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>>
>> This patch adds the page size to the arm64 kernel image header
>> so that one can infer the PAGESIZE used by the kernel. This will
>> be helpful to diagnose failures to boot the kernel with page size
>> not supported by the CPU.
>>
>> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>> Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com>
>> Acked-by: Catalin Marinas <catalin.marinas@arm.com>
>> Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
>> ---
>>   Documentation/arm64/booting.txt |    7 ++++++-
>>   arch/arm64/kernel/image.h       |    5 ++++-
>>   2 files changed, 10 insertions(+), 2 deletions(-)
>>
>> diff --git a/Documentation/arm64/booting.txt b/Documentation/arm64/booting.txt
>> index 7d9d3c2..aaf6d77 100644
>> --- a/Documentation/arm64/booting.txt
>> +++ b/Documentation/arm64/booting.txt
>> @@ -104,7 +104,12 @@ Header notes:
>>   - The flags field (introduced in v3.17) is a little-endian 64-bit field
>>     composed as follows:
>>     Bit 0:	Kernel endianness.  1 if BE, 0 if LE.
>> -  Bits 1-63:	Reserved.
>> +  Bit 1-2:	Kernel Page size.
>> +			0 - Unspecified.
>> +			1 - 4K
>> +			2 - 16K
>> +			3 - 64K
>> +  Bits 3-63:	Reserved.
>>
>>   - When image_size is zero, a bootloader should attempt to keep as much
>>     memory as possible free for use by the kernel immediately after the
>> diff --git a/arch/arm64/kernel/image.h b/arch/arm64/kernel/image.h
>> index 6eb8fee..e45759e 100644
>> --- a/arch/arm64/kernel/image.h
>> +++ b/arch/arm64/kernel/image.h
>> @@ -47,7 +47,10 @@
>>   #define __HEAD_FLAG_BE	0
>>   #endif
>>
>> -#define __HEAD_FLAGS	(__HEAD_FLAG_BE << 0)
>> +#define __HEAD_FLAG_PAGE_SIZE ((PAGE_SHIFT - 10) / 2)
>> +
>> +#define __HEAD_FLAGS	(__HEAD_FLAG_BE << 0) |		\
>> +			(__HEAD_FLAG_PAGE_SIZE << 1)
>
> I'd prefer that we also had brackets around the whole of the
> __HEAD_FLAGS value, so we don't get caught out later on by some
> unexpected expansion (though we are safe currently).
>

Sure, will add that.

> With that:
>
> Acked-by: Mark Rutland <mark.rutland@arm.com>

Thanks
Suzuki

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

* Re: [PATCHv3 03/11] arm64: Introduce helpers for page table levels
  2015-10-14 17:07     ` Mark Rutland
@ 2015-10-15  9:35       ` Suzuki K. Poulose
  -1 siblings, 0 replies; 110+ messages in thread
From: Suzuki K. Poulose @ 2015-10-15  9:35 UTC (permalink / raw)
  To: Mark Rutland
  Cc: linux-arm-kernel, linux-kernel, catalin.marinas, will.deacon,
	steve.capper, marc.zyngier, ard.biesheuvel, christoffer.dall

On 14/10/15 18:07, Mark Rutland wrote:
> On Wed, Oct 14, 2015 at 12:20:26PM +0100, Suzuki K. Poulose wrote:

>> + * Number of page-table levels required to address 'va_bits' wide
>> + * address, without section mapping. We resolve the top (va_bits - PAGE_SHIFT)
>> + * bits with (PAGE_SHIFT - 3) bits at each page table level. Hence:
>> + *
>> + *  levels = DIV_ROUND_UP((va_bits - PAGE_SHIFT), (PAGE_SHIFT - 3))
>> + *
>> + * We cannot include linux/kernel.h which defines DIV_ROUND_UP here
>> + * due to build issues. So we use the following magic formula.
>> + */
>> +#define ARM64_HW_PGTABLE_LEVELS(va_bits) (((va_bits) - 4) / (PAGE_SHIFT - 3))
>
> I think I failed the interview question [1]. :(
>
> I read the comment to mean this was a brand-new piece of magic, as
> opposed to a constant-folded copy of DIV_ROUND_UP. So it seems there's
> still some scope for confusion, even if that only includes me.
>

Wouldn't it be better to modify the comment to say, we open coded the DIV_ROUND_UP ?
We could potentially end up in a conflict if somebody else does __DIV_ROUND_UP.
I have seen similar issues with the CPU feature series, where if I include one
particular header file in another, kernel build breaks without giving you a clue,
what caused the error. Usually due to the multiple definitions (e.g NSEC_PER_SEC)
and other conflicts. Given that this header file gets included with asm/page.h and
hence would be used included for people outside arch/arm64, I would prefer, not to
head there, instead update the comment, something like this :


/*
  * Number of page-table levels required to address 'va_bits' wide
  * address, without section mapping. We resolve the top (va_bits - PAGE_SHIFT)
  * bits with (PAGE_SHIFT - 3) bits at each page table level. Hence:
  *
  *  levels = DIV_ROUND_UP((va_bits - PAGE_SHIFT), (PAGE_SHIFT - 3))
  *
  * where DIV_ROUND_UP (n, d) = > ((n) + (d) - 1) / (d)
  *
  * We cannot include linux/kernel.h which defines DIV_ROUND_UP here
  * due to build issues. So we open code the DIV_ROUND_UP and hence
  * we get :
  *  ((va_bits - PAGE_SHIFT) + (PAGE_SHIFT - 3) -1) / (PAGE_SHIFT - 3)
  *
  * which gets simplified as :
  *  (((va_bits) - 4) / (PAGE_SHIFT - 3))
  *
  */

Let me know if you are happy with that ?

Thanks
Suzuki


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

* [PATCHv3 03/11] arm64: Introduce helpers for page table levels
@ 2015-10-15  9:35       ` Suzuki K. Poulose
  0 siblings, 0 replies; 110+ messages in thread
From: Suzuki K. Poulose @ 2015-10-15  9:35 UTC (permalink / raw)
  To: linux-arm-kernel

On 14/10/15 18:07, Mark Rutland wrote:
> On Wed, Oct 14, 2015 at 12:20:26PM +0100, Suzuki K. Poulose wrote:

>> + * Number of page-table levels required to address 'va_bits' wide
>> + * address, without section mapping. We resolve the top (va_bits - PAGE_SHIFT)
>> + * bits with (PAGE_SHIFT - 3) bits at each page table level. Hence:
>> + *
>> + *  levels = DIV_ROUND_UP((va_bits - PAGE_SHIFT), (PAGE_SHIFT - 3))
>> + *
>> + * We cannot include linux/kernel.h which defines DIV_ROUND_UP here
>> + * due to build issues. So we use the following magic formula.
>> + */
>> +#define ARM64_HW_PGTABLE_LEVELS(va_bits) (((va_bits) - 4) / (PAGE_SHIFT - 3))
>
> I think I failed the interview question [1]. :(
>
> I read the comment to mean this was a brand-new piece of magic, as
> opposed to a constant-folded copy of DIV_ROUND_UP. So it seems there's
> still some scope for confusion, even if that only includes me.
>

Wouldn't it be better to modify the comment to say, we open coded the DIV_ROUND_UP ?
We could potentially end up in a conflict if somebody else does __DIV_ROUND_UP.
I have seen similar issues with the CPU feature series, where if I include one
particular header file in another, kernel build breaks without giving you a clue,
what caused the error. Usually due to the multiple definitions (e.g NSEC_PER_SEC)
and other conflicts. Given that this header file gets included with asm/page.h and
hence would be used included for people outside arch/arm64, I would prefer, not to
head there, instead update the comment, something like this :


/*
  * Number of page-table levels required to address 'va_bits' wide
  * address, without section mapping. We resolve the top (va_bits - PAGE_SHIFT)
  * bits with (PAGE_SHIFT - 3) bits at each page table level. Hence:
  *
  *  levels = DIV_ROUND_UP((va_bits - PAGE_SHIFT), (PAGE_SHIFT - 3))
  *
  * where DIV_ROUND_UP (n, d) = > ((n) + (d) - 1) / (d)
  *
  * We cannot include linux/kernel.h which defines DIV_ROUND_UP here
  * due to build issues. So we open code the DIV_ROUND_UP and hence
  * we get :
  *  ((va_bits - PAGE_SHIFT) + (PAGE_SHIFT - 3) -1) / (PAGE_SHIFT - 3)
  *
  * which gets simplified as :
  *  (((va_bits) - 4) / (PAGE_SHIFT - 3))
  *
  */

Let me know if you are happy with that ?

Thanks
Suzuki

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

* Re: [PATCHv3 08/11] arm64: Check for selected granule support
  2015-10-14 17:24     ` Mark Rutland
@ 2015-10-15  9:45       ` Suzuki K. Poulose
  -1 siblings, 0 replies; 110+ messages in thread
From: Suzuki K. Poulose @ 2015-10-15  9:45 UTC (permalink / raw)
  To: Mark Rutland
  Cc: linux-arm-kernel, linux-kernel, catalin.marinas, will.deacon,
	steve.capper, marc.zyngier, ard.biesheuvel, christoffer.dall

On 14/10/15 18:24, Mark Rutland wrote:

>> - * other registers depend on the function called upon completion
>> + * Other registers depend on the function called upon completion.
>> + *
>> + * Checks if the selected granule size is supported by the CPU.
>> + * If it doesn't park the CPU
>
> Nit: "If it isn't, park the CPU."

OK

>
>>    */
>> +#if	defined(CONFIG_ARM64_64K_PAGES)
>> +
>> +#define id_aa64mmfr0_tgran_shift	ID_AA64MMFR0_TGRAN64_SHIFT
>> +#define id_aa64mmfr0_tgran_on		ID_AA64MMFR0_TGRAN64_ON
>> +
>> +#else
>> +
>> +#define id_aa64mmfr0_tgran_shift	ID_AA64MMFR0_TGRAN4_SHIFT
>> +#define id_aa64mmfr0_tgran_on		ID_AA64MMFR0_TGRAN4_ON
>
> Any reason for not using upper-case names for the macros?

Nothing in particular. I had them in upper-case in the previous version,
changed it here ;) for absolutely no reason. I could switch it back.

> Given they're local you could just call them TGRAN_SHIFT and TRGRAN_ON
> to make the asm slightly nicer.

Given Jeremy's suggestion to add something to the EFI stub, I will retain
the original definition with all upper-case and define it somewhere in
a header so that we can reuse it.

>> +
>> +__no_granule_support:
>> +	wfe
>> +	b __no_granule_support
>> +ENDPROC(__no_granule_support)
>
> Other than the above, this loogs fine to me.
>
> In future it would be nice if we could somehow signal that these dead
> CPUs are trapped in the kernel -- we should have some kind of canary
> mechanism for that. That needn't block this patch, though.

Yes, we should.

Thanks for the review
Suzuki


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

* [PATCHv3 08/11] arm64: Check for selected granule support
@ 2015-10-15  9:45       ` Suzuki K. Poulose
  0 siblings, 0 replies; 110+ messages in thread
From: Suzuki K. Poulose @ 2015-10-15  9:45 UTC (permalink / raw)
  To: linux-arm-kernel

On 14/10/15 18:24, Mark Rutland wrote:

>> - * other registers depend on the function called upon completion
>> + * Other registers depend on the function called upon completion.
>> + *
>> + * Checks if the selected granule size is supported by the CPU.
>> + * If it doesn't park the CPU
>
> Nit: "If it isn't, park the CPU."

OK

>
>>    */
>> +#if	defined(CONFIG_ARM64_64K_PAGES)
>> +
>> +#define id_aa64mmfr0_tgran_shift	ID_AA64MMFR0_TGRAN64_SHIFT
>> +#define id_aa64mmfr0_tgran_on		ID_AA64MMFR0_TGRAN64_ON
>> +
>> +#else
>> +
>> +#define id_aa64mmfr0_tgran_shift	ID_AA64MMFR0_TGRAN4_SHIFT
>> +#define id_aa64mmfr0_tgran_on		ID_AA64MMFR0_TGRAN4_ON
>
> Any reason for not using upper-case names for the macros?

Nothing in particular. I had them in upper-case in the previous version,
changed it here ;) for absolutely no reason. I could switch it back.

> Given they're local you could just call them TGRAN_SHIFT and TRGRAN_ON
> to make the asm slightly nicer.

Given Jeremy's suggestion to add something to the EFI stub, I will retain
the original definition with all upper-case and define it somewhere in
a header so that we can reuse it.

>> +
>> +__no_granule_support:
>> +	wfe
>> +	b __no_granule_support
>> +ENDPROC(__no_granule_support)
>
> Other than the above, this loogs fine to me.
>
> In future it would be nice if we could somehow signal that these dead
> CPUs are trapped in the kernel -- we should have some kind of canary
> mechanism for that. That needn't block this patch, though.

Yes, we should.

Thanks for the review
Suzuki

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

* Re: [PATCHv3 08/11] arm64: Check for selected granule support
  2015-10-14 21:13     ` Jeremy Linton
@ 2015-10-15  9:48       ` Suzuki K. Poulose
  -1 siblings, 0 replies; 110+ messages in thread
From: Suzuki K. Poulose @ 2015-10-15  9:48 UTC (permalink / raw)
  To: Jeremy Linton, linux-arm-kernel
  Cc: mark.rutland, steve.capper, ard.biesheuvel, marc.zyngier,
	catalin.marinas, will.deacon, linux-kernel, christoffer.dall

On 14/10/15 22:13, Jeremy Linton wrote:
> On 10/14/2015 06:20 AM, Suzuki K. Poulose wrote:
>
>> + * Checks if the selected granule size is supported by the CPU.
>> + * If it doesn't park the CPU
>
> The problem is when you park the boot CPU.
>
> I think for EFI there is a slightly better error mechanism. This tweak will print an
> error and return to the EFI boot manager rather than hanging the machine without any
>  notification. Now it prints:
>
> EFI stub: Booting Linux Kernel...
> EFI stub: ERROR: 16K granule not supported by this machine
> EFI stub: ERROR: Failed to relocate kernel
> FS4:\>

Nice ! I will pick this up.

>
>
> Signed-off-by: Jeremy Linton <jeremy.linton@arm.com>
> ---
>   arch/arm64/kernel/efi-stub.c | 14 ++++++++++++++
>   1 file changed, 14 insertions(+)
>
> diff --git a/arch/arm64/kernel/efi-stub.c b/arch/arm64/kernel/efi-stub.c
> index 816120e..90fb868 100644
> --- a/arch/arm64/kernel/efi-stub.c
> +++ b/arch/arm64/kernel/efi-stub.c
> @@ -25,6 +25,20 @@ efi_status_t __init handle_kernel_image(efi_system_table_t *sys_table_arg,
>          unsigned long kernel_size, kernel_memsize = 0;
>          unsigned long nr_pages;
>          void *old_image_addr = (void *)*image_addr;
> +       u32 aa64mmfr0_el1;
> +
> +#ifdef CONFIG_ARM64_16K_PAGES

I would prefer to have it on for all page sizes and not just 16K, to be on a safer side

> +       /*
> +        * check to see if this kernel image is
> +        * compatible with the current system
> +        */
> +       asm volatile("mrs %0, ID_AA64MMFR0_EL1" : "=r" (aa64mmfr0_el1));
> +       aa64mmfr0_el1 >>= ID_AA64MMFR0_TGRAN16_SHIFT;
> +       if ((aa64mmfr0_el1 & ID_AA64MMFR0_TGRAN4_ON) == 0) {
> +               pr_efi_err(sys_table_arg, "16K granule not supported by this machine\n");
> +               return EFI_UNSUPPORTED;
> +       }
> +#endif

Thanks
Suzuki


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

* [PATCHv3 08/11] arm64: Check for selected granule support
@ 2015-10-15  9:48       ` Suzuki K. Poulose
  0 siblings, 0 replies; 110+ messages in thread
From: Suzuki K. Poulose @ 2015-10-15  9:48 UTC (permalink / raw)
  To: linux-arm-kernel

On 14/10/15 22:13, Jeremy Linton wrote:
> On 10/14/2015 06:20 AM, Suzuki K. Poulose wrote:
>
>> + * Checks if the selected granule size is supported by the CPU.
>> + * If it doesn't park the CPU
>
> The problem is when you park the boot CPU.
>
> I think for EFI there is a slightly better error mechanism. This tweak will print an
> error and return to the EFI boot manager rather than hanging the machine without any
>  notification. Now it prints:
>
> EFI stub: Booting Linux Kernel...
> EFI stub: ERROR: 16K granule not supported by this machine
> EFI stub: ERROR: Failed to relocate kernel
> FS4:\>

Nice ! I will pick this up.

>
>
> Signed-off-by: Jeremy Linton <jeremy.linton@arm.com>
> ---
>   arch/arm64/kernel/efi-stub.c | 14 ++++++++++++++
>   1 file changed, 14 insertions(+)
>
> diff --git a/arch/arm64/kernel/efi-stub.c b/arch/arm64/kernel/efi-stub.c
> index 816120e..90fb868 100644
> --- a/arch/arm64/kernel/efi-stub.c
> +++ b/arch/arm64/kernel/efi-stub.c
> @@ -25,6 +25,20 @@ efi_status_t __init handle_kernel_image(efi_system_table_t *sys_table_arg,
>          unsigned long kernel_size, kernel_memsize = 0;
>          unsigned long nr_pages;
>          void *old_image_addr = (void *)*image_addr;
> +       u32 aa64mmfr0_el1;
> +
> +#ifdef CONFIG_ARM64_16K_PAGES

I would prefer to have it on for all page sizes and not just 16K, to be on a safer side

> +       /*
> +        * check to see if this kernel image is
> +        * compatible with the current system
> +        */
> +       asm volatile("mrs %0, ID_AA64MMFR0_EL1" : "=r" (aa64mmfr0_el1));
> +       aa64mmfr0_el1 >>= ID_AA64MMFR0_TGRAN16_SHIFT;
> +       if ((aa64mmfr0_el1 & ID_AA64MMFR0_TGRAN4_ON) == 0) {
> +               pr_efi_err(sys_table_arg, "16K granule not supported by this machine\n");
> +               return EFI_UNSUPPORTED;
> +       }
> +#endif

Thanks
Suzuki

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

* Re: [PATCHv3 03/11] arm64: Introduce helpers for page table levels
  2015-10-15  9:35       ` Suzuki K. Poulose
@ 2015-10-15 10:37         ` Mark Rutland
  -1 siblings, 0 replies; 110+ messages in thread
From: Mark Rutland @ 2015-10-15 10:37 UTC (permalink / raw)
  To: Suzuki K. Poulose
  Cc: linux-arm-kernel, linux-kernel, catalin.marinas, will.deacon,
	steve.capper, marc.zyngier, ard.biesheuvel, christoffer.dall

On Thu, Oct 15, 2015 at 10:35:38AM +0100, Suzuki K. Poulose wrote:
> On 14/10/15 18:07, Mark Rutland wrote:
> >On Wed, Oct 14, 2015 at 12:20:26PM +0100, Suzuki K. Poulose wrote:
> 
> >>+ * Number of page-table levels required to address 'va_bits' wide
> >>+ * address, without section mapping. We resolve the top (va_bits - PAGE_SHIFT)
> >>+ * bits with (PAGE_SHIFT - 3) bits at each page table level. Hence:
> >>+ *
> >>+ *  levels = DIV_ROUND_UP((va_bits - PAGE_SHIFT), (PAGE_SHIFT - 3))
> >>+ *
> >>+ * We cannot include linux/kernel.h which defines DIV_ROUND_UP here
> >>+ * due to build issues. So we use the following magic formula.
> >>+ */
> >>+#define ARM64_HW_PGTABLE_LEVELS(va_bits) (((va_bits) - 4) / (PAGE_SHIFT - 3))
> >
> >I think I failed the interview question [1]. :(
> >
> >I read the comment to mean this was a brand-new piece of magic, as
> >opposed to a constant-folded copy of DIV_ROUND_UP. So it seems there's
> >still some scope for confusion, even if that only includes me.
> >
> 
> Wouldn't it be better to modify the comment to say, we open coded the DIV_ROUND_UP ?
> We could potentially end up in a conflict if somebody else does __DIV_ROUND_UP.
> I have seen similar issues with the CPU feature series, where if I include one
> particular header file in another, kernel build breaks without giving you a clue,
> what caused the error. Usually due to the multiple definitions (e.g NSEC_PER_SEC)
> and other conflicts. Given that this header file gets included with asm/page.h and
> hence would be used included for people outside arch/arm64, I would prefer, not to
> head there, instead update the comment, something like this :
> 
> 
> /*
>  * Number of page-table levels required to address 'va_bits' wide
>  * address, without section mapping. We resolve the top (va_bits - PAGE_SHIFT)
>  * bits with (PAGE_SHIFT - 3) bits at each page table level. Hence:
>  *
>  *  levels = DIV_ROUND_UP((va_bits - PAGE_SHIFT), (PAGE_SHIFT - 3))
>  *
>  * where DIV_ROUND_UP (n, d) = > ((n) + (d) - 1) / (d)
>  *
>  * We cannot include linux/kernel.h which defines DIV_ROUND_UP here
>  * due to build issues. So we open code the DIV_ROUND_UP and hence
>  * we get :
>  *  ((va_bits - PAGE_SHIFT) + (PAGE_SHIFT - 3) -1) / (PAGE_SHIFT - 3)
>  *
>  * which gets simplified as :
>  *  (((va_bits) - 4) / (PAGE_SHIFT - 3))
>  *
>  */
> 
> Let me know if you are happy with that ?

I am also happy with this. For the above, feel free to add:

Acked-by: Mark Rutland <mark.rutland@arm.com>

Thanks,
Mark.

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

* [PATCHv3 03/11] arm64: Introduce helpers for page table levels
@ 2015-10-15 10:37         ` Mark Rutland
  0 siblings, 0 replies; 110+ messages in thread
From: Mark Rutland @ 2015-10-15 10:37 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Oct 15, 2015 at 10:35:38AM +0100, Suzuki K. Poulose wrote:
> On 14/10/15 18:07, Mark Rutland wrote:
> >On Wed, Oct 14, 2015 at 12:20:26PM +0100, Suzuki K. Poulose wrote:
> 
> >>+ * Number of page-table levels required to address 'va_bits' wide
> >>+ * address, without section mapping. We resolve the top (va_bits - PAGE_SHIFT)
> >>+ * bits with (PAGE_SHIFT - 3) bits at each page table level. Hence:
> >>+ *
> >>+ *  levels = DIV_ROUND_UP((va_bits - PAGE_SHIFT), (PAGE_SHIFT - 3))
> >>+ *
> >>+ * We cannot include linux/kernel.h which defines DIV_ROUND_UP here
> >>+ * due to build issues. So we use the following magic formula.
> >>+ */
> >>+#define ARM64_HW_PGTABLE_LEVELS(va_bits) (((va_bits) - 4) / (PAGE_SHIFT - 3))
> >
> >I think I failed the interview question [1]. :(
> >
> >I read the comment to mean this was a brand-new piece of magic, as
> >opposed to a constant-folded copy of DIV_ROUND_UP. So it seems there's
> >still some scope for confusion, even if that only includes me.
> >
> 
> Wouldn't it be better to modify the comment to say, we open coded the DIV_ROUND_UP ?
> We could potentially end up in a conflict if somebody else does __DIV_ROUND_UP.
> I have seen similar issues with the CPU feature series, where if I include one
> particular header file in another, kernel build breaks without giving you a clue,
> what caused the error. Usually due to the multiple definitions (e.g NSEC_PER_SEC)
> and other conflicts. Given that this header file gets included with asm/page.h and
> hence would be used included for people outside arch/arm64, I would prefer, not to
> head there, instead update the comment, something like this :
> 
> 
> /*
>  * Number of page-table levels required to address 'va_bits' wide
>  * address, without section mapping. We resolve the top (va_bits - PAGE_SHIFT)
>  * bits with (PAGE_SHIFT - 3) bits at each page table level. Hence:
>  *
>  *  levels = DIV_ROUND_UP((va_bits - PAGE_SHIFT), (PAGE_SHIFT - 3))
>  *
>  * where DIV_ROUND_UP (n, d) = > ((n) + (d) - 1) / (d)
>  *
>  * We cannot include linux/kernel.h which defines DIV_ROUND_UP here
>  * due to build issues. So we open code the DIV_ROUND_UP and hence
>  * we get :
>  *  ((va_bits - PAGE_SHIFT) + (PAGE_SHIFT - 3) -1) / (PAGE_SHIFT - 3)
>  *
>  * which gets simplified as :
>  *  (((va_bits) - 4) / (PAGE_SHIFT - 3))
>  *
>  */
> 
> Let me know if you are happy with that ?

I am also happy with this. For the above, feel free to add:

Acked-by: Mark Rutland <mark.rutland@arm.com>

Thanks,
Mark.

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

* Re: [PATCHv3 08/11] arm64: Check for selected granule support
  2015-10-15  9:45       ` Suzuki K. Poulose
@ 2015-10-15 10:39         ` Mark Rutland
  -1 siblings, 0 replies; 110+ messages in thread
From: Mark Rutland @ 2015-10-15 10:39 UTC (permalink / raw)
  To: Suzuki K. Poulose
  Cc: linux-arm-kernel, linux-kernel, catalin.marinas, will.deacon,
	steve.capper, marc.zyngier, ard.biesheuvel, christoffer.dall

> >>+#define id_aa64mmfr0_tgran_shift	ID_AA64MMFR0_TGRAN64_SHIFT
> >>+#define id_aa64mmfr0_tgran_on		ID_AA64MMFR0_TGRAN64_ON
> >>+
> >>+#else
> >>+
> >>+#define id_aa64mmfr0_tgran_shift	ID_AA64MMFR0_TGRAN4_SHIFT
> >>+#define id_aa64mmfr0_tgran_on		ID_AA64MMFR0_TGRAN4_ON
> >
> >Any reason for not using upper-case names for the macros?
> 
> Nothing in particular. I had them in upper-case in the previous version,
> changed it here ;) for absolutely no reason. I could switch it back.

Please do!

> >Given they're local you could just call them TGRAN_SHIFT and TRGRAN_ON
> >to make the asm slightly nicer.
> 
> Given Jeremy's suggestion to add something to the EFI stub, I will retain
> the original definition with all upper-case and define it somewhere in
> a header so that we can reuse it.

Ok, that's also fine by me.

Thanks,
Mark.

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

* [PATCHv3 08/11] arm64: Check for selected granule support
@ 2015-10-15 10:39         ` Mark Rutland
  0 siblings, 0 replies; 110+ messages in thread
From: Mark Rutland @ 2015-10-15 10:39 UTC (permalink / raw)
  To: linux-arm-kernel

> >>+#define id_aa64mmfr0_tgran_shift	ID_AA64MMFR0_TGRAN64_SHIFT
> >>+#define id_aa64mmfr0_tgran_on		ID_AA64MMFR0_TGRAN64_ON
> >>+
> >>+#else
> >>+
> >>+#define id_aa64mmfr0_tgran_shift	ID_AA64MMFR0_TGRAN4_SHIFT
> >>+#define id_aa64mmfr0_tgran_on		ID_AA64MMFR0_TGRAN4_ON
> >
> >Any reason for not using upper-case names for the macros?
> 
> Nothing in particular. I had them in upper-case in the previous version,
> changed it here ;) for absolutely no reason. I could switch it back.

Please do!

> >Given they're local you could just call them TGRAN_SHIFT and TRGRAN_ON
> >to make the asm slightly nicer.
> 
> Given Jeremy's suggestion to add something to the EFI stub, I will retain
> the original definition with all upper-case and define it somewhere in
> a header so that we can reuse it.

Ok, that's also fine by me.

Thanks,
Mark.

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

* Re: [PATCHv3 08/11] arm64: Check for selected granule support
  2015-10-14 21:13     ` Jeremy Linton
@ 2015-10-15 10:45       ` Mark Rutland
  -1 siblings, 0 replies; 110+ messages in thread
From: Mark Rutland @ 2015-10-15 10:45 UTC (permalink / raw)
  To: Jeremy Linton
  Cc: Suzuki K. Poulose, linux-arm-kernel, steve.capper,
	ard.biesheuvel, marc.zyngier, catalin.marinas, will.deacon,
	linux-kernel, christoffer.dall

On Wed, Oct 14, 2015 at 04:13:47PM -0500, Jeremy Linton wrote:
> On 10/14/2015 06:20 AM, Suzuki K. Poulose wrote:
> 
> >+ * Checks if the selected granule size is supported by the CPU.
> >+ * If it doesn't park the CPU
> 
> The problem is when you park the boot CPU.
> 
> I think for EFI there is a slightly better error mechanism. This
> tweak will print an error and return to the EFI boot manager rather
> than hanging the machine without any notification. Now it prints:
> 
> EFI stub: Booting Linux Kernel...
> EFI stub: ERROR: 16K granule not supported by this machine
> EFI stub: ERROR: Failed to relocate kernel
> FS4:\>

Neat. We should definitely have checks like this in the stub.

However, we still need checks in head.S, given !EFI systems, SMP, and
kexec, so this is a complementary mechanism.

Thanks,
Mark.

> Signed-off-by: Jeremy Linton <jeremy.linton@arm.com>
> ---
>  arch/arm64/kernel/efi-stub.c | 14 ++++++++++++++
>  1 file changed, 14 insertions(+)
> 
> diff --git a/arch/arm64/kernel/efi-stub.c b/arch/arm64/kernel/efi-stub.c
> index 816120e..90fb868 100644
> --- a/arch/arm64/kernel/efi-stub.c
> +++ b/arch/arm64/kernel/efi-stub.c
> @@ -25,6 +25,20 @@ efi_status_t __init
> handle_kernel_image(efi_system_table_t *sys_table_arg,
>         unsigned long kernel_size, kernel_memsize = 0;
>         unsigned long nr_pages;
>         void *old_image_addr = (void *)*image_addr;
> +       u32 aa64mmfr0_el1;
> +
> +#ifdef CONFIG_ARM64_16K_PAGES
> +       /*
> +        * check to see if this kernel image is
> +        * compatible with the current system
> +        */
> +       asm volatile("mrs %0, ID_AA64MMFR0_EL1" : "=r" (aa64mmfr0_el1));
> +       aa64mmfr0_el1 >>= ID_AA64MMFR0_TGRAN16_SHIFT;
> +       if ((aa64mmfr0_el1 & ID_AA64MMFR0_TGRAN4_ON) == 0) {
> +               pr_efi_err(sys_table_arg, "16K granule not supported
> by this machine\n");
> +               return EFI_UNSUPPORTED;
> +       }
> +#endif
> 
>         /* Relocate the image, if required. */
>         kernel_size = _edata - _text;
> -- 
> 2.4.3
> 
> 
> 
> 
> 
> 
> 

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

* [PATCHv3 08/11] arm64: Check for selected granule support
@ 2015-10-15 10:45       ` Mark Rutland
  0 siblings, 0 replies; 110+ messages in thread
From: Mark Rutland @ 2015-10-15 10:45 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Oct 14, 2015 at 04:13:47PM -0500, Jeremy Linton wrote:
> On 10/14/2015 06:20 AM, Suzuki K. Poulose wrote:
> 
> >+ * Checks if the selected granule size is supported by the CPU.
> >+ * If it doesn't park the CPU
> 
> The problem is when you park the boot CPU.
> 
> I think for EFI there is a slightly better error mechanism. This
> tweak will print an error and return to the EFI boot manager rather
> than hanging the machine without any notification. Now it prints:
> 
> EFI stub: Booting Linux Kernel...
> EFI stub: ERROR: 16K granule not supported by this machine
> EFI stub: ERROR: Failed to relocate kernel
> FS4:\>

Neat. We should definitely have checks like this in the stub.

However, we still need checks in head.S, given !EFI systems, SMP, and
kexec, so this is a complementary mechanism.

Thanks,
Mark.

> Signed-off-by: Jeremy Linton <jeremy.linton@arm.com>
> ---
>  arch/arm64/kernel/efi-stub.c | 14 ++++++++++++++
>  1 file changed, 14 insertions(+)
> 
> diff --git a/arch/arm64/kernel/efi-stub.c b/arch/arm64/kernel/efi-stub.c
> index 816120e..90fb868 100644
> --- a/arch/arm64/kernel/efi-stub.c
> +++ b/arch/arm64/kernel/efi-stub.c
> @@ -25,6 +25,20 @@ efi_status_t __init
> handle_kernel_image(efi_system_table_t *sys_table_arg,
>         unsigned long kernel_size, kernel_memsize = 0;
>         unsigned long nr_pages;
>         void *old_image_addr = (void *)*image_addr;
> +       u32 aa64mmfr0_el1;
> +
> +#ifdef CONFIG_ARM64_16K_PAGES
> +       /*
> +        * check to see if this kernel image is
> +        * compatible with the current system
> +        */
> +       asm volatile("mrs %0, ID_AA64MMFR0_EL1" : "=r" (aa64mmfr0_el1));
> +       aa64mmfr0_el1 >>= ID_AA64MMFR0_TGRAN16_SHIFT;
> +       if ((aa64mmfr0_el1 & ID_AA64MMFR0_TGRAN4_ON) == 0) {
> +               pr_efi_err(sys_table_arg, "16K granule not supported
> by this machine\n");
> +               return EFI_UNSUPPORTED;
> +       }
> +#endif
> 
>         /* Relocate the image, if required. */
>         kernel_size = _edata - _text;
> -- 
> 2.4.3
> 
> 
> 
> 
> 
> 
> 

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

* Re: [PATCHv3 08/11] arm64: Check for selected granule support
  2015-10-15 10:45       ` Mark Rutland
@ 2015-10-15 11:25         ` Suzuki K. Poulose
  -1 siblings, 0 replies; 110+ messages in thread
From: Suzuki K. Poulose @ 2015-10-15 11:25 UTC (permalink / raw)
  To: Mark Rutland
  Cc: Jeremy Linton, linux-arm-kernel, steve.capper, ard.biesheuvel,
	marc.zyngier, catalin.marinas, will.deacon, linux-kernel,
	christoffer.dall

On Thu, Oct 15, 2015 at 11:45:15AM +0100, Mark Rutland wrote:
> On Wed, Oct 14, 2015 at 04:13:47PM -0500, Jeremy Linton wrote:
> > On 10/14/2015 06:20 AM, Suzuki K. Poulose wrote:
> > 
> > >+ * Checks if the selected granule size is supported by the CPU.
> > >+ * If it doesn't park the CPU
> > 
> > The problem is when you park the boot CPU.
> > 
> > I think for EFI there is a slightly better error mechanism. This
> > tweak will print an error and return to the EFI boot manager rather
> > than hanging the machine without any notification. Now it prints:
> > 
> > EFI stub: Booting Linux Kernel...
> > EFI stub: ERROR: 16K granule not supported by this machine
> > EFI stub: ERROR: Failed to relocate kernel
> > FS4:\>
> 
> Neat. We should definitely have checks like this in the stub.
> 
> However, we still need checks in head.S, given !EFI systems, SMP, and
> kexec, so this is a complementary mechanism.

Indeed. I meant to add the above check. The updated patch looks like :

----8>----

Author: Suzuki K. Poulose <suzuki.poulose@arm.com>
Date:   Wed Oct 14 11:25:16 2015 +0100

    arm64: Check for selected granule support
    
    Ensure that the selected page size is supported by the CPU(s). If it isn't
    park the CPU. A check is added to the EFI stub to detect if the boot CPU
    supports the page size, failing which, we fail the boot gracefully, with
    an error message.
    
    Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com>
    [ Added a check to EFI stub ]
    Signed-off-by: Jeremy Linton <jeremy.linton@arm.com>

diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index a7f3d4b..72d814c 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -44,6 +44,26 @@
 #define SET_PSTATE_PAN(x) __inst_arm(0xd5000000 | REG_PSTATE_PAN_IMM |\
 				     (!!x)<<8 | 0x1f)
 
+
+#define ID_AA64MMFR0_TGRAN4_SHIFT	28
+#define ID_AA64MMFR0_TGRAN64_SHIFT	24
+#define ID_AA64MMFR0_TGRAN16_SHIFT	20
+
+#define ID_AA64MMFR0_TGRAN4_NI		0xf
+#define ID_AA64MMFR0_TGRAN4_ON		0x0
+#define ID_AA64MMFR0_TGRAN64_NI		0xf
+#define ID_AA64MMFR0_TGRAN64_ON		0x0
+#define ID_AA64MMFR0_TGRAN16_NI		0x0
+#define ID_AA64MMFR0_TGRAN16_ON		0x1
+
+#if defined(CONFIG_ARM64_4K_PAGES)
+#define ID_AA64MMFR0_TGRAN_SHIFT	ID_AA64MMFR0_TGRAN4_SHIFT
+#define ID_AA64MMFR0_TGRAN_SUPPORTED	ID_AA64MMFR0_TGRAN4_ON
+#else
+#define ID_AA64MMFR0_TGRAN_SHIFT	ID_AA64MMFR0_TGRAN64_SHIFT
+#define ID_AA64MMFR0_TGRAN_SUPPORTED	ID_AA64MMFR0_TGRAN64_ON
+#endif
+
 #ifdef __ASSEMBLY__
 
 	.irp	num,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30
diff --git a/arch/arm64/kernel/efi-stub.c b/arch/arm64/kernel/efi-stub.c
index 816120e..77d7de1 100644
--- a/arch/arm64/kernel/efi-stub.c
+++ b/arch/arm64/kernel/efi-stub.c
@@ -11,8 +11,15 @@
  */
 #include <linux/efi.h>
 #include <asm/efi.h>
+#include <asm/sysreg.h>
 #include <asm/sections.h>
 
+#if defined(CONFIG_ARM64_4K_PAGES)
+#define PAGE_SIZE_STR	"4K"
+#elif defined(CONFIG_ARM64_64K_PAGES)
+#define PAGE_SIZE_STR	"64K"
+#endif
+
 efi_status_t __init handle_kernel_image(efi_system_table_t *sys_table_arg,
 					unsigned long *image_addr,
 					unsigned long *image_size,
@@ -25,6 +32,17 @@ efi_status_t __init handle_kernel_image(efi_system_table_t *sys_table_arg,
 	unsigned long kernel_size, kernel_memsize = 0;
 	unsigned long nr_pages;
 	void *old_image_addr = (void *)*image_addr;
+	u64 aa64mmfr0_el1;
+
+	/*
+	 * Check to see if the CPU supports the requested pagesize
+	 */
+	asm volatile("mrs %0, ID_AA64MMFR0_EL1" : "=r" (aa64mmfr0_el1));
+	aa64mmfr0_el1 >>= ID_AA64MMFR0_TGRAN_SHIFT;
+	if ((aa64mmfr0_el1 & 0xf) != ID_AA64MMFR0_TGRAN_SUPPORTED) {
+		pr_efi_err(sys_table_arg, PAGE_SIZE_STR" granule not supported by the CPU\n");
+		return EFI_UNSUPPORTED;
+	}
 
 	/* Relocate the image, if required. */
 	kernel_size = _edata - _text;
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index 7ace955..514c1cc 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -31,10 +31,11 @@
 #include <asm/cputype.h>
 #include <asm/kernel-pgtable.h>
 #include <asm/memory.h>
-#include <asm/thread_info.h>
 #include <asm/pgtable-hwdef.h>
 #include <asm/pgtable.h>
 #include <asm/page.h>
+#include <asm/sysreg.h>
+#include <asm/thread_info.h>
 #include <asm/virt.h>
 
 #define __PHYS_OFFSET	(KERNEL_START - TEXT_OFFSET)
@@ -613,10 +614,17 @@ ENDPROC(__secondary_switched)
  *  x0  = SCTLR_EL1 value for turning on the MMU.
  *  x27 = *virtual* address to jump to upon completion
  *
- * other registers depend on the function called upon completion
+ * Other registers depend on the function called upon completion.
+ *
+ * Checks if the selected granule size is supported by the CPU.
+ * If it isn't, park the CPU
  */
 	.section	".idmap.text", "ax"
 __enable_mmu:
+	mrs	x1, ID_AA64MMFR0_EL1
+	ubfx	x2, x1, #ID_AA64MMFR0_TGRAN_SHIFT, 4
+	cmp	x2, #ID_AA64MMFR0_TGRAN_SUPPORTED
+	b.ne	__no_granule_support
 	ldr	x5, =vectors
 	msr	vbar_el1, x5
 	msr	ttbr0_el1, x25			// load TTBR0
@@ -634,3 +642,8 @@ __enable_mmu:
 	isb
 	br	x27
 ENDPROC(__enable_mmu)
+
+__no_granule_support:
+	wfe
+	b __no_granule_support
+ENDPROC(__no_granule_support)

----8<----
> 
> Thanks,
> Mark.
> 
> > Signed-off-by: Jeremy Linton <jeremy.linton@arm.com>
> > ---
> >  arch/arm64/kernel/efi-stub.c | 14 ++++++++++++++
> >  1 file changed, 14 insertions(+)
> > 
> > diff --git a/arch/arm64/kernel/efi-stub.c b/arch/arm64/kernel/efi-stub.c
> > index 816120e..90fb868 100644
> > --- a/arch/arm64/kernel/efi-stub.c
> > +++ b/arch/arm64/kernel/efi-stub.c
> > @@ -25,6 +25,20 @@ efi_status_t __init
> > handle_kernel_image(efi_system_table_t *sys_table_arg,
> >         unsigned long kernel_size, kernel_memsize = 0;
> >         unsigned long nr_pages;
> >         void *old_image_addr = (void *)*image_addr;
> > +       u32 aa64mmfr0_el1;
> > +
> > +#ifdef CONFIG_ARM64_16K_PAGES
> > +       /*
> > +        * check to see if this kernel image is
> > +        * compatible with the current system
> > +        */
> > +       asm volatile("mrs %0, ID_AA64MMFR0_EL1" : "=r" (aa64mmfr0_el1));
> > +       aa64mmfr0_el1 >>= ID_AA64MMFR0_TGRAN16_SHIFT;
> > +       if ((aa64mmfr0_el1 & ID_AA64MMFR0_TGRAN4_ON) == 0) {
> > +               pr_efi_err(sys_table_arg, "16K granule not supported
> > by this machine\n");
> > +               return EFI_UNSUPPORTED;
> > +       }
> > +#endif
> > 
> >         /* Relocate the image, if required. */
> >         kernel_size = _edata - _text;
> > -- 
> > 2.4.3
> > 
> > 
> > 
> > 
> > 
> > 
> > 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
> 


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

* [PATCHv3 08/11] arm64: Check for selected granule support
@ 2015-10-15 11:25         ` Suzuki K. Poulose
  0 siblings, 0 replies; 110+ messages in thread
From: Suzuki K. Poulose @ 2015-10-15 11:25 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Oct 15, 2015 at 11:45:15AM +0100, Mark Rutland wrote:
> On Wed, Oct 14, 2015 at 04:13:47PM -0500, Jeremy Linton wrote:
> > On 10/14/2015 06:20 AM, Suzuki K. Poulose wrote:
> > 
> > >+ * Checks if the selected granule size is supported by the CPU.
> > >+ * If it doesn't park the CPU
> > 
> > The problem is when you park the boot CPU.
> > 
> > I think for EFI there is a slightly better error mechanism. This
> > tweak will print an error and return to the EFI boot manager rather
> > than hanging the machine without any notification. Now it prints:
> > 
> > EFI stub: Booting Linux Kernel...
> > EFI stub: ERROR: 16K granule not supported by this machine
> > EFI stub: ERROR: Failed to relocate kernel
> > FS4:\>
> 
> Neat. We should definitely have checks like this in the stub.
> 
> However, we still need checks in head.S, given !EFI systems, SMP, and
> kexec, so this is a complementary mechanism.

Indeed. I meant to add the above check. The updated patch looks like :

----8>----

Author: Suzuki K. Poulose <suzuki.poulose@arm.com>
Date:   Wed Oct 14 11:25:16 2015 +0100

    arm64: Check for selected granule support
    
    Ensure that the selected page size is supported by the CPU(s). If it isn't
    park the CPU. A check is added to the EFI stub to detect if the boot CPU
    supports the page size, failing which, we fail the boot gracefully, with
    an error message.
    
    Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com>
    [ Added a check to EFI stub ]
    Signed-off-by: Jeremy Linton <jeremy.linton@arm.com>

diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index a7f3d4b..72d814c 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -44,6 +44,26 @@
 #define SET_PSTATE_PAN(x) __inst_arm(0xd5000000 | REG_PSTATE_PAN_IMM |\
 				     (!!x)<<8 | 0x1f)
 
+
+#define ID_AA64MMFR0_TGRAN4_SHIFT	28
+#define ID_AA64MMFR0_TGRAN64_SHIFT	24
+#define ID_AA64MMFR0_TGRAN16_SHIFT	20
+
+#define ID_AA64MMFR0_TGRAN4_NI		0xf
+#define ID_AA64MMFR0_TGRAN4_ON		0x0
+#define ID_AA64MMFR0_TGRAN64_NI		0xf
+#define ID_AA64MMFR0_TGRAN64_ON		0x0
+#define ID_AA64MMFR0_TGRAN16_NI		0x0
+#define ID_AA64MMFR0_TGRAN16_ON		0x1
+
+#if defined(CONFIG_ARM64_4K_PAGES)
+#define ID_AA64MMFR0_TGRAN_SHIFT	ID_AA64MMFR0_TGRAN4_SHIFT
+#define ID_AA64MMFR0_TGRAN_SUPPORTED	ID_AA64MMFR0_TGRAN4_ON
+#else
+#define ID_AA64MMFR0_TGRAN_SHIFT	ID_AA64MMFR0_TGRAN64_SHIFT
+#define ID_AA64MMFR0_TGRAN_SUPPORTED	ID_AA64MMFR0_TGRAN64_ON
+#endif
+
 #ifdef __ASSEMBLY__
 
 	.irp	num,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30
diff --git a/arch/arm64/kernel/efi-stub.c b/arch/arm64/kernel/efi-stub.c
index 816120e..77d7de1 100644
--- a/arch/arm64/kernel/efi-stub.c
+++ b/arch/arm64/kernel/efi-stub.c
@@ -11,8 +11,15 @@
  */
 #include <linux/efi.h>
 #include <asm/efi.h>
+#include <asm/sysreg.h>
 #include <asm/sections.h>
 
+#if defined(CONFIG_ARM64_4K_PAGES)
+#define PAGE_SIZE_STR	"4K"
+#elif defined(CONFIG_ARM64_64K_PAGES)
+#define PAGE_SIZE_STR	"64K"
+#endif
+
 efi_status_t __init handle_kernel_image(efi_system_table_t *sys_table_arg,
 					unsigned long *image_addr,
 					unsigned long *image_size,
@@ -25,6 +32,17 @@ efi_status_t __init handle_kernel_image(efi_system_table_t *sys_table_arg,
 	unsigned long kernel_size, kernel_memsize = 0;
 	unsigned long nr_pages;
 	void *old_image_addr = (void *)*image_addr;
+	u64 aa64mmfr0_el1;
+
+	/*
+	 * Check to see if the CPU supports the requested pagesize
+	 */
+	asm volatile("mrs %0, ID_AA64MMFR0_EL1" : "=r" (aa64mmfr0_el1));
+	aa64mmfr0_el1 >>= ID_AA64MMFR0_TGRAN_SHIFT;
+	if ((aa64mmfr0_el1 & 0xf) != ID_AA64MMFR0_TGRAN_SUPPORTED) {
+		pr_efi_err(sys_table_arg, PAGE_SIZE_STR" granule not supported by the CPU\n");
+		return EFI_UNSUPPORTED;
+	}
 
 	/* Relocate the image, if required. */
 	kernel_size = _edata - _text;
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index 7ace955..514c1cc 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -31,10 +31,11 @@
 #include <asm/cputype.h>
 #include <asm/kernel-pgtable.h>
 #include <asm/memory.h>
-#include <asm/thread_info.h>
 #include <asm/pgtable-hwdef.h>
 #include <asm/pgtable.h>
 #include <asm/page.h>
+#include <asm/sysreg.h>
+#include <asm/thread_info.h>
 #include <asm/virt.h>
 
 #define __PHYS_OFFSET	(KERNEL_START - TEXT_OFFSET)
@@ -613,10 +614,17 @@ ENDPROC(__secondary_switched)
  *  x0  = SCTLR_EL1 value for turning on the MMU.
  *  x27 = *virtual* address to jump to upon completion
  *
- * other registers depend on the function called upon completion
+ * Other registers depend on the function called upon completion.
+ *
+ * Checks if the selected granule size is supported by the CPU.
+ * If it isn't, park the CPU
  */
 	.section	".idmap.text", "ax"
 __enable_mmu:
+	mrs	x1, ID_AA64MMFR0_EL1
+	ubfx	x2, x1, #ID_AA64MMFR0_TGRAN_SHIFT, 4
+	cmp	x2, #ID_AA64MMFR0_TGRAN_SUPPORTED
+	b.ne	__no_granule_support
 	ldr	x5, =vectors
 	msr	vbar_el1, x5
 	msr	ttbr0_el1, x25			// load TTBR0
@@ -634,3 +642,8 @@ __enable_mmu:
 	isb
 	br	x27
 ENDPROC(__enable_mmu)
+
+__no_granule_support:
+	wfe
+	b __no_granule_support
+ENDPROC(__no_granule_support)

----8<----
> 
> Thanks,
> Mark.
> 
> > Signed-off-by: Jeremy Linton <jeremy.linton@arm.com>
> > ---
> >  arch/arm64/kernel/efi-stub.c | 14 ++++++++++++++
> >  1 file changed, 14 insertions(+)
> > 
> > diff --git a/arch/arm64/kernel/efi-stub.c b/arch/arm64/kernel/efi-stub.c
> > index 816120e..90fb868 100644
> > --- a/arch/arm64/kernel/efi-stub.c
> > +++ b/arch/arm64/kernel/efi-stub.c
> > @@ -25,6 +25,20 @@ efi_status_t __init
> > handle_kernel_image(efi_system_table_t *sys_table_arg,
> >         unsigned long kernel_size, kernel_memsize = 0;
> >         unsigned long nr_pages;
> >         void *old_image_addr = (void *)*image_addr;
> > +       u32 aa64mmfr0_el1;
> > +
> > +#ifdef CONFIG_ARM64_16K_PAGES
> > +       /*
> > +        * check to see if this kernel image is
> > +        * compatible with the current system
> > +        */
> > +       asm volatile("mrs %0, ID_AA64MMFR0_EL1" : "=r" (aa64mmfr0_el1));
> > +       aa64mmfr0_el1 >>= ID_AA64MMFR0_TGRAN16_SHIFT;
> > +       if ((aa64mmfr0_el1 & ID_AA64MMFR0_TGRAN4_ON) == 0) {
> > +               pr_efi_err(sys_table_arg, "16K granule not supported
> > by this machine\n");
> > +               return EFI_UNSUPPORTED;
> > +       }
> > +#endif
> > 
> >         /* Relocate the image, if required. */
> >         kernel_size = _edata - _text;
> > -- 
> > 2.4.3
> > 
> > 
> > 
> > 
> > 
> > 
> > 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
> 

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

* Re: [PATCHv3 03/11] arm64: Introduce helpers for page table levels
  2015-10-14 11:20   ` Suzuki K. Poulose
@ 2015-10-15 11:37     ` Christoffer Dall
  -1 siblings, 0 replies; 110+ messages in thread
From: Christoffer Dall @ 2015-10-15 11:37 UTC (permalink / raw)
  To: Suzuki K. Poulose
  Cc: linux-arm-kernel, linux-kernel, catalin.marinas, will.deacon,
	mark.rutland, steve.capper, marc.zyngier, ard.biesheuvel

On Wed, Oct 14, 2015 at 12:20:26PM +0100, Suzuki K. Poulose wrote:
> Introduce helpers for finding the number of page table
> levels required for a given VA width, shift for a particular
> page table level.
> 
> Convert the existing users to the new helpers. More users
> to follow.
> 
> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>
> Cc: Marc Zyngier <marc.zyngier@arm.com>
> Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com>
> 
> ---
> Changes since V2:
>   - Add comments around the macros
>   - Change ARM64_HW_PGTABLE_LEVEL_SHIFT to accept pagetable level as
>     described by ARM ARM
> ---
>  arch/arm64/include/asm/pgtable-hwdef.h |   25 ++++++++++++++++++++++---
>  1 file changed, 22 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/pgtable-hwdef.h b/arch/arm64/include/asm/pgtable-hwdef.h
> index 95c1ec0..c6194ab 100644
> --- a/arch/arm64/include/asm/pgtable-hwdef.h
> +++ b/arch/arm64/include/asm/pgtable-hwdef.h
> @@ -16,13 +16,31 @@
>  #ifndef __ASM_PGTABLE_HWDEF_H
>  #define __ASM_PGTABLE_HWDEF_H
>  
> +/*
> + * Number of page-table levels required to address 'va_bits' wide
> + * address, without section mapping. We resolve the top (va_bits - PAGE_SHIFT)
> + * bits with (PAGE_SHIFT - 3) bits at each page table level. Hence:
> + *
> + *  levels = DIV_ROUND_UP((va_bits - PAGE_SHIFT), (PAGE_SHIFT - 3))
> + *
> + * We cannot include linux/kernel.h which defines DIV_ROUND_UP here
> + * due to build issues. So we use the following magic formula.
> + */
> +#define ARM64_HW_PGTABLE_LEVELS(va_bits) (((va_bits) - 4) / (PAGE_SHIFT - 3))
> +
> +/*
> + * Size mapped by an entry at level n
> + * We map PAGE_SHIFT - 3 at all levels, except the PAGE_SHIFT bits at the last level
> + */
> +#define ARM64_HW_PGTABLE_LEVEL_SHIFT(n)	((PAGE_SHIFT - 3) * (4 - (n)) + 3)

I feel like I'm partially failing the interview question again, in that
I don't fully understand the '+ 3' in the end?

Also the comment could be expanded to explain the (4 - (n)), but I
couldn't easily come up with good language for explaining that you have
a maximum of 4 levels and you subtract the 'n' levels that your are not
accounting for...

That said, this still looks functionally correct to me.

-Christoffer


> +
>  #define PTRS_PER_PTE		(1 << (PAGE_SHIFT - 3))
>  
>  /*
>   * PMD_SHIFT determines the size a level 2 page table entry can map.
>   */
>  #if CONFIG_PGTABLE_LEVELS > 2
> -#define PMD_SHIFT		((PAGE_SHIFT - 3) * 2 + 3)
> +#define PMD_SHIFT		ARM64_HW_PGTABLE_LEVEL_SHIFT(2)
>  #define PMD_SIZE		(_AC(1, UL) << PMD_SHIFT)
>  #define PMD_MASK		(~(PMD_SIZE-1))
>  #define PTRS_PER_PMD		PTRS_PER_PTE
> @@ -32,7 +50,7 @@
>   * PUD_SHIFT determines the size a level 1 page table entry can map.
>   */
>  #if CONFIG_PGTABLE_LEVELS > 3
> -#define PUD_SHIFT		((PAGE_SHIFT - 3) * 3 + 3)
> +#define PUD_SHIFT		ARM64_HW_PGTABLE_LEVEL_SHIFT(1)
>  #define PUD_SIZE		(_AC(1, UL) << PUD_SHIFT)
>  #define PUD_MASK		(~(PUD_SIZE-1))
>  #define PTRS_PER_PUD		PTRS_PER_PTE
> @@ -42,7 +60,8 @@
>   * PGDIR_SHIFT determines the size a top-level page table entry can map
>   * (depending on the configuration, this level can be 0, 1 or 2).
>   */
> -#define PGDIR_SHIFT		((PAGE_SHIFT - 3) * CONFIG_PGTABLE_LEVELS + 3)
> +#define PGDIR_SHIFT	\
> +		ARM64_HW_PGTABLE_LEVEL_SHIFT(4 - CONFIG_PGTABLE_LEVELS)
>  #define PGDIR_SIZE		(_AC(1, UL) << PGDIR_SHIFT)
>  #define PGDIR_MASK		(~(PGDIR_SIZE-1))
>  #define PTRS_PER_PGD		(1 << (VA_BITS - PGDIR_SHIFT))
> -- 
> 1.7.9.5
> 

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

* [PATCHv3 03/11] arm64: Introduce helpers for page table levels
@ 2015-10-15 11:37     ` Christoffer Dall
  0 siblings, 0 replies; 110+ messages in thread
From: Christoffer Dall @ 2015-10-15 11:37 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Oct 14, 2015 at 12:20:26PM +0100, Suzuki K. Poulose wrote:
> Introduce helpers for finding the number of page table
> levels required for a given VA width, shift for a particular
> page table level.
> 
> Convert the existing users to the new helpers. More users
> to follow.
> 
> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>
> Cc: Marc Zyngier <marc.zyngier@arm.com>
> Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com>
> 
> ---
> Changes since V2:
>   - Add comments around the macros
>   - Change ARM64_HW_PGTABLE_LEVEL_SHIFT to accept pagetable level as
>     described by ARM ARM
> ---
>  arch/arm64/include/asm/pgtable-hwdef.h |   25 ++++++++++++++++++++++---
>  1 file changed, 22 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/pgtable-hwdef.h b/arch/arm64/include/asm/pgtable-hwdef.h
> index 95c1ec0..c6194ab 100644
> --- a/arch/arm64/include/asm/pgtable-hwdef.h
> +++ b/arch/arm64/include/asm/pgtable-hwdef.h
> @@ -16,13 +16,31 @@
>  #ifndef __ASM_PGTABLE_HWDEF_H
>  #define __ASM_PGTABLE_HWDEF_H
>  
> +/*
> + * Number of page-table levels required to address 'va_bits' wide
> + * address, without section mapping. We resolve the top (va_bits - PAGE_SHIFT)
> + * bits with (PAGE_SHIFT - 3) bits at each page table level. Hence:
> + *
> + *  levels = DIV_ROUND_UP((va_bits - PAGE_SHIFT), (PAGE_SHIFT - 3))
> + *
> + * We cannot include linux/kernel.h which defines DIV_ROUND_UP here
> + * due to build issues. So we use the following magic formula.
> + */
> +#define ARM64_HW_PGTABLE_LEVELS(va_bits) (((va_bits) - 4) / (PAGE_SHIFT - 3))
> +
> +/*
> + * Size mapped by an entry at level n
> + * We map PAGE_SHIFT - 3 at all levels, except the PAGE_SHIFT bits at the last level
> + */
> +#define ARM64_HW_PGTABLE_LEVEL_SHIFT(n)	((PAGE_SHIFT - 3) * (4 - (n)) + 3)

I feel like I'm partially failing the interview question again, in that
I don't fully understand the '+ 3' in the end?

Also the comment could be expanded to explain the (4 - (n)), but I
couldn't easily come up with good language for explaining that you have
a maximum of 4 levels and you subtract the 'n' levels that your are not
accounting for...

That said, this still looks functionally correct to me.

-Christoffer


> +
>  #define PTRS_PER_PTE		(1 << (PAGE_SHIFT - 3))
>  
>  /*
>   * PMD_SHIFT determines the size a level 2 page table entry can map.
>   */
>  #if CONFIG_PGTABLE_LEVELS > 2
> -#define PMD_SHIFT		((PAGE_SHIFT - 3) * 2 + 3)
> +#define PMD_SHIFT		ARM64_HW_PGTABLE_LEVEL_SHIFT(2)
>  #define PMD_SIZE		(_AC(1, UL) << PMD_SHIFT)
>  #define PMD_MASK		(~(PMD_SIZE-1))
>  #define PTRS_PER_PMD		PTRS_PER_PTE
> @@ -32,7 +50,7 @@
>   * PUD_SHIFT determines the size a level 1 page table entry can map.
>   */
>  #if CONFIG_PGTABLE_LEVELS > 3
> -#define PUD_SHIFT		((PAGE_SHIFT - 3) * 3 + 3)
> +#define PUD_SHIFT		ARM64_HW_PGTABLE_LEVEL_SHIFT(1)
>  #define PUD_SIZE		(_AC(1, UL) << PUD_SHIFT)
>  #define PUD_MASK		(~(PUD_SIZE-1))
>  #define PTRS_PER_PUD		PTRS_PER_PTE
> @@ -42,7 +60,8 @@
>   * PGDIR_SHIFT determines the size a top-level page table entry can map
>   * (depending on the configuration, this level can be 0, 1 or 2).
>   */
> -#define PGDIR_SHIFT		((PAGE_SHIFT - 3) * CONFIG_PGTABLE_LEVELS + 3)
> +#define PGDIR_SHIFT	\
> +		ARM64_HW_PGTABLE_LEVEL_SHIFT(4 - CONFIG_PGTABLE_LEVELS)
>  #define PGDIR_SIZE		(_AC(1, UL) << PGDIR_SHIFT)
>  #define PGDIR_MASK		(~(PGDIR_SIZE-1))
>  #define PTRS_PER_PGD		(1 << (VA_BITS - PGDIR_SHIFT))
> -- 
> 1.7.9.5
> 

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

* Re: [PATCHv3 03/11] arm64: Introduce helpers for page table levels
  2015-10-15  9:35       ` Suzuki K. Poulose
@ 2015-10-15 11:40         ` Christoffer Dall
  -1 siblings, 0 replies; 110+ messages in thread
From: Christoffer Dall @ 2015-10-15 11:40 UTC (permalink / raw)
  To: Suzuki K. Poulose
  Cc: Mark Rutland, linux-arm-kernel, linux-kernel, catalin.marinas,
	will.deacon, steve.capper, marc.zyngier, ard.biesheuvel

On Thu, Oct 15, 2015 at 10:35:38AM +0100, Suzuki K. Poulose wrote:
> On 14/10/15 18:07, Mark Rutland wrote:
> >On Wed, Oct 14, 2015 at 12:20:26PM +0100, Suzuki K. Poulose wrote:
> 
> >>+ * Number of page-table levels required to address 'va_bits' wide
> >>+ * address, without section mapping. We resolve the top (va_bits - PAGE_SHIFT)
> >>+ * bits with (PAGE_SHIFT - 3) bits at each page table level. Hence:
> >>+ *
> >>+ *  levels = DIV_ROUND_UP((va_bits - PAGE_SHIFT), (PAGE_SHIFT - 3))
> >>+ *
> >>+ * We cannot include linux/kernel.h which defines DIV_ROUND_UP here
> >>+ * due to build issues. So we use the following magic formula.
> >>+ */
> >>+#define ARM64_HW_PGTABLE_LEVELS(va_bits) (((va_bits) - 4) / (PAGE_SHIFT - 3))
> >
> >I think I failed the interview question [1]. :(
> >
> >I read the comment to mean this was a brand-new piece of magic, as
> >opposed to a constant-folded copy of DIV_ROUND_UP. So it seems there's
> >still some scope for confusion, even if that only includes me.
> >
> 
> Wouldn't it be better to modify the comment to say, we open coded the DIV_ROUND_UP ?
> We could potentially end up in a conflict if somebody else does __DIV_ROUND_UP.
> I have seen similar issues with the CPU feature series, where if I include one
> particular header file in another, kernel build breaks without giving you a clue,
> what caused the error. Usually due to the multiple definitions (e.g NSEC_PER_SEC)
> and other conflicts. Given that this header file gets included with asm/page.h and
> hence would be used included for people outside arch/arm64, I would prefer, not to
> head there, instead update the comment, something like this :
> 
> 
> /*
>  * Number of page-table levels required to address 'va_bits' wide
>  * address, without section mapping. We resolve the top (va_bits - PAGE_SHIFT)
>  * bits with (PAGE_SHIFT - 3) bits at each page table level. Hence:
>  *
>  *  levels = DIV_ROUND_UP((va_bits - PAGE_SHIFT), (PAGE_SHIFT - 3))
>  *
>  * where DIV_ROUND_UP (n, d) = > ((n) + (d) - 1) / (d)
>  *
>  * We cannot include linux/kernel.h which defines DIV_ROUND_UP here
>  * due to build issues. So we open code the DIV_ROUND_UP and hence
>  * we get :
>  *  ((va_bits - PAGE_SHIFT) + (PAGE_SHIFT - 3) -1) / (PAGE_SHIFT - 3)
>  *
>  * which gets simplified as :
>  *  (((va_bits) - 4) / (PAGE_SHIFT - 3))
>  *
>  */
> 
> Let me know if you are happy with that ?
> 

I preferred Mark's suggestion, but I don't have the experience with
breaking builds with kernel header includes, so I guess we'll do with
this.

Thanks for adding the comments!
-Christoffer

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

* [PATCHv3 03/11] arm64: Introduce helpers for page table levels
@ 2015-10-15 11:40         ` Christoffer Dall
  0 siblings, 0 replies; 110+ messages in thread
From: Christoffer Dall @ 2015-10-15 11:40 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Oct 15, 2015 at 10:35:38AM +0100, Suzuki K. Poulose wrote:
> On 14/10/15 18:07, Mark Rutland wrote:
> >On Wed, Oct 14, 2015 at 12:20:26PM +0100, Suzuki K. Poulose wrote:
> 
> >>+ * Number of page-table levels required to address 'va_bits' wide
> >>+ * address, without section mapping. We resolve the top (va_bits - PAGE_SHIFT)
> >>+ * bits with (PAGE_SHIFT - 3) bits at each page table level. Hence:
> >>+ *
> >>+ *  levels = DIV_ROUND_UP((va_bits - PAGE_SHIFT), (PAGE_SHIFT - 3))
> >>+ *
> >>+ * We cannot include linux/kernel.h which defines DIV_ROUND_UP here
> >>+ * due to build issues. So we use the following magic formula.
> >>+ */
> >>+#define ARM64_HW_PGTABLE_LEVELS(va_bits) (((va_bits) - 4) / (PAGE_SHIFT - 3))
> >
> >I think I failed the interview question [1]. :(
> >
> >I read the comment to mean this was a brand-new piece of magic, as
> >opposed to a constant-folded copy of DIV_ROUND_UP. So it seems there's
> >still some scope for confusion, even if that only includes me.
> >
> 
> Wouldn't it be better to modify the comment to say, we open coded the DIV_ROUND_UP ?
> We could potentially end up in a conflict if somebody else does __DIV_ROUND_UP.
> I have seen similar issues with the CPU feature series, where if I include one
> particular header file in another, kernel build breaks without giving you a clue,
> what caused the error. Usually due to the multiple definitions (e.g NSEC_PER_SEC)
> and other conflicts. Given that this header file gets included with asm/page.h and
> hence would be used included for people outside arch/arm64, I would prefer, not to
> head there, instead update the comment, something like this :
> 
> 
> /*
>  * Number of page-table levels required to address 'va_bits' wide
>  * address, without section mapping. We resolve the top (va_bits - PAGE_SHIFT)
>  * bits with (PAGE_SHIFT - 3) bits at each page table level. Hence:
>  *
>  *  levels = DIV_ROUND_UP((va_bits - PAGE_SHIFT), (PAGE_SHIFT - 3))
>  *
>  * where DIV_ROUND_UP (n, d) = > ((n) + (d) - 1) / (d)
>  *
>  * We cannot include linux/kernel.h which defines DIV_ROUND_UP here
>  * due to build issues. So we open code the DIV_ROUND_UP and hence
>  * we get :
>  *  ((va_bits - PAGE_SHIFT) + (PAGE_SHIFT - 3) -1) / (PAGE_SHIFT - 3)
>  *
>  * which gets simplified as :
>  *  (((va_bits) - 4) / (PAGE_SHIFT - 3))
>  *
>  */
> 
> Let me know if you are happy with that ?
> 

I preferred Mark's suggestion, but I don't have the experience with
breaking builds with kernel header includes, so I guess we'll do with
this.

Thanks for adding the comments!
-Christoffer

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

* Re: [PATCHv3 08/11] arm64: Check for selected granule support
  2015-10-15 11:25         ` Suzuki K. Poulose
@ 2015-10-15 12:37           ` Mark Rutland
  -1 siblings, 0 replies; 110+ messages in thread
From: Mark Rutland @ 2015-10-15 12:37 UTC (permalink / raw)
  To: Suzuki K. Poulose
  Cc: Jeremy Linton, linux-arm-kernel, steve.capper, ard.biesheuvel,
	marc.zyngier, catalin.marinas, will.deacon, linux-kernel,
	christoffer.dall

On Thu, Oct 15, 2015 at 12:25:33PM +0100, Suzuki K. Poulose wrote:
> On Thu, Oct 15, 2015 at 11:45:15AM +0100, Mark Rutland wrote:
> > On Wed, Oct 14, 2015 at 04:13:47PM -0500, Jeremy Linton wrote:
> > > On 10/14/2015 06:20 AM, Suzuki K. Poulose wrote:
> > > 
> > > >+ * Checks if the selected granule size is supported by the CPU.
> > > >+ * If it doesn't park the CPU
> > > 
> > > The problem is when you park the boot CPU.
> > > 
> > > I think for EFI there is a slightly better error mechanism. This
> > > tweak will print an error and return to the EFI boot manager rather
> > > than hanging the machine without any notification. Now it prints:
> > > 
> > > EFI stub: Booting Linux Kernel...
> > > EFI stub: ERROR: 16K granule not supported by this machine
> > > EFI stub: ERROR: Failed to relocate kernel
> > > FS4:\>
> > 
> > Neat. We should definitely have checks like this in the stub.
> > 
> > However, we still need checks in head.S, given !EFI systems, SMP, and
> > kexec, so this is a complementary mechanism.
> 
> Indeed. I meant to add the above check. The updated patch looks like :
> 
> ----8>----
> 
> Author: Suzuki K. Poulose <suzuki.poulose@arm.com>
> Date:   Wed Oct 14 11:25:16 2015 +0100
> 
>     arm64: Check for selected granule support
>     
>     Ensure that the selected page size is supported by the CPU(s). If it isn't
>     park the CPU. A check is added to the EFI stub to detect if the boot CPU
>     supports the page size, failing which, we fail the boot gracefully, with
>     an error message.
>     
>     Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com>
>     [ Added a check to EFI stub ]
>     Signed-off-by: Jeremy Linton <jeremy.linton@arm.com>

Your sign-off should be last, given you are taking resposibility for
Jeremy's patch.

However, I would prefer that the EFI stub addition were a separate/later
patch.

> diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
> index a7f3d4b..72d814c 100644
> --- a/arch/arm64/include/asm/sysreg.h
> +++ b/arch/arm64/include/asm/sysreg.h
> @@ -44,6 +44,26 @@
>  #define SET_PSTATE_PAN(x) __inst_arm(0xd5000000 | REG_PSTATE_PAN_IMM |\
>  				     (!!x)<<8 | 0x1f)
>  
> +
> +#define ID_AA64MMFR0_TGRAN4_SHIFT	28
> +#define ID_AA64MMFR0_TGRAN64_SHIFT	24
> +#define ID_AA64MMFR0_TGRAN16_SHIFT	20
> +
> +#define ID_AA64MMFR0_TGRAN4_NI		0xf
> +#define ID_AA64MMFR0_TGRAN4_ON		0x0
> +#define ID_AA64MMFR0_TGRAN64_NI		0xf
> +#define ID_AA64MMFR0_TGRAN64_ON		0x0
> +#define ID_AA64MMFR0_TGRAN16_NI		0x0
> +#define ID_AA64MMFR0_TGRAN16_ON		0x1

I still don't like "ON" here -- I thought these would also be changed
s/ON/SUPPORTED/.

> +
> +#if defined(CONFIG_ARM64_4K_PAGES)
> +#define ID_AA64MMFR0_TGRAN_SHIFT	ID_AA64MMFR0_TGRAN4_SHIFT
> +#define ID_AA64MMFR0_TGRAN_SUPPORTED	ID_AA64MMFR0_TGRAN4_ON
> +#else
> +#define ID_AA64MMFR0_TGRAN_SHIFT	ID_AA64MMFR0_TGRAN64_SHIFT
> +#define ID_AA64MMFR0_TGRAN_SUPPORTED	ID_AA64MMFR0_TGRAN64_ON
> +#endif
> +
>  #ifdef __ASSEMBLY__
>  
>  	.irp	num,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30
> diff --git a/arch/arm64/kernel/efi-stub.c b/arch/arm64/kernel/efi-stub.c
> index 816120e..77d7de1 100644
> --- a/arch/arm64/kernel/efi-stub.c
> +++ b/arch/arm64/kernel/efi-stub.c
> @@ -11,8 +11,15 @@
>   */
>  #include <linux/efi.h>
>  #include <asm/efi.h>
> +#include <asm/sysreg.h>
>  #include <asm/sections.h>

Nit: include order.

>  
> +#if defined(CONFIG_ARM64_4K_PAGES)
> +#define PAGE_SIZE_STR	"4K"
> +#elif defined(CONFIG_ARM64_64K_PAGES)
> +#define PAGE_SIZE_STR	"64K"
> +#endif
> +
>  efi_status_t __init handle_kernel_image(efi_system_table_t *sys_table_arg,
>  					unsigned long *image_addr,
>  					unsigned long *image_size,
> @@ -25,6 +32,17 @@ efi_status_t __init handle_kernel_image(efi_system_table_t *sys_table_arg,
>  	unsigned long kernel_size, kernel_memsize = 0;
>  	unsigned long nr_pages;
>  	void *old_image_addr = (void *)*image_addr;
> +	u64 aa64mmfr0_el1;
> +
> +	/*
> +	 * Check to see if the CPU supports the requested pagesize
> +	 */
> +	asm volatile("mrs %0, ID_AA64MMFR0_EL1" : "=r" (aa64mmfr0_el1));

Can we not use read_cpuid() or similar here?

> +	aa64mmfr0_el1 >>= ID_AA64MMFR0_TGRAN_SHIFT;

... and can we not do the shift and mask in one go?

> +	if ((aa64mmfr0_el1 & 0xf) != ID_AA64MMFR0_TGRAN_SUPPORTED) {
> +		pr_efi_err(sys_table_arg, PAGE_SIZE_STR" granule not supported by the CPU\n");

Nit: space before the first quote, please.

Thanks,
Mark.

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

* [PATCHv3 08/11] arm64: Check for selected granule support
@ 2015-10-15 12:37           ` Mark Rutland
  0 siblings, 0 replies; 110+ messages in thread
From: Mark Rutland @ 2015-10-15 12:37 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Oct 15, 2015 at 12:25:33PM +0100, Suzuki K. Poulose wrote:
> On Thu, Oct 15, 2015 at 11:45:15AM +0100, Mark Rutland wrote:
> > On Wed, Oct 14, 2015 at 04:13:47PM -0500, Jeremy Linton wrote:
> > > On 10/14/2015 06:20 AM, Suzuki K. Poulose wrote:
> > > 
> > > >+ * Checks if the selected granule size is supported by the CPU.
> > > >+ * If it doesn't park the CPU
> > > 
> > > The problem is when you park the boot CPU.
> > > 
> > > I think for EFI there is a slightly better error mechanism. This
> > > tweak will print an error and return to the EFI boot manager rather
> > > than hanging the machine without any notification. Now it prints:
> > > 
> > > EFI stub: Booting Linux Kernel...
> > > EFI stub: ERROR: 16K granule not supported by this machine
> > > EFI stub: ERROR: Failed to relocate kernel
> > > FS4:\>
> > 
> > Neat. We should definitely have checks like this in the stub.
> > 
> > However, we still need checks in head.S, given !EFI systems, SMP, and
> > kexec, so this is a complementary mechanism.
> 
> Indeed. I meant to add the above check. The updated patch looks like :
> 
> ----8>----
> 
> Author: Suzuki K. Poulose <suzuki.poulose@arm.com>
> Date:   Wed Oct 14 11:25:16 2015 +0100
> 
>     arm64: Check for selected granule support
>     
>     Ensure that the selected page size is supported by the CPU(s). If it isn't
>     park the CPU. A check is added to the EFI stub to detect if the boot CPU
>     supports the page size, failing which, we fail the boot gracefully, with
>     an error message.
>     
>     Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com>
>     [ Added a check to EFI stub ]
>     Signed-off-by: Jeremy Linton <jeremy.linton@arm.com>

Your sign-off should be last, given you are taking resposibility for
Jeremy's patch.

However, I would prefer that the EFI stub addition were a separate/later
patch.

> diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
> index a7f3d4b..72d814c 100644
> --- a/arch/arm64/include/asm/sysreg.h
> +++ b/arch/arm64/include/asm/sysreg.h
> @@ -44,6 +44,26 @@
>  #define SET_PSTATE_PAN(x) __inst_arm(0xd5000000 | REG_PSTATE_PAN_IMM |\
>  				     (!!x)<<8 | 0x1f)
>  
> +
> +#define ID_AA64MMFR0_TGRAN4_SHIFT	28
> +#define ID_AA64MMFR0_TGRAN64_SHIFT	24
> +#define ID_AA64MMFR0_TGRAN16_SHIFT	20
> +
> +#define ID_AA64MMFR0_TGRAN4_NI		0xf
> +#define ID_AA64MMFR0_TGRAN4_ON		0x0
> +#define ID_AA64MMFR0_TGRAN64_NI		0xf
> +#define ID_AA64MMFR0_TGRAN64_ON		0x0
> +#define ID_AA64MMFR0_TGRAN16_NI		0x0
> +#define ID_AA64MMFR0_TGRAN16_ON		0x1

I still don't like "ON" here -- I thought these would also be changed
s/ON/SUPPORTED/.

> +
> +#if defined(CONFIG_ARM64_4K_PAGES)
> +#define ID_AA64MMFR0_TGRAN_SHIFT	ID_AA64MMFR0_TGRAN4_SHIFT
> +#define ID_AA64MMFR0_TGRAN_SUPPORTED	ID_AA64MMFR0_TGRAN4_ON
> +#else
> +#define ID_AA64MMFR0_TGRAN_SHIFT	ID_AA64MMFR0_TGRAN64_SHIFT
> +#define ID_AA64MMFR0_TGRAN_SUPPORTED	ID_AA64MMFR0_TGRAN64_ON
> +#endif
> +
>  #ifdef __ASSEMBLY__
>  
>  	.irp	num,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30
> diff --git a/arch/arm64/kernel/efi-stub.c b/arch/arm64/kernel/efi-stub.c
> index 816120e..77d7de1 100644
> --- a/arch/arm64/kernel/efi-stub.c
> +++ b/arch/arm64/kernel/efi-stub.c
> @@ -11,8 +11,15 @@
>   */
>  #include <linux/efi.h>
>  #include <asm/efi.h>
> +#include <asm/sysreg.h>
>  #include <asm/sections.h>

Nit: include order.

>  
> +#if defined(CONFIG_ARM64_4K_PAGES)
> +#define PAGE_SIZE_STR	"4K"
> +#elif defined(CONFIG_ARM64_64K_PAGES)
> +#define PAGE_SIZE_STR	"64K"
> +#endif
> +
>  efi_status_t __init handle_kernel_image(efi_system_table_t *sys_table_arg,
>  					unsigned long *image_addr,
>  					unsigned long *image_size,
> @@ -25,6 +32,17 @@ efi_status_t __init handle_kernel_image(efi_system_table_t *sys_table_arg,
>  	unsigned long kernel_size, kernel_memsize = 0;
>  	unsigned long nr_pages;
>  	void *old_image_addr = (void *)*image_addr;
> +	u64 aa64mmfr0_el1;
> +
> +	/*
> +	 * Check to see if the CPU supports the requested pagesize
> +	 */
> +	asm volatile("mrs %0, ID_AA64MMFR0_EL1" : "=r" (aa64mmfr0_el1));

Can we not use read_cpuid() or similar here?

> +	aa64mmfr0_el1 >>= ID_AA64MMFR0_TGRAN_SHIFT;

... and can we not do the shift and mask in one go?

> +	if ((aa64mmfr0_el1 & 0xf) != ID_AA64MMFR0_TGRAN_SUPPORTED) {
> +		pr_efi_err(sys_table_arg, PAGE_SIZE_STR" granule not supported by the CPU\n");

Nit: space before the first quote, please.

Thanks,
Mark.

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

* Re: [PATCHv3 03/11] arm64: Introduce helpers for page table levels
  2015-10-15 11:37     ` Christoffer Dall
@ 2015-10-15 12:44       ` Mark Rutland
  -1 siblings, 0 replies; 110+ messages in thread
From: Mark Rutland @ 2015-10-15 12:44 UTC (permalink / raw)
  To: Christoffer Dall
  Cc: Suzuki K. Poulose, linux-arm-kernel, linux-kernel,
	catalin.marinas, will.deacon, steve.capper, marc.zyngier,
	ard.biesheuvel

On Thu, Oct 15, 2015 at 01:37:35PM +0200, Christoffer Dall wrote:
> On Wed, Oct 14, 2015 at 12:20:26PM +0100, Suzuki K. Poulose wrote:
> > Introduce helpers for finding the number of page table
> > levels required for a given VA width, shift for a particular
> > page table level.
> > 
> > Convert the existing users to the new helpers. More users
> > to follow.
> > 
> > Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> > Cc: Mark Rutland <mark.rutland@arm.com>
> > Cc: Catalin Marinas <catalin.marinas@arm.com>
> > Cc: Will Deacon <will.deacon@arm.com>
> > Cc: Marc Zyngier <marc.zyngier@arm.com>
> > Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com>
> > 
> > ---
> > Changes since V2:
> >   - Add comments around the macros
> >   - Change ARM64_HW_PGTABLE_LEVEL_SHIFT to accept pagetable level as
> >     described by ARM ARM
> > ---
> >  arch/arm64/include/asm/pgtable-hwdef.h |   25 ++++++++++++++++++++++---
> >  1 file changed, 22 insertions(+), 3 deletions(-)
> > 
> > diff --git a/arch/arm64/include/asm/pgtable-hwdef.h b/arch/arm64/include/asm/pgtable-hwdef.h
> > index 95c1ec0..c6194ab 100644
> > --- a/arch/arm64/include/asm/pgtable-hwdef.h
> > +++ b/arch/arm64/include/asm/pgtable-hwdef.h
> > @@ -16,13 +16,31 @@
> >  #ifndef __ASM_PGTABLE_HWDEF_H
> >  #define __ASM_PGTABLE_HWDEF_H
> >  
> > +/*
> > + * Number of page-table levels required to address 'va_bits' wide
> > + * address, without section mapping. We resolve the top (va_bits - PAGE_SHIFT)
> > + * bits with (PAGE_SHIFT - 3) bits at each page table level. Hence:
> > + *
> > + *  levels = DIV_ROUND_UP((va_bits - PAGE_SHIFT), (PAGE_SHIFT - 3))
> > + *
> > + * We cannot include linux/kernel.h which defines DIV_ROUND_UP here
> > + * due to build issues. So we use the following magic formula.
> > + */
> > +#define ARM64_HW_PGTABLE_LEVELS(va_bits) (((va_bits) - 4) / (PAGE_SHIFT - 3))
> > +
> > +/*
> > + * Size mapped by an entry at level n
> > + * We map PAGE_SHIFT - 3 at all levels, except the PAGE_SHIFT bits at the last level
> > + */
> > +#define ARM64_HW_PGTABLE_LEVEL_SHIFT(n)	((PAGE_SHIFT - 3) * (4 - (n)) + 3)
> 
> I feel like I'm partially failing the interview question again, in that
> I don't fully understand the '+ 3' in the end?

The last level handles PAGE_SHIFT bits (the bits from the VA that are
the same in the PA). We only accounted for (PAGE_SHIFT - 3) bits at each
level when multiplying, so we add those 3 missing bits back at the end.

Thanks,
Mark.

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

* [PATCHv3 03/11] arm64: Introduce helpers for page table levels
@ 2015-10-15 12:44       ` Mark Rutland
  0 siblings, 0 replies; 110+ messages in thread
From: Mark Rutland @ 2015-10-15 12:44 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Oct 15, 2015 at 01:37:35PM +0200, Christoffer Dall wrote:
> On Wed, Oct 14, 2015 at 12:20:26PM +0100, Suzuki K. Poulose wrote:
> > Introduce helpers for finding the number of page table
> > levels required for a given VA width, shift for a particular
> > page table level.
> > 
> > Convert the existing users to the new helpers. More users
> > to follow.
> > 
> > Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> > Cc: Mark Rutland <mark.rutland@arm.com>
> > Cc: Catalin Marinas <catalin.marinas@arm.com>
> > Cc: Will Deacon <will.deacon@arm.com>
> > Cc: Marc Zyngier <marc.zyngier@arm.com>
> > Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com>
> > 
> > ---
> > Changes since V2:
> >   - Add comments around the macros
> >   - Change ARM64_HW_PGTABLE_LEVEL_SHIFT to accept pagetable level as
> >     described by ARM ARM
> > ---
> >  arch/arm64/include/asm/pgtable-hwdef.h |   25 ++++++++++++++++++++++---
> >  1 file changed, 22 insertions(+), 3 deletions(-)
> > 
> > diff --git a/arch/arm64/include/asm/pgtable-hwdef.h b/arch/arm64/include/asm/pgtable-hwdef.h
> > index 95c1ec0..c6194ab 100644
> > --- a/arch/arm64/include/asm/pgtable-hwdef.h
> > +++ b/arch/arm64/include/asm/pgtable-hwdef.h
> > @@ -16,13 +16,31 @@
> >  #ifndef __ASM_PGTABLE_HWDEF_H
> >  #define __ASM_PGTABLE_HWDEF_H
> >  
> > +/*
> > + * Number of page-table levels required to address 'va_bits' wide
> > + * address, without section mapping. We resolve the top (va_bits - PAGE_SHIFT)
> > + * bits with (PAGE_SHIFT - 3) bits at each page table level. Hence:
> > + *
> > + *  levels = DIV_ROUND_UP((va_bits - PAGE_SHIFT), (PAGE_SHIFT - 3))
> > + *
> > + * We cannot include linux/kernel.h which defines DIV_ROUND_UP here
> > + * due to build issues. So we use the following magic formula.
> > + */
> > +#define ARM64_HW_PGTABLE_LEVELS(va_bits) (((va_bits) - 4) / (PAGE_SHIFT - 3))
> > +
> > +/*
> > + * Size mapped by an entry at level n
> > + * We map PAGE_SHIFT - 3 at all levels, except the PAGE_SHIFT bits at the last level
> > + */
> > +#define ARM64_HW_PGTABLE_LEVEL_SHIFT(n)	((PAGE_SHIFT - 3) * (4 - (n)) + 3)
> 
> I feel like I'm partially failing the interview question again, in that
> I don't fully understand the '+ 3' in the end?

The last level handles PAGE_SHIFT bits (the bits from the VA that are
the same in the PA). We only accounted for (PAGE_SHIFT - 3) bits at each
level when multiplying, so we add those 3 missing bits back at the end.

Thanks,
Mark.

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

* Re: [PATCHv3 08/11] arm64: Check for selected granule support
  2015-10-15 12:37           ` Mark Rutland
@ 2015-10-15 12:58             ` Suzuki K. Poulose
  -1 siblings, 0 replies; 110+ messages in thread
From: Suzuki K. Poulose @ 2015-10-15 12:58 UTC (permalink / raw)
  To: Mark Rutland
  Cc: Jeremy Linton, linux-arm-kernel, steve.capper, ard.biesheuvel,
	marc.zyngier, catalin.marinas, will.deacon, linux-kernel,
	christoffer.dall

On 15/10/15 13:37, Mark Rutland wrote:
> On Thu, Oct 15, 2015 at 12:25:33PM +0100, Suzuki K. Poulose wrote:
>> On Thu, Oct 15, 2015 at 11:45:15AM +0100, Mark Rutland wrote:
>>> On Wed, Oct 14, 2015 at 04:13:47PM -0500, Jeremy Linton wrote:
>>>> On 10/14/2015 06:20 AM, Suzuki K. Poulose wrote:


>>
>> ----8>----
>>
>> Author: Suzuki K. Poulose <suzuki.poulose@arm.com>
>> Date:   Wed Oct 14 11:25:16 2015 +0100
>>
>>      arm64: Check for selected granule support
>>
>>      Ensure that the selected page size is supported by the CPU(s). If it isn't
>>      park the CPU. A check is added to the EFI stub to detect if the boot CPU
>>      supports the page size, failing which, we fail the boot gracefully, with
>>      an error message.
>>
>>      Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com>
>>      [ Added a check to EFI stub ]
>>      Signed-off-by: Jeremy Linton <jeremy.linton@arm.com>
>
> Your sign-off should be last, given you are taking resposibility for
> Jeremy's patch.

OK, I was a bit confused about how it should look like. I kept it on top
so that I could add [ ] for Jeremy's contribution.

>
> However, I would prefer that the EFI stub addition were a separate/later
> patch.

OK, that makes sense.

>
>> diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
>> index a7f3d4b..72d814c 100644
>> --- a/arch/arm64/include/asm/sysreg.h
>> +++ b/arch/arm64/include/asm/sysreg.h

>> +#define ID_AA64MMFR0_TGRAN4_NI		0xf
>> +#define ID_AA64MMFR0_TGRAN4_ON		0x0
>> +#define ID_AA64MMFR0_TGRAN64_NI		0xf
>> +#define ID_AA64MMFR0_TGRAN64_ON		0x0
>> +#define ID_AA64MMFR0_TGRAN16_NI		0x0
>> +#define ID_AA64MMFR0_TGRAN16_ON		0x1
>
> I still don't like "ON" here -- I thought these would also be changed
> s/ON/SUPPORTED/.

I know and I expected that. I have "_ON" in my 'CPU feature' series, which
will/can be reused here. Hence kept it _ON. I can change it everywhere to
_SUPPORTED, since I may need to spin another version for that.


>>   #include <linux/efi.h>
>>   #include <asm/efi.h>
>> +#include <asm/sysreg.h>
>>   #include <asm/sections.h>
>
> Nit: include order.

OK

>
>>
>> +#if defined(CONFIG_ARM64_4K_PAGES)
>> +#define PAGE_SIZE_STR	"4K"
>> +#elif defined(CONFIG_ARM64_64K_PAGES)
>> +#define PAGE_SIZE_STR	"64K"
>> +#endif
>> +
>>   efi_status_t __init handle_kernel_image(efi_system_table_t *sys_table_arg,
>>   					unsigned long *image_addr,
>>   					unsigned long *image_size,
>> @@ -25,6 +32,17 @@ efi_status_t __init handle_kernel_image(efi_system_table_t *sys_table_arg,
>>   	unsigned long kernel_size, kernel_memsize = 0;
>>   	unsigned long nr_pages;
>>   	void *old_image_addr = (void *)*image_addr;
>> +	u64 aa64mmfr0_el1;
>> +
>> +	/*
>> +	 * Check to see if the CPU supports the requested pagesize
>> +	 */
>> +	asm volatile("mrs %0, ID_AA64MMFR0_EL1" : "=r" (aa64mmfr0_el1));
>
> Can we not use read_cpuid() or similar here?

Yes, I will try that out. I didn't want to include additional header-files
in efi-stub.c.


>> +	aa64mmfr0_el1 >>= ID_AA64MMFR0_TGRAN_SHIFT;
>
> ... and can we not do the shift and mask in one go?
>

>> +	if ((aa64mmfr0_el1 & 0xf) != ID_AA64MMFR0_TGRAN_SUPPORTED) {
>> +		pr_efi_err(sys_table_arg, PAGE_SIZE_STR" granule not supported by the CPU\n");
>
> Nit: space before the first quote, please.

Will do

Thanks
Suzuki


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

* [PATCHv3 08/11] arm64: Check for selected granule support
@ 2015-10-15 12:58             ` Suzuki K. Poulose
  0 siblings, 0 replies; 110+ messages in thread
From: Suzuki K. Poulose @ 2015-10-15 12:58 UTC (permalink / raw)
  To: linux-arm-kernel

On 15/10/15 13:37, Mark Rutland wrote:
> On Thu, Oct 15, 2015 at 12:25:33PM +0100, Suzuki K. Poulose wrote:
>> On Thu, Oct 15, 2015 at 11:45:15AM +0100, Mark Rutland wrote:
>>> On Wed, Oct 14, 2015 at 04:13:47PM -0500, Jeremy Linton wrote:
>>>> On 10/14/2015 06:20 AM, Suzuki K. Poulose wrote:


>>
>> ----8>----
>>
>> Author: Suzuki K. Poulose <suzuki.poulose@arm.com>
>> Date:   Wed Oct 14 11:25:16 2015 +0100
>>
>>      arm64: Check for selected granule support
>>
>>      Ensure that the selected page size is supported by the CPU(s). If it isn't
>>      park the CPU. A check is added to the EFI stub to detect if the boot CPU
>>      supports the page size, failing which, we fail the boot gracefully, with
>>      an error message.
>>
>>      Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com>
>>      [ Added a check to EFI stub ]
>>      Signed-off-by: Jeremy Linton <jeremy.linton@arm.com>
>
> Your sign-off should be last, given you are taking resposibility for
> Jeremy's patch.

OK, I was a bit confused about how it should look like. I kept it on top
so that I could add [ ] for Jeremy's contribution.

>
> However, I would prefer that the EFI stub addition were a separate/later
> patch.

OK, that makes sense.

>
>> diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
>> index a7f3d4b..72d814c 100644
>> --- a/arch/arm64/include/asm/sysreg.h
>> +++ b/arch/arm64/include/asm/sysreg.h

>> +#define ID_AA64MMFR0_TGRAN4_NI		0xf
>> +#define ID_AA64MMFR0_TGRAN4_ON		0x0
>> +#define ID_AA64MMFR0_TGRAN64_NI		0xf
>> +#define ID_AA64MMFR0_TGRAN64_ON		0x0
>> +#define ID_AA64MMFR0_TGRAN16_NI		0x0
>> +#define ID_AA64MMFR0_TGRAN16_ON		0x1
>
> I still don't like "ON" here -- I thought these would also be changed
> s/ON/SUPPORTED/.

I know and I expected that. I have "_ON" in my 'CPU feature' series, which
will/can be reused here. Hence kept it _ON. I can change it everywhere to
_SUPPORTED, since I may need to spin another version for that.


>>   #include <linux/efi.h>
>>   #include <asm/efi.h>
>> +#include <asm/sysreg.h>
>>   #include <asm/sections.h>
>
> Nit: include order.

OK

>
>>
>> +#if defined(CONFIG_ARM64_4K_PAGES)
>> +#define PAGE_SIZE_STR	"4K"
>> +#elif defined(CONFIG_ARM64_64K_PAGES)
>> +#define PAGE_SIZE_STR	"64K"
>> +#endif
>> +
>>   efi_status_t __init handle_kernel_image(efi_system_table_t *sys_table_arg,
>>   					unsigned long *image_addr,
>>   					unsigned long *image_size,
>> @@ -25,6 +32,17 @@ efi_status_t __init handle_kernel_image(efi_system_table_t *sys_table_arg,
>>   	unsigned long kernel_size, kernel_memsize = 0;
>>   	unsigned long nr_pages;
>>   	void *old_image_addr = (void *)*image_addr;
>> +	u64 aa64mmfr0_el1;
>> +
>> +	/*
>> +	 * Check to see if the CPU supports the requested pagesize
>> +	 */
>> +	asm volatile("mrs %0, ID_AA64MMFR0_EL1" : "=r" (aa64mmfr0_el1));
>
> Can we not use read_cpuid() or similar here?

Yes, I will try that out. I didn't want to include additional header-files
in efi-stub.c.


>> +	aa64mmfr0_el1 >>= ID_AA64MMFR0_TGRAN_SHIFT;
>
> ... and can we not do the shift and mask in one go?
>

>> +	if ((aa64mmfr0_el1 & 0xf) != ID_AA64MMFR0_TGRAN_SUPPORTED) {
>> +		pr_efi_err(sys_table_arg, PAGE_SIZE_STR" granule not supported by the CPU\n");
>
> Nit: space before the first quote, please.

Will do

Thanks
Suzuki

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

* Re: [PATCHv3 03/11] arm64: Introduce helpers for page table levels
  2015-10-15 12:44       ` Mark Rutland
@ 2015-10-15 13:14         ` Suzuki K. Poulose
  -1 siblings, 0 replies; 110+ messages in thread
From: Suzuki K. Poulose @ 2015-10-15 13:14 UTC (permalink / raw)
  To: Mark Rutland, Christoffer Dall
  Cc: linux-arm-kernel, linux-kernel, catalin.marinas, will.deacon,
	steve.capper, marc.zyngier, ard.biesheuvel

On 15/10/15 13:44, Mark Rutland wrote:
> On Thu, Oct 15, 2015 at 01:37:35PM +0200, Christoffer Dall wrote:
>> On Wed, Oct 14, 2015 at 12:20:26PM +0100, Suzuki K. Poulose wrote:
>>> Introduce helpers for finding the number of page table
>>> levels required for a given VA width, shift for a particular
>>> page table level.

>>> +/*
>>> + * Size mapped by an entry at level n
>>> + * We map PAGE_SHIFT - 3 at all levels, except the PAGE_SHIFT bits at the last level
>>> + */
>>> +#define ARM64_HW_PGTABLE_LEVEL_SHIFT(n)	((PAGE_SHIFT - 3) * (4 - (n)) + 3)
>>
>> I feel like I'm partially failing the interview question again, in that
>> I don't fully understand the '+ 3' in the end?
>
> The last level handles PAGE_SHIFT bits (the bits from the VA that are
> the same in the PA). We only accounted for (PAGE_SHIFT - 3) bits at each
> level when multiplying, so we add those 3 missing bits back at the end.
>

Something like :

/*
  * Size mapped by an entry at level n
  * We map PAGE_SHIFT - 3 at all levels, except the last, where we map PAGE_SHIFT bits.
  * The maximum number of levels supported by the architecture is 4. Hence at starting
  * at level n, we hanve (4 - n) levels of translation. So, the total number of bits
  * mapped by an entry at level n is :
  *
  *  ((4 - n) - 1) * (PAGE_SHIFT - 3) + PAGE_SHIFT
  *
  * Rearranging it a bit we get :
  *   (4 - n) * (PAGE_SHIFT - 3) + 3
  */

Or we could use the formula without rearranging.

Thanks
Suzuki


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

* [PATCHv3 03/11] arm64: Introduce helpers for page table levels
@ 2015-10-15 13:14         ` Suzuki K. Poulose
  0 siblings, 0 replies; 110+ messages in thread
From: Suzuki K. Poulose @ 2015-10-15 13:14 UTC (permalink / raw)
  To: linux-arm-kernel

On 15/10/15 13:44, Mark Rutland wrote:
> On Thu, Oct 15, 2015 at 01:37:35PM +0200, Christoffer Dall wrote:
>> On Wed, Oct 14, 2015 at 12:20:26PM +0100, Suzuki K. Poulose wrote:
>>> Introduce helpers for finding the number of page table
>>> levels required for a given VA width, shift for a particular
>>> page table level.

>>> +/*
>>> + * Size mapped by an entry at level n
>>> + * We map PAGE_SHIFT - 3 at all levels, except the PAGE_SHIFT bits at the last level
>>> + */
>>> +#define ARM64_HW_PGTABLE_LEVEL_SHIFT(n)	((PAGE_SHIFT - 3) * (4 - (n)) + 3)
>>
>> I feel like I'm partially failing the interview question again, in that
>> I don't fully understand the '+ 3' in the end?
>
> The last level handles PAGE_SHIFT bits (the bits from the VA that are
> the same in the PA). We only accounted for (PAGE_SHIFT - 3) bits at each
> level when multiplying, so we add those 3 missing bits back at the end.
>

Something like :

/*
  * Size mapped by an entry at level n
  * We map PAGE_SHIFT - 3 at all levels, except the last, where we map PAGE_SHIFT bits.
  * The maximum number of levels supported by the architecture is 4. Hence at starting
  * at level n, we hanve (4 - n) levels of translation. So, the total number of bits
  * mapped by an entry at level n is :
  *
  *  ((4 - n) - 1) * (PAGE_SHIFT - 3) + PAGE_SHIFT
  *
  * Rearranging it a bit we get :
  *   (4 - n) * (PAGE_SHIFT - 3) + 3
  */

Or we could use the formula without rearranging.

Thanks
Suzuki

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

* Re: [PATCHv3 03/11] arm64: Introduce helpers for page table levels
  2015-10-15 13:14         ` Suzuki K. Poulose
@ 2015-10-15 13:30           ` Christoffer Dall
  -1 siblings, 0 replies; 110+ messages in thread
From: Christoffer Dall @ 2015-10-15 13:30 UTC (permalink / raw)
  To: Suzuki K. Poulose
  Cc: Mark Rutland, linux-arm-kernel, linux-kernel, catalin.marinas,
	will.deacon, steve.capper, marc.zyngier, ard.biesheuvel

On Thu, Oct 15, 2015 at 02:14:22PM +0100, Suzuki K. Poulose wrote:
> On 15/10/15 13:44, Mark Rutland wrote:
> >On Thu, Oct 15, 2015 at 01:37:35PM +0200, Christoffer Dall wrote:
> >>On Wed, Oct 14, 2015 at 12:20:26PM +0100, Suzuki K. Poulose wrote:
> >>>Introduce helpers for finding the number of page table
> >>>levels required for a given VA width, shift for a particular
> >>>page table level.
> 
> >>>+/*
> >>>+ * Size mapped by an entry at level n
> >>>+ * We map PAGE_SHIFT - 3 at all levels, except the PAGE_SHIFT bits at the last level
> >>>+ */
> >>>+#define ARM64_HW_PGTABLE_LEVEL_SHIFT(n)	((PAGE_SHIFT - 3) * (4 - (n)) + 3)
> >>
> >>I feel like I'm partially failing the interview question again, in that
> >>I don't fully understand the '+ 3' in the end?
> >
> >The last level handles PAGE_SHIFT bits (the bits from the VA that are
> >the same in the PA). We only accounted for (PAGE_SHIFT - 3) bits at each
> >level when multiplying, so we add those 3 missing bits back at the end.
> >
> 
> Something like :
> 
> /*
>  * Size mapped by an entry at level n
>  * We map PAGE_SHIFT - 3 at all levels, except the last, where we map PAGE_SHIFT bits.
>  * The maximum number of levels supported by the architecture is 4. Hence at starting
>  * at level n, we hanve (4 - n) levels of translation. So, the total number of bits

nit: s/hanve/have/

>  * mapped by an entry at level n is :
>  *
>  *  ((4 - n) - 1) * (PAGE_SHIFT - 3) + PAGE_SHIFT
>  *
>  * Rearranging it a bit we get :
>  *   (4 - n) * (PAGE_SHIFT - 3) + 3
>  */
> 
> Or we could use the formula without rearranging.
> 
Either way, even I get it now.

Thanks for the explanation!!

Assuming some version of this goes in:

Acked-by: Christoffer Dall <christoffer.dall@linaro.org>

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

* [PATCHv3 03/11] arm64: Introduce helpers for page table levels
@ 2015-10-15 13:30           ` Christoffer Dall
  0 siblings, 0 replies; 110+ messages in thread
From: Christoffer Dall @ 2015-10-15 13:30 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Oct 15, 2015 at 02:14:22PM +0100, Suzuki K. Poulose wrote:
> On 15/10/15 13:44, Mark Rutland wrote:
> >On Thu, Oct 15, 2015 at 01:37:35PM +0200, Christoffer Dall wrote:
> >>On Wed, Oct 14, 2015 at 12:20:26PM +0100, Suzuki K. Poulose wrote:
> >>>Introduce helpers for finding the number of page table
> >>>levels required for a given VA width, shift for a particular
> >>>page table level.
> 
> >>>+/*
> >>>+ * Size mapped by an entry at level n
> >>>+ * We map PAGE_SHIFT - 3 at all levels, except the PAGE_SHIFT bits at the last level
> >>>+ */
> >>>+#define ARM64_HW_PGTABLE_LEVEL_SHIFT(n)	((PAGE_SHIFT - 3) * (4 - (n)) + 3)
> >>
> >>I feel like I'm partially failing the interview question again, in that
> >>I don't fully understand the '+ 3' in the end?
> >
> >The last level handles PAGE_SHIFT bits (the bits from the VA that are
> >the same in the PA). We only accounted for (PAGE_SHIFT - 3) bits at each
> >level when multiplying, so we add those 3 missing bits back at the end.
> >
> 
> Something like :
> 
> /*
>  * Size mapped by an entry at level n
>  * We map PAGE_SHIFT - 3 at all levels, except the last, where we map PAGE_SHIFT bits.
>  * The maximum number of levels supported by the architecture is 4. Hence at starting
>  * at level n, we hanve (4 - n) levels of translation. So, the total number of bits

nit: s/hanve/have/

>  * mapped by an entry at level n is :
>  *
>  *  ((4 - n) - 1) * (PAGE_SHIFT - 3) + PAGE_SHIFT
>  *
>  * Rearranging it a bit we get :
>  *   (4 - n) * (PAGE_SHIFT - 3) + 3
>  */
> 
> Or we could use the formula without rearranging.
> 
Either way, even I get it now.

Thanks for the explanation!!

Assuming some version of this goes in:

Acked-by: Christoffer Dall <christoffer.dall@linaro.org>

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

* Re: [PATCHv3 03/11] arm64: Introduce helpers for page table levels
  2015-10-15 13:30           ` Christoffer Dall
@ 2015-10-15 13:48             ` Suzuki K. Poulose
  -1 siblings, 0 replies; 110+ messages in thread
From: Suzuki K. Poulose @ 2015-10-15 13:48 UTC (permalink / raw)
  To: Christoffer Dall
  Cc: Mark Rutland, linux-arm-kernel, linux-kernel, catalin.marinas,
	will.deacon, steve.capper, marc.zyngier, ard.biesheuvel

On 15/10/15 14:30, Christoffer Dall wrote:
> On Thu, Oct 15, 2015 at 02:14:22PM +0100, Suzuki K. Poulose wrote:
>> On 15/10/15 13:44, Mark Rutland wrote:
>>> On Thu, Oct 15, 2015 at 01:37:35PM +0200, Christoffer Dall wrote:
>>>> On Wed, Oct 14, 2015 at 12:20:26PM +0100, Suzuki K. Poulose wrote:


>>   * The maximum number of levels supported by the architecture is 4. Hence at starting
>>   * at level n, we hanve (4 - n) levels of translation. So, the total number of bits
>
> nit: s/hanve/have/

Fixed.

>
>>   * mapped by an entry at level n is :
>>   *
>>   *  ((4 - n) - 1) * (PAGE_SHIFT - 3) + PAGE_SHIFT
>>   *
>>   * Rearranging it a bit we get :
>>   *   (4 - n) * (PAGE_SHIFT - 3) + 3
>>   */
>>
>> Or we could use the formula without rearranging.
>>
> Either way, even I get it now.
>
> Thanks for the explanation!!

:). I was involved too much in these calculations that, the formula looked
obvious to me, when I wrote it. But yes, I did realise that it is indeed
complicated, once I really started looking at explaining why I wrote it so.
Thanks for being patient :) and complaining peacefully !

Btw, I have a revised (hopefully better) version here :

/*
  * Size mapped by an entry at level n ( 0 <= n <= 3)
  * We map (PAGE_SHIFT - 3) at all translation levels and PAGE_SHIFT bits
  * in the final page. The maximum number of translation levels supported by
  * the architecture is 4. Hence, starting at at level n, we have further
  * ((4 - n) - 1) levels of translation excluding the offset within the page.
  * So, the total number of bits mapped by an entry at level n is :
  *
  *  ((4 - n) - 1) * (PAGE_SHIFT - 3) + PAGE_SHIFT
  *
  * Rearranging it a bit we get :
  *   (4 - n) * (PAGE_SHIFT - 3) + 3
  */


>
> Assuming some version of this goes in:
>
> Acked-by: Christoffer Dall <christoffer.dall@linaro.org>
>

Thanks. I lost two interview questions though ;)

Suzuki


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

* [PATCHv3 03/11] arm64: Introduce helpers for page table levels
@ 2015-10-15 13:48             ` Suzuki K. Poulose
  0 siblings, 0 replies; 110+ messages in thread
From: Suzuki K. Poulose @ 2015-10-15 13:48 UTC (permalink / raw)
  To: linux-arm-kernel

On 15/10/15 14:30, Christoffer Dall wrote:
> On Thu, Oct 15, 2015 at 02:14:22PM +0100, Suzuki K. Poulose wrote:
>> On 15/10/15 13:44, Mark Rutland wrote:
>>> On Thu, Oct 15, 2015 at 01:37:35PM +0200, Christoffer Dall wrote:
>>>> On Wed, Oct 14, 2015 at 12:20:26PM +0100, Suzuki K. Poulose wrote:


>>   * The maximum number of levels supported by the architecture is 4. Hence at starting
>>   * at level n, we hanve (4 - n) levels of translation. So, the total number of bits
>
> nit: s/hanve/have/

Fixed.

>
>>   * mapped by an entry at level n is :
>>   *
>>   *  ((4 - n) - 1) * (PAGE_SHIFT - 3) + PAGE_SHIFT
>>   *
>>   * Rearranging it a bit we get :
>>   *   (4 - n) * (PAGE_SHIFT - 3) + 3
>>   */
>>
>> Or we could use the formula without rearranging.
>>
> Either way, even I get it now.
>
> Thanks for the explanation!!

:). I was involved too much in these calculations that, the formula looked
obvious to me, when I wrote it. But yes, I did realise that it is indeed
complicated, once I really started looking at explaining why I wrote it so.
Thanks for being patient :) and complaining peacefully !

Btw, I have a revised (hopefully better) version here :

/*
  * Size mapped by an entry at level n ( 0 <= n <= 3)
  * We map (PAGE_SHIFT - 3) at all translation levels and PAGE_SHIFT bits
  * in the final page. The maximum number of translation levels supported by
  * the architecture is 4. Hence, starting at at level n, we have further
  * ((4 - n) - 1) levels of translation excluding the offset within the page.
  * So, the total number of bits mapped by an entry@level n is :
  *
  *  ((4 - n) - 1) * (PAGE_SHIFT - 3) + PAGE_SHIFT
  *
  * Rearranging it a bit we get :
  *   (4 - n) * (PAGE_SHIFT - 3) + 3
  */


>
> Assuming some version of this goes in:
>
> Acked-by: Christoffer Dall <christoffer.dall@linaro.org>
>

Thanks. I lost two interview questions though ;)

Suzuki

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

* Re: [PATCHv3 10/11] arm64: Add 16K page size support
  2015-10-14 11:20   ` Suzuki K. Poulose
@ 2015-10-15 14:06     ` Mark Rutland
  -1 siblings, 0 replies; 110+ messages in thread
From: Mark Rutland @ 2015-10-15 14:06 UTC (permalink / raw)
  To: Suzuki K. Poulose
  Cc: linux-arm-kernel, linux-kernel, catalin.marinas, will.deacon,
	steve.capper, marc.zyngier, ard.biesheuvel, christoffer.dall,
	Jeremy Linton

Hi,

> +config ARM64_16K_PAGES
> +	bool "16KB"
> +	help
> +	  The system will use 16KB pages support. AArch32 emulation
> +	  requires applications compiled with 16K(or multiple of 16K)
> +	  aligned segments.

Nit: missing space before '('
Nit: 'a multiple of'

> @@ -503,6 +517,7 @@ config XEN
>  config FORCE_MAX_ZONEORDER
>  	int
>  	default "14" if (ARM64_64K_PAGES && TRANSPARENT_HUGEPAGE)
> +	default "12" if (ARM64_16K_PAGES && TRANSPARENT_HUGEPAGE)
>  	default "11"

I'm a little lost here. How are these numbers derived?

>  menuconfig ARMV8_DEPRECATED
> @@ -689,9 +704,9 @@ config COMPAT
>  	  the user helper functions, VFP support and the ptrace interface are
>  	  handled appropriately by the kernel.
>  
> -	  If you also enabled CONFIG_ARM64_64K_PAGES, please be aware that you
> -	  will only be able to execute AArch32 binaries that were compiled with
> -	  64k aligned segments.
> +	  If you use a page size other than 4KB(i.e, 16KB or 64KB), please be aware

Nit: missing space before '(' please.

> diff --git a/arch/arm64/include/asm/fixmap.h b/arch/arm64/include/asm/fixmap.h
> index 8b9884c..a294c70 100644
> --- a/arch/arm64/include/asm/fixmap.h
> +++ b/arch/arm64/include/asm/fixmap.h
> @@ -55,8 +55,10 @@ enum fixed_addresses {
>  	 * Temporary boot-time mappings, used by early_ioremap(),
>  	 * before ioremap() is functional.
>  	 */
> -#ifdef CONFIG_ARM64_64K_PAGES
> +#if	defined(CONFIG_ARM64_64K_PAGES)
>  #define NR_FIX_BTMAPS		4
> +#elif	defined (CONFIG_ARM64_16K_PAGES)
> +#define NR_FIX_BTMAPS		16
>  #else
>  #define NR_FIX_BTMAPS		64
>  #endif

We could include <linux/sizes.h> and simplify this to:

#define NR_FIX_BTMAPS (SZ_256K / PAGE_SIZE)

Which works for me locally.

> diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h
> index 5eac6a2..90c7ff2 100644
> --- a/arch/arm64/include/asm/thread_info.h
> +++ b/arch/arm64/include/asm/thread_info.h
> @@ -25,6 +25,8 @@
>  
>  #ifdef CONFIG_ARM64_4K_PAGES
>  #define THREAD_SIZE_ORDER	2
> +#elif defined(CONFIG_ARM64_16K_PAGES)
> +#define THREAD_SIZE_ORDER	0
>  #endif
>  #define THREAD_SIZE		16384

The above looks correct.

As an open/general question, why do both THREAD_SIZE_ORDER and
THREAD_SIZE exist? One really should be defined in terms of the other.

As far as I can tell,the only user of THREAD_SIZE_ORDER outside of arch
code is fork.c, which could calculate it as:

ilog2(DIV_ROUND_UP(THREAD_SIZE, PAGE_SIZE))

Though I suspect we can't do that in a macro here for fear of a fragile
build, so that's something for another time.

> diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
> index b6aa9e0..2ed57a8 100644
> --- a/arch/arm64/kernel/head.S
> +++ b/arch/arm64/kernel/head.S
> @@ -624,7 +624,12 @@ ENDPROC(__secondary_switched)
>  #define id_aa64mmfr0_tgran_shift	ID_AA64MMFR0_TGRAN64_SHIFT
>  #define id_aa64mmfr0_tgran_on		ID_AA64MMFR0_TGRAN64_ON
>  
> -#else
> +#elif	defined(CONFIG_ARM64_16K_PAGES)
> +
> +#define id_aa64mmfr0_tgran_shift	ID_AA64MMFR0_TGRAN16_SHIFT
> +#define id_aa64mmfr0_tgran_on		ID_AA64MMFR0_TGRAN16_ON
> +
> +#elif	defined(CONFIG_ARM64_4K_PAGES)
>  
>  #define id_aa64mmfr0_tgran_shift	ID_AA64MMFR0_TGRAN4_SHIFT
>  #define id_aa64mmfr0_tgran_on		ID_AA64MMFR0_TGRAN4_ON

I assume you'll s/ON/SUPPORTED/ per comments in another thread.

Otherwise this looks fine to me.

Thanks,
Mark.

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

* [PATCHv3 10/11] arm64: Add 16K page size support
@ 2015-10-15 14:06     ` Mark Rutland
  0 siblings, 0 replies; 110+ messages in thread
From: Mark Rutland @ 2015-10-15 14:06 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

> +config ARM64_16K_PAGES
> +	bool "16KB"
> +	help
> +	  The system will use 16KB pages support. AArch32 emulation
> +	  requires applications compiled with 16K(or multiple of 16K)
> +	  aligned segments.

Nit: missing space before '('
Nit: 'a multiple of'

> @@ -503,6 +517,7 @@ config XEN
>  config FORCE_MAX_ZONEORDER
>  	int
>  	default "14" if (ARM64_64K_PAGES && TRANSPARENT_HUGEPAGE)
> +	default "12" if (ARM64_16K_PAGES && TRANSPARENT_HUGEPAGE)
>  	default "11"

I'm a little lost here. How are these numbers derived?

>  menuconfig ARMV8_DEPRECATED
> @@ -689,9 +704,9 @@ config COMPAT
>  	  the user helper functions, VFP support and the ptrace interface are
>  	  handled appropriately by the kernel.
>  
> -	  If you also enabled CONFIG_ARM64_64K_PAGES, please be aware that you
> -	  will only be able to execute AArch32 binaries that were compiled with
> -	  64k aligned segments.
> +	  If you use a page size other than 4KB(i.e, 16KB or 64KB), please be aware

Nit: missing space before '(' please.

> diff --git a/arch/arm64/include/asm/fixmap.h b/arch/arm64/include/asm/fixmap.h
> index 8b9884c..a294c70 100644
> --- a/arch/arm64/include/asm/fixmap.h
> +++ b/arch/arm64/include/asm/fixmap.h
> @@ -55,8 +55,10 @@ enum fixed_addresses {
>  	 * Temporary boot-time mappings, used by early_ioremap(),
>  	 * before ioremap() is functional.
>  	 */
> -#ifdef CONFIG_ARM64_64K_PAGES
> +#if	defined(CONFIG_ARM64_64K_PAGES)
>  #define NR_FIX_BTMAPS		4
> +#elif	defined (CONFIG_ARM64_16K_PAGES)
> +#define NR_FIX_BTMAPS		16
>  #else
>  #define NR_FIX_BTMAPS		64
>  #endif

We could include <linux/sizes.h> and simplify this to:

#define NR_FIX_BTMAPS (SZ_256K / PAGE_SIZE)

Which works for me locally.

> diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h
> index 5eac6a2..90c7ff2 100644
> --- a/arch/arm64/include/asm/thread_info.h
> +++ b/arch/arm64/include/asm/thread_info.h
> @@ -25,6 +25,8 @@
>  
>  #ifdef CONFIG_ARM64_4K_PAGES
>  #define THREAD_SIZE_ORDER	2
> +#elif defined(CONFIG_ARM64_16K_PAGES)
> +#define THREAD_SIZE_ORDER	0
>  #endif
>  #define THREAD_SIZE		16384

The above looks correct.

As an open/general question, why do both THREAD_SIZE_ORDER and
THREAD_SIZE exist? One really should be defined in terms of the other.

As far as I can tell,the only user of THREAD_SIZE_ORDER outside of arch
code is fork.c, which could calculate it as:

ilog2(DIV_ROUND_UP(THREAD_SIZE, PAGE_SIZE))

Though I suspect we can't do that in a macro here for fear of a fragile
build, so that's something for another time.

> diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
> index b6aa9e0..2ed57a8 100644
> --- a/arch/arm64/kernel/head.S
> +++ b/arch/arm64/kernel/head.S
> @@ -624,7 +624,12 @@ ENDPROC(__secondary_switched)
>  #define id_aa64mmfr0_tgran_shift	ID_AA64MMFR0_TGRAN64_SHIFT
>  #define id_aa64mmfr0_tgran_on		ID_AA64MMFR0_TGRAN64_ON
>  
> -#else
> +#elif	defined(CONFIG_ARM64_16K_PAGES)
> +
> +#define id_aa64mmfr0_tgran_shift	ID_AA64MMFR0_TGRAN16_SHIFT
> +#define id_aa64mmfr0_tgran_on		ID_AA64MMFR0_TGRAN16_ON
> +
> +#elif	defined(CONFIG_ARM64_4K_PAGES)
>  
>  #define id_aa64mmfr0_tgran_shift	ID_AA64MMFR0_TGRAN4_SHIFT
>  #define id_aa64mmfr0_tgran_on		ID_AA64MMFR0_TGRAN4_ON

I assume you'll s/ON/SUPPORTED/ per comments in another thread.

Otherwise this looks fine to me.

Thanks,
Mark.

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

* Re: [PATCHv3 03/11] arm64: Introduce helpers for page table levels
  2015-10-15 13:48             ` Suzuki K. Poulose
@ 2015-10-15 14:15               ` Christoffer Dall
  -1 siblings, 0 replies; 110+ messages in thread
From: Christoffer Dall @ 2015-10-15 14:15 UTC (permalink / raw)
  To: Suzuki K. Poulose
  Cc: Mark Rutland, linux-arm-kernel, linux-kernel, catalin.marinas,
	will.deacon, steve.capper, marc.zyngier, ard.biesheuvel

On Thu, Oct 15, 2015 at 02:48:47PM +0100, Suzuki K. Poulose wrote:
> On 15/10/15 14:30, Christoffer Dall wrote:
> >On Thu, Oct 15, 2015 at 02:14:22PM +0100, Suzuki K. Poulose wrote:
> >>On 15/10/15 13:44, Mark Rutland wrote:
> >>>On Thu, Oct 15, 2015 at 01:37:35PM +0200, Christoffer Dall wrote:
> >>>>On Wed, Oct 14, 2015 at 12:20:26PM +0100, Suzuki K. Poulose wrote:
> 
> 
> >>  * The maximum number of levels supported by the architecture is 4. Hence at starting
> >>  * at level n, we hanve (4 - n) levels of translation. So, the total number of bits
> >
> >nit: s/hanve/have/
> 
> Fixed.
> 
> >
> >>  * mapped by an entry at level n is :
> >>  *
> >>  *  ((4 - n) - 1) * (PAGE_SHIFT - 3) + PAGE_SHIFT
> >>  *
> >>  * Rearranging it a bit we get :
> >>  *   (4 - n) * (PAGE_SHIFT - 3) + 3
> >>  */
> >>
> >>Or we could use the formula without rearranging.
> >>
> >Either way, even I get it now.
> >
> >Thanks for the explanation!!
> 
> :). I was involved too much in these calculations that, the formula looked
> obvious to me, when I wrote it. But yes, I did realise that it is indeed
> complicated, once I really started looking at explaining why I wrote it so.
> Thanks for being patient :) and complaining peacefully !
> 
> Btw, I have a revised (hopefully better) version here :
> 
> /*
>  * Size mapped by an entry at level n ( 0 <= n <= 3)
>  * We map (PAGE_SHIFT - 3) at all translation levels and PAGE_SHIFT bits
>  * in the final page. The maximum number of translation levels supported by
>  * the architecture is 4. Hence, starting at at level n, we have further
>  * ((4 - n) - 1) levels of translation excluding the offset within the page.
>  * So, the total number of bits mapped by an entry at level n is :
>  *
>  *  ((4 - n) - 1) * (PAGE_SHIFT - 3) + PAGE_SHIFT
>  *
>  * Rearranging it a bit we get :
>  *   (4 - n) * (PAGE_SHIFT - 3) + 3
>  */
> 

Looks good.

> 
> >
> >Assuming some version of this goes in:
> >
> >Acked-by: Christoffer Dall <christoffer.dall@linaro.org>
> >
> 
> Thanks. I lost two interview questions though ;)
> 
There are plenty of good sources for that in the KVM/ARM code.

-Christoffer

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

* [PATCHv3 03/11] arm64: Introduce helpers for page table levels
@ 2015-10-15 14:15               ` Christoffer Dall
  0 siblings, 0 replies; 110+ messages in thread
From: Christoffer Dall @ 2015-10-15 14:15 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Oct 15, 2015 at 02:48:47PM +0100, Suzuki K. Poulose wrote:
> On 15/10/15 14:30, Christoffer Dall wrote:
> >On Thu, Oct 15, 2015 at 02:14:22PM +0100, Suzuki K. Poulose wrote:
> >>On 15/10/15 13:44, Mark Rutland wrote:
> >>>On Thu, Oct 15, 2015 at 01:37:35PM +0200, Christoffer Dall wrote:
> >>>>On Wed, Oct 14, 2015 at 12:20:26PM +0100, Suzuki K. Poulose wrote:
> 
> 
> >>  * The maximum number of levels supported by the architecture is 4. Hence at starting
> >>  * at level n, we hanve (4 - n) levels of translation. So, the total number of bits
> >
> >nit: s/hanve/have/
> 
> Fixed.
> 
> >
> >>  * mapped by an entry at level n is :
> >>  *
> >>  *  ((4 - n) - 1) * (PAGE_SHIFT - 3) + PAGE_SHIFT
> >>  *
> >>  * Rearranging it a bit we get :
> >>  *   (4 - n) * (PAGE_SHIFT - 3) + 3
> >>  */
> >>
> >>Or we could use the formula without rearranging.
> >>
> >Either way, even I get it now.
> >
> >Thanks for the explanation!!
> 
> :). I was involved too much in these calculations that, the formula looked
> obvious to me, when I wrote it. But yes, I did realise that it is indeed
> complicated, once I really started looking at explaining why I wrote it so.
> Thanks for being patient :) and complaining peacefully !
> 
> Btw, I have a revised (hopefully better) version here :
> 
> /*
>  * Size mapped by an entry at level n ( 0 <= n <= 3)
>  * We map (PAGE_SHIFT - 3) at all translation levels and PAGE_SHIFT bits
>  * in the final page. The maximum number of translation levels supported by
>  * the architecture is 4. Hence, starting at at level n, we have further
>  * ((4 - n) - 1) levels of translation excluding the offset within the page.
>  * So, the total number of bits mapped by an entry at level n is :
>  *
>  *  ((4 - n) - 1) * (PAGE_SHIFT - 3) + PAGE_SHIFT
>  *
>  * Rearranging it a bit we get :
>  *   (4 - n) * (PAGE_SHIFT - 3) + 3
>  */
> 

Looks good.

> 
> >
> >Assuming some version of this goes in:
> >
> >Acked-by: Christoffer Dall <christoffer.dall@linaro.org>
> >
> 
> Thanks. I lost two interview questions though ;)
> 
There are plenty of good sources for that in the KVM/ARM code.

-Christoffer

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

* Re: [PATCHv3 08/11] arm64: Check for selected granule support
  2015-10-15 11:25         ` Suzuki K. Poulose
@ 2015-10-15 14:47           ` Jeremy Linton
  -1 siblings, 0 replies; 110+ messages in thread
From: Jeremy Linton @ 2015-10-15 14:47 UTC (permalink / raw)
  To: Suzuki K. Poulose, Mark Rutland
  Cc: linux-arm-kernel, steve.capper, ard.biesheuvel, marc.zyngier,
	catalin.marinas, will.deacon, linux-kernel, christoffer.dall

On 10/15/2015 06:25 AM, Suzuki K. Poulose wrote:
> +	/*
> +	 * Check to see if the CPU supports the requested pagesize
> +	 */
> +	asm volatile("mrs %0, ID_AA64MMFR0_EL1" : "=r" (aa64mmfr0_el1));
> +	aa64mmfr0_el1 >>= ID_AA64MMFR0_TGRAN_SHIFT;
> +	if ((aa64mmfr0_el1 & 0xf) != ID_AA64MMFR0_TGRAN_SUPPORTED) {
> +		pr_efi_err(sys_table_arg, PAGE_SIZE_STR" granule not supported by the CPU\n");
> +		return EFI_UNSUPPORTED;
> +	}


This is definitely an improvement over my original hack job.

I would like to add, that I actually think this should be in a new 
function "check_kernel_compatibility" (or whatever) that is called 
before handle_kernel_image.

That is because I don't really think it belongs in handle_kernel_image 
which is focused on relocation. Plus, if you add another function, you 
can avoid the "Failed to relocate kernel" error that comes out following 
the granule not supported message. Further, checks like this in the 
future will have a place to live.

Of course you will then need a matching stubbed out function for the 
normal arm kernel as well.

Thanks,



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

* [PATCHv3 08/11] arm64: Check for selected granule support
@ 2015-10-15 14:47           ` Jeremy Linton
  0 siblings, 0 replies; 110+ messages in thread
From: Jeremy Linton @ 2015-10-15 14:47 UTC (permalink / raw)
  To: linux-arm-kernel

On 10/15/2015 06:25 AM, Suzuki K. Poulose wrote:
> +	/*
> +	 * Check to see if the CPU supports the requested pagesize
> +	 */
> +	asm volatile("mrs %0, ID_AA64MMFR0_EL1" : "=r" (aa64mmfr0_el1));
> +	aa64mmfr0_el1 >>= ID_AA64MMFR0_TGRAN_SHIFT;
> +	if ((aa64mmfr0_el1 & 0xf) != ID_AA64MMFR0_TGRAN_SUPPORTED) {
> +		pr_efi_err(sys_table_arg, PAGE_SIZE_STR" granule not supported by the CPU\n");
> +		return EFI_UNSUPPORTED;
> +	}


This is definitely an improvement over my original hack job.

I would like to add, that I actually think this should be in a new 
function "check_kernel_compatibility" (or whatever) that is called 
before handle_kernel_image.

That is because I don't really think it belongs in handle_kernel_image 
which is focused on relocation. Plus, if you add another function, you 
can avoid the "Failed to relocate kernel" error that comes out following 
the granule not supported message. Further, checks like this in the 
future will have a place to live.

Of course you will then need a matching stubbed out function for the 
normal arm kernel as well.

Thanks,

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

* Re: [PATCHv3 10/11] arm64: Add 16K page size support
  2015-10-15 14:06     ` Mark Rutland
@ 2015-10-15 14:48       ` Suzuki K. Poulose
  -1 siblings, 0 replies; 110+ messages in thread
From: Suzuki K. Poulose @ 2015-10-15 14:48 UTC (permalink / raw)
  To: Mark Rutland
  Cc: linux-arm-kernel, linux-kernel, catalin.marinas, will.deacon,
	steve.capper, marc.zyngier, ard.biesheuvel, christoffer.dall,
	Jeremy Linton

On 15/10/15 15:06, Mark Rutland wrote:
> Hi,
>

I have fixed all the nits locally. Thanks for pointing them out.

>>   config FORCE_MAX_ZONEORDER
>>   	int
>>   	default "14" if (ARM64_64K_PAGES && TRANSPARENT_HUGEPAGE)
>> +	default "12" if (ARM64_16K_PAGES && TRANSPARENT_HUGEPAGE)
>>   	default "11"
>
> I'm a little lost here. How are these numbers derived?
>

I struggled to find the right value for 16K. Thanks to Steve Capper
for the following explanation. I will add it as a comment.

All allocations from the buddy allocator have to have compound order
strictly less than MAX_ORDER. i.e, the maximum allocation size is
(MAX_ORDER - 1) PAGES. To align with the transparent huge page size,
we get :

  (MAX_ORDER - 1) + PAGE_SHIFT = PMD_SHIFT

Which gives us:

MAX_ORDER = PAGE_SHIFT - 3 + PAGE_SHIFT - PAGE_SHIFT + 1
           = PAGE_SHIFT - 2

That raises an interesting question about the selection of the value
for 4K. Shouldn't that be 10 instead of 11 ?

Steve ?

>> -#ifdef CONFIG_ARM64_64K_PAGES
>> +#if	defined(CONFIG_ARM64_64K_PAGES)
>>   #define NR_FIX_BTMAPS		4
>> +#elif	defined (CONFIG_ARM64_16K_PAGES)
>> +#define NR_FIX_BTMAPS		16
>>   #else
>>   #define NR_FIX_BTMAPS		64
>>   #endif
>
> We could include <linux/sizes.h> and simplify this to:
>
> #define NR_FIX_BTMAPS (SZ_256K / PAGE_SIZE)
>
> Which works for me locally.

Nice cleanup. I will pick that as a separate patch in the series.

>
>> diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h
>> index 5eac6a2..90c7ff2 100644
>> --- a/arch/arm64/include/asm/thread_info.h
>> +++ b/arch/arm64/include/asm/thread_info.h
>> @@ -25,6 +25,8 @@
>>
>>   #ifdef CONFIG_ARM64_4K_PAGES
>>   #define THREAD_SIZE_ORDER	2
>> +#elif defined(CONFIG_ARM64_16K_PAGES)
>> +#define THREAD_SIZE_ORDER	0
>>   #endif
>>   #define THREAD_SIZE		16384
>
> The above looks correct.
>
> As an open/general question, why do both THREAD_SIZE_ORDER and
> THREAD_SIZE exist? One really should be defined in terms of the other.

I think its mainly for choosing the mechanism for stack allocation. If it
is a multiple of a page, you allocate a page. If not, uses a kmem_cache.


>>   #define id_aa64mmfr0_tgran_shift	ID_AA64MMFR0_TGRAN4_SHIFT
>>   #define id_aa64mmfr0_tgran_on		ID_AA64MMFR0_TGRAN4_ON
>
> I assume you'll s/ON/SUPPORTED/ per comments in another thread.
>

Yes

Thanks
Suzuki


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

* [PATCHv3 10/11] arm64: Add 16K page size support
@ 2015-10-15 14:48       ` Suzuki K. Poulose
  0 siblings, 0 replies; 110+ messages in thread
From: Suzuki K. Poulose @ 2015-10-15 14:48 UTC (permalink / raw)
  To: linux-arm-kernel

On 15/10/15 15:06, Mark Rutland wrote:
> Hi,
>

I have fixed all the nits locally. Thanks for pointing them out.

>>   config FORCE_MAX_ZONEORDER
>>   	int
>>   	default "14" if (ARM64_64K_PAGES && TRANSPARENT_HUGEPAGE)
>> +	default "12" if (ARM64_16K_PAGES && TRANSPARENT_HUGEPAGE)
>>   	default "11"
>
> I'm a little lost here. How are these numbers derived?
>

I struggled to find the right value for 16K. Thanks to Steve Capper
for the following explanation. I will add it as a comment.

All allocations from the buddy allocator have to have compound order
strictly less than MAX_ORDER. i.e, the maximum allocation size is
(MAX_ORDER - 1) PAGES. To align with the transparent huge page size,
we get :

  (MAX_ORDER - 1) + PAGE_SHIFT = PMD_SHIFT

Which gives us:

MAX_ORDER = PAGE_SHIFT - 3 + PAGE_SHIFT - PAGE_SHIFT + 1
           = PAGE_SHIFT - 2

That raises an interesting question about the selection of the value
for 4K. Shouldn't that be 10 instead of 11 ?

Steve ?

>> -#ifdef CONFIG_ARM64_64K_PAGES
>> +#if	defined(CONFIG_ARM64_64K_PAGES)
>>   #define NR_FIX_BTMAPS		4
>> +#elif	defined (CONFIG_ARM64_16K_PAGES)
>> +#define NR_FIX_BTMAPS		16
>>   #else
>>   #define NR_FIX_BTMAPS		64
>>   #endif
>
> We could include <linux/sizes.h> and simplify this to:
>
> #define NR_FIX_BTMAPS (SZ_256K / PAGE_SIZE)
>
> Which works for me locally.

Nice cleanup. I will pick that as a separate patch in the series.

>
>> diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h
>> index 5eac6a2..90c7ff2 100644
>> --- a/arch/arm64/include/asm/thread_info.h
>> +++ b/arch/arm64/include/asm/thread_info.h
>> @@ -25,6 +25,8 @@
>>
>>   #ifdef CONFIG_ARM64_4K_PAGES
>>   #define THREAD_SIZE_ORDER	2
>> +#elif defined(CONFIG_ARM64_16K_PAGES)
>> +#define THREAD_SIZE_ORDER	0
>>   #endif
>>   #define THREAD_SIZE		16384
>
> The above looks correct.
>
> As an open/general question, why do both THREAD_SIZE_ORDER and
> THREAD_SIZE exist? One really should be defined in terms of the other.

I think its mainly for choosing the mechanism for stack allocation. If it
is a multiple of a page, you allocate a page. If not, uses a kmem_cache.


>>   #define id_aa64mmfr0_tgran_shift	ID_AA64MMFR0_TGRAN4_SHIFT
>>   #define id_aa64mmfr0_tgran_on		ID_AA64MMFR0_TGRAN4_ON
>
> I assume you'll s/ON/SUPPORTED/ per comments in another thread.
>

Yes

Thanks
Suzuki

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

* Re: [PATCHv3 08/11] arm64: Check for selected granule support
  2015-10-15 14:47           ` Jeremy Linton
@ 2015-10-15 15:02             ` Suzuki K. Poulose
  -1 siblings, 0 replies; 110+ messages in thread
From: Suzuki K. Poulose @ 2015-10-15 15:02 UTC (permalink / raw)
  To: Jeremy Linton, Mark Rutland
  Cc: linux-arm-kernel, steve.capper, ard.biesheuvel, marc.zyngier,
	catalin.marinas, will.deacon, linux-kernel, christoffer.dall

On 15/10/15 15:47, Jeremy Linton wrote:
> On 10/15/2015 06:25 AM, Suzuki K. Poulose wrote:
>> +    /*
>> +     * Check to see if the CPU supports the requested pagesize
>> +     */
>> +    asm volatile("mrs %0, ID_AA64MMFR0_EL1" : "=r" (aa64mmfr0_el1));
>> +    aa64mmfr0_el1 >>= ID_AA64MMFR0_TGRAN_SHIFT;
>> +    if ((aa64mmfr0_el1 & 0xf) != ID_AA64MMFR0_TGRAN_SUPPORTED) {
>> +        pr_efi_err(sys_table_arg, PAGE_SIZE_STR" granule not supported by the CPU\n");
>> +        return EFI_UNSUPPORTED;
>> +    }
>
>
> This is definitely an improvement over my original hack job.
>
> I would like to add, that I actually think this should be in a new function
> "check_kernel_compatibility" (or whatever) that is called before handle_kernel_image.
>
> That is because I don't really think it belongs in handle_kernel_image which is
>  focused on relocation.  Plus, if you add another function, you can avoid the
> "Failed to relocate kernel" error that comes out following the granule not supported message.
> Further, checks like this in the future will have a place to live.
>
> Of course you will then need a matching stubbed out function for the normal arm kernel as well.


OK, I will drop it from this series then and can be worked as a separate patch.

Thanks
Suzuki


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

* [PATCHv3 08/11] arm64: Check for selected granule support
@ 2015-10-15 15:02             ` Suzuki K. Poulose
  0 siblings, 0 replies; 110+ messages in thread
From: Suzuki K. Poulose @ 2015-10-15 15:02 UTC (permalink / raw)
  To: linux-arm-kernel

On 15/10/15 15:47, Jeremy Linton wrote:
> On 10/15/2015 06:25 AM, Suzuki K. Poulose wrote:
>> +    /*
>> +     * Check to see if the CPU supports the requested pagesize
>> +     */
>> +    asm volatile("mrs %0, ID_AA64MMFR0_EL1" : "=r" (aa64mmfr0_el1));
>> +    aa64mmfr0_el1 >>= ID_AA64MMFR0_TGRAN_SHIFT;
>> +    if ((aa64mmfr0_el1 & 0xf) != ID_AA64MMFR0_TGRAN_SUPPORTED) {
>> +        pr_efi_err(sys_table_arg, PAGE_SIZE_STR" granule not supported by the CPU\n");
>> +        return EFI_UNSUPPORTED;
>> +    }
>
>
> This is definitely an improvement over my original hack job.
>
> I would like to add, that I actually think this should be in a new function
> "check_kernel_compatibility" (or whatever) that is called before handle_kernel_image.
>
> That is because I don't really think it belongs in handle_kernel_image which is
>  focused on relocation.  Plus, if you add another function, you can avoid the
> "Failed to relocate kernel" error that comes out following the granule not supported message.
> Further, checks like this in the future will have a place to live.
>
> Of course you will then need a matching stubbed out function for the normal arm kernel as well.


OK, I will drop it from this series then and can be worked as a separate patch.

Thanks
Suzuki

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

* Re: [PATCHv3 08/11] arm64: Check for selected granule support
  2015-10-15 14:47           ` Jeremy Linton
@ 2015-10-15 15:11             ` Mark Rutland
  -1 siblings, 0 replies; 110+ messages in thread
From: Mark Rutland @ 2015-10-15 15:11 UTC (permalink / raw)
  To: Jeremy Linton
  Cc: Suzuki K. Poulose, linux-arm-kernel, steve.capper,
	ard.biesheuvel, marc.zyngier, catalin.marinas, will.deacon,
	linux-kernel, christoffer.dall

On Thu, Oct 15, 2015 at 09:47:53AM -0500, Jeremy Linton wrote:
> On 10/15/2015 06:25 AM, Suzuki K. Poulose wrote:
> >+	/*
> >+	 * Check to see if the CPU supports the requested pagesize
> >+	 */
> >+	asm volatile("mrs %0, ID_AA64MMFR0_EL1" : "=r" (aa64mmfr0_el1));
> >+	aa64mmfr0_el1 >>= ID_AA64MMFR0_TGRAN_SHIFT;
> >+	if ((aa64mmfr0_el1 & 0xf) != ID_AA64MMFR0_TGRAN_SUPPORTED) {
> >+		pr_efi_err(sys_table_arg, PAGE_SIZE_STR" granule not supported by the CPU\n");
> >+		return EFI_UNSUPPORTED;
> >+	}
> 
> 
> This is definitely an improvement over my original hack job.
> 
> I would like to add, that I actually think this should be in a new
> function "check_kernel_compatibility" (or whatever) that is called
> before handle_kernel_image.

To bikeshed, perhaps efi_arch_check_system?

> That is because I don't really think it belongs in
> handle_kernel_image which is focused on relocation. Plus, if you add
> another function, you can avoid the "Failed to relocate kernel"
> error that comes out following the granule not supported message.
> Further, checks like this in the future will have a place to live.

I agree.

There are some other diagnostic utilities I'd like to add to the stub
(e.g. dumping the memory map and ID registers) that would help with
diagnosing boot issues. I started on those at Connect, but realised I
needed to first implement half of printf for those to be useful.

> Of course you will then need a matching stubbed out function for the
> normal arm kernel as well.

I'm sure there are similar things we'll want to check for 32-bit (e.g.
LPAE support), but a stub should be fine for now.

Thanks,
Mark.

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

* [PATCHv3 08/11] arm64: Check for selected granule support
@ 2015-10-15 15:11             ` Mark Rutland
  0 siblings, 0 replies; 110+ messages in thread
From: Mark Rutland @ 2015-10-15 15:11 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Oct 15, 2015 at 09:47:53AM -0500, Jeremy Linton wrote:
> On 10/15/2015 06:25 AM, Suzuki K. Poulose wrote:
> >+	/*
> >+	 * Check to see if the CPU supports the requested pagesize
> >+	 */
> >+	asm volatile("mrs %0, ID_AA64MMFR0_EL1" : "=r" (aa64mmfr0_el1));
> >+	aa64mmfr0_el1 >>= ID_AA64MMFR0_TGRAN_SHIFT;
> >+	if ((aa64mmfr0_el1 & 0xf) != ID_AA64MMFR0_TGRAN_SUPPORTED) {
> >+		pr_efi_err(sys_table_arg, PAGE_SIZE_STR" granule not supported by the CPU\n");
> >+		return EFI_UNSUPPORTED;
> >+	}
> 
> 
> This is definitely an improvement over my original hack job.
> 
> I would like to add, that I actually think this should be in a new
> function "check_kernel_compatibility" (or whatever) that is called
> before handle_kernel_image.

To bikeshed, perhaps efi_arch_check_system?

> That is because I don't really think it belongs in
> handle_kernel_image which is focused on relocation. Plus, if you add
> another function, you can avoid the "Failed to relocate kernel"
> error that comes out following the granule not supported message.
> Further, checks like this in the future will have a place to live.

I agree.

There are some other diagnostic utilities I'd like to add to the stub
(e.g. dumping the memory map and ID registers) that would help with
diagnosing boot issues. I started on those at Connect, but realised I
needed to first implement half of printf for those to be useful.

> Of course you will then need a matching stubbed out function for the
> normal arm kernel as well.

I'm sure there are similar things we'll want to check for 32-bit (e.g.
LPAE support), but a stub should be fine for now.

Thanks,
Mark.

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

* Re: [PATCHv3 10/11] arm64: Add 16K page size support
  2015-10-15 14:48       ` Suzuki K. Poulose
@ 2015-10-15 15:36         ` Steve Capper
  -1 siblings, 0 replies; 110+ messages in thread
From: Steve Capper @ 2015-10-15 15:36 UTC (permalink / raw)
  To: Suzuki K. Poulose
  Cc: Mark Rutland, linux-arm-kernel, linux-kernel, Catalin Marinas,
	Will Deacon, Marc Zyngier, Ard Biesheuvel, Christoffer Dall,
	Jeremy Linton

On 15 October 2015 at 15:48, Suzuki K. Poulose <Suzuki.Poulose@arm.com> wrote:
> On 15/10/15 15:06, Mark Rutland wrote:
>>
>> Hi,
>>
>
> I have fixed all the nits locally. Thanks for pointing them out.
>
>>>   config FORCE_MAX_ZONEORDER
>>>         int
>>>         default "14" if (ARM64_64K_PAGES && TRANSPARENT_HUGEPAGE)
>>> +       default "12" if (ARM64_16K_PAGES && TRANSPARENT_HUGEPAGE)
>>>         default "11"
>>
>>
>> I'm a little lost here. How are these numbers derived?
>>
>
> I struggled to find the right value for 16K. Thanks to Steve Capper
> for the following explanation. I will add it as a comment.
>
> All allocations from the buddy allocator have to have compound order
> strictly less than MAX_ORDER. i.e, the maximum allocation size is
> (MAX_ORDER - 1) PAGES. To align with the transparent huge page size,
> we get :
>
>  (MAX_ORDER - 1) + PAGE_SHIFT = PMD_SHIFT
>
> Which gives us:
>
> MAX_ORDER = PAGE_SHIFT - 3 + PAGE_SHIFT - PAGE_SHIFT + 1
>           = PAGE_SHIFT - 2
>
> That raises an interesting question about the selection of the value
> for 4K. Shouldn't that be 10 instead of 11 ?
>
> Steve ?

Hi,
My understanding is that 11 is a "good minimum" value for the page
allocator with 4KB pages.
(There are references to it being 10 in 2.4 kernels but raised to 11
on 2.6 kernels?)

We need to raise the minimum when we have a 16KB or 64KB PAGE_SIZE to
be able allocate a 32MB or 512MB Transparent HugePages.

Cheers,
--
Steve

>
>>> -#ifdef CONFIG_ARM64_64K_PAGES
>>> +#if    defined(CONFIG_ARM64_64K_PAGES)
>>>   #define NR_FIX_BTMAPS         4
>>> +#elif  defined (CONFIG_ARM64_16K_PAGES)
>>> +#define NR_FIX_BTMAPS          16
>>>   #else
>>>   #define NR_FIX_BTMAPS         64
>>>   #endif
>>
>>
>> We could include <linux/sizes.h> and simplify this to:
>>
>> #define NR_FIX_BTMAPS (SZ_256K / PAGE_SIZE)
>>
>> Which works for me locally.
>
>
> Nice cleanup. I will pick that as a separate patch in the series.
>
>>
>>> diff --git a/arch/arm64/include/asm/thread_info.h
>>> b/arch/arm64/include/asm/thread_info.h
>>> index 5eac6a2..90c7ff2 100644
>>> --- a/arch/arm64/include/asm/thread_info.h
>>> +++ b/arch/arm64/include/asm/thread_info.h
>>> @@ -25,6 +25,8 @@
>>>
>>>   #ifdef CONFIG_ARM64_4K_PAGES
>>>   #define THREAD_SIZE_ORDER     2
>>> +#elif defined(CONFIG_ARM64_16K_PAGES)
>>> +#define THREAD_SIZE_ORDER      0
>>>   #endif
>>>   #define THREAD_SIZE           16384
>>
>>
>> The above looks correct.
>>
>> As an open/general question, why do both THREAD_SIZE_ORDER and
>> THREAD_SIZE exist? One really should be defined in terms of the other.
>
>
> I think its mainly for choosing the mechanism for stack allocation. If it
> is a multiple of a page, you allocate a page. If not, uses a kmem_cache.
>
>
>>>   #define id_aa64mmfr0_tgran_shift      ID_AA64MMFR0_TGRAN4_SHIFT
>>>   #define id_aa64mmfr0_tgran_on         ID_AA64MMFR0_TGRAN4_ON
>>
>>
>> I assume you'll s/ON/SUPPORTED/ per comments in another thread.
>>
>
> Yes
>
> Thanks
> Suzuki
>

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

* [PATCHv3 10/11] arm64: Add 16K page size support
@ 2015-10-15 15:36         ` Steve Capper
  0 siblings, 0 replies; 110+ messages in thread
From: Steve Capper @ 2015-10-15 15:36 UTC (permalink / raw)
  To: linux-arm-kernel

On 15 October 2015 at 15:48, Suzuki K. Poulose <Suzuki.Poulose@arm.com> wrote:
> On 15/10/15 15:06, Mark Rutland wrote:
>>
>> Hi,
>>
>
> I have fixed all the nits locally. Thanks for pointing them out.
>
>>>   config FORCE_MAX_ZONEORDER
>>>         int
>>>         default "14" if (ARM64_64K_PAGES && TRANSPARENT_HUGEPAGE)
>>> +       default "12" if (ARM64_16K_PAGES && TRANSPARENT_HUGEPAGE)
>>>         default "11"
>>
>>
>> I'm a little lost here. How are these numbers derived?
>>
>
> I struggled to find the right value for 16K. Thanks to Steve Capper
> for the following explanation. I will add it as a comment.
>
> All allocations from the buddy allocator have to have compound order
> strictly less than MAX_ORDER. i.e, the maximum allocation size is
> (MAX_ORDER - 1) PAGES. To align with the transparent huge page size,
> we get :
>
>  (MAX_ORDER - 1) + PAGE_SHIFT = PMD_SHIFT
>
> Which gives us:
>
> MAX_ORDER = PAGE_SHIFT - 3 + PAGE_SHIFT - PAGE_SHIFT + 1
>           = PAGE_SHIFT - 2
>
> That raises an interesting question about the selection of the value
> for 4K. Shouldn't that be 10 instead of 11 ?
>
> Steve ?

Hi,
My understanding is that 11 is a "good minimum" value for the page
allocator with 4KB pages.
(There are references to it being 10 in 2.4 kernels but raised to 11
on 2.6 kernels?)

We need to raise the minimum when we have a 16KB or 64KB PAGE_SIZE to
be able allocate a 32MB or 512MB Transparent HugePages.

Cheers,
--
Steve

>
>>> -#ifdef CONFIG_ARM64_64K_PAGES
>>> +#if    defined(CONFIG_ARM64_64K_PAGES)
>>>   #define NR_FIX_BTMAPS         4
>>> +#elif  defined (CONFIG_ARM64_16K_PAGES)
>>> +#define NR_FIX_BTMAPS          16
>>>   #else
>>>   #define NR_FIX_BTMAPS         64
>>>   #endif
>>
>>
>> We could include <linux/sizes.h> and simplify this to:
>>
>> #define NR_FIX_BTMAPS (SZ_256K / PAGE_SIZE)
>>
>> Which works for me locally.
>
>
> Nice cleanup. I will pick that as a separate patch in the series.
>
>>
>>> diff --git a/arch/arm64/include/asm/thread_info.h
>>> b/arch/arm64/include/asm/thread_info.h
>>> index 5eac6a2..90c7ff2 100644
>>> --- a/arch/arm64/include/asm/thread_info.h
>>> +++ b/arch/arm64/include/asm/thread_info.h
>>> @@ -25,6 +25,8 @@
>>>
>>>   #ifdef CONFIG_ARM64_4K_PAGES
>>>   #define THREAD_SIZE_ORDER     2
>>> +#elif defined(CONFIG_ARM64_16K_PAGES)
>>> +#define THREAD_SIZE_ORDER      0
>>>   #endif
>>>   #define THREAD_SIZE           16384
>>
>>
>> The above looks correct.
>>
>> As an open/general question, why do both THREAD_SIZE_ORDER and
>> THREAD_SIZE exist? One really should be defined in terms of the other.
>
>
> I think its mainly for choosing the mechanism for stack allocation. If it
> is a multiple of a page, you allocate a page. If not, uses a kmem_cache.
>
>
>>>   #define id_aa64mmfr0_tgran_shift      ID_AA64MMFR0_TGRAN4_SHIFT
>>>   #define id_aa64mmfr0_tgran_on         ID_AA64MMFR0_TGRAN4_ON
>>
>>
>> I assume you'll s/ON/SUPPORTED/ per comments in another thread.
>>
>
> Yes
>
> Thanks
> Suzuki
>

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

* Re: [PATCHv3 10/11] arm64: Add 16K page size support
  2015-10-15 15:36         ` Steve Capper
@ 2015-10-15 15:48           ` Suzuki K. Poulose
  -1 siblings, 0 replies; 110+ messages in thread
From: Suzuki K. Poulose @ 2015-10-15 15:48 UTC (permalink / raw)
  To: Steve Capper
  Cc: Mark Rutland, linux-arm-kernel, linux-kernel, Catalin Marinas,
	Will Deacon, Marc Zyngier, Ard Biesheuvel, Christoffer Dall,
	Jeremy Linton

On 15/10/15 16:36, Steve Capper wrote:
> On 15 October 2015 at 15:48, Suzuki K. Poulose <Suzuki.Poulose@arm.com> wrote:
>> On 15/10/15 15:06, Mark Rutland wrote:
>>>
>>> Hi,
>>>
>>
>> I have fixed all the nits locally. Thanks for pointing them out.
>>
>>>>    config FORCE_MAX_ZONEORDER
>>>>          int
>>>>          default "14" if (ARM64_64K_PAGES && TRANSPARENT_HUGEPAGE)
>>>> +       default "12" if (ARM64_16K_PAGES && TRANSPARENT_HUGEPAGE)
>>>>          default "11"
>>>
>>>
>>> I'm a little lost here. How are these numbers derived?
>>>
>>
>> I struggled to find the right value for 16K. Thanks to Steve Capper
>> for the following explanation. I will add it as a comment.
>>
>> All allocations from the buddy allocator have to have compound order
>> strictly less than MAX_ORDER. i.e, the maximum allocation size is
>> (MAX_ORDER - 1) PAGES. To align with the transparent huge page size,
>> we get :
>>
>>   (MAX_ORDER - 1) + PAGE_SHIFT = PMD_SHIFT
>>
>> Which gives us:
>>
>> MAX_ORDER = PAGE_SHIFT - 3 + PAGE_SHIFT - PAGE_SHIFT + 1
>>            = PAGE_SHIFT - 2
>>
>> That raises an interesting question about the selection of the value
>> for 4K. Shouldn't that be 10 instead of 11 ?
>>
>> Steve ?
>
> Hi,
> My understanding is that 11 is a "good minimum" value for the page
> allocator with 4KB pages.
> (There are references to it being 10 in 2.4 kernels but raised to 11
> on 2.6 kernels?)
>
> We need to raise the minimum when we have a 16KB or 64KB PAGE_SIZE to
> be able allocate a 32MB or 512MB Transparent HugePages.
>

Thanks Steve, for the clarification. I will add the following comment
to the Kconfig

#
# All allocations from the buddy allocator have to have compound order
# strictly less than MAX_ORDER. i.e, the maximum allocation size is
# (MAX_ORDER - 1) PAGES. To align with the transparent huge page size,
# we get :
#
#  (MAX_ORDER - 1) + PAGE_SHIFT = PMD_SHIFT
#
# Which gives us:
#
# MAX_ORDER = PAGE_SHIFT - 3 + PAGE_SHIFT - PAGE_SHIFT + 1
#           = PAGE_SHIFT - 2
#
# However for 4K, we choose a higher default value 11 as opposed to 10, (giving us size 4M)
# matching the default value used by the generic code.
#


Thanks
Suzuki


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

* [PATCHv3 10/11] arm64: Add 16K page size support
@ 2015-10-15 15:48           ` Suzuki K. Poulose
  0 siblings, 0 replies; 110+ messages in thread
From: Suzuki K. Poulose @ 2015-10-15 15:48 UTC (permalink / raw)
  To: linux-arm-kernel

On 15/10/15 16:36, Steve Capper wrote:
> On 15 October 2015 at 15:48, Suzuki K. Poulose <Suzuki.Poulose@arm.com> wrote:
>> On 15/10/15 15:06, Mark Rutland wrote:
>>>
>>> Hi,
>>>
>>
>> I have fixed all the nits locally. Thanks for pointing them out.
>>
>>>>    config FORCE_MAX_ZONEORDER
>>>>          int
>>>>          default "14" if (ARM64_64K_PAGES && TRANSPARENT_HUGEPAGE)
>>>> +       default "12" if (ARM64_16K_PAGES && TRANSPARENT_HUGEPAGE)
>>>>          default "11"
>>>
>>>
>>> I'm a little lost here. How are these numbers derived?
>>>
>>
>> I struggled to find the right value for 16K. Thanks to Steve Capper
>> for the following explanation. I will add it as a comment.
>>
>> All allocations from the buddy allocator have to have compound order
>> strictly less than MAX_ORDER. i.e, the maximum allocation size is
>> (MAX_ORDER - 1) PAGES. To align with the transparent huge page size,
>> we get :
>>
>>   (MAX_ORDER - 1) + PAGE_SHIFT = PMD_SHIFT
>>
>> Which gives us:
>>
>> MAX_ORDER = PAGE_SHIFT - 3 + PAGE_SHIFT - PAGE_SHIFT + 1
>>            = PAGE_SHIFT - 2
>>
>> That raises an interesting question about the selection of the value
>> for 4K. Shouldn't that be 10 instead of 11 ?
>>
>> Steve ?
>
> Hi,
> My understanding is that 11 is a "good minimum" value for the page
> allocator with 4KB pages.
> (There are references to it being 10 in 2.4 kernels but raised to 11
> on 2.6 kernels?)
>
> We need to raise the minimum when we have a 16KB or 64KB PAGE_SIZE to
> be able allocate a 32MB or 512MB Transparent HugePages.
>

Thanks Steve, for the clarification. I will add the following comment
to the Kconfig

#
# All allocations from the buddy allocator have to have compound order
# strictly less than MAX_ORDER. i.e, the maximum allocation size is
# (MAX_ORDER - 1) PAGES. To align with the transparent huge page size,
# we get :
#
#  (MAX_ORDER - 1) + PAGE_SHIFT = PMD_SHIFT
#
# Which gives us:
#
# MAX_ORDER = PAGE_SHIFT - 3 + PAGE_SHIFT - PAGE_SHIFT + 1
#           = PAGE_SHIFT - 2
#
# However for 4K, we choose a higher default value 11 as opposed to 10, (giving us size 4M)
# matching the default value used by the generic code.
#


Thanks
Suzuki

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

* Re: [PATCHv3 08/11] arm64: Check for selected granule support
  2015-10-15 12:58             ` Suzuki K. Poulose
@ 2015-10-16  8:03               ` Ard Biesheuvel
  -1 siblings, 0 replies; 110+ messages in thread
From: Ard Biesheuvel @ 2015-10-16  8:03 UTC (permalink / raw)
  To: Suzuki K. Poulose
  Cc: Mark Rutland, Jeremy Linton, linux-arm-kernel, Steve Capper,
	Marc Zyngier, Catalin Marinas, Will Deacon, linux-kernel,
	Christoffer Dall

On 15 October 2015 at 14:58, Suzuki K. Poulose <Suzuki.Poulose@arm.com> wrote:
> On 15/10/15 13:37, Mark Rutland wrote:
>>
>> On Thu, Oct 15, 2015 at 12:25:33PM +0100, Suzuki K. Poulose wrote:
>>>
>>> On Thu, Oct 15, 2015 at 11:45:15AM +0100, Mark Rutland wrote:
>>>>
>>>> On Wed, Oct 14, 2015 at 04:13:47PM -0500, Jeremy Linton wrote:
>>>>>
>>>>> On 10/14/2015 06:20 AM, Suzuki K. Poulose wrote:
>
>
>
>>>
>>> ----8>----
>>>
>>> Author: Suzuki K. Poulose <suzuki.poulose@arm.com>
>>> Date:   Wed Oct 14 11:25:16 2015 +0100
>>>
>>>      arm64: Check for selected granule support
>>>
>>>      Ensure that the selected page size is supported by the CPU(s). If it
>>> isn't
>>>      park the CPU. A check is added to the EFI stub to detect if the boot
>>> CPU
>>>      supports the page size, failing which, we fail the boot gracefully,
>>> with
>>>      an error message.
>>>
>>>      Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com>
>>>      [ Added a check to EFI stub ]
>>>      Signed-off-by: Jeremy Linton <jeremy.linton@arm.com>
>>
>>
>> Your sign-off should be last, given you are taking resposibility for
>> Jeremy's patch.
>
>
> OK, I was a bit confused about how it should look like. I kept it on top
> so that I could add [ ] for Jeremy's contribution.
>
>>
>> However, I would prefer that the EFI stub addition were a separate/later
>> patch.
>
>
> OK, that makes sense.
>
>>
>>> diff --git a/arch/arm64/include/asm/sysreg.h
>>> b/arch/arm64/include/asm/sysreg.h
>>> index a7f3d4b..72d814c 100644
>>> --- a/arch/arm64/include/asm/sysreg.h
>>> +++ b/arch/arm64/include/asm/sysreg.h
>
>
>>> +#define ID_AA64MMFR0_TGRAN4_NI         0xf
>>> +#define ID_AA64MMFR0_TGRAN4_ON         0x0
>>> +#define ID_AA64MMFR0_TGRAN64_NI                0xf
>>> +#define ID_AA64MMFR0_TGRAN64_ON                0x0
>>> +#define ID_AA64MMFR0_TGRAN16_NI                0x0
>>> +#define ID_AA64MMFR0_TGRAN16_ON                0x1
>>
>>
>> I still don't like "ON" here -- I thought these would also be changed
>> s/ON/SUPPORTED/.
>
>
> I know and I expected that. I have "_ON" in my 'CPU feature' series, which
> will/can be reused here. Hence kept it _ON. I can change it everywhere to
> _SUPPORTED, since I may need to spin another version for that.
>
>
>>>   #include <linux/efi.h>
>>>   #include <asm/efi.h>
>>> +#include <asm/sysreg.h>
>>>   #include <asm/sections.h>
>>
>>
>> Nit: include order.
>
>
> OK
>
>>
>>>
>>> +#if defined(CONFIG_ARM64_4K_PAGES)
>>> +#define PAGE_SIZE_STR  "4K"
>>> +#elif defined(CONFIG_ARM64_64K_PAGES)
>>> +#define PAGE_SIZE_STR  "64K"
>>> +#endif
>>> +

4k can be dropped (since UEFI support implies support for 4k pages)
16k is missing here

>>>   efi_status_t __init handle_kernel_image(efi_system_table_t
>>> *sys_table_arg,
>>>                                         unsigned long *image_addr,
>>>                                         unsigned long *image_size,
>>> @@ -25,6 +32,17 @@ efi_status_t __init
>>> handle_kernel_image(efi_system_table_t *sys_table_arg,
>>>         unsigned long kernel_size, kernel_memsize = 0;
>>>         unsigned long nr_pages;
>>>         void *old_image_addr = (void *)*image_addr;
>>> +       u64 aa64mmfr0_el1;
>>> +
>>> +       /*
>>> +        * Check to see if the CPU supports the requested pagesize
>>> +        */

... so here you would need a #ifndef CONFIG_ARM_4K_PAGES as well.

>>> +       asm volatile("mrs %0, ID_AA64MMFR0_EL1" : "=r" (aa64mmfr0_el1));
>>
>>
>> Can we not use read_cpuid() or similar here?
>
>
> Yes, I will try that out. I didn't want to include additional header-files
> in efi-stub.c.
>
>
>>> +       aa64mmfr0_el1 >>= ID_AA64MMFR0_TGRAN_SHIFT;
>>
>>
>> ... and can we not do the shift and mask in one go?
>>
>
>>> +       if ((aa64mmfr0_el1 & 0xf) != ID_AA64MMFR0_TGRAN_SUPPORTED) {
>>> +               pr_efi_err(sys_table_arg, PAGE_SIZE_STR" granule not
>>> supported by the CPU\n");
>>
>>
>> Nit: space before the first quote, please.
>
>
> Will do
>
> Thanks
> Suzuki
>

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

* [PATCHv3 08/11] arm64: Check for selected granule support
@ 2015-10-16  8:03               ` Ard Biesheuvel
  0 siblings, 0 replies; 110+ messages in thread
From: Ard Biesheuvel @ 2015-10-16  8:03 UTC (permalink / raw)
  To: linux-arm-kernel

On 15 October 2015 at 14:58, Suzuki K. Poulose <Suzuki.Poulose@arm.com> wrote:
> On 15/10/15 13:37, Mark Rutland wrote:
>>
>> On Thu, Oct 15, 2015 at 12:25:33PM +0100, Suzuki K. Poulose wrote:
>>>
>>> On Thu, Oct 15, 2015 at 11:45:15AM +0100, Mark Rutland wrote:
>>>>
>>>> On Wed, Oct 14, 2015 at 04:13:47PM -0500, Jeremy Linton wrote:
>>>>>
>>>>> On 10/14/2015 06:20 AM, Suzuki K. Poulose wrote:
>
>
>
>>>
>>> ----8>----
>>>
>>> Author: Suzuki K. Poulose <suzuki.poulose@arm.com>
>>> Date:   Wed Oct 14 11:25:16 2015 +0100
>>>
>>>      arm64: Check for selected granule support
>>>
>>>      Ensure that the selected page size is supported by the CPU(s). If it
>>> isn't
>>>      park the CPU. A check is added to the EFI stub to detect if the boot
>>> CPU
>>>      supports the page size, failing which, we fail the boot gracefully,
>>> with
>>>      an error message.
>>>
>>>      Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com>
>>>      [ Added a check to EFI stub ]
>>>      Signed-off-by: Jeremy Linton <jeremy.linton@arm.com>
>>
>>
>> Your sign-off should be last, given you are taking resposibility for
>> Jeremy's patch.
>
>
> OK, I was a bit confused about how it should look like. I kept it on top
> so that I could add [ ] for Jeremy's contribution.
>
>>
>> However, I would prefer that the EFI stub addition were a separate/later
>> patch.
>
>
> OK, that makes sense.
>
>>
>>> diff --git a/arch/arm64/include/asm/sysreg.h
>>> b/arch/arm64/include/asm/sysreg.h
>>> index a7f3d4b..72d814c 100644
>>> --- a/arch/arm64/include/asm/sysreg.h
>>> +++ b/arch/arm64/include/asm/sysreg.h
>
>
>>> +#define ID_AA64MMFR0_TGRAN4_NI         0xf
>>> +#define ID_AA64MMFR0_TGRAN4_ON         0x0
>>> +#define ID_AA64MMFR0_TGRAN64_NI                0xf
>>> +#define ID_AA64MMFR0_TGRAN64_ON                0x0
>>> +#define ID_AA64MMFR0_TGRAN16_NI                0x0
>>> +#define ID_AA64MMFR0_TGRAN16_ON                0x1
>>
>>
>> I still don't like "ON" here -- I thought these would also be changed
>> s/ON/SUPPORTED/.
>
>
> I know and I expected that. I have "_ON" in my 'CPU feature' series, which
> will/can be reused here. Hence kept it _ON. I can change it everywhere to
> _SUPPORTED, since I may need to spin another version for that.
>
>
>>>   #include <linux/efi.h>
>>>   #include <asm/efi.h>
>>> +#include <asm/sysreg.h>
>>>   #include <asm/sections.h>
>>
>>
>> Nit: include order.
>
>
> OK
>
>>
>>>
>>> +#if defined(CONFIG_ARM64_4K_PAGES)
>>> +#define PAGE_SIZE_STR  "4K"
>>> +#elif defined(CONFIG_ARM64_64K_PAGES)
>>> +#define PAGE_SIZE_STR  "64K"
>>> +#endif
>>> +

4k can be dropped (since UEFI support implies support for 4k pages)
16k is missing here

>>>   efi_status_t __init handle_kernel_image(efi_system_table_t
>>> *sys_table_arg,
>>>                                         unsigned long *image_addr,
>>>                                         unsigned long *image_size,
>>> @@ -25,6 +32,17 @@ efi_status_t __init
>>> handle_kernel_image(efi_system_table_t *sys_table_arg,
>>>         unsigned long kernel_size, kernel_memsize = 0;
>>>         unsigned long nr_pages;
>>>         void *old_image_addr = (void *)*image_addr;
>>> +       u64 aa64mmfr0_el1;
>>> +
>>> +       /*
>>> +        * Check to see if the CPU supports the requested pagesize
>>> +        */

... so here you would need a #ifndef CONFIG_ARM_4K_PAGES as well.

>>> +       asm volatile("mrs %0, ID_AA64MMFR0_EL1" : "=r" (aa64mmfr0_el1));
>>
>>
>> Can we not use read_cpuid() or similar here?
>
>
> Yes, I will try that out. I didn't want to include additional header-files
> in efi-stub.c.
>
>
>>> +       aa64mmfr0_el1 >>= ID_AA64MMFR0_TGRAN_SHIFT;
>>
>>
>> ... and can we not do the shift and mask in one go?
>>
>
>>> +       if ((aa64mmfr0_el1 & 0xf) != ID_AA64MMFR0_TGRAN_SUPPORTED) {
>>> +               pr_efi_err(sys_table_arg, PAGE_SIZE_STR" granule not
>>> supported by the CPU\n");
>>
>>
>> Nit: space before the first quote, please.
>
>
> Will do
>
> Thanks
> Suzuki
>

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

* Re: [PATCHv3 08/11] arm64: Check for selected granule support
  2015-10-15 15:11             ` Mark Rutland
@ 2015-10-16  8:11               ` Ard Biesheuvel
  -1 siblings, 0 replies; 110+ messages in thread
From: Ard Biesheuvel @ 2015-10-16  8:11 UTC (permalink / raw)
  To: Mark Rutland
  Cc: Jeremy Linton, Suzuki K. Poulose, linux-arm-kernel, Steve Capper,
	Marc Zyngier, Catalin Marinas, Will Deacon, linux-kernel,
	Christoffer Dall

On 15 October 2015 at 17:11, Mark Rutland <mark.rutland@arm.com> wrote:
> On Thu, Oct 15, 2015 at 09:47:53AM -0500, Jeremy Linton wrote:
>> On 10/15/2015 06:25 AM, Suzuki K. Poulose wrote:
>> >+    /*
>> >+     * Check to see if the CPU supports the requested pagesize
>> >+     */
>> >+    asm volatile("mrs %0, ID_AA64MMFR0_EL1" : "=r" (aa64mmfr0_el1));
>> >+    aa64mmfr0_el1 >>= ID_AA64MMFR0_TGRAN_SHIFT;
>> >+    if ((aa64mmfr0_el1 & 0xf) != ID_AA64MMFR0_TGRAN_SUPPORTED) {
>> >+            pr_efi_err(sys_table_arg, PAGE_SIZE_STR" granule not supported by the CPU\n");
>> >+            return EFI_UNSUPPORTED;
>> >+    }
>>
>>
>> This is definitely an improvement over my original hack job.
>>
>> I would like to add, that I actually think this should be in a new
>> function "check_kernel_compatibility" (or whatever) that is called
>> before handle_kernel_image.
>
> To bikeshed, perhaps efi_arch_check_system?
>

Yes, that makes sense. But before we add such a function, we should
move all the stub C code to libstub where it will be subject to the
new check against R_AARCH64_ABSxx relocations (which we cannot support
in the stub).

>> That is because I don't really think it belongs in
>> handle_kernel_image which is focused on relocation. Plus, if you add
>> another function, you can avoid the "Failed to relocate kernel"
>> error that comes out following the granule not supported message.
>> Further, checks like this in the future will have a place to live.
>
> I agree.
>
> There are some other diagnostic utilities I'd like to add to the stub
> (e.g. dumping the memory map and ID registers) that would help with
> diagnosing boot issues. I started on those at Connect, but realised I
> needed to first implement half of printf for those to be useful.
>

Yes, printf() is sorely lacking in that context. But note that the
memory map can already be retrieved from the UEFI shell via the
'memmap' command.

>> Of course you will then need a matching stubbed out function for the
>> normal arm kernel as well.
>
> I'm sure there are similar things we'll want to check for 32-bit (e.g.
> LPAE support), but a stub should be fine for now.
>

ARM support is not merged yet, but it is good to keep it in mind.

-- 
Ard.

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

* [PATCHv3 08/11] arm64: Check for selected granule support
@ 2015-10-16  8:11               ` Ard Biesheuvel
  0 siblings, 0 replies; 110+ messages in thread
From: Ard Biesheuvel @ 2015-10-16  8:11 UTC (permalink / raw)
  To: linux-arm-kernel

On 15 October 2015 at 17:11, Mark Rutland <mark.rutland@arm.com> wrote:
> On Thu, Oct 15, 2015 at 09:47:53AM -0500, Jeremy Linton wrote:
>> On 10/15/2015 06:25 AM, Suzuki K. Poulose wrote:
>> >+    /*
>> >+     * Check to see if the CPU supports the requested pagesize
>> >+     */
>> >+    asm volatile("mrs %0, ID_AA64MMFR0_EL1" : "=r" (aa64mmfr0_el1));
>> >+    aa64mmfr0_el1 >>= ID_AA64MMFR0_TGRAN_SHIFT;
>> >+    if ((aa64mmfr0_el1 & 0xf) != ID_AA64MMFR0_TGRAN_SUPPORTED) {
>> >+            pr_efi_err(sys_table_arg, PAGE_SIZE_STR" granule not supported by the CPU\n");
>> >+            return EFI_UNSUPPORTED;
>> >+    }
>>
>>
>> This is definitely an improvement over my original hack job.
>>
>> I would like to add, that I actually think this should be in a new
>> function "check_kernel_compatibility" (or whatever) that is called
>> before handle_kernel_image.
>
> To bikeshed, perhaps efi_arch_check_system?
>

Yes, that makes sense. But before we add such a function, we should
move all the stub C code to libstub where it will be subject to the
new check against R_AARCH64_ABSxx relocations (which we cannot support
in the stub).

>> That is because I don't really think it belongs in
>> handle_kernel_image which is focused on relocation. Plus, if you add
>> another function, you can avoid the "Failed to relocate kernel"
>> error that comes out following the granule not supported message.
>> Further, checks like this in the future will have a place to live.
>
> I agree.
>
> There are some other diagnostic utilities I'd like to add to the stub
> (e.g. dumping the memory map and ID registers) that would help with
> diagnosing boot issues. I started on those at Connect, but realised I
> needed to first implement half of printf for those to be useful.
>

Yes, printf() is sorely lacking in that context. But note that the
memory map can already be retrieved from the UEFI shell via the
'memmap' command.

>> Of course you will then need a matching stubbed out function for the
>> normal arm kernel as well.
>
> I'm sure there are similar things we'll want to check for 32-bit (e.g.
> LPAE support), but a stub should be fine for now.
>

ARM support is not merged yet, but it is good to keep it in mind.

-- 
Ard.

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

end of thread, other threads:[~2015-10-16  8:11 UTC | newest]

Thread overview: 110+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-10-14 11:20 [PATCHv3 00/11] arm64: 16K translation granule support Suzuki K. Poulose
2015-10-14 11:20 ` Suzuki K. Poulose
2015-10-14 11:20 ` [PATCHv3 01/11] arm64: Move swapper pagetable definitions Suzuki K. Poulose
2015-10-14 11:20   ` Suzuki K. Poulose
2015-10-14 11:42   ` Mark Rutland
2015-10-14 11:42     ` Mark Rutland
2015-10-14 12:41     ` Suzuki K. Poulose
2015-10-14 12:41       ` Suzuki K. Poulose
2015-10-14 11:20 ` [PATCHv3 02/11] arm64: Handle section maps for swapper/idmap Suzuki K. Poulose
2015-10-14 11:20   ` Suzuki K. Poulose
2015-10-14 12:06   ` Mark Rutland
2015-10-14 12:06     ` Mark Rutland
2015-10-14 13:21     ` Suzuki K. Poulose
2015-10-14 13:21       ` Suzuki K. Poulose
2015-10-14 14:51       ` Mark Rutland
2015-10-14 14:51         ` Mark Rutland
2015-10-14 15:08         ` Suzuki K. Poulose
2015-10-14 15:08           ` Suzuki K. Poulose
2015-10-14 15:14           ` Mark Rutland
2015-10-14 15:14             ` Mark Rutland
2015-10-14 11:20 ` [PATCHv3 03/11] arm64: Introduce helpers for page table levels Suzuki K. Poulose
2015-10-14 11:20   ` Suzuki K. Poulose
2015-10-14 17:07   ` Mark Rutland
2015-10-14 17:07     ` Mark Rutland
2015-10-15  9:35     ` Suzuki K. Poulose
2015-10-15  9:35       ` Suzuki K. Poulose
2015-10-15 10:37       ` Mark Rutland
2015-10-15 10:37         ` Mark Rutland
2015-10-15 11:40       ` Christoffer Dall
2015-10-15 11:40         ` Christoffer Dall
2015-10-15 11:37   ` Christoffer Dall
2015-10-15 11:37     ` Christoffer Dall
2015-10-15 12:44     ` Mark Rutland
2015-10-15 12:44       ` Mark Rutland
2015-10-15 13:14       ` Suzuki K. Poulose
2015-10-15 13:14         ` Suzuki K. Poulose
2015-10-15 13:30         ` Christoffer Dall
2015-10-15 13:30           ` Christoffer Dall
2015-10-15 13:48           ` Suzuki K. Poulose
2015-10-15 13:48             ` Suzuki K. Poulose
2015-10-15 14:15             ` Christoffer Dall
2015-10-15 14:15               ` Christoffer Dall
2015-10-14 11:20 ` [PATCHv3 04/11] arm64: Calculate size for idmap_pg_dir at compile time Suzuki K. Poulose
2015-10-14 11:20   ` Suzuki K. Poulose
2015-10-14 17:12   ` Mark Rutland
2015-10-14 17:12     ` Mark Rutland
2015-10-14 11:20 ` [PATCHv3 05/11] arm64: Handle 4 level page table for swapper Suzuki K. Poulose
2015-10-14 11:20   ` Suzuki K. Poulose
2015-10-14 17:15   ` Mark Rutland
2015-10-14 17:15     ` Mark Rutland
2015-10-14 11:20 ` [PATCHv3 06/11] arm64: Clean config usages for page size Suzuki K. Poulose
2015-10-14 11:20   ` Suzuki K. Poulose
2015-10-14 11:20 ` [PATCHv3 07/11] arm64: Kconfig: Fix help text about AArch32 support with 64K pages Suzuki K. Poulose
2015-10-14 11:20   ` Suzuki K. Poulose
2015-10-14 17:16   ` Mark Rutland
2015-10-14 17:16     ` Mark Rutland
2015-10-14 11:20 ` [PATCHv3 08/11] arm64: Check for selected granule support Suzuki K. Poulose
2015-10-14 11:20   ` Suzuki K. Poulose
2015-10-14 17:24   ` Mark Rutland
2015-10-14 17:24     ` Mark Rutland
2015-10-14 17:32     ` Mark Rutland
2015-10-14 17:32       ` Mark Rutland
2015-10-15  9:45     ` Suzuki K. Poulose
2015-10-15  9:45       ` Suzuki K. Poulose
2015-10-15 10:39       ` Mark Rutland
2015-10-15 10:39         ` Mark Rutland
2015-10-14 21:13   ` Jeremy Linton
2015-10-14 21:13     ` Jeremy Linton
2015-10-15  9:48     ` Suzuki K. Poulose
2015-10-15  9:48       ` Suzuki K. Poulose
2015-10-15 10:45     ` Mark Rutland
2015-10-15 10:45       ` Mark Rutland
2015-10-15 11:25       ` Suzuki K. Poulose
2015-10-15 11:25         ` Suzuki K. Poulose
2015-10-15 12:37         ` Mark Rutland
2015-10-15 12:37           ` Mark Rutland
2015-10-15 12:58           ` Suzuki K. Poulose
2015-10-15 12:58             ` Suzuki K. Poulose
2015-10-16  8:03             ` Ard Biesheuvel
2015-10-16  8:03               ` Ard Biesheuvel
2015-10-15 14:47         ` Jeremy Linton
2015-10-15 14:47           ` Jeremy Linton
2015-10-15 15:02           ` Suzuki K. Poulose
2015-10-15 15:02             ` Suzuki K. Poulose
2015-10-15 15:11           ` Mark Rutland
2015-10-15 15:11             ` Mark Rutland
2015-10-16  8:11             ` Ard Biesheuvel
2015-10-16  8:11               ` Ard Biesheuvel
2015-10-14 11:20 ` [PATCHv3 09/11] arm64: Add page size to the kernel image header Suzuki K. Poulose
2015-10-14 11:20   ` Suzuki K. Poulose
2015-10-14 17:27   ` Mark Rutland
2015-10-14 17:27     ` Mark Rutland
2015-10-15  9:19     ` Suzuki K. Poulose
2015-10-15  9:19       ` Suzuki K. Poulose
2015-10-14 11:20 ` [PATCHv3 10/11] arm64: Add 16K page size support Suzuki K. Poulose
2015-10-14 11:20   ` Suzuki K. Poulose
2015-10-14 15:40   ` Jeremy Linton
2015-10-14 15:40     ` Jeremy Linton
2015-10-14 15:53     ` Suzuki K. Poulose
2015-10-14 15:53       ` Suzuki K. Poulose
2015-10-15 14:06   ` Mark Rutland
2015-10-15 14:06     ` Mark Rutland
2015-10-15 14:48     ` Suzuki K. Poulose
2015-10-15 14:48       ` Suzuki K. Poulose
2015-10-15 15:36       ` Steve Capper
2015-10-15 15:36         ` Steve Capper
2015-10-15 15:48         ` Suzuki K. Poulose
2015-10-15 15:48           ` Suzuki K. Poulose
2015-10-14 11:20 ` [PATCHv3 11/11] arm64: 36 bit VA Suzuki K. Poulose
2015-10-14 11:20   ` Suzuki K. Poulose

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.