All of lore.kernel.org
 help / color / mirror / Atom feed
From: Adalbert Lazar <alazar@bitdefender.com>
To: kvm@vger.kernel.org
Cc: "Paolo Bonzini" <pbonzini@redhat.com>,
	"Radim Krčmář" <rkrcmar@redhat.com>,
	alazar@bitdefender.com, mdontu@bitdefender.com
Subject: [RFC PATCH 01/19] kvm: x86: mmu: Add kvm_mmu_get_spte() and kvm_mmu_set_spte()
Date: Fri, 16 Jun 2017 16:43:30 +0300	[thread overview]
Message-ID: <20170616134348.17725-2-alazar@bitdefender.com> (raw)
In-Reply-To: <20170616134348.17725-1-alazar@bitdefender.com>

From: Mihai Dontu <mdontu@bitdefender.com>

These are helpers used by the introspection subsystem to adjust the SPTE
rwx flags. At present, the code assumes we're deadling with 4-level
hardware shadow page tables.

Signed-off-by: Mihai Dontu <mdontu@bitdefender.com>
---
 arch/x86/kvm/mmu.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 arch/x86/kvm/mmu.h |  3 +++
 2 files changed, 78 insertions(+)

diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index cb8225969255..12e4c33ff879 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -5350,3 +5350,78 @@ void kvm_mmu_module_exit(void)
 	unregister_shrinker(&mmu_shrinker);
 	mmu_audit_disable();
 }
+
+u64 kvm_mmu_get_spte(struct kvm *kvm, struct kvm_vcpu *vcpu, gpa_t gpa)
+{
+	u64 spte = -1;
+	unsigned int c = 0;
+	const u64 mask = PT_PRESENT_MASK | PT_WRITABLE_MASK | PT_USER_MASK;
+	struct kvm_shadow_walk_iterator iterator;
+
+	spin_lock(&kvm->mmu_lock);
+	if (!VALID_PAGE(vcpu->arch.mmu.root_hpa))
+		goto error;
+	for_each_shadow_entry(vcpu, gpa & PAGE_MASK, iterator) {
+		u64 __spte = *iterator.sptep;
+
+		if (!(__spte & mask))
+			break;
+		else if (++c == PT64_ROOT_LEVEL) {
+			spte = __spte;
+			break;
+		}
+	}
+	if (spte == (u64) -1)
+		goto error;
+	spin_unlock(&kvm->mmu_lock);
+	return spte & mask;
+error:
+	spin_unlock(&kvm->mmu_lock);
+	return -ENOENT;
+}
+
+int kvm_mmu_set_spte(struct kvm *kvm, struct kvm_vcpu *vcpu, gpa_t gpa,
+		     unsigned int r, unsigned int w, unsigned int x)
+{
+	int flush = 0;
+	u64 *pspte[4] = { };
+	u64 spte;
+	u64 old_spte;
+	unsigned int c = 0;
+	const u64 mask = PT_PRESENT_MASK | PT_WRITABLE_MASK | PT_USER_MASK;
+	struct kvm_shadow_walk_iterator iterator;
+
+	spin_lock(&kvm->mmu_lock);
+	if (!VALID_PAGE(vcpu->arch.mmu.root_hpa))
+		goto error;
+	for_each_shadow_entry(vcpu, gpa & PAGE_MASK, iterator) {
+		u64 __spte = *iterator.sptep;
+
+		if (!(__spte & mask))
+			break;
+		pspte[c++] = iterator.sptep;
+	}
+	if (c < PT64_ROOT_LEVEL || !pspte[c - 1])
+		goto error;
+	c--;
+	old_spte = *pspte[c];
+	spte = old_spte & ~mask;
+	if (r)
+		spte |= PT_PRESENT_MASK;
+	if (w)
+		spte |= PT_WRITABLE_MASK;
+	if (x)
+		spte |= PT_USER_MASK;
+	if (old_spte != spte)
+		flush |= mmu_spte_update(pspte[c], spte);
+	while (c-- > 0) {
+		spte = *pspte[c];
+		if ((spte & mask) != mask)
+			flush |= mmu_spte_update(pspte[c], spte | mask);
+	}
+	spin_unlock(&kvm->mmu_lock);
+	return flush;
+error:
+	spin_unlock(&kvm->mmu_lock);
+	return -ENOENT;
+}
diff --git a/arch/x86/kvm/mmu.h b/arch/x86/kvm/mmu.h
index 330bf3a811fb..82246fdc0479 100644
--- a/arch/x86/kvm/mmu.h
+++ b/arch/x86/kvm/mmu.h
@@ -204,4 +204,7 @@ void kvm_mmu_gfn_allow_lpage(struct kvm_memory_slot *slot, gfn_t gfn);
 bool kvm_mmu_slot_gfn_write_protect(struct kvm *kvm,
 				    struct kvm_memory_slot *slot, u64 gfn);
 int kvm_arch_write_log_dirty(struct kvm_vcpu *vcpu);
+u64 kvm_mmu_get_spte(struct kvm *kvm, struct kvm_vcpu *vcpu, gpa_t gpa);
+int kvm_mmu_set_spte(struct kvm *kvm, struct kvm_vcpu *vcpu, gpa_t gpa,
+		     unsigned int r, unsigned int w, unsigned int x);
 #endif
-- 
2.12.2

  reply	other threads:[~2017-06-16 13:42 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-06-16 13:43 [RFC PATCH 00/19] Guest introspection Adalbert Lazar
2017-06-16 13:43 ` Adalbert Lazar [this message]
2017-06-16 13:43 ` [RFC PATCH 02/19] kvm: x86: Add kvm_arch_vcpu_set_regs() Adalbert Lazar
2017-06-16 13:43 ` [RFC PATCH 03/19] mm: Add vm_replace_page() Adalbert Lazar
2017-06-16 13:43 ` [RFC PATCH 04/19] kvm: Add kvm_enum() Adalbert Lazar
2017-06-16 13:43 ` [RFC PATCH 05/19] kvm: Add uuid member in struct kvm + support for KVM_CAP_VM_UUID Adalbert Lazar
2017-06-16 13:43 ` [RFC PATCH 06/19] kvm: Add kvm_vm_shutdown() Adalbert Lazar
2017-06-16 13:43 ` [RFC PATCH 07/19] kvm: x86: Add kvm_arch_msr_intercept() Adalbert Lazar
2017-06-16 13:43 ` [RFC PATCH 08/19] kvm: Add the introspection subsystem Adalbert Lazar
2017-06-21 11:54   ` Paolo Bonzini
2017-06-21 12:36     ` Mihai Donțu
2017-06-21 12:57       ` Paolo Bonzini
2017-06-16 13:43 ` [RFC PATCH 09/19] kvm: Hook in kvmi on VM on/off events Adalbert Lazar
2017-06-16 13:43 ` [RFC PATCH 10/19] kvm: vmx: Hook in kvmi_page_fault() Adalbert Lazar
2017-06-16 13:43 ` [RFC PATCH 11/19] kvm: x86: Hook in kvmi_breakpoint_event() Adalbert Lazar
2017-06-21 11:48   ` Paolo Bonzini
2017-06-21 12:37     ` Mihai Donțu
2017-06-16 13:43 ` [RFC PATCH 12/19] kvm: x86: Hook in kvmi_trap_event() Adalbert Lazar
2017-06-16 13:43 ` [RFC PATCH 13/19] kvm: x86: Hook in kvmi_cr_event() Adalbert Lazar
2017-06-16 13:43 ` [RFC PATCH 14/19] kvm: x86: Hook in kvmi_xsetbv_event() Adalbert Lazar
2017-06-16 13:43 ` [RFC PATCH 15/19] kvm: x86: Hook in kvmi_msr_event() Adalbert Lazar
2017-06-16 13:43 ` [RFC PATCH 16/19] kvm: x86: Change the emulation context Adalbert Lazar
2017-06-16 13:43 ` [RFC PATCH 17/19] kvm: x86: Hook in kvmi_vmcall_event() Adalbert Lazar
2017-06-16 13:43 ` [RFC PATCH 18/19] kvm: x86: Set the new spte flags before entering the guest Adalbert Lazar
2017-06-16 13:43 ` [RFC PATCH 19/19] kvm: x86: Handle KVM_REQ_INTROSPECTION Adalbert Lazar
2017-06-16 14:45 ` [RFC PATCH 00/19] Guest introspection Jan Kiszka
2017-06-16 15:18   ` Mihai Donțu
2017-06-16 15:34     ` Jan Kiszka
2017-06-16 15:59       ` Mihai Donțu
2017-06-19  9:39       ` Stefan Hajnoczi
2017-06-20 14:58         ` alazar
2017-06-20 15:03           ` Jan Kiszka
2017-06-21 11:04           ` Stefan Hajnoczi
2017-06-21 13:25             ` Paolo Bonzini
2017-06-27 16:12               ` Mihai Donțu
2017-06-27 16:23                 ` Paolo Bonzini
2017-06-16 17:05     ` Paolo Bonzini
2017-06-16 17:27       ` Jan Kiszka

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=20170616134348.17725-2-alazar@bitdefender.com \
    --to=alazar@bitdefender.com \
    --cc=kvm@vger.kernel.org \
    --cc=mdontu@bitdefender.com \
    --cc=pbonzini@redhat.com \
    --cc=rkrcmar@redhat.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.