Как разрешить регистры MSR в Virtual Box

MSR ( model specific register ) — регистры процессора специфичные для данного типа процессора.

Virtual Box — программное обеспечение для виртуализации.

Virtual Box 4.0.4 и более ранние версии игнорируют большинство регистров MSR. Хотя мог бы разрешать доступ к регистрам хостовой системы. Однако, процессоров много и каждый имеет свой собственный набор регистров MSR и потому проще запретить все, что не относится к стандартному набору, так безопаснее.

Иногда  хочется запустить в виртуальной машине и отладить что-нибудь, что работает с MSR. При этом, например, известно какие регистры нужно использовать и насколько безопасно их использовать из виртуальной машины. Если бы нужно было бы использовать VMWare, то с мыслю этой пришлось бы попрощаться( если конечно не мил подход реверсить-патчить-реверсить-патчить). Но, к счастью, Virtual Box предоставляется с исходниками. Правда только Virtual Box OSE. Не беда, будем использовать его. А именно две версии: 3.2.8 ( стандартный для Ununtu 10.10 ) и 4.0.4 ( последняя версия на момент написание текста ). Сразу же предупрежу: НЕ ПЫТАЙТЕСЬ СОБРАТЬ VIRTUAL BOX НА WINDOWS. Я потратил на это неблагодарное дело 4 дня и не добился результатов. Попробовал в Linux — сразу же все получилось. На Windows пытался качать, устанавливать миллион зависимостей, пока не наткнулся на ветку форума, где в итоге было сказано  «мы используем свои внутренние тулзы для сборки дистрибутивов для Windows. Мило …

Так вот, под Linux все просто. Делаем все по инструкции. Пробовал для i386 и x64. Продукт собирается и запускается.

Перейдем теперь непосредственно к тому, что патчить. Путем простых умозаключений стало понятно, что если что-то править то в файле src/VBox/VMM/VMMR0/HWVMXR0.cpp. Путь у него и имя говорящие. Номера регистров для вашего процессора можно найти в мануле от  «Intel® 64 and IA-32 Architectures Software Developer’s Manual Volume 3B: System Programming Guide, Part 2«. Для моего i3 я получил значения, общие для всего семейства i7

#define MSR_LASTBRANCH_TOS 0x1c9
#define MSR_LASTBRANCH_0_FROM_IP 0x680
#define MSR_LASTBRANCH_1_FROM_IP 0x681
#define MSR_LASTBRANCH_2_FROM_IP 0x682
#define MSR_LASTBRANCH_3_FROM_IP 0x683
#define MSR_LASTBRANCH_4_FROM_IP 0x684
#define MSR_LASTBRANCH_5_FROM_IP 0x685
#define MSR_LASTBRANCH_6_FROM_IP 0x686
#define MSR_LASTBRANCH_7_FROM_IP 0x687
#define MSR_LASTBRANCH_8_FROM_IP 0x688
#define MSR_LASTBRANCH_9_FROM_IP 0x689
#define MSR_LASTBRANCH_10_FROM_IP 0x68a
#define MSR_LASTBRANCH_11_FROM_IP 0x68b
#define MSR_LASTBRANCH_12_FROM_IP 0x68c
#define MSR_LASTBRANCH_13_FROM_IP 0x68d
#define MSR_LASTBRANCH_14_FROM_IP 0x68e
#define MSR_LASTBRANCH_15_FROM_IP 0x68f

#define MSR_LASTBRANCH_0_TO_IP 0x6c0
#define MSR_LASTBRANCH_1_TO_IP 0x6c1
#define MSR_LASTBRANCH_2_TO_IP 0x6c2
#define MSR_LASTBRANCH_3_TO_IP 0x6c3
#define MSR_LASTBRANCH_4_TO_IP 0x6c4
#define MSR_LASTBRANCH_5_TO_IP 0x6c5
#define MSR_LASTBRANCH_6_TO_IP 0x6c6
#define MSR_LASTBRANCH_7_TO_IP 0x6c7
#define MSR_LASTBRANCH_8_TO_IP 0x6c8
#define MSR_LASTBRANCH_9_TO_IP 0x6c9
#define MSR_LASTBRANCH_10_TO_IP 0x6ca
#define MSR_LASTBRANCH_11_TO_IP 0x6cb
#define MSR_LASTBRANCH_12_TO_IP 0x6cc
#define MSR_LASTBRANCH_13_TO_IP 0x6cd
#define MSR_LASTBRANCH_14_TO_IP 0x6ce
#define MSR_LASTBRANCH_15_TO_IP 0x6cf

Вставить дефайны можно где-нибудь в обозначенном файле. Номера регистров есть. Теперь нужно дать указание Virtual Box «прокидывать» их в хост.

 

/* Nehalem family DEBUG MSRs */
vmxR0SetMSRPermission(pVCpu, MSR_IA32_DEBUGCTL, true, true);

vmxR0SetMSRPermission(pVCpu, MSR_LASTBRANCH_TOS, true, false);

vmxR0SetMSRPermission(pVCpu, MSR_LASTBRANCH_0_FROM_IP, true, false);
vmxR0SetMSRPermission(pVCpu, MSR_LASTBRANCH_1_FROM_IP, true, false);
vmxR0SetMSRPermission(pVCpu, MSR_LASTBRANCH_2_FROM_IP, true, false);
vmxR0SetMSRPermission(pVCpu, MSR_LASTBRANCH_3_FROM_IP, true, false);
vmxR0SetMSRPermission(pVCpu, MSR_LASTBRANCH_4_FROM_IP, true, false);
vmxR0SetMSRPermission(pVCpu, MSR_LASTBRANCH_5_FROM_IP, true, false);
vmxR0SetMSRPermission(pVCpu, MSR_LASTBRANCH_6_FROM_IP, true, false);
vmxR0SetMSRPermission(pVCpu, MSR_LASTBRANCH_7_FROM_IP, true, false);
vmxR0SetMSRPermission(pVCpu, MSR_LASTBRANCH_8_FROM_IP, true, false);
vmxR0SetMSRPermission(pVCpu, MSR_LASTBRANCH_9_FROM_IP, true, false);
vmxR0SetMSRPermission(pVCpu, MSR_LASTBRANCH_10_FROM_IP, true, false);
vmxR0SetMSRPermission(pVCpu, MSR_LASTBRANCH_11_FROM_IP, true, false);
vmxR0SetMSRPermission(pVCpu, MSR_LASTBRANCH_12_FROM_IP, true, false);
vmxR0SetMSRPermission(pVCpu, MSR_LASTBRANCH_13_FROM_IP, true, false);
vmxR0SetMSRPermission(pVCpu, MSR_LASTBRANCH_14_FROM_IP, true, false);
vmxR0SetMSRPermission(pVCpu, MSR_LASTBRANCH_15_FROM_IP, true, false);

vmxR0SetMSRPermission(pVCpu, MSR_LASTBRANCH_0_TO_IP, true, false);
vmxR0SetMSRPermission(pVCpu, MSR_LASTBRANCH_1_TO_IP, true, false);
vmxR0SetMSRPermission(pVCpu, MSR_LASTBRANCH_2_TO_IP, true, false);
vmxR0SetMSRPermission(pVCpu, MSR_LASTBRANCH_3_TO_IP, true, false);
vmxR0SetMSRPermission(pVCpu, MSR_LASTBRANCH_4_TO_IP, true, false);
vmxR0SetMSRPermission(pVCpu, MSR_LASTBRANCH_5_TO_IP, true, false);
vmxR0SetMSRPermission(pVCpu, MSR_LASTBRANCH_6_TO_IP, true, false);
vmxR0SetMSRPermission(pVCpu, MSR_LASTBRANCH_7_TO_IP, true, false);
vmxR0SetMSRPermission(pVCpu, MSR_LASTBRANCH_8_TO_IP, true, false);
vmxR0SetMSRPermission(pVCpu, MSR_LASTBRANCH_9_TO_IP, true, false);
vmxR0SetMSRPermission(pVCpu, MSR_LASTBRANCH_10_TO_IP, true, false);
vmxR0SetMSRPermission(pVCpu, MSR_LASTBRANCH_11_TO_IP, true, false);
vmxR0SetMSRPermission(pVCpu, MSR_LASTBRANCH_12_TO_IP, true, false);
vmxR0SetMSRPermission(pVCpu, MSR_LASTBRANCH_13_TO_IP, true, false);
vmxR0SetMSRPermission(pVCpu, MSR_LASTBRANCH_14_TO_IP, true, false);
vmxR0SetMSRPermission(pVCpu, MSR_LASTBRANCH_15_TO_IP, true, false);

Параметры «true, false» означают доступ для чтения, если нужна запись, то добавляем «true, true». Вставляем их в группу подобных вызовов.
Теперь можно пересобрать, перезагрузить драйвера и все должно работать.

Что бы упросить задачу выкладываю патчи для virtual box 3.2.8 и virtual box 4.0.4. Качаем их в папку с исходниками и выполняем: patch -p1 < virtualbox-ose_3.2.8-dfsg-enable-MSR-i7.diff или patch -p1 < VirtualBox-4.0.4_OSE-enable-MSR-i7.diff.