diff options
66 files changed, 3061 insertions, 953 deletions
diff --git a/Documentation/arm64/booting.txt b/Documentation/arm64/booting.txt index 37fc4f632176..85af34d55cee 100644 --- a/Documentation/arm64/booting.txt +++ b/Documentation/arm64/booting.txt | |||
| @@ -72,27 +72,54 @@ The decompressed kernel image contains a 64-byte header as follows: | |||
| 72 | 72 | ||
| 73 | u32 code0; /* Executable code */ | 73 | u32 code0; /* Executable code */ |
| 74 | u32 code1; /* Executable code */ | 74 | u32 code1; /* Executable code */ |
| 75 | u64 text_offset; /* Image load offset */ | 75 | u64 text_offset; /* Image load offset, little endian */ |
| 76 | u64 res0 = 0; /* reserved */ | 76 | u64 image_size; /* Effective Image size, little endian */ |
| 77 | u64 res1 = 0; /* reserved */ | 77 | u64 flags; /* kernel flags, little endian */ |
| 78 | u64 res2 = 0; /* reserved */ | 78 | u64 res2 = 0; /* reserved */ |
| 79 | u64 res3 = 0; /* reserved */ | 79 | u64 res3 = 0; /* reserved */ |
| 80 | u64 res4 = 0; /* reserved */ | 80 | u64 res4 = 0; /* reserved */ |
| 81 | u32 magic = 0x644d5241; /* Magic number, little endian, "ARM\x64" */ | 81 | u32 magic = 0x644d5241; /* Magic number, little endian, "ARM\x64" */ |
| 82 | u32 res5 = 0; /* reserved */ | 82 | u32 res5; /* reserved (used for PE COFF offset) */ |
| 83 | 83 | ||
| 84 | 84 | ||
| 85 | Header notes: | 85 | Header notes: |
| 86 | 86 | ||
| 87 | - As of v3.17, all fields are little endian unless stated otherwise. | ||
| 88 | |||
| 87 | - code0/code1 are responsible for branching to stext. | 89 | - code0/code1 are responsible for branching to stext. |
| 90 | |||
| 88 | - when booting through EFI, code0/code1 are initially skipped. | 91 | - when booting through EFI, code0/code1 are initially skipped. |
| 89 | res5 is an offset to the PE header and the PE header has the EFI | 92 | res5 is an offset to the PE header and the PE header has the EFI |
| 90 | entry point (efi_stub_entry). When the stub has done its work, it | 93 | entry point (efi_stub_entry). When the stub has done its work, it |
| 91 | jumps to code0 to resume the normal boot process. | 94 | jumps to code0 to resume the normal boot process. |
| 92 | 95 | ||
| 93 | The image must be placed at the specified offset (currently 0x80000) | 96 | - Prior to v3.17, the endianness of text_offset was not specified. In |
| 94 | from the start of the system RAM and called there. The start of the | 97 | these cases image_size is zero and text_offset is 0x80000 in the |
| 95 | system RAM must be aligned to 2MB. | 98 | endianness of the kernel. Where image_size is non-zero image_size is |
| 99 | little-endian and must be respected. Where image_size is zero, | ||
| 100 | text_offset can be assumed to be 0x80000. | ||
| 101 | |||
| 102 | - The flags field (introduced in v3.17) is a little-endian 64-bit field | ||
| 103 | composed as follows: | ||
| 104 | Bit 0: Kernel endianness. 1 if BE, 0 if LE. | ||
| 105 | Bits 1-63: Reserved. | ||
| 106 | |||
| 107 | - When image_size is zero, a bootloader should attempt to keep as much | ||
| 108 | memory as possible free for use by the kernel immediately after the | ||
| 109 | end of the kernel image. The amount of space required will vary | ||
| 110 | depending on selected features, and is effectively unbound. | ||
| 111 | |||
| 112 | The Image must be placed text_offset bytes from a 2MB aligned base | ||
| 113 | address near the start of usable system RAM and called there. Memory | ||
| 114 | below that base address is currently unusable by Linux, and therefore it | ||
| 115 | is strongly recommended that this location is the start of system RAM. | ||
| 116 | At least image_size bytes from the start of the image must be free for | ||
| 117 | use by the kernel. | ||
| 118 | |||
| 119 | Any memory described to the kernel (even that below the 2MB aligned base | ||
| 120 | address) which is not marked as reserved from the kernel e.g. with a | ||
| 121 | memreserve region in the device tree) will be considered as available to | ||
| 122 | the kernel. | ||
| 96 | 123 | ||
| 97 | Before jumping into the kernel, the following conditions must be met: | 124 | Before jumping into the kernel, the following conditions must be met: |
| 98 | 125 | ||
diff --git a/Documentation/arm64/memory.txt b/Documentation/arm64/memory.txt index d50fa618371b..344e85cc7323 100644 --- a/Documentation/arm64/memory.txt +++ b/Documentation/arm64/memory.txt | |||
| @@ -2,18 +2,18 @@ | |||
| 2 | ============================== | 2 | ============================== |
| 3 | 3 | ||
| 4 | Author: Catalin Marinas <catalin.marinas@arm.com> | 4 | Author: Catalin Marinas <catalin.marinas@arm.com> |
| 5 | Date : 20 February 2012 | ||
| 6 | 5 | ||
| 7 | This document describes the virtual memory layout used by the AArch64 | 6 | This document describes the virtual memory layout used by the AArch64 |
| 8 | Linux kernel. The architecture allows up to 4 levels of translation | 7 | Linux kernel. The architecture allows up to 4 levels of translation |
| 9 | tables with a 4KB page size and up to 3 levels with a 64KB page size. | 8 | tables with a 4KB page size and up to 3 levels with a 64KB page size. |
| 10 | 9 | ||
| 11 | AArch64 Linux uses 3 levels of translation tables with the 4KB page | 10 | AArch64 Linux uses either 3 levels or 4 levels of translation tables |
| 12 | configuration, allowing 39-bit (512GB) virtual addresses for both user | 11 | with the 4KB page configuration, allowing 39-bit (512GB) or 48-bit |
| 13 | and kernel. With 64KB pages, only 2 levels of translation tables are | 12 | (256TB) virtual addresses, respectively, for both user and kernel. With |
| 14 | used but the memory layout is the same. | 13 | 64KB pages, only 2 levels of translation tables, allowing 42-bit (4TB) |
| 14 | virtual address, are used but the memory layout is the same. | ||
| 15 | 15 | ||
| 16 | User addresses have bits 63:39 set to 0 while the kernel addresses have | 16 | User addresses have bits 63:48 set to 0 while the kernel addresses have |
| 17 | the same bits set to 1. TTBRx selection is given by bit 63 of the | 17 | the same bits set to 1. TTBRx selection is given by bit 63 of the |
| 18 | virtual address. The swapper_pg_dir contains only kernel (global) | 18 | virtual address. The swapper_pg_dir contains only kernel (global) |
| 19 | mappings while the user pgd contains only user (non-global) mappings. | 19 | mappings while the user pgd contains only user (non-global) mappings. |
| @@ -21,58 +21,40 @@ The swapper_pgd_dir address is written to TTBR1 and never written to | |||
| 21 | TTBR0. | 21 | TTBR0. |
| 22 | 22 | ||
| 23 | 23 | ||
| 24 | AArch64 Linux memory layout with 4KB pages: | 24 | AArch64 Linux memory layout with 4KB pages + 3 levels: |
| 25 | 25 | ||
| 26 | Start End Size Use | 26 | Start End Size Use |
| 27 | ----------------------------------------------------------------------- | 27 | ----------------------------------------------------------------------- |
| 28 | 0000000000000000 0000007fffffffff 512GB user | 28 | 0000000000000000 0000007fffffffff 512GB user |
| 29 | ffffff8000000000 ffffffffffffffff 512GB kernel | ||
| 29 | 30 | ||
| 30 | ffffff8000000000 ffffffbbfffeffff ~240GB vmalloc | ||
| 31 | 31 | ||
| 32 | ffffffbbffff0000 ffffffbbffffffff 64KB [guard page] | 32 | AArch64 Linux memory layout with 4KB pages + 4 levels: |
| 33 | 33 | ||
| 34 | ffffffbc00000000 ffffffbdffffffff 8GB vmemmap | 34 | Start End Size Use |
| 35 | 35 | ----------------------------------------------------------------------- | |
| 36 | ffffffbe00000000 ffffffbffbbfffff ~8GB [guard, future vmmemap] | 36 | 0000000000000000 0000ffffffffffff 256TB user |
| 37 | 37 | ffff000000000000 ffffffffffffffff 256TB kernel | |
| 38 | ffffffbffa000000 ffffffbffaffffff 16MB PCI I/O space | ||
| 39 | |||
| 40 | ffffffbffb000000 ffffffbffbbfffff 12MB [guard] | ||
| 41 | |||
| 42 | ffffffbffbc00000 ffffffbffbdfffff 2MB fixed mappings | ||
| 43 | |||
| 44 | ffffffbffbe00000 ffffffbffbffffff 2MB [guard] | ||
| 45 | |||
| 46 | ffffffbffc000000 ffffffbfffffffff 64MB modules | ||
| 47 | |||
| 48 | ffffffc000000000 ffffffffffffffff 256GB kernel logical memory map | ||
| 49 | 38 | ||
| 50 | 39 | ||
| 51 | AArch64 Linux memory layout with 64KB pages: | 40 | AArch64 Linux memory layout with 64KB pages + 2 levels: |
| 52 | 41 | ||
| 53 | Start End Size Use | 42 | Start End Size Use |
| 54 | ----------------------------------------------------------------------- | 43 | ----------------------------------------------------------------------- |
| 55 | 0000000000000000 000003ffffffffff 4TB user | 44 | 0000000000000000 000003ffffffffff 4TB user |
| 45 | fffffc0000000000 ffffffffffffffff 4TB kernel | ||
| 56 | 46 | ||
| 57 | fffffc0000000000 fffffdfbfffeffff ~2TB vmalloc | ||
| 58 | 47 | ||
| 59 | fffffdfbffff0000 fffffdfbffffffff 64KB [guard page] | 48 | AArch64 Linux memory layout with 64KB pages + 3 levels: |
| 60 | 49 | ||
| 61 | fffffdfc00000000 fffffdfdffffffff 8GB vmemmap | 50 | Start End Size Use |
| 62 | 51 | ----------------------------------------------------------------------- | |
| 63 | fffffdfe00000000 fffffdfffbbfffff ~8GB [guard, future vmmemap] | 52 | 0000000000000000 0000ffffffffffff 256TB user |
| 64 | 53 | ffff000000000000 ffffffffffffffff 256TB kernel | |
| 65 | fffffdfffa000000 fffffdfffaffffff 16MB PCI I/O space | ||
| 66 | |||
| 67 | fffffdfffb000000 fffffdfffbbfffff 12MB [guard] | ||
| 68 | |||
| 69 | fffffdfffbc00000 fffffdfffbdfffff 2MB fixed mappings | ||
| 70 | |||
| 71 | fffffdfffbe00000 fffffdfffbffffff 2MB [guard] | ||
| 72 | 54 | ||
| 73 | fffffdfffc000000 fffffdffffffffff 64MB modules | ||
| 74 | 55 | ||
| 75 | fffffe0000000000 ffffffffffffffff 2TB kernel logical memory map | 56 | For details of the virtual kernel memory layout please see the kernel |
| 57 | booting log. | ||
| 76 | 58 | ||
| 77 | 59 | ||
| 78 | Translation table lookup with 4KB pages: | 60 | Translation table lookup with 4KB pages: |
| @@ -86,7 +68,7 @@ Translation table lookup with 4KB pages: | |||
| 86 | | | | | +-> [20:12] L3 index | 68 | | | | | +-> [20:12] L3 index |
| 87 | | | | +-----------> [29:21] L2 index | 69 | | | | +-----------> [29:21] L2 index |
| 88 | | | +---------------------> [38:30] L1 index | 70 | | | +---------------------> [38:30] L1 index |
| 89 | | +-------------------------------> [47:39] L0 index (not used) | 71 | | +-------------------------------> [47:39] L0 index |
| 90 | +-------------------------------------------------> [63] TTBR0/1 | 72 | +-------------------------------------------------> [63] TTBR0/1 |
| 91 | 73 | ||
| 92 | 74 | ||
| @@ -99,10 +81,11 @@ Translation table lookup with 64KB pages: | |||
| 99 | | | | | v | 81 | | | | | v |
| 100 | | | | | [15:0] in-page offset | 82 | | | | | [15:0] in-page offset |
| 101 | | | | +----------> [28:16] L3 index | 83 | | | | +----------> [28:16] L3 index |
| 102 | | | +--------------------------> [41:29] L2 index (only 38:29 used) | 84 | | | +--------------------------> [41:29] L2 index |
| 103 | | +-------------------------------> [47:42] L1 index (not used) | 85 | | +-------------------------------> [47:42] L1 index |
| 104 | +-------------------------------------------------> [63] TTBR0/1 | 86 | +-------------------------------------------------> [63] TTBR0/1 |
| 105 | 87 | ||
| 88 | |||
| 106 | When using KVM, the hypervisor maps kernel pages in EL2, at a fixed | 89 | When using KVM, the hypervisor maps kernel pages in EL2, at a fixed |
| 107 | offset from the kernel VA (top 24bits of the kernel VA set to zero): | 90 | offset from the kernel VA (top 24bits of the kernel VA set to zero): |
| 108 | 91 | ||
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 839f48c26ef0..f3b584be76d7 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig | |||
| @@ -1,7 +1,6 @@ | |||
| 1 | config ARM64 | 1 | config ARM64 |
| 2 | def_bool y | 2 | def_bool y |
| 3 | select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE | 3 | select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE |
| 4 | select ARCH_HAS_OPP | ||
| 5 | select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST | 4 | select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST |
| 6 | select ARCH_USE_CMPXCHG_LOCKREF | 5 | select ARCH_USE_CMPXCHG_LOCKREF |
| 7 | select ARCH_SUPPORTS_ATOMIC_RMW | 6 | select ARCH_SUPPORTS_ATOMIC_RMW |
| @@ -11,6 +10,8 @@ config ARM64 | |||
| 11 | select ARM_AMBA | 10 | select ARM_AMBA |
| 12 | select ARM_ARCH_TIMER | 11 | select ARM_ARCH_TIMER |
| 13 | select ARM_GIC | 12 | select ARM_GIC |
| 13 | select AUDIT_ARCH_COMPAT_GENERIC | ||
| 14 | select ARM_GIC_V3 | ||
| 14 | select BUILDTIME_EXTABLE_SORT | 15 | select BUILDTIME_EXTABLE_SORT |
| 15 | select CLONE_BACKWARDS | 16 | select CLONE_BACKWARDS |
| 16 | select COMMON_CLK | 17 | select COMMON_CLK |
| @@ -29,10 +30,12 @@ config ARM64 | |||
| 29 | select GENERIC_STRNLEN_USER | 30 | select GENERIC_STRNLEN_USER |
| 30 | select GENERIC_TIME_VSYSCALL | 31 | select GENERIC_TIME_VSYSCALL |
| 31 | select HARDIRQS_SW_RESEND | 32 | select HARDIRQS_SW_RESEND |
| 33 | select HAVE_ARCH_AUDITSYSCALL | ||
| 32 | select HAVE_ARCH_JUMP_LABEL | 34 | select HAVE_ARCH_JUMP_LABEL |
| 33 | select HAVE_ARCH_KGDB | 35 | select HAVE_ARCH_KGDB |
| 34 | select HAVE_ARCH_TRACEHOOK | 36 | select HAVE_ARCH_TRACEHOOK |
| 35 | select HAVE_C_RECORDMCOUNT | 37 | select HAVE_C_RECORDMCOUNT |
| 38 | select HAVE_CC_STACKPROTECTOR | ||
| 36 | select HAVE_DEBUG_BUGVERBOSE | 39 | select HAVE_DEBUG_BUGVERBOSE |
| 37 | select HAVE_DEBUG_KMEMLEAK | 40 | select HAVE_DEBUG_KMEMLEAK |
| 38 | select HAVE_DMA_API_DEBUG | 41 | select HAVE_DMA_API_DEBUG |
| @@ -63,6 +66,7 @@ config ARM64 | |||
| 63 | select RTC_LIB | 66 | select RTC_LIB |
| 64 | select SPARSE_IRQ | 67 | select SPARSE_IRQ |
| 65 | select SYSCTL_EXCEPTION_TRACE | 68 | select SYSCTL_EXCEPTION_TRACE |
| 69 | select HAVE_CONTEXT_TRACKING | ||
| 66 | help | 70 | help |
| 67 | ARM 64-bit (AArch64) Linux support. | 71 | ARM 64-bit (AArch64) Linux support. |
| 68 | 72 | ||
| @@ -155,14 +159,63 @@ endmenu | |||
| 155 | 159 | ||
| 156 | menu "Kernel Features" | 160 | menu "Kernel Features" |
| 157 | 161 | ||
| 162 | choice | ||
| 163 | prompt "Page size" | ||
| 164 | default ARM64_4K_PAGES | ||
| 165 | help | ||
| 166 | Page size (translation granule) configuration. | ||
| 167 | |||
| 168 | config ARM64_4K_PAGES | ||
| 169 | bool "4KB" | ||
| 170 | help | ||
| 171 | This feature enables 4KB pages support. | ||
| 172 | |||
| 158 | config ARM64_64K_PAGES | 173 | config ARM64_64K_PAGES |
| 159 | bool "Enable 64KB pages support" | 174 | bool "64KB" |
| 160 | help | 175 | help |
| 161 | This feature enables 64KB pages support (4KB by default) | 176 | This feature enables 64KB pages support (4KB by default) |
| 162 | allowing only two levels of page tables and faster TLB | 177 | allowing only two levels of page tables and faster TLB |
| 163 | look-up. AArch32 emulation is not available when this feature | 178 | look-up. AArch32 emulation is not available when this feature |
| 164 | is enabled. | 179 | is enabled. |
| 165 | 180 | ||
| 181 | endchoice | ||
| 182 | |||
| 183 | choice | ||
| 184 | prompt "Virtual address space size" | ||
| 185 | default ARM64_VA_BITS_39 if ARM64_4K_PAGES | ||
| 186 | default ARM64_VA_BITS_42 if ARM64_64K_PAGES | ||
| 187 | help | ||
| 188 | Allows choosing one of multiple possible virtual address | ||
| 189 | space sizes. The level of translation table is determined by | ||
| 190 | a combination of page size and virtual address space size. | ||
| 191 | |||
| 192 | config ARM64_VA_BITS_39 | ||
| 193 | bool "39-bit" | ||
| 194 | depends on ARM64_4K_PAGES | ||
| 195 | |||
| 196 | config ARM64_VA_BITS_42 | ||
| 197 | bool "42-bit" | ||
| 198 | depends on ARM64_64K_PAGES | ||
| 199 | |||
| 200 | config ARM64_VA_BITS_48 | ||
| 201 | bool "48-bit" | ||
| 202 | depends on BROKEN | ||
| 203 | |||
| 204 | endchoice | ||
| 205 | |||
| 206 | config ARM64_VA_BITS | ||
| 207 | int | ||
| 208 | default 39 if ARM64_VA_BITS_39 | ||
| 209 | default 42 if ARM64_VA_BITS_42 | ||
| 210 | default 48 if ARM64_VA_BITS_48 | ||
| 211 | |||
| 212 | config ARM64_PGTABLE_LEVELS | ||
| 213 | int | ||
| 214 | default 2 if ARM64_64K_PAGES && ARM64_VA_BITS_42 | ||
| 215 | default 3 if ARM64_64K_PAGES && ARM64_VA_BITS_48 | ||
| 216 | default 3 if ARM64_4K_PAGES && ARM64_VA_BITS_39 | ||
| 217 | default 4 if ARM64_4K_PAGES && ARM64_VA_BITS_48 | ||
| 218 | |||
| 166 | config CPU_BIG_ENDIAN | 219 | config CPU_BIG_ENDIAN |
| 167 | bool "Build big-endian kernel" | 220 | bool "Build big-endian kernel" |
| 168 | help | 221 | help |
diff --git a/arch/arm64/Kconfig.debug b/arch/arm64/Kconfig.debug index 1c1b75629842..4ee8e90b7a45 100644 --- a/arch/arm64/Kconfig.debug +++ b/arch/arm64/Kconfig.debug | |||
| @@ -28,4 +28,19 @@ config PID_IN_CONTEXTIDR | |||
| 28 | instructions during context switch. Say Y here only if you are | 28 | instructions during context switch. Say Y here only if you are |
| 29 | planning to use hardware trace tools with this kernel. | 29 | planning to use hardware trace tools with this kernel. |
| 30 | 30 | ||
| 31 | config ARM64_RANDOMIZE_TEXT_OFFSET | ||
| 32 | bool "Randomize TEXT_OFFSET at build time" | ||
| 33 | help | ||
| 34 | Say Y here if you want the image load offset (AKA TEXT_OFFSET) | ||
| 35 | of the kernel to be randomized at build-time. When selected, | ||
| 36 | this option will cause TEXT_OFFSET to be randomized upon any | ||
| 37 | build of the kernel, and the offset will be reflected in the | ||
| 38 | text_offset field of the resulting Image. This can be used to | ||
| 39 | fuzz-test bootloaders which respect text_offset. | ||
| 40 | |||
| 41 | This option is intended for bootloader and/or kernel testing | ||
| 42 | only. Bootloaders must make no assumptions regarding the value | ||
| 43 | of TEXT_OFFSET and platforms must not require a specific | ||
| 44 | value. | ||
| 45 | |||
| 31 | endmenu | 46 | endmenu |
diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile index 8185a913c5ed..e8d025c1459e 100644 --- a/arch/arm64/Makefile +++ b/arch/arm64/Makefile | |||
| @@ -38,7 +38,11 @@ CHECKFLAGS += -D__aarch64__ | |||
| 38 | head-y := arch/arm64/kernel/head.o | 38 | head-y := arch/arm64/kernel/head.o |
| 39 | 39 | ||
| 40 | # The byte offset of the kernel image in RAM from the start of RAM. | 40 | # The byte offset of the kernel image in RAM from the start of RAM. |
| 41 | ifeq ($(CONFIG_ARM64_RANDOMIZE_TEXT_OFFSET), y) | ||
| 42 | TEXT_OFFSET := $(shell awk 'BEGIN {srand(); printf "0x%04x0\n", int(65535 * rand())}') | ||
| 43 | else | ||
| 41 | TEXT_OFFSET := 0x00080000 | 44 | TEXT_OFFSET := 0x00080000 |
| 45 | endif | ||
| 42 | 46 | ||
| 43 | export TEXT_OFFSET GZFLAGS | 47 | export TEXT_OFFSET GZFLAGS |
| 44 | 48 | ||
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index 3421f316f5dc..1e52b741d806 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig | |||
| @@ -52,8 +52,11 @@ CONFIG_IP_PNP_BOOTP=y | |||
| 52 | # CONFIG_INET_LRO is not set | 52 | # CONFIG_INET_LRO is not set |
| 53 | # CONFIG_IPV6 is not set | 53 | # CONFIG_IPV6 is not set |
| 54 | # CONFIG_WIRELESS is not set | 54 | # CONFIG_WIRELESS is not set |
| 55 | CONFIG_NET_9P=y | ||
| 56 | CONFIG_NET_9P_VIRTIO=y | ||
| 55 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | 57 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" |
| 56 | CONFIG_DEVTMPFS=y | 58 | CONFIG_DEVTMPFS=y |
| 59 | CONFIG_DEVTMPFS_MOUNT=y | ||
| 57 | CONFIG_DMA_CMA=y | 60 | CONFIG_DMA_CMA=y |
| 58 | CONFIG_BLK_DEV_LOOP=y | 61 | CONFIG_BLK_DEV_LOOP=y |
| 59 | CONFIG_VIRTIO_BLK=y | 62 | CONFIG_VIRTIO_BLK=y |
| @@ -65,6 +68,7 @@ CONFIG_PATA_PLATFORM=y | |||
| 65 | CONFIG_PATA_OF_PLATFORM=y | 68 | CONFIG_PATA_OF_PLATFORM=y |
| 66 | CONFIG_NETDEVICES=y | 69 | CONFIG_NETDEVICES=y |
| 67 | CONFIG_TUN=y | 70 | CONFIG_TUN=y |
| 71 | CONFIG_VIRTIO_NET=y | ||
| 68 | CONFIG_SMC91X=y | 72 | CONFIG_SMC91X=y |
| 69 | CONFIG_SMSC911X=y | 73 | CONFIG_SMSC911X=y |
| 70 | # CONFIG_WLAN is not set | 74 | # CONFIG_WLAN is not set |
| @@ -76,6 +80,7 @@ CONFIG_SERIAL_8250_CONSOLE=y | |||
| 76 | CONFIG_SERIAL_AMBA_PL011=y | 80 | CONFIG_SERIAL_AMBA_PL011=y |
| 77 | CONFIG_SERIAL_AMBA_PL011_CONSOLE=y | 81 | CONFIG_SERIAL_AMBA_PL011_CONSOLE=y |
| 78 | CONFIG_SERIAL_OF_PLATFORM=y | 82 | CONFIG_SERIAL_OF_PLATFORM=y |
| 83 | CONFIG_VIRTIO_CONSOLE=y | ||
| 79 | # CONFIG_HW_RANDOM is not set | 84 | # CONFIG_HW_RANDOM is not set |
| 80 | # CONFIG_HWMON is not set | 85 | # CONFIG_HWMON is not set |
| 81 | CONFIG_REGULATOR=y | 86 | CONFIG_REGULATOR=y |
| @@ -90,6 +95,7 @@ CONFIG_USB_ISP1760_HCD=y | |||
| 90 | CONFIG_USB_STORAGE=y | 95 | CONFIG_USB_STORAGE=y |
| 91 | CONFIG_MMC=y | 96 | CONFIG_MMC=y |
| 92 | CONFIG_MMC_ARMMMCI=y | 97 | CONFIG_MMC_ARMMMCI=y |
| 98 | CONFIG_VIRTIO_BALLOON=y | ||
| 93 | CONFIG_VIRTIO_MMIO=y | 99 | CONFIG_VIRTIO_MMIO=y |
| 94 | # CONFIG_IOMMU_SUPPORT is not set | 100 | # CONFIG_IOMMU_SUPPORT is not set |
| 95 | CONFIG_EXT2_FS=y | 101 | CONFIG_EXT2_FS=y |
| @@ -107,6 +113,7 @@ CONFIG_HUGETLBFS=y | |||
| 107 | # CONFIG_MISC_FILESYSTEMS is not set | 113 | # CONFIG_MISC_FILESYSTEMS is not set |
| 108 | CONFIG_NFS_FS=y | 114 | CONFIG_NFS_FS=y |
| 109 | CONFIG_ROOT_NFS=y | 115 | CONFIG_ROOT_NFS=y |
| 116 | CONFIG_9P_FS=y | ||
| 110 | CONFIG_NLS_CODEPAGE_437=y | 117 | CONFIG_NLS_CODEPAGE_437=y |
| 111 | CONFIG_NLS_ISO8859_1=y | 118 | CONFIG_NLS_ISO8859_1=y |
| 112 | CONFIG_VIRTUALIZATION=y | 119 | CONFIG_VIRTUALIZATION=y |
diff --git a/arch/arm64/crypto/Makefile b/arch/arm64/crypto/Makefile index 2070a56ecc46..a3f935fde975 100644 --- a/arch/arm64/crypto/Makefile +++ b/arch/arm64/crypto/Makefile | |||
| @@ -35,4 +35,4 @@ AFLAGS_aes-neon.o := -DINTERLEAVE=4 | |||
| 35 | CFLAGS_aes-glue-ce.o := -DUSE_V8_CRYPTO_EXTENSIONS | 35 | CFLAGS_aes-glue-ce.o := -DUSE_V8_CRYPTO_EXTENSIONS |
| 36 | 36 | ||
| 37 | $(obj)/aes-glue-%.o: $(src)/aes-glue.c FORCE | 37 | $(obj)/aes-glue-%.o: $(src)/aes-glue.c FORCE |
| 38 | $(call if_changed_dep,cc_o_c) | 38 | $(call if_changed_rule,cc_o_c) |
diff --git a/arch/arm64/include/asm/cacheflush.h b/arch/arm64/include/asm/cacheflush.h index a5176cf32dad..f2defe1c380c 100644 --- a/arch/arm64/include/asm/cacheflush.h +++ b/arch/arm64/include/asm/cacheflush.h | |||
| @@ -138,19 +138,10 @@ static inline void __flush_icache_all(void) | |||
| 138 | #define flush_icache_page(vma,page) do { } while (0) | 138 | #define flush_icache_page(vma,page) do { } while (0) |
| 139 | 139 | ||
| 140 | /* | 140 | /* |
| 141 | * flush_cache_vmap() is used when creating mappings (eg, via vmap, | 141 | * Not required on AArch64 (PIPT or VIPT non-aliasing D-cache). |
| 142 | * vmalloc, ioremap etc) in kernel space for pages. On non-VIPT | ||
| 143 | * caches, since the direct-mappings of these pages may contain cached | ||
| 144 | * data, we need to do a full cache flush to ensure that writebacks | ||
| 145 | * don't corrupt data placed into these pages via the new mappings. | ||
| 146 | */ | 142 | */ |
| 147 | static inline void flush_cache_vmap(unsigned long start, unsigned long end) | 143 | static inline void flush_cache_vmap(unsigned long start, unsigned long end) |
| 148 | { | 144 | { |
| 149 | /* | ||
| 150 | * set_pte_at() called from vmap_pte_range() does not | ||
| 151 | * have a DSB after cleaning the cache line. | ||
| 152 | */ | ||
| 153 | dsb(ish); | ||
| 154 | } | 145 | } |
| 155 | 146 | ||
| 156 | static inline void flush_cache_vunmap(unsigned long start, unsigned long end) | 147 | static inline void flush_cache_vunmap(unsigned long start, unsigned long end) |
diff --git a/arch/arm64/include/asm/cachetype.h b/arch/arm64/include/asm/cachetype.h index 4b23e758d5e0..7a2e0762cb40 100644 --- a/arch/arm64/include/asm/cachetype.h +++ b/arch/arm64/include/asm/cachetype.h | |||
| @@ -30,10 +30,14 @@ | |||
| 30 | 30 | ||
| 31 | #ifndef __ASSEMBLY__ | 31 | #ifndef __ASSEMBLY__ |
| 32 | 32 | ||
| 33 | static inline u32 icache_policy(void) | 33 | #include <linux/bitops.h> |
| 34 | { | 34 | |
| 35 | return (read_cpuid_cachetype() >> CTR_L1IP_SHIFT) & CTR_L1IP_MASK; | 35 | #define CTR_L1IP(ctr) (((ctr) >> CTR_L1IP_SHIFT) & CTR_L1IP_MASK) |
| 36 | } | 36 | |
| 37 | #define ICACHEF_ALIASING BIT(0) | ||
| 38 | #define ICACHEF_AIVIVT BIT(1) | ||
| 39 | |||
| 40 | extern unsigned long __icache_flags; | ||
| 37 | 41 | ||
| 38 | /* | 42 | /* |
| 39 | * Whilst the D-side always behaves as PIPT on AArch64, aliasing is | 43 | * Whilst the D-side always behaves as PIPT on AArch64, aliasing is |
| @@ -41,12 +45,12 @@ static inline u32 icache_policy(void) | |||
| 41 | */ | 45 | */ |
| 42 | static inline int icache_is_aliasing(void) | 46 | static inline int icache_is_aliasing(void) |
| 43 | { | 47 | { |
| 44 | return icache_policy() != ICACHE_POLICY_PIPT; | 48 | return test_bit(ICACHEF_ALIASING, &__icache_flags); |
| 45 | } | 49 | } |
| 46 | 50 | ||
| 47 | static inline int icache_is_aivivt(void) | 51 | static inline int icache_is_aivivt(void) |
| 48 | { | 52 | { |
| 49 | return icache_policy() == ICACHE_POLICY_AIVIVT; | 53 | return test_bit(ICACHEF_AIVIVT, &__icache_flags); |
| 50 | } | 54 | } |
| 51 | 55 | ||
| 52 | static inline u32 cache_type_cwg(void) | 56 | static inline u32 cache_type_cwg(void) |
diff --git a/arch/arm64/include/asm/cpu.h b/arch/arm64/include/asm/cpu.h new file mode 100644 index 000000000000..056443086019 --- /dev/null +++ b/arch/arm64/include/asm/cpu.h | |||
| @@ -0,0 +1,59 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2014 ARM Ltd. | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License version 2 as | ||
| 6 | * published by the Free Software Foundation. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License | ||
| 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 15 | */ | ||
| 16 | #ifndef __ASM_CPU_H | ||
| 17 | #define __ASM_CPU_H | ||
| 18 | |||
| 19 | #include <linux/cpu.h> | ||
| 20 | #include <linux/init.h> | ||
| 21 | #include <linux/percpu.h> | ||
| 22 | |||
| 23 | /* | ||
| 24 | * Records attributes of an individual CPU. | ||
| 25 | */ | ||
| 26 | struct cpuinfo_arm64 { | ||
| 27 | struct cpu cpu; | ||
| 28 | u32 reg_ctr; | ||
| 29 | u32 reg_cntfrq; | ||
| 30 | u32 reg_dczid; | ||
| 31 | u32 reg_midr; | ||
| 32 | |||
| 33 | u64 reg_id_aa64isar0; | ||
| 34 | u64 reg_id_aa64isar1; | ||
| 35 | u64 reg_id_aa64mmfr0; | ||
| 36 | u64 reg_id_aa64mmfr1; | ||
| 37 | u64 reg_id_aa64pfr0; | ||
| 38 | u64 reg_id_aa64pfr1; | ||
| 39 | |||
| 40 | u32 reg_id_isar0; | ||
| 41 | u32 reg_id_isar1; | ||
| 42 | u32 reg_id_isar2; | ||
| 43 | u32 reg_id_isar3; | ||
| 44 | u32 reg_id_isar4; | ||
| 45 | u32 reg_id_isar5; | ||
| 46 | u32 reg_id_mmfr0; | ||
| 47 | u32 reg_id_mmfr1; | ||
| 48 | u32 reg_id_mmfr2; | ||
| 49 | u32 reg_id_mmfr3; | ||
| 50 | u32 reg_id_pfr0; | ||
| 51 | u32 reg_id_pfr1; | ||
| 52 | }; | ||
| 53 | |||
| 54 | DECLARE_PER_CPU(struct cpuinfo_arm64, cpu_data); | ||
| 55 | |||
| 56 | void cpuinfo_store_cpu(void); | ||
| 57 | void __init cpuinfo_store_boot_cpu(void); | ||
| 58 | |||
| 59 | #endif /* __ASM_CPU_H */ | ||
diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h index 27f54a7cc81b..379d0b874328 100644 --- a/arch/arm64/include/asm/cputype.h +++ b/arch/arm64/include/asm/cputype.h | |||
| @@ -18,6 +18,8 @@ | |||
| 18 | 18 | ||
| 19 | #define INVALID_HWID ULONG_MAX | 19 | #define INVALID_HWID ULONG_MAX |
| 20 | 20 | ||
| 21 | #define MPIDR_UP_BITMASK (0x1 << 30) | ||
| 22 | #define MPIDR_MT_BITMASK (0x1 << 24) | ||
| 21 | #define MPIDR_HWID_BITMASK 0xff00ffffff | 23 | #define MPIDR_HWID_BITMASK 0xff00ffffff |
| 22 | 24 | ||
| 23 | #define MPIDR_LEVEL_BITS_SHIFT 3 | 25 | #define MPIDR_LEVEL_BITS_SHIFT 3 |
| @@ -36,15 +38,34 @@ | |||
| 36 | __val; \ | 38 | __val; \ |
| 37 | }) | 39 | }) |
| 38 | 40 | ||
| 41 | #define MIDR_REVISION_MASK 0xf | ||
| 42 | #define MIDR_REVISION(midr) ((midr) & MIDR_REVISION_MASK) | ||
| 43 | #define MIDR_PARTNUM_SHIFT 4 | ||
| 44 | #define MIDR_PARTNUM_MASK (0xfff << MIDR_PARTNUM_SHIFT) | ||
| 45 | #define MIDR_PARTNUM(midr) \ | ||
| 46 | (((midr) & MIDR_PARTNUM_MASK) >> MIDR_PARTNUM_SHIFT) | ||
| 47 | #define MIDR_ARCHITECTURE_SHIFT 16 | ||
| 48 | #define MIDR_ARCHITECTURE_MASK (0xf << MIDR_ARCHITECTURE_SHIFT) | ||
| 49 | #define MIDR_ARCHITECTURE(midr) \ | ||
| 50 | (((midr) & MIDR_ARCHITECTURE_MASK) >> MIDR_ARCHITECTURE_SHIFT) | ||
| 51 | #define MIDR_VARIANT_SHIFT 20 | ||
| 52 | #define MIDR_VARIANT_MASK (0xf << MIDR_VARIANT_SHIFT) | ||
| 53 | #define MIDR_VARIANT(midr) \ | ||
| 54 | (((midr) & MIDR_VARIANT_MASK) >> MIDR_VARIANT_SHIFT) | ||
| 55 | #define MIDR_IMPLEMENTOR_SHIFT 24 | ||
| 56 | #define MIDR_IMPLEMENTOR_MASK (0xff << MIDR_IMPLEMENTOR_SHIFT) | ||
| 57 | #define MIDR_IMPLEMENTOR(midr) \ | ||
| 58 | (((midr) & MIDR_IMPLEMENTOR_MASK) >> MIDR_IMPLEMENTOR_SHIFT) | ||
| 59 | |||
| 39 | #define ARM_CPU_IMP_ARM 0x41 | 60 | #define ARM_CPU_IMP_ARM 0x41 |
| 40 | #define ARM_CPU_IMP_APM 0x50 | 61 | #define ARM_CPU_IMP_APM 0x50 |
| 41 | 62 | ||
| 42 | #define ARM_CPU_PART_AEM_V8 0xD0F0 | 63 | #define ARM_CPU_PART_AEM_V8 0xD0F |
| 43 | #define ARM_CPU_PART_FOUNDATION 0xD000 | 64 | #define ARM_CPU_PART_FOUNDATION 0xD00 |
| 44 | #define ARM_CPU_PART_CORTEX_A53 0xD030 | 65 | #define ARM_CPU_PART_CORTEX_A57 0xD07 |
| 45 | #define ARM_CPU_PART_CORTEX_A57 0xD070 | 66 | #define ARM_CPU_PART_CORTEX_A53 0xD03 |
| 46 | 67 | ||
| 47 | #define APM_CPU_PART_POTENZA 0x0000 | 68 | #define APM_CPU_PART_POTENZA 0x000 |
| 48 | 69 | ||
| 49 | #ifndef __ASSEMBLY__ | 70 | #ifndef __ASSEMBLY__ |
| 50 | 71 | ||
| @@ -65,12 +86,12 @@ static inline u64 __attribute_const__ read_cpuid_mpidr(void) | |||
| 65 | 86 | ||
| 66 | static inline unsigned int __attribute_const__ read_cpuid_implementor(void) | 87 | static inline unsigned int __attribute_const__ read_cpuid_implementor(void) |
| 67 | { | 88 | { |
| 68 | return (read_cpuid_id() & 0xFF000000) >> 24; | 89 | return MIDR_IMPLEMENTOR(read_cpuid_id()); |
| 69 | } | 90 | } |
| 70 | 91 | ||
| 71 | static inline unsigned int __attribute_const__ read_cpuid_part_number(void) | 92 | static inline unsigned int __attribute_const__ read_cpuid_part_number(void) |
| 72 | { | 93 | { |
| 73 | return (read_cpuid_id() & 0xFFF0); | 94 | return MIDR_PARTNUM(read_cpuid_id()); |
| 74 | } | 95 | } |
| 75 | 96 | ||
| 76 | static inline u32 __attribute_const__ read_cpuid_cachetype(void) | 97 | static inline u32 __attribute_const__ read_cpuid_cachetype(void) |
diff --git a/arch/arm64/include/asm/fpsimdmacros.h b/arch/arm64/include/asm/fpsimdmacros.h index 768414d55e64..007618b8188c 100644 --- a/arch/arm64/include/asm/fpsimdmacros.h +++ b/arch/arm64/include/asm/fpsimdmacros.h | |||
| @@ -40,6 +40,19 @@ | |||
| 40 | str w\tmpnr, [\state, #16 * 2 + 4] | 40 | str w\tmpnr, [\state, #16 * 2 + 4] |
| 41 | .endm | 41 | .endm |
| 42 | 42 | ||
| 43 | .macro fpsimd_restore_fpcr state, tmp | ||
| 44 | /* | ||
| 45 | * Writes to fpcr may be self-synchronising, so avoid restoring | ||
| 46 | * the register if it hasn't changed. | ||
| 47 | */ | ||
| 48 | mrs \tmp, fpcr | ||
| 49 | cmp \tmp, \state | ||
| 50 | b.eq 9999f | ||
| 51 | msr fpcr, \state | ||
| 52 | 9999: | ||
| 53 | .endm | ||
| 54 | |||
| 55 | /* Clobbers \state */ | ||
| 43 | .macro fpsimd_restore state, tmpnr | 56 | .macro fpsimd_restore state, tmpnr |
| 44 | ldp q0, q1, [\state, #16 * 0] | 57 | ldp q0, q1, [\state, #16 * 0] |
| 45 | ldp q2, q3, [\state, #16 * 2] | 58 | ldp q2, q3, [\state, #16 * 2] |
| @@ -60,7 +73,7 @@ | |||
| 60 | ldr w\tmpnr, [\state, #16 * 2] | 73 | ldr w\tmpnr, [\state, #16 * 2] |
| 61 | msr fpsr, x\tmpnr | 74 | msr fpsr, x\tmpnr |
| 62 | ldr w\tmpnr, [\state, #16 * 2 + 4] | 75 | ldr w\tmpnr, [\state, #16 * 2 + 4] |
| 63 | msr fpcr, x\tmpnr | 76 | fpsimd_restore_fpcr x\tmpnr, \state |
| 64 | .endm | 77 | .endm |
| 65 | 78 | ||
| 66 | .altmacro | 79 | .altmacro |
| @@ -84,7 +97,7 @@ | |||
| 84 | .macro fpsimd_restore_partial state, tmpnr1, tmpnr2 | 97 | .macro fpsimd_restore_partial state, tmpnr1, tmpnr2 |
| 85 | ldp w\tmpnr1, w\tmpnr2, [\state] | 98 | ldp w\tmpnr1, w\tmpnr2, [\state] |
| 86 | msr fpsr, x\tmpnr1 | 99 | msr fpsr, x\tmpnr1 |
| 87 | msr fpcr, x\tmpnr2 | 100 | fpsimd_restore_fpcr x\tmpnr2, x\tmpnr1 |
| 88 | adr x\tmpnr1, 0f | 101 | adr x\tmpnr1, 0f |
| 89 | ldr w\tmpnr2, [\state, #8] | 102 | ldr w\tmpnr2, [\state, #8] |
| 90 | add \state, \state, x\tmpnr2, lsl #4 | 103 | add \state, \state, x\tmpnr2, lsl #4 |
diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h index 902eb708804a..ccc7087d3c4e 100644 --- a/arch/arm64/include/asm/memory.h +++ b/arch/arm64/include/asm/memory.h | |||
| @@ -41,11 +41,7 @@ | |||
| 41 | * The module space lives between the addresses given by TASK_SIZE | 41 | * The module space lives between the addresses given by TASK_SIZE |
| 42 | * and PAGE_OFFSET - it must be within 128MB of the kernel text. | 42 | * and PAGE_OFFSET - it must be within 128MB of the kernel text. |
| 43 | */ | 43 | */ |
| 44 | #ifdef CONFIG_ARM64_64K_PAGES | 44 | #define VA_BITS (CONFIG_ARM64_VA_BITS) |
| 45 | #define VA_BITS (42) | ||
| 46 | #else | ||
| 47 | #define VA_BITS (39) | ||
| 48 | #endif | ||
| 49 | #define PAGE_OFFSET (UL(0xffffffffffffffff) << (VA_BITS - 1)) | 45 | #define PAGE_OFFSET (UL(0xffffffffffffffff) << (VA_BITS - 1)) |
| 50 | #define MODULES_END (PAGE_OFFSET) | 46 | #define MODULES_END (PAGE_OFFSET) |
| 51 | #define MODULES_VADDR (MODULES_END - SZ_64M) | 47 | #define MODULES_VADDR (MODULES_END - SZ_64M) |
diff --git a/arch/arm64/include/asm/page.h b/arch/arm64/include/asm/page.h index 46bf66628b6a..7a3f462133b0 100644 --- a/arch/arm64/include/asm/page.h +++ b/arch/arm64/include/asm/page.h | |||
| @@ -31,14 +31,26 @@ | |||
| 31 | /* We do define AT_SYSINFO_EHDR but don't use the gate mechanism */ | 31 | /* We do define AT_SYSINFO_EHDR but don't use the gate mechanism */ |
| 32 | #define __HAVE_ARCH_GATE_AREA 1 | 32 | #define __HAVE_ARCH_GATE_AREA 1 |
| 33 | 33 | ||
| 34 | #ifndef __ASSEMBLY__ | 34 | /* |
| 35 | 35 | * The idmap and swapper page tables need some space reserved in the kernel | |
| 36 | * image. Both require pgd, pud (4 levels only) and pmd tables to (section) | ||
| 37 | * map the kernel. With the 64K page configuration, swapper and idmap need to | ||
| 38 | * map to pte level. The swapper also maps the FDT (see __create_page_tables | ||
| 39 | * for more information). | ||
| 40 | */ | ||
| 36 | #ifdef CONFIG_ARM64_64K_PAGES | 41 | #ifdef CONFIG_ARM64_64K_PAGES |
| 37 | #include <asm/pgtable-2level-types.h> | 42 | #define SWAPPER_PGTABLE_LEVELS (CONFIG_ARM64_PGTABLE_LEVELS) |
| 38 | #else | 43 | #else |
| 39 | #include <asm/pgtable-3level-types.h> | 44 | #define SWAPPER_PGTABLE_LEVELS (CONFIG_ARM64_PGTABLE_LEVELS - 1) |
| 40 | #endif | 45 | #endif |
| 41 | 46 | ||
| 47 | #define SWAPPER_DIR_SIZE (SWAPPER_PGTABLE_LEVELS * PAGE_SIZE) | ||
| 48 | #define IDMAP_DIR_SIZE (SWAPPER_DIR_SIZE) | ||
| 49 | |||
| 50 | #ifndef __ASSEMBLY__ | ||
| 51 | |||
| 52 | #include <asm/pgtable-types.h> | ||
| 53 | |||
| 42 | extern void __cpu_clear_user_page(void *p, unsigned long user); | 54 | extern void __cpu_clear_user_page(void *p, unsigned long user); |
| 43 | extern void __cpu_copy_user_page(void *to, const void *from, | 55 | extern void __cpu_copy_user_page(void *to, const void *from, |
| 44 | unsigned long user); | 56 | unsigned long user); |
diff --git a/arch/arm64/include/asm/pgalloc.h b/arch/arm64/include/asm/pgalloc.h index 9bea6e74a001..d5bed02073d6 100644 --- a/arch/arm64/include/asm/pgalloc.h +++ b/arch/arm64/include/asm/pgalloc.h | |||
| @@ -26,7 +26,7 @@ | |||
| 26 | 26 | ||
| 27 | #define check_pgt_cache() do { } while (0) | 27 | #define check_pgt_cache() do { } while (0) |
| 28 | 28 | ||
| 29 | #ifndef CONFIG_ARM64_64K_PAGES | 29 | #if CONFIG_ARM64_PGTABLE_LEVELS > 2 |
| 30 | 30 | ||
| 31 | static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr) | 31 | static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr) |
| 32 | { | 32 | { |
| @@ -44,7 +44,27 @@ static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd) | |||
| 44 | set_pud(pud, __pud(__pa(pmd) | PMD_TYPE_TABLE)); | 44 | set_pud(pud, __pud(__pa(pmd) | PMD_TYPE_TABLE)); |
| 45 | } | 45 | } |
| 46 | 46 | ||
| 47 | #endif /* CONFIG_ARM64_64K_PAGES */ | 47 | #endif /* CONFIG_ARM64_PGTABLE_LEVELS > 2 */ |
| 48 | |||
| 49 | #if CONFIG_ARM64_PGTABLE_LEVELS > 3 | ||
| 50 | |||
| 51 | static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr) | ||
| 52 | { | ||
| 53 | return (pud_t *)get_zeroed_page(GFP_KERNEL | __GFP_REPEAT); | ||
| 54 | } | ||
| 55 | |||
| 56 | static inline void pud_free(struct mm_struct *mm, pud_t *pud) | ||
| 57 | { | ||
| 58 | BUG_ON((unsigned long)pud & (PAGE_SIZE-1)); | ||
| 59 | free_page((unsigned long)pud); | ||
| 60 | } | ||
| 61 | |||
| 62 | static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pud_t *pud) | ||
| 63 | { | ||
| 64 | set_pgd(pgd, __pgd(__pa(pud) | PUD_TYPE_TABLE)); | ||
| 65 | } | ||
| 66 | |||
| 67 | #endif /* CONFIG_ARM64_PGTABLE_LEVELS > 3 */ | ||
| 48 | 68 | ||
| 49 | extern pgd_t *pgd_alloc(struct mm_struct *mm); | 69 | extern pgd_t *pgd_alloc(struct mm_struct *mm); |
| 50 | extern void pgd_free(struct mm_struct *mm, pgd_t *pgd); | 70 | extern void pgd_free(struct mm_struct *mm, pgd_t *pgd); |
diff --git a/arch/arm64/include/asm/pgtable-2level-hwdef.h b/arch/arm64/include/asm/pgtable-2level-hwdef.h deleted file mode 100644 index 2593b490c56a..000000000000 --- a/arch/arm64/include/asm/pgtable-2level-hwdef.h +++ /dev/null | |||
| @@ -1,43 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2012 ARM Ltd. | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License version 2 as | ||
| 6 | * published by the Free Software Foundation. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License | ||
| 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 15 | */ | ||
| 16 | #ifndef __ASM_PGTABLE_2LEVEL_HWDEF_H | ||
| 17 | #define __ASM_PGTABLE_2LEVEL_HWDEF_H | ||
| 18 | |||
| 19 | /* | ||
| 20 | * With LPAE and 64KB pages, there are 2 levels of page tables. Each level has | ||
| 21 | * 8192 entries of 8 bytes each, occupying a 64KB page. Levels 0 and 1 are not | ||
| 22 | * used. The 2nd level table (PGD for Linux) can cover a range of 4TB, each | ||
| 23 | * entry representing 512MB. The user and kernel address spaces are limited to | ||
| 24 | * 4TB in the 64KB page configuration. | ||
| 25 | */ | ||
| 26 | #define PTRS_PER_PTE 8192 | ||
| 27 | #define PTRS_PER_PGD 8192 | ||
| 28 | |||
| 29 | /* | ||
| 30 | * PGDIR_SHIFT determines the size a top-level page table entry can map. | ||
| 31 | */ | ||
| 32 | #define PGDIR_SHIFT 29 | ||
| 33 | #define PGDIR_SIZE (_AC(1, UL) << PGDIR_SHIFT) | ||
| 34 | #define PGDIR_MASK (~(PGDIR_SIZE-1)) | ||
| 35 | |||
| 36 | /* | ||
| 37 | * section address mask and size definitions. | ||
| 38 | */ | ||
| 39 | #define SECTION_SHIFT 29 | ||
| 40 | #define SECTION_SIZE (_AC(1, UL) << SECTION_SHIFT) | ||
| 41 | #define SECTION_MASK (~(SECTION_SIZE-1)) | ||
| 42 | |||
| 43 | #endif | ||
diff --git a/arch/arm64/include/asm/pgtable-2level-types.h b/arch/arm64/include/asm/pgtable-2level-types.h deleted file mode 100644 index 5f101e63dfc1..000000000000 --- a/arch/arm64/include/asm/pgtable-2level-types.h +++ /dev/null | |||
| @@ -1,62 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2012 ARM Ltd. | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License version 2 as | ||
| 6 | * published by the Free Software Foundation. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License | ||
| 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 15 | */ | ||
| 16 | #ifndef __ASM_PGTABLE_2LEVEL_TYPES_H | ||
| 17 | #define __ASM_PGTABLE_2LEVEL_TYPES_H | ||
| 18 | |||
| 19 | #include <asm/types.h> | ||
| 20 | |||
| 21 | typedef u64 pteval_t; | ||
| 22 | typedef u64 pgdval_t; | ||
| 23 | typedef pgdval_t pmdval_t; | ||
| 24 | |||
| 25 | #undef STRICT_MM_TYPECHECKS | ||
| 26 | |||
| 27 | #ifdef STRICT_MM_TYPECHECKS | ||
| 28 | |||
| 29 | /* | ||
| 30 | * These are used to make use of C type-checking.. | ||
| 31 | */ | ||
| 32 | typedef struct { pteval_t pte; } pte_t; | ||
| 33 | typedef struct { pgdval_t pgd; } pgd_t; | ||
| 34 | typedef struct { pteval_t pgprot; } pgprot_t; | ||
| 35 | |||
| 36 | #define pte_val(x) ((x).pte) | ||
| 37 | #define pgd_val(x) ((x).pgd) | ||
| 38 | #define pgprot_val(x) ((x).pgprot) | ||
| 39 | |||
| 40 | #define __pte(x) ((pte_t) { (x) } ) | ||
| 41 | #define __pgd(x) ((pgd_t) { (x) } ) | ||
| 42 | #define __pgprot(x) ((pgprot_t) { (x) } ) | ||
| 43 | |||
| 44 | #else /* !STRICT_MM_TYPECHECKS */ | ||
| 45 | |||
| 46 | typedef pteval_t pte_t; | ||
| 47 | typedef pgdval_t pgd_t; | ||
| 48 | typedef pteval_t pgprot_t; | ||
| 49 | |||
| 50 | #define pte_val(x) (x) | ||
| 51 | #define pgd_val(x) (x) | ||
| 52 | #define pgprot_val(x) (x) | ||
| 53 | |||
| 54 | #define __pte(x) (x) | ||
| 55 | #define __pgd(x) (x) | ||
| 56 | #define __pgprot(x) (x) | ||
| 57 | |||
| 58 | #endif /* STRICT_MM_TYPECHECKS */ | ||
| 59 | |||
| 60 | #include <asm-generic/pgtable-nopmd.h> | ||
| 61 | |||
| 62 | #endif /* __ASM_PGTABLE_2LEVEL_TYPES_H */ | ||
diff --git a/arch/arm64/include/asm/pgtable-3level-hwdef.h b/arch/arm64/include/asm/pgtable-3level-hwdef.h deleted file mode 100644 index 3dbf941d7767..000000000000 --- a/arch/arm64/include/asm/pgtable-3level-hwdef.h +++ /dev/null | |||
| @@ -1,50 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2012 ARM Ltd. | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License version 2 as | ||
| 6 | * published by the Free Software Foundation. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License | ||
| 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 15 | */ | ||
| 16 | #ifndef __ASM_PGTABLE_3LEVEL_HWDEF_H | ||
| 17 | #define __ASM_PGTABLE_3LEVEL_HWDEF_H | ||
| 18 | |||
| 19 | /* | ||
| 20 | * With LPAE and 4KB pages, there are 3 levels of page tables. Each level has | ||
| 21 | * 512 entries of 8 bytes each, occupying a 4K page. The first level table | ||
| 22 | * covers a range of 512GB, each entry representing 1GB. The user and kernel | ||
| 23 | * address spaces are limited to 512GB each. | ||
| 24 | */ | ||
| 25 | #define PTRS_PER_PTE 512 | ||
| 26 | #define PTRS_PER_PMD 512 | ||
| 27 | #define PTRS_PER_PGD 512 | ||
| 28 | |||
| 29 | /* | ||
| 30 | * PGDIR_SHIFT determines the size a top-level page table entry can map. | ||
| 31 | */ | ||
| 32 | #define PGDIR_SHIFT 30 | ||
| 33 | #define PGDIR_SIZE (_AC(1, UL) << PGDIR_SHIFT) | ||
| 34 | #define PGDIR_MASK (~(PGDIR_SIZE-1)) | ||
| 35 | |||
| 36 | /* | ||
| 37 | * PMD_SHIFT determines the size a middle-level page table entry can map. | ||
| 38 | */ | ||
| 39 | #define PMD_SHIFT 21 | ||
| 40 | #define PMD_SIZE (_AC(1, UL) << PMD_SHIFT) | ||
| 41 | #define PMD_MASK (~(PMD_SIZE-1)) | ||
| 42 | |||
| 43 | /* | ||
| 44 | * section address mask and size definitions. | ||
| 45 | */ | ||
| 46 | #define SECTION_SHIFT 21 | ||
| 47 | #define SECTION_SIZE (_AC(1, UL) << SECTION_SHIFT) | ||
| 48 | #define SECTION_MASK (~(SECTION_SIZE-1)) | ||
| 49 | |||
| 50 | #endif | ||
diff --git a/arch/arm64/include/asm/pgtable-hwdef.h b/arch/arm64/include/asm/pgtable-hwdef.h index 955e8c5f0afb..88174e0bfafe 100644 --- a/arch/arm64/include/asm/pgtable-hwdef.h +++ b/arch/arm64/include/asm/pgtable-hwdef.h | |||
| @@ -16,18 +16,50 @@ | |||
| 16 | #ifndef __ASM_PGTABLE_HWDEF_H | 16 | #ifndef __ASM_PGTABLE_HWDEF_H |
| 17 | #define __ASM_PGTABLE_HWDEF_H | 17 | #define __ASM_PGTABLE_HWDEF_H |
| 18 | 18 | ||
| 19 | #ifdef CONFIG_ARM64_64K_PAGES | 19 | #define PTRS_PER_PTE (1 << (PAGE_SHIFT - 3)) |
| 20 | #include <asm/pgtable-2level-hwdef.h> | 20 | |
| 21 | #else | 21 | /* |
| 22 | #include <asm/pgtable-3level-hwdef.h> | 22 | * PMD_SHIFT determines the size a level 2 page table entry can map. |
| 23 | */ | ||
| 24 | #if CONFIG_ARM64_PGTABLE_LEVELS > 2 | ||
| 25 | #define PMD_SHIFT ((PAGE_SHIFT - 3) * 2 + 3) | ||
| 26 | #define PMD_SIZE (_AC(1, UL) << PMD_SHIFT) | ||
| 27 | #define PMD_MASK (~(PMD_SIZE-1)) | ||
| 28 | #define PTRS_PER_PMD PTRS_PER_PTE | ||
| 29 | #endif | ||
| 30 | |||
| 31 | /* | ||
| 32 | * PUD_SHIFT determines the size a level 1 page table entry can map. | ||
| 33 | */ | ||
| 34 | #if CONFIG_ARM64_PGTABLE_LEVELS > 3 | ||
| 35 | #define PUD_SHIFT ((PAGE_SHIFT - 3) * 3 + 3) | ||
| 36 | #define PUD_SIZE (_AC(1, UL) << PUD_SHIFT) | ||
| 37 | #define PUD_MASK (~(PUD_SIZE-1)) | ||
| 38 | #define PTRS_PER_PUD PTRS_PER_PTE | ||
| 23 | #endif | 39 | #endif |
| 24 | 40 | ||
| 25 | /* | 41 | /* |
| 42 | * PGDIR_SHIFT determines the size a top-level page table entry can map | ||
| 43 | * (depending on the configuration, this level can be 0, 1 or 2). | ||
| 44 | */ | ||
| 45 | #define PGDIR_SHIFT ((PAGE_SHIFT - 3) * CONFIG_ARM64_PGTABLE_LEVELS + 3) | ||
| 46 | #define PGDIR_SIZE (_AC(1, UL) << PGDIR_SHIFT) | ||
| 47 | #define PGDIR_MASK (~(PGDIR_SIZE-1)) | ||
| 48 | #define PTRS_PER_PGD (1 << (VA_BITS - PGDIR_SHIFT)) | ||
| 49 | |||
| 50 | /* | ||
| 51 | * Section address mask and size definitions. | ||
| 52 | */ | ||
| 53 | #define SECTION_SHIFT PMD_SHIFT | ||
| 54 | #define SECTION_SIZE (_AC(1, UL) << SECTION_SHIFT) | ||
| 55 | #define SECTION_MASK (~(SECTION_SIZE-1)) | ||
| 56 | |||
| 57 | /* | ||
| 26 | * Hardware page table definitions. | 58 | * Hardware page table definitions. |
| 27 | * | 59 | * |
| 28 | * Level 1 descriptor (PUD). | 60 | * Level 1 descriptor (PUD). |
| 29 | */ | 61 | */ |
| 30 | 62 | #define PUD_TYPE_TABLE (_AT(pudval_t, 3) << 0) | |
| 31 | #define PUD_TABLE_BIT (_AT(pgdval_t, 1) << 1) | 63 | #define PUD_TABLE_BIT (_AT(pgdval_t, 1) << 1) |
| 32 | #define PUD_TYPE_MASK (_AT(pgdval_t, 3) << 0) | 64 | #define PUD_TYPE_MASK (_AT(pgdval_t, 3) << 0) |
| 33 | #define PUD_TYPE_SECT (_AT(pgdval_t, 1) << 0) | 65 | #define PUD_TYPE_SECT (_AT(pgdval_t, 1) << 0) |
diff --git a/arch/arm64/include/asm/pgtable-3level-types.h b/arch/arm64/include/asm/pgtable-types.h index 4e94424938a4..ca9df80af896 100644 --- a/arch/arm64/include/asm/pgtable-3level-types.h +++ b/arch/arm64/include/asm/pgtable-types.h | |||
| @@ -1,7 +1,10 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright (C) 2012 ARM Ltd. | 2 | * Page table types definitions. |
| 3 | * | 3 | * |
| 4 | * This program is free software; you can redistribute it and/or modify | 4 | * Copyright (C) 2014 ARM Ltd. |
| 5 | * Author: Catalin Marinas <catalin.marinas@arm.com> | ||
| 6 | * | ||
| 7 | * This program is free software: you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License version 2 as | 8 | * it under the terms of the GNU General Public License version 2 as |
| 6 | * published by the Free Software Foundation. | 9 | * published by the Free Software Foundation. |
| 7 | * | 10 | * |
| @@ -13,13 +16,15 @@ | |||
| 13 | * You should have received a copy of the GNU General Public License | 16 | * You should have received a copy of the GNU General Public License |
| 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | 17 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 15 | */ | 18 | */ |
| 16 | #ifndef __ASM_PGTABLE_3LEVEL_TYPES_H | 19 | |
| 17 | #define __ASM_PGTABLE_3LEVEL_TYPES_H | 20 | #ifndef __ASM_PGTABLE_TYPES_H |
| 21 | #define __ASM_PGTABLE_TYPES_H | ||
| 18 | 22 | ||
| 19 | #include <asm/types.h> | 23 | #include <asm/types.h> |
| 20 | 24 | ||
| 21 | typedef u64 pteval_t; | 25 | typedef u64 pteval_t; |
| 22 | typedef u64 pmdval_t; | 26 | typedef u64 pmdval_t; |
| 27 | typedef u64 pudval_t; | ||
| 23 | typedef u64 pgdval_t; | 28 | typedef u64 pgdval_t; |
| 24 | 29 | ||
| 25 | #undef STRICT_MM_TYPECHECKS | 30 | #undef STRICT_MM_TYPECHECKS |
| @@ -30,39 +35,61 @@ typedef u64 pgdval_t; | |||
| 30 | * These are used to make use of C type-checking.. | 35 | * These are used to make use of C type-checking.. |
| 31 | */ | 36 | */ |
| 32 | typedef struct { pteval_t pte; } pte_t; | 37 | typedef struct { pteval_t pte; } pte_t; |
| 38 | #define pte_val(x) ((x).pte) | ||
| 39 | #define __pte(x) ((pte_t) { (x) } ) | ||
| 40 | |||
| 41 | #if CONFIG_ARM64_PGTABLE_LEVELS > 2 | ||
| 33 | typedef struct { pmdval_t pmd; } pmd_t; | 42 | typedef struct { pmdval_t pmd; } pmd_t; |
| 34 | typedef struct { pgdval_t pgd; } pgd_t; | 43 | #define pmd_val(x) ((x).pmd) |
| 35 | typedef struct { pteval_t pgprot; } pgprot_t; | 44 | #define __pmd(x) ((pmd_t) { (x) } ) |
| 45 | #endif | ||
| 36 | 46 | ||
| 37 | #define pte_val(x) ((x).pte) | 47 | #if CONFIG_ARM64_PGTABLE_LEVELS > 3 |
| 38 | #define pmd_val(x) ((x).pmd) | 48 | typedef struct { pudval_t pud; } pud_t; |
| 39 | #define pgd_val(x) ((x).pgd) | 49 | #define pud_val(x) ((x).pud) |
| 40 | #define pgprot_val(x) ((x).pgprot) | 50 | #define __pud(x) ((pud_t) { (x) } ) |
| 51 | #endif | ||
| 41 | 52 | ||
| 42 | #define __pte(x) ((pte_t) { (x) } ) | 53 | typedef struct { pgdval_t pgd; } pgd_t; |
| 43 | #define __pmd(x) ((pmd_t) { (x) } ) | 54 | #define pgd_val(x) ((x).pgd) |
| 44 | #define __pgd(x) ((pgd_t) { (x) } ) | 55 | #define __pgd(x) ((pgd_t) { (x) } ) |
| 45 | #define __pgprot(x) ((pgprot_t) { (x) } ) | 56 | |
| 57 | typedef struct { pteval_t pgprot; } pgprot_t; | ||
| 58 | #define pgprot_val(x) ((x).pgprot) | ||
| 59 | #define __pgprot(x) ((pgprot_t) { (x) } ) | ||
| 46 | 60 | ||
| 47 | #else /* !STRICT_MM_TYPECHECKS */ | 61 | #else /* !STRICT_MM_TYPECHECKS */ |
| 48 | 62 | ||
| 49 | typedef pteval_t pte_t; | 63 | typedef pteval_t pte_t; |
| 50 | typedef pmdval_t pmd_t; | ||
| 51 | typedef pgdval_t pgd_t; | ||
| 52 | typedef pteval_t pgprot_t; | ||
| 53 | |||
| 54 | #define pte_val(x) (x) | 64 | #define pte_val(x) (x) |
| 55 | #define pmd_val(x) (x) | ||
| 56 | #define pgd_val(x) (x) | ||
| 57 | #define pgprot_val(x) (x) | ||
| 58 | |||
| 59 | #define __pte(x) (x) | 65 | #define __pte(x) (x) |
| 66 | |||
| 67 | #if CONFIG_ARM64_PGTABLE_LEVELS > 2 | ||
| 68 | typedef pmdval_t pmd_t; | ||
| 69 | #define pmd_val(x) (x) | ||
| 60 | #define __pmd(x) (x) | 70 | #define __pmd(x) (x) |
| 71 | #endif | ||
| 72 | |||
| 73 | #if CONFIG_ARM64_PGTABLE_LEVELS > 3 | ||
| 74 | typedef pudval_t pud_t; | ||
| 75 | #define pud_val(x) (x) | ||
| 76 | #define __pud(x) (x) | ||
| 77 | #endif | ||
| 78 | |||
| 79 | typedef pgdval_t pgd_t; | ||
| 80 | #define pgd_val(x) (x) | ||
| 61 | #define __pgd(x) (x) | 81 | #define __pgd(x) (x) |
| 82 | |||
| 83 | typedef pteval_t pgprot_t; | ||
| 84 | #define pgprot_val(x) (x) | ||
| 62 | #define __pgprot(x) (x) | 85 | #define __pgprot(x) (x) |
| 63 | 86 | ||
| 64 | #endif /* STRICT_MM_TYPECHECKS */ | 87 | #endif /* STRICT_MM_TYPECHECKS */ |
| 65 | 88 | ||
| 89 | #if CONFIG_ARM64_PGTABLE_LEVELS == 2 | ||
| 90 | #include <asm-generic/pgtable-nopmd.h> | ||
| 91 | #elif CONFIG_ARM64_PGTABLE_LEVELS == 3 | ||
| 66 | #include <asm-generic/pgtable-nopud.h> | 92 | #include <asm-generic/pgtable-nopud.h> |
| 93 | #endif | ||
| 67 | 94 | ||
| 68 | #endif /* __ASM_PGTABLE_3LEVEL_TYPES_H */ | 95 | #endif /* __ASM_PGTABLE_TYPES_H */ |
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h index e0ccceb317d9..ffe1ba0506d1 100644 --- a/arch/arm64/include/asm/pgtable.h +++ b/arch/arm64/include/asm/pgtable.h | |||
| @@ -33,9 +33,16 @@ | |||
| 33 | 33 | ||
| 34 | /* | 34 | /* |
| 35 | * VMALLOC and SPARSEMEM_VMEMMAP ranges. | 35 | * VMALLOC and SPARSEMEM_VMEMMAP ranges. |
| 36 | * | ||
| 37 | * VMEMAP_SIZE: allows the whole VA space to be covered by a struct page array | ||
| 38 | * (rounded up to PUD_SIZE). | ||
| 39 | * VMALLOC_START: beginning of the kernel VA space | ||
| 40 | * VMALLOC_END: extends to the available space below vmmemmap, PCI I/O space, | ||
| 41 | * fixed mappings and modules | ||
| 36 | */ | 42 | */ |
| 43 | #define VMEMMAP_SIZE ALIGN((1UL << (VA_BITS - PAGE_SHIFT)) * sizeof(struct page), PUD_SIZE) | ||
| 37 | #define VMALLOC_START (UL(0xffffffffffffffff) << VA_BITS) | 44 | #define VMALLOC_START (UL(0xffffffffffffffff) << VA_BITS) |
| 38 | #define VMALLOC_END (PAGE_OFFSET - UL(0x400000000) - SZ_64K) | 45 | #define VMALLOC_END (PAGE_OFFSET - PUD_SIZE - VMEMMAP_SIZE - SZ_64K) |
| 39 | 46 | ||
| 40 | #define vmemmap ((struct page *)(VMALLOC_END + SZ_64K)) | 47 | #define vmemmap ((struct page *)(VMALLOC_END + SZ_64K)) |
| 41 | 48 | ||
| @@ -44,14 +51,9 @@ | |||
| 44 | #ifndef __ASSEMBLY__ | 51 | #ifndef __ASSEMBLY__ |
| 45 | extern void __pte_error(const char *file, int line, unsigned long val); | 52 | extern void __pte_error(const char *file, int line, unsigned long val); |
| 46 | extern void __pmd_error(const char *file, int line, unsigned long val); | 53 | extern void __pmd_error(const char *file, int line, unsigned long val); |
| 54 | extern void __pud_error(const char *file, int line, unsigned long val); | ||
| 47 | extern void __pgd_error(const char *file, int line, unsigned long val); | 55 | extern void __pgd_error(const char *file, int line, unsigned long val); |
| 48 | 56 | ||
| 49 | #define pte_ERROR(pte) __pte_error(__FILE__, __LINE__, pte_val(pte)) | ||
| 50 | #ifndef CONFIG_ARM64_64K_PAGES | ||
| 51 | #define pmd_ERROR(pmd) __pmd_error(__FILE__, __LINE__, pmd_val(pmd)) | ||
| 52 | #endif | ||
| 53 | #define pgd_ERROR(pgd) __pgd_error(__FILE__, __LINE__, pgd_val(pgd)) | ||
| 54 | |||
| 55 | #ifdef CONFIG_SMP | 57 | #ifdef CONFIG_SMP |
| 56 | #define PROT_DEFAULT (PTE_TYPE_PAGE | PTE_AF | PTE_SHARED) | 58 | #define PROT_DEFAULT (PTE_TYPE_PAGE | PTE_AF | PTE_SHARED) |
| 57 | #define PROT_SECT_DEFAULT (PMD_TYPE_SECT | PMD_SECT_AF | PMD_SECT_S) | 59 | #define PROT_SECT_DEFAULT (PMD_TYPE_SECT | PMD_SECT_AF | PMD_SECT_S) |
| @@ -112,6 +114,8 @@ extern void __pgd_error(const char *file, int line, unsigned long val); | |||
| 112 | extern struct page *empty_zero_page; | 114 | extern struct page *empty_zero_page; |
| 113 | #define ZERO_PAGE(vaddr) (empty_zero_page) | 115 | #define ZERO_PAGE(vaddr) (empty_zero_page) |
| 114 | 116 | ||
| 117 | #define pte_ERROR(pte) __pte_error(__FILE__, __LINE__, pte_val(pte)) | ||
| 118 | |||
| 115 | #define pte_pfn(pte) ((pte_val(pte) & PHYS_MASK) >> PAGE_SHIFT) | 119 | #define pte_pfn(pte) ((pte_val(pte) & PHYS_MASK) >> PAGE_SHIFT) |
| 116 | 120 | ||
| 117 | #define pfn_pte(pfn,prot) (__pte(((phys_addr_t)(pfn) << PAGE_SHIFT) | pgprot_val(prot))) | 121 | #define pfn_pte(pfn,prot) (__pte(((phys_addr_t)(pfn) << PAGE_SHIFT) | pgprot_val(prot))) |
| @@ -119,6 +123,10 @@ extern struct page *empty_zero_page; | |||
| 119 | #define pte_none(pte) (!pte_val(pte)) | 123 | #define pte_none(pte) (!pte_val(pte)) |
| 120 | #define pte_clear(mm,addr,ptep) set_pte(ptep, __pte(0)) | 124 | #define pte_clear(mm,addr,ptep) set_pte(ptep, __pte(0)) |
| 121 | #define pte_page(pte) (pfn_to_page(pte_pfn(pte))) | 125 | #define pte_page(pte) (pfn_to_page(pte_pfn(pte))) |
| 126 | |||
| 127 | /* Find an entry in the third-level page table. */ | ||
| 128 | #define pte_index(addr) (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)) | ||
| 129 | |||
| 122 | #define pte_offset_kernel(dir,addr) (pmd_page_vaddr(*(dir)) + pte_index(addr)) | 130 | #define pte_offset_kernel(dir,addr) (pmd_page_vaddr(*(dir)) + pte_index(addr)) |
| 123 | 131 | ||
| 124 | #define pte_offset_map(dir,addr) pte_offset_kernel((dir), (addr)) | 132 | #define pte_offset_map(dir,addr) pte_offset_kernel((dir), (addr)) |
| @@ -138,6 +146,8 @@ extern struct page *empty_zero_page; | |||
| 138 | 146 | ||
| 139 | #define pte_valid_user(pte) \ | 147 | #define pte_valid_user(pte) \ |
| 140 | ((pte_val(pte) & (PTE_VALID | PTE_USER)) == (PTE_VALID | PTE_USER)) | 148 | ((pte_val(pte) & (PTE_VALID | PTE_USER)) == (PTE_VALID | PTE_USER)) |
| 149 | #define pte_valid_not_user(pte) \ | ||
| 150 | ((pte_val(pte) & (PTE_VALID | PTE_USER)) == PTE_VALID) | ||
| 141 | 151 | ||
| 142 | static inline pte_t pte_wrprotect(pte_t pte) | 152 | static inline pte_t pte_wrprotect(pte_t pte) |
| 143 | { | 153 | { |
| @@ -184,6 +194,15 @@ static inline pte_t pte_mkspecial(pte_t pte) | |||
| 184 | static inline void set_pte(pte_t *ptep, pte_t pte) | 194 | static inline void set_pte(pte_t *ptep, pte_t pte) |
| 185 | { | 195 | { |
| 186 | *ptep = pte; | 196 | *ptep = pte; |
| 197 | |||
| 198 | /* | ||
| 199 | * Only if the new pte is valid and kernel, otherwise TLB maintenance | ||
| 200 | * or update_mmu_cache() have the necessary barriers. | ||
| 201 | */ | ||
| 202 | if (pte_valid_not_user(pte)) { | ||
| 203 | dsb(ishst); | ||
| 204 | isb(); | ||
| 205 | } | ||
| 187 | } | 206 | } |
| 188 | 207 | ||
| 189 | extern void __sync_icache_dcache(pte_t pteval, unsigned long addr); | 208 | extern void __sync_icache_dcache(pte_t pteval, unsigned long addr); |
| @@ -303,6 +322,7 @@ static inline void set_pmd(pmd_t *pmdp, pmd_t pmd) | |||
| 303 | { | 322 | { |
| 304 | *pmdp = pmd; | 323 | *pmdp = pmd; |
| 305 | dsb(ishst); | 324 | dsb(ishst); |
| 325 | isb(); | ||
| 306 | } | 326 | } |
| 307 | 327 | ||
| 308 | static inline void pmd_clear(pmd_t *pmdp) | 328 | static inline void pmd_clear(pmd_t *pmdp) |
| @@ -323,7 +343,9 @@ static inline pte_t *pmd_page_vaddr(pmd_t pmd) | |||
| 323 | */ | 343 | */ |
| 324 | #define mk_pte(page,prot) pfn_pte(page_to_pfn(page),prot) | 344 | #define mk_pte(page,prot) pfn_pte(page_to_pfn(page),prot) |
| 325 | 345 | ||
| 326 | #ifndef CONFIG_ARM64_64K_PAGES | 346 | #if CONFIG_ARM64_PGTABLE_LEVELS > 2 |
| 347 | |||
| 348 | #define pmd_ERROR(pmd) __pmd_error(__FILE__, __LINE__, pmd_val(pmd)) | ||
| 327 | 349 | ||
| 328 | #define pud_none(pud) (!pud_val(pud)) | 350 | #define pud_none(pud) (!pud_val(pud)) |
| 329 | #define pud_bad(pud) (!(pud_val(pud) & 2)) | 351 | #define pud_bad(pud) (!(pud_val(pud) & 2)) |
| @@ -333,6 +355,7 @@ static inline void set_pud(pud_t *pudp, pud_t pud) | |||
| 333 | { | 355 | { |
| 334 | *pudp = pud; | 356 | *pudp = pud; |
| 335 | dsb(ishst); | 357 | dsb(ishst); |
| 358 | isb(); | ||
| 336 | } | 359 | } |
| 337 | 360 | ||
| 338 | static inline void pud_clear(pud_t *pudp) | 361 | static inline void pud_clear(pud_t *pudp) |
| @@ -345,7 +368,51 @@ static inline pmd_t *pud_page_vaddr(pud_t pud) | |||
| 345 | return __va(pud_val(pud) & PHYS_MASK & (s32)PAGE_MASK); | 368 | return __va(pud_val(pud) & PHYS_MASK & (s32)PAGE_MASK); |
| 346 | } | 369 | } |
| 347 | 370 | ||
| 348 | #endif /* CONFIG_ARM64_64K_PAGES */ | 371 | /* Find an entry in the second-level page table. */ |
| 372 | #define pmd_index(addr) (((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1)) | ||
| 373 | |||
| 374 | static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr) | ||
| 375 | { | ||
| 376 | return (pmd_t *)pud_page_vaddr(*pud) + pmd_index(addr); | ||
| 377 | } | ||
| 378 | |||
| 379 | #endif /* CONFIG_ARM64_PGTABLE_LEVELS > 2 */ | ||
| 380 | |||
| 381 | #if CONFIG_ARM64_PGTABLE_LEVELS > 3 | ||
| 382 | |||
| 383 | #define pud_ERROR(pud) __pud_error(__FILE__, __LINE__, pud_val(pud)) | ||
| 384 | |||
| 385 | #define pgd_none(pgd) (!pgd_val(pgd)) | ||
| 386 | #define pgd_bad(pgd) (!(pgd_val(pgd) & 2)) | ||
| 387 | #define pgd_present(pgd) (pgd_val(pgd)) | ||
| 388 | |||
| 389 | static inline void set_pgd(pgd_t *pgdp, pgd_t pgd) | ||
| 390 | { | ||
| 391 | *pgdp = pgd; | ||
| 392 | dsb(ishst); | ||
| 393 | } | ||
| 394 | |||
| 395 | static inline void pgd_clear(pgd_t *pgdp) | ||
| 396 | { | ||
| 397 | set_pgd(pgdp, __pgd(0)); | ||
| 398 | } | ||
| 399 | |||
| 400 | static inline pud_t *pgd_page_vaddr(pgd_t pgd) | ||
| 401 | { | ||
| 402 | return __va(pgd_val(pgd) & PHYS_MASK & (s32)PAGE_MASK); | ||
| 403 | } | ||
| 404 | |||
| 405 | /* Find an entry in the frst-level page table. */ | ||
| 406 | #define pud_index(addr) (((addr) >> PUD_SHIFT) & (PTRS_PER_PUD - 1)) | ||
| 407 | |||
| 408 | static inline pud_t *pud_offset(pgd_t *pgd, unsigned long addr) | ||
| 409 | { | ||
| 410 | return (pud_t *)pgd_page_vaddr(*pgd) + pud_index(addr); | ||
| 411 | } | ||
| 412 | |||
| 413 | #endif /* CONFIG_ARM64_PGTABLE_LEVELS > 3 */ | ||
| 414 | |||
| 415 | #define pgd_ERROR(pgd) __pgd_error(__FILE__, __LINE__, pgd_val(pgd)) | ||
| 349 | 416 | ||
| 350 | /* to find an entry in a page-table-directory */ | 417 | /* to find an entry in a page-table-directory */ |
| 351 | #define pgd_index(addr) (((addr) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1)) | 418 | #define pgd_index(addr) (((addr) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1)) |
| @@ -355,18 +422,6 @@ static inline pmd_t *pud_page_vaddr(pud_t pud) | |||
| 355 | /* to find an entry in a kernel page-table-directory */ | 422 | /* to find an entry in a kernel page-table-directory */ |
| 356 | #define pgd_offset_k(addr) pgd_offset(&init_mm, addr) | 423 | #define pgd_offset_k(addr) pgd_offset(&init_mm, addr) |
| 357 | 424 | ||
| 358 | /* Find an entry in the second-level page table.. */ | ||
| 359 | #ifndef CONFIG_ARM64_64K_PAGES | ||
| 360 | #define pmd_index(addr) (((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1)) | ||
| 361 | static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr) | ||
| 362 | { | ||
| 363 | return (pmd_t *)pud_page_vaddr(*pud) + pmd_index(addr); | ||
| 364 | } | ||
| 365 | #endif | ||
| 366 | |||
| 367 | /* Find an entry in the third-level page table.. */ | ||
| 368 | #define pte_index(addr) (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)) | ||
| 369 | |||
| 370 | static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) | 425 | static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) |
| 371 | { | 426 | { |
| 372 | const pteval_t mask = PTE_USER | PTE_PXN | PTE_UXN | PTE_RDONLY | | 427 | const pteval_t mask = PTE_USER | PTE_PXN | PTE_UXN | PTE_RDONLY | |
| @@ -383,9 +438,6 @@ static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot) | |||
| 383 | extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; | 438 | extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; |
| 384 | extern pgd_t idmap_pg_dir[PTRS_PER_PGD]; | 439 | extern pgd_t idmap_pg_dir[PTRS_PER_PGD]; |
| 385 | 440 | ||
| 386 | #define SWAPPER_DIR_SIZE (3 * PAGE_SIZE) | ||
| 387 | #define IDMAP_DIR_SIZE (2 * PAGE_SIZE) | ||
| 388 | |||
| 389 | /* | 441 | /* |
| 390 | * Encode and decode a swap entry: | 442 | * Encode and decode a swap entry: |
| 391 | * bits 0-1: present (must be zero) | 443 | * bits 0-1: present (must be zero) |
diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h index 34de2a8f7d93..77712454486b 100644 --- a/arch/arm64/include/asm/processor.h +++ b/arch/arm64/include/asm/processor.h | |||
| @@ -137,8 +137,8 @@ extern struct task_struct *cpu_switch_to(struct task_struct *prev, | |||
| 137 | #define task_pt_regs(p) \ | 137 | #define task_pt_regs(p) \ |
| 138 | ((struct pt_regs *)(THREAD_START_SP + task_stack_page(p)) - 1) | 138 | ((struct pt_regs *)(THREAD_START_SP + task_stack_page(p)) - 1) |
| 139 | 139 | ||
| 140 | #define KSTK_EIP(tsk) task_pt_regs(tsk)->pc | 140 | #define KSTK_EIP(tsk) ((unsigned long)task_pt_regs(tsk)->pc) |
| 141 | #define KSTK_ESP(tsk) task_pt_regs(tsk)->sp | 141 | #define KSTK_ESP(tsk) ((unsigned long)task_pt_regs(tsk)->sp) |
| 142 | 142 | ||
| 143 | /* | 143 | /* |
| 144 | * Prefetching support | 144 | * Prefetching support |
diff --git a/arch/arm64/include/asm/stackprotector.h b/arch/arm64/include/asm/stackprotector.h new file mode 100644 index 000000000000..fe5e287dc56b --- /dev/null +++ b/arch/arm64/include/asm/stackprotector.h | |||
| @@ -0,0 +1,38 @@ | |||
| 1 | /* | ||
| 2 | * GCC stack protector support. | ||
| 3 | * | ||
| 4 | * Stack protector works by putting predefined pattern at the start of | ||
| 5 | * the stack frame and verifying that it hasn't been overwritten when | ||
| 6 | * returning from the function. The pattern is called stack canary | ||
| 7 | * and gcc expects it to be defined by a global variable called | ||
| 8 | * "__stack_chk_guard" on ARM. This unfortunately means that on SMP | ||
| 9 | * we cannot have a different canary value per task. | ||
| 10 | */ | ||
| 11 | |||
| 12 | #ifndef __ASM_STACKPROTECTOR_H | ||
| 13 | #define __ASM_STACKPROTECTOR_H | ||
| 14 | |||
| 15 | #include <linux/random.h> | ||
| 16 | #include <linux/version.h> | ||
| 17 | |||
| 18 | extern unsigned long __stack_chk_guard; | ||
| 19 | |||
| 20 | /* | ||
| 21 | * Initialize the stackprotector canary value. | ||
| 22 | * | ||
| 23 | * NOTE: this must only be called from functions that never return, | ||
| 24 | * and it must always be inlined. | ||
| 25 | */ | ||
| 26 | static __always_inline void boot_init_stack_canary(void) | ||
| 27 | { | ||
| 28 | unsigned long canary; | ||
| 29 | |||
| 30 | /* Try to get a semi random initial value. */ | ||
| 31 | get_random_bytes(&canary, sizeof(canary)); | ||
| 32 | canary ^= LINUX_VERSION_CODE; | ||
| 33 | |||
| 34 | current->stack_canary = canary; | ||
| 35 | __stack_chk_guard = current->stack_canary; | ||
| 36 | } | ||
| 37 | |||
| 38 | #endif /* _ASM_STACKPROTECTOR_H */ | ||
diff --git a/arch/arm64/include/asm/syscall.h b/arch/arm64/include/asm/syscall.h index 383771eb0b87..709a574468f0 100644 --- a/arch/arm64/include/asm/syscall.h +++ b/arch/arm64/include/asm/syscall.h | |||
| @@ -16,6 +16,8 @@ | |||
| 16 | #ifndef __ASM_SYSCALL_H | 16 | #ifndef __ASM_SYSCALL_H |
| 17 | #define __ASM_SYSCALL_H | 17 | #define __ASM_SYSCALL_H |
| 18 | 18 | ||
| 19 | #include <uapi/linux/audit.h> | ||
| 20 | #include <linux/compat.h> | ||
| 19 | #include <linux/err.h> | 21 | #include <linux/err.h> |
| 20 | 22 | ||
| 21 | extern const void *sys_call_table[]; | 23 | extern const void *sys_call_table[]; |
| @@ -105,4 +107,16 @@ static inline void syscall_set_arguments(struct task_struct *task, | |||
| 105 | memcpy(®s->regs[i], args, n * sizeof(args[0])); | 107 | memcpy(®s->regs[i], args, n * sizeof(args[0])); |
| 106 | } | 108 | } |
| 107 | 109 | ||
| 110 | /* | ||
| 111 | * We don't care about endianness (__AUDIT_ARCH_LE bit) here because | ||
| 112 | * AArch64 has the same system calls both on little- and big- endian. | ||
| 113 | */ | ||
| 114 | static inline int syscall_get_arch(void) | ||
| 115 | { | ||
| 116 | if (is_compat_task()) | ||
| 117 | return AUDIT_ARCH_ARM; | ||
| 118 | |||
| 119 | return AUDIT_ARCH_AARCH64; | ||
| 120 | } | ||
| 121 | |||
| 108 | #endif /* __ASM_SYSCALL_H */ | 122 | #endif /* __ASM_SYSCALL_H */ |
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h new file mode 100644 index 000000000000..5c89df0acbcb --- /dev/null +++ b/arch/arm64/include/asm/sysreg.h | |||
| @@ -0,0 +1,60 @@ | |||
| 1 | /* | ||
| 2 | * Macros for accessing system registers with older binutils. | ||
| 3 | * | ||
| 4 | * Copyright (C) 2014 ARM Ltd. | ||
| 5 | * Author: Catalin Marinas <catalin.marinas@arm.com> | ||
| 6 | * | ||
| 7 | * This program is free software: you can redistribute it and/or modify | ||
| 8 | * it under the terms of the GNU General Public License version 2 as | ||
| 9 | * published by the Free Software Foundation. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * GNU General Public License for more details. | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License | ||
| 17 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 18 | */ | ||
| 19 | |||
| 20 | #ifndef __ASM_SYSREG_H | ||
| 21 | #define __ASM_SYSREG_H | ||
| 22 | |||
| 23 | #define sys_reg(op0, op1, crn, crm, op2) \ | ||
| 24 | ((((op0)-2)<<19)|((op1)<<16)|((crn)<<12)|((crm)<<8)|((op2)<<5)) | ||
| 25 | |||
| 26 | #ifdef __ASSEMBLY__ | ||
| 27 | |||
| 28 | .irp num,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30 | ||
| 29 | .equ __reg_num_x\num, \num | ||
| 30 | .endr | ||
| 31 | .equ __reg_num_xzr, 31 | ||
| 32 | |||
| 33 | .macro mrs_s, rt, sreg | ||
| 34 | .inst 0xd5300000|(\sreg)|(__reg_num_\rt) | ||
| 35 | .endm | ||
| 36 | |||
| 37 | .macro msr_s, sreg, rt | ||
| 38 | .inst 0xd5100000|(\sreg)|(__reg_num_\rt) | ||
| 39 | .endm | ||
| 40 | |||
| 41 | #else | ||
| 42 | |||
| 43 | asm( | ||
| 44 | " .irp num,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30\n" | ||
| 45 | " .equ __reg_num_x\\num, \\num\n" | ||
| 46 | " .endr\n" | ||
| 47 | " .equ __reg_num_xzr, 31\n" | ||
| 48 | "\n" | ||
| 49 | " .macro mrs_s, rt, sreg\n" | ||
| 50 | " .inst 0xd5300000|(\\sreg)|(__reg_num_\\rt)\n" | ||
| 51 | " .endm\n" | ||
| 52 | "\n" | ||
| 53 | " .macro msr_s, sreg, rt\n" | ||
| 54 | " .inst 0xd5100000|(\\sreg)|(__reg_num_\\rt)\n" | ||
| 55 | " .endm\n" | ||
| 56 | ); | ||
| 57 | |||
| 58 | #endif | ||
| 59 | |||
| 60 | #endif /* __ASM_SYSREG_H */ | ||
diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h index e40b6d06d515..45108d802f5e 100644 --- a/arch/arm64/include/asm/thread_info.h +++ b/arch/arm64/include/asm/thread_info.h | |||
| @@ -103,6 +103,7 @@ static inline struct thread_info *current_thread_info(void) | |||
| 103 | #define TIF_NEED_RESCHED 1 | 103 | #define TIF_NEED_RESCHED 1 |
| 104 | #define TIF_NOTIFY_RESUME 2 /* callback before returning to user */ | 104 | #define TIF_NOTIFY_RESUME 2 /* callback before returning to user */ |
| 105 | #define TIF_FOREIGN_FPSTATE 3 /* CPU's FP state is not current's */ | 105 | #define TIF_FOREIGN_FPSTATE 3 /* CPU's FP state is not current's */ |
| 106 | #define TIF_NOHZ 7 | ||
| 106 | #define TIF_SYSCALL_TRACE 8 | 107 | #define TIF_SYSCALL_TRACE 8 |
| 107 | #define TIF_SYSCALL_AUDIT 9 | 108 | #define TIF_SYSCALL_AUDIT 9 |
| 108 | #define TIF_SYSCALL_TRACEPOINT 10 | 109 | #define TIF_SYSCALL_TRACEPOINT 10 |
| @@ -118,6 +119,7 @@ static inline struct thread_info *current_thread_info(void) | |||
| 118 | #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) | 119 | #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) |
| 119 | #define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) | 120 | #define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) |
| 120 | #define _TIF_FOREIGN_FPSTATE (1 << TIF_FOREIGN_FPSTATE) | 121 | #define _TIF_FOREIGN_FPSTATE (1 << TIF_FOREIGN_FPSTATE) |
| 122 | #define _TIF_NOHZ (1 << TIF_NOHZ) | ||
| 121 | #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) | 123 | #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) |
| 122 | #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) | 124 | #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) |
| 123 | #define _TIF_SYSCALL_TRACEPOINT (1 << TIF_SYSCALL_TRACEPOINT) | 125 | #define _TIF_SYSCALL_TRACEPOINT (1 << TIF_SYSCALL_TRACEPOINT) |
| @@ -128,7 +130,8 @@ static inline struct thread_info *current_thread_info(void) | |||
| 128 | _TIF_NOTIFY_RESUME | _TIF_FOREIGN_FPSTATE) | 130 | _TIF_NOTIFY_RESUME | _TIF_FOREIGN_FPSTATE) |
| 129 | 131 | ||
| 130 | #define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \ | 132 | #define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \ |
| 131 | _TIF_SYSCALL_TRACEPOINT | _TIF_SECCOMP) | 133 | _TIF_SYSCALL_TRACEPOINT | _TIF_SECCOMP | \ |
| 134 | _TIF_NOHZ) | ||
| 132 | 135 | ||
| 133 | #endif /* __KERNEL__ */ | 136 | #endif /* __KERNEL__ */ |
| 134 | #endif /* __ASM_THREAD_INFO_H */ | 137 | #endif /* __ASM_THREAD_INFO_H */ |
diff --git a/arch/arm64/include/asm/tlb.h b/arch/arm64/include/asm/tlb.h index 80e2c08900d6..62731ef9749a 100644 --- a/arch/arm64/include/asm/tlb.h +++ b/arch/arm64/include/asm/tlb.h | |||
| @@ -91,7 +91,7 @@ static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte, | |||
| 91 | tlb_remove_page(tlb, pte); | 91 | tlb_remove_page(tlb, pte); |
| 92 | } | 92 | } |
| 93 | 93 | ||
| 94 | #ifndef CONFIG_ARM64_64K_PAGES | 94 | #if CONFIG_ARM64_PGTABLE_LEVELS > 2 |
| 95 | static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmdp, | 95 | static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmdp, |
| 96 | unsigned long addr) | 96 | unsigned long addr) |
| 97 | { | 97 | { |
| @@ -100,6 +100,15 @@ static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmdp, | |||
| 100 | } | 100 | } |
| 101 | #endif | 101 | #endif |
| 102 | 102 | ||
| 103 | #if CONFIG_ARM64_PGTABLE_LEVELS > 3 | ||
| 104 | static inline void __pud_free_tlb(struct mmu_gather *tlb, pud_t *pudp, | ||
| 105 | unsigned long addr) | ||
| 106 | { | ||
| 107 | tlb_add_flush(tlb, addr); | ||
| 108 | tlb_remove_page(tlb, virt_to_page(pudp)); | ||
| 109 | } | ||
| 110 | #endif | ||
| 111 | |||
| 103 | static inline void __tlb_remove_pmd_tlb_entry(struct mmu_gather *tlb, pmd_t *pmdp, | 112 | static inline void __tlb_remove_pmd_tlb_entry(struct mmu_gather *tlb, pmd_t *pmdp, |
| 104 | unsigned long address) | 113 | unsigned long address) |
| 105 | { | 114 | { |
diff --git a/arch/arm64/include/asm/tlbflush.h b/arch/arm64/include/asm/tlbflush.h index b9349c4513ea..73f0ce570fb3 100644 --- a/arch/arm64/include/asm/tlbflush.h +++ b/arch/arm64/include/asm/tlbflush.h | |||
| @@ -98,8 +98,8 @@ static inline void flush_tlb_page(struct vm_area_struct *vma, | |||
| 98 | dsb(ish); | 98 | dsb(ish); |
| 99 | } | 99 | } |
| 100 | 100 | ||
| 101 | static inline void flush_tlb_range(struct vm_area_struct *vma, | 101 | static inline void __flush_tlb_range(struct vm_area_struct *vma, |
| 102 | unsigned long start, unsigned long end) | 102 | unsigned long start, unsigned long end) |
| 103 | { | 103 | { |
| 104 | unsigned long asid = (unsigned long)ASID(vma->vm_mm) << 48; | 104 | unsigned long asid = (unsigned long)ASID(vma->vm_mm) << 48; |
| 105 | unsigned long addr; | 105 | unsigned long addr; |
| @@ -112,7 +112,7 @@ static inline void flush_tlb_range(struct vm_area_struct *vma, | |||
| 112 | dsb(ish); | 112 | dsb(ish); |
| 113 | } | 113 | } |
| 114 | 114 | ||
| 115 | static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end) | 115 | static inline void __flush_tlb_kernel_range(unsigned long start, unsigned long end) |
| 116 | { | 116 | { |
| 117 | unsigned long addr; | 117 | unsigned long addr; |
| 118 | start >>= 12; | 118 | start >>= 12; |
| @@ -122,6 +122,30 @@ static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end | |||
| 122 | for (addr = start; addr < end; addr += 1 << (PAGE_SHIFT - 12)) | 122 | for (addr = start; addr < end; addr += 1 << (PAGE_SHIFT - 12)) |
| 123 | asm("tlbi vaae1is, %0" : : "r"(addr)); | 123 | asm("tlbi vaae1is, %0" : : "r"(addr)); |
| 124 | dsb(ish); | 124 | dsb(ish); |
| 125 | isb(); | ||
| 126 | } | ||
| 127 | |||
| 128 | /* | ||
| 129 | * This is meant to avoid soft lock-ups on large TLB flushing ranges and not | ||
| 130 | * necessarily a performance improvement. | ||
| 131 | */ | ||
| 132 | #define MAX_TLB_RANGE (1024UL << PAGE_SHIFT) | ||
| 133 | |||
| 134 | static inline void flush_tlb_range(struct vm_area_struct *vma, | ||
| 135 | unsigned long start, unsigned long end) | ||
| 136 | { | ||
| 137 | if ((end - start) <= MAX_TLB_RANGE) | ||
| 138 | __flush_tlb_range(vma, start, end); | ||
| 139 | else | ||
| 140 | flush_tlb_mm(vma->vm_mm); | ||
| 141 | } | ||
| 142 | |||
| 143 | static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end) | ||
| 144 | { | ||
| 145 | if ((end - start) <= MAX_TLB_RANGE) | ||
| 146 | __flush_tlb_kernel_range(start, end); | ||
| 147 | else | ||
| 148 | flush_tlb_all(); | ||
| 125 | } | 149 | } |
| 126 | 150 | ||
| 127 | /* | 151 | /* |
| @@ -131,8 +155,8 @@ static inline void update_mmu_cache(struct vm_area_struct *vma, | |||
| 131 | unsigned long addr, pte_t *ptep) | 155 | unsigned long addr, pte_t *ptep) |
| 132 | { | 156 | { |
| 133 | /* | 157 | /* |
| 134 | * set_pte() does not have a DSB, so make sure that the page table | 158 | * set_pte() does not have a DSB for user mappings, so make sure that |
| 135 | * write is visible. | 159 | * the page table write is visible. |
| 136 | */ | 160 | */ |
| 137 | dsb(ishst); | 161 | dsb(ishst); |
| 138 | } | 162 | } |
diff --git a/arch/arm64/include/asm/unistd.h b/arch/arm64/include/asm/unistd.h index e5f47df00c24..4bc95d27e063 100644 --- a/arch/arm64/include/asm/unistd.h +++ b/arch/arm64/include/asm/unistd.h | |||
| @@ -26,7 +26,24 @@ | |||
| 26 | #define __ARCH_WANT_COMPAT_SYS_SENDFILE | 26 | #define __ARCH_WANT_COMPAT_SYS_SENDFILE |
| 27 | #define __ARCH_WANT_SYS_FORK | 27 | #define __ARCH_WANT_SYS_FORK |
| 28 | #define __ARCH_WANT_SYS_VFORK | 28 | #define __ARCH_WANT_SYS_VFORK |
| 29 | |||
| 30 | /* | ||
| 31 | * Compat syscall numbers used by the AArch64 kernel. | ||
| 32 | */ | ||
| 33 | #define __NR_compat_restart_syscall 0 | ||
| 34 | #define __NR_compat_sigreturn 119 | ||
| 35 | #define __NR_compat_rt_sigreturn 173 | ||
| 36 | |||
| 37 | /* | ||
| 38 | * The following SVCs are ARM private. | ||
| 39 | */ | ||
| 40 | #define __ARM_NR_COMPAT_BASE 0x0f0000 | ||
| 41 | #define __ARM_NR_compat_cacheflush (__ARM_NR_COMPAT_BASE+2) | ||
| 42 | #define __ARM_NR_compat_set_tls (__ARM_NR_COMPAT_BASE+5) | ||
| 43 | |||
| 44 | #define __NR_compat_syscalls 383 | ||
| 29 | #endif | 45 | #endif |
| 46 | |||
| 30 | #define __ARCH_WANT_SYS_CLONE | 47 | #define __ARCH_WANT_SYS_CLONE |
| 31 | #include <uapi/asm/unistd.h> | 48 | #include <uapi/asm/unistd.h> |
| 32 | 49 | ||
diff --git a/arch/arm64/include/asm/unistd32.h b/arch/arm64/include/asm/unistd32.h index c8d8fc17bd5a..e242600c4046 100644 --- a/arch/arm64/include/asm/unistd32.h +++ b/arch/arm64/include/asm/unistd32.h | |||
| @@ -21,403 +21,769 @@ | |||
| 21 | #define __SYSCALL(x, y) | 21 | #define __SYSCALL(x, y) |
| 22 | #endif | 22 | #endif |
| 23 | 23 | ||
| 24 | __SYSCALL(0, sys_restart_syscall) | 24 | #define __NR_restart_syscall 0 |
| 25 | __SYSCALL(1, sys_exit) | 25 | __SYSCALL(__NR_restart_syscall, sys_restart_syscall) |
| 26 | __SYSCALL(2, sys_fork) | 26 | #define __NR_exit 1 |
| 27 | __SYSCALL(3, sys_read) | 27 | __SYSCALL(__NR_exit, sys_exit) |
| 28 | __SYSCALL(4, sys_write) | 28 | #define __NR_fork 2 |
| 29 | __SYSCALL(5, compat_sys_open) | 29 | __SYSCALL(__NR_fork, sys_fork) |
| 30 | __SYSCALL(6, sys_close) | 30 | #define __NR_read 3 |
| 31 | __SYSCALL(7, sys_ni_syscall) /* 7 was sys_waitpid */ | 31 | __SYSCALL(__NR_read, sys_read) |
| 32 | __SYSCALL(8, sys_creat) | 32 | #define __NR_write 4 |
| 33 | __SYSCALL(9, sys_link) | 33 | __SYSCALL(__NR_write, sys_write) |
| 34 | __SYSCALL(10, sys_unlink) | 34 | #define __NR_open 5 |
| 35 | __SYSCALL(11, compat_sys_execve) | 35 | __SYSCALL(__NR_open, compat_sys_open) |
| 36 | __SYSCALL(12, sys_chdir) | 36 | #define __NR_close 6 |
| 37 | __SYSCALL(13, sys_ni_syscall) /* 13 was sys_time */ | 37 | __SYSCALL(__NR_close, sys_close) |
| 38 | __SYSCALL(14, sys_mknod) | 38 | /* 7 was sys_waitpid */ |
| 39 | __SYSCALL(15, sys_chmod) | 39 | __SYSCALL(7, sys_ni_syscall) |
| 40 | __SYSCALL(16, sys_lchown16) | 40 | #define __NR_creat 8 |
| 41 | __SYSCALL(17, sys_ni_syscall) /* 17 was sys_break */ | 41 | __SYSCALL(__NR_creat, sys_creat) |
| 42 | __SYSCALL(18, sys_ni_syscall) /* 18 was sys_stat */ | 42 | #define __NR_link 9 |
| 43 | __SYSCALL(19, compat_sys_lseek) | 43 | __SYSCALL(__NR_link, sys_link) |
| 44 | __SYSCALL(20, sys_getpid) | 44 | #define __NR_unlink 10 |
| 45 | __SYSCALL(21, compat_sys_mount) | 45 | __SYSCALL(__NR_unlink, sys_unlink) |
| 46 | __SYSCALL(22, sys_ni_syscall) /* 22 was sys_umount */ | 46 | #define __NR_execve 11 |
| 47 | __SYSCALL(23, sys_setuid16) | 47 | __SYSCALL(__NR_execve, compat_sys_execve) |
| 48 | __SYSCALL(24, sys_getuid16) | 48 | #define __NR_chdir 12 |
| 49 | __SYSCALL(25, sys_ni_syscall) /* 25 was sys_stime */ | 49 | __SYSCALL(__NR_chdir, sys_chdir) |
| 50 | __SYSCALL(26, compat_sys_ptrace) | 50 | /* 13 was sys_time */ |
| 51 | __SYSCALL(27, sys_ni_syscall) /* 27 was sys_alarm */ | 51 | __SYSCALL(13, sys_ni_syscall) |
| 52 | __SYSCALL(28, sys_ni_syscall) /* 28 was sys_fstat */ | 52 | #define __NR_mknod 14 |
| 53 | __SYSCALL(29, sys_pause) | 53 | __SYSCALL(__NR_mknod, sys_mknod) |
| 54 | __SYSCALL(30, sys_ni_syscall) /* 30 was sys_utime */ | 54 | #define __NR_chmod 15 |
| 55 | __SYSCALL(31, sys_ni_syscall) /* 31 was sys_stty */ | 55 | __SYSCALL(__NR_chmod, sys_chmod) |
| 56 | __SYSCALL(32, sys_ni_syscall) /* 32 was sys_gtty */ | 56 | #define __NR_lchown 16 |
| 57 | __SYSCALL(33, sys_access) | 57 | __SYSCALL(__NR_lchown, sys_lchown16) |
| 58 | __SYSCALL(34, sys_nice) | 58 | /* 17 was sys_break */ |
| 59 | __SYSCALL(35, sys_ni_syscall) /* 35 was sys_ftime */ | 59 | __SYSCALL(17, sys_ni_syscall) |
| 60 | __SYSCALL(36, sys_sync) | 60 | /* 18 was sys_stat */ |
| 61 | __SYSCALL(37, sys_kill) | 61 | __SYSCALL(18, sys_ni_syscall) |
| 62 | __SYSCALL(38, sys_rename) | 62 | #define __NR_lseek 19 |
| 63 | __SYSCALL(39, sys_mkdir) | 63 | __SYSCALL(__NR_lseek, compat_sys_lseek) |
| 64 | __SYSCALL(40, sys_rmdir) | 64 | #define __NR_getpid 20 |
| 65 | __SYSCALL(41, sys_dup) | 65 | __SYSCALL(__NR_getpid, sys_getpid) |
| 66 | __SYSCALL(42, sys_pipe) | 66 | #define __NR_mount 21 |
| 67 | __SYSCALL(43, compat_sys_times) | 67 | __SYSCALL(__NR_mount, compat_sys_mount) |
| 68 | __SYSCALL(44, sys_ni_syscall) /* 44 was sys_prof */ | 68 | /* 22 was sys_umount */ |
| 69 | __SYSCALL(45, sys_brk) | 69 | __SYSCALL(22, sys_ni_syscall) |
| 70 | __SYSCALL(46, sys_setgid16) | 70 | #define __NR_setuid 23 |
| 71 | __SYSCALL(47, sys_getgid16) | 71 | __SYSCALL(__NR_setuid, sys_setuid16) |
| 72 | __SYSCALL(48, sys_ni_syscall) /* 48 was sys_signal */ | 72 | #define __NR_getuid 24 |
| 73 | __SYSCALL(49, sys_geteuid16) | 73 | __SYSCALL(__NR_getuid, sys_getuid16) |
| 74 | __SYSCALL(50, sys_getegid16) | 74 | /* 25 was sys_stime */ |
| 75 | __SYSCALL(51, sys_acct) | 75 | __SYSCALL(25, sys_ni_syscall) |
| 76 | __SYSCALL(52, sys_umount) | 76 | #define __NR_ptrace 26 |
| 77 | __SYSCALL(53, sys_ni_syscall) /* 53 was sys_lock */ | 77 | __SYSCALL(__NR_ptrace, compat_sys_ptrace) |
| 78 | __SYSCALL(54, compat_sys_ioctl) | 78 | /* 27 was sys_alarm */ |
| 79 | __SYSCALL(55, compat_sys_fcntl) | 79 | __SYSCALL(27, sys_ni_syscall) |
| 80 | __SYSCALL(56, sys_ni_syscall) /* 56 was sys_mpx */ | 80 | /* 28 was sys_fstat */ |
| 81 | __SYSCALL(57, sys_setpgid) | 81 | __SYSCALL(28, sys_ni_syscall) |
| 82 | __SYSCALL(58, sys_ni_syscall) /* 58 was sys_ulimit */ | 82 | #define __NR_pause 29 |
| 83 | __SYSCALL(59, sys_ni_syscall) /* 59 was sys_olduname */ | 83 | __SYSCALL(__NR_pause, sys_pause) |
| 84 | __SYSCALL(60, sys_umask) | 84 | /* 30 was sys_utime */ |
| 85 | __SYSCALL(61, sys_chroot) | 85 | __SYSCALL(30, sys_ni_syscall) |
| 86 | __SYSCALL(62, compat_sys_ustat) | 86 | /* 31 was sys_stty */ |
| 87 | __SYSCALL(63, sys_dup2) | 87 | __SYSCALL(31, sys_ni_syscall) |
| 88 | __SYSCALL(64, sys_getppid) | 88 | /* 32 was sys_gtty */ |
| 89 | __SYSCALL(65, sys_getpgrp) | 89 | __SYSCALL(32, sys_ni_syscall) |
| 90 | __SYSCALL(66, sys_setsid) | 90 | #define __NR_access 33 |
| 91 | __SYSCALL(67, compat_sys_sigaction) | 91 | __SYSCALL(__NR_access, sys_access) |
| 92 | __SYSCALL(68, sys_ni_syscall) /* 68 was sys_sgetmask */ | 92 | #define __NR_nice 34 |
| 93 | __SYSCALL(69, sys_ni_syscall) /* 69 was sys_ssetmask */ | 93 | __SYSCALL(__NR_nice, sys_nice) |
| 94 | __SYSCALL(70, sys_setreuid16) | 94 | /* 35 was sys_ftime */ |
| 95 | __SYSCALL(71, sys_setregid16) | 95 | __SYSCALL(35, sys_ni_syscall) |
| 96 | __SYSCALL(72, sys_sigsuspend) | 96 | #define __NR_sync 36 |
| 97 | __SYSCALL(73, compat_sys_sigpending) | 97 | __SYSCALL(__NR_sync, sys_sync) |
| 98 | __SYSCALL(74, sys_sethostname) | 98 | #define __NR_kill 37 |
| 99 | __SYSCALL(75, compat_sys_setrlimit) | 99 | __SYSCALL(__NR_kill, sys_kill) |
| 100 | __SYSCALL(76, sys_ni_syscall) /* 76 was compat_sys_getrlimit */ | 100 | #define __NR_rename 38 |
| 101 | __SYSCALL(77, compat_sys_getrusage) | 101 | __SYSCALL(__NR_rename, sys_rename) |
| 102 | __SYSCALL(78, compat_sys_gettimeofday) | 102 | #define __NR_mkdir 39 |
| 103 | __SYSCALL(79, compat_sys_settimeofday) | 103 | __SYSCALL(__NR_mkdir, sys_mkdir) |
| 104 | __SYSCALL(80, sys_getgroups16) | 104 | #define __NR_rmdir 40 |
| 105 | __SYSCALL(81, sys_setgroups16) | 105 | __SYSCALL(__NR_rmdir, sys_rmdir) |
| 106 | __SYSCALL(82, sys_ni_syscall) /* 82 was compat_sys_select */ | 106 | #define __NR_dup 41 |
| 107 | __SYSCALL(83, sys_symlink) | 107 | __SYSCALL(__NR_dup, sys_dup) |
| 108 | __SYSCALL(84, sys_ni_syscall) /* 84 was sys_lstat */ | 108 | #define __NR_pipe 42 |
| 109 | __SYSCALL(85, sys_readlink) | 109 | __SYSCALL(__NR_pipe, sys_pipe) |
| 110 | __SYSCALL(86, sys_uselib) | 110 | #define __NR_times 43 |
| 111 | __SYSCALL(87, sys_swapon) | 111 | __SYSCALL(__NR_times, compat_sys_times) |
| 112 | __SYSCALL(88, sys_reboot) | 112 | /* 44 was sys_prof */ |
| 113 | __SYSCALL(89, sys_ni_syscall) /* 89 was sys_readdir */ | 113 | __SYSCALL(44, sys_ni_syscall) |
| 114 | __SYSCALL(90, sys_ni_syscall) /* 90 was sys_mmap */ | 114 | #define __NR_brk 45 |
| 115 | __SYSCALL(91, sys_munmap) | 115 | __SYSCALL(__NR_brk, sys_brk) |
| 116 | __SYSCALL(92, compat_sys_truncate) | 116 | #define __NR_setgid 46 |
| 117 | __SYSCALL(93, compat_sys_ftruncate) | 117 | __SYSCALL(__NR_setgid, sys_setgid16) |
| 118 | __SYSCALL(94, sys_fchmod) | 118 | #define __NR_getgid 47 |
| 119 | __SYSCALL(95, sys_fchown16) | 119 | __SYSCALL(__NR_getgid, sys_getgid16) |
| 120 | __SYSCALL(96, sys_getpriority) | 120 | /* 48 was sys_signal */ |
| 121 | __SYSCALL(97, sys_setpriority) | 121 | __SYSCALL(48, sys_ni_syscall) |
| 122 | __SYSCALL(98, sys_ni_syscall) /* 98 was sys_profil */ | 122 | #define __NR_geteuid 49 |
| 123 | __SYSCALL(99, compat_sys_statfs) | 123 | __SYSCALL(__NR_geteuid, sys_geteuid16) |
| 124 | __SYSCALL(100, compat_sys_fstatfs) | 124 | #define __NR_getegid 50 |
| 125 | __SYSCALL(101, sys_ni_syscall) /* 101 was sys_ioperm */ | 125 | __SYSCALL(__NR_getegid, sys_getegid16) |
| 126 | __SYSCALL(102, sys_ni_syscall) /* 102 was sys_socketcall */ | 126 | #define __NR_acct 51 |
| 127 | __SYSCALL(103, sys_syslog) | 127 | __SYSCALL(__NR_acct, sys_acct) |
| 128 | __SYSCALL(104, compat_sys_setitimer) | 128 | #define __NR_umount2 52 |
| 129 | __SYSCALL(105, compat_sys_getitimer) | 129 | __SYSCALL(__NR_umount2, sys_umount) |
| 130 | __SYSCALL(106, compat_sys_newstat) | 130 | /* 53 was sys_lock */ |
| 131 | __SYSCALL(107, compat_sys_newlstat) | 131 | __SYSCALL(53, sys_ni_syscall) |
| 132 | __SYSCALL(108, compat_sys_newfstat) | 132 | #define __NR_ioctl 54 |
| 133 | __SYSCALL(109, sys_ni_syscall) /* 109 was sys_uname */ | 133 | __SYSCALL(__NR_ioctl, compat_sys_ioctl) |
| 134 | __SYSCALL(110, sys_ni_syscall) /* 110 was sys_iopl */ | 134 | #define __NR_fcntl 55 |
| 135 | __SYSCALL(111, sys_vhangup) | 135 | __SYSCALL(__NR_fcntl, compat_sys_fcntl) |
| 136 | __SYSCALL(112, sys_ni_syscall) /* 112 was sys_idle */ | 136 | /* 56 was sys_mpx */ |
| 137 | __SYSCALL(113, sys_ni_syscall) /* 113 was sys_syscall */ | 137 | __SYSCALL(56, sys_ni_syscall) |
| 138 | __SYSCALL(114, compat_sys_wait4) | 138 | #define __NR_setpgid 57 |
| 139 | __SYSCALL(115, sys_swapoff) | 139 | __SYSCALL(__NR_setpgid, sys_setpgid) |
| 140 | __SYSCALL(116, compat_sys_sysinfo) | 140 | /* 58 was sys_ulimit */ |
| 141 | __SYSCALL(117, sys_ni_syscall) /* 117 was sys_ipc */ | 141 | __SYSCALL(58, sys_ni_syscall) |
| 142 | __SYSCALL(118, sys_fsync) | 142 | /* 59 was sys_olduname */ |
| 143 | __SYSCALL(119, compat_sys_sigreturn_wrapper) | 143 | __SYSCALL(59, sys_ni_syscall) |
| 144 | __SYSCALL(120, sys_clone) | 144 | #define __NR_umask 60 |
| 145 | __SYSCALL(121, sys_setdomainname) | 145 | __SYSCALL(__NR_umask, sys_umask) |
| 146 | __SYSCALL(122, sys_newuname) | 146 | #define __NR_chroot 61 |
| 147 | __SYSCALL(123, sys_ni_syscall) /* 123 was sys_modify_ldt */ | 147 | __SYSCALL(__NR_chroot, sys_chroot) |
| 148 | __SYSCALL(124, compat_sys_adjtimex) | 148 | #define __NR_ustat 62 |
| 149 | __SYSCALL(125, sys_mprotect) | 149 | __SYSCALL(__NR_ustat, compat_sys_ustat) |
| 150 | __SYSCALL(126, compat_sys_sigprocmask) | 150 | #define __NR_dup2 63 |
| 151 | __SYSCALL(127, sys_ni_syscall) /* 127 was sys_create_module */ | 151 | __SYSCALL(__NR_dup2, sys_dup2) |
| 152 | __SYSCALL(128, sys_init_module) | 152 | #define __NR_getppid 64 |
| 153 | __SYSCALL(129, sys_delete_module) | 153 | __SYSCALL(__NR_getppid, sys_getppid) |
| 154 | __SYSCALL(130, sys_ni_syscall) /* 130 was sys_get_kernel_syms */ | 154 | #define __NR_getpgrp 65 |
| 155 | __SYSCALL(131, sys_quotactl) | 155 | __SYSCALL(__NR_getpgrp, sys_getpgrp) |
| 156 | __SYSCALL(132, sys_getpgid) | 156 | #define __NR_setsid 66 |
| 157 | __SYSCALL(133, sys_fchdir) | 157 | __SYSCALL(__NR_setsid, sys_setsid) |
| 158 | __SYSCALL(134, sys_bdflush) | 158 | #define __NR_sigaction 67 |
| 159 | __SYSCALL(135, sys_sysfs) | 159 | __SYSCALL(__NR_sigaction, compat_sys_sigaction) |
| 160 | __SYSCALL(136, sys_personality) | 160 | /* 68 was sys_sgetmask */ |
| 161 | __SYSCALL(137, sys_ni_syscall) /* 137 was sys_afs_syscall */ | 161 | __SYSCALL(68, sys_ni_syscall) |
| 162 | __SYSCALL(138, sys_setfsuid16) | 162 | /* 69 was sys_ssetmask */ |
| 163 | __SYSCALL(139, sys_setfsgid16) | 163 | __SYSCALL(69, sys_ni_syscall) |
| 164 | __SYSCALL(140, sys_llseek) | 164 | #define __NR_setreuid 70 |
| 165 | __SYSCALL(141, compat_sys_getdents) | 165 | __SYSCALL(__NR_setreuid, sys_setreuid16) |
| 166 | __SYSCALL(142, compat_sys_select) | 166 | #define __NR_setregid 71 |
| 167 | __SYSCALL(143, sys_flock) | 167 | __SYSCALL(__NR_setregid, sys_setregid16) |
| 168 | __SYSCALL(144, sys_msync) | 168 | #define __NR_sigsuspend 72 |
| 169 | __SYSCALL(145, compat_sys_readv) | 169 | __SYSCALL(__NR_sigsuspend, sys_sigsuspend) |
| 170 | __SYSCALL(146, compat_sys_writev) | 170 | #define __NR_sigpending 73 |
| 171 | __SYSCALL(147, sys_getsid) | 171 | __SYSCALL(__NR_sigpending, compat_sys_sigpending) |
| 172 | __SYSCALL(148, sys_fdatasync) | 172 | #define __NR_sethostname 74 |
| 173 | __SYSCALL(149, compat_sys_sysctl) | 173 | __SYSCALL(__NR_sethostname, sys_sethostname) |
| 174 | __SYSCALL(150, sys_mlock) | 174 | #define __NR_setrlimit 75 |
| 175 | __SYSCALL(151, sys_munlock) | 175 | __SYSCALL(__NR_setrlimit, compat_sys_setrlimit) |
| 176 | __SYSCALL(152, sys_mlockall) | 176 | /* 76 was compat_sys_getrlimit */ |
| 177 | __SYSCALL(153, sys_munlockall) | 177 | __SYSCALL(76, sys_ni_syscall) |
| 178 | __SYSCALL(154, sys_sched_setparam) | 178 | #define __NR_getrusage 77 |
| 179 | __SYSCALL(155, sys_sched_getparam) | 179 | __SYSCALL(__NR_getrusage, compat_sys_getrusage) |
| 180 | __SYSCALL(156, sys_sched_setscheduler) | 180 | #define __NR_gettimeofday 78 |
| 181 | __SYSCALL(157, sys_sched_getscheduler) | 181 | __SYSCALL(__NR_gettimeofday, compat_sys_gettimeofday) |
| 182 | __SYSCALL(158, sys_sched_yield) | 182 | #define __NR_settimeofday 79 |
| 183 | __SYSCALL(159, sys_sched_get_priority_max) | 183 | __SYSCALL(__NR_settimeofday, compat_sys_settimeofday) |
| 184 | __SYSCALL(160, sys_sched_get_priority_min) | 184 | #define __NR_getgroups 80 |
| 185 | __SYSCALL(161, compat_sys_sched_rr_get_interval) | 185 | __SYSCALL(__NR_getgroups, sys_getgroups16) |
| 186 | __SYSCALL(162, compat_sys_nanosleep) | 186 | #define __NR_setgroups 81 |
| 187 | __SYSCALL(163, sys_mremap) | 187 | __SYSCALL(__NR_setgroups, sys_setgroups16) |
| 188 | __SYSCALL(164, sys_setresuid16) | 188 | /* 82 was compat_sys_select */ |
| 189 | __SYSCALL(165, sys_getresuid16) | 189 | __SYSCALL(82, sys_ni_syscall) |
| 190 | __SYSCALL(166, sys_ni_syscall) /* 166 was sys_vm86 */ | 190 | #define __NR_symlink 83 |
| 191 | __SYSCALL(167, sys_ni_syscall) /* 167 was sys_query_module */ | 191 | __SYSCALL(__NR_symlink, sys_symlink) |
| 192 | __SYSCALL(168, sys_poll) | 192 | /* 84 was sys_lstat */ |
| 193 | __SYSCALL(169, sys_ni_syscall) | 193 | __SYSCALL(84, sys_ni_syscall) |
| 194 | __SYSCALL(170, sys_setresgid16) | 194 | #define __NR_readlink 85 |
| 195 | __SYSCALL(171, sys_getresgid16) | 195 | __SYSCALL(__NR_readlink, sys_readlink) |
| 196 | __SYSCALL(172, sys_prctl) | 196 | #define __NR_uselib 86 |
| 197 | __SYSCALL(173, compat_sys_rt_sigreturn_wrapper) | 197 | __SYSCALL(__NR_uselib, sys_uselib) |
| 198 | __SYSCALL(174, compat_sys_rt_sigaction) | 198 | #define __NR_swapon 87 |
| 199 | __SYSCALL(175, compat_sys_rt_sigprocmask) | 199 | __SYSCALL(__NR_swapon, sys_swapon) |
| 200 | __SYSCALL(176, compat_sys_rt_sigpending) | 200 | #define __NR_reboot 88 |
| 201 | __SYSCALL(177, compat_sys_rt_sigtimedwait) | 201 | __SYSCALL(__NR_reboot, sys_reboot) |
| 202 | __SYSCALL(178, compat_sys_rt_sigqueueinfo) | 202 | /* 89 was sys_readdir */ |
| 203 | __SYSCALL(179, compat_sys_rt_sigsuspend) | 203 | __SYSCALL(89, sys_ni_syscall) |
| 204 | __SYSCALL(180, compat_sys_pread64_wrapper) | 204 | /* 90 was sys_mmap */ |
| 205 | __SYSCALL(181, compat_sys_pwrite64_wrapper) | 205 | __SYSCALL(90, sys_ni_syscall) |
| 206 | __SYSCALL(182, sys_chown16) | 206 | #define __NR_munmap 91 |
| 207 | __SYSCALL(183, sys_getcwd) | 207 | __SYSCALL(__NR_munmap, sys_munmap) |
| 208 | __SYSCALL(184, sys_capget) | 208 | #define __NR_truncate 92 |
| 209 | __SYSCALL(185, sys_capset) | 209 | __SYSCALL(__NR_truncate, compat_sys_truncate) |
| 210 | __SYSCALL(186, compat_sys_sigaltstack) | 210 | #define __NR_ftruncate 93 |
| 211 | __SYSCALL(187, compat_sys_sendfile) | 211 | __SYSCALL(__NR_ftruncate, compat_sys_ftruncate) |
| 212 | __SYSCALL(188, sys_ni_syscall) /* 188 reserved */ | 212 | #define __NR_fchmod 94 |
| 213 | __SYSCALL(189, sys_ni_syscall) /* 189 reserved */ | 213 | __SYSCALL(__NR_fchmod, sys_fchmod) |
| 214 | __SYSCALL(190, sys_vfork) | 214 | #define __NR_fchown 95 |
| 215 | __SYSCALL(191, compat_sys_getrlimit) /* SuS compliant getrlimit */ | 215 | __SYSCALL(__NR_fchown, sys_fchown16) |
| 216 | __SYSCALL(192, sys_mmap_pgoff) | 216 | #define __NR_getpriority 96 |
| 217 | __SYSCALL(193, compat_sys_truncate64_wrapper) | 217 | __SYSCALL(__NR_getpriority, sys_getpriority) |
| 218 | __SYSCALL(194, compat_sys_ftruncate64_wrapper) | 218 | #define __NR_setpriority 97 |
| 219 | __SYSCALL(195, sys_stat64) | 219 | __SYSCALL(__NR_setpriority, sys_setpriority) |
| 220 | __SYSCALL(196, sys_lstat64) | 220 | /* 98 was sys_profil */ |
| 221 | __SYSCALL(197, sys_fstat64) | 221 | __SYSCALL(98, sys_ni_syscall) |
| 222 | __SYSCALL(198, sys_lchown) | 222 | #define __NR_statfs 99 |
| 223 | __SYSCALL(199, sys_getuid) | 223 | __SYSCALL(__NR_statfs, compat_sys_statfs) |
| 224 | __SYSCALL(200, sys_getgid) | 224 | #define __NR_fstatfs 100 |
| 225 | __SYSCALL(201, sys_geteuid) | 225 | __SYSCALL(__NR_fstatfs, compat_sys_fstatfs) |
| 226 | __SYSCALL(202, sys_getegid) | 226 | /* 101 was sys_ioperm */ |
| 227 | __SYSCALL(203, sys_setreuid) | 227 | __SYSCALL(101, sys_ni_syscall) |
| 228 | __SYSCALL(204, sys_setregid) | 228 | /* 102 was sys_socketcall */ |
| 229 | __SYSCALL(205, sys_getgroups) | 229 | __SYSCALL(102, sys_ni_syscall) |
| 230 | __SYSCALL(206, sys_setgroups) | 230 | #define __NR_syslog 103 |
| 231 | __SYSCALL(207, sys_fchown) | 231 | __SYSCALL(__NR_syslog, sys_syslog) |
| 232 | __SYSCALL(208, sys_setresuid) | 232 | #define __NR_setitimer 104 |
| 233 | __SYSCALL(209, sys_getresuid) | 233 | __SYSCALL(__NR_setitimer, compat_sys_setitimer) |
| 234 | __SYSCALL(210, sys_setresgid) | 234 | #define __NR_getitimer 105 |
| 235 | __SYSCALL(211, sys_getresgid) | 235 | __SYSCALL(__NR_getitimer, compat_sys_getitimer) |
| 236 | __SYSCALL(212, sys_chown) | 236 | #define __NR_stat 106 |
| 237 | __SYSCALL(213, sys_setuid) | 237 | __SYSCALL(__NR_stat, compat_sys_newstat) |
| 238 | __SYSCALL(214, sys_setgid) | 238 | #define __NR_lstat 107 |
| 239 | __SYSCALL(215, sys_setfsuid) | 239 | __SYSCALL(__NR_lstat, compat_sys_newlstat) |
| 240 | __SYSCALL(216, sys_setfsgid) | 240 | #define __NR_fstat 108 |
| 241 | __SYSCALL(217, compat_sys_getdents64) | 241 | __SYSCALL(__NR_fstat, compat_sys_newfstat) |
| 242 | __SYSCALL(218, sys_pivot_root) | 242 | /* 109 was sys_uname */ |
| 243 | __SYSCALL(219, sys_mincore) | 243 | __SYSCALL(109, sys_ni_syscall) |
| 244 | __SYSCALL(220, sys_madvise) | 244 | /* 110 was sys_iopl */ |
| 245 | __SYSCALL(221, compat_sys_fcntl64) | 245 | __SYSCALL(110, sys_ni_syscall) |
| 246 | __SYSCALL(222, sys_ni_syscall) /* 222 for tux */ | 246 | #define __NR_vhangup 111 |
| 247 | __SYSCALL(223, sys_ni_syscall) /* 223 is unused */ | 247 | __SYSCALL(__NR_vhangup, sys_vhangup) |
| 248 | __SYSCALL(224, sys_gettid) | 248 | /* 112 was sys_idle */ |
| 249 | __SYSCALL(225, compat_sys_readahead_wrapper) | 249 | __SYSCALL(112, sys_ni_syscall) |
| 250 | __SYSCALL(226, sys_setxattr) | 250 | /* 113 was sys_syscall */ |
| 251 | __SYSCALL(227, sys_lsetxattr) | 251 | __SYSCALL(113, sys_ni_syscall) |
| 252 | __SYSCALL(228, sys_fsetxattr) | 252 | #define __NR_wait4 114 |
| 253 | __SYSCALL(229, sys_getxattr) | 253 | __SYSCALL(__NR_wait4, compat_sys_wait4) |
| 254 | __SYSCALL(230, sys_lgetxattr) | 254 | #define __NR_swapoff 115 |
| 255 | __SYSCALL(231, sys_fgetxattr) | 255 | __SYSCALL(__NR_swapoff, sys_swapoff) |
| 256 | __SYSCALL(232, sys_listxattr) | 256 | #define __NR_sysinfo 116 |
| 257 | __SYSCALL(233, sys_llistxattr) | 257 | __SYSCALL(__NR_sysinfo, compat_sys_sysinfo) |
| 258 | __SYSCALL(234, sys_flistxattr) | 258 | /* 117 was sys_ipc */ |
| 259 | __SYSCALL(235, sys_removexattr) | 259 | __SYSCALL(117, sys_ni_syscall) |
| 260 | __SYSCALL(236, sys_lremovexattr) | 260 | #define __NR_fsync 118 |
| 261 | __SYSCALL(237, sys_fremovexattr) | 261 | __SYSCALL(__NR_fsync, sys_fsync) |
| 262 | __SYSCALL(238, sys_tkill) | 262 | #define __NR_sigreturn 119 |
| 263 | __SYSCALL(239, sys_sendfile64) | 263 | __SYSCALL(__NR_sigreturn, compat_sys_sigreturn_wrapper) |
| 264 | __SYSCALL(240, compat_sys_futex) | 264 | #define __NR_clone 120 |
| 265 | __SYSCALL(241, compat_sys_sched_setaffinity) | 265 | __SYSCALL(__NR_clone, sys_clone) |
| 266 | __SYSCALL(242, compat_sys_sched_getaffinity) | 266 | #define __NR_setdomainname 121 |
| 267 | __SYSCALL(243, compat_sys_io_setup) | 267 | __SYSCALL(__NR_setdomainname, sys_setdomainname) |
| 268 | __SYSCALL(244, sys_io_destroy) | 268 | #define __NR_uname 122 |
| 269 | __SYSCALL(245, compat_sys_io_getevents) | 269 | __SYSCALL(__NR_uname, sys_newuname) |
| 270 | __SYSCALL(246, compat_sys_io_submit) | 270 | /* 123 was sys_modify_ldt */ |
| 271 | __SYSCALL(247, sys_io_cancel) | 271 | __SYSCALL(123, sys_ni_syscall) |
| 272 | __SYSCALL(248, sys_exit_group) | 272 | #define __NR_adjtimex 124 |
| 273 | __SYSCALL(249, compat_sys_lookup_dcookie) | 273 | __SYSCALL(__NR_adjtimex, compat_sys_adjtimex) |
| 274 | __SYSCALL(250, sys_epoll_create) | 274 | #define __NR_mprotect 125 |
| 275 | __SYSCALL(251, sys_epoll_ctl) | 275 | __SYSCALL(__NR_mprotect, sys_mprotect) |
| 276 | __SYSCALL(252, sys_epoll_wait) | 276 | #define __NR_sigprocmask 126 |
| 277 | __SYSCALL(253, sys_remap_file_pages) | 277 | __SYSCALL(__NR_sigprocmask, compat_sys_sigprocmask) |
| 278 | __SYSCALL(254, sys_ni_syscall) /* 254 for set_thread_area */ | 278 | /* 127 was sys_create_module */ |
| 279 | __SYSCALL(255, sys_ni_syscall) /* 255 for get_thread_area */ | 279 | __SYSCALL(127, sys_ni_syscall) |
| 280 | __SYSCALL(256, sys_set_tid_address) | 280 | #define __NR_init_module 128 |
| 281 | __SYSCALL(257, compat_sys_timer_create) | 281 | __SYSCALL(__NR_init_module, sys_init_module) |
| 282 | __SYSCALL(258, compat_sys_timer_settime) | 282 | #define __NR_delete_module 129 |
| 283 | __SYSCALL(259, compat_sys_timer_gettime) | 283 | __SYSCALL(__NR_delete_module, sys_delete_module) |
| 284 | __SYSCALL(260, sys_timer_getoverrun) | 284 | /* 130 was sys_get_kernel_syms */ |
| 285 | __SYSCALL(261, sys_timer_delete) | 285 | __SYSCALL(130, sys_ni_syscall) |
| 286 | __SYSCALL(262, compat_sys_clock_settime) | 286 | #define __NR_quotactl 131 |
| 287 | __SYSCALL(263, compat_sys_clock_gettime) | 287 | __SYSCALL(__NR_quotactl, sys_quotactl) |
| 288 | __SYSCALL(264, compat_sys_clock_getres) | 288 | #define __NR_getpgid 132 |
| 289 | __SYSCALL(265, compat_sys_clock_nanosleep) | 289 | __SYSCALL(__NR_getpgid, sys_getpgid) |
| 290 | __SYSCALL(266, compat_sys_statfs64_wrapper) | 290 | #define __NR_fchdir 133 |
| 291 | __SYSCALL(267, compat_sys_fstatfs64_wrapper) | 291 | __SYSCALL(__NR_fchdir, sys_fchdir) |
| 292 | __SYSCALL(268, sys_tgkill) | 292 | #define __NR_bdflush 134 |
| 293 | __SYSCALL(269, compat_sys_utimes) | 293 | __SYSCALL(__NR_bdflush, sys_bdflush) |
| 294 | __SYSCALL(270, compat_sys_fadvise64_64_wrapper) | 294 | #define __NR_sysfs 135 |
| 295 | __SYSCALL(271, sys_pciconfig_iobase) | 295 | __SYSCALL(__NR_sysfs, sys_sysfs) |
| 296 | __SYSCALL(272, sys_pciconfig_read) | 296 | #define __NR_personality 136 |
| 297 | __SYSCALL(273, sys_pciconfig_write) | 297 | __SYSCALL(__NR_personality, sys_personality) |
| 298 | __SYSCALL(274, compat_sys_mq_open) | 298 | /* 137 was sys_afs_syscall */ |
| 299 | __SYSCALL(275, sys_mq_unlink) | 299 | __SYSCALL(137, sys_ni_syscall) |
| 300 | __SYSCALL(276, compat_sys_mq_timedsend) | 300 | #define __NR_setfsuid 138 |
| 301 | __SYSCALL(277, compat_sys_mq_timedreceive) | 301 | __SYSCALL(__NR_setfsuid, sys_setfsuid16) |
| 302 | __SYSCALL(278, compat_sys_mq_notify) | 302 | #define __NR_setfsgid 139 |
| 303 | __SYSCALL(279, compat_sys_mq_getsetattr) | 303 | __SYSCALL(__NR_setfsgid, sys_setfsgid16) |
| 304 | __SYSCALL(280, compat_sys_waitid) | 304 | #define __NR__llseek 140 |
| 305 | __SYSCALL(281, sys_socket) | 305 | __SYSCALL(__NR__llseek, sys_llseek) |
| 306 | __SYSCALL(282, sys_bind) | 306 | #define __NR_getdents 141 |
| 307 | __SYSCALL(283, sys_connect) | 307 | __SYSCALL(__NR_getdents, compat_sys_getdents) |
| 308 | __SYSCALL(284, sys_listen) | 308 | #define __NR__newselect 142 |
| 309 | __SYSCALL(285, sys_accept) | 309 | __SYSCALL(__NR__newselect, compat_sys_select) |
| 310 | __SYSCALL(286, sys_getsockname) | 310 | #define __NR_flock 143 |
| 311 | __SYSCALL(287, sys_getpeername) | 311 | __SYSCALL(__NR_flock, sys_flock) |
| 312 | __SYSCALL(288, sys_socketpair) | 312 | #define __NR_msync 144 |
| 313 | __SYSCALL(289, sys_send) | 313 | __SYSCALL(__NR_msync, sys_msync) |
| 314 | __SYSCALL(290, sys_sendto) | 314 | #define __NR_readv 145 |
| 315 | __SYSCALL(291, compat_sys_recv) | 315 | __SYSCALL(__NR_readv, compat_sys_readv) |
| 316 | __SYSCALL(292, compat_sys_recvfrom) | 316 | #define __NR_writev 146 |
| 317 | __SYSCALL(293, sys_shutdown) | 317 | __SYSCALL(__NR_writev, compat_sys_writev) |
| 318 | __SYSCALL(294, compat_sys_setsockopt) | 318 | #define __NR_getsid 147 |
| 319 | __SYSCALL(295, compat_sys_getsockopt) | 319 | __SYSCALL(__NR_getsid, sys_getsid) |
| 320 | __SYSCALL(296, compat_sys_sendmsg) | 320 | #define __NR_fdatasync 148 |
| 321 | __SYSCALL(297, compat_sys_recvmsg) | 321 | __SYSCALL(__NR_fdatasync, sys_fdatasync) |
| 322 | __SYSCALL(298, sys_semop) | 322 | #define __NR__sysctl 149 |
| 323 | __SYSCALL(299, sys_semget) | 323 | __SYSCALL(__NR__sysctl, compat_sys_sysctl) |
| 324 | __SYSCALL(300, compat_sys_semctl) | 324 | #define __NR_mlock 150 |
| 325 | __SYSCALL(301, compat_sys_msgsnd) | 325 | __SYSCALL(__NR_mlock, sys_mlock) |
| 326 | __SYSCALL(302, compat_sys_msgrcv) | 326 | #define __NR_munlock 151 |
| 327 | __SYSCALL(303, sys_msgget) | 327 | __SYSCALL(__NR_munlock, sys_munlock) |
| 328 | __SYSCALL(304, compat_sys_msgctl) | 328 | #define __NR_mlockall 152 |
| 329 | __SYSCALL(305, compat_sys_shmat) | 329 | __SYSCALL(__NR_mlockall, sys_mlockall) |
| 330 | __SYSCALL(306, sys_shmdt) | 330 | #define __NR_munlockall 153 |
| 331 | __SYSCALL(307, sys_shmget) | 331 | __SYSCALL(__NR_munlockall, sys_munlockall) |
| 332 | __SYSCALL(308, compat_sys_shmctl) | 332 | #define __NR_sched_setparam 154 |
| 333 | __SYSCALL(309, sys_add_key) | 333 | __SYSCALL(__NR_sched_setparam, sys_sched_setparam) |
| 334 | __SYSCALL(310, sys_request_key) | 334 | #define __NR_sched_getparam 155 |
| 335 | __SYSCALL(311, compat_sys_keyctl) | 335 | __SYSCALL(__NR_sched_getparam, sys_sched_getparam) |
| 336 | __SYSCALL(312, compat_sys_semtimedop) | 336 | #define __NR_sched_setscheduler 156 |
| 337 | __SYSCALL(313, sys_ni_syscall) | 337 | __SYSCALL(__NR_sched_setscheduler, sys_sched_setscheduler) |
| 338 | __SYSCALL(314, sys_ioprio_set) | 338 | #define __NR_sched_getscheduler 157 |
| 339 | __SYSCALL(315, sys_ioprio_get) | 339 | __SYSCALL(__NR_sched_getscheduler, sys_sched_getscheduler) |
| 340 | __SYSCALL(316, sys_inotify_init) | 340 | #define __NR_sched_yield 158 |
| 341 | __SYSCALL(317, sys_inotify_add_watch) | 341 | __SYSCALL(__NR_sched_yield, sys_sched_yield) |
| 342 | __SYSCALL(318, sys_inotify_rm_watch) | 342 | #define __NR_sched_get_priority_max 159 |
| 343 | __SYSCALL(319, compat_sys_mbind) | 343 | __SYSCALL(__NR_sched_get_priority_max, sys_sched_get_priority_max) |
| 344 | __SYSCALL(320, compat_sys_get_mempolicy) | 344 | #define __NR_sched_get_priority_min 160 |
| 345 | __SYSCALL(321, compat_sys_set_mempolicy) | 345 | __SYSCALL(__NR_sched_get_priority_min, sys_sched_get_priority_min) |
| 346 | __SYSCALL(322, compat_sys_openat) | 346 | #define __NR_sched_rr_get_interval 161 |
| 347 | __SYSCALL(323, sys_mkdirat) | 347 | __SYSCALL(__NR_sched_rr_get_interval, compat_sys_sched_rr_get_interval) |
| 348 | __SYSCALL(324, sys_mknodat) | 348 | #define __NR_nanosleep 162 |
| 349 | __SYSCALL(325, sys_fchownat) | 349 | __SYSCALL(__NR_nanosleep, compat_sys_nanosleep) |
| 350 | __SYSCALL(326, compat_sys_futimesat) | 350 | #define __NR_mremap 163 |
| 351 | __SYSCALL(327, sys_fstatat64) | 351 | __SYSCALL(__NR_mremap, sys_mremap) |
| 352 | __SYSCALL(328, sys_unlinkat) | 352 | #define __NR_setresuid 164 |
| 353 | __SYSCALL(329, sys_renameat) | 353 | __SYSCALL(__NR_setresuid, sys_setresuid16) |
| 354 | __SYSCALL(330, sys_linkat) | 354 | #define __NR_getresuid 165 |
| 355 | __SYSCALL(331, sys_symlinkat) | 355 | __SYSCALL(__NR_getresuid, sys_getresuid16) |
| 356 | __SYSCALL(332, sys_readlinkat) | 356 | /* 166 was sys_vm86 */ |
| 357 | __SYSCALL(333, sys_fchmodat) | 357 | __SYSCALL(166, sys_ni_syscall) |
| 358 | __SYSCALL(334, sys_faccessat) | 358 | /* 167 was sys_query_module */ |
| 359 | __SYSCALL(335, compat_sys_pselect6) | 359 | __SYSCALL(167, sys_ni_syscall) |
| 360 | __SYSCALL(336, compat_sys_ppoll) | 360 | #define __NR_poll 168 |
| 361 | __SYSCALL(337, sys_unshare) | 361 | __SYSCALL(__NR_poll, sys_poll) |
| 362 | __SYSCALL(338, compat_sys_set_robust_list) | 362 | #define __NR_nfsservctl 169 |
| 363 | __SYSCALL(339, compat_sys_get_robust_list) | 363 | __SYSCALL(__NR_nfsservctl, sys_ni_syscall) |
| 364 | __SYSCALL(340, sys_splice) | 364 | #define __NR_setresgid 170 |
| 365 | __SYSCALL(341, compat_sys_sync_file_range2_wrapper) | 365 | __SYSCALL(__NR_setresgid, sys_setresgid16) |
| 366 | __SYSCALL(342, sys_tee) | 366 | #define __NR_getresgid 171 |
| 367 | __SYSCALL(343, compat_sys_vmsplice) | 367 | __SYSCALL(__NR_getresgid, sys_getresgid16) |
| 368 | __SYSCALL(344, compat_sys_move_pages) | 368 | #define __NR_prctl 172 |
| 369 | __SYSCALL(345, sys_getcpu) | 369 | __SYSCALL(__NR_prctl, sys_prctl) |
| 370 | __SYSCALL(346, compat_sys_epoll_pwait) | 370 | #define __NR_rt_sigreturn 173 |
| 371 | __SYSCALL(347, compat_sys_kexec_load) | 371 | __SYSCALL(__NR_rt_sigreturn, compat_sys_rt_sigreturn_wrapper) |
| 372 | __SYSCALL(348, compat_sys_utimensat) | 372 | #define __NR_rt_sigaction 174 |
| 373 | __SYSCALL(349, compat_sys_signalfd) | 373 | __SYSCALL(__NR_rt_sigaction, compat_sys_rt_sigaction) |
| 374 | __SYSCALL(350, sys_timerfd_create) | 374 | #define __NR_rt_sigprocmask 175 |
| 375 | __SYSCALL(351, sys_eventfd) | 375 | __SYSCALL(__NR_rt_sigprocmask, compat_sys_rt_sigprocmask) |
| 376 | __SYSCALL(352, compat_sys_fallocate_wrapper) | 376 | #define __NR_rt_sigpending 176 |
| 377 | __SYSCALL(353, compat_sys_timerfd_settime) | 377 | __SYSCALL(__NR_rt_sigpending, compat_sys_rt_sigpending) |
| 378 | __SYSCALL(354, compat_sys_timerfd_gettime) | 378 | #define __NR_rt_sigtimedwait 177 |
| 379 | __SYSCALL(355, compat_sys_signalfd4) | 379 | __SYSCALL(__NR_rt_sigtimedwait, compat_sys_rt_sigtimedwait) |
| 380 | __SYSCALL(356, sys_eventfd2) | 380 | #define __NR_rt_sigqueueinfo 178 |
| 381 | __SYSCALL(357, sys_epoll_create1) | 381 | __SYSCALL(__NR_rt_sigqueueinfo, compat_sys_rt_sigqueueinfo) |
| 382 | __SYSCALL(358, sys_dup3) | 382 | #define __NR_rt_sigsuspend 179 |
| 383 | __SYSCALL(359, sys_pipe2) | 383 | __SYSCALL(__NR_rt_sigsuspend, compat_sys_rt_sigsuspend) |
| 384 | __SYSCALL(360, sys_inotify_init1) | 384 | #define __NR_pread64 180 |
| 385 | __SYSCALL(361, compat_sys_preadv) | 385 | __SYSCALL(__NR_pread64, compat_sys_pread64_wrapper) |
| 386 | __SYSCALL(362, compat_sys_pwritev) | 386 | #define __NR_pwrite64 181 |
| 387 | __SYSCALL(363, compat_sys_rt_tgsigqueueinfo) | 387 | __SYSCALL(__NR_pwrite64, compat_sys_pwrite64_wrapper) |
| 388 | __SYSCALL(364, sys_perf_event_open) | 388 | #define __NR_chown 182 |
| 389 | __SYSCALL(365, compat_sys_recvmmsg) | 389 | __SYSCALL(__NR_chown, sys_chown16) |
| 390 | __SYSCALL(366, sys_accept4) | 390 | #define __NR_getcwd 183 |
| 391 | __SYSCALL(367, sys_fanotify_init) | 391 | __SYSCALL(__NR_getcwd, sys_getcwd) |
| 392 | __SYSCALL(368, compat_sys_fanotify_mark) | 392 | #define __NR_capget 184 |
| 393 | __SYSCALL(369, sys_prlimit64) | 393 | __SYSCALL(__NR_capget, sys_capget) |
| 394 | __SYSCALL(370, sys_name_to_handle_at) | 394 | #define __NR_capset 185 |
| 395 | __SYSCALL(371, compat_sys_open_by_handle_at) | 395 | __SYSCALL(__NR_capset, sys_capset) |
| 396 | __SYSCALL(372, compat_sys_clock_adjtime) | 396 | #define __NR_sigaltstack 186 |
| 397 | __SYSCALL(373, sys_syncfs) | 397 | __SYSCALL(__NR_sigaltstack, compat_sys_sigaltstack) |
| 398 | __SYSCALL(374, compat_sys_sendmmsg) | 398 | #define __NR_sendfile 187 |
| 399 | __SYSCALL(375, sys_setns) | 399 | __SYSCALL(__NR_sendfile, compat_sys_sendfile) |
| 400 | __SYSCALL(376, compat_sys_process_vm_readv) | 400 | /* 188 reserved */ |
| 401 | __SYSCALL(377, compat_sys_process_vm_writev) | 401 | __SYSCALL(188, sys_ni_syscall) |
| 402 | __SYSCALL(378, sys_kcmp) | 402 | /* 189 reserved */ |
| 403 | __SYSCALL(379, sys_finit_module) | 403 | __SYSCALL(189, sys_ni_syscall) |
| 404 | __SYSCALL(380, sys_sched_setattr) | 404 | #define __NR_vfork 190 |
| 405 | __SYSCALL(381, sys_sched_getattr) | 405 | __SYSCALL(__NR_vfork, sys_vfork) |
| 406 | __SYSCALL(382, sys_renameat2) | 406 | #define __NR_ugetrlimit 191 /* SuS compliant getrlimit */ |
| 407 | 407 | __SYSCALL(__NR_ugetrlimit, compat_sys_getrlimit) /* SuS compliant getrlimit */ | |
| 408 | #define __NR_compat_syscalls 383 | 408 | #define __NR_mmap2 192 |
| 409 | 409 | __SYSCALL(__NR_mmap2, sys_mmap_pgoff) | |
| 410 | /* | 410 | #define __NR_truncate64 193 |
| 411 | * Compat syscall numbers used by the AArch64 kernel. | 411 | __SYSCALL(__NR_truncate64, compat_sys_truncate64_wrapper) |
| 412 | */ | 412 | #define __NR_ftruncate64 194 |
| 413 | #define __NR_compat_restart_syscall 0 | 413 | __SYSCALL(__NR_ftruncate64, compat_sys_ftruncate64_wrapper) |
| 414 | #define __NR_compat_sigreturn 119 | 414 | #define __NR_stat64 195 |
| 415 | #define __NR_compat_rt_sigreturn 173 | 415 | __SYSCALL(__NR_stat64, sys_stat64) |
| 416 | 416 | #define __NR_lstat64 196 | |
| 417 | 417 | __SYSCALL(__NR_lstat64, sys_lstat64) | |
| 418 | /* | 418 | #define __NR_fstat64 197 |
| 419 | * The following SVCs are ARM private. | 419 | __SYSCALL(__NR_fstat64, sys_fstat64) |
| 420 | */ | 420 | #define __NR_lchown32 198 |
| 421 | #define __ARM_NR_COMPAT_BASE 0x0f0000 | 421 | __SYSCALL(__NR_lchown32, sys_lchown) |
| 422 | #define __ARM_NR_compat_cacheflush (__ARM_NR_COMPAT_BASE+2) | 422 | #define __NR_getuid32 199 |
| 423 | #define __ARM_NR_compat_set_tls (__ARM_NR_COMPAT_BASE+5) | 423 | __SYSCALL(__NR_getuid32, sys_getuid) |
| 424 | #define __NR_getgid32 200 | ||
| 425 | __SYSCALL(__NR_getgid32, sys_getgid) | ||
| 426 | #define __NR_geteuid32 201 | ||
| 427 | __SYSCALL(__NR_geteuid32, sys_geteuid) | ||
| 428 | #define __NR_getegid32 202 | ||
| 429 | __SYSCALL(__NR_getegid32, sys_getegid) | ||
| 430 | #define __NR_setreuid32 203 | ||
| 431 | __SYSCALL(__NR_setreuid32, sys_setreuid) | ||
| 432 | #define __NR_setregid32 204 | ||
| 433 | __SYSCALL(__NR_setregid32, sys_setregid) | ||
| 434 | #define __NR_getgroups32 205 | ||
| 435 | __SYSCALL(__NR_getgroups32, sys_getgroups) | ||
| 436 | #define __NR_setgroups32 206 | ||
| 437 | __SYSCALL(__NR_setgroups32, sys_setgroups) | ||
| 438 | #define __NR_fchown32 207 | ||
| 439 | __SYSCALL(__NR_fchown32, sys_fchown) | ||
| 440 | #define __NR_setresuid32 208 | ||
| 441 | __SYSCALL(__NR_setresuid32, sys_setresuid) | ||
| 442 | #define __NR_getresuid32 209 | ||
| 443 | __SYSCALL(__NR_getresuid32, sys_getresuid) | ||
| 444 | #define __NR_setresgid32 210 | ||
| 445 | __SYSCALL(__NR_setresgid32, sys_setresgid) | ||
| 446 | #define __NR_getresgid32 211 | ||
| 447 | __SYSCALL(__NR_getresgid32, sys_getresgid) | ||
| 448 | #define __NR_chown32 212 | ||
| 449 | __SYSCALL(__NR_chown32, sys_chown) | ||
| 450 | #define __NR_setuid32 213 | ||
| 451 | __SYSCALL(__NR_setuid32, sys_setuid) | ||
| 452 | #define __NR_setgid32 214 | ||
| 453 | __SYSCALL(__NR_setgid32, sys_setgid) | ||
| 454 | #define __NR_setfsuid32 215 | ||
| 455 | __SYSCALL(__NR_setfsuid32, sys_setfsuid) | ||
| 456 | #define __NR_setfsgid32 216 | ||
| 457 | __SYSCALL(__NR_setfsgid32, sys_setfsgid) | ||
| 458 | #define __NR_getdents64 217 | ||
| 459 | __SYSCALL(__NR_getdents64, compat_sys_getdents64) | ||
| 460 | #define __NR_pivot_root 218 | ||
| 461 | __SYSCALL(__NR_pivot_root, sys_pivot_root) | ||
| 462 | #define __NR_mincore 219 | ||
| 463 | __SYSCALL(__NR_mincore, sys_mincore) | ||
| 464 | #define __NR_madvise 220 | ||
| 465 | __SYSCALL(__NR_madvise, sys_madvise) | ||
| 466 | #define __NR_fcntl64 221 | ||
| 467 | __SYSCALL(__NR_fcntl64, compat_sys_fcntl64) | ||
| 468 | /* 222 for tux */ | ||
| 469 | __SYSCALL(222, sys_ni_syscall) | ||
| 470 | /* 223 is unused */ | ||
| 471 | __SYSCALL(223, sys_ni_syscall) | ||
| 472 | #define __NR_gettid 224 | ||
| 473 | __SYSCALL(__NR_gettid, sys_gettid) | ||
| 474 | #define __NR_readahead 225 | ||
| 475 | __SYSCALL(__NR_readahead, compat_sys_readahead_wrapper) | ||
| 476 | #define __NR_setxattr 226 | ||
| 477 | __SYSCALL(__NR_setxattr, sys_setxattr) | ||
| 478 | #define __NR_lsetxattr 227 | ||
| 479 | __SYSCALL(__NR_lsetxattr, sys_lsetxattr) | ||
| 480 | #define __NR_fsetxattr 228 | ||
| 481 | __SYSCALL(__NR_fsetxattr, sys_fsetxattr) | ||
| 482 | #define __NR_getxattr 229 | ||
| 483 | __SYSCALL(__NR_getxattr, sys_getxattr) | ||
| 484 | #define __NR_lgetxattr 230 | ||
| 485 | __SYSCALL(__NR_lgetxattr, sys_lgetxattr) | ||
| 486 | #define __NR_fgetxattr 231 | ||
| 487 | __SYSCALL(__NR_fgetxattr, sys_fgetxattr) | ||
| 488 | #define __NR_listxattr 232 | ||
| 489 | __SYSCALL(__NR_listxattr, sys_listxattr) | ||
| 490 | #define __NR_llistxattr 233 | ||
| 491 | __SYSCALL(__NR_llistxattr, sys_llistxattr) | ||
| 492 | #define __NR_flistxattr 234 | ||
| 493 | __SYSCALL(__NR_flistxattr, sys_flistxattr) | ||
| 494 | #define __NR_removexattr 235 | ||
| 495 | __SYSCALL(__NR_removexattr, sys_removexattr) | ||
| 496 | #define __NR_lremovexattr 236 | ||
| 497 | __SYSCALL(__NR_lremovexattr, sys_lremovexattr) | ||
| 498 | #define __NR_fremovexattr 237 | ||
| 499 | __SYSCALL(__NR_fremovexattr, sys_fremovexattr) | ||
| 500 | #define __NR_tkill 238 | ||
| 501 | __SYSCALL(__NR_tkill, sys_tkill) | ||
| 502 | #define __NR_sendfile64 239 | ||
| 503 | __SYSCALL(__NR_sendfile64, sys_sendfile64) | ||
| 504 | #define __NR_futex 240 | ||
| 505 | __SYSCALL(__NR_futex, compat_sys_futex) | ||
| 506 | #define __NR_sched_setaffinity 241 | ||
| 507 | __SYSCALL(__NR_sched_setaffinity, compat_sys_sched_setaffinity) | ||
| 508 | #define __NR_sched_getaffinity 242 | ||
| 509 | __SYSCALL(__NR_sched_getaffinity, compat_sys_sched_getaffinity) | ||
| 510 | #define __NR_io_setup 243 | ||
| 511 | __SYSCALL(__NR_io_setup, compat_sys_io_setup) | ||
| 512 | #define __NR_io_destroy 244 | ||
| 513 | __SYSCALL(__NR_io_destroy, sys_io_destroy) | ||
| 514 | #define __NR_io_getevents 245 | ||
| 515 | __SYSCALL(__NR_io_getevents, compat_sys_io_getevents) | ||
| 516 | #define __NR_io_submit 246 | ||
| 517 | __SYSCALL(__NR_io_submit, compat_sys_io_submit) | ||
| 518 | #define __NR_io_cancel 247 | ||
| 519 | __SYSCALL(__NR_io_cancel, sys_io_cancel) | ||
| 520 | #define __NR_exit_group 248 | ||
| 521 | __SYSCALL(__NR_exit_group, sys_exit_group) | ||
| 522 | #define __NR_lookup_dcookie 249 | ||
| 523 | __SYSCALL(__NR_lookup_dcookie, compat_sys_lookup_dcookie) | ||
| 524 | #define __NR_epoll_create 250 | ||
| 525 | __SYSCALL(__NR_epoll_create, sys_epoll_create) | ||
| 526 | #define __NR_epoll_ctl 251 | ||
| 527 | __SYSCALL(__NR_epoll_ctl, sys_epoll_ctl) | ||
| 528 | #define __NR_epoll_wait 252 | ||
| 529 | __SYSCALL(__NR_epoll_wait, sys_epoll_wait) | ||
| 530 | #define __NR_remap_file_pages 253 | ||
| 531 | __SYSCALL(__NR_remap_file_pages, sys_remap_file_pages) | ||
| 532 | /* 254 for set_thread_area */ | ||
| 533 | __SYSCALL(254, sys_ni_syscall) | ||
| 534 | /* 255 for get_thread_area */ | ||
| 535 | __SYSCALL(255, sys_ni_syscall) | ||
| 536 | #define __NR_set_tid_address 256 | ||
| 537 | __SYSCALL(__NR_set_tid_address, sys_set_tid_address) | ||
| 538 | #define __NR_timer_create 257 | ||
| 539 | __SYSCALL(__NR_timer_create, compat_sys_timer_create) | ||
| 540 | #define __NR_timer_settime 258 | ||
| 541 | __SYSCALL(__NR_timer_settime, compat_sys_timer_settime) | ||
| 542 | #define __NR_timer_gettime 259 | ||
| 543 | __SYSCALL(__NR_timer_gettime, compat_sys_timer_gettime) | ||
| 544 | #define __NR_timer_getoverrun 260 | ||
| 545 | __SYSCALL(__NR_timer_getoverrun, sys_timer_getoverrun) | ||
| 546 | #define __NR_timer_delete 261 | ||
| 547 | __SYSCALL(__NR_timer_delete, sys_timer_delete) | ||
| 548 | #define __NR_clock_settime 262 | ||
| 549 | __SYSCALL(__NR_clock_settime, compat_sys_clock_settime) | ||
| 550 | #define __NR_clock_gettime 263 | ||
| 551 | __SYSCALL(__NR_clock_gettime, compat_sys_clock_gettime) | ||
| 552 | #define __NR_clock_getres 264 | ||
| 553 | __SYSCALL(__NR_clock_getres, compat_sys_clock_getres) | ||
| 554 | #define __NR_clock_nanosleep 265 | ||
| 555 | __SYSCALL(__NR_clock_nanosleep, compat_sys_clock_nanosleep) | ||
| 556 | #define __NR_statfs64 266 | ||
| 557 | __SYSCALL(__NR_statfs64, compat_sys_statfs64_wrapper) | ||
| 558 | #define __NR_fstatfs64 267 | ||
| 559 | __SYSCALL(__NR_fstatfs64, compat_sys_fstatfs64_wrapper) | ||
| 560 | #define __NR_tgkill 268 | ||
| 561 | __SYSCALL(__NR_tgkill, sys_tgkill) | ||
| 562 | #define __NR_utimes 269 | ||
| 563 | __SYSCALL(__NR_utimes, compat_sys_utimes) | ||
| 564 | #define __NR_arm_fadvise64_64 270 | ||
| 565 | __SYSCALL(__NR_arm_fadvise64_64, compat_sys_fadvise64_64_wrapper) | ||
| 566 | #define __NR_pciconfig_iobase 271 | ||
| 567 | __SYSCALL(__NR_pciconfig_iobase, sys_pciconfig_iobase) | ||
| 568 | #define __NR_pciconfig_read 272 | ||
| 569 | __SYSCALL(__NR_pciconfig_read, sys_pciconfig_read) | ||
| 570 | #define __NR_pciconfig_write 273 | ||
| 571 | __SYSCALL(__NR_pciconfig_write, sys_pciconfig_write) | ||
| 572 | #define __NR_mq_open 274 | ||
| 573 | __SYSCALL(__NR_mq_open, compat_sys_mq_open) | ||
| 574 | #define __NR_mq_unlink 275 | ||
| 575 | __SYSCALL(__NR_mq_unlink, sys_mq_unlink) | ||
| 576 | #define __NR_mq_timedsend 276 | ||
| 577 | __SYSCALL(__NR_mq_timedsend, compat_sys_mq_timedsend) | ||
| 578 | #define __NR_mq_timedreceive 277 | ||
| 579 | __SYSCALL(__NR_mq_timedreceive, compat_sys_mq_timedreceive) | ||
| 580 | #define __NR_mq_notify 278 | ||
| 581 | __SYSCALL(__NR_mq_notify, compat_sys_mq_notify) | ||
| 582 | #define __NR_mq_getsetattr 279 | ||
| 583 | __SYSCALL(__NR_mq_getsetattr, compat_sys_mq_getsetattr) | ||
| 584 | #define __NR_waitid 280 | ||
| 585 | __SYSCALL(__NR_waitid, compat_sys_waitid) | ||
| 586 | #define __NR_socket 281 | ||
| 587 | __SYSCALL(__NR_socket, sys_socket) | ||
| 588 | #define __NR_bind 282 | ||
| 589 | __SYSCALL(__NR_bind, sys_bind) | ||
| 590 | #define __NR_connect 283 | ||
| 591 | __SYSCALL(__NR_connect, sys_connect) | ||
| 592 | #define __NR_listen 284 | ||
| 593 | __SYSCALL(__NR_listen, sys_listen) | ||
| 594 | #define __NR_accept 285 | ||
| 595 | __SYSCALL(__NR_accept, sys_accept) | ||
| 596 | #define __NR_getsockname 286 | ||
| 597 | __SYSCALL(__NR_getsockname, sys_getsockname) | ||
| 598 | #define __NR_getpeername 287 | ||
| 599 | __SYSCALL(__NR_getpeername, sys_getpeername) | ||
| 600 | #define __NR_socketpair 288 | ||
| 601 | __SYSCALL(__NR_socketpair, sys_socketpair) | ||
| 602 | #define __NR_send 289 | ||
| 603 | __SYSCALL(__NR_send, sys_send) | ||
| 604 | #define __NR_sendto 290 | ||
| 605 | __SYSCALL(__NR_sendto, sys_sendto) | ||
| 606 | #define __NR_recv 291 | ||
| 607 | __SYSCALL(__NR_recv, compat_sys_recv) | ||
| 608 | #define __NR_recvfrom 292 | ||
| 609 | __SYSCALL(__NR_recvfrom, compat_sys_recvfrom) | ||
| 610 | #define __NR_shutdown 293 | ||
| 611 | __SYSCALL(__NR_shutdown, sys_shutdown) | ||
| 612 | #define __NR_setsockopt 294 | ||
| 613 | __SYSCALL(__NR_setsockopt, compat_sys_setsockopt) | ||
| 614 | #define __NR_getsockopt 295 | ||
| 615 | __SYSCALL(__NR_getsockopt, compat_sys_getsockopt) | ||
| 616 | #define __NR_sendmsg 296 | ||
| 617 | __SYSCALL(__NR_sendmsg, compat_sys_sendmsg) | ||
| 618 | #define __NR_recvmsg 297 | ||
| 619 | __SYSCALL(__NR_recvmsg, compat_sys_recvmsg) | ||
| 620 | #define __NR_semop 298 | ||
| 621 | __SYSCALL(__NR_semop, sys_semop) | ||
| 622 | #define __NR_semget 299 | ||
| 623 | __SYSCALL(__NR_semget, sys_semget) | ||
| 624 | #define __NR_semctl 300 | ||
| 625 | __SYSCALL(__NR_semctl, compat_sys_semctl) | ||
| 626 | #define __NR_msgsnd 301 | ||
| 627 | __SYSCALL(__NR_msgsnd, compat_sys_msgsnd) | ||
| 628 | #define __NR_msgrcv 302 | ||
| 629 | __SYSCALL(__NR_msgrcv, compat_sys_msgrcv) | ||
| 630 | #define __NR_msgget 303 | ||
| 631 | __SYSCALL(__NR_msgget, sys_msgget) | ||
| 632 | #define __NR_msgctl 304 | ||
| 633 | __SYSCALL(__NR_msgctl, compat_sys_msgctl) | ||
| 634 | #define __NR_shmat 305 | ||
| 635 | __SYSCALL(__NR_shmat, compat_sys_shmat) | ||
| 636 | #define __NR_shmdt 306 | ||
| 637 | __SYSCALL(__NR_shmdt, sys_shmdt) | ||
| 638 | #define __NR_shmget 307 | ||
| 639 | __SYSCALL(__NR_shmget, sys_shmget) | ||
| 640 | #define __NR_shmctl 308 | ||
| 641 | __SYSCALL(__NR_shmctl, compat_sys_shmctl) | ||
| 642 | #define __NR_add_key 309 | ||
| 643 | __SYSCALL(__NR_add_key, sys_add_key) | ||
| 644 | #define __NR_request_key 310 | ||
| 645 | __SYSCALL(__NR_request_key, sys_request_key) | ||
| 646 | #define __NR_keyctl 311 | ||
| 647 | __SYSCALL(__NR_keyctl, compat_sys_keyctl) | ||
| 648 | #define __NR_semtimedop 312 | ||
| 649 | __SYSCALL(__NR_semtimedop, compat_sys_semtimedop) | ||
| 650 | #define __NR_vserver 313 | ||
| 651 | __SYSCALL(__NR_vserver, sys_ni_syscall) | ||
| 652 | #define __NR_ioprio_set 314 | ||
| 653 | __SYSCALL(__NR_ioprio_set, sys_ioprio_set) | ||
| 654 | #define __NR_ioprio_get 315 | ||
| 655 | __SYSCALL(__NR_ioprio_get, sys_ioprio_get) | ||
| 656 | #define __NR_inotify_init 316 | ||
| 657 | __SYSCALL(__NR_inotify_init, sys_inotify_init) | ||
| 658 | #define __NR_inotify_add_watch 317 | ||
| 659 | __SYSCALL(__NR_inotify_add_watch, sys_inotify_add_watch) | ||
| 660 | #define __NR_inotify_rm_watch 318 | ||
| 661 | __SYSCALL(__NR_inotify_rm_watch, sys_inotify_rm_watch) | ||
| 662 | #define __NR_mbind 319 | ||
| 663 | __SYSCALL(__NR_mbind, compat_sys_mbind) | ||
| 664 | #define __NR_get_mempolicy 320 | ||
| 665 | __SYSCALL(__NR_get_mempolicy, compat_sys_get_mempolicy) | ||
| 666 | #define __NR_set_mempolicy 321 | ||
| 667 | __SYSCALL(__NR_set_mempolicy, compat_sys_set_mempolicy) | ||
| 668 | #define __NR_openat 322 | ||
| 669 | __SYSCALL(__NR_openat, compat_sys_openat) | ||
| 670 | #define __NR_mkdirat 323 | ||
| 671 | __SYSCALL(__NR_mkdirat, sys_mkdirat) | ||
| 672 | #define __NR_mknodat 324 | ||
| 673 | __SYSCALL(__NR_mknodat, sys_mknodat) | ||
| 674 | #define __NR_fchownat 325 | ||
| 675 | __SYSCALL(__NR_fchownat, sys_fchownat) | ||
| 676 | #define __NR_futimesat 326 | ||
| 677 | __SYSCALL(__NR_futimesat, compat_sys_futimesat) | ||
| 678 | #define __NR_fstatat64 327 | ||
| 679 | __SYSCALL(__NR_fstatat64, sys_fstatat64) | ||
| 680 | #define __NR_unlinkat 328 | ||
| 681 | __SYSCALL(__NR_unlinkat, sys_unlinkat) | ||
| 682 | #define __NR_renameat 329 | ||
| 683 | __SYSCALL(__NR_renameat, sys_renameat) | ||
| 684 | #define __NR_linkat 330 | ||
| 685 | __SYSCALL(__NR_linkat, sys_linkat) | ||
| 686 | #define __NR_symlinkat 331 | ||
| 687 | __SYSCALL(__NR_symlinkat, sys_symlinkat) | ||
| 688 | #define __NR_readlinkat 332 | ||
| 689 | __SYSCALL(__NR_readlinkat, sys_readlinkat) | ||
| 690 | #define __NR_fchmodat 333 | ||
| 691 | __SYSCALL(__NR_fchmodat, sys_fchmodat) | ||
| 692 | #define __NR_faccessat 334 | ||
| 693 | __SYSCALL(__NR_faccessat, sys_faccessat) | ||
| 694 | #define __NR_pselect6 335 | ||
| 695 | __SYSCALL(__NR_pselect6, compat_sys_pselect6) | ||
| 696 | #define __NR_ppoll 336 | ||
| 697 | __SYSCALL(__NR_ppoll, compat_sys_ppoll) | ||
| 698 | #define __NR_unshare 337 | ||
| 699 | __SYSCALL(__NR_unshare, sys_unshare) | ||
| 700 | #define __NR_set_robust_list 338 | ||
| 701 | __SYSCALL(__NR_set_robust_list, compat_sys_set_robust_list) | ||
| 702 | #define __NR_get_robust_list 339 | ||
| 703 | __SYSCALL(__NR_get_robust_list, compat_sys_get_robust_list) | ||
| 704 | #define __NR_splice 340 | ||
| 705 | __SYSCALL(__NR_splice, sys_splice) | ||
| 706 | #define __NR_sync_file_range2 341 | ||
| 707 | __SYSCALL(__NR_sync_file_range2, compat_sys_sync_file_range2_wrapper) | ||
| 708 | #define __NR_tee 342 | ||
| 709 | __SYSCALL(__NR_tee, sys_tee) | ||
| 710 | #define __NR_vmsplice 343 | ||
| 711 | __SYSCALL(__NR_vmsplice, compat_sys_vmsplice) | ||
| 712 | #define __NR_move_pages 344 | ||
| 713 | __SYSCALL(__NR_move_pages, compat_sys_move_pages) | ||
| 714 | #define __NR_getcpu 345 | ||
| 715 | __SYSCALL(__NR_getcpu, sys_getcpu) | ||
| 716 | #define __NR_epoll_pwait 346 | ||
| 717 | __SYSCALL(__NR_epoll_pwait, compat_sys_epoll_pwait) | ||
| 718 | #define __NR_kexec_load 347 | ||
| 719 | __SYSCALL(__NR_kexec_load, compat_sys_kexec_load) | ||
| 720 | #define __NR_utimensat 348 | ||
| 721 | __SYSCALL(__NR_utimensat, compat_sys_utimensat) | ||
| 722 | #define __NR_signalfd 349 | ||
| 723 | __SYSCALL(__NR_signalfd, compat_sys_signalfd) | ||
| 724 | #define __NR_timerfd_create 350 | ||
| 725 | __SYSCALL(__NR_timerfd_create, sys_timerfd_create) | ||
| 726 | #define __NR_eventfd 351 | ||
| 727 | __SYSCALL(__NR_eventfd, sys_eventfd) | ||
| 728 | #define __NR_fallocate 352 | ||
| 729 | __SYSCALL(__NR_fallocate, compat_sys_fallocate_wrapper) | ||
| 730 | #define __NR_timerfd_settime 353 | ||
| 731 | __SYSCALL(__NR_timerfd_settime, compat_sys_timerfd_settime) | ||
| 732 | #define __NR_timerfd_gettime 354 | ||
| 733 | __SYSCALL(__NR_timerfd_gettime, compat_sys_timerfd_gettime) | ||
| 734 | #define __NR_signalfd4 355 | ||
| 735 | __SYSCALL(__NR_signalfd4, compat_sys_signalfd4) | ||
| 736 | #define __NR_eventfd2 356 | ||
| 737 | __SYSCALL(__NR_eventfd2, sys_eventfd2) | ||
| 738 | #define __NR_epoll_create1 357 | ||
| 739 | __SYSCALL(__NR_epoll_create1, sys_epoll_create1) | ||
| 740 | #define __NR_dup3 358 | ||
| 741 | __SYSCALL(__NR_dup3, sys_dup3) | ||
| 742 | #define __NR_pipe2 359 | ||
| 743 | __SYSCALL(__NR_pipe2, sys_pipe2) | ||
| 744 | #define __NR_inotify_init1 360 | ||
| 745 | __SYSCALL(__NR_inotify_init1, sys_inotify_init1) | ||
| 746 | #define __NR_preadv 361 | ||
| 747 | __SYSCALL(__NR_preadv, compat_sys_preadv) | ||
| 748 | #define __NR_pwritev 362 | ||
| 749 | __SYSCALL(__NR_pwritev, compat_sys_pwritev) | ||
| 750 | #define __NR_rt_tgsigqueueinfo 363 | ||
| 751 | __SYSCALL(__NR_rt_tgsigqueueinfo, compat_sys_rt_tgsigqueueinfo) | ||
| 752 | #define __NR_perf_event_open 364 | ||
| 753 | __SYSCALL(__NR_perf_event_open, sys_perf_event_open) | ||
| 754 | #define __NR_recvmmsg 365 | ||
| 755 | __SYSCALL(__NR_recvmmsg, compat_sys_recvmmsg) | ||
| 756 | #define __NR_accept4 366 | ||
| 757 | __SYSCALL(__NR_accept4, sys_accept4) | ||
| 758 | #define __NR_fanotify_init 367 | ||
| 759 | __SYSCALL(__NR_fanotify_init, sys_fanotify_init) | ||
| 760 | #define __NR_fanotify_mark 368 | ||
| 761 | __SYSCALL(__NR_fanotify_mark, compat_sys_fanotify_mark) | ||
| 762 | #define __NR_prlimit64 369 | ||
| 763 | __SYSCALL(__NR_prlimit64, sys_prlimit64) | ||
| 764 | #define __NR_name_to_handle_at 370 | ||
| 765 | __SYSCALL(__NR_name_to_handle_at, sys_name_to_handle_at) | ||
| 766 | #define __NR_open_by_handle_at 371 | ||
| 767 | __SYSCALL(__NR_open_by_handle_at, compat_sys_open_by_handle_at) | ||
| 768 | #define __NR_clock_adjtime 372 | ||
| 769 | __SYSCALL(__NR_clock_adjtime, compat_sys_clock_adjtime) | ||
| 770 | #define __NR_syncfs 373 | ||
| 771 | __SYSCALL(__NR_syncfs, sys_syncfs) | ||
| 772 | #define __NR_sendmmsg 374 | ||
| 773 | __SYSCALL(__NR_sendmmsg, compat_sys_sendmmsg) | ||
| 774 | #define __NR_setns 375 | ||
| 775 | __SYSCALL(__NR_setns, sys_setns) | ||
| 776 | #define __NR_process_vm_readv 376 | ||
| 777 | __SYSCALL(__NR_process_vm_readv, compat_sys_process_vm_readv) | ||
| 778 | #define __NR_process_vm_writev 377 | ||
| 779 | __SYSCALL(__NR_process_vm_writev, compat_sys_process_vm_writev) | ||
| 780 | #define __NR_kcmp 378 | ||
| 781 | __SYSCALL(__NR_kcmp, sys_kcmp) | ||
| 782 | #define __NR_finit_module 379 | ||
| 783 | __SYSCALL(__NR_finit_module, sys_finit_module) | ||
| 784 | #define __NR_sched_setattr 380 | ||
| 785 | __SYSCALL(__NR_sched_setattr, sys_sched_setattr) | ||
| 786 | #define __NR_sched_getattr 381 | ||
| 787 | __SYSCALL(__NR_sched_getattr, sys_sched_getattr) | ||
| 788 | #define __NR_renameat2 382 | ||
| 789 | __SYSCALL(__NR_renameat2, sys_renameat2) | ||
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile index cdaedad3afe5..27c72ef4fd7a 100644 --- a/arch/arm64/kernel/Makefile +++ b/arch/arm64/kernel/Makefile | |||
| @@ -15,7 +15,8 @@ CFLAGS_REMOVE_return_address.o = -pg | |||
| 15 | arm64-obj-y := cputable.o debug-monitors.o entry.o irq.o fpsimd.o \ | 15 | arm64-obj-y := cputable.o debug-monitors.o entry.o irq.o fpsimd.o \ |
| 16 | entry-fpsimd.o process.o ptrace.o setup.o signal.o \ | 16 | entry-fpsimd.o process.o ptrace.o setup.o signal.o \ |
| 17 | sys.o stacktrace.o time.o traps.o io.o vdso.o \ | 17 | sys.o stacktrace.o time.o traps.o io.o vdso.o \ |
| 18 | hyp-stub.o psci.o cpu_ops.o insn.o return_address.o | 18 | hyp-stub.o psci.o cpu_ops.o insn.o return_address.o \ |
| 19 | cpuinfo.o | ||
| 19 | 20 | ||
| 20 | arm64-obj-$(CONFIG_COMPAT) += sys32.o kuser32.o signal32.o \ | 21 | arm64-obj-$(CONFIG_COMPAT) += sys32.o kuser32.o signal32.o \ |
| 21 | sys_compat.o | 22 | sys_compat.o |
diff --git a/arch/arm64/kernel/cpu_ops.c b/arch/arm64/kernel/cpu_ops.c index d62d12fb36c8..cce952440c64 100644 --- a/arch/arm64/kernel/cpu_ops.c +++ b/arch/arm64/kernel/cpu_ops.c | |||
| @@ -30,8 +30,8 @@ const struct cpu_operations *cpu_ops[NR_CPUS]; | |||
| 30 | static const struct cpu_operations *supported_cpu_ops[] __initconst = { | 30 | static const struct cpu_operations *supported_cpu_ops[] __initconst = { |
| 31 | #ifdef CONFIG_SMP | 31 | #ifdef CONFIG_SMP |
| 32 | &smp_spin_table_ops, | 32 | &smp_spin_table_ops, |
| 33 | &cpu_psci_ops, | ||
| 34 | #endif | 33 | #endif |
| 34 | &cpu_psci_ops, | ||
| 35 | NULL, | 35 | NULL, |
| 36 | }; | 36 | }; |
| 37 | 37 | ||
diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c new file mode 100644 index 000000000000..f798f66634af --- /dev/null +++ b/arch/arm64/kernel/cpuinfo.c | |||
| @@ -0,0 +1,192 @@ | |||
| 1 | /* | ||
| 2 | * Record and handle CPU attributes. | ||
| 3 | * | ||
| 4 | * Copyright (C) 2014 ARM Ltd. | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License version 2 as | ||
| 7 | * published by the Free Software Foundation. | ||
| 8 | * | ||
| 9 | * This program is distributed in the hope that it will be useful, | ||
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | * GNU General Public License for more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU General Public License | ||
| 15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | #include <asm/arch_timer.h> | ||
| 18 | #include <asm/cachetype.h> | ||
| 19 | #include <asm/cpu.h> | ||
| 20 | #include <asm/cputype.h> | ||
| 21 | |||
| 22 | #include <linux/bitops.h> | ||
| 23 | #include <linux/init.h> | ||
| 24 | #include <linux/kernel.h> | ||
| 25 | #include <linux/printk.h> | ||
| 26 | #include <linux/smp.h> | ||
| 27 | |||
| 28 | /* | ||
| 29 | * In case the boot CPU is hotpluggable, we record its initial state and | ||
| 30 | * current state separately. Certain system registers may contain different | ||
| 31 | * values depending on configuration at or after reset. | ||
| 32 | */ | ||
| 33 | DEFINE_PER_CPU(struct cpuinfo_arm64, cpu_data); | ||
| 34 | static struct cpuinfo_arm64 boot_cpu_data; | ||
| 35 | |||
| 36 | static char *icache_policy_str[] = { | ||
| 37 | [ICACHE_POLICY_RESERVED] = "RESERVED/UNKNOWN", | ||
| 38 | [ICACHE_POLICY_AIVIVT] = "AIVIVT", | ||
| 39 | [ICACHE_POLICY_VIPT] = "VIPT", | ||
| 40 | [ICACHE_POLICY_PIPT] = "PIPT", | ||
| 41 | }; | ||
| 42 | |||
| 43 | unsigned long __icache_flags; | ||
| 44 | |||
| 45 | static void cpuinfo_detect_icache_policy(struct cpuinfo_arm64 *info) | ||
| 46 | { | ||
| 47 | unsigned int cpu = smp_processor_id(); | ||
| 48 | u32 l1ip = CTR_L1IP(info->reg_ctr); | ||
| 49 | |||
| 50 | if (l1ip != ICACHE_POLICY_PIPT) | ||
| 51 | set_bit(ICACHEF_ALIASING, &__icache_flags); | ||
| 52 | if (l1ip == ICACHE_POLICY_AIVIVT); | ||
| 53 | set_bit(ICACHEF_AIVIVT, &__icache_flags); | ||
| 54 | |||
| 55 | pr_info("Detected %s I-cache on CPU%d\n", icache_policy_str[l1ip], cpu); | ||
| 56 | } | ||
| 57 | |||
| 58 | static int check_reg_mask(char *name, u64 mask, u64 boot, u64 cur, int cpu) | ||
| 59 | { | ||
| 60 | if ((boot & mask) == (cur & mask)) | ||
| 61 | return 0; | ||
| 62 | |||
| 63 | pr_warn("SANITY CHECK: Unexpected variation in %s. Boot CPU: %#016lx, CPU%d: %#016lx\n", | ||
| 64 | name, (unsigned long)boot, cpu, (unsigned long)cur); | ||
| 65 | |||
| 66 | return 1; | ||
| 67 | } | ||
| 68 | |||
| 69 | #define CHECK_MASK(field, mask, boot, cur, cpu) \ | ||
| 70 | check_reg_mask(#field, mask, (boot)->reg_ ## field, (cur)->reg_ ## field, cpu) | ||
| 71 | |||
| 72 | #define CHECK(field, boot, cur, cpu) \ | ||
| 73 | CHECK_MASK(field, ~0ULL, boot, cur, cpu) | ||
| 74 | |||
| 75 | /* | ||
| 76 | * Verify that CPUs don't have unexpected differences that will cause problems. | ||
| 77 | */ | ||
| 78 | static void cpuinfo_sanity_check(struct cpuinfo_arm64 *cur) | ||
| 79 | { | ||
| 80 | unsigned int cpu = smp_processor_id(); | ||
| 81 | struct cpuinfo_arm64 *boot = &boot_cpu_data; | ||
| 82 | unsigned int diff = 0; | ||
| 83 | |||
| 84 | /* | ||
| 85 | * The kernel can handle differing I-cache policies, but otherwise | ||
| 86 | * caches should look identical. Userspace JITs will make use of | ||
| 87 | * *minLine. | ||
| 88 | */ | ||
| 89 | diff |= CHECK_MASK(ctr, 0xffff3fff, boot, cur, cpu); | ||
| 90 | |||
| 91 | /* | ||
| 92 | * Userspace may perform DC ZVA instructions. Mismatched block sizes | ||
| 93 | * could result in too much or too little memory being zeroed if a | ||
| 94 | * process is preempted and migrated between CPUs. | ||
| 95 | */ | ||
| 96 | diff |= CHECK(dczid, boot, cur, cpu); | ||
| 97 | |||
| 98 | /* If different, timekeeping will be broken (especially with KVM) */ | ||
| 99 | diff |= CHECK(cntfrq, boot, cur, cpu); | ||
| 100 | |||
| 101 | /* | ||
| 102 | * Even in big.LITTLE, processors should be identical instruction-set | ||
| 103 | * wise. | ||
| 104 | */ | ||
| 105 | diff |= CHECK(id_aa64isar0, boot, cur, cpu); | ||
| 106 | diff |= CHECK(id_aa64isar1, boot, cur, cpu); | ||
| 107 | |||
| 108 | /* | ||
| 109 | * Differing PARange support is fine as long as all peripherals and | ||
| 110 | * memory are mapped within the minimum PARange of all CPUs. | ||
| 111 | * Linux should not care about secure memory. | ||
| 112 | * ID_AA64MMFR1 is currently RES0. | ||
| 113 | */ | ||
| 114 | diff |= CHECK_MASK(id_aa64mmfr0, 0xffffffffffff0ff0, boot, cur, cpu); | ||
| 115 | diff |= CHECK(id_aa64mmfr1, boot, cur, cpu); | ||
| 116 | |||
| 117 | /* | ||
| 118 | * EL3 is not our concern. | ||
| 119 | * ID_AA64PFR1 is currently RES0. | ||
| 120 | */ | ||
| 121 | diff |= CHECK_MASK(id_aa64pfr0, 0xffffffffffff0fff, boot, cur, cpu); | ||
| 122 | diff |= CHECK(id_aa64pfr1, boot, cur, cpu); | ||
| 123 | |||
| 124 | /* | ||
| 125 | * If we have AArch32, we care about 32-bit features for compat. These | ||
| 126 | * registers should be RES0 otherwise. | ||
| 127 | */ | ||
| 128 | diff |= CHECK(id_isar0, boot, cur, cpu); | ||
| 129 | diff |= CHECK(id_isar1, boot, cur, cpu); | ||
| 130 | diff |= CHECK(id_isar2, boot, cur, cpu); | ||
| 131 | diff |= CHECK(id_isar3, boot, cur, cpu); | ||
| 132 | diff |= CHECK(id_isar4, boot, cur, cpu); | ||
| 133 | diff |= CHECK(id_isar5, boot, cur, cpu); | ||
| 134 | diff |= CHECK(id_mmfr0, boot, cur, cpu); | ||
| 135 | diff |= CHECK(id_mmfr1, boot, cur, cpu); | ||
| 136 | diff |= CHECK(id_mmfr2, boot, cur, cpu); | ||
| 137 | diff |= CHECK(id_mmfr3, boot, cur, cpu); | ||
| 138 | diff |= CHECK(id_pfr0, boot, cur, cpu); | ||
| 139 | diff |= CHECK(id_pfr1, boot, cur, cpu); | ||
| 140 | |||
| 141 | /* | ||
| 142 | * Mismatched CPU features are a recipe for disaster. Don't even | ||
| 143 | * pretend to support them. | ||
| 144 | */ | ||
| 145 | WARN_TAINT_ONCE(diff, TAINT_CPU_OUT_OF_SPEC, | ||
| 146 | "Unsupported CPU feature variation."); | ||
| 147 | } | ||
| 148 | |||
| 149 | static void __cpuinfo_store_cpu(struct cpuinfo_arm64 *info) | ||
| 150 | { | ||
| 151 | info->reg_cntfrq = arch_timer_get_cntfrq(); | ||
| 152 | info->reg_ctr = read_cpuid_cachetype(); | ||
| 153 | info->reg_dczid = read_cpuid(DCZID_EL0); | ||
| 154 | info->reg_midr = read_cpuid_id(); | ||
| 155 | |||
| 156 | info->reg_id_aa64isar0 = read_cpuid(ID_AA64ISAR0_EL1); | ||
| 157 | info->reg_id_aa64isar1 = read_cpuid(ID_AA64ISAR1_EL1); | ||
| 158 | info->reg_id_aa64mmfr0 = read_cpuid(ID_AA64MMFR0_EL1); | ||
| 159 | info->reg_id_aa64mmfr1 = read_cpuid(ID_AA64MMFR1_EL1); | ||
| 160 | info->reg_id_aa64pfr0 = read_cpuid(ID_AA64PFR0_EL1); | ||
| 161 | info->reg_id_aa64pfr1 = read_cpuid(ID_AA64PFR1_EL1); | ||
| 162 | |||
| 163 | info->reg_id_isar0 = read_cpuid(ID_ISAR0_EL1); | ||
| 164 | info->reg_id_isar1 = read_cpuid(ID_ISAR1_EL1); | ||
| 165 | info->reg_id_isar2 = read_cpuid(ID_ISAR2_EL1); | ||
| 166 | info->reg_id_isar3 = read_cpuid(ID_ISAR3_EL1); | ||
| 167 | info->reg_id_isar4 = read_cpuid(ID_ISAR4_EL1); | ||
| 168 | info->reg_id_isar5 = read_cpuid(ID_ISAR5_EL1); | ||
| 169 | info->reg_id_mmfr0 = read_cpuid(ID_MMFR0_EL1); | ||
| 170 | info->reg_id_mmfr1 = read_cpuid(ID_MMFR1_EL1); | ||
| 171 | info->reg_id_mmfr2 = read_cpuid(ID_MMFR2_EL1); | ||
| 172 | info->reg_id_mmfr3 = read_cpuid(ID_MMFR3_EL1); | ||
| 173 | info->reg_id_pfr0 = read_cpuid(ID_PFR0_EL1); | ||
| 174 | info->reg_id_pfr1 = read_cpuid(ID_PFR1_EL1); | ||
| 175 | |||
| 176 | cpuinfo_detect_icache_policy(info); | ||
| 177 | } | ||
| 178 | |||
| 179 | void cpuinfo_store_cpu(void) | ||
| 180 | { | ||
| 181 | struct cpuinfo_arm64 *info = this_cpu_ptr(&cpu_data); | ||
| 182 | __cpuinfo_store_cpu(info); | ||
| 183 | cpuinfo_sanity_check(info); | ||
| 184 | } | ||
| 185 | |||
| 186 | void __init cpuinfo_store_boot_cpu(void) | ||
| 187 | { | ||
| 188 | struct cpuinfo_arm64 *info = &per_cpu(cpu_data, 0); | ||
| 189 | __cpuinfo_store_cpu(info); | ||
| 190 | |||
| 191 | boot_cpu_data = *info; | ||
| 192 | } | ||
diff --git a/arch/arm64/kernel/debug-monitors.c b/arch/arm64/kernel/debug-monitors.c index a7fb874b595e..fe5b94078d82 100644 --- a/arch/arm64/kernel/debug-monitors.c +++ b/arch/arm64/kernel/debug-monitors.c | |||
| @@ -315,20 +315,20 @@ static int brk_handler(unsigned long addr, unsigned int esr, | |||
| 315 | { | 315 | { |
| 316 | siginfo_t info; | 316 | siginfo_t info; |
| 317 | 317 | ||
| 318 | if (call_break_hook(regs, esr) == DBG_HOOK_HANDLED) | 318 | if (user_mode(regs)) { |
| 319 | return 0; | 319 | info = (siginfo_t) { |
| 320 | .si_signo = SIGTRAP, | ||
| 321 | .si_errno = 0, | ||
| 322 | .si_code = TRAP_BRKPT, | ||
| 323 | .si_addr = (void __user *)instruction_pointer(regs), | ||
| 324 | }; | ||
| 320 | 325 | ||
| 321 | if (!user_mode(regs)) | 326 | force_sig_info(SIGTRAP, &info, current); |
| 327 | } else if (call_break_hook(regs, esr) != DBG_HOOK_HANDLED) { | ||
| 328 | pr_warning("Unexpected kernel BRK exception at EL1\n"); | ||
| 322 | return -EFAULT; | 329 | return -EFAULT; |
| 330 | } | ||
| 323 | 331 | ||
| 324 | info = (siginfo_t) { | ||
| 325 | .si_signo = SIGTRAP, | ||
| 326 | .si_errno = 0, | ||
| 327 | .si_code = TRAP_BRKPT, | ||
| 328 | .si_addr = (void __user *)instruction_pointer(regs), | ||
| 329 | }; | ||
| 330 | |||
| 331 | force_sig_info(SIGTRAP, &info, current); | ||
| 332 | return 0; | 332 | return 0; |
| 333 | } | 333 | } |
| 334 | 334 | ||
diff --git a/arch/arm64/kernel/entry-fpsimd.S b/arch/arm64/kernel/entry-fpsimd.S index d358ccacfc00..c44a82f146b1 100644 --- a/arch/arm64/kernel/entry-fpsimd.S +++ b/arch/arm64/kernel/entry-fpsimd.S | |||
| @@ -52,7 +52,7 @@ ENDPROC(fpsimd_load_state) | |||
| 52 | ENTRY(fpsimd_save_partial_state) | 52 | ENTRY(fpsimd_save_partial_state) |
| 53 | fpsimd_save_partial x0, 1, 8, 9 | 53 | fpsimd_save_partial x0, 1, 8, 9 |
| 54 | ret | 54 | ret |
| 55 | ENDPROC(fpsimd_load_partial_state) | 55 | ENDPROC(fpsimd_save_partial_state) |
| 56 | 56 | ||
| 57 | /* | 57 | /* |
| 58 | * Load the bottom n FP registers. | 58 | * Load the bottom n FP registers. |
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S index 9ce04ba6bcb0..f0b5e5120a87 100644 --- a/arch/arm64/kernel/entry.S +++ b/arch/arm64/kernel/entry.S | |||
| @@ -27,7 +27,32 @@ | |||
| 27 | #include <asm/esr.h> | 27 | #include <asm/esr.h> |
| 28 | #include <asm/thread_info.h> | 28 | #include <asm/thread_info.h> |
| 29 | #include <asm/unistd.h> | 29 | #include <asm/unistd.h> |
| 30 | #include <asm/unistd32.h> | 30 | |
| 31 | /* | ||
| 32 | * Context tracking subsystem. Used to instrument transitions | ||
| 33 | * between user and kernel mode. | ||
| 34 | */ | ||
| 35 | .macro ct_user_exit, syscall = 0 | ||
| 36 | #ifdef CONFIG_CONTEXT_TRACKING | ||
| 37 | bl context_tracking_user_exit | ||
| 38 | .if \syscall == 1 | ||
| 39 | /* | ||
| 40 | * Save/restore needed during syscalls. Restore syscall arguments from | ||
| 41 | * the values already saved on stack during kernel_entry. | ||
| 42 | */ | ||
| 43 | ldp x0, x1, [sp] | ||
| 44 | ldp x2, x3, [sp, #S_X2] | ||
| 45 | ldp x4, x5, [sp, #S_X4] | ||
| 46 | ldp x6, x7, [sp, #S_X6] | ||
| 47 | .endif | ||
| 48 | #endif | ||
| 49 | .endm | ||
| 50 | |||
| 51 | .macro ct_user_enter | ||
| 52 | #ifdef CONFIG_CONTEXT_TRACKING | ||
| 53 | bl context_tracking_user_enter | ||
| 54 | #endif | ||
| 55 | .endm | ||
| 31 | 56 | ||
| 32 | /* | 57 | /* |
| 33 | * Bad Abort numbers | 58 | * Bad Abort numbers |
| @@ -91,6 +116,7 @@ | |||
| 91 | .macro kernel_exit, el, ret = 0 | 116 | .macro kernel_exit, el, ret = 0 |
| 92 | ldp x21, x22, [sp, #S_PC] // load ELR, SPSR | 117 | ldp x21, x22, [sp, #S_PC] // load ELR, SPSR |
| 93 | .if \el == 0 | 118 | .if \el == 0 |
| 119 | ct_user_enter | ||
| 94 | ldr x23, [sp, #S_SP] // load return stack pointer | 120 | ldr x23, [sp, #S_SP] // load return stack pointer |
| 95 | .endif | 121 | .endif |
| 96 | .if \ret | 122 | .if \ret |
| @@ -353,7 +379,6 @@ el0_sync: | |||
| 353 | lsr x24, x25, #ESR_EL1_EC_SHIFT // exception class | 379 | lsr x24, x25, #ESR_EL1_EC_SHIFT // exception class |
| 354 | cmp x24, #ESR_EL1_EC_SVC64 // SVC in 64-bit state | 380 | cmp x24, #ESR_EL1_EC_SVC64 // SVC in 64-bit state |
| 355 | b.eq el0_svc | 381 | b.eq el0_svc |
| 356 | adr lr, ret_to_user | ||
| 357 | cmp x24, #ESR_EL1_EC_DABT_EL0 // data abort in EL0 | 382 | cmp x24, #ESR_EL1_EC_DABT_EL0 // data abort in EL0 |
| 358 | b.eq el0_da | 383 | b.eq el0_da |
| 359 | cmp x24, #ESR_EL1_EC_IABT_EL0 // instruction abort in EL0 | 384 | cmp x24, #ESR_EL1_EC_IABT_EL0 // instruction abort in EL0 |
| @@ -382,7 +407,6 @@ el0_sync_compat: | |||
| 382 | lsr x24, x25, #ESR_EL1_EC_SHIFT // exception class | 407 | lsr x24, x25, #ESR_EL1_EC_SHIFT // exception class |
| 383 | cmp x24, #ESR_EL1_EC_SVC32 // SVC in 32-bit state | 408 | cmp x24, #ESR_EL1_EC_SVC32 // SVC in 32-bit state |
| 384 | b.eq el0_svc_compat | 409 | b.eq el0_svc_compat |
| 385 | adr lr, ret_to_user | ||
| 386 | cmp x24, #ESR_EL1_EC_DABT_EL0 // data abort in EL0 | 410 | cmp x24, #ESR_EL1_EC_DABT_EL0 // data abort in EL0 |
| 387 | b.eq el0_da | 411 | b.eq el0_da |
| 388 | cmp x24, #ESR_EL1_EC_IABT_EL0 // instruction abort in EL0 | 412 | cmp x24, #ESR_EL1_EC_IABT_EL0 // instruction abort in EL0 |
| @@ -425,48 +449,59 @@ el0_da: | |||
| 425 | /* | 449 | /* |
| 426 | * Data abort handling | 450 | * Data abort handling |
| 427 | */ | 451 | */ |
| 428 | mrs x0, far_el1 | 452 | mrs x26, far_el1 |
| 429 | bic x0, x0, #(0xff << 56) | ||
| 430 | // enable interrupts before calling the main handler | 453 | // enable interrupts before calling the main handler |
| 431 | enable_dbg_and_irq | 454 | enable_dbg_and_irq |
| 455 | ct_user_exit | ||
| 456 | bic x0, x26, #(0xff << 56) | ||
| 432 | mov x1, x25 | 457 | mov x1, x25 |
| 433 | mov x2, sp | 458 | mov x2, sp |
| 459 | adr lr, ret_to_user | ||
| 434 | b do_mem_abort | 460 | b do_mem_abort |
| 435 | el0_ia: | 461 | el0_ia: |
| 436 | /* | 462 | /* |
| 437 | * Instruction abort handling | 463 | * Instruction abort handling |
| 438 | */ | 464 | */ |
| 439 | mrs x0, far_el1 | 465 | mrs x26, far_el1 |
| 440 | // enable interrupts before calling the main handler | 466 | // enable interrupts before calling the main handler |
| 441 | enable_dbg_and_irq | 467 | enable_dbg_and_irq |
| 468 | ct_user_exit | ||
| 469 | mov x0, x26 | ||
| 442 | orr x1, x25, #1 << 24 // use reserved ISS bit for instruction aborts | 470 | orr x1, x25, #1 << 24 // use reserved ISS bit for instruction aborts |
| 443 | mov x2, sp | 471 | mov x2, sp |
| 472 | adr lr, ret_to_user | ||
| 444 | b do_mem_abort | 473 | b do_mem_abort |
| 445 | el0_fpsimd_acc: | 474 | el0_fpsimd_acc: |
| 446 | /* | 475 | /* |
| 447 | * Floating Point or Advanced SIMD access | 476 | * Floating Point or Advanced SIMD access |
| 448 | */ | 477 | */ |
| 449 | enable_dbg | 478 | enable_dbg |
| 479 | ct_user_exit | ||
| 450 | mov x0, x25 | 480 | mov x0, x25 |
| 451 | mov x1, sp | 481 | mov x1, sp |
| 482 | adr lr, ret_to_user | ||
| 452 | b do_fpsimd_acc | 483 | b do_fpsimd_acc |
| 453 | el0_fpsimd_exc: | 484 | el0_fpsimd_exc: |
| 454 | /* | 485 | /* |
| 455 | * Floating Point or Advanced SIMD exception | 486 | * Floating Point or Advanced SIMD exception |
| 456 | */ | 487 | */ |
| 457 | enable_dbg | 488 | enable_dbg |
| 489 | ct_user_exit | ||
| 458 | mov x0, x25 | 490 | mov x0, x25 |
| 459 | mov x1, sp | 491 | mov x1, sp |
| 492 | adr lr, ret_to_user | ||
| 460 | b do_fpsimd_exc | 493 | b do_fpsimd_exc |
| 461 | el0_sp_pc: | 494 | el0_sp_pc: |
| 462 | /* | 495 | /* |
| 463 | * Stack or PC alignment exception handling | 496 | * Stack or PC alignment exception handling |
| 464 | */ | 497 | */ |
| 465 | mrs x0, far_el1 | 498 | mrs x26, far_el1 |
| 466 | // enable interrupts before calling the main handler | 499 | // enable interrupts before calling the main handler |
| 467 | enable_dbg_and_irq | 500 | enable_dbg_and_irq |
| 501 | mov x0, x26 | ||
| 468 | mov x1, x25 | 502 | mov x1, x25 |
| 469 | mov x2, sp | 503 | mov x2, sp |
| 504 | adr lr, ret_to_user | ||
| 470 | b do_sp_pc_abort | 505 | b do_sp_pc_abort |
| 471 | el0_undef: | 506 | el0_undef: |
| 472 | /* | 507 | /* |
| @@ -474,7 +509,9 @@ el0_undef: | |||
| 474 | */ | 509 | */ |
| 475 | // enable interrupts before calling the main handler | 510 | // enable interrupts before calling the main handler |
| 476 | enable_dbg_and_irq | 511 | enable_dbg_and_irq |
| 512 | ct_user_exit | ||
| 477 | mov x0, sp | 513 | mov x0, sp |
| 514 | adr lr, ret_to_user | ||
| 478 | b do_undefinstr | 515 | b do_undefinstr |
| 479 | el0_dbg: | 516 | el0_dbg: |
| 480 | /* | 517 | /* |
| @@ -486,12 +523,15 @@ el0_dbg: | |||
| 486 | mov x2, sp | 523 | mov x2, sp |
| 487 | bl do_debug_exception | 524 | bl do_debug_exception |
| 488 | enable_dbg | 525 | enable_dbg |
| 526 | ct_user_exit | ||
| 489 | b ret_to_user | 527 | b ret_to_user |
| 490 | el0_inv: | 528 | el0_inv: |
| 491 | enable_dbg | 529 | enable_dbg |
| 530 | ct_user_exit | ||
| 492 | mov x0, sp | 531 | mov x0, sp |
| 493 | mov x1, #BAD_SYNC | 532 | mov x1, #BAD_SYNC |
| 494 | mrs x2, esr_el1 | 533 | mrs x2, esr_el1 |
| 534 | adr lr, ret_to_user | ||
| 495 | b bad_mode | 535 | b bad_mode |
| 496 | ENDPROC(el0_sync) | 536 | ENDPROC(el0_sync) |
| 497 | 537 | ||
| @@ -504,6 +544,7 @@ el0_irq_naked: | |||
| 504 | bl trace_hardirqs_off | 544 | bl trace_hardirqs_off |
| 505 | #endif | 545 | #endif |
| 506 | 546 | ||
| 547 | ct_user_exit | ||
| 507 | irq_handler | 548 | irq_handler |
| 508 | 549 | ||
| 509 | #ifdef CONFIG_TRACE_IRQFLAGS | 550 | #ifdef CONFIG_TRACE_IRQFLAGS |
| @@ -608,6 +649,7 @@ el0_svc: | |||
| 608 | el0_svc_naked: // compat entry point | 649 | el0_svc_naked: // compat entry point |
| 609 | stp x0, scno, [sp, #S_ORIG_X0] // save the original x0 and syscall number | 650 | stp x0, scno, [sp, #S_ORIG_X0] // save the original x0 and syscall number |
| 610 | enable_dbg_and_irq | 651 | enable_dbg_and_irq |
| 652 | ct_user_exit 1 | ||
| 611 | 653 | ||
| 612 | ldr x16, [tsk, #TI_FLAGS] // check for syscall hooks | 654 | ldr x16, [tsk, #TI_FLAGS] // check for syscall hooks |
| 613 | tst x16, #_TIF_SYSCALL_WORK | 655 | tst x16, #_TIF_SYSCALL_WORK |
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S index a2c1195abb7f..144f10567f82 100644 --- a/arch/arm64/kernel/head.S +++ b/arch/arm64/kernel/head.S | |||
| @@ -22,6 +22,7 @@ | |||
| 22 | 22 | ||
| 23 | #include <linux/linkage.h> | 23 | #include <linux/linkage.h> |
| 24 | #include <linux/init.h> | 24 | #include <linux/init.h> |
| 25 | #include <linux/irqchip/arm-gic-v3.h> | ||
| 25 | 26 | ||
| 26 | #include <asm/assembler.h> | 27 | #include <asm/assembler.h> |
| 27 | #include <asm/ptrace.h> | 28 | #include <asm/ptrace.h> |
| @@ -35,37 +36,31 @@ | |||
| 35 | #include <asm/page.h> | 36 | #include <asm/page.h> |
| 36 | #include <asm/virt.h> | 37 | #include <asm/virt.h> |
| 37 | 38 | ||
| 38 | /* | ||
| 39 | * swapper_pg_dir is the virtual address of the initial page table. We place | ||
| 40 | * the page tables 3 * PAGE_SIZE below KERNEL_RAM_VADDR. The idmap_pg_dir has | ||
| 41 | * 2 pages and is placed below swapper_pg_dir. | ||
| 42 | */ | ||
| 43 | #define KERNEL_RAM_VADDR (PAGE_OFFSET + TEXT_OFFSET) | 39 | #define KERNEL_RAM_VADDR (PAGE_OFFSET + TEXT_OFFSET) |
| 44 | 40 | ||
| 45 | #if (KERNEL_RAM_VADDR & 0xfffff) != 0x80000 | 41 | #if (TEXT_OFFSET & 0xf) != 0 |
| 46 | #error KERNEL_RAM_VADDR must start at 0xXXX80000 | 42 | #error TEXT_OFFSET must be at least 16B aligned |
| 43 | #elif (PAGE_OFFSET & 0xfffff) != 0 | ||
| 44 | #error PAGE_OFFSET must be at least 2MB aligned | ||
| 45 | #elif TEXT_OFFSET > 0xfffff | ||
| 46 | #error TEXT_OFFSET must be less than 2MB | ||
| 47 | #endif | 47 | #endif |
| 48 | 48 | ||
| 49 | #define SWAPPER_DIR_SIZE (3 * PAGE_SIZE) | 49 | .macro pgtbl, ttb0, ttb1, virt_to_phys |
| 50 | #define IDMAP_DIR_SIZE (2 * PAGE_SIZE) | 50 | ldr \ttb1, =swapper_pg_dir |
| 51 | 51 | ldr \ttb0, =idmap_pg_dir | |
| 52 | .globl swapper_pg_dir | 52 | add \ttb1, \ttb1, \virt_to_phys |
| 53 | .equ swapper_pg_dir, KERNEL_RAM_VADDR - SWAPPER_DIR_SIZE | 53 | add \ttb0, \ttb0, \virt_to_phys |
| 54 | |||
| 55 | .globl idmap_pg_dir | ||
| 56 | .equ idmap_pg_dir, swapper_pg_dir - IDMAP_DIR_SIZE | ||
| 57 | |||
| 58 | .macro pgtbl, ttb0, ttb1, phys | ||
| 59 | add \ttb1, \phys, #TEXT_OFFSET - SWAPPER_DIR_SIZE | ||
| 60 | sub \ttb0, \ttb1, #IDMAP_DIR_SIZE | ||
| 61 | .endm | 54 | .endm |
| 62 | 55 | ||
| 63 | #ifdef CONFIG_ARM64_64K_PAGES | 56 | #ifdef CONFIG_ARM64_64K_PAGES |
| 64 | #define BLOCK_SHIFT PAGE_SHIFT | 57 | #define BLOCK_SHIFT PAGE_SHIFT |
| 65 | #define BLOCK_SIZE PAGE_SIZE | 58 | #define BLOCK_SIZE PAGE_SIZE |
| 59 | #define TABLE_SHIFT PMD_SHIFT | ||
| 66 | #else | 60 | #else |
| 67 | #define BLOCK_SHIFT SECTION_SHIFT | 61 | #define BLOCK_SHIFT SECTION_SHIFT |
| 68 | #define BLOCK_SIZE SECTION_SIZE | 62 | #define BLOCK_SIZE SECTION_SIZE |
| 63 | #define TABLE_SHIFT PUD_SHIFT | ||
| 69 | #endif | 64 | #endif |
| 70 | 65 | ||
| 71 | #define KERNEL_START KERNEL_RAM_VADDR | 66 | #define KERNEL_START KERNEL_RAM_VADDR |
| @@ -120,9 +115,9 @@ efi_head: | |||
| 120 | b stext // branch to kernel start, magic | 115 | b stext // branch to kernel start, magic |
| 121 | .long 0 // reserved | 116 | .long 0 // reserved |
| 122 | #endif | 117 | #endif |
| 123 | .quad TEXT_OFFSET // Image load offset from start of RAM | 118 | .quad _kernel_offset_le // Image load offset from start of RAM, little-endian |
| 124 | .quad 0 // reserved | 119 | .quad _kernel_size_le // Effective size of kernel image, little-endian |
| 125 | .quad 0 // reserved | 120 | .quad _kernel_flags_le // Informative flags, little-endian |
| 126 | .quad 0 // reserved | 121 | .quad 0 // reserved |
| 127 | .quad 0 // reserved | 122 | .quad 0 // reserved |
| 128 | .quad 0 // reserved | 123 | .quad 0 // reserved |
| @@ -295,6 +290,23 @@ CPU_LE( bic x0, x0, #(3 << 24) ) // Clear the EE and E0E bits for EL1 | |||
| 295 | msr cnthctl_el2, x0 | 290 | msr cnthctl_el2, x0 |
| 296 | msr cntvoff_el2, xzr // Clear virtual offset | 291 | msr cntvoff_el2, xzr // Clear virtual offset |
| 297 | 292 | ||
| 293 | #ifdef CONFIG_ARM_GIC_V3 | ||
| 294 | /* GICv3 system register access */ | ||
| 295 | mrs x0, id_aa64pfr0_el1 | ||
| 296 | ubfx x0, x0, #24, #4 | ||
| 297 | cmp x0, #1 | ||
| 298 | b.ne 3f | ||
| 299 | |||
| 300 | mrs_s x0, ICC_SRE_EL2 | ||
| 301 | orr x0, x0, #ICC_SRE_EL2_SRE // Set ICC_SRE_EL2.SRE==1 | ||
| 302 | orr x0, x0, #ICC_SRE_EL2_ENABLE // Set ICC_SRE_EL2.Enable==1 | ||
| 303 | msr_s ICC_SRE_EL2, x0 | ||
| 304 | isb // Make sure SRE is now set | ||
| 305 | msr_s ICH_HCR_EL2, xzr // Reset ICC_HCR_EL2 to defaults | ||
| 306 | |||
| 307 | 3: | ||
| 308 | #endif | ||
| 309 | |||
| 298 | /* Populate ID registers. */ | 310 | /* Populate ID registers. */ |
| 299 | mrs x0, midr_el1 | 311 | mrs x0, midr_el1 |
| 300 | mrs x1, mpidr_el1 | 312 | mrs x1, mpidr_el1 |
| @@ -413,7 +425,7 @@ ENTRY(secondary_startup) | |||
| 413 | mov x23, x0 // x23=current cpu_table | 425 | mov x23, x0 // x23=current cpu_table |
| 414 | cbz x23, __error_p // invalid processor (x23=0)? | 426 | cbz x23, __error_p // invalid processor (x23=0)? |
| 415 | 427 | ||
| 416 | pgtbl x25, x26, x24 // x25=TTBR0, x26=TTBR1 | 428 | pgtbl x25, x26, x28 // x25=TTBR0, x26=TTBR1 |
| 417 | ldr x12, [x23, #CPU_INFO_SETUP] | 429 | ldr x12, [x23, #CPU_INFO_SETUP] |
| 418 | add x12, x12, x28 // __virt_to_phys | 430 | add x12, x12, x28 // __virt_to_phys |
| 419 | blr x12 // initialise processor | 431 | blr x12 // initialise processor |
| @@ -455,8 +467,13 @@ ENDPROC(__enable_mmu) | |||
| 455 | * x27 = *virtual* address to jump to upon completion | 467 | * x27 = *virtual* address to jump to upon completion |
| 456 | * | 468 | * |
| 457 | * other registers depend on the function called upon completion | 469 | * other registers depend on the function called upon completion |
| 470 | * | ||
| 471 | * We align the entire function to the smallest power of two larger than it to | ||
| 472 | * ensure it fits within a single block map entry. Otherwise were PHYS_OFFSET | ||
| 473 | * close to the end of a 512MB or 1GB block we might require an additional | ||
| 474 | * table to map the entire function. | ||
| 458 | */ | 475 | */ |
| 459 | .align 6 | 476 | .align 4 |
| 460 | __turn_mmu_on: | 477 | __turn_mmu_on: |
| 461 | msr sctlr_el1, x0 | 478 | msr sctlr_el1, x0 |
| 462 | isb | 479 | isb |
| @@ -479,17 +496,38 @@ ENDPROC(__calc_phys_offset) | |||
| 479 | .quad PAGE_OFFSET | 496 | .quad PAGE_OFFSET |
| 480 | 497 | ||
| 481 | /* | 498 | /* |
| 482 | * Macro to populate the PGD for the corresponding block entry in the next | 499 | * Macro to create a table entry to the next page. |
| 483 | * level (tbl) for the given virtual address. | 500 | * |
| 501 | * tbl: page table address | ||
| 502 | * virt: virtual address | ||
| 503 | * shift: #imm page table shift | ||
| 504 | * ptrs: #imm pointers per table page | ||
| 505 | * | ||
| 506 | * Preserves: virt | ||
| 507 | * Corrupts: tmp1, tmp2 | ||
| 508 | * Returns: tbl -> next level table page address | ||
| 509 | */ | ||
| 510 | .macro create_table_entry, tbl, virt, shift, ptrs, tmp1, tmp2 | ||
| 511 | lsr \tmp1, \virt, #\shift | ||
| 512 | and \tmp1, \tmp1, #\ptrs - 1 // table index | ||
| 513 | add \tmp2, \tbl, #PAGE_SIZE | ||
| 514 | orr \tmp2, \tmp2, #PMD_TYPE_TABLE // address of next table and entry type | ||
| 515 | str \tmp2, [\tbl, \tmp1, lsl #3] | ||
| 516 | add \tbl, \tbl, #PAGE_SIZE // next level table page | ||
| 517 | .endm | ||
| 518 | |||
| 519 | /* | ||
| 520 | * Macro to populate the PGD (and possibily PUD) for the corresponding | ||
| 521 | * block entry in the next level (tbl) for the given virtual address. | ||
| 484 | * | 522 | * |
| 485 | * Preserves: pgd, tbl, virt | 523 | * Preserves: tbl, next, virt |
| 486 | * Corrupts: tmp1, tmp2 | 524 | * Corrupts: tmp1, tmp2 |
| 487 | */ | 525 | */ |
| 488 | .macro create_pgd_entry, pgd, tbl, virt, tmp1, tmp2 | 526 | .macro create_pgd_entry, tbl, virt, tmp1, tmp2 |
| 489 | lsr \tmp1, \virt, #PGDIR_SHIFT | 527 | create_table_entry \tbl, \virt, PGDIR_SHIFT, PTRS_PER_PGD, \tmp1, \tmp2 |
| 490 | and \tmp1, \tmp1, #PTRS_PER_PGD - 1 // PGD index | 528 | #if SWAPPER_PGTABLE_LEVELS == 3 |
| 491 | orr \tmp2, \tbl, #3 // PGD entry table type | 529 | create_table_entry \tbl, \virt, TABLE_SHIFT, PTRS_PER_PTE, \tmp1, \tmp2 |
| 492 | str \tmp2, [\pgd, \tmp1, lsl #3] | 530 | #endif |
| 493 | .endm | 531 | .endm |
| 494 | 532 | ||
| 495 | /* | 533 | /* |
| @@ -522,7 +560,7 @@ ENDPROC(__calc_phys_offset) | |||
| 522 | * - pgd entry for fixed mappings (TTBR1) | 560 | * - pgd entry for fixed mappings (TTBR1) |
| 523 | */ | 561 | */ |
| 524 | __create_page_tables: | 562 | __create_page_tables: |
| 525 | pgtbl x25, x26, x24 // idmap_pg_dir and swapper_pg_dir addresses | 563 | pgtbl x25, x26, x28 // idmap_pg_dir and swapper_pg_dir addresses |
| 526 | mov x27, lr | 564 | mov x27, lr |
| 527 | 565 | ||
| 528 | /* | 566 | /* |
| @@ -550,10 +588,10 @@ __create_page_tables: | |||
| 550 | /* | 588 | /* |
| 551 | * Create the identity mapping. | 589 | * Create the identity mapping. |
| 552 | */ | 590 | */ |
| 553 | add x0, x25, #PAGE_SIZE // section table address | 591 | mov x0, x25 // idmap_pg_dir |
| 554 | ldr x3, =KERNEL_START | 592 | ldr x3, =KERNEL_START |
| 555 | add x3, x3, x28 // __pa(KERNEL_START) | 593 | add x3, x3, x28 // __pa(KERNEL_START) |
| 556 | create_pgd_entry x25, x0, x3, x5, x6 | 594 | create_pgd_entry x0, x3, x5, x6 |
| 557 | ldr x6, =KERNEL_END | 595 | ldr x6, =KERNEL_END |
| 558 | mov x5, x3 // __pa(KERNEL_START) | 596 | mov x5, x3 // __pa(KERNEL_START) |
| 559 | add x6, x6, x28 // __pa(KERNEL_END) | 597 | add x6, x6, x28 // __pa(KERNEL_END) |
| @@ -562,9 +600,9 @@ __create_page_tables: | |||
| 562 | /* | 600 | /* |
| 563 | * Map the kernel image (starting with PHYS_OFFSET). | 601 | * Map the kernel image (starting with PHYS_OFFSET). |
| 564 | */ | 602 | */ |
| 565 | add x0, x26, #PAGE_SIZE // section table address | 603 | mov x0, x26 // swapper_pg_dir |
| 566 | mov x5, #PAGE_OFFSET | 604 | mov x5, #PAGE_OFFSET |
| 567 | create_pgd_entry x26, x0, x5, x3, x6 | 605 | create_pgd_entry x0, x5, x3, x6 |
| 568 | ldr x6, =KERNEL_END | 606 | ldr x6, =KERNEL_END |
| 569 | mov x3, x24 // phys offset | 607 | mov x3, x24 // phys offset |
| 570 | create_block_map x0, x7, x3, x5, x6 | 608 | create_block_map x0, x7, x3, x5, x6 |
| @@ -586,13 +624,6 @@ __create_page_tables: | |||
| 586 | create_block_map x0, x7, x3, x5, x6 | 624 | create_block_map x0, x7, x3, x5, x6 |
| 587 | 1: | 625 | 1: |
| 588 | /* | 626 | /* |
| 589 | * Create the pgd entry for the fixed mappings. | ||
| 590 | */ | ||
| 591 | ldr x5, =FIXADDR_TOP // Fixed mapping virtual address | ||
| 592 | add x0, x26, #2 * PAGE_SIZE // section table address | ||
| 593 | create_pgd_entry x26, x0, x5, x6, x7 | ||
| 594 | |||
| 595 | /* | ||
| 596 | * Since the page tables have been populated with non-cacheable | 627 | * Since the page tables have been populated with non-cacheable |
| 597 | * accesses (MMU disabled), invalidate the idmap and swapper page | 628 | * accesses (MMU disabled), invalidate the idmap and swapper page |
| 598 | * tables again to remove any speculatively loaded cache lines. | 629 | * tables again to remove any speculatively loaded cache lines. |
| @@ -611,7 +642,7 @@ ENDPROC(__create_page_tables) | |||
| 611 | __switch_data: | 642 | __switch_data: |
| 612 | .quad __mmap_switched | 643 | .quad __mmap_switched |
| 613 | .quad __bss_start // x6 | 644 | .quad __bss_start // x6 |
| 614 | .quad _end // x7 | 645 | .quad __bss_stop // x7 |
| 615 | .quad processor_id // x4 | 646 | .quad processor_id // x4 |
| 616 | .quad __fdt_pointer // x5 | 647 | .quad __fdt_pointer // x5 |
| 617 | .quad memstart_addr // x6 | 648 | .quad memstart_addr // x6 |
diff --git a/arch/arm64/kernel/hyp-stub.S b/arch/arm64/kernel/hyp-stub.S index 0959611d9ff1..a272f335c289 100644 --- a/arch/arm64/kernel/hyp-stub.S +++ b/arch/arm64/kernel/hyp-stub.S | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | 19 | ||
| 20 | #include <linux/init.h> | 20 | #include <linux/init.h> |
| 21 | #include <linux/linkage.h> | 21 | #include <linux/linkage.h> |
| 22 | #include <linux/irqchip/arm-gic-v3.h> | ||
| 22 | 23 | ||
| 23 | #include <asm/assembler.h> | 24 | #include <asm/assembler.h> |
| 24 | #include <asm/ptrace.h> | 25 | #include <asm/ptrace.h> |
diff --git a/arch/arm64/kernel/image.h b/arch/arm64/kernel/image.h new file mode 100644 index 000000000000..8fae0756e175 --- /dev/null +++ b/arch/arm64/kernel/image.h | |||
| @@ -0,0 +1,62 @@ | |||
| 1 | /* | ||
| 2 | * Linker script macros to generate Image header fields. | ||
| 3 | * | ||
| 4 | * Copyright (C) 2014 ARM Ltd. | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License version 2 as | ||
| 8 | * published by the Free Software Foundation. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 17 | */ | ||
| 18 | #ifndef __ASM_IMAGE_H | ||
| 19 | #define __ASM_IMAGE_H | ||
| 20 | |||
| 21 | #ifndef LINKER_SCRIPT | ||
| 22 | #error This file should only be included in vmlinux.lds.S | ||
| 23 | #endif | ||
| 24 | |||
| 25 | /* | ||
| 26 | * There aren't any ELF relocations we can use to endian-swap values known only | ||
| 27 | * at link time (e.g. the subtraction of two symbol addresses), so we must get | ||
| 28 | * the linker to endian-swap certain values before emitting them. | ||
| 29 | */ | ||
| 30 | #ifdef CONFIG_CPU_BIG_ENDIAN | ||
| 31 | #define DATA_LE64(data) \ | ||
| 32 | ((((data) & 0x00000000000000ff) << 56) | \ | ||
| 33 | (((data) & 0x000000000000ff00) << 40) | \ | ||
| 34 | (((data) & 0x0000000000ff0000) << 24) | \ | ||
| 35 | (((data) & 0x00000000ff000000) << 8) | \ | ||
| 36 | (((data) & 0x000000ff00000000) >> 8) | \ | ||
| 37 | (((data) & 0x0000ff0000000000) >> 24) | \ | ||
| 38 | (((data) & 0x00ff000000000000) >> 40) | \ | ||
| 39 | (((data) & 0xff00000000000000) >> 56)) | ||
| 40 | #else | ||
| 41 | #define DATA_LE64(data) ((data) & 0xffffffffffffffff) | ||
| 42 | #endif | ||
| 43 | |||
| 44 | #ifdef CONFIG_CPU_BIG_ENDIAN | ||
| 45 | #define __HEAD_FLAG_BE 1 | ||
| 46 | #else | ||
| 47 | #define __HEAD_FLAG_BE 0 | ||
| 48 | #endif | ||
| 49 | |||
| 50 | #define __HEAD_FLAGS (__HEAD_FLAG_BE << 0) | ||
| 51 | |||
| 52 | /* | ||
| 53 | * These will output as part of the Image header, which should be little-endian | ||
| 54 | * regardless of the endianness of the kernel. While constant values could be | ||
| 55 | * endian swapped in head.S, all are done here for consistency. | ||
| 56 | */ | ||
| 57 | #define HEAD_SYMBOLS \ | ||
| 58 | _kernel_size_le = DATA_LE64(_end - _text); \ | ||
| 59 | _kernel_offset_le = DATA_LE64(TEXT_OFFSET); \ | ||
| 60 | _kernel_flags_le = DATA_LE64(__HEAD_FLAGS); | ||
| 61 | |||
| 62 | #endif /* __ASM_IMAGE_H */ | ||
diff --git a/arch/arm64/kernel/kuser32.S b/arch/arm64/kernel/kuser32.S index 7787208e8cc6..997e6b27ff6a 100644 --- a/arch/arm64/kernel/kuser32.S +++ b/arch/arm64/kernel/kuser32.S | |||
| @@ -28,7 +28,7 @@ | |||
| 28 | * See Documentation/arm/kernel_user_helpers.txt for formal definitions. | 28 | * See Documentation/arm/kernel_user_helpers.txt for formal definitions. |
| 29 | */ | 29 | */ |
| 30 | 30 | ||
| 31 | #include <asm/unistd32.h> | 31 | #include <asm/unistd.h> |
| 32 | 32 | ||
| 33 | .align 5 | 33 | .align 5 |
| 34 | .globl __kuser_helper_start | 34 | .globl __kuser_helper_start |
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c index 43b7c34f92cb..1309d64aa926 100644 --- a/arch/arm64/kernel/process.c +++ b/arch/arm64/kernel/process.c | |||
| @@ -51,6 +51,12 @@ | |||
| 51 | #include <asm/processor.h> | 51 | #include <asm/processor.h> |
| 52 | #include <asm/stacktrace.h> | 52 | #include <asm/stacktrace.h> |
| 53 | 53 | ||
| 54 | #ifdef CONFIG_CC_STACKPROTECTOR | ||
| 55 | #include <linux/stackprotector.h> | ||
| 56 | unsigned long __stack_chk_guard __read_mostly; | ||
| 57 | EXPORT_SYMBOL(__stack_chk_guard); | ||
| 58 | #endif | ||
| 59 | |||
| 54 | static void setup_restart(void) | 60 | static void setup_restart(void) |
| 55 | { | 61 | { |
| 56 | /* | 62 | /* |
diff --git a/arch/arm64/kernel/psci.c b/arch/arm64/kernel/psci.c index 9e9798f91172..553954771a67 100644 --- a/arch/arm64/kernel/psci.c +++ b/arch/arm64/kernel/psci.c | |||
| @@ -235,7 +235,7 @@ static void psci_sys_poweroff(void) | |||
| 235 | * PSCI Function IDs for v0.2+ are well defined so use | 235 | * PSCI Function IDs for v0.2+ are well defined so use |
| 236 | * standard values. | 236 | * standard values. |
| 237 | */ | 237 | */ |
| 238 | static int psci_0_2_init(struct device_node *np) | 238 | static int __init psci_0_2_init(struct device_node *np) |
| 239 | { | 239 | { |
| 240 | int err, ver; | 240 | int err, ver; |
| 241 | 241 | ||
| @@ -296,7 +296,7 @@ out_put_node: | |||
| 296 | /* | 296 | /* |
| 297 | * PSCI < v0.2 get PSCI Function IDs via DT. | 297 | * PSCI < v0.2 get PSCI Function IDs via DT. |
| 298 | */ | 298 | */ |
| 299 | static int psci_0_1_init(struct device_node *np) | 299 | static int __init psci_0_1_init(struct device_node *np) |
| 300 | { | 300 | { |
| 301 | u32 id; | 301 | u32 id; |
| 302 | int err; | 302 | int err; |
| @@ -434,9 +434,11 @@ static int cpu_psci_cpu_kill(unsigned int cpu) | |||
| 434 | return 0; | 434 | return 0; |
| 435 | } | 435 | } |
| 436 | #endif | 436 | #endif |
| 437 | #endif | ||
| 437 | 438 | ||
| 438 | const struct cpu_operations cpu_psci_ops = { | 439 | const struct cpu_operations cpu_psci_ops = { |
| 439 | .name = "psci", | 440 | .name = "psci", |
| 441 | #ifdef CONFIG_SMP | ||
| 440 | .cpu_init = cpu_psci_cpu_init, | 442 | .cpu_init = cpu_psci_cpu_init, |
| 441 | .cpu_prepare = cpu_psci_cpu_prepare, | 443 | .cpu_prepare = cpu_psci_cpu_prepare, |
| 442 | .cpu_boot = cpu_psci_cpu_boot, | 444 | .cpu_boot = cpu_psci_cpu_boot, |
| @@ -445,6 +447,6 @@ const struct cpu_operations cpu_psci_ops = { | |||
| 445 | .cpu_die = cpu_psci_cpu_die, | 447 | .cpu_die = cpu_psci_cpu_die, |
| 446 | .cpu_kill = cpu_psci_cpu_kill, | 448 | .cpu_kill = cpu_psci_cpu_kill, |
| 447 | #endif | 449 | #endif |
| 450 | #endif | ||
| 448 | }; | 451 | }; |
| 449 | 452 | ||
| 450 | #endif | ||
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c index 9fde010c945f..0310811bd77d 100644 --- a/arch/arm64/kernel/ptrace.c +++ b/arch/arm64/kernel/ptrace.c | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | 19 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 20 | */ | 20 | */ |
| 21 | 21 | ||
| 22 | #include <linux/audit.h> | ||
| 22 | #include <linux/compat.h> | 23 | #include <linux/compat.h> |
| 23 | #include <linux/kernel.h> | 24 | #include <linux/kernel.h> |
| 24 | #include <linux/sched.h> | 25 | #include <linux/sched.h> |
| @@ -39,6 +40,7 @@ | |||
| 39 | #include <asm/compat.h> | 40 | #include <asm/compat.h> |
| 40 | #include <asm/debug-monitors.h> | 41 | #include <asm/debug-monitors.h> |
| 41 | #include <asm/pgtable.h> | 42 | #include <asm/pgtable.h> |
| 43 | #include <asm/syscall.h> | ||
| 42 | #include <asm/traps.h> | 44 | #include <asm/traps.h> |
| 43 | #include <asm/system_misc.h> | 45 | #include <asm/system_misc.h> |
| 44 | 46 | ||
| @@ -1113,11 +1115,20 @@ asmlinkage int syscall_trace_enter(struct pt_regs *regs) | |||
| 1113 | if (test_thread_flag(TIF_SYSCALL_TRACEPOINT)) | 1115 | if (test_thread_flag(TIF_SYSCALL_TRACEPOINT)) |
| 1114 | trace_sys_enter(regs, regs->syscallno); | 1116 | trace_sys_enter(regs, regs->syscallno); |
| 1115 | 1117 | ||
| 1118 | #ifdef CONFIG_AUDITSYSCALL | ||
| 1119 | audit_syscall_entry(syscall_get_arch(), regs->syscallno, | ||
| 1120 | regs->orig_x0, regs->regs[1], regs->regs[2], regs->regs[3]); | ||
| 1121 | #endif | ||
| 1122 | |||
| 1116 | return regs->syscallno; | 1123 | return regs->syscallno; |
| 1117 | } | 1124 | } |
| 1118 | 1125 | ||
| 1119 | asmlinkage void syscall_trace_exit(struct pt_regs *regs) | 1126 | asmlinkage void syscall_trace_exit(struct pt_regs *regs) |
| 1120 | { | 1127 | { |
| 1128 | #ifdef CONFIG_AUDITSYSCALL | ||
| 1129 | audit_syscall_exit(regs); | ||
| 1130 | #endif | ||
| 1131 | |||
| 1121 | if (test_thread_flag(TIF_SYSCALL_TRACEPOINT)) | 1132 | if (test_thread_flag(TIF_SYSCALL_TRACEPOINT)) |
| 1122 | trace_sys_exit(regs, regs_return_value(regs)); | 1133 | trace_sys_exit(regs, regs_return_value(regs)); |
| 1123 | 1134 | ||
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c index 46d1125571f6..f6f0ccf35ae6 100644 --- a/arch/arm64/kernel/setup.c +++ b/arch/arm64/kernel/setup.c | |||
| @@ -45,6 +45,7 @@ | |||
| 45 | #include <linux/efi.h> | 45 | #include <linux/efi.h> |
| 46 | 46 | ||
| 47 | #include <asm/fixmap.h> | 47 | #include <asm/fixmap.h> |
| 48 | #include <asm/cpu.h> | ||
| 48 | #include <asm/cputype.h> | 49 | #include <asm/cputype.h> |
| 49 | #include <asm/elf.h> | 50 | #include <asm/elf.h> |
| 50 | #include <asm/cputable.h> | 51 | #include <asm/cputable.h> |
| @@ -77,7 +78,6 @@ unsigned int compat_elf_hwcap2 __read_mostly; | |||
| 77 | #endif | 78 | #endif |
| 78 | 79 | ||
| 79 | static const char *cpu_name; | 80 | static const char *cpu_name; |
| 80 | static const char *machine_name; | ||
| 81 | phys_addr_t __fdt_pointer __initdata; | 81 | phys_addr_t __fdt_pointer __initdata; |
| 82 | 82 | ||
| 83 | /* | 83 | /* |
| @@ -219,6 +219,8 @@ static void __init setup_processor(void) | |||
| 219 | sprintf(init_utsname()->machine, ELF_PLATFORM); | 219 | sprintf(init_utsname()->machine, ELF_PLATFORM); |
| 220 | elf_hwcap = 0; | 220 | elf_hwcap = 0; |
| 221 | 221 | ||
| 222 | cpuinfo_store_boot_cpu(); | ||
| 223 | |||
| 222 | /* | 224 | /* |
| 223 | * Check for sane CTR_EL0.CWG value. | 225 | * Check for sane CTR_EL0.CWG value. |
| 224 | */ | 226 | */ |
| @@ -307,8 +309,6 @@ static void __init setup_machine_fdt(phys_addr_t dt_phys) | |||
| 307 | while (true) | 309 | while (true) |
| 308 | cpu_relax(); | 310 | cpu_relax(); |
| 309 | } | 311 | } |
| 310 | |||
| 311 | machine_name = of_flat_dt_get_machine_name(); | ||
| 312 | } | 312 | } |
| 313 | 313 | ||
| 314 | /* | 314 | /* |
| @@ -417,14 +417,12 @@ static int __init arm64_device_init(void) | |||
| 417 | } | 417 | } |
| 418 | arch_initcall_sync(arm64_device_init); | 418 | arch_initcall_sync(arm64_device_init); |
| 419 | 419 | ||
| 420 | static DEFINE_PER_CPU(struct cpu, cpu_data); | ||
| 421 | |||
| 422 | static int __init topology_init(void) | 420 | static int __init topology_init(void) |
| 423 | { | 421 | { |
| 424 | int i; | 422 | int i; |
| 425 | 423 | ||
| 426 | for_each_possible_cpu(i) { | 424 | for_each_possible_cpu(i) { |
| 427 | struct cpu *cpu = &per_cpu(cpu_data, i); | 425 | struct cpu *cpu = &per_cpu(cpu_data.cpu, i); |
| 428 | cpu->hotpluggable = 1; | 426 | cpu->hotpluggable = 1; |
| 429 | register_cpu(cpu, i); | 427 | register_cpu(cpu, i); |
| 430 | } | 428 | } |
| @@ -449,10 +447,21 @@ static int c_show(struct seq_file *m, void *v) | |||
| 449 | { | 447 | { |
| 450 | int i; | 448 | int i; |
| 451 | 449 | ||
| 452 | seq_printf(m, "Processor\t: %s rev %d (%s)\n", | 450 | /* |
| 453 | cpu_name, read_cpuid_id() & 15, ELF_PLATFORM); | 451 | * Dump out the common processor features in a single line. Userspace |
| 452 | * should read the hwcaps with getauxval(AT_HWCAP) rather than | ||
| 453 | * attempting to parse this. | ||
| 454 | */ | ||
| 455 | seq_puts(m, "features\t:"); | ||
| 456 | for (i = 0; hwcap_str[i]; i++) | ||
| 457 | if (elf_hwcap & (1 << i)) | ||
| 458 | seq_printf(m, " %s", hwcap_str[i]); | ||
| 459 | seq_puts(m, "\n\n"); | ||
| 454 | 460 | ||
| 455 | for_each_online_cpu(i) { | 461 | for_each_online_cpu(i) { |
| 462 | struct cpuinfo_arm64 *cpuinfo = &per_cpu(cpu_data, i); | ||
| 463 | u32 midr = cpuinfo->reg_midr; | ||
| 464 | |||
| 456 | /* | 465 | /* |
| 457 | * glibc reads /proc/cpuinfo to determine the number of | 466 | * glibc reads /proc/cpuinfo to determine the number of |
| 458 | * online processors, looking for lines beginning with | 467 | * online processors, looking for lines beginning with |
| @@ -461,25 +470,13 @@ static int c_show(struct seq_file *m, void *v) | |||
| 461 | #ifdef CONFIG_SMP | 470 | #ifdef CONFIG_SMP |
| 462 | seq_printf(m, "processor\t: %d\n", i); | 471 | seq_printf(m, "processor\t: %d\n", i); |
| 463 | #endif | 472 | #endif |
| 473 | seq_printf(m, "implementer\t: 0x%02x\n", | ||
| 474 | MIDR_IMPLEMENTOR(midr)); | ||
| 475 | seq_printf(m, "variant\t\t: 0x%x\n", MIDR_VARIANT(midr)); | ||
| 476 | seq_printf(m, "partnum\t\t: 0x%03x\n", MIDR_PARTNUM(midr)); | ||
| 477 | seq_printf(m, "revision\t: 0x%x\n\n", MIDR_REVISION(midr)); | ||
| 464 | } | 478 | } |
| 465 | 479 | ||
| 466 | /* dump out the processor features */ | ||
| 467 | seq_puts(m, "Features\t: "); | ||
| 468 | |||
| 469 | for (i = 0; hwcap_str[i]; i++) | ||
| 470 | if (elf_hwcap & (1 << i)) | ||
| 471 | seq_printf(m, "%s ", hwcap_str[i]); | ||
| 472 | |||
| 473 | seq_printf(m, "\nCPU implementer\t: 0x%02x\n", read_cpuid_id() >> 24); | ||
| 474 | seq_printf(m, "CPU architecture: AArch64\n"); | ||
| 475 | seq_printf(m, "CPU variant\t: 0x%x\n", (read_cpuid_id() >> 20) & 15); | ||
| 476 | seq_printf(m, "CPU part\t: 0x%03x\n", (read_cpuid_id() >> 4) & 0xfff); | ||
| 477 | seq_printf(m, "CPU revision\t: %d\n", read_cpuid_id() & 15); | ||
| 478 | |||
| 479 | seq_puts(m, "\n"); | ||
| 480 | |||
| 481 | seq_printf(m, "Hardware\t: %s\n", machine_name); | ||
| 482 | |||
| 483 | return 0; | 480 | return 0; |
| 484 | } | 481 | } |
| 485 | 482 | ||
diff --git a/arch/arm64/kernel/signal32.c b/arch/arm64/kernel/signal32.c index 3491c638f172..c5ee208321c3 100644 --- a/arch/arm64/kernel/signal32.c +++ b/arch/arm64/kernel/signal32.c | |||
| @@ -27,7 +27,7 @@ | |||
| 27 | #include <asm/fpsimd.h> | 27 | #include <asm/fpsimd.h> |
| 28 | #include <asm/signal32.h> | 28 | #include <asm/signal32.h> |
| 29 | #include <asm/uaccess.h> | 29 | #include <asm/uaccess.h> |
| 30 | #include <asm/unistd32.h> | 30 | #include <asm/unistd.h> |
| 31 | 31 | ||
| 32 | struct compat_sigcontext { | 32 | struct compat_sigcontext { |
| 33 | /* We always set these two fields to 0 */ | 33 | /* We always set these two fields to 0 */ |
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c index 40f38f46c8e0..3e2f5ebbf63e 100644 --- a/arch/arm64/kernel/smp.c +++ b/arch/arm64/kernel/smp.c | |||
| @@ -39,6 +39,7 @@ | |||
| 39 | 39 | ||
| 40 | #include <asm/atomic.h> | 40 | #include <asm/atomic.h> |
| 41 | #include <asm/cacheflush.h> | 41 | #include <asm/cacheflush.h> |
| 42 | #include <asm/cpu.h> | ||
| 42 | #include <asm/cputype.h> | 43 | #include <asm/cputype.h> |
| 43 | #include <asm/cpu_ops.h> | 44 | #include <asm/cpu_ops.h> |
| 44 | #include <asm/mmu_context.h> | 45 | #include <asm/mmu_context.h> |
| @@ -155,6 +156,11 @@ asmlinkage void secondary_start_kernel(void) | |||
| 155 | cpu_ops[cpu]->cpu_postboot(); | 156 | cpu_ops[cpu]->cpu_postboot(); |
| 156 | 157 | ||
| 157 | /* | 158 | /* |
| 159 | * Log the CPU info before it is marked online and might get read. | ||
| 160 | */ | ||
| 161 | cpuinfo_store_cpu(); | ||
| 162 | |||
| 163 | /* | ||
| 158 | * Enable GIC and timers. | 164 | * Enable GIC and timers. |
| 159 | */ | 165 | */ |
| 160 | notify_cpu_starting(cpu); | 166 | notify_cpu_starting(cpu); |
diff --git a/arch/arm64/kernel/suspend.c b/arch/arm64/kernel/suspend.c index 1fa9ce4afd8f..55a99b9a97e0 100644 --- a/arch/arm64/kernel/suspend.c +++ b/arch/arm64/kernel/suspend.c | |||
| @@ -119,7 +119,7 @@ int cpu_suspend(unsigned long arg) | |||
| 119 | extern struct sleep_save_sp sleep_save_sp; | 119 | extern struct sleep_save_sp sleep_save_sp; |
| 120 | extern phys_addr_t sleep_idmap_phys; | 120 | extern phys_addr_t sleep_idmap_phys; |
| 121 | 121 | ||
| 122 | static int cpu_suspend_init(void) | 122 | static int __init cpu_suspend_init(void) |
| 123 | { | 123 | { |
| 124 | void *ctx_ptr; | 124 | void *ctx_ptr; |
| 125 | 125 | ||
diff --git a/arch/arm64/kernel/sys_compat.c b/arch/arm64/kernel/sys_compat.c index 26e9c4eeaba8..de2b0226e06d 100644 --- a/arch/arm64/kernel/sys_compat.c +++ b/arch/arm64/kernel/sys_compat.c | |||
| @@ -26,7 +26,7 @@ | |||
| 26 | #include <linux/uaccess.h> | 26 | #include <linux/uaccess.h> |
| 27 | 27 | ||
| 28 | #include <asm/cacheflush.h> | 28 | #include <asm/cacheflush.h> |
| 29 | #include <asm/unistd32.h> | 29 | #include <asm/unistd.h> |
| 30 | 30 | ||
| 31 | static inline void | 31 | static inline void |
| 32 | do_compat_cache_op(unsigned long start, unsigned long end, int flags) | 32 | do_compat_cache_op(unsigned long start, unsigned long end, int flags) |
diff --git a/arch/arm64/kernel/topology.c b/arch/arm64/kernel/topology.c index 43514f905916..b6ee26b0939a 100644 --- a/arch/arm64/kernel/topology.c +++ b/arch/arm64/kernel/topology.c | |||
| @@ -20,6 +20,7 @@ | |||
| 20 | #include <linux/of.h> | 20 | #include <linux/of.h> |
| 21 | #include <linux/sched.h> | 21 | #include <linux/sched.h> |
| 22 | 22 | ||
| 23 | #include <asm/cputype.h> | ||
| 23 | #include <asm/topology.h> | 24 | #include <asm/topology.h> |
| 24 | 25 | ||
| 25 | static int __init get_cpu_for_node(struct device_node *node) | 26 | static int __init get_cpu_for_node(struct device_node *node) |
| @@ -188,13 +189,9 @@ static int __init parse_dt_topology(void) | |||
| 188 | * Check that all cores are in the topology; the SMP code will | 189 | * Check that all cores are in the topology; the SMP code will |
| 189 | * only mark cores described in the DT as possible. | 190 | * only mark cores described in the DT as possible. |
| 190 | */ | 191 | */ |
| 191 | for_each_possible_cpu(cpu) { | 192 | for_each_possible_cpu(cpu) |
| 192 | if (cpu_topology[cpu].cluster_id == -1) { | 193 | if (cpu_topology[cpu].cluster_id == -1) |
| 193 | pr_err("CPU%d: No topology information specified\n", | ||
| 194 | cpu); | ||
| 195 | ret = -EINVAL; | 194 | ret = -EINVAL; |
| 196 | } | ||
| 197 | } | ||
| 198 | 195 | ||
| 199 | out_map: | 196 | out_map: |
| 200 | of_node_put(map); | 197 | of_node_put(map); |
| @@ -219,14 +216,6 @@ static void update_siblings_masks(unsigned int cpuid) | |||
| 219 | struct cpu_topology *cpu_topo, *cpuid_topo = &cpu_topology[cpuid]; | 216 | struct cpu_topology *cpu_topo, *cpuid_topo = &cpu_topology[cpuid]; |
| 220 | int cpu; | 217 | int cpu; |
| 221 | 218 | ||
| 222 | if (cpuid_topo->cluster_id == -1) { | ||
| 223 | /* | ||
| 224 | * DT does not contain topology information for this cpu. | ||
| 225 | */ | ||
| 226 | pr_debug("CPU%u: No topology information configured\n", cpuid); | ||
| 227 | return; | ||
| 228 | } | ||
| 229 | |||
| 230 | /* update core and thread sibling masks */ | 219 | /* update core and thread sibling masks */ |
| 231 | for_each_possible_cpu(cpu) { | 220 | for_each_possible_cpu(cpu) { |
| 232 | cpu_topo = &cpu_topology[cpu]; | 221 | cpu_topo = &cpu_topology[cpu]; |
| @@ -249,6 +238,36 @@ static void update_siblings_masks(unsigned int cpuid) | |||
| 249 | 238 | ||
| 250 | void store_cpu_topology(unsigned int cpuid) | 239 | void store_cpu_topology(unsigned int cpuid) |
| 251 | { | 240 | { |
| 241 | struct cpu_topology *cpuid_topo = &cpu_topology[cpuid]; | ||
| 242 | u64 mpidr; | ||
| 243 | |||
| 244 | if (cpuid_topo->cluster_id != -1) | ||
| 245 | goto topology_populated; | ||
| 246 | |||
| 247 | mpidr = read_cpuid_mpidr(); | ||
| 248 | |||
| 249 | /* Uniprocessor systems can rely on default topology values */ | ||
| 250 | if (mpidr & MPIDR_UP_BITMASK) | ||
| 251 | return; | ||
| 252 | |||
| 253 | /* Create cpu topology mapping based on MPIDR. */ | ||
| 254 | if (mpidr & MPIDR_MT_BITMASK) { | ||
| 255 | /* Multiprocessor system : Multi-threads per core */ | ||
| 256 | cpuid_topo->thread_id = MPIDR_AFFINITY_LEVEL(mpidr, 0); | ||
| 257 | cpuid_topo->core_id = MPIDR_AFFINITY_LEVEL(mpidr, 1); | ||
| 258 | cpuid_topo->cluster_id = MPIDR_AFFINITY_LEVEL(mpidr, 2); | ||
| 259 | } else { | ||
| 260 | /* Multiprocessor system : Single-thread per core */ | ||
| 261 | cpuid_topo->thread_id = -1; | ||
| 262 | cpuid_topo->core_id = MPIDR_AFFINITY_LEVEL(mpidr, 0); | ||
| 263 | cpuid_topo->cluster_id = MPIDR_AFFINITY_LEVEL(mpidr, 1); | ||
| 264 | } | ||
| 265 | |||
| 266 | pr_debug("CPU%u: cluster %d core %d thread %d mpidr %#016llx\n", | ||
| 267 | cpuid, cpuid_topo->cluster_id, cpuid_topo->core_id, | ||
| 268 | cpuid_topo->thread_id, mpidr); | ||
| 269 | |||
| 270 | topology_populated: | ||
| 252 | update_siblings_masks(cpuid); | 271 | update_siblings_masks(cpuid); |
| 253 | } | 272 | } |
| 254 | 273 | ||
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c index c43cfa9b8304..02cd3f023e9a 100644 --- a/arch/arm64/kernel/traps.c +++ b/arch/arm64/kernel/traps.c | |||
| @@ -156,7 +156,7 @@ static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk) | |||
| 156 | frame.pc = thread_saved_pc(tsk); | 156 | frame.pc = thread_saved_pc(tsk); |
| 157 | } | 157 | } |
| 158 | 158 | ||
| 159 | printk("Call trace:\n"); | 159 | pr_emerg("Call trace:\n"); |
| 160 | while (1) { | 160 | while (1) { |
| 161 | unsigned long where = frame.pc; | 161 | unsigned long where = frame.pc; |
| 162 | int ret; | 162 | int ret; |
| @@ -331,17 +331,22 @@ asmlinkage void bad_mode(struct pt_regs *regs, int reason, unsigned int esr) | |||
| 331 | 331 | ||
| 332 | void __pte_error(const char *file, int line, unsigned long val) | 332 | void __pte_error(const char *file, int line, unsigned long val) |
| 333 | { | 333 | { |
| 334 | printk("%s:%d: bad pte %016lx.\n", file, line, val); | 334 | pr_crit("%s:%d: bad pte %016lx.\n", file, line, val); |
| 335 | } | 335 | } |
| 336 | 336 | ||
| 337 | void __pmd_error(const char *file, int line, unsigned long val) | 337 | void __pmd_error(const char *file, int line, unsigned long val) |
| 338 | { | 338 | { |
| 339 | printk("%s:%d: bad pmd %016lx.\n", file, line, val); | 339 | pr_crit("%s:%d: bad pmd %016lx.\n", file, line, val); |
| 340 | } | ||
| 341 | |||
| 342 | void __pud_error(const char *file, int line, unsigned long val) | ||
| 343 | { | ||
| 344 | pr_crit("%s:%d: bad pud %016lx.\n", file, line, val); | ||
| 340 | } | 345 | } |
| 341 | 346 | ||
| 342 | void __pgd_error(const char *file, int line, unsigned long val) | 347 | void __pgd_error(const char *file, int line, unsigned long val) |
| 343 | { | 348 | { |
| 344 | printk("%s:%d: bad pgd %016lx.\n", file, line, val); | 349 | pr_crit("%s:%d: bad pgd %016lx.\n", file, line, val); |
| 345 | } | 350 | } |
| 346 | 351 | ||
| 347 | void __init trap_init(void) | 352 | void __init trap_init(void) |
diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c index 50384fec56c4..24f2e8c62479 100644 --- a/arch/arm64/kernel/vdso.c +++ b/arch/arm64/kernel/vdso.c | |||
| @@ -88,22 +88,29 @@ int aarch32_setup_vectors_page(struct linux_binprm *bprm, int uses_interp) | |||
| 88 | { | 88 | { |
| 89 | struct mm_struct *mm = current->mm; | 89 | struct mm_struct *mm = current->mm; |
| 90 | unsigned long addr = AARCH32_VECTORS_BASE; | 90 | unsigned long addr = AARCH32_VECTORS_BASE; |
| 91 | int ret; | 91 | static struct vm_special_mapping spec = { |
| 92 | .name = "[vectors]", | ||
| 93 | .pages = vectors_page, | ||
| 94 | |||
| 95 | }; | ||
| 96 | void *ret; | ||
| 92 | 97 | ||
| 93 | down_write(&mm->mmap_sem); | 98 | down_write(&mm->mmap_sem); |
| 94 | current->mm->context.vdso = (void *)addr; | 99 | current->mm->context.vdso = (void *)addr; |
| 95 | 100 | ||
| 96 | /* Map vectors page at the high address. */ | 101 | /* Map vectors page at the high address. */ |
| 97 | ret = install_special_mapping(mm, addr, PAGE_SIZE, | 102 | ret = _install_special_mapping(mm, addr, PAGE_SIZE, |
| 98 | VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYEXEC, | 103 | VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYEXEC, |
| 99 | vectors_page); | 104 | &spec); |
| 100 | 105 | ||
| 101 | up_write(&mm->mmap_sem); | 106 | up_write(&mm->mmap_sem); |
| 102 | 107 | ||
| 103 | return ret; | 108 | return PTR_ERR_OR_ZERO(ret); |
| 104 | } | 109 | } |
| 105 | #endif /* CONFIG_COMPAT */ | 110 | #endif /* CONFIG_COMPAT */ |
| 106 | 111 | ||
| 112 | static struct vm_special_mapping vdso_spec[2]; | ||
| 113 | |||
| 107 | static int __init vdso_init(void) | 114 | static int __init vdso_init(void) |
| 108 | { | 115 | { |
| 109 | int i; | 116 | int i; |
| @@ -114,8 +121,8 @@ static int __init vdso_init(void) | |||
| 114 | } | 121 | } |
| 115 | 122 | ||
| 116 | vdso_pages = (&vdso_end - &vdso_start) >> PAGE_SHIFT; | 123 | vdso_pages = (&vdso_end - &vdso_start) >> PAGE_SHIFT; |
| 117 | pr_info("vdso: %ld pages (%ld code, %ld data) at base %p\n", | 124 | pr_info("vdso: %ld pages (%ld code @ %p, %ld data @ %p)\n", |
| 118 | vdso_pages + 1, vdso_pages, 1L, &vdso_start); | 125 | vdso_pages + 1, vdso_pages, &vdso_start, 1L, vdso_data); |
| 119 | 126 | ||
| 120 | /* Allocate the vDSO pagelist, plus a page for the data. */ | 127 | /* Allocate the vDSO pagelist, plus a page for the data. */ |
| 121 | vdso_pagelist = kcalloc(vdso_pages + 1, sizeof(struct page *), | 128 | vdso_pagelist = kcalloc(vdso_pages + 1, sizeof(struct page *), |
| @@ -123,12 +130,23 @@ static int __init vdso_init(void) | |||
| 123 | if (vdso_pagelist == NULL) | 130 | if (vdso_pagelist == NULL) |
| 124 | return -ENOMEM; | 131 | return -ENOMEM; |
| 125 | 132 | ||
| 133 | /* Grab the vDSO data page. */ | ||
| 134 | vdso_pagelist[0] = virt_to_page(vdso_data); | ||
| 135 | |||
| 126 | /* Grab the vDSO code pages. */ | 136 | /* Grab the vDSO code pages. */ |
| 127 | for (i = 0; i < vdso_pages; i++) | 137 | for (i = 0; i < vdso_pages; i++) |
| 128 | vdso_pagelist[i] = virt_to_page(&vdso_start + i * PAGE_SIZE); | 138 | vdso_pagelist[i + 1] = virt_to_page(&vdso_start + i * PAGE_SIZE); |
| 129 | 139 | ||
| 130 | /* Grab the vDSO data page. */ | 140 | /* Populate the special mapping structures */ |
| 131 | vdso_pagelist[i] = virt_to_page(vdso_data); | 141 | vdso_spec[0] = (struct vm_special_mapping) { |
| 142 | .name = "[vvar]", | ||
| 143 | .pages = vdso_pagelist, | ||
| 144 | }; | ||
| 145 | |||
| 146 | vdso_spec[1] = (struct vm_special_mapping) { | ||
| 147 | .name = "[vdso]", | ||
| 148 | .pages = &vdso_pagelist[1], | ||
| 149 | }; | ||
| 132 | 150 | ||
| 133 | return 0; | 151 | return 0; |
| 134 | } | 152 | } |
| @@ -138,52 +156,42 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, | |||
| 138 | int uses_interp) | 156 | int uses_interp) |
| 139 | { | 157 | { |
| 140 | struct mm_struct *mm = current->mm; | 158 | struct mm_struct *mm = current->mm; |
| 141 | unsigned long vdso_base, vdso_mapping_len; | 159 | unsigned long vdso_base, vdso_text_len, vdso_mapping_len; |
| 142 | int ret; | 160 | void *ret; |
| 143 | 161 | ||
| 162 | vdso_text_len = vdso_pages << PAGE_SHIFT; | ||
| 144 | /* Be sure to map the data page */ | 163 | /* Be sure to map the data page */ |
| 145 | vdso_mapping_len = (vdso_pages + 1) << PAGE_SHIFT; | 164 | vdso_mapping_len = vdso_text_len + PAGE_SIZE; |
| 146 | 165 | ||
| 147 | down_write(&mm->mmap_sem); | 166 | down_write(&mm->mmap_sem); |
| 148 | vdso_base = get_unmapped_area(NULL, 0, vdso_mapping_len, 0, 0); | 167 | vdso_base = get_unmapped_area(NULL, 0, vdso_mapping_len, 0, 0); |
| 149 | if (IS_ERR_VALUE(vdso_base)) { | 168 | if (IS_ERR_VALUE(vdso_base)) { |
| 150 | ret = vdso_base; | 169 | ret = ERR_PTR(vdso_base); |
| 151 | goto up_fail; | 170 | goto up_fail; |
| 152 | } | 171 | } |
| 153 | mm->context.vdso = (void *)vdso_base; | 172 | ret = _install_special_mapping(mm, vdso_base, PAGE_SIZE, |
| 154 | 173 | VM_READ|VM_MAYREAD, | |
| 155 | ret = install_special_mapping(mm, vdso_base, vdso_mapping_len, | 174 | &vdso_spec[0]); |
| 156 | VM_READ|VM_EXEC| | 175 | if (IS_ERR(ret)) |
| 157 | VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC, | ||
| 158 | vdso_pagelist); | ||
| 159 | if (ret) { | ||
| 160 | mm->context.vdso = NULL; | ||
| 161 | goto up_fail; | 176 | goto up_fail; |
| 162 | } | ||
| 163 | 177 | ||
| 164 | up_fail: | 178 | vdso_base += PAGE_SIZE; |
| 165 | up_write(&mm->mmap_sem); | 179 | mm->context.vdso = (void *)vdso_base; |
| 180 | ret = _install_special_mapping(mm, vdso_base, vdso_text_len, | ||
| 181 | VM_READ|VM_EXEC| | ||
| 182 | VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC, | ||
| 183 | &vdso_spec[1]); | ||
| 184 | if (IS_ERR(ret)) | ||
| 185 | goto up_fail; | ||
| 166 | 186 | ||
| 167 | return ret; | ||
| 168 | } | ||
| 169 | 187 | ||
| 170 | const char *arch_vma_name(struct vm_area_struct *vma) | 188 | up_write(&mm->mmap_sem); |
| 171 | { | 189 | return 0; |
| 172 | /* | ||
| 173 | * We can re-use the vdso pointer in mm_context_t for identifying | ||
| 174 | * the vectors page for compat applications. The vDSO will always | ||
| 175 | * sit above TASK_UNMAPPED_BASE and so we don't need to worry about | ||
| 176 | * it conflicting with the vectors base. | ||
| 177 | */ | ||
| 178 | if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso) { | ||
| 179 | #ifdef CONFIG_COMPAT | ||
| 180 | if (vma->vm_start == AARCH32_VECTORS_BASE) | ||
| 181 | return "[vectors]"; | ||
| 182 | #endif | ||
| 183 | return "[vdso]"; | ||
| 184 | } | ||
| 185 | 190 | ||
| 186 | return NULL; | 191 | up_fail: |
| 192 | mm->context.vdso = NULL; | ||
| 193 | up_write(&mm->mmap_sem); | ||
| 194 | return PTR_ERR(ret); | ||
| 187 | } | 195 | } |
| 188 | 196 | ||
| 189 | /* | 197 | /* |
diff --git a/arch/arm64/kernel/vdso/Makefile b/arch/arm64/kernel/vdso/Makefile index 6d20b7d162d8..ff3bddea482d 100644 --- a/arch/arm64/kernel/vdso/Makefile +++ b/arch/arm64/kernel/vdso/Makefile | |||
| @@ -43,13 +43,13 @@ $(obj)/vdso-offsets.h: $(obj)/vdso.so.dbg FORCE | |||
| 43 | $(call if_changed,vdsosym) | 43 | $(call if_changed,vdsosym) |
| 44 | 44 | ||
| 45 | # Assembly rules for the .S files | 45 | # Assembly rules for the .S files |
| 46 | $(obj-vdso): %.o: %.S | 46 | $(obj-vdso): %.o: %.S FORCE |
| 47 | $(call if_changed_dep,vdsoas) | 47 | $(call if_changed_dep,vdsoas) |
| 48 | 48 | ||
| 49 | # Actual build commands | 49 | # Actual build commands |
| 50 | quiet_cmd_vdsold = VDSOL $@ | 50 | quiet_cmd_vdsold = VDSOL $@ |
| 51 | cmd_vdsold = $(CC) $(c_flags) -Wl,-n -Wl,-T $^ -o $@ | 51 | cmd_vdsold = $(CC) $(c_flags) -Wl,-n -Wl,-T $^ -o $@ |
| 52 | quiet_cmd_vdsoas = VDSOA $@ | 52 | quiet_cmd_vdsoas = VDSOA $@ |
| 53 | cmd_vdsoas = $(CC) $(a_flags) -c -o $@ $< | 53 | cmd_vdsoas = $(CC) $(a_flags) -c -o $@ $< |
| 54 | 54 | ||
| 55 | # Install commands for the unstripped file | 55 | # Install commands for the unstripped file |
diff --git a/arch/arm64/kernel/vdso/vdso.lds.S b/arch/arm64/kernel/vdso/vdso.lds.S index 8154b8d1c826..beca249bc2f3 100644 --- a/arch/arm64/kernel/vdso/vdso.lds.S +++ b/arch/arm64/kernel/vdso/vdso.lds.S | |||
| @@ -28,6 +28,7 @@ OUTPUT_ARCH(aarch64) | |||
| 28 | 28 | ||
| 29 | SECTIONS | 29 | SECTIONS |
| 30 | { | 30 | { |
| 31 | PROVIDE(_vdso_data = . - PAGE_SIZE); | ||
| 31 | . = VDSO_LBASE + SIZEOF_HEADERS; | 32 | . = VDSO_LBASE + SIZEOF_HEADERS; |
| 32 | 33 | ||
| 33 | .hash : { *(.hash) } :text | 34 | .hash : { *(.hash) } :text |
| @@ -57,9 +58,6 @@ SECTIONS | |||
| 57 | _end = .; | 58 | _end = .; |
| 58 | PROVIDE(end = .); | 59 | PROVIDE(end = .); |
| 59 | 60 | ||
| 60 | . = ALIGN(PAGE_SIZE); | ||
| 61 | PROVIDE(_vdso_data = .); | ||
| 62 | |||
| 63 | /DISCARD/ : { | 61 | /DISCARD/ : { |
| 64 | *(.note.GNU-stack) | 62 | *(.note.GNU-stack) |
| 65 | *(.data .data.* .gnu.linkonce.d.* .sdata*) | 63 | *(.data .data.* .gnu.linkonce.d.* .sdata*) |
diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S index f1e6d5c032e1..97f0c0429dfa 100644 --- a/arch/arm64/kernel/vmlinux.lds.S +++ b/arch/arm64/kernel/vmlinux.lds.S | |||
| @@ -9,6 +9,8 @@ | |||
| 9 | #include <asm/memory.h> | 9 | #include <asm/memory.h> |
| 10 | #include <asm/page.h> | 10 | #include <asm/page.h> |
| 11 | 11 | ||
| 12 | #include "image.h" | ||
| 13 | |||
| 12 | #define ARM_EXIT_KEEP(x) | 14 | #define ARM_EXIT_KEEP(x) |
| 13 | #define ARM_EXIT_DISCARD(x) x | 15 | #define ARM_EXIT_DISCARD(x) x |
| 14 | 16 | ||
| @@ -104,9 +106,18 @@ SECTIONS | |||
| 104 | _edata = .; | 106 | _edata = .; |
| 105 | 107 | ||
| 106 | BSS_SECTION(0, 0, 0) | 108 | BSS_SECTION(0, 0, 0) |
| 109 | |||
| 110 | . = ALIGN(PAGE_SIZE); | ||
| 111 | idmap_pg_dir = .; | ||
| 112 | . += IDMAP_DIR_SIZE; | ||
| 113 | swapper_pg_dir = .; | ||
| 114 | . += SWAPPER_DIR_SIZE; | ||
| 115 | |||
| 107 | _end = .; | 116 | _end = .; |
| 108 | 117 | ||
| 109 | STABS_DEBUG | 118 | STABS_DEBUG |
| 119 | |||
| 120 | HEAD_SYMBOLS | ||
| 110 | } | 121 | } |
| 111 | 122 | ||
| 112 | /* | 123 | /* |
| @@ -114,3 +125,8 @@ SECTIONS | |||
| 114 | */ | 125 | */ |
| 115 | ASSERT(((__hyp_idmap_text_start + PAGE_SIZE) > __hyp_idmap_text_end), | 126 | ASSERT(((__hyp_idmap_text_start + PAGE_SIZE) > __hyp_idmap_text_end), |
| 116 | "HYP init code too big") | 127 | "HYP init code too big") |
| 128 | |||
| 129 | /* | ||
| 130 | * If padding is applied before .head.text, virt<->phys conversions will fail. | ||
| 131 | */ | ||
| 132 | ASSERT(_text == (PAGE_OFFSET + TEXT_OFFSET), "HEAD is misaligned") | ||
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c index bcc965e2cce1..41cb6d3d6075 100644 --- a/arch/arm64/mm/fault.c +++ b/arch/arm64/mm/fault.c | |||
| @@ -62,6 +62,7 @@ void show_pte(struct mm_struct *mm, unsigned long addr) | |||
| 62 | break; | 62 | break; |
| 63 | 63 | ||
| 64 | pud = pud_offset(pgd, addr); | 64 | pud = pud_offset(pgd, addr); |
| 65 | printk(", *pud=%016llx", pud_val(*pud)); | ||
| 65 | if (pud_none(*pud) || pud_bad(*pud)) | 66 | if (pud_none(*pud) || pud_bad(*pud)) |
| 66 | break; | 67 | break; |
| 67 | 68 | ||
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c index e90c5426fe14..5b4526ee3a01 100644 --- a/arch/arm64/mm/init.c +++ b/arch/arm64/mm/init.c | |||
| @@ -33,6 +33,7 @@ | |||
| 33 | #include <linux/dma-mapping.h> | 33 | #include <linux/dma-mapping.h> |
| 34 | #include <linux/dma-contiguous.h> | 34 | #include <linux/dma-contiguous.h> |
| 35 | 35 | ||
| 36 | #include <asm/fixmap.h> | ||
| 36 | #include <asm/sections.h> | 37 | #include <asm/sections.h> |
| 37 | #include <asm/setup.h> | 38 | #include <asm/setup.h> |
| 38 | #include <asm/sizes.h> | 39 | #include <asm/sizes.h> |
| @@ -137,20 +138,16 @@ void __init arm64_memblock_init(void) | |||
| 137 | { | 138 | { |
| 138 | phys_addr_t dma_phys_limit = 0; | 139 | phys_addr_t dma_phys_limit = 0; |
| 139 | 140 | ||
| 140 | /* Register the kernel text, kernel data and initrd with memblock */ | 141 | /* |
| 142 | * Register the kernel text, kernel data, initrd, and initial | ||
| 143 | * pagetables with memblock. | ||
| 144 | */ | ||
| 141 | memblock_reserve(__pa(_text), _end - _text); | 145 | memblock_reserve(__pa(_text), _end - _text); |
| 142 | #ifdef CONFIG_BLK_DEV_INITRD | 146 | #ifdef CONFIG_BLK_DEV_INITRD |
| 143 | if (initrd_start) | 147 | if (initrd_start) |
| 144 | memblock_reserve(__virt_to_phys(initrd_start), initrd_end - initrd_start); | 148 | memblock_reserve(__virt_to_phys(initrd_start), initrd_end - initrd_start); |
| 145 | #endif | 149 | #endif |
| 146 | 150 | ||
| 147 | /* | ||
| 148 | * Reserve the page tables. These are already in use, | ||
| 149 | * and can only be in node 0. | ||
| 150 | */ | ||
| 151 | memblock_reserve(__pa(swapper_pg_dir), SWAPPER_DIR_SIZE); | ||
| 152 | memblock_reserve(__pa(idmap_pg_dir), IDMAP_DIR_SIZE); | ||
| 153 | |||
| 154 | early_init_fdt_scan_reserved_mem(); | 151 | early_init_fdt_scan_reserved_mem(); |
| 155 | 152 | ||
| 156 | /* 4GB maximum for 32-bit only capable devices */ | 153 | /* 4GB maximum for 32-bit only capable devices */ |
| @@ -269,26 +266,33 @@ void __init mem_init(void) | |||
| 269 | 266 | ||
| 270 | #define MLK(b, t) b, t, ((t) - (b)) >> 10 | 267 | #define MLK(b, t) b, t, ((t) - (b)) >> 10 |
| 271 | #define MLM(b, t) b, t, ((t) - (b)) >> 20 | 268 | #define MLM(b, t) b, t, ((t) - (b)) >> 20 |
| 269 | #define MLG(b, t) b, t, ((t) - (b)) >> 30 | ||
| 272 | #define MLK_ROUNDUP(b, t) b, t, DIV_ROUND_UP(((t) - (b)), SZ_1K) | 270 | #define MLK_ROUNDUP(b, t) b, t, DIV_ROUND_UP(((t) - (b)), SZ_1K) |
| 273 | 271 | ||
| 274 | pr_notice("Virtual kernel memory layout:\n" | 272 | pr_notice("Virtual kernel memory layout:\n" |
| 275 | " vmalloc : 0x%16lx - 0x%16lx (%6ld MB)\n" | 273 | " vmalloc : 0x%16lx - 0x%16lx (%6ld GB)\n" |
| 276 | #ifdef CONFIG_SPARSEMEM_VMEMMAP | 274 | #ifdef CONFIG_SPARSEMEM_VMEMMAP |
| 277 | " vmemmap : 0x%16lx - 0x%16lx (%6ld MB)\n" | 275 | " vmemmap : 0x%16lx - 0x%16lx (%6ld GB maximum)\n" |
| 276 | " 0x%16lx - 0x%16lx (%6ld MB actual)\n" | ||
| 278 | #endif | 277 | #endif |
| 278 | " PCI I/O : 0x%16lx - 0x%16lx (%6ld MB)\n" | ||
| 279 | " fixed : 0x%16lx - 0x%16lx (%6ld KB)\n" | ||
| 279 | " modules : 0x%16lx - 0x%16lx (%6ld MB)\n" | 280 | " modules : 0x%16lx - 0x%16lx (%6ld MB)\n" |
| 280 | " memory : 0x%16lx - 0x%16lx (%6ld MB)\n" | 281 | " memory : 0x%16lx - 0x%16lx (%6ld MB)\n" |
| 281 | " .init : 0x%p" " - 0x%p" " (%6ld kB)\n" | 282 | " .init : 0x%p" " - 0x%p" " (%6ld KB)\n" |
| 282 | " .text : 0x%p" " - 0x%p" " (%6ld kB)\n" | 283 | " .text : 0x%p" " - 0x%p" " (%6ld KB)\n" |
| 283 | " .data : 0x%p" " - 0x%p" " (%6ld kB)\n", | 284 | " .data : 0x%p" " - 0x%p" " (%6ld KB)\n", |
| 284 | MLM(VMALLOC_START, VMALLOC_END), | 285 | MLG(VMALLOC_START, VMALLOC_END), |
| 285 | #ifdef CONFIG_SPARSEMEM_VMEMMAP | 286 | #ifdef CONFIG_SPARSEMEM_VMEMMAP |
| 287 | MLG((unsigned long)vmemmap, | ||
| 288 | (unsigned long)vmemmap + VMEMMAP_SIZE), | ||
| 286 | MLM((unsigned long)virt_to_page(PAGE_OFFSET), | 289 | MLM((unsigned long)virt_to_page(PAGE_OFFSET), |
| 287 | (unsigned long)virt_to_page(high_memory)), | 290 | (unsigned long)virt_to_page(high_memory)), |
| 288 | #endif | 291 | #endif |
| 292 | MLM((unsigned long)PCI_IOBASE, (unsigned long)PCI_IOBASE + SZ_16M), | ||
| 293 | MLK(FIXADDR_START, FIXADDR_TOP), | ||
| 289 | MLM(MODULES_VADDR, MODULES_END), | 294 | MLM(MODULES_VADDR, MODULES_END), |
| 290 | MLM(PAGE_OFFSET, (unsigned long)high_memory), | 295 | MLM(PAGE_OFFSET, (unsigned long)high_memory), |
| 291 | |||
| 292 | MLK_ROUNDUP(__init_begin, __init_end), | 296 | MLK_ROUNDUP(__init_begin, __init_end), |
| 293 | MLK_ROUNDUP(_text, _etext), | 297 | MLK_ROUNDUP(_text, _etext), |
| 294 | MLK_ROUNDUP(_sdata, _edata)); | 298 | MLK_ROUNDUP(_sdata, _edata)); |
diff --git a/arch/arm64/mm/ioremap.c b/arch/arm64/mm/ioremap.c index 7ec328392ae0..fa324bd5a5c4 100644 --- a/arch/arm64/mm/ioremap.c +++ b/arch/arm64/mm/ioremap.c | |||
| @@ -103,19 +103,28 @@ void __iomem *ioremap_cache(phys_addr_t phys_addr, size_t size) | |||
| 103 | } | 103 | } |
| 104 | EXPORT_SYMBOL(ioremap_cache); | 104 | EXPORT_SYMBOL(ioremap_cache); |
| 105 | 105 | ||
| 106 | #ifndef CONFIG_ARM64_64K_PAGES | ||
| 107 | static pte_t bm_pte[PTRS_PER_PTE] __page_aligned_bss; | 106 | static pte_t bm_pte[PTRS_PER_PTE] __page_aligned_bss; |
| 107 | #if CONFIG_ARM64_PGTABLE_LEVELS > 2 | ||
| 108 | static pte_t bm_pmd[PTRS_PER_PMD] __page_aligned_bss; | ||
| 109 | #endif | ||
| 110 | #if CONFIG_ARM64_PGTABLE_LEVELS > 3 | ||
| 111 | static pte_t bm_pud[PTRS_PER_PUD] __page_aligned_bss; | ||
| 108 | #endif | 112 | #endif |
| 109 | 113 | ||
| 110 | static inline pmd_t * __init early_ioremap_pmd(unsigned long addr) | 114 | static inline pud_t * __init early_ioremap_pud(unsigned long addr) |
| 111 | { | 115 | { |
| 112 | pgd_t *pgd; | 116 | pgd_t *pgd; |
| 113 | pud_t *pud; | ||
| 114 | 117 | ||
| 115 | pgd = pgd_offset_k(addr); | 118 | pgd = pgd_offset_k(addr); |
| 116 | BUG_ON(pgd_none(*pgd) || pgd_bad(*pgd)); | 119 | BUG_ON(pgd_none(*pgd) || pgd_bad(*pgd)); |
| 117 | 120 | ||
| 118 | pud = pud_offset(pgd, addr); | 121 | return pud_offset(pgd, addr); |
| 122 | } | ||
| 123 | |||
| 124 | static inline pmd_t * __init early_ioremap_pmd(unsigned long addr) | ||
| 125 | { | ||
| 126 | pud_t *pud = early_ioremap_pud(addr); | ||
| 127 | |||
| 119 | BUG_ON(pud_none(*pud) || pud_bad(*pud)); | 128 | BUG_ON(pud_none(*pud) || pud_bad(*pud)); |
| 120 | 129 | ||
| 121 | return pmd_offset(pud, addr); | 130 | return pmd_offset(pud, addr); |
| @@ -132,13 +141,18 @@ static inline pte_t * __init early_ioremap_pte(unsigned long addr) | |||
| 132 | 141 | ||
| 133 | void __init early_ioremap_init(void) | 142 | void __init early_ioremap_init(void) |
| 134 | { | 143 | { |
| 144 | pgd_t *pgd; | ||
| 145 | pud_t *pud; | ||
| 135 | pmd_t *pmd; | 146 | pmd_t *pmd; |
| 147 | unsigned long addr = fix_to_virt(FIX_BTMAP_BEGIN); | ||
| 136 | 148 | ||
| 137 | pmd = early_ioremap_pmd(fix_to_virt(FIX_BTMAP_BEGIN)); | 149 | pgd = pgd_offset_k(addr); |
| 138 | #ifndef CONFIG_ARM64_64K_PAGES | 150 | pgd_populate(&init_mm, pgd, bm_pud); |
| 139 | /* need to populate pmd for 4k pagesize only */ | 151 | pud = pud_offset(pgd, addr); |
| 152 | pud_populate(&init_mm, pud, bm_pmd); | ||
| 153 | pmd = pmd_offset(pud, addr); | ||
| 140 | pmd_populate_kernel(&init_mm, pmd, bm_pte); | 154 | pmd_populate_kernel(&init_mm, pmd, bm_pte); |
| 141 | #endif | 155 | |
| 142 | /* | 156 | /* |
| 143 | * The boot-ioremap range spans multiple pmds, for which | 157 | * The boot-ioremap range spans multiple pmds, for which |
| 144 | * we are not prepared: | 158 | * we are not prepared: |
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c index c43f1dd19489..c55567283cde 100644 --- a/arch/arm64/mm/mmu.c +++ b/arch/arm64/mm/mmu.c | |||
| @@ -32,6 +32,7 @@ | |||
| 32 | #include <asm/setup.h> | 32 | #include <asm/setup.h> |
| 33 | #include <asm/sizes.h> | 33 | #include <asm/sizes.h> |
| 34 | #include <asm/tlb.h> | 34 | #include <asm/tlb.h> |
| 35 | #include <asm/memblock.h> | ||
| 35 | #include <asm/mmu_context.h> | 36 | #include <asm/mmu_context.h> |
| 36 | 37 | ||
| 37 | #include "mm.h" | 38 | #include "mm.h" |
| @@ -204,9 +205,16 @@ static void __init alloc_init_pud(pgd_t *pgd, unsigned long addr, | |||
| 204 | unsigned long end, unsigned long phys, | 205 | unsigned long end, unsigned long phys, |
| 205 | int map_io) | 206 | int map_io) |
| 206 | { | 207 | { |
| 207 | pud_t *pud = pud_offset(pgd, addr); | 208 | pud_t *pud; |
| 208 | unsigned long next; | 209 | unsigned long next; |
| 209 | 210 | ||
| 211 | if (pgd_none(*pgd)) { | ||
| 212 | pud = early_alloc(PTRS_PER_PUD * sizeof(pud_t)); | ||
| 213 | pgd_populate(&init_mm, pgd, pud); | ||
| 214 | } | ||
| 215 | BUG_ON(pgd_bad(*pgd)); | ||
| 216 | |||
| 217 | pud = pud_offset(pgd, addr); | ||
| 210 | do { | 218 | do { |
| 211 | next = pud_addr_end(addr, end); | 219 | next = pud_addr_end(addr, end); |
| 212 | 220 | ||
| @@ -290,10 +298,10 @@ static void __init map_mem(void) | |||
| 290 | * memory addressable from the initial direct kernel mapping. | 298 | * memory addressable from the initial direct kernel mapping. |
| 291 | * | 299 | * |
| 292 | * The initial direct kernel mapping, located at swapper_pg_dir, | 300 | * The initial direct kernel mapping, located at swapper_pg_dir, |
| 293 | * gives us PGDIR_SIZE memory starting from PHYS_OFFSET (which must be | 301 | * gives us PUD_SIZE memory starting from PHYS_OFFSET (which must be |
| 294 | * aligned to 2MB as per Documentation/arm64/booting.txt). | 302 | * aligned to 2MB as per Documentation/arm64/booting.txt). |
| 295 | */ | 303 | */ |
| 296 | limit = PHYS_OFFSET + PGDIR_SIZE; | 304 | limit = PHYS_OFFSET + PUD_SIZE; |
| 297 | memblock_set_current_limit(limit); | 305 | memblock_set_current_limit(limit); |
| 298 | 306 | ||
| 299 | /* map all the memory banks */ | 307 | /* map all the memory banks */ |
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index bbb746e35500..7f0c2a30267b 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig | |||
| @@ -10,6 +10,11 @@ config ARM_GIC | |||
| 10 | config GIC_NON_BANKED | 10 | config GIC_NON_BANKED |
| 11 | bool | 11 | bool |
| 12 | 12 | ||
| 13 | config ARM_GIC_V3 | ||
| 14 | bool | ||
| 15 | select IRQ_DOMAIN | ||
| 16 | select MULTI_IRQ_HANDLER | ||
| 17 | |||
| 13 | config ARM_NVIC | 18 | config ARM_NVIC |
| 14 | bool | 19 | bool |
| 15 | select IRQ_DOMAIN | 20 | select IRQ_DOMAIN |
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index 62a13e5ef98f..c57e642700d4 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile | |||
| @@ -15,7 +15,8 @@ obj-$(CONFIG_ORION_IRQCHIP) += irq-orion.o | |||
| 15 | obj-$(CONFIG_ARCH_SUNXI) += irq-sun4i.o | 15 | obj-$(CONFIG_ARCH_SUNXI) += irq-sun4i.o |
| 16 | obj-$(CONFIG_ARCH_SUNXI) += irq-sunxi-nmi.o | 16 | obj-$(CONFIG_ARCH_SUNXI) += irq-sunxi-nmi.o |
| 17 | obj-$(CONFIG_ARCH_SPEAR3XX) += spear-shirq.o | 17 | obj-$(CONFIG_ARCH_SPEAR3XX) += spear-shirq.o |
| 18 | obj-$(CONFIG_ARM_GIC) += irq-gic.o | 18 | obj-$(CONFIG_ARM_GIC) += irq-gic.o irq-gic-common.o |
| 19 | obj-$(CONFIG_ARM_GIC_V3) += irq-gic-v3.o irq-gic-common.o | ||
| 19 | obj-$(CONFIG_ARM_NVIC) += irq-nvic.o | 20 | obj-$(CONFIG_ARM_NVIC) += irq-nvic.o |
| 20 | obj-$(CONFIG_ARM_VIC) += irq-vic.o | 21 | obj-$(CONFIG_ARM_VIC) += irq-vic.o |
| 21 | obj-$(CONFIG_IMGPDC_IRQ) += irq-imgpdc.o | 22 | obj-$(CONFIG_IMGPDC_IRQ) += irq-imgpdc.o |
diff --git a/drivers/irqchip/irq-gic-common.c b/drivers/irqchip/irq-gic-common.c new file mode 100644 index 000000000000..60ac704d2090 --- /dev/null +++ b/drivers/irqchip/irq-gic-common.c | |||
| @@ -0,0 +1,115 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2002 ARM Limited, All Rights Reserved. | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License version 2 as | ||
| 6 | * published by the Free Software Foundation. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License | ||
| 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 15 | */ | ||
| 16 | |||
| 17 | #include <linux/interrupt.h> | ||
| 18 | #include <linux/io.h> | ||
| 19 | #include <linux/irq.h> | ||
| 20 | #include <linux/irqchip/arm-gic.h> | ||
| 21 | |||
| 22 | #include "irq-gic-common.h" | ||
| 23 | |||
| 24 | void gic_configure_irq(unsigned int irq, unsigned int type, | ||
| 25 | void __iomem *base, void (*sync_access)(void)) | ||
| 26 | { | ||
| 27 | u32 enablemask = 1 << (irq % 32); | ||
| 28 | u32 enableoff = (irq / 32) * 4; | ||
| 29 | u32 confmask = 0x2 << ((irq % 16) * 2); | ||
| 30 | u32 confoff = (irq / 16) * 4; | ||
| 31 | bool enabled = false; | ||
| 32 | u32 val; | ||
| 33 | |||
| 34 | /* | ||
| 35 | * Read current configuration register, and insert the config | ||
| 36 | * for "irq", depending on "type". | ||
| 37 | */ | ||
| 38 | val = readl_relaxed(base + GIC_DIST_CONFIG + confoff); | ||
| 39 | if (type == IRQ_TYPE_LEVEL_HIGH) | ||
| 40 | val &= ~confmask; | ||
| 41 | else if (type == IRQ_TYPE_EDGE_RISING) | ||
| 42 | val |= confmask; | ||
| 43 | |||
| 44 | /* | ||
| 45 | * As recommended by the spec, disable the interrupt before changing | ||
| 46 | * the configuration | ||
| 47 | */ | ||
| 48 | if (readl_relaxed(base + GIC_DIST_ENABLE_SET + enableoff) & enablemask) { | ||
| 49 | writel_relaxed(enablemask, base + GIC_DIST_ENABLE_CLEAR + enableoff); | ||
| 50 | if (sync_access) | ||
| 51 | sync_access(); | ||
| 52 | enabled = true; | ||
| 53 | } | ||
| 54 | |||
| 55 | /* | ||
| 56 | * Write back the new configuration, and possibly re-enable | ||
| 57 | * the interrupt. | ||
| 58 | */ | ||
| 59 | writel_relaxed(val, base + GIC_DIST_CONFIG + confoff); | ||
| 60 | |||
| 61 | if (enabled) | ||
| 62 | writel_relaxed(enablemask, base + GIC_DIST_ENABLE_SET + enableoff); | ||
| 63 | |||
| 64 | if (sync_access) | ||
| 65 | sync_access(); | ||
| 66 | } | ||
| 67 | |||
| 68 | void __init gic_dist_config(void __iomem *base, int gic_irqs, | ||
| 69 | void (*sync_access)(void)) | ||
| 70 | { | ||
| 71 | unsigned int i; | ||
| 72 | |||
| 73 | /* | ||
| 74 | * Set all global interrupts to be level triggered, active low. | ||
| 75 | */ | ||
| 76 | for (i = 32; i < gic_irqs; i += 16) | ||
| 77 | writel_relaxed(0, base + GIC_DIST_CONFIG + i / 4); | ||
| 78 | |||
| 79 | /* | ||
| 80 | * Set priority on all global interrupts. | ||
| 81 | */ | ||
| 82 | for (i = 32; i < gic_irqs; i += 4) | ||
| 83 | writel_relaxed(0xa0a0a0a0, base + GIC_DIST_PRI + i); | ||
| 84 | |||
| 85 | /* | ||
| 86 | * Disable all interrupts. Leave the PPI and SGIs alone | ||
| 87 | * as they are enabled by redistributor registers. | ||
| 88 | */ | ||
| 89 | for (i = 32; i < gic_irqs; i += 32) | ||
| 90 | writel_relaxed(0xffffffff, base + GIC_DIST_ENABLE_CLEAR + i / 8); | ||
| 91 | |||
| 92 | if (sync_access) | ||
| 93 | sync_access(); | ||
| 94 | } | ||
| 95 | |||
| 96 | void gic_cpu_config(void __iomem *base, void (*sync_access)(void)) | ||
| 97 | { | ||
| 98 | int i; | ||
| 99 | |||
| 100 | /* | ||
| 101 | * Deal with the banked PPI and SGI interrupts - disable all | ||
| 102 | * PPI interrupts, ensure all SGI interrupts are enabled. | ||
| 103 | */ | ||
| 104 | writel_relaxed(0xffff0000, base + GIC_DIST_ENABLE_CLEAR); | ||
| 105 | writel_relaxed(0x0000ffff, base + GIC_DIST_ENABLE_SET); | ||
| 106 | |||
| 107 | /* | ||
| 108 | * Set priority on PPI and SGI interrupts | ||
| 109 | */ | ||
| 110 | for (i = 0; i < 32; i += 4) | ||
| 111 | writel_relaxed(0xa0a0a0a0, base + GIC_DIST_PRI + i * 4 / 4); | ||
| 112 | |||
| 113 | if (sync_access) | ||
| 114 | sync_access(); | ||
| 115 | } | ||
diff --git a/drivers/irqchip/irq-gic-common.h b/drivers/irqchip/irq-gic-common.h new file mode 100644 index 000000000000..b41f02481c3a --- /dev/null +++ b/drivers/irqchip/irq-gic-common.h | |||
| @@ -0,0 +1,29 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2002 ARM Limited, All Rights Reserved. | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License version 2 as | ||
| 6 | * published by the Free Software Foundation. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License | ||
| 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 15 | */ | ||
| 16 | |||
| 17 | #ifndef _IRQ_GIC_COMMON_H | ||
| 18 | #define _IRQ_GIC_COMMON_H | ||
| 19 | |||
| 20 | #include <linux/of.h> | ||
| 21 | #include <linux/irqdomain.h> | ||
| 22 | |||
| 23 | void gic_configure_irq(unsigned int irq, unsigned int type, | ||
| 24 | void __iomem *base, void (*sync_access)(void)); | ||
| 25 | void gic_dist_config(void __iomem *base, int gic_irqs, | ||
| 26 | void (*sync_access)(void)); | ||
| 27 | void gic_cpu_config(void __iomem *base, void (*sync_access)(void)); | ||
| 28 | |||
| 29 | #endif /* _IRQ_GIC_COMMON_H */ | ||
diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c new file mode 100644 index 000000000000..57eaa5a0b1e3 --- /dev/null +++ b/drivers/irqchip/irq-gic-v3.c | |||
| @@ -0,0 +1,692 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2013, 2014 ARM Limited, All Rights Reserved. | ||
| 3 | * Author: Marc Zyngier <marc.zyngier@arm.com> | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License version 2 as | ||
| 7 | * published by the Free Software Foundation. | ||
| 8 | * | ||
| 9 | * This program is distributed in the hope that it will be useful, | ||
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | * GNU General Public License for more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU General Public License | ||
| 15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #include <linux/cpu.h> | ||
| 19 | #include <linux/delay.h> | ||
| 20 | #include <linux/interrupt.h> | ||
| 21 | #include <linux/of.h> | ||
| 22 | #include <linux/of_address.h> | ||
| 23 | #include <linux/of_irq.h> | ||
| 24 | #include <linux/percpu.h> | ||
| 25 | #include <linux/slab.h> | ||
| 26 | |||
| 27 | #include <linux/irqchip/arm-gic-v3.h> | ||
| 28 | |||
| 29 | #include <asm/cputype.h> | ||
| 30 | #include <asm/exception.h> | ||
| 31 | #include <asm/smp_plat.h> | ||
| 32 | |||
| 33 | #include "irq-gic-common.h" | ||
| 34 | #include "irqchip.h" | ||
| 35 | |||
| 36 | struct gic_chip_data { | ||
| 37 | void __iomem *dist_base; | ||
| 38 | void __iomem **redist_base; | ||
| 39 | void __percpu __iomem **rdist; | ||
| 40 | struct irq_domain *domain; | ||
| 41 | u64 redist_stride; | ||
| 42 | u32 redist_regions; | ||
| 43 | unsigned int irq_nr; | ||
| 44 | }; | ||
| 45 | |||
| 46 | static struct gic_chip_data gic_data __read_mostly; | ||
| 47 | |||
| 48 | #define gic_data_rdist() (this_cpu_ptr(gic_data.rdist)) | ||
| 49 | #define gic_data_rdist_rd_base() (*gic_data_rdist()) | ||
| 50 | #define gic_data_rdist_sgi_base() (gic_data_rdist_rd_base() + SZ_64K) | ||
| 51 | |||
| 52 | /* Our default, arbitrary priority value. Linux only uses one anyway. */ | ||
| 53 | #define DEFAULT_PMR_VALUE 0xf0 | ||
| 54 | |||
| 55 | static inline unsigned int gic_irq(struct irq_data *d) | ||
| 56 | { | ||
| 57 | return d->hwirq; | ||
| 58 | } | ||
| 59 | |||
| 60 | static inline int gic_irq_in_rdist(struct irq_data *d) | ||
| 61 | { | ||
| 62 | return gic_irq(d) < 32; | ||
| 63 | } | ||
| 64 | |||
| 65 | static inline void __iomem *gic_dist_base(struct irq_data *d) | ||
| 66 | { | ||
| 67 | if (gic_irq_in_rdist(d)) /* SGI+PPI -> SGI_base for this CPU */ | ||
| 68 | return gic_data_rdist_sgi_base(); | ||
| 69 | |||
| 70 | if (d->hwirq <= 1023) /* SPI -> dist_base */ | ||
| 71 | return gic_data.dist_base; | ||
| 72 | |||
| 73 | if (d->hwirq >= 8192) | ||
| 74 | BUG(); /* LPI Detected!!! */ | ||
| 75 | |||
| 76 | return NULL; | ||
| 77 | } | ||
| 78 | |||
| 79 | static void gic_do_wait_for_rwp(void __iomem *base) | ||
| 80 | { | ||
| 81 | u32 count = 1000000; /* 1s! */ | ||
| 82 | |||
| 83 | while (readl_relaxed(base + GICD_CTLR) & GICD_CTLR_RWP) { | ||
| 84 | count--; | ||
| 85 | if (!count) { | ||
| 86 | pr_err_ratelimited("RWP timeout, gone fishing\n"); | ||
| 87 | return; | ||
| 88 | } | ||
| 89 | cpu_relax(); | ||
| 90 | udelay(1); | ||
| 91 | }; | ||
| 92 | } | ||
| 93 | |||
| 94 | /* Wait for completion of a distributor change */ | ||
| 95 | static void gic_dist_wait_for_rwp(void) | ||
| 96 | { | ||
| 97 | gic_do_wait_for_rwp(gic_data.dist_base); | ||
| 98 | } | ||
| 99 | |||
| 100 | /* Wait for completion of a redistributor change */ | ||
| 101 | static void gic_redist_wait_for_rwp(void) | ||
| 102 | { | ||
| 103 | gic_do_wait_for_rwp(gic_data_rdist_rd_base()); | ||
| 104 | } | ||
| 105 | |||
| 106 | /* Low level accessors */ | ||
| 107 | static u64 gic_read_iar(void) | ||
| 108 | { | ||
| 109 | u64 irqstat; | ||
| 110 | |||
| 111 | asm volatile("mrs_s %0, " __stringify(ICC_IAR1_EL1) : "=r" (irqstat)); | ||
| 112 | return irqstat; | ||
| 113 | } | ||
| 114 | |||
| 115 | static void gic_write_pmr(u64 val) | ||
| 116 | { | ||
| 117 | asm volatile("msr_s " __stringify(ICC_PMR_EL1) ", %0" : : "r" (val)); | ||
| 118 | } | ||
| 119 | |||
| 120 | static void gic_write_ctlr(u64 val) | ||
| 121 | { | ||
| 122 | asm volatile("msr_s " __stringify(ICC_CTLR_EL1) ", %0" : : "r" (val)); | ||
| 123 | isb(); | ||
| 124 | } | ||
| 125 | |||
| 126 | static void gic_write_grpen1(u64 val) | ||
| 127 | { | ||
| 128 | asm volatile("msr_s " __stringify(ICC_GRPEN1_EL1) ", %0" : : "r" (val)); | ||
| 129 | isb(); | ||
| 130 | } | ||
| 131 | |||
| 132 | static void gic_write_sgi1r(u64 val) | ||
| 133 | { | ||
| 134 | asm volatile("msr_s " __stringify(ICC_SGI1R_EL1) ", %0" : : "r" (val)); | ||
| 135 | } | ||
| 136 | |||
| 137 | static void gic_enable_sre(void) | ||
| 138 | { | ||
| 139 | u64 val; | ||
| 140 | |||
| 141 | asm volatile("mrs_s %0, " __stringify(ICC_SRE_EL1) : "=r" (val)); | ||
| 142 | val |= ICC_SRE_EL1_SRE; | ||
| 143 | asm volatile("msr_s " __stringify(ICC_SRE_EL1) ", %0" : : "r" (val)); | ||
| 144 | isb(); | ||
| 145 | |||
| 146 | /* | ||
| 147 | * Need to check that the SRE bit has actually been set. If | ||
| 148 | * not, it means that SRE is disabled at EL2. We're going to | ||
| 149 | * die painfully, and there is nothing we can do about it. | ||
| 150 | * | ||
| 151 | * Kindly inform the luser. | ||
| 152 | */ | ||
| 153 | asm volatile("mrs_s %0, " __stringify(ICC_SRE_EL1) : "=r" (val)); | ||
| 154 | if (!(val & ICC_SRE_EL1_SRE)) | ||
| 155 | pr_err("GIC: unable to set SRE (disabled at EL2), panic ahead\n"); | ||
| 156 | } | ||
| 157 | |||
| 158 | static void gic_enable_redist(void) | ||
| 159 | { | ||
| 160 | void __iomem *rbase; | ||
| 161 | u32 count = 1000000; /* 1s! */ | ||
| 162 | u32 val; | ||
| 163 | |||
| 164 | rbase = gic_data_rdist_rd_base(); | ||
| 165 | |||
| 166 | /* Wake up this CPU redistributor */ | ||
| 167 | val = readl_relaxed(rbase + GICR_WAKER); | ||
| 168 | val &= ~GICR_WAKER_ProcessorSleep; | ||
| 169 | writel_relaxed(val, rbase + GICR_WAKER); | ||
| 170 | |||
| 171 | while (readl_relaxed(rbase + GICR_WAKER) & GICR_WAKER_ChildrenAsleep) { | ||
| 172 | count--; | ||
| 173 | if (!count) { | ||
| 174 | pr_err_ratelimited("redist didn't wake up...\n"); | ||
| 175 | return; | ||
| 176 | } | ||
| 177 | cpu_relax(); | ||
| 178 | udelay(1); | ||
| 179 | }; | ||
| 180 | } | ||
| 181 | |||
| 182 | /* | ||
| 183 | * Routines to disable, enable, EOI and route interrupts | ||
| 184 | */ | ||
| 185 | static void gic_poke_irq(struct irq_data *d, u32 offset) | ||
| 186 | { | ||
| 187 | u32 mask = 1 << (gic_irq(d) % 32); | ||
| 188 | void (*rwp_wait)(void); | ||
| 189 | void __iomem *base; | ||
| 190 | |||
| 191 | if (gic_irq_in_rdist(d)) { | ||
| 192 | base = gic_data_rdist_sgi_base(); | ||
| 193 | rwp_wait = gic_redist_wait_for_rwp; | ||
| 194 | } else { | ||
| 195 | base = gic_data.dist_base; | ||
| 196 | rwp_wait = gic_dist_wait_for_rwp; | ||
| 197 | } | ||
| 198 | |||
| 199 | writel_relaxed(mask, base + offset + (gic_irq(d) / 32) * 4); | ||
| 200 | rwp_wait(); | ||
| 201 | } | ||
| 202 | |||
| 203 | static int gic_peek_irq(struct irq_data *d, u32 offset) | ||
| 204 | { | ||
| 205 | u32 mask = 1 << (gic_irq(d) % 32); | ||
| 206 | void __iomem *base; | ||
| 207 | |||
| 208 | if (gic_irq_in_rdist(d)) | ||
| 209 | base = gic_data_rdist_sgi_base(); | ||
| 210 | else | ||
| 211 | base = gic_data.dist_base; | ||
| 212 | |||
| 213 | return !!(readl_relaxed(base + offset + (gic_irq(d) / 32) * 4) & mask); | ||
| 214 | } | ||
| 215 | |||
| 216 | static void gic_mask_irq(struct irq_data *d) | ||
| 217 | { | ||
| 218 | gic_poke_irq(d, GICD_ICENABLER); | ||
| 219 | } | ||
| 220 | |||
| 221 | static void gic_unmask_irq(struct irq_data *d) | ||
| 222 | { | ||
| 223 | gic_poke_irq(d, GICD_ISENABLER); | ||
| 224 | } | ||
| 225 | |||
| 226 | static void gic_eoi_irq(struct irq_data *d) | ||
| 227 | { | ||
| 228 | gic_write_eoir(gic_irq(d)); | ||
| 229 | } | ||
| 230 | |||
| 231 | static int gic_set_type(struct irq_data *d, unsigned int type) | ||
| 232 | { | ||
| 233 | unsigned int irq = gic_irq(d); | ||
| 234 | void (*rwp_wait)(void); | ||
| 235 | void __iomem *base; | ||
| 236 | |||
| 237 | /* Interrupt configuration for SGIs can't be changed */ | ||
| 238 | if (irq < 16) | ||
| 239 | return -EINVAL; | ||
| 240 | |||
| 241 | if (type != IRQ_TYPE_LEVEL_HIGH && type != IRQ_TYPE_EDGE_RISING) | ||
| 242 | return -EINVAL; | ||
| 243 | |||
| 244 | if (gic_irq_in_rdist(d)) { | ||
| 245 | base = gic_data_rdist_sgi_base(); | ||
| 246 | rwp_wait = gic_redist_wait_for_rwp; | ||
| 247 | } else { | ||
| 248 | base = gic_data.dist_base; | ||
| 249 | rwp_wait = gic_dist_wait_for_rwp; | ||
| 250 | } | ||
| 251 | |||
| 252 | gic_configure_irq(irq, type, base, rwp_wait); | ||
| 253 | |||
| 254 | return 0; | ||
| 255 | } | ||
| 256 | |||
| 257 | static u64 gic_mpidr_to_affinity(u64 mpidr) | ||
| 258 | { | ||
| 259 | u64 aff; | ||
| 260 | |||
| 261 | aff = (MPIDR_AFFINITY_LEVEL(mpidr, 3) << 32 | | ||
| 262 | MPIDR_AFFINITY_LEVEL(mpidr, 2) << 16 | | ||
| 263 | MPIDR_AFFINITY_LEVEL(mpidr, 1) << 8 | | ||
| 264 | MPIDR_AFFINITY_LEVEL(mpidr, 0)); | ||
| 265 | |||
| 266 | return aff; | ||
| 267 | } | ||
| 268 | |||
| 269 | static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs) | ||
| 270 | { | ||
| 271 | u64 irqnr; | ||
| 272 | |||
| 273 | do { | ||
| 274 | irqnr = gic_read_iar(); | ||
| 275 | |||
| 276 | if (likely(irqnr > 15 && irqnr < 1020)) { | ||
| 277 | u64 irq = irq_find_mapping(gic_data.domain, irqnr); | ||
| 278 | if (likely(irq)) { | ||
| 279 | handle_IRQ(irq, regs); | ||
| 280 | continue; | ||
| 281 | } | ||
| 282 | |||
| 283 | WARN_ONCE(true, "Unexpected SPI received!\n"); | ||
| 284 | gic_write_eoir(irqnr); | ||
| 285 | } | ||
| 286 | if (irqnr < 16) { | ||
| 287 | gic_write_eoir(irqnr); | ||
| 288 | #ifdef CONFIG_SMP | ||
| 289 | handle_IPI(irqnr, regs); | ||
| 290 | #else | ||
| 291 | WARN_ONCE(true, "Unexpected SGI received!\n"); | ||
| 292 | #endif | ||
| 293 | continue; | ||
| 294 | } | ||
| 295 | } while (irqnr != ICC_IAR1_EL1_SPURIOUS); | ||
| 296 | } | ||
| 297 | |||
| 298 | static void __init gic_dist_init(void) | ||
| 299 | { | ||
| 300 | unsigned int i; | ||
| 301 | u64 affinity; | ||
| 302 | void __iomem *base = gic_data.dist_base; | ||
| 303 | |||
| 304 | /* Disable the distributor */ | ||
| 305 | writel_relaxed(0, base + GICD_CTLR); | ||
| 306 | gic_dist_wait_for_rwp(); | ||
| 307 | |||
| 308 | gic_dist_config(base, gic_data.irq_nr, gic_dist_wait_for_rwp); | ||
| 309 | |||
| 310 | /* Enable distributor with ARE, Group1 */ | ||
| 311 | writel_relaxed(GICD_CTLR_ARE_NS | GICD_CTLR_ENABLE_G1A | GICD_CTLR_ENABLE_G1, | ||
| 312 | base + GICD_CTLR); | ||
| 313 | |||
| 314 | /* | ||
| 315 | * Set all global interrupts to the boot CPU only. ARE must be | ||
| 316 | * enabled. | ||
| 317 | */ | ||
| 318 | affinity = gic_mpidr_to_affinity(cpu_logical_map(smp_processor_id())); | ||
| 319 | for (i = 32; i < gic_data.irq_nr; i++) | ||
| 320 | writeq_relaxed(affinity, base + GICD_IROUTER + i * 8); | ||
| 321 | } | ||
| 322 | |||
| 323 | static int gic_populate_rdist(void) | ||
| 324 | { | ||
| 325 | u64 mpidr = cpu_logical_map(smp_processor_id()); | ||
| 326 | u64 typer; | ||
| 327 | u32 aff; | ||
| 328 | int i; | ||
| 329 | |||
| 330 | /* | ||
| 331 | * Convert affinity to a 32bit value that can be matched to | ||
| 332 | * GICR_TYPER bits [63:32]. | ||
| 333 | */ | ||
| 334 | aff = (MPIDR_AFFINITY_LEVEL(mpidr, 3) << 24 | | ||
| 335 | MPIDR_AFFINITY_LEVEL(mpidr, 2) << 16 | | ||
| 336 | MPIDR_AFFINITY_LEVEL(mpidr, 1) << 8 | | ||
| 337 | MPIDR_AFFINITY_LEVEL(mpidr, 0)); | ||
| 338 | |||
| 339 | for (i = 0; i < gic_data.redist_regions; i++) { | ||
| 340 | void __iomem *ptr = gic_data.redist_base[i]; | ||
| 341 | u32 reg; | ||
| 342 | |||
| 343 | reg = readl_relaxed(ptr + GICR_PIDR2) & GIC_PIDR2_ARCH_MASK; | ||
| 344 | if (reg != GIC_PIDR2_ARCH_GICv3 && | ||
| 345 | reg != GIC_PIDR2_ARCH_GICv4) { /* We're in trouble... */ | ||
| 346 | pr_warn("No redistributor present @%p\n", ptr); | ||
| 347 | break; | ||
| 348 | } | ||
| 349 | |||
| 350 | do { | ||
| 351 | typer = readq_relaxed(ptr + GICR_TYPER); | ||
| 352 | if ((typer >> 32) == aff) { | ||
| 353 | gic_data_rdist_rd_base() = ptr; | ||
| 354 | pr_info("CPU%d: found redistributor %llx @%p\n", | ||
| 355 | smp_processor_id(), | ||
| 356 | (unsigned long long)mpidr, ptr); | ||
| 357 | return 0; | ||
| 358 | } | ||
| 359 | |||
| 360 | if (gic_data.redist_stride) { | ||
| 361 | ptr += gic_data.redist_stride; | ||
| 362 | } else { | ||
| 363 | ptr += SZ_64K * 2; /* Skip RD_base + SGI_base */ | ||
| 364 | if (typer & GICR_TYPER_VLPIS) | ||
| 365 | ptr += SZ_64K * 2; /* Skip VLPI_base + reserved page */ | ||
| 366 | } | ||
| 367 | } while (!(typer & GICR_TYPER_LAST)); | ||
| 368 | } | ||
| 369 | |||
| 370 | /* We couldn't even deal with ourselves... */ | ||
| 371 | WARN(true, "CPU%d: mpidr %llx has no re-distributor!\n", | ||
| 372 | smp_processor_id(), (unsigned long long)mpidr); | ||
| 373 | return -ENODEV; | ||
| 374 | } | ||
| 375 | |||
| 376 | static void gic_cpu_init(void) | ||
| 377 | { | ||
| 378 | void __iomem *rbase; | ||
| 379 | |||
| 380 | /* Register ourselves with the rest of the world */ | ||
| 381 | if (gic_populate_rdist()) | ||
| 382 | return; | ||
| 383 | |||
| 384 | gic_enable_redist(); | ||
| 385 | |||
| 386 | rbase = gic_data_rdist_sgi_base(); | ||
| 387 | |||
| 388 | gic_cpu_config(rbase, gic_redist_wait_for_rwp); | ||
| 389 | |||
| 390 | /* Enable system registers */ | ||
| 391 | gic_enable_sre(); | ||
| 392 | |||
| 393 | /* Set priority mask register */ | ||
| 394 | gic_write_pmr(DEFAULT_PMR_VALUE); | ||
| 395 | |||
| 396 | /* EOI deactivates interrupt too (mode 0) */ | ||
| 397 | gic_write_ctlr(ICC_CTLR_EL1_EOImode_drop_dir); | ||
| 398 | |||
| 399 | /* ... and let's hit the road... */ | ||
| 400 | gic_write_grpen1(1); | ||
| 401 | } | ||
| 402 | |||
| 403 | #ifdef CONFIG_SMP | ||
| 404 | static int gic_secondary_init(struct notifier_block *nfb, | ||
| 405 | unsigned long action, void *hcpu) | ||
| 406 | { | ||
| 407 | if (action == CPU_STARTING || action == CPU_STARTING_FROZEN) | ||
| 408 | gic_cpu_init(); | ||
| 409 | return NOTIFY_OK; | ||
| 410 | } | ||
| 411 | |||
| 412 | /* | ||
| 413 | * Notifier for enabling the GIC CPU interface. Set an arbitrarily high | ||
| 414 | * priority because the GIC needs to be up before the ARM generic timers. | ||
| 415 | */ | ||
| 416 | static struct notifier_block gic_cpu_notifier = { | ||
| 417 | .notifier_call = gic_secondary_init, | ||
| 418 | .priority = 100, | ||
| 419 | }; | ||
| 420 | |||
| 421 | static u16 gic_compute_target_list(int *base_cpu, const struct cpumask *mask, | ||
| 422 | u64 cluster_id) | ||
| 423 | { | ||
| 424 | int cpu = *base_cpu; | ||
| 425 | u64 mpidr = cpu_logical_map(cpu); | ||
| 426 | u16 tlist = 0; | ||
| 427 | |||
| 428 | while (cpu < nr_cpu_ids) { | ||
| 429 | /* | ||
| 430 | * If we ever get a cluster of more than 16 CPUs, just | ||
| 431 | * scream and skip that CPU. | ||
| 432 | */ | ||
| 433 | if (WARN_ON((mpidr & 0xff) >= 16)) | ||
| 434 | goto out; | ||
| 435 | |||
| 436 | tlist |= 1 << (mpidr & 0xf); | ||
| 437 | |||
| 438 | cpu = cpumask_next(cpu, mask); | ||
| 439 | if (cpu == nr_cpu_ids) | ||
| 440 | goto out; | ||
| 441 | |||
| 442 | mpidr = cpu_logical_map(cpu); | ||
| 443 | |||
| 444 | if (cluster_id != (mpidr & ~0xffUL)) { | ||
| 445 | cpu--; | ||
| 446 | goto out; | ||
| 447 | } | ||
| 448 | } | ||
| 449 | out: | ||
| 450 | *base_cpu = cpu; | ||
| 451 | return tlist; | ||
| 452 | } | ||
| 453 | |||
| 454 | static void gic_send_sgi(u64 cluster_id, u16 tlist, unsigned int irq) | ||
| 455 | { | ||
| 456 | u64 val; | ||
| 457 | |||
| 458 | val = (MPIDR_AFFINITY_LEVEL(cluster_id, 3) << 48 | | ||
| 459 | MPIDR_AFFINITY_LEVEL(cluster_id, 2) << 32 | | ||
| 460 | irq << 24 | | ||
| 461 | MPIDR_AFFINITY_LEVEL(cluster_id, 1) << 16 | | ||
| 462 | tlist); | ||
| 463 | |||
| 464 | pr_debug("CPU%d: ICC_SGI1R_EL1 %llx\n", smp_processor_id(), val); | ||
| 465 | gic_write_sgi1r(val); | ||
| 466 | } | ||
| 467 | |||
| 468 | static void gic_raise_softirq(const struct cpumask *mask, unsigned int irq) | ||
| 469 | { | ||
| 470 | int cpu; | ||
| 471 | |||
| 472 | if (WARN_ON(irq >= 16)) | ||
| 473 | return; | ||
| 474 | |||
| 475 | /* | ||
| 476 | * Ensure that stores to Normal memory are visible to the | ||
| 477 | * other CPUs before issuing the IPI. | ||
| 478 | */ | ||
| 479 | smp_wmb(); | ||
| 480 | |||
| 481 | for_each_cpu_mask(cpu, *mask) { | ||
| 482 | u64 cluster_id = cpu_logical_map(cpu) & ~0xffUL; | ||
| 483 | u16 tlist; | ||
| 484 | |||
| 485 | tlist = gic_compute_target_list(&cpu, mask, cluster_id); | ||
| 486 | gic_send_sgi(cluster_id, tlist, irq); | ||
| 487 | } | ||
| 488 | |||
| 489 | /* Force the above writes to ICC_SGI1R_EL1 to be executed */ | ||
| 490 | isb(); | ||
| 491 | } | ||
| 492 | |||
| 493 | static void gic_smp_init(void) | ||
| 494 | { | ||
| 495 | set_smp_cross_call(gic_raise_softirq); | ||
| 496 | register_cpu_notifier(&gic_cpu_notifier); | ||
| 497 | } | ||
| 498 | |||
| 499 | static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val, | ||
| 500 | bool force) | ||
| 501 | { | ||
| 502 | unsigned int cpu = cpumask_any_and(mask_val, cpu_online_mask); | ||
| 503 | void __iomem *reg; | ||
| 504 | int enabled; | ||
| 505 | u64 val; | ||
| 506 | |||
| 507 | if (gic_irq_in_rdist(d)) | ||
| 508 | return -EINVAL; | ||
| 509 | |||
| 510 | /* If interrupt was enabled, disable it first */ | ||
| 511 | enabled = gic_peek_irq(d, GICD_ISENABLER); | ||
| 512 | if (enabled) | ||
| 513 | gic_mask_irq(d); | ||
| 514 | |||
| 515 | reg = gic_dist_base(d) + GICD_IROUTER + (gic_irq(d) * 8); | ||
| 516 | val = gic_mpidr_to_affinity(cpu_logical_map(cpu)); | ||
| 517 | |||
| 518 | writeq_relaxed(val, reg); | ||
| 519 | |||
| 520 | /* | ||
| 521 | * If the interrupt was enabled, enabled it again. Otherwise, | ||
| 522 | * just wait for the distributor to have digested our changes. | ||
| 523 | */ | ||
| 524 | if (enabled) | ||
| 525 | gic_unmask_irq(d); | ||
| 526 | else | ||
| 527 | gic_dist_wait_for_rwp(); | ||
| 528 | |||
| 529 | return IRQ_SET_MASK_OK; | ||
| 530 | } | ||
| 531 | #else | ||
| 532 | #define gic_set_affinity NULL | ||
| 533 | #define gic_smp_init() do { } while(0) | ||
| 534 | #endif | ||
| 535 | |||
| 536 | static struct irq_chip gic_chip = { | ||
| 537 | .name = "GICv3", | ||
| 538 | .irq_mask = gic_mask_irq, | ||
| 539 | .irq_unmask = gic_unmask_irq, | ||
| 540 | .irq_eoi = gic_eoi_irq, | ||
| 541 | .irq_set_type = gic_set_type, | ||
| 542 | .irq_set_affinity = gic_set_affinity, | ||
| 543 | }; | ||
| 544 | |||
| 545 | static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq, | ||
| 546 | irq_hw_number_t hw) | ||
| 547 | { | ||
| 548 | /* SGIs are private to the core kernel */ | ||
| 549 | if (hw < 16) | ||
| 550 | return -EPERM; | ||
| 551 | /* PPIs */ | ||
| 552 | if (hw < 32) { | ||
| 553 | irq_set_percpu_devid(irq); | ||
| 554 | irq_set_chip_and_handler(irq, &gic_chip, | ||
| 555 | handle_percpu_devid_irq); | ||
| 556 | set_irq_flags(irq, IRQF_VALID | IRQF_NOAUTOEN); | ||
| 557 | } | ||
| 558 | /* SPIs */ | ||
| 559 | if (hw >= 32 && hw < gic_data.irq_nr) { | ||
| 560 | irq_set_chip_and_handler(irq, &gic_chip, | ||
| 561 | handle_fasteoi_irq); | ||
| 562 | set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); | ||
| 563 | } | ||
| 564 | irq_set_chip_data(irq, d->host_data); | ||
| 565 | return 0; | ||
| 566 | } | ||
| 567 | |||
| 568 | static int gic_irq_domain_xlate(struct irq_domain *d, | ||
| 569 | struct device_node *controller, | ||
| 570 | const u32 *intspec, unsigned int intsize, | ||
| 571 | unsigned long *out_hwirq, unsigned int *out_type) | ||
| 572 | { | ||
| 573 | if (d->of_node != controller) | ||
| 574 | return -EINVAL; | ||
| 575 | if (intsize < 3) | ||
| 576 | return -EINVAL; | ||
| 577 | |||
| 578 | switch(intspec[0]) { | ||
| 579 | case 0: /* SPI */ | ||
| 580 | *out_hwirq = intspec[1] + 32; | ||
| 581 | break; | ||
| 582 | case 1: /* PPI */ | ||
| 583 | *out_hwirq = intspec[1] + 16; | ||
| 584 | break; | ||
| 585 | default: | ||
| 586 | return -EINVAL; | ||
| 587 | } | ||
| 588 | |||
| 589 | *out_type = intspec[2] & IRQ_TYPE_SENSE_MASK; | ||
| 590 | return 0; | ||
| 591 | } | ||
| 592 | |||
| 593 | static const struct irq_domain_ops gic_irq_domain_ops = { | ||
| 594 | .map = gic_irq_domain_map, | ||
| 595 | .xlate = gic_irq_domain_xlate, | ||
| 596 | }; | ||
| 597 | |||
| 598 | static int __init gic_of_init(struct device_node *node, struct device_node *parent) | ||
| 599 | { | ||
| 600 | void __iomem *dist_base; | ||
| 601 | void __iomem **redist_base; | ||
| 602 | u64 redist_stride; | ||
| 603 | u32 redist_regions; | ||
| 604 | u32 reg; | ||
| 605 | int gic_irqs; | ||
| 606 | int err; | ||
| 607 | int i; | ||
| 608 | |||
| 609 | dist_base = of_iomap(node, 0); | ||
| 610 | if (!dist_base) { | ||
| 611 | pr_err("%s: unable to map gic dist registers\n", | ||
| 612 | node->full_name); | ||
| 613 | return -ENXIO; | ||
| 614 | } | ||
| 615 | |||
| 616 | reg = readl_relaxed(dist_base + GICD_PIDR2) & GIC_PIDR2_ARCH_MASK; | ||
| 617 | if (reg != GIC_PIDR2_ARCH_GICv3 && reg != GIC_PIDR2_ARCH_GICv4) { | ||
| 618 | pr_err("%s: no distributor detected, giving up\n", | ||
| 619 | node->full_name); | ||
| 620 | err = -ENODEV; | ||
| 621 | goto out_unmap_dist; | ||
| 622 | } | ||
| 623 | |||
| 624 | if (of_property_read_u32(node, "#redistributor-regions", &redist_regions)) | ||
| 625 | redist_regions = 1; | ||
| 626 | |||
| 627 | redist_base = kzalloc(sizeof(*redist_base) * redist_regions, GFP_KERNEL); | ||
| 628 | if (!redist_base) { | ||
| 629 | err = -ENOMEM; | ||
| 630 | goto out_unmap_dist; | ||
| 631 | } | ||
| 632 | |||
| 633 | for (i = 0; i < redist_regions; i++) { | ||
| 634 | redist_base[i] = of_iomap(node, 1 + i); | ||
| 635 | if (!redist_base[i]) { | ||
| 636 | pr_err("%s: couldn't map region %d\n", | ||
| 637 | node->full_name, i); | ||
| 638 | err = -ENODEV; | ||
| 639 | goto out_unmap_rdist; | ||
| 640 | } | ||
| 641 | } | ||
| 642 | |||
| 643 | if (of_property_read_u64(node, "redistributor-stride", &redist_stride)) | ||
| 644 | redist_stride = 0; | ||
| 645 | |||
| 646 | gic_data.dist_base = dist_base; | ||
| 647 | gic_data.redist_base = redist_base; | ||
| 648 | gic_data.redist_regions = redist_regions; | ||
| 649 | gic_data.redist_stride = redist_stride; | ||
| 650 | |||
| 651 | /* | ||
| 652 | * Find out how many interrupts are supported. | ||
| 653 | * The GIC only supports up to 1020 interrupt sources (SGI+PPI+SPI) | ||
| 654 | */ | ||
| 655 | gic_irqs = readl_relaxed(gic_data.dist_base + GICD_TYPER) & 0x1f; | ||
| 656 | gic_irqs = (gic_irqs + 1) * 32; | ||
| 657 | if (gic_irqs > 1020) | ||
| 658 | gic_irqs = 1020; | ||
| 659 | gic_data.irq_nr = gic_irqs; | ||
| 660 | |||
| 661 | gic_data.domain = irq_domain_add_tree(node, &gic_irq_domain_ops, | ||
| 662 | &gic_data); | ||
| 663 | gic_data.rdist = alloc_percpu(typeof(*gic_data.rdist)); | ||
| 664 | |||
| 665 | if (WARN_ON(!gic_data.domain) || WARN_ON(!gic_data.rdist)) { | ||
| 666 | err = -ENOMEM; | ||
| 667 | goto out_free; | ||
| 668 | } | ||
| 669 | |||
| 670 | set_handle_irq(gic_handle_irq); | ||
| 671 | |||
| 672 | gic_smp_init(); | ||
| 673 | gic_dist_init(); | ||
| 674 | gic_cpu_init(); | ||
| 675 | |||
| 676 | return 0; | ||
| 677 | |||
| 678 | out_free: | ||
| 679 | if (gic_data.domain) | ||
| 680 | irq_domain_remove(gic_data.domain); | ||
| 681 | free_percpu(gic_data.rdist); | ||
| 682 | out_unmap_rdist: | ||
| 683 | for (i = 0; i < redist_regions; i++) | ||
| 684 | if (redist_base[i]) | ||
| 685 | iounmap(redist_base[i]); | ||
| 686 | kfree(redist_base); | ||
| 687 | out_unmap_dist: | ||
| 688 | iounmap(dist_base); | ||
| 689 | return err; | ||
| 690 | } | ||
| 691 | |||
| 692 | IRQCHIP_DECLARE(gic_v3, "arm,gic-v3", gic_of_init); | ||
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index 7c131cf7cc13..9c1f883fc5a3 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c | |||
| @@ -47,6 +47,7 @@ | |||
| 47 | #include <asm/exception.h> | 47 | #include <asm/exception.h> |
| 48 | #include <asm/smp_plat.h> | 48 | #include <asm/smp_plat.h> |
| 49 | 49 | ||
| 50 | #include "irq-gic-common.h" | ||
| 50 | #include "irqchip.h" | 51 | #include "irqchip.h" |
| 51 | 52 | ||
| 52 | union gic_base { | 53 | union gic_base { |
| @@ -189,12 +190,6 @@ static int gic_set_type(struct irq_data *d, unsigned int type) | |||
| 189 | { | 190 | { |
| 190 | void __iomem *base = gic_dist_base(d); | 191 | void __iomem *base = gic_dist_base(d); |
| 191 | unsigned int gicirq = gic_irq(d); | 192 | unsigned int gicirq = gic_irq(d); |
| 192 | u32 enablemask = 1 << (gicirq % 32); | ||
| 193 | u32 enableoff = (gicirq / 32) * 4; | ||
| 194 | u32 confmask = 0x2 << ((gicirq % 16) * 2); | ||
| 195 | u32 confoff = (gicirq / 16) * 4; | ||
| 196 | bool enabled = false; | ||
| 197 | u32 val; | ||
| 198 | 193 | ||
| 199 | /* Interrupt configuration for SGIs can't be changed */ | 194 | /* Interrupt configuration for SGIs can't be changed */ |
| 200 | if (gicirq < 16) | 195 | if (gicirq < 16) |
| @@ -208,25 +203,7 @@ static int gic_set_type(struct irq_data *d, unsigned int type) | |||
| 208 | if (gic_arch_extn.irq_set_type) | 203 | if (gic_arch_extn.irq_set_type) |
| 209 | gic_arch_extn.irq_set_type(d, type); | 204 | gic_arch_extn.irq_set_type(d, type); |
| 210 | 205 | ||
| 211 | val = readl_relaxed(base + GIC_DIST_CONFIG + confoff); | 206 | gic_configure_irq(gicirq, type, base, NULL); |
| 212 | if (type == IRQ_TYPE_LEVEL_HIGH) | ||
| 213 | val &= ~confmask; | ||
| 214 | else if (type == IRQ_TYPE_EDGE_RISING) | ||
| 215 | val |= confmask; | ||
| 216 | |||
| 217 | /* | ||
| 218 | * As recommended by the spec, disable the interrupt before changing | ||
| 219 | * the configuration | ||
| 220 | */ | ||
| 221 | if (readl_relaxed(base + GIC_DIST_ENABLE_SET + enableoff) & enablemask) { | ||
| 222 | writel_relaxed(enablemask, base + GIC_DIST_ENABLE_CLEAR + enableoff); | ||
| 223 | enabled = true; | ||
| 224 | } | ||
| 225 | |||
| 226 | writel_relaxed(val, base + GIC_DIST_CONFIG + confoff); | ||
| 227 | |||
| 228 | if (enabled) | ||
| 229 | writel_relaxed(enablemask, base + GIC_DIST_ENABLE_SET + enableoff); | ||
| 230 | 207 | ||
| 231 | raw_spin_unlock(&irq_controller_lock); | 208 | raw_spin_unlock(&irq_controller_lock); |
| 232 | 209 | ||
| @@ -388,12 +365,6 @@ static void __init gic_dist_init(struct gic_chip_data *gic) | |||
| 388 | writel_relaxed(0, base + GIC_DIST_CTRL); | 365 | writel_relaxed(0, base + GIC_DIST_CTRL); |
| 389 | 366 | ||
| 390 | /* | 367 | /* |
| 391 | * Set all global interrupts to be level triggered, active low. | ||
| 392 | */ | ||
| 393 | for (i = 32; i < gic_irqs; i += 16) | ||
| 394 | writel_relaxed(0, base + GIC_DIST_CONFIG + i * 4 / 16); | ||
| 395 | |||
| 396 | /* | ||
| 397 | * Set all global interrupts to this CPU only. | 368 | * Set all global interrupts to this CPU only. |
| 398 | */ | 369 | */ |
| 399 | cpumask = gic_get_cpumask(gic); | 370 | cpumask = gic_get_cpumask(gic); |
| @@ -402,18 +373,7 @@ static void __init gic_dist_init(struct gic_chip_data *gic) | |||
| 402 | for (i = 32; i < gic_irqs; i += 4) | 373 | for (i = 32; i < gic_irqs; i += 4) |
| 403 | writel_relaxed(cpumask, base + GIC_DIST_TARGET + i * 4 / 4); | 374 | writel_relaxed(cpumask, base + GIC_DIST_TARGET + i * 4 / 4); |
| 404 | 375 | ||
| 405 | /* | 376 | gic_dist_config(base, gic_irqs, NULL); |
| 406 | * Set priority on all global interrupts. | ||
| 407 | */ | ||
| 408 | for (i = 32; i < gic_irqs; i += 4) | ||
| 409 | writel_relaxed(0xa0a0a0a0, base + GIC_DIST_PRI + i * 4 / 4); | ||
| 410 | |||
| 411 | /* | ||
| 412 | * Disable all interrupts. Leave the PPI and SGIs alone | ||
| 413 | * as these enables are banked registers. | ||
| 414 | */ | ||
| 415 | for (i = 32; i < gic_irqs; i += 32) | ||
| 416 | writel_relaxed(0xffffffff, base + GIC_DIST_ENABLE_CLEAR + i * 4 / 32); | ||
| 417 | 377 | ||
| 418 | writel_relaxed(1, base + GIC_DIST_CTRL); | 378 | writel_relaxed(1, base + GIC_DIST_CTRL); |
| 419 | } | 379 | } |
| @@ -440,18 +400,7 @@ static void gic_cpu_init(struct gic_chip_data *gic) | |||
| 440 | if (i != cpu) | 400 | if (i != cpu) |
| 441 | gic_cpu_map[i] &= ~cpu_mask; | 401 | gic_cpu_map[i] &= ~cpu_mask; |
| 442 | 402 | ||
| 443 | /* | 403 | gic_cpu_config(dist_base, NULL); |
| 444 | * Deal with the banked PPI and SGI interrupts - disable all | ||
| 445 | * PPI interrupts, ensure all SGI interrupts are enabled. | ||
| 446 | */ | ||
| 447 | writel_relaxed(0xffff0000, dist_base + GIC_DIST_ENABLE_CLEAR); | ||
| 448 | writel_relaxed(0x0000ffff, dist_base + GIC_DIST_ENABLE_SET); | ||
| 449 | |||
| 450 | /* | ||
| 451 | * Set priority on PPI and SGI interrupts | ||
| 452 | */ | ||
| 453 | for (i = 0; i < 32; i += 4) | ||
| 454 | writel_relaxed(0xa0a0a0a0, dist_base + GIC_DIST_PRI + i * 4 / 4); | ||
| 455 | 404 | ||
| 456 | writel_relaxed(0xf0, base + GIC_CPU_PRIMASK); | 405 | writel_relaxed(0xf0, base + GIC_CPU_PRIMASK); |
| 457 | writel_relaxed(1, base + GIC_CPU_CTRL); | 406 | writel_relaxed(1, base + GIC_CPU_CTRL); |
diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h new file mode 100644 index 000000000000..03a4ea37ba86 --- /dev/null +++ b/include/linux/irqchip/arm-gic-v3.h | |||
| @@ -0,0 +1,200 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2013, 2014 ARM Limited, All Rights Reserved. | ||
| 3 | * Author: Marc Zyngier <marc.zyngier@arm.com> | ||
| 4 | * | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License version 2 as | ||
| 8 | * published by the Free Software Foundation. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 17 | */ | ||
| 18 | #ifndef __LINUX_IRQCHIP_ARM_GIC_V3_H | ||
| 19 | #define __LINUX_IRQCHIP_ARM_GIC_V3_H | ||
| 20 | |||
| 21 | #include <asm/sysreg.h> | ||
| 22 | |||
| 23 | /* | ||
| 24 | * Distributor registers. We assume we're running non-secure, with ARE | ||
| 25 | * being set. Secure-only and non-ARE registers are not described. | ||
| 26 | */ | ||
| 27 | #define GICD_CTLR 0x0000 | ||
| 28 | #define GICD_TYPER 0x0004 | ||
| 29 | #define GICD_IIDR 0x0008 | ||
| 30 | #define GICD_STATUSR 0x0010 | ||
| 31 | #define GICD_SETSPI_NSR 0x0040 | ||
| 32 | #define GICD_CLRSPI_NSR 0x0048 | ||
| 33 | #define GICD_SETSPI_SR 0x0050 | ||
| 34 | #define GICD_CLRSPI_SR 0x0058 | ||
| 35 | #define GICD_SEIR 0x0068 | ||
| 36 | #define GICD_ISENABLER 0x0100 | ||
| 37 | #define GICD_ICENABLER 0x0180 | ||
| 38 | #define GICD_ISPENDR 0x0200 | ||
| 39 | #define GICD_ICPENDR 0x0280 | ||
| 40 | #define GICD_ISACTIVER 0x0300 | ||
| 41 | #define GICD_ICACTIVER 0x0380 | ||
| 42 | #define GICD_IPRIORITYR 0x0400 | ||
| 43 | #define GICD_ICFGR 0x0C00 | ||
| 44 | #define GICD_IROUTER 0x6000 | ||
| 45 | #define GICD_PIDR2 0xFFE8 | ||
| 46 | |||
| 47 | #define GICD_CTLR_RWP (1U << 31) | ||
| 48 | #define GICD_CTLR_ARE_NS (1U << 4) | ||
| 49 | #define GICD_CTLR_ENABLE_G1A (1U << 1) | ||
| 50 | #define GICD_CTLR_ENABLE_G1 (1U << 0) | ||
| 51 | |||
| 52 | #define GICD_IROUTER_SPI_MODE_ONE (0U << 31) | ||
| 53 | #define GICD_IROUTER_SPI_MODE_ANY (1U << 31) | ||
| 54 | |||
| 55 | #define GIC_PIDR2_ARCH_MASK 0xf0 | ||
| 56 | #define GIC_PIDR2_ARCH_GICv3 0x30 | ||
| 57 | #define GIC_PIDR2_ARCH_GICv4 0x40 | ||
| 58 | |||
| 59 | /* | ||
| 60 | * Re-Distributor registers, offsets from RD_base | ||
| 61 | */ | ||
| 62 | #define GICR_CTLR GICD_CTLR | ||
| 63 | #define GICR_IIDR 0x0004 | ||
| 64 | #define GICR_TYPER 0x0008 | ||
| 65 | #define GICR_STATUSR GICD_STATUSR | ||
| 66 | #define GICR_WAKER 0x0014 | ||
| 67 | #define GICR_SETLPIR 0x0040 | ||
| 68 | #define GICR_CLRLPIR 0x0048 | ||
| 69 | #define GICR_SEIR GICD_SEIR | ||
| 70 | #define GICR_PROPBASER 0x0070 | ||
| 71 | #define GICR_PENDBASER 0x0078 | ||
| 72 | #define GICR_INVLPIR 0x00A0 | ||
| 73 | #define GICR_INVALLR 0x00B0 | ||
| 74 | #define GICR_SYNCR 0x00C0 | ||
| 75 | #define GICR_MOVLPIR 0x0100 | ||
| 76 | #define GICR_MOVALLR 0x0110 | ||
| 77 | #define GICR_PIDR2 GICD_PIDR2 | ||
| 78 | |||
| 79 | #define GICR_WAKER_ProcessorSleep (1U << 1) | ||
| 80 | #define GICR_WAKER_ChildrenAsleep (1U << 2) | ||
| 81 | |||
| 82 | /* | ||
| 83 | * Re-Distributor registers, offsets from SGI_base | ||
| 84 | */ | ||
| 85 | #define GICR_ISENABLER0 GICD_ISENABLER | ||
| 86 | #define GICR_ICENABLER0 GICD_ICENABLER | ||
| 87 | #define GICR_ISPENDR0 GICD_ISPENDR | ||
| 88 | #define GICR_ICPENDR0 GICD_ICPENDR | ||
| 89 | #define GICR_ISACTIVER0 GICD_ISACTIVER | ||
| 90 | #define GICR_ICACTIVER0 GICD_ICACTIVER | ||
| 91 | #define GICR_IPRIORITYR0 GICD_IPRIORITYR | ||
| 92 | #define GICR_ICFGR0 GICD_ICFGR | ||
| 93 | |||
| 94 | #define GICR_TYPER_VLPIS (1U << 1) | ||
| 95 | #define GICR_TYPER_LAST (1U << 4) | ||
| 96 | |||
| 97 | /* | ||
| 98 | * CPU interface registers | ||
| 99 | */ | ||
| 100 | #define ICC_CTLR_EL1_EOImode_drop_dir (0U << 1) | ||
| 101 | #define ICC_CTLR_EL1_EOImode_drop (1U << 1) | ||
| 102 | #define ICC_SRE_EL1_SRE (1U << 0) | ||
| 103 | |||
| 104 | /* | ||
| 105 | * Hypervisor interface registers (SRE only) | ||
| 106 | */ | ||
| 107 | #define ICH_LR_VIRTUAL_ID_MASK ((1UL << 32) - 1) | ||
| 108 | |||
| 109 | #define ICH_LR_EOI (1UL << 41) | ||
| 110 | #define ICH_LR_GROUP (1UL << 60) | ||
| 111 | #define ICH_LR_STATE (3UL << 62) | ||
| 112 | #define ICH_LR_PENDING_BIT (1UL << 62) | ||
| 113 | #define ICH_LR_ACTIVE_BIT (1UL << 63) | ||
| 114 | |||
| 115 | #define ICH_MISR_EOI (1 << 0) | ||
| 116 | #define ICH_MISR_U (1 << 1) | ||
| 117 | |||
| 118 | #define ICH_HCR_EN (1 << 0) | ||
| 119 | #define ICH_HCR_UIE (1 << 1) | ||
| 120 | |||
| 121 | #define ICH_VMCR_CTLR_SHIFT 0 | ||
| 122 | #define ICH_VMCR_CTLR_MASK (0x21f << ICH_VMCR_CTLR_SHIFT) | ||
| 123 | #define ICH_VMCR_BPR1_SHIFT 18 | ||
| 124 | #define ICH_VMCR_BPR1_MASK (7 << ICH_VMCR_BPR1_SHIFT) | ||
| 125 | #define ICH_VMCR_BPR0_SHIFT 21 | ||
| 126 | #define ICH_VMCR_BPR0_MASK (7 << ICH_VMCR_BPR0_SHIFT) | ||
| 127 | #define ICH_VMCR_PMR_SHIFT 24 | ||
| 128 | #define ICH_VMCR_PMR_MASK (0xffUL << ICH_VMCR_PMR_SHIFT) | ||
| 129 | |||
| 130 | #define ICC_EOIR1_EL1 sys_reg(3, 0, 12, 12, 1) | ||
| 131 | #define ICC_IAR1_EL1 sys_reg(3, 0, 12, 12, 0) | ||
| 132 | #define ICC_SGI1R_EL1 sys_reg(3, 0, 12, 11, 5) | ||
| 133 | #define ICC_PMR_EL1 sys_reg(3, 0, 4, 6, 0) | ||
| 134 | #define ICC_CTLR_EL1 sys_reg(3, 0, 12, 12, 4) | ||
| 135 | #define ICC_SRE_EL1 sys_reg(3, 0, 12, 12, 5) | ||
| 136 | #define ICC_GRPEN1_EL1 sys_reg(3, 0, 12, 12, 7) | ||
| 137 | |||
| 138 | #define ICC_IAR1_EL1_SPURIOUS 0x3ff | ||
| 139 | |||
| 140 | #define ICC_SRE_EL2 sys_reg(3, 4, 12, 9, 5) | ||
| 141 | |||
| 142 | #define ICC_SRE_EL2_SRE (1 << 0) | ||
| 143 | #define ICC_SRE_EL2_ENABLE (1 << 3) | ||
| 144 | |||
| 145 | /* | ||
| 146 | * System register definitions | ||
| 147 | */ | ||
| 148 | #define ICH_VSEIR_EL2 sys_reg(3, 4, 12, 9, 4) | ||
| 149 | #define ICH_HCR_EL2 sys_reg(3, 4, 12, 11, 0) | ||
| 150 | #define ICH_VTR_EL2 sys_reg(3, 4, 12, 11, 1) | ||
| 151 | #define ICH_MISR_EL2 sys_reg(3, 4, 12, 11, 2) | ||
| 152 | #define ICH_EISR_EL2 sys_reg(3, 4, 12, 11, 3) | ||
| 153 | #define ICH_ELSR_EL2 sys_reg(3, 4, 12, 11, 5) | ||
| 154 | #define ICH_VMCR_EL2 sys_reg(3, 4, 12, 11, 7) | ||
| 155 | |||
| 156 | #define __LR0_EL2(x) sys_reg(3, 4, 12, 12, x) | ||
| 157 | #define __LR8_EL2(x) sys_reg(3, 4, 12, 13, x) | ||
| 158 | |||
| 159 | #define ICH_LR0_EL2 __LR0_EL2(0) | ||
| 160 | #define ICH_LR1_EL2 __LR0_EL2(1) | ||
| 161 | #define ICH_LR2_EL2 __LR0_EL2(2) | ||
| 162 | #define ICH_LR3_EL2 __LR0_EL2(3) | ||
| 163 | #define ICH_LR4_EL2 __LR0_EL2(4) | ||
| 164 | #define ICH_LR5_EL2 __LR0_EL2(5) | ||
| 165 | #define ICH_LR6_EL2 __LR0_EL2(6) | ||
| 166 | #define ICH_LR7_EL2 __LR0_EL2(7) | ||
| 167 | #define ICH_LR8_EL2 __LR8_EL2(0) | ||
| 168 | #define ICH_LR9_EL2 __LR8_EL2(1) | ||
| 169 | #define ICH_LR10_EL2 __LR8_EL2(2) | ||
| 170 | #define ICH_LR11_EL2 __LR8_EL2(3) | ||
| 171 | #define ICH_LR12_EL2 __LR8_EL2(4) | ||
| 172 | #define ICH_LR13_EL2 __LR8_EL2(5) | ||
| 173 | #define ICH_LR14_EL2 __LR8_EL2(6) | ||
| 174 | #define ICH_LR15_EL2 __LR8_EL2(7) | ||
| 175 | |||
| 176 | #define __AP0Rx_EL2(x) sys_reg(3, 4, 12, 8, x) | ||
| 177 | #define ICH_AP0R0_EL2 __AP0Rx_EL2(0) | ||
| 178 | #define ICH_AP0R1_EL2 __AP0Rx_EL2(1) | ||
| 179 | #define ICH_AP0R2_EL2 __AP0Rx_EL2(2) | ||
| 180 | #define ICH_AP0R3_EL2 __AP0Rx_EL2(3) | ||
| 181 | |||
| 182 | #define __AP1Rx_EL2(x) sys_reg(3, 4, 12, 9, x) | ||
| 183 | #define ICH_AP1R0_EL2 __AP1Rx_EL2(0) | ||
| 184 | #define ICH_AP1R1_EL2 __AP1Rx_EL2(1) | ||
| 185 | #define ICH_AP1R2_EL2 __AP1Rx_EL2(2) | ||
| 186 | #define ICH_AP1R3_EL2 __AP1Rx_EL2(3) | ||
| 187 | |||
| 188 | #ifndef __ASSEMBLY__ | ||
| 189 | |||
| 190 | #include <linux/stringify.h> | ||
| 191 | |||
| 192 | static inline void gic_write_eoir(u64 irq) | ||
| 193 | { | ||
| 194 | asm volatile("msr_s " __stringify(ICC_EOIR1_EL1) ", %0" : : "r" (irq)); | ||
| 195 | isb(); | ||
| 196 | } | ||
| 197 | |||
| 198 | #endif | ||
| 199 | |||
| 200 | #endif | ||
diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h index cf6714752b69..3b9ff33e1768 100644 --- a/include/uapi/linux/audit.h +++ b/include/uapi/linux/audit.h | |||
| @@ -342,6 +342,7 @@ enum { | |||
| 342 | #define __AUDIT_ARCH_64BIT 0x80000000 | 342 | #define __AUDIT_ARCH_64BIT 0x80000000 |
| 343 | #define __AUDIT_ARCH_LE 0x40000000 | 343 | #define __AUDIT_ARCH_LE 0x40000000 |
| 344 | 344 | ||
| 345 | #define AUDIT_ARCH_AARCH64 (EM_AARCH64|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE) | ||
| 345 | #define AUDIT_ARCH_ALPHA (EM_ALPHA|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE) | 346 | #define AUDIT_ARCH_ALPHA (EM_ALPHA|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE) |
| 346 | #define AUDIT_ARCH_ARM (EM_ARM|__AUDIT_ARCH_LE) | 347 | #define AUDIT_ARCH_ARM (EM_ARM|__AUDIT_ARCH_LE) |
| 347 | #define AUDIT_ARCH_ARMEB (EM_ARM) | 348 | #define AUDIT_ARCH_ARMEB (EM_ARM) |
