All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sheng Yang <sheng@linux.intel.com>
To: Avi Kivity <avi@redhat.com>, Marcelo Tosatti <mtosatti@redhat.com>
Cc: kvm@vger.kernel.org, Sheng Yang <sheng@linux.intel.com>
Subject: [PATCH] KVM: x86: XSAVE/XRSTOR live migration support
Date: Thu, 27 May 2010 17:48:40 +0800	[thread overview]
Message-ID: <1274953721-5068-1-git-send-email-sheng@linux.intel.com> (raw)

This patch enable save/restore of xsave state.

Signed-off-by: Sheng Yang <sheng@linux.intel.com>
---
 arch/x86/include/asm/kvm.h |   29 ++++++++++++++++
 arch/x86/kvm/x86.c         |   79 ++++++++++++++++++++++++++++++++++++++++++++
 include/linux/kvm.h        |    6 +++
 3 files changed, 114 insertions(+), 0 deletions(-)

diff --git a/arch/x86/include/asm/kvm.h b/arch/x86/include/asm/kvm.h
index ff90055..d3f4d9f 100644
--- a/arch/x86/include/asm/kvm.h
+++ b/arch/x86/include/asm/kvm.h
@@ -22,6 +22,7 @@
 #define __KVM_HAVE_XEN_HVM
 #define __KVM_HAVE_VCPU_EVENTS
 #define __KVM_HAVE_DEBUGREGS
+#define __KVM_HAVE_XSAVE
 
 /* Architectural interrupt line count. */
 #define KVM_NR_INTERRUPTS 256
@@ -299,4 +300,32 @@ struct kvm_debugregs {
 	__u64 reserved[9];
 };
 
+/* for KVM_CAP_XSAVE */
+struct kvm_xsave {
+	struct {
+		__u16 cwd;
+		__u16 swd;
+		__u16 twd;
+		__u16 fop;
+		__u64 rip;
+		__u64 rdp;
+		__u32 mxcsr;
+		__u32 mxcsr_mask;
+		__u32 st_space[32];
+		__u32 xmm_space[64];
+		__u32 padding[12];
+		__u32 sw_reserved[12];
+	} i387;
+	struct {
+		__u64 xstate_bv;
+		__u64 reserved1[2];
+		__u64 reserved2[5];
+	} xsave_hdr;
+	struct {
+		__u32 ymmh_space[64];
+	} ymmh;
+	__u64 xcr0;
+	__u32 padding[256];
+};
+
 #endif /* _ASM_X86_KVM_H */
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index e7acc9d..5badba2 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -1711,6 +1711,9 @@ int kvm_dev_ioctl_check_extension(long ext)
 	case KVM_CAP_MCE:
 		r = KVM_MAX_MCE_BANKS;
 		break;
+	case KVM_CAP_XSAVE:
+		r = cpu_has_xsave;
+		break;
 	default:
 		r = 0;
 		break;
@@ -2363,6 +2366,59 @@ static int kvm_vcpu_ioctl_x86_set_debugregs(struct kvm_vcpu *vcpu,
 	return 0;
 }
 
+static void kvm_vcpu_ioctl_x86_get_xsave(struct kvm_vcpu *vcpu,
+					struct kvm_xsave *guest_xsave)
+{
+	struct xsave_struct *xsave = &vcpu->arch.guest_fpu.state->xsave;
+
+	if (!cpu_has_xsave)
+		return;
+
+	guest_xsave->i387.cwd = xsave->i387.cwd;
+	guest_xsave->i387.swd = xsave->i387.swd;
+	guest_xsave->i387.twd = xsave->i387.twd;
+	guest_xsave->i387.fop = xsave->i387.fop;
+	guest_xsave->i387.rip = xsave->i387.rip;
+	guest_xsave->i387.rdp = xsave->i387.rdp;
+	memcpy(guest_xsave->i387.st_space, xsave->i387.st_space, 128);
+	memcpy(guest_xsave->i387.xmm_space, xsave->i387.xmm_space,
+			sizeof guest_xsave->i387.xmm_space);
+
+	guest_xsave->xsave_hdr.xstate_bv = xsave->xsave_hdr.xstate_bv;
+	memcpy(guest_xsave->ymmh.ymmh_space, xsave->ymmh.ymmh_space,
+			sizeof xsave->ymmh.ymmh_space);
+
+	guest_xsave->xcr0 = vcpu->arch.xcr0;
+}
+
+static int kvm_vcpu_ioctl_x86_set_xsave(struct kvm_vcpu *vcpu,
+					struct kvm_xsave *guest_xsave)
+{
+	struct xsave_struct *xsave = &vcpu->arch.guest_fpu.state->xsave;
+
+	if (!cpu_has_xsave)
+		return -EINVAL;
+
+	xsave->i387.cwd = guest_xsave->i387.cwd;
+	xsave->i387.swd = guest_xsave->i387.swd;
+	xsave->i387.twd = guest_xsave->i387.twd;
+	xsave->i387.fop = guest_xsave->i387.fop;
+	xsave->i387.rip = guest_xsave->i387.rip;
+	xsave->i387.rdp = guest_xsave->i387.rdp;
+	memcpy(xsave->i387.st_space, guest_xsave->i387.st_space, 128);
+	memcpy(xsave->i387.xmm_space, guest_xsave->i387.xmm_space,
+			sizeof guest_xsave->i387.xmm_space);
+
+	xsave->xsave_hdr.xstate_bv = guest_xsave->xsave_hdr.xstate_bv;
+	memcpy(xsave->ymmh.ymmh_space, guest_xsave->ymmh.ymmh_space,
+		sizeof guest_xsave->ymmh.ymmh_space);
+
+	/* set_xsave may override the initial value of xcr0... */
+	if (guest_xsave->xcr0 != 0)
+		kvm_set_xcr0(vcpu, guest_xsave->xcr0);
+	return 0;
+}
+
 long kvm_arch_vcpu_ioctl(struct file *filp,
 			 unsigned int ioctl, unsigned long arg)
 {
@@ -2564,6 +2620,29 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
 		r = kvm_vcpu_ioctl_x86_set_debugregs(vcpu, &dbgregs);
 		break;
 	}
+	case KVM_GET_XSAVE: {
+		struct kvm_xsave xsave;
+
+		kvm_vcpu_ioctl_x86_get_xsave(vcpu, &xsave);
+
+		r = -EFAULT;
+		if (copy_to_user(argp, &xsave,
+				 sizeof(struct kvm_xsave)))
+			break;
+		r = 0;
+		break;
+	}
+	case KVM_SET_XSAVE: {
+		struct kvm_xsave xsave;
+
+		r = -EFAULT;
+		if (copy_from_user(&xsave, argp,
+				   sizeof(struct kvm_xsave)))
+			break;
+
+		r = kvm_vcpu_ioctl_x86_set_xsave(vcpu, &xsave);
+		break;
+	}
 	default:
 		r = -EINVAL;
 	}
diff --git a/include/linux/kvm.h b/include/linux/kvm.h
index 23ea022..5006761 100644
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -524,6 +524,9 @@ struct kvm_enable_cap {
 #define KVM_CAP_PPC_OSI 52
 #define KVM_CAP_PPC_UNSET_IRQ 53
 #define KVM_CAP_ENABLE_CAP 54
+#ifdef __KVM_HAVE_XSAVE
+#define KVM_CAP_XSAVE 55
+#endif
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
@@ -714,6 +717,9 @@ struct kvm_clock_data {
 #define KVM_GET_DEBUGREGS         _IOR(KVMIO,  0xa1, struct kvm_debugregs)
 #define KVM_SET_DEBUGREGS         _IOW(KVMIO,  0xa2, struct kvm_debugregs)
 #define KVM_ENABLE_CAP            _IOW(KVMIO,  0xa3, struct kvm_enable_cap)
+/* Available with KVM_CAP_XSAVE */
+#define KVM_GET_XSAVE		  _IOR(KVMIO,  0xa4, struct kvm_xsave)
+#define KVM_SET_XSAVE		  _IOW(KVMIO,  0xa5, struct kvm_xsave)
 
 #define KVM_DEV_ASSIGN_ENABLE_IOMMU	(1 << 0)
 
-- 
1.7.0.1


             reply	other threads:[~2010-05-27  9:47 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-05-27  9:48 Sheng Yang [this message]
2010-05-27 10:02 ` [PATCH] KVM: x86: XSAVE/XRSTOR live migration support Avi Kivity
2010-05-27 10:33   ` Sheng Yang
2010-05-27 11:34     ` Avi Kivity
2010-05-31 11:21   ` Sheng Yang
2010-05-31 11:26     ` 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=1274953721-5068-1-git-send-email-sheng@linux.intel.com \
    --to=sheng@linux.intel.com \
    --cc=avi@redhat.com \
    --cc=kvm@vger.kernel.org \
    --cc=mtosatti@redhat.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.