KVM: nVMX: Verify VMCS shadowing VMCS link pointer
Intel SDM considers these checks to be part of "Checks on Guest Non-Register State". Note that it is legal for vmcs->vmcs_link_pointer to be -1ull when VMCS shadowing is enabled. In this case, any VMREAD/VMWRITE to shadowed-field sets the ALU flags for VMfailInvalid (i.e. CF=1). Signed-off-by: Liran Alon <liran.alon@oracle.com> Signed-off-by: Jim Mattson <jmattson@google.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Родитель
a8a7c02bf7
Коммит
f145d90d97
|
@ -11755,6 +11755,33 @@ static int check_vmentry_prereqs(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int nested_vmx_check_vmcs_link_ptr(struct kvm_vcpu *vcpu,
|
||||||
|
struct vmcs12 *vmcs12)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
struct page *page;
|
||||||
|
struct vmcs12 *shadow;
|
||||||
|
|
||||||
|
if (vmcs12->vmcs_link_pointer == -1ull)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!page_address_valid(vcpu, vmcs12->vmcs_link_pointer))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
page = kvm_vcpu_gpa_to_page(vcpu, vmcs12->vmcs_link_pointer);
|
||||||
|
if (is_error_page(page))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
r = 0;
|
||||||
|
shadow = kmap(page);
|
||||||
|
if (shadow->hdr.revision_id != VMCS12_REVISION ||
|
||||||
|
shadow->hdr.shadow_vmcs != nested_cpu_has_shadow_vmcs(vmcs12))
|
||||||
|
r = -EINVAL;
|
||||||
|
kunmap(page);
|
||||||
|
kvm_release_page_clean(page);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
static int check_vmentry_postreqs(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12,
|
static int check_vmentry_postreqs(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12,
|
||||||
u32 *exit_qual)
|
u32 *exit_qual)
|
||||||
{
|
{
|
||||||
|
@ -11766,8 +11793,7 @@ static int check_vmentry_postreqs(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12,
|
||||||
!nested_guest_cr4_valid(vcpu, vmcs12->guest_cr4))
|
!nested_guest_cr4_valid(vcpu, vmcs12->guest_cr4))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (!nested_cpu_has_shadow_vmcs(vmcs12) &&
|
if (nested_vmx_check_vmcs_link_ptr(vcpu, vmcs12)) {
|
||||||
vmcs12->vmcs_link_pointer != -1ull) {
|
|
||||||
*exit_qual = ENTRY_FAIL_VMCS_LINK_PTR;
|
*exit_qual = ENTRY_FAIL_VMCS_LINK_PTR;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче