VirtualBox

Changeset 15815 in vbox


Ignore:
Timestamp:
Jan 5, 2009 7:42:23 PM (16 years ago)
Author:
vboxsync
Message:

fix Linux passthrough by introducing a double buffer which is required as long as we don't use vm_insert_page()

Location:
trunk
Files:
4 edited

Legend:

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

    r15482 r15815  
    3232
    3333#include <iprt/assert.h>
     34
     35#define SCSI_MAX_BUFFER_SIZE (100 * _1K)
    3436
    3537
  • trunk/src/VBox/Devices/Storage/DevATA.cpp

    r15711 r15815  
    17891789
    17901790    if (pProf) { STAM_PROFILE_ADV_START(pProf, b); }
    1791     if (cbTransfer > 100 * _1K)
     1791    if (cbTransfer > SCSI_MAX_BUFFER_SIZE)
    17921792    {
    17931793        /* Linux accepts commands with up to 100KB of data, but expects
     
    18361836        for (uint32_t i = cSectors; i > 0; i -= cReqSectors)
    18371837        {
    1838             if (i * s->cbATAPISector > 100 * _1K)
    1839                 cReqSectors = (100 * _1K) / s->cbATAPISector;
     1838            if (i * s->cbATAPISector > SCSI_MAX_BUFFER_SIZE)
     1839                cReqSectors = SCSI_MAX_BUFFER_SIZE / s->cbATAPISector;
    18401840            else
    18411841                cReqSectors = i;
  • trunk/src/VBox/Devices/Storage/DrvHostBase.h

    r8155 r15815  
    131131#endif
    132132
     133#ifdef RT_OS_LINUX
     134    /** Double buffer required for ioctl with the Linux kernel as long as we use
     135     * remap_pfn_range() instead of vm_insert_page(). */
     136    void                    *pbDoubleBuffer;
     137#endif
     138
    133139
    134140    /**
  • trunk/src/VBox/Devices/Storage/DrvHostDVD.cpp

    r15776 r15815  
    5656# include <errno.h>
    5757# include <limits.h>
     58# include <iprt/mem.h>
    5859# define USE_MEDIA_POLLING
    5960
     
    430431        case PDMBLOCKTXDIR_FROM_DEVICE:
    431432            Assert(*pcbBuf != 0);
     433            Assert(*pcbBuf <= SCSI_MAX_BUFFER_SIZE);
    432434            /* Make sure that the buffer is clear for commands reading
    433435             * data. The actually received data may be shorter than what
     
    437439             * security problems inside the guest OS, if users can issue
    438440             * commands to the CDROM device. */
    439             memset(pvBuf, '\0', *pcbBuf);
     441            memset(pThis->pbDoubleBuffer, '\0', *pcbBuf);
    440442            direction = CGC_DATA_READ;
    441443            break;
    442444        case PDMBLOCKTXDIR_TO_DEVICE:
    443445            Assert(*pcbBuf != 0);
     446            Assert(*pcbBuf <= SCSI_MAX_BUFFER_SIZE);
     447            memcpy(pThis->pbDoubleBuffer, pvBuf, *pcbBuf);
    444448            direction = CGC_DATA_WRITE;
    445449            break;
     
    450454    memset(&cgc, '\0', sizeof(cgc));
    451455    memcpy(cgc.cmd, pbCmd, CDROM_PACKET_SIZE);
    452     cgc.buffer = (unsigned char *)pvBuf;
     456    cgc.buffer = (unsigned char *)pThis->pbDoubleBuffer;
    453457    cgc.buflen = *pcbBuf;
    454458    cgc.stat = 0;
     
    472476            Log2(("%s: error status %d, rc=%Rrc\n", __FUNCTION__, cgc.stat, rc));
    473477        }
     478    }
     479    switch (enmTxDir)
     480    {
     481        case PDMBLOCKTXDIR_FROM_DEVICE:
     482            memcpy(pvBuf, pThis->pbDoubleBuffer, *pcbBuf);
     483            break;
     484        default:
     485            ;
    474486    }
    475487    Log2(("%s: after ioctl: cgc.buflen=%d txlen=%d\n", __FUNCTION__, cgc.buflen, *pcbBuf));
     
    722734         * Override stuff.
    723735         */
     736#ifdef RT_OS_LINUX
     737        pThis->pbDoubleBuffer = RTMemAlloc(SCSI_MAX_BUFFER_SIZE);
     738        if (!pThis->pbDoubleBuffer)
     739            return VERR_NO_MEMORY;
     740#endif
    724741
    725742#ifndef RT_OS_L4 /* Passthrough is not supported on L4 yet */
     
    776793}
    777794
     795/** @copydoc FNPDMDRVDESTRUCT */
     796DECLCALLBACK(void) drvHostDvdDestruct(PPDMDRVINS pDrvIns)
     797{
     798#ifdef RT_OS_LINUX
     799    PDRVHOSTBASE pThis = PDMINS_2_DATA(pDrvIns, PDRVHOSTBASE);
     800
     801    if (pThis->pbDoubleBuffer)
     802    {
     803        RTMemFree(pThis->pbDoubleBuffer);
     804        pThis->pbDoubleBuffer = NULL;
     805    }
     806#endif
     807    return DRVHostBaseDestruct(pDrvIns);
     808}
    778809
    779810/**
     
    799830    drvHostDvdConstruct,
    800831    /* pfnDestruct */
    801     DRVHostBaseDestruct,
     832    drvHostDvdDestruct,
    802833    /* pfnIOCtl */
    803834    NULL,
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