[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH RFC v1 53/74] xen/pvshim: modify Dom0 builder in order to build a DomU
>>> On 04.01.18 at 14:06, <wei.liu2@xxxxxxxxxx> wrote: > From: Roger Pau Monne <roger.pau@xxxxxxxxxx> > > According to the PV ABI the initial virtual memory regions should > contain the xenstore and console pages after the start_info. Fix this > and add the pages to the p2m/m2p after the start_info page also. I don't think "fix" is the right term here. > --- a/xen/arch/x86/pv/dom0_build.c > +++ b/xen/arch/x86/pv/dom0_build.c > @@ -31,9 +31,8 @@ > #define L3_PROT (BASE_PROT|_PAGE_DIRTY) > #define L4_PROT (BASE_PROT|_PAGE_DIRTY) > > -static __init void dom0_update_physmap(struct domain *d, unsigned long pfn, > - unsigned long mfn, > - unsigned long vphysmap_s) > +__init void dom0_update_physmap(struct domain *d, unsigned long pfn, Please don't re-order type and annotation. > @@ -443,9 +446,18 @@ int __init dom0_construct_pv(struct domain *d, > vstartinfo_start = round_pgup(vphysmap_end); > vstartinfo_end = (vstartinfo_start + > sizeof(struct start_info) + > - sizeof(struct dom0_vga_console_info)); > + (pv_shim ? 0 : sizeof(struct > dom0_vga_console_info))); Why not move this addition ... > - vpt_start = round_pgup(vstartinfo_end); > + if ( pv_shim ) > + { > + vxenstore_start = round_pgup(vstartinfo_end); > + vxenstore_end = vxenstore_start + PAGE_SIZE; > + vconsole_start = vxenstore_end; > + vconsole_end = vconsole_start + PAGE_SIZE; > + vpt_start = vconsole_end; > + } > + else > + vpt_start = round_pgup(vstartinfo_end); ... into this "else" block. > @@ -538,6 +550,8 @@ int __init dom0_construct_pv(struct domain *d, > " Init. ramdisk: %p->%p\n" > " Phys-Mach map: %p->%p\n" > " Start info: %p->%p\n" > + " Xenstore ring: %p->%p\n" > + " Console ring: %p->%p\n" > " Page tables: %p->%p\n" > " Boot stack: %p->%p\n" > " TOTAL: %p->%p\n", > @@ -545,6 +559,8 @@ int __init dom0_construct_pv(struct domain *d, > _p(vinitrd_start), _p(vinitrd_end), > _p(vphysmap_start), _p(vphysmap_end), > _p(vstartinfo_start), _p(vstartinfo_end), > + _p(vxenstore_start), _p(vxenstore_end), > + _p(vconsole_start), _p(vconsole_end), I'm not convinced the extra verbosity is helpful - the pages are at fixed offsets from start_info, which already is being logged. > @@ -830,15 +847,20 @@ int __init dom0_construct_pv(struct domain *d, > strlcpy((char *)si->cmd_line, cmdline, sizeof(si->cmd_line)); > > #ifdef CONFIG_VIDEO > - if ( fill_console_start_info((void *)(si + 1)) ) > + if ( !pv_shim && fill_console_start_info((void *)(si + 1)) ) > { > si->console.dom0.info_off = sizeof(struct start_info); > si->console.dom0.info_size = sizeof(struct dom0_vga_console_info); > } > #endif > > + if ( pv_shim ) > + pv_shim_setup_dom(d, l4start, v_start, vxenstore_start, > vconsole_start, > + vphysmap_start, si); With fill_console_start_info() being given a stub in the !CONFIG_VIDEO case (ideally right in the earlier patch), this could become if ( pv_shim ) pv_shim_setup_dom(d, l4start, v_start, vxenstore_start, vconsole_start, vphysmap_start, si); else if ( fill_console_start_info((void *)(si + 1)) ) { si->console.dom0.info_off = sizeof(struct start_info); si->console.dom0.info_size = sizeof(struct dom0_vga_console_info); } > +static void __init replace_va(struct domain *d, l4_pgentry_t *l4start, > + unsigned long va, unsigned long mfn) I tdoesn't look like you're replacing a VA here (and really: how could you?), so how about "replace_va_mapping()"? > +{ > + struct page_info *page; > + l4_pgentry_t *pl4e; > + l3_pgentry_t *pl3e; > + l2_pgentry_t *pl2e; > + l1_pgentry_t *pl1e; > + > + pl4e = l4start + l4_table_offset(va); > + pl3e = l4e_to_l3e(*pl4e); > + pl3e += l3_table_offset(va); > + pl2e = l3e_to_l2e(*pl3e); > + pl2e += l2_table_offset(va); > + pl1e = l2e_to_l1e(*pl2e); > + pl1e += l1_table_offset(va); > + > + page = mfn_to_page(l1e_get_pfn(*pl1e)); > + /* Free original page, will be replaced */ > + put_page_and_type(page); > + free_domheap_pages(page, 0); This looks bogus - free_domheap_pages() should be called by the last put_page(), not directly. If that doesn't happen, I would guess you need the usual PGC_allocated clearing logic here. > +void __init pv_shim_setup_dom(struct domain *d, l4_pgentry_t *l4start, > + unsigned long va_start, unsigned long store_va, > + unsigned long console_va, unsigned long > vphysmap, > + start_info_t *si) > +{ > + uint64_t param = 0; > + long rc; > + > +#define SET_AND_MAP_PARAM(p, si, va) ({ > \ > + rc = xen_hypercall_hvm_get_param(p, ¶m); > \ > + if ( rc ) > \ > + panic("Unable to get " #p "\n"); > \ > + (si) = param; > \ > + if ( va ) > \ > + { > \ > + BUG_ON(unshare_xen_page_with_guest(mfn_to_page(param), dom_io)); > \ > + share_xen_page_with_guest(mfn_to_page(param), d, XENSHARE_writable); > \ > + replace_va(d, l4start, va, param); > \ > + dom0_update_physmap(d, (va - va_start) >> PAGE_SHIFT, param, > vphysmap);\ PFN_DOWN() > + } > \ > +}) > + SET_AND_MAP_PARAM(HVM_PARAM_STORE_PFN, si->store_mfn, store_va); > + SET_AND_MAP_PARAM(HVM_PARAM_STORE_EVTCHN, si->store_evtchn, 0); > + if ( !pv_console ) > + { > + SET_AND_MAP_PARAM(HVM_PARAM_CONSOLE_PFN, si->console.domU.mfn, > + console_va); > + SET_AND_MAP_PARAM(HVM_PARAM_CONSOLE_EVTCHN, si->console.domU.evtchn, > 0); > + } > +#undef SET_AND_MAP_PARAM Here, even more than earlier on, it becomes rather desirable to move the HVM_PARAM_ prefixes into the macro. But yes, I know at least Andrew won't like it ... Jan _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |