|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH RFC] x86/EFI: allow FPU/XMM use in runtime service functions
>>> On 11.06.14 at 10:53, <JBeulich@xxxxxxxx> wrote:
> UEFI spec update 2.4B developed a requirement to enter runtime service
> functions with CR0.TS (and CR0.EM) clear, thus making feasible the
> already previously stated permission for these functions to use some of
> the XMM registers. Enforce this requirement (along with the connected
> ones on FPU control word and MXCSR) by going through a full FPU save
> cycle (if the FPU was dirty) in efi_rs_enter() (along with loading the
> specified values into the other two registers).
>
> Note that the UEFI spec mandates that extension registers other than
> XMM ones (for our purposes all that get restored eagerly) are preserved
> across runtime function calls, hence there's nothing we need to restore
> in efi_rs_leave() (they do get saved, but just for simplicity's sake).
>
> Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
> ---
> RFC because the patch is yet to be tested on a system where XMM
> registers are actually being used by runtime service calls.
Successful testing (on 4.4) has just been reported back, so unless I
hear objections I'm intending to commit this without submitting a 2nd
time without the RFC tag.
Jan
> --- a/xen/arch/x86/efi/runtime.c
> +++ b/xen/arch/x86/efi/runtime.c
> @@ -10,6 +10,8 @@ DEFINE_XEN_GUEST_HANDLE(CHAR16);
>
> #ifndef COMPAT
>
> +# include <asm/i387.h>
> +# include <asm/xstate.h>
> # include <public/platform.h>
>
> const bool_t efi_enabled = 1;
> @@ -45,8 +47,14 @@ const struct efi_pci_rom *__read_mostly
>
> unsigned long efi_rs_enter(void)
> {
> + static const u16 fcw = FCW_DEFAULT;
> + static const u32 mxcsr = MXCSR_DEFAULT;
> unsigned long cr3 = read_cr3();
>
> + save_fpu_enable();
> + asm volatile ( "fldcw %0" :: "m" (fcw) );
> + asm volatile ( "ldmxcsr %0" :: "m" (mxcsr) );
> +
> spin_lock(&efi_rs_lock);
>
> /* prevent fixup_page_fault() from doing anything */
> @@ -82,6 +90,7 @@ void efi_rs_leave(unsigned long cr3)
> }
> irq_exit();
> spin_unlock(&efi_rs_lock);
> + stts();
> }
>
> unsigned long efi_get_time(void)
> --- a/xen/arch/x86/i387.c
> +++ b/xen/arch/x86/i387.c
> @@ -266,10 +266,10 @@ void vcpu_restore_fpu_lazy(struct vcpu *
> * On each context switch, save the necessary FPU info of VCPU being switch
>
> * out. It dispatches saving operation based on CPU's capability.
> */
> -void vcpu_save_fpu(struct vcpu *v)
> +static bool_t _vcpu_save_fpu(struct vcpu *v)
> {
> if ( !v->fpu_dirtied && !v->arch.nonlazy_xstate_used )
> - return;
> + return 0;
>
> ASSERT(!is_idle_vcpu(v));
>
> @@ -284,9 +284,22 @@ void vcpu_save_fpu(struct vcpu *v)
> fpu_fsave(v);
>
> v->fpu_dirtied = 0;
> +
> + return 1;
> +}
> +
> +void vcpu_save_fpu(struct vcpu *v)
> +{
> + _vcpu_save_fpu(v);
> stts();
> }
>
> +void save_fpu_enable(void)
> +{
> + if ( !_vcpu_save_fpu(current) )
> + clts();
> +}
> +
> /* Initialize FPU's context save area */
> int vcpu_init_fpu(struct vcpu *v)
> {
> --- a/xen/include/asm-x86/i387.h
> +++ b/xen/include/asm-x86/i387.h
> @@ -38,6 +38,7 @@ struct ix87_state {
> void vcpu_restore_fpu_eager(struct vcpu *v);
> void vcpu_restore_fpu_lazy(struct vcpu *v);
> void vcpu_save_fpu(struct vcpu *v);
> +void save_fpu_enable(void);
>
> int vcpu_init_fpu(struct vcpu *v);
> void vcpu_destroy_fpu(struct vcpu *v);
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |