blob: 022ffe2ca2e9b3eea0ec766982a40db367b446a1 [file] [log] [blame]
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Qais Yousef <qais.yousef@arm.com>
Date: Tue, 15 Sep 2020 11:42:28 +0100
Subject: ANDROID: arm64: Handle AArch32 tasks running on non AArch32 cpu
On Asym AArch32 system, if a tasks tries to run on unsupported CPU, we
fix up the cpumask silently to make sure tasks aren't killed if placed
on a CPU without AArch32 support
This patch can be omitted if user-space can guarantee the cpumask of
all AArch32 apps only contains AArch32 capable CPUs.
The biggest danger is in apps who try to modify their own cpu affinity
via sched_setaffinity(). Without this change they could trigger
a SIGKILL if they unknowingly affine to the wrong CPU.
Without this patch user-space must ensure that any 32bit app is cloned
into a cpuset cgroup that will restrict it to aarch32 capable cpus.
clone3 syscall allows specifying the cgroup on fork.
Split from Catalin's original patch to support Asym AArch32 systems.
Only modified cpumask_t to become cpumask_var_t in
set_32bit_cpus_allowed().
Bug: 168847043
Reason: Needed for bringup. Revert when upstream patch is available
Signed-off-by: Qais Yousef <qais.yousef@arm.com>
Change-Id: If520cbf5cd705fb0e0399f36b81d4a68e90beb3a
---
arch/arm64/Kconfig | 7 +++----
arch/arm64/kernel/signal.c | 32 ++++++++++++++++++++++++++------
2 files changed, 29 insertions(+), 10 deletions(-)
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -1906,10 +1906,9 @@ config ASYMMETRIC_AARCH32
Enable this option to allow support for asymmetric AArch32 EL0
CPU configurations. Once the AArch32 EL0 support is detected
on a CPU, the feature is made available to user space to allow
- the execution of 32-bit (compat) applications. If the affinity
- of the 32-bit application contains a non-AArch32 capable CPU
- or the last AArch32 capable CPU is offlined, the application
- will be killed.
+ the execution of 32-bit (compat) applications by migrating
+ them to the capable CPUs. Offlining such CPUs leads to 32-bit
+ applications being killed.
If unsure say N.
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -912,14 +912,34 @@ static void do_signal(struct pt_regs *regs)
restore_saved_sigmask();
}
-static void check_aarch32_cpumask(void)
+static void set_32bit_cpus_allowed(void)
{
+ int ret;
+
/*
- * The task must be a subset of aarch32_el0_mask or it could end up
- * migrating and running on the wrong CPU.
+ * Try to honour as best as possible whatever affinity request this
+ * task has. If it spans no compatible CPU, disregard it entirely.
*/
- if (!cpumask_subset(current->cpus_ptr, &aarch32_el0_mask)) {
- pr_warn_once("CPU affinity contains CPUs that are not capable of running 32-bit tasks\n");
+ if (cpumask_intersects(current->cpus_ptr, &aarch32_el0_mask)) {
+ cpumask_var_t cpus_allowed;
+
+ if (!alloc_cpumask_var(&cpus_allowed, GFP_ATOMIC)) {
+
+ ret = set_cpus_allowed_ptr(current, &aarch32_el0_mask);
+
+ } else {
+
+ cpumask_and(cpus_allowed, current->cpus_ptr, &aarch32_el0_mask);
+ ret = set_cpus_allowed_ptr(current, cpus_allowed);
+ free_cpumask_var(cpus_allowed);
+
+ }
+ } else {
+ ret = set_cpus_allowed_ptr(current, &aarch32_el0_mask);
+ }
+
+ if (ret) {
+ pr_warn_once("No CPUs capable of running 32-bit tasks\n");
force_sig(SIGKILL);
}
}
@@ -946,7 +966,7 @@ asmlinkage void do_notify_resume(struct pt_regs *regs,
if (IS_ENABLED(CONFIG_ASYMMETRIC_AARCH32) &&
thread_flags & _TIF_CHECK_32BIT_AFFINITY) {
clear_thread_flag(TIF_CHECK_32BIT_AFFINITY);
- check_aarch32_cpumask();
+ set_32bit_cpus_allowed();
}
if (thread_flags & _TIF_UPROBE)