Re: [PATCH v5 03/15] KVM: SVM: Disable SEV/SEV-ES if NPT is disabled

Paolo Bonzini
2021-04-22T07:14:35Z

On 22/04/21 04:11, Sean Christopherson wrote:
> Disable SEV and SEV-ES if NPT is disabled. While the APM doesn't clearly
> state that NPT is mandatory, it's alluded to by:
>
> The guest page tables, managed by the guest, may mark data memory pages
> as either private or shared, thus allowing selected pages to be shared
> outside the guest.
>
> And practically speaking, shadow paging can't work since KVM can't read
> the guest's page tables.
>
> Fixes: e9df09428996 ("KVM: SVM: Add sev module_param")
> Cc: Brijesh Singh <brijesh.singh@amd.com
> Cc: Tom Lendacky <thomas.lendacky@amd.com>
> Signed-off-by: Sean Christopherson <seanjc@google.com>
> ---
> arch/x86/kvm/svm/svm.c | 30 +++++++++++++++---------------
> 1 file changed, 15 insertions(+), 15 deletions(-)
>
> diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
> index fed153314aef..0e8489908216 100644
> --- a/arch/x86/kvm/svm/svm.c
> +++ b/arch/x86/kvm/svm/svm.c
> @@ -970,7 +970,21 @@ static __init int svm_hardware_setup(void)
> kvm_enable_efer_bits(EFER_SVME | EFER_LMSLE);
> }
>
> - if (IS_ENABLED(CONFIG_KVM_AMD_SEV) && sev) {
> + /*
> + * KVM's MMU doesn't support using 2-level paging for itself, and thus
> + * NPT isn't supported if the host is using 2-level paging since host
> + * CR4 is unchanged on VMRUN.
> + */
> + if (!IS_ENABLED(CONFIG_X86_64) && !IS_ENABLED(CONFIG_X86_PAE))
> + npt_enabled = false;

Unrelated, but since you're moving this code: should we be pre-scient
and tackle host 5-level paging as well?

Support for 5-level page tables on NPT is not hard to fix and could be
tested by patching QEMU. However, the !NPT case would also have to be
fixed by extending the PDP and PML4 stacking trick to a PML5.

However, without real hardware to test on I'd be a bit wary to do it.
Looking at 5-level EPT there might be other issues (e.g. what's the
guest MAXPHYADDR) and I would prefer to see what AMD comes up with
exactly in the APM. So I would just block loading KVM on hypothetical
AMD hosts with CR4.LA57=1.

Paolo

> + if (!boot_cpu_has(X86_FEATURE_NPT))
> + npt_enabled = false;
> +
> + kvm_configure_mmu(npt_enabled, get_max_npt_level(), PG_LEVEL_1G);
> + pr_info("kvm: Nested Paging %sabled\n", npt_enabled ? "en" : "dis");
> +
> + if (IS_ENABLED(CONFIG_KVM_AMD_SEV) && sev && npt_enabled) {
> sev_hardware_setup();
> } else {
> sev = false;
> @@ -985,20 +999,6 @@ static __init int svm_hardware_setup(void)
> goto err;
> }
>
> - /*
> - * KVM's MMU doesn't support using 2-level paging for itself, and thus
> - * NPT isn't supported if the host is using 2-level paging since host
> - * CR4 is unchanged on VMRUN.
> - */
> - if (!IS_ENABLED(CONFIG_X86_64) && !IS_ENABLED(CONFIG_X86_PAE))
> - npt_enabled = false;
> -
> - if (!boot_cpu_has(X86_FEATURE_NPT))
> - npt_enabled = false;
> -
> - kvm_configure_mmu(npt_enabled, get_max_npt_level(), PG_LEVEL_1G);
> - pr_info("kvm: Nested Paging %sabled\n", npt_enabled ? "en" : "dis");
> -
> if (nrips) {
> if (!boot_cpu_has(X86_FEATURE_NRIPS))
> nrips = false;
>