Процессоры ARM работают с двумя типами памяти:
normal memory и device memory. Задать тип памяти можно при помощи регистра MAIR (Memory Attribute Indirection Register) и группы из трех бит в записи таблицы страниц.Тип памяти
device memory обычно применяют для тех регионов, доступ к которым может породить какой-либо сайд-эффект. Обычно это память регистров устройств.Во всем этом нет ничего удивительного, пока мы не сталкиваемся с конвейером процессора и спекулятивным исполнением. Процессор может пытаться спекулятивно исполнять код, выбирая его из памяти, любой памяти, которая не маркирована атрибутом XN (Execute Never). В том числе из
device memory!В документации ARM утверждают, что выборка инструкций из
device memory приводит к непредсказуемому результату.Описанное выше — не просто теория, приходилось сталкиваться с подобным поведением на практике: из-за забытого XN-бита в записях таблиц страниц контроллер прерываний иногда работал некорректно, переходя в непредсказуемые состояния. Виновником оказалась спекулятивная выборка из
device memory.