diff options
author | Avi Kivity <avi@qumranet.com> | 2007-01-05 19:36:47 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.osdl.org> | 2007-01-06 02:55:25 -0500 |
commit | 5f015a5b28c75bb6cc5158640db58689b1ee1b51 (patch) | |
tree | 7b103d11d256bfc83c8cd61841cdb893d2b09617 /drivers/kvm | |
parent | ebeace8609205bf5e1b96fe325b7dea148042232 (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>
Diffstat (limited to 'drivers/kvm')
-rw-r--r-- | drivers/kvm/kvm.h | 1 | ||||
-rw-r--r-- | drivers/kvm/kvm_main.c | 4 | ||||
-rw-r--r-- | drivers/kvm/mmu.c | 43 | ||||
-rw-r--r-- | drivers/kvm/svm.c | 1 | ||||
-rw-r--r-- | drivers/kvm/vmx.c | 13 |
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; | |||
158 | struct kvm_mmu { | 158 | struct 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 | ||
944 | int emulate_invlpg(struct kvm_vcpu *vcpu, gva_t address) | 944 | int 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 | ||
770 | static void nonpaging_inval_page(struct kvm_vcpu *vcpu, gva_t addr) | ||
771 | { | ||
772 | } | ||
773 | |||
774 | static void nonpaging_free(struct kvm_vcpu *vcpu) | 770 | static 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 | */ | ||
901 | static 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 | |||
934 | static void paging_free(struct kvm_vcpu *vcpu) | 893 | static 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 | ||
1441 | static 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 | |||
1452 | static int handle_cr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | 1440 | static 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, |