public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Binbin Wu <binbin.wu@linux.intel.com>
To: pbonzini@redhat.com, seanjc@google.com, kvm@vger.kernel.org
Cc: rick.p.edgecombe@intel.com, kai.huang@intel.com,
	adrian.hunter@intel.com, reinette.chatre@intel.com,
	xiaoyao.li@intel.com, tony.lindgren@intel.com,
	isaku.yamahata@intel.com, yan.y.zhao@intel.com,
	chao.gao@intel.com, mikko.ylinen@linux.intel.com,
	linux-kernel@vger.kernel.org, binbin.wu@linux.intel.com
Subject: [PATCH 2/2] KVM: TDX: Handle TDG.VP.VMCALL<SetupEventNotifyInterrupt>
Date: Wed,  2 Apr 2025 08:15:57 +0800	[thread overview]
Message-ID: <20250402001557.173586-3-binbin.wu@linux.intel.com> (raw)
In-Reply-To: <20250402001557.173586-1-binbin.wu@linux.intel.com>

Handle TDVMCALL for SetupEventNotifyInterrupt to set up an event-notify
vector.

TDX guests can make a request to host VMMs to specify which interrupt
vector to use as an event-notify vector.  E.g., for GetQuote operation,
which may take several seconds, if a TDX guest has set up the event-notify
vector, the host VMM can inject an interrupt with the specified vector
to the TDX guest on the completion of the operation.

KVM itself doesn't use this mechanism.  Add KVM_EXIT_TDX_SETUP_EVENT_NOTIFY
as a new exit reason to userspace to forward the request to userspace VMM
(e.g., QEMU) after sanity checks, so that userspace can inject an interrupt
with the event-notify vector to the TDX guest when the operation completes.

Since there is nothing special for SetupEventNotifyInterrupt beyond setting
the return code in the complete_userspace_io() callback, the code reuses
the version developed for GetQuote.

Signed-off-by: Binbin Wu <binbin.wu@linux.intel.com>
---
 Documentation/virt/kvm/api.rst    | 22 +++++++++++++++++++++-
 arch/x86/include/asm/shared/tdx.h |  1 +
 arch/x86/kvm/vmx/tdx.c            | 25 +++++++++++++++++++++++--
 include/uapi/linux/kvm.h          |  6 ++++++
 4 files changed, 51 insertions(+), 3 deletions(-)

diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst
index 90aa7a328dc8..16e15f151620 100644
--- a/Documentation/virt/kvm/api.rst
+++ b/Documentation/virt/kvm/api.rst
@@ -7179,7 +7179,27 @@ TDX guest passes a TD report. When completed, the generated quote is returned
 via the same buffer. The 'ret' field represents the return value. The userspace
 should update the return value before resuming the vCPU according to TDX GHCI
 spec. It's an asynchronous request. After the TDVMCALL is returned and back to
-TDX guest, TDX guest can poll the status field of the shared-memory area.
+TDX guest, TDX guest can poll the status field of the shared-memory area. Or TDX
+guest can register an event-notify vector by TDVMCALL_SETUP_EVENT_NOTIFY, so
+that on completion, an interrupt can be injected to TDX guest.
+
+::
+
+		/* KVM_EXIT_TDX_SETUP_EVENT_NOTIFY */
+		struct tdx_get_quote {
+			__u64 ret;
+			__u8 vector;
+		};
+
+If the exit reason is KVM_EXIT_TDX_SETUP_EVENT_NOTIFY, then it indicates that a
+TDX guest has requested to specify an interrupt vector used as the event-notify
+vector. E.g., for GetQuote operation, which may take several seconds, if the
+TDX guest has set up the event-notify vector, the host injects an interrupt
+with the specified vector to the guest on the completion of the operation. The
+'vector' field specifies the interrupt vector, with a valid range [32, 255], to
+be used for the event-notify. The 'ret' field represents the return value. The
+userspace should update the return value before resuming the vCPU according
+to TDX GHCI spec.
 
 ::
 
diff --git a/arch/x86/include/asm/shared/tdx.h b/arch/x86/include/asm/shared/tdx.h
index 606d93a1cbac..eddc3f696b38 100644
--- a/arch/x86/include/asm/shared/tdx.h
+++ b/arch/x86/include/asm/shared/tdx.h
@@ -71,6 +71,7 @@
 #define TDVMCALL_MAP_GPA		0x10001
 #define TDVMCALL_GET_QUOTE		0x10002
 #define TDVMCALL_REPORT_FATAL_ERROR	0x10003
+#define TDVMCALL_SETUP_EVENT_NOTIFY	0x10004
 
 /*
  * TDG.VP.VMCALL Status Codes (returned in R10)
diff --git a/arch/x86/kvm/vmx/tdx.c b/arch/x86/kvm/vmx/tdx.c
index 535200446c21..48461520cb44 100644
--- a/arch/x86/kvm/vmx/tdx.c
+++ b/arch/x86/kvm/vmx/tdx.c
@@ -1463,7 +1463,10 @@ static int tdx_get_td_vm_call_info(struct kvm_vcpu *vcpu)
 	return 1;
 }
 
-static int tdx_complete_get_quote(struct kvm_vcpu *vcpu)
+static_assert(offsetof(struct kvm_run, tdx_setup_event_notify.ret) ==
+	      offsetof(struct kvm_run, tdx_get_quote.ret));
+
+static int tdx_complete_tdcall_common(struct kvm_vcpu *vcpu)
 {
 	tdvmcall_set_return_code(vcpu, vcpu->run->tdx_get_quote.ret);
 	return 1;
@@ -1491,7 +1494,23 @@ static int tdx_get_quote(struct kvm_vcpu *vcpu)
 	vcpu->run->tdx_get_quote.gpa = gpa;
 	vcpu->run->tdx_get_quote.size = size;
 
-	vcpu->arch.complete_userspace_io = tdx_complete_get_quote;
+	vcpu->arch.complete_userspace_io = tdx_complete_tdcall_common;
+
+	return 0;
+}
+
+static int tdx_setup_event_notify(struct kvm_vcpu *vcpu)
+{
+	u64 vector = to_tdx(vcpu)->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_SETUP_EVENT_NOTIFY;
+	vcpu->run->tdx_setup_event_notify.vector = (u8)vector;
+	vcpu->arch.complete_userspace_io = tdx_complete_tdcall_common;
 
 	return 0;
 }
@@ -1507,6 +1526,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:
+		return tdx_setup_event_notify(vcpu);
 	default:
 		break;
 	}
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index eca86b7f0cbc..1a9397e8997b 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -179,6 +179,7 @@ struct kvm_xen_exit {
 #define KVM_EXIT_LOONGARCH_IOCSR  38
 #define KVM_EXIT_MEMORY_FAULT     39
 #define KVM_EXIT_TDX_GET_QUOTE    41
+#define KVM_EXIT_TDX_SETUP_EVENT_NOTIFY 42
 
 /* For KVM_EXIT_INTERNAL_ERROR */
 /* Emulate instruction failed. */
@@ -454,6 +455,11 @@ struct kvm_run {
 			__u64 gpa;
 			__u64 size;
 		} tdx_get_quote;
+		/* KVM_EXIT_TDX_SETUP_EVENT_NOTIFY */
+		struct {
+			__u64 ret;
+			__u8 vector;
+		} tdx_setup_event_notify;
 		/* Fix the size of the union. */
 		char padding[256];
 	};
-- 
2.46.0


  parent reply	other threads:[~2025-04-02  0:14 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-04-02  0:15 [PATCH 0/2] TDX attestation support Binbin Wu
2025-04-02  0:15 ` [PATCH 1/2] KVM: TDX: Handle TDG.VP.VMCALL<GetQuote> Binbin Wu
2025-04-02  0:53   ` Huang, Kai
2025-04-02  8:58     ` Huang, Kai
2025-04-02 12:53     ` Binbin Wu
2025-04-02 13:16       ` Binbin Wu
2025-04-02 22:05         ` Huang, Kai
2025-04-02 22:00       ` Huang, Kai
2025-04-08  2:35         ` Binbin Wu
2025-04-09 13:49       ` Sean Christopherson
2025-04-10  0:06         ` Binbin Wu
2025-04-10  0:15         ` Huang, Kai
2025-04-02 22:19   ` Huang, Kai
2025-04-07  1:00     ` Binbin Wu
2025-04-15  1:49   ` Xiaoyao Li
2025-04-15  1:51     ` Edgecombe, Rick P
2025-04-15  1:55       ` Binbin Wu
2025-04-02  0:15 ` Binbin Wu [this message]
2025-04-02  0:20 ` [PATCH 0/2] TDX attestation support Edgecombe, Rick P
2025-04-11  1:42   ` Binbin Wu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20250402001557.173586-3-binbin.wu@linux.intel.com \
    --to=binbin.wu@linux.intel.com \
    --cc=adrian.hunter@intel.com \
    --cc=chao.gao@intel.com \
    --cc=isaku.yamahata@intel.com \
    --cc=kai.huang@intel.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mikko.ylinen@linux.intel.com \
    --cc=pbonzini@redhat.com \
    --cc=reinette.chatre@intel.com \
    --cc=rick.p.edgecombe@intel.com \
    --cc=seanjc@google.com \
    --cc=tony.lindgren@intel.com \
    --cc=xiaoyao.li@intel.com \
    --cc=yan.y.zhao@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox