В чем разница между Call Gate, Interrupt Gate, Trap Gate?

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

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

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

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

Обновление 1

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

Обновление 2

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

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


person smwikipedia    schedule 06.08.2010    source источник
comment
После того, как я проверил другие архитектуры, такие как ARM, у меня появилось ощущение, что x86 облажался своей сложностью ...   -  person smwikipedia    schedule 28.09.2020


Ответы (3)


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

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

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

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

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

Обновлять

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

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

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

Однако в приведенном выше примере предполагаются маскируемые прерывания. В любом случае вы не захотите игнорировать NMI.

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

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

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

Для получения дополнительной информации я предлагаю вам проверить:

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

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

person Michael Foukarakis    schedule 06.08.2010
comment
Спасибо за подробный ответ. Не могли бы вы подробнее рассказать о воротах для прерывания и ловушки? Например, почему шлюзы прерывания и ловушки по-разному обрабатывают EFLAGS [IF]? Почему это делает их идеальными для обслуживания аппаратных прерываний? Насколько я понимаю, шлюзы прерываний предназначены для маскируемых аппаратных прерываний, а шлюзы-ловушки предназначены для программных прерываний (вызванных исключением выполнения кода или инструкцией INT X). И, кроме того, не могли бы вы дать мне еще несколько ссылок о том, как ловушки используются в аппаратной виртуализации? Извините за столько вопросов ... - person smwikipedia; 07.08.2010
comment
Спасибо за Ваш ответ. У меня есть несколько новых вопросов: stackoverflow.com/questions/3442193/ Не могли бы вы мне помочь? Спасибо, что уделили мне столько времени ... - person smwikipedia; 09.08.2010
comment
Люблю твой ответ! и книга о драйверах устройств linux действительно хороша - person Timothy Leung; 25.01.2014

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

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

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

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

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

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

Типы ворот

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

Ворота задач

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

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

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

Ворота-ловушки

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. Подобно шлюзу-ловушке, но дополнительно может передавать ряд параметров из стека задач пользовательского режима в стек задач режима ядра. Количество переданных параметров указывается в дескрипторе шлюза вызова.

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

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

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

Резюме

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

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

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

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

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

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

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

person ZarathustrA    schedule 23.12.2012
comment
Я изо всех сил стараюсь прояснить этот вопрос, потому что здесь есть настоящее золото, которым, боюсь, пренебрегли из-за грамматики и опечаток. Пожалуйста, оставайся. Этот ответ на высшем уровне. - person Evan Carroll; 23.03.2018

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

person Hans Passant    schedule 06.08.2010
comment
Спасибо за ответ. Как насчет Врат Ловушки? - person smwikipedia; 07.08.2010
comment
Ну, он использует вектор, не сбрасывает IF, не сохраняет состояние процессора. Отличается от остальных 3. - person Hans Passant; 07.08.2010
comment
Проверяет ли ЦП поля TYPE шлюзов прерывания / прерывания, чтобы решить, сбрасывать ли бит IF? Потому что Типовые поля - единственное различие между этими двумя воротами. - person smwikipedia; 07.08.2010
comment
Да, поле типа определяет поведение. - person Hans Passant; 07.08.2010
comment
Спасибо, Ганс. Как мы узнаем, какой номер вектора присваивать воротам прерывания или воротам-ловушкам? Какие критерии? - person smwikipedia; 10.08.2010
comment
Я видел, как вы задали еще один вопрос по этой теме. Мне кажется совершенно неуместным отвечать на него здесь. - person Hans Passant; 10.08.2010