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 799E0C433FE for ; Tue, 21 Dec 2021 15:12:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238997AbhLUPMN (ORCPT ); Tue, 21 Dec 2021 10:12:13 -0500 Received: from mga18.intel.com ([134.134.136.126]:45583 "EHLO mga18.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238974AbhLUPML (ORCPT ); Tue, 21 Dec 2021 10:12:11 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1640099531; x=1671635531; h=from:to:cc:subject:date:message-id; bh=bhiBZIBPUvq8tNjFZYJrVCRkahxll9ZU4gU5+TYg0gQ=; b=ZC5NfSsf31t7XUFVAFX+QIMUdFZH2+blNulPZ7um0g5ji4P4jq0UhjxF bn5e9YfbY+fssBdtx8RM/3orIDI0Jfu5Qpiwh45hbZ7uckpgzOL0/AsYZ CN+rZZpQc0+/oI+ZG4Or/nBP8N1o7ceNsY1atlpkUhHwZgdaaB8TlAoBy NAzaGAUJcJscn7tlAoZ6cFZ3/cRQOsHxIKsYu5Eu8tdG+ZfD9ZGNWBg8F v+nw/Qz0oDTyoyNe3Gen+BHcYsBxn9/+SPe4GIchK3Act9pKMgiTT9t4f 4WjmpzWu44uAnD6RzRRbZrleuK9phCMdBRl9gxv+Fd+wPPQlKIm9mLJ1d Q==; X-IronPort-AV: E=McAfee;i="6200,9189,10204"; a="227259260" X-IronPort-AV: E=Sophos;i="5.88,223,1635231600"; d="scan'208";a="227259260" Received: from orsmga005.jf.intel.com ([10.7.209.41]) by orsmga106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 21 Dec 2021 07:12:11 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.88,223,1635231600"; d="scan'208";a="684688254" Received: from chaop.bj.intel.com ([10.240.192.101]) by orsmga005.jf.intel.com with ESMTP; 21 Dec 2021 07:12:03 -0800 From: Chao Peng To: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, linux-fsdevel@vger.kernel.org, qemu-devel@nongnu.org Cc: Paolo Bonzini , Jonathan Corbet , Sean Christopherson , Vitaly Kuznetsov , Wanpeng Li , Jim Mattson , Joerg Roedel , Thomas Gleixner , Ingo Molnar , Borislav Petkov , x86@kernel.org, "H . Peter Anvin" , Hugh Dickins , Jeff Layton , "J . Bruce Fields" , Andrew Morton , Yu Zhang , Chao Peng , "Kirill A . Shutemov" , luto@kernel.org, john.ji@intel.com, susie.li@intel.com, jun.nakajima@intel.com, dave.hansen@intel.com, ak@linux.intel.com, david@redhat.com Subject: [PATCH v3 00/15] KVM: mm: fd-based approach for supporting KVM guest private memory Date: Tue, 21 Dec 2021 23:11:10 +0800 Message-Id: <20211221151125.19446-1-chao.p.peng@linux.intel.com> X-Mailer: git-send-email 2.17.1 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This is the third version of this series which try to implement the fd-based KVM guest private memory. In general this patch series introduce fd-based memslot which provide guest memory through a memfd file descriptor fd[offset,size] instead of hva/size. The fd then can be created from a supported memory filesystem like tmpfs/hugetlbfs etc which we refer as memory backend. KVM and the memory backend exchange some callbacks when such memslot gets created. At runtime KVM will call into callbacks provided by backend to get the pfn with the fd+offset. Memory backend will also call into KVM callbacks when userspace fallocate/punch hole on the fd to notify KVM to map/unmap secondary MMU page tables. Comparing to existing hva-based memslot, this new type of memslot allow guest memory unmapped from host userspace like QEMU and even the kernel itself, therefore reduce attack surface and prevent userspace bugs. Based on this fd-based memslot, we can build guest private memory that is going to be used in confidential computing environments such as Intel TDX and AMD SEV. When supported, the memory backend can provide more enforcement on the fd and KVM can use a single memslot to hold both the private and shared part of the guest memory. Memfd/shmem extension --------------------- Introduces new MFD_INACCESSIBLE flag for memfd_create(), the file created with this flag cannot read(), write() or mmap() etc. In addition, two sets of callbacks are introduced as new MEMFD_OPS: - memfd_falloc_notifier: memfd -> KVM notifier when memory gets allocated/invalidated through fallocate(). - memfd_pfn_ops: kvm -> memfd to get a pfn with the fd+offset. Memslot extension ----------------- Add the private fd and the offset into the fd to existing 'shared' memslot so that both private/shared guest memory can live in one single memslot. A page in the memslot is either private or shared. A page is private only when it's already allocated in the backend fd, all the other cases it's treated as shared, this includes those already mapped as shared as well as those having not been mapped. This means the memory backend is the place which tells the truth of which page is private. Private memory map/unmap and conversion --------------------------------------- Userspace's map/unmap operations are done by fallocate() ioctl on the backend fd. - map: default fallocate() with mode=0. - unmap: fallocate() with FALLOC_FL_PUNCH_HOLE. The map/unmap will trigger above memfd_falloc_notifier to let KVM map/unmap second MMU page tables. Test ---- This code has been tested with latest TDX code patches hosted at (https://github.com/intel/tdx/tree/kvm-upstream) with minimal TDX adaption and QEMU support. Example QEMU command line: -object tdx-guest,id=tdx \ -object memory-backend-memfd-private,id=ram1,size=2G \ -machine q35,kvm-type=tdx,pic=no,kernel_irqchip=split,memory-encryption=tdx,memory-backend=ram1 Changelog ---------- v3: - Added locking protection when calling invalidate_page_range/fallocate callbacks. - Changed memslot structure to keep use useraddr for shared memory. - Re-organized F_SEAL_INACCESSIBLE and MEMFD_OPS. - Added MFD_INACCESSIBLE flag to force F_SEAL_INACCESSIBLE. - Commit message improvement. - Many small fixes for comments from the last version. Links of previous discussions ----------------------------- [1] https://lkml.kernel.org/kvm/51a6f74f-6c05-74b9-3fd7-b7cd900fb8cc@redhat.com/ [2] https://lkml.kernel.org/linux-fsdevel/20211111141352.26311-1-chao.p.peng@linux.intel.com/ Chao Peng (13): mm/memfd: Introduce MFD_INACCESSIBLE flag KVM: Extend the memslot to support fd-based private memory KVM: Implement fd-based memory using MEMFD_OPS interfaces KVM: Refactor hva based memory invalidation code KVM: Special handling for fd-based memory invalidation KVM: Split out common memory invalidation code KVM: Implement fd-based memory invalidation KVM: Add kvm_map_gfn_range KVM: Implement fd-based memory fallocation KVM: Add KVM_EXIT_MEMORY_ERROR exit KVM: Handle page fault for private memory KVM: Use kvm_userspace_memory_region_ext KVM: Register/unregister private memory slot to memfd Kirill A. Shutemov (2): mm/shmem: Introduce F_SEAL_INACCESSIBLE mm/memfd: Introduce MEMFD_OPS arch/arm64/kvm/mmu.c | 14 +- arch/mips/kvm/mips.c | 14 +- arch/powerpc/include/asm/kvm_ppc.h | 28 ++-- arch/powerpc/kvm/book3s.c | 14 +- arch/powerpc/kvm/book3s_hv.c | 14 +- arch/powerpc/kvm/book3s_pr.c | 14 +- arch/powerpc/kvm/booke.c | 14 +- arch/powerpc/kvm/powerpc.c | 14 +- arch/riscv/kvm/mmu.c | 14 +- arch/s390/kvm/kvm-s390.c | 14 +- arch/x86/kvm/Kconfig | 1 + arch/x86/kvm/Makefile | 3 +- arch/x86/kvm/mmu/mmu.c | 112 +++++++++++++- arch/x86/kvm/mmu/paging_tmpl.h | 11 +- arch/x86/kvm/x86.c | 16 +- include/linux/kvm_host.h | 57 +++++-- include/linux/memfd.h | 22 +++ include/linux/shmem_fs.h | 16 ++ include/uapi/linux/fcntl.h | 1 + include/uapi/linux/kvm.h | 27 ++++ include/uapi/linux/memfd.h | 1 + mm/Kconfig | 4 + mm/memfd.c | 33 +++- mm/shmem.c | 195 ++++++++++++++++++++++- virt/kvm/kvm_main.c | 239 +++++++++++++++++++++-------- virt/kvm/memfd.c | 100 ++++++++++++ 26 files changed, 822 insertions(+), 170 deletions(-) create mode 100644 virt/kvm/memfd.c -- 2.17.1 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 lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 980D1C433F5 for ; Tue, 21 Dec 2021 15:20:55 +0000 (UTC) Received: from localhost ([::1]:57274 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mzgwg-0002TJ-Ob for qemu-devel@archiver.kernel.org; Tue, 21 Dec 2021 10:20:54 -0500 Received: from eggs.gnu.org ([209.51.188.92]:45762) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mzgoL-0006Mw-M6 for qemu-devel@nongnu.org; Tue, 21 Dec 2021 10:12:17 -0500 Received: from mga01.intel.com ([192.55.52.88]:50879) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mzgoI-00084y-W3 for qemu-devel@nongnu.org; Tue, 21 Dec 2021 10:12:17 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1640099534; x=1671635534; h=from:to:cc:subject:date:message-id; bh=bhiBZIBPUvq8tNjFZYJrVCRkahxll9ZU4gU5+TYg0gQ=; b=ZqRl0YJZb+eGd3d+Tb+qPul/aoYujWzZz4fBAu0DmVQGnzCD/xecn1gR NTP8OGPKtUlp9QcwRjWx3t1umzZSSUgvbgSpb6Q6R/60pyxoEsrL97Yh/ Zjs7WcFep5pFVRbOlnaj97xMdhLjbN16vUgJF3R/xG2cLKHHMR2Y5tIdb XT4+51U5NEisPQHpMhoErbJAb/ZdB1qIKmhJCYEqPcVTO94Rnag3tvNrJ yu7bCEKDjXEeFtxj8Z0aQoon9D/ZzzvtELNcpxtSCDrLz8x9pGyRlCK30 0Pnzt94IUAqf/0Nqk3GrHb1Y19nCFwqp/VEmu0rLE26SVI9wairciRtf/ A==; X-IronPort-AV: E=McAfee;i="6200,9189,10204"; a="264601270" X-IronPort-AV: E=Sophos;i="5.88,223,1635231600"; d="scan'208";a="264601270" Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 21 Dec 2021 07:12:11 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.88,223,1635231600"; d="scan'208";a="684688254" Received: from chaop.bj.intel.com ([10.240.192.101]) by orsmga005.jf.intel.com with ESMTP; 21 Dec 2021 07:12:03 -0800 From: Chao Peng To: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, linux-fsdevel@vger.kernel.org, qemu-devel@nongnu.org Subject: [PATCH v3 00/15] KVM: mm: fd-based approach for supporting KVM guest private memory Date: Tue, 21 Dec 2021 23:11:10 +0800 Message-Id: <20211221151125.19446-1-chao.p.peng@linux.intel.com> X-Mailer: git-send-email 2.17.1 Received-SPF: none client-ip=192.55.52.88; envelope-from=chao.p.peng@linux.intel.com; helo=mga01.intel.com X-Spam_score_int: -71 X-Spam_score: -7.2 X-Spam_bar: ------- X-Spam_report: (-7.2 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.203, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_HI=-5, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Wanpeng Li , jun.nakajima@intel.com, david@redhat.com, "J . Bruce Fields" , dave.hansen@intel.com, "H . Peter Anvin" , Chao Peng , ak@linux.intel.com, Jonathan Corbet , Joerg Roedel , x86@kernel.org, Hugh Dickins , Ingo Molnar , Borislav Petkov , luto@kernel.org, Thomas Gleixner , Vitaly Kuznetsov , Jim Mattson , Sean Christopherson , susie.li@intel.com, Jeff Layton , john.ji@intel.com, Yu Zhang , Paolo Bonzini , Andrew Morton , "Kirill A . Shutemov" Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" This is the third version of this series which try to implement the fd-based KVM guest private memory. In general this patch series introduce fd-based memslot which provide guest memory through a memfd file descriptor fd[offset,size] instead of hva/size. The fd then can be created from a supported memory filesystem like tmpfs/hugetlbfs etc which we refer as memory backend. KVM and the memory backend exchange some callbacks when such memslot gets created. At runtime KVM will call into callbacks provided by backend to get the pfn with the fd+offset. Memory backend will also call into KVM callbacks when userspace fallocate/punch hole on the fd to notify KVM to map/unmap secondary MMU page tables. Comparing to existing hva-based memslot, this new type of memslot allow guest memory unmapped from host userspace like QEMU and even the kernel itself, therefore reduce attack surface and prevent userspace bugs. Based on this fd-based memslot, we can build guest private memory that is going to be used in confidential computing environments such as Intel TDX and AMD SEV. When supported, the memory backend can provide more enforcement on the fd and KVM can use a single memslot to hold both the private and shared part of the guest memory. Memfd/shmem extension --------------------- Introduces new MFD_INACCESSIBLE flag for memfd_create(), the file created with this flag cannot read(), write() or mmap() etc. In addition, two sets of callbacks are introduced as new MEMFD_OPS: - memfd_falloc_notifier: memfd -> KVM notifier when memory gets allocated/invalidated through fallocate(). - memfd_pfn_ops: kvm -> memfd to get a pfn with the fd+offset. Memslot extension ----------------- Add the private fd and the offset into the fd to existing 'shared' memslot so that both private/shared guest memory can live in one single memslot. A page in the memslot is either private or shared. A page is private only when it's already allocated in the backend fd, all the other cases it's treated as shared, this includes those already mapped as shared as well as those having not been mapped. This means the memory backend is the place which tells the truth of which page is private. Private memory map/unmap and conversion --------------------------------------- Userspace's map/unmap operations are done by fallocate() ioctl on the backend fd. - map: default fallocate() with mode=0. - unmap: fallocate() with FALLOC_FL_PUNCH_HOLE. The map/unmap will trigger above memfd_falloc_notifier to let KVM map/unmap second MMU page tables. Test ---- This code has been tested with latest TDX code patches hosted at (https://github.com/intel/tdx/tree/kvm-upstream) with minimal TDX adaption and QEMU support. Example QEMU command line: -object tdx-guest,id=tdx \ -object memory-backend-memfd-private,id=ram1,size=2G \ -machine q35,kvm-type=tdx,pic=no,kernel_irqchip=split,memory-encryption=tdx,memory-backend=ram1 Changelog ---------- v3: - Added locking protection when calling invalidate_page_range/fallocate callbacks. - Changed memslot structure to keep use useraddr for shared memory. - Re-organized F_SEAL_INACCESSIBLE and MEMFD_OPS. - Added MFD_INACCESSIBLE flag to force F_SEAL_INACCESSIBLE. - Commit message improvement. - Many small fixes for comments from the last version. Links of previous discussions ----------------------------- [1] https://lkml.kernel.org/kvm/51a6f74f-6c05-74b9-3fd7-b7cd900fb8cc@redhat.com/ [2] https://lkml.kernel.org/linux-fsdevel/20211111141352.26311-1-chao.p.peng@linux.intel.com/ Chao Peng (13): mm/memfd: Introduce MFD_INACCESSIBLE flag KVM: Extend the memslot to support fd-based private memory KVM: Implement fd-based memory using MEMFD_OPS interfaces KVM: Refactor hva based memory invalidation code KVM: Special handling for fd-based memory invalidation KVM: Split out common memory invalidation code KVM: Implement fd-based memory invalidation KVM: Add kvm_map_gfn_range KVM: Implement fd-based memory fallocation KVM: Add KVM_EXIT_MEMORY_ERROR exit KVM: Handle page fault for private memory KVM: Use kvm_userspace_memory_region_ext KVM: Register/unregister private memory slot to memfd Kirill A. Shutemov (2): mm/shmem: Introduce F_SEAL_INACCESSIBLE mm/memfd: Introduce MEMFD_OPS arch/arm64/kvm/mmu.c | 14 +- arch/mips/kvm/mips.c | 14 +- arch/powerpc/include/asm/kvm_ppc.h | 28 ++-- arch/powerpc/kvm/book3s.c | 14 +- arch/powerpc/kvm/book3s_hv.c | 14 +- arch/powerpc/kvm/book3s_pr.c | 14 +- arch/powerpc/kvm/booke.c | 14 +- arch/powerpc/kvm/powerpc.c | 14 +- arch/riscv/kvm/mmu.c | 14 +- arch/s390/kvm/kvm-s390.c | 14 +- arch/x86/kvm/Kconfig | 1 + arch/x86/kvm/Makefile | 3 +- arch/x86/kvm/mmu/mmu.c | 112 +++++++++++++- arch/x86/kvm/mmu/paging_tmpl.h | 11 +- arch/x86/kvm/x86.c | 16 +- include/linux/kvm_host.h | 57 +++++-- include/linux/memfd.h | 22 +++ include/linux/shmem_fs.h | 16 ++ include/uapi/linux/fcntl.h | 1 + include/uapi/linux/kvm.h | 27 ++++ include/uapi/linux/memfd.h | 1 + mm/Kconfig | 4 + mm/memfd.c | 33 +++- mm/shmem.c | 195 ++++++++++++++++++++++- virt/kvm/kvm_main.c | 239 +++++++++++++++++++++-------- virt/kvm/memfd.c | 100 ++++++++++++ 26 files changed, 822 insertions(+), 170 deletions(-) create mode 100644 virt/kvm/memfd.c -- 2.17.1