/** * Intialize the CPU struct and start VM by invoking VmxVirtualize() * requires: a valid <GuestRsp> */ NTSTATUS NTAPI HvmSubvertCpu ( PVOID GuestRsp ) { //Finish PCPU Cpu;//It will be used as the hypervisor struct. gvaddr_t HostKernelStackBase; NTSTATUS Status; gpaddr_t HostStackPA; ULONG i; Print(("HvmSubvertCpu(): Running on processor #%d\n", KeGetCurrentProcessorNumber())); // allocate memory for host stack, 16 * 4k HostKernelStackBase = MmAllocatePages(HOST_STACK_SIZE_IN_PAGES, &HostStackPA, TRUE); //HostKernelStackBase = MmAllocateContiguousPages(HOST_STACK_SIZE_IN_PAGES, &HostStackPA, TRUE); if (!HostKernelStackBase) { Print(("HvmSubvertCpu(): Failed to allocate %d pages for the host stack\n", HOST_STACK_SIZE_IN_PAGES)); return STATUS_INSUFFICIENT_RESOURCES; } // unchecked -8 or -4 ? Cpu = (PCPU) ((PCHAR) HostKernelStackBase + HOST_STACK_SIZE_IN_PAGES * PAGE_SIZE - 4 - sizeof (CPU)); Cpu->HostStack = HostKernelStackBase; // for interrupt handlers which will address CPU through the FS Cpu->SelfPointer = Cpu; Cpu->ProcessorNumber = KeGetCurrentProcessorNumber(); // Cpu->Nested = FALSE; // InitializeListHead (&Cpu->GeneralTrapsList); // InitializeListHead (&Cpu->MsrTrapsList); // InitializeListHead (&Cpu->IoTrapsList); for(i = 0; i < VMX_EXITS_NUM; i++) InitializeListHead (&Cpu->TrapsList[i]); Cpu->GdtArea = (PSEGMENT_DESCRIPTOR)MmAllocatePages (BYTES_TO_PAGES (BP_GDT_LIMIT), NULL, TRUE);//Currently we create our own GDT and IDT area if (!Cpu->GdtArea) { Print(("HvmSubvertCpu(): Failed to allocate memory for GDT\n")); return STATUS_INSUFFICIENT_RESOURCES; } Cpu->IdtArea = MmAllocatePages (BYTES_TO_PAGES (BP_IDT_LIMIT), NULL, TRUE); if (!Cpu->IdtArea) { Print(("HvmSubvertCpu(): Failed to allocate memory for IDT\n")); return STATUS_INSUFFICIENT_RESOURCES; } Status = Hvm->ArchRegisterTraps(Cpu, arch);//<----------------3.1 Finish if (!NT_SUCCESS (Status)) { Print(("HvmSubvertCpu(): Failed to register NewBluePill traps, status 0x%08hX\n", Status)); return STATUS_UNSUCCESSFUL; } Status = Hvm->ArchInitialize (Cpu, CmSlipIntoMatrix, GuestRsp);//<----------------3.2 Finish if (!NT_SUCCESS (Status)) { Print(("HvmSubvertCpu(): ArchInitialize() failed with status 0x%08hX\n", Status)); return Status; } InterlockedIncrement (&g_uSubvertedCPUs); // no API calls allowed below this point: we have overloaded GDTR and selectors // unchecked _HvmSetupGdt (Cpu);//<----------------3.3 Finish _HvmSetupIdt (Cpu);//<----------------3.4 Finish #if DEBUG_LEVEL > 1 Print(("HvmSubvertCpu(): RFLAGS = %#x\n", RegGetRflags ())); #endif Status = Hvm->ArchVirtualize(Cpu);//<----------------3.5 Finish // never reached InterlockedDecrement (&g_uSubvertedCPUs); return Status; }
ZVMSTATUS ZVMAPI HvmSubvertCpu ( void * GuestRsp ) { // UnFinished!!!!! The most important PCPU Cpu;//It will be used as the hypervisor struct. void * HostKernelStackBase; ZVMSTATUS Status; ZION_PHYSICAL_ADDRESS HostStackPA; // allocate memory for host stack, 16 * 4k HostKernelStackBase = MmAllocPages(HOST_STACK_SIZE_IN_PAGES, (uint32_t *)&HostStackPA); if (!HostKernelStackBase) { cprintf("HvmSubvertCpu(): Failed to allocate %d pages for the host stack\n",HOST_STACK_SIZE_IN_PAGES); //return STATUS_INSUFFICIENT_RESOURCES; return -1; } // unchecked -8 or -4 ? Cpu = (PCPU) ((char *) HostKernelStackBase + HOST_STACK_SIZE_IN_PAGES * Zion_PageSize - 4 - sizeof (CPU)); Cpu->HostStack = HostKernelStackBase; // for interrupt handlers which will address CPU through the FS Cpu->SelfPointer = Cpu; Cpu->ProcessorNumber = 0; //Cpu->ProcessorNumber = KeGetCurrentProcessorNumber(); //Cpu->ProcessorNumber = NumberOfProcessors; //Cpu->Nested = FALSE; InitializeListHead (&Cpu->GeneralTrapsList); InitializeListHead (&Cpu->MsrTrapsList); // // InitializeListHead (&Cpu->IoTrapsList); Cpu->GdtArea = (PSEGMENT_DESCRIPTOR)MmAllocPages(BYTES_TO_PAGES(BP_GDT_LIMIT),NULL);//Currently we create our own GDT and IDT area if (!Cpu->GdtArea) { cprintf(("HvmSubvertCpu(): Failed to allocate memory for GDT\n")); //return STATUS_INSUFFICIENT_RESOURCES; return -1; } // Cpu->IdtArea = (PSEGMENT_DESCRIPTOR)MmAllocPages(BYTES_TO_PAGES(BP_IDT_LIMIT),NULL); if (!Cpu->IdtArea) { cprintf(("HvmSubvertCpu(): Failed to allocate memory for IDT\n")); //return STATUS_INSUFFICIENT_RESOURCES; return -1; } // Status = Hvm->ArchRegisterTraps(Cpu);//<----------------3.1 Finish ///Status = g_HvmControl->ApplyTraps(Cpu); if (!ZVM_SUCCESS(Status)) { cprintf("Helloworld:HvmSubvertCpu(): Failed to register NewBluePill traps, status 0x%08hX\n"); //return EFI_LOAD_ERROR; return -1; } // Status = Hvm->ArchInitialize (Cpu, (void *)&CmSlipIntoMatrix, GuestRsp);//<----------------3.2 Finish // Status = Hvm->ArchInitialize (Cpu, (PVOID) (UINTN)CmSlipIntoMatrix, GuestRsp); // Can't use CmSlipIntoMatrix by PVOID if (!ZVM_SUCCESS (Status)) { cprintf("Helloworld:HvmSubvertCpu(): ArchInitialize() failed with status 0x%08hX\n"); return Status; } // // no API calls allowed below this point: we have overloaded GDTR and selectors // // unchecked HvmSetupGdt (Cpu);//<----------------3.3 Finish HvmSetupIdt (Cpu);//<----------------3.4 Finish // Status = Hvm->ArchVirtualize(Cpu);//<----------------3.5 Finish cprintf("Wrong again...\n"); return Status; }