From: Michael Roth <mdroth@linux.vnet.ibm.com>
To: qemu-stable@nongnu.org
Cc: aliguori@us.ibm.com, qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH 22/43] tcg/arm: fix TLB access in qemu-ld/st ops
Date: Mon, 3 Dec 2012 16:08:46 -0600 [thread overview]
Message-ID: <1354572547-21271-23-git-send-email-mdroth@linux.vnet.ibm.com> (raw)
In-Reply-To: <1354572547-21271-1-git-send-email-mdroth@linux.vnet.ibm.com>
From: Aurelien Jarno <aurelien@aurel32.net>
The TCG arm backend considers likely that the offset to the TLB
entries does not exceed 12 bits for mem_index = 0. In practice this is
not true for at least the MIPS target.
The current patch fixes that by loading the bits 23-12 with a separate
instruction, and using loads with address writeback, independently of
the value of mem_idx. In total this allow a 24-bit offset, which is a
lot more than needed.
Cc: Andrzej Zaborowski <balrogg@gmail.com>
Cc: Peter Maydell <peter.maydell@linaro.org>
Cc: qemu-stable@nongnu.org
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit d17bd1d8cc27f8c1a24c65f555a77a661c332b7f)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
tcg/arm/tcg-target.c | 78 +++++++++++++++++++++++++++-----------------------
1 file changed, 42 insertions(+), 36 deletions(-)
diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c
index aed3b53..fbad716 100644
--- a/tcg/arm/tcg-target.c
+++ b/tcg/arm/tcg-target.c
@@ -630,6 +630,22 @@ static inline void tcg_out_ld32_12(TCGContext *s, int cond,
(rn << 16) | (rd << 12) | ((-im) & 0xfff));
}
+/* Offset pre-increment with base writeback. */
+static inline void tcg_out_ld32_12wb(TCGContext *s, int cond,
+ int rd, int rn, tcg_target_long im)
+{
+ /* ldr with writeback and both register equals is UNPREDICTABLE */
+ assert(rd != rn);
+
+ if (im >= 0) {
+ tcg_out32(s, (cond << 28) | 0x05b00000 |
+ (rn << 16) | (rd << 12) | (im & 0xfff));
+ } else {
+ tcg_out32(s, (cond << 28) | 0x05300000 |
+ (rn << 16) | (rd << 12) | ((-im) & 0xfff));
+ }
+}
+
static inline void tcg_out_st32_12(TCGContext *s, int cond,
int rd, int rn, tcg_target_long im)
{
@@ -1062,7 +1078,7 @@ static inline void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc)
{
int addr_reg, data_reg, data_reg2, bswap;
#ifdef CONFIG_SOFTMMU
- int mem_index, s_bits;
+ int mem_index, s_bits, tlb_offset;
TCGReg argreg;
# if TARGET_LONG_BITS == 64
int addr_reg2;
@@ -1102,19 +1118,15 @@ static inline void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc)
TCG_REG_R0, TCG_REG_R8, CPU_TLB_SIZE - 1);
tcg_out_dat_reg(s, COND_AL, ARITH_ADD, TCG_REG_R0, TCG_AREG0,
TCG_REG_R0, SHIFT_IMM_LSL(CPU_TLB_ENTRY_BITS));
- /* In the
- * ldr r1 [r0, #(offsetof(CPUArchState, tlb_table[mem_index][0].addr_read))]
- * below, the offset is likely to exceed 12 bits if mem_index != 0 and
- * not exceed otherwise, so use an
- * add r0, r0, #(mem_index * sizeof *CPUArchState.tlb_table)
- * before.
- */
- if (mem_index)
+ /* We assume that the offset is contained within 20 bits. */
+ tlb_offset = offsetof(CPUArchState, tlb_table[mem_index][0].addr_read);
+ assert(tlb_offset & ~0xfffff == 0);
+ if (tlb_offset > 0xfff) {
tcg_out_dat_imm(s, COND_AL, ARITH_ADD, TCG_REG_R0, TCG_REG_R0,
- (mem_index << (TLB_SHIFT & 1)) |
- ((16 - (TLB_SHIFT >> 1)) << 8));
- tcg_out_ld32_12(s, COND_AL, TCG_REG_R1, TCG_REG_R0,
- offsetof(CPUArchState, tlb_table[0][0].addr_read));
+ 0xa00 | (tlb_offset >> 12));
+ tlb_offset &= 0xfff;
+ }
+ tcg_out_ld32_12wb(s, COND_AL, TCG_REG_R1, TCG_REG_R0, tlb_offset);
tcg_out_dat_reg(s, COND_AL, ARITH_CMP, 0, TCG_REG_R1,
TCG_REG_R8, SHIFT_IMM_LSL(TARGET_PAGE_BITS));
/* Check alignment. */
@@ -1122,15 +1134,14 @@ static inline void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc)
tcg_out_dat_imm(s, COND_EQ, ARITH_TST,
0, addr_reg, (1 << s_bits) - 1);
# if TARGET_LONG_BITS == 64
- /* XXX: possibly we could use a block data load or writeback in
- * the first access. */
- tcg_out_ld32_12(s, COND_EQ, TCG_REG_R1, TCG_REG_R0,
- offsetof(CPUArchState, tlb_table[0][0].addr_read) + 4);
+ /* XXX: possibly we could use a block data load in the first access. */
+ tcg_out_ld32_12(s, COND_EQ, TCG_REG_R1, TCG_REG_R0, 4);
tcg_out_dat_reg(s, COND_EQ, ARITH_CMP, 0,
TCG_REG_R1, addr_reg2, SHIFT_IMM_LSL(0));
# endif
tcg_out_ld32_12(s, COND_EQ, TCG_REG_R1, TCG_REG_R0,
- offsetof(CPUArchState, tlb_table[0][0].addend));
+ offsetof(CPUTLBEntry, addend)
+ - offsetof(CPUTLBEntry, addr_read));
switch (opc) {
case 0:
@@ -1288,7 +1299,7 @@ static inline void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc)
{
int addr_reg, data_reg, data_reg2, bswap;
#ifdef CONFIG_SOFTMMU
- int mem_index, s_bits;
+ int mem_index, s_bits, tlb_offset;
TCGReg argreg;
# if TARGET_LONG_BITS == 64
int addr_reg2;
@@ -1325,19 +1336,15 @@ static inline void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc)
TCG_REG_R0, TCG_REG_R8, CPU_TLB_SIZE - 1);
tcg_out_dat_reg(s, COND_AL, ARITH_ADD, TCG_REG_R0,
TCG_AREG0, TCG_REG_R0, SHIFT_IMM_LSL(CPU_TLB_ENTRY_BITS));
- /* In the
- * ldr r1 [r0, #(offsetof(CPUArchState, tlb_table[mem_index][0].addr_write))]
- * below, the offset is likely to exceed 12 bits if mem_index != 0 and
- * not exceed otherwise, so use an
- * add r0, r0, #(mem_index * sizeof *CPUArchState.tlb_table)
- * before.
- */
- if (mem_index)
+ /* We assume that the offset is contained within 20 bits. */
+ tlb_offset = offsetof(CPUArchState, tlb_table[mem_index][0].addr_write);
+ assert(tlb_offset & ~0xfffff == 0);
+ if (tlb_offset > 0xfff) {
tcg_out_dat_imm(s, COND_AL, ARITH_ADD, TCG_REG_R0, TCG_REG_R0,
- (mem_index << (TLB_SHIFT & 1)) |
- ((16 - (TLB_SHIFT >> 1)) << 8));
- tcg_out_ld32_12(s, COND_AL, TCG_REG_R1, TCG_REG_R0,
- offsetof(CPUArchState, tlb_table[0][0].addr_write));
+ 0xa00 | (tlb_offset >> 12));
+ tlb_offset &= 0xfff;
+ }
+ tcg_out_ld32_12wb(s, COND_AL, TCG_REG_R1, TCG_REG_R0, tlb_offset);
tcg_out_dat_reg(s, COND_AL, ARITH_CMP, 0, TCG_REG_R1,
TCG_REG_R8, SHIFT_IMM_LSL(TARGET_PAGE_BITS));
/* Check alignment. */
@@ -1345,15 +1352,14 @@ static inline void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc)
tcg_out_dat_imm(s, COND_EQ, ARITH_TST,
0, addr_reg, (1 << s_bits) - 1);
# if TARGET_LONG_BITS == 64
- /* XXX: possibly we could use a block data load or writeback in
- * the first access. */
- tcg_out_ld32_12(s, COND_EQ, TCG_REG_R1, TCG_REG_R0,
- offsetof(CPUArchState, tlb_table[0][0].addr_write) + 4);
+ /* XXX: possibly we could use a block data load in the first access. */
+ tcg_out_ld32_12(s, COND_EQ, TCG_REG_R1, TCG_REG_R0, 4);
tcg_out_dat_reg(s, COND_EQ, ARITH_CMP, 0,
TCG_REG_R1, addr_reg2, SHIFT_IMM_LSL(0));
# endif
tcg_out_ld32_12(s, COND_EQ, TCG_REG_R1, TCG_REG_R0,
- offsetof(CPUArchState, tlb_table[0][0].addend));
+ offsetof(CPUTLBEntry, addend)
+ - offsetof(CPUTLBEntry, addr_write));
switch (opc) {
case 0:
--
1.7.9.5
next prev parent reply other threads:[~2012-12-03 22:15 UTC|newest]
Thread overview: 45+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-12-03 22:08 [Qemu-devel] Patch Round-up for stable 1.2.2, freeze Wednesday Michael Roth
2012-12-03 22:08 ` [Qemu-devel] [PATCH 01/43] configure: Fix CONFIG_QEMU_HELPERDIR generation Michael Roth
2012-12-03 22:08 ` [Qemu-devel] [PATCH 02/43] fix CONFIG_QEMU_HELPERDIR generation again Michael Roth
2012-12-03 22:08 ` [Qemu-devel] [PATCH 03/43] ui/vnc: Only report/use TIGHT_PNG encoding if enabled Michael Roth
2012-12-03 22:08 ` [Qemu-devel] [PATCH 04/43] vnc: fix "info vnc" with "-vnc ..., reverse=on" Michael Roth
2012-12-03 22:08 ` [Qemu-devel] [PATCH 05/43] uhci: Raise interrupt when requested even for non active tds Michael Roth
2012-12-03 22:08 ` [Qemu-devel] [PATCH 06/43] hw/qxl: qxl_dirty_surfaces: use uintptr_t Michael Roth
2012-12-03 22:08 ` [Qemu-devel] [PATCH 07/43] qxl: always update displaysurface on resize Michael Roth
2012-12-03 22:08 ` [Qemu-devel] [PATCH 08/43] rtc: fix overflow in mktimegm Michael Roth
2012-12-03 22:08 ` [Qemu-devel] [PATCH 09/43] hw: Fix return value check for bdrv_read, bdrv_write Michael Roth
2012-12-03 22:08 ` [Qemu-devel] [PATCH 10/43] target-i386: Allow tsc-frequency to be larger then 2.147G Michael Roth
2012-12-03 22:08 ` [Qemu-devel] [PATCH 11/43] e1000: drop check_rxov, always treat RX ring with RDH == RDT as empty Michael Roth
2012-12-03 22:08 ` [Qemu-devel] [PATCH 12/43] memory: fix rendering of a region obscured by another Michael Roth
2012-12-03 22:08 ` [Qemu-devel] [PATCH 13/43] s390x: fix -initrd in virtio machine Michael Roth
2012-12-03 22:08 ` [Qemu-devel] [PATCH 14/43] PPC: Bamboo: Fix memory size DT property Michael Roth
2012-12-03 22:08 ` [Qemu-devel] [PATCH 15/43] target-sparc64: disable VGA cirrus Michael Roth
2012-12-03 22:08 ` [Qemu-devel] [PATCH 16/43] xhci: fix usb name in caps Michael Roth
2012-12-03 22:08 ` [Qemu-devel] [PATCH 17/43] tools: initialize main loop before block layer Michael Roth
2012-12-03 22:08 ` [Qemu-devel] [PATCH 18/43] m68k: Return semihosting errno values correctly Michael Roth
2012-12-03 22:08 ` [Qemu-devel] [PATCH 19/43] nbd: fixes to read-only handling Michael Roth
2012-12-03 22:08 ` [Qemu-devel] [PATCH 20/43] mips/malta: fix CBUS UART interrupt pin Michael Roth
2012-12-03 22:08 ` [Qemu-devel] [PATCH 21/43] target-mips: fix wrong microMIPS opcode encoding Michael Roth
2012-12-03 22:08 ` Michael Roth [this message]
2013-01-17 16:55 ` [Qemu-devel] [PATCH 22/43] tcg/arm: fix TLB access in qemu-ld/st ops Peter Maydell
2012-12-03 22:08 ` [Qemu-devel] [PATCH 23/43] tcg/arm: fix cross-endian qemu_st16 Michael Roth
2012-12-03 22:08 ` [Qemu-devel] [PATCH 24/43] target-openrisc: remove conflicting definitions from cpu.h Michael Roth
2012-12-03 22:08 ` [Qemu-devel] [PATCH 25/43] configure: avoid compiler warning in pipe2 detection Michael Roth
2012-12-03 22:08 ` [Qemu-devel] [PATCH 26/43] qcow2: Fix refcount table size calculation Michael Roth
2012-12-03 22:08 ` [Qemu-devel] [PATCH 27/43] tci: Fix type of tci_read_label Michael Roth
2012-12-03 22:25 ` [Qemu-devel] [PATCH 28/43] block: Fix regression for MinGW (assertion caused by short string) Michael Roth
2012-12-03 22:25 ` [Qemu-devel] [PATCH 29/43] qom: dynamic_cast of NULL is always NULL Michael Roth
2012-12-03 22:25 ` [Qemu-devel] [PATCH 30/43] hmp: do not crash on invalid SCSI hotplug Michael Roth
2012-12-03 22:25 ` [Qemu-devel] [PATCH 31/43] PPC: Fix missing TRACE exception Michael Roth
2012-12-03 22:25 ` [Qemu-devel] [PATCH 32/43] qom: fix refcount of non-heap-allocated objects Michael Roth
2012-12-03 22:44 ` [Qemu-devel] [PATCH 33/43] qapi: handle visitor->type_size() in QapiDeallocVisitor Michael Roth
2012-12-03 22:44 ` [Qemu-devel] [PATCH 34/43] qapi: fix qapi_dealloc_type_size parameter type Michael Roth
2012-12-03 22:44 ` [Qemu-devel] [PATCH 35/43] iscsi: fix segfault in url parsing Michael Roth
2012-12-03 22:44 ` [Qemu-devel] [PATCH 36/43] iscsi: fix deadlock during login Michael Roth
2012-12-03 22:44 ` [Qemu-devel] [PATCH 37/43] iscsi: do not assume device is zero initialized Michael Roth
2012-12-03 22:44 ` [Qemu-devel] [PATCH 38/43] virtio-scsi: Fix some endian bugs with virtio-scsi Michael Roth
2012-12-03 22:44 ` [Qemu-devel] [PATCH 39/43] virtio-scsi: Fix subtle (guest) endian bug Michael Roth
2012-12-03 22:44 ` [Qemu-devel] [PATCH 40/43] qxl: reload memslots after migration, when qxl is in UNDEFINED mode Michael Roth
2012-12-03 22:44 ` [Qemu-devel] [PATCH 41/43] usb: fail usbdevice_create() when there is no USB bus Michael Roth
2012-12-03 22:44 ` [Qemu-devel] [PATCH 42/43] stream: fix ratelimit_set_speed Michael Roth
2012-12-03 22:44 ` [Qemu-devel] [PATCH 43/43] e1000: Discard packets that are too long if !SBP and !LPE Michael Roth
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=1354572547-21271-23-git-send-email-mdroth@linux.vnet.ibm.com \
--to=mdroth@linux.vnet.ibm.com \
--cc=aliguori@us.ibm.com \
--cc=qemu-devel@nongnu.org \
--cc=qemu-stable@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).