All of lore.kernel.org
 help / color / mirror / Atom feed
From: Baoquan He <bhe@redhat.com>
To: Bhupesh Sharma <bhsharma@redhat.com>
Cc: Mark Rutland <mark.rutland@arm.com>,
	Ard Biesheuvel <ard.biesheuvel@linaro.org>,
	kexec@lists.infradead.org, Will Deacon <will.deacon@arm.com>,
	AKASHI Takahiro <takahiro.akashi@linaro.org>,
	James Morse <james.morse@arm.com>,
	Catalin Marinas <catalin.marinas@arm.com>,
	Bhupesh SHARMA <bhupesh.linux@gmail.com>,
	linux-arm-kernel <linux-arm-kernel@lists.infradead.org>
Subject: Re: [Query] PAGE_OFFSET on KASLR enabled ARM64 kernel
Date: Mon, 28 May 2018 11:58:18 +0800	[thread overview]
Message-ID: <20180528035818.GB31261@MiWiFi-R3L-srv> (raw)
In-Reply-To: <20180528021609.GA31261@MiWiFi-R3L-srv>

On 05/28/18 at 10:16am, Baoquan He wrote:
> On 05/28/18 at 02:33am, Bhupesh Sharma wrote:
> > Hi ARM64 maintainers,
> > 
> > I am confused about the PAGE_OFFSET value (or the start of the linear
> > map) on a KASLR enabled ARM64 kernel that I am seeing on a board which
> > supports a compatible EFI firmware (with EFI_RNG_PROTOCOL support).
> > 
> > 1. 'arch/arm64/include/asm/memory.h' defines PAGE_OFFSET as:
> > 
> > /*
> >  * PAGE_OFFSET - the virtual address of the start of the linear map (top
> >  *         (VA_BITS - 1))
> >  */
> > #define PAGE_OFFSET        (UL(0xffffffffffffffff) - \
> >     (UL(1) << (VA_BITS - 1)) + 1)
> > 
> > So for example on a platform with VA_BITS=48, we have:
> > PAGE_OFFSET = 0xffff800000000000
> > 
> > 2. However, for the KASLR case, we set the 'memstart_offset_seed ' to
> > use the 16-bits of the 'kaslr-seed' to randomize the linear region in
> > 'arch/arm64/kernel/kaslr.c' :
> > 
> > u64 __init kaslr_early_init(u64 dt_phys)
> > {
> > <snip..>
> >     /* use the top 16 bits to randomize the linear region */
> >     memstart_offset_seed = seed >> 48;
> > <snip..>
> > }
> > 
> > 3. Now, we use the 'memstart_offset_seed' value to randomize the
> > 'memstart_addr' value in 'arch/arm64/mm/init.c':
> > 
> > void __init arm64_memblock_init(void)
> > {
> > <snip..>
> > 
> >     if (IS_ENABLED(CONFIG_RANDOMIZE_BASE)) {
> >         extern u16 memstart_offset_seed;
> >         u64 range = linear_region_size -
> >                 (memblock_end_of_DRAM() - memblock_start_of_DRAM());
> > 
> >         /*
> >          * If the size of the linear region exceeds, by a sufficient
> >          * margin, the size of the region that the available physical
> >          * memory spans, randomize the linear region as well.
> >          */
> >         if (memstart_offset_seed > 0 && range >= ARM64_MEMSTART_ALIGN) {
> >             range = range / ARM64_MEMSTART_ALIGN + 1;
> >             memstart_addr -= ARM64_MEMSTART_ALIGN *
> >                      ((range * memstart_offset_seed) >> 16);
> >         }
> >     }
> > <snip..>
> > }
> > 
> > 4. Since 'memstart_addr' indicates the start of physical RAM, we
> > randomize the same on basis of 'memstart_offset_seed' value above.
> > Also the 'memstart_addr' value is available in '/proc/kallsyms' and
> > hence can be accessed by user-space applications to read the
> > 'memstart_addr' value.
> > 
> > 5. Now since the PAGE_OFFSET value is also used by several user space
> > tools (for e.g. makedumpfile tool uses the same to determine the start
> > of linear region and hence to read PT_NOTE fields from /proc/kcore), I
> > am not sure how to read the randomized value of the same in the KASLR
> > enabled case.
> > 
> > 6. Reading the code further and adding some debug prints, it seems the
> > 'memblock_start_of_DRAM()' value is more closer to the actual start of
> > linear region rather than 'memstart_addr' and 'PAGE_OFFSET" in case of
> > KASLR enabled kernel:
> 
> 
> Can you paste your complete dmesg or boot log? Here I guess it only
> means the virtual address of memblock_start_of_DRAM, not its value.

Oh, it's an offset value, I was mistaken.

> 
> VA_START == 0Xffff000000000000
> PAGE_OFFSET == 0xffff800000000000
> > 
> > [root@qualcomm-amberwing] # dmesg | grep -i "arm64_memblock_init" -A 5
> > 
> > [    0.000000] inside arm64_memblock_init, memstart_addr = ffff976a00000000,
> > linearstart_addr = ffffe89600200000, memblock_start_of_DRAM = ffffe89600200000,
> > PHYS_OFFSET = ffff976a00000000, PAGE_OFFSET = ffff800000000000,
> > KIMAGE_VADDR = ffff000008000000, kimage_vaddr = ffff20c2d7800000
> > 
> > [root@qualcomm-amberwing] # dmesg | grep -i "Virtual kernel memory layout" -A 15
> > [    0.000000] Virtual kernel memory layout:
> > [    0.000000]     modules : 0xffff000000000000 - 0xffff000008000000
> > (   128 MB)
> > [    0.000000]     vmalloc : 0xffff000008000000 - 0xffff7bdfffff0000
> > (126847 GB)
> > [    0.000000]       .text : 0xffff20c2d7880000 - 0xffff20c2d8040000
> > (  7936 KB)
> > [    0.000000]     .rodata : 0xffff20c2d8040000 - 0xffff20c2d83a0000
> > (  3456 KB)
> > [    0.000000]       .init : 0xffff20c2d83a0000 - 0xffff20c2d8750000
> > (  3776 KB)
> > [    0.000000]       .data : 0xffff20c2d8750000 - 0xffff20c2d891b200
> > (  1837 KB)
> > [    0.000000]        .bss : 0xffff20c2d891b200 - 0xffff20c2d90a5198
> > (  7720 KB)
> > [    0.000000]     fixed   : 0xffff7fdffe790000 - 0xffff7fdffec00000
> > (  4544 KB)
> > [    0.000000]     PCI I/O : 0xffff7fdffee00000 - 0xffff7fdfffe00000
> > (    16 MB)
> > [    0.000000]     vmemmap : 0xffff7fe000000000 - 0xffff800000000000
> > (   128 GB maximum)
> > [    0.000000]               0xffff7ffa25800800 - 0xffff7ffa2b800000
> > (    95 MB actual)
> > [    0.000000]     memory  : 0xffffe89600200000 - 0xffffe8ae00000000
> > ( 98302 MB)
> > 
> > As one can see above, the 'memblock_start_of_DRAM()' value of
> > 0xffffe89600200000 represents the start of linear region:
> > 
> > [    0.000000]     memory  : 0xffffe89600200000 - 0xffffe8ae00000000
> > ( 98302 MB)
> > 
> > So, my question is to access the start of linear region (which was
> > earlier determinable via PAGE_OFFSET macro), whether I should:
> > 
> > - do some back-computation for the start of linear region from the
> > 'memstart_addr' in user-space, or
> > - use a new global variable in kernel which is assigned the value of
> > memblock_start_of_DRAM()' and assign it to '/proc/kallsyms', so that
> > it can be read by user-space tools, or
> > - whether we should rather look at removing the PAGE_OFFSET usage from
> > the kernel and replace it with a global variable instead which is
> > properly updated for KASLR case as well.
> > 
> > Kindly share your opinions on what can be a suitable solution in this case.
> > 
> > Thanks for your help.
> > 
> > Regards,
> > Bhupesh
> > 
> > _______________________________________________
> > kexec mailing list
> > kexec@lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/kexec
> 
> _______________________________________________
> kexec mailing list
> kexec@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/kexec

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

WARNING: multiple messages have this Message-ID (diff)
From: bhe@redhat.com (Baoquan He)
To: linux-arm-kernel@lists.infradead.org
Subject: [Query] PAGE_OFFSET on KASLR enabled ARM64 kernel
Date: Mon, 28 May 2018 11:58:18 +0800	[thread overview]
Message-ID: <20180528035818.GB31261@MiWiFi-R3L-srv> (raw)
In-Reply-To: <20180528021609.GA31261@MiWiFi-R3L-srv>

On 05/28/18 at 10:16am, Baoquan He wrote:
> On 05/28/18 at 02:33am, Bhupesh Sharma wrote:
> > Hi ARM64 maintainers,
> > 
> > I am confused about the PAGE_OFFSET value (or the start of the linear
> > map) on a KASLR enabled ARM64 kernel that I am seeing on a board which
> > supports a compatible EFI firmware (with EFI_RNG_PROTOCOL support).
> > 
> > 1. 'arch/arm64/include/asm/memory.h' defines PAGE_OFFSET as:
> > 
> > /*
> >  * PAGE_OFFSET - the virtual address of the start of the linear map (top
> >  *         (VA_BITS - 1))
> >  */
> > #define PAGE_OFFSET        (UL(0xffffffffffffffff) - \
> >     (UL(1) << (VA_BITS - 1)) + 1)
> > 
> > So for example on a platform with VA_BITS=48, we have:
> > PAGE_OFFSET = 0xffff800000000000
> > 
> > 2. However, for the KASLR case, we set the 'memstart_offset_seed ' to
> > use the 16-bits of the 'kaslr-seed' to randomize the linear region in
> > 'arch/arm64/kernel/kaslr.c' :
> > 
> > u64 __init kaslr_early_init(u64 dt_phys)
> > {
> > <snip..>
> >     /* use the top 16 bits to randomize the linear region */
> >     memstart_offset_seed = seed >> 48;
> > <snip..>
> > }
> > 
> > 3. Now, we use the 'memstart_offset_seed' value to randomize the
> > 'memstart_addr' value in 'arch/arm64/mm/init.c':
> > 
> > void __init arm64_memblock_init(void)
> > {
> > <snip..>
> > 
> >     if (IS_ENABLED(CONFIG_RANDOMIZE_BASE)) {
> >         extern u16 memstart_offset_seed;
> >         u64 range = linear_region_size -
> >                 (memblock_end_of_DRAM() - memblock_start_of_DRAM());
> > 
> >         /*
> >          * If the size of the linear region exceeds, by a sufficient
> >          * margin, the size of the region that the available physical
> >          * memory spans, randomize the linear region as well.
> >          */
> >         if (memstart_offset_seed > 0 && range >= ARM64_MEMSTART_ALIGN) {
> >             range = range / ARM64_MEMSTART_ALIGN + 1;
> >             memstart_addr -= ARM64_MEMSTART_ALIGN *
> >                      ((range * memstart_offset_seed) >> 16);
> >         }
> >     }
> > <snip..>
> > }
> > 
> > 4. Since 'memstart_addr' indicates the start of physical RAM, we
> > randomize the same on basis of 'memstart_offset_seed' value above.
> > Also the 'memstart_addr' value is available in '/proc/kallsyms' and
> > hence can be accessed by user-space applications to read the
> > 'memstart_addr' value.
> > 
> > 5. Now since the PAGE_OFFSET value is also used by several user space
> > tools (for e.g. makedumpfile tool uses the same to determine the start
> > of linear region and hence to read PT_NOTE fields from /proc/kcore), I
> > am not sure how to read the randomized value of the same in the KASLR
> > enabled case.
> > 
> > 6. Reading the code further and adding some debug prints, it seems the
> > 'memblock_start_of_DRAM()' value is more closer to the actual start of
> > linear region rather than 'memstart_addr' and 'PAGE_OFFSET" in case of
> > KASLR enabled kernel:
> 
> 
> Can you paste your complete dmesg or boot log? Here I guess it only
> means the virtual address of memblock_start_of_DRAM, not its value.

Oh, it's an offset value, I was mistaken.

> 
> VA_START == 0Xffff000000000000
> PAGE_OFFSET == 0xffff800000000000
> > 
> > [root at qualcomm-amberwing] # dmesg | grep -i "arm64_memblock_init" -A 5
> > 
> > [    0.000000] inside arm64_memblock_init, memstart_addr = ffff976a00000000,
> > linearstart_addr = ffffe89600200000, memblock_start_of_DRAM = ffffe89600200000,
> > PHYS_OFFSET = ffff976a00000000, PAGE_OFFSET = ffff800000000000,
> > KIMAGE_VADDR = ffff000008000000, kimage_vaddr = ffff20c2d7800000
> > 
> > [root at qualcomm-amberwing] # dmesg | grep -i "Virtual kernel memory layout" -A 15
> > [    0.000000] Virtual kernel memory layout:
> > [    0.000000]     modules : 0xffff000000000000 - 0xffff000008000000
> > (   128 MB)
> > [    0.000000]     vmalloc : 0xffff000008000000 - 0xffff7bdfffff0000
> > (126847 GB)
> > [    0.000000]       .text : 0xffff20c2d7880000 - 0xffff20c2d8040000
> > (  7936 KB)
> > [    0.000000]     .rodata : 0xffff20c2d8040000 - 0xffff20c2d83a0000
> > (  3456 KB)
> > [    0.000000]       .init : 0xffff20c2d83a0000 - 0xffff20c2d8750000
> > (  3776 KB)
> > [    0.000000]       .data : 0xffff20c2d8750000 - 0xffff20c2d891b200
> > (  1837 KB)
> > [    0.000000]        .bss : 0xffff20c2d891b200 - 0xffff20c2d90a5198
> > (  7720 KB)
> > [    0.000000]     fixed   : 0xffff7fdffe790000 - 0xffff7fdffec00000
> > (  4544 KB)
> > [    0.000000]     PCI I/O : 0xffff7fdffee00000 - 0xffff7fdfffe00000
> > (    16 MB)
> > [    0.000000]     vmemmap : 0xffff7fe000000000 - 0xffff800000000000
> > (   128 GB maximum)
> > [    0.000000]               0xffff7ffa25800800 - 0xffff7ffa2b800000
> > (    95 MB actual)
> > [    0.000000]     memory  : 0xffffe89600200000 - 0xffffe8ae00000000
> > ( 98302 MB)
> > 
> > As one can see above, the 'memblock_start_of_DRAM()' value of
> > 0xffffe89600200000 represents the start of linear region:
> > 
> > [    0.000000]     memory  : 0xffffe89600200000 - 0xffffe8ae00000000
> > ( 98302 MB)
> > 
> > So, my question is to access the start of linear region (which was
> > earlier determinable via PAGE_OFFSET macro), whether I should:
> > 
> > - do some back-computation for the start of linear region from the
> > 'memstart_addr' in user-space, or
> > - use a new global variable in kernel which is assigned the value of
> > memblock_start_of_DRAM()' and assign it to '/proc/kallsyms', so that
> > it can be read by user-space tools, or
> > - whether we should rather look at removing the PAGE_OFFSET usage from
> > the kernel and replace it with a global variable instead which is
> > properly updated for KASLR case as well.
> > 
> > Kindly share your opinions on what can be a suitable solution in this case.
> > 
> > Thanks for your help.
> > 
> > Regards,
> > Bhupesh
> > 
> > _______________________________________________
> > kexec mailing list
> > kexec at lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/kexec
> 
> _______________________________________________
> kexec mailing list
> kexec at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/kexec

  reply	other threads:[~2018-05-28  3:58 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-05-27 21:03 [Query] PAGE_OFFSET on KASLR enabled ARM64 kernel Bhupesh Sharma
2018-05-27 21:03 ` Bhupesh Sharma
2018-05-28  2:16 ` Baoquan He
2018-05-28  2:16   ` Baoquan He
2018-05-28  3:58   ` Baoquan He [this message]
2018-05-28  3:58     ` Baoquan He
2018-05-28  6:46 ` Ard Biesheuvel
2018-05-28  6:46   ` Ard Biesheuvel
2018-05-31  4:51   ` Bhupesh Sharma
2018-05-31  4:51     ` Bhupesh Sharma
2018-06-01 21:41     ` Bhupesh Sharma
2018-06-01 21:41       ` Bhupesh Sharma
2018-06-01 21:52       ` Bhupesh Sharma
2018-06-01 21:52         ` Bhupesh Sharma
2018-05-30  2:35 ` Pratyush Anand
2018-05-30  2:35   ` Pratyush Anand
2018-05-31  4:57   ` Bhupesh Sharma
2018-05-31  4:57     ` Bhupesh Sharma

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180528035818.GB31261@MiWiFi-R3L-srv \
    --to=bhe@redhat.com \
    --cc=ard.biesheuvel@linaro.org \
    --cc=bhsharma@redhat.com \
    --cc=bhupesh.linux@gmail.com \
    --cc=catalin.marinas@arm.com \
    --cc=james.morse@arm.com \
    --cc=kexec@lists.infradead.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=mark.rutland@arm.com \
    --cc=takahiro.akashi@linaro.org \
    --cc=will.deacon@arm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.