From patchwork Wed Mar 12 17:58:15 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fuad Tabba X-Patchwork-Id: 872849 Received: from mail-wm1-f73.google.com (mail-wm1-f73.google.com [209.85.128.73]) (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 307B72571A3 for ; Wed, 12 Mar 2025 17:58:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741802313; cv=none; b=Ot32qkb4puG2i3A09sCDpJSagBcFjUgA3lNSnSEFw2I4hj0rYbIr+XsFio3ZnSBNRLDe7zpra5hIhtjF77BY15ZJ/5lRfd/VDJ4AbmsD3md1FzqWIWPZvLu7vOpI16mV0rmaeM8nCMuP168PU67FFMdLk1dpPN2fvvrx14/SWdY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741802313; c=relaxed/simple; bh=DE5SQ9QQ7pg1t8bcHulsVBC516s9NBbF9b2TCSRWhrE=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=jiKezM4xVy83YpGCrnHgZeN1MqLkFTpOkdqi/UK9zSQFn5lOOOiY3EoCCcf5tgn7dXhg+A6R2u6yPNmrLNphdfjUdE8ZpTouRSygjPvVKfVT0z0judpyAD6JBEKtbXQsSs27O8Z7VaCBr8nnSgbHlVqqNvpoqt09CpSZCQEYX+4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--tabba.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=YVlrTEnv; arc=none smtp.client-ip=209.85.128.73 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--tabba.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="YVlrTEnv" Received: by mail-wm1-f73.google.com with SMTP id 5b1f17b1804b1-43d007b2c79so431945e9.2 for ; Wed, 12 Mar 2025 10:58:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1741802309; x=1742407109; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=ZH2ddFSySXL8ljh40ScGRRkvOagkKQt0yLw/o+/C9xs=; b=YVlrTEnvS/mArfraNJ6Njg2NDyWAtR1pXL87nKDvWL5UUSPv4V8hU6jHRtF6rUEiWh AsHyAOAnPFJugpJdCkf+2xZH5OahStVcM+lEhxOBPvgYZJWXKO4AL8lWs1oBLho5Gm9a CCTxSRwlGRIw2lor+5BLy03y3fpmoccu7p5PDG2mYeVS1WFd4LlvshZgHmNwwqqHz2sD 15GYzNdqY5/HLtGGJhYhKO9VbYu5BVJsjMbX+Fa5okuNIhf60HnMdabF1PoMxvLFAm1q d//i4Xun91Hg9ANJXRihMQ/G/oFjExMXzfTKJMLDouPTaDRap+qMCbQ7hG1S9NP9BmYP c4YQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741802309; x=1742407109; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=ZH2ddFSySXL8ljh40ScGRRkvOagkKQt0yLw/o+/C9xs=; b=m5e9FRx+6siqqI7WIbC9qdgnSVLOmPKrsTV9GjNC6g7U4pjEjAFW5ntb+gxXjnoDUq o33lIXoYYWNN26u5yu2X3x+t+peIP0WDbL8CMFYZ6Bk2QqYLHW1D9zHnqa9w+/nlqYP1 cM4zXb0zJAVdrgydp8DPFByVkdzxaHBzgaXoMk2zEidsdDnpAekDENsU0+wgOdyMQ0YD OKe2V0eV9pcomyeG68Y6t6GPdc4gDIV0Lb4wQOmvCc7Lc0Fy0ksJ5qiJjJ1oWO4SQ/Uj vxhcsKmaBJ0v5R/BB0/0ZhLajJ9Uor70bAc5SETQYL2/pA9ZbfkwbfRe3mDetnzHr0X+ mMUQ== X-Forwarded-Encrypted: i=1; AJvYcCUaqYH96Sg7YA/QXw/aL+cN3kqLdsdu4ltvpqfFLYf4e5Y1eq8/huyT4hmsbBjM6xoO9d+6ZOXDHw4ONq+c@vger.kernel.org X-Gm-Message-State: AOJu0Yyh2joE8wXuM867hKUP32JSLB01A0hMagU+W7biAtvLPBIvNlg0 6ERA0va+jUMOOAPD36ZOlrwB3NGNoKLFLL9enki7gs4n5gqh7toZEQxeNpAvn3gQvSfBWHSkTA= = X-Google-Smtp-Source: AGHT+IG3QL0FD0w8QJ+6eYUXr0ym7H16e0KnHlntRiSz0AzMSuHdXLBjD/jyLDhLgORTX5AXNY0xHban7Q== X-Received: from wmbgz9-n2.prod.google.com ([2002:a05:600c:8889:20b0:43c:fcbd:f2eb]) (user=tabba job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:4f90:b0:43d:fa:1f9a with SMTP id 5b1f17b1804b1-43d01c22acfmr99270665e9.30.1741802309618; Wed, 12 Mar 2025 10:58:29 -0700 (PDT) Date: Wed, 12 Mar 2025 17:58:15 +0000 In-Reply-To: <20250312175824.1809636-1-tabba@google.com> Precedence: bulk X-Mailing-List: linux-arm-msm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20250312175824.1809636-1-tabba@google.com> X-Mailer: git-send-email 2.49.0.rc0.332.g42c0ae87b1-goog Message-ID: <20250312175824.1809636-3-tabba@google.com> Subject: [PATCH v6 02/10] KVM: guest_memfd: Handle final folio_put() of guest_memfd pages From: Fuad Tabba To: kvm@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-mm@kvack.org Cc: pbonzini@redhat.com, chenhuacai@kernel.org, mpe@ellerman.id.au, anup@brainfault.org, paul.walmsley@sifive.com, palmer@dabbelt.com, aou@eecs.berkeley.edu, seanjc@google.com, viro@zeniv.linux.org.uk, brauner@kernel.org, willy@infradead.org, akpm@linux-foundation.org, xiaoyao.li@intel.com, yilun.xu@intel.com, chao.p.peng@linux.intel.com, jarkko@kernel.org, amoorthy@google.com, dmatlack@google.com, isaku.yamahata@intel.com, mic@digikod.net, vbabka@suse.cz, vannapurve@google.com, ackerleytng@google.com, mail@maciej.szmigiero.name, david@redhat.com, michael.roth@amd.com, wei.w.wang@intel.com, liam.merwick@oracle.com, isaku.yamahata@gmail.com, kirill.shutemov@linux.intel.com, suzuki.poulose@arm.com, steven.price@arm.com, quic_eberman@quicinc.com, quic_mnalajal@quicinc.com, quic_tsoni@quicinc.com, quic_svaddagi@quicinc.com, quic_cvanscha@quicinc.com, quic_pderrin@quicinc.com, quic_pheragu@quicinc.com, catalin.marinas@arm.com, james.morse@arm.com, yuzenghui@huawei.com, oliver.upton@linux.dev, maz@kernel.org, will@kernel.org, qperret@google.com, keirf@google.com, roypat@amazon.co.uk, shuah@kernel.org, hch@infradead.org, jgg@nvidia.com, rientjes@google.com, jhubbard@nvidia.com, fvdl@google.com, hughd@google.com, jthoughton@google.com, peterx@redhat.com, tabba@google.com Before transitioning a guest_memfd folio to unshared, thereby disallowing access by the host and allowing the hypervisor to transition its view of the guest page as private, we need to be sure that the host doesn't have any references to the folio. This patch introduces a new type for guest_memfd folios, which isn't activated in this series but is here as a placeholder and to facilitate the code in the subsequent patch series. This will be used in the future to register a callback that informs the guest_memfd subsystem when the last reference is dropped, therefore knowing that the host doesn't have any remaining references. This patch also introduces the configuration option, KVM_GMEM_SHARED_MEM, which toggles support for mapping guest_memfd shared memory at the host. Signed-off-by: Fuad Tabba Acked-by: Vlastimil Babka Acked-by: David Hildenbrand --- include/linux/kvm_host.h | 7 +++++++ include/linux/page-flags.h | 16 ++++++++++++++++ mm/debug.c | 1 + mm/swap.c | 9 +++++++++ virt/kvm/Kconfig | 4 ++++ 5 files changed, 37 insertions(+) diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index f34f4cfaa513..7788e3625f6d 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -2571,4 +2571,11 @@ long kvm_arch_vcpu_pre_fault_memory(struct kvm_vcpu *vcpu, struct kvm_pre_fault_memory *range); #endif +#ifdef CONFIG_KVM_GMEM_SHARED_MEM +static inline void kvm_gmem_handle_folio_put(struct folio *folio) +{ + WARN_ONCE(1, "A placeholder that shouldn't trigger. Work in progress."); +} +#endif + #endif diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h index 6dc2494bd002..daeee9a38e4c 100644 --- a/include/linux/page-flags.h +++ b/include/linux/page-flags.h @@ -933,6 +933,7 @@ enum pagetype { PGTY_slab = 0xf5, PGTY_zsmalloc = 0xf6, PGTY_unaccepted = 0xf7, + PGTY_guestmem = 0xf8, PGTY_mapcount_underflow = 0xff }; @@ -1082,6 +1083,21 @@ FOLIO_TYPE_OPS(hugetlb, hugetlb) FOLIO_TEST_FLAG_FALSE(hugetlb) #endif +/* + * guestmem folios are used to back VM memory as managed by guest_memfd. Once + * the last reference is put, instead of freeing these folios back to the page + * allocator, they are returned to guest_memfd. + * + * For now, guestmem will only be set on these folios as long as they cannot be + * mapped to user space ("private state"), with the plan of always setting that + * type once typed folios can be mapped to user space cleanly. + */ +#ifdef CONFIG_KVM_GMEM_SHARED_MEM +FOLIO_TYPE_OPS(guestmem, guestmem) +#else +FOLIO_TEST_FLAG_FALSE(guestmem) +#endif + PAGE_TYPE_OPS(Zsmalloc, zsmalloc, zsmalloc) /* diff --git a/mm/debug.c b/mm/debug.c index 8d2acf432385..08bc42c6cba8 100644 --- a/mm/debug.c +++ b/mm/debug.c @@ -56,6 +56,7 @@ static const char *page_type_names[] = { DEF_PAGETYPE_NAME(table), DEF_PAGETYPE_NAME(buddy), DEF_PAGETYPE_NAME(unaccepted), + DEF_PAGETYPE_NAME(guestmem), }; static const char *page_type_name(unsigned int page_type) diff --git a/mm/swap.c b/mm/swap.c index 47bc1bb919cc..241880a46358 100644 --- a/mm/swap.c +++ b/mm/swap.c @@ -38,6 +38,10 @@ #include #include +#ifdef CONFIG_KVM_GMEM_SHARED_MEM +#include +#endif + #include "internal.h" #define CREATE_TRACE_POINTS @@ -101,6 +105,11 @@ static void free_typed_folio(struct folio *folio) case PGTY_hugetlb: free_huge_folio(folio); return; +#endif +#ifdef CONFIG_KVM_GMEM_SHARED_MEM + case PGTY_guestmem: + kvm_gmem_handle_folio_put(folio); + return; #endif default: WARN_ON_ONCE(1); diff --git a/virt/kvm/Kconfig b/virt/kvm/Kconfig index 54e959e7d68f..4e759e8020c5 100644 --- a/virt/kvm/Kconfig +++ b/virt/kvm/Kconfig @@ -124,3 +124,7 @@ config HAVE_KVM_ARCH_GMEM_PREPARE config HAVE_KVM_ARCH_GMEM_INVALIDATE bool depends on KVM_PRIVATE_MEM + +config KVM_GMEM_SHARED_MEM + select KVM_PRIVATE_MEM + bool From patchwork Wed Mar 12 17:58:17 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fuad Tabba X-Patchwork-Id: 872848 Received: from mail-wm1-f74.google.com (mail-wm1-f74.google.com [209.85.128.74]) (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 45919254B02 for ; Wed, 12 Mar 2025 17:58:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741802317; cv=none; b=XLCXNT8z6YNYyiar05ctLDA4PFeugTL0Z09sAWmGySImzt8YfhyIBWkFUCfi9ZgTmj0E8fvZOX6XI+9Uy4UXEaC+1RLcGAFk4VitHkadpXOTLevb9GSJlZVyJMz0vyuS9yJotly4IytzLgLBml1BgnaI+XTkxmQ3tqnwVrf6Waw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741802317; c=relaxed/simple; bh=0+R6PiRiVf6Qfgl6Xb/wXg3JYf8Soq67nwhFbPIQJKM=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=JJvmA1ExL5GsNMtTObXtzYXidMtImrki1F+oejVPnerUofjEuLwgIPbxLQ+T4vFpDGnsix+5YkoD0TBfD2qUq7wCBWlBZIH5col+nTEeRLamOVFJOd23nRaN93Az/A7J45DBKxiicEDe5Nu2M7o86cOdRe0Kl75mEzKLE3oVaY0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--tabba.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=ykbRyp2W; arc=none smtp.client-ip=209.85.128.74 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--tabba.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="ykbRyp2W" Received: by mail-wm1-f74.google.com with SMTP id 5b1f17b1804b1-43bd8fd03a2so306705e9.3 for ; Wed, 12 Mar 2025 10:58:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1741802313; x=1742407113; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=ja4c56NjFxjN3VuYRxoRbDc+8encrsyBoZ8FkcBEBAk=; b=ykbRyp2WRU4AT6iLugfQ1mGMrdf59qyDKZud5oI2dZ5/24peaNeV/STAbB6VZ9ZMle QrD/WsIEjvscNbQQj6I308Xuzy5ei4/R3JDQx6KJl3WNzf6LB8n9SntXQtpLVLGvNhYh Qn4d8P+U+Jt6ggujjQ+hMnojnzfPIUKXQQ8TAt9aKqMXjkORGv2qaFpDRRFgBOsEUKNU 02vxEJG3MJztHCctACydULMfZVWLELkmNEDVEGJEajSfNTTqcCNhEs32pGBIO/+Y88Jj MuX0J2kElylEeKE0HWVAf3CnTVrTFyAISoF/BH5OPEI2faQCJSXpSXpiyKNuDI4pupXp lUaQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741802313; x=1742407113; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=ja4c56NjFxjN3VuYRxoRbDc+8encrsyBoZ8FkcBEBAk=; b=StiG44UQcN3AxzzUyf9DHV6CmgckTbredvbYqOrIE99pkSeyc7buKN8fqbRPwz4IWW uxRsY8oTbJeYhfcZKDxTkGss7FulA+2V/zzZvD1qUwcUJjHwKUPk/qc1ZEOsYvAJl+lU O0TGTwDJ8DIS+okgCW7cDvBeYWGmIPJ/j0RgV8vzDPktfVAg8Q2B4F41sBfB25aez0EE avqUmHbL5q38dXBpbvjZNcOK62xqrlOrLwqtnXv16mF5UsVOKLhS14xiSX/bs7kozefR emvBKAwmGhMCpXadkaF6+8FvBNXrBmLydoPaVFKGFu1FTqyS/FGtuPnCDyLoqXwB7Gcn Gbyg== X-Forwarded-Encrypted: i=1; AJvYcCXX1Mtu2EWuk9Bj9XeOuFonhIeCEKPuISX8QfzV/CfuU7FYaI6M2zMWOYrkp5ks8UMRkvAIhpCUryaCsjDN@vger.kernel.org X-Gm-Message-State: AOJu0YwX2VetX3MPEvmycYVEWi8Wq9gkRTBEJx0Fu1McqOkcUKs3OPtU TD/3xC8ueEIb6AFAvDjRk+p03ltT9bCV1CdFHSXasnZGFuHl2ppkA/2EApxFc4AGQ6oCGNd6LA= = X-Google-Smtp-Source: AGHT+IH6LramvrAethqSEJ43co3nUgcdaI6Hl8zlyi/Cxvas2W6mO2vl5zZ/oeJPP/4J6sjTcPIlLBCdsQ== X-Received: from wmbfl17.prod.google.com ([2002:a05:600c:b91:b0:43c:f5f7:f76a]) (user=tabba job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:1ca0:b0:43c:f5e4:895e with SMTP id 5b1f17b1804b1-43cf5e48a1dmr101433505e9.1.1741802313446; Wed, 12 Mar 2025 10:58:33 -0700 (PDT) Date: Wed, 12 Mar 2025 17:58:17 +0000 In-Reply-To: <20250312175824.1809636-1-tabba@google.com> Precedence: bulk X-Mailing-List: linux-arm-msm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20250312175824.1809636-1-tabba@google.com> X-Mailer: git-send-email 2.49.0.rc0.332.g42c0ae87b1-goog Message-ID: <20250312175824.1809636-5-tabba@google.com> Subject: [PATCH v6 04/10] KVM: guest_memfd: Allow host to map guest_memfd() pages From: Fuad Tabba To: kvm@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-mm@kvack.org Cc: pbonzini@redhat.com, chenhuacai@kernel.org, mpe@ellerman.id.au, anup@brainfault.org, paul.walmsley@sifive.com, palmer@dabbelt.com, aou@eecs.berkeley.edu, seanjc@google.com, viro@zeniv.linux.org.uk, brauner@kernel.org, willy@infradead.org, akpm@linux-foundation.org, xiaoyao.li@intel.com, yilun.xu@intel.com, chao.p.peng@linux.intel.com, jarkko@kernel.org, amoorthy@google.com, dmatlack@google.com, isaku.yamahata@intel.com, mic@digikod.net, vbabka@suse.cz, vannapurve@google.com, ackerleytng@google.com, mail@maciej.szmigiero.name, david@redhat.com, michael.roth@amd.com, wei.w.wang@intel.com, liam.merwick@oracle.com, isaku.yamahata@gmail.com, kirill.shutemov@linux.intel.com, suzuki.poulose@arm.com, steven.price@arm.com, quic_eberman@quicinc.com, quic_mnalajal@quicinc.com, quic_tsoni@quicinc.com, quic_svaddagi@quicinc.com, quic_cvanscha@quicinc.com, quic_pderrin@quicinc.com, quic_pheragu@quicinc.com, catalin.marinas@arm.com, james.morse@arm.com, yuzenghui@huawei.com, oliver.upton@linux.dev, maz@kernel.org, will@kernel.org, qperret@google.com, keirf@google.com, roypat@amazon.co.uk, shuah@kernel.org, hch@infradead.org, jgg@nvidia.com, rientjes@google.com, jhubbard@nvidia.com, fvdl@google.com, hughd@google.com, jthoughton@google.com, peterx@redhat.com, tabba@google.com Add support for mmap() and fault() for guest_memfd backed memory in the host for VMs that support in-place conversion between shared and private. To that end, this patch adds the ability to check whether the VM type supports in-place conversion, and only allows mapping its memory if that's the case. Also add the KVM capability KVM_CAP_GMEM_SHARED_MEM, which indicates that the VM supports shared memory in guest_memfd, or that the host can create VMs that support shared memory. Supporting shared memory implies that memory can be mapped when shared with the host. This is controlled by the KVM_GMEM_SHARED_MEM configuration option. Signed-off-by: Fuad Tabba --- include/linux/kvm_host.h | 11 +++++ include/uapi/linux/kvm.h | 1 + virt/kvm/guest_memfd.c | 102 +++++++++++++++++++++++++++++++++++++++ virt/kvm/kvm_main.c | 4 ++ 4 files changed, 118 insertions(+) diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 3ad0719bfc4f..601bbcaa5e41 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -728,6 +728,17 @@ static inline bool kvm_arch_has_private_mem(struct kvm *kvm) } #endif +/* + * Arch code must define kvm_arch_gmem_supports_shared_mem if support for + * private memory is enabled and it supports in-place shared/private conversion. + */ +#if !defined(kvm_arch_gmem_supports_shared_mem) && !IS_ENABLED(CONFIG_KVM_GMEM_SHARED_MEM) +static inline bool kvm_arch_gmem_supports_shared_mem(struct kvm *kvm) +{ + return false; +} +#endif + #ifndef kvm_arch_has_readonly_mem static inline bool kvm_arch_has_readonly_mem(struct kvm *kvm) { diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index 45e6d8fca9b9..117937a895da 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -929,6 +929,7 @@ struct kvm_enable_cap { #define KVM_CAP_PRE_FAULT_MEMORY 236 #define KVM_CAP_X86_APIC_BUS_CYCLES_NS 237 #define KVM_CAP_X86_GUEST_MODE 238 +#define KVM_CAP_GMEM_SHARED_MEM 239 struct kvm_irq_routing_irqchip { __u32 irqchip; diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c index 5fc414becae5..eea44e003ed1 100644 --- a/virt/kvm/guest_memfd.c +++ b/virt/kvm/guest_memfd.c @@ -320,7 +320,109 @@ static pgoff_t kvm_gmem_get_index(struct kvm_memory_slot *slot, gfn_t gfn) return gfn - slot->base_gfn + slot->gmem.pgoff; } +#ifdef CONFIG_KVM_GMEM_SHARED_MEM +static bool folio_offset_is_shared(const struct folio *folio, struct file *file, pgoff_t index) +{ + struct kvm_gmem *gmem = file->private_data; + + VM_BUG_ON_FOLIO(!folio_test_locked(folio), folio); + + /* For now, VMs that support shared memory share all their memory. */ + return kvm_arch_gmem_supports_shared_mem(gmem->kvm); +} + +static vm_fault_t kvm_gmem_fault(struct vm_fault *vmf) +{ + struct inode *inode = file_inode(vmf->vma->vm_file); + struct folio *folio; + vm_fault_t ret = VM_FAULT_LOCKED; + + filemap_invalidate_lock_shared(inode->i_mapping); + + folio = kvm_gmem_get_folio(inode, vmf->pgoff); + if (IS_ERR(folio)) { + int err = PTR_ERR(folio); + + if (err == -EAGAIN) + ret = VM_FAULT_RETRY; + else + ret = vmf_error(err); + + goto out_filemap; + } + + if (folio_test_hwpoison(folio)) { + ret = VM_FAULT_HWPOISON; + goto out_folio; + } + + if (!folio_offset_is_shared(folio, vmf->vma->vm_file, vmf->pgoff)) { + ret = VM_FAULT_SIGBUS; + goto out_folio; + } + + /* + * Shared folios would not be marked as "guestmem" so far, and we only + * expect shared folios at this point. + */ + if (WARN_ON_ONCE(folio_test_guestmem(folio))) { + ret = VM_FAULT_SIGBUS; + goto out_folio; + } + + /* No support for huge pages. */ + if (WARN_ON_ONCE(folio_test_large(folio))) { + ret = VM_FAULT_SIGBUS; + goto out_folio; + } + + if (!folio_test_uptodate(folio)) { + clear_highpage(folio_page(folio, 0)); + kvm_gmem_mark_prepared(folio); + } + + vmf->page = folio_file_page(folio, vmf->pgoff); + +out_folio: + if (ret != VM_FAULT_LOCKED) { + folio_unlock(folio); + folio_put(folio); + } + +out_filemap: + filemap_invalidate_unlock_shared(inode->i_mapping); + + return ret; +} + +static const struct vm_operations_struct kvm_gmem_vm_ops = { + .fault = kvm_gmem_fault, +}; + +static int kvm_gmem_mmap(struct file *file, struct vm_area_struct *vma) +{ + struct kvm_gmem *gmem = file->private_data; + + if (!kvm_arch_gmem_supports_shared_mem(gmem->kvm)) + return -ENODEV; + + if ((vma->vm_flags & (VM_SHARED | VM_MAYSHARE)) != + (VM_SHARED | VM_MAYSHARE)) { + return -EINVAL; + } + + file_accessed(file); + vm_flags_set(vma, VM_DONTDUMP); + vma->vm_ops = &kvm_gmem_vm_ops; + + return 0; +} +#else +#define kvm_gmem_mmap NULL +#endif /* CONFIG_KVM_GMEM_SHARED_MEM */ + static struct file_operations kvm_gmem_fops = { + .mmap = kvm_gmem_mmap, .open = generic_file_open, .release = kvm_gmem_release, .fallocate = kvm_gmem_fallocate, diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index ba0327e2d0d3..38f0f402ea46 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -4830,6 +4830,10 @@ static int kvm_vm_ioctl_check_extension_generic(struct kvm *kvm, long arg) #ifdef CONFIG_KVM_PRIVATE_MEM case KVM_CAP_GUEST_MEMFD: return !kvm || kvm_arch_has_private_mem(kvm); +#endif +#ifdef CONFIG_KVM_GMEM_SHARED_MEM + case KVM_CAP_GMEM_SHARED_MEM: + return !kvm || kvm_arch_gmem_supports_shared_mem(kvm); #endif default: break; From patchwork Wed Mar 12 17:58:19 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fuad Tabba X-Patchwork-Id: 872847 Received: from mail-wm1-f73.google.com (mail-wm1-f73.google.com [209.85.128.73]) (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 58E9D2566E1 for ; Wed, 12 Mar 2025 17:58:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741802321; cv=none; b=THjahWwkwLBqqYCDfJ5jGF4cKL7dVWbPKCxX3vPGEZjl3gK1hlZbn0CoR8DjW0mqMpirOIToFlRPTYt6epaebGo/j4Wz/MTjvo/rj/h9F3dA44o5z/4wBY+RGUMc7m4Qu+XdhVaP25KPbnVyPe3f+oIKm/6wyWDPzAV0SV7KOQc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741802321; c=relaxed/simple; bh=tZucr18dFkzlB3deJ6wbqtZ+bsyrb7slNtwTBa7RNbo=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=lTlR4ctmI52Dr3ElZvri29JiQBaoiK5az5QkcRn9o5xu2TfE+FB3zvyMHkvBfSjZ5HQzWEXqRjM17r5bUs1VuCgWVOcIsJOa7KDWm6w6RrOYLoNACW0njghTFdILDisudVUjYWdz89ZiR10EpG4qb39O+DlmtX6raZnTJhSFSJc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--tabba.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=K6xosv+R; arc=none smtp.client-ip=209.85.128.73 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--tabba.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="K6xosv+R" Received: by mail-wm1-f73.google.com with SMTP id 5b1f17b1804b1-43d025a52c2so402055e9.0 for ; Wed, 12 Mar 2025 10:58:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1741802318; x=1742407118; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=Wx8w/RZ95u4Jazhb7Dc1SjbWTPE/GXa4O3urxkMUigQ=; b=K6xosv+Re/1yS+0++zsehDJXwpa8iLxb5wcADpWixPHIAXnM8R+3bgiRDLALiv0E2y Shiazdz1GuLqxvbXa7Zdjkrx6FGFMQeBFXGt2fAQIJlcN9W4iOnRNZlH5+WoH2sNfHYc vV5euj1zKYMe6AuPDzBg+6u5eyF9uqBVqqBRY9QoSvzIwCOZvEbCGfKrnEf+mCraEnFK deoMnnxESQ9KjBm6Scshx69YYkuvyihnSNy2jJttu59PmdrxZ/Qc8oRpAhOAhHAOs1W8 1z55RxSNGrVOLrVRuApT/yr6Pe0Xm+5Kj5fCQA8aM2Z4jgHP3tTvWG0HNIgNzMoKrtLU UUyg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741802318; x=1742407118; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=Wx8w/RZ95u4Jazhb7Dc1SjbWTPE/GXa4O3urxkMUigQ=; b=vs/cOJSMi6tG9orGs/xeqKGwW2Qisj4y+zUyJjrTUzSYWBb4Bm3x7DxsBNwt6ZFw26 d+2iAQoWVN9vXcUthGBZwzRYW5kquYVHY/swc4fSYLdIOJO1w+jv0vNiw2GIcjrTyjY9 WhZ8qyqqJkfm/5XSza5j4SUogXw0E0607y6WOZNZrVjf8Hw6OeEknf4RVRyES9aXLns7 al9eutLpqPArxnJetmohh5/VglTO+8+PhTFawebCZJKeKkOhsTIgmPZJ/6B4KUhoycTm +i1MbSVkmdT7HUH7sdSSRZ4DrzmmN9dJRti2Pf2makvSoSbMU3JeYmBHcJGbGbAXUpna iyAQ== X-Forwarded-Encrypted: i=1; AJvYcCWupOr6qWzWu/5lvXq59yJRpLnem6AWu8lXkC3rGiYiJN6nuBe/J4EaAvhrPG4LIzik8ABVzwpkBPkMvUjf@vger.kernel.org X-Gm-Message-State: AOJu0YxL0TwFPthh0zgttBAw52jmL2s2r/xKEUExbj5TIYjSo1NAzcVp MFVPG80kwX/6leUFQpWj/VAJb6VpVrhbV5sTIaXQUTu495PeQylENigPUm/yIu6FxmqcDJrsIA= = X-Google-Smtp-Source: AGHT+IFJlj4nTok+ueA0jACRwns8uL5LH08IddJBcx9wqowAWc71zjFE+8nTZuhjVvmJcfe8xTEJ+RPsaQ== X-Received: from wmsp15.prod.google.com ([2002:a05:600c:1d8f:b0:43c:ec4d:6037]) (user=tabba job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:4fce:b0:43b:cd0d:9466 with SMTP id 5b1f17b1804b1-43d07fd485emr45933555e9.9.1741802317784; Wed, 12 Mar 2025 10:58:37 -0700 (PDT) Date: Wed, 12 Mar 2025 17:58:19 +0000 In-Reply-To: <20250312175824.1809636-1-tabba@google.com> Precedence: bulk X-Mailing-List: linux-arm-msm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20250312175824.1809636-1-tabba@google.com> X-Mailer: git-send-email 2.49.0.rc0.332.g42c0ae87b1-goog Message-ID: <20250312175824.1809636-7-tabba@google.com> Subject: [PATCH v6 06/10] KVM: x86: Mark KVM_X86_SW_PROTECTED_VM as supporting guest_memfd shared memory From: Fuad Tabba To: kvm@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-mm@kvack.org Cc: pbonzini@redhat.com, chenhuacai@kernel.org, mpe@ellerman.id.au, anup@brainfault.org, paul.walmsley@sifive.com, palmer@dabbelt.com, aou@eecs.berkeley.edu, seanjc@google.com, viro@zeniv.linux.org.uk, brauner@kernel.org, willy@infradead.org, akpm@linux-foundation.org, xiaoyao.li@intel.com, yilun.xu@intel.com, chao.p.peng@linux.intel.com, jarkko@kernel.org, amoorthy@google.com, dmatlack@google.com, isaku.yamahata@intel.com, mic@digikod.net, vbabka@suse.cz, vannapurve@google.com, ackerleytng@google.com, mail@maciej.szmigiero.name, david@redhat.com, michael.roth@amd.com, wei.w.wang@intel.com, liam.merwick@oracle.com, isaku.yamahata@gmail.com, kirill.shutemov@linux.intel.com, suzuki.poulose@arm.com, steven.price@arm.com, quic_eberman@quicinc.com, quic_mnalajal@quicinc.com, quic_tsoni@quicinc.com, quic_svaddagi@quicinc.com, quic_cvanscha@quicinc.com, quic_pderrin@quicinc.com, quic_pheragu@quicinc.com, catalin.marinas@arm.com, james.morse@arm.com, yuzenghui@huawei.com, oliver.upton@linux.dev, maz@kernel.org, will@kernel.org, qperret@google.com, keirf@google.com, roypat@amazon.co.uk, shuah@kernel.org, hch@infradead.org, jgg@nvidia.com, rientjes@google.com, jhubbard@nvidia.com, fvdl@google.com, hughd@google.com, jthoughton@google.com, peterx@redhat.com, tabba@google.com The KVM_X86_SW_PROTECTED_VM type is meant for experimentation and does not have any underlying support for protected guests. This makes it a good candidate for testing mapping shared memory. Therefore, when the kconfig option is enabled, mark KVM_X86_SW_PROTECTED_VM as supporting shared memory. This means that this memory is considered by guest_memfd to be shared with the host, with the possibility of in-place conversion between shared and private. This allows the host to map and fault in guest_memfd memory belonging to this VM type. Signed-off-by: Fuad Tabba --- arch/x86/include/asm/kvm_host.h | 5 +++++ arch/x86/kvm/Kconfig | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 32ae3aa50c7e..b874e54a5ee4 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -2246,8 +2246,13 @@ void kvm_configure_mmu(bool enable_tdp, int tdp_forced_root_level, #ifdef CONFIG_KVM_PRIVATE_MEM #define kvm_arch_has_private_mem(kvm) ((kvm)->arch.has_private_mem) + +#define kvm_arch_gmem_supports_shared_mem(kvm) \ + (IS_ENABLED(CONFIG_KVM_GMEM_SHARED_MEM) && \ + ((kvm)->arch.vm_type == KVM_X86_SW_PROTECTED_VM)) #else #define kvm_arch_has_private_mem(kvm) false +#define kvm_arch_gmem_supports_shared_mem(kvm) false #endif #define kvm_arch_has_readonly_mem(kvm) (!(kvm)->arch.has_protected_state) diff --git a/arch/x86/kvm/Kconfig b/arch/x86/kvm/Kconfig index ea2c4f21c1ca..22d1bcdaad58 100644 --- a/arch/x86/kvm/Kconfig +++ b/arch/x86/kvm/Kconfig @@ -45,7 +45,8 @@ config KVM_X86 select HAVE_KVM_PM_NOTIFIER if PM select KVM_GENERIC_HARDWARE_ENABLING select KVM_GENERIC_PRE_FAULT_MEMORY - select KVM_GENERIC_PRIVATE_MEM if KVM_SW_PROTECTED_VM + select KVM_PRIVATE_MEM if KVM_SW_PROTECTED_VM + select KVM_GMEM_SHARED_MEM if KVM_SW_PROTECTED_VM select KVM_WERROR if WERROR config KVM From patchwork Wed Mar 12 17:58:21 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fuad Tabba X-Patchwork-Id: 872846 Received: from mail-wm1-f74.google.com (mail-wm1-f74.google.com [209.85.128.74]) (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 A3BD2258CCB for ; Wed, 12 Mar 2025 17:58:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741802326; cv=none; b=YB2Y7pP3HIGyjZzl/DtzL0hWKv/YT0+tYgbQrCe+MeJr60zLMxr6gUcwAcY8HyYAzLGSBXU82pd8FJNehUNPfHOlyXkaiV4x9HbDj7K6sCJ8Mu0D/+MvFJIpBAtwBmN9gUAiKz7MmVujNygNtyH6YyT1ApqFLYJ1Q8S+pMXsgVY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741802326; c=relaxed/simple; bh=JrTvyHiXKHvsC898MaHDvFWzZFHSfI05OZDM7sRwtrc=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=irE4bWaPSUbsve5Sh7rN/6EDKgySD+XNUpVAZIq8oYTz8B4DtkcJwfhJIPbCIRTfOisD/7RtoAUh5jhqvY9EmaQQ++BDA43/gxW/eiFElmkizPwmXzSDTZcDqyrB5p/ojihSPRWlfXbQ2xAud+Po1TnQhDyxACMa6jNYsYBJ7lg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--tabba.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=SoUTC50M; arc=none smtp.client-ip=209.85.128.74 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--tabba.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="SoUTC50M" Received: by mail-wm1-f74.google.com with SMTP id 5b1f17b1804b1-43cfd9b833bso5599715e9.1 for ; Wed, 12 Mar 2025 10:58:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1741802322; x=1742407122; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=We8c70tl+Zx5FQcQtlW287aL/adOZePxySoQID49z3A=; b=SoUTC50MIyZdgx/Nu3+DD5sfwK4hcE1FUKf7LOzJYQmxgxD3VrkwTeC17ZAX0nw1OQ 2iLgJMUaOSIC9bGrxDYgW2w9x8/m1OSZEUv4onpdhMMHoSWTbisUKHXPvqfPt7hPBRey q2mZ5ebX3mR7pzv/lOa3VO6V41lU6ydimBH6AuFD6OIbW5oCJXm5z+HuuSic8crUxv0p TSxwlG5SgJpLmuVBDMdADXQZd/nzVaRSkA1Lpy8oUrsSq1FaFvkbzJSWxo8slr+MhmG7 jtxC5CUAZdAiETpaf5C4VfAQqNZSi/HmeHLzf9xgdXwezdZkTsr2odVEs4oein3sCUYH tP+Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741802322; x=1742407122; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=We8c70tl+Zx5FQcQtlW287aL/adOZePxySoQID49z3A=; b=vUf+hX8iNNnJNmb3v/TyHHfRwLSVCGVkO14ffKUk0vAshcGLeB+ykqXoc3C7biygrW eb5XWa2zeemkmX6tSjl+VHrgo7EjKksKQE+9DL42Tck1A0serh0RNbelQFxlt4U3L2Pd MOJQIqQz7w9YaY5sY/erS60FXC7I8ip4sn9PQ0LeFVW9lqELFpcsjyDhf6KnE3wbVSBG 6BIM7R11cC0ewgOyZr0dly+Om6GvQvDUvl9HB/5HManT5PwgYsjojrz+3ZPw9wzwyjFH hZwUTm5Zi7yAnltnsRdpJj2QiPnSoiIBaWW8tnyQBRtoU6yzWlbZri/JkW8Ti+y/GM3g 25SQ== X-Forwarded-Encrypted: i=1; AJvYcCVzdcu9BV1VNVAYikykhJUJYhSVsx+oKsBAPscCDQW0LmPXYe/bj2tQR5CdtjtN5sMbN0li3h0np6PDDjHO@vger.kernel.org X-Gm-Message-State: AOJu0Yyqs/Bs7M0kirYGpd9SdWSHWTfCyJfeaNFoFec2q9Z6mkHnbkzs vWbNyC3hES61C7VkhtJ2y4QPuoTGGt98HGHq85V+hbZ/dW/v+IMya78AqPs/xCX5ettJtcqXZA= = X-Google-Smtp-Source: AGHT+IFgL9irGVEt2YWfb1UQbIwVL/VNkbXIcKNXEidvOBQCQVT8F8I3RbRKchYk4z05AIfWZpjSXgIKCw== X-Received: from wmbeq9.prod.google.com ([2002:a05:600c:8489:b0:43b:c9fc:b269]) (user=tabba job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:1913:b0:439:8e95:796a with SMTP id 5b1f17b1804b1-43d161ea047mr4367375e9.13.1741802321988; Wed, 12 Mar 2025 10:58:41 -0700 (PDT) Date: Wed, 12 Mar 2025 17:58:21 +0000 In-Reply-To: <20250312175824.1809636-1-tabba@google.com> Precedence: bulk X-Mailing-List: linux-arm-msm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20250312175824.1809636-1-tabba@google.com> X-Mailer: git-send-email 2.49.0.rc0.332.g42c0ae87b1-goog Message-ID: <20250312175824.1809636-9-tabba@google.com> Subject: [PATCH v6 08/10] KVM: arm64: Handle guest_memfd()-backed guest page faults From: Fuad Tabba To: kvm@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-mm@kvack.org Cc: pbonzini@redhat.com, chenhuacai@kernel.org, mpe@ellerman.id.au, anup@brainfault.org, paul.walmsley@sifive.com, palmer@dabbelt.com, aou@eecs.berkeley.edu, seanjc@google.com, viro@zeniv.linux.org.uk, brauner@kernel.org, willy@infradead.org, akpm@linux-foundation.org, xiaoyao.li@intel.com, yilun.xu@intel.com, chao.p.peng@linux.intel.com, jarkko@kernel.org, amoorthy@google.com, dmatlack@google.com, isaku.yamahata@intel.com, mic@digikod.net, vbabka@suse.cz, vannapurve@google.com, ackerleytng@google.com, mail@maciej.szmigiero.name, david@redhat.com, michael.roth@amd.com, wei.w.wang@intel.com, liam.merwick@oracle.com, isaku.yamahata@gmail.com, kirill.shutemov@linux.intel.com, suzuki.poulose@arm.com, steven.price@arm.com, quic_eberman@quicinc.com, quic_mnalajal@quicinc.com, quic_tsoni@quicinc.com, quic_svaddagi@quicinc.com, quic_cvanscha@quicinc.com, quic_pderrin@quicinc.com, quic_pheragu@quicinc.com, catalin.marinas@arm.com, james.morse@arm.com, yuzenghui@huawei.com, oliver.upton@linux.dev, maz@kernel.org, will@kernel.org, qperret@google.com, keirf@google.com, roypat@amazon.co.uk, shuah@kernel.org, hch@infradead.org, jgg@nvidia.com, rientjes@google.com, jhubbard@nvidia.com, fvdl@google.com, hughd@google.com, jthoughton@google.com, peterx@redhat.com, tabba@google.com Add arm64 support for handling guest page faults on guest_memfd backed memslots. For now, the fault granule is restricted to PAGE_SIZE. Signed-off-by: Fuad Tabba --- arch/arm64/kvm/mmu.c | 65 +++++++++++++++++++++++++++------------- include/linux/kvm_host.h | 5 ++++ virt/kvm/kvm_main.c | 5 ---- 3 files changed, 50 insertions(+), 25 deletions(-) diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c index 887ffa1f5b14..adb0681fc1c6 100644 --- a/arch/arm64/kvm/mmu.c +++ b/arch/arm64/kvm/mmu.c @@ -1454,6 +1454,30 @@ static bool kvm_vma_mte_allowed(struct vm_area_struct *vma) return vma->vm_flags & VM_MTE_ALLOWED; } +static kvm_pfn_t faultin_pfn(struct kvm *kvm, struct kvm_memory_slot *slot, + gfn_t gfn, bool write_fault, bool *writable, + struct page **page, bool is_private) +{ + kvm_pfn_t pfn; + int ret; + + if (!is_private) + return __kvm_faultin_pfn(slot, gfn, write_fault ? FOLL_WRITE : 0, writable, page); + + *writable = false; + + ret = kvm_gmem_get_pfn(kvm, slot, gfn, &pfn, page, NULL); + if (!ret) { + *writable = !memslot_is_readonly(slot); + return pfn; + } + + if (ret == -EHWPOISON) + return KVM_PFN_ERR_HWPOISON; + + return KVM_PFN_ERR_NOSLOT_MASK; +} + static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, struct kvm_s2_trans *nested, struct kvm_memory_slot *memslot, unsigned long hva, @@ -1461,19 +1485,20 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, { int ret = 0; bool write_fault, writable; - bool exec_fault, mte_allowed; + bool exec_fault, mte_allowed = false; bool device = false, vfio_allow_any_uc = false; unsigned long mmu_seq; phys_addr_t ipa = fault_ipa; struct kvm *kvm = vcpu->kvm; - struct vm_area_struct *vma; + struct vm_area_struct *vma = NULL; short vma_shift; void *memcache; - gfn_t gfn; + gfn_t gfn = ipa >> PAGE_SHIFT; kvm_pfn_t pfn; bool logging_active = memslot_is_logging(memslot); - bool force_pte = logging_active || is_protected_kvm_enabled(); - long vma_pagesize, fault_granule; + bool is_gmem = kvm_mem_is_private(kvm, gfn); + bool force_pte = logging_active || is_gmem || is_protected_kvm_enabled(); + long vma_pagesize, fault_granule = PAGE_SIZE; enum kvm_pgtable_prot prot = KVM_PGTABLE_PROT_R; struct kvm_pgtable *pgt; struct page *page; @@ -1510,16 +1535,22 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, return ret; } + mmap_read_lock(current->mm); + /* * Let's check if we will get back a huge page backed by hugetlbfs, or * get block mapping for device MMIO region. */ - mmap_read_lock(current->mm); - vma = vma_lookup(current->mm, hva); - if (unlikely(!vma)) { - kvm_err("Failed to find VMA for hva 0x%lx\n", hva); - mmap_read_unlock(current->mm); - return -EFAULT; + if (!is_gmem) { + vma = vma_lookup(current->mm, hva); + if (unlikely(!vma)) { + kvm_err("Failed to find VMA for hva 0x%lx\n", hva); + mmap_read_unlock(current->mm); + return -EFAULT; + } + + vfio_allow_any_uc = vma->vm_flags & VM_ALLOW_ANY_UNCACHED; + mte_allowed = kvm_vma_mte_allowed(vma); } if (force_pte) @@ -1590,18 +1621,13 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, ipa &= ~(vma_pagesize - 1); } - gfn = ipa >> PAGE_SHIFT; - mte_allowed = kvm_vma_mte_allowed(vma); - - vfio_allow_any_uc = vma->vm_flags & VM_ALLOW_ANY_UNCACHED; - /* Don't use the VMA after the unlock -- it may have vanished */ vma = NULL; /* * Read mmu_invalidate_seq so that KVM can detect if the results of - * vma_lookup() or __kvm_faultin_pfn() become stale prior to - * acquiring kvm->mmu_lock. + * vma_lookup() or faultin_pfn() become stale prior to acquiring + * kvm->mmu_lock. * * Rely on mmap_read_unlock() for an implicit smp_rmb(), which pairs * with the smp_wmb() in kvm_mmu_invalidate_end(). @@ -1609,8 +1635,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, mmu_seq = vcpu->kvm->mmu_invalidate_seq; mmap_read_unlock(current->mm); - pfn = __kvm_faultin_pfn(memslot, gfn, write_fault ? FOLL_WRITE : 0, - &writable, &page); + pfn = faultin_pfn(kvm, memslot, gfn, write_fault, &writable, &page, is_gmem); if (pfn == KVM_PFN_ERR_HWPOISON) { kvm_send_hwpoison_signal(hva, vma_shift); return 0; diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 3d5595a71a2a..ec3bedc18eab 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -1882,6 +1882,11 @@ static inline int memslot_id(struct kvm *kvm, gfn_t gfn) return gfn_to_memslot(kvm, gfn)->id; } +static inline bool memslot_is_readonly(const struct kvm_memory_slot *slot) +{ + return slot->flags & KVM_MEM_READONLY; +} + static inline gfn_t hva_to_gfn_memslot(unsigned long hva, struct kvm_memory_slot *slot) { diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 38f0f402ea46..3e40acb9f5c0 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -2624,11 +2624,6 @@ unsigned long kvm_host_page_size(struct kvm_vcpu *vcpu, gfn_t gfn) return size; } -static bool memslot_is_readonly(const struct kvm_memory_slot *slot) -{ - return slot->flags & KVM_MEM_READONLY; -} - static unsigned long __gfn_to_hva_many(const struct kvm_memory_slot *slot, gfn_t gfn, gfn_t *nr_pages, bool write) { From patchwork Wed Mar 12 17:58:23 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fuad Tabba X-Patchwork-Id: 872845 Received: from mail-wm1-f73.google.com (mail-wm1-f73.google.com [209.85.128.73]) (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 74E491D5176 for ; Wed, 12 Mar 2025 17:58:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741802329; cv=none; b=U1kP7J+Hkj6yxkDE7/e/CiEmxxjyCy+Mg/JuTxLhX2i+WgiY/vMp63P0cTGPn9KhPutdR2xnRwAQ2+lWHybA09lDMkMgPpmFzPTtbJHs+zWSfM9+Vz5zTIOK8wrOSec0dww1RgZd/iQxBu83reZGENLT2XimyYl3uzfc6eZli2Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741802329; c=relaxed/simple; bh=dBp330nwbC7q4iPH2IoIUZ3Q0GJxinDrCajbj2wj9s0=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=OvLN/XNrtzPWzVlJla6JLaI90eXgq/41/ERWjsE5SaILR6dGNZaROMfE5lBv5PSibWcuxhie1lmbuCxaW2IAp30YFkpYdp/ZZWqYSUXs/4RbEV2e77BYyffrsCVRw8faiwnuG0vFSng/IQzFAbG59VOi2lSz7XFfGBfYhsboIZE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--tabba.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=VMenEBkN; arc=none smtp.client-ip=209.85.128.73 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--tabba.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="VMenEBkN" Received: by mail-wm1-f73.google.com with SMTP id 5b1f17b1804b1-43d025a52c2so402685e9.0 for ; Wed, 12 Mar 2025 10:58:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1741802326; x=1742407126; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=IlIj3TjUhtkedIPYTVHeRQbthVzaFoCCtbaBiaH1aMs=; b=VMenEBkNgjG7/kRyc1xc2e8vAftptPXLVORUiTRFurTxFfUYQZmorBRSvN25uudUQy g585dTGZOz/Lo2aDflADS5rS8YAJwyAMzptUjN7nw9foymv438eP1y+dgkEGt7tvGEmm fsQgP/2l/0AFPQqu7PkvI5fbOy/X9r0g1X25i4akgDJjq9Q1ij8vKtvjxh06razNV8TI Pi49jUkd7f4K8XDYsjrZ8dOX49YoQMflOZcFPfeJndWdDsO9UzDySd7SGFx7ZNeq47JZ B4aVHH5vMOcJypUAEa6vD6UOiasGrn64Gh4Q0ZS797E84ulmvBYiSjCeX/pkubxJRUvM 7chA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741802326; x=1742407126; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=IlIj3TjUhtkedIPYTVHeRQbthVzaFoCCtbaBiaH1aMs=; b=GQMNbJhEqgc32i3b0NRWLaE+ClRJ7GLN9qZOc2oAY4WaCSyGo5JtHNKVR3dqYVXPrP hqd4tjcG2/rXlo6HTPPzITMrdszML16sCjRHfr1bA2821295CgdtGN3hQ0oqGdxgIEN9 KDqj9gm/B1jE9gCI8ZP0IOI90yHor5J2cVczUgvqypWc+m/TPvT1ZvcAZJCE9UDEnpY3 0Nexo2a49Z2+K8Vxi7uKaPTdoICBWWVfmJqYw5EAfMusTimIbdVEWd28rTuXo1f2zjMg k0luGW8p9DrY6+JDzWB1wl3TaonkLwHEXDZOSJ0d/4O1XrzBAf4HAixbe3szg2CPDIM7 KaLg== X-Forwarded-Encrypted: i=1; AJvYcCXfGglD4ZflkLcPFxIQ/HbDRw/Y2HaLt1Yhmtq0nz6OTLV5Bf4evLvGc9cmXLFI6IbzzsW3c3q+0PikEtzp@vger.kernel.org X-Gm-Message-State: AOJu0YwnkYqbfH/hmq0whyC+hbK3eKeWQUR/LLoBE6fMYteFoIeu9HHZ kKKu/gCPbMCRR038IqBGVXoMyRhJQ7j6xrL9tgq+/RGteROPUG40lt5GmBwv1LFym46u8ZEggg= = X-Google-Smtp-Source: AGHT+IEjvTr2HYGSAjPDkNMw4G4npR8OoTHD1VZTAuD0hSm6xCoVT94NRgIvuCOHObtSUaBMEiPsUwonRg== X-Received: from wmqa16.prod.google.com ([2002:a05:600c:3490:b0:43c:fa2a:77d]) (user=tabba job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:1d09:b0:43c:efed:732b with SMTP id 5b1f17b1804b1-43cefed78bcmr140968325e9.5.1741802326090; Wed, 12 Mar 2025 10:58:46 -0700 (PDT) Date: Wed, 12 Mar 2025 17:58:23 +0000 In-Reply-To: <20250312175824.1809636-1-tabba@google.com> Precedence: bulk X-Mailing-List: linux-arm-msm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20250312175824.1809636-1-tabba@google.com> X-Mailer: git-send-email 2.49.0.rc0.332.g42c0ae87b1-goog Message-ID: <20250312175824.1809636-11-tabba@google.com> Subject: [PATCH v6 10/10] KVM: guest_memfd: selftests: guest_memfd mmap() test when mapping is allowed From: Fuad Tabba To: kvm@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-mm@kvack.org Cc: pbonzini@redhat.com, chenhuacai@kernel.org, mpe@ellerman.id.au, anup@brainfault.org, paul.walmsley@sifive.com, palmer@dabbelt.com, aou@eecs.berkeley.edu, seanjc@google.com, viro@zeniv.linux.org.uk, brauner@kernel.org, willy@infradead.org, akpm@linux-foundation.org, xiaoyao.li@intel.com, yilun.xu@intel.com, chao.p.peng@linux.intel.com, jarkko@kernel.org, amoorthy@google.com, dmatlack@google.com, isaku.yamahata@intel.com, mic@digikod.net, vbabka@suse.cz, vannapurve@google.com, ackerleytng@google.com, mail@maciej.szmigiero.name, david@redhat.com, michael.roth@amd.com, wei.w.wang@intel.com, liam.merwick@oracle.com, isaku.yamahata@gmail.com, kirill.shutemov@linux.intel.com, suzuki.poulose@arm.com, steven.price@arm.com, quic_eberman@quicinc.com, quic_mnalajal@quicinc.com, quic_tsoni@quicinc.com, quic_svaddagi@quicinc.com, quic_cvanscha@quicinc.com, quic_pderrin@quicinc.com, quic_pheragu@quicinc.com, catalin.marinas@arm.com, james.morse@arm.com, yuzenghui@huawei.com, oliver.upton@linux.dev, maz@kernel.org, will@kernel.org, qperret@google.com, keirf@google.com, roypat@amazon.co.uk, shuah@kernel.org, hch@infradead.org, jgg@nvidia.com, rientjes@google.com, jhubbard@nvidia.com, fvdl@google.com, hughd@google.com, jthoughton@google.com, peterx@redhat.com, tabba@google.com Expand the guest_memfd selftests to include testing mapping guest memory for VM types that support it. Also, build the guest_memfd selftest for aarch64. Signed-off-by: Fuad Tabba --- tools/testing/selftests/kvm/Makefile.kvm | 1 + .../testing/selftests/kvm/guest_memfd_test.c | 75 +++++++++++++++++-- 2 files changed, 70 insertions(+), 6 deletions(-) diff --git a/tools/testing/selftests/kvm/Makefile.kvm b/tools/testing/selftests/kvm/Makefile.kvm index 4277b983cace..c9a3f30e28dd 100644 --- a/tools/testing/selftests/kvm/Makefile.kvm +++ b/tools/testing/selftests/kvm/Makefile.kvm @@ -160,6 +160,7 @@ TEST_GEN_PROGS_arm64 += coalesced_io_test TEST_GEN_PROGS_arm64 += demand_paging_test TEST_GEN_PROGS_arm64 += dirty_log_test TEST_GEN_PROGS_arm64 += dirty_log_perf_test +TEST_GEN_PROGS_arm64 += guest_memfd_test TEST_GEN_PROGS_arm64 += guest_print_test TEST_GEN_PROGS_arm64 += get-reg-list TEST_GEN_PROGS_arm64 += kvm_create_max_vcpus diff --git a/tools/testing/selftests/kvm/guest_memfd_test.c b/tools/testing/selftests/kvm/guest_memfd_test.c index ce687f8d248f..38c501e49e0e 100644 --- a/tools/testing/selftests/kvm/guest_memfd_test.c +++ b/tools/testing/selftests/kvm/guest_memfd_test.c @@ -34,12 +34,48 @@ static void test_file_read_write(int fd) "pwrite on a guest_mem fd should fail"); } -static void test_mmap(int fd, size_t page_size) +static void test_mmap_allowed(int fd, size_t total_size) { + size_t page_size = getpagesize(); + const char val = 0xaa; + char *mem; + int ret; + int i; + + mem = mmap(NULL, total_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + TEST_ASSERT(mem != MAP_FAILED, "mmaping() guest memory should pass."); + + memset(mem, val, total_size); + for (i = 0; i < total_size; i++) + TEST_ASSERT_EQ(mem[i], val); + + ret = fallocate(fd, FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE, 0, + page_size); + TEST_ASSERT(!ret, "fallocate the first page should succeed"); + + for (i = 0; i < page_size; i++) + TEST_ASSERT_EQ(mem[i], 0x00); + for (; i < total_size; i++) + TEST_ASSERT_EQ(mem[i], val); + + memset(mem, val, total_size); + for (i = 0; i < total_size; i++) + TEST_ASSERT_EQ(mem[i], val); + + ret = munmap(mem, total_size); + TEST_ASSERT(!ret, "munmap should succeed"); +} + +static void test_mmap_denied(int fd, size_t total_size) +{ + size_t page_size = getpagesize(); char *mem; mem = mmap(NULL, page_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); TEST_ASSERT_EQ(mem, MAP_FAILED); + + mem = mmap(NULL, total_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + TEST_ASSERT_EQ(mem, MAP_FAILED); } static void test_file_size(int fd, size_t page_size, size_t total_size) @@ -170,19 +206,27 @@ static void test_create_guest_memfd_multiple(struct kvm_vm *vm) close(fd1); } -int main(int argc, char *argv[]) +unsigned long get_shared_type(void) { - size_t page_size; +#ifdef __x86_64__ + return KVM_X86_SW_PROTECTED_VM; +#endif + return 0; +} + +void test_vm_type(unsigned long type, bool is_shared) +{ + struct kvm_vm *vm; size_t total_size; + size_t page_size; int fd; - struct kvm_vm *vm; TEST_REQUIRE(kvm_has_cap(KVM_CAP_GUEST_MEMFD)); page_size = getpagesize(); total_size = page_size * 4; - vm = vm_create_barebones(); + vm = vm_create_barebones_type(type); test_create_guest_memfd_invalid(vm); test_create_guest_memfd_multiple(vm); @@ -190,10 +234,29 @@ int main(int argc, char *argv[]) fd = vm_create_guest_memfd(vm, total_size, 0); test_file_read_write(fd); - test_mmap(fd, page_size); + + if (is_shared) + test_mmap_allowed(fd, total_size); + else + test_mmap_denied(fd, total_size); + test_file_size(fd, page_size, total_size); test_fallocate(fd, page_size, total_size); test_invalid_punch_hole(fd, page_size, total_size); close(fd); + kvm_vm_release(vm); +} + +int main(int argc, char *argv[]) +{ +#ifndef __aarch64__ + /* For now, arm64 only supports shared guest memory. */ + test_vm_type(VM_TYPE_DEFAULT, false); +#endif + + if (kvm_has_cap(KVM_CAP_GMEM_SHARED_MEM)) + test_vm_type(get_shared_type(), true); + + return 0; }