diff options
author | Xiao Guangrong <xiaoguangrong@cn.fujitsu.com> | 2010-11-16 23:11:41 -0500 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2011-01-12 04:29:27 -0500 |
commit | e730b63cc083852551b092e1c93f0ef22c25f220 (patch) | |
tree | 9bd7c6a96f38e8fe925a6cac855e5aaa549985ba | |
parent | 49f481720438bbd0138218b0bcb494c3512a454f (diff) |
KVM: MMU: don't mark spte notrap if reserved bit set
If reserved bit is set, we need inject the #PF with PFEC.RSVD=1,
but shadow_notrap_nonpresent_pte injects #PF with PFEC.RSVD=0 only
Signed-off-by: Xiao Guangrong <xiaoguangrong@cn.fujitsu.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
-rw-r--r-- | arch/x86/kvm/paging_tmpl.h | 17 |
1 files changed, 11 insertions, 6 deletions
diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h index ba00eefa7bcd..590bf1223cb4 100644 --- a/arch/x86/kvm/paging_tmpl.h +++ b/arch/x86/kvm/paging_tmpl.h | |||
@@ -395,8 +395,10 @@ static void FNAME(pte_prefetch)(struct kvm_vcpu *vcpu, struct guest_walker *gw, | |||
395 | 395 | ||
396 | gpte = gptep[i]; | 396 | gpte = gptep[i]; |
397 | 397 | ||
398 | if (!is_present_gpte(gpte) || | 398 | if (is_rsvd_bits_set(mmu, gpte, PT_PAGE_TABLE_LEVEL)) |
399 | is_rsvd_bits_set(mmu, gpte, PT_PAGE_TABLE_LEVEL)) { | 399 | continue; |
400 | |||
401 | if (!is_present_gpte(gpte)) { | ||
400 | if (!sp->unsync) | 402 | if (!sp->unsync) |
401 | __set_spte(spte, shadow_notrap_nonpresent_pte); | 403 | __set_spte(spte, shadow_notrap_nonpresent_pte); |
402 | continue; | 404 | continue; |
@@ -760,6 +762,7 @@ static int FNAME(sync_page)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp, | |||
760 | pt_element_t gpte; | 762 | pt_element_t gpte; |
761 | gpa_t pte_gpa; | 763 | gpa_t pte_gpa; |
762 | gfn_t gfn; | 764 | gfn_t gfn; |
765 | bool rsvd_bits_set; | ||
763 | 766 | ||
764 | if (!is_shadow_present_pte(sp->spt[i])) | 767 | if (!is_shadow_present_pte(sp->spt[i])) |
765 | continue; | 768 | continue; |
@@ -771,12 +774,14 @@ static int FNAME(sync_page)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp, | |||
771 | return -EINVAL; | 774 | return -EINVAL; |
772 | 775 | ||
773 | gfn = gpte_to_gfn(gpte); | 776 | gfn = gpte_to_gfn(gpte); |
774 | if (is_rsvd_bits_set(&vcpu->arch.mmu, gpte, PT_PAGE_TABLE_LEVEL) | 777 | rsvd_bits_set = is_rsvd_bits_set(&vcpu->arch.mmu, gpte, |
775 | || gfn != sp->gfns[i] || !is_present_gpte(gpte) | 778 | PT_PAGE_TABLE_LEVEL); |
776 | || !(gpte & PT_ACCESSED_MASK)) { | 779 | if (rsvd_bits_set || gfn != sp->gfns[i] || |
780 | !is_present_gpte(gpte) || !(gpte & PT_ACCESSED_MASK)) { | ||
777 | u64 nonpresent; | 781 | u64 nonpresent; |
778 | 782 | ||
779 | if (is_present_gpte(gpte) || !clear_unsync) | 783 | if (rsvd_bits_set || is_present_gpte(gpte) || |
784 | !clear_unsync) | ||
780 | nonpresent = shadow_trap_nonpresent_pte; | 785 | nonpresent = shadow_trap_nonpresent_pte; |
781 | else | 786 | else |
782 | nonpresent = shadow_notrap_nonpresent_pte; | 787 | nonpresent = shadow_notrap_nonpresent_pte; |