aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorXiao Guangrong <guangrong.xiao@linux.intel.com>2015-08-05 00:04:27 -0400
committerPaolo Bonzini <pbonzini@redhat.com>2015-08-05 06:47:26 -0400
commitf735d4af4b0ec3d87885710adf18b077480e7b19 (patch)
tree700a0b8ea19a52fcb7400a2855ebacde9072d21c
parent47ab8751695f71d85562ff497e21b521c789247c (diff)
KVM: VMX: drop ept misconfig check
The logic used to check ept misconfig is completely contained in common reserved bits check for sptes, so it can be removed Signed-off-by: Xiao Guangrong <guangrong.xiao@linux.intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r--arch/x86/kvm/mmu.c22
-rw-r--r--arch/x86/kvm/mmu.h1
-rw-r--r--arch/x86/kvm/vmx.c74
3 files changed, 2 insertions, 95 deletions
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index dfa3cee2aa10..fb16a8ea3dee 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -4939,28 +4939,6 @@ unsigned int kvm_mmu_calculate_mmu_pages(struct kvm *kvm)
4939 return nr_mmu_pages; 4939 return nr_mmu_pages;
4940} 4940}
4941 4941
4942int kvm_mmu_get_spte_hierarchy(struct kvm_vcpu *vcpu, u64 addr, u64 sptes[4])
4943{
4944 struct kvm_shadow_walk_iterator iterator;
4945 u64 spte;
4946 int nr_sptes = 0;
4947
4948 if (!VALID_PAGE(vcpu->arch.mmu.root_hpa))
4949 return nr_sptes;
4950
4951 walk_shadow_page_lockless_begin(vcpu);
4952 for_each_shadow_entry_lockless(vcpu, addr, iterator, spte) {
4953 sptes[iterator.level-1] = spte;
4954 nr_sptes++;
4955 if (!is_shadow_present_pte(spte))
4956 break;
4957 }
4958 walk_shadow_page_lockless_end(vcpu);
4959
4960 return nr_sptes;
4961}
4962EXPORT_SYMBOL_GPL(kvm_mmu_get_spte_hierarchy);
4963
4964void kvm_mmu_destroy(struct kvm_vcpu *vcpu) 4942void kvm_mmu_destroy(struct kvm_vcpu *vcpu)
4965{ 4943{
4966 kvm_mmu_unload(vcpu); 4944 kvm_mmu_unload(vcpu);
diff --git a/arch/x86/kvm/mmu.h b/arch/x86/kvm/mmu.h
index 2299d15c91dc..e4202e41d535 100644
--- a/arch/x86/kvm/mmu.h
+++ b/arch/x86/kvm/mmu.h
@@ -50,7 +50,6 @@ static inline u64 rsvd_bits(int s, int e)
50 return ((1ULL << (e - s + 1)) - 1) << s; 50 return ((1ULL << (e - s + 1)) - 1) << s;
51} 51}
52 52
53int kvm_mmu_get_spte_hierarchy(struct kvm_vcpu *vcpu, u64 addr, u64 sptes[4]);
54void kvm_mmu_set_mmio_spte_mask(u64 mmio_mask); 53void kvm_mmu_set_mmio_spte_mask(u64 mmio_mask);
55 54
56void 55void
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 4014a82ae846..37eae551857c 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -5759,73 +5759,9 @@ static int handle_ept_violation(struct kvm_vcpu *vcpu)
5759 return kvm_mmu_page_fault(vcpu, gpa, error_code, NULL, 0); 5759 return kvm_mmu_page_fault(vcpu, gpa, error_code, NULL, 0);
5760} 5760}
5761 5761
5762static u64 ept_rsvd_mask(u64 spte, int level)
5763{
5764 int i;
5765 u64 mask = 0;
5766
5767 for (i = 51; i > boot_cpu_data.x86_phys_bits; i--)
5768 mask |= (1ULL << i);
5769
5770 if (level == 4)
5771 /* bits 7:3 reserved */
5772 mask |= 0xf8;
5773 else if (spte & (1ULL << 7))
5774 /*
5775 * 1GB/2MB page, bits 29:12 or 20:12 reserved respectively,
5776 * level == 1 if the hypervisor is using the ignored bit 7.
5777 */
5778 mask |= (PAGE_SIZE << ((level - 1) * 9)) - PAGE_SIZE;
5779 else if (level > 1)
5780 /* bits 6:3 reserved */
5781 mask |= 0x78;
5782
5783 return mask;
5784}
5785
5786static void ept_misconfig_inspect_spte(struct kvm_vcpu *vcpu, u64 spte,
5787 int level)
5788{
5789 printk(KERN_ERR "%s: spte 0x%llx level %d\n", __func__, spte, level);
5790
5791 /* 010b (write-only) */
5792 WARN_ON((spte & 0x7) == 0x2);
5793
5794 /* 110b (write/execute) */
5795 WARN_ON((spte & 0x7) == 0x6);
5796
5797 /* 100b (execute-only) and value not supported by logical processor */
5798 if (!cpu_has_vmx_ept_execute_only())
5799 WARN_ON((spte & 0x7) == 0x4);
5800
5801 /* not 000b */
5802 if ((spte & 0x7)) {
5803 u64 rsvd_bits = spte & ept_rsvd_mask(spte, level);
5804
5805 if (rsvd_bits != 0) {
5806 printk(KERN_ERR "%s: rsvd_bits = 0x%llx\n",
5807 __func__, rsvd_bits);
5808 WARN_ON(1);
5809 }
5810
5811 /* bits 5:3 are _not_ reserved for large page or leaf page */
5812 if ((rsvd_bits & 0x38) == 0) {
5813 u64 ept_mem_type = (spte & 0x38) >> 3;
5814
5815 if (ept_mem_type == 2 || ept_mem_type == 3 ||
5816 ept_mem_type == 7) {
5817 printk(KERN_ERR "%s: ept_mem_type=0x%llx\n",
5818 __func__, ept_mem_type);
5819 WARN_ON(1);
5820 }
5821 }
5822 }
5823}
5824
5825static int handle_ept_misconfig(struct kvm_vcpu *vcpu) 5762static int handle_ept_misconfig(struct kvm_vcpu *vcpu)
5826{ 5763{
5827 u64 sptes[4]; 5764 int ret;
5828 int nr_sptes, i, ret;
5829 gpa_t gpa; 5765 gpa_t gpa;
5830 5766
5831 gpa = vmcs_read64(GUEST_PHYSICAL_ADDRESS); 5767 gpa = vmcs_read64(GUEST_PHYSICAL_ADDRESS);
@@ -5846,13 +5782,7 @@ static int handle_ept_misconfig(struct kvm_vcpu *vcpu)
5846 return 1; 5782 return 1;
5847 5783
5848 /* It is the real ept misconfig */ 5784 /* It is the real ept misconfig */
5849 printk(KERN_ERR "EPT: Misconfiguration.\n"); 5785 WARN_ON(1);
5850 printk(KERN_ERR "EPT: GPA: 0x%llx\n", gpa);
5851
5852 nr_sptes = kvm_mmu_get_spte_hierarchy(vcpu, gpa, sptes);
5853
5854 for (i = PT64_ROOT_LEVEL; i > PT64_ROOT_LEVEL - nr_sptes; --i)
5855 ept_misconfig_inspect_spte(vcpu, sptes[i-1], i);
5856 5786
5857 vcpu->run->exit_reason = KVM_EXIT_UNKNOWN; 5787 vcpu->run->exit_reason = KVM_EXIT_UNKNOWN;
5858 vcpu->run->hw.hardware_exit_reason = EXIT_REASON_EPT_MISCONFIG; 5788 vcpu->run->hw.hardware_exit_reason = EXIT_REASON_EPT_MISCONFIG;