VirtualBox

Ignore:
Timestamp:
Sep 22, 2023 9:06:14 AM (16 months ago)
Author:
vboxsync
Message:

VMM/NEMR3Native-darwin-armv8.cpp: Need to sync the ID registers upon first guest code exec call or overrides from loading a saved state are not accounted for, bugref:10390

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR3/NEMR3Native-darwin-armv8.cpp

    r101115 r101234  
    836836        return VMSetError(pVM, VERR_NEM_VM_CREATE_FAILED, RT_SRC_POS,
    837837                          "Setting MPIDR_EL1 failed on vCPU %u: %#x (%Rrc)", idCpu, hrc, nemR3DarwinHvSts2Rc(hrc));
    838 
    839     /*
    840      * The guest ID registers are populated after the call to CPUMR3PopulateFeaturesByIdRegisters() so
    841      * query the guest ID registers now and sync them to the vCPU once as they are constant during guest lifetime.
    842      */
    843     static const struct
    844     {
    845         const char       *pszIdReg;
    846         hv_sys_reg_t     enmHvReg;
    847         uint32_t         offIdStruct;
    848     } s_aSysIdRegs[] =
    849     {
    850 #define ID_SYS_REG_CREATE(a_IdReg, a_CpumIdReg) { #a_IdReg, HV_SYS_REG_##a_IdReg,     RT_UOFFSETOF(CPUMIDREGS, a_CpumIdReg) }
    851         ID_SYS_REG_CREATE(ID_AA64DFR0_EL1,  u64RegIdAa64Dfr0El1),
    852         ID_SYS_REG_CREATE(ID_AA64DFR1_EL1,  u64RegIdAa64Dfr1El1),
    853         ID_SYS_REG_CREATE(ID_AA64ISAR0_EL1, u64RegIdAa64Isar0El1),
    854         ID_SYS_REG_CREATE(ID_AA64ISAR1_EL1, u64RegIdAa64Isar1El1),
    855         ID_SYS_REG_CREATE(ID_AA64MMFR0_EL1, u64RegIdAa64Mmfr0El1),
    856         ID_SYS_REG_CREATE(ID_AA64MMFR1_EL1, u64RegIdAa64Mmfr1El1),
    857         ID_SYS_REG_CREATE(ID_AA64MMFR2_EL1, u64RegIdAa64Mmfr2El1),
    858         ID_SYS_REG_CREATE(ID_AA64PFR0_EL1,  u64RegIdAa64Pfr0El1),
    859         ID_SYS_REG_CREATE(ID_AA64PFR1_EL1,  u64RegIdAa64Pfr1El1),
    860 #undef ID_SYS_REG_CREATE
    861     };
    862 
    863     PCCPUMIDREGS pIdRegsGst = NULL;
    864     int rc = CPUMR3QueryGuestIdRegs(pVM, &pIdRegsGst);
    865     AssertRCReturn(rc, rc);
    866 
    867     for (uint32_t i = 0; i < RT_ELEMENTS(s_aSysIdRegs); i++)
    868     {
    869         uint64_t *pu64 = (uint64_t *)((uint8_t *)pIdRegsGst + s_aSysIdRegs[i].offIdStruct);
    870         hrc = hv_vcpu_set_sys_reg(pVCpu->nem.s.hVCpu, s_aSysIdRegs[i].enmHvReg, *pu64);
    871         if (hrc != HV_SUCCESS)
    872             return VMSetError(pVM, VERR_NEM_VM_CREATE_FAILED, RT_SRC_POS,
    873                               "Setting %s failed on vCPU %u: %#x (%Rrc)", s_aSysIdRegs[i].pszIdReg, idCpu, hrc, nemR3DarwinHvSts2Rc(hrc));
    874     }
    875838
    876839    return VINF_SUCCESS;
     
    16401603    AssertReturn(NEMR3CanExecuteGuest(pVM, pVCpu), VERR_NEM_IPE_9);
    16411604
     1605    if (RT_UNLIKELY(!pVCpu->nem.s.fIdRegsSynced))
     1606    {
     1607        /*
     1608         * Sync the guest ID registers which are per VM once (they are readonly and stay constant during VM lifetime).
     1609         * Need to do it here and not during the init because loading a saved state might change the ID registers from what
     1610         * done in the call to CPUMR3PopulateFeaturesByIdRegisters().
     1611         */
     1612        static const struct
     1613        {
     1614            const char       *pszIdReg;
     1615            hv_sys_reg_t     enmHvReg;
     1616            uint32_t         offIdStruct;
     1617        } s_aSysIdRegs[] =
     1618        {
     1619#define ID_SYS_REG_CREATE(a_IdReg, a_CpumIdReg) { #a_IdReg, HV_SYS_REG_##a_IdReg,     RT_UOFFSETOF(CPUMIDREGS, a_CpumIdReg) }
     1620            ID_SYS_REG_CREATE(ID_AA64DFR0_EL1,  u64RegIdAa64Dfr0El1),
     1621            ID_SYS_REG_CREATE(ID_AA64DFR1_EL1,  u64RegIdAa64Dfr1El1),
     1622            ID_SYS_REG_CREATE(ID_AA64ISAR0_EL1, u64RegIdAa64Isar0El1),
     1623            ID_SYS_REG_CREATE(ID_AA64ISAR1_EL1, u64RegIdAa64Isar1El1),
     1624            ID_SYS_REG_CREATE(ID_AA64MMFR0_EL1, u64RegIdAa64Mmfr0El1),
     1625            ID_SYS_REG_CREATE(ID_AA64MMFR1_EL1, u64RegIdAa64Mmfr1El1),
     1626            ID_SYS_REG_CREATE(ID_AA64MMFR2_EL1, u64RegIdAa64Mmfr2El1),
     1627            ID_SYS_REG_CREATE(ID_AA64PFR0_EL1,  u64RegIdAa64Pfr0El1),
     1628            ID_SYS_REG_CREATE(ID_AA64PFR1_EL1,  u64RegIdAa64Pfr1El1),
     1629#undef ID_SYS_REG_CREATE
     1630        };
     1631
     1632        PCCPUMIDREGS pIdRegsGst = NULL;
     1633        int rc = CPUMR3QueryGuestIdRegs(pVM, &pIdRegsGst);
     1634        AssertRCReturn(rc, rc);
     1635
     1636        for (uint32_t i = 0; i < RT_ELEMENTS(s_aSysIdRegs); i++)
     1637        {
     1638            uint64_t *pu64 = (uint64_t *)((uint8_t *)pIdRegsGst + s_aSysIdRegs[i].offIdStruct);
     1639            hv_return_t hrc = hv_vcpu_set_sys_reg(pVCpu->nem.s.hVCpu, s_aSysIdRegs[i].enmHvReg, *pu64);
     1640            if (hrc != HV_SUCCESS)
     1641                return VMSetError(pVM, VERR_NEM_SET_REGISTERS_FAILED, RT_SRC_POS,
     1642                                  "Setting %s failed on vCPU %u: %#x (%Rrc)", s_aSysIdRegs[i].pszIdReg, pVCpu->idCpu, hrc, nemR3DarwinHvSts2Rc(hrc));
     1643        }
     1644
     1645        pVCpu->nem.s.fIdRegsSynced = true;
     1646    }
     1647
    16421648    /*
    16431649     * Try switch to NEM runloop state.
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette