diff options
-rw-r--r-- | exec.c | 10 | ||||
-rw-r--r-- | hw/misc/ivshmem.c | 9 | ||||
-rw-r--r-- | include/exec/ram_addr.h | 1 |
3 files changed, 18 insertions, 2 deletions
@@ -1757,6 +1757,16 @@ int qemu_get_ram_fd(ram_addr_t addr) return fd; } +void qemu_set_ram_fd(ram_addr_t addr, int fd) +{ + RAMBlock *block; + + rcu_read_lock(); + block = qemu_get_ram_block(addr); + block->fd = fd; + rcu_read_unlock(); +} + void *qemu_get_ram_block_host_ptr(ram_addr_t addr) { RAMBlock *block; diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c index f73f0c2b17..df585de10f 100644 --- a/hw/misc/ivshmem.c +++ b/hw/misc/ivshmem.c @@ -29,6 +29,7 @@ #include "sysemu/char.h" #include "sysemu/hostmem.h" #include "qapi/visitor.h" +#include "exec/ram_addr.h" #include "hw/misc/ivshmem.h" @@ -422,6 +423,7 @@ static int create_shared_memory_BAR(IVShmemState *s, int fd, uint8_t attr, memory_region_init_ram_ptr(&s->ivshmem, OBJECT(s), "ivshmem.bar2", s->ivshmem_size, ptr); + qemu_set_ram_fd(s->ivshmem.ram_addr, fd); vmstate_register_ram(&s->ivshmem, DEVICE(s)); memory_region_add_subregion(&s->bar, 0, &s->ivshmem); @@ -682,6 +684,7 @@ static void ivshmem_read(void *opaque, const uint8_t *buf, int size) } memory_region_init_ram_ptr(&s->ivshmem, OBJECT(s), "ivshmem.bar2", s->ivshmem_size, map_ptr); + qemu_set_ram_fd(s->ivshmem.ram_addr, incoming_fd); vmstate_register_ram(&s->ivshmem, DEVICE(s)); IVSHMEM_DPRINTF("guest h/w addr = %p, size = %" PRIu64 "\n", @@ -689,7 +692,6 @@ static void ivshmem_read(void *opaque, const uint8_t *buf, int size) memory_region_add_subregion(&s->bar, 0, &s->ivshmem); - close(incoming_fd); return; } @@ -991,7 +993,6 @@ static void pci_ivshmem_realize(PCIDevice *dev, Error **errp) } create_shared_memory_BAR(s, fd, attr, errp); - close(fd); } } @@ -1010,11 +1011,15 @@ static void pci_ivshmem_exit(PCIDevice *dev) if (memory_region_is_mapped(&s->ivshmem)) { if (!s->hostmem) { void *addr = memory_region_get_ram_ptr(&s->ivshmem); + int fd; if (munmap(addr, s->ivshmem_size) == -1) { error_report("Failed to munmap shared memory %s", strerror(errno)); } + + if ((fd = qemu_get_ram_fd(s->ivshmem.ram_addr)) != -1) + close(fd); } vmstate_unregister_ram(&s->ivshmem, DEVICE(dev)); diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h index ba4c04d202..ef1489da77 100644 --- a/include/exec/ram_addr.h +++ b/include/exec/ram_addr.h @@ -72,6 +72,7 @@ ram_addr_t qemu_ram_alloc_resizeable(ram_addr_t size, ram_addr_t max_size, void *host), MemoryRegion *mr, Error **errp); int qemu_get_ram_fd(ram_addr_t addr); +void qemu_set_ram_fd(ram_addr_t addr, int fd); void *qemu_get_ram_block_host_ptr(ram_addr_t addr); void qemu_ram_free(ram_addr_t addr); |