diff options
author | Lai Jiangshan <laijs@cn.fujitsu.com> | 2010-04-19 05:41:23 -0400 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2010-05-17 05:18:01 -0400 |
commit | 90d83dc3d49f5101addae962ccc1b4aff66b68d8 (patch) | |
tree | 855aec81663eff4597ab276f13d449be9b798ec2 /virt/kvm/kvm_main.c | |
parent | 9beeaa2d689842f7760aa16c512e6bb8182d38b6 (diff) |
KVM: use the correct RCU API for PROVE_RCU=y
The RCU/SRCU API have already changed for proving RCU usage.
I got the following dmesg when PROVE_RCU=y because we used incorrect API.
This patch coverts rcu_deference() to srcu_dereference() or family API.
===================================================
[ INFO: suspicious rcu_dereference_check() usage. ]
---------------------------------------------------
arch/x86/kvm/mmu.c:3020 invoked rcu_dereference_check() without protection!
other info that might help us debug this:
rcu_scheduler_active = 1, debug_locks = 0
2 locks held by qemu-system-x86/8550:
#0: (&kvm->slots_lock){+.+.+.}, at: [<ffffffffa011a6ac>] kvm_set_memory_region+0x29/0x50 [kvm]
#1: (&(&kvm->mmu_lock)->rlock){+.+...}, at: [<ffffffffa012262d>] kvm_arch_commit_memory_region+0xa6/0xe2 [kvm]
stack backtrace:
Pid: 8550, comm: qemu-system-x86 Not tainted 2.6.34-rc4-tip-01028-g939eab1 #27
Call Trace:
[<ffffffff8106c59e>] lockdep_rcu_dereference+0xaa/0xb3
[<ffffffffa012f6c1>] kvm_mmu_calculate_mmu_pages+0x44/0x7d [kvm]
[<ffffffffa012263e>] kvm_arch_commit_memory_region+0xb7/0xe2 [kvm]
[<ffffffffa011a5d7>] __kvm_set_memory_region+0x636/0x6e2 [kvm]
[<ffffffffa011a6ba>] kvm_set_memory_region+0x37/0x50 [kvm]
[<ffffffffa015e956>] vmx_set_tss_addr+0x46/0x5a [kvm_intel]
[<ffffffffa0126592>] kvm_arch_vm_ioctl+0x17a/0xcf8 [kvm]
[<ffffffff810a8692>] ? unlock_page+0x27/0x2c
[<ffffffff810bf879>] ? __do_fault+0x3a9/0x3e1
[<ffffffffa011b12f>] kvm_vm_ioctl+0x364/0x38d [kvm]
[<ffffffff81060cfa>] ? up_read+0x23/0x3d
[<ffffffff810f3587>] vfs_ioctl+0x32/0xa6
[<ffffffff810f3b19>] do_vfs_ioctl+0x495/0x4db
[<ffffffff810e6b2f>] ? fget_light+0xc2/0x241
[<ffffffff810e416c>] ? do_sys_open+0x104/0x116
[<ffffffff81382d6d>] ? retint_swapgs+0xe/0x13
[<ffffffff810f3ba6>] sys_ioctl+0x47/0x6a
[<ffffffff810021db>] system_call_fastpath+0x16/0x1b
Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'virt/kvm/kvm_main.c')
-rw-r--r-- | virt/kvm/kvm_main.c | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index d6351a34b297..4901ec5061ba 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c | |||
@@ -834,7 +834,7 @@ EXPORT_SYMBOL_GPL(kvm_is_error_hva); | |||
834 | struct kvm_memory_slot *gfn_to_memslot_unaliased(struct kvm *kvm, gfn_t gfn) | 834 | struct kvm_memory_slot *gfn_to_memslot_unaliased(struct kvm *kvm, gfn_t gfn) |
835 | { | 835 | { |
836 | int i; | 836 | int i; |
837 | struct kvm_memslots *slots = rcu_dereference(kvm->memslots); | 837 | struct kvm_memslots *slots = kvm_memslots(kvm); |
838 | 838 | ||
839 | for (i = 0; i < slots->nmemslots; ++i) { | 839 | for (i = 0; i < slots->nmemslots; ++i) { |
840 | struct kvm_memory_slot *memslot = &slots->memslots[i]; | 840 | struct kvm_memory_slot *memslot = &slots->memslots[i]; |
@@ -856,7 +856,7 @@ struct kvm_memory_slot *gfn_to_memslot(struct kvm *kvm, gfn_t gfn) | |||
856 | int kvm_is_visible_gfn(struct kvm *kvm, gfn_t gfn) | 856 | int kvm_is_visible_gfn(struct kvm *kvm, gfn_t gfn) |
857 | { | 857 | { |
858 | int i; | 858 | int i; |
859 | struct kvm_memslots *slots = rcu_dereference(kvm->memslots); | 859 | struct kvm_memslots *slots = kvm_memslots(kvm); |
860 | 860 | ||
861 | gfn = unalias_gfn_instantiation(kvm, gfn); | 861 | gfn = unalias_gfn_instantiation(kvm, gfn); |
862 | for (i = 0; i < KVM_MEMORY_SLOTS; ++i) { | 862 | for (i = 0; i < KVM_MEMORY_SLOTS; ++i) { |
@@ -900,7 +900,7 @@ out: | |||
900 | int memslot_id(struct kvm *kvm, gfn_t gfn) | 900 | int memslot_id(struct kvm *kvm, gfn_t gfn) |
901 | { | 901 | { |
902 | int i; | 902 | int i; |
903 | struct kvm_memslots *slots = rcu_dereference(kvm->memslots); | 903 | struct kvm_memslots *slots = kvm_memslots(kvm); |
904 | struct kvm_memory_slot *memslot = NULL; | 904 | struct kvm_memory_slot *memslot = NULL; |
905 | 905 | ||
906 | gfn = unalias_gfn(kvm, gfn); | 906 | gfn = unalias_gfn(kvm, gfn); |
@@ -1994,7 +1994,9 @@ int kvm_io_bus_write(struct kvm *kvm, enum kvm_bus bus_idx, gpa_t addr, | |||
1994 | int len, const void *val) | 1994 | int len, const void *val) |
1995 | { | 1995 | { |
1996 | int i; | 1996 | int i; |
1997 | struct kvm_io_bus *bus = rcu_dereference(kvm->buses[bus_idx]); | 1997 | struct kvm_io_bus *bus; |
1998 | |||
1999 | bus = srcu_dereference(kvm->buses[bus_idx], &kvm->srcu); | ||
1998 | for (i = 0; i < bus->dev_count; i++) | 2000 | for (i = 0; i < bus->dev_count; i++) |
1999 | if (!kvm_iodevice_write(bus->devs[i], addr, len, val)) | 2001 | if (!kvm_iodevice_write(bus->devs[i], addr, len, val)) |
2000 | return 0; | 2002 | return 0; |
@@ -2006,8 +2008,9 @@ int kvm_io_bus_read(struct kvm *kvm, enum kvm_bus bus_idx, gpa_t addr, | |||
2006 | int len, void *val) | 2008 | int len, void *val) |
2007 | { | 2009 | { |
2008 | int i; | 2010 | int i; |
2009 | struct kvm_io_bus *bus = rcu_dereference(kvm->buses[bus_idx]); | 2011 | struct kvm_io_bus *bus; |
2010 | 2012 | ||
2013 | bus = srcu_dereference(kvm->buses[bus_idx], &kvm->srcu); | ||
2011 | for (i = 0; i < bus->dev_count; i++) | 2014 | for (i = 0; i < bus->dev_count; i++) |
2012 | if (!kvm_iodevice_read(bus->devs[i], addr, len, val)) | 2015 | if (!kvm_iodevice_read(bus->devs[i], addr, len, val)) |
2013 | return 0; | 2016 | return 0; |