All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Wang, Wei W" <wei.w.wang@intel.com>
To: Thomas Gleixner <tglx@linutronix.de>,
	LKML <linux-kernel@vger.kernel.org>
Cc: Jing Liu <jing2.liu@linux.intel.com>,
	"Zhong, Yang" <yang.zhong@intel.com>,
	Paolo Bonzini <pbonzini@redhat.com>,
	"x86@kernel.org" <x86@kernel.org>,
	"kvm@vger.kernel.org" <kvm@vger.kernel.org>,
	"Sean Christoperson" <seanjc@google.com>,
	"Nakajima, Jun" <jun.nakajima@intel.com>,
	"Tian, Kevin" <kevin.tian@intel.com>
Subject: RE: [patch 5/6] x86/fpu: Provide fpu_update_guest_xcr0/xfd()
Date: Tue, 14 Dec 2021 15:09:54 +0000	[thread overview]
Message-ID: <854480525e7f4f3baeba09ec6a864b80@intel.com> (raw)
In-Reply-To: <20211214024948.048572883@linutronix.de>

On Tuesday, December 14, 2021 10:50 AM, Thomas Gleixner wrote:
> KVM can require fpstate expansion due to updates to XCR0 and to the XFD
> MSR. In both cases it is required to check whether:
> 
>   - the requested values are correct or permitted
> 
>   - the resulting xfeature mask which is relevant for XSAVES is a subset of
>     the guests fpstate xfeature mask for which the register buffer is sized.
> 
>     If the feature mask does not fit into the guests fpstate then
>     reallocation is required.
> 
> Provide a common update function which utilizes the existing XFD
> enablement mechanics and two wrapper functions, one for XCR0 and one
> for XFD.
> 
> These wrappers have to be invoked from XSETBV emulation and the XFD
> MSR write emulation.
> 
> XCR0 modification can only proceed when fpu_update_guest_xcr0() returns
> success.
> 
> XFD modification is done by the FPU core code as it requires to update the
> software state as well.
> 
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> ---
> New version to handle the restore case and XCR0 updates correctly.
> ---
>  arch/x86/include/asm/fpu/api.h |   57
> +++++++++++++++++++++++++++++++++++++++++
>  arch/x86/kernel/fpu/core.c     |   57
> +++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 114 insertions(+)
> 
> --- a/arch/x86/include/asm/fpu/api.h
> +++ b/arch/x86/include/asm/fpu/api.h
> @@ -136,6 +136,63 @@ extern void fpstate_clear_xstate_compone
> extern bool fpu_alloc_guest_fpstate(struct fpu_guest *gfpu);  extern void
> fpu_free_guest_fpstate(struct fpu_guest *gfpu);  extern int
> fpu_swap_kvm_fpstate(struct fpu_guest *gfpu, bool enter_guest);
> +extern int __fpu_update_guest_features(struct fpu_guest *guest_fpu, u64
> +xcr0, u64 xfd);
> +
> +/**
> + * fpu_update_guest_xcr0 - Update guest XCR0 from XSETBV emulation
> + * @guest_fpu:	Pointer to the guest FPU container
> + * @xcr0:	Requested guest XCR0
> + *
> + * Has to be invoked before making the guest XCR0 update effective. The
> + * function validates that the requested features are permitted and
> +ensures
> + * that @guest_fpu->fpstate is properly sized taking
> +@guest_fpu->fpstate->xfd
> + * into account.
> + *
> + * If @guest_fpu->fpstate is not the current tasks active fpstate then
> +the
> + * caller has to ensure that @guest_fpu->fpstate cannot be concurrently
> +in
> + * use, i.e. the guest restore case.
> + *
> + * Return:
> + * 0		- Success
> + * -EPERM	- Feature(s) not permitted
> + * -EFAULT	- Resizing of fpstate failed
> + */
> +static inline int fpu_update_guest_xcr0(struct fpu_guest *guest_fpu,
> +u64 xcr0) {
> +	return __fpu_update_guest_features(guest_fpu, xcr0,
> +guest_fpu->fpstate->xfd); }
> +
> +/**
> + * fpu_update_guest_xfd - Update guest XFD from MSR write emulation
> + * @guest_fpu:	Pointer to the guest FPU container
> + * @xcr0:	Current guest XCR0
> + * @xfd:	Requested XFD value
> + *
> + * Has to be invoked to make the guest XFD update effective. The
> +function
> + * validates the XFD value and ensures that @guest_fpu->fpstate is
> +properly
> + * sized by taking @xcr0 into account.
> + *
> + * The caller must not modify @guest_fpu->fpstate->xfd or the XFD MSR
> + * directly.
> + *
> + * If @guest_fpu->fpstate is not the current tasks active fpstate then
> +the
> + * caller has to ensure that @guest_fpu->fpstate cannot be concurrently
> +in
> + * use, i.e. the guest restore case.
> + *
> + * On success the buffer size is valid, @guest_fpu->fpstate.xfd == @xfd
> +and
> + * if the guest fpstate is active then MSR_IA32_XFD == @xfd.
> + *
> + * On failure the previous state is retained.
> + *
> + * Return:
> + * 0		- Success
> + * -ENOTSUPP	- XFD value not supported
> + * -EFAULT	- Resizing of fpstate failed
> + */
> +static inline int fpu_update_guest_xfd(struct fpu_guest *guest_fpu, u64
> +xcr0, u64 xfd) {
> +	return __fpu_update_guest_features(guest_fpu, xcr0, xfd); }
> 
>  extern void fpu_copy_guest_fpstate_to_uabi(struct fpu_guest *gfpu, void
> *buf, unsigned int size, u32 pkru);  extern int
> fpu_copy_uabi_to_guest_fpstate(struct fpu_guest *gfpu, const void *buf,
> u64 xcr0, u32 *vpkru);
> --- a/arch/x86/kernel/fpu/core.c
> +++ b/arch/x86/kernel/fpu/core.c
> @@ -261,6 +261,63 @@ void fpu_free_guest_fpstate(struct fpu_g  }
> EXPORT_SYMBOL_GPL(fpu_free_guest_fpstate);
> 
> +/**
> + * __fpu_update_guest_features - Validate and enable guest XCR0 and XFD
> updates
> + * @guest_fpu:	Pointer to the guest FPU container
> + * @xcr0:	Guest XCR0
> + * @xfd:	Guest XFD
> + *
> + * Note: @xcr0 and @xfd must either be the already validated values or
> +the
> + * requested values (guest emulation or host write on restore).
> + *
> + * Do not invoke directly. Use the provided wrappers
> +fpu_validate_guest_xcr0()
> + * and fpu_update_guest_xfd() instead.
> + *
> + * Return: 0 on success, error code otherwise  */ int
> +__fpu_update_guest_features(struct fpu_guest *guest_fpu, u64 xcr0, u64
> +xfd) {

I think there would be one issue for the "host write on restore" case.
The current QEMU based host restore uses the following sequence:
1) restore xsave
2) restore xcr0
3) restore XFD MSR

At the time of "1) restore xsave", KVM already needs fpstate expansion before restoring the xsave data.
So the 2 APIs here might not be usable for this usage.
Our current solution to fpstate expansion at KVM_SET_XSAVE (i.e. step 1) above) is:

kvm_load_guest_fpu(vcpu);
guest_fpu->realloc_request = realloc_request;
kvm_put_guest_fpu(vcpu);

"realloc_request" above is generated from the "xstate_header" received from userspace.

Thanks,
Wei


  parent reply	other threads:[~2021-12-14 15:10 UTC|newest]

Thread overview: 47+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-12-14  2:50 [patch 0/6] x86/fpu: Preparatory changes for guest AMX support Thomas Gleixner
2021-12-14  2:50 ` [patch 1/6] x86/fpu: Extend fpu_xstate_prctl() with guest permissions Thomas Gleixner
2021-12-14  5:13   ` Tian, Kevin
2021-12-14 10:37     ` Paolo Bonzini
2021-12-14  2:50 ` [patch 2/6] x86/fpu: Prepare guest FPU for dynamically enabled FPU features Thomas Gleixner
2021-12-14  2:50 ` [patch 3/6] x86/fpu: Make XFD initialization in __fpstate_reset() a function argument Thomas Gleixner
2021-12-14  2:50 ` [patch 4/6] x86/fpu: Add guest support to xfd_enable_feature() Thomas Gleixner
2021-12-14  6:05   ` Tian, Kevin
2021-12-14 10:21     ` Paolo Bonzini
2021-12-14 13:15       ` Thomas Gleixner
2021-12-15  5:46         ` Tian, Kevin
2021-12-15  9:53           ` Thomas Gleixner
2021-12-15 10:02             ` Tian, Kevin
2021-12-14  2:50 ` [patch 5/6] x86/fpu: Provide fpu_update_guest_xcr0/xfd() Thomas Gleixner
2021-12-14  6:25   ` Tian, Kevin
2021-12-14 15:09   ` Wang, Wei W [this message]
2021-12-14 15:40     ` Thomas Gleixner
2021-12-14 16:11       ` Wang, Wei W
2021-12-14 18:04         ` Thomas Gleixner
2021-12-14 19:07           ` Juan Quintela
2021-12-14 20:28             ` Thomas Gleixner
2021-12-14 21:35               ` Juan Quintela
2021-12-15  2:17                 ` Wang, Wei W
2021-12-15 10:09                   ` Thomas Gleixner
2021-12-15 10:27                     ` Paolo Bonzini
2021-12-15 10:41                       ` Paolo Bonzini
2021-12-16  1:00                         ` Tian, Kevin
2021-12-16  5:36                         ` Tian, Kevin
2021-12-16 21:07                           ` Paolo Bonzini
2021-12-16 10:21                         ` Tian, Kevin
2021-12-16 10:24                           ` Paolo Bonzini
2021-12-16 10:26                           ` Paolo Bonzini
2021-12-16 13:00                         ` Tian, Kevin
2021-12-16  1:04                       ` Tian, Kevin
2021-12-16  9:34                         ` Thomas Gleixner
2021-12-16  9:59                           ` Tian, Kevin
2021-12-16 14:12                             ` Thomas Gleixner
2021-12-17 15:33                               ` Tian, Kevin
2021-12-15  6:14   ` Tian, Kevin
2021-12-14  2:50 ` [patch 6/6] x86/fpu: Provide kvm_sync_guest_vmexit_xfd_state() Thomas Gleixner
2021-12-15  6:35   ` Liu, Jing2
2021-12-15  9:49     ` Thomas Gleixner
2021-12-14  6:50 ` [patch 0/6] x86/fpu: Preparatory changes for guest AMX support Tian, Kevin
2021-12-14  6:52 ` Liu, Jing2
2021-12-14  7:54   ` Tian, Kevin
2021-12-14 10:42 ` Paolo Bonzini
2021-12-14 13:24   ` Thomas Gleixner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=854480525e7f4f3baeba09ec6a864b80@intel.com \
    --to=wei.w.wang@intel.com \
    --cc=jing2.liu@linux.intel.com \
    --cc=jun.nakajima@intel.com \
    --cc=kevin.tian@intel.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=pbonzini@redhat.com \
    --cc=seanjc@google.com \
    --cc=tglx@linutronix.de \
    --cc=x86@kernel.org \
    --cc=yang.zhong@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.