[Qemu-devel] [PULL 19/34] address_space_access_valid: address_space_to_flatview needs RCU lock

Paolo Bonzini posted 34 patches 7 years, 7 months ago
[Qemu-devel] [PULL 19/34] address_space_access_valid: address_space_to_flatview needs RCU lock
Posted by Paolo Bonzini 7 years, 7 months ago
address_space_access_valid 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_access_valid to address_space_access_valid.

Reviewed-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 exec.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/exec.c b/exec.c
index e4552ee..62ed49d 100644
--- a/exec.c
+++ b/exec.c
@@ -3395,7 +3395,6 @@ static bool flatview_access_valid(FlatView *fv, hwaddr addr, int len,
     MemoryRegion *mr;
     hwaddr l, xlat;
 
-    rcu_read_lock();
     while (len > 0) {
         l = len;
         mr = flatview_translate(fv, addr, &xlat, &l, is_write);
@@ -3410,15 +3409,20 @@ static bool flatview_access_valid(FlatView *fv, hwaddr addr, int len,
         len -= l;
         addr += l;
     }
-    rcu_read_unlock();
     return true;
 }
 
 bool address_space_access_valid(AddressSpace *as, hwaddr addr,
                                 int len, bool is_write)
 {
-    return flatview_access_valid(address_space_to_flatview(as),
-                                 addr, len, is_write);
+    FlatView *fv;
+    bool result;
+
+    rcu_read_lock();
+    fv = address_space_to_flatview(as);
+    result = flatview_access_valid(fv, addr, len, is_write);
+    rcu_read_unlock();
+    return result;
 }
 
 static hwaddr
-- 
1.8.3.1



Re: [Qemu-devel] [PULL 19/34] address_space_access_valid: address_space_to_flatview needs RCU lock
Posted by Cornelia Huck 7 years, 7 months ago
On Tue,  6 Mar 2018 14:19:15 +0100
Paolo Bonzini <pbonzini@redhat.com> wrote:

> address_space_access_valid 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_access_valid to address_space_access_valid.
> 
> Reviewed-by: Alexey Kardashevskiy <aik@ozlabs.ru>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>  exec.c | 12 ++++++++----
>  1 file changed, 8 insertions(+), 4 deletions(-)

This one kills my s390x guests when running under tcg:

qemu-system-s390x: /home/cohuck/git/qemu/include/qemu/rcu.h:89: void rcu_read_unlock(void): Assertion `p_rcu_reader->depth != 0' failed.

Easy to reproduce with the moon buggy image from the QEMU Advent
Calendar:

s390x-softmmu/qemu-system-s390x -M s390-ccw-virtio -nographic -smp 2 -kernel ~/Downloads/s390-moon-buggy/s390-bb.kernel -initrd ~/Downloads/s390-moon-buggy/s390-moon-buggy.initrd

(regardless whether using smp or not)

Backchain:

(gdb) bt
#0  0x00007ffff399d9fb in raise () from /lib64/libc.so.6
#1  0x00007ffff399f800 in abort () from /lib64/libc.so.6
#2  0x00007ffff39960da in __assert_fail_base () from /lib64/libc.so.6
#3  0x00007ffff3996152 in __assert_fail () from /lib64/libc.so.6
#4  0x00005555556a4919 in rcu_read_unlock ()
    at /home/cohuck/git/qemu/include/qemu/rcu.h:89
#5  cpu_exec (cpu=0x555556423f50)
    at /home/cohuck/git/qemu/accel/tcg/cpu-exec.c:740
#6  0x000055555566cbf5 in tcg_cpu_exec (cpu=<optimized out>)
    at /home/cohuck/git/qemu/cpus.c:1341
#7  qemu_tcg_rr_cpu_thread_fn (arg=<optimized out>)
    at /home/cohuck/git/qemu/cpus.c:1435
#8  0x00007ffff3d4336d in start_thread () from /lib64/libpthread.so.0
#9  0x00007ffff3a77b4f in clone () from /lib64/libc.so.6

F26 host, qemu built with clang.

Re: [Qemu-devel] [PULL 19/34] address_space_access_valid: address_space_to_flatview needs RCU lock
Posted by Paolo Bonzini 7 years, 7 months ago
On 07/03/2018 13:49, Cornelia Huck wrote:
> On Tue,  6 Mar 2018 14:19:15 +0100
> Paolo Bonzini <pbonzini@redhat.com> wrote:
> 
>> address_space_access_valid 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_access_valid to address_space_access_valid.
>>
>> Reviewed-by: Alexey Kardashevskiy <aik@ozlabs.ru>
>> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
>> ---
>>  exec.c | 12 ++++++++----
>>  1 file changed, 8 insertions(+), 4 deletions(-)
> 
> This one kills my s390x guests when running under tcg:
> 
> qemu-system-s390x: /home/cohuck/git/qemu/include/qemu/rcu.h:89: void rcu_read_unlock(void): Assertion `p_rcu_reader->depth != 0' failed.
> 
> Easy to reproduce with the moon buggy image from the QEMU Advent
> Calendar:
> 
> s390x-softmmu/qemu-system-s390x -M s390-ccw-virtio -nographic -smp 2 -kernel ~/Downloads/s390-moon-buggy/s390-bb.kernel -initrd ~/Downloads/s390-moon-buggy/s390-moon-buggy.initrd

This is the fix for all of these:

diff --git a/exec.c b/exec.c
index 604f03c535..a9181e6417 100644
--- a/exec.c
+++ b/exec.c
@@ -3393,7 +3393,6 @@ static bool flatview_access_valid(FlatView *fv,
hwaddr addr, int len,
         if (!memory_access_is_direct(mr, is_write)) {
             l = memory_access_size(mr, l, addr);
             if (!memory_region_access_valid(mr, xlat, l, is_write)) {
-                rcu_read_unlock();
                 return false;
             }
         }

Paolo