public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
From: Anthony Liguori <aliguori-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
To: kvm-devel
	<kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org>,
	Avi Kivity <avi-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
Subject: [PATCH] Lazy FPU for SVM
Date: Sun, 22 Apr 2007 21:56:08 -0500	[thread overview]
Message-ID: <462C2048.4040700@us.ibm.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 683 bytes --]

Attached patch implements lazy FPU save/restore for SVM.  It's much more 
conservative than my previous patch.  We can now mark the guest FPU as 
inactive whenever we want which will trigger CR0.TS to be set in the 
guest's shadowed CR0.

Right now, we only mark the FPU as inactive when the guest does (via a 
mov %cr0, clts, etc.) or during a mov %cr3.  There may be a better 
heuristic out there but this seemed like the obvious one.

I'm still playing around with the VT version of this patch so I'll post 
that tomorrow.

I've tested on a 32bit and 64bit SVM host using Avi's previously posted 
fpu-test and some others.  Everything seems to be fine.

Regards,

Anthony Liguori

[-- Attachment #2: kvm-svm-lazy-fpu.diff --]
[-- Type: text/x-patch, Size: 3774 bytes --]

Author: Anthony Liguori <aliguori-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
Date:   Sun Apr 22 20:34:03 2007 -0500

    Lazy FPU support for SVM.
    
    Signed-off-by: Anthony Liguori <aliguori-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>

diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
index d1a90c5..4859c32 100644
--- a/drivers/kvm/kvm.h
+++ b/drivers/kvm/kvm.h
@@ -63,6 +63,9 @@
 #define FX_BUF_SIZE (2 * FX_IMAGE_SIZE + FX_IMAGE_ALIGN)
 
 #define DE_VECTOR 0
+#define DB_VECTOR 2
+#define UD_VECTOR 6
+#define NM_VECTOR 7
 #define DF_VECTOR 8
 #define TS_VECTOR 10
 #define NP_VECTOR 11
@@ -301,6 +304,7 @@ struct kvm_vcpu {
 	char fx_buf[FX_BUF_SIZE];
 	char *host_fx_image;
 	char *guest_fx_image;
+	int fpu_active;
 
 	int mmio_needed;
 	int mmio_read_completed;
diff --git a/drivers/kvm/svm.c b/drivers/kvm/svm.c
index 644efc5..bbde031 100644
--- a/drivers/kvm/svm.c
+++ b/drivers/kvm/svm.c
@@ -30,10 +30,6 @@ MODULE_LICENSE("GPL");
 #define IOPM_ALLOC_ORDER 2
 #define MSRPM_ALLOC_ORDER 1
 
-#define DB_VECTOR 1
-#define UD_VECTOR 6
-#define GP_VECTOR 13
-
 #define DR7_GD_MASK (1 << 13)
 #define DR6_BD_MASK (1 << 13)
 #define CR4_DE_MASK (1UL << 3)
@@ -587,6 +583,7 @@ static int svm_create_vcpu(struct kvm_vcpu *vcpu)
 	init_vmcb(vcpu->svm->vmcb);
 
 	fx_init(vcpu);
+	vcpu->fpu_active = 1;
 	vcpu->apic_base = 0xfee00000 |
 			/*for vcpu 0*/ MSR_IA32_APICBASE_BSP |
 			MSR_IA32_APICBASE_ENABLE;
@@ -756,6 +753,11 @@ static void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
 		}
 	}
 #endif
+	if ((vcpu->cr0 & CR0_TS_MASK) && !(cr0 & CR0_TS_MASK)) {
+		vcpu->svm->vmcb->control.intercept_exceptions &= ~(1 << NM_VECTOR);
+		vcpu->fpu_active = 1;
+	}
+ 
 	vcpu->cr0 = cr0;
 	cr0 |= CR0_PG_MASK | CR0_WP_MASK;
 	cr0 &= ~(CR0_CD_MASK | CR0_NW_MASK);
@@ -928,6 +930,20 @@ static int pf_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 	return 0;
 }
 
+static int nm_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
+{
+       spin_lock(&vcpu->kvm->lock);
+
+       vcpu->svm->vmcb->control.intercept_exceptions &= ~(1 << NM_VECTOR);
+       if (!(vcpu->cr0 & CR0_TS_MASK))
+               vcpu->svm->vmcb->save.cr0 &= ~CR0_TS_MASK;
+       vcpu->fpu_active = 1;
+
+       spin_unlock(&vcpu->kvm->lock);
+
+       return 1;
+}
+
 static int shutdown_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 {
 	/*
@@ -1292,6 +1308,7 @@ static int (*svm_exit_handlers[])(struct kvm_vcpu *vcpu,
 	[SVM_EXIT_WRITE_DR5]			= emulate_on_interception,
 	[SVM_EXIT_WRITE_DR7]			= emulate_on_interception,
 	[SVM_EXIT_EXCP_BASE + PF_VECTOR] 	= pf_interception,
+	[SVM_EXIT_EXCP_BASE + NM_VECTOR] 	= nm_interception,
 	[SVM_EXIT_INTR] 			= nop_on_interception,
 	[SVM_EXIT_NMI]				= nop_on_interception,
 	[SVM_EXIT_SMI]				= nop_on_interception,
@@ -1481,8 +1498,10 @@ again:
 		load_db_regs(vcpu->svm->db_regs);
 	}
 
-	fx_save(vcpu->host_fx_image);
-	fx_restore(vcpu->guest_fx_image);
+	if (vcpu->fpu_active) {
+		fx_save(vcpu->host_fx_image);
+		fx_restore(vcpu->guest_fx_image);
+	}
 
 	asm volatile (
 #ifdef CONFIG_X86_64
@@ -1593,8 +1612,10 @@ again:
 #endif
 		: "cc", "memory" );
 
-	fx_save(vcpu->guest_fx_image);
-	fx_restore(vcpu->host_fx_image);
+	if (vcpu->fpu_active) {
+		fx_save(vcpu->guest_fx_image);
+		fx_restore(vcpu->host_fx_image);
+	}
 
 	if ((vcpu->svm->vmcb->save.dr7 & 0xff))
 		load_db_regs(vcpu->svm->host_db_regs);
@@ -1664,6 +1685,12 @@ static void svm_set_cr3(struct kvm_vcpu *vcpu, unsigned long root)
 {
 	vcpu->svm->vmcb->save.cr3 = root;
 	force_new_asid(vcpu);
+ 
+	if (vcpu->fpu_active) {
+		vcpu->svm->vmcb->control.intercept_exceptions |= (1 << NM_VECTOR);
+		vcpu->svm->vmcb->save.cr0 |= CR0_TS_MASK;
+		vcpu->fpu_active = 0;
+	}
 }
 
 static void svm_inject_page_fault(struct kvm_vcpu *vcpu,

[-- Attachment #3: Type: text/plain, Size: 286 bytes --]

-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/

[-- Attachment #4: Type: text/plain, Size: 186 bytes --]

_______________________________________________
kvm-devel mailing list
kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
https://lists.sourceforge.net/lists/listinfo/kvm-devel

             reply	other threads:[~2007-04-23  2:56 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-04-23  2:56 Anthony Liguori [this message]
     [not found] ` <462C2048.4040700-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
2007-04-23  6:50   ` [PATCH] Lazy FPU for SVM Avi Kivity
     [not found]     ` <462C574E.2030304-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-04-23 14:32       ` Anthony Liguori
     [not found]         ` <462CC380.5020405-rdkfGonbjUSkNkDKm+mE6A@public.gmane.org>
2007-04-24 10:39           ` Avi Kivity
     [not found]             ` <462DDE52.5040303-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-04-24 13:59               ` Anthony Liguori
     [not found]                 ` <462E0D52.5000707-rdkfGonbjUSkNkDKm+mE6A@public.gmane.org>
2007-04-24 14:32                   ` Avi Kivity
2007-04-25  8:03           ` [PATCH] Remove redundant MSR save/restore Dong, Eddie
     [not found]             ` <10EA09EFD8728347A513008B6B0DA77A01599D74-wq7ZOvIWXbNpB2pF5aRoyrfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2007-04-25  8:17               ` Avi Kivity
     [not found]                 ` <462F0E90.8010307-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-04-25  8:53                   ` Dong, Eddie
     [not found]                     ` <10EA09EFD8728347A513008B6B0DA77A01599E01-wq7ZOvIWXbNpB2pF5aRoyrfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2007-04-25  9:28                       ` Avi Kivity
2007-04-25  7:30   ` [PATCH] Remove heavy is_empty_shadow_page call Dong, Eddie
     [not found]     ` <10EA09EFD8728347A513008B6B0DA77A01599D2B-wq7ZOvIWXbNpB2pF5aRoyrfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2007-04-25  8:03       ` Avi Kivity
     [not found]         ` <462F0B40.9060109-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-04-25  8:09           ` Dong, Eddie
     [not found]             ` <10EA09EFD8728347A513008B6B0DA77A01599D87-wq7ZOvIWXbNpB2pF5aRoyrfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2007-04-25  8:20               ` Avi Kivity
2007-04-25  8:40       ` Michael Riepe
     [not found]         ` <462F13E0.80104-0QoEqw4nQxo@public.gmane.org>
2007-04-25  8:45           ` Dong, Eddie
2007-04-25  8:49           ` 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=462C2048.4040700@us.ibm.com \
    --to=aliguori-r/jw6+rmf7hqt0dzr+alfa@public.gmane.org \
    --cc=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