address_space_write: address_space_to_flatview needs RCU lock

address_space_write is calling address_space_to_flatview but it can
be called outside the RCU lock.  To fix it, push the rcu_read_lock/unlock
pair up from flatview_write to address_space_write.

Reviewed-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 4c6ebbb364)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
stable-2.11
Paolo Bonzini 2018-03-05 09:23:56 +01:00 committed by Michael Roth
parent ac25a3257f
commit df04d1f16a
1 changed files with 22 additions and 15 deletions

37
exec.c
View File

@ -3005,6 +3005,7 @@ static MemTxResult flatview_write_continue(FlatView *fv, hwaddr addr,
return result;
}
/* Called from RCU critical section. */
static MemTxResult flatview_write(FlatView *fv, hwaddr addr, MemTxAttrs attrs,
const uint8_t *buf, int len)
{
@ -3013,25 +3014,14 @@ static MemTxResult flatview_write(FlatView *fv, hwaddr addr, MemTxAttrs attrs,
MemoryRegion *mr;
MemTxResult result = MEMTX_OK;
if (len > 0) {
rcu_read_lock();
l = len;
mr = flatview_translate(fv, addr, &addr1, &l, true);
result = flatview_write_continue(fv, addr, attrs, buf, len,
addr1, l, mr);
rcu_read_unlock();
}
l = len;
mr = flatview_translate(fv, addr, &addr1, &l, true);
result = flatview_write_continue(fv, addr, attrs, buf, len,
addr1, l, mr);
return result;
}
MemTxResult address_space_write(AddressSpace *as, hwaddr addr,
MemTxAttrs attrs,
const uint8_t *buf, int len)
{
return flatview_write(address_space_to_flatview(as), addr, attrs, buf, len);
}
/* Called within RCU critical section. */
MemTxResult flatview_read_continue(FlatView *fv, hwaddr addr,
MemTxAttrs attrs, uint8_t *buf,
@ -3140,6 +3130,23 @@ MemTxResult address_space_rw(AddressSpace *as, hwaddr addr,
addr, attrs, buf, len, is_write);
}
MemTxResult address_space_write(AddressSpace *as, hwaddr addr,
MemTxAttrs attrs,
const uint8_t *buf, int len)
{
MemTxResult result = MEMTX_OK;
FlatView *fv;
if (len > 0) {
rcu_read_lock();
fv = address_space_to_flatview(as);
result = flatview_write(fv, addr, attrs, buf, len);
rcu_read_unlock();
}
return result;
}
void cpu_physical_memory_rw(hwaddr addr, uint8_t *buf,
int len, int is_write)
{