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

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

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

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

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

2 ответа2

2

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

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

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

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

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

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

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

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

0

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

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

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

*(int *)0 = 0xdead;

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

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

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

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

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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .