[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v4 10/14] xen/x86: populate PVHv2 Dom0 physical memory map
>>> On 16.12.16 at 18:38, <roger.pau@xxxxxxxxxx> wrote: > On Fri, Dec 09, 2016 at 09:48:32AM -0700, Jan Beulich wrote: >> >>> On 30.11.16 at 17:49, <roger.pau@xxxxxxxxxx> wrote: >> > @@ -545,11 +552,12 @@ static __init void pvh_map_all_iomem(struct domain >> > *d, unsigned long nr_pages) >> > ASSERT(nr_holes == 0); >> > } >> > >> > -static __init void pvh_setup_e820(struct domain *d, unsigned long >> > nr_pages) >> > +static __init void hvm_setup_e820(struct domain *d, unsigned long >> > nr_pages) >> >> Why? > > So that afterwards I can remove all the pvh_ functions and leave the hvm_ ones > only. But seeing your response to the other patch, would you prefer me to just > use pvh_ for the new functions also? Yes. After all the intention is to rip out all PVHv1 stuff. >> > @@ -577,8 +585,19 @@ static __init void pvh_setup_e820(struct domain *d, >> > unsigned long nr_pages) >> > continue; >> > } >> > >> > - *entry_guest = *entry; >> > - pages = PFN_UP(entry_guest->size); >> > + /* >> > + * Make sure the start and length are aligned to PAGE_SIZE, >> > because >> > + * that's the minimum granularity of the 2nd stage translation. >> > + */ >> > + start = ROUNDUP(entry->addr, PAGE_SIZE); >> > + end = (entry->addr + entry->size) & PAGE_MASK; >> >> Taking the comment into consideration, I wonder whether you >> wouldn't better use PAGE_ORDER_4K here, as that's what the >> p2m code uses. > > That's going to be more cumbersome, since PAGE_SIZE would become 1UL << > PAGE_ORDER_4K << PAGE_SHIFT, and PAGE_MASK is going to be -1 and ~ of the > previous construct. But I see your point, maybe I should define PAGE_SIZE_4K > and PAGE_MASK_4K in xen/include/asm-x86/page.h? That's an option, but considering the p2m code has got along without it so far, I'm not fully convinced we need it. Perhaps get an opinion from George (as the x86/mm maintainer). >> > +static int __init hvm_setup_p2m(struct domain *d) >> > +{ >> > + struct vcpu *v = d->vcpu[0]; >> > + unsigned long nr_pages; >> > + unsigned int i; >> > + int rc; >> > + bool preempted; >> > +#define MB1_PAGES PFN_DOWN(MB(1)) >> > + >> > + nr_pages = compute_dom0_nr_pages(d, NULL, 0); >> > + >> > + hvm_setup_e820(d, nr_pages); >> > + do { >> > + preempted = false; >> > + paging_set_allocation(d, dom0_paging_pages(d, nr_pages), >> > + &preempted); >> > + process_pending_softirqs(); >> > + } while ( preempted ); >> > + >> > + /* >> > + * Memory below 1MB is identity mapped. >> > + * NB: this only makes sense when booted from legacy BIOS. >> > + */ >> > + rc = modify_identity_mmio(d, 0, PFN_DOWN(MB(1)), true); >> > + if ( rc ) >> > + { >> > + printk("Failed to identity map low 1MB: %d\n", rc); >> > + return rc; >> > + } >> > + >> > + /* Populate memory map. */ >> > + for ( i = 0; i < d->arch.nr_e820; i++ ) >> > + { >> > + unsigned long addr, size; >> > + >> > + if ( d->arch.e820[i].type != E820_RAM ) >> > + continue; >> > + >> > + addr = PFN_DOWN(d->arch.e820[i].addr); >> > + size = PFN_DOWN(d->arch.e820[i].size); >> > + >> > + if ( addr >= MB1_PAGES ) >> > + rc = hvm_populate_memory_range(d, addr, size); >> > + else if ( addr + size > MB1_PAGES ) >> > + { >> > + hvm_steal_low_ram(d, addr, MB1_PAGES - addr); >> > + rc = hvm_populate_memory_range(d, MB1_PAGES, >> > + size - (MB1_PAGES - addr)); >> >> Is this case possible at all? All x86 systems have some form of >> BIOS right below the 1Mb boundary, and the E820 map for >> Dom0 is being derived from the host one. > > Heh, I don't think so but I wanted to cover all possible inputs. TBH I have no > idea how broken e820 memory maps can really be. > > Would you be fine with removing this case and adding an ASSERT instead? Yes; in fact that would be my preference. >> > + /* Remove the owner and clear the flags. */ >> > + page_set_owner(page, NULL); >> > + page->u.inuse.type_info = 0; >> >> I think you'd better bail early if this is non-zero. Or else please use >> the order used elsewhere (clearing type info, then owner) - while >> it's benign, it avoids someone later wondering whether the order >> is wrong in either place. > > It's certainly going to be non-zero, because share_xen_page_with_guests sets > it > to: > > page->u.inuse.type_info = (readonly ? PGT_none : PGT_writable_page); > page->u.inuse.type_info |= PGT_validated | 1; > > I've ended up coding it as: > > int __init unshare_xen_page_with_guest(struct page_info *page, > struct domain *d) > { > if ( page_get_owner(page) != d || !is_xen_heap_page(page) ) > return -EINVAL; > > if ( test_and_clear_bit(_PGC_allocated, &page->count_info) ) > put_page(page); > > /* Remove the owner and clear the flags. */ > page->u.inuse.type_info = 0; > page_set_owner(page, NULL); > > return 0; > } This looks good, thanks. Jan _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |