On 24/06/20 01:01, Eduardo Habkost wrote:
> QEMU incorrectly validates FEAT_SVM feature flags against
> GET_SUPPORTED_CPUID even if SVM features are being masked out by
> cpu_x86_cpuid(). This can make QEMU print warnings on most AMD
> CPU models, even when SVM nesting is disabled (which is the
> default).
>
> This bug was never detected before because of a Linux KVM bug:
> until Linux v5.6, KVM was not filtering out SVM features in
> GET_SUPPORTED_CPUID when nested was disabled. This KVM bug was
> fixed in Linux v5.7-rc1, on Linux commit a50718cc3f43 ("KVM:
> nSVM: Expose SVM features to L1 iff nested is enabled").
>
> Fix the problem by adding a CPUID_EXT3_SVM dependency to all
> FEAT_SVM feature flags in the feature_dependencies table.
>
> Reported-by: Yanan Fu <[email protected]>
> Signed-off-by: Eduardo Habkost <[email protected]>
> ---
> target/i386/cpu.c | 4 ++++
> 1 file changed, 4 insertions(+)
>
> diff --git a/target/i386/cpu.c b/target/i386/cpu.c
> index b1b311baa2..a9edcaf531 100644
> --- a/target/i386/cpu.c
> +++ b/target/i386/cpu.c
> @@ -1404,6 +1404,10 @@ static FeatureDep feature_dependencies[] = {
> .from = { FEAT_VMX_SECONDARY_CTLS, VMX_SECONDARY_EXEC_ENABLE_VMFUNC
> },
> .to = { FEAT_VMX_VMFUNC, ~0ull },
> },
> + {
> + .from = { FEAT_8000_0001_ECX, CPUID_EXT3_SVM },
> + .to = { FEAT_SVM, ~0ull },
> + },
> };
>
> typedef struct X86RegisterInfo32 {
>
Queued with this fixup:
diff --git a/tests/qtest/test-x86-cpuid-compat.c
b/tests/qtest/test-x86-cpuid-compat.c
index 772287bdb4..8709e7d9ce 100644
--- a/tests/qtest/test-x86-cpuid-compat.c
+++ b/tests/qtest/test-x86-cpuid-compat.c
@@ -256,7 +256,7 @@ int main(int argc, char **argv)
"-cpu 486,+invtsc", "xlevel", 0x80000007);
/* CPUID[8000_000A].EDX: */
add_cpuid_test("x86/cpuid/auto-xlevel/486/npt",
- "-cpu 486,+npt", "xlevel", 0x8000000A);
+ "-cpu 486,+svm,+npt", "xlevel", 0x8000000A);
/* CPUID[C000_0001].EDX: */
add_cpuid_test("x86/cpuid/auto-xlevel2/phenom/xstore",
"-cpu phenom,+xstore", "xlevel2", 0xC0000001);
@@ -348,7 +348,7 @@ int main(int argc, char **argv)
"-machine pc-i440fx-2.4 -cpu SandyBridge,",
"xlevel", 0x80000008);
add_cpuid_test("x86/cpuid/xlevel-compat/pc-i440fx-2.4/npt-on",
- "-machine pc-i440fx-2.4 -cpu SandyBridge,+npt",
+ "-machine pc-i440fx-2.4 -cpu SandyBridge,+svm,+npt",
"xlevel", 0x80000008);
/* Test feature parsing */
Paolo