diff options
author | Xiao Guangrong <xiaoguangrong@cn.fujitsu.com> | 2010-05-15 06:53:35 -0400 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2010-08-01 03:35:50 -0400 |
commit | f78978aa3a8222f7822f15fba5dbaea990ef0887 (patch) | |
tree | b961f86576c2bfd58d546c44efa193bc9db449c6 | |
parent | e02aa901b1aa41fb541521800cc2a4774c162485 (diff) |
KVM: MMU: only update unsync page in invlpg path
Only unsync pages need updated at invlpg time since other shadow
pages are write-protected
Signed-off-by: Xiao Guangrong <xiaoguangrong@cn.fujitsu.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
-rw-r--r-- | arch/x86/kvm/paging_tmpl.h | 8 |
1 files changed, 6 insertions, 2 deletions
diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h index 22f13797f521..0671d7a29c3c 100644 --- a/arch/x86/kvm/paging_tmpl.h +++ b/arch/x86/kvm/paging_tmpl.h | |||
@@ -461,6 +461,7 @@ out_unlock: | |||
461 | static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva) | 461 | static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva) |
462 | { | 462 | { |
463 | struct kvm_shadow_walk_iterator iterator; | 463 | struct kvm_shadow_walk_iterator iterator; |
464 | struct kvm_mmu_page *sp; | ||
464 | gpa_t pte_gpa = -1; | 465 | gpa_t pte_gpa = -1; |
465 | int level; | 466 | int level; |
466 | u64 *sptep; | 467 | u64 *sptep; |
@@ -472,10 +473,13 @@ static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva) | |||
472 | level = iterator.level; | 473 | level = iterator.level; |
473 | sptep = iterator.sptep; | 474 | sptep = iterator.sptep; |
474 | 475 | ||
476 | sp = page_header(__pa(sptep)); | ||
475 | if (is_last_spte(*sptep, level)) { | 477 | if (is_last_spte(*sptep, level)) { |
476 | struct kvm_mmu_page *sp = page_header(__pa(sptep)); | ||
477 | int offset, shift; | 478 | int offset, shift; |
478 | 479 | ||
480 | if (!sp->unsync) | ||
481 | break; | ||
482 | |||
479 | shift = PAGE_SHIFT - | 483 | shift = PAGE_SHIFT - |
480 | (PT_LEVEL_BITS - PT64_LEVEL_BITS) * level; | 484 | (PT_LEVEL_BITS - PT64_LEVEL_BITS) * level; |
481 | offset = sp->role.quadrant << shift; | 485 | offset = sp->role.quadrant << shift; |
@@ -493,7 +497,7 @@ static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva) | |||
493 | break; | 497 | break; |
494 | } | 498 | } |
495 | 499 | ||
496 | if (!is_shadow_present_pte(*sptep)) | 500 | if (!is_shadow_present_pte(*sptep) || !sp->unsync_children) |
497 | break; | 501 | break; |
498 | } | 502 | } |
499 | 503 | ||