Commit cdc63a059508b96cad1de793437ad2296d80ffe6
Exists in
ti-lsk-linux-4.1.y
and in
10 other branches
Merge tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux
Pull arm64 fixes from Catalin Marinas: - enable 48-bit VA space now that KVM has been fixed, together with a couple of fixes for pgd allocation alignment and initial memblock current_limit. There is still a dependency on !ARM_SMMU which needs to be updated as it uses the page table manipulation macros of the host kernel - eBPF fixes following changes/conflicts during the merging window - Compat types affecting compat_elf_prpsinfo - Compilation error on UP builds - ASLR fix when /proc/sys/kernel/randomize_va_space == 0 - DT definitions for CLCD support on ARMv8 model platform * tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux: arm64: Fix memblock current_limit with 64K pages and 48-bit VA arm64: ASLR: Don't randomise text when randomise_va_space == 0 arm64: vexpress: Add CLCD support to the ARMv8 model platform arm64: Fix compilation error on UP builds Documentation/arm64/memory.txt: fix typo net: bpf: arm64: minor fix of type in jited arm64: bpf: add 'load 64-bit immediate' instruction arm64: bpf: add 'shift by register' instructions net: bpf: arm64: address randomize and write protect JIT code arm64: mm: Correct fixmap pagetable types arm64: compat: fix compat types affecting struct compat_elf_prpsinfo arm64: Align less than PAGE_SIZE pgds naturally arm64: Allow 48-bits VA space without ARM_SMMU
Showing 13 changed files Side-by-side Diff
- Documentation/arm64/memory.txt
- arch/arm64/Kconfig
- arch/arm64/boot/dts/rtsm_ve-motherboard.dtsi
- arch/arm64/configs/defconfig
- arch/arm64/include/asm/compat.h
- arch/arm64/include/asm/elf.h
- arch/arm64/include/asm/irq_work.h
- arch/arm64/kernel/process.c
- arch/arm64/mm/ioremap.c
- arch/arm64/mm/mmu.c
- arch/arm64/mm/pgd.c
- arch/arm64/net/bpf_jit.h
- arch/arm64/net/bpf_jit_comp.c
Documentation/arm64/memory.txt
... | ... | @@ -17,7 +17,7 @@ |
17 | 17 | the same bits set to 1. TTBRx selection is given by bit 63 of the |
18 | 18 | virtual address. The swapper_pg_dir contains only kernel (global) |
19 | 19 | mappings while the user pgd contains only user (non-global) mappings. |
20 | -The swapper_pgd_dir address is written to TTBR1 and never written to | |
20 | +The swapper_pg_dir address is written to TTBR1 and never written to | |
21 | 21 | TTBR0. |
22 | 22 | |
23 | 23 |
arch/arm64/Kconfig
1 | 1 | config ARM64 |
2 | 2 | def_bool y |
3 | + select ARCH_BINFMT_ELF_RANDOMIZE_PIE | |
3 | 4 | select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE |
4 | 5 | select ARCH_HAS_SG_CHAIN |
5 | 6 | select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST |
... | ... | @@ -232,7 +233,7 @@ |
232 | 233 | |
233 | 234 | config ARM64_VA_BITS_48 |
234 | 235 | bool "48-bit" |
235 | - depends on BROKEN | |
236 | + depends on !ARM_SMMU | |
236 | 237 | |
237 | 238 | endchoice |
238 | 239 |
arch/arm64/boot/dts/rtsm_ve-motherboard.dtsi
... | ... | @@ -22,7 +22,7 @@ |
22 | 22 | bank-width = <4>; |
23 | 23 | }; |
24 | 24 | |
25 | - vram@2,00000000 { | |
25 | + v2m_video_ram: vram@2,00000000 { | |
26 | 26 | compatible = "arm,vexpress-vram"; |
27 | 27 | reg = <2 0x00000000 0x00800000>; |
28 | 28 | }; |
29 | 29 | |
... | ... | @@ -179,9 +179,42 @@ |
179 | 179 | clcd@1f0000 { |
180 | 180 | compatible = "arm,pl111", "arm,primecell"; |
181 | 181 | reg = <0x1f0000 0x1000>; |
182 | + interrupt-names = "combined"; | |
182 | 183 | interrupts = <14>; |
183 | 184 | clocks = <&v2m_oscclk1>, <&v2m_clk24mhz>; |
184 | 185 | clock-names = "clcdclk", "apb_pclk"; |
186 | + arm,pl11x,framebuffer = <0x18000000 0x00180000>; | |
187 | + memory-region = <&v2m_video_ram>; | |
188 | + max-memory-bandwidth = <130000000>; /* 16bpp @ 63.5MHz */ | |
189 | + | |
190 | + port { | |
191 | + v2m_clcd_pads: endpoint { | |
192 | + remote-endpoint = <&v2m_clcd_panel>; | |
193 | + arm,pl11x,tft-r0g0b0-pads = <0 8 16>; | |
194 | + }; | |
195 | + }; | |
196 | + | |
197 | + panel { | |
198 | + compatible = "panel-dpi"; | |
199 | + | |
200 | + port { | |
201 | + v2m_clcd_panel: endpoint { | |
202 | + remote-endpoint = <&v2m_clcd_pads>; | |
203 | + }; | |
204 | + }; | |
205 | + | |
206 | + panel-timing { | |
207 | + clock-frequency = <63500127>; | |
208 | + hactive = <1024>; | |
209 | + hback-porch = <152>; | |
210 | + hfront-porch = <48>; | |
211 | + hsync-len = <104>; | |
212 | + vactive = <768>; | |
213 | + vback-porch = <23>; | |
214 | + vfront-porch = <3>; | |
215 | + vsync-len = <4>; | |
216 | + }; | |
217 | + }; | |
185 | 218 | }; |
186 | 219 | |
187 | 220 | virtio_block@0130000 { |
arch/arm64/configs/defconfig
... | ... | @@ -78,6 +78,7 @@ |
78 | 78 | # CONFIG_WLAN is not set |
79 | 79 | CONFIG_INPUT_EVDEV=y |
80 | 80 | # CONFIG_SERIO_SERPORT is not set |
81 | +CONFIG_SERIO_AMBAKMI=y | |
81 | 82 | CONFIG_LEGACY_PTY_COUNT=16 |
82 | 83 | CONFIG_SERIAL_8250=y |
83 | 84 | CONFIG_SERIAL_8250_CONSOLE=y |
... | ... | @@ -90,6 +91,7 @@ |
90 | 91 | CONFIG_REGULATOR=y |
91 | 92 | CONFIG_REGULATOR_FIXED_VOLTAGE=y |
92 | 93 | CONFIG_FB=y |
94 | +CONFIG_FB_ARMCLCD=y | |
93 | 95 | CONFIG_FRAMEBUFFER_CONSOLE=y |
94 | 96 | CONFIG_LOGO=y |
95 | 97 | # CONFIG_LOGO_LINUX_MONO is not set |
arch/arm64/include/asm/compat.h
... | ... | @@ -37,8 +37,8 @@ |
37 | 37 | typedef s32 compat_time_t; |
38 | 38 | typedef s32 compat_clock_t; |
39 | 39 | typedef s32 compat_pid_t; |
40 | -typedef u32 __compat_uid_t; | |
41 | -typedef u32 __compat_gid_t; | |
40 | +typedef u16 __compat_uid_t; | |
41 | +typedef u16 __compat_gid_t; | |
42 | 42 | typedef u16 __compat_uid16_t; |
43 | 43 | typedef u16 __compat_gid16_t; |
44 | 44 | typedef u32 __compat_uid32_t; |
arch/arm64/include/asm/elf.h
... | ... | @@ -126,7 +126,7 @@ |
126 | 126 | * that it will "exec", and that there is sufficient room for the brk. |
127 | 127 | */ |
128 | 128 | extern unsigned long randomize_et_dyn(unsigned long base); |
129 | -#define ELF_ET_DYN_BASE (randomize_et_dyn(2 * TASK_SIZE_64 / 3)) | |
129 | +#define ELF_ET_DYN_BASE (2 * TASK_SIZE_64 / 3) | |
130 | 130 | |
131 | 131 | /* |
132 | 132 | * When the program starts, a1 contains a pointer to a function to be |
... | ... | @@ -169,7 +169,7 @@ |
169 | 169 | #define COMPAT_ELF_PLATFORM ("v8l") |
170 | 170 | #endif |
171 | 171 | |
172 | -#define COMPAT_ELF_ET_DYN_BASE (randomize_et_dyn(2 * TASK_SIZE_32 / 3)) | |
172 | +#define COMPAT_ELF_ET_DYN_BASE (2 * TASK_SIZE_32 / 3) | |
173 | 173 | |
174 | 174 | /* AArch32 registers. */ |
175 | 175 | #define COMPAT_ELF_NGREG 18 |
arch/arm64/include/asm/irq_work.h
1 | 1 | #ifndef __ASM_IRQ_WORK_H |
2 | 2 | #define __ASM_IRQ_WORK_H |
3 | 3 | |
4 | +#ifdef CONFIG_SMP | |
5 | + | |
4 | 6 | #include <asm/smp.h> |
5 | 7 | |
6 | 8 | static inline bool arch_irq_work_has_interrupt(void) |
7 | 9 | { |
8 | 10 | return !!__smp_cross_call; |
9 | 11 | } |
12 | + | |
13 | +#else | |
14 | + | |
15 | +static inline bool arch_irq_work_has_interrupt(void) | |
16 | +{ | |
17 | + return false; | |
18 | +} | |
19 | + | |
20 | +#endif | |
10 | 21 | |
11 | 22 | #endif /* __ASM_IRQ_WORK_H */ |
arch/arm64/kernel/process.c
arch/arm64/mm/ioremap.c
... | ... | @@ -105,10 +105,10 @@ |
105 | 105 | |
106 | 106 | static pte_t bm_pte[PTRS_PER_PTE] __page_aligned_bss; |
107 | 107 | #if CONFIG_ARM64_PGTABLE_LEVELS > 2 |
108 | -static pte_t bm_pmd[PTRS_PER_PMD] __page_aligned_bss; | |
108 | +static pmd_t bm_pmd[PTRS_PER_PMD] __page_aligned_bss; | |
109 | 109 | #endif |
110 | 110 | #if CONFIG_ARM64_PGTABLE_LEVELS > 3 |
111 | -static pte_t bm_pud[PTRS_PER_PUD] __page_aligned_bss; | |
111 | +static pud_t bm_pud[PTRS_PER_PUD] __page_aligned_bss; | |
112 | 112 | #endif |
113 | 113 | |
114 | 114 | static inline pud_t * __init early_ioremap_pud(unsigned long addr) |
arch/arm64/mm/mmu.c
... | ... | @@ -297,11 +297,15 @@ |
297 | 297 | * create_mapping requires puds, pmds and ptes to be allocated from |
298 | 298 | * memory addressable from the initial direct kernel mapping. |
299 | 299 | * |
300 | - * The initial direct kernel mapping, located at swapper_pg_dir, | |
301 | - * gives us PUD_SIZE memory starting from PHYS_OFFSET (which must be | |
302 | - * aligned to 2MB as per Documentation/arm64/booting.txt). | |
300 | + * The initial direct kernel mapping, located at swapper_pg_dir, gives | |
301 | + * us PUD_SIZE (4K pages) or PMD_SIZE (64K pages) memory starting from | |
302 | + * PHYS_OFFSET (which must be aligned to 2MB as per | |
303 | + * Documentation/arm64/booting.txt). | |
303 | 304 | */ |
304 | - limit = PHYS_OFFSET + PUD_SIZE; | |
305 | + if (IS_ENABLED(CONFIG_ARM64_64K_PAGES)) | |
306 | + limit = PHYS_OFFSET + PMD_SIZE; | |
307 | + else | |
308 | + limit = PHYS_OFFSET + PUD_SIZE; | |
305 | 309 | memblock_set_current_limit(limit); |
306 | 310 | |
307 | 311 | /* map all the memory banks */ |
arch/arm64/mm/pgd.c
... | ... | @@ -30,12 +30,14 @@ |
30 | 30 | |
31 | 31 | #define PGD_SIZE (PTRS_PER_PGD * sizeof(pgd_t)) |
32 | 32 | |
33 | +static struct kmem_cache *pgd_cache; | |
34 | + | |
33 | 35 | pgd_t *pgd_alloc(struct mm_struct *mm) |
34 | 36 | { |
35 | 37 | if (PGD_SIZE == PAGE_SIZE) |
36 | 38 | return (pgd_t *)get_zeroed_page(GFP_KERNEL); |
37 | 39 | else |
38 | - return kzalloc(PGD_SIZE, GFP_KERNEL); | |
40 | + return kmem_cache_zalloc(pgd_cache, GFP_KERNEL); | |
39 | 41 | } |
40 | 42 | |
41 | 43 | void pgd_free(struct mm_struct *mm, pgd_t *pgd) |
42 | 44 | |
... | ... | @@ -43,6 +45,18 @@ |
43 | 45 | if (PGD_SIZE == PAGE_SIZE) |
44 | 46 | free_page((unsigned long)pgd); |
45 | 47 | else |
46 | - kfree(pgd); | |
48 | + kmem_cache_free(pgd_cache, pgd); | |
47 | 49 | } |
50 | + | |
51 | +static int __init pgd_cache_init(void) | |
52 | +{ | |
53 | + /* | |
54 | + * Naturally aligned pgds required by the architecture. | |
55 | + */ | |
56 | + if (PGD_SIZE != PAGE_SIZE) | |
57 | + pgd_cache = kmem_cache_create("pgd_cache", PGD_SIZE, PGD_SIZE, | |
58 | + SLAB_PANIC, NULL); | |
59 | + return 0; | |
60 | +} | |
61 | +core_initcall(pgd_cache_init); |
arch/arm64/net/bpf_jit.h
... | ... | @@ -144,8 +144,12 @@ |
144 | 144 | |
145 | 145 | /* Data-processing (2 source) */ |
146 | 146 | /* Rd = Rn OP Rm */ |
147 | -#define A64_UDIV(sf, Rd, Rn, Rm) aarch64_insn_gen_data2(Rd, Rn, Rm, \ | |
148 | - A64_VARIANT(sf), AARCH64_INSN_DATA2_UDIV) | |
147 | +#define A64_DATA2(sf, Rd, Rn, Rm, type) aarch64_insn_gen_data2(Rd, Rn, Rm, \ | |
148 | + A64_VARIANT(sf), AARCH64_INSN_DATA2_##type) | |
149 | +#define A64_UDIV(sf, Rd, Rn, Rm) A64_DATA2(sf, Rd, Rn, Rm, UDIV) | |
150 | +#define A64_LSLV(sf, Rd, Rn, Rm) A64_DATA2(sf, Rd, Rn, Rm, LSLV) | |
151 | +#define A64_LSRV(sf, Rd, Rn, Rm) A64_DATA2(sf, Rd, Rn, Rm, LSRV) | |
152 | +#define A64_ASRV(sf, Rd, Rn, Rm) A64_DATA2(sf, Rd, Rn, Rm, ASRV) | |
149 | 153 | |
150 | 154 | /* Data-processing (3 source) */ |
151 | 155 | /* Rd = Ra + Rn * Rm */ |
arch/arm64/net/bpf_jit_comp.c
... | ... | @@ -19,12 +19,13 @@ |
19 | 19 | #define pr_fmt(fmt) "bpf_jit: " fmt |
20 | 20 | |
21 | 21 | #include <linux/filter.h> |
22 | -#include <linux/moduleloader.h> | |
23 | 22 | #include <linux/printk.h> |
24 | 23 | #include <linux/skbuff.h> |
25 | 24 | #include <linux/slab.h> |
25 | + | |
26 | 26 | #include <asm/byteorder.h> |
27 | 27 | #include <asm/cacheflush.h> |
28 | +#include <asm/debug-monitors.h> | |
28 | 29 | |
29 | 30 | #include "bpf_jit.h" |
30 | 31 | |
... | ... | @@ -119,6 +120,14 @@ |
119 | 120 | return to - from; |
120 | 121 | } |
121 | 122 | |
123 | +static void jit_fill_hole(void *area, unsigned int size) | |
124 | +{ | |
125 | + u32 *ptr; | |
126 | + /* We are guaranteed to have aligned memory. */ | |
127 | + for (ptr = area; size >= sizeof(u32); size -= sizeof(u32)) | |
128 | + *ptr++ = cpu_to_le32(AARCH64_BREAK_FAULT); | |
129 | +} | |
130 | + | |
122 | 131 | static inline int epilogue_offset(const struct jit_ctx *ctx) |
123 | 132 | { |
124 | 133 | int to = ctx->offset[ctx->prog->len - 1]; |
... | ... | @@ -196,6 +205,12 @@ |
196 | 205 | emit(A64_RET(A64_LR), ctx); |
197 | 206 | } |
198 | 207 | |
208 | +/* JITs an eBPF instruction. | |
209 | + * Returns: | |
210 | + * 0 - successfully JITed an 8-byte eBPF instruction. | |
211 | + * >0 - successfully JITed a 16-byte eBPF instruction. | |
212 | + * <0 - failed to JIT. | |
213 | + */ | |
199 | 214 | static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx) |
200 | 215 | { |
201 | 216 | const u8 code = insn->code; |
... | ... | @@ -252,6 +267,18 @@ |
252 | 267 | emit(A64_MUL(is64, tmp, tmp, src), ctx); |
253 | 268 | emit(A64_SUB(is64, dst, dst, tmp), ctx); |
254 | 269 | break; |
270 | + case BPF_ALU | BPF_LSH | BPF_X: | |
271 | + case BPF_ALU64 | BPF_LSH | BPF_X: | |
272 | + emit(A64_LSLV(is64, dst, dst, src), ctx); | |
273 | + break; | |
274 | + case BPF_ALU | BPF_RSH | BPF_X: | |
275 | + case BPF_ALU64 | BPF_RSH | BPF_X: | |
276 | + emit(A64_LSRV(is64, dst, dst, src), ctx); | |
277 | + break; | |
278 | + case BPF_ALU | BPF_ARSH | BPF_X: | |
279 | + case BPF_ALU64 | BPF_ARSH | BPF_X: | |
280 | + emit(A64_ASRV(is64, dst, dst, src), ctx); | |
281 | + break; | |
255 | 282 | /* dst = -dst */ |
256 | 283 | case BPF_ALU | BPF_NEG: |
257 | 284 | case BPF_ALU64 | BPF_NEG: |
... | ... | @@ -443,6 +470,27 @@ |
443 | 470 | emit(A64_B(jmp_offset), ctx); |
444 | 471 | break; |
445 | 472 | |
473 | + /* dst = imm64 */ | |
474 | + case BPF_LD | BPF_IMM | BPF_DW: | |
475 | + { | |
476 | + const struct bpf_insn insn1 = insn[1]; | |
477 | + u64 imm64; | |
478 | + | |
479 | + if (insn1.code != 0 || insn1.src_reg != 0 || | |
480 | + insn1.dst_reg != 0 || insn1.off != 0) { | |
481 | + /* Note: verifier in BPF core must catch invalid | |
482 | + * instructions. | |
483 | + */ | |
484 | + pr_err_once("Invalid BPF_LD_IMM64 instruction\n"); | |
485 | + return -EINVAL; | |
486 | + } | |
487 | + | |
488 | + imm64 = (u64)insn1.imm << 32 | imm; | |
489 | + emit_a64_mov_i64(dst, imm64, ctx); | |
490 | + | |
491 | + return 1; | |
492 | + } | |
493 | + | |
446 | 494 | /* LDX: dst = *(size *)(src + off) */ |
447 | 495 | case BPF_LDX | BPF_MEM | BPF_W: |
448 | 496 | case BPF_LDX | BPF_MEM | BPF_H: |
... | ... | @@ -594,6 +642,10 @@ |
594 | 642 | ctx->offset[i] = ctx->idx; |
595 | 643 | |
596 | 644 | ret = build_insn(insn, ctx); |
645 | + if (ret > 0) { | |
646 | + i++; | |
647 | + continue; | |
648 | + } | |
597 | 649 | if (ret) |
598 | 650 | return ret; |
599 | 651 | } |
600 | 652 | |
... | ... | @@ -613,8 +665,10 @@ |
613 | 665 | |
614 | 666 | void bpf_int_jit_compile(struct bpf_prog *prog) |
615 | 667 | { |
668 | + struct bpf_binary_header *header; | |
616 | 669 | struct jit_ctx ctx; |
617 | 670 | int image_size; |
671 | + u8 *image_ptr; | |
618 | 672 | |
619 | 673 | if (!bpf_jit_enable) |
620 | 674 | return; |
621 | 675 | |
622 | 676 | |
623 | 677 | |
624 | 678 | |
... | ... | @@ -636,23 +690,25 @@ |
636 | 690 | goto out; |
637 | 691 | |
638 | 692 | build_prologue(&ctx); |
639 | - | |
640 | 693 | build_epilogue(&ctx); |
641 | 694 | |
642 | 695 | /* Now we know the actual image size. */ |
643 | 696 | image_size = sizeof(u32) * ctx.idx; |
644 | - ctx.image = module_alloc(image_size); | |
645 | - if (unlikely(ctx.image == NULL)) | |
697 | + header = bpf_jit_binary_alloc(image_size, &image_ptr, | |
698 | + sizeof(u32), jit_fill_hole); | |
699 | + if (header == NULL) | |
646 | 700 | goto out; |
647 | 701 | |
648 | 702 | /* 2. Now, the actual pass. */ |
649 | 703 | |
704 | + ctx.image = (u32 *)image_ptr; | |
650 | 705 | ctx.idx = 0; |
706 | + | |
651 | 707 | build_prologue(&ctx); |
652 | 708 | |
653 | 709 | ctx.body_offset = ctx.idx; |
654 | 710 | if (build_body(&ctx)) { |
655 | - module_free(NULL, ctx.image); | |
711 | + bpf_jit_binary_free(header); | |
656 | 712 | goto out; |
657 | 713 | } |
658 | 714 | |
659 | 715 | |
660 | 716 | |
661 | 717 | |
... | ... | @@ -663,18 +719,26 @@ |
663 | 719 | bpf_jit_dump(prog->len, image_size, 2, ctx.image); |
664 | 720 | |
665 | 721 | bpf_flush_icache(ctx.image, ctx.image + ctx.idx); |
666 | - prog->bpf_func = (void *)ctx.image; | |
667 | - prog->jited = 1; | |
668 | 722 | |
723 | + set_memory_ro((unsigned long)header, header->pages); | |
724 | + prog->bpf_func = (void *)ctx.image; | |
725 | + prog->jited = true; | |
669 | 726 | out: |
670 | 727 | kfree(ctx.offset); |
671 | 728 | } |
672 | 729 | |
673 | 730 | void bpf_jit_free(struct bpf_prog *prog) |
674 | 731 | { |
675 | - if (prog->jited) | |
676 | - module_free(NULL, prog->bpf_func); | |
732 | + unsigned long addr = (unsigned long)prog->bpf_func & PAGE_MASK; | |
733 | + struct bpf_binary_header *header = (void *)addr; | |
677 | 734 | |
678 | - kfree(prog); | |
735 | + if (!prog->jited) | |
736 | + goto free_filter; | |
737 | + | |
738 | + set_memory_rw(addr, header->pages); | |
739 | + bpf_jit_binary_free(header); | |
740 | + | |
741 | +free_filter: | |
742 | + bpf_prog_unlock_free(prog); | |
679 | 743 | } |