[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] Why we are doing this (below code) in __init setup_pagetables() method in ARM arch in setup.c.



On Mon, 10 Dec 2012, Ian Campbell wrote:
> Please read http://wiki.xen.org/wiki/Asking_Xen_Devel_Questions and
> consider re-asking your question with more context. 
> 
> e.g. include your actual goal, what steps have you taken to find the
> answer for yourself etc.

Yes, that would be very helpful, even if the context is just "I am
trying to learn the Xen ARM code".


> On Sat, 2012-12-08 at 13:02 +0000, asad raza wrote:
> >  /* Link in the fixmap pagetable */
> >     pte = mfn_to_xen_entry((((unsigned long) xen_fixmap) + phys_offset)
> >                            >> PAGE_SHIFT);
> >     pte.pt.table = 1;
> >     write_pte(xen_second + second_table_offset(FIXMAP_ADDR(0)), pte);
> >     /*
> >      * No flush required here. Individual flushes are done in
> >      * set_fixmap as entries are used.
> >      */

As the comment say, these few lines hook the new copy of the fixmap
pagetable page to the new copy of the second level pagetable page.

Keep in mind that at this point we have copied Xen to the new location
in memory, but the new copy of the pagetable, that is not in-use yet, is
still pointing at the old location.


> >     /* Break up the Xen mapping into 4k pages and protect them separately. 
> > */
> >     for ( i = 0; i < LPAE_ENTRIES; i++ )
> >     {
> >         unsigned long mfn = paddr_to_pfn(xen_paddr) + i;
> >         unsigned long va = XEN_VIRT_START + (i << PAGE_SHIFT);
> >         if ( !is_kernel(va) )
> >             break;
> >         pte = mfn_to_xen_entry(mfn);
> >         pte.pt.table = 1; /* 4k mappings always have this bit set */
> >         if ( is_kernel_text(va) || is_kernel_inittext(va) )
> >         {
> >             pte.pt.xn = 0;
> >             pte.pt.ro = 1;
> >         }
> >         if ( is_kernel_rodata(va) )
> >             pte.pt.ro = 1;
> >         write_pte(xen_xenmap + i, pte);
> >         /* No flush required here as page table is not hooked in yet. */
> >     }

This loop updates the Xen mappings in the new copy of the pagetable to
point to the physical address of the new copy of Xen (xen_paddr).
As well as doing that, this loop also changes the way Xen is mapped: so
far Xen was mapped using 2M mappings (only 2 pagetable levels), here we
introduce a third level (xen_xenmap) to map Xen using 4K pages.


> >     pte = mfn_to_xen_entry((((unsigned long) xen_xenmap) + phys_offset)
> >                            >> PAGE_SHIFT);
> >     pte.pt.table = 1;
> >     write_pte(xen_second + second_linear_offset(XEN_VIRT_START), pte);
> >     /* Have changed a mapping used for .text. Flush everything for safety. 
> > */
> >     flush_xen_text_tlb();

We hook the third level pagetable page that maps Xen at the new location
using 4K mappings in the new copy of the pagetable.


> >     /* From now on, no mapping may be both writable and executable. */
> >     WRITE_CP32(READ_CP32(HSCTLR) | SCTLR_WXN, HSCTLR);



_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.