AArch64 Linux kernel port
Subsystems (16)
Catalin Marinas
maintainerv3 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 +
Catalin Marinas
maintainerPATCH 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
@@ -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
Catalin Marinas
maintainerPATCH v3 2/31 arm64: Kernel booting and initialisation
In reply to Catalin MarinasThe 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
@@ -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
@@ -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
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.txtdescribes the booting protocol on the AArch64 Linux kernel. This is subject to change following the work on boot standardisation, ACPI.Signed-off-by Will Deacon <[email protected]>Signed-off-by Catalin Marinas <[email protected]>Acked-by Nicolas Pitre <[email protected]>Acked-by Tony Lindgren <[email protected]>
Re: [PATCH v3 02/31] arm64: Kernel booting and initialisation
In reply to Catalin MarinasQuoted 67 lines · Catalin Marinas
The patch adds the kernel booting and the initial setup code.
Documentation/arm64/booting.txtdescribes the booting protocol on the AArch64 Linux kernel. This is subject to change following the work on boot standardisation, ACPI.Signed-off-by Will Deacon <[email protected]>Signed-off-by Catalin Marinas <[email protected]>Acked-by Nicolas Pitre <[email protected]>Acked-by Tony Lindgren <[email protected]>--- 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.cDocumentation/arm64/booting.txt new file +41
-0@@ -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.
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
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
0x14000008at 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.
Catalin Marinas
maintainerRe: [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
Arnd Bergmann
maintainerRe: [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-timePHYS_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
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-timePHYS_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
Arnd Bergmann
maintainerRe: [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
Catalin Marinas
maintainerRe: [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
Re: [PATCH v3 02/31] arm64: Kernel booting and initialisation
In reply to Arnd BergmannQuoted 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
Re: [PATCH v3 02/31] arm64: Kernel booting and initialisation
In reply to Catalin MarinasQuoted 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-timePHYS_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.
Catalin Marinas
maintainerRe: [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-timePHYS_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
Re: [PATCH v3 02/31] arm64: Kernel booting and initialisation
In reply to Jean-Christophe PLAGNIOL-VILLARDQuoted 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-timePHYS_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
Re: [PATCH v3 02/31] arm64: Kernel booting and initialisation
In reply to Jean-Christophe PLAGNIOL-VILLARDQuoted 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
0x14000008at 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.
Catalin Marinas
maintainerRe: [PATCH v3 02/31] arm64: Kernel booting and initialisation
In reply to Jean-Christophe PLAGNIOL-VILLARDQuoted 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
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.Sto 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 areaQuoted 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.
Catalin Marinas
maintainerRe: [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.Sor 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 treeDocumentation/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
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
Catalin Marinas
maintainerRe: [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.gitThe 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
Catalin Marinas
maintainerPATCH v3 3/31 arm64: Exception handling
In reply to Catalin MarinasThe 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
@@ -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
@@ -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
@@ -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
Re: [PATCH v3 03/31] arm64: Exception handling
Quoted 11 lines · Catalin Marinas
The patch contains the exception entry code (
kernel/entry.S),pt_regsstructure 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.
Signed-off-by Will Deacon <[email protected]>Signed-off-by Catalin Marinas <[email protected]>Acked-by Tony Lindgren <[email protected]>
Catalin Marinas
maintainerPATCH v3 4/31 arm64: MMU definitions
In reply to Catalin MarinasThe 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
@@ -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
@@ -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
@@ -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
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. TheSECTION_SIZEis 2MB with 4KB page and 512MB with 64KB page configuration.
PHYS_OFFSETis 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_VMEMMAPenabled by default.Signed-off-by Will Deacon <[email protected]>Signed-off-by Catalin Marinas <[email protected]>Acked-by Tony Lindgren <[email protected]>
Catalin Marinas
maintainerPATCH v3 5/31 arm64: MMU initialisation
In reply to Catalin MarinasThis 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
@@ -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
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_VMEMMAPinitialisation.Signed-off-by Will Deacon <[email protected]>Signed-off-by Catalin Marinas <[email protected]>Acked-by Tony Lindgren <[email protected]>
Catalin Marinas
maintainerPATCH v3 6/31 arm64: MMU fault handling and page table management
In reply to Catalin MarinasThis 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
@@ -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
@@ -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
@@ -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
@@ -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
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.Signed-off-by Will Deacon <[email protected]>Signed-off-by Catalin Marinas <[email protected]>Acked-by Tony Lindgren <[email protected]>
Catalin Marinas
maintainerPATCH v3 7/31 arm64: Process management
In reply to Catalin MarinasThe 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
@@ -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
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.Sfile). AArch64 supports ASID-tagged TLBs and the ASID can be either 8 or 16-bit wide (detectable via theID_AA64AFR0_EL1register).Signed-off-by Will Deacon <[email protected]>Signed-off-by Catalin Marinas <[email protected]>Acked-by Tony Lindgren <[email protected]>
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+ +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
Catalin Marinas
maintainerPATCH v3 8/31 arm64: CPU support
In reply to Catalin MarinasThis 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
@@ -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
@@ -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
Arnd Bergmann
maintainerRe: [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
Catalin Marinas
maintainerRe: [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
Catalin Marinas
maintainerPATCH v3 9/31 arm64: Cache maintenance routines
In reply to Catalin MarinasThe 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
@@ -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
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:
Catalin Marinas
maintainerRe: [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
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
Catalin Marinas
maintainerRe: [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
Re: [PATCH v3 09/31] arm64: Cache maintenance routines
In reply to Catalin MarinasHi 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.
Signed-off-by Will Deacon <[email protected]>Signed-off-by Catalin Marinas <[email protected]>Acked-by Tony Lindgren <[email protected]>--- 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.carch/arm64/include/asm/cache.h new file +32
-0@@ -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@@ -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@@ -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@@ -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@@ -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
Catalin Marinas
maintainerRe: [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)inflush_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
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) inflush_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
...
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 +
Catalin Marinas
maintainerRe: [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) inflush_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 offlush_dcache_page()(which is not supposed to handle anon pages) intoflush_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 fromget_user_pages()directly, i.e. also anonymous pages. Many drivers (especially emulated storage drivers like dm-crypt) useflush_dcache_page()after modifying a page. Althoughflush_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
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 fromget_user_pages()directly, i.e. also anonymous pages. Many drivers (especially emulated storage drivers like dm-crypt) useflush_dcache_page()after modifying a page. Althoughflush_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 toflush_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 theclear_bitpart 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
Catalin Marinas
maintainerPATCH v3 10/31 arm64: TLB maintenance functionality
In reply to Catalin MarinasThis 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
@@ -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
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_gatherpatches are merged.Signed-off-by Will Deacon <[email protected]>Signed-off-by Catalin Marinas <[email protected]>Acked-by Tony Lindgren <[email protected]>
Catalin Marinas
maintainerPATCH v3 11/31 arm64: IRQ handling
In reply to Catalin MarinasFrom: 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
@@ -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
@@ -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
Arnd Bergmann
maintainerRe: [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
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
Catalin Marinas
maintainerRe: [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@@ -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
Catalin Marinas
maintainerPATCH v3 12/31 arm64: Atomic operations
In reply to Catalin MarinasThis 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
@@ -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; + + asmvolatile ("// 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; + + asmvolatile ("// 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; + + asmvolatile ("// 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; + + asmvolatile ("// 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; + + asmvolatile ("// 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; + + asmvolatile ("// 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; + + asmvolatile ("// 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; + + asmvolatile ("// 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; + + asmvolatile ("// 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; + + asmvolatile ("// 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; + + asmvolatile ("// 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; + + asmvolatile ("// 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
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.
Signed-off-by Will Deacon <[email protected]>Signed-off-by Catalin Marinas <[email protected]>Acked-by Tony Lindgren <[email protected]>
Catalin Marinas
maintainerPATCH v3 13/31 arm64: Device specific operations
In reply to Catalin MarinasThis 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
@@ -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
@@ -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
Catalin Marinas
maintainerPATCH v3 14/31 arm64: DMA mapping API
In reply to Catalin MarinasThis 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
@@ -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
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_opsfor 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.Signed-off-by Catalin Marinas <[email protected]>Acked-by Tony Lindgren <[email protected]>
Catalin Marinas
maintainerPATCH v3 15/31 arm64: SMP support
In reply to Catalin MarinasThis 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
@@ -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
@@ -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
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.Signed-off-by Will Deacon <[email protected]>Signed-off-by Marc Zyngier <[email protected]>Signed-off-by Catalin Marinas <[email protected]>Acked-by Arnd Bergmann <[email protected]>Acked-by Tony Lindgren <[email protected]>
PATCH v3 15/31 arm64: SMP support
In reply to Catalin MarinasCatalin,
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.
Catalin Marinas
maintainerPATCH 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 becauseemergency_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 makesemergency_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
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 becauseemergency_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 makesemergency_restart()almost useless.
Quoted 3 lines
This code was inherited from
arch/armwhich initially was always dumping the stack but it later gained thesystem_statecheck. 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
PATCH v3 15/31 arm64: SMP support
Quoted 7 lines · Hanjun Guo
Quoted 4 lines
This code was inherited from
arch/armwhich initially was always dumping the stack but it later gained thesystem_statecheck. 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.
PATCH v3 15/31 arm64: SMP support
Quoted 9 lines · Timur Tabi
Quoted 7 lines
Quoted 4 lines
This code was inherited from
arch/armwhich initially was always dumping the stack but it later gained thesystem_statecheck. 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.
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/armwhich initially was always dumping
the stack but it later gained thesystem_statecheck. 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'tmachine_restart()change thesystem_statetoSYSTEM_RESTARTbefore it callssmp_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
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'tmachine_restart()change thesystem_statetoSYSTEM_RESTARTbefore it callssmp_send_stop()?The
system_stateis set toSYSTEM_RESTARTinkernel_restart_prepare(), andkernel_restart()will callkernel_restart_prepare()andmachine_restart(), so if we change thesystem_statetoSYSTEM_RESTARTinmachine_restart(), it seems duplicate.
I don't see where emergency_restart() ever callskernel_restart_prepare(). Here's the call chain:
emergency_restartmachine_emergency_restartmachine_restartefi_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.
Catalin Marinas
maintainerPATCH v3 16/31 arm64: ELF definitions
In reply to Catalin MarinasThis 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
@@ -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
@@ -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
@@ -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 */
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_FPandHWCAP_ASIMD.Signed-off-by Will Deacon <[email protected]>Signed-off-by Catalin Marinas <[email protected]>Acked-by Tony Lindgren <[email protected]>
Catalin Marinas
maintainerPATCH v3 17/31 arm64: System calls handling
In reply to Catalin MarinasThis 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
@@ -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
@@ -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
@@ -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
@@ -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
Arnd Bergmann
maintainerRe: [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 (®s,0 ,sizeof (struct pt_regs )); + ret =do_execve (filename, + (const char __user *const __user *)argv, + (const char __user *const __user *)envp, ®s); +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" (®s), + "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
Al Viro
maintainerRe: [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" (®s), +" 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)...
Catalin Marinas
maintainerRe: [PATCH v3 17/31] arm64: System calls handling
In reply to Arnd BergmannQuoted 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
@@ -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
Arnd Bergmann
maintainerRe: [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
Catalin Marinas
maintainerRe: [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
Arnd Bergmann
maintainerRe: [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/armone. 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
Catalin Marinas
maintainerRe: [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/armone. 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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) {
Catalin Marinas
maintainerPATCH v3 18/31 arm64: VDSO support
In reply to Catalin MarinasFrom: 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
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 optimisedgettimeofday()(using the user-accessible generic counter).Signed-off-by Will Deacon <[email protected]>Signed-off-by Catalin Marinas <[email protected]>Acked-by Tony Lindgren <[email protected]>
Catalin Marinas
maintainerPATCH v3 19/31 arm64: Signal handling support
In reply to Catalin MarinasThis 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
@@ -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
@@ -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
@@ -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
@@ -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
Catalin Marinas
maintainerPATCH v3 20/31 arm64: User access library functions
In reply to Catalin MarinasThis 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
@@ -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
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)).Signed-off-by Will Deacon <[email protected]>Signed-off-by Marc Zyngier <[email protected]>Signed-off-by Catalin Marinas <[email protected]>Acked-by Tony Lindgren <[email protected]>
Catalin Marinas
maintainerPATCH v3 21/31 arm64: 32-bit (compat) applications support
In reply to Catalin MarinasFrom: 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
@@ -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
Arnd Bergmann
maintainerRe: [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.
Signed-off-by Will Deacon <[email protected]>Signed-off-by Catalin Marinas <[email protected]>Acked-by Tony Lindgren <[email protected]>
I guess you haven't had time to turn any of these into architecture independent functions as discussed last time?
Arnd
Catalin Marinas
maintainerRe: [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
Signed-off-by Will Deacon <[email protected]>Signed-off-by Catalin Marinas <[email protected]>Acked-by Tony Lindgren <[email protected]>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
87fb5301a44ac05b4e6d7245db02acc2dedde831Mon 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
@@ -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
fa734f9523e35d7a6e9ab5e252ab344133111c1fMon 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
@@ -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
@@ -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
79ed6c77bdd4480b81defe1cd81198235e9d4d03Mon 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
@@ -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
@@ -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
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@@ -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.
Catalin Marinas
maintainerRe: [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.cand get rid of the get_fs/set_fs hack, like
Quoted 2 lines
asmlinkage int compat_sys_sendfile(int
out_fd, intin_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 whereloff_tis defined differently fromcompat_loff_t, so you can probably just use the nativesys_sendfile64for 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
7c6747fc9f69d20f445e4af69c644acb04a74f45Mon 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
@@ -1007,3 +1007,25 @@ SYSCALL_DEFINE4(sendfile64, int, out_fd, int, in_fd, loff_t __user *, offset, sireturn 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
@@ -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)
Catalin Marinas
maintainerPATCH v3 22/31 arm64: Floating point and SIMD
In reply to Catalin MarinasThis 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
@@ -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
Catalin Marinas
maintainerPATCH v3 23/31 arm64: Debugging support
In reply to Catalin MarinasFrom: 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
@@ -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
@@ -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 */
Re: [PATCH v3 23/31] arm64: Debugging support
Quoted 7 lines · Catalin Marinas
From: Will Deacon <[email protected]>
This patch adds ptrace, debug monitors and hardware breakpoints support.
Signed-off-by Will Deacon <[email protected]>Signed-off-by Catalin Marinas <[email protected]>Acked-by Tony Lindgren <[email protected]>
Looks good to me now,
Catalin Marinas
maintainerPATCH v3 24/31 arm64: Add support for /proc/sys/debug/exception-trace
In reply to Catalin MarinasThis 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
@@ -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,
Catalin Marinas
maintainerPATCH v3 25/31 arm64: Performance counters support
In reply to Catalin MarinasFrom: 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
@@ -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
@@ -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( \
Catalin Marinas
maintainerPATCH v3 26/31 arm64: Miscellaneous library functions
In reply to Catalin MarinasFrom: 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
@@ -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
@@ -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
@@ -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
@@ -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
Arnd Bergmann
maintainerRe: [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
Catalin Marinas
maintainerRe: [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
64ec78a2fce931e0148db90747c69688f248a531Mon 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
@@ -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
@@ -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
@@ -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
@@ -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
542f0b34b5674d8472b820f1ce751118ecdf9470Mon 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
@@ -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>
Re: [PATCH v3 26/31] arm64: Miscellaneous library functions
Quoted 11 lines · Catalin Marinas
From
64ec78a2fce931e0148db90747c69688f248a531Mon 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_* functionsThis patch implements ffs,
__ffs, fls,__flsusing __builtin_* gcc functions. These header files can be used by other architectures that rely on the gcc builtins.Signed-off-by Catalin Marinas <[email protected]>Cc Arnd Bergmann <[email protected]>
Very good.
Catalin Marinas
maintainerPATCH v3 27/31 arm64: Loadable modules
In reply to Catalin MarinasFrom: 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
@@ -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
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).Signed-off-by Will Deacon <[email protected]>Signed-off-by Catalin Marinas <[email protected]>Acked-by Tony Lindgren <[email protected]>
Catalin Marinas
maintainerPATCH v3 28/31 arm64: Generic timers support
In reply to Catalin MarinasFrom: 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
@@ -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 : + asmvolatile ("msr cntp_ctl_el0, %0" : :"r" (val)); +break ; +case ARCH_TIMER_REG_TVAL : + asmvolatile ("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 : + asmvolatile ("mrs %0, cntp_ctl_el0" :"=r" (val)); +break ; +case ARCH_TIMER_REG_FREQ : + asmvolatile ("mrs %0, cntfrq_el0" :"=r" (val)); +break ; +case ARCH_TIMER_REG_TVAL : + asmvolatile ("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. */ + asmvolatile ("mrs %0, cntkctl_el1" :"=r" (cntkctl)); + cntkctl &= ~((3 <<8 ) | (1 <<1 )); + +/* Enable user access to the physical counter and frequency. */ + cntkctl |=1 ; + asmvolatile ("msr cntkctl_el1, %0" : :"r" (cntkctl)); +} + +static inline cycle_t arch_counter_get_cntpct (void ) +{ +cycle_t cval; + + asmvolatile ("mrs %0, cntpct_el0" :"=r" (cval)); + +return cval; +} + +static inline cycle_t arch_counter_get_cntvct (void ) +{ +cycle_t cval; + + asmvolatile ("mrs %0, cntvct_el0" :"=r" (cval)); + +return cval; +} + +#endif
arch/arm64/include/asm/timex.h new file +29 -0
@@ -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
@@ -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
@@ -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
@@ -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
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_EL0register. The physical counter is also accessible from user space allowing fastgettimeofday()implementation.Signed-off-by Marc Zyngier <[email protected]>Signed-off-by Will Deacon <[email protected]>Signed-off-by Catalin Marinas <[email protected]>Acked-by Tony Lindgren <[email protected]>
Re: [PATCH v3 28/31] arm64: Generic timers support
In reply to Catalin MarinasQuoted 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_EL0register. The physical counter is also accessible from user space allowing fastgettimeofday()implementation.
Quoted 5 lines
Signed-off-by Marc Zyngier <[email protected]>Signed-off-by Will Deacon <[email protected]>Signed-off-by Catalin Marinas <[email protected]>Acked-by Tony Lindgren <[email protected]>---
Thanks for C3STOP update.
Catalin Marinas
maintainerPATCH v3 29/31 arm64: Miscellaneous header files
In reply to Catalin MarinasThis 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
Re: [PATCH v3 29/31] arm64: Miscellaneous header files
Quoted 7 lines · Catalin Marinas
This patch introduces a few AArch64-specific header files together with
Kbuildentries for generic headers.Signed-off-by Will Deacon <[email protected]>Signed-off-by Catalin Marinas <[email protected]>Acked-by Tony Lindgren <[email protected]>
Catalin Marinas
maintainerPATCH v3 30/31 arm64: Build infrastructure
In reply to Catalin MarinasThis 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
@@ -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
@@ -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
@@ -0,0 +1,2 @@ +Image +Image.gz
arch/arm64/boot/Makefile new file +36 -0
@@ -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
@@ -0,0 +1 @@ +/* Empty for now */
arch/arm64/kernel/.gitignore new file +1 -0
@@ -0,0 +1 @@ +vmlinux.lds
arch/arm64/kernel/Makefile new file +27 -0
@@ -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
@@ -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
@@ -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
@@ -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
Re: [PATCH v3 30/31] arm64: Build infrastructure
Quoted 6 lines · Catalin Marinas
This patch adds
MakefileandKconfigfiles required for building an AArch64 kernel.Signed-off-by Will Deacon <[email protected]>Signed-off-by Catalin Marinas <[email protected]>Acked-by Tony Lindgren <[email protected]>
Catalin Marinas
maintainerPATCH v3 31/31 arm64: MAINTAINERS update
In reply to Catalin MarinasThis patch updates the MAINTAINERS file for the AArch64 Linux kernel port.
--- MAINTAINERS | 6 ++++++ 1 files changed, 6 insertions(+), 0 deletions(-)
MAINTAINERS +6 -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]> +L: [email protected] (moderated for non-subscribers) +S: Maintained +F: arch/arm64/ + ASC7621 HARDWARE MONITOR DRIVER M: George Joseph <[email protected]> L: [email protected]
Re: [PATCH v3 31/31] arm64: MAINTAINERS update
Quoted 15 lines · Catalin Marinas
This patch updates the
MAINTAINERSfile for the AArch64 Linux kernel port.Signed-off-by Catalin Marinas <[email protected]>Acked-by Tony Lindgren <[email protected]>Acked-by Arnd Bergmann <[email protected]>--- MAINTAINERS | 6 ++++++ 1 files changed, 6 insertions(+), 0 deletions(-)MAINTAINERS +0
-0
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.
Re: [PATCH v3 31/31] arm64: MAINTAINERS update
Quoted 19 lines · Jean-Christophe PLAGNIOL-VILLARD
Quoted 18 lines · Catalin Marinas
This patch updates the
MAINTAINERSfile for the AArch64 Linux kernel port.Signed-off-by Catalin Marinas <[email protected]>Acked-by Tony Lindgren <[email protected]>Acked-by Arnd Bergmann <[email protected]>--- MAINTAINERS | 6 ++++++ 1 files changed, 6 insertions(+), 0 deletions(-)MAINTAINERS +0
-0@@ -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
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
MAINTAINERSfile for the AArch64 Linux kernel port.Signed-off-by Catalin Marinas <[email protected]>Acked-by Tony Lindgren <[email protected]>Acked-by Arnd Bergmann <[email protected]>--- MAINTAINERS | 6 ++++++ 1 files changed, 6 insertions(+), 0 deletions(-)MAINTAINERS +0
-0@@ -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.
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
MAINTAINERSfile for the AArch64 Linux kernel port.Signed-off-by Catalin Marinas <[email protected]>Acked-by Tony Lindgren <[email protected]>Acked-by Arnd Bergmann <[email protected]>--- MAINTAINERS | 6 ++++++ 1 files changed, 6 insertions(+), 0 deletions(-)MAINTAINERS +0
-0@@ -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
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.gitupstream
Quoted 15 lines
Main changes since the previous version:
- ptrace interface now using regsets for TLS and hardware debug registers.
-sys_personalityfixes.PER_LINUXis the default for all tasks (32 or 64-bit) and there is nocompat_sys_personalitydefined.
-Kconfigclean-up (unused symbols,AARCH32_EMULATIONremoved in favour of COMPAT).
- Clean-up of the __cpuc_* function prefixes.
- CPU information table implemented in C rather than assembly.
- __bad_* function calls replaced withBUILD_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 toarch/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
Catalin Marinas
maintainerQuoted 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.gitupstreamQuoted 15 lines
Main changes since the previous version:
- ptrace interface now using regsets for TLS and hardware debug registers.
-sys_personalityfixes.PER_LINUXis the default for all tasks (32 or 64-bit) and there is nocompat_sys_personalitydefined.
-Kconfigclean-up (unused symbols,AARCH32_EMULATIONremoved in favour of COMPAT).
- Clean-up of the __cpuc_* function prefixes.
- CPU information table implemented in C rather than assembly.
- __bad_* function calls replaced withBUILD_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 toarch/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
Acked-by Olof Johansson <[email protected]>
Thanks.
Signature · 1 line
Catalin
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.
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
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
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.gitupstream
Quoted 15 lines
Main changes since the previous version:
- ptrace interface now using regsets for TLS and hardware debug registers.
-sys_personalityfixes.PER_LINUXis the default for all tasks (32 or 64-bit) and there is nocompat_sys_personalitydefined.
-Kconfigclean-up (unused symbols,AARCH32_EMULATIONremoved in favour of COMPAT).
- Clean-up of the __cpuc_* function prefixes.
- CPU information table implemented in C rather than assembly.
- __bad_* function calls replaced withBUILD_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 toarch/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
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.
Arnd Bergmann
maintainerQuoted 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