aboutsummaryrefslogtreecommitdiff
path: root/target-i386/kvm.c
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2015-01-14 18:02:47 +0000
committerPeter Maydell <peter.maydell@linaro.org>2015-01-14 18:02:47 +0000
commitb629a38a13745d62d44de8ebb00f4e38ec6d8f7e (patch)
tree2318cf294ffd0390d5078593fdcfdb1ce830a274 /target-i386/kvm.c
parent3a7f560fa612610822727f7647ed6bc10bccd6ec (diff)
parent1979b908b6e99cc24c1c0746060422f8778aa9d9 (diff)
Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging
Mostly bugfixes and cleanups from qemu-devel. Yet another small patch from the record/replay series, and a few SCSI and i386 patches as well. # gpg: Signature made Wed 14 Jan 2015 09:39:14 GMT using RSA key ID 78C7AE83 # gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" # gpg: aka "Paolo Bonzini <pbonzini@redhat.com>" # gpg: WARNING: This key is not certified with sufficiently trusted signatures! # gpg: It is not certain that the signature belongs to the owner. # Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4 E2F7 7E15 100C CD36 69B1 # Subkey fingerprint: F133 3857 4B66 2389 866C 7682 BFFB D25F 78C7 AE83 * remotes/bonzini/tags/for-upstream: cpus: consistently use QEMU_CLOCK_VIRTUAL_RT for icount_warp_rt timer qemu-timer: rename timer_init to timer_init_tl scsi: fix cancellation when I/O was completed but DMA was not. rules.mak: Fix module build hw/scsi/lsi53c895a: add support for additional diag / debug registers qemu-common.h: optimise muldiv64 if int128 is available target-i386: do not memcpy in and out of xmm_regs target-i386: fix movntsd on big-endian hosts vl.c: fix regression when reading memory size from config file vl: Don't silently change topology when all -smp options were set vl: fix max_cpus check vl: Avoid unnecessary 'if' nesting 9pfs: changed to use event_notifier instead of qemu_pipe vl.c: fix regression when reading machine type from config file char: restore stdio echo on resume from suspend. Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target-i386/kvm.c')
-rw-r--r--target-i386/kvm.c30
1 files changed, 24 insertions, 6 deletions
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 54ccb890b5..36b1519f34 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -1019,7 +1019,10 @@ static int kvm_put_fpu(X86CPU *cpu)
fpu.ftwx |= (!env->fptags[i]) << i;
}
memcpy(fpu.fpr, env->fpregs, sizeof env->fpregs);
- memcpy(fpu.xmm, env->xmm_regs, sizeof env->xmm_regs);
+ for (i = 0; i < CPU_NB_REGS; i++) {
+ stq_p(&fpu.xmm[i][0], env->xmm_regs[i].XMM_Q(0));
+ stq_p(&fpu.xmm[i][8], env->xmm_regs[i].XMM_Q(1));
+ }
fpu.mxcsr = env->mxcsr;
return kvm_vcpu_ioctl(CPU(cpu), KVM_SET_FPU, &fpu);
@@ -1045,6 +1048,7 @@ static int kvm_put_xsave(X86CPU *cpu)
CPUX86State *env = &cpu->env;
struct kvm_xsave* xsave = env->kvm_xsave_buf;
uint16_t cwd, swd, twd;
+ uint8_t *xmm;
int i, r;
if (!kvm_has_xsave()) {
@@ -1065,8 +1069,6 @@ static int kvm_put_xsave(X86CPU *cpu)
memcpy(&xsave->region[XSAVE_CWD_RDP], &env->fpdp, sizeof(env->fpdp));
memcpy(&xsave->region[XSAVE_ST_SPACE], env->fpregs,
sizeof env->fpregs);
- memcpy(&xsave->region[XSAVE_XMM_SPACE], env->xmm_regs,
- sizeof env->xmm_regs);
xsave->region[XSAVE_MXCSR] = env->mxcsr;
*(uint64_t *)&xsave->region[XSAVE_XSTATE_BV] = env->xstate_bv;
memcpy(&xsave->region[XSAVE_YMMH_SPACE], env->ymmh_regs,
@@ -1079,6 +1081,13 @@ static int kvm_put_xsave(X86CPU *cpu)
sizeof env->opmask_regs);
memcpy(&xsave->region[XSAVE_ZMM_Hi256], env->zmmh_regs,
sizeof env->zmmh_regs);
+
+ xmm = (uint8_t *)&xsave->region[XSAVE_XMM_SPACE];
+ for (i = 0; i < CPU_NB_REGS; i++, xmm += 16) {
+ stq_p(xmm, env->xmm_regs[i].XMM_Q(0));
+ stq_p(xmm+8, env->xmm_regs[i].XMM_Q(1));
+ }
+
#ifdef TARGET_X86_64
memcpy(&xsave->region[XSAVE_Hi16_ZMM], env->hi16_zmm_regs,
sizeof env->hi16_zmm_regs);
@@ -1384,7 +1393,10 @@ static int kvm_get_fpu(X86CPU *cpu)
env->fptags[i] = !((fpu.ftwx >> i) & 1);
}
memcpy(env->fpregs, fpu.fpr, sizeof env->fpregs);
- memcpy(env->xmm_regs, fpu.xmm, sizeof env->xmm_regs);
+ for (i = 0; i < CPU_NB_REGS; i++) {
+ env->xmm_regs[i].XMM_Q(0) = ldq_p(&fpu.xmm[i][0]);
+ env->xmm_regs[i].XMM_Q(1) = ldq_p(&fpu.xmm[i][8]);
+ }
env->mxcsr = fpu.mxcsr;
return 0;
@@ -1395,6 +1407,7 @@ static int kvm_get_xsave(X86CPU *cpu)
CPUX86State *env = &cpu->env;
struct kvm_xsave* xsave = env->kvm_xsave_buf;
int ret, i;
+ const uint8_t *xmm;
uint16_t cwd, swd, twd;
if (!kvm_has_xsave()) {
@@ -1421,8 +1434,6 @@ static int kvm_get_xsave(X86CPU *cpu)
env->mxcsr = xsave->region[XSAVE_MXCSR];
memcpy(env->fpregs, &xsave->region[XSAVE_ST_SPACE],
sizeof env->fpregs);
- memcpy(env->xmm_regs, &xsave->region[XSAVE_XMM_SPACE],
- sizeof env->xmm_regs);
env->xstate_bv = *(uint64_t *)&xsave->region[XSAVE_XSTATE_BV];
memcpy(env->ymmh_regs, &xsave->region[XSAVE_YMMH_SPACE],
sizeof env->ymmh_regs);
@@ -1434,6 +1445,13 @@ static int kvm_get_xsave(X86CPU *cpu)
sizeof env->opmask_regs);
memcpy(env->zmmh_regs, &xsave->region[XSAVE_ZMM_Hi256],
sizeof env->zmmh_regs);
+
+ xmm = (const uint8_t *)&xsave->region[XSAVE_XMM_SPACE];
+ for (i = 0; i < CPU_NB_REGS; i++, xmm += 16) {
+ env->xmm_regs[i].XMM_Q(0) = ldq_p(xmm);
+ env->xmm_regs[i].XMM_Q(1) = ldq_p(xmm+8);
+ }
+
#ifdef TARGET_X86_64
memcpy(env->hi16_zmm_regs, &xsave->region[XSAVE_Hi16_ZMM],
sizeof env->hi16_zmm_regs);