Loading hw/vfio/pci-quirks.c +0 −155 Original line number Diff line number Diff line Loading @@ -247,161 +247,6 @@ static bool vfio_range_contained(uint64_t first1, uint64_t len1, return (first1 >= first2 && first1 + len1 <= first2 + len2); } static bool vfio_flags_enabled(uint8_t flags, uint8_t mask) { return (mask && (flags & mask) == mask); } static uint64_t vfio_generic_window_quirk_read(void *opaque, hwaddr addr, unsigned size) { VFIOLegacyQuirk *quirk = opaque; VFIOPCIDevice *vdev = quirk->vdev; uint64_t data; if (vfio_flags_enabled(quirk->data.flags, quirk->data.read_flags) && ranges_overlap(addr, size, quirk->data.data_offset, quirk->data.data_size)) { hwaddr offset = addr - quirk->data.data_offset; if (!vfio_range_contained(addr, size, quirk->data.data_offset, quirk->data.data_size)) { hw_error("%s: window data read not fully contained: %s", __func__, memory_region_name(quirk->mem)); } data = vfio_pci_read_config(&vdev->pdev, quirk->data.address_val + offset, size); trace_vfio_generic_window_quirk_read(memory_region_name(quirk->mem), vdev->vbasedev.name, quirk->data.bar, addr, size, data); } else { data = vfio_region_read(&vdev->bars[quirk->data.bar].region, addr + quirk->data.base_offset, size); } return data; } static void vfio_generic_window_quirk_write(void *opaque, hwaddr addr, uint64_t data, unsigned size) { VFIOLegacyQuirk *quirk = opaque; VFIOPCIDevice *vdev = quirk->vdev; if (ranges_overlap(addr, size, quirk->data.address_offset, quirk->data.address_size)) { if (addr != quirk->data.address_offset) { hw_error("%s: offset write into address window: %s", __func__, memory_region_name(quirk->mem)); } if ((data & ~quirk->data.address_mask) == quirk->data.address_match) { quirk->data.flags |= quirk->data.write_flags | quirk->data.read_flags; quirk->data.address_val = data & quirk->data.address_mask; } else { quirk->data.flags &= ~(quirk->data.write_flags | quirk->data.read_flags); } } if (vfio_flags_enabled(quirk->data.flags, quirk->data.write_flags) && ranges_overlap(addr, size, quirk->data.data_offset, quirk->data.data_size)) { hwaddr offset = addr - quirk->data.data_offset; if (!vfio_range_contained(addr, size, quirk->data.data_offset, quirk->data.data_size)) { hw_error("%s: window data write not fully contained: %s", __func__, memory_region_name(quirk->mem)); } vfio_pci_write_config(&vdev->pdev, quirk->data.address_val + offset, data, size); trace_vfio_generic_window_quirk_write(memory_region_name(quirk->mem), vdev->vbasedev.name, quirk->data.bar, addr, data, size); return; } vfio_region_write(&vdev->bars[quirk->data.bar].region, addr + quirk->data.base_offset, data, size); } static const MemoryRegionOps vfio_generic_window_quirk = { .read = vfio_generic_window_quirk_read, .write = vfio_generic_window_quirk_write, .endianness = DEVICE_LITTLE_ENDIAN, }; static uint64_t vfio_generic_quirk_read(void *opaque, hwaddr addr, unsigned size) { VFIOLegacyQuirk *quirk = opaque; VFIOPCIDevice *vdev = quirk->vdev; hwaddr base = quirk->data.address_match & TARGET_PAGE_MASK; hwaddr offset = quirk->data.address_match & ~TARGET_PAGE_MASK; uint64_t data; if (vfio_flags_enabled(quirk->data.flags, quirk->data.read_flags) && ranges_overlap(addr, size, offset, quirk->data.address_mask + 1)) { if (!vfio_range_contained(addr, size, offset, quirk->data.address_mask + 1)) { hw_error("%s: read not fully contained: %s", __func__, memory_region_name(quirk->mem)); } data = vfio_pci_read_config(&vdev->pdev, addr - offset, size); trace_vfio_generic_quirk_read(memory_region_name(quirk->mem), vdev->vbasedev.name, quirk->data.bar, addr + base, size, data); } else { data = vfio_region_read(&vdev->bars[quirk->data.bar].region, addr + base, size); } return data; } static void vfio_generic_quirk_write(void *opaque, hwaddr addr, uint64_t data, unsigned size) { VFIOLegacyQuirk *quirk = opaque; VFIOPCIDevice *vdev = quirk->vdev; hwaddr base = quirk->data.address_match & TARGET_PAGE_MASK; hwaddr offset = quirk->data.address_match & ~TARGET_PAGE_MASK; if (vfio_flags_enabled(quirk->data.flags, quirk->data.write_flags) && ranges_overlap(addr, size, offset, quirk->data.address_mask + 1)) { if (!vfio_range_contained(addr, size, offset, quirk->data.address_mask + 1)) { hw_error("%s: write not fully contained: %s", __func__, memory_region_name(quirk->mem)); } vfio_pci_write_config(&vdev->pdev, addr - offset, data, size); trace_vfio_generic_quirk_write(memory_region_name(quirk->mem), vdev->vbasedev.name, quirk->data.bar, addr + base, data, size); } else { vfio_region_write(&vdev->bars[quirk->data.bar].region, addr + base, data, size); } } static const MemoryRegionOps vfio_generic_quirk = { .read = vfio_generic_quirk_read, .write = vfio_generic_quirk_write, .endianness = DEVICE_LITTLE_ENDIAN, }; #define PCI_VENDOR_ID_ATI 0x1002 /* Loading hw/vfio/pci.h +0 −22 Original line number Diff line number Diff line Loading @@ -22,28 +22,6 @@ struct VFIOPCIDevice; typedef struct VFIOLegacyQuirk { struct VFIOPCIDevice *vdev; MemoryRegion *mem; struct { uint32_t base_offset:TARGET_PAGE_BITS; uint32_t address_offset:TARGET_PAGE_BITS; uint32_t address_size:3; uint32_t bar:3; uint32_t address_match; uint32_t address_mask; uint32_t address_val:TARGET_PAGE_BITS; uint32_t data_offset:TARGET_PAGE_BITS; uint32_t data_size:3; uint8_t flags; uint8_t read_flags; uint8_t write_flags; } data; } VFIOLegacyQuirk; typedef struct VFIOQuirk { QLIST_ENTRY(VFIOQuirk) next; void *data; Loading trace-events +0 −9 Original line number Diff line number Diff line Loading @@ -1542,15 +1542,6 @@ vfio_rom_read(const char *name, uint64_t addr, int size, uint64_t data) " (%s, 0 vfio_pci_size_rom(const char *name, int size) "%s ROM size 0x%x" vfio_vga_write(uint64_t addr, uint64_t data, int size) " (0x%"PRIx64", 0x%"PRIx64", %d)" vfio_vga_read(uint64_t addr, int size, uint64_t data) " (0x%"PRIx64", %d) = 0x%"PRIx64 # remove ) = vfio_generic_window_quirk_read(const char * region_name, const char *name, int index, uint64_t addr, int size, uint64_t data) "%s read(%s:BAR%d+0x%"PRIx64", %d = 0x%"PRIx64 ## remove ) vfio_generic_window_quirk_write(const char * region_name, const char *name, int index, uint64_t addr, uint64_t data, int size) "%s write(%s:BAR%d+0x%"PRIx64", 0x%"PRIx64", %d" # remove ) = vfio_generic_quirk_read(const char * region_name, const char *name, int index, uint64_t addr, int size, uint64_t data) "%s read(%s:BAR%d+0x%"PRIx64", %d = 0x%"PRIx64 # remove ) vfio_generic_quirk_write(const char * region_name, const char *name, int index, uint64_t addr, uint64_t data, int size) "%s write(%s:BAR%d+0x%"PRIx64", 0x%"PRIx64", %d" #issue with ) vfio_pci_read_config(const char *name, int addr, int len, int val) " (%s, @0x%x, len=0x%x) %x" vfio_pci_write_config(const char *name, int addr, int val, int len) " (%s, @0x%x, 0x%x, len=0x%x)" vfio_msi_setup(const char *name, int pos) "%s PCI MSI CAP @0x%x" Loading Loading
hw/vfio/pci-quirks.c +0 −155 Original line number Diff line number Diff line Loading @@ -247,161 +247,6 @@ static bool vfio_range_contained(uint64_t first1, uint64_t len1, return (first1 >= first2 && first1 + len1 <= first2 + len2); } static bool vfio_flags_enabled(uint8_t flags, uint8_t mask) { return (mask && (flags & mask) == mask); } static uint64_t vfio_generic_window_quirk_read(void *opaque, hwaddr addr, unsigned size) { VFIOLegacyQuirk *quirk = opaque; VFIOPCIDevice *vdev = quirk->vdev; uint64_t data; if (vfio_flags_enabled(quirk->data.flags, quirk->data.read_flags) && ranges_overlap(addr, size, quirk->data.data_offset, quirk->data.data_size)) { hwaddr offset = addr - quirk->data.data_offset; if (!vfio_range_contained(addr, size, quirk->data.data_offset, quirk->data.data_size)) { hw_error("%s: window data read not fully contained: %s", __func__, memory_region_name(quirk->mem)); } data = vfio_pci_read_config(&vdev->pdev, quirk->data.address_val + offset, size); trace_vfio_generic_window_quirk_read(memory_region_name(quirk->mem), vdev->vbasedev.name, quirk->data.bar, addr, size, data); } else { data = vfio_region_read(&vdev->bars[quirk->data.bar].region, addr + quirk->data.base_offset, size); } return data; } static void vfio_generic_window_quirk_write(void *opaque, hwaddr addr, uint64_t data, unsigned size) { VFIOLegacyQuirk *quirk = opaque; VFIOPCIDevice *vdev = quirk->vdev; if (ranges_overlap(addr, size, quirk->data.address_offset, quirk->data.address_size)) { if (addr != quirk->data.address_offset) { hw_error("%s: offset write into address window: %s", __func__, memory_region_name(quirk->mem)); } if ((data & ~quirk->data.address_mask) == quirk->data.address_match) { quirk->data.flags |= quirk->data.write_flags | quirk->data.read_flags; quirk->data.address_val = data & quirk->data.address_mask; } else { quirk->data.flags &= ~(quirk->data.write_flags | quirk->data.read_flags); } } if (vfio_flags_enabled(quirk->data.flags, quirk->data.write_flags) && ranges_overlap(addr, size, quirk->data.data_offset, quirk->data.data_size)) { hwaddr offset = addr - quirk->data.data_offset; if (!vfio_range_contained(addr, size, quirk->data.data_offset, quirk->data.data_size)) { hw_error("%s: window data write not fully contained: %s", __func__, memory_region_name(quirk->mem)); } vfio_pci_write_config(&vdev->pdev, quirk->data.address_val + offset, data, size); trace_vfio_generic_window_quirk_write(memory_region_name(quirk->mem), vdev->vbasedev.name, quirk->data.bar, addr, data, size); return; } vfio_region_write(&vdev->bars[quirk->data.bar].region, addr + quirk->data.base_offset, data, size); } static const MemoryRegionOps vfio_generic_window_quirk = { .read = vfio_generic_window_quirk_read, .write = vfio_generic_window_quirk_write, .endianness = DEVICE_LITTLE_ENDIAN, }; static uint64_t vfio_generic_quirk_read(void *opaque, hwaddr addr, unsigned size) { VFIOLegacyQuirk *quirk = opaque; VFIOPCIDevice *vdev = quirk->vdev; hwaddr base = quirk->data.address_match & TARGET_PAGE_MASK; hwaddr offset = quirk->data.address_match & ~TARGET_PAGE_MASK; uint64_t data; if (vfio_flags_enabled(quirk->data.flags, quirk->data.read_flags) && ranges_overlap(addr, size, offset, quirk->data.address_mask + 1)) { if (!vfio_range_contained(addr, size, offset, quirk->data.address_mask + 1)) { hw_error("%s: read not fully contained: %s", __func__, memory_region_name(quirk->mem)); } data = vfio_pci_read_config(&vdev->pdev, addr - offset, size); trace_vfio_generic_quirk_read(memory_region_name(quirk->mem), vdev->vbasedev.name, quirk->data.bar, addr + base, size, data); } else { data = vfio_region_read(&vdev->bars[quirk->data.bar].region, addr + base, size); } return data; } static void vfio_generic_quirk_write(void *opaque, hwaddr addr, uint64_t data, unsigned size) { VFIOLegacyQuirk *quirk = opaque; VFIOPCIDevice *vdev = quirk->vdev; hwaddr base = quirk->data.address_match & TARGET_PAGE_MASK; hwaddr offset = quirk->data.address_match & ~TARGET_PAGE_MASK; if (vfio_flags_enabled(quirk->data.flags, quirk->data.write_flags) && ranges_overlap(addr, size, offset, quirk->data.address_mask + 1)) { if (!vfio_range_contained(addr, size, offset, quirk->data.address_mask + 1)) { hw_error("%s: write not fully contained: %s", __func__, memory_region_name(quirk->mem)); } vfio_pci_write_config(&vdev->pdev, addr - offset, data, size); trace_vfio_generic_quirk_write(memory_region_name(quirk->mem), vdev->vbasedev.name, quirk->data.bar, addr + base, data, size); } else { vfio_region_write(&vdev->bars[quirk->data.bar].region, addr + base, data, size); } } static const MemoryRegionOps vfio_generic_quirk = { .read = vfio_generic_quirk_read, .write = vfio_generic_quirk_write, .endianness = DEVICE_LITTLE_ENDIAN, }; #define PCI_VENDOR_ID_ATI 0x1002 /* Loading
hw/vfio/pci.h +0 −22 Original line number Diff line number Diff line Loading @@ -22,28 +22,6 @@ struct VFIOPCIDevice; typedef struct VFIOLegacyQuirk { struct VFIOPCIDevice *vdev; MemoryRegion *mem; struct { uint32_t base_offset:TARGET_PAGE_BITS; uint32_t address_offset:TARGET_PAGE_BITS; uint32_t address_size:3; uint32_t bar:3; uint32_t address_match; uint32_t address_mask; uint32_t address_val:TARGET_PAGE_BITS; uint32_t data_offset:TARGET_PAGE_BITS; uint32_t data_size:3; uint8_t flags; uint8_t read_flags; uint8_t write_flags; } data; } VFIOLegacyQuirk; typedef struct VFIOQuirk { QLIST_ENTRY(VFIOQuirk) next; void *data; Loading
trace-events +0 −9 Original line number Diff line number Diff line Loading @@ -1542,15 +1542,6 @@ vfio_rom_read(const char *name, uint64_t addr, int size, uint64_t data) " (%s, 0 vfio_pci_size_rom(const char *name, int size) "%s ROM size 0x%x" vfio_vga_write(uint64_t addr, uint64_t data, int size) " (0x%"PRIx64", 0x%"PRIx64", %d)" vfio_vga_read(uint64_t addr, int size, uint64_t data) " (0x%"PRIx64", %d) = 0x%"PRIx64 # remove ) = vfio_generic_window_quirk_read(const char * region_name, const char *name, int index, uint64_t addr, int size, uint64_t data) "%s read(%s:BAR%d+0x%"PRIx64", %d = 0x%"PRIx64 ## remove ) vfio_generic_window_quirk_write(const char * region_name, const char *name, int index, uint64_t addr, uint64_t data, int size) "%s write(%s:BAR%d+0x%"PRIx64", 0x%"PRIx64", %d" # remove ) = vfio_generic_quirk_read(const char * region_name, const char *name, int index, uint64_t addr, int size, uint64_t data) "%s read(%s:BAR%d+0x%"PRIx64", %d = 0x%"PRIx64 # remove ) vfio_generic_quirk_write(const char * region_name, const char *name, int index, uint64_t addr, uint64_t data, int size) "%s write(%s:BAR%d+0x%"PRIx64", 0x%"PRIx64", %d" #issue with ) vfio_pci_read_config(const char *name, int addr, int len, int val) " (%s, @0x%x, len=0x%x) %x" vfio_pci_write_config(const char *name, int addr, int val, int len) " (%s, @0x%x, 0x%x, len=0x%x)" vfio_msi_setup(const char *name, int pos) "%s PCI MSI CAP @0x%x" Loading