3

x87 FPU の FOP 互換モードを有効にするカーネル モジュールを作成しようとしています。これは、IA32_MISC_ENABLEMSR のビット 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 で互換モードを有効にするにはどうすればよいかということです。

4

1 に答える 1

6

on_each_cpuすべての CPU 使用関数でコードを実行する場合。

サイン:

int on_each_cpu(void (*func) (void *info), void *info, int wait)

説明:

すべてのプロセッサで関数を呼び出します。

パラメータwaitがゼロ以外の場合、すべての CPU で関数の完了を待ちます。

関数funcはスリープ状態にすべきではありませんが、呼び出し全体on_each_cpu()をアトミック コンテキストで実行するべきではありません。

于 2016-01-06T14:45:02.813 に答える