mirror of
https://github.com/xemu-project/xemu.git
synced 2024-11-27 21:40:49 +00:00
vfio/pci: Convert all MemoryRegion to dynamic alloc and consistent functions
Match common vfio code with setup, exit, and finalize functions for BAR, quirk, and VGA management. VGA is also changed to dynamic allocation to match the other MemoryRegions. Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
This commit is contained in:
parent
db0da029a1
commit
2d82f8a3cd
@ -290,10 +290,10 @@ static void vfio_vga_probe_ati_3c3_quirk(VFIOPCIDevice *vdev)
|
||||
|
||||
memory_region_init_io(quirk->mem, OBJECT(vdev), &vfio_ati_3c3_quirk, vdev,
|
||||
"vfio-ati-3c3-quirk", 1);
|
||||
memory_region_add_subregion(&vdev->vga.region[QEMU_PCI_VGA_IO_HI].mem,
|
||||
memory_region_add_subregion(&vdev->vga->region[QEMU_PCI_VGA_IO_HI].mem,
|
||||
3 /* offset 3 bytes from 0x3c0 */, quirk->mem);
|
||||
|
||||
QLIST_INSERT_HEAD(&vdev->vga.region[QEMU_PCI_VGA_IO_HI].quirks,
|
||||
QLIST_INSERT_HEAD(&vdev->vga->region[QEMU_PCI_VGA_IO_HI].quirks,
|
||||
quirk, next);
|
||||
|
||||
trace_vfio_quirk_ati_3c3_probe(vdev->vbasedev.name);
|
||||
@ -428,7 +428,7 @@ static uint64_t vfio_nvidia_3d4_quirk_read(void *opaque,
|
||||
|
||||
quirk->state = NONE;
|
||||
|
||||
return vfio_vga_read(&vdev->vga.region[QEMU_PCI_VGA_IO_HI],
|
||||
return vfio_vga_read(&vdev->vga->region[QEMU_PCI_VGA_IO_HI],
|
||||
addr + 0x14, size);
|
||||
}
|
||||
|
||||
@ -465,7 +465,7 @@ static void vfio_nvidia_3d4_quirk_write(void *opaque, hwaddr addr,
|
||||
break;
|
||||
}
|
||||
|
||||
vfio_vga_write(&vdev->vga.region[QEMU_PCI_VGA_IO_HI],
|
||||
vfio_vga_write(&vdev->vga->region[QEMU_PCI_VGA_IO_HI],
|
||||
addr + 0x14, data, size);
|
||||
}
|
||||
|
||||
@ -481,7 +481,7 @@ static uint64_t vfio_nvidia_3d0_quirk_read(void *opaque,
|
||||
VFIONvidia3d0Quirk *quirk = opaque;
|
||||
VFIOPCIDevice *vdev = quirk->vdev;
|
||||
VFIONvidia3d0State old_state = quirk->state;
|
||||
uint64_t data = vfio_vga_read(&vdev->vga.region[QEMU_PCI_VGA_IO_HI],
|
||||
uint64_t data = vfio_vga_read(&vdev->vga->region[QEMU_PCI_VGA_IO_HI],
|
||||
addr + 0x10, size);
|
||||
|
||||
quirk->state = NONE;
|
||||
@ -523,7 +523,7 @@ static void vfio_nvidia_3d0_quirk_write(void *opaque, hwaddr addr,
|
||||
}
|
||||
}
|
||||
|
||||
vfio_vga_write(&vdev->vga.region[QEMU_PCI_VGA_IO_HI],
|
||||
vfio_vga_write(&vdev->vga->region[QEMU_PCI_VGA_IO_HI],
|
||||
addr + 0x10, data, size);
|
||||
}
|
||||
|
||||
@ -551,15 +551,15 @@ static void vfio_vga_probe_nvidia_3d0_quirk(VFIOPCIDevice *vdev)
|
||||
|
||||
memory_region_init_io(&quirk->mem[0], OBJECT(vdev), &vfio_nvidia_3d4_quirk,
|
||||
data, "vfio-nvidia-3d4-quirk", 2);
|
||||
memory_region_add_subregion(&vdev->vga.region[QEMU_PCI_VGA_IO_HI].mem,
|
||||
memory_region_add_subregion(&vdev->vga->region[QEMU_PCI_VGA_IO_HI].mem,
|
||||
0x14 /* 0x3c0 + 0x14 */, &quirk->mem[0]);
|
||||
|
||||
memory_region_init_io(&quirk->mem[1], OBJECT(vdev), &vfio_nvidia_3d0_quirk,
|
||||
data, "vfio-nvidia-3d0-quirk", 2);
|
||||
memory_region_add_subregion(&vdev->vga.region[QEMU_PCI_VGA_IO_HI].mem,
|
||||
memory_region_add_subregion(&vdev->vga->region[QEMU_PCI_VGA_IO_HI].mem,
|
||||
0x10 /* 0x3c0 + 0x10 */, &quirk->mem[1]);
|
||||
|
||||
QLIST_INSERT_HEAD(&vdev->vga.region[QEMU_PCI_VGA_IO_HI].quirks,
|
||||
QLIST_INSERT_HEAD(&vdev->vga->region[QEMU_PCI_VGA_IO_HI].quirks,
|
||||
quirk, next);
|
||||
|
||||
trace_vfio_quirk_nvidia_3d0_probe(vdev->vbasedev.name);
|
||||
@ -970,28 +970,28 @@ void vfio_vga_quirk_setup(VFIOPCIDevice *vdev)
|
||||
vfio_vga_probe_nvidia_3d0_quirk(vdev);
|
||||
}
|
||||
|
||||
void vfio_vga_quirk_teardown(VFIOPCIDevice *vdev)
|
||||
void vfio_vga_quirk_exit(VFIOPCIDevice *vdev)
|
||||
{
|
||||
VFIOQuirk *quirk;
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(vdev->vga.region); i++) {
|
||||
QLIST_FOREACH(quirk, &vdev->vga.region[i].quirks, next) {
|
||||
for (i = 0; i < ARRAY_SIZE(vdev->vga->region); i++) {
|
||||
QLIST_FOREACH(quirk, &vdev->vga->region[i].quirks, next) {
|
||||
for (j = 0; j < quirk->nr_mem; j++) {
|
||||
memory_region_del_subregion(&vdev->vga.region[i].mem,
|
||||
memory_region_del_subregion(&vdev->vga->region[i].mem,
|
||||
&quirk->mem[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void vfio_vga_quirk_free(VFIOPCIDevice *vdev)
|
||||
void vfio_vga_quirk_finalize(VFIOPCIDevice *vdev)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(vdev->vga.region); i++) {
|
||||
while (!QLIST_EMPTY(&vdev->vga.region[i].quirks)) {
|
||||
VFIOQuirk *quirk = QLIST_FIRST(&vdev->vga.region[i].quirks);
|
||||
for (i = 0; i < ARRAY_SIZE(vdev->vga->region); i++) {
|
||||
while (!QLIST_EMPTY(&vdev->vga->region[i].quirks)) {
|
||||
VFIOQuirk *quirk = QLIST_FIRST(&vdev->vga->region[i].quirks);
|
||||
QLIST_REMOVE(quirk, next);
|
||||
for (j = 0; j < quirk->nr_mem; j++) {
|
||||
object_unparent(OBJECT(&quirk->mem[j]));
|
||||
@ -1012,7 +1012,7 @@ void vfio_bar_quirk_setup(VFIOPCIDevice *vdev, int nr)
|
||||
vfio_probe_rtl8168_bar2_quirk(vdev, nr);
|
||||
}
|
||||
|
||||
void vfio_bar_quirk_teardown(VFIOPCIDevice *vdev, int nr)
|
||||
void vfio_bar_quirk_exit(VFIOPCIDevice *vdev, int nr)
|
||||
{
|
||||
VFIOBAR *bar = &vdev->bars[nr];
|
||||
VFIOQuirk *quirk;
|
||||
@ -1025,7 +1025,7 @@ void vfio_bar_quirk_teardown(VFIOPCIDevice *vdev, int nr)
|
||||
}
|
||||
}
|
||||
|
||||
void vfio_bar_quirk_free(VFIOPCIDevice *vdev, int nr)
|
||||
void vfio_bar_quirk_finalize(VFIOPCIDevice *vdev, int nr)
|
||||
{
|
||||
VFIOBAR *bar = &vdev->bars[nr];
|
||||
int i;
|
||||
|
114
hw/vfio/pci.c
114
hw/vfio/pci.c
@ -1377,42 +1377,16 @@ static void vfio_mmap_set_enabled(VFIOPCIDevice *vdev, bool enabled)
|
||||
}
|
||||
}
|
||||
|
||||
static void vfio_unregister_bar(VFIOPCIDevice *vdev, int nr)
|
||||
static void vfio_bar_setup(VFIOPCIDevice *vdev, int nr)
|
||||
{
|
||||
VFIOBAR *bar = &vdev->bars[nr];
|
||||
|
||||
if (!bar->region.size) {
|
||||
return;
|
||||
}
|
||||
|
||||
vfio_bar_quirk_teardown(vdev, nr);
|
||||
|
||||
vfio_region_exit(&bar->region);
|
||||
}
|
||||
|
||||
static void vfio_unmap_bar(VFIOPCIDevice *vdev, int nr)
|
||||
{
|
||||
VFIOBAR *bar = &vdev->bars[nr];
|
||||
|
||||
if (!bar->region.size) {
|
||||
return;
|
||||
}
|
||||
|
||||
vfio_bar_quirk_free(vdev, nr);
|
||||
|
||||
vfio_region_finalize(&bar->region);
|
||||
}
|
||||
|
||||
static void vfio_map_bar(VFIOPCIDevice *vdev, int nr)
|
||||
{
|
||||
VFIOBAR *bar = &vdev->bars[nr];
|
||||
uint64_t size = bar->region.size;
|
||||
uint32_t pci_bar;
|
||||
uint8_t type;
|
||||
int ret;
|
||||
|
||||
/* Skip both unimplemented BARs and the upper half of 64bit BARS. */
|
||||
if (!size) {
|
||||
if (!bar->region.size) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1430,72 +1404,78 @@ static void vfio_map_bar(VFIOPCIDevice *vdev, int nr)
|
||||
type = pci_bar & (bar->ioport ? ~PCI_BASE_ADDRESS_IO_MASK :
|
||||
~PCI_BASE_ADDRESS_MEM_MASK);
|
||||
|
||||
pci_register_bar(&vdev->pdev, nr, type, bar->region.mem);
|
||||
|
||||
if (vfio_region_mmap(&bar->region)) {
|
||||
error_report("Failed to mmap %s BAR %d. Performance may be slow",
|
||||
vdev->vbasedev.name, nr);
|
||||
}
|
||||
|
||||
vfio_bar_quirk_setup(vdev, nr);
|
||||
|
||||
pci_register_bar(&vdev->pdev, nr, type, bar->region.mem);
|
||||
}
|
||||
|
||||
static void vfio_map_bars(VFIOPCIDevice *vdev)
|
||||
static void vfio_bars_setup(VFIOPCIDevice *vdev)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < PCI_ROM_SLOT; i++) {
|
||||
vfio_map_bar(vdev, i);
|
||||
vfio_bar_setup(vdev, i);
|
||||
}
|
||||
|
||||
if (vdev->has_vga) {
|
||||
memory_region_init_io(&vdev->vga.region[QEMU_PCI_VGA_MEM].mem,
|
||||
if (vdev->vga) {
|
||||
memory_region_init_io(&vdev->vga->region[QEMU_PCI_VGA_MEM].mem,
|
||||
OBJECT(vdev), &vfio_vga_ops,
|
||||
&vdev->vga.region[QEMU_PCI_VGA_MEM],
|
||||
&vdev->vga->region[QEMU_PCI_VGA_MEM],
|
||||
"vfio-vga-mmio@0xa0000",
|
||||
QEMU_PCI_VGA_MEM_SIZE);
|
||||
memory_region_init_io(&vdev->vga.region[QEMU_PCI_VGA_IO_LO].mem,
|
||||
memory_region_init_io(&vdev->vga->region[QEMU_PCI_VGA_IO_LO].mem,
|
||||
OBJECT(vdev), &vfio_vga_ops,
|
||||
&vdev->vga.region[QEMU_PCI_VGA_IO_LO],
|
||||
&vdev->vga->region[QEMU_PCI_VGA_IO_LO],
|
||||
"vfio-vga-io@0x3b0",
|
||||
QEMU_PCI_VGA_IO_LO_SIZE);
|
||||
memory_region_init_io(&vdev->vga.region[QEMU_PCI_VGA_IO_HI].mem,
|
||||
memory_region_init_io(&vdev->vga->region[QEMU_PCI_VGA_IO_HI].mem,
|
||||
OBJECT(vdev), &vfio_vga_ops,
|
||||
&vdev->vga.region[QEMU_PCI_VGA_IO_HI],
|
||||
&vdev->vga->region[QEMU_PCI_VGA_IO_HI],
|
||||
"vfio-vga-io@0x3c0",
|
||||
QEMU_PCI_VGA_IO_HI_SIZE);
|
||||
|
||||
pci_register_vga(&vdev->pdev, &vdev->vga.region[QEMU_PCI_VGA_MEM].mem,
|
||||
&vdev->vga.region[QEMU_PCI_VGA_IO_LO].mem,
|
||||
&vdev->vga.region[QEMU_PCI_VGA_IO_HI].mem);
|
||||
pci_register_vga(&vdev->pdev, &vdev->vga->region[QEMU_PCI_VGA_MEM].mem,
|
||||
&vdev->vga->region[QEMU_PCI_VGA_IO_LO].mem,
|
||||
&vdev->vga->region[QEMU_PCI_VGA_IO_HI].mem);
|
||||
vfio_vga_quirk_setup(vdev);
|
||||
}
|
||||
}
|
||||
|
||||
static void vfio_unregister_bars(VFIOPCIDevice *vdev)
|
||||
static void vfio_bars_exit(VFIOPCIDevice *vdev)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < PCI_ROM_SLOT; i++) {
|
||||
vfio_unregister_bar(vdev, i);
|
||||
vfio_bar_quirk_exit(vdev, i);
|
||||
vfio_region_exit(&vdev->bars[i].region);
|
||||
}
|
||||
|
||||
if (vdev->has_vga) {
|
||||
vfio_vga_quirk_teardown(vdev);
|
||||
if (vdev->vga) {
|
||||
pci_unregister_vga(&vdev->pdev);
|
||||
vfio_vga_quirk_exit(vdev);
|
||||
}
|
||||
}
|
||||
|
||||
static void vfio_unmap_bars(VFIOPCIDevice *vdev)
|
||||
static void vfio_bars_finalize(VFIOPCIDevice *vdev)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < PCI_ROM_SLOT; i++) {
|
||||
vfio_unmap_bar(vdev, i);
|
||||
vfio_bar_quirk_finalize(vdev, i);
|
||||
vfio_region_finalize(&vdev->bars[i].region);
|
||||
}
|
||||
|
||||
if (vdev->has_vga) {
|
||||
vfio_vga_quirk_free(vdev);
|
||||
if (vdev->vga) {
|
||||
vfio_vga_quirk_finalize(vdev);
|
||||
for (i = 0; i < ARRAY_SIZE(vdev->vga->region); i++) {
|
||||
object_unparent(OBJECT(&vdev->vga->region[i].mem));
|
||||
}
|
||||
g_free(vdev->vga);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2124,24 +2104,24 @@ static int vfio_populate_device(VFIOPCIDevice *vdev)
|
||||
goto error;
|
||||
}
|
||||
|
||||
vdev->vga.fd_offset = reg_info->offset;
|
||||
vdev->vga.fd = vdev->vbasedev.fd;
|
||||
vdev->vga = g_new0(VFIOVGA, 1);
|
||||
|
||||
vdev->vga->fd_offset = reg_info->offset;
|
||||
vdev->vga->fd = vdev->vbasedev.fd;
|
||||
|
||||
g_free(reg_info);
|
||||
|
||||
vdev->vga.region[QEMU_PCI_VGA_MEM].offset = QEMU_PCI_VGA_MEM_BASE;
|
||||
vdev->vga.region[QEMU_PCI_VGA_MEM].nr = QEMU_PCI_VGA_MEM;
|
||||
QLIST_INIT(&vdev->vga.region[QEMU_PCI_VGA_MEM].quirks);
|
||||
vdev->vga->region[QEMU_PCI_VGA_MEM].offset = QEMU_PCI_VGA_MEM_BASE;
|
||||
vdev->vga->region[QEMU_PCI_VGA_MEM].nr = QEMU_PCI_VGA_MEM;
|
||||
QLIST_INIT(&vdev->vga->region[QEMU_PCI_VGA_MEM].quirks);
|
||||
|
||||
vdev->vga.region[QEMU_PCI_VGA_IO_LO].offset = QEMU_PCI_VGA_IO_LO_BASE;
|
||||
vdev->vga.region[QEMU_PCI_VGA_IO_LO].nr = QEMU_PCI_VGA_IO_LO;
|
||||
QLIST_INIT(&vdev->vga.region[QEMU_PCI_VGA_IO_LO].quirks);
|
||||
vdev->vga->region[QEMU_PCI_VGA_IO_LO].offset = QEMU_PCI_VGA_IO_LO_BASE;
|
||||
vdev->vga->region[QEMU_PCI_VGA_IO_LO].nr = QEMU_PCI_VGA_IO_LO;
|
||||
QLIST_INIT(&vdev->vga->region[QEMU_PCI_VGA_IO_LO].quirks);
|
||||
|
||||
vdev->vga.region[QEMU_PCI_VGA_IO_HI].offset = QEMU_PCI_VGA_IO_HI_BASE;
|
||||
vdev->vga.region[QEMU_PCI_VGA_IO_HI].nr = QEMU_PCI_VGA_IO_HI;
|
||||
QLIST_INIT(&vdev->vga.region[QEMU_PCI_VGA_IO_HI].quirks);
|
||||
|
||||
vdev->has_vga = true;
|
||||
vdev->vga->region[QEMU_PCI_VGA_IO_HI].offset = QEMU_PCI_VGA_IO_HI_BASE;
|
||||
vdev->vga->region[QEMU_PCI_VGA_IO_HI].nr = QEMU_PCI_VGA_IO_HI;
|
||||
QLIST_INIT(&vdev->vga->region[QEMU_PCI_VGA_IO_HI].quirks);
|
||||
}
|
||||
|
||||
irq_info.index = VFIO_PCI_ERR_IRQ_INDEX;
|
||||
@ -2528,7 +2508,7 @@ static int vfio_initfn(PCIDevice *pdev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
vfio_map_bars(vdev);
|
||||
vfio_bars_setup(vdev);
|
||||
|
||||
ret = vfio_add_capabilities(vdev);
|
||||
if (ret) {
|
||||
@ -2565,7 +2545,7 @@ static int vfio_initfn(PCIDevice *pdev)
|
||||
out_teardown:
|
||||
pci_device_set_intx_routing_notifier(&vdev->pdev, NULL);
|
||||
vfio_teardown_msi(vdev);
|
||||
vfio_unregister_bars(vdev);
|
||||
vfio_bars_exit(vdev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -2575,7 +2555,7 @@ static void vfio_instance_finalize(Object *obj)
|
||||
VFIOPCIDevice *vdev = DO_UPCAST(VFIOPCIDevice, pdev, pci_dev);
|
||||
VFIOGroup *group = vdev->vbasedev.group;
|
||||
|
||||
vfio_unmap_bars(vdev);
|
||||
vfio_bars_finalize(vdev);
|
||||
g_free(vdev->emulated_config_bits);
|
||||
g_free(vdev->rom);
|
||||
vfio_put_device(vdev);
|
||||
@ -2594,7 +2574,7 @@ static void vfio_exitfn(PCIDevice *pdev)
|
||||
timer_free(vdev->intx.mmap_timer);
|
||||
}
|
||||
vfio_teardown_msi(vdev);
|
||||
vfio_unregister_bars(vdev);
|
||||
vfio_bars_exit(vdev);
|
||||
}
|
||||
|
||||
static void vfio_pci_reset(DeviceState *dev)
|
||||
|
@ -114,7 +114,7 @@ typedef struct VFIOPCIDevice {
|
||||
int nr_vectors; /* Number of MSI/MSIX vectors currently in use */
|
||||
int interrupt; /* Current interrupt type */
|
||||
VFIOBAR bars[PCI_NUM_REGIONS - 1]; /* No ROM */
|
||||
VFIOVGA vga; /* 0xa0000, 0x3b0, 0x3c0 */
|
||||
VFIOVGA *vga; /* 0xa0000, 0x3b0, 0x3c0 */
|
||||
PCIHostDeviceAddress host;
|
||||
EventNotifier err_notifier;
|
||||
EventNotifier req_notifier;
|
||||
@ -150,11 +150,11 @@ void vfio_vga_write(void *opaque, hwaddr addr, uint64_t data, unsigned size);
|
||||
|
||||
bool vfio_blacklist_opt_rom(VFIOPCIDevice *vdev);
|
||||
void vfio_vga_quirk_setup(VFIOPCIDevice *vdev);
|
||||
void vfio_vga_quirk_teardown(VFIOPCIDevice *vdev);
|
||||
void vfio_vga_quirk_free(VFIOPCIDevice *vdev);
|
||||
void vfio_vga_quirk_exit(VFIOPCIDevice *vdev);
|
||||
void vfio_vga_quirk_finalize(VFIOPCIDevice *vdev);
|
||||
void vfio_bar_quirk_setup(VFIOPCIDevice *vdev, int nr);
|
||||
void vfio_bar_quirk_teardown(VFIOPCIDevice *vdev, int nr);
|
||||
void vfio_bar_quirk_free(VFIOPCIDevice *vdev, int nr);
|
||||
void vfio_bar_quirk_exit(VFIOPCIDevice *vdev, int nr);
|
||||
void vfio_bar_quirk_finalize(VFIOPCIDevice *vdev, int nr);
|
||||
void vfio_setup_resetfn_quirk(VFIOPCIDevice *vdev);
|
||||
|
||||
#endif /* HW_VFIO_VFIO_PCI_H */
|
||||
|
Loading…
Reference in New Issue
Block a user