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, linux-kernel@vger.kernel.org,
binbin.wu@linux.intel.com
Subject: [PATCH v2 7/8] KVM: TDX: Handle TDX PV port I/O hypercall
Date: Tue, 11 Feb 2025 10:54:41 +0800 [thread overview]
Message-ID: <20250211025442.3071607-8-binbin.wu@linux.intel.com> (raw)
In-Reply-To: <20250211025442.3071607-1-binbin.wu@linux.intel.com>
From: Isaku Yamahata <isaku.yamahata@intel.com>
Emulate port I/O requested by TDX guest via TDVMCALL with leaf
Instruction.IO (same value as EXIT_REASON_IO_INSTRUCTION) according to
TDX Guest Host Communication Interface (GHCI).
All port I/O instructions inside the TDX guest trigger the #VE exception.
On #VE triggered by I/O instructions, TDX guest can call TDVMCALL with
leaf Instruction.IO to request VMM to emulate I/O instructions.
Similar to normal port I/O emulation, try to handle the port I/O in kernel
first, if kernel can't support it, forward the request to userspace.
Note string I/O operations are not supported in TDX. Guest should unroll
them before calling the TDVMCALL.
Suggested-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Isaku Yamahata <isaku.yamahata@intel.com>
Co-developed-by: Binbin Wu <binbin.wu@linux.intel.com>
Signed-off-by: Binbin Wu <binbin.wu@linux.intel.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
---
Hypercalls exit to userspace v2:
- Morph PV port I/O hypercall to EXIT_REASON_IO_INSTRUCTION. (Sean)
- Use vp_enter_args instead of x86 registers.
- Check write is either 0 or 1. (Chao)
- Skip setting return code as TDVMCALL_STATUS_SUCCESS. (Sean)
Hypercalls exit to userspace v1:
- Renamed from "KVM: TDX: Handle TDX PV port io hypercall" to
"KVM: TDX: Handle TDX PV port I/O hypercall".
- Update changelog.
- Add missing curly brackets.
- Move reset of pio.count to tdx_complete_pio_out() and remove the stale
comment. (binbin)
- Use TDVMCALL_STATUS prefix for TDX call status codes (Binbin)
- Set status code to TDVMCALL_STATUS_SUCCESS when PIO is handled in kernel.
- Don't write to R11 when it is a write operation for output.
v18:
- Fix out case to set R10 and R11 correctly when user space handled port
out.
---
arch/x86/kvm/vmx/tdx.c | 60 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 60 insertions(+)
diff --git a/arch/x86/kvm/vmx/tdx.c b/arch/x86/kvm/vmx/tdx.c
index 85956768c515..f13da28dd4a2 100644
--- a/arch/x86/kvm/vmx/tdx.c
+++ b/arch/x86/kvm/vmx/tdx.c
@@ -1135,6 +1135,64 @@ static int tdx_report_fatal_error(struct kvm_vcpu *vcpu)
return 0;
}
+static int tdx_complete_pio_out(struct kvm_vcpu *vcpu)
+{
+ vcpu->arch.pio.count = 0;
+ return 1;
+}
+
+static int tdx_complete_pio_in(struct kvm_vcpu *vcpu)
+{
+ struct x86_emulate_ctxt *ctxt = vcpu->arch.emulate_ctxt;
+ unsigned long val = 0;
+ int ret;
+
+ ret = ctxt->ops->pio_in_emulated(ctxt, vcpu->arch.pio.size,
+ vcpu->arch.pio.port, &val, 1);
+
+ WARN_ON_ONCE(!ret);
+
+ tdvmcall_set_return_val(vcpu, val);
+
+ return 1;
+}
+
+static int tdx_emulate_io(struct kvm_vcpu *vcpu)
+{
+ struct vcpu_tdx *tdx = to_tdx(vcpu);
+ struct x86_emulate_ctxt *ctxt = vcpu->arch.emulate_ctxt;
+ unsigned long val = 0;
+ unsigned int port;
+ u64 size, write;
+ int ret;
+
+ ++vcpu->stat.io_exits;
+
+ size = tdx->vp_enter_args.r12;
+ write = tdx->vp_enter_args.r13;
+ port = tdx->vp_enter_args.r14;
+
+ if ((write != 0 && write != 1) || (size != 1 && size != 2 && size != 4)) {
+ tdvmcall_set_return_code(vcpu, TDVMCALL_STATUS_INVALID_OPERAND);
+ return 1;
+ }
+
+ if (write) {
+ val = tdx->vp_enter_args.r15;
+ ret = ctxt->ops->pio_out_emulated(ctxt, size, port, &val, 1);
+ } else {
+ ret = ctxt->ops->pio_in_emulated(ctxt, size, port, &val, 1);
+ }
+
+ if (!ret)
+ vcpu->arch.complete_userspace_io = write ? tdx_complete_pio_out :
+ tdx_complete_pio_in;
+ else if (!write)
+ tdvmcall_set_return_val(vcpu, val);
+
+ return ret;
+}
+
static int handle_tdvmcall(struct kvm_vcpu *vcpu)
{
switch (tdvmcall_leaf(vcpu)) {
@@ -1486,6 +1544,8 @@ int tdx_handle_exit(struct kvm_vcpu *vcpu, fastpath_t fastpath)
return handle_tdvmcall(vcpu);
case EXIT_REASON_VMCALL:
return tdx_emulate_vmcall(vcpu);
+ case EXIT_REASON_IO_INSTRUCTION:
+ return tdx_emulate_io(vcpu);
default:
break;
}
--
2.46.0
next prev parent reply other threads:[~2025-02-11 2:53 UTC|newest]
Thread overview: 39+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-02-11 2:54 [PATCH v2 0/8] KVM: TDX: TDX hypercalls may exit to userspace Binbin Wu
2025-02-11 2:54 ` [PATCH v2 1/8] KVM: x86: Have ____kvm_emulate_hypercall() read the GPRs Binbin Wu
2025-02-11 5:05 ` Huang, Kai
2025-02-11 10:23 ` Xiaoyao Li
2025-02-12 1:32 ` Binbin Wu
2025-02-12 3:12 ` Xiaoyao Li
2025-02-11 2:54 ` [PATCH v2 2/8] KVM: TDX: Add a place holder to handle TDX VM exit Binbin Wu
2025-02-11 2:54 ` [PATCH v2 3/8] KVM: TDX: Add a place holder for handler of TDX hypercalls (TDG.VP.VMCALL) Binbin Wu
2025-02-11 8:41 ` Chao Gao
2025-02-11 9:08 ` Binbin Wu
2025-02-11 23:46 ` Sean Christopherson
2025-02-12 2:21 ` Binbin Wu
2025-02-11 2:54 ` [PATCH v2 4/8] KVM: TDX: Handle KVM hypercall with TDG.VP.VMCALL Binbin Wu
2025-02-11 23:48 ` Sean Christopherson
2025-02-11 2:54 ` [PATCH v2 5/8] KVM: TDX: Handle TDG.VP.VMCALL<MapGPA> Binbin Wu
2025-02-11 6:54 ` Yan Zhao
2025-02-11 8:11 ` Binbin Wu
2025-02-11 8:59 ` Chao Gao
2025-02-12 0:46 ` Sean Christopherson
2025-02-12 5:16 ` Binbin Wu
2025-02-12 18:56 ` Sean Christopherson
2025-02-13 3:23 ` Binbin Wu
2025-02-13 5:11 ` Binbin Wu
2025-02-13 15:17 ` Sean Christopherson
2025-02-17 3:41 ` Binbin Wu
2025-02-19 0:29 ` Sean Christopherson
2025-02-19 0:49 ` Binbin Wu
2025-02-11 2:54 ` [PATCH v2 6/8] KVM: TDX: Handle TDG.VP.VMCALL<ReportFatalError> Binbin Wu
2025-02-12 0:18 ` Sean Christopherson
2025-02-12 5:37 ` Binbin Wu
2025-02-12 13:53 ` Sean Christopherson
2025-02-11 2:54 ` Binbin Wu [this message]
2025-02-11 2:54 ` [PATCH v2 8/8] KVM: TDX: Handle TDX PV MMIO hypercall Binbin Wu
2025-02-12 2:28 ` Chao Gao
2025-02-12 2:39 ` Binbin Wu
2025-02-13 21:41 ` Edgecombe, Rick P
2025-02-14 0:47 ` Binbin Wu
2025-02-14 1:01 ` Edgecombe, Rick P
2025-02-14 1:20 ` 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=20250211025442.3071607-8-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=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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.