On 05/03/18 19:36, Paolo Bonzini wrote: > 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. > > Cc: qemu-sta...@nongnu.org
Reviewed-by: Alexey Kardashevskiy <a...@ozlabs.ru> > Signed-off-by: Paolo Bonzini <pbonz...@redhat.com> > --- > exec.c | 37 ++++++++++++++++++++++--------------- > 1 file changed, 22 insertions(+), 15 deletions(-) > > diff --git a/exec.c b/exec.c > index e8d7b335b6..0b74b58d45 100644 > --- a/exec.c > +++ b/exec.c > @@ -3074,6 +3074,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) > { > @@ -3082,25 +3083,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, > @@ -3209,6 +3199,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) > { > -- Alexey