[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH 01/10] xen: arm: map memory as inner shareable.
On Fri, Jun 28, 2013 at 05:10:47PM +0100, Ian Campbell wrote: > The inner shareable domain contains all SMP processors, including different > clusters (e.g. big.LITTLE). Therefore this is the correct thing to use for Xen > memory mappings. The outer shareable domain is for devices on busses which are > barriers (e.g. AMBA4). I think this should say something like "which are coherent and barrier-aware". And to be technically correct, the example should say "AMBA4 AXI with ACE"). > While the system domain is for things behind bridges > which do not. And given the above ... -> which "are" not. > One wrinkle is that Normal memory with attributes Inner Non-cacheable, Outer > Non-cacheable (which we call BUFFERABLE) must be mapped Outer Shareable on ARM > v7. Therefore change the prototype of mfn_to_xen_entry to take the attribute > index so we can DTRT. On ARMv8 the sharability is ignored and considered to > always be Outer Shareable. > > While I'm here change all the dmb/dsb with an implicit sy to an explicit sy, > to make future changes simpler. Other than that don't adjust the barriers, > flushes etc, those remain as they were (which is more than is now required). > I'll change those in a later patch. > > Many thanks to Leif for explaining the difference between Inner- and > Outer-Shareable in words of two or less syllables, I hope I've replicated that > explanation properly above! Apart from my usual nitpicking, indeed :) > Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx> > Cc: Leif Lindholm <leif.lindholm@xxxxxxxxxx> > --- > xen/arch/arm/arm32/head.S | 8 +++--- > xen/arch/arm/arm64/head.S | 8 +++--- > xen/arch/arm/mm.c | 24 ++++++++++------------ > xen/include/asm-arm/arm32/system.h | 4 +- > xen/include/asm-arm/page.h | 38 ++++++++++++++++++++++++++++++++--- > 5 files changed, 55 insertions(+), 27 deletions(-) > > diff --git a/xen/arch/arm/arm32/head.S b/xen/arch/arm/arm32/head.S > index 0588d54..464c351 100644 > --- a/xen/arch/arm/arm32/head.S > +++ b/xen/arch/arm/arm32/head.S > @@ -24,8 +24,8 @@ > > #define ZIMAGE_MAGIC_NUMBER 0x016f2818 > > -#define PT_PT 0xe7f /* nG=1 AF=1 SH=10 AP=01 NS=1 ATTR=111 T=1 P=1 */ > -#define PT_MEM 0xe7d /* nG=1 AF=1 SH=10 AP=01 NS=1 ATTR=111 T=0 P=1 */ > +#define PT_PT 0xf7f /* nG=1 AF=1 SH=11 AP=01 NS=1 ATTR=111 T=1 P=1 */ > +#define PT_MEM 0xf7d /* nG=1 AF=1 SH=11 AP=01 NS=1 ATTR=111 T=0 P=1 */ > #define PT_DEV 0xe71 /* nG=1 AF=1 SH=10 AP=01 NS=1 ATTR=100 T=0 P=1 */ > #define PT_DEV_L3 0xe73 /* nG=1 AF=1 SH=10 AP=01 NS=1 ATTR=100 T=1 P=1 */ > > @@ -206,10 +206,10 @@ skip_bss: > mcr CP32(r1, HMAIR1) > > /* Set up the HTCR: > - * PT walks use Outer-Shareable accesses, > + * PT walks use Inner-Shareable accesses, > * PT walks are write-back, write-allocate in both cache levels, > * Full 32-bit address space goes through this table. */ > - ldr r0, =0x80002500 > + ldr r0, =0x80003500 > mcr CP32(r0, HTCR) > > /* Set up the HSCTLR: > diff --git a/xen/arch/arm/arm64/head.S b/xen/arch/arm/arm64/head.S > index 21b7e4d..ffcb880 100644 > --- a/xen/arch/arm/arm64/head.S > +++ b/xen/arch/arm/arm64/head.S > @@ -24,8 +24,8 @@ > #include <asm/page.h> > #include <asm/asm_defns.h> > > -#define PT_PT 0xe7f /* nG=1 AF=1 SH=10 AP=01 NS=1 ATTR=111 T=1 P=1 */ > -#define PT_MEM 0xe7d /* nG=1 AF=1 SH=10 AP=01 NS=1 ATTR=111 T=0 P=1 */ > +#define PT_PT 0xf7f /* nG=1 AF=1 SH=11 AP=01 NS=1 ATTR=111 T=1 P=1 */ > +#define PT_MEM 0xf7d /* nG=1 AF=1 SH=11 AP=01 NS=1 ATTR=111 T=0 P=1 */ > #define PT_DEV 0xe71 /* nG=1 AF=1 SH=10 AP=01 NS=1 ATTR=100 T=0 P=1 */ > #define PT_DEV_L3 0xe73 /* nG=1 AF=1 SH=10 AP=01 NS=1 ATTR=100 T=1 P=1 */ > > @@ -178,10 +178,10 @@ skip_bss: > /* Set up the HTCR: > * PASize -- 4G > * Top byte is used > - * PT walks use Outer-Shareable accesses, > + * PT walks use Inner-Shareable accesses, > * PT walks are write-back, write-allocate in both cache levels, > * Full 64-bit address space goes through this table. */ > - ldr x0, =0x80802500 > + ldr x0, =0x80803500 > msr tcr_el2, x0 > > /* Set up the HSCTLR: > diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c > index d1290cd..c5213f2 100644 > --- a/xen/arch/arm/mm.c > +++ b/xen/arch/arm/mm.c > @@ -163,9 +163,8 @@ void dump_hyp_walk(vaddr_t addr) > /* Map a 4k page in a fixmap entry */ > void set_fixmap(unsigned map, unsigned long mfn, unsigned attributes) > { > - lpae_t pte = mfn_to_xen_entry(mfn); > + lpae_t pte = mfn_to_xen_entry(mfn, attributes); > pte.pt.table = 1; /* 4k mappings always have this bit set */ > - pte.pt.ai = attributes; > pte.pt.xn = 1; > write_pte(xen_fixmap + third_table_offset(FIXMAP_ADDR(map)), pte); > flush_xen_data_tlb_range_va(FIXMAP_ADDR(map), PAGE_SIZE); > @@ -212,7 +211,7 @@ void *map_domain_page(unsigned long mfn) > if ( map[slot].pt.avail == 0 ) > { > /* Commandeer this 2MB slot */ > - pte = mfn_to_xen_entry(slot_mfn); > + pte = mfn_to_xen_entry(slot_mfn, WRITEALLOC); > pte.pt.avail = 1; > write_pte(map + slot, pte); > break; > @@ -340,7 +339,7 @@ void __init setup_pagetables(unsigned long > boot_phys_offset, paddr_t xen_paddr) > > /* Map the destination in the boot misc area. */ > dest_va = BOOT_MISC_VIRT_START; > - pte = mfn_to_xen_entry(xen_paddr >> PAGE_SHIFT); > + pte = mfn_to_xen_entry(xen_paddr >> PAGE_SHIFT, WRITEALLOC); > write_pte(xen_second + second_table_offset(dest_va), pte); > flush_xen_data_tlb_range_va(dest_va, SECOND_SIZE); > > @@ -387,7 +386,7 @@ void __init setup_pagetables(unsigned long > boot_phys_offset, paddr_t xen_paddr) > > /* Link in the fixmap pagetable */ > pte = mfn_to_xen_entry((((unsigned long) xen_fixmap) + phys_offset) > - >> PAGE_SHIFT); > + >> PAGE_SHIFT, WRITEALLOC); > pte.pt.table = 1; > write_pte(xen_second + second_table_offset(FIXMAP_ADDR(0)), pte); > /* > @@ -402,7 +401,7 @@ void __init setup_pagetables(unsigned long > boot_phys_offset, paddr_t xen_paddr) > unsigned long va = XEN_VIRT_START + (i << PAGE_SHIFT); > if ( !is_kernel(va) ) > break; > - pte = mfn_to_xen_entry(mfn); > + pte = mfn_to_xen_entry(mfn, WRITEALLOC); > pte.pt.table = 1; /* 4k mappings always have this bit set */ > if ( is_kernel_text(va) || is_kernel_inittext(va) ) > { > @@ -415,7 +414,7 @@ void __init setup_pagetables(unsigned long > boot_phys_offset, paddr_t xen_paddr) > /* No flush required here as page table is not hooked in yet. */ > } > pte = mfn_to_xen_entry((((unsigned long) xen_xenmap) + phys_offset) > - >> PAGE_SHIFT); > + >> PAGE_SHIFT, WRITEALLOC); > pte.pt.table = 1; > write_pte(xen_second + second_linear_offset(XEN_VIRT_START), pte); > /* TLBFLUSH and ISB would be needed here, but wait until we set WXN */ > @@ -467,7 +466,7 @@ int init_secondary_pagetables(int cpu) > /* Initialise first pagetable from first level of boot tables, and > * hook into the new root. */ > memcpy(first, boot_first, PAGE_SIZE); > - pte = mfn_to_xen_entry(virt_to_mfn(first)); > + pte = mfn_to_xen_entry(virt_to_mfn(first), WRITEALLOC); > pte.pt.table = 1; > write_pte(root, pte); > #endif > @@ -479,7 +478,7 @@ int init_secondary_pagetables(int cpu) > * domheap mapping pages. */ > for ( i = 0; i < DOMHEAP_SECOND_PAGES; i++ ) > { > - pte = mfn_to_xen_entry(virt_to_mfn(domheap+i*LPAE_ENTRIES)); > + pte = mfn_to_xen_entry(virt_to_mfn(domheap+i*LPAE_ENTRIES), > WRITEALLOC); > pte.pt.table = 1; > > write_pte(&first[first_table_offset(DOMHEAP_VIRT_START+i*FIRST_SIZE)], pte); > } > @@ -525,7 +524,7 @@ static void __init create_mappings(unsigned long virt, > > count = nr_mfns / LPAE_ENTRIES; > p = xen_second + second_linear_offset(virt); > - pte = mfn_to_xen_entry(base_mfn); > + pte = mfn_to_xen_entry(base_mfn, WRITEALLOC); > pte.pt.hint = 1; /* These maps are in 16-entry contiguous chunks. */ > for ( i = 0; i < count; i++ ) > { > @@ -595,7 +594,7 @@ static int create_xen_table(lpae_t *entry) > if ( p == NULL ) > return -ENOMEM; > clear_page(p); > - pte = mfn_to_xen_entry(virt_to_mfn(p)); > + pte = mfn_to_xen_entry(virt_to_mfn(p), WRITEALLOC); > pte.pt.table = 1; > write_pte(entry, pte); > return 0; > @@ -641,9 +640,8 @@ static int create_xen_entries(enum xenmap_operation op, > addr, mfn); > return -EINVAL; > } > - pte = mfn_to_xen_entry(mfn); > + pte = mfn_to_xen_entry(mfn, ai); > pte.pt.table = 1; > - pte.pt.ai = ai; > write_pte(&third[third_table_offset(addr)], pte); > break; > case REMOVE: > diff --git a/xen/include/asm-arm/arm32/system.h > b/xen/include/asm-arm/arm32/system.h > index 60148cb..b3736f4 100644 > --- a/xen/include/asm-arm/arm32/system.h > +++ b/xen/include/asm-arm/arm32/system.h > @@ -7,8 +7,8 @@ > #define wfi() __asm__ __volatile__ ("wfi" : : : "memory") > > #define isb() __asm__ __volatile__ ("isb" : : : "memory") > -#define dsb() __asm__ __volatile__ ("dsb" : : : "memory") > -#define dmb() __asm__ __volatile__ ("dmb" : : : "memory") > +#define dsb() __asm__ __volatile__ ("dsb sy" : : : "memory") > +#define dmb() __asm__ __volatile__ ("dmb sy" : : : "memory") > > #define mb() dsb() > #define rmb() dsb() > diff --git a/xen/include/asm-arm/page.h b/xen/include/asm-arm/page.h > index 41e9eff..cd38956 100644 > --- a/xen/include/asm-arm/page.h > +++ b/xen/include/asm-arm/page.h > @@ -185,7 +185,7 @@ typedef union { > /* Standard entry type that we'll use to build Xen's own pagetables. > * We put the same permissions at every level, because they're ignored > * by the walker in non-leaf entries. */ > -static inline lpae_t mfn_to_xen_entry(unsigned long mfn) > +static inline lpae_t mfn_to_xen_entry(unsigned long mfn, unsigned attr) > { > paddr_t pa = ((paddr_t) mfn) << PAGE_SHIFT; > lpae_t e = (lpae_t) { > @@ -193,10 +193,9 @@ static inline lpae_t mfn_to_xen_entry(unsigned long mfn) > .xn = 1, /* No need to execute outside .text */ > .ng = 1, /* Makes TLB flushes easier */ > .af = 1, /* No need for access tracking */ > - .sh = LPAE_SH_OUTER, /* Xen mappings are globally coherent */ > .ns = 1, /* Hyp mode is in the non-secure world */ > .user = 1, /* See below */ > - .ai = WRITEALLOC, > + .ai = attr, > .table = 0, /* Set to 1 for links and 4k maps */ > .valid = 1, /* Mappings are present */ > }};; > @@ -205,6 +204,37 @@ static inline lpae_t mfn_to_xen_entry(unsigned long mfn) > * pagetables un User mode it's OK. If this changes, remember > * to update the hard-coded values in head.S too */ > > + switch ( attr ) > + { > + case BUFFERABLE: > + /* > + * ARM ARM: Overlaying the shareability attribute (B3-1376 to 1377) It would be worth to indicate the revision of the ARM ARM here (in this instance DDI 0406C.b). > + * > + * A memory region with a resultant memory type attribute of Normal, > + * and a resultant cacheability attribute of Inner Non-cacheable, > + * Outer Non-cacheable, must have a resultant shareability attribute > + * of Outer Shareable, otherwise shareability is UNPREDICTABLE. > + * > + * On ARMv8 sharability is ignored and explicitly treated as Outer > + * Shareable for Normal Inner Non_cacheable, Outer Non-cacheable. > + */ > + e.pt.sh = LPAE_SH_OUTER; > + break; > + case UNCACHED: > + case DEV_SHARED: > + /* Shareability is ignored for non-Normal memory, Outer is as > + * good as anything. > + * > + * On ARMv8 sharability is ignored and explicitly treated as Outer > + * Shareable for any device memory type. > + */ > + e.pt.sh = LPAE_SH_OUTER; > + break; > + default: > + e.pt.sh = LPAE_SH_INNER; /* Xen mappings are SMP coherent */ > + break; > + } > + > ASSERT(!(pa & ~PAGE_MASK)); > ASSERT(!(pa & ~PADDR_MASK)); > > @@ -219,7 +249,7 @@ static inline lpae_t mfn_to_p2m_entry(unsigned long mfn, > unsigned int mattr) > lpae_t e = (lpae_t) { > .p2m.xn = 0, > .p2m.af = 1, > - .p2m.sh = LPAE_SH_OUTER, > + .p2m.sh = LPAE_SH_INNER, > .p2m.write = 1, > .p2m.read = 1, > .p2m.mattr = mattr, > -- > 1.7.2.5 > _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |