[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 40/63] KVM: track whether guest state is encrypted
From: |
Paolo Bonzini |
Subject: |
[PULL 40/63] KVM: track whether guest state is encrypted |
Date: |
Tue, 23 Apr 2024 17:09:28 +0200 |
So far, KVM has allowed KVM_GET/SET_* ioctls to execute even if the
guest state is encrypted, in which case they do nothing. For the new
API using VM types, instead, the ioctls will fail which is a safer and
more robust approach.
The new API will be the only one available for SEV-SNP and TDX, but it
is also usable for SEV and SEV-ES. In preparation for that, require
architecture-specific KVM code to communicate the point at which guest
state is protected (which must be after kvm_cpu_synchronize_post_init(),
though that might change in the future in order to suppor migration).
>From that point, skip reading registers so that cpu->vcpu_dirty is
never true: if it ever becomes true, kvm_arch_put_registers() will
fail miserably.
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
include/sysemu/kvm.h | 2 ++
include/sysemu/kvm_int.h | 1 +
accel/kvm/kvm-all.c | 17 ++++++++++++++---
target/i386/sev.c | 1 +
4 files changed, 18 insertions(+), 3 deletions(-)
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index 2cba899270c..14b1ddb3be1 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -539,6 +539,8 @@ bool kvm_dirty_ring_enabled(void);
uint32_t kvm_dirty_ring_size(void);
+void kvm_mark_guest_state_protected(void);
+
/**
* kvm_hwpoisoned_mem - indicate if there is any hwpoisoned page
* reported for the VM.
diff --git a/include/sysemu/kvm_int.h b/include/sysemu/kvm_int.h
index 94488d2c1a2..227b61fec3d 100644
--- a/include/sysemu/kvm_int.h
+++ b/include/sysemu/kvm_int.h
@@ -87,6 +87,7 @@ struct KVMState
bool kernel_irqchip_required;
OnOffAuto kernel_irqchip_split;
bool sync_mmu;
+ bool guest_state_protected;
uint64_t manual_dirty_log_protect;
/* The man page (and posix) say ioctl numbers are signed int, but
* they're not. Linux, glibc and *BSD all treat ioctl numbers as
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index d58916e33ae..d6ebadbf386 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -2703,7 +2703,7 @@ bool kvm_cpu_check_are_resettable(void)
static void do_kvm_cpu_synchronize_state(CPUState *cpu, run_on_cpu_data arg)
{
- if (!cpu->vcpu_dirty) {
+ if (!cpu->vcpu_dirty && !kvm_state->guest_state_protected) {
int ret = kvm_arch_get_registers(cpu);
if (ret) {
error_report("Failed to get registers: %s", strerror(-ret));
@@ -2717,7 +2717,7 @@ static void do_kvm_cpu_synchronize_state(CPUState *cpu,
run_on_cpu_data arg)
void kvm_cpu_synchronize_state(CPUState *cpu)
{
- if (!cpu->vcpu_dirty) {
+ if (!cpu->vcpu_dirty && !kvm_state->guest_state_protected) {
run_on_cpu(cpu, do_kvm_cpu_synchronize_state, RUN_ON_CPU_NULL);
}
}
@@ -2752,7 +2752,13 @@ static void do_kvm_cpu_synchronize_post_init(CPUState
*cpu, run_on_cpu_data arg)
void kvm_cpu_synchronize_post_init(CPUState *cpu)
{
- run_on_cpu(cpu, do_kvm_cpu_synchronize_post_init, RUN_ON_CPU_NULL);
+ if (!kvm_state->guest_state_protected) {
+ /*
+ * This runs before the machine_init_done notifiers, and is the last
+ * opportunity to synchronize the state of confidential guests.
+ */
+ run_on_cpu(cpu, do_kvm_cpu_synchronize_post_init, RUN_ON_CPU_NULL);
+ }
}
static void do_kvm_cpu_synchronize_pre_loadvm(CPUState *cpu, run_on_cpu_data
arg)
@@ -4099,3 +4105,8 @@ void query_stats_schemas_cb(StatsSchemaList **result,
Error **errp)
query_stats_schema_vcpu(first_cpu, &stats_args);
}
}
+
+void kvm_mark_guest_state_protected(void)
+{
+ kvm_state->guest_state_protected = true;
+}
diff --git a/target/i386/sev.c b/target/i386/sev.c
index b8f79d34d19..c49a8fd55eb 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -755,6 +755,7 @@ sev_launch_get_measure(Notifier *notifier, void *unused)
if (ret) {
exit(1);
}
+ kvm_mark_guest_state_protected();
}
/* query the measurement blob length */
--
2.44.0
- [PULL 44/63] target/i386: SEV: use KVM_SEV_INIT2 if possible, (continued)
- [PULL 44/63] target/i386: SEV: use KVM_SEV_INIT2 if possible, Paolo Bonzini, 2024/04/23
- [PULL 45/63] i386/sev: Add 'legacy-vm-type' parameter for SEV guest objects, Paolo Bonzini, 2024/04/23
- [PULL 46/63] hw/i386/sev: Use legacy SEV VM types for older machine types, Paolo Bonzini, 2024/04/23
- [PULL 50/63] kvm: Enable KVM_SET_USER_MEMORY_REGION2 for memslot, Paolo Bonzini, 2024/04/23
- [PULL 49/63] RAMBlock: Add support of KVM private guest memfd, Paolo Bonzini, 2024/04/23
- [PULL 51/63] kvm/memory: Make memory type private by default if it has guest memfd backend, Paolo Bonzini, 2024/04/23
- [PULL 62/63] pythondeps.toml: warn about updates needed to docs/requirements.txt, Paolo Bonzini, 2024/04/23
- [PULL 52/63] HostMem: Add mechanism to opt in kvm guest memfd via MachineState, Paolo Bonzini, 2024/04/23
- [PULL 57/63] kvm/tdx: Ignore memory conversion to shared of unassigned region, Paolo Bonzini, 2024/04/23
- [PULL 31/63] hw/i386/acpi: Set PCAT_COMPAT bit only when pic is not disabled, Paolo Bonzini, 2024/04/23
- [PULL 40/63] KVM: track whether guest state is encrypted,
Paolo Bonzini <=
- [PULL 47/63] trace/kvm: Split address space and slot id in trace_kvm_set_user_memory(), Paolo Bonzini, 2024/04/23
- [PULL 18/63] stubs: move monitor_fdsets_cleanup with other fdset stubs, Paolo Bonzini, 2024/04/23
- [PULL 16/63] stubs: split record/replay stubs further, Paolo Bonzini, 2024/04/23
- [PULL 26/63] target/i386: Introduce Icelake-Server-v7 to enable TSX, Paolo Bonzini, 2024/04/23
- [PULL 28/63] target/i386: Export RFDS bit to guests, Paolo Bonzini, 2024/04/23
- [PULL 35/63] s390: Switch to use confidential_guest_kvm_init(), Paolo Bonzini, 2024/04/23
- [PULL 43/63] target/i386: Implement mc->kvm_type() to get VM type, Paolo Bonzini, 2024/04/23
- [PULL 61/63] accel/tcg/icount-common: Consolidate the use of warn_report_once(), Paolo Bonzini, 2024/04/23
- [PULL 59/63] target/i386/cpu: Consolidate the use of warn_report_once(), Paolo Bonzini, 2024/04/23