From: Richard Henderson <rth@twiddle.net>
To: qemu-devel@nongnu.org
Cc: peter.maydell@linaro.org
Subject: [Qemu-devel] [PULL 02/24] tcg-mips: Constrain the code_gen_buffer to be within one 256mb segment
Date: Sat, 24 May 2014 08:53:39 -0700 [thread overview]
Message-ID: <1400946841-21079-3-git-send-email-rth@twiddle.net> (raw)
In-Reply-To: <1400946841-21079-1-git-send-email-rth@twiddle.net>
This assures us use of J for exit_tb and goto_tb, and JAL for calling
into the generated bswap helpers.
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
translate-all.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 85 insertions(+), 5 deletions(-)
diff --git a/translate-all.c b/translate-all.c
index c631694..6b7b46e 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -513,14 +513,47 @@ static inline size_t size_code_gen_buffer(size_t tb_size)
return tb_size;
}
+#ifdef __mips__
+/* In order to use J and JAL within the code_gen_buffer, we require
+ that the buffer not cross a 256MB boundary. */
+static inline bool cross_256mb(void *addr, size_t size)
+{
+ return ((uintptr_t)addr ^ ((uintptr_t)addr + size)) & 0xf0000000;
+}
+
+/* We weren't able to allocate a buffer without crossing that boundary,
+ so make do with the larger portion of the buffer that doesn't cross.
+ Returns the new base of the buffer, and adjusts code_gen_buffer_size. */
+static inline void *split_cross_256mb(void *buf1, size_t size1)
+{
+ void *buf2 = (void *)(((uintptr_t)buf1 + size1) & 0xf0000000);
+ size_t size2 = buf1 + size1 - buf2;
+
+ size1 = buf2 - buf1;
+ if (size1 < size2) {
+ size1 = size2;
+ buf1 = buf2;
+ }
+
+ tcg_ctx.code_gen_buffer_size = size1;
+ return buf1;
+}
+#endif
+
#ifdef USE_STATIC_CODE_GEN_BUFFER
static uint8_t static_code_gen_buffer[DEFAULT_CODE_GEN_BUFFER_SIZE]
__attribute__((aligned(CODE_GEN_ALIGN)));
static inline void *alloc_code_gen_buffer(void)
{
- map_exec(static_code_gen_buffer, tcg_ctx.code_gen_buffer_size);
- return static_code_gen_buffer;
+ void *buf = static_code_gen_buffer;
+#ifdef __mips__
+ if (cross_256mb(buf, tcg_ctx.code_gen_buffer_size)) {
+ buf = split_cross_256mb(buf, tcg_ctx.code_gen_buffer_size);
+ }
+#endif
+ map_exec(buf, tcg_ctx.code_gen_buffer_size);
+ return buf;
}
#elif defined(USE_MMAP)
static inline void *alloc_code_gen_buffer(void)
@@ -562,16 +595,63 @@ static inline void *alloc_code_gen_buffer(void)
buf = mmap((void *)start, tcg_ctx.code_gen_buffer_size,
PROT_WRITE | PROT_READ | PROT_EXEC, flags, -1, 0);
- return buf == MAP_FAILED ? NULL : buf;
+ if (buf == MAP_FAILED) {
+ return NULL;
+ }
+
+#ifdef __mips__
+ if (cross_256mb(buf, tcg_ctx.code_gen_buffer_size)) {
+ /* Try again, with the original still mapped, to avoid re-aquiring
+ that 256mb crossing. This time don't specify an address. */
+ size_t size2, size1 = tcg_ctx.code_gen_buffer_size;
+ void *buf2 = mmap(NULL, size1, PROT_WRITE | PROT_READ | PROT_EXEC,
+ flags, -1, 0);
+ if (buf2 != MAP_FAILED) {
+ if (!cross_256mb(buf2, size1)) {
+ /* Success! Use the new buffer. */
+ munmap(buf, size1);
+ return buf2;
+ }
+ /* Failure. Work with what we had. */
+ munmap(buf2, size1);
+ }
+
+ /* Split the original buffer. Free the smaller half. */
+ buf2 = split_cross_256mb(buf, size1);
+ size2 = tcg_ctx.code_gen_buffer_size;
+ munmap(buf + (buf == buf2 ? size2 : 0), size1 - size2);
+ return buf2;
+ }
+#endif
+
+ return buf;
}
#else
static inline void *alloc_code_gen_buffer(void)
{
void *buf = g_malloc(tcg_ctx.code_gen_buffer_size);
- if (buf) {
- map_exec(buf, tcg_ctx.code_gen_buffer_size);
+ if (buf == NULL) {
+ return NULL;
}
+
+#ifdef __mips__
+ if (cross_256mb(buf, tcg_ctx.code_gen_buffer_size)) {
+ void *buf2 = g_malloc(tcg_ctx.code_gen_buffer_size);
+ if (buf2 != NULL && !cross_256mb(buf2, size1)) {
+ /* Success! Use the new buffer. */
+ free(buf);
+ buf = buf2;
+ } else {
+ /* Failure. Work with what we had. Since this is malloc
+ and not mmap, we can't free the other half. */
+ free(buf2);
+ buf = split_cross_256mb(buf, tcg_ctx.code_gen_buffer_size);
+ }
+ }
+#endif
+
+ map_exec(buf, tcg_ctx.code_gen_buffer_size);
return buf;
}
#endif /* USE_STATIC_CODE_GEN_BUFFER, USE_MMAP */
--
1.9.0
next prev parent reply other threads:[~2014-05-24 15:54 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-05-24 15:53 [Qemu-devel] [PULL 00/24] tcg mips updates Richard Henderson
2014-05-24 15:53 ` [Qemu-devel] [PULL 01/24] tcg-mips: Layout executable and code_gen_buffer Richard Henderson
2014-05-24 15:53 ` Richard Henderson [this message]
2014-05-24 15:53 ` [Qemu-devel] [PULL 03/24] tcg-mips: Use J and JAL opcodes Richard Henderson
2014-05-24 15:53 ` [Qemu-devel] [PULL 04/24] tcg-mips: Fill the exit_tb delay slot Richard Henderson
2014-05-24 15:53 ` [Qemu-devel] [PULL 05/24] tcg-mips: Split large ldst offsets Richard Henderson
2014-05-24 15:53 ` [Qemu-devel] [PULL 06/24] tcg-mips: Move softmmu slow path out of line Richard Henderson
2014-05-24 15:53 ` [Qemu-devel] [PULL 07/24] tcg-mips: Convert to new qemu_l/st helpers Richard Henderson
2014-05-24 15:53 ` [Qemu-devel] [PULL 08/24] tcg-mips: Convert to new_ldst Richard Henderson
2014-05-24 15:53 ` [Qemu-devel] [PULL 09/24] tcg-mips: Rearrange register allocation Richard Henderson
2014-05-24 15:53 ` [Qemu-devel] [PULL 10/24] tcg-mips: Introduce TCG_TMP0, TCG_TMP1 Richard Henderson
2014-05-24 15:53 ` [Qemu-devel] [PULL 11/24] tcg-mips: Use T9 for TCG_TMP1 Richard Henderson
2014-05-24 15:53 ` [Qemu-devel] [PULL 12/24] tcg-mips: Use EXT for AND on mips32r2 Richard Henderson
2014-05-24 15:53 ` [Qemu-devel] [PULL 13/24] tcg-mips: Name the opcode enumeration Richard Henderson
2014-05-24 15:53 ` [Qemu-devel] [PULL 14/24] tcg-mips: Fix subtract immediate range Richard Henderson
2014-05-24 15:53 ` [Qemu-devel] [PULL 15/24] tcg-mips: Hoist args loads Richard Henderson
2014-05-24 15:53 ` [Qemu-devel] [PULL 16/24] tcg-mips: Improve add2/sub2 Richard Henderson
2014-05-24 15:53 ` [Qemu-devel] [PULL 17/24] tcg-mips: Commonize opcode implementations Richard Henderson
2014-05-24 15:53 ` [Qemu-devel] [PULL 18/24] tcg-mips: Simplify setcond Richard Henderson
2014-05-24 15:53 ` [Qemu-devel] [PULL 19/24] tcg-mips: Simplify brcond Richard Henderson
2014-05-24 15:53 ` [Qemu-devel] [PULL 20/24] tcg-mips: Simplify setcond2 Richard Henderson
2014-05-24 15:53 ` [Qemu-devel] [PULL 21/24] tcg-mips: Improve setcond eq/ne vs zeros Richard Henderson
2014-05-24 15:53 ` [Qemu-devel] [PULL 22/24] tcg-mips: Simplify brcond2 Richard Henderson
2014-05-24 15:54 ` [Qemu-devel] [PULL 23/24] tcg-mips: Simplify movcond Richard Henderson
2014-05-24 15:54 ` [Qemu-devel] [PULL 24/24] tcg-mips: Enable direct chaining of TBs Richard Henderson
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=1400946841-21079-3-git-send-email-rth@twiddle.net \
--to=rth@twiddle.net \
--cc=peter.maydell@linaro.org \
--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).