qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Richard Henderson <richard.henderson@linaro.org>
To: qemu-devel@nongnu.org
Cc: Jonathan Cameron <Jonathan.Cameron@huawei.com>,
	Peter Maydell <peter.maydell@linaro.org>
Subject: [PULL 03/39] tcg: Avoid double lock if page tables happen to be in mmio memory.
Date: Thu, 22 Feb 2024 10:42:47 -1000	[thread overview]
Message-ID: <20240222204323.268539-4-richard.henderson@linaro.org> (raw)
In-Reply-To: <20240222204323.268539-1-richard.henderson@linaro.org>

From: Jonathan Cameron <Jonathan.Cameron@huawei.com>

On i386, after fixing the page walking code to work with pages in
MMIO memory (specifically CXL emulated interleaved memory),
a crash was seen in an interrupt handling path.

Useful part of backtrace

7  0x0000555555ab1929 in bql_lock_impl (file=0x555556049122 "../../accel/tcg/cputlb.c", line=2033) at ../../system/cpus.c:524
8  bql_lock_impl (file=file@entry=0x555556049122 "../../accel/tcg/cputlb.c", line=line@entry=2033) at ../../system/cpus.c:520
9  0x0000555555c9f7d6 in do_ld_mmio_beN (cpu=0x5555578e0cb0, full=0x7ffe88012950, ret_be=ret_be@entry=0, addr=19595792376, size=size@entry=8, mmu_idx=4, type=MMU_DATA_LOAD, ra=0) at ../../accel/tcg/cputlb.c:2033
10 0x0000555555ca0fbd in do_ld_8 (cpu=cpu@entry=0x5555578e0cb0, p=p@entry=0x7ffff4efd1d0, mmu_idx=<optimized out>, type=type@entry=MMU_DATA_LOAD, memop=<optimized out>, ra=ra@entry=0) at ../../accel/tcg/cputlb.c:2356
11 0x0000555555ca341f in do_ld8_mmu (cpu=cpu@entry=0x5555578e0cb0, addr=addr@entry=19595792376, oi=oi@entry=52, ra=0, ra@entry=52, access_type=access_type@entry=MMU_DATA_LOAD) at ../../accel/tcg/cputlb.c:2439
12 0x0000555555ca5f59 in cpu_ldq_mmu (ra=52, oi=52, addr=19595792376, env=0x5555578e3470) at ../../accel/tcg/ldst_common.c.inc:169
13 cpu_ldq_le_mmuidx_ra (env=0x5555578e3470, addr=19595792376, mmu_idx=<optimized out>, ra=ra@entry=0) at ../../accel/tcg/ldst_common.c.inc:301
14 0x0000555555b4b5fc in ptw_ldq (ra=0, in=0x7ffff4efd320) at ../../target/i386/tcg/sysemu/excp_helper.c:98
15 ptw_ldq (ra=0, in=0x7ffff4efd320) at ../../target/i386/tcg/sysemu/excp_helper.c:93
16 mmu_translate (env=env@entry=0x5555578e3470, in=0x7ffff4efd3e0, out=0x7ffff4efd3b0, err=err@entry=0x7ffff4efd3c0, ra=ra@entry=0) at ../../target/i386/tcg/sysemu/excp_helper.c:174
17 0x0000555555b4c4b3 in get_physical_address (ra=0, err=0x7ffff4efd3c0, out=0x7ffff4efd3b0, mmu_idx=0, access_type=MMU_DATA_LOAD, addr=18446741874686299840, env=0x5555578e3470) at ../../target/i386/tcg/sysemu/excp_helper.c:580
18 x86_cpu_tlb_fill (cs=0x5555578e0cb0, addr=18446741874686299840, size=<optimized out>, access_type=MMU_DATA_LOAD, mmu_idx=0, probe=<optimized out>, retaddr=0) at ../../target/i386/tcg/sysemu/excp_helper.c:606
19 0x0000555555ca0ee9 in tlb_fill (retaddr=0, mmu_idx=0, access_type=MMU_DATA_LOAD, size=<optimized out>, addr=18446741874686299840, cpu=0x7ffff4efd540) at ../../accel/tcg/cputlb.c:1315
20 mmu_lookup1 (cpu=cpu@entry=0x5555578e0cb0, data=data@entry=0x7ffff4efd540, mmu_idx=0, access_type=access_type@entry=MMU_DATA_LOAD, ra=ra@entry=0) at ../../accel/tcg/cputlb.c:1713
21 0x0000555555ca2c61 in mmu_lookup (cpu=cpu@entry=0x5555578e0cb0, addr=addr@entry=18446741874686299840, oi=oi@entry=32, ra=ra@entry=0, type=type@entry=MMU_DATA_LOAD, l=l@entry=0x7ffff4efd540) at ../../accel/tcg/cputlb.c:1803
22 0x0000555555ca3165 in do_ld4_mmu (cpu=cpu@entry=0x5555578e0cb0, addr=addr@entry=18446741874686299840, oi=oi@entry=32, ra=ra@entry=0, access_type=access_type@entry=MMU_DATA_LOAD) at ../../accel/tcg/cputlb.c:2416
23 0x0000555555ca5ef9 in cpu_ldl_mmu (ra=0, oi=32, addr=18446741874686299840, env=0x5555578e3470) at ../../accel/tcg/ldst_common.c.inc:158
24 cpu_ldl_le_mmuidx_ra (env=env@entry=0x5555578e3470, addr=addr@entry=18446741874686299840, mmu_idx=<optimized out>, ra=ra@entry=0) at ../../accel/tcg/ldst_common.c.inc:294
25 0x0000555555bb6cdd in do_interrupt64 (is_hw=1, next_eip=18446744072399775809, error_code=0, is_int=0, intno=236, env=0x5555578e3470) at ../../target/i386/tcg/seg_helper.c:889
26 do_interrupt_all (cpu=cpu@entry=0x5555578e0cb0, intno=236, is_int=is_int@entry=0, error_code=error_code@entry=0, next_eip=next_eip@entry=0, is_hw=is_hw@entry=1) at ../../target/i386/tcg/seg_helper.c:1130
27 0x0000555555bb87da in do_interrupt_x86_hardirq (env=env@entry=0x5555578e3470, intno=<optimized out>, is_hw=is_hw@entry=1) at ../../target/i386/tcg/seg_helper.c:1162
28 0x0000555555b5039c in x86_cpu_exec_interrupt (cs=0x5555578e0cb0, interrupt_request=<optimized out>) at ../../target/i386/tcg/sysemu/seg_helper.c:197
29 0x0000555555c94480 in cpu_handle_interrupt (last_tb=<synthetic pointer>, cpu=0x5555578e0cb0) at ../../accel/tcg/cpu-exec.c:844

Peter identified this as being due to the BQL already being
held when the page table walker encounters MMIO memory and attempts
to take the lock again.  There are other examples of similar paths
TCG, so this follows the approach taken in those of simply checking
if the lock is already held and if it is, don't take it again.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Message-Id: <20240219173153.12114-4-Jonathan.Cameron@huawei.com>
[rth: Use BQL_LOCK_GUARD]
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 accel/tcg/cputlb.c | 34 ++++++++++------------------------
 1 file changed, 10 insertions(+), 24 deletions(-)

diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
index 047cd2cc0a..6243bcb179 100644
--- a/accel/tcg/cputlb.c
+++ b/accel/tcg/cputlb.c
@@ -2022,7 +2022,6 @@ static uint64_t do_ld_mmio_beN(CPUState *cpu, CPUTLBEntryFull *full,
     MemoryRegion *mr;
     hwaddr mr_offset;
     MemTxAttrs attrs;
-    uint64_t ret;
 
     tcg_debug_assert(size > 0 && size <= 8);
 
@@ -2030,12 +2029,9 @@ static uint64_t do_ld_mmio_beN(CPUState *cpu, CPUTLBEntryFull *full,
     section = io_prepare(&mr_offset, cpu, full->xlat_section, attrs, addr, ra);
     mr = section->mr;
 
-    bql_lock();
-    ret = int_ld_mmio_beN(cpu, full, ret_be, addr, size, mmu_idx,
-                          type, ra, mr, mr_offset);
-    bql_unlock();
-
-    return ret;
+    BQL_LOCK_GUARD();
+    return int_ld_mmio_beN(cpu, full, ret_be, addr, size, mmu_idx,
+                           type, ra, mr, mr_offset);
 }
 
 static Int128 do_ld16_mmio_beN(CPUState *cpu, CPUTLBEntryFull *full,
@@ -2054,13 +2050,11 @@ static Int128 do_ld16_mmio_beN(CPUState *cpu, CPUTLBEntryFull *full,
     section = io_prepare(&mr_offset, cpu, full->xlat_section, attrs, addr, ra);
     mr = section->mr;
 
-    bql_lock();
+    BQL_LOCK_GUARD();
     a = int_ld_mmio_beN(cpu, full, ret_be, addr, size - 8, mmu_idx,
                         MMU_DATA_LOAD, ra, mr, mr_offset);
     b = int_ld_mmio_beN(cpu, full, ret_be, addr + size - 8, 8, mmu_idx,
                         MMU_DATA_LOAD, ra, mr, mr_offset + size - 8);
-    bql_unlock();
-
     return int128_make128(b, a);
 }
 
@@ -2569,7 +2563,6 @@ static uint64_t do_st_mmio_leN(CPUState *cpu, CPUTLBEntryFull *full,
     hwaddr mr_offset;
     MemoryRegion *mr;
     MemTxAttrs attrs;
-    uint64_t ret;
 
     tcg_debug_assert(size > 0 && size <= 8);
 
@@ -2577,12 +2570,9 @@ static uint64_t do_st_mmio_leN(CPUState *cpu, CPUTLBEntryFull *full,
     section = io_prepare(&mr_offset, cpu, full->xlat_section, attrs, addr, ra);
     mr = section->mr;
 
-    bql_lock();
-    ret = int_st_mmio_leN(cpu, full, val_le, addr, size, mmu_idx,
-                          ra, mr, mr_offset);
-    bql_unlock();
-
-    return ret;
+    BQL_LOCK_GUARD();
+    return int_st_mmio_leN(cpu, full, val_le, addr, size, mmu_idx,
+                           ra, mr, mr_offset);
 }
 
 static uint64_t do_st16_mmio_leN(CPUState *cpu, CPUTLBEntryFull *full,
@@ -2593,7 +2583,6 @@ static uint64_t do_st16_mmio_leN(CPUState *cpu, CPUTLBEntryFull *full,
     MemoryRegion *mr;
     hwaddr mr_offset;
     MemTxAttrs attrs;
-    uint64_t ret;
 
     tcg_debug_assert(size > 8 && size <= 16);
 
@@ -2601,14 +2590,11 @@ static uint64_t do_st16_mmio_leN(CPUState *cpu, CPUTLBEntryFull *full,
     section = io_prepare(&mr_offset, cpu, full->xlat_section, attrs, addr, ra);
     mr = section->mr;
 
-    bql_lock();
+    BQL_LOCK_GUARD();
     int_st_mmio_leN(cpu, full, int128_getlo(val_le), addr, 8,
                     mmu_idx, ra, mr, mr_offset);
-    ret = int_st_mmio_leN(cpu, full, int128_gethi(val_le), addr + 8,
-                          size - 8, mmu_idx, ra, mr, mr_offset + 8);
-    bql_unlock();
-
-    return ret;
+    return int_st_mmio_leN(cpu, full, int128_gethi(val_le), addr + 8,
+                           size - 8, mmu_idx, ra, mr, mr_offset + 8);
 }
 
 /*
-- 
2.34.1



  parent reply	other threads:[~2024-02-22 20:45 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-02-22 20:42 [PULL 00/39] tcg and linux-user patch queue Richard Henderson
2024-02-22 20:42 ` [PULL 01/39] tcg/aarch64: Apple does not align __int128_t in even registers Richard Henderson
2024-02-22 20:42 ` [PULL 02/39] accel/tcg: Set can_do_io at at start of lookup_tb_ptr helper Richard Henderson
2024-02-22 20:42 ` Richard Henderson [this message]
2024-02-22 20:42 ` [PULL 04/39] accel/tcg: Remove qemu_host_page_size from page_protect/page_unprotect Richard Henderson
2024-02-22 20:42 ` [PULL 05/39] linux-user: Adjust SVr4 NULL page mapping Richard Henderson
2024-02-22 20:42 ` [PULL 06/39] linux-user: Remove qemu_host_page_{size, mask} in probe_guest_base Richard Henderson
2024-02-22 20:42 ` [PULL 07/39] linux-user: Remove qemu_host_page_size from create_elf_tables Richard Henderson
2024-02-22 20:42 ` [PULL 08/39] linux-user/hppa: Simplify init_guest_commpage Richard Henderson
2024-02-22 20:42 ` [PULL 09/39] linux-user/nios2: Remove qemu_host_page_size from init_guest_commpage Richard Henderson
2024-02-22 20:42 ` [PULL 10/39] linux-user/arm: " Richard Henderson
2024-02-22 20:42 ` [PULL 11/39] linux-user: Remove qemu_host_page_{size, mask} from mmap.c Richard Henderson
2024-02-22 20:42 ` [PULL 12/39] linux-user: Remove REAL_HOST_PAGE_ALIGN " Richard Henderson
2024-02-22 20:42 ` [PULL 13/39] linux-user: Remove HOST_PAGE_ALIGN " Richard Henderson
2024-02-22 20:42 ` [PULL 14/39] migration: Remove qemu_host_page_size Richard Henderson
2024-02-22 20:42 ` [PULL 15/39] hw/tpm: Remove HOST_PAGE_ALIGN from tpm_ppi_init Richard Henderson
2024-02-22 20:43 ` [PULL 16/39] softmmu/physmem: Remove qemu_host_page_size Richard Henderson
2024-02-22 20:43 ` [PULL 17/39] softmmu/physmem: Remove HOST_PAGE_ALIGN Richard Henderson
2024-02-22 20:43 ` [PULL 18/39] linux-user: Remove qemu_host_page_size from main Richard Henderson
2024-02-22 20:43 ` [PULL 19/39] linux-user: Split out target_mmap__locked Richard Henderson
2024-02-22 20:43 ` [PULL 20/39] linux-user: Move some mmap checks outside the lock Richard Henderson
2024-02-22 20:43 ` [PULL 21/39] linux-user: Fix sub-host-page mmap Richard Henderson
2024-02-22 20:43 ` [PULL 22/39] linux-user: Split out mmap_end Richard Henderson
2024-02-22 20:43 ` [PULL 23/39] linux-user: Do early mmap placement only for reserved_va Richard Henderson
2024-02-22 20:43 ` [PULL 24/39] linux-user: Split out do_munmap Richard Henderson
2024-02-22 20:43 ` [PULL 25/39] linux-user: Use do_munmap for target_mmap failure Richard Henderson
2024-02-22 20:43 ` [PULL 26/39] linux-user: Split out mmap_h_eq_g Richard Henderson
2024-02-22 20:43 ` [PULL 27/39] linux-user: Split out mmap_h_lt_g Richard Henderson
2024-02-22 20:43 ` [PULL 28/39] linux-user: Split out mmap_h_gt_g Richard Henderson
2024-02-22 20:43 ` [PULL 29/39] tests/tcg: Remove run-test-mmap-* Richard Henderson
2024-02-22 20:43 ` [PULL 30/39] tests/tcg: Extend file in linux-madvise.c Richard Henderson
2024-02-22 20:43 ` [PULL 31/39] *-user: Deprecate and disable -p pagesize Richard Henderson
2024-02-22 20:43 ` [PULL 32/39] cpu: Remove page_size_init Richard Henderson
2024-02-22 20:43 ` [PULL 33/39] accel/tcg: Disconnect TargetPageDataNode from page size Richard Henderson
2024-02-22 20:43 ` [PULL 34/39] linux-user: Allow TARGET_PAGE_BITS_VARY Richard Henderson
2024-02-22 20:43 ` [PULL 35/39] target/arm: Enable TARGET_PAGE_BITS_VARY for AArch64 user-only Richard Henderson
2024-02-22 20:43 ` [PULL 36/39] linux-user: Bound mmap_min_addr by host page size Richard Henderson
2024-02-22 20:43 ` [PULL 37/39] target/ppc: Enable TARGET_PAGE_BITS_VARY for user-only Richard Henderson
2024-02-22 20:43 ` [PULL 38/39] target/alpha: " Richard Henderson
2024-02-22 20:43 ` [PULL 39/39] linux-user: Remove pgb_dynamic alignment assertion Richard Henderson
2024-02-23 13:45 ` [PULL 00/39] tcg and linux-user patch queue Peter Maydell
2024-02-23 22:26   ` 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=20240222204323.268539-4-richard.henderson@linaro.org \
    --to=richard.henderson@linaro.org \
    --cc=Jonathan.Cameron@huawei.com \
    --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).