Commit 84e4dccc authored by Chang S. Bae's avatar Chang S. Bae Committed by Borislav Petkov
Browse files

x86/fpu/xstate: Provide xstate_calculate_size()



Split out the size calculation from the paranoia check so it can be used
for recalculating buffer sizes when dynamically enabled features are
supported.

Signed-off-by: default avatarChang S. Bae <chang.seok.bae@intel.com>
[ tglx: Adopted to changed base code ]
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Signed-off-by: default avatarChang S. Bae <chang.seok.bae@intel.com>
Signed-off-by: default avatarBorislav Petkov <bp@suse.de>
Link: https://lkml.kernel.org/r/20211021225527.10184-4-chang.seok.bae@intel.com
parent 3aac3ebe
Loading
Loading
Loading
Loading
+28 −18
Original line number Diff line number Diff line
@@ -549,6 +549,33 @@ static bool __init check_xstate_against_struct(int nr)
	return true;
}

static unsigned int xstate_calculate_size(u64 xfeatures, bool compacted)
{
	unsigned int size = FXSAVE_SIZE + XSAVE_HDR_SIZE;
	int i;

	for_each_extended_xfeature(i, xfeatures) {
		/* Align from the end of the previous feature */
		if (xfeature_is_aligned(i))
			size = ALIGN(size, 64);
		/*
		 * In compacted format the enabled features are packed,
		 * i.e. disabled features do not occupy space.
		 *
		 * In non-compacted format the offsets are fixed and
		 * disabled states still occupy space in the memory buffer.
		 */
		if (!compacted)
			size = xfeature_uncompacted_offset(i);
		/*
		 * Add the feature size even for non-compacted format
		 * to make the end result correct
		 */
		size += xfeature_size(i);
	}
	return size;
}

/*
 * This essentially double-checks what the cpu told us about
 * how large the XSAVE buffer needs to be.  We are recalculating
@@ -575,25 +602,8 @@ static bool __init paranoid_xstate_size_valid(unsigned int kernel_size)
			XSTATE_WARN_ON(1);
			return false;
		}

		/* Align from the end of the previous feature */
		if (xfeature_is_aligned(i))
			size = ALIGN(size, 64);
		/*
		 * In compacted format the enabled features are packed,
		 * i.e. disabled features do not occupy space.
		 *
		 * In non-compacted format the offsets are fixed and
		 * disabled states still occupy space in the memory buffer.
		 */
		if (!compacted)
			size = xfeature_uncompacted_offset(i);
		/*
		 * Add the feature size even for non-compacted format
		 * to make the end result correct
		 */
		size += xfeature_size(i);
	}
	size = xstate_calculate_size(fpu_kernel_cfg.max_features, compacted);
	XSTATE_WARN_ON(size != kernel_size);
	return size == kernel_size;
}