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>
This commit is contained in:
parent
47ab875169
commit
f735d4af4b
@ -4939,28 +4939,6 @@ unsigned int kvm_mmu_calculate_mmu_pages(struct kvm *kvm)
|
|||||||
return nr_mmu_pages;
|
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)
|
void kvm_mmu_destroy(struct kvm_vcpu *vcpu)
|
||||||
{
|
{
|
||||||
kvm_mmu_unload(vcpu);
|
kvm_mmu_unload(vcpu);
|
||||||
|
@ -50,7 +50,6 @@ static inline u64 rsvd_bits(int s, int e)
|
|||||||
return ((1ULL << (e - s + 1)) - 1) << s;
|
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 kvm_mmu_set_mmio_spte_mask(u64 mmio_mask);
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -5759,73 +5759,9 @@ static int handle_ept_violation(struct kvm_vcpu *vcpu)
|
|||||||
return kvm_mmu_page_fault(vcpu, gpa, error_code, NULL, 0);
|
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)
|
static int handle_ept_misconfig(struct kvm_vcpu *vcpu)
|
||||||
{
|
{
|
||||||
u64 sptes[4];
|
int ret;
|
||||||
int nr_sptes, i, ret;
|
|
||||||
gpa_t gpa;
|
gpa_t gpa;
|
||||||
|
|
||||||
gpa = vmcs_read64(GUEST_PHYSICAL_ADDRESS);
|
gpa = vmcs_read64(GUEST_PHYSICAL_ADDRESS);
|
||||||
@ -5846,13 +5782,7 @@ static int handle_ept_misconfig(struct kvm_vcpu *vcpu)
|
|||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
/* It is the real ept misconfig */
|
/* It is the real ept misconfig */
|
||||||
printk(KERN_ERR "EPT: Misconfiguration.\n");
|
WARN_ON(1);
|
||||||
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);
|
|
||||||
|
|
||||||
vcpu->run->exit_reason = KVM_EXIT_UNKNOWN;
|
vcpu->run->exit_reason = KVM_EXIT_UNKNOWN;
|
||||||
vcpu->run->hw.hardware_exit_reason = EXIT_REASON_EPT_MISCONFIG;
|
vcpu->run->hw.hardware_exit_reason = EXIT_REASON_EPT_MISCONFIG;
|
||||||
|
Loading…
Reference in New Issue
Block a user