diff options
Diffstat (limited to 'arch/x86/kvm/paging_tmpl.h')
| -rw-r--r-- | arch/x86/kvm/paging_tmpl.h | 22 |
1 files changed, 3 insertions, 19 deletions
diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h index a6017132fba8..ede2131a9225 100644 --- a/arch/x86/kvm/paging_tmpl.h +++ b/arch/x86/kvm/paging_tmpl.h | |||
| @@ -150,7 +150,9 @@ walk: | |||
| 150 | walker->table_gfn[walker->level - 1] = table_gfn; | 150 | walker->table_gfn[walker->level - 1] = table_gfn; |
| 151 | walker->pte_gpa[walker->level - 1] = pte_gpa; | 151 | walker->pte_gpa[walker->level - 1] = pte_gpa; |
| 152 | 152 | ||
| 153 | kvm_read_guest(vcpu->kvm, pte_gpa, &pte, sizeof(pte)); | 153 | if (kvm_read_guest(vcpu->kvm, pte_gpa, &pte, sizeof(pte))) |
| 154 | goto not_present; | ||
| 155 | |||
| 154 | trace_kvm_mmu_paging_element(pte, walker->level); | 156 | trace_kvm_mmu_paging_element(pte, walker->level); |
| 155 | 157 | ||
| 156 | if (!is_present_gpte(pte)) | 158 | if (!is_present_gpte(pte)) |
| @@ -455,8 +457,6 @@ out_unlock: | |||
| 455 | static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva) | 457 | static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva) |
| 456 | { | 458 | { |
| 457 | struct kvm_shadow_walk_iterator iterator; | 459 | struct kvm_shadow_walk_iterator iterator; |
| 458 | pt_element_t gpte; | ||
| 459 | gpa_t pte_gpa = -1; | ||
| 460 | int level; | 460 | int level; |
| 461 | u64 *sptep; | 461 | u64 *sptep; |
| 462 | int need_flush = 0; | 462 | int need_flush = 0; |
| @@ -470,10 +470,6 @@ static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva) | |||
| 470 | if (level == PT_PAGE_TABLE_LEVEL || | 470 | if (level == PT_PAGE_TABLE_LEVEL || |
| 471 | ((level == PT_DIRECTORY_LEVEL && is_large_pte(*sptep))) || | 471 | ((level == PT_DIRECTORY_LEVEL && is_large_pte(*sptep))) || |
| 472 | ((level == PT_PDPE_LEVEL && is_large_pte(*sptep)))) { | 472 | ((level == PT_PDPE_LEVEL && is_large_pte(*sptep)))) { |
| 473 | struct kvm_mmu_page *sp = page_header(__pa(sptep)); | ||
| 474 | |||
| 475 | pte_gpa = (sp->gfn << PAGE_SHIFT); | ||
| 476 | pte_gpa += (sptep - sp->spt) * sizeof(pt_element_t); | ||
| 477 | 473 | ||
| 478 | if (is_shadow_present_pte(*sptep)) { | 474 | if (is_shadow_present_pte(*sptep)) { |
| 479 | rmap_remove(vcpu->kvm, sptep); | 475 | rmap_remove(vcpu->kvm, sptep); |
| @@ -492,18 +488,6 @@ static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva) | |||
| 492 | if (need_flush) | 488 | if (need_flush) |
| 493 | kvm_flush_remote_tlbs(vcpu->kvm); | 489 | kvm_flush_remote_tlbs(vcpu->kvm); |
| 494 | spin_unlock(&vcpu->kvm->mmu_lock); | 490 | spin_unlock(&vcpu->kvm->mmu_lock); |
| 495 | |||
| 496 | if (pte_gpa == -1) | ||
| 497 | return; | ||
| 498 | if (kvm_read_guest_atomic(vcpu->kvm, pte_gpa, &gpte, | ||
| 499 | sizeof(pt_element_t))) | ||
| 500 | return; | ||
| 501 | if (is_present_gpte(gpte) && (gpte & PT_ACCESSED_MASK)) { | ||
| 502 | if (mmu_topup_memory_caches(vcpu)) | ||
| 503 | return; | ||
| 504 | kvm_mmu_pte_write(vcpu, pte_gpa, (const u8 *)&gpte, | ||
| 505 | sizeof(pt_element_t), 0); | ||
| 506 | } | ||
| 507 | } | 491 | } |
| 508 | 492 | ||
| 509 | static gpa_t FNAME(gva_to_gpa)(struct kvm_vcpu *vcpu, gva_t vaddr) | 493 | static gpa_t FNAME(gva_to_gpa)(struct kvm_vcpu *vcpu, gva_t vaddr) |
