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