public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Xiao Guangrong <xiaoguangrong@linux.vnet.ibm.com>
To: Xiao Guangrong <xiaoguangrong@linux.vnet.ibm.com>
Cc: Avi Kivity <avi@redhat.com>,
	Marcelo Tosatti <mtosatti@redhat.com>,
	LKML <linux-kernel@vger.kernel.org>, KVM <kvm@vger.kernel.org>
Subject: [PATCH v2 08/16] KVM: MMU: store more bits in rmap
Date: Fri, 13 Apr 2012 18:13:10 +0800	[thread overview]
Message-ID: <4F87FC36.20307@linux.vnet.ibm.com> (raw)
In-Reply-To: <4F87FA69.5060106@linux.vnet.ibm.com>

In current code, only one bit (bit 0) is used in rmap, this patch
export more bits from rmap, during spte add/remove, only bit 0 is
touched and other bits are keeped

Signed-off-by: Xiao Guangrong <xiaoguangrong@linux.vnet.ibm.com>
---
 arch/x86/kvm/mmu.c |  138 ++++++++++++++++++++++++++++++++--------------------
 1 files changed, 85 insertions(+), 53 deletions(-)

diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index 4e91e94..53e92de 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -796,13 +796,24 @@ static int mapping_level(struct kvm_vcpu *vcpu, gfn_t large_gfn)
 	return level - 1;
 }

+#define PTE_LIST_DESC		(0x1ull)
+#define PTE_LIST_FLAG_MASK	(0x3ull)
+
+static void
+pte_list_decode(const unsigned long *pte_list, unsigned long *map,
+		unsigned long *flags)
+{
+	*map = *pte_list & (~PTE_LIST_FLAG_MASK);
+	*flags = *pte_list & PTE_LIST_FLAG_MASK;
+}
+
 /*
  * Pte mapping structures:
  *
- * If pte_list bit zero is zero, then pte_list point to the spte.
+ * If PTE_LIST_DESC bit is zero, then pte_list point to the spte.
  *
- * If pte_list bit zero is one, (then pte_list & ~1) points to a struct
- * pte_list_desc containing more mappings.
+ * If PTE_LIST_DESC bit is one, (then pte_list & ~PTE_LIST_FLAG_MASK) points
+ * to a struct pte_list_desc containing more mappings.
  *
  * Returns the number of pte entries before the spte was added or zero if
  * the spte was not added.
@@ -812,39 +823,52 @@ static int pte_list_add(struct kvm_vcpu *vcpu, u64 *spte,
 			unsigned long *pte_list)
 {
 	struct pte_list_desc *desc;
+	unsigned long map, flags;
 	int i, count = 0;

-	if (!*pte_list) {
+	pte_list_decode(pte_list, &map, &flags);
+
+	if (!map) {
 		rmap_printk("pte_list_add: %p %llx 0->1\n", spte, *spte);
-		*pte_list = (unsigned long)spte;
-	} else if (!(*pte_list & 1)) {
+		WARN_ON(flags & PTE_LIST_DESC);
+		*pte_list = (unsigned long)spte | flags;
+
+		 return 0;
+	}
+
+	if (!(flags & PTE_LIST_DESC)) {
 		rmap_printk("pte_list_add: %p %llx 1->many\n", spte, *spte);
 		desc = mmu_alloc_pte_list_desc(vcpu);
-		desc->sptes[0] = (u64 *)*pte_list;
+		desc->sptes[0] = (u64 *)map;
 		desc->sptes[1] = spte;
-		*pte_list = (unsigned long)desc | 1;
-		++count;
-	} else {
-		rmap_printk("pte_list_add: %p %llx many->many\n", spte, *spte);
-		desc = (struct pte_list_desc *)(*pte_list & ~1ul);
-		while (desc->sptes[PTE_LIST_EXT-1] && desc->more) {
-			desc = desc->more;
-			count += PTE_LIST_EXT;
-		}
-		if (desc->sptes[PTE_LIST_EXT-1]) {
-			desc->more = mmu_alloc_pte_list_desc(vcpu);
-			desc = desc->more;
-		}
-		for (i = 0; desc->sptes[i]; ++i)
-			++count;
-		desc->sptes[i] = spte;
+		*pte_list = (unsigned long)desc | flags | PTE_LIST_DESC;
+
+		return 1;
+	}
+
+	rmap_printk("pte_list_add: %p %llx many->many\n", spte, *spte);
+	desc = (struct pte_list_desc *)map;
+	while (desc->sptes[PTE_LIST_EXT - 1] && desc->more) {
+		desc = desc->more;
+		count += PTE_LIST_EXT;
 	}
+
+	if (desc->sptes[PTE_LIST_EXT - 1]) {
+		desc->more = mmu_alloc_pte_list_desc(vcpu);
+		desc = desc->more;
+	}
+
+	for (i = 0; desc->sptes[i]; ++i)
+		++count;
+	desc->sptes[i] = spte;
+
 	return count;
 }

 static void
 pte_list_desc_remove_entry(unsigned long *pte_list, struct pte_list_desc *desc,
-			   int i, struct pte_list_desc *prev_desc)
+			   int i, struct pte_list_desc *prev_desc,
+			   unsigned long flags)
 {
 	int j;

@@ -855,12 +879,13 @@ pte_list_desc_remove_entry(unsigned long *pte_list, struct pte_list_desc *desc,
 	if (j != 0)
 		return;
 	if (!prev_desc && !desc->more)
-		*pte_list = (unsigned long)desc->sptes[0];
+		*pte_list = (unsigned long)desc->sptes[0] |
+					(flags & (~PTE_LIST_DESC)) ;
 	else
 		if (prev_desc)
 			prev_desc->more = desc->more;
 		else
-			*pte_list = (unsigned long)desc->more | 1;
+			*pte_list = (unsigned long)desc->more | flags;
 	mmu_free_pte_list_desc(desc);
 }

@@ -868,36 +893,42 @@ static void pte_list_remove(u64 *spte, unsigned long *pte_list)
 {
 	struct pte_list_desc *desc;
 	struct pte_list_desc *prev_desc;
+	unsigned long map, flags;
 	int i;

-	if (!*pte_list) {
+	pte_list_decode(pte_list, &map, &flags);
+
+	if (!map) {
 		printk(KERN_ERR "pte_list_remove: %p 0->BUG\n", spte);
 		BUG();
-	} else if (!(*pte_list & 1)) {
+		return;
+	}
+
+	if (!(flags & PTE_LIST_DESC)) {
 		rmap_printk("pte_list_remove:  %p 1->0\n", spte);
-		if ((u64 *)*pte_list != spte) {
+		if ((u64 *)map != spte) {
 			printk(KERN_ERR "pte_list_remove:  %p 1->BUG\n", spte);
 			BUG();
 		}
-		*pte_list = 0;
-	} else {
-		rmap_printk("pte_list_remove:  %p many->many\n", spte);
-		desc = (struct pte_list_desc *)(*pte_list & ~1ul);
-		prev_desc = NULL;
-		while (desc) {
-			for (i = 0; i < PTE_LIST_EXT && desc->sptes[i]; ++i)
-				if (desc->sptes[i] == spte) {
-					pte_list_desc_remove_entry(pte_list,
-							       desc, i,
-							       prev_desc);
-					return;
-				}
-			prev_desc = desc;
-			desc = desc->more;
-		}
-		pr_err("pte_list_remove: %p many->many\n", spte);
-		BUG();
+		*pte_list = flags;
+		return;
+	}
+
+	rmap_printk("pte_list_remove:  %p many->many\n", spte);
+	desc = (struct pte_list_desc *)map;
+	prev_desc = NULL;
+	while (desc) {
+		for (i = 0; i < PTE_LIST_EXT && desc->sptes[i]; ++i)
+			if (desc->sptes[i] == spte) {
+				pte_list_desc_remove_entry(pte_list,
+						desc, i, prev_desc, flags);
+				return;
+			}
+		prev_desc = desc;
+		desc = desc->more;
 	}
+	pr_err("pte_list_remove: %p many->many\n", spte);
+	BUG();
 }

 /*
@@ -932,21 +963,22 @@ static void pte_list_walk_check_restart(struct spte_iterator *iter, u64 *spte)

 static u64 *pte_list_first(struct spte_iterator *iter)
 {
-	unsigned long pte_list = *iter->pte_list;
+	unsigned long map, flags;
 	u64 *sptep;

-	if (!pte_list)
+	pte_list_decode(iter->pte_list, &map, &flags);
+
+	if (!map)
 		return NULL;

-	if (!(pte_list & 1)) {
+	if (!(flags & PTE_LIST_DESC)) {
 		iter->desc = NULL;
 		iter->pos = 0;
-		sptep = (u64 *)pte_list;
-
+		sptep = (u64 *)map;
 		goto exit;
 	}

-	iter->desc = (struct pte_list_desc *)(pte_list & ~1ul);
+	iter->desc = (struct pte_list_desc *)map;
 	iter->pos = 0;
 	sptep = iter->desc->sptes[iter->pos];

-- 
1.7.7.6


  parent reply	other threads:[~2012-04-13 10:13 UTC|newest]

Thread overview: 49+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-04-13 10:05 [PATCH v2 00/16] KVM: MMU: fast page fault Xiao Guangrong
2012-04-13 10:09 ` [PATCH v2 01/16] KVM: MMU: cleanup __direct_map Xiao Guangrong
2012-04-13 10:10 ` [PATCH v2 02/16] KVM: MMU: introduce mmu_spte_establish Xiao Guangrong
2012-04-13 10:10 ` [PATCH v2 03/16] KVM: MMU: properly assert spte on rmap walking path Xiao Guangrong
2012-04-14  2:15   ` Takuya Yoshikawa
2012-04-16  3:26     ` Xiao Guangrong
2012-04-13 10:11 ` [PATCH v2 04/16] KVM: MMU: return bool in __rmap_write_protect Xiao Guangrong
2012-04-14  2:00   ` Takuya Yoshikawa
2012-04-15 11:25     ` Avi Kivity
2012-04-16 14:14       ` Takuya Yoshikawa
2012-04-16 14:28         ` Avi Kivity
2012-04-16 15:54           ` Takuya Yoshikawa
2012-04-13 10:11 ` [PATCH v2 05/16] KVM: MMU: abstract spte write-protect Xiao Guangrong
2012-04-14  2:26   ` Takuya Yoshikawa
2012-04-16  3:27     ` Xiao Guangrong
2012-04-13 10:12 ` [PATCH v2 06/16] KVM: VMX: export PFEC.P bit on ept Xiao Guangrong
2012-04-13 10:12 ` [PATCH v2 07/16] KVM: MMU: introduce for_each_pte_list_spte Xiao Guangrong
2012-04-14  2:44   ` Takuya Yoshikawa
2012-04-16  3:36     ` Xiao Guangrong
2012-04-17 14:47       ` Takuya Yoshikawa
2012-04-18  4:01         ` Xiao Guangrong
2012-04-21  1:01           ` Takuya Yoshikawa
2012-04-21  4:36             ` Xiao Guangrong
2012-04-18 10:03         ` Xiao Guangrong
2012-04-21  1:03           ` Takuya Yoshikawa
2012-04-13 10:13 ` Xiao Guangrong [this message]
2012-04-13 10:13 ` [PATCH v2 09/16] KVM: MMU: fast mmu_need_write_protect path for hard mmu Xiao Guangrong
2012-04-13 10:14 ` [PATCH v2 10/16] KVM: MMU: fask check whether page is writable Xiao Guangrong
2012-04-14  3:01   ` Takuya Yoshikawa
2012-04-16  3:38     ` Xiao Guangrong
2012-04-15 15:16   ` Avi Kivity
2012-04-16  3:25     ` Xiao Guangrong
2012-04-16 10:02       ` Avi Kivity
2012-04-16 10:20         ` Xiao Guangrong
2012-04-16 11:47           ` Avi Kivity
2012-04-17  3:55             ` Xiao Guangrong
2012-04-17  7:41               ` Avi Kivity
2012-04-17 12:10                 ` Xiao Guangrong
2012-04-13 10:14 ` [PATCH v2 11/16] KVM: MMU: introduce SPTE_ALLOW_WRITE bit Xiao Guangrong
2012-04-13 10:15 ` [PATCH v2 12/16] KVM: MMU: introduce SPTE_WRITE_PROTECT bit Xiao Guangrong
2012-04-13 10:15 ` [PATCH v2 13/16] KVM: MMU: break sptes write-protect if gfn is writable Xiao Guangrong
2012-04-13 10:16 ` [PATCH v2 14/16] KVM: MMU: fast path of handling guest page fault Xiao Guangrong
2012-04-18  1:47   ` Marcelo Tosatti
2012-04-18  3:53     ` Xiao Guangrong
2012-04-18 23:08       ` Marcelo Tosatti
2012-04-13 10:17 ` [PATCH v2 15/16] KVM: MMU: trace fast " Xiao Guangrong
2012-04-13 10:17 ` [PATCH v2 16/16] KVM: MMU: fix kvm_mmu_pagetable_walk tracepoint Xiao Guangrong
2012-04-14  3:37 ` [PATCH v2 00/16] KVM: MMU: fast page fault Takuya Yoshikawa
2012-04-16  3:50   ` Xiao Guangrong

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=4F87FC36.20307@linux.vnet.ibm.com \
    --to=xiaoguangrong@linux.vnet.ibm.com \
    --cc=avi@redhat.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mtosatti@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox