CPUID: Почему MISC_ENABLE.LCMV должен быть установлен на 0 для некоторых функций? Могу ли я временно перезаписать его?

Я пытаюсь использовать CPUID, но есть некоторые ограничения. Согласно странице CPUID на sandpile.org, стандартные функции CPUID 0000_0004h и выше будут работать, только если установлен флаг MISC_ENABLE. Флаг LCMV установлен на 0. Этот флаг представляет собой бит 22 регистра модели (MSR) 1A0. По-видимому, это ограничение связано с ошибкой в ​​Windows NT (спасибо, Microsoft, что облегчили мне задачу ;)).

Я могу проверить наличие флага LCMV с CPUID 0000_0001h (флаги ecx, бит 3). Если предположить, что он присутствует, то для чего он нужен и почему он так влияет на CPUID? Является ли MSR 1A0 регистром для чтения/записи или только для чтения? Как такой специальный регистр вообще считывается/записывается с использованием ассемблерного кода?

Если регистр технически доступен для чтения/записи, безопасно ли сбросить бит 22 в 0 на время выполнения инструкции CPUID перед восстановлением исходного значения? Или я сильно облажался, если он установлен неправильно (т.е. включен)?

Наконец, sandpile использует формулировку: "Этот уровень доступен, только если для MISC_ENABLE.LCMV установлено значение 0. , Это связано с ошибкой Windows NT». Если набор стандартных уровней специально отключен по этой причине, будет ли это отражено в выводе регистра eax уровня CPUID 0000_000h (максимально поддерживаемый стандартный уровень)?

Фу... Думаю, на этом все.


person Mike S    schedule 30.08.2011    source источник


Ответы (2)


Вам потребуется загрузить Intel® 64 и Руководства разработчика программного обеспечения для архитектур IA-32, так как они содержат всю запрашиваемую информацию.

Я могу проверить наличие флага LCMV с CPUID 0000_0001h (флаги ecx, бит 3). Если предположить, что он присутствует, то для чего он нужен и почему он так влияет на CPUID?

Полное имя флага (см. Vol. 3B B-17) является "Limit CPUID MaxVal" и определяет его эффект как "Когда этот бит установлен в 1, CPUID.00H возвращает максимальное значение в EAX[7:0] равное 3".

Является ли MSR 1A0 регистром для чтения/записи или только для чтения?

Чтение/запись в соответствии с руководством Intel (с одной оговоркой, читайте дальше).

Как такой специальный регистр вообще считывается/записывается с использованием ассемблерного кода?

Вы читаете, используя RDMSR (том 2B 4-301), и пишете, используя WRMSR (том 2B 4-505), но обратите внимание, что они требуют, чтобы вы работали либо в реальном режиме, либо с уровнем привилегий 0 (он же режим ядра).

Если регистр технически доступен для чтения/записи, безопасно ли сбросить бит 22 в 0 на время выполнения инструкции CPUID перед восстановлением исходного значения? Или я сильно облажался, если он установлен неправильно (т.е. включен)?

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

Наконец, sandpile использует формулировку: «Этот уровень доступен, только если MISC_ENABLE.LCMV установлен в 0. Это связано с ошибкой Windows NT». Если набор стандартных уровней специально отключен по этой причине, будет ли это отражено в выводе регистра eax уровня CPUID 0000_000h (максимально поддерживаемый стандартный уровень)?

Да, он специально предназначен для принудительного возврата 3 в этом случае (см. описание выше).

person user786653    schedule 30.08.2011
comment
Потрясающий. Большое спасибо! Ваш ответ действительно является лучшим сценарием, потому что это означает, что бит не будет установлен в любом случае, если это действительно не нужно, например. в Windows NT. Я боялся, что это указывает на то, что некоторые (в основном ортогональные) функции процессора активированы, что не очень хорошо работает с CPUID в Windows NT. Я рад, что это не так. :) - person Mike S; 31.08.2011

У меня есть только немного, чтобы добавить к очень исчерпывающему ответу, данному выше. (Я бы добавил это в качестве комментария, но я пока не могу добавлять комментарии.) Инженер Intel предоставил еще несколько исторических подробностей по этой проблеме по адресу https://software.intel.com/en-us/forums/topic/306523?language=en#comment-1590394 Цитата оттуда с небольшими исправлениями форматирования/орфографии:

В некоторых версиях BIOS есть параметр меню, который позволяет пользователю ограничить максимальное значение (или конечный индекс), которое CPUID будет поддерживать после следующей перезагрузки. BIOS предоставил этот параметр исключительно для того, чтобы позволить конечному пользователю обойти проблему установки Microsoft Windows* NT 4.0, потому что программа установки Windows NT 4.0 содержала ошибку и отображала синий экран, если CPUID сообщал, что поддерживает листья выше. чем 3. Включение параметра BIOS для ограничения максимального значения CPUID EAX до 3 необходимо только для целей установки Windows NT 4.0. Во всех остальных случаях BIOS должен быть настроен так, чтобы не ограничивать максимальные значения CPUID EAX.

Когда CPUID ограничен тем, что он поддерживает листья выше 3, на процессоре Intel Pentium 4 и более поздних версиях лист 3 [также] не поддерживается, поэтому запрос CPUID на отчет о листе 4 будет получать данные от CPUID на листе 2 ( самый высокий листовой индекс). Когда программное обеспечение выполняет CPUID с недопустимым входным значением EAX (т. е. конечным индексом), CPUID сообщит с наивысшим конечным значением, которое оно поддерживает в текущей конфигурации времени выполнения.

Кроме того, рассматриваемый флаг MSR называется IA32_MISC_ENABLE.BOOT_NT4 [бит 22] в текущем (июнь 2014 г.) выпуске Руководства разработчика программного обеспечения для архитектур Intel® 64 и IA-32. Я подозреваю, что в какой-то момент они решили переименовать его, чтобы сделать более очевидным, что это устаревшая проблема, которую в настоящее время можно безопасно игнорировать.

person Fizz    schedule 11.07.2014