KVM MMU: fix race in invlpg code
A message that is not in the archive (sent off-list or not yet received): [email protected]
Quoted 38 lines · Xiao Guangrong
It has race in invlpg code, like below sequences:
A: hold
mmu_lockand get 'sp'
B: releasemmu_lockand do other things
C: holdmmu_lockand 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<[email protected]>--- arch/x86/kvm/paging_tmpl.h | 18 +++++++++++++++++- 1 files changed, 17 insertions(+), 1 deletions(-)arch/x86/kvm/paging_tmpl.h +5
-1@@ -462,11 +462,15 @@ 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;spin_lock (&vcpu->kvm->mmu_lock);
arch/x86/kvm/paging_tmpl.h static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva) · line 530
Quoted 8 lines
arch/x86/kvm/paging_tmpl.h +4
-0@@ -519,10 +523,22 @@ 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) {
At this point, sp might have been freed and re-allocated, now pointing at something completely different. So need to check role etc.
Alternatively, increase root_count. Then sp is guaranteed to be live (though it may have role.invalid set).
Quoted 16 lines
arch/x86/kvm/paging_tmpl.h +8
-0+ 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);}
Signature · 1 line
Do not meddle in the internals of kernels, for they are subtle and quick to panic.
A message that is not in the archive (sent off-list or not yet received): [email protected]
A message that is not in the archive (sent off-list or not yet received): [email protected]
Re: [PATCH 3/4] KVM MMU: allow shadow page become unsync at creating time
Quoted 8 lines · Xiao Guangrong
Allow new shadow page become unsync when is created, then we no need write-protect the '
sp->gfn', this idea is from Avi:|Another interesting case is to create new shadow pages in the unsync |state. That can help when the guest starts a short lived process: we |can avoid write protecting its pagetables completely
Any idea how this improves performance? A kernel build has a lot of short lived processes, might see an improvement there.
Signature · 1 line
Do not meddle in the internals of kernels, for they are subtle and quick to panic.
A message that is not in the archive (sent off-list or not yet received): [email protected]
Re: [PATCH 4/4] KVM MMU: do not intercept invlpg if 'oos_shadow' is disabled
Quoted 7 lines · Xiao Guangrong
If '
oos_shadow' == 0, intercepting invlpg command is really unnecessary.And it's good for us to compare the performance between enable '
oos_shadow' and disable 'oos_shadow'
Review static int dbg = 0; · line 80
Quoted 8 lines
(quoted diff) +2
-1@@ -74,8 +74,9 @@ static int dbg = 0; module_param(dbg, bool, 0644); #endif -static int oos_shadow = 1; +int __read_mostly oos_shadow = 1; module_param(oos_shadow, bool, 0644); +EXPORT_SYMBOL_GPL(oos_shadow);
Please rename to kvm_oos_shadow to reduce potential for conflict with other global names.
But really, this is a debug option, I don't expect people to run with oos_shadow=0, so there's not much motivation to optimize it.
Signature · 1 line
Do not meddle in the internals of kernels, for they are subtle and quick to panic.
Re: [PATCH 4/4] KVM MMU: do not intercept invlpg if 'oos_shadow' is disabled
Quoted 21 lines · Avi Kivity
Quoted 8 lines · Xiao Guangrong
If '
oos_shadow' == 0, intercepting invlpg command is really unnecessary.And it's good for us to compare the performance between enable '
oos_shadow'
and disable 'oos_shadow'Review static int dbg = 0; · line 80
Quoted 8 lines
(quoted diff) +2
-1@@ -74,8 +74,9 @@ static int dbg = 0; module_param(dbg, bool, 0644); #endif -static int oos_shadow = 1; +int __read_mostly oos_shadow = 1; module_param(oos_shadow, bool, 0644); +EXPORT_SYMBOL_GPL(oos_shadow);Please rename to
kvm_oos_shadowto reduce potential for conflict with other global names.
Quoted 2 lines
But really, this is a debug option, I don't expect people to run with oos_shadow=0, so there's not much motivation to optimize it.
Agreed, but, 'oos_shadow' option is document in Documentation/kernel-parameters.txt, if it's just a debug option, i think we do better not document it.
Thanks,
Xiao
Re: [PATCH 4/4] KVM MMU: do not intercept invlpg if 'oos_shadow' is disabled
Quoted 25 lines · Xiao Guangrong
Quoted 22 lines · Avi Kivity
Quoted 8 lines · Xiao Guangrong
If '
oos_shadow' == 0, intercepting invlpg command is really unnecessary.And it's good for us to compare the performance between enable '
oos_shadow'
and disable 'oos_shadow'Review static int dbg = 0; · line 81
Quoted 9 lines
(quoted diff) +2
-1@@ -74,8 +74,9 @@ static int dbg = 0; module_param(dbg, bool, 0644); #endif -static int oos_shadow = 1; +int __read_mostly oos_shadow = 1; module_param(oos_shadow, bool, 0644); +EXPORT_SYMBOL_GPL(oos_shadow);Please rename to
kvm_oos_shadowto reduce potential for conflict with other global names.
Quoted 6 lines
Quoted 3 lines
But really, this is a debug option, I don't expect people to run with oos_shadow=0, so there's not much motivation to optimize it.
Agreed, but, '
oos_shadow' option is document inDocumentation/kernel-parameters.txt, if it's just a debug option, i think we do better not document it.
It has to be documented, otherwise people complain :)
Anyway the variable name and the option name don't have to be the same (I think).
Signature · 1 line
error compiling committee.c: too many arguments to function