aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAvi Kivity <avi@qumranet.com>2007-01-05 19:36:47 -0500
committerLinus Torvalds <torvalds@woody.osdl.org>2007-01-06 02:55:25 -0500
commit5f015a5b28c75bb6cc5158640db58689b1ee1b51 (patch)
tree7b103d11d256bfc83c8cd61841cdb893d2b09617
parentebeace8609205bf5e1b96fe325b7dea148042232 (diff)
[PATCH] KVM: MMU: Remove invlpg interception
Since we write protect shadowed guest page tables, there is no need to trap page invalidations (the guest will always change the mapping before issuing the invlpg instruction). Signed-off-by: Avi Kivity <avi@qumranet.com> Acked-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--drivers/kvm/kvm.h1
-rw-r--r--drivers/kvm/kvm_main.c4
-rw-r--r--drivers/kvm/mmu.c43
-rw-r--r--drivers/kvm/svm.c1
-rw-r--r--drivers/kvm/vmx.c13
5 files changed, 0 insertions, 62 deletions
diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
index 1d0be85651f5..6e4daf404146 100644
--- a/drivers/kvm/kvm.h
+++ b/drivers/kvm/kvm.h
@@ -158,7 +158,6 @@ struct kvm_vcpu;
158struct kvm_mmu { 158struct kvm_mmu {
159 void (*new_cr3)(struct kvm_vcpu *vcpu); 159 void (*new_cr3)(struct kvm_vcpu *vcpu);
160 int (*page_fault)(struct kvm_vcpu *vcpu, gva_t gva, u32 err); 160 int (*page_fault)(struct kvm_vcpu *vcpu, gva_t gva, u32 err);
161 void (*inval_page)(struct kvm_vcpu *vcpu, gva_t gva);
162 void (*free)(struct kvm_vcpu *vcpu); 161 void (*free)(struct kvm_vcpu *vcpu);
163 gpa_t (*gva_to_gpa)(struct kvm_vcpu *vcpu, gva_t gva); 162 gpa_t (*gva_to_gpa)(struct kvm_vcpu *vcpu, gva_t gva);
164 hpa_t root_hpa; 163 hpa_t root_hpa;
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index 79032438dd16..cec10106ce77 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -943,10 +943,6 @@ static unsigned long get_segment_base(struct kvm_vcpu *vcpu, int seg)
943 943
944int emulate_invlpg(struct kvm_vcpu *vcpu, gva_t address) 944int emulate_invlpg(struct kvm_vcpu *vcpu, gva_t address)
945{ 945{
946 spin_lock(&vcpu->kvm->lock);
947 vcpu->mmu.inval_page(vcpu, address);
948 spin_unlock(&vcpu->kvm->lock);
949 kvm_arch_ops->invlpg(vcpu, address);
950 return X86EMUL_CONTINUE; 946 return X86EMUL_CONTINUE;
951} 947}
952 948
diff --git a/drivers/kvm/mmu.c b/drivers/kvm/mmu.c
index e4a20a45d834..b7b05c44399d 100644
--- a/drivers/kvm/mmu.c
+++ b/drivers/kvm/mmu.c
@@ -767,10 +767,6 @@ static int nonpaging_page_fault(struct kvm_vcpu *vcpu, gva_t gva,
767 return nonpaging_map(vcpu, addr & PAGE_MASK, paddr); 767 return nonpaging_map(vcpu, addr & PAGE_MASK, paddr);
768} 768}
769 769
770static void nonpaging_inval_page(struct kvm_vcpu *vcpu, gva_t addr)
771{
772}
773
774static void nonpaging_free(struct kvm_vcpu *vcpu) 770static void nonpaging_free(struct kvm_vcpu *vcpu)
775{ 771{
776 mmu_free_roots(vcpu); 772 mmu_free_roots(vcpu);
@@ -782,7 +778,6 @@ static int nonpaging_init_context(struct kvm_vcpu *vcpu)
782 778
783 context->new_cr3 = nonpaging_new_cr3; 779 context->new_cr3 = nonpaging_new_cr3;
784 context->page_fault = nonpaging_page_fault; 780 context->page_fault = nonpaging_page_fault;
785 context->inval_page = nonpaging_inval_page;
786 context->gva_to_gpa = nonpaging_gva_to_gpa; 781 context->gva_to_gpa = nonpaging_gva_to_gpa;
787 context->free = nonpaging_free; 782 context->free = nonpaging_free;
788 context->root_level = 0; 783 context->root_level = 0;
@@ -895,42 +890,6 @@ static int may_access(u64 pte, int write, int user)
895 return 1; 890 return 1;
896} 891}
897 892
898/*
899 * Remove a shadow pte.
900 */
901static void paging_inval_page(struct kvm_vcpu *vcpu, gva_t addr)
902{
903 hpa_t page_addr = vcpu->mmu.root_hpa;
904 int level = vcpu->mmu.shadow_root_level;
905
906 ++kvm_stat.invlpg;
907
908 for (; ; level--) {
909 u32 index = PT64_INDEX(addr, level);
910 u64 *table = __va(page_addr);
911
912 if (level == PT_PAGE_TABLE_LEVEL ) {
913 rmap_remove(vcpu->kvm, &table[index]);
914 table[index] = 0;
915 return;
916 }
917
918 if (!is_present_pte(table[index]))
919 return;
920
921 page_addr = table[index] & PT64_BASE_ADDR_MASK;
922
923 if (level == PT_DIRECTORY_LEVEL &&
924 (table[index] & PT_SHADOW_PS_MARK)) {
925 table[index] = 0;
926 release_pt_page_64(vcpu, page_addr, PT_PAGE_TABLE_LEVEL);
927
928 kvm_arch_ops->tlb_flush(vcpu);
929 return;
930 }
931 }
932}
933
934static void paging_free(struct kvm_vcpu *vcpu) 893static void paging_free(struct kvm_vcpu *vcpu)
935{ 894{
936 nonpaging_free(vcpu); 895 nonpaging_free(vcpu);
@@ -951,7 +910,6 @@ static int paging64_init_context_common(struct kvm_vcpu *vcpu, int level)
951 ASSERT(is_pae(vcpu)); 910 ASSERT(is_pae(vcpu));
952 context->new_cr3 = paging_new_cr3; 911 context->new_cr3 = paging_new_cr3;
953 context->page_fault = paging64_page_fault; 912 context->page_fault = paging64_page_fault;
954 context->inval_page = paging_inval_page;
955 context->gva_to_gpa = paging64_gva_to_gpa; 913 context->gva_to_gpa = paging64_gva_to_gpa;
956 context->free = paging_free; 914 context->free = paging_free;
957 context->root_level = level; 915 context->root_level = level;
@@ -974,7 +932,6 @@ static int paging32_init_context(struct kvm_vcpu *vcpu)
974 932
975 context->new_cr3 = paging_new_cr3; 933 context->new_cr3 = paging_new_cr3;
976 context->page_fault = paging32_page_fault; 934 context->page_fault = paging32_page_fault;
977 context->inval_page = paging_inval_page;
978 context->gva_to_gpa = paging32_gva_to_gpa; 935 context->gva_to_gpa = paging32_gva_to_gpa;
979 context->free = paging_free; 936 context->free = paging_free;
980 context->root_level = PT32_ROOT_LEVEL; 937 context->root_level = PT32_ROOT_LEVEL;
diff --git a/drivers/kvm/svm.c b/drivers/kvm/svm.c
index 869b524dda6b..99250011a471 100644
--- a/drivers/kvm/svm.c
+++ b/drivers/kvm/svm.c
@@ -497,7 +497,6 @@ static void init_vmcb(struct vmcb *vmcb)
497 /* (1ULL << INTERCEPT_SELECTIVE_CR0) | */ 497 /* (1ULL << INTERCEPT_SELECTIVE_CR0) | */
498 (1ULL << INTERCEPT_CPUID) | 498 (1ULL << INTERCEPT_CPUID) |
499 (1ULL << INTERCEPT_HLT) | 499 (1ULL << INTERCEPT_HLT) |
500 (1ULL << INTERCEPT_INVLPG) |
501 (1ULL << INTERCEPT_INVLPGA) | 500 (1ULL << INTERCEPT_INVLPGA) |
502 (1ULL << INTERCEPT_IOIO_PROT) | 501 (1ULL << INTERCEPT_IOIO_PROT) |
503 (1ULL << INTERCEPT_MSR_PROT) | 502 (1ULL << INTERCEPT_MSR_PROT) |
diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c
index 2a1c37eed711..59178ad4d344 100644
--- a/drivers/kvm/vmx.c
+++ b/drivers/kvm/vmx.c
@@ -1059,7 +1059,6 @@ static int vmx_vcpu_setup(struct kvm_vcpu *vcpu)
1059 | CPU_BASED_CR8_LOAD_EXITING /* 20.6.2 */ 1059 | CPU_BASED_CR8_LOAD_EXITING /* 20.6.2 */
1060 | CPU_BASED_CR8_STORE_EXITING /* 20.6.2 */ 1060 | CPU_BASED_CR8_STORE_EXITING /* 20.6.2 */
1061 | CPU_BASED_UNCOND_IO_EXITING /* 20.6.2 */ 1061 | CPU_BASED_UNCOND_IO_EXITING /* 20.6.2 */
1062 | CPU_BASED_INVDPG_EXITING
1063 | CPU_BASED_MOV_DR_EXITING 1062 | CPU_BASED_MOV_DR_EXITING
1064 | CPU_BASED_USE_TSC_OFFSETING /* 21.3 */ 1063 | CPU_BASED_USE_TSC_OFFSETING /* 21.3 */
1065 ); 1064 );
@@ -1438,17 +1437,6 @@ static int handle_io(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
1438 return 0; 1437 return 0;
1439} 1438}
1440 1439
1441static int handle_invlpg(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
1442{
1443 u64 address = vmcs_read64(EXIT_QUALIFICATION);
1444 int instruction_length = vmcs_read32(VM_EXIT_INSTRUCTION_LEN);
1445 spin_lock(&vcpu->kvm->lock);
1446 vcpu->mmu.inval_page(vcpu, address);
1447 spin_unlock(&vcpu->kvm->lock);
1448 vmcs_writel(GUEST_RIP, vmcs_readl(GUEST_RIP) + instruction_length);
1449 return 1;
1450}
1451
1452static int handle_cr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) 1440static int handle_cr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
1453{ 1441{
1454 u64 exit_qualification; 1442 u64 exit_qualification;
@@ -1636,7 +1624,6 @@ static int (*kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu,
1636 [EXIT_REASON_EXCEPTION_NMI] = handle_exception, 1624 [EXIT_REASON_EXCEPTION_NMI] = handle_exception,
1637 [EXIT_REASON_EXTERNAL_INTERRUPT] = handle_external_interrupt, 1625 [EXIT_REASON_EXTERNAL_INTERRUPT] = handle_external_interrupt,
1638 [EXIT_REASON_IO_INSTRUCTION] = handle_io, 1626 [EXIT_REASON_IO_INSTRUCTION] = handle_io,
1639 [EXIT_REASON_INVLPG] = handle_invlpg,
1640 [EXIT_REASON_CR_ACCESS] = handle_cr, 1627 [EXIT_REASON_CR_ACCESS] = handle_cr,
1641 [EXIT_REASON_DR_ACCESS] = handle_dr, 1628 [EXIT_REASON_DR_ACCESS] = handle_dr,
1642 [EXIT_REASON_CPUID] = handle_cpuid, 1629 [EXIT_REASON_CPUID] = handle_cpuid,