- Timestamp:
- Sep 22, 2007 12:04:09 AM (17 years ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMM.cpp
r4971 r4979 641 641 if (VBOX_FAILURE(rc) || (rc >= VINF_EM_FIRST && rc <= VINF_EM_LAST)) 642 642 break; 643 break; // remove this when we do setjmp for all ring-0 stuff.643 /* Resume R0 */ 644 644 } 645 645 … … 647 647 { 648 648 LogRel(("R0 init failed, rc=%Vra\n", rc)); 649 if ( rc >= VINF_EM_FIRST && rc <= VINF_EM_LAST)649 if (VBOX_SUCCESS(rc)) 650 650 rc = VERR_INTERNAL_ERROR; 651 651 } … … 758 758 if (VBOX_FAILURE(rc) || (rc >= VINF_EM_FIRST && rc <= VINF_EM_LAST)) 759 759 break; 760 break; // remove this when we do setjmp for all ring-0 stuff.760 /* Resume R0 */ 761 761 } 762 762 if (VBOX_FAILURE(rc) || (rc >= VINF_EM_FIRST && rc <= VINF_EM_LAST)) 763 763 { 764 764 LogRel(("VMMR3Term: R0 term failed, rc=%Vra. (warning)\n", rc)); 765 if ( rc >= VINF_EM_FIRST && rc <= VINF_EM_LAST)765 if (VBOX_SUCCESS(rc)) 766 766 rc = VERR_INTERNAL_ERROR; 767 767 } … … 2257 2257 /* 2258 2258 * Signal a ring 0 hypervisor assertion. 2259 * Cancel the longjmp operation that's in progress. 2259 2260 */ 2260 2261 case VMMCALLHOST_VM_R0_HYPER_ASSERTION: 2262 pVM->vmm.s.CallHostR0JmpBuf.fInRing3Call = false; 2263 #ifdef RT_ARCH_X86 2264 pVM->vmm.s.CallHostR0JmpBuf.eip = 0; 2265 #else 2266 pVM->vmm.s.CallHostR0JmpBuf.rip = 0; 2267 #endif 2261 2268 return VINF_EM_DBG_HYPER_ASSERTION; 2262 2269 -
trunk/src/VBox/VMM/VMMInternal.h
r4787 r4979 404 404 405 405 /** 406 * Callback function for vmmR0CallHostSetJmpEx. 407 * 408 * @returns VBox status code. 409 * @param pvUser The user argument. 410 */ 411 typedef DECLCALLBACK(int) FNVMMR0SETJMPEX(void *pvUser); 412 /** Pointer to FNVMMR0SETJMP(). */ 413 typedef FNVMMR0SETJMPEX *PFNVMMR0SETJMPEX; 414 415 /** 416 * Same as vmmR0CallHostSetJmp except for the function signature. 417 * 418 * @returns VINF_SUCCESS on success or whatever is passed to vmmR0CallHostLongJmp. 419 * @param pJmpBuf The jmp_buf to set. 420 * @param pfn The function to be called when not resuming.. 421 * @param pvUser The argument of that function. 422 */ 423 DECLASM(int) vmmR0CallHostSetJmpEx(PVMMR0JMPBUF pJmpBuf, PFNVMMR0SETJMPEX pfn, void *pvUser); 424 425 426 /** 406 427 * Worker for VMMR0CallHost. 407 428 * This will save the stack and registers. -
trunk/src/VBox/VMM/VMMR0/VMMR0.cpp
r4971 r4979 54 54 __END_DECLS 55 55 56 57 /** @def DEBUG_NO_RING0_ASSERTIONS58 * Define this if you don't wish to BSOD on debug assertions in59 * the VMMR0.r0 code. If would of course be nice to have this60 * feature enabled by default of course, but it's not currently61 * safe when more than one VM is running or when using internal62 * networking. */63 #if defined(DEBUG_sandervl) /*|| defined(DEBUG_bird)*/64 # define DEBUG_NO_RING0_ASSERTIONS65 #endif66 #ifdef DEBUG_NO_RING0_ASSERTIONS67 static PVM g_pVMAssert = 0;68 #endif69 56 70 57 /******************************************************************************* … … 616 603 if (VBOX_SUCCESS(rc)) 617 604 { 618 #ifdef DEBUG_NO_RING0_ASSERTIONS619 g_pVMAssert = pVM;620 #endif621 605 rc = vmmR0CallHostSetJmp(&pVM->vmm.s.CallHostR0JmpBuf, HWACCMR0RunGuestCode, pVM); /* this may resume code. */ 622 #ifdef DEBUG_NO_RING0_ASSERTIONS623 g_pVMAssert = NULL;624 #endif625 606 int rc2 = HWACCMR0Disable(pVM); 626 607 AssertRC(rc2); … … 655 636 656 637 /** 657 * The Ring 0 entry point, called by the support library (SUP). 638 * VMMR0EntryEx worker function, either called directly or when ever possible 639 * called thru a longjmp so we can exit safely on failure. 658 640 * 659 641 * @returns VBox status code. … … 664 646 * @remarks Assume called with interrupts _enabled_. 665 647 */ 666 VMMR0DECL(int) VMMR0EntryEx(PVM pVM, VMMR0OPERATION enmOperation, PSUPVMMR0REQHDR pReq, uint64_t u64Arg)648 static int vmmR0EntryExWorker(PVM pVM, VMMR0OPERATION enmOperation, PSUPVMMR0REQHDR pReq, uint64_t u64Arg) 667 649 { 668 650 switch (enmOperation) … … 672 654 */ 673 655 case VMMR0_DO_VMMR0_INIT: 674 { 675 int rc = VMMR0Init(pVM, (unsigned)u64Arg); 676 return rc; 677 } 656 return VMMR0Init(pVM, (unsigned)u64Arg); 678 657 679 658 /* … … 681 660 */ 682 661 case VMMR0_DO_VMMR0_TERM: 683 { 684 int rc = VMMR0Term(pVM); 685 return rc; 686 } 662 return VMMR0Term(pVM); 687 663 688 664 /* … … 833 809 834 810 811 /** 812 * Argument for vmmR0EntryExWrapper containing the argument s ofr VMMR0EntryEx. 813 */ 814 typedef struct VMMR0ENTRYEXARGS 815 { 816 PVM pVM; 817 VMMR0OPERATION enmOperation; 818 PSUPVMMR0REQHDR pReq; 819 uint64_t u64Arg; 820 } VMMR0ENTRYEXARGS; 821 /** Pointer to a vmmR0EntryExWrapper argument package. */ 822 typedef VMMR0ENTRYEXARGS *PVMMR0ENTRYEXARGS; 823 824 /** 825 * This is just a longjmp wrapper function for VMMR0EntryEx calls. 826 * 827 * @returns VBox status code. 828 * @param pvArgs The argument package 829 */ 830 static int vmmR0EntryExWrapper(void *pvArgs) 831 { 832 return vmmR0EntryExWorker(((PVMMR0ENTRYEXARGS)pvArgs)->pVM, 833 ((PVMMR0ENTRYEXARGS)pvArgs)->enmOperation, 834 ((PVMMR0ENTRYEXARGS)pvArgs)->pReq, 835 ((PVMMR0ENTRYEXARGS)pvArgs)->u64Arg); 836 } 837 838 839 /** 840 * The Ring 0 entry point, called by the support library (SUP). 841 * 842 * @returns VBox status code. 843 * @param pVM The VM to operate on. 844 * @param enmOperation Which operation to execute. 845 * @param pReq This points to a SUPVMMR0REQHDR packet. Optional. 846 * @param u64Arg Some simple constant argument. 847 * @remarks Assume called with interrupts _enabled_. 848 */ 849 VMMR0DECL(int) VMMR0EntryEx(PVM pVM, VMMR0OPERATION enmOperation, PSUPVMMR0REQHDR pReq, uint64_t u64Arg) 850 { 851 /* 852 * Requests that should only happen on the EMT thread will be 853 * wrapped in a setjmp so we can assert without causing trouble. 854 */ 855 if ( VALID_PTR(pVM) 856 && pVM->pVMR0) 857 { 858 switch (enmOperation) 859 { 860 case VMMR0_DO_VMMR0_INIT: 861 case VMMR0_DO_VMMR0_TERM: 862 { 863 VMMR0ENTRYEXARGS Args; 864 Args.pVM = pVM; 865 Args.enmOperation = enmOperation; 866 Args.pReq = pReq; 867 Args.u64Arg = u64Arg; 868 return vmmR0CallHostSetJmpEx(&pVM->vmm.s.CallHostR0JmpBuf, vmmR0EntryExWrapper, &Args); 869 } 870 871 default: 872 break; 873 } 874 } 875 return vmmR0EntryExWorker(pVM, enmOperation, pReq, u64Arg); 876 } 877 835 878 836 879 … … 883 926 884 927 885 #ifdef DEBUG_NO_RING0_ASSERTIONS 886 /** 887 * Check if we really want to hit a breakpoint. 888 * Can jump back to ring-3 when the longjmp is armed. 889 */ 890 DECLEXPORT(bool) RTCALL RTAssertDoBreakpoint() 891 { 892 if (g_pVMAssert) 893 { 894 int rc = VMMR0CallHost(g_pVMAssert, VMMCALLHOST_VM_R0_HYPER_ASSERTION, 0); 895 if (rc == VINF_SUCCESS) 896 rc = g_pVMAssert->vmm.s.rcCallHost; 897 } 898 899 return false; 900 } 901 #endif /* !DEBUG_NO_RING0_ASSERTIONS */ 928 929 /** 930 * Jump back to ring-3 if we're the EMT and the longjmp is armed. 931 * 932 * @returns true if the breakpoint should be hit, false if it should be ignored. 933 * @remark The RTDECL() makes this a bit difficult to override on windows. Sorry. 934 */ 935 DECLEXPORT(bool) RTCALL RTAssertDoBreakpoint() 936 { 937 PVM pVM = GVMR0ByEMT(NIL_RTNATIVETHREAD); 938 if (pVM) 939 { 940 #ifdef RT_ARCH_X86 941 if (pVM->vmm.s.CallHostR0JmpBuf.eip) 942 #else 943 if (pVM->vmm.s.CallHostR0JmpBuf.rip) 944 #endif 945 { 946 int rc = VMMR0CallHost(pVM, VMMCALLHOST_VM_R0_HYPER_ASSERTION, 0); 947 return RT_FAILURE_NP(rc); 948 } 949 } 950 return true; 951 } 902 952 903 953 … … 906 956 # define LOG_GROUP LOG_GROUP_EM 907 957 908 DECLEXPORT(void) RTCALL RTR0AssertBreakpoint(void *pvVM) 909 { 910 if (pvVM) 911 { 912 PVM pVM = (PVM)pvVM; 913 VMMR0CallHost(pVM, VMMCALLHOST_VM_R0_HYPER_ASSERTION, 0); 914 /* does not return */ 915 } 916 } 917 918 958 /** 959 * Override this so we can push 960 * 961 * @param pszExpr Expression. Can be NULL. 962 * @param uLine Location line number. 963 * @param pszFile Location file name. 964 * @param pszFunction Location function name. 965 * @remark This API exists in HC Ring-3 and GC. 966 */ 919 967 DECLEXPORT(void) RTCALL AssertMsg1(const char *pszExpr, unsigned uLine, const char *pszFile, const char *pszFunction) 920 968 { … … 939 987 for (size_t i = 0; i < cbChars; i++) 940 988 { 941 LogRel(("%c", pachChars[i])); 989 LogRel(("%c", pachChars[i])); /** @todo this isn't any release logging in ring-0 from what I can tell... */ 942 990 SUPR0Printf("%c", pachChars[i]); 943 991 } … … 959 1007 } 960 1008 } 1009 1010 -
trunk/src/VBox/VMM/VMMR0/VMMR0A.asm
r4477 r4979 41 41 ; @param pJmpBuf msc:rcx gcc:rdi x86:[esp+4] Our jmp_buf. 42 42 ; @param pfn msc:rdx gcc:rsi x86:[esp+8] The function to be called when not resuming. 43 ; @param p VMmsc:r8 gcc:rdx x86:[esp+c] The argument of that function.43 ; @param pvUser msc:r8 gcc:rdx x86:[esp+c] The argument of that function. 44 44 ; 45 45 BEGINPROC vmmR0CallHostSetJmp 46 GLOBALNAME vmmR0CallHostSetJmpEx 46 47 %ifdef RT_ARCH_X86 47 48 ; … … 135 136 %else 136 137 sub rsp, 10h 137 mov r8, rdx ; p VM(save it like MSC)138 mov r8, rdx ; pvUser (save it like MSC) 138 139 mov r11, rsi ; pfn 139 140 mov rdx, rdi ; pJmpBuf … … 163 164 mov [rbp - 8], rdx ; Save it and fix stack alignment (16). 164 165 %ifdef ASM_CALL64_MSC 165 mov rcx, r8 ; p VM-> arg0166 mov rcx, r8 ; pvUser -> arg0 166 167 %else 167 mov rdi, r8 ; p VM-> arg0168 mov rdi, r8 ; pvUser -> arg0 168 169 %endif 169 170 call r11
Note:
See TracChangeset
for help on using the changeset viewer.