[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v2 02/21] xen/arm: make allocate_memory work for non 1:1 mapped guests
On Mon, 9 Jul 2018, Julien Grall wrote: > Hi Stefano, > > On 07/07/18 00:11, Stefano Stabellini wrote: > > Extend allocate_memory to work for non 1:1 mapped domUs. Specifically, > > memory allocated for domU will be mapped into the domU pseudo-physical > > address space at the appropriate addresses according to the guest memory > > map: GUEST_RAM0_BASE and GUEST_RAM1_BASE. > > > > To do that, insert_11_bank has been extended to deal with non-dom0 > > mappings starting from GUEST_RAM0_BASE. insert_11_bank has been renamed > > to insert_bank. > > > > Signed-off-by: Stefano Stabellini <stefanos@xxxxxxxxxx> > > > > --- > > Changes in v2: > > - new patch > > --- > > xen/arch/arm/domain_build.c | 57 > > ++++++++++++++++++++++++++++++++++----------- > > 1 file changed, 44 insertions(+), 13 deletions(-) > > > > diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c > > index 182e3d5..2a6619a 100644 > > --- a/xen/arch/arm/domain_build.c > > +++ b/xen/arch/arm/domain_build.c > > @@ -97,27 +97,51 @@ static unsigned int get_allocation_size(paddr_t size) > > * Returns false if the memory would be below bank 0 or we have run > > * out of banks. In this case it will free the pages. > > */ > > -static bool insert_11_bank(struct domain *d, > > - struct kernel_info *kinfo, > > - struct page_info *pg, > > - unsigned int order) > > +static bool insert_bank(struct domain *d, > > + struct kernel_info *kinfo, > > + struct page_info *pg, > > + unsigned int order, > > + bool map_11) > > { > > - int res, i; > > + int res, i, nr_mem_banks = map_11 ? NR_MEM_BANKS : 2; > > nr_mem_banks should be unsigned. I also would drop "mem_" to shorten a bit the > name. OK > > mfn_t smfn; > > paddr_t start, size; > > + struct membank *bank; > > smfn = page_to_mfn(pg); > > start = mfn_to_maddr(smfn); > > The new code is pretty horrible to read. Can you please add some comments to > help understanding it? > > Here is already an example where you set start to MFN. But then override after > with none comment to understand why. > > Also, this code as always assumed MFN == GFN so start was making sense. Now, > you re-purpose it to just the guest-physical address. So more likely you want > to rework the code a bit. I'll add more comments in the code. Next time the patch will be clearer. This is a snippet to give you an idea, but it might be best for you to just wait for the next version before reading this again. /* * smfn: the address of the set of pages to map * start: the address in guest pseudo-physical memory where to map * the pages */ smfn = page_to_mfn(pg); start = mfn_to_maddr(smfn); size = pfn_to_paddr(1UL << order); if ( !is_hardware_domain(d) ) { /* * Dom0 is 1:1 mapped, so start is the same as (smfn << * PAGE_SHIFT). * * Instead, DomU memory is provided in two banks: * GUEST_RAM0_BASE - GUEST_RAM0_BASE + GUEST_RAM0_SIZE * GUEST_RAM1_BASE - GUEST_RAM1_BASE + GUEST_RAM1_SIZE * * Find the right start address for DomUs accordingly. */ > > size = pfn_to_paddr(1UL << order); > > + if ( !map_11 ) > > I am not sure why map_11 would mean DomU? I don't see any reason to not allow > that for Dom0. Note that I am not asking to do it, just having clearer name. Good point. I think I should just drop the option, which is just confusing, and keep using is_hardware_domain(d) checks like in allocate_memory. Otherwise let me know if you have a better idea. > > + { > > + start = GUEST_RAM0_BASE; > > + if ( kinfo->mem.nr_banks > 0 ) > > + { > > + for( i = 0; i < kinfo->mem.nr_banks; i++ ) > > + { > > + bank = &kinfo->mem.bank[i]; > > + start = bank->start + bank->size; > > + } > > + if ( bank->start == GUEST_RAM0_BASE && > > + start + size > (GUEST_RAM0_BASE + GUEST_RAM0_SIZE) ) > > The indentation looks wrong. OK > > + start = GUEST_RAM1_BASE; > > + if ( bank->start == GUEST_RAM1_BASE && > > + start + size > (GUEST_RAM1_BASE + GUEST_RAM1_SIZE) ) > > + { > > + D11PRINT("Allocation of domain memory exceeds max > > amount\n"); > > This looks quite strange to use D11PRINT here as this related to direct-domain > mapped. You are right, but I didn't feel like replacing all D11PRINT occurrences. Should I do that? Or should I change just this instance? I could also just drop this D11PRINT, given that the printk is not even enabled by default. Let me know. > > + goto fail; > > + } > > + } > > + } > > - D11PRINT("Allocated %#"PRIpaddr"-%#"PRIpaddr" (%ldMB/%ldMB, order > > %d)\n", > > + D11PRINT("Allocated %#"PRIpaddr"-%#"PRIpaddr":%#"PRIpaddr"-%#"PRIpaddr" > > (%ldMB/%ldMB, order %d)\n", > > + mfn_to_maddr(smfn), mfn_to_maddr(smfn) + size, > > start, start + size, > > 1UL << (order + PAGE_SHIFT - 20), > > /* Don't want format this as PRIpaddr (16 digit hex) */ > > (unsigned long)(kinfo->unassigned_mem >> 20), > > order); > > - if ( kinfo->mem.nr_banks > 0 && > > + if ( map_11 && kinfo->mem.nr_banks > 0 && > > Why do you drop that check? It should be harmless for non-direct mapped > domain. You are right. I'll remove this change. > > size < MB(128) && > start + size < > > kinfo->mem.bank[0].start ) > > { > > @@ -125,7 +149,7 @@ static bool insert_11_bank(struct domain *d, > > goto fail; > > } > > - res = guest_physmap_add_page(d, _gfn(mfn_x(smfn)), smfn, order); > > + res = guest_physmap_add_page(d, gaddr_to_gfn(start), smfn, order); > > if ( res ) > > panic("Failed map pages to DOM0: %d", res); > > @@ -141,7 +165,7 @@ static bool insert_11_bank(struct domain *d, > > for( i = 0; i < kinfo->mem.nr_banks; i++ ) > > { > > - struct membank *bank = &kinfo->mem.bank[i]; > > + bank = &kinfo->mem.bank[i]; > > /* If possible merge new memory into the start of the bank */ > > if ( bank->start == start+size ) > > @@ -164,7 +188,7 @@ static bool insert_11_bank(struct domain *d, > > * could have inserted the memory into/before we would already > > * have done so, so this must be the right place. > > */ > > - if ( start + size < bank->start && kinfo->mem.nr_banks < > > NR_MEM_BANKS ) > > + if ( start + size < bank->start && kinfo->mem.nr_banks < > > nr_mem_banks ) > > { > > memmove(bank + 1, bank, > > sizeof(*bank) * (kinfo->mem.nr_banks - i)); > > @@ -175,7 +199,7 @@ static bool insert_11_bank(struct domain *d, > > } > > } > > - if ( i == kinfo->mem.nr_banks && kinfo->mem.nr_banks < NR_MEM_BANKS ) > > + if ( i == kinfo->mem.nr_banks && kinfo->mem.nr_banks < nr_mem_banks ) > > { > > struct membank *bank = &kinfo->mem.bank[kinfo->mem.nr_banks]; > > @@ -253,6 +277,7 @@ static void allocate_memory(struct domain *d, struct > > kernel_info *kinfo) > > struct page_info *pg; > > unsigned int order = get_allocation_size(kinfo->unassigned_mem); > > int i; > > + bool hwdom = d->domain_id == 0; > > You should use is_hardware_domain(...). Yes, I'll do that here and elsewhere in this patch > > bool lowmem = true; > > unsigned int bits; > > @@ -263,6 +288,12 @@ static void allocate_memory(struct domain *d, struct > > kernel_info *kinfo) > > kinfo->mem.nr_banks = 0; > > + if ( !hwdom ) > > + { > > + lowmem = false; > > + goto got_bank0; > > + } > > Can you explain why you need this? Yes, I'll add a comment. The first part of allocate_memory tries to allocate memory as low as possible, which is fine for dom0 but it is unnecessary for DomUs, given that they are not 1:1 mapped. So, this check is meant to go straight to the regular allocation for DomUs, skipping the special below-4G allocation loop. > > + > > /* > > * First try and allocate the largest thing we can as low as > > * possible to be bank 0. > > @@ -274,7 +305,7 @@ static void allocate_memory(struct domain *d, struct > > kernel_info *kinfo) > > pg = alloc_domheap_pages(d, order, MEMF_bits(bits)); > > if ( pg != NULL ) > > { > > - if ( !insert_11_bank(d, kinfo, pg, order) ) > > + if ( !insert_bank(d, kinfo, pg, order, hwdom) ) > > BUG(); /* Cannot fail for first bank */ > > goto got_bank0; > > @@ -319,7 +350,7 @@ static void allocate_memory(struct domain *d, struct > > kernel_info *kinfo) > > break; > > } > > - if ( !insert_11_bank(d, kinfo, pg, order) ) > > + if ( !insert_bank(d, kinfo, pg, order, hwdom) ) > > { > > if ( kinfo->mem.nr_banks == NR_MEM_BANKS ) > > /* Nothing more we can do. */ > > _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |