Changeset 106983 in vbox for trunk/src/VBox/VMM/VMMR3
- Timestamp:
- Nov 13, 2024 12:12:30 PM (2 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR3/NEMR3Native-win-armv8.cpp
r106952 r106983 54 54 #include <winerror.h> /* no api header for this. */ 55 55 56 #include <VBox/dis.h> 56 57 #include <VBox/vmm/nem.h> 57 58 #include <VBox/vmm/iem.h> … … 128 129 129 130 /** 131 * The ARM64 reset context. 132 */ 133 typedef struct MY_WHV_ARM64_RESET_CONTEXT 134 { 135 WHV_INTERCEPT_MESSAGE_HEADER Header; 136 uint32_t ResetType; 137 uint32_t u32Rsvd; 138 } MY_WHV_ARM64_RESET_CONTEXT; 139 typedef MY_WHV_ARM64_RESET_CONTEXT *PMY_WHV_ARM64_RESET_CONTEXT; 140 AssertCompileSize(MY_WHV_ARM64_RESET_CONTEXT, 24 + 2 * sizeof(uint32_t)); 141 142 143 #define WHV_ARM64_RESET_CONTEXT_TYPE_POWER_OFF 0 144 #define WHV_ARM64_RESET_CONTEXT_TYPE_RESET 1 145 146 147 /** 130 148 * The exit reason context for arm64, the size is different 131 149 * from the default SDK we build against. … … 142 160 MY_WHV_HYPERCALL_CONTEXT Hypercall; 143 161 WHV_UNRECOVERABLE_EXCEPTION_CONTEXT UnrecoverableException; 162 MY_WHV_ARM64_RESET_CONTEXT Arm64Reset; 144 163 uint64_t au64Rsvd2[32]; 145 164 }; … … 745 764 HRESULT hrc; 746 765 747 #if 0748 /* Not sure if we really need to set the vendor.749 Update: Apparently we don't. WHvPartitionPropertyCodeProcessorVendor was removed in 17110. */750 RT_ZERO(Property);751 Property.ProcessorVendor = pVM->nem.s.enmCpuVendor == CPUMCPUVENDOR_AMD ? WHvProcessorVendorAmd752 : WHvProcessorVendorIntel;753 hrc = WHvSetPartitionProperty(hPartition, WHvPartitionPropertyCodeProcessorVendor, &Property, sizeof(Property));754 if (FAILED(hrc))755 return VMSetError(pVM, VERR_NEM_VM_CREATE_FAILED, RT_SRC_POS,756 "Failed to set WHvPartitionPropertyCodeProcessorVendor to %u: %Rhrc (Last=%#x/%u)",757 Property.ProcessorVendor, hrc, RTNtLastStatusValue(), RTNtLastErrorValue());758 #endif759 760 766 /* Not sure if we really need to set the cache line flush size. */ 761 767 RT_ZERO(Property); … … 821 827 if (idCpu == 0) 822 828 { 823 /* Need to query the ID registers and populate CPUM. */ 829 /* 830 * Need to query the ID registers and populate CPUM, 831 * these are partition wide registers and need to be queried/set with WHV_ANY_VP. 832 */ 824 833 CPUMIDREGS IdRegs; RT_ZERO(IdRegs); 825 834 826 #if 0 827 WHV_REGISTER_NAME aenmNames[12]; 828 WHV_REGISTER_VALUE aValues[12]; 835 WHV_REGISTER_NAME aenmNames[10]; 836 WHV_REGISTER_VALUE aValues[10]; 829 837 RT_ZERO(aValues); 830 838 … … 839 847 aenmNames[8] = WHvArm64RegisterIdAa64Pfr0El1; 840 848 aenmNames[9] = WHvArm64RegisterIdAa64Pfr1El1; 841 aenmNames[10] = WHvArm64RegisterCtrEl0;842 aenmNames[11] = WHvArm64RegisterDczidEl0;843 849 844 850 hrc = WHvGetVirtualProcessorRegisters(hPartition, WHV_ANY_VP /*idCpu*/, aenmNames, RT_ELEMENTS(aenmNames), aValues); … … 858 864 IdRegs.u64RegIdAa64Mmfr1El1 = aValues[6].Reg64; 859 865 IdRegs.u64RegIdAa64Mmfr2El1 = aValues[7].Reg64; 860 IdRegs.u64RegCtrEl0 = aValues[10].Reg64;861 IdRegs.u64RegDczidEl0 = aValues[11].Reg64;862 #else863 switch (pVM->nem.s.cPhysicalAddressWidth)864 {865 case 32: IdRegs.u64RegIdAa64Mmfr0El1 = RT_BF_SET(IdRegs.u64RegIdAa64Mmfr0El1, ARMV8_ID_AA64MMFR0_EL1_PARANGE, ARMV8_ID_AA64MMFR0_EL1_PARANGE_32BITS); break;866 case 36: IdRegs.u64RegIdAa64Mmfr0El1 = RT_BF_SET(IdRegs.u64RegIdAa64Mmfr0El1, ARMV8_ID_AA64MMFR0_EL1_PARANGE, ARMV8_ID_AA64MMFR0_EL1_PARANGE_36BITS); break;867 case 40: IdRegs.u64RegIdAa64Mmfr0El1 = RT_BF_SET(IdRegs.u64RegIdAa64Mmfr0El1, ARMV8_ID_AA64MMFR0_EL1_PARANGE, ARMV8_ID_AA64MMFR0_EL1_PARANGE_40BITS); break;868 case 42: IdRegs.u64RegIdAa64Mmfr0El1 = RT_BF_SET(IdRegs.u64RegIdAa64Mmfr0El1, ARMV8_ID_AA64MMFR0_EL1_PARANGE, ARMV8_ID_AA64MMFR0_EL1_PARANGE_42BITS); break;869 case 44: IdRegs.u64RegIdAa64Mmfr0El1 = RT_BF_SET(IdRegs.u64RegIdAa64Mmfr0El1, ARMV8_ID_AA64MMFR0_EL1_PARANGE, ARMV8_ID_AA64MMFR0_EL1_PARANGE_44BITS); break;870 case 48: IdRegs.u64RegIdAa64Mmfr0El1 = RT_BF_SET(IdRegs.u64RegIdAa64Mmfr0El1, ARMV8_ID_AA64MMFR0_EL1_PARANGE, ARMV8_ID_AA64MMFR0_EL1_PARANGE_48BITS); break;871 case 52: IdRegs.u64RegIdAa64Mmfr0El1 = RT_BF_SET(IdRegs.u64RegIdAa64Mmfr0El1, ARMV8_ID_AA64MMFR0_EL1_PARANGE, ARMV8_ID_AA64MMFR0_EL1_PARANGE_52BITS); break;872 default: AssertReleaseFailed(); break;873 }874 #endif875 866 876 867 rc = CPUMR3PopulateFeaturesByIdRegisters(pVM, &IdRegs); 877 868 if (RT_FAILURE(rc)) 878 869 return rc; 870 871 /* Apply any overrides to the partition. */ 872 PCCPUMIDREGS pIdRegsGst = NULL; 873 rc = CPUMR3QueryGuestIdRegs(pVM, &pIdRegsGst); 874 AssertRCReturn(rc, rc); 875 876 aValues[0].Reg64 = pIdRegsGst->u64RegIdAa64Dfr0El1; 877 aValues[1].Reg64 = pIdRegsGst->u64RegIdAa64Dfr1El1; 878 aValues[2].Reg64 = pIdRegsGst->u64RegIdAa64Isar0El1; 879 aValues[3].Reg64 = pIdRegsGst->u64RegIdAa64Isar1El1; 880 aValues[4].Reg64 = pIdRegsGst->u64RegIdAa64Isar2El1; 881 aValues[5].Reg64 = pIdRegsGst->u64RegIdAa64Mmfr0El1; 882 aValues[6].Reg64 = pIdRegsGst->u64RegIdAa64Mmfr1El1; 883 aValues[7].Reg64 = pIdRegsGst->u64RegIdAa64Mmfr2El1; 884 aValues[8].Reg64 = pIdRegsGst->u64RegIdAa64Pfr0El1; 885 aValues[9].Reg64 = pIdRegsGst->u64RegIdAa64Pfr1El1; 886 887 hrc = WHvSetVirtualProcessorRegisters(hPartition, WHV_ANY_VP /*idCpu*/, aenmNames, RT_ELEMENTS(aenmNames), aValues); 888 AssertLogRelMsgReturn(SUCCEEDED(hrc), 889 ("WHvGetVirtualProcessorRegisters(%p, %u,,%u,) -> %Rhrc (Last=%#x/%u)\n", 890 hPartition, WHV_ANY_VP, RT_ELEMENTS(aenmNames), hrc, RTNtLastStatusValue(), RTNtLastErrorValue()) 891 , VERR_NEM_SET_REGISTERS_FAILED); 892 893 /* Save the amount of break-/watchpoints supported for syncing the guest register state later. */ 894 pVM->nem.s.cBreakpoints = RT_BF_GET(pIdRegsGst->u64RegIdAa64Dfr0El1, ARMV8_ID_AA64DFR0_EL1_BRPS) + 1; 895 pVM->nem.s.cWatchpoints = RT_BF_GET(pIdRegsGst->u64RegIdAa64Dfr0El1, ARMV8_ID_AA64DFR0_EL1_WRPS) + 1; 879 896 } 880 897 … … 1147 1164 iReg++; \ 1148 1165 } while (0) 1166 #define ADD_SYSREG64(a_enmName, a_uValue) do { \ 1167 aenmNames[iReg] = (a_enmName); \ 1168 aValues[iReg].Reg128.High64 = 0; \ 1169 aValues[iReg].Reg64 = (a_uValue).u64; \ 1170 iReg++; \ 1171 } while (0) 1149 1172 #define ADD_REG128(a_enmName, a_uValue) do { \ 1150 1173 aenmNames[iReg] = (a_enmName); \ … … 1201 1224 /* RIP & Flags */ 1202 1225 if (fWhat & CPUMCTX_EXTRN_PC) 1203 ADD_ REG64_RAW(WHvArm64RegisterPc, pVCpu->cpum.GstCtx.Pc.u64);1226 ADD_SYSREG64(WHvArm64RegisterPc, pVCpu->cpum.GstCtx.Pc); 1204 1227 if (fWhat & CPUMCTX_EXTRN_PSTATE) 1205 1228 ADD_REG64_RAW(WHvArm64RegisterPstate, pVCpu->cpum.GstCtx.fPState); 1229 if (fWhat & CPUMCTX_EXTRN_SPSR) 1230 ADD_SYSREG64(WHvArm64RegisterSpsrEl1, pVCpu->cpum.GstCtx.Spsr); 1231 if (fWhat & CPUMCTX_EXTRN_ELR) 1232 ADD_SYSREG64(WHvArm64RegisterElrEl1, pVCpu->cpum.GstCtx.Elr); 1233 if (fWhat & CPUMCTX_EXTRN_SP) 1234 { 1235 ADD_SYSREG64(WHvArm64RegisterSpEl0, pVCpu->cpum.GstCtx.aSpReg[0]); 1236 ADD_SYSREG64(WHvArm64RegisterSpEl1, pVCpu->cpum.GstCtx.aSpReg[1]); 1237 } 1238 if (fWhat & CPUMCTX_EXTRN_SCTLR_TCR_TTBR) 1239 { 1240 ADD_SYSREG64(WHvArm64RegisterSctlrEl1, pVCpu->cpum.GstCtx.Sctlr); 1241 ADD_SYSREG64(WHvArm64RegisterTcrEl1, pVCpu->cpum.GstCtx.Tcr); 1242 ADD_SYSREG64(WHvArm64RegisterTtbr0El1, pVCpu->cpum.GstCtx.Ttbr0); 1243 ADD_SYSREG64(WHvArm64RegisterTtbr1El1, pVCpu->cpum.GstCtx.Ttbr1); 1244 } 1206 1245 1207 1246 /* Vector state. */ … … 1242 1281 } 1243 1282 1283 if (fWhat & CPUMCTX_EXTRN_FPCR) 1284 ADD_REG64_RAW(WHvArm64RegisterFpcr, pVCpu->cpum.GstCtx.fpcr); 1285 if (fWhat & CPUMCTX_EXTRN_FPSR) 1286 ADD_REG64_RAW(WHvArm64RegisterFpsr, pVCpu->cpum.GstCtx.fpsr); 1287 1288 /* System registers. */ 1289 if (fWhat & CPUMCTX_EXTRN_SYSREG_MISC) 1290 { 1291 ADD_SYSREG64(WHvArm64RegisterVbarEl1, pVCpu->cpum.GstCtx.VBar); 1292 ADD_SYSREG64(WHvArm64RegisterEsrEl1, pVCpu->cpum.GstCtx.Esr); 1293 ADD_SYSREG64(WHvArm64RegisterFarEl1, pVCpu->cpum.GstCtx.Far); 1294 ADD_SYSREG64(WHvArm64RegisterCntkctlEl1, pVCpu->cpum.GstCtx.CntKCtl); 1295 ADD_SYSREG64(WHvArm64RegisterContextidrEl1, pVCpu->cpum.GstCtx.ContextIdr); 1296 ADD_SYSREG64(WHvArm64RegisterCpacrEl1, pVCpu->cpum.GstCtx.Cpacr); 1297 ADD_SYSREG64(WHvArm64RegisterCsselrEl1, pVCpu->cpum.GstCtx.Csselr); 1298 ADD_SYSREG64(WHvArm64RegisterMairEl1, pVCpu->cpum.GstCtx.Mair); 1299 ADD_SYSREG64(WHvArm64RegisterParEl1, pVCpu->cpum.GstCtx.Par); 1300 ADD_SYSREG64(WHvArm64RegisterTpidrroEl0, pVCpu->cpum.GstCtx.TpIdrRoEl0); 1301 ADD_SYSREG64(WHvArm64RegisterTpidrEl0, pVCpu->cpum.GstCtx.aTpIdr[0]); 1302 ADD_SYSREG64(WHvArm64RegisterTpidrEl1, pVCpu->cpum.GstCtx.aTpIdr[1]); 1303 } 1304 1305 if (fWhat & CPUMCTX_EXTRN_SYSREG_DEBUG) 1306 { 1307 for (uint32_t i = 0; i < pVM->nem.s.cBreakpoints; i++) 1308 { 1309 ADD_SYSREG64((WHV_REGISTER_NAME)((uint32_t)WHvArm64RegisterDbgbcr0El1 + i), pVCpu->cpum.GstCtx.aBp[i].Ctrl); 1310 ADD_SYSREG64((WHV_REGISTER_NAME)((uint32_t)WHvArm64RegisterDbgbvr0El1 + i), pVCpu->cpum.GstCtx.aBp[i].Value); 1311 } 1312 1313 for (uint32_t i = 0; i < pVM->nem.s.cWatchpoints; i++) 1314 { 1315 ADD_SYSREG64((WHV_REGISTER_NAME)((uint32_t)WHvArm64RegisterDbgwcr0El1 + i), pVCpu->cpum.GstCtx.aWp[i].Ctrl); 1316 ADD_SYSREG64((WHV_REGISTER_NAME)((uint32_t)WHvArm64RegisterDbgwvr0El1 + i), pVCpu->cpum.GstCtx.aWp[i].Value); 1317 } 1318 1319 ADD_SYSREG64(WHvArm64RegisterMdscrEl1, pVCpu->cpum.GstCtx.Mdscr); 1320 } 1321 1322 if (fWhat & CPUMCTX_EXTRN_SYSREG_PAUTH_KEYS) 1323 { 1324 ADD_SYSREG64(WHvArm64RegisterApdAKeyHiEl1, pVCpu->cpum.GstCtx.Apda.High); 1325 ADD_SYSREG64(WHvArm64RegisterApdAKeyLoEl1, pVCpu->cpum.GstCtx.Apda.Low); 1326 ADD_SYSREG64(WHvArm64RegisterApdBKeyHiEl1, pVCpu->cpum.GstCtx.Apdb.High); 1327 ADD_SYSREG64(WHvArm64RegisterApdBKeyLoEl1, pVCpu->cpum.GstCtx.Apdb.Low); 1328 ADD_SYSREG64(WHvArm64RegisterApgAKeyHiEl1, pVCpu->cpum.GstCtx.Apga.High); 1329 ADD_SYSREG64(WHvArm64RegisterApgAKeyLoEl1, pVCpu->cpum.GstCtx.Apga.Low); 1330 ADD_SYSREG64(WHvArm64RegisterApiAKeyHiEl1, pVCpu->cpum.GstCtx.Apia.High); 1331 ADD_SYSREG64(WHvArm64RegisterApiAKeyLoEl1, pVCpu->cpum.GstCtx.Apia.Low); 1332 ADD_SYSREG64(WHvArm64RegisterApiBKeyHiEl1, pVCpu->cpum.GstCtx.Apib.High); 1333 ADD_SYSREG64(WHvArm64RegisterApiBKeyLoEl1, pVCpu->cpum.GstCtx.Apib.Low); 1334 } 1335 1244 1336 #undef ADD_REG64 1245 1337 #undef ADD_REG64_RAW … … 1266 1358 NEM_TMPL_STATIC int nemHCWinCopyStateFromHyperV(PVMCC pVM, PVMCPUCC pVCpu, uint64_t fWhat) 1267 1359 { 1268 WHV_REGISTER_NAME aenmNames[ 128];1360 WHV_REGISTER_NAME aenmNames[256]; 1269 1361 1270 1362 fWhat &= pVCpu->cpum.GstCtx.fExtrn; … … 1389 1481 aenmNames[iReg++] = WHvArm64RegisterEsrEl1; 1390 1482 aenmNames[iReg++] = WHvArm64RegisterFarEl1; 1391 /** @todo */ 1392 } 1393 1394 #if 0 1483 aenmNames[iReg++] = WHvArm64RegisterCntkctlEl1; 1484 aenmNames[iReg++] = WHvArm64RegisterContextidrEl1; 1485 aenmNames[iReg++] = WHvArm64RegisterCpacrEl1; 1486 aenmNames[iReg++] = WHvArm64RegisterCsselrEl1; 1487 aenmNames[iReg++] = WHvArm64RegisterMairEl1; 1488 aenmNames[iReg++] = WHvArm64RegisterParEl1; 1489 aenmNames[iReg++] = WHvArm64RegisterTpidrroEl0; 1490 aenmNames[iReg++] = WHvArm64RegisterTpidrEl0; 1491 aenmNames[iReg++] = WHvArm64RegisterTpidrEl1; 1492 } 1493 1395 1494 if (fWhat & CPUMCTX_EXTRN_SYSREG_DEBUG) 1396 1495 { 1397 aenmNames[iReg++] = WHvArm64RegisterDbgbcr0El1; 1398 /** @todo */ 1399 } 1400 #endif 1496 /* Hyper-V doesn't allow syncing debug break-/watchpoint registers which aren't there. */ 1497 for (uint32_t i = 0; i < pVM->nem.s.cBreakpoints; i++) 1498 { 1499 aenmNames[iReg++] = (WHV_REGISTER_NAME)((uint32_t)WHvArm64RegisterDbgbcr0El1 + i); 1500 aenmNames[iReg++] = (WHV_REGISTER_NAME)((uint32_t)WHvArm64RegisterDbgbvr0El1 + i); 1501 } 1502 1503 for (uint32_t i = 0; i < pVM->nem.s.cWatchpoints; i++) 1504 { 1505 aenmNames[iReg++] = (WHV_REGISTER_NAME)((uint32_t)WHvArm64RegisterDbgwcr0El1 + i); 1506 aenmNames[iReg++] = (WHV_REGISTER_NAME)((uint32_t)WHvArm64RegisterDbgwvr0El1 + i); 1507 } 1508 1509 aenmNames[iReg++] = WHvArm64RegisterMdscrEl1; 1510 } 1401 1511 1402 1512 if (fWhat & CPUMCTX_EXTRN_SYSREG_PAUTH_KEYS) 1403 1513 { 1404 1514 aenmNames[iReg++] = WHvArm64RegisterApdAKeyHiEl1; 1405 /** @todo */ 1515 aenmNames[iReg++] = WHvArm64RegisterApdAKeyLoEl1; 1516 aenmNames[iReg++] = WHvArm64RegisterApdBKeyHiEl1; 1517 aenmNames[iReg++] = WHvArm64RegisterApdBKeyLoEl1; 1518 aenmNames[iReg++] = WHvArm64RegisterApgAKeyHiEl1; 1519 aenmNames[iReg++] = WHvArm64RegisterApgAKeyLoEl1; 1520 aenmNames[iReg++] = WHvArm64RegisterApiAKeyHiEl1; 1521 aenmNames[iReg++] = WHvArm64RegisterApiAKeyLoEl1; 1522 aenmNames[iReg++] = WHvArm64RegisterApiBKeyHiEl1; 1523 aenmNames[iReg++] = WHvArm64RegisterApiBKeyLoEl1; 1406 1524 } 1407 1525 … … 1412 1530 * Get the registers. 1413 1531 */ 1414 WHV_REGISTER_VALUE aValues[ 128];1532 WHV_REGISTER_VALUE aValues[256]; 1415 1533 RT_ZERO(aValues); 1416 1534 Assert(RT_ELEMENTS(aValues) >= cRegs); … … 1557 1675 if (fWhat & CPUMCTX_EXTRN_SYSREG_MISC) 1558 1676 { 1559 GET_SYSREG64(pVCpu->cpum.GstCtx.VBar, WHvArm64RegisterVbarEl1); 1560 GET_SYSREG64(pVCpu->cpum.GstCtx.Esr, WHvArm64RegisterEsrEl1); 1561 GET_SYSREG64(pVCpu->cpum.GstCtx.Far, WHvArm64RegisterFarEl1); 1562 /** @todo */ 1563 } 1564 1565 #if 0 1677 GET_SYSREG64(pVCpu->cpum.GstCtx.VBar, WHvArm64RegisterVbarEl1); 1678 GET_SYSREG64(pVCpu->cpum.GstCtx.Esr, WHvArm64RegisterEsrEl1); 1679 GET_SYSREG64(pVCpu->cpum.GstCtx.Far, WHvArm64RegisterFarEl1); 1680 GET_SYSREG64(pVCpu->cpum.GstCtx.CntKCtl, WHvArm64RegisterCntkctlEl1); 1681 GET_SYSREG64(pVCpu->cpum.GstCtx.ContextIdr, WHvArm64RegisterContextidrEl1); 1682 GET_SYSREG64(pVCpu->cpum.GstCtx.Cpacr, WHvArm64RegisterCpacrEl1); 1683 GET_SYSREG64(pVCpu->cpum.GstCtx.Csselr, WHvArm64RegisterCsselrEl1); 1684 GET_SYSREG64(pVCpu->cpum.GstCtx.Mair, WHvArm64RegisterMairEl1); 1685 GET_SYSREG64(pVCpu->cpum.GstCtx.Par, WHvArm64RegisterParEl1); 1686 GET_SYSREG64(pVCpu->cpum.GstCtx.TpIdrRoEl0, WHvArm64RegisterTpidrroEl0); 1687 GET_SYSREG64(pVCpu->cpum.GstCtx.aTpIdr[0], WHvArm64RegisterTpidrEl0); 1688 GET_SYSREG64(pVCpu->cpum.GstCtx.aTpIdr[1], WHvArm64RegisterTpidrEl1); 1689 } 1690 1566 1691 if (fWhat & CPUMCTX_EXTRN_SYSREG_DEBUG) 1567 1692 { 1568 GET_SYSREG64(pVCpu->cpum.GstCtx.aBp[0].Ctrl, WHvArm64RegisterDbgbcr0El1); 1569 /** @todo */ 1570 } 1571 #endif 1693 for (uint32_t i = 0; i < pVM->nem.s.cBreakpoints; i++) 1694 { 1695 GET_SYSREG64(pVCpu->cpum.GstCtx.aBp[i].Ctrl, (WHV_REGISTER_NAME)((uint32_t)WHvArm64RegisterDbgbcr0El1 + i)); 1696 GET_SYSREG64(pVCpu->cpum.GstCtx.aBp[i].Value, (WHV_REGISTER_NAME)((uint32_t)WHvArm64RegisterDbgbvr0El1 + i)); 1697 } 1698 1699 for (uint32_t i = 0; i < pVM->nem.s.cWatchpoints; i++) 1700 { 1701 GET_SYSREG64(pVCpu->cpum.GstCtx.aWp[i].Ctrl, (WHV_REGISTER_NAME)((uint32_t)WHvArm64RegisterDbgwcr0El1 + i)); 1702 GET_SYSREG64(pVCpu->cpum.GstCtx.aWp[i].Value, (WHV_REGISTER_NAME)((uint32_t)WHvArm64RegisterDbgwvr0El1 + i)); 1703 } 1704 1705 GET_SYSREG64(pVCpu->cpum.GstCtx.Mdscr, WHvArm64RegisterMdscrEl1); 1706 } 1572 1707 1573 1708 if (fWhat & CPUMCTX_EXTRN_SYSREG_PAUTH_KEYS) 1574 1709 { 1575 1710 GET_SYSREG64(pVCpu->cpum.GstCtx.Apda.High, WHvArm64RegisterApdAKeyHiEl1); 1576 /** @todo */ 1711 GET_SYSREG64(pVCpu->cpum.GstCtx.Apda.Low, WHvArm64RegisterApdAKeyLoEl1); 1712 GET_SYSREG64(pVCpu->cpum.GstCtx.Apdb.High, WHvArm64RegisterApdBKeyHiEl1); 1713 GET_SYSREG64(pVCpu->cpum.GstCtx.Apdb.Low, WHvArm64RegisterApdBKeyLoEl1); 1714 GET_SYSREG64(pVCpu->cpum.GstCtx.Apga.High, WHvArm64RegisterApgAKeyHiEl1); 1715 GET_SYSREG64(pVCpu->cpum.GstCtx.Apga.Low, WHvArm64RegisterApgAKeyLoEl1); 1716 GET_SYSREG64(pVCpu->cpum.GstCtx.Apia.High, WHvArm64RegisterApiAKeyHiEl1); 1717 GET_SYSREG64(pVCpu->cpum.GstCtx.Apia.Low, WHvArm64RegisterApiAKeyLoEl1); 1718 GET_SYSREG64(pVCpu->cpum.GstCtx.Apib.High, WHvArm64RegisterApiBKeyHiEl1); 1719 GET_SYSREG64(pVCpu->cpum.GstCtx.Apib.Low, WHvArm64RegisterApiBKeyLoEl1); 1577 1720 } 1578 1721 … … 2043 2186 RT_NOREF(fL2Fault); 2044 2187 2045 AssertReturn(fIsv, VERR_NOT_SUPPORTED); /** @todo Implement using IEM when this should occur. */ 2046 2047 EMHistoryAddExit(pVCpu, 2048 fWrite 2049 ? EMEXIT_MAKE_FT(EMEXIT_F_KIND_EM, EMEXITTYPE_MMIO_WRITE) 2050 : EMEXIT_MAKE_FT(EMEXIT_F_KIND_EM, EMEXITTYPE_MMIO_READ), 2051 pVCpu->cpum.GstCtx.Pc.u64, ASMReadTSC()); 2052 2053 VBOXSTRICTRC rcStrict = VINF_SUCCESS; 2054 uint64_t u64Val = 0; 2055 if (fWrite) 2056 { 2057 u64Val = nemR3WinGetGReg(pVCpu, uReg); 2058 rcStrict = PGMPhysWrite(pVM, GCPhys, &u64Val, cbAcc, PGMACCESSORIGIN_HM); 2059 Log4(("MmioExit/%u: %08RX64: WRITE %RGp LB %u, %.*Rhxs -> rcStrict=%Rrc\n", 2060 pVCpu->idCpu, pVCpu->cpum.GstCtx.Pc.u64, GCPhys, cbAcc, cbAcc, 2061 &u64Val, VBOXSTRICTRC_VAL(rcStrict) )); 2188 VBOXSTRICTRC rcStrict; 2189 if (fIsv) 2190 { 2191 EMHistoryAddExit(pVCpu, 2192 fWrite 2193 ? EMEXIT_MAKE_FT(EMEXIT_F_KIND_EM, EMEXITTYPE_MMIO_WRITE) 2194 : EMEXIT_MAKE_FT(EMEXIT_F_KIND_EM, EMEXITTYPE_MMIO_READ), 2195 pVCpu->cpum.GstCtx.Pc.u64, ASMReadTSC()); 2196 2197 uint64_t u64Val = 0; 2198 if (fWrite) 2199 { 2200 u64Val = nemR3WinGetGReg(pVCpu, uReg); 2201 rcStrict = PGMPhysWrite(pVM, GCPhys, &u64Val, cbAcc, PGMACCESSORIGIN_HM); 2202 Log4(("MmioExit/%u: %08RX64: WRITE %RGp LB %u, %.*Rhxs -> rcStrict=%Rrc\n", 2203 pVCpu->idCpu, pVCpu->cpum.GstCtx.Pc.u64, GCPhys, cbAcc, cbAcc, 2204 &u64Val, VBOXSTRICTRC_VAL(rcStrict) )); 2205 } 2206 else 2207 { 2208 rcStrict = PGMPhysRead(pVM, GCPhys, &u64Val, cbAcc, PGMACCESSORIGIN_HM); 2209 Log4(("MmioExit/%u: %08RX64: READ %RGp LB %u -> %.*Rhxs rcStrict=%Rrc\n", 2210 pVCpu->idCpu, pVCpu->cpum.GstCtx.Pc.u64, GCPhys, cbAcc, cbAcc, 2211 &u64Val, VBOXSTRICTRC_VAL(rcStrict) )); 2212 if (rcStrict == VINF_SUCCESS) 2213 nemR3WinSetGReg(pVCpu, uReg, f64BitReg, fSignExtend, u64Val); 2214 } 2062 2215 } 2063 2216 else 2064 2217 { 2065 rcStrict = PGMPhysRead(pVM, GCPhys, &u64Val, cbAcc, PGMACCESSORIGIN_HM); 2066 Log4(("MmioExit/%u: %08RX64: READ %RGp LB %u -> %.*Rhxs rcStrict=%Rrc\n", 2067 pVCpu->idCpu, pVCpu->cpum.GstCtx.Pc.u64, GCPhys, cbAcc, cbAcc, 2068 &u64Val, VBOXSTRICTRC_VAL(rcStrict) )); 2218 /** @todo Our UEFI firmware accesses the flash region with the following instruction 2219 * when the NVRAM actually contains data: 2220 * ldrb w9, [x6, #-0x0001]! 2221 * This is too complicated for the hardware so the ISV bit is not set. Until there 2222 * is a proper IEM implementation we just handle this here for now to avoid annoying 2223 * users too much. 2224 */ 2225 /* The following ASSUMES that the vCPU state is completely synced. */ 2226 2227 /* Read instruction. */ 2228 RTGCPTR GCPtrPage = pVCpu->cpum.GstCtx.Pc.u64 & ~(RTGCPTR)GUEST_PAGE_OFFSET_MASK; 2229 const void *pvPageR3 = NULL; 2230 PGMPAGEMAPLOCK PageMapLock; 2231 2232 rcStrict = PGMPhysGCPtr2CCPtrReadOnly(pVCpu, GCPtrPage, &pvPageR3, &PageMapLock); 2069 2233 if (rcStrict == VINF_SUCCESS) 2070 nemR3WinSetGReg(pVCpu, uReg, f64BitReg, fSignExtend, u64Val); 2234 { 2235 uint32_t u32Instr = *(uint32_t *)((uint8_t *)pvPageR3 + (pVCpu->cpum.GstCtx.Pc.u64 - GCPtrPage)); 2236 PGMPhysReleasePageMappingLock(pVCpu->pVMR3, &PageMapLock); 2237 2238 DISSTATE Dis; 2239 rcStrict = DISInstrWithPrefetchedBytes((uintptr_t)pVCpu->cpum.GstCtx.Pc.u64, DISCPUMODE_ARMV8_A64, 0 /*fFilter - none */, 2240 &u32Instr, sizeof(u32Instr), NULL, NULL, &Dis, NULL); 2241 if (rcStrict == VINF_SUCCESS) 2242 { 2243 if ( Dis.pCurInstr->uOpcode == OP_ARMV8_A64_LDRB 2244 && Dis.aParams[0].armv8.enmType == kDisArmv8OpParmReg 2245 && Dis.aParams[0].armv8.Op.Reg.enmRegType == kDisOpParamArmV8RegType_Gpr_32Bit 2246 && Dis.aParams[1].armv8.enmType == kDisArmv8OpParmAddrInGpr 2247 && Dis.aParams[1].armv8.Op.Reg.enmRegType == kDisOpParamArmV8RegType_Gpr_64Bit 2248 && (Dis.aParams[1].fUse & DISUSE_PRE_INDEXED)) 2249 { 2250 /* The fault address is already the final address. */ 2251 uint8_t bVal = 0; 2252 rcStrict = PGMPhysRead(pVM, GCPhys, &bVal, 1, PGMACCESSORIGIN_HM); 2253 Log4(("MmioExit/%u: %08RX64: READ %#RGp LB %u -> %.*Rhxs rcStrict=%Rrc\n", 2254 pVCpu->idCpu, pVCpu->cpum.GstCtx.Pc.u64, GCPhys, sizeof(bVal), sizeof(bVal), 2255 &bVal, VBOXSTRICTRC_VAL(rcStrict) )); 2256 if (rcStrict == VINF_SUCCESS) 2257 { 2258 nemR3WinSetGReg(pVCpu, Dis.aParams[0].armv8.Op.Reg.idReg, false /*f64BitReg*/, false /*fSignExtend*/, bVal); 2259 /* Update the indexed register. */ 2260 pVCpu->cpum.GstCtx.aGRegs[Dis.aParams[1].armv8.Op.Reg.idReg].x += Dis.aParams[1].armv8.u.offBase; 2261 } 2262 } 2263 else 2264 AssertFailedReturn(VERR_NOT_SUPPORTED); 2265 } 2266 } 2071 2267 } 2072 2268 … … 2234 2430 return nemR3WinHandleExitHypercall(pVM, pVCpu, pExit); 2235 2431 2432 case 0x8001000c: /* WHvRunVpExitReasonArm64Reset */ 2433 { 2434 if (pExit->Arm64Reset.ResetType == WHV_ARM64_RESET_CONTEXT_TYPE_POWER_OFF) 2435 return VMR3PowerOff(pVM->pUVM); 2436 else if (pExit->Arm64Reset.ResetType == WHV_ARM64_RESET_CONTEXT_TYPE_RESET) 2437 { 2438 VM_FF_SET(pVM, VM_FF_RESET); 2439 return VINF_EM_RESET; 2440 } 2441 else 2442 AssertLogRelFailedReturn(VERR_NEM_IPE_3); 2443 } 2444 2236 2445 case WHvRunVpExitReasonUnrecoverableException: 2237 2446 STAM_REL_COUNTER_INC(&pVCpu->nem.s.StatExitUnrecoverable);
Note:
See TracChangeset
for help on using the changeset viewer.