qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [V17 3/4] hw/i386: Introduce AMD IOMMU


From: Michael S. Tsirkin
Subject: Re: [Qemu-devel] [V17 3/4] hw/i386: Introduce AMD IOMMU
Date: Fri, 16 Sep 2016 21:58:54 +0300

On Wed, Aug 31, 2016 at 07:17:42PM +0300, David Kiarie wrote:
> +/* serialize IOMMU command processing */
> +typedef struct QEMU_PACKED {
> +#ifdef HOST_WORDS_BIGENDIAN
> +    uint64_t type:4;               /* command type           */
> +    uint64_t reserved:8;
> +    uint64_t store_addr:49;        /* addr to write          */
> +    uint64_t completion_flush:1;   /* allow more executions  */
> +    uint64_t completion_int:1;     /* set MMIOWAITINT        */
> +    uint64_t completion_store:1;   /* write data to address  */
> +#else
> +    uint64_t completion_store:1;
> +    uint64_t completion_int:1;
> +    uint64_t completion_flush:1;
> +    uint64_t store_addr:49;
> +    uint64_t reserved:8;
> +    uint64_t type:4;
> +#endif /* __BIG_ENDIAN_BITFIELD */
> +    uint64_t store_data;           /* data to write          */
> +} CMDCompletionWait;
> +
> +/* invalidate internal caches for devid */
> +typedef struct QEMU_PACKED {
> +#ifdef HOST_WORDS_BIGENDIAN
> +    uint64_t devid:16;             /* device to invalidate   */
> +    uint64_t reserved_1:44;
> +    uint64_t type:4;               /* command type           */
> +#else
> +    uint64_t devid:16;
> +    uint64_t reserved_1:44;
> +    uint64_t type:4;
> +#endif /* __BIG_ENDIAN_BITFIELD */
> +    uint64_t reserved_2;
> +} CMDInvalDevEntry;
> +
> +/* invalidate a range of entries in IOMMU translation cache for devid */
> +typedef struct QEMU_PACKED {
> +#ifdef HOST_WORDS_BIGENDIAN
> +    uint64_t type:4;               /* command type           */
> +    uint64_t reserved_2:12
> +    uint64_t domid:16;             /* domain to inval for    */
> +    uint64_t reserved_1:12;
> +    uint64_t pasid:20;
> +#else
> +    uint64_t pasid:20;
> +    uint64_t reserved_1:12;
> +    uint64_t domid:16;
> +    uint64_t reserved_2:12;
> +    uint64_t type:4;
> +#endif /* __BIG_ENDIAN_BITFIELD */
> +
> +#ifdef HOST_WORDS_BIGENDIAN
> +    uint64_t address:51;          /* address to invalidate   */
> +    uint64_t reserved_3:10;
> +    uint64_t guest:1;             /* G/N invalidation        */
> +    uint64_t pde:1;               /* invalidate cached ptes  */
> +    uint64_t size:1               /* size of invalidation    */
> +#else
> +    uint64_t size:1;
> +    uint64_t pde:1;
> +    uint64_t guest:1;
> +    uint64_t reserved_3:10;
> +    uint64_t address:51;
> +#endif /* __BIG_ENDIAN_BITFIELD */
> +} CMDInvalIommuPages;
> +
> +/* inval specified address for devid from remote IOTLB */
> +typedef struct QEMU_PACKED {
> +#ifdef HOST_WORDS_BIGENDIAN
> +    uint64_t type:4;            /* command type        */
> +    uint64_t pasid_19_6:4;
> +    uint64_t pasid_7_0:8;
> +    uint64_t queuid:16;
> +    uint64_t maxpend:8;
> +    uint64_t pasid_15_8;
> +    uint64_t devid:16;         /* related devid        */
> +#else
> +    uint64_t devid:16;
> +    uint64_t pasid_15_8:8;
> +    uint64_t maxpend:8;
> +    uint64_t queuid:16;
> +    uint64_t pasid_7_0:8;
> +    uint64_t pasid_19_6:4;
> +    uint64_t type:4;
> +#endif /* __BIG_ENDIAN_BITFIELD */
> +
> +#ifdef HOST_WORDS_BIGENDIAN
> +    uint64_t address:52;       /* invalidate addr      */
> +    uint64_t reserved_2:9;
> +    uint64_t guest:1;          /* G/N invalidate       */
> +    uint64_t reserved_1:1;
> +    uint64_t size:1;           /* size of invalidation */
> +#else
> +    uint64_t size:1;
> +    uint64_t reserved_1:1;
> +    uint64_t guest:1;
> +    uint64_t reserved_2:9;
> +    uint64_t address:52;
> +#endif /* __BIG_ENDIAN_BITFIELD */
> +} CMDInvalIOTLBPages;
> +
> +/* invalidate all cached interrupt info for devid */
> +typedef struct QEMU_PACKED {
> +#ifdef HOST_WORDS_BIGENDIAN
> +    uint64_t type:4;          /* command type        */
> +    uint64_t reserved_1:44;
> +    uint64_t devid:16;        /* related devid       */
> +#else
> +    uint64_t devid:16;
> +    uint64_t reserved_1:44;
> +    uint64_t type:4;
> +#endif /* __BIG_ENDIAN_BITFIELD */
> +    uint64_t reserved_2;
> +} CMDInvalIntrTable;
> +
> +/* load adddress translation info for devid into translation cache */
> +typedef struct QEMU_PACKED {
> +#ifdef HOST_WORDS_BIGENDIAN
> +    uint64_t type:4;          /* command type       */
> +    uint64_t reserved_2:8;
> +    uint64_t pasid_19_0:20;
> +    uint64_t pfcount_7_0:8;
> +    uint64_t reserved_1:8;
> +    uint64_t devid:16;        /* related devid      */
> +#else
> +    uint64_t devid:16;
> +    uint64_t reserved_1:8;
> +    uint64_t pfcount_7_0:8;
> +    uint64_t pasid_19_0:20;
> +    uint64_t reserved_2:8;
> +    uint64_t type:4;
> +#endif /* __BIG_ENDIAN_BITFIELD */
> +
> +#ifdef HOST_WORDS_BIGENDIAN
> +    uint64_t address:52;     /* invalidate address       */
> +    uint64_t reserved_5:7;
> +    uint64_t inval:1;        /* inval matching entries   */
> +    uint64_t reserved_4:1;
> +    uint64_t guest:1;        /* G/N invalidate           */
> +    uint64_t reserved_3:1;
> +    uint64_t size:1;         /* prefetched page size     */
> +#else
> +    uint64_t size:1;
> +    uint64_t reserved_3:1;
> +    uint64_t guest:1;
> +    uint64_t reserved_4:1;
> +    uint64_t inval:1;
> +    uint64_t reserved_5:7;
> +    uint64_t address:52;
> +#endif /* __BIG_ENDIAN_BITFIELD */
> +} CMDPrefetchPages;
> +
> +/* clear all address translation/interrupt remapping caches */
> +typedef struct QEMU_PACKED {
> +#ifdef HOST_WORDS_BIGENDIAN
> +    uint64_t type:4;              /* command type       */
> +    uint64_t reserved_1:60;
> +#else
> +    uint64_t reserved_1:60;
> +    uint64_t type:4;
> +#endif /* __BIG_ENDIAN_BITFIELD */
> +    uint64_t reserved_2;
> +} CMDInvalIommuAll;
> +
> +/* issue a PCIe completion packet for devid */
> +typedef struct QEMU_PACKED {
> +    uint32_t reserved_1:16;
> +    uint32_t devid:16;
> +
> +#ifdef HOST_WORDS_BIGENDIAN
> +    uint32_t type:4;              /* command type       */
> +    uint32_t reserved_2:8;
> +    uint32_t pasid_19_0:20
> +#else
> +    uint32_t pasid_19_0:20;
> +    uint32_t reserved_2:8;
> +    uint32_t type:4;
> +#endif /* __BIG_ENDIAN_BITFIELD */
> +
> +#ifdef HOST_WORDS_BIGENDIAN
> +    uint32_t reserved_3:29;
> +    uint32_t guest:1;
> +    uint32_t reserved_4:2;
> +#else
> +    uint32_t reserved_3:2;
> +    uint32_t guest:1;
> +    uint32_t reserved_4:29;
> +#endif /* __BIG_ENDIAN_BITFIELD */
> +
> +    uint32_t completion_tag:16;  /* PCIe PRI information */
> +    uint32_t reserved_5:16;
> +} CMDCompletePPR;

So as Peter points, out, we don't do this kind of
thing. Pls drop this ifdefery and rework using
masks and cpu_to_le. E.g.

    > +#ifdef HOST_WORDS_BIGENDIAN
    > +    uint32_t reserved_3:29;
    > +    uint32_t guest:1;
    > +    uint32_t reserved_4:2;
    > +#else
    > +    uint32_t reserved_3:2;
    > +    uint32_t guest:1;
    > +    uint32_t reserved_4:29;
    > +#endif /* __BIG_ENDIAN_BITFIELD */

    guest = 1;

->

#define GUEST cpu_to_le32(0x1 << 2)
uint32_t guest;

guest = GUEST;


-- 
MST



reply via email to

[Prev in Thread] Current Thread [Next in Thread]