[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH RFC v1 53/74] xen/pvshim: modify Dom0 builder in order to build a DomU
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. Also set the correct values in the start_info for DomU operation. Signed-off-by: Roger Pau Monné <roger.pau@xxxxxxxxxx> --- xen/arch/x86/pv/dom0_build.c | 38 ++++++++++++++++++----- xen/arch/x86/pv/shim.c | 66 ++++++++++++++++++++++++++++++++++++++++ xen/include/asm-x86/dom0_build.h | 4 +++ xen/include/asm-x86/pv/shim.h | 21 +++++++++++++ 4 files changed, 121 insertions(+), 8 deletions(-) diff --git a/xen/arch/x86/pv/dom0_build.c b/xen/arch/x86/pv/dom0_build.c index 95347c6fd2..e152fe3a9e 100644 --- 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, + unsigned long mfn, unsigned long vphysmap_s) { if ( !is_pv_32bit_domain(d) ) ((unsigned long *)vphysmap_s)[pfn] = mfn; @@ -316,6 +315,10 @@ int __init dom0_construct_pv(struct domain *d, unsigned long vphysmap_end; unsigned long vstartinfo_start; unsigned long vstartinfo_end; + unsigned long vxenstore_start = 0; + unsigned long vxenstore_end = 0; + unsigned long vconsole_start = 0; + unsigned long vconsole_end = 0; unsigned long vstack_start; unsigned long vstack_end; unsigned long vpt_start; @@ -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))); - 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); for ( nr_pt_pages = 2; ; nr_pt_pages++ ) { vpt_end = vpt_start + (nr_pt_pages * PAGE_SIZE); @@ -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), _p(vpt_start), _p(vpt_end), _p(vstack_start), _p(vstack_end), _p(v_start), _p(v_end)); @@ -738,7 +754,8 @@ int __init dom0_construct_pv(struct domain *d, si->shared_info = virt_to_maddr(d->shared_info); - si->flags = SIF_PRIVILEGED | SIF_INITDOMAIN; + if ( !pv_shim ) + si->flags = SIF_PRIVILEGED | SIF_INITDOMAIN; if ( !vinitrd_start && initrd_len ) si->flags |= SIF_MOD_START_PFN; si->flags |= (xen_processor_pmbits << 8) & SIF_PM_MASK; @@ -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); + if ( is_pv_32bit_domain(d) ) - xlat_start_info(si, XLAT_start_info_console_dom0); + xlat_start_info(si, pv_shim ? XLAT_start_info_console_domU + : XLAT_start_info_console_dom0); /* Return to idle domain's page tables. */ mapcache_override_current(NULL); diff --git a/xen/arch/x86/pv/shim.c b/xen/arch/x86/pv/shim.c index 4d037355db..5e7e46632b 100644 --- a/xen/arch/x86/pv/shim.c +++ b/xen/arch/x86/pv/shim.c @@ -18,16 +18,82 @@ * * Copyright (c) 2017 Citrix Systems Ltd. */ +#include <xen/hypercall.h> #include <xen/init.h> #include <xen/types.h> #include <asm/apic.h> +#include <asm/dom0_build.h> +#include <asm/guest.h> +#include <asm/pv/mm.h> #ifndef CONFIG_PV_SHIM_EXCLUSIVE bool pv_shim; boolean_param("pv-shim", pv_shim); #endif +#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_USER| \ + _PAGE_GUEST_KERNEL) +#define COMPAT_L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED) + +static void __init replace_va(struct domain *d, l4_pgentry_t *l4start, + unsigned long va, unsigned long mfn) +{ + 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); + + *pl1e = l1e_from_pfn(mfn, (!is_pv_32bit_domain(d) ? L1_PROT + : COMPAT_L1_PROT)); +} + +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);\ + } \ +}) + 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 +} + /* * Local variables: * mode: C diff --git a/xen/include/asm-x86/dom0_build.h b/xen/include/asm-x86/dom0_build.h index d83d2b4387..d985406503 100644 --- a/xen/include/asm-x86/dom0_build.h +++ b/xen/include/asm-x86/dom0_build.h @@ -1,6 +1,7 @@ #ifndef _DOM0_BUILD_H_ #define _DOM0_BUILD_H_ +#include <xen/libelf.h> #include <xen/sched.h> #include <asm/setup.h> @@ -29,6 +30,9 @@ int dom0_construct_pvh(struct domain *d, const module_t *image, unsigned long dom0_paging_pages(const struct domain *d, unsigned long nr_pages); +void dom0_update_physmap(struct domain *d, unsigned long pfn, + unsigned long mfn, unsigned long vphysmap_s); + #endif /* _DOM0_BUILD_H_ */ /* diff --git a/xen/include/asm-x86/pv/shim.h b/xen/include/asm-x86/pv/shim.h index 1468cfd498..b0c361cba1 100644 --- a/xen/include/asm-x86/pv/shim.h +++ b/xen/include/asm-x86/pv/shim.h @@ -29,6 +29,27 @@ extern bool pv_shim; # define pv_shim 0 #endif /* CONFIG_PV_SHIM{,_EXCLUSIVE} */ +#ifdef CONFIG_PV_SHIM + +void 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); + +#else + +static inline void 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) +{ + ASSERT_UNREACHABLE(); +} + +#endif + #endif /* __X86_PV_SHIM_H__ */ /* -- 2.11.0 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |