According to section "Canonicalization and Consistency Checks" in APM vol 2, the following guest state is illegal: "The MSR or IOIO intercept tables extend to a physical address that is greater than or equal to the maximum supported physical address." Also check that these addresses are aligned on page boundary. Signed-off-by: Krish Sadhukhan <krish.sadhukhan@xxxxxxxxxx> --- arch/x86/kvm/svm/nested.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c index cb4c6ee10029..389a8108ddb5 100644 --- a/arch/x86/kvm/svm/nested.c +++ b/arch/x86/kvm/svm/nested.c @@ -211,8 +211,11 @@ static bool svm_get_nested_state_pages(struct kvm_vcpu *vcpu) return true; } -static bool nested_vmcb_check_controls(struct vmcb_control_area *control) +static bool nested_vmcb_check_controls(struct vcpu_svm *svm, + struct vmcb_control_area *control) { + int maxphyaddr; + if ((vmcb_is_intercept(control, INTERCEPT_VMRUN)) == 0) return false; @@ -223,6 +226,14 @@ static bool nested_vmcb_check_controls(struct vmcb_control_area *control) !npt_enabled) return false; + maxphyaddr = cpuid_maxphyaddr(&svm->vcpu); + if (!IS_ALIGNED(control->msrpm_base_pa, PAGE_SIZE) || + control->msrpm_base_pa >> maxphyaddr) + return false; + if (!IS_ALIGNED(control->iopm_base_pa, PAGE_SIZE) || + control->iopm_base_pa >> maxphyaddr) + return false; + return true; } @@ -258,7 +269,7 @@ static bool nested_vmcb_checks(struct vcpu_svm *svm, struct vmcb *vmcb12) if (!kvm_is_valid_cr4(&svm->vcpu, vmcb12->save.cr4)) return false; - return nested_vmcb_check_controls(&vmcb12->control); + return nested_vmcb_check_controls(svm, &vmcb12->control); } static void load_nested_vmcb_control(struct vcpu_svm *svm, @@ -1173,7 +1184,7 @@ static int svm_set_nested_state(struct kvm_vcpu *vcpu, goto out_free; ret = -EINVAL; - if (!nested_vmcb_check_controls(ctl)) + if (!nested_vmcb_check_controls(svm, ctl)) goto out_free; /* -- 2.27.0