Предисловие

Информации в данной статье не стоит стопроцентно и безоговорочно доверять. Я и мой товарищ, который помогал мне со сбором информации, только изучаем тему микроэлектроники не являемся экспертами в отрасли процессорных архитектур, в особенности RISC-V, отчего в данной статье могут быть ошибки, в виду не полного понимания темы. Всю информацию мы брали из открытых источников, документаций и статей с нашего любимого Хабра, Гит-хаба и подобных, поэтому для погруженных в тему людей данная статья, скорее всего, ничего нового и полезного не даст. Однако, я был бы рад получить конструктивную критику от знающих людей, чтобы разобраться в этой теме лучше.

P.S. Огромное спасибо за помощь в сборе информации моему товарищу Елфимову Артёму Андреевичу

Введение

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

Разработка аппаратной безопасности включает в себя множество различных механизмов, такие как: разграничение уровней доступа, изоляция памяти, контроль выполнения привилегированных команд, использование доверенных сред исполнения. Важно понимать, что безопасность в процессорах — это не просто возможность дополнительной защиты, а необходимость, которая обхватывает не только микроархитектуру, но и программную инфраструктуру, взаимодействующую с ней. При правильном проектировании аппаратная безопасность позволяет предотвращать атаки.

Исторически считалось, что закрытые архитектуры, такие как x86 (Intel, AMD) и ARM, обладают встроенной безопасностью, благодаря контролю производителя над всеми составляющими в процессоре. Однако, с ростом сложности микропроцессоров, оказалось, что даже они не являются безопасными.

Яркий пример — атаки Spectre и Meltdown, позволившие извлекать данные из защищённой памяти [1]. Эти атаки затронули почти все современные процессоры, включая Intel, AMD и ARM.

В этом контексте особое внимание вызывает RISC-V — открытая архитектура команд, предоставляющая гибкость и прозрачность во всех своих аспектах. Но возникает вопрос: если даже закрытые архитектуры уязвимы, как обеспечивается безопасность в открытой архитектуре RISC-V? Но для начала, нам нужна небольшая историческая справочка в истории архитектур

1 Эволюция архитектур: от CISC к RISC

1.1 CISC-процессоры

В 1970-1980-ых годах на рынке микроэлектроники доминировали CISC-процессоры (Complex Instruction Set Computer - компьютер с полным набором команд), архитектуры x86. Главная особенность подобных процессоров была в том, что сложные операции выполнялись одной инструкцией длиной от 1 до 15 байт. Инструкция – это закодированная команда, определяющая операцию, которую должен выполнить процессор. Данный подход хоть и был неплохим, но имел в себе много недостатков:

  • Так как инструкции могли быть очень длинными, они требовали больше транзисторов, что повышало энергопотребление процессора, что было большой проблемой для отрасли 3д-моделирования и рендеринга того времени;

  • Для декодирования и выполнения нескольких сложных операций процессору требовалось много памяти, которая на тот момент стоила очень дорого (к примеру, один мегабайт оперативной памяти стоил около 5000 долларов). Также при обращении декодера к памяти скорость обработки инструкций становилась меньше;

  • Большинство возможностей CISC (например, строковые операции) редко использовались, но усложняли декодер.

1.2 Возникновение архитектуры RISC

В середине 1980-ых стали появляться процессоры на новом архитектурном подходе RISC (reduced instruction set computer - вычислитель с сокращённым набором команд). Его отличием от CISC было:

  1. Фиксированная длина инструкции - всего 4 байта, что снизило энергопотребление.

  2. Минимально необходимый набор команд, без лишней нагрузки на декодер.

  3. Большое количество регистров, куда часть необходимых команд могли сохраняться, не прибегая к использованию памяти.

Но главным преимуществом RISC стала конвейеризация процессора - выполнение несколько инструкций одновременно. К примеру, для исполнения инструкции, она проходит 5 этапов:

  1. Fetch (чтение инструкции).

  2. Decode (декодирование).

  3. Execute (выполнение).

  4. Memory Access (работа с памятью).

  5. Writeback (запись в регистр).

Каждый из этих этапов выполняется в один такт. В CISC процессорах пока одна инструкция проходит эти 5 этапов, вторая ждёт полного исполнения инструкции, чтобы начинать первый этап, когда как в RISC вторая инструкция может приступать первому этапу сразу, как первая инструкция перешла на второй. Если в CISC первая инструкция выполняется за 5 тактов, то вторая уже за 10, а третья за 15, в то время как в RISC все три выполнялись за 5 тактов. Архитектура оказалась успешной и производительной: любой процессор на базе RISC был в разы эффективнее в работе, чем его аналог на CISC[2].

1.3 Распространение RISC-архитектур

В дальнейшем началось сильно развитие архитектур на основе подхода RISC: в последнее время популярная архитектура ARM, процессоры которой стоят в каждом смартфоне и современных ноутбуках, и персональных компьютерах от Apple, нынче почившая MIPS, на базе которой делали процессор для PlayStation 1 и 2, а также появившаяся в 2010 году открытая архитектура RISC -V.

Основной особенностью RISC-V является её открытость и персонализированность в настройках. Если процессоры на архитектуре ARM хоть и являются производительными и современными, их нужно лицензировать, когда как RISC -V, несмотря на то, что подобен процессорам RISC 80-х и 90-х годов и во многом сильно проигрывает ARM, является открытой, и имеет возможность добавить собственные инструкции и декодер, настроить опциональные расширения для команд и также инструменты для информационной защиты процессора [3].

2 PMP: Защита памяти в RISC-V

2.1 Зачем нужна защита памяти

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

2.2 Защита памяти в архитектуре RISC-V

В архитектуре RISC-V есть такой механизм защиты памяти, как PMP (Physical Memory Protection). С помощью него можно задать участки физической памяти, записав его в один из регистров, доступ к которым будет запрещен. Например, можно сделать запрет на чтение, запись или выполнение программ. Это полезно, если программа в пользовательском режиме, то она не сможет прочитать или изменить память, доступ к которой запрещён в настройках PMP. Его главным отличие от аналогов в x86 и ARM является использование физической памяти, а не виртуальной, благодаря чему PMP в выбранной области памяти будет осуществлять защиту лучше, чем методы, использующие виртуальную память. Но из-за небольшого количества регистров (от 8 до 16), метод не подходит для сложных ОС (например, Linux), так как не сможет защитить все области системы, поэтому PMP более эффективен для встраиваемых систем и устройств без полноценной операционной системы.

Основной принцип работы PMP поделен на два типа регистров:

  1. Регистры pmpaddr0–pmpaddrN: Определяют границы защищаемых областей памяти. Количество регистров зависит от конкретной реализации (обычно от 8 до 16). Формат адреса зависит от режима адресации (TOR, NAPOT).

  2. Регистры pmpcfg0–pmpcfgN: Задают права доступа для соответствующих областей. Каждый регистр pmpcfg содержит 8 бит, которые определяют:

    • Разрешение на чтение (R), запись (W) и выполнение (X);

    • Режим блокировки (L), предотвращающий изменение правил до перезагрузки системы.

Данные регистры важно настроить правильно, ведь при неверных ограничениях областей памяти может произойти утечка данных [4].

Пример записи длины защищаемой области в регистр pmpaddr
Пример записи длины защищаемой области в регистр pmpaddr
Схема записи байтов в регистр pmpcgf0
Схема записи байтов в регистр pmpcgf0

2.3 Защита памяти в архитектуре x86

В архитектуре x86 механизм защиты памяти устроен иначе, через метод страничной организации (paging), который использует виртуальную память. Механизм так и называет - Paging Protection. Он позволяет:

  • Изолировать процессы друг от друга;

  • Контролировать доступ к памяти на уровне страниц (обычно 4 КБ);

  • Реализовывать разграничения по уровню привилегий Ring levels (0–3) для разных участков памяти.

Данный механизм отлично подойдёт для сложный систем, ведь имеет многоуровневую структуру регистров (PML4 - Page Map Level 4, PDP - Page Directory Pointer, PD - Page Directory, PT - Page Table), благодаря чему охватывает всю ОС, но из-за сложности настройки не подойдёт для простых устройств [5].

2.4 Защита памяти в архитектуре ARM

Архитектура ARM использует комбинацию MMU (Memory Management Unit) и бита PXN (Privileged Execute Never):

  • MMU: Управляет трансляцией виртуальных адресов в физические;

  • PXN: Запрещает выполнение кода в пользовательском режиме для определенных страниц.

Данный механизм больше нацелен на энергоэффективность, поэтому имеет меньше регистров и более прост в настройке, чем Paging, но также пригоден для работы со сложными ОС [6]. Для корректной работы механизма потребуется настроенный TrustZone, о котором мы расскажем далее.

Критерий 

RISC-V (PMP)

x86 (Paging)

ARM (MMU+PXN)

Работа без ОС

Да

Нет

Нет

Гранулярность

8–16 регистров

4 КБ–1 ГБ

4 КБ–1 ГБ

Сложность    настройки 

Простая (регистры)

Сложные таблицы страниц

Для настройки требуется TrustZone

3. Доверенная среда исполнения в RISC-V

3.1 Что такое TEE (Trusted Execution Environment)

Методы безопасности нужны не только памяти процессора, но и код и его корректное исполнения. Для такого типа информации есть TEE (Trusted Execution Environment - доверенная среда исполнения) – это среда внутри процессора, предназначенная для безопасного исполнения кода и хранения чувствительных данных. Данная среда обеспечивает изоляцию от основной операционной системы и приложений. Даже если хост-система скомпрометирована, код внутри TEE остаётся защищённым [7].

3.2 Подход к TEE в архитектуре RISC-V

В RISC-V нет встроенного TEE на уровне архитектуры, но есть множество внешних решений, которые пользователь по предпочтению может поставить сам: Keystone Enclave, OpenTitan, Hex-Five MultiZone Security, Bao Hypervisor, Silicon Labs Secure Vault и другие. Из них всех возьмём лишь самый популярный - Keystone Enclave [8].

Keystone — это платформа открытого исходного кода (open-source), предназначенная для реализации TEE (Trusted Execution Environment) на базе архитектуры RISC-V.

Концепция Keystone базируется на технологиях Intel SGX, то есть доверенная среда реализуется через анклав - защищённую область памяти, которая позволяет выполнять код и хранить данные так, что даже операционная система или привилегированный пользователь не могут получить к ним доступ без соответствующих прав, и данная защищённая область в Keystone выделяется с помощью PMP. Но несмотря на заимствования идей у Intel и ARM, построена данная TEE с учётом всех их слабостей. Сам Keystone, подобно RISC-V, также открыт и гибок в настройках, его можно проанализировать на уязвимости, улучшить или адаптировать под себя, чего нельзя сказать про SGX и TrustZone. Так же и сама доверенная среда построена модульно, и разработчик может самостоятельно настроить, какие компоненты попадут в доверенную базу, а какие останутся за пределами защищённой области. Но для данного метода нужна точная и правильная настройка, ведь при неверных параметрах может произойти утечка данных и потеря конфиденциальной информации[9]. Keystone — это гибкий, программный и открытый аналог, реализующий TEE поверх минимального набора аппаратных расширений.

Работа анклавов Keystone
Работа анклавов Keystone

3.3 Сравнение Keystone Enclave с аналогами других архитектур

Intel SGX — это набор инструкций на x86 от Intel, позволяющий создавать анклавы внутри адресного пространства процесса. В отличии от Keystone, анклав в SGX находится в пределах одного процесса, но область памяти анклава шифруется и аппаратно защищена от остальной ОС. Работает SGX на уровне пользовательского режима (Ring 3), в качестве самого анклава реализует защищённую область DRAM, и данный TEE широко используется в облачных решениях, таких как Azure Confidential Computing. Из недостатков выделяют сложность программирования и отладки SGX, а так наличие серьёзных уязвимостей, которые невозможно проанализировать из-за проприетарности метода [10].

Работа анклава Intel SGX
Работа анклава Intel SGX

TrustZone – аппаратная технология от ARM, которая делит систему на два "мира":

  1. Secure World — по сути является той самой доверенной средой.

  2. Normal World — основная операционная система и приложения.

