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

878
Nik Novák

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

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

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

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

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

0
Я рекомендую отправить ваш вопрос в StackOverflow. Ваш вопрос имеет непосредственное отношение к оборудованию, но здесь очень мало программистов на ассемблере или хакеров ядра, и это немного над моей головой. Удачи тебе. Frank Thomas 8 лет назад 1
Они будут отклонять эту миграцию .... Ramhound 8 лет назад 0
Там нет ни кода, ни запроса, почему это не по теме здесь? Ramhound 8 лет назад 1
Учитывая, что там, кажется, есть 4 вопроса, я голосую за закрытие как слишком широкое. DavidPostill 8 лет назад 0

2 ответа на вопрос

2
Frank Thomas

Лучший ответ, который я могу вам дать, это то, что да, это правильно, что в большинстве современных процессоров только код, работающий в режиме ядра, может вызвать двойной или тройной сбой . Очень редко (но не невозможно), чтобы команда, не инициированная ядром, вызывала серьезную ошибку из-за операции 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]

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

Спасибо за ваш ответ, но извините, он не ответил на мои вопросы. С новым процессором я не имел в виду переход между процессором, работающим с реальными адресами, и процессором, работающим с виртуальными адресами. Я имел в виду, что если преемник некоторого ЦП (оба поддерживают виртуальную адресацию с некоторой защитой и полностью совместимы с прямой версией) добавил какую-то новую инструкцию, можно ли эту инструкцию использовать в режиме ядра программного обеспечения, которое будет работать на обоих этих ЦП. В этом случае ЦП в режиме ядра вызовет двойной сбой на старом ЦП из-за неопределенного исключения инструкции, не правда ли? Nik Novák 8 лет назад 0
Неопределенное исключение команды вызовет двойной / тройной сбой, если это инструкция, указанная в процедуре прерывания или исключения. если это в нормальном коде, однако, это не должно. ошибка произойдет, и переход к обработке исключений должен произойти как обычно. Я не совсем вижу, где защищенный или режим ядра входит в это все же. Планируете ли вы запустить некоторый код в качестве ядра, чтобы обойти совместимость защищенного режима и спросить, может ли такой подход вызвать проблемы? потому что да, это могло. будет ли он? зависит от кода и оборудования. Frank Thomas 8 лет назад 0
Спасибо за ваш ответ. Нет, это не мой план. Итак, вы хотите сказать мне, когда «нормальный» код выполняется в режиме ядра, исключение не возникает, прямой вызов двойного обработчика ошибок, но он вызывает соответствующий обработчик исключений? Если так, то в чем же разница между «нормальным» кодом и кодом обработчика прерываний и как ЦП знает, какой обработчик исключений должен вызывать? (имеется в виду любой обработчик исключений против двойного обработчика ошибок) Nik Novák 8 лет назад 0
двойная ошибка возникает, когда есть одна ошибка, а затем, когда процессор пытается ее обработать, в обработчике возникает другая ошибка. двойные ошибки могут произойти только в коде обработчика. Итак, является ли рассматриваемая инструкция частью обработчика исключений / прерываний? если это так, это может вызвать двойную ошибку. если нет, то не может. Frank Thomas 8 лет назад 0
Спасибо за ваш ответ. По вашему, поток ядра может нормально вызывать исключения? (не означает ошибки программиста, но, например, уже упоминавшуюся неопределенную инструкцию, может быть, ошибки страницы (заменены, если это возможно для потока ядра)). Он имеет некоторую логику, но как процессор распознает, если это обработчик прерываний / исключений, а не поток ядра, который вызывает исключение (оба работают в режиме ядра процессора)? Nik Novák 8 лет назад 0
это вне меня. Я знаю, что у большинства процессоров есть регистр прерываний, в котором хранятся векторы адресов, содержащие команды, которые нужно запускать в случае прерывания, но я не знаю, что помещает инструкции в эти адреса или как эти инструкции определены. Frank Thomas 8 лет назад 0
В любом случае, спасибо за ваше время, но я не могу принять ваш ответ, потому что он не дает прямого ответа на мой вопрос. Но это обсуждение было очень полезно для меня. Nik Novák 8 лет назад 0
0
John Burger

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

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

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

*(int *)0 = 0xdead; 

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

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

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

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

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

Похожие вопросы