From 4d54c7392f4267262a7a10cf73b7f8fd5f4fa31a Mon Sep 17 00:00:00 2001 From: Shengwen Cheng Date: Wed, 4 Sep 2024 08:16:29 +0800 Subject: [PATCH] Introduce PACKED macro Introduce PACKED macro for cross-platform structure alignment, frequently used by VirtIO device implementations in the semu. --- common.h | 9 +++++++++ virtio-blk.c | 8 ++++---- virtio-net.c | 4 ++-- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/common.h b/common.h index 2a45682..5c6d807 100644 --- a/common.h +++ b/common.h @@ -25,3 +25,12 @@ static inline int ilog2(int x) */ #define RANGE_CHECK(x, minx, size) \ ((int32_t) ((x - minx) | (minx + size - 1 - x)) >= 0) + +/* Packed macro */ +#if defined(__GNUC__) || defined(__clang__) +#define PACKED(name) name __attribute__((packed)) +#elif defined(_MSC_VER) +#define PACKED(name) __pragma(pack(push, 1)) name __pragma(pack(pop)) +#else /* unsupported compilers */ +#define PACKED(name) +#endif diff --git a/virtio-blk.c b/virtio-blk.c index 416583b..63ecf1d 100644 --- a/virtio-blk.c +++ b/virtio-blk.c @@ -26,7 +26,7 @@ #define PRIV(x) ((struct virtio_blk_config *) x->priv) -struct virtio_blk_config { +PACKED(struct virtio_blk_config { uint64_t capacity; uint32_t size_max; uint32_t seg_max; @@ -55,14 +55,14 @@ struct virtio_blk_config { uint32_t max_write_zeroes_seg; uint8_t write_zeroes_may_unmap; uint8_t unused1[3]; -} __attribute__((packed)); +}); -struct vblk_req_header { +PACKED(struct vblk_req_header { uint32_t type; uint32_t reserved; uint64_t sector; uint8_t status; -} __attribute__((packed)); +}); static struct virtio_blk_config vblk_configs[VBLK_DEV_CNT_MAX]; static int vblk_dev_cnt = 0; diff --git a/virtio-net.c b/virtio-net.c index 69642de..ddba34d 100644 --- a/virtio-net.c +++ b/virtio-net.c @@ -30,12 +30,12 @@ enum { VNET_QUEUE_RX = 0, VNET_QUEUE_TX = 1 }; -struct virtio_net_config { +PACKED(struct virtio_net_config { uint8_t mac[6]; uint16_t status; uint16_t max_virtqueue_pairs; uint16_t mtu; -} __attribute__((packed)); +}); static struct virtio_net_config vnet_configs[VNET_DEV_CNT_MAX]; static int vnet_dev_cnt = 0;