From: Gerd Hoffmann <kraxel@novell.com>
To: xen-devel@lists.xensource.com
Subject: [patch 05/10] libelf: use for hvm builder.
Date: Fri, 01 Dec 2006 16:02:29 +0100 [thread overview]
Message-ID: <20061201153202.283669000@novell.com> (raw)
In-Reply-To: 20061201150224.756564000@novell.com
[-- Attachment #1: libelf-use-hvm-build.diff --]
[-- Type: text/plain, Size: 9195 bytes --]
This patch switches over the hvm domain builder to libelf
(for loading hvmloader).
Signed-off-by: Gerd Hoffmann <kraxel@suse.de>
---
tools/libxc/xc_hvm_build.c | 215 +++++++++++++--------------------------------
1 file changed, 65 insertions(+), 150 deletions(-)
Index: build-32-unstable-12621/tools/libxc/xc_hvm_build.c
===================================================================
--- build-32-unstable-12621.orig/tools/libxc/xc_hvm_build.c
+++ build-32-unstable-12621/tools/libxc/xc_hvm_build.c
@@ -2,29 +2,22 @@
* xc_hvm_build.c
*/
-#define ELFSIZE 32
#include <stddef.h>
#include <inttypes.h>
-#include "xg_private.h"
-#include "xc_private.h"
-#include "xc_elf.h"
#include <stdlib.h>
#include <unistd.h>
#include <zlib.h>
+
+#include "xg_private.h"
+#include "xc_private.h"
+
#include <xen/hvm/hvm_info_table.h>
#include <xen/hvm/params.h>
#include <xen/hvm/e820.h>
-#define SCRATCH_PFN 0xFFFFF
+#include <xen/libelf.h>
-#define HVM_LOADER_ENTR_ADDR 0x00100000
-static int
-parseelfimage(
- char *elfbase, unsigned long elfsize, struct domain_setup_info *dsi);
-static int
-loadelfimage(
- char *elfbase, int xch, uint32_t dom, unsigned long *parray,
- struct domain_setup_info *dsi);
+#define SCRATCH_PFN 0xFFFFF
int xc_set_hvm_param(
int handle, domid_t dom, int param, unsigned long value)
@@ -144,6 +137,48 @@ static void build_e820map(void *e820_pag
*(((unsigned char *)e820_page) + E820_MAP_NR_OFFSET) = nr_map;
}
+static int
+loadelfimage(struct elf_binary *elf, int xch, uint32_t dom, unsigned long *parray)
+{
+ privcmd_mmap_entry_t *entries = NULL;
+ int pages = (elf->pend - elf->pstart + PAGE_SIZE - 1) >> PAGE_SHIFT;
+ int i, rc = -1;
+
+ /* map hvmloader address space */
+ entries = malloc(pages * sizeof(privcmd_mmap_entry_t));
+ if (NULL == entries)
+ goto err;
+ elf->dest = mmap(NULL, pages << PAGE_SHIFT, PROT_READ | PROT_WRITE,
+ MAP_SHARED, xch, 0);
+ if (MAP_FAILED == elf->dest)
+ goto err;
+
+ for (i = 0; i < pages; i++)
+ {
+ entries[i].va = (uintptr_t)elf->dest + (i << PAGE_SHIFT);
+ entries[i].mfn = parray[(elf->pstart >> PAGE_SHIFT) + i];
+ entries[i].npages = 1;
+ }
+ rc = xc_map_foreign_ranges(xch, dom, entries, pages);
+ if (rc < 0)
+ goto err;
+
+ /* load hvmloader */
+ elf_load_binary(elf);
+ rc = 0;
+
+ err:
+ /* cleanup */
+ if (elf->dest) {
+ munmap(elf->dest, pages << PAGE_SHIFT);
+ elf->dest = NULL;
+ }
+ if (entries)
+ free(entries);
+
+ return rc;
+}
+
static int setup_guest(int xc_handle,
uint32_t dom, int memsize,
char *image, unsigned long image_size,
@@ -155,35 +190,35 @@ static int setup_guest(int xc_handle,
struct xen_add_to_physmap xatp;
struct shared_info *shared_info;
void *e820_page;
- struct domain_setup_info dsi;
- uint64_t v_end;
+ struct elf_binary elf;
+ uint64_t v_start, v_end;
int rc;
- memset(&dsi, 0, sizeof(struct domain_setup_info));
-
- if ( (parseelfimage(image, image_size, &dsi)) != 0 )
+ if (0 != elf_init(&elf, image, image_size))
goto error_out;
+ elf_parse_binary(&elf);
+ v_start = 0;
+ v_end = (unsigned long long)memsize << 20;
- if ( (dsi.v_kernstart & (PAGE_SIZE - 1)) != 0 )
+ if ( (elf.pstart & (PAGE_SIZE - 1)) != 0 )
{
PERROR("Guest OS must load to a page boundary.\n");
goto error_out;
}
- v_end = (unsigned long long)memsize << 20;
-
IPRINTF("VIRTUAL MEMORY ARRANGEMENT:\n"
- " Loaded HVM loader: %016"PRIx64"->%016"PRIx64"\n"
- " TOTAL: %016"PRIx64"->%016"PRIx64"\n",
- dsi.v_kernstart, dsi.v_kernend,
- dsi.v_start, v_end);
- IPRINTF(" ENTRY ADDRESS: %016"PRIx64"\n", dsi.v_kernentry);
+ " Loaded HVM loader: %016"PRIx64"->%016"PRIx64"\n"
+ " TOTAL: %016"PRIx64"->%016"PRIx64"\n"
+ " ENTRY ADDRESS: %016"PRIx64"\n",
+ elf.pstart, elf.pend,
+ v_start, v_end,
+ elf_uval(&elf, elf.ehdr, e_entry));
- if ( (v_end - dsi.v_start) > ((unsigned long long)nr_pages << PAGE_SHIFT) )
+ if ( (v_end - v_start) > ((unsigned long long)nr_pages << PAGE_SHIFT) )
{
PERROR("Initial guest OS requires too much space: "
"(%lluMB is greater than %lluMB limit)\n",
- (unsigned long long)(v_end - dsi.v_start) >> 20,
+ (unsigned long long)(v_end - v_start) >> 20,
((unsigned long long)nr_pages << PAGE_SHIFT) >> 20);
goto error_out;
}
@@ -212,7 +247,7 @@ static int setup_guest(int xc_handle,
goto error_out;
}
- loadelfimage(image, xc_handle, dom, page_array, &dsi);
+ loadelfimage(&elf, xc_handle, dom, page_array);
if ( (e820_page = xc_map_foreign_range(
xc_handle, dom, PAGE_SIZE, PROT_READ | PROT_WRITE,
@@ -256,7 +291,7 @@ static int setup_guest(int xc_handle,
free(page_array);
- ctxt->user_regs.eip = dsi.v_kernentry;
+ ctxt->user_regs.eip = elf_uval(&elf, elf.ehdr, e_entry);
return 0;
@@ -316,126 +351,6 @@ static inline int is_loadable_phdr(Elf32
((phdr->p_flags & (PF_W|PF_X)) != 0));
}
-static int parseelfimage(char *elfbase,
- unsigned long elfsize,
- struct domain_setup_info *dsi)
-{
- Elf32_Ehdr *ehdr = (Elf32_Ehdr *)elfbase;
- Elf32_Phdr *phdr;
- Elf32_Shdr *shdr;
- unsigned long kernstart = ~0UL, kernend=0UL;
- char *shstrtab;
- int h;
-
- if ( !IS_ELF(*ehdr) )
- {
- ERROR("Kernel image does not have an ELF header.");
- return -EINVAL;
- }
-
- if ( (ehdr->e_phoff + (ehdr->e_phnum * ehdr->e_phentsize)) > elfsize )
- {
- ERROR("ELF program headers extend beyond end of image.");
- return -EINVAL;
- }
-
- if ( (ehdr->e_shoff + (ehdr->e_shnum * ehdr->e_shentsize)) > elfsize )
- {
- ERROR("ELF section headers extend beyond end of image.");
- return -EINVAL;
- }
-
- /* Find the section-header strings table. */
- if ( ehdr->e_shstrndx == SHN_UNDEF )
- {
- ERROR("ELF image has no section-header strings table (shstrtab).");
- return -EINVAL;
- }
- shdr = (Elf32_Shdr *)(elfbase + ehdr->e_shoff +
- (ehdr->e_shstrndx*ehdr->e_shentsize));
- shstrtab = elfbase + shdr->sh_offset;
-
- for ( h = 0; h < ehdr->e_phnum; h++ )
- {
- phdr = (Elf32_Phdr *)(elfbase + ehdr->e_phoff + (h*ehdr->e_phentsize));
- if ( !is_loadable_phdr(phdr) )
- continue;
- if ( phdr->p_paddr < kernstart )
- kernstart = phdr->p_paddr;
- if ( (phdr->p_paddr + phdr->p_memsz) > kernend )
- kernend = phdr->p_paddr + phdr->p_memsz;
- }
-
- if ( (kernstart > kernend) ||
- (ehdr->e_entry < kernstart) ||
- (ehdr->e_entry > kernend) )
- {
- ERROR("Malformed ELF image.");
- return -EINVAL;
- }
-
- dsi->v_start = 0x00000000;
-
- dsi->v_kernstart = kernstart;
- dsi->v_kernend = kernend;
- dsi->v_kernentry = HVM_LOADER_ENTR_ADDR;
-
- dsi->v_end = dsi->v_kernend;
-
- return 0;
-}
-
-static int
-loadelfimage(
- char *elfbase, int xch, uint32_t dom, unsigned long *parray,
- struct domain_setup_info *dsi)
-{
- Elf32_Ehdr *ehdr = (Elf32_Ehdr *)elfbase;
- Elf32_Phdr *phdr;
- int h;
-
- char *va;
- unsigned long pa, done, chunksz;
-
- for ( h = 0; h < ehdr->e_phnum; h++ )
- {
- phdr = (Elf32_Phdr *)(elfbase + ehdr->e_phoff + (h*ehdr->e_phentsize));
- if ( !is_loadable_phdr(phdr) )
- continue;
-
- for ( done = 0; done < phdr->p_filesz; done += chunksz )
- {
- pa = (phdr->p_paddr + done) - dsi->v_start;
- if ((va = xc_map_foreign_range(
- xch, dom, PAGE_SIZE, PROT_WRITE,
- parray[pa >> PAGE_SHIFT])) == 0)
- return -1;
- chunksz = phdr->p_filesz - done;
- if ( chunksz > (PAGE_SIZE - (pa & (PAGE_SIZE-1))) )
- chunksz = PAGE_SIZE - (pa & (PAGE_SIZE-1));
- memcpy(va + (pa & (PAGE_SIZE-1)),
- elfbase + phdr->p_offset + done, chunksz);
- munmap(va, PAGE_SIZE);
- }
-
- for ( ; done < phdr->p_memsz; done += chunksz )
- {
- pa = (phdr->p_paddr + done) - dsi->v_start;
- if ((va = xc_map_foreign_range(
- xch, dom, PAGE_SIZE, PROT_WRITE,
- parray[pa >> PAGE_SHIFT])) == 0)
- return -1;
- chunksz = phdr->p_memsz - done;
- if ( chunksz > (PAGE_SIZE - (pa & (PAGE_SIZE-1))) )
- chunksz = PAGE_SIZE - (pa & (PAGE_SIZE-1));
- memset(va + (pa & (PAGE_SIZE-1)), 0, chunksz);
- munmap(va, PAGE_SIZE);
- }
- }
-
- return 0;
-}
-
/* xc_hvm_build
*
* Create a domain for a virtualized Linux, using files/filenames
--
next prev parent reply other threads:[~2006-12-01 15:02 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-12-01 15:02 [patch 00/10] libelf and the new domain builder Gerd Hoffmann
2006-12-01 15:02 ` [patch 01/10] Generate headers with arch-specific structs Gerd Hoffmann
2006-12-01 15:02 ` [patch 02/10] add libelf: an ELF binary parser library Gerd Hoffmann
2006-12-01 15:02 ` [patch 03/10] libelf: use for x86 dom0 builder Gerd Hoffmann
2006-12-01 15:02 ` [patch 04/10] libelf: add to libxc Gerd Hoffmann
2006-12-01 15:02 ` Gerd Hoffmann [this message]
2006-12-01 15:02 ` [patch 06/10] libelf: use for readnotes utility Gerd Hoffmann
2006-12-01 15:02 ` [patch 07/10] libxc header fixups Gerd Hoffmann
2006-12-01 15:02 ` [patch 08/10] libxc domain builder rewrite, core bits Gerd Hoffmann
2006-12-01 15:02 ` [patch 09/10] libxc domain builder rewrite, linux builder Gerd Hoffmann
2006-12-01 15:02 ` [patch 10/10] Support transparant gunzipping in the readnotes utility Gerd Hoffmann
-- strict thread matches above, loose matches on Subject: below --
2006-12-04 10:58 [patch 00/10] libelf and the new domain builder Gerd Hoffmann
2006-12-04 10:58 ` [patch 05/10] libelf: use for hvm builder Gerd Hoffmann
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20061201153202.283669000@novell.com \
--to=kraxel@novell.com \
--cc=xen-devel@lists.xensource.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.