Commit 7f112e60 authored by Cyrill Gorcunov's avatar Cyrill Gorcunov Committed by Andrei Vagin

x86: cpu -- Make detailed verification of xsave elements in image

Signed-off-by: 's avatarCyrill Gorcunov <gorcunov@gmail.com>
Reviewed-by: 's avatarDmitry Safonov <0x7f454c46@gmail.com>
Signed-off-by: 's avatarAndrei Vagin <avagin@virtuozzo.com>
parent 9166f90e
...@@ -287,6 +287,7 @@ void arch_free_thread_info(CoreEntry *core) ...@@ -287,6 +287,7 @@ void arch_free_thread_info(CoreEntry *core)
static bool valid_xsave_frame(CoreEntry *core) static bool valid_xsave_frame(CoreEntry *core)
{ {
UserX86XsaveEntry *xsave = core->thread_info->fpregs->xsave;
struct xsave_struct *x = NULL; struct xsave_struct *x = NULL;
if (core->thread_info->fpregs->n_st_space < ARRAY_SIZE(x->i387.st_space)) { if (core->thread_info->fpregs->n_st_space < ARRAY_SIZE(x->i387.st_space)) {
...@@ -306,27 +307,76 @@ static bool valid_xsave_frame(CoreEntry *core) ...@@ -306,27 +307,76 @@ static bool valid_xsave_frame(CoreEntry *core)
} }
if (compel_cpu_has_feature(X86_FEATURE_OSXSAVE)) { if (compel_cpu_has_feature(X86_FEATURE_OSXSAVE)) {
if (core->thread_info->fpregs->xsave && if (xsave) {
core->thread_info->fpregs->xsave->n_ymmh_space < ARRAY_SIZE(x->ymmh.ymmh_space)) { size_t i;
pr_err("Corruption in FPU ymmh_space area " struct {
"(got %li but %li expected)\n", const char *name;
(long)core->thread_info->fpregs->xsave->n_ymmh_space, size_t expected;
(long)ARRAY_SIZE(x->ymmh.ymmh_space)); size_t obtained;
void *ptr;
} features[] = {
{
.name = __stringify_1(XFEATURE_YMM),
.expected = XSAVE_PB_NELEMS(struct ymmh_struct, xsave, ymmh_space),
.obtained = xsave->n_ymmh_space,
.ptr = xsave->ymmh_space,
}, {
.name = __stringify_1(XFEATURE_BNDREGS),
.expected = XSAVE_PB_NELEMS(struct mpx_bndreg_state, xsave, bndreg_state),
.obtained = xsave->n_bndreg_state,
.ptr = xsave->bndreg_state,
}, {
.name = __stringify_1(XFEATURE_BNDCSR),
.expected = XSAVE_PB_NELEMS(struct mpx_bndcsr_state, xsave, bndcsr_state),
.obtained = xsave->n_bndcsr_state,
.ptr = xsave->bndcsr_state,
}, {
.name = __stringify_1(XFEATURE_OPMASK),
.expected = XSAVE_PB_NELEMS(struct avx_512_opmask_state, xsave, opmask_reg),
.obtained = xsave->n_opmask_reg,
.ptr = xsave->opmask_reg,
}, {
.name = __stringify_1(XFEATURE_ZMM_Hi256),
.expected = XSAVE_PB_NELEMS(struct avx_512_zmm_uppers_state, xsave, zmm_upper),
.obtained = xsave->n_zmm_upper,
.ptr = xsave->zmm_upper,
}, {
.name = __stringify_1(XFEATURE_Hi16_ZMM),
.expected = XSAVE_PB_NELEMS(struct avx_512_hi16_state, xsave, hi16_zmm),
.obtained = xsave->n_hi16_zmm,
.ptr = xsave->hi16_zmm,
}, {
.name = __stringify_1(XFEATURE_PKRU),
.expected = XSAVE_PB_NELEMS(struct pkru_state, xsave, pkru),
.obtained = xsave->n_pkru,
.ptr = xsave->pkru,
},
};
for (i = 0; i < ARRAY_SIZE(features); i++) {
if (!features[i].ptr && i > 0)
continue;
if (features[i].expected > features[i].obtained) {
pr_err("Corruption in %s area (expected %zu but %zu obtained)\n",
features[i].name, features[i].expected, features[i].obtained);
return false; return false;
} }
}
}
} else { } else {
/* /*
* If the image has xsave area present then CPU we're restoring * If the image has xsave area present then CPU we're restoring
* on must have X86_FEATURE_OSXSAVE feature until explicitly * on must have X86_FEATURE_OSXSAVE feature until explicitly
* stated in options. * stated in options.
*/ */
if (core->thread_info->fpregs->xsave) { if (xsave) {
if (opts.cpu_cap & CPU_CAP_FPU) { if (opts.cpu_cap & CPU_CAP_FPU) {
pr_err("FPU xsave area present, " pr_err("FPU xsave area present, "
"but host cpu doesn't support it\n"); "but host cpu doesn't support it\n");
return false; return false;
} else } else
pr_warn_once("FPU is about to restore ignoring ymm state!\n"); pr_warn_once("FPU is about to restore ignoring xsave state!\n");
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment