<div dir="ltr"><div>Hi Timothy, sorry for that. I'll do it.<br><br></div>Oscar<br></div><div class="gmail_extra"><br><div class="gmail_quote">2016-10-11 20:05 GMT+02:00 Bird, Timothy <span dir="ltr"><<a href="mailto:Tim.Bird@am.sony.com" target="_blank">Tim.Bird@am.sony.com</a>></span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">This is not really the list for a technical discussion like this.  The elinux-discuss list is<br>
for discussion of issues affecting the elinux wiki.  I recommend you post your<br>
issue on the Linux kernel ARM mailing list.<br>
 -- Tim<br>
<div class="HOEnZb"><div class="h5"><br>
<br>
> -----Original Message-----<br>
> From: Elinux-discuss [mailto:<a href="mailto:elinux-discuss-bounces@lists.elinux.org">elinux-discuss-<wbr>bounces@lists.elinux.org</a>] On<br>
> Behalf Of Oscar Salvador<br>
> Sent: Tuesday, October 11, 2016 12:38 PM<br>
> To: <a href="mailto:elinux-discuss@lists.elinux.org">elinux-discuss@lists.elinux.<wbr>org</a><br>
> Subject: [Elinux-discuss] doubt regarding page tables layout on arm<br>
><br>
> Hi all,<br>
><br>
><br>
> I'm writing here because after been reading a lot of papers regarding this<br>
> topic, I still can't get the point with it.<br>
><br>
> Let me explain it:<br>
><br>
><br>
> I'm writing a module, and within this module I'm trying to emulate the<br>
> lookup_address from x86, but on arm.<br>
><br>
><br>
> I'm getting the value of swapper_pg_dir through the TTBR1 (which is the<br>
> same value I get if I try to print the memory address of swapper_pg_dir with<br>
> GDB).<br>
><br>
><br>
> Then, since I'm working on arm32 without LPAE, Linux is just using PMD (pgd<br>
> and pud are gone).<br>
><br>
><br>
> As it explains here: include/asm/pgtable-2level.h<br>
><br>
> The layout pte page tables looks like:<br>
><br>
><br>
> - linux_pte_0<br>
><br>
> - linux_pte_1<br>
><br>
> - arm_pte_0<br>
><br>
> - arm_pte_1<br>
><br>
><br>
> That's within a page.<br>
><br>
><br>
> linux_pte_* are being used in order that linux can check for dirty/young bits<br>
> since ARM does not provide such bits.<br>
><br>
><br>
> When creating the mappings through __create_mapping function, we set up<br>
> the page table permissions of arm page tables depending of the permissions<br>
> this type of memory has (this flags are being set in static struct mem_type<br>
> mem_types[]).<br>
><br>
><br>
> For example:<br>
><br>
><br>
> In function alloc_init_pte we call arm_pte_alloc in order:<br>
><br>
><br>
> - Allocate PTE_HWTABLE_OFF + PTE_HWTABLE_SIZE bytes (4096bytes)<br>
><br>
> - populate pmd with (function __pmd_populate):<br>
><br>
>        - physical memory of space allocated before + PTE_HWTABLE_OFF<br>
> (2048bytes) | protecion_bits<br>
><br>
>         - this ends up with: pmdval of this pmd stores:<br>
> physical_address_of_arm_pte|<wbr>protection_bits<br>
><br>
><br>
> code from __pmd_populate:<br>
><br>
>  pmdval_t pmdval = (pte + PTE_HWTABLE_OFF) | prot;<br>
>  pmdp[0] = __pmd(pmdval);<br>
><br>
><br>
> Once this is done, arm_pte_alloc returns with pte_offset_kernel, which does<br>
> this steps:<br>
><br>
><br>
>  - ANDs the value of this pmd with PHYS_MASK && PAGE_MASK<br>
><br>
>  - return the virtual address of the value stored before (returns vaddrr of the<br>
> top of page=<br>
>  - adds virtual_address of this page + pte_index (addr)<br>
><br>
><br>
> Once this is done, the arm page tables permissions are being set with:<br>
><br>
> set_pte_ext function, that in my case is going to call cpu_v7_set_pte_ext<br>
> function from mm/proc-v7-2level.S.<br>
><br>
> There r3 is being set depending of L_PTE_* bits, and then r3 is being written<br>
> in linux_pte + 2048 (whete it points the arm_pte).<br>
><br>
><br>
> Given this explanation I'll what I'm doing:<br>
><br>
><br>
> Let's say I want to get the pte of X (X is a linear address)<br>
><br>
><br>
> pgd = get_global_pgd_from_ttbr1 (same value as swapper_pg_dir)<br>
><br>
> pgd += pgd_index (X)<br>
><br>
> pud = pud_offset (pgd, X)<br>
><br>
> pmd = pmd_offset (pud, X)<br>
><br>
><br>
> At this point, pmd should contain: (pte + PTE_HWTABLE_OFF) | prot  (since it<br>
> was populated with this value).<br>
><br>
><br>
> Then:<br>
><br>
><br>
> pte = pte_offset_kernel (pmd, X) (gets virtual address of pmd_val masked<br>
> with PHYS_MASK && PAGE_MASK and adds it the pte_index (X))<br>
><br>
><br>
> Here I should get a pointer of the pte related to X address, and since I points<br>
> to the top (where Linux PTE are), I should be able to check L_PTE_ bits, but<br>
> I'm afraid i'm getting weird values here.<br>
><br>
><br>
><br>
> I hope I could explain my question as clear as I wanted.<br>
><br>
><br>
> Thank you very much<br>
><br>
> Oscar Salvador<br>
<br>
</div></div></blockquote></div><br></div>