Между этими “мирами” переключение осуществляется через инструкции SMC (Secure Monitor Call). Secure World имеет доступ к ресурсам Normal World, но не наоборот. Обычно эта технология используется в Android для реализации Trusty OS, а также в чипах с DRM (Технические средства защиты авторских прав). Минусом у TrustZone является его закрытая реализация, и разработчики не могут свободно адаптировать TEE под необходимые задачи [11].

Пример работы TrustZone
Пример работы TrustZone

Параметр

Keystone  (RISC-V)

Intel SGX (x86)

TrustZone (ARM)

Открытость

Полностью открытый код и спецификации

Закрытая реализация

Закрытая реализация

Изоляция

На основе PMP и привилегий

Аппаратная изоляция в CPU

Аппаратный делитель мира

Гибкость

Пользователь может адаптировать архитектуру под нужды

Жёстко привязан к Intel чипам

Жёстко привязан к ARM Cortex

Применение

IoT, edge-серверы, исследовательская среда

Облачные сервисы, DRM

Мобильные устройства, криптооперации

4. Контроль привилегий в процессорах

4.1 Зачем нужен контроль привилегий

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

4.2 Механизм привилегий в архитектуре RISC-V и ее аналогах

В RISC-V существует три уровня привилегий:

  • Machine mode (M-mode) — самый высокий, доступ ко всей памяти, как виртуальной, так и физической;

  • Supervisor mode (S-mode) — для операционной системы, может управлять виртуальной памятью и процессами;

  • User mode (U-mode) — для обычных приложений.

Для каждого режима разрешен только определенный набор действий [12].

Если сравнивать с архитектурой x86, то там контроль привилегий действует иначе, есть кольца (Ring 0 — Ring 3), где Ring 0 - это самый высокий уровень, а Ring 3 - это обычные приложения [13].

Уровни привилегий в x86
Уровни привилегий в x86

У ARM тоже своя система и в старых версиях она была схожа с RISC-V, но в более новых появился механизм TrustZone, который делит систему на обычную и защищённую, что позволяет выполнять важные задачи отдельно от основной операционной системы.

Уровни привилегий в ARM
Уровни привилегий в ARM

5. Защита от спекулятивных атак в процессорах

5.1 Что такое спекулятивное выполнение

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

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

  1. Атакующий многократно вызывает код с корректным индексом x, чтобы процессор «привык» выполнять эту ветку.

  2. Теперь он передаёт нужный ему индекс, выходящий за границы массива и указывающий на защищённые данные (к примеру, пароли и ключи шифрования). Тем временем процессор:

    • Спекулятивно загружает array[x] (например, секретный ключ);

    • Проверяет условие и понимает, что доступ запрещён;

    • Отменяет операцию, но следы остаются в кэше;

  3. Атакующий измеряет время доступа к ячейкам памяти:

    • Если данные были в кэше (значит, они спекулятивно загружались) — доступ быстрый;

    • Если не были — доступ медленный.

Таким образом атакующий получает доступ к защищённой информации. Подобных уязвимостей много, самые популярные из них:

  1. Spectre — манипулирование ветвлениями, обход изоляции между процессами.

  2. Meltdown — доступ к защищённой памяти через спекулятивное выполнение.

Эти уязвимости затронули почти все современные процессоры на x86 и ARM, и возникла необходимость в их архитектурных изменениях [14].

Пример работы Spectre-атаки
Пример работы Spectre-атаки
Пример работы Spectre-атаки
Пример работы Spectre-атаки

5.2 Реализация защиты в RISC-V и других архитектурах

RISC-V, в отличие от x86 и Arm, не требует спекулятивного выполнения для высокой производительности. Однако некоторые ядра поддерживают эту оптимизацию, что делает их потенциально уязвимыми. К примеру, 64-битное ядро CVA6 поддерживает спекулятивное выполнение, и несмотря на то, что это ускоряет доступ к памяти, повышая эффективность ядер, появляется потенциальная уязвимость Spectre-атаки. Для защиты ядра была создана fence инструкция - принудительный барьер, который сбрасывает спекулятивные операции при смене контекста. И всё равно, если от атак Spectre-V2 fence защищает, то Spectre-V1 все ещё возможен, если ядро спекулятивно выполнит инструкции после условного перехода. Но ядро Ariane не имеет поддержки спекулятивного выполнения, что хоть и понижает их производительность, по сравнению с CVA6, но делает его абсолютно неуязвимым к любым спекулятивным атакам [15].

Intel и AMD выпускают обновления для своих x86 процессоров, которые добавляют новые механизмы защиты:

  • IBRS (Indirect Branch Restricted Speculation) – ограничивает спекулятивное выполнение косвенных переходов;

  • STIBP (Single Thread Indirect Branch Predictors) – защищает от атак между потоками (например, в облаке).

Данные механизмы запрещают использование истории предсказаний ветвлений инструкций, что защищает от Spectre-атак, но уязвима к Meltdown и понижает производительность процессора на 5–15%. В качестве альтернативы этим механизмам есть LFENCE-барьер, который принудительно останавливает спекулятивное выполнение последующих команд. Данный метод помимо неуязвимости к Spectre даёт частичную защиту к Meltdown, и понижает производительно всего на 5%.

Процессорные ядра у ARM более уязвимые к Spectre, чем x86[16], поэтому был создан аналог LFENCE в ARM - инструкция CSDB. Принципиально, они ничем друг от друга не отличаются, и CSDB, так же как LFENCE, блокируют большинство Spectre-атак, но в отличии от x86, армовский аналог понижает производительность до 10%. Также, из аппаратных методов у ARM есть SSBS (Speculative Store Bypass Safe)[17], который отключает спекулятивный обход проверок памяти, защищает от большинства Spectre-атак и понижает производительность на 5-10%. Но данный метод включается через регистр SCTLR_ELx.SSBS, по умолчанию включён только CSDB[18].

6. Экспериментальная часть, с целью проверки методов безопасности процессоров RISC-V на практике

К сожалению, у меня нет системы с процессором на архитектуре RISC-V, поэтому эксперименты были проведены в программе для эмуляции аппаратного обеспечения различных платформ QEMU, так как он поддерживает эмуляцию процессоров на архитектуре RISC-V, на виртуальной операционной системе Ubuntu. В программировании на ассемблере я чайник, поэтому в помощь мне приходили некоторые форумы и нейронный товарищ в лице ChatGPT. Прошу сильно не сердиться)

6.1 Эксперимент 1: Настройка PMP

Цель эксперимента: проверить, как механизм PMP настраивается и ограничивает доступ программ к определённым физическим адресам, особенно при переходе из режима привилегий M-mode (Machine) в U-mode (User).

Для начала попробуем корректную настройку PMP.

Структура проекта:

  1. main.c - основной код (настройка PMP + тест записи).

  2. start.S - ассемблерный код, который выполняется самым первым после загрузки программы. Его задачи:

    • инициализировать стек (sp);

    • подготовить окружение для запуска main() (например, очистить .bss);

    • переключиться в нужный режим.

  3. linker.ld - конфигурационный файл, который указывает компоновщику:

    • где в памяти размещать код (text), данные (data, bss) и другие секции;

    • как выравнивать секции;

    • какие симоволы (например, _start) считать точками входа.

Корректная настройка PMP:

Файл main.c
Файл main.c
  1. configure_pmp() настраивает pmpaddr0 на область 4К от 0x80000000.

  2. Устанавливается pmpcfg0 на RWX (команда для изменения прав доступа).

  3. Данные регистров pmpaddr0 и pmpcfg0 записываются в allowed.

  4. Запись регистров в forbidden — выходит за пределы и вызывает trap (в QEMU просто "виснет").

Файл linker.ld
Файл linker.ld

Файл linker.ld размещает код по адресу 0x80000000, так как PMP настраивается на этот же адрес.

Файл start.S
Файл start.S

Минимальный стартовый код:

  • устанавливает стек (sp);

  • Вызывает main;

  • Бесконечный цикл после выхода из main.

Ожидаемое поведение:

  • если QEMU с поддержкой PMP — trap при второй записи;

  • если PMP не эмулируется — запись произойдёт (плохой результат);

  • если всё настроено верно — QEMU зависнет или покажет trap (в зависимости от настроек).

Запуск:

Компиляция start.S и main.c в нужные форматы

Запуск QEMU с файлом формата .elf

Видим, что QEMU – завис. Чтобы в этом удостовериться используем команду «ps aux | grep qemu», если увидим, что сеанс программы не завершён – QEMU зависла. QEMU действительно зависла, следовательно, произошёл вызов «trap», PMP заблокировал доступ к выделенной области, и эксперимент прошёл успешно.

Некорректная настройка PMP:

Дальше попробуем намеренно настроить PMP неправильно. Изменим файл main.c

Файл main.c
Файл main.c
Файл main.c
Файл main.c

PMP настроен на 0x80200000, но ошибочно: разрешены все доступы. Происходит переход в U-mode. U-код обращается по адресу 0x80200000, и это срабатывает. Выводится «[U-MODE] Write succeeded! PMP failed!»

Файл linker.ld
Файл linker.ld

Добавляет секцию .rodata для смены уровня привилегий, а также исключает лишнее. Файл start.S остаётся без изменений.

Программа должна вывести:

«[M-MODE] PMP incorrectly configured. Should block, but doesn't.

[U-MODE] Attempting to write to protected memory...

[U-MODE] Write succeeded! PMP failed!»

Запуск. Компилируем файлы и запускаем QEMU

Программа зависла – следовательно PMP сработал или произошла проблема при переходе в другой уровень привилегий. Попробуем добавить в код настройку mstatus перед mret, для корректного перехода по уровням привилегий.

Добавление настройки mstatus

Запуск эмулятора через интерфейс OpenSBI

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

6.2 Эксперимент 2: Моделирование Spectre-подобной атаки в RISC-V

Цель эксперимента: Смоделировать условия для Spectre-атаки в эмуляторе RISC-V. В RISC-V QEMU обычно нет поддержки спекуляции, но мы имитируем её поведение: покажем, как потенциально могла бы произойти утечка через побочный канал, даже если реально спекуляции нет.

Суть нашей Spectre-атаки:

  • есть секретный массив, который мы должны достать: secret[];

  • есть проверка границы доступа к array[index], которая должна ограничить доступ;

  • но при спекуляции CPU может временно проигнорировать проверку границы и начать выполнять следующую команду (например, доступ к secret);

  • даже если потом выполнение отменяется, побочные эффекты (например, кэш) остаются — их можно "заметить";

  • именно этой уязвимостью мы и воспользуемся.

Структура проекта:

  • main.c - основной код — имитация Spectre;

  • start.S - инициализация и запуск main;

  • linker.ld - разметка памяти.

Файл main.c
Файл main.c
Файл main.c
Файл main.c

Пояснение кода: есть массив unused_array — безопасный буфер. Есть секретный байт secret, расположенный сразу за unused_array. Функция victim_function получает индекс, проверяет, что он внутри unused_array и читает значение из этого массива, а затем обращается к probe_array по индексу, зависящему от прочитанного байта. В норме выход за пределы массива невозможен, но в спекулятивном исполнении процессор мог бы "спекулятивно" выполнить код с неправильным индексом, косвенно раскрывая значение secret. Функция spectre_attack пытается вызвать victim_function с индексом, указывающим на секретный байт, и затем анализирует изменения в probe_array, чтобы "угадать" секрет. В выводе показывается угаданное значение секретного байта (в данном случае — D0 в шестнадцатеричном виде).

Файл linker.ld
Файл linker.ld
Файл start.S
Файл start.S

Почему это не реальная спекулятивна атака:

  • нет спекуляции в QEMU;

  • нет реального кэша, а значит и времени доступа;

  • это учебная симуляция: мы "предполагаем", что доступ по неверному индексу всё же произошёл и повлиял на поведение.

Программа должна вывести:

«[SPECTRE] Starting simulation...

Guessed secret: D0»

Запуск. Компилируем start.S и main.c в нужные для работы форматы

Запуск QEMU с файлом формата .elf

В выводе мы видим секретный байт, следовательно, Spectre атака прошла успешно – эксперимент удачный.

6.3 Эксперимент 3: Демонстрация Keystone Enclave в QEMU

Цель эксперимента: Запустить защищённое исполняемое окружение (TEE) с помощью Keystone и продемонстрировать его работу на RISC-V через эмулятор QEMU. Несмотря на то, что вариантов механизма TEE в архитектуре RISC-V достаточно, мы решили так же взять Keystone, так как он позволяет:

  • создавать и запускать энклавы — приложения в изолированной защищённой среде;

  • использовать SDK для их написания;

  • запускать всё это в QEMU, даже без физического RISC-V железа.

Запуск. Установка зависимостей

Так как Keystone — это внешняя open-source система, её нужно клонировать вручную с GitHub [20].

Далее идет сборка собственного RISC-V компилятора, настроенного для работы с Keystone

Переходим в директорию папки sdk. Запускаем скрипт init.sh. Скрипт init.sh подготовит окружение и необходимые зависимости

Далее производим сборку тестовой энклавы (HelloWorld)

После сборки появились два бинарных файла:

  • host_helloworld — программа на стороне хоста;

  • eapp_helloworld — исполняемый код в энклаве.

Производим запуск через QEMU. Переходим в директорию scripts – ближе к «сердцу» Keystone и запускаем скрипты

На консоль выводится запуск системы и выполнение защищённого кода. Энклава демонстрирует базовую функциональность TEE: код исполняется в изолированном пространстве, доступ к нему ограничен со стороны основной ОС.

Данный вывод означает что:

  • хост-приложение запустило энклаву;

  • код внутри энклавы выполнен изолированно;

  • доверительная среда (TEE) работает.

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

7. Заключение

Архитектура RISC-V, несмотря на свою относительную молодость и моральную устарелость, демонстрирует высокую степень возможности глубокой настройки систем безопасности. В отличие от закрытых архитектур x86 и ARM, она предлагает разработчикам возможность гибко настраивать уровни доступа, расширять набор инструкций и интегрировать механизмы защиты по своему вкусу. Такие технологии, как PMP, Keystone и трёхуровневая модель привилегий, позволяют реализовать надёжную защиту данных и изоляцию процессов на уровне встраиваемых систем.

Однако RISC‑V имеет и определённые ограничения. Архитектура не имеет полноценной защиты от спекулятивных атак в общедоступных ядрах, а PMP ограничен по количеству регионов и подходит в первую очередь для встраиваемых решений, а не для полноценных операционных систем. Архитектуры x86 и ARM имеют более зрелые аппаратные защиты, но их сложность и закрытость осложняют аудит, доверие и анализ уязвимостей.

RISC‑V обеспечивает удобную площадку для создания систем с расширяемой и проверяемой моделью защиты, что особенно важно для критических сфер и встраиваемых систем.

Сравнение с архитектурами x86 и ARM показывает, что закрытость не является гарантией защищённости. Примеры атак Spectre и Meltdown затронули многие устройства, преимущественно на закрытых архитектурах.

Открытость RISC‑V даёт возможность независимым исследователям и организациям самостоятельно изучать и расширять защитные механизмы, и главное — доверять тому, что их процессор действительно делает. Примеры Keystone Enclave показывают, что открытые TEE‑решения могут быть не менее сильными, чем закрытые TrustZone и SGX.

Таким образом, открытые архитектуры, при грамотной настройке и сообществе разработчиков, способны обеспечивать более надёжную и контролируемую защиту, чем проприетарные.

Список использованных источников

  1. Статья об атаках Spectre и Meltdown на сайте Касперского URL: https://www.kaspersky.ru/blog/spectre-meltdown-in-practice/32334/

  2. «Ретроспективный взгляд на развитие микропроцессоров CISC, RISC, MIPS, ARM» URL: https://habr.com/ru/companies/first/articles/798635/ 

  3. «Гениальность микропроцессоров RISC-V» URL: https://habr.com/ru/companies/vdsina/articles/534542/ 

  4. Официальная документация про PMP на сайте проекта «RISC-V» URL: https://riscv.org/blog/2024/03/adding-physical-memory-protection-to-the-veer-el2-risc-v-core-2/

  5. Страница на OSDev Wiki про механизм защиты Paging URL: https://wiki.osdev.org/Paging

  6. Страница на DeepWiki про меры безопасности архитектуры ARM URL: https://deepwiki.com/nccgroup/exploit_mitigations/4.1-arm-architecture-security-mitigations

  7. Статья про Trusted Execution Environment на сайте Microsoft URL: https://learn.microsoft.com/ru-ru/azure/confidential-computing/trusted-execution-environment

  8. Статья про особенности TEE Xuantie на сайте проекта «RISC-V» URL: https://riscv.org/blog/2023/01/xuantie-risc-v-tee-solution-for-mcu/ 

  9. «Проект Keystone: доверенная среда для запуска приложений на базе RISC-V» URL:  https://habr.com/ru/companies/mws/articles/423777/

  10. «Trusted Execution Environment на примере Intel SGX. Основные принципы простыми словами. «Hello World!»» URL: https://habr.com/ru/articles/518004/

  11. «TrustZone: доверенная ОС и ее приложения» URL: https://www.aladdin-rd.ru/company/pressroom/articles/trustzone-doverennaa-os-i-ee-prilozenia/

  12. Руководство по набору инструкций RISC-V, Том II: Привилегированная архитектура URL: https://www.five-embeddev.com/riscv-priv-isa-manual/latest-latex/priv-intro.html

  13. «Кольца, уровни привилегий и защита в x86» URL: https://habr.com/ru/companies/smart_soft/articles/184174/

  14. «Новая техника атак на основе Meltdown. Использование спекулятивных инструкций для детектирования виртуализации» URL: https://habr.com/ru/companies/bizone/articles/359110/

  15. «Программное обеспечение для защиты от атак Spectre в RISC-V» URL: https://link.springer.com/chapter/10.1007/978-3-031-52947-4_5 

  16. Статья «Новая атака обходит аппаратную защиту от уязвимостей Spectre в процессорах Intel и ARM» URL: https://www.csoonline.com/article/572191/new-attack-bypasses-hardware-defenses-for-spectre-flaw-in-intel-and-arm-cpus.html

  17. SSBS, Speculative Store Bypass Safe Documentation URL: https://developer.arm.com/documentation/ddi0601/2025-03/AArch64-Registers/SSBS--Speculative-Store-Bypass-Safe

  18. CSDB, Consumption of Speculative Data Barrier Documentation URL: https://developer.arm.com/documentation/ddi0596/2020-12/Base-Instructions/CSDB--Consumption-of-Speculative-Data-Barrier-

  19. QEMU User space emulator URL: https://www.qemu.org/docs/master/user/main.html

  20. Keystone Enclave (QEMU + HiFive Unleashed) URL:  https://github.com/keystone-enclave/keystone

