VirtualBox

Changeset 99575 in vbox


Ignore:
Timestamp:
May 3, 2023 9:35:33 AM (17 months ago)
Author:
vboxsync
Message:

VMM/NEMR3Native-darwin-armv8.cpp: Fixes and stubbing the hvc exception handling, bugref:10390

File:
1 edited

Legend:

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

    r99379 r99575  
    284284
    285285/**
     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 */
     291DECLINLINE(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/**
    286313 * Unmaps the given guest physical address range (page aligned).
    287314 *
     
    350377    {
    351378        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);
    355380        return VINF_SUCCESS;
    356381    }
     
    496521
    497522/**
    498  * State to pass between vmxHCExitEptViolation
    499  * and nemR3DarwinHandleMemoryAccessPageCheckerCallback.
    500  */
    501 typedef struct NEMHCDARWINHMACPCCSTATE
    502 {
    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 a
    514  *      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->fWriteAccess
    544                 && !(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 /**
    617523 * Exports the guest state to HV for execution.
    618524 *
     
    947853DECLINLINE(uint64_t) nemR3DarwinGetGReg(PVMCPU pVCpu, uint8_t uReg)
    948854{
    949     AssertReturn(uReg < 31, 0);
     855    AssertReturn(uReg <= ARMV8_AARCH64_REG_ZR, 0);
     856
     857    if (uReg == ARMV8_AARCH64_REG_ZR)
     858        return 0;
    950859
    951860    /** @todo Import the register if extern. */
     
    991900
    992901    VBOXSTRICTRC rcStrict = VINF_SUCCESS;
    993     uint64_t u64Val;
     902    uint64_t u64Val = 0;
    994903    if (fWrite)
    995904    {
     
    1076985
    1077986/**
     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 */
     995static 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/**
    10781019 * Handles an exception VM exit.
    10791020 *
     
    11001041        case ARMV8_ESR_EL2_EC_AARCH64_TRAPPED_SYS_INSN:
    11011042            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;
    11021047        case ARMV8_ESR_EL2_EC_UNKNOWN:
    11031048        default:
    11041049            LogRel(("NEM/Darwin: Unknown Exception Class in syndrome: uEc=%u{%s} uIss=%#RX32 fInsn32Bit=%RTbool\n",
    11051050                    uEc, nemR3DarwinEsrEl2EcStringify(uEc), uIss, fInsn32Bit));
     1051            AssertReleaseFailed();
    11061052            return VERR_NOT_IMPLEMENTED;
    11071053    }
     
    11371083        case HV_EXIT_REASON_EXCEPTION:
    11381084            return nemR3DarwinHandleExitException(pVM, pVCpu, pExit);
     1085        case HV_EXIT_REASON_VTIMER_ACTIVATED:
     1086            return VINF_EM_RESCHEDULE;
    11391087        default:
    11401088            AssertReleaseFailed();
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