- Timestamp:
- Sep 20, 2023 11:51:34 AM (15 months ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR3/CPUM-armv8.cpp
r101121 r101190 499 499 { 500 500 AssertReturn(uPass == 0, VERR_SSM_UNEXPECTED_PASS); 501 /** @todo */ RT_NOREF(pVM, pSSM);501 cpumR3SaveCpuId(pVM, pSSM); 502 502 return VINF_SSM_DONT_CALL_AGAIN; 503 503 } … … 526 526 SSMR3PutU32(pSSM, pVCpu->cpum.s.fChanged); 527 527 } 528 529 cpumR3SaveCpuId(pVM, pSSM); 528 530 return VINF_SUCCESS; 529 531 } … … 584 586 585 587 pVM->cpum.s.fPendingRestore = false; 586 return VINF_SUCCESS; 588 589 /* Load CPUID and explode guest features. */ 590 return cpumR3LoadCpuId(pVM, pSSM, uVersion); 587 591 } 588 592 -
trunk/src/VBox/VMM/VMMR3/CPUMR3CpuId-armv8.cpp
r101186 r101190 654 654 *ppIdRegs = &pVM->cpum.s.GuestIdRegs; 655 655 return VINF_SUCCESS; 656 } 657 658 659 /* 660 * 661 * 662 * Saved state related code. 663 * Saved state related code. 664 * Saved state related code. 665 * 666 * 667 */ 668 /** Saved state field descriptors for CPUMIDREGS. */ 669 static const SSMFIELD g_aCpumIdRegsFields[] = 670 { 671 SSMFIELD_ENTRY(CPUMIDREGS, u64RegIdAa64Pfr0El1), 672 SSMFIELD_ENTRY(CPUMIDREGS, u64RegIdAa64Pfr1El1), 673 SSMFIELD_ENTRY(CPUMIDREGS, u64RegIdAa64Dfr0El1), 674 SSMFIELD_ENTRY(CPUMIDREGS, u64RegIdAa64Dfr1El1), 675 SSMFIELD_ENTRY(CPUMIDREGS, u64RegIdAa64Afr0El1), 676 SSMFIELD_ENTRY(CPUMIDREGS, u64RegIdAa64Afr1El1), 677 SSMFIELD_ENTRY(CPUMIDREGS, u64RegIdAa64Isar0El1), 678 SSMFIELD_ENTRY(CPUMIDREGS, u64RegIdAa64Isar1El1), 679 SSMFIELD_ENTRY(CPUMIDREGS, u64RegIdAa64Isar2El1), 680 SSMFIELD_ENTRY(CPUMIDREGS, u64RegIdAa64Mmfr0El1), 681 SSMFIELD_ENTRY(CPUMIDREGS, u64RegIdAa64Mmfr1El1), 682 SSMFIELD_ENTRY(CPUMIDREGS, u64RegIdAa64Mmfr2El1), 683 SSMFIELD_ENTRY(CPUMIDREGS, u64RegClidrEl1), 684 SSMFIELD_ENTRY(CPUMIDREGS, u64RegCtrEl0), 685 SSMFIELD_ENTRY(CPUMIDREGS, u64RegDczidEl0), 686 SSMFIELD_ENTRY_TERM() 687 }; 688 689 690 /** 691 * Called both in pass 0 and the final pass. 692 * 693 * @param pVM The cross context VM structure. 694 * @param pSSM The saved state handle. 695 */ 696 void cpumR3SaveCpuId(PVM pVM, PSSMHANDLE pSSM) 697 { 698 /* 699 * Save all the CPU ID leaves. 700 */ 701 SSMR3PutStructEx(pSSM, &pVM->cpum.s.GuestIdRegs, sizeof(pVM->cpum.s.GuestIdRegs), 0, g_aCpumIdRegsFields, NULL); 702 } 703 704 705 /** 706 * Loads the CPU ID leaves saved by pass 0, inner worker. 707 * 708 * @returns VBox status code. 709 * @param pVM The cross context VM structure. 710 * @param pSSM The saved state handle. 711 * @param uVersion The format version. 712 * @param pGuestIdRegs The guest ID register as loaded from the saved state. 713 */ 714 static int cpumR3LoadCpuIdInner(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion, PCCPUMIDREGS pGuestIdRegs) 715 { 716 /* 717 * This can be skipped. 718 */ 719 bool fStrictCpuIdChecks; 720 CFGMR3QueryBoolDef(CFGMR3GetChild(CFGMR3GetRoot(pVM), "CPUM"), "StrictCpuIdChecks", &fStrictCpuIdChecks, true); 721 722 /* 723 * Define a bunch of macros for simplifying the santizing/checking code below. 724 */ 725 /* For checking guest features. */ 726 #define CPUID_GST_FEATURE_RET(a_IdReg, a_Field) \ 727 do { \ 728 if (RT_BF_GET(pGuestIdRegs->a_IdReg, a_Field) > RT_BF_GET(pVM->cpum.s.GuestIdRegs.a_IdReg, a_Field)) \ 729 { \ 730 if (fStrictCpuIdChecks) \ 731 return SSMR3SetLoadError(pSSM, VERR_SSM_LOAD_CPUID_MISMATCH, RT_SRC_POS, \ 732 N_(#a_Field " is not supported by the host but has already exposed to the guest")); \ 733 LogRel(("CPUM: " #a_Field " is not supported by the host but has already been exposed to the guest\n")); \ 734 } \ 735 } while (0) 736 #define CPUID_GST_FEATURE_WRN(a_IdReg, a_Field) \ 737 do { \ 738 if (RT_BF_GET(pGuestIdRegs->a_IdReg, a_Field) > RT_BF_GET(pVM->cpum.s.GuestIdRegs.a_IdReg, a_Field)) \ 739 LogRel(("CPUM: " #a_Field " is not supported by the host but has already been exposed to the guest\n")); \ 740 } while (0) 741 #define CPUID_GST_FEATURE_EMU(a_IdReg, a_Field) \ 742 do { \ 743 if (RT_BF_GET(pGuestIdRegs->a_IdReg, a_Field) > RT_BF_GET(pVM->cpum.s.GuestIdRegs.a_IdReg, a_Field)) \ 744 LogRel(("CPUM: Warning - " #a_Field " is not supported by the host but has already been exposed to the guest. This may impact performance.\n")); \ 745 } while (0) 746 #define CPUID_GST_FEATURE_IGN(a_IdReg, a_Field) do { } while (0) 747 748 RT_NOREF(uVersion); 749 /* 750 * Verify that we can support the features already exposed to the guest on 751 * this host. 752 * 753 * Most of the features we're emulating requires intercepting instruction 754 * and doing it the slow way, so there is no need to warn when they aren't 755 * present in the host CPU. Thus we use IGN instead of EMU on these. 756 * 757 * Trailing comments: 758 * "EMU" - Possible to emulate, could be lots of work and very slow. 759 * "EMU?" - Can this be emulated? 760 */ 761 /* ID_AA64ISAR0_EL1 */ 762 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar0El1, ARMV8_ID_AA64ISAR0_EL1_AES); 763 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar0El1, ARMV8_ID_AA64ISAR0_EL1_SHA1); 764 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar0El1, ARMV8_ID_AA64ISAR0_EL1_SHA2); 765 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar0El1, ARMV8_ID_AA64ISAR0_EL1_CRC32); 766 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar0El1, ARMV8_ID_AA64ISAR0_EL1_ATOMIC); 767 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar0El1, ARMV8_ID_AA64ISAR0_EL1_TME); 768 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar0El1, ARMV8_ID_AA64ISAR0_EL1_RDM); 769 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar0El1, ARMV8_ID_AA64ISAR0_EL1_SHA3); 770 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar0El1, ARMV8_ID_AA64ISAR0_EL1_SM3); 771 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar0El1, ARMV8_ID_AA64ISAR0_EL1_SM4); 772 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar0El1, ARMV8_ID_AA64ISAR0_EL1_DP); 773 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar0El1, ARMV8_ID_AA64ISAR0_EL1_FHM); 774 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar0El1, ARMV8_ID_AA64ISAR0_EL1_TS); 775 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar0El1, ARMV8_ID_AA64ISAR0_EL1_TLB); 776 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar0El1, ARMV8_ID_AA64ISAR0_EL1_RNDR); 777 778 /* ID_AA64ISAR1_EL1 */ 779 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar1El1, ARMV8_ID_AA64ISAR1_EL1_DPB); 780 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar1El1, ARMV8_ID_AA64ISAR1_EL1_APA); 781 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar1El1, ARMV8_ID_AA64ISAR1_EL1_API); 782 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar1El1, ARMV8_ID_AA64ISAR1_EL1_FJCVTZS); 783 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar1El1, ARMV8_ID_AA64ISAR1_EL1_LRCPC); 784 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar1El1, ARMV8_ID_AA64ISAR1_EL1_GPA); 785 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar1El1, ARMV8_ID_AA64ISAR1_EL1_GPI); 786 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar1El1, ARMV8_ID_AA64ISAR1_EL1_FRINTTS); 787 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar1El1, ARMV8_ID_AA64ISAR1_EL1_SB); 788 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar1El1, ARMV8_ID_AA64ISAR1_EL1_SPECRES); 789 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar1El1, ARMV8_ID_AA64ISAR1_EL1_BF16); 790 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar1El1, ARMV8_ID_AA64ISAR1_EL1_DGH); 791 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar1El1, ARMV8_ID_AA64ISAR1_EL1_I8MM); 792 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar1El1, ARMV8_ID_AA64ISAR1_EL1_XS); 793 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar1El1, ARMV8_ID_AA64ISAR1_EL1_LS64); 794 795 /* ID_AA64ISAR2_EL1 */ 796 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar2El1, ARMV8_ID_AA64ISAR2_EL1_WFXT); 797 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar2El1, ARMV8_ID_AA64ISAR2_EL1_RPRES); 798 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar2El1, ARMV8_ID_AA64ISAR2_EL1_GPA3); 799 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar2El1, ARMV8_ID_AA64ISAR2_EL1_APA3); 800 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar2El1, ARMV8_ID_AA64ISAR2_EL1_MOPS); 801 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar2El1, ARMV8_ID_AA64ISAR2_EL1_BC); 802 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar2El1, ARMV8_ID_AA64ISAR2_EL1_PACFRAC); 803 804 #undef CPUID_GST_FEATURE_RET 805 #undef CPUID_GST_FEATURE_WRN 806 #undef CPUID_GST_FEATURE_EMU 807 #undef CPUID_GST_FEATURE_IGN 808 809 /* 810 * We're good, commit the CPU ID registers. 811 */ 812 pVM->cpum.s.GuestIdRegs = *pGuestIdRegs; 813 return VINF_SUCCESS; 814 } 815 816 817 /** 818 * Loads the CPU ID leaves saved by pass 0. 819 * 820 * @returns VBox status code. 821 * @param pVM The cross context VM structure. 822 * @param pSSM The saved state handle. 823 * @param uVersion The format version. 824 */ 825 int cpumR3LoadCpuId(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion) 826 { 827 CPUMIDREGS GuestIdRegs; 828 int rc = SSMR3GetStructEx(pSSM, &GuestIdRegs, sizeof(GuestIdRegs), 0, g_aCpumIdRegsFields, NULL); 829 AssertRCReturn(rc, rc); 830 831 return cpumR3LoadCpuIdInner(pVM, pSSM, uVersion, &GuestIdRegs); 656 832 } 657 833 -
trunk/src/VBox/VMM/include/CPUMInternal-armv8.h
r101121 r101190 175 175 DECLHIDDEN(int) cpumR3SysRegStrictInitChecks(void); 176 176 177 void cpumR3SaveCpuId(PVM pVM, PSSMHANDLE pSSM); 178 int cpumR3LoadCpuId(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion); 179 177 180 DECLCALLBACK(void) cpumR3CpuIdInfo(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs); 178 181 DECLCALLBACK(void) cpumR3CpuFeatInfo(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs);
Note:
See TracChangeset
for help on using the changeset viewer.