Комментарии (25)


  1. Kerman
    04.08.2025 18:12

    Каждый из этих этапов выполняется в один такт. В CISC процессорах пока одна инструкция проходит эти 5 этапов, вторая ждёт полного исполнения инструкции, чтобы начинать первый этап

    Нет, в CISC вполне себе конвеер c i486 и какие-то команды могут исполняться в один и тот же такт на разных блоках (с пентиума про). Вот старая статья про них.


    1. SIISII
      04.08.2025 18:12

      Более того, и конвейер, и суперскалярность появились ещё на машинах 1960-х годов. У нас первой конвейерной машиной была БЭСМ-6 (1967 год), у американцев всё это появилось ещё раньше.


    1. Fin_Debov Автор
      04.08.2025 18:12

      Это да, но i486 является гибридом RISC и CISC, а в статье я говорил именно про момент появления RISC, когда у CISC ещё не было конвейеризации. Понятно, что позже, в погоне за RISC, CISC-подобные архитектуры начали задумываться о добавлении конвейеризации, и в последствии появился i486. Но спасибо за дополнение


      1. SIISII
        04.08.2025 18:12

        Если говорить про архитектуры (в первом приближении -- про системы команд), то никаким гибридом i486 не является -- самый натуральный (и плохой) CISC.

        Если же говорить про внутреннее устройство, то, как я уже написал, конвейеризация появилась задолго до появления RISC, и одно с другим не связано от слова "совсем".


      1. Kerman
        04.08.2025 18:12

        Гибридом RISC и CISC был Cyrix 6x86 (M1) намного позже. У него было рисковое ядро и транслятор x86 в команды ядра. Вот статья.


  1. anoldman25
    04.08.2025 18:12

    Яркий пример — атаки Spectre и Meltdown, позволившие извлекать данные из защищённой памяти [1]. Эти атаки затронули почти все современные процессоры, включая Intel, AMD и ARM.

    Вот еще одна ошибка в первых pentium - FDIV:

    https://ru.wikipedia.org/wiki/Ошибка_Pentium_FDIV


    1. Fin_Debov Автор
      04.08.2025 18:12

      Спасибо за дополнение, изучу этот вопрос


    1. SIISII
      04.08.2025 18:12

      Ну, это именно ошибка в чистом виде, а не "фишка" (особенность микроархитектуры), которая превращается в уязвимость.


  1. SIISII
    04.08.2025 18:12

    • Так как инструкции могли быть очень длинными, они требовали больше транзисторов, что повышало энергопотребление процессора, что было большой проблемой для отрасли 3д-моделирования и рендеринга того времени;

    • Для декодирования и выполнения нескольких сложных операций процессору требовалось много памяти, которая на тот момент стоила очень дорого (к примеру, один мегабайт оперативной памяти стоил около 5000 долларов). Также при обращении декодера к памяти скорость обработки инструкций становилась меньше;

    • Большинство возможностей CISC (например, строковые операции) редко использовались, но усложняли декодер.

    Строго говоря, неверны все три пункта.

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

    С декодированием тоже далеко не всё однозначно. Когда автор статьи пишет про длину команды от 1 до 15 байт, он, несомненно, имеет в виду IA-32 aka x86. Эта кодировка не самая длинная (у VAX-11, если память не изменяет, длина команды могла достигать вообще 36 байт), но одна из самых бредовых и сложных для декодирования -- в первую очередь, из-за наличия префиксов, ни количество, ни порядок которых никак архитектурой не ограничены. Однако CISC отнюдь не обязан быть столь безумным. Скажем, такой классический CISC, как IBM System/360 (и все её потомки, включая современную z/Architecture), имеет длину команды 2, 4 или 6 байт, причём длина однозначно устанавливается анализом двух старших битов первого байта -- т.е. даже проще, чем, скажем, для команд набора Thumb-2 архитектуры ARM (там всего две длины -- 2 или 4 байта, -- но анализ длины сложнее).

    Насчёт памяти написана вообще полная ерунда -- CISC как раз требует меньше памяти, поскольку в одной команде может закодировать куда более сложную операцию. Сколько места займёт подпрограмма шифрования AES на ARM или RISC-V? Ну а на мэйнфреймах z/Architecture это делается одной командой. А если необходима десятичная арифметика? (а она необходима для финансового сектора -- недаром соответствующие вещи есть, например, в Жабе) На большинстве архитектур, включая IA-32, будут пляски с бубном, чтобы добиться того же результата, используя целочисленную двоичную арифметику, ну а мэйнфреймы ещё с Системы 360 имеют и команды десятичной арифметики. Да, и операция пересылки строк на них тоже используется весьма и весьма часто -- пересылать ведь не только строки в узком смысле приходится, а произвольные блоки данных.

    (Замечу, что есть по крайней мере одно типа исследование, которое "доказывает", что плотность кода CISC ниже, чем RISC: но, во-первых, сами авторы там между строк замечают, что, фактически, их сравнение неправомерно, поскольку сравнивают современные 64-разрядные архитектуры ARMv8 и RISC-V с древними CISCами, где 64-разрядные расширения были добавлены много позже -- а соответственно, все короткие коды операций уже попросту были заняты; а во-вторых, они начисто игнорируют случаи, когда сложные операции выполняются на CISCах одной-двумя командами, а на RISCах требуют подпрограмм значительного размера -- т.е., попросту говоря, подбирают тесты под требуемые результаты)

    Усложнение декодера -- тоже далеко не факт. В частности, декодер для системы команд Thumb-2 будет сложней, чем даже для современных мэйнфреймов z/Architecture, не говоря о классической Системе 360

    Усложнение управляющей логики, о чём автор почему-то не говорит, -- чуть ли не единственный пункт, где можно было бы согласиться, но и здесь не всё просто. Многие CISCи (а с 1970-х годов -- пожалуй, все или почти все) используют не чисто схемное, а микропрограммное или смешанное микропрограммно-аппаратное управление, что многократно упрощает конструкцию управляющей части процессора (память микропрограмм многократно проще и дешевле, чем управляющая логика). Впервые микропрограммы были использованы на младших и средних моделях Системы 360; старшие модели делались со схемным управлением (и были конвейерными) -- разработчики опасались, что микропрограммное управление будет медленнее. Но, как оказалось, оно может быть столь же быстрым: это зависит от особенностей микроархитектуры; поэтому, набив руку, его стали использовать и в топовых моделях. Скажем, в младших моделях (IBM System360/30 и наша ЕС-1020) АЛУ было 8-разрядным, а соответственно, простейшая 32-разрядная операция требовала для своего выполнения четыре микрокоманды только для собственно вычислений -- не говоря о всяких других потребных действиях; понятно, что это было очень медленно -- но требовало очень мало аппаратуры, почему, собственно, и использовалось. Однако, если не экономить оборудование для выборки команд и для собственно выполнения операций, разницы в скорости с машиной с чисто схемным управлением не будет, а разница в объёме аппаратуры окажется весьма значительной. Скажем, наша ЕС-1130 при заполненном конвейере выполняла простые команды регистр-регистр и регистр-память (!) за один такт, но была микропрограммной, просто вся микропрограмма для этих простых команд состояла из единственной микрокоманды (а вот выборка команды, декодирование, вычисление адресов операндов и их подготовка в ней были сделаны чисто аппаратно; микропрограмма управляла лишь ходом выполнения собственно обработки данных -- была, как я уже сказал, элементарнейшей для простейших операций, но сложной для сложных). Примерно ту же идею, только в значительно более сложном исполнении (в первую очередь, из-за суперскалярности и внеочередного исполнения) используют и современные CISC-процессоры (что у интеловских процессоров есть микрокод, наверное, все знают).

    В 1980-х RISC-микропроцессоры (подчёркиваю микро) показывали более высокую производительность над CISC-микропроцессорами за счёт того, что благодаря очень малому числу команд (первый из них насчитывал, насколько помню, всего 31 команду) и другим упрощениям его можно было сделать конвейерным, но всё равно впихнуть на один кристалл; для CISC-процессора на тот момент это было невозможно, поэтому приходилось выбирать: либо медленная микропрограммная реализация на одном кристалле, либо быстрая, но на куче микросхем (в IA-32 первым конвейерным стал 80486; в мэйнфреймах конвейерными давно уже были все модели, а некоторые -- и суперскалярными, но они достаточно долго оставались многокристальными). Однако, если рассматривать все процессоры, а не только микро, RISC по скорости первыми отнюдь не были -- но далеко не каждый может позволить себе поставить мэйнфрейм или, тем более, какой-нибудь Cray с охлаждением жидким азотом (и хорошо, если азотом). Но в 1990-х, когда количество транзисторов на кристалле значительно выросло, конвейерные CISC тоже стали однокристальными -- и догнали (а нередко и перегнали) по скорости RISC. Да и сами современные RISC, прямо скажем, зачастую мало чем отличаются от CISC: имеют сотни, а то и тысячи команд, включают ряд достаточно сложных операций и т.д. Изначальная идея RISC (напомню, у первого из них была 31 команда, и среди них не было даже умножения и деления -- они сложные) оказалась несовместима с высокой производительностью, поэтому от неё отошли; фактически единственное, что осталось -- это отсутствие команд обработки данных вида "регистр-память" или "память-память" -- вся обработка выполняется исключительно в регистрах.


    1. Fin_Debov Автор
      04.08.2025 18:12

      Большое спасибо, за пояснение и разбор моих ошибок. При чтении статей про историю CISC я, видимо, не совсем корректно понял информацию по кризису CISC 80-ых, перепутал момент по поводу использования памяти, не до конца раскрыл другие пункты, и не упомянул некоторые краеугольные проблемы CISC 80-ых годов,которые и стали причиной кризиса. Буду изучать этот вопрос подробнее, чтобы в дальнейшем избежать таких ошибок и неточностей.


    1. unreal_undead2
      04.08.2025 18:12

      Сколько места займёт подпрограмма шифрования AES на ARM или RISC-V? Ну а на мэйнфреймах z/Architecture это делается одной командой.

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


      1. SIISII
        04.08.2025 18:12

        1. Про RISC-V не знал -- по большому счёту, я с ним не знаком, хотя всё собираюсь заняться. В известных же мне типа RISCах подобные операции (шифрование, например) выполняются железными блоками, которые расположены отдельно от процессора и, по сути, выступают в роли внешних устройств, т.е. частью соответствующей архитектуры не являются. Таковы, например, многие микроконтроллеры ARM: сама система команд никаких тебе шифраций или, скажем, преобразования UTF-8 в UTF-32 или обратно не содержит.

        2. Ну и опять повторюсь, что от изначальной идеи RISC (а она -- именно что небольшое количество простых команд) отказались, считай, полностью -- она оказалась неконкурентоспособной с CISCами, как только совершенствование технологий дало возможность конвейерный (а позже и суперскалярный) CISC впихнуть на один кристалл. Так что лично для меня сейчас RISC -- это архитектура, не имеющая команд обработки данных прямо в памяти, ибо это, по сути, единственное, что нынешние RISCи отличает от нынешних CISCов, хотя и это различие, похоже, постепенно уходит (ведь, полагаю, RISC-V шифрует данные в памяти? Регистров у него не так уж много, и большой объём в них не впихнуть. Надо как-нибудь изучить сей вопрос...)


        1. unreal_undead2
          04.08.2025 18:12

          подобные операции (шифрование, например) выполняются железными блоками, которые расположены отдельно от процессора

          Да, для микроконтроллеров это логично, но в серверных чипах вполне можно выделить транзисторы на самом процессоре.

           от изначальной идеи RISC (а она -- именно что небольшое количество простых команд) 

          Всё таки изначально Паттерсон в статье выступал в основном против микрокода. И да, в те времена - когда даже FPU на чипе встречалось нечасто - ISA, отображающая только то, что реализовано в железе, получалась весьма компактной. Но если в микроархитектуру добавляются векторные регистры, специализированные блоки в ALU и т.д. - странно не предоставлять к этому архитектурный доступ на уровне ISA.

          ведь, полагаю, RISC-V шифрует данные в памяти? Регистров у него не так уж много

          Инструкции работают со скалярными или векторными регистрами, если надо обработать большой массив, нужен цикл. И да, сейчас видимые отличие CISC/RISC скорее в наличии/отстутствии аргументов в памяти в арифметических инструкциях. Хотя сейчас в ARM есть, скажем, CISC-style атомики, инкрементирующие значение в памяти одной инструкцией, в спецификации (в железе пока не видел) есть и инструкции копирования памяти по типу REP MOVS в x86.


          1. SIISII
            04.08.2025 18:12

            Инструкции работают со скалярными или векторными регистрами, если надо обработать большой массив, нужен цикл. И да, сейчас видимые отличие CISC/RISC скорее в наличии/отсутствии аргументов в памяти в арифметических инструкциях. Хотя сейчас в ARM есть, скажем, CISC-style атомики, инкрементирующие значение в памяти одной инструкцией, в спецификации (в железе пока не видел) есть и инструкции копирования памяти по типу REP MOVS в x86.

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

            В общем, похоже, от изначальных RISCов теперь не осталось ничего. Ну а микрокод высокой производительности ни разу не противоречит, как и я говорил, и всякие там Интелы на практике доказывали. Как по мне, бороться с ним не надо -- он даёт гибкость (медленная, но компактная реализация тоже может быть ценной -- а использование микропрограммного управления даёт возможность легко подстраиваться под потребности). В общем, исходить, смотря по задаче.


            1. unreal_undead2
              04.08.2025 18:12

              микрокод высокой производительности ни разу не противоречит

              Изначальный посыл RISC был в том, что реализованные в микрокоде инструкции со сложной семантикой удобны скорее человеку - компиляторы их не генерируют, а большая часть ПО пишется на языках высокого уровня - соответственно, все эти навороты с микрокодом только зря расходуют транзисторы, которые можно использовать более продуктивно.


  1. unreal_undead2
    04.08.2025 18:12

    RISC-V, в отличие от x86 и Arm, не требует спекулятивного выполнения для высокой производительности

    И что он предлагает взамен (и как тут вообще влияет ISA)? Вроде пока ничего лучше для ускорения обычного однопоточного кода не придумано.


    1. SIISII
      04.08.2025 18:12

      Мне кажется, автор просто что-то там недопонял. Недостаточное понимание видно, например, из "описания" MMU -- ведь принципиально и на ARM, и на IA-32, и почти в любых других архитектурах MMU работают одинаково -- точно так же, как ещё в Системе 370 (несколько уровней таблиц переадресации в памяти, базовый адрес таблицы верхнего уровня -- в некоем специальном регистре, а для ускорения преобразования -- TLB).


      1. Fin_Debov Автор
        04.08.2025 18:12

        Тут вы правы, я в этой теме только начинаю вариться и не сильно "прошарен")
        Этот проект - по сути, моя курсовая, которую я опубликовал на хабр, больше не с целью того, чтобы не знающие люди почерпнули для себя что-то новое в теме процессорных архитектур(хотя и не без этого),а получения критики от более матёрых в этой теме людей, чтобы более основательно погрузится в изучение вопросов архитектур и их безопасности.


        1. unreal_undead2
          04.08.2025 18:12

          Стоит тогда на Эльбрус посмотреть - там, например, разделены стеки возрата и данных. А если копнуть в историю - то ещё и на старый советский Эльбрус с аппаратным контролем типизации (подобное было и в iAPX 432).


          1. SIISII
            04.08.2025 18:12

            И всё это провалилось :)


            1. unreal_undead2
              04.08.2025 18:12

              Угу, но поучиться на ошибках предков стоит )


    1. Fin_Debov Автор
      04.08.2025 18:12

      Тут я не совсем корректно выразился. Я имел в виду, что в основе у RISC-V есть ядра, которые не поддерживают спекулятивное выполнение, что понижает производительность этих самых ядер, но делает их менее уязвимыми к Spectre-атакам, когда как у x86 и ARM все ядра имеют поддержку спекулятивного выполнения. Я здесь больше говорю не про производительность, а про уязвимость к Spectre и Meltdown.


      1. unreal_undead2
        04.08.2025 18:12

         когда как у x86 и ARM все ядра имеют поддержку спекулятивного выполнения

        По крайней мере ARM ядра c in order микроархитектурой ещё живы; насчёт x86 не уверен, но они достаточно долго были таковыми (спекулятивное выполнение появилось только в Pentium Pro) и никто не мешает сделать новое x86 in order ядро - вопрос только в рыночной востребованности, сама по себе ISA не требует какой то конкретной микроархитектуры. При этом если RISC V таки дойдёт до HPC и энтерпрайза, спекулятивное выполнение в таких чипах скорее всего будет - например, у Syntacore в ядрах начиная с SCR6 спекулятивное выполнение есть.


        1. Fin_Debov Автор
          04.08.2025 18:12

          При рассмотрении методов безопасности, в том числе про спекулятивные атаки, я брал для сравнения современные x86 и ARM, но про in order я не знал. Спасибо за дополнение, будет, что дополнительно изучить.


      1. SIISII
        04.08.2025 18:12

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

        Во-вторых, и x86, и ARM -- понятия очень сильно растяжимые. У последнего, в частности, выпускаются процессоры с ядрами, где даже простой суперскалярности нет, не говоря уже о внеочередном выполнении, а среди микроконтроллеров таких явно больше половины -- а ведь они тоже ARM.

        Ну а в-третьих, указанные уязвимости прямо не связаны с суперскалярностью и внеочередным исполнением: там очень большую роль играет стратегия использования кэша. Скажем, у мэйнфреймов любое прерывание вызывает т.н. сериализацию ("временную отмену совмещений", как её переводили в советской литературе), в результате чего, по сути, кэш очищается (все изменения, внесённые программой, выполнявшейся до прерывания, записываются в память, а все ранее выбранные данные аннулируются, заставляя в дальнейшем сначала выбирать их из памяти). Соответственно, любые данные, попавшие в кэш в результате спекулятивного выполнения, в случае прерывания будут благополучно "забыты" -- а, если мне память не изменяет, Spectre был основан именно на таком сценарии (обращение к запрещённой области с последующим прерыванием и возобновлением работы -- но чужие данные уже в кэше). Хотя, возможно, с чем-то путаю, смотрел очень давно...