qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

misc: Replace zero-length arrays with flexible array member (automatic)

Description copied from Linux kernel commit from Gustavo A. R. Silva
(see [3]):

--v-- description start --v--

The current codebase makes use of the zero-length array language
extension to the C90 standard, but the preferred mechanism to
declare variable-length types such as these ones is a flexible
array member [1], introduced in C99:

struct foo {
int stuff;
struct boo array[];
};

By making use of the mechanism above, we will get a compiler
warning in case the flexible array does not occur last in the
structure, which will help us prevent some kind of undefined
behavior bugs from being unadvertenly introduced [2] to the
Linux codebase from now on.

--^-- description end --^--

Do the similar housekeeping in the QEMU codebase (which uses
C99 since commit 7be41675f7cb).

All these instances of code were found with the help of the
following Coccinelle script:

@@
identifier s, m, a;
type t, T;
@@
struct s {
...
t m;
- T a[0];
+ T a[];
};
@@
identifier s, m, a;
type t, T;
@@
struct s {
...
t m;
- T a[0];
+ T a[];
} QEMU_PACKED;

[1] https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html
[2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=76497732932f
[3] https://git.kernel.org/pub/scm/linux/kernel/git/gustavoars/linux.git/commit/?id=17642a2fbd2c1

Inspired-by: Gustavo A. R. Silva <gustavo@embeddedor.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

authored by

Philippe Mathieu-Daudé and committed by
Paolo Bonzini
f7795e40 770275ed

+35 -34
+1 -1
block/linux-aio.c
··· 121 121 unsigned incompat_features; 122 122 unsigned header_length; /* size of aio_ring */ 123 123 124 - struct io_event io_events[0]; 124 + struct io_event io_events[]; 125 125 }; 126 126 127 127 /**
+1 -1
bsd-user/qemu.h
··· 95 95 struct sigqueue *first_free; /* first free siginfo queue entry */ 96 96 int signal_pending; /* non zero if a signal may be pending */ 97 97 98 - uint8_t stack[0]; 98 + uint8_t stack[]; 99 99 } __attribute__((aligned(16))) TaskState; 100 100 101 101 void init_task_state(TaskState *ts);
+1 -1
contrib/libvhost-user/libvhost-user.h
··· 286 286 uint16_t used_idx; 287 287 288 288 /* Used to track the state of each descriptor in descriptor table */ 289 - VuDescStateSplit desc[0]; 289 + VuDescStateSplit desc[]; 290 290 } VuVirtqInflight; 291 291 292 292 typedef struct VuVirtqInflightDesc {
+3 -3
hw/acpi/nvdimm.c
··· 485 485 /* the size of buffer filled by QEMU. */ 486 486 uint32_t len; 487 487 uint32_t func_ret_status; /* return status code. */ 488 - uint8_t out_buf[0]; /* the data got via Get Namesapce Label function. */ 488 + uint8_t out_buf[]; /* the data got via Get Namesapce Label function. */ 489 489 } QEMU_PACKED; 490 490 typedef struct NvdimmFuncGetLabelDataOut NvdimmFuncGetLabelDataOut; 491 491 QEMU_BUILD_BUG_ON(sizeof(NvdimmFuncGetLabelDataOut) > NVDIMM_DSM_MEMORY_SIZE); ··· 493 493 struct NvdimmFuncSetLabelDataIn { 494 494 uint32_t offset; /* the offset in the namespace label data area. */ 495 495 uint32_t length; /* the size of data is to be written via the function. */ 496 - uint8_t in_buf[0]; /* the data written to label data area. */ 496 + uint8_t in_buf[]; /* the data written to label data area. */ 497 497 } QEMU_PACKED; 498 498 typedef struct NvdimmFuncSetLabelDataIn NvdimmFuncSetLabelDataIn; 499 499 QEMU_BUILD_BUG_ON(sizeof(NvdimmFuncSetLabelDataIn) + ··· 510 510 /* the size of buffer filled by QEMU. */ 511 511 uint32_t len; 512 512 uint32_t func_ret_status; /* return status code. */ 513 - uint8_t fit[0]; /* the FIT data. */ 513 + uint8_t fit[]; /* the FIT data. */ 514 514 } QEMU_PACKED; 515 515 typedef struct NvdimmFuncReadFITOut NvdimmFuncReadFITOut; 516 516 QEMU_BUILD_BUG_ON(sizeof(NvdimmFuncReadFITOut) > NVDIMM_DSM_MEMORY_SIZE);
+1 -1
hw/dma/soc_dma.c
··· 80 80 } *memmap; 81 81 int memmap_size; 82 82 83 - struct soc_dma_ch_s ch[0]; 83 + struct soc_dma_ch_s ch[]; 84 84 }; 85 85 86 86 static void soc_dma_ch_schedule(struct soc_dma_ch_s *ch, int delay_bytes)
+1 -1
hw/i386/x86.c
··· 328 328 uint64_t next; 329 329 uint32_t type; 330 330 uint32_t len; 331 - uint8_t data[0]; 331 + uint8_t data[]; 332 332 } __attribute__((packed)); 333 333 334 334
+1 -1
hw/m68k/bootinfo.h
··· 14 14 struct bi_record { 15 15 uint16_t tag; /* tag ID */ 16 16 uint16_t size; /* size of record */ 17 - uint32_t data[0]; /* data */ 17 + uint32_t data[]; /* data */ 18 18 }; 19 19 20 20 /* machine independent tags */
+1 -1
hw/misc/omap_l4.c
··· 24 24 MemoryRegion *address_space; 25 25 hwaddr base; 26 26 int ta_num; 27 - struct omap_target_agent_s ta[0]; 27 + struct omap_target_agent_s ta[]; 28 28 }; 29 29 30 30 struct omap_l4_s *omap_l4_init(MemoryRegion *address_space,
+1 -1
hw/nvram/eeprom93xx.c
··· 86 86 uint8_t addrbits; 87 87 uint16_t size; 88 88 uint16_t data; 89 - uint16_t contents[0]; 89 + uint16_t contents[]; 90 90 }; 91 91 92 92 /* Code for saving and restoring of EEPROM state. */
+2 -2
hw/rdma/vmw/pvrdma_qp_ops.c
··· 34 34 /* Send Queue WQE */ 35 35 typedef struct PvrdmaSqWqe { 36 36 struct pvrdma_sq_wqe_hdr hdr; 37 - struct pvrdma_sge sge[0]; 37 + struct pvrdma_sge sge[]; 38 38 } PvrdmaSqWqe; 39 39 40 40 /* Recv Queue WQE */ 41 41 typedef struct PvrdmaRqWqe { 42 42 struct pvrdma_rq_wqe_hdr hdr; 43 - struct pvrdma_sge sge[0]; 43 + struct pvrdma_sge sge[]; 44 44 } PvrdmaRqWqe; 45 45 46 46 /*
+1 -1
hw/usb/dev-network.c
··· 626 626 struct rndis_response { 627 627 QTAILQ_ENTRY(rndis_response) entries; 628 628 uint32_t length; 629 - uint8_t buf[0]; 629 + uint8_t buf[]; 630 630 }; 631 631 632 632 typedef struct USBNetState {
+2 -2
hw/usb/dev-smartcard-reader.c
··· 227 227 typedef struct QEMU_PACKED CCID_DataBlock { 228 228 CCID_BULK_IN b; 229 229 uint8_t bChainParameter; 230 - uint8_t abData[0]; 230 + uint8_t abData[]; 231 231 } CCID_DataBlock; 232 232 233 233 /* 6.1.4 PC_to_RDR_XfrBlock */ ··· 235 235 CCID_Header hdr; 236 236 uint8_t bBWI; /* Block Waiting Timeout */ 237 237 uint16_t wLevelParameter; /* XXX currently unused */ 238 - uint8_t abData[0]; 238 + uint8_t abData[]; 239 239 } CCID_XferBlock; 240 240 241 241 typedef struct QEMU_PACKED CCID_IccPowerOn {
+2 -2
hw/virtio/virtio.c
··· 54 54 { 55 55 uint16_t flags; 56 56 uint16_t idx; 57 - uint16_t ring[0]; 57 + uint16_t ring[]; 58 58 } VRingAvail; 59 59 60 60 typedef struct VRingUsedElem ··· 67 67 { 68 68 uint16_t flags; 69 69 uint16_t idx; 70 - VRingUsedElem ring[0]; 70 + VRingUsedElem ring[]; 71 71 } VRingUsed; 72 72 73 73 typedef struct VRingMemoryRegionCaches {
+1 -1
hw/xen/xen_pt.h
··· 203 203 uint64_t mmio_base_addr; 204 204 MemoryRegion mmio; 205 205 void *phys_iomem_base; 206 - XenPTMSIXEntry msix_entry[0]; 206 + XenPTMSIXEntry msix_entry[]; 207 207 } XenPTMSIX; 208 208 209 209 struct XenPCIPassthroughState {
+6 -6
include/hw/acpi/acpi-defs.h
··· 518 518 struct { 519 519 uint8_t device; 520 520 uint8_t function; 521 - } path[0]; 521 + } path[]; 522 522 } QEMU_PACKED; 523 523 typedef struct AcpiDmarDeviceScope AcpiDmarDeviceScope; 524 524 ··· 530 530 uint8_t reserved; 531 531 uint16_t pci_segment; /* The PCI Segment associated with this unit */ 532 532 uint64_t address; /* Base address of remapping hardware register-set */ 533 - AcpiDmarDeviceScope scope[0]; 533 + AcpiDmarDeviceScope scope[]; 534 534 } QEMU_PACKED; 535 535 typedef struct AcpiDmarHardwareUnit AcpiDmarHardwareUnit; 536 536 ··· 541 541 uint8_t flags; 542 542 uint8_t reserved; 543 543 uint16_t pci_segment; 544 - AcpiDmarDeviceScope scope[0]; 544 + AcpiDmarDeviceScope scope[]; 545 545 } QEMU_PACKED; 546 546 typedef struct AcpiDmarRootPortATS AcpiDmarRootPortATS; 547 547 ··· 604 604 struct AcpiIortItsGroup { 605 605 ACPI_IORT_NODE_HEADER_DEF 606 606 uint32_t its_count; 607 - uint32_t identifiers[0]; 607 + uint32_t identifiers[]; 608 608 } QEMU_PACKED; 609 609 typedef struct AcpiIortItsGroup AcpiIortItsGroup; 610 610 ··· 621 621 uint32_t pri_gsiv; 622 622 uint32_t gerr_gsiv; 623 623 uint32_t sync_gsiv; 624 - AcpiIortIdMapping id_mapping_array[0]; 624 + AcpiIortIdMapping id_mapping_array[]; 625 625 } QEMU_PACKED; 626 626 typedef struct AcpiIortSmmu3 AcpiIortSmmu3; 627 627 ··· 630 630 AcpiIortMemoryAccess memory_properties; 631 631 uint32_t ats_attribute; 632 632 uint32_t pci_segment_number; 633 - AcpiIortIdMapping id_mapping_array[0]; 633 + AcpiIortIdMapping id_mapping_array[]; 634 634 } QEMU_PACKED; 635 635 typedef struct AcpiIortRC AcpiIortRC; 636 636
+1 -1
include/hw/arm/smmu-common.h
··· 85 85 86 86 typedef struct SMMUPciBus { 87 87 PCIBus *bus; 88 - SMMUDevice *pbdev[0]; /* Parent array is sparse, so dynamically alloc */ 88 + SMMUDevice *pbdev[]; /* Parent array is sparse, so dynamically alloc */ 89 89 } SMMUPciBus; 90 90 91 91 typedef struct SMMUIOTLBKey {
+2 -1
include/hw/i386/intel_iommu.h
··· 114 114 115 115 struct VTDBus { 116 116 PCIBus* bus; /* A reference to the bus to provide translation for */ 117 - VTDAddressSpace *dev_as[0]; /* A table of VTDAddressSpace objects indexed by devfn */ 117 + /* A table of VTDAddressSpace objects indexed by devfn */ 118 + VTDAddressSpace *dev_as[]; 118 119 }; 119 120 120 121 struct VTDIOTLBEntry {
+1 -1
include/hw/virtio/virtio-iommu.h
··· 41 41 42 42 typedef struct IOMMUPciBus { 43 43 PCIBus *bus; 44 - IOMMUDevice *pbdev[0]; /* Parent array is sparse, so dynamically alloc */ 44 + IOMMUDevice *pbdev[]; /* Parent array is sparse, so dynamically alloc */ 45 45 } IOMMUPciBus; 46 46 47 47 typedef struct VirtIOIOMMU {
+1 -1
include/sysemu/cryptodev.h
··· 143 143 uint8_t *dst; 144 144 uint8_t *aad_data; 145 145 uint8_t *digest_result; 146 - uint8_t data[0]; 146 + uint8_t data[]; 147 147 } CryptoDevBackendSymOpInfo; 148 148 149 149 typedef struct CryptoDevBackendClass {
+1 -1
include/tcg/tcg.h
··· 267 267 typedef struct TCGPool { 268 268 struct TCGPool *next; 269 269 int size; 270 - uint8_t data[0] __attribute__ ((aligned)); 270 + uint8_t data[] __attribute__ ((aligned)); 271 271 } TCGPool; 272 272 273 273 #define TCG_POOL_CHUNK_SIZE 32768
+1 -1
net/queue.c
··· 46 46 unsigned flags; 47 47 int size; 48 48 NetPacketSent *sent_cb; 49 - uint8_t data[0]; 49 + uint8_t data[]; 50 50 }; 51 51 52 52 struct NetQueue {
+1 -1
pc-bios/s390-ccw/bootmap.h
··· 136 136 137 137 typedef struct BootMapScript { 138 138 BootMapScriptHeader header; 139 - BootMapScriptEntry entry[0]; 139 + BootMapScriptEntry entry[]; 140 140 } __attribute__ ((packed)) BootMapScript; 141 141 142 142 /*
+1 -1
pc-bios/s390-ccw/sclp.h
··· 95 95 typedef struct WriteEventData { 96 96 SCCBHeader h; 97 97 EventBufferHeader ebh; 98 - char data[0]; 98 + char data[]; 99 99 } __attribute__((packed)) WriteEventData; 100 100 101 101 typedef struct ReadEventData {
+1 -1
tests/qtest/libqos/ahci.h
··· 351 351 typedef struct FIS { 352 352 uint8_t fis_type; 353 353 uint8_t flags; 354 - char data[0]; 354 + char data[]; 355 355 } __attribute__((__packed__)) FIS; 356 356 357 357 /**