mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Avi Kivity <avi@qumranet.com>
To: kvm-devel@lists.sourceforge.net
Cc: linux-kernel@vger.kernel.org, "Dong, Eddie" <eddie.dong@intel.com>
Subject: [PATCH 01/40] KVM: MMU: Update shadow ptes on partial guest pte writes
Date: Mon, 31 Mar 2008 17:36:45 +0300	[thread overview]
Message-ID: <1206974244-9716-2-git-send-email-avi@qumranet.com> (raw)
In-Reply-To: <1206974244-9716-1-git-send-email-avi@qumranet.com>

From: Dong, Eddie <eddie.dong@intel.com>

A guest partial guest pte write will leave shadow_trap_nonpresent_pte
in spte, which generates a vmexit at the next guest access through that pte.

This patch improves this by reading the full guest pte in advance and thus
being able to update the spte and eliminate the vmexit.

This helps pae guests which use two 32-bit writes to set a single 64-bit pte.

[truncation fix by Eric]

Signed-off-by: Yaozu (Eddie) Dong <eddie.dong@intel.com>
Signed-off-by: Feng (Eric) Liu <eric.e.liu@intel.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
 arch/x86/kvm/mmu.c         |   23 ++++++++++++++++-------
 arch/x86/kvm/paging_tmpl.h |    7 ++-----
 2 files changed, 18 insertions(+), 12 deletions(-)

diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index e55af12..28f9a44 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -1329,8 +1329,7 @@ static void mmu_pte_write_zap_pte(struct kvm_vcpu *vcpu,
 static void mmu_pte_write_new_pte(struct kvm_vcpu *vcpu,
 				  struct kvm_mmu_page *sp,
 				  u64 *spte,
-				  const void *new, int bytes,
-				  int offset_in_pte)
+				  const void *new)
 {
 	if (sp->role.level != PT_PAGE_TABLE_LEVEL) {
 		++vcpu->kvm->stat.mmu_pde_zapped;
@@ -1339,9 +1338,9 @@ static void mmu_pte_write_new_pte(struct kvm_vcpu *vcpu,
 
 	++vcpu->kvm->stat.mmu_pte_updated;
 	if (sp->role.glevels == PT32_ROOT_LEVEL)
-		paging32_update_pte(vcpu, sp, spte, new, bytes, offset_in_pte);
+		paging32_update_pte(vcpu, sp, spte, new);
 	else
-		paging64_update_pte(vcpu, sp, spte, new, bytes, offset_in_pte);
+		paging64_update_pte(vcpu, sp, spte, new);
 }
 
 static bool need_remote_flush(u64 old, u64 new)
@@ -1423,7 +1422,7 @@ void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,
 	struct hlist_node *node, *n;
 	struct hlist_head *bucket;
 	unsigned index;
-	u64 entry;
+	u64 entry, gentry;
 	u64 *spte;
 	unsigned offset = offset_in_page(gpa);
 	unsigned pte_size;
@@ -1433,6 +1432,7 @@ void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,
 	int level;
 	int flooded = 0;
 	int npte;
+	int r;
 
 	pgprintk("%s: gpa %llx bytes %d\n", __FUNCTION__, gpa, bytes);
 	mmu_guess_page_from_pte_write(vcpu, gpa, new, bytes);
@@ -1496,11 +1496,20 @@ void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,
 				continue;
 		}
 		spte = &sp->spt[page_offset / sizeof(*spte)];
+		if ((gpa & (pte_size - 1)) || (bytes < pte_size)) {
+			gentry = 0;
+			r = kvm_read_guest_atomic(vcpu->kvm,
+						  gpa & ~(u64)(pte_size - 1),
+						  &gentry, pte_size);
+			new = (const void *)&gentry;
+			if (r < 0)
+				new = NULL;
+		}
 		while (npte--) {
 			entry = *spte;
 			mmu_pte_write_zap_pte(vcpu, sp, spte);
-			mmu_pte_write_new_pte(vcpu, sp, spte, new, bytes,
-					      page_offset & (pte_size - 1));
+			if (new)
+				mmu_pte_write_new_pte(vcpu, sp, spte, new);
 			mmu_pte_write_flush_tlb(vcpu, entry, *spte);
 			++spte;
 		}
diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h
index ecc0856..c2fd2b9 100644
--- a/arch/x86/kvm/paging_tmpl.h
+++ b/arch/x86/kvm/paging_tmpl.h
@@ -243,8 +243,7 @@ err:
 }
 
 static void FNAME(update_pte)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *page,
