Почему порт arm ядра Linux не сделал резервную копию регистра "cpsr" во время переключения контекста? - PullRequest
0 голосов
/ 20 февраля 2020

Переключение на сборку arm32 в linux выглядит следующим образом: вы можете видеть, что нет резервной копии cigr reigister, сравните ее с другими архивами, такими как mips или riscv, для которых все соответствующие mstatus и регистр состояния выполняют резервное копирование и восстановление. во время _switch_to, так, почему есть различия?

  12948 8010d328 <__switch_to>:
  12949 8010d328:       e281c018        add     ip, r1, #24
  12950 8010d32c:       e8ac6ff0        stmia   ip!, {r4, r5, r6, r7, r8, r9, sl, fp, sp, lr}
  12951 8010d330:       e592405c        ldr     r4, [r2, #92]   ; 0x5c
  12952 8010d334:       e5925060        ldr     r5, [r2, #96]   ; 0x60
  12953 8010d338:       ee1d7f50        mrc     15, 0, r7, cr13, cr0, {2}
  12954 8010d33c:       ee0d4f70        mcr     15, 0, r4, cr13, cr0, {3}
  12955 8010d340:       ee0d5f50        mcr     15, 0, r5, cr13, cr0, {2}
  12956 8010d344:       e5817060        str     r7, [r1, #96]   ; 0x60
  12957 8010d348:       e1a05000        mov     r5, r0
  12958 8010d34c:       e2824018        add     r4, r2, #24
  12959 8010d350:       e59f000c        ldr     r0, [pc, #12]   ; 8010d364 <__switch_to+0x3c>
  12960 8010d354:       e3a01002        mov     r1, #2
  12961 8010d358:       eb00c813        bl      8013f3ac <atomic_notifier_call_chain>
  12962 8010d35c:       e1a00005        mov     r0, r5
  12963 8010d360:       e894aff0        ldm     r4, {r4, r5, r6, r7, r8, r9, sl, fp, sp, pc}
  12964 8010d364:       80b61200        .word   0x80b61200
  12965 8010d368:       e58d403c        str     r4, [sp, #60]   ; 0x3c
  12966 8010d36c:       e1a0f009        mov     pc, r9

1 Ответ

3 голосов
/ 20 февраля 2020

Существует несколько различных вариантов использования cpsr, и неясно, к какому из них вы обращаетесь.

  1. Режим супервизора cpsr.
  2. Режим пользователя cpsr.
  3. Некоторое исключение cpsr.

Эти значения сохраняются во время исключения на процессоре ARM.

См .: Linux стек исключений ARM ядра

Это делает все 'spsr', кроме sv c и пользовательского режима бессмысленными.

Примечание: ARM имеет банки SP, cpsr и lr. Другие упоминаемые архитектуры могут иметь или не иметь банковские регистры. Наверняка всем нужно восстановить регистр состояния пользовательского режима или пользовательский CPSR на ARM.

Ассемблер switch_to используется для переключения состояния ядра для процесса. sp, который восстанавливается, представляет собой страницу размером 8 КБ, где нижняя часть представляет собой thread_info, содержащую копию пользовательских регистров. Функция switch_to() принимает от и до thread_info, хранящихся в R1 и R2.

Код

  add     r4, r2, #24
  ldm     r4, {r4, r5, r6, r7, r8, r9, sl, fp, sp, pc}

больше похож на longjmp() на предыдущий вызов switch_to(); код не направляется в то же место, откуда он был вызван. SPSR, который является возвращением в режим пользователя CPSR (и lr). Они сохраняются в r1, r2 векторными заглушками. Они восстанавливаются макросом restore_user_regs . Инструкция movs pc, lr восстановит пользовательский CPSR и вернется из исключения / syscall.

Активный с кодом ядра cpsr (SV C) защищен ABI-интерфейсом C, который сообщает состояние биты не действительны после вызова функции. Также предполагается, что код any sv c использует один и тот же бит T (весь код ядра - только Thumb или ARM), и функцию необходимо вызывать с битами F и I в известном состоянии. switch_to вызывающим абонентам следует использовать функции маски стека ИЛИ никогда не иметь маскируемых прерываний. Я думаю, что это, вероятно, последний. Если вы попытаетесь смешать код Thumb / ARM или использовать / изменить маскировку прерываний с вызовами на switch_to, это будет проблемой; в противном случае нет необходимости сохранять / восстанавливать это значение.

...