From fd106bc530d58442daf5e9c2961b91a341833765 Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Mon, 13 Feb 2012 17:46:35 +0100 Subject: [PATCH 98/99] kvm: x86: Avoid runtime allocation of xsave buffer RH-Author: Alex Williamson Message-id: <20120213174625.14789.71975.stgit@bling.home> Patchwork-id: 37188 O-Subject: [RHEL6.3 qemu-kvm PATCH v2 2/2] kvm: x86: Avoid runtime allocation of xsave buffer Bugzilla: 789417 RH-Acked-by: Marcelo Tosatti RH-Acked-by: Laszlo Ersek RH-Acked-by: Markus Armbruster Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=789417 Brew: https://brewweb.devel.redhat.com/taskinfo?taskID=4034963 Upstream: based on commit fabacc0f79ccfe9b8b34e6b9ed35ffd17415c918 RHEL Note: As kvm_xsave_buf will be NULL without the exported extension, use that to avoid extension ioctl without needing kvm_has_xsave Keep a per-VCPU xsave buffer for kvm_put/get_xsave instead of continuously allocating and freeing it on state sync. Signed-off-by: Alex Williamson --- qemu-kvm-x86.c | 16 ++++++++-------- target-i386/cpu.h | 1 + 2 files changed, 9 insertions(+), 8 deletions(-) Signed-off-by: Michal Novotny --- qemu-kvm-x86.c | 16 ++++++++-------- target-i386/cpu.h | 1 + 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/qemu-kvm-x86.c b/qemu-kvm-x86.c index a04521c..54c9102 100644 --- a/qemu-kvm-x86.c +++ b/qemu-kvm-x86.c @@ -935,7 +935,7 @@ void kvm_arch_load_regs(CPUState *env) { struct kvm_regs regs; struct kvm_fpu fpu; - struct kvm_xsave* xsave; + struct kvm_xsave* xsave = env->kvm_xsave_buf; struct kvm_xcrs xcrs; struct kvm_sregs sregs; struct kvm_msr_entry msrs[100]; @@ -965,10 +965,9 @@ void kvm_arch_load_regs(CPUState *env) kvm_set_regs(env, ®s); - if (kvm_check_extension(kvm_state, KVM_CAP_XSAVE)) { + if (xsave) { uint16_t cwd, swd, twd, fop; - xsave = qemu_memalign(4096, sizeof(struct kvm_xsave)); memset(xsave, 0, sizeof(struct kvm_xsave)); cwd = swd = twd = fop = 0; swd = env->fpus & ~(7 << 11); @@ -994,7 +993,6 @@ void kvm_arch_load_regs(CPUState *env) xcrs.xcrs[0].value = env->xcr0; kvm_set_xcrs(env, &xcrs); } - qemu_free(xsave); } else { memset(&fpu, 0, sizeof fpu); fpu.fsw = env->fpus & ~(7 << 11); @@ -1140,7 +1138,7 @@ void kvm_arch_save_regs(CPUState *env) { struct kvm_regs regs; struct kvm_fpu fpu; - struct kvm_xsave* xsave; + struct kvm_xsave* xsave = env->kvm_xsave_buf; struct kvm_xcrs xcrs; struct kvm_sregs sregs; struct kvm_msr_entry msrs[100]; @@ -1171,9 +1169,8 @@ void kvm_arch_save_regs(CPUState *env) env->eflags = regs.rflags; env->eip = regs.rip; - if (kvm_check_extension(kvm_state, KVM_CAP_XSAVE)) { + if (xsave) { uint16_t cwd, swd, twd, fop; - xsave = qemu_memalign(4096, sizeof(struct kvm_xsave)); kvm_get_xsave(env, xsave); cwd = (uint16_t)xsave->region[0]; swd = (uint16_t)(xsave->region[0] >> 16); @@ -1197,7 +1194,6 @@ void kvm_arch_save_regs(CPUState *env) if (xcrs.xcrs[0].xcr == 0) env->xcr0 = xcrs.xcrs[0].value; } - qemu_free(xsave); } else { kvm_get_fpu(env, &fpu); env->fpstt = (fpu.fsw >> 11) & 7; @@ -1490,6 +1486,10 @@ int kvm_arch_init_vcpu(CPUState *cenv) qemu_add_vm_change_state_handler(cpu_update_state, cenv); + if (kvm_check_extension(kvm_state, KVM_CAP_XSAVE)) { + cenv->kvm_xsave_buf = qemu_memalign(4096, sizeof(struct kvm_xsave)); + } + return 0; } diff --git a/target-i386/cpu.h b/target-i386/cpu.h index 7ada730..09ba354 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h @@ -720,6 +720,7 @@ typedef struct CPUX86State { uint32_t sipi_vector; uint32_t cpuid_kvm_features; bool tsc_valid; + void *kvm_xsave_buf; /* in order to simplify APIC support, we leave this pointer to the user */ -- 1.7.7.5