From: Rusty Russell <rusty-8n+1lVoiYb80n/F98K4Iww@public.gmane.org>
To: kvm-devel <kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org>
Subject: [PATCH 4/4] Use kmem cache for allocating vcpus, simplify FPU ops
Date: Mon, 30 Jul 2007 16:39:01 +1000 [thread overview]
Message-ID: <1185777542.12151.156.camel@localhost.localdomain> (raw)
In-Reply-To: <1185777368.12151.152.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
If we use a kmem cache for allocating vcpus, we can get the 16-byte
alignment required by fxsave & fxrstor instructions, and avoid
manually aligning the buffer.
Signed-off-by: Rusty Russell <rusty-8n+1lVoiYb80n/F98K4Iww@public.gmane.org>
diff -r 39421cbc0486 drivers/kvm/kvm.h
--- a/drivers/kvm/kvm.h Mon Jul 30 15:01:44 2007 +1000
+++ b/drivers/kvm/kvm.h Mon Jul 30 15:09:54 2007 +1000
@@ -43,10 +43,6 @@
#define KVM_MIN_FREE_MMU_PAGES 5
#define KVM_REFILL_PAGES 25
#define KVM_MAX_CPUID_ENTRIES 40
-
-#define FX_IMAGE_SIZE 512
-#define FX_IMAGE_ALIGN 16
-#define FX_BUF_SIZE (2 * FX_IMAGE_SIZE + FX_IMAGE_ALIGN)
#define DE_VECTOR 0
#define NM_VECTOR 7
@@ -339,9 +335,8 @@ struct kvm_vcpu {
struct kvm_guest_debug guest_debug;
- char fx_buf[FX_BUF_SIZE];
- char *host_fx_image;
- char *guest_fx_image;
+ struct i387_fxsave_struct host_fx_image;
+ struct i387_fxsave_struct guest_fx_image;
int fpu_active;
int guest_fpu_loaded;
@@ -697,12 +692,12 @@ static inline unsigned long read_msr(uns
}
#endif
-static inline void fx_save(void *image)
+static inline void fx_save(struct i387_fxsave_struct *image)
{
asm ("fxsave (%0)":: "r" (image));
}
-static inline void fx_restore(void *image)
+static inline void fx_restore(struct i387_fxsave_struct *image)
{
asm ("fxrstor (%0)":: "r" (image));
}
diff -r 39421cbc0486 drivers/kvm/kvm_main.c
--- a/drivers/kvm/kvm_main.c Mon Jul 30 15:01:44 2007 +1000
+++ b/drivers/kvm/kvm_main.c Mon Jul 30 15:10:09 2007 +1000
@@ -218,8 +218,8 @@ void kvm_load_guest_fpu(struct kvm_vcpu
return;
vcpu->guest_fpu_loaded = 1;
- fx_save(vcpu->host_fx_image);
- fx_restore(vcpu->guest_fx_image);
+ fx_save(&vcpu->host_fx_image);
+ fx_restore(&vcpu->guest_fx_image);
}
EXPORT_SYMBOL_GPL(kvm_load_guest_fpu);
@@ -229,8 +229,8 @@ void kvm_put_guest_fpu(struct kvm_vcpu *
return;
vcpu->guest_fpu_loaded = 0;
- fx_save(vcpu->guest_fx_image);
- fx_restore(vcpu->host_fx_image);
+ fx_save(&vcpu->guest_fx_image);
+ fx_restore(&vcpu->host_fx_image);
}
EXPORT_SYMBOL_GPL(kvm_put_guest_fpu);
@@ -317,10 +317,6 @@ int kvm_vcpu_init(struct kvm_vcpu *vcpu,
goto fail_free_run;
}
vcpu->pio_data = page_address(page);
-
- vcpu->host_fx_image = (char*)ALIGN((hva_t)vcpu->fx_buf,
- FX_IMAGE_ALIGN);
- vcpu->guest_fx_image = vcpu->host_fx_image + FX_IMAGE_SIZE;
r = kvm_mmu_create(vcpu);
if (r < 0)
@@ -672,30 +668,20 @@ EXPORT_SYMBOL_GPL(set_cr8);
void fx_init(struct kvm_vcpu *vcpu)
{
- struct __attribute__ ((__packed__)) fx_image_s {
- u16 control; //fcw
- u16 status; //fsw
- u16 tag; // ftw
- u16 opcode; //fop
- u64 ip; // fpu ip
- u64 operand;// fpu dp
- u32 mxcsr;
- u32 mxcsr_mask;
-
- } *fx_image;
+ unsigned after_mxcsr_mask;
/* Initialize guest FPU by resetting ours and saving into guest's */
preempt_disable();
- fx_save(vcpu->host_fx_image);
+ fx_save(&vcpu->host_fx_image);
fpu_init();
- fx_save(vcpu->guest_fx_image);
- fx_restore(vcpu->host_fx_image);
+ fx_save(&vcpu->guest_fx_image);
+ fx_restore(&vcpu->host_fx_image);
preempt_enable();
- fx_image = (struct fx_image_s *)vcpu->guest_fx_image;
- fx_image->mxcsr = 0x1f80;
- memset(vcpu->guest_fx_image + sizeof(struct fx_image_s),
- 0, FX_IMAGE_SIZE - sizeof(struct fx_image_s));
+ after_mxcsr_mask = offsetof(struct i387_fxsave_struct, st_space);
+ vcpu->guest_fx_image.mxcsr = 0x1f80;
+ memset((void *)&vcpu->guest_fx_image + after_mxcsr_mask,
+ 0, sizeof(struct i387_fxsave_struct) - after_mxcsr_mask);
}
EXPORT_SYMBOL_GPL(fx_init);
@@ -2414,6 +2400,9 @@ static int kvm_vm_ioctl_create_vcpu(stru
if (IS_ERR(vcpu))
return PTR_ERR(vcpu);
+ /* We do fxsave: this must be aligned. */
+ BUG_ON((unsigned long)&vcpu->host_fx_image & 0xF);
+
vcpu_load(vcpu);
r = kvm_mmu_setup(vcpu);
vcpu_put(vcpu);
@@ -2526,7 +2515,7 @@ struct fxsave {
static int kvm_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
{
- struct fxsave *fxsave = (struct fxsave *)vcpu->guest_fx_image;
+ struct fxsave *fxsave = (struct fxsave *)&vcpu->guest_fx_image;
vcpu_load(vcpu);
@@ -2546,7 +2535,7 @@ static int kvm_vcpu_ioctl_get_fpu(struct
static int kvm_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
{
- struct fxsave *fxsave = (struct fxsave *)vcpu->guest_fx_image;
+ struct fxsave *fxsave = (struct fxsave *)&vcpu->guest_fx_image;
vcpu_load(vcpu);
diff -r 39421cbc0486 drivers/kvm/svm.c
--- a/drivers/kvm/svm.c Mon Jul 30 15:01:44 2007 +1000
+++ b/drivers/kvm/svm.c Mon Jul 30 15:09:54 2007 +1000
@@ -79,6 +79,7 @@ struct svm_cpu_data {
static DEFINE_PER_CPU(struct svm_cpu_data *, svm_data);
static uint32_t svm_features;
+static struct kmem_cache *svm_kmem_cache;
struct svm_init_data {
int cpu;
@@ -559,7 +560,7 @@ static struct kvm_vcpu *svm_create_vcpu(
struct page *page;
int err;
- svm = kzalloc(sizeof *svm, GFP_KERNEL);
+ svm = kmem_cache_zalloc(svm_kmem_cache, GFP_KERNEL);
if (!svm) {
err = -ENOMEM;
goto out;
@@ -1540,8 +1541,8 @@ again:
}
if (vcpu->fpu_active) {
- fx_save(vcpu->host_fx_image);
- fx_restore(vcpu->guest_fx_image);
+ fx_save(&vcpu->host_fx_image);
+ fx_restore(&vcpu->guest_fx_image);
}
asm volatile (
@@ -1653,8 +1654,8 @@ again:
vcpu->guest_mode = 0;
if (vcpu->fpu_active) {
- fx_save(vcpu->guest_fx_image);
- fx_restore(vcpu->host_fx_image);
+ fx_save(&vcpu->guest_fx_image);
+ fx_restore(&vcpu->host_fx_image);
}
if ((svm->vmcb->save.dr7 & 0xff))
@@ -1832,12 +1833,23 @@ static struct kvm_arch_ops svm_arch_ops
static int __init svm_init(void)
{
- return kvm_init_arch(&svm_arch_ops, THIS_MODULE);
+ int err;
+
+ /* A kmem cache lets us meet the alignment requirements of fx_save. */
+ svm_kmem_cache = KMEM_CACHE(vcpu_svm, 0);
+ if (!svm_kmem_cache)
+ return -ENOMEM;
+
+ err = kvm_init_arch(&svm_arch_ops, THIS_MODULE);
+ if (err)
+ kmem_cache_destroy(svm_kmem_cache);
+ return err;
}
static void __exit svm_exit(void)
{
kvm_exit_arch();
+ kmem_cache_destroy(svm_kmem_cache);
}
module_init(svm_init)
diff -r 39421cbc0486 drivers/kvm/vmx.c
--- a/drivers/kvm/vmx.c Mon Jul 30 15:01:44 2007 +1000
+++ b/drivers/kvm/vmx.c Mon Jul 30 15:09:54 2007 +1000
@@ -70,6 +70,7 @@ static DEFINE_PER_CPU(struct vmcs *, cur
static struct page *vmx_io_bitmap_a;
static struct page *vmx_io_bitmap_b;
+static struct kmem_cache *vmx_kmem_cache;
#ifdef CONFIG_X86_64
#define HOST_IS_64 1
@@ -2295,7 +2296,7 @@ static struct kvm_vcpu *vmx_create_vcpu(
static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id)
{
int err;
- struct vcpu_vmx *vmx = kzalloc(sizeof(*vmx), GFP_KERNEL);
+ struct vcpu_vmx *vmx = kmem_cache_zalloc(vmx_kmem_cache, GFP_KERNEL);
if (!vmx)
return ERR_PTR(-ENOMEM);
@@ -2404,6 +2405,13 @@ static int __init vmx_init(void)
goto out;
}
+ /* A kmem cache lets us meet the alignment requirements of fx_save. */
+ vmx_kmem_cache = KMEM_CACHE(vcpu_vmx, 0);
+ if (!vmx_kmem_cache) {
+ r = -ENOMEM;
+ goto out1;
+ }
+
/*
* Allow direct access to the PC debug port (it is often used for I/O
* delays, but the vmexits simply slow things down).
@@ -2419,10 +2427,12 @@ static int __init vmx_init(void)
r = kvm_init_arch(&vmx_arch_ops, THIS_MODULE);
if (r)
- goto out1;
+ goto out2;
return 0;
+out2:
+ kmem_cache_destroy(vmx_kmem_cache);
out1:
__free_page(vmx_io_bitmap_b);
out:
@@ -2432,6 +2442,7 @@ out:
static void __exit vmx_exit(void)
{
+ kmem_cache_destroy(vmx_kmem_cache);
__free_page(vmx_io_bitmap_b);
__free_page(vmx_io_bitmap_a);
-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
next prev parent reply other threads:[~2007-07-30 6:39 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-07-30 6:31 [PATCH 1/4] vmx: pass vcpu_vmx internally Rusty Russell
[not found] ` <1185777103.12151.147.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2007-07-30 6:32 ` [PATCH 2/4] svm: pass vcpu_svm internally Rusty Russell
[not found] ` <1185777179.12151.149.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2007-07-30 6:36 ` [PATCH 3/4] House svm.c's pop_irq and push_irq helpers into generic header Rusty Russell
[not found] ` <1185777368.12151.152.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2007-07-30 6:39 ` Rusty Russell [this message]
[not found] ` <1185777542.12151.156.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2007-07-30 9:12 ` [PATCH 4/4] Use kmem cache for allocating vcpus, simplify FPU ops Avi Kivity
[not found] ` <46ADAB67.5070805-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-07-30 10:04 ` Rusty Russell
[not found] ` <1185789882.6131.30.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2007-07-30 10:26 ` Avi Kivity
[not found] ` <46ADBCBC.9050207-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-07-30 11:12 ` [PATCH 1/2] Use kmem cache for allocating vcpus Rusty Russell
[not found] ` <1185793939.6131.38.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2007-07-30 11:13 ` [PATCH 2/2] Use alignment properties of vcpu to simplify FPU ops Rusty Russell
[not found] ` <1185794023.6131.41.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2007-07-30 13:09 ` Avi Kivity
2007-07-30 6:39 ` [PATCH 3/4] House svm.c's pop_irq and push_irq helpers into generic header Rusty Russell
2007-07-30 9:03 ` [PATCH 2/4] svm: pass vcpu_svm internally Avi Kivity
[not found] ` <46ADA971.9030406-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-07-30 10:07 ` [PATCH 1/2] svm de-containization Rusty Russell
[not found] ` <1185790028.6131.32.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2007-07-30 10:08 ` [PATCH 2/2] svm internal function name cleanup Rusty Russell
2007-07-30 10:22 ` [PATCH 1/2] svm de-containization Avi Kivity
2007-07-30 9:02 ` [PATCH 1/4] vmx: pass vcpu_vmx internally 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=1185777542.12151.156.camel@localhost.localdomain \
--to=rusty-8n+1lvoiyb80n/f98k4iww@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