On 06/25/2012 10:01 AM, Jan Kiszka wrote:
> Flush pending coalesced MMIO before performing mapping or state changes
> that could affect the event orderings or route the buffered requests to
> a wrong region.
>
> Signed-off-by: Jan Kiszka <[email protected]>
>
> In addition, we also have to
Yes, we do.
>
> void memory_region_transaction_begin(void)
> {
> + qemu_flush_coalesced_mmio_buffer();
> ++memory_region_transaction_depth;
> }
Why is this needed?
>
> @@ -1109,6 +1110,9 @@ void memory_region_sync_dirty_bitmap(MemoryRegion *mr)
>
> void memory_region_set_readonly(MemoryRegion *mr, bool readonly)
> {
> + if (!QTAILQ_EMPTY(&mr->coalesced)) {
> + qemu_flush_coalesced_mmio_buffer();
> + }
The readonly attribute is inherited by subregions and alias targets, so
this check is insufficient. See render_memory_region(). Need to flush
unconditionally.
> if (mr->readonly != readonly) {
> mr->readonly = readonly;
> memory_region_update_topology(mr);
> @@ -1117,6 +1121,9 @@ void memory_region_set_readonly(MemoryRegion *mr, bool
> readonly)
>
> void memory_region_rom_device_set_readable(MemoryRegion *mr, bool readable)
> {
> + if (!QTAILQ_EMPTY(&mr->coalesced)) {
> + qemu_flush_coalesced_mmio_buffer();
> + }
This property is not inherited, but let's flush unconditionally just the
same, to reduce fragility.
> @@ -1219,6 +1228,9 @@ void memory_region_add_eventfd(MemoryRegion *mr,
> };
> unsigned i;
>
> + if (!QTAILQ_EMPTY(&mr->coalesced)) {
> + qemu_flush_coalesced_mmio_buffer();
> + }
Ditto. It's possible that an eventfd overlays a subregion which has
coalescing enabled. It's not really defined what happens in this case,
and such code and its submitter should be perma-nacked, but let's play
it safe here since there isn't much to be gained by avoiding the flush.
This code is a very slow path anyway, including and rcu and/or srcu
synchronization, and a rebuild of the dispatch radix tree (trees when we
dma-enable this code).
> for (i = 0; i < mr->ioeventfd_nb; ++i) {
> if (memory_region_ioeventfd_before(mrfd, mr->ioeventfds[i])) {
> break;
> @@ -1249,6 +1261,9 @@ void memory_region_del_eventfd(MemoryRegion *mr,
> };
> unsigned i;
>
> + if (!QTAILQ_EMPTY(&mr->coalesced)) {
> + qemu_flush_coalesced_mmio_buffer();
> + }
Same.
The repetitiveness of this code suggests a different way of doing this:
make every API call be its own subtransaction and perform the flush in
memory_region_begin_transaction() (maybe that's the answer to my
question above).
--
error compiling committee.c: too many arguments to function
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html