diff options
author | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2020-11-28 17:57:21 +0100 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2020-11-28 18:35:40 +0100 |
commit | 0e59d87e06f967680d250b9a74d08da1389b6212 (patch) | |
tree | f1daffaca55b607ba9c60a4ae04444e52b95a362 /i386 | |
parent | b885c5ea26fb3c2f2d91b6e9a1495070da429ea4 (diff) | |
download | gnumach-0e59d87e06f967680d250b9a74d08da1389b6212.tar.gz gnumach-0e59d87e06f967680d250b9a74d08da1389b6212.tar.bz2 gnumach-0e59d87e06f967680d250b9a74d08da1389b6212.zip |
x86: Extend XSAVE support to unbound state
* i386/i386/fpu.c (fp_xsave_size): New variable.
(init_fpu): Save XSAVE size to fp_xsave_size.
(fpu_module_init): Pass fp_xsave_size as size to kmem_cache_init.
(fpu_set_state, fp_load, fp_state_alloc): Use fp_xsave_size to clear
ifps.
* i386/include/mach/i386/fp_reg.h (struct i386_xfp_save): Replace static
fp_yreg_word with extended field.
* i386/i386/thread.h (struct i386_fpsave_state): Make fp_valid field
first in the structure to let the extended finish the structure.
Diffstat (limited to 'i386')
-rw-r--r-- | i386/i386/fpu.c | 25 | ||||
-rw-r--r-- | i386/i386/thread.h | 3 | ||||
-rw-r--r-- | i386/include/mach/i386/fp_reg.h | 7 |
3 files changed, 12 insertions, 23 deletions
diff --git a/i386/i386/fpu.c b/i386/i386/fpu.c index 517764d6..3961f17b 100644 --- a/i386/i386/fpu.c +++ b/i386/i386/fpu.c @@ -71,6 +71,7 @@ int fp_kind = FP_387; /* 80387 present */ uint64_t fp_xsave_support; /* Bitmap of supported XSAVE save areas */ +unsigned fp_xsave_size = sizeof(struct i386_fpsave_state); struct kmem_cache ifps_cache; /* cache for FPU save area */ static unsigned long mxcsr_feature_mask = 0xffffffff; /* Always AND user-provided mxcsr with this security mask */ @@ -168,22 +169,12 @@ init_fpu(void) eax = 0xd; ecx = 0x0; cpuid(eax, ebx, ecx, edx); + fp_xsave_size = offsetof(struct i386_fpsave_state, xfp_save_state) + ebx; - if (ebx > sizeof(struct i386_xfp_save)) { - /* TODO: rather make struct unbound and set size - * in fpu_module_init */ - printf("XSAVE area size %u larger than provisioned " - "%u, not enabling XSAVE\n", - ebx, sizeof(struct i386_xfp_save)); -#ifndef MACH_RING1 - set_cr4(get_cr4() & ~(CR4_OSFXSR | CR4_OSXSAVE)); -#endif /* MACH_RING1 */ - } else { - fp_kind = FP_387X; - } + fp_kind = FP_387X; } - if (fp_kind == FP_387 && CPU_HAS_FEATURE(CPU_FEATURE_FXSR)) { + else if (CPU_HAS_FEATURE(CPU_FEATURE_FXSR)) { #ifndef MACH_RING1 set_cr4(get_cr4() | CR4_OSFXSR); #endif /* MACH_RING1 */ @@ -226,7 +217,7 @@ void fpu_module_init(void) { kmem_cache_init(&ifps_cache, "i386_fpsave_state", - sizeof(struct i386_fpsave_state), + fp_xsave_size, alignof(struct i386_fpsave_state), NULL, 0); } @@ -398,7 +389,7 @@ ASSERT_IPL(SPL0); /* * Ensure that reserved parts of the environment are 0. */ - memset(ifps, 0, sizeof(*ifps)); + memset(ifps, 0, fp_xsave_size); if (fp_kind == FP_387X || fp_kind == FP_387FX) { int i; @@ -842,7 +833,7 @@ ASSERT_IPL(SPL0); ifps = pcb->ims.ifps; if (ifps == 0) { ifps = (struct i386_fpsave_state *) kmem_cache_alloc(&ifps_cache); - memset(ifps, 0, sizeof *ifps); + memset(ifps, 0, fp_xsave_size); pcb->ims.ifps = ifps; fpinit(thread); #if 1 @@ -895,7 +886,7 @@ fp_state_alloc(void) struct i386_fpsave_state *ifps; ifps = (struct i386_fpsave_state *)kmem_cache_alloc(&ifps_cache); - memset(ifps, 0, sizeof *ifps); + memset(ifps, 0, fp_xsave_size); pcb->ims.ifps = ifps; ifps->fp_valid = TRUE; diff --git a/i386/i386/thread.h b/i386/i386/thread.h index 3d4808c7..4a9c1987 100644 --- a/i386/i386/thread.h +++ b/i386/i386/thread.h @@ -129,6 +129,8 @@ struct i386_kernel_state { */ struct i386_fpsave_state { + boolean_t fp_valid; + union { struct { struct i386_fp_save fp_save_state; @@ -136,7 +138,6 @@ struct i386_fpsave_state { }; struct i386_xfp_save xfp_save_state; }; - boolean_t fp_valid; }; /* diff --git a/i386/include/mach/i386/fp_reg.h b/i386/include/mach/i386/fp_reg.h index 5992ea78..41301ec4 100644 --- a/i386/include/mach/i386/fp_reg.h +++ b/i386/include/mach/i386/fp_reg.h @@ -79,12 +79,9 @@ struct i386_xfp_save { /* space for 16 128-bit XMM registers */ unsigned int padding[24]; struct i386_xfp_xstate_header header; - - unsigned char fp_yreg_word[16][16]; - /* space for the high part of the - * 16 256-bit YMM registers */ + unsigned char extended[0]; /* Extended region */ } __attribute__((packed, aligned(64))); -_Static_assert(sizeof(struct i386_xfp_save) == 512 + 8*8 + 16*16); +_Static_assert(sizeof(struct i386_xfp_save) == 512 + 8*8); /* * Control register |