|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH 3/4] x86/i387: Rework fpu_fxrstor() given a newer toolchain baseline
Use asm goto rather than hiding a memset() in the fixup section. With the
compiler now able to see the write into fpu_ctxt (as opposed to the asm
constraint erroneously stating it as input-only), it validly objects to the
pointer being const.
While FXRSTOR oughtn't to fault on an all-zeros input, avoid a risk of an
infinite loop entirely by using a fixup scheme similar to xrstor(), and
crashing the domain if we run out options.
No functional change.
Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
---
CC: Jan Beulich <JBeulich@xxxxxxxx>
CC: Roger Pau Monné <roger.pau@xxxxxxxxxx>
---
xen/arch/x86/i387.c | 65 ++++++++++++++++++++-------------------------
1 file changed, 29 insertions(+), 36 deletions(-)
diff --git a/xen/arch/x86/i387.c b/xen/arch/x86/i387.c
index b84cd6f7a9e1..e0714ab2267d 100644
--- a/xen/arch/x86/i387.c
+++ b/xen/arch/x86/i387.c
@@ -38,7 +38,8 @@ static inline void fpu_xrstor(struct vcpu *v, uint64_t mask)
/* Restore x87 FPU, MMX, SSE and SSE2 state */
static inline void fpu_fxrstor(struct vcpu *v)
{
- const fpusse_t *fpu_ctxt = &v->arch.xsave_area->fpu_sse;
+ fpusse_t *fpu_ctxt = &v->arch.xsave_area->fpu_sse;
+ unsigned int faults = 0;
/*
* Some CPUs don't save/restore FDP/FIP/FOP unless an exception
@@ -59,49 +60,41 @@ static inline void fpu_fxrstor(struct vcpu *v)
* possibility, which may occur if the block was passed to us by control
* tools or through VCPUOP_initialise, by silently clearing the block.
*/
+ retry:
switch ( __builtin_expect(fpu_ctxt->x[FPU_WORD_SIZE_OFFSET], 8) )
{
default:
- asm_inline volatile (
+ asm_inline volatile goto (
"1: fxrstorq %0\n"
- ".section .fixup,\"ax\" \n"
- "2: push %%"__OP"ax \n"
- " push %%"__OP"cx \n"
- " push %%"__OP"di \n"
- " lea %0,%%"__OP"di \n"
- " mov %1,%%ecx \n"
- " xor %%eax,%%eax \n"
- " rep ; stosl \n"
- " pop %%"__OP"di \n"
- " pop %%"__OP"cx \n"
- " pop %%"__OP"ax \n"
- " jmp 1b \n"
- ".previous \n"
- _ASM_EXTABLE(1b, 2b)
- :
- : "m" (*fpu_ctxt), "i" (sizeof(*fpu_ctxt) / 4) );
+ _ASM_EXTABLE(1b, %l[fault])
+ :: "m" (*fpu_ctxt)
+ :: fault );
break;
+
case 4: case 2:
- asm_inline volatile (
- "1: fxrstor %0 \n"
- ".section .fixup,\"ax\"\n"
- "2: push %%"__OP"ax \n"
- " push %%"__OP"cx \n"
- " push %%"__OP"di \n"
- " lea %0,%%"__OP"di \n"
- " mov %1,%%ecx \n"
- " xor %%eax,%%eax \n"
- " rep ; stosl \n"
- " pop %%"__OP"di \n"
- " pop %%"__OP"cx \n"
- " pop %%"__OP"ax \n"
- " jmp 1b \n"
- ".previous \n"
- _ASM_EXTABLE(1b, 2b)
- :
- : "m" (*fpu_ctxt), "i" (sizeof(*fpu_ctxt) / 4) );
+ asm_inline volatile goto (
+ "1: fxrstor %0\n"
+ _ASM_EXTABLE(1b, %l[fault])
+ :: "m" (*fpu_ctxt)
+ :: fault );
break;
}
+
+ return;
+
+ fault:
+ faults++;
+
+ switch ( faults )
+ {
+ case 1: /* Stage 1: Reset all state. */
+ memset(fpu_ctxt, 0, sizeof(*fpu_ctxt));
+ goto retry;
+
+ default: /* Stage 2: Nothing else to do. */
+ domain_crash(v->domain, "Uncorrectable FXRSTOR fault\n");
+ return;
+ }
}
/*******************************/
--
2.39.5
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |