From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2EBA1C00140 for ; Wed, 10 Aug 2022 15:21:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233196AbiHJPVG (ORCPT ); Wed, 10 Aug 2022 11:21:06 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37178 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233084AbiHJPUp (ORCPT ); Wed, 10 Aug 2022 11:20:45 -0400 Received: from mail-pf1-x44a.google.com (mail-pf1-x44a.google.com [IPv6:2607:f8b0:4864:20::44a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7FE002C107 for ; Wed, 10 Aug 2022 08:20:44 -0700 (PDT) Received: by mail-pf1-x44a.google.com with SMTP id j10-20020a62b60a000000b0052b30f6626bso6680587pff.17 for ; Wed, 10 Aug 2022 08:20:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc; bh=wUnNC45e2hnxoz0Q2Km6sVkIgu+FYYkWmLFW62kGR4A=; b=bE6EN2CKvCbMW6GRrrudOdbMe33OYr4fP/ZpAiuVlu4yctMBqSwGIK16Wi7w3hCQHd mjOAV8gTzcg7LJH9bk7/WLBHw2/VC3MwgYCtsHvV6VOL9uJLUSdj3KloYm4IuxKLtU2x R8vWMrpZE7CGKf0qi+hpELvBOiLNEiDi9ZLGakaMbrUhafmXca5Hrxt8XzQDN/2nPnb6 xDw6k8NRvixy5FNufjHklnLRQsTtioVX9sQ4e7iOZTinzK+ZJosL+MOewei8ECwkIaNs M7RlDU7xoq+2CAC/fycg8CQi/vQ8pixKaYJ0vD3VtRsv7blNgszBK67kwtx/dHRVq/pw 9Q0A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc; bh=wUnNC45e2hnxoz0Q2Km6sVkIgu+FYYkWmLFW62kGR4A=; b=0tgHOveb5lLOxMc9vW4NyhBY9Dsv7DremCXvUNY+rEpvlNR1XEIEXY2ydFAaKTcZEw c5K+Q/INevu+f85aGCo44J0UiIgctdBjHiY6STqapPly6kx0ePrGEJ4VZYvMkZnvGSXy RqhqjCvdeg8cy30v2RSeaiEtBSLoP3E/ayccftzzZDHrgXRhvwpWYipXgLRr0HXdj5lF xkMDEZ/tbY2q0j/Lw4OaDzwKUKt0djG1yifLh+CW0Q03PZP5isYPJ20ghFBacHiVvpUO DZmx3ZcrUoNbackBTLo5XvRNldBkNDfUZuRxWU9vijDwMa+NkZLD7/gHBnrPf9TwDC/U 6Rjg== X-Gm-Message-State: ACgBeo2N7eI56tadwfDWwooaDGE8Pj8T0FZH5AzCgf53A5Hu1sd0w19g xE9H6kGJYj9MydAk1Ww7I1qWZG0K21E= X-Google-Smtp-Source: AA6agR4kVXd/NdDCSVVCawPQsiv66EqvY8xWY/SBh432v2Bp2mnV7vaZNiumoN5iLQoCK7KKKpTo+0hqrKU= X-Received: from pgonda1.kir.corp.google.com ([2620:15c:29:203:b185:1827:5b23:bbe2]) (user=pgonda job=sendgmr) by 2002:a17:90b:1e50:b0:1f5:4f69:d6b8 with SMTP id pi16-20020a17090b1e5000b001f54f69d6b8mr4371150pjb.34.1660144844030; Wed, 10 Aug 2022 08:20:44 -0700 (PDT) Date: Wed, 10 Aug 2022 08:20:26 -0700 In-Reply-To: <20220810152033.946942-1-pgonda@google.com> Message-Id: <20220810152033.946942-5-pgonda@google.com> Mime-Version: 1.0 References: <20220810152033.946942-1-pgonda@google.com> X-Mailer: git-send-email 2.37.1.559.g78731f0fdb-goog Subject: [V3 04/11] KVM: selftests: handle encryption bits in page tables From: Peter Gonda To: kvm@vger.kernel.org Cc: linux-kernel@vger.kernel.org, marcorr@google.com, seanjc@google.com, michael.roth@amd.com, thomas.lendacky@amd.com, joro@8bytes.org, mizhang@google.com, pbonzini@redhat.com, andrew.jones@linux.dev, vannapurve@google.com, Peter Gonda Content-Type: text/plain; charset="UTF-8" Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Michael Roth SEV guests rely on an encyption bit which resides within the range that current code treats as address bits. Guest code will expect these bits to be set appropriately in their page tables, whereas the rest of the kvm_util functions will generally expect these bits to not be present. Introduce addr_gpa2raw()/addr_raw2gpa() to add/remove these bits, then use them where appropriate. Signed-off-by: Michael Roth Signed-off-by: Peter Gonda --- .../selftests/kvm/include/kvm_util_base.h | 2 + tools/testing/selftests/kvm/lib/kvm_util.c | 55 ++++++++++++++++++- .../selftests/kvm/lib/x86_64/processor.c | 15 +++-- 3 files changed, 66 insertions(+), 6 deletions(-) diff --git a/tools/testing/selftests/kvm/include/kvm_util_base.h b/tools/testing/selftests/kvm/include/kvm_util_base.h index 3928351e497e..de769b3de274 100644 --- a/tools/testing/selftests/kvm/include/kvm_util_base.h +++ b/tools/testing/selftests/kvm/include/kvm_util_base.h @@ -399,6 +399,8 @@ void *addr_gpa2hva(struct kvm_vm *vm, vm_paddr_t gpa); void *addr_gva2hva(struct kvm_vm *vm, vm_vaddr_t gva); vm_paddr_t addr_hva2gpa(struct kvm_vm *vm, void *hva); void *addr_gpa2alias(struct kvm_vm *vm, vm_paddr_t gpa); +vm_paddr_t addr_raw2gpa(struct kvm_vm *vm, vm_vaddr_t gpa_raw); +vm_paddr_t addr_gpa2raw(struct kvm_vm *vm, vm_vaddr_t gpa); void vcpu_run(struct kvm_vcpu *vcpu); int _vcpu_run(struct kvm_vcpu *vcpu); diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c index c6b87b411186..87772e23d1b5 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util.c +++ b/tools/testing/selftests/kvm/lib/kvm_util.c @@ -1377,6 +1377,58 @@ void virt_map(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr, } } +/* + * Mask off any special bits from raw GPA + * + * Input Args: + * vm - Virtual Machine + * gpa_raw - Raw VM physical address + * + * Output Args: None + * + * Return: + * GPA with special bits (e.g. shared/encrypted) masked off. + */ +vm_paddr_t addr_raw2gpa(struct kvm_vm *vm, vm_paddr_t gpa_raw) +{ + if (!vm->memcrypt.has_enc_bit) + return gpa_raw; + + return gpa_raw & ~(1ULL << vm->memcrypt.enc_bit); +} + +/* + * Add special/encryption bits to a GPA based on encryption bitmap. + * + * Input Args: + * vm - Virtual Machine + * gpa - VM physical address + * + * Output Args: None + * + * Return: + * GPA with special bits (e.g. shared/encrypted) added in. + */ +vm_paddr_t addr_gpa2raw(struct kvm_vm *vm, vm_paddr_t gpa) +{ + struct userspace_mem_region *region; + sparsebit_idx_t pg; + vm_paddr_t gpa_raw = gpa; + + TEST_ASSERT(addr_raw2gpa(vm, gpa) == gpa, "Unexpected bits in GPA: %lx", + gpa); + + if (!vm->memcrypt.has_enc_bit) + return gpa; + + region = userspace_mem_region_find(vm, gpa, gpa); + pg = gpa >> vm->page_shift; + if (sparsebit_is_set(region->encrypted_phy_pages, pg)) + gpa_raw |= (1ULL << vm->memcrypt.enc_bit); + + return gpa_raw; +} + /* * Address VM Physical to Host Virtual * @@ -1394,9 +1446,10 @@ void virt_map(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr, * address providing the memory to the vm physical address is returned. * A TEST_ASSERT failure occurs if no region containing gpa exists. */ -void *addr_gpa2hva(struct kvm_vm *vm, vm_paddr_t gpa) +void *addr_gpa2hva(struct kvm_vm *vm, vm_paddr_t gpa_raw) { struct userspace_mem_region *region; + vm_paddr_t gpa = addr_raw2gpa(vm, gpa_raw); region = userspace_mem_region_find(vm, gpa, gpa); if (!region) { diff --git a/tools/testing/selftests/kvm/lib/x86_64/processor.c b/tools/testing/selftests/kvm/lib/x86_64/processor.c index f35626df1dea..55855594d26d 100644 --- a/tools/testing/selftests/kvm/lib/x86_64/processor.c +++ b/tools/testing/selftests/kvm/lib/x86_64/processor.c @@ -118,7 +118,7 @@ void virt_arch_pgd_alloc(struct kvm_vm *vm) /* If needed, create page map l4 table. */ if (!vm->pgd_created) { - vm->pgd = vm_alloc_page_table(vm); + vm->pgd = addr_gpa2raw(vm, vm_alloc_page_table(vm)); vm->pgd_created = true; } } @@ -140,13 +140,15 @@ static uint64_t *virt_create_upper_pte(struct kvm_vm *vm, int target_level) { uint64_t *pte = virt_get_pte(vm, pt_pfn, vaddr, current_level); + uint64_t paddr_raw = addr_gpa2raw(vm, paddr); if (!(*pte & PTE_PRESENT_MASK)) { *pte = PTE_PRESENT_MASK | PTE_WRITABLE_MASK; if (current_level == target_level) - *pte |= PTE_LARGE_MASK | (paddr & PHYSICAL_PAGE_MASK); + *pte |= PTE_LARGE_MASK | (paddr_raw & PHYSICAL_PAGE_MASK); else - *pte |= vm_alloc_page_table(vm) & PHYSICAL_PAGE_MASK; + *pte |= addr_gpa2raw(vm, vm_alloc_page_table(vm)) & PHYSICAL_PAGE_MASK; + } else { /* * Entry already present. Assert that the caller doesn't want @@ -184,6 +186,8 @@ void __virt_pg_map(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr, int level) "Physical address beyond maximum supported,\n" " paddr: 0x%lx vm->max_gfn: 0x%lx vm->page_size: 0x%x", paddr, vm->max_gfn, vm->page_size); + TEST_ASSERT(addr_raw2gpa(vm, paddr) == paddr, + "Unexpected bits in paddr: %lx", paddr); /* * Allocate upper level page tables, if not already present. Return @@ -206,7 +210,8 @@ void __virt_pg_map(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr, int level) pte = virt_get_pte(vm, PTE_GET_PFN(*pde), vaddr, PG_LEVEL_4K); TEST_ASSERT(!(*pte & PTE_PRESENT_MASK), "PTE already present for 4k page at vaddr: 0x%lx\n", vaddr); - *pte = PTE_PRESENT_MASK | PTE_WRITABLE_MASK | (paddr & PHYSICAL_PAGE_MASK); + *pte = PTE_PRESENT_MASK | PTE_WRITABLE_MASK | + (addr_gpa2raw(vm, paddr) & PHYSICAL_PAGE_MASK); } void virt_arch_pg_map(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr) @@ -515,7 +520,7 @@ vm_paddr_t addr_arch_gva2gpa(struct kvm_vm *vm, vm_vaddr_t gva) if (!(pte[index[0]] & PTE_PRESENT_MASK)) goto unmapped_gva; - return (PTE_GET_PFN(pte[index[0]]) * vm->page_size) + (gva & ~PAGE_MASK); + return addr_raw2gpa(vm, PTE_GET_PFN(pte[index[0]]) * vm->page_size) + (gva & ~PAGE_MASK); unmapped_gva: TEST_FAIL("No mapping for vm virtual address, gva: 0x%lx", gva); -- 2.37.1.559.g78731f0fdb-goog