Message ID | 20170222142459.28199-5-roger.pau@citrix.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
>>> On 22.02.17 at 15:24, <roger.pau@citrix.com> wrote: > Allow setting the destination vCPU for libelf, so that elf_load_image can take > it into account when loading the kernel for Dom0. This is needed for PVHv2 Dom0 > build, so that hvm_copy_to_guest_phys can be called with a Dom0 vCPU instead of > current (that contains the idle vCPU at this point). > > Signed-off-by: Roger Pau Monné <roger.pau@citrix.com> Reviewed-by: Jan Beulich <jbeulich@suse.com> albeit ... > --- a/xen/common/libelf/libelf-loader.c > +++ b/xen/common/libelf/libelf-loader.c > @@ -146,6 +146,25 @@ void elf_set_verbose(struct elf_binary *elf) > elf->verbose = 1; > } > > +static elf_errorstatus elf_memcpy(struct vcpu *v, void *dst, void *src, > + uint64_t size) > +{ > + int rc = 0; > + > +#ifdef CONFIG_X86 > + if ( is_hvm_vcpu(v) ) > + { > + rc = hvm_copy_to_guest_phys((paddr_t)dst, src, size, v); > + rc = rc != HVMCOPY_okay ? -1 : 0; > + } > + else > +#endif > + rc = src == NULL ? raw_clear_guest(dst, size) : > + raw_copy_to_guest(dst, src, size); > + > + return rc; > +} ... elf_errorstatus is not a correct type for the return values of raw_{copy_to,clear}_guest(). Nevertheless that's in line with ... > static elf_errorstatus elf_load_image(struct elf_binary *elf, elf_ptrval dst, elf_ptrval src, uint64_t filesz, uint64_t memsz) > { > elf_errorstatus rc; ... the variable declared here having been used ... > @@ -153,10 +172,12 @@ static elf_errorstatus elf_load_image(struct elf_binary *elf, elf_ptrval dst, el > return -1; > /* We trust the dom0 kernel image completely, so we don't care > * about overruns etc. here. */ > - rc = raw_copy_to_guest(ELF_UNSAFE_PTR(dst), ELF_UNSAFE_PTR(src), filesz); > + rc = elf_memcpy(elf->vcpu, ELF_UNSAFE_PTR(dst), ELF_UNSAFE_PTR(src), > + filesz); > if ( rc != 0 ) > return -1; > - rc = raw_clear_guest(ELF_UNSAFE_PTR(dst + filesz), memsz - filesz); > + rc = elf_memcpy(elf->vcpu, ELF_UNSAFE_PTR(dst + filesz), NULL, > + memsz - filesz); ... the same (wrong) way, so should be good enough for now. Ideally the setting of rc in elf_memcpy() would be corrected, though. Jan
diff --git a/xen/arch/x86/domain_build.c b/xen/arch/x86/domain_build.c index aa1625a..d2a1105 100644 --- a/xen/arch/x86/domain_build.c +++ b/xen/arch/x86/domain_build.c @@ -1462,6 +1462,7 @@ static int __init construct_dom0_pv( /* Copy the OS image and free temporary buffer. */ elf.dest_base = (void*)vkern_start; elf.dest_size = vkern_end - vkern_start; + elf_set_vcpu(&elf, v); rc = elf_load_binary(&elf); if ( rc < 0 ) { diff --git a/xen/common/libelf/libelf-loader.c b/xen/common/libelf/libelf-loader.c index 1644f16..371061c 100644 --- a/xen/common/libelf/libelf-loader.c +++ b/xen/common/libelf/libelf-loader.c @@ -146,6 +146,25 @@ void elf_set_verbose(struct elf_binary *elf) elf->verbose = 1; } +static elf_errorstatus elf_memcpy(struct vcpu *v, void *dst, void *src, + uint64_t size) +{ + int rc = 0; + +#ifdef CONFIG_X86 + if ( is_hvm_vcpu(v) ) + { + rc = hvm_copy_to_guest_phys((paddr_t)dst, src, size, v); + rc = rc != HVMCOPY_okay ? -1 : 0; + } + else +#endif + rc = src == NULL ? raw_clear_guest(dst, size) : + raw_copy_to_guest(dst, src, size); + + return rc; +} + static elf_errorstatus elf_load_image(struct elf_binary *elf, elf_ptrval dst, elf_ptrval src, uint64_t filesz, uint64_t memsz) { elf_errorstatus rc; @@ -153,10 +172,12 @@ static elf_errorstatus elf_load_image(struct elf_binary *elf, elf_ptrval dst, el return -1; /* We trust the dom0 kernel image completely, so we don't care * about overruns etc. here. */ - rc = raw_copy_to_guest(ELF_UNSAFE_PTR(dst), ELF_UNSAFE_PTR(src), filesz); + rc = elf_memcpy(elf->vcpu, ELF_UNSAFE_PTR(dst), ELF_UNSAFE_PTR(src), + filesz); if ( rc != 0 ) return -1; - rc = raw_clear_guest(ELF_UNSAFE_PTR(dst + filesz), memsz - filesz); + rc = elf_memcpy(elf->vcpu, ELF_UNSAFE_PTR(dst + filesz), NULL, + memsz - filesz); if ( rc != 0 ) return -1; return 0; diff --git a/xen/include/xen/libelf.h b/xen/include/xen/libelf.h index 1b763f3..b739981 100644 --- a/xen/include/xen/libelf.h +++ b/xen/include/xen/libelf.h @@ -212,6 +212,8 @@ struct elf_binary { /* misc */ elf_log_callback *log_callback; void *log_caller_data; +#else + struct vcpu *vcpu; #endif bool verbose; const char *broken; @@ -351,6 +353,10 @@ elf_errorstatus elf_init(struct elf_binary *elf, const char *image, size_t size) */ #ifdef __XEN__ void elf_set_verbose(struct elf_binary *elf); +static inline void elf_set_vcpu(struct elf_binary *elf, struct vcpu *v) +{ + elf->vcpu = v; +} #else void elf_set_log(struct elf_binary *elf, elf_log_callback*, void *log_caller_pointer, bool verbose);
Allow setting the destination vCPU for libelf, so that elf_load_image can take it into account when loading the kernel for Dom0. This is needed for PVHv2 Dom0 build, so that hvm_copy_to_guest_phys can be called with a Dom0 vCPU instead of current (that contains the idle vCPU at this point). Signed-off-by: Roger Pau Monné <roger.pau@citrix.com> --- Cc: Jan Beulich <jbeulich@suse.com> Cc: Andrew Cooper <andrew.cooper3@citrix.com> Cc: Ian Jackson <ian.jackson@eu.citrix.com> --- Changes since v6: - New in this version. --- xen/arch/x86/domain_build.c | 1 + xen/common/libelf/libelf-loader.c | 25 +++++++++++++++++++++++-- xen/include/xen/libelf.h | 6 ++++++ 3 files changed, 30 insertions(+), 2 deletions(-)