linux/arch/x86/kernel/fpu/xstate.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * xsave/xrstor support.
 *
 * Author: Suresh Siddha <[email protected]>
 */
#include <linux/bitops.h>
#include <linux/compat.h>
#include <linux/cpu.h>
#include <linux/mman.h>
#include <linux/nospec.h>
#include <linux/pkeys.h>
#include <linux/seq_file.h>
#include <linux/proc_fs.h>
#include <linux/vmalloc.h>
#include <linux/coredump.h>

#include <asm/fpu/api.h>
#include <asm/fpu/regset.h>
#include <asm/fpu/signal.h>
#include <asm/fpu/xcr.h>

#include <asm/tlbflush.h>
#include <asm/prctl.h>
#include <asm/elf.h>

#include <uapi/asm/elf.h>

#include "context.h"
#include "internal.h"
#include "legacy.h"
#include "xstate.h"

#define for_each_extended_xfeature(bit, mask)

/*
 * Although we spell it out in here, the Processor Trace
 * xfeature is completely unused.  We use other mechanisms
 * to save/restore PT state in Linux.
 */
static const char *xfeature_names[] =;

static unsigned short xsave_cpuid_features[] __initdata =;

static unsigned int xstate_offsets[XFEATURE_MAX] __ro_after_init =;
static unsigned int xstate_sizes[XFEATURE_MAX] __ro_after_init =;
static unsigned int xstate_flags[XFEATURE_MAX] __ro_after_init;

#define XSTATE_FLAG_SUPERVISOR
#define XSTATE_FLAG_ALIGNED64

/*
 * Return whether the system supports a given xfeature.
 *
 * Also return the name of the (most advanced) feature that the caller requested:
 */
int cpu_has_xfeatures(u64 xfeatures_needed, const char **feature_name)
{}
EXPORT_SYMBOL_GPL();

static bool xfeature_is_aligned64(int xfeature_nr)
{}

static bool xfeature_is_supervisor(int xfeature_nr)
{}

static unsigned int xfeature_get_offset(u64 xcomp_bv, int xfeature)
{}

/*
 * Enable the extended processor state save/restore feature.
 * Called once per CPU onlining.
 */
void fpu__init_cpu_xstate(void)
{}

static bool xfeature_enabled(enum xfeature xfeature)
{}

/*
 * Record the offsets and sizes of various xstates contained
 * in the XSAVE state memory layout.
 */
static void __init setup_xstate_cache(void)
{}

static void __init print_xstate_feature(u64 xstate_mask)
{}

/*
 * Print out all the supported xstate features:
 */
static void __init print_xstate_features(void)
{}

/*
 * This check is important because it is easy to get XSTATE_*
 * confused with XSTATE_BIT_*.
 */
#define CHECK_XFEATURE(nr)

/*
 * Print out xstate component offsets and sizes
 */
static void __init print_xstate_offset_size(void)
{}

/*
 * This function is called only during boot time when x86 caps are not set
 * up and alternative can not be used yet.
 */
static __init void os_xrstor_booting(struct xregs_state *xstate)
{}

/*
 * All supported features have either init state all zeros or are
 * handled in setup_init_fpu() individually. This is an explicit
 * feature list and does not use XFEATURE_MASK*SUPPORTED to catch
 * newly added supported features at build time and make people
 * actually look at the init state for the new feature.
 */
#define XFEATURES_INIT_FPSTATE_HANDLED

/*
 * setup the xstate image representing the init state
 */
static void __init setup_init_fpu_buf(void)
{}

int xfeature_size(int xfeature_nr)
{}

/* Validate an xstate header supplied by userspace (ptrace or sigreturn) */
static int validate_user_xstate_header(const struct xstate_header *hdr,
				       struct fpstate *fpstate)
{}

static void __init __xstate_dump_leaves(void)
{}

#define XSTATE_WARN_ON(x, fmt, ...)

#define XCHECK_SZ(sz, nr, __struct)


/**
 * check_xtile_data_against_struct - Check tile data state size.
 *
 * Calculate the state size by multiplying the single tile size which is
 * recorded in a C struct, and the number of tiles that the CPU informs.
 * Compare the provided size with the calculation.
 *
 * @size:	The tile data state size
 *
 * Returns:	0 on success, -EINVAL on mismatch.
 */
static int __init check_xtile_data_against_struct(int size)
{}

/*
 * We have a C struct for each 'xstate'.  We need to ensure
 * that our software representation matches what the CPU
 * tells us about the state's size.
 */
static bool __init check_xstate_against_struct(int nr)
{}

static unsigned int xstate_calculate_size(u64 xfeatures, bool compacted)
{}

/*
 * This essentially double-checks what the cpu told us about
 * how large the XSAVE buffer needs to be.  We are recalculating
 * it to be safe.
 *
 * Independent XSAVE features allocate their own buffers and are not
 * covered by these checks. Only the size of the buffer for task->fpu
 * is checked here.
 */
static bool __init paranoid_xstate_size_valid(unsigned int kernel_size)
{}

/*
 * Get total size of enabled xstates in XCR0 | IA32_XSS.
 *
 * Note the SDM's wording here.  "sub-function 0" only enumerates
 * the size of the *user* states.  If we use it to size a buffer
 * that we use 'XSAVES' on, we could potentially overflow the
 * buffer because 'XSAVES' saves system states too.
 *
 * This also takes compaction into account. So this works for
 * XSAVEC as well.
 */
static unsigned int __init get_compacted_size(void)
{}

/*
 * Get the total size of the enabled xstates without the independent supervisor
 * features.
 */
static unsigned int __init get_xsave_compacted_size(void)
{}

static unsigned int __init get_xsave_size_user(void)
{}

static int __init init_xstate_size(void)
{}

/*
 * We enabled the XSAVE hardware, but something went wrong and
 * we can not use it.  Disable it.
 */
static void __init fpu__init_disable_system_xstate(unsigned int legacy_size)
{}

/*
 * Enable and initialize the xsave feature.
 * Called once per system bootup.
 */
void __init fpu__init_system_xstate(unsigned int legacy_size)
{}

/*
 * Restore minimal FPU state after suspend:
 */
void fpu__resume_cpu(void)
{}

/*
 * Given an xstate feature nr, calculate where in the xsave
 * buffer the state is.  Callers should ensure that the buffer
 * is valid.
 */
static void *__raw_xsave_addr(struct xregs_state *xsave, int xfeature_nr)
{}

/*
 * Given the xsave area and a state inside, this function returns the
 * address of the state.
 *
 * This is the API that is called to get xstate address in either
 * standard format or compacted format of xsave area.
 *
 * Note that if there is no data for the field in the xsave buffer
 * this will return NULL.
 *
 * Inputs:
 *	xstate: the thread's storage area for all FPU data
 *	xfeature_nr: state which is defined in xsave.h (e.g. XFEATURE_FP,
 *	XFEATURE_SSE, etc...)
 * Output:
 *	address of the state in the xsave area, or NULL if the
 *	field is not present in the xsave buffer.
 */
void *get_xsave_addr(struct xregs_state *xsave, int xfeature_nr)
{}
EXPORT_SYMBOL_GPL();

/*
 * Given an xstate feature nr, calculate where in the xsave buffer the state is.
 * The xsave buffer should be in standard format, not compacted (e.g. user mode
 * signal frames).
 */
void __user *get_xsave_addr_user(struct xregs_state __user *xsave, int xfeature_nr)
{}

#ifdef CONFIG_ARCH_HAS_PKEYS

/*
 * This will go out and modify PKRU register to set the access
 * rights for @pkey to @init_val.
 */
int arch_set_user_pkey_access(struct task_struct *tsk, int pkey,
			      unsigned long init_val)
{}
#endif /* ! CONFIG_ARCH_HAS_PKEYS */

static void copy_feature(bool from_xstate, struct membuf *to, void *xstate,
			 void *init_xstate, unsigned int size)
{}

/**
 * __copy_xstate_to_uabi_buf - Copy kernel saved xstate to a UABI buffer
 * @to:		membuf descriptor
 * @fpstate:	The fpstate buffer from which to copy
 * @xfeatures:	The mask of xfeatures to save (XSAVE mode only)
 * @pkru_val:	The PKRU value to store in the PKRU component
 * @copy_mode:	The requested copy mode
 *
 * Converts from kernel XSAVE or XSAVES compacted format to UABI conforming
 * format, i.e. from the kernel internal hardware dependent storage format
 * to the requested @mode. UABI XSTATE is always uncompacted!
 *
 * It supports partial copy but @to.pos always starts from zero.
 */
void __copy_xstate_to_uabi_buf(struct membuf to, struct fpstate *fpstate,
			       u64 xfeatures, u32 pkru_val,
			       enum xstate_copy_mode copy_mode)
{}

/**
 * copy_xstate_to_uabi_buf - Copy kernel saved xstate to a UABI buffer
 * @to:		membuf descriptor
 * @tsk:	The task from which to copy the saved xstate
 * @copy_mode:	The requested copy mode
 *
 * Converts from kernel XSAVE or XSAVES compacted format to UABI conforming
 * format, i.e. from the kernel internal hardware dependent storage format
 * to the requested @mode. UABI XSTATE is always uncompacted!
 *
 * It supports partial copy but @to.pos always starts from zero.
 */
void copy_xstate_to_uabi_buf(struct membuf to, struct task_struct *tsk,
			     enum xstate_copy_mode copy_mode)
{}

static int copy_from_buffer(void *dst, unsigned int offset, unsigned int size,
			    const void *kbuf, const void __user *ubuf)
{}


/**
 * copy_uabi_to_xstate - Copy a UABI format buffer to the kernel xstate
 * @fpstate:	The fpstate buffer to copy to
 * @kbuf:	The UABI format buffer, if it comes from the kernel
 * @ubuf:	The UABI format buffer, if it comes from userspace
 * @pkru:	The location to write the PKRU value to
 *
 * Converts from the UABI format into the kernel internal hardware
 * dependent format.
 *
 * This function ultimately has three different callers with distinct PKRU
 * behavior.
 * 1.	When called from sigreturn the PKRU register will be restored from
 *	@fpstate via an XRSTOR. Correctly copying the UABI format buffer to
 *	@fpstate is sufficient to cover this case, but the caller will also
 *	pass a pointer to the thread_struct's pkru field in @pkru and updating
 *	it is harmless.
 * 2.	When called from ptrace the PKRU register will be restored from the
 *	thread_struct's pkru field. A pointer to that is passed in @pkru.
 *	The kernel will restore it manually, so the XRSTOR behavior that resets
 *	the PKRU register to the hardware init value (0) if the corresponding
 *	xfeatures bit is not set is emulated here.
 * 3.	When called from KVM the PKRU register will be restored from the vcpu's
 *	pkru field. A pointer to that is passed in @pkru. KVM hasn't used
 *	XRSTOR and hasn't had the PKRU resetting behavior described above. To
 *	preserve that KVM behavior, it passes NULL for @pkru if the xfeatures
 *	bit is not set.
 */
static int copy_uabi_to_xstate(struct fpstate *fpstate, const void *kbuf,
			       const void __user *ubuf, u32 *pkru)
{}

/*
 * Convert from a ptrace standard-format kernel buffer to kernel XSAVE[S]
 * format and copy to the target thread. Used by ptrace and KVM.
 */
int copy_uabi_from_kernel_to_xstate(struct fpstate *fpstate, const void *kbuf, u32 *pkru)
{}

/*
 * Convert from a sigreturn standard-format user-space buffer to kernel
 * XSAVE[S] format and copy to the target thread. This is called from the
 * sigreturn() and rt_sigreturn() system calls.
 */
int copy_sigframe_from_user_to_xstate(struct task_struct *tsk,
				      const void __user *ubuf)
{}

static bool validate_independent_components(u64 mask)
{}

/**
 * xsaves - Save selected components to a kernel xstate buffer
 * @xstate:	Pointer to the buffer
 * @mask:	Feature mask to select the components to save
 *
 * The @xstate buffer must be 64 byte aligned and correctly initialized as
 * XSAVES does not write the full xstate header. Before first use the
 * buffer should be zeroed otherwise a consecutive XRSTORS from that buffer
 * can #GP.
 *
 * The feature mask must be a subset of the independent features.
 */
void xsaves(struct xregs_state *xstate, u64 mask)
{}

/**
 * xrstors - Restore selected components from a kernel xstate buffer
 * @xstate:	Pointer to the buffer
 * @mask:	Feature mask to select the components to restore
 *
 * The @xstate buffer must be 64 byte aligned and correctly initialized
 * otherwise XRSTORS from that buffer can #GP.
 *
 * Proper usage is to restore the state which was saved with
 * xsaves() into @xstate.
 *
 * The feature mask must be a subset of the independent features.
 */
void xrstors(struct xregs_state *xstate, u64 mask)
{}

#if IS_ENABLED(CONFIG_KVM)
void fpstate_clear_xstate_component(struct fpstate *fps, unsigned int xfeature)
{}
EXPORT_SYMBOL_GPL();
#endif

#ifdef CONFIG_X86_64

#ifdef CONFIG_X86_DEBUG_FPU
/*
 * Ensure that a subsequent XSAVE* or XRSTOR* instruction with RFBM=@mask
 * can safely operate on the @fpstate buffer.
 */
static bool xstate_op_valid(struct fpstate *fpstate, u64 mask, bool rstor)
{}

void xfd_validate_state(struct fpstate *fpstate, u64 mask, bool rstor)
{}
#endif /* CONFIG_X86_DEBUG_FPU */

static int __init xfd_update_static_branch(void)
{}
arch_initcall()

void fpstate_free(struct fpu *fpu)
{}

/**
 * fpstate_realloc - Reallocate struct fpstate for the requested new features
 *
 * @xfeatures:	A bitmap of xstate features which extend the enabled features
 *		of that task
 * @ksize:	The required size for the kernel buffer
 * @usize:	The required size for user space buffers
 * @guest_fpu:	Pointer to a guest FPU container. NULL for host allocations
 *
 * Note vs. vmalloc(): If the task with a vzalloc()-allocated buffer
 * terminates quickly, vfree()-induced IPIs may be a concern, but tasks
 * with large states are likely to live longer.
 *
 * Returns: 0 on success, -ENOMEM on allocation error.
 */
static int fpstate_realloc(u64 xfeatures, unsigned int ksize,
			   unsigned int usize, struct fpu_guest *guest_fpu)
{}

static int validate_sigaltstack(unsigned int usize)
{}

static int __xstate_request_perm(u64 permitted, u64 requested, bool guest)
{}

/*
 * Permissions array to map facilities with more than one component
 */
static const u64 xstate_prctl_req[XFEATURE_MAX] =;

static int xstate_request_perm(unsigned long idx, bool guest)
{}

int __xfd_enable_feature(u64 xfd_err, struct fpu_guest *guest_fpu)
{}

int xfd_enable_feature(u64 xfd_err)
{}

#else /* CONFIG_X86_64 */
static inline int xstate_request_perm(unsigned long idx, bool guest)
{
	return -EPERM;
}
#endif  /* !CONFIG_X86_64 */

u64 xstate_get_guest_group_perm(void)
{}
EXPORT_SYMBOL_GPL();

/**
 * fpu_xstate_prctl - xstate permission operations
 * @option:	A subfunction of arch_prctl()
 * @arg2:	option argument
 * Return:	0 if successful; otherwise, an error code
 *
 * Option arguments:
 *
 * ARCH_GET_XCOMP_SUPP: Pointer to user space u64 to store the info
 * ARCH_GET_XCOMP_PERM: Pointer to user space u64 to store the info
 * ARCH_REQ_XCOMP_PERM: Facility number requested
 *
 * For facilities which require more than one XSTATE component, the request
 * must be the highest state component number related to that facility,
 * e.g. for AMX which requires XFEATURE_XTILE_CFG(17) and
 * XFEATURE_XTILE_DATA(18) this would be XFEATURE_XTILE_DATA(18).
 */
long fpu_xstate_prctl(int option, unsigned long arg2)
{}

#ifdef CONFIG_PROC_PID_ARCH_STATUS
/*
 * Report the amount of time elapsed in millisecond since last AVX512
 * use in the task.
 */
static void avx512_status(struct seq_file *m, struct task_struct *task)
{}

/*
 * Report architecture specific information
 */
int proc_pid_arch_status(struct seq_file *m, struct pid_namespace *ns,
			struct pid *pid, struct task_struct *task)
{}
#endif /* CONFIG_PROC_PID_ARCH_STATUS */

#ifdef CONFIG_COREDUMP
static const char owner_name[] =;

/*
 * Dump type, size, offset and flag values for every xfeature that is present.
 */
static int dump_xsave_layout_desc(struct coredump_params *cprm)
{}

static u32 get_xsave_desc_size(void)
{}

int elf_coredump_extra_notes_write(struct coredump_params *cprm)
{}

int elf_coredump_extra_notes_size(void)
{}
#endif /* CONFIG_COREDUMP */