-			      u64 *spte, const void *pte, int bytes,
-			      int offset_in_pte)
+			      u64 *spte, const void *pte)
 {
 	pt_element_t gpte;
 	unsigned pte_access;
@@ -252,12 +251,10 @@ static void FNAME(update_pte)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *page,
 
 	gpte = *(const pt_element_t *)pte;
 	if (~gpte & (PT_PRESENT_MASK | PT_ACCESSED_MASK)) {
-		if (!offset_in_pte && !is_present_pte(gpte))
+		if (!is_present_pte(gpte))
 			set_shadow_pte(spte, shadow_notrap_nonpresent_pte);
 		return;
 	}
-	if (bytes < sizeof(pt_element_t))
-		return;
 	pgprintk("%s: gpte %llx spte %p\n", __FUNCTION__, (u64)gpte, spte);
 	pte_access = page->role.access & FNAME(gpte_access)(vcpu, gpte);
 	if (gpte_to_gfn(gpte) != vcpu->arch.update_pte.gfn)
-- 
1.5.4.5


  reply	other threads:[~2008-03-31 14:38 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-03-31 14:36 [PATCH 00/40] KVM updates for the 2.6.26 merge window (part I) Avi Kivity
2008-03-31 14:36 ` Avi Kivity [this message]
2008-03-31 14:36 ` [PATCH 02/40] KVM: MMU: Simplify hash table indexing Avi Kivity
2008-03-31 14:36 ` [PATCH 03/40] KVM: x86 emulator: add support for group decoding Avi Kivity
2008-03-31 14:36 ` [PATCH 04/40] KVM: x86 emulator: group decoding for group 1A Avi Kivity
2008-03-31 14:36 ` [PATCH 05/40] KVM: x86 emulator: Group decoding for group 3 Avi Kivity
2008-03-31 14:36 ` [PATCH 06/40] KVM: x86 emulator: Group decoding for groups 4 and 5 Avi Kivity
2008-03-31 14:36 ` [PATCH 07/40] KVM: x86 emulator: add group 7 decoding Avi Kivity
2008-03-31 14:36 ` [PATCH 08/40] KVM: constify function pointer tables Avi Kivity
2008-03-31 14:36 ` [PATCH 09/40] KVM: Only x86 has pio Avi Kivity
2008-03-31 14:36 ` [PATCH 10/40] KVM: x86 emulator: group decoding for group 1 instructions Avi Kivity
2008-03-31 14:36 ` [PATCH 11/40] KVM: MMU: Decouple mmio from shadow page tables Avi Kivity
2008-03-31 14:36 ` [PATCH 12/40] KVM: Limit vcpu mmap size to one page on non-x86 Avi Kivity
2008-03-31 14:36 ` [PATCH 13/40] KVM: VMX: Enable Virtual Processor Identification (VPID) Avi Kivity
2008-03-31 14:36 ` [PATCH 14/40] KVM: Use CONFIG_PREEMPT_NOTIFIERS around struct preempt_notifier Avi Kivity
2008-03-31 14:36 ` [PATCH 15/40] KVM: Disable pagefaults during copy_from_user_inatomic() Avi Kivity
2008-03-31 14:37 ` [PATCH 16/40] KVM: make EFER_RESERVED_BITS configurable for architecture code Avi Kivity
2008-03-31 14:37 ` [PATCH 17/40] KVM: align valid EFER bits with the features of the host system Avi Kivity
2008-03-31 14:37 ` [PATCH 18/40] KVM: VMX: unifdef the EFER specific code Avi Kivity
2008-03-31 14:37 ` [PATCH 19/40] KVM: allow access to EFER in 32bit KVM Avi Kivity
2008-03-31 14:37 ` [PATCH 20/40] KVM: SVM: move feature detection to hardware setup code Avi Kivity
2008-03-31 14:37 ` [PATCH 21/40] KVM: SVM: add detection of Nested Paging feature Avi Kivity
2008-03-31 14:37 ` [PATCH 22/40] KVM: SVM: add module parameter to disable Nested Paging Avi Kivity
2008-03-31 14:37 ` [PATCH 23/40] KVM: export information about NPT to generic x86 code Avi Kivity
2008-03-31 14:37 ` [PATCH 24/40] KVM: MMU: make the __nonpaging_map function generic Avi Kivity
2008-03-31 14:37 ` [PATCH 25/40] KVM: export the load_pdptrs() function to modules Avi Kivity
2008-03-31 14:37 ` [PATCH 26/40] KVM: MMU: add TDP support to the KVM MMU Avi Kivity
2008-03-31 14:37 ` [PATCH 27/40] KVM: SVM: add support for Nested Paging Avi Kivity
2008-03-31 14:37 ` [PATCH 28/40] KVM: VMX: fix typo in VMX header define Avi Kivity
2008-03-31 14:37 ` [PATCH 29/40] KVM: SVM: let init_vmcb() take struct vcpu_svm as parameter Avi Kivity
2008-03-31 14:37 ` [PATCH 30/40] KVM: SVM: allocate the MSR permission map per VCPU Avi Kivity
2008-03-31 14:37 ` [PATCH 31/40] KVM: SVM: enable LBR virtualization Avi Kivity
2008-03-31 14:37 ` [PATCH 32/40] KVM: paravirtualized clocksource: host part Avi Kivity
2008-03-31 14:37 ` [PATCH 33/40] x86: KVM guest: paravirtualized clocksource Avi Kivity
2008-03-31 14:37 ` [PATCH 34/40] KVM: x86 emulator: add ad_mask static inline Avi Kivity
2008-03-31 14:37 ` [PATCH 35/40] KVM: x86 emulator: make register_address, address_mask static inlines Avi Kivity
2008-03-31 14:37 ` [PATCH 36/40] KVM: x86 emulator: make register_address_increment and JMP_REL " Avi Kivity
2008-03-31 14:37 ` [PATCH 37/40] KVM: Add API to retrieve the number of supported vcpus per vm Avi Kivity
2008-03-31 14:37 ` [PATCH 38/40] KVM: Increase vcpu count to 16 Avi Kivity
2008-03-31 14:37 ` [PATCH 39/40] KVM: Add API for determining the number of supported memory slots Avi Kivity
2008-03-31 14:37 ` [PATCH 40/40] KVM: Increase the number of user memory slots per vm Avi Kivity

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=1206974244-9716-2-git-send-email-avi@qumranet.com \
    --to=avi@qumranet.com \
    --cc=eddie.dong@intel.com \
    --cc=kvm-devel@lists.sourceforge.net \
    --cc=linux-kernel@vger.kernel.org \
    /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

all inboxes | Powered by JetHome®