VirtualBox

Changeset 83732 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Apr 17, 2020 7:13:48 AM (5 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
137250
Message:

AMD IOMMU: bugref:9654 Bits.

File:
1 edited

Legend:

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

    r83714 r83732  
    380380
    381381/**
    382  * Acquires the IOMMU lock or returns.
     382 * Acquires the IOMMU PDM lock or returns @a a_rcBusy if it's busy.
    383383 */
    384384#define IOMMU_LOCK_RET(a_pDevIns, a_pThis, a_rcBusy)  \
    385385    do { \
    386         int rcLock = PDMDevHlpCritSectEnter((a_pDevIns), &(a_pThis)->CritSect, (a_rcBusy)); \
     386        NOREF(pThis); \
     387        int rcLock = PDMDevHlpCritSectEnter((a_pDevIns), (a_pDevIns)->CTX_SUFF(pCritSectRo), (a_rcBusy)); \
    387388        if (RT_LIKELY(rcLock == VINF_SUCCESS)) \
    388389        { /* likely */ } \
     
    392393
    393394/**
    394  * Releases the IOMMU lock.
     395 * Releases the IOMMU PDM lock.
    395396 */
    396397#define IOMMU_UNLOCK(a_pDevIns, a_pThis) \
    397     do { PDMDevHlpCritSectLeave((a_pDevIns), &(a_pThis)->CritSect); } while (0)
     398    do { \
     399        PDMDevHlpCritSectLeave((a_pDevIns), (a_pDevIns)->CTX_SUFF(pCritSectRo)); \
     400    } while (0)
    398401
    399402
     
    9991002
    10001003/**
     1004 * IOMMU Base Address (Lo and Hi) Register (PCI).
     1005 * In accordance with the AMD spec.
     1006 */
     1007typedef union
     1008{
     1009    struct
     1010    {
     1011        uint32_t   u1Enable : 1;       /**< Bit  1     - Enable: RW1S - Enable IOMMU MMIO region. */
     1012        uint32_t   u12Rsvd0 : 12;      /**< Bits 13:1  - Reserved. */
     1013        uint32_t   u18BaseAddrLo : 18; /**< Bits 31:14 - Base address (Lo) of the MMIO region. */
     1014        uint32_t   u32BaseAddrHi;      /**< Bits 63:32 - Base address (Hi) of the MMIO region. */
     1015    } n;
     1016    /** The 32-bit unsigned integer view. */
     1017    uint32_t    au32[2];
     1018    /** The 64-bit unsigned integer view. */
     1019    uint64_t    u64;
     1020} IOMMU_BAR_T;
     1021AssertCompileSize(IOMMU_BAR_T, 8);
     1022#define IOMMU_BAR_VALID_MASK    UINT64_C(0xffffffffffffc001)
     1023
     1024/**
     1025 * IOMMU Range Register (PCI).
     1026 * In accordance with the AMD spec.
     1027 */
     1028typedef union
     1029{
     1030    struct
     1031    {
     1032        uint32_t    u5HtUnitId : 5;     /**< Bits 4:0   - UnitID: IOMMU HyperTransport Unit ID (not used). */
     1033        uint32_t    u2Rsvd0 : 2;        /**< Bits 6:5   - Reserved. */
     1034        uint32_t    u1RangeValid : 1;   /**< Bit  7     - RngValid: Range Valid. */
     1035        uint32_t    u8Bus : 8;          /**< Bits 15:8  - BusNumber: Bus number of the first and last device. */
     1036        uint32_t    u8FirstDevice : 8;  /**< Bits 23:16 - FirstDevice: Device and function number of the first device. */
     1037        uint32_t    u8LastDevice: 8;    /**< Bits 31:24 - LastDevice: Device and function number of the last device. */
     1038    } n;
     1039    /** The 32-bit unsigned integer view. */
     1040    uint32_t    u32;
     1041} IOMMU_RANGE_T;
     1042AssertCompileSize(IOMMU_RANGE_T, 4);
     1043
     1044/**
    10011045 * Device Table Base Address Register (MMIO).
    10021046 * In accordance with the AMD spec.
     
    11511195#define IOMMU_EXCL_RANGE_LIMIT_VALID_MASK   UINT64_C(0x000ffffffffff000)
    11521196
    1153 
    11541197/**
    11551198 * IOMMU Extended Feature Register (MMIO).
     
    18521895    bool                        afPadding[7];
    18531896
     1897    /** @name PCI: Base capability block registers.
     1898     * @{ */
     1899    IOMMU_BAR_T                 IommuBar;
     1900    /** @} */
     1901
    18541902    /** @name MMIO: Control and status registers.
    18551903     * @{ */
     
    21052153{
    21062154    RT_NOREF(pDevIns, pThis, iReg, u64Value);
    2107     Log((IOMMU_LOG_PFX ": iommuAmdIgnore_w: Write to read-only register (%#x) with value %#RX64 ignored\n", iReg, u64Value));
     2155    Log((IOMMU_LOG_PFX ": Write to read-only register (%#x) with value %#RX64 ignored\n", iReg, u64Value));
    21082156    return VINF_SUCCESS;
    21092157}
     
    25572605        case IOMMU_MMIO_OFF_SMI_FLT_LAST:
    25582606        {
    2559             Log((IOMMU_LOG_PFX ": iommuAmdWriteRegister: Writing unsupported register: SMI filter %u -> Ignored\n",
     2607            Log((IOMMU_LOG_PFX ": Writing unsupported register: SMI filter %u -> Ignored\n",
    25602608                 (off - IOMMU_MMIO_OFF_SMI_FLT_FIRST) >> 3));
    25612609            return VINF_SUCCESS;
     
    25652613        default:
    25662614        {
    2567             Log((IOMMU_LOG_PFX ": iommuAmdWriteRegister: Trying to write unknown register at %u (%#x) with %#RX64\n", off, off,
    2568                  uValue));
     2615            Log((IOMMU_LOG_PFX ": Writing unknown register %u (%#x) with %#RX64 -> Ignored\n", off, off, uValue));
    25692616            return VINF_SUCCESS;
    25702617        }
     
    26892736        case IOMMU_MMIO_OFF_SMI_FLT_LAST:
    26902737        {
    2691             Log((IOMMU_LOG_PFX ": iommuAmdReadRegister: Reading unsupported register: SMI filter %u\n",
    2692                  (off - IOMMU_MMIO_OFF_SMI_FLT_FIRST) >> 3));
     2738            Log((IOMMU_LOG_PFX ": Reading unsupported register: SMI filter %u\n", (off - IOMMU_MMIO_OFF_SMI_FLT_FIRST) >> 3));
    26932739            uReg = 0;
    26942740            break;
     
    26982744        default:
    26992745        {
    2700             Log((IOMMU_LOG_PFX ": iommuAmdReadRegister: Trying to read unknown register at %u (%#x)\n", off, off));
     2746            Log((IOMMU_LOG_PFX ": Reading unknown register %u (%#x) -> 0\n", off, off));
    27012747            uReg = 0;
    27022748            return VINF_IOM_MMIO_UNUSED_00;
     
    27512797    /** @todo IOMMU: PCI config read stat counter. */
    27522798    VBOXSTRICTRC rcStrict = PDMDevHlpPCIConfigRead(pDevIns, pPciDev, uAddress, cb, pu32Value);
    2753     Log3((IOMMU_LOG_PFX ": PCI config read: At %#x (%u) -> %#x %Rrc\n", uAddress, cb, *pu32Value, VBOXSTRICTRC_VAL(rcStrict)));
     2799    Log3((IOMMU_LOG_PFX ": Reading PCI config register %#x (cb=%u) -> %#x %Rrc\n", uAddress, cb, *pu32Value,
     2800          VBOXSTRICTRC_VAL(rcStrict)));
    27542801    return rcStrict;
    27552802}
     
    27622809                                                           unsigned cb, uint32_t u32Value)
    27632810{
    2764     /** @todo IOMMU: PCI config write. */
    2765     VBOXSTRICTRC rcStrict = PDMDevHlpPCIConfigWrite(pDevIns, pPciDev, uAddress, cb, u32Value);
     2811    PIOMMU pThis = PDMDEVINS_2_DATA(pDevIns, PIOMMU);
     2812    Assert(pThis);
     2813
     2814    /*
     2815     * Discard writes to read-only registers that are specific to the IOMMU.
     2816     * Other common PCI registers are handled by the generic code, see devpciR3IsConfigByteWritable().
     2817     * See PCI spec. 6.1. "Configuration Space Organization".
     2818     */
     2819    switch (uAddress)
     2820    {
     2821        case IOMMU_PCI_OFF_CAP_HDR:
     2822        case IOMMU_PCI_OFF_RANGE_REG:
     2823        case IOMMU_PCI_OFF_MISCINFO_REG_0:
     2824        case IOMMU_PCI_OFF_MISCINFO_REG_1: /* We don't support guest-address translation (GASup=0). */
     2825        {
     2826            Log((IOMMU_LOG_PFX ": PCI config write (%#RX32) to read-only register %#x -> Ignored\n", u32Value, uAddress));
     2827            return VINF_SUCCESS;
     2828        }
     2829    }
     2830
     2831    IOMMU_LOCK_RET(pDevIns, pThis, VERR_IGNORED);
     2832
     2833    VBOXSTRICTRC rcStrict;
     2834    switch (uAddress)
     2835    {
     2836        case IOMMU_PCI_OFF_BASE_ADDR_REG_LO:
     2837        {
     2838            IOMMU_BAR_T const IommuBar = pThis->IommuBar;
     2839            if (!IommuBar.n.u1Enable)
     2840            {
     2841                pThis->IommuBar.au32[0] = u32Value & IOMMU_BAR_VALID_MASK;
     2842                Assert(pThis->hMmio == NIL_IOMMMIOHANDLE);
     2843                RTGCPHYS const GCPhysMmioBase = RT_MAKE_U64(pThis->IommuBar.n.u18BaseAddrLo, pThis->IommuBar.n.u32BaseAddrHi);
     2844                rcStrict = PDMDevHlpMmioMap(pDevIns, pThis->hMmio, GCPhysMmioBase);
     2845                if (RT_FAILURE(rcStrict))
     2846                    Log((IOMMU_LOG_PFX ": Failed to map IOMMU MMIO region at %#RGp. rc=%Rrc\n", GCPhysMmioBase, rcStrict));
     2847            }
     2848            else
     2849            {
     2850                rcStrict = VINF_SUCCESS;
     2851                Log((IOMMU_LOG_PFX ": Writing Base Address (Lo) when it's already enabled -> Ignored\n"));
     2852            }
     2853            break;
     2854        }
     2855
     2856        case IOMMU_PCI_OFF_BASE_ADDR_REG_HI:
     2857        {
     2858            IOMMU_BAR_T const IommuBar = pThis->IommuBar;
     2859            if (!IommuBar.n.u1Enable)
     2860                pThis->IommuBar.au32[1] = u32Value;
     2861            else
     2862            {
     2863                rcStrict = VINF_SUCCESS;
     2864                Log((IOMMU_LOG_PFX ": Writing Base Address (Hi) when it's already enabled -> Ignored\n"));
     2865            }
     2866            break;
     2867        }
     2868
     2869        default:
     2870            rcStrict = PDMDevHlpPCIConfigWrite(pDevIns, pPciDev, uAddress, cb, u32Value);
     2871            break;
     2872    }
     2873
     2874    IOMMU_UNLOCK(pDevIns, pThis);
     2875
    27662876    Log3((IOMMU_LOG_PFX ": PCI config write: %#x -> To %#x (%u) %Rrc\n", u32Value, uAddress, cb, VBOXSTRICTRC_VAL(rcStrict)));
    27672877    return rcStrict;
     
    27772887    Assert(pThis);
    27782888
    2779     LogFlow((IOMMU_LOG_PFX ": iommuAmdR3DbgInfo: pThis=%p pszArgs=%s\n", pThis, pszArgs));
     2889    LogFlow((IOMMU_LOG_PFX ": %s: pThis=%p pszArgs=%s\n", __PRETTY_FUNCTION__, pThis, pszArgs));
    27802890    bool const fVerbose = !strncmp(pszArgs, RT_STR_TUPLE("verbose")) ? true : false;
    27812891
     
    33703480    pThis->ExtFeat.n.u1InvAllSup             = 0;
    33713481    pThis->ExtFeat.n.u1GstVirtApicSup        = 0;
    3372     pThis->ExtFeat.n.u1HwErrorSup            = 0;
     3482    pThis->ExtFeat.n.u1HwErrorSup            = 1;
    33733483    pThis->ExtFeat.n.u1PerfCounterSup        = 0;
    33743484    pThis->ExtFeat.n.u2HostAddrTranslateSize = 0;   /* Requires GstTranslateSup. */
     
    36013711
    36023712    /*
    3603      * Register the MMIO region.
     3713     * Create the MMIO region.
     3714     * Mapping of the region is done when software configures it via PCI config space.
    36043715     */
    36053716    rc = PDMDevHlpMmioCreate(pDevIns, IOMMU_MMIO_REGION_SIZE, pPciDev, 0 /* iPciRegion */, iommuAmdMmioWrite, iommuAmdMmioRead,
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