All of lore.kernel.org
 help / color / mirror / Atom feed
From: isaku.yamahata@intel.com
To: kvm@vger.kernel.org
Cc: isaku.yamahata@intel.com, isaku.yamahata@gmail.com,
	linux-kernel@vger.kernel.org,
	Sean Christopherson <seanjc@google.com>,
	Paolo Bonzini <pbonzini@redhat.com>,
	Michael Roth <michael.roth@amd.com>,
	David Matlack <dmatlack@google.com>,
	Federico Parola <federico.parola@polito.it>,
	Kai Huang <kai.huang@intel.com>
Subject: [PATCH v2 07/10] KVM: x86: Always populate L1 GPA for KVM_MAP_MEMORY
Date: Wed, 10 Apr 2024 15:07:33 -0700	[thread overview]
Message-ID: <2f1de1b7b6512280fae4ac05e77ced80a585971b.1712785629.git.isaku.yamahata@intel.com> (raw)
In-Reply-To: <cover.1712785629.git.isaku.yamahata@intel.com>

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

Forcibly switch vCPU mode out from guest mode and SMM mode before calling
KVM page fault handler for KVM_MAP_MEMORY.

KVM_MAP_MEMORY populates guest memory with guest physical address (GPA).
If the vCPU is in guest mode, it populates with L2 GPA.  If vCPU is in SMM
mode, it populates the SMM address pace.  The API would be difficult to use
as such.  Change vCPU MMU mode around populating the guest memory to always
populate with L1 GPA.

There are several options to populate L1 GPA irrelevant to vCPU mode.
- Switch vCPU MMU only: This patch.
  Pros: Concise implementation.
  Cons: Heavily dependent on the KVM MMU implementation.
- Use kvm_x86_nested_ops.get/set_state() to switch to/from guest mode.
  Use __get/set_sregs2() to switch to/from SMM mode.
  Pros: straightforward.
  Cons: This may cause unintended side effects.
- Refactor KVM page fault handler not to pass vCPU. Pass around necessary
  parameters and struct kvm.
  Pros: The end result will have clearly no side effects.
  Cons: This will require big refactoring.
- Return error on guest mode or SMM mode:  Without this patch.
  Pros: No additional patch.
  Cons: Difficult to use.

Signed-off-by: Isaku Yamahata <isaku.yamahata@intel.com>
---
v2:
- Newly added.
---
 arch/x86/kvm/x86.c | 26 +++++++++++++++++++++++++-
 1 file changed, 25 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 2c765de3531e..8ba9c1720ac9 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -5871,8 +5871,10 @@ static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu,
 int kvm_arch_vcpu_map_memory(struct kvm_vcpu *vcpu,
 			     struct kvm_memory_mapping *mapping)
 {
+	struct kvm_mmu *mmu = NULL, *walk_mmu = NULL;
 	u64 end, error_code = 0;
 	u8 level = PG_LEVEL_4K;
+	bool is_smm;
 	int r;
 
 	/*
@@ -5882,18 +5884,40 @@ int kvm_arch_vcpu_map_memory(struct kvm_vcpu *vcpu,
 	if (!tdp_enabled)
 		return -EOPNOTSUPP;
 
+	/* Force to use L1 GPA despite of vcpu MMU mode. */
+	is_smm = !!(vcpu->arch.hflags & HF_SMM_MASK);
+	if (is_smm ||
+	    vcpu->arch.mmu != &vcpu->arch.root_mmu ||
+	    vcpu->arch.walk_mmu != &vcpu->arch.root_mmu) {
+		vcpu->arch.hflags &= ~HF_SMM_MASK;
+		mmu = vcpu->arch.mmu;
+		walk_mmu = vcpu->arch.walk_mmu;
+		vcpu->arch.mmu = &vcpu->arch.root_mmu;
+		vcpu->arch.walk_mmu = &vcpu->arch.root_mmu;
+		kvm_mmu_reset_context(vcpu);
+	}
+
 	/* reload is optimized for repeated call. */
 	kvm_mmu_reload(vcpu);
 
 	r = kvm_tdp_map_page(vcpu, mapping->base_address, error_code, &level);
 	if (r)
-		return r;
+		goto out;
 
 	/* mapping->base_address is not necessarily aligned to level-hugepage. */
 	end = (mapping->base_address & KVM_HPAGE_MASK(level)) +
 		KVM_HPAGE_SIZE(level);
 	mapping->size -= end - mapping->base_address;
 	mapping->base_address = end;
+
+out:
+	/* Restore MMU state. */
+	if (is_smm || mmu) {
+		vcpu->arch.hflags |= is_smm ? HF_SMM_MASK : 0;
+		vcpu->arch.mmu = mmu;
+		vcpu->arch.walk_mmu = walk_mmu;
+		kvm_mmu_reset_context(vcpu);
+	}
 	return r;
 }
 
-- 
2.43.2


  parent reply	other threads:[~2024-04-10 22:07 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-04-10 22:07 [PATCH v2 00/10] KVM: Guest Memory Pre-Population API isaku.yamahata
2024-04-10 22:07 ` [PATCH v2 01/10] KVM: Document KVM_MAP_MEMORY ioctl isaku.yamahata
2024-04-15 23:27   ` Edgecombe, Rick P
2024-04-15 23:47     ` Isaku Yamahata
2024-04-17 11:56     ` Paolo Bonzini
2024-04-10 22:07 ` [PATCH v2 02/10] KVM: Add KVM_MAP_MEMORY vcpu ioctl to pre-populate guest memory isaku.yamahata
2024-04-16 14:20   ` Edgecombe, Rick P
2024-04-10 22:07 ` [PATCH v2 03/10] KVM: x86/mmu: Extract __kvm_mmu_do_page_fault() isaku.yamahata
2024-04-16  8:22   ` Chao Gao
2024-04-16 23:43     ` Isaku Yamahata
2024-04-16 14:36   ` Edgecombe, Rick P
2024-04-16 23:52     ` Isaku Yamahata
2024-04-17 15:41       ` Paolo Bonzini
2024-04-10 22:07 ` [PATCH v2 04/10] KVM: x86/mmu: Make __kvm_mmu_do_page_fault() return mapped level isaku.yamahata
2024-04-16 14:40   ` Edgecombe, Rick P
2024-04-16 23:59     ` Isaku Yamahata
2024-04-10 22:07 ` [PATCH v2 05/10] KVM: x86/mmu: Introduce kvm_tdp_map_page() to populate guest memory isaku.yamahata
2024-04-16 14:46   ` Edgecombe, Rick P
2024-04-17 18:39     ` Isaku Yamahata
2024-04-17  7:04   ` Chao Gao
2024-04-17 18:44     ` Isaku Yamahata
2024-04-10 22:07 ` [PATCH v2 06/10] KVM: x86: Implement kvm_arch_vcpu_map_memory() isaku.yamahata
2024-04-16 15:12   ` Edgecombe, Rick P
2024-04-17  7:20   ` Chao Gao
2024-04-17 12:18   ` Paolo Bonzini
2024-04-10 22:07 ` isaku.yamahata [this message]
2024-04-15 19:12   ` [PATCH v2 07/10] KVM: x86: Always populate L1 GPA for KVM_MAP_MEMORY Edgecombe, Rick P
2024-04-15 21:17     ` Sean Christopherson
2024-04-15 21:36       ` Edgecombe, Rick P
2024-04-15 22:59         ` Sean Christopherson
2024-04-16  1:49       ` Isaku Yamahata
2024-04-16 14:22         ` Sean Christopherson
2024-04-16 21:41       ` Paolo Bonzini
2024-04-16 23:00         ` Sean Christopherson
2024-04-17 10:28           ` Paolo Bonzini
2024-04-15 19:37   ` Edgecombe, Rick P
2024-04-16 17:11   ` Edgecombe, Rick P
2024-04-10 22:07 ` [PATCH v2 08/10] KVM: x86: Add a hook in kvm_arch_vcpu_map_memory() isaku.yamahata
2024-04-16 14:57   ` Edgecombe, Rick P
2024-04-17 12:26   ` Paolo Bonzini
2024-04-10 22:07 ` [PATCH v2 09/10] KVM: SVM: Implement pre_mmu_map_page() to refuse KVM_MAP_MEMORY isaku.yamahata
2024-04-10 22:07 ` [PATCH v2 10/10] KVM: selftests: x86: Add test for KVM_MAP_MEMORY isaku.yamahata

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=2f1de1b7b6512280fae4ac05e77ced80a585971b.1712785629.git.isaku.yamahata@intel.com \
    --to=isaku.yamahata@intel.com \
    --cc=dmatlack@google.com \
    --cc=federico.parola@polito.it \
    --cc=isaku.yamahata@gmail.com \
    --cc=kai.huang@intel.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=michael.roth@amd.com \
    --cc=pbonzini@redhat.com \
    --cc=seanjc@google.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.