Intel и AMD планируют различные замены для обработки прерываний x86

intelиamdпланируютразличныезаменыдляобработкипрерыванийx86

В какой-то момент карточный домик начинает опрокидываться. Ни для кого не секрет, что архитектура процессора x 86 практически устарела, чтобы собирать пенсию. Это, если не сказать особо, старая скрипящая металлическая фурнитура, которая, будь боги микропроцессорной архитектуры более щедрыми, была бы давно предана забвению.

Intel и AMD проделали потрясающую работу, удерживая старую девочку все эти десятилетия, но напряжение начинает сказываться. Программирование x 86 чипов сложно и неприятно, потому что новые функции продолжают накапливаться, а старые никогда не исчезают. Это похоже на управление ракетным кораблем с использованием румпеля, парусов и троса. Это вообще чудо работает.

Итак, неудивительно, что Intel и AMD – не говоря уже о тысячах x 86 программисты по всему миру – возможно, захотят выбросить часть этого решетчатого механизма и заменить его чем-то менее… причудливым.

Показательный пример: обработка прерываний. Еще со времен ‘286 (около MCMLXXXII) мир x 86 все процессоры использовали византийскую систему для управления прерываниями, сбоями и исключениями, которые объединяли таблицы поиска, проверки привилегий, манипулирование границами, сохранение контекста и управление памятью, что сбивало с толку многих программистов – и все же каким-то образом работало. Большую часть времени.

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

Время перезагрузки? Может быть. Intel и AMD независимо друг от друга разработали схемы для упрощения обработки ошибок, ловушек и прерываний процессорами x 86. Естественно, эти два подхода различны и несовместимы друг с другом. Intel более амбициозна, но она также требует больше работы для программистов, надеющихся воспользоваться преимуществами нового механизма. Подход AMD проще; это скорее заплатка, чем капитальный ремонт.

Впервые за долгое время Intel действительно хочет отказаться, а не просто настроить одну из своих основных функций. предложенная система FRED (гибкий возврат и доставка событий) полностью заменит IDT вместе с дескрипторами прерываний. Это также эффективно снижает количество уровней привилегий с четырех до двух. Наконец, ворота вызова ушли в прошлое. В свою очередь (так сказать) обработка прерываний будет быстрее, проще, полнее и менее подвержена серьезным ошибкам. Для многих из нас это будет первая переработка обработки прерываний x 86 в нашей жизни.

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

Прерывания, ловушки и исключения все вместе называются «событиями», и маршрутизация этих событий их соответствующему обработчику становится «доставкой событий». Все обработчики событий (то есть обработчики прерываний, обработчики ошибок, обработчики исключений и т. Д.) Работают на уровне привилегий 0, самом привилегированном и самом внутреннем из четырех привилегированных «колец». Вместо того, чтобы использовать IDT для определения точки входа каждого обработчика, аппаратное обеспечение процессора просто вычислит смещение от фиксированного базового адреса. Она менее гибкая, чем система IDT, но ее проще настроить и быстрее реализовать на оборудовании.

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

Почему только два уровня привилегий? FRED сворачивает четыре кольца привилегий семейства x 286 в два: пользователя и супервизора. Это большой шаг назад по сравнению с тем, когда четырехуровневая схема была представлена ​​в 1980, но прошедшие десятилетия показали, что немногие программисты когда-либо использовали все четыре уровня. уровни. Большинство просто отделили привилегированных от непривилегированных, поэтому Intel воспользовалась возможностью с FRED, чтобы освятить то, что все в любом случае делали.

Различие между пользователем и супервизором важно, потому что оно определяет, будете ли вы менять стеки или нет. Это всегда было слабым местом обработки прерываний x 286, и это стало еще более странным с 64 – битовые расширения и операционные системы. Процессор номинально поддерживает четыре отдельных стека (по одному для каждого уровня привилегий) плюс возможный «теневой стек» для операционной системы или гипервизора. Стало сложно понять, какой стек использовать, какой сохранить, а какой никогда не трогать.

По соглашению, 64 – битовый рабочий системы также использовали регистр сегмента GS для поддержания целостности потока, но это не управлялось аппаратным обеспечением. Обработчикам прерываний приходилось манипулировать селекторами GS и сегментами памяти, надеясь сохранить входящий контекст, а для этого нет атомарных операций.

FRED сделает все это автоматически. Он помещает 64 байтов в привилегированный стек обработчика событий вместе с другим 64 байтов информации о событии (по сути, дамп мини-ядра) в другом месте. К моменту вызова обработчик событий должен иметь весь контекст, необходимый для непосредственной работы.

В документации Intel говорится: «Основная функция доставки событий FRED – установить новый контекст, контекст обработчика событий в кольце 0, при сохранении старого контекста для последующего возврата. Некоторые части нового контекста имеют фиксированные значения, в то время как другие зависят от старого контекста, характера доставляемого события и конфигурации программного обеспечения ».

При возврате из обработчика событий будут использоваться две новые инструкции: ERETU и ERETS (возврат события пользователю / супервизору). Версия для пользовательского режима восстанавливает весь непривилегированный контекст, включая стек, указатель инструкций, регистры и так далее. Версия супервизора проще и, следовательно, быстрее, потому что она не пересекает границы уровней привилегий.

Точно так же инструкции SYSCALL и SYSENTER изменяют поведение. Они по-прежнему разрешают вызовы функций системного уровня, но больше не могут передавать данные через (несуществующую) IDT.

Еще одно большое изменение – вызов ворот. Забудь о них. IDT может быть заполнена воротами вызова, которые определяют как точку входа обработчика прерывания, так и его уровень привилегий. Теперь у всех обработчиков событий есть предопределенные точки входа, и все они работают с наивысшим уровнем привилегий. Следовательно, нет необходимости в шлюзах вызова в IDT.

А как насчет шлюзов вызова где-нибудь еще, например, в GDT или LDT? Все еще нет. Intel утверждает: «Когда переходы FRED разрешены, любое выполнение удаленного вызова или удаленного JMP, которое ссылается на шлюз вызова, вызывает исключение общей защиты (#GP)». Другими словами, вы все еще можете вызывать / переходить к коду в других сегментах, но он должен быть на том же уровне привилегий.

Ворота вызова были обычным – и официально признанным – способом повышения привилегий, но не более того. FRED не допускает изменения привилегий («пересечения кольца»), кроме как через свой собственный механизм, что означает преднамеренное прерывание или исключение.

Это вызывает интересный побочный эффект, который, я уверен, был преднамеренным. Если все изменения привилегий должны происходить через события FRED, и если FRED распознает только два уровня привилегий, больше нет никакого способа получить доступ к коду на уровнях привилегий 1 или 2. Эти два промежуточных уровня привилегий были фактически изгнаны и стали непригодными для использования. Даже если вам каким-то образом удастся начать работу с CPL1 или CPL2, самое первое прерывание или исключение приведет вас к обработчику события CPL0, который затем вернет вас к CPL3, когда он завершится. Ага, я бы сказал, что эти два дополнительных уровня привилегий processora non grata .

В отличие от капитального ремонта прерываний Intel, подход AMD – это всего лишь легкая полировка. Предлагаемые компанией Расширения для доступа супервизора (SEE) сохраняют знакомую IDT, шлюзы вызова и четыре кольца привилегий. Он изменяет существующую инструкцию SYSCALL, добавляет бит состояния, чтобы пометить обработчики прерываний как повторно входимые, и делает немаскируемые прерывания маскируемыми (!).

SEE стремится просто залатать некоторые лазейки, обнаруженные годами разработки программного обеспечения, «чтобы должным образом справиться с обстоятельствами, которые на практике редки, но их нельзя игнорировать ». Одна из них – проблема реентерабельных обработчиков ошибок: их нет. Слишком легко получить ошибку или исключение, перейти к соответствующему обработчику ошибок (через IDT) и быстро получить вторую идентичную ошибку, прежде чем вы правильно сохраните достаточно контекста из первой. Если немного не повезет, можно потерять контекст или создать бесконечный цикл, если вы находитесь в процессе настройки указателей стека.

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

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

Оба предложения совершенно новые, и оба остались относительно незамеченными до определенного Линус Торвальдс взвесил с характерно ярким мнением. Его мнение? Это хорошие идеи. Почему бы не реализовать их оба? Хотя Intel и AMD использовали совершенно разные подходы, они не исключают друг друга. В худшем случае вы можете представить себе реализацию их обоих, а затем включение одного или другого (или ни одного) во время загрузки. Какой еще вариант конфигурации?

Не часто мы видим серьезные изменения в x 86 семейство процессоров. Может, это уже давно пора. Но поменять крыло на авиалайнере в полете (если воспользоваться старой аналогией) – дело непростое. Семейство x 86 выжило во многом благодаря своей обратной совместимости. Обе компании это понимают; эти предложения варианты , не обязательно замены. И они должны влиять только на код ядра ОС, а не на приложения или драйверы, поэтому они будут невидимы почти для всех. Возможно, мы никогда не увидим ни того, ни другого. Или мы можем рассчитывать на то, что обработка прерываний станет немного менее глючной.