[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 38/45] i386/kvm: Add KVM_EXIT_HYPERCALL handling for KVM_HC_MAP_GP
From: |
Paolo Bonzini |
Subject: |
[PULL 38/45] i386/kvm: Add KVM_EXIT_HYPERCALL handling for KVM_HC_MAP_GPA_RANGE |
Date: |
Tue, 4 Jun 2024 08:44:02 +0200 |
From: Michael Roth <michael.roth@amd.com>
KVM_HC_MAP_GPA_RANGE will be used to send requests to userspace for
private/shared memory attribute updates requested by the guest.
Implement handling for that use-case along with some basic
infrastructure for enabling specific hypercall events.
Signed-off-by: Michael Roth <michael.roth@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-31-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/kvm/kvm_i386.h | 1 +
target/i386/kvm/kvm.c | 55 ++++++++++++++++++++++++++++++++++++
target/i386/kvm/trace-events | 1 +
3 files changed, 57 insertions(+)
diff --git a/target/i386/kvm/kvm_i386.h b/target/i386/kvm/kvm_i386.h
index 6b44844d95d..34fc60774b8 100644
--- a/target/i386/kvm/kvm_i386.h
+++ b/target/i386/kvm/kvm_i386.h
@@ -33,6 +33,7 @@
bool kvm_has_smm(void);
bool kvm_enable_x2apic(void);
bool kvm_hv_vpindex_settable(void);
+bool kvm_enable_hypercall(uint64_t enable_mask);
bool kvm_enable_sgx_provisioning(KVMState *s);
bool kvm_hyperv_expand_features(X86CPU *cpu, Error **errp);
diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
index 23a003aaa7e..ede3ef1225f 100644
--- a/target/i386/kvm/kvm.c
+++ b/target/i386/kvm/kvm.c
@@ -21,6 +21,7 @@
#include <sys/syscall.h>
#include <linux/kvm.h>
+#include <linux/kvm_para.h>
#include "standard-headers/asm-x86/kvm_para.h"
#include "hw/xen/interface/arch-x86/cpuid.h"
@@ -209,6 +210,13 @@ int kvm_get_vm_type(MachineState *ms)
return kvm_type;
}
+bool kvm_enable_hypercall(uint64_t enable_mask)
+{
+ KVMState *s = KVM_STATE(current_accel());
+
+ return !kvm_vm_enable_cap(s, KVM_CAP_EXIT_HYPERCALL, 0, enable_mask);
+}
+
bool kvm_has_smm(void)
{
return kvm_vm_check_extension(kvm_state, KVM_CAP_X86_SMM);
@@ -5322,6 +5330,50 @@ static bool host_supports_vmx(void)
return ecx & CPUID_EXT_VMX;
}
+/*
+ * Currently the handling here only supports use of KVM_HC_MAP_GPA_RANGE
+ * to service guest-initiated memory attribute update requests so that
+ * KVM_SET_MEMORY_ATTRIBUTES can update whether or not a page should be
+ * backed by the private memory pool provided by guest_memfd, and as such
+ * is only applicable to guest_memfd-backed guests (e.g. SNP/TDX).
+ *
+ * Other other use-cases for KVM_HC_MAP_GPA_RANGE, such as for SEV live
+ * migration, are not implemented here currently.
+ *
+ * For the guest_memfd use-case, these exits will generally be synthesized
+ * by KVM based on platform-specific hypercalls, like GHCB requests in the
+ * case of SEV-SNP, and not issued directly within the guest though the
+ * KVM_HC_MAP_GPA_RANGE hypercall. So in this case, KVM_HC_MAP_GPA_RANGE is
+ * not actually advertised to guests via the KVM CPUID feature bit, as
+ * opposed to SEV live migration where it would be. Since it is unlikely the
+ * SEV live migration use-case would be useful for guest-memfd backed guests,
+ * because private/shared page tracking is already provided through other
+ * means, these 2 use-cases should be treated as being mutually-exclusive.
+ */
+static int kvm_handle_hc_map_gpa_range(struct kvm_run *run)
+{
+ uint64_t gpa, size, attributes;
+
+ if (!machine_require_guest_memfd(current_machine))
+ return -EINVAL;
+
+ gpa = run->hypercall.args[0];
+ size = run->hypercall.args[1] * TARGET_PAGE_SIZE;
+ attributes = run->hypercall.args[2];
+
+ trace_kvm_hc_map_gpa_range(gpa, size, attributes, run->hypercall.flags);
+
+ return kvm_convert_memory(gpa, size, attributes &
KVM_MAP_GPA_RANGE_ENCRYPTED);
+}
+
+static int kvm_handle_hypercall(struct kvm_run *run)
+{
+ if (run->hypercall.nr == KVM_HC_MAP_GPA_RANGE)
+ return kvm_handle_hc_map_gpa_range(run);
+
+ return -EINVAL;
+}
+
#define VMX_INVALID_GUEST_STATE 0x80000021
int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
@@ -5417,6 +5469,9 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run
*run)
ret = kvm_xen_handle_exit(cpu, &run->xen);
break;
#endif
+ case KVM_EXIT_HYPERCALL:
+ ret = kvm_handle_hypercall(run);
+ break;
default:
fprintf(stderr, "KVM: unknown exit reason %d\n", run->exit_reason);
ret = -1;
diff --git a/target/i386/kvm/trace-events b/target/i386/kvm/trace-events
index b365a8e8e28..74a6234ff7f 100644
--- a/target/i386/kvm/trace-events
+++ b/target/i386/kvm/trace-events
@@ -5,6 +5,7 @@ kvm_x86_fixup_msi_error(uint32_t gsi) "VT-d failed to remap
interrupt for GSI %"
kvm_x86_add_msi_route(int virq) "Adding route entry for virq %d"
kvm_x86_remove_msi_route(int virq) "Removing route entry for virq %d"
kvm_x86_update_msi_routes(int num) "Updated %d MSI routes"
+kvm_hc_map_gpa_range(uint64_t gpa, uint64_t size, uint64_t attributes,
uint64_t flags) "gpa 0x%" PRIx64 " size 0x%" PRIx64 " attributes 0x%" PRIx64 "
flags 0x%" PRIx64
# xen-emu.c
kvm_xen_hypercall(int cpu, uint8_t cpl, uint64_t input, uint64_t a0, uint64_t
a1, uint64_t a2, uint64_t ret) "xen_hypercall: cpu %d cpl %d input %" PRIu64 "
a0 0x%" PRIx64 " a1 0x%" PRIx64 " a2 0x%" PRIx64" ret 0x%" PRIx64
--
2.45.1
- [PULL 27/45] i386/sev: Add a class method to determine KVM VM type for SNP guests, (continued)
- [PULL 27/45] i386/sev: Add a class method to determine KVM VM type for SNP guests, Paolo Bonzini, 2024/06/04
- [PULL 32/45] hw/i386/sev: Add function to get SEV metadata from OVMF header, Paolo Bonzini, 2024/06/04
- [PULL 41/45] i386/sev: Reorder struct declarations, Paolo Bonzini, 2024/06/04
- [PULL 30/45] i386/sev: Add handling to encrypt/finalize guest launch data, Paolo Bonzini, 2024/06/04
- [PULL 26/45] i386/sev: Don't return launch measurements for SEV-SNP guests, Paolo Bonzini, 2024/06/04
- [PULL 25/45] i386/cpu: Set SEV-SNP CPUID bit when SNP enabled, Paolo Bonzini, 2024/06/04
- [PULL 34/45] i386/sev: Add support for SNP CPUID validation, Paolo Bonzini, 2024/06/04
- [PULL 37/45] i386/sev: Invoke launch_updata_data() for SNP class, Paolo Bonzini, 2024/06/04
- [PULL 35/45] hw/i386/sev: Add support to encrypt BIOS when SEV-SNP is enabled, Paolo Bonzini, 2024/06/04
- [PULL 38/45] i386/kvm: Add KVM_EXIT_HYPERCALL handling for KVM_HC_MAP_GPA_RANGE,
Paolo Bonzini <=
- [PULL 40/45] i386/sev: Extract build_kernel_loader_hashes, Paolo Bonzini, 2024/06/04
- [PULL 43/45] memory: Introduce memory_region_init_ram_guest_memfd(), Paolo Bonzini, 2024/06/04
- [PULL 45/45] hw/i386: Add support for loading BIOS using guest_memfd, Paolo Bonzini, 2024/06/04
- [PULL 31/45] i386/sev: Set CPU state to protected once SNP guest payload is finalized, Paolo Bonzini, 2024/06/04
- [PULL 29/45] i386/sev: Add the SNP launch start context, Paolo Bonzini, 2024/06/04
- [PULL 33/45] i386/sev: Add support for populating OVMF metadata pages, Paolo Bonzini, 2024/06/04
- [PULL 39/45] i386/sev: Enable KVM_HC_MAP_GPA_RANGE hcall for SNP guests, Paolo Bonzini, 2024/06/04
- [PULL 42/45] i386/sev: Allow measured direct kernel boot on SNP, Paolo Bonzini, 2024/06/04
- [PULL 28/45] i386/sev: Update query-sev QAPI format to handle SEV-SNP, Paolo Bonzini, 2024/06/04
- [PULL 36/45] i386/sev: Invoke launch_updata_data() for SEV class, Paolo Bonzini, 2024/06/04