在Intel CPU上设置写缓存策略以进行回写

时间:2015-11-11 19:07:55

标签: caching kernel cpu intel

我正在尝试将CPU缓存写入策略设置为“回写”,因此我需要设置CR0.NW = 1.

我写了一个内核模块:

int
init_module (void)
{
  printk (KERN_INFO "init_module\n\n\n");
  uint64_t cr0;
  asm volatile ("mov %%cr0,%%rax\n\t":"=a"(cr0));
  printk(KERN_INFO"CR0 ===== %ld\n",cr0);

  asm volatile("push %rax\n\t" "push %rbx\n\t");

    asm volatile( //disable cache before changing cr0.nw
    "mov $1,%rbx\n\t"
    "shl $30,%rbx\n\t"
    "mov %cr0,%rax\n\t"
    "xor %rbx,%rax\n\t"
    "mov %rax,%cr0\n\t"
    "wbinvd\n\t"  //flush
  );

  asm volatile( //invert bit
    "mov $1,%rbx\n\t"
    "shl $29,%rbx\n\t"
    "mov %cr0,%rax\n\t"
    "xor %rbx,%rax\n\t"
    "mov %rax,%cr0\n\t"
  );

      asm volatile( //enable cache
        "mov $1,%rbx\n\t"
        "shl $30,%rbx\n\t"
        "mov %cr0,%rax\n\t"
        "xor %rbx,%rax\n\t" //xor : 1 => 0 , 0 => 1
       "mov %rax,%cr0\n\t"
       "wbinvd\n\t"  //flush
    );
     asm volatile("pop %rbx\n\t" "pop %rax\n\t");
    return 0;
    }

但它不起作用。 dmesg给我:

[ 1190.301973] general protection fault: 0000 [#1] SMP
[ 1190.301975] Modules linked in: cache(POE+) ipt_MASQUERADE iptable_nat nf_nat_ipv4 nf_nat nf_conntrack_ipv4 nf_defrag_ipv4 xt_conntrack nf_conntrack ipt_REJECT xt_CHECKSUM iptable_mangle xt_tcpudp bridge stp llc ip6table_filter ip6_tables iptable_filter ip_tables ebtable_nat ebtables x_tables bnep rfcomm bluetooth 6lowpan_iphc binfmt_misc nls_iso8859_1 nvidia(POE) cp210x usbserial joydev snd_hda_codec_hdmi eeepc_wmi asus_wmi sparse_keymap snd_hda_codec_realtek snd_hda_codec_generic intel_rapl snd_hda_intel x86_pkg_temp_thermal intel_powerclamp snd_hda_controller coretemp snd_hda_codec kvm_intel snd_hwdep snd_pcm kvm snd_seq_midi snd_seq_midi_event crct10dif_pclmul crc32_pclmul snd_rawmidi ghash_clmulni_intel aesni_intel snd_seq aes_x86_64 lrw gf128mul glue_helper ablk_helper cryptd nouveau serio_raw mxm_wmi ttm snd_seq_device snd_timer lpc_ich drm_kms_helper drm snd mei_me mei soundcore i2c_algo_bit shpchp wmi video mac_hid soc_button_array tpm_infineon parport_pc ppdev lp parport uas usb_storage hid_generic usbhid hid ahci r8169 psmouse libahci mii
[ 1190.302013] CPU: 5 PID: 5159 Comm: insmod Tainted: P           OE 3.16.0-45-generic #60~14.04.1-Ubuntu
[ 1190.302014] Hardware name: ASUS All Series/Z87-A, BIOS 1007 05/17/2013
[ 1190.302015] task: ffff8807d95765e0 ti: ffff8807d95b0000 task.ti: ffff8807d95b0000
[ 1190.302016] RIP: 0010:[<ffffffffc0fd402a>]  [<ffffffffc0fd402a>] init_module+0x2a/0x40 [cache]
[ 1190.302019] RSP: 0018:ffff8807d95b3d30  EFLAGS: 00010206
[ 1190.302019] RAX: 00000000a0050033 RBX: 0000000020000000 RCX: 0000000000000000
[ 1190.302020] RDX: ffff88081ed4ee40 RSI: ffff88081ed4d418 RDI: 0000000000000246
[ 1190.302021] RBP: ffff8807d95b3d40 R08: 0000000000000082 R09: 00000000000012e5
[ 1190.302022] R10: 0000000000000000 R11: ffff8807d95b3a5e R12: ffff8807ef817de0
[ 1190.302022] R13: 0000000000000000 R14: ffffffffc0fd4000 R15: ffffffffc0fd6000
[ 1190.302023] FS:  00007f405d04f740(0000) GS:ffff88081ed40000(0000) knlGS:0000000000000000
[ 1190.302024] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 1190.302025] CR2: 00007f405d26a248 CR3: 00000007e5d81000 CR4: 00000000001407e0
[ 1190.302026] Stack:
[ 1190.302026]  ffffffff81c1a020 000000000000000d ffff8807d95b3db8 ffffffff81002144
[ 1190.302028]  0000000000000001 0000000000000001 0000000000000001 ffff8800dca9b440
[ 1190.302029]  0000000000000001 ffff8807d95b3da0 ffffffff8119d7d2 ffffffffc0fd6018
[ 1190.302030] Call Trace:
[ 1190.302035]  [<ffffffff81002144>] do_one_initcall+0xd4/0x210
[ 1190.302037]  [<ffffffff8119d7d2>] ? __vunmap+0xb2/0x100
[ 1190.302039]  [<ffffffff810edd79>] load_module+0x13d9/0x1b90
[ 1190.302043]  [<ffffffff810e9910>] ? store_uevent+0x40/0x40
[ 1190.302044]  [<ffffffff810ee6a6>] SyS_finit_module+0x86/0xb0
[ 1190.302048]  [<ffffffff8176e34d>] system_call_fastpath+0x1a/0x1f
[ 1190.302048] Code: <0f> 22 c0 5b 58 31 c0 5d c3 66 66 66 66 2e 0f 1f 84 00 00 00 00 00
[ 1190.302055] RIP  [<ffffffffc0fd402a>] init_module+0x2a/0x40 [cache]
[ 1190.302056]  RSP <ffff8807d95b3d30>
[ 1190.302057] ---[ end trace bf14887f4e905bad ]---

你知道发生了什么吗?这不是说我不能改变CR0.NW吗?

我的CPU:i7-4770K

1 个答案:

答案 0 :(得分:3)

根据Intel's manual提供的信息(见表11-5), 当CR0.CD为0时,不允许将CR0.NW设置为1。

我假设您尝试同时更改写策略(CR.NW = 1)和使用缓存(CR.CD = 0),这是无效的。

当我找到和你一样的东西时,我发现了它......