Blame 0203-cpu_physical_memory_write_rom-needs-to-do-TB-invalid.patch

5544c1
From 897815f54c446671cae0f202c54e9548e969d427 Mon Sep 17 00:00:00 2001
5544c1
From: David Gibson <david@gibson.dropbear.id.au>
5544c1
Date: Mon, 10 Sep 2012 12:30:57 +1000
5544c1
Subject: [PATCH] cpu_physical_memory_write_rom() needs to do TB invalidates
5544c1
5544c1
cpu_physical_memory_write_rom(), despite the name, can also be used to
5544c1
write images into RAM - and will often be used that way if the machine
5544c1
uses load_image_targphys() into RAM addresses.
5544c1
5544c1
However, cpu_physical_memory_write_rom(), unlike cpu_physical_memory_rw()
5544c1
doesn't invalidate any cached TBs which might be affected by the region
5544c1
written.
5544c1
5544c1
This was breaking reset (under full emu) on the pseries machine - we loaded
5544c1
our firmware image into RAM, and while executing it rewrite the code at
5544c1
the entry point (correctly causing a TB invalidate/refresh).  When we
5544c1
reset the firmware image was reloaded, but the TB from the rewrite was
5544c1
still active and caused us to get an illegal instruction trap.
5544c1
5544c1
This patch fixes the bug by duplicating the tb invalidate code from
5544c1
cpu_physical_memory_rw() in cpu_physical_memory_write_rom().
5544c1
5544c1
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
5544c1
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
5544c1
(cherry picked from commit 0b57e287138728f72d88b06e69b970c5d745c44a)
5544c1
5544c1
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
5544c1
---
5544c1
 exec.c | 7 +++++++
5544c1
 1 file changed, 7 insertions(+)
5544c1
5544c1
diff --git a/exec.c b/exec.c
5544c1
index ad175db..3fdbbde 100644
5544c1
--- a/exec.c
5544c1
+++ b/exec.c
5544c1
@@ -3521,6 +3521,13 @@ void cpu_physical_memory_write_rom(target_phys_addr_t addr,
5544c1
             /* ROM/RAM case */
5544c1
             ptr = qemu_get_ram_ptr(addr1);
5544c1
             memcpy(ptr, buf, l);
5544c1
+            if (!cpu_physical_memory_is_dirty(addr1)) {
5544c1
+                /* invalidate code */
5544c1
+                tb_invalidate_phys_page_range(addr1, addr1 + l, 0);
5544c1
+                /* set dirty bit */
5544c1
+                cpu_physical_memory_set_dirty_flags(
5544c1
+                    addr1, (0xff & ~CODE_DIRTY_FLAG));
5544c1
+            }
5544c1
             qemu_put_ram_ptr(ptr);
5544c1
         }
5544c1
         len -= l;
5544c1
-- 
5544c1
1.7.12.1
5544c1