From 8163bd183e5fb3f99ffb0285a027e611b9b84bbe Mon Sep 17 00:00:00 2001 From: Shivam7-1 <55046031+Shivam7-1@users.noreply.github.com> Date: Tue, 10 Dec 2024 09:51:03 +0530 Subject: [PATCH] Update memory enc kvm.c --- arch/x86/kernel/kvm.c | 111 +++++++++++++++++++++++++----------------- 1 file changed, 67 insertions(+), 44 deletions(-) diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c index 21e9e484535415..c1eefb98c8ef89 100644 --- a/arch/x86/kernel/kvm.c +++ b/arch/x86/kernel/kvm.c @@ -927,65 +927,88 @@ static bool __init kvm_msi_ext_dest_id(void) static void kvm_sev_hc_page_enc_status(unsigned long pfn, int npages, bool enc) { - kvm_sev_hypercall3(KVM_HC_MAP_GPA_RANGE, pfn << PAGE_SHIFT, npages, - KVM_MAP_GPA_RANGE_ENC_STAT(enc) | KVM_MAP_GPA_RANGE_PAGE_SZ_4K); + unsigned long end_pfn = pfn + npages; + + // Input validation: Ensure that the page frame numbers are aligned and within bounds + if (pfn % PAGE_SIZE != 0) { + pr_err("Invalid memory address: pfn is not page-aligned\n"); + return; + } + + if (end_pfn > MAX_MEMORY_PFN) { + pr_err("Memory range exceeds maximum allowed physical address space\n"); + return; + } + + if (npages <= 0) { + pr_err("Invalid number of pages: npages must be positive\n"); + return; + } + + // Debugging: Log the memory encryption status change for traceability + pr_info("Changing encryption status for memory range: [0x%lx - 0x%lx] to %s\n", pfn, end_pfn - 1, enc ? "encrypted" : "decrypted"); + + // Perform the hypercall to update encryption status + if (kvm_sev_hypercall3(KVM_HC_MAP_GPA_RANGE, pfn << PAGE_SHIFT, npages, + KVM_MAP_GPA_RANGE_ENC_STAT(enc) | KVM_MAP_GPA_RANGE_PAGE_SZ_4K)) { + pr_err("Failed to update memory encryption status for range [0x%lx - 0x%lx]\n", pfn, end_pfn - 1); + } } static void __init kvm_init_platform(void) { - if (cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT) && - kvm_para_has_feature(KVM_FEATURE_MIGRATION_CONTROL)) { - unsigned long nr_pages; - int i; + if (cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT) && kvm_para_has_feature(KVM_FEATURE_MIGRATION_CONTROL)) { + unsigned long nr_pages; + int i; - pv_ops.mmu.notify_page_enc_status_changed = - kvm_sev_hc_page_enc_status; + pv_ops.mmu.notify_page_enc_status_changed = kvm_sev_hc_page_enc_status; - /* - * Reset the host's shared pages list related to kernel - * specific page encryption status settings before we load a - * new kernel by kexec. Reset the page encryption status - * during early boot instead of just before kexec to avoid SMP - * races during kvm_pv_guest_cpu_reboot(). - * NOTE: We cannot reset the complete shared pages list - * here as we need to retain the UEFI/OVMF firmware - * specific settings. - */ + for (i = 0; i < e820_table->nr_entries; i++) { + struct e820_entry *entry = &e820_table->entries[i]; - for (i = 0; i < e820_table->nr_entries; i++) { - struct e820_entry *entry = &e820_table->entries[i]; + if (entry->type != E820_TYPE_RAM) + continue; - if (entry->type != E820_TYPE_RAM) - continue; + nr_pages = DIV_ROUND_UP(entry->size, PAGE_SIZE); - nr_pages = DIV_ROUND_UP(entry->size, PAGE_SIZE); + // Input validation for memory range + if (entry->addr % PAGE_SIZE != 0) { + pr_err("Invalid memory address in e820 entry (not page-aligned): 0x%lx\n", entry->addr); + continue; + } - kvm_sev_hypercall3(KVM_HC_MAP_GPA_RANGE, entry->addr, - nr_pages, - KVM_MAP_GPA_RANGE_ENCRYPTED | KVM_MAP_GPA_RANGE_PAGE_SZ_4K); - } + if (entry->addr + entry->size > MAX_MEMORY_ADDR) { + pr_err("Memory range in e820 entry exceeds maximum allowed address space: 0x%lx\n", entry->addr); + continue; + } - /* - * Ensure that _bss_decrypted section is marked as decrypted in the - * shared pages list. - */ - early_set_mem_enc_dec_hypercall((unsigned long)__start_bss_decrypted, - __end_bss_decrypted - __start_bss_decrypted, 0); + // Log memory encryption status for debugging + pr_info("Encrypting memory range in e820 entry: [0x%lx - 0x%lx]\n", entry->addr, entry->addr + entry->size - 1); - /* - * If not booted using EFI, enable Live migration support. - */ - if (!efi_enabled(EFI_BOOT)) - wrmsrl(MSR_KVM_MIGRATION_CONTROL, - KVM_MIGRATION_READY); - } - kvmclock_init(); - x86_platform.apic_post_init = kvm_apic_init; + // Perform memory encryption for the range + kvm_sev_hypercall3(KVM_HC_MAP_GPA_RANGE, entry->addr, nr_pages, + KVM_MAP_GPA_RANGE_ENCRYPTED | KVM_MAP_GPA_RANGE_PAGE_SZ_4K); + } + + // Ensure that _bss_decrypted section is marked as decrypted + early_set_mem_enc_dec_hypercall((unsigned long)__start_bss_decrypted, + __end_bss_decrypted - __start_bss_decrypted, 0); + + // Log that the memory is being decrypted + pr_info("Marking _bss_decrypted section as decrypted\n"); - /* Set WB as the default cache mode for SEV-SNP and TDX */ - mtrr_overwrite_state(NULL, 0, MTRR_TYPE_WRBACK); + if (!efi_enabled(EFI_BOOT)) + wrmsrl(MSR_KVM_MIGRATION_CONTROL, KVM_MIGRATION_READY); + } + + kvmclock_init(); + x86_platform.apic_post_init = kvm_apic_init; + + // Set WB as the default cache mode for SEV-SNP and TDX + mtrr_overwrite_state(NULL, 0, MTRR_TYPE_WRBACK); } + #if defined(CONFIG_AMD_MEM_ENCRYPT) static void kvm_sev_es_hcall_prepare(struct ghcb *ghcb, struct pt_regs *regs) {