* [PATCH 1/2] KVM MMU: fix for forgot mark parent->unsync_children bit @ 2010-05-05 12:19 Xiao Guangrong 2010-05-05 12:21 ` [PATCH 2/2] KVM MMU: fix race in invlpg code Xiao Guangrong 2010-05-05 12:30 ` [PATCH 1/2] KVM MMU: fix for forgot mark parent->unsync_children bit Avi Kivity 0 siblings, 2 replies; 7+ messages in thread From: Xiao Guangrong @ 2010-05-05 12:19 UTC (permalink / raw) To: Avi Kivity; +Cc: Marcelo Tosatti, KVM list, LKML When mapping a new parent to unsync shadow page, we should mark parent's unsync_children bit Reported-by: Marcelo Tosatti <mtosatti@redhat.com> Signed-off-by: Xiao Guangrong <xiaoguangrong@cn.fujitsu.com> --- arch/x86/kvm/mmu.c | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 97f2ea0..bf35a2f 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -1374,7 +1374,9 @@ static struct kvm_mmu_page *kvm_mmu_get_page(struct kvm_vcpu *vcpu, if (sp->unsync_children) { set_bit(KVM_REQ_MMU_SYNC, &vcpu->requests); kvm_mmu_mark_parents_unsync(sp); - } + } else if (sp->unsync) + kvm_mmu_mark_parents_unsync(sp); + trace_kvm_mmu_get_page(sp, false); return sp; } -- 1.6.1.2 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 2/2] KVM MMU: fix race in invlpg code 2010-05-05 12:19 [PATCH 1/2] KVM MMU: fix for forgot mark parent->unsync_children bit Xiao Guangrong @ 2010-05-05 12:21 ` Xiao Guangrong 2010-05-05 12:31 ` Avi Kivity 2010-05-05 12:30 ` [PATCH 1/2] KVM MMU: fix for forgot mark parent->unsync_children bit Avi Kivity 1 sibling, 1 reply; 7+ messages in thread From: Xiao Guangrong @ 2010-05-05 12:21 UTC (permalink / raw) To: Avi Kivity; +Cc: Marcelo Tosatti, KVM list, LKML It has race in invlpg code, like below sequences: A: hold mmu_lock and get 'sp' B: release mmu_lock and do other things C: hold mmu_lock and continue use 'sp' if other path freed 'sp' in stage B, then kernel will crash This patch checks 'sp' whether lived before use 'sp' in stage C Signed-off-by: Xiao Guangrong <xiaoguangrong@cn.fujitsu.com> --- arch/x86/kvm/paging_tmpl.h | 22 ++++++++++++++++++++-- 1 files changed, 20 insertions(+), 2 deletions(-) diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h index 624b38f..13ea675 100644 --- a/arch/x86/kvm/paging_tmpl.h +++ b/arch/x86/kvm/paging_tmpl.h @@ -462,11 +462,16 @@ out_unlock: static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva) { - struct kvm_mmu_page *sp = NULL; + struct kvm_mmu_page *sp = NULL, *s; struct kvm_shadow_walk_iterator iterator; + struct hlist_head *bucket; + struct hlist_node *node, *tmp; gfn_t gfn = -1; u64 *sptep = NULL, gentry; int invlpg_counter, level, offset = 0, need_flush = 0; + unsigned index; + bool live = false; + union kvm_mmu_page_role role; spin_lock(&vcpu->kvm->mmu_lock); @@ -480,7 +485,7 @@ static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva) if (!sp->unsync) break; - + role = sp->role; WARN_ON(level != PT_PAGE_TABLE_LEVEL); shift = PAGE_SHIFT - (PT_LEVEL_BITS - PT64_LEVEL_BITS) * level; @@ -519,10 +524,23 @@ static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva) mmu_guess_page_from_pte_write(vcpu, gfn_to_gpa(gfn) + offset, gentry); spin_lock(&vcpu->kvm->mmu_lock); + index = kvm_page_table_hashfn(gfn); + bucket = &vcpu->kvm->arch.mmu_page_hash[index]; + hlist_for_each_entry_safe(s, node, tmp, bucket, hash_link) + if (s == sp) { + if (s->gfn == gfn && s->role.word == role.word) + live = true; + break; + } + + if (!live) + goto unlock_exit; + if (atomic_read(&vcpu->kvm->arch.invlpg_counter) == invlpg_counter) { ++vcpu->kvm->stat.mmu_pte_updated; FNAME(update_pte)(vcpu, sp, sptep, &gentry); } +unlock_exit: spin_unlock(&vcpu->kvm->mmu_lock); mmu_release_page_from_pte_write(vcpu); } -- 1.6.1.2 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 2/2] KVM MMU: fix race in invlpg code 2010-05-05 12:21 ` [PATCH 2/2] KVM MMU: fix race in invlpg code Xiao Guangrong @ 2010-05-05 12:31 ` Avi Kivity 2010-05-05 12:45 ` Xiao Guangrong 0 siblings, 1 reply; 7+ messages in thread From: Avi Kivity @ 2010-05-05 12:31 UTC (permalink / raw) To: Xiao Guangrong; +Cc: Marcelo Tosatti, KVM list, LKML On 05/05/2010 03:21 PM, Xiao Guangrong wrote: > It has race in invlpg code, like below sequences: > > A: hold mmu_lock and get 'sp' > B: release mmu_lock and do other things > C: hold mmu_lock and continue use 'sp' > > if other path freed 'sp' in stage B, then kernel will crash > > This patch checks 'sp' whether lived before use 'sp' in stage C > > Signed-off-by: Xiao Guangrong<xiaoguangrong@cn.fujitsu.com> > --- > arch/x86/kvm/paging_tmpl.h | 22 ++++++++++++++++++++-- > 1 files changed, 20 insertions(+), 2 deletions(-) > > diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h > index 624b38f..13ea675 100644 > --- a/arch/x86/kvm/paging_tmpl.h > +++ b/arch/x86/kvm/paging_tmpl.h > @@ -462,11 +462,16 @@ out_unlock: > > static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva) > { > - struct kvm_mmu_page *sp = NULL; > + struct kvm_mmu_page *sp = NULL, *s; > struct kvm_shadow_walk_iterator iterator; > + struct hlist_head *bucket; > + struct hlist_node *node, *tmp; > gfn_t gfn = -1; > u64 *sptep = NULL, gentry; > int invlpg_counter, level, offset = 0, need_flush = 0; > + unsigned index; > + bool live = false; > + union kvm_mmu_page_role role; > > spin_lock(&vcpu->kvm->mmu_lock); > > @@ -480,7 +485,7 @@ static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva) > > if (!sp->unsync) > break; > - > + role = sp->role; > WARN_ON(level != PT_PAGE_TABLE_LEVEL); > shift = PAGE_SHIFT - > (PT_LEVEL_BITS - PT64_LEVEL_BITS) * level; > @@ -519,10 +524,23 @@ static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva) > > mmu_guess_page_from_pte_write(vcpu, gfn_to_gpa(gfn) + offset, gentry); > spin_lock(&vcpu->kvm->mmu_lock); > + index = kvm_page_table_hashfn(gfn); > + bucket =&vcpu->kvm->arch.mmu_page_hash[index]; > + hlist_for_each_entry_safe(s, node, tmp, bucket, hash_link) > + if (s == sp) { > + if (s->gfn == gfn&& s->role.word == role.word) > + live = true; > + break; > + } > + > + if (!live) > + goto unlock_exit; > + > Did you try the root_count method? I think it's cleaner. -- error compiling committee.c: too many arguments to function ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 2/2] KVM MMU: fix race in invlpg code 2010-05-05 12:31 ` Avi Kivity @ 2010-05-05 12:45 ` Xiao Guangrong 2010-05-05 12:52 ` Avi Kivity 0 siblings, 1 reply; 7+ messages in thread From: Xiao Guangrong @ 2010-05-05 12:45 UTC (permalink / raw) To: Avi Kivity; +Cc: Marcelo Tosatti, KVM list, LKML Avi Kivity wrote: >> spin_lock(&vcpu->kvm->mmu_lock); >> + index = kvm_page_table_hashfn(gfn); >> + bucket =&vcpu->kvm->arch.mmu_page_hash[index]; >> + hlist_for_each_entry_safe(s, node, tmp, bucket, hash_link) >> + if (s == sp) { >> + if (s->gfn == gfn&& s->role.word == role.word) >> + live = true; >> + break; >> + } >> + >> + if (!live) >> + goto unlock_exit; >> + >> > > Did you try the root_count method? I think it's cleaner. Avi, Thanks for your idea. I have considered this method, but i'm not sure when it's the good time to real free this page, and i think we also need a way to synchronize the real free path and this path. Do you have any comment for it :-( Xiao ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 2/2] KVM MMU: fix race in invlpg code 2010-05-05 12:45 ` Xiao Guangrong @ 2010-05-05 12:52 ` Avi Kivity 0 siblings, 0 replies; 7+ messages in thread From: Avi Kivity @ 2010-05-05 12:52 UTC (permalink / raw) To: Xiao Guangrong; +Cc: Marcelo Tosatti, KVM list, LKML On 05/05/2010 03:45 PM, Xiao Guangrong wrote: > > Avi Kivity wrote: > > >>> spin_lock(&vcpu->kvm->mmu_lock); >>> + index = kvm_page_table_hashfn(gfn); >>> + bucket =&vcpu->kvm->arch.mmu_page_hash[index]; >>> + hlist_for_each_entry_safe(s, node, tmp, bucket, hash_link) >>> + if (s == sp) { >>> + if (s->gfn == gfn&& s->role.word == role.word) >>> + live = true; >>> + break; >>> + } >>> + >>> + if (!live) >>> + goto unlock_exit; >>> + >>> >>> >> Did you try the root_count method? I think it's cleaner. >> > Avi, Thanks for your idea. > > I have considered this method, but i'm not sure when it's the good time > to real free this page, and i think we also need a way to synchronize the > real free path and this path. Do you have any comment for it :-( > Same as mmu_free_roots(): --sp->root_count; if (!sp->root_count && sp->role.invalid) { kvm_mmu_zap_page(vcpu->kvm, sp); goto unlock_exit; } -- error compiling committee.c: too many arguments to function ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 1/2] KVM MMU: fix for forgot mark parent->unsync_children bit 2010-05-05 12:19 [PATCH 1/2] KVM MMU: fix for forgot mark parent->unsync_children bit Xiao Guangrong 2010-05-05 12:21 ` [PATCH 2/2] KVM MMU: fix race in invlpg code Xiao Guangrong @ 2010-05-05 12:30 ` Avi Kivity 2010-05-05 12:35 ` Xiao Guangrong 1 sibling, 1 reply; 7+ messages in thread From: Avi Kivity @ 2010-05-05 12:30 UTC (permalink / raw) To: Xiao Guangrong; +Cc: Marcelo Tosatti, KVM list, LKML On 05/05/2010 03:19 PM, Xiao Guangrong wrote: > When mapping a new parent to unsync shadow page, we should mark > parent's unsync_children bit > > Reported-by: Marcelo Tosatti<mtosatti@redhat.com> > Signed-off-by: Xiao Guangrong<xiaoguangrong@cn.fujitsu.com> > --- > arch/x86/kvm/mmu.c | 4 +++- > 1 files changed, 3 insertions(+), 1 deletions(-) > > diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c > index 97f2ea0..bf35a2f 100644 > --- a/arch/x86/kvm/mmu.c > +++ b/arch/x86/kvm/mmu.c > @@ -1374,7 +1374,9 @@ static struct kvm_mmu_page *kvm_mmu_get_page(struct kvm_vcpu *vcpu, > if (sp->unsync_children) { > set_bit(KVM_REQ_MMU_SYNC,&vcpu->requests); > kvm_mmu_mark_parents_unsync(sp); > - } > + } else if (sp->unsync) > + kvm_mmu_mark_parents_unsync(sp); > + > trace_kvm_mmu_get_page(sp, false); > return sp; > } > Which patch does this fix? If it wasn't merge yet, please repost with the fix included. -- error compiling committee.c: too many arguments to function ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 1/2] KVM MMU: fix for forgot mark parent->unsync_children bit 2010-05-05 12:30 ` [PATCH 1/2] KVM MMU: fix for forgot mark parent->unsync_children bit Avi Kivity @ 2010-05-05 12:35 ` Xiao Guangrong 0 siblings, 0 replies; 7+ messages in thread From: Xiao Guangrong @ 2010-05-05 12:35 UTC (permalink / raw) To: Avi Kivity; +Cc: Marcelo Tosatti, KVM list, LKML Avi Kivity wrote: > On 05/05/2010 03:19 PM, Xiao Guangrong wrote: >> When mapping a new parent to unsync shadow page, we should mark >> parent's unsync_children bit >> >> Reported-by: Marcelo Tosatti<mtosatti@redhat.com> >> Signed-off-by: Xiao Guangrong<xiaoguangrong@cn.fujitsu.com> >> --- >> arch/x86/kvm/mmu.c | 4 +++- >> 1 files changed, 3 insertions(+), 1 deletions(-) >> >> diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c >> index 97f2ea0..bf35a2f 100644 >> --- a/arch/x86/kvm/mmu.c >> +++ b/arch/x86/kvm/mmu.c >> @@ -1374,7 +1374,9 @@ static struct kvm_mmu_page >> *kvm_mmu_get_page(struct kvm_vcpu *vcpu, >> if (sp->unsync_children) { >> set_bit(KVM_REQ_MMU_SYNC,&vcpu->requests); >> kvm_mmu_mark_parents_unsync(sp); >> - } >> + } else if (sp->unsync) >> + kvm_mmu_mark_parents_unsync(sp); >> + >> trace_kvm_mmu_get_page(sp, false); >> return sp; >> } >> > > > Which patch does this fix? If it wasn't merge yet, please repost with > the fix included. Oh, OK, i'll sent the previous pathset that are reverted by Marcelo. Thanks, Xiao ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2010-05-05 12:52 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2010-05-05 12:19 [PATCH 1/2] KVM MMU: fix for forgot mark parent->unsync_children bit Xiao Guangrong 2010-05-05 12:21 ` [PATCH 2/2] KVM MMU: fix race in invlpg code Xiao Guangrong 2010-05-05 12:31 ` Avi Kivity 2010-05-05 12:45 ` Xiao Guangrong 2010-05-05 12:52 ` Avi Kivity 2010-05-05 12:30 ` [PATCH 1/2] KVM MMU: fix for forgot mark parent->unsync_children bit Avi Kivity 2010-05-05 12:35 ` Xiao Guangrong
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox