Commit cdc63a05 authored by Linus Torvalds's avatar Linus Torvalds

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
parents 83da00fb 3dec0fe4
...@@ -17,7 +17,7 @@ User addresses have bits 63:48 set to 0 while the kernel addresses have ...@@ -17,7 +17,7 @@ User addresses have bits 63:48 set to 0 while the kernel addresses have
the same bits set to 1. TTBRx selection is given by bit 63 of the the same bits set to 1. TTBRx selection is given by bit 63 of the
virtual address. The swapper_pg_dir contains only kernel (global) virtual address. The swapper_pg_dir contains only kernel (global)
mappings while the user pgd contains only user (non-global) mappings. mappings while the user pgd contains only user (non-global) mappings.
The swapper_pgd_dir address is written to TTBR1 and never written to The swapper_pg_dir address is written to TTBR1 and never written to
TTBR0. TTBR0.
......
config ARM64 config ARM64
def_bool y def_bool y
select ARCH_BINFMT_ELF_RANDOMIZE_PIE
select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
select ARCH_HAS_SG_CHAIN select ARCH_HAS_SG_CHAIN
select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
...@@ -232,7 +233,7 @@ config ARM64_VA_BITS_42 ...@@ -232,7 +233,7 @@ config ARM64_VA_BITS_42
config ARM64_VA_BITS_48 config ARM64_VA_BITS_48
bool "48-bit" bool "48-bit"
depends on BROKEN depends on !ARM_SMMU
endchoice endchoice
......
...@@ -22,7 +22,7 @@ flash@0,00000000 { ...@@ -22,7 +22,7 @@ flash@0,00000000 {
bank-width = <4>; bank-width = <4>;
}; };
vram@2,00000000 { v2m_video_ram: vram@2,00000000 {
compatible = "arm,vexpress-vram"; compatible = "arm,vexpress-vram";
reg = <2 0x00000000 0x00800000>; reg = <2 0x00000000 0x00800000>;
}; };
...@@ -179,9 +179,42 @@ rtc@170000 { ...@@ -179,9 +179,42 @@ rtc@170000 {
clcd@1f0000 { clcd@1f0000 {
compatible = "arm,pl111", "arm,primecell"; compatible = "arm,pl111", "arm,primecell";
reg = <0x1f0000 0x1000>; reg = <0x1f0000 0x1000>;
interrupt-names = "combined";
interrupts = <14>; interrupts = <14>;
clocks = <&v2m_oscclk1>, <&v2m_clk24mhz>; clocks = <&v2m_oscclk1>, <&v2m_clk24mhz>;
clock-names = "clcdclk", "apb_pclk"; clock-names = "clcdclk", "apb_pclk";
arm,pl11x,framebuffer = <0x18000000 0x00180000>;
memory-region = <&v2m_video_ram>;
max-memory-bandwidth = <130000000>; /* 16bpp @ 63.5MHz */
port {
v2m_clcd_pads: endpoint {
remote-endpoint = <&v2m_clcd_panel>;
arm,pl11x,tft-r0g0b0-pads = <0 8 16>;
};
};
panel {
compatible = "panel-dpi";
port {
v2m_clcd_panel: endpoint {
remote-endpoint = <&v2m_clcd_pads>;
};
};
panel-timing {
clock-frequency = <63500127>;
hactive = <1024>;
hback-porch = <152>;
hfront-porch = <48>;
hsync-len = <104>;
vactive = <768>;
vback-porch = <23>;
vfront-porch = <3>;
vsync-len = <4>;
};
};
}; };
virtio_block@0130000 { virtio_block@0130000 {
......
...@@ -78,6 +78,7 @@ CONFIG_NET_XGENE=y ...@@ -78,6 +78,7 @@ CONFIG_NET_XGENE=y
# CONFIG_WLAN is not set # CONFIG_WLAN is not set
CONFIG_INPUT_EVDEV=y CONFIG_INPUT_EVDEV=y
# CONFIG_SERIO_SERPORT is not set # CONFIG_SERIO_SERPORT is not set
CONFIG_SERIO_AMBAKMI=y
CONFIG_LEGACY_PTY_COUNT=16 CONFIG_LEGACY_PTY_COUNT=16
CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_CONSOLE=y
...@@ -90,6 +91,7 @@ CONFIG_VIRTIO_CONSOLE=y ...@@ -90,6 +91,7 @@ CONFIG_VIRTIO_CONSOLE=y
CONFIG_REGULATOR=y CONFIG_REGULATOR=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_FB=y CONFIG_FB=y
CONFIG_FB_ARMCLCD=y
CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE=y
CONFIG_LOGO=y CONFIG_LOGO=y
# CONFIG_LOGO_LINUX_MONO is not set # CONFIG_LOGO_LINUX_MONO is not set
......
...@@ -37,8 +37,8 @@ typedef s32 compat_ssize_t; ...@@ -37,8 +37,8 @@ typedef s32 compat_ssize_t;
typedef s32 compat_time_t; typedef s32 compat_time_t;
typedef s32 compat_clock_t; typedef s32 compat_clock_t;
typedef s32 compat_pid_t; typedef s32 compat_pid_t;
typedef u32 __compat_uid_t; typedef u16 __compat_uid_t;
typedef u32 __compat_gid_t; typedef u16 __compat_gid_t;
typedef u16 __compat_uid16_t; typedef u16 __compat_uid16_t;
typedef u16 __compat_gid16_t; typedef u16 __compat_gid16_t;
typedef u32 __compat_uid32_t; typedef u32 __compat_uid32_t;
......
...@@ -126,7 +126,7 @@ typedef struct user_fpsimd_state elf_fpregset_t; ...@@ -126,7 +126,7 @@ typedef struct user_fpsimd_state elf_fpregset_t;
* that it will "exec", and that there is sufficient room for the brk. * that it will "exec", and that there is sufficient room for the brk.
*/ */
extern unsigned long randomize_et_dyn(unsigned long base); extern unsigned long randomize_et_dyn(unsigned long base);
#define ELF_ET_DYN_BASE (randomize_et_dyn(2 * TASK_SIZE_64 / 3)) #define ELF_ET_DYN_BASE (2 * TASK_SIZE_64 / 3)
/* /*
* When the program starts, a1 contains a pointer to a function to be * When the program starts, a1 contains a pointer to a function to be
...@@ -169,7 +169,7 @@ extern unsigned long arch_randomize_brk(struct mm_struct *mm); ...@@ -169,7 +169,7 @@ extern unsigned long arch_randomize_brk(struct mm_struct *mm);
#define COMPAT_ELF_PLATFORM ("v8l") #define COMPAT_ELF_PLATFORM ("v8l")
#endif #endif
#define COMPAT_ELF_ET_DYN_BASE (randomize_et_dyn(2 * TASK_SIZE_32 / 3)) #define COMPAT_ELF_ET_DYN_BASE (2 * TASK_SIZE_32 / 3)
/* AArch32 registers. */ /* AArch32 registers. */
#define COMPAT_ELF_NGREG 18 #define COMPAT_ELF_NGREG 18
......
#ifndef __ASM_IRQ_WORK_H #ifndef __ASM_IRQ_WORK_H
#define __ASM_IRQ_WORK_H #define __ASM_IRQ_WORK_H
#ifdef CONFIG_SMP
#include <asm/smp.h> #include <asm/smp.h>
static inline bool arch_irq_work_has_interrupt(void) static inline bool arch_irq_work_has_interrupt(void)
...@@ -8,4 +10,13 @@ static inline bool arch_irq_work_has_interrupt(void) ...@@ -8,4 +10,13 @@ static inline bool arch_irq_work_has_interrupt(void)
return !!__smp_cross_call; return !!__smp_cross_call;
} }
#else
static inline bool arch_irq_work_has_interrupt(void)
{
return false;
}
#endif
#endif /* __ASM_IRQ_WORK_H */ #endif /* __ASM_IRQ_WORK_H */
...@@ -378,8 +378,3 @@ unsigned long arch_randomize_brk(struct mm_struct *mm) ...@@ -378,8 +378,3 @@ unsigned long arch_randomize_brk(struct mm_struct *mm)
{ {
return randomize_base(mm->brk); return randomize_base(mm->brk);
} }
unsigned long randomize_et_dyn(unsigned long base)
{
return randomize_base(base);
}
...@@ -105,10 +105,10 @@ EXPORT_SYMBOL(ioremap_cache); ...@@ -105,10 +105,10 @@ EXPORT_SYMBOL(ioremap_cache);
static pte_t bm_pte[PTRS_PER_PTE] __page_aligned_bss; static pte_t bm_pte[PTRS_PER_PTE] __page_aligned_bss;
#if CONFIG_ARM64_PGTABLE_LEVELS > 2 #if CONFIG_ARM64_PGTABLE_LEVELS > 2
static pte_t bm_pmd[PTRS_PER_PMD] __page_aligned_bss; static pmd_t bm_pmd[PTRS_PER_PMD] __page_aligned_bss;
#endif #endif
#if CONFIG_ARM64_PGTABLE_LEVELS > 3 #if CONFIG_ARM64_PGTABLE_LEVELS > 3
static pte_t bm_pud[PTRS_PER_PUD] __page_aligned_bss; static pud_t bm_pud[PTRS_PER_PUD] __page_aligned_bss;
#endif #endif
static inline pud_t * __init early_ioremap_pud(unsigned long addr) static inline pud_t * __init early_ioremap_pud(unsigned long addr)
......
...@@ -297,11 +297,15 @@ static void __init map_mem(void) ...@@ -297,11 +297,15 @@ static void __init map_mem(void)
* create_mapping requires puds, pmds and ptes to be allocated from * create_mapping requires puds, pmds and ptes to be allocated from
* memory addressable from the initial direct kernel mapping. * memory addressable from the initial direct kernel mapping.
* *
* The initial direct kernel mapping, located at swapper_pg_dir, * The initial direct kernel mapping, located at swapper_pg_dir, gives
* gives us PUD_SIZE memory starting from PHYS_OFFSET (which must be * us PUD_SIZE (4K pages) or PMD_SIZE (64K pages) memory starting from
* aligned to 2MB as per Documentation/arm64/booting.txt). * PHYS_OFFSET (which must be aligned to 2MB as per
* Documentation/arm64/booting.txt).
*/ */
limit = PHYS_OFFSET + PUD_SIZE; if (IS_ENABLED(CONFIG_ARM64_64K_PAGES))
limit = PHYS_OFFSET + PMD_SIZE;
else
limit = PHYS_OFFSET + PUD_SIZE;
memblock_set_current_limit(limit); memblock_set_current_limit(limit);
/* map all the memory banks */ /* map all the memory banks */
......
...@@ -30,12 +30,14 @@ ...@@ -30,12 +30,14 @@
#define PGD_SIZE (PTRS_PER_PGD * sizeof(pgd_t)) #define PGD_SIZE (PTRS_PER_PGD * sizeof(pgd_t))
static struct kmem_cache *pgd_cache;
pgd_t *pgd_alloc(struct mm_struct *mm) pgd_t *pgd_alloc(struct mm_struct *mm)
{ {
if (PGD_SIZE == PAGE_SIZE) if (PGD_SIZE == PAGE_SIZE)
return (pgd_t *)get_zeroed_page(GFP_KERNEL); return (pgd_t *)get_zeroed_page(GFP_KERNEL);
else else
return kzalloc(PGD_SIZE, GFP_KERNEL); return kmem_cache_zalloc(pgd_cache, GFP_KERNEL);
} }
void pgd_free(struct mm_struct *mm, pgd_t *pgd) void pgd_free(struct mm_struct *mm, pgd_t *pgd)
...@@ -43,5 +45,17 @@ void pgd_free(struct mm_struct *mm, pgd_t *pgd) ...@@ -43,5 +45,17 @@ void pgd_free(struct mm_struct *mm, pgd_t *pgd)
if (PGD_SIZE == PAGE_SIZE) if (PGD_SIZE == PAGE_SIZE)
free_page((unsigned long)pgd); free_page((unsigned long)pgd);
else else
kfree(pgd); kmem_cache_free(pgd_cache, pgd);
}
static int __init pgd_cache_init(void)
{
/*
* Naturally aligned pgds required by the architecture.
*/
if (PGD_SIZE != PAGE_SIZE)
pgd_cache = kmem_cache_create("pgd_cache", PGD_SIZE, PGD_SIZE,
SLAB_PANIC, NULL);
return 0;
} }
core_initcall(pgd_cache_init);
...@@ -144,8 +144,12 @@ ...@@ -144,8 +144,12 @@
/* Data-processing (2 source) */ /* Data-processing (2 source) */
/* Rd = Rn OP Rm */ /* Rd = Rn OP Rm */
#define A64_UDIV(sf, Rd, Rn, Rm) aarch64_insn_gen_data2(Rd, Rn, Rm, \ #define A64_DATA2(sf, Rd, Rn, Rm, type) aarch64_insn_gen_data2(Rd, Rn, Rm, \
A64_VARIANT(sf), AARCH64_INSN_DATA2_UDIV) A64_VARIANT(sf), AARCH64_INSN_DATA2_##type)
#define A64_UDIV(sf, Rd, Rn, Rm) A64_DATA2(sf, Rd, Rn, Rm, UDIV)
#define A64_LSLV(sf, Rd, Rn, Rm) A64_DATA2(sf, Rd, Rn, Rm, LSLV)
#define A64_LSRV(sf, Rd, Rn, Rm) A64_DATA2(sf, Rd, Rn, Rm, LSRV)
#define A64_ASRV(sf, Rd, Rn, Rm) A64_DATA2(sf, Rd, Rn, Rm, ASRV)
/* Data-processing (3 source) */ /* Data-processing (3 source) */
/* Rd = Ra + Rn * Rm */ /* Rd = Ra + Rn * Rm */
......
...@@ -19,12 +19,13 @@ ...@@ -19,12 +19,13 @@
#define pr_fmt(fmt) "bpf_jit: " fmt #define pr_fmt(fmt) "bpf_jit: " fmt
#include <linux/filter.h> #include <linux/filter.h>
#include <linux/moduleloader.h>
#include <linux/printk.h> #include <linux/printk.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <asm/byteorder.h> #include <asm/byteorder.h>
#include <asm/cacheflush.h> #include <asm/cacheflush.h>
#include <asm/debug-monitors.h>
#include "bpf_jit.h" #include "bpf_jit.h"
...@@ -119,6 +120,14 @@ static inline int bpf2a64_offset(int bpf_to, int bpf_from, ...@@ -119,6 +120,14 @@ static inline int bpf2a64_offset(int bpf_to, int bpf_from,
return to - from; return to - from;
} }
static void jit_fill_hole(void *area, unsigned int size)
{
u32 *ptr;
/* We are guaranteed to have aligned memory. */
for (ptr = area; size >= sizeof(u32); size -= sizeof(u32))
*ptr++ = cpu_to_le32(AARCH64_BREAK_FAULT);
}
static inline int epilogue_offset(const struct jit_ctx *ctx) static inline int epilogue_offset(const struct jit_ctx *ctx)
{ {
int to = ctx->offset[ctx->prog->len - 1]; int to = ctx->offset[ctx->prog->len - 1];
...@@ -196,6 +205,12 @@ static void build_epilogue(struct jit_ctx *ctx) ...@@ -196,6 +205,12 @@ static void build_epilogue(struct jit_ctx *ctx)
emit(A64_RET(A64_LR), ctx); emit(A64_RET(A64_LR), ctx);
} }
/* JITs an eBPF instruction.
* Returns:
* 0 - successfully JITed an 8-byte eBPF instruction.
* >0 - successfully JITed a 16-byte eBPF instruction.
* <0 - failed to JIT.
*/
static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx) static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
{ {
const u8 code = insn->code; const u8 code = insn->code;
...@@ -252,6 +267,18 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx) ...@@ -252,6 +267,18 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
emit(A64_MUL(is64, tmp, tmp, src), ctx); emit(A64_MUL(is64, tmp, tmp, src), ctx);
emit(A64_SUB(is64, dst, dst, tmp), ctx); emit(A64_SUB(is64, dst, dst, tmp), ctx);
break; break;
case BPF_ALU | BPF_LSH | BPF_X:
case BPF_ALU64 | BPF_LSH | BPF_X:
emit(A64_LSLV(is64, dst, dst, src), ctx);
break;
case BPF_ALU | BPF_RSH | BPF_X:
case BPF_ALU64 | BPF_RSH | BPF_X:
emit(A64_LSRV(is64, dst, dst, src), ctx);
break;
case BPF_ALU | BPF_ARSH | BPF_X:
case BPF_ALU64 | BPF_ARSH | BPF_X:
emit(A64_ASRV(is64, dst, dst, src), ctx);
break;
/* dst = -dst */ /* dst = -dst */
case BPF_ALU | BPF_NEG: case BPF_ALU | BPF_NEG:
case BPF_ALU64 | BPF_NEG: case BPF_ALU64 | BPF_NEG:
...@@ -443,6 +470,27 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx) ...@@ -443,6 +470,27 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
emit(A64_B(jmp_offset), ctx); emit(A64_B(jmp_offset), ctx);
break; break;
/* dst = imm64 */
case BPF_LD | BPF_IMM | BPF_DW:
{
const struct bpf_insn insn1 = insn[1];
u64 imm64;
if (insn1.code != 0 || insn1.src_reg != 0 ||
insn1.dst_reg != 0 || insn1.off != 0) {
/* Note: verifier in BPF core must catch invalid
* instructions.
*/
pr_err_once("Invalid BPF_LD_IMM64 instruction\n");
return -EINVAL;
}
imm64 = (u64)insn1.imm << 32 | imm;
emit_a64_mov_i64(dst, imm64, ctx);
return 1;
}
/* LDX: dst = *(size *)(src + off) */ /* LDX: dst = *(size *)(src + off) */
case BPF_LDX | BPF_MEM | BPF_W: case BPF_LDX | BPF_MEM | BPF_W:
case BPF_LDX | BPF_MEM | BPF_H: case BPF_LDX | BPF_MEM | BPF_H:
...@@ -594,6 +642,10 @@ static int build_body(struct jit_ctx *ctx) ...@@ -594,6 +642,10 @@ static int build_body(struct jit_ctx *ctx)
ctx->offset[i] = ctx->idx; ctx->offset[i] = ctx->idx;
ret = build_insn(insn, ctx); ret = build_insn(insn, ctx);
if (ret > 0) {
i++;
continue;
}
if (ret) if (ret)
return ret; return ret;
} }
...@@ -613,8 +665,10 @@ void bpf_jit_compile(struct bpf_prog *prog) ...@@ -613,8 +665,10 @@ void bpf_jit_compile(struct bpf_prog *prog)
void bpf_int_jit_compile(struct bpf_prog *prog) void bpf_int_jit_compile(struct bpf_prog *prog)
{ {
struct bpf_binary_header *header;
struct jit_ctx ctx; struct jit_ctx ctx;
int image_size; int image_size;
u8 *image_ptr;
if (!bpf_jit_enable) if (!bpf_jit_enable)
return; return;
...@@ -636,23 +690,25 @@ void bpf_int_jit_compile(struct bpf_prog *prog) ...@@ -636,23 +690,25 @@ void bpf_int_jit_compile(struct bpf_prog *prog)
goto out; goto out;
build_prologue(&ctx); build_prologue(&ctx);
build_epilogue(&ctx); build_epilogue(&ctx);
/* Now we know the actual image size. */ /* Now we know the actual image size. */
image_size = sizeof(u32) * ctx.idx; image_size = sizeof(u32) * ctx.idx;
ctx.image = module_alloc(image_size); header = bpf_jit_binary_alloc(image_size, &image_ptr,
if (unlikely(ctx.image == NULL)) sizeof(u32), jit_fill_hole);
if (header == NULL)
goto out; goto out;
/* 2. Now, the actual pass. */ /* 2. Now, the actual pass. */
ctx.image = (u32 *)image_ptr;
ctx.idx = 0; ctx.idx = 0;
build_prologue(&ctx); build_prologue(&ctx);
ctx.body_offset = ctx.idx; ctx.body_offset = ctx.idx;
if (build_body(&ctx)) { if (build_body(&ctx)) {
module_free(NULL, ctx.image); bpf_jit_binary_free(header);
goto out; goto out;
} }
...@@ -663,17 +719,25 @@ void bpf_int_jit_compile(struct bpf_prog *prog) ...@@ -663,17 +719,25 @@ void bpf_int_jit_compile(struct bpf_prog *prog)
bpf_jit_dump(prog->len, image_size, 2, ctx.image); bpf_jit_dump(prog->len, image_size, 2, ctx.image);
bpf_flush_icache(ctx.image, ctx.image + ctx.idx); bpf_flush_icache(ctx.image, ctx.image + ctx.idx);
prog->bpf_func = (void *)ctx.image;
prog->jited = 1;
set_memory_ro((unsigned long)header, header->pages);
prog->bpf_func = (void *)ctx.image;
prog->jited = true;
out: out:
kfree(ctx.offset); kfree(ctx.offset);
} }
void bpf_jit_free(struct bpf_prog *prog) void bpf_jit_free(struct bpf_prog *prog)
{ {
if (prog->jited) unsigned long addr = (unsigned long)prog->bpf_func & PAGE_MASK;
module_free(NULL, prog->bpf_func); struct bpf_binary_header *header = (void *)addr;
if (!prog->jited)
goto free_filter;
set_memory_rw(addr, header->pages);
bpf_jit_binary_free(header);
kfree(prog); free_filter:
bpf_prog_unlock_free(prog);
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment