[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v2 45/62] 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. Also set the correct values in the start_info for DomU operation. Signed-off-by: Roger Pau Monné <roger.pau@xxxxxxxxxx> --- Changes since v1: - Modify the position of the __init attribute in dom0_update_physmap. - Move the addition of sizeof(struct dom0_vga_console_info) to vstartinfo_end with an existing if branch. - Add a TODO item for fill_console_start_info in the !CONFIG_VIDEO case. - s/replace_va/replace_va_mapping/. - Remove call to free_domheap_pages in replace_va_mapping. put_page_and_type should already take care of freeing the page. - Use PFN_DOWN in SET_AND_MAP_PARAM macro. - Parenthesize va in SET_AND_MAP_PARAM macro when required. --- xen/arch/x86/pv/dom0_build.c | 48 +++++++++++++++++++++++------- xen/arch/x86/pv/shim.c | 63 ++++++++++++++++++++++++++++++++++++++++ xen/include/asm-x86/dom0_build.h | 4 +++ xen/include/asm-x86/pv/shim.h | 21 ++++++++++++++ 4 files changed, 126 insertions(+), 10 deletions(-) diff --git a/xen/arch/x86/pv/dom0_build.c b/xen/arch/x86/pv/dom0_build.c index 6118970d44..52576795cc 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) +void __init 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; @@ -315,6 +314,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; @@ -440,11 +443,22 @@ int __init dom0_construct_pv(struct domain *d, if ( parms.p2m_base != UNSET_ADDR ) vphysmap_end = vphysmap_start; vstartinfo_start = round_pgup(vphysmap_end); - vstartinfo_end = (vstartinfo_start + - sizeof(struct start_info) + - sizeof(struct dom0_vga_console_info)); + vstartinfo_end = vstartinfo_start + sizeof(struct start_info); + + 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); + vstartinfo_end += sizeof(struct dom0_vga_console_info); + } - vpt_start = round_pgup(vstartinfo_end); for ( nr_pt_pages = 2; ; nr_pt_pages++ ) { vpt_end = vpt_start + (nr_pt_pages * PAGE_SIZE); @@ -537,6 +551,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", @@ -544,6 +560,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)); @@ -737,7 +755,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; @@ -829,15 +848,24 @@ 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 + /* + * TODO: provide an empty stub for fill_console_start_info in the + * !CONFIG_VIDEO case so the logic here can be simplified. + */ + 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..75365b0697 100644 --- a/xen/arch/x86/pv/shim.c +++ b/xen/arch/x86/pv/shim.c @@ -18,16 +18,79 @@ * * 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_mapping(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)); + put_page_and_type(page); + + *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 ) \ + { \ + share_xen_page_with_guest(mfn_to_page(param), d, XENSHARE_writable); \ + replace_va_mapping(d, l4start, va, param); \ + dom0_update_physmap(d, PFN_DOWN((va) - va_start), 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 25d124f8d4..33a5483739 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> @@ -27,6 +28,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 |