LINUX.ORG.RU

[Поведение процессора][Мутабельный код] Вопрос.


0

1

Пусть у меня есть участок памяти, в который разрешена запись.

Я записал в этот участок какие-то инструкции.

Этот кусок будет кешироваться. (Так?)

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

Эти изменения изменяют некоторые последующие инструкции.

Как будет вести себя процессор, ведь эти изменения будут для него неожиданными. Как известно, процессор обрабатывает инструкции с помощью конвеера. В случае подобного изменения кода, инструкции, которые уже были взяты на конвеер следует отбросить.

Что происходит в подобных случаях?

/me вспомнил свой сайрикс 486 и прослезился :)

arsi
()
Ответ на: комментарий от mv

Я думаю еще стоит кеш инструкций сбросить (можно выборочно), потому что он ничего не знает о новых данных. Вообще нужны ли memory barriers зависит сильно от процессора. Имел как раз дело недавно с self-modifying code на ppc, там достаточно было сделать icache invalidate.

frey
()
Ответ на: комментарий от frey

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

С чего вдруг? На x86 кэш когерентный.

Вообще нужны ли memory barriers зависит сильно от процессора.

Зависит. Но проще делать. Производительно в любом случае пострадает: либо процессор сам конвейер сбрасывает, либо ты его в ручную.

Имел как раз дело недавно с self-modifying code на ppc, там достаточно было сделать icache invalidate.

Это примерно, как лечить головную боль гильотиной :) На x86, как уже говорил, смысла сбрасывать когерентный кэш нет.

На пеньтиумах и выше конвейер сбрасывается автоматически при записи по адресу (строки), в котором содержалась декодированная инструкция. Заморочки возникают, если код меняется на одном процессоре, а исполняется в другом. Другой процессор изменения не увидит, потому что триггер очистки конвейера для него не срабатывает. В таком случе тебе нужно упорядочить инструкции в конвейерах (через fence, cpuid, много их).

На 486 конвейер автоматически не сбрасывался, поэтому после записи нужно делать безусловный jmp куда-нибудь, чтобы инвалидировать таким образом содержимое конвейера.

mv
()
Ответ на: комментарий от frey

Вообще, чтобы не гадать, скачай architecture manual у производителя процессора. Там раздел про self-modifying code должен быть.

mv
()
Ответ на: комментарий от mv

А теперь главный вопрос, с чего ты решил, что у ТС x86? :) На моем ppc кэш не когерентный и после изменения кода кэш инструкций надо инвалидировать, как и написано в мануале. Опять же если процессор один на x86 с когерентным кэшем даже memory barrier не нужен, как ты и сказал. Если ТС имеет дело с несколькими процессами\процессорами помимо memory barrier надо бы проверить виртуальными или физическими адресами проиндексирован кэш, там тоже могут быть проблемы.

Кстати имеются ли сейчас процессоры, которые сами не сбрасывают конвейер?

frey
()
Ответ на: комментарий от frey

А теперь главный вопрос, с чего ты решил, что у ТС x86? :)

Дефолт сити, дефолт операционная система, дефолт процессор.

Опять же если процессор один на x86 с когерентным кэшем даже memory barrier не нужен, как ты и сказал.

Я откопал таки интеловский мануал (Intel® 64 and IA-32 Architectures Software Developer's Manual.Volume 3A: System Programming Guide), и там прямым текстом сказано, что для выполнения самомодифицирующегося кода нужно делать либо фенсинг (барьер), либо сбрасывать очередь декодированных инструкций через jmp.

Фенсинг нужен и в случае выполнения кода на том же процессоре, и в случае кросс-модификации, когда код меняет один процессор, а выполняет другой. Плюс другому процессору, естественно, нужно запрещать выполнять код в момент его модификации.

Кстати имеются ли сейчас процессоры, которые сами не сбрасывают конвейер?

Имеются процессоры, где их нет ;)

mv
()
Ответ на: комментарий от frey

Тогда я не понял про автоматический сброс конвейра, надо бы прояснить этот вопрос в мануале.

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

mv
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.