mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-07-25 14:33:31 -04:00
KVM: SEV: Turn sev_es_validate_vmgexit() into a dedicated predicate
Now that sev_es_validate_vmgexit() is only responsible for checking that all required GHCB fields are marked valid, turn it into a predicate whose name reflects exactly that. No functional change intended. Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com> Reviewed-by: Michael Roth <michael.roth@amd.com> Signed-off-by: Sean Christopherson <seanjc@google.com> Message-ID: <20260501202250.2115252-24-seanjc@google.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Message-ID: <20260529183549.1104619-24-pbonzini@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
committed by
Paolo Bonzini
parent
b911484177
commit
abb97ac118
@@ -3410,7 +3410,7 @@ static void sev_es_sync_from_ghcb(struct vcpu_svm *svm)
|
||||
memset(ghcb->save.valid_bitmap, 0, sizeof(ghcb->save.valid_bitmap));
|
||||
}
|
||||
|
||||
static int sev_es_validate_vmgexit(struct vcpu_svm *svm)
|
||||
static bool sev_es_are_required_ghcb_fields_valid(struct vcpu_svm *svm)
|
||||
{
|
||||
struct vmcb_control_area *control = &svm->vmcb->control;
|
||||
struct kvm_vcpu *vcpu = &svm->vcpu;
|
||||
@@ -3418,92 +3418,53 @@ static int sev_es_validate_vmgexit(struct vcpu_svm *svm)
|
||||
if (!kvm_ghcb_sw_exit_code_is_valid(svm) ||
|
||||
!kvm_ghcb_sw_exit_info_1_is_valid(svm) ||
|
||||
!kvm_ghcb_sw_exit_info_2_is_valid(svm))
|
||||
goto vmgexit_err;
|
||||
return false;
|
||||
|
||||
switch (control->exit_code) {
|
||||
case SVM_EXIT_WRITE_DR7:
|
||||
if (!kvm_ghcb_rax_is_valid(svm))
|
||||
goto vmgexit_err;
|
||||
break;
|
||||
return kvm_ghcb_rax_is_valid(svm);
|
||||
case SVM_EXIT_RDPMC:
|
||||
if (!kvm_ghcb_rcx_is_valid(svm))
|
||||
goto vmgexit_err;
|
||||
break;
|
||||
return kvm_ghcb_rcx_is_valid(svm);
|
||||
case SVM_EXIT_CPUID:
|
||||
if (!kvm_ghcb_rax_is_valid(svm) ||
|
||||
!kvm_ghcb_rcx_is_valid(svm))
|
||||
goto vmgexit_err;
|
||||
if (vcpu->arch.regs[VCPU_REGS_RAX] == 0xd)
|
||||
if (!kvm_ghcb_xcr0_is_valid(svm))
|
||||
goto vmgexit_err;
|
||||
break;
|
||||
return false;
|
||||
|
||||
return vcpu->arch.regs[VCPU_REGS_RAX] != 0xd ||
|
||||
kvm_ghcb_xcr0_is_valid(svm);
|
||||
case SVM_EXIT_IOIO:
|
||||
if (control->exit_info_1 & SVM_IOIO_STR_MASK) {
|
||||
if (!kvm_ghcb_sw_scratch_is_valid(svm))
|
||||
goto vmgexit_err;
|
||||
} else {
|
||||
if (!(control->exit_info_1 & SVM_IOIO_TYPE_MASK))
|
||||
if (!kvm_ghcb_rax_is_valid(svm))
|
||||
goto vmgexit_err;
|
||||
}
|
||||
break;
|
||||
if (control->exit_info_1 & SVM_IOIO_STR_MASK)
|
||||
return kvm_ghcb_sw_scratch_is_valid(svm);
|
||||
|
||||
if (!(control->exit_info_1 & SVM_IOIO_TYPE_MASK))
|
||||
return kvm_ghcb_rax_is_valid(svm);
|
||||
|
||||
return true;
|
||||
case SVM_EXIT_MSR:
|
||||
if (!kvm_ghcb_rcx_is_valid(svm))
|
||||
goto vmgexit_err;
|
||||
if (control->exit_info_1) {
|
||||
if (!kvm_ghcb_rax_is_valid(svm) ||
|
||||
!kvm_ghcb_rdx_is_valid(svm))
|
||||
goto vmgexit_err;
|
||||
}
|
||||
break;
|
||||
return false;
|
||||
|
||||
return !control->exit_info_1 ||
|
||||
(kvm_ghcb_rax_is_valid(svm) && kvm_ghcb_rdx_is_valid(svm));
|
||||
case SVM_EXIT_VMMCALL:
|
||||
if (!kvm_ghcb_rax_is_valid(svm) ||
|
||||
!kvm_ghcb_cpl_is_valid(svm))
|
||||
goto vmgexit_err;
|
||||
break;
|
||||
return kvm_ghcb_rax_is_valid(svm) && kvm_ghcb_cpl_is_valid(svm);
|
||||
case SVM_EXIT_MONITOR:
|
||||
if (!kvm_ghcb_rax_is_valid(svm) ||
|
||||
!kvm_ghcb_rcx_is_valid(svm) ||
|
||||
!kvm_ghcb_rdx_is_valid(svm))
|
||||
goto vmgexit_err;
|
||||
break;
|
||||
return kvm_ghcb_rax_is_valid(svm) &&
|
||||
kvm_ghcb_rcx_is_valid(svm) &&
|
||||
kvm_ghcb_rdx_is_valid(svm);
|
||||
case SVM_EXIT_MWAIT:
|
||||
if (!kvm_ghcb_rax_is_valid(svm) ||
|
||||
!kvm_ghcb_rcx_is_valid(svm))
|
||||
goto vmgexit_err;
|
||||
return kvm_ghcb_rax_is_valid(svm) && kvm_ghcb_rcx_is_valid(svm);
|
||||
case SVM_VMGEXIT_AP_CREATION:
|
||||
return kvm_ghcb_rax_is_valid(svm) ||
|
||||
lower_32_bits(control->exit_info_1) == SVM_VMGEXIT_AP_DESTROY;
|
||||
break;
|
||||
case SVM_VMGEXIT_MMIO_READ:
|
||||
case SVM_VMGEXIT_MMIO_WRITE:
|
||||
if (!kvm_ghcb_sw_scratch_is_valid(svm))
|
||||
goto vmgexit_err;
|
||||
break;
|
||||
case SVM_VMGEXIT_AP_CREATION:
|
||||
if (lower_32_bits(control->exit_info_1) != SVM_VMGEXIT_AP_DESTROY)
|
||||
if (!kvm_ghcb_rax_is_valid(svm))
|
||||
goto vmgexit_err;
|
||||
break;
|
||||
case SVM_VMGEXIT_PSC:
|
||||
if (!kvm_ghcb_sw_scratch_is_valid(svm))
|
||||
goto vmgexit_err;
|
||||
break;
|
||||
return kvm_ghcb_sw_scratch_is_valid(svm);
|
||||
default:
|
||||
break;
|
||||
return true;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
vmgexit_err:
|
||||
/*
|
||||
* Print the exit code even though it may not be marked valid as it
|
||||
* could help with debugging.
|
||||
*/
|
||||
vcpu_unimpl(vcpu, "vmgexit: exit code %#llx input is not valid\n",
|
||||
control->exit_code);
|
||||
dump_ghcb(svm);
|
||||
svm_vmgexit_bad_input(svm, GHCB_ERR_MISSING_INPUT);
|
||||
|
||||
/* Resume the guest to "return" the error code. */
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void __sev_es_unmap_ghcb(struct vcpu_svm *svm)
|
||||
@@ -4510,9 +4471,17 @@ int sev_handle_vmgexit(struct kvm_vcpu *vcpu)
|
||||
return 1;
|
||||
}
|
||||
|
||||
ret = sev_es_validate_vmgexit(svm);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (!sev_es_are_required_ghcb_fields_valid(svm)) {
|
||||
/*
|
||||
* Print the exit code even though it may not be marked valid
|
||||
* as it could help with debugging.
|
||||
*/
|
||||
vcpu_unimpl(vcpu, "vmgexit: exit code %#llx input is not valid\n",
|
||||
control->exit_code);
|
||||
dump_ghcb(svm);
|
||||
svm_vmgexit_bad_input(svm, GHCB_ERR_MISSING_INPUT);
|
||||
return 1;
|
||||
}
|
||||
|
||||
svm_vmgexit_success(svm, 0);
|
||||
|
||||
@@ -4599,6 +4568,7 @@ int sev_handle_vmgexit(struct kvm_vcpu *vcpu)
|
||||
vcpu->run->system_event.type = KVM_SYSTEM_EVENT_SEV_TERM;
|
||||
vcpu->run->system_event.ndata = 1;
|
||||
vcpu->run->system_event.data[0] = control->ghcb_gpa;
|
||||
ret = 0;
|
||||
break;
|
||||
case SVM_VMGEXIT_PSC:
|
||||
ret = setup_vmgexit_scratch(svm, true, sizeof(struct psc_hdr));
|
||||
|
||||
Reference in New Issue
Block a user