lkml.org 
[lkml]   [2021]   [Jul]   [30]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v11 11/16] arm64: exec: Adjust affinity for compat tasks with mismatched 32-bit EL0
    Date
    When exec'ing a 32-bit task on a system with mismatched support for
    32-bit EL0, try to ensure that it starts life on a CPU that can actually
    run it.

    Similarly, when exec'ing a 64-bit task on such a system, try to restore
    the old affinity mask if it was previously restricted.

    Reviewed-by: Daniel Bristot de Oliveira <bristot@redhat.com>
    Reviewed-by: Quentin Perret <qperret@google.com>
    Signed-off-by: Will Deacon <will@kernel.org>
    ---
    arch/arm64/include/asm/elf.h | 6 ++----
    arch/arm64/kernel/process.c | 39 +++++++++++++++++++++++++++++++++++-
    2 files changed, 40 insertions(+), 5 deletions(-)

    diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
    index 8d1c8dcb87fd..97932fbf973d 100644
    --- a/arch/arm64/include/asm/elf.h
    +++ b/arch/arm64/include/asm/elf.h
    @@ -213,10 +213,8 @@ typedef compat_elf_greg_t compat_elf_gregset_t[COMPAT_ELF_NGREG];

    /* AArch32 EABI. */
    #define EF_ARM_EABI_MASK 0xff000000
    -#define compat_elf_check_arch(x) (system_supports_32bit_el0() && \
    - ((x)->e_machine == EM_ARM) && \
    - ((x)->e_flags & EF_ARM_EABI_MASK))
    -
    +int compat_elf_check_arch(const struct elf32_hdr *);
    +#define compat_elf_check_arch compat_elf_check_arch
    #define compat_start_thread compat_start_thread
    /*
    * Unlike the native SET_PERSONALITY macro, the compat version maintains
    diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
    index c8989b999250..583ee58f8c9c 100644
    --- a/arch/arm64/kernel/process.c
    +++ b/arch/arm64/kernel/process.c
    @@ -21,6 +21,7 @@
    #include <linux/mman.h>
    #include <linux/mm.h>
    #include <linux/nospec.h>
    +#include <linux/sched.h>
    #include <linux/stddef.h>
    #include <linux/sysctl.h>
    #include <linux/unistd.h>
    @@ -579,6 +580,28 @@ unsigned long arch_align_stack(unsigned long sp)
    return sp & ~0xf;
    }

    +#ifdef CONFIG_COMPAT
    +int compat_elf_check_arch(const struct elf32_hdr *hdr)
    +{
    + if (!system_supports_32bit_el0())
    + return false;
    +
    + if ((hdr)->e_machine != EM_ARM)
    + return false;
    +
    + if (!((hdr)->e_flags & EF_ARM_EABI_MASK))
    + return false;
    +
    + /*
    + * Prevent execve() of a 32-bit program from a deadline task
    + * if the restricted affinity mask would be inadmissible on an
    + * asymmetric system.
    + */
    + return !static_branch_unlikely(&arm64_mismatched_32bit_el0) ||
    + !dl_task_check_affinity(current, system_32bit_el0_cpumask());
    +}
    +#endif
    +
    /*
    * Called from setup_new_exec() after (COMPAT_)SET_PERSONALITY.
    */
    @@ -588,8 +611,22 @@ void arch_setup_new_exec(void)

    if (is_compat_task()) {
    mmflags = MMCF_AARCH32;
    - if (static_branch_unlikely(&arm64_mismatched_32bit_el0))
    +
    + /*
    + * Restrict the CPU affinity mask for a 32-bit task so that
    + * it contains only 32-bit-capable CPUs.
    + *
    + * From the perspective of the task, this looks similar to
    + * what would happen if the 64-bit-only CPUs were hot-unplugged
    + * at the point of execve(), although we try a bit harder to
    + * honour the cpuset hierarchy.
    + */
    + if (static_branch_unlikely(&arm64_mismatched_32bit_el0)) {
    + force_compatible_cpus_allowed_ptr(current);
    set_tsk_thread_flag(current, TIF_NOTIFY_RESUME);
    + }
    + } else if (static_branch_unlikely(&arm64_mismatched_32bit_el0)) {
    + relax_compatible_cpus_allowed_ptr(current);
    }

    current->mm->context.flags = mmflags;
    --
    2.32.0.402.g57bb445576-goog
    \
     
     \ /
      Last update: 2021-07-30 13:26    [W:4.287 / U:0.076 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site