public inbox for kvm-ppc@vger.kernel.org
 help / color / mirror / Atom feed
From: Alexander Graf <agraf@suse.de>
To: kvm-ppc <kvm-ppc@vger.kernel.org>
Cc: kvm list <kvm@vger.kernel.org>, Avi Kivity <avi@redhat.com>,
	Bharat Bhushan <r65777@freescale.com>,
	Bharat Bhushan <bharat.bhushan@freescale.com>
Subject: [PATCH 01/16] KVM: Use minimum and maximum address mapped by TLB1
Date: Sun, 06 May 2012 14:20:45 +0000	[thread overview]
Message-ID: <1336314060-32640-2-git-send-email-agraf@suse.de> (raw)
In-Reply-To: <1336314060-32640-1-git-send-email-agraf@suse.de>

From: Bharat Bhushan <r65777@freescale.com>

Keep track of minimum and maximum address mapped by tlb1.
This helps in TLBMISS handling in KVM to quick check whether the address lies in mapped range.
If address does not lies in this range then no need to look in each tlb1 entry of tlb1 array.

Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 arch/powerpc/kvm/e500.h     |    4 ++
 arch/powerpc/kvm/e500_tlb.c |   88 ++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 90 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/kvm/e500.h b/arch/powerpc/kvm/e500.h
index 7967f3f..aa8b814 100644
--- a/arch/powerpc/kvm/e500.h
+++ b/arch/powerpc/kvm/e500.h
@@ -89,6 +89,10 @@ struct kvmppc_vcpu_e500 {
 	u64 *g2h_tlb1_map;
 	unsigned int *h2g_tlb1_rmap;
 
+	/* Minimum and maximum address mapped my TLB1 */
+	unsigned long tlb1_min_eaddr;
+	unsigned long tlb1_max_eaddr;
+
 #ifdef CONFIG_KVM_E500V2
 	u32 pid[E500_PID_NUM];
 
diff --git a/arch/powerpc/kvm/e500_tlb.c b/arch/powerpc/kvm/e500_tlb.c
index e05232b..c510fc9 100644
--- a/arch/powerpc/kvm/e500_tlb.c
+++ b/arch/powerpc/kvm/e500_tlb.c
@@ -261,6 +261,9 @@ static int kvmppc_e500_tlb_index(struct kvmppc_vcpu_e500 *vcpu_e500,
 		set_base = gtlb0_set_base(vcpu_e500, eaddr);
 		size = vcpu_e500->gtlb_params[0].ways;
 	} else {
+		if (eaddr < vcpu_e500->tlb1_min_eaddr ||
+				eaddr > vcpu_e500->tlb1_max_eaddr)
+			return -1;
 		set_base = 0;
 	}
 
@@ -583,6 +586,65 @@ static int kvmppc_e500_tlb1_map(struct kvmppc_vcpu_e500 *vcpu_e500,
 	return victim;
 }
 
+static void kvmppc_recalc_tlb1map_range(struct kvmppc_vcpu_e500 *vcpu_e500)
+{
+	int size = vcpu_e500->gtlb_params[1].entries;
+	unsigned int offset;
+	gva_t eaddr;
+	int i;
+
+	vcpu_e500->tlb1_min_eaddr = ~0UL;
+	vcpu_e500->tlb1_max_eaddr = 0;
+	offset = vcpu_e500->gtlb_offset[1];
+
+	for (i = 0; i < size; i++) {
+		struct kvm_book3e_206_tlb_entry *tlbe +			&vcpu_e500->gtlb_arch[offset + i];
+
+		if (!get_tlb_v(tlbe))
+			continue;
+
+		eaddr = get_tlb_eaddr(tlbe);
+		vcpu_e500->tlb1_min_eaddr +				min(vcpu_e500->tlb1_min_eaddr, eaddr);
+
+		eaddr = get_tlb_end(tlbe);
+		vcpu_e500->tlb1_max_eaddr +				max(vcpu_e500->tlb1_max_eaddr, eaddr);
+	}
+}
+
+static int kvmppc_need_recalc_tlb1map_range(struct kvmppc_vcpu_e500 *vcpu_e500,
+				struct kvm_book3e_206_tlb_entry *gtlbe)
+{
+	unsigned long start, end, size;
+
+	size = get_tlb_bytes(gtlbe);
+	start = get_tlb_eaddr(gtlbe) & ~(size - 1);
+	end = start + size - 1;
+
+	return vcpu_e500->tlb1_min_eaddr = start ||
+			vcpu_e500->tlb1_max_eaddr = end;
+}
+
+/* This function is supposed to be called for a adding a new valid tlb entry */
+static void kvmppc_set_tlb1map_range(struct kvm_vcpu *vcpu,
+				struct kvm_book3e_206_tlb_entry *gtlbe)
+{
+	unsigned long start, end, size;
+	struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
+
+	if (!get_tlb_v(gtlbe))
+		return;
+
+	size = get_tlb_bytes(gtlbe);
+	start = get_tlb_eaddr(gtlbe) & ~(size - 1);
+	end = start + size - 1;
+
+	vcpu_e500->tlb1_min_eaddr = min(vcpu_e500->tlb1_min_eaddr, start);
+	vcpu_e500->tlb1_max_eaddr = max(vcpu_e500->tlb1_max_eaddr, end);
+}
+
 static inline int kvmppc_e500_gtlbe_invalidate(
 				struct kvmppc_vcpu_e500 *vcpu_e500,
 				int tlbsel, int esel)
@@ -593,6 +655,9 @@ static inline int kvmppc_e500_gtlbe_invalidate(
 	if (unlikely(get_tlb_iprot(gtlbe)))
 		return -1;
 
+	if (tlbsel = 1 && kvmppc_need_recalc_tlb1map_range(vcpu_e500, gtlbe))
+		kvmppc_recalc_tlb1map_range(vcpu_e500);
+
 	gtlbe->mas1 = 0;
 
 	return 0;
@@ -792,14 +857,19 @@ int kvmppc_e500_emul_tlbwe(struct kvm_vcpu *vcpu)
 	struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
 	struct kvm_book3e_206_tlb_entry *gtlbe, stlbe;
 	int tlbsel, esel, stlbsel, sesel;
+	int recal = 0;
 
 	tlbsel = get_tlb_tlbsel(vcpu);
 	esel = get_tlb_esel(vcpu, tlbsel);
 
 	gtlbe = get_entry(vcpu_e500, tlbsel, esel);
 
-	if (get_tlb_v(gtlbe))
+	if (get_tlb_v(gtlbe)) {
 		inval_gtlbe_on_host(vcpu_e500, tlbsel, esel);
+		if ((tlbsel = 1) &&
+			kvmppc_need_recalc_tlb1map_range(vcpu_e500, gtlbe))
+			recal = 1;
+	}
 
 	gtlbe->mas1 = vcpu->arch.shared->mas1;
 	gtlbe->mas2 = vcpu->arch.shared->mas2;
@@ -808,6 +878,18 @@ int kvmppc_e500_emul_tlbwe(struct kvm_vcpu *vcpu)
 	trace_kvm_booke206_gtlb_write(vcpu->arch.shared->mas0, gtlbe->mas1,
 	                              gtlbe->mas2, gtlbe->mas7_3);
 
+	if (tlbsel = 1) {
+		/*
+		 * If a valid tlb1 entry is overwritten then recalculate the
+		 * min/max TLB1 map address range otherwise no need to look
+		 * in tlb1 array.
+		 */
+		if (recal)
+			kvmppc_recalc_tlb1map_range(vcpu_e500);
+		else
+			kvmppc_set_tlb1map_range(vcpu, gtlbe);
+	}
+
 	/* Invalidate shadow mappings for the about-to-be-clobbered TLBE. */
 	if (tlbe_is_host_safe(vcpu, gtlbe)) {
 		u64 eaddr;
@@ -1145,6 +1227,7 @@ int kvm_vcpu_ioctl_config_tlb(struct kvm_vcpu *vcpu,
 	vcpu_e500->gtlb_params[1].ways = params.tlb_sizes[1];
 	vcpu_e500->gtlb_params[1].sets = 1;
 
+	kvmppc_recalc_tlb1map_range(vcpu_e500);
 	return 0;
 
 err_put_page:
@@ -1163,7 +1246,7 @@ int kvm_vcpu_ioctl_dirty_tlb(struct kvm_vcpu *vcpu,
 			     struct kvm_dirty_tlb *dirty)
 {
 	struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
-
+	kvmppc_recalc_tlb1map_range(vcpu_e500);
 	clear_tlb_refs(vcpu_e500);
 	return 0;
 }
@@ -1272,6 +1355,7 @@ int kvmppc_e500_tlb_init(struct kvmppc_vcpu_e500 *vcpu_e500)
 	vcpu->arch.tlbcfg[1] | 		vcpu_e500->gtlb_params[1].ways << TLBnCFG_ASSOC_SHIFT;
 
+	kvmppc_recalc_tlb1map_range(vcpu_e500);
 	return 0;
 
 err:
-- 
1.6.0.2


  reply	other threads:[~2012-05-06 14:20 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-05-06 14:20 [PULL 00/16] ppc patch queue 2012-05-06 Alexander Graf
2012-05-06 14:20 ` Alexander Graf [this message]
2012-05-06 14:20 ` [PATCH 02/16] KVM: PPC: Use clockevent multiplier and shifter for decrementer Alexander Graf
2012-05-06 14:20 ` [PATCH 03/16] KVM: PPC: bookehv: Use a Macro for saving/restoring guest registers to/from their 64 b Alexander Graf
2012-05-06 14:20 ` [PATCH 04/16] KVM: PPC: Restrict PPC_[L|ST]D macro to asm code Alexander Graf
2012-05-06 14:20 ` [PATCH 05/16] KVM: PPC: booke(hv): Fix save/restore of guest accessible SPRGs Alexander Graf
2012-05-06 14:20 ` [PATCH 06/16] KVM: PPC: Book3S: PR: Optimize entry path Alexander Graf
2012-05-06 14:20 ` [PATCH 07/16] KVM: PPC: Book3S: PR: No isync in slbie path Alexander Graf
2012-05-06 14:20 ` [PATCH 08/16] KVM: PPC: bookehv: Use lwz/stw instead of PPC_LL/PPC_STL for 32-bit fields Alexander Graf
2012-05-06 14:20 ` [PATCH 09/16] KVM: PPC: Fix stbux emulation Alexander Graf
2012-05-06 14:20 ` [PATCH 10/16] KVM: PPC: Fix PR KVM on POWER7 bare metal Alexander Graf
2012-05-06 14:20 ` [PATCH 11/16] KVM: PPC: Book3S: Enable IRQs during exit handling Alexander Graf
2012-05-06 14:20 ` [PATCH 12/16] KVM: PPC: bookehv: Fix r8/r13 storing in level exception handler Alexander Graf
2012-05-06 14:20 ` [PATCH 13/16] kvm/book3s: Make kernel emulated H_PUT_TCE available for "PR" KVM Alexander Graf
2012-05-06 14:20 ` [PATCH 14/16] kvm/powerpc: Add new ioctl to retreive server MMU infos Alexander Graf
2012-05-06 14:20 ` [PATCH 15/16] KVM: PPC: Emulator: clean up instruction parsing Alexander Graf
2012-05-06 14:21 ` [PATCH 16/16] KVM: PPC: Emulator: clean up SPR reads and writes Alexander Graf
2012-05-08 14:01 ` [PULL 00/16] ppc patch queue 2012-05-06 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=1336314060-32640-2-git-send-email-agraf@suse.de \
    --to=agraf@suse.de \
    --cc=avi@redhat.com \
    --cc=bharat.bhushan@freescale.com \
    --cc=kvm-ppc@vger.kernel.org \
    --cc=kvm@vger.kernel.org \
    --cc=r65777@freescale.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