Changeset 71087 in vbox for trunk/src/VBox/VMM/VMMR0
- Timestamp:
- Feb 21, 2018 4:35:23 PM (7 years ago)
- svn:sync-xref-src-repo-rev:
- 120951
- Location:
- trunk/src/VBox/VMM/VMMR0
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR0/NEMR0Native-win.cpp
r71075 r71087 50 50 * Global Variables * 51 51 *********************************************************************************************************************************/ 52 static uint64_t (* g_pfnHvlInvokeHypercall)(uint64_t uCallInfo, uint64_t GCPhysInput, uint64_t GCPhysOutput);52 static uint64_t (* g_pfnHvlInvokeHypercall)(uint64_t uCallInfo, uint64_t HCPhysInput, uint64_t HCPhysOutput); 53 53 54 54 … … 327 327 328 328 329 /** 330 * Worker for NEMR0ExportState. 331 * 332 * Intention is to use it internally later. 333 * 334 * @returns VBox status code. 335 * @param pGVM The ring-0 VM handle. 336 * @param pGVCpu The irng-0 VCPU handle. 337 * @param pCtx The CPU context structure to import into. 338 * @param fWhat What to export. To be defined, UINT64_MAX for now. 339 */ 340 static int nemR0WinExportState(PGVM pGVM, PGVMCPU pGVCpu, PCPUMCTX pCtx, uint64_t fWhat) 341 { 342 PVMCPU pVCpu = &pGVM->pVM->aCpus[pGVCpu->idCpu]; 343 HV_INPUT_SET_VP_REGISTERS *pInput = (HV_INPUT_SET_VP_REGISTERS *)pGVCpu->nem.s.pbHypercallData; 344 AssertPtrReturn(pInput, VERR_INTERNAL_ERROR_3); 345 346 pInput->PartitionId = pGVM->nem.s.idHvPartition; 347 pInput->VpIndex = pGVCpu->idCpu; 348 pInput->RsvdZ = 0; 349 350 RT_NOREF_PV(fWhat); /** @todo group selection. */ 351 352 /* GPRs */ 353 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[0]); 354 pInput->Elements[0].Name = HvX64RegisterRax; 355 pInput->Elements[0].Value.Reg64 = pCtx->rax; 356 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[1]); 357 pInput->Elements[1].Name = HvX64RegisterRcx; 358 pInput->Elements[1].Value.Reg64 = pCtx->rcx; 359 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[2]); 360 pInput->Elements[2].Name = HvX64RegisterRdx; 361 pInput->Elements[2].Value.Reg64 = pCtx->rdx; 362 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[3]); 363 pInput->Elements[3].Name = HvX64RegisterRbx; 364 pInput->Elements[3].Value.Reg64 = pCtx->rbx; 365 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[4]); 366 pInput->Elements[4].Name = HvX64RegisterRsp; 367 pInput->Elements[4].Value.Reg64 = pCtx->rsp; 368 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[5]); 369 pInput->Elements[5].Name = HvX64RegisterRbp; 370 pInput->Elements[5].Value.Reg64 = pCtx->rbp; 371 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[6]); 372 pInput->Elements[6].Name = HvX64RegisterRsi; 373 pInput->Elements[6].Value.Reg64 = pCtx->rsi; 374 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[7]); 375 pInput->Elements[7].Name = HvX64RegisterRdi; 376 pInput->Elements[7].Value.Reg64 = pCtx->rdi; 377 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[8]); 378 pInput->Elements[8].Name = HvX64RegisterR8; 379 pInput->Elements[8].Value.Reg64 = pCtx->r8; 380 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[9]); 381 pInput->Elements[9].Name = HvX64RegisterR9; 382 pInput->Elements[9].Value.Reg64 = pCtx->r9; 383 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[10]); 384 pInput->Elements[10].Name = HvX64RegisterR10; 385 pInput->Elements[10].Value.Reg64 = pCtx->r10; 386 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[11]); 387 pInput->Elements[11].Name = HvX64RegisterR11; 388 pInput->Elements[11].Value.Reg64 = pCtx->r11; 389 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[12]); 390 pInput->Elements[12].Name = HvX64RegisterR12; 391 pInput->Elements[12].Value.Reg64 = pCtx->r12; 392 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[13]); 393 pInput->Elements[13].Name = HvX64RegisterR13; 394 pInput->Elements[13].Value.Reg64 = pCtx->r13; 395 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[14]); 396 pInput->Elements[14].Name = HvX64RegisterR14; 397 pInput->Elements[14].Value.Reg64 = pCtx->r14; 398 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[15]); 399 pInput->Elements[15].Name = HvX64RegisterR15; 400 pInput->Elements[15].Value.Reg64 = pCtx->r15; 401 402 /* RIP & Flags */ 403 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[16]); 404 pInput->Elements[16].Name = HvX64RegisterRip; 405 pInput->Elements[16].Value.Reg64 = pCtx->rip; 406 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[17]); 407 pInput->Elements[17].Name = HvX64RegisterRflags; 408 pInput->Elements[17].Value.Reg64 = pCtx->rflags.u; 409 410 /* Segments */ 411 #define COPY_OUT_SEG(a_idx, a_enmName, a_SReg) \ 412 do { \ 413 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[a_idx]); \ 414 pInput->Elements[a_idx].Name = a_enmName; \ 415 pInput->Elements[a_idx].Value.Segment.Base = (a_SReg).u64Base; \ 416 pInput->Elements[a_idx].Value.Segment.Limit = (a_SReg).u32Limit; \ 417 pInput->Elements[a_idx].Value.Segment.Selector = (a_SReg).Sel; \ 418 pInput->Elements[a_idx].Value.Segment.Attributes = (a_SReg).Attr.u; \ 419 } while (0) 420 COPY_OUT_SEG(18, HvX64RegisterEs, pCtx->es); 421 COPY_OUT_SEG(19, HvX64RegisterCs, pCtx->cs); 422 COPY_OUT_SEG(20, HvX64RegisterSs, pCtx->ss); 423 COPY_OUT_SEG(21, HvX64RegisterDs, pCtx->ds); 424 COPY_OUT_SEG(22, HvX64RegisterFs, pCtx->fs); 425 COPY_OUT_SEG(23, HvX64RegisterGs, pCtx->gs); 426 COPY_OUT_SEG(24, HvX64RegisterLdtr, pCtx->ldtr); 427 COPY_OUT_SEG(25, HvX64RegisterTr, pCtx->tr); 428 429 uintptr_t iReg = 26; 430 /* Descriptor tables. */ 431 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 432 pInput->Elements[iReg].Value.Table.Pad[0] = 0; 433 pInput->Elements[iReg].Value.Table.Pad[1] = 0; 434 pInput->Elements[iReg].Value.Table.Pad[2] = 0; 435 pInput->Elements[iReg].Name = HvX64RegisterIdtr; 436 pInput->Elements[iReg].Value.Table.Limit = pCtx->idtr.cbIdt; 437 pInput->Elements[iReg].Value.Table.Base = pCtx->idtr.pIdt; 438 iReg++; 439 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 440 pInput->Elements[iReg].Value.Table.Pad[0] = 0; 441 pInput->Elements[iReg].Value.Table.Pad[1] = 0; 442 pInput->Elements[iReg].Value.Table.Pad[2] = 0; 443 pInput->Elements[iReg].Name = HvX64RegisterGdtr; 444 pInput->Elements[iReg].Value.Table.Limit = pCtx->gdtr.cbGdt; 445 pInput->Elements[iReg].Value.Table.Base = pCtx->gdtr.pGdt; 446 iReg++; 447 448 /* Control registers. */ 449 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 450 pInput->Elements[iReg].Name = HvX64RegisterCr0; 451 pInput->Elements[iReg].Value.Reg64 = pCtx->cr0; 452 iReg++; 453 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 454 pInput->Elements[iReg].Name = HvX64RegisterCr2; 455 pInput->Elements[iReg].Value.Reg64 = pCtx->cr2; 456 iReg++; 457 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 458 pInput->Elements[iReg].Name = HvX64RegisterCr3; 459 pInput->Elements[iReg].Value.Reg64 = pCtx->cr3; 460 iReg++; 461 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 462 pInput->Elements[iReg].Name = HvX64RegisterCr4; 463 pInput->Elements[iReg].Value.Reg64 = pCtx->cr4; 464 iReg++; 465 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 466 pInput->Elements[iReg].Name = HvX64RegisterCr8; 467 pInput->Elements[iReg].Value.Reg64 = CPUMGetGuestCR8(pVCpu); 468 iReg++; 469 470 /* Debug registers. */ 471 /** @todo fixme. Figure out what the hyper-v version of KVM_SET_GUEST_DEBUG would be. */ 472 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 473 pInput->Elements[iReg].Name = HvX64RegisterDr0; 474 //pInput->Elements[iReg].Value.Reg64 = CPUMGetHyperDR0(pVCpu); 475 pInput->Elements[iReg].Value.Reg64 = pCtx->dr[0]; 476 iReg++; 477 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 478 pInput->Elements[iReg].Name = HvX64RegisterDr1; 479 //pInput->Elements[iReg].Value.Reg64 = CPUMGetHyperDR1(pVCpu); 480 pInput->Elements[iReg].Value.Reg64 = pCtx->dr[1]; 481 iReg++; 482 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 483 pInput->Elements[iReg].Name = HvX64RegisterDr2; 484 //pInput->Elements[iReg].Value.Reg64 = CPUMGetHyperDR2(pVCpu); 485 pInput->Elements[iReg].Value.Reg64 = pCtx->dr[2]; 486 iReg++; 487 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 488 pInput->Elements[iReg].Name = HvX64RegisterDr3; 489 //pInput->Elements[iReg].Value.Reg64 = CPUMGetHyperDR3(pVCpu); 490 pInput->Elements[iReg].Value.Reg64 = pCtx->dr[3]; 491 iReg++; 492 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 493 pInput->Elements[iReg].Name = HvX64RegisterDr6; 494 //pInput->Elements[iReg].Value.Reg64 = CPUMGetHyperDR6(pVCpu); 495 pInput->Elements[iReg].Value.Reg64 = pCtx->dr[6]; 496 iReg++; 497 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 498 pInput->Elements[iReg].Name = HvX64RegisterDr7; 499 //pInput->Elements[iReg].Value.Reg64 = CPUMGetHyperDR7(pVCpu); 500 pInput->Elements[iReg].Value.Reg64 = pCtx->dr[7]; 501 iReg++; 502 503 /* Vector state. */ 504 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 505 pInput->Elements[iReg].Name = HvX64RegisterXmm0; 506 pInput->Elements[iReg].Value.Reg128.Low64 = pCtx->pXStateR0->x87.aXMM[0].uXmm.s.Lo; 507 pInput->Elements[iReg].Value.Reg128.High64 = pCtx->pXStateR0->x87.aXMM[0].uXmm.s.Hi; 508 iReg++; 509 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 510 pInput->Elements[iReg].Name = HvX64RegisterXmm1; 511 pInput->Elements[iReg].Value.Reg128.Low64 = pCtx->pXStateR0->x87.aXMM[1].uXmm.s.Lo; 512 pInput->Elements[iReg].Value.Reg128.High64 = pCtx->pXStateR0->x87.aXMM[1].uXmm.s.Hi; 513 iReg++; 514 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 515 pInput->Elements[iReg].Name = HvX64RegisterXmm2; 516 pInput->Elements[iReg].Value.Reg128.Low64 = pCtx->pXStateR0->x87.aXMM[2].uXmm.s.Lo; 517 pInput->Elements[iReg].Value.Reg128.High64 = pCtx->pXStateR0->x87.aXMM[2].uXmm.s.Hi; 518 iReg++; 519 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 520 pInput->Elements[iReg].Name = HvX64RegisterXmm3; 521 pInput->Elements[iReg].Value.Reg128.Low64 = pCtx->pXStateR0->x87.aXMM[3].uXmm.s.Lo; 522 pInput->Elements[iReg].Value.Reg128.High64 = pCtx->pXStateR0->x87.aXMM[3].uXmm.s.Hi; 523 iReg++; 524 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 525 pInput->Elements[iReg].Name = HvX64RegisterXmm4; 526 pInput->Elements[iReg].Value.Reg128.Low64 = pCtx->pXStateR0->x87.aXMM[4].uXmm.s.Lo; 527 pInput->Elements[iReg].Value.Reg128.High64 = pCtx->pXStateR0->x87.aXMM[4].uXmm.s.Hi; 528 iReg++; 529 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 530 pInput->Elements[iReg].Name = HvX64RegisterXmm5; 531 pInput->Elements[iReg].Value.Reg128.Low64 = pCtx->pXStateR0->x87.aXMM[5].uXmm.s.Lo; 532 pInput->Elements[iReg].Value.Reg128.High64 = pCtx->pXStateR0->x87.aXMM[5].uXmm.s.Hi; 533 iReg++; 534 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 535 pInput->Elements[iReg].Name = HvX64RegisterXmm6; 536 pInput->Elements[iReg].Value.Reg128.Low64 = pCtx->pXStateR0->x87.aXMM[6].uXmm.s.Lo; 537 pInput->Elements[iReg].Value.Reg128.High64 = pCtx->pXStateR0->x87.aXMM[6].uXmm.s.Hi; 538 iReg++; 539 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 540 pInput->Elements[iReg].Name = HvX64RegisterXmm7; 541 pInput->Elements[iReg].Value.Reg128.Low64 = pCtx->pXStateR0->x87.aXMM[7].uXmm.s.Lo; 542 pInput->Elements[iReg].Value.Reg128.High64 = pCtx->pXStateR0->x87.aXMM[7].uXmm.s.Hi; 543 iReg++; 544 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 545 pInput->Elements[iReg].Name = HvX64RegisterXmm8; 546 pInput->Elements[iReg].Value.Reg128.Low64 = pCtx->pXStateR0->x87.aXMM[8].uXmm.s.Lo; 547 pInput->Elements[iReg].Value.Reg128.High64 = pCtx->pXStateR0->x87.aXMM[8].uXmm.s.Hi; 548 iReg++; 549 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 550 pInput->Elements[iReg].Name = HvX64RegisterXmm9; 551 pInput->Elements[iReg].Value.Reg128.Low64 = pCtx->pXStateR0->x87.aXMM[9].uXmm.s.Lo; 552 pInput->Elements[iReg].Value.Reg128.High64 = pCtx->pXStateR0->x87.aXMM[9].uXmm.s.Hi; 553 iReg++; 554 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 555 pInput->Elements[iReg].Name = HvX64RegisterXmm10; 556 pInput->Elements[iReg].Value.Reg128.Low64 = pCtx->pXStateR0->x87.aXMM[10].uXmm.s.Lo; 557 pInput->Elements[iReg].Value.Reg128.High64 = pCtx->pXStateR0->x87.aXMM[10].uXmm.s.Hi; 558 iReg++; 559 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 560 pInput->Elements[iReg].Name = HvX64RegisterXmm11; 561 pInput->Elements[iReg].Value.Reg128.Low64 = pCtx->pXStateR0->x87.aXMM[11].uXmm.s.Lo; 562 pInput->Elements[iReg].Value.Reg128.High64 = pCtx->pXStateR0->x87.aXMM[11].uXmm.s.Hi; 563 iReg++; 564 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 565 pInput->Elements[iReg].Name = HvX64RegisterXmm12; 566 pInput->Elements[iReg].Value.Reg128.Low64 = pCtx->pXStateR0->x87.aXMM[12].uXmm.s.Lo; 567 pInput->Elements[iReg].Value.Reg128.High64 = pCtx->pXStateR0->x87.aXMM[12].uXmm.s.Hi; 568 iReg++; 569 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 570 pInput->Elements[iReg].Name = HvX64RegisterXmm13; 571 pInput->Elements[iReg].Value.Reg128.Low64 = pCtx->pXStateR0->x87.aXMM[13].uXmm.s.Lo; 572 pInput->Elements[iReg].Value.Reg128.High64 = pCtx->pXStateR0->x87.aXMM[13].uXmm.s.Hi; 573 iReg++; 574 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 575 pInput->Elements[iReg].Name = HvX64RegisterXmm14; 576 pInput->Elements[iReg].Value.Reg128.Low64 = pCtx->pXStateR0->x87.aXMM[14].uXmm.s.Lo; 577 pInput->Elements[iReg].Value.Reg128.High64 = pCtx->pXStateR0->x87.aXMM[14].uXmm.s.Hi; 578 iReg++; 579 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 580 pInput->Elements[iReg].Name = HvX64RegisterXmm15; 581 pInput->Elements[iReg].Value.Reg128.Low64 = pCtx->pXStateR0->x87.aXMM[15].uXmm.s.Lo; 582 pInput->Elements[iReg].Value.Reg128.High64 = pCtx->pXStateR0->x87.aXMM[15].uXmm.s.Hi; 583 iReg++; 584 585 /* Floating point state. */ 586 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 587 pInput->Elements[iReg].Name = HvX64RegisterFpMmx0; 588 pInput->Elements[iReg].Value.Fp.AsUINT128.Low64 = pCtx->pXStateR0->x87.aRegs[0].au64[0]; 589 pInput->Elements[iReg].Value.Fp.AsUINT128.High64 = pCtx->pXStateR0->x87.aRegs[0].au64[1]; 590 iReg++; 591 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 592 pInput->Elements[iReg].Name = HvX64RegisterFpMmx1; 593 pInput->Elements[iReg].Value.Fp.AsUINT128.Low64 = pCtx->pXStateR0->x87.aRegs[1].au64[0]; 594 pInput->Elements[iReg].Value.Fp.AsUINT128.High64 = pCtx->pXStateR0->x87.aRegs[1].au64[1]; 595 iReg++; 596 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 597 pInput->Elements[iReg].Name = HvX64RegisterFpMmx2; 598 pInput->Elements[iReg].Value.Fp.AsUINT128.Low64 = pCtx->pXStateR0->x87.aRegs[2].au64[0]; 599 pInput->Elements[iReg].Value.Fp.AsUINT128.High64 = pCtx->pXStateR0->x87.aRegs[2].au64[1]; 600 iReg++; 601 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 602 pInput->Elements[iReg].Name = HvX64RegisterFpMmx3; 603 pInput->Elements[iReg].Value.Fp.AsUINT128.Low64 = pCtx->pXStateR0->x87.aRegs[3].au64[0]; 604 pInput->Elements[iReg].Value.Fp.AsUINT128.High64 = pCtx->pXStateR0->x87.aRegs[3].au64[1]; 605 iReg++; 606 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 607 pInput->Elements[iReg].Name = HvX64RegisterFpMmx4; 608 pInput->Elements[iReg].Value.Fp.AsUINT128.Low64 = pCtx->pXStateR0->x87.aRegs[4].au64[0]; 609 pInput->Elements[iReg].Value.Fp.AsUINT128.High64 = pCtx->pXStateR0->x87.aRegs[4].au64[1]; 610 iReg++; 611 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 612 pInput->Elements[iReg].Name = HvX64RegisterFpMmx5; 613 pInput->Elements[iReg].Value.Fp.AsUINT128.Low64 = pCtx->pXStateR0->x87.aRegs[5].au64[0]; 614 pInput->Elements[iReg].Value.Fp.AsUINT128.High64 = pCtx->pXStateR0->x87.aRegs[5].au64[1]; 615 iReg++; 616 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 617 pInput->Elements[iReg].Name = HvX64RegisterFpMmx6; 618 pInput->Elements[iReg].Value.Fp.AsUINT128.Low64 = pCtx->pXStateR0->x87.aRegs[6].au64[0]; 619 pInput->Elements[iReg].Value.Fp.AsUINT128.High64 = pCtx->pXStateR0->x87.aRegs[6].au64[1]; 620 iReg++; 621 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 622 pInput->Elements[iReg].Name = HvX64RegisterFpMmx7; 623 pInput->Elements[iReg].Value.Fp.AsUINT128.Low64 = pCtx->pXStateR0->x87.aRegs[7].au64[0]; 624 pInput->Elements[iReg].Value.Fp.AsUINT128.High64 = pCtx->pXStateR0->x87.aRegs[7].au64[1]; 625 iReg++; 626 627 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 628 pInput->Elements[iReg].Name = HvX64RegisterFpControlStatus; 629 pInput->Elements[iReg].Value.FpControlStatus.FpControl = pCtx->pXStateR0->x87.FCW; 630 pInput->Elements[iReg].Value.FpControlStatus.FpStatus = pCtx->pXStateR0->x87.FSW; 631 pInput->Elements[iReg].Value.FpControlStatus.FpTag = pCtx->pXStateR0->x87.FTW; 632 pInput->Elements[iReg].Value.FpControlStatus.Reserved = pCtx->pXStateR0->x87.FTW >> 8; 633 pInput->Elements[iReg].Value.FpControlStatus.LastFpOp = pCtx->pXStateR0->x87.FOP; 634 pInput->Elements[iReg].Value.FpControlStatus.LastFpRip = (pCtx->pXStateR0->x87.FPUIP) 635 | ((uint64_t)pCtx->pXStateR0->x87.CS << 32) 636 | ((uint64_t)pCtx->pXStateR0->x87.Rsrvd1 << 48); 637 iReg++; 638 639 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]); 640 pInput->Elements[iReg].Name = HvX64RegisterXmmControlStatus; 641 pInput->Elements[iReg].Value.XmmControlStatus.LastFpRdp = (pCtx->pXStateR0->x87.FPUDP) 642 | ((uint64_t)pCtx->pXStateR0->x87.DS << 32) 643 | ((uint64_t)pCtx->pXStateR0->x87.Rsrvd2 << 48); 644 pInput->Elements[iReg].Value.XmmControlStatus.XmmStatusControl = pCtx->pXStateR0->x87.MXCSR; 645 pInput->Elements[iReg].Value.XmmControlStatus.XmmStatusControlMask = pCtx->pXStateR0->x87.MXCSR_MASK; /** @todo ??? (Isn't this an output field?) */ 646 iReg++; 647 648 /* MSRs */ 649 // HvX64RegisterTsc - don't touch 650 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 651 pInput->Elements[iReg].Name = HvX64RegisterEfer; 652 pInput->Elements[iReg].Value.Reg64 = pCtx->msrEFER; 653 iReg++; 654 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 655 pInput->Elements[iReg].Name = HvX64RegisterKernelGsBase; 656 pInput->Elements[iReg].Value.Reg64 = pCtx->msrKERNELGSBASE; 657 iReg++; 658 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 659 pInput->Elements[iReg].Name = HvX64RegisterApicBase; 660 pInput->Elements[iReg].Value.Reg64 = APICGetBaseMsrNoCheck(pVCpu); 661 iReg++; 662 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 663 pInput->Elements[iReg].Name = HvX64RegisterPat; 664 pInput->Elements[iReg].Value.Reg64 = pCtx->msrPAT; 665 iReg++; 666 /// @todo HvX64RegisterSysenterCs 667 /// @todo HvX64RegisterSysenterEip 668 /// @todo HvX64RegisterSysenterEsp 669 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 670 pInput->Elements[iReg].Name = HvX64RegisterStar; 671 pInput->Elements[iReg].Value.Reg64 = pCtx->msrSTAR; 672 iReg++; 673 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 674 pInput->Elements[iReg].Name = HvX64RegisterLstar; 675 pInput->Elements[iReg].Value.Reg64 = pCtx->msrLSTAR; 676 iReg++; 677 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 678 pInput->Elements[iReg].Name = HvX64RegisterCstar; 679 pInput->Elements[iReg].Value.Reg64 = pCtx->msrCSTAR; 680 iReg++; 681 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 682 pInput->Elements[iReg].Name = HvX64RegisterSfmask; 683 pInput->Elements[iReg].Value.Reg64 = pCtx->msrSFMASK; 684 iReg++; 685 686 /* event injection (always clear it). */ 687 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 688 pInput->Elements[iReg].Name = HvRegisterPendingInterruption; 689 pInput->Elements[iReg].Value.Reg64 = 0; 690 iReg++; 691 /// @todo HvRegisterInterruptState 692 /// @todo HvRegisterPendingEvent0 693 /// @todo HvRegisterPendingEvent1 694 695 /* 696 * Set the registers. 697 */ 698 Assert((uintptr_t)&pInput->Elements[iReg] - (uintptr_t)pGVCpu->nem.s.pbHypercallData < PAGE_SIZE); /* max is 127 */ 699 700 /* 701 * Make the hypercall. 702 */ 703 uint64_t uResult = g_pfnHvlInvokeHypercall(HV_MAKE_CALL_INFO(HvCallSetVpRegisters, iReg), 704 pGVCpu->nem.s.HCPhysHypercallData, 0 /*GCPhysOutput*/); 705 AssertLogRelMsgReturn(uResult == HV_MAKE_CALL_REP_RET(iReg), 706 ("uResult=%RX64 iRegs=%#x\n", uResult, iReg), 707 VERR_NEM_SET_REGISTERS_FAILED); 708 return VINF_SUCCESS; 709 } 710 711 712 /** 713 * Export the state to the native API (out of CPUMCTX). 714 * 715 * @returns VBox status code 716 * @param pGVM The ring-0 VM handle. 717 * @param pVM The cross context VM handle. 718 * @param idCpu The calling EMT. Necessary for getting the 719 * hypercall page and arguments. 720 * @param fWhat What to export. To be defined, UINT64_MAX for now. 721 */ 722 VMMR0_INT_DECL(int) NEMR0ExportState(PGVM pGVM, PVM pVM, VMCPUID idCpu, uint64_t fWhat) 723 { 724 /* 725 * Validate the call. 726 */ 727 int rc = GVMMR0ValidateGVMandVMandEMT(pGVM, pVM, idCpu); 728 if (RT_SUCCESS(rc)) 729 { 730 PVMCPU pVCpu = &pVM->aCpus[idCpu]; 731 PGVMCPU pGVCpu = &pGVM->aCpus[idCpu]; 732 AssertReturn(g_pfnHvlInvokeHypercall, VERR_NEM_MISSING_KERNEL_API); 733 734 /** @todo fix pGVM->nem.s.idHvPartition init. */ 735 if (pGVM->nem.s.idHvPartition == 0) 736 pGVM->nem.s.idHvPartition = pVM->nem.s.idHvPartition; 737 738 /* 739 * Call worker. 740 */ 741 rc = nemR0WinExportState(pGVM, pGVCpu, CPUMQueryGuestCtxPtr(pVCpu), fWhat); 742 } 743 return rc; 744 } 745 746 747 /** 748 * Worker for NEMR0ImportState. 749 * 750 * Intention is to use it internally later. 751 * 752 * @returns VBox status code. 753 * @param pGVM The ring-0 VM handle. 754 * @param pGVCpu The irng-0 VCPU handle. 755 * @param pCtx The CPU context structure to import into. 756 * @param fWhat What to import. To be defined, UINT64_MAX for now. 757 */ 758 static int nemR0WinImportState(PGVM pGVM, PGVMCPU pGVCpu, PCPUMCTX pCtx, uint64_t fWhat) 759 { 760 HV_INPUT_GET_VP_REGISTERS *pInput = (HV_INPUT_GET_VP_REGISTERS *)pGVCpu->nem.s.pbHypercallData; 761 AssertPtrReturn(pInput, VERR_INTERNAL_ERROR_3); 762 763 pInput->PartitionId = pGVM->nem.s.idHvPartition; 764 pInput->VpIndex = pGVCpu->idCpu; 765 pInput->fFlags = 0; 766 767 RT_NOREF_PV(fWhat); /** @todo group selection. */ 768 769 /* GPRs */ 770 pInput->Names[0] = HvX64RegisterRax; 771 pInput->Names[1] = HvX64RegisterRcx; 772 pInput->Names[2] = HvX64RegisterRdx; 773 pInput->Names[3] = HvX64RegisterRbx; 774 pInput->Names[4] = HvX64RegisterRsp; 775 pInput->Names[5] = HvX64RegisterRbp; 776 pInput->Names[6] = HvX64RegisterRsi; 777 pInput->Names[7] = HvX64RegisterRdi; 778 pInput->Names[8] = HvX64RegisterR8; 779 pInput->Names[9] = HvX64RegisterR9; 780 pInput->Names[10] = HvX64RegisterR10; 781 pInput->Names[11] = HvX64RegisterR11; 782 pInput->Names[12] = HvX64RegisterR12; 783 pInput->Names[13] = HvX64RegisterR13; 784 pInput->Names[14] = HvX64RegisterR14; 785 pInput->Names[15] = HvX64RegisterR15; 786 787 /* RIP & Flags */ 788 pInput->Names[16] = HvX64RegisterRip; 789 pInput->Names[17] = HvX64RegisterRflags; 790 791 /* Segments */ 792 pInput->Names[18] = HvX64RegisterEs; 793 pInput->Names[19] = HvX64RegisterCs; 794 pInput->Names[20] = HvX64RegisterSs; 795 pInput->Names[21] = HvX64RegisterDs; 796 pInput->Names[22] = HvX64RegisterFs; 797 pInput->Names[23] = HvX64RegisterGs; 798 pInput->Names[24] = HvX64RegisterLdtr; 799 pInput->Names[25] = HvX64RegisterTr; 800 801 /* Descriptor tables. */ 802 pInput->Names[26] = HvX64RegisterIdtr; 803 pInput->Names[27] = HvX64RegisterGdtr; 804 805 /* Control registers. */ 806 pInput->Names[28] = HvX64RegisterCr0; 807 pInput->Names[29] = HvX64RegisterCr2; 808 pInput->Names[30] = HvX64RegisterCr3; 809 pInput->Names[31] = HvX64RegisterCr4; 810 pInput->Names[32] = HvX64RegisterCr8; 811 812 /* Debug registers. */ 813 pInput->Names[33] = HvX64RegisterDr0; 814 pInput->Names[34] = HvX64RegisterDr1; 815 pInput->Names[35] = HvX64RegisterDr2; 816 pInput->Names[36] = HvX64RegisterDr3; 817 pInput->Names[37] = HvX64RegisterDr6; 818 pInput->Names[38] = HvX64RegisterDr7; 819 820 /* Vector state. */ 821 pInput->Names[39] = HvX64RegisterXmm0; 822 pInput->Names[40] = HvX64RegisterXmm1; 823 pInput->Names[41] = HvX64RegisterXmm2; 824 pInput->Names[42] = HvX64RegisterXmm3; 825 pInput->Names[43] = HvX64RegisterXmm4; 826 pInput->Names[44] = HvX64RegisterXmm5; 827 pInput->Names[45] = HvX64RegisterXmm6; 828 pInput->Names[46] = HvX64RegisterXmm7; 829 pInput->Names[47] = HvX64RegisterXmm8; 830 pInput->Names[48] = HvX64RegisterXmm9; 831 pInput->Names[49] = HvX64RegisterXmm10; 832 pInput->Names[50] = HvX64RegisterXmm11; 833 pInput->Names[51] = HvX64RegisterXmm12; 834 pInput->Names[52] = HvX64RegisterXmm13; 835 pInput->Names[53] = HvX64RegisterXmm14; 836 pInput->Names[54] = HvX64RegisterXmm15; 837 838 /* Floating point state. */ 839 pInput->Names[55] = HvX64RegisterFpMmx0; 840 pInput->Names[56] = HvX64RegisterFpMmx1; 841 pInput->Names[57] = HvX64RegisterFpMmx2; 842 pInput->Names[58] = HvX64RegisterFpMmx3; 843 pInput->Names[59] = HvX64RegisterFpMmx4; 844 pInput->Names[60] = HvX64RegisterFpMmx5; 845 pInput->Names[61] = HvX64RegisterFpMmx6; 846 pInput->Names[62] = HvX64RegisterFpMmx7; 847 pInput->Names[63] = HvX64RegisterFpControlStatus; 848 pInput->Names[64] = HvX64RegisterXmmControlStatus; 849 850 /* MSRs */ 851 // HvX64RegisterTsc - don't touch 852 pInput->Names[65] = HvX64RegisterEfer; 853 pInput->Names[66] = HvX64RegisterKernelGsBase; 854 pInput->Names[67] = HvX64RegisterApicBase; 855 pInput->Names[68] = HvX64RegisterPat; 856 pInput->Names[69] = HvX64RegisterSysenterCs; 857 pInput->Names[70] = HvX64RegisterSysenterEip; 858 pInput->Names[71] = HvX64RegisterSysenterEsp; 859 pInput->Names[72] = HvX64RegisterStar; 860 pInput->Names[73] = HvX64RegisterLstar; 861 pInput->Names[74] = HvX64RegisterCstar; 862 pInput->Names[75] = HvX64RegisterSfmask; 863 864 /* event injection */ 865 pInput->Names[76] = HvRegisterPendingInterruption; 866 pInput->Names[77] = HvRegisterInterruptState; 867 pInput->Names[78] = HvRegisterInterruptState; 868 pInput->Names[79] = HvRegisterPendingEvent0; 869 pInput->Names[80] = HvRegisterPendingEvent1; 870 unsigned const cRegs = 81; 871 size_t const cbInput = RT_ALIGN_Z(RT_OFFSETOF(HV_INPUT_GET_VP_REGISTERS, Names[cRegs]), 32); 872 873 HV_REGISTER_VALUE *paValues = (HV_REGISTER_VALUE *)((uint8_t *)pInput + cbInput); 874 Assert((uintptr_t)&paValues[cRegs] - (uintptr_t)pGVCpu->nem.s.pbHypercallData < PAGE_SIZE); /* (max is around 168 registers) */ 875 RT_BZERO(paValues, cRegs * sizeof(paValues[0])); 876 877 /* 878 * Make the hypercall. 879 */ 880 uint64_t uResult = g_pfnHvlInvokeHypercall(HV_MAKE_CALL_INFO(HvCallGetVpRegisters, cRegs), 881 pGVCpu->nem.s.HCPhysHypercallData, 882 pGVCpu->nem.s.HCPhysHypercallData + cbInput); 883 AssertLogRelMsgReturn(uResult == HV_MAKE_CALL_REP_RET(cRegs), 884 ("uResult=%RX64 cRegs=%#x\n", uResult, cRegs), 885 VERR_NEM_GET_REGISTERS_FAILED); 886 887 /* 888 * Copy information to the CPUM context. 889 */ 890 PVMCPU pVCpu = &pGVM->pVM->aCpus[pGVCpu->idCpu]; 891 892 /* GPRs */ 893 Assert(pInput->Names[0] == HvX64RegisterRax); 894 Assert(pInput->Names[15] == HvX64RegisterR15); 895 pCtx->rax = paValues[0].Reg64; 896 pCtx->rcx = paValues[1].Reg64; 897 pCtx->rdx = paValues[2].Reg64; 898 pCtx->rbx = paValues[3].Reg64; 899 pCtx->rsp = paValues[4].Reg64; 900 pCtx->rbp = paValues[5].Reg64; 901 pCtx->rsi = paValues[6].Reg64; 902 pCtx->rdi = paValues[7].Reg64; 903 pCtx->r8 = paValues[8].Reg64; 904 pCtx->r9 = paValues[9].Reg64; 905 pCtx->r10 = paValues[10].Reg64; 906 pCtx->r11 = paValues[11].Reg64; 907 pCtx->r12 = paValues[12].Reg64; 908 pCtx->r13 = paValues[13].Reg64; 909 pCtx->r14 = paValues[14].Reg64; 910 pCtx->r15 = paValues[15].Reg64; 911 912 /* RIP & Flags */ 913 Assert(pInput->Names[16] == HvX64RegisterRip); 914 pCtx->rip = paValues[16].Reg64; 915 pCtx->rflags.u = paValues[17].Reg64; 916 917 /* Segments */ 918 #define COPY_BACK_SEG(a_idx, a_enmName, a_SReg) \ 919 do { \ 920 Assert(pInput->Names[a_idx] == a_enmName); \ 921 (a_SReg).u64Base = paValues[a_idx].Segment.Base; \ 922 (a_SReg).u32Limit = paValues[a_idx].Segment.Limit; \ 923 (a_SReg).ValidSel = (a_SReg).Sel = paValues[a_idx].Segment.Selector; \ 924 (a_SReg).Attr.u = paValues[a_idx].Segment.Attributes; \ 925 (a_SReg).fFlags = CPUMSELREG_FLAGS_VALID; \ 926 } while (0) 927 COPY_BACK_SEG(18, HvX64RegisterEs, pCtx->es); 928 COPY_BACK_SEG(19, HvX64RegisterCs, pCtx->cs); 929 COPY_BACK_SEG(20, HvX64RegisterSs, pCtx->ss); 930 COPY_BACK_SEG(21, HvX64RegisterDs, pCtx->ds); 931 COPY_BACK_SEG(22, HvX64RegisterFs, pCtx->fs); 932 COPY_BACK_SEG(23, HvX64RegisterGs, pCtx->gs); 933 COPY_BACK_SEG(24, HvX64RegisterLdtr, pCtx->ldtr); 934 COPY_BACK_SEG(25, HvX64RegisterTr, pCtx->tr); 935 936 /* Descriptor tables. */ 937 Assert(pInput->Names[26] == HvX64RegisterIdtr); 938 pCtx->idtr.cbIdt = paValues[26].Table.Limit; 939 pCtx->idtr.pIdt = paValues[26].Table.Base; 940 Assert(pInput->Names[27] == HvX64RegisterGdtr); 941 pCtx->gdtr.cbGdt = paValues[27].Table.Limit; 942 pCtx->gdtr.pGdt = paValues[27].Table.Base; 943 944 /* Control registers. */ 945 Assert(pInput->Names[28] == HvX64RegisterCr0); 946 bool fMaybeChangedMode = false; 947 bool fFlushTlb = false; 948 bool fFlushGlobalTlb = false; 949 if (pCtx->cr0 != paValues[28].Reg64) 950 { 951 CPUMSetGuestCR0(pVCpu, paValues[28].Reg64); 952 fMaybeChangedMode = true; 953 fFlushTlb = fFlushGlobalTlb = true; /// @todo fix this 954 } 955 Assert(pInput->Names[29] == HvX64RegisterCr2); 956 pCtx->cr2 = paValues[29].Reg64; 957 if (pCtx->cr3 != paValues[30].Reg64) 958 { 959 CPUMSetGuestCR3(pVCpu, paValues[30].Reg64); 960 fFlushTlb = true; 961 } 962 if (pCtx->cr4 != paValues[31].Reg64) 963 { 964 CPUMSetGuestCR4(pVCpu, paValues[31].Reg64); 965 fMaybeChangedMode = true; 966 fFlushTlb = fFlushGlobalTlb = true; /// @todo fix this 967 } 968 APICSetTpr(pVCpu, (uint8_t)paValues[32].Reg64 << 4); 969 970 /* Debug registers. */ 971 Assert(pInput->Names[33] == HvX64RegisterDr0); 972 /** @todo fixme */ 973 if (pCtx->dr[0] != paValues[33].Reg64) 974 CPUMSetGuestDR0(pVCpu, paValues[33].Reg64); 975 if (pCtx->dr[1] != paValues[34].Reg64) 976 CPUMSetGuestDR1(pVCpu, paValues[34].Reg64); 977 if (pCtx->dr[2] != paValues[35].Reg64) 978 CPUMSetGuestDR2(pVCpu, paValues[35].Reg64); 979 if (pCtx->dr[3] != paValues[36].Reg64) 980 CPUMSetGuestDR3(pVCpu, paValues[36].Reg64); 981 Assert(pInput->Names[37] == HvX64RegisterDr6); 982 Assert(pInput->Names[38] == HvX64RegisterDr7); 983 if (pCtx->dr[6] != paValues[37].Reg64) 984 CPUMSetGuestDR6(pVCpu, paValues[37].Reg64); 985 if (pCtx->dr[7] != paValues[38].Reg64) 986 CPUMSetGuestDR6(pVCpu, paValues[38].Reg64); 987 988 /* Vector state. */ 989 Assert(pInput->Names[39] == HvX64RegisterXmm0); 990 Assert(pInput->Names[54] == HvX64RegisterXmm15); 991 pCtx->pXStateR0->x87.aXMM[0].uXmm.s.Lo = paValues[39].Reg128.Low64; 992 pCtx->pXStateR0->x87.aXMM[0].uXmm.s.Hi = paValues[39].Reg128.High64; 993 pCtx->pXStateR0->x87.aXMM[1].uXmm.s.Lo = paValues[40].Reg128.Low64; 994 pCtx->pXStateR0->x87.aXMM[1].uXmm.s.Hi = paValues[40].Reg128.High64; 995 pCtx->pXStateR0->x87.aXMM[2].uXmm.s.Lo = paValues[41].Reg128.Low64; 996 pCtx->pXStateR0->x87.aXMM[2].uXmm.s.Hi = paValues[41].Reg128.High64; 997 pCtx->pXStateR0->x87.aXMM[3].uXmm.s.Lo = paValues[42].Reg128.Low64; 998 pCtx->pXStateR0->x87.aXMM[3].uXmm.s.Hi = paValues[42].Reg128.High64; 999 pCtx->pXStateR0->x87.aXMM[4].uXmm.s.Lo = paValues[43].Reg128.Low64; 1000 pCtx->pXStateR0->x87.aXMM[4].uXmm.s.Hi = paValues[43].Reg128.High64; 1001 pCtx->pXStateR0->x87.aXMM[5].uXmm.s.Lo = paValues[44].Reg128.Low64; 1002 pCtx->pXStateR0->x87.aXMM[5].uXmm.s.Hi = paValues[44].Reg128.High64; 1003 pCtx->pXStateR0->x87.aXMM[6].uXmm.s.Lo = paValues[45].Reg128.Low64; 1004 pCtx->pXStateR0->x87.aXMM[6].uXmm.s.Hi = paValues[45].Reg128.High64; 1005 pCtx->pXStateR0->x87.aXMM[7].uXmm.s.Lo = paValues[46].Reg128.Low64; 1006 pCtx->pXStateR0->x87.aXMM[7].uXmm.s.Hi = paValues[46].Reg128.High64; 1007 pCtx->pXStateR0->x87.aXMM[8].uXmm.s.Lo = paValues[47].Reg128.Low64; 1008 pCtx->pXStateR0->x87.aXMM[8].uXmm.s.Hi = paValues[47].Reg128.High64; 1009 pCtx->pXStateR0->x87.aXMM[9].uXmm.s.Lo = paValues[48].Reg128.Low64; 1010 pCtx->pXStateR0->x87.aXMM[9].uXmm.s.Hi = paValues[48].Reg128.High64; 1011 pCtx->pXStateR0->x87.aXMM[10].uXmm.s.Lo = paValues[49].Reg128.Low64; 1012 pCtx->pXStateR0->x87.aXMM[10].uXmm.s.Hi = paValues[49].Reg128.High64; 1013 pCtx->pXStateR0->x87.aXMM[11].uXmm.s.Lo = paValues[50].Reg128.Low64; 1014 pCtx->pXStateR0->x87.aXMM[11].uXmm.s.Hi = paValues[50].Reg128.High64; 1015 pCtx->pXStateR0->x87.aXMM[12].uXmm.s.Lo = paValues[51].Reg128.Low64; 1016 pCtx->pXStateR0->x87.aXMM[12].uXmm.s.Hi = paValues[51].Reg128.High64; 1017 pCtx->pXStateR0->x87.aXMM[13].uXmm.s.Lo = paValues[52].Reg128.Low64; 1018 pCtx->pXStateR0->x87.aXMM[13].uXmm.s.Hi = paValues[52].Reg128.High64; 1019 pCtx->pXStateR0->x87.aXMM[14].uXmm.s.Lo = paValues[53].Reg128.Low64; 1020 pCtx->pXStateR0->x87.aXMM[14].uXmm.s.Hi = paValues[53].Reg128.High64; 1021 pCtx->pXStateR0->x87.aXMM[15].uXmm.s.Lo = paValues[54].Reg128.Low64; 1022 pCtx->pXStateR0->x87.aXMM[15].uXmm.s.Hi = paValues[54].Reg128.High64; 1023 1024 /* Floating point state. */ 1025 Assert(pInput->Names[55] == HvX64RegisterFpMmx0); 1026 Assert(pInput->Names[62] == HvX64RegisterFpMmx7); 1027 pCtx->pXStateR0->x87.aRegs[0].au64[0] = paValues[55].Fp.AsUINT128.Low64; 1028 pCtx->pXStateR0->x87.aRegs[0].au64[1] = paValues[55].Fp.AsUINT128.High64; 1029 pCtx->pXStateR0->x87.aRegs[1].au64[0] = paValues[56].Fp.AsUINT128.Low64; 1030 pCtx->pXStateR0->x87.aRegs[1].au64[1] = paValues[56].Fp.AsUINT128.High64; 1031 pCtx->pXStateR0->x87.aRegs[2].au64[0] = paValues[57].Fp.AsUINT128.Low64; 1032 pCtx->pXStateR0->x87.aRegs[2].au64[1] = paValues[57].Fp.AsUINT128.High64; 1033 pCtx->pXStateR0->x87.aRegs[3].au64[0] = paValues[58].Fp.AsUINT128.Low64; 1034 pCtx->pXStateR0->x87.aRegs[3].au64[1] = paValues[58].Fp.AsUINT128.High64; 1035 pCtx->pXStateR0->x87.aRegs[4].au64[0] = paValues[59].Fp.AsUINT128.Low64; 1036 pCtx->pXStateR0->x87.aRegs[4].au64[1] = paValues[59].Fp.AsUINT128.High64; 1037 pCtx->pXStateR0->x87.aRegs[5].au64[0] = paValues[60].Fp.AsUINT128.Low64; 1038 pCtx->pXStateR0->x87.aRegs[5].au64[1] = paValues[60].Fp.AsUINT128.High64; 1039 pCtx->pXStateR0->x87.aRegs[6].au64[0] = paValues[61].Fp.AsUINT128.Low64; 1040 pCtx->pXStateR0->x87.aRegs[6].au64[1] = paValues[61].Fp.AsUINT128.High64; 1041 pCtx->pXStateR0->x87.aRegs[7].au64[0] = paValues[62].Fp.AsUINT128.Low64; 1042 pCtx->pXStateR0->x87.aRegs[7].au64[1] = paValues[62].Fp.AsUINT128.High64; 1043 1044 Assert(pInput->Names[63] == HvX64RegisterFpControlStatus); 1045 pCtx->pXStateR0->x87.FCW = paValues[63].FpControlStatus.FpControl; 1046 pCtx->pXStateR0->x87.FSW = paValues[63].FpControlStatus.FpStatus; 1047 pCtx->pXStateR0->x87.FTW = paValues[63].FpControlStatus.FpTag 1048 /*| (paValues[63].FpControlStatus.Reserved << 8)*/; 1049 pCtx->pXStateR0->x87.FOP = paValues[63].FpControlStatus.LastFpOp; 1050 pCtx->pXStateR0->x87.FPUIP = (uint32_t)paValues[63].FpControlStatus.LastFpRip; 1051 pCtx->pXStateR0->x87.CS = (uint16_t)(paValues[63].FpControlStatus.LastFpRip >> 32); 1052 pCtx->pXStateR0->x87.Rsrvd1 = (uint16_t)(paValues[63].FpControlStatus.LastFpRip >> 48); 1053 1054 Assert(pInput->Names[64] == HvX64RegisterXmmControlStatus); 1055 pCtx->pXStateR0->x87.FPUDP = (uint32_t)paValues[64].XmmControlStatus.LastFpRdp; 1056 pCtx->pXStateR0->x87.DS = (uint16_t)(paValues[64].XmmControlStatus.LastFpRdp >> 32); 1057 pCtx->pXStateR0->x87.Rsrvd2 = (uint16_t)(paValues[64].XmmControlStatus.LastFpRdp >> 48); 1058 pCtx->pXStateR0->x87.MXCSR = paValues[64].XmmControlStatus.XmmStatusControl; 1059 pCtx->pXStateR0->x87.MXCSR_MASK = paValues[64].XmmControlStatus.XmmStatusControlMask; /** @todo ??? (Isn't this an output field?) */ 1060 1061 /* MSRs */ 1062 // HvX64RegisterTsc - don't touch 1063 Assert(pInput->Names[65] == HvX64RegisterEfer); 1064 if (paValues[65].Reg64 != pCtx->msrEFER) 1065 { 1066 pCtx->msrEFER = paValues[65].Reg64; 1067 fMaybeChangedMode = true; 1068 } 1069 1070 Assert(pInput->Names[66] == HvX64RegisterKernelGsBase); 1071 pCtx->msrKERNELGSBASE = paValues[66].Reg64; 1072 1073 Assert(pInput->Names[67] == HvX64RegisterApicBase); 1074 if (paValues[67].Reg64 != APICGetBaseMsrNoCheck(pVCpu)) 1075 { 1076 VBOXSTRICTRC rc2 = APICSetBaseMsr(pVCpu, paValues[67].Reg64); 1077 Assert(rc2 == VINF_SUCCESS); NOREF(rc2); 1078 } 1079 1080 Assert(pInput->Names[68] == HvX64RegisterPat); 1081 pCtx->msrPAT = paValues[68].Reg64; 1082 /// @todo HvX64RegisterSysenterCs 1083 /// @todo HvX64RegisterSysenterEip 1084 /// @todo HvX64RegisterSysenterEsp 1085 Assert(pInput->Names[72] == HvX64RegisterStar); 1086 pCtx->msrSTAR = paValues[72].Reg64; 1087 Assert(pInput->Names[73] == HvX64RegisterLstar); 1088 pCtx->msrLSTAR = paValues[73].Reg64; 1089 Assert(pInput->Names[74] == HvX64RegisterCstar); 1090 pCtx->msrCSTAR = paValues[74].Reg64; 1091 Assert(pInput->Names[75] == HvX64RegisterSfmask); 1092 pCtx->msrSFMASK = paValues[75].Reg64; 1093 1094 /// @todo HvRegisterPendingInterruption 1095 Assert(pInput->Names[76] == HvRegisterPendingInterruption); 1096 if (paValues[76].PendingInterruption.InterruptionPending) 1097 { 1098 Log7(("PendingInterruption: type=%u vector=%#x errcd=%RTbool/%#x instr-len=%u nested=%u\n", 1099 paValues[76].PendingInterruption.InterruptionType, paValues[76].PendingInterruption.InterruptionVector, 1100 paValues[76].PendingInterruption.DeliverErrorCode, paValues[76].PendingInterruption.ErrorCode, 1101 paValues[76].PendingInterruption.InstructionLength, paValues[76].PendingInterruption.NestedEvent)); 1102 AssertMsg((paValues[76].PendingInterruption.AsUINT64 & UINT64_C(0xfc00)) == 0, 1103 ("%#RX64\n", paValues[76].PendingInterruption.AsUINT64)); 1104 } 1105 1106 /// @todo HvRegisterInterruptState 1107 /// @todo HvRegisterPendingEvent0 1108 /// @todo HvRegisterPendingEvent1 1109 1110 int rc = VINF_SUCCESS; 1111 if (fMaybeChangedMode) 1112 { 1113 rc = PGMChangeMode(pVCpu, pCtx->cr0, pCtx->cr4, pCtx->msrEFER); 1114 if (rc == VINF_PGM_CHANGE_MODE) 1115 rc = VERR_NEM_CHANGE_PGM_MODE; 1116 else 1117 AssertRC(rc); 1118 } 1119 if (fFlushTlb && rc == VINF_SUCCESS) 1120 rc = VERR_NEM_FLUSH_TLB; /* Calling PGMFlushTLB w/o long jump setup doesn't work, ring-3 does it. */ 1121 1122 return rc; 1123 } 1124 1125 1126 /** 1127 * Import the state from the native API (back to CPUMCTX). 1128 * 1129 * @returns VBox status code 1130 * @param pGVM The ring-0 VM handle. 1131 * @param pVM The cross context VM handle. 1132 * @param idCpu The calling EMT. Necessary for getting the 1133 * hypercall page and arguments. 1134 * @param fWhat What to import. To be defined, UINT64_MAX for now. 1135 */ 1136 VMMR0_INT_DECL(int) NEMR0ImportState(PGVM pGVM, PVM pVM, VMCPUID idCpu, uint64_t fWhat) 1137 { 1138 /* 1139 * Validate the call. 1140 */ 1141 int rc = GVMMR0ValidateGVMandVMandEMT(pGVM, pVM, idCpu); 1142 if (RT_SUCCESS(rc)) 1143 { 1144 PVMCPU pVCpu = &pVM->aCpus[idCpu]; 1145 PGVMCPU pGVCpu = &pGVM->aCpus[idCpu]; 1146 AssertReturn(g_pfnHvlInvokeHypercall, VERR_NEM_MISSING_KERNEL_API); 1147 1148 /** @todo fix pGVM->nem.s.idHvPartition init. */ 1149 if (pGVM->nem.s.idHvPartition == 0) 1150 pGVM->nem.s.idHvPartition = pVM->nem.s.idHvPartition; 1151 1152 /* 1153 * Call worker. 1154 */ 1155 rc = nemR0WinImportState(pGVM, pGVCpu, CPUMQueryGuestCtxPtr(pVCpu), fWhat); 1156 } 1157 return rc; 1158 } 1159 -
trunk/src/VBox/VMM/VMMR0/VMMR0.cpp
r71075 r71087 1988 1988 VMM_CHECK_SMAP_CHECK2(pVM, RT_NOTHING); 1989 1989 break; 1990 1991 case VMMR0_DO_NEM_EXPORT_STATE: 1992 if (pReqHdr || idCpu == NIL_VMCPUID) 1993 return VERR_INVALID_PARAMETER; 1994 rc = NEMR0ExportState(pGVM, pVM, idCpu, u64Arg); 1995 VMM_CHECK_SMAP_CHECK2(pVM, RT_NOTHING); 1996 break; 1997 1998 case VMMR0_DO_NEM_IMPORT_STATE: 1999 if (pReqHdr || idCpu == NIL_VMCPUID) 2000 return VERR_INVALID_PARAMETER; 2001 rc = NEMR0ImportState(pGVM, pVM, idCpu, u64Arg); 2002 VMM_CHECK_SMAP_CHECK2(pVM, RT_NOTHING); 2003 break; 1990 2004 # endif 1991 2005 #endif
Note:
See TracChangeset
for help on using the changeset viewer.