- Timestamp:
- May 3, 2023 9:35:33 AM (17 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR3/NEMR3Native-darwin-armv8.cpp
r99379 r99575 284 284 285 285 /** 286 * Resolves a NEM page state from the given protection flags. 287 * 288 * @returns NEM page state. 289 * @param fPageProt The page protection flags. 290 */ 291 DECLINLINE(uint8_t) nemR3DarwinPageStateFromProt(uint32_t fPageProt) 292 { 293 switch (fPageProt) 294 { 295 case NEM_PAGE_PROT_NONE: 296 return NEM_DARWIN_PAGE_STATE_UNMAPPED; 297 case NEM_PAGE_PROT_READ | NEM_PAGE_PROT_EXECUTE: 298 return NEM_DARWIN_PAGE_STATE_RX; 299 case NEM_PAGE_PROT_READ | NEM_PAGE_PROT_WRITE: 300 return NEM_DARWIN_PAGE_STATE_RW; 301 case NEM_PAGE_PROT_READ | NEM_PAGE_PROT_WRITE | NEM_PAGE_PROT_EXECUTE: 302 return NEM_DARWIN_PAGE_STATE_RWX; 303 default: 304 break; 305 } 306 307 AssertLogRelMsgFailed(("Invalid combination of page protection flags %#x, can't map to page state!\n", fPageProt)); 308 return NEM_DARWIN_PAGE_STATE_UNMAPPED; 309 } 310 311 312 /** 286 313 * Unmaps the given guest physical address range (page aligned). 287 314 * … … 350 377 { 351 378 if (pu2State) 352 *pu2State = (fPageProt & NEM_PAGE_PROT_WRITE) 353 ? NEM_DARWIN_PAGE_STATE_WRITABLE 354 : NEM_DARWIN_PAGE_STATE_READABLE; 379 *pu2State = nemR3DarwinPageStateFromProt(fPageProt); 355 380 return VINF_SUCCESS; 356 381 } … … 496 521 497 522 /** 498 * State to pass between vmxHCExitEptViolation499 * and nemR3DarwinHandleMemoryAccessPageCheckerCallback.500 */501 typedef struct NEMHCDARWINHMACPCCSTATE502 {503 /** Input: Write access. */504 bool fWriteAccess;505 /** Output: Set if we did something. */506 bool fDidSomething;507 /** Output: Set it we should resume. */508 bool fCanResume;509 } NEMHCDARWINHMACPCCSTATE;510 511 /**512 * @callback_method_impl{FNPGMPHYSNEMCHECKPAGE,513 * Worker for vmxHCExitEptViolation; pvUser points to a514 * NEMHCDARWINHMACPCCSTATE structure. }515 */516 static DECLCALLBACK(int)517 nemR3DarwinHandleMemoryAccessPageCheckerCallback(PVMCC pVM, PVMCPUCC pVCpu, RTGCPHYS GCPhys, PPGMPHYSNEMPAGEINFO pInfo, void *pvUser)518 {519 RT_NOREF(pVCpu);520 521 NEMHCDARWINHMACPCCSTATE *pState = (NEMHCDARWINHMACPCCSTATE *)pvUser;522 pState->fDidSomething = false;523 pState->fCanResume = false;524 525 uint8_t u2State = pInfo->u2NemState;526 527 /*528 * Consolidate current page state with actual page protection and access type.529 * We don't really consider downgrades here, as they shouldn't happen.530 */531 switch (u2State)532 {533 case NEM_DARWIN_PAGE_STATE_UNMAPPED:534 case NEM_DARWIN_PAGE_STATE_NOT_SET:535 {536 if (pInfo->fNemProt == NEM_PAGE_PROT_NONE)537 {538 Log4(("nemR3DarwinHandleMemoryAccessPageCheckerCallback: %RGp - #1\n", GCPhys));539 return VINF_SUCCESS;540 }541 542 /* Don't bother remapping it if it's a write request to a non-writable page. */543 if ( pState->fWriteAccess544 && !(pInfo->fNemProt & NEM_PAGE_PROT_WRITE))545 {546 Log4(("nemR3DarwinHandleMemoryAccessPageCheckerCallback: %RGp - #1w\n", GCPhys));547 return VINF_SUCCESS;548 }549 550 int rc = VINF_SUCCESS;551 if (pInfo->fNemProt & NEM_PAGE_PROT_WRITE)552 {553 void *pvPage;554 rc = nemR3NativeGCPhys2R3PtrWriteable(pVM, GCPhys, &pvPage);555 if (RT_SUCCESS(rc))556 rc = nemR3DarwinMap(pVM, GCPhys & ~(RTGCPHYS)X86_PAGE_OFFSET_MASK, pvPage, X86_PAGE_SIZE, pInfo->fNemProt, &u2State);557 }558 else if (pInfo->fNemProt & NEM_PAGE_PROT_READ)559 {560 const void *pvPage;561 rc = nemR3NativeGCPhys2R3PtrReadOnly(pVM, GCPhys, &pvPage);562 if (RT_SUCCESS(rc))563 rc = nemR3DarwinMap(pVM, GCPhys & ~(RTGCPHYS)X86_PAGE_OFFSET_MASK, pvPage, X86_PAGE_SIZE, pInfo->fNemProt, &u2State);564 }565 else /* Only EXECUTE doesn't work. */566 AssertReleaseFailed();567 568 pInfo->u2NemState = u2State;569 Log4(("nemR3DarwinHandleMemoryAccessPageCheckerCallback: %RGp - synced => %s + %Rrc\n",570 GCPhys, g_apszPageStates[u2State], rc));571 pState->fDidSomething = true;572 pState->fCanResume = true;573 return rc;574 }575 case NEM_DARWIN_PAGE_STATE_READABLE:576 if ( !(pInfo->fNemProt & NEM_PAGE_PROT_WRITE)577 && (pInfo->fNemProt & (NEM_PAGE_PROT_READ | NEM_PAGE_PROT_EXECUTE)))578 {579 pState->fCanResume = true;580 Log4(("nemR3DarwinHandleMemoryAccessPageCheckerCallback: %RGp - #2\n", GCPhys));581 return VINF_SUCCESS;582 }583 break;584 585 case NEM_DARWIN_PAGE_STATE_WRITABLE:586 if (pInfo->fNemProt & NEM_PAGE_PROT_WRITE)587 {588 pState->fCanResume = true;589 if (pInfo->u2OldNemState == NEM_DARWIN_PAGE_STATE_WRITABLE)590 Log4(("nemR3DarwinHandleMemoryAccessPageCheckerCallback: Spurious EPT fault\n", GCPhys));591 return VINF_SUCCESS;592 }593 break;594 595 default:596 AssertLogRelMsgFailedReturn(("u2State=%#x\n", u2State), VERR_NEM_IPE_4);597 }598 599 /* Unmap and restart the instruction. */600 int rc = nemR3DarwinUnmap(pVM, GCPhys & ~(RTGCPHYS)X86_PAGE_OFFSET_MASK, X86_PAGE_SIZE, &u2State);601 if (RT_SUCCESS(rc))602 {603 pInfo->u2NemState = u2State;604 pState->fDidSomething = true;605 pState->fCanResume = true;606 Log5(("NEM GPA unmapped/exit: %RGp (was %s)\n", GCPhys, g_apszPageStates[u2State]));607 return VINF_SUCCESS;608 }609 610 LogRel(("nemR3DarwinHandleMemoryAccessPageCheckerCallback/unmap: GCPhys=%RGp %s rc=%Rrc\n",611 GCPhys, g_apszPageStates[u2State], rc));612 return VERR_NEM_UNMAP_PAGES_FAILED;613 }614 615 616 /**617 523 * Exports the guest state to HV for execution. 618 524 * … … 947 853 DECLINLINE(uint64_t) nemR3DarwinGetGReg(PVMCPU pVCpu, uint8_t uReg) 948 854 { 949 AssertReturn(uReg < 31, 0); 855 AssertReturn(uReg <= ARMV8_AARCH64_REG_ZR, 0); 856 857 if (uReg == ARMV8_AARCH64_REG_ZR) 858 return 0; 950 859 951 860 /** @todo Import the register if extern. */ … … 991 900 992 901 VBOXSTRICTRC rcStrict = VINF_SUCCESS; 993 uint64_t u64Val ;902 uint64_t u64Val = 0; 994 903 if (fWrite) 995 904 { … … 1076 985 1077 986 /** 987 * Works on the trapped HVC instruction exception. 988 * 989 * @returns VBox strict status code. 990 * @param pVM The cross context VM structure. 991 * @param pVCpu The cross context virtual CPU structure of the 992 * calling EMT. 993 * @param uIss The instruction specific syndrome value. 994 */ 995 static VBOXSTRICTRC nemR3DarwinHandleExitExceptionTrappedHvcInsn(PVM pVM, PVMCPU pVCpu, uint32_t uIss) 996 { 997 uint16_t u16Imm = ARMV8_EC_ISS_AARCH64_TRAPPED_HVC_INSN_IMM_GET(uIss); 998 LogFlowFunc(("u16Imm=%#RX16\n", u16Imm)); 999 1000 #if 0 /** @todo For later */ 1001 EMHistoryAddExit(pVCpu, 1002 fRead 1003 ? EMEXIT_MAKE_FT(EMEXIT_F_KIND_EM, EMEXITTYPE_MSR_READ) 1004 : EMEXIT_MAKE_FT(EMEXIT_F_KIND_EM, EMEXITTYPE_MSR_WRITE), 1005 pVCpu->cpum.GstCtx.Pc.u64, ASMReadTSC()); 1006 #endif 1007 1008 RT_NOREF(pVM); 1009 VBOXSTRICTRC rcStrict = VINF_SUCCESS; 1010 /** @todo Raise exception to EL1 if PSCI not configured. */ 1011 /** @todo Need a generic mechanism here to pass this to, GIM maybe?. Always return -1 for now (PSCI). */ 1012 nemR3DarwinSetGReg(pVCpu, ARMV8_AARCH64_REG_X0, true /*f64BitReg*/, false /*fSignExtend*/, (uint64_t)-1); 1013 1014 return rcStrict; 1015 } 1016 1017 1018 /** 1078 1019 * Handles an exception VM exit. 1079 1020 * … … 1100 1041 case ARMV8_ESR_EL2_EC_AARCH64_TRAPPED_SYS_INSN: 1101 1042 return nemR3DarwinHandleExitExceptionTrappedSysInsn(pVM, pVCpu, uIss, fInsn32Bit); 1043 case ARMV8_ESR_EL2_EC_AARCH64_HVC_INSN: 1044 return nemR3DarwinHandleExitExceptionTrappedHvcInsn(pVM, pVCpu, uIss); 1045 case ARMV8_ESR_EL2_EC_TRAPPED_WFX: 1046 return VINF_EM_HALT; 1102 1047 case ARMV8_ESR_EL2_EC_UNKNOWN: 1103 1048 default: 1104 1049 LogRel(("NEM/Darwin: Unknown Exception Class in syndrome: uEc=%u{%s} uIss=%#RX32 fInsn32Bit=%RTbool\n", 1105 1050 uEc, nemR3DarwinEsrEl2EcStringify(uEc), uIss, fInsn32Bit)); 1051 AssertReleaseFailed(); 1106 1052 return VERR_NOT_IMPLEMENTED; 1107 1053 } … … 1137 1083 case HV_EXIT_REASON_EXCEPTION: 1138 1084 return nemR3DarwinHandleExitException(pVM, pVCpu, pExit); 1085 case HV_EXIT_REASON_VTIMER_ACTIVATED: 1086 return VINF_EM_RESCHEDULE; 1139 1087 default: 1140 1088 AssertReleaseFailed();
Note:
See TracChangeset
for help on using the changeset viewer.

