VirtualBox

Changeset 89993 in vbox


Ignore:
Timestamp:
Jul 2, 2021 9:21:45 AM (4 years ago)
Author:
vboxsync
Message:

VMM/HMVMX/EM: Do a rendezvous when a split-lock #AC is emulated. Currently doing this for single-cpu VMs too, will change that after some testing. bugref:10052

Location:
trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/err.h

    r89695 r89993  
    264264/** Trick for resuming EMHistoryExec after a VMCPU_FF_IOM is handled. */
    265265#define VINF_EM_RESUME_R3_HISTORY_EXEC       1161
     266/** Emulate split-lock access on SMP. */
     267#define VINF_EM_EMULATE_SPLIT_LOCK           1162
    266268/** @} */
    267269
  • trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp

    r89980 r89993  
    1418914189         * detection on the host.  This isn't all that satisfactory, though...
    1419014190         */
    14191         Log8Func(("cs:rip=%#04x:%#RX64 rflags=%#RX64 cr0=%#RX64 split-lock #AC?\n", pVCpu->cpum.GstCtx.cs.Sel,
     14191#if 0
     14192        Log8Func(("cs:rip=%#04x:%#RX64 rflags=%#RX64 cr0=%#RX64 split-lock #AC\n", pVCpu->cpum.GstCtx.cs.Sel,
    1419214193                  pVCpu->cpum.GstCtx.rip, pVCpu->cpum.GstCtx.rflags, pVCpu->cpum.GstCtx.cr0));
    1419314194
     
    1421114212        }
    1421214213        return rcStrict;
     14214#else
     14215        Log8Func(("cs:rip=%#04x:%#RX64 rflags=%#RX64 cr0=%#RX64 split-lock #AC -> VINF_EM_EMULATE_SPLIT_LOCK\n",
     14216                  pVCpu->cpum.GstCtx.cs.Sel, pVCpu->cpum.GstCtx.rip, pVCpu->cpum.GstCtx.rflags, pVCpu->cpum.GstCtx.cr0));
     14217        return VINF_EM_EMULATE_SPLIT_LOCK;
     14218#endif
    1421314219    }
    1421414220
  • trunk/src/VBox/VMM/VMMR3/EM.cpp

    r87594 r89993  
    789789
    790790/**
     791 * @callback_method_impl{FNVMMEMTRENDEZVOUS,
     792 * Worker for emR3ExecuteSplitLockInstruction}
     793 */
     794static DECLCALLBACK(VBOXSTRICTRC) emR3ExecuteSplitLockInstructionRendezvous(PVM pVM, PVMCPU pVCpu, void *pvUser)
     795{
     796    /* Only execute on the specified EMT. */
     797    if (pVCpu == (PVMCPU)pvUser)
     798    {
     799        LogFunc(("\n"));
     800        VBOXSTRICTRC rcStrict = IEMExecOneIgnoreLock(pVCpu);
     801        LogFunc(("rcStrict=%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
     802        if (rcStrict == VINF_IEM_RAISED_XCPT)
     803            rcStrict = VINF_SUCCESS;
     804        return rcStrict;
     805    }
     806    RT_NOREF(pVM);
     807    return VINF_SUCCESS;
     808}
     809
     810
     811/**
     812 * Handle an instruction causing a split cacheline lock access in SMP VMs.
     813 *
     814 * Generally we only get here if the host has split-lock detection enabled and
     815 * this caused an \#AC because of something the guest did.  If we interpret the
     816 * instruction as-is, we'll likely just repeat the split-lock access and
     817 * possibly be killed, get a SIGBUS, or trigger a warning followed by extra MSR
     818 * changes on context switching (costs a tiny bit).  Assuming these \#ACs are
     819 * rare to non-existing, we'll do a rendezvous of all EMTs and tell IEM to
     820 * disregard the lock prefix when emulating the instruction.
     821 *
     822 * Yes, we could probably modify the MSR (or MSRs) controlling the detection
     823 * feature when entering guest context, but the support for the feature isn't a
     824 * 100% given and we'll need the debug-only supdrvOSMsrProberRead and
     825 * supdrvOSMsrProberWrite functionality from SUPDrv.cpp to safely detect it.
     826 * Thus the approach is to just deal with the spurious \#ACs first and maybe add
     827 * propert detection to SUPDrv later if we find it necessary.
     828 *
     829 * @see     @bugref{10052}
     830 *
     831 * @returns Strict VBox status code.
     832 * @param   pVM     The cross context VM structure.
     833 * @param   pVCpu   The cross context virtual CPU structure.
     834 */
     835VBOXSTRICTRC emR3ExecuteSplitLockInstruction(PVM pVM, PVMCPU pVCpu)
     836{
     837    LogFunc(("\n"));
     838    return VMMR3EmtRendezvous(pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_ALL_AT_ONCE, emR3ExecuteSplitLockInstructionRendezvous, pVCpu);
     839}
     840
     841
     842/**
    791843 * Debug loop.
    792844 *
  • trunk/src/VBox/VMM/include/EMHandleRCTmpl.h

    r82968 r89993  
    166166            if (rc == VERR_IEM_ASPECT_NOT_IMPLEMENTED)
    167167                rc = emR3ExecuteInstruction(pVM, pVCpu, "EVENT: ");
     168            break;
     169
     170        case VINF_EM_EMULATE_SPLIT_LOCK:
     171            rc = VBOXSTRICTRC_TODO(emR3ExecuteSplitLockInstruction(pVM, pVCpu));
    168172            break;
    169173
  • trunk/src/VBox/VMM/include/EMInternal.h

    r82968 r89993  
    362362VBOXSTRICTRC    emR3ExecutePendingIoPortWrite(PVM pVM, PVMCPU pVCpu);
    363363VBOXSTRICTRC    emR3ExecutePendingIoPortRead(PVM pVM, PVMCPU pVCpu);
     364VBOXSTRICTRC    emR3ExecuteSplitLockInstruction(PVM pVM, PVMCPU pVCpu);
    364365
    365366RT_C_DECLS_END
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