Messages in this thread Patch in this message | | | Date | Sun, 23 Jan 2011 20:06:30 +0100 | From | matthieu castet <> | Subject | Re: -tip tree resume fail, bisect to 5bd5a45(x86: Add NX protection for kernel data) |
| |
Lin Ming a écrit : > On Tue, 2010-11-30 at 19:27 +0800, Peter Zijlstra wrote: >> On Tue, 2010-11-30 at 13:00 +0800, Lin Ming wrote: >>> echo 0 > /sys/devices/system/cpu/cpu1/online; >>> echo 1 > /sys/devices/system/cpu/cpu1/online; >>> >>> then machine just reboots... >>> I tried to do the same thing on qemu, and the same behavior happened (ie reboot when resuming cpu1).
After enabling qemu log, I found that a triple fault was happening at the beginning of secondary_startup_64 when doing "addq phys_base(%rip), %rax".
Why ? I suppose because we access data set to NX, but we don't have enabled yet NX in the msr. So the cpu crash due to "reserved bit check".
If we enable NX before reading data, there is no more crash (patch attached).
Now I am not sure this is the correct fix. I think the problem is that trampoline using kernel page table is very dangerous. The kernel can have modified them atfer booting ! May be all the paging stuff should have been done in head_64.S. A first one with identity mapping, and the second one for the real kernel stuff.
Matthieu diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S index 239046b..9f32295 100644 --- a/arch/x86/kernel/head_64.S +++ b/arch/x86/kernel/head_64.S @@ -165,16 +165,6 @@ ENTRY(secondary_startup_64) movl $(X86_CR4_PAE | X86_CR4_PGE), %eax movq %rax, %cr4 - /* Setup early boot stage 4 level pagetables. */ - movq $(init_level4_pgt - __START_KERNEL_map), %rax - addq phys_base(%rip), %rax - movq %rax, %cr3 - - /* Ensure I am executing from virtual addresses */ - movq $1f, %rax - jmp *%rax -1: - /* Check if nx is implemented */ movl $0x80000001, %eax cpuid @@ -189,6 +179,17 @@ ENTRY(secondary_startup_64) btsl $_EFER_NX, %eax 1: wrmsr /* Make changes effective */ + /* Setup early boot stage 4 level pagetables. */ + movq $(init_level4_pgt - __START_KERNEL_map), %rax + addq phys_base(%rip), %rax + movq %rax, %cr3 + + /* Ensure I am executing from virtual addresses */ + movq $1f, %rax + jmp *%rax +1: + + /* Setup cr0 */ #define CR0_STATE (X86_CR0_PE | X86_CR0_MP | X86_CR0_ET | \ X86_CR0_NE | X86_CR0_WP | X86_CR0_AM | \ | |