kvm: x86: Save/restore FPU OP, IP and DP
PATCH 1/1 kvm: x86: Save/restore FPU OP, IP and DP
From: Jan Kiszka <[email protected]>
These FPU states are properly maintained by KVM but not yet by TCG. So far we unconditionally set them to 0 in the guest which may cause state corruptions - not only during migration.
--- target-i386/cpu.h | 6 +++++- target-i386/kvm.c | 20 +++++++++++++++----- target-i386/machine.c | 4 ++++ 3 files changed, 24 insertions(+), 6 deletions(-)
target-i386/cpu.h +5 -1
@@ -641,6 +641,10 @@ typedef struct CPUX86State {uint16_t fpuc;uint8_t fptags[8 ];/* 0 = valid, 1 = empty */ FPReg fpregs[8 ]; +/* KVM-only so far */ +uint16_t fpop; +uint64_t fpip; +uint64_t fpdp;/* emulator internal variables */ float_status fp_status;
@@ -942,7 +946,7 @@ uint64_t cpu_get_tsc(CPUX86State *env);#define cpu_list_id x86_cpu_list#define cpudef_setup x86_cpudef_setup -#define CPU_SAVE_VERSION 12 +#define CPU_SAVE_VERSION 13/* MMU modes definitions */ #define MMU_MODE0_SUFFIX _kernel
target-i386/kvm.c +15 -5
@@ -718,6 +718,9 @@ static int kvm_put_fpu(CPUState *env) fpu.fsw = env->fpus & ~(7 <<11 ); fpu.fsw |= (env->fpstt &7 ) <<11 ; fpu.fcw = env->fpuc; + fpu.last_opcode = env->fpop; + fpu.last_ip = env->fpip; + fpu.last_dp = env->fpdp;for (i =0 ; i <8 ; ++i) { fpu.ftwx |= (!env->fptags[i]) << i; }
@@ -740,7 +743,7 @@ static int kvm_put_xsave(CPUState *env) {int i, r;struct kvm_xsave * xsave; -uint16_t cwd, swd, twd, fop; +uint16_t cwd, swd, twd;if (!kvm_has_xsave ()) {return kvm_put_fpu (env);
@@ -748,7 +751,7 @@ static int kvm_put_xsave(CPUState *env) xsave =qemu_memalign (4096 ,sizeof (struct kvm_xsave ));memset (xsave,0 ,sizeof (struct kvm_xsave )); - cwd = swd = twd = fop =0 ; + cwd = swd = twd =0 ; swd = env->fpus & ~(7 <<11 ); swd |= (env->fpstt &7 ) <<11 ; cwd = env->fpuc;
@@ -756,7 +759,9 @@ static int kvm_put_xsave(CPUState *env) twd |= (!env->fptags[i]) << i; } xsave->region[0 ] = (uint32_t )(swd <<16 ) + cwd; - xsave->region[1 ] = (uint32_t )(fop <<16 ) + twd; + xsave->region[1 ] = (uint32_t )(env->fpop <<16 ) + twd; +memcpy (&xsave->region[XSAVE_CWD_RIP ], &env->fpip,sizeof (env->fpip)); +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,
@@ -921,6 +926,9 @@ static int kvm_get_fpu(CPUState *env) env->fpstt = (fpu.fsw >>11 ) &7 ; env->fpus = fpu.fsw; env->fpuc = fpu.fcw; + env->fpop = fpu.last_opcode; + env->fpip = fpu.last_ip; + env->fpdp = fpu.last_dp;for (i =0 ; i <8 ; ++i) { env->fptags[i] = !((fpu.ftwx >> i) &1 ); }
@@ -935,7 +943,7 @@ static int kvm_get_xsave(CPUState *env) {struct kvm_xsave * xsave;int ret, i; -uint16_t cwd, swd, twd, fop; +uint16_t cwd, swd, twd;if (!kvm_has_xsave ()) {return kvm_get_fpu (env);
@@ -951,13 +959,15 @@ static int kvm_get_xsave(CPUState *env) cwd = (uint16_t )xsave->region[0 ]; swd = (uint16_t )(xsave->region[0 ] >>16 ); twd = (uint16_t )xsave->region[1 ]; - fop = (uint16_t )(xsave->region[1 ] >>16 ); + env->fpop = (uint16_t )(xsave->region[1 ] >>16 ); env->fpstt = (swd >>11 ) &7 ; env->fpus = swd; env->fpuc = cwd;for (i =0 ; i <8 ; ++i) { env->fptags[i] = !((twd >> i) &1 ); } +memcpy (&env->fpip, &xsave->region[XSAVE_CWD_RIP ],sizeof (env->fpip)); +memcpy (&env->fpdp, &xsave->region[XSAVE_CWD_RDP ],sizeof (env->fpdp)); env->mxcsr = xsave->region[XSAVE_MXCSR ];memcpy (env->fpregs, &xsave->region[XSAVE_ST_SPACE ],sizeof env->fpregs);
target-i386/machine.c +4 -0
@@ -390,6 +390,10 @@ static const VMStateDescription vmstate_cpu = {VMSTATE_UINT64_V (xcr0, CPUState,12 ),VMSTATE_UINT64_V (xstate_bv, CPUState,12 ),VMSTATE_YMMH_REGS_VARS (ymmh_regs, CPUState,CPU_NB_REGS ,12 ), +/* Further FPU states */ +VMSTATE_UINT16_V (fpop, CPUState,13 ), +VMSTATE_UINT64_V (fpip, CPUState,13 ), +VMSTATE_UINT64_V (fpdp, CPUState,13 ),VMSTATE_END_OF_LIST ()/* The above list is not sorted /wrt version numbers, watch out! */ },
Signature · 1 line
1.7.1
target-i386/cpu.h uint64_t cpu_get_tsc(CPUX86State *env); · line 949
Quoted 10 lines · Jan Kiszka
From: Jan Kiszka<[email protected]>
These FPU states are properly maintained by KVM but not yet by TCG. So far we unconditionally set them to 0 in the guest which may cause state corruptions - not only during migration.
target-i386/cpu.h +1
-1-#define CPU_SAVE_VERSION 12 +#define CPU_SAVE_VERSION 13
Incrementing the version number seems excessive - I can't imagine a real-life guest will break due to fp pointer corruption
However, I don't think we have a mechanism for optional state. We discussed this during the 18th VMState Subsection Symposium and IIRC agreed to re-raise the issue when we encountered it, which appears to be now.
Signature · 1 line
error compiling committee.c: too many arguments to function
Quoted 15 lines · Avi Kivity
target-i386/cpu.h uint64_t cpu_get_tsc(CPUX86State *env); · line 949
Quoted 10 lines · Jan Kiszka
From: Jan Kiszka<[email protected]>
These FPU states are properly maintained by KVM but not yet by TCG. So far we unconditionally set them to 0 in the guest which may cause state corruptions - not only during migration.
target-i386/cpu.h +1
-1-#define CPU_SAVE_VERSION 12 +#define CPU_SAVE_VERSION 13Incrementing the version number seems excessive - I can't imagine a real-life guest will break due to fp pointer corruption
Quoted 5 lines
However, I don't think we have a mechanism for optional state. We discussed this during the 18th VMState Subsection Symposium and IIRC agreed to re-raise the issue when we encountered it, which appears to be now.
Whatever we invent, it has to be backported as well to allow that infamous traveling back in time, migrating VMs from newer to older versions.
Would that backporting be simpler if we used an unconditional subsection for the additional states?
Jan
Quoted 22 lines · Jan Kiszka
Quoted 12 lines · Avi Kivity
Quoted 10 lines · Jan Kiszka
From: Jan Kiszka<[email protected]>
These FPU states are properly maintained by KVM but not yet by TCG. So far we unconditionally set them to 0 in the guest which may cause state corruptions - not only during migration.
-#define
CPU_SAVE_VERSION12
+#defineCPU_SAVE_VERSION13Quoted 8 lines
Incrementing the version number seems excessive - I can't imagine a real-life guest will break due to fp pointer corruption
However, I don't think we have a mechanism for optional state. We discussed this during the 18th VMState Subsection Symposium and IIRC agreed to re-raise the issue when we encountered it, which appears to be now.
Quoted 5 lines
Whatever we invent, it has to be backported as well to allow that infamous traveling back in time, migrating VMs from newer to older versions.
Would that backporting be simpler if we used an unconditional subsection for the additional states?
Most likely. It depends on what mechanism we use.
Let's spend some time to think about what it would be like. This patch is not urgent, is it? (i.e. it was discovered by code inspection, not live migration that caught the cpu between an instruction that caused a math exception and the exception handler).
Signature · 1 line
error compiling committee.c: too many arguments to function
Quoted 32 lines · Avi Kivity
Quoted 24 lines · Jan Kiszka
Quoted 4 lines · Avi Kivity
Quoted 3 lines · Jan Kiszka
From: Jan Kiszka<[email protected]>
These FPU states are properly maintained by KVM but not yet by
TCG. So
Quoted 8 lines
Quoted 7 lines
far we unconditionally set them to 0 in the guest which may cause state corruptions - not only during migration.
-#define
CPU_SAVE_VERSION12
+#defineCPU_SAVE_VERSION13Quoted 6 lines
Incrementing the version number seems excessive - I can't imagine a real-life guest will break due to fp pointer corruption
However, I don't think we have a mechanism for optional state. We discussed this during the 18th VMState Subsection Symposium and IIRC agreed to re-raise the issue when we encountered it, which appears
to be
Quoted 2 lines
now.
Quoted 6 lines
Whatever we invent, it has to be backported as well to allow that infamous traveling back in time, migrating VMs from newer to older versions.
Would that backporting be simpler if we used an unconditional subsection for the additional states?
Quoted 6 lines
Most likely. It depends on what mechanism we use.
Let's spend some time to think about what it would be like. This patch is not urgent, is it? (i.e. it was discovered by code inspection, not live migration that caught the cpu between an instruction that caused a math exception and the exception handler).
Right, not urgent, should just make it into 0.15 in the end.
Jan
Quoted 22 lines · Jan Kiszka
Quoted 12 lines · Avi Kivity
Quoted 10 lines · Jan Kiszka
From: Jan Kiszka<[email protected]>
These FPU states are properly maintained by KVM but not yet by TCG. So far we unconditionally set them to 0 in the guest which may cause state corruptions - not only during migration.
-#define
CPU_SAVE_VERSION12
+#defineCPU_SAVE_VERSION13Quoted 8 lines
Incrementing the version number seems excessive - I can't imagine a real-life guest will break due to fp pointer corruption
However, I don't think we have a mechanism for optional state. We discussed this during the 18th VMState Subsection Symposium and IIRC agreed to re-raise the issue when we encountered it, which appears to be now.
Quoted 5 lines
Whatever we invent, it has to be backported as well to allow that infamous traveling back in time, migrating VMs from newer to older versions.
Would that backporting be simpler if we used an unconditional subsection for the additional states?
Thinking about it, a conditional subsection would work fine. Most threads will never see an fpu error, and are all initialized to a clean slate.
SDM 1 8.1.9.1 says:
Quoted 10 lines
8.1.9.1 Fopcode Compatibility Sub-mode
Beginning with the Pentium 4 and Intel Xeon processors, the IA-32 architecture provides program control over the storing of the last instruction opcode (sometimes referred to as the fopcode). Here, bit 2 of theIA32_MISC_ENABLEMSR enables (set) or disables (clear) the fopcode compatibility mode.
If FOP code compatibility mode is enabled, the FOP is defined as it has always been in previous IA32 implementations (always defined as the FOP of the last non-trans- parent FP instruction executed before a FSAVE/FSTENV/FXSAVE). If FOP code compatibility mode is disabled (default), FOP is only valid if the last non-transparent FP instruction executed before a FSAVE/FSTENV/FXSAVE had an unmasked exception.
So fopcode will usually be clear.
Signature · 1 line
error compiling committee.c: too many arguments to function
Quoted 56 lines · Avi Kivity
Quoted 24 lines · Jan Kiszka
Quoted 4 lines · Avi Kivity
Quoted 3 lines · Jan Kiszka
From: Jan Kiszka<[email protected]>
These FPU states are properly maintained by KVM but not yet by
TCG. So
Quoted 8 lines
Quoted 7 lines
far we unconditionally set them to 0 in the guest which may cause state corruptions - not only during migration.
-#define
CPU_SAVE_VERSION12
+#defineCPU_SAVE_VERSION13Quoted 6 lines
Incrementing the version number seems excessive - I can't imagine a real-life guest will break due to fp pointer corruption
However, I don't think we have a mechanism for optional state. We discussed this during the 18th VMState Subsection Symposium and IIRC agreed to re-raise the issue when we encountered it, which appears
to be
Quoted 2 lines
now.
Quoted 6 lines
Whatever we invent, it has to be backported as well to allow that infamous traveling back in time, migrating VMs from newer to older versions.
Would that backporting be simpler if we used an unconditional subsection for the additional states?
Thinking about it, a conditional subsection would work fine. Most threads will never see an fpu error, and are all initialized to a clean slate.
SDM 1 8.1.9.1 says:
Quoted 9 lines
8.1.9.1 Fopcode Compatibility Sub-mode
Beginning with the Pentium 4 and Intel Xeon processors, the IA-32 architecture
provides program control over the storing of the last instruction opcode (sometimes
referred to as the fopcode). Here, bit 2 of theIA32_MISC_ENABLEMSR enables (set)
or disables (clear) the fopcode compatibility mode.
If FOP code compatibility mode is enabled, the FOP is defined as itQuoted 8 lines
has always been
in previous IA32 implementations (always defined as the FOP of the last non-trans-
parent FP instruction executed before a FSAVE/FSTENV/FXSAVE). If FOP code compatibility mode is disabled (default), FOP is only valid if the last non-transparent
FP instruction executed before a FSAVE/FSTENV/FXSAVE had an unmasked exception.
Quoted 2 lines
So fopcode will usually be clear.
OK. So if bit 2 of IA32_MISC_ENABLE MSR, we must save that fields. But if it's off, how to test for that other condition "last non-transparent FP instruction ... had an unmasked exception" from the host?
Jan
Quoted 57 lines · Jan Kiszka
Quoted 56 lines · Avi Kivity
Quoted 24 lines · Jan Kiszka
Quoted 4 lines · Avi Kivity
Quoted 3 lines · Jan Kiszka
From: Jan Kiszka<[email protected]>
These FPU states are properly maintained by KVM but not yet by
TCG. So
Quoted 8 lines
Quoted 7 lines
far we unconditionally set them to 0 in the guest which may cause state corruptions - not only during migration.
-#define
CPU_SAVE_VERSION12
+#defineCPU_SAVE_VERSION13Quoted 6 lines
Incrementing the version number seems excessive - I can't imagine a real-life guest will break due to fp pointer corruption
However, I don't think we have a mechanism for optional state. We discussed this during the 18th VMState Subsection Symposium and IIRC agreed to re-raise the issue when we encountered it, which appears
to be
Quoted 2 lines
now.
Quoted 6 lines
Whatever we invent, it has to be backported as well to allow that infamous traveling back in time, migrating VMs from newer to older versions.
Would that backporting be simpler if we used an unconditional subsection for the additional states?
Thinking about it, a conditional subsection would work fine. Most threads will never see an fpu error, and are all initialized to a clean slate.
SDM 1 8.1.9.1 says:
Quoted 17 lines
8.1.9.1 Fopcode Compatibility Sub-mode
Beginning with the Pentium 4 and Intel Xeon processors, the IA-32 architecture
provides program control over the storing of the last instruction opcode (sometimes
referred to as the fopcode). Here, bit 2 of theIA32_MISC_ENABLEMSR enables (set)
or disables (clear) the fopcode compatibility mode.
If FOP code compatibility mode is enabled, the FOP is defined as it has always been
in previous IA32 implementations (always defined as the FOP of the last non-trans-
parent FP instruction executed before a FSAVE/FSTENV/FXSAVE). If FOP code compatibility mode is disabled (default), FOP is only valid if the last non-transparent
FP instruction executed before a FSAVE/FSTENV/FXSAVE had an unmasked exception.
Quoted 6 lines
Quoted 2 lines
So fopcode will usually be clear.
OK. So if bit 2 of
IA32_MISC_ENABLEMSR, we must save that fields. But if it's off, how to test for that other condition "last non-transparent FP instruction ... had an unmasked exception" from the host?
I briefly thought about status.ES == 1. But the guest may clear the flag in its exception handler before reading opcode etc.
Jan
Signature · 2 lines
Siemens AG, Corporate Technology, CT T DE IT 1 Corporate Competence Center Embedded Linux
Quoted 8 lines · Jan Kiszka
Quoted 3 lines
So fopcode will usually be clear.
OK. So if bit 2 of
IA32_MISC_ENABLEMSR, we must save that fields. But if it's off, how to test for that other condition "last non-transparent FP instruction ... had an unmasked exception" from the host?
We save fopcode unconditionally. But if IA32_MISC_ENABLE_MSR[2]=0, then fopcode will be zero, and we can skip the subsection (if the data and instruction pointers are also zero, which they will be).
If it isn't zero, there's still a good chance fopcode will be zero (64-bit userspace, thread that hasn't used the fpu since the last context switch, last opcode happened to be zero).
Signature · 1 line
error compiling committee.c: too many arguments to function
Quoted 10 lines · Avi Kivity
Quoted 8 lines · Jan Kiszka
Quoted 3 lines
So fopcode will usually be clear.
OK. So if bit 2 of
IA32_MISC_ENABLEMSR, we must save that fields. But if it's off, how to test for that other condition "last non-transparent FP instruction ... had an unmasked exception" from the host?
Quoted 7 lines
We save fopcode unconditionally. But if IA32_MISC_ENABLE_MSR[2]=0, then fopcode will be zero, and we can skip the subsection (if the data and instruction pointers are also zero, which they will be).
If it isn't zero, there's still a good chance fopcode will be zero (64-bit userspace, thread that hasn't used the fpu since the last context switch, last opcode happened to be zero).
I do not yet find "if fopcode is invalid, it is zero, just as IP and DP" in the spec. What clears them reliably?
Jan
Signature · 2 lines
Siemens AG, Corporate Technology, CT T DE IT 1 Corporate Competence Center Embedded Linux
Quoted 7 lines · Jan Kiszka
Quoted 4 lines
If it isn't zero, there's still a good chance fopcode will be zero (64-bit userspace, thread that hasn't used the fpu since the last context switch, last opcode happened to be zero).
I do not yet find "if fopcode is invalid, it is zero, just as IP and DP" in the spec. What clears them reliably?
FNINIT
Signature · 1 line
error compiling committee.c: too many arguments to function
Quoted 10 lines · Avi Kivity
Quoted 7 lines · Jan Kiszka
Quoted 4 lines
If it isn't zero, there's still a good chance fopcode will be zero (64-bit userspace, thread that hasn't used the fpu since the last context switch, last opcode happened to be zero).
I do not yet find "if fopcode is invalid, it is zero, just as IP and DP" in the spec. What clears them reliably?
FNINIT
OK, I see. So we simply check for all fields being zero and skip the section in that case. The MSR doesn't actually to us here.
Will write v2.
Jan
Signature · 2 lines
Siemens AG, Corporate Technology, CT T DE IT 1 Corporate Competence Center Embedded Linux
PATCH v2 1/1 kvm: x86: Save/restore FPU OP, IP and DP
In reply to Jan KiszkaThese FPU states are properly maintained by KVM but not yet by TCG. So far we unconditionally set them to 0 in the guest which may cause state corruptions, though not with modern guests.
To avoid breaking backward migration, use a conditional subsection that is only written if any of the three fields is non-zero. The guest's FNINIT clears them frequently, and cleared IA32_MISC_ENABLE MSR[2] reduces the probability of non-zero values further so that this subsection is not expected to restrict migration in any common scenario.
---
Changes in v2:
- use conditional subsection
target-i386/cpu.h | 4 ++++ target-i386/kvm.c | 20 +++++++++++++++----- target-i386/machine.c | 23 +++++++++++++++++++++++ 3 files changed, 42 insertions(+), 5 deletions(-)
target-i386/cpu.h +4 -0
@@ -641,6 +641,10 @@ typedef struct CPUX86State {uint16_t fpuc;uint8_t fptags[8 ];/* 0 = valid, 1 = empty */ FPReg fpregs[8 ]; +/* KVM-only so far */ +uint16_t fpop; +uint64_t fpip; +uint64_t fpdp;/* emulator internal variables */ float_status fp_status;
target-i386/kvm.c +15 -5
@@ -718,6 +718,9 @@ static int kvm_put_fpu(CPUState *env) fpu.fsw = env->fpus & ~(7 <<11 ); fpu.fsw |= (env->fpstt &7 ) <<11 ; fpu.fcw = env->fpuc; + fpu.last_opcode = env->fpop; + fpu.last_ip = env->fpip; + fpu.last_dp = env->fpdp;for (i =0 ; i <8 ; ++i) { fpu.ftwx |= (!env->fptags[i]) << i; }
@@ -740,7 +743,7 @@ static int kvm_put_xsave(CPUState *env) {int i, r;struct kvm_xsave * xsave; -uint16_t cwd, swd, twd, fop; +uint16_t cwd, swd, twd;if (!kvm_has_xsave ()) {return kvm_put_fpu (env);
@@ -748,7 +751,7 @@ static int kvm_put_xsave(CPUState *env) xsave =qemu_memalign (4096 ,sizeof (struct kvm_xsave ));memset (xsave,0 ,sizeof (struct kvm_xsave )); - cwd = swd = twd = fop =0 ; + cwd = swd = twd =0 ; swd = env->fpus & ~(7 <<11 ); swd |= (env->fpstt &7 ) <<11 ; cwd = env->fpuc;
@@ -756,7 +759,9 @@ static int kvm_put_xsave(CPUState *env) twd |= (!env->fptags[i]) << i; } xsave->region[0 ] = (uint32_t )(swd <<16 ) + cwd; - xsave->region[1 ] = (uint32_t )(fop <<16 ) + twd; + xsave->region[1 ] = (uint32_t )(env->fpop <<16 ) + twd; +memcpy (&xsave->region[XSAVE_CWD_RIP ], &env->fpip,sizeof (env->fpip)); +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,
@@ -921,6 +926,9 @@ static int kvm_get_fpu(CPUState *env) env->fpstt = (fpu.fsw >>11 ) &7 ; env->fpus = fpu.fsw; env->fpuc = fpu.fcw; + env->fpop = fpu.last_opcode; + env->fpip = fpu.last_ip; + env->fpdp = fpu.last_dp;for (i =0 ; i <8 ; ++i) { env->fptags[i] = !((fpu.ftwx >> i) &1 ); }
@@ -935,7 +943,7 @@ static int kvm_get_xsave(CPUState *env) {struct kvm_xsave * xsave;int ret, i; -uint16_t cwd, swd, twd, fop; +uint16_t cwd, swd, twd;if (!kvm_has_xsave ()) {return kvm_get_fpu (env);
@@ -951,13 +959,15 @@ static int kvm_get_xsave(CPUState *env) cwd = (uint16_t )xsave->region[0 ]; swd = (uint16_t )(xsave->region[0 ] >>16 ); twd = (uint16_t )xsave->region[1 ]; - fop = (uint16_t )(xsave->region[1 ] >>16 ); + env->fpop = (uint16_t )(xsave->region[1 ] >>16 ); env->fpstt = (swd >>11 ) &7 ; env->fpus = swd; env->fpuc = cwd;for (i =0 ; i <8 ; ++i) { env->fptags[i] = !((twd >> i) &1 ); } +memcpy (&env->fpip, &xsave->region[XSAVE_CWD_RIP ],sizeof (env->fpip)); +memcpy (&env->fpdp, &xsave->region[XSAVE_CWD_RDP ],sizeof (env->fpdp)); env->mxcsr = xsave->region[XSAVE_MXCSR ];memcpy (env->fpregs, &xsave->region[XSAVE_ST_SPACE ],sizeof env->fpregs);
target-i386/machine.c +23 -0
@@ -290,6 +290,26 @@ static const VMStateDescription vmstate_async_pf_msr = { } }; +static bool fpop_ip_dp_needed (void *opaque) +{ +CPUState *env = opaque; + +return env->fpop !=0 || env->fpip !=0 || env->fpdp !=0 ; +} + +static const VMStateDescription vmstate_fpop_ip_dp = { + .name ="cpu/fpop_ip_dp" , + .version_id =1 , + .minimum_version_id =1 , + .minimum_version_id_old =1 , + .fields = (VMStateField []) { +VMSTATE_UINT16_V (fpop, CPUState,13 ), +VMSTATE_UINT64_V (fpip, CPUState,13 ), +VMSTATE_UINT64_V (fpdp, CPUState,13 ), +VMSTATE_END_OF_LIST () + } +}; +static const VMStateDescription vmstate_cpu = { .name ="cpu" , .version_id =CPU_SAVE_VERSION ,
@@ -398,6 +418,9 @@ static const VMStateDescription vmstate_cpu = { .vmsd = &vmstate_async_pf_msr, .needed = async_pf_msr_needed, } , { + .vmsd = &vmstate_fpop_ip_dp, + .needed = fpop_ip_dp_needed, + } , {/* empty */ } }
Quoted 3 lines · Jan Kiszka
These FPU states are properly maintained by KVM but not yet by TCG. So far we unconditionally set them to 0 in the guest which may cause state corruptions, though not with modern guests.
And this one's fine too from a compilation point of view on f15/gcc4.6
Christophe
Quoted 9 lines · Jan Kiszka
These FPU states are properly maintained by KVM but not yet by TCG. So far we unconditionally set them to 0 in the guest which may cause state corruptions, though not with modern guests.
To avoid breaking backward migration, use a conditional subsection that is only written if any of the three fields is non-zero. The guest's FNINIT clears them frequently, and cleared
IA32_MISC_ENABLEMSR[2] reduces the probability of non-zero values further so that this subsection is not expected to restrict migration in any common scenario.
Thanks, applied to uq/master. A test migration showed that the subsection in fact did not show up.
Signature · 1 line
error compiling committee.c: too many arguments to function
Hi Jan,
Quoted 3 lines · Jan Kiszka
These FPU states are properly maintained by KVM but not yet by TCG. So far we unconditionally set them to 0 in the guest which may cause state corruptions - not only during migration.
I can't judge whether the patch is correct or not, but I can confirm it fixes my compilation problem. Feel free to add an Acked-by-me if that makes sense.
Christophe