Skip to contentSkip to conversation

AArch64 Linux kernel port

PATCH In review Catalin Marinas 13 participants 115 messages Sep 7, 2012 – Aug 27, 2015

Subsystems (16)
lore
Share & tools
lore

Catalin Marinas

author maintainer
#0 lore raw

v3 cover AArch64 Linux kernel port

This is the 3rd version of patches implementing Linux kernel support for the 64-bit ARM architecture. Most of the review comments for the previous release have been implemented. There are a few left (like generic timer dts specification) but the main goal was to freeze the user ABI.

The Linux kernel patches are available on this tree:

git://git.kernel.org/pub/scm/linux/kernel/git/cmarinas/linux-aarch64.git upstream

Main changes since the previous version:
- ptrace interface now using regsets for TLS and hardware debug registers.
- sys_personality fixes. PER_LINUX is the default for all tasks (32 or 64-bit) and there is no compat_sys_personality defined.
- Kconfig clean-up (unused symbols, AARCH32_EMULATION removed in favour of COMPAT).
- Clean-up of the __cpuc_* function prefixes.
- CPU information table implemented in C rather than assembly.
- __bad_* function calls replaced with BUILD_BUG.
- Inline get_user/put_user (code cleaner, slightly bigger kernel Image).
- DMA API implementation simplified, defaulting to swiotlb. It will be extended as hardware becomes available.
- Arch-specific code in the generic timer patch moved to arch/arm64/.
- Comment fixes and clarifications.

Background to the 64-bit ARM architecture:

ARM introduced AArch64 as part of the ARMv8 architecture and consists of a substantially revised exception model (with 4 exception levels: EL0 - user, EL1 - kernel, EL2 - hypervisor, EL3 - secure monitor), new A64 instruction set based on larger register file, new FP/SIMD instructions. The new ABI is LP64 and takes advantage of the larger register file. It also mandates FP.

AArch64 documentation currently available (publicly, though click-through agreement required):

- Instruction Set Overview:
http://infocenter.arm.com/help/topic/com.arm.doc.genc010197a/index.html

- ABI (PCS, ELF, DWARF, C++):
http://infocenter.arm.com/help/topic/com.arm.doc.ihi0059a/index.html

Regards,

Catalin

Catalin Marinas (23):
arm64: Assembly macros and definitions
arm64: Kernel booting and initialisation
arm64: Exception handling
arm64: MMU definitions
arm64: MMU initialisation
arm64: MMU fault handling and page table management
arm64: Process management
arm64: CPU support
arm64: Cache maintenance routines
arm64: TLB maintenance functionality
arm64: Atomic operations
arm64: Device specific operations
arm64: DMA mapping API
arm64: SMP support
arm64: ELF definitions
arm64: System calls handling
arm64: Signal handling support
arm64: User access library functions
arm64: Floating point and SIMD
arm64: Add support for /proc/sys/debug/exception-trace
arm64: Miscellaneous header files
arm64: Build infrastructure
arm64: MAINTAINERS update

Marc Zyngier (3):
arm64: IRQ handling
arm64: Miscellaneous library functions
arm64: Generic timers support

Will Deacon (5):
arm64: VDSO support
arm64: 32-bit (compat) applications support
arm64: Debugging support
arm64: Performance counters support
arm64: Loadable modules

 Documentation/arm64/booting.txt               |  152 +++
 Documentation/arm64/memory.txt                |   69 ++
 MAINTAINERS                                   |    6 +
 arch/arm64/Kconfig                            |  222 ++++
 arch/arm64/Kconfig.debug                      |   27 +
 arch/arm64/Makefile                           |   71 ++
 arch/arm64/boot/.gitignore                    |    2 +
 arch/arm64/boot/Makefile                      |   36 +
 arch/arm64/boot/install.sh                    |   46 +
 arch/arm64/configs/defconfig                  |   85 ++
 arch/arm64/include/asm/Kbuild                 |   51 +
 arch/arm64/include/asm/arm_generic.h          |  100 ++
 arch/arm64/include/asm/asm-offsets.h          |    1 +
 arch/arm64/include/asm/assembler.h            |  109 ++
 arch/arm64/include/asm/atomic.h               |  305 ++++++
 arch/arm64/include/asm/auxvec.h               |   22 +
 arch/arm64/include/asm/barrier.h              |   52 +
 arch/arm64/include/asm/bitops.h               |   74 ++
 arch/arm64/include/asm/bitsperlong.h          |   23 +
 arch/arm64/include/asm/byteorder.h            |   21 +
 arch/arm64/include/asm/cache.h                |   32 +
 arch/arm64/include/asm/cacheflush.h           |  168 +++
 arch/arm64/include/asm/cachetype.h            |   48 +
 arch/arm64/include/asm/cmpxchg.h              |  173 ++++
 arch/arm64/include/asm/compat.h               |  242 +++++
 arch/arm64/include/asm/compiler.h             |   30 +
 arch/arm64/include/asm/cputable.h             |   30 +
 arch/arm64/include/asm/cputype.h              |   49 +
 arch/arm64/include/asm/debug-monitors.h       |   88 ++
 arch/arm64/include/asm/device.h               |   26 +
 arch/arm64/include/asm/dma-mapping.h          |  124 +++
 arch/arm64/include/asm/elf.h                  |  179 ++++
 arch/arm64/include/asm/exception.h            |   23 +
 arch/arm64/include/asm/exec.h                 |   23 +
 arch/arm64/include/asm/fb.h                   |   34 +
 arch/arm64/include/asm/fcntl.h                |   29 +
 arch/arm64/include/asm/fpsimd.h               |   64 ++
 arch/arm64/include/asm/futex.h                |  136 +++
 arch/arm64/include/asm/hardirq.h              |   52 +
 arch/arm64/include/asm/hw_breakpoint.h        |  137 +++
 arch/arm64/include/asm/hwcap.h                |   53 +
 arch/arm64/include/asm/io.h                   |  263 +++++
 arch/arm64/include/asm/irq.h                  |    8 +
 arch/arm64/include/asm/irqflags.h             |   91 ++
 arch/arm64/include/asm/memblock.h             |   21 +
 arch/arm64/include/asm/memory.h               |  144 +++
 arch/arm64/include/asm/mmu.h                  |   27 +
 arch/arm64/include/asm/mmu_context.h          |  152 +++
 arch/arm64/include/asm/module.h               |   23 +
 arch/arm64/include/asm/page.h                 |   67 ++
 arch/arm64/include/asm/param.h                |   23 +
 arch/arm64/include/asm/perf_event.h           |   22 +
 arch/arm64/include/asm/pgalloc.h              |  113 ++
 arch/arm64/include/asm/pgtable-2level-hwdef.h |   43 +
 arch/arm64/include/asm/pgtable-2level-types.h |   60 ++
 arch/arm64/include/asm/pgtable-3level-hwdef.h |   50 +
 arch/arm64/include/asm/pgtable-3level-types.h |   66 ++
 arch/arm64/include/asm/pgtable-hwdef.h        |   94 ++
 arch/arm64/include/asm/pgtable.h              |  328 ++++++
 arch/arm64/include/asm/pmu.h                  |   82 ++
 arch/arm64/include/asm/proc-fns.h             |   51 +
 arch/arm64/include/asm/processor.h            |  175 ++++
 arch/arm64/include/asm/prom.h                 |    1 +
 arch/arm64/include/asm/ptrace.h               |  212 ++++
 arch/arm64/include/asm/setup.h                |   26 +
 arch/arm64/include/asm/shmparam.h             |   28 +
 arch/arm64/include/asm/sigcontext.h           |   69 ++
 arch/arm64/include/asm/siginfo.h              |   23 +
 arch/arm64/include/asm/signal.h               |   24 +
 arch/arm64/include/asm/signal32.h             |   53 +
 arch/arm64/include/asm/smp.h                  |   69 ++
 arch/arm64/include/asm/sparsemem.h            |   24 +
 arch/arm64/include/asm/spinlock.h             |  202 ++++
 arch/arm64/include/asm/spinlock_types.h       |   38 +
 arch/arm64/include/asm/stacktrace.h           |   29 +
 arch/arm64/include/asm/stat.h                 |   62 ++
 arch/arm64/include/asm/statfs.h               |   23 +
 arch/arm64/include/asm/syscall.h              |  101 ++
 arch/arm64/include/asm/syscalls.h             |   40 +
 arch/arm64/include/asm/system_misc.h          |   54 +
 arch/arm64/include/asm/thread_info.h          |  127 +++
 arch/arm64/include/asm/timex.h                |   29 +
 arch/arm64/include/asm/tlb.h                  |  190 ++++
 arch/arm64/include/asm/tlbflush.h             |  122 +++
 arch/arm64/include/asm/traps.h                |   30 +
 arch/arm64/include/asm/uaccess.h              |  297 ++++++
 arch/arm64/include/asm/ucontext.h             |   30 +
 arch/arm64/include/asm/unistd.h               |   27 +
 arch/arm64/include/asm/unistd32.h             |  758 ++++++++++++++
 arch/arm64/include/asm/vdso.h                 |   41 +
 arch/arm64/include/asm/vdso_datapage.h        |   43 +
 arch/arm64/kernel/.gitignore                  |    1 +
 arch/arm64/kernel/Makefile                    |   27 +
 arch/arm64/kernel/arm64ksyms.c                |   46 +
 arch/arm64/kernel/asm-offsets.c               |  108 ++
 arch/arm64/kernel/cputable.c                  |   33 +
 arch/arm64/kernel/debug-monitors.c            |  288 ++++++
 arch/arm64/kernel/entry-fpsimd.S              |   80 ++
 arch/arm64/kernel/entry.S                     |  695 +++++++++++++
 arch/arm64/kernel/fpsimd.c                    |  106 ++
 arch/arm64/kernel/head.S                      |  510 +++++++++
 arch/arm64/kernel/hw_breakpoint.c             |  880 ++++++++++++++++
 arch/arm64/kernel/io.c                        |   64 ++
 arch/arm64/kernel/irq.c                       |   84 ++
 arch/arm64/kernel/kuser32.S                   |   77 ++
 arch/arm64/kernel/module.c                    |  456 ++++++++
 arch/arm64/kernel/perf_event.c                | 1368 +++++++++++++++++++++++++
 arch/arm64/kernel/process.c                   |  412 ++++++++
 arch/arm64/kernel/ptrace.c                    | 1126 ++++++++++++++++++++
 arch/arm64/kernel/setup.c                     |  351 +++++++
 arch/arm64/kernel/signal.c                    |  437 ++++++++
 arch/arm64/kernel/signal32.c                  |  876 ++++++++++++++++
 arch/arm64/kernel/smp.c                       |  469 +++++++++
 arch/arm64/kernel/stacktrace.c                |  127 +++
 arch/arm64/kernel/sys.c                       |  138 +++
 arch/arm64/kernel/sys32.S                     |  282 +++++
 arch/arm64/kernel/sys_compat.c                |  164 +++
 arch/arm64/kernel/time.c                      |   65 ++
 arch/arm64/kernel/traps.c                     |  348 +++++++
 arch/arm64/kernel/vdso.c                      |  261 +++++
 arch/arm64/kernel/vdso/.gitignore             |    2 +
 arch/arm64/kernel/vdso/Makefile               |   63 ++
 arch/arm64/kernel/vdso/gen_vdso_offsets.sh    |   15 +
 arch/arm64/kernel/vdso/gettimeofday.S         |  242 +++++
 arch/arm64/kernel/vdso/note.S                 |   28 +
 arch/arm64/kernel/vdso/sigreturn.S            |   37 +
 arch/arm64/kernel/vdso/vdso.S                 |   33 +
 arch/arm64/kernel/vdso/vdso.lds.S             |  100 ++
 arch/arm64/kernel/vmlinux.lds.S               |  126 +++
 arch/arm64/lib/Makefile                       |    4 +
 arch/arm64/lib/bitops.c                       |   25 +
 arch/arm64/lib/clear_page.S                   |   39 +
 arch/arm64/lib/clear_user.S                   |   58 ++
 arch/arm64/lib/copy_from_user.S               |   66 ++
 arch/arm64/lib/copy_in_user.S                 |   63 ++
 arch/arm64/lib/copy_page.S                    |   46 +
 arch/arm64/lib/copy_to_user.S                 |   61 ++
 arch/arm64/lib/delay.c                        |   55 +
 arch/arm64/lib/strncpy_from_user.S            |   50 +
 arch/arm64/lib/strnlen_user.S                 |   47 +
 arch/arm64/mm/Makefile                        |    4 +
 arch/arm64/mm/cache.S                         |  251 +++++
 arch/arm64/mm/context.c                       |  159 +++
 arch/arm64/mm/copypage.c                      |   34 +
 arch/arm64/mm/dma-mapping.c                   |   79 ++
 arch/arm64/mm/extable.c                       |   17 +
 arch/arm64/mm/fault.c                         |  534 ++++++++++
 arch/arm64/mm/flush.c                         |  138 +++
 arch/arm64/mm/init.c                          |  416 ++++++++
 arch/arm64/mm/ioremap.c                       |   84 ++
 arch/arm64/mm/mm.h                            |    2 +
 arch/arm64/mm/mmap.c                          |  144 +++
 arch/arm64/mm/mmu.c                           |  395 +++++++
 arch/arm64/mm/pgd.c                           |   54 +
 arch/arm64/mm/proc-macros.S                   |   55 +
 arch/arm64/mm/proc.S                          |  181 ++++
 arch/arm64/mm/tlb.S                           |   71 ++
 drivers/clocksource/Kconfig                   |    5 +
 drivers/clocksource/Makefile                  |    1 +
 drivers/clocksource/arm_generic.c             |  232 +++++
 include/clocksource/arm_generic.h             |   21 +
 include/linux/elf.h                           |    3 +
 init/Kconfig                                  |    3 +-
 kernel/sysctl.c                               |    2 +-
 lib/Kconfig.debug                             |    6 +-
 tools/perf/perf.h                             |    6 +
author maintainer
#1 lore raw

PATCH v3 1/31 arm64: Assembly macros and definitions

This patch introduces several assembly macros and definitions used in the .S files across arch/arm64/ like IRQ disabling/enabling, together with asm-offsets.c.

---
 arch/arm64/include/asm/asm-offsets.h |    1 +
 arch/arm64/include/asm/assembler.h   |  109 ++++++++++++++++++++++++++++++++++
 arch/arm64/kernel/asm-offsets.c      |  108 +++++++++++++++++++++++++++++++++
 arch/arm64/mm/proc-macros.S          |   55 +++++++++++++++++
 4 files changed, 273 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm64/include/asm/asm-offsets.h
 create mode 100644 arch/arm64/include/asm/assembler.h
 create mode 100644 arch/arm64/kernel/asm-offsets.c
 create mode 100644 arch/arm64/mm/proc-macros.S
arch/arm64/include/asm/asm-offsets.h new file +1 -0
new file mode 100644
index 0000000..d370ee3
@@ -0,0 +1 @@
+#include <generated/asm-offsets.h>
arch/arm64/include/asm/assembler.h new file +109 -0

109 lines not on this page · raw message

arch/arm64/kernel/asm-offsets.c new file +108 -0

108 lines not on this page · raw message

arch/arm64/mm/proc-macros.S new file +55 -0

55 lines not on this page · raw message

author maintainer
#2 lore raw

PATCH v3 2/31 arm64: Kernel booting and initialisation

In reply to Catalin Marinas

The patch adds the kernel booting and the initial setup code. Documentation/arm64/booting.txt describes the booting protocol on the AArch64 Linux kernel. This is subject to change following the work on boot standardisation, ACPI.

---
 Documentation/arm64/booting.txt |  152 ++++++++++++
 arch/arm64/include/asm/setup.h  |   26 ++
 arch/arm64/kernel/head.S        |  510 +++++++++++++++++++++++++++++++++++++++
 arch/arm64/kernel/setup.c       |  351 +++++++++++++++++++++++++++
 4 files changed, 1039 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/arm64/booting.txt
 create mode 100644 arch/arm64/include/asm/setup.h
 create mode 100644 arch/arm64/kernel/head.S
 create mode 100644 arch/arm64/kernel/setup.c
Documentation/arm64/booting.txt new file +152 -0
new file mode 100644
index 0000000..9c4d388
@@ -0,0 +1,152 @@
+			Booting AArch64 Linux
+			=====================
+
+Author: Will Deacon <[email protected]>
+Date  : 07 September 2012
+
+This document is based on the ARM booting document by Russell King and
+is relevant to all public releases of the AArch64 Linux kernel.
+
+The AArch64 exception model is made up of a number of exception levels
+(EL0 - EL3), with EL0 and EL1 having a secure and a non-secure
+counterpart.  EL2 is the hypervisor level and exists only in non-secure
+mode. EL3 is the highest priority level and exists only in secure mode.
+
+For the purposes of this document, we will use the term `boot loader'
+simply to define all software that executes on the CPU(s) before control
+is passed to the Linux kernel.  This may include secure monitor and
+hypervisor code, or it may just be a handful of instructions for
+preparing a minimal boot environment.
+
+Essentially, the boot loader should provide (as a minimum) the
+following:
+
+1. Setup and initialise the RAM
+2. Setup the device tree
+3. Decompress the kernel image
+4. Call the kernel image
+
+
+1. Setup and initialise RAM
+---------------------------
+
+Requirement: MANDATORY
+
+The boot loader is expected to find and initialise all RAM that the
+kernel will use for volatile data storage in the system.  It performs
+this in a machine dependent manner.  (It may use internal algorithms
+to automatically locate and size all RAM, or it may use knowledge of
+the RAM in the machine, or any other method the boot loader designer
+sees fit.)
+
+
+2. Setup the device tree
+-------------------------
+
+Requirement: MANDATORY
+
+The device tree blob (dtb) must be no bigger than 2 megabytes in size
+and placed at a 2-megabyte boundary within the first 512 megabytes from
+the start of the kernel image. This is to allow the kernel to map the
+blob using a single section mapping in the initial page tables.
+
+
+3. Decompress the kernel image
+------------------------------
+
+Requirement: OPTIONAL
+
+The AArch64 kernel does not currently provide a decompressor and
+therefore requires decompression (gzip etc.) to be performed by the boot
+loader if a compressed Image target (e.g. Image.gz) is used.  For
+bootloaders that do not implement this requirement, the uncompressed
+Image target is available instead.
+
+
+4. Call the kernel image
+------------------------
+
+Requirement: MANDATORY
+
+The decompressed kernel image contains a 32-byte header as follows:
+
+  u32 magic	= 0x14000008;	/* branch to stext, little-endian */
+  u32 res0	= 0;		/* reserved */
+  u64 text_offset;		/* Image load offset */
+  u64 res1	= 0;		/* reserved */
+  u64 res2	= 0;		/* reserved */
+
+The image must be placed at the specified offset (currently 0x80000)
+from the start of the system RAM and called there. The start of the
+system RAM must be aligned to 2MB.
+
+Before jumping into the kernel, the following conditions must be met:
+
+- Quiesce all DMA capable devices so that memory does not get
+  corrupted by bogus network packets or disk data.  This will save
+  you many hours of debug.
+
+- Primary CPU general-purpose register settings
+  x0 = physical address of device tree blob (dtb) in system RAM.
+  x1 = 0 (reserved for future use)
+  x2 = 0 (reserved for future use)
+  x3 = 0 (reserved for future use)
+
+- CPU mode
+  All forms of interrupts must be masked in PSTATE.DAIF (Debug, SError,
+  IRQ and FIQ).
+  The CPU must be in either EL2 (RECOMMENDED in order to have access to
+  the virtualisation extensions) or non-secure EL1.
+
+- Caches, MMUs
+  The MMU must be off.
+  Instruction cache may be on or off.
+  Data cache must be off and invalidated.
+  External caches (if present) must be configured and disabled.
+
+- Architected timers
+  CNTFRQ must be programmed with the timer frequency.
+  If entering the kernel at EL1, CNTHCTL_EL2 must have EL1PCTEN (bit 0)
+  set where available.
+
+- Coherency
+  All CPUs to be booted by the kernel must be part of the same coherency
+  domain on entry to the kernel.  This may require IMPLEMENTATION DEFINED
+  initialisation to enable the receiving of maintenance operations on
+  each CPU.
+
+- System registers
+  All writable architected system registers at the exception level where
+  the kernel image will be entered must be initialised by software at a
+  higher exception level to prevent execution in an UNKNOWN state.
+
+The boot loader is expected to enter the kernel on each CPU in the
+following manner:
+
+- The primary CPU must jump directly to the first instruction of the
+  kernel image.  The device tree blob passed by this CPU must contain
+  for each CPU node:
+
+    1. An 'enable-method' property. Currently, the only supported value
+       for this field is the string "spin-table".
+
+    2. A 'cpu-release-addr' property identifying a 64-bit,
+       zero-initialised memory location.
+
+  It is expected that the bootloader will generate these device tree
+  properties and insert them into the blob prior to kernel entry.
+
+- Any secondary CPUs must spin outside of the kernel in a reserved area
+  of memory (communicated to the kernel by a /memreserve/ region in the
+  device tree) polling their cpu-release-addr location, which must be
+  contained in the reserved region.  A wfe instruction may be inserted
+  to reduce the overhead of the busy-loop and a sev will be issued by
+  the primary CPU.  When a read of the location pointed to by the
+  cpu-release-addr returns a non-zero value, the CPU must jump directly
+  to this value.
+
+- Secondary CPU general-purpose register settings
+  x0 = 0 (reserved for future use)
+  x1 = 0 (reserved for future use)
+  x2 = 0 (reserved for future use)
+  x3 = 0 (reserved for future use)
arch/arm64/include/asm/setup.h new file +26 -0
new file mode 100644
index 0000000..9cf2e46
@@ -0,0 +1,26 @@
+/*
+ * Based on arch/arm/include/asm/setup.h
+ *
+ * Copyright (C) 1997-1999 Russell King
+ * Copyright (C) 2012 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_SETUP_H
+#define __ASM_SETUP_H
+
+#include <linux/types.h>
+
+#define COMMAND_LINE_SIZE	2048
+
+#endif
arch/arm64/kernel/head.S new file +510 -0

510 lines not on this page · raw message

arch/arm64/kernel/setup.c new file +351 -0

351 lines not on this page · raw message

maintainer Acked-by on v3 2/31
#3 lore raw

Re: [PATCH v3 02/31] arm64: Kernel booting and initialisation

Quoted 10 lines · Catalin Marinas

The patch adds the kernel booting and the initial setup code. Documentation/arm64/booting.txt describes the booting protocol on the AArch64 Linux kernel. This is subject to change following the work on boot standardisation, ACPI.

#4 lore raw

Re: [PATCH v3 02/31] arm64: Kernel booting and initialisation

In reply to Catalin Marinas
Quoted 67 lines · Catalin Marinas

The patch adds the kernel booting and the initial setup code. Documentation/arm64/booting.txt describes the booting protocol on the AArch64 Linux kernel. This is subject to change following the work on boot standardisation, ACPI.

---
 Documentation/arm64/booting.txt |  152 ++++++++++++
 arch/arm64/include/asm/setup.h  |   26 ++
 arch/arm64/kernel/head.S        |  510 +++++++++++++++++++++++++++++++++++++++
 arch/arm64/kernel/setup.c       |  351 +++++++++++++++++++++++++++
 4 files changed, 1039 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/arm64/booting.txt
 create mode 100644 arch/arm64/include/asm/setup.h
 create mode 100644 arch/arm64/kernel/head.S
 create mode 100644 arch/arm64/kernel/setup.c
Documentation/arm64/booting.txt new file +41 -0
new file mode 100644
index 0000000..9c4d388
@@ -0,0 +1,152 @@
+			Booting AArch64 Linux
+			=====================
+
+Author: Will Deacon <[email protected]>
+Date  : 07 September 2012
+
+This document is based on the ARM booting document by Russell King and
+is relevant to all public releases of the AArch64 Linux kernel.
+
+The AArch64 exception model is made up of a number of exception levels
+(EL0 - EL3), with EL0 and EL1 having a secure and a non-secure
+counterpart.  EL2 is the hypervisor level and exists only in non-secure
+mode. EL3 is the highest priority level and exists only in secure mode.
+
+For the purposes of this document, we will use the term `boot loader'
+simply to define all software that executes on the CPU(s) before control
+is passed to the Linux kernel.  This may include secure monitor and
+hypervisor code, or it may just be a handful of instructions for
+preparing a minimal boot environment.
+
+Essentially, the boot loader should provide (as a minimum) the
+following:
+
+1. Setup and initialise the RAM
+2. Setup the device tree
+3. Decompress the kernel image
+4. Call the kernel image
+
+
+1. Setup and initialise RAM
+---------------------------
+
+Requirement: MANDATORY
+
+The boot loader is expected to find and initialise all RAM that the
+kernel will use for volatile data storage in the system.  It performs
+this in a machine dependent manner.  (It may use internal algorithms
+to automatically locate and size all RAM, or it may use knowledge of
+the RAM in the machine, or any other method the boot loader designer
+sees fit.)
+

Documentation/arm64/booting.txt line 51

Quoted 10 lines
Documentation/arm64/booting.txt new file +10 -0
+
+2. Setup the device tree
+-------------------------
+
+Requirement: MANDATORY
+
+The device tree blob (dtb) must be no bigger than 2 megabytes in size
+and placed at a 2-megabyte boundary within the first 512 megabytes from
+the start of the kernel image. This is to allow the kernel to map the
+blob using a single section mapping in the initial page tables.

why do you want to restrict the DT to be less tahn 2MiB?

Quoted 16 lines
Documentation/arm64/booting.txt new file +16 -0
+
+
+3. Decompress the kernel image
+------------------------------
+
+Requirement: OPTIONAL
+
+The AArch64 kernel does not currently provide a decompressor and
+therefore requires decompression (gzip etc.) to be performed by the boot
+loader if a compressed Image target (e.g. Image.gz) is used.  For
+bootloaders that do not implement this requirement, the uncompressed
+Image target is available instead.
+
+
+4. Call the kernel image
+------------------------

Documentation/arm64/booting.txt line 77

Quoted 10 lines
Documentation/arm64/booting.txt new file +10 -0
+
+Requirement: MANDATORY
+
+The decompressed kernel image contains a 32-byte header as follows:
+
+  u32 magic	= 0x14000008;	/* branch to stext, little-endian */
+  u32 res0	= 0;		/* reserved */
+  u64 text_offset;		/* Image load offset */
+  u64 res1	= 0;		/* reserved */
+  u64 res2	= 0;		/* reserved */

we need to have a magic to known it's a arm64 kernel

Documentation/arm64/booting.txt line 81

Quoted 4 lines
Documentation/arm64/booting.txt new file +4 -0
+
+The image must be placed at the specified offset (currently 0x80000)
+from the start of the system RAM and called there. The start of the
+system RAM must be aligned to 2MB.

can we drop this

Quoted 19 lines
Documentation/arm64/booting.txt new file +19 -0
+
+Before jumping into the kernel, the following conditions must be met:
+
+- Quiesce all DMA capable devices so that memory does not get
+  corrupted by bogus network packets or disk data.  This will save
+  you many hours of debug.
+
+- Primary CPU general-purpose register settings
+  x0 = physical address of device tree blob (dtb) in system RAM.
+  x1 = 0 (reserved for future use)
+  x2 = 0 (reserved for future use)
+  x3 = 0 (reserved for future use)
+
+- CPU mode
+  All forms of interrupts must be masked in PSTATE.DAIF (Debug, SError,
+  IRQ and FIQ).
+  The CPU must be in either EL2 (RECOMMENDED in order to have access to
+  the virtualisation extensions) or non-secure EL1.
+

Documentation/arm64/booting.txt line 110

Quoted 10 lines
Documentation/arm64/booting.txt new file +10 -0
+- Caches, MMUs
+  The MMU must be off.
+  Instruction cache may be on or off.
+  Data cache must be off and invalidated.
+  External caches (if present) must be configured and disabled.
+
+- Architected timers
+  CNTFRQ must be programmed with the timer frequency.
+  If entering the kernel at EL1, CNTHCTL_EL2 must have EL1PCTEN (bit 0)
+  set where available.

can you explain why?

Quoted 26 lines
Documentation/arm64/booting.txt new file +26 -0
+
+- Coherency
+  All CPUs to be booted by the kernel must be part of the same coherency
+  domain on entry to the kernel.  This may require IMPLEMENTATION DEFINED
+  initialisation to enable the receiving of maintenance operations on
+  each CPU.
+
+- System registers
+  All writable architected system registers at the exception level where
+  the kernel image will be entered must be initialised by software at a
+  higher exception level to prevent execution in an UNKNOWN state.
+
+The boot loader is expected to enter the kernel on each CPU in the
+following manner:
+
+- The primary CPU must jump directly to the first instruction of the
+  kernel image.  The device tree blob passed by this CPU must contain
+  for each CPU node:
+
+    1. An 'enable-method' property. Currently, the only supported value
+       for this field is the string "spin-table".
+
+    2. A 'cpu-release-addr' property identifying a 64-bit,
+       zero-initialised memory location.
+
+  It is expected that the bootloader will generate these device tree

Documentation/arm64/booting.txt line 146

Quoted 10 lines
Documentation/arm64/booting.txt new file +10 -0
+  properties and insert them into the blob prior to kernel entry.
+
+- Any secondary CPUs must spin outside of the kernel in a reserved area
+  of memory (communicated to the kernel by a /memreserve/ region in the
+  device tree) polling their cpu-release-addr location, which must be
+  contained in the reserved region.  A wfe instruction may be inserted
+  to reduce the overhead of the busy-loop and a sev will be issued by
+  the primary CPU.  When a read of the location pointed to by the
+  cpu-release-addr returns a non-zero value, the CPU must jump directly
+  to this value.

do you plan AMP boot?

Best Regards,
J.

#5 lore raw

Re: [PATCH v3 02/31] arm64: Kernel booting and initialisation

Quoted 14 lines · Jean-Christophe PLAGNIOL-VILLARD

Documentation/arm64/booting.txt line 77

Quoted 12 lines · Catalin Marinas

+4. Call the kernel image
+------------------------

Documentation/arm64/booting.txt new file +10 -0
+
+Requirement: MANDATORY
+
+The decompressed kernel image contains a 32-byte header as follows:
+
+  u32 magic	= 0x14000008;	/* branch to stext, little-endian */
+  u32 res0	= 0;		/* reserved */
+  u64 text_offset;		/* Image load offset */
+  u64 res1	= 0;		/* reserved */
+  u64 res2	= 0;		/* reserved */

we need to have a magic to known it's a arm64 kernel

You have it: it's 0x14000008 at the beginning.

Quoted 5 lines

Documentation/arm64/booting.txt line 81

Quoted 4 lines
Documentation/arm64/booting.txt new file +4 -0
+
+The image must be placed at the specified offset (currently 0x80000)
+from the start of the system RAM and called there. The start of the
+system RAM must be aligned to 2MB.

can we drop this

Drop what?
And why?

Nicolas

#6 lore raw

Re: [PATCH v3 02/31] arm64: Kernel booting and initialisation

Quoted 17 lines · Nicolas Pitre
Quoted 14 lines · Jean-Christophe PLAGNIOL-VILLARD

Documentation/arm64/booting.txt line 77

Quoted 12 lines · Catalin Marinas

+4. Call the kernel image
+------------------------

Documentation/arm64/booting.txt new file +10 -0
+
+Requirement: MANDATORY
+
+The decompressed kernel image contains a 32-byte header as follows:
+
+  u32 magic	= 0x14000008;	/* branch to stext, little-endian */
+  u32 res0	= 0;		/* reserved */
+  u64 text_offset;		/* Image load offset */
+  u64 res1	= 0;		/* reserved */
+  u64 res2	= 0;		/* reserved */

we need to have a magic to known it's a arm64 kernel

Quoted 1 line

You have it: it's 0x14000008 at the beginning.

fragile

Quoted 9 lines
Quoted 6 lines

Documentation/arm64/booting.txt line 81

Quoted 5 lines
Documentation/arm64/booting.txt new file +4 -0
+
+The image must be placed at the specified offset (currently 0x80000)
+from the start of the system RAM and called there. The start of the
+system RAM must be aligned to 2MB.

can we drop this

Drop what?
And why?

This contrain the must be loadable at any address

Best Regards,
J.

author maintainer
#7 lore raw

Re: [PATCH v3 02/31] arm64: Kernel booting and initialisation

Quoted 11 lines · Jean-Christophe PLAGNIOL-VILLARD
Quoted 9 lines · Nicolas Pitre
Quoted 5 lines · Jean-Christophe PLAGNIOL-VILLARD

Documentation/arm64/booting.txt line 81

Quoted 3 lines · Catalin Marinas
Documentation/arm64/booting.txt new file +3 -0
+The image must be placed at the specified offset (currently 0x80000)
+from the start of the system RAM and called there. The start of the
+system RAM must be aligned to 2MB.

can we drop this

Drop what?
And why?

This contrain the must be loadable at any address

You can't easily load the kernel image at any address, unless it can relocate itself and you have a way to specify PHYS_OFFSET. We don't want a compile-time PHYS_OFFSET, the kernel detects it at boot time based on the load address.

Signature · 1 line
Catalin
maintainer
#8 lore raw

Re: [PATCH v3 02/31] arm64: Kernel booting and initialisation

Quoted 9 lines · Catalin Marinas
Quoted 8 lines · Jean-Christophe PLAGNIOL-VILLARD
Quoted 7 lines · Nicolas Pitre
Quoted 5 lines · Jean-Christophe PLAGNIOL-VILLARD

Documentation/arm64/booting.txt line 81

Quoted 3 lines · Catalin Marinas
Documentation/arm64/booting.txt new file +3 -0
+The image must be placed at the specified offset (currently 0x80000)
+from the start of the system RAM and called there. The start of the
+system RAM must be aligned to 2MB.

can we drop this

Quoted 8 lines
Quoted 3 lines
Quoted 2 lines

Drop what?
And why?

This contrain the must be loadable at any address

You can't easily load the kernel image at any address, unless it can relocate itself and you have a way to specify PHYS_OFFSET. We don't want a compile-time PHYS_OFFSET, the kernel detects it at boot time based on the load address.

I think a bunch of other architectures can have relocatable kernels, which is useful e.g. for kdump. It does imply a small runtime cost and may have other disadvantages though.

Arnd

#9 lore raw

Re: [PATCH v3 02/31] arm64: Kernel booting and initialisation

Quoted 14 lines · Arnd Bergmann
Quoted 13 lines · Catalin Marinas
Quoted 11 lines · Jean-Christophe PLAGNIOL-VILLARD
Quoted 9 lines · Nicolas Pitre
Quoted 5 lines · Jean-Christophe PLAGNIOL-VILLARD

Documentation/arm64/booting.txt line 81

Quoted 3 lines · Catalin Marinas
Documentation/arm64/booting.txt new file +3 -0
+The image must be placed at the specified offset (currently 0x80000)
+from the start of the system RAM and called there. The start of the
+system RAM must be aligned to 2MB.

can we drop this

Drop what?
And why?

This contrain the must be loadable at any address

Quoted 8 lines
Quoted 4 lines

You can't easily load the kernel image at any address, unless it can relocate itself and you have a way to specify PHYS_OFFSET. We don't want a compile-time PHYS_OFFSET, the kernel detects it at boot time based on the load address.

I think a bunch of other architectures can have relocatable kernels, which is useful e.g. for kdump. It does imply a small runtime cost and may have other disadvantages though.

Relocatable in physical space is what kdump actually needs, and that's what we already have here (as well as on ARM32 for that matter with CONFIG_ARM_PATCH_PHYS_VIRT). Relocatable in the virtual space is costly and we shouldn't need to go there.

Nicolas

maintainer
#10 lore raw

Re: [PATCH v3 02/31] arm64: Kernel booting and initialisation

Quoted 11 lines · Nicolas Pitre
Quoted 5 lines · Arnd Bergmann
Quoted 1 line · Catalin Marinas

On Mon, Sep 10, 2012 at 06:53:39AM +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:

I think a bunch of other architectures can have relocatable kernels, which is useful e.g. for kdump. It does imply a small runtime cost and may have other disadvantages though.

Relocatable in physical space is what kdump actually needs, and that's what we already have here (as well as on ARM32 for that matter with CONFIG_ARM_PATCH_PHYS_VIRT). Relocatable in the virtual space is costly and we shouldn't need to go there.

Ah, I see. I thought that the other architectures (powerpc and x86) doing this were actually building with -fPIC, but they do the same kind of early patching that we do.

Arnd

author maintainer
#11 lore raw

Re: [PATCH v3 02/31] arm64: Kernel booting and initialisation

Quoted 8 lines · Arnd Bergmann
Quoted 7 lines · Nicolas Pitre
Quoted 5 lines · Arnd Bergmann
Quoted 1 line · Catalin Marinas

On Mon, Sep 10, 2012 at 06:53:39AM +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:

I think a bunch of other architectures can have relocatable kernels, which is useful e.g. for kdump. It does imply a small runtime cost and may have other disadvantages though.

Quoted 8 lines
Quoted 4 lines

Relocatable in physical space is what kdump actually needs, and that's what we already have here (as well as on ARM32 for that matter with CONFIG_ARM_PATCH_PHYS_VIRT). Relocatable in the virtual space is costly and we shouldn't need to go there.

Ah, I see. I thought that the other architectures (powerpc and x86) doing this were actually building with -fPIC, but they do the same kind of early patching that we do.

On arm64 I don't have run-time code patching (yet) but a PHYS_OFFSET variable set at boot time. It may prove useful to have run-time code patching but that's just an optimisation that can be added later.

Signature · 1 line
Catalin
#12 lore raw

Re: [PATCH v3 02/31] arm64: Kernel booting and initialisation

In reply to Arnd Bergmann
Quoted 8 lines · Arnd Bergmann
Quoted 7 lines · Nicolas Pitre
Quoted 5 lines · Arnd Bergmann
Quoted 1 line · Catalin Marinas

On Mon, Sep 10, 2012 at 06:53:39AM +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:

I think a bunch of other architectures can have relocatable kernels, which is useful e.g. for kdump. It does imply a small runtime cost and may have other disadvantages though.

Quoted 8 lines
Quoted 4 lines

Relocatable in physical space is what kdump actually needs, and that's what we already have here (as well as on ARM32 for that matter with CONFIG_ARM_PATCH_PHYS_VIRT). Relocatable in the virtual space is costly and we shouldn't need to go there.

Ah, I see. I thought that the other architectures (powerpc and x86) doing this were actually building with -fPIC, but they do the same kind of early patching that we do.

This being said, on ARM we don't take advantage of this physically relocatable attribute with kdump. Granted, PATCH_PHYS_VIRT was introduced after kdump support, therefore the kernel had to be copied at its expected physical location after the memory content there had been preserved. These days the only thing that kdump would need to do is to just boot the kdump kernel in place with its reserved memory range and let it ioremap the previous kernel's memory for analysis.

Nicolas

#13 lore raw

Re: [PATCH v3 02/31] arm64: Kernel booting and initialisation

In reply to Catalin Marinas
Quoted 9 lines · Catalin Marinas
Quoted 8 lines · Jean-Christophe PLAGNIOL-VILLARD
Quoted 7 lines · Nicolas Pitre
Quoted 5 lines · Jean-Christophe PLAGNIOL-VILLARD

Documentation/arm64/booting.txt line 81

Quoted 3 lines · Catalin Marinas
Documentation/arm64/booting.txt new file +3 -0
+The image must be placed at the specified offset (currently 0x80000)
+from the start of the system RAM and called there. The start of the
+system RAM must be aligned to 2MB.

can we drop this

Quoted 8 lines
Quoted 3 lines
Quoted 2 lines

Drop what?
And why?

This contrain the must be loadable at any address

You can't easily load the kernel image at any address, unless it can relocate itself and you have a way to specify PHYS_OFFSET. We don't want a compile-time PHYS_OFFSET, the kernel detects it at boot time based on the load address.

so NACK kexec and other boot loaders require it

Best Regards,
J.

author maintainer
#14 lore raw

Re: [PATCH v3 02/31] arm64: Kernel booting and initialisation

Quoted 12 lines · Jean-Christophe PLAGNIOL-VILLARD
Quoted 11 lines · Catalin Marinas
Quoted 10 lines · Jean-Christophe PLAGNIOL-VILLARD
Quoted 9 lines · Nicolas Pitre
Quoted 5 lines · Jean-Christophe PLAGNIOL-VILLARD

Documentation/arm64/booting.txt line 81

Quoted 3 lines · Catalin Marinas
Documentation/arm64/booting.txt new file +3 -0
+The image must be placed at the specified offset (currently 0x80000)
+from the start of the system RAM and called there. The start of the
+system RAM must be aligned to 2MB.

can we drop this

Drop what?
And why?

Quoted 7 lines
Quoted 6 lines
Quoted 1 line

This contrain the must be loadable at any address

You can't easily load the kernel image at any address, unless it can relocate itself and you have a way to specify PHYS_OFFSET. We don't want a compile-time PHYS_OFFSET, the kernel detects it at boot time based on the load address.

so NACK kexec and other boot loaders require it

Just in case it wasn't clear, the kernel can be loaded at any address in RAM (and the RAM can start at any sane address). The way the kernel calculates PHYS_OFFSET is (load address - TEXT_OFFSET) unless we pass it by other means (none currently specified). For a kdump kernel, it just assumes that its PHYS_OFFSET is higher but it can ioremap the crashed kernel memory.

Signature · 1 line
Catalin
#15 lore raw

Re: [PATCH v3 02/31] arm64: Kernel booting and initialisation

In reply to Jean-Christophe PLAGNIOL-VILLARD
Quoted 12 lines · Jean-Christophe PLAGNIOL-VILLARD
Quoted 11 lines · Catalin Marinas
Quoted 10 lines · Jean-Christophe PLAGNIOL-VILLARD
Quoted 9 lines · Nicolas Pitre
Quoted 5 lines · Jean-Christophe PLAGNIOL-VILLARD

Documentation/arm64/booting.txt line 81

Quoted 3 lines · Catalin Marinas
Documentation/arm64/booting.txt new file +3 -0
+The image must be placed at the specified offset (currently 0x80000)
+from the start of the system RAM and called there. The start of the
+system RAM must be aligned to 2MB.

can we drop this

Drop what?
And why?

Quoted 7 lines
Quoted 6 lines
Quoted 1 line

This contrain the must be loadable at any address

You can't easily load the kernel image at any address, unless it can relocate itself and you have a way to specify PHYS_OFFSET. We don't want a compile-time PHYS_OFFSET, the kernel detects it at boot time based on the load address.

so NACK kexec and other boot loaders require it

I think you might have misunderstood something.

What's there now is perfectly sane.

SO I must NACK your NACK. :-)

Nicolas

#16 lore raw

Re: [PATCH v3 02/31] arm64: Kernel booting and initialisation

In reply to Jean-Christophe PLAGNIOL-VILLARD
Quoted 18 lines · Jean-Christophe PLAGNIOL-VILLARD
Quoted 17 lines · Nicolas Pitre
Quoted 14 lines · Jean-Christophe PLAGNIOL-VILLARD

Documentation/arm64/booting.txt line 77

Quoted 12 lines · Catalin Marinas

+4. Call the kernel image
+------------------------

Documentation/arm64/booting.txt new file +10 -0
+
+Requirement: MANDATORY
+
+The decompressed kernel image contains a 32-byte header as follows:
+
+  u32 magic	= 0x14000008;	/* branch to stext, little-endian */
+  u32 res0	= 0;		/* reserved */
+  u64 text_offset;		/* Image load offset */
+  u64 res1	= 0;		/* reserved */
+  u64 res2	= 0;		/* reserved */

we need to have a magic to known it's a arm64 kernel

Quoted 2 lines
Quoted 1 line

You have it: it's 0x14000008 at the beginning.

fragile

Others have commented on the relocatable kernel non-issue. But to this part, also bear in mind that Catalin pointed out boot standardization work may change how some AArch64 systems ultimately end up booting.

Thanks,

Jon.

author maintainer
#17 lore raw

Re: [PATCH v3 02/31] arm64: Kernel booting and initialisation

In reply to Jean-Christophe PLAGNIOL-VILLARD
Quoted 6 lines · Jean-Christophe PLAGNIOL-VILLARD

Documentation/arm64/booting.txt line 51

Quoted 4 lines · Catalin Marinas
Documentation/arm64/booting.txt new file +4 -0
+The device tree blob (dtb) must be no bigger than 2 megabytes in size
+and placed at a 2-megabyte boundary within the first 512 megabytes from
+the start of the kernel image. This is to allow the kernel to map the
+blob using a single section mapping in the initial page tables.

why do you want to restrict the DT to be less tahn 2MiB?

That's a restriction due on the initial memory map. At some point we may add support in head.S to parse the dtb and extract the size information. Not critical at this stage.

Quoted 21 lines
Quoted 21 lines
Documentation/arm64/booting.txt new file +21 -0
+Before jumping into the kernel, the following conditions must be met:
+
+- Quiesce all DMA capable devices so that memory does not get
+  corrupted by bogus network packets or disk data.  This will save
+  you many hours of debug.
+
+- Primary CPU general-purpose register settings
+  x0 = physical address of device tree blob (dtb) in system RAM.
+  x1 = 0 (reserved for future use)
+  x2 = 0 (reserved for future use)
+  x3 = 0 (reserved for future use)
+
+- CPU mode
+  All forms of interrupts must be masked in PSTATE.DAIF (Debug, SError,
+  IRQ and FIQ).
+  The CPU must be in either EL2 (RECOMMENDED in order to have access to
+  the virtualisation extensions) or non-secure EL1.
+
+- Caches, MMUs
+  The MMU must be off.
+  Instruction cache may be on or off.
Quoted 8 lines

Documentation/arm64/booting.txt line 110

Quoted 7 lines
Documentation/arm64/booting.txt new file +7 -0
+  Data cache must be off and invalidated.
+  External caches (if present) must be configured and disabled.
+
+- Architected timers
+  CNTFRQ must be programmed with the timer frequency.
+  If entering the kernel at EL1, CNTHCTL_EL2 must have EL1PCTEN (bit 0)
+  set where available.

can you explain why?

Otherwise the kernel cannot access the generic timer registers (it is described in the AArch64 exception model which isn't public yet).

Quoted 14 lines
Quoted 14 lines

+- The primary CPU must jump directly to the first instruction of the

Documentation/arm64/booting.txt new file +13 -0
+  kernel image.  The device tree blob passed by this CPU must contain
+  for each CPU node:
+
+    1. An 'enable-method' property. Currently, the only supported value
+       for this field is the string "spin-table".
+
+    2. A 'cpu-release-addr' property identifying a 64-bit,
+       zero-initialised memory location.
+
+  It is expected that the bootloader will generate these device tree
+  properties and insert them into the blob prior to kernel entry.
+
+- Any secondary CPUs must spin outside of the kernel in a reserved area
Quoted 8 lines

Documentation/arm64/booting.txt line 146

Quoted 7 lines
Documentation/arm64/booting.txt new file +7 -0
+  of memory (communicated to the kernel by a /memreserve/ region in the
+  device tree) polling their cpu-release-addr location, which must be
+  contained in the reserved region.  A wfe instruction may be inserted
+  to reduce the overhead of the busy-loop and a sev will be issued by
+  the primary CPU.  When a read of the location pointed to by the
+  cpu-release-addr returns a non-zero value, the CPU must jump directly
+  to this value.

do you plan AMP boot?

What do you mean by AMP?

If you only want to use 3 CPUs out of 4 for example, you change the FDT information that gets passed to the kernel accordingly. So the kernel wouldn't touch the 4th one.

Signature · 1 line
Catalin
#18 lore raw

Re: [PATCH v3 02/31] arm64: Kernel booting and initialisation

Quoted 42 lines · Catalin Marinas
Quoted 6 lines · Jean-Christophe PLAGNIOL-VILLARD

Documentation/arm64/booting.txt line 51

Quoted 4 lines · Catalin Marinas
Documentation/arm64/booting.txt new file +4 -0
+The device tree blob (dtb) must be no bigger than 2 megabytes in size
+and placed at a 2-megabyte boundary within the first 512 megabytes from
+the start of the kernel image. This is to allow the kernel to map the
+blob using a single section mapping in the initial page tables.

why do you want to restrict the DT to be less tahn 2MiB?

That's a restriction due on the initial memory map. At some point we may add support in head.S to parse the dtb and extract the size information. Not critical at this stage.

Quoted 21 lines
Quoted 21 lines
Documentation/arm64/booting.txt new file +21 -0
+Before jumping into the kernel, the following conditions must be met:
+
+- Quiesce all DMA capable devices so that memory does not get
+  corrupted by bogus network packets or disk data.  This will save
+  you many hours of debug.
+
+- Primary CPU general-purpose register settings
+  x0 = physical address of device tree blob (dtb) in system RAM.
+  x1 = 0 (reserved for future use)
+  x2 = 0 (reserved for future use)
+  x3 = 0 (reserved for future use)
+
+- CPU mode
+  All forms of interrupts must be masked in PSTATE.DAIF (Debug, SError,
+  IRQ and FIQ).
+  The CPU must be in either EL2 (RECOMMENDED in order to have access to
+  the virtualisation extensions) or non-secure EL1.
+
+- Caches, MMUs
+  The MMU must be off.
+  Instruction cache may be on or off.
Quoted 8 lines

Documentation/arm64/booting.txt line 110

Quoted 7 lines
Documentation/arm64/booting.txt new file +7 -0
+  Data cache must be off and invalidated.
+  External caches (if present) must be configured and disabled.
+
+- Architected timers
+  CNTFRQ must be programmed with the timer frequency.
+  If entering the kernel at EL1, CNTHCTL_EL2 must have EL1PCTEN (bit 0)
+  set where available.

can you explain why?

Quoted 2 lines

Otherwise the kernel cannot access the generic timer registers (it is described in the AArch64 exception model which isn't public yet).

I do not like the idea to do too much in the boot loader

can we drop it and do it the head.S or find an other way

Quoted 24 lines
Quoted 15 lines
Quoted 15 lines

+- The primary CPU must jump directly to the first instruction of the

Documentation/arm64/booting.txt new file +13 -0
+  kernel image.  The device tree blob passed by this CPU must contain
+  for each CPU node:
+
+    1. An 'enable-method' property. Currently, the only supported value
+       for this field is the string "spin-table".
+
+    2. A 'cpu-release-addr' property identifying a 64-bit,
+       zero-initialised memory location.
+
+  It is expected that the bootloader will generate these device tree
+  properties and insert them into the blob prior to kernel entry.
+
+- Any secondary CPUs must spin outside of the kernel in a reserved area
Quoted 8 lines

Documentation/arm64/booting.txt line 146

Quoted 7 lines
Documentation/arm64/booting.txt new file +7 -0
+  of memory (communicated to the kernel by a /memreserve/ region in the
+  device tree) polling their cpu-release-addr location, which must be
+  contained in the reserved region.  A wfe instruction may be inserted
+  to reduce the overhead of the busy-loop and a sev will be issued by
+  the primary CPU.  When a read of the location pointed to by the
+  cpu-release-addr returns a non-zero value, the CPU must jump directly
+  to this value.

do you plan AMP boot?

Quoted 5 lines

What do you mean by AMP?

If you only want to use 3 CPUs out of 4 for example, you change the FDT information that gets passed to the kernel accordingly. So the kernel wouldn't touch the 4th one.

I mean boot a different kernel in each core as example

Best Regards,
J.

author maintainer
#19 lore raw

Re: [PATCH v3 02/31] arm64: Kernel booting and initialisation

Quoted 33 lines · Jean-Christophe PLAGNIOL-VILLARD
Quoted 32 lines · Catalin Marinas
Quoted 30 lines · Jean-Christophe PLAGNIOL-VILLARD
Quoted 18 lines · Catalin Marinas
Documentation/arm64/booting.txt new file +18 -0
+Before jumping into the kernel, the following conditions must be met:
+
+- Quiesce all DMA capable devices so that memory does not get
+  corrupted by bogus network packets or disk data.  This will save
+  you many hours of debug.
+
+- Primary CPU general-purpose register settings
+  x0 = physical address of device tree blob (dtb) in system RAM.
+  x1 = 0 (reserved for future use)
+  x2 = 0 (reserved for future use)
+  x3 = 0 (reserved for future use)
+
+- CPU mode
+  All forms of interrupts must be masked in PSTATE.DAIF (Debug, SError,
+  IRQ and FIQ).
+  The CPU must be in either EL2 (RECOMMENDED in order to have access to
+  the virtualisation extensions) or non-secure EL1.
+

Documentation/arm64/booting.txt line 110

Quoted 10 lines
Documentation/arm64/booting.txt new file +10 -0
+- Caches, MMUs
+  The MMU must be off.
+  Instruction cache may be on or off.
+  Data cache must be off and invalidated.
+  External caches (if present) must be configured and disabled.
+
+- Architected timers
+  CNTFRQ must be programmed with the timer frequency.
+  If entering the kernel at EL1, CNTHCTL_EL2 must have EL1PCTEN (bit 0)
+  set where available.

can you explain why?

Quoted 5 lines
Quoted 2 lines

Otherwise the kernel cannot access the generic timer registers (it is described in the AArch64 exception model which isn't public yet).

I do not like the idea to do too much in the boot loader

can we drop it and do it the head.S or find an other way

No. The kernel expects some sane setup before it can start. That's the case already on AArch32. With AArch64 we also mandate single Image from start. You can have a look at an example boot wrapper that creates an environment for the AArch64 kernel:

git://git.kernel.org/pub/scm/linux/kernel/git/cmarinas/boot-wrapper-aarch64.git

Quoted 23 lines
Quoted 23 lines
Quoted 22 lines
Quoted 11 lines

+- The primary CPU must jump directly to the first instruction of the

Documentation/arm64/booting.txt new file +10 -0
+  kernel image.  The device tree blob passed by this CPU must contain
+  for each CPU node:
+
+    1. An 'enable-method' property. Currently, the only supported value
+       for this field is the string "spin-table".
+
+    2. A 'cpu-release-addr' property identifying a 64-bit,
+       zero-initialised memory location.
+
+  It is expected that the bootloader will generate these device tree

Documentation/arm64/booting.txt line 146

Quoted 10 lines
Documentation/arm64/booting.txt new file +10 -0
+  properties and insert them into the blob prior to kernel entry.
+
+- Any secondary CPUs must spin outside of the kernel in a reserved area
+  of memory (communicated to the kernel by a /memreserve/ region in the
+  device tree) polling their cpu-release-addr location, which must be
+  contained in the reserved region.  A wfe instruction may be inserted
+  to reduce the overhead of the busy-loop and a sev will be issued by
+  the primary CPU.  When a read of the location pointed to by the
+  cpu-release-addr returns a non-zero value, the CPU must jump directly
+  to this value.

do you plan AMP boot?

Quoted 6 lines
Quoted 5 lines

What do you mean by AMP?

If you only want to use 3 CPUs out of 4 for example, you change the FDT information that gets passed to the kernel accordingly. So the kernel wouldn't touch the 4th one.

I mean boot a different kernel in each core as example

That's not on my plan. It may be doable but I don't see any need for it.

Signature · 1 line
Catalin
#20 lore raw

Re: [PATCH v3 02/31] arm64: Kernel booting and initialisation

Hi Catalin and Will,

Quoted 34 lines · Catalin Marinas
Quoted 33 lines · Jean-Christophe PLAGNIOL-VILLARD
Quoted 32 lines · Catalin Marinas
Quoted 30 lines · Jean-Christophe PLAGNIOL-VILLARD
Quoted 18 lines · Catalin Marinas
Documentation/arm64/booting.txt new file +18 -0
+Before jumping into the kernel, the following conditions must be met:
+
+- Quiesce all DMA capable devices so that memory does not get
+  corrupted by bogus network packets or disk data.  This will save
+  you many hours of debug.
+
+- Primary CPU general-purpose register settings
+  x0 = physical address of device tree blob (dtb) in system RAM.
+  x1 = 0 (reserved for future use)
+  x2 = 0 (reserved for future use)
+  x3 = 0 (reserved for future use)
+
+- CPU mode
+  All forms of interrupts must be masked in PSTATE.DAIF (Debug, SError,
+  IRQ and FIQ).
+  The CPU must be in either EL2 (RECOMMENDED in order to have access to
+  the virtualisation extensions) or non-secure EL1.
+

Documentation/arm64/booting.txt line 110

Quoted 10 lines
Documentation/arm64/booting.txt new file +10 -0
+- Caches, MMUs
+  The MMU must be off.
+  Instruction cache may be on or off.
+  Data cache must be off and invalidated.
+  External caches (if present) must be configured and disabled.
+
+- Architected timers
+  CNTFRQ must be programmed with the timer frequency.
+  If entering the kernel at EL1, CNTHCTL_EL2 must have EL1PCTEN (bit 0)
+  set where available.

can you explain why?

Quoted 3 lines
Quoted 3 lines
Quoted 2 lines

Otherwise the kernel cannot access the generic timer registers (it is described in the AArch64 exception model which isn't public yet).

I do not like the idea to do too much in the boot loader

I agree that where possible we should minimize the amount of work required of bootloaders. I'm not sure that the percentage of work we might be able to trim away on hardware would be significant, but on simulators I think we might be able to get to the point where, if you can specify the r0 reset value to be the dtb pointer, you can just load a devicetree blob and kernel image into memory and start executing the kernel, no boot wrapper required.

I don't know if Jean-Christophe was commenting on just the EL1PCTEN bit or also the CNTFRQ register, but with regard to the latter, it appears to me that the timer code actually reads the frequency primarily from the devicetree and only reads CNTFRQ if the "clock-frequency" property is unspecified or specified as zero.

I suggest that the kernel calling requirements be modified to communicate this fallback, rather than mandatory, status, unless some not-yet-released part of the arm64 kernel needs it. If userspace code will need to use CNTFRQ at some point then perhaps that should be mentioned in an informational note rather than being presented as a kernel booting requirement.

Quoted 1 line

git://git.kernel.org/pub/scm/linux/kernel/git/cmarinas/boot-wrapper-aarch64.git

The UART and GIC stuff is board-specific, and I don't currently have any suggestions about the multicore initialization, but would you object to the kernel eventually being equipped to make the descent from EL3 itself?

Thanks,
Christopher

Signature · 3 lines
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by
the Linux Foundation
author maintainer
#21 lore raw

Re: [PATCH v3 02/31] arm64: Kernel booting and initialisation

Quoted 37 lines · Christopher Covington
Quoted 36 lines · Catalin Marinas
Quoted 35 lines · Jean-Christophe PLAGNIOL-VILLARD
Quoted 34 lines · Catalin Marinas
Quoted 22 lines · Jean-Christophe PLAGNIOL-VILLARD
Quoted 21 lines · Catalin Marinas
Documentation/arm64/booting.txt new file +21 -0
+Before jumping into the kernel, the following conditions must be met:
+
+- Quiesce all DMA capable devices so that memory does not get
+  corrupted by bogus network packets or disk data.  This will save
+  you many hours of debug.
+
+- Primary CPU general-purpose register settings
+  x0 = physical address of device tree blob (dtb) in system RAM.
+  x1 = 0 (reserved for future use)
+  x2 = 0 (reserved for future use)
+  x3 = 0 (reserved for future use)
+
+- CPU mode
+  All forms of interrupts must be masked in PSTATE.DAIF (Debug, SError,
+  IRQ and FIQ).
+  The CPU must be in either EL2 (RECOMMENDED in order to have access to
+  the virtualisation extensions) or non-secure EL1.
+
+- Caches, MMUs
+  The MMU must be off.
+  Instruction cache may be on or off.
Quoted 8 lines

Documentation/arm64/booting.txt line 110

Quoted 7 lines
Documentation/arm64/booting.txt new file +7 -0
+  Data cache must be off and invalidated.
+  External caches (if present) must be configured and disabled.
+
+- Architected timers
+  CNTFRQ must be programmed with the timer frequency.
+  If entering the kernel at EL1, CNTHCTL_EL2 must have EL1PCTEN (bit 0)
+  set where available.

can you explain why?

Otherwise the kernel cannot access the generic timer registers (it is described in the AArch64 exception model which isn't public yet).

Quoted 8 lines
Quoted 1 line
Quoted 1 line

I do not like the idea to do too much in the boot loader

I agree that where possible we should minimize the amount of work required of bootloaders. I'm not sure that the percentage of work we might be able to trim away on hardware would be significant, but on simulators I think we might be able to get to the point where, if you can specify the r0 reset value to be the dtb pointer, you can just load a devicetree blob and kernel image into memory and start executing the kernel, no boot wrapper required.

The boot wrapper is *only* required on our software model because this model does not have any firmware and it simply starts at EL3. We do not have this behaviour on real hardware where there is firmware to initialise the hardware, memory controller, secure world etc. before a normal boot loader can be loaded. Many of the requirements would be part of the board firmware rather than boot loader, so the boot loader would just need to deal with the usual cache maintenance and turning the MMU off.

The conditions above are not really much in addition to what we require on 32-bit.

Quoted 1 line

I don't know if Jean-Christophe was commenting on just the EL1PCTEN bit or

The EL1PCTEN requirement is pretty clearly described above - only if Linux is started at EL1 (e.g. guest OS), since the CNTHCTL_EL2 register is an EL2 only register and not accessible at EL1.

Quoted 4 lines

also the CNTFRQ register, but with regard to the latter, it appears to me that the timer code actually reads the frequency primarily from the devicetree and only reads CNTFRQ if the "clock-frequency" property is unspecified or specified as zero.

Linus W has a few more suggestions here but I didn't get to implementing them.

Quoted 5 lines

I suggest that the kernel calling requirements be modified to communicate this fallback, rather than mandatory, status, unless some not-yet-released part of the arm64 kernel needs it. If userspace code will need to use CNTFRQ at some point then perhaps that should be mentioned in an informational note rather than being presented as a kernel booting requirement.

In general, we would like the firmware to write the correct value into the CNTFRQ register, as specified in the generic timers spec, or maybe hard-wire the register to the correct value. However, in case some firmware gets it wrong or a read-only register is not hard-wired we want to override the value with the FDT. A historical reason for this was that the software model we use doesn't have any firmware. But primarily we should use the hardware value.

So far we don't export the CNTFRQ to user because of the possibility to override the value via other means. That's pretty much a read-only or EL3 writable only register.

Quoted 5 lines
Quoted 1 line

git://git.kernel.org/pub/scm/linux/kernel/git/cmarinas/boot-wrapper-aarch64.git

The UART and GIC stuff is board-specific, and I don't currently have any suggestions about the multicore initialization, but would you object to the kernel eventually being equipped to make the descent from EL3 itself?

I'm strongly pushing for single Image support from the beginning and this would require a few things to be initialised by the firmware (on a case by case basis). The secondary CPU release also needs to be handled by the firmware.

For example, in a standard system you would want to run the kernel in non-secure mode to make use of the virtualisation extensions. The GIC (address depending on the SoC) would need to be configured to enable interrupts for the non-secure world and this can only be done in secure mode. So even if you start the kernel at EL3 and shortly drop to EL2/EL1, for the single Image to work you need such GIC initialisation to be done by the firmware.

While the requirement to have some hardware pre-initialisation does not necessarily mandate the mode in which Linux is started, I don't see value in starting Linux at EL3. You most likely will have some boot loader and we don't want to add extra complexity to them for running in different modes or having to switch back to the highest mode before calling the kernel. The boot loader already needs to handle EL1 and EL2.

ARM is also proposing an SMC API to make secondary startup and a few power management things simpler from a Linux perspective. Such code would reside at EL3.

Signature · 1 line
Catalin
author maintainer
#22 lore raw

PATCH v3 3/31 arm64: Exception handling

In reply to Catalin Marinas

The patch contains the exception entry code (kernel/entry.S), pt_regs structure and related accessors, undefined instruction trapping and stack tracing.

AArch64 Linux kernel (including kernel threads) runs in EL1 mode using the SP1 stack. The vectors don't have a fixed address, only alignment (2^11) requirements.

---
 arch/arm64/include/asm/ptrace.h     |  212 +++++++++++
 arch/arm64/include/asm/stacktrace.h |   29 ++
 arch/arm64/include/asm/traps.h      |   30 ++
 arch/arm64/kernel/entry.S           |  695 +++++++++++++++++++++++++++++++++++
 arch/arm64/kernel/stacktrace.c      |  127 +++++++
 arch/arm64/kernel/traps.c           |  348 ++++++++++++++++++
 6 files changed, 1441 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm64/include/asm/ptrace.h
 create mode 100644 arch/arm64/include/asm/stacktrace.h
 create mode 100644 arch/arm64/include/asm/traps.h
 create mode 100644 arch/arm64/kernel/entry.S
 create mode 100644 arch/arm64/kernel/stacktrace.c
 create mode 100644 arch/arm64/kernel/traps.c
arch/arm64/include/asm/ptrace.h new file +212 -0
new file mode 100644
index 0000000..b0a2e1f
@@ -0,0 +1,212 @@
+/*
+ * Based on arch/arm/include/asm/ptrace.h
+ *
+ * Copyright (C) 1996-2003 Russell King
+ * Copyright (C) 2012 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_PTRACE_H
+#define __ASM_PTRACE_H
+
+#include <linux/types.h>
+
+#include <asm/hwcap.h>
+
+#define PTRACE_GETREGS		12
+#define PTRACE_SETREGS		13
+#define PTRACE_GETFPSIMDREGS	14
+#define PTRACE_SETFPSIMDREGS	15
+/* PTRACE_ATTACH is 16 */
+/* PTRACE_DETACH is 17 */
+#define PTRACE_GET_THREAD_AREA	22
+#define PTRACE_SET_SYSCALL	23
+#define PTRACE_GETHBPREGS	29
+#define PTRACE_SETHBPREGS	30
+
+/* AArch32-specific ptrace requests */
+#define COMPAT_PTRACE_GETVFPREGS	27
+#define COMPAT_PTRACE_SETVFPREGS	28
+
+/*
+ * PSR bits
+ */
+#define PSR_MODE_EL0t	0x00000000
+#define PSR_MODE_EL1t	0x00000004
+#define PSR_MODE_EL1h	0x00000005
+#define PSR_MODE_EL2t	0x00000008
+#define PSR_MODE_EL2h	0x00000009
+#define PSR_MODE_EL3t	0x0000000c
+#define PSR_MODE_EL3h	0x0000000d
+#define PSR_MODE_MASK	0x0000000f
+
+/* AArch32 CPSR bits */
+#define PSR_MODE32_BIT		0x00000010
+#define COMPAT_PSR_MODE_USR	0x00000010
+#define COMPAT_PSR_T_BIT	0x00000020
+#define COMPAT_PSR_IT_MASK	0x0600fc00	/* If-Then execution state mask */
+
+/* AArch64 SPSR bits */
+#define PSR_F_BIT	0x00000040
+#define PSR_I_BIT	0x00000080
+#define PSR_A_BIT	0x00000100
+#define PSR_D_BIT	0x00000200
+#define PSR_Q_BIT	0x08000000
+#define PSR_V_BIT	0x10000000
+#define PSR_C_BIT	0x20000000
+#define PSR_Z_BIT	0x40000000
+#define PSR_N_BIT	0x80000000
+
+/*
+ * Groups of PSR bits
+ */
+#define PSR_f		0xff000000	/* Flags		*/
+#define PSR_s		0x00ff0000	/* Status		*/
+#define PSR_x		0x0000ff00	/* Extension		*/
+#define PSR_c		0x000000ff	/* Control		*/
+
+/*
+ * These are 'magic' values for PTRACE_PEEKUSR that return info about where a
+ * process is located in memory.
+ */
+#define PT_TEXT_ADDR		0x10000
+#define PT_DATA_ADDR		0x10004
+#define PT_TEXT_END_ADDR	0x10008
+
+#ifndef __ASSEMBLY__
+
+/*
+ * User structures for general purpose, floating point and debug registers.
+ */
+struct user_pt_regs {
+	__u64		regs[31];
+	__u64		sp;
+	__u64		pc;
+	__u64		pstate;
+};
+
+struct user_fpsimd_state {
+	__uint128_t	vregs[32];
+	__u32		fpsr;
+	__u32		fpcr;
+};
+
+struct user_hwdebug_state {
+	__u32		dbg_info;
+	struct {
+		__u64	addr;
+		__u32	ctrl;
+	}		dbg_regs[16];
+};
+
+#ifdef __KERNEL__
+
+/* sizeof(struct user) for AArch32 */
+#define COMPAT_USER_SZ	296
+/* AArch32 uses x13 as the stack pointer... */
+#define compat_sp	regs[13]
+/* ... and x14 as the link register. */
+#define compat_lr	regs[14]
+
+/*
+ * This struct defines the way the registers are stored on the stack during an
+ * exception. Note that sizeof(struct pt_regs) has to be a multiple of 16 (for
+ * stack alignment). struct user_pt_regs must form a prefix of struct pt_regs.
+ */
+struct pt_regs {
+	union {
+		struct user_pt_regs user_regs;
+		struct {
+			u64 regs[31];
+			u64 sp;
+			u64 pc;
+			u64 pstate;
+		};
+	};
+	u64 orig_x0;
+	u64 syscallno;
+};
+
+#define arch_has_single_step()	(1)
+
+#ifdef CONFIG_COMPAT
+#define compat_thumb_mode(regs) \
+	(((regs)->pstate & COMPAT_PSR_T_BIT))
+#else
+#define compat_thumb_mode(regs) (0)
+#endif
+
+#define user_mode(regs)	\
+	(((regs)->pstate & PSR_MODE_MASK) == PSR_MODE_EL0t)
+
+#define compat_user_mode(regs)	\
+	(((regs)->pstate & (PSR_MODE32_BIT | PSR_MODE_MASK)) == \
+	 (PSR_MODE32_BIT | PSR_MODE_EL0t))
+
+#define processor_mode(regs) \
+	((regs)->pstate & PSR_MODE_MASK)
+
+#define interrupts_enabled(regs) \
+	(!((regs)->pstate & PSR_I_BIT))
+
+#define fast_interrupts_enabled(regs) \
+	(!((regs)->pstate & PSR_F_BIT))
+
+#define user_stack_pointer(regs) \
+	((regs)->sp)
+
+/*
+ * Are the current registers suitable for user mode? (used to maintain
+ * security in signal handlers)
+ */
+static inline int valid_user_regs(struct user_pt_regs *regs)
+{
+	if (user_mode(regs) && (regs->pstate & PSR_I_BIT) == 0) {
+		regs->pstate &= ~(PSR_F_BIT | PSR_A_BIT);
+
+		/* The T bit is reserved for AArch64 */
+		if (!(regs->pstate & PSR_MODE32_BIT))
+			regs->pstate &= ~COMPAT_PSR_T_BIT;
+
+		return 1;
+	}
+
+	/*
+	 * Force PSR to something logical...
+	 */
+	regs->pstate &= PSR_f | PSR_s | (PSR_x & ~PSR_A_BIT) | \
+			COMPAT_PSR_T_BIT | PSR_MODE32_BIT;
+
+	if (!(regs->pstate & PSR_MODE32_BIT)) {
+		regs->pstate &= ~COMPAT_PSR_T_BIT;
+		regs->pstate |= PSR_MODE_EL0t;
+	}
+
+	return 0;
+}
+
+#define instruction_pointer(regs)	(regs)->pc
+
+#ifdef CONFIG_SMP
+extern unsigned long profile_pc(struct pt_regs *regs);
+#else
+#define profile_pc(regs) instruction_pointer(regs)
+#endif
+
+extern int aarch32_break_trap(struct pt_regs *regs);
+
+#endif /* __KERNEL__ */
+
+#endif /* __ASSEMBLY__ */
+
+#endif
arch/arm64/include/asm/stacktrace.h new file +29 -0
new file mode 100644
index 0000000..7318f6d
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2012 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_STACKTRACE_H
+#define __ASM_STACKTRACE_H
+
+struct stackframe {
+	unsigned long fp;
+	unsigned long sp;
+	unsigned long pc;
+};
+
+extern int unwind_frame(struct stackframe *frame);
+extern void walk_stackframe(struct stackframe *frame,
+			    int (*fn)(struct stackframe *, void *), void *data);
+
+#endif	/* __ASM_STACKTRACE_H */
arch/arm64/include/asm/traps.h new file +30 -0
new file mode 100644
index 0000000..10ca8ff
@@ -0,0 +1,30 @@
+/*
+ * Based on arch/arm/include/asm/traps.h
+ *
+ * Copyright (C) 2012 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_TRAP_H
+#define __ASM_TRAP_H
+
+static inline int in_exception_text(unsigned long ptr)
+{
+	extern char __exception_text_start[];
+	extern char __exception_text_end[];
+
+	return ptr >= (unsigned long)&__exception_text_start &&
+	       ptr < (unsigned long)&__exception_text_end;
+}
+
+#endif
arch/arm64/kernel/entry.S new file +695 -0

695 lines not on this page · raw message

arch/arm64/kernel/stacktrace.c new file +127 -0

127 lines not on this page · raw message

arch/arm64/kernel/traps.c new file +348 -0

348 lines not on this page · raw message

maintainer Acked-by on v3 3/31
#23 lore raw

Re: [PATCH v3 03/31] arm64: Exception handling

Quoted 11 lines · Catalin Marinas

The patch contains the exception entry code (kernel/entry.S), pt_regs structure and related accessors, undefined instruction trapping and stack tracing.

AArch64 Linux kernel (including kernel threads) runs in EL1 mode using the SP1 stack. The vectors don't have a fixed address, only alignment (2^11) requirements.

author maintainer
#24 lore raw

PATCH v3 4/31 arm64: MMU definitions

In reply to Catalin Marinas

The virtual memory layout is described in Documentation/arm64/memory.txt. This patch adds the MMU definitions for the 4KB and 64KB translation table configurations. The SECTION_SIZE is 2MB with 4KB page and 512MB with 64KB page configuration.

PHYS_OFFSET is calculated at run-time and stored in a variable (no run-time code patching at this stage).

On the current implementation, both user and kernel address spaces are 512G (39-bit) each with a maximum of 256G for the RAM linear mapping. Linux uses 3 levels of translation tables with the 4K page configuration and 2 levels with the 64K configuration. Extending the memory space beyond 39-bit with the 4K pages or 42-bit with 64K pages requires an additional level of translation tables.

The SPARSEMEM configuration is global to all AArch64 platforms and allows for 1GB sections with SPARSEMEM_VMEMMAP enabled by default.

---
 Documentation/arm64/memory.txt                |   69 +++++
 arch/arm64/include/asm/memory.h               |  144 +++++++++++
 arch/arm64/include/asm/mmu.h                  |   27 ++
 arch/arm64/include/asm/pgtable-2level-hwdef.h |   43 ++++
 arch/arm64/include/asm/pgtable-2level-types.h |   60 +++++
 arch/arm64/include/asm/pgtable-3level-hwdef.h |   50 ++++
 arch/arm64/include/asm/pgtable-3level-types.h |   66 +++++
 arch/arm64/include/asm/pgtable-hwdef.h        |   94 +++++++
 arch/arm64/include/asm/pgtable.h              |  328 +++++++++++++++++++++++++
 arch/arm64/include/asm/sparsemem.h            |   24 ++
 10 files changed, 905 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/arm64/memory.txt
 create mode 100644 arch/arm64/include/asm/memory.h
 create mode 100644 arch/arm64/include/asm/mmu.h
 create mode 100644 arch/arm64/include/asm/pgtable-2level-hwdef.h
 create mode 100644 arch/arm64/include/asm/pgtable-2level-types.h
 create mode 100644 arch/arm64/include/asm/pgtable-3level-hwdef.h
 create mode 100644 arch/arm64/include/asm/pgtable-3level-types.h
 create mode 100644 arch/arm64/include/asm/pgtable-hwdef.h
 create mode 100644 arch/arm64/include/asm/pgtable.h
 create mode 100644 arch/arm64/include/asm/sparsemem.h
Documentation/arm64/memory.txt new file +69 -0
new file mode 100644
index 0000000..7210af7
@@ -0,0 +1,69 @@
+		     Memory Layout on AArch64 Linux
+		     ==============================
+
+Author: Catalin Marinas <[email protected]>
+Date  : 20 February 2012
+
+This document describes the virtual memory layout used by the AArch64
+Linux kernel. The architecture allows up to 4 levels of translation
+tables with a 4KB page size and up to 3 levels with a 64KB page size.
+
+AArch64 Linux uses 3 levels of translation tables with the 4KB page
+configuration, allowing 39-bit (512GB) virtual addresses for both user
+and kernel. With 64KB pages, only 2 levels of translation tables are
+used but the memory layout is the same.
+
+User addresses have bits 63:39 set to 0 while the kernel addresses have
+the same bits set to 1. TTBRx selection is given by bit 63 of the
+virtual address. The swapper_pg_dir contains only kernel (global)
+mappings while the user pgd contains only user (non-global) mappings.
+The swapper_pgd_dir address is written to TTBR1 and never written to
+TTBR0.
+
+
+AArch64 Linux memory layout:
+
+Start			End			Size		Use
+-----------------------------------------------------------------------
+0000000000000000	0000007fffffffff	 512GB		user
+
+ffffff8000000000	ffffffbbfffeffff	~240GB		vmalloc
+
+ffffffbbffff0000	ffffffbcffffffff	  64KB		[guard page]
+
+ffffffbc00000000	ffffffbdffffffff	   8GB		vmemmap
+
+ffffffbe00000000	ffffffbffbffffff	  ~8GB		[guard, future vmmemap]
+
+ffffffbffc000000	ffffffbfffffffff	  64MB		modules
+
+ffffffc000000000	ffffffffffffffff	 256GB		memory
+
+
+Translation table lookup with 4KB pages:
+
++--------+--------+--------+--------+--------+--------+--------+--------+
+|63    56|55    48|47    40|39    32|31    24|23    16|15     8|7      0|
++--------+--------+--------+--------+--------+--------+--------+--------+
+ |                 |         |         |         |         |
+ |                 |         |         |         |         v
+ |                 |         |         |         |   [11:0]  in-page offset
+ |                 |         |         |         +-> [20:12] L3 index
+ |                 |         |         +-----------> [29:21] L2 index
+ |                 |         +---------------------> [38:30] L1 index
+ |                 +-------------------------------> [47:39] L0 index (not used)
+ +-------------------------------------------------> [63] TTBR0/1
+
+
+Translation table lookup with 64KB pages:
+
++--------+--------+--------+--------+--------+--------+--------+--------+
+|63    56|55    48|47    40|39    32|31    24|23    16|15     8|7      0|
++--------+--------+--------+--------+--------+--------+--------+--------+
+ |                 |    |               |              |
+ |                 |    |               |              v
+ |                 |    |               |            [15:0]  in-page offset
+ |                 |    |               +----------> [28:16] L3 index
+ |                 |    +--------------------------> [41:29] L2 index (only 38:29 used)
+ |                 +-------------------------------> [47:42] L1 index (not used)
+ +-------------------------------------------------> [63] TTBR0/1
arch/arm64/include/asm/memory.h new file +144 -0

144 lines not on this page · raw message

arch/arm64/include/asm/mmu.h new file +27 -0
new file mode 100644
index 0000000..c72ad38
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2012 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_MMU_H
+#define __ASM_MMU_H
+
+typedef struct {
+	unsigned int id;
+	raw_spinlock_t id_lock;
+	void *vdso;
+} mm_context_t;
+
+#define ASID(mm)	((mm)->context.id & 0xffff)
+
+#endif
arch/arm64/include/asm/pgtable-2level-hwdef.h new file +43 -0

43 lines not on this page · raw message

arch/arm64/include/asm/pgtable-2level-types.h new file +60 -0

60 lines not on this page · raw message

arch/arm64/include/asm/pgtable-3level-hwdef.h new file +50 -0

50 lines not on this page · raw message

arch/arm64/include/asm/pgtable-3level-types.h new file +66 -0

66 lines not on this page · raw message

arch/arm64/include/asm/pgtable-hwdef.h new file +94 -0

94 lines not on this page · raw message

arch/arm64/include/asm/pgtable.h new file +328 -0

328 lines not on this page · raw message

arch/arm64/include/asm/sparsemem.h new file +24 -0
new file mode 100644
index 0000000..1be62bc
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2012 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_SPARSEMEM_H
+#define __ASM_SPARSEMEM_H
+
+#ifdef CONFIG_SPARSEMEM
+#define MAX_PHYSMEM_BITS	40
+#define SECTION_SIZE_BITS	30
+#endif
+
+#endif
maintainer Acked-by on v3 4/31
#25 lore raw

Re: [PATCH v3 04/31] arm64: MMU definitions

Quoted 16 lines · Catalin Marinas

The virtual memory layout is described in Documentation/arm64/memory.txt. This patch adds the MMU definitions for the 4KB and 64KB translation table configurations. The SECTION_SIZE is 2MB with 4KB page and 512MB with 64KB page configuration.

PHYS_OFFSET is calculated at run-time and stored in a variable (no run-time code patching at this stage).

On the current implementation, both user and kernel address spaces are 512G (39-bit) each with a maximum of 256G for the RAM linear mapping. Linux uses 3 levels of translation tables with the 4K page configuration and 2 levels with the 64K configuration. Extending the memory space beyond 39-bit with the 4K pages or 42-bit with 64K pages requires an additional level of translation tables.

Quoted 6 lines

The SPARSEMEM configuration is global to all AArch64 platforms and allows for 1GB sections with SPARSEMEM_VMEMMAP enabled by default.

author maintainer
#26 lore raw

PATCH v3 5/31 arm64: MMU initialisation

In reply to Catalin Marinas

This patch contains the initialisation of the memory blocks, MMU attributes and the memory map. Only five memory types are defined:
Device nGnRnE (equivalent to Strongly Ordered), Device nGnRE (classic Device memory), Device GRE, Normal Non-cacheable and Normal Cacheable. Cache policies are supported via the memory attributes register (MAIR_EL1) and only affect the Normal Cacheable mappings.

This patch also adds the SPARSEMEM_VMEMMAP initialisation.

---
 arch/arm64/include/asm/memblock.h |   21 ++
 arch/arm64/mm/init.c              |  416 +++++++++++++++++++++++++++++++++++++
 arch/arm64/mm/mmu.c               |  395 +++++++++++++++++++++++++++++++++++
 3 files changed, 832 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm64/include/asm/memblock.h
 create mode 100644 arch/arm64/mm/init.c
 create mode 100644 arch/arm64/mm/mmu.c
arch/arm64/include/asm/memblock.h new file +21 -0
new file mode 100644
index 0000000..6afeed2
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2012 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_MEMBLOCK_H
+#define __ASM_MEMBLOCK_H
+
+extern void arm64_memblock_init(void);
+
+#endif
arch/arm64/mm/init.c new file +416 -0

416 lines not on this page · raw message

arch/arm64/mm/mmu.c new file +395 -0

395 lines not on this page · raw message

maintainer Acked-by on v3 5/31
#27 lore raw

Re: [PATCH v3 05/31] arm64: MMU initialisation

Quoted 8 lines · Catalin Marinas

This patch contains the initialisation of the memory blocks, MMU attributes and the memory map. Only five memory types are defined:
Device nGnRnE (equivalent to Strongly Ordered), Device nGnRE (classic Device memory), Device GRE, Normal Non-cacheable and Normal Cacheable. Cache policies are supported via the memory attributes register (MAIR_EL1) and only affect the Normal Cacheable mappings.

Quoted 5 lines

This patch also adds the SPARSEMEM_VMEMMAP initialisation.

author maintainer
#28 lore raw

PATCH v3 6/31 arm64: MMU fault handling and page table management

In reply to Catalin Marinas

This patch adds support for the handling of the MMU faults (exception entry code introduced by a previous patch) and page table management.

The user translation table is pointed to by TTBR0 and the kernel one (swapper_pg_dir) by TTBR1. There is no translation information shared or address space overlapping between user and kernel page tables.

---
 arch/arm64/include/asm/page.h    |   67 +++++
 arch/arm64/include/asm/pgalloc.h |  113 ++++++++
 arch/arm64/mm/copypage.c         |   34 +++
 arch/arm64/mm/extable.c          |   17 ++
 arch/arm64/mm/fault.c            |  534 ++++++++++++++++++++++++++++++++++++++
 arch/arm64/mm/mm.h               |    2 +
 arch/arm64/mm/mmap.c             |  144 ++++++++++
 arch/arm64/mm/pgd.c              |   54 ++++
 8 files changed, 965 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm64/include/asm/page.h
 create mode 100644 arch/arm64/include/asm/pgalloc.h
 create mode 100644 arch/arm64/mm/copypage.c
 create mode 100644 arch/arm64/mm/extable.c
 create mode 100644 arch/arm64/mm/fault.c
 create mode 100644 arch/arm64/mm/mm.h
 create mode 100644 arch/arm64/mm/mmap.c
 create mode 100644 arch/arm64/mm/pgd.c
arch/arm64/include/asm/page.h new file +67 -0
new file mode 100644
index 0000000..46bf666
@@ -0,0 +1,67 @@
+/*
+ * Based on arch/arm/include/asm/page.h
+ *
+ * Copyright (C) 1995-2003 Russell King
+ * Copyright (C) 2012 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_PAGE_H
+#define __ASM_PAGE_H
+
+/* PAGE_SHIFT determines the page size */
+#ifdef CONFIG_ARM64_64K_PAGES
+#define PAGE_SHIFT		16
+#else
+#define PAGE_SHIFT		12
+#endif
+#define PAGE_SIZE		(_AC(1,UL) << PAGE_SHIFT)
+#define PAGE_MASK		(~(PAGE_SIZE-1))
+
+/* We do define AT_SYSINFO_EHDR but don't use the gate mechanism */
+#define __HAVE_ARCH_GATE_AREA		1
+
+#ifndef __ASSEMBLY__
+
+#ifdef CONFIG_ARM64_64K_PAGES
+#include <asm/pgtable-2level-types.h>
+#else
+#include <asm/pgtable-3level-types.h>
+#endif
+
+extern void __cpu_clear_user_page(void *p, unsigned long user);
+extern void __cpu_copy_user_page(void *to, const void *from,
+				 unsigned long user);
+extern void copy_page(void *to, const void *from);
+extern void clear_page(void *to);
+
+#define clear_user_page(addr,vaddr,pg)  __cpu_clear_user_page(addr, vaddr)
+#define copy_user_page(to,from,vaddr,pg) __cpu_copy_user_page(to, from, vaddr)
+
+typedef struct page *pgtable_t;
+
+#ifdef CONFIG_HAVE_ARCH_PFN_VALID
+extern int pfn_valid(unsigned long);
+#endif
+
+#include <asm/memory.h>
+
+#endif /* !__ASSEMBLY__ */
+
+#define VM_DATA_DEFAULT_FLAGS \
+	(((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0) | \
+	 VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
+
+#include <asm-generic/getorder.h>
+
+#endif
arch/arm64/include/asm/pgalloc.h new file +113 -0

113 lines not on this page · raw message

arch/arm64/mm/copypage.c new file +34 -0
new file mode 100644
index 0000000..9aecbac
@@ -0,0 +1,34 @@
+/*
+ * Based on arch/arm/mm/copypage.c
+ *
+ * Copyright (C) 2002 Deep Blue Solutions Ltd, All Rights Reserved.
+ * Copyright (C) 2012 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/>.
+ */
+
+#include <linux/mm.h>
+
+#include <asm/page.h>
+#include <asm/cacheflush.h>
+
+void __cpu_copy_user_page(void *kto, const void *kfrom, unsigned long vaddr)
+{
+	copy_page(kto, kfrom);
+	__flush_dcache_area(kto, PAGE_SIZE);
+}
+
+void __cpu_clear_user_page(void *kaddr, unsigned long vaddr)
+{
+	clear_page(kaddr);
+}
arch/arm64/mm/extable.c new file +17 -0
new file mode 100644
index 0000000..7944427
@@ -0,0 +1,17 @@
+/*
+ * Based on arch/arm/mm/extable.c
+ */
+
+#include <linux/module.h>
+#include <linux/uaccess.h>
+
+int fixup_exception(struct pt_regs *regs)
+{
+	const struct exception_table_entry *fixup;
+
+	fixup = search_exception_tables(instruction_pointer(regs));
+	if (fixup)
+		regs->pc = fixup->fixup;
+
+	return fixup != NULL;
+}
arch/arm64/mm/fault.c new file +534 -0

534 lines not on this page · raw message

arch/arm64/mm/mm.h new file +2 -0
new file mode 100644
index 0000000..c84f68b
@@ -0,0 +1,2 @@
+extern void __flush_dcache_page(struct address_space *mapping, struct page *page);
+extern void __init bootmem_init(void);
arch/arm64/mm/mmap.c new file +144 -0

144 lines not on this page · raw message

arch/arm64/mm/pgd.c new file +54 -0

54 lines not on this page · raw message

maintainer Acked-by on v3 6/31
#29 lore raw

Re: [PATCH v3 06/31] arm64: MMU fault handling and page table management

Quoted 11 lines · Catalin Marinas

This patch adds support for the handling of the MMU faults (exception entry code introduced by a previous patch) and page table management.

The user translation table is pointed to by TTBR0 and the kernel one (swapper_pg_dir) by TTBR1. There is no translation information shared or address space overlapping between user and kernel page tables.

author maintainer
#30 lore raw

PATCH v3 7/31 arm64: Process management

In reply to Catalin Marinas

The patch adds support for thread creation and context switching. The context switching CPU specific code is introduced with the CPU support patch (part of the arch/arm64/mm/proc.S file). AArch64 supports ASID-tagged TLBs and the ASID can be either 8 or 16-bit wide (detectable via the ID_AA64AFR0_EL1 register).

---
 arch/arm64/include/asm/mmu_context.h |  152 +++++++++++++
 arch/arm64/include/asm/thread_info.h |  127 +++++++++++
 arch/arm64/kernel/process.c          |  412 ++++++++++++++++++++++++++++++++++
 arch/arm64/mm/context.c              |  159 +++++++++++++
 4 files changed, 850 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm64/include/asm/mmu_context.h
 create mode 100644 arch/arm64/include/asm/thread_info.h
 create mode 100644 arch/arm64/kernel/process.c
 create mode 100644 arch/arm64/mm/context.c
arch/arm64/include/asm/mmu_context.h new file +152 -0
new file mode 100644
index 0000000..f68465d
@@ -0,0 +1,152 @@
+/*
+ * Based on arch/arm/include/asm/mmu_context.h
+ *
+ * Copyright (C) 1996 Russell King.
+ * Copyright (C) 2012 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_MMU_CONTEXT_H
+#define __ASM_MMU_CONTEXT_H
+
+#include <linux/compiler.h>
+#include <linux/sched.h>
+
+#include <asm/cacheflush.h>
+#include <asm/proc-fns.h>
+#include <asm-generic/mm_hooks.h>
+#include <asm/cputype.h>
+#include <asm/pgtable.h>
+
+#define MAX_ASID_BITS	16
+
+extern unsigned int cpu_last_asid;
+
+void __init_new_context(struct task_struct *tsk, struct mm_struct *mm);
+void __new_context(struct mm_struct *mm);
+
+/*
+ * Set TTBR0 to empty_zero_page. No translations will be possible via TTBR0.
+ */
+static inline void cpu_set_reserved_ttbr0(void)
+{
+	unsigned long ttbr = page_to_phys(empty_zero_page);
+
+	asm(
+	"	msr	ttbr0_el1, %0			// set TTBR0\n"
+	"	isb"
+	:
+	: "r" (ttbr));
+}
+
+static inline void switch_new_context(struct mm_struct *mm)
+{
+	unsigned long flags;
+
+	__new_context(mm);
+
+	local_irq_save(flags);
+	cpu_switch_mm(mm->pgd, mm);
+	local_irq_restore(flags);
+}
+
+static inline void check_and_switch_context(struct mm_struct *mm,
+					    struct task_struct *tsk)
+{
+	/*
+	 * Required during context switch to avoid speculative page table
+	 * walking with the wrong TTBR.
+	 */
+	cpu_set_reserved_ttbr0();
+
+	if (!((mm->context.id ^ cpu_last_asid) >> MAX_ASID_BITS))
+		/*
+		 * The ASID is from the current generation, just switch to the
+		 * new pgd. This condition is only true for calls from
+		 * context_switch() and interrupts are already disabled.
+		 */
+		cpu_switch_mm(mm->pgd, mm);
+	else if (irqs_disabled())
+		/*
+		 * Defer the new ASID allocation until after the context
+		 * switch critical region since __new_context() cannot be
+		 * called with interrupts disabled.
+		 */
+		set_ti_thread_flag(task_thread_info(tsk), TIF_SWITCH_MM);
+	else
+		/*
+		 * That is a direct call to switch_mm() or activate_mm() with
+		 * interrupts enabled and a new context.
+		 */
+		switch_new_context(mm);
+}
+
+#define init_new_context(tsk,mm)	(__init_new_context(tsk,mm),0)
+#define destroy_context(mm)		do { } while(0)
+
+#define finish_arch_post_lock_switch \
+	finish_arch_post_lock_switch
+static inline void finish_arch_post_lock_switch(void)
+{
+	if (test_and_clear_thread_flag(TIF_SWITCH_MM)) {
+		struct mm_struct *mm = current->mm;
+		unsigned long flags;
+
+		__new_context(mm);
+
+		local_irq_save(flags);
+		cpu_switch_mm(mm->pgd, mm);
+		local_irq_restore(flags);
+	}
+}
+
+/*
+ * This is called when "tsk" is about to enter lazy TLB mode.
+ *
+ * mm:  describes the currently active mm context
+ * tsk: task which is entering lazy tlb
+ * cpu: cpu number which is entering lazy tlb
+ *
+ * tsk->mm will be NULL
+ */
+static inline void
+enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
+{
+}
+
+/*
+ * This is the actual mm switch as far as the scheduler
+ * is concerned.  No registers are touched.  We avoid
+ * calling the CPU specific function when the mm hasn't
+ * actually changed.
+ */
+static inline void
+switch_mm(struct mm_struct *prev, struct mm_struct *next,
+	  struct task_struct *tsk)
+{
+	unsigned int cpu = smp_processor_id();
+
+#ifdef CONFIG_SMP
+	/* check for possible thread migration */
+	if (!cpumask_empty(mm_cpumask(next)) &&
+	    !cpumask_test_cpu(cpu, mm_cpumask(next)))
+		__flush_icache_all();
+#endif
+	if (!cpumask_test_and_set_cpu(cpu, mm_cpumask(next)) || prev != next)
+		check_and_switch_context(next, tsk);
+}
+
+#define deactivate_mm(tsk,mm)	do { } while (0)
+#define activate_mm(prev,next)	switch_mm(prev, next, NULL)
+
+#endif
arch/arm64/include/asm/thread_info.h new file +127 -0

127 lines not on this page · raw message

arch/arm64/kernel/process.c new file +412 -0

412 lines not on this page · raw message

arch/arm64/mm/context.c new file +159 -0

159 lines not on this page · raw message

maintainer Acked-by on v3 7/31
#31 lore raw

Re: [PATCH v3 07/31] arm64: Process management

Quoted 9 lines · Catalin Marinas

The patch adds support for thread creation and context switching. The context switching CPU specific code is introduced with the CPU support patch (part of the arch/arm64/mm/proc.S file). AArch64 supports ASID-tagged TLBs and the ASID can be either 8 or 16-bit wide (detectable via the ID_AA64AFR0_EL1 register).

But please fix a few small issues in process.c:

arch/arm64/kernel/process.c line 52

Quoted 8 lines
arch/arm64/kernel/process.c new file +2 -0
new file mode 100644
index 0000000..6dfd96f
 
+
+extern void setup_mm_for_reboot(void);

No extern declarations in .c files, put it in a header file instead.

arch/arm64/kernel/process.c line 103

Quoted 13 lines
arch/arm64/kernel/process.c new file +12 -0
+
+/*
+ * Function pointers to optional machine specific functions
+ */
+void (*pm_power_off)(void);
+EXPORT_SYMBOL(pm_power_off);
+
+void (*pm_restart)(const char *cmd);
+EXPORT_SYMBOL_GPL(pm_restart);
+
 
+void (*pm_idle)(void) = default_idle;
+EXPORT_SYMBOL(pm_idle);

I'd make them all EXPORT_SYMBOL_GPL. External modules have no business overriding them.

arch/arm64/kernel/process.c line 182

Quoted 7 lines
arch/arm64/kernel/process.c new file +7 -0
+	/*
+	 * Whoops - the architecture was unable to reboot.
+	 * Tell the user!
+	 */
+	mdelay(1000);
+	printk("Reboot failed -- System halted\n");
+	while (1);

This delay seems pointless.

Arnd

author maintainer
#32 lore raw

PATCH v3 8/31 arm64: CPU support

In reply to Catalin Marinas

This patch adds AArch64 CPU specific functionality. It assumes that the implementation is generic to AArch64 and does not require specific identification. Different CPU implementations may require the setting of various ACTLR_EL1 bits but such information is not currently available and it should ideally be pushed to firmware.

---
 arch/arm64/include/asm/cputable.h  |   30 ++++++
 arch/arm64/include/asm/cputype.h   |   49 ++++++++++
 arch/arm64/include/asm/proc-fns.h  |   51 ++++++++++
 arch/arm64/include/asm/processor.h |  175 ++++++++++++++++++++++++++++++++++
 arch/arm64/kernel/cputable.c       |   33 +++++++
 arch/arm64/mm/proc.S               |  181 ++++++++++++++++++++++++++++++++++++
 6 files changed, 519 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm64/include/asm/cputable.h
 create mode 100644 arch/arm64/include/asm/cputype.h
 create mode 100644 arch/arm64/include/asm/proc-fns.h
 create mode 100644 arch/arm64/include/asm/processor.h
 create mode 100644 arch/arm64/kernel/cputable.c
 create mode 100644 arch/arm64/mm/proc.S
arch/arm64/include/asm/cputable.h new file +30 -0
new file mode 100644
index 0000000..e3bd983
@@ -0,0 +1,30 @@
+/*
+ * arch/arm64/include/asm/cputable.h
+ *
+ * Copyright (C) 2012 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_CPUTABLE_H
+#define __ASM_CPUTABLE_H
+
+struct cpu_info {
+	unsigned int	cpu_id_val;
+	unsigned int	cpu_id_mask;
+	const char	*cpu_name;
+	unsigned long	(*cpu_setup)(void);
+};
+
+extern struct cpu_info *lookup_processor_type(unsigned int);
+
+#endif
arch/arm64/include/asm/cputype.h new file +49 -0

49 lines not on this page · raw message

arch/arm64/include/asm/proc-fns.h new file +51 -0

51 lines not on this page · raw message

arch/arm64/include/asm/processor.h new file +175 -0

175 lines not on this page · raw message

arch/arm64/kernel/cputable.c new file +33 -0
new file mode 100644
index 0000000..63cfc4a
@@ -0,0 +1,33 @@
+/*
+ * arch/arm64/kernel/cputable.c
+ *
+ * Copyright (C) 2012 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/>.
+ */
+
+#include <linux/init.h>
+
+#include <asm/cputable.h>
+
+extern unsigned long __cpu_setup(void);
+
+struct cpu_info __initdata cpu_table[] = {
+	{
+		.cpu_id_val	= 0x000f0000,
+		.cpu_id_mask	= 0x000f0000,
+		.cpu_name	= "AArch64 Processor",
+		.cpu_setup	= __cpu_setup,
+	},
+	{ /* Empty */ },
+};
arch/arm64/mm/proc.S new file +181 -0

181 lines not on this page · raw message

maintainer
#33 lore raw

Re: [PATCH v3 08/31] arm64: CPU support

Quoted 14 lines · Catalin Marinas
arch/arm64/kernel/cputable.c new file +14 -0
+
+#include <asm/cputable.h>
+
+extern unsigned long __cpu_setup(void);
+
+struct cpu_info __initdata cpu_table[] = {
+	{
+		.cpu_id_val	= 0x000f0000,
+		.cpu_id_mask	= 0x000f0000,
+		.cpu_name	= "AArch64 Processor",
+		.cpu_setup	= __cpu_setup,
+	},
+	{ /* Empty */ },
+};

arch/arm64/kernel/cputable.c

Quoted 10 lines
arch/arm64/kernel/cputable.c new file +9 -0
 
+#define MAIR(attr, mt)	((attr) << ((mt) * 8))
+
+ENTRY(cpu_proc_init)
+	ret
+ENDPROC(cpu_proc_init)
+
+ENTRY(cpu_proc_fin)
+	ret
+ENDPROC(cpu_proc_fin)

These seem to be leftovers from multi-cpu support that can be removed.

Arnd

author maintainer
#34 lore raw

Re: [PATCH v3 08/31] arm64: CPU support

Quoted 15 lines · Arnd Bergmann
Quoted 13 lines · Catalin Marinas
arch/arm64/kernel/cputable.c new file +13 -0
+#include <asm/cputable.h>
+
+extern unsigned long __cpu_setup(void);
+
+struct cpu_info __initdata cpu_table[] = {
+	{
+		.cpu_id_val	= 0x000f0000,
+		.cpu_id_mask	= 0x000f0000,
+		.cpu_name	= "AArch64 Processor",
+		.cpu_setup	= __cpu_setup,
+	},
+	{ /* Empty */ },
+};
Quoted 12 lines

arch/arm64/mm/proc.S line 47

Quoted 9 lines
arch/arm64/mm/proc.S new file +9 -0
+#define MAIR(attr, mt)	((attr) << ((mt) * 8))
+
+ENTRY(cpu_proc_init)
+	ret
+ENDPROC(cpu_proc_init)
+
+ENTRY(cpu_proc_fin)
+	ret
+ENDPROC(cpu_proc_fin)

These seem to be leftovers from multi-cpu support that can be removed.

Actually cpu_proc_fin() needs to be implemented for turning the caches off during setup_restart(). But I'll rename it to something more meaningful like cpu_cache_off(). The other can go.

Signature · 1 line
Catalin
author maintainer
#35 lore raw

PATCH v3 9/31 arm64: Cache maintenance routines

In reply to Catalin Marinas

The patch adds functionality required for cache maintenance. The AArch64 architecture mandates non-aliasing VIPT or PIPT D-cache and VIPT (may have aliases) or ASID-tagged VIVT I-cache. Cache maintenance operations are automatically broadcast in hardware between CPUs.

---
 arch/arm64/include/asm/cache.h      |   32 +++++
 arch/arm64/include/asm/cacheflush.h |  168 +++++++++++++++++++++++
 arch/arm64/include/asm/cachetype.h  |   48 +++++++
 arch/arm64/mm/cache.S               |  251 +++++++++++++++++++++++++++++++++++
 arch/arm64/mm/flush.c               |  138 +++++++++++++++++++
 5 files changed, 637 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm64/include/asm/cache.h
 create mode 100644 arch/arm64/include/asm/cacheflush.h
 create mode 100644 arch/arm64/include/asm/cachetype.h
 create mode 100644 arch/arm64/mm/cache.S
 create mode 100644 arch/arm64/mm/flush.c
arch/arm64/include/asm/cache.h new file +32 -0
new file mode 100644
index 0000000..390308a
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2012 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_CACHE_H
+#define __ASM_CACHE_H
+
+#define L1_CACHE_SHIFT		6
+#define L1_CACHE_BYTES		(1 << L1_CACHE_SHIFT)
+
+/*
+ * Memory returned by kmalloc() may be used for DMA, so we must make
+ * sure that all such allocations are cache aligned. Otherwise,
+ * unrelated code may cause parts of the buffer to be read into the
+ * cache before the transfer is done, causing old data to be seen by
+ * the CPU.
+ */
+#define ARCH_DMA_MINALIGN	L1_CACHE_BYTES
+#define ARCH_SLAB_MINALIGN	8
+
+#endif
arch/arm64/include/asm/cacheflush.h new file +168 -0

168 lines not on this page · raw message

arch/arm64/include/asm/cachetype.h new file +48 -0

48 lines not on this page · raw message

arch/arm64/mm/cache.S new file +251 -0

251 lines not on this page · raw message

arch/arm64/mm/flush.c new file +138 -0

138 lines not on this page · raw message

maintainer Acked-by on v3 9/31
#36 lore raw

Re: [PATCH v3 09/31] arm64: Cache maintenance routines

arch/arm64/mm/cache.S line 171

Quoted 3 lines · Catalin Marinas
arch/arm64/mm/cache.S new file +3 -0
+
+/*
+ *	dmac_inv_range(start,end)

all of these appear to be unused now. Can you remove them?

Quoted 69 lines

+ * Invalidate the data cache within the specified region; we will be
+ * performing a DMA operation in this region and we want to purge old
+ * data in the cache.
+ *
+ * - start - virtual start address of region
+ * - end - virtual end address of region
+ */

arch/arm64/mm/cache.S new file +62 -0
+ENTRY(dmac_inv_range)
+	dcache_line_size x2, x3
+	sub	x3, x2, #1
+	bic	x0, x0, x3
+	bic	x1, x1, x3
+1:	dc	ivac, x0			// invalidate D / U line
+	add	x0, x0, x2
+	cmp	x0, x1
+	b.lo	1b
+	dsb	sy
+	ret
+ENDPROC(dmac_inv_range)
+
+/*
+ *	dmac_clean_range(start,end)
+ *	- start   - virtual start address of region
+ *	- end     - virtual end address of region
+ */
+ENTRY(dmac_clean_range)
+	dcache_line_size x2, x3
+	sub	x3, x2, #1
+	bic	x0, x0, x3
+1:	dc	cvac, x0			// clean D / U line
+	add	x0, x0, x2
+	cmp	x0, x1
+	b.lo	1b
+	dsb	sy
+	ret
+ENDPROC(dmac_clean_range)
+
+/*
+ *	dmac_flush_range(start,end)
+ *	- start   - virtual start address of region
+ *	- end     - virtual end address of region
+ */
+ENTRY(dmac_flush_range)
+	dcache_line_size x2, x3
+	sub	x3, x2, #1
+	bic	x0, x0, x3
+1:	dc	civac, x0			// clean & invalidate D / U line
+	add	x0, x0, x2
+	cmp	x0, x1
+	b.lo	1b
+	dsb	sy
+	ret
+ENDPROC(dmac_flush_range)
+
+/*
+ *	dmac_map_area(start, size, dir)
+ *	- start	- kernel virtual start address
+ *	- size	- size of region
+ *	- dir	- DMA direction
+ */
+ENTRY(dmac_map_area)
+	add	x1, x1, x0
+	cmp	x2, #DMA_FROM_DEVICE
+	b.eq	dmac_inv_range
+	b	dmac_clean_range
+ENDPROC(dmac_map_area)
+
+/*
+ *	dmac_unmap_area(start, size, dir)

arch/arm64/mm/cache.S line 251

Quoted 10 lines
arch/arm64/mm/cache.S new file +10 -0
+ *	- start	- kernel virtual start address
+ *	- size	- size of region
+ *	- dir	- DMA direction
+ */
+ENTRY(dmac_unmap_area)
+	add	x1, x1, x0
+	cmp	x2, #DMA_TO_DEVICE
+	b.ne	dmac_inv_range
+	ret
+ENDPROC(dmac_unmap_area)

Aside from this:

author maintainer
#37 lore raw

Re: [PATCH v3 09/31] arm64: Cache maintenance routines

Quoted 6 lines · Arnd Bergmann

arch/arm64/mm/cache.S line 171

Quoted 3 lines · Catalin Marinas
arch/arm64/mm/cache.S new file +3 -0
+
+/*
+ *	dmac_inv_range(start,end)

all of these appear to be unused now. Can you remove them?

They aren't currently used but I expect some partners to make use of them on their private development. I could drop them from the upstream branch temporarily.

Signature · 1 line
Catalin
#38 lore raw

Re: [PATCH v3 09/31] arm64: Cache maintenance routines

Quoted 11 lines · Catalin Marinas
Quoted 6 lines · Arnd Bergmann

arch/arm64/mm/cache.S line 171

Quoted 3 lines · Catalin Marinas
arch/arm64/mm/cache.S new file +3 -0
+
+/*
+ *	dmac_inv_range(start,end)

all of these appear to be unused now. Can you remove them?

They aren't currently used but I expect some partners to make use of them on their private development. I could drop them from the upstream branch temporarily.

Depends. If your expectation from those partners is a real probability then it is best to keep a skeleton in place for them to use, otherwise they might get ... creative. If this is just wild speculation then you should drop it.

Nicolas

author maintainer
#39 lore raw

Re: [PATCH v3 09/31] arm64: Cache maintenance routines

Quoted 10 lines · Nicolas Pitre
Quoted 8 lines · Catalin Marinas
Quoted 6 lines · Arnd Bergmann

arch/arm64/mm/cache.S line 171

Quoted 3 lines · Catalin Marinas
arch/arm64/mm/cache.S new file +3 -0
+
+/*
+ *	dmac_inv_range(start,end)

all of these appear to be unused now. Can you remove them?

Quoted 8 lines
Quoted 3 lines

They aren't currently used but I expect some partners to make use of them on their private development. I could drop them from the upstream branch temporarily.

Depends. If your expectation from those partners is a real probability then it is best to keep a skeleton in place for them to use, otherwise they might get ... creative. If this is just wild speculation then you should drop it.

I dropped them for now since there is no API using those functions. But I have a feeling they will be needed at some point (so I'll keep the patches around).

Signature · 1 line
Catalin
#40 lore raw

Re: [PATCH v3 09/31] arm64: Cache maintenance routines

In reply to Catalin Marinas

Hi Catalin,

Quoted 186 lines · Catalin Marinas

The patch adds functionality required for cache maintenance. The AArch64 architecture mandates non-aliasing VIPT or PIPT D-cache and VIPT (may have aliases) or ASID-tagged VIVT I-cache. Cache maintenance operations are automatically broadcast in hardware between CPUs.

---
 arch/arm64/include/asm/cache.h      |   32 +++++
 arch/arm64/include/asm/cacheflush.h |  168 +++++++++++++++++++++++
 arch/arm64/include/asm/cachetype.h  |   48 +++++++
 arch/arm64/mm/cache.S               |  251 +++++++++++++++++++++++++++++++++++
 arch/arm64/mm/flush.c               |  138 +++++++++++++++++++
 5 files changed, 637 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm64/include/asm/cache.h
 create mode 100644 arch/arm64/include/asm/cacheflush.h
 create mode 100644 arch/arm64/include/asm/cachetype.h
 create mode 100644 arch/arm64/mm/cache.S
 create mode 100644 arch/arm64/mm/flush.c
arch/arm64/include/asm/cache.h new file +32 -0
new file mode 100644
index 0000000..390308a
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2012 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_CACHE_H
+#define __ASM_CACHE_H
+
+#define L1_CACHE_SHIFT		6
+#define L1_CACHE_BYTES		(1 << L1_CACHE_SHIFT)
+
+/*
+ * Memory returned by kmalloc() may be used for DMA, so we must make
+ * sure that all such allocations are cache aligned. Otherwise,
+ * unrelated code may cause parts of the buffer to be read into the
+ * cache before the transfer is done, causing old data to be seen by
+ * the CPU.
+ */
+#define ARCH_DMA_MINALIGN	L1_CACHE_BYTES
+#define ARCH_SLAB_MINALIGN	8
+
+#endif
arch/arm64/include/asm/cacheflush.h new file +121 -0
new file mode 100644
index 0000000..0bb9853
@@ -0,0 +1,168 @@
+/*
+ * Based on arch/arm/include/asm/cacheflush.h
+ *
+ * Copyright (C) 1999-2002 Russell King.
+ * Copyright (C) 2012 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_CACHEFLUSH_H
+#define __ASM_CACHEFLUSH_H
+
+#include <linux/mm.h>
+
+/*
+ * This flag is used to indicate that the page pointed to by a pte is clean
+ * and does not require cleaning before returning it to the user.
+ */
+#define PG_dcache_clean PG_arch_1
+
+/*
+ *	MM Cache Management
+ *	===================
+ *
+ *	The arch/arm64/mm/cache.S implements these methods.
+ *
+ *	Start addresses are inclusive and end addresses are exclusive; start
+ *	addresses should be rounded down, end addresses up.
+ *
+ *	See Documentation/cachetlb.txt for more information. Please note that
+ *	the implementation assumes non-aliasing VIPT D-cache and (aliasing)
+ *	VIPT or ASID-tagged VIVT I-cache.
+ *
+ *	flush_cache_all()
+ *
+ *		Unconditionally clean and invalidate the entire cache.
+ *
+ *	flush_cache_mm(mm)
+ *
+ *		Clean and invalidate all user space cache entries
+ *		before a change of page tables.
+ *
+ *	flush_icache_range(start, end)
+ *
+ *		Ensure coherency between the I-cache and the D-cache in the
+ *		region described by start, end.
+ *		- start  - virtual start address
+ *		- end    - virtual end address
+ *
+ *	__flush_cache_user_range(start, end)
+ *
+ *		Ensure coherency between the I-cache and the D-cache in the
+ *		region described by start, end.
+ *		- start  - virtual start address
+ *		- end    - virtual end address
+ *
+ *	__flush_dcache_area(kaddr, size)
+ *
+ *		Ensure that the data held in page is written back.
+ *		- kaddr  - page address
+ *		- size   - region size
+ */
+extern void flush_cache_all(void);
+extern void flush_cache_mm(struct mm_struct *mm);
+extern void flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end);
+extern void flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr, unsigned long pfn);
+extern void flush_icache_range(unsigned long start, unsigned long end);
+extern void __flush_dcache_area(void *addr, size_t len);
+extern void __flush_cache_user_range(unsigned long start, unsigned long end);
+
+/*
+ * These are private to the dma-mapping API.  Do not use directly.
+ * Their sole purpose is to ensure that data held in the cache
+ * is visible to DMA, or data written by DMA to system memory is
+ * visible to the CPU.
+ */
+extern void dmac_map_area(const void *, size_t, int);
+extern void dmac_unmap_area(const void *, size_t, int);
+extern void dmac_flush_range(const void *, const void *);
+
+/*
+ * Copy user data from/to a page which is mapped into a different
+ * processes address space.  Really, we want to allow our "user
+ * space" model to handle this.
+ */
+extern void copy_to_user_page(struct vm_area_struct *, struct page *,
+	unsigned long, void *, const void *, unsigned long);
+#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
+	do {							\
+		memcpy(dst, src, len);				\
+	} while (0)
+
+#define flush_cache_dup_mm(mm) flush_cache_mm(mm)
+
+/*
+ * flush_dcache_page is used when the kernel has written to the page
+ * cache page at virtual address page->virtual.
+ *
+ * If this page isn't mapped (ie, page_mapping == NULL), or it might
+ * have userspace mappings, then we _must_ always clean + invalidate
+ * the dcache entries associated with the kernel mapping.
+ *
+ * Otherwise we can defer the operation, and clean the cache when we are
+ * about to change to user space.  This is the same method as used on SPARC64.
+ * See update_mmu_cache for the user space part.
+ */
+#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
+extern void flush_dcache_page(struct page *);
+
+static inline void __flush_icache_all(void)
+{
+	asm("ic	ialluis");

arch/arm64/include/asm/cacheflush.h line 131

Quoted 10 lines
arch/arm64/include/asm/cacheflush.h new file +10 -0
+}
+
+#define ARCH_HAS_FLUSH_ANON_PAGE
+static inline void flush_anon_page(struct vm_area_struct *vma,
+			 struct page *page, unsigned long vmaddr)
+{
+	extern void __flush_anon_page(struct vm_area_struct *vma,
+				struct page *, unsigned long);
+	if (PageAnon(page))
+		__flush_anon_page(vma, page, vmaddr);

__flush_anon_page() does nothing. Shouldn't this be removed as well?

Quoted 236 lines
arch/arm64/include/asm/cacheflush.h new file +37 -0
+}
+
+#define flush_dcache_mmap_lock(mapping) \
+	spin_lock_irq(&(mapping)->tree_lock)
+#define flush_dcache_mmap_unlock(mapping) \
+	spin_unlock_irq(&(mapping)->tree_lock)
+
+#define flush_icache_user_range(vma,page,addr,len) \
+	flush_dcache_page(page)
+
+/*
+ * We don't appear to need to do anything here.  In fact, if we did, we'd
+ * duplicate cache flushing elsewhere performed by flush_dcache_page().
+ */
+#define flush_icache_page(vma,page)	do { } while (0)
+
+/*
+ * flush_cache_vmap() is used when creating mappings (eg, via vmap,
+ * vmalloc, ioremap etc) in kernel space for pages.  On non-VIPT
+ * caches, since the direct-mappings of these pages may contain cached
+ * data, we need to do a full cache flush to ensure that writebacks
+ * don't corrupt data placed into these pages via the new mappings.
+ */
+static inline void flush_cache_vmap(unsigned long start, unsigned long end)
+{
+	/*
+	 * set_pte_at() called from vmap_pte_range() does not
+	 * have a DSB after cleaning the cache line.
+	 */
+	dsb();
+}
+
+static inline void flush_cache_vunmap(unsigned long start, unsigned long end)
+{
+}
+
+#endif
arch/arm64/include/asm/cachetype.h new file +48 -0
new file mode 100644
index 0000000..85f5f51
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2012 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_CACHETYPE_H
+#define __ASM_CACHETYPE_H
+
+#include <asm/cputype.h>
+
+#define CTR_L1IP_SHIFT		14
+#define CTR_L1IP_MASK		3
+
+#define ICACHE_POLICY_RESERVED	0
+#define ICACHE_POLICY_AIVIVT	1
+#define ICACHE_POLICY_VIPT	2
+#define ICACHE_POLICY_PIPT	3
+
+static inline u32 icache_policy(void)
+{
+	return (read_cpuid_cachetype() >> CTR_L1IP_SHIFT) & CTR_L1IP_MASK;
+}
+
+/*
+ * Whilst the D-side always behaves as PIPT on AArch64, aliasing is
+ * permitted in the I-cache.
+ */
+static inline int icache_is_aliasing(void)
+{
+	return icache_policy() != ICACHE_POLICY_PIPT;
+}
+
+static inline int icache_is_aivivt(void)
+{
+	return icache_policy() == ICACHE_POLICY_AIVIVT;
+}
+
+#endif	/* __ASM_CACHETYPE_H */
arch/arm64/mm/cache.S new file +139 -0
new file mode 100644
index 0000000..3df0aa7
@@ -0,0 +1,251 @@
+/*
+ * Cache maintenance
+ *
+ * Copyright (C) 2001 Deep Blue Solutions Ltd.
+ * Copyright (C) 2012 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/>.
+ */
+
+#include <linux/linkage.h>
+#include <linux/init.h>
+#include <asm/assembler.h>
+
+#include "proc-macros.S"
+
+/*
+ *	__flush_dcache_all()
+ *
+ *	Flush the whole D-cache.
+ *
+ *	Corrupted registers: x0-x7, x9-x11
+ */
+ENTRY(__flush_dcache_all)
+	dsb	sy				// ensure ordering with previous memory accesses
+	mrs	x0, clidr_el1			// read clidr
+	and	x3, x0, #0x7000000		// extract loc from clidr
+	lsr	x3, x3, #23			// left align loc bit field
+	cbz	x3, finished			// if loc is 0, then no need to clean
+	mov	x10, #0				// start clean at cache level 0
+loop1:
+	add	x2, x10, x10, lsr #1		// work out 3x current cache level
+	lsr	x1, x0, x2			// extract cache type bits from clidr
+	and	x1, x1, #7			// mask of the bits for current cache only
+	cmp	x1, #2				// see what cache we have at this level
+	b.lt	skip				// skip if no cache, or just i-cache
+	save_and_disable_irqs x9		// make CSSELR and CCSIDR access atomic
+	msr	csselr_el1, x10			// select current cache level in csselr
+	isb					// isb to sych the new cssr&csidr
+	mrs	x1, ccsidr_el1			// read the new ccsidr
+	restore_irqs x9
+	and	x2, x1, #7			// extract the length of the cache lines
+	add	x2, x2, #4			// add 4 (line length offset)
+	mov	x4, #0x3ff
+	and	x4, x4, x1, lsr #3		// find maximum number on the way size
+	clz	x5, x4				// find bit position of way size increment
+	mov	x7, #0x7fff
+	and	x7, x7, x1, lsr #13		// extract max number of the index size
+loop2:
+	mov	x9, x4				// create working copy of max way size
+loop3:
+	lsl	x6, x9, x5
+	orr	x11, x10, x6			// factor way and cache number into x11
+	lsl	x6, x7, x2
+	orr	x11, x11, x6			// factor index number into x11
+	dc	cisw, x11			// clean & invalidate by set/way
+	subs	x9, x9, #1			// decrement the way
+	b.ge	loop3
+	subs	x7, x7, #1			// decrement the index
+	b.ge	loop2
+skip:
+	add	x10, x10, #2			// increment cache number
+	cmp	x3, x10
+	b.gt	loop1
+finished:
+	mov	x10, #0				// swith back to cache level 0
+	msr	csselr_el1, x10			// select current cache level in csselr
+	dsb	sy
+	isb
+	ret
+ENDPROC(__flush_dcache_all)
+
+/*
+ *	flush_cache_all()
+ *
+ *	Flush the entire cache system.  The data cache flush is now achieved
+ *	using atomic clean / invalidates working outwards from L1 cache. This
+ *	is done using Set/Way based cache maintainance instructions.  The
+ *	instruction cache can still be invalidated back to the point of
+ *	unification in a single instruction.
+ */
+ENTRY(flush_cache_all)
+	mov	x12, lr
+	bl	__flush_dcache_all
+	mov	x0, #0
+	ic	ialluis				// I+BTB cache invalidate
+	ret	x12
+ENDPROC(flush_cache_all)
+
+/*
+ *	flush_icache_range(start,end)
+ *
+ *	Ensure that the I and D caches are coherent within specified region.
+ *	This is typically used when code has been written to a memory region,
+ *	and will be executed.
+ *
+ *	- start   - virtual start address of region
+ *	- end     - virtual end address of region
+ */
+ENTRY(flush_icache_range)
+	/* FALLTHROUGH */
+
+/*
+ *	__flush_cache_user_range(start,end)
+ *
+ *	Ensure that the I and D caches are coherent within specified region.
+ *	This is typically used when code has been written to a memory region,
+ *	and will be executed.
+ *
+ *	- start   - virtual start address of region
+ *	- end     - virtual end address of region
+ */
+ENTRY(__flush_cache_user_range)
+	dcache_line_size x2, x3
+	sub	x3, x2, #1
+	bic	x4, x0, x3
+1:
+USER(9f, dc	cvau, x4	)		// clean D line to PoU
+	add	x4, x4, x2
+	cmp	x4, x1
+	b.lo	1b
+	dsb	sy
+
+	icache_line_size x2, x3
+	sub	x3, x2, #1
+	bic	x4, x0, x3
+1:
+USER(9f, ic	ivau, x4	)		// invalidate I line PoU
+	add	x4, x4, x2
+	cmp	x4, x1

arch/arm64/mm/cache.S line 149

Quoted 10 lines
arch/arm64/mm/cache.S new file +10 -0
+	b.lo	1b
+9:						// ignore any faulting cache operation
+	dsb	sy
+	isb
+	ret
+ENDPROC(flush_icache_range)
+ENDPROC(__flush_cache_user_range)
+
+/*
+ *	__flush_kern_dcache_page(kaddr)

Should be: __flush_dcache_area(kaddr,size)

arch/arm64/mm/cache.S line 152

Quoted 3 lines
arch/arm64/mm/cache.S new file +3 -0
+ *
+ *	Ensure that the data held in the page kaddr is written back to the
+ *	page in question.

s/page/area

Quoted 219 lines
arch/arm64/mm/cache.S new file +99 -0
+ *
+ *	- kaddr   - kernel address
+ *	- size    - size in question
+ */
+ENTRY(__flush_dcache_area)
+	dcache_line_size x2, x3
+	add	x1, x0, x1
+	sub	x3, x2, #1
+	bic	x0, x0, x3
+1:	dc	civac, x0			// clean & invalidate D line / unified line
+	add	x0, x0, x2
+	cmp	x0, x1
+	b.lo	1b
+	dsb	sy
+	ret
+ENDPROC(__flush_dcache_area)
+
+/*
+ *	dmac_inv_range(start,end)
+ *
+ *	Invalidate the data cache within the specified region; we will be
+ *	performing a DMA operation in this region and we want to purge old
+ *	data in the cache.
+ *
+ *	- start   - virtual start address of region
+ *	- end     - virtual end address of region
+ */
+ENTRY(dmac_inv_range)
+	dcache_line_size x2, x3
+	sub	x3, x2, #1
+	bic	x0, x0, x3
+	bic	x1, x1, x3
+1:	dc	ivac, x0			// invalidate D / U line
+	add	x0, x0, x2
+	cmp	x0, x1
+	b.lo	1b
+	dsb	sy
+	ret
+ENDPROC(dmac_inv_range)
+
+/*
+ *	dmac_clean_range(start,end)
+ *	- start   - virtual start address of region
+ *	- end     - virtual end address of region
+ */
+ENTRY(dmac_clean_range)
+	dcache_line_size x2, x3
+	sub	x3, x2, #1
+	bic	x0, x0, x3
+1:	dc	cvac, x0			// clean D / U line
+	add	x0, x0, x2
+	cmp	x0, x1
+	b.lo	1b
+	dsb	sy
+	ret
+ENDPROC(dmac_clean_range)
+
+/*
+ *	dmac_flush_range(start,end)
+ *	- start   - virtual start address of region
+ *	- end     - virtual end address of region
+ */
+ENTRY(dmac_flush_range)
+	dcache_line_size x2, x3
+	sub	x3, x2, #1
+	bic	x0, x0, x3
+1:	dc	civac, x0			// clean & invalidate D / U line
+	add	x0, x0, x2
+	cmp	x0, x1
+	b.lo	1b
+	dsb	sy
+	ret
+ENDPROC(dmac_flush_range)
+
+/*
+ *	dmac_map_area(start, size, dir)
+ *	- start	- kernel virtual start address
+ *	- size	- size of region
+ *	- dir	- DMA direction
+ */
+ENTRY(dmac_map_area)
+	add	x1, x1, x0
+	cmp	x2, #DMA_FROM_DEVICE
+	b.eq	dmac_inv_range
+	b	dmac_clean_range
+ENDPROC(dmac_map_area)
+
+/*
+ *	dmac_unmap_area(start, size, dir)
+ *	- start	- kernel virtual start address
+ *	- size	- size of region
+ *	- dir	- DMA direction
+ */
+ENTRY(dmac_unmap_area)
+	add	x1, x1, x0
+	cmp	x2, #DMA_TO_DEVICE
+	b.ne	dmac_inv_range
+	ret
+ENDPROC(dmac_unmap_area)
arch/arm64/mm/flush.c new file +114 -0
new file mode 100644
index 0000000..6138d86
@@ -0,0 +1,138 @@
+/*
+ * Based on arch/arm/mm/flush.c
+ *
+ * Copyright (C) 1995-2002 Russell King
+ * Copyright (C) 2012 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/>.
+ */
+
+#include <linux/export.h>
+#include <linux/mm.h>
+#include <linux/pagemap.h>
+
+#include <asm/cacheflush.h>
+#include <asm/cachetype.h>
+#include <asm/tlbflush.h>
+
+#include "mm.h"
+
+void flush_cache_mm(struct mm_struct *mm)
+{
+}
+
+void flush_cache_range(struct vm_area_struct *vma, unsigned long start,
+		       unsigned long end)
+{
+	if (vma->vm_flags & VM_EXEC)
+		__flush_icache_all();
+}
+
+void flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr,
+		      unsigned long pfn)
+{
+}
+
+static void flush_ptrace_access(struct vm_area_struct *vma, struct page *page,
+				unsigned long uaddr, void *kaddr,
+				unsigned long len)
+{
+	if (vma->vm_flags & VM_EXEC) {
+		unsigned long addr = (unsigned long)kaddr;
+		if (icache_is_aliasing()) {
+			__flush_dcache_area(kaddr, len);
+			__flush_icache_all();
+		} else {
+			flush_icache_range(addr, addr + len);
+		}
+	}
+}
+
+/*
+ * Copy user data from/to a page which is mapped into a different processes
+ * address space.  Really, we want to allow our "user space" model to handle
+ * this.
+ *
+ * Note that this code needs to run on the current CPU.
+ */
+void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
+		       unsigned long uaddr, void *dst, const void *src,
+		       unsigned long len)
+{
+#ifdef CONFIG_SMP
+	preempt_disable();
+#endif
+	memcpy(dst, src, len);
+	flush_ptrace_access(vma, page, uaddr, dst, len);
+#ifdef CONFIG_SMP
+	preempt_enable();
+#endif
+}
+
+void __flush_dcache_page(struct address_space *mapping, struct page *page)
+{
+	__flush_dcache_area(page_address(page), PAGE_SIZE);
+}
+
+void __sync_icache_dcache(pte_t pte)
+{
+	unsigned long pfn;
+	struct page *page;
+
+	pfn = pte_pfn(pte);
+	if (!pfn_valid(pfn))
+		return;
+
+	page = pfn_to_page(pfn);
+	if (!test_and_set_bit(PG_dcache_clean, &page->flags))
+		__flush_dcache_page(NULL, page);
+	__flush_icache_all();
+}
+
+/*
+ * Ensure cache coherency between kernel mapping and userspace mapping of this
+ * page.
+ */
+void flush_dcache_page(struct page *page)
+{
+	struct address_space *mapping;
+
+	/*
+	 * The zero page is never written to, so never has any dirty cache
+	 * lines, and therefore never needs to be flushed.
+	 */
+	if (page == ZERO_PAGE(0))

arch/arm64/mm/flush.c line 124

Quoted 10 lines
arch/arm64/mm/flush.c new file +10 -0
+		return;
+
+	mapping = page_mapping(page);
+
+	if (mapping && !mapping_mapped(mapping))
+		clear_bit(PG_dcache_clean, &page->flags);
+	else {
+		__flush_dcache_page(mapping, page);
+		if (mapping)
+			__flush_icache_all();

Is this necessary to ensure I/D coherency? Then, I would have expected

		if (mapping) {
			__flush_dcache_page(mapping, page);
			__flush_icache_all();
		}

similar to __sync_icache_dcache() above.

What is the reason why the D-cache flush is done in different cases than the following I-cache flush?

arch/arm64/mm/flush.c line 132

Quoted 8 lines
arch/arm64/mm/flush.c new file +8 -0
+		set_bit(PG_dcache_clean, &page->flags);
+	}
+}
+EXPORT_SYMBOL(flush_dcache_page);
+
+void __flush_anon_page(struct vm_area_struct *vma, struct page *page, unsigned long vmaddr)
+{
+}

Note that the __flush_dcache_page(mapping, page) in flush_dcache_page() above is called when page is an anonymous page (since mapping == NULL in this case). If the call to __flush_dcache_page() is right above, it should be needed here as well?

arch/arm64/mm/flush.c line 138

Quoted 8 lines
arch/arm64/mm/flush.c new file +6 -0
+
+/*
+ * Additional functions defined in assembly.
+ */
+EXPORT_SYMBOL(flush_cache_all);
+EXPORT_SYMBOL(flush_icache_range);

- Simon

author maintainer
#41 lore raw

Re: [PATCH v3 09/31] arm64: Cache maintenance routines

Hi Simon,

Quoted 12 lines · Simon Baatz

arch/arm64/include/asm/cacheflush.h line 131

Quoted 8 lines · Catalin Marinas
arch/arm64/include/asm/cacheflush.h new file +8 -0
+#define ARCH_HAS_FLUSH_ANON_PAGE
+static inline void flush_anon_page(struct vm_area_struct *vma,
+                      struct page *page, unsigned long vmaddr)
+{
+     extern void __flush_anon_page(struct vm_area_struct *vma,
+                             struct page *, unsigned long);
+     if (PageAnon(page))
+             __flush_anon_page(vma, page, vmaddr);

__flush_anon_page() does nothing. Shouldn't this be removed as well?

Yes, good point.

Quoted 48 lines
Quoted 33 lines
arch/arm64/mm/flush.c new file +33 -0
+void __flush_dcache_page(struct address_space *mapping, struct page *page)
+{
+     __flush_dcache_area(page_address(page), PAGE_SIZE);
+}
+
+void __sync_icache_dcache(pte_t pte)
+{
+     unsigned long pfn;
+     struct page *page;
+
+     pfn = pte_pfn(pte);
+     if (!pfn_valid(pfn))
+             return;
+
+     page = pfn_to_page(pfn);
+     if (!test_and_set_bit(PG_dcache_clean, &page->flags))
+             __flush_dcache_page(NULL, page);
+     __flush_icache_all();
+}
+
+/*
+ * Ensure cache coherency between kernel mapping and userspace mapping of this
+ * page.
+ */
+void flush_dcache_page(struct page *page)
+{
+     struct address_space *mapping;
+
+     /*
+      * The zero page is never written to, so never has any dirty cache
+      * lines, and therefore never needs to be flushed.
+      */
+     if (page == ZERO_PAGE(0))

arch/arm64/mm/flush.c line 124

Quoted 10 lines
arch/arm64/mm/flush.c new file +10 -0
+             return;
+
+     mapping = page_mapping(page);
+
+     if (mapping && !mapping_mapped(mapping))
+             clear_bit(PG_dcache_clean, &page->flags);
+     else {
+             __flush_dcache_page(mapping, page);
+             if (mapping)
+                     __flush_icache_all();

Is this necessary to ensure I/D coherency? Then, I would have expected

Quoted 6 lines
                if (mapping) {
                        __flush_dcache_page(mapping, page);
                        __flush_icache_all();
                }

similar to __sync_icache_dcache() above.

We don't want to do additional flushing if !mapping_mapped() as the page isn't mapped in user space. In this case we defer the flushing until __sync_icache_dcache().

The other case is for anonymous pages where mapping == NULL. Here we don't defer the D-cache flush and do it directly. The I-cache, if needed, is handled later in __sync_icache_dcache(). This was based on the idea that this case is mainly for the args/env page which is mapped shortly after anyway, so not worth deferring. On AArch64, I don't think it makes any difference. Maybe a slight improvement (at least in clarity) in flush_dcache_page():

	if (mapping && mapping_mapped(mapping)) {
		__flush_dcache_page(page);
		__flush_icache_all();
		set_bit(PG_dcache_clean, &page->flags);
	} else {
		clear_bit(PG_dcache_clean, &page->flags);
	}

In this case the anonymous page flushing is deferred to __sync_icache_dcache().

Quoted 2 lines

What is the reason why the D-cache flush is done in different cases than the following I-cache flush?

For __sync_icache_dcache(), we need to handle the situation where the page mapped into user space has been cleaned (D-cache) but there may be stale data in the I-cache. I think this can only happen with an ASID-tagged VIVT I-cache configuration (which is allowed on AArch64) if an existing page has been unmapped and the same virtual address remapped (withing the same mm context) to a different page that had been cleaned previously. We could optimise the __sync_icache_dcache() as below:

	if (!test_and_set_bit(PG_dcache_clean, &page->flags)) {
		__flush_dcache_page(page);
		__flush_icache_all();
	} else if (icache_is_aivivt()) {
		__flush_icache_all();
	}
Quoted 6 lines
Quoted 6 lines
arch/arm64/mm/flush.c new file +6 -0
+             set_bit(PG_dcache_clean, &page->flags);
+     }
+}
+EXPORT_SYMBOL(flush_dcache_page);
+
+void __flush_anon_page(struct vm_area_struct *vma, struct page *page, unsigned long vmaddr)
Quoted 8 lines

Review

Quoted 2 lines
(quoted diff) +2 -0
+{
+}

Note that the __flush_dcache_page(mapping, page) in flush_dcache_page() above is called when page is an anonymous page (since mapping == NULL in this case). If the call to __flush_dcache_page() is right above, it should be needed here as well?

flush_anon_page() is called when the kernel needs to access an anonymous page. Given that the D-cache behaves like a PIPT, there is no need for additional flushing here. The flush_dcache_page() call was based on the assumption that such page needs flushing anyway and it's not worth deferring. But the code may be easier to understand as I suggested above (and slightly more optimal for the VIPT I-cache case).

It looks like any other architecture does something different here.

Signature · 1 line
Catalin
#42 lore raw

Re: [PATCH v3 09/31] arm64: Cache maintenance routines

Hi Catalin,

Quoted 76 lines · Catalin Marinas
Quoted 49 lines
Quoted 34 lines
arch/arm64/mm/flush.c new file +33 -0
+void __flush_dcache_page(struct address_space *mapping, struct page *page)
+{
+     __flush_dcache_area(page_address(page), PAGE_SIZE);
+}
+
+void __sync_icache_dcache(pte_t pte)
+{
+     unsigned long pfn;
+     struct page *page;
+
+     pfn = pte_pfn(pte);
+     if (!pfn_valid(pfn))
+             return;
+
+     page = pfn_to_page(pfn);
+     if (!test_and_set_bit(PG_dcache_clean, &page->flags))
+             __flush_dcache_page(NULL, page);
+     __flush_icache_all();
+}
+
+/*
+ * Ensure cache coherency between kernel mapping and userspace mapping of this
+ * page.
+ */
+void flush_dcache_page(struct page *page)
+{
+     struct address_space *mapping;
+
+     /*
+      * The zero page is never written to, so never has any dirty cache
+      * lines, and therefore never needs to be flushed.
+      */
+     if (page == ZERO_PAGE(0))

arch/arm64/mm/flush.c line 124

Quoted 10 lines
arch/arm64/mm/flush.c new file +10 -0
+             return;
+
+     mapping = page_mapping(page);
+
+     if (mapping && !mapping_mapped(mapping))
+             clear_bit(PG_dcache_clean, &page->flags);
+     else {
+             __flush_dcache_page(mapping, page);
+             if (mapping)
+                     __flush_icache_all();

Is this necessary to ensure I/D coherency? Then, I would have expected

Quoted 6 lines
                if (mapping) {
                        __flush_dcache_page(mapping, page);
                        __flush_icache_all();
                }

similar to __sync_icache_dcache() above.

We don't want to do additional flushing if !mapping_mapped() as the page isn't mapped in user space. In this case we defer the flushing until __sync_icache_dcache().

The other case is for anonymous pages where mapping == NULL. Here we don't defer the D-cache flush and do it directly. The I-cache, if needed, is handled later in __sync_icache_dcache(). This was based on the idea that this case is mainly for the args/env page which is mapped shortly after anyway, so not worth deferring. On AArch64, I don't think it makes any difference. Maybe a slight improvement (at least in clarity) in flush_dcache_page():

	if (mapping && mapping_mapped(mapping)) {
		__flush_dcache_page(page);
		__flush_icache_all();
		set_bit(PG_dcache_clean, &page->flags);
	} else {
		clear_bit(PG_dcache_clean, &page->flags);
	}
Quoted 2 lines

In this case the anonymous page flushing is deferred to __sync_icache_dcache().

Yes, I think this is much clearer. It makes clear that the D-cache flush is done to avoid I/D incoherencies. Previously, the obvious question was "Why do we flush only the D-cache in some situations given that it essentially behaves like a PIPT cache?" (the motivation for this became only clear to me after your explanation.)

However, the reason why this was an obvious question for me is
interesting: I think the main use case you had in mind does not happen since about five years (since commit b6a2fe, "mm: variable length argument support"). And I had a completely different main use case in mind.

I reckon that the use case you refer to is the use in fs/exec.c? Copying arg/env was changed in the commit mentioned above. This also changed the use of flush_dcache_page() (which is not supposed to handle anon pages) into flush_kernel_dcache_page() (which is supposed to handle kernel modified user pages, i.e. also anon pages).

Nevertheless, the __flush_dcache_page(mapping, page) in the mapping==NULL case is absoluty necessary for aliasing D-caches on arm for the use case I had in mind (which does not apply to arm64 and thus my question).

In case of direct I/O (and probably also in other cases like SG_IO) the block layer will see pages from get_user_pages() directly, i.e. also anonymous pages. Many drivers (especially emulated storage drivers like dm-crypt) use flush_dcache_page() after modifying a page. Although flush_dcache_page() is not even supposed to handle anonymous pages, it flushes the kernel mapping of the page because of this code line and everything is well on aliasing D-caches.

Ironically, flush_kernel_dcache_page(), which is specifically designed to handle this case, does not on arm. Thus, those few parts of the kernel which use flush_kernel_dcache_page() may fail horribly (for example the scatterlist memory iterator API, see [1]).

Back to arm64 (and possibly to arm with non-aliasing D-caches?), this also means that the saved D-cache flush in the anonymous page case is not only a slight improvement on clarity, but may avoid a considerable number of D-cache flushes in some I/O situations. (If it is still correct that there are no problems with the I-cache for this use case.)

If now we could additionally avoid to flush the entire I-cache for every page in direct I/O operations with user mapped page cache pages (e.g. direct I/O read into an mmap region)...

Quoted 11 lines
Quoted 2 lines

What is the reason why the D-cache flush is done in different cases than the following I-cache flush?

For __sync_icache_dcache(), we need to handle the situation where the page mapped into user space has been cleaned (D-cache) but there may be stale data in the I-cache. I think this can only happen with an ASID-tagged VIVT I-cache configuration (which is allowed on AArch64) if an existing page has been unmapped and the same virtual address remapped (withing the same mm context) to a different page that had been cleaned previously. We could optimise the __sync_icache_dcache() as below:

Quoted 6 lines
	if (!test_and_set_bit(PG_dcache_clean, &page->flags)) {
		__flush_dcache_page(page);
		__flush_icache_all();
	} else if (icache_is_aivivt()) {
		__flush_icache_all();
	}

Sorry, this is out of my depth. I think I don't really understand the cases leading to I/D incoherency.

- Simon

[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2012-July/111393.html

PS: You did not mention the following comment from my mail. It was easy to overlook. Just to make sure you did not miss it:

Quoted 5 lines
arch/arm64/mm/cache.S new file +0 -0
new file mode 100644
index 0000000..3df0aa7

...

Quoted 2 lines

+/*
+ * __flush_kern_dcache_page(kaddr)

Should be: __flush_dcache_area(kaddr,size)

Quoted 4 lines

+ *
+ * Ensure that the data held in the page kaddr is written back
to the
+ * page in question.

s/page/area

Quoted 8 lines

+ *
+ * - kaddr - kernel address
+ * - size - size in question
+ */

arch/arm64/mm/cache.S new file +4 -0
+ENTRY(__flush_dcache_area)
+	dcache_line_size x2, x3
+	add	x1, x0, x1
+
author maintainer
#43 lore raw

Re: [PATCH v3 09/31] arm64: Cache maintenance routines

Quoted 91 lines · Simon Baatz
Quoted 75 lines · Catalin Marinas
Quoted 48 lines
Quoted 33 lines
arch/arm64/mm/flush.c new file +33 -0
+void __flush_dcache_page(struct address_space *mapping, struct page *page)
+{
+     __flush_dcache_area(page_address(page), PAGE_SIZE);
+}
+
+void __sync_icache_dcache(pte_t pte)
+{
+     unsigned long pfn;
+     struct page *page;
+
+     pfn = pte_pfn(pte);
+     if (!pfn_valid(pfn))
+             return;
+
+     page = pfn_to_page(pfn);
+     if (!test_and_set_bit(PG_dcache_clean, &page->flags))
+             __flush_dcache_page(NULL, page);
+     __flush_icache_all();
+}
+
+/*
+ * Ensure cache coherency between kernel mapping and userspace mapping of this
+ * page.
+ */
+void flush_dcache_page(struct page *page)
+{
+     struct address_space *mapping;
+
+     /*
+      * The zero page is never written to, so never has any dirty cache
+      * lines, and therefore never needs to be flushed.
+      */
+     if (page == ZERO_PAGE(0))

arch/arm64/mm/flush.c line 124

Quoted 10 lines
arch/arm64/mm/flush.c new file +10 -0
+             return;
+
+     mapping = page_mapping(page);
+
+     if (mapping && !mapping_mapped(mapping))
+             clear_bit(PG_dcache_clean, &page->flags);
+     else {
+             __flush_dcache_page(mapping, page);
+             if (mapping)
+                     __flush_icache_all();

Is this necessary to ensure I/D coherency? Then, I would have expected

Quoted 6 lines
                if (mapping) {
                        __flush_dcache_page(mapping, page);
                        __flush_icache_all();
                }

similar to __sync_icache_dcache() above.

We don't want to do additional flushing if !mapping_mapped() as the page isn't mapped in user space. In this case we defer the flushing until __sync_icache_dcache().

The other case is for anonymous pages where mapping == NULL. Here we don't defer the D-cache flush and do it directly. The I-cache, if needed, is handled later in __sync_icache_dcache(). This was based on the idea that this case is mainly for the args/env page which is mapped shortly after anyway, so not worth deferring. On AArch64, I don't think it makes any difference. Maybe a slight improvement (at least in clarity) in flush_dcache_page():

	if (mapping && mapping_mapped(mapping)) {
		__flush_dcache_page(page);
		__flush_icache_all();
		set_bit(PG_dcache_clean, &page->flags);
	} else {
		clear_bit(PG_dcache_clean, &page->flags);
	}
Quoted 2 lines

In this case the anonymous page flushing is deferred to __sync_icache_dcache().

Yes, I think this is much clearer. It makes clear that the D-cache flush is done to avoid I/D incoherencies. Previously, the obvious question was "Why do we flush only the D-cache in some situations given that it essentially behaves like a PIPT cache?" (the motivation for this became only clear to me after your explanation.)

However, the reason why this was an obvious question for me is
interesting: I think the main use case you had in mind does not happen since about five years (since commit b6a2fe, "mm: variable length argument support"). And I had a completely different main use case in mind.

Quoted 5 lines

I reckon that the use case you refer to is the use in fs/exec.c? Copying arg/env was changed in the commit mentioned above. This also changed the use of flush_dcache_page() (which is not supposed to handle anon pages) into flush_kernel_dcache_page() (which is supposed to handle kernel modified user pages, i.e. also anon pages).

That's what I was thinking about, thanks for the pointer. I still get a flush_dcache_page() call (on the source page) from copy_strings() via get_user_page() but with my changes above it doesn't trigger any cache flushing (which is correct).

Quoted 7 lines

In case of direct I/O (and probably also in other cases like SG_IO) the block layer will see pages from get_user_pages() directly, i.e. also anonymous pages. Many drivers (especially emulated storage drivers like dm-crypt) use flush_dcache_page() after modifying a page. Although flush_dcache_page() is not even supposed to handle anonymous pages, it flushes the kernel mapping of the page because of this code line and everything is well on aliasing D-caches.

According to the cachetlb.txt document (though not sure architecture ports follow it entirely), flush_dcache_page() deliberately shouldn't follow anonymous pages. But it seems that we do it on ARM (maybe as an alternative to flush_kernel_dcache_page()).

Quoted 6 lines

Back to arm64 (and possibly to arm with non-aliasing D-caches?), this also means that the saved D-cache flush in the anonymous page case is not only a slight improvement on clarity, but may avoid a considerable number of D-cache flushes in some I/O situations. (If it is still correct that there are no problems with the I-cache for this use case.)

The I-cache would be needed if the kernel modifies an executable user page. But I don't see a case for this yet. So with non-aliasing D-cache the flush_kernel_dcache_page() can be a nop.

Quoted 3 lines

If now we could additionally avoid to flush the entire I-cache for every page in direct I/O operations with user mapped page cache pages (e.g. direct I/O read into an mmap region)...

If the page is already mapped, we don't have a later hook to be able to flush the caches, so we do it here. We can avoid the I-cache operation only if we are sure that the user would not execute code from such page. IOW the direct I/O wouldn't write any instructions.

The powerpc implementation of flush_dcache_page() doesn't even check for the existence of a mapping, it always marks the page as dirty. We can do the same on arm64 (only leave the clear_bit part of the condition) as long as we know that the kernel wouldn't write new code into a page that is already mapped.

Quoted 18 lines
Quoted 11 lines
Quoted 2 lines

What is the reason why the D-cache flush is done in different cases than the following I-cache flush?

For __sync_icache_dcache(), we need to handle the situation where the page mapped into user space has been cleaned (D-cache) but there may be stale data in the I-cache. I think this can only happen with an ASID-tagged VIVT I-cache configuration (which is allowed on AArch64) if an existing page has been unmapped and the same virtual address remapped (withing the same mm context) to a different page that had been cleaned previously. We could optimise the __sync_icache_dcache() as below:

Quoted 6 lines
	if (!test_and_set_bit(PG_dcache_clean, &page->flags)) {
		__flush_dcache_page(page);
		__flush_icache_all();
	} else if (icache_is_aivivt()) {
		__flush_icache_all();
	}
Quoted 2 lines

Sorry, this is out of my depth. I think I don't really understand the cases leading to I/D incoherency.

That's with a VIVT I-cache where a process mapped some file at a virtual address, unmapped it and remapped a different file at the same virtual address. For the latter file, the page may have already been cleaned by a different process but our process has stale I-cache entries from the previous mapping. With physically tagged I-cache, this wouldn't be necessary.

Signature · 1 line
Catalin
#44 lore raw

Re: [PATCH v3 09/31] arm64: Cache maintenance routines

Quoted 24 lines · Catalin Marinas
Quoted 1 line · Simon Baatz

On Wed, Sep 12, 2012 at 10:29:54AM +0100, Catalin Marinas wrote:

...

Quoted 7 lines

In case of direct I/O (and probably also in other cases like SG_IO) the block layer will see pages from get_user_pages() directly, i.e. also anonymous pages. Many drivers (especially emulated storage drivers like dm-crypt) use flush_dcache_page() after modifying a page. Although flush_dcache_page() is not even supposed to handle anonymous pages, it flushes the kernel mapping of the page because of this code line and everything is well on aliasing D-caches.

According to the cachetlb.txt document (though not sure architecture ports follow it entirely), flush_dcache_page() deliberately shouldn't follow anonymous pages. But it seems that we do it on ARM (maybe as an alternative to flush_kernel_dcache_page()).

Quoted 6 lines

Back to arm64 (and possibly to arm with non-aliasing D-caches?), this also means that the saved D-cache flush in the anonymous page case is not only a slight improvement on clarity, but may avoid a considerable number of D-cache flushes in some I/O situations. (If it is still correct that there are no problems with the I-cache for this use case.)

Quoted 3 lines

The I-cache would be needed if the kernel modifies an executable user page. But I don't see a case for this yet. So with non-aliasing D-cache the flush_kernel_dcache_page() can be a nop.

Ok, this is true for anon pages. But, if we really need to do the D/I flush for user mapped page cache pages in flush_dcache_page() then it should also be done by flush_kernel_dcache_page(). In general, both flush_dcache_page() and flush_kernel_dcache_page() need to handle the case in which the kernel modifies such a page. (This means that in effect, both functions should be the same in the arm64 case.)

Quoted 9 lines
Quoted 3 lines

If now we could additionally avoid to flush the entire I-cache for every page in direct I/O operations with user mapped page cache pages (e.g. direct I/O read into an mmap region)...

If the page is already mapped, we don't have a later hook to be able to flush the caches, so we do it here. We can avoid the I-cache operation only if we are sure that the user would not execute code from such page. IOW the direct I/O wouldn't write any instructions.

Quoted 5 lines

The powerpc implementation of flush_dcache_page() doesn't even check for the existence of a mapping, it always marks the page as dirty. We can do the same on arm64 (only leave the clear_bit part of the condition) as long as we know that the kernel wouldn't write new code into a page that is already mapped.

Yes, but how do we know?

- Simon

author maintainer
#45 lore raw

PATCH v3 10/31 arm64: TLB maintenance functionality

In reply to Catalin Marinas

This patch adds the TLB maintenance functions. There is no distinction made between the I and D TLBs. TLB maintenance operations are automatically broadcast between CPUs in hardware. The inner-shareable operations are always present, even on UP systems.

NOTE: Large part of this patch to be dropped once Peter Z's generic mmu_gather patches are merged.

---
 arch/arm64/include/asm/tlb.h      |  190 +++++++++++++++++++++++++++++++++++++
 arch/arm64/include/asm/tlbflush.h |  122 ++++++++++++++++++++++++
 arch/arm64/mm/tlb.S               |   71 ++++++++++++++
 3 files changed, 383 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm64/include/asm/tlb.h
 create mode 100644 arch/arm64/include/asm/tlbflush.h
 create mode 100644 arch/arm64/mm/tlb.S
arch/arm64/include/asm/tlb.h new file +190 -0
new file mode 100644
index 0000000..654f096
@@ -0,0 +1,190 @@
+/*
+ * Based on arch/arm/include/asm/tlb.h
+ *
+ * Copyright (C) 2002 Russell King
+ * Copyright (C) 2012 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_TLB_H
+#define __ASM_TLB_H
+
+#include <linux/pagemap.h>
+#include <linux/swap.h>
+
+#include <asm/pgalloc.h>
+#include <asm/tlbflush.h>
+
+#define MMU_GATHER_BUNDLE	8
+
+/*
+ * TLB handling.  This allows us to remove pages from the page
+ * tables, and efficiently handle the TLB issues.
+ */
+struct mmu_gather {
+	struct mm_struct	*mm;
+	unsigned int		fullmm;
+	struct vm_area_struct	*vma;
+	unsigned long		range_start;
+	unsigned long		range_end;
+	unsigned int		nr;
+	unsigned int		max;
+	struct page		**pages;
+	struct page		*local[MMU_GATHER_BUNDLE];
+};
+
+/*
+ * This is unnecessarily complex.  There's three ways the TLB shootdown
+ * code is used:
+ *  1. Unmapping a range of vmas.  See zap_page_range(), unmap_region().
+ *     tlb->fullmm = 0, and tlb_start_vma/tlb_end_vma will be called.
+ *     tlb->vma will be non-NULL.
+ *  2. Unmapping all vmas.  See exit_mmap().
+ *     tlb->fullmm = 1, and tlb_start_vma/tlb_end_vma will be called.
+ *     tlb->vma will be non-NULL.  Additionally, page tables will be freed.
+ *  3. Unmapping argument pages.  See shift_arg_pages().
+ *     tlb->fullmm = 0, but tlb_start_vma/tlb_end_vma will not be called.
+ *     tlb->vma will be NULL.
+ */
+static inline void tlb_flush(struct mmu_gather *tlb)
+{
+	if (tlb->fullmm || !tlb->vma)
+		flush_tlb_mm(tlb->mm);
+	else if (tlb->range_end > 0) {
+		flush_tlb_range(tlb->vma, tlb->range_start, tlb->range_end);
+		tlb->range_start = TASK_SIZE;
+		tlb->range_end = 0;
+	}
+}
+
+static inline void tlb_add_flush(struct mmu_gather *tlb, unsigned long addr)
+{
+	if (!tlb->fullmm) {
+		if (addr < tlb->range_start)
+			tlb->range_start = addr;
+		if (addr + PAGE_SIZE > tlb->range_end)
+			tlb->range_end = addr + PAGE_SIZE;
+	}
+}
+
+static inline void __tlb_alloc_page(struct mmu_gather *tlb)
+{
+	unsigned long addr = __get_free_pages(GFP_NOWAIT | __GFP_NOWARN, 0);
+
+	if (addr) {
+		tlb->pages = (void *)addr;
+		tlb->max = PAGE_SIZE / sizeof(struct page *);
+	}
+}
+
+static inline void tlb_flush_mmu(struct mmu_gather *tlb)
+{
+	tlb_flush(tlb);
+	free_pages_and_swap_cache(tlb->pages, tlb->nr);
+	tlb->nr = 0;
+	if (tlb->pages == tlb->local)
+		__tlb_alloc_page(tlb);
+}
+
+static inline void
+tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned int fullmm)
+{
+	tlb->mm = mm;
+	tlb->fullmm = fullmm;
+	tlb->vma = NULL;
+	tlb->max = ARRAY_SIZE(tlb->local);
+	tlb->pages = tlb->local;
+	tlb->nr = 0;
+	__tlb_alloc_page(tlb);
+}
+
+static inline void
+tlb_finish_mmu(struct mmu_gather *tlb, unsigned long start, unsigned long end)
+{
+	tlb_flush_mmu(tlb);
+
+	/* keep the page table cache within bounds */
+	check_pgt_cache();
+
+	if (tlb->pages != tlb->local)
+		free_pages((unsigned long)tlb->pages, 0);
+}
+
+/*
+ * Memorize the range for the TLB flush.
+ */
+static inline void
+tlb_remove_tlb_entry(struct mmu_gather *tlb, pte_t *ptep, unsigned long addr)
+{
+	tlb_add_flush(tlb, addr);
+}
+
+/*
+ * In the case of tlb vma handling, we can optimise these away in the
+ * case where we're doing a full MM flush.  When we're doing a munmap,
+ * the vmas are adjusted to only cover the region to be torn down.
+ */
+static inline void
+tlb_start_vma(struct mmu_gather *tlb, struct vm_area_struct *vma)
+{
+	if (!tlb->fullmm) {
+		tlb->vma = vma;
+		tlb->range_start = TASK_SIZE;
+		tlb->range_end = 0;
+	}
+}
+
+static inline void
+tlb_end_vma(struct mmu_gather *tlb, struct vm_area_struct *vma)
+{
+	if (!tlb->fullmm)
+		tlb_flush(tlb);
+}
+
+static inline int __tlb_remove_page(struct mmu_gather *tlb, struct page *page)
+{
+	tlb->pages[tlb->nr++] = page;
+	VM_BUG_ON(tlb->nr > tlb->max);
+	return tlb->max - tlb->nr;
+}
+
+static inline void tlb_remove_page(struct mmu_gather *tlb, struct page *page)
+{
+	if (!__tlb_remove_page(tlb, page))
+		tlb_flush_mmu(tlb);
+}
+
+static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte,
+	unsigned long addr)
+{
+	pgtable_page_dtor(pte);
+	tlb_add_flush(tlb, addr);
+	tlb_remove_page(tlb, pte);
+}
+
+#ifndef CONFIG_ARM64_64K_PAGES
+static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmdp,
+				  unsigned long addr)
+{
+	tlb_add_flush(tlb, addr);
+	tlb_remove_page(tlb, virt_to_page(pmdp));
+}
+#endif
+
+#define pte_free_tlb(tlb, ptep, addr)	__pte_free_tlb(tlb, ptep, addr)
+#define pmd_free_tlb(tlb, pmdp, addr)	__pmd_free_tlb(tlb, pmdp, addr)
+#define pud_free_tlb(tlb, pudp, addr)	pud_free((tlb)->mm, pudp)
+
+#define tlb_migrate_finish(mm)		do { } while (0)
+
+#endif
arch/arm64/include/asm/tlbflush.h new file +122 -0

122 lines not on this page · raw message

arch/arm64/mm/tlb.S new file +71 -0

71 lines not on this page · raw message

maintainer Acked-by on v3 10/31
#46 lore raw

Re: [PATCH v3 10/31] arm64: TLB maintenance functionality

Quoted 6 lines · Catalin Marinas

This patch adds the TLB maintenance functions. There is no distinction made between the I and D TLBs. TLB maintenance operations are automatically broadcast between CPUs in hardware. The inner-shareable operations are always present, even on UP systems.

Quoted 6 lines

NOTE: Large part of this patch to be dropped once Peter Z's generic mmu_gather patches are merged.

author maintainer
#47 lore raw

PATCH v3 11/31 arm64: IRQ handling

In reply to Catalin Marinas

From: Marc Zyngier <[email protected]>

This patch adds the support for IRQ handling. The actual interrupt controller will be part of a separate patch (going into drivers/irqchip/).

---
 arch/arm64/include/asm/hardirq.h  |   47 +++++++++++++++++++
 arch/arm64/include/asm/irq.h      |    8 +++
 arch/arm64/include/asm/irqflags.h |   91 +++++++++++++++++++++++++++++++++++++
 arch/arm64/kernel/irq.c           |   84 ++++++++++++++++++++++++++++++++++
 4 files changed, 230 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm64/include/asm/hardirq.h
 create mode 100644 arch/arm64/include/asm/irq.h
 create mode 100644 arch/arm64/include/asm/irqflags.h
 create mode 100644 arch/arm64/kernel/irq.c
arch/arm64/include/asm/hardirq.h new file +47 -0
new file mode 100644
index 0000000..c6c9514
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2012 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_HARDIRQ_H
+#define __ASM_HARDIRQ_H
+
+#include <linux/cache.h>
+#include <linux/threads.h>
+#include <asm/irq.h>
+
+typedef struct {
+	unsigned int __softirq_pending;
+} ____cacheline_aligned irq_cpustat_t;
+
+#include <linux/irq_cpustat.h>	/* Standard mappings for irq_cpustat_t above */
+
+#define __inc_irq_stat(cpu, member)	__IRQ_STAT(cpu, member)++
+#define __get_irq_stat(cpu, member)	__IRQ_STAT(cpu, member)
+
+#ifdef CONFIG_SMP
+u64 smp_irq_stat_cpu(unsigned int cpu);
+#define arch_irq_stat_cpu	smp_irq_stat_cpu
+#endif
+
+#define __ARCH_IRQ_EXIT_IRQS_DISABLED	1
+
+static inline void ack_bad_irq(unsigned int irq)
+{
+	extern unsigned long irq_err_count;
+	irq_err_count++;
+}
+
+extern void handle_IRQ(unsigned int, struct pt_regs *);
+
+#endif /* __ASM_HARDIRQ_H */
arch/arm64/include/asm/irq.h new file +8 -0
new file mode 100644
index 0000000..a4e1cad
@@ -0,0 +1,8 @@
+#ifndef __ASM_IRQ_H
+#define __ASM_IRQ_H
+
+#include <asm-generic/irq.h>
+
+extern void (*handle_arch_irq)(struct pt_regs *);
+
+#endif
arch/arm64/include/asm/irqflags.h new file +91 -0

91 lines not on this page · raw message

arch/arm64/kernel/irq.c new file +84 -0

84 lines not on this page · raw message

maintainer
#48 lore raw

Re: [PATCH v3 11/31] arm64: IRQ handling

arch/arm64/include/asm/hardirq.h line 30

Quoted 2 lines · Catalin Marinas
arch/arm64/include/asm/hardirq.h new file +2 -0
+#define __inc_irq_stat(cpu, member)	__IRQ_STAT(cpu, member)++
+#define __get_irq_stat(cpu, member)	__IRQ_STAT(cpu, member)

Isn't this something that the IRQ core code already keeps track of?

Quoted 7 lines
arch/arm64/include/asm/hardirq.h new file +1 -0
+#endif /* __ASM_HARDIRQ_H */
arch/arm64/include/asm/irq.h new file +0 -0
new file mode 100644
index 0000000..a4e1cad

arch/arm64/include/asm/irq.h line 8

Quoted 8 lines
arch/arm64/include/asm/irq.h new file +8 -0
@@ -0,0 +1,8 @@
+#ifndef __ASM_IRQ_H
+#define __ASM_IRQ_H
+
+#include <asm-generic/irq.h>
+
+extern void (*handle_arch_irq)(struct pt_regs *);
+
+#endif

Is this one still needed?

Arnd

author maintainer
#49 lore raw

Re: [PATCH v3 11/31] arm64: IRQ handling

Quoted 6 lines · Arnd Bergmann

arch/arm64/include/asm/hardirq.h line 30

Quoted 2 lines · Catalin Marinas
arch/arm64/include/asm/hardirq.h new file +2 -0
+#define __inc_irq_stat(cpu, member)	__IRQ_STAT(cpu, member)++
+#define __get_irq_stat(cpu, member)	__IRQ_STAT(cpu, member)

Isn't this something that the IRQ core code already keeps track of?

That's for the IPIs which are handled directly by the arch code. We don't even allocate irq descriptors for them.

Quoted 9 lines
Quoted 9 lines
arch/arm64/include/asm/hardirq.h new file +1 -0
+#endif /* __ASM_HARDIRQ_H */
arch/arm64/include/asm/irq.h new file +2 -0
new file mode 100644
index 0000000..a4e1cad
@@ -0,0 +1,8 @@
+#ifndef __ASM_IRQ_H
+#define __ASM_IRQ_H
Quoted 8 lines

arch/arm64/include/asm/irq.h line 8

Quoted 6 lines
arch/arm64/include/asm/irq.h new file +6 -0
+
+#include <asm-generic/irq.h>
+
+extern void (*handle_arch_irq)(struct pt_regs *);
+
+#endif

Is this one still needed?

Yes. It's initialised by the GIC code (called via of_irq_init) and we want to allow different GIC versions (GICv2 used by the model currently but we would expect GICv3 with hardware).

Signature · 1 line
Catalin
author maintainer
#50 lore raw

PATCH v3 12/31 arm64: Atomic operations

In reply to Catalin Marinas

This patch introduces the atomic, mutex and futex operations. Many atomic operations use the load-acquire and store-release operations which imply barriers, avoiding the need for explicit DMB.

---
 arch/arm64/include/asm/atomic.h |  305 +++++++++++++++++++++++++++++++++++++++
 arch/arm64/include/asm/futex.h  |  136 +++++++++++++++++
 2 files changed, 441 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm64/include/asm/atomic.h
 create mode 100644 arch/arm64/include/asm/futex.h
arch/arm64/include/asm/atomic.h new file +305 -0
new file mode 100644
index 0000000..407717b
@@ -0,0 +1,305 @@
+/*
+ * Based on arch/arm/include/asm/atomic.h
+ *
+ * Copyright (C) 1996 Russell King.
+ * Copyright (C) 2002 Deep Blue Solutions Ltd.
+ * Copyright (C) 2012 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_ATOMIC_H
+#define __ASM_ATOMIC_H
+
+#include <linux/compiler.h>
+#include <linux/types.h>
+
+#include <asm/barrier.h>
+#include <asm/cmpxchg.h>
+
+#define ATOMIC_INIT(i)	{ (i) }
+
+#ifdef __KERNEL__
+
+/*
+ * On ARM, ordinary assignment (str instruction) doesn't clear the local
+ * strex/ldrex monitor on some implementations. The reason we can use it for
+ * atomic_set() is the clrex or dummy strex done on every exception return.
+ */
+#define atomic_read(v)	(*(volatile int *)&(v)->counter)
+#define atomic_set(v,i)	(((v)->counter) = (i))
+
+/*
+ * AArch64 UP and SMP safe atomic ops.  We use load exclusive and
+ * store exclusive to ensure that these are atomic.  We may loop
+ * to ensure that the update happens.
+ */
+static inline void atomic_add(int i, atomic_t *v)
+{
+	unsigned long tmp;
+	int result;
+
+	asm volatile("// atomic_add\n"
+"1:	ldxr	%w0, [%3]\n"
+"	add	%w0, %w0, %w4\n"
+"	stxr	%w1, %w0, [%3]\n"
+"	cbnz	%w1, 1b"
+	: "=&r" (result), "=&r" (tmp), "+o" (v->counter)
+	: "r" (&v->counter), "Ir" (i)
+	: "cc");
+}
+
+static inline int atomic_add_return(int i, atomic_t *v)
+{
+	unsigned long tmp;
+	int result;
+
+	asm volatile("// atomic_add_return\n"
+"1:	ldaxr	%w0, [%3]\n"
+"	add	%w0, %w0, %w4\n"
+"	stlxr	%w1, %w0, [%3]\n"
+"	cbnz	%w1, 1b"
+	: "=&r" (result), "=&r" (tmp), "+o" (v->counter)
+	: "r" (&v->counter), "Ir" (i)
+	: "cc");
+
+	return result;
+}
+
+static inline void atomic_sub(int i, atomic_t *v)
+{
+	unsigned long tmp;
+	int result;
+
+	asm volatile("// atomic_sub\n"
+"1:	ldxr	%w0, [%3]\n"
+"	sub	%w0, %w0, %w4\n"
+"	stxr	%w1, %w0, [%3]\n"
+"	cbnz	%w1, 1b"
+	: "=&r" (result), "=&r" (tmp), "+o" (v->counter)
+	: "r" (&v->counter), "Ir" (i)
+	: "cc");
+}
+
+static inline int atomic_sub_return(int i, atomic_t *v)
+{
+	unsigned long tmp;
+	int result;
+
+	asm volatile("// atomic_sub_return\n"
+"1:	ldaxr	%w0, [%3]\n"
+"	sub	%w0, %w0, %w4\n"
+"	stlxr	%w1, %w0, [%3]\n"
+"	cbnz	%w1, 1b"
+	: "=&r" (result), "=&r" (tmp), "+o" (v->counter)
+	: "r" (&v->counter), "Ir" (i)
+	: "cc");
+
+	return result;
+}
+
+static inline int atomic_cmpxchg(atomic_t *ptr, int old, int new)
+{
+	unsigned long tmp;
+	int oldval;
+
+	asm volatile("// atomic_cmpxchg\n"
+"1:	ldaxr	%w1, [%3]\n"
+"	cmp	%w1, %w4\n"
+"	b.ne	2f\n"
+"	stlxr	%w0, %w5, [%3]\n"
+"	cbnz	%w0, 1b\n"
+"2:"
+	: "=&r" (tmp), "=&r" (oldval), "+o" (ptr->counter)
+	: "r" (&ptr->counter), "Ir" (old), "r" (new)
+	: "cc");
+
+	return oldval;
+}
+
+static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr)
+{
+	unsigned long tmp, tmp2;
+
+	asm volatile("// atomic_clear_mask\n"
+"1:	ldxr	%0, [%3]\n"
+"	bic	%0, %0, %4\n"
+"	stxr	%w1, %0, [%3]\n"
+"	cbnz	%w1, 1b"
+	: "=&r" (tmp), "=&r" (tmp2), "+o" (*addr)
+	: "r" (addr), "Ir" (mask)
+	: "cc");
+}
+
+#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
+
+static inline int __atomic_add_unless(atomic_t *v, int a, int u)
+{
+	int c, old;
+
+	c = atomic_read(v);
+	while (c != u && (old = atomic_cmpxchg((v), c, c + a)) != c)
+		c = old;
+	return c;
+}
+
+#define atomic_inc(v)		atomic_add(1, v)
+#define atomic_dec(v)		atomic_sub(1, v)
+
+#define atomic_inc_and_test(v)	(atomic_add_return(1, v) == 0)
+#define atomic_dec_and_test(v)	(atomic_sub_return(1, v) == 0)
+#define atomic_inc_return(v)    (atomic_add_return(1, v))
+#define atomic_dec_return(v)    (atomic_sub_return(1, v))
+#define atomic_sub_and_test(i, v) (atomic_sub_return(i, v) == 0)
+
+#define atomic_add_negative(i,v) (atomic_add_return(i, v) < 0)
+
+#define smp_mb__before_atomic_dec()	smp_mb()
+#define smp_mb__after_atomic_dec()	smp_mb()
+#define smp_mb__before_atomic_inc()	smp_mb()
+#define smp_mb__after_atomic_inc()	smp_mb()
+
+/*
+ * 64-bit atomic operations.
+ */
+#define ATOMIC64_INIT(i) { (i) }
+
+#define atomic64_read(v)	(*(volatile long long *)&(v)->counter)
+#define atomic64_set(v,i)	(((v)->counter) = (i))
+
+static inline void atomic64_add(u64 i, atomic64_t *v)
+{
+	long result;
+	unsigned long tmp;
+
+	asm volatile("// atomic64_add\n"
+"1:	ldxr	%0, [%3]\n"
+"	add	%0, %0, %4\n"
+"	stxr	%w1, %0, [%3]\n"
+"	cbnz	%w1, 1b"
+	: "=&r" (result), "=&r" (tmp), "+o" (v->counter)
+	: "r" (&v->counter), "Ir" (i)
+	: "cc");
+}
+
+static inline long atomic64_add_return(long i, atomic64_t *v)
+{
+	long result;
+	unsigned long tmp;
+
+	asm volatile("// atomic64_add_return\n"
+"1:	ldaxr	%0, [%3]\n"
+"	add	%0, %0, %4\n"
+"	stlxr	%w1, %0, [%3]\n"
+"	cbnz	%w1, 1b"
+	: "=&r" (result), "=&r" (tmp), "+o" (v->counter)
+	: "r" (&v->counter), "Ir" (i)
+	: "cc");
+
+	return result;
+}
+
+static inline void atomic64_sub(u64 i, atomic64_t *v)
+{
+	long result;
+	unsigned long tmp;
+
+	asm volatile("// atomic64_sub\n"
+"1:	ldxr	%0, [%3]\n"
+"	sub	%0, %0, %4\n"
+"	stxr	%w1, %0, [%3]\n"
+"	cbnz	%w1, 1b"
+	: "=&r" (result), "=&r" (tmp), "+o" (v->counter)
+	: "r" (&v->counter), "Ir" (i)
+	: "cc");
+}
+
+static inline long atomic64_sub_return(long i, atomic64_t *v)
+{
+	long result;
+	unsigned long tmp;
+
+	asm volatile("// atomic64_sub_return\n"
+"1:	ldaxr	%0, [%3]\n"
+"	sub	%0, %0, %4\n"
+"	stlxr	%w1, %0, [%3]\n"
+"	cbnz	%w1, 1b"
+	: "=&r" (result), "=&r" (tmp), "+o" (v->counter)
+	: "r" (&v->counter), "Ir" (i)
+	: "cc");
+
+	return result;
+}
+
+static inline long atomic64_cmpxchg(atomic64_t *ptr, long old, long new)
+{
+	long oldval;
+	unsigned long res;
+
+	asm volatile("// atomic64_cmpxchg\n"
+"1:	ldaxr	%1, [%3]\n"
+"	cmp	%1, %4\n"
+"	b.ne	2f\n"
+"	stlxr	%w0, %5, [%3]\n"
+"	cbnz	%w0, 1b\n"
+"2:"
+	: "=&r" (res), "=&r" (oldval), "+o" (ptr->counter)
+	: "r" (&ptr->counter), "Ir" (old), "r" (new)
+	: "cc");
+
+	return oldval;
+}
+
+#define atomic64_xchg(v, new) (xchg(&((v)->counter), new))
+
+static inline long atomic64_dec_if_positive(atomic64_t *v)
+{
+	long result;
+	unsigned long tmp;
+
+	asm volatile("// atomic64_dec_if_positive\n"
+"1:	ldaxr	%0, [%3]\n"
+"	subs	%0, %0, #1\n"
+"	b.mi	2f\n"
+"	stlxr	%w1, %0, [%3]\n"
+"	cbnz	%w1, 1b\n"
+"2:"
+	: "=&r" (result), "=&r" (tmp), "+o" (v->counter)
+	: "r" (&v->counter)
+	: "cc");
+
+	return result;
+}
+
+static inline int atomic64_add_unless(atomic64_t *v, long a, long u)
+{
+	long c, old;
+
+	c = atomic64_read(v);
+	while (c != u && (old = atomic64_cmpxchg((v), c, c + a)) != c)
+		c = old;
+
+	return c != u;
+}
+
+#define atomic64_add_negative(a, v)	(atomic64_add_return((a), (v)) < 0)
+#define atomic64_inc(v)			atomic64_add(1LL, (v))
+#define atomic64_inc_return(v)		atomic64_add_return(1LL, (v))
+#define atomic64_inc_and_test(v)	(atomic64_inc_return(v) == 0)
+#define atomic64_sub_and_test(a, v)	(atomic64_sub_return((a), (v)) == 0)
+#define atomic64_dec(v)			atomic64_sub(1LL, (v))
+#define atomic64_dec_return(v)		atomic64_sub_return(1LL, (v))
+#define atomic64_dec_and_test(v)	(atomic64_dec_return((v)) == 0)
+#define atomic64_inc_not_zero(v)	atomic64_add_unless((v), 1LL, 0LL)
+
+#endif
+#endif
arch/arm64/include/asm/futex.h new file +136 -0

136 lines not on this page · raw message

maintainer Acked-by on v3 12/31
#51 lore raw

Re: [PATCH v3 12/31] arm64: Atomic operations

Quoted 7 lines · Catalin Marinas

This patch introduces the atomic, mutex and futex operations. Many atomic operations use the load-acquire and store-release operations which imply barriers, avoiding the need for explicit DMB.

author maintainer
#52 lore raw

PATCH v3 13/31 arm64: Device specific operations

In reply to Catalin Marinas

This patch adds several definitions for device communication, including I/O accessors and ioremap(). The __raw_* accessors are implemented as inline asm to avoid compiler generation of post-indexed accesses (less efficient to emulate in a virtualised environment).

---
 arch/arm64/include/asm/device.h |   26 ++++
 arch/arm64/include/asm/fb.h     |   34 +++++
 arch/arm64/include/asm/io.h     |  263 +++++++++++++++++++++++++++++++++++++++
 arch/arm64/kernel/io.c          |   64 ++++++++++
 arch/arm64/mm/ioremap.c         |   84 +++++++++++++
 5 files changed, 471 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm64/include/asm/device.h
 create mode 100644 arch/arm64/include/asm/fb.h
 create mode 100644 arch/arm64/include/asm/io.h
 create mode 100644 arch/arm64/kernel/io.c
 create mode 100644 arch/arm64/mm/ioremap.c
arch/arm64/include/asm/device.h new file +26 -0
new file mode 100644
index 0000000..0d8453c
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2012 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_DEVICE_H
+#define __ASM_DEVICE_H
+
+struct dev_archdata {
+	struct dma_map_ops *dma_ops;
+};
+
+struct pdev_archdata {
+};
+
+#endif
arch/arm64/include/asm/fb.h new file +34 -0
new file mode 100644
index 0000000..adb88a6
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2012 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_FB_H_
+#define __ASM_FB_H_
+
+#include <linux/fb.h>
+#include <linux/fs.h>
+#include <asm/page.h>
+
+static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
+				unsigned long off)
+{
+	vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
+}
+
+static inline int fb_is_primary_device(struct fb_info *info)
+{
+	return 0;
+}
+
+#endif /* __ASM_FB_H_ */
arch/arm64/include/asm/io.h new file +263 -0

263 lines not on this page · raw message

arch/arm64/kernel/io.c new file +64 -0

64 lines not on this page · raw message

arch/arm64/mm/ioremap.c new file +84 -0

84 lines not on this page · raw message

author maintainer
#53 lore raw

PATCH v3 14/31 arm64: DMA mapping API

In reply to Catalin Marinas

This patch adds support for the DMA mapping API. It uses dma_map_ops for flexibility and it currently supports swiotlb. This patch could be simplified further if the DMA accesses are coherent (not mandated by the architecture) or if corresponding hooks are placed in the generic swiotlb code to deal with cache maintenance.

---
 arch/arm64/include/asm/dma-mapping.h |  124 ++++++++++++++++++++++++++++++++++
 arch/arm64/mm/dma-mapping.c          |   79 +++++++++++++++++++++
 2 files changed, 203 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm64/include/asm/dma-mapping.h
 create mode 100644 arch/arm64/mm/dma-mapping.c
arch/arm64/include/asm/dma-mapping.h new file +124 -0
new file mode 100644
index 0000000..538f4b4
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2012 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_DMA_MAPPING_H
+#define __ASM_DMA_MAPPING_H
+
+#ifdef __KERNEL__
+
+#include <linux/types.h>
+#include <linux/vmalloc.h>
+
+#include <asm-generic/dma-coherent.h>
+
+#define ARCH_HAS_DMA_GET_REQUIRED_MASK
+
+extern struct dma_map_ops *dma_ops;
+
+static inline struct dma_map_ops *get_dma_ops(struct device *dev)
+{
+	if (unlikely(!dev) || !dev->archdata.dma_ops)
+		return dma_ops;
+	else
+		return dev->archdata.dma_ops;
+}
+
+#include <asm-generic/dma-mapping-common.h>
+
+static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
+{
+	return (dma_addr_t)paddr;
+}
+
+static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t dev_addr)
+{
+	return (phys_addr_t)dev_addr;
+}
+
+static inline int dma_mapping_error(struct device *dev, dma_addr_t dev_addr)
+{
+	struct dma_map_ops *ops = get_dma_ops(dev);
+	return ops->mapping_error(dev, dev_addr);
+}
+
+static inline int dma_supported(struct device *dev, u64 mask)
+{
+	struct dma_map_ops *ops = get_dma_ops(dev);
+	return ops->dma_supported(dev, mask);
+}
+
+static inline int dma_set_mask(struct device *dev, u64 mask)
+{
+	if (!dev->dma_mask || !dma_supported(dev, mask))
+		return -EIO;
+	*dev->dma_mask = mask;
+
+	return 0;
+}
+
+static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
+{
+	if (!dev->dma_mask)
+		return 0;
+
+	return addr + size - 1 <= *dev->dma_mask;
+}
+
+static inline void dma_mark_clean(void *addr, size_t size)
+{
+}
+
+static inline void *dma_alloc_coherent(struct device *dev, size_t size,
+				       dma_addr_t *dma_handle, gfp_t flags)
+{
+	struct dma_map_ops *ops = get_dma_ops(dev);
+	void *vaddr;
+
+	if (dma_alloc_from_coherent(dev, size, dma_handle, &vaddr))
+		return vaddr;
+
+	vaddr = ops->alloc(dev, size, dma_handle, flags, NULL);
+	debug_dma_alloc_coherent(dev, size, *dma_handle, vaddr);
+	return vaddr;
+}
+
+static inline void dma_free_coherent(struct device *dev, size_t size,
+				     void *vaddr, dma_addr_t dev_addr)
+{
+	struct dma_map_ops *ops = get_dma_ops(dev);
+
+	if (dma_release_from_coherent(dev, get_order(size), vaddr))
+		return;
+
+	debug_dma_free_coherent(dev, size, vaddr, dev_addr);
+	ops->free(dev, size, vaddr, dev_addr, NULL);
+}
+
+/*
+ * There is no dma_cache_sync() implementation, so just return NULL here.
+ */
+static inline void *dma_alloc_noncoherent(struct device *dev, size_t size,
+					  dma_addr_t *handle, gfp_t flags)
+{
+	return NULL;
+}
+
+static inline void dma_free_noncoherent(struct device *dev, size_t size,
+					void *cpu_addr, dma_addr_t handle)
+{
+}
+
+#endif	/* __KERNEL__ */
+#endif	/* __ASM_DMA_MAPPING_H */
arch/arm64/mm/dma-mapping.c new file +79 -0

79 lines not on this page · raw message

maintainer Acked-by on v3 14/31
#54 lore raw

Re: [PATCH v3 14/31] arm64: DMA mapping API

Quoted 8 lines · Catalin Marinas

This patch adds support for the DMA mapping API. It uses dma_map_ops for flexibility and it currently supports swiotlb. This patch could be simplified further if the DMA accesses are coherent (not mandated by the architecture) or if corresponding hooks are placed in the generic swiotlb code to deal with cache maintenance.

author maintainer
#55 lore raw

PATCH v3 15/31 arm64: SMP support

In reply to Catalin Marinas

This patch adds SMP initialisation and spinlocks implementation for AArch64. The spinlock support uses the new load-acquire/store-release instructions to avoid explicit barriers. The architecture also specifies that an event is automatically generated when clearing the exclusive monitor state to wake up processors in WFE, so there is no need for an explicit DSB/SEV instruction sequence. The SEVL instruction is used to set the exclusive monitor locally as there is no conditional WFE and a branch is more expensive.

For the SMP booting protocol, see Documentation/arm64/booting.txt.

---
 arch/arm64/include/asm/hardirq.h        |    5 +
 arch/arm64/include/asm/smp.h            |   69 +++++
 arch/arm64/include/asm/spinlock.h       |  202 +++++++++++++
 arch/arm64/include/asm/spinlock_types.h |   38 +++
 arch/arm64/kernel/smp.c                 |  469 +++++++++++++++++++++++++++++++
 5 files changed, 783 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm64/include/asm/smp.h
 create mode 100644 arch/arm64/include/asm/spinlock.h
 create mode 100644 arch/arm64/include/asm/spinlock_types.h
 create mode 100644 arch/arm64/kernel/smp.c
arch/arm64/include/asm/hardirq.h +5 -0
index c6c9514..5075463 100644
@@ -20,8 +20,13 @@
 #include <linux/threads.h>
 #include <asm/irq.h>
 
+#define NR_IPI	4
+
 typedef struct {
 	unsigned int __softirq_pending;
+#ifdef CONFIG_SMP
+	unsigned int ipi_irqs[NR_IPI];
+#endif
 } ____cacheline_aligned irq_cpustat_t;
 
 #include <linux/irq_cpustat.h>	/* Standard mappings for irq_cpustat_t above */
arch/arm64/include/asm/smp.h new file +69 -0

69 lines not on this page · raw message

arch/arm64/include/asm/spinlock.h new file +202 -0

202 lines not on this page · raw message

arch/arm64/include/asm/spinlock_types.h new file +38 -0
new file mode 100644
index 0000000..9a49434
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2012 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_SPINLOCK_TYPES_H
+#define __ASM_SPINLOCK_TYPES_H
+
+#if !defined(__LINUX_SPINLOCK_TYPES_H) && !defined(__ASM_SPINLOCK_H)
+# error "please don't include this file directly"
+#endif
+
+/* We only require natural alignment for exclusive accesses. */
+#define __lock_aligned
+
+typedef struct {
+	volatile unsigned int lock;
+} arch_spinlock_t;
+
+#define __ARCH_SPIN_LOCK_UNLOCKED	{ 0 }
+
+typedef struct {
+	volatile unsigned int lock;
+} arch_rwlock_t;
+
+#define __ARCH_RW_LOCK_UNLOCKED		{ 0 }
+
+#endif
arch/arm64/kernel/smp.c new file +469 -0

469 lines not on this page · raw message

maintainer Acked-by on v3 15/31
#56 lore raw

Re: [PATCH v3 15/31] arm64: SMP support

Quoted 9 lines · Catalin Marinas

This patch adds SMP initialisation and spinlocks implementation for AArch64. The spinlock support uses the new load-acquire/store-release instructions to avoid explicit barriers. The architecture also specifies that an event is automatically generated when clearing the exclusive monitor state to wake up processors in WFE, so there is no need for an explicit DSB/SEV instruction sequence. The SEVL instruction is used to set the exclusive monitor locally as there is no conditional WFE and a branch is more expensive.

Quoted 7 lines

For the SMP booting protocol, see Documentation/arm64/booting.txt.

#57 lore raw

PATCH v3 15/31 arm64: SMP support

In reply to Catalin Marinas

Catalin,

I know this patch is three years old, but I have a question about it:

Quoted 8 lines · Catalin Marinas
arch/arm64/kernel/smp.c new file +8 -0
+static void ipi_cpu_stop(unsigned int cpu)
+{
+       if (system_state == SYSTEM_BOOTING ||
+           system_state == SYSTEM_RUNNING) {
+               raw_spin_lock(&stop_lock);
+               pr_crit("CPU%u: stopping\n", cpu);
+               dump_stack();
+               raw_spin_unlock(&stop_lock);

arch/arm64/kernel/smp.c line 393

Quoted 10 lines
arch/arm64/kernel/smp.c new file +10 -0
+       }
+
+       set_cpu_online(cpu, false);
+
+       local_fiq_disable();
+       local_irq_disable();
+
+       while (1)
+               cpu_relax();
+}

Why do you display a message and dump the stack when a CPU is stopped?
I ask because emergency_restart() calls this function, and so
whenever I want to do an "emergency" reboot, it dumps the stack for each core. On an ARM64 system with lots of cores, this produces a ton of output. That makes emergency_restart() almost useless.

Signature · 3 lines
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project.
author maintainer
#58 lore raw

PATCH v3 15/31 arm64: SMP support

Quoted 21 lines · Timur Tabi

Catalin,

I know this patch is three years old, but I have a question about it:

Quoted 16 lines · Catalin Marinas
arch/arm64/kernel/smp.c new file +16 -0
+static void ipi_cpu_stop(unsigned int cpu)
+{
+       if (system_state == SYSTEM_BOOTING ||
+           system_state == SYSTEM_RUNNING) {
+               raw_spin_lock(&stop_lock);
+               pr_crit("CPU%u: stopping\n", cpu);
+               dump_stack();
+               raw_spin_unlock(&stop_lock);
+       }
+
+       set_cpu_online(cpu, false);
+
+       local_fiq_disable();
+       local_irq_disable();
+
+       while (1)
Quoted 8 lines

Review

Quoted 2 lines
(quoted diff) +2 -0
+               cpu_relax();
+}

Why do you display a message and dump the stack when a CPU is stopped?
I ask because emergency_restart() calls this function, and so
whenever I want to do an "emergency" reboot, it dumps the stack for each core. On an ARM64 system with lots of cores, this produces a ton of output. That makes emergency_restart() almost useless.

This code was inherited from arch/arm which initially was always dumping the stack but it later gained the system_state check. Unless it's useful to anyone for debugging purposes, I'm ok with removing it.

Signature · 1 line
Catalin
#59 lore raw

PATCH v3 15/31 arm64: SMP support

Hi Timur,

Quoted 31 lines · Catalin Marinas
Quoted 21 lines · Timur Tabi

Catalin,

I know this patch is three years old, but I have a question about it:

Quoted 16 lines · Catalin Marinas
arch/arm64/kernel/smp.c new file +16 -0
+static void ipi_cpu_stop(unsigned int cpu)
+{
+       if (system_state == SYSTEM_BOOTING ||
+           system_state == SYSTEM_RUNNING) {
+               raw_spin_lock(&stop_lock);
+               pr_crit("CPU%u: stopping\n", cpu);
+               dump_stack();
+               raw_spin_unlock(&stop_lock);
+       }
+
+       set_cpu_online(cpu, false);
+
+       local_fiq_disable();
+       local_irq_disable();
+
+       while (1)
Quoted 8 lines

Review

Quoted 2 lines
(quoted diff) +2 -0
+               cpu_relax();
+}

Why do you display a message and dump the stack when a CPU is stopped?
I ask because emergency_restart() calls this function, and so
whenever I want to do an "emergency" reboot, it dumps the stack for each core. On an ARM64 system with lots of cores, this produces a ton of output. That makes emergency_restart() almost useless.

Quoted 3 lines

This code was inherited from arch/arm which initially was always dumping the stack but it later gained the system_state check. Unless it's useful to anyone for debugging purposes, I'm ok with removing it.

Do you have patch for this one? My colleagues said that they met the same problem :)

Thanks
Hanjun

#60 lore raw

PATCH v3 15/31 arm64: SMP support

Quoted 7 lines · Hanjun Guo
Quoted 4 lines

This code was inherited from arch/arm which initially was always dumping the stack but it later gained the system_state check. Unless it's useful to anyone for debugging purposes, I'm ok with removing it.

Do you have patch for this one? My colleagues said that they met the same problem :)

Dropping the call to dump_stack() would probably be sufficient.

Signature · 3 lines
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the
Code Aurora Forum, hosted by The Linux Foundation.
#61 lore raw

PATCH v3 15/31 arm64: SMP support

Quoted 9 lines · Timur Tabi
Quoted 7 lines
Quoted 4 lines

This code was inherited from arch/arm which initially was always dumping the stack but it later gained the system_state check. Unless it's useful to anyone for debugging purposes, I'm ok with removing it.

Do you have patch for this one? My colleagues said that they met the same problem :)

Dropping the call to dump_stack() would probably be sufficient.

Actually, I think we need to keep it. I just heard from another developer who does actually use it for debugging.

I think the real problem is that emergency_restart() should not be causing these outputs. Shouldn't machine_restart() change the system_state to SYSTEM_RESTART before it calls smp_send_stop()?

Signature · 3 lines
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the
Code Aurora Forum, a Linux Foundation Collaborative Project.
#62 lore raw

PATCH v3 15/31 arm64: SMP support

Hi Timur,

Quoted 8 lines · Timur Tabi
Quoted 7 lines · Timur Tabi
Quoted 7 lines
Quoted 6 lines

This code was inherited from arch/arm which initially was always dumping
the stack but it later gained the system_state check. Unless it's useful
to anyone for debugging purposes, I'm ok with removing it.

Quoted 7 lines
Quoted 4 lines
Quoted 2 lines

Do you have patch for this one? My colleagues said that they met the same problem :)

Dropping the call to dump_stack() would probably be sufficient.

Actually, I think we need to keep it. I just heard from another developer who does actually use it for debugging.

Hmm, could you please give a example for how it used?

Quoted 4 lines

I think the real problem is that emergency_restart() should not be causing these outputs. Shouldn't machine_restart() change the system_state to SYSTEM_RESTART before it calls smp_send_stop()?

The system_state is set to SYSTEM_RESTART in kernel_restart_prepare(), and kernel_restart() will call kernel_restart_prepare() and machine_restart(), so if we change the system_state to SYSTEM_RESTART in machine_restart(), it seems duplicate.

Could we just wait longer than one second in the following function?

void smp_send_stop(void)

{
         unsigned long timeout;

         if (num_online_cpus() > 1) {
                 cpumask_t mask;

                 cpumask_copy(&mask, cpu_online_mask);
                 cpumask_clear_cpu(smp_processor_id(), &mask);

                 smp_cross_call(&mask, IPI_CPU_STOP);
         }

         /* Wait up to one second for other CPUs to stop */
         timeout = USEC_PER_SEC;
         while (num_online_cpus() > 1 && timeout--)
                 udelay(1);

If we have lots of CPUs, one second seems not enough as it print lots dump message.

Thanks
Hanjun

#63 lore raw

PATCH v3 15/31 arm64: SMP support

Quoted 4 lines · Hanjun Guo
Quoted 2 lines

Actually, I think we need to keep it. I just heard from another developer who does actually use it for debugging.

Hmm, could you please give a example for how it used?

For KVM guests, it's handy to know what the guests were doing when the guest crashes. However, I still think we should quiesce the stack dumps by default.

Quoted 8 lines
Quoted 3 lines

I think the real problem is that emergency_restart() should not be causing these outputs. Shouldn't machine_restart() change the system_state to SYSTEM_RESTART before it calls smp_send_stop()?

The system_state is set to SYSTEM_RESTART in kernel_restart_prepare(), and kernel_restart() will call kernel_restart_prepare() and machine_restart(), so if we change the system_state to SYSTEM_RESTART in machine_restart(), it seems duplicate.

I don't see where emergency_restart() ever calls
kernel_restart_prepare(). Here's the call chain:

emergency_restart
machine_emergency_restart
machine_restart
efi_reboot

I don't see where kernel_restart_prepare() is actually called in this chain.

kernel_restart() calls kernel_restart_prepare() and then calls machine_restart(). Perhaps machine_emergency_restart() also needs to call. kernel_restart_prepare() before calling machine_restart()? Either that, or machine_emergency_restart() needs to manually set system_state is set to SYSTEM_RESTART.

static inline void machine_emergency_restart(void) {
+ system_state = SYSTEM_RESTART;
machine_restart(NULL);
}

Quoted 20 lines

Could we just wait longer than one second in the following function?

void smp_send_stop(void)

{
         unsigned long timeout;

         if (num_online_cpus() > 1) {
                 cpumask_t mask;

                 cpumask_copy(&mask, cpu_online_mask);
                 cpumask_clear_cpu(smp_processor_id(), &mask);

                 smp_cross_call(&mask, IPI_CPU_STOP);
         }

         /* Wait up to one second for other CPUs to stop */
         timeout = USEC_PER_SEC;
         while (num_online_cpus() > 1 && timeout--)
                 udelay(1);
Quoted 2 lines

If we have lots of CPUs, one second seems not enough as it print lots dump message.

Yes, that's what we do internally. However, as the number of cores is increased, the problem gets worse. The default maximum cores is 64, so it just seems like this problem is going to get worse and worse as the core count grows. I believe a large core count is going to be standard modus operandi for ARM64 servers.

Signature · 3 lines
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the
Code Aurora Forum, a Linux Foundation Collaborative Project.
author maintainer
#64 lore raw

PATCH v3 16/31 arm64: ELF definitions

In reply to Catalin Marinas

This patch adds definitions for the ELF format, including personality personality setting and EXEC_PAGESIZE. The are only two hwcap definitions for 64-bit applications - HWCAP_FP and HWCAP_ASIMD.

---
 arch/arm64/include/asm/auxvec.h   |   22 +++++
 arch/arm64/include/asm/elf.h      |  179 +++++++++++++++++++++++++++++++++++++
 arch/arm64/include/asm/hwcap.h    |   53 +++++++++++
 arch/arm64/include/asm/param.h    |   23 +++++
 arch/arm64/include/asm/shmparam.h |   28 ++++++
 5 files changed, 305 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm64/include/asm/auxvec.h
 create mode 100644 arch/arm64/include/asm/elf.h
 create mode 100644 arch/arm64/include/asm/hwcap.h
 create mode 100644 arch/arm64/include/asm/param.h
 create mode 100644 arch/arm64/include/asm/shmparam.h
arch/arm64/include/asm/auxvec.h new file +22 -0
new file mode 100644
index 0000000..22d6d88
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2012 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_AUXVEC_H
+#define __ASM_AUXVEC_H
+
+/* vDSO location */
+#define AT_SYSINFO_EHDR	33
+
+#endif
arch/arm64/include/asm/elf.h new file +179 -0

179 lines not on this page · raw message

arch/arm64/include/asm/hwcap.h new file +53 -0

53 lines not on this page · raw message

arch/arm64/include/asm/param.h new file +23 -0
new file mode 100644
index 0000000..8e3a281
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2012 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_PARAM_H
+#define __ASM_PARAM_H
+
+#define EXEC_PAGESIZE	65536
+
+#include <asm-generic/param.h>
+
+#endif
arch/arm64/include/asm/shmparam.h new file +28 -0
new file mode 100644
index 0000000..4df608a
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2012 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_SHMPARAM_H
+#define __ASM_SHMPARAM_H
+
+/*
+ * For IPC syscalls from compat tasks, we need to use the legacy 16k
+ * alignment value. Since we don't have aliasing D-caches, the rest of
+ * the time we can safely use PAGE_SIZE.
+ */
+#define COMPAT_SHMLBA	0x4000
+
+#include <asm-generic/shmparam.h>
+
+#endif /* __ASM_SHMPARAM_H */
maintainer Acked-by on v3 16/31
#65 lore raw

Re: [PATCH v3 16/31] arm64: ELF definitions

Quoted 7 lines · Catalin Marinas

This patch adds definitions for the ELF format, including personality personality setting and EXEC_PAGESIZE. The are only two hwcap definitions for 64-bit applications - HWCAP_FP and HWCAP_ASIMD.

author maintainer
#66 lore raw

PATCH v3 17/31 arm64: System calls handling

In reply to Catalin Marinas

This patch adds support for system calls coming from 64-bit applications. It uses the asm-generic/unistd.h definitions with the canonical set of system calls. The private system calls are only used for 32-bit (compat) applications as 64-bit ones can set the TLS and flush the caches entirely from user space.

The sys_call_table is just an array defined in a C file and it contains pointers to the syscall functions. The array is 4KB aligned to allow the use of the ADRP instruction (longer range ADR) in entry.S.

---
 arch/arm64/include/asm/stat.h     |   62 +++++++++++++++++
 arch/arm64/include/asm/statfs.h   |   23 ++++++
 arch/arm64/include/asm/syscalls.h |   40 +++++++++++
 arch/arm64/include/asm/unistd.h   |   27 +++++++
 arch/arm64/kernel/sys.c           |  138 +++++++++++++++++++++++++++++++++++++
 5 files changed, 290 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm64/include/asm/stat.h
 create mode 100644 arch/arm64/include/asm/statfs.h
 create mode 100644 arch/arm64/include/asm/syscalls.h
 create mode 100644 arch/arm64/include/asm/unistd.h
 create mode 100644 arch/arm64/kernel/sys.c
arch/arm64/include/asm/stat.h new file +62 -0
new file mode 100644
index 0000000..d87225c
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2012 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_STAT_H
+#define __ASM_STAT_H
+
+#include <asm-generic/stat.h>
+
+#if defined(__KERNEL__) && defined(CONFIG_COMPAT)
+
+#include <asm/compat.h>
+
+/*
+ * struct stat64 is needed for compat tasks only. Its definition is different
+ * from the generic struct stat64.
+ */
+struct stat64 {
+	compat_u64	st_dev;
+	unsigned char   __pad0[4];
+
+#define STAT64_HAS_BROKEN_ST_INO	1
+	compat_ulong_t	__st_ino;
+	compat_uint_t	st_mode;
+	compat_uint_t	st_nlink;
+
+	compat_ulong_t	st_uid;
+	compat_ulong_t	st_gid;
+
+	compat_u64	st_rdev;
+	unsigned char   __pad3[4];
+
+	compat_s64	st_size;
+	compat_ulong_t	st_blksize;
+	compat_u64	st_blocks;	/* Number of 512-byte blocks allocated. */
+
+	compat_ulong_t	st_atime;
+	compat_ulong_t	st_atime_nsec;
+
+	compat_ulong_t	st_mtime;
+	compat_ulong_t	st_mtime_nsec;
+
+	compat_ulong_t	st_ctime;
+	compat_ulong_t	st_ctime_nsec;
+
+	compat_u64	st_ino;
+};
+
+#endif
+
+#endif
arch/arm64/include/asm/statfs.h new file +23 -0
new file mode 100644
index 0000000..6f62190
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2012 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_STATFS_H
+#define __ASM_STATFS_H
+
+#define ARCH_PACK_COMPAT_STATFS64 __attribute__((packed,aligned(4)))
+
+#include <asm-generic/statfs.h>
+
+#endif
arch/arm64/include/asm/syscalls.h new file +40 -0
new file mode 100644
index 0000000..09ff335
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2012 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_SYSCALLS_H
+#define __ASM_SYSCALLS_H
+
+#include <linux/linkage.h>
+#include <linux/compiler.h>
+#include <linux/signal.h>
+
+/*
+ * System call wrappers implemented in kernel/entry.S.
+ */
+asmlinkage long sys_execve_wrapper(const char __user *filename,
+				   const char __user *const __user *argv,
+				   const char __user *const __user *envp);
+asmlinkage long sys_clone_wrapper(unsigned long clone_flags,
+				  unsigned long newsp,
+				  void __user *parent_tid,
+				  unsigned long tls_val,
+				  void __user *child_tid);
+asmlinkage long sys_rt_sigreturn_wrapper(void);
+asmlinkage long sys_sigaltstack_wrapper(const stack_t __user *uss,
+					stack_t __user *uoss);
+
+#include <asm-generic/syscalls.h>
+
+#endif	/* __ASM_SYSCALLS_H */
arch/arm64/include/asm/unistd.h new file +27 -0
new file mode 100644
index 0000000..fe18a68
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2012 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/>.
+ */
+#if !defined(__ASM_UNISTD_H) || defined(__SYSCALL)
+#define __ASM_UNISTD_H
+
+#ifndef __SYSCALL_COMPAT
+#include <asm-generic/unistd.h>
+#endif
+
+#if defined(__KERNEL__) && defined(CONFIG_COMPAT)
+#include <asm/unistd32.h>
+#endif
+
+#endif /* __ASM_UNISTD_H */
arch/arm64/kernel/sys.c new file +138 -0

138 lines not on this page · raw message

maintainer
#67 lore raw

Re: [PATCH v3 17/31] arm64: System calls handling

Quoted 52 lines · Catalin Marinas
arch/arm64/kernel/sys.c new file +52 -0
+/*
+ * sys_execve() executes a new program.
+ */
+asmlinkage long sys_execve(const char __user *filenamei,
+                          const char __user *const __user *argv,
+                          const char __user *const __user *envp,
+                          struct pt_regs *regs)
+{
+       long error;
+       char * filename;
+
+       filename = getname(filenamei);
+       error = PTR_ERR(filename);
+       if (IS_ERR(filename))
+               goto out;
+       error = do_execve(filename, argv, envp, regs);
+       putname(filename);
+out:
+       return error;
+}
+
+int kernel_execve(const char *filename,
+                 const char *const argv[],
+                 const char *const envp[])
+{
+       struct pt_regs regs;
+       int ret;
+
+       memset(&regs, 0, sizeof(struct pt_regs));
+       ret = do_execve(filename,
+                       (const char __user *const __user *)argv,
+                       (const char __user *const __user *)envp, &regs);
+       if (ret < 0)
+               goto out;
+
+       /*
+        * Save argc to the register structure for userspace.
+        */
+       regs.regs[0] = ret;
+
+       /*
+        * We were successful.  We won't be returning to our caller, but
+        * instead to user space by manipulating the kernel stack.
+        */
+       asm(    "add    x0, %0, %1\n\t"
+               "mov    x1, %2\n\t"
+               "mov    x2, %3\n\t"
+               "bl     memmove\n\t"    /* copy regs to top of stack */
+               "mov    x27, #0\n\t"    /* not a syscall */
+               "mov    x28, %0\n\t"    /* thread structure */
+               "mov    sp, x0\n\t"     /* reposition stack pointer */
+               "b      ret_to_user"

arch/arm64/kernel/sys.c line 105

Quoted 10 lines
arch/arm64/kernel/sys.c new file +10 -0
+               :
+               : "r" (current_thread_info()),
+                 "Ir" (THREAD_START_SP - sizeof(regs)),
+                 "r" (&regs),
+                 "Ir" (sizeof(regs))
+               : "x0", "x1", "x2", "x27", "x28", "x30", "memory");
+
+ out:
+       return ret;
+}

Al Viro is currently reworking this code across all architectures, please have a look at https://git.kernel.org/?p=linux/kernel/git/viro/signal.git;a=shortlog;h=refs/heads/execve2

Quoted 1 line

+EXPORT_SYMBOL(kernel_execve);

You certainly don't need to export it.

Arnd

maintainer
#68 lore raw

Re: [PATCH v3 17/31] arm64: System calls handling

Quoted 6 lines · Arnd Bergmann
Quoted 6 lines
arch/arm64/kernel/sys.c new file +6 -0
+       asm(    "add    x0, %0, %1\n\t"
+               "mov    x1, %2\n\t"
+               "mov    x2, %3\n\t"
+               "bl     memmove\n\t"    /* copy regs to top of stack */
+               "mov    x27, #0\n\t"    /* not a syscall */
+               "mov    x28, %0\n\t"    /* thread structure */
Quoted 8 lines

arch/arm64/kernel/sys.c line 101

Quoted 8 lines
arch/arm64/kernel/sys.c new file +8 -0
+               "mov    sp, x0\n\t"     /* reposition stack pointer */
+               "b      ret_to_user"
+               :
+               : "r" (current_thread_info()),
+                 "Ir" (THREAD_START_SP - sizeof(regs)),
+                 "r" (&regs),
+                 "Ir" (sizeof(regs))
+               : "x0", "x1", "x2", "x27", "x28", "x30", "memory");

This should just become ret_from_kernel_execve(); FWIW, arm variant is ENTRY(ret_from_kernel_execve)

        mov     why, #0                 @ not a syscall
        str     why, [r1, #S_R0]        @ ... and we want 0 in ->ARM_r0 as well
        mov     r2, #S_FRAME_SIZE
        bl      memmove                 @ copy regs to normal location; return

@ value is in r0 and it's the same as @ the first argument, so r0 is unchanged.
get_thread_info tsk @ thread structure
mov sp, r0 @ stack pointer just under pt_regs
b ret_slow_syscall

and AFAICS you want pretty much the same, modulo different registers - 'why' (aka r8) seems to correspond to your x27, 'tsk' (aka r9) - to x28 and the rest matches one-to-one: x1.. for arguments in place of r1.. and x0 for return value (instead of r0)...

author maintainer
#69 lore raw

Re: [PATCH v3 17/31] arm64: System calls handling

In reply to Arnd Bergmann
Quoted 8 lines · Arnd Bergmann
Quoted 7 lines · Catalin Marinas
(quoted diff) +7 -0
+/*
+ * sys_execve() executes a new program.
+ */
+asmlinkage long sys_execve(const char __user *filenamei,
+                          const char __user *const __user *argv,
+                          const char __user *const __user *envp,
+                          struct pt_regs *regs)

...

Quoted 3 lines
Quoted 3 lines
(quoted diff) +3 -0
+int kernel_execve(const char *filename,
+                 const char *const argv[],
+                 const char *const envp[])

...

Quoted 2 lines

Al Viro is currently reworking this code across all architectures, please have a look at https://git.kernel.org/?p=linux/kernel/git/viro/signal.git;a=shortlog;h=refs/heads/execve2

Yes, I've seen these but since Al's patches are not in mainline, I don't want to add additional dependencies to the arm64 patches (currently based on 3.6-rc4). Once they get into mainline, I'll add a patch that converts arm64 to the generic functions above.

For kernel_execve(), I think I can simplify it further and not rely on Al's patches (similar to other architectures doing an SVC from kernel):

arch/arm64/kernel/entry.S +15 -3
index ed2e58f..e712abe 100644
@@ -241,10 +241,12 @@ ENDPROC(el1_error_invalid)
 	.align	6
 el1_sync:
 	kernel_entry 1
-	mrs	x1, esr_el1			// read the syndrome register
-	lsr	x24, x1, #26			// exception class
+	mrs	x25, esr_el1			// read the syndrome register
+	lsr	x24, x25, #26			// exception class
 	cmp	x24, #0x25			// data abort in EL1
 	b.eq	el1_da
+	cmp	x24, #0x15			// SVC in 64-bit state
+	b.eq	el0_svc
 	cmp	x24, #0x18			// configurable trap
 	b.eq	el1_undef
 	cmp	x24, #0x26			// stack alignment exception
@@ -266,6 +268,7 @@ el1_da:
 	tbnz	x23, #7, 1f			// PSR_I_BIT
 	enable_irq
 1:
+	mov	x1, x25
 	mov	x2, sp				// struct pt_regs
 	bl	do_mem_abort
 
@@ -592,7 +595,7 @@ work_resched:
 /*
  * "slow" syscall return path.
  */
-ENTRY(ret_to_user)
+ret_to_user:
 	disable_irq				// disable interrupts
 	ldr	x1, [tsk, #TI_FLAGS]
 	and	x2, x1, #_TIF_WORK_MASK
@@ -605,6 +608,15 @@ no_work_pending:
 ENDPROC(ret_to_user)
 
 /*
+ * kernel_execve() - just issue a __NR_execve syscall
+ */
+ENTRY(kernel_execve)
+	mov	x8, #__NR_execve
+	svc	#0
+	ret
+ENDPROC(kernel_execve)
+
+/*
  * This is how we return from a fork.
  */
 ENTRY(ret_from_fork)
arch/arm64/kernel/sys.c +0 -43

49 lines not on this page · raw message

Signature · 1 line
Catalin
maintainer
#70 lore raw

Re: [PATCH v3 17/31] arm64: System calls handling

Quoted 7 lines · Catalin Marinas

Yes, I've seen these but since Al's patches are not in mainline, I don't want to add additional dependencies to the arm64 patches (currently based on 3.6-rc4). Once they get into mainline, I'll add a patch that converts arm64 to the generic functions above.

For kernel_execve(), I think I can simplify it further and not rely on Al's patches (similar to other architectures doing an SVC from kernel):

Hmm, I thought one of the reasons for Al to do his series was to discourage people from doing syscalls from kernel space, but I may be misremembering things. Al?

Arnd

author maintainer
#71 lore raw

Re: [PATCH v3 17/31] arm64: System calls handling

Quoted 6 lines · Arnd Bergmann
Quoted 5 lines · Catalin Marinas

Yes, I've seen these but since Al's patches are not in mainline, I don't want to add additional dependencies to the arm64 patches (currently based on 3.6-rc4). Once they get into mainline, I'll add a patch that converts arm64 to the generic functions above.

Quoted 6 lines
Quoted 2 lines

For kernel_execve(), I think I can simplify it further and not rely on Al's patches (similar to other architectures doing an SVC from kernel):

Hmm, I thought one of the reasons for Al to do his series was to discourage people from doing syscalls from kernel space, but I may be misremembering things. Al?

If that was the aim, I'm happy to change the code similar to the arch/arm one. But as I said I would wait until Al's patches get into mainline.

Signature · 1 line
Catalin
maintainer
#72 lore raw

Re: [PATCH v3 17/31] arm64: System calls handling

Quoted 11 lines · Catalin Marinas
Quoted 9 lines · Arnd Bergmann
Quoted 7 lines · Catalin Marinas

Yes, I've seen these but since Al's patches are not in mainline, I don't want to add additional dependencies to the arm64 patches (currently based on 3.6-rc4). Once they get into mainline, I'll add a patch that converts arm64 to the generic functions above.

For kernel_execve(), I think I can simplify it further and not rely on Al's patches (similar to other architectures doing an SVC from kernel):

Quoted 7 lines
Quoted 3 lines

Hmm, I thought one of the reasons for Al to do his series was to discourage people from doing syscalls from kernel space, but I may be misremembering things. Al?

If that was the aim, I'm happy to change the code similar to the arch/arm one. But as I said I would wait until Al's patches get into mainline.

Ok. Another point: I wouldn't be too worried about dependencies for new code, because it's not possible to bisect through your series anyway (one needs all the patches before anything starts working really), so from my point of view you could also write your code in a way that expects Al's patches to get merged first.

Arnd

author maintainer
#73 lore raw

Re: [PATCH v3 17/31] arm64: System calls handling

Quoted 20 lines · Arnd Bergmann
Quoted 11 lines · Catalin Marinas
Quoted 9 lines · Arnd Bergmann
Quoted 7 lines · Catalin Marinas

Yes, I've seen these but since Al's patches are not in mainline, I don't want to add additional dependencies to the arm64 patches (currently based on 3.6-rc4). Once they get into mainline, I'll add a patch that converts arm64 to the generic functions above.

For kernel_execve(), I think I can simplify it further and not rely on Al's patches (similar to other architectures doing an SVC from kernel):

Quoted 7 lines
Quoted 3 lines

Hmm, I thought one of the reasons for Al to do his series was to discourage people from doing syscalls from kernel space, but I may be misremembering things. Al?

If that was the aim, I'm happy to change the code similar to the arch/arm one. But as I said I would wait until Al's patches get into mainline.

Quoted 5 lines

Ok. Another point: I wouldn't be too worried about dependencies for new code, because it's not possible to bisect through your series anyway (one needs all the patches before anything starts working really), so from my point of view you could also write your code in a way that expects Al's patches to get merged first.

It's not about bisectability but rather a way to test the branch that I publish. On its own, my branch wouldn't even compile. Anyway, here's the update (tested on a local branch with Al's execve2 branch merged):

arm64: Switch to generic sys_execve/kernel_execve

This patch converts the arm64 port to use the generic sys_execve and kernel_execve() functions. It introduces the ret_from_kernel_execve() function for starting the new user context and removes the (compat_)sys_execve_wrapper() functions.

arch/arm64/include/asm/syscalls.h +0 -3
index 09ff335..81680a0 100644
@@ -23,9 +23,6 @@
 /*
  * System call wrappers implemented in kernel/entry.S.
  */
-asmlinkage long sys_execve_wrapper(const char __user *filename,
-				   const char __user *const __user *argv,
-				   const char __user *const __user *envp);
 asmlinkage long sys_clone_wrapper(unsigned long clone_flags,
 				  unsigned long newsp,
 				  void __user *parent_tid,
arch/arm64/include/asm/unistd.h +3 -0
index fe18a68..948cfb1 100644
@@ -24,4 +24,7 @@
 #include <asm/unistd32.h>
 #endif
 
+#define __ARCH_WANT_SYS_EXECVE
+#define __ARCH_WANT_KERNEL_EXECVE
+
 #endif /* __ASM_UNISTD_H */
arch/arm64/kernel/entry.S +17 -6
index 38cf853..5e0b28c 100644
@@ -592,7 +592,7 @@ work_resched:
 /*
  * "slow" syscall return path.
  */
-ENTRY(ret_to_user)
+ret_to_user:
 	disable_irq				// disable interrupts
 	ldr	x1, [tsk, #TI_FLAGS]
 	and	x2, x1, #_TIF_WORK_MASK
@@ -614,6 +614,22 @@ ENTRY(ret_from_fork)
 ENDPROC(ret_from_fork)
 
 /*
+ * ret_from_kernel_execve(struct pt_regs *normal, struct pt_regs *new)
+ *
+ * Turn a kernel thread into a user process.
+ */
+ENTRY(ret_from_kernel_execve)
+	str	xzr, [x1, #S_X0]		// returning 0
+	mov	x2, #-1
+	str	x2, [x1, #S_SYSCALLNO]		// not a syscall
+	mov	x2, #S_FRAME_SIZE
+	bl	memmove				// copy regs to the normal location
+	get_thread_info tsk
+	mov	sp, x0				// normal pt_regs
+	b	ret_to_user
+ENDPROC(ret_from_kernel_execve)
+
+/*
  * SVC handler.
  */
 	.align	6
@@ -671,11 +687,6 @@ __sys_trace_return:
 /*
  * Special system call wrappers.
  */
-ENTRY(sys_execve_wrapper)
-	mov	x3, sp
-	b	sys_execve
-ENDPROC(sys_execve_wrapper)
-
 ENTRY(sys_clone_wrapper)
 	mov	x5, sp
 	b	sys_clone
arch/arm64/kernel/sys.c +0 -65

77 lines not on this page · raw message

arch/arm64/kernel/sys32.S +1 -6
index 5e4dc93..903ba9d 100644
@@ -36,11 +36,6 @@ compat_sys_vfork_wrapper:
 	b	compat_sys_vfork
 ENDPROC(compat_sys_vfork_wrapper)
 
-compat_sys_execve_wrapper:
-	mov	x3, sp
-	b	compat_sys_execve
-ENDPROC(compat_sys_execve_wrapper)
-
 compat_sys_clone_wrapper:
 	mov	x5, sp
 	b	compat_sys_clone
@@ -152,7 +147,7 @@ ENDPROC(compat_sys_fanotify_mark_wrapper)
  */
 #define sys_fork		compat_sys_fork_wrapper
 #define sys_open		compat_sys_open
-#define sys_execve		compat_sys_execve_wrapper
+#define sys_execve		compat_sys_execve
 #define sys_lseek		compat_sys_lseek_wrapper
 #define sys_mount		compat_sys_mount
 #define sys_ptrace		compat_sys_ptrace
arch/arm64/kernel/sys_compat.c +0 -18
index 967e92f..d77ba8e 100644
@@ -51,24 +51,6 @@ asmlinkage int compat_sys_vfork(struct pt_regs *regs)
 		       regs, 0, NULL, NULL);
 }
 
-asmlinkage int compat_sys_execve(const char __user *filenamei,
-				 compat_uptr_t argv, compat_uptr_t envp,
-				 struct pt_regs *regs)
-{
-	int error;
-	char * filename;
-
-	filename = getname(filenamei);
-	error = PTR_ERR(filename);
-	if (IS_ERR(filename))
-		goto out;
-	error = compat_do_execve(filename, compat_ptr(argv), compat_ptr(envp),
-				 regs);
-	putname(filename);
-out:
-	return error;
-}
-
 asmlinkage int compat_sys_sched_rr_get_interval(compat_pid_t pid,
 						struct compat_timespec __user *interval)
 {
author maintainer
#74 lore raw

PATCH v3 18/31 arm64: VDSO support

In reply to Catalin Marinas

From: Will Deacon <[email protected]>

This patch adds VDSO support for 64-bit applications. The VDSO code is currently used for sys_rt_sigreturn() and optimised gettimeofday() (using the user-accessible generic counter).

---
 arch/arm64/include/asm/vdso.h              |   41 +++++
 arch/arm64/include/asm/vdso_datapage.h     |   43 +++++
 arch/arm64/kernel/vdso.c                   |  261 ++++++++++++++++++++++++++++
 arch/arm64/kernel/vdso/.gitignore          |    2 +
 arch/arm64/kernel/vdso/Makefile            |   63 +++++++
 arch/arm64/kernel/vdso/gen_vdso_offsets.sh |   15 ++
 arch/arm64/kernel/vdso/gettimeofday.S      |  242 ++++++++++++++++++++++++++
 arch/arm64/kernel/vdso/note.S              |   28 +++
 arch/arm64/kernel/vdso/sigreturn.S         |   37 ++++
 arch/arm64/kernel/vdso/vdso.S              |   33 ++++
 arch/arm64/kernel/vdso/vdso.lds.S          |  100 +++++++++++
 11 files changed, 865 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm64/include/asm/vdso.h
 create mode 100644 arch/arm64/include/asm/vdso_datapage.h
 create mode 100644 arch/arm64/kernel/vdso.c
 create mode 100644 arch/arm64/kernel/vdso/.gitignore
 create mode 100644 arch/arm64/kernel/vdso/Makefile
 create mode 100755 arch/arm64/kernel/vdso/gen_vdso_offsets.sh
 create mode 100644 arch/arm64/kernel/vdso/gettimeofday.S
 create mode 100644 arch/arm64/kernel/vdso/note.S
 create mode 100644 arch/arm64/kernel/vdso/sigreturn.S
 create mode 100644 arch/arm64/kernel/vdso/vdso.S
 create mode 100644 arch/arm64/kernel/vdso/vdso.lds.S
arch/arm64/include/asm/vdso.h new file +41 -0
new file mode 100644
index 0000000..839ce00
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2012 ARM Limited
+ *
+ * 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_VDSO_H
+#define __ASM_VDSO_H
+
+#ifdef __KERNEL__
+
+/*
+ * Default link address for the vDSO.
+ * Since we randomise the VDSO mapping, there's little point in trying
+ * to prelink this.
+ */
+#define VDSO_LBASE	0x0
+
+#ifndef __ASSEMBLY__
+
+#include <generated/vdso-offsets.h>
+
+#define VDSO_SYMBOL(base, name)						   \
+({									   \
+	(void *)(vdso_offset_##name - VDSO_LBASE + (unsigned long)(base)); \
+})
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* __KERNEL__ */
+
+#endif /* __ASM_VDSO_H */
arch/arm64/include/asm/vdso_datapage.h new file +43 -0

43 lines not on this page · raw message

arch/arm64/kernel/vdso.c new file +261 -0

261 lines not on this page · raw message

arch/arm64/kernel/vdso/.gitignore new file +2 -0
new file mode 100644
index 0000000..b8cc94e
@@ -0,0 +1,2 @@
+vdso.lds
+vdso-offsets.h
arch/arm64/kernel/vdso/Makefile new file +63 -0

63 lines not on this page · raw message

arch/arm64/kernel/vdso/gen_vdso_offsets.sh new file +15 -0
new file mode 100755
index 0000000..01924ff
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+#
+# Match symbols in the DSO that look like VDSO_*; produce a header file
+# of constant offsets into the shared object.
+#
+# Doing this inside the Makefile will break the $(filter-out) function,
+# causing Kbuild to rebuild the vdso-offsets header file every time.
+#
+# Author: Will Deacon <[email protected]
+#
+
+LC_ALL=C
+sed -n -e 's/^00*/0/' -e \
+'s/^\([0-9a-fA-F]*\) . VDSO_\([a-zA-Z0-9_]*\)$/\#define vdso_offset_\2\t0x\1/p'
arch/arm64/kernel/vdso/gettimeofday.S new file +242 -0

242 lines not on this page · raw message

arch/arm64/kernel/vdso/note.S new file +28 -0
new file mode 100644
index 0000000..b82c85e
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2012 ARM Limited
+ *
+ * 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/>.
+ *
+ * Author: Will Deacon <[email protected]>
+ *
+ * This supplies .note.* sections to go into the PT_NOTE inside the vDSO text.
+ * Here we can supply some information useful to userland.
+ */
+
+#include <linux/uts.h>
+#include <linux/version.h>
+#include <linux/elfnote.h>
+
+ELFNOTE_START(Linux, 0, "a")
+	.long LINUX_VERSION_CODE
+ELFNOTE_END
arch/arm64/kernel/vdso/sigreturn.S new file +37 -0
new file mode 100644
index 0000000..20d98ef
@@ -0,0 +1,37 @@
+/*
+ * Sigreturn trampoline for returning from a signal when the SA_RESTORER
+ * flag is not set.
+ *
+ * Copyright (C) 2012 ARM Limited
+ *
+ * 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/>.
+ *
+ * Author: Will Deacon <[email protected]>
+ */
+
+#include <linux/linkage.h>
+#include <asm/unistd.h>
+
+	.text
+
+	nop
+ENTRY(__kernel_rt_sigreturn)
+	.cfi_startproc
+	.cfi_signal_frame
+	.cfi_def_cfa	x29, 0
+	.cfi_offset	x29, 0 * 8
+	.cfi_offset	x30, 1 * 8
+	mov	x8, #__NR_rt_sigreturn
+	svc	#0
+	.cfi_endproc
+ENDPROC(__kernel_rt_sigreturn)
arch/arm64/kernel/vdso/vdso.S new file +33 -0
new file mode 100644
index 0000000..60c1db5
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2012 ARM Limited
+ *
+ * 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/>.
+ *
+ * Author: Will Deacon <[email protected]>
+ */
+
+#include <linux/init.h>
+#include <linux/linkage.h>
+#include <linux/const.h>
+#include <asm/page.h>
+
+	__PAGE_ALIGNED_DATA
+
+	.globl vdso_start, vdso_end
+	.balign PAGE_SIZE
+vdso_start:
+	.incbin "arch/arm64/kernel/vdso/vdso.so"
+	.balign PAGE_SIZE
+vdso_end:
+
+	.previous
arch/arm64/kernel/vdso/vdso.lds.S new file +100 -0

100 lines not on this page · raw message

maintainer Acked-by on v3 18/31
#75 lore raw

Re: [PATCH v3 18/31] arm64: VDSO support

Quoted 9 lines · Catalin Marinas

From: Will Deacon <[email protected]>

This patch adds VDSO support for 64-bit applications. The VDSO code is currently used for sys_rt_sigreturn() and optimised gettimeofday() (using the user-accessible generic counter).

author maintainer
#76 lore raw

PATCH v3 19/31 arm64: Signal handling support

In reply to Catalin Marinas

This patch adds support for signal handling. The sigreturn is done via VDSO, introduced by a previous patch. The SA_RESTORER is still defined as it is required for 32-bit (compat) support but it is not to be used for 64-bit applications.

---
 arch/arm64/include/asm/sigcontext.h |   69 ++++++
 arch/arm64/include/asm/siginfo.h    |   23 ++
 arch/arm64/include/asm/signal.h     |   24 ++
 arch/arm64/include/asm/ucontext.h   |   30 +++
 arch/arm64/kernel/signal.c          |  437 +++++++++++++++++++++++++++++++++++
 5 files changed, 583 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm64/include/asm/sigcontext.h
 create mode 100644 arch/arm64/include/asm/siginfo.h
 create mode 100644 arch/arm64/include/asm/signal.h
 create mode 100644 arch/arm64/include/asm/ucontext.h
 create mode 100644 arch/arm64/kernel/signal.c
arch/arm64/include/asm/sigcontext.h new file +69 -0
new file mode 100644
index 0000000..573cec7
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2012 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_SIGCONTEXT_H
+#define __ASM_SIGCONTEXT_H
+
+#include <linux/types.h>
+
+/*
+ * Signal context structure - contains all info to do with the state
+ * before the signal handler was invoked.
+ */
+struct sigcontext {
+	__u64 fault_address;
+	/* AArch64 registers */
+	__u64 regs[31];
+	__u64 sp;
+	__u64 pc;
+	__u64 pstate;
+	/* 4K reserved for FP/SIMD state and future expansion */
+	__u8 __reserved[4096] __attribute__((__aligned__(16)));
+};
+
+/*
+ * Header to be used at the beginning of structures extending the user
+ * context. Such structures must be placed after the rt_sigframe on the stack
+ * and be 16-byte aligned. The last structure must be a dummy one with the
+ * magic and size set to 0.
+ */
+struct _aarch64_ctx {
+	__u32 magic;
+	__u32 size;
+};
+
+#define FPSIMD_MAGIC	0x46508001
+
+struct fpsimd_context {
+	struct _aarch64_ctx head;
+	__u32 fpsr;
+	__u32 fpcr;
+	__uint128_t vregs[32];
+};
+
+#ifdef __KERNEL__
+/*
+ * Auxiliary context saved in the sigcontext.__reserved array. Not exported to
+ * user space as it will change with the addition of new context. User space
+ * should check the magic/size information.
+ */
+struct aux_context {
+	struct fpsimd_context fpsimd;
+	/* additional context to be added before "end" */
+	struct _aarch64_ctx end;
+};
+#endif
+
+#endif
arch/arm64/include/asm/siginfo.h new file +23 -0
new file mode 100644
index 0000000..5a74a08
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2012 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_SIGINFO_H
+#define __ASM_SIGINFO_H
+
+#define __ARCH_SI_PREAMBLE_SIZE	(4 * sizeof(int))
+
+#include <asm-generic/siginfo.h>
+
+#endif
arch/arm64/include/asm/signal.h new file +24 -0
new file mode 100644
index 0000000..8d1e723
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2012 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_SIGNAL_H
+#define __ASM_SIGNAL_H
+
+/* Required for AArch32 compatibility. */
+#define SA_RESTORER	0x04000000
+
+#include <asm-generic/signal.h>
+
+#endif
arch/arm64/include/asm/ucontext.h new file +30 -0
new file mode 100644
index 0000000..bde9607
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2012 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_UCONTEXT_H
+#define __ASM_UCONTEXT_H
+
+struct ucontext {
+	unsigned long	  uc_flags;
+	struct ucontext	 *uc_link;
+	stack_t		  uc_stack;
+	sigset_t	  uc_sigmask;
+	/* glibc uses a 1024-bit sigset_t */
+	__u8		  __unused[(1024 - sizeof(sigset_t)) / 8];
+	/* last for future expansion */
+	struct sigcontext uc_mcontext;
+};
+
+#endif /* __ASM_UCONTEXT_H */
arch/arm64/kernel/signal.c new file +437 -0

437 lines not on this page · raw message

author maintainer
#77 lore raw

PATCH v3 20/31 arm64: User access library functions

In reply to Catalin Marinas

This patch add support for various user access functions. These functions use the standard LDR/STR instructions and not the LDRT/STRT variants in order to allow kernel addresses (after set_fs(KERNEL_DS)).

---
 arch/arm64/include/asm/uaccess.h   |  297 ++++++++++++++++++++++++++++++++++++
 arch/arm64/lib/clear_user.S        |   58 +++++++
 arch/arm64/lib/copy_from_user.S    |   66 ++++++++
 arch/arm64/lib/copy_in_user.S      |   63 ++++++++
 arch/arm64/lib/copy_to_user.S      |   61 ++++++++
 arch/arm64/lib/strncpy_from_user.S |   50 ++++++
 arch/arm64/lib/strnlen_user.S      |   47 ++++++
 7 files changed, 642 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm64/include/asm/uaccess.h
 create mode 100644 arch/arm64/lib/clear_user.S
 create mode 100644 arch/arm64/lib/copy_from_user.S
 create mode 100644 arch/arm64/lib/copy_in_user.S
 create mode 100644 arch/arm64/lib/copy_to_user.S
 create mode 100644 arch/arm64/lib/strncpy_from_user.S
 create mode 100644 arch/arm64/lib/strnlen_user.S
arch/arm64/include/asm/uaccess.h new file +297 -0
new file mode 100644
index 0000000..008f848
@@ -0,0 +1,297 @@
+/*
+ * Based on arch/arm/include/asm/uaccess.h
+ *
+ * Copyright (C) 2012 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_UACCESS_H
+#define __ASM_UACCESS_H
+
+/*
+ * User space memory access functions
+ */
+#include <linux/string.h>
+#include <linux/thread_info.h>
+
+#include <asm/ptrace.h>
+#include <asm/errno.h>
+#include <asm/memory.h>
+#include <asm/compiler.h>
+
+#define VERIFY_READ 0
+#define VERIFY_WRITE 1
+
+/*
+ * The exception table consists of pairs of addresses: the first is the
+ * address of an instruction that is allowed to fault, and the second is
+ * the address at which the program should continue.  No registers are
+ * modified, so it is entirely up to the continuation code to figure out
+ * what to do.
+ *
+ * All the routines below use bits of fixup code that are out of line
+ * with the main instruction path.  This means when everything is well,
+ * we don't even have to jump over them.  Further, they do not intrude
+ * on our cache or tlb entries.
+ */
+
+struct exception_table_entry
+{
+	unsigned long insn, fixup;
+};
+
+extern int fixup_exception(struct pt_regs *regs);
+
+#define KERNEL_DS	(-1UL)
+#define get_ds()	(KERNEL_DS)
+
+#define USER_DS		TASK_SIZE_64
+#define get_fs()	(current_thread_info()->addr_limit)
+
+static inline void set_fs(mm_segment_t fs)
+{
+	current_thread_info()->addr_limit = fs;
+}
+
+#define segment_eq(a,b)	((a) == (b))
+
+/*
+ * Return 1 if addr < current->addr_limit, 0 otherwise.
+ */
+#define __addr_ok(addr)							\
+({									\
+	unsigned long flag;						\
+	asm("cmp %1, %0; cset %0, lo"					\
+		: "=&r" (flag)						\
+		: "r" (addr), "0" (current_thread_info()->addr_limit)	\
+		: "cc");						\
+	flag;								\
+})
+
+/*
+ * Test whether a block of memory is a valid user space address.
+ * Returns 1 if the range is valid, 0 otherwise.
+ *
+ * This is equivalent to the following test:
+ * (u65)addr + (u65)size < (u65)current->addr_limit
+ *
+ * This needs 65-bit arithmetic.
+ */
+#define __range_ok(addr, size)						\
+({									\
+	unsigned long flag, roksum;					\
+	__chk_user_ptr(addr);						\
+	asm("adds %1, %1, %3; ccmp %1, %4, #2, cc; cset %0, cc"		\
+		: "=&r" (flag), "=&r" (roksum)				\
+		: "1" (addr), "Ir" (size),				\
+		  "r" (current_thread_info()->addr_limit)		\
+		: "cc");						\
+	flag;								\
+})
+
+#define access_ok(type, addr, size)	__range_ok(addr, size)
+
+/*
+ * The "__xxx" versions of the user access functions do not verify the address
+ * space - it must have been done previously with a separate "access_ok()"
+ * call.
+ *
+ * The "__xxx_error" versions set the third argument to -EFAULT if an error
+ * occurs, and leave it unchanged on success.
+ */
+#define __get_user_asm(instr, reg, x, addr, err)			\
+	asm volatile(							\
+	"1:	" instr "	" reg "1, [%2]\n"			\
+	"2:\n"								\
+	"	.section .fixup, \"ax\"\n"				\
+	"	.align	2\n"						\
+	"3:	mov	%w0, %3\n"					\
+	"	mov	%1, #0\n"					\
+	"	b	2b\n"						\
+	"	.previous\n"						\
+	"	.section __ex_table,\"a\"\n"				\
+	"	.align	3\n"						\
+	"	.quad	1b, 3b\n"					\
+	"	.previous"						\
+	: "+r" (err), "=&r" (x)						\
+	: "r" (addr), "i" (-EFAULT))
+
+#define __get_user_err(x, ptr, err)					\
+do {									\
+	unsigned long __gu_val;						\
+	__chk_user_ptr(ptr);						\
+	switch (sizeof(*(ptr))) {					\
+	case 1:								\
+		__get_user_asm("ldrb", "%w", __gu_val, (ptr), (err));	\
+		break;							\
+	case 2:								\
+		__get_user_asm("ldrh", "%w", __gu_val, (ptr), (err));	\
+		break;							\
+	case 4:								\
+		__get_user_asm("ldr", "%w", __gu_val, (ptr), (err));	\
+		break;							\
+	case 8:								\
+		__get_user_asm("ldr", "%",  __gu_val, (ptr), (err));	\
+		break;							\
+	default:							\
+		BUILD_BUG();						\
+	}								\
+	(x) = (__typeof__(*(ptr)))__gu_val;				\
+} while (0)
+
+#define __get_user(x, ptr)						\
+({									\
+	int __gu_err = 0;						\
+	__get_user_err((x), (ptr), __gu_err);				\
+	__gu_err;							\
+})
+
+#define __get_user_error(x, ptr, err)					\
+({									\
+	__get_user_err((x), (ptr), (err));				\
+	(void)0;							\
+})
+
+#define __get_user_unaligned __get_user
+
+#define get_user(x, ptr)						\
+({									\
+	might_sleep();							\
+	access_ok(VERIFY_READ, (ptr), sizeof(*(ptr))) ?			\
+		__get_user((x), (ptr)) :				\
+		((x) = 0, -EFAULT);					\
+})
+
+#define __put_user_asm(instr, reg, x, addr, err)			\
+	asm volatile(							\
+	"1:	" instr "	" reg "1, [%2]\n"			\
+	"2:\n"								\
+	"	.section .fixup,\"ax\"\n"				\
+	"	.align	2\n"						\
+	"3:	mov	%w0, %3\n"					\
+	"	b	2b\n"						\
+	"	.previous\n"						\
+	"	.section __ex_table,\"a\"\n"				\
+	"	.align	3\n"						\
+	"	.quad	1b, 3b\n"					\
+	"	.previous"						\
+	: "+r" (err)							\
+	: "r" (x), "r" (addr), "i" (-EFAULT))
+
+#define __put_user_err(x, ptr, err)					\
+do {									\
+	__typeof__(*(ptr)) __pu_val = (x);				\
+	__chk_user_ptr(ptr);						\
+	switch (sizeof(*(ptr))) {					\
+	case 1:								\
+		__put_user_asm("strb", "%w", __pu_val, (ptr), (err));	\
+		break;							\
+	case 2:								\
+		__put_user_asm("strh", "%w", __pu_val, (ptr), (err));	\
+		break;							\
+	case 4:								\
+		__put_user_asm("str",  "%w", __pu_val, (ptr), (err));	\
+		break;							\
+	case 8:								\
+		__put_user_asm("str",  "%", __pu_val, (ptr), (err));	\
+		break;							\
+	default:							\
+		BUILD_BUG();						\
+	}								\
+} while (0)
+
+#define __put_user(x, ptr)						\
+({									\
+	int __pu_err = 0;						\
+	__put_user_err((x), (ptr), __pu_err);				\
+	__pu_err;							\
+})
+
+#define __put_user_error(x, ptr, err)					\
+({									\
+	__put_user_err((x), (ptr), (err));				\
+	(void)0;							\
+})
+
+#define __put_user_unaligned __put_user
+
+#define put_user(x, ptr)						\
+({									\
+	might_sleep();							\
+	access_ok(VERIFY_WRITE, (ptr), sizeof(*(ptr))) ?		\
+		__put_user((x), (ptr)) :				\
+		-EFAULT;						\
+})
+
+extern unsigned long __must_check __copy_from_user(void *to, const void __user *from, unsigned long n);
+extern unsigned long __must_check __copy_to_user(void __user *to, const void *from, unsigned long n);
+extern unsigned long __must_check __copy_in_user(void __user *to, const void __user *from, unsigned long n);
+extern unsigned long __must_check __clear_user(void __user *addr, unsigned long n);
+
+extern unsigned long __must_check __strncpy_from_user(char *to, const char __user *from, unsigned long count);
+extern unsigned long __must_check __strnlen_user(const char __user *s, long n);
+
+static inline unsigned long __must_check copy_from_user(void *to, const void __user *from, unsigned long n)
+{
+	if (access_ok(VERIFY_READ, from, n))
+		n = __copy_from_user(to, from, n);
+	else /* security hole - plug it */
+		memset(to, 0, n);
+	return n;
+}
+
+static inline unsigned long __must_check copy_to_user(void __user *to, const void *from, unsigned long n)
+{
+	if (access_ok(VERIFY_WRITE, to, n))
+		n = __copy_to_user(to, from, n);
+	return n;
+}
+
+static inline unsigned long __must_check copy_in_user(void __user *to, const void __user *from, unsigned long n)
+{
+	if (access_ok(VERIFY_READ, from, n) && access_ok(VERIFY_WRITE, to, n))
+		n = __copy_in_user(to, from, n);
+	return n;
+}
+
+#define __copy_to_user_inatomic __copy_to_user
+#define __copy_from_user_inatomic __copy_from_user
+
+static inline unsigned long __must_check clear_user(void __user *to, unsigned long n)
+{
+	if (access_ok(VERIFY_WRITE, to, n))
+		n = __clear_user(to, n);
+	return n;
+}
+
+static inline long __must_check strncpy_from_user(char *dst, const char __user *src, long count)
+{
+	long res = -EFAULT;
+	if (access_ok(VERIFY_READ, src, 1))
+		res = __strncpy_from_user(dst, src, count);
+	return res;
+}
+
+#define strlen_user(s)	strnlen_user(s, ~0UL >> 1)
+
+static inline long __must_check strnlen_user(const char __user *s, long n)
+{
+	unsigned long res = 0;
+
+	if (__addr_ok(s))
+		res = __strnlen_user(s, n);
+
+	return res;
+}
+
+#endif /* __ASM_UACCESS_H */
arch/arm64/lib/clear_user.S new file +58 -0

58 lines not on this page · raw message

arch/arm64/lib/copy_from_user.S new file +66 -0

66 lines not on this page · raw message

arch/arm64/lib/copy_in_user.S new file +63 -0

63 lines not on this page · raw message

arch/arm64/lib/copy_to_user.S new file +61 -0

61 lines not on this page · raw message

arch/arm64/lib/strncpy_from_user.S new file +50 -0

50 lines not on this page · raw message

arch/arm64/lib/strnlen_user.S new file +47 -0

47 lines not on this page · raw message

maintainer Acked-by on v3 20/31
#78 lore raw

Re: [PATCH v3 20/31] arm64: User access library functions

Quoted 8 lines · Catalin Marinas

This patch add support for various user access functions. These functions use the standard LDR/STR instructions and not the LDRT/STRT variants in order to allow kernel addresses (after set_fs(KERNEL_DS)).

author maintainer
#79 lore raw

PATCH v3 21/31 arm64: 32-bit (compat) applications support

In reply to Catalin Marinas

From: Will Deacon <[email protected]>

This patch adds support for 32-bit applications. The vectors page is a binary blob mapped into the application user space at 0xffff0000 (the AArch64 toolchain does not support compilation of AArch32 code). Full compatibility with ARMv7 user space is supported. The use of deprecated ARMv7 functionality (SWP, CP15 barriers) has been disabled by default on AArch64 kernels and unaligned LDM/STM is not supported.

Please note that only the ARM 32-bit EABI is supported, so no OABI compatibility.

---
 arch/arm64/include/asm/compat.h   |  242 ++++++++++
 arch/arm64/include/asm/signal32.h |   53 +++
 arch/arm64/include/asm/unistd32.h |  758 ++++++++++++++++++++++++++++++++
 arch/arm64/kernel/kuser32.S       |   77 ++++
 arch/arm64/kernel/signal32.c      |  876 +++++++++++++++++++++++++++++++++++++
 arch/arm64/kernel/sys32.S         |  282 ++++++++++++
 arch/arm64/kernel/sys_compat.c    |  164 +++++++
 7 files changed, 2452 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm64/include/asm/compat.h
 create mode 100644 arch/arm64/include/asm/signal32.h
 create mode 100644 arch/arm64/include/asm/unistd32.h
 create mode 100644 arch/arm64/kernel/kuser32.S
 create mode 100644 arch/arm64/kernel/signal32.c
 create mode 100644 arch/arm64/kernel/sys32.S
 create mode 100644 arch/arm64/kernel/sys_compat.c
arch/arm64/include/asm/compat.h new file +242 -0
new file mode 100644
index 0000000..a670a33
@@ -0,0 +1,242 @@
+/*
+ * Copyright (C) 2012 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_COMPAT_H
+#define __ASM_COMPAT_H
+#ifdef __KERNEL__
+#ifdef CONFIG_COMPAT
+
+/*
+ * Architecture specific compatibility types
+ */
+#include <linux/types.h>
+#include <linux/sched.h>
+
+#define COMPAT_USER_HZ		100
+#define COMPAT_UTS_MACHINE	"armv8l\0\0"
+
+typedef u32		compat_size_t;
+typedef s32		compat_ssize_t;
+typedef s32		compat_time_t;
+typedef s32		compat_clock_t;
+typedef s32		compat_pid_t;
+typedef u32		__compat_uid_t;
+typedef u32		__compat_gid_t;
+typedef u32		__compat_uid32_t;
+typedef u32		__compat_gid32_t;
+typedef u32		compat_mode_t;
+typedef u32		compat_ino_t;
+typedef u32		compat_dev_t;
+typedef s32		compat_off_t;
+typedef s64		compat_loff_t;
+typedef s16		compat_nlink_t;
+typedef u16		compat_ipc_pid_t;
+typedef s32		compat_daddr_t;
+typedef u32		compat_caddr_t;
+typedef __kernel_fsid_t	compat_fsid_t;
+typedef s32		compat_key_t;
+typedef s32		compat_timer_t;
+
+typedef s32		compat_int_t;
+typedef s32		compat_long_t;
+typedef s64		compat_s64;
+typedef u32		compat_uint_t;
+typedef u32		compat_ulong_t;
+typedef u64		compat_u64;
+
+struct compat_timespec {
+	compat_time_t	tv_sec;
+	s32		tv_nsec;
+};
+
+struct compat_timeval {
+	compat_time_t	tv_sec;
+	s32		tv_usec;
+};
+
+struct compat_stat {
+	compat_dev_t	st_dev;
+	compat_ino_t	st_ino;
+	compat_mode_t	st_mode;
+	compat_nlink_t	st_nlink;
+	__compat_uid32_t	st_uid;
+	__compat_gid32_t	st_gid;
+	compat_dev_t	st_rdev;
+	compat_off_t	st_size;
+	compat_off_t	st_blksize;
+	compat_off_t	st_blocks;
+	compat_time_t	st_atime;
+	u32		st_atime_nsec;
+	compat_time_t	st_mtime;
+	u32		st_mtime_nsec;
+	compat_time_t	st_ctime;
+	u32		st_ctime_nsec;
+	u32		__unused4[2];
+};
+
+struct compat_flock {
+	short		l_type;
+	short		l_whence;
+	compat_off_t	l_start;
+	compat_off_t	l_len;
+	compat_pid_t	l_pid;
+};
+
+#define F_GETLK64	12	/*  using 'struct flock64' */
+#define F_SETLK64	13
+#define F_SETLKW64	14
+
+struct compat_flock64 {
+	short		l_type;
+	short		l_whence;
+	compat_loff_t	l_start;
+	compat_loff_t	l_len;
+	compat_pid_t	l_pid;
+};
+
+struct compat_statfs {
+	int		f_type;
+	int		f_bsize;
+	int		f_blocks;
+	int		f_bfree;
+	int		f_bavail;
+	int		f_files;
+	int		f_ffree;
+	compat_fsid_t	f_fsid;
+	int		f_namelen;	/* SunOS ignores this field. */
+	int		f_frsize;
+	int		f_flags;
+	int		f_spare[4];
+};
+
+#define COMPAT_RLIM_INFINITY		0xffffffff
+
+typedef u32		compat_old_sigset_t;
+
+#define _COMPAT_NSIG		64
+#define _COMPAT_NSIG_BPW	32
+
+typedef u32		compat_sigset_word;
+
+#define COMPAT_OFF_T_MAX	0x7fffffff
+#define COMPAT_LOFF_T_MAX	0x7fffffffffffffffL
+
+/*
+ * A pointer passed in from user mode. This should not
+ * be used for syscall parameters, just declare them
+ * as pointers because the syscall entry code will have
+ * appropriately converted them already.
+ */
+typedef	u32		compat_uptr_t;
+
+static inline void __user *compat_ptr(compat_uptr_t uptr)
+{
+	return (void __user *)(unsigned long)uptr;
+}
+
+static inline compat_uptr_t ptr_to_compat(void __user *uptr)
+{
+	return (u32)(unsigned long)uptr;
+}
+
+static inline void __user *arch_compat_alloc_user_space(long len)
+{
+	struct pt_regs *regs = task_pt_regs(current);
+	return (void __user *)regs->compat_sp - len;
+}
+
+struct compat_ipc64_perm {
+	compat_key_t key;
+	__compat_uid32_t uid;
+	__compat_gid32_t gid;
+	__compat_uid32_t cuid;
+	__compat_gid32_t cgid;
+	unsigned short mode;
+	unsigned short __pad1;
+	unsigned short seq;
+	unsigned short __pad2;
+	compat_ulong_t unused1;
+	compat_ulong_t unused2;
+};
+
+struct compat_semid64_ds {
+	struct compat_ipc64_perm sem_perm;
+	compat_time_t  sem_otime;
+	compat_ulong_t __unused1;
+	compat_time_t  sem_ctime;
+	compat_ulong_t __unused2;
+	compat_ulong_t sem_nsems;
+	compat_ulong_t __unused3;
+	compat_ulong_t __unused4;
+};
+
+struct compat_msqid64_ds {
+	struct compat_ipc64_perm msg_perm;
+	compat_time_t  msg_stime;
+	compat_ulong_t __unused1;
+	compat_time_t  msg_rtime;
+	compat_ulong_t __unused2;
+	compat_time_t  msg_ctime;
+	compat_ulong_t __unused3;
+	compat_ulong_t msg_cbytes;
+	compat_ulong_t msg_qnum;
+	compat_ulong_t msg_qbytes;
+	compat_pid_t   msg_lspid;
+	compat_pid_t   msg_lrpid;
+	compat_ulong_t __unused4;
+	compat_ulong_t __unused5;
+};
+
+struct compat_shmid64_ds {
+	struct compat_ipc64_perm shm_perm;
+	compat_size_t  shm_segsz;
+	compat_time_t  shm_atime;
+	compat_ulong_t __unused1;
+	compat_time_t  shm_dtime;
+	compat_ulong_t __unused2;
+	compat_time_t  shm_ctime;
+	compat_ulong_t __unused3;
+	compat_pid_t   shm_cpid;
+	compat_pid_t   shm_lpid;
+	compat_ulong_t shm_nattch;
+	compat_ulong_t __unused4;
+	compat_ulong_t __unused5;
+};
+
+static inline int is_compat_task(void)
+{
+	return test_thread_flag(TIF_32BIT);
+}
+
+static inline int is_compat_thread(struct thread_info *thread)
+{
+	return test_ti_thread_flag(thread, TIF_32BIT);
+}
+
+#else /* !CONFIG_COMPAT */
+
+static inline int is_compat_task(void)
+{
+	return 0;
+}
+
+static inline int is_compat_thread(struct thread_info *thread)
+{
+	return 0;
+}
+
+#endif /* CONFIG_COMPAT */
+#endif /* __KERNEL__ */
+#endif /* __ASM_COMPAT_H */
arch/arm64/include/asm/signal32.h new file +53 -0

53 lines not on this page · raw message

arch/arm64/include/asm/unistd32.h new file +758 -0

758 lines not on this page · raw message

arch/arm64/kernel/kuser32.S new file +77 -0

77 lines not on this page · raw message

arch/arm64/kernel/signal32.c new file +876 -0

876 lines not on this page · raw message

arch/arm64/kernel/sys32.S new file +282 -0

282 lines not on this page · raw message

arch/arm64/kernel/sys_compat.c new file +164 -0

164 lines not on this page · raw message

maintainer
#80 lore raw

Re: [PATCH v3 21/31] arm64: 32-bit (compat) applications support

Quoted 10 lines · Catalin Marinas

From: Will Deacon <[email protected]>

This patch adds support for 32-bit applications. The vectors page is a binary blob mapped into the application user space at 0xffff0000 (the AArch64 toolchain does not support compilation of AArch32 code). Full compatibility with ARMv7 user space is supported. The use of deprecated ARMv7 functionality (SWP, CP15 barriers) has been disabled by default on AArch64 kernels and unaligned LDM/STM is not supported.

Quoted 6 lines

Please note that only the ARM 32-bit EABI is supported, so no OABI compatibility.

I guess you haven't had time to turn any of these into architecture independent functions as discussed last time?

Arnd

author maintainer
#81 lore raw

Re: [PATCH v3 21/31] arm64: 32-bit (compat) applications support

Quoted 14 lines · Arnd Bergmann
Quoted 13 lines · Catalin Marinas

From: Will Deacon <[email protected]>

This patch adds support for 32-bit applications. The vectors page is a binary blob mapped into the application user space at 0xffff0000 (the AArch64 toolchain does not support compilation of AArch32 code). Full compatibility with ARMv7 user space is supported. The use of deprecated ARMv7 functionality (SWP, CP15 barriers) has been disabled by default on AArch64 kernels and unaligned LDM/STM is not supported.

Please note that only the ARM 32-bit EABI is supported, so no OABI compatibility.

Quoted 6 lines
Quoted 3 lines

I guess you haven't had time to turn any of these into architecture independent functions as discussed last time?

Here they are. For converting the other architectures, I'll post separate patches as I don't want to add an extra dependency to the arm64 series.

Quoted 1 line

From 87fb5301a44ac05b4e6d7245db02acc2dedde831 Mon Sep 17 00:00:00 2001

From: Catalin Marinas <[email protected]>
Date: Thu, 13 Sep 2012 09:51:10 +0100
Subject: [PATCH 1/3] Add generic compat_sys_sendfile and
compat_sys_sendfile64

These functions are used by other architectures requiring compat support, so just make them generic.

---
 include/linux/compat.h |    5 +++++
 kernel/compat.c        |   44 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 49 insertions(+), 0 deletions(-)
include/linux/compat.h +5 -0
index c4be3f5..e2f5e9a 100644
@@ -594,6 +594,11 @@ asmlinkage ssize_t compat_sys_process_vm_writev(compat_pid_t pid,
 		unsigned long liovcnt, const struct compat_iovec __user *rvec,
 		unsigned long riovcnt, unsigned long flags);
 
+asmlinkage int compat_sys_sendfile(int out_fd, int in_fd,
+				   compat_off_t __user *offset, s32 count);
+asmlinkage int compat_sys_sendfile64(int out_fd, int in_fd,
+				     compat_loff_t __user *offset, s32 count);
+
 #else
 
 #define is_compat_task() (0)
kernel/compat.c +44 -0

50 lines not on this page · raw message

Quoted 1 line

From fa734f9523e35d7a6e9ab5e252ab344133111c1f Mon Sep 17 00:00:00 2001

From: Catalin Marinas <[email protected]>
Date: Thu, 13 Sep 2012 09:55:17 +0100
Subject: [PATCH 2/3] Add generic compat_sys_sched_rr_get_interval
implementation

This patch adds a generic implementation for compat_sys_sched_rr_get_interval as it is used by other architectures.

---
 include/linux/compat.h |    3 +++
 kernel/compat.c        |   17 +++++++++++++++++
 2 files changed, 20 insertions(+), 0 deletions(-)
include/linux/compat.h +3 -0
index e2f5e9a..bbe89b8 100644
@@ -599,6 +599,9 @@ asmlinkage int compat_sys_sendfile(int out_fd, int in_fd,
 asmlinkage int compat_sys_sendfile64(int out_fd, int in_fd,
 				     compat_loff_t __user *offset, s32 count);
 
+asmlinkage int compat_sys_sched_rr_get_interval(compat_pid_t pid,
+						struct compat_timespec __user *interval);
+
 #else
 
 #define is_compat_task() (0)
kernel/compat.c +17 -0
index 5f07388..3961f67 100644
@@ -1259,6 +1259,23 @@ asmlinkage int compat_sys_sendfile64(int out_fd, int in_fd,
 }
 #endif /* __ARCH_WANT_COMPAT_SYS_SENDFILE64 */
 
+#ifdef __ARCH_WANT_COMPAT_SYS_SCHED_RR_GET_INTERVAL
+asmlinkage int compat_sys_sched_rr_get_interval(compat_pid_t pid,
+						struct compat_timespec __user *interval)
+{
+	struct timespec t;
+	int ret;
+	mm_segment_t old_fs = get_fs();
+
+	set_fs(KERNEL_DS);
+	ret = sys_sched_rr_get_interval(pid, (struct timespec __user *)&t);
+	set_fs(old_fs);
+	if (put_compat_timespec(&t, interval))
+		return -EFAULT;
+	return ret;
+}
+#endif /* __ARCH_WANT_COMPAT_SYS_SCHED_RR_GET_INTERVAL */
+
 /*
  * Allocate user-space memory for the duration of a single system call,
  * in order to marshall parameters inside a compat thunk.
Quoted 1 line

From 79ed6c77bdd4480b81defe1cd81198235e9d4d03 Mon Sep 17 00:00:00 2001

From: Catalin Marinas <[email protected]>
Date: Thu, 13 Sep 2012 10:02:26 +0100
Subject: [PATCH 3/3] arm64: Use generic compat_sys_sendfile and
compat_sys_sched_rr_get_interval

This patch switches the arm64 port to use the generic implementation of the above functions.

---
 arch/arm64/include/asm/unistd32.h |    2 ++
 arch/arm64/kernel/sys_compat.c    |   35 -----------------------------------
 2 files changed, 2 insertions(+), 35 deletions(-)
arch/arm64/include/asm/unistd32.h +2 -0
index a50405f..4161b4c 100644
@@ -754,5 +754,7 @@ __SYSCALL(__NR_syncfs, sys_syncfs)
 #define __ARCH_WANT_SYS_SIGPENDING
 #define __ARCH_WANT_SYS_SIGPROCMASK
 #define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
+#define __ARCH_WANT_COMPAT_SYS_SENDFILE
+#define __ARCH_WANT_COMPAT_SYS_SCHED_RR_GET_INTERVAL
 
 #endif /* __ASM_UNISTD32_H */
arch/arm64/kernel/sys_compat.c +0 -35
index d77ba8e..740485d 100644
@@ -51,41 +51,6 @@ asmlinkage int compat_sys_vfork(struct pt_regs *regs)
 		       regs, 0, NULL, NULL);
 }
 
-asmlinkage int compat_sys_sched_rr_get_interval(compat_pid_t pid,
-						struct compat_timespec __user *interval)
-{
-	struct timespec t;
-	int ret;
-	mm_segment_t old_fs = get_fs();
-
-	set_fs(KERNEL_DS);
-	ret = sys_sched_rr_get_interval(pid, (struct timespec __user *)&t);
-	set_fs(old_fs);
-	if (put_compat_timespec(&t, interval))
-		return -EFAULT;
-	return ret;
-}
-
-asmlinkage int compat_sys_sendfile(int out_fd, int in_fd,
-				   compat_off_t __user *offset, s32 count)
-{
-	mm_segment_t old_fs = get_fs();
-	int ret;
-	off_t of;
-
-	if (offset && get_user(of, offset))
-		return -EFAULT;
-
-	set_fs(KERNEL_DS);
-	ret = sys_sendfile(out_fd, in_fd, offset ? (off_t __user *)&of : NULL,
-			   count);
-	set_fs(old_fs);
-
-	if (offset && put_user(of, offset))
-		return -EFAULT;
-	return ret;
-}
-
 static inline void
 do_compat_cache_op(unsigned long start, unsigned long end, int flags)
 {
Signature · 1 line
Catalin
maintainer Acked-by
#82 lore raw

Re: [PATCH v3 21/31] arm64: 32-bit (compat) applications support

Quoted 3 lines · Catalin Marinas

Here they are. For converting the other architectures, I'll post separate patches as I don't want to add an extra dependency to the arm64 series.

Ok, thanks!

Quoted 19 lines
kernel/compat.c +11 -0
index c28a306..5f07388 100644
@@ -1215,6 +1215,50 @@ compat_sys_sysinfo(struct compat_sysinfo __user *info)
        return 0;
 }
 
+#ifdef __ARCH_WANT_COMPAT_SYS_SENDFILE
+asmlinkage int compat_sys_sendfile(int out_fd, int in_fd,
+                                  compat_off_t __user *offset, s32 count)
+{
+       mm_segment_t old_fs = get_fs();
+       int ret;
+       off_t of;
+
+       if (offset && get_user(of, offset))
+               return -EFAULT;
+

kernel/compat.c compat_sys_sysinfo(struct compat_sysinfo __user *info) · line 1238

Quoted 10 lines
kernel/compat.c +10 -0
+       set_fs(KERNEL_DS);
+       ret = sys_sendfile(out_fd, in_fd,
+                          offset ? (off_t __user *)&of : NULL, count);
+       set_fs(old_fs);
+
+       if (offset && put_user(of, offset))
+               return -EFAULT;
+       return ret;
+}
+#endif /* __ARCH_WANT_COMPAT_SYS_SENDFILE */

Looking at this code in detail now, I think it's better to move the functions to fs/read_write.c and get rid of the get_fs/set_fs hack, like

asmlinkage int compat_sys_sendfile(int out_fd, int in_fd,
compat_off_t __user *offset, s32 count)

{       
        loff_t pos;
        compat_off_t off;
        ssize_t ret;
        
        if (offset) {
                if (unlikely(get_user(off, offset)))
                        return -EFAULT;
                pos = off;
                ret = do_sendfile(out_fd, in_fd, &pos, count, MAX_NON_LFS);
                if (unlikely(put_user(pos, offset)))
                        return -EFAULT;
                return ret;
        }
        
        return do_sendfile(out_fd, in_fd, NULL, count, 0);
}

This implementation is smaller and more efficient than the common one.

Same for compat_sys_sendfile64, although I don't think there is ever a case where loff_t is defined differently from compat_loff_t, so you can probably just use the native sys_sendfile64 for the compat case.

Quoted 8 lines
kernel/compat.c +7 -0
+#ifdef __ARCH_WANT_COMPAT_SYS_SCHED_RR_GET_INTERVAL
+asmlinkage int compat_sys_sched_rr_get_interval(compat_pid_t pid,
+                                               struct compat_timespec __user *interval)
+{
+       struct timespec t;
+       int ret;
+       mm_segment_t old_fs = get_fs();

kernel/compat.c asmlinkage int compat_sys_sendfile64(int out_fd, int in_fd, · line 1278

Quoted 10 lines
kernel/compat.c +10 -0
+
+       set_fs(KERNEL_DS);
+       ret = sys_sched_rr_get_interval(pid, (struct timespec __user *)&t);
+       set_fs(old_fs);
+       if (put_compat_timespec(&t, interval))
+               return -EFAULT;
+       return ret;
+}
+#endif /* __ARCH_WANT_COMPAT_SYS_SCHED_RR_GET_INTERVAL */
+

This one looks reasonable. It would be nice to kill the get_fs/set_fs but here it would just make the native code slower or duplicate a lot of it.

author maintainer
#83 lore raw

Re: [PATCH v3 21/31] arm64: 32-bit (compat) applications support

Quoted 26 lines · Arnd Bergmann
Quoted 11 lines · Catalin Marinas
(quoted diff) +11 -0
+#ifdef __ARCH_WANT_COMPAT_SYS_SENDFILE
+asmlinkage int compat_sys_sendfile(int out_fd, int in_fd,
+                                  compat_off_t __user *offset, s32 count)
+{
+       mm_segment_t old_fs = get_fs();
+       int ret;
+       off_t of;
+
+       if (offset && get_user(of, offset))
+               return -EFAULT;
+

Review

Quoted 10 lines
(quoted diff) +10 -0
+       set_fs(KERNEL_DS);
+       ret = sys_sendfile(out_fd, in_fd,
+                          offset ? (off_t __user *)&of : NULL, count);
+       set_fs(old_fs);
+
+       if (offset && put_user(of, offset))
+               return -EFAULT;
+       return ret;
+}
+#endif /* __ARCH_WANT_COMPAT_SYS_SENDFILE */

Looking at this code in detail now, I think it's better to move the functions to fs/read_write.c and get rid of the get_fs/set_fs hack, like

Quoted 2 lines

asmlinkage int compat_sys_sendfile(int out_fd, int in_fd,
compat_off_t __user *offset, s32 count)

...

It makes sense (copied below, just for compat_sys_sendfile until my comments below are clarified). One minor improvement, I think we should use compat_size_t for the count, it is a u32 in all cases.

Quoted 6 lines

This implementation is smaller and more efficient than the common one.

Same for compat_sys_sendfile64, although I don't think there is ever a case where loff_t is defined differently from compat_loff_t, so you can probably just use the native sys_sendfile64 for the compat case.

That's what we do on AArch64, though powerpc and sparc define their own. The "count" argument would be different between compat and non-compat versions and I'm not sure what assumptions are made on the syscall entry path on these architectures (on AArch64 we ensure that the top 32-bit part of an X register is always 0 for 32-bit syscalls).

Another difference is that the "count" argument for compat_sys_sendfile64 is s32 on powerpc and u32 on sparc. I can't tell whether it would make a difference in practice but if we use compat_size_t for the generic version the powerpc wouldn't get the sign extension.

Powerpc has some comment about a need to treat in_fd/out_fd arguments as signed ints but I don't fully understand it (well, maybe powerpc needs the sign to be fully extended to 64-bit even for int).

----------8<-----------------------

Quoted 1 line

From 7c6747fc9f69d20f445e4af69c644acb04a74f45 Mon Sep 17 00:00:00 2001

From: Catalin Marinas <[email protected]>
Date: Thu, 13 Sep 2012 09:51:10 +0100
Subject: [PATCH 1/3] Add generic compat_sys_sendfile implementation

This function is used by other architectures requiring compat support, so just make it generic.

---
 fs/read_write.c        |   22 ++++++++++++++++++++++
 include/linux/compat.h |    3 +++
 2 files changed, 25 insertions(+), 0 deletions(-)
fs/read_write.c +22 -0
index 1adfb69..91b91c4 100644
@@ -1007,3 +1007,25 @@ SYSCALL_DEFINE4(sendfile64, int, out_fd, int, in_fd, loff_t __user *, offset, si
 
 	return do_sendfile(out_fd, in_fd, NULL, count, 0);
 }
+
+#ifdef __ARCH_WANT_COMPAT_SYS_SENDFILE
+asmlinkage int compat_sys_sendfile(int out_fd, int in_fd,
+				   compat_off_t __user *offset, compat_size_t count)
+{
+	loff_t pos;
+	off_t off;
+	ssize_t ret;
+
+	if (offset) {
+		if (unlikely(get_user(off, offset)))
+			return -EFAULT;
+		pos = off;
+		ret = do_sendfile(out_fd, in_fd, &pos, count, MAX_NON_LFS);
+		if (unlikely(put_user(pos, offset)))
+			return -EFAULT;
+		return ret;
+	}
+
+	return do_sendfile(out_fd, in_fd, NULL, count, 0);
+}
+#endif /* __ARCH_WANT_COMPAT_SYS_SENDFILE */
include/linux/compat.h +3 -0
index c4be3f5..f386e82 100644
@@ -594,6 +594,9 @@ asmlinkage ssize_t compat_sys_process_vm_writev(compat_pid_t pid,
 		unsigned long liovcnt, const struct compat_iovec __user *rvec,
 		unsigned long riovcnt, unsigned long flags);
 
+asmlinkage int compat_sys_sendfile(int out_fd, int in_fd,
+				   compat_off_t __user *offset, s32 count);
+
 #else
 
 #define is_compat_task() (0)
author maintainer
#84 lore raw

PATCH v3 22/31 arm64: Floating point and SIMD

In reply to Catalin Marinas

This patch adds support for FP/ASIMD register bank saving and restoring during context switch and FP exception handling to generate SIGFPE. There are 32 128-bit registers and the context switching is currently done non-lazily. Benchmarks on real hardware are required before implementing lazy FP state saving/restoring.

---
 arch/arm64/include/asm/fpsimd.h  |   64 +++++++++++++++++++++++
 arch/arm64/kernel/entry-fpsimd.S |   80 ++++++++++++++++++++++++++++
 arch/arm64/kernel/fpsimd.c       |  106 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 250 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm64/include/asm/fpsimd.h
 create mode 100644 arch/arm64/kernel/entry-fpsimd.S
 create mode 100644 arch/arm64/kernel/fpsimd.c
arch/arm64/include/asm/fpsimd.h new file +64 -0
new file mode 100644
index 0000000..b42fab9
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2012 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_FP_H
+#define __ASM_FP_H
+
+#include <asm/ptrace.h>
+
+#ifndef __ASSEMBLY__
+
+/*
+ * FP/SIMD storage area has:
+ *  - FPSR and FPCR
+ *  - 32 128-bit data registers
+ *
+ * Note that user_fp forms a prefix of this structure, which is relied
+ * upon in the ptrace FP/SIMD accessors. struct user_fpsimd_state must
+ * form a prefix of struct fpsimd_state.
+ */
+struct fpsimd_state {
+	union {
+		struct user_fpsimd_state user_fpsimd;
+		struct {
+			__uint128_t vregs[32];
+			u32 fpsr;
+			u32 fpcr;
+		};
+	};
+};
+
+#if defined(__KERNEL__) && defined(CONFIG_COMPAT)
+/* Masks for extracting the FPSR and FPCR from the FPSCR */
+#define VFP_FPSCR_STAT_MASK	0xf800009f
+#define VFP_FPSCR_CTRL_MASK	0x07f79f00
+/*
+ * The VFP state has 32x64-bit registers and a single 32-bit
+ * control/status register.
+ */
+#define VFP_STATE_SIZE		((32 * 8) + 4)
+#endif
+
+struct task_struct;
+
+extern void fpsimd_save_state(struct fpsimd_state *state);
+extern void fpsimd_load_state(struct fpsimd_state *state);
+
+extern void fpsimd_thread_switch(struct task_struct *next);
+extern void fpsimd_flush_thread(void);
+
+#endif
+
+#endif
arch/arm64/kernel/entry-fpsimd.S new file +80 -0

80 lines not on this page · raw message

arch/arm64/kernel/fpsimd.c new file +106 -0

106 lines not on this page · raw message

author maintainer
#85 lore raw

PATCH v3 23/31 arm64: Debugging support

In reply to Catalin Marinas

From: Will Deacon <[email protected]>

This patch adds ptrace, debug monitors and hardware breakpoints support.

---
 arch/arm64/include/asm/debug-monitors.h |   88 +++
 arch/arm64/include/asm/hw_breakpoint.h  |  137 ++++
 arch/arm64/kernel/debug-monitors.c      |  288 ++++++++
 arch/arm64/kernel/hw_breakpoint.c       |  880 ++++++++++++++++++++++++
 arch/arm64/kernel/ptrace.c              | 1126 +++++++++++++++++++++++++++++++
 include/linux/elf.h                     |    3 +
 6 files changed, 2522 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm64/include/asm/debug-monitors.h
 create mode 100644 arch/arm64/include/asm/hw_breakpoint.h
 create mode 100644 arch/arm64/kernel/debug-monitors.c
 create mode 100644 arch/arm64/kernel/hw_breakpoint.c
 create mode 100644 arch/arm64/kernel/ptrace.c
arch/arm64/include/asm/debug-monitors.h new file +88 -0
new file mode 100644
index 0000000..7eaa0b3
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2012 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_DEBUG_MONITORS_H
+#define __ASM_DEBUG_MONITORS_H
+
+#ifdef __KERNEL__
+
+#define	DBG_ESR_EVT(x)		(((x) >> 27) & 0x7)
+
+/* AArch64 */
+#define DBG_ESR_EVT_HWBP	0x0
+#define DBG_ESR_EVT_HWSS	0x1
+#define DBG_ESR_EVT_HWWP	0x2
+#define DBG_ESR_EVT_BRK		0x6
+
+enum debug_el {
+	DBG_ACTIVE_EL0 = 0,
+	DBG_ACTIVE_EL1,
+};
+
+/* AArch32 */
+#define DBG_ESR_EVT_BKPT	0x4
+#define DBG_ESR_EVT_VECC	0x5
+
+#define AARCH32_BREAK_ARM	0x07f001f0
+#define AARCH32_BREAK_THUMB	0xde01
+#define AARCH32_BREAK_THUMB2_LO	0xf7f0
+#define AARCH32_BREAK_THUMB2_HI	0xa000
+
+#ifndef __ASSEMBLY__
+struct task_struct;
+
+#define local_dbg_save(flags)							\
+	do {									\
+		typecheck(unsigned long, flags);				\
+		asm volatile(							\
+		"mrs	%0, daif			// local_dbg_save\n"	\
+		"msr	daifset, #8"						\
+		: "=r" (flags) : : "memory");					\
+	} while (0)
+
+#define local_dbg_restore(flags)						\
+	do {									\
+		typecheck(unsigned long, flags);				\
+		asm volatile(							\
+		"msr	daif, %0			// local_dbg_restore\n"	\
+		: : "r" (flags) : "memory");					\
+	} while (0)
+
+#define DBG_ARCH_ID_RESERVED	0	/* In case of ptrace ABI updates. */
+
+u8 debug_monitors_arch(void);
+
+void enable_debug_monitors(enum debug_el el);
+void disable_debug_monitors(enum debug_el el);
+
+void user_rewind_single_step(struct task_struct *task);
+void user_fastforward_single_step(struct task_struct *task);
+
+void kernel_enable_single_step(struct pt_regs *regs);
+void kernel_disable_single_step(void);
+int kernel_active_single_step(void);
+
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+int reinstall_suspended_bps(struct pt_regs *regs);
+#else
+static inline int reinstall_suspended_bps(struct pt_regs *regs)
+{
+	return -ENODEV;
+}
+#endif
+
+#endif	/* __ASSEMBLY */
+#endif	/* __KERNEL__ */
+#endif	/* __ASM_DEBUG_MONITORS_H */
arch/arm64/include/asm/hw_breakpoint.h new file +137 -0

137 lines not on this page · raw message

arch/arm64/kernel/debug-monitors.c new file +288 -0

288 lines not on this page · raw message

arch/arm64/kernel/hw_breakpoint.c new file +880 -0

880 lines not on this page · raw message

arch/arm64/kernel/ptrace.c new file +1126 -0

1,126 lines not on this page · raw message

include/linux/elf.h +3 -0
index 999b4f5..1e935e4 100644
@@ -388,6 +388,9 @@ typedef struct elf64_shdr {
 #define NT_S390_LAST_BREAK	0x306	/* s390 breaking event address */
 #define NT_S390_SYSTEM_CALL	0x307	/* s390 system call restart data */
 #define NT_ARM_VFP	0x400		/* ARM VFP/NEON registers */
+#define NT_ARM_TLS	0x401		/* ARM TLS register */
+#define NT_ARM_HW_BREAK	0x402		/* ARM hardware breakpoint registers */
+#define NT_ARM_HW_WATCH	0x403		/* ARM hardware watchpoint registers */
 
 
 /* Note header in a PT_NOTE section */
author maintainer
#87 lore raw

PATCH v3 24/31 arm64: Add support for /proc/sys/debug/exception-trace

In reply to Catalin Marinas

This patch allows setting of the show_unhandled_signals variable via /proc/sys/debug/exception-trace. The default value is currently 1 showing unhandled user faults (undefined instructions, data aborts) and invalid signal stack frames.

---
 kernel/sysctl.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
kernel/sysctl.c +1 -1
index 87174ef..79dcb00 100644
@@ -1544,7 +1544,7 @@ static struct ctl_table fs_table[] = {
 
 static struct ctl_table debug_table[] = {
 #if defined(CONFIG_X86) || defined(CONFIG_PPC) || defined(CONFIG_SPARC) || \
-    defined(CONFIG_S390) || defined(CONFIG_TILE)
+    defined(CONFIG_S390) || defined(CONFIG_TILE) || defined(CONFIG_ARM64)
 	{
 		.procname	= "exception-trace",
 		.data		= &show_unhandled_signals,
author maintainer
#88 lore raw

PATCH v3 25/31 arm64: Performance counters support

In reply to Catalin Marinas

From: Will Deacon <[email protected]>

This patch adds support for the AArch64 performance counters.

---
 arch/arm64/include/asm/perf_event.h |   22 +
 arch/arm64/include/asm/pmu.h        |   82 +++
 arch/arm64/kernel/perf_event.c      | 1368 +++++++++++++++++++++++++++++++++++
 tools/perf/perf.h                   |    6 +
 4 files changed, 1478 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm64/include/asm/perf_event.h
 create mode 100644 arch/arm64/include/asm/pmu.h
 create mode 100644 arch/arm64/kernel/perf_event.c
arch/arm64/include/asm/perf_event.h new file +22 -0
new file mode 100644
index 0000000..a6fffd5
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2012 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_PERF_EVENT_H
+#define __ASM_PERF_EVENT_H
+
+/* It's quiet around here... */
+
+#endif
arch/arm64/include/asm/pmu.h new file +82 -0

82 lines not on this page · raw message

arch/arm64/kernel/perf_event.c new file +1368 -0

1,368 lines not on this page · raw message

tools/perf/perf.h +6 -0
index f960ccb..8c36763 100644
@@ -88,6 +88,12 @@ void get_term_dimensions(struct winsize *ws);
 #define CPUINFO_PROC	"Processor"
 #endif
 
+#ifdef __aarch64__
+#include "../../arch/arm64/include/asm/unistd.h"
+#define rmb()		asm volatile("dmb ld" ::: "memory")
+#define cpu_relax()	asm volatile("yield" ::: "memory")
+#endif
+
 #ifdef __mips__
 #include "../../arch/mips/include/asm/unistd.h"
 #define rmb()		asm volatile(					\
author maintainer
#89 lore raw

PATCH v3 26/31 arm64: Miscellaneous library functions

In reply to Catalin Marinas

From: Marc Zyngier <[email protected]>

This patch adds udelay, memory and bit operations together with the ksyms exports.

---
 arch/arm64/include/asm/bitops.h  |   74 ++++++++++++++++++++++++++++
 arch/arm64/include/asm/syscall.h |  101 ++++++++++++++++++++++++++++++++++++++
 arch/arm64/kernel/arm64ksyms.c   |   46 +++++++++++++++++
 arch/arm64/lib/Makefile          |    4 ++
 arch/arm64/lib/bitops.c          |   25 +++++++++
 arch/arm64/lib/clear_page.S      |   39 +++++++++++++++
 arch/arm64/lib/copy_page.S       |   46 +++++++++++++++++
 arch/arm64/lib/delay.c           |   55 ++++++++++++++++++++
 8 files changed, 390 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm64/include/asm/bitops.h
 create mode 100644 arch/arm64/include/asm/syscall.h
 create mode 100644 arch/arm64/kernel/arm64ksyms.c
 create mode 100644 arch/arm64/lib/Makefile
 create mode 100644 arch/arm64/lib/bitops.c
 create mode 100644 arch/arm64/lib/clear_page.S
 create mode 100644 arch/arm64/lib/copy_page.S
 create mode 100644 arch/arm64/lib/delay.c
arch/arm64/include/asm/bitops.h new file +74 -0
new file mode 100644
index 0000000..67df4d2
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2012 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_BITOPS_H
+#define __ASM_BITOPS_H
+
+#include <linux/compiler.h>
+
+#include <asm/barrier.h>
+
+/*
+ * clear_bit may not imply a memory barrier
+ */
+#ifndef smp_mb__before_clear_bit
+#define smp_mb__before_clear_bit()	smp_mb()
+#define smp_mb__after_clear_bit()	smp_mb()
+#endif
+
+/*
+ * Use compiler builtins for simple inline operations.
+ */
+static inline unsigned long __ffs(unsigned long word)
+{
+	return __builtin_ffsl(word) - 1;
+}
+
+static inline int ffs(int x)
+{
+	return __builtin_ffs(x);
+}
+
+static inline unsigned long __fls(unsigned long word)
+{
+	return BITS_PER_LONG - 1 - __builtin_clzl(word);
+}
+
+static inline int fls(int x)
+{
+	return x ? sizeof(x) * BITS_PER_BYTE - __builtin_clz(x) : 0;
+}
+
+/*
+ * Mainly use the generic routines for now.
+ */
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
+#include <asm-generic/bitops/ffz.h>
+#include <asm-generic/bitops/fls64.h>
+#include <asm-generic/bitops/find.h>
+
+#include <asm-generic/bitops/sched.h>
+#include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/lock.h>
+
+#include <asm-generic/bitops/atomic.h>
+#include <asm-generic/bitops/non-atomic.h>
+#include <asm-generic/bitops/le.h>
+#include <asm-generic/bitops/ext2-atomic.h>
+
+#endif /* __ASM_BITOPS_H */
arch/arm64/include/asm/syscall.h new file +101 -0

101 lines not on this page · raw message

arch/arm64/kernel/arm64ksyms.c new file +46 -0

46 lines not on this page · raw message

arch/arm64/lib/Makefile new file +4 -0
new file mode 100644
index 0000000..2fb7f60
@@ -0,0 +1,4 @@
+lib-y		:= bitops.o delay.o					\
+		   strncpy_from_user.o strnlen_user.o clear_user.o	\
+		   copy_from_user.o copy_to_user.o copy_in_user.o	\
+		   copy_page.o clear_page.o
arch/arm64/lib/bitops.c new file +25 -0
new file mode 100644
index 0000000..aa4965e
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2012 ARM Limited
+ *
+ * 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/>.
+ */
+
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <linux/atomic.h>
+
+#ifdef CONFIG_SMP
+arch_spinlock_t __atomic_hash[ATOMIC_HASH_SIZE] __lock_aligned = {
+       [0 ... (ATOMIC_HASH_SIZE-1)]  = __ARCH_SPIN_LOCK_UNLOCKED
+};
+#endif
arch/arm64/lib/clear_page.S new file +39 -0
new file mode 100644
index 0000000..ef08e90
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2012 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/>.
+ */
+
+#include <linux/linkage.h>
+#include <linux/const.h>
+#include <asm/assembler.h>
+#include <asm/page.h>
+
+/*
+ * Clear page @dest
+ *
+ * Parameters:
+ *	x0 - dest
+ */
+ENTRY(clear_page)
+	mrs	x1, dczid_el0
+	and	w1, w1, #0xf
+	mov	x2, #4
+	lsl	x1, x2, x1
+
+1:	dc	zva, x0
+	add	x0, x0, x1
+	tst	x0, #(PAGE_SIZE - 1)
+	b.ne	1b
+	ret
+ENDPROC(clear_page)
arch/arm64/lib/copy_page.S new file +46 -0

46 lines not on this page · raw message

arch/arm64/lib/delay.c new file +55 -0

55 lines not on this page · raw message

maintainer
#90 lore raw

Re: [PATCH v3 26/31] arm64: Miscellaneous library functions

Quoted 12 lines · Catalin Marinas
arch/arm64/include/asm/bitops.h new file +12 -0
+/*
+ * Use compiler builtins for simple inline operations.
+ */
+static inline unsigned long __ffs(unsigned long word)
+{
+	return __builtin_ffsl(word) - 1;
+}
+
+static inline int ffs(int x)
+{
+	return __builtin_ffs(x);
+}

arch/arm64/include/asm/bitops.h line 52

Quoted 10 lines
arch/arm64/include/asm/bitops.h new file +10 -0
+
+static inline unsigned long __fls(unsigned long word)
+{
+	return BITS_PER_LONG - 1 - __builtin_clzl(word);
+}
+
+static inline int fls(int x)
+{
+	return x ? sizeof(x) * BITS_PER_BYTE - __builtin_clz(x) : 0;
+}

Still waiting for the generic version of these.

Arnd

author maintainer
#91 lore raw

Re: [PATCH v3 26/31] arm64: Miscellaneous library functions

Quoted 17 lines · Arnd Bergmann
Quoted 16 lines · Catalin Marinas
(quoted diff) +16 -0
+/*
+ * Use compiler builtins for simple inline operations.
+ */
+static inline unsigned long __ffs(unsigned long word)
+{
+	return __builtin_ffsl(word) - 1;
+}
+
+static inline int ffs(int x)
+{
+	return __builtin_ffs(x);
+}
+
+static inline unsigned long __fls(unsigned long word)
+{
+	return BITS_PER_LONG - 1 - __builtin_clzl(word);
Quoted 8 lines

Review

Quoted 6 lines
(quoted diff) +6 -0
+}
+
+static inline int fls(int x)
+{
+	return x ? sizeof(x) * BITS_PER_BYTE - __builtin_clz(x) : 0;
+}

Still waiting for the generic version of these.

What about these:

Quoted 1 line

From 64ec78a2fce931e0148db90747c69688f248a531 Mon Sep 17 00:00:00 2001

From: Catalin Marinas <[email protected]>
Date: Wed, 12 Sep 2012 22:00:53 +0100
Subject: [PATCH 1/2] Implement generic ffs/fls using __builtin_* functions

This patch implements ffs, __ffs, fls, __fls using __builtin_* gcc functions. These header files can be used by other architectures that rely on the gcc builtins.

---
 include/asm-generic/bitops/builtin-__ffs.h |   15 +++++++++++++++
 include/asm-generic/bitops/builtin-__fls.h |   15 +++++++++++++++
 include/asm-generic/bitops/builtin-ffs.h   |   17 +++++++++++++++++
 include/asm-generic/bitops/builtin-fls.h   |   16 ++++++++++++++++
 4 files changed, 63 insertions(+), 0 deletions(-)
 create mode 100644 include/asm-generic/bitops/builtin-__ffs.h
 create mode 100644 include/asm-generic/bitops/builtin-__fls.h
 create mode 100644 include/asm-generic/bitops/builtin-ffs.h
 create mode 100644 include/asm-generic/bitops/builtin-fls.h
include/asm-generic/bitops/builtin-__ffs.h new file +15 -0
new file mode 100644
index 0000000..90041e3
@@ -0,0 +1,15 @@
+#ifndef _ASM_GENERIC_BITOPS_BUILTIN___FFS_H_
+#define _ASM_GENERIC_BITOPS_BUILTIN___FFS_H_
+
+/**
+ * __ffs - find first bit in word.
+ * @word: The word to search
+ *
+ * Undefined if no bit exists, so code should check against 0 first.
+ */
+static __always_inline unsigned long __ffs(unsigned long word)
+{
+	return __builtin_ctzl(word);
+}
+
+#endif
include/asm-generic/bitops/builtin-__fls.h new file +15 -0
new file mode 100644
index 0000000..0248f38
@@ -0,0 +1,15 @@
+#ifndef _ASM_GENERIC_BITOPS_BUILTIN___FLS_H_
+#define _ASM_GENERIC_BITOPS_BUILTIN___FLS_H_
+
+/**
+ * __fls - find last (most-significant) set bit in a long word
+ * @word: the word to search
+ *
+ * Undefined if no set bit exists, so code should check against 0 first.
+ */
+static __always_inline unsigned long __fls(unsigned long word)
+{
+	return (sizeof(word) * 8) - 1 - __builtin_clzl(word);
+}
+
+#endif
include/asm-generic/bitops/builtin-ffs.h new file +17 -0
new file mode 100644
index 0000000..0648258
@@ -0,0 +1,17 @@
+#ifndef _ASM_GENERIC_BITOPS_BUILTIN_FFS_H_
+#define _ASM_GENERIC_BITOPS_BUILTIN_FFS_H_
+
+/**
+ * ffs - find first bit set
+ * @x: the word to search
+ *
+ * This is defined the same way as
+ * the libc and compiler builtin ffs routines, therefore
+ * differs in spirit from the above ffz (man ffs).
+ */
+static __always_inline int ffs(int x)
+{
+	return __builtin_ffs(x);
+}
+
+#endif
include/asm-generic/bitops/builtin-fls.h new file +16 -0
new file mode 100644
index 0000000..eda652d
@@ -0,0 +1,16 @@
+#ifndef _ASM_GENERIC_BITOPS_BUILTIN_FLS_H_
+#define _ASM_GENERIC_BITOPS_BUILTIN_FLS_H_
+
+/**
+ * fls - find last (most-significant) bit set
+ * @x: the word to search
+ *
+ * This is defined the same way as ffs.
+ * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
+ */
+static __always_inline int fls(int x)
+{
+	return x ? sizeof(x) * 8 - __builtin_clz(x) : 0;
+}
+
+#endif
Quoted 1 line

From 542f0b34b5674d8472b820f1ce751118ecdf9470 Mon Sep 17 00:00:00 2001

From: Catalin Marinas <[email protected]>
Date: Wed, 12 Sep 2012 22:06:22 +0100
Subject: [PATCH 2/2] arm64: Use the generic builtin-* ffs/fls implementation

This patch removes the arm64-specific ffs/fls implementation and includes the generic gcc builtins implementation.

---
 arch/arm64/include/asm/bitops.h |   31 +++++--------------------------
 1 files changed, 5 insertions(+), 26 deletions(-)
arch/arm64/include/asm/bitops.h +5 -26
index 67df4d2..5e69307 100644
@@ -28,36 +28,15 @@
 #define smp_mb__after_clear_bit()	smp_mb()
 #endif
 
-/*
- * Use compiler builtins for simple inline operations.
- */
-static inline unsigned long __ffs(unsigned long word)
-{
-	return __builtin_ffsl(word) - 1;
-}
-
-static inline int ffs(int x)
-{
-	return __builtin_ffs(x);
-}
-
-static inline unsigned long __fls(unsigned long word)
-{
-	return BITS_PER_LONG - 1 - __builtin_clzl(word);
-}
-
-static inline int fls(int x)
-{
-	return x ? sizeof(x) * BITS_PER_BYTE - __builtin_clz(x) : 0;
-}
-
-/*
- * Mainly use the generic routines for now.
- */
 #ifndef _LINUX_BITOPS_H
 #error only <linux/bitops.h> can be included directly
 #endif
 
+#include <asm-generic/bitops/builtin-__ffs.h>
+#include <asm-generic/bitops/builtin-ffs.h>
+#include <asm-generic/bitops/builtin-__fls.h>
+#include <asm-generic/bitops/builtin-fls.h>
+
 #include <asm-generic/bitops/ffz.h>
 #include <asm-generic/bitops/fls64.h>
 #include <asm-generic/bitops/find.h>
maintainer Acked-by
#92 lore raw

Re: [PATCH v3 26/31] arm64: Miscellaneous library functions

Quoted 11 lines · Catalin Marinas

From 64ec78a2fce931e0148db90747c69688f248a531 Mon Sep 17 00:00:00 2001
From: Catalin Marinas <[email protected]>
Date: Wed, 12 Sep 2012 22:00:53 +0100
Subject: [PATCH 1/2] Implement generic ffs/fls using __builtin_* functions

This patch implements ffs, __ffs, fls, __fls using __builtin_* gcc functions. These header files can be used by other architectures that rely on the gcc builtins.

Very good.

author maintainer
#93 lore raw

PATCH v3 27/31 arm64: Loadable modules

In reply to Catalin Marinas

From: Will Deacon <[email protected]>

This patch adds support for loadable modules. Loadable modules are loaded 64MB below the kernel image due to branch relocation restrictions (see Documentation/arm64/memory.txt).

---
 arch/arm64/include/asm/module.h |   23 ++
 arch/arm64/kernel/module.c      |  456 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 479 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm64/include/asm/module.h
 create mode 100644 arch/arm64/kernel/module.c
arch/arm64/include/asm/module.h new file +23 -0
new file mode 100644
index 0000000..e80e232
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2012 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_MODULE_H
+#define __ASM_MODULE_H
+
+#include <asm-generic/module.h>
+
+#define MODULE_ARCH_VERMAGIC	"aarch64"
+
+#endif /* __ASM_MODULE_H */
arch/arm64/kernel/module.c new file +456 -0

456 lines not on this page · raw message

maintainer Acked-by on v3 27/31
#94 lore raw

Re: [PATCH v3 27/31] arm64: Loadable modules

Quoted 9 lines · Catalin Marinas

From: Will Deacon <[email protected]>

This patch adds support for loadable modules. Loadable modules are loaded 64MB below the kernel image due to branch relocation restrictions (see Documentation/arm64/memory.txt).

author maintainer
#95 lore raw

PATCH v3 28/31 arm64: Generic timers support

In reply to Catalin Marinas

From: Marc Zyngier <[email protected]>

This patch adds support for the ARM generic timers with A64 instructions for accessing the timer registers. It uses the physical counter as the clock source and the virtual counter as sched_clock.

The timer frequency can be specified via DT or read from the CNTFRQ_EL0 register. The physical counter is also accessible from user space allowing fast gettimeofday() implementation.

---
 arch/arm64/include/asm/arm_generic.h |  100 +++++++++++++++
 arch/arm64/include/asm/timex.h       |   29 +++++
 arch/arm64/kernel/time.c             |   65 ++++++++++
 drivers/clocksource/Kconfig          |    5 +
 drivers/clocksource/Makefile         |    1 +
 drivers/clocksource/arm_generic.c    |  232 ++++++++++++++++++++++++++++++++++
 include/clocksource/arm_generic.h    |   21 +++
 7 files changed, 453 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm64/include/asm/arm_generic.h
 create mode 100644 arch/arm64/include/asm/timex.h
 create mode 100644 arch/arm64/kernel/time.c
 create mode 100644 drivers/clocksource/arm_generic.c
 create mode 100644 include/clocksource/arm_generic.h
arch/arm64/include/asm/arm_generic.h new file +100 -0
new file mode 100644
index 0000000..e4cec9d
@@ -0,0 +1,100 @@
+/*
+ * arch/arm64/include/asm/arm_generic.h
+ *
+ * Copyright (C) 2012 ARM Ltd.
+ * Author: Marc Zyngier <[email protected]>
+ *
+ * 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_ARM_GENERIC_H
+#define __ASM_ARM_GENERIC_H
+
+#include <linux/clocksource.h>
+
+#define ARCH_TIMER_CTRL_ENABLE		(1 << 0)
+#define ARCH_TIMER_CTRL_IMASK		(1 << 1)
+#define ARCH_TIMER_CTRL_ISTATUS		(1 << 2)
+
+#define ARCH_TIMER_REG_CTRL		0
+#define ARCH_TIMER_REG_FREQ		1
+#define ARCH_TIMER_REG_TVAL		2
+
+static inline void arch_timer_reg_write(int reg, u32 val)
+{
+	switch (reg) {
+	case ARCH_TIMER_REG_CTRL:
+		asm volatile("msr cntp_ctl_el0,  %0" : : "r" (val));
+		break;
+	case ARCH_TIMER_REG_TVAL:
+		asm volatile("msr cntp_tval_el0, %0" : : "r" (val));
+		break;
+	default:
+		BUILD_BUG();
+	}
+
+	isb();
+}
+
+static inline u32 arch_timer_reg_read(int reg)
+{
+	u32 val;
+
+	switch (reg) {
+	case ARCH_TIMER_REG_CTRL:
+		asm volatile("mrs %0,  cntp_ctl_el0" : "=r" (val));
+		break;
+	case ARCH_TIMER_REG_FREQ:
+		asm volatile("mrs %0,   cntfrq_el0" : "=r" (val));
+		break;
+	case ARCH_TIMER_REG_TVAL:
+		asm volatile("mrs %0, cntp_tval_el0" : "=r" (val));
+		break;
+	default:
+		BUILD_BUG();
+	}
+
+	return val;
+}
+
+static inline void __cpuinit arch_counter_enable_user_access(void)
+{
+	u32 cntkctl;
+
+	/* Disable user access to the timers and the virtual counter. */
+	asm volatile("mrs	%0, cntkctl_el1" : "=r" (cntkctl));
+	cntkctl &= ~((3 << 8) | (1 << 1));
+
+	/* Enable user access to the physical counter and frequency. */
+	cntkctl |= 1;
+	asm volatile("msr	cntkctl_el1, %0" : : "r" (cntkctl));
+}
+
+static inline cycle_t arch_counter_get_cntpct(void)
+{
+	cycle_t cval;
+
+	asm volatile("mrs %0, cntpct_el0" : "=r" (cval));
+
+	return cval;
+}
+
+static inline cycle_t arch_counter_get_cntvct(void)
+{
+	cycle_t cval;
+
+	asm volatile("mrs %0, cntvct_el0" : "=r" (cval));
+
+	return cval;
+}
+
+#endif
arch/arm64/include/asm/timex.h new file +29 -0
new file mode 100644
index 0000000..b24a31a
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2012 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_TIMEX_H
+#define __ASM_TIMEX_H
+
+/*
+ * Use the current timer as a cycle counter since this is what we use for
+ * the delay loop.
+ */
+#define get_cycles()	({ cycles_t c; read_current_timer(&c); c; })
+
+#include <asm-generic/timex.h>
+
+#define ARCH_HAS_READ_CURRENT_TIMER
+
+#endif
arch/arm64/kernel/time.c new file +65 -0

65 lines not on this page · raw message

drivers/clocksource/Kconfig +5 -0
index d53cd0a..6a78073 100644
@@ -35,3 +35,8 @@ config CLKSRC_DBX500_PRCMU_SCHED_CLOCK
 	default y
 	help
 	  Use the always on PRCMU Timer as sched_clock
+
+config CLKSRC_ARM_GENERIC
+	def_bool y if ARM64
+	help
+	  This option enables support for the ARM generic timer.
drivers/clocksource/Makefile +1 -0
index b65d0c5..6591990 100644
@@ -13,3 +13,4 @@ obj-$(CONFIG_DW_APB_TIMER)	+= dw_apb_timer.o
 obj-$(CONFIG_DW_APB_TIMER_OF)	+= dw_apb_timer_of.o
 obj-$(CONFIG_CLKSRC_DBX500_PRCMU)	+= clksrc-dbx500-prcmu.o
 obj-$(CONFIG_ARMADA_370_XP_TIMER)	+= time-armada-370-xp.o
+obj-$(CONFIG_CLKSRC_ARM_GENERIC)	+= arm_generic.o
drivers/clocksource/arm_generic.c new file +232 -0

232 lines not on this page · raw message

include/clocksource/arm_generic.h new file +21 -0
new file mode 100644
index 0000000..5b41b0d
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2012 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 __CLKSOURCE_ARM_GENERIC_H
+#define __CLKSOURCE_ARM_GENERIC_H
+
+extern int arm_generic_timer_init(void);
+
+#endif
maintainer Acked-by on v3 28/31
#96 lore raw

Re: [PATCH v3 28/31] arm64: Generic timers support

Quoted 6 lines · Catalin Marinas

From: Marc Zyngier <[email protected]>

This patch adds support for the ARM generic timers with A64 instructions for accessing the timer registers. It uses the physical counter as the clock source and the virtual counter as sched_clock.

Quoted 8 lines

The timer frequency can be specified via DT or read from the CNTFRQ_EL0 register. The physical counter is also accessible from user space allowing fast gettimeofday() implementation.

Acked-by on v3 28/31
#97 lore raw

Re: [PATCH v3 28/31] arm64: Generic timers support

In reply to Catalin Marinas
Quoted 10 lines · Catalin Marinas

From: Marc Zyngier <[email protected]>

This patch adds support for the ARM generic timers with A64 instructions for accessing the timer registers. It uses the physical counter as the clock source and the virtual counter as sched_clock.

The timer frequency can be specified via DT or read from the CNTFRQ_EL0 register. The physical counter is also accessible from user space allowing fast gettimeofday() implementation.

Quoted 5 lines

---

Thanks for C3STOP update.

author maintainer
#98 lore raw

PATCH v3 29/31 arm64: Miscellaneous header files

In reply to Catalin Marinas

This patch introduces a few AArch64-specific header files together with Kbuild entries for generic headers.

---
 arch/arm64/include/asm/Kbuild        |   51 ++++++++++
 arch/arm64/include/asm/barrier.h     |   52 ++++++++++
 arch/arm64/include/asm/bitsperlong.h |   23 +++++
 arch/arm64/include/asm/byteorder.h   |   21 ++++
 arch/arm64/include/asm/cmpxchg.h     |  173 ++++++++++++++++++++++++++++++++++
 arch/arm64/include/asm/compiler.h    |   30 ++++++
 arch/arm64/include/asm/exception.h   |   23 +++++
 arch/arm64/include/asm/exec.h        |   23 +++++
 arch/arm64/include/asm/fcntl.h       |   29 ++++++
 arch/arm64/include/asm/system_misc.h |   54 +++++++++++
 10 files changed, 479 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm64/include/asm/Kbuild
 create mode 100644 arch/arm64/include/asm/barrier.h
 create mode 100644 arch/arm64/include/asm/bitsperlong.h
 create mode 100644 arch/arm64/include/asm/byteorder.h
 create mode 100644 arch/arm64/include/asm/cmpxchg.h
 create mode 100644 arch/arm64/include/asm/compiler.h
 create mode 100644 arch/arm64/include/asm/exception.h
 create mode 100644 arch/arm64/include/asm/exec.h
 create mode 100644 arch/arm64/include/asm/fcntl.h
 create mode 100644 arch/arm64/include/asm/system_misc.h
arch/arm64/include/asm/Kbuild new file +51 -0
new file mode 100644
index 0000000..35924a5
@@ -0,0 +1,51 @@
+include include/asm-generic/Kbuild.asm
+
+header-y += hwcap.h
+
+generic-y += bug.h
+generic-y += bugs.h
+generic-y += checksum.h
+generic-y += cputime.h
+generic-y += current.h
+generic-y += delay.h
+generic-y += div64.h
+generic-y += dma.h
+generic-y += emergency-restart.h
+generic-y += errno.h
+generic-y += ftrace.h
+generic-y += hw_irq.h
+generic-y += ioctl.h
+generic-y += ioctls.h
+generic-y += ipcbuf.h
+generic-y += irq_regs.h
+generic-y += kdebug.h
+generic-y += kmap_types.h
+generic-y += linkage.h
+generic-y += local.h
+generic-y += local64.h
+generic-y += mman.h
+generic-y += msgbuf.h
+generic-y += mutex.h
+generic-y += pci.h
+generic-y += percpu.h
+generic-y += poll.h
+generic-y += posix_types.h
+generic-y += resource.h
+generic-y += scatterlist.h
+generic-y += sections.h
+generic-y += segment.h
+generic-y += sembuf.h
+generic-y += serial.h
+generic-y += shmbuf.h
+generic-y += sizes.h
+generic-y += socket.h
+generic-y += sockios.h
+generic-y += string.h
+generic-y += switch_to.h
+generic-y += swab.h
+generic-y += termbits.h
+generic-y += termios.h
+generic-y += topology.h
+generic-y += types.h
+generic-y += unaligned.h
+generic-y += user.h
arch/arm64/include/asm/barrier.h new file +52 -0

52 lines not on this page · raw message

arch/arm64/include/asm/bitsperlong.h new file +23 -0
new file mode 100644
index 0000000..fce9c29
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2012 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_BITSPERLONG_H
+#define __ASM_BITSPERLONG_H
+
+#define __BITS_PER_LONG 64
+
+#include <asm-generic/bitsperlong.h>
+
+#endif	/* __ASM_BITSPERLONG_H */
arch/arm64/include/asm/byteorder.h new file +21 -0
new file mode 100644
index 0000000..2b92046
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2012 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_BYTEORDER_H
+#define __ASM_BYTEORDER_H
+
+#include <linux/byteorder/little_endian.h>
+
+#endif	/* __ASM_BYTEORDER_H */
arch/arm64/include/asm/cmpxchg.h new file +173 -0

173 lines not on this page · raw message

arch/arm64/include/asm/compiler.h new file +30 -0
new file mode 100644
index 0000000..ee35fd0
@@ -0,0 +1,30 @@
+/*
+ * Based on arch/arm/include/asm/compiler.h
+ *
+ * Copyright (C) 2012 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_COMPILER_H
+#define __ASM_COMPILER_H
+
+/*
+ * This is used to ensure the compiler did actually allocate the register we
+ * asked it for some inline assembly sequences.  Apparently we can't trust the
+ * compiler from one version to another so a bit of paranoia won't hurt.  This
+ * string is meant to be concatenated with the inline asm string and will
+ * cause compilation to stop on mismatch.  (for details, see gcc PR 15089)
+ */
+#define __asmeq(x, y)  ".ifnc " x "," y " ; .err ; .endif\n\t"
+
+#endif	/* __ASM_COMPILER_H */
arch/arm64/include/asm/exception.h new file +23 -0
new file mode 100644
index 0000000..ac63519
@@ -0,0 +1,23 @@
+/*
+ * Based on arch/arm/include/asm/exception.h
+ *
+ * Copyright (C) 2012 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_EXCEPTION_H
+#define __ASM_EXCEPTION_H
+
+#define __exception	__attribute__((section(".exception.text")))
+
+#endif	/* __ASM_EXCEPTION_H */
arch/arm64/include/asm/exec.h new file +23 -0
new file mode 100644
index 0000000..db0563c
@@ -0,0 +1,23 @@
+/*
+ * Based on arch/arm/include/asm/exec.h
+ *
+ * Copyright (C) 2012 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_EXEC_H
+#define __ASM_EXEC_H
+
+extern unsigned long arch_align_stack(unsigned long sp);
+
+#endif	/* __ASM_EXEC_H */
arch/arm64/include/asm/fcntl.h new file +29 -0
new file mode 100644
index 0000000..cd2e630
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2012 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_FCNTL_H
+#define __ASM_FCNTL_H
+
+/*
+ * Using our own definitions for AArch32 (compat) support.
+ */
+#define O_DIRECTORY	 040000	/* must be a directory */
+#define O_NOFOLLOW	0100000	/* don't follow links */
+#define O_DIRECT	0200000	/* direct disk access hint - currently ignored */
+#define O_LARGEFILE	0400000
+
+#include <asm-generic/fcntl.h>
+
+#endif
arch/arm64/include/asm/system_misc.h new file +54 -0

54 lines not on this page · raw message

author maintainer
#100 lore raw

PATCH v3 30/31 arm64: Build infrastructure

In reply to Catalin Marinas

This patch adds Makefile and Kconfig files required for building an AArch64 kernel.

---
 arch/arm64/Kconfig              |  222 +++++++++++++++++++++++++++++++++++++++
 arch/arm64/Kconfig.debug        |   27 +++++
 arch/arm64/Makefile             |   71 +++++++++++++
 arch/arm64/boot/.gitignore      |    2 +
 arch/arm64/boot/Makefile        |   36 +++++++
 arch/arm64/boot/install.sh      |   46 ++++++++
 arch/arm64/configs/defconfig    |   85 +++++++++++++++
 arch/arm64/include/asm/prom.h   |    1 +
 arch/arm64/kernel/.gitignore    |    1 +
 arch/arm64/kernel/Makefile      |   27 +++++
 arch/arm64/kernel/vmlinux.lds.S |  126 ++++++++++++++++++++++
 arch/arm64/mm/Makefile          |    4 +
 init/Kconfig                    |    3 +-
 lib/Kconfig.debug               |    6 +-
 14 files changed, 654 insertions(+), 3 deletions(-)
 create mode 100644 arch/arm64/Kconfig
 create mode 100644 arch/arm64/Kconfig.debug
 create mode 100644 arch/arm64/Makefile
 create mode 100644 arch/arm64/boot/.gitignore
 create mode 100644 arch/arm64/boot/Makefile
 create mode 100644 arch/arm64/boot/install.sh
 create mode 100644 arch/arm64/configs/defconfig
 create mode 100644 arch/arm64/include/asm/prom.h
 create mode 100644 arch/arm64/kernel/.gitignore
 create mode 100644 arch/arm64/kernel/Makefile
 create mode 100644 arch/arm64/kernel/vmlinux.lds.S
 create mode 100644 arch/arm64/mm/Makefile
arch/arm64/Kconfig new file +222 -0
new file mode 100644
index 0000000..767ba56
@@ -0,0 +1,222 @@
+config ARM64
+	def_bool y
+	select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
+	select GENERIC_CLOCKEVENTS
+	select GENERIC_HARDIRQS_NO_DEPRECATED
+	select GENERIC_IOMAP
+	select GENERIC_IRQ_PROBE
+	select GENERIC_IRQ_SHOW
+	select GENERIC_SMP_IDLE_THREAD
+	select GENERIC_TIME_VSYSCALL
+	select HARDIRQS_SW_RESEND
+	select HAVE_ARCH_TRACEHOOK
+	select HAVE_DMA_API_DEBUG
+	select HAVE_DMA_ATTRS
+	select HAVE_GENERIC_DMA_COHERENT
+	select HAVE_GENERIC_HARDIRQS
+	select HAVE_HW_BREAKPOINT if PERF_EVENTS
+	select HAVE_IRQ_WORK
+	select HAVE_MEMBLOCK
+	select HAVE_PERF_EVENTS
+	select HAVE_SPARSE_IRQ
+	select IRQ_DOMAIN
+	select NO_BOOTMEM
+	select OF
+	select OF_EARLY_FLATTREE
+	select PERF_USE_VMALLOC
+	select RTC_LIB
+	select SPARSE_IRQ
+	help
+	  ARM 64-bit (AArch64) Linux support.
+
+config 64BIT
+	def_bool y
+
+config ARCH_PHYS_ADDR_T_64BIT
+	def_bool y
+
+config MMU
+	def_bool y
+
+config NO_IOPORT
+	def_bool y
+
+config STACKTRACE_SUPPORT
+	def_bool y
+
+config LOCKDEP_SUPPORT
+	def_bool y
+
+config TRACE_IRQFLAGS_SUPPORT
+	def_bool y
+
+config GENERIC_LOCKBREAK
+	def_bool y
+	depends on SMP && PREEMPT
+
+config RWSEM_GENERIC_SPINLOCK
+	def_bool y
+
+config GENERIC_HWEIGHT
+	def_bool y
+
+config GENERIC_CSUM
+        def_bool y
+
+config GENERIC_CALIBRATE_DELAY
+	def_bool y
+
+config ZONE_DMA32
+	def_bool y
+
+config ARCH_DMA_ADDR_T_64BIT
+	def_bool y
+
+config NEED_DMA_MAP_STATE
+	def_bool y
+
+config NEED_SG_DMA_LENGTH
+	def_bool y
+
+config SWIOTLB
+	def_bool y
+
+config IOMMU_HELPER
+	def_bool SWIOTLB
+
+source "init/Kconfig"
+
+source "kernel/Kconfig.freezer"
+
+menu "System Type"
+
+endmenu
+
+menu "Bus support"
+
+config ARM_AMBA
+	bool
+
+endmenu
+
+menu "Kernel Features"
+
+source "kernel/time/Kconfig"
+
+config ARM64_64K_PAGES
+	bool "Enable 64KB pages support"
+	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.
+
+config SMP
+	bool "Symmetric Multi-Processing"
+	select USE_GENERIC_SMP_HELPERS
+	help
+	  This enables support for systems with more than one CPU.  If
+	  you say N here, the kernel will run on single and
+	  multiprocessor machines, but will use only one CPU of a
+	  multiprocessor machine. If you say Y here, the kernel will run
+	  on many, but not all, single processor machines. On a single
+	  processor machine, the kernel will run faster if you say N
+	  here.
+
+	  If you don't know what to do here, say N.
+
+config NR_CPUS
+	int "Maximum number of CPUs (2-32)"
+	range 2 32
+	depends on SMP
+	default "4"
+
+source kernel/Kconfig.preempt
+
+config HZ
+	int
+	default 100
+
+config ARCH_HAS_HOLES_MEMORYMODEL
+	def_bool y if SPARSEMEM
+
+config ARCH_SPARSEMEM_ENABLE
+	def_bool y
+	select SPARSEMEM_VMEMMAP_ENABLE
+
+config ARCH_SPARSEMEM_DEFAULT
+	def_bool ARCH_SPARSEMEM_ENABLE
+
+config ARCH_SELECT_MEMORY_MODEL
+	def_bool ARCH_SPARSEMEM_ENABLE
+
+config HAVE_ARCH_PFN_VALID
+	def_bool ARCH_HAS_HOLES_MEMORYMODEL || !SPARSEMEM
+
+config HW_PERF_EVENTS
+	bool "Enable hardware performance counter support for perf events"
+	depends on PERF_EVENTS
+	default y
+	help
+	  Enable hardware performance counter support for perf events. If
+	  disabled, perf events will use software events only.
+
+source "mm/Kconfig"
+
+endmenu
+
+menu "Boot options"
+
+config CMDLINE
+	string "Default kernel command string"
+	default ""
+	help
+	  Provide a set of default command-line options at build time by
+	  entering them here. As a minimum, you should specify the the
+	  root device (e.g. root=/dev/nfs).
+
+config CMDLINE_FORCE
+	bool "Always use the default kernel command string"
+	help
+	  Always use the default kernel command string, even if the boot
+	  loader passes other arguments to the kernel.
+	  This is useful if you cannot or don't want to change the
+	  command-line options your boot loader passes to the kernel.
+
+endmenu
+
+menu "Userspace binary formats"
+
+source "fs/Kconfig.binfmt"
+
+config COMPAT
+	bool "Kernel support for 32-bit EL0"
+	depends on !ARM64_64K_PAGES
+	select COMPAT_BINFMT_ELF
+	help
+	  This option enables support for a 32-bit EL0 running under a 64-bit
+	  kernel at EL1. AArch32-specific components such as system calls,
+	  the user helper functions, VFP support and the ptrace interface are
+	  handled appropriately by the kernel.
+
+	  If you want to execute 32-bit userspace applications, say Y.
+
+config SYSVIPC_COMPAT
+	def_bool y
+	depends on COMPAT && SYSVIPC
+
+endmenu
+
+source "net/Kconfig"
+
+source "drivers/Kconfig"
+
+source "fs/Kconfig"
+
+source "arch/arm64/Kconfig.debug"
+
+source "security/Kconfig"
+
+source "crypto/Kconfig"
+
+source "lib/Kconfig"
arch/arm64/Kconfig.debug new file +27 -0
new file mode 100644
index 0000000..d7553f2
@@ -0,0 +1,27 @@
+menu "Kernel hacking"
+
+source "lib/Kconfig.debug"
+
+config FRAME_POINTER
+	bool
+	default y
+
+config DEBUG_ERRORS
+	bool "Verbose kernel error messages"
+	depends on DEBUG_KERNEL
+	help
+	  This option controls verbose debugging information which can be
+	  printed when the kernel detects an internal error. This debugging
+	  information is useful to kernel hackers when tracking down problems,
+	  but mostly meaningless to other people. It's safe to say Y unless
+	  you are concerned with the code size or don't want to see these
+	  messages.
+
+config DEBUG_STACK_USAGE
+	bool "Enable stack utilization instrumentation"
+	depends on DEBUG_KERNEL
+	help
+	  Enables the display of the minimum amount of free stack which each
+	  task has ever had available in the sysrq-T output.
+
+endmenu
arch/arm64/Makefile new file +71 -0

71 lines not on this page · raw message

arch/arm64/boot/.gitignore new file +2 -0
new file mode 100644
index 0000000..8dab0bb
@@ -0,0 +1,2 @@
+Image
+Image.gz
arch/arm64/boot/Makefile new file +36 -0
new file mode 100644
index 0000000..eca209b
@@ -0,0 +1,36 @@
+#
+# arch/arm64/boot/Makefile
+#
+# This file is included by the global makefile so that you can add your own
+# architecture-specific flags and dependencies.
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 2012, ARM Ltd.
+# Author: Will Deacon <[email protected]>
+#
+# Based on the ia64 boot/Makefile.
+#
+
+targets := Image Image.gz
+
+$(obj)/Image: vmlinux FORCE
+	$(call if_changed,objcopy)
+
+$(obj)/Image.gz: $(obj)/Image FORCE
+	$(call if_changed,gzip)
+
+$(obj)/%.dtb: $(src)/dts/%.dts
+	$(call cmd,dtc)
+
+install: $(obj)/Image
+	$(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \
+	$(obj)/Image System.map "$(INSTALL_PATH)"
+
+zinstall: $(obj)/Image.gz
+	$(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \
+	$(obj)/Image.gz System.map "$(INSTALL_PATH)"
+
+clean-files += *.dtb
arch/arm64/boot/install.sh new file +46 -0

46 lines not on this page · raw message

arch/arm64/configs/defconfig new file +85 -0

85 lines not on this page · raw message

arch/arm64/include/asm/prom.h new file +1 -0
new file mode 100644
index 0000000..68b90e6
@@ -0,0 +1 @@
+/* Empty for now */
arch/arm64/kernel/.gitignore new file +1 -0
new file mode 100644
index 0000000..c5f676c
@@ -0,0 +1 @@
+vmlinux.lds
arch/arm64/kernel/Makefile new file +27 -0
new file mode 100644
index 0000000..e2caff1
@@ -0,0 +1,27 @@
+#
+# Makefile for the linux kernel.
+#
+
+CPPFLAGS_vmlinux.lds	:= -DTEXT_OFFSET=$(TEXT_OFFSET)
+AFLAGS_head.o		:= -DTEXT_OFFSET=$(TEXT_OFFSET)
+
+# Object file lists.
+arm64-obj-y		:= cputable.o debug-monitors.o entry.o irq.o fpsimd.o	\
+			   entry-fpsimd.o process.o ptrace.o setup.o signal.o	\
+			   sys.o stacktrace.o time.o traps.o io.o vdso.o
+
+arm64-obj-$(CONFIG_COMPAT)		+= sys32.o kuser32.o signal32.o 	\
+					   sys_compat.o
+arm64-obj-$(CONFIG_MODULES)		+= arm64ksyms.o module.o
+arm64-obj-$(CONFIG_SMP)			+= smp.o
+arm64-obj-$(CONFIG_HW_PERF_EVENTS)	+= perf_event.o
+arm64-obj-$(CONFIG_HAVE_HW_BREAKPOINT)+= hw_breakpoint.o
+
+obj-y					+= $(arm64-obj-y) vdso/
+obj-m					+= $(arm64-obj-m)
+head-y					:= head.o
+extra-y					:= $(head-y) vmlinux.lds
+
+# vDSO - this must be built first to generate the symbol offsets
+$(call objectify,$(arm64-obj-y)): $(obj)/vdso/vdso-offsets.h
+$(obj)/vdso/vdso-offsets.h: $(obj)/vdso
arch/arm64/kernel/vmlinux.lds.S new file +126 -0

126 lines not on this page · raw message

arch/arm64/mm/Makefile new file +4 -0
new file mode 100644
index 0000000..3140a2a
@@ -0,0 +1,4 @@
+obj-y				:= dma-mapping.o extable.o fault.o init.o \
+				   cache.o copypage.o flush.o \
+				   ioremap.o mmap.o pgd.o mmu.o \
+				   context.o tlb.o proc.o
init/Kconfig +2 -1
index af6c7f8..8bfda46 100644
@@ -1153,7 +1153,8 @@ menuconfig EXPERT
 
 config UID16
 	bool "Enable 16-bit UID system calls" if EXPERT
-	depends on ARM || BLACKFIN || CRIS || FRV || H8300 || X86_32 || M68K || (S390 && !64BIT) || SUPERH || SPARC32 || (SPARC64 && COMPAT) || UML || (X86_64 && IA32_EMULATION)
+	depends on ARM || BLACKFIN || CRIS || FRV || H8300 || X86_32 || M68K || (S390 && !64BIT) || SUPERH || SPARC32 || (SPARC64 && COMPAT) || UML || (X86_64 && IA32_EMULATION) \
+		|| AARCH32_EMULATION
 	default y
 	help
 	  This enables the legacy 16-bit UID syscall wrappers.
lib/Kconfig.debug +4 -2
index 2403a63..cfb4578 100644
@@ -452,7 +452,8 @@ config SLUB_STATS
 config DEBUG_KMEMLEAK
 	bool "Kernel memory leak detector"
 	depends on DEBUG_KERNEL && EXPERIMENTAL && \
-		(X86 || ARM || PPC || MIPS || S390 || SPARC64 || SUPERH || MICROBLAZE || TILE)
+		(X86 || ARM || PPC || MIPS || S390 || SPARC64 || SUPERH || \
+		 MICROBLAZE || TILE || ARM64)
 
 	select DEBUG_FS
 	select STACKTRACE if STACKTRACE_SUPPORT
@@ -739,7 +740,8 @@ config DEBUG_BUGVERBOSE
 	bool "Verbose BUG() reporting (adds 70K)" if DEBUG_KERNEL && EXPERT
 	depends on BUG
 	depends on ARM || AVR32 || M32R || M68K || SPARC32 || SPARC64 || \
-		   FRV || SUPERH || GENERIC_BUG || BLACKFIN || MN10300 || TILE
+		   FRV || SUPERH || GENERIC_BUG || BLACKFIN || MN10300 || \
+		   TILE || ARM64
 	default y
 	help
 	  Say Y here to make BUG() panics output the file name and line number
author maintainer
#102 lore raw

PATCH v3 31/31 arm64: MAINTAINERS update

In reply to Catalin Marinas

This patch updates the MAINTAINERS file for the AArch64 Linux kernel port.

---
 MAINTAINERS |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)
MAINTAINERS +6 -0
index fdc0119..de368a5 100644
@@ -1209,6 +1209,12 @@ S:	Maintained
 F:	arch/arm/mach-pxa/z2.c
 F:	arch/arm/mach-pxa/include/mach/z2.h
 
+ARM64 PORT (AARCH64 ARCHITECTURE)
+M:	Catalin Marinas <[email protected]>
+L:	[email protected] (moderated for non-subscribers)
+S:	Maintained
+F:	arch/arm64/
+
 ASC7621 HARDWARE MONITOR DRIVER
 M:	George Joseph <[email protected]>
 L:	[email protected]
#103 lore raw

Re: [PATCH v3 31/31] arm64: MAINTAINERS update

Quoted 15 lines · Catalin Marinas

This patch updates the MAINTAINERS file for the AArch64 Linux kernel port.

---
 MAINTAINERS |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)
MAINTAINERS +0 -0
index fdc0119..de368a5 100644

MAINTAINERS S: Maintained · line 1213

Quoted 5 lines
MAINTAINERS +2 -0
@@ -1209,6 +1209,12 @@ S:	Maintained
 F:	arch/arm/mach-pxa/z2.c
 F:	arch/arm/mach-pxa/include/mach/z2.h
 
+ARM64 PORT (AARCH64 ARCHITECTURE)
+M:	Catalin Marinas <[email protected]>

we should put Russell too

Best Regards,
J.

#104 lore raw

Re: [PATCH v3 31/31] arm64: MAINTAINERS update

Quoted 19 lines · Jean-Christophe PLAGNIOL-VILLARD
Quoted 18 lines · Catalin Marinas

This patch updates the MAINTAINERS file for the AArch64 Linux kernel port.

---
 MAINTAINERS |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)
MAINTAINERS +0 -0
index fdc0119..de368a5 100644
@@ -1209,6 +1209,12 @@ S:	Maintained
 F:	arch/arm/mach-pxa/z2.c
 F:	arch/arm/mach-pxa/include/mach/z2.h
 
Quoted 3 lines

MAINTAINERS S: Maintained · line 1213

Quoted 2 lines
MAINTAINERS +2 -0
+ARM64 PORT (AARCH64 ARCHITECTURE)
+M:	Catalin Marinas <[email protected]>

we should put Russell too

He is not maintaining the ARM64 code.

Nicolas

#105 lore raw

Re: [PATCH v3 31/31] arm64: MAINTAINERS update

Quoted 21 lines · Nicolas Pitre
Quoted 19 lines · Jean-Christophe PLAGNIOL-VILLARD
Quoted 18 lines · Catalin Marinas

This patch updates the MAINTAINERS file for the AArch64 Linux kernel port.

---
 MAINTAINERS |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)
MAINTAINERS +0 -0
index fdc0119..de368a5 100644
@@ -1209,6 +1209,12 @@ S:	Maintained
 F:	arch/arm/mach-pxa/z2.c
 F:	arch/arm/mach-pxa/include/mach/z2.h
 
Quoted 5 lines
Quoted 3 lines

MAINTAINERS S: Maintained · line 1213

Quoted 2 lines
MAINTAINERS +2 -0
+ARM64 PORT (AARCH64 ARCHITECTURE)
+M:	Catalin Marinas <[email protected]>

we should put Russell too

He is not maintaining the ARM64 code.

And, let's say the rest of it - it doesn't take much inteligence to work out what that means for me personally.

#106 lore raw

Re: [PATCH v3 31/31] arm64: MAINTAINERS update

Quoted 22 lines · Russell King - ARM Linux
Quoted 21 lines · Nicolas Pitre
Quoted 19 lines · Jean-Christophe PLAGNIOL-VILLARD
Quoted 18 lines · Catalin Marinas

This patch updates the MAINTAINERS file for the AArch64 Linux kernel port.

---
 MAINTAINERS |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)
MAINTAINERS +0 -0
index fdc0119..de368a5 100644
@@ -1209,6 +1209,12 @@ S:	Maintained
 F:	arch/arm/mach-pxa/z2.c
 F:	arch/arm/mach-pxa/include/mach/z2.h
 
Quoted 8 lines
Quoted 5 lines
Quoted 3 lines

MAINTAINERS S: Maintained · line 1213

Quoted 2 lines
MAINTAINERS +2 -0
+ARM64 PORT (AARCH64 ARCHITECTURE)
+M:	Catalin Marinas <[email protected]>

we should put Russell too

He is not maintaining the ARM64 code.

And, let's say the rest of it - it doesn't take much inteligence to work out what that means for me personally.

For the record, let me state out loud what I think.

I truly think that the core ARM code is a nice piece of art, and this is because of your technical excellence and good taste with code. The ARM ecosystem is wide and varied, and keeping it from morphing into a horrid mess is a thankless challenge. We as a community certainly don't say this very often if at all, but we certainly owe you a big "thank you" for the excellent work you did so far, and I hope you'll go on with it for quite some time yet. In any case, no one with excellent coding skills such as yours is ever going to lack work and opportunities in this community.

Even x86, despite its long history in the Linux kernel, is less fragmented and diversified than the ARM architecture. For better or worse, the ARM Ltd business model is different from Intel's. That might be good for the ARM market share and vendor differentiation, but this is far from the ideal scenario for kernel developers. I said it in the past and I'll say it again: X86 is peanuts in comparison.

Yet, X86 has 3 listed maintainers according to the MAINTAINERS file. ARM has only one. AS far as I can see, no one is crazy enough to be maintainer for two or more architectures.

Unless you were to give up on the ARM 32 bit maintenance, I don't see how you could be able to maintain both ARM and ARM64 at the same time without losing your sanity or sacrificing on the quality of the code you contribute. . Fortunately, Catalin is willing to maintain the ARM64 port and he appears pretty motivated as well. Unless he does screw up, we should let him bear this weight.

Nicolas

Acked-by on the v3 series
#107 lore raw
In reply to Catalin Marinas
Quoted 10 lines · Catalin Marinas

This is the 3rd version of patches implementing Linux kernel support for the 64-bit ARM architecture. Most of the review comments for the previous release have been implemented. There are a few left (like generic timer dts specification) but the main goal was to freeze the user ABI.

The Linux kernel patches are available on this tree:

git://git.kernel.org/pub/scm/linux/kernel/git/cmarinas/linux-aarch64.git upstream

Quoted 15 lines

Main changes since the previous version:
- ptrace interface now using regsets for TLS and hardware debug registers.
- sys_personality fixes. PER_LINUX is the default for all tasks (32 or 64-bit) and there is no compat_sys_personality defined.
- Kconfig clean-up (unused symbols, AARCH32_EMULATION removed in favour of COMPAT).
- Clean-up of the __cpuc_* function prefixes.
- CPU information table implemented in C rather than assembly.
- __bad_* function calls replaced with BUILD_BUG.
- Inline get_user/put_user (code cleaner, slightly bigger kernel Image).
- DMA API implementation simplified, defaulting to swiotlb. It will be extended as hardware becomes available.
- Arch-specific code in the generic timer patch moved to arch/arm64/.
- Comment fixes and clarifications.

I see that a good amount of the comments I had on v2 have neither been replied to nor addressed.

Please address them where appropriate, ideally before merging. I'll be happy to be told I'm wrong in some of the cases too, but completely ignoring feedback isn't cool.

However, most of them were nits, and I've had a look-through of the rest of the patches, feel free to add:

on the patches in this series.

-Olof

author maintainer
#108 lore raw
Quoted 27 lines · Olof Johansson
Quoted 10 lines · Catalin Marinas

This is the 3rd version of patches implementing Linux kernel support for the 64-bit ARM architecture. Most of the review comments for the previous release have been implemented. There are a few left (like generic timer dts specification) but the main goal was to freeze the user ABI.

The Linux kernel patches are available on this tree:

git://git.kernel.org/pub/scm/linux/kernel/git/cmarinas/linux-aarch64.git upstream

Quoted 15 lines

Main changes since the previous version:
- ptrace interface now using regsets for TLS and hardware debug registers.
- sys_personality fixes. PER_LINUX is the default for all tasks (32 or 64-bit) and there is no compat_sys_personality defined.
- Kconfig clean-up (unused symbols, AARCH32_EMULATION removed in favour of COMPAT).
- Clean-up of the __cpuc_* function prefixes.
- CPU information table implemented in C rather than assembly.
- __bad_* function calls replaced with BUILD_BUG.
- Inline get_user/put_user (code cleaner, slightly bigger kernel Image).
- DMA API implementation simplified, defaulting to swiotlb. It will be extended as hardware becomes available.
- Arch-specific code in the generic timer patch moved to arch/arm64/.
- Comment fixes and clarifications.

Quoted 2 lines

I see that a good amount of the comments I had on v2 have neither been replied to nor addressed.

Sorry, as I said above, my main focus was get the user ABI sorted out as a code is public and there are people that started using it. There are still a few emails marked as "unread" in my inbox that need to be addressed but I did not consider them critical for version 3 of the series. They are not forgotten, however, I'm working back through those emails and either reply or implement the suggestions.

Quoted 1 line

Thanks.

Signature · 1 line
Catalin
Acked-by on the v3 series
#109 lore raw
In reply to Catalin Marinas

Catalin,

Quoted 8 lines · Catalin Marinas

This is the 3rd version of patches implementing Linux kernel support for the 64-bit ARM architecture. Most of the review comments for the previous release have been implemented. There are a few left (like generic timer dts specification) but the main goal was to freeze the user ABI.

The Linux kernel patches are available on this tree:

Firstly thanks for clarifying the questions asked on the previous version and also for the update on the arch timer code.

Mostly I was looking at the series from SOC boot and CPU PM point of view and boot part seems to just fine.

As per discussion at LPC, I have gone through the SMC proposal which ARM has published. In general the boot part with SMC seems to be doable and can be standardized across SOCs. The part which will be conflicting is the CPU power management. That seems to be the harder one and the document is at too infancy stage from the details point of view. Some bits about save, restore are related to switcher kind of architecture, which may not be the requirement for all the SoCs.

Ofcourse the SMC discussion is not related to $subject series as such. Also the PM support for ARMv8 not seems be the scope of the series so the discussion can be parked aside till we need to talk about it. I have few more questions on the various MM attribute usage, exceptions and PL's but I will do some reading before asking those to you.

For the series itself, feel free to add my ack if yo need one.

#110 lore raw
Quoted 11 lines · Santosh Shilimkar

Mostly I was looking at the series from SOC boot and CPU PM point of view and boot part seems to just fine.

As per discussion at LPC, I have gone through the SMC proposal which ARM has published. In general the boot part with SMC seems to be doable and can be standardized across SOCs. The part which will be conflicting is the CPU power management. That seems to be the harder one and the document is at too infancy stage from the details point of view. Some bits about save, restore are related to switcher kind of architecture, which may not be the requirement for all the SoCs.

I've reviewed an earlier draft of that document. Although the examples in the latest document appear to be geared towards switcher usage, my suggestions to the ARM folks was to take into account the CPU hotplug scenario instead. The provided examples remained switcher centric, but the API in the published document is now much more generic than it used to be. I think it should cover all usage scenarios now.

Quoted 4 lines

Ofcourse the SMC discussion is not related to $subject series as such. Also the PM support for ARMv8 not seems be the scope of the series so the discussion can be parked aside till we need to talk about it.

If you wish to discuss this further (maybe in a separate thread) I'll be glad to discuss this with you.

Nicolas

#111 lore raw
Quoted 14 lines · Nicolas Pitre
Quoted 11 lines · Santosh Shilimkar

Mostly I was looking at the series from SOC boot and CPU PM point of view and boot part seems to just fine.

As per discussion at LPC, I have gone through the SMC proposal which ARM has published. In general the boot part with SMC seems to be doable and can be standardized across SOCs. The part which will be conflicting is the CPU power management. That seems to be the harder one and the document is at too infancy stage from the details point of view. Some bits about save, restore are related to switcher kind of architecture, which may not be the requirement for all the SoCs.

Quoted 7 lines

I've reviewed an earlier draft of that document. Although the examples in the latest document appear to be geared towards switcher usage, my suggestions to the ARM folks was to take into account the CPU hotplug scenario instead. The provided examples remained switcher centric, but the API in the published document is now much more generic than it used to be. I think it should cover all usage scenarios now.

Thanks for the background Nicolas.

Regards,
Santosh

Acked-by on the v3 series
#112 lore raw
In reply to Catalin Marinas
Quoted 10 lines · Catalin Marinas

This is the 3rd version of patches implementing Linux kernel support for the 64-bit ARM architecture. Most of the review comments for the previous release have been implemented. There are a few left (like generic timer dts specification) but the main goal was to freeze the user ABI.

The Linux kernel patches are available on this tree:

git://git.kernel.org/pub/scm/linux/kernel/git/cmarinas/linux-aarch64.git upstream

Quoted 15 lines

Main changes since the previous version:
- ptrace interface now using regsets for TLS and hardware debug registers.
- sys_personality fixes. PER_LINUX is the default for all tasks (32 or 64-bit) and there is no compat_sys_personality defined.
- Kconfig clean-up (unused symbols, AARCH32_EMULATION removed in favour of COMPAT).
- Clean-up of the __cpuc_* function prefixes.
- CPU information table implemented in C rather than assembly.
- __bad_* function calls replaced with BUILD_BUG.
- Inline get_user/put_user (code cleaner, slightly bigger kernel Image).
- DMA API implementation simplified, defaulting to swiotlb. It will be extended as hardware becomes available.
- Arch-specific code in the generic timer patch moved to arch/arm64/.
- Comment fixes and clarifications.

For those patches in this series I didn't comment on already:

Small nit: please s/[email protected]/[email protected]/.

Nicolas

#113 lore raw
In reply to Catalin Marinas
Quoted 2 lines · Catalin Marinas

This is the 3rd version of patches implementing Linux kernel support for the 64-bit ARM architecture.

<snip>

Quoted 1 line

...but the main goal was to freeze the user ABI.

Is the consensus now that we're good from an ABI viewpoint?

Jon.

maintainer
#114 lore raw
Quoted 11 lines · Jon Masters
Quoted 2 lines · Catalin Marinas

This is the 3rd version of patches implementing Linux kernel support for the 64-bit ARM architecture.

<snip>

Quoted 1 line

...but the main goal was to freeze the user ABI.

Is the consensus now that we're good from an ABI viewpoint?

From my point of view, no more changes are needed. I would not give any

guarantees until we have a first kernel release including this code, but I think we can agree that we would consult you about ABI changes if they seem necessary before then.

If you start (re)building the Fedora packages based on these kernel headers, the changes are pretty good that this will keep working.

Arnd