diff mbox series

[1/2] target/i386: kvm: Block migration on vCPU exposed with SVM when kernel lacks caps to save/restore nested state

Message ID 20190621213712.16222-2-liran.alon@oracle.com (mailing list archive)
State New, archived
Headers show
Series target/i386: kvm: Fix treatment of AMD SVM in nested migration | expand

Commit Message

Liran Alon June 21, 2019, 9:37 p.m. UTC
Commit 18ab37ba1cee ("target/i386: kvm: Block migration for vCPUs exposed with nested virtualization")
was originally suppose to block migration for vCPUs exposed with nested virtualization, either Intel VMX
or AMD SVM. However, during merge to upstream, commit was changed such that it doesn't even compile...

This was done unintentionally in an attempt to modify submitted patch-series such that commit
12604092e26c ("target/i386: kvm: Add nested migration blocker only when kernel lacks required capabilities")
will only block migration of vCPU exposed with VMX but still allow migration of vCPU exposed
with SVM.

However, since QEMU commit 75d373ef9729 ("target-i386: Disable SVM by default in KVM mode"),
an AMD vCPU that is virtualized by KVM doesn’t expose SVM by default, even if you use "-cpu host".
Therefore, it is unlikely that vCPU expose SVM CPUID flag when user is not running an SVM
workload inside guest.

Therefore, change code back to original intent to block migration in
case of vCPU exposed with SVM if kernel does not support required
capabilities to save/restore nested-state.

Fixes: 12604092e26c ("target/i386: kvm: Add nested migration blocker only when kernel lacks required capabilities")
Reviewed-by: Mark Kanda <mark.kanda@oracle.com>
Reviewed-by: Karl Heubaum <karl.heubaum@oracle.com>
Signed-off-by: Liran Alon <liran.alon@oracle.com>
---
 target/i386/cpu.h     | 10 ++++++++++
 target/i386/kvm.c     |  2 +-
 target/i386/machine.c |  2 +-
 3 files changed, 12 insertions(+), 2 deletions(-)
diff mbox series

Patch

diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 93345792f4cb..cbe904beeb25 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -1867,6 +1867,16 @@  static inline bool cpu_has_vmx(CPUX86State *env)
     return env->features[FEAT_1_ECX] & CPUID_EXT_VMX;
 }
 
+static inline bool cpu_has_svm(CPUX86State *env)
+{
+    return env->features[FEAT_8000_0001_ECX] & CPUID_EXT3_SVM;
+}
+
+static inline bool cpu_has_nested_virt(CPUX86State *env)
+{
+    return (cpu_has_vmx(env) || cpu_has_svm(env));
+}
+
 /* fpu_helper.c */
 void update_fp_status(CPUX86State *env);
 void update_mxcsr_status(CPUX86State *env);
diff --git a/target/i386/kvm.c b/target/i386/kvm.c
index e4b4f5756a34..c2bae6a3023a 100644
--- a/target/i386/kvm.c
+++ b/target/i386/kvm.c
@@ -1640,7 +1640,7 @@  int kvm_arch_init_vcpu(CPUState *cs)
                                   !!(c->ecx & CPUID_EXT_SMX);
     }
 
-    if (cpu_has_vmx(env) && !nested_virt_mig_blocker &&
+    if (cpu_has_nested_virt(env) && !nested_virt_mig_blocker &&
         ((kvm_max_nested_state_length() <= 0) || !has_exception_payload)) {
         error_setg(&nested_virt_mig_blocker,
                    "Kernel do not provide required capabilities for "
diff --git a/target/i386/machine.c b/target/i386/machine.c
index 851b249d1a39..f4d502386df4 100644
--- a/target/i386/machine.c
+++ b/target/i386/machine.c
@@ -233,7 +233,7 @@  static int cpu_pre_save(void *opaque)
 
 #ifdef CONFIG_KVM
     /* Verify we have nested virtualization state from kernel if required */
-    if (kvm_enabled() && cpu_has_vmx(env) && !env->nested_state) {
+    if (kvm_enabled() && cpu_has_nested_virt(env) && !env->nested_state) {
         error_report("Guest enabled nested virtualization but kernel "
                 "does not support saving of nested state");
         return -EINVAL;