diff options
author | Michael Olbrich <m.olbrich@pengutronix.de> | 2015-12-28 00:49:22 +0100 |
---|---|---|
committer | Michael Olbrich <m.olbrich@pengutronix.de> | 2016-01-12 14:41:24 +0100 |
commit | cb21bbd4b351fe5cf5b47c8fc9d34d2f67903621 (patch) | |
tree | 869e49f58a54c6b451befd9a7ac4467912d1ec78 /patches | |
parent | cef73cf034809ee6928f9990937a0e189f69c2a3 (diff) | |
download | ptxdist-cb21bbd4b351fe5cf5b47c8fc9d34d2f67903621.tar.gz ptxdist-cb21bbd4b351fe5cf5b47c8fc9d34d2f67903621.tar.xz |
host-qemu: add patches
Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de>
Diffstat (limited to 'patches')
3 files changed, 327 insertions, 0 deletions
diff --git a/patches/qemu-2.4.1/0001-linux-user-remove-unused-image_info-members.patch b/patches/qemu-2.4.1/0001-linux-user-remove-unused-image_info-members.patch new file mode 100644 index 000000000..6eec068f9 --- /dev/null +++ b/patches/qemu-2.4.1/0001-linux-user-remove-unused-image_info-members.patch @@ -0,0 +1,48 @@ +From: =?UTF-8?q?Stefan=20Br=C3=BCns?= <address@hidden> +Date: Wed, 23 Sep 2015 14:38:18 +0200 +Subject: [PATCH] linux-user: remove unused image_info members +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Stefan Brüns <address@hidden> +Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de> +--- + linux-user/elfload.c | 3 --- + linux-user/qemu.h | 2 -- + 2 files changed, 5 deletions(-) + +diff --git a/linux-user/elfload.c b/linux-user/elfload.c +index 17883686f070..0b3c337fae9d 100644 +--- a/linux-user/elfload.c ++++ b/linux-user/elfload.c +@@ -1447,7 +1447,6 @@ static abi_ulong setup_arg_pages(abi_ulong p, struct linux_binprm *bprm, + + for (i = 0 ; i < MAX_ARG_PAGES ; i++) { + if (bprm->page[i]) { +- info->rss++; + /* FIXME - check return value of memcpy_to_target() for failure */ + memcpy_to_target(stack_base, bprm->page[i], TARGET_PAGE_SIZE); + g_free(bprm->page[i]); +@@ -2200,8 +2199,6 @@ int load_elf_binary(struct linux_binprm *bprm, struct image_info *info) + char *elf_interpreter = NULL; + + info->start_mmap = (abi_ulong)ELF_START_MMAP; +- info->mmap = 0; +- info->rss = 0; + + load_elf_image(bprm->filename, bprm->fd, info, + &elf_interpreter, bprm->buf); +diff --git a/linux-user/qemu.h b/linux-user/qemu.h +index 8012cc2f5b86..7d0009e81c1a 100644 +--- a/linux-user/qemu.h ++++ b/linux-user/qemu.h +@@ -36,8 +36,6 @@ struct image_info { + abi_ulong start_brk; + abi_ulong brk; + abi_ulong start_mmap; +- abi_ulong mmap; +- abi_ulong rss; + abi_ulong start_stack; + abi_ulong stack_limit; + abi_ulong entry; diff --git a/patches/qemu-2.4.1/0002-linux-user-remove-MAX_ARG_PAGES-limit.patch b/patches/qemu-2.4.1/0002-linux-user-remove-MAX_ARG_PAGES-limit.patch new file mode 100644 index 000000000..93b6db298 --- /dev/null +++ b/patches/qemu-2.4.1/0002-linux-user-remove-MAX_ARG_PAGES-limit.patch @@ -0,0 +1,274 @@ +From: =?UTF-8?q?Stefan=20Br=C3=BCns?= <address@hidden> +Date: Wed, 23 Sep 2015 14:39:19 +0200 +Subject: [PATCH] linux-user: remove MAX_ARG_PAGES limit +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Instead of creating a temporary copy for the whole environment and +the arguments, directly copy everything to the target stack. + +For this to work, we have to change the order of stack creation and +copying the arguments. + +Signed-off-by: Stefan Brüns <address@hidden> +Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de> +--- + linux-user/elfload.c | 110 ++++++++++++++++++++++++------------------------- + linux-user/flatload.c | 2 +- + linux-user/linuxload.c | 7 ---- + linux-user/qemu.h | 7 ---- + linux-user/syscall.c | 6 --- + 5 files changed, 56 insertions(+), 76 deletions(-) + +diff --git a/linux-user/elfload.c b/linux-user/elfload.c +index 0b3c337fae9d..55b9d99e8495 100644 +--- a/linux-user/elfload.c ++++ b/linux-user/elfload.c +@@ -1365,66 +1365,69 @@ static bool elf_check_ehdr(struct elfhdr *ehdr) + * to be put directly into the top of new user memory. + * + */ +-static abi_ulong copy_elf_strings(int argc,char ** argv, void **page, +- abi_ulong p) ++static abi_ulong copy_elf_strings(int argc, char **argv, char *scratch, ++ abi_ulong p, abi_ulong stack_limit) + { +- char *tmp, *tmp1, *pag = NULL; +- int len, offset = 0; ++ char *tmp; ++ int len, offset; ++ abi_ulong top = p; + + if (!p) { + return 0; /* bullet-proofing */ + } ++ ++ offset = ((p - 1) % TARGET_PAGE_SIZE) + 1; ++ + while (argc-- > 0) { + tmp = argv[argc]; + if (!tmp) { + fprintf(stderr, "VFS: argc is wrong"); + exit(-1); + } +- tmp1 = tmp; +- while (*tmp++); +- len = tmp - tmp1; +- if (p < len) { /* this shouldn't happen - 128kB */ ++ len = strlen(tmp) + 1; ++ tmp += len; ++ ++ if (len > (p - stack_limit)) { + return 0; + } + while (len) { +- --p; --tmp; --len; +- if (--offset < 0) { +- offset = p % TARGET_PAGE_SIZE; +- pag = (char *)page[p/TARGET_PAGE_SIZE]; +- if (!pag) { +- pag = g_try_malloc0(TARGET_PAGE_SIZE); +- page[p/TARGET_PAGE_SIZE] = pag; +- if (!pag) +- return 0; +- } +- } +- if (len == 0 || offset == 0) { +- *(pag + offset) = *tmp; +- } +- else { +- int bytes_to_copy = (len > offset) ? offset : len; +- tmp -= bytes_to_copy; +- p -= bytes_to_copy; +- offset -= bytes_to_copy; +- len -= bytes_to_copy; +- memcpy_fromfs(pag + offset, tmp, bytes_to_copy + 1); ++ int bytes_to_copy = (len > offset) ? offset : len; ++ tmp -= bytes_to_copy; ++ p -= bytes_to_copy; ++ offset -= bytes_to_copy; ++ len -= bytes_to_copy; ++ ++ memcpy_fromfs(scratch + offset, tmp, bytes_to_copy); ++ ++ if (offset == 0) { ++ memcpy_to_target(p, scratch, top - p); ++ top = p; ++ offset = TARGET_PAGE_SIZE; + } + } + } ++ if (offset) { ++ memcpy_to_target(p, scratch + offset, top - p); ++ } ++ + return p; + } + +-static abi_ulong setup_arg_pages(abi_ulong p, struct linux_binprm *bprm, ++/* Older linux kernels provide up to MAX_ARG_PAGES (default: 32) of ++ * argument/environment space. Newer kernels (>2.6.33) allow more, ++ * dependent on stack size, but guarantee at least 32 pages for ++ * backwards compatibility. ++ */ ++#define STACK_LOWER_LIMIT (32 * TARGET_PAGE_SIZE) ++ ++static abi_ulong setup_arg_pages(struct linux_binprm *bprm, + struct image_info *info) + { +- abi_ulong stack_base, size, error, guard; +- int i; ++ abi_ulong size, error, guard; + +- /* Create enough stack to hold everything. If we don't use +- it for args, we'll use it for something else. */ + size = guest_stack_size; +- if (size < MAX_ARG_PAGES*TARGET_PAGE_SIZE) { +- size = MAX_ARG_PAGES*TARGET_PAGE_SIZE; ++ if (size < STACK_LOWER_LIMIT) { ++ size = STACK_LOWER_LIMIT; + } + guard = TARGET_PAGE_SIZE; + if (guard < qemu_real_host_page_size) { +@@ -1442,18 +1445,8 @@ static abi_ulong setup_arg_pages(abi_ulong p, struct linux_binprm *bprm, + target_mprotect(error, guard, PROT_NONE); + + info->stack_limit = error + guard; +- stack_base = info->stack_limit + size - MAX_ARG_PAGES*TARGET_PAGE_SIZE; +- p += stack_base; +- +- for (i = 0 ; i < MAX_ARG_PAGES ; i++) { +- if (bprm->page[i]) { +- /* FIXME - check return value of memcpy_to_target() for failure */ +- memcpy_to_target(stack_base, bprm->page[i], TARGET_PAGE_SIZE); +- g_free(bprm->page[i]); +- } +- stack_base += TARGET_PAGE_SIZE; +- } +- return p; ++ ++ return info->stack_limit + size - sizeof(void *); + } + + /* Map and zero the bss. We need to explicitly zero any fractional pages +@@ -2197,6 +2190,7 @@ int load_elf_binary(struct linux_binprm *bprm, struct image_info *info) + struct image_info interp_info; + struct elfhdr elf_ex; + char *elf_interpreter = NULL; ++ char *scratch; + + info->start_mmap = (abi_ulong)ELF_START_MMAP; + +@@ -2208,18 +2202,24 @@ int load_elf_binary(struct linux_binprm *bprm, struct image_info *info) + when we load the interpreter. */ + elf_ex = *(struct elfhdr *)bprm->buf; + +- bprm->p = copy_elf_strings(1, &bprm->filename, bprm->page, bprm->p); +- bprm->p = copy_elf_strings(bprm->envc,bprm->envp,bprm->page,bprm->p); +- bprm->p = copy_elf_strings(bprm->argc,bprm->argv,bprm->page,bprm->p); ++ /* Do this so that we can load the interpreter, if need be. We will ++ change some of these later */ ++ bprm->p = setup_arg_pages(bprm, info); ++ ++ scratch = g_new0(char, TARGET_PAGE_SIZE); ++ bprm->p = copy_elf_strings(1, &bprm->filename, scratch, ++ bprm->p, info->stack_limit); ++ bprm->p = copy_elf_strings(bprm->envc, bprm->envp, scratch, ++ bprm->p, info->stack_limit); ++ bprm->p = copy_elf_strings(bprm->argc, bprm->argv, scratch, ++ bprm->p, info->stack_limit); ++ g_free(scratch); ++ + if (!bprm->p) { + fprintf(stderr, "%s: %s\n", bprm->filename, strerror(E2BIG)); + exit(-1); + } + +- /* Do this so that we can load the interpreter, if need be. We will +- change some of these later */ +- bprm->p = setup_arg_pages(bprm->p, bprm, info); +- + if (elf_interpreter) { + load_elf_interp(elf_interpreter, &interp_info, bprm->buf); + +diff --git a/linux-user/flatload.c b/linux-user/flatload.c +index 566a7a87a345..ceacb9844a45 100644 +--- a/linux-user/flatload.c ++++ b/linux-user/flatload.c +@@ -707,7 +707,7 @@ static int load_flat_shared_library(int id, struct lib_info *libs) + int load_flt_binary(struct linux_binprm *bprm, struct image_info *info) + { + struct lib_info libinfo[MAX_SHARED_LIBS]; +- abi_ulong p = bprm->p; ++ abi_ulong p; + abi_ulong stack_len; + abi_ulong start_addr; + abi_ulong sp; +diff --git a/linux-user/linuxload.c b/linux-user/linuxload.c +index 506e837ae18b..dbaf0ec58604 100644 +--- a/linux-user/linuxload.c ++++ b/linux-user/linuxload.c +@@ -135,10 +135,7 @@ int loader_exec(int fdexec, const char *filename, char **argv, char **envp, + struct linux_binprm *bprm) + { + int retval; +- int i; + +- bprm->p = TARGET_PAGE_SIZE*MAX_ARG_PAGES-sizeof(unsigned int); +- memset(bprm->page, 0, sizeof(bprm->page)); + bprm->fd = fdexec; + bprm->filename = (char *)filename; + bprm->argc = count(argv); +@@ -172,9 +169,5 @@ int loader_exec(int fdexec, const char *filename, char **argv, char **envp, + return retval; + } + +- /* Something went wrong, return the inode and free the argument pages*/ +- for (i=0 ; i<MAX_ARG_PAGES ; i++) { +- g_free(bprm->page[i]); +- } + return(retval); + } +diff --git a/linux-user/qemu.h b/linux-user/qemu.h +index 7d0009e81c1a..0341df8604c8 100644 +--- a/linux-user/qemu.h ++++ b/linux-user/qemu.h +@@ -143,12 +143,6 @@ extern const char *qemu_uname_release; + extern unsigned long mmap_min_addr; + + /* ??? See if we can avoid exposing so much of the loader internals. */ +-/* +- * MAX_ARG_PAGES defines the number of pages allocated for arguments +- * and envelope for the new program. 32 should suffice, this gives +- * a maximum env+arg of 128kB w/4KB pages! +- */ +-#define MAX_ARG_PAGES 33 + + /* Read a good amount of data initially, to hopefully get all the + program headers loaded. */ +@@ -160,7 +154,6 @@ extern unsigned long mmap_min_addr; + */ + struct linux_binprm { + char buf[BPRM_BUF_SIZE] __attribute__((aligned)); +- void *page[MAX_ARG_PAGES]; + abi_ulong p; + int fd; + int e_uid, e_gid; +diff --git a/linux-user/syscall.c b/linux-user/syscall.c +index f62c69894899..7d4e60e1f364 100644 +--- a/linux-user/syscall.c ++++ b/linux-user/syscall.c +@@ -5799,12 +5799,6 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, + } + *q = NULL; + +- /* This case will not be caught by the host's execve() if its +- page size is bigger than the target's. */ +- if (total_size > MAX_ARG_PAGES * TARGET_PAGE_SIZE) { +- ret = -TARGET_E2BIG; +- goto execve_end; +- } + if (!(p = lock_user_string(arg1))) + goto execve_efault; + ret = get_errno(execve(p, argp, envp)); diff --git a/patches/qemu-2.4.1/series b/patches/qemu-2.4.1/series new file mode 100644 index 000000000..d1328b305 --- /dev/null +++ b/patches/qemu-2.4.1/series @@ -0,0 +1,5 @@ +# generated by git-ptx-patches +#tag:base --start-number 1 +0001-linux-user-remove-unused-image_info-members.patch +0002-linux-user-remove-MAX_ARG_PAGES-limit.patch +# 835a365b0bb32db8486a8650c5e45b38 - git-ptx-patches magic |