Re: [PATCH 0/6] randomize kernel physical address and virtual address separately

From: Baoquan He
Date: Sun Feb 01 2015 - 03:11:20 EST


On 01/20/15 at 08:19pm, Andy Lutomirski wrote:
> On 01/20/2015 07:37 PM, Baoquan He wrote:
>
> I have no idea what the #PF thing you're referring to is, but I have
> code to implement a #PF handler in boot/compressed if it would be
> helpful. It's two patches:
>
> https://git.kernel.org/cgit/linux/kernel/git/luto/linux.git/commit/?h=sync_rand_seed&id=89476ea6a2becbaee4f45c3b6689ff31b6aa959a
>
> https://git.kernel.org/cgit/linux/kernel/git/luto/linux.git/commit/?h=sync_rand_seed&id=142d86921e6f271261584016fc8cfa5cdbf455ba
>
> You can't recover from a page fault in my version of this code, but that
> would be straightforward to add.
>
Hi all,

I used Andy's patch to setup idt and implement #PF handler before kernel
decompression, and it works. Then a problem is encountered that when
choose a position above 4G and decompress kernel there system will
reboot to BIOS after kernel decompression. I use hlt command to position
where the asm code will cause that reboot and found it happened after
jumping when adjusted page table is loaded in arch/x86/kernel/head_64.S

/* Setup early boot stage 4 level pagetables. */
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
movl %edx,%edi

Now I doubt gdt table is not approporiate when extend identity mapping
to be above 4G in arch/x86/boot/compressed/head_64.S. As far as I
understand, that gdt is a gdt with the 64bit segments using 32bit
descriptor, still has attribute of segment base addr and limit. I wrote
a simple patch to debug this, but still don't know how to make it work,
does anyone can help or point out what I should do to make it work?