History

KVM: TDX: Exit to userspace for SetupEventNotifyInterrupt

Paolo Bonzini committed 1 year ago

Commit 4580dbe1 parent 25e8b1d4 files · +35 −0Browse files

Unified · Split

4 files
  1. Documentation/virt/kvm/api.rst +7 −0
  2. arch/x86/include/asm/shared/tdx.h +1 −0
  3. arch/x86/kvm/vmx/tdx.c +23 −0
  4. include/uapi/linux/kvm.h +4 −0
Documentation/virt/kvm/api.rst+7−0
@@ -7196,6 +7196,10 @@ The valid value for 'flags' is: · 7195 unmodified lines
71967196 u64 leaf;
71977197 u64 r11, r12, r13, r14;
71987198 } get_tdvmcall_info;
7199+ struct {
7200+ u64 ret;
7201+ u64 vector;
7202+ } setup_event_notify;
71997203 };
72007204 } tdx;
72017205
@@ -7226,6 +7230,9 @@ status of TDVMCALLs. The output values for the given leaf should be · 24 unmodified lines
72267230 placed in fields from ``r11`` to ``r14`` of the ``get_tdvmcall_info``
72277231 field of the union.
72287232
7233+* ``TDVMCALL_SETUP_EVENT_NOTIFY_INTERRUPT``: the guest has requested to
7234+set up a notification interrupt for vector ``vector``.
7235+
72297236 KVM may add support for more values in the future that may cause a userspace
72307237 exit, even without calls to ``KVM_ENABLE_CAP`` or similar. In this case,
72317238 it will enter with output fields already valid; in the common case, the
arch/x86/include/asm/shared/tdx.h+1−0
@@ -72,6 +72,7 @@ · 71 unmodified lines
7272 #define TDVMCALL_MAP_GPA 0x10001
7373 #define TDVMCALL_GET_QUOTE 0x10002
7474 #define TDVMCALL_REPORT_FATAL_ERROR 0x10003
75+#define TDVMCALL_SETUP_EVENT_NOTIFY_INTERRUPT 0x10004ULL
7576
7677 /*
7778 * TDG.VP.VMCALL Status Codes (returned in R10)
arch/x86/kvm/vmx/tdx.c+23−0
@@ -1530,6 +1530,27 @@ static int tdx_get_quote(struct kvm_vcpu *vcpu) · 1529 unmodified lines
15301530 return 0;
15311531 }
15321532
1533+static int tdx_setup_event_notify_interrupt(struct kvm_vcpu *vcpu)
1534+{
1535+ struct vcpu_tdx *tdx = to_tdx(vcpu);
1536+ u64 vector = tdx->vp_enter_args.r12;
1537+
1538+ if (vector < 32 || vector > 255) {
1539+ tdvmcall_set_return_code(vcpu, TDVMCALL_STATUS_INVALID_OPERAND);
1540+ return 1;
1541+ }
1542+
1543+ vcpu->run->exit_reason = KVM_EXIT_TDX;
1544+ vcpu->run->tdx.flags = 0;
1545+ vcpu->run->tdx.nr = TDVMCALL_SETUP_EVENT_NOTIFY_INTERRUPT;
1546+ vcpu->run->tdx.setup_event_notify.ret = TDVMCALL_STATUS_SUBFUNC_UNSUPPORTED;
1547+ vcpu->run->tdx.setup_event_notify.vector = vector;
1548+
1549+ vcpu->arch.complete_userspace_io = tdx_complete_simple;
1550+
1551+ return 0;
1552+}
1553+
15331554 static int handle_tdvmcall(struct kvm_vcpu *vcpu)
15341555 {
15351556 switch (tdvmcall_leaf(vcpu)) {
@@ -1541,6 +1562,8 @@ static int handle_tdvmcall(struct kvm_vcpu *vcpu) · 5 unmodified lines
15411562 return tdx_get_td_vm_call_info(vcpu);
15421563 case TDVMCALL_GET_QUOTE:
15431564 return tdx_get_quote(vcpu);
1565+ case TDVMCALL_SETUP_EVENT_NOTIFY_INTERRUPT:
1566+ return tdx_setup_event_notify_interrupt(vcpu);
15441567 default:
15451568 break;
15461569 }
include/uapi/linux/kvm.h+4−0
@@ -467,6 +467,10 @@ struct kvm_run { · 466 unmodified lines
467467 __u64 leaf;
468468 __u64 r11, r12, r13, r14;
469469 } get_tdvmcall_info;
470+ struct {
471+ __u64 ret;
472+ __u64 vector;
473+ } setup_event_notify;
470474 };
471475 } tdx;
472476 /* Fix the size of the union. */