mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-02 15:23:53 -06:00
memory: Flush coalesced MMIO on selected region access
Instead of flushing pending coalesced MMIO requests on every vmexit, this provides a mechanism to selectively flush when memory regions related to the coalesced one are accessed. This first of all includes the coalesced region itself but can also applied to other regions, e.g. of the same device, by calling memory_region_set_flush_coalesced. Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com> Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
This commit is contained in:
parent
8732fbd2af
commit
d410515e03
2 changed files with 50 additions and 0 deletions
24
memory.c
24
memory.c
|
@ -311,6 +311,9 @@ static void memory_region_read_accessor(void *opaque,
|
|||
MemoryRegion *mr = opaque;
|
||||
uint64_t tmp;
|
||||
|
||||
if (mr->flush_coalesced_mmio) {
|
||||
qemu_flush_coalesced_mmio_buffer();
|
||||
}
|
||||
tmp = mr->ops->read(mr->opaque, addr, size);
|
||||
*value |= (tmp & mask) << shift;
|
||||
}
|
||||
|
@ -325,6 +328,9 @@ static void memory_region_write_accessor(void *opaque,
|
|||
MemoryRegion *mr = opaque;
|
||||
uint64_t tmp;
|
||||
|
||||
if (mr->flush_coalesced_mmio) {
|
||||
qemu_flush_coalesced_mmio_buffer();
|
||||
}
|
||||
tmp = (*value >> shift) & mask;
|
||||
mr->ops->write(mr->opaque, addr, tmp, size);
|
||||
}
|
||||
|
@ -826,6 +832,7 @@ void memory_region_init(MemoryRegion *mr,
|
|||
mr->dirty_log_mask = 0;
|
||||
mr->ioeventfd_nb = 0;
|
||||
mr->ioeventfds = NULL;
|
||||
mr->flush_coalesced_mmio = false;
|
||||
}
|
||||
|
||||
static bool memory_region_access_valid(MemoryRegion *mr,
|
||||
|
@ -1176,12 +1183,16 @@ void memory_region_add_coalescing(MemoryRegion *mr,
|
|||
cmr->addr = addrrange_make(int128_make64(offset), int128_make64(size));
|
||||
QTAILQ_INSERT_TAIL(&mr->coalesced, cmr, link);
|
||||
memory_region_update_coalesced_range(mr);
|
||||
memory_region_set_flush_coalesced(mr);
|
||||
}
|
||||
|
||||
void memory_region_clear_coalescing(MemoryRegion *mr)
|
||||
{
|
||||
CoalescedMemoryRange *cmr;
|
||||
|
||||
qemu_flush_coalesced_mmio_buffer();
|
||||
mr->flush_coalesced_mmio = false;
|
||||
|
||||
while (!QTAILQ_EMPTY(&mr->coalesced)) {
|
||||
cmr = QTAILQ_FIRST(&mr->coalesced);
|
||||
QTAILQ_REMOVE(&mr->coalesced, cmr, link);
|
||||
|
@ -1190,6 +1201,19 @@ void memory_region_clear_coalescing(MemoryRegion *mr)
|
|||
memory_region_update_coalesced_range(mr);
|
||||
}
|
||||
|
||||
void memory_region_set_flush_coalesced(MemoryRegion *mr)
|
||||
{
|
||||
mr->flush_coalesced_mmio = true;
|
||||
}
|
||||
|
||||
void memory_region_clear_flush_coalesced(MemoryRegion *mr)
|
||||
{
|
||||
qemu_flush_coalesced_mmio_buffer();
|
||||
if (QTAILQ_EMPTY(&mr->coalesced)) {
|
||||
mr->flush_coalesced_mmio = false;
|
||||
}
|
||||
}
|
||||
|
||||
void memory_region_add_eventfd(MemoryRegion *mr,
|
||||
target_phys_addr_t addr,
|
||||
unsigned size,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue