Commit 4580dbef authored by Paolo Bonzini's avatar Paolo Bonzini
Browse files

KVM: TDX: Exit to userspace for SetupEventNotifyInterrupt

parent 25e8b1dd
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -7196,6 +7196,10 @@ The valid value for 'flags' is:
					u64 leaf;
					u64 r11, r12, r13, r14;
				} get_tdvmcall_info;
				struct {
					u64 ret;
					u64 vector;
				} setup_event_notify;
			};
		} tdx;

@@ -7226,6 +7230,9 @@ status of TDVMCALLs. The output values for the given leaf should be
placed in fields from ``r11`` to ``r14`` of the ``get_tdvmcall_info``
field of the union.

* ``TDVMCALL_SETUP_EVENT_NOTIFY_INTERRUPT``: the guest has requested to
set up a notification interrupt for vector ``vector``.

KVM may add support for more values in the future that may cause a userspace
exit, even without calls to ``KVM_ENABLE_CAP`` or similar.  In this case,
it will enter with output fields already valid; in the common case, the
+1 −0
Original line number Diff line number Diff line
@@ -72,6 +72,7 @@
#define TDVMCALL_MAP_GPA		0x10001
#define TDVMCALL_GET_QUOTE		0x10002
#define TDVMCALL_REPORT_FATAL_ERROR	0x10003
#define TDVMCALL_SETUP_EVENT_NOTIFY_INTERRUPT 0x10004ULL

/*
 * TDG.VP.VMCALL Status Codes (returned in R10)
+23 −0
Original line number Diff line number Diff line
@@ -1530,6 +1530,27 @@ static int tdx_get_quote(struct kvm_vcpu *vcpu)
	return 0;
}

static int tdx_setup_event_notify_interrupt(struct kvm_vcpu *vcpu)
{
	struct vcpu_tdx *tdx = to_tdx(vcpu);
	u64 vector = tdx->vp_enter_args.r12;

	if (vector < 32 || vector > 255) {
		tdvmcall_set_return_code(vcpu, TDVMCALL_STATUS_INVALID_OPERAND);
		return 1;
	}

	vcpu->run->exit_reason = KVM_EXIT_TDX;
	vcpu->run->tdx.flags = 0;
	vcpu->run->tdx.nr = TDVMCALL_SETUP_EVENT_NOTIFY_INTERRUPT;
	vcpu->run->tdx.setup_event_notify.ret = TDVMCALL_STATUS_SUBFUNC_UNSUPPORTED;
	vcpu->run->tdx.setup_event_notify.vector = vector;

	vcpu->arch.complete_userspace_io = tdx_complete_simple;

	return 0;
}

static int handle_tdvmcall(struct kvm_vcpu *vcpu)
{
	switch (tdvmcall_leaf(vcpu)) {
@@ -1541,6 +1562,8 @@ static int handle_tdvmcall(struct kvm_vcpu *vcpu)
		return tdx_get_td_vm_call_info(vcpu);
	case TDVMCALL_GET_QUOTE:
		return tdx_get_quote(vcpu);
	case TDVMCALL_SETUP_EVENT_NOTIFY_INTERRUPT:
		return tdx_setup_event_notify_interrupt(vcpu);
	default:
		break;
	}
+4 −0
Original line number Diff line number Diff line
@@ -467,6 +467,10 @@ struct kvm_run {
					__u64 leaf;
					__u64 r11, r12, r13, r14;
				} get_tdvmcall_info;
				struct {
					__u64 ret;
					__u64 vector;
				} setup_event_notify;
			};
		} tdx;
		/* Fix the size of the union. */