ivshmem: convert to memory API
excluding msix. Reviewed-by: Richard Henderson <rth@twiddle.net> Reviewed-by: Anthony Liguori <aliguori@us.ibm.com> Signed-off-by: Avi Kivity <avi@redhat.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
		
							parent
							
								
									a9deb8c69a
								
							
						
					
					
						commit
						cb06608e17
					
				
							
								
								
									
										148
									
								
								hw/ivshmem.c
									
									
									
									
									
								
							
							
						
						
									
										148
									
								
								hw/ivshmem.c
									
									
									
									
									
								
							| @ -56,11 +56,15 @@ typedef struct IVShmemState { | ||||
| 
 | ||||
|     CharDriverState **eventfd_chr; | ||||
|     CharDriverState *server_chr; | ||||
|     int ivshmem_mmio_io_addr; | ||||
|     MemoryRegion ivshmem_mmio; | ||||
| 
 | ||||
|     pcibus_t mmio_addr; | ||||
|     pcibus_t shm_pci_addr; | ||||
|     uint64_t ivshmem_offset; | ||||
|     /* We might need to register the BAR before we actually have the memory.
 | ||||
|      * So prepare a container MemoryRegion for the BAR immediately and | ||||
|      * add a subregion when we have the memory. | ||||
|      */ | ||||
|     MemoryRegion bar; | ||||
|     MemoryRegion ivshmem; | ||||
|     uint64_t ivshmem_size; /* size of shared memory region */ | ||||
|     int shm_fd; /* shared memory file descriptor */ | ||||
| 
 | ||||
| @ -96,23 +100,6 @@ static inline bool is_power_of_two(uint64_t x) { | ||||
|     return (x & (x - 1)) == 0; | ||||
| } | ||||
| 
 | ||||
| static void ivshmem_map(PCIDevice *pci_dev, int region_num, | ||||
|                     pcibus_t addr, pcibus_t size, int type) | ||||
| { | ||||
|     IVShmemState *s = DO_UPCAST(IVShmemState, dev, pci_dev); | ||||
| 
 | ||||
|     s->shm_pci_addr = addr; | ||||
| 
 | ||||
|     if (s->ivshmem_offset > 0) { | ||||
|         cpu_register_physical_memory(s->shm_pci_addr, s->ivshmem_size, | ||||
|                                                             s->ivshmem_offset); | ||||
|     } | ||||
| 
 | ||||
|     IVSHMEM_DPRINTF("guest pci addr = %" FMT_PCIBUS ", guest h/w addr = %" | ||||
|         PRIu64 ", size = %" FMT_PCIBUS "\n", addr, s->ivshmem_offset, size); | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| /* accessing registers - based on rtl8139 */ | ||||
| static void ivshmem_update_irq(IVShmemState *s, int val) | ||||
| { | ||||
| @ -168,15 +155,8 @@ static uint32_t ivshmem_IntrStatus_read(IVShmemState *s) | ||||
|     return ret; | ||||
| } | ||||
| 
 | ||||
| static void ivshmem_io_writew(void *opaque, target_phys_addr_t addr, | ||||
|                                                             uint32_t val) | ||||
| { | ||||
| 
 | ||||
|     IVSHMEM_DPRINTF("We shouldn't be writing words\n"); | ||||
| } | ||||
| 
 | ||||
| static void ivshmem_io_writel(void *opaque, target_phys_addr_t addr, | ||||
|                                                             uint32_t val) | ||||
| static void ivshmem_io_write(void *opaque, target_phys_addr_t addr, | ||||
|                              uint64_t val, unsigned size) | ||||
| { | ||||
|     IVShmemState *s = opaque; | ||||
| 
 | ||||
| @ -219,20 +199,8 @@ static void ivshmem_io_writel(void *opaque, target_phys_addr_t addr, | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| static void ivshmem_io_writeb(void *opaque, target_phys_addr_t addr, | ||||
|                                                                 uint32_t val) | ||||
| { | ||||
|     IVSHMEM_DPRINTF("We shouldn't be writing bytes\n"); | ||||
| } | ||||
| 
 | ||||
| static uint32_t ivshmem_io_readw(void *opaque, target_phys_addr_t addr) | ||||
| { | ||||
| 
 | ||||
|     IVSHMEM_DPRINTF("We shouldn't be reading words\n"); | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| static uint32_t ivshmem_io_readl(void *opaque, target_phys_addr_t addr) | ||||
| static uint64_t ivshmem_io_read(void *opaque, target_phys_addr_t addr, | ||||
|                                 unsigned size) | ||||
| { | ||||
| 
 | ||||
|     IVShmemState *s = opaque; | ||||
| @ -265,23 +233,14 @@ static uint32_t ivshmem_io_readl(void *opaque, target_phys_addr_t addr) | ||||
|     return ret; | ||||
| } | ||||
| 
 | ||||
| static uint32_t ivshmem_io_readb(void *opaque, target_phys_addr_t addr) | ||||
| { | ||||
|     IVSHMEM_DPRINTF("We shouldn't be reading bytes\n"); | ||||
| 
 | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| static CPUReadMemoryFunc * const ivshmem_mmio_read[3] = { | ||||
|     ivshmem_io_readb, | ||||
|     ivshmem_io_readw, | ||||
|     ivshmem_io_readl, | ||||
| }; | ||||
| 
 | ||||
| static CPUWriteMemoryFunc * const ivshmem_mmio_write[3] = { | ||||
|     ivshmem_io_writeb, | ||||
|     ivshmem_io_writew, | ||||
|     ivshmem_io_writel, | ||||
| static const MemoryRegionOps ivshmem_mmio_ops = { | ||||
|     .read = ivshmem_io_read, | ||||
|     .write = ivshmem_io_write, | ||||
|     .endianness = DEVICE_NATIVE_ENDIAN, | ||||
|     .impl = { | ||||
|         .min_access_size = 4, | ||||
|         .max_access_size = 4, | ||||
|     }, | ||||
| }; | ||||
| 
 | ||||
| static void ivshmem_receive(void *opaque, const uint8_t *buf, int size) | ||||
| @ -371,12 +330,12 @@ static void create_shared_memory_BAR(IVShmemState *s, int fd) { | ||||
| 
 | ||||
|     ptr = mmap(0, s->ivshmem_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); | ||||
| 
 | ||||
|     s->ivshmem_offset = qemu_ram_alloc_from_ptr(&s->dev.qdev, "ivshmem.bar2", | ||||
|                                                         s->ivshmem_size, ptr); | ||||
|     memory_region_init_ram_ptr(&s->ivshmem, &s->dev.qdev, "ivshmem.bar2", | ||||
|                                s->ivshmem_size, ptr); | ||||
|     memory_region_add_subregion(&s->bar, 0, &s->ivshmem); | ||||
| 
 | ||||
|     /* region for shared memory */ | ||||
|     pci_register_bar(&s->dev, 2, s->ivshmem_size, | ||||
|                                 PCI_BASE_ADDRESS_SPACE_MEMORY, ivshmem_map); | ||||
|     pci_register_bar_region(&s->dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->bar); | ||||
| } | ||||
| 
 | ||||
| static void close_guest_eventfds(IVShmemState *s, int posn) | ||||
| @ -401,8 +360,12 @@ static void setup_ioeventfds(IVShmemState *s) { | ||||
| 
 | ||||
|     for (i = 0; i <= s->max_peer; i++) { | ||||
|         for (j = 0; j < s->peers[i].nb_eventfds; j++) { | ||||
|             kvm_set_ioeventfd_mmio_long(s->peers[i].eventfds[j], | ||||
|                     s->mmio_addr + DOORBELL, (i << 16) | j, 1); | ||||
|             memory_region_add_eventfd(&s->ivshmem_mmio, | ||||
|                                       DOORBELL, | ||||
|                                       4, | ||||
|                                       true, | ||||
|                                       (i << 16) | j, | ||||
|                                       s->peers[i].eventfds[j]); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -483,18 +446,13 @@ static void ivshmem_read(void *opaque, const uint8_t * buf, int flags) | ||||
|         /* mmap the region and map into the BAR2 */ | ||||
|         map_ptr = mmap(0, s->ivshmem_size, PROT_READ|PROT_WRITE, MAP_SHARED, | ||||
|                                                             incoming_fd, 0); | ||||
|         s->ivshmem_offset = qemu_ram_alloc_from_ptr(&s->dev.qdev, | ||||
|                                     "ivshmem.bar2", s->ivshmem_size, map_ptr); | ||||
|         memory_region_init_ram_ptr(&s->ivshmem, &s->dev.qdev, | ||||
|                                    "ivshmem.bar2", s->ivshmem_size, map_ptr); | ||||
| 
 | ||||
|         IVSHMEM_DPRINTF("guest pci addr = %" FMT_PCIBUS ", guest h/w addr = %" | ||||
|                          PRIu64 ", size = %" PRIu64 "\n", s->shm_pci_addr, | ||||
|         IVSHMEM_DPRINTF("guest h/w addr = %" PRIu64 ", size = %" PRIu64 "\n", | ||||
|                          s->ivshmem_offset, s->ivshmem_size); | ||||
| 
 | ||||
|         if (s->shm_pci_addr > 0) { | ||||
|             /* map memory into BAR2 */ | ||||
|             cpu_register_physical_memory(s->shm_pci_addr, s->ivshmem_size, | ||||
|                                                             s->ivshmem_offset); | ||||
|         } | ||||
|         memory_region_add_subregion(&s->bar, 0, &s->ivshmem); | ||||
| 
 | ||||
|         /* only store the fd if it is successfully mapped */ | ||||
|         s->shm_fd = incoming_fd; | ||||
| @ -549,20 +507,6 @@ static void ivshmem_reset(DeviceState *d) | ||||
|     return; | ||||
| } | ||||
| 
 | ||||
| static void ivshmem_mmio_map(PCIDevice *pci_dev, int region_num, | ||||
|                        pcibus_t addr, pcibus_t size, int type) | ||||
| { | ||||
|     IVShmemState *s = DO_UPCAST(IVShmemState, dev, pci_dev); | ||||
| 
 | ||||
|     s->mmio_addr = addr; | ||||
|     cpu_register_physical_memory(addr + 0, IVSHMEM_REG_BAR_SIZE, | ||||
|                                                 s->ivshmem_mmio_io_addr); | ||||
| 
 | ||||
|     if (ivshmem_has_feature(s, IVSHMEM_IOEVENTFD)) { | ||||
|         setup_ioeventfds(s); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| static uint64_t ivshmem_get_size(IVShmemState * s) { | ||||
| 
 | ||||
|     uint64_t value; | ||||
| @ -710,15 +654,20 @@ static int pci_ivshmem_init(PCIDevice *dev) | ||||
| 
 | ||||
|     pci_config_set_interrupt_pin(pci_conf, 1); | ||||
| 
 | ||||
|     s->shm_pci_addr = 0; | ||||
|     s->ivshmem_offset = 0; | ||||
|     s->shm_fd = 0; | ||||
| 
 | ||||
|     s->ivshmem_mmio_io_addr = cpu_register_io_memory(ivshmem_mmio_read, | ||||
|                                     ivshmem_mmio_write, s, DEVICE_NATIVE_ENDIAN); | ||||
|     memory_region_init_io(&s->ivshmem_mmio, &ivshmem_mmio_ops, s, | ||||
|                           "ivshmem-mmio", IVSHMEM_REG_BAR_SIZE); | ||||
| 
 | ||||
|     if (ivshmem_has_feature(s, IVSHMEM_IOEVENTFD)) { | ||||
|         setup_ioeventfds(s); | ||||
|     } | ||||
| 
 | ||||
|     /* region for registers*/ | ||||
|     pci_register_bar(&s->dev, 0, IVSHMEM_REG_BAR_SIZE, | ||||
|                            PCI_BASE_ADDRESS_SPACE_MEMORY, ivshmem_mmio_map); | ||||
|     pci_register_bar_region(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, | ||||
|                             &s->ivshmem_mmio); | ||||
| 
 | ||||
|     memory_region_init(&s->bar, "ivshmem-bar2-container", s->ivshmem_size); | ||||
| 
 | ||||
|     if ((s->server_chr != NULL) && | ||||
|                         (strncmp(s->server_chr->filename, "unix:", 5) == 0)) { | ||||
| @ -744,8 +693,8 @@ static int pci_ivshmem_init(PCIDevice *dev) | ||||
|         /* allocate/initialize space for interrupt handling */ | ||||
|         s->peers = qemu_mallocz(s->nb_peers * sizeof(Peer)); | ||||
| 
 | ||||
|         pci_register_bar(&s->dev, 2, s->ivshmem_size, | ||||
|                                 PCI_BASE_ADDRESS_SPACE_MEMORY, ivshmem_map); | ||||
|         pci_register_bar_region(&s->dev, 2, | ||||
|                                 PCI_BASE_ADDRESS_SPACE_MEMORY, &s->ivshmem); | ||||
| 
 | ||||
|         s->eventfd_chr = qemu_mallocz(s->vectors * sizeof(CharDriverState *)); | ||||
| 
 | ||||
| @ -792,7 +741,10 @@ static int pci_ivshmem_uninit(PCIDevice *dev) | ||||
| { | ||||
|     IVShmemState *s = DO_UPCAST(IVShmemState, dev, dev); | ||||
| 
 | ||||
|     cpu_unregister_io_memory(s->ivshmem_mmio_io_addr); | ||||
|     memory_region_destroy(&s->ivshmem_mmio); | ||||
|     memory_region_del_subregion(&s->bar, &s->ivshmem); | ||||
|     memory_region_destroy(&s->ivshmem); | ||||
|     memory_region_destroy(&s->bar); | ||||
|     unregister_savevm(&dev->qdev, "ivshmem", s); | ||||
| 
 | ||||
|     return 0; | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Avi Kivity
						Avi Kivity