1
0
Fork 0

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>
hifive-unleashed-5.1
Xiao Guangrong 2015-08-05 12:04:27 +08:00 committed by Paolo Bonzini
parent 47ab875169
commit f735d4af4b
3 changed files with 2 additions and 95 deletions

View File

@ -4939,28 +4939,6 @@ unsigned int kvm_mmu_calculate_mmu_pages(struct kvm *kvm)
return nr_mmu_pages;
}
int kvm_mmu_get_spte_hierarchy(struct kvm_vcpu *vcpu, u64 addr, u64 sptes[4])
{
struct kvm_shadow_walk_iterator iterator;
u64 spte;
int nr_sptes = 0;
if (!VALID_PAGE(vcpu->arch.mmu.root_hpa))
return nr_sptes;
walk_shadow_page_lockless_begin(vcpu);
for_each_shadow_entry_lockless(vcpu, addr, iterator, spte) {
sptes[iterator.level-1] = spte;
nr_sptes++;
if (!is_shadow_present_pte(spte))
break;
}
walk_shadow_page_lockless_end(vcpu);
return nr_sptes;
}
EXPORT_SYMBOL_GPL(kvm_mmu_get_spte_hierarchy);
void kvm_mmu_destroy(struct kvm_vcpu *vcpu)
{
kvm_mmu_unload(vcpu);

View File

@ -50,7 +50,6 @@ static inline u64 rsvd_bits(int s, int e)
return ((1ULL << (e - s + 1)) - 1) << s;
}
int kvm_mmu_get_spte_hierarchy(struct kvm_vcpu *vcpu, u64 addr, u64 sptes[4]);
void kvm_mmu_set_mmio_spte_mask(u64 mmio_mask);
void

View File

@ -5759,73 +5759,9 @@ static int handle_ept_violation(struct kvm_vcpu *vcpu)
return kvm_mmu_page_fault(vcpu, gpa, error_code, NULL, 0);
}
static u64 ept_rsvd_mask(u64 spte, int level)
{
int i;
u64 mask = 0;
for (i = 51; i > boot_cpu_data.x86_phys_bits; i--)
mask |= (1ULL << i);
if (level == 4)
/* bits 7:3 reserved */
mask |= 0xf8;
else if (spte & (1ULL << 7))
/*
* 1GB/2MB page, bits 29:12 or 20:12 reserved respectively,
* level == 1 if the hypervisor is using the ignored bit 7.
*/
mask |= (PAGE_SIZE << ((level - 1) * 9)) - PAGE_SIZE;
else if (level > 1)
/* bits 6:3 reserved */
mask |= 0x78;
return mask;
}
static void ept_misconfig_inspect_spte(struct kvm_vcpu *vcpu, u64 spte,
int level)
{
printk(KERN_ERR "%s: spte 0x%llx level %d\n", __func__, spte, level);
/* 010b (write-only) */
WARN_ON((spte & 0x7) == 0x2);
/* 110b (write/execute) */
WARN_ON((spte & 0x7) == 0x6);
/* 100b (execute-only) and value not supported by logical processor */
if (!cpu_has_vmx_ept_execute_only())
WARN_ON((spte & 0x7) == 0x4);
/* not 000b */
if ((spte & 0x7)) {
u64 rsvd_bits = spte & ept_rsvd_mask(spte, level);
if (rsvd_bits != 0) {
printk(KERN_ERR "%s: rsvd_bits = 0x%llx\n",
__func__, rsvd_bits);
WARN_ON(1);
}
/* bits 5:3 are _not_ reserved for large page or leaf page */
if ((rsvd_bits & 0x38) == 0) {
u64 ept_mem_type = (spte & 0x38) >> 3;
if (ept_mem_type == 2 || ept_mem_type == 3 ||
ept_mem_type == 7) {
printk(KERN_ERR "%s: ept_mem_type=0x%llx\n",
__func__, ept_mem_type);
WARN_ON(1);
}
}
}
}
static int handle_ept_misconfig(struct kvm_vcpu *vcpu)
{
u64 sptes[4];
int nr_sptes, i, ret;
int ret;
gpa_t gpa;
gpa = vmcs_read64(GUEST_PHYSICAL_ADDRESS);
@ -5846,13 +5782,7 @@ static int handle_ept_misconfig(struct kvm_vcpu *vcpu)
return 1;
/* It is the real ept misconfig */
printk(KERN_ERR "EPT: Misconfiguration.\n");
printk(KERN_ERR "EPT: GPA: 0x%llx\n", gpa);
nr_sptes = kvm_mmu_get_spte_hierarchy(vcpu, gpa, sptes);
for (i = PT64_ROOT_LEVEL; i > PT64_ROOT_LEVEL - nr_sptes; --i)
ept_misconfig_inspect_spte(vcpu, sptes[i-1], i);
WARN_ON(1);
vcpu->run->exit_reason = KVM_EXIT_UNKNOWN;
vcpu->run->hw.hardware_exit_reason = EXIT_REASON_EPT_MISCONFIG;