Commit 240c35a3 authored by Marc Orr's avatar Marc Orr Committed by Paolo Bonzini

kvm: x86: Use task structs fpu field for user

Previously, x86's instantiation of 'struct kvm_vcpu_arch' added an fpu
field to save/restore fpu-related architectural state, which will differ
from kvm's fpu state. However, this is redundant to the 'struct fpu'
field, called fpu, embedded in the task struct, via the thread field.
Thus, this patch removes the user_fpu field from the kvm_vcpu_arch
struct and replaces it with the task struct's fpu field.

This change is significant because the fpu struct is actually quite
large. For example, on the system used to develop this patch, this
change reduces the size of the vcpu_vmx struct from 23680 bytes down to
19520 bytes, when building the kernel with kvmconfig. This reduction in
the size of the vcpu_vmx struct moves us closer to being able to
allocate the struct at order 2, rather than order 3.
Suggested-by: default avatarDave Hansen <dave.hansen@intel.com>
Signed-off-by: default avatarMarc Orr <marcorr@google.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent 4e445aee
...@@ -601,16 +601,15 @@ struct kvm_vcpu_arch { ...@@ -601,16 +601,15 @@ struct kvm_vcpu_arch {
/* /*
* QEMU userspace and the guest each have their own FPU state. * QEMU userspace and the guest each have their own FPU state.
* In vcpu_run, we switch between the user and guest FPU contexts. * In vcpu_run, we switch between the user, maintained in the
* While running a VCPU, the VCPU thread will have the guest FPU * task_struct struct, and guest FPU contexts. While running a VCPU,
* context. * the VCPU thread will have the guest FPU context.
* *
* Note that while the PKRU state lives inside the fpu registers, * Note that while the PKRU state lives inside the fpu registers,
* it is switched out separately at VMENTER and VMEXIT time. The * it is switched out separately at VMENTER and VMEXIT time. The
* "guest_fpu" state here contains the guest FPU context, with the * "guest_fpu" state here contains the guest FPU context, with the
* host PRKU bits. * host PRKU bits.
*/ */
struct fpu user_fpu;
struct fpu guest_fpu; struct fpu guest_fpu;
u64 xcr0; u64 xcr0;
......
...@@ -8035,7 +8035,7 @@ static int complete_emulated_mmio(struct kvm_vcpu *vcpu) ...@@ -8035,7 +8035,7 @@ static int complete_emulated_mmio(struct kvm_vcpu *vcpu)
static void kvm_load_guest_fpu(struct kvm_vcpu *vcpu) static void kvm_load_guest_fpu(struct kvm_vcpu *vcpu)
{ {
preempt_disable(); preempt_disable();
copy_fpregs_to_fpstate(&vcpu->arch.user_fpu); copy_fpregs_to_fpstate(&current->thread.fpu);
/* PKRU is separately restored in kvm_x86_ops->run. */ /* PKRU is separately restored in kvm_x86_ops->run. */
__copy_kernel_to_fpregs(&vcpu->arch.guest_fpu.state, __copy_kernel_to_fpregs(&vcpu->arch.guest_fpu.state,
~XFEATURE_MASK_PKRU); ~XFEATURE_MASK_PKRU);
...@@ -8048,7 +8048,7 @@ static void kvm_put_guest_fpu(struct kvm_vcpu *vcpu) ...@@ -8048,7 +8048,7 @@ static void kvm_put_guest_fpu(struct kvm_vcpu *vcpu)
{ {
preempt_disable(); preempt_disable();
copy_fpregs_to_fpstate(&vcpu->arch.guest_fpu); copy_fpregs_to_fpstate(&vcpu->arch.guest_fpu);
copy_kernel_to_fpregs(&vcpu->arch.user_fpu.state); copy_kernel_to_fpregs(&current->thread.fpu.state);
preempt_enable(); preempt_enable();
++vcpu->stat.fpu_reload; ++vcpu->stat.fpu_reload;
trace_kvm_fpu(0); trace_kvm_fpu(0);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment