public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
From: Rick Edgecombe <rick.p.edgecombe@intel.com>
To: pbonzini@redhat.com, seanjc@google.com, kvm@vger.kernel.org
Cc: linux-kernel@vger.kernel.org, isaku.yamahata@gmail.com,
	erdemaktas@google.com, sagis@google.com, yan.y.zhao@intel.com,
	dmatlack@google.com, rick.p.edgecombe@intel.com
Subject: [PATCH 05/16] KVM: Add member to struct kvm_gfn_range for target alias
Date: Tue, 14 May 2024 17:59:41 -0700	[thread overview]
Message-ID: <20240515005952.3410568-6-rick.p.edgecombe@intel.com> (raw)
In-Reply-To: <20240515005952.3410568-1-rick.p.edgecombe@intel.com>

From: Isaku Yamahata <isaku.yamahata@intel.com>

Add new members to strut kvm_gfn_range to indicate which mapping
(private-vs-shared) to operate on: enum kvm_process process.
Update the core zapping operations to set them appropriately.

TDX utilizes two GPA aliases for the same memslots, one for memory that is
for private memory and one that is for shared. For private memory, KVM
cannot always perform the same operations it does on memory for default
VMs, such as zapping pages and having them be faulted back in, as this
requires guest coordination. However, some operations such as guest driven
conversion of memory between private and shared should zap private memory.

Internally to the MMU, private and shared mappings are tracked on separate
roots. Mapping and zapping operations will operate on the respective GFN
alias for each root (private or shared). So zapping operations will by
default zap both aliases. Add fields in struct kvm_gfn_range to allow
callers to specify which aliases so they can only target the aliases
appropriate for their specific operation.

There was feedback that target aliases should be specified such that the
default value (0) is to operate on both aliases. Several options were
considered. Several variations of having separate bools defined such
that the default behavior was to process both aliases. They either allowed
nonsensical configurations, or were confusing for the caller. A simple
enum was also explored and was close, but was hard to process in the
caller. Instead, use an enum with the default value (0) reserved as a
disallowed value. Catch ranges that didn't have the target aliases
specified by looking for that specific value.

Set target alias with enum appropriately for these MMU operations:
 - For KVM's mmu notifier callbacks, zap shared pages only because private
   pages won't have a userspace mapping
 - For setting memory attributes, kvm_arch_pre_set_memory_attributes()
   chooses the aliases based on the attribute.
 - For guest_memfd invalidations, zap private only.

Link: https://lore.kernel.org/kvm/ZivIF9vjKcuGie3s@google.com/
Signed-off-by: Isaku Yamahata <isaku.yamahata@intel.com>
Co-developed-by: Rick Edgecombe <rick.p.edgecombe@intel.com>
Signed-off-by: Rick Edgecombe <rick.p.edgecombe@intel.com>
---
TDX MMU Part 1:
 - Replaced KVM_PROCESS_BASED_ON_ARG with BUGGY_KVM_INVALIDATION to follow
   the original suggestion and not populte kvm_handle_gfn_range(). And add
   WARN_ON_ONCE().
 - Move attribute specific logic into kvm_vm_set_mem_attributes()
 - Drop Sean's suggested-by tag as the solution has changed
 - Re-write commit log

v18:
 - rebased to kvm-next

v3:
 - Drop the KVM_GFN_RANGE flags
 - Updated struct kvm_gfn_range
 - Change kvm_arch_set_memory_attributes() to return bool for flush
 - Added set_memory_attributes x86 op for vendor backends
 - Refined commit message to describe TDX care concretely

v2:
 - consolidate KVM_GFN_RANGE_FLAGS_GMEM_{PUNCH_HOLE, RELEASE} into
   KVM_GFN_RANGE_FLAGS_GMEM.
 - Update the commit message to describe TDX more.  Drop SEV_SNP.
---
 arch/x86/kvm/mmu/mmu.c   | 12 ++++++++++++
 include/linux/kvm_host.h |  8 ++++++++
 virt/kvm/guest_memfd.c   |  2 ++
 virt/kvm/kvm_main.c      | 14 ++++++++++++++
 4 files changed, 36 insertions(+)

diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c
index 4a8e819794db..1998267a330e 100644
--- a/arch/x86/kvm/mmu/mmu.c
+++ b/arch/x86/kvm/mmu/mmu.c
@@ -6979,6 +6979,12 @@ static void kvm_mmu_zap_memslot_leafs(struct kvm *kvm, struct kvm_memory_slot *s
 		.start = slot->base_gfn,
 		.end = slot->base_gfn + slot->npages,
 		.may_block = true,
+
+		/*
+		 * All private and shared page should be zapped on memslot
+		 * deletion.
+		 */
+		.process = KVM_PROCESS_PRIVATE_AND_SHARED,
 	};
 
 	if (kvm_tdp_mmu_unmap_gfn_range(kvm, &range, false))
@@ -7479,6 +7485,12 @@ bool kvm_arch_pre_set_memory_attributes(struct kvm *kvm,
 	if (WARN_ON_ONCE(!kvm_arch_has_private_mem(kvm)))
 		return false;
 
+	/* Unmmap the old attribute page. */
+	if (range->arg.attributes & KVM_MEMORY_ATTRIBUTE_PRIVATE)
+		range->process = KVM_PROCESS_SHARED;
+	else
+		range->process = KVM_PROCESS_PRIVATE;
+
 	return kvm_unmap_gfn_range(kvm, range);
 }
 
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index c3c922bf077f..f92c8b605b03 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -260,11 +260,19 @@ union kvm_mmu_notifier_arg {
 	unsigned long attributes;
 };
 
+enum kvm_process {
+	BUGGY_KVM_INVALIDATION		= 0,
+	KVM_PROCESS_SHARED		= BIT(0),
+	KVM_PROCESS_PRIVATE		= BIT(1),
+	KVM_PROCESS_PRIVATE_AND_SHARED	= KVM_PROCESS_SHARED | KVM_PROCESS_PRIVATE,
+};
+
 struct kvm_gfn_range {
 	struct kvm_memory_slot *slot;
 	gfn_t start;
 	gfn_t end;
 	union kvm_mmu_notifier_arg arg;
+	enum kvm_process process;
 	bool may_block;
 };
 bool kvm_unmap_gfn_range(struct kvm *kvm, struct kvm_gfn_range *range);
diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c
index 9714add38852..e5ff6fde2db3 100644
--- a/virt/kvm/guest_memfd.c
+++ b/virt/kvm/guest_memfd.c
@@ -109,6 +109,8 @@ static void kvm_gmem_invalidate_begin(struct kvm_gmem *gmem, pgoff_t start,
 			.end = slot->base_gfn + min(pgoff + slot->npages, end) - pgoff,
 			.slot = slot,
 			.may_block = true,
+			/* guest memfd is relevant to only private mappings. */
+			.process = KVM_PROCESS_PRIVATE,
 		};
 
 		if (!found_memslot) {
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 1b1ffb6fc786..cc434c7509f1 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -635,6 +635,11 @@ static __always_inline kvm_mn_ret_t __kvm_handle_hva_range(struct kvm *kvm,
 			 */
 			gfn_range.arg = range->arg;
 			gfn_range.may_block = range->may_block;
+			/*
+			 * HVA-based notifications aren't relevant to private
+			 * mappings as they don't have a userspace mapping.
+			 */
+			gfn_range.process = KVM_PROCESS_SHARED;
 
 			/*
 			 * {gfn(page) | page intersects with [hva_start, hva_end)} =
@@ -2453,6 +2458,14 @@ static __always_inline void kvm_handle_gfn_range(struct kvm *kvm,
 	gfn_range.arg = range->arg;
 	gfn_range.may_block = range->may_block;
 
+	/*
+	 * If/when KVM supports more attributes beyond private .vs shared, this
+	 * _could_ set exclude_{private,shared} appropriately if the entire target
+	 * range already has the desired private vs. shared state (it's unclear
+	 * if that is a net win).  For now, KVM reaches this point if and only
+	 * if the private flag is being toggled, i.e. all mappings are in play.
+	 */
+
 	for (i = 0; i < kvm_arch_nr_memslot_as_ids(kvm); i++) {
 		slots = __kvm_memslots(kvm, i);
 
@@ -2509,6 +2522,7 @@ static int kvm_vm_set_mem_attributes(struct kvm *kvm, gfn_t start, gfn_t end,
 	struct kvm_mmu_notifier_range pre_set_range = {
 		.start = start,
 		.end = end,
+		.arg.attributes = attributes,
 		.handler = kvm_pre_set_memory_attributes,
 		.on_lock = kvm_mmu_invalidate_begin,
 		.flush_on_ret = true,
-- 
2.34.1


  parent reply	other threads:[~2024-05-15  1:00 UTC|newest]

Thread overview: 152+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-05-15  0:59 [PATCH 00/16] TDX MMU prep series part 1 Rick Edgecombe
2024-05-15  0:59 ` [PATCH 01/16] KVM: x86: Add a VM type define for TDX Rick Edgecombe
2024-05-15  0:59 ` [PATCH 02/16] KVM: x86/mmu: Introduce a slot flag to zap only slot leafs on slot deletion Rick Edgecombe
2024-05-15 13:24   ` Huang, Kai
2024-05-15 19:09     ` Sean Christopherson
2024-05-15 19:23       ` Edgecombe, Rick P
2024-05-15 20:05         ` Sean Christopherson
2024-05-15 20:53           ` Edgecombe, Rick P
2024-05-15 22:47             ` Sean Christopherson
2024-05-15 23:06               ` Huang, Kai
2024-05-15 23:20                 ` Sean Christopherson
2024-05-15 23:36                   ` Huang, Kai
2024-05-16  1:12                   ` Xiaoyao Li
2024-05-17 15:30                   ` Paolo Bonzini
2024-05-22  1:29                     ` Yan Zhao
2024-05-22  2:31                       ` Sean Christopherson
2024-05-22  6:48                         ` Yan Zhao
2024-05-22 15:45                           ` Paolo Bonzini
2024-05-24  1:50                             ` Yan Zhao
2024-05-15 23:56               ` Edgecombe, Rick P
2024-05-16  2:21                 ` Edgecombe, Rick P
2024-05-16  3:56                 ` Yan Zhao
2024-05-17 15:27           ` Paolo Bonzini
2024-05-17 15:25       ` Paolo Bonzini
2024-05-15 18:03   ` Isaku Yamahata
2024-05-15  0:59 ` [PATCH 03/16] KVM: x86/tdp_mmu: Add a helper function to walk down the TDP MMU Rick Edgecombe
2024-05-17  7:44   ` Chao Gao
2024-05-17  9:08     ` Isaku Yamahata
2024-05-15  0:59 ` [PATCH 04/16] KVM: x86/mmu: Add address conversion functions for TDX shared bit of GPA Rick Edgecombe
2024-05-15 22:34   ` Huang, Kai
2024-05-15 23:21     ` Edgecombe, Rick P
2024-05-15 23:31       ` Huang, Kai
2024-05-15 23:38         ` Edgecombe, Rick P
2024-05-15 23:44           ` Huang, Kai
2024-05-15 23:59             ` Edgecombe, Rick P
2024-05-16  0:12               ` Huang, Kai
2024-05-16  0:19                 ` Edgecombe, Rick P
2024-05-16  0:25                   ` Huang, Kai
2024-05-16  0:35                     ` Edgecombe, Rick P
2024-05-16  1:04                       ` Huang, Kai
2024-05-16  1:20                         ` Edgecombe, Rick P
2024-05-16  1:40                           ` Huang, Kai
2024-05-16  5:52                             ` Yan Zhao
2024-05-18  0:25                               ` Edgecombe, Rick P
2024-05-16 23:08                           ` Edgecombe, Rick P
2024-05-17  0:37                             ` Huang, Kai
2024-05-17  1:51                               ` Edgecombe, Rick P
2024-05-17  4:26                                 ` Huang, Kai
2024-05-17 21:12                                   ` Edgecombe, Rick P
2024-05-15  0:59 ` Rick Edgecombe [this message]
2024-05-17 20:58   ` [PATCH 05/16] KVM: Add member to struct kvm_gfn_range for target alias Edgecombe, Rick P
2024-05-15  0:59 ` [PATCH 06/16] KVM: x86/mmu: Add a new is_private member for union kvm_mmu_page_role Rick Edgecombe
2024-05-15  0:59 ` [PATCH 07/16] KVM: x86/mmu: Add a private pointer to struct kvm_mmu_page Rick Edgecombe
2024-05-15  0:59 ` [PATCH 08/16] KVM: x86/mmu: Bug the VM if kvm_zap_gfn_range() is called for TDX Rick Edgecombe
2024-05-15 13:27   ` Huang, Kai
2024-05-15 15:22     ` Edgecombe, Rick P
2024-05-15 23:14       ` Huang, Kai
2024-05-15 15:34   ` Sean Christopherson
2024-05-15 15:49     ` Edgecombe, Rick P
2024-05-15 15:56       ` Edgecombe, Rick P
2024-05-15 16:02         ` Sean Christopherson
2024-05-15 16:12           ` Edgecombe, Rick P
2024-05-15 18:09             ` Sean Christopherson
2024-05-15 18:22               ` Edgecombe, Rick P
2024-05-15 19:48                 ` Sean Christopherson
2024-05-15 20:32                   ` Edgecombe, Rick P
2024-05-15 23:26                     ` Sean Christopherson
2024-05-15 16:22     ` Isaku Yamahata
2024-05-15 22:17       ` Huang, Kai
2024-05-15 23:14         ` Edgecombe, Rick P
2024-05-15 23:38           ` Huang, Kai
2024-05-16  0:13             ` Edgecombe, Rick P
2024-05-16  0:27               ` Isaku Yamahata
2024-05-16  1:11               ` Huang, Kai
2024-05-16  0:15         ` Isaku Yamahata
2024-05-16  0:52           ` Edgecombe, Rick P
2024-05-16  1:21           ` Huang, Kai
2024-05-16 17:27             ` Isaku Yamahata
2024-05-16 21:46   ` Edgecombe, Rick P
2024-05-16 22:23     ` Huang, Kai
2024-05-16 22:38       ` Edgecombe, Rick P
2024-05-16 23:16         ` Huang, Kai
2024-05-15  0:59 ` [PATCH 09/16] KVM: x86/mmu: Make kvm_tdp_mmu_alloc_root() return void Rick Edgecombe
2024-05-15  0:59 ` [PATCH 10/16] KVM: x86/tdp_mmu: Support TDX private mapping for TDP MMU Rick Edgecombe
2024-05-15 17:35   ` Isaku Yamahata
2024-05-15 18:00     ` Edgecombe, Rick P
2024-05-16  0:52   ` Huang, Kai
2024-05-16  1:27     ` Edgecombe, Rick P
2024-05-16  2:07       ` Huang, Kai
2024-05-16  2:57         ` Edgecombe, Rick P
2024-05-16 13:04           ` Huang, Kai
2024-05-16 16:36             ` Edgecombe, Rick P
2024-05-16 19:42               ` Isaku Yamahata
2024-05-17  2:35                 ` Edgecombe, Rick P
2024-05-17  9:03                   ` Isaku Yamahata
2024-05-17 18:16                     ` Edgecombe, Rick P
2024-05-17 19:16                       ` Isaku Yamahata
2024-05-20 23:32                         ` Isaku Yamahata
2024-05-21 15:07                           ` Edgecombe, Rick P
2024-05-21 16:15                             ` Isaku Yamahata
2024-05-22 22:34                               ` Isaku Yamahata
2024-05-22 23:09                                 ` Edgecombe, Rick P
2024-05-22 23:47                                   ` Isaku Yamahata
2024-05-22 23:50                                     ` Edgecombe, Rick P
2024-05-23  0:01                                       ` Isaku Yamahata
2024-05-23 18:27                                         ` Edgecombe, Rick P
2024-05-24  7:55                                           ` Isaku Yamahata
2024-05-28 16:27                                             ` Edgecombe, Rick P
2024-05-28 17:47                                               ` Paolo Bonzini
2024-05-29  2:13                                                 ` Edgecombe, Rick P
2024-05-29  7:25                                                   ` Paolo Bonzini
2024-05-31 14:11                                                     ` Isaku Yamahata
2024-05-28 17:43                           ` Paolo Bonzini
2024-05-28 17:16                         ` Paolo Bonzini
2024-05-28 18:29                           ` Edgecombe, Rick P
2024-05-29  1:06                             ` Isaku Yamahata
2024-05-29  1:51                               ` Edgecombe, Rick P
2024-05-17  2:36                 ` Huang, Kai
2024-05-17  8:14                   ` Isaku Yamahata
2024-05-18  5:42                     ` Huang, Kai
2024-05-18 15:41                       ` Edgecombe, Rick P
2024-05-20 10:38                         ` Huang, Kai
2024-05-20 18:58                           ` Isaku Yamahata
2024-05-20 19:02                             ` Edgecombe, Rick P
2024-05-20 23:39                               ` Edgecombe, Rick P
2024-05-21  2:25                                 ` Isaku Yamahata
2024-05-21  2:57                                   ` Edgecombe, Rick P
2024-05-20 22:34                             ` Huang, Kai
2024-05-16  1:48     ` Isaku Yamahata
2024-05-16  2:00       ` Edgecombe, Rick P
2024-05-16  2:10         ` Huang, Kai
2024-05-28 16:59           ` Paolo Bonzini
2024-05-16 17:10         ` Isaku Yamahata
2024-05-23 23:14   ` Edgecombe, Rick P
2024-05-24  8:20     ` Isaku Yamahata
2024-05-28 21:48       ` Edgecombe, Rick P
2024-05-29  1:16         ` Isaku Yamahata
2024-05-29  1:50           ` Edgecombe, Rick P
2024-05-29  2:20             ` Isaku Yamahata
2024-05-29  2:29               ` Edgecombe, Rick P
2024-05-28 20:54   ` Edgecombe, Rick P
2024-05-29  1:24     ` Isaku Yamahata
2024-05-28 23:06   ` Edgecombe, Rick P
2024-05-29  1:57     ` Isaku Yamahata
2024-05-29  2:13       ` Edgecombe, Rick P
2024-05-29 16:55         ` Isaku Yamahata
2024-05-15  0:59 ` [PATCH 11/16] KVM: x86/tdp_mmu: Extract root invalid check from tdx_mmu_next_root() Rick Edgecombe
2024-05-15  0:59 ` [PATCH 12/16] KVM: x86/tdp_mmu: Introduce KVM MMU root types to specify page table type Rick Edgecombe
2024-05-15  0:59 ` [PATCH 13/16] KVM: x86/tdp_mmu: Introduce shared, private KVM MMU root types Rick Edgecombe
2024-05-15  0:59 ` [PATCH 14/16] KVM: x86/tdp_mmu: Take root types for kvm_tdp_mmu_invalidate_all_roots() Rick Edgecombe
2024-05-15  0:59 ` [PATCH 15/16] KVM: x86/tdp_mmu: Make mmu notifier callbacks to check kvm_process Rick Edgecombe
2024-05-15  0:59 ` [PATCH 16/16] KVM: x86/tdp_mmu: Invalidate correct roots Rick Edgecombe

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240515005952.3410568-6-rick.p.edgecombe@intel.com \
    --to=rick.p.edgecombe@intel.com \
    --cc=dmatlack@google.com \
    --cc=erdemaktas@google.com \
    --cc=isaku.yamahata@gmail.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=pbonzini@redhat.com \
    --cc=sagis@google.com \
    --cc=seanjc@google.com \
    --cc=yan.y.zhao@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox