Received: by 2002:ad5:4acb:0:0:0:0:0 with SMTP id n11csp771000imw; Fri, 15 Jul 2022 12:32:31 -0700 (PDT) X-Google-Smtp-Source: AGRyM1vT2qmzTsbWB1n9wjggNLaJ+7VkvXjYgOGi3srCP5GHNULqq/Om8ccIaGsikS2Ln568rhNE X-Received: by 2002:a05:6871:93:b0:fe:23b6:6efb with SMTP id u19-20020a056871009300b000fe23b66efbmr8163506oaa.201.1657913551543; Fri, 15 Jul 2022 12:32:31 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1657913551; cv=none; d=google.com; s=arc-20160816; b=0pkVEZdomrMbIDWBODtDbmkCkdRcYC2Ypo3q6OeXqSuSUQh2rIfgLaMZM44oED3zPi tLmh7kH6+tciwmvxqtnbFf6tKLz7Tt8a7oN6+aQILFLgrfggIAPhxVAvKGNcX92t550I +wv6xC6ix4Rn69dceh9gjuV8hTvqtpUwe2nLFnEs3BbcaDpdvS7/NmjyF+7z54qZaxY9 r1m/fmgTeTOTgkqn4wdCL5F45I6Izgj4jd4Bd9M0ZYUZ721L0XFp0gXGyWzlPo8N8A6g 8I2bYFSsZA9kB6PwTy6JXp3kJXCyIJrgBvj1GLDJonSNEkRuI7NDQdYa3/yyXeYem1wN IcXg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:from:subject:references:mime-version :message-id:in-reply-to:date:dkim-signature; bh=yOrbZ7RaV7Jx4ZXQ1D7tU72Pr1kFVsoHo/rJhv/+f3g=; b=hzLreTH42MivDM79hXAsYec0vn+M/354+o8QPZjoFyseO1Bd6Hzelel+e2Y3tiaJIx QroZUga8YWRw2ri7UHSE61KfQYaU0E9SRl9dXjXzulKluU7WptFU/N4F0nFGJDQkf3lN 47hdDUbbWXd3/Mq2vYA/ZYszS3Pzu0OiX67NdIhBeYvcvqLjch+JRwzvXs42fiG16rGo aPO/3ZlVUj2nBcfZE+KVo5TDHFBV4DFaO6iJLPX9fWdl9mYddWMVOLuOWIe0WkWDcEA6 4QurmKqkwztyl5eqBds/dhd0dfhV60u0KqCIYgajg62Fk97gnMK9o6Sz+Puz1nxrRhzJ tTow== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20210112 header.b=oArOwSWG; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id u3-20020a056870d58300b0010200d63a12si5621274oao.199.2022.07.15.12.32.18; Fri, 15 Jul 2022 12:32:31 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20210112 header.b=oArOwSWG; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231411AbiGOTa3 (ORCPT + 99 others); Fri, 15 Jul 2022 15:30:29 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60862 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231326AbiGOTaT (ORCPT ); Fri, 15 Jul 2022 15:30:19 -0400 Received: from mail-pg1-x54a.google.com (mail-pg1-x54a.google.com [IPv6:2607:f8b0:4864:20::54a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5458071BEE for ; Fri, 15 Jul 2022 12:30:15 -0700 (PDT) Received: by mail-pg1-x54a.google.com with SMTP id 81-20020a630054000000b0041978b2aa9eso3148765pga.9 for ; Fri, 15 Jul 2022 12:30:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=yOrbZ7RaV7Jx4ZXQ1D7tU72Pr1kFVsoHo/rJhv/+f3g=; b=oArOwSWG8Bb9+5BGHMFgAnUdMJxS2ROAx0bvTpoTeYW2xU5V2YPuMnDS8qUXvn+fvW Ql+JiTST9SKDeO+ivkOfAJj7zazO4OTmqwrxFZRYnEznjhQOw9BBiTNMom7bjYgr8kV0 oyw35ZqK1AxRHnIXQHJW3fVxvYj4+YlXxasXIWCRvlo2HqVFD+MfYOivXiuP1Qblk5wO ja68CsCXWGbxy9+mZRXaWBtLOxdX7R8RJfKQ/mdHfuVjXjFGBsrfBoodbYThusFjUJJY cbpDCsyiGE5LURNEhxzmqUdGt5fPbqsAnOPD9GQDKE+0feDY+z0DDkHeh1vEmxmy5IDX 1Eew== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=yOrbZ7RaV7Jx4ZXQ1D7tU72Pr1kFVsoHo/rJhv/+f3g=; b=TWWXHbdnLZAkc6dsNOjb0/00c5+zyD2MgoCcdRc9J09dOt7Q3tTfE91Z02DlxeVKIX saStOMLIW/zaydD6AwxMsVk9U63c4S+fKc/nnqKUOqXAbOziGok/9At36MOARQKKwl6X qzwUgQsD49fWJ/HVCmwLzPb1uvF1z8hGcFAO2AFWTnagij0SbbxIFIS+nDk/P5ShqYrH kcfh9TAypHOk8bUcgksjOUi6Hex3DYl6l2nwnggxtMMs4jTVaK0Sp30erZAGqKNfQ7AV 7d7y8NoE8XfRbK+zkcZv/KbfrXJHhMLq4IXCMdzai1q833MAR1T5roHocV22vzJ55V8K 6pmw== X-Gm-Message-State: AJIora+fVbaHoOCKDgcPAA0DFXBIsMlACzTfFnEirmgdn7eDhbAk3nko HCogy3x1F9tyUdEO1rj2lQCzHqNScvI= X-Received: from pgonda1.kir.corp.google.com ([2620:15c:29:203:bd4e:b81d:4780:497d]) (user=pgonda job=sendgmr) by 2002:a17:90a:249:b0:1e0:a8a3:3c6c with SMTP id t9-20020a17090a024900b001e0a8a33c6cmr911058pje.0.1657913414519; Fri, 15 Jul 2022 12:30:14 -0700 (PDT) Date: Fri, 15 Jul 2022 12:29:50 -0700 In-Reply-To: <20220715192956.1873315-1-pgonda@google.com> Message-Id: <20220715192956.1873315-6-pgonda@google.com> Mime-Version: 1.0 References: <20220715192956.1873315-1-pgonda@google.com> X-Mailer: git-send-email 2.37.0.170.g444d1eabd0-goog Subject: [RFC V1 04/10] 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, Peter Gonda Content-Type: text/plain; charset="UTF-8" X-Spam-Status: No, score=-9.6 required=5.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net 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 3acb1552942b..17eb5fb70867 100644 --- a/tools/testing/selftests/kvm/include/kvm_util_base.h +++ b/tools/testing/selftests/kvm/include/kvm_util_base.h @@ -396,6 +396,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 6f96d1c51f75..5b473a8c90ae 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util.c +++ b/tools/testing/selftests/kvm/lib/kvm_util.c @@ -1365,6 +1365,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 * @@ -1382,9 +1434,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 1a32b1c75e9a..53b115876417 100644 --- a/tools/testing/selftests/kvm/lib/x86_64/processor.c +++ b/tools/testing/selftests/kvm/lib/x86_64/processor.c @@ -116,7 +116,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; } } @@ -138,13 +138,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 @@ -182,6 +184,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 @@ -204,7 +208,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) @@ -517,7 +522,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.0.170.g444d1eabd0-goog