KVM: svm: do not call kvm_set_cr0 from init_vmcb
kvm_set_cr0 may want to call kvm_zap_gfn_range and thus access the memslots array (SRCU protected). Using a mini SRCU critical section is ugly, and adding it to kvm_arch_vcpu_create doesn't work because the VMX vcpu_create callback calls synchronize_srcu. Fixes this lockdep splat: =============================== [ INFO: suspicious RCU usage. ] 4.3.0-rc1+ #1 Not tainted ------------------------------- include/linux/kvm_host.h:488 suspicious rcu_dereference_check() usage! other info that might help us debug this: rcu_scheduler_active = 1, debug_locks = 0 1 lock held by qemu-system-i38/17000: #0: (&(&kvm->mmu_lock)->rlock){+.+...}, at: kvm_zap_gfn_range+0x24/0x1a0 [kvm] [...] Call Trace: dump_stack+0x4e/0x84 lockdep_rcu_suspicious+0xfd/0x130 kvm_zap_gfn_range+0x188/0x1a0 [kvm] kvm_set_cr0+0xde/0x1e0 [kvm] init_vmcb+0x760/0xad0 [kvm_amd] svm_create_vcpu+0x197/0x250 [kvm_amd] kvm_arch_vcpu_create+0x47/0x70 [kvm] kvm_vm_ioctl+0x302/0x7e0 [kvm] ? __lock_is_held+0x51/0x70 ? __fget+0x101/0x210 do_vfs_ioctl+0x2f4/0x560 ? __fget_light+0x29/0x90 SyS_ioctl+0x4c/0x90 entry_SYSCALL_64_fastpath+0x16/0x73 Reported-by: Borislav Petkov <bp@alien8.de> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Родитель
5b6a7175bf
Коммит
79a8059d24
|
@ -202,6 +202,7 @@ module_param(npt, int, S_IRUGO);
|
||||||
static int nested = true;
|
static int nested = true;
|
||||||
module_param(nested, int, S_IRUGO);
|
module_param(nested, int, S_IRUGO);
|
||||||
|
|
||||||
|
static void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0);
|
||||||
static void svm_flush_tlb(struct kvm_vcpu *vcpu);
|
static void svm_flush_tlb(struct kvm_vcpu *vcpu);
|
||||||
static void svm_complete_interrupts(struct vcpu_svm *svm);
|
static void svm_complete_interrupts(struct vcpu_svm *svm);
|
||||||
|
|
||||||
|
@ -1263,7 +1264,7 @@ static void init_vmcb(struct vcpu_svm *svm, bool init_event)
|
||||||
* svm_set_cr0() sets PG and WP and clears NW and CD on save->cr0.
|
* svm_set_cr0() sets PG and WP and clears NW and CD on save->cr0.
|
||||||
* It also updates the guest-visible cr0 value.
|
* It also updates the guest-visible cr0 value.
|
||||||
*/
|
*/
|
||||||
(void)kvm_set_cr0(&svm->vcpu, X86_CR0_NW | X86_CR0_CD | X86_CR0_ET);
|
svm_set_cr0(&svm->vcpu, X86_CR0_NW | X86_CR0_CD | X86_CR0_ET);
|
||||||
kvm_mmu_reset_context(&svm->vcpu);
|
kvm_mmu_reset_context(&svm->vcpu);
|
||||||
|
|
||||||
save->cr4 = X86_CR4_PAE;
|
save->cr4 = X86_CR4_PAE;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче