Changeset 54308 in vbox
- Timestamp:
- Feb 19, 2015 7:43:51 PM (10 years ago)
- Location:
- trunk
- Files:
-
- 18 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/sup.h
r54286 r54308 455 455 * as volatile. Thus, there is no PCSUPGLOBALINFOPAGE type. 456 456 */ 457 #if defined(IN_SUP_R0) || defined(IN_SUP_R3) || defined(IN_SUP_RC)457 #ifdef IN_SUP_R3 458 458 extern DECLEXPORT(PSUPGLOBALINFOPAGE) g_pSUPGlobalInfoPage; 459 459 … … 489 489 SUPDECL(PSUPGLOBALINFOPAGE) SUPGetGIP(void); 490 490 491 /** Whether the application of TSC-deltas is required. */ 492 #define GIP_ARE_TSC_DELTAS_APPLICABLE(a_pGip) ((a_pGip)->enmUseTscDelta > SUPGIPUSETSCDELTA_PRACTICALLY_ZERO) 493 494 495 #if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86) 491 492 /** @internal */ 493 SUPDECL(uint64_t) SUPGetCpuHzFromGipForAsyncMode(PSUPGLOBALINFOPAGE pGip); 494 496 495 /** 497 496 * Gets the TSC frequency of the calling CPU. … … 500 499 * @param pGip The GIP pointer. 501 500 */ 502 DECLINLINE(uint64_t) SUPGetCpuHzFromGIP(PSUPGLOBALINFOPAGE pGip) 503 { 504 unsigned iCpu; 505 506 if (RT_UNLIKELY(!pGip || pGip->u32Magic != SUPGLOBALINFOPAGE_MAGIC || !pGip->u64CpuHz)) 507 return UINT64_MAX; 508 509 if ( pGip->u32Mode == SUPGIPMODE_INVARIANT_TSC 510 || pGip->u32Mode == SUPGIPMODE_SYNC_TSC) 511 iCpu = 0; 512 else 501 DECLINLINE(uint64_t) SUPGetCpuHzFromGip(PSUPGLOBALINFOPAGE pGip) 502 { 503 if (RT_LIKELY( pGip 504 && pGip->u32Magic == SUPGLOBALINFOPAGE_MAGIC 505 && pGip->u64CpuHz)) 513 506 { 514 Assert(pGip->u32Mode == SUPGIPMODE_ASYNC_TSC); 515 iCpu = pGip->aiCpuFromApicId[ASMGetApicId()]; 516 if (RT_UNLIKELY(iCpu >= pGip->cCpus)) 517 return UINT64_MAX; 507 switch (pGip->u32Mode) 508 { 509 case SUPGIPMODE_INVARIANT_TSC: 510 case SUPGIPMODE_SYNC_TSC: 511 return pGip->aCPUs[0].u64CpuHz; 512 case SUPGIPMODE_ASYNC_TSC: 513 return SUPGetCpuHzFromGipForAsyncMode(pGip); 514 default: break; /* shut up gcc */ 515 } 518 516 } 519 520 return pGip->aCPUs[iCpu].u64CpuHz;517 AssertFailed(); 518 return UINT64_MAX; 521 519 } 522 #endif /* X86 || AMD64 */ 523 524 /** 525 * Request for generic VMMR0Entry calls. 526 */ 527 typedef struct SUPVMMR0REQHDR 528 { 529 /** The magic. (SUPVMMR0REQHDR_MAGIC) */ 530 uint32_t u32Magic; 531 /** The size of the request. */ 532 uint32_t cbReq; 533 } SUPVMMR0REQHDR; 534 /** Pointer to a ring-0 request header. */ 535 typedef SUPVMMR0REQHDR *PSUPVMMR0REQHDR; 536 /** the SUPVMMR0REQHDR::u32Magic value (Ethan Iverson - The Bad Plus). */ 537 #define SUPVMMR0REQHDR_MAGIC UINT32_C(0x19730211) 538 539 540 /** For the fast ioctl path. 541 * @{ 542 */ 543 /** @see VMMR0_DO_RAW_RUN. */ 544 #define SUP_VMMR0_DO_RAW_RUN 0 545 /** @see VMMR0_DO_HM_RUN. */ 546 #define SUP_VMMR0_DO_HM_RUN 1 547 /** @see VMMR0_DO_NOP */ 548 #define SUP_VMMR0_DO_NOP 2 549 /** @} */ 550 551 /** SUPR3QueryVTCaps capability flags 552 * @{ 553 */ 554 #define SUPVTCAPS_AMD_V RT_BIT(0) 555 #define SUPVTCAPS_VT_X RT_BIT(1) 556 #define SUPVTCAPS_NESTED_PAGING RT_BIT(2) 557 /** @} */ 558 559 /** 560 * Request for generic FNSUPR0SERVICEREQHANDLER calls. 561 */ 562 typedef struct SUPR0SERVICEREQHDR 563 { 564 /** The magic. (SUPR0SERVICEREQHDR_MAGIC) */ 565 uint32_t u32Magic; 566 /** The size of the request. */ 567 uint32_t cbReq; 568 } SUPR0SERVICEREQHDR; 569 /** Pointer to a ring-0 service request header. */ 570 typedef SUPR0SERVICEREQHDR *PSUPR0SERVICEREQHDR; 571 /** the SUPVMMR0REQHDR::u32Magic value (Esbjoern Svensson - E.S.P.). */ 572 #define SUPR0SERVICEREQHDR_MAGIC UINT32_C(0x19640416) 573 574 575 /** Event semaphore handle. Ring-0 / ring-3. */ 576 typedef R0PTRTYPE(struct SUPSEMEVENTHANDLE *) SUPSEMEVENT; 577 /** Pointer to an event semaphore handle. */ 578 typedef SUPSEMEVENT *PSUPSEMEVENT; 579 /** Nil event semaphore handle. */ 580 #define NIL_SUPSEMEVENT ((SUPSEMEVENT)0) 581 582 /** 583 * Creates a single release event semaphore. 584 * 585 * @returns VBox status code. 586 * @param pSession The session handle of the caller. 587 * @param phEvent Where to return the handle to the event semaphore. 588 */ 589 SUPDECL(int) SUPSemEventCreate(PSUPDRVSESSION pSession, PSUPSEMEVENT phEvent); 590 591 /** 592 * Closes a single release event semaphore handle. 593 * 594 * @returns VBox status code. 595 * @retval VINF_OBJECT_DESTROYED if the semaphore was destroyed. 596 * @retval VINF_SUCCESS if the handle was successfully closed but the semaphore 597 * object remained alive because of other references. 598 * 599 * @param pSession The session handle of the caller. 600 * @param hEvent The handle. Nil is quietly ignored. 601 */ 602 SUPDECL(int) SUPSemEventClose(PSUPDRVSESSION pSession, SUPSEMEVENT hEvent); 603 604 /** 605 * Signals a single release event semaphore. 606 * 607 * @returns VBox status code. 608 * @param pSession The session handle of the caller. 609 * @param hEvent The semaphore handle. 610 */ 611 SUPDECL(int) SUPSemEventSignal(PSUPDRVSESSION pSession, SUPSEMEVENT hEvent); 612 613 #ifdef IN_RING0 614 /** 615 * Waits on a single release event semaphore, not interruptible. 616 * 617 * @returns VBox status code. 618 * @param pSession The session handle of the caller. 619 * @param hEvent The semaphore handle. 620 * @param cMillies The number of milliseconds to wait. 621 * @remarks Not available in ring-3. 622 */ 623 SUPDECL(int) SUPSemEventWait(PSUPDRVSESSION pSession, SUPSEMEVENT hEvent, uint32_t cMillies); 624 #endif 625 626 /** 627 * Waits on a single release event semaphore, interruptible. 628 * 629 * @returns VBox status code. 630 * @param pSession The session handle of the caller. 631 * @param hEvent The semaphore handle. 632 * @param cMillies The number of milliseconds to wait. 633 */ 634 SUPDECL(int) SUPSemEventWaitNoResume(PSUPDRVSESSION pSession, SUPSEMEVENT hEvent, uint32_t cMillies); 635 636 /** 637 * Waits on a single release event semaphore, interruptible. 638 * 639 * @returns VBox status code. 640 * @param pSession The session handle of the caller. 641 * @param hEvent The semaphore handle. 642 * @param uNsTimeout The deadline given on the RTTimeNanoTS() clock. 643 */ 644 SUPDECL(int) SUPSemEventWaitNsAbsIntr(PSUPDRVSESSION pSession, SUPSEMEVENT hEvent, uint64_t uNsTimeout); 645 646 /** 647 * Waits on a single release event semaphore, interruptible. 648 * 649 * @returns VBox status code. 650 * @param pSession The session handle of the caller. 651 * @param hEvent The semaphore handle. 652 * @param cNsTimeout The number of nanoseconds to wait. 653 */ 654 SUPDECL(int) SUPSemEventWaitNsRelIntr(PSUPDRVSESSION pSession, SUPSEMEVENT hEvent, uint64_t cNsTimeout); 655 656 /** 657 * Gets the best timeout resolution that SUPSemEventWaitNsAbsIntr and 658 * SUPSemEventWaitNsAbsIntr can do. 659 * 660 * @returns The resolution in nanoseconds. 661 * @param pSession The session handle of the caller. 662 */ 663 SUPDECL(uint32_t) SUPSemEventGetResolution(PSUPDRVSESSION pSession); 664 665 666 /** Multiple release event semaphore handle. Ring-0 / ring-3. */ 667 typedef R0PTRTYPE(struct SUPSEMEVENTMULTIHANDLE *) SUPSEMEVENTMULTI; 668 /** Pointer to an multiple release event semaphore handle. */ 669 typedef SUPSEMEVENTMULTI *PSUPSEMEVENTMULTI; 670 /** Nil multiple release event semaphore handle. */ 671 #define NIL_SUPSEMEVENTMULTI ((SUPSEMEVENTMULTI)0) 672 673 /** 674 * Creates a multiple release event semaphore. 675 * 676 * @returns VBox status code. 677 * @param pSession The session handle of the caller. 678 * @param phEventMulti Where to return the handle to the event semaphore. 679 */ 680 SUPDECL(int) SUPSemEventMultiCreate(PSUPDRVSESSION pSession, PSUPSEMEVENTMULTI phEventMulti); 681 682 /** 683 * Closes a multiple release event semaphore handle. 684 * 685 * @returns VBox status code. 686 * @retval VINF_OBJECT_DESTROYED if the semaphore was destroyed. 687 * @retval VINF_SUCCESS if the handle was successfully closed but the semaphore 688 * object remained alive because of other references. 689 * 690 * @param pSession The session handle of the caller. 691 * @param hEventMulti The handle. Nil is quietly ignored. 692 */ 693 SUPDECL(int) SUPSemEventMultiClose(PSUPDRVSESSION pSession, SUPSEMEVENTMULTI hEventMulti); 694 695 /** 696 * Signals a multiple release event semaphore. 697 * 698 * @returns VBox status code. 699 * @param pSession The session handle of the caller. 700 * @param hEventMulti The semaphore handle. 701 */ 702 SUPDECL(int) SUPSemEventMultiSignal(PSUPDRVSESSION pSession, SUPSEMEVENTMULTI hEventMulti); 703 704 /** 705 * Resets a multiple release event semaphore. 706 * 707 * @returns VBox status code. 708 * @param pSession The session handle of the caller. 709 * @param hEventMulti The semaphore handle. 710 */ 711 SUPDECL(int) SUPSemEventMultiReset(PSUPDRVSESSION pSession, SUPSEMEVENTMULTI hEventMulti); 712 713 #ifdef IN_RING0 714 /** 715 * Waits on a multiple release event semaphore, not interruptible. 716 * 717 * @returns VBox status code. 718 * @param pSession The session handle of the caller. 719 * @param hEventMulti The semaphore handle. 720 * @param cMillies The number of milliseconds to wait. 721 * @remarks Not available in ring-3. 722 */ 723 SUPDECL(int) SUPSemEventMultiWait(PSUPDRVSESSION pSession, SUPSEMEVENTMULTI hEventMulti, uint32_t cMillies); 724 #endif 725 726 /** 727 * Waits on a multiple release event semaphore, interruptible. 728 * 729 * @returns VBox status code. 730 * @param pSession The session handle of the caller. 731 * @param hEventMulti The semaphore handle. 732 * @param cMillies The number of milliseconds to wait. 733 */ 734 SUPDECL(int) SUPSemEventMultiWaitNoResume(PSUPDRVSESSION pSession, SUPSEMEVENTMULTI hEventMulti, uint32_t cMillies); 735 736 /** 737 * Waits on a multiple release event semaphore, interruptible. 738 * 739 * @returns VBox status code. 740 * @param pSession The session handle of the caller. 741 * @param hEventMulti The semaphore handle. 742 * @param uNsTimeout The deadline given on the RTTimeNanoTS() clock. 743 */ 744 SUPDECL(int) SUPSemEventMultiWaitNsAbsIntr(PSUPDRVSESSION pSession, SUPSEMEVENTMULTI hEventMulti, uint64_t uNsTimeout); 745 746 /** 747 * Waits on a multiple release event semaphore, interruptible. 748 * 749 * @returns VBox status code. 750 * @param pSession The session handle of the caller. 751 * @param hEventMulti The semaphore handle. 752 * @param cNsTimeout The number of nanoseconds to wait. 753 */ 754 SUPDECL(int) SUPSemEventMultiWaitNsRelIntr(PSUPDRVSESSION pSession, SUPSEMEVENTMULTI hEventMulti, uint64_t cNsTimeout); 755 756 /** 757 * Gets the best timeout resolution that SUPSemEventMultiWaitNsAbsIntr and 758 * SUPSemEventMultiWaitNsRelIntr can do. 759 * 760 * @returns The resolution in nanoseconds. 761 * @param pSession The session handle of the caller. 762 */ 763 SUPDECL(uint32_t) SUPSemEventMultiGetResolution(PSUPDRVSESSION pSession); 764 765 766 #ifdef IN_RING3 767 768 /** @defgroup grp_sup_r3 SUP Host Context Ring-3 API 769 * @{ 770 */ 771 772 /** 773 * Installs the support library. 774 * 775 * @returns VBox status code. 776 */ 777 SUPR3DECL(int) SUPR3Install(void); 778 779 /** 780 * Uninstalls the support library. 781 * 782 * @returns VBox status code. 783 */ 784 SUPR3DECL(int) SUPR3Uninstall(void); 785 786 /** 787 * Trusted main entry point. 788 * 789 * This is exported as "TrustedMain" by the dynamic libraries which contains the 790 * "real" application binary for which the hardened stub is built. The entry 791 * point is invoked upon successful initialization of the support library and 792 * runtime. 793 * 794 * @returns main kind of exit code. 795 * @param argc The argument count. 796 * @param argv The argument vector. 797 * @param envp The environment vector. 798 */ 799 typedef DECLCALLBACK(int) FNSUPTRUSTEDMAIN(int argc, char **argv, char **envp); 800 /** Pointer to FNSUPTRUSTEDMAIN(). */ 801 typedef FNSUPTRUSTEDMAIN *PFNSUPTRUSTEDMAIN; 802 803 /** Which operation failed. */ 804 typedef enum SUPINITOP 805 { 806 /** Invalid. */ 807 kSupInitOp_Invalid = 0, 808 /** Installation integrity error. */ 809 kSupInitOp_Integrity, 810 /** Setuid related. */ 811 kSupInitOp_RootCheck, 812 /** Driver related. */ 813 kSupInitOp_Driver, 814 /** IPRT init related. */ 815 kSupInitOp_IPRT, 816 /** Miscellaneous. */ 817 kSupInitOp_Misc, 818 /** Place holder. */ 819 kSupInitOp_End 820 } SUPINITOP; 821 822 /** 823 * Trusted error entry point, optional. 824 * 825 * This is exported as "TrustedError" by the dynamic libraries which contains 826 * the "real" application binary for which the hardened stub is built. The 827 * hardened main() must specify SUPSECMAIN_FLAGS_TRUSTED_ERROR when calling 828 * SUPR3HardenedMain. 829 * 830 * @param pszWhere Where the error occurred (function name). 831 * @param enmWhat Which operation went wrong. 832 * @param rc The status code. 833 * @param pszMsgFmt Error message format string. 834 * @param va The message format arguments. 835 */ 836 typedef DECLCALLBACK(void) FNSUPTRUSTEDERROR(const char *pszWhere, SUPINITOP enmWhat, int rc, const char *pszMsgFmt, va_list va); 837 /** Pointer to FNSUPTRUSTEDERROR. */ 838 typedef FNSUPTRUSTEDERROR *PFNSUPTRUSTEDERROR; 839 840 /** 841 * Secure main. 842 * 843 * This is used for the set-user-ID-on-execute binaries on unixy systems 844 * and when using the open-vboxdrv-via-root-service setup on Windows. 845 * 846 * This function will perform the integrity checks of the VirtualBox 847 * installation, open the support driver, open the root service (later), 848 * and load the DLL corresponding to \a pszProgName and execute its main 849 * function. 850 * 851 * @returns Return code appropriate for main(). 852 * 853 * @param pszProgName The program name. This will be used to figure out which 854 * DLL/SO/DYLIB to load and execute. 855 * @param fFlags Flags. 856 * @param argc The argument count. 857 * @param argv The argument vector. 858 * @param envp The environment vector. 859 */ 860 DECLHIDDEN(int) SUPR3HardenedMain(const char *pszProgName, uint32_t fFlags, int argc, char **argv, char **envp); 861 862 /** @name SUPR3HardenedMain flags. 863 * @{ */ 864 /** Don't open the device. (Intended for VirtualBox without -startvm.) */ 865 #define SUPSECMAIN_FLAGS_DONT_OPEN_DEV RT_BIT_32(0) 866 /** The hardened DLL has a "TrustedError" function (see FNSUPTRUSTEDERROR). */ 867 #define SUPSECMAIN_FLAGS_TRUSTED_ERROR RT_BIT_32(1) 868 /** @} */ 869 870 /** 871 * Initializes the support library. 872 * 873 * Each successful call to SUPR3Init() or SUPR3InitEx must be countered by a 874 * call to SUPR3Term(false). 875 * 876 * @returns VBox status code. 877 * @param ppSession Where to store the session handle. Defaults to NULL. 878 */ 879 SUPR3DECL(int) SUPR3Init(PSUPDRVSESSION *ppSession); 880 881 882 /** 883 * Initializes the support library, extended version. 884 * 885 * Each successful call to SUPR3Init() or SUPR3InitEx must be countered by a 886 * call to SUPR3Term(false). 887 * 888 * @returns VBox status code. 889 * @param fUnrestricted The desired access. 890 * @param ppSession Where to store the session handle. Defaults to NULL. 891 */ 892 SUPR3DECL(int) SUPR3InitEx(bool fUnrestricted, PSUPDRVSESSION *ppSession); 893 894 /** 895 * Terminates the support library. 896 * 897 * @returns VBox status code. 898 * @param fForced Forced termination. This means to ignore the 899 * init call count and just terminated. 900 */ 901 #ifdef __cplusplus 902 SUPR3DECL(int) SUPR3Term(bool fForced = false); 903 #else 904 SUPR3DECL(int) SUPR3Term(int fForced); 905 #endif 906 907 /** 908 * Sets the ring-0 VM handle for use with fast IOCtls. 909 * 910 * @returns VBox status code. 911 * @param pVMR0 The ring-0 VM handle. 912 * NIL_RTR0PTR can be used to unset the handle when the 913 * VM is about to be destroyed. 914 */ 915 SUPR3DECL(int) SUPR3SetVMForFastIOCtl(PVMR0 pVMR0); 916 917 /** 918 * Calls the HC R0 VMM entry point. 919 * See VMMR0Entry() for more details. 920 * 921 * @returns error code specific to uFunction. 922 * @param pVMR0 Pointer to the Ring-0 (Host Context) mapping of the VM structure. 923 * @param idCpu The virtual CPU ID. 924 * @param uOperation Operation to execute. 925 * @param pvArg Argument. 926 */ 927 SUPR3DECL(int) SUPR3CallVMMR0(PVMR0 pVMR0, VMCPUID idCpu, unsigned uOperation, void *pvArg); 928 929 /** 930 * Variant of SUPR3CallVMMR0, except that this takes the fast ioclt path 931 * regardsless of compile-time defaults. 932 * 933 * @returns VBox status code. 934 * @param pVMR0 The ring-0 VM handle. 935 * @param uOperation The operation; only the SUP_VMMR0_DO_* ones are valid. 936 * @param idCpu The virtual CPU ID. 937 */ 938 SUPR3DECL(int) SUPR3CallVMMR0Fast(PVMR0 pVMR0, unsigned uOperation, VMCPUID idCpu); 939 940 /** 941 * Calls the HC R0 VMM entry point, in a safer but slower manner than 942 * SUPR3CallVMMR0. When entering using this call the R0 components can call 943 * into the host kernel (i.e. use the SUPR0 and RT APIs). 944 * 945 * See VMMR0Entry() for more details. 946 * 947 * @returns error code specific to uFunction. 948 * @param pVMR0 Pointer to the Ring-0 (Host Context) mapping of the VM structure. 949 * @param idCpu The virtual CPU ID. 950 * @param uOperation Operation to execute. 951 * @param u64Arg Constant argument. 952 * @param pReqHdr Pointer to a request header. Optional. 953 * This will be copied in and out of kernel space. There currently is a size 954 * limit on this, just below 4KB. 955 */ 956 SUPR3DECL(int) SUPR3CallVMMR0Ex(PVMR0 pVMR0, VMCPUID idCpu, unsigned uOperation, uint64_t u64Arg, PSUPVMMR0REQHDR pReqHdr); 957 958 /** 959 * Calls a ring-0 service. 960 * 961 * The operation and the request packet is specific to the service. 962 * 963 * @returns error code specific to uFunction. 964 * @param pszService The service name. 965 * @param cchService The length of the service name. 966 * @param uReq The request number. 967 * @param u64Arg Constant argument. 968 * @param pReqHdr Pointer to a request header. Optional. 969 * This will be copied in and out of kernel space. There currently is a size 970 * limit on this, just below 4KB. 971 */ 972 SUPR3DECL(int) SUPR3CallR0Service(const char *pszService, size_t cchService, uint32_t uOperation, uint64_t u64Arg, PSUPR0SERVICEREQHDR pReqHdr); 973 974 /** Which logger. */ 975 typedef enum SUPLOGGER 976 { 977 SUPLOGGER_DEBUG = 1, 978 SUPLOGGER_RELEASE 979 } SUPLOGGER; 980 981 /** 982 * Changes the settings of the specified ring-0 logger. 983 * 984 * @returns VBox status code. 985 * @param enmWhich Which logger. 986 * @param pszFlags The flags settings. 987 * @param pszGroups The groups settings. 988 * @param pszDest The destination specificier. 989 */ 990 SUPR3DECL(int) SUPR3LoggerSettings(SUPLOGGER enmWhich, const char *pszFlags, const char *pszGroups, const char *pszDest); 991 992 /** 993 * Creates a ring-0 logger instance. 994 * 995 * @returns VBox status code. 996 * @param enmWhich Which logger to create. 997 * @param pszFlags The flags settings. 998 * @param pszGroups The groups settings. 999 * @param pszDest The destination specificier. 1000 */ 1001 SUPR3DECL(int) SUPR3LoggerCreate(SUPLOGGER enmWhich, const char *pszFlags, const char *pszGroups, const char *pszDest); 1002 1003 /** 1004 * Destroys a ring-0 logger instance. 1005 * 1006 * @returns VBox status code. 1007 * @param enmWhich Which logger. 1008 */ 1009 SUPR3DECL(int) SUPR3LoggerDestroy(SUPLOGGER enmWhich); 1010 1011 /** 1012 * Queries the paging mode of the host OS. 1013 * 1014 * @returns The paging mode. 1015 */ 1016 SUPR3DECL(SUPPAGINGMODE) SUPR3GetPagingMode(void); 1017 1018 /** 1019 * Allocate zero-filled pages. 1020 * 1021 * Use this to allocate a number of pages suitable for seeding / locking. 1022 * Call SUPR3PageFree() to free the pages once done with them. 1023 * 1024 * @returns VBox status. 1025 * @param cPages Number of pages to allocate. 1026 * @param ppvPages Where to store the base pointer to the allocated pages. 1027 */ 1028 SUPR3DECL(int) SUPR3PageAlloc(size_t cPages, void **ppvPages); 1029 1030 /** 1031 * Frees pages allocated with SUPR3PageAlloc(). 1032 * 1033 * @returns VBox status. 1034 * @param pvPages Pointer returned by SUPR3PageAlloc(). 1035 * @param cPages Number of pages that was allocated. 1036 */ 1037 SUPR3DECL(int) SUPR3PageFree(void *pvPages, size_t cPages); 1038 1039 /** 1040 * Allocate non-zeroed, locked, pages with user and, optionally, kernel 1041 * mappings. 1042 * 1043 * Use SUPR3PageFreeEx() to free memory allocated with this function. 1044 * 1045 * @returns VBox status code. 1046 * @param cPages The number of pages to allocate. 1047 * @param fFlags Flags, reserved. Must be zero. 1048 * @param ppvPages Where to store the address of the user mapping. 1049 * @param pR0Ptr Where to store the address of the kernel mapping. 1050 * NULL if no kernel mapping is desired. 1051 * @param paPages Where to store the physical addresses of each page. 1052 * Optional. 1053 */ 1054 SUPR3DECL(int) SUPR3PageAllocEx(size_t cPages, uint32_t fFlags, void **ppvPages, PRTR0PTR pR0Ptr, PSUPPAGE paPages); 1055 1056 /** 1057 * Maps a portion of a ring-3 only allocation into kernel space. 1058 * 1059 * @returns VBox status code. 1060 * 1061 * @param pvR3 The address SUPR3PageAllocEx return. 1062 * @param off Offset to start mapping at. Must be page aligned. 1063 * @param cb Number of bytes to map. Must be page aligned. 1064 * @param fFlags Flags, must be zero. 1065 * @param pR0Ptr Where to store the address on success. 1066 * 1067 */ 1068 SUPR3DECL(int) SUPR3PageMapKernel(void *pvR3, uint32_t off, uint32_t cb, uint32_t fFlags, PRTR0PTR pR0Ptr); 1069 1070 /** 1071 * Changes the protection of 1072 * 1073 * @returns VBox status code. 1074 * @retval VERR_NOT_SUPPORTED if the OS doesn't allow us to change page level 1075 * protection. See also RTR0MemObjProtect. 1076 * 1077 * @param pvR3 The ring-3 address SUPR3PageAllocEx returned. 1078 * @param R0Ptr The ring-0 address SUPR3PageAllocEx returned if it 1079 * is desired that the corresponding ring-0 page 1080 * mappings should change protection as well. Pass 1081 * NIL_RTR0PTR if the ring-0 pages should remain 1082 * unaffected. 1083 * @param off Offset to start at which to start chagning the page 1084 * level protection. Must be page aligned. 1085 * @param cb Number of bytes to change. Must be page aligned. 1086 * @param fProt The new page level protection, either a combination 1087 * of RTMEM_PROT_READ, RTMEM_PROT_WRITE and 1088 * RTMEM_PROT_EXEC, or just RTMEM_PROT_NONE. 1089 */ 1090 SUPR3DECL(int) SUPR3PageProtect(void *pvR3, RTR0PTR R0Ptr, uint32_t off, uint32_t cb, uint32_t fProt); 1091 1092 /** 1093 * Free pages allocated by SUPR3PageAllocEx. 1094 * 1095 * @returns VBox status code. 1096 * @param pvPages The address of the user mapping. 1097 * @param cPages The number of pages. 1098 */ 1099 SUPR3DECL(int) SUPR3PageFreeEx(void *pvPages, size_t cPages); 1100 1101 /** 1102 * Allocated memory with page aligned memory with a contiguous and locked physical 1103 * memory backing below 4GB. 1104 * 1105 * @returns Pointer to the allocated memory (virtual address). 1106 * *pHCPhys is set to the physical address of the memory. 1107 * If ppvR0 isn't NULL, *ppvR0 is set to the ring-0 mapping. 1108 * The returned memory must be freed using SUPR3ContFree(). 1109 * @returns NULL on failure. 1110 * @param cPages Number of pages to allocate. 1111 * @param pR0Ptr Where to store the ring-0 mapping of the allocation. (optional) 1112 * @param pHCPhys Where to store the physical address of the memory block. 1113 * 1114 * @remark This 2nd version of this API exists because we're not able to map the 1115 * ring-3 mapping executable on WIN64. This is a serious problem in regard to 1116 * the world switchers. 1117 */ 1118 SUPR3DECL(void *) SUPR3ContAlloc(size_t cPages, PRTR0PTR pR0Ptr, PRTHCPHYS pHCPhys); 1119 1120 /** 1121 * Frees memory allocated with SUPR3ContAlloc(). 1122 * 1123 * @returns VBox status code. 1124 * @param pv Pointer to the memory block which should be freed. 1125 * @param cPages Number of pages to be freed. 1126 */ 1127 SUPR3DECL(int) SUPR3ContFree(void *pv, size_t cPages); 1128 1129 /** 1130 * Allocated non contiguous physical memory below 4GB. 1131 * 1132 * The memory isn't zeroed. 1133 * 1134 * @returns VBox status code. 1135 * @returns NULL on failure. 1136 * @param cPages Number of pages to allocate. 1137 * @param ppvPages Where to store the pointer to the allocated memory. 1138 * The pointer stored here on success must be passed to 1139 * SUPR3LowFree when the memory should be released. 1140 * @param ppvPagesR0 Where to store the ring-0 pointer to the allocated memory. optional. 1141 * @param paPages Where to store the physical addresses of the individual pages. 1142 */ 1143 SUPR3DECL(int) SUPR3LowAlloc(size_t cPages, void **ppvPages, PRTR0PTR ppvPagesR0, PSUPPAGE paPages); 1144 1145 /** 1146 * Frees memory allocated with SUPR3LowAlloc(). 1147 * 1148 * @returns VBox status code. 1149 * @param pv Pointer to the memory block which should be freed. 1150 * @param cPages Number of pages that was allocated. 1151 */ 1152 SUPR3DECL(int) SUPR3LowFree(void *pv, size_t cPages); 1153 1154 /** 1155 * Load a module into R0 HC. 1156 * 1157 * This will verify the file integrity in a similar manner as 1158 * SUPR3HardenedVerifyFile before loading it. 1159 * 1160 * @returns VBox status code. 1161 * @param pszFilename The path to the image file. 1162 * @param pszModule The module name. Max 32 bytes. 1163 * @param ppvImageBase Where to store the image address. 1164 * @param pErrInfo Where to return extended error information. 1165 * Optional. 1166 */ 1167 SUPR3DECL(int) SUPR3LoadModule(const char *pszFilename, const char *pszModule, void **ppvImageBase, PRTERRINFO pErrInfo); 1168 1169 /** 1170 * Load a module into R0 HC. 1171 * 1172 * This will verify the file integrity in a similar manner as 1173 * SUPR3HardenedVerifyFile before loading it. 1174 * 1175 * @returns VBox status code. 1176 * @param pszFilename The path to the image file. 1177 * @param pszModule The module name. Max 32 bytes. 1178 * @param pszSrvReqHandler The name of the service request handler entry 1179 * point. See FNSUPR0SERVICEREQHANDLER. 1180 * @param ppvImageBase Where to store the image address. 1181 */ 1182 SUPR3DECL(int) SUPR3LoadServiceModule(const char *pszFilename, const char *pszModule, 1183 const char *pszSrvReqHandler, void **ppvImageBase); 1184 1185 /** 1186 * Frees a R0 HC module. 1187 * 1188 * @returns VBox status code. 1189 * @param pszModule The module to free. 1190 * @remark This will not actually 'free' the module, there are of course usage counting. 1191 */ 1192 SUPR3DECL(int) SUPR3FreeModule(void *pvImageBase); 1193 1194 /** 1195 * Lock down the module loader interface. 1196 * 1197 * This will lock down the module loader interface. No new modules can be 1198 * loaded and all loaded modules can no longer be freed. 1199 * 1200 * @returns VBox status code. 1201 * @param pErrInfo Where to return extended error information. 1202 * Optional. 1203 */ 1204 SUPR3DECL(int) SUPR3LockDownLoader(PRTERRINFO pErrInfo); 1205 1206 /** 1207 * Get the address of a symbol in a ring-0 module. 1208 * 1209 * @returns VBox status code. 1210 * @param pszModule The module name. 1211 * @param pszSymbol Symbol name. If it's value is less than 64k it's treated like a 1212 * ordinal value rather than a string pointer. 1213 * @param ppvValue Where to store the symbol value. 1214 */ 1215 SUPR3DECL(int) SUPR3GetSymbolR0(void *pvImageBase, const char *pszSymbol, void **ppvValue); 1216 1217 /** 1218 * Load R0 HC VMM code. 1219 * 1220 * @returns VBox status code. 1221 * @deprecated Use SUPR3LoadModule(pszFilename, "VMMR0.r0", &pvImageBase) 1222 */ 1223 SUPR3DECL(int) SUPR3LoadVMM(const char *pszFilename); 1224 1225 /** 1226 * Unloads R0 HC VMM code. 1227 * 1228 * @returns VBox status code. 1229 * @deprecated Use SUPR3FreeModule(). 1230 */ 1231 SUPR3DECL(int) SUPR3UnloadVMM(void); 1232 1233 /** 1234 * Get the physical address of the GIP. 1235 * 1236 * @returns VBox status code. 1237 * @param pHCPhys Where to store the physical address of the GIP. 1238 */ 1239 SUPR3DECL(int) SUPR3GipGetPhys(PRTHCPHYS pHCPhys); 1240 1241 /** 1242 * Initializes only the bits relevant for the SUPR3HardenedVerify* APIs. 1243 * 1244 * This is for users that don't necessarily need to initialize the whole of 1245 * SUPLib. There is no harm in calling this one more time. 1246 * 1247 * @returns VBox status code. 1248 * @remarks Currently not counted, so only call once. 1249 */ 1250 SUPR3DECL(int) SUPR3HardenedVerifyInit(void); 1251 1252 /** 1253 * Reverses the effect of SUPR3HardenedVerifyInit if SUPR3InitEx hasn't been 1254 * called. 1255 * 1256 * Ignored if the support library was initialized using SUPR3Init or 1257 * SUPR3InitEx. 1258 * 1259 * @returns VBox status code. 1260 */ 1261 SUPR3DECL(int) SUPR3HardenedVerifyTerm(void); 1262 1263 /** 1264 * Verifies the integrity of a file, and optionally opens it. 1265 * 1266 * The integrity check is for whether the file is suitable for loading into 1267 * the hypervisor or VM process. The integrity check may include verifying 1268 * the authenticode/elfsign/whatever signature of the file, which can take 1269 * a little while. 1270 * 1271 * @returns VBox status code. On failure it will have printed a LogRel message. 1272 * 1273 * @param pszFilename The file. 1274 * @param pszWhat For the LogRel on failure. 1275 * @param phFile Where to store the handle to the opened file. This is optional, pass NULL 1276 * if the file should not be opened. 1277 * @deprecated Write a new one. 1278 */ 1279 SUPR3DECL(int) SUPR3HardenedVerifyFile(const char *pszFilename, const char *pszWhat, PRTFILE phFile); 1280 1281 /** 1282 * Verifies the integrity of a the current process, including the image 1283 * location and that the invocation was absolute. 1284 * 1285 * This must currently be called after initializing the runtime. The intended 1286 * audience is set-uid-to-root applications, root services and similar. 1287 * 1288 * @returns VBox status code. On failure 1289 * message. 1290 * @param pszArgv0 The first argument to main(). 1291 * @param fInternal Set this to @c true if this is an internal 1292 * VirtualBox application. Otherwise pass @c false. 1293 * @param pErrInfo Where to return extended error information. 1294 */ 1295 SUPR3DECL(int) SUPR3HardenedVerifySelf(const char *pszArgv0, bool fInternal, PRTERRINFO pErrInfo); 1296 1297 /** 1298 * Verifies the integrity of an installation directory. 1299 * 1300 * The integrity check verifies that the directory cannot be tampered with by 1301 * normal users on the system. On Unix this translates to root ownership and 1302 * no symbolic linking. 1303 * 1304 * @returns VBox status code. On failure a message will be stored in @a pszErr. 1305 * 1306 * @param pszDirPath The directory path. 1307 * @param fRecursive Whether the check should be recursive or 1308 * not. When set, all sub-directores will be checked, 1309 * including files (@a fCheckFiles is ignored). 1310 * @param fCheckFiles Whether to apply the same basic integrity check to 1311 * the files in the directory as the directory itself. 1312 * @param pErrInfo Where to return extended error information. 1313 * Optional. 1314 */ 1315 SUPR3DECL(int) SUPR3HardenedVerifyDir(const char *pszDirPath, bool fRecursive, bool fCheckFiles, PRTERRINFO pErrInfo); 1316 1317 /** 1318 * Verifies the integrity of a plug-in module. 1319 * 1320 * This is similar to SUPR3HardenedLdrLoad, except it does not load the module 1321 * and that the module does not have to be shipped with VirtualBox. 1322 * 1323 * @returns VBox status code. On failure a message will be stored in @a pszErr. 1324 * 1325 * @param pszFilename The filename of the plug-in module (nothing can be 1326 * omitted here). 1327 * @param pErrInfo Where to return extended error information. 1328 * Optional. 1329 */ 1330 SUPR3DECL(int) SUPR3HardenedVerifyPlugIn(const char *pszFilename, PRTERRINFO pErrInfo); 1331 1332 /** 1333 * Same as RTLdrLoad() but will verify the files it loads (hardened builds). 1334 * 1335 * Will add dll suffix if missing and try load the file. 1336 * 1337 * @returns iprt status code. 1338 * @param pszFilename Image filename. This must have a path. 1339 * @param phLdrMod Where to store the handle to the loaded module. 1340 * @param fFlags See RTLDRLOAD_FLAGS_XXX. 1341 * @param pErrInfo Where to return extended error information. 1342 * Optional. 1343 */ 1344 SUPR3DECL(int) SUPR3HardenedLdrLoad(const char *pszFilename, PRTLDRMOD phLdrMod, uint32_t fFlags, PRTERRINFO pErrInfo); 1345 1346 /** 1347 * Same as RTLdrLoadAppPriv() but it will verify the files it loads (hardened 1348 * builds). 1349 * 1350 * Will add dll suffix to the file if missing, then look for it in the 1351 * architecture dependent application directory. 1352 * 1353 * @returns iprt status code. 1354 * @param pszFilename Image filename. 1355 * @param phLdrMod Where to store the handle to the loaded module. 1356 * @param fFlags See RTLDRLOAD_FLAGS_XXX. 1357 * @param pErrInfo Where to return extended error information. 1358 * Optional. 1359 */ 1360 SUPR3DECL(int) SUPR3HardenedLdrLoadAppPriv(const char *pszFilename, PRTLDRMOD phLdrMod, uint32_t fFlags, PRTERRINFO pErrInfo); 1361 1362 /** 1363 * Same as RTLdrLoad() but will verify the files it loads (hardened builds). 1364 * 1365 * This differs from SUPR3HardenedLdrLoad() in that it can load modules from 1366 * extension packs and anything else safely installed on the system, provided 1367 * they pass the hardening tests. 1368 * 1369 * @returns iprt status code. 1370 * @param pszFilename The full path to the module, with extension. 1371 * @param phLdrMod Where to store the handle to the loaded module. 1372 * @param pErrInfo Where to return extended error information. 1373 * Optional. 1374 */ 1375 SUPR3DECL(int) SUPR3HardenedLdrLoadPlugIn(const char *pszFilename, PRTLDRMOD phLdrMod, PRTERRINFO pErrInfo); 1376 1377 /** 1378 * Check if the host kernel can run in VMX root mode. 1379 * 1380 * @returns VINF_SUCCESS if supported, error code indicating why if not. 1381 */ 1382 SUPR3DECL(int) SUPR3QueryVTxSupported(void); 1383 1384 /** 1385 * Return VT-x/AMD-V capabilities. 1386 * 1387 * @returns VINF_SUCCESS if supported, error code indicating why if not. 1388 * @param pfCaps Pointer to capability dword (out). 1389 * @todo Intended for main, which means we need to relax the privilege requires 1390 * when accessing certain vboxdrv functions. 1391 */ 1392 SUPR3DECL(int) SUPR3QueryVTCaps(uint32_t *pfCaps); 1393 1394 /** 1395 * Open the tracer. 1396 * 1397 * @returns VBox status code. 1398 * @param uCookie Cookie identifying the tracer we expect to talk to. 1399 * @param uArg Tracer specific open argument. 1400 */ 1401 SUPR3DECL(int) SUPR3TracerOpen(uint32_t uCookie, uintptr_t uArg); 1402 1403 /** 1404 * Closes the tracer. 1405 * 1406 * @returns VBox status code. 1407 */ 1408 SUPR3DECL(int) SUPR3TracerClose(void); 1409 1410 /** 1411 * Perform an I/O request on the tracer. 1412 * 1413 * @returns VBox status. 1414 * @param uCmd The tracer command. 1415 * @param uArg The argument. 1416 * @param piRetVal Where to store the tracer return value. 1417 */ 1418 SUPR3DECL(int) SUPR3TracerIoCtl(uintptr_t uCmd, uintptr_t uArg, int32_t *piRetVal); 1419 1420 /** 1421 * Registers the user module with the tracer. 1422 * 1423 * @returns VBox status code. 1424 * @param hModNative Native module handle. Pass ~(uintptr_t)0 if not 1425 * at hand. 1426 * @param pszModule The module name. 1427 * @param pVtgHdr The VTG header. 1428 * @param uVtgHdrAddr The address to which the VTG header is loaded 1429 * in the relevant execution context. 1430 * @param fFlags See SUP_TRACER_UMOD_FLAGS_XXX 1431 */ 1432 SUPR3DECL(int) SUPR3TracerRegisterModule(uintptr_t hModNative, const char *pszModule, struct VTGOBJHDR *pVtgHdr, 1433 RTUINTPTR uVtgHdrAddr, uint32_t fFlags); 1434 1435 /** 1436 * Deregisters the user module. 1437 * 1438 * @returns VBox status code. 1439 * @param pVtgHdr The VTG header. 1440 */ 1441 SUPR3DECL(int) SUPR3TracerDeregisterModule(struct VTGOBJHDR *pVtgHdr); 1442 1443 /** 1444 * Fire the probe. 1445 * 1446 * @param pVtgProbeLoc The probe location record. 1447 * @param uArg0 Raw probe argument 0. 1448 * @param uArg1 Raw probe argument 1. 1449 * @param uArg2 Raw probe argument 2. 1450 * @param uArg3 Raw probe argument 3. 1451 * @param uArg4 Raw probe argument 4. 1452 */ 1453 SUPDECL(void) SUPTracerFireProbe(struct VTGPROBELOC *pVtgProbeLoc, uintptr_t uArg0, uintptr_t uArg1, uintptr_t uArg2, 1454 uintptr_t uArg3, uintptr_t uArg4); 1455 1456 1457 /** 1458 * Attempts to read the value of an MSR. 1459 * 1460 * @returns VBox status code. 1461 * @param uMsr The MSR to read. 1462 * @param idCpu The CPU to read it on, NIL_RTCPUID if it doesn't 1463 * matter which CPU. 1464 * @param puValue Where to return the value. 1465 * @param pfGp Where to store the \#GP indicator for the read 1466 * operation. 1467 */ 1468 SUPR3DECL(int) SUPR3MsrProberRead(uint32_t uMsr, RTCPUID idCpu, uint64_t *puValue, bool *pfGp); 1469 1470 /** 1471 * Attempts to write to an MSR. 1472 * 1473 * @returns VBox status code. 1474 * @param uMsr The MSR to write to. 1475 * @param idCpu The CPU to wrtie it on, NIL_RTCPUID if it 1476 * doesn't matter which CPU. 1477 * @param uValue The value to write. 1478 * @param pfGp Where to store the \#GP indicator for the write 1479 * operation. 1480 */ 1481 SUPR3DECL(int) SUPR3MsrProberWrite(uint32_t uMsr, RTCPUID idCpu, uint64_t uValue, bool *pfGp); 1482 1483 /** 1484 * Attempts to modify the value of an MSR. 1485 * 1486 * @returns VBox status code. 1487 * @param uMsr The MSR to modify. 1488 * @param idCpu The CPU to modify it on, NIL_RTCPUID if it 1489 * doesn't matter which CPU. 1490 * @param fAndMask The bits to keep in the current MSR value. 1491 * @param fOrMask The bits to set before writing. 1492 * @param pResult The result buffer. 1493 */ 1494 SUPR3DECL(int) SUPR3MsrProberModify(uint32_t uMsr, RTCPUID idCpu, uint64_t fAndMask, uint64_t fOrMask, 1495 PSUPMSRPROBERMODIFYRESULT pResult); 1496 1497 /** 1498 * Attempts to modify the value of an MSR, extended version. 1499 * 1500 * @returns VBox status code. 1501 * @param uMsr The MSR to modify. 1502 * @param idCpu The CPU to modify it on, NIL_RTCPUID if it 1503 * doesn't matter which CPU. 1504 * @param fAndMask The bits to keep in the current MSR value. 1505 * @param fOrMask The bits to set before writing. 1506 * @param fFaster If set to @c true some cache/tlb invalidation is 1507 * skipped, otherwise behave like 1508 * SUPR3MsrProberModify. 1509 * @param pResult The result buffer. 1510 */ 1511 SUPR3DECL(int) SUPR3MsrProberModifyEx(uint32_t uMsr, RTCPUID idCpu, uint64_t fAndMask, uint64_t fOrMask, bool fFaster, 1512 PSUPMSRPROBERMODIFYRESULT pResult); 1513 1514 /** 1515 * Resume built-in keyboard on MacBook Air and Pro hosts. 1516 * 1517 * @returns VBox status code. 1518 */ 1519 SUPR3DECL(int) SUPR3ResumeSuspendedKeyboards(void); 1520 1521 1522 /** 1523 * Measure the TSC-delta for the specified CPU. 1524 * 1525 * @returns VBox status code. 1526 * @param idCpu The CPU to measure the TSC-delta for. 1527 * @param fAsync Whether the measurement is asynchronous, returns 1528 * immediately after signalling a measurement 1529 * request. 1530 * @param fForce Whether to perform a measurement even if the 1531 * specified CPU has a (possibly) valid TSC delta. 1532 * @param cRetries Number of times to retry failed delta 1533 * measurements. 1534 * @param cMsWaitRetry Number of milliseconds to wait between retries. 1535 */ 1536 SUPR3DECL(int) SUPR3TscDeltaMeasure(RTCPUID idCpu, bool fAsync, bool fForce, uint8_t cRetries, uint8_t cMsWaitRetry); 1537 1538 /** 1539 * Reads the delta-adjust TSC value. 1540 * 1541 * @returns VBox status code. 1542 * @param puTsc Where to store the read TSC value. 1543 * @param pidApic Where to store the APIC ID of the CPU where the TSC 1544 * was read (optional, can be NULL). 1545 */ 1546 SUPR3DECL(int) SUPR3ReadTsc(uint64_t *puTsc, uint16_t *pidApic); 1547 1548 /** @} */ 1549 #endif /* IN_RING3 */ 1550 1551 1552 /** 1553 * Gets the descriptive GIP mode name. 1554 * 1555 * @returns The name. 1556 * @param pGip Pointer to the GIP. 1557 */ 1558 DECLINLINE(const char *) SUPGetGIPModeName(PSUPGLOBALINFOPAGE pGip) 1559 { 1560 AssertReturn(pGip, NULL); 1561 switch (pGip->u32Mode) 520 521 522 /** 523 * Gets the TSC frequency of the specified CPU. 524 * 525 * @returns TSC frequency, UINT64_MAX on failure. 526 * @param pGip The GIP pointer. 527 * @param iCpuSet The CPU set index of the CPU in question. 528 */ 529 DECLINLINE(uint64_t) SUPGetCpuHzFromGipBySetIndex(PSUPGLOBALINFOPAGE pGip, uint32_t iCpuSet) 530 { 531 if (RT_LIKELY( pGip 532 && pGip->u32Magic == SUPGLOBALINFOPAGE_MAGIC 533 && pGip->u64CpuHz)) 1562 534 { 1563 case SUPGIPMODE_INVARIANT_TSC: return "Invariant"; 1564 case SUPGIPMODE_SYNC_TSC: return "Synchronous"; 1565 case SUPGIPMODE_ASYNC_TSC: return "Asynchronous"; 1566 case SUPGIPMODE_INVALID: return "Invalid"; 1567 default: return "???"; 535 switch (pGip->u32Mode) 536 { 537 case SUPGIPMODE_INVARIANT_TSC: 538 case SUPGIPMODE_SYNC_TSC: 539 return pGip->aCPUs[0].u64CpuHz; 540 case SUPGIPMODE_ASYNC_TSC: 541 if (RT_LIKELY(iCpuSet < RT_ELEMENTS(pGip->aiCpuFromCpuSetIdx))) 542 { 543 uint16_t iCpu = pGip->aiCpuFromCpuSetIdx[iCpuSet]; 544 if (RT_LIKELY(iCpu < pGip->cCpus)) 545 return pGip->aCPUs[iCpu].u64CpuHz; 546 } 547 break; 548 default: break; /* shut up gcc */ 549 } 1568 550 } 551 AssertFailed(); 552 return UINT64_MAX; 1569 553 } 1570 554 … … 1600 584 1601 585 /** @internal */ 1602 SUPDECL(uint64_t) SUPReadTscWithDelta(void); 1603 1604 /** 1605 * Reads the host TSC value. 1606 * 1607 * If applicable, normalizes the host TSC value with intercpu TSC deltas. 586 SUPDECL(uint64_t) SUPReadTscWithDelta(PSUPGLOBALINFOPAGE pGip); 587 588 /** 589 * Read the host TSC value and applies the TSC delta if appropriate. 1608 590 * 1609 591 * @returns the TSC value. 1610 * 1611 * @remarks Requires GIP to be initialized. 592 * @remarks Requires GIP to be initialized and valid. 1612 593 */ 1613 594 DECLINLINE(uint64_t) SUPReadTsc(void) 1614 595 { 1615 if (g_pSUPGlobalInfoPage->enmUseTscDelta <= SUPGIPUSETSCDELTA_ROUGHLY_ZERO) 596 PSUPGLOBALINFOPAGE pGip = g_pSUPGlobalInfoPage; 597 if (pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_ROUGHLY_ZERO) 1616 598 return ASMReadTSC(); 1617 return SUPReadTscWithDelta( );599 return SUPReadTscWithDelta(pGip); 1618 600 } 1619 601 1620 602 #endif /* X86 || AMD64 */ 603 604 /** @internal */ 605 SUPDECL(uint64_t) SUPGetTscDeltaSlow(PSUPGLOBALINFOPAGE pGip); 606 607 /** 608 * Gets the TSC delta for the current CPU. 609 * 610 * @returns The TSC delta value (will not return the special INT64_MAX value). 611 * @remarks Requires GIP to be initialized and valid. 612 */ 613 DECLINLINE(int64_t) SUPGetTscDelta(void) 614 { 615 PSUPGLOBALINFOPAGE pGip = g_pSUPGlobalInfoPage; 616 if (pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_ROUGHLY_ZERO) 617 return 0; 618 return SUPGetTscDeltaSlow(pGip); 619 } 620 621 622 /** 623 * Gets the TSC delta for a given CPU. 624 * 625 * @returns The TSC delta value (will not return the special INT64_MAX value). 626 * @param iCpuSet The CPU set index of the CPU which TSC delta we want. 627 * @remarks Requires GIP to be initialized and valid. 628 */ 629 DECLINLINE(int64_t) SUPGetTscDeltaByCpuSetIndex(uint32_t iCpuSet) 630 { 631 PSUPGLOBALINFOPAGE pGip = g_pSUPGlobalInfoPage; 632 if (pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_ROUGHLY_ZERO) 633 return 0; 634 if (RT_LIKELY(iCpuSet < RT_ELEMENTS(pGip->aiCpuFromCpuSetIdx))) 635 { 636 uint16_t iCpu = pGip->aiCpuFromCpuSetIdx[iCpuSet]; 637 if (RT_LIKELY(iCpu < pGip->cCpus)) 638 { 639 int64_t iTscDelta = pGip->aCPUs[iCpu].i64TSCDelta; 640 if (iTscDelta != INT64_MAX) 641 return iTscDelta; 642 } 643 } 644 AssertFailed(); 645 return 0; 646 } 647 648 649 /** 650 * Gets the descriptive GIP mode name. 651 * 652 * @returns The name. 653 * @param pGip Pointer to the GIP. 654 */ 655 DECLINLINE(const char *) SUPGetGIPModeName(PSUPGLOBALINFOPAGE pGip) 656 { 657 AssertReturn(pGip, NULL); 658 switch (pGip->u32Mode) 659 { 660 case SUPGIPMODE_INVARIANT_TSC: return "Invariant"; 661 case SUPGIPMODE_SYNC_TSC: return "Synchronous"; 662 case SUPGIPMODE_ASYNC_TSC: return "Asynchronous"; 663 case SUPGIPMODE_INVALID: return "Invalid"; 664 default: return "???"; 665 } 666 } 667 668 669 /** 670 * Request for generic VMMR0Entry calls. 671 */ 672 typedef struct SUPVMMR0REQHDR 673 { 674 /** The magic. (SUPVMMR0REQHDR_MAGIC) */ 675 uint32_t u32Magic; 676 /** The size of the request. */ 677 uint32_t cbReq; 678 } SUPVMMR0REQHDR; 679 /** Pointer to a ring-0 request header. */ 680 typedef SUPVMMR0REQHDR *PSUPVMMR0REQHDR; 681 /** the SUPVMMR0REQHDR::u32Magic value (Ethan Iverson - The Bad Plus). */ 682 #define SUPVMMR0REQHDR_MAGIC UINT32_C(0x19730211) 683 684 685 /** For the fast ioctl path. 686 * @{ 687 */ 688 /** @see VMMR0_DO_RAW_RUN. */ 689 #define SUP_VMMR0_DO_RAW_RUN 0 690 /** @see VMMR0_DO_HM_RUN. */ 691 #define SUP_VMMR0_DO_HM_RUN 1 692 /** @see VMMR0_DO_NOP */ 693 #define SUP_VMMR0_DO_NOP 2 694 /** @} */ 695 696 /** SUPR3QueryVTCaps capability flags 697 * @{ 698 */ 699 #define SUPVTCAPS_AMD_V RT_BIT(0) 700 #define SUPVTCAPS_VT_X RT_BIT(1) 701 #define SUPVTCAPS_NESTED_PAGING RT_BIT(2) 702 /** @} */ 703 704 /** 705 * Request for generic FNSUPR0SERVICEREQHANDLER calls. 706 */ 707 typedef struct SUPR0SERVICEREQHDR 708 { 709 /** The magic. (SUPR0SERVICEREQHDR_MAGIC) */ 710 uint32_t u32Magic; 711 /** The size of the request. */ 712 uint32_t cbReq; 713 } SUPR0SERVICEREQHDR; 714 /** Pointer to a ring-0 service request header. */ 715 typedef SUPR0SERVICEREQHDR *PSUPR0SERVICEREQHDR; 716 /** the SUPVMMR0REQHDR::u32Magic value (Esbjoern Svensson - E.S.P.). */ 717 #define SUPR0SERVICEREQHDR_MAGIC UINT32_C(0x19640416) 718 719 720 /** Event semaphore handle. Ring-0 / ring-3. */ 721 typedef R0PTRTYPE(struct SUPSEMEVENTHANDLE *) SUPSEMEVENT; 722 /** Pointer to an event semaphore handle. */ 723 typedef SUPSEMEVENT *PSUPSEMEVENT; 724 /** Nil event semaphore handle. */ 725 #define NIL_SUPSEMEVENT ((SUPSEMEVENT)0) 726 727 /** 728 * Creates a single release event semaphore. 729 * 730 * @returns VBox status code. 731 * @param pSession The session handle of the caller. 732 * @param phEvent Where to return the handle to the event semaphore. 733 */ 734 SUPDECL(int) SUPSemEventCreate(PSUPDRVSESSION pSession, PSUPSEMEVENT phEvent); 735 736 /** 737 * Closes a single release event semaphore handle. 738 * 739 * @returns VBox status code. 740 * @retval VINF_OBJECT_DESTROYED if the semaphore was destroyed. 741 * @retval VINF_SUCCESS if the handle was successfully closed but the semaphore 742 * object remained alive because of other references. 743 * 744 * @param pSession The session handle of the caller. 745 * @param hEvent The handle. Nil is quietly ignored. 746 */ 747 SUPDECL(int) SUPSemEventClose(PSUPDRVSESSION pSession, SUPSEMEVENT hEvent); 748 749 /** 750 * Signals a single release event semaphore. 751 * 752 * @returns VBox status code. 753 * @param pSession The session handle of the caller. 754 * @param hEvent The semaphore handle. 755 */ 756 SUPDECL(int) SUPSemEventSignal(PSUPDRVSESSION pSession, SUPSEMEVENT hEvent); 757 758 #ifdef IN_RING0 759 /** 760 * Waits on a single release event semaphore, not interruptible. 761 * 762 * @returns VBox status code. 763 * @param pSession The session handle of the caller. 764 * @param hEvent The semaphore handle. 765 * @param cMillies The number of milliseconds to wait. 766 * @remarks Not available in ring-3. 767 */ 768 SUPDECL(int) SUPSemEventWait(PSUPDRVSESSION pSession, SUPSEMEVENT hEvent, uint32_t cMillies); 769 #endif 770 771 /** 772 * Waits on a single release event semaphore, interruptible. 773 * 774 * @returns VBox status code. 775 * @param pSession The session handle of the caller. 776 * @param hEvent The semaphore handle. 777 * @param cMillies The number of milliseconds to wait. 778 */ 779 SUPDECL(int) SUPSemEventWaitNoResume(PSUPDRVSESSION pSession, SUPSEMEVENT hEvent, uint32_t cMillies); 780 781 /** 782 * Waits on a single release event semaphore, interruptible. 783 * 784 * @returns VBox status code. 785 * @param pSession The session handle of the caller. 786 * @param hEvent The semaphore handle. 787 * @param uNsTimeout The deadline given on the RTTimeNanoTS() clock. 788 */ 789 SUPDECL(int) SUPSemEventWaitNsAbsIntr(PSUPDRVSESSION pSession, SUPSEMEVENT hEvent, uint64_t uNsTimeout); 790 791 /** 792 * Waits on a single release event semaphore, interruptible. 793 * 794 * @returns VBox status code. 795 * @param pSession The session handle of the caller. 796 * @param hEvent The semaphore handle. 797 * @param cNsTimeout The number of nanoseconds to wait. 798 */ 799 SUPDECL(int) SUPSemEventWaitNsRelIntr(PSUPDRVSESSION pSession, SUPSEMEVENT hEvent, uint64_t cNsTimeout); 800 801 /** 802 * Gets the best timeout resolution that SUPSemEventWaitNsAbsIntr and 803 * SUPSemEventWaitNsAbsIntr can do. 804 * 805 * @returns The resolution in nanoseconds. 806 * @param pSession The session handle of the caller. 807 */ 808 SUPDECL(uint32_t) SUPSemEventGetResolution(PSUPDRVSESSION pSession); 809 810 811 /** Multiple release event semaphore handle. Ring-0 / ring-3. */ 812 typedef R0PTRTYPE(struct SUPSEMEVENTMULTIHANDLE *) SUPSEMEVENTMULTI; 813 /** Pointer to an multiple release event semaphore handle. */ 814 typedef SUPSEMEVENTMULTI *PSUPSEMEVENTMULTI; 815 /** Nil multiple release event semaphore handle. */ 816 #define NIL_SUPSEMEVENTMULTI ((SUPSEMEVENTMULTI)0) 817 818 /** 819 * Creates a multiple release event semaphore. 820 * 821 * @returns VBox status code. 822 * @param pSession The session handle of the caller. 823 * @param phEventMulti Where to return the handle to the event semaphore. 824 */ 825 SUPDECL(int) SUPSemEventMultiCreate(PSUPDRVSESSION pSession, PSUPSEMEVENTMULTI phEventMulti); 826 827 /** 828 * Closes a multiple release event semaphore handle. 829 * 830 * @returns VBox status code. 831 * @retval VINF_OBJECT_DESTROYED if the semaphore was destroyed. 832 * @retval VINF_SUCCESS if the handle was successfully closed but the semaphore 833 * object remained alive because of other references. 834 * 835 * @param pSession The session handle of the caller. 836 * @param hEventMulti The handle. Nil is quietly ignored. 837 */ 838 SUPDECL(int) SUPSemEventMultiClose(PSUPDRVSESSION pSession, SUPSEMEVENTMULTI hEventMulti); 839 840 /** 841 * Signals a multiple release event semaphore. 842 * 843 * @returns VBox status code. 844 * @param pSession The session handle of the caller. 845 * @param hEventMulti The semaphore handle. 846 */ 847 SUPDECL(int) SUPSemEventMultiSignal(PSUPDRVSESSION pSession, SUPSEMEVENTMULTI hEventMulti); 848 849 /** 850 * Resets a multiple release event semaphore. 851 * 852 * @returns VBox status code. 853 * @param pSession The session handle of the caller. 854 * @param hEventMulti The semaphore handle. 855 */ 856 SUPDECL(int) SUPSemEventMultiReset(PSUPDRVSESSION pSession, SUPSEMEVENTMULTI hEventMulti); 857 858 #ifdef IN_RING0 859 /** 860 * Waits on a multiple release event semaphore, not interruptible. 861 * 862 * @returns VBox status code. 863 * @param pSession The session handle of the caller. 864 * @param hEventMulti The semaphore handle. 865 * @param cMillies The number of milliseconds to wait. 866 * @remarks Not available in ring-3. 867 */ 868 SUPDECL(int) SUPSemEventMultiWait(PSUPDRVSESSION pSession, SUPSEMEVENTMULTI hEventMulti, uint32_t cMillies); 869 #endif 870 871 /** 872 * Waits on a multiple release event semaphore, interruptible. 873 * 874 * @returns VBox status code. 875 * @param pSession The session handle of the caller. 876 * @param hEventMulti The semaphore handle. 877 * @param cMillies The number of milliseconds to wait. 878 */ 879 SUPDECL(int) SUPSemEventMultiWaitNoResume(PSUPDRVSESSION pSession, SUPSEMEVENTMULTI hEventMulti, uint32_t cMillies); 880 881 /** 882 * Waits on a multiple release event semaphore, interruptible. 883 * 884 * @returns VBox status code. 885 * @param pSession The session handle of the caller. 886 * @param hEventMulti The semaphore handle. 887 * @param uNsTimeout The deadline given on the RTTimeNanoTS() clock. 888 */ 889 SUPDECL(int) SUPSemEventMultiWaitNsAbsIntr(PSUPDRVSESSION pSession, SUPSEMEVENTMULTI hEventMulti, uint64_t uNsTimeout); 890 891 /** 892 * Waits on a multiple release event semaphore, interruptible. 893 * 894 * @returns VBox status code. 895 * @param pSession The session handle of the caller. 896 * @param hEventMulti The semaphore handle. 897 * @param cNsTimeout The number of nanoseconds to wait. 898 */ 899 SUPDECL(int) SUPSemEventMultiWaitNsRelIntr(PSUPDRVSESSION pSession, SUPSEMEVENTMULTI hEventMulti, uint64_t cNsTimeout); 900 901 /** 902 * Gets the best timeout resolution that SUPSemEventMultiWaitNsAbsIntr and 903 * SUPSemEventMultiWaitNsRelIntr can do. 904 * 905 * @returns The resolution in nanoseconds. 906 * @param pSession The session handle of the caller. 907 */ 908 SUPDECL(uint32_t) SUPSemEventMultiGetResolution(PSUPDRVSESSION pSession); 909 910 911 #ifdef IN_RING3 912 913 /** @defgroup grp_sup_r3 SUP Host Context Ring-3 API 914 * @{ 915 */ 916 917 /** 918 * Installs the support library. 919 * 920 * @returns VBox status code. 921 */ 922 SUPR3DECL(int) SUPR3Install(void); 923 924 /** 925 * Uninstalls the support library. 926 * 927 * @returns VBox status code. 928 */ 929 SUPR3DECL(int) SUPR3Uninstall(void); 930 931 /** 932 * Trusted main entry point. 933 * 934 * This is exported as "TrustedMain" by the dynamic libraries which contains the 935 * "real" application binary for which the hardened stub is built. The entry 936 * point is invoked upon successful initialization of the support library and 937 * runtime. 938 * 939 * @returns main kind of exit code. 940 * @param argc The argument count. 941 * @param argv The argument vector. 942 * @param envp The environment vector. 943 */ 944 typedef DECLCALLBACK(int) FNSUPTRUSTEDMAIN(int argc, char **argv, char **envp); 945 /** Pointer to FNSUPTRUSTEDMAIN(). */ 946 typedef FNSUPTRUSTEDMAIN *PFNSUPTRUSTEDMAIN; 947 948 /** Which operation failed. */ 949 typedef enum SUPINITOP 950 { 951 /** Invalid. */ 952 kSupInitOp_Invalid = 0, 953 /** Installation integrity error. */ 954 kSupInitOp_Integrity, 955 /** Setuid related. */ 956 kSupInitOp_RootCheck, 957 /** Driver related. */ 958 kSupInitOp_Driver, 959 /** IPRT init related. */ 960 kSupInitOp_IPRT, 961 /** Miscellaneous. */ 962 kSupInitOp_Misc, 963 /** Place holder. */ 964 kSupInitOp_End 965 } SUPINITOP; 966 967 /** 968 * Trusted error entry point, optional. 969 * 970 * This is exported as "TrustedError" by the dynamic libraries which contains 971 * the "real" application binary for which the hardened stub is built. The 972 * hardened main() must specify SUPSECMAIN_FLAGS_TRUSTED_ERROR when calling 973 * SUPR3HardenedMain. 974 * 975 * @param pszWhere Where the error occurred (function name). 976 * @param enmWhat Which operation went wrong. 977 * @param rc The status code. 978 * @param pszMsgFmt Error message format string. 979 * @param va The message format arguments. 980 */ 981 typedef DECLCALLBACK(void) FNSUPTRUSTEDERROR(const char *pszWhere, SUPINITOP enmWhat, int rc, const char *pszMsgFmt, va_list va); 982 /** Pointer to FNSUPTRUSTEDERROR. */ 983 typedef FNSUPTRUSTEDERROR *PFNSUPTRUSTEDERROR; 984 985 /** 986 * Secure main. 987 * 988 * This is used for the set-user-ID-on-execute binaries on unixy systems 989 * and when using the open-vboxdrv-via-root-service setup on Windows. 990 * 991 * This function will perform the integrity checks of the VirtualBox 992 * installation, open the support driver, open the root service (later), 993 * and load the DLL corresponding to \a pszProgName and execute its main 994 * function. 995 * 996 * @returns Return code appropriate for main(). 997 * 998 * @param pszProgName The program name. This will be used to figure out which 999 * DLL/SO/DYLIB to load and execute. 1000 * @param fFlags Flags. 1001 * @param argc The argument count. 1002 * @param argv The argument vector. 1003 * @param envp The environment vector. 1004 */ 1005 DECLHIDDEN(int) SUPR3HardenedMain(const char *pszProgName, uint32_t fFlags, int argc, char **argv, char **envp); 1006 1007 /** @name SUPR3HardenedMain flags. 1008 * @{ */ 1009 /** Don't open the device. (Intended for VirtualBox without -startvm.) */ 1010 #define SUPSECMAIN_FLAGS_DONT_OPEN_DEV RT_BIT_32(0) 1011 /** The hardened DLL has a "TrustedError" function (see FNSUPTRUSTEDERROR). */ 1012 #define SUPSECMAIN_FLAGS_TRUSTED_ERROR RT_BIT_32(1) 1013 /** @} */ 1014 1015 /** 1016 * Initializes the support library. 1017 * 1018 * Each successful call to SUPR3Init() or SUPR3InitEx must be countered by a 1019 * call to SUPR3Term(false). 1020 * 1021 * @returns VBox status code. 1022 * @param ppSession Where to store the session handle. Defaults to NULL. 1023 */ 1024 SUPR3DECL(int) SUPR3Init(PSUPDRVSESSION *ppSession); 1025 1026 1027 /** 1028 * Initializes the support library, extended version. 1029 * 1030 * Each successful call to SUPR3Init() or SUPR3InitEx must be countered by a 1031 * call to SUPR3Term(false). 1032 * 1033 * @returns VBox status code. 1034 * @param fUnrestricted The desired access. 1035 * @param ppSession Where to store the session handle. Defaults to NULL. 1036 */ 1037 SUPR3DECL(int) SUPR3InitEx(bool fUnrestricted, PSUPDRVSESSION *ppSession); 1038 1039 /** 1040 * Terminates the support library. 1041 * 1042 * @returns VBox status code. 1043 * @param fForced Forced termination. This means to ignore the 1044 * init call count and just terminated. 1045 */ 1046 #ifdef __cplusplus 1047 SUPR3DECL(int) SUPR3Term(bool fForced = false); 1048 #else 1049 SUPR3DECL(int) SUPR3Term(int fForced); 1050 #endif 1051 1052 /** 1053 * Sets the ring-0 VM handle for use with fast IOCtls. 1054 * 1055 * @returns VBox status code. 1056 * @param pVMR0 The ring-0 VM handle. 1057 * NIL_RTR0PTR can be used to unset the handle when the 1058 * VM is about to be destroyed. 1059 */ 1060 SUPR3DECL(int) SUPR3SetVMForFastIOCtl(PVMR0 pVMR0); 1061 1062 /** 1063 * Calls the HC R0 VMM entry point. 1064 * See VMMR0Entry() for more details. 1065 * 1066 * @returns error code specific to uFunction. 1067 * @param pVMR0 Pointer to the Ring-0 (Host Context) mapping of the VM structure. 1068 * @param idCpu The virtual CPU ID. 1069 * @param uOperation Operation to execute. 1070 * @param pvArg Argument. 1071 */ 1072 SUPR3DECL(int) SUPR3CallVMMR0(PVMR0 pVMR0, VMCPUID idCpu, unsigned uOperation, void *pvArg); 1073 1074 /** 1075 * Variant of SUPR3CallVMMR0, except that this takes the fast ioclt path 1076 * regardsless of compile-time defaults. 1077 * 1078 * @returns VBox status code. 1079 * @param pVMR0 The ring-0 VM handle. 1080 * @param uOperation The operation; only the SUP_VMMR0_DO_* ones are valid. 1081 * @param idCpu The virtual CPU ID. 1082 */ 1083 SUPR3DECL(int) SUPR3CallVMMR0Fast(PVMR0 pVMR0, unsigned uOperation, VMCPUID idCpu); 1084 1085 /** 1086 * Calls the HC R0 VMM entry point, in a safer but slower manner than 1087 * SUPR3CallVMMR0. When entering using this call the R0 components can call 1088 * into the host kernel (i.e. use the SUPR0 and RT APIs). 1089 * 1090 * See VMMR0Entry() for more details. 1091 * 1092 * @returns error code specific to uFunction. 1093 * @param pVMR0 Pointer to the Ring-0 (Host Context) mapping of the VM structure. 1094 * @param idCpu The virtual CPU ID. 1095 * @param uOperation Operation to execute. 1096 * @param u64Arg Constant argument. 1097 * @param pReqHdr Pointer to a request header. Optional. 1098 * This will be copied in and out of kernel space. There currently is a size 1099 * limit on this, just below 4KB. 1100 */ 1101 SUPR3DECL(int) SUPR3CallVMMR0Ex(PVMR0 pVMR0, VMCPUID idCpu, unsigned uOperation, uint64_t u64Arg, PSUPVMMR0REQHDR pReqHdr); 1102 1103 /** 1104 * Calls a ring-0 service. 1105 * 1106 * The operation and the request packet is specific to the service. 1107 * 1108 * @returns error code specific to uFunction. 1109 * @param pszService The service name. 1110 * @param cchService The length of the service name. 1111 * @param uReq The request number. 1112 * @param u64Arg Constant argument. 1113 * @param pReqHdr Pointer to a request header. Optional. 1114 * This will be copied in and out of kernel space. There currently is a size 1115 * limit on this, just below 4KB. 1116 */ 1117 SUPR3DECL(int) SUPR3CallR0Service(const char *pszService, size_t cchService, uint32_t uOperation, uint64_t u64Arg, PSUPR0SERVICEREQHDR pReqHdr); 1118 1119 /** Which logger. */ 1120 typedef enum SUPLOGGER 1121 { 1122 SUPLOGGER_DEBUG = 1, 1123 SUPLOGGER_RELEASE 1124 } SUPLOGGER; 1125 1126 /** 1127 * Changes the settings of the specified ring-0 logger. 1128 * 1129 * @returns VBox status code. 1130 * @param enmWhich Which logger. 1131 * @param pszFlags The flags settings. 1132 * @param pszGroups The groups settings. 1133 * @param pszDest The destination specificier. 1134 */ 1135 SUPR3DECL(int) SUPR3LoggerSettings(SUPLOGGER enmWhich, const char *pszFlags, const char *pszGroups, const char *pszDest); 1136 1137 /** 1138 * Creates a ring-0 logger instance. 1139 * 1140 * @returns VBox status code. 1141 * @param enmWhich Which logger to create. 1142 * @param pszFlags The flags settings. 1143 * @param pszGroups The groups settings. 1144 * @param pszDest The destination specificier. 1145 */ 1146 SUPR3DECL(int) SUPR3LoggerCreate(SUPLOGGER enmWhich, const char *pszFlags, const char *pszGroups, const char *pszDest); 1147 1148 /** 1149 * Destroys a ring-0 logger instance. 1150 * 1151 * @returns VBox status code. 1152 * @param enmWhich Which logger. 1153 */ 1154 SUPR3DECL(int) SUPR3LoggerDestroy(SUPLOGGER enmWhich); 1155 1156 /** 1157 * Queries the paging mode of the host OS. 1158 * 1159 * @returns The paging mode. 1160 */ 1161 SUPR3DECL(SUPPAGINGMODE) SUPR3GetPagingMode(void); 1162 1163 /** 1164 * Allocate zero-filled pages. 1165 * 1166 * Use this to allocate a number of pages suitable for seeding / locking. 1167 * Call SUPR3PageFree() to free the pages once done with them. 1168 * 1169 * @returns VBox status. 1170 * @param cPages Number of pages to allocate. 1171 * @param ppvPages Where to store the base pointer to the allocated pages. 1172 */ 1173 SUPR3DECL(int) SUPR3PageAlloc(size_t cPages, void **ppvPages); 1174 1175 /** 1176 * Frees pages allocated with SUPR3PageAlloc(). 1177 * 1178 * @returns VBox status. 1179 * @param pvPages Pointer returned by SUPR3PageAlloc(). 1180 * @param cPages Number of pages that was allocated. 1181 */ 1182 SUPR3DECL(int) SUPR3PageFree(void *pvPages, size_t cPages); 1183 1184 /** 1185 * Allocate non-zeroed, locked, pages with user and, optionally, kernel 1186 * mappings. 1187 * 1188 * Use SUPR3PageFreeEx() to free memory allocated with this function. 1189 * 1190 * @returns VBox status code. 1191 * @param cPages The number of pages to allocate. 1192 * @param fFlags Flags, reserved. Must be zero. 1193 * @param ppvPages Where to store the address of the user mapping. 1194 * @param pR0Ptr Where to store the address of the kernel mapping. 1195 * NULL if no kernel mapping is desired. 1196 * @param paPages Where to store the physical addresses of each page. 1197 * Optional. 1198 */ 1199 SUPR3DECL(int) SUPR3PageAllocEx(size_t cPages, uint32_t fFlags, void **ppvPages, PRTR0PTR pR0Ptr, PSUPPAGE paPages); 1200 1201 /** 1202 * Maps a portion of a ring-3 only allocation into kernel space. 1203 * 1204 * @returns VBox status code. 1205 * 1206 * @param pvR3 The address SUPR3PageAllocEx return. 1207 * @param off Offset to start mapping at. Must be page aligned. 1208 * @param cb Number of bytes to map. Must be page aligned. 1209 * @param fFlags Flags, must be zero. 1210 * @param pR0Ptr Where to store the address on success. 1211 * 1212 */ 1213 SUPR3DECL(int) SUPR3PageMapKernel(void *pvR3, uint32_t off, uint32_t cb, uint32_t fFlags, PRTR0PTR pR0Ptr); 1214 1215 /** 1216 * Changes the protection of 1217 * 1218 * @returns VBox status code. 1219 * @retval VERR_NOT_SUPPORTED if the OS doesn't allow us to change page level 1220 * protection. See also RTR0MemObjProtect. 1221 * 1222 * @param pvR3 The ring-3 address SUPR3PageAllocEx returned. 1223 * @param R0Ptr The ring-0 address SUPR3PageAllocEx returned if it 1224 * is desired that the corresponding ring-0 page 1225 * mappings should change protection as well. Pass 1226 * NIL_RTR0PTR if the ring-0 pages should remain 1227 * unaffected. 1228 * @param off Offset to start at which to start chagning the page 1229 * level protection. Must be page aligned. 1230 * @param cb Number of bytes to change. Must be page aligned. 1231 * @param fProt The new page level protection, either a combination 1232 * of RTMEM_PROT_READ, RTMEM_PROT_WRITE and 1233 * RTMEM_PROT_EXEC, or just RTMEM_PROT_NONE. 1234 */ 1235 SUPR3DECL(int) SUPR3PageProtect(void *pvR3, RTR0PTR R0Ptr, uint32_t off, uint32_t cb, uint32_t fProt); 1236 1237 /** 1238 * Free pages allocated by SUPR3PageAllocEx. 1239 * 1240 * @returns VBox status code. 1241 * @param pvPages The address of the user mapping. 1242 * @param cPages The number of pages. 1243 */ 1244 SUPR3DECL(int) SUPR3PageFreeEx(void *pvPages, size_t cPages); 1245 1246 /** 1247 * Allocated memory with page aligned memory with a contiguous and locked physical 1248 * memory backing below 4GB. 1249 * 1250 * @returns Pointer to the allocated memory (virtual address). 1251 * *pHCPhys is set to the physical address of the memory. 1252 * If ppvR0 isn't NULL, *ppvR0 is set to the ring-0 mapping. 1253 * The returned memory must be freed using SUPR3ContFree(). 1254 * @returns NULL on failure. 1255 * @param cPages Number of pages to allocate. 1256 * @param pR0Ptr Where to store the ring-0 mapping of the allocation. (optional) 1257 * @param pHCPhys Where to store the physical address of the memory block. 1258 * 1259 * @remark This 2nd version of this API exists because we're not able to map the 1260 * ring-3 mapping executable on WIN64. This is a serious problem in regard to 1261 * the world switchers. 1262 */ 1263 SUPR3DECL(void *) SUPR3ContAlloc(size_t cPages, PRTR0PTR pR0Ptr, PRTHCPHYS pHCPhys); 1264 1265 /** 1266 * Frees memory allocated with SUPR3ContAlloc(). 1267 * 1268 * @returns VBox status code. 1269 * @param pv Pointer to the memory block which should be freed. 1270 * @param cPages Number of pages to be freed. 1271 */ 1272 SUPR3DECL(int) SUPR3ContFree(void *pv, size_t cPages); 1273 1274 /** 1275 * Allocated non contiguous physical memory below 4GB. 1276 * 1277 * The memory isn't zeroed. 1278 * 1279 * @returns VBox status code. 1280 * @returns NULL on failure. 1281 * @param cPages Number of pages to allocate. 1282 * @param ppvPages Where to store the pointer to the allocated memory. 1283 * The pointer stored here on success must be passed to 1284 * SUPR3LowFree when the memory should be released. 1285 * @param ppvPagesR0 Where to store the ring-0 pointer to the allocated memory. optional. 1286 * @param paPages Where to store the physical addresses of the individual pages. 1287 */ 1288 SUPR3DECL(int) SUPR3LowAlloc(size_t cPages, void **ppvPages, PRTR0PTR ppvPagesR0, PSUPPAGE paPages); 1289 1290 /** 1291 * Frees memory allocated with SUPR3LowAlloc(). 1292 * 1293 * @returns VBox status code. 1294 * @param pv Pointer to the memory block which should be freed. 1295 * @param cPages Number of pages that was allocated. 1296 */ 1297 SUPR3DECL(int) SUPR3LowFree(void *pv, size_t cPages); 1298 1299 /** 1300 * Load a module into R0 HC. 1301 * 1302 * This will verify the file integrity in a similar manner as 1303 * SUPR3HardenedVerifyFile before loading it. 1304 * 1305 * @returns VBox status code. 1306 * @param pszFilename The path to the image file. 1307 * @param pszModule The module name. Max 32 bytes. 1308 * @param ppvImageBase Where to store the image address. 1309 * @param pErrInfo Where to return extended error information. 1310 * Optional. 1311 */ 1312 SUPR3DECL(int) SUPR3LoadModule(const char *pszFilename, const char *pszModule, void **ppvImageBase, PRTERRINFO pErrInfo); 1313 1314 /** 1315 * Load a module into R0 HC. 1316 * 1317 * This will verify the file integrity in a similar manner as 1318 * SUPR3HardenedVerifyFile before loading it. 1319 * 1320 * @returns VBox status code. 1321 * @param pszFilename The path to the image file. 1322 * @param pszModule The module name. Max 32 bytes. 1323 * @param pszSrvReqHandler The name of the service request handler entry 1324 * point. See FNSUPR0SERVICEREQHANDLER. 1325 * @param ppvImageBase Where to store the image address. 1326 */ 1327 SUPR3DECL(int) SUPR3LoadServiceModule(const char *pszFilename, const char *pszModule, 1328 const char *pszSrvReqHandler, void **ppvImageBase); 1329 1330 /** 1331 * Frees a R0 HC module. 1332 * 1333 * @returns VBox status code. 1334 * @param pszModule The module to free. 1335 * @remark This will not actually 'free' the module, there are of course usage counting. 1336 */ 1337 SUPR3DECL(int) SUPR3FreeModule(void *pvImageBase); 1338 1339 /** 1340 * Lock down the module loader interface. 1341 * 1342 * This will lock down the module loader interface. No new modules can be 1343 * loaded and all loaded modules can no longer be freed. 1344 * 1345 * @returns VBox status code. 1346 * @param pErrInfo Where to return extended error information. 1347 * Optional. 1348 */ 1349 SUPR3DECL(int) SUPR3LockDownLoader(PRTERRINFO pErrInfo); 1350 1351 /** 1352 * Get the address of a symbol in a ring-0 module. 1353 * 1354 * @returns VBox status code. 1355 * @param pszModule The module name. 1356 * @param pszSymbol Symbol name. If it's value is less than 64k it's treated like a 1357 * ordinal value rather than a string pointer. 1358 * @param ppvValue Where to store the symbol value. 1359 */ 1360 SUPR3DECL(int) SUPR3GetSymbolR0(void *pvImageBase, const char *pszSymbol, void **ppvValue); 1361 1362 /** 1363 * Load R0 HC VMM code. 1364 * 1365 * @returns VBox status code. 1366 * @deprecated Use SUPR3LoadModule(pszFilename, "VMMR0.r0", &pvImageBase) 1367 */ 1368 SUPR3DECL(int) SUPR3LoadVMM(const char *pszFilename); 1369 1370 /** 1371 * Unloads R0 HC VMM code. 1372 * 1373 * @returns VBox status code. 1374 * @deprecated Use SUPR3FreeModule(). 1375 */ 1376 SUPR3DECL(int) SUPR3UnloadVMM(void); 1377 1378 /** 1379 * Get the physical address of the GIP. 1380 * 1381 * @returns VBox status code. 1382 * @param pHCPhys Where to store the physical address of the GIP. 1383 */ 1384 SUPR3DECL(int) SUPR3GipGetPhys(PRTHCPHYS pHCPhys); 1385 1386 /** 1387 * Initializes only the bits relevant for the SUPR3HardenedVerify* APIs. 1388 * 1389 * This is for users that don't necessarily need to initialize the whole of 1390 * SUPLib. There is no harm in calling this one more time. 1391 * 1392 * @returns VBox status code. 1393 * @remarks Currently not counted, so only call once. 1394 */ 1395 SUPR3DECL(int) SUPR3HardenedVerifyInit(void); 1396 1397 /** 1398 * Reverses the effect of SUPR3HardenedVerifyInit if SUPR3InitEx hasn't been 1399 * called. 1400 * 1401 * Ignored if the support library was initialized using SUPR3Init or 1402 * SUPR3InitEx. 1403 * 1404 * @returns VBox status code. 1405 */ 1406 SUPR3DECL(int) SUPR3HardenedVerifyTerm(void); 1407 1408 /** 1409 * Verifies the integrity of a file, and optionally opens it. 1410 * 1411 * The integrity check is for whether the file is suitable for loading into 1412 * the hypervisor or VM process. The integrity check may include verifying 1413 * the authenticode/elfsign/whatever signature of the file, which can take 1414 * a little while. 1415 * 1416 * @returns VBox status code. On failure it will have printed a LogRel message. 1417 * 1418 * @param pszFilename The file. 1419 * @param pszWhat For the LogRel on failure. 1420 * @param phFile Where to store the handle to the opened file. This is optional, pass NULL 1421 * if the file should not be opened. 1422 * @deprecated Write a new one. 1423 */ 1424 SUPR3DECL(int) SUPR3HardenedVerifyFile(const char *pszFilename, const char *pszWhat, PRTFILE phFile); 1425 1426 /** 1427 * Verifies the integrity of a the current process, including the image 1428 * location and that the invocation was absolute. 1429 * 1430 * This must currently be called after initializing the runtime. The intended 1431 * audience is set-uid-to-root applications, root services and similar. 1432 * 1433 * @returns VBox status code. On failure 1434 * message. 1435 * @param pszArgv0 The first argument to main(). 1436 * @param fInternal Set this to @c true if this is an internal 1437 * VirtualBox application. Otherwise pass @c false. 1438 * @param pErrInfo Where to return extended error information. 1439 */ 1440 SUPR3DECL(int) SUPR3HardenedVerifySelf(const char *pszArgv0, bool fInternal, PRTERRINFO pErrInfo); 1441 1442 /** 1443 * Verifies the integrity of an installation directory. 1444 * 1445 * The integrity check verifies that the directory cannot be tampered with by 1446 * normal users on the system. On Unix this translates to root ownership and 1447 * no symbolic linking. 1448 * 1449 * @returns VBox status code. On failure a message will be stored in @a pszErr. 1450 * 1451 * @param pszDirPath The directory path. 1452 * @param fRecursive Whether the check should be recursive or 1453 * not. When set, all sub-directores will be checked, 1454 * including files (@a fCheckFiles is ignored). 1455 * @param fCheckFiles Whether to apply the same basic integrity check to 1456 * the files in the directory as the directory itself. 1457 * @param pErrInfo Where to return extended error information. 1458 * Optional. 1459 */ 1460 SUPR3DECL(int) SUPR3HardenedVerifyDir(const char *pszDirPath, bool fRecursive, bool fCheckFiles, PRTERRINFO pErrInfo); 1461 1462 /** 1463 * Verifies the integrity of a plug-in module. 1464 * 1465 * This is similar to SUPR3HardenedLdrLoad, except it does not load the module 1466 * and that the module does not have to be shipped with VirtualBox. 1467 * 1468 * @returns VBox status code. On failure a message will be stored in @a pszErr. 1469 * 1470 * @param pszFilename The filename of the plug-in module (nothing can be 1471 * omitted here). 1472 * @param pErrInfo Where to return extended error information. 1473 * Optional. 1474 */ 1475 SUPR3DECL(int) SUPR3HardenedVerifyPlugIn(const char *pszFilename, PRTERRINFO pErrInfo); 1476 1477 /** 1478 * Same as RTLdrLoad() but will verify the files it loads (hardened builds). 1479 * 1480 * Will add dll suffix if missing and try load the file. 1481 * 1482 * @returns iprt status code. 1483 * @param pszFilename Image filename. This must have a path. 1484 * @param phLdrMod Where to store the handle to the loaded module. 1485 * @param fFlags See RTLDRLOAD_FLAGS_XXX. 1486 * @param pErrInfo Where to return extended error information. 1487 * Optional. 1488 */ 1489 SUPR3DECL(int) SUPR3HardenedLdrLoad(const char *pszFilename, PRTLDRMOD phLdrMod, uint32_t fFlags, PRTERRINFO pErrInfo); 1490 1491 /** 1492 * Same as RTLdrLoadAppPriv() but it will verify the files it loads (hardened 1493 * builds). 1494 * 1495 * Will add dll suffix to the file if missing, then look for it in the 1496 * architecture dependent application directory. 1497 * 1498 * @returns iprt status code. 1499 * @param pszFilename Image filename. 1500 * @param phLdrMod Where to store the handle to the loaded module. 1501 * @param fFlags See RTLDRLOAD_FLAGS_XXX. 1502 * @param pErrInfo Where to return extended error information. 1503 * Optional. 1504 */ 1505 SUPR3DECL(int) SUPR3HardenedLdrLoadAppPriv(const char *pszFilename, PRTLDRMOD phLdrMod, uint32_t fFlags, PRTERRINFO pErrInfo); 1506 1507 /** 1508 * Same as RTLdrLoad() but will verify the files it loads (hardened builds). 1509 * 1510 * This differs from SUPR3HardenedLdrLoad() in that it can load modules from 1511 * extension packs and anything else safely installed on the system, provided 1512 * they pass the hardening tests. 1513 * 1514 * @returns iprt status code. 1515 * @param pszFilename The full path to the module, with extension. 1516 * @param phLdrMod Where to store the handle to the loaded module. 1517 * @param pErrInfo Where to return extended error information. 1518 * Optional. 1519 */ 1520 SUPR3DECL(int) SUPR3HardenedLdrLoadPlugIn(const char *pszFilename, PRTLDRMOD phLdrMod, PRTERRINFO pErrInfo); 1521 1522 /** 1523 * Check if the host kernel can run in VMX root mode. 1524 * 1525 * @returns VINF_SUCCESS if supported, error code indicating why if not. 1526 */ 1527 SUPR3DECL(int) SUPR3QueryVTxSupported(void); 1528 1529 /** 1530 * Return VT-x/AMD-V capabilities. 1531 * 1532 * @returns VINF_SUCCESS if supported, error code indicating why if not. 1533 * @param pfCaps Pointer to capability dword (out). 1534 * @todo Intended for main, which means we need to relax the privilege requires 1535 * when accessing certain vboxdrv functions. 1536 */ 1537 SUPR3DECL(int) SUPR3QueryVTCaps(uint32_t *pfCaps); 1538 1539 /** 1540 * Open the tracer. 1541 * 1542 * @returns VBox status code. 1543 * @param uCookie Cookie identifying the tracer we expect to talk to. 1544 * @param uArg Tracer specific open argument. 1545 */ 1546 SUPR3DECL(int) SUPR3TracerOpen(uint32_t uCookie, uintptr_t uArg); 1547 1548 /** 1549 * Closes the tracer. 1550 * 1551 * @returns VBox status code. 1552 */ 1553 SUPR3DECL(int) SUPR3TracerClose(void); 1554 1555 /** 1556 * Perform an I/O request on the tracer. 1557 * 1558 * @returns VBox status. 1559 * @param uCmd The tracer command. 1560 * @param uArg The argument. 1561 * @param piRetVal Where to store the tracer return value. 1562 */ 1563 SUPR3DECL(int) SUPR3TracerIoCtl(uintptr_t uCmd, uintptr_t uArg, int32_t *piRetVal); 1564 1565 /** 1566 * Registers the user module with the tracer. 1567 * 1568 * @returns VBox status code. 1569 * @param hModNative Native module handle. Pass ~(uintptr_t)0 if not 1570 * at hand. 1571 * @param pszModule The module name. 1572 * @param pVtgHdr The VTG header. 1573 * @param uVtgHdrAddr The address to which the VTG header is loaded 1574 * in the relevant execution context. 1575 * @param fFlags See SUP_TRACER_UMOD_FLAGS_XXX 1576 */ 1577 SUPR3DECL(int) SUPR3TracerRegisterModule(uintptr_t hModNative, const char *pszModule, struct VTGOBJHDR *pVtgHdr, 1578 RTUINTPTR uVtgHdrAddr, uint32_t fFlags); 1579 1580 /** 1581 * Deregisters the user module. 1582 * 1583 * @returns VBox status code. 1584 * @param pVtgHdr The VTG header. 1585 */ 1586 SUPR3DECL(int) SUPR3TracerDeregisterModule(struct VTGOBJHDR *pVtgHdr); 1587 1588 /** 1589 * Fire the probe. 1590 * 1591 * @param pVtgProbeLoc The probe location record. 1592 * @param uArg0 Raw probe argument 0. 1593 * @param uArg1 Raw probe argument 1. 1594 * @param uArg2 Raw probe argument 2. 1595 * @param uArg3 Raw probe argument 3. 1596 * @param uArg4 Raw probe argument 4. 1597 */ 1598 SUPDECL(void) SUPTracerFireProbe(struct VTGPROBELOC *pVtgProbeLoc, uintptr_t uArg0, uintptr_t uArg1, uintptr_t uArg2, 1599 uintptr_t uArg3, uintptr_t uArg4); 1600 1601 1602 /** 1603 * Attempts to read the value of an MSR. 1604 * 1605 * @returns VBox status code. 1606 * @param uMsr The MSR to read. 1607 * @param idCpu The CPU to read it on, NIL_RTCPUID if it doesn't 1608 * matter which CPU. 1609 * @param puValue Where to return the value. 1610 * @param pfGp Where to store the \#GP indicator for the read 1611 * operation. 1612 */ 1613 SUPR3DECL(int) SUPR3MsrProberRead(uint32_t uMsr, RTCPUID idCpu, uint64_t *puValue, bool *pfGp); 1614 1615 /** 1616 * Attempts to write to an MSR. 1617 * 1618 * @returns VBox status code. 1619 * @param uMsr The MSR to write to. 1620 * @param idCpu The CPU to wrtie it on, NIL_RTCPUID if it 1621 * doesn't matter which CPU. 1622 * @param uValue The value to write. 1623 * @param pfGp Where to store the \#GP indicator for the write 1624 * operation. 1625 */ 1626 SUPR3DECL(int) SUPR3MsrProberWrite(uint32_t uMsr, RTCPUID idCpu, uint64_t uValue, bool *pfGp); 1627 1628 /** 1629 * Attempts to modify the value of an MSR. 1630 * 1631 * @returns VBox status code. 1632 * @param uMsr The MSR to modify. 1633 * @param idCpu The CPU to modify it on, NIL_RTCPUID if it 1634 * doesn't matter which CPU. 1635 * @param fAndMask The bits to keep in the current MSR value. 1636 * @param fOrMask The bits to set before writing. 1637 * @param pResult The result buffer. 1638 */ 1639 SUPR3DECL(int) SUPR3MsrProberModify(uint32_t uMsr, RTCPUID idCpu, uint64_t fAndMask, uint64_t fOrMask, 1640 PSUPMSRPROBERMODIFYRESULT pResult); 1641 1642 /** 1643 * Attempts to modify the value of an MSR, extended version. 1644 * 1645 * @returns VBox status code. 1646 * @param uMsr The MSR to modify. 1647 * @param idCpu The CPU to modify it on, NIL_RTCPUID if it 1648 * doesn't matter which CPU. 1649 * @param fAndMask The bits to keep in the current MSR value. 1650 * @param fOrMask The bits to set before writing. 1651 * @param fFaster If set to @c true some cache/tlb invalidation is 1652 * skipped, otherwise behave like 1653 * SUPR3MsrProberModify. 1654 * @param pResult The result buffer. 1655 */ 1656 SUPR3DECL(int) SUPR3MsrProberModifyEx(uint32_t uMsr, RTCPUID idCpu, uint64_t fAndMask, uint64_t fOrMask, bool fFaster, 1657 PSUPMSRPROBERMODIFYRESULT pResult); 1658 1659 /** 1660 * Resume built-in keyboard on MacBook Air and Pro hosts. 1661 * 1662 * @returns VBox status code. 1663 */ 1664 SUPR3DECL(int) SUPR3ResumeSuspendedKeyboards(void); 1665 1666 1667 /** 1668 * Measure the TSC-delta for the specified CPU. 1669 * 1670 * @returns VBox status code. 1671 * @param idCpu The CPU to measure the TSC-delta for. 1672 * @param fAsync Whether the measurement is asynchronous, returns 1673 * immediately after signalling a measurement 1674 * request. 1675 * @param fForce Whether to perform a measurement even if the 1676 * specified CPU has a (possibly) valid TSC delta. 1677 * @param cRetries Number of times to retry failed delta 1678 * measurements. 1679 * @param cMsWaitRetry Number of milliseconds to wait between retries. 1680 */ 1681 SUPR3DECL(int) SUPR3TscDeltaMeasure(RTCPUID idCpu, bool fAsync, bool fForce, uint8_t cRetries, uint8_t cMsWaitRetry); 1682 1683 /** 1684 * Reads the delta-adjust TSC value. 1685 * 1686 * @returns VBox status code. 1687 * @param puTsc Where to store the read TSC value. 1688 * @param pidApic Where to store the APIC ID of the CPU where the TSC 1689 * was read (optional, can be NULL). 1690 */ 1691 SUPR3DECL(int) SUPR3ReadTsc(uint64_t *puTsc, uint16_t *pidApic); 1692 1693 /** @} */ 1694 #endif /* IN_RING3 */ 1621 1695 1622 1696 -
trunk/include/VBox/vmm/tm.h
r54065 r54308 133 133 VMMDECL(uint64_t) TMCpuTickGet(PVMCPU pVCpu); 134 134 VMM_INT_DECL(uint64_t) TMCpuTickGetNoCheck(PVMCPU pVCpu); 135 VMM_INT_DECL(bool) TMCpuTickCanUseRealTSC(PVM CPU pVCpu, uint64_t *poffRealTSC, bool *pfParavirtTsc);136 VMM_INT_DECL(uint64_t) TMCpuTickGetDeadlineAndTscOffset(PVM CPU pVCpu, uint64_t *poffRealTSC, bool *pfOffsettedTsc, bool *pfParavirtTsc);135 VMM_INT_DECL(bool) TMCpuTickCanUseRealTSC(PVM pVM, PVMCPU pVCpu, uint64_t *poffRealTSC, bool *pfParavirtTsc); 136 VMM_INT_DECL(uint64_t) TMCpuTickGetDeadlineAndTscOffset(PVM pVM, PVMCPU pVCpu, uint64_t *poffRealTSC, bool *pfOffsettedTsc, bool *pfParavirtTsc); 137 137 VMM_INT_DECL(int) TMCpuTickSet(PVM pVM, PVMCPU pVCpu, uint64_t u64Tick); 138 138 VMM_INT_DECL(int) TMCpuTickSetLastSeen(PVMCPU pVCpu, uint64_t u64LastSeenTick); -
trunk/src/VBox/HostDrivers/Support/Makefile.kmk
r54227 r54308 467 467 # 468 468 SUPRC_TEMPLATE := VBoxRc 469 SUPRC_DEFS := IN_SUP_RC 469 SUPRC_DEFS := IN_SUP_RC IN_RT_RC IN_VMM_RC 470 470 SUPRC_SOURCES := SUPLibAll.cpp 471 471 -
trunk/src/VBox/HostDrivers/Support/SUPDrv.c
r54307 r54308 215 215 { "g_pSUPGlobalInfoPage", (void *)&g_pSUPGlobalInfoPage }, /* SED: DATA */ 216 216 { "SUPGetGIP", (void *)SUPGetGIP }, 217 { "SUPReadTscWithDelta", (void *)SUPReadTscWithDelta }, 218 { "SUPGetTscDeltaSlow", (void *)SUPGetTscDeltaSlow }, 219 { "SUPGetCpuHzFromGipForAsyncMode", (void *)SUPGetCpuHzFromGipForAsyncMode }, 217 220 { "SUPR0ComponentDeregisterFactory", (void *)SUPR0ComponentDeregisterFactory }, 218 221 { "SUPR0ComponentQueryFactory", (void *)SUPR0ComponentQueryFactory }, -
trunk/src/VBox/HostDrivers/Support/SUPDrvIOC.h
r54252 r54308 215 215 * - Fix SUPTSCREAD padding (#if 0 -> #if 1). 216 216 */ 217 #define SUPDRV_IOC_VERSION 0x001f000 0217 #define SUPDRV_IOC_VERSION 0x001f0001 218 218 219 219 /** SUP_IOCTL_COOKIE. */ -
trunk/src/VBox/HostDrivers/Support/SUPLib.cpp
r54249 r54308 279 279 strcpy(CookieReq.u.In.szMagic, SUPCOOKIE_MAGIC); 280 280 CookieReq.u.In.u32ReqVersion = SUPDRV_IOC_VERSION; 281 const uint32_t uMinVersion = (SUPDRV_IOC_VERSION & 0xffff0000) == 0x001 d0000282 ? 0x001 d0002281 const uint32_t uMinVersion = (SUPDRV_IOC_VERSION & 0xffff0000) == 0x001f0000 282 ? 0x001f0001 283 283 : SUPDRV_IOC_VERSION & 0xffff0000; 284 284 CookieReq.u.In.u32MinVersion = uMinVersion; -
trunk/src/VBox/HostDrivers/Support/SUPLibAll.cpp
r54259 r54308 50 50 * 51 51 * @returns TSC with delta applied. 52 * @param pGip Pointer to the GIP. 52 53 * 53 54 * @remarks May be called with interrupts disabled in ring-0! This is why the … … 56 57 * @internal 57 58 */ 58 SUPDECL(uint64_t) SUPReadTscWithDelta(void) 59 { 60 PSUPGLOBALINFOPAGE pGip = g_pSUPGlobalInfoPage; 59 SUPDECL(uint64_t) SUPReadTscWithDelta(PSUPGLOBALINFOPAGE pGip) 60 { 61 61 uint64_t uTsc; 62 62 uint16_t iGipCpu; 63 63 AssertCompile(RT_IS_POWER_OF_TWO(RTCPUSET_MAX_CPUS)); 64 64 AssertCompile(RT_ELEMENTS(pGip->aiCpuFromCpuSetIdx) >= RTCPUSET_MAX_CPUS); 65 Assert( GIP_ARE_TSC_DELTAS_APPLICABLE(pGip));65 Assert(pGip->enmUseTscDelta > SUPGIPUSETSCDELTA_PRACTICALLY_ZERO); 66 66 67 67 /* 68 68 * Read the TSC and get the corresponding aCPUs index. 69 69 */ 70 #ifdef IN_RING3 70 71 if (pGip->fGetGipCpu & SUPGIPGETCPU_RDTSCP_MASK_MAX_SET_CPUS) 71 72 { … … 76 77 iGipCpu = pGip->aiCpuFromCpuSetIdx[iCpuSet]; 77 78 } 78 # ifndef IN_RING079 79 else if (pGip->fGetGipCpu & SUPGIPGETCPU_IDTR_LIMIT_MASK_MAX_SET_CPUS) 80 80 { … … 100 100 } 101 101 } 102 # endif /* !IN_RING0 */ 103 else 104 { 105 # ifdef IN_RING3 106 /* Ring-3: Get APIC ID via the slow CPUID instruction, requires looping. */ 102 else 103 { 104 /* Get APIC ID via the slow CPUID instruction, requires looping. */ 107 105 uint32_t cTries = 0; 108 106 for (;;) … … 122 120 cTries++; 123 121 } 124 125 # 126 127 128 129 130 131 132 133 134 122 } 123 #elif defined(IN_RING0) 124 /* Ring-0: Use use RTMpCpuId(), no loops. */ 125 RTCCUINTREG uFlags = ASMIntDisableFlags(); 126 int iCpuSet = RTMpCpuIdToSetIndex(RTMpCpuId()); 127 if (RT_LIKELY((unsigned)iCpuSet < RT_ELEMENTS(pGip->aiCpuFromCpuSetIdx))) 128 iGipCpu = pGip->aiCpuFromCpuSetIdx[iCpuSet]; 129 else 130 iGipCpu = UINT16_MAX; 131 uTsc = ASMReadTSC(); 132 ASMSetFlags(uFlags); 135 133 136 134 # elif defined(IN_RC) 137 /* Raw-mode context: We can get the host CPU set index via VMCPU, no loops. */ 138 RTCCUINTREG uFlags = ASMIntDisableFlags(); /* Are already disable, but play safe. */ 139 uint32_t iCpuSet = VMMGetCpu(&g_VM)->iHostCpuSet; 140 if (RT_LIKELY(iCpuSet < RT_ELEMENTS(pGip->aiCpuFromCpuSetIdx))) 141 iGipCpu = pGip->aiCpuFromCpuSetIdx[iCpuSet]; 142 else 143 iGipCpu = UINT16_MAX; 144 uTsc = ASMReadTSC(); 145 ASMSetFlags(uFlags); 146 # else 147 # error "IN_RING3, IN_RC or IN_RING0 must be defined!" 148 # endif 149 } 135 /* Raw-mode context: We can get the host CPU set index via VMCPU, no loops. */ 136 RTCCUINTREG uFlags = ASMIntDisableFlags(); /* Are already disable, but play safe. */ 137 uint32_t iCpuSet = VMMGetCpu(&g_VM)->iHostCpuSet; 138 if (RT_LIKELY(iCpuSet < RT_ELEMENTS(pGip->aiCpuFromCpuSetIdx))) 139 iGipCpu = pGip->aiCpuFromCpuSetIdx[iCpuSet]; 140 else 141 iGipCpu = UINT16_MAX; 142 uTsc = ASMReadTSC(); 143 ASMSetFlags(uFlags); 144 #else 145 # error "IN_RING3, IN_RC or IN_RING0 must be defined!" 146 #endif 150 147 151 148 /* … … 178 175 } 179 176 177 178 /** 179 * Internal worker for getting the GIP CPU array index for the calling CPU. 180 * 181 * @returns Index into SUPGLOBALINFOPAGE::aCPUs or UINT16_MAX. 182 * @param pGip The GIP. 183 */ 184 DECLINLINE(uint16_t) supGetGipCpuIndex(PSUPGLOBALINFOPAGE pGip) 185 { 186 uint16_t iGipCpu; 187 #ifdef IN_RING3 188 if (pGip->fGetGipCpu & SUPGIPGETCPU_IDTR_LIMIT_MASK_MAX_SET_CPUS) 189 { 190 /* Storing the IDTR is normally very fast. */ 191 uint16_t cbLim = ASMGetIdtrLimit(); 192 uint16_t iCpuSet = cbLim - 256 * (ARCH_BITS == 64 ? 16 : 8); 193 iCpuSet &= RTCPUSET_MAX_CPUS - 1; 194 iGipCpu = pGip->aiCpuFromCpuSetIdx[iCpuSet]; 195 } 196 else if (pGip->fGetGipCpu & SUPGIPGETCPU_RDTSCP_MASK_MAX_SET_CPUS) 197 { 198 /* RDTSCP gives us what need need and more. */ 199 uint32_t iCpuSet; 200 ASMReadTscWithAux(&iCpuSet); 201 iCpuSet &= RTCPUSET_MAX_CPUS - 1; 202 iGipCpu = pGip->aiCpuFromCpuSetIdx[iCpuSet]; 203 } 204 else 205 { 206 /* Get APIC ID via the slow CPUID instruction. */ 207 uint8_t idApic = ASMGetApicId(); 208 iGipCpu = pGip->aiCpuFromApicId[idApic]; 209 } 210 #elif defined(IN_RING0) 211 /* Ring-0: Use use RTMpCpuId() (disables cli to avoid host OS assertions about unsafe CPU number usage). */ 212 RTCCUINTREG uFlags = ASMIntDisableFlags(); 213 int iCpuSet = RTMpCpuIdToSetIndex(RTMpCpuId()); 214 if (RT_LIKELY((unsigned)iCpuSet < RT_ELEMENTS(pGip->aiCpuFromCpuSetIdx))) 215 iGipCpu = pGip->aiCpuFromCpuSetIdx[iCpuSet]; 216 else 217 iGipCpu = UINT16_MAX; 218 ASMSetFlags(uFlags); 219 220 # elif defined(IN_RC) 221 /* Raw-mode context: We can get the host CPU set index via VMCPU. */ 222 uint32_t iCpuSet = VMMGetCpu(&g_VM)->iHostCpuSet; 223 if (RT_LIKELY(iCpuSet < RT_ELEMENTS(pGip->aiCpuFromCpuSetIdx))) 224 iGipCpu = pGip->aiCpuFromCpuSetIdx[iCpuSet]; 225 else 226 iGipCpu = UINT16_MAX; 227 #else 228 # error "IN_RING3, IN_RC or IN_RING0 must be defined!" 229 #endif 230 return iGipCpu; 231 } 232 233 234 /** 235 * Slow path in SUPGetTscDelta, don't call directly. 236 * 237 * @returns See SUPGetTscDelta. 238 * @param pGip The GIP. 239 * @internal 240 */ 241 SUPDECL(uint64_t) SUPGetTscDeltaSlow(PSUPGLOBALINFOPAGE pGip) 242 { 243 uint16_t iGipCpu = supGetGipCpuIndex(pGip); 244 if (RT_LIKELY(iGipCpu < pGip->cCpus)) 245 { 246 int64_t iTscDelta = pGip->aCPUs[iGipCpu].i64TSCDelta; 247 if (iTscDelta != INT64_MAX) 248 return iTscDelta; 249 } 250 AssertFailed(); 251 return 0; 252 } 253 254 255 /** 256 * Slow path in SUPGetCpuHzFromGip, don't call directly. 257 * 258 * @returns See SUPGetCpuHzFromGip. 259 * @param pGip The GIP. 260 * @internal 261 */ 262 SUPDECL(uint64_t) SUPGetCpuHzFromGipForAsyncMode(PSUPGLOBALINFOPAGE pGip) 263 { 264 uint16_t iGipCpu = supGetGipCpuIndex(pGip); 265 if (RT_LIKELY(iGipCpu < pGip->cCpus)) 266 return pGip->aCPUs[iGipCpu].u64CpuHz; 267 AssertFailed(); 268 return pGip->u64CpuHz; 269 } 270 271 180 272 #endif /* RT_ARCH_AMD64 || RT_ARCH_X86 */ 181 273 -
trunk/src/VBox/Runtime/Makefile.kmk
r54254 r54308 2262 2262 # 2263 2263 RuntimeRC_TEMPLATE = VBoxRc 2264 RuntimeRC_DEFS = IN_RT_RC RT_WITH_VBOX 2264 RuntimeRC_DEFS = IN_RT_RC RT_WITH_VBOX IN_SUP_R0 IN_VMM_RC 2265 2265 RuntimeRC_INCS = include 2266 2266 RuntimeRC_SOURCES := \ -
trunk/src/VBox/Runtime/VBox/VBoxRTDeps.cpp
r52144 r54308 5 5 6 6 /* 7 * Copyright (C) 2006-201 4Oracle Corporation7 * Copyright (C) 2006-2015 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 58 58 (PFNRT)SUPSemEventCreate, 59 59 (PFNRT)SUPTracerFireProbe, 60 (PFNRT)SUPGetTscDeltaSlow, 60 61 #endif 61 62 (PFNRT)xmlLoadCatalogs, -
trunk/src/VBox/VMM/Makefile.kmk
r53781 r54308 404 404 VMMRC_SYSSUFF = .gc 405 405 406 VMMRC_DEFS = IN_VMM_RC IN_RT_RC IN_DIS DIS_CORE_ONLY VBOX_WITH_RAW_MODE VBOX_WITH_RAW_MODE_NOT_R0 $(VMM_COMMON_DEFS) 406 VMMRC_DEFS = IN_VMM_RC IN_RT_RC IN_DIS DIS_CORE_ONLY VBOX_WITH_RAW_MODE VBOX_WITH_RAW_MODE_NOT_R0 IN_SUP_RC \ 407 $(VMM_COMMON_DEFS) 407 408 ifdef VBOX_WITH_VMM_R0_SWITCH_STACK 408 409 VMMRC_DEFS += VMM_R0_SWITCH_STACK … … 422 423 VMMRC_LIBS = \ 423 424 $(PATH_STAGE_LIB)/DisasmRC$(VBOX_SUFF_LIB) \ 424 $(PATH_STAGE_LIB)/RuntimeRC$(VBOX_SUFF_LIB) 425 $(PATH_STAGE_LIB)/RuntimeRC$(VBOX_SUFF_LIB) \ 426 $(PATH_STAGE_LIB)/SUPRC$(VBOX_SUFF_LIB) 425 427 ifneq ($(filter pe lx,$(VBOX_LDR_FMT32)),) 426 428 VMMRC_LIBS += \ -
trunk/src/VBox/VMM/VMMAll/TMAllCpu.cpp
r54065 r54308 51 51 52 52 53 #ifdef IN_RING3 54 /** 55 * Used by tmR3CpuTickParavirtEnable and tmR3CpuTickParavirtDisable. 56 */ 57 uint64_t tmR3CpuTickGetRawVirtualNoCheck(PVM pVM) 58 { 59 return tmCpuTickGetRawVirtual(pVM, false /*fCheckTimers*/); 60 } 61 #endif 62 63 53 64 /** 54 65 * Resumes the CPU timestamp counter ticking. … … 68 79 * unpaused before the virtual time and stopped after it. */ 69 80 if (pVM->tm.s.enmTSCMode == TMTSCMODE_REAL_TSC_OFFSET) 70 pVCpu->tm.s.offTSCRawSrc = ASMReadTSC() - pVCpu->tm.s.u64TSC;81 pVCpu->tm.s.offTSCRawSrc = SUPReadTsc() - pVCpu->tm.s.u64TSC; 71 82 else 72 83 pVCpu->tm.s.offTSCRawSrc = tmCpuTickGetRawVirtual(pVM, false /* don't check for pending timers */) … … 103 114 /* When resuming, use the TSC value of the last stopped VCPU to avoid the TSC going back. */ 104 115 if (pVM->tm.s.enmTSCMode == TMTSCMODE_REAL_TSC_OFFSET) 105 pVCpu->tm.s.offTSCRawSrc = ASMReadTSC() - pVM->tm.s.u64LastPausedTSC;116 pVCpu->tm.s.offTSCRawSrc = SUPReadTsc() - pVM->tm.s.u64LastPausedTSC; 106 117 else 107 118 pVCpu->tm.s.offTSCRawSrc = tmCpuTickGetRawVirtual(pVM, false /* don't check for pending timers */) … … 211 222 * 212 223 * @returns true/false accordingly. 224 * @param pVM Pointer to the cross context VM structure. 213 225 * @param pVCpu Pointer to the VMCPU. 214 * @param poffRealTSC The offset against the TSC of the current CPU. 215 * @param pfParavirtTsc Where to store whether paravirt. TSC is enabled. 226 * @param poffRealTsc The offset against the TSC of the current host CPU, 227 * if pfOffsettedTsc is set to true. 228 * @param pfParavirtTsc Where to return whether paravirt TSC is enabled. 216 229 * 217 230 * @thread EMT(pVCpu). 218 231 * @see TMCpuTickGetDeadlineAndTscOffset(). 219 232 */ 220 VMM_INT_DECL(bool) TMCpuTickCanUseRealTSC(PVMCPU pVCpu, uint64_t *poffRealTSC, bool *pfParavirtTsc) 221 { 222 PVM pVM = pVCpu->CTX_SUFF(pVM); 223 bool fOffsettedTsc = false; 233 VMM_INT_DECL(bool) TMCpuTickCanUseRealTSC(PVM pVM, PVMCPU pVCpu, uint64_t *poffRealTsc, bool *pfParavirtTsc) 234 { 235 Assert(pVCpu->tm.s.fTSCTicking); 236 237 *pfParavirtTsc = pVM->tm.s.fParavirtTscEnabled; 238 239 /* 240 * In real TSC mode it's easy, we just need the delta & offTscRawSrc and 241 * the CPU will add them to RDTSC and RDTSCP at runtime. 242 * 243 * In tmCpuTickGetInternal we do: 244 * SUPReadTsc() - pVCpu->tm.s.offTSCRawSrc; 245 * Where SUPReadTsc() does: 246 * ASMReadTSC() - pGipCpu->i64TscDelta; 247 * Which means tmCpuTickGetInternal actually does: 248 * ASMReadTSC() - pGipCpu->i64TscDelta - pVCpu->tm.s.offTSCRawSrc; 249 * So, the offset to be ADDED to RDTSC[P] is: 250 * offRealTsc = -(pGipCpu->i64TscDelta + pVCpu->tm.s.offTSCRawSrc) 251 */ 252 if (pVM->tm.s.enmTSCMode == TMTSCMODE_REAL_TSC_OFFSET) 253 { 254 /** @todo We should negate both deltas! It's soo weird that we do the 255 * exact opposite of what the hardware implements. */ 256 #ifdef IN_RING3 257 *poffRealTsc = 0 - pVCpu->tm.s.offTSCRawSrc - SUPGetTscDelta(); 258 #else 259 *poffRealTsc = 0 - pVCpu->tm.s.offTSCRawSrc - SUPGetTscDeltaByCpuSetIndex(pVCpu->iHostCpuSet); 260 #endif 261 return true; 262 } 224 263 225 264 /* … … 232 271 * c) we're not using warp drive (accelerated virtual guest time). 233 272 */ 234 Assert(pVCpu->tm.s.fTSCTicking);235 *pfParavirtTsc = pVM->tm.s.fParavirtTscEnabled;236 237 if (pVM->tm.s.enmTSCMode == TMTSCMODE_REAL_TSC_OFFSET)238 {239 /* The source is the real TSC. */240 *poffRealTSC = 0 - pVCpu->tm.s.offTSCRawSrc;241 return true; /** @todo count this? */242 }243 244 273 if ( pVM->tm.s.enmTSCMode == TMTSCMODE_DYNAMIC 245 274 && !pVM->tm.s.fVirtualSyncCatchUp … … 254 283 * timer timeout. If it's lower than the avg. length, we should trap rdtsc to increase 255 284 * the chance that we'll get interrupted right after the timer expired. */ 256 uint64_t u64TSC = ASMReadTSC(); /** @todo should be replaced with SUPReadTSC() eventually. */ 257 *poffRealTSC = u64Now - u64TSC; 258 fOffsettedTsc = u64Now >= pVCpu->tm.s.u64TSCLastSeen; 259 return true; /** @todo count this? */ 285 if (u64Now >= pVCpu->tm.s.u64TSCLastSeen) 286 { 287 *poffRealTsc = u64Now - ASMReadTSC(); 288 return true; /** @todo count this? */ 289 } 260 290 } 261 291 … … 274 304 * 275 305 * @returns The number of host cpu ticks to the next deadline. Max one second. 276 * @param cNsToDeadline The number of nano seconds to the next virtual 277 * sync deadline. 278 */ 279 DECLINLINE(uint64_t) tmCpuCalcTicksToDeadline(uint64_t cNsToDeadline) 306 * @param pVCpu The current CPU. 307 * @param cNsToDeadline The number of nano seconds to the next virtual 308 * sync deadline. 309 */ 310 DECLINLINE(uint64_t) tmCpuCalcTicksToDeadline(PVMCPU pVCpu, uint64_t cNsToDeadline) 280 311 { 281 312 AssertCompile(TMCLOCK_FREQ_VIRTUAL <= _4G); 313 #ifdef IN_RING3 314 uint64_t uCpuHz = SUPGetCpuHzFromGip(g_pSUPGlobalInfoPage); 315 #else 316 uint64_t uCpuHz = SUPGetCpuHzFromGipBySetIndex(g_pSUPGlobalInfoPage, pVCpu->iHostCpuSet); 317 #endif 282 318 if (RT_UNLIKELY(cNsToDeadline >= TMCLOCK_FREQ_VIRTUAL)) 283 return SUPGetCpuHzFromGIP(g_pSUPGlobalInfoPage); 284 uint64_t cTicks = ASMMultU64ByU32DivByU32(SUPGetCpuHzFromGIP(g_pSUPGlobalInfoPage), 285 cNsToDeadline, 286 TMCLOCK_FREQ_VIRTUAL); 319 return uCpuHz; 320 uint64_t cTicks = ASMMultU64ByU32DivByU32(uCpuHz, cNsToDeadline, TMCLOCK_FREQ_VIRTUAL); 287 321 if (cTicks > 4000) 288 322 cTicks -= 4000; /* fudge to account for overhead */ … … 298 332 * 299 333 * @returns The number of host CPU clock ticks to the next timer deadline. 334 * @param pVM Pointer to the cross context VM structure. 300 335 * @param pVCpu The current CPU. 301 * @param poffRealTSC The offset against the TSC of the current CPU. 302 * @param pfOffsettedTsc Where to store whether TSC offsetting can be used. 303 * @param pfParavirtTsc Where to store whether paravirt. TSC is enabled. 336 * @param poffRealTsc The offset against the TSC of the current host CPU, 337 * if pfOffsettedTsc is set to true. 338 * @param pfOffsettedTsc Where to return whether TSC offsetting can be used. 339 * @param pfParavirtTsc Where to return whether paravirt TSC is enabled. 304 340 * 305 341 * @thread EMT(pVCpu). 306 342 * @see TMCpuTickCanUseRealTSC(). 307 343 */ 308 VMM_INT_DECL(uint64_t) TMCpuTickGetDeadlineAndTscOffset(PVMCPU pVCpu, uint64_t *poffRealTSC, bool *pfOffsettedTsc, 309 bool *pfParavirtTsc) 310 { 311 PVM pVM = pVCpu->CTX_SUFF(pVM); 312 uint64_t cTicksToDeadline; 344 VMM_INT_DECL(uint64_t) TMCpuTickGetDeadlineAndTscOffset(PVM pVM, PVMCPU pVCpu, uint64_t *poffRealTsc, 345 bool *pfOffsettedTsc, bool *pfParavirtTsc) 346 { 347 Assert(pVCpu->tm.s.fTSCTicking); 348 349 *pfParavirtTsc = pVM->tm.s.fParavirtTscEnabled; 313 350 314 351 /* 315 * We require: 316 * 1. A fixed TSC, this is checked at init time. 317 * 2. That the TSC is ticking (we shouldn't be here if it isn't) 318 * 3. Either that we're using the real TSC as time source or 319 * a) we don't have any lag to catch up, and 320 * b) the virtual sync clock hasn't been halted by an expired timer, and 321 * c) we're not using warp drive (accelerated virtual guest time). 352 * Same logic as in TMCpuTickCanUseRealTSC. 322 353 */ 323 Assert(pVCpu->tm.s.fTSCTicking);324 *pfParavirtTsc = pVM->tm.s.fParavirtTscEnabled;325 326 354 if (pVM->tm.s.enmTSCMode == TMTSCMODE_REAL_TSC_OFFSET) 327 355 { 328 /* The source is the real TSC. */ 329 *poffRealTSC = 0 - pVCpu->tm.s.offTSCRawSrc; 330 *pfOffsettedTsc = true; 331 cTicksToDeadline = tmCpuCalcTicksToDeadline(TMVirtualSyncGetNsToDeadline(pVM)); 332 return cTicksToDeadline; 333 } 334 356 /** @todo We should negate both deltas! It's soo weird that we do the 357 * exact opposite of what the hardware implements. */ 358 #ifdef IN_RING3 359 *poffRealTsc = 0 - pVCpu->tm.s.offTSCRawSrc - SUPGetTscDelta(); 360 #else 361 *poffRealTsc = 0 - pVCpu->tm.s.offTSCRawSrc - SUPGetTscDeltaByCpuSetIndex(pVCpu->iHostCpuSet); 362 #endif 363 *pfOffsettedTsc = true; 364 return tmCpuCalcTicksToDeadline(pVCpu, TMVirtualSyncGetNsToDeadline(pVM)); 365 } 366 367 /* 368 * Same logic as in TMCpuTickCanUseRealTSC. 369 */ 335 370 if ( pVM->tm.s.enmTSCMode == TMTSCMODE_DYNAMIC 336 371 && !pVM->tm.s.fVirtualSyncCatchUp … … 345 380 : u64NowVirtSync; 346 381 u64Now -= pVCpu->tm.s.offTSCRawSrc; 347 *poffRealT SC = u64Now - ASMReadTSC(); /** @todo replace with SUPReadTSC() eventually. */382 *poffRealTsc = u64Now - ASMReadTSC(); 348 383 *pfOffsettedTsc = u64Now >= pVCpu->tm.s.u64TSCLastSeen; 349 cTicksToDeadline = tmCpuCalcTicksToDeadline(cNsToDeadline); 350 return cTicksToDeadline; 384 return tmCpuCalcTicksToDeadline(pVCpu, cNsToDeadline); 351 385 } 352 386 … … 355 389 #endif 356 390 *pfOffsettedTsc = false; 357 *poffRealTSC = 0; 358 cTicksToDeadline = tmCpuCalcTicksToDeadline(TMVirtualSyncGetNsToDeadline(pVM)); 359 return cTicksToDeadline; 391 *poffRealTsc = 0; 392 return tmCpuCalcTicksToDeadline(pVCpu, TMVirtualSyncGetNsToDeadline(pVM)); 360 393 } 361 394 … … 375 408 PVM pVM = pVCpu->CTX_SUFF(pVM); 376 409 if (pVM->tm.s.enmTSCMode == TMTSCMODE_REAL_TSC_OFFSET) 377 u64 = ASMReadTSC();410 u64 = SUPReadTsc(); 378 411 else 379 412 u64 = tmCpuTickGetRawVirtual(pVM, fCheckTimers); … … 497 530 && g_pSUPGlobalInfoPage->u32Mode != SUPGIPMODE_INVARIANT_TSC) 498 531 { 499 uint64_t cTSCTicksPerSecond = SUPGetCpuHzFromGIP(g_pSUPGlobalInfoPage); 532 #ifdef IN_RING3 533 uint64_t cTSCTicksPerSecond = SUPGetCpuHzFromGip(g_pSUPGlobalInfoPage); 534 #elif defined(IN_RING0) 535 uint64_t cTSCTicksPerSecond = SUPGetCpuHzFromGipBySetIndex(g_pSUPGlobalInfoPage, RTMpCpuIdToSetIndex(RTMpCpuId())); 536 #else 537 uint64_t cTSCTicksPerSecond = SUPGetCpuHzFromGipBySetIndex(g_pSUPGlobalInfoPage, VMMGetCpu(pVM)->iHostCpuSet); 538 #endif 500 539 if (RT_LIKELY(cTSCTicksPerSecond != ~(uint64_t)0)) 501 540 return cTSCTicksPerSecond; -
trunk/src/VBox/VMM/VMMR0/HMR0.cpp
r54277 r54308 1403 1403 1404 1404 /* Clear the VCPU <-> host CPU mapping as we've left HM context. */ 1405 ASMAtomicWriteU32(&pVCpu->idHostCpu, NIL_RTCPUID); 1405 ASMAtomicWriteU32(&pVCpu->idHostCpu, NIL_RTCPUID); /** @todo r=bird: This is VMMR0.cpp's job, isn't it? */ 1406 1406 1407 1407 return VINF_SUCCESS; -
trunk/src/VBox/VMM/VMMR0/HMSVMR0.cpp
r54196 r54308 2251 2251 * intercepts. 2252 2252 * 2253 * @param pVM The shared VM handle. 2253 2254 * @param pVCpu Pointer to the VMCPU. 2254 2255 * 2255 2256 * @remarks No-long-jump zone!!! 2256 2257 */ 2257 static void hmR0SvmUpdateTscOffsetting(PVMCPU pVCpu) 2258 { 2259 bool fParavirtTsc; 2260 bool fCanUseRealTsc; 2258 static void hmR0SvmUpdateTscOffsetting(PVM pVM, PVMCPU pVCpu) 2259 { 2260 bool fParavirtTsc; 2261 2261 PSVMVMCB pVmcb = (PSVMVMCB)pVCpu->hm.s.svm.pvVmcb; 2262 fCanUseRealTsc = TMCpuTickCanUseRealTSC(pVCpu, &pVmcb->ctrl.u64TSCOffset, &fParavirtTsc);2262 bool fCanUseRealTsc = TMCpuTickCanUseRealTSC(pVM, pVCpu, &pVmcb->ctrl.u64TSCOffset, &fParavirtTsc); 2263 2263 if (fCanUseRealTsc) 2264 2264 { … … 2279 2279 if (fParavirtTsc) 2280 2280 { 2281 int rc = GIMR0UpdateParavirtTsc(pV Cpu->CTX_SUFF(pVM), 0 /* u64Offset */);2281 int rc = GIMR0UpdateParavirtTsc(pVM, 0 /* u64Offset */); 2282 2282 AssertRC(rc); 2283 2283 STAM_COUNTER_INC(&pVCpu->hm.s.StatTscParavirt); … … 3068 3068 || idCurrentCpu != pVCpu->hm.s.idLastCpu) 3069 3069 { 3070 hmR0SvmUpdateTscOffsetting(pV Cpu);3070 hmR0SvmUpdateTscOffsetting(pVM, pVCpu); 3071 3071 pSvmTransient->fUpdateTscOffsetting = false; 3072 3072 } … … 3190 3190 3191 3191 if (!(pVmcb->ctrl.u32InterceptCtrl1 & SVM_CTRL1_INTERCEPT_RDTSC)) 3192 TMCpuTickSetLastSeen(pVCpu, ASMReadTSC() + pVmcb->ctrl.u64TSCOffset); /** @todo use SUPReadTSC() eventually. */3192 TMCpuTickSetLastSeen(pVCpu, ASMReadTSC() + pVmcb->ctrl.u64TSCOffset); 3193 3193 3194 3194 STAM_PROFILE_ADV_STOP_START(&pVCpu->hm.s.StatInGC, &pVCpu->hm.s.StatExit1, x); -
trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp
r54196 r54308 5603 5603 * 5604 5604 * @returns VBox status code. 5605 * @param pVM Pointer to the cross context VM structure. 5605 5606 * @param pVCpu Pointer to the VMCPU. 5606 5607 * 5607 5608 * @remarks No-long-jump zone!!! 5608 5609 */ 5609 static void hmR0VmxUpdateTscOffsettingAndPreemptTimer(PVMCPU pVCpu) 5610 { 5611 int rc = VERR_INTERNAL_ERROR_5; 5612 bool fOffsettedTsc = false; 5613 bool fParavirtTsc = false; 5614 PVM pVM = pVCpu->CTX_SUFF(pVM); 5610 static void hmR0VmxUpdateTscOffsettingAndPreemptTimer(PVM pVM, PVMCPU pVCpu) 5611 { 5612 int rc; 5613 bool fOffsettedTsc; 5614 bool fParavirtTsc; 5615 5615 if (pVM->hm.s.vmx.fUsePreemptTimer) 5616 5616 { 5617 uint64_t cTicksToDeadline = TMCpuTickGetDeadlineAndTscOffset(pV Cpu, &pVCpu->hm.s.vmx.u64TSCOffset, &fOffsettedTsc,5618 &f ParavirtTsc);5617 uint64_t cTicksToDeadline = TMCpuTickGetDeadlineAndTscOffset(pVM, pVCpu, &pVCpu->hm.s.vmx.u64TSCOffset, 5618 &fOffsettedTsc, &fParavirtTsc); 5619 5619 5620 5620 /* Make sure the returned values have sane upper and lower boundaries. */ 5621 uint64_t u64CpuHz = SUPGetCpuHzFromG IP(g_pSUPGlobalInfoPage);5621 uint64_t u64CpuHz = SUPGetCpuHzFromGipBySetIndex(g_pSUPGlobalInfoPage, pVCpu->iHostCpuSet); 5622 5622 cTicksToDeadline = RT_MIN(cTicksToDeadline, u64CpuHz / 64); /* 1/64th of a second */ 5623 5623 cTicksToDeadline = RT_MAX(cTicksToDeadline, u64CpuHz / 2048); /* 1/2048th of a second */ … … 5628 5628 } 5629 5629 else 5630 fOffsettedTsc = TMCpuTickCanUseRealTSC(pV Cpu, &pVCpu->hm.s.vmx.u64TSCOffset, &fParavirtTsc);5630 fOffsettedTsc = TMCpuTickCanUseRealTSC(pVM, pVCpu, &pVCpu->hm.s.vmx.u64TSCOffset, &fParavirtTsc); 5631 5631 5632 5632 /** @todo later optimize this to be done elsewhere and not before every … … 8637 8637 || idCurrentCpu != pVCpu->hm.s.idLastCpu) 8638 8638 { 8639 hmR0VmxUpdateTscOffsettingAndPreemptTimer(pV Cpu);8639 hmR0VmxUpdateTscOffsettingAndPreemptTimer(pVM, pVCpu); 8640 8640 pVmxTransient->fUpdateTscOffsettingAndPreemptTimer = false; 8641 8641 } … … 8718 8718 8719 8719 if (!(pVCpu->hm.s.vmx.u32ProcCtls & VMX_VMCS_CTRL_PROC_EXEC_RDTSC_EXIT)) 8720 TMCpuTickSetLastSeen(pVCpu, ASMReadTSC() + pVCpu->hm.s.vmx.u64TSCOffset); /** @todo use SUPReadTSC() eventually. */8720 TMCpuTickSetLastSeen(pVCpu, ASMReadTSC() + pVCpu->hm.s.vmx.u64TSCOffset); 8721 8721 8722 8722 STAM_PROFILE_ADV_STOP_START(&pVCpu->hm.s.StatInGC, &pVCpu->hm.s.StatExit1, x); -
trunk/src/VBox/VMM/VMMR3/TM.cpp
r54292 r54308 182 182 static DECLCALLBACK(void) tmR3TimerInfoActive(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs); 183 183 static DECLCALLBACK(void) tmR3InfoClocks(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs); 184 static DECLCALLBACK(VBOXSTRICTRC) tmR3CpuTickParavirt Toggle(PVM pVM, PVMCPU pVCpu, void *pvData);184 static DECLCALLBACK(VBOXSTRICTRC) tmR3CpuTickParavirtDisable(PVM pVM, PVMCPU pVCpu, void *pvData); 185 185 186 186 … … 934 934 * Use GIP when available. 935 935 */ 936 uint64_t u64Hz = SUPGetCpuHzFromG IP(g_pSUPGlobalInfoPage);936 uint64_t u64Hz = SUPGetCpuHzFromGip(g_pSUPGlobalInfoPage); 937 937 if (g_pSUPGlobalInfoPage->u32Mode == SUPGIPMODE_INVARIANT_TSC) 938 938 { … … 954 954 } 955 955 956 u64Hz = SUPGetCpuHzFromG IP(g_pSUPGlobalInfoPage);956 u64Hz = SUPGetCpuHzFromGip(g_pSUPGlobalInfoPage); 957 957 if (u64Hz != UINT64_MAX) 958 958 return u64Hz; … … 1182 1182 { 1183 1183 bool fParavirtTSC = false; 1184 tmR3CpuTickParavirt Toggle(pVM, NULL /* pVCpuEmt */, &fParavirtTSC);1184 tmR3CpuTickParavirtDisable(pVM, NULL, NULL); 1185 1185 } 1186 1186 Assert(!GIMIsParavirtTscEnabled(pVM)); … … 3093 3093 3094 3094 /** 3095 * Switch TM TSC mode to the most appropriate/efficient one. 3096 * 3097 * @returns strict VBox status code. 3098 * @param pVM Pointer to the VM. 3099 * @param pVCpuEmt Pointer to the VMCPU it's called on, can be NULL. 3100 * @param pvData Opaque pointer to whether usage of paravirt. TSC is 3101 * enabled or disabled by the guest OS. 3102 * 3103 * @thread EMT. 3104 * @remarks Must only be called during an EMTs rendezvous. 3105 */ 3106 static DECLCALLBACK(VBOXSTRICTRC) tmR3CpuTickParavirtToggle(PVM pVM, PVMCPU pVCpuEmt, void *pvData) 3107 { 3108 Assert(pVM); 3109 Assert(pvData); 3110 Assert(pVM->tm.s.fTSCModeSwitchAllowed); 3111 NOREF(pVCpuEmt); 3112 3113 bool *pfEnable = (bool *)pvData; 3114 if (*pfEnable) 3115 { 3116 if (pVM->tm.s.enmTSCMode != TMTSCMODE_REAL_TSC_OFFSET) 3095 * @callback_method_impl{PFNVMMEMTRENDEZVOUS, 3096 * Worker for TMR3CpuTickParavirtEnable} 3097 */ 3098 static DECLCALLBACK(VBOXSTRICTRC) tmR3CpuTickParavirtEnable(PVM pVM, PVMCPU pVCpuEmt, void *pvData) 3099 { 3100 AssertPtr(pVM); Assert(pVM->tm.s.fTSCModeSwitchAllowed); NOREF(pVCpuEmt); NOREF(pvData); 3101 Assert(pVCpuEmt->tm.s.fTSCTicking); 3102 3103 if (pVM->tm.s.enmTSCMode != TMTSCMODE_REAL_TSC_OFFSET) 3104 { 3105 if (tmR3HasFixedTSC(pVM)) 3117 3106 { 3118 if (tmR3HasFixedTSC(pVM)) 3119 { 3120 uint64_t u64NowVirtSync = TMVirtualSyncGetNoCheck(pVM); 3121 uint64_t u64Now = ASMMultU64ByU32DivByU32(u64NowVirtSync, pVM->tm.s.cTSCTicksPerSecond, TMCLOCK_FREQ_VIRTUAL); 3122 uint32_t cCpus = pVM->cCpus; 3123 uint64_t u64RealTSC = ASMReadTSC(); /** @todo should use SUPReadTsc() */ 3124 for (uint32_t i = 0; i < cCpus; i++) 3125 { 3126 PVMCPU pVCpu = &pVM->aCpus[i]; 3127 uint64_t u64TickOld = u64Now - pVCpu->tm.s.offTSCRawSrc; 3128 3129 /* 3130 * The return value of TMCpuTickGet() and the guest's TSC value (u64Tick) must 3131 * remain constant across the TM TSC mode-switch. 3132 * OldTick = VrSync - CurOff 3133 * NewTick = RealTsc - NewOff 3134 * NewTick = OldTick 3135 * => RealTsc - NewOff = VrSync - CurOff 3136 * => NewOff = CurOff + RealTsc - VrSync 3137 */ 3138 pVCpu->tm.s.offTSCRawSrc = pVCpu->tm.s.offTSCRawSrc + u64RealTSC - u64Now; 3139 3140 /* If the new offset results in the TSC going backwards, re-adjust the offset. */ 3141 if (u64RealTSC - pVCpu->tm.s.offTSCRawSrc < u64TickOld) 3142 pVCpu->tm.s.offTSCRawSrc += u64TickOld - u64RealTSC; 3143 Assert(u64RealTSC - pVCpu->tm.s.offTSCRawSrc >= u64TickOld); 3144 } 3145 pVM->tm.s.enmTSCMode = TMTSCMODE_REAL_TSC_OFFSET; 3146 LogRel(("TM: Switched TSC mode. New enmTSCMode=%d (%s)\n", pVM->tm.s.enmTSCMode, tmR3GetTSCModeName(pVM))); 3147 } 3148 else 3149 LogRel(("TM: Host is not suitable for using TSC mode (%d - %s). Request to change TSC mode ignored.\n", 3150 TMTSCMODE_REAL_TSC_OFFSET, tmR3GetTSCModeNameEx(TMTSCMODE_REAL_TSC_OFFSET))); 3151 } 3152 } 3153 else 3154 { 3155 if ( pVM->tm.s.enmTSCMode == TMTSCMODE_REAL_TSC_OFFSET 3156 && pVM->tm.s.enmTSCMode != pVM->tm.s.enmOriginalTSCMode) 3157 { 3158 uint64_t u64NowVirtSync = TMVirtualSyncGetNoCheck(pVM); 3159 uint64_t u64Now = ASMMultU64ByU32DivByU32(u64NowVirtSync, pVM->tm.s.cTSCTicksPerSecond, TMCLOCK_FREQ_VIRTUAL); 3160 uint64_t u64RealTSC = ASMReadTSC(); /** @todo replace with SUPReadTSC() eventually. */ 3161 uint32_t cCpus = pVM->cCpus; 3107 /* 3108 * The return value of TMCpuTickGet() and the guest's TSC value for each 3109 * CPU must remain constant across the TM TSC mode-switch. Thus we have 3110 * the following equation (new/old signifies the new/old tsc modes): 3111 * uNewTsc = uOldTsc 3112 * 3113 * Where (see tmCpuTickGetInternal): 3114 * uOldTsc = uRawOldTsc - offTscRawSrcOld 3115 * uNewTsc = uRawNewTsc - offTscRawSrcNew 3116 * 3117 * Solve it for offTscRawSrcNew without replacing uOldTsc: 3118 * uRawNewTsc - offTscRawSrcNew = uOldTsc 3119 * => -offTscRawSrcNew = uOldTsc - uRawNewTsc 3120 * => offTscRawSrcNew = uRawNewTsc - uOldTsc 3121 */ 3122 uint64_t uRawOldTsc = tmR3CpuTickGetRawVirtualNoCheck(pVM); 3123 uint64_t uRawNewTsc = SUPReadTsc(); 3124 uint32_t cCpus = pVM->cCpus; 3162 3125 for (uint32_t i = 0; i < cCpus; i++) 3163 3126 { 3164 PVMCPU pVCpu = &pVM->aCpus[i]; 3165 uint64_t u64TickOld = u64RealTSC - pVCpu->tm.s.offTSCRawSrc; 3166 3167 /* Update the last-seen tick here as we havent't been updating it (as we don't 3168 need it) while in pure TSC-offsetting mode. */ 3169 pVCpu->tm.s.u64TSCLastSeen = pVCpu->tm.s.u64TSC; 3170 3171 /* 3172 * The return value of TMCpuTickGet() and the guest's TSC value (u64Tick) must 3173 * remain constant across the TM TSC mode-switch. 3174 * OldTick = RealTsc - CurOff 3175 * NewTick = VrSync - NewOff 3176 * NewTick = OldTick 3177 * => VrSync - NewOff = RealTsc - CurOff 3178 * => NewOff = CurOff + VrSync - RealTsc 3179 */ 3180 pVCpu->tm.s.offTSCRawSrc = pVCpu->tm.s.offTSCRawSrc + u64Now - u64RealTSC; 3181 3182 /* If the new offset results in the TSC going backwards, re-adjust the offset. */ 3183 if (u64Now - pVCpu->tm.s.offTSCRawSrc < u64TickOld) 3184 pVCpu->tm.s.offTSCRawSrc += u64TickOld - u64Now; 3185 Assert(u64Now - pVCpu->tm.s.offTSCRawSrc >= u64TickOld); 3127 PVMCPU pVCpu = &pVM->aCpus[i]; 3128 uint64_t uOldTsc = uRawOldTsc - pVCpu->tm.s.offTSCRawSrc; 3129 pVCpu->tm.s.offTSCRawSrc = uRawNewTsc - uOldTsc; 3130 Assert(uRawNewTsc - pVCpu->tm.s.offTSCRawSrc >= uOldTsc); /* paranoia^256 */ 3186 3131 } 3187 pVM->tm.s.enmTSCMode = pVM->tm.s.enmOriginalTSCMode; 3132 3133 pVM->tm.s.enmTSCMode = TMTSCMODE_REAL_TSC_OFFSET; 3188 3134 LogRel(("TM: Switched TSC mode. New enmTSCMode=%d (%s)\n", pVM->tm.s.enmTSCMode, tmR3GetTSCModeName(pVM))); 3189 3135 } 3136 else 3137 LogRel(("TM: Host is not suitable for using TSC mode (%d - %s). Request to change TSC mode ignored.\n", 3138 TMTSCMODE_REAL_TSC_OFFSET, tmR3GetTSCModeNameEx(TMTSCMODE_REAL_TSC_OFFSET))); 3190 3139 } 3191 3140 return VINF_SUCCESS; … … 3195 3144 /** 3196 3145 * Notify TM that the guest has enabled usage of a paravirtualized TSC. 3146 * 3147 * This may perform a EMT rendezvous and change the TSC virtualization mode. 3197 3148 * 3198 3149 * @returns VBox status code. … … 3203 3154 int rc = VINF_SUCCESS; 3204 3155 if (pVM->tm.s.fTSCModeSwitchAllowed) 3205 { 3206 bool fEnable = true; 3207 rc = VMMR3EmtRendezvous(pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_ONCE, tmR3CpuTickParavirtToggle, (void *)&fEnable); 3208 } 3156 rc = VMMR3EmtRendezvous(pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_ONCE, tmR3CpuTickParavirtEnable, NULL); 3209 3157 pVM->tm.s.fParavirtTscEnabled = true; 3210 3158 return rc; … … 3213 3161 3214 3162 /** 3163 * @callback_method_impl{PFNVMMEMTRENDEZVOUS, 3164 * Worker for TMR3CpuTickParavirtDisable} 3165 */ 3166 static DECLCALLBACK(VBOXSTRICTRC) tmR3CpuTickParavirtDisable(PVM pVM, PVMCPU pVCpuEmt, void *pvData) 3167 { 3168 AssertPtr(pVM); Assert(pVM->tm.s.fTSCModeSwitchAllowed); NOREF(pVCpuEmt); 3169 Assert(pVCpuEmt->tm.s.fTSCTicking); 3170 3171 if ( pVM->tm.s.enmTSCMode == TMTSCMODE_REAL_TSC_OFFSET 3172 && pVM->tm.s.enmTSCMode != pVM->tm.s.enmOriginalTSCMode) 3173 { 3174 /* 3175 * See tmR3CpuTickParavirtEnable for an explanation of the conversion math. 3176 */ 3177 uint64_t uRawOldTsc = SUPReadTsc(); 3178 uint64_t uRawNewTsc = tmR3CpuTickGetRawVirtualNoCheck(pVM); 3179 uint32_t cCpus = pVM->cCpus; 3180 for (uint32_t i = 0; i < cCpus; i++) 3181 { 3182 PVMCPU pVCpu = &pVM->aCpus[i]; 3183 uint64_t uOldTsc = uRawOldTsc - pVCpu->tm.s.offTSCRawSrc; 3184 pVCpu->tm.s.offTSCRawSrc = uRawNewTsc - uOldTsc; 3185 Assert(uRawNewTsc - pVCpu->tm.s.offTSCRawSrc >= uOldTsc); /* paranoia^256 */ 3186 3187 /* Update the last-seen tick here as we havent't been updating it (as we don't 3188 need it) while in pure TSC-offsetting mode. */ 3189 #if 0 /** @todo r=bird: Why use the TSC value from the last time we paused the TSC? Makes more sense to use uOldTsc doesn't it? */ 3190 pVCpu->tm.s.u64TSCLastSeen = pVCpu->tm.s.u64TSC; 3191 #else 3192 pVCpu->tm.s.u64TSCLastSeen = uOldTsc; 3193 #endif 3194 } 3195 pVM->tm.s.enmTSCMode = pVM->tm.s.enmOriginalTSCMode; 3196 LogRel(("TM: Switched TSC mode. New enmTSCMode=%d (%s)\n", pVM->tm.s.enmTSCMode, tmR3GetTSCModeName(pVM))); 3197 } 3198 return VINF_SUCCESS; 3199 } 3200 3201 3202 /** 3215 3203 * Notify TM that the guest has disabled usage of a paravirtualized TSC. 3204 * 3205 * If TMR3CpuTickParavirtEnable changed the TSC virtualization mode, this will 3206 * perform an EMT rendezvous to revert those changes. 3216 3207 * 3217 3208 * @returns VBox status code. … … 3222 3213 int rc = VINF_SUCCESS; 3223 3214 if (pVM->tm.s.fTSCModeSwitchAllowed) 3224 { 3225 bool fEnable = false; 3226 rc = VMMR3EmtRendezvous(pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_ONCE, tmR3CpuTickParavirtToggle, (void *)&fEnable); 3227 } 3215 rc = VMMR3EmtRendezvous(pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_ONCE, tmR3CpuTickParavirtDisable, NULL); 3228 3216 pVM->tm.s.fParavirtTscEnabled = false; 3229 3217 return rc; -
trunk/src/VBox/VMM/VMMR3/VMMTests.cpp
r50115 r54308 495 495 } 496 496 uint64_t Ticks = ASMReadTSC() - StartTick; 497 if (Ticks < (SUPGetCpuHzFromG IP(g_pSUPGlobalInfoPage) / 10000))498 RTPrintf("Warning: Ticks=%RU64 (< %RU64)\n", Ticks, SUPGetCpuHzFromG IP(g_pSUPGlobalInfoPage) / 10000);497 if (Ticks < (SUPGetCpuHzFromGip(g_pSUPGlobalInfoPage) / 10000)) 498 RTPrintf("Warning: Ticks=%RU64 (< %RU64)\n", Ticks, SUPGetCpuHzFromGip(g_pSUPGlobalInfoPage) / 10000); 499 499 } 500 500 -
trunk/src/VBox/VMM/VMMRC/VMMRC.cpp
r49893 r54308 136 136 case VMMGC_DO_TESTCASE_INTERRUPT_MASKING: 137 137 { 138 uint64_t u64MaxTicks = (SUPGetCpuHzFromG IP(g_pSUPGlobalInfoPage) != ~(uint64_t)0139 ? SUPGetCpuHzFromG IP(g_pSUPGlobalInfoPage)138 uint64_t u64MaxTicks = (SUPGetCpuHzFromGip(g_pSUPGlobalInfoPage) != ~(uint64_t)0 139 ? SUPGetCpuHzFromGip(g_pSUPGlobalInfoPage) 140 140 : _2G) 141 141 / 10000; -
trunk/src/VBox/VMM/include/TMInternal.h
r54270 r54308 759 759 #endif 760 760 761 uint64_t tmR3CpuTickGetRawVirtualNoCheck(PVM pVM); 761 762 int tmCpuTickPause(PVMCPU pVCpu); 762 763 int tmCpuTickPauseLocked(PVM pVM, PVMCPU pVCpu);
Note:
See TracChangeset
for help on using the changeset viewer.