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.ka...@oracle.com> Reviewed-by: Karl Heubaum <karl.heub...@oracle.com> Signed-off-by: Liran Alon <liran.a...@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 --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; -- 2.20.1