VirtualBox

Changeset 80168 in vbox for trunk/src


Ignore:
Timestamp:
Aug 7, 2019 12:48:58 AM (5 years ago)
Author:
vboxsync
Message:

Fixed offset usage that caused reaching into wrong values of newest driver-side config struct, and further refined logging (see #9440, Comment 42)

Location:
trunk/src/VBox/Devices
Files:
1 added
3 edited

Legend:

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

    r80149 r80168  
    6060#define VIRTIOSCSI_REGION_PCI_CAP                   2
    6161
    62 /**
    63  * Definitions that follow are based on the VirtIO 1.0 specification.
    64  * Struct names are the same. The field names have been adapted to VirtualBox
    65  * data type + camel case annotation, with the original field name from the
    66  * VirtIO specification in the field's comment.
    67  */
    68 
    6962#define MATCH_SCSI_CONFIG(member) \
    7063    ((int)uOffset >= RT_OFFSETOF(VIRTIO_SCSI_CONFIG_T, member) \
     
    7568
    7669#define LOG_ACCESSOR(member) \
    77         LogFunc(("Guest %s %s [%d:%d]: %.*Rhxs\n", \
    78                   fWrite ? "wrote" : "read ", #member,  mOffset, mOffset + cb, cb, pv));
     70        virtioLogMappedIoValue(__FUNCTION__, #member, pv, cb, uMemberOffset, fWrite, false, 0);
    7971
    8072#define SCSI_CONFIG_ACCESSOR(member) \
    8173    { \
    82         uint32_t mOffset = uOffset - RT_OFFSETOF(VIRTIO_SCSI_CONFIG_T, member); \
     74        uint32_t uMemberOffset = uOffset - RT_OFFSETOF(VIRTIO_SCSI_CONFIG_T, member); \
    8375        if (fWrite) \
    84             memcpy(((char *)&pThis->virtioScsiConfig.member) + uOffset, (const char *)pv, cb); \
     76            memcpy(((char *)&pThis->virtioScsiConfig.member) + uMemberOffset, (const char *)pv, cb); \
    8577        else \
    86             memcpy((char *)pv, (const char *)(((char *)&pThis->virtioScsiConfig.member) + uOffset), cb); \
     78            memcpy((char *)pv, (const char *)(((char *)&pThis->virtioScsiConfig.member) + uMemberOffset), cb); \
    8779        LOG_ACCESSOR(member); \
    8880    }
     
    9082#define SCSI_CONFIG_ACCESSOR_READONLY(member) \
    9183    { \
    92         uint32_t mOffset = uOffset - RT_OFFSETOF(VIRTIO_SCSI_CONFIG_T, member); \
     84        uint32_t uMemberOffset = uOffset - RT_OFFSETOF(VIRTIO_SCSI_CONFIG_T, member); \
    9385        if (fWrite) \
    9486            LogFunc(("Guest attempted to write readonly virtio_pci_common_cfg.%s\n", #member)); \
    9587        else \
    9688        { \
    97             memcpy((char *)pv, (const char *)(((char *)&pThis->virtioScsiConfig.member) + uOffset), cb); \
     89            memcpy((char *)pv, (const char *)(((char *)&pThis->virtioScsiConfig.member) + uMemberOffset), cb); \
    9890            LOG_ACCESSOR(member); \
    9991        } \
    10092    }
    10193
     94/**
     95 * Definitions that follow are based on the VirtIO 1.0 specification.
     96 * Struct names are the same. The field names have been adapted to VirtualBox
     97 * data type + camel case annotation, with the original field name from the
     98 * VirtIO specification in the field's comment.
     99 */
    102100
    103101/** @name VirtIO 1.0 SCSI Host feature bits
     
    112110 * Features VirtIO 1.0 Host SCSI controller offers guest driver
    113111 */
    114 #define VIRTIOSCSI_HOST_SCSI_FEATURES_OFFERED         VIRTIOSCSI_F_INOUT   \
    115                                                     | VIRTIOSCSI_F_HOTPLUG \
    116                                                     | VIRTIOSCSI_F_CHANGE  \
    117                                                     | VIRTIOSCSI_F_T10_PI  \
     112#define VIRTIOSCSI_HOST_SCSI_FEATURES_OFFERED \
     113            (VIRTIOSCSI_F_INOUT | VIRTIOSCSI_F_HOTPLUG | VIRTIOSCSI_F_CHANGE | VIRTIOSCSI_F_T10_PI)
    118114
    119115typedef struct virtio_scsi_config
     
    167163} VIRTIO_SCSI_REQ_CMD_T, *PVIRTIO_SCSI_REQ_CMD_T;
    168164
    169 /** Command-specific response values */
     165/** @name VirtIO 1.0 SCSI req command-specific response values
     166 * @{  */
    170167#define VIRTIOSCSI_S_OK                            0       /* control, command   */
    171168#define VIRTIOSCSI_S_OVERRUN                       1       /* control */
     
    179176#define VIRTIOSCSI_S_FAILURE                       9       /* control, command */
    180177#define VIRTIOSCSI_S_INCORRECT_LUN                12       /* command */
    181 
    182 
    183 /** task_attr */
     178/** @} */
     179
     180
     181/** @name VirtIO 1.0 SCSI Command-specific task_attr values
     182 * @{  */
    184183#define VIRTIOSCSI_S_SIMPLE                        0
    185184#define VIRTIOSCSI_S_ORDERED                       1
    186185#define VIRTIOSCSI_S_HEAD                          2
    187186#define VIRTIOSCSI_S_ACA                           3
     187/** @} */
    188188
    189189#define VIRTIOSCSI_T_TMF                           0
     
    208208} VIRTIO_SCSI_CTRL_BUF_T, *PVIRTIO_SCSI_CTRL_BUF_T;
    209209
    210 /* command-specific response values */
    211 
     210/** @name VirtIO 1.0 SCSI tmf control command-specific response values
     211 * @{  */
    212212#define VIRTIOSCSI_S_FUNCTION_COMPLETE            0
    213213#define VIRTIOSCSI_S_FUNCTION_SUCCEEDED           10
    214214#define VIRTIOSCSI_S_FUNCTION_REJECTED            11
     215/** @} */
    215216
    216217#define VIRTIOSCSI_T_AN_QUERY                     1         /** Asynchronous notification query */
     
    242243    uint8_t  response;                                       /** response        */
    243244} VIRTIO_SCSI_CTRL_T, *PVIRTIO_SCSI_CTRL_T;
     245
    244246
    245247#define VIRTIOSCSI_T_NO_EVENT                   0
     
    758760}
    759761
    760 static int virtioScsiR3ConfigAccess(PVIRTIOSCSI pThis, uint32_t uOffset,
     762static int virtioScsiR3CfgAccessed(PVIRTIOSCSI pThis, uint32_t uOffset,
    761763                                    const void *pv, size_t cb, uint8_t fWrite)
    762764{
     
    825827 * @param   pDevIns     The device instance.
    826828 * @param   uOffset     Offset within device specific capabilities struct
    827  * @param   pv       Buffer in which to save read data
     829 * @param   pv          Buffer in which to save read data
    828830 * @param   cb          Number of bytes to read
    829831 */
     
    836838//              uOffset, cb));
    837839
    838     rc = virtioScsiR3ConfigAccess(pThis, uOffset, pv, cb, false);
     840    rc = virtioScsiR3CfgAccessed(pThis, uOffset, pv, cb, false);
    839841
    840842    return rc;
     
    847849 * @param   pDevIns     The device instance.
    848850 * @param   uOffset     Offset within device specific capabilities struct
    849  * @param   pv       Buffer in which to save read data
     851 * @param   pv          Buffer in which to save read data
    850852 * @param   cb          Number of bytes to write
    851853 */
     
    858860//              uOffset, cb));
    859861
    860     rc = virtioScsiR3ConfigAccess(pThis, uOffset, pv, cb, true);
     862    rc = virtioScsiR3CfgAccessed(pThis, uOffset, pv, cb, true);
    861863
    862864    return rc;
  • trunk/src/VBox/Devices/VirtIO/Virtio_1_0.cpp

    r80148 r80168  
    2828#include <VBox/vmm/pdmdev.h>
    2929#include "Virtio_1_0.h"
     30#include "Virtio_1_0_impl.h"
    3031
    3132#define INSTANCE(pState) pState->szInstance
     
    3536# define QUEUENAME(s, q) (q->pcszName)
    3637#endif
    37 
    38 
    39 /**
    40 * Returns true if physical address and access length are within the mapped capability struct.
    41 *
    42 * Actual Parameters:
    43 *     [IN]  pPhysCapStruct - Pointer to MMIO mapped capability struct
    44 *     [IN]  pCfgCap        - Pointer to capability in PCI configuration area
    45 *     [OUT] fMatched       - True if GCPhysAddr is within the physically mapped capability.
    46 *
    47 * Implied parameters:
    48 *     [IN]  GCPhysAddr     - Physical address accessed (via MMIO callback)
    49 *     [IN]  cb             - Number of bytes to access
    50 *     [OUT] result          - true or false
    51 *
    52 */
    53 #define MATCH_VIRTIO_CAP_STRUCT(pGcPhysCapData, pCfgCap, fMatched) \
    54         bool fMatched = false; \
    55         if (pGcPhysCapData && pCfgCap && GCPhysAddr >= (RTGCPHYS)pGcPhysCapData \
    56             && GCPhysAddr < ((RTGCPHYS)pGcPhysCapData + ((PVIRTIO_PCI_CAP_T)pCfgCap)->uLength) \
    57             && cb <= ((PVIRTIO_PCI_CAP_T)pCfgCap)->uLength) \
    58                 fMatched = true;
    59 
    60 /**
    61  * This macro resolves to boolean true if uoff is within the specified member offset and length.
    62  *
    63  * Actual Parameters:
    64  *     [IN] member      - Member of VIRTIO_PCI_COMMON_CFG_T
    65  *
    66  * Implied Parameters:
    67  *     [IN]  uoff        - Offset into VIRTIO_PCI_COMMON_CFG_T
    68  *     [IN]  cb          - Number of bytes to access
    69  *     [OUT] result      - true or false
    70  */
    71 #define COMMON_CFG(member) \
    72            (uoff >= RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, member) \
    73         &&  uoff < (uint32_t)(RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, member) \
    74                              + RT_SIZEOFMEMB(VIRTIO_PCI_COMMON_CFG_T, member)) \
    75         &&   cb <= RT_SIZEOFMEMB(VIRTIO_PCI_COMMON_CFG_T, member) \
    76                   - (uoff - RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, member)))
    77 
    78 #define LOG_ACCESSOR(member) \
    79         LogFunc(("Guest %s %s[%d:%d]: %.*Rhxs\n", \
    80                   fWrite ? "wrote" : "read ", #member, foff, foff + cb, cb, pv));
    81 
    82 #define LOG_INDEXED_ACCESSOR(member, idx) \
    83         LogFunc(("Guest %s %s[%d][%d:%d]: %.*Rhxs\n", \
    84                   fWrite ? "wrote" : "read ", #member, idx, foff, foff + cb, cb, pv));
    85 
    86 #define ACCESSOR(member) \
    87     { \
    88         uint32_t foff = uoff - RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, member); \
    89         if (fWrite) \
    90             memcpy(((char *)&pVirtio->member) + uoff, (const char *)pv, cb); \
    91         else \
    92             memcpy((char *)pv, (const char *)(((char *)&pVirtio->member) + uoff), cb); \
    93         LOG_ACCESSOR(member); \
    94     }
    95 
    96 #define ACCESSOR_WITH_IDX(member, idx) \
    97     { \
    98         uint32_t foff = uoff - RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, member); \
    99         if (fWrite) \
    100             memcpy(((char *)(pVirtio->member + idx)) + uoff, (const char *)pv, cb); \
    101         else \
    102             memcpy((char *)pv, (const char *)(((char *)(pVirtio->member + idx)) + uoff), cb); \
    103         LOG_INDEXED_ACCESSOR(member, idx); \
    104     }
    105 
    106 #define ACCESSOR_READONLY(member) \
    107     { \
    108         uint32_t foff = uoff - RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, member); \
    109         if (fWrite) \
    110             LogFunc(("Guest attempted to write readonly virtio_pci_common_cfg.%s\n", #member)); \
    111         else \
    112         { \
    113             memcpy((char *)pv, (const char *)(((char *)&pVirtio->member) + uoff), cb); \
    114             LOG_ACCESSOR(member); \
    115         } \
    116     }
    117 
    118 #define ACCESSOR_READONLY_WITH_IDX(member, idx) \
    119     { \
    120         uint32_t foff = uoff - RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, member); \
    121         if (fWrite) \
    122             LogFunc(("Guest attempted to write readonly virtio_pci_common_cfg.%s[%d]\n", #member, idx)); \
    123         else \
    124         { \
    125             memcpy((char *)pv, ((char *)(pVirtio->member + idx)) + uoff, cb); \
    126             LOG_INDEXED_ACCESSOR(member, idx); \
    127         } \
    128     }
    129 
    130 
    131 #ifdef VBOX_DEVICE_STRUCT_TESTCASE
    132 #  define virtioDumpState(x, s)  do {} while (0)
    133 #else
    134 #  ifdef DEBUG /* This still needs to be migrated to VirtIO 1.0 */
    135 __attribute__((unused))
    136 static void virtioDumpState(PVIRTIOSTATE pState, const char *pcszCaller)
    137 {
    138     RT_NOREF2(pState, pcszCaller);
    139     /* PK TODO, dump state features, selector, status, ISR, queue info (iterate),
    140                 descriptors, avail, used, size, indices, address
    141                 each by variable name on new line, indented slightly */
    142 }
    143 #endif
    144 
    14538
    14639void virtQueueReadDesc(PVIRTIOSTATE pState, PVIRTQUEUE pVirtQueue, uint32_t idx, PVIRTQUEUEDESC pDesc)
     
    466359 * @param   pSSM        The handle to the saved state.
    467360 */
    468 int virtioSaveExec(PVIRTIOSTATE pState, PSSMHANDLE pSSM)
    469 {
    470     RT_NOREF2(pState, pSSM);
     361int virtioSaveExec(PVIRTIOSTATE pVirtio, PSSMHANDLE pSSM)
     362{
    471363    int rc = VINF_SUCCESS;
    472 //    virtioDumpState(pState, "virtioSaveExec");
     364    virtioDumpState(pVirtio, "virtioSaveExec");
     365    RT_NOREF(pSSM);
    473366    /*
    474367     * PK TODO save guest features, queue selector, sttus ISR,
     
    490383 * @param   uPass       The data pass.
    491384 */
    492 int virtioLoadExec(PVIRTIOSTATE pState, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass, uint32_t nQueues)
    493 {
    494     RT_NOREF5(pState, pSSM, uVersion, uPass, nQueues);
     385int virtioLoadExec(PVIRTIOSTATE pVirtio, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass, uint32_t nQueues)
     386{
     387    RT_NOREF5(pVirtio, pSSM, uVersion, uPass, nQueues);
    495388    int rc = VINF_SUCCESS;
     389    virtioDumpState(pVirtio, "virtioLoadExec");
    496390
    497391    /*
     
    503397    {
    504398    }
    505 
    506 //    virtioDumpState(pState, "virtioLoadExec");
    507 
    508399    return rc;
    509400}
     
    612503{
    613504    RT_NOREF(pVirtio);
    614     LogFunc((""));
     505    LogFunc(("\n"));
    615506    pVirtio->uDeviceStatus = 0;
    616507}
     
    626517 * @param   cb          Number of bytes to read or write
    627518 */
    628 
    629 
    630 int virtioCommonCfgAccessed(PVIRTIOSTATE pVirtio, int fWrite, off_t uoff, unsigned cb, void const *pv)
    631 {
    632     int rv = VINF_SUCCESS;
     519int virtioCommonCfgAccessed(PVIRTIOSTATE pVirtio, int fWrite, off_t uOffset, unsigned cb, void const *pv)
     520{
     521    int rc = VINF_SUCCESS;
    633522    uint64_t val;
    634523    if (COMMON_CFG(uDeviceFeatures))
     
    638527        else /* Guest READ pCommonCfg->uDeviceFeatures */
    639528        {
    640             uint32_t foff = uoff - RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, uDeviceFeatures);
     529            uint32_t uIntraOff = uOffset - RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, uDeviceFeatures);
    641530            switch(pVirtio->uDeviceFeaturesSelect)
    642531            {
     
    644533                    val = pVirtio->uDeviceFeatures & 0xffffffff;
    645534                    memcpy((void *)pv, (const void *)&val, cb);
    646                     LogFunc(("Guest read  uDeviceFeatures(LO)[%d:%d]: %.*Rhxs\n",
    647                               foff, foff + cb, cb, pv));
     535                    LOG_ACCESSOR(uDeviceFeatures);
    648536                    break;
    649537                case 1:
    650538                    val = (pVirtio->uDeviceFeatures >> 32) & 0xffffffff;
     539                    uIntraOff += 4;
    651540                    memcpy((void *)pv, (const void *)&val, cb);
    652                     LogFunc(("Guest read  uDeviceFeatures(HI)[%d:%d]: %.*Rhxs\n",
    653                               foff, foff + cb, cb, pv));
     541                    LOG_ACCESSOR(uDeviceFeatures);
    654542                    break;
    655543                default:
    656                     Log(("Guest read uDeviceFeatures with out of range selector (%d), returning 0\n",
     544                    LogFunc(("Guest read uDeviceFeatures with out of range selector (%d), returning 0\n",
    657545                          pVirtio->uDeviceFeaturesSelect));
     546                    return VERR_ACCESS_DENIED;
    658547            }
    659548        }
     
    663552        if (fWrite) /* Guest WRITE pCommonCfg->udriverFeatures */
    664553        {
    665             uint32_t foff = uoff - RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, uDriverFeatures);
     554            uint32_t uIntraOff = uOffset - RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, uDriverFeatures);
    666555            switch(pVirtio->uDriverFeaturesSelect)
    667556            {
    668557                case 0:
    669558                    memcpy(&pVirtio->uDriverFeatures, pv, cb);
    670                     LogFunc(("Guest wrote uDriverFeatures(LO)[%d:%d]: %.*Rhxs\n",
    671                               foff, foff + cb, cb, pv));
     559                    LOG_ACCESSOR(uDriverFeatures);
    672560                    break;
    673561                case 1:
    674562                    memcpy(((char *)&pVirtio->uDriverFeatures) + sizeof(uint32_t), pv, cb);
    675                     LogFunc(("Guest wrote uDriverFeatures(HI)[%d:%d]: %.*Rhxs\n",
    676                               foff, foff + cb, cb, pv));
     563                    uIntraOff += 4;
     564                    LOG_ACCESSOR(uDriverFeatures);
    677565                    break;
     566                default:
     567                    LogFunc(("Guest wrote uDriverFeatures with out of range selector (%d), returning 0\n",
     568                         pVirtio->uDriverFeaturesSelect));
     569                    return VERR_ACCESS_DENIED;
    678570            }
    679571        }
    680572        else /* Guest READ pCommonCfg->udriverFeatures */
    681573        {
    682             uint32_t foff = uoff - RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, uDriverFeatures);
     574            uint32_t uIntraOff = uOffset - RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, uDriverFeatures);
    683575            switch(pVirtio->uDriverFeaturesSelect)
    684576            {
     
    686578                    val = pVirtio->uDriverFeatures & 0xffffffff;
    687579                    memcpy((void *)pv, (const void *)&val, cb);
    688                     LogFunc(("Guest read  uDriverFeatures(LO)[%d:%d]: %.*Rhxs\n",
    689                               foff, foff + cb, cb, pv));
     580                    LOG_ACCESSOR(uDriverFeatures);
    690581                    break;
    691582                case 1:
    692583                    val = (pVirtio->uDriverFeatures >> 32) & 0xffffffff;
     584                    uIntraOff += 4;
    693585                    memcpy((void *)pv, (const void *)&val, cb);
    694                     LogFunc(("Guest read  uDriverFeatures(HI)[%d:%d]: %.*Rhxs\n",
    695                               foff, foff + cb, cb, pv));
     586                    LOG_ACCESSOR(uDriverFeatures);
    696587                    break;
    697588                default:
    698                     Log(("Guest read uDriverFeatures with out of range selector (%d), returning 0\n",
     589                    LogFunc(("Guest read uDriverFeatures with out of range selector (%d), returning 0\n",
    699590                         pVirtio->uDriverFeaturesSelect));
     591                    return VERR_ACCESS_DENIED;
    700592            }
    701593        }
     
    704596    {
    705597        if (fWrite)
    706             Log(("Guest attempted to write readonly virtio_pci_common_cfg.num_queues\n"));
     598        {
     599            LogFunc(("Guest attempted to write readonly virtio_pci_common_cfg.num_queues\n"));
     600            return VERR_ACCESS_DENIED;
     601        }
    707602        else
    708603        {
     604            uint32_t uIntraOff = 0;
    709605            *(uint16_t *)pv = MAX_QUEUES;
    710             Log(("Guest read 0x%x from pVirtio->uNumQueues\n", MAX_QUEUES));
     606            LOG_ACCESSOR(uNumQueues);
    711607        }
    712608    }
     
    716612        {
    717613            pVirtio->uDeviceStatus = *(uint8_t *)pv;
    718             LogFunc(("Driver wrote uDeviceStatus:\n"));
    719             logDeviceStatus(pVirtio->uDeviceStatus);
     614            LogFunc(("Guest wrote uDeviceStatus ................ ("));
     615            virtioLogDeviceStatus(pVirtio->uDeviceStatus);
     616            Log((")\n"));
    720617            if (pVirtio->uDeviceStatus == 0)
    721618                virtioResetDevice(pVirtio);
     
    723620        else /* Guest READ pCommonCfg->uDeviceStatus */
    724621        {
    725             LogFunc(("Driver read uDeviceStatus:\n"));
     622            LogFunc(("Guest read  uDeviceStatus ................ ("));
    726623            *(uint32_t *)pv = pVirtio->uDeviceStatus;
    727             logDeviceStatus(pVirtio->uDeviceStatus);
     624            virtioLogDeviceStatus(pVirtio->uDeviceStatus);
     625            Log((")\n"));
    728626        }
    729627    }
     
    778676    else
    779677    {
    780         LogFunc(("Bad access by guest to virtio_pci_common_cfg: uoff=%d, cb=%d\n", uoff, cb));
    781         rv = VERR_ACCESS_DENIED;
    782     }
    783     return rv;
     678        LogFunc(("Bad access by guest to virtio_pci_common_cfg: uOffset=%d, cb=%d\n", uOffset, cb));
     679        rc = VERR_ACCESS_DENIED;
     680    }
     681    return rc;
    784682}
    785683
     
    11531051#endif
    11541052
    1155 #define CFGADDR2IDX(addr) ((uint64_t)addr - (uint64_t)&pVirtio->dev.abConfig)
    11561053
    11571054    /* The following capability mapped via VirtIO 1.0: struct virtio_pci_cfg_cap (VIRTIO_PCI_CFG_CAP_T)
     
    11611058     * therefore does not contribute to the capabilities region (BAR) the other capabilities use.
    11621059     */
     1060#define CFGADDR2IDX(addr) ((uint64_t)addr - (uint64_t)&pVirtio->dev.abConfig)
     1061
    11631062    PVIRTIO_PCI_CAP_T pCfg;
    11641063
     
    12511150#endif /* IN_RING3 */
    12521151
    1253 #endif /* VBOX_DEVICE_STRUCT_TESTCASE */
    1254 
  • trunk/src/VBox/Devices/VirtIO/Virtio_1_0.h

    r80148 r80168  
    7373#define VIRTIO_MSI_NO_VECTOR                0xffff
    7474
    75 typedef DECLCALLBACK(uint32_t) FNGETHOSTFEATURES(void *pvState);
    76 typedef FNGETHOSTFEATURES *PFNGETHOSTFEATURES;
    77 
    78 
    7975/** Most of the following definitions attempt to adhere to the names and
    8076 *  and forms used by the VirtIO 1.0 specification to increase the maintainability
     
    440436void    vringSetNotification( PVIRTIOSTATE pVirtio, PVIRTQUEUE pVirtQueue, bool fEnabled);
    441437
    442 DECLINLINE(void) logDeviceStatus(uint8_t status)
    443 {
    444     if (status & VIRTIO_STATUS_ACKNOWLEDGE)
    445         Log(("                         ACKNOWLEDGE\n"));
    446     if (status & VIRTIO_STATUS_DRIVER)
    447         Log(("                         DRIVER\n"));
    448     if (status & VIRTIO_STATUS_DRIVER_OK)
    449         Log(("                         DRIVER_OK\n"));
    450     if (status & VIRTIO_STATUS_FEATURES_OK)
    451         Log(("                         FEATURES_OK\n"));
    452     if (status & VIRTIO_STATUS_FAILED)
    453         Log(("                         FAILED\n"));
    454     if (status & VIRTIO_STATUS_DEVICE_NEEDS_RESET)
    455         Log(("                         ACKNOWLEDGE\n"));
    456     if (status == 0)
    457         Log(("                         RESET\n"));
    458     Log(("\n"));
    459 }
    460438
    461439/*  FROM Virtio 1.0 SPEC, NYI
     
    477455*/
    478456
     457
     458
     459/**
     460 * Formats the logging of a memory-mapped I/O input or output value
     461 *
     462 * @param   pszFunc     - To avoid displaying this function's name via __FUNCTION__ or LogFunc()
     463 * @param   pszMember   - Name of struct member
     464 * @param   pv          - pointer to value
     465 * @param   cb          - size of value
     466 * @param   uOffset     - offset into member where value starts
     467 * @param   fWrite      - True if write I/O
     468 * @param   fHasIndex   - True if the member is indexed
     469 * @param   idx         - The index if fHasIndex
     470 */
     471DECLINLINE(void) virtioLogMappedIoValue(const char *pszFunc, const char *pszMember, const void *pv, uint32_t cb,
     472                        uint32_t uOffset, bool fWrite, bool fHasIndex, uint32_t idx)
     473{
     474
     475#define FMTHEX(fmtout, v, cNybs) \
     476    fmtout[cNybs] = '\0'; \
     477    for (uint8_t i = 0; i < cNybs; i++) \
     478        fmtout[(cNybs - i) -1] = "0123456789abcdef"[(val >> (i * 4)) & 0xf];
     479
     480#define MAX_STRING   64
     481    char pszIdx[MAX_STRING] = { 0 };
     482    char pszDepiction[MAX_STRING] = { 0 };
     483    char pszFormattedVal[MAX_STRING] = { 0 };
     484    if (fHasIndex)
     485        RTStrPrintf(pszIdx, sizeof(pszIdx), "[%d]", idx);
     486    if (cb == 1 || cb == 2 || cb == 4 || cb == 8)
     487    {
     488        /* manually padding with 0's instead of \b due to different impl of %x precision than printf() */
     489        uint64_t val = 0;
     490        memcpy((char *)&val, pv, cb);
     491        FMTHEX(pszFormattedVal, val, cb * 2);
     492        RTStrPrintf(pszDepiction, sizeof(pszDepiction), "%s%s[%d:%d]", pszMember, pszIdx, uOffset, uOffset + cb);
     493        RTStrPrintf(pszDepiction, sizeof(pszDepiction), "%-30s", pszDepiction);
     494        int first = 0;
     495        for (uint8_t i = 0; i < sizeof(pszDepiction); i++)
     496            if (pszDepiction[i] == ' ' && first++ != 0)
     497                pszDepiction[i] = '.';
     498        Log(("%s: Guest %s %s 0x%s\n", \
     499                  pszFunc, fWrite ? "wrote" : "read ", pszDepiction, pszFormattedVal));
     500    }
     501    else /* odd number or oversized access, ... log inline hex-dump style */
     502    {
     503        Log(("%s: Guest %s %s%s[%d:%d]: %.*Rhxs\n", \
     504              pszFunc, fWrite ? "wrote" : "read ", pszMember,
     505              pszIdx, uOffset, uOffset + cb, cb, pv));
     506    }
     507}
     508
     509typedef DECLCALLBACK(uint32_t) FNGETHOSTFEATURES(void *pvState);
     510typedef FNGETHOSTFEATURES *PFNGETHOSTFEATURES;
     511
    479512DECLINLINE(uint16_t) vringReadAvail(PVIRTIOSTATE pState, PVIRTQUEUE pVirtQueue)
    480513{
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