[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 16/17] [V3]PVH xen: elf and iommu related changes to prep for dom0 PVH
This patch prepares for dom0 PVH by making some changes in the elf code; add a new parameter to indicate PVH dom0 and use different copy function for PVH. Also, add check in iommu.c to check for iommu enabled for dom0 PVH. Changes in V2: None Changes in V3: - introduct early_pvh_copy_or_zero() to replace dbg_rw_mem(). Signed-off-by: Mukesh Rathor <mukesh.rathor@xxxxxxxxxx> --- xen/arch/x86/domain_build.c | 39 +++++++++++++++++++++++++++++++++++- xen/common/libelf/libelf-loader.c | 40 +++++++++++++++++++++++++++++++++--- xen/drivers/passthrough/iommu.c | 22 ++++++++++++++++++- xen/include/xen/libelf.h | 3 +- 4 files changed, 96 insertions(+), 8 deletions(-) diff --git a/xen/arch/x86/domain_build.c b/xen/arch/x86/domain_build.c index c8f435d..f8cae52 100644 --- a/xen/arch/x86/domain_build.c +++ b/xen/arch/x86/domain_build.c @@ -307,6 +307,43 @@ static void __init process_dom0_ioports_disable(void) } } + /* + * Copy or zero function for dom0 only during boot. This because + * raw_copy_to_guest -> copy_to_user_hvm -> __hvm_copy needs curr to + * point to the hvm/pvh vcpu which is not all setup yet. + * + * If src is NULL, then len bytes are zeroed. + */ +void __init early_pvh_copy_or_zero(unsigned long dest, char *src, int len, + unsigned long v_start) +{ + while ( len > 0 ) + { + char *va; + p2m_type_t gfntype; + unsigned long mfn, gfn, pagecnt; + struct domain *d = get_domain_by_id(0); + + pagecnt = min_t(unsigned long, PAGE_SIZE - (dest & ~PAGE_MASK), len); + + gfn = (dest - v_start) >> PAGE_SHIFT; + if ( (mfn = mfn_x(get_gfn_query(d, gfn, &gfntype))) == INVALID_MFN ) + panic("Unable to get mfn for gfn:%lx\n", gfn); + put_gfn(d, gfn); + + va = map_domain_page(mfn) + (dest & (PAGE_SIZE-1)); + if ( src ) + memcpy(va, src, pagecnt); + else + memset(va, 0, pagecnt); + unmap_domain_page(va); + + dest += pagecnt; + src = src ? src + pagecnt : 0; + len -= pagecnt; + } +} + int __init construct_dom0( struct domain *d, const module_t *image, unsigned long image_headroom, @@ -766,7 +803,7 @@ int __init construct_dom0( /* Copy the OS image and free temporary buffer. */ elf.dest = (void*)vkern_start; - rc = elf_load_binary(&elf); + rc = elf_load_binary(&elf, (is_pvh_domain(d) ? v_start : 0)); if ( rc < 0 ) { printk("Failed to load the kernel binary\n"); diff --git a/xen/common/libelf/libelf-loader.c b/xen/common/libelf/libelf-loader.c index 3cf9c59..012c00c 100644 --- a/xen/common/libelf/libelf-loader.c +++ b/xen/common/libelf/libelf-loader.c @@ -108,7 +108,8 @@ void elf_set_log(struct elf_binary *elf, elf_log_callback *log_callback, elf->verbose = verbose; } -static int elf_load_image(void *dst, const void *src, uint64_t filesz, uint64_t memsz) +static int elf_load_image(void *dst, const void *src, uint64_t filesz, + uint64_t memsz, int not_used) { memcpy(dst, src, filesz); memset(dst + filesz, 0, memsz - filesz); @@ -122,11 +123,25 @@ void elf_set_verbose(struct elf_binary *elf) elf->verbose = 1; } -static int elf_load_image(void *dst, const void *src, uint64_t filesz, uint64_t memsz) +extern void __init early_pvh_copy_or_zero(unsigned long dest, char *src, + int len, unsigned long v_start); + +static int elf_load_image(void *dst, const void *src, uint64_t filesz, + uint64_t memsz, unsigned long v_start) { int rc; if ( filesz > ULONG_MAX || memsz > ULONG_MAX ) return -1; + + if ( v_start ) + { + unsigned long addr = (unsigned long)dst; + early_pvh_copy_or_zero(addr, (char *)src, filesz, v_start); + early_pvh_copy_or_zero(addr + filesz, NULL, memsz - filesz, v_start); + + return 0; + } + rc = raw_copy_to_guest(dst, src, filesz); if ( rc != 0 ) return -1; @@ -260,7 +275,11 @@ void elf_parse_binary(struct elf_binary *elf) __FUNCTION__, elf->pstart, elf->pend); } -int elf_load_binary(struct elf_binary *elf) +/* + * This function called from the libraries when building guests, and also for + * dom0 from construct_dom0(). + */ +static int _elf_load_binary(struct elf_binary *elf, unsigned long v_start) { const elf_phdr *phdr; uint64_t i, count, paddr, offset, filesz, memsz; @@ -279,7 +298,8 @@ int elf_load_binary(struct elf_binary *elf) dest = elf_get_ptr(elf, paddr); elf_msg(elf, "%s: phdr %" PRIu64 " at 0x%p -> 0x%p\n", __func__, i, dest, dest + filesz); - if ( elf_load_image(dest, elf->image + offset, filesz, memsz) != 0 ) + if ( elf_load_image(dest, elf->image + offset, filesz, memsz, + v_start) != 0 ) return -1; } @@ -287,6 +307,18 @@ int elf_load_binary(struct elf_binary *elf) return 0; } +#ifdef __XEN__ +int elf_load_binary(struct elf_binary *elf, unsigned long v_start) +{ + return _elf_load_binary(elf, v_start); +} +#else +int elf_load_binary(struct elf_binary *elf) +{ + return _elf_load_binary(elf, 0); +} +#endif + void *elf_get_ptr(struct elf_binary *elf, unsigned long addr) { return elf->dest + addr - elf->pstart; diff --git a/xen/drivers/passthrough/iommu.c b/xen/drivers/passthrough/iommu.c index c1d3c12..2555ba0 100644 --- a/xen/drivers/passthrough/iommu.c +++ b/xen/drivers/passthrough/iommu.c @@ -125,15 +125,25 @@ int iommu_domain_init(struct domain *d) return hd->platform_ops->init(d); } +static inline void check_dom0_pvh_reqs(struct domain *d) +{ + if (!iommu_enabled || iommu_passthrough) + panic("For pvh dom0, iommu must be enabled, dom0-passthrough must " + "not be enabled \n"); +} + void __init iommu_dom0_init(struct domain *d) { struct hvm_iommu *hd = domain_hvm_iommu(d); + if ( is_pvh_domain(d) ) + check_dom0_pvh_reqs(d); + if ( !iommu_enabled ) return; register_keyhandler('o', &iommu_p2m_table); - d->need_iommu = !!iommu_dom0_strict; + d->need_iommu = is_pvh_domain(d) || !!iommu_dom0_strict; if ( need_iommu(d) ) { struct page_info *page; @@ -146,7 +156,15 @@ void __init iommu_dom0_init(struct domain *d) ((page->u.inuse.type_info & PGT_type_mask) == PGT_writable_page) ) mapping |= IOMMUF_writable; - hd->platform_ops->map_page(d, mfn, mfn, mapping); + + if ( is_pvh_domain(d) ) + { + unsigned long gfn = mfn_to_gfn(d, _mfn(mfn)); + hd->platform_ops->map_page(d, gfn, mfn, mapping); + } + else + hd->platform_ops->map_page(d, mfn, mfn, mapping); + if ( !(i++ & 0xfffff) ) process_pending_softirqs(); } diff --git a/xen/include/xen/libelf.h b/xen/include/xen/libelf.h index 218bb18..9d695b7 100644 --- a/xen/include/xen/libelf.h +++ b/xen/include/xen/libelf.h @@ -192,13 +192,14 @@ int elf_phdr_is_loadable(struct elf_binary *elf, const elf_phdr * phdr); int elf_init(struct elf_binary *elf, const char *image, size_t size); #ifdef __XEN__ void elf_set_verbose(struct elf_binary *elf); +int elf_load_binary(struct elf_binary *elf, unsigned long v_start); #else void elf_set_log(struct elf_binary *elf, elf_log_callback*, void *log_caller_pointer, int verbose); +int elf_load_binary(struct elf_binary *elf); #endif void elf_parse_binary(struct elf_binary *elf); -int elf_load_binary(struct elf_binary *elf); void *elf_get_ptr(struct elf_binary *elf, unsigned long addr); uint64_t elf_lookup_addr(struct elf_binary *elf, const char *symbol); -- 1.7.2.3 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |