rmusser01/hyperdbg

Multiprocessor support

GoogleCodeExporter opened this issue · 1 comments

Currently, HyperDbg only puts a single logical CPU into VMX mode. HyperDbg 
will still run on a machine with multiple logical processors, but not very 
well - pressing F12 to break into HyperDbg will only break 25% of the time 
on a 4 CPU box, since the keyboard I/O is only getting intercepted on one 
CPU. 

(Note: When I say processor or CPU below, I mean a logical processor, not a 
physical one. A dual-core processor with HT enabled has 4 logical 
processors).

These changes will need to be made to HyperDbg to support multiple 
processors:

1. Each CPU needs its own vmxInitState and associated memory regions (VMXON 
region, VMCS region, VMEXIT handler stack memory, I/O bitmap, IDT, etc), 
2. VMXON needs called on each processor
3. Each CPU needs its own guest context (CPU_CONTEXT) structure, and any 
function that references the context needs to be able to get the right 
context for the CPU it's running on.
4. Any global structures that can be modified by more than one processor 
will need a lock
5. The cleanup/exit code needs to take all of this into account
6. I'm sure there are other issues 

It's possible to count the logical processors and get the ID of the current 
processor in a OS-independent way with CPUID(1). Getting code to run on a 
specific processor is something that is OS-specific though - you have to 
ask the OS to run a thread on a certain processor by setting the affinity 
mask. In Windows this can be done with ZwSetInformationThread(2). 

Since a major goal of HyperDbg is to have a platform independent core, I 
don't want to muddy up vmx.c with a bunch of Windows-specific API calls 
(although it already makes calls to the Windows kernel's Mm* functions to 
allocate memory...).

With that in mind, here's what I propose:

1. Move any code that requires Windows APIs in vmx.c to a file that 
identifies it as platform-dependent, maybe "vmx-windows.c". Most of 
VmxInitialize() and VmxFinalize() will need to implemented in a platform-
dependent way. #ifdef's can be used to call the right code for the platform 
HyperDbg is built on. Anyone who wants to implement support for other OS's 
can add a vmx-linux.c or vmx-freebsd.c or whatever.
2. Add a function that can identify the current processor and get the 
correct guest context for it. This will be needed by many functions in 
vmx.c and vmhandlers.c. This should be done platform-independently.
3. Review the code to see if there are any other issues that need taken 
into account for multiple processors.

References:

(1): Intel Processor Identification and the CPUID Instruction - 
http://www.intel.com/assets/pdf/appnote/241618.pdf
(2): Processor Affinity in a driver - 
http://www.osronline.com/showThread.cfm?link=26006

Original issue reported on code.google.com by jlari...@gmail.com on 31 May 2010 at 2:17

I looked at the code some more, and I think it's better if the memory 
initialization/cleanup and thread 
affinity stuff happens in pill.c. That code is already very Windows-centric, 
and any implementation of 
a Linux driver will need a completely different entry point and cleanup code 
anyway.

So now I propose moving the generic code out of pill.c and into vmx.c (some of 
this has already been 
happening) and moving the memory allocation/freeing stuff from vmx.c and into 
pill.c.

Original comment by jlari...@gmail.com on 31 May 2010 at 9:04