[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v5 48/65] i386/tdx: handle TDG.VP.VMCALL<SetupEventNotifyInterrup
From: |
Xiaoyao Li |
Subject: |
[PATCH v5 48/65] i386/tdx: handle TDG.VP.VMCALL<SetupEventNotifyInterrupt> |
Date: |
Thu, 29 Feb 2024 01:37:09 -0500 |
From: Isaku Yamahata <isaku.yamahata@intel.com>
For SetupEventNotifyInterrupt, record interrupt vector and the apic id
of the vcpu that received this TDVMCALL.
Later it can inject interrupt with given vector to the specific vcpu
that received SetupEventNotifyInterrupt.
Signed-off-by: Isaku Yamahata <isaku.yamahata@intel.com>
Signed-off-by: Xiaoyao Li <xiaoyao.li@intel.com>
---
target/i386/kvm/kvm.c | 8 ++++++
target/i386/kvm/tdx-stub.c | 5 ++++
target/i386/kvm/tdx.c | 53 ++++++++++++++++++++++++++++++++++++++
target/i386/kvm/tdx.h | 14 ++++++++++
4 files changed, 80 insertions(+)
diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
index 4f998b2d6d37..2748086231d5 100644
--- a/target/i386/kvm/kvm.c
+++ b/target/i386/kvm/kvm.c
@@ -5413,6 +5413,14 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run
*run)
ret = kvm_xen_handle_exit(cpu, &run->xen);
break;
#endif
+ case KVM_EXIT_TDX:
+ if (!is_tdx_vm()) {
+ error_report("KVM: get KVM_EXIT_TDX for a non-TDX VM.");
+ ret = -1;
+ break;
+ }
+ ret = tdx_handle_exit(cpu, &run->tdx);
+ break;
default:
fprintf(stderr, "KVM: unknown exit reason %d\n", run->exit_reason);
ret = -1;
diff --git a/target/i386/kvm/tdx-stub.c b/target/i386/kvm/tdx-stub.c
index a064d583d393..57cd25793842 100644
--- a/target/i386/kvm/tdx-stub.c
+++ b/target/i386/kvm/tdx-stub.c
@@ -11,3 +11,8 @@ int tdx_parse_tdvf(void *flash_ptr, int size)
{
return -EINVAL;
}
+
+int tdx_handle_exit(X86CPU *cpu, struct kvm_tdx_exit *tdx_exit)
+{
+ return -EINVAL;
+}
diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c
index d445d4b70f77..49f94d9d46f4 100644
--- a/target/i386/kvm/tdx.c
+++ b/target/i386/kvm/tdx.c
@@ -866,6 +866,56 @@ int tdx_parse_tdvf(void *flash_ptr, int size)
return tdvf_parse_metadata(&tdx_guest->tdvf, flash_ptr, size);
}
+static int tdx_handle_setup_event_notify_interrupt(X86CPU *cpu,
+ struct kvm_tdx_vmcall
*vmcall)
+{
+ int vector = vmcall->in_r12;
+
+ if (32 <= vector && vector <= 255) {
+ qemu_mutex_lock(&tdx_guest->lock);
+ tdx_guest->event_notify_vector = vector;
+ tdx_guest->event_notify_apicid = cpu->apic_id;
+ qemu_mutex_unlock(&tdx_guest->lock);
+ vmcall->status_code = TDG_VP_VMCALL_SUCCESS;
+ } else {
+ vmcall->status_code = TDG_VP_VMCALL_INVALID_OPERAND;
+ }
+
+ return 0;
+}
+
+static int tdx_handle_vmcall(X86CPU *cpu, struct kvm_tdx_vmcall *vmcall)
+{
+ vmcall->status_code = TDG_VP_VMCALL_INVALID_OPERAND;
+
+ /* For now handle only TDG.VP.VMCALL leaf defined in TDX GHCI */
+ if (vmcall->type != 0) {
+ error_report("Unknown TDG.VP.VMCALL type 0x%llx subfunction 0x%llx",
+ vmcall->type, vmcall->subfunction);
+ return -1;
+ }
+
+ switch (vmcall->subfunction) {
+ case TDG_VP_VMCALL_SETUP_EVENT_NOTIFY_INTERRUPT:
+ return tdx_handle_setup_event_notify_interrupt(cpu, vmcall);
+ default:
+ error_report("Unknown TDG.VP.VMCALL type 0x%llx subfunction 0x%llx",
+ vmcall->type, vmcall->subfunction);
+ return -1;
+ }
+}
+
+int tdx_handle_exit(X86CPU *cpu, struct kvm_tdx_exit *tdx_exit)
+{
+ switch (tdx_exit->type) {
+ case KVM_EXIT_TDX_VMCALL:
+ return tdx_handle_vmcall(cpu, &tdx_exit->u.vmcall);
+ default:
+ error_report("unknown tdx exit type 0x%x", tdx_exit->type);
+ return -1;
+ }
+}
+
static bool tdx_guest_get_sept_ve_disable(Object *obj, Error **errp)
{
TdxGuest *tdx = TDX_GUEST(obj);
@@ -956,6 +1006,9 @@ static void tdx_guest_init(Object *obj)
object_property_add_str(obj, "mrownerconfig",
tdx_guest_get_mrownerconfig,
tdx_guest_set_mrownerconfig);
+
+ tdx->event_notify_vector = -1;
+ tdx->event_notify_apicid = -1;
}
static void tdx_guest_finalize(Object *obj)
diff --git a/target/i386/kvm/tdx.h b/target/i386/kvm/tdx.h
index 3fb4069268f6..b3d4462fe718 100644
--- a/target/i386/kvm/tdx.h
+++ b/target/i386/kvm/tdx.h
@@ -7,6 +7,7 @@
#include "exec/confidential-guest-support.h"
#include "hw/i386/tdvf.h"
+#include "sysemu/kvm.h"
#define TYPE_TDX_GUEST "tdx-guest"
#define TDX_GUEST(obj) OBJECT_CHECK(TdxGuest, (obj), TYPE_TDX_GUEST)
@@ -15,6 +16,14 @@ typedef struct TdxGuestClass {
ConfidentialGuestSupportClass parent_class;
} TdxGuestClass;
+#define TDG_VP_VMCALL_SETUP_EVENT_NOTIFY_INTERRUPT 0x10004ULL
+
+#define TDG_VP_VMCALL_SUCCESS 0x0000000000000000ULL
+#define TDG_VP_VMCALL_RETRY 0x0000000000000001ULL
+#define TDG_VP_VMCALL_INVALID_OPERAND 0x8000000000000000ULL
+#define TDG_VP_VMCALL_GPA_INUSE 0x8000000000000001ULL
+#define TDG_VP_VMCALL_ALIGN_ERROR 0x8000000000000002ULL
+
enum TdxRamType{
TDX_RAM_UNACCEPTED,
TDX_RAM_ADDED,
@@ -42,6 +51,10 @@ typedef struct TdxGuest {
uint32_t nr_ram_entries;
TdxRamEntry *ram_entries;
+
+ /* runtime state */
+ uint32_t event_notify_vector;
+ uint32_t event_notify_apicid;
} TdxGuest;
#ifdef CONFIG_TDX
@@ -55,5 +68,6 @@ void tdx_get_supported_cpuid(uint32_t function, uint32_t
index, int reg,
int tdx_pre_create_vcpu(CPUState *cpu, Error **errp);
void tdx_set_tdvf_region(MemoryRegion *tdvf_mr);
int tdx_parse_tdvf(void *flash_ptr, int size);
+int tdx_handle_exit(X86CPU *cpu, struct kvm_tdx_exit *tdx_exit);
#endif /* QEMU_I386_TDX_H */
--
2.34.1
- [PATCH v5 36/65] i386/tdx: load TDVF for TD guest, (continued)
- [PATCH v5 36/65] i386/tdx: load TDVF for TD guest, Xiaoyao Li, 2024/02/29
- [PATCH v5 38/65] i386/tdx: Parse TDVF metadata for TDX VM, Xiaoyao Li, 2024/02/29
- [PATCH v5 40/65] i386/tdx: Don't initialize pc.rom for TDX VMs, Xiaoyao Li, 2024/02/29
- [PATCH v5 41/65] i386/tdx: Track mem_ptr for each firmware entry of TDVF, Xiaoyao Li, 2024/02/29
- [PATCH v5 42/65] i386/tdx: Track RAM entries for TDX VM, Xiaoyao Li, 2024/02/29
- [PATCH v5 44/65] i386/tdx: Setup the TD HOB list, Xiaoyao Li, 2024/02/29
- [PATCH v5 43/65] headers: Add definitions from UEFI spec for volumes, resources, etc..., Xiaoyao Li, 2024/02/29
- [PATCH v5 45/65] i386/tdx: Populate TDVF private memory via KVM_MEMORY_MAPPING, Xiaoyao Li, 2024/02/29
- [PATCH v5 46/65] i386/tdx: Call KVM_TDX_INIT_VCPU to initialize TDX vcpu, Xiaoyao Li, 2024/02/29
- [PATCH v5 47/65] i386/tdx: Finalize TDX VM, Xiaoyao Li, 2024/02/29
- [PATCH v5 48/65] i386/tdx: handle TDG.VP.VMCALL<SetupEventNotifyInterrupt>,
Xiaoyao Li <=
- [PATCH v5 50/65] i386/tdx: handle TDG.VP.VMCALL<MapGPA> hypercall, Xiaoyao Li, 2024/02/29
- [PATCH v5 49/65] i386/tdx: handle TDG.VP.VMCALL<GetQuote>, Xiaoyao Li, 2024/02/29
- [PATCH v5 51/65] i386/tdx: Handle TDG.VP.VMCALL<REPORT_FATAL_ERROR>, Xiaoyao Li, 2024/02/29
- [PATCH v5 52/65] i386/tdx: Wire TDX_REPORT_FATAL_ERROR with GuestPanic facility, Xiaoyao Li, 2024/02/29
- [PATCH v5 53/65] pci-host/q35: Move PAM initialization above SMRAM initialization, Xiaoyao Li, 2024/02/29
- [PATCH v5 54/65] q35: Introduce smm_ranges property for q35-pci-host, Xiaoyao Li, 2024/02/29