/* * Enable and initialize the xsave feature. */ void __ref xsave_cntxt_init(void) { unsigned int eax, ebx, ecx, edx; cpuid_count(0xd, 0, &eax, &ebx, &ecx, &edx); pcntxt_mask = eax + ((u64)edx << 32); if ((pcntxt_mask & XSTATE_FPSSE) != XSTATE_FPSSE) { printk(KERN_ERR "FP/SSE not shown under xsave features 0x%llx\n", pcntxt_mask); BUG(); } /* * Support only the state known to OS. */ pcntxt_mask = pcntxt_mask & XCNTXT_MASK; xsave_init(); /* * Recompute the context size for enabled features */ cpuid_count(0xd, 0, &eax, &ebx, &ecx, &edx); xstate_size = ebx; prepare_fx_sw_frame(); setup_xstate_init(); printk(KERN_INFO "xsave/xrstor: enabled xstate_bv 0x%llx, " "cntxt size 0x%x\n", pcntxt_mask, xstate_size); }
/* * Enable and initialize the xsave feature. */ static void __init xstate_enable_boot_cpu(void) { unsigned int eax, ebx, ecx, edx; if (boot_cpu_data.cpuid_level < XSTATE_CPUID) { WARN(1, KERN_ERR "XSTATE_CPUID missing\n"); return; } cpuid_count(XSTATE_CPUID, 0, &eax, &ebx, &ecx, &edx); pcntxt_mask = eax + ((u64)edx << 32); if ((pcntxt_mask & XSTATE_FPSSE) != XSTATE_FPSSE) { printk(KERN_ERR "FP/SSE not shown under xsave features 0x%llx\n", pcntxt_mask); BUG(); } /* * Support only the state known to OS. */ pcntxt_mask = pcntxt_mask & XCNTXT_MASK; xstate_enable(); /* * Recompute the context size for enabled features */ cpuid_count(XSTATE_CPUID, 0, &eax, &ebx, &ecx, &edx); xstate_size = ebx; update_regset_xstate_info(xstate_size, pcntxt_mask); prepare_fx_sw_frame(); setup_xstate_init(); printk(KERN_INFO "xsave/xrstor: enabled xstate_bv 0x%llx, " "cntxt size 0x%x\n", pcntxt_mask, xstate_size); }