From b437c2085bdb88a35fab574a24052da3dc386096 Mon Sep 17 00:00:00 2001 From: yangge Date: Tue, 29 Oct 2024 03:48:38 -0400 Subject: [PATCH 1/4] anolis: KVM: SVM: CSV: fix CSV3 launch failures because of concurrent longterm pin ANBZ: #23279 If a large number of CMA memory are configured in system (for example, the CMA memory accounts for 50% of the system memory), starting a virtual machine with device passthrough, it will call pin_user_pages_remote(..., FOLL_LONGTERM, ...) to pin memory. Normally if a page is present and in CMA area, pin_user_pages_remote() will migrate the page from CMA area to non-CMA area because of FOLL_LONGTERM flag. But the current code will cause the migration failure due to unexpected page refcounts, and eventually cause the virtual machine fail to start. During CSV3 virtual machine startup, it will also call pin_user_pages_fast(..., FOLL_LONGTERM, ...) to pin shared memory in #NPF handler. If pin_user_pages_remote() and pin_user_pages_fast() pin a same page concurrently, it may lead to unexpected page refcounts. To solve the problem above, we use mmap_write_lock/unlock() to serialize the execution of pin_user_pages_remote() and pin_user_pages_fast(). Fixes: 6855ee8af1b5 ("anolis: KVM: SVM: CSV: Manage CSV guest's nested page table") Signed-off-by: yangge Signed-off-by: hanliyang --- arch/x86/kvm/svm/csv.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/arch/x86/kvm/svm/csv.c b/arch/x86/kvm/svm/csv.c index 2751ef92c60c..8381f1e0216f 100644 --- a/arch/x86/kvm/svm/csv.c +++ b/arch/x86/kvm/svm/csv.c @@ -1503,12 +1503,16 @@ static int csv_pin_shared_memory(struct kvm_vcpu *vcpu, return -ENOMEM; hva = __gfn_to_hva_memslot(slot, gfn); - npinned = pin_user_pages_fast(hva, 1, FOLL_WRITE | FOLL_LONGTERM, &page); + + mmap_write_lock(current->mm); + npinned = pin_user_pages(hva, 1, FOLL_WRITE | FOLL_LONGTERM, &page, NULL); if (npinned != 1) { + mmap_write_unlock(current->mm); kmem_cache_free(csv->sp_slab, sp); return -ENOMEM; } + mmap_write_unlock(current->mm); sp->page = page; sp->gfn = gfn; shared_page_insert(&csv->sp_mgr, sp); -- Gitee From b0fcd2614a934189574f36400f2d2ec74a25dace Mon Sep 17 00:00:00 2001 From: hanliyang Date: Sat, 19 Apr 2025 16:48:11 +0800 Subject: [PATCH 2/4] anolis: KVM: SVM: CSV: Return 0 at the beginning of csv_guest_hygon_coco_extension() for non-CSV3 VMs ANBZ: #23279 The commit 6bd0e8d58f44 ("anolis: KVM: SVM: CSV: Provide KVM_CAP_HYGON_COCO_EXT interface") provides a helper function csv_guest_hygon_coco_extension() to express that the available Hygon Confidential-Computing extensions can be used by the current VM. Obviously, a Non-Confidential-Computing VM will not be able to use these extensions, so return 0 at the beginning of csv_guest_hygon_coco_extension() for Non-CSV3 VMs. Fixes: 6bd0e8d58f44 ("anolis: KVM: SVM: CSV: Provide KVM_CAP_HYGON_COCO_EXT interface") Signed-off-by: hanliyang --- arch/x86/kvm/svm/csv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kvm/svm/csv.c b/arch/x86/kvm/svm/csv.c index 8381f1e0216f..0a6ca10eb09a 100644 --- a/arch/x86/kvm/svm/csv.c +++ b/arch/x86/kvm/svm/csv.c @@ -1928,7 +1928,7 @@ static int csv_get_hygon_coco_extension(struct kvm *kvm) size_t len = sizeof(uint32_t); int ret = 0; - if (!kvm) + if (!kvm || !csv3_guest(kvm)) return 0; csv = &to_kvm_svm_csv(kvm)->csv_info; -- Gitee From 2869441ee036b0541d09c060e008948e8d7a8ba3 Mon Sep 17 00:00:00 2001 From: hanliyang Date: Thu, 15 May 2025 16:19:39 +0800 Subject: [PATCH 3/4] anolis: KVM: SVM: The ASID range available for CSV2 guests vary across different firmware ANBZ: #23279 For firmware with a build ID < 1810, if CPUID_0x8000_001F_EDX.bits0-31 is 1, the ASID range available for CSV2 guests is [0, 0) (i.e., no ASIDs are available). Otherwise, the range is [1, CPUID_0x8000_001F_EDX.bits0-31). For firmware with a build ID >= 1810, the ASID range available for CSV2 guests is [1, CPUID_0x8000_001F_ECX.bits0-31]. Fixes: 37a1f4ca7a29 ("anolis: KVM: SVM: Fix the available ASID range for CSV2 guest") Signed-off-by: hanliyang --- arch/x86/kvm/svm/csv.h | 2 ++ arch/x86/kvm/svm/sev.c | 22 ++++++++++++++-------- drivers/crypto/ccp/hygon/csv-dev.c | 1 + 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/arch/x86/kvm/svm/csv.h b/arch/x86/kvm/svm/csv.h index baade835b9f2..5bb5e2158962 100644 --- a/arch/x86/kvm/svm/csv.h +++ b/arch/x86/kvm/svm/csv.h @@ -10,6 +10,8 @@ #ifndef __CSV_H #define __CSV_H +extern u32 hygon_csv_build; + #ifdef CONFIG_HYGON_CSV /* diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c index 586f852e62cc..701145859992 100644 --- a/arch/x86/kvm/svm/sev.c +++ b/arch/x86/kvm/svm/sev.c @@ -146,10 +146,10 @@ static int sev_asid_new(bool es_active, const char *userid, u32 userid_len) max_asid = es_active ? min_sev_asid - 1 : max_sev_asid; /* - * No matter what the min_sev_asid is, all asids in range + * When the firmware is with build ID >= 1810, all asids in range * [1, max_sev_asid] can be used for CSV2 guest on Hygon CPUs. */ - if (boot_cpu_data.x86_vendor == X86_VENDOR_HYGON) + if (is_x86_vendor_hygon() && hygon_csv_build >= 1810) max_asid = max_sev_asid; again: pos = find_next_zero_bit(sev_asid_bitmap, max_sev_asid, min_asid); @@ -2840,12 +2840,18 @@ void __init sev_hardware_setup(void) if (!boot_cpu_has(X86_FEATURE_SEV_ES)) goto out; - /* - * The ASIDs from 1 to max_sev_asid are available for hygon CSV2 - * guest. - */ - if (boot_cpu_data.x86_vendor == X86_VENDOR_HYGON) { - pr_info("CSV2 supported: %u ASIDs\n", max_sev_asid); + if (is_x86_vendor_hygon()) { + if (hygon_csv_build < 1810 && min_sev_asid <= 1) + goto out; + + /* + * If firmware version >= 1810, the ASIDs from 1 to max_sev_asid + * are available for hygon CSV2 guest. + * If firmware version < 1810, the ASIDs from 1 to CPUID function + * 0x8000_001F_EDX are available for hygon CSV2 guest. + */ + pr_info("CSV2 supported: %u ASIDs\n", + hygon_csv_build >= 1810 ? max_sev_asid : min_sev_asid - 1); sev_es_supported = true; goto out; } diff --git a/drivers/crypto/ccp/hygon/csv-dev.c b/drivers/crypto/ccp/hygon/csv-dev.c index fae8fbb5072c..724db8c7588e 100644 --- a/drivers/crypto/ccp/hygon/csv-dev.c +++ b/drivers/crypto/ccp/hygon/csv-dev.c @@ -23,6 +23,7 @@ * in AMD SEV. */ u32 hygon_csv_build; +EXPORT_SYMBOL_GPL(hygon_csv_build); /* * csv_update_api_version used to update the api version of HYGON CSV -- Gitee From a7a79e27e2cf0f8fd0dbaff2155726f47a94e329 Mon Sep 17 00:00:00 2001 From: hanliyang Date: Thu, 15 May 2025 17:41:40 +0800 Subject: [PATCH 4/4] anolis: KVM: SVM: CSV is unsupported if both the firmware with a build ID < 1878 and SME is not in use ANBZ: #23279 For firmware with a build ID < 1878, the CSV guest cannot run if the host kernel is not using SME. Fixes: b7628d1d2f87 ("anolis: KVM: SVM: Print Hygon CSV support info if support is detected") Signed-off-by: hanliyang --- arch/x86/kvm/svm/sev.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c index 701145859992..abf4f5c490ff 100644 --- a/arch/x86/kvm/svm/sev.c +++ b/arch/x86/kvm/svm/sev.c @@ -2764,6 +2764,9 @@ void __init sev_hardware_setup(void) bool sev_es_supported = false; bool sev_supported = false; + if (is_x86_vendor_hygon() && hygon_csv_build < 1878 && !sme_me_mask) + goto out; + /* * SEV must obviously be supported in hardware. Sanity check that the * CPU supports decode assists, which is mandatory for SEV guests to -- Gitee