Enable VT-X on Mac Pro (Early 2008): Difference between revisions

From KVM
Line 5: Line 5:
== The problem ==
== The problem ==
It would seem that there is a special set of registers on Intel processors called the MSR (manufacturs specific register). One of these registers is used to turn on VT-X (Intels HVM tech).                       
It would seem that there is a special set of registers on Intel processors called the MSR (manufacturs specific register). One of these registers is used to turn on VT-X (Intels HVM tech).                       
The way is works is that it has 2 flags, one of which enables/disables VTX, and a lock bit, which once set prevents the VTX enable from being changed.                                                           
The way is works is that it has 2 flags, one of which enables/disables VTX, and a lock bit, which once set prevents the VTX enable from being changed.                                                           


Normally, the PC BIOS will set and lock VTX on / off according to a setting in the CMOS setup screen.
Normally, the PC BIOS will set and lock VTX on / off according to a setting in the CMOS setup screen.
Line 20: Line 20:
Linux has a driver called msr, which allows userland programs to write / read the MSR. It is loaded (in Ubuntu 8.10 at least) by                                                                                   
Linux has a driver called msr, which allows userland programs to write / read the MSR. It is loaded (in Ubuntu 8.10 at least) by                                                                                   


modprobe msr
modprobe msr
           
 
The following is some source I ([GeorgeStyles]) wrote that when compiled (gcc -o msrmagic) will create a program that will tell you the status of your MSR (on all cores), and if its unlocked and off, will attempt to turn on VTX and lock it on. It will then stay on until the machine is power-cycled.
The following is some source I ([GeorgeStyles]) wrote that when compiled (gcc -o msrmagic) will create a program that will tell you the status of your MSR (on all cores), and if its unlocked and off, will attempt to turn on VTX and lock it on. It will then stay on until the machine is power-cycled.
It seems to be OK to run this, and them immediately run KVM without a reboot. This is prefereable to the other method of getting VTX turned on, which is to boot into MacOs and run a VM such as VMWare which flips MSR on.
It seems to be OK to run this, and them immediately run KVM without a reboot. This is prefereable to the other method of getting VTX turned on, which is to boot into MacOs and run a VM such as VMWare which flips MSR on.
Line 28: Line 28:
                                                                                                          
                                                                                                          
It wont help you if the BIOS locks VTX off however
It wont help you if the BIOS locks VTX off however
Code:                                                                                                   
 
Code:                                                                                                   


  #include <sys/types.h>
  #include <sys/types.h>
Line 50: Line 51:
   {                                             
   {                                             
     printf("Device %s does not exist. Either we have run out of processors, or the msr kernel module is not loaded\n", devfile);                                                                                   
     printf("Device %s does not exist. Either we have run out of processors, or the msr kernel module is not loaded\n", devfile);                                                                                   
     return 0;                                                                                          
     return 0;
  }                                                                                                       
}                                                                                                       
                                                                                                          
                                                                                                          
   char buf[8];                                                                                          
   char buf[8];
                                                                                                          
                                                                                                          
  //  printf("Setting up cpu %d - %s\n",cpuid, devfile);                                                
  //  printf("Setting up cpu %d - %s\n",cpuid, devfile);
                                                                                                          
                                                                                                          
   lseek(fd, addr, SEEK_SET);                                                                            
   lseek(fd, addr, SEEK_SET);
   read(fd, buf, 8);                                                                                    
   read(fd, buf, 8);                                                            
                                                                                                          
                                                                                                          
   char bLo = buf[0]; // Low byte                                                                        
   char bLo = buf[0]; // Low byte
   if (bLo & 1) // locked                                                                                
   if (bLo & 1) // locked
   {                                                                                                    
   {  
     if (bLo & 4)                                                                                        
     if (bLo & 4)
       printf("cpud %d is locked ON :)\n", cpuid);                                                      
       printf("cpud %d is locked ON :)\n", cpuid);
     else                                                                                                
     else
       printf("cpud %d is locked OFF :(\n", cpuid);                                                      
       printf("cpud %d is locked OFF :(\n", cpuid);
   }                                                                                                    
   }
   else                                                                                                   
   else                                                                                                   
   {  // Unlocked - we can try and turn vtx on                                                          
   {  // Unlocked - we can try and turn vtx on
     fd = open(devfile, O_WRONLY);                                                                      
     fd = open(devfile, O_WRONLY);
     if (fd == -1)                                                                                      
     if (fd == -1)
     {                                                                                                  
     {
       printf("Failed to open device %s for writing\n", devfile);                                        
       printf("Failed to open device %s for writing\n", devfile);
     }
     }
     else
     else

Revision as of 09:47, 4 February 2009

Why?

The Mac Pro is a great home server machine - twin quad core Xeons, plenty of memory capability, and very quiet. The problem is that by default, Apple doesnt enable the intel VT-X extensions, which are needed to get KVM working.

The problem

It would seem that there is a special set of registers on Intel processors called the MSR (manufacturs specific register). One of these registers is used to turn on VT-X (Intels HVM tech). The way is works is that it has 2 flags, one of which enables/disables VTX, and a lock bit, which once set prevents the VTX enable from being changed.

Normally, the PC BIOS will set and lock VTX on / off according to a setting in the CMOS setup screen.

There are 4 situations you can be in regarding this -

1. BIOS support for VT-X, in which case VTX will be locked on / off according to a bios setting 2. BIOS locks VT-X off (ie, unsets VTX enable, sets lock bit). Nothing can be done about this :( 3. BIOS locks VT-X on - you are already OK 4. BIOS does nothing...

The Mac Pro ('s EFI BIOS) does number 4 - it neither turns VTX on, nor locks it. This means we can enable it later :)

Linux has a driver called msr, which allows userland programs to write / read the MSR. It is loaded (in Ubuntu 8.10 at least) by

modprobe msr

The following is some source I ([GeorgeStyles]) wrote that when compiled (gcc -o msrmagic) will create a program that will tell you the status of your MSR (on all cores), and if its unlocked and off, will attempt to turn on VTX and lock it on. It will then stay on until the machine is power-cycled. It seems to be OK to run this, and them immediately run KVM without a reboot. This is prefereable to the other method of getting VTX turned on, which is to boot into MacOs and run a VM such as VMWare which flips MSR on.

This will probably work on other Intel based machines that have VTX capability in the CPU / Chipset, but no BIOS support.

It wont help you if the BIOS locks VTX off however

Code:

#include <sys/types.h>
#include <sys/stat.h> 
#include <fcntl.h>    
                      
#include <unistd.h>   
#include <stdio.h>    
                      
/* Returns 1 if processor found, 0 otherwise */
                                               
int setupCpu(int cpuid)                        
{                                              
 int addr = 0x3a; // VTX enable                
                                               
 char devfile[255];                            
 sprintf(devfile, "/dev/cpu/%d/msr", cpuid);   
                                               
 int fd = open(devfile, O_RDONLY);             
 if (fd==-1)                                   
 {                                             
   printf("Device %s does not exist. Either we have run out of processors, or the msr kernel module is not loaded\n", devfile);                                                                                  
   return 0;

}

 char buf[8];
                                                                                                        
//  printf("Setting up cpu %d - %s\n",cpuid, devfile);
                                                                                                        
 lseek(fd, addr, SEEK_SET);
 read(fd, buf, 8);                                                             
                                                                                                        
 char bLo = buf[0]; // Low byte
 if (bLo & 1) // locked
 { 
   if (bLo & 4)
     printf("cpud %d is locked ON :)\n", cpuid);
   else
     printf("cpud %d is locked OFF :(\n", cpuid);
 }
 else                                                                                                   
 {  // Unlocked - we can try and turn vtx on
   fd = open(devfile, O_WRONLY);
   if (fd == -1)
   {
     printf("Failed to open device %s for writing\n", devfile);
   }
   else
   {
     buf[0] = buf[0] | 5; // On + lock
     lseek(fd, addr, SEEK_SET);
     if (write(fd, buf, 8) < 0)
     {
       printf("Failed to write to device %s\n", devfile);
     }
     else
     {
       printf("cpu %d - Switched VT-X on :)\n", cpuid);
     }
   }
 }
 return 1;
}
int main(int argc, char *argv[])
{
 printf("MSR Magic 1.0 (C) 2009 George Styles www.georgestyles.co.uk\n\n");
 int iCpu = 0;
 while (setupCpu(iCpu) != 0)
 {
   iCpu++;
 }
 return 0;
}