VirtualBox

Changeset 84134 in vbox


Ignore:
Timestamp:
May 4, 2020 7:05:33 AM (5 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
137724
Message:

AMD IOMMU: bugref:9654 Bits.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Bus/DevIommuAmd.cpp

    r84133 r84134  
    419419/** @} */
    420420
     421/** @name IOMMU_PERM_XXX: IOMMU I/O access permissions bits.
     422 * In accordance with the AMD spec.
     423 *
     424 * These values match the shifted values of the IR and IW field of the DTE and the
     425 * PTE, PDE of the I/O page tables.
     426 *
     427 * @{ */
     428#define IOMMU_IO_PERM_READ                             RT_BIT_64(0)
     429#define IOMMU_IO_PERM_WRITE                            RT_BIT_64(1)
     430#define IOMMU_IO_PERM_SHIFT                            61
     431#define IOMMU_IO_PERM_MASK                             0x3
     432/** @} */
     433
    421434/**
    422435 * @name IOMMU Control Register Bits.
     
    522535    struct
    523536    {
    524         uint32_t    u1Valid : 1;                      /**< Bit  0       - V: Valid. */
    525         uint32_t    u1TranslationValid : 1;           /**< Bit  1       - TV: Translation information Valid. */
    526         uint32_t    u5Rsvd0 : 5;                      /**< Bits 6:2     - Reserved. */
    527         uint32_t    u2Had : 2;                        /**< Bits 8:7     - HAD: Host Access Dirty. */
    528         uint32_t    u3Mode : 3;                       /**< Bits 11:9    - Mode: Paging mode. */
    529         uint32_t    u20PageTableRootPtrLo : 20;       /**< Bits 31:12   - Page Table Root Pointer (Lo). */
    530         uint32_t    u20PageTableRootPtrHi : 20;       /**< Bits 51:32   - Page Table Root Pointer (Hi). */
    531         uint32_t    u1Ppr : 1;                        /**< Bit  52      - PPR: Peripheral Page Request. */
    532         uint32_t    u1GstPprRespPasid : 1;            /**< Bit  53      - GRPR: Guest PPR Response with PASID. */
    533         uint32_t    u1GstIoValid : 1;                 /**< Bit  54      - GIoV: Guest I/O Protection Valid. */
    534         uint32_t    u1GstTranslateValid : 1;          /**< Bit  55      - GV: Guest translation Valid. */
    535         uint32_t    u2GstCr3RootTblTranslated : 2;    /**< Bits 57:56   - GLX: Guest Levels Translated. */
    536         uint32_t    u3GstCr3TableRootPtrLo : 2;       /**< Bits 60:58   - GCR3 TRP: Guest CR3 Table Root Pointer (Lo). */
    537         uint32_t    u1IoRead : 1;                     /**< Bit  61      - IR: I/O Read permission. */
    538         uint32_t    u1IoWrite : 1;                    /**< Bit  62      - IW: I/O Write permission. */
    539         uint32_t    u1Rsvd0 : 1;                      /**< Bit  63      - Reserved. */
    540         uint32_t    u16DomainId : 1;                  /**< Bits 79:64   - Domain ID. */
    541         uint32_t    u16GstCr3TableRootPtrMed : 16;    /**< Bits 95:80   - GCR3 TRP: Guest CR3 Table Root Pointer (Mid). */
    542         uint32_t    u1IoTlbEnable : 1;                /**< Bit  96      - I: IOTLB Enable. */
    543         uint32_t    u1SuppressPfEvents : 1;           /**< Bit  97      - SE: Supress Page-fault events. */
    544         uint32_t    u1SuppressAllPfEvents : 1;        /**< Bit  98      - SA: Supress All Page-fault events. */
    545         uint32_t    u2IoCtl : 1;                      /**< Bits 100:99  - IoCtl: Port I/O Control. */
    546         uint32_t    u1Cache : 1;                      /**< Bit  101     - Cache: IOTLB Cache Hint. */
    547         uint32_t    u1SnoopDisable : 1;               /**< Bit  102     - SD: Snoop Disable. */
    548         uint32_t    u1AllowExclusion : 1;             /**< Bit  103     - EX: Allow Exclusion. */
    549         uint32_t    u2SysMgt : 2;                     /**< Bits 105:104 - SysMgt: System Management message enable. */
    550         uint32_t    u1Rsvd1 : 1;                      /**< Bit  106     - Reserved. */
    551         uint32_t    u21GstCr3TableRootPtrHi : 21;     /**< Bits 127:107 - GCR3 TRP: Guest CR3 Table Root Pointer (Hi). */
    552         uint32_t    u1IntrMapValid : 1;               /**< Bit  128     - IV: Interrupt map Valid. */
    553         uint32_t    u4IntrTableLength : 4;            /**< Bits 132:129 - IntTabLen: Interrupt Table Length. */
    554         uint32_t    u1IgnoreUnmappedIntrs : 1;        /**< Bits 133     - IG: Ignore unmapped interrupts. */
    555         uint32_t    u26IntrTableRootPtr : 26;         /**< Bits 159:134 - Interrupt Root Table Pointer (Lo). */
    556         uint32_t    u20IntrTableRootPtr : 20;         /**< Bits 179:160 - Interrupt Root Table Pointer (Hi). */
    557         uint32_t    u4Rsvd0 : 4;                      /**< Bits 183:180 - Reserved. */
    558         uint32_t    u1InitPassthru : 1;               /**< Bits 184     - INIT Pass-through. */
    559         uint32_t    u1ExtIntPassthru : 1;             /**< Bits 185     - External Interrupt Pass-through. */
    560         uint32_t    u1NmiPassthru : 1;                /**< Bits 186     - NMI Pass-through. */
    561         uint32_t    u1Rsvd2 : 1;                      /**< Bits 187     - Reserved. */
    562         uint32_t    u2IntrCtrl : 2;                   /**< Bits 189:188 - IntCtl: Interrupt Control. */
    563         uint32_t    u1Lint0Passthru : 1;              /**< Bit  190     - Lint0Pass: LINT0 (Legacy PIC NMI) Pass-thru. */
    564         uint32_t    u1Lint1Passthru : 1;              /**< Bit  191     - Lint1Pass: LINT1 (Legacy PIC NMI) Pass-thru. */
    565         uint32_t    u32Rsvd0;                         /**< Bits 223:192 - Reserved. */
    566         uint32_t    u22Rsvd0 : 22;                    /**< Bits 245:224 - Reserved. */
    567         uint32_t    u1AttrOverride : 1;               /**< Bit  246     - AttrV: Attribute Override. */
    568         uint32_t    u1Mode0FC: 1;                     /**< Bit  247     - Mode0FC. */
    569         uint32_t    u8SnoopAttr: 1;                   /**< Bits 255:248 - Snoop Attribute. */
     537        RT_GCC_EXTENSION uint64_t  u1Valid : 1;                   /**< Bit  0       - V: Valid. */
     538        RT_GCC_EXTENSION uint64_t  u1TranslationValid : 1;        /**< Bit  1       - TV: Translation information Valid. */
     539        RT_GCC_EXTENSION uint64_t  u5Rsvd0 : 5;                   /**< Bits 6:2     - Reserved. */
     540        RT_GCC_EXTENSION uint64_t  u2Had : 2;                     /**< Bits 8:7     - HAD: Host Access Dirty. */
     541        RT_GCC_EXTENSION uint64_t  u3Mode : 3;                    /**< Bits 11:9    - Mode: Paging mode. */
     542        RT_GCC_EXTENSION uint64_t  u40PageTableRootPtrLo : 40;    /**< Bits 51:12   - Page Table Root Pointer. */
     543        RT_GCC_EXTENSION uint64_t  u1Ppr : 1;                     /**< Bit  52      - PPR: Peripheral Page Request. */
     544        RT_GCC_EXTENSION uint64_t  u1GstPprRespPasid : 1;         /**< Bit  53      - GRPR: Guest PPR Response with PASID. */
     545        RT_GCC_EXTENSION uint64_t  u1GstIoValid : 1;              /**< Bit  54      - GIoV: Guest I/O Protection Valid. */
     546        RT_GCC_EXTENSION uint64_t  u1GstTranslateValid : 1;       /**< Bit  55      - GV: Guest translation Valid. */
     547        RT_GCC_EXTENSION uint64_t  u2GstCr3RootTblTranslated : 2; /**< Bits 57:56   - GLX: Guest Levels Translated. */
     548        RT_GCC_EXTENSION uint64_t  u3GstCr3TableRootPtrLo : 2;    /**< Bits 60:58   - GCR3 TRP: Guest CR3 Table Root Ptr (Lo). */
     549        RT_GCC_EXTENSION uint64_t  u1IoRead : 1;                  /**< Bit  61      - IR: I/O Read permission. */
     550        RT_GCC_EXTENSION uint64_t  u1IoWrite : 1;                 /**< Bit  62      - IW: I/O Write permission. */
     551        RT_GCC_EXTENSION uint64_t  u1Rsvd0 : 1;                   /**< Bit  63      - Reserved. */
     552        RT_GCC_EXTENSION uint64_t  u16DomainId : 1;               /**< Bits 79:64   - Domain ID. */
     553        RT_GCC_EXTENSION uint64_t  u16GstCr3TableRootPtrMed : 16; /**< Bits 95:80   - GCR3 TRP: Guest CR3 Table Root Ptr (Mid). */
     554        RT_GCC_EXTENSION uint64_t  u1IoTlbEnable : 1;             /**< Bit  96      - I: IOTLB Enable. */
     555        RT_GCC_EXTENSION uint64_t  u1SuppressPfEvents : 1;        /**< Bit  97      - SE: Supress Page-fault events. */
     556        RT_GCC_EXTENSION uint64_t  u1SuppressAllPfEvents : 1;     /**< Bit  98      - SA: Supress All Page-fault events. */
     557        RT_GCC_EXTENSION uint64_t  u2IoCtl : 1;                   /**< Bits 100:99  - IoCtl: Port I/O Control. */
     558        RT_GCC_EXTENSION uint64_t  u1Cache : 1;                   /**< Bit  101     - Cache: IOTLB Cache Hint. */
     559        RT_GCC_EXTENSION uint64_t  u1SnoopDisable : 1;            /**< Bit  102     - SD: Snoop Disable. */
     560        RT_GCC_EXTENSION uint64_t  u1AllowExclusion : 1;          /**< Bit  103     - EX: Allow Exclusion. */
     561        RT_GCC_EXTENSION uint64_t  u2SysMgt : 2;                  /**< Bits 105:104 - SysMgt: System Management message enable. */
     562        RT_GCC_EXTENSION uint64_t  u1Rsvd1 : 1;                   /**< Bit  106     - Reserved. */
     563        RT_GCC_EXTENSION uint64_t  u21GstCr3TableRootPtrHi : 21;  /**< Bits 127:107 - GCR3 TRP: Guest CR3 Table Root Ptr (Hi). */
     564        RT_GCC_EXTENSION uint64_t  u1IntrMapValid : 1;            /**< Bit  128     - IV: Interrupt map Valid. */
     565        RT_GCC_EXTENSION uint64_t  u4IntrTableLength : 4;         /**< Bits 132:129 - IntTabLen: Interrupt Table Length. */
     566        RT_GCC_EXTENSION uint64_t  u1IgnoreUnmappedIntrs : 1;     /**< Bits 133     - IG: Ignore unmapped interrupts. */
     567        RT_GCC_EXTENSION uint64_t  u26IntrTableRootPtr : 26;      /**< Bits 159:134 - Interrupt Root Table Pointer (Lo). */
     568        RT_GCC_EXTENSION uint64_t  u20IntrTableRootPtr : 20;      /**< Bits 179:160 - Interrupt Root Table Pointer (Hi). */
     569        RT_GCC_EXTENSION uint64_t  u4Rsvd0 : 4;                   /**< Bits 183:180 - Reserved. */
     570        RT_GCC_EXTENSION uint64_t  u1InitPassthru : 1;            /**< Bits 184     - INIT Pass-through. */
     571        RT_GCC_EXTENSION uint64_t  u1ExtIntPassthru : 1;          /**< Bits 185     - External Interrupt Pass-through. */
     572        RT_GCC_EXTENSION uint64_t  u1NmiPassthru : 1;             /**< Bits 186     - NMI Pass-through. */
     573        RT_GCC_EXTENSION uint64_t  u1Rsvd2 : 1;                   /**< Bits 187     - Reserved. */
     574        RT_GCC_EXTENSION uint64_t  u2IntrCtrl : 2;                /**< Bits 189:188 - IntCtl: Interrupt Control. */
     575        RT_GCC_EXTENSION uint64_t  u1Lint0Passthru : 1;           /**< Bit  190     - Lint0Pass: LINT0 Pass-through. */
     576        RT_GCC_EXTENSION uint64_t  u1Lint1Passthru : 1;           /**< Bit  191     - Lint1Pass: LINT1 Pass-through. */
     577        RT_GCC_EXTENSION uint64_t  u32Rsvd0 : 32;                 /**< Bits 223:192 - Reserved. */
     578        RT_GCC_EXTENSION uint64_t  u22Rsvd0 : 22;                 /**< Bits 245:224 - Reserved. */
     579        RT_GCC_EXTENSION uint64_t  u1AttrOverride : 1;            /**< Bit  246     - AttrV: Attribute Override. */
     580        RT_GCC_EXTENSION uint64_t  u1Mode0FC: 1;                  /**< Bit  247     - Mode0FC. */
     581        RT_GCC_EXTENSION uint64_t  u8SnoopAttr: 1;                /**< Bits 255:248 - Snoop Attribute. */
    570582    } n;
    571583    /** The 32-bit unsigned integer view. */
     
    573585    /** The 64-bit unsigned integer view. */
    574586    uint64_t        au64[4];
    575 } DEV_TAB_ENTRY_T;
    576 AssertCompileSize(DEV_TAB_ENTRY_T, 32);
    577 #define IOMMU_DEV_TAB_ENTRY_QWORD_0_VALID_MASK      UINT64_C(0x7fffffffffffff83)
    578 #define IOMMU_DEV_TAB_ENTRY_QWORD_1_VALID_MASK      UINT64_C(0xfffffbffffffffff)
    579 #define IOMMU_DEV_TAB_ENTRY_QWORD_2_VALID_MASK      UINT64_C(0xf70fffffffffffff)
    580 #define IOMMU_DEV_TAB_ENTRY_QWORD_3_VALID_MASK      UINT64_C(0xffc0000000000000)
     587} DTE_T;
     588AssertCompileSize(DTE_T, 32);
     589#define IOMMU_DTE_QWORD_0_VALID_MASK      UINT64_C(0x7fffffffffffff83)
     590#define IOMMU_DTE_QWORD_1_VALID_MASK      UINT64_C(0xfffffbffffffffff)
     591#define IOMMU_DTE_QWORD_2_VALID_MASK      UINT64_C(0xf70fffffffffffff)
     592#define IOMMU_DTE_QWORD_3_VALID_MASK      UINT64_C(0xffc0000000000000)
    581593/** Pointer to a device table entry. */
    582 typedef DEV_TAB_ENTRY_T *PDEV_TAB_ENTRY_T;
     594typedef DTE_T *PDTE_T;
    583595/** Pointer to a const device table entry. */
    584 typedef DEV_TAB_ENTRY_T const *PCDEV_TAB_ENTRY_T;
     596typedef DTE_T const *PCDTE_T;
    585597
    586598/**
     
    717729    /** The 64-bit unsigned integer view. */
    718730    uint64_t    au64[2];
    719 } CMD_INV_DEV_TAB_ENTRY_T;
    720 AssertCompileSize(CMD_INV_DEV_TAB_ENTRY_T, 16);
     731} CMD_INV_DTE_T;
     732AssertCompileSize(CMD_INV_DTE_T, 16);
    721733
    722734/**
     
    899911    /** The 32-bit unsigned integer view.  */
    900912    uint32_t    au32[4];
    901 } EVT_ILLEGAL_DEV_TAB_ENTRY_T;
    902 AssertCompileSize(EVT_ILLEGAL_DEV_TAB_ENTRY_T, 16);
     913} EVT_ILLEGAL_DTE_T;
     914AssertCompileSize(EVT_ILLEGAL_DTE_T, 16);
    903915/** Pointer to an illegal device table entry event. */
    904 typedef EVT_ILLEGAL_DEV_TAB_ENTRY_T *PEVT_ILLEGAL_DEV_TAB_ENTRY_T;
     916typedef EVT_ILLEGAL_DTE_T *PEVT_ILLEGAL_DTE_T;
    905917
    906918/**
     
    20072019AssertCompileSize(IOMMUOP, 4);
    20082020
    2009 
    20102021/**
    20112022 * The shared IOMMU device state.
     
    32133224}
    32143225
     3226
    32153227/**
    32163228 * Clears the MSI interrupt for the IOMMU device.
     
    33133325 * Constructs a DEV_TAB_HARDWARE_ERROR event.
    33143326 *
    3315  * @param   uDevId              The device ID.
    3316  * @param   GCPhysDevTabEntry   The system physical address of the failed device
    3317  *                              table access.
    3318  * @param   enmOp               The operation being performed.
    3319  * @param   pEvent              Where to store the constructed event.
     3327 * @param   uDevId      The device ID.
     3328 * @param   GCPhysDte   The system physical address of the failed device table
     3329 *                      access.
     3330 * @param   enmOp       The operation being performed.
     3331 * @param   pEvent      Where to store the constructed event.
    33203332 *
    33213333 * @thread  Any.
    33223334 */
    3323 static void iommuAmdMakeDevTabHwErrorEvent(uint16_t uDevId, RTGCPHYS GCPhysDevTabEntry, IOMMUOP enmOp, PEVT_GENERIC_T pEvent)
     3335static void iommuAmdMakeDevTabHwErrorEvent(uint16_t uDevId, RTGCPHYS GCPhysDte, IOMMUOP enmOp, PEVT_GENERIC_T pEvent)
    33243336{
    33253337    memset(pEvent, 0, sizeof(*pEvent));
     
    33323344    pDevTabHwErr->n.u2Type        = enmOp == IOMMUOP_CMD ? HWEVTTYPE_DATA_ERROR : HWEVTTYPE_TARGET_ABORT;
    33333345    pDevTabHwErr->n.u4EvtCode     = IOMMU_EVT_DEV_TAB_HW_ERROR;
    3334     pDevTabHwErr->n.u64Addr       = GCPhysDevTabEntry;
     3346    pDevTabHwErr->n.u64Addr       = GCPhysDte;
    33353347}
    33363348
     
    33393351 * Raises a DEV_TAB_HARDWARE_ERROR event.
    33403352 *
    3341  * @param   pDevIns             The IOMMU device instance.
    3342  * @param   uDevId              The device ID.
    3343  * @param   GCPhysDevTabEntry   The system physical address of the failed device
    3344  *                              table access.
    3345  * @param   enmOp               The operation being performed by the IOMMU.
    3346  */
    3347 static void iommuAmdRaiseDevTabHwErrorEvent(PPDMDEVINS pDevIns, uint16_t uDevId, RTGCPHYS GCPhysDevTabEntry, IOMMUOP enmOp)
     3353 * @param   pDevIns     The IOMMU device instance.
     3354 * @param   uDevId      The device ID.
     3355 * @param   GCPhysDte   The system physical address of the failed device table
     3356 *                      access.
     3357 * @param   enmOp       The operation being performed by the IOMMU.
     3358 */
     3359static void iommuAmdRaiseDevTabHwErrorEvent(PPDMDEVINS pDevIns, uint16_t uDevId, RTGCPHYS GCPhysDte, IOMMUOP enmOp)
    33483360{
    33493361    EVT_GENERIC_T Event;
    3350     iommuAmdMakeDevTabHwErrorEvent(uDevId, GCPhysDevTabEntry, enmOp, &Event);
     3362    iommuAmdMakeDevTabHwErrorEvent(uDevId, GCPhysDte, enmOp, &Event);
    33513363    iommuAmdSetHwError(pDevIns, &Event);
    33523364    iommuAmdWriteEvtLogEntry(pDevIns, &Event);
     
    33663378 * @param   pEvent          Where to store the constructed event.
    33673379 */
    3368 static void iommuAmdMakeIllegalDevTabEntryEvent(uint16_t uDevId, uint64_t uDva, bool fRsvdNotZero, IOMMUOP enmOp,
    3369                                                 PEVT_GENERIC_T pEvent)
     3380static void iommuAmdMakeIllegalDteEvent(uint16_t uDevId, uint64_t uDva, bool fRsvdNotZero, IOMMUOP enmOp, PEVT_GENERIC_T pEvent)
    33703381{
    33713382    memset(pEvent, 0, sizeof(*pEvent));
    3372     AssertCompile(sizeof(EVT_ILLEGAL_DEV_TAB_ENTRY_T) == sizeof(EVT_GENERIC_T));
    3373     PEVT_ILLEGAL_DEV_TAB_ENTRY_T pIllegalDteErr = (PEVT_ILLEGAL_DEV_TAB_ENTRY_T)pEvent;
     3383    AssertCompile(sizeof(EVT_ILLEGAL_DTE_T) == sizeof(EVT_GENERIC_T));
     3384    PEVT_ILLEGAL_DTE_T pIllegalDteErr = (PEVT_ILLEGAL_DTE_T)pEvent;
    33743385    pIllegalDteErr->n.u16DevId      = uDevId;
    33753386    pIllegalDteErr->n.u1Interrupt   = RT_BOOL(enmOp == IOMMUOP_INTR_REQ);
     
    33953406 * @param   enmOp           The operation being performed.
    33963407 */
    3397 static void iommuAmdRaiseIllegalDevTabEntryEvent(PPDMDEVINS pDevIns, uint16_t uDevId, uint64_t uDva, bool fRsvdNotZero,
    3398                                                  IOMMUOP enmOp)
     3408static void iommuAmdRaiseIllegalDteEvent(PPDMDEVINS pDevIns, uint16_t uDevId, uint64_t uDva, bool fRsvdNotZero, IOMMUOP enmOp)
    33993409{
    34003410    EVT_GENERIC_T Event;
    3401     iommuAmdMakeIllegalDevTabEntryEvent(uDevId, uDva, fRsvdNotZero, enmOp, &Event);
     3411    iommuAmdMakeIllegalDteEvent(uDevId, uDva, fRsvdNotZero, enmOp, &Event);
    34023412    iommuAmdWriteEvtLogEntry(pDevIns, &Event);
    34033413    if (enmOp != IOMMUOP_CMD)
    34043414        iommuAmdSetPciTargetAbort(pDevIns);
    34053415}
    3406 
    34073416
    34083417
     
    34123421 *
    34133422 * @returns @c true if the DVA is excluded, @c false otherwise.
    3414  * @param   pThis           The IOMMU device state.
    3415  * @param   pDevTabEntry    The device table entry.
    3416  * @param   uDva            The device virtual address.
    3417  */
    3418 static bool iommuAmdIsDvaSubjectToExclRange(PCIOMMU pThis, PCDEV_TAB_ENTRY_T pDevTabEntry, uint64_t uDva)
     3423 * @param   pThis   The IOMMU device state.
     3424 * @param   pDte    The device table entry.
     3425 * @param   uDva    The device virtual address.
     3426 */
     3427static bool iommuAmdIsDvaSubjectToExclRange(PCIOMMU pThis, PCDTE_T pDte, uint64_t uDva)
    34193428{
    34203429    /* Check if the exclusion range is enabled. */
     
    34283437            /* Check if device access to addresses in the exclusion range can be forwarded untranslated. */
    34293438            if (    pThis->ExclRangeBaseAddr.n.u1AllowAll
    3430                 ||  pDevTabEntry->n.u1AllowExclusion)
     3439                ||  pDte->n.u1AllowExclusion)
    34313440                return true;
    34323441        }
     
    34403449 *
    34413450 * @returns VBox status code.
    3442  * @param   pDevIns         The IOMMU device instance.
    3443  * @param   uDevId          The device ID.
    3444  * @param   enmOp           The operation being performed by the IOMMU.
    3445  * @param   pDevTabEntry    Where to store the device table entry.
     3451 * @param   pDevIns     The IOMMU device instance.
     3452 * @param   uDevId      The device ID.
     3453 * @param   enmOp       The operation being performed by the IOMMU.
     3454 * @param   pDte        Where to store the device table entry.
    34463455 *
    34473456 * @thread  Any.
    34483457 */
    3449 static int iommuAmdReadDevTabEntry(PPDMDEVINS pDevIns, uint16_t uDevId, IOMMUOP enmOp, PDEV_TAB_ENTRY_T pDevTabEntry)
     3458static int iommuAmdReadDte(PPDMDEVINS pDevIns, uint16_t uDevId, IOMMUOP enmOp, PDTE_T pDte)
    34503459{
    34513460    PCIOMMU pThis = PDMDEVINS_2_DATA(pDevIns, PIOMMU);
     
    34583467    Assert(idxSeg < RT_ELEMENTS(pThis->aDevTabBaseAddrs));
    34593468
    3460     RTGCPHYS const GCPhysDevTab      = pThis->aDevTabBaseAddrs[idxSeg].n.u40Base << X86_PAGE_4K_SHIFT;
    3461     uint16_t const offDevTabEntry    = uDevId & ~g_auDevTabSegMasks[idxSegsEn];
    3462     RTGCPHYS const GCPhysDevTabEntry = GCPhysDevTab + offDevTabEntry;
     3469    RTGCPHYS const GCPhysDevTab = pThis->aDevTabBaseAddrs[idxSeg].n.u40Base << X86_PAGE_4K_SHIFT;
     3470    uint16_t const offDte       = uDevId & ~g_auDevTabSegMasks[idxSegsEn];
     3471    RTGCPHYS const GCPhysDte    = GCPhysDevTab + offDte;
    34633472
    34643473    Assert(!(GCPhysDevTab & X86_PAGE_4K_OFFSET_MASK));
    3465     int rc = PDMDevHlpPCIPhysRead(pDevIns, GCPhysDevTabEntry, pDevTabEntry, sizeof(*pDevTabEntry));
     3474    int rc = PDMDevHlpPCIPhysRead(pDevIns, GCPhysDte, pDte, sizeof(*pDte));
    34663475    if (RT_FAILURE(rc))
    34673476    {
    3468         Log((IOMMU_LOG_PFX ": Failed to read device table entry at %#RGp. rc=%Rrc\n", GCPhysDevTabEntry, rc));
    3469         iommuAmdRaiseDevTabHwErrorEvent(pDevIns, uDevId, GCPhysDevTabEntry, enmOp);
     3477        Log((IOMMU_LOG_PFX ": Failed to read device table entry at %#RGp. rc=%Rrc\n", GCPhysDte, rc));
     3478        iommuAmdRaiseDevTabHwErrorEvent(pDevIns, uDevId, GCPhysDte, enmOp);
    34703479    }
    34713480
     
    34743483
    34753484
    3476 /**
    3477  * Memory read transaction from a device.
     3485#if 0
     3486/**
     3487 * Walks the I/O page tables to translate the given device virtual address and
     3488 * associated data.
     3489 *
     3490 * @returns VBox status code.
     3491 * @param   pDevIns     The IOMMU device instance.
     3492 * @param   uDva        The device virtual address.
     3493 * @param   cbRead      The size of the access.
     3494 * @param   fPerms      The access permissions (IOMMU_PERM_XXX).
     3495 * @param   pGCPhys     Where to store the translated address.
     3496 */
     3497static int iommuAmdWalkIoPageTable(PPDMDEVINS pDevIns, uint64_t uDva, size_t cbRead, uint32_t fAccess, PRTGCPHYS pGCPhys)
     3498{
     3499
     3500}
     3501#endif
     3502
     3503
     3504/**
     3505 * Memory read translation request from a device.
    34783506 *
    34793507 * @returns VBox status code.
     
    35033531
    35043532        /* Read the device table entry. */
    3505         DEV_TAB_ENTRY_T DevTabEntry;
    3506         int rc = iommuAmdReadDevTabEntry(pDevIns, uDevId, enmOp, &DevTabEntry);
     3533        DTE_T Dte;
     3534        int rc = iommuAmdReadDte(pDevIns, uDevId, enmOp, &Dte);
    35073535        if (RT_SUCCESS(rc))
    35083536        {
    35093537            /* Addresses are forwarded without translation when DTE.V is 0. */
    3510             if (DevTabEntry.n.u1Valid)
     3538            if (Dte.n.u1Valid)
    35113539            {
    35123540                /* Validate bits 127:0 of the device table entry when DTE.V is 1. */
    3513                 uint64_t const fRsvdQword0 = DevTabEntry.au64[0] & ~IOMMU_DEV_TAB_ENTRY_QWORD_0_VALID_MASK;
    3514                 uint64_t const fRsvdQword1 = DevTabEntry.au64[1] & ~IOMMU_DEV_TAB_ENTRY_QWORD_1_VALID_MASK;
     3541                uint64_t const fRsvdQword0 = Dte.au64[0] & ~IOMMU_DTE_QWORD_0_VALID_MASK;
     3542                uint64_t const fRsvdQword1 = Dte.au64[1] & ~IOMMU_DTE_QWORD_1_VALID_MASK;
    35153543                if (   fRsvdQword0
    35163544                    || fRsvdQword1)
    35173545                {
    35183546                    Log((IOMMU_LOG_PFX ":DTE invalid reserved bits ([0]=%#RX64 [1]=%#RX64)\n", fRsvdQword0, fRsvdQword1));
    3519                     iommuAmdRaiseIllegalDevTabEntryEvent(pDevIns, uDevId, uDva, true /* fRsvdNotZero */, enmOp);
     3547                    iommuAmdRaiseIllegalDteEvent(pDevIns, uDevId, uDva, true /* fRsvdNotZero */, enmOp);
    35203548                    return VERR_GENERAL_FAILURE; /** @todo IOMMU: Change this. */
    35213549                }
    35223550
    3523                 /* Check if the exclusion range is active. */
    3524                 if (!iommuAmdIsDvaSubjectToExclRange(pThis, &DevTabEntry, uDva))
     3551                /* Check if the device virtual address is subject to address exclusion. */
     3552                if (!iommuAmdIsDvaSubjectToExclRange(pThis, &Dte, uDva))
    35253553                {
    35263554                    /** @todo IOMMU: Traverse the I/O page table and translate. */
     3555
    35273556                    return VERR_NOT_IMPLEMENTED;
    35283557                }
     
    35423571
    35433572/**
    3544  * Memory write transaction from a device.
     3573 * Memory write translation request from a device.
    35453574 *
    35463575 * @returns VBox status code.
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette