Почему эта инструкция mov gs вызывает ошибку в гостевой системе VMWare Workstation под управлением ОС Windows 7? - PullRequest
0 голосов
/ 29 июня 2018

Когда я запускаю следующую последовательность сборки в режиме ядра Windows 7 x64 на виртуальной машине VMWare Workstation:

xor eax, eax
mov ax, gs
mov gs, ax     ; this instruction

enter image description here

эта последняя инструкция mov gs, ax немедленно вызывает сбой (или, возможно, проверку на ошибку) виртуальной машины со следующим всплывающим сообщением:

enter image description here

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

Повторная загрузка gs, регистрирующаяся как таковая, вызывает проблему в ядре, или это проблема виртуализации?

Я не вижу ничего необычного в этой инструкции mov в руководстве Intel.

PS. Кстати, замена gs регистра на fs не вызывает эту ошибку.


Редактировать: Ответить на вопрос о состоянии дескриптора сегмента в GDT. Вот оно:

0: kd> r gs
gs=002b
0: kd> dg 28
                                                    P Si Gr Pr Lo
Sel        Base              Limit          Type    l ze an es ng Flags
---- ----------------- ----------------- ---------- - -- -- -- -- --------
0028 00000000`00000000 00000000`ffffffff Data RW Ac 3 Bg Pg P  Nl 00000cf3

1 Ответ

0 голосов
/ 29 июня 2018

Я не уверен, почему перемещение mov gs,ax вызвало бы немедленную тройную ошибку Windows, но вскоре произойдет сбой. В 64-битном ядре Windows сегмент GS используется в качестве указателя для доступа к текущему процессору Область управления процессором (PCR). Каждый ЦП имеет свое базовое значение GS, указывающее на свою PCR Ваша последовательность mov ax,gs mov gs,ax фактически нарушает это, потому что загружает неверное значение для базы GS в кэш дескриптора.

GDT на самом деле не содержит правильную базу для регистра GS. Поскольку GDT может хранить только 32-битные адреса, он фактически не используется для загрузки базы GS. Вместо этого используются MSR IA32_GS_BASE и IA32_KERNEL_GS_BASE, последние в сочетании с инструкцией SWAPGS, для установки 64-битного базового адреса для сегмента GS. Значение селектора, хранящееся в регистре GS, является просто фиктивным значением.

Таким образом, ваша инструкция mov gs,ax загружает фиктивное 32-битное базовое значение, хранящееся в GDT, а не 64-битное значение, хранящееся в IA32_GS_BASE. Это означает, что базовый адрес сегмента GS установлен на 0, а не на адрес PCR для текущего CPU. После загрузки этой некорректной базы GS это лишь вопрос времени, когда ядро ​​Windows попытается использовать регистр GS для доступа к PCR (с инструкцией, подобной mov rax, gs:[10]) и в конечном итоге прочитает, что, вероятно, не отображено в памяти, вызывая неожиданную ошибку страницы ядра. и сбой.

...