static void virtio_balloon_handle_output(VirtIODevice *vdev, VirtQueue *vq) { VirtIOBalloon *s = to_virtio_balloon(vdev); VirtQueueElement elem; MemoryRegionSection section; while (virtqueue_pop(vq, &elem)) { size_t offset = 0; uint32_t pfn; while (iov_to_buf(elem.out_sg, elem.out_num, offset, &pfn, 4) == 4) { ram_addr_t pa; ram_addr_t addr; pa = (ram_addr_t)ldl_p(&pfn) << VIRTIO_BALLOON_PFN_SHIFT; offset += 4; /* FIXME: remove get_system_memory(), but how? */ section = memory_region_find(get_system_memory(), pa, 1); if (!section.size || !memory_region_is_ram(section.mr)) continue; /* Using memory_region_get_ram_ptr is bending the rules a bit, but should be OK because we only want a single page. */ addr = section.offset_within_region; balloon_page(memory_region_get_ram_ptr(section.mr) + addr, !!(vq == s->dvq)); } virtqueue_push(vq, &elem, offset); virtio_notify(vdev, vq); } }
static void virtio_balloon_handle_output(VirtIODevice *vdev, VirtQueue *vq) { VirtIOBalloon *s = to_virtio_balloon(vdev); VirtQueueElement elem; while (virtqueue_pop(vq, &elem)) { size_t offset = 0; uint32_t pfn; while (iov_to_buf(elem.out_sg, elem.out_num, &pfn, offset, 4) == 4) { ram_addr_t pa; ram_addr_t addr; pa = (ram_addr_t)ldl_p(&pfn) << VIRTIO_BALLOON_PFN_SHIFT; offset += 4; addr = cpu_get_physical_page_desc(pa); if ((addr & ~TARGET_PAGE_MASK) != IO_MEM_RAM) continue; /* Using qemu_get_ram_ptr is bending the rules a bit, but should be OK because we only want a single page. */ balloon_page(qemu_get_ram_ptr(addr), !!(vq == s->dvq)); } virtqueue_push(vq, &elem, offset); virtio_notify(vdev, vq); } }
static void virtio_balloon_set_config(VirtIODevice *vdev, const uint8_t *config_data) { VirtIOBalloon *dev = to_virtio_balloon(vdev); struct virtio_balloon_config config; memcpy(&config, config_data, 8); dev->actual = le32_to_cpu(config.actual); }
static void virtio_balloon_get_config(VirtIODevice *vdev, uint8_t *config_data) { VirtIOBalloon *dev = to_virtio_balloon(vdev); struct virtio_balloon_config config; config.num_pages = cpu_to_le32(dev->num_pages); config.actual = cpu_to_le32(dev->actual); memcpy(config_data, &config, 8); }
static void virtio_balloon_set_config(VirtIODevice *vdev, const uint8_t *config_data) { VirtIOBalloon *dev = to_virtio_balloon(vdev); struct virtio_balloon_config config; uint32_t oldactual = dev->actual; memcpy(&config, config_data, 8); dev->actual = le32_to_cpu(config.actual); if (dev->actual != oldactual) { qemu_balloon_changed(ram_size - (dev->actual << VIRTIO_BALLOON_PFN_SHIFT)); } }