VirtualBox

Changeset 22727 in vbox for trunk


Ignore:
Timestamp:
Sep 2, 2009 11:08:23 PM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
51854
Message:

AHCI: Fallback to a safe method for processing the PRDTL if mapping guest RAM fails

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Storage/DevAHCI.cpp

    r22480 r22727  
    40684068
    40694069/**
     4070 * Fallback scatter gather list creator.
     4071 * Used if the normal one fails in PDMDevHlpPhysGCPhys2CCPtr() or
     4072 * PDMDevHlpPhysGCPhys2CCPtrReadonly()
     4073 *
     4074 * returns VBox status code.
     4075 * @param   pAhciPort              The ahci port.
     4076 * @param   pAhciPortTaskState     The task state which contains the S/G list entries.
     4077 * @param   fReadonly              If the mappings should be readonly.
     4078 * @param   cSGEntriesProcessed    Number of entries the normal creator procecssed
     4079 *                                 before an error occurred. Used to free
     4080 *                                 any ressources allocated before.
     4081 * @thread  EMT
     4082 */
     4083static int ahciScatterGatherListCreateSafe(PAHCIPort pAhciPort, PAHCIPORTTASKSTATE pAhciPortTaskState,
     4084                                           bool fReadonly, unsigned cSGEntriesProcessed)
     4085{
     4086    CmdHdr                    *pCmdHdr = &pAhciPortTaskState->cmdHdr;
     4087    PPDMDEVINS                 pDevIns = pAhciPort->CTX_SUFF(pDevIns);
     4088    PAHCIPORTTASKSTATESGENTRY  pSGInfoCurr  = pAhciPortTaskState->paSGEntries;
     4089
     4090    AssertPtr(pAhciPortTaskState->pSGListHead);
     4091    AssertPtr(pAhciPortTaskState->paSGEntries);
     4092
     4093    for (unsigned cSGEntryCurr = 0; cSGEntryCurr < cSGEntriesProcessed; cSGEntryCurr++)
     4094    {
     4095        if (pSGInfoCurr->fGuestMemory)
     4096        {
     4097            /* Release the lock. */
     4098            PDMDevHlpPhysReleasePageMappingLock(pDevIns, &pSGInfoCurr->u.direct.PageLock);
     4099        }
     4100
     4101        /* Go to the next entry. */
     4102        pSGInfoCurr++;
     4103    }
     4104
     4105    if (pAhciPortTaskState->pvBufferUnaligned)
     4106        RTMemFree(pAhciPortTaskState->pvBufferUnaligned);
     4107
     4108    pAhciPortTaskState->cSGListTooBig     = 0;
     4109
     4110    RTMemFree(pAhciPortTaskState->pSGListHead);
     4111    RTMemFree(pAhciPortTaskState->paSGEntries);
     4112    pAhciPortTaskState->cSGEntries = 1;
     4113    pAhciPortTaskState->cSGListSize = 1;
     4114    pAhciPortTaskState->cbBufferUnaligned = pAhciPortTaskState->cbTransfer;
     4115
     4116    /* Allocate new buffers and SG lists. */
     4117    pAhciPortTaskState->pvBufferUnaligned = RTMemAlloc(pAhciPortTaskState->cbTransfer);
     4118    if (!pAhciPortTaskState->pvBufferUnaligned)
     4119        return VERR_NO_MEMORY;
     4120
     4121    pAhciPortTaskState->pSGListHead = (PPDMDATASEG)RTMemAllocZ(1 * sizeof(PDMDATASEG));
     4122    if (!pAhciPortTaskState->pSGListHead)
     4123    {
     4124        RTMemFree(pAhciPortTaskState->pvBufferUnaligned);
     4125        return VERR_NO_MEMORY;
     4126    }
     4127
     4128    pAhciPortTaskState->paSGEntries = (PAHCIPORTTASKSTATESGENTRY)RTMemAllocZ(1 * sizeof(AHCIPORTTASKSTATESGENTRY));
     4129    if (!pAhciPortTaskState->paSGEntries)
     4130    {
     4131        RTMemFree(pAhciPortTaskState->pvBufferUnaligned);
     4132        RTMemFree(pAhciPortTaskState->pSGListHead);
     4133        return VERR_NO_MEMORY;
     4134    }
     4135
     4136    /* Set pointers. */
     4137    pAhciPortTaskState->pSGListHead[0].cbSeg = pAhciPortTaskState->cbTransfer;
     4138    pAhciPortTaskState->pSGListHead[0].pvSeg = pAhciPortTaskState->pvBufferUnaligned;
     4139
     4140    pAhciPortTaskState->paSGEntries[0].fGuestMemory = false;
     4141    pAhciPortTaskState->paSGEntries[0].u.temp.cUnaligned   = AHCI_CMDHDR_PRDTL_ENTRIES(pCmdHdr->u32DescInf);
     4142    pAhciPortTaskState->paSGEntries[0].u.temp.GCPhysAddrBaseFirstUnaligned = AHCI_RTGCPHYS_FROM_U32(pCmdHdr->u32CmdTblAddrUp, pCmdHdr->u32CmdTblAddr) + AHCI_CMDHDR_PRDT_OFFSET;
     4143
     4144    if (pAhciPortTaskState->uTxDir == PDMBLOCKTXDIR_TO_DEVICE)
     4145        ahciCopyFromSGListIntoBuffer(pDevIns, &pAhciPortTaskState->paSGEntries[0]);
     4146
     4147    return VINF_SUCCESS;
     4148}
     4149
     4150/**
    40704151 * Create scatter gather list descriptors.
    40714152 *
     
    40824163    PPDMDEVINS pDevIns = pAhciPort->CTX_SUFF(pDevIns);
    40834164    unsigned   cActualSGEntry;
    4084     unsigned   cSGEntriesR3   = 0;             /* Needed scatter gather list entries in R3. */
     4165    unsigned   cSGEntriesR3 = 0;               /* Needed scatter gather list entries in R3. */
     4166    unsigned   cSGEntriesProcessed = 0;        /* Number of SG entries procesed. */
    40854167    SGLEntry   aSGLEntry[32];                  /* Holds read sg entries from guest. Biggest seen number of entries a guest set up. */
    40864168    unsigned   cSGLEntriesGCRead;
     
    42194301                                pSGInfoCurr++;
    42204302                                pSGEntryCurr++;
     4303                                cSGEntriesProcessed++;
    42214304                            }
    42224305                        }
     
    43034386
    43044387                                        if (RT_FAILURE(rc))
    4305                                             AssertMsgFailed(("Creating mapping failed rc=%Rrc\n", rc));
     4388                                        {
     4389                                            /* Mapping failed. Fall back to a bounce buffer. */
     4390                                            ahciLog(("%s: Mapping guest physical address %RGp failed with rc=%Rc\n",
     4391                                                     __FUNCTION__, GCPhysBufferPageAligned, rc));
     4392
     4393                                            return ahciScatterGatherListCreateSafe(pAhciPort, pAhciPortTaskState, fReadonly,
     4394                                                                                   cSGEntriesProcessed);
     4395                                        }
    43064396
    43074397                                        if ((pbMapping + (GCPhysAddrDataBase - GCPhysBufferPageAligned) == ((uint8_t *)pSGEntryPrev->pvSeg + pSGEntryCurr->cbSeg)))
     
    43294419                                        pSGInfoPrev  = pSGInfoCurr;
    43304420                                        pSGInfoCurr++;
     4421                                        cSGEntriesProcessed++;
    43314422                                    }
    43324423                                    else
     
    43714462
    43724463                                    if (RT_FAILURE(rc))
    4373                                         AssertMsgFailed(("Creating mapping failed rc=%Rrc\n", rc));
     4464                                    {
     4465                                        /* Mapping failed. Fall back to a bounce buffer. */
     4466                                        ahciLog(("%s: Mapping guest physical address %RGp failed with rc=%Rc\n",
     4467                                                    __FUNCTION__, GCPhysAddrDataBase, rc));
     4468
     4469                                        return ahciScatterGatherListCreateSafe(pAhciPort, pAhciPortTaskState, fReadonly,
     4470                                                                               cSGEntriesProcessed);
     4471                                    }
    43744472
    43754473                                    /* Check for adjacent mappings. */
     
    43964494                                    pSGInfoPrev = pSGInfoCurr;
    43974495                                    pSGInfoCurr++;
     4496                                    cSGEntriesProcessed++;
    43984497                                }
    43994498                                else
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