mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-10 11:40:19 -04:00
KVM: x86: Add function for vectoring error generation
Extract VMX code for unhandleable VM-Exit during vectoring into vendor-agnostic function so that boiler-plate code can be shared by SVM. To avoid unnecessarily complexity in the helper, unconditionally report a GPA to userspace instead of having a conditional entry. For exits that don't report a GPA, i.e. everything except EPT Misconfig, simply report KVM's "invalid GPA". Signed-off-by: Ivan Orlov <iorlov@amazon.com> Link: https://lore.kernel.org/r/20241217181458.68690-2-iorlov@amazon.com [sean: clarify that the INVALID_GPA logic is new] Signed-off-by: Sean Christopherson <seanjc@google.com>
This commit is contained in:
committed by
Sean Christopherson
parent
871ac338ef
commit
11c98fa07a
@@ -2075,6 +2075,8 @@ void __kvm_prepare_emulation_failure_exit(struct kvm_vcpu *vcpu,
|
||||
u64 *data, u8 ndata);
|
||||
void kvm_prepare_emulation_failure_exit(struct kvm_vcpu *vcpu);
|
||||
|
||||
void kvm_prepare_event_vectoring_exit(struct kvm_vcpu *vcpu, gpa_t gpa);
|
||||
|
||||
void kvm_enable_efer_bits(u64);
|
||||
bool kvm_valid_efer(struct kvm_vcpu *vcpu, u64 efer);
|
||||
int kvm_get_msr_with_filter(struct kvm_vcpu *vcpu, u32 index, u64 *data);
|
||||
|
||||
@@ -6554,19 +6554,12 @@ static int __vmx_handle_exit(struct kvm_vcpu *vcpu, fastpath_t exit_fastpath)
|
||||
exit_reason.basic != EXIT_REASON_APIC_ACCESS &&
|
||||
exit_reason.basic != EXIT_REASON_TASK_SWITCH &&
|
||||
exit_reason.basic != EXIT_REASON_NOTIFY)) {
|
||||
int ndata = 3;
|
||||
gpa_t gpa = INVALID_GPA;
|
||||
|
||||
vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
|
||||
vcpu->run->internal.suberror = KVM_INTERNAL_ERROR_DELIVERY_EV;
|
||||
vcpu->run->internal.data[0] = vectoring_info;
|
||||
vcpu->run->internal.data[1] = exit_reason.full;
|
||||
vcpu->run->internal.data[2] = vmx_get_exit_qual(vcpu);
|
||||
if (exit_reason.basic == EXIT_REASON_EPT_MISCONFIG) {
|
||||
vcpu->run->internal.data[ndata++] =
|
||||
vmcs_read64(GUEST_PHYSICAL_ADDRESS);
|
||||
}
|
||||
vcpu->run->internal.data[ndata++] = vcpu->arch.last_vmentry_cpu;
|
||||
vcpu->run->internal.ndata = ndata;
|
||||
if (exit_reason.basic == EXIT_REASON_EPT_MISCONFIG)
|
||||
gpa = vmcs_read64(GUEST_PHYSICAL_ADDRESS);
|
||||
|
||||
kvm_prepare_event_vectoring_exit(vcpu, gpa);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -8804,6 +8804,28 @@ void kvm_prepare_emulation_failure_exit(struct kvm_vcpu *vcpu)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(kvm_prepare_emulation_failure_exit);
|
||||
|
||||
void kvm_prepare_event_vectoring_exit(struct kvm_vcpu *vcpu, gpa_t gpa)
|
||||
{
|
||||
u32 reason, intr_info, error_code;
|
||||
struct kvm_run *run = vcpu->run;
|
||||
u64 info1, info2;
|
||||
int ndata = 0;
|
||||
|
||||
kvm_x86_call(get_exit_info)(vcpu, &reason, &info1, &info2,
|
||||
&intr_info, &error_code);
|
||||
|
||||
run->internal.data[ndata++] = info2;
|
||||
run->internal.data[ndata++] = reason;
|
||||
run->internal.data[ndata++] = info1;
|
||||
run->internal.data[ndata++] = gpa;
|
||||
run->internal.data[ndata++] = vcpu->arch.last_vmentry_cpu;
|
||||
|
||||
run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
|
||||
run->internal.suberror = KVM_INTERNAL_ERROR_DELIVERY_EV;
|
||||
run->internal.ndata = ndata;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(kvm_prepare_event_vectoring_exit);
|
||||
|
||||
static int handle_emulation_failure(struct kvm_vcpu *vcpu, int emulation_type)
|
||||
{
|
||||
struct kvm *kvm = vcpu->kvm;
|
||||
|
||||
Reference in New Issue
Block a user