Changeset 97321 in vbox
- Timestamp:
- Oct 27, 2022 12:46:16 PM (2 years ago)
- Location:
- trunk/src/VBox/ValidationKit/bootsectors
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-weird-1-template.mac
r96407 r97321 116 116 117 117 118 ; 119 ; PC (IP/EIP) wrapper templates. 120 ; These will potentially trigger VM exits, except for the benign one. 121 ; 122 123 BS3_PROC_BEGIN_CMN bs3CpuWeird1_PcWrapBenign1, BS3_PBC_NEAR 124 nop 125 BS3_PROC_END_CMN bs3CpuWeird1_PcWrapBenign1 126 127 BS3_PROC_BEGIN_CMN bs3CpuWeird1_PcWrapBenign2, BS3_PBC_NEAR 128 xor xDX, xAX 129 BS3_PROC_END_CMN bs3CpuWeird1_PcWrapBenign2 130 131 BS3_PROC_BEGIN_CMN bs3CpuWeird1_PcWrapCpuId, BS3_PBC_NEAR 132 xor eax, eax 133 cpuid 134 BS3_PROC_END_CMN bs3CpuWeird1_PcWrapCpuId 135 136 BS3_PROC_BEGIN_CMN bs3CpuWeird1_PcWrapIn80, BS3_PBC_NEAR 137 in al, 80h 138 BS3_PROC_END_CMN bs3CpuWeird1_PcWrapIn80 139 140 BS3_PROC_BEGIN_CMN bs3CpuWeird1_PcWrapOut80, BS3_PBC_NEAR 141 out 80h, al 142 BS3_PROC_END_CMN bs3CpuWeird1_PcWrapOut80 143 144 BS3_PROC_BEGIN_CMN bs3CpuWeird1_PcWrapSmsw, BS3_PBC_NEAR 145 smsw si 146 BS3_PROC_END_CMN bs3CpuWeird1_PcWrapSmsw 147 148 BS3_PROC_BEGIN_CMN bs3CpuWeird1_PcWrapRdCr0, BS3_PBC_NEAR 149 mov sAX, cr0 150 BS3_PROC_END_CMN bs3CpuWeird1_PcWrapRdCr0 151 152 BS3_PROC_BEGIN_CMN bs3CpuWeird1_PcWrapRdDr0, BS3_PBC_NEAR 153 mov sAX, dr0 154 BS3_PROC_END_CMN bs3CpuWeird1_PcWrapRdDr0 155 156 BS3_PROC_BEGIN_CMN bs3CpuWeird1_PcWrapWrDr0, BS3_PBC_NEAR 157 xor sAX, sAX 158 mov dr0, sAX 159 BS3_PROC_END_CMN bs3CpuWeird1_PcWrapWrDr0 160 161 118 162 %endif ; BS3_INSTANTIATING_CMN 119 163 -
trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-weird-1-x0.c
r96407 r97321 41 41 #define BS3_USE_X0_TEXT_SEG 42 42 #include <bs3kit.h> 43 #include <bs3-cmn-memory.h> 43 44 #include <iprt/asm.h> 44 45 #include <iprt/asm-amd64-x86.h> … … 530 531 } 531 532 533 534 /********************************************************************************************************************************* 535 * IP / EIP Wrapping * 536 *********************************************************************************************************************************/ 537 #define PROTO1632(a_Template) FNBS3FAR a_Template ## _c16, a_Template ## _c16_EndProc, a_Template ## _c32, a_Template ## _c32_EndProc 538 PROTO1632(bs3CpuWeird1_PcWrapBenign1); 539 PROTO1632(bs3CpuWeird1_PcWrapBenign2); 540 PROTO1632(bs3CpuWeird1_PcWrapCpuId); 541 PROTO1632(bs3CpuWeird1_PcWrapIn80); 542 PROTO1632(bs3CpuWeird1_PcWrapOut80); 543 PROTO1632(bs3CpuWeird1_PcWrapSmsw); 544 PROTO1632(bs3CpuWeird1_PcWrapRdCr0); 545 PROTO1632(bs3CpuWeird1_PcWrapRdDr0); 546 PROTO1632(bs3CpuWeird1_PcWrapWrDr0); 547 #undef PROTO1632 548 549 550 /** 551 * Compares pc wraparound result. 552 */ 553 static uint8_t bs3CpuWeird1_ComparePcWrap(PCBS3TRAPFRAME pTrapCtx, PCBS3TRAPFRAME pTrapExpect) 554 { 555 uint16_t const cErrorsBefore = Bs3TestSubErrorCount(); 556 CHECK_MEMBER("bXcpt", "%#04x", pTrapCtx->bXcpt, pTrapExpect->bXcpt); 557 CHECK_MEMBER("bErrCd", "%#06RX64", pTrapCtx->uErrCd, pTrapExpect->uErrCd); 558 Bs3TestCheckRegCtxEx(&pTrapCtx->Ctx, &pTrapExpect->Ctx, 0 /*cbPcAdjust*/, 0 /*cbSpAdjust*/, 0 /*fExtraEfl*/, 559 g_pszTestMode, g_usBs3TestStep); 560 if (Bs3TestSubErrorCount() != cErrorsBefore) 561 { 562 Bs3TrapPrintFrame(pTrapCtx); 563 Bs3TestPrintf("CS=%04RX16 SS:ESP=%04RX16:%08RX64 EFL=%RX64 cbIret=%#x\n", 564 pTrapCtx->uHandlerCs, pTrapCtx->uHandlerSs, pTrapCtx->uHandlerRsp, 565 pTrapCtx->fHandlerRfl, pTrapCtx->cbIretFrame); 566 #if 0 567 Bs3TestPrintf("Halting in ComparePcWrap: bXcpt=%#x\n", pTrapCtx->bXcpt); 568 ASMHalt(); 569 #endif 570 return 1; 571 } 572 return 0; 573 } 574 575 576 static uint8_t bs3CpuWeird1_PcWrapping_Worker16(uint8_t bMode, uint8_t BS3_FAR *pbCode, uint8_t BS3_FAR *pbHead, 577 uint8_t BS3_FAR *pbTail, uint8_t BS3_FAR *pbAfter, 578 void const BS3_FAR *pvTemplate, size_t cbTemplate) 579 { 580 BS3TRAPFRAME TrapCtx; 581 BS3TRAPFRAME TrapExpect; 582 BS3REGCTX Ctx; 583 uint8_t bXcpt; 584 585 /* make sure they're allocated */ 586 Bs3MemZero(&Ctx, sizeof(Ctx)); 587 Bs3MemZero(&TrapCtx, sizeof(TrapCtx)); 588 Bs3MemZero(&TrapExpect, sizeof(TrapExpect)); 589 590 /* 591 * Create the expected result by first placing the code template 592 * at the start of the buffer and giving it a quick run. 593 * 594 * I cannot think of any instruction always causing #GP(0) right now, so 595 * we generate a ud2 and modify it instead. 596 */ 597 Bs3MemCpy(pbHead, pvTemplate, cbTemplate); 598 if ((g_uBs3CpuDetected & BS3CPU_TYPE_MASK) <= BS3CPU_80286) 599 { 600 pbHead[cbTemplate] = 0xcc; /* int3 */ 601 bXcpt = X86_XCPT_BP; 602 } 603 else 604 { 605 pbHead[cbTemplate] = 0x0f; /* ud2 */ 606 pbHead[cbTemplate + 1] = 0x0b; 607 bXcpt = X86_XCPT_UD; 608 } 609 610 Bs3RegCtxSaveEx(&Ctx, bMode, 1024); 611 612 Ctx.cs = BS3_FP_SEG(pbCode); 613 Ctx.rip.u = 0; 614 615 /* V8086: Set IOPL to 3. */ 616 if (BS3_MODE_IS_V86(bMode)) 617 Ctx.rflags.u32 |= X86_EFL_IOPL; 618 619 Bs3TrapSetJmpAndRestore(&Ctx, &TrapExpect); 620 if (TrapExpect.bXcpt != bXcpt) 621 { 622 623 Bs3TestFailedF("%u: Setup: bXcpt is %#x, expected %#x!\n", g_usBs3TestStep, TrapExpect.bXcpt, bXcpt); 624 Bs3TrapPrintFrame(&TrapExpect); 625 return 1; 626 } 627 628 /* 629 * Adjust the contexts for the real test. 630 */ 631 Ctx.cs = BS3_FP_SEG(pbCode); 632 Ctx.rip.u = (uint32_t)_64K - cbTemplate; 633 634 if ((g_uBs3CpuDetected & BS3CPU_TYPE_MASK) <= BS3CPU_80286) 635 TrapExpect.Ctx.rip.u = 1; 636 else 637 { 638 if (BS3_MODE_IS_16BIT_SYS(bMode)) 639 TrapExpect.Ctx.rip.u = 0; 640 else 641 TrapExpect.Ctx.rip.u = UINT32_C(0x10000); 642 TrapExpect.bXcpt = X86_XCPT_GP; 643 TrapExpect.uErrCd = 0; 644 } 645 646 /* 647 * Prepare the buffer for 16-bit wrap around. 648 */ 649 Bs3MemSet(pbHead, 0xcc, 64); /* int3 */ 650 if (bXcpt == X86_XCPT_UD) 651 { 652 pbHead[0] = 0x0f; /* ud2 */ 653 pbHead[1] = 0x0b; 654 } 655 Bs3MemCpy(&pbTail[_4K - cbTemplate], pvTemplate, cbTemplate); 656 Bs3MemSet(pbAfter, 0xf1, 64); /* icebp / int1 */ 657 658 /* 659 * Do a test run. 660 */ 661 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx); 662 return bs3CpuWeird1_ComparePcWrap(&TrapCtx, &TrapExpect); 663 } 664 665 666 static uint8_t bs3CpuWeird1_PcWrapping_Worker32(uint8_t bMode, RTSEL SelCode, uint8_t BS3_FAR *pbPage1, 667 uint8_t BS3_FAR *pbPage2, uint32_t uFlatPage2, 668 void const BS3_FAR *pvTemplate, size_t cbTemplate) 669 { 670 BS3TRAPFRAME TrapCtx; 671 BS3TRAPFRAME TrapExpect; 672 BS3REGCTX Ctx; 673 674 /* make sure they're allocated */ 675 Bs3MemZero(&Ctx, sizeof(Ctx)); 676 Bs3MemZero(&TrapCtx, sizeof(TrapCtx)); 677 Bs3MemZero(&TrapExpect, sizeof(TrapExpect)); 678 679 //Bs3TestPrintf("SelCode=%#x pbPage1=%p pbPage2=%p uFlatPage2=%RX32 pvTemplate=%p cbTemplate\n", 680 // SelCode, pbPage1, pbPage2, uFlatPage2, pvTemplate, cbTemplate); 681 682 /* 683 * Create the expected result by first placing the code template 684 * at the start of the buffer and giving it a quick run. 685 */ 686 Bs3MemSet(pbPage1, 0xcc, _4K); 687 Bs3MemSet(pbPage2, 0xcc, _4K); 688 Bs3MemCpy(&pbPage1[_4K - cbTemplate], pvTemplate, cbTemplate); 689 pbPage2[0] = 0x0f; /* ud2 */ 690 pbPage2[1] = 0x0b; 691 692 Bs3RegCtxSaveEx(&Ctx, bMode, 1024); 693 694 Ctx.cs = BS3_SEL_R0_CS32; 695 Ctx.rip.u = uFlatPage2 - cbTemplate; 696 697 Bs3TrapSetJmpAndRestore(&Ctx, &TrapExpect); 698 if (TrapExpect.bXcpt != X86_XCPT_UD) 699 { 700 701 Bs3TestFailedF("%u: Setup: bXcpt is %#x, expected %#x!\n", g_usBs3TestStep, TrapExpect.bXcpt, X86_XCPT_UD); 702 Bs3TrapPrintFrame(&TrapExpect); 703 return 1; 704 } 705 706 /* 707 * Adjust the contexts for the real test. 708 */ 709 Ctx.cs = SelCode; 710 Ctx.rip.u = UINT32_MAX - cbTemplate + 1; 711 712 TrapExpect.Ctx.cs = SelCode; 713 TrapExpect.Ctx.rip.u = 0; 714 715 /* 716 * Do a test run. 717 */ 718 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx); 719 if (bs3CpuWeird1_ComparePcWrap(&TrapCtx, &TrapExpect)) 720 ASMHalt(); 721 return 0; 722 } 723 724 725 726 BS3_DECL_FAR(uint8_t) BS3_CMN_FAR_NM(bs3CpuWeird1_PcWrapping)(uint8_t bMode) 727 { 728 /* 729 * Allocate a 68KB buffer for testing. 730 * 731 * This is a little annoying to work with from 16-bit bit, so we use 732 * separate pointers to each interesting bit of it. 733 */ 734 uint8_t bRet = 1; 735 /** @todo add api for doing this, so we don't need to include bs3-cmn-memory.h. */ 736 uint8_t BS3_FAR *pbBuf = (uint8_t BS3_FAR *)Bs3SlabAllocEx(&g_Bs3Mem4KLow.Core, 17 /*cPages*/, 0 /*fFlags*/); 737 if (pbBuf != NULL) 738 { 739 uint32_t const uFlatBuf = Bs3SelPtrToFlat(pbBuf); 740 uint8_t BS3_FAR *pbTail = Bs3XptrFlatToCurrent(uFlatBuf + 0x0f000); 741 uint8_t BS3_FAR *pbAfter = Bs3XptrFlatToCurrent(uFlatBuf + UINT32_C(0x10000)); 742 uint32_t off; 743 size_t i; 744 745 /* Fill the buffer with int1 instructions: */ 746 for (off = 0; off < UINT32_C(0x11000); off += _4K) 747 { 748 uint8_t BS3_FAR *pbPage = Bs3XptrFlatToCurrent(uFlatBuf + off); 749 Bs3MemSet(pbPage, 0xf1, _4K); 750 } 751 752 /* 753 * Now for the testing. 754 */ 755 bs3CpuWeird1_SetGlobals(bMode); 756 #define WITH_LEN(a_Template) a_Template, (uintptr_t)a_Template##_EndProc - (uintptr_t)a_Template 757 758 if (BS3_MODE_IS_16BIT_CODE(bMode)) 759 { 760 static struct { FPFNBS3FAR pfnStart, pfnEnd; unsigned fNoV86 : 1; } const s_aTemplates16[] = 761 { 762 #define ENTRY16(a_Template, a_fNoV86) { a_Template ## _c16, a_Template##_c16_EndProc, a_fNoV86 } 763 ENTRY16(bs3CpuWeird1_PcWrapBenign1, 0), 764 ENTRY16(bs3CpuWeird1_PcWrapBenign2, 0), 765 ENTRY16(bs3CpuWeird1_PcWrapCpuId, 0), 766 ENTRY16(bs3CpuWeird1_PcWrapIn80, 0), 767 ENTRY16(bs3CpuWeird1_PcWrapOut80, 0), 768 ENTRY16(bs3CpuWeird1_PcWrapSmsw, 0), 769 ENTRY16(bs3CpuWeird1_PcWrapRdCr0, 1), 770 ENTRY16(bs3CpuWeird1_PcWrapRdDr0, 1), 771 ENTRY16(bs3CpuWeird1_PcWrapWrDr0, 1), 772 #undef ENTRY16 773 }; 774 uint8_t BS3_FAR *pbCode = BS3_FP_MAKE((uint16_t)(uFlatBuf >> 4), 0); 775 if (!BS3_MODE_IS_RM_OR_V86(bMode)) 776 { 777 Bs3SelSetup16BitCode(&Bs3GdteSpare00, uFlatBuf, 0); 778 pbCode = BS3_FP_MAKE(BS3_SEL_SPARE_00, 0); 779 } 780 781 /* Allow IN and OUT to port 80h from V8086 mode. */ 782 if (BS3_MODE_IS_V86(bMode)) 783 { 784 Bs3RegSetTr(BS3_SEL_TSS32_IOBP_IRB); 785 ASMBitClear(Bs3SharedIobp, 0x80); 786 } 787 788 for (i = 0; i < RT_ELEMENTS(s_aTemplates16); i++, g_usBs3TestStep++) 789 { 790 if (s_aTemplates16[i].fNoV86 && BS3_MODE_IS_V86(bMode)) 791 continue; 792 bs3CpuWeird1_PcWrapping_Worker16(bMode, pbCode, pbBuf, pbTail, pbAfter, s_aTemplates16[i].pfnStart, 793 (uintptr_t)s_aTemplates16[i].pfnEnd - (uintptr_t)s_aTemplates16[i].pfnStart); 794 } 795 796 if (BS3_MODE_IS_V86(bMode)) 797 ASMBitSet(Bs3SharedIobp, 0x80); 798 bRet = 0; 799 } 800 else if (BS3_MODE_IS_32BIT_CODE(bMode)) 801 { 802 static struct { FPFNBS3FAR pfnStart, pfnEnd; } const s_aTemplates32[] = 803 { 804 #define ENTRY32(a_Template) { a_Template ## _c32, a_Template##_c32_EndProc } 805 ENTRY32(bs3CpuWeird1_PcWrapBenign1), 806 ENTRY32(bs3CpuWeird1_PcWrapBenign2), 807 ENTRY32(bs3CpuWeird1_PcWrapCpuId), 808 //ENTRY32(bs3CpuWeird1_PcWrapIn80), - causes GURU because of vmxHCAdvanceGuestRipBy. 809 //ENTRY32(bs3CpuWeird1_PcWrapOut80), - ditto. 810 ENTRY32(bs3CpuWeird1_PcWrapSmsw), 811 ENTRY32(bs3CpuWeird1_PcWrapRdCr0), 812 ENTRY32(bs3CpuWeird1_PcWrapRdDr0), 813 ENTRY32(bs3CpuWeird1_PcWrapWrDr0), 814 #undef ENTRY32 815 }; 816 817 Bs3SelSetup32BitCode(&Bs3GdteSpare00, uFlatBuf + UINT32_C(0x10000), UINT32_MAX, 0); 818 819 for (i = 0; i < RT_ELEMENTS(s_aTemplates32); i++, g_usBs3TestStep++) 820 { 821 //Bs3TestPrintf("pfnStart=%p pfnEnd=%p\n", s_aTemplates32[i].pfnStart, s_aTemplates32[i].pfnEnd); 822 bs3CpuWeird1_PcWrapping_Worker32(bMode, BS3_SEL_SPARE_00, pbTail, pbAfter, uFlatBuf + UINT32_C(0x10000), 823 Bs3SelLnkPtrToCurPtr(s_aTemplates32[i].pfnStart), 824 (uintptr_t)s_aTemplates32[i].pfnEnd - (uintptr_t)s_aTemplates32[i].pfnStart); 825 } 826 bRet = 0; 827 } 828 else 829 { 830 BS3_ASSERT(bMode == BS3_MODE_LM64); 831 /** @todo test LM64 wraparound too (doing some page table aliasing perhaps). */ 832 bRet = BS3TESTDOMODE_SKIPPED; 833 } 834 835 Bs3SlabFree(&g_Bs3Mem4KLow.Core, uFlatBuf, 17); 836 } 837 else 838 Bs3TestFailed("Failed to allocate 17 pages (68KB)"); 839 840 return bRet; 841 } 842 -
trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-weird-1.c
r96407 r97321 47 47 *********************************************************************************************************************************/ 48 48 FNBS3TESTDOMODE bs3CpuWeird1_DbgInhibitRingXfer_f16; 49 FNBS3TESTDOMODE bs3CpuWeird1_PcWrapping_f16; 49 50 50 51 … … 55 56 { 56 57 { "dbg+inhibit+ringxfer", bs3CpuWeird1_DbgInhibitRingXfer_f16, 0 }, 58 { "pc wrapping", bs3CpuWeird1_PcWrapping_f16, 0 }, 57 59 }; 58 60 … … 70 72 71 73 Bs3TestTerm(); 72 for (;;) { ASMHalt(); } 74 Bs3Shutdown(); 73 75 } 74 76
Note:
See TracChangeset
for help on using the changeset viewer.