Разница между Call Gate, Interrupt Gate, Trap Gate? - PullRequest
38 голосов
/ 06 августа 2010

Я изучаю защищенный режим Intel.Я обнаружил, что Call Gate, Interrupt Gate, Trap Gate почти одинаковы.На самом деле, кроме того, что Call Gate имеет поля для счетчика параметров, и что эти 3 шлюза имеют поля разных типов, они идентичны во всех других полях.

Что касается их функций, то все они используются для передачи кодауправление в некоторой процедуре в некотором сегменте кода.

Мне интересно, так как все эти 3 шлюза содержат информацию, необходимую для вызова через границы привилегий.Зачем нам их 3 вида?Разве 1 ​​не достаточно хорош?

Спасибо за ваше время и ответ.

Обновление 1

Смежный вопрос: Когда использовать Interrupt Gate или Trap Gate?

Обновление 2

Сегодня я пришел с такой мыслью:

Различное назначение, разные логические элементы и различные детали поведения процессора.Например, обработка флага IF.

Ответы [ 3 ]

59 голосов
/ 06 августа 2010

Гейт (вызов, прерывание, задача или ловушка) используется для передачи управления выполнением по сегментам. Проверка уровня привилегий выполняется по-разному в зависимости от типа получателя и используемой инструкции.

Шлюз вызова использует инструкции CALL и JMP. Ворота вызова передают управление из кода с более низкими привилегиями в код с более высокими привилегиями. Шлюз DPL используется для определения того, какие уровни привилегий имеют доступ к шлюзу. Ворота вызовов (или, возможно, были), вероятно, постепенно отменяются в пользу механизма SYSENTER / SYSEXIT, который работает быстрее.

Ворота задач используются для поддержки аппаратной многозадачности. Аппаратное переключение задач может происходить добровольно (CALL / JMP для дескриптора шлюза задач) или через прерывание или IRET, когда установлен флаг NT. Это работает так же, как с прерываниями или ловушками. Насколько мне известно, ворота задач не используются, поскольку ядрам обычно требуется дополнительная работа при переключении задач.

Ворота прерываний и ловушек вместе с воротами задач называются таблицей дескрипторов прерываний. Они работают так же, как шлюзы вызовов, за исключением передачи параметров из одного стека привилегий в другой. Единственное отличие состоит в том, что шлюзы прерываний очищают бит IF в EFLAGS, а шлюзы-ловушки - нет. Это делает их идеальными для обслуживания аппаратных прерываний. Ловушки широко используются в аппаратной виртуализации.

Для получения дополнительной информации см. Руководства по архитектуре Intel по интересующим вас процессорам.

Обновление

Чтобы ответить на комментарий:

Есть много причин отличать прерывания от ловушек. Одним из них является различие в объеме: шлюзы прерываний указывают на пространство ядра (в конце концов, именно ядро ​​управляет оборудованием), а ловушки вызываются в пространстве пользователя. Обработчики прерываний вызываются в ответ на аппаратные события, а прерывания выполняются в ответ на инструкцию CPU.

Для простого (но непрактичного) примера, чтобы лучше понять, почему шлюзы прерываний и ловушек по-разному относятся к EFLAGS, рассмотрим, что произойдет, если бы мы писали обработчик прерываний для аппаратных событий в однопроцессорной системе и не могли очистить IF немного, пока мы служили одному. Было бы возможно прибыть второе прерывание, пока мы были заняты обслуживанием первого. Тогда наш обработчик прерываний будет вызываться процессором в некоторой случайной точке во время нашего выполнения IH. Это может привести к повреждению данных, блокировке или другим опасным явлениям. На практике отключение прерываний является одним из механизмов, обеспечивающих обработку ряда операторов ядра как критического раздела.

Приведенный выше пример предполагает маскируемое прерывание. В любом случае, вы не захотите игнорировать НМИ.

Сегодня это тоже в значительной степени неактуально. Сегодня практически нет различий между быстрыми и медленными обработчиками прерываний (поиск "быстрых и медленных обработчиков"), обработчики прерываний могут выполняться вложенным способом, процессоры SMP делают обязательным объединение локальных отключений прерываний с помощью спин-блокировок и пр.

Теперь шлюзы действительно используются для обслуживания программных прерываний, исключений и т. Д. Сбой страницы или исключение деления на ноль в вашем процессоре, вероятно, обрабатывается через шлюзы. Простейшим примером использования шлюзов для управления выполнением программы является инструкция INT 3, которая используется для реализации точек останова в отладчиках. При выполнении виртуализации происходит то, что гипервизор работает в кольце 0, а гостевое ядро ​​обычно в кольце 1 - где привилегированный код завершится с ошибкой общего исключения. Витчел и Розенблюм разработали двоичный перевод , который в основном переписывает инструкции для имитации их эффектов. Критические инструкции обнаружены и заменены ловушками. Затем, когда выполняется ловушка, управление передается VMM / гипервизору, который отвечает за эмуляцию критических инструкций в кольце 0.

При аппаратной виртуализации технология ловушки и эмуляции была несколько ограничена в использовании (поскольку она довольно дорогая, особенно когда она динамическая), но практика бинарного перевода все еще широко используется .

Для получения дополнительной информации, я бы посоветовал вам проверить:

  • Драйверы для устройств Linux, третье издание (доступно онлайн )
  • Для двоичного перевода QEMU - отличное начало.
  • Относительно ловушки и эмуляции, посмотрите сравнение между программными / аппаратными методами.

Надеюсь, это поможет!

19 голосов
/ 23 декабря 2012

Архитектура и дизайн

С точки зрения защиты архитектура x86 основана на иерархических кольцах, согласно которым все пространство выполнения, предоставляемое процессором, делится на четыре иерархических домена защиты каждому из которых назначен собственный уровень привилегий.Этот дизайн предполагает, что большая часть временного кода будет выполняться в домене с наименьшими привилегиями, и иногда будут запрашиваться службы из более привилегированного домена безопасности, и эти службы будут выгружать менее стековые действия в стек, а затем восстанавливать его таким образом, чтобыполное вытеснение будет невидимым для менее привилегированного кода.

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

Шлюз является функциейАрхитектура x86 для передачи управления из менее привилегированных сегментов кода в более привилегированные, но не наоборот.Кроме того, точка в менее привилегированном сегменте, откуда будет передаваться управление, может быть произвольной, но строго указывается в более привилегированном сегменте, куда будет передаваться управление.Передача управления назад в менее привилегированный сегмент разрешается только с помощью инструкции IRET.В этом отношении в заявлении руководства разработчика программного обеспечения Intel:

Модули кода в сегментах с более низкими привилегиями могут получать доступ только к модулям, работающим с сегментами с более высокими привилегиями, с помощью строго контролируемого и защищенного интерфейса, называемого шлюзом.Попытки получить доступ к сегментам с более высокими привилегиями без прохождения через защитный шлюз и без достаточных прав доступа приводят к генерации исключения общей защиты (#GP).

Другими словами, шлюз являетсяточка входа в привилегированный домен с необходимыми правами доступа и целевым адресом.Таким образом, все шлюзы схожи и используются практически для одних и тех же целей, и все дескрипторы шлюза содержат поле DPL, которое используется процессором для управления правами доступа.Но обратите внимание, процессор проверяет DPL шлюза только в том случае, если источником вызова была программная инструкция CALL, JMP или INT, и обходит эту проверку, если источником вызова является аппаратное обеспечение.

Типы ворот

Несмотря на то, что все ворота похожи, они имеют некоторые различия, потому что изначально инженеры Intel думали, что разные ворота будут использоваться для разных целей.

ЗадачаGate

Gate Gate может храниться только в IDT и GDT и вызываться командой INT.Это очень особый тип шлюза, который значительно отличается от других.

Изначально инженеры Intel думали, что они революционизируют многозадачность, предоставляя функции на основе ЦП для переключения задач.Они представили TSS (сегмент состояния задачи), который хранит состояние регистров задачи и может использоваться для переключения аппаратных задач.Существует два способа запуска аппаратного переключения задач: с помощью самого TSS и с помощью Task Gate.Для переключения аппаратных задач вы можете использовать инструкции CALL или JMP.Если я правильно понимаю, главная причина введения шлюза задач состояла в том, чтобы иметь возможность запускать переключатели аппаратных задач в ответ на поступление прерывания, потому что переключение аппаратной задачи не может быть вызвано с помощью JMP для селектора TSS.

На самом деле, никто не использует это, ни аппаратное переключение контекста.На практике эта функция не оптимальна с точки зрения производительности и не удобна в использовании.Например, принимая во внимание, что TSS может храниться только в GDT, а длина GDT не может превышать 8192, мы не можем иметь более 8 000 задач с аппаратной точки зрения.

Trap Gate

Trap Gate может храниться только в IDT и вызываться командой INT.Это можно рассматривать как основной тип ворот.Он просто передает управление конкретному адресу, указанному в дескрипторе шлюза, в более привилегированном сегменте и ничего более.Ловушки активно используются для различных целей, которые могут включать в себя:

  • реализация системного вызова (например, Linux использует INT 0x80 и Windows использует INT 0x2E для этих целей)
  • Реализация обработки исключений (у нас нет никаких причин отключать прерывания в случае исключения).
  • Реализация обработки прерываний на машинах с APIC (мы можем лучше контролировать стек ядра).

Ворота прерывания

Шлюз прерывания может храниться только в IDT и вызываться командой INT. Это то же самое, что и у шлюза-ловушки, но, кроме того, вызов шлюза прерывания дополнительно запрещает дальнейшее принятие прерывания путем автоматической очистки флага IF в регистре EFLAGS.

Ворота прерываний активно используются для реализации обработки прерываний, особенно на машинах на основе PIC. Причиной является требование контролировать глубину стека. PIC не имеет функции приоритетов источников прерываний. Благодаря этому по умолчанию PIC отключает только те прерывания, которые уже есть при обработке в процессоре. Но другие прерывания все еще могут прибыть в середину и опередить обработку прерываний. Таким образом, в стеке ядра может одновременно находиться 15 обработчиков прерываний. В результате разработчики ядра вынуждены либо значительно увеличить размер стека ядра, что приводит к потере памяти, либо быть готовыми к случайным переполнениям стека ядра. Interrupt Gate может гарантировать, что в стеке ядра одновременно может находиться только один обработчик.

Call Gate

Шлюз вызовов может храниться в GDL и LDT и вызываться с помощью инструкций CALL и JMP. Похож на trap gate, но в дополнение может передавать количество параметров из стека задач режима пользователя в стек задач режима ядра. Количество передаваемых параметров указывается в дескрипторе шлюза вызова.

Ворота звонков никогда не были популярны. Для этого есть несколько причин:

  • Их можно заменить на ворота-ловушки (бритва Оккама).
  • Они не переносимы много. Другие процессоры не имеют таких функций, что означает, что поддержка шлюзов вызовов для системных вызовов является бременем при переносе операционной системы, поскольку эти вызовы должны быть переписаны.
  • Они не слишком гибкие из-за того, что количество параметров, которые можно передавать между стеками, ограничено.
  • Они не оптимальны с точки зрения производительности.

В конце 1990-х годов Intel и AMD представили дополнительные инструкции для системных вызовов: SYSENTER / SYSEXIT (Intel) и SYSCALL / SYSRET (AMD). В отличие от шлюзов, новые инструкции обеспечивают повышение производительности и нашли применение.

Резюме

Я не согласен с Майклом Фукаракисом. Извините, но между прерываниями и прерываниями нет никаких отличий, кроме влияющих на флаг IF.

  • Теоретически каждый тип шлюза может служить интерфейсом, указывающим на сегмент с любым уровнем привилегий. На практике в современной операционной системе используются только прерывания и прерывания, которые используются в IDT для системных вызовов, прерываний и обработки исключений, и благодаря этому все они служат точкой входа в ядро.

  • Любой тип шлюза (включая прерывание, ловушку и задачу) может быть вызван программно с помощью инструкции INT. Единственная функция, которая может запретить доступ кода режима пользователя к конкретному шлюзу, - это DPL. Например, когда операционная система собирает IDT, независимо от типов конкретных шлюзов, ядро ​​устанавливает DPL шлюзов, которые будут использоваться для обработки аппаратных событий, до 0 и в соответствии с этим доступ к этим вентилям будет разрешен только из пространства ядра. (это работает в наиболее привилегированном домене), но когда он устанавливает шлюз для системного вызова, он устанавливает DPL равным 3, чтобы разрешить доступ к этому шлюзу из любого кода. В результате задача пользовательского режима может выполнять системный вызов с использованием шлюза с DPL = 3, но при попытке вызвать обработчик прерывания клавиатуры, например, будет обнаружена ошибка общей защиты.

  • Аппаратно может вызывать любой тип шлюза в IDT.Люди используют шлюзы прерываний для этой аппаратной обработки событий только в тех случаях, когда они хотят добиться некоторой синхронизации.Например, быть уверенным, что переполнение стека ядра невозможно.Например, у меня есть успешный опыт использования шлюзов для обработки аппаратных прерываний в системе на основе APIC.

  • Аналогичным образом, в программном обеспечении могут вызываться шлюзы любого типа в IDT.Причина использования шлюзов для системных вызовов и исключений проста.Нет причин отключать прерывания.Отключение прерываний - плохая вещь, потому что это увеличивает задержки обработки прерываний и увеличивает вероятность потери прерываний.Из-за этого никто не сможет отключить их без каких-либо серьезных оснований.

  • Обработчик прерываний, как правило, написан в строгом реентерабельном стиле.Таким образом, обработчики прерываний обычно не разделяют данные и могут прозрачно вытеснять друг друга.Даже когда нам необходимо взаимно исключить одновременный доступ к данным в обработчике прерываний, мы можем защитить только доступ к совместно используемым данным, используя инструкции cli и sti.Нет никаких причин рассматривать весь обработчик прерываний как критическую секцию.Нет никаких причин использовать шлюзы прерываний, кроме желания предотвратить возможное переполнение стека ядра в системах на основе PIC.

Ворота-ловушки - это стандартное решение для взаимодействия с ядром.Ворота прерывания можно использовать вместо шлюза-ловушки, если для этого есть серьезная причина.

8 голосов
/ 06 августа 2010

Шлюз прерывания является особенным, потому что флаг IF автоматически очищается. Вызов Call является особенным, потому что он не активируется через вектор прерывания. Шлюз задач является особенным, поскольку он автоматически сохраняет состояние процессора. Четыре различных поведения, для которых удобно иметь четыре имени.

...