Received: by 2002:a05:7412:798b:b0:fc:a2b0:25d7 with SMTP id fb11csp679039rdb; Thu, 22 Feb 2024 16:44:23 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCUJU9mAaaV0N7WiZPBhedi35KKySTVOChUMBuxYtNGtaKY93vSw/RMWep42yscmxEFKRm82Ikkexnjec712XVE/4JiV0tm14wfjsBBSnA== X-Google-Smtp-Source: AGHT+IGU0BwckFWMg2OB4nHSba4cTrnsNJOfjNKCiN4lf570h2P4DGBriGjbD460N2wpoiVw1U/R X-Received: by 2002:a05:6214:d4c:b0:68f:2c23:dcd8 with SMTP id 12-20020a0562140d4c00b0068f2c23dcd8mr1216684qvr.29.1708649063105; Thu, 22 Feb 2024 16:44:23 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708649063; cv=pass; d=google.com; s=arc-20160816; b=O94pSuP2BLwI7YrNalOwVqdsY6/YQ8H5BcJG+xviXQvwqTgscUodAYLBPPaXTYPziE NoVePsqxBGI70J6QoaIenE+4xH0/sFh9Xtk9G1ebKku+l+T5Zf5WWwUpz62g3S05FTUF sElyzJYUsvgsX1ClrmHrjzVbguoG9+6YTw7ZzZ1f+r8eqBnWpu53eYF4vOV3xhpXQ4eg NLL+jMdKxnsnJhe/bdAu1evWGV020DBXjnZrlb1AQBvZo+bdIG/6Njg2KknUGrpdfaew BtCkhbELVLea1rnLyJfFDONyZdqC2rLfyJMGpp8h8hY/iDY+UUs8HDbaLwo/FPV5/kK6 pHsQ== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=cc:to:from:subject:message-id:references:mime-version :list-unsubscribe:list-subscribe:list-id:precedence:in-reply-to:date :reply-to:dkim-signature; bh=HqrOgwqdeyKlRqEiiRXs7cvS3neUx0UIcneX8OI5QMg=; fh=VVqTLqkqCfz4AX96k+AzTAjF9WA28GOhWS1HHqaShks=; b=dG10yQEbie3q4z8r1yMmL3uu5M+gORTxMzF3tdtGzZCw4hxKSfCqSchqFy+43BFMMT AqxxNRK7ojyrH+BI0izyxmBEgu9in1CBTjY8cTKGDRTFmuWsU/OvYduUOP2ogOk1uljL gOhJW3J87b7kwApWK/psREjm+kJl7eTA4kM2aj6+SVNaCZNlbZvPUojmzPgGgQkCRfGR 4RmZBakeOaJOIQP/Hqx8El5rqxVhbGutYSSjTsoIir2McxOV+7O2CfcjmVnCuNCd3243 sa7v60sAAyeTnAOKhapI1GuUcXeGIY8ttfoAnAuCRhYpu6jVhGSFMyhg1cOBKN0zVyJ5 RiqA==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=aQEWBEBw; arc=pass (i=1 spf=pass spfdomain=flex--seanjc.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-77585-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77585-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [147.75.199.223]) by mx.google.com with ESMTPS id t5-20020ad45bc5000000b0067f49d274besi13994689qvt.428.2024.02.22.16.44.22 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 Feb 2024 16:44:23 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-77585-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) client-ip=147.75.199.223; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=aQEWBEBw; arc=pass (i=1 spf=pass spfdomain=flex--seanjc.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-77585-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77585-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ny.mirrors.kernel.org (Postfix) with ESMTPS id 85BC41C224E6 for ; Fri, 23 Feb 2024 00:44:22 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 559B810A0F; Fri, 23 Feb 2024 00:43:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="aQEWBEBw" Received: from mail-yb1-f202.google.com (mail-yb1-f202.google.com [209.85.219.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 496F9CA73 for ; Fri, 23 Feb 2024 00:43:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.202 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708648992; cv=none; b=WoEc8Xtub/FN+XZtPoDFGmuKcaIHKF6Uv2534KM6/NY2Ou+S5r8aVSVrzBYNBBZ+B70jLwSxvZIVXKazBy+r70Q/AO2mywUBkPrkpZIdMvslXeN1lWWno0uo6ct9LOJuyL4SUJzjbssS87alOZ9tKkLU2LAeJR1nSN221QsKKLA= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708648992; c=relaxed/simple; bh=kOWMpHRm0Jt6rsGNN4rcuUv5pHmG0Bajgke/K8TPQlw=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=R3swIlzlaHM9hU/ZN3Pp9JCG2r7LiWnbFWcYgJQF9oytDHb3oXCZfX8Bd8hRHMufVogWAoySQm9J6dmevnXyBai7wNvpoZ/7+V30g8pkDY2ZJfEd9bKxrPb2u9/I6GBs5OzAnH0cvG5L6BK8lMwmx9oed4UZpkNdh2lpW5fDV48= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=aQEWBEBw; arc=none smtp.client-ip=209.85.219.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com Received: by mail-yb1-f202.google.com with SMTP id 3f1490d57ef6-dc6b26eef6cso425073276.3 for ; Thu, 22 Feb 2024 16:43:10 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1708648989; x=1709253789; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:from:to:cc:subject:date:message-id:reply-to; bh=HqrOgwqdeyKlRqEiiRXs7cvS3neUx0UIcneX8OI5QMg=; b=aQEWBEBwkqntI56A32yvU+TzYfrUGEtwR7LHvWnjZTTOCDLtIIfVp+1ArIfc1u8ycu nAWWA1EhGy7NGJlFkIhps/7bNmHhsI5XR0Fa+jh0pIeXHrc2YDXYKMRHEyzYQh1ndUdu lO/ZTN5HSPKgXqylaH86fwmg5304SXqqG/F/L0Iv4x15vle1MWkrNeRLNsCc6fmuRpQH 7RGWMk7EMITNDvtl9slESSt+htJ5vfpxV7qDOF5IvZNWOjRPUBqZhp+u0kV02cS4yaO2 wH3OicR9QYQPqk3zyhFv7IdTCs2A4ea94sCcRR52AWGylv01cQQp2jn04cNHi3yD4Ado Lv4A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1708648989; x=1709253789; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=HqrOgwqdeyKlRqEiiRXs7cvS3neUx0UIcneX8OI5QMg=; b=gJ1rjQGjDzFemARJxAhbB1J5JSYeqWhwLx6iuYoczA9019Z5sCIRmiDIvsO7/xJDAl GRNgWlliwansSm38rzaCvlafdhOjjxBfMuoD3JYTpAXUMemoCqfEUxkH7xxR1w7EhNnS g8Q31pzVE2G+D7V4mtkLBOU3JH7BKRZ/CSGijqxZroiBPdmPWxVhvTwZxuPmDO+3+QXz 6aIuPhW0FSwj6SdSW7URXloVmiZnZBytIJosfHc7mBK9JhsvUYIHi25IckOLqsPqAIor f7/U1DkS1JvE6WpWkq/D/RZ3Lo8fQikE+HOYk0GE1JDPTpwICja4dnF/MRl8kcE8mK+v f7Sw== X-Forwarded-Encrypted: i=1; AJvYcCWbKTYhq+qEmHFWOgSqb2GrPFB8ORQ2oNTiHCr0uIdKlQadtSjAwlKmAc4aqBkN2+mcitedapnqw9bg6QtJDgVMKLfZiKrFZ7/E6SyC X-Gm-Message-State: AOJu0Yyeq9uRbWZ/007A8IiK6dFxTHX/ej5yJwfob/B+zmrRobefqnwa AsHsaLpnwnTWhHA2RFJ2U/kz7rdL4ilTNEwsKuTtOvM5zCgZ2PVz1HZDOXgUF0sy3laxcB4xc60 LKg== X-Received: from zagreus.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:5c37]) (user=seanjc job=sendgmr) by 2002:a05:6902:181f:b0:dcc:94b7:a7a3 with SMTP id cf31-20020a056902181f00b00dcc94b7a7a3mr21587ybb.12.1708648989306; Thu, 22 Feb 2024 16:43:09 -0800 (PST) Reply-To: Sean Christopherson Date: Thu, 22 Feb 2024 16:42:51 -0800 In-Reply-To: <20240223004258.3104051-1-seanjc@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240223004258.3104051-1-seanjc@google.com> X-Mailer: git-send-email 2.44.0.rc0.258.g7320e95886-goog Message-ID: <20240223004258.3104051-5-seanjc@google.com> Subject: [PATCH v9 04/11] KVM: selftests: Add support for allocating/managing protected guest memory From: Sean Christopherson To: Paolo Bonzini , Marc Zyngier , Oliver Upton , Anup Patel , Paul Walmsley , Palmer Dabbelt , Albert Ou , Christian Borntraeger , Janosch Frank , Claudio Imbrenda , Sean Christopherson Cc: kvm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev, kvm-riscv@lists.infradead.org, linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org, Vishal Annapurve , Ackerley Tng , Andrew Jones , Tom Lendacky , Michael Roth , Carlos Bilbao , Peter Gonda , Itaru Kitayama Content-Type: text/plain; charset="UTF-8" From: Peter Gonda Add support for differentiating between protected (a.k.a. private, a.k.a. encrypted) memory and normal (a.k.a. shared) memory for VMs that support protected guest memory, e.g. x86's SEV. Provide and manage a common bitmap for tracking whether a given physical page resides in protected memory, as support for protected memory isn't x86 specific, i.e. adding a arch hook would be a net negative now, and in the future. Cc: Paolo Bonzini Cc: Sean Christopherson Cc: Vishal Annapurve Cc: Ackerley Tng cc: Andrew Jones Cc: Tom Lendacky Cc: Michael Roth Reviewed-by: Itaru Kitayama Tested-by: Carlos Bilbao Originally-by: Michael Roth Signed-off-by: Peter Gonda Co-developed-by: Sean Christopherson Signed-off-by: Sean Christopherson --- .../selftests/kvm/include/kvm_util_base.h | 25 +++++++++++++++++-- tools/testing/selftests/kvm/lib/kvm_util.c | 22 +++++++++++++--- 2 files changed, 41 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 d9dc31af2f96..a82149305349 100644 --- a/tools/testing/selftests/kvm/include/kvm_util_base.h +++ b/tools/testing/selftests/kvm/include/kvm_util_base.h @@ -46,6 +46,7 @@ typedef uint64_t vm_vaddr_t; /* Virtual Machine (Guest) virtual address */ struct userspace_mem_region { struct kvm_userspace_memory_region2 region; struct sparsebit *unused_phy_pages; + struct sparsebit *protected_phy_pages; int fd; off_t offset; enum vm_mem_backing_src_type backing_src_type; @@ -573,6 +574,13 @@ void vm_mem_add(struct kvm_vm *vm, enum vm_mem_backing_src_type src_type, uint64_t guest_paddr, uint32_t slot, uint64_t npages, uint32_t flags, int guest_memfd_fd, uint64_t guest_memfd_offset); +#ifndef vm_arch_has_protected_memory +static inline bool vm_arch_has_protected_memory(struct kvm_vm *vm) +{ + return false; +} +#endif + void vm_mem_region_set_flags(struct kvm_vm *vm, uint32_t slot, uint32_t flags); void vm_mem_region_move(struct kvm_vm *vm, uint32_t slot, uint64_t new_gpa); void vm_mem_region_delete(struct kvm_vm *vm, uint32_t slot); @@ -836,10 +844,23 @@ const char *exit_reason_str(unsigned int exit_reason); vm_paddr_t vm_phy_page_alloc(struct kvm_vm *vm, vm_paddr_t paddr_min, uint32_t memslot); -vm_paddr_t vm_phy_pages_alloc(struct kvm_vm *vm, size_t num, - vm_paddr_t paddr_min, uint32_t memslot); +vm_paddr_t __vm_phy_pages_alloc(struct kvm_vm *vm, size_t num, + vm_paddr_t paddr_min, uint32_t memslot, + bool protected); vm_paddr_t vm_alloc_page_table(struct kvm_vm *vm); +static inline vm_paddr_t vm_phy_pages_alloc(struct kvm_vm *vm, size_t num, + vm_paddr_t paddr_min, uint32_t memslot) +{ + /* + * By default, allocate memory as protected for VMs that support + * protected memory, as the majority of memory for such VMs is + * protected, i.e. using shared memory is effectively opt-in. + */ + return __vm_phy_pages_alloc(vm, num, paddr_min, memslot, + vm_arch_has_protected_memory(vm)); +} + /* * ____vm_create() does KVM_CREATE_VM and little else. __vm_create() also * loads the test binary into guest memory and creates an IRQ chip (x86 only). diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c index a53caf81eb87..ea677aa019ef 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util.c +++ b/tools/testing/selftests/kvm/lib/kvm_util.c @@ -717,6 +717,7 @@ static void __vm_mem_region_delete(struct kvm_vm *vm, vm_ioctl(vm, KVM_SET_USER_MEMORY_REGION2, ®ion->region); sparsebit_free(®ion->unused_phy_pages); + sparsebit_free(®ion->protected_phy_pages); ret = munmap(region->mmap_start, region->mmap_size); TEST_ASSERT(!ret, __KVM_SYSCALL_ERROR("munmap()", ret)); if (region->fd >= 0) { @@ -1098,6 +1099,8 @@ void vm_mem_add(struct kvm_vm *vm, enum vm_mem_backing_src_type src_type, } region->unused_phy_pages = sparsebit_alloc(); + if (vm_arch_has_protected_memory(vm)) + region->protected_phy_pages = sparsebit_alloc(); sparsebit_set_num(region->unused_phy_pages, guest_paddr >> vm->page_shift, npages); region->region.slot = slot; @@ -1924,6 +1927,10 @@ void vm_dump(FILE *stream, struct kvm_vm *vm, uint8_t indent) region->host_mem); fprintf(stream, "%*sunused_phy_pages: ", indent + 2, ""); sparsebit_dump(stream, region->unused_phy_pages, 0); + if (region->protected_phy_pages) { + fprintf(stream, "%*sprotected_phy_pages: ", indent + 2, ""); + sparsebit_dump(stream, region->protected_phy_pages, 0); + } } fprintf(stream, "%*sMapped Virtual Pages:\n", indent, ""); sparsebit_dump(stream, vm->vpages_mapped, indent + 2); @@ -2025,6 +2032,7 @@ const char *exit_reason_str(unsigned int exit_reason) * num - number of pages * paddr_min - Physical address minimum * memslot - Memory region to allocate page from + * protected - True if the pages will be used as protected/private memory * * Output Args: None * @@ -2036,8 +2044,9 @@ const char *exit_reason_str(unsigned int exit_reason) * and their base address is returned. A TEST_ASSERT failure occurs if * not enough pages are available at or above paddr_min. */ -vm_paddr_t vm_phy_pages_alloc(struct kvm_vm *vm, size_t num, - vm_paddr_t paddr_min, uint32_t memslot) +vm_paddr_t __vm_phy_pages_alloc(struct kvm_vm *vm, size_t num, + vm_paddr_t paddr_min, uint32_t memslot, + bool protected) { struct userspace_mem_region *region; sparsebit_idx_t pg, base; @@ -2050,8 +2059,10 @@ vm_paddr_t vm_phy_pages_alloc(struct kvm_vm *vm, size_t num, paddr_min, vm->page_size); region = memslot2region(vm, memslot); + TEST_ASSERT(!protected || region->protected_phy_pages, + "Region doesn't support protected memory"); + base = pg = paddr_min >> vm->page_shift; - do { for (; pg < base + num; ++pg) { if (!sparsebit_is_set(region->unused_phy_pages, pg)) { @@ -2070,8 +2081,11 @@ vm_paddr_t vm_phy_pages_alloc(struct kvm_vm *vm, size_t num, abort(); } - for (pg = base; pg < base + num; ++pg) + for (pg = base; pg < base + num; ++pg) { sparsebit_clear(region->unused_phy_pages, pg); + if (protected) + sparsebit_set(region->protected_phy_pages, pg); + } return base * vm->page_size; } -- 2.44.0.rc0.258.g7320e95886-goog