From: riku.voipio@iki.fi
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH 06/10] Revived GUEST_BASE support for usermode emulation targets [v2]
Date: Wed, 29 Apr 2009 21:03:19 +0300 [thread overview]
Message-ID: <1241028203-19687-6-git-send-email-riku.voipio@iki.fi> (raw)
In-Reply-To: <1241028203-19687-1-git-send-email-riku.voipio@iki.fi>
From: Mika Westerberg <mika.westerberg@iki.fi>
From: Mika Westerberg <mika.westerberg@iki.fi>
- Now GUEST_BASE is dynamic and can be set from command line.
- Qemu checks /proc/sys/vm/mmap_min_addr and sets GUEST_BASE
if needed.
- Code generation supports GUEST_BASE for i386 and x86_64 hosts.
[v2]: implemented GUEST_BASE with single LEA
Changed TCG (on x86 and x86_64) to generate single LEA instead
of MOV+ADD when calculating GUEST_BASE host addresses.
From: Mika Westerberg <mika.westerberg@iki.fi>
Signed-off-by: Riku Voipio <riku.voipio@iki.fi>
---
configure | 9 +++++++
cpu-all.h | 6 ++++-
linux-user/elfload.c | 24 ++++++++++++++++++++
linux-user/main.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++
linux-user/qemu.h | 3 ++
tcg/i386/tcg-target.c | 14 ++++++++++++
tcg/x86_64/tcg-target.c | 14 ++++++++++++
7 files changed, 123 insertions(+), 1 deletions(-)
diff --git a/configure b/configure
index 82fb60a..bc89227 100755
--- a/configure
+++ b/configure
@@ -178,6 +178,7 @@ softmmu="yes"
linux_user="no"
darwin_user="no"
bsd_user="no"
+guest_base="no"
build_docs="no"
uname_release=""
curses="yes"
@@ -457,6 +458,8 @@ for opt do
;;
--enable-bsd-user) bsd_user="yes"
;;
+ --enable-guest-base) guest_base="yes"
+ ;;
--enable-uname-release=*) uname_release="$optarg"
;;
--sparc_cpu=*)
@@ -611,6 +614,8 @@ echo " --enable-darwin-user enable all darwin usermode emulation targets"
echo " --disable-darwin-user disable all darwin usermode emulation targets"
echo " --enable-bsd-user enable all BSD usermode emulation targets"
echo " --disable-bsd-user disable all BSD usermode emulation targets"
+echo " --enable-guest-base enable GUEST_BASE support for usermode"
+echo " emulation targets"
echo " --fmod-lib path to FMOD library"
echo " --fmod-inc path to FMOD includes"
echo " --oss-lib path to OSS library"
@@ -1335,6 +1340,7 @@ echo "Documentation $build_docs"
[ ! -z "$uname_release" ] && \
echo "uname -r $uname_release"
echo "NPTL support $nptl"
+echo "GUEST_BASE $guest_base"
echo "vde support $vde"
echo "AIO support $aio"
echo "IO thread $io_thread"
@@ -2022,6 +2028,9 @@ if test "$target_user_only" = "yes" -a "$elfload32" = "yes"; then
echo "TARGET_HAS_ELFLOAD32=yes" >> $config_mak
echo "#define TARGET_HAS_ELFLOAD32 1" >> $config_h
fi
+if test "$target_user_only" = "yes" -a "$guest_base" = "yes"; then
+ echo "#define CONFIG_USE_GUEST_BASE 1" >> $config_h
+fi
if test "$target_bsd_user" = "yes" ; then
echo "CONFIG_BSD_USER=yes" >> $config_mak
echo "#define CONFIG_BSD_USER 1" >> $config_h
diff --git a/cpu-all.h b/cpu-all.h
index 43a06ba..5413a92 100644
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -629,8 +629,12 @@ static inline void stfq_be_p(void *ptr, float64 v)
/* On some host systems the guest address space is reserved on the host.
* This allows the guest address space to be offset to a convenient location.
*/
-//#define GUEST_BASE 0x20000000
+#if defined(CONFIG_USE_GUEST_BASE)
+extern unsigned long guest_base;
+#define GUEST_BASE guest_base
+#else
#define GUEST_BASE 0
+#endif
/* All direct uses of g2h and h2g need to go away for usermode softmmu. */
#define g2h(x) ((void *)((unsigned long)(x) + GUEST_BASE))
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index dc797bd..b5565dd 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -1466,6 +1466,30 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
info->mmap = 0;
elf_entry = (abi_ulong) elf_ex.e_entry;
+#if defined(CONFIG_USE_GUEST_BASE)
+ /*
+ * In case where user has not explicitly set the guest_base, we
+ * probe here that should we set it automatically.
+ */
+ if (guest_base == 0) {
+ /*
+ * Go through ELF program header table and find out whether
+ * any of the segments drop below our current mmap_min_addr and
+ * in that case set guest_base to corresponding address.
+ */
+ for (i = 0, elf_ppnt = elf_phdata; i < elf_ex.e_phnum;
+ i++, elf_ppnt++) {
+ if (elf_ppnt->p_type != PT_LOAD)
+ continue;
+ if (HOST_PAGE_ALIGN(elf_ppnt->p_vaddr) < mmap_min_addr) {
+ guest_base = HOST_PAGE_ALIGN(mmap_min_addr);
+ qemu_log("setting guest_base=0x%lx\n", guest_base);
+ break;
+ }
+ }
+ }
+#endif /* CONFIG_USE_GUEST_BASE */
+
/* Do this so that we can load the interpreter, if need be. We will
change some of these later */
info->rss = 0;
diff --git a/linux-user/main.c b/linux-user/main.c
index 72734c1..64b1ff0 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -41,6 +41,10 @@
char *exec_path;
int singlestep;
+#if defined(CONFIG_USE_GUEST_BASE)
+unsigned long mmap_min_addr = 0;
+unsigned long guest_base = 0;
+#endif
static const char *interp_prefix = CONFIG_QEMU_PREFIX;
const char *qemu_uname_release = CONFIG_UNAME_RELEASE;
@@ -2229,6 +2233,9 @@ static void usage(void)
"-E var=value sets/modifies targets environment variable(s)\n"
"-U var unsets targets environment variable(s)\n"
"-0 argv0 forces target process argv[0] to be argv0\n"
+#if defined(CONFIG_USE_GUEST_BASE)
+ "-B address set guest_base address to address\n"
+#endif
"\n"
"Debug options:\n"
"-d options activate log (logfile=%s)\n"
@@ -2403,6 +2410,10 @@ int main(int argc, char **argv, char **envp)
#endif
exit(1);
}
+#if defined(CONFIG_USE_GUEST_BASE)
+ } else if (!strcmp(r, "B")) {
+ guest_base = strtol(argv[optind++], NULL, 0);
+#endif
} else if (!strcmp(r, "drop-ld-preload")) {
(void) envlist_unsetenv(envlist, "LD_PRELOAD");
} else if (!strcmp(r, "singlestep")) {
@@ -2480,6 +2491,36 @@ int main(int argc, char **argv, char **envp)
target_environ = envlist_to_environ(envlist, NULL);
envlist_free(envlist);
+#if defined(CONFIG_USE_GUEST_BASE)
+ /*
+ * Now that page sizes are configured in cpu_init() we can do
+ * proper page alignment for guest_base.
+ */
+ guest_base = HOST_PAGE_ALIGN(guest_base);
+
+ /*
+ * Read in mmap_min_addr kernel parameter and check
+ * whether it is set to some value > 0. This value is used
+ * later on when doing mmap(2)s to calculate where guest_base
+ * is to set, if needed.
+ *
+ * When user has explicitly set the quest base, we skip this
+ * test.
+ */
+ if (guest_base == 0) {
+ FILE *fp;
+
+ if ((fp = fopen("/proc/sys/vm/mmap_min_addr", "r")) != NULL) {
+ unsigned long tmp;
+ if (fscanf(fp, "%lu", &tmp) == 1) {
+ mmap_min_addr = tmp;
+ qemu_log("kernel mmap_min_addr=%lu\n", mmap_min_addr);
+ }
+ fclose(fp);
+ }
+ }
+#endif /* CONFIG_USE_GUEST_BASE */
+
/*
* Prepare copy of argv vector for target.
*/
@@ -2529,6 +2570,19 @@ int main(int argc, char **argv, char **envp)
free(target_environ);
if (qemu_log_enabled()) {
+#if defined(CONFIG_USE_GUEST_BASE)
+ if (guest_base > 0) {
+ qemu_log("guest_base is set to 0x%lx\n", guest_base);
+ qemu_log(
+ "==========================================================\n"
+ "Note that all target addresses below are given in target\n"
+ "address space which is different from host by guest_base.\n"
+ "For example: target address 0x" TARGET_ABI_FMT_lx " becomes\n"
+ "%p and so on.\n"
+ "==========================================================\n",
+ (abi_ulong)0x8000, g2h(0x8000));
+ }
+#endif
log_page_dump();
qemu_log("start_brk 0x" TARGET_ABI_FMT_lx "\n", info->start_brk);
diff --git a/linux-user/qemu.h b/linux-user/qemu.h
index ea4a57d..762f31f 100644
--- a/linux-user/qemu.h
+++ b/linux-user/qemu.h
@@ -133,6 +133,9 @@ void init_task_state(TaskState *ts);
void task_settid(TaskState *);
void stop_all_tasks(void);
extern const char *qemu_uname_release;
+#if defined(CONFIG_USE_GUEST_BASE)
+extern unsigned long mmap_min_addr;
+#endif
/* ??? See if we can avoid exposing so much of the loader internals. */
/*
diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c
index e0fd434..757e128 100644
--- a/tcg/i386/tcg-target.c
+++ b/tcg/i386/tcg-target.c
@@ -560,6 +560,13 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
/* add x(r1), r0 */
tcg_out_modrm_offset(s, 0x03, r0, r1, offsetof(CPUTLBEntry, addend) -
offsetof(CPUTLBEntry, addr_read));
+#elif defined(CONFIG_USE_GUEST_BASE)
+ /*
+ * Add guest_base to all loads.
+ *
+ * leaq GUEST_BASE(addr_reg), r0
+ */
+ tcg_out_modrm_offset(s, 0x8d, r0, addr_reg, GUEST_BASE);
#else
r0 = addr_reg;
#endif
@@ -794,6 +801,13 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
/* add x(r1), r0 */
tcg_out_modrm_offset(s, 0x03, r0, r1, offsetof(CPUTLBEntry, addend) -
offsetof(CPUTLBEntry, addr_write));
+#elif defined(CONFIG_USE_GUEST_BASE)
+ /*
+ * Add guest_base to all stores.
+ *
+ * leaq GUEST_BASE(addr_reg), r0
+ */
+ tcg_out_modrm_offset(s, 0x8d, r0, addr_reg, GUEST_BASE);
#else
r0 = addr_reg;
#endif
diff --git a/tcg/x86_64/tcg-target.c b/tcg/x86_64/tcg-target.c
index 5378e85..ece2876 100644
--- a/tcg/x86_64/tcg-target.c
+++ b/tcg/x86_64/tcg-target.c
@@ -604,6 +604,13 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
/* add x(r1), r0 */
tcg_out_modrm_offset(s, 0x03 | P_REXW, r0, r1, offsetof(CPUTLBEntry, addend) -
offsetof(CPUTLBEntry, addr_read));
+#elif defined(CONFIG_USE_GUEST_BASE)
+ /*
+ * Add guest_base to all loads.
+ *
+ * leaq GUEST_BASE(addr_reg), r0
+ */
+ tcg_out_modrm_offset(s, 0x8d | rexw, r0, addr_reg, GUEST_BASE);
#else
r0 = addr_reg;
#endif
@@ -775,6 +782,13 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
/* add x(r1), r0 */
tcg_out_modrm_offset(s, 0x03 | P_REXW, r0, r1, offsetof(CPUTLBEntry, addend) -
offsetof(CPUTLBEntry, addr_write));
+#elif defined(CONFIG_USE_GUEST_BASE)
+ /*
+ * Add guest_base to all stores.
+ *
+ * leaq GUEST_BASE(addr_reg), r0
+ */
+ tcg_out_modrm_offset(s, 0x8d | rexw, r0, addr_reg, GUEST_BASE);
#else
r0 = addr_reg;
#endif
--
1.6.2.1
next prev parent reply other threads:[~2009-04-29 18:03 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-04-29 18:03 [Qemu-devel] [PATCH 01/10] export mmap_find_vma for shmat riku.voipio
2009-04-29 18:03 ` [Qemu-devel] [PATCH 02/10] Implement shm* syscalls and fix 64/32bit errors riku.voipio
2009-04-29 18:03 ` [Qemu-devel] [PATCH 03/10] linux-user: implemented ELF coredump support for ARM target [v2] riku.voipio
2009-04-29 18:03 ` [Qemu-devel] [PATCH 04/10] linux-user: added x86 and x86_64 support for ELF coredump riku.voipio
2009-04-29 18:03 ` [Qemu-devel] [PATCH 05/10] linux-user: strace now handles guest strings correctly riku.voipio
2009-04-29 18:03 ` riku.voipio [this message]
2009-04-29 19:50 ` [Qemu-devel] [PATCH 06/10] Revived GUEST_BASE support for usermode emulation targets [v2] malc
2009-05-05 13:27 ` [Qemu-devel] [PATCH] Revived GUEST_BASE support for usermode emulation targets [v3] Riku Voipio
2009-05-05 13:53 ` Paul Brook
2009-05-05 14:18 ` Riku Voipio
2009-05-05 14:34 ` Paul Brook
2009-05-05 18:02 ` malc
2009-05-05 20:46 ` [Qemu-devel] [PATCH] Revived GUEST_BASE support for usermode emulation targets [v4] Riku Voipio
2009-05-15 2:25 ` Paul Brook
2009-05-15 8:41 ` Martin Mohring
2009-05-15 9:50 ` Paul Brook
2009-05-15 9:57 ` Riku Voipio
2009-05-15 10:02 ` Paul Brook
2009-05-15 10:09 ` Paul Brook
2009-05-15 12:07 ` malc
2009-05-15 10:12 ` Martin Mohring
2009-05-15 14:13 ` Riku Voipio
2009-05-15 15:25 ` Martin Mohring
2009-04-30 7:07 ` [Qemu-devel] [PATCH 06/10] Revived GUEST_BASE support for usermode emulation targets [v2] Martin Mohring
2009-04-29 18:03 ` [Qemu-devel] [PATCH 07/10] linux-user: fix utimensat when used as futimens riku.voipio
2009-04-29 18:03 ` [Qemu-devel] [PATCH 08/10] Fix struct termios host - target translation riku.voipio
2009-04-29 18:03 ` [Qemu-devel] [PATCH 09/10] linux-user: fix utimensat with NULL timespec riku.voipio
2009-04-29 18:03 ` [Qemu-devel] [PATCH 10/10] Return EOPNOTSUPP instead of ENOSYS for *xattr* syscalls riku.voipio
2009-04-30 7:09 ` [Qemu-devel] [PATCH 01/10] export mmap_find_vma for shmat Martin Mohring
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=1241028203-19687-6-git-send-email-riku.voipio@iki.fi \
--to=riku.voipio@iki.fi \
--cc=qemu-devel@nongnu.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).