Ссылка https://community.arm.com/developer/ip-products/processors/f/cortex-a-forum/6706/in-aarch32-state-what-is-the-mechanism-to-switch-to-aarch64-in-software, опубликованная в комментариях 0andriy ( разработчик ядра ), объясняет переключение между процессом пользовательского пространства AArch32 и AArch64 linux ядро Мартин Вайдман . Переключение режима 32-> 64 выполняется при исключениях; и переключение 64-> 32 выполняется при возврате исключения.
Если вы в данный момент запускаете одно из 32-битных приложений, и вы берете исключение (например, IRQ, SV C из системного вызова) , прервать ошибку страницы, ....) вы входите в 64-битную ОС. Итак, переход AArch32 -> AArch64. Когда ОС выполняет возврат исключения в приложение, это переход AArch64 -> AArch32. ... Любой тип исключения в состоянии AArch32 потенциально может привести к изменению состояния выполнения на AArch64. ... Для исключений возвращает обратное верно. Возврат исключительной ситуации в AArch64 может привести к изменению состояния выполнения на AArch32.
Как для исключений, так и для возвратов исключений, изменение состояния выполнения может произойти только в том случае, если есть также изменение в EL. Это исключение из EL0 в EL1 может привести к изменению состояния выполнения. Но исключение из EL1 в EL1 не может.
В потоке https://community.arm.com/developer/ip-products/processors/f/cortex-a-forum/6706/in-aarch32-state-what-is-the-mechanism-to-switch-to-aarch64-in-software есть еще несколько деталей. Или есть гораздо более простое объяснение в https://medium.com/@om.nara / aarch64-exception-levels-60d3a74280e6 в «Перемещение между AArch32 и AArch64»
При принятии исключения, если уровень Exception изменяется, состояние выполнения может: остаться неизменным, или измениться с AArch32 на AArch64.
при возврате из исключения, если уровень исключения изменится, состояние выполнения может: остаться неизменным, или изменить с AArch64 на AArch32.
То же в https://events.static.linuxfound.org/images/stories/pdf/lcna_co2012_marinas.pdf презентации (слайд 5) или в https://developer.arm.com/architectures/learn-the-architecture/exception-model/execution-and-security-states или в https://www.realworldtech.com/arm64/2/:
Модель исключений AArch64
Теперь по вашим вопросам:
как Linux обрабатывает переключатели AArch32 и AArch64?
Используя аппаратную возможность обработки исключений (и возврата) с переключателем EL0 / EL1 с различными значениями PSTATE.
Знает ли ядро, что запущенный процесс является 32-битным или 64-битным -bit?
Да, в ядре есть проверка 32-битных процессов («задач») на 64-битных ядрах (compys syscalls): arch / arm64 / kernel / syscall . c
static long do_ni_syscall(struct pt_regs *regs, int scno)
{
#ifdef CONFIG_COMPAT
long ret;
if (is_compat_task()) {
ret = compat_arm_syscall(regs, scno);
if (ret != -ENOSYS)
return ret;
}
#endif
return sys_ni_syscall();
}
Тест определен в include / asm / compat.h и arch / arm64 / include / asm / thread_info.h as
#define TIF_32BIT 22 /* 32bit process */
static inline int is_compat_task(void)
{
return test_thread_flag(TIF_32BIT);
}
TIF_32BIT устанавливается в fs / compat_binfmt_elf. c при 32-битной загрузке эльфа с несколькими макросами личности:
https://elixir.bootlin.com/linux/v4.19.107/source/arch/arm64/include/asm/elf.h#L208
/*
* Unlike the native SET_PERSONALITY macro, the compat version maintains
* READ_IMPLIES_EXEC across an execve() since this is the behaviour on
* arch/arm/.
*/
#define COMPAT_SET_PERSONALITY(ex) \
({ \
set_thread_flag(TIF_32BIT); \
})
https://elixir.bootlin.com/linux/v4.19.107/source/fs/compat_binfmt_elf.c#L104
#define SET_PERSONALITY COMPAT_SET_PERSONALITY
https://elixir.bootlin.com/linux/v4.19.107/source/fs/binfmt_elf.c#L690
#define SET_PERSONALITY2(ex, state) \
SET_PERSONALITY(ex)
static int load_elf_binary(struct linux_binprm *bprm)
SET_PERSONALITY2(loc->elf_ex, &arch_state);