lkml.org 
[lkml]   [2023]   [Dec]   [21]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v8 06/26] x86/fpu/xstate: Create guest fpstate with guest specific config
    Date
    Use fpu_guest_cfg to calculate guest fpstate settings, open code for
    __fpstate_reset() to avoid using kernel FPU config.

    Below configuration steps are currently enforced to get guest fpstate:
    1) Kernel sets up guest FPU settings in fpu__init_system_xstate().
    2) User space sets vCPU thread group xstate permits via arch_prctl().
    3) User space creates guest fpstate via __fpu_alloc_init_guest_fpstate()
    for vcpu thread.
    4) User space enables guest dynamic xfeatures and re-allocate guest
    fpstate.

    By adding kernel dynamic xfeatures in above #1 and #2, guest xstate area
    size is expanded to hold (fpu_kernel_cfg.default_features | kernel dynamic
    xfeatures | user dynamic xfeatures), then host xsaves/xrstors can operate
    for all guest xfeatures.

    The user_* fields remain unchanged for compatibility with KVM uAPIs.

    Signed-off-by: Yang Weijiang <weijiang.yang@intel.com>
    ---
    arch/x86/kernel/fpu/core.c | 47 ++++++++++++++++++++++++++++++--------
    1 file changed, 37 insertions(+), 10 deletions(-)

    diff --git a/arch/x86/kernel/fpu/core.c b/arch/x86/kernel/fpu/core.c
    index 976f519721e2..0e0bf151418f 100644
    --- a/arch/x86/kernel/fpu/core.c
    +++ b/arch/x86/kernel/fpu/core.c
    @@ -250,8 +250,6 @@ void fpu_reset_from_exception_fixup(void)
    }

    #if IS_ENABLED(CONFIG_KVM)
    -static void __fpstate_reset(struct fpstate *fpstate, u64 xfd);
    -
    static void fpu_init_guest_permissions(struct fpu_guest *gfpu)
    {
    struct fpu_state_perm *fpuperm;
    @@ -272,25 +270,54 @@ static void fpu_init_guest_permissions(struct fpu_guest *gfpu)
    gfpu->perm = perm & ~FPU_GUEST_PERM_LOCKED;
    }

    -bool fpu_alloc_guest_fpstate(struct fpu_guest *gfpu)
    +static struct fpstate *__fpu_alloc_init_guest_fpstate(struct fpu_guest *gfpu)
    {
    + bool compacted = cpu_feature_enabled(X86_FEATURE_XCOMPACTED);
    + unsigned int gfpstate_size, size;
    struct fpstate *fpstate;
    - unsigned int size;

    - size = fpu_user_cfg.default_size + ALIGN(offsetof(struct fpstate, regs), 64);
    + /*
    + * fpu_guest_cfg.default_size is initialized to hold all enabled
    + * xfeatures except the user dynamic xfeatures. If the user dynamic
    + * xfeatures are enabled, the guest fpstate will be re-allocated to
    + * hold all guest enabled xfeatures, so omit user dynamic xfeatures
    + * here.
    + */
    + size = fpu_guest_cfg.default_size +
    + ALIGN(offsetof(struct fpstate, regs), 64);
    +
    fpstate = vzalloc(size);
    if (!fpstate)
    - return false;
    + return NULL;
    + /*
    + * Initialize sizes and feature masks, use fpu_user_cfg.*
    + * for user_* settings for compatibility of exiting uAPIs.
    + */
    + fpstate->size = gfpstate_size;
    + fpstate->xfeatures = fpu_guest_cfg.default_features;
    + fpstate->user_size = fpu_user_cfg.default_size;
    + fpstate->user_xfeatures = fpu_user_cfg.default_features;
    + fpstate->xfd = 0;

    - /* Leave xfd to 0 (the reset value defined by spec) */
    - __fpstate_reset(fpstate, 0);
    fpstate_init_user(fpstate);
    fpstate->is_valloc = true;
    fpstate->is_guest = true;

    gfpu->fpstate = fpstate;
    - gfpu->xfeatures = fpu_user_cfg.default_features;
    - gfpu->perm = fpu_user_cfg.default_features;
    + gfpu->xfeatures = fpu_guest_cfg.default_features;
    + gfpu->perm = fpu_guest_cfg.default_features;
    +
    + return fpstate;
    +}
    +
    +bool fpu_alloc_guest_fpstate(struct fpu_guest *gfpu)
    +{
    + struct fpstate *fpstate;
    +
    + fpstate = __fpu_alloc_init_guest_fpstate(gfpu);
    +
    + if (!fpstate)
    + return false;

    /*
    * KVM sets the FP+SSE bits in the XSAVE header when copying FPU state
    --
    2.39.3

    \
     
     \ /
      Last update: 2023-12-21 10:14    [W:5.871 / U:0.012 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site