qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* {PATCH] accel/tcg: Fix CPU specific unaligned behaviour
@ 2024-10-02  2:37 Helge Deller
  2024-10-02 15:35 ` Alex Bennée
  0 siblings, 1 reply; 8+ messages in thread
From: Helge Deller @ 2024-10-02  2:37 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: linux-parisc

When the emulated CPU reads or writes to a memory location
a) for which no read/write permissions exists, *and*
b) the access happens unaligned (non-natural alignment),
then the CPU should either
- trigger a permission fault, or
- trigger an unalign access fault.

In the current code the alignment check happens before the memory
permission checks, so only unalignment faults will be triggered.

This behaviour breaks the emulation of the PARISC architecture, where the CPU
does a memory verification first. The behaviour can be tested with the testcase
from the bugzilla report.

Add the necessary code to allow PARISC and possibly other architectures to
trigger a memory fault instead.

Signed-off-by: Helge Deller <deller@gmx.de>
Fixes: https://bugzilla.kernel.org/show_bug.cgi?id=219339


diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
index 117b516739..dd1da358fb 100644
--- a/accel/tcg/cputlb.c
+++ b/accel/tcg/cputlb.c
@@ -1684,6 +1684,26 @@ static void mmu_watch_or_dirty(CPUState *cpu, MMULookupPageData *data,
     data->flags = flags;
 }
 
+/* when accessing unreadable memory unaligned, will the CPU issue
+ * a alignment trap or a memory access trap ? */
+#ifdef TARGET_HPPA
+# define CPU_ALIGNMENT_CHECK_AFTER_MEMCHECK  1
+#else
+# define CPU_ALIGNMENT_CHECK_AFTER_MEMCHECK  0
+#endif
+
+static void mmu_check_alignment(CPUState *cpu, vaddr addr,
+                       uintptr_t ra, MMUAccessType type, MMULookupLocals *l)
+{
+    unsigned a_bits;
+
+    /* Handle CPU specific unaligned behaviour */
+    a_bits = get_alignment_bits(l->memop);
+    if (addr & ((1 << a_bits) - 1)) {
+        cpu_unaligned_access(cpu, addr, type, l->mmu_idx, ra);
+    }
+}
+
 /**
  * mmu_lookup: translate page(s)
  * @cpu: generic cpu state
@@ -1699,7 +1719,6 @@ static void mmu_watch_or_dirty(CPUState *cpu, MMULookupPageData *data,
 static bool mmu_lookup(CPUState *cpu, vaddr addr, MemOpIdx oi,
                        uintptr_t ra, MMUAccessType type, MMULookupLocals *l)
 {
-    unsigned a_bits;
     bool crosspage;
     int flags;
 
@@ -1708,10 +1727,8 @@ static bool mmu_lookup(CPUState *cpu, vaddr addr, MemOpIdx oi,
 
     tcg_debug_assert(l->mmu_idx < NB_MMU_MODES);
 
-    /* Handle CPU specific unaligned behaviour */
-    a_bits = get_alignment_bits(l->memop);
-    if (addr & ((1 << a_bits) - 1)) {
-        cpu_unaligned_access(cpu, addr, type, l->mmu_idx, ra);
+    if (!CPU_ALIGNMENT_CHECK_AFTER_MEMCHECK) {
+        mmu_check_alignment(cpu, addr, ra, type, l);
     }
 
     l->page[0].addr = addr;
@@ -1760,6 +1777,10 @@ static bool mmu_lookup(CPUState *cpu, vaddr addr, MemOpIdx oi,
         tcg_debug_assert((flags & TLB_BSWAP) == 0);
     }
 
+    if (CPU_ALIGNMENT_CHECK_AFTER_MEMCHECK) {
+        mmu_check_alignment(cpu, addr, ra, type, l);
+    }
+
     /*
      * This alignment check differs from the one above, in that this is
      * based on the atomicity of the operation. The intended use case is


^ permalink raw reply related	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2024-10-05 16:56 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-10-02  2:37 {PATCH] accel/tcg: Fix CPU specific unaligned behaviour Helge Deller
2024-10-02 15:35 ` Alex Bennée
2024-10-02 15:47   ` Peter Maydell
2024-10-02 17:25     ` Alex Bennée
2024-10-02 19:38     ` Helge Deller
2024-10-03 23:08     ` Richard Henderson
2024-10-04 14:24   ` Richard Henderson
2024-10-05 16:55     ` Richard Henderson

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).