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

Re: [Xen-devel] idle_pg_tables??



* Petersson, Mats <Mats.Petersson@xxxxxxx> [2006-09-01 11:52]:
>  
> 
> > -----Original Message-----
> > From: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx 
> > [mailto:xen-devel-bounces@xxxxxxxxxxxxxxxxxxx] On Behalf Of 
> > PUCCETTI Armand
> > Sent: 01 September 2006 17:11
> > To: xen-devel@xxxxxxxxxxxxxxxxxxx
> > Subject: [Xen-devel] idle_pg_tables??
> > 
> > In the paging mechanism of XEN what is the role of the variable 
> > 'idle_pg_table*' variables ??
> > 
> > For a 4-levels paging system these variables are defined in 
> > x86_64.S and 
> > partially initialised.
> > Here is the code, copied from x86_64.S:
> > 
> > __________________________________________________
> > ...
> > 
> > /* Initial PML4 -- level-4 page table. */
> >         .org 0x2000
> > ENTRY(idle_pg_table)
> > ENTRY(idle_pg_table_4)
> >         .quad idle_pg_table_l3 - __PAGE_OFFSET + 7 # PML4[0]
> >         .fill 261,8,0
> >         .quad idle_pg_table_l3 - __PAGE_OFFSET + 7 # PML4[262]
> > 
> > /* Initial PDP -- level-3 page table. */
> >         .org 0x3000
> > ENTRY(idle_pg_table_l3)
> >         .quad idle_pg_table_l2 - __PAGE_OFFSET + 7
> > 
> > /* Initial PDE -- level-2 page table. Maps first 64MB 
> > physical memory. */
> >         .org 0x4000
> > ENTRY(idle_pg_table_l2)
> >         .macro identmap from=0, count=32
> >         .if \count-1
> >         identmap "(\from+0)","(\count/2)"
> >         identmap "(\from+(0x200000*(\count/2)))","(\count/2)"
> >         .else
> >         .quad 0x00000000000001e3 + \from
> >         .endif
> >         .endm
> >         identmap
> > 
> >         .org 0x4000 + PAGE_SIZE
> >         .code64
> > 
> > .section ".bss.stack_aligned","w"
> > ENTRY(cpu0_stack)
> >         .fill STACK_SIZE,1,0
> > ______________________________________________________
> > trying to understand that:
> > 
> > - idle_pg_table_l4 is the same as idle_pg_table and contains 
> > 263 enties, 
> > all zeroed but two (identical) ones. These
> > two pointers point somewhere close to idle_pg_table_l3. Why are there 
> > two identical pointers and why shift them by __PAGE_OFFSET +7?
> 
> So that we can have a map for both LOW memory (address zero and 1GB
> forward) and a map for the upper range of memory where Xen's
> base-virtual address is (__PAGE_OFFSET). I think you'll find that if you
> shift __PAGE_OFFSET sufficient number of bits (30 or so), the remaining
> number is 262... [I haven't checked this]. Reusing the same-pagetable
> entry allows the use of a single entry in the next page-table level. 
> 
> It's shifted by PAGE_OFFSET because the code is linked such that
> everything is based on the virtual address that we eventually will use
> in the system. But the page-table wants to have a PHYSICAL address, so
> we subtract the virtual baseaddress from the location that we want the
> PT entry to point to. 
> 
> The magic number of 7 represents the flags for the page-entry, which is
> bit 0=Present, bit 1= R/W (Writable) and bit 2 U/S => User accessible.
> Since this is the top lavel page, it makes sense to set it all to
> present and allow full access, since next level down can always override
> a permission (but can't allow something forbidden by upper level). 
> 
> > 
> > - idle_pg_table_l3 is located between 0x3000 and 0x4000 , 
> > with only the 
> > first slot initialised. The later points to
> > level 2 table with some offset.
> 
> This allows the next 128MB of memory to be mapped. Which is sufficient
> for the initialization of the system.
> > 
> > - idle_pg_table_l2 has terrible code with a recursive macro, 
> > who expands 
> > into 63 quad constants. It is unclear
> > to me why this complicated macro?? I would have put a table 
> > of constants 
> > pretty simply... Every entry in that l2 table points to a
> > fixed address, at intervals of 4K (a page).l2 tables are 
> > located between 
> > 0x01E3 to 0x03E001E3 in groups. Every group
> > is apparently a set of 4 page tables and each table has a 
> > size of 128K. 
> > Groups are separated by approx 256MB.
> > Why are these spacings and groups?
> 
> I can't explain why there is a macro and why it does things in the way
> it does, except I think you'll find that it's related to the code being
> located at a virtual address which is non-zero at this level [I haven't
> checked this out]. 
> 
> The value 0x1E3 is used to indicate that the pages are 2MB, Dirty
> (prevents the MMU from rewriting them dirty if they are later written),
> Accessed (same reason as D), Writeable and Present. 
> > 
> > - idle_pg_table_l1 is not an entry and so l1 tables are not 
> > allocated. Why?
> 
> Because the value 1E3 (or part thereof) is indicating that the page is
> 2MB pages, so we don't need a L1 table entry for the pages defined in
> the above way. 
> 
> May I ask what you're trying to achieve - as far as I know, the above
> code is working just fine, so messing with it doesn't seem like a good
> plan [Getting page-table initialization and such things to work right is
> notoriously complicated, because it tends to break without any way of
> really debugging it]. 
> 
> --
> Mats

The above was a lot of help for me and I'm sure many others.  Thanks.
Do we have a good place in the xenwiki where this sort of low-level
initialization can be captured for future reference?  Maybe another
entry in http://wiki.xensource.com/xenwiki/XenArchitecture ?


-- 
Ryan Harper
Software Engineer; Linux Technology Center
IBM Corp., Austin, Tx
(512) 838-9253   T/L: 678-9253
ryanh@xxxxxxxxxx

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel


 


Rackspace

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