x87 FPU の FOP 互換モードを有効にするカーネル モジュールを作成しようとしています。これは、IA32_MISC_ENABLE
MSR のビット 2 を設定することによって行われます。コードは次のとおりです。
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <asm/msr-index.h>
#include <asm/msr.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("10110111");
MODULE_DESCRIPTION("Module to enable FOPcode compatibility mode");
MODULE_VERSION("0.1");
static int __init fopCompat_init(void)
{
unsigned long long misc_enable=native_read_msr(MSR_IA32_MISC_ENABLE);
printk(KERN_INFO "Before trying to set FOP_COMPAT, IA32_MISC_ENABLE=%llx,"
" i.e. FOP_COMPAT is %senabled\n"
,misc_enable,misc_enable&MSR_IA32_MISC_ENABLE_X87_COMPAT?"":"NOT ");
wrmsrl(MSR_IA32_MISC_ENABLE,misc_enable|MSR_IA32_MISC_ENABLE_X87_COMPAT);
misc_enable=native_read_msr(MSR_IA32_MISC_ENABLE);
printk(KERN_INFO "Tried to set FOP_COMPAT. Result: IA32_MISC_ENABLE=%llx,"
" i.e. FOP_COMPAT is now %senabled\n"
,misc_enable,misc_enable&MSR_IA32_MISC_ENABLE_X87_COMPAT?"":"NOT ");
return 0;
}
static void __exit fopCompat_exit(void)
{
const unsigned long long misc_enable=native_read_msr(MSR_IA32_MISC_ENABLE);
printk(KERN_INFO "Quitting FOP-compat with IA32_MISC_ENABLE=%llx\n",misc_enable);
if(!(misc_enable & MSR_IA32_MISC_ENABLE_X87_COMPAT))
printk(KERN_INFO "NOTE: seems some CPUs still have to be set up, "
"or compatibility mode will work inconsistently\n");
printk(KERN_INFO "\n");
}
module_init(fopCompat_init);
module_exit(fopCompat_exit);
動作しているように見えますが、複数のinsmod/rmmod
サイクルdmesg
で、互換モードがまだ有効になっていないという出力が得られることがありますwrmsr
. 少し考えた後、モジュールコードが異なる論理CPUで実行されたためであることに気付きました(4コア* HT = 8論理CPUのCore i7を使用しています)rmmod
。このサイクルを約 20 回繰り返した後、一貫した「有効な」印刷が得られ、ユーザー空間アプリケーションはそれで問題なく動作しました。
そこで私の質問は、システムに存在するすべての論理 CPU でコードを実行して、すべての論理 CPU で互換モードを有効にするにはどうすればよいかということです。