Назад | Перейти на главную страницу

Системные вызовы в x86_64 linux по-прежнему генерируют прерывания?

В старых версиях архитектуры Linux системные вызовы всегда генерировали прерывание во время своего выполнения. Они будут выполняться путем установки номера системного вызова в% eax и параметров в% ebx,% ecx и т. Д. С последующим выдачей специального прерывания int 0x80. Таким образом, можно сказать, что системные вызовы являются частой причиной программных прерываний в системе.

Однако на современных архитектурах x86_64 есть специальная инструкция системного вызова "syscall", которая вообще обходит необходимость использования прерывания 0x80 и, следовательно, таблицы дескрипторов прерываний. Хотя я считаю, что предыдущий метод генерации прерывания для системного вызова по-прежнему поддерживается, инструкция системного вызова, похоже, является тем способом, которым это делается на практике.

Таким образом, мой вопрос: не правильно ли говорить, что системные вызовы генерируют прерывания? Может ли системный вызов по-прежнему увеличивать число, отображаемое, например, в столбце «прерывания» vmstat?

Да, современный код C для Linux x86_64 использует инструкцию syscall, см., Например, glibc sysdeps / unix / sysv / linux / x86_64 / syscall.S. Нет, это не означает, что прерывания системного вызова исчезнут из-за совместимости.

https://www.kernel.org/doc/Documentation/x86/entry_64.txt

В архитектуре x86 есть несколько различных способов перейти в код ядра. Большинство этих точек входа зарегистрированы в arch / x86 / kernel / traps.c и реализованы в arch / x86 / entry / entry_64.S для 64-битных, arch / x86 / entry / entry_32.S для 32-битных и, наконец, в arch /x86/entry/entry_64_compat.S, который реализует точки входа системных вызовов для 32-разрядной совместимости и, таким образом, предоставляет 32-разрядным процессам возможность выполнять системные вызовы при работе на 64-разрядных ядрах.

Назначения векторов IDT перечислены в arch / x86 / include / asm / irq_vectors.h.

Некоторые из этих записей:

  • system_call: инструкция системного вызова из 64-битного кода.

  • entry_INT80_compat: int 0x80 из 32-битного или 64-битного кода; совместим с системным вызовом в любом случае.

  • entry_INT80_compat, ia32_sysenter: syscall и sysenter из 32-битного кода

А для системных вызовов только для чтения (gettimeofday) существует vDSO, который вообще не входит в режим ядра.

Системные вызовы можно профилировать несколькими способами, например, ftrace или eBPF. Помимо устаревания в 64-битном режиме, прерывания возникают по причинам, отличным от системных вызовов.