VirtualBox

Changeset 106666 in vbox for trunk/src/VBox/VMM


Ignore:
Timestamp:
Oct 24, 2024 4:42:23 PM (4 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
165520
Message:

VMM/ARM: Workaround for the UEFI accessing MMIO space with an instruction which doesn't produce a valid instruction syndrome, bugref:10732

Location:
trunk/src/VBox/VMM/VMMR3
Files:
2 edited

Legend:

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

    r106476 r106666  
    3636#define LOG_GROUP LOG_GROUP_NEM
    3737#define VMCPU_INCL_CPUM_GST_CTX
     38#define VBOX_DIS_WITH_ARMV8
     39
    3840#include <VBox/vmm/nem.h>
    3941#include <VBox/vmm/iem.h>
     
    4648#include <VBox/vmm/vmcc.h>
    4749#include <VBox/vmm/vmm.h>
     50#include <VBox/dis.h>
    4851#include <VBox/gic.h>
    4952#include "dtrace/VBoxVMM.h"
     
    16611664    }
    16621665
    1663     AssertReturn(fIsv, VERR_NOT_SUPPORTED); /** @todo Implement using IEM when this should occur. */
    1664 
    1665     EMHistoryAddExit(pVCpu,
    1666                      fWrite
    1667                      ? EMEXIT_MAKE_FT(EMEXIT_F_KIND_EM, EMEXITTYPE_MMIO_WRITE)
    1668                      : EMEXIT_MAKE_FT(EMEXIT_F_KIND_EM, EMEXITTYPE_MMIO_READ),
    1669                      pVCpu->cpum.GstCtx.Pc.u64, ASMReadTSC());
    1670 
    1671     VBOXSTRICTRC rcStrict = VINF_SUCCESS;
    1672     uint64_t u64Val = 0;
    1673     if (fWrite)
    1674     {
    1675         u64Val = nemR3DarwinGetGReg(pVCpu, uReg);
    1676         rcStrict = PGMPhysWrite(pVM, GCPhysDataAbrt, &u64Val, cbAcc, PGMACCESSORIGIN_HM);
    1677         Log4(("MmioExit/%u: %08RX64: WRITE %#RGp LB %u, %.*Rhxs -> rcStrict=%Rrc\n",
    1678               pVCpu->idCpu, pVCpu->cpum.GstCtx.Pc.u64, GCPhysDataAbrt, cbAcc, cbAcc,
    1679               &u64Val, VBOXSTRICTRC_VAL(rcStrict) ));
     1666    VBOXSTRICTRC rcStrict;
     1667    if (fIsv)
     1668    {
     1669        EMHistoryAddExit(pVCpu,
     1670                         fWrite
     1671                         ? EMEXIT_MAKE_FT(EMEXIT_F_KIND_EM, EMEXITTYPE_MMIO_WRITE)
     1672                         : EMEXIT_MAKE_FT(EMEXIT_F_KIND_EM, EMEXITTYPE_MMIO_READ),
     1673                         pVCpu->cpum.GstCtx.Pc.u64, ASMReadTSC());
     1674
     1675        uint64_t u64Val = 0;
     1676        if (fWrite)
     1677        {
     1678            u64Val = nemR3DarwinGetGReg(pVCpu, uReg);
     1679            rcStrict = PGMPhysWrite(pVM, GCPhysDataAbrt, &u64Val, cbAcc, PGMACCESSORIGIN_HM);
     1680            Log4(("MmioExit/%u: %08RX64: WRITE %#RGp LB %u, %.*Rhxs -> rcStrict=%Rrc\n",
     1681                  pVCpu->idCpu, pVCpu->cpum.GstCtx.Pc.u64, GCPhysDataAbrt, cbAcc, cbAcc,
     1682                  &u64Val, VBOXSTRICTRC_VAL(rcStrict) ));
     1683        }
     1684        else
     1685        {
     1686            rcStrict = PGMPhysRead(pVM, GCPhysDataAbrt, &u64Val, cbAcc, PGMACCESSORIGIN_HM);
     1687            Log4(("MmioExit/%u: %08RX64: READ %#RGp LB %u -> %.*Rhxs rcStrict=%Rrc\n",
     1688                  pVCpu->idCpu, pVCpu->cpum.GstCtx.Pc.u64, GCPhysDataAbrt, cbAcc, cbAcc,
     1689                  &u64Val, VBOXSTRICTRC_VAL(rcStrict) ));
     1690            if (rcStrict == VINF_SUCCESS)
     1691                nemR3DarwinSetGReg(pVCpu, uReg, f64BitReg, fSignExtend, u64Val);
     1692        }
    16801693    }
    16811694    else
    16821695    {
    1683         rcStrict = PGMPhysRead(pVM, GCPhysDataAbrt, &u64Val, cbAcc, PGMACCESSORIGIN_HM);
    1684         Log4(("MmioExit/%u: %08RX64: READ %#RGp LB %u -> %.*Rhxs rcStrict=%Rrc\n",
    1685               pVCpu->idCpu, pVCpu->cpum.GstCtx.Pc.u64, GCPhysDataAbrt, cbAcc, cbAcc,
    1686               &u64Val, VBOXSTRICTRC_VAL(rcStrict) ));
     1696        /** @todo Our UEFI firmware accesses the flash region with the following instruction
     1697         *        when the NVRAM actually contains data:
     1698         *             ldrb w9, [x6, #-0x0001]!
     1699         *        This is too complicated for the hardware so the ISV bit is not set. Until there
     1700         *        is a proper IEM implementation we just handle this here for now to avoid annoying
     1701         *        users too much.
     1702         */
     1703        /* The following ASSUMES that the vCPU state is completely synced. */
     1704
     1705        /* Read instruction. */
     1706        RTGCPTR GCPtrPage = pVCpu->cpum.GstCtx.Pc.u64 & ~(RTGCPTR)GUEST_PAGE_OFFSET_MASK;
     1707        const void *pvPageR3 = NULL;
     1708        PGMPAGEMAPLOCK  PageMapLock;
     1709
     1710        rcStrict = PGMPhysGCPtr2CCPtrReadOnly(pVCpu, GCPtrPage, &pvPageR3, &PageMapLock);
    16871711        if (rcStrict == VINF_SUCCESS)
    1688             nemR3DarwinSetGReg(pVCpu, uReg, f64BitReg, fSignExtend, u64Val);
     1712        {
     1713            uint32_t u32Instr = *(uint32_t *)((uint8_t *)pvPageR3 + (pVCpu->cpum.GstCtx.Pc.u64 - GCPtrPage));
     1714            PGMPhysReleasePageMappingLock(pVCpu->pVMR3, &PageMapLock);
     1715
     1716            DISSTATE Dis;
     1717            rcStrict = DISInstrWithPrefetchedBytes((uintptr_t)pVCpu->cpum.GstCtx.Pc.u64, DISCPUMODE_ARMV8_A64,  0 /*fFilter - none */,
     1718                                                   &u32Instr, sizeof(u32Instr), NULL, NULL, &Dis, NULL);
     1719            if (rcStrict == VINF_SUCCESS)
     1720            {
     1721                if (   Dis.pCurInstr->uOpcode == OP_ARMV8_A64_LDRB
     1722                    && Dis.aParams[0].armv8.enmType == kDisArmv8OpParmReg
     1723                    && Dis.aParams[0].armv8.Op.Reg.enmRegType == kDisOpParamArmV8RegType_Gpr_32Bit
     1724                    && Dis.aParams[1].armv8.enmType == kDisArmv8OpParmAddrInGpr
     1725                    && Dis.aParams[1].armv8.Op.Reg.enmRegType == kDisOpParamArmV8RegType_Gpr_64Bit
     1726                    && (Dis.aParams[1].fUse & DISUSE_PRE_INDEXED))
     1727                {
     1728                    /* The fault address is already the final address. */
     1729                    uint64_t u64Val = 0;
     1730                    rcStrict = PGMPhysRead(pVM, GCPhysDataAbrt, &u64Val, cbAcc, PGMACCESSORIGIN_HM);
     1731                    Log4(("MmioExit/%u: %08RX64: READ %#RGp LB %u -> %.*Rhxs rcStrict=%Rrc\n",
     1732                          pVCpu->idCpu, pVCpu->cpum.GstCtx.Pc.u64, GCPhysDataAbrt, cbAcc, cbAcc,
     1733                          &u64Val, VBOXSTRICTRC_VAL(rcStrict) ));
     1734                    if (rcStrict == VINF_SUCCESS)
     1735                    {
     1736                        nemR3DarwinSetGReg(pVCpu, Dis.aParams[0].armv8.Op.Reg.idReg, false /*f64BitReg*/, false /*fSignExtend*/, u64Val);
     1737                        /* Update the indexed register. */
     1738                        pVCpu->cpum.GstCtx.aGRegs[Dis.aParams[1].armv8.Op.Reg.idReg].x += Dis.aParams[1].armv8.u.offBase;
     1739                    }
     1740                }
     1741                else
     1742                    AssertFailedReturn(VERR_NOT_SUPPORTED);
     1743            }
     1744        }
    16891745    }
    16901746
  • trunk/src/VBox/VMM/VMMR3/PGM-armv8.cpp

    r106389 r106666  
    781781    VMCPU_ASSERT_EMT(pVCpu);
    782782    Assert(pWalk);
    783 #ifndef DEBUG_aeichner
    784     AssertReleaseFailed();
    785     RT_NOREF(pVCpu, GCPtr, pWalk);
    786     return VERR_NOT_IMPLEMENTED;
    787 #else
     783
    788784    pWalk->fSucceeded = false;
    789785
     
    930926    pWalk->GCPhys     = (RTGCPHYS)(uPt & UINT64_C(0xfffffffff000)) | (GCPtr & (RTGCPTR)(_4K - 1));
    931927    return VINF_SUCCESS;
    932 #endif
    933928}
    934929
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