aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
authorLai Jiangshan <laijs@cn.fujitsu.com>2010-04-19 05:41:23 -0400
committerAvi Kivity <avi@redhat.com>2010-05-17 05:18:01 -0400
commit90d83dc3d49f5101addae962ccc1b4aff66b68d8 (patch)
tree855aec81663eff4597ab276f13d449be9b798ec2 /arch/x86
parent9beeaa2d689842f7760aa16c512e6bb8182d38b6 (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 'arch/x86')
-rw-r--r--arch/x86/kvm/mmu.c7
-rw-r--r--arch/x86/kvm/vmx.c2
-rw-r--r--arch/x86/kvm/x86.c4
-rw-r--r--arch/x86/kvm/x86.h7
4 files changed, 14 insertions, 6 deletions
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index 7a17db1cdcd6..0682a393ad90 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -787,7 +787,7 @@ static int kvm_handle_hva(struct kvm *kvm, unsigned long hva,
787 int retval = 0; 787 int retval = 0;
788 struct kvm_memslots *slots; 788 struct kvm_memslots *slots;
789 789
790 slots = rcu_dereference(kvm->memslots); 790 slots = kvm_memslots(kvm);
791 791
792 for (i = 0; i < slots->nmemslots; i++) { 792 for (i = 0; i < slots->nmemslots; i++) {
793 struct kvm_memory_slot *memslot = &slots->memslots[i]; 793 struct kvm_memory_slot *memslot = &slots->memslots[i];
@@ -3016,7 +3016,8 @@ unsigned int kvm_mmu_calculate_mmu_pages(struct kvm *kvm)
3016 unsigned int nr_pages = 0; 3016 unsigned int nr_pages = 0;
3017 struct kvm_memslots *slots; 3017 struct kvm_memslots *slots;
3018 3018
3019 slots = rcu_dereference(kvm->memslots); 3019 slots = kvm_memslots(kvm);
3020
3020 for (i = 0; i < slots->nmemslots; i++) 3021 for (i = 0; i < slots->nmemslots; i++)
3021 nr_pages += slots->memslots[i].npages; 3022 nr_pages += slots->memslots[i].npages;
3022 3023
@@ -3292,7 +3293,7 @@ static int count_rmaps(struct kvm_vcpu *vcpu)
3292 int i, j, k, idx; 3293 int i, j, k, idx;
3293 3294
3294 idx = srcu_read_lock(&kvm->srcu); 3295 idx = srcu_read_lock(&kvm->srcu);
3295 slots = rcu_dereference(kvm->memslots); 3296 slots = kvm_memslots(kvm);
3296 for (i = 0; i < KVM_MEMORY_SLOTS; ++i) { 3297 for (i = 0; i < KVM_MEMORY_SLOTS; ++i) {
3297 struct kvm_memory_slot *m = &slots->memslots[i]; 3298 struct kvm_memory_slot *m = &slots->memslots[i];
3298 struct kvm_rmap_desc *d; 3299 struct kvm_rmap_desc *d;
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 0b896ac7e4bb..d0a10b5612e9 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -1558,7 +1558,7 @@ static gva_t rmode_tss_base(struct kvm *kvm)
1558 struct kvm_memslots *slots; 1558 struct kvm_memslots *slots;
1559 gfn_t base_gfn; 1559 gfn_t base_gfn;
1560 1560
1561 slots = rcu_dereference(kvm->memslots); 1561 slots = kvm_memslots(kvm);
1562 base_gfn = kvm->memslots->memslots[0].base_gfn + 1562 base_gfn = kvm->memslots->memslots[0].base_gfn +
1563 kvm->memslots->memslots[0].npages - 3; 1563 kvm->memslots->memslots[0].npages - 3;
1564 return base_gfn << PAGE_SHIFT; 1564 return base_gfn << PAGE_SHIFT;
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 58a96e6a234c..638248c96999 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -2497,7 +2497,7 @@ gfn_t unalias_gfn_instantiation(struct kvm *kvm, gfn_t gfn)
2497 struct kvm_mem_alias *alias; 2497 struct kvm_mem_alias *alias;
2498 struct kvm_mem_aliases *aliases; 2498 struct kvm_mem_aliases *aliases;
2499 2499
2500 aliases = rcu_dereference(kvm->arch.aliases); 2500 aliases = kvm_aliases(kvm);
2501 2501
2502 for (i = 0; i < aliases->naliases; ++i) { 2502 for (i = 0; i < aliases->naliases; ++i) {
2503 alias = &aliases->aliases[i]; 2503 alias = &aliases->aliases[i];
@@ -2516,7 +2516,7 @@ gfn_t unalias_gfn(struct kvm *kvm, gfn_t gfn)
2516 struct kvm_mem_alias *alias; 2516 struct kvm_mem_alias *alias;
2517 struct kvm_mem_aliases *aliases; 2517 struct kvm_mem_aliases *aliases;
2518 2518
2519 aliases = rcu_dereference(kvm->arch.aliases); 2519 aliases = kvm_aliases(kvm);
2520 2520
2521 for (i = 0; i < aliases->naliases; ++i) { 2521 for (i = 0; i < aliases->naliases; ++i) {
2522 alias = &aliases->aliases[i]; 2522 alias = &aliases->aliases[i];
diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h
index b7a404722d2b..f4b54458285b 100644
--- a/arch/x86/kvm/x86.h
+++ b/arch/x86/kvm/x86.h
@@ -65,6 +65,13 @@ static inline int is_paging(struct kvm_vcpu *vcpu)
65 return kvm_read_cr0_bits(vcpu, X86_CR0_PG); 65 return kvm_read_cr0_bits(vcpu, X86_CR0_PG);
66} 66}
67 67
68static inline struct kvm_mem_aliases *kvm_aliases(struct kvm *kvm)
69{
70 return rcu_dereference_check(kvm->arch.aliases,
71 srcu_read_lock_held(&kvm->srcu)
72 || lockdep_is_held(&kvm->slots_lock));
73}
74
68void kvm_before_handle_nmi(struct kvm_vcpu *vcpu); 75void kvm_before_handle_nmi(struct kvm_vcpu *vcpu);
69void kvm_after_handle_nmi(struct kvm_vcpu *vcpu); 76void kvm_after_handle_nmi(struct kvm_vcpu *vcpu);
70 77