Что является причиной двойной ошибки на процессоре

Это мое предположение верно, если я скажу, что двойной сбой может и должен произойти только в режиме ядра процессора (или кольцо 0 для x86), когда происходит какое-либо исключение (синхронное), и никогда больше?

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

И моя дополнительная мысль. Есть ли какие-либо преимущества от того, что он будет реализован "внутренний бит включения INT" в регистре состояния, который будет автоматически установлен и очищен при возникновении прерывания / исключения и его возврате, а если исключение случится, HW считывает этот бит и, если установлено, оно переходит к адрес обработчика исключений, в противном случае переходит к двойному обработчику ошибок?

Если это зависит от архитектуры / ОС, я выбираю Linux на MIPS.

Извините за мой английский.

2 ответа

У меня большой опыт работы с x86, но в MIPS ничего нет, извините, но я считаю, что к нему применимо следующее описание.

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

Вот пример простой ошибки. Если код пытается получить доступ к недопустимой памяти:

*(int *)0 = 0xdead;

затем процессор обнаружит ссылку на нулевой указатель и попытается запустить обработчик ошибок памяти. Это может быть код пользователя (кольцо 3) или супервизора (кольцо 0), и двойной сбой не произойдет - ЦП просто попытается запустить обработчик ошибок памяти.

Представьте себе, что в ОС была ошибка, а сам обработчик ошибок памяти находился в недопустимой памяти. Таким образом, при попытке запустить обработчик ошибок памяти произошла другая ошибка, и первая ошибка не может быть обработана. Затем будет вызван обработчик Double Fault. (Если ошибка возникает при попытке запустить обработчик Double Fault, процессор x86 просто отключается с тройным отказом. Аппаратное обеспечение ПК обнаруживает это и сбрасывает процессор.)

Я неоднократно подчеркивал запуск, так как после успешного запуска обработчика сбоев больше не будет возникать двойной сбой. Первая ошибка начала обрабатываться, и ЦПУ теперь может обрабатывать любые новые ошибки, которые могут возникнуть. Процессор не "запоминает", что он находится внутри обработчика ошибок и вызывает двойной сбой, если возникает новый сбой.

В соответствии с вашим примером, если обработчик ошибок пытается использовать неопределенный код операции, то для этой инструкции будет просто вызван обработчик ошибок Неопределенный код операции. Это не двойная ошибка, это просто ошибка внутри ошибки.

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

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

Таким образом, да, любой машинный код, собранный для ЦП без ProtectedMode, должен быть хотя бы пересобран, если не изменен, для работы на более новом ЦП.

Из Википедии: https://en.wikipedia.org/wiki/Protected_mode

Виртуальный режим 8086 Основная статья: Виртуальный режим 8086

С выпуском 386 защищенный режим предлагает то, что в руководствах Intel называют виртуальным режимом 8086. Виртуальный режим 8086 разработан для того, чтобы код, ранее написанный для 8086, мог работать без изменений и одновременно с другими задачами без ущерба для безопасности или стабильности системы.[29]

Виртуальный режим 8086, однако, не полностью обратно совместим со всеми программами. Программы, которые требуют манипулирования сегментами, привилегированных инструкций, прямого доступа к оборудованию или используют самоизменяющийся код, будут генерировать исключение, которое должно обслуживаться операционной системой.[30] Кроме того, приложения, работающие в режиме виртуального 8086, генерируют ловушку с использованием инструкций, которые включают ввод / вывод (I/O), что может негативно повлиять на производительность.[31]

Из-за этих ограничений некоторые программы, изначально предназначенные для работы на 8086, не могут быть запущены в виртуальном режиме 8086. В результате системное программное обеспечение вынуждено либо ставить под угрозу безопасность системы, либо обратную совместимость при работе с устаревшим программным обеспечением. Пример такого компромисса можно увидеть с выпуском Windows NT, в котором отсутствует обратная совместимость для "плохого поведения" приложений DOS.[32]

Я надеюсь, что это немного поможет, и что, если этого недостаточно, другой может заполнить любые пробелы в моем понимании.

Другие вопросы по тегам