public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
From: Avi Kivity <avi-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
To: kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
Cc: Avi Kivity <avi-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
Subject: [PATCH 6/7] KVM: Move tpr threshold calculation into common code
Date: Tue,  4 Dec 2007 11:44:13 +0200	[thread overview]
Message-ID: <11967614551161-git-send-email-avi@qumranet.com> (raw)
In-Reply-To: <11967614542283-git-send-email-avi-atKUWr5tajBWk0Htik3J/w@public.gmane.org>

This moves the tpr shadow processing into the local apic code from the vmx
interrupt injection path.  This will allow decoupling the irq injection path
from normal execution (which needs to update the tpr threshold even when no
irq is being injected).

Signed-off-by: Avi Kivity <avi-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
---
 drivers/kvm/irq.c      |    6 ++++--
 drivers/kvm/irq.h      |    8 +++++---
 drivers/kvm/kvm_main.c |    3 ++-
 drivers/kvm/lapic.c    |   17 ++++++++++++-----
 drivers/kvm/svm.c      |    3 ++-
 drivers/kvm/vmx.c      |   19 ++++++-------------
 6 files changed, 31 insertions(+), 25 deletions(-)

diff --git a/drivers/kvm/irq.c b/drivers/kvm/irq.c
index 66d1a91..8a95eef 100644
--- a/drivers/kvm/irq.c
+++ b/drivers/kvm/irq.c
@@ -28,9 +28,11 @@
 /*
  * Read pending interrupt vector and intack.
  */
-bool kvm_cpu_get_interrupt(struct kvm_vcpu *v, struct kvm_pending_irq *irq)
+bool kvm_cpu_get_interrupt(struct kvm_vcpu *v, struct kvm_pending_irq *irq,
+			   unsigned *tpr_threshold)
 {
-	if (kvm_get_apic_interrupt(v, irq))
+	*tpr_threshold = 0;
+	if (kvm_get_apic_interrupt(v, irq, tpr_threshold))
 		return true;
 	if (kvm_apic_accept_pic_intr(v))
 		return kvm_pic_read_irq(pic_irqchip(v->kvm), irq);
diff --git a/drivers/kvm/irq.h b/drivers/kvm/irq.h
index 49af30b..c12734d 100644
--- a/drivers/kvm/irq.h
+++ b/drivers/kvm/irq.h
@@ -63,7 +63,8 @@ struct kvm_pic {
 struct kvm_pic *kvm_create_pic(struct kvm *kvm);
 void kvm_pic_set_irq(void *opaque, int irq, int level);
 bool kvm_pic_read_irq(struct kvm_pic *s, struct kvm_pending_irq *irq);
-bool kvm_cpu_get_interrupt(struct kvm_vcpu *v, struct kvm_pending_irq *irq);
+bool kvm_cpu_get_interrupt(struct kvm_vcpu *v, struct kvm_pending_irq *irq,
+			   unsigned *tpr_threshold);
 void kvm_pic_update_irq(struct kvm_pic *s);
 
 #define IOAPIC_NUM_PINS  KVM_IOAPIC_NUM_PINS
@@ -147,9 +148,10 @@ do {									\
 #endif
 
 void kvm_vcpu_kick(struct kvm_vcpu *vcpu);
-int kvm_apic_has_interrupt(struct kvm_vcpu *vcpu);
+int kvm_apic_has_interrupt(struct kvm_vcpu *vcpu, unsigned *tpr_threshold);
 int kvm_apic_accept_pic_intr(struct kvm_vcpu *vcpu);
-bool kvm_get_apic_interrupt(struct kvm_vcpu *vcpu, struct kvm_pending_irq *irq);
+bool kvm_get_apic_interrupt(struct kvm_vcpu *vcpu, struct kvm_pending_irq *irq,
+			    unsigned *tpr_threshold);
 int kvm_create_lapic(struct kvm_vcpu *vcpu);
 void kvm_lapic_reset(struct kvm_vcpu *vcpu);
 void kvm_pic_reset(struct kvm_kpic_state *s);
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index 41658d7..7cc4508 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -638,13 +638,14 @@ void kvm_vcpu_block(struct kvm_vcpu *vcpu)
 {
 	DECLARE_WAITQUEUE(wait, current);
 	struct kvm_pending_irq irq;
+	unsigned tpr_threshold;
 
 	add_wait_queue(&vcpu->wq, &wait);
 
 	/*
 	 * We will block until either an interrupt or a signal wakes us up
 	 */
-	while (!kvm_cpu_get_interrupt(vcpu, &irq)
+	while (!kvm_cpu_get_interrupt(vcpu, &irq, &tpr_threshold)
 	       && !signal_pending(current)
 	       && vcpu->mp_state != VCPU_MP_STATE_RUNNABLE
 	       && vcpu->mp_state != VCPU_MP_STATE_SIPI_RECEIVED) {
diff --git a/drivers/kvm/lapic.c b/drivers/kvm/lapic.c
index 804a177..f2168d4 100644
--- a/drivers/kvm/lapic.c
+++ b/drivers/kvm/lapic.c
@@ -992,19 +992,25 @@ nomem:
 }
 EXPORT_SYMBOL_GPL(kvm_create_lapic);
 
-int kvm_apic_has_interrupt(struct kvm_vcpu *vcpu)
+int kvm_apic_has_interrupt(struct kvm_vcpu *vcpu, unsigned *tpr_threshold)
 {
 	struct kvm_lapic *apic = vcpu->apic;
 	int highest_irr;
+	unsigned tpr;
 
 	if (!apic || !apic_enabled(apic))
 		return -1;
 
 	apic_update_ppr(apic);
 	highest_irr = apic_find_highest_irr(apic);
-	if ((highest_irr == -1) ||
-	    ((highest_irr & 0xF0) <= apic_get_reg(apic, APIC_PROCPRI)))
+	if (highest_irr == -1)
 		return -1;
+	if ((highest_irr & 0xF0) <= apic_get_reg(apic, APIC_PROCPRI)) {
+		tpr = apic_get_reg(apic, APIC_TASKPRI) & 0xff;
+		if ((highest_irr & 0xF0) < tpr)
+			*tpr_threshold = highest_irr & 0xF0;
+		return -1;
+	}
 	return highest_irr;
 }
 
@@ -1053,9 +1059,10 @@ static void kvm_apic_ack_interrupt(struct kvm_vcpu *vcpu, unsigned vector)
 	apic_clear_irr(vector, apic);
 }
 
-bool kvm_get_apic_interrupt(struct kvm_vcpu *vcpu, struct kvm_pending_irq *irq)
+bool kvm_get_apic_interrupt(struct kvm_vcpu *vcpu, struct kvm_pending_irq *irq,
+			    unsigned *tpr_threshold)
 {
-	int vector = kvm_apic_has_interrupt(vcpu);
+	int vector = kvm_apic_has_interrupt(vcpu, tpr_threshold);
 
 	if (vector == -1)
 		return false;
diff --git a/drivers/kvm/svm.c b/drivers/kvm/svm.c
index 155b266..10146a8 100644
--- a/drivers/kvm/svm.c
+++ b/drivers/kvm/svm.c
@@ -1317,6 +1317,7 @@ static void svm_intr_assist(struct kvm_vcpu *vcpu)
 	struct vmcb *vmcb = svm->vmcb;
 	int intr_vector = -1;
 	struct kvm_pending_irq irq;
+	unsigned tpr_threshold;
 
 	if ((vmcb->control.exit_int_info & SVM_EVTINJ_VALID) &&
 	    ((vmcb->control.exit_int_info & SVM_EVTINJ_TYPE_MASK) == 0)) {
@@ -1330,7 +1331,7 @@ static void svm_intr_assist(struct kvm_vcpu *vcpu)
 	if (vmcb->control.int_ctl & V_IRQ_MASK)
 		return;
 
-	if (!kvm_cpu_get_interrupt(vcpu, &irq))
+	if (!kvm_cpu_get_interrupt(vcpu, &irq, &tpr_threshold))
 		return;
 
 	if (!(vmcb->save.rflags & X86_EFLAGS_IF) ||
diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c
index ed14849..b788c6b 100644
--- a/drivers/kvm/vmx.c
+++ b/drivers/kvm/vmx.c
@@ -2218,21 +2218,12 @@ static void vmx_flush_tlb(struct kvm_vcpu *vcpu)
 {
 }
 
-static void update_tpr_threshold(struct kvm_vcpu *vcpu)
+static void update_tpr_threshold(struct kvm_vcpu *vcpu, unsigned tpr_threshold)
 {
-	int max_irr, tpr;
-
 	if (!vm_need_tpr_shadow(vcpu->kvm))
 		return;
 
-	if (!kvm_lapic_enabled(vcpu) ||
-	    ((max_irr = kvm_lapic_find_highest_irr(vcpu)) == -1)) {
-		vmcs_write32(TPR_THRESHOLD, 0);
-		return;
-	}
-
-	tpr = (kvm_lapic_get_cr8(vcpu) & 0x0f) << 4;
-	vmcs_write32(TPR_THRESHOLD, (max_irr > tpr) ? tpr >> 4 : max_irr >> 4);
+	vmcs_write32(TPR_THRESHOLD, tpr_threshold >> 4);
 }
 
 static void enable_irq_window(struct kvm_vcpu *vcpu)
@@ -2251,10 +2242,12 @@ static void vmx_intr_assist(struct kvm_vcpu *vcpu)
 	int has_ext_irq, interrupt_window_open;
 	struct kvm_pending_irq irq;
 	int vector;
+	unsigned tpr_threshold;
+
+	has_ext_irq = kvm_cpu_get_interrupt(vcpu, &irq, &tpr_threshold);
 
-	update_tpr_threshold(vcpu);
+	update_tpr_threshold(vcpu, tpr_threshold);
 
-	has_ext_irq = kvm_cpu_get_interrupt(vcpu, &irq);
 	intr_info_field = vmcs_read32(VM_ENTRY_INTR_INFO_FIELD);
 	idtv_info_field = vmx->idt_vectoring_info;
 	if (intr_info_field & INTR_INFO_VALID_MASK) {
-- 
1.5.3


-------------------------------------------------------------------------
SF.Net email is sponsored by: The Future of Linux Business White Paper
from Novell.  From the desktop to the data center, Linux is going
mainstream.  Let it simplify your IT future.
http://altfarm.mediaplex.com/ad/ck/8857-50307-18918-4

  parent reply	other threads:[~2007-12-04  9:44 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-12-04  9:44 [PATCH 0/7] Rework irq injection infrastructure Avi Kivity
     [not found] ` <11967614542283-git-send-email-avi-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-12-04  9:44   ` [PATCH 1/7] KVM: Generalize exception injection mechanism Avi Kivity
2007-12-04  9:44   ` [PATCH 2/7] KVM: Replace page fault injection by the generalized exception queue Avi Kivity
2007-12-04  9:44   ` [PATCH 3/7] KVM: Replace #GP " Avi Kivity
2007-12-04  9:44   ` [PATCH 4/7] KVM: Use generalized exception queue for injecting #UD Avi Kivity
2007-12-04  9:44   ` [PATCH 5/7] KVM: Add explicit acks to interrupt controller model Avi Kivity
2007-12-04  9:44   ` Avi Kivity [this message]
2007-12-04  9:44   ` [PATCH 7/7] KVM: Ack interrupts only after they have successfully been injected Avi Kivity
2007-12-04 16:51   ` [PATCH 0/7] Rework irq injection infrastructure Joerg Roedel
     [not found]     ` <20071204165101.GA23093-5C7GfCeVMHo@public.gmane.org>
2007-12-04 16:56       ` Avi Kivity
2007-12-06  7:50   ` Dong, Eddie
     [not found]     ` <10EA09EFD8728347A513008B6B0DA77A0279CC10-wq7ZOvIWXbNpB2pF5aRoyrfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2007-12-06  8:28       ` Avi Kivity
     [not found]         ` <4757B2C3.3000402-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-12-06  9:33           ` Dong, Eddie
     [not found]             ` <10EA09EFD8728347A513008B6B0DA77A0279CCE0-wq7ZOvIWXbNpB2pF5aRoyrfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2007-12-06 10:10               ` Avi Kivity
     [not found]                 ` <4757CA93.1090704-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-12-06 10:26                   ` Dong, Eddie
     [not found]                     ` <10EA09EFD8728347A513008B6B0DA77A0279CCF2-wq7ZOvIWXbNpB2pF5aRoyrfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2007-12-06 13:24                       ` Dong, Eddie
     [not found]                         ` <10EA09EFD8728347A513008B6B0DA77A0279CD1C-wq7ZOvIWXbNpB2pF5aRoyrfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2007-12-06 14:19                           ` 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=11967614551161-git-send-email-avi@qumranet.com \
    --to=avi-atkuwr5tajbwk0htik3j/w@public.gmane.org \
    --cc=kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.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