VirtualBox

Changeset 106983 in vbox for trunk/src/VBox/VMM/VMMR3


Ignore:
Timestamp:
Nov 13, 2024 12:12:30 PM (2 months ago)
Author:
vboxsync
Message:

VMM/NEMR3Native-win-armv8.cpp: More state syncing, it is now possible to query and overwrite the ID registers, bugref:10392

File:
1 edited

Legend:

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

    r106952 r106983  
    5454#include <winerror.h> /* no api header for this. */
    5555
     56#include <VBox/dis.h>
    5657#include <VBox/vmm/nem.h>
    5758#include <VBox/vmm/iem.h>
     
    128129
    129130/**
     131 * The ARM64 reset context.
     132 */
     133typedef 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;
     139typedef MY_WHV_ARM64_RESET_CONTEXT *PMY_WHV_ARM64_RESET_CONTEXT;
     140AssertCompileSize(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/**
    130148 * The exit reason context for arm64, the size is different
    131149 * from the default SDK we build against.
     
    142160        MY_WHV_HYPERCALL_CONTEXT            Hypercall;
    143161        WHV_UNRECOVERABLE_EXCEPTION_CONTEXT UnrecoverableException;
     162        MY_WHV_ARM64_RESET_CONTEXT          Arm64Reset;
    144163        uint64_t au64Rsvd2[32];
    145164    };
     
    745764    HRESULT                hrc;
    746765
    747 #if 0
    748     /* 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 ? WHvProcessorVendorAmd
    752                              : 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 #endif
    759 
    760766    /* Not sure if we really need to set the cache line flush size. */
    761767    RT_ZERO(Property);
     
    821827        if (idCpu == 0)
    822828        {
    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             */
    824833            CPUMIDREGS IdRegs; RT_ZERO(IdRegs);
    825834
    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];
    829837            RT_ZERO(aValues);
    830838
     
    839847            aenmNames[8] = WHvArm64RegisterIdAa64Pfr0El1;
    840848            aenmNames[9] = WHvArm64RegisterIdAa64Pfr1El1;
    841             aenmNames[10] = WHvArm64RegisterCtrEl0;
    842             aenmNames[11] = WHvArm64RegisterDczidEl0;
    843849
    844850            hrc = WHvGetVirtualProcessorRegisters(hPartition, WHV_ANY_VP /*idCpu*/, aenmNames, RT_ELEMENTS(aenmNames), aValues);
     
    858864            IdRegs.u64RegIdAa64Mmfr1El1 = aValues[6].Reg64;
    859865            IdRegs.u64RegIdAa64Mmfr2El1 = aValues[7].Reg64;
    860             IdRegs.u64RegCtrEl0         = aValues[10].Reg64;
    861             IdRegs.u64RegDczidEl0       = aValues[11].Reg64;
    862 #else
    863             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 #endif
    875866
    876867            rc = CPUMR3PopulateFeaturesByIdRegisters(pVM, &IdRegs);
    877868            if (RT_FAILURE(rc))
    878869                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;
    879896        }
    880897
     
    11471164            iReg++; \
    11481165        } 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)
    11491172#define ADD_REG128(a_enmName, a_uValue) do { \
    11501173            aenmNames[iReg] = (a_enmName); \
     
    12011224    /* RIP & Flags */
    12021225    if (fWhat & CPUMCTX_EXTRN_PC)
    1203         ADD_REG64_RAW(WHvArm64RegisterPc, pVCpu->cpum.GstCtx.Pc.u64);
     1226        ADD_SYSREG64(WHvArm64RegisterPc, pVCpu->cpum.GstCtx.Pc);
    12041227    if (fWhat & CPUMCTX_EXTRN_PSTATE)
    12051228        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    }
    12061245
    12071246    /* Vector state. */
     
    12421281    }
    12431282
     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
    12441336#undef ADD_REG64
    12451337#undef ADD_REG64_RAW
     
    12661358NEM_TMPL_STATIC int nemHCWinCopyStateFromHyperV(PVMCC pVM, PVMCPUCC pVCpu, uint64_t fWhat)
    12671359{
    1268     WHV_REGISTER_NAME  aenmNames[128];
     1360    WHV_REGISTER_NAME  aenmNames[256];
    12691361
    12701362    fWhat &= pVCpu->cpum.GstCtx.fExtrn;
     
    13891481        aenmNames[iReg++] = WHvArm64RegisterEsrEl1;
    13901482        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
    13951494    if (fWhat & CPUMCTX_EXTRN_SYSREG_DEBUG)
    13961495    {
    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    }
    14011511
    14021512    if (fWhat & CPUMCTX_EXTRN_SYSREG_PAUTH_KEYS)
    14031513    {
    14041514        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;
    14061524    }
    14071525
     
    14121530     * Get the registers.
    14131531     */
    1414     WHV_REGISTER_VALUE aValues[128];
     1532    WHV_REGISTER_VALUE aValues[256];
    14151533    RT_ZERO(aValues);
    14161534    Assert(RT_ELEMENTS(aValues) >= cRegs);
     
    15571675    if (fWhat & CPUMCTX_EXTRN_SYSREG_MISC)
    15581676    {
    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
    15661691    if (fWhat & CPUMCTX_EXTRN_SYSREG_DEBUG)
    15671692    {
    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    }
    15721707
    15731708    if (fWhat & CPUMCTX_EXTRN_SYSREG_PAUTH_KEYS)
    15741709    {
    15751710        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);
    15771720    }
    15781721
     
    20432186    RT_NOREF(fL2Fault);
    20442187
    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        }
    20622215    }
    20632216    else
    20642217    {
    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);
    20692233        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        }
    20712267    }
    20722268
     
    22342430            return nemR3WinHandleExitHypercall(pVM, pVCpu, pExit);
    22352431
     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
    22362445        case WHvRunVpExitReasonUnrecoverableException:
    22372446            STAM_REL_COUNTER_INC(&pVCpu->nem.s.StatExitUnrecoverable